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
}
}