From 1be1a99c19f38e28540ff8b3af5ebaec14142e5a Mon Sep 17 00:00:00 2001 From: Lenkomotive <90652966+lenkomotive@users.noreply.github.com> Date: Mon, 22 May 2023 16:34:05 +0200 Subject: [PATCH 1/3] PAINTROID-532: Update app for android 13 --- Paintroid/src/debug/AndroidManifest.xml | 1 + Paintroid/src/main/AndroidManifest.xml | 1 + .../java/org/catrobat/paintroid/FileIO.kt | 6 ++--- .../contract/MainActivityContracts.kt | 1 + .../presenter/MainActivityPresenter.kt | 24 ++++++++++++++++--- .../paintroid/ui/MainActivityNavigator.kt | 6 ++++- .../presenter/MainActivityPresenterTest.kt | 19 ++++++++------- build.gradle | 4 ++-- 8 files changed, 44 insertions(+), 18 deletions(-) diff --git a/Paintroid/src/debug/AndroidManifest.xml b/Paintroid/src/debug/AndroidManifest.xml index 18ddbc41af..ff48bbb59f 100644 --- a/Paintroid/src/debug/AndroidManifest.xml +++ b/Paintroid/src/debug/AndroidManifest.xml @@ -21,6 +21,7 @@ + + diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/FileIO.kt b/Paintroid/src/main/java/org/catrobat/paintroid/FileIO.kt index 895c4484f2..864f069b0c 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/FileIO.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/FileIO.kt @@ -358,7 +358,7 @@ object FileIO { cursor?.use { if (cursor.moveToFirst()) { fileName = - cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DISPLAY_NAME)) + cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DISPLAY_NAME)) } } if (fileName.endsWith(FileType.JPG.toExtension()) || fileName.endsWith(".jpeg")) { @@ -406,9 +406,9 @@ object FileIO { val cursor = resolver.query(contentLocationUri, null, selection, selectionArgs, null) cursor?.run { while (moveToNext()) { - val fileName = getString(cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)) + val fileName = getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME)) if (fileName == filename) { - val id = cursor.getLong(cursor.getColumnIndex(MediaStore.MediaColumns._ID)) + val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID)) close() return ContentUris.withAppendedId(contentLocationUri, id) } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/contract/MainActivityContracts.kt b/Paintroid/src/main/java/org/catrobat/paintroid/contract/MainActivityContracts.kt index cb3670335f..6328ef10d7 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/contract/MainActivityContracts.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/contract/MainActivityContracts.kt @@ -44,6 +44,7 @@ interface MainActivityContracts { interface Navigator { val isSdkAboveOrEqualM: Boolean val isSdkAboveOrEqualQ: Boolean + val isSdkAboveOrEqualT: Boolean fun showColorPickerDialog() diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/presenter/MainActivityPresenter.kt b/Paintroid/src/main/java/org/catrobat/paintroid/presenter/MainActivityPresenter.kt index 229b3333d3..f86fb4abcf 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/presenter/MainActivityPresenter.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/presenter/MainActivityPresenter.kt @@ -19,6 +19,7 @@ package org.catrobat.paintroid.presenter import android.Manifest +import android.annotation.TargetApi import android.app.Activity import android.content.ContentResolver import android.content.ContentUris @@ -386,7 +387,22 @@ open class MainActivityPresenter( ) return } - if (navigator.isSdkAboveOrEqualQ) { + + @TargetApi(Build.VERSION_CODES.TIRAMISU) + if (navigator.isSdkAboveOrEqualT) { + if (!navigator.doIHavePermission(Manifest.permission.READ_MEDIA_IMAGES)) { + navigator.askForPermission( + arrayOf(Manifest.permission.READ_MEDIA_IMAGES), + requestCode + ) + } else { + handleRequestPermissionsResult( + requestCode, + arrayOf(Manifest.permission.READ_MEDIA_IMAGES), + intArrayOf(PackageManager.PERMISSION_GRANTED) + ) + } + } else if (navigator.isSdkAboveOrEqualQ) { if (!navigator.doIHavePermission(Manifest.permission.READ_EXTERNAL_STORAGE)) { navigator.askForPermission( arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), @@ -472,7 +488,9 @@ open class MainActivityPresenter( permissions: Array, grantResults: IntArray ) { - if (permissions.size == 1 && (permissions[0] == Manifest.permission.READ_EXTERNAL_STORAGE || permissions[0] == Manifest.permission.WRITE_EXTERNAL_STORAGE)) { + if (permissions.size == 1 && (permissions[0] == Manifest.permission.READ_EXTERNAL_STORAGE || + permissions[0] == Manifest.permission.WRITE_EXTERNAL_STORAGE || + permissions[0] == Manifest.permission.READ_MEDIA_IMAGES)) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { when (requestCode) { PERMISSION_EXTERNAL_STORAGE_SAVE -> { @@ -1050,7 +1068,7 @@ open class MainActivityPresenter( val cursor = fileActivity?.contentResolver?.query(uri, null, null, null, null) cursor?.use { if (it.moveToFirst()) { - result = it.getString(it.getColumnIndex(OpenableColumns.DISPLAY_NAME)) + result = it.getString(it.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME)) } } } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/ui/MainActivityNavigator.kt b/Paintroid/src/main/java/org/catrobat/paintroid/ui/MainActivityNavigator.kt index 3136f1cc98..027f8dbeae 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/ui/MainActivityNavigator.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/ui/MainActivityNavigator.kt @@ -105,6 +105,10 @@ class MainActivityNavigator( @SuppressLint("AnnotateVersionCheck") get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q + override val isSdkAboveOrEqualT: Boolean + @SuppressLint("AnnotateVersionCheck") + get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + private var commandFactory: CommandFactory = DefaultCommandFactory() private fun showFragment( @@ -190,7 +194,7 @@ class MainActivityNavigator( val queryCursor = mainActivity.contentResolver.query(uri, null, null, null, null) queryCursor.use { cursor -> if (cursor != null && cursor.moveToFirst()) { - result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)) + result = cursor.getString(cursor.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME)) } } } diff --git a/Paintroid/src/test/java/org/catrobat/paintroid/test/presenter/MainActivityPresenterTest.kt b/Paintroid/src/test/java/org/catrobat/paintroid/test/presenter/MainActivityPresenterTest.kt index 4cd7606a54..c06cca6f7c 100644 --- a/Paintroid/src/test/java/org/catrobat/paintroid/test/presenter/MainActivityPresenterTest.kt +++ b/Paintroid/src/test/java/org/catrobat/paintroid/test/presenter/MainActivityPresenterTest.kt @@ -1435,6 +1435,7 @@ class MainActivityPresenterTest { false ) presenter!!.switchBetweenVersions(PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_LOAD_NEW) + Mockito.verify(interactor).saveImage( presenter!!, SAVE_IMAGE_LOAD_NEW, workspace!!.layerModel, commandSerializer!!, FileIO.storeImageUri, @@ -1445,20 +1446,20 @@ class MainActivityPresenterTest { @Test fun testSaveAndLoadImagePermissionNotGranted() { Mockito.`when`(navigator!!.doIHavePermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) - .thenReturn(false) + .thenReturn(false) Mockito.`when`(navigator.isSdkAboveOrEqualM).thenReturn(false).thenReturn(true) presenter!!.saveBeforeLoadImage() Mockito.verify(navigator) - .showSaveImageInformationDialogWhenStandalone( - PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_LOAD_NEW, - sharedPreferences!!.preferenceImageNumber, - false - ) + .showSaveImageInformationDialogWhenStandalone( + PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_LOAD_NEW, + sharedPreferences!!.preferenceImageNumber, + false + ) presenter!!.switchBetweenVersions(PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_LOAD_NEW) Mockito.verify(navigator).askForPermission( - arrayOf( - Manifest.permission.WRITE_EXTERNAL_STORAGE - ), PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_LOAD_NEW + arrayOf( + Manifest.permission.WRITE_EXTERNAL_STORAGE + ), PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_LOAD_NEW ) } diff --git a/build.gradle b/build.gradle index 9734277b42..911f7de923 100644 --- a/build.gradle +++ b/build.gradle @@ -41,9 +41,9 @@ plugins { } ext { - androidCompileSdkVersion = 30 + androidCompileSdkVersion = 33 androidMinSdkVersion = 21 - androidTargetSdkVersion = 31 + androidTargetSdkVersion = 33 androidSupportLibraryVersion = '28.0.0' From 0de759684b9cde2c028d3260fa02c2852b43f156 Mon Sep 17 00:00:00 2001 From: Khalid Nasralla Date: Tue, 30 May 2023 19:20:57 +0200 Subject: [PATCH 2/3] PAINTROID-614 Fix using LineTool too fast crashes the app sometimes. --- .../catrobat/paintroid/model/LayerModel.kt | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/model/LayerModel.kt b/Paintroid/src/main/java/org/catrobat/paintroid/model/LayerModel.kt index aea2ac33a7..5940115640 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/model/LayerModel.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/model/LayerModel.kt @@ -62,17 +62,20 @@ open class LayerModel : LayerContracts.Model { false } + @Synchronized override fun getBitmapOfAllLayers(): Bitmap? { - if (layers.isEmpty()) { - return null - } - val referenceBitmap = layers[0].bitmap - val bitmap = Bitmap.createBitmap(referenceBitmap.width, referenceBitmap.height, Bitmap.Config.ARGB_8888) - val canvas = bitmap?.let { Canvas(it) } + synchronized(this) { + if (layers.isEmpty()) { + return null + } + val referenceBitmap = layers[0].bitmap + val bitmap = Bitmap.createBitmap(referenceBitmap.width, referenceBitmap.height, Bitmap.Config.ARGB_8888) + val canvas = bitmap?.let { Canvas(it) } - drawLayersOntoCanvas(canvas) + drawLayersOntoCanvas(canvas) - return bitmap + return bitmap + } } override fun getBitmapListOfAllLayers(): List = layers.map { it.bitmap } From e51c31ceabeb8abbdfb77056b5ddea13d7f4a743 Mon Sep 17 00:00:00 2001 From: Rd <122200035+Rd4dev@users.noreply.github.com> Date: Fri, 21 Jul 2023 20:19:11 +0530 Subject: [PATCH 3/3] PAINTROID-607 Spraycan ignores alpha value (#1275) --- .../tools/BrushToolIntegrationTest.kt | 118 +++++++++++++++++- .../tools/SprayToolIntegrationTest.kt | 106 ++++++++++++++++ .../tools/implementation/SprayTool.kt | 15 +++ .../zoomwindow/DefaultZoomWindowController.kt | 35 +++--- 4 files changed, 251 insertions(+), 23 deletions(-) diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/BrushToolIntegrationTest.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/BrushToolIntegrationTest.kt index 9a9cb69561..58dfd3f1ad 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/BrushToolIntegrationTest.kt +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/BrushToolIntegrationTest.kt @@ -1,3 +1,5 @@ +package org.catrobat.paintroid.test.espresso.tools + /* * Paintroid: An image manipulation application for Android. * Copyright (C) 2010-2023 The Catrobat Team @@ -17,16 +19,29 @@ * along with this program. If not, see . */ -package org.catrobat.paintroid.test.espresso.tools - +import android.graphics.Color import android.os.Build import androidx.annotation.RequiresApi +import androidx.test.espresso.Espresso +import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 import org.catrobat.paintroid.MainActivity +import org.catrobat.paintroid.R +import org.catrobat.paintroid.test.espresso.util.BitmapLocationProvider import org.catrobat.paintroid.test.espresso.util.DrawingSurfaceLocationProvider +import org.catrobat.paintroid.test.espresso.util.UiInteractions import org.catrobat.paintroid.test.espresso.util.UiInteractions.swipeAccurate +import org.catrobat.paintroid.test.espresso.util.UiMatcher +import org.catrobat.paintroid.test.espresso.util.wrappers.ColorPickerViewInteraction.Companion.onColorPickerView import org.catrobat.paintroid.test.espresso.util.wrappers.DrawingSurfaceInteraction +import org.catrobat.paintroid.test.espresso.util.wrappers.ToolBarViewInteraction +import org.catrobat.paintroid.test.espresso.util.wrappers.ToolPropertiesInteraction +import org.catrobat.paintroid.test.utils.ScreenshotOnFailRule +import org.catrobat.paintroid.tools.ToolReference +import org.catrobat.paintroid.tools.ToolType +import org.hamcrest.Matchers import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Rule @@ -38,10 +53,14 @@ import org.junit.runner.RunWith class BrushToolIntegrationTest { private lateinit var activity: MainActivity + private var toolReference: ToolReference? = null @get:Rule var activityScenarioRule: ActivityScenarioRule = ActivityScenarioRule(MainActivity::class.java) + @get:Rule + var screenshotOnFailRule = ScreenshotOnFailRule() + private fun getActivity(): MainActivity { lateinit var activity: MainActivity activityScenarioRule.scenario.onActivity { @@ -53,6 +72,8 @@ class BrushToolIntegrationTest { @Before fun setUp() { activity = getActivity() + toolReference = activity.toolReference + ToolBarViewInteraction.onToolBarView().performSelectTool(ToolType.BRUSH) } @Test @@ -64,4 +85,97 @@ class BrushToolIntegrationTest { val updatedCommandCount = commandManager.getUndoCommandCount() assertEquals(previousCommandCount + 1, updatedCommandCount) } + + @Test + fun testBrushToolColor() { + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.BRUSH) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkPixelColor(Color.BLACK, BitmapLocationProvider.MIDDLE) + } + + @Test + fun testBrushToolTransparentColor() { + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.BRUSH) + onColorPickerView() + .performOpenColorPicker() + Espresso.onView( + Matchers.allOf( + withId(R.id.color_picker_tab_icon), + UiMatcher.withBackground(R.drawable.ic_color_picker_tab_preset) + ) + ).perform(ViewActions.click()) + Espresso.onView(withId(R.id.color_alpha_slider)).perform( + ViewActions.scrollTo(), + UiInteractions.touchCenterMiddle() + ) + Espresso.onView( + Matchers.allOf( + withId(R.id.color_picker_tab_icon), + UiMatcher.withBackground(R.drawable.ic_color_picker_tab_rgba) + ) + ).perform(ViewActions.click()) + onColorPickerView() + .onPositiveButton() + .perform(ViewActions.click()) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + + val selectedColor = toolReference?.tool?.drawPaint!!.color + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkPixelColor(selectedColor, BitmapLocationProvider.MIDDLE) + } + + @Test + fun testBrushToolWithHandleMoveColor() { + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.BRUSH) + ToolPropertiesInteraction.onToolProperties() + .setColor(Color.BLACK) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.swipe(DrawingSurfaceLocationProvider.MIDDLE, DrawingSurfaceLocationProvider.BOTTOM_MIDDLE)) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkPixelColor(Color.BLACK, BitmapLocationProvider.MIDDLE) + } + + @Test + fun testBrushToolWithHandleMoveTransparentColor() { + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.BRUSH) + onColorPickerView() + .performOpenColorPicker() + Espresso.onView( + Matchers.allOf( + withId(R.id.color_picker_tab_icon), + UiMatcher.withBackground(R.drawable.ic_color_picker_tab_preset) + ) + ).perform(ViewActions.click()) + Espresso.onView(withId(R.id.color_alpha_slider)).perform( + ViewActions.scrollTo(), + UiInteractions.touchCenterMiddle() + ) + Espresso.onView( + Matchers.allOf( + withId(R.id.color_picker_tab_icon), + UiMatcher.withBackground(R.drawable.ic_color_picker_tab_rgba) + ) + ).perform(ViewActions.click()) + onColorPickerView() + .onPositiveButton() + .perform(ViewActions.click()) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform( + UiInteractions.swipe( + DrawingSurfaceLocationProvider.MIDDLE, + DrawingSurfaceLocationProvider.BOTTOM_MIDDLE + ) + ) + + val selectedColor = toolReference?.tool?.drawPaint!!.color + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkPixelColor(selectedColor, BitmapLocationProvider.MIDDLE) + } } diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/SprayToolIntegrationTest.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/SprayToolIntegrationTest.kt index 3bc6d2223f..c09bb8fc8d 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/SprayToolIntegrationTest.kt +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/SprayToolIntegrationTest.kt @@ -18,7 +18,10 @@ */ package org.catrobat.paintroid.test.espresso.tools +import android.graphics.Color import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.replaceText import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.withId @@ -27,11 +30,20 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.rule.ActivityTestRule import org.catrobat.paintroid.MainActivity import org.catrobat.paintroid.R +import org.catrobat.paintroid.test.espresso.util.BitmapLocationProvider +import org.catrobat.paintroid.test.espresso.util.DrawingSurfaceLocationProvider +import org.catrobat.paintroid.test.espresso.util.UiInteractions +import org.catrobat.paintroid.test.espresso.util.UiMatcher import org.catrobat.paintroid.test.espresso.util.UiMatcher.withProgress +import org.catrobat.paintroid.test.espresso.util.wrappers.ColorPickerViewInteraction.Companion.onColorPickerView +import org.catrobat.paintroid.test.espresso.util.wrappers.DrawingSurfaceInteraction.Companion.onDrawingSurfaceView import org.catrobat.paintroid.test.espresso.util.wrappers.ToolBarViewInteraction +import org.catrobat.paintroid.test.espresso.util.wrappers.ToolPropertiesInteraction.Companion.onToolProperties import org.catrobat.paintroid.test.utils.ScreenshotOnFailRule +import org.catrobat.paintroid.tools.ToolReference import org.catrobat.paintroid.tools.ToolType import org.catrobat.paintroid.ui.tools.MIN_RADIUS +import org.hamcrest.Matchers.allOf import org.junit.Before import org.junit.Rule import org.junit.Test @@ -39,6 +51,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class SprayToolIntegrationTest { + private var toolReference: ToolReference? = null @get:Rule var launchActivityRule = ActivityTestRule(MainActivity::class.java) @@ -48,6 +61,7 @@ class SprayToolIntegrationTest { @Before fun setUp() { + toolReference = launchActivityRule.activity.toolReference ToolBarViewInteraction.onToolBarView().performSelectTool(ToolType.SPRAY) } @@ -63,6 +77,98 @@ class SprayToolIntegrationTest { } @Test + fun testSprayToolColor() { + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.SPRAY) + onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + onDrawingSurfaceView() + .checkPixelColor(Color.BLACK, BitmapLocationProvider.MIDDLE) + } + + @Test + fun testSprayToolTransparentColor() { + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.SPRAY) + onColorPickerView() + .performOpenColorPicker() + onView( + allOf( + withId(R.id.color_picker_tab_icon), + UiMatcher.withBackground(R.drawable.ic_color_picker_tab_preset) + ) + ).perform(click()) + onView(withId(R.id.color_alpha_slider)).perform( + ViewActions.scrollTo(), + UiInteractions.touchCenterMiddle() + ) + onView( + allOf( + withId(R.id.color_picker_tab_icon), + UiMatcher.withBackground(R.drawable.ic_color_picker_tab_rgba) + ) + ).perform(click()) + onColorPickerView() + .onPositiveButton() + .perform(click()) + onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + + val selectedColor = toolReference?.tool?.drawPaint!!.color + onDrawingSurfaceView() + .checkPixelColor(selectedColor, BitmapLocationProvider.MIDDLE) + } + + @Test + fun testSprayToolWithHandleMoveColor() { + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.SPRAY) + onToolProperties() + .setColor(Color.BLACK) + onDrawingSurfaceView() + .perform(UiInteractions.swipe(DrawingSurfaceLocationProvider.MIDDLE, DrawingSurfaceLocationProvider.BOTTOM_MIDDLE)) + onDrawingSurfaceView() + .checkPixelColor(Color.BLACK, BitmapLocationProvider.MIDDLE) + } + + @Test + fun testSprayToolWithHandleMoveTransparentColor() { + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.SPRAY) + onColorPickerView() + .performOpenColorPicker() + onView( + allOf( + withId(R.id.color_picker_tab_icon), + UiMatcher.withBackground(R.drawable.ic_color_picker_tab_preset) + ) + ).perform(click()) + onView(withId(R.id.color_alpha_slider)).perform( + ViewActions.scrollTo(), + UiInteractions.touchCenterMiddle() + ) + onView( + allOf( + withId(R.id.color_picker_tab_icon), + UiMatcher.withBackground(R.drawable.ic_color_picker_tab_rgba) + ) + ).perform(click()) + onColorPickerView() + .onPositiveButton() + .perform(click()) + onDrawingSurfaceView() + .perform( + UiInteractions.swipe( + DrawingSurfaceLocationProvider.MIDDLE, + DrawingSurfaceLocationProvider.BOTTOM_MIDDLE + ) + ) + + val selectedColor = toolReference?.tool?.drawPaint!!.color + onDrawingSurfaceView() + .checkPixelColor(selectedColor, BitmapLocationProvider.MIDDLE) + } + fun testSprayRadiusToStrokeWidthStaysConsistent() { ToolBarViewInteraction.onToolBarView().performSelectTool(ToolType.BRUSH) diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/SprayTool.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/SprayTool.kt index 75808958d2..5aff0d38a5 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/SprayTool.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/SprayTool.kt @@ -192,6 +192,13 @@ class SprayTool( sprayToolScope.launch { while (true) { repeat(sprayRadius / DEFAULT_RADIUS) { + if (sprayedPoints.isEmpty()) { + val midPoint = createMidPoint() + if (workspace.contains(midPoint)) { + previewCanvas.drawPoint(midPoint.x, midPoint.y, drawPaint) + sprayedPoints.add(midPoint) + } + } val point = createRandomPointInCircle() if (workspace.contains(point)) { previewCanvas.drawPoint(point.x, point.y, drawPaint) @@ -221,6 +228,14 @@ class SprayTool( return point } + private fun createMidPoint(): PointF { + val pointM = PointF() + + pointM.x = currentCoordinate?.x ?: 0f + pointM.y = currentCoordinate?.y ?: 0f + return pointM + } + fun resetRadiusToStrokeWidth() { toolPaint.strokeWidth = sprayToolOptionsView.getRadius() } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/ui/zoomwindow/DefaultZoomWindowController.kt b/Paintroid/src/main/java/org/catrobat/paintroid/ui/zoomwindow/DefaultZoomWindowController.kt index ca2cc76f44..4f2f3d8e9c 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/ui/zoomwindow/DefaultZoomWindowController.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/ui/zoomwindow/DefaultZoomWindowController.kt @@ -221,27 +221,20 @@ class DefaultZoomWindowController } override fun checkIfToolCompatibleWithZoomWindow(tool: Tool?): Constants { - if ( - tool?.toolType?.name.equals(ToolType.HAND.name) || - tool?.toolType?.name.equals(ToolType.FILL.name) || - tool?.toolType?.name.equals(ToolType.CLIPBOARD.name) || - tool?.toolType?.name.equals(ToolType.TRANSFORM.name) - ) { - return Constants.NOT_COMPATIBLE - } else if ( - tool?.toolType?.name.equals(ToolType.IMPORTPNG.name) || - tool?.toolType?.name.equals(ToolType.SHAPE.name) || - tool?.toolType?.name.equals(ToolType.TEXT.name) - ) { - return Constants.NOT_COMPATIBLE - } else if ( - tool?.toolType?.name.equals(ToolType.LINE.name) || - tool?.toolType?.name.equals(ToolType.CURSOR.name) || - tool?.toolType?.name.equals(ToolType.WATERCOLOR.name) - ) { - return Constants.COMPATIBLE_NEW - } else { - return Constants.COMPATIBLE_ALL + return when (tool?.toolType?.name) { + ToolType.HAND.name, + ToolType.FILL.name, + ToolType.CLIPBOARD.name, + ToolType.TRANSFORM.name, + ToolType.IMPORTPNG.name, + ToolType.SHAPE.name, + ToolType.TEXT.name -> Constants.NOT_COMPATIBLE + ToolType.LINE.name, + ToolType.CURSOR.name, + ToolType.WATERCOLOR.name, + ToolType.SPRAY.name, + ToolType.BRUSH.name -> Constants.COMPATIBLE_NEW + else -> Constants.COMPATIBLE_ALL } }