diff --git a/.github/workflows/sync_crowdin_colorpicker.yml b/.github/workflows/sync_crowdin_colorpicker.yml index 97b7756439..57db0caef4 100644 --- a/.github/workflows/sync_crowdin_colorpicker.yml +++ b/.github/workflows/sync_crowdin_colorpicker.yml @@ -12,7 +12,7 @@ # # - Secrets required! # -name: Synchronize Crowdin +name: Synchronize Color Picker Crowdin # # New base strings could be uploaded on the merge of a new feature. @@ -53,6 +53,9 @@ jobs: upload_translations: false download_translations: true config: 'crowdin_colorpicker.yml' + localization_branch_name: l10n_colorpicker_crowdin_action + create_pull_request: true + pull_request_title: 'New Colorpicker Crowdin translations by Github Action' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} diff --git a/Jenkinsfile b/Jenkinsfile index 0e30ef48d7..a1c7ff94c7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -56,7 +56,7 @@ pipeline { triggers { cron(env.BRANCH_NAME == 'develop' ? '@midnight' : '') - issueCommentTrigger('.*test this please.*') + issueCommentTrigger('.*(test this please|please test this).*') } stages { diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LayerIntegrationTest.java b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LayerIntegrationTest.java deleted file mode 100644 index 627ec6706d..0000000000 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LayerIntegrationTest.java +++ /dev/null @@ -1,752 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2021 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.test.espresso; - -import android.graphics.Color; - -import org.catrobat.paintroid.MainActivity; -import org.catrobat.paintroid.R; -import org.catrobat.paintroid.test.espresso.util.DrawingSurfaceLocationProvider; -import org.catrobat.paintroid.test.espresso.util.EspressoUtils; -import org.catrobat.paintroid.test.utils.ScreenshotOnFailRule; -import org.catrobat.paintroid.tools.ToolType; -import org.catrobat.paintroid.tools.Workspace; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.rule.ActivityTestRule; -import androidx.test.rule.GrantPermissionRule; - -import static org.catrobat.paintroid.test.espresso.util.UiInteractions.touchAt; -import static org.catrobat.paintroid.test.espresso.util.UiMatcher.withDrawable; -import static org.catrobat.paintroid.test.espresso.util.wrappers.DrawingSurfaceInteraction.onDrawingSurfaceView; -import static org.catrobat.paintroid.test.espresso.util.wrappers.LayerMenuViewInteraction.onLayerMenuView; -import static org.catrobat.paintroid.test.espresso.util.wrappers.ToolBarViewInteraction.onToolBarView; -import static org.catrobat.paintroid.test.espresso.util.wrappers.ToolPropertiesInteraction.onToolProperties; -import static org.catrobat.paintroid.test.espresso.util.wrappers.TopBarViewInteraction.onTopBarView; -import static org.catrobat.paintroid.test.espresso.util.wrappers.TransformToolOptionsViewInteraction.onTransformToolOptionsView; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.lessThan; -import static org.hamcrest.Matchers.not; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.RootMatchers.withDecorView; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; -import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; -import static androidx.test.espresso.matcher.ViewMatchers.withText; - -@RunWith(AndroidJUnit4.class) -public class LayerIntegrationTest { - - @Rule - public ActivityTestRule launchActivityRule = new ActivityTestRule<>(MainActivity.class); - - @Rule - public ScreenshotOnFailRule screenshotOnFailRule = new ScreenshotOnFailRule(); - - @ClassRule - public static GrantPermissionRule grantPermissionRule = EspressoUtils.grantPermissionRulesVersionCheck(); - - private int bitmapHeight; - private int bitmapWidth; - - @Before - public void setUp() { - Workspace workspace = launchActivityRule.getActivity().workspace; - bitmapHeight = workspace.getHeight(); - bitmapWidth = workspace.getWidth(); - } - - @Test - public void testShowLayerMenu() { - onLayerMenuView() - .performOpen() - .check(matches(isDisplayed())); - } - - @Test - public void testInitialSetup() { - onLayerMenuView() - .check(matches(not(isDisplayed()))); - onLayerMenuView().onButtonAdd() - .check(matches(allOf(isEnabled(), withDrawable(R.drawable.ic_pocketpaint_layers_add)))); - onLayerMenuView().onButtonDelete() - .check(matches(allOf(not(isEnabled()), withDrawable(R.drawable.ic_pocketpaint_layers_delete_disabled)))); - } - - @Test - public void testAddOneLayer() { - onLayerMenuView() - .checkLayerCount(1) - .performOpen() - .performAddLayer() - .checkLayerCount(2); - } - - @Test - public void testTryAddMoreLayersThanLimit() { - onLayerMenuView() - .checkLayerCount(1) - .performOpen() - .performAddLayer() - .performAddLayer() - .performAddLayer() - .checkLayerCount(4) - .performAddLayer() - .checkLayerCount(4); - } - - @Test - public void testButtonsAddOneLayer() { - onLayerMenuView() - .performOpen() - .performAddLayer() - .checkLayerCount(2); - - onLayerMenuView().onButtonAdd() - .check(matches(allOf(isEnabled(), withDrawable(R.drawable.ic_pocketpaint_layers_add)))); - onLayerMenuView().onButtonDelete() - .check(matches(allOf(isEnabled(), withDrawable(R.drawable.ic_pocketpaint_layers_delete)))); - - onLayerMenuView() - .performAddLayer() - .performAddLayer() - .checkLayerCount(4); - - onLayerMenuView().onButtonAdd() - .check(matches(allOf(not(isEnabled()), withDrawable(R.drawable.ic_pocketpaint_layers_add_disabled)))); - onLayerMenuView().onButtonDelete() - .check(matches(allOf(isEnabled(), withDrawable(R.drawable.ic_pocketpaint_layers_delete)))); - - onLayerMenuView() - .performDeleteLayer() - .performDeleteLayer() - .performDeleteLayer() - .checkLayerCount(1); - - onLayerMenuView().onButtonAdd() - .check(matches(allOf(isEnabled(), withDrawable(R.drawable.ic_pocketpaint_layers_add)))); - onLayerMenuView().onButtonDelete() - .check(matches(allOf(not(isEnabled()), withDrawable(R.drawable.ic_pocketpaint_layers_delete_disabled)))); - } - - @Test - public void testButtonsAfterNewImage() { - onLayerMenuView() - .performOpen() - .performAddLayer() - .performAddLayer() - .performAddLayer() - .performClose() - .checkLayerCount(4); - - onLayerMenuView().onButtonAdd() - .check(matches(allOf(not(isEnabled()), withDrawable(R.drawable.ic_pocketpaint_layers_add_disabled)))); - onLayerMenuView().onButtonDelete() - .check(matches(allOf(isEnabled(), withDrawable(R.drawable.ic_pocketpaint_layers_delete)))); - onTopBarView() - .performOpenMoreOptions(); - onView(withText(R.string.menu_new_image)) - .perform(click()); - onView(withText(R.string.discard_button_text)) - .perform(click()); - - onLayerMenuView().onButtonAdd() - .check(matches(allOf(isEnabled(), withDrawable(R.drawable.ic_pocketpaint_layers_add)))); - onLayerMenuView().onButtonDelete() - .check(matches(allOf(not(isEnabled()), withDrawable(R.drawable.ic_pocketpaint_layers_delete_disabled)))); - onLayerMenuView() - .checkLayerCount(1); - } - - @Test - public void testUndoRedoLayerAdd() { - onLayerMenuView() - .performOpen() - .performAddLayer() - .performClose() - .checkLayerCount(2); - - onTopBarView() - .performUndo(); - - onLayerMenuView() - .checkLayerCount(1); - - onTopBarView() - .performRedo(); - - onLayerMenuView() - .checkLayerCount(2); - } - - @Test - public void testDeleteEmptyLayer() { - onLayerMenuView() - .checkLayerCount(1) - .performOpen() - .performAddLayer() - .checkLayerCount(2) - .performDeleteLayer() - .checkLayerCount(1); - } - - @Ignore("Fail due to Pipette") - @Test - public void testDeleteFilledLayer() { - onLayerMenuView() - .checkLayerCount(1) - .performOpen() - .performAddLayer() - .performClose(); - - onToolBarView() - .performSelectTool(ToolType.PIPETTE); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - onToolProperties() - .checkMatchesColor(Color.TRANSPARENT); - - onToolBarView() - .performSelectTool(ToolType.FILL); - onToolProperties() - .setColor(Color.BLACK); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - - onToolBarView() - .performSelectTool(ToolType.PIPETTE); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - onToolProperties() - .checkMatchesColor(Color.BLACK); - - onLayerMenuView() - .checkLayerCount(2) - .performOpen() - .performDeleteLayer() - .performClose() - .checkLayerCount(1); - - onToolBarView() - .performSelectTool(ToolType.PIPETTE); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - onToolProperties() - .checkMatchesColor(Color.TRANSPARENT); - } - - @Test - public void testTryDeleteOnlyLayer() { - onLayerMenuView() - .checkLayerCount(1) - .performOpen() - .performDeleteLayer() - .checkLayerCount(1); - } - - @Ignore("Fail due to Pipette") - @Test - public void testSwitchBetweenFilledLayers() { - onToolBarView() - .performSelectTool(ToolType.FILL); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - onToolBarView() - .performSelectTool(ToolType.PIPETTE); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - onToolProperties() - .checkMatchesColor(Color.BLACK); - - onLayerMenuView() - .performOpen() - .performAddLayer() - .performClose(); - - onToolBarView() - .performSelectTool(ToolType.FILL); - onToolProperties() - .setColor(Color.WHITE); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - onToolBarView() - .performSelectTool(ToolType.PIPETTE); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - onToolProperties() - .checkMatchesColor(Color.WHITE); - - onLayerMenuView() - .performOpen() - .performSelectLayer(1) - .performClose(); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - onToolProperties() - .checkMatchesColor(Color.WHITE); - } - - @Ignore("Fail due to Pipette") - @Test - public void testMultipleLayersNewImageDiscardOld() { - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - - onLayerMenuView() - .performOpen() - .performAddLayer() - .performAddLayer() - .performAddLayer() - .checkLayerCount(4) - .performClose(); - - onTopBarView() - .performOpenMoreOptions(); - onView(withText(R.string.menu_new_image)) - .perform(click()); - onView(withText(R.string.discard_button_text)) - .perform(click()); - - onToolBarView() - .performSelectTool(ToolType.PIPETTE); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - onToolProperties() - .checkMatchesColor(Color.TRANSPARENT); - onLayerMenuView() - .checkLayerCount(1); - } - - @Ignore("Fail due to Pipette") - @Test - public void testMultipleLayersNewImageSaveOld() { - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - - onLayerMenuView() - .performOpen() - .performAddLayer() - .performAddLayer() - .performAddLayer() - .checkLayerCount(4) - .performClose(); - - onTopBarView() - .performOpenMoreOptions(); - onView(withText(R.string.menu_new_image)) - .perform(click()); - onView(withText(R.string.save_button_text)) - .perform(click()); - onView(withText(R.string.save_button_text)) - .perform(click()); - - onToolBarView() - .performSelectTool(ToolType.PIPETTE); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - - onToolProperties() - .checkMatchesColor(Color.TRANSPARENT); - - onLayerMenuView() - .checkLayerCount(1); - } - - @Test - public void testResizingThroughAllLayers() { - onLayerMenuView() - .performOpen() - .performAddLayer() - .performAddLayer() - .performAddLayer() - .performClose(); - - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - - onToolBarView() - .performSelectTool(ToolType.TRANSFORM); - onTransformToolOptionsView() - .performAutoCrop(); - - onTopBarView() - .performClickCheckmark(); - - onDrawingSurfaceView() - .checkThatLayerDimensions(lessThan(bitmapWidth), lessThan(bitmapHeight)); - - onTopBarView() - .performUndo(); - - onDrawingSurfaceView() - .checkLayerDimensions(bitmapWidth, bitmapHeight); - - onTopBarView() - .performRedo(); - - onDrawingSurfaceView() - .checkThatLayerDimensions(lessThan(bitmapWidth), lessThan(bitmapHeight)); - - onLayerMenuView() - .performOpen() - .performSelectLayer(2) - .performClose(); - - onTopBarView() - .performUndo() - .performUndo(); - - onDrawingSurfaceView() - .checkLayerDimensions(bitmapWidth, bitmapHeight); - - onLayerMenuView() - .performOpen() - .performSelectLayer(3) - .performClose(); - - onToolBarView() - .performOpenToolOptionsView(); - onTransformToolOptionsView() - .performAutoCrop(); - onTopBarView() - .performClickCheckmark(); - - onDrawingSurfaceView() - .checkThatLayerDimensions(lessThan(bitmapWidth), lessThan(bitmapHeight)); - - onLayerMenuView() - .performOpen() - .performDeleteLayer() - .performAddLayer() - .performClose(); - - onTopBarView() - .performUndo() - .performUndo() - .performUndo(); - - onDrawingSurfaceView() - .checkLayerDimensions(bitmapWidth, bitmapHeight); - - onTopBarView() - .performRedo(); - - onDrawingSurfaceView() - .checkThatLayerDimensions(lessThan(bitmapWidth), lessThan(bitmapHeight)); - } - - @Ignore("Fail due to Pipette") - @Test - public void testRotatingThroughAllLayers() { - onLayerMenuView() - .performOpen() - .performAddLayer() - .performAddLayer() - .performAddLayer() - .performClose(); - - onToolBarView() - .performSelectTool(ToolType.FILL); - - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - - onToolBarView() - .performSelectTool(ToolType.TRANSFORM); - onTransformToolOptionsView() - .performRotateClockwise(); - - onDrawingSurfaceView() - .checkLayerDimensions(bitmapHeight, bitmapWidth); - - onToolBarView() - .performSelectTool(ToolType.PIPETTE); - - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - - onToolProperties() - .checkMatchesColor(Color.BLACK); - - onToolBarView() - .performSelectTool(ToolType.TRANSFORM); - onTransformToolOptionsView() - .performRotateCounterClockwise() - .performRotateCounterClockwise(); - - onDrawingSurfaceView() - .checkLayerDimensions(bitmapHeight, bitmapWidth); - - onToolBarView() - .performSelectTool(ToolType.PIPETTE); - - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - - onToolProperties() - .checkMatchesColor(Color.BLACK); - } - - @Ignore("Fail due to Pipette") - @Test - public void testReflectingOnlyCurrentLayer() { - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.HALFWAY_LEFT_MIDDLE)); - - onLayerMenuView() - .performOpen() - .performAddLayer() - .performClose(); - - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.HALFWAY_RIGHT_MIDDLE)); - - onToolBarView() - .performSelectTool(ToolType.TRANSFORM); - onTransformToolOptionsView() - .performFlipVertical(); - - onToolBarView().performSelectTool(ToolType.PIPETTE); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.HALFWAY_RIGHT_MIDDLE)); - onToolProperties() - .checkMatchesColor(Color.TRANSPARENT); - - onTopBarView() - .performUndo(); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.HALFWAY_RIGHT_MIDDLE)); - onToolProperties() - .checkMatchesColor(Color.BLACK); - - onTopBarView() - .performRedo(); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.HALFWAY_RIGHT_MIDDLE)); - onToolProperties() - .checkMatchesColor(Color.TRANSPARENT); - } - - @Test - public void testUndoRedoLayerDelete() { - onLayerMenuView() - .performOpen() - .performAddLayer() - .checkLayerCount(2) - .performDeleteLayer() - .checkLayerCount(1) - .performClose(); - - onTopBarView() - .performUndo(); - - onLayerMenuView() - .checkLayerCount(2); - - onTopBarView() - .performRedo(); - - onLayerMenuView() - .checkLayerCount(1); - } - - @Ignore("Fail due to Pipette") - @Test - public void testLayerOrderUndoDelete() { - onToolBarView() - .performSelectTool(ToolType.FILL); - - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - - onLayerMenuView() - .performOpen() - .performAddLayer() - .checkLayerCount(2) - .performClose(); - - onToolProperties() - .setColorResource(R.color.pocketpaint_color_picker_green1) - .checkMatchesColorResource(R.color.pocketpaint_color_picker_green1); - - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - - onLayerMenuView() - .performOpen() - .performSelectLayer(1) - .performDeleteLayer() - .performClose() - .checkLayerCount(1); - - onTopBarView() - .performUndo(); - - onLayerMenuView() - .checkLayerCount(2); - - onToolBarView() - .performSelectTool(ToolType.PIPETTE); - onDrawingSurfaceView() - .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); - onToolProperties() - .checkMatchesColorResource(R.color.pocketpaint_color_picker_green1); - } - - @Test - public void testUndoRedoLayerRotate() { - onLayerMenuView() - .performOpen() - .performAddLayer() - .performAddLayer() - .performAddLayer() - .performClose(); - - onToolBarView() - .performSelectTool(ToolType.TRANSFORM); - onTransformToolOptionsView() - .performRotateClockwise(); - - onDrawingSurfaceView() - .checkLayerDimensions(bitmapHeight, bitmapWidth); - - onToolBarView() - .performCloseToolOptionsView(); - onTopBarView() - .performUndo(); - - onDrawingSurfaceView() - .checkLayerDimensions(bitmapWidth, bitmapHeight); - - onTopBarView() - .performRedo(); - - onDrawingSurfaceView() - .checkLayerDimensions(bitmapHeight, bitmapWidth); - - onLayerMenuView() - .performOpen() - .performDeleteLayer() - .performAddLayer() - .performSelectLayer(3) - .performClose(); - - onTopBarView() - .performUndo() - .performUndo() - .performUndo() - .performUndo(); - - onDrawingSurfaceView() - .checkLayerDimensions(bitmapWidth, bitmapHeight); - - onTopBarView() - .performRedo(); - - onDrawingSurfaceView() - .checkLayerDimensions(bitmapHeight, bitmapWidth); - } - - @Test - public void testHideLayer() { - onLayerMenuView() - .performOpen() - .performAddLayer() - .checkLayerCount(2) - .performClose(); - - onToolBarView() - .performSelectTool(ToolType.FILL); - - onDrawingSurfaceView().perform(click()); - onDrawingSurfaceView().checkPixelColor(Color.BLACK, 1, 1); - - onLayerMenuView() - .performOpen() - .perfomToggleLayerVisibility(0) - .performClose(); - - onDrawingSurfaceView().checkPixelColor(Color.TRANSPARENT, 1, 1); - } - - @Test - public void testHideThenUnhideLayer() { - onLayerMenuView() - .performOpen() - .performAddLayer() - .checkLayerCount(2) - .performClose(); - - onToolBarView() - .performSelectTool(ToolType.FILL); - - onDrawingSurfaceView().perform(click()); - onDrawingSurfaceView().checkPixelColor(Color.BLACK, 1, 1); - - onLayerMenuView() - .performOpen() - .perfomToggleLayerVisibility(0) - .performClose(); - - onDrawingSurfaceView().checkPixelColor(Color.TRANSPARENT, 1, 1); - - onLayerMenuView() - .performOpen() - .perfomToggleLayerVisibility(0) - .performClose(); - - onDrawingSurfaceView().checkPixelColor(Color.BLACK, 1, 1); - } - - @Test - public void testTryMergeOrReorderWhileALayerIsHidden() { - onLayerMenuView() - .performOpen() - .performAddLayer() - .checkLayerCount(2) - .perfomToggleLayerVisibility(0) - .performLongClickLayer(0); - - onView(withText(R.string.no_longclick_on_hidden_layer)).inRoot(withDecorView(not(launchActivityRule.getActivity().getWindow().getDecorView()))).check(matches(isDisplayed())); - } - - @Test - public void testTryChangeToolWhileALayerIsHidden() { - onLayerMenuView() - .performOpen() - .performAddLayer() - .checkLayerCount(2) - .perfomToggleLayerVisibility(0) - .performClose(); - - onToolBarView() - .onToolsClicked(); - - onView(withText(R.string.no_tools_on_hidden_layer)).inRoot(withDecorView(not(launchActivityRule.getActivity().getWindow().getDecorView()))).check(matches(isDisplayed())); - } -} diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LayerIntegrationTest.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LayerIntegrationTest.kt new file mode 100644 index 0000000000..6541f3322f --- /dev/null +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LayerIntegrationTest.kt @@ -0,0 +1,693 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.test.espresso + +import android.app.Activity +import android.app.Instrumentation.ActivityResult +import android.content.Intent +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Color +import android.net.Uri +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.assertion.ViewAssertions +import androidx.test.espresso.intent.Intents +import androidx.test.espresso.intent.matcher.IntentMatchers +import androidx.test.espresso.matcher.RootMatchers +import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.rule.ActivityTestRule +import androidx.test.rule.GrantPermissionRule +import org.catrobat.paintroid.MainActivity +import org.catrobat.paintroid.R +import org.catrobat.paintroid.common.Constants +import org.catrobat.paintroid.test.espresso.util.* +import org.catrobat.paintroid.test.espresso.util.wrappers.* +import org.catrobat.paintroid.test.utils.ScreenshotOnFailRule +import org.catrobat.paintroid.tools.ToolType +import org.hamcrest.Matchers +import org.junit.* +import org.junit.runner.RunWith +import java.io.File +import kotlin.collections.ArrayList + +@RunWith(AndroidJUnit4::class) +class LayerIntegrationTest { + @get:Rule + var launchActivityRule = ActivityTestRule(MainActivity::class.java) + + @get:Rule + var screenshotOnFailRule = ScreenshotOnFailRule() + + @get:Rule + var grantPermissionRule: GrantPermissionRule = EspressoUtils.grantPermissionRulesVersionCheck() + + private var bitmapHeight = 0 + private var bitmapWidth = 0 + private lateinit var deletionFileList: ArrayList + + @Before + fun setUp() { + deletionFileList = ArrayList() + val workspace = launchActivityRule.activity.workspace + bitmapHeight = workspace.height + bitmapWidth = workspace.width + } + + @After + fun tearDown() { + deletionFileList.forEach { file -> + if (file != null && file.exists()) { + Assert.assertTrue(file.delete()) + } + } + } + + @Test + fun testShowLayerMenu() { + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + } + + @Test + fun testInitialSetup() { + LayerMenuViewInteraction.onLayerMenuView() + .check(ViewAssertions.matches(Matchers.not(ViewMatchers.isDisplayed()))) + LayerMenuViewInteraction.onLayerMenuView().onButtonAdd() + .check(ViewAssertions.matches(Matchers.allOf(ViewMatchers.isEnabled(), UiMatcher.withDrawable(R.drawable.ic_pocketpaint_layers_add)))) + LayerMenuViewInteraction.onLayerMenuView().onButtonDelete() + .check(ViewAssertions.matches(Matchers.allOf(Matchers.not(ViewMatchers.isEnabled()), UiMatcher.withDrawable(R.drawable.ic_pocketpaint_layers_delete_disabled)))) + } + + @Test + fun testAddOneLayer() { + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(1) + .performOpen() + .performAddLayer() + .checkLayerCount(2) + } + + @Test + fun testTryAddMoreLayersThanLimit() { + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(1) + .performOpen() + .performAddLayer() + .performAddLayer() + .performAddLayer() + .checkLayerCount(4) + .performAddLayer() + .checkLayerCount(4) + } + + @Test + fun testButtonsAddOneLayer() { + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .checkLayerCount(2) + LayerMenuViewInteraction.onLayerMenuView().onButtonAdd() + .check(ViewAssertions.matches(Matchers.allOf(ViewMatchers.isEnabled(), UiMatcher.withDrawable(R.drawable.ic_pocketpaint_layers_add)))) + LayerMenuViewInteraction.onLayerMenuView().onButtonDelete() + .check(ViewAssertions.matches(Matchers.allOf(ViewMatchers.isEnabled(), UiMatcher.withDrawable(R.drawable.ic_pocketpaint_layers_delete)))) + LayerMenuViewInteraction.onLayerMenuView() + .performAddLayer() + .performAddLayer() + .checkLayerCount(4) + LayerMenuViewInteraction.onLayerMenuView().onButtonAdd() + .check(ViewAssertions.matches(Matchers.allOf(Matchers.not(ViewMatchers.isEnabled()), UiMatcher.withDrawable(R.drawable.ic_pocketpaint_layers_add_disabled)))) + LayerMenuViewInteraction.onLayerMenuView().onButtonDelete() + .check(ViewAssertions.matches(Matchers.allOf(ViewMatchers.isEnabled(), UiMatcher.withDrawable(R.drawable.ic_pocketpaint_layers_delete)))) + LayerMenuViewInteraction.onLayerMenuView() + .performDeleteLayer() + .performDeleteLayer() + .performDeleteLayer() + .checkLayerCount(1) + LayerMenuViewInteraction.onLayerMenuView().onButtonAdd() + .check(ViewAssertions.matches(Matchers.allOf(ViewMatchers.isEnabled(), UiMatcher.withDrawable(R.drawable.ic_pocketpaint_layers_add)))) + LayerMenuViewInteraction.onLayerMenuView().onButtonDelete() + .check(ViewAssertions.matches(Matchers.allOf(Matchers.not(ViewMatchers.isEnabled()), UiMatcher.withDrawable(R.drawable.ic_pocketpaint_layers_delete_disabled)))) + } + + @Test + fun testButtonsAfterNewImage() { + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .performAddLayer() + .performAddLayer() + .performClose() + .checkLayerCount(4) + LayerMenuViewInteraction.onLayerMenuView().onButtonAdd() + .check(ViewAssertions.matches(Matchers.allOf(Matchers.not(ViewMatchers.isEnabled()), UiMatcher.withDrawable(R.drawable.ic_pocketpaint_layers_add_disabled)))) + LayerMenuViewInteraction.onLayerMenuView().onButtonDelete() + .check(ViewAssertions.matches(Matchers.allOf(ViewMatchers.isEnabled(), UiMatcher.withDrawable(R.drawable.ic_pocketpaint_layers_delete)))) + TopBarViewInteraction.onTopBarView() + .performOpenMoreOptions() + onView(withText(R.string.menu_new_image)) + .perform(click()) + onView(withText(R.string.discard_button_text)) + .perform(click()) + LayerMenuViewInteraction.onLayerMenuView().onButtonAdd() + .check(ViewAssertions.matches(Matchers.allOf(ViewMatchers.isEnabled(), UiMatcher.withDrawable(R.drawable.ic_pocketpaint_layers_add)))) + LayerMenuViewInteraction.onLayerMenuView().onButtonDelete() + .check(ViewAssertions.matches(Matchers.allOf(Matchers.not(ViewMatchers.isEnabled()), UiMatcher.withDrawable(R.drawable.ic_pocketpaint_layers_delete_disabled)))) + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(1) + } + + @Test + fun testUndoRedoLayerAdd() { + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .performClose() + .checkLayerCount(2) + TopBarViewInteraction.onTopBarView() + .performUndo() + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(1) + TopBarViewInteraction.onTopBarView() + .performRedo() + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(2) + } + + @Test + fun testDeleteEmptyLayer() { + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(1) + .performOpen() + .performAddLayer() + .checkLayerCount(2) + .performDeleteLayer() + .checkLayerCount(1) + } + + @Ignore("Fail due to Pipette") + @Test + fun testDeleteFilledLayer() { + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(1) + .performOpen() + .performAddLayer() + .performClose() + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.PIPETTE) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.TRANSPARENT) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.FILL) + ToolPropertiesInteraction.onToolProperties() + .setColor(Color.BLACK) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.PIPETTE) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.BLACK) + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(2) + .performOpen() + .performDeleteLayer() + .performClose() + .checkLayerCount(1) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.PIPETTE) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.TRANSPARENT) + } + + @Test + fun testTryDeleteOnlyLayer() { + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(1) + .performOpen() + .performDeleteLayer() + .checkLayerCount(1) + } + + @Ignore("Fail due to Pipette") + @Test + fun testSwitchBetweenFilledLayers() { + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.FILL) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.PIPETTE) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.BLACK) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .performClose() + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.FILL) + ToolPropertiesInteraction.onToolProperties() + .setColor(Color.WHITE) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.PIPETTE) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.WHITE) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performSelectLayer(1) + .performClose() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.WHITE) + } + + @Ignore("Fail due to Pipette") + @Test + fun testMultipleLayersNewImageDiscardOld() { + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .performAddLayer() + .performAddLayer() + .checkLayerCount(4) + .performClose() + TopBarViewInteraction.onTopBarView() + .performOpenMoreOptions() + onView(withText(R.string.menu_new_image)) + .perform(click()) + onView(withText(R.string.discard_button_text)) + .perform(click()) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.PIPETTE) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.TRANSPARENT) + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(1) + } + + @Ignore("Fail due to Pipette") + @Test + fun testMultipleLayersNewImageSaveOld() { + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .performAddLayer() + .performAddLayer() + .checkLayerCount(4) + .performClose() + TopBarViewInteraction.onTopBarView() + .performOpenMoreOptions() + onView(withText(R.string.menu_new_image)) + .perform(click()) + onView(withText(R.string.save_button_text)) + .perform(click()) + onView(withText(R.string.save_button_text)) + .perform(click()) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.PIPETTE) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.TRANSPARENT) + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(1) + } + + @Test + fun testResizingThroughAllLayers() { + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .performAddLayer() + .performAddLayer() + .performClose() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.TRANSFORM) + TransformToolOptionsViewInteraction.onTransformToolOptionsView() + .performAutoCrop() + TopBarViewInteraction.onTopBarView() + .performClickCheckmark() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkThatLayerDimensions(Matchers.lessThan(bitmapWidth), Matchers.lessThan(bitmapHeight)) + TopBarViewInteraction.onTopBarView() + .performUndo() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkLayerDimensions(bitmapWidth, bitmapHeight) + TopBarViewInteraction.onTopBarView() + .performRedo() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkThatLayerDimensions(Matchers.lessThan(bitmapWidth), Matchers.lessThan(bitmapHeight)) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performSelectLayer(2) + .performClose() + TopBarViewInteraction.onTopBarView() + .performUndo() + .performUndo() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkLayerDimensions(bitmapWidth, bitmapHeight) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performSelectLayer(3) + .performClose() + ToolBarViewInteraction.onToolBarView() + .performOpenToolOptionsView() + TransformToolOptionsViewInteraction.onTransformToolOptionsView() + .performAutoCrop() + TopBarViewInteraction.onTopBarView() + .performClickCheckmark() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkThatLayerDimensions(Matchers.lessThan(bitmapWidth), Matchers.lessThan(bitmapHeight)) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performDeleteLayer() + .performAddLayer() + .performClose() + TopBarViewInteraction.onTopBarView() + .performUndo() + .performUndo() + .performUndo() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkLayerDimensions(bitmapWidth, bitmapHeight) + TopBarViewInteraction.onTopBarView() + .performRedo() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkThatLayerDimensions(Matchers.lessThan(bitmapWidth), Matchers.lessThan(bitmapHeight)) + } + + @Ignore("Fail due to Pipette") + @Test + fun testRotatingThroughAllLayers() { + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .performAddLayer() + .performAddLayer() + .performClose() + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.FILL) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.TRANSFORM) + TransformToolOptionsViewInteraction.onTransformToolOptionsView() + .performRotateClockwise() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkLayerDimensions(bitmapHeight, bitmapWidth) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.PIPETTE) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.BLACK) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.TRANSFORM) + TransformToolOptionsViewInteraction.onTransformToolOptionsView() + .performRotateCounterClockwise() + .performRotateCounterClockwise() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkLayerDimensions(bitmapHeight, bitmapWidth) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.PIPETTE) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.BLACK) + } + + @Ignore("Fail due to Pipette") + @Test + fun testReflectingOnlyCurrentLayer() { + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.HALFWAY_LEFT_MIDDLE)) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .performClose() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.HALFWAY_RIGHT_MIDDLE)) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.TRANSFORM) + TransformToolOptionsViewInteraction.onTransformToolOptionsView() + .performFlipVertical() + ToolBarViewInteraction.onToolBarView().performSelectTool(ToolType.PIPETTE) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.HALFWAY_RIGHT_MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.TRANSPARENT) + TopBarViewInteraction.onTopBarView() + .performUndo() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.HALFWAY_RIGHT_MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.BLACK) + TopBarViewInteraction.onTopBarView() + .performRedo() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.HALFWAY_RIGHT_MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColor(Color.TRANSPARENT) + } + + @Test + fun testUndoRedoLayerDelete() { + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .checkLayerCount(2) + .performDeleteLayer() + .checkLayerCount(1) + .performClose() + TopBarViewInteraction.onTopBarView() + .performUndo() + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(2) + TopBarViewInteraction.onTopBarView() + .performRedo() + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(1) + } + + @Ignore("Fail due to Pipette") + @Test + fun testLayerOrderUndoDelete() { + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.FILL) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .checkLayerCount(2) + .performClose() + ToolPropertiesInteraction.onToolProperties() + .setColorResource(R.color.pocketpaint_color_picker_green1) + .checkMatchesColorResource(R.color.pocketpaint_color_picker_green1) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performSelectLayer(1) + .performDeleteLayer() + .performClose() + .checkLayerCount(1) + TopBarViewInteraction.onTopBarView() + .performUndo() + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(2) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.PIPETTE) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + ToolPropertiesInteraction.onToolProperties() + .checkMatchesColorResource(R.color.pocketpaint_color_picker_green1) + } + + @Test + fun testUndoRedoLayerRotate() { + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .performAddLayer() + .performAddLayer() + .performClose() + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.TRANSFORM) + TransformToolOptionsViewInteraction.onTransformToolOptionsView() + .performRotateClockwise() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkLayerDimensions(bitmapHeight, bitmapWidth) + ToolBarViewInteraction.onToolBarView() + .performCloseToolOptionsView() + TopBarViewInteraction.onTopBarView() + .performUndo() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkLayerDimensions(bitmapWidth, bitmapHeight) + TopBarViewInteraction.onTopBarView() + .performRedo() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkLayerDimensions(bitmapHeight, bitmapWidth) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performDeleteLayer() + .performAddLayer() + .performSelectLayer(3) + .performClose() + TopBarViewInteraction.onTopBarView() + .performUndo() + .performUndo() + .performUndo() + .performUndo() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkLayerDimensions(bitmapWidth, bitmapHeight) + TopBarViewInteraction.onTopBarView() + .performRedo() + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkLayerDimensions(bitmapHeight, bitmapWidth) + } + + @Test + fun testHideLayer() { + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .checkLayerCount(2) + .performClose() + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.FILL) + DrawingSurfaceInteraction.onDrawingSurfaceView().perform(click()) + DrawingSurfaceInteraction.onDrawingSurfaceView().checkPixelColor(Color.BLACK, 1f, 1f) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .perfomToggleLayerVisibility(0) + .performClose() + DrawingSurfaceInteraction.onDrawingSurfaceView().checkPixelColor(Color.TRANSPARENT, 1f, 1f) + } + + @Test + fun testHideThenUnhideLayer() { + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .checkLayerCount(2) + .performClose() + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.FILL) + DrawingSurfaceInteraction.onDrawingSurfaceView().perform(click()) + DrawingSurfaceInteraction.onDrawingSurfaceView().checkPixelColor(Color.BLACK, 1f, 1f) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .perfomToggleLayerVisibility(0) + .performClose() + DrawingSurfaceInteraction.onDrawingSurfaceView().checkPixelColor(Color.TRANSPARENT, 1f, 1f) + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .perfomToggleLayerVisibility(0) + .performClose() + DrawingSurfaceInteraction.onDrawingSurfaceView().checkPixelColor(Color.BLACK, 1f, 1f) + } + + @Test + fun testTryMergeOrReorderWhileALayerIsHidden() { + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .checkLayerCount(2) + .perfomToggleLayerVisibility(0) + .performLongClickLayer(0) + onView(withText(R.string.no_longclick_on_hidden_layer)).inRoot(RootMatchers.withDecorView(Matchers.not(launchActivityRule.activity.window.decorView))).check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + } + + @Test + fun testTryChangeToolWhileALayerIsHidden() { + LayerMenuViewInteraction.onLayerMenuView() + .performOpen() + .performAddLayer() + .checkLayerCount(2) + .perfomToggleLayerVisibility(0) + .performClose() + ToolBarViewInteraction.onToolBarView() + .onToolsClicked() + onView(withText(R.string.no_tools_on_hidden_layer)).inRoot(RootMatchers.withDecorView(Matchers.not(launchActivityRule.activity.window.decorView))).check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + } + + @Test + fun testLoadLargeBitmapAndAddMaxLayerMenu() { + val intent = Intent().apply { + data = createTestImageFile() + } + Intents.init() + val intentResult = ActivityResult(Activity.RESULT_OK, intent) + + Intents.intending(IntentMatchers.anyIntent()).respondWith(intentResult) + TopBarViewInteraction.onTopBarView() + .performOpenMoreOptions() + onView(withText(R.string.menu_load_image)).perform(click()) + Intents.release() + onView(withText(R.string.dialog_warning_new_image)).check(ViewAssertions.doesNotExist()) + onView(withText(R.string.pocketpaint_ok)).perform(click()) + DrawingSurfaceInteraction.onDrawingSurfaceView() + .checkPixelColor(Color.BLACK, BitmapLocationProvider.MIDDLE) + LayerMenuViewInteraction.onLayerMenuView() + .checkLayerCount(1) + .performOpen() + .performAddLayer() + .performAddLayer() + .performAddLayer() + .checkLayerCount(Constants.MAX_LAYERS) + } + + private fun createTestImageFile(): Uri { + val bitmap = Bitmap.createBitmap(7000, 7000, Bitmap.Config.ARGB_8888) + with(Canvas(bitmap)) { + drawColor(Color.BLACK) + drawBitmap(bitmap, 0f, 0f, null) + } + val imageFile = File(launchActivityRule.activity.getExternalFilesDir(null)!!.absolutePath, "loadImage.jpg") + val imageUri = Uri.fromFile(imageFile) + launchActivityRule.activity.contentResolver.openOutputStream((imageUri)).use { fos -> + Assert.assertTrue(bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos)) + } + deletionFileList.add(imageFile) + return imageUri + } +} diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/MainActivityIntegrationTest.java b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/MainActivityIntegrationTest.java index be67cea7c4..7e6b5c9f0a 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/MainActivityIntegrationTest.java +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/MainActivityIntegrationTest.java @@ -19,20 +19,27 @@ package org.catrobat.paintroid.test.espresso; +import android.app.Activity; import android.content.Context; import org.catrobat.paintroid.MainActivity; import org.catrobat.paintroid.R; +import org.catrobat.paintroid.contract.MainActivityContracts; +import org.catrobat.paintroid.presenter.MainActivityPresenter; import org.catrobat.paintroid.test.utils.ScreenshotOnFailRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; import static org.catrobat.paintroid.test.espresso.util.wrappers.TopBarViewInteraction.onTopBarView; +import static org.mockito.Mockito.verify; import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.Espresso.pressBack; @@ -45,6 +52,12 @@ @RunWith(AndroidJUnit4.class) public class MainActivityIntegrationTest { + @Mock + private MainActivityContracts.MainView view; + + @InjectMocks + private MainActivityPresenter presenter; + @Rule public ActivityTestRule launchActivityRule = new ActivityTestRule<>(MainActivity.class); @@ -81,4 +94,12 @@ public void testMoreOptionsMenuAboutClosesMoreOptions() { onView(withText(R.string.pocketpaint_menu_about)) .check(doesNotExist()); } + + @Test + public void testHandleActivityResultWhenIntentIsNull() { + launchActivityRule.getActivity().onActivityResult(0, Activity.RESULT_OK, null); + MockitoAnnotations.initMocks(this); + presenter.handleActivityResult(0, Activity.RESULT_OK, null); + verify(view).superHandleActivityResult(0, Activity.RESULT_OK, null); + } } diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/MenuFileActivityIntegrationTest.java b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/MenuFileActivityIntegrationTest.java index 2e66409b3d..1e845f010e 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/MenuFileActivityIntegrationTest.java +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/MenuFileActivityIntegrationTest.java @@ -63,6 +63,7 @@ import static org.catrobat.paintroid.test.espresso.util.wrappers.DrawingSurfaceInteraction.onDrawingSurfaceView; import static org.catrobat.paintroid.test.espresso.util.wrappers.ToolBarViewInteraction.onToolBarView; import static org.catrobat.paintroid.test.espresso.util.wrappers.TopBarViewInteraction.onTopBarView; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.core.AllOf.allOf; @@ -87,6 +88,7 @@ import static androidx.test.espresso.matcher.ViewMatchers.isClickable; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withSpinnerText; import static androidx.test.espresso.matcher.ViewMatchers.withText; @RunWith(AndroidJUnit4.class) @@ -554,6 +556,61 @@ public void testCheckSaveFileWithDifferentFormats() { assertNotSame(oldFile, newFile); } + @Test + public void testCheckSaveImageDialogShowJPGSpinnerText() { + + createImageIntent(); + + onTopBarView() + .performOpenMoreOptions(); + + onView(withText(R.string.menu_load_image)).perform(click()); + onView(withText(R.string.dialog_warning_new_image)).check(doesNotExist()); + onDrawingSurfaceView() + .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); + + onTopBarView() + .performOpenMoreOptions(); + + onView(withText(R.string.menu_save_image)) + .perform(click()); + + onView(withId(R.id.pocketpaint_save_dialog_spinner)) + .check(matches(withSpinnerText(containsString("jpg")))); + } + + @Test + public void testCheckSaveImageDialogShowPNGSpinnerText() { + FileIO.compressFormat = Bitmap.CompressFormat.PNG; + onDrawingSurfaceView() + .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); + + onTopBarView() + .performOpenMoreOptions(); + + onView(withText(R.string.menu_save_image)) + .perform(click()); + + onView(withId(R.id.pocketpaint_save_dialog_spinner)) + .check(matches(withSpinnerText(containsString("png")))); + } + + @Test + public void testCheckSaveImageDialogShowORASpinnerText() { + FileIO.isCatrobatImage = true; + onDrawingSurfaceView() + .perform(touchAt(DrawingSurfaceLocationProvider.MIDDLE)); + + onTopBarView() + .performOpenMoreOptions(); + + onView(withText(R.string.menu_save_image)) + .perform(click()); + + onView(withId(R.id.pocketpaint_save_dialog_spinner)) + .check(matches(withSpinnerText(containsString("ora")))); + } + @Test public void testCheckSaveImageDialogShowsSavedImageOptions() { onDrawingSurfaceView() @@ -628,6 +685,13 @@ public void testCheckCopyIsAlwaysDefaultOptions() { .check(matches(isDisplayed())); } + private void createImageIntent() { + Intent intent = new Intent(); + intent.setData(createTestImageFile()); + Instrumentation.ActivityResult resultOK = new Instrumentation.ActivityResult(Activity.RESULT_OK, intent); + intending(hasAction(Intent.ACTION_GET_CONTENT)).respondWith(resultOK); + } + private Uri createTestImageFile() { Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888); diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/OraFileIntentTest.java b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/OraFileIntentTest.java new file mode 100644 index 0000000000..eb1cb39365 --- /dev/null +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/OraFileIntentTest.java @@ -0,0 +1,152 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.catrobat.paintroid.test.espresso; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.provider.MediaStore; +import android.util.Log; + +import org.catrobat.paintroid.FileIO; +import org.catrobat.paintroid.MainActivity; +import org.catrobat.paintroid.tools.ToolType; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Objects; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.rule.ActivityTestRule; + +import static org.catrobat.paintroid.test.espresso.util.wrappers.ToolBarViewInteraction.onToolBarView; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +@RunWith(AndroidJUnit4.class) +public class OraFileIntentTest { + private static ArrayList deletionFileList = null; + @Rule + public ActivityTestRule launchActivityRule = new ActivityTestRule<>(MainActivity.class); + private ContentResolver resolver; + + @Before + public void setUp() { + onToolBarView().performSelectTool(ToolType.BRUSH); + deletionFileList = new ArrayList<>(); + resolver = launchActivityRule.getActivity().getContentResolver(); + } + + @After + public void tearDown() { + for (File file : deletionFileList) { + if (file != null && file.exists()) { + assertTrue(file.delete()); + } + } + } + + @Test + public void testCheckIntentForOraFile() { + Intent intent = new Intent(); + Uri receivedUri = createTestImageFile(); + Bitmap receivedBitmap = null; + + try { + receivedBitmap = FileIO.getBitmapFromUri(resolver, receivedUri, launchActivityRule.getActivity().getBaseContext()); + } catch (Exception e) { + Log.e("Can't Read", "Can't get Bitmap from File"); + } + + Objects.requireNonNull(receivedBitmap); + intent.setAction(Intent.ACTION_EDIT); + intent.setData(receivedUri); + intent.setType("image/*"); + intent.putExtra(Intent.EXTRA_STREAM, receivedUri); + + launchActivityRule.launchActivity(intent); + Intent mainActivityIntent = launchActivityRule.getActivity().getIntent(); + + String intentAction = intent.getAction(); + String intentType = intent.getType(); + Bundle intentBundle = intent.getExtras(); + Objects.requireNonNull(intentBundle); + Uri intentUri = (Uri) intentBundle.get(Intent.EXTRA_STREAM); + + String mainActivityIntentAction = mainActivityIntent.getAction(); + String mainActivityIntentType = mainActivityIntent.getType(); + Bundle mainActivityIntentBundle = mainActivityIntent.getExtras(); + Objects.requireNonNull(mainActivityIntentBundle); + Uri mainActivityIntentUri = (Uri) mainActivityIntentBundle.get(Intent.EXTRA_STREAM); + Bitmap mainActivityIntentBitmap = null; + Objects.requireNonNull(mainActivityIntentUri); + + try { + mainActivityIntentBitmap = FileIO.getBitmapFromUri(resolver, mainActivityIntentUri, launchActivityRule.getActivity().getBaseContext()); + } catch (Exception e) { + Log.e("Can't read", "Can't get Bitmap From File"); + } + + Objects.requireNonNull(mainActivityIntentBitmap); + + assertEquals(intentAction, mainActivityIntentAction); + assertEquals(intentType, mainActivityIntentType); + assertEquals(intentUri, mainActivityIntentUri); + assertEquals(receivedBitmap.getWidth(), mainActivityIntentBitmap.getWidth()); + assertEquals(receivedBitmap.getHeight(), mainActivityIntentBitmap.getHeight()); + } + + private Uri createTestImageFile() { + Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888); + + ContentValues contentValues = new ContentValues(); + contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, "testfile.ora"); + contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/*"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES); + } + + Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); + try { + OutputStream fos = resolver.openOutputStream(Objects.requireNonNull(imageUri)); + assertTrue(bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)); + assert fos != null; + fos.close(); + } catch (IOException e) { + throw new AssertionError("Picture file could not be created.", e); + } + + File imageFile = new File(imageUri.getPath(), "testfile.ora"); + deletionFileList.add(imageFile); + return imageUri; + } +} diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/rtl/ButtonLayersRtlLayoutTest.java b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/rtl/ButtonLayersRtlLayoutTest.java index a853094b2e..2636bd161b 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/rtl/ButtonLayersRtlLayoutTest.java +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/rtl/ButtonLayersRtlLayoutTest.java @@ -62,5 +62,11 @@ public void testButtonLayers() { onView(withId(R.id.pocketpaint_layer_side_nav_button_delete)) .check(matches(isClickable())) .perform(click()); + onView(withId(R.id.pocketpaint_stroke_ibtn_circle)) + .check(matches(isClickable())) + .perform(click()); + onView(withId(R.id.pocketpaint_stroke_ibtn_rect)) + .check(matches(isClickable())) + .perform(click()); } } diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/FillToolIntegrationTest.java b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/FillToolIntegrationTest.java index c0c9be35f6..1b97728284 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/FillToolIntegrationTest.java +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/FillToolIntegrationTest.java @@ -50,6 +50,7 @@ import static org.catrobat.paintroid.test.espresso.util.wrappers.ToolBarViewInteraction.onToolBarView; import static org.catrobat.paintroid.test.espresso.util.wrappers.ToolPropertiesInteraction.onToolProperties; import static org.catrobat.paintroid.test.espresso.util.wrappers.TopBarViewInteraction.onTopBarView; +import static org.catrobat.paintroid.tools.implementation.FillToolKt.DEFAULT_TOLERANCE_IN_PERCENT; import static org.junit.Assert.assertEquals; import static androidx.test.espresso.Espresso.onView; @@ -155,7 +156,7 @@ public void testFillToolOptionsDialog() { FillTool fillTool = (FillTool) toolReference.get(); assertEquals( "Wrong fill tool member value for color tolerance", - fillTool.getToleranceAbsoluteValue(FillTool.DEFAULT_TOLERANCE_IN_PERCENT), + fillTool.getToleranceAbsoluteValue(DEFAULT_TOLERANCE_IN_PERCENT), fillTool.colorTolerance, TOLERANCE_DELTA ); @@ -168,7 +169,7 @@ public void testFillToolOptionsDialog() { String testToleranceText = "100"; - colorToleranceInput.check(matches(withText(Integer.toString(FillTool.DEFAULT_TOLERANCE_IN_PERCENT)))); + colorToleranceInput.check(matches(withText(Integer.toString(DEFAULT_TOLERANCE_IN_PERCENT)))); colorToleranceInput.perform(replaceText(testToleranceText), closeSoftKeyboard()); @@ -213,8 +214,8 @@ public void testFillToolDialogAfterToolSwitch() { onToolBarView() .performClickSelectedToolButton(); - colorToleranceInput.check(matches(withText(Integer.toString(FillTool.DEFAULT_TOLERANCE_IN_PERCENT)))); - colorToleranceSeekBar.check(matches(withProgress(FillTool.DEFAULT_TOLERANCE_IN_PERCENT))); + colorToleranceInput.check(matches(withText(Integer.toString(DEFAULT_TOLERANCE_IN_PERCENT)))); + colorToleranceSeekBar.check(matches(withProgress(DEFAULT_TOLERANCE_IN_PERCENT))); } @Ignore("Fails on Jenkins, trying out if everything works without this test or if error is due to a bug on Jenkins") diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/algorithm/FillAlgorithmTest.java b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/algorithm/FillAlgorithmTest.java index 0e259334ee..908cba4891 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/algorithm/FillAlgorithmTest.java +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/algorithm/FillAlgorithmTest.java @@ -23,7 +23,6 @@ import android.graphics.Point; import org.catrobat.paintroid.tools.helper.JavaFillAlgorithm; -import org.catrobat.paintroid.tools.implementation.FillTool; import org.junit.Test; import org.junit.runner.RunWith; @@ -31,12 +30,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; +import static org.catrobat.paintroid.tools.implementation.FillToolKt.MAX_ABSOLUTE_TOLERANCE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @RunWith(AndroidJUnit4.class) public class FillAlgorithmTest { - private static final float HALF_TOLERANCE = FillTool.MAX_ABSOLUTE_TOLERANCE / 2.0f; + private static final float HALF_TOLERANCE = MAX_ABSOLUTE_TOLERANCE / 2.0f; @Test public void testFillAlgorithmMembers() { diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/command/FillCommandTest.java b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/command/FillCommandTest.java index 495ed1b384..45245ce7c8 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/command/FillCommandTest.java +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/command/FillCommandTest.java @@ -31,7 +31,6 @@ import org.catrobat.paintroid.model.Layer; import org.catrobat.paintroid.model.LayerModel; import org.catrobat.paintroid.tools.helper.JavaFillAlgorithmFactory; -import org.catrobat.paintroid.tools.implementation.FillTool; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -43,6 +42,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; +import static org.catrobat.paintroid.tools.implementation.FillToolKt.MAX_ABSOLUTE_TOLERANCE; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.lessThan; import static org.junit.Assert.assertEquals; @@ -52,8 +52,8 @@ @RunWith(AndroidJUnit4.class) public class FillCommandTest { private static final float NO_TOLERANCE = 0.0f; - private static final float HALF_TOLERANCE = FillTool.MAX_ABSOLUTE_TOLERANCE / 2.0f; - private static final float MAX_TOLERANCE = FillTool.MAX_ABSOLUTE_TOLERANCE; + private static final float HALF_TOLERANCE = MAX_ABSOLUTE_TOLERANCE / 2.0f; + private static final float MAX_TOLERANCE = MAX_ABSOLUTE_TOLERANCE; private LayerContracts.Model layerModel; diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/BrushToolTest.java b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/BrushToolTest.java index 878ce93cc4..d7ce1f886a 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/BrushToolTest.java +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/BrushToolTest.java @@ -34,7 +34,7 @@ import org.catrobat.paintroid.tools.ToolPaint; import org.catrobat.paintroid.tools.ToolType; import org.catrobat.paintroid.tools.Workspace; -import org.catrobat.paintroid.tools.common.Constants; +import org.catrobat.paintroid.tools.common.ConstantsKt; import org.catrobat.paintroid.tools.implementation.BrushTool; import org.catrobat.paintroid.tools.implementation.DefaultToolPaint; import org.catrobat.paintroid.tools.options.BrushToolOptionsView; @@ -60,7 +60,7 @@ @RunWith(MockitoJUnitRunner.class) public class BrushToolTest { - private static final float MOVE_TOLERANCE = Constants.MOVE_TOLERANCE; + private static final float MOVE_TOLERANCE = ConstantsKt.MOVE_TOLERANCE; @Mock private CommandManager commandManager; @Mock diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/CursorToolTest.java b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/CursorToolTest.java index 7149438c10..fb4156ec6a 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/CursorToolTest.java +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/CursorToolTest.java @@ -32,7 +32,7 @@ import org.catrobat.paintroid.tools.ToolPaint; import org.catrobat.paintroid.tools.ToolType; import org.catrobat.paintroid.tools.Workspace; -import org.catrobat.paintroid.tools.common.Constants; +import org.catrobat.paintroid.tools.common.ConstantsKt; import org.catrobat.paintroid.tools.implementation.CursorTool; import org.catrobat.paintroid.tools.options.BrushToolOptionsView; import org.catrobat.paintroid.tools.options.ToolOptionsVisibilityController; @@ -58,7 +58,7 @@ @RunWith(MockitoJUnitRunner.class) public class CursorToolTest { - private static final float MOVE_TOLERANCE = Constants.MOVE_TOLERANCE; + private static final float MOVE_TOLERANCE = ConstantsKt.MOVE_TOLERANCE; @Mock private CommandManager commandManager; @Mock diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/LineToolTest.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/LineToolTest.kt index 6e00648d59..a379aa9997 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/LineToolTest.kt +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/LineToolTest.kt @@ -1,3 +1,21 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package org.catrobat.paintroid.test.junit.tools import android.graphics.PointF diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/SprayToolTest.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/SprayToolTest.kt index d737e13d4b..350edde9cd 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/SprayToolTest.kt +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/junit/tools/SprayToolTest.kt @@ -1,3 +1,21 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package org.catrobat.paintroid.test.junit.tools import android.graphics.Color diff --git a/Paintroid/src/main/AndroidManifest.xml b/Paintroid/src/main/AndroidManifest.xml index ff5022c331..72d8fab7e9 100644 --- a/Paintroid/src/main/AndroidManifest.xml +++ b/Paintroid/src/main/AndroidManifest.xml @@ -18,6 +18,7 @@ * along with this program. If not, see . --> @@ -58,12 +59,22 @@ - + + + + + + + + + + + diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/FileIO.java b/Paintroid/src/main/java/org/catrobat/paintroid/FileIO.java index 9738ee7921..fedf07482b 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/FileIO.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/FileIO.java @@ -53,6 +53,8 @@ import androidx.core.content.FileProvider; import androidx.exifinterface.media.ExifInterface; +import static org.catrobat.paintroid.common.Constants.MAX_LAYERS; + public final class FileIO { public static String filename = "image"; public static String ending = ".png"; @@ -403,7 +405,7 @@ public static int getScaleFactor(ContentResolver resolver, @NonNull Uri bitmapUr Runtime info = Runtime.getRuntime(); availableMemory = (float) ((info.maxMemory() - info.totalMemory() + info.freeMemory()) * 0.9); heightToWidthFactor = (float) (options.outWidth / (options.outHeight * 1.0)); - availablePixels = (float) ((availableMemory * 0.9) / 4.0); //4 byte per pixel, 10% safety buffer on memory + availablePixels = (float) (((availableMemory / (float) MAX_LAYERS) * 0.9) / 4.0); //4 byte per pixel, 10% safety buffer on memory availableHeight = (float) Math.sqrt(availablePixels / heightToWidthFactor); availableWidth = availablePixels / availableHeight; return calculateSampleSize(options.outWidth, options.outHeight, diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/MainActivity.kt b/Paintroid/src/main/java/org/catrobat/paintroid/MainActivity.kt index f1cf1fa7f0..f480c927ef 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/MainActivity.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/MainActivity.kt @@ -18,6 +18,7 @@ */ package org.catrobat.paintroid +import android.content.ContentResolver import android.content.Context import android.content.Intent import android.net.Uri @@ -28,6 +29,7 @@ import android.util.DisplayMetrics import android.util.Log import android.view.* import android.view.inputmethod.InputMethodManager +import android.webkit.MimeTypeMap import androidx.annotation.VisibleForTesting import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar @@ -46,6 +48,8 @@ import org.catrobat.paintroid.contract.LayerContracts import org.catrobat.paintroid.contract.MainActivityContracts import org.catrobat.paintroid.contract.MainActivityContracts.MainView import org.catrobat.paintroid.controller.DefaultToolController +import org.catrobat.paintroid.iotasks.OpenRasterFileFormatConversion +import org.catrobat.paintroid.listener.DrawerLayoutListener import org.catrobat.paintroid.listener.PresenterColorPickedListener import org.catrobat.paintroid.model.LayerModel import org.catrobat.paintroid.model.MainActivityModel @@ -134,16 +138,31 @@ class MainActivity : AppCompatActivity(), MainView, CommandListener { val receivedIntent = intent val receivedAction = receivedIntent.action val receivedType = receivedIntent.type - if (receivedAction != null && receivedType != null && (receivedAction == Intent.ACTION_SEND || receivedAction == Intent.ACTION_EDIT) && receivedType.startsWith("image/")) { + if (receivedAction != null && receivedType != null && (receivedAction == Intent.ACTION_SEND || receivedAction == Intent.ACTION_EDIT || receivedAction == Intent.ACTION_VIEW) && (receivedType.startsWith("image/") || receivedType.startsWith("application/"))) { var receivedUri = receivedIntent .getParcelableExtra(Intent.EXTRA_STREAM) receivedUri = receivedUri ?: receivedIntent.data + + val mimeType: String? = if (receivedUri.scheme == ContentResolver.SCHEME_CONTENT) { + contentResolver.getType(receivedUri) + } else { + val fileExtension = MimeTypeMap.getFileExtensionFromUrl(receivedUri.toString()) + MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension.toLowerCase(Locale.US)) + } + if (receivedUri != null) { try { - FileIO.filename = "image" - val receivedBitmap = FileIO.getBitmapFromUri(contentResolver, receivedUri, applicationContext) - commandManager.setInitialStateCommand(commandFactory.createInitCommand(receivedBitmap)) + if (mimeType.equals("application/zip") || mimeType.equals("application/octet-stream")) { + OpenRasterFileFormatConversion.importOraFile(contentResolver, receivedUri, applicationContext).bitmapList?.let { bitmapList -> + commandManager.setInitialStateCommand(commandFactory.createInitCommand(bitmapList)) + } + } else { + FileIO.filename = "image" + FileIO.getBitmapFromUri(contentResolver, receivedUri, applicationContext)?.let { receivedBitmap -> + commandManager.setInitialStateCommand(commandFactory.createInitCommand(receivedBitmap)) + } + } } catch (e: IOException) { Log.e("Can not read", "Unable to retrieve Bitmap from Uri") } @@ -269,6 +288,9 @@ class MainActivity : AppCompatActivity(), MainView, CommandListener { val layerAdapter = LayerAdapter(layerPresenter) presenter.setLayerAdapter(layerAdapter) layerPresenter.setAdapter(layerAdapter) + findViewById(R.id.pocketpaint_drawer_layout).apply { + addDrawerListener(DrawerLayoutListener(this, layerAdapter)) + } layerListView.setPresenter(layerPresenter) layerListView.adapter = layerAdapter layerPresenter.refreshLayerMenuViewHolder() @@ -380,11 +402,11 @@ class MainActivity : AppCompatActivity(), MainView, CommandListener { presenter.handleActivityResult(requestCode, resultCode, data) } - override fun superHandleActivityResult(requestCode: Int, resultCode: Int, data: Intent) { + override fun superHandleActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) } - override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { if (VERSION.SDK_INT == Build.VERSION_CODES.M) { deferredRequestPermissionsResult = Runnable { presenter.handleRequestPermissionsResult(requestCode, permissions, grantResults) } } else { @@ -392,7 +414,7 @@ class MainActivity : AppCompatActivity(), MainView, CommandListener { } } - override fun superHandleRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + override fun superHandleRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/command/implementation/AsyncCommandManager.java b/Paintroid/src/main/java/org/catrobat/paintroid/command/implementation/AsyncCommandManager.java deleted file mode 100644 index 6ef5831a6f..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/command/implementation/AsyncCommandManager.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.command.implementation; - -import android.os.AsyncTask; - -import org.catrobat.paintroid.command.Command; -import org.catrobat.paintroid.command.CommandManager; -import org.catrobat.paintroid.contract.LayerContracts; - -import java.util.ArrayList; -import java.util.List; - -public class AsyncCommandManager implements CommandManager { - private List commandListeners = new ArrayList<>(); - private CommandManager commandManager; - private final LayerContracts.Model layerModel; - private boolean shuttingDown; - private boolean busy; - - public AsyncCommandManager(CommandManager commandManager, LayerContracts.Model layerModel) { - this.commandManager = commandManager; - this.layerModel = layerModel; - } - - @Override - public void addCommandListener(CommandListener commandListener) { - commandListeners.add(commandListener); - } - - @Override - public void removeCommandListener(CommandListener commandListener) { - commandListeners.remove(commandListener); - } - - @Override - public boolean isUndoAvailable() { - return commandManager.isUndoAvailable(); - } - - @Override - public boolean isRedoAvailable() { - return commandManager.isRedoAvailable(); - } - - @Override - public void addCommand(final Command command) { - if (busy) { - return; - } - - new AsyncTask() { - @Override - protected void onPreExecute() { - notifyCommandPreExecute(); - } - - @Override - protected Void doInBackground(Void... voids) { - if (!shuttingDown) { - synchronized (layerModel) { - commandManager.addCommand(command); - } - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - notifyCommandPostExecute(); - } - }.execute(); - } - - @Override - public void undo() { - if (busy) { - return; - } - - new AsyncTask() { - @Override - protected void onPreExecute() { - busy = true; - } - - @Override - protected Void doInBackground(Void... voids) { - if (!shuttingDown) { - synchronized (layerModel) { - commandManager.undo(); - } - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - notifyCommandPostExecute(); - } - }.execute(); - } - - @Override - public void redo() { - if (busy) { - return; - } - - new AsyncTask() { - - @Override - protected void onPreExecute() { - busy = true; - } - - @Override - protected Void doInBackground(Void... voids) { - if (!shuttingDown) { - synchronized (layerModel) { - commandManager.redo(); - } - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - notifyCommandPostExecute(); - } - }.execute(); - } - - @Override - public void reset() { - synchronized (layerModel) { - commandManager.reset(); - } - notifyCommandPostExecute(); - } - - @Override - public void shutdown() { - shuttingDown = true; - } - - @Override - public void setInitialStateCommand(Command command) { - synchronized (layerModel) { - commandManager.setInitialStateCommand(command); - } - } - - @Override - public boolean isBusy() { - return busy; - } - - private void notifyCommandPreExecute() { - busy = true; - } - - private void notifyCommandPostExecute() { - busy = false; - if (!shuttingDown) { - for (CommandListener listener : commandListeners) { - listener.commandPostExecute(); - } - } - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/command/implementation/AsyncCommandManager.kt b/Paintroid/src/main/java/org/catrobat/paintroid/command/implementation/AsyncCommandManager.kt new file mode 100644 index 0000000000..444860a7ef --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/command/implementation/AsyncCommandManager.kt @@ -0,0 +1,113 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.command.implementation + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import kotlinx.coroutines.withContext +import org.catrobat.paintroid.command.Command +import org.catrobat.paintroid.command.CommandManager +import org.catrobat.paintroid.command.CommandManager.CommandListener +import org.catrobat.paintroid.contract.LayerContracts + +class AsyncCommandManager( + private val commandManager: CommandManager, + private val layerModel: LayerContracts.Model +) : CommandManager { + private val commandListeners: MutableList = ArrayList() + private var shuttingDown = false + private var mutex = Mutex() + + override fun addCommandListener(commandListener: CommandListener) { + commandListeners.add(commandListener) + } + + override fun removeCommandListener(commandListener: CommandListener) { + commandListeners.remove(commandListener) + } + + override fun isUndoAvailable(): Boolean = commandManager.isUndoAvailable + + override fun isRedoAvailable(): Boolean = commandManager.isRedoAvailable + + override fun addCommand(command: Command) { + CoroutineScope(Dispatchers.Default).launch { + mutex.withLock { + if (!shuttingDown) { + synchronized(layerModel) { commandManager.addCommand(command) } + } + withContext(Dispatchers.Main) { + notifyCommandPostExecute() + } + } + } + } + + override fun undo() { + CoroutineScope(Dispatchers.Default).launch { + mutex.withLock { + if (!shuttingDown) { + synchronized(layerModel) { commandManager.undo() } + } + withContext(Dispatchers.Main) { + notifyCommandPostExecute() + } + } + } + } + + override fun redo() { + CoroutineScope(Dispatchers.Default).launch { + mutex.withLock { + if (!shuttingDown) { + synchronized(layerModel) { commandManager.redo() } + } + withContext(Dispatchers.Main) { + notifyCommandPostExecute() + } + } + } + } + + override fun reset() { + synchronized(layerModel) { commandManager.reset() } + notifyCommandPostExecute() + } + + override fun shutdown() { + shuttingDown = true + } + + override fun setInitialStateCommand(command: Command) { + synchronized(layerModel) { commandManager.setInitialStateCommand(command) } + } + + override fun isBusy(): Boolean = mutex.isLocked + + private fun notifyCommandPostExecute() { + if (!shuttingDown) { + for (listener in commandListeners) { + listener.commandPostExecute() + } + } + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/common/MainActivityConstants.java b/Paintroid/src/main/java/org/catrobat/paintroid/common/MainActivityConstants.java index 720372afc1..027184ac1d 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/common/MainActivityConstants.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/common/MainActivityConstants.java @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -46,6 +46,7 @@ public final class MainActivityConstants { public static final int PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_NEW_EMPTY = 4; public static final int PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_FINISH = 5; public static final int PERMISSION_REQUEST_CODE_LOAD_PICTURE = 6; + public static final int PERMISSION_REQUEST_CODE_IMPORT_PICTURE = 7; public static final int RESULT_INTRO_MW_NOT_SUPPORTED = 10; @@ -74,7 +75,8 @@ public final class MainActivityConstants { PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_LOAD_NEW, PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_NEW_EMPTY, PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_FINISH, - PERMISSION_REQUEST_CODE_LOAD_PICTURE}) + PERMISSION_REQUEST_CODE_LOAD_PICTURE, + PERMISSION_REQUEST_CODE_IMPORT_PICTURE}) @Retention(RetentionPolicy.SOURCE) public @interface PermissionRequestCode { } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/contract/LayerContracts.java b/Paintroid/src/main/java/org/catrobat/paintroid/contract/LayerContracts.java index 0be512a940..c2a7597584 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/contract/LayerContracts.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/contract/LayerContracts.java @@ -18,11 +18,13 @@ interface Adapter { void notifyDataSetChanged(); LayerViewHolder getViewHolderAt(int position); + + void setDrawerLayoutOpen(boolean isOpen); } interface Presenter { - void onBindLayerViewHolderAtPosition(int position, LayerViewHolder viewHolder); + void onBindLayerViewHolderAtPosition(int position, LayerViewHolder viewHolder, boolean isOpen); void refreshLayerMenuViewHolder(); @@ -63,6 +65,8 @@ interface LayerViewHolder { void setBitmap(Bitmap bitmap); + void updateImageView(Bitmap bitmap, boolean isDrawerLayoutOpen); + View getView(); void setMergable(); diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/listener/DrawerLayoutListener.kt b/Paintroid/src/main/java/org/catrobat/paintroid/listener/DrawerLayoutListener.kt new file mode 100644 index 0000000000..a3f9b262cd --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/listener/DrawerLayoutListener.kt @@ -0,0 +1,29 @@ +package org.catrobat.paintroid.listener + +import android.view.View +import androidx.core.view.GravityCompat +import androidx.drawerlayout.widget.DrawerLayout +import org.catrobat.paintroid.ui.LayerAdapter + +class DrawerLayoutListener(private val view: DrawerLayout, private val adapter: LayerAdapter) : DrawerLayout.DrawerListener{ + override fun onDrawerSlide(drawerView: View, slideOffset: Float) {} + + override fun onDrawerOpened(drawerView: View) {} + + override fun onDrawerClosed(drawerView: View) { + adapter.setDrawerLayoutOpen(false) + } + + override fun onDrawerStateChanged(newState: Int) { + if (newState == DrawerLayout.STATE_DRAGGING && !view.isDrawerOpen(GravityCompat.END)) { + adapter.setDrawerLayoutOpen(true) + for (i in 0 until adapter.count) { + adapter.getViewHolderAt(i)?.let { holder -> + holder.bitmap?.let { bitmapImageView -> + holder.updateImageView(bitmapImageView, true) + } + } + } + } + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/listener/DrawingSurfaceListener.java b/Paintroid/src/main/java/org/catrobat/paintroid/listener/DrawingSurfaceListener.java deleted file mode 100644 index e039684362..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/listener/DrawingSurfaceListener.java +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.listener; - -import android.graphics.Point; -import android.graphics.PointF; -import android.os.Handler; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnTouchListener; - -import org.catrobat.paintroid.tools.Tool; -import org.catrobat.paintroid.tools.Tool.StateChange; -import org.catrobat.paintroid.tools.ToolType; -import org.catrobat.paintroid.tools.options.ToolOptionsViewController; -import org.catrobat.paintroid.ui.DrawingSurface; - -import java.util.EnumSet; - -import static org.catrobat.paintroid.tools.ToolType.FILL; -import static org.catrobat.paintroid.tools.ToolType.TRANSFORM; - -public class DrawingSurfaceListener implements OnTouchListener { - private static final float DRAWER_EDGE_SIZE = 20; - private final DrawingSurfaceListenerCallback callback; - private TouchMode touchMode; - - private float pointerDistance; - private final AutoScrollTask autoScrollTask; - - private float xMidPoint; - private float yMidPoint; - - private float eventX; - private float eventY; - - private PointF canvasTouchPoint; - private PointF eventTouchPoint; - private int drawerEdgeSize; - private boolean autoScroll = true; - - public DrawingSurfaceListener(AutoScrollTask autoScrollTask, DrawingSurfaceListenerCallback callback, float displayDensity) { - this.autoScrollTask = autoScrollTask; - this.callback = callback; - drawerEdgeSize = (int) (DRAWER_EDGE_SIZE * displayDensity + 0.5f); - touchMode = TouchMode.DRAW; - - canvasTouchPoint = new PointF(); - eventTouchPoint = new PointF(); - } - - private void newHandEvent(float x, float y) { - eventX = x; - eventY = y; - } - - private float calculatePointerDistance(MotionEvent event) { - float x = event.getX(0) - event.getX(1); - float y = event.getY(0) - event.getY(1); - return (float) Math.hypot(x, y); - } - - private void calculateMidPoint(MotionEvent event) { - xMidPoint = (event.getX(0) + event.getX(1)) / 2f; - yMidPoint = (event.getY(0) + event.getY(1)) / 2f; - } - - public void enableAutoScroll() { - autoScroll = true; - } - - public void disableAutoScroll() { - autoScroll = false; - if (autoScrollTask.isRunning()) { - autoScrollTask.stop(); - } - } - - @Override - public boolean onTouch(View view, MotionEvent event) { - - DrawingSurface drawingSurface = (DrawingSurface) view; - Tool currentTool = callback.getCurrentTool(); - - canvasTouchPoint.x = event.getX(); - canvasTouchPoint.y = event.getY(); - eventTouchPoint.x = canvasTouchPoint.x; - eventTouchPoint.y = canvasTouchPoint.y; - - callback.convertToCanvasFromSurface(canvasTouchPoint); - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - if (eventTouchPoint.x < drawerEdgeSize || view.getWidth() - eventTouchPoint.x < drawerEdgeSize) { - return false; - } - - currentTool.handleDown(canvasTouchPoint); - - if (autoScroll) { - autoScrollTask.setEventPoint(eventTouchPoint.x, eventTouchPoint.y); - autoScrollTask.setViewDimensions(view.getWidth(), view.getHeight()); - autoScrollTask.start(); - } - - break; - case MotionEvent.ACTION_MOVE: - if (event.getPointerCount() == 1 && !(currentTool.handToolMode())) { - if (touchMode == TouchMode.PINCH) { - break; - } - - touchMode = TouchMode.DRAW; - if (autoScroll) { - autoScrollTask.setEventPoint(eventTouchPoint.x, eventTouchPoint.y); - autoScrollTask.setViewDimensions(view.getWidth(), view.getHeight()); - } - - currentTool.handleMove(canvasTouchPoint); - } else if (event.getPointerCount() == 1 && currentTool.handToolMode()) { - float xOld; - float yOld; - if (autoScrollTask.isRunning()) { - autoScrollTask.stop(); - } - - if (touchMode == TouchMode.PINCH) { - xOld = 0; - yOld = 0; - touchMode = TouchMode.DRAW; - } else { - xOld = eventX; - yOld = eventY; - } - - newHandEvent(event.getX(), event.getY()); - if (xOld > 0 && eventX != xOld || yOld > 0 && eventY != yOld) { - callback.translatePerspective(eventX - xOld, eventY - yOld); - } - } else { - if (autoScrollTask.isRunning()) { - autoScrollTask.stop(); - } - if (touchMode == TouchMode.DRAW) { - currentTool.resetInternalState(StateChange.MOVE_CANCELED); - } - - touchMode = TouchMode.PINCH; - - float pointerDistanceOld = pointerDistance; - pointerDistance = calculatePointerDistance(event); - if (pointerDistanceOld > 0 && pointerDistanceOld != pointerDistance) { - float scale = pointerDistance / pointerDistanceOld; - callback.multiplyPerspectiveScale(scale); - } - - float xOld = xMidPoint; - float yOld = yMidPoint; - calculateMidPoint(event); - if (xOld > 0 && xMidPoint != xOld || yOld > 0 && yMidPoint != yOld) { - callback.translatePerspective(xMidPoint - xOld, yMidPoint - yOld); - } - } - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - - if (autoScrollTask.isRunning()) { - autoScrollTask.stop(); - } - - if (touchMode == TouchMode.DRAW) { - currentTool.handleUp(canvasTouchPoint); - } else { - currentTool.resetInternalState(StateChange.MOVE_CANCELED); - } - - pointerDistance = 0; - xMidPoint = 0; - yMidPoint = 0; - eventX = 0; - eventY = 0; - touchMode = TouchMode.DRAW; - break; - } - drawingSurface.refreshDrawingSurface(); - return true; - } - - enum TouchMode { - DRAW, PINCH - } - - public static class AutoScrollTask implements Runnable { - // IMPORTANT: If the SCROLL_INTERVAL_FACTOR is chosen too low, - // espresso will wait forever for the handler queue to be empty on long touch events. - private static final int SCROLL_INTERVAL_FACTOR = 40; - private static final float STEP = 2f; - - private boolean running; - private float pointX; - private float pointY; - private int width; - private int height; - private EnumSet ignoredTools = EnumSet.of(FILL, TRANSFORM); - private final PointF newMovePoint; - - private final Handler handler; - private AutoScrollTaskCallback callback; - - public AutoScrollTask(Handler handler, AutoScrollTaskCallback callback) { - this.handler = handler; - this.callback = callback; - running = false; - newMovePoint = new PointF(); - } - - public void setEventPoint(float pointX, float pointY) { - this.pointX = pointX; - this.pointY = pointY; - } - - public void setViewDimensions(int width, int height) { - this.width = width; - this.height = height; - } - - public void start() { - if (running || width == 0 || height == 0) { - throw new IllegalStateException(); - } else if (ignoredTools.contains(callback.getCurrentToolType())) { - return; - } - running = true; - run(); - } - - public void stop() { - if (running) { - running = false; - handler.removeCallbacks(this); - } - } - - public boolean isRunning() { - return running; - } - - private int calculateScrollInterval(float scale) { - return (int) (SCROLL_INTERVAL_FACTOR / Math.cbrt(scale)); - } - - @Override - public void run() { - Point autoScrollDirection = callback.getToolAutoScrollDirection(pointX, pointY, width, height); - - if (autoScrollDirection.x != 0 || autoScrollDirection.y != 0) { - newMovePoint.x = pointX; - newMovePoint.y = pointY; - callback.convertToCanvasFromSurface(newMovePoint); - - if (callback.isPointOnCanvas((int) newMovePoint.x, (int) newMovePoint.y)) { - callback.translatePerspective(autoScrollDirection.x * STEP, autoScrollDirection.y * STEP); - callback.handleToolMove(newMovePoint); - callback.refreshDrawingSurface(); - } - } - handler.postDelayed(this, calculateScrollInterval(callback.getPerspectiveScale())); - } - } - - public interface AutoScrollTaskCallback { - boolean isPointOnCanvas(int pointX, int pointY); - - void refreshDrawingSurface(); - - void handleToolMove(PointF coordinate); - - Point getToolAutoScrollDirection(float pointX, float pointY, int screenWidth, int screenHeight); - - float getPerspectiveScale(); - - void translatePerspective(float dx, float dy); - - void convertToCanvasFromSurface(PointF surfacePoint); - - ToolType getCurrentToolType(); - } - - public interface DrawingSurfaceListenerCallback { - Tool getCurrentTool(); - - void multiplyPerspectiveScale(float factor); - - void translatePerspective(float x, float y); - - void convertToCanvasFromSurface(PointF surfacePoint); - - ToolOptionsViewController getToolOptionsViewController(); - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/listener/DrawingSurfaceListener.kt b/Paintroid/src/main/java/org/catrobat/paintroid/listener/DrawingSurfaceListener.kt new file mode 100644 index 0000000000..5948396044 --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/listener/DrawingSurfaceListener.kt @@ -0,0 +1,274 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.listener + +import android.graphics.Point +import android.graphics.PointF +import android.os.Handler +import android.view.MotionEvent +import android.view.View +import android.view.View.OnTouchListener +import org.catrobat.paintroid.tools.Tool +import org.catrobat.paintroid.tools.Tool.StateChange +import org.catrobat.paintroid.tools.ToolType +import org.catrobat.paintroid.tools.options.ToolOptionsViewController +import org.catrobat.paintroid.ui.DrawingSurface +import java.util.EnumSet + +private const val DRAWER_EDGE_SIZE = 20f + +open class DrawingSurfaceListener( + private val autoScrollTask: AutoScrollTask, + private val callback: DrawingSurfaceListenerCallback, + displayDensity: Float +) : OnTouchListener { + private var touchMode: TouchMode + private var pointerDistance = 0f + private var xMidPoint = 0f + private var yMidPoint = 0f + private var eventX = 0f + private var eventY = 0f + private val canvasTouchPoint: PointF + private val eventTouchPoint: PointF + private val drawerEdgeSize: Int = (DRAWER_EDGE_SIZE * displayDensity + 0.5f).toInt() + private var autoScroll = true + + internal enum class TouchMode { + DRAW, PINCH + } + + init { + touchMode = TouchMode.DRAW + canvasTouchPoint = PointF() + eventTouchPoint = PointF() + } + + private fun newHandEvent(x: Float, y: Float) { + eventX = x + eventY = y + } + + private fun calculatePointerDistance(event: MotionEvent): Float { + val x = event.getX(0) - event.getX(1) + val y = event.getY(0) - event.getY(1) + return Math.hypot(x.toDouble(), y.toDouble()).toFloat() + } + + private fun calculateMidPoint(event: MotionEvent) { + xMidPoint = (event.getX(0) + event.getX(1)) / 2f + yMidPoint = (event.getY(0) + event.getY(1)) / 2f + } + + fun enableAutoScroll() { + autoScroll = true + } + + fun disableAutoScroll() { + autoScroll = false + if (autoScrollTask.isRunning) { + autoScrollTask.stop() + } + } + + override fun onTouch(view: View, event: MotionEvent): Boolean { + val drawingSurface = view as DrawingSurface + val currentTool = callback.getCurrentTool() + canvasTouchPoint.x = event.x + canvasTouchPoint.y = event.y + eventTouchPoint.x = canvasTouchPoint.x + eventTouchPoint.y = canvasTouchPoint.y + callback.convertToCanvasFromSurface(canvasTouchPoint) + when (event.action) { + MotionEvent.ACTION_DOWN -> { + if (eventTouchPoint.x < drawerEdgeSize || view.getWidth() - eventTouchPoint.x < drawerEdgeSize) { + return false + } + currentTool.handleDown(canvasTouchPoint) + if (autoScroll) { + autoScrollTask.setEventPoint(eventTouchPoint.x, eventTouchPoint.y) + autoScrollTask.setViewDimensions(view.getWidth(), view.getHeight()) + autoScrollTask.start() + } + } + MotionEvent.ACTION_MOVE -> if (event.pointerCount == 1 && !currentTool.handToolMode()) { + if (touchMode != TouchMode.PINCH) { + touchMode = TouchMode.DRAW + if (autoScroll) { + autoScrollTask.setEventPoint(eventTouchPoint.x, eventTouchPoint.y) + autoScrollTask.setViewDimensions(view.getWidth(), view.getHeight()) + } + currentTool.handleMove(canvasTouchPoint) + } + } else if (event.pointerCount == 1 && currentTool.handToolMode()) { + val xOld: Float + val yOld: Float + if (autoScrollTask.isRunning) { + autoScrollTask.stop() + } + if (touchMode == TouchMode.PINCH) { + xOld = 0f + yOld = 0f + touchMode = TouchMode.DRAW + } else { + xOld = eventX + yOld = eventY + } + newHandEvent(event.x, event.y) + if (xOld > 0 && eventX != xOld || yOld > 0 && eventY != yOld) { + callback.translatePerspective(eventX - xOld, eventY - yOld) + } + } else { + if (autoScrollTask.isRunning) { + autoScrollTask.stop() + } + if (touchMode == TouchMode.DRAW) { + currentTool.resetInternalState(StateChange.MOVE_CANCELED) + } + touchMode = TouchMode.PINCH + val pointerDistanceOld = pointerDistance + pointerDistance = calculatePointerDistance(event) + if (pointerDistanceOld > 0 && pointerDistanceOld != pointerDistance) { + val scale = pointerDistance / pointerDistanceOld + callback.multiplyPerspectiveScale(scale) + } + val xOld = xMidPoint + val yOld = yMidPoint + calculateMidPoint(event) + if (xOld > 0 && xMidPoint != xOld || yOld > 0 && yMidPoint != yOld) { + callback.translatePerspective(xMidPoint - xOld, yMidPoint - yOld) + } + } + MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { + if (autoScrollTask.isRunning) { + autoScrollTask.stop() + } + if (touchMode == TouchMode.DRAW) { + currentTool.handleUp(canvasTouchPoint) + } else { + currentTool.resetInternalState(StateChange.MOVE_CANCELED) + } + pointerDistance = 0f + xMidPoint = 0f + yMidPoint = 0f + eventX = 0f + eventY = 0f + touchMode = TouchMode.DRAW + } + } + drawingSurface.refreshDrawingSurface() + return true + } + + open class AutoScrollTask( + private val handler: Handler, + private val callback: AutoScrollTaskCallback + ) : Runnable { + open var isRunning = false + private var pointX = 0f + private var pointY = 0f + private var width = 0 + private var height = 0 + private val ignoredTools = EnumSet.of(ToolType.FILL, ToolType.TRANSFORM) + private val newMovePoint: PointF = PointF() + + companion object { + // IMPORTANT: If the SCROLL_INTERVAL_FACTOR is chosen too low, + // espresso will wait forever for the handler queue to be empty on long touch events. + private const val SCROLL_INTERVAL_FACTOR = 40 + private const val STEP = 2f + } + + open fun setEventPoint(pointX: Float, pointY: Float) { + this.pointX = pointX + this.pointY = pointY + } + + open fun setViewDimensions(width: Int, height: Int) { + this.width = width + this.height = height + } + + open fun start() { + check(!(isRunning || width == 0 || height == 0)) + if (ignoredTools.contains(callback.getCurrentToolType())) { + return + } + isRunning = true + run() + } + + open fun stop() { + if (isRunning) { + isRunning = false + handler.removeCallbacks(this) + } + } + + private fun calculateScrollInterval(scale: Float): Int { + return (SCROLL_INTERVAL_FACTOR / Math.cbrt(scale.toDouble())).toInt() + } + + override fun run() { + val autoScrollDirection = + callback.getToolAutoScrollDirection(pointX, pointY, width, height) + if (autoScrollDirection.x != 0 || autoScrollDirection.y != 0) { + newMovePoint.x = pointX + newMovePoint.y = pointY + callback.convertToCanvasFromSurface(newMovePoint) + if (callback.isPointOnCanvas(newMovePoint.x.toInt(), newMovePoint.y.toInt())) { + callback.translatePerspective( + autoScrollDirection.x * STEP, + autoScrollDirection.y * STEP + ) + callback.handleToolMove(newMovePoint) + callback.refreshDrawingSurface() + } + } + handler.postDelayed( + this, + calculateScrollInterval(callback.getPerspectiveScale()).toLong() + ) + } + } + + interface AutoScrollTaskCallback { + fun isPointOnCanvas(pointX: Int, pointY: Int): Boolean + fun refreshDrawingSurface() + fun handleToolMove(coordinate: PointF) + fun getToolAutoScrollDirection( + pointX: Float, + pointY: Float, + screenWidth: Int, + screenHeight: Int + ): Point + + fun getPerspectiveScale(): Float + fun translatePerspective(dx: Float, dy: Float) + fun convertToCanvasFromSurface(surfacePoint: PointF) + fun getCurrentToolType(): ToolType + } + + interface DrawingSurfaceListenerCallback { + fun getCurrentTool(): Tool + fun multiplyPerspectiveScale(factor: Float) + fun translatePerspective(x: Float, y: Float) + fun convertToCanvasFromSurface(surfacePoint: PointF) + fun getToolOptionsViewController(): ToolOptionsViewController + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/presenter/LayerPresenter.java b/Paintroid/src/main/java/org/catrobat/paintroid/presenter/LayerPresenter.java index e30c764a06..3805ae7d2f 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/presenter/LayerPresenter.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/presenter/LayerPresenter.java @@ -91,7 +91,7 @@ public void setbottomNavigationViewHolder(BottomNavigationViewHolder bottomNavig } @Override - public void onBindLayerViewHolderAtPosition(int position, LayerViewHolder viewHolder) { + public void onBindLayerViewHolderAtPosition(int position, LayerViewHolder viewHolder, boolean isOpen) { LayerContracts.Layer layer = getLayerItem(position); if (layer == model.getCurrentLayer()) { @@ -100,10 +100,10 @@ public void onBindLayerViewHolderAtPosition(int position, LayerViewHolder viewHo viewHolder.setDeselected(); } if (!layers.get(position).getCheckBox()) { - viewHolder.setBitmap(layer.getTransparentBitmap()); + viewHolder.updateImageView(layer.getTransparentBitmap(), isOpen); viewHolder.setCheckBox(false); } else { - viewHolder.setBitmap(layer.getBitmap()); + viewHolder.updateImageView(layer.getBitmap(), isOpen); viewHolder.setCheckBox(true); } } @@ -180,7 +180,7 @@ public void unhideLayer(int position, LayerViewHolder viewHolder) { destinationLayer.setBitmap(bitmapToAdd); destinationLayer.setCheckBox(true); - viewHolder.setBitmap(bitmapToAdd); + viewHolder.updateImageView(bitmapToAdd, true); drawingSurface.refreshDrawingSurface(); diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/presenter/MainActivityPresenter.java b/Paintroid/src/main/java/org/catrobat/paintroid/presenter/MainActivityPresenter.java index da8c532665..260de8c7af 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/presenter/MainActivityPresenter.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/presenter/MainActivityPresenter.java @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -32,6 +32,7 @@ import android.os.Environment; import android.provider.DocumentsContract; import android.provider.MediaStore; +import android.provider.OpenableColumns; import android.util.DisplayMetrics; import android.util.Log; import android.view.Gravity; @@ -50,6 +51,7 @@ import org.catrobat.paintroid.common.MainActivityConstants.LoadImageRequestCode; import org.catrobat.paintroid.common.MainActivityConstants.PermissionRequestCode; import org.catrobat.paintroid.common.MainActivityConstants.SaveImageRequestCode; +import org.catrobat.paintroid.contract.LayerContracts; import org.catrobat.paintroid.contract.MainActivityContracts.BottomBarViewHolder; import org.catrobat.paintroid.contract.MainActivityContracts.BottomNavigationViewHolder; import org.catrobat.paintroid.contract.MainActivityContracts.DrawerLayoutViewHolder; @@ -71,6 +73,7 @@ import org.catrobat.paintroid.ui.Perspective; import java.io.File; +import java.util.Objects; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -85,6 +88,7 @@ import static org.catrobat.paintroid.common.MainActivityConstants.PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_LOAD_NEW; import static org.catrobat.paintroid.common.MainActivityConstants.PERMISSION_EXTERNAL_STORAGE_SAVE_CONFIRMED_NEW_EMPTY; import static org.catrobat.paintroid.common.MainActivityConstants.PERMISSION_EXTERNAL_STORAGE_SAVE_COPY; +import static org.catrobat.paintroid.common.MainActivityConstants.PERMISSION_REQUEST_CODE_IMPORT_PICTURE; import static org.catrobat.paintroid.common.MainActivityConstants.PERMISSION_REQUEST_CODE_LOAD_PICTURE; import static org.catrobat.paintroid.common.MainActivityConstants.REQUEST_CODE_IMPORTPNG; import static org.catrobat.paintroid.common.MainActivityConstants.REQUEST_CODE_INTRO; @@ -319,6 +323,9 @@ public void onNewImage() { FileIO.uriFilePng = null; FileIO.currentFileNameJpg = null; FileIO.currentFileNamePng = null; + FileIO.compressFormat = Bitmap.CompressFormat.PNG; + FileIO.ending = ".png"; + FileIO.isCatrobatImage = false; Command initCommand = commandFactory.createInitCommand(metrics.widthPixels, metrics.heightPixels); commandManager.setInitialStateCommand(initCommand); commandManager.reset(); @@ -341,6 +348,8 @@ public void switchBetweenVersions(@PermissionRequestCode int requestCode, boolea switch (requestCode) { case PERMISSION_REQUEST_CODE_LOAD_PICTURE: break; + case PERMISSION_REQUEST_CODE_IMPORT_PICTURE: + break; case PERMISSION_EXTERNAL_STORAGE_SAVE: checkforDefaultFilename(); showLikeUsDialogIfFirstTimeSave(); @@ -470,6 +479,9 @@ public void handleRequestPermissionsResult(@PermissionRequestCode int requestCod navigator.showSaveBeforeLoadImageDialog(); } break; + case PERMISSION_REQUEST_CODE_IMPORT_PICTURE: + navigator.startImportImageActivity(REQUEST_CODE_IMPORTPNG); + break; default: view.superHandleRequestPermissionsResult(requestCode, permissions, grantResults); break; @@ -538,6 +550,15 @@ public void showColorPickerClicked() { @Override public void showLayerMenuClicked() { + if (layerAdapter != null) { + layerAdapter.setDrawerLayoutOpen(true); + for (int i = 0; i < layerAdapter.getCount(); i++) { + LayerContracts.LayerViewHolder currentHolder = layerAdapter.getViewHolderAt(i); + if (currentHolder.getBitmap() != null) { + currentHolder.updateImageView(currentHolder.getBitmap(), true); + } + } + } drawerLayoutViewHolder.openDrawer(Gravity.END); } @@ -748,6 +769,23 @@ public void onLoadImagePostExecute(@LoadImageRequestCode int requestCode, Uri ur } model.setCameraImageUri(null); FileIO.wasImageLoaded = true; + if (uri != null) { + String name = getFileName(uri); + if (name != null) { + if (name.endsWith("jpg") || name.endsWith("jpeg")) { + FileIO.compressFormat = Bitmap.CompressFormat.JPEG; + FileIO.ending = ".jpg"; + FileIO.isCatrobatImage = false; + } else if (name.endsWith("png")) { + FileIO.compressFormat = Bitmap.CompressFormat.PNG; + FileIO.ending = ".png"; + FileIO.isCatrobatImage = false; + } else { + FileIO.ending = ".ora"; + FileIO.isCatrobatImage = true; + } + } + } break; case LOAD_IMAGE_IMPORTPNG: if (toolController.getToolType() == ToolType.IMPORTPNG) { @@ -971,6 +1009,21 @@ public void actionCurrentToolClicked() { } } + public String getFileName(Uri uri) { + String result = null; + if (Objects.equals(uri.getScheme(), "content")) { + Cursor cursor = fileActivity.getContentResolver().query(uri, null, null, null, null); + try { + if (cursor != null && cursor.moveToFirst()) { + result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); + } + } finally { + cursor.close(); + } + } + return result; + } + @Override public void rateUsClicked() { navigator.rateUsClicked(); @@ -982,7 +1035,7 @@ public void setLayerAdapter(LayerAdapter layerAdapter) { @Override public void importFromGalleryClicked() { - navigator.startImportImageActivity(REQUEST_CODE_IMPORTPNG); + switchBetweenVersions(PERMISSION_REQUEST_CODE_IMPORT_PICTURE); } @Override diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/ContextCallback.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/ContextCallback.java deleted file mode 100644 index 7967800a8f..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/ContextCallback.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools; - -import android.graphics.Shader; -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.util.DisplayMetrics; - -import androidx.annotation.ColorInt; -import androidx.annotation.ColorRes; -import androidx.annotation.DrawableRes; -import androidx.annotation.FontRes; -import androidx.annotation.StringRes; - -public interface ContextCallback { - void showNotification(@StringRes int resId); - - void showNotification(@StringRes int resId, NotificationDuration duration); - - int getScrollTolerance(); - - ScreenOrientation getOrientation(); - - Typeface getFont(@FontRes int id); - - DisplayMetrics getDisplayMetrics(); - - @ColorInt - int getColor(@ColorRes int id); - - Shader getCheckeredBitmapShader(); - - Drawable getDrawable(@DrawableRes int resource); - - enum ScreenOrientation { - PORTRAIT, - LANDSCAPE - } - - enum NotificationDuration { - SHORT, - LONG - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/ContextCallback.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/ContextCallback.kt new file mode 100644 index 0000000000..17fbe75c04 --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/ContextCallback.kt @@ -0,0 +1,57 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools + +import androidx.annotation.StringRes +import androidx.annotation.FontRes +import android.graphics.Typeface +import android.util.DisplayMetrics +import androidx.annotation.ColorInt +import androidx.annotation.ColorRes +import android.graphics.Shader +import android.graphics.drawable.Drawable +import androidx.annotation.DrawableRes + +interface ContextCallback { + fun showNotification(@StringRes resId: Int) + + fun showNotification(@StringRes resId: Int, duration: NotificationDuration) + + val scrollTolerance: Int + val orientation: ScreenOrientation? + + fun getFont(@FontRes id: Int): Typeface? + + val displayMetrics: DisplayMetrics? + + @ColorInt + fun getColor(@ColorRes id: Int): Int + + val checkeredBitmapShader: Shader? + + fun getDrawable(@DrawableRes resource: Int): Drawable? + + enum class ScreenOrientation { + PORTRAIT, LANDSCAPE + } + + enum class NotificationDuration { + SHORT, LONG + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/Tool.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/Tool.java deleted file mode 100644 index eb745310cc..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/Tool.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Cap; -import android.graphics.Point; -import android.graphics.PointF; -import android.os.Bundle; - -public interface Tool { - - boolean handToolMode(); - - boolean handleDown(PointF coordinate); - - boolean handleMove(PointF coordinate); - - boolean handleUp(PointF coordinate); - - void changePaintColor(int color); - - void changePaintStrokeWidth(int strokeWidth); - - void changePaintStrokeCap(Cap cap); - - Paint getDrawPaint(); - - void draw(Canvas canvas); - - ToolType getToolType(); - - void resetInternalState(StateChange stateChange); - - Point getAutoScrollDirection(float pointX, float pointY, int screenWidth, int screenHeight); - - void onSaveInstanceState(Bundle bundle); - - void onRestoreInstanceState(Bundle bundle); - - enum StateChange { - ALL, RESET_INTERNAL_STATE, NEW_IMAGE_LOADED, MOVE_CANCELED - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/Tool.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/Tool.kt new file mode 100644 index 0000000000..5264a7d5b9 --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/Tool.kt @@ -0,0 +1,65 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools + +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Paint.Cap +import android.graphics.Point +import android.graphics.PointF +import android.os.Bundle + +interface Tool { + val toolType: ToolType + + val drawPaint: Paint + + fun handToolMode(): Boolean + + fun handleDown(coordinate: PointF?): Boolean + + fun handleMove(coordinate: PointF?): Boolean + + fun handleUp(coordinate: PointF?): Boolean + + fun changePaintColor(color: Int) + + fun changePaintStrokeWidth(strokeWidth: Int) + + fun changePaintStrokeCap(cap: Cap) + + fun draw(canvas: Canvas) + + fun resetInternalState(stateChange: StateChange) + + fun getAutoScrollDirection( + pointX: Float, + pointY: Float, + screenWidth: Int, + screenHeight: Int + ): Point + + fun onSaveInstanceState(bundle: Bundle?) + + fun onRestoreInstanceState(bundle: Bundle?) + + enum class StateChange { + ALL, RESET_INTERNAL_STATE, NEW_IMAGE_LOADED, MOVE_CANCELED + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolFactory.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolFactory.kt similarity index 60% rename from Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolFactory.java rename to Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolFactory.kt index b98f3b0145..8ce06e8094 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolFactory.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolFactory.kt @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -16,15 +16,20 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +package org.catrobat.paintroid.tools -package org.catrobat.paintroid.tools; +import org.catrobat.paintroid.colorpicker.OnColorPickedListener +import org.catrobat.paintroid.command.CommandManager +import org.catrobat.paintroid.tools.options.ToolOptionsViewController -import org.catrobat.paintroid.colorpicker.OnColorPickedListener; -import org.catrobat.paintroid.command.CommandManager; -import org.catrobat.paintroid.tools.options.ToolOptionsViewController; - -public interface ToolFactory { - Tool createTool(ToolType toolType, ToolOptionsViewController toolOptionsViewController, CommandManager commandManager, - Workspace workspace, ToolPaint toolPaint, ContextCallback contextCallback, - OnColorPickedListener onColorPickedListener); +interface ToolFactory { + fun createTool( + toolType: ToolType, + toolOptionsViewController: ToolOptionsViewController, + commandManager: CommandManager, + workspace: Workspace, + toolPaint: ToolPaint, + contextCallback: ContextCallback, + onColorPickedListener: OnColorPickedListener + ): Tool } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableFactory.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolPaint.kt similarity index 63% rename from Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableFactory.java rename to Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolPaint.kt index 04ed4633e5..d82e4d58a7 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableFactory.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolPaint.kt @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -16,21 +16,20 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +package org.catrobat.paintroid.tools -package org.catrobat.paintroid.tools.drawable; +import android.graphics.Paint +import android.graphics.Paint.Cap +import android.graphics.PorterDuffXfermode +import android.graphics.Shader -public class DrawableFactory { - public ShapeDrawable createDrawable(DrawableShape shape) { - switch (shape) { - case RECTANGLE: - return new RectangleDrawable(); - case OVAL: - return new OvalDrawable(); - case HEART: - return new HeartDrawable(); - case STAR: - return new StarDrawable(); - } - throw new IllegalArgumentException(); - } +interface ToolPaint { + var paint: Paint + val previewPaint: Paint + var color: Int + val eraseXfermode: PorterDuffXfermode + val previewColor: Int + var strokeWidth: Float + var strokeCap: Cap + val checkeredShader: Shader } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolReference.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolReference.kt similarity index 83% rename from Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolReference.java rename to Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolReference.kt index 32c583d8d7..5bde266c42 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolReference.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolReference.kt @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -16,11 +16,9 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +package org.catrobat.paintroid.tools -package org.catrobat.paintroid.tools; - -public interface ToolReference { - Tool get(); - - void set(Tool tool); +interface ToolReference { + fun get(): Tool + fun set(tool: Tool) } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolType.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolType.java deleted file mode 100644 index 8be48fd7b9..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolType.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools; - -import org.catrobat.paintroid.R; -import org.catrobat.paintroid.tools.Tool.StateChange; - -import java.util.EnumSet; - -import androidx.annotation.DrawableRes; -import androidx.annotation.IdRes; -import androidx.annotation.StringRes; - -import static org.catrobat.paintroid.common.Constants.INVALID_RESOURCE_ID; - -public enum ToolType { - PIPETTE(R.string.button_pipette, R.string.help_content_eyedropper, R.drawable.ic_pocketpaint_tool_pipette, EnumSet.of(StateChange.ALL), 1, INVALID_RESOURCE_ID, false), - BRUSH(R.string.button_brush, R.string.help_content_brush, R.drawable.ic_pocketpaint_tool_brush, EnumSet.of(StateChange.ALL), R.id.pocketpaint_tools_brush, INVALID_RESOURCE_ID, true), - UNDO(R.string.button_undo, R.string.help_content_undo, R.drawable.ic_pocketpaint_undo, EnumSet.of(StateChange.ALL), R.id.pocketpaint_btn_top_undo, INVALID_RESOURCE_ID, false), - REDO(R.string.button_redo, R.string.help_content_redo, R.drawable.ic_pocketpaint_redo, EnumSet.of(StateChange.ALL), R.id.pocketpaint_btn_top_redo, INVALID_RESOURCE_ID, false), - FILL(R.string.button_fill, R.string.help_content_fill, R.drawable.ic_pocketpaint_tool_fill, EnumSet.of(StateChange.ALL), R.id.pocketpaint_tools_fill, INVALID_RESOURCE_ID, true), - STAMP(R.string.button_stamp, R.string.help_content_stamp, R.drawable.ic_pocketpaint_tool_stamp, EnumSet.of(StateChange.ALL), R.id.pocketpaint_tools_stamp, R.drawable.pocketpaint_stamp_tool_overlay, true), - LINE(R.string.button_line, R.string.help_content_line, R.drawable.ic_pocketpaint_tool_line, EnumSet.of(StateChange.ALL), R.id.pocketpaint_tools_line, INVALID_RESOURCE_ID, true), - CURSOR(R.string.button_cursor, R.string.help_content_cursor, R.drawable.ic_pocketpaint_tool_cursor, EnumSet.of(StateChange.ALL), R.id.pocketpaint_tools_cursor, INVALID_RESOURCE_ID, true), - IMPORTPNG(R.string.button_import_image, R.string.help_content_import_png, R.drawable.ic_pocketpaint_tool_import, EnumSet.of(StateChange.ALL), R.id.pocketpaint_tools_import, R.drawable.pocketpaint_import_tool_overlay, false), - TRANSFORM(R.string.button_transform, R.string.help_content_transform, R.drawable.ic_pocketpaint_tool_transform, EnumSet.of(StateChange.RESET_INTERNAL_STATE, StateChange.NEW_IMAGE_LOADED), R.id.pocketpaint_tools_transform, INVALID_RESOURCE_ID, true), - ERASER(R.string.button_eraser, R.string.help_content_eraser, R.drawable.ic_pocketpaint_tool_eraser, EnumSet.of(StateChange.ALL), R.id.pocketpaint_tools_eraser, INVALID_RESOURCE_ID, true), - SHAPE(R.string.button_shape, R.string.help_content_shape, R.drawable.ic_pocketpaint_tool_rectangle, EnumSet.of(StateChange.ALL), R.id.pocketpaint_tools_rectangle, R.drawable.pocketpaint_rectangle_tool_overlay, true), - TEXT(R.string.button_text, R.string.help_content_text, R.drawable.ic_pocketpaint_tool_text, EnumSet.of(StateChange.ALL), R.id.pocketpaint_tools_text, R.drawable.pocketpaint_text_tool_overlay, true), - LAYER(R.string.layers_title, R.string.help_content_layer, R.drawable.ic_pocketpaint_layers, EnumSet.of(StateChange.ALL), INVALID_RESOURCE_ID, INVALID_RESOURCE_ID, false), - COLORCHOOSER(R.string.color_picker_title, R.string.help_content_color_chooser, R.drawable.ic_pocketpaint_color_palette, EnumSet.of(StateChange.ALL), INVALID_RESOURCE_ID, INVALID_RESOURCE_ID, false), - HAND(R.string.button_hand, R.string.help_content_hand, R.drawable.ic_pocketpaint_tool_hand, EnumSet.of(StateChange.ALL), R.id.pocketpaint_tools_hand, INVALID_RESOURCE_ID, false), - SPRAY(R.string.button_spray_can, R.string.help_content_spray_can, R.drawable.ic_pocketpaint_tool_spray_can, EnumSet.of(StateChange.ALL), R.id.pocketpaint_tools_spray_can, INVALID_RESOURCE_ID, true); - - private int nameResource; - private int helpTextResource; - private int drawableResource; - private EnumSet stateChangeBehaviour; - private int toolButtonID; - private int overlayDrawableResource; - private boolean hasOptions; - - ToolType(int nameResource, int helpTextResource, int drawableResource, EnumSet stateChangeBehaviour, - int toolButtonID, int overlayDrawableResource, boolean hasOptions) { - this.nameResource = nameResource; - this.helpTextResource = helpTextResource; - this.drawableResource = drawableResource; - this.stateChangeBehaviour = stateChangeBehaviour; - this.toolButtonID = toolButtonID; - this.overlayDrawableResource = overlayDrawableResource; - this.hasOptions = hasOptions; - } - - public @StringRes int getNameResource() { - return nameResource; - } - - public @StringRes int getHelpTextResource() { - return helpTextResource; - } - - public @DrawableRes int getOverlayDrawableResource() { - return overlayDrawableResource; - } - - public boolean shouldReactToStateChange(StateChange stateChange) { - return stateChangeBehaviour.contains(StateChange.ALL) || stateChangeBehaviour.contains(stateChange); - } - - public @IdRes int getToolButtonID() { - return toolButtonID; - } - - public boolean hasOptions() { - return hasOptions; - } - - public @DrawableRes int getDrawableResource() { - return drawableResource; - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolType.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolType.kt new file mode 100644 index 0000000000..844ee70fc9 --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolType.kt @@ -0,0 +1,198 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools + +import androidx.annotation.DrawableRes +import androidx.annotation.IdRes +import androidx.annotation.StringRes +import org.catrobat.paintroid.R +import org.catrobat.paintroid.common.Constants.INVALID_RESOURCE_ID +import org.catrobat.paintroid.tools.Tool.StateChange +import java.util.* + +enum class ToolType( + @get:StringRes val nameResource: Int, + @get:StringRes val helpTextResource: Int, + @get:DrawableRes val drawableResource: Int, + private val stateChangeBehaviour: EnumSet, + @get:IdRes val toolButtonID: Int, + @get:DrawableRes val overlayDrawableResource: Int, + private val hasOptions: Boolean +) { + PIPETTE( + R.string.button_pipette, + R.string.help_content_eyedropper, + R.drawable.ic_pocketpaint_tool_pipette, + EnumSet.of(StateChange.ALL), + 1, + INVALID_RESOURCE_ID, + false + ), + BRUSH( + R.string.button_brush, + R.string.help_content_brush, + R.drawable.ic_pocketpaint_tool_brush, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_tools_brush, + INVALID_RESOURCE_ID, + true + ), + UNDO( + R.string.button_undo, + R.string.help_content_undo, + R.drawable.ic_pocketpaint_undo, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_btn_top_undo, + INVALID_RESOURCE_ID, + false + ), + REDO( + R.string.button_redo, + R.string.help_content_redo, + R.drawable.ic_pocketpaint_redo, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_btn_top_redo, + INVALID_RESOURCE_ID, + false + ), + FILL( + R.string.button_fill, + R.string.help_content_fill, + R.drawable.ic_pocketpaint_tool_fill, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_tools_fill, + INVALID_RESOURCE_ID, + true + ), + STAMP( + R.string.button_stamp, + R.string.help_content_stamp, + R.drawable.ic_pocketpaint_tool_stamp, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_tools_stamp, + R.drawable.pocketpaint_stamp_tool_overlay, + true + ), + LINE( + R.string.button_line, + R.string.help_content_line, + R.drawable.ic_pocketpaint_tool_line, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_tools_line, + INVALID_RESOURCE_ID, + true + ), + CURSOR( + R.string.button_cursor, + R.string.help_content_cursor, + R.drawable.ic_pocketpaint_tool_cursor, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_tools_cursor, + INVALID_RESOURCE_ID, + true + ), + IMPORTPNG( + R.string.button_import_image, + R.string.help_content_import_png, + R.drawable.ic_pocketpaint_tool_import, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_tools_import, + R.drawable.pocketpaint_import_tool_overlay, + false + ), + TRANSFORM( + R.string.button_transform, + R.string.help_content_transform, + R.drawable.ic_pocketpaint_tool_transform, + EnumSet.of(StateChange.RESET_INTERNAL_STATE, StateChange.NEW_IMAGE_LOADED), + R.id.pocketpaint_tools_transform, + INVALID_RESOURCE_ID, + true + ), + ERASER( + R.string.button_eraser, + R.string.help_content_eraser, + R.drawable.ic_pocketpaint_tool_eraser, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_tools_eraser, + INVALID_RESOURCE_ID, + true + ), + SHAPE( + R.string.button_shape, + R.string.help_content_shape, + R.drawable.ic_pocketpaint_tool_rectangle, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_tools_rectangle, + R.drawable.pocketpaint_rectangle_tool_overlay, + true + ), + TEXT( + R.string.button_text, + R.string.help_content_text, + R.drawable.ic_pocketpaint_tool_text, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_tools_text, + R.drawable.pocketpaint_text_tool_overlay, + true + ), + LAYER( + R.string.layers_title, + R.string.help_content_layer, + R.drawable.ic_pocketpaint_layers, + EnumSet.of(StateChange.ALL), + INVALID_RESOURCE_ID, + INVALID_RESOURCE_ID, + false + ), + COLORCHOOSER( + R.string.color_picker_title, + R.string.help_content_color_chooser, + R.drawable.ic_pocketpaint_color_palette, + EnumSet.of(StateChange.ALL), + INVALID_RESOURCE_ID, + INVALID_RESOURCE_ID, + false + ), + HAND( + R.string.button_hand, + R.string.help_content_hand, + R.drawable.ic_pocketpaint_tool_hand, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_tools_hand, + INVALID_RESOURCE_ID, + false + ), + SPRAY( + R.string.button_spray_can, + R.string.help_content_spray_can, + R.drawable.ic_pocketpaint_tool_spray_can, + EnumSet.of(StateChange.ALL), + R.id.pocketpaint_tools_spray_can, + INVALID_RESOURCE_ID, + true + ); + + fun shouldReactToStateChange(stateChange: StateChange): Boolean = + stateChangeBehaviour.contains(StateChange.ALL) || stateChangeBehaviour.contains( + stateChange + ) + + fun hasOptions(): Boolean = hasOptions +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/Workspace.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/Workspace.java deleted file mode 100644 index a2e7fde4de..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/Workspace.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools; - -import android.graphics.Bitmap; -import android.graphics.PointF; -import android.graphics.RectF; - -import org.catrobat.paintroid.ui.Perspective; - -import java.util.List; - -public interface Workspace { - boolean contains(PointF point); - - boolean intersectsWith(RectF rectF); - - int getHeight(); - - int getWidth(); - - int getSurfaceWidth(); - - int getSurfaceHeight(); - - Bitmap getBitmapOfAllLayers(); - - List getBitmapLisOfAllLayers(); - - Bitmap getBitmapOfCurrentLayer(); - - int getCurrentLayerIndex(); - - int getPixelOfCurrentLayer(PointF coordinate); - - void resetPerspective(); - - void setScale(float zoomFactor); - - float getScaleForCenterBitmap(); - - float getScale(); - - PointF getSurfacePointFromCanvasPoint(PointF coordinate); - - PointF getCanvasPointFromSurfacePoint(PointF surfacePoint); - - void invalidate(); - - Perspective getPerspective(); -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/Workspace.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/Workspace.kt new file mode 100644 index 0000000000..a0d0c242a5 --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/Workspace.kt @@ -0,0 +1,46 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools + +import android.graphics.Bitmap +import android.graphics.PointF +import android.graphics.RectF +import org.catrobat.paintroid.ui.Perspective + +interface Workspace { + val height: Int + val width: Int + val surfaceWidth: Int + val surfaceHeight: Int + val bitmapOfAllLayers: Bitmap? + val bitmapLisOfAllLayers: List + val bitmapOfCurrentLayer: Bitmap? + val currentLayerIndex: Int + val scaleForCenterBitmap: Float + var scale: Float + val perspective: Perspective + + fun contains(point: PointF): Boolean + fun intersectsWith(rectF: RectF): Boolean + fun getPixelOfCurrentLayer(coordinate: PointF): Int + fun resetPerspective() + fun getSurfacePointFromCanvasPoint(coordinate: PointF): PointF + fun getCanvasPointFromSurfacePoint(surfacePoint: PointF): PointF + fun invalidate() +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/CommonBrushChangedListener.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/CommonBrushChangedListener.kt similarity index 60% rename from Paintroid/src/main/java/org/catrobat/paintroid/tools/common/CommonBrushChangedListener.java rename to Paintroid/src/main/java/org/catrobat/paintroid/tools/common/CommonBrushChangedListener.kt index 4ac1d18ff3..5a29a5f127 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/CommonBrushChangedListener.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/CommonBrushChangedListener.kt @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -16,28 +16,18 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +package org.catrobat.paintroid.tools.common -package org.catrobat.paintroid.tools.common; +import android.graphics.Paint.Cap +import org.catrobat.paintroid.tools.Tool +import org.catrobat.paintroid.tools.options.BrushToolOptionsView.OnBrushChangedListener -import android.graphics.Paint; +class CommonBrushChangedListener(private val tool: Tool) : OnBrushChangedListener { + override fun setCap(strokeCap: Cap) { + tool.changePaintStrokeCap(strokeCap) + } -import org.catrobat.paintroid.tools.Tool; -import org.catrobat.paintroid.tools.options.BrushToolOptionsView; - -public class CommonBrushChangedListener implements BrushToolOptionsView.OnBrushChangedListener { - private Tool tool; - - public CommonBrushChangedListener(Tool tool) { - this.tool = tool; - } - - @Override - public void setCap(Paint.Cap strokeCap) { - tool.changePaintStrokeCap(strokeCap); - } - - @Override - public void setStrokeWidth(int strokeWidth) { - tool.changePaintStrokeWidth(strokeWidth); - } + override fun setStrokeWidth(strokeWidth: Int) { + tool.changePaintStrokeWidth(strokeWidth) + } } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/CommonBrushPreviewListener.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/CommonBrushPreviewListener.java deleted file mode 100644 index 768368522c..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/CommonBrushPreviewListener.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools.common; - -import android.graphics.Paint; - -import org.catrobat.paintroid.tools.ToolPaint; -import org.catrobat.paintroid.tools.ToolType; -import org.catrobat.paintroid.tools.options.BrushToolOptionsView; - -public class CommonBrushPreviewListener implements BrushToolOptionsView.OnBrushPreviewListener { - private ToolType toolType; - private ToolPaint toolPaint; - - public CommonBrushPreviewListener(ToolPaint toolPaint, ToolType toolType) { - this.toolType = toolType; - this.toolPaint = toolPaint; - } - - @Override - public float getStrokeWidth() { - return toolPaint.getStrokeWidth(); - } - - @Override - public Paint.Cap getStrokeCap() { - return toolPaint.getStrokeCap(); - } - - @Override - public int getColor() { - return toolPaint.getColor(); - } - - @Override - public ToolType getToolType() { - return toolType; - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolPaint.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/CommonBrushPreviewListener.kt similarity index 54% rename from Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolPaint.java rename to Paintroid/src/main/java/org/catrobat/paintroid/tools/common/CommonBrushPreviewListener.kt index 7afeada2fb..8df75b825d 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/ToolPaint.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/CommonBrushPreviewListener.kt @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -16,38 +16,20 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +package org.catrobat.paintroid.tools.common -package org.catrobat.paintroid.tools; +import android.graphics.Paint.Cap +import org.catrobat.paintroid.tools.ToolPaint +import org.catrobat.paintroid.tools.ToolType +import org.catrobat.paintroid.tools.options.BrushToolOptionsView.OnBrushPreviewListener -import android.graphics.Paint; -import android.graphics.PorterDuffXfermode; -import android.graphics.Shader; +class CommonBrushPreviewListener(private val toolPaint: ToolPaint, private val toolType: ToolType) : + OnBrushPreviewListener { + override fun getStrokeWidth(): Float = toolPaint.strokeWidth -import androidx.annotation.ColorInt; + override fun getStrokeCap(): Cap = toolPaint.strokeCap -public interface ToolPaint { + override fun getColor(): Int = toolPaint.color - Paint getPaint(); - - void setPaint(Paint paint); - - Paint getPreviewPaint(); - - int getColor(); - - void setColor(@ColorInt int color); - - PorterDuffXfermode getEraseXfermode(); - - int getPreviewColor(); - - float getStrokeWidth(); - - void setStrokeWidth(float strokeWidth); - - Paint.Cap getStrokeCap(); - - void setStrokeCap(Paint.Cap strokeCap); - - Shader getCheckeredShader(); + override fun getToolType(): ToolType = toolType } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/Constants.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/Constants.kt new file mode 100644 index 0000000000..d88ddf338f --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/Constants.kt @@ -0,0 +1,22 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools.common + +const val SCROLL_TOLERANCE_PERCENTAGE = 0.1f +const val MOVE_TOLERANCE = 5f diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/PointScrollBehavior.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/PointScrollBehavior.java deleted file mode 100644 index f5db4774c2..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/PointScrollBehavior.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.catrobat.paintroid.tools.common; - -import android.graphics.Point; - -public class PointScrollBehavior implements ScrollBehavior { - private final int scrollTolerance; - - public PointScrollBehavior(int scrollTolerance) { - this.scrollTolerance = scrollTolerance; - } - - @Override - public Point getScrollDirection(float pointX, float pointY, int viewWidth, int viewHeight) { - int deltaX = 0; - int deltaY = 0; - - if (pointX < scrollTolerance) { - deltaX = 1; - } - if (pointX > viewWidth - scrollTolerance) { - deltaX = -1; - } - - if (pointY < scrollTolerance) { - deltaY = 1; - } - - if (pointY > viewHeight - scrollTolerance) { - deltaY = -1; - } - - return new Point(deltaX, deltaY); - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/PointScrollBehavior.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/PointScrollBehavior.kt new file mode 100644 index 0000000000..96be4a6206 --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/PointScrollBehavior.kt @@ -0,0 +1,46 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools.common + +import android.graphics.Point + +class PointScrollBehavior(private val scrollTolerance: Int) : ScrollBehavior { + override fun getScrollDirection( + pointX: Float, + pointY: Float, + viewWidth: Int, + viewHeight: Int + ): Point { + var deltaX = 0 + var deltaY = 0 + if (pointX < scrollTolerance) { + deltaX = 1 + } + if (pointX > viewWidth - scrollTolerance) { + deltaX = -1 + } + if (pointY < scrollTolerance) { + deltaY = 1 + } + if (pointY > viewHeight - scrollTolerance) { + deltaY = -1 + } + return Point(deltaX, deltaY) + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/ScrollBehavior.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/ScrollBehavior.java deleted file mode 100644 index 4b7b8bcd23..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/ScrollBehavior.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.catrobat.paintroid.tools.common; - -import android.graphics.Point; - -public interface ScrollBehavior { - Point getScrollDirection(float pointX, float pointY, int viewWidth, int viewHeight); -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/options/FillToolOptionsView.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/ScrollBehavior.kt similarity index 76% rename from Paintroid/src/main/java/org/catrobat/paintroid/tools/options/FillToolOptionsView.java rename to Paintroid/src/main/java/org/catrobat/paintroid/tools/common/ScrollBehavior.kt index e1c46d81ed..079fd90c83 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/options/FillToolOptionsView.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/ScrollBehavior.kt @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -16,13 +16,10 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +package org.catrobat.paintroid.tools.common -package org.catrobat.paintroid.tools.options; +import android.graphics.Point -public interface FillToolOptionsView { - void setCallback(Callback callback); - - interface Callback { - void onColorToleranceChanged(int colorTolerance); - } +interface ScrollBehavior { + fun getScrollDirection(pointX: Float, pointY: Float, viewWidth: Int, viewHeight: Int): Point } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableFactory.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableFactory.kt new file mode 100644 index 0000000000..15ee6609ca --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableFactory.kt @@ -0,0 +1,30 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools.drawable + +class DrawableFactory { + fun createDrawable(shape: DrawableShape): ShapeDrawable { + return when (shape) { + DrawableShape.RECTANGLE -> RectangleDrawable() + DrawableShape.OVAL -> OvalDrawable() + DrawableShape.HEART -> HeartDrawable() + DrawableShape.STAR -> StarDrawable() + } + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableShape.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableShape.kt similarity index 83% rename from Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableShape.java rename to Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableShape.kt index c541f95bf7..4af9704694 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableShape.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableShape.kt @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -16,12 +16,8 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +package org.catrobat.paintroid.tools.drawable -package org.catrobat.paintroid.tools.drawable; - -public enum DrawableShape { - RECTANGLE, - OVAL, - HEART, - STAR +enum class DrawableShape { + RECTANGLE, OVAL, HEART, STAR } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableStyle.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableStyle.kt similarity index 85% rename from Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableStyle.java rename to Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableStyle.kt index fdce19f59b..1b07c64cd6 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableStyle.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableStyle.kt @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -16,10 +16,8 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +package org.catrobat.paintroid.tools.drawable -package org.catrobat.paintroid.tools.drawable; - -public enum DrawableStyle { - STROKE, - FILL +enum class DrawableStyle { + STROKE, FILL } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/HeartDrawable.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/HeartDrawable.java deleted file mode 100644 index c43a886fe9..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/HeartDrawable.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools.drawable; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.RectF; - -public class HeartDrawable implements ShapeDrawable { - private Path path = new Path(); - private Paint paint = new Paint(); - - @Override - public void draw(Canvas canvas, RectF shapeRect, Paint drawPaint) { - paint.set(drawPaint); - - float midWidth = shapeRect.width() / 2; - float height = shapeRect.height(); - float width = shapeRect.width(); - - path.reset(); - path.moveTo(midWidth, height); - path.cubicTo(-0.2f * width, 4.5f * height / 8, - 0.8f * width / 8, -1.5f * height / 8, - midWidth, 1.5f * height / 8); - path.cubicTo(7.2f * width / 8, -1.5f * height / 8, - 1.2f * width, 4.5f * height / 8, - midWidth, height); - path.close(); - - path.offset(shapeRect.left, shapeRect.top); - canvas.drawPath(path, paint); - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/HeartDrawable.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/HeartDrawable.kt new file mode 100644 index 0000000000..776681fa6b --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/HeartDrawable.kt @@ -0,0 +1,52 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools.drawable + +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path +import android.graphics.RectF + +class HeartDrawable : ShapeDrawable { + private val path = Path() + private val paint = Paint() + override fun draw(canvas: Canvas, shapeRect: RectF, drawPaint: Paint) { + paint.set(drawPaint) + val midWidth = shapeRect.width() / 2 + val height = shapeRect.height() + val width = shapeRect.width() + path.run { + reset() + moveTo(midWidth, height) + cubicTo( + -0.2f * width, 4.5f * height / 8, + 0.8f * width / 8, -1.5f * height / 8, + midWidth, 1.5f * height / 8 + ) + cubicTo( + 7.2f * width / 8, -1.5f * height / 8, + 1.2f * width, 4.5f * height / 8, + midWidth, height + ) + close() + offset(shapeRect.left, shapeRect.top) + } + canvas.drawPath(path, paint) + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/OvalDrawable.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/OvalDrawable.java deleted file mode 100644 index dd6343d667..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/OvalDrawable.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools.drawable; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.RectF; - -public class OvalDrawable implements ShapeDrawable { - @Override - public void draw(Canvas canvas, RectF shapeRect, Paint drawPaint) { - canvas.drawOval(shapeRect, drawPaint); - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/Constants.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/OvalDrawable.kt similarity index 69% rename from Paintroid/src/main/java/org/catrobat/paintroid/tools/common/Constants.java rename to Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/OvalDrawable.kt index b6a7d628fc..255d5bfdb3 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/common/Constants.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/OvalDrawable.kt @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -16,14 +16,14 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +package org.catrobat.paintroid.tools.drawable -package org.catrobat.paintroid.tools.common; +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.RectF -public final class Constants { - public static final float SCROLL_TOLERANCE_PERCENTAGE = 0.1f; - public static final float MOVE_TOLERANCE = 5; - - private Constants() { - throw new RuntimeException("no"); - } +class OvalDrawable : ShapeDrawable { + override fun draw(canvas: Canvas, shapeRect: RectF, drawPaint: Paint) { + canvas.drawOval(shapeRect, drawPaint) + } } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/RectangleDrawable.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/RectangleDrawable.java deleted file mode 100644 index 04f337e3fc..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/RectangleDrawable.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools.drawable; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.RectF; - -public class RectangleDrawable implements ShapeDrawable { - @Override - public void draw(Canvas canvas, RectF shapeRect, Paint drawPaint) { - canvas.drawRect(shapeRect, drawPaint); - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/RectangleDrawable.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/RectangleDrawable.kt new file mode 100644 index 0000000000..03030cf37e --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/RectangleDrawable.kt @@ -0,0 +1,29 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools.drawable + +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.RectF + +class RectangleDrawable : ShapeDrawable { + override fun draw(canvas: Canvas, shapeRect: RectF, drawPaint: Paint) { + canvas.drawRect(shapeRect, drawPaint) + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/ShapeDrawable.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/ShapeDrawable.java deleted file mode 100644 index 6c8503c7d7..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/ShapeDrawable.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools.drawable; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.RectF; - -public interface ShapeDrawable { - void draw(Canvas canvas, RectF shapeRect, Paint drawPaint); -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/ShapeDrawable.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/ShapeDrawable.kt new file mode 100644 index 0000000000..44435b2599 --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/ShapeDrawable.kt @@ -0,0 +1,27 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools.drawable + +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.RectF + +interface ShapeDrawable { + fun draw(canvas: Canvas, shapeRect: RectF, drawPaint: Paint) +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/StarDrawable.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/StarDrawable.java deleted file mode 100644 index 798ec08170..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/StarDrawable.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools.drawable; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.RectF; - -public class StarDrawable implements ShapeDrawable { - private Path path = new Path(); - private Paint paint = new Paint(); - - @Override - public void draw(Canvas canvas, RectF shapeRect, Paint drawPaint) { - paint.set(drawPaint); - - float midWidth = shapeRect.width() / 2; - float midHeight = shapeRect.height() / 2; - float height = shapeRect.height(); - float width = shapeRect.width(); - - path.reset(); - path.moveTo(midWidth, 0); - path.lineTo(midWidth + width / 8, midHeight - height / 8); - path.lineTo(width, midHeight - height / 8); - path.lineTo(midWidth + 1.8f * width / 8, midHeight + 1 * height / 8); - path.lineTo(midWidth + 3 * width / 8, height); - path.lineTo(midWidth, midHeight + 2 * height / 8); - path.lineTo(midWidth - 3 * width / 8, height); - path.lineTo(midWidth - 1.8f * width / 8, midHeight + 1 * height / 8); - path.lineTo(0, midHeight - height / 8); - path.lineTo(midWidth - width / 8, midHeight - height / 8); - path.lineTo(midWidth, 0); - path.close(); - - path.offset(shapeRect.left, shapeRect.top); - canvas.drawPath(path, paint); - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/StarDrawable.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/StarDrawable.kt new file mode 100644 index 0000000000..46124e1fe8 --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/StarDrawable.kt @@ -0,0 +1,53 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools.drawable + +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path +import android.graphics.RectF + +class StarDrawable : ShapeDrawable { + private val path = Path() + private val paint = Paint() + override fun draw(canvas: Canvas, shapeRect: RectF, drawPaint: Paint) { + paint.set(drawPaint) + val midWidth = shapeRect.width() / 2 + val midHeight = shapeRect.height() / 2 + val height = shapeRect.height() + val width = shapeRect.width() + path.run { + reset() + moveTo(midWidth, 0f) + lineTo(midWidth + width / 8, midHeight - height / 8) + lineTo(width, midHeight - height / 8) + lineTo(midWidth + 1.8f * width / 8, midHeight + 1 * height / 8) + lineTo(midWidth + 3 * width / 8, height) + lineTo(midWidth, midHeight + 2 * height / 8) + lineTo(midWidth - 3 * width / 8, height) + lineTo(midWidth - 1.8f * width / 8, midHeight + 1 * height / 8) + lineTo(0f, midHeight - height / 8) + lineTo(midWidth - width / 8, midHeight - height / 8) + lineTo(midWidth, 0f) + close() + offset(shapeRect.left, shapeRect.top) + } + canvas.drawPath(path, paint) + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BaseTool.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BaseTool.java deleted file mode 100644 index 2bf0fc1028..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BaseTool.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools.implementation; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Cap; -import android.graphics.Point; -import android.graphics.PointF; -import android.os.Bundle; - -import org.catrobat.paintroid.command.CommandFactory; -import org.catrobat.paintroid.command.CommandManager; -import org.catrobat.paintroid.command.implementation.DefaultCommandFactory; -import org.catrobat.paintroid.tools.ContextCallback; -import org.catrobat.paintroid.tools.Tool; -import org.catrobat.paintroid.tools.ToolPaint; -import org.catrobat.paintroid.tools.Workspace; -import org.catrobat.paintroid.tools.common.PointScrollBehavior; -import org.catrobat.paintroid.tools.common.ScrollBehavior; -import org.catrobat.paintroid.tools.options.ToolOptionsVisibilityController; - -import androidx.annotation.ColorInt; - -public abstract class BaseTool implements Tool { - protected final PointF movedDistance; - protected ScrollBehavior scrollBehavior; - protected PointF previousEventCoordinate; - protected CommandFactory commandFactory = new DefaultCommandFactory(); - protected CommandManager commandManager; - protected Workspace workspace; - protected ContextCallback contextCallback; - protected ToolOptionsVisibilityController toolOptionsViewController; - protected ToolPaint toolPaint; - - public BaseTool(ContextCallback contextCallback, ToolOptionsVisibilityController toolOptionsViewController, - ToolPaint toolPaint, Workspace workspace, CommandManager commandManager) { - this.contextCallback = contextCallback; - this.toolOptionsViewController = toolOptionsViewController; - this.toolPaint = toolPaint; - this.workspace = workspace; - this.commandManager = commandManager; - - int scrollTolerance = contextCallback.getScrollTolerance(); - scrollBehavior = new PointScrollBehavior(scrollTolerance); - - movedDistance = new PointF(0f, 0f); - previousEventCoordinate = new PointF(0f, 0f); - } - - @Override - public void onSaveInstanceState(Bundle bundle) { - } - - @Override - public void onRestoreInstanceState(Bundle bundle) { - } - - @Override - public void changePaintColor(@ColorInt int color) { - toolPaint.setColor(color); - } - - @Override - public void changePaintStrokeWidth(int strokeWidth) { - toolPaint.setStrokeWidth(strokeWidth); - } - - @Override - public void changePaintStrokeCap(Cap cap) { - toolPaint.setStrokeCap(cap); - } - - @Override - public Paint getDrawPaint() { - return new Paint(toolPaint.getPaint()); - } - - @Override - public abstract void draw(Canvas canvas); - - protected void resetInternalState() { - } - - @Override - public void resetInternalState(StateChange stateChange) { - if (getToolType().shouldReactToStateChange(stateChange)) { - resetInternalState(); - } - } - - @Override - public Point getAutoScrollDirection(float pointX, float pointY, int viewWidth, int viewHeight) { - return scrollBehavior.getScrollDirection(pointX, pointY, viewWidth, viewHeight); - } - - public boolean handToolMode() { - return false; - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BaseTool.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BaseTool.kt new file mode 100644 index 0000000000..1120304d7f --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BaseTool.kt @@ -0,0 +1,108 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools.implementation + +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Paint.Cap +import android.graphics.Point +import android.graphics.PointF +import android.os.Bundle +import androidx.annotation.ColorInt +import org.catrobat.paintroid.command.CommandFactory +import org.catrobat.paintroid.command.CommandManager +import org.catrobat.paintroid.command.implementation.DefaultCommandFactory +import org.catrobat.paintroid.tools.ContextCallback +import org.catrobat.paintroid.tools.Tool +import org.catrobat.paintroid.tools.Tool.StateChange +import org.catrobat.paintroid.tools.ToolPaint +import org.catrobat.paintroid.tools.Workspace +import org.catrobat.paintroid.tools.common.PointScrollBehavior +import org.catrobat.paintroid.tools.common.ScrollBehavior +import org.catrobat.paintroid.tools.options.ToolOptionsVisibilityController + +abstract class BaseTool( + @JvmField + open var contextCallback: ContextCallback, + @JvmField + protected var toolOptionsViewController: ToolOptionsVisibilityController, + @JvmField + protected var toolPaint: ToolPaint, + @JvmField + protected var workspace: Workspace, + @JvmField + protected var commandManager: CommandManager +) : Tool { + @JvmField + protected val movedDistance: PointF + + @JvmField + protected var scrollBehavior: ScrollBehavior + + @JvmField + protected var previousEventCoordinate: PointF? + + @JvmField + protected var commandFactory: CommandFactory = DefaultCommandFactory() + + init { + val scrollTolerance = contextCallback.scrollTolerance + scrollBehavior = PointScrollBehavior(scrollTolerance) + movedDistance = PointF(0f, 0f) + previousEventCoordinate = PointF(0f, 0f) + } + + override fun onSaveInstanceState(bundle: Bundle?) = Unit + + override fun onRestoreInstanceState(bundle: Bundle?) = Unit + + override fun changePaintColor(@ColorInt color: Int) { + toolPaint.color = color + } + + override fun changePaintStrokeWidth(strokeWidth: Int) { + toolPaint.strokeWidth = strokeWidth.toFloat() + } + + override fun changePaintStrokeCap(cap: Cap) { + toolPaint.strokeCap = cap + } + + override val drawPaint + get() = Paint(toolPaint.paint) + + abstract override fun draw(canvas: Canvas) + + protected open fun resetInternalState() = Unit + + override fun resetInternalState(stateChange: StateChange) { + if (toolType.shouldReactToStateChange(stateChange)) { + resetInternalState() + } + } + + override fun getAutoScrollDirection( + pointX: Float, + pointY: Float, + viewWidth: Int, + viewHeight: Int + ): Point = scrollBehavior.getScrollDirection(pointX, pointY, viewWidth, viewHeight) + + override fun handToolMode(): Boolean = false +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BaseToolWithShape.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BaseToolWithShape.java deleted file mode 100644 index 54ee89fae6..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BaseToolWithShape.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools.implementation; - -import android.annotation.SuppressLint; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Point; -import android.graphics.PointF; -import android.os.Bundle; -import android.util.DisplayMetrics; - -import org.catrobat.paintroid.R; -import org.catrobat.paintroid.command.CommandManager; -import org.catrobat.paintroid.tools.ContextCallback; -import org.catrobat.paintroid.tools.ToolPaint; -import org.catrobat.paintroid.tools.Workspace; -import org.catrobat.paintroid.tools.options.ToolOptionsVisibilityController; -import org.catrobat.paintroid.ui.Perspective; - -import androidx.annotation.VisibleForTesting; - -public abstract class BaseToolWithShape extends BaseTool { - - private static final String BUNDLE_TOOL_POSITION_X = "TOOL_POSITION_X"; - private static final String BUNDLE_TOOL_POSITION_Y = "TOOL_POSITION_Y"; - - @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) - public final PointF toolPosition; - - int primaryShapeColor; - int secondaryShapeColor; - - final Paint linePaint; - final DisplayMetrics metrics; - - @SuppressLint("VisibleForTests") - public BaseToolWithShape(ContextCallback contextCallback, ToolOptionsVisibilityController toolOptionsViewController, ToolPaint toolPaint, Workspace workspace, CommandManager commandManager) { - super(contextCallback, toolOptionsViewController, toolPaint, workspace, commandManager); - - metrics = contextCallback.getDisplayMetrics(); - - primaryShapeColor = contextCallback.getColor(R.color.pocketpaint_main_rectangle_tool_primary_color); - secondaryShapeColor = contextCallback.getColor(R.color.pocketpaint_colorAccent); - Perspective perspective = workspace.getPerspective(); - - if (perspective.getScale() > 1) { - toolPosition = new PointF(perspective.surfaceCenterX - perspective.surfaceTranslationX, perspective.surfaceCenterY - perspective.surfaceTranslationY); - } else { - toolPosition = new PointF(workspace.getWidth() / 2f, workspace.getHeight() / 2f); - } - - linePaint = new Paint(); - linePaint.setColor(primaryShapeColor); - } - - public abstract void drawShape(Canvas canvas); - - float getStrokeWidthForZoom(float defaultStrokeWidth, float minStrokeWidth, float maxStrokeWidth) { - float strokeWidth = (defaultStrokeWidth * metrics.density) / workspace.getScale(); - return Math.min(maxStrokeWidth, Math.max(minStrokeWidth, strokeWidth)); - } - - float getInverselyProportionalSizeForZoom(float defaultSize) { - float applicationScale = workspace.getScale(); - return (defaultSize * metrics.density) / applicationScale; - } - - @Override - public void onSaveInstanceState(Bundle bundle) { - super.onSaveInstanceState(bundle); - - bundle.putFloat(BUNDLE_TOOL_POSITION_X, toolPosition.x); - bundle.putFloat(BUNDLE_TOOL_POSITION_Y, toolPosition.y); - } - - @Override - public void onRestoreInstanceState(Bundle bundle) { - super.onRestoreInstanceState(bundle); - - toolPosition.x = bundle.getFloat(BUNDLE_TOOL_POSITION_X, toolPosition.x); - toolPosition.y = bundle.getFloat(BUNDLE_TOOL_POSITION_Y, toolPosition.y); - } - - @Override - public Point getAutoScrollDirection(float pointX, float pointY, int viewWidth, int viewHeight) { - PointF surfaceToolPosition = workspace.getSurfacePointFromCanvasPoint(toolPosition); - return scrollBehavior.getScrollDirection(surfaceToolPosition.x, surfaceToolPosition.y, viewWidth, viewHeight); - } - - public abstract void onClickOnButton(); - - protected void drawToolSpecifics(Canvas canvas, float boxWidth, float boxHeight) { - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BaseToolWithShape.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BaseToolWithShape.kt new file mode 100644 index 0000000000..c3e269612e --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BaseToolWithShape.kt @@ -0,0 +1,136 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools.implementation + +import android.annotation.SuppressLint +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Point +import android.graphics.PointF +import android.os.Bundle +import android.util.DisplayMetrics +import androidx.annotation.VisibleForTesting +import org.catrobat.paintroid.R +import org.catrobat.paintroid.command.CommandManager +import org.catrobat.paintroid.tools.ContextCallback +import org.catrobat.paintroid.tools.ToolPaint +import org.catrobat.paintroid.tools.Workspace +import org.catrobat.paintroid.tools.options.ToolOptionsVisibilityController + +private const val BUNDLE_TOOL_POSITION_Y = "TOOL_POSITION_Y" +private const val BUNDLE_TOOL_POSITION_X = "TOOL_POSITION_X" + +abstract class BaseToolWithShape @SuppressLint("VisibleForTests") constructor( + contextCallback: ContextCallback, + toolOptionsViewController: ToolOptionsVisibilityController, + toolPaint: ToolPaint, + workspace: Workspace, + commandManager: CommandManager +) : BaseTool( + contextCallback, + toolOptionsViewController, + toolPaint, + workspace, + commandManager +) { + + @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) + @JvmField + val toolPosition: PointF + + @JvmField + var primaryShapeColor: Int = + contextCallback.getColor(R.color.pocketpaint_main_rectangle_tool_primary_color) + + @JvmField + var secondaryShapeColor: Int = contextCallback.getColor(R.color.pocketpaint_colorAccent) + + @JvmField + val linePaint: Paint + + @JvmField + val metrics: DisplayMetrics? = contextCallback.displayMetrics + + init { + val perspective = workspace.perspective + toolPosition = if (perspective.scale > 1) { + PointF( + perspective.surfaceCenterX - perspective.surfaceTranslationX, + perspective.surfaceCenterY - perspective.surfaceTranslationY + ) + } else { + PointF(workspace.width / 2f, workspace.height / 2f) + } + linePaint = Paint() + linePaint.color = primaryShapeColor + } + + abstract fun drawShape(canvas: Canvas?) + + fun getStrokeWidthForZoom( + defaultStrokeWidth: Float, + minStrokeWidth: Float, + maxStrokeWidth: Float + ): Float? { + metrics ?: return null + val strokeWidth = defaultStrokeWidth * metrics.density / workspace.scale + return Math.min(maxStrokeWidth, Math.max(minStrokeWidth, strokeWidth)) + } + + fun getInverselyProportionalSizeForZoom(defaultSize: Float): Float? { + metrics ?: return null + val applicationScale = workspace.scale + return defaultSize * metrics.density / applicationScale + } + + override fun onSaveInstanceState(bundle: Bundle?) { + super.onSaveInstanceState(bundle) + bundle?.apply { + putFloat(BUNDLE_TOOL_POSITION_X, toolPosition.x) + putFloat(BUNDLE_TOOL_POSITION_Y, toolPosition.y) + } + } + + override fun onRestoreInstanceState(bundle: Bundle?) { + super.onRestoreInstanceState(bundle) + bundle?.apply { + toolPosition.x = getFloat(BUNDLE_TOOL_POSITION_X, toolPosition.x) + toolPosition.y = getFloat(BUNDLE_TOOL_POSITION_Y, toolPosition.y) + } + } + + override fun getAutoScrollDirection( + pointX: Float, + pointY: Float, + viewWidth: Int, + viewHeight: Int + ): Point { + val surfaceToolPosition = workspace.getSurfacePointFromCanvasPoint(toolPosition) + return scrollBehavior.getScrollDirection( + surfaceToolPosition.x, + surfaceToolPosition.y, + viewWidth, + viewHeight + ) + } + + abstract fun onClickOnButton() + + protected open fun drawToolSpecifics(canvas: Canvas?, boxWidth: Float, boxHeight: Float) = Unit +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BrushTool.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BrushTool.java index 0eb1a82c57..cdbdfb8f29 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BrushTool.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/BrushTool.java @@ -37,7 +37,7 @@ import androidx.annotation.VisibleForTesting; -import static org.catrobat.paintroid.tools.common.Constants.MOVE_TOLERANCE; +import static org.catrobat.paintroid.tools.common.ConstantsKt.MOVE_TOLERANCE; public class BrushTool extends BaseTool { diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/CursorTool.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/CursorTool.java index d4c0167dcc..debd794f27 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/CursorTool.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/CursorTool.java @@ -41,7 +41,7 @@ import androidx.annotation.VisibleForTesting; -import static org.catrobat.paintroid.tools.common.Constants.MOVE_TOLERANCE; +import static org.catrobat.paintroid.tools.common.ConstantsKt.MOVE_TOLERANCE; public class CursorTool extends BaseToolWithShape { diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/DefaultContextCallback.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/DefaultContextCallback.java index 7134e1a378..311c2f7610 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/DefaultContextCallback.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/DefaultContextCallback.java @@ -33,7 +33,6 @@ import org.catrobat.paintroid.R; import org.catrobat.paintroid.tools.ContextCallback; -import org.catrobat.paintroid.tools.common.Constants; import org.catrobat.paintroid.ui.ToastFactory; import androidx.annotation.ColorInt; @@ -45,6 +44,8 @@ import androidx.core.content.ContextCompat; import androidx.core.content.res.ResourcesCompat; +import static org.catrobat.paintroid.tools.common.ConstantsKt.SCROLL_TOLERANCE_PERCENTAGE; + public class DefaultContextCallback implements ContextCallback { private Shader checkeredBitmapShader; private Context context; @@ -71,7 +72,7 @@ public void showNotification(@StringRes int resId, NotificationDuration duration @Override public int getScrollTolerance() { return (int) (context.getResources().getDisplayMetrics().widthPixels - * Constants.SCROLL_TOLERANCE_PERCENTAGE); + * SCROLL_TOLERANCE_PERCENTAGE); } @Override diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/FillTool.java b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/FillTool.java deleted file mode 100644 index fde0eb3952..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/FillTool.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.tools.implementation; - -import android.graphics.Canvas; -import android.graphics.PointF; - -import org.catrobat.paintroid.command.Command; -import org.catrobat.paintroid.command.CommandManager; -import org.catrobat.paintroid.tools.ContextCallback; -import org.catrobat.paintroid.tools.ToolPaint; -import org.catrobat.paintroid.tools.ToolType; -import org.catrobat.paintroid.tools.Workspace; -import org.catrobat.paintroid.tools.options.FillToolOptionsView; -import org.catrobat.paintroid.tools.options.ToolOptionsVisibilityController; - -import androidx.annotation.VisibleForTesting; - -public class FillTool extends BaseTool { - - public static final int DEFAULT_TOLERANCE_IN_PERCENT = 12; - public static final int MAX_ABSOLUTE_TOLERANCE = 510; - - @VisibleForTesting - public float colorTolerance = MAX_ABSOLUTE_TOLERANCE * DEFAULT_TOLERANCE_IN_PERCENT / 100.0f; - - public FillTool(FillToolOptionsView fillToolOptionsView, ContextCallback contextCallback, - ToolOptionsVisibilityController toolOptionsViewController, ToolPaint toolPaint, Workspace workspace, - CommandManager commandManager) { - super(contextCallback, toolOptionsViewController, toolPaint, workspace, commandManager); - - fillToolOptionsView.setCallback(new FillToolOptionsView.Callback() { - @Override - public void onColorToleranceChanged(int colorTolerance) { - updateColorTolerance(colorTolerance); - } - }); - } - - public void updateColorTolerance(int colorToleranceInPercent) { - colorTolerance = getToleranceAbsoluteValue(colorToleranceInPercent); - } - - public float getToleranceAbsoluteValue(int toleranceInPercent) { - return MAX_ABSOLUTE_TOLERANCE * toleranceInPercent / 100.0f; - } - - @Override - public boolean handleDown(PointF coordinate) { - return false; - } - - @Override - public boolean handleMove(PointF coordinate) { - return false; - } - - @Override - public boolean handleUp(PointF coordinate) { - if (workspace.contains(coordinate)) { - Command command = commandFactory.createFillCommand((int) coordinate.x, (int) coordinate.y, toolPaint.getPaint(), colorTolerance); - commandManager.addCommand(command); - return true; - } - - return false; - } - - @Override - public void resetInternalState() { - } - - @Override - public void draw(Canvas canvas) { - } - - @Override - public ToolType getToolType() { - return ToolType.FILL; - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/FillTool.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/FillTool.kt new file mode 100644 index 0000000000..3a8a5e2491 --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/FillTool.kt @@ -0,0 +1,90 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools.implementation + +import android.graphics.Canvas +import android.graphics.PointF +import androidx.annotation.VisibleForTesting +import org.catrobat.paintroid.command.CommandManager +import org.catrobat.paintroid.tools.ContextCallback +import org.catrobat.paintroid.tools.ToolPaint +import org.catrobat.paintroid.tools.ToolType +import org.catrobat.paintroid.tools.Workspace +import org.catrobat.paintroid.tools.options.FillToolOptionsView +import org.catrobat.paintroid.tools.options.ToolOptionsVisibilityController + +const val DEFAULT_TOLERANCE_IN_PERCENT = 12 +const val MAX_ABSOLUTE_TOLERANCE = 510 + +class FillTool( + fillToolOptionsView: FillToolOptionsView, + contextCallback: ContextCallback, + toolOptionsViewController: ToolOptionsVisibilityController, + toolPaint: ToolPaint, + workspace: Workspace, + commandManager: CommandManager +) : BaseTool( + contextCallback, + toolOptionsViewController, + toolPaint, + workspace, + commandManager +) { + @VisibleForTesting + @JvmField + var colorTolerance = MAX_ABSOLUTE_TOLERANCE * DEFAULT_TOLERANCE_IN_PERCENT / 100.0f + + init { + fillToolOptionsView.setCallback(object : FillToolOptionsView.Callback { + override fun onColorToleranceChanged(colorTolerance: Int) { + updateColorTolerance(colorTolerance) + } + }) + } + + fun updateColorTolerance(colorToleranceInPercent: Int) { + colorTolerance = getToleranceAbsoluteValue(colorToleranceInPercent) + } + + fun getToleranceAbsoluteValue(toleranceInPercent: Int): Float = + MAX_ABSOLUTE_TOLERANCE * toleranceInPercent / 100.0f + + override fun handleDown(coordinate: PointF?): Boolean = false + + override fun handleMove(coordinate: PointF?): Boolean = false + + override fun handleUp(coordinate: PointF?): Boolean { + coordinate ?: return false + if (!workspace.contains(coordinate)) { + return false + } + + val command = commandFactory.createFillCommand( + coordinate.x.toInt(), coordinate.y.toInt(), toolPaint.paint, colorTolerance + ) + commandManager.addCommand(command) + return true + } + + public override fun resetInternalState() = Unit + + override val toolType: ToolType = ToolType.FILL + + override fun draw(canvas: Canvas) = Unit +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/LineTool.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/LineTool.kt index 80abdd151a..8d737c4375 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/LineTool.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/LineTool.kt @@ -1,3 +1,21 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ package org.catrobat.paintroid.tools.implementation import android.graphics.Canvas @@ -15,19 +33,31 @@ import org.catrobat.paintroid.tools.common.CommonBrushPreviewListener import org.catrobat.paintroid.tools.options.BrushToolOptionsView import org.catrobat.paintroid.tools.options.ToolOptionsVisibilityController -class LineTool(private val brushToolOptionsView: BrushToolOptionsView, contextCallback: ContextCallback, - toolOptionsViewController: ToolOptionsVisibilityController, toolPaint: ToolPaint, - workspace: Workspace, commandManager: CommandManager) - : BaseTool(contextCallback, toolOptionsViewController, toolPaint, workspace, commandManager) { +class LineTool( + private val brushToolOptionsView: BrushToolOptionsView, + contextCallback: ContextCallback, + toolOptionsViewController: ToolOptionsVisibilityController, + toolPaint: ToolPaint, + workspace: Workspace, + commandManager: CommandManager +) : BaseTool(contextCallback, toolOptionsViewController, toolPaint, workspace, commandManager) { @VisibleForTesting var initialEventCoordinate: PointF? = null + @VisibleForTesting var currentCoordinate: PointF? = null + override var toolType: ToolType = ToolType.LINE + init { brushToolOptionsView.setBrushChangedListener(CommonBrushChangedListener(this)) - brushToolOptionsView.setBrushPreviewListener(CommonBrushPreviewListener(toolPaint, toolType)) + brushToolOptionsView.setBrushPreviewListener( + CommonBrushPreviewListener( + toolPaint, + toolType + ) + ) brushToolOptionsView.setCurrentPaint(toolPaint.paint) } @@ -37,19 +67,17 @@ class LineTool(private val brushToolOptionsView: BrushToolOptionsView, contextCa canvas.run { save() clipRect(0, 0, workspace.width, workspace.height) - drawLine(initialCoordinate.x, - initialCoordinate.y, currentCoordinate.x, - currentCoordinate.y, toolPaint.previewPaint) + drawLine( + initialCoordinate.x, + initialCoordinate.y, currentCoordinate.x, + currentCoordinate.y, toolPaint.previewPaint + ) restore() } } } } - override fun getToolType(): ToolType { - return ToolType.LINE - } - override fun handleDown(coordinate: PointF?): Boolean { coordinate ?: return false initialEventCoordinate = PointF(coordinate.x, coordinate.y) @@ -69,8 +97,10 @@ class LineTool(private val brushToolOptionsView: BrushToolOptionsView, contextCa } val bounds = RectF() val finalPath = Path().apply { - moveTo(initialEventCoordinate?.x ?: return false, - initialEventCoordinate?.y ?: return false) + moveTo( + initialEventCoordinate?.x ?: return false, + initialEventCoordinate?.y ?: return false + ) lineTo(coordinate.x, coordinate.y) computeBounds(bounds, true) } @@ -93,4 +123,4 @@ class LineTool(private val brushToolOptionsView: BrushToolOptionsView, contextCa super.changePaintColor(color) brushToolOptionsView.invalidate() } -} \ No newline at end of file +} 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 c3a655263b..dbb675b166 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 @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -16,7 +16,6 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ - package org.catrobat.paintroid.tools.implementation import android.graphics.Bitmap @@ -25,7 +24,11 @@ import android.graphics.Color import android.graphics.PointF import android.os.Bundle import androidx.annotation.VisibleForTesting -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import org.catrobat.paintroid.command.CommandManager import org.catrobat.paintroid.tools.ContextCallback import org.catrobat.paintroid.tools.ToolPaint @@ -39,25 +42,30 @@ import kotlin.math.pow import kotlin.math.sin import kotlin.random.Random -class SprayTool(var stampToolOptionsView: SprayToolOptionsView, - val contextCallback: ContextCallback, - toolOptionsViewController: ToolOptionsVisibilityController, - toolPaint: ToolPaint, - workspace: Workspace, - commandManager: CommandManager) - : BaseTool(contextCallback, toolOptionsViewController, toolPaint, workspace, commandManager) { +class SprayTool( + var stampToolOptionsView: SprayToolOptionsView, + override var contextCallback: ContextCallback, + toolOptionsViewController: ToolOptionsVisibilityController, + toolPaint: ToolPaint, + workspace: Workspace, + commandManager: CommandManager +) : BaseTool(contextCallback, toolOptionsViewController, toolPaint, workspace, commandManager) { @VisibleForTesting var sprayToolScope = CoroutineScope(Dispatchers.Main) + @VisibleForTesting var sprayedPoints = ConcurrentLinkedQueue() + @VisibleForTesting var sprayActive = false - private var currentCoordinate: PointF? = null - private var previewBitmap: Bitmap = Bitmap.createBitmap(workspace.width, workspace.height, Bitmap.Config.ARGB_8888) - private val previewCanvas = Canvas(previewBitmap) + override var toolType: ToolType = ToolType.SPRAY + private var currentCoordinate: PointF? = null private var sprayRadius = DEFAULT_RADIUS + private var previewBitmap: Bitmap = + Bitmap.createBitmap(workspace.width, workspace.height, Bitmap.Config.ARGB_8888) + private val previewCanvas = Canvas(previewBitmap) companion object { const val BUNDLE_RADIUS = "BUNDLE_RADIUS" @@ -69,7 +77,7 @@ class SprayTool(var stampToolOptionsView: SprayToolOptionsView, stampToolOptionsView.setCallback(object : SprayToolOptionsView.Callback { override fun radiusChanged(radius: Int) { - sprayRadius = DEFAULT_RADIUS + radius * 2 + sprayRadius = DEFAULT_RADIUS + radius * 2 } }) @@ -77,8 +85,8 @@ class SprayTool(var stampToolOptionsView: SprayToolOptionsView, toolOptionsViewController.showDelayed() } - override fun draw(canvas: Canvas?) { - canvas?.run { + override fun draw(canvas: Canvas) { + canvas.run { save() drawBitmap(previewBitmap, 0.0f, 0.0f, null) restore() @@ -98,7 +106,7 @@ class SprayTool(var stampToolOptionsView: SprayToolOptionsView, } override fun handleDown(coordinate: PointF?): Boolean { - if(sprayActive || coordinate == null) { + if (sprayActive || coordinate == null) { return false } @@ -138,11 +146,10 @@ class SprayTool(var stampToolOptionsView: SprayToolOptionsView, commandManager.addCommand(command) } - private fun createSprayPatternAsync() { sprayToolScope = CoroutineScope(Dispatchers.Default) sprayToolScope.launch { - while(true) { + while (true) { repeat((sprayRadius / DEFAULT_RADIUS)) { val point = createRandomPointInCircle() if (workspace.contains(point)) { @@ -172,8 +179,4 @@ class SprayTool(var stampToolOptionsView: SprayToolOptionsView, point.y = radius * sin(theta).toFloat() + (currentCoordinate?.y ?: 0f) return point } - - override fun getToolType(): ToolType? { - return ToolType.SPRAY - } -} \ No newline at end of file +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/options/FillToolOptionsView.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/options/FillToolOptionsView.kt new file mode 100644 index 0000000000..1705b76e65 --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/options/FillToolOptionsView.kt @@ -0,0 +1,26 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.tools.options + +interface FillToolOptionsView { + fun setCallback(callback: Callback) + interface Callback { + fun onColorToleranceChanged(colorTolerance: Int) + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/ui/DrawingSurface.java b/Paintroid/src/main/java/org/catrobat/paintroid/ui/DrawingSurface.java deleted file mode 100644 index 675ad410d8..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/ui/DrawingSurface.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.ui; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.BitmapShader; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.PixelFormat; -import android.graphics.Point; -import android.graphics.PointF; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; -import android.graphics.Rect; -import android.graphics.Shader; -import android.os.Build; -import android.os.Handler; -import android.os.Looper; -import android.util.AttributeSet; -import android.view.SurfaceHolder; -import android.view.SurfaceView; - -import org.catrobat.paintroid.R; -import org.catrobat.paintroid.contract.LayerContracts; -import org.catrobat.paintroid.listener.DrawingSurfaceListener; -import org.catrobat.paintroid.listener.DrawingSurfaceListener.AutoScrollTask; -import org.catrobat.paintroid.listener.DrawingSurfaceListener.AutoScrollTaskCallback; -import org.catrobat.paintroid.tools.Tool; -import org.catrobat.paintroid.tools.ToolReference; -import org.catrobat.paintroid.tools.ToolType; -import org.catrobat.paintroid.tools.options.ToolOptionsViewController; - -import java.util.ListIterator; - -import androidx.core.content.ContextCompat; - -public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback { - private final Rect canvasRect = new Rect(); - private final Paint framePaint = new Paint(); - private final Paint checkeredPattern = new Paint(); - private final Object surfaceLock = new Object(); - private boolean surfaceDirty = false; - private boolean surfaceReady = false; - private int backgroundColor; - - private DrawingSurfaceThread drawingThread; - private LayerContracts.Model layerModel; - private Perspective perspective; - private DrawingSurfaceListener drawingSurfaceListener; - private ToolReference toolReference; - private ToolOptionsViewController toolOptionsViewController; - - public DrawingSurface(Context context, AttributeSet attrSet) { - super(context, attrSet); - init(); - } - - public DrawingSurface(Context context) { - super(context); - init(); - } - - private void init() { - backgroundColor = ContextCompat.getColor(getContext(), - R.color.pocketpaint_main_drawing_surface_background); - - framePaint.setColor(Color.BLACK); - framePaint.setStyle(Paint.Style.STROKE); - framePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); - - Bitmap checkerboard = BitmapFactory.decodeResource(getResources(), R.drawable.pocketpaint_checkeredbg); - BitmapShader shader = new BitmapShader(checkerboard, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); - checkeredPattern.setShader(shader); - checkeredPattern.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); - - Handler handler = new Handler(Looper.getMainLooper()); - AutoScrollTask autoScrollTask = new AutoScrollTask(handler, new AutoScrollTaskCallbackImpl()); - float density = getResources().getDisplayMetrics().density; - DrawingSurfaceListener.DrawingSurfaceListenerCallback callback = new DrawingSurfaceListener.DrawingSurfaceListenerCallback() { - @Override - public Tool getCurrentTool() { - return toolReference.get(); - } - - @Override - public void multiplyPerspectiveScale(float factor) { - perspective.multiplyScale(factor); - } - - @Override - public void translatePerspective(float x, float y) { - perspective.translate(x, y); - } - - @Override - public void convertToCanvasFromSurface(PointF surfacePoint) { - perspective.convertToCanvasFromSurface(surfacePoint); - } - - @Override - public ToolOptionsViewController getToolOptionsViewController() { - return toolOptionsViewController; - } - }; - drawingSurfaceListener = new DrawingSurfaceListener(autoScrollTask, callback, density); - setOnTouchListener(drawingSurfaceListener); - } - - public void setArguments(LayerContracts.Model layerModel, Perspective perspective, ToolReference toolReference, ToolOptionsViewController toolOptionsViewController) { - this.layerModel = layerModel; - this.perspective = perspective; - this.toolReference = toolReference; - this.toolOptionsViewController = toolOptionsViewController; - } - - private synchronized void doDraw(Canvas surfaceViewCanvas) { - final LayerContracts.Model model = layerModel; - - synchronized (model) { - if (surfaceReady) { - - canvasRect.set(0, 0, model.getWidth(), model.getHeight()); - - perspective.applyToCanvas(surfaceViewCanvas); - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { - surfaceViewCanvas.drawColor(backgroundColor, PorterDuff.Mode.SRC); - } else { - surfaceViewCanvas.save(); - surfaceViewCanvas.clipOutRect(canvasRect); - surfaceViewCanvas.drawColor(backgroundColor, PorterDuff.Mode.SRC); - surfaceViewCanvas.restore(); - } - - surfaceViewCanvas.drawRect(canvasRect, checkeredPattern); - surfaceViewCanvas.drawRect(canvasRect, framePaint); - - ListIterator iterator = model.listIterator(model.getLayerCount()); - while (iterator.hasPrevious()) { - surfaceViewCanvas.drawBitmap(iterator.previous().getBitmap(), 0, 0, null); - } - - Tool tool = toolReference.get(); - if (tool != null) { - tool.draw(surfaceViewCanvas); - } - } - } - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - getHolder().addCallback(this); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - getHolder().removeCallback(this); - } - - public void refreshDrawingSurface() { - synchronized (surfaceLock) { - surfaceDirty = true; - surfaceLock.notify(); - } - } - - public void enableAutoScroll() { - drawingSurfaceListener.enableAutoScroll(); - } - - public void disableAutoScroll() { - drawingSurfaceListener.disableAutoScroll(); - } - - public synchronized void setBitmap(Bitmap bitmap) { - layerModel.getCurrentLayer().setBitmap(bitmap); - } - - public synchronized boolean isPointOnCanvas(int pointX, int pointY) { - return pointX > 0 && pointX < layerModel.getWidth() - && pointY > 0 && pointY < layerModel.getHeight(); - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - surfaceReady = true; - ToolType currentToolType = toolReference.get().getToolType(); - - if (currentToolType != ToolType.IMPORTPNG && currentToolType != ToolType.TRANSFORM && currentToolType != ToolType.TEXT) { - perspective.resetScaleAndTranslation(); - } - perspective.setSurfaceFrame(holder.getSurfaceFrame()); - - if (drawingThread != null) { - drawingThread.start(); - } - - refreshDrawingSurface(); - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - holder.setFormat(PixelFormat.RGBA_8888); - - if (drawingThread != null) { - drawingThread.stop(); - } - drawingThread = new DrawingSurfaceThread(this, new DrawLoop()); - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - surfaceReady = false; - if (drawingThread != null) { - drawingThread.stop(); - } - } - - private class AutoScrollTaskCallbackImpl implements AutoScrollTaskCallback { - public boolean isPointOnCanvas(int pointX, int pointY) { - return DrawingSurface.this.isPointOnCanvas(pointX, pointY); - } - - public void refreshDrawingSurface() { - DrawingSurface.this.refreshDrawingSurface(); - } - - public void handleToolMove(PointF coordinate) { - toolReference.get().handleMove(coordinate); - } - - public Point getToolAutoScrollDirection(float pointX, float pointY, int screenWidth, int screenHeight) { - return toolReference.get().getAutoScrollDirection(pointX, pointY, screenWidth, screenHeight); - } - - public float getPerspectiveScale() { - return perspective.getScale(); - } - - public void translatePerspective(float dx, float dy) { - perspective.translate(dx, dy); - } - - public void convertToCanvasFromSurface(PointF surfacePoint) { - perspective.convertToCanvasFromSurface(surfacePoint); - } - - public ToolType getCurrentToolType() { - return toolReference.get().getToolType(); - } - } - - private class DrawLoop implements Runnable { - final SurfaceHolder holder = getHolder(); - - @Override - public void run() { - - synchronized (surfaceLock) { - if (!surfaceDirty && surfaceReady) { - try { - surfaceLock.wait(); - } catch (InterruptedException e) { - return; - } - } else { - surfaceDirty = false; - } - - if (!surfaceReady) { - return; - } - } - - Canvas canvas = null; - - synchronized (holder) { - try { - canvas = holder.lockCanvas(); - if (canvas != null) { - doDraw(canvas); - } - } finally { - if (canvas != null) { - holder.unlockCanvasAndPost(canvas); - } - } - } - } - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/ui/DrawingSurface.kt b/Paintroid/src/main/java/org/catrobat/paintroid/ui/DrawingSurface.kt new file mode 100644 index 0000000000..b92aafafa2 --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/ui/DrawingSurface.kt @@ -0,0 +1,279 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.ui + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.BitmapShader +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.graphics.PixelFormat +import android.graphics.Point +import android.graphics.PointF +import android.graphics.PorterDuff +import android.graphics.PorterDuffXfermode +import android.graphics.Rect +import android.graphics.Shader +import android.os.Build +import android.os.Handler +import android.os.Looper +import android.util.AttributeSet +import android.view.SurfaceHolder +import android.view.SurfaceView +import androidx.core.content.ContextCompat +import org.catrobat.paintroid.R +import org.catrobat.paintroid.contract.LayerContracts +import org.catrobat.paintroid.listener.DrawingSurfaceListener +import org.catrobat.paintroid.listener.DrawingSurfaceListener.AutoScrollTask +import org.catrobat.paintroid.listener.DrawingSurfaceListener.AutoScrollTaskCallback +import org.catrobat.paintroid.listener.DrawingSurfaceListener.DrawingSurfaceListenerCallback +import org.catrobat.paintroid.tools.Tool +import org.catrobat.paintroid.tools.ToolReference +import org.catrobat.paintroid.tools.ToolType +import org.catrobat.paintroid.tools.options.ToolOptionsViewController + +open class DrawingSurface : SurfaceView, SurfaceHolder.Callback { + private val canvasRect = Rect() + private val framePaint = Paint() + private val checkeredPattern = Paint() + private var surfaceDirty = false + private var surfaceReady = false + private var bgColor = 0 + private var surfaceLock: Object? = null + private var drawingThread: DrawingSurfaceThread? = null + private var drawingSurfaceListener: DrawingSurfaceListener + private lateinit var layerModel: LayerContracts.Model + private lateinit var perspective: Perspective + private lateinit var toolReference: ToolReference + private lateinit var toolOptionsViewController: ToolOptionsViewController + + constructor(context: Context?, attrSet: AttributeSet?) : super(context, attrSet) {} + + constructor(context: Context?) : super(context) {} + + init { + surfaceLock = Object() + bgColor = ContextCompat.getColor( + context, + R.color.pocketpaint_main_drawing_surface_background + ) + framePaint.color = Color.BLACK + framePaint.style = Paint.Style.STROKE + framePaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC) + val checkerboard = + BitmapFactory.decodeResource(resources, R.drawable.pocketpaint_checkeredbg) + val shader = BitmapShader(checkerboard, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT) + checkeredPattern.shader = shader + checkeredPattern.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC) + val handler = Handler(Looper.getMainLooper()) + val autoScrollTask = AutoScrollTask(handler, AutoScrollTaskCallbackImpl()) + val density = resources.displayMetrics.density + val callback: DrawingSurfaceListenerCallback = object : DrawingSurfaceListenerCallback { + override fun getCurrentTool(): Tool = toolReference.get() + + override fun multiplyPerspectiveScale(factor: Float) { + perspective.multiplyScale(factor) + } + + override fun translatePerspective(x: Float, y: Float) { + perspective.translate(x, y) + } + + override fun convertToCanvasFromSurface(surfacePoint: PointF) { + perspective.convertToCanvasFromSurface(surfacePoint) + } + + override fun getToolOptionsViewController(): ToolOptionsViewController = + toolOptionsViewController + } + drawingSurfaceListener = DrawingSurfaceListener(autoScrollTask, callback, density) + setOnTouchListener(drawingSurfaceListener) + } + + fun setArguments( + layerModel: LayerContracts.Model, + perspective: Perspective, + toolReference: ToolReference, + toolOptionsViewController: ToolOptionsViewController + ) { + this.layerModel = layerModel + this.perspective = perspective + this.toolReference = toolReference + this.toolOptionsViewController = toolOptionsViewController + } + + @Synchronized + private fun doDraw(surfaceViewCanvas: Canvas) { + synchronized(layerModel) { + if (surfaceReady) { + canvasRect.set(0, 0, layerModel.width, layerModel.height) + perspective.applyToCanvas(surfaceViewCanvas) + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + surfaceViewCanvas.drawColor(bgColor, PorterDuff.Mode.SRC) + } else { + surfaceViewCanvas.save() + surfaceViewCanvas.clipOutRect(canvasRect) + surfaceViewCanvas.drawColor(bgColor, PorterDuff.Mode.SRC) + surfaceViewCanvas.restore() + } + + surfaceViewCanvas.drawRect(canvasRect, checkeredPattern) + surfaceViewCanvas.drawRect(canvasRect, framePaint) + + val iterator = layerModel.listIterator(layerModel.layerCount) + + while (iterator.hasPrevious()) { + surfaceViewCanvas.drawBitmap(iterator.previous().bitmap, 0f, 0f, null) + } + + val tool = toolReference.get() + tool?.draw(surfaceViewCanvas) + } + } + } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + holder.addCallback(this) + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + holder.removeCallback(this) + } + + fun refreshDrawingSurface() { + surfaceLock?.apply { + synchronized(this) { + surfaceDirty = true + notify() + } + } + } + + fun enableAutoScroll() { + drawingSurfaceListener.enableAutoScroll() + } + + fun disableAutoScroll() { + drawingSurfaceListener.disableAutoScroll() + } + + @Synchronized + fun setBitmap(bitmap: Bitmap?) { + layerModel.currentLayer.bitmap = bitmap + } + + fun isPointOnCanvas(pointX: Int, pointY: Int): Boolean = + pointX > 0 && pointX < layerModel.width && pointY > 0 && pointY < layerModel.height + + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + surfaceReady = true + val currentToolType = toolReference.get().toolType + if (currentToolType != ToolType.IMPORTPNG && currentToolType != ToolType.TRANSFORM && currentToolType != ToolType.TEXT) { + perspective.resetScaleAndTranslation() + } + perspective.setSurfaceFrame(holder.surfaceFrame) + drawingThread?.start() + refreshDrawingSurface() + } + + override fun surfaceCreated(holder: SurfaceHolder) { + holder.setFormat(PixelFormat.RGBA_8888) + drawingThread?.stop() + drawingThread = DrawingSurfaceThread(this, DrawLoop()) + } + + override fun surfaceDestroyed(holder: SurfaceHolder) { + surfaceReady = false + drawingThread?.stop() + } + + private open inner class AutoScrollTaskCallbackImpl : AutoScrollTaskCallback { + override fun isPointOnCanvas(pointX: Int, pointY: Int): Boolean = + this@DrawingSurface.isPointOnCanvas(pointX, pointY) + + override fun refreshDrawingSurface() { + this@DrawingSurface.refreshDrawingSurface() + } + + override fun handleToolMove(coordinate: PointF) { + toolReference.get().handleMove(coordinate) + } + + override fun getToolAutoScrollDirection( + pointX: Float, + pointY: Float, + screenWidth: Int, + screenHeight: Int + ): Point = toolReference.get() + .getAutoScrollDirection(pointX, pointY, screenWidth, screenHeight) + + override fun getPerspectiveScale(): Float = perspective.scale + + override fun translatePerspective(dx: Float, dy: Float) { + perspective.translate(dx, dy) + } + + override fun convertToCanvasFromSurface(surfacePoint: PointF) { + perspective.convertToCanvasFromSurface(surfacePoint) + } + + override fun getCurrentToolType(): ToolType = toolReference.get().toolType + } + + private inner class DrawLoop : Runnable { + val holder: SurfaceHolder = getHolder() + override fun run() { + surfaceLock?.apply { + synchronized(this) { + if (!surfaceDirty && surfaceReady) { + try { + wait() + } catch (e: InterruptedException) { + return + } + } else { + surfaceDirty = false + } + if (!surfaceReady) { + return + } + } + } + + var canvas: Canvas? = null + synchronized(holder) { + try { + canvas = holder.lockCanvas() + canvas?.let { + doDraw(it) + } + } finally { + canvas?.let { + holder.unlockCanvasAndPost(it) + } + } + } + } + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/ui/LayerAdapter.java b/Paintroid/src/main/java/org/catrobat/paintroid/ui/LayerAdapter.java deleted file mode 100644 index ad44fa4a2e..0000000000 --- a/Paintroid/src/main/java/org/catrobat/paintroid/ui/LayerAdapter.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team - * () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.catrobat.paintroid.ui; - -import android.graphics.Bitmap; -import android.graphics.Color; -import android.util.SparseArray; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.CheckBox; -import android.widget.ImageView; -import android.widget.LinearLayout; - -import org.catrobat.paintroid.R; -import org.catrobat.paintroid.contract.LayerContracts; -import org.catrobat.paintroid.controller.DefaultToolController; -import org.catrobat.paintroid.tools.ToolType; -import org.catrobat.paintroid.ui.viewholder.BottomNavigationViewHolder; - -public class LayerAdapter extends BaseAdapter implements LayerContracts.Adapter { - private final LayerContracts.Presenter presenter; - private final SparseArray viewHolders; - - public LayerAdapter(LayerContracts.Presenter presenter) { - this.presenter = presenter; - viewHolders = new SparseArray<>(); - } - - @Override - public int getCount() { - return presenter.getLayerCount(); - } - - public LayerContracts.Presenter getPresenter() { - return this.presenter; - } - - @Override - public Object getItem(int position) { - return presenter.getLayerItem(position); - } - - @Override - public long getItemId(int position) { - return presenter.getLayerItemId(position); - } - - @Override - public void notifyDataSetChanged() { - viewHolders.clear(); - super.notifyDataSetChanged(); - } - - @Override - public View getView(final int position, View convertView, final ViewGroup parent) { - final LayerContracts.LayerViewHolder viewHolder; - - if (convertView == null) { - LayoutInflater inflater = LayoutInflater.from(parent.getContext()); - convertView = inflater.inflate(R.layout.pocketpaint_item_layer, parent, false); - viewHolder = new LayerViewHolder(convertView, presenter); - convertView.setTag(viewHolder); - } else { - viewHolder = (LayerContracts.LayerViewHolder) convertView.getTag(); - } - viewHolders.put(position, viewHolder); - presenter.onBindLayerViewHolderAtPosition(position, viewHolder); - final CheckBox checkBox = convertView.findViewById(R.id.pocketpaint_checkbox_layer); - checkBox.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View arg0) { - final boolean isChecked = checkBox.isChecked(); - if (isChecked) { - presenter.unhideLayer(position, viewHolder); - presenter.getLayerItem(position).setCheckBox(isChecked); - } else { - presenter.hideLayer(position); - presenter.getLayerItem(position).setCheckBox(isChecked); - } - } - }); - return convertView; - } - - @Override - public LayerContracts.LayerViewHolder getViewHolderAt(int position) { - return viewHolders.get(position); - } - - static class LayerViewHolder implements LayerContracts.LayerViewHolder { - private final View itemView; - private final LinearLayout layerBackground; - private final ImageView imageView; - private Bitmap bitmap; - private CheckBox checkBox; - private LayerContracts.Presenter layerPresenter; - - LayerViewHolder(View itemView, LayerContracts.Presenter layerPresenter) { - this.itemView = itemView; - layerBackground = itemView.findViewById(R.id.pocketpaint_item_layer_background); - imageView = itemView.findViewById(R.id.pocketpaint_item_layer_image); - this.checkBox = itemView.findViewById(R.id.pocketpaint_checkbox_layer); - this.layerPresenter = layerPresenter; - } - - @Override - public void setSelected(int position, BottomNavigationViewHolder bottomNavigationViewHolder, DefaultToolController defaultToolController) { - if (!layerPresenter.getLayerItem(position).getCheckBox()) { - defaultToolController.switchTool(ToolType.HAND, false); - bottomNavigationViewHolder.showCurrentTool(ToolType.HAND); - } - layerBackground.setBackgroundColor(Color.BLUE); - } - - @Override - public void setSelected() { - layerBackground.setBackgroundColor(Color.BLUE); - } - - @Override - public void setDeselected() { - layerBackground.setBackgroundColor(Color.TRANSPARENT); - } - - @Override - public void setBitmap(Bitmap bitmap) { - imageView.setImageBitmap(bitmap); - this.bitmap = bitmap; - } - - @Override - public void setCheckBox(boolean setTo) { - this.checkBox.setChecked(setTo); - } - - @Override - public Bitmap getBitmap() { - return this.bitmap; - } - - @Override - public View getView() { - return itemView; - } - - @Override - public void setMergable() { - layerBackground.setBackgroundColor(Color.YELLOW); - } - } -} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/ui/LayerAdapter.kt b/Paintroid/src/main/java/org/catrobat/paintroid/ui/LayerAdapter.kt new file mode 100644 index 0000000000..c4486d533d --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/ui/LayerAdapter.kt @@ -0,0 +1,154 @@ +/* + * Paintroid: An image manipulation application for Android. + * Copyright (C) 2010-2021 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.catrobat.paintroid.ui + +import android.graphics.Bitmap +import android.graphics.Color +import android.util.SparseArray +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.BaseAdapter +import android.widget.CheckBox +import android.widget.ImageView +import android.widget.LinearLayout +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.catrobat.paintroid.R +import org.catrobat.paintroid.contract.LayerContracts +import org.catrobat.paintroid.controller.DefaultToolController +import org.catrobat.paintroid.tools.ToolType +import org.catrobat.paintroid.ui.viewholder.BottomNavigationViewHolder + +class LayerAdapter(val presenter: LayerContracts.Presenter) : BaseAdapter(), LayerContracts.Adapter { + private val viewHolders: SparseArray = SparseArray() + private var isDrawerLayoutOpen = false + + override fun getCount() = presenter.layerCount + + override fun getItem(position: Int): LayerContracts.Layer = presenter.getLayerItem(position) + + override fun getItemId(position: Int) = presenter.getLayerItemId(position) + + override fun notifyDataSetChanged() { + viewHolders.clear() + super.notifyDataSetChanged() + } + + override fun setDrawerLayoutOpen(isOpen: Boolean) { + isDrawerLayoutOpen = isOpen + } + + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View? { + var localConvertView = convertView + val viewHolder: LayerContracts.LayerViewHolder + if (localConvertView == null) { + val inflater = LayoutInflater.from(parent.context) + localConvertView = inflater.inflate(R.layout.pocketpaint_item_layer, parent, false) + viewHolder = LayerViewHolder(localConvertView, presenter) + localConvertView.tag = viewHolder + } else { + viewHolder = localConvertView.tag as LayerContracts.LayerViewHolder + } + viewHolders.put(position, viewHolder) + presenter.onBindLayerViewHolderAtPosition(position, viewHolder, isDrawerLayoutOpen) + val checkBox = localConvertView?.findViewById(R.id.pocketpaint_checkbox_layer) + checkBox?.setOnClickListener { + with (presenter) { + if (checkBox.isChecked) { + unhideLayer(position, viewHolder) + getLayerItem(position).checkBox = true + } else { + hideLayer(position) + getLayerItem(position).checkBox = false + } + } + } + return localConvertView + } + + override fun getViewHolderAt(position: Int): LayerContracts.LayerViewHolder? { + return viewHolders[position] + } + + internal class LayerViewHolder(private val itemView: View, private val layerPresenter: LayerContracts.Presenter) : LayerContracts.LayerViewHolder { + private val layerBackground: LinearLayout = itemView.findViewById(R.id.pocketpaint_item_layer_background) + private val imageView: ImageView = itemView.findViewById(R.id.pocketpaint_item_layer_image) + private var bitmap: Bitmap? = null + private val checkBox: CheckBox = itemView.findViewById(R.id.pocketpaint_checkbox_layer) + + companion object { + private const val RESIZE_LENGTH = 400f + } + + override fun setSelected(position: Int, bottomNavigationViewHolder: BottomNavigationViewHolder, defaultToolController: DefaultToolController) { + if (!layerPresenter.getLayerItem(position).checkBox) { + defaultToolController.switchTool(ToolType.HAND, false) + bottomNavigationViewHolder.showCurrentTool(ToolType.HAND) + } + layerBackground.setBackgroundColor(Color.BLUE) + } + + override fun setSelected() { + layerBackground.setBackgroundColor(Color.BLUE) + } + + override fun setDeselected() { + layerBackground.setBackgroundColor(Color.TRANSPARENT) + } + + override fun setBitmap(bitmap: Bitmap) { + this.bitmap = bitmap + } + + override fun updateImageView(bitmap: Bitmap, isDrawerLayerOpen: Boolean) { + if (isDrawerLayerOpen) { + runBlocking { + launch { + imageView.setImageBitmap(resizeBitmap(bitmap)) + } + } + } + setBitmap(bitmap) + } + + private fun resizeBitmap(bitmap: Bitmap): Bitmap { + val newWidth: Float + val newHeight: Float + if (bitmap.width > bitmap.height) { + newWidth = RESIZE_LENGTH + newHeight = RESIZE_LENGTH * (bitmap.height.toFloat() / bitmap.width.toFloat()) + 1 + } else { + newWidth = RESIZE_LENGTH * (bitmap.width.toFloat() / bitmap.height.toFloat()) + 1 + newHeight = RESIZE_LENGTH + } + return Bitmap.createScaledBitmap(bitmap, newWidth.toInt(), newHeight.toInt(), false) + } + + override fun setCheckBox(setTo: Boolean) { + checkBox.isChecked = setTo + } + + override fun getView() = itemView + + override fun setMergable() = layerBackground.setBackgroundColor(Color.YELLOW) + + override fun getBitmap() = bitmap + } +} diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/ui/tools/DefaultFillToolOptionsView.java b/Paintroid/src/main/java/org/catrobat/paintroid/ui/tools/DefaultFillToolOptionsView.java index b5018659b2..60830697e6 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/ui/tools/DefaultFillToolOptionsView.java +++ b/Paintroid/src/main/java/org/catrobat/paintroid/ui/tools/DefaultFillToolOptionsView.java @@ -1,6 +1,6 @@ /* * Paintroid: An image manipulation application for Android. - * Copyright (C) 2010-2015 The Catrobat Team + * Copyright (C) 2010-2021 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -16,7 +16,6 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ - package org.catrobat.paintroid.ui.tools; import android.text.Editable; @@ -31,11 +30,12 @@ import org.catrobat.paintroid.R; import org.catrobat.paintroid.tools.helper.DefaultNumberRangeFilter; -import org.catrobat.paintroid.tools.implementation.FillTool; import org.catrobat.paintroid.tools.options.FillToolOptionsView; import java.util.Locale; +import static org.catrobat.paintroid.tools.implementation.FillToolKt.DEFAULT_TOLERANCE_IN_PERCENT; + public class DefaultFillToolOptionsView implements FillToolOptionsView { private SeekBar colorToleranceSeekBar; private EditText colorToleranceEditText; @@ -85,7 +85,7 @@ public void afterTextChanged(Editable s) { } } }); - setColorToleranceText(FillTool.DEFAULT_TOLERANCE_IN_PERCENT); + setColorToleranceText(DEFAULT_TOLERANCE_IN_PERCENT); } private void updateColorTolerance(int colorTolerance) { diff --git a/Paintroid/src/main/res/layout/dialog_pocketpaint_spray_tool.xml b/Paintroid/src/main/res/layout/dialog_pocketpaint_spray_tool.xml index bd9fced42e..c266fb1477 100644 --- a/Paintroid/src/main/res/layout/dialog_pocketpaint_spray_tool.xml +++ b/Paintroid/src/main/res/layout/dialog_pocketpaint_spray_tool.xml @@ -45,6 +45,7 @@ android:background="@drawable/pocketpaint_round_rect_shape" android:textColor="?attr/colorAccent" android:textStyle="bold" + android:layoutDirection="ltr" tools:ignore="LabelFor" tools:text="100" /> diff --git a/Paintroid/src/main/res/layout/dialog_pocketpaint_stroke.xml b/Paintroid/src/main/res/layout/dialog_pocketpaint_stroke.xml index 0c7bfbaa4e..9e80dec075 100644 --- a/Paintroid/src/main/res/layout/dialog_pocketpaint_stroke.xml +++ b/Paintroid/src/main/res/layout/dialog_pocketpaint_stroke.xml @@ -45,6 +45,7 @@ android:background="@drawable/pocketpaint_round_rect_shape" android:textColor="?attr/colorAccent" android:textStyle="bold" + android:layoutDirection="ltr" tools:ignore="LabelFor" android:gravity="center" tools:text="100" /> @@ -81,9 +82,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:layoutDirection="ltr" app:singleSelection="true" - app:singleLine="true" - android:layoutDirection="ltr"> + app:singleLine="true"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Paintroid/src/main/res/layout/pocketpaint_slide_intro_tools_selection.xml b/Paintroid/src/main/res/layout/pocketpaint_slide_intro_tools_selection.xml index 3aa4744b76..41e00b4937 100644 --- a/Paintroid/src/main/res/layout/pocketpaint_slide_intro_tools_selection.xml +++ b/Paintroid/src/main/res/layout/pocketpaint_slide_intro_tools_selection.xml @@ -31,7 +31,8 @@ android:layout_height="wrap_content" android:layout_toEndOf="@+id/pocketpaint_textview_intro_tools_header" tools:src="@drawable/ic_pocketpaint_dialog_warning" - android:contentDescription="@string/pocketpaint_tool_icon_description" /> + android:contentDescription="@string/pocketpaint_tool_icon_description" + app:tint="@color/pocketpaint_color_picker_white" /> الوصول الى الحد الأقصى لدقة الشاشة النص الخاص بك: خيارات التنسيق: - تسطير - مائل - غامق + يو + ص + ب abc أنقر هنا للكتابة مستطيل diff --git a/Paintroid/src/main/res/values-az-rAZ/string.xml b/Paintroid/src/main/res/values-az-rAZ/string.xml index 209d82f68a..ff6bda175b 100644 --- a/Paintroid/src/main/res/values-az-rAZ/string.xml +++ b/Paintroid/src/main/res/values-az-rAZ/string.xml @@ -25,7 +25,7 @@ Pipetka Geri qaytar Təkrarla - Information + Məlumat Ştamp Təsvir əlavə et Pozan @@ -35,19 +35,19 @@ Mətn Formalar Əl - Spray can + Sprey qutusu Tətbiq et - Checkmark + Təsdiq işarəsi Hazırdır - Gallery - Could not load Sticker - Something went wrong. + Qalareya + Stiker yüklənə bilmədi + Nəsə səhv getdi. Dairə Kvadrat - Paste + Yapışdır Surətini çıxar - Cut - Stickers + Kəs + Stikerlər Alətlər Fayl yükləmə/saxlama xətası Təsviri və ya SD kartı yoxla! @@ -60,132 +60,132 @@ Əvvəlki hərəkəti geri qaytarmaq üçün toxunun. Geri qaytarılan hərəkəti təkrarlamaq üçün toxunun. Bir sahəni seçilmiş rənglə doldurmaq üçün təsvirə toxunun. - Position the cursor where you want to draw. Tap to activate the cursor. Move your finger to draw. Tap again to deactivate. - Use to transform the image. + Kursoru çəkmək istədiyiniz yerə aparın. Kursuru aktivləşdirmək üçün toxunun. Çəkmək üçün barmağınızı hərəkət etdirin. Deaktiv etmək üçün yenidən toxunun. + Təsviri çevirmək üçün istifadə edin. Move and resize the rectangle to cover the area you want to stamp. Long press to select the area. Move and tap again to stamp. - Import an image from the gallery to the stamp tool. - Draw a straight line. + Qalareyadakı bir təsviri möhür alətinə idxal edin. + Düz bir xətt çəkin. Write text and format it. Resize the text box afterwards. Tap to insert the text on the image. Choose a shape and tap it to insert the selected shape. - Create new layers or modify existing ones. - Select or adjust a color. - Move your finger to move the canvas. - Move your finger on the image to create a spray can pattern. - Back to project - Quit - Save changes? - New image - Discard image - You are only able to merge or reorder if all layers are visible - No tools are available on hidden layer - Load image - Save image - Save copy - Fullscreen - Share image - Send image via + Yeni qatlar yaradın və ya mövcud qatları dəyişdirin. + Seçin və ya bir rəng nizamlayın. + Kətanı hərəkət etdirmək üçün barmağınızı hərəkət etdirin. + Sprey qutu forması yaratmaq üçün təsvirdə barmağınızı hərəkət etdirin. + Layihəyə geri qayıdın + Çıxış + Dəyişikliklər saxlanılsın? + Yeni təsvir + Təsviri sil + Yalnız bütün qatlar görünürsə birləşdirilə və ye yenidən sıralana bilər + Gizli qatda heç bir alət mövcud deyil + Təsvir yüklə + Təsvir saxla + Kopyasını saxla + Tam ekran + Təsviri paylaş + Təsviri göndər Bizə qiymət verin! - Export - Feedback - Image saved to\n - Image saved - Copy saved to\n - Copy saved - Quit - Save - Discard + İxrac et + Əks əlaqə + Təsvir saxlanıldı\n + Təsvir saxlanıldı + Kopyası saxlanıldı\n + Kopya saxlanıldı + Çıxış + Saxla + Ləğv et İmtina et - Overwrite - nothing to resize - cannot resize to this size - max image resolution reached - Your text: - Format options: + Üzərinə yaz + ölçüsü dəyişdiriləcək heç nə yoxdur + bu ölçüdə təyin edilə bilməz + maksimal təsvir ölçülərinə çatıldı + Mətniniz: + Format seçimləri: U I B abc - Tap here to write - Rectangle - Ellipse - Star - Heart + Yazmaq üçün bura toxunun + Düzbucaqlı + Elips + Ulduz + Ürək Doldur - Outline - Color tolerance - rotate left - rotate right - flip vertical - flip horizontal - resize - crop/enlarge - Width - Height - Auto - px - Long press to copy content - Layers - New layer - Delete layer - Too many layers - Layers merged - Layer background - Shape - Error on loading image - Not a valid image + Çevrə + Rəng toleransı + sola döndər + sağa döndər + şaquli çevir + üfüqi çevir + yenidən ölçüləndir + kəs/böyüt + En + Hündürlük + Avto + pk + Məzmunu kopyalamaq üçün uzun basın + Qatlar + Yeni qat + Qatı sil + Həddən çox qat + Birləşdirilən qatlar + Qat arxaplanı + Forma + Təsvir yükləmə xətası + Etibarlı bir təsvir deyil Ayarlar - Image name - Image format - Quality: - Takes up minimal storage space. No transparency is remembered. - Lossless compression. Transparency is preserved. - This format remembers layers. It can be opened by apps that support the Openraster format. - This app needs the requested permission to function properly. In order to save images to the local memory, the app needs read and write access to it. - This app needs the requested permission to function properly. In order to save images to the local memory, the app needs read and write access to it. - As you have denied permission with do not ask again, please go to your phone settings and grant the required permissions if you wish to use the associated functions. + Təsvir adı + Təsvir formatı + Keyfiyyət: + Minimal saxlama sahəsi götürülür. Heç bir şəffaflıq xatırlanmır. + İtkisiz sıxışdırma. Şəffaflıq qorunur. + Bu format qatları xatırlayır. Openraster formatını dəstəkləyən tətbiqlər tərəfindən açıla bilər. + Bu tətbiqin düzgün işləməsi üçün tələb olunan icazəyə ehtiyacı var. Təsvirləri yerli yaddaşda saxlamaq üçün, tətbiqin yazma və oxuma müraciətinə ehtiyacı var. + Bu tətbiqin düzgün işləməsi üçün tələb olunan icazəyə ehtiyacı var. Təsvirləri yerli yaddaşda saxlamaq üçün, tətbiqin yazma və oxuma müraciətinə ehtiyacı var. + Təkrar soruşma ilə icazəni rədd etmisinizsə və əlaqəli özəllikləri istifadə etmək istəyirsinizsə, zəhmət olmasa telefon tənzimləmələrinə gedib lazımi icazələri verin. Open navigation drawer Close navigation drawer Drag edges to their new position, then tap to enlarge or crop the image area. Pan to position, then tap to start painting. Pan to draw, then tap again to stop painting. - Welcome To Pocket Paint - With Pocket Paint there are no limits to your creativity. If you are new, start the intro, or skip it if you are already familiar with Pocket Paint. - Click on a tool to get more information - More possibilities - Use the top bar to open the main menu and undo or redo changes - Landscape - Pocket Paint also supports drawing in landscape mode to give you the best painting experience. - You are all set. Enjoy Pocket Paint. - Get started and create a new masterpiece. - Let\'s go - Next - Skip - About + Cib Boyasına Xoş Gəldiniz + Cib Boyası ilə yaradıcılığınızda sərhəd yoxdur. Yenisinizsə tanıtım başladın, Cib Boyasını bilirsinizsə bu hissəni ötürün. + Daha ətraflı məlumat üçün bir alətə klikləyin + Daha çox imkanlar + Əsas menyunu açmaq və dəyişiklikləri geri almaq və ya yenidən etmək üçün üst sətri istifadə edin + Üfüqi + Ən yaxşı rəsm təcrübəsi üçün Cib Boyası, üfüqi rejimdə də çəkməni dəstəkləyir. + Hazırsınız. \"Cib Boyası\"ndan həzz alın. + Başla və yeni bir şah əsər yarat + Getdik + Növbəti + Ötür + Haqqında Pocket Paint is a picture editing library that is part of the Catrobat project.\n\nCatrobat is a visual programming language and set of creativity tools for smartphones.\n\nThe source code of Pocket Paint is mainly licensed under the %s.\nFor precise details of the license see the link below. - Pocket Paint source code license + Cib Boyası mənbə kodu lisenziyası Catrobat haqqında - Intro + Giriş Intro does not support split screen. - Overwrite File? - You are about to overwrite an existing image (hint: To save it as a new image, use the \"%s\" option). Save anyway? - Do you like Pocket Paint? - Would you like to rate Pocket Paint? - We are sorry to hear that. If you want to share your experience with us, please write to contact@catrobat.org + Faylın üzərinə yazılsın? + Mövcud bir təsvirin üzərinə yazırsınız (məsləhət: yeni bir təsvir kimi saxlamaq üçün \"%s\" seçimini istifadə edin). Yenə də saxlanılsın? + Cib Boyasını sevdiyiniz? + Cib Boyasını qiymətləndirmək istərdiniz? + Bunu eşitdiyimizə məyus olduq. Əgər təcrübənizi bizimlə paylaşmaq istəsəniz, zəhmət olmasa contact@catrobat.org ünvanına yazın. Bəli Xeyr İmtina et - Not now - Rate Pocket Paint + İndi yox + Cib Boyasını qiymətləndir Alətlər - Current - Color - Layers - Item for bottom navigation - Switch to the tool you want to use. - Shows the currently used tool and opens its options. - Shows the currently used color and opens the color picker. - Opens the layer menu and lets you manage your layers. - Current tool icon - Image is too big to load - The image is too big to load. Click OK to scale down the image automatically. + Hazırki + Rəng + Qatlar + Alt hərəkət üçün element + İstifadə etmək istədiyiniz alətə keçin. + Hazırda istifadə edilən aləti göstərər və seçimləri açar. + Hazırda istifadə edilən rəngi göstərər və rəng seçicini açar. + Qat menyusunu açar və qatlarınızı idarə etməyinizə imkan verər. + Hazırkı alət nişanı + Təsvir yüklənmək üçün çox böyükdür + Təsvir yüklənmək üçün çox böyükdür. Təsviri avtomati kiçiltmək üçün Olduya basın. diff --git a/Paintroid/src/main/res/values-bn-rBD/string.xml b/Paintroid/src/main/res/values-bn-rBD/string.xml index 68efb7dbdf..1cdfd51af6 100644 --- a/Paintroid/src/main/res/values-bn-rBD/string.xml +++ b/Paintroid/src/main/res/values-bn-rBD/string.xml @@ -35,19 +35,19 @@ পাঠ্য আকার হাত - Spray can + স্প্রে করতে পারেন প্রয়োগ করুন - Checkmark + চেক চিহ্ন করা হয়েছে - Gallery - Could not load Sticker + গ্যালারী + স্টিকার লোড করা যায়নি কিছু একটা ভুল হয়েছে বৃত্ত বর্গক্ষেত্র - Paste + আটকান অনুলিপি - Cut - Stickers + কাটা + স্টিকার সরঞ্জামসমূহ ফাইল লোড / সংরক্ষণের সময় ভুল চিত্র বা এসডি-কার্ড পরীক্ষা করুন! @@ -70,41 +70,41 @@ নতুন স্তর তৈরি করুন বা বিদ্যমানগুলি সংশোধন করুন রঙ নির্বাচন বা সমন্বয় করুন ক্যানভাসটি সরানোর জন্য আপনার আঙুলটি সরান। - Move your finger on the image to create a spray can pattern. + স্প্রে ক্যান প্যাটার্ন তৈরি করতে ইমেজটিতে আপনার আঙুলটি সরান। প্রজেক্টে ফিরে যান বের হোন পরিবর্তনগুলোর সংরক্ষন? নতুন ছবি চিত্র বাতিল করুন - You are only able to merge or reorder if all layers are visible - No tools are available on hidden layer + সমস্ত স্তর দৃশ্যমান থাকলে আপনি কেবল মার্জ বা পুনঃক্রম করতে সক্ষম হবেন + লুকানো স্তরে কোনও সরঞ্জাম উপলব্ধ নেই চিত্র লোড করুন চিত্র সংরক্ষণ করুন অনুলিপি সংরক্ষণ করুন পূর্ণস্ক্রিন - Share image - Send image via + ছবি শেয়ার করুন + এর মাধ্যমে চিত্র প্রেরণ করুন আমাদের মতামত দিন রপ্তানি - Feedback - Image saved to\n + মতামত + চিত্রটি এতে সংরক্ষণ করা হয়েছে\n চিত্র সংরক্ষিত হয়েছে - Copy saved to\n + অনুলিপি এতে সংরক্ষণ করা হয়েছে\n অনুলিপি সংরক্ষণ করা হয়েছে বের হোন সংরক্ষণ করুন বাতিল করুন বাতিল - Overwrite + ওভাররাইট পুনঃস্থাপন করার মত কিছু নেই এই আকার পরিবর্তন করতে পারে না সর্বোচ্চ চিত্রের রেজোলিউশনে পৌঁছেছে তোমার পাঠ ফর্ম্যাট অপশন - U - I - B - abc + + আমি + + এবিসি লিখতে এখানে আলতো চাপুন আয়তক্ষেত্র উপবৃত্ত @@ -121,7 +121,7 @@ কাটা/পরিবর্ধন প্রস্থ উচ্চতা - Auto + অটো পিক্সেল বিষয়বস্তু অনুলিপি করতে দীর্ঘ চাপুন স্তর @@ -132,19 +132,19 @@ স্তর ব্যাকগ্রাউন্ড আকার চিত্র লোড করার সময় ভুল - Not a valid image + বৈধ চিত্র নয় সেটিংস ছবির নাম - Image format - Quality: - Takes up minimal storage space. No transparency is remembered. - Lossless compression. Transparency is preserved. - This format remembers layers. It can be opened by apps that support the Openraster format. - This app needs the requested permission to function properly. In order to save images to the local memory, the app needs read and write access to it. - This app needs the requested permission to function properly. In order to save images to the local memory, the app needs read and write access to it. - As you have denied permission with do not ask again, please go to your phone settings and grant the required permissions if you wish to use the associated functions. - Open navigation drawer - Close navigation drawer + চিত্র বিন্যাস + গুণ: + ন্যূনতম সঞ্চয় স্থান নেয় Tকোনও স্বচ্ছতামনে নেই। + ক্ষয়হীন সংকোচনের। স্বচ্ছতা সংরক্ষণ করা হয়। + এই ফর্ম্যাটটি স্তরগুলিমনে রাখে। এটি অ্যাপ্লিকেশনগুলি ওপেনারস্টার ফর্ম্যাটকে সমর্থন করে opened + এই অ্যাপ্লিকেশনটির সঠিকভাবে কাজ করার জন্য অনুরোধ করা অনুমতি দরকার। স্থানীয় মেমোরিতে চিত্রগুলি সংরক্ষণ করার জন্য, অ্যাপ্লিকেশনটির এতে পড়ার এবং লেখার অ্যাক্সেসের প্রয়োজন। + এই অ্যাপ্লিকেশনটির সঠিকভাবে কাজ করার জন্য অনুরোধ করা অনুমতি দরকার। স্থানীয় মেমোরিতে চিত্রগুলি সংরক্ষণ করার জন্য, অ্যাপ্লিকেশনটির এতে পড়ার এবং লেখার অ্যাক্সেসের প্রয়োজন। + আপনি আবারও জিজ্ঞাসা করবেন না এমন অনুমতি যেমন অস্বীকার করেছেন, দয়া করে আপনার ফোন সেটিংসে যান এবং যদি আপনি সম্পর্কিত ফাংশনগুলি ব্যবহার করতে চান তবে প্রয়োজনীয় অনুমতিগুলি দিন। + নেভিগেশন ড্রয়ার খুলুন + নেভিগেশন ড্রয়ারটি বন্ধ করুন প্রান্তগুলি তাদের নতুন অবস্থানে টেনে আনুন, তারপরে চিত্রের ক্ষেত্রটি প্রসারিত করতে বা কাটতে আলতো চাপুন। অবস্থানে প্যান করুন, তারপরে পেইন্টিং শুরু করতে আলতো চাপুন। আঁকতে প্যান করুন, তারপরে পেইন্টিং বন্ধ করতে আবার আলতো চাপুন। @@ -152,40 +152,40 @@ পকেট পেইন্টের সাথে আপনার সৃজনশীলতার সীমাবদ্ধতা নেই। আপনি যদি নতুন হিসেবে সূচনা করেন বা পকেট পেইন্টের সাথে ইতিমধ্যে পরিচিত হন তবে এটি এড়িয়ে যান। আরও তথ্য পেতে একটি সরঞ্জামে ক্লিক করুন আরও সম্ভাবনা - Use the top bar to open the main menu and undo or redo changes + প্রধান মেনু খুলতে উপরের বারটি ব্যবহার করুন এবং পরিবর্তনগুলি পূর্বাবস্থায় ফেরান বা পুনরায় করুন আড়াআড়ি পকেট পেইন্ট আপনাকে সেরা চিত্রের অভিজ্ঞতা দেওয়ার জন্য ল্যান্ডস্কেপ মোডে অঙ্কন সমর্থন করে। আপনি সব নিয়মিত. পকেট পেইন্ট উপভোগ করুন। শুরু করুন এবং একটি নতুন মাস্টারপিস তৈরি করুন। - Let\'s go + চলো যাই পরবর্তী এড়িয়ে যান সম্পর্কে - Pocket Paint is a picture editing library that is part of the Catrobat project.\n\nCatrobat is a visual programming language and set of creativity tools for smartphones.\n\nThe source code of Pocket Paint is mainly licensed under the %s.\nFor precise details of the license see the link below. + পকেট পেইন্ট একটি চিত্র সম্পাদনা গ্রন্থাগার যা ক্যাট্রোব্যাট প্রকল্পের অংশ।\n\nক্যাটরোব্যাট একটি ভিজ্যুয়াল প্রোগ্রামিং ভাষা এবং স্মার্টফোনের জন্য সৃজনশীলতার সরঞ্জামগুলির সেট।\n\nপকেট পেইন্টের উত্স কোডটি মূলত %s এর অধীনে লাইসেন্সযুক্ত।\nলাইসেন্সের সুনির্দিষ্ট বিবরণের জন্য নীচের লিঙ্কটি দেখুন। পকেট পেইন্ট সোর্স কোড লাইসেন্স ক্যাট্রোব্যাট সম্পর্কে সূচনা ইন্ট্রো স্প্লিট স্ক্রিন সমর্থন করে না - Overwrite File? - You are about to overwrite an existing image (hint: To save it as a new image, use the \"%s\" option). Save anyway? - Do you like Pocket Paint? - Would you like to rate Pocket Paint? - We are sorry to hear that. If you want to share your experience with us, please write to contact@catrobat.org + ওভাররাইট ফাইল? + আপনি একটি বিদ্যমান চিত্র ওভাররাইট করতে চলেছেন (ইঙ্গিত: এটি একটি নতুন চিত্র হিসাবে সংরক্ষণ করতে, \"%s\" বিকল্পটি ব্যবহার করুন)। যাইহোক সংরক্ষণ করবেন? + আপনি পকেট পেইন্ট পছন্দ করেন? + আপনি কি পকেট পেইন্ট রেট করতে চান? + এটি শুনে আমরা অত্যন্ত দুঃখিত। আপনি যদি আমাদের সাথে আপনার অভিজ্ঞতা ভাগ করতে চান তবে যোগাযোগ করুন@catrobat.org এ লিখুন হ্যাঁ না বাতিল - Not now - Rate Pocket Paint + এখন না + হার পকেট পেইন্ট সরঞ্জামসমূহ - Current - Color + কারেন্ট + রঙ স্তর - Item for bottom navigation - Switch to the tool you want to use. - Shows the currently used tool and opens its options. - Shows the currently used color and opens the color picker. - Opens the layer menu and lets you manage your layers. - Current tool icon - Image is too big to load - The image is too big to load. Click OK to scale down the image automatically. + নীচে নেভিগেশনের জন্য আইটেম + আপনি যে সরঞ্জামটি ব্যবহার করতে চান তাতে স্যুইচ করুন। + বর্তমানে ব্যবহৃত সরঞ্জাম দেখায় এবং এর বিকল্পগুলি খুলবে। + বর্তমানে ব্যবহৃত রঙ দেখায় এবং রঙ চয়নকারীটি খোলে। + স্তর মেনু খোলে এবং আপনাকে আপনার স্তরগুলি পরিচালনা করতে দেয়। + বর্তমান সরঞ্জাম আইকন + চিত্র লোড করার জন্য খুব বড় is + চিত্রটি লোড করার জন্য খুব বড়। চিত্রটি স্বয়ংক্রিয়ভাবে স্কেল করতে ওকে ক্লিক করুন। diff --git a/Paintroid/src/main/res/values-de-rDE/string.xml b/Paintroid/src/main/res/values-de-rDE/string.xml index b128a2b866..fb9690b4a6 100644 --- a/Paintroid/src/main/res/values-de-rDE/string.xml +++ b/Paintroid/src/main/res/values-de-rDE/string.xml @@ -90,7 +90,7 @@ Bild gespeichert unter\n Bild gespeichert\n Kopie gespeichert in\n - Kopie gespeichert\n + Kopie gespeichert Verlassen Speichern Verwerfen diff --git a/Paintroid/src/main/res/values-en-rAU/string.xml b/Paintroid/src/main/res/values-en-rAU/string.xml index b2ad9cb6f0..b61051e2fc 100644 --- a/Paintroid/src/main/res/values-en-rAU/string.xml +++ b/Paintroid/src/main/res/values-en-rAU/string.xml @@ -68,7 +68,7 @@ Write text and format it. Resize the text box afterwards. Tap to insert the text on the image. Choose a shape and tap it to insert the selected shape. Create new layers or modify existing ones. - Select or adjust a color. + Select or adjust a colour. Move your finger to move the canvas. Move your finger on the image to create a spray can pattern. Back to project @@ -112,7 +112,7 @@ Heart Fill Outline - Color tolerance + Colour tolerance rotate left rotate right flip vertical @@ -178,12 +178,12 @@ Rate Pocket Paint Tools Current - Color + Colour Layers Item for bottom navigation Switch to the tool you want to use. Shows the currently used tool and opens its options. - Shows the currently used color and opens the color picker. + Shows the currently used colour and opens the colour picker. Opens the layer menu and lets you manage your layers. Current tool icon Image is too big to load diff --git a/Paintroid/src/main/res/values-en-rCA/string.xml b/Paintroid/src/main/res/values-en-rCA/string.xml index 7074c37b83..b61051e2fc 100644 --- a/Paintroid/src/main/res/values-en-rCA/string.xml +++ b/Paintroid/src/main/res/values-en-rCA/string.xml @@ -55,11 +55,11 @@ Save Changes? Help Remove parts of the image like with an eraser. - Tap on the symbols on the bottom bar to change the color or the brush size. - Tap on the image to select a color. + Tap on the symbols on the bottom bar to change the colour or the brush size. + Tap on the image to select a colour. Tap to undo your previous action. Tap to redo an undone action. - Tap on the image to fill an area with the selected color. + Tap on the image to fill an area with the selected colour. Position the cursor where you want to draw. Tap to activate the cursor. Move your finger to draw. Tap again to deactivate. Use to transform the image. Move and resize the rectangle to cover the area you want to stamp. Long press to select the area. Move and tap again to stamp. @@ -68,7 +68,7 @@ Write text and format it. Resize the text box afterwards. Tap to insert the text on the image. Choose a shape and tap it to insert the selected shape. Create new layers or modify existing ones. - Select or adjust a color. + Select or adjust a colour. Move your finger to move the canvas. Move your finger on the image to create a spray can pattern. Back to project @@ -112,7 +112,7 @@ Heart Fill Outline - Color tolerance + Colour tolerance rotate left rotate right flip vertical @@ -178,12 +178,12 @@ Rate Pocket Paint Tools Current - Color + Colour Layers Item for bottom navigation Switch to the tool you want to use. Shows the currently used tool and opens its options. - Shows the currently used color and opens the color picker. + Shows the currently used colour and opens the colour picker. Opens the layer menu and lets you manage your layers. Current tool icon Image is too big to load diff --git a/Paintroid/src/main/res/values-en-rGB/string.xml b/Paintroid/src/main/res/values-en-rGB/string.xml index b2ad9cb6f0..b61051e2fc 100644 --- a/Paintroid/src/main/res/values-en-rGB/string.xml +++ b/Paintroid/src/main/res/values-en-rGB/string.xml @@ -68,7 +68,7 @@ Write text and format it. Resize the text box afterwards. Tap to insert the text on the image. Choose a shape and tap it to insert the selected shape. Create new layers or modify existing ones. - Select or adjust a color. + Select or adjust a colour. Move your finger to move the canvas. Move your finger on the image to create a spray can pattern. Back to project @@ -112,7 +112,7 @@ Heart Fill Outline - Color tolerance + Colour tolerance rotate left rotate right flip vertical @@ -178,12 +178,12 @@ Rate Pocket Paint Tools Current - Color + Colour Layers Item for bottom navigation Switch to the tool you want to use. Shows the currently used tool and opens its options. - Shows the currently used color and opens the color picker. + Shows the currently used colour and opens the colour picker. Opens the layer menu and lets you manage your layers. Current tool icon Image is too big to load diff --git a/Paintroid/src/main/res/values-es-rES/string.xml b/Paintroid/src/main/res/values-es-rES/string.xml index cb62014895..701e9a8320 100644 --- a/Paintroid/src/main/res/values-es-rES/string.xml +++ b/Paintroid/src/main/res/values-es-rES/string.xml @@ -101,7 +101,7 @@ resolución de imagen máxima alcanzada Tu texto: Opciones de formato: - Fecha de actualización + U I B abc @@ -143,8 +143,8 @@ Esta aplicación necesita el permiso solicitado para funcionar correctamente. Para guardar las imágenes en la memoria local, la app necesita acceso de lectura y escritura a la misma. Esta aplicación necesita el permiso solicitado para funcionar correctamente. Para guardar las imágenes en la memoria local, la app necesita acceso de lectura y escritura a la misma. Como has denegado el permiso con no preguntar de nuevo, por favor, ve a los ajustes de tu teléfono y concede los permisos necesarios si deseas utilizar las funciones asociadas. - Open navigation drawer - Close navigation drawer + Abrir cajón de navegación + Cerrar cajón de navegación Arrastra los bordes a su nueva posición, luego pulsa para agrandar o recortar el área de imagen. Pan a la posición, después pulsa para empezar a pintar. Pan a dibujar, después pulsa y deja de dibujar. diff --git a/Paintroid/src/main/res/values-fa-rAF/string.xml b/Paintroid/src/main/res/values-fa-rAF/string.xml index e1c57e0006..5e7912c42a 100644 --- a/Paintroid/src/main/res/values-fa-rAF/string.xml +++ b/Paintroid/src/main/res/values-fa-rAF/string.xml @@ -19,173 +19,173 @@ --> - Pocket Paint - Brush - Cursor - Pipette - Undo - Redo - Information - Stamp - Import image - Eraser - Transform - Fill - Line - Text - Shapes - Hand - Spray can - Apply - Checkmark - Done - Gallery - Could not load Sticker - Something went wrong. - Circle - Square - Paste - Copy - Cut - Stickers - Tools - Error load/save file - Check image or SD-card! - Stroke width - Save changes? - Help - Remove parts of the image like with an eraser. - Tap on the symbols on the bottom bar to change the color or the brush size. - Tap on the image to select a color. - Tap to undo your previous action. - Tap to redo an undone action. - Tap on the image to fill an area with the selected color. - Position the cursor where you want to draw. Tap to activate the cursor. Move your finger to draw. Tap again to deactivate. - Use to transform the image. + رنگ جیب Pocket Paint + برس + مکان نما + پاپت + خنثی کردن + باز کرد + اطلاعات + مهر + وارد کردن تصویر + پاک کن + تبدیل + پر کن + ردیف + متن + شکل ها + دست + قوطی اسپری + بکار ببر + سوال سحی + انجام شد + گالری + برچسب را نمی توان بارگیری کرد + چیزی اشتباه شد + دایره + مربع + علاوه کن + نقل + قطع کن + برچسب ها + ابزارها + خطا بارگیری / فایل ذخیره کن + تصویر یا کارت SD را بررسی کنید! + عرض ضربه + ذخیره تغییرات؟ + کمک + بخش هایی از تصویر را با یک پاک کن حذف کنید. + برای تغییر رنگ یا اندازه قلم مو بر روی نمادها در نوار پایین ضربه بزنید. + برای انتخاب یک رنگ روی تصویر ضربه بزنید. + ضربه بزنید تا اقدام قبلی خود را لغو کنید. + ضربه بزنید تا یک اقدام لغو شود. + روی تصویر ضربه بزنید تا یک منطقه را با رنگ انتخاب شده پر کنید. + مکان نما را جایی که می خواهید قرعه کشی کنید. برای فعال کردن مکان نما ضربه بزنید. انگشت خود را به قرعه کشی حرکت دهید. دوباره ضربه بزنید تا غیرفعال شود. + برای تبدیل تصویر از آن استفاده کنید. Move and resize the rectangle to cover the area you want to stamp. Long press to select the area. Move and tap again to stamp. - Import an image from the gallery to the stamp tool. - Draw a straight line. + تصویر را از گالری به ابزار تمبر وارد کنید. + یک خط مستقیم را بکشید. Write text and format it. Resize the text box afterwards. Tap to insert the text on the image. Choose a shape and tap it to insert the selected shape. - Create new layers or modify existing ones. - Select or adjust a color. - Move your finger to move the canvas. - Move your finger on the image to create a spray can pattern. - Back to project - Quit - Save changes? - New image - Discard image - You are only able to merge or reorder if all layers are visible - No tools are available on hidden layer - Load image - Save image - Save copy - Fullscreen - Share image - Send image via - Rate us! - Export - Feedback - Image saved to\n - Image saved - Copy saved to\n - Copy saved - Quit - Save - Discard - Cancel - Overwrite - nothing to resize - cannot resize to this size - max image resolution reached - Your text: - Format options: + ایجاد لایه های جدید و یا تغییر موجودات موجود. + رنگ را انتخاب یا تنظیم کنید. + انگشت خود را حرکت دهید تا بوم را حرکت دهید. + انگشت خود را بر روی تصویر حرکت دهید تا یک الگوی اسپری ایجاد شود. + بازگشت به پروژه + ترک کن + ذخیره تغییرات؟ + عکس جدید + تصویر را از بین ببر + شما فقط قادر به ادغام یا مرتب کردن مجدد اگر تمام لایه ها قابل مشاهده باشند + هیچ ابزار در لایه پنهان موجود نیست + تصویر اضافه کن + ذخیره تصویر + ذخیره کپی + تمام صفحه + به اشتراک گذاری تصویر + ارسال تصویر از طریق + به ما رای دهید! + صادر + بازخورد + تصویر ذخیره شده در\n + تصویر ذخیره شد + تصویر ذخیره شد در\n + کپی ذخیره شد + ترک کن + ذخیره + لغو تغییرات + لغو + روی نوشتن + چیز برای تغییر اندازه نیست + نمی تواند به این اندازه تغییر اندازه دهد + حداکثر رزولوشن تصویر رسیده است + متن تو: + گزینه ها فرمت: U I B - abc - Tap here to write - Rectangle - Ellipse - Star - Heart - Fill - Outline - Color tolerance - rotate left - rotate right - flip vertical - flip horizontal - resize - crop/enlarge - Width - Height - Auto - px - Long press to copy content - Layers - New layer - Delete layer - Too many layers - Layers merged - Layer background - Shape - Error on loading image - Not a valid image - Settings - Image name - Image format - Quality: - Takes up minimal storage space. No transparency is remembered. - Lossless compression. Transparency is preserved. - This format remembers layers. It can be opened by apps that support the Openraster format. - This app needs the requested permission to function properly. In order to save images to the local memory, the app needs read and write access to it. - This app needs the requested permission to function properly. In order to save images to the local memory, the app needs read and write access to it. - As you have denied permission with do not ask again, please go to your phone settings and grant the required permissions if you wish to use the associated functions. + ا ب ت + برای نوشتن اینجا را ضربه بزنید + مستطیل + بیضی + ستاره + قلب + پر کن + رئوس مطالب + تحمل رنگ + چرخش چپ + چرخش راست + تلنگر عمودی + تلنگر افقی + تغییر اندازه دوباره + محصول / بزرگ شدن + عرض + ارتفاع + خودکار + پیکسل + مطبوعات طولانی برای کپی محتوا + لایه های + لایه جدید + لایه را حذف کنید + لایه های بیش از حد + لایه ها ادغام شده + پس زمینه لایه + شکل + خطا در بارگیری تصویر + تصویر معتبر نیست + تنظیمات + نام تصویر + فرمت تصویر + کیفیت: + طول می کشد فضای ذخیره سازی حداقل . هیچ شفافیت به یاد میآید. + فشرده سازی بدون افتادگی. شفافیت حفظ می شود. + این فرمت لایه های را به یاد می آورد. این را می توان با برنامه هایی که از فرمت OpenRaster پشتیبانی می کنند باز می شود. + این برنامه نیاز به اجازه درخواست شده برای عملکرد به درستی دارد. به منظور ذخیره تصاویر به حافظه محلی، برنامه نیاز به خواندن و نوشتن دسترسی به آن دارد. + این برنامه نیاز به اجازه درخواست شده برای عملکرد به درستی دارد. به منظور ذخیره تصاویر به حافظه محلی، برنامه نیاز به خواندن و نوشتن دسترسی به آن دارد. + همانطور که مجوز را رد کردید، دوباره درخواست نکنید، لطفا به تنظیمات تلفن خود بروید و اگر بخواهید از توابع مرتبط استفاده کنید، مجوزهای مورد نیاز را دریافت کنید. Open navigation drawer Close navigation drawer Drag edges to their new position, then tap to enlarge or crop the image area. - Pan to position, then tap to start painting. - Pan to draw, then tap again to stop painting. - Welcome To Pocket Paint - With Pocket Paint there are no limits to your creativity. If you are new, start the intro, or skip it if you are already familiar with Pocket Paint. - Click on a tool to get more information - More possibilities - Use the top bar to open the main menu and undo or redo changes - Landscape - Pocket Paint also supports drawing in landscape mode to give you the best painting experience. - You are all set. Enjoy Pocket Paint. - Get started and create a new masterpiece. - Let\'s go - Next - Skip - About - Pocket Paint is a picture editing library that is part of the Catrobat project.\n\nCatrobat is a visual programming language and set of creativity tools for smartphones.\n\nThe source code of Pocket Paint is mainly licensed under the %s.\nFor precise details of the license see the link below. - Pocket Paint source code license - About Catrobat - Intro - Intro does not support split screen. - Overwrite File? - You are about to overwrite an existing image (hint: To save it as a new image, use the \"%s\" option). Save anyway? - Do you like Pocket Paint? - Would you like to rate Pocket Paint? - We are sorry to hear that. If you want to share your experience with us, please write to contact@catrobat.org - Yes - No - Cancel - Not now - Rate Pocket Paint - Tools - Current - Color - Layers - Item for bottom navigation - Switch to the tool you want to use. - Shows the currently used tool and opens its options. - Shows the currently used color and opens the color picker. - Opens the layer menu and lets you manage your layers. - Current tool icon - Image is too big to load - The image is too big to load. Click OK to scale down the image automatically. + پان به موقعیت، سپس برای شروع نقاشی ضربه بزنید. + پان به قرعه کشی، سپس برای متوقف کردن نقاشی ضربه بزنید. + به رنگ جیب Pocket Paint خوش آمدید + با رنگ جیب Pocket Paint هیچ محدودیتی برای خلاقیت شما وجود ندارد. اگر شما جدید هستید، مقدمه را شروع کنید یا آن را پر کنید اگر قبلا با رنگ جیب Pocket Paint آشنا هستید. + بر روی یک ابزار کلیک کنید تا اطلاعات بیشتری بدست اورید + امکانات بیشتر + از نوار بالا برای باز کردن منوی اصلی و تغییرات مجدد یا تغییر مجدد استفاده کنید + مناظر طبیعی + رنگ جیبی Pocket Pain همچنین از طراحی در حالت افقی پشتیبانی می کند تا بهترین تجربه نقاشی را به شما بدهد. + همه شما تنظیم شده اید. از رنگ جیب Pocket Paint لزت ببرید. + شروع کنید و یک شاهکار جدید ایجاد کنید. + بیا بریم + بعد + رد کن + در باره + رنگ جیبی Pocket Paint یک کتابخانه ویرایش تصویری است که بخشی از پروژه کاتروبات Catrobat است.\n\n کاتروبات Catrobat یک زبان برنامه نویسی بصری و مجموعه ای از ابزار خلاقیت برای گوشی های هوشمند است.\n\n کد منبع رنگ جیب عمدتا تحت مجوز%s\nمجاز است. جزئیات دقیق مجوز، لینک زیر را ببینید. + مجوز کد رنگ جیبی Pocket Paint + درباره کاتروبات Catrobat + اینترو + مقدمه از صفحه تقسیم پشتیبانی نمی کند. + بازنویسی فایل؟ + شما می خواهید یک تصویر موجود را بازنویسی کنید (اشاره: برای ذخیره آن به عنوان یک تصویر جدید، از گزینه \"%s\" استفاده کنید). زخیره در هر حال؟ + آیا رنگ جیبی Pocket Paint را دوست دارید؟ + آیا می خواهید رنگ جیبی Pocket Paint را ارزیابی کنید؟ + ما متاسفیم که این را مشنویم. اگر می خواهید تجربه خود را با ما به اشتراک بگذارید، لطفا به contact@catrobat.org بنویسید + بله + نخیر + لغو + الان نه + رنگ جیبی Pocket Paint ارزیابی کنید + ابزارها + جاری + رنگ + لایه های + مورد برای ناوبری پایین + به ابزار مورد نظر خود مراجعه کنید. + ابزار مورد استفاده را نشان می دهد و گزینه های آن را باز می کند. + رنگ در حال حاضر مورد استفاده را نشان می دهد و جمع کننده رنگ را باز می کند. + منوی لایه را باز می کند و به شما اجازه می دهد لایه های خود را مدیریت کنید. + آیکون فعلی ابزار + تصویر بیش از حد بزرگ برای بارگذاری است + تصویر بیش از حد بزرگ برای بارگذاری است. روی OK کلیک کنید تا تصویر را به طور خودکار به پایین بکشید. diff --git a/Paintroid/src/main/res/values-fr-rFR/string.xml b/Paintroid/src/main/res/values-fr-rFR/string.xml index 5830b11ae2..d6a0646585 100644 --- a/Paintroid/src/main/res/values-fr-rFR/string.xml +++ b/Paintroid/src/main/res/values-fr-rFR/string.xml @@ -102,7 +102,7 @@ Votre texte : Options de formatage : U - I + l B abc Appuyez ici pour écrire @@ -143,8 +143,8 @@ Cette application a besoin de l\'autorisation requise pour fonctionner correctement. Afin d\'enregistrer des images dans la mémoire locale, l\'application a besoin d\'y accéder en lecture et en écriture. Cette application a besoin de l\'autorisation requise pour fonctionner correctement. Afin d\'enregistrer des images dans la mémoire locale, l\'application a besoin d\'y accéder en lecture et en écriture. Comme vous avez refusé la permission avec ne pas demander à nouveau, allez dans les paramètres de votre téléphone et accordez les autorisations requises si vous souhaitez utiliser les fonctions associées. - Open navigation drawer - Close navigation drawer + Ouvrir le tiroir de navigation + Fermer le tiroir de navigation Drag edges to their new position, then tap to enlarge or crop the image area. Pan pour positionner, puis appuyez pour commencer à peindre. Pan pour dessiner, puis appuyez à nouveau pour arrêter la peinture. diff --git a/Paintroid/src/main/res/values-hi-rIN/string.xml b/Paintroid/src/main/res/values-hi-rIN/string.xml index 0a465b3698..bfd1d75d03 100644 --- a/Paintroid/src/main/res/values-hi-rIN/string.xml +++ b/Paintroid/src/main/res/values-hi-rIN/string.xml @@ -143,8 +143,8 @@ इस एप्लिकेशन को ठीक से काम करने के लिए अनुरोध की अनुमति की आवश्यकता है। छवियों को स्थानीय मेमोरी में सहेजने के लिए, एप्लिकेशन को उस तक पहुंच पढ़ने और लिखने की आवश्यकता होती है। इस एप्लिकेशन को ठीक से काम करने के लिए अनुरोध की अनुमति की आवश्यकता है। छवियों को स्थानीय मेमोरी में सहेजने के लिए, एप्लिकेशन को उस तक पहुंच पढ़ने और लिखने की आवश्यकता होती है। जैसा कि आपने दोबारा अनुमति नहीं देने से इनकार कर दिया है, कृपया अपनी फोन सेटिंग में जाएं और यदि आप संबंधित कार्यों का उपयोग करना चाहते हैं तो आवश्यक अनुमति दें। - Open navigation drawer - Close navigation drawer + नेविगेशन दराज खोलें + नेविगेशन दराज बंद करें किनारों को अपनी नई स्थिति में खींचें, फिर छवि क्षेत्र को विस्तार देने या क्रॉप करने के लिए टैप करें. स्थिति के लिए पैन, तो पेंटिंग शुरू करने के लिए नल. ड्रा करने के लिए पैन, तो पेंटिंग को रोकने के लिए फिर से नल । diff --git a/Paintroid/src/main/res/values-in-rID/string.xml b/Paintroid/src/main/res/values-in-rID/string.xml index 919e4badff..3b60e2328f 100644 --- a/Paintroid/src/main/res/values-in-rID/string.xml +++ b/Paintroid/src/main/res/values-in-rID/string.xml @@ -143,8 +143,8 @@ Aplikasi ini membutuhkan izin yang diminta agar berfungsi dengan baik. Untuk menyimpan gambar ke memori lokal, aplikasi membutuhkan akses baca dan tulis ke dalamnya. Aplikasi ini membutuhkan izin yang diminta agar berfungsi dengan baik. Untuk menyimpan gambar ke memori lokal, aplikasi membutuhkan akses baca dan tulis ke dalamnya. Karena Anda telah menolak izin dengan jangan tanya lagi, silakan buka pengaturan ponsel Anda dan berikan izin yang diperlukan jika Anda ingin menggunakan fungsi terkait. - Open navigation drawer - Close navigation drawer + Buka laci navigasi + Tutup laci navigasi Drag edges to their new position, then tap to enlarge or crop the image area. Geser ke posisi, lalu ketuk untuk mulai mengecat. Geser untuk menggambar, lalu ketuk lagi untuk berhenti melukis. diff --git a/Paintroid/src/main/res/values-ja-rJP/string.xml b/Paintroid/src/main/res/values-ja-rJP/string.xml index 8791f001a7..1ea81fc998 100644 --- a/Paintroid/src/main/res/values-ja-rJP/string.xml +++ b/Paintroid/src/main/res/values-ja-rJP/string.xml @@ -101,7 +101,7 @@ 最大の画像解像度に達しました テキスト: 書式設定オプション: - U + I B あいう diff --git a/Paintroid/src/main/res/values-kab-rDZ/string.xml b/Paintroid/src/main/res/values-kab-rDZ/string.xml new file mode 100644 index 0000000000..a8667f1887 --- /dev/null +++ b/Paintroid/src/main/res/values-kab-rDZ/string.xml @@ -0,0 +1,191 @@ + + + + Pocket Paint + Brush + Cursor + Pipette + Undo + Redo + Information + Stamp + Import image + Eraser + Transform + Fill + Line + Aḍris + Shapes + Hand + Spray can + Snes + Checkmark + Immed + Tamidelt + Could not load Sticker + Something went wrong. + Tawinest + Amkuẓ + Senṭeḍ + Nɣel + Gzem + Stickers + Ifecka + Error load/save file + Check image or SD-card! + Stroke width + Save changes? + Tallelt + Remove parts of the image like with an eraser. + Tap on the symbols on the bottom bar to change the color or the brush size. + Tap on the image to select a color. + Tap to undo your previous action. + Tap to redo an undone action. + Tap on the image to fill an area with the selected color. + Position the cursor where you want to draw. Tap to activate the cursor. Move your finger to draw. Tap again to deactivate. + Use to transform the image. + Move and resize the rectangle to cover the area you want to stamp. Long press to select the area. Move it, then tap on the checkmark to stamp. + Import an image from the gallery to the stamp tool. + Draw a straight line. + Write text and format it. Resize the text box afterwards. Tap on the checkmark to insert the text on the image. + Choose a shape and tap on the checkmark to insert the selected shape. + Create new layers or modify existing ones. + Select or adjust a color. + Move your finger to move the canvas. + Move your finger on the image to create a spray can pattern. + Back to project + Quit + Save changes? + New image + Discard image + You are only able to merge or reorder if all layers are visible + No tools are available on hidden layer + Load image + Save image + Save copy + Agdil ačuran + Bḍu tugna + Azen tugna s + Rnu-yaɣ tazmilt! + Sifeḍ + Awennit + Image saved to\n + Image saved + Copy saved to\n + Copy saved + Ffeɣ + Sekles + Sefsex + Sefsex + Overwrite + nothing to resize + cannot resize to this size + max image resolution reached + Your text: + Format options: + U + I + B + abc + Tap here to write + Rectangle + Ellipse + Star + Heart + Fill + Outline + Color tolerance + rotate left + rotate right + flip vertical + flip horizontal + resize + crop/enlarge + Width + Height + Auto + px + Long press to copy content + Layers + New layer + Delete layer + Too many layers + Layers merged + Layer background + Shape + Error on loading image + Not a valid image + Iɣewwaṛen + Isem n tugna + Image format + Quality: + Takes up minimal storage space. No transparency is remembered. + Lossless compression. Transparency is preserved. + This format remembers layers. It can be opened by apps that support the Openraster format. + This app needs the requested permission to function properly. In order to save images to the local memory, the app needs read and write access to it. + This app needs the requested permission to function properly. In order to save images to the local memory, the app needs read and write access to it. + As you have denied permission with do not ask again, please go to your phone settings and grant the required permissions if you wish to use the associated functions. + Open navigation drawer + Close navigation drawer + Drag edges to their new position, tap on the checkmark to enlarge or crop the image area. + Pan to position, then tap to start painting. + Pan to draw, then tap again to stop painting. + Welcome To Pocket Paint + With Pocket Paint there are no limits to your creativity. If you are new, start the intro, or skip it if you are already familiar with Pocket Paint. + Click on a tool to get more information + More possibilities + Use the top bar to open the main menu and undo or redo changes + Landscape + Pocket Paint also supports drawing in landscape mode to give you the best painting experience. + You are all set. Enjoy Pocket Paint. + Get started and create a new masterpiece. + Bdu + Uḍfiṛ + Zgel + Ɣef + Pocket Paint is a picture editing library that is part of the Catrobat project.\n\nCatrobat is a visual programming language and set of creativity tools for smartphones.\n\nThe source code of Pocket Paint is mainly licensed under the %s.\nFor precise details of the license see the link below. + Pocket Paint source code license + About Catrobat + Tazwart + Intro does not support split screen. + Overwrite File? + You are about to overwrite an existing image (hint: To save it as a new image, use the \"%s\" option). Save anyway? + Do you like Pocket Paint? + Would you like to rate Pocket Paint? + We are sorry to hear that. If you want to share your experience with us, please write to contact@catrobat.org + Ih + Ala + Sefsex + Not now + Rate Pocket Paint + Ifecka + Current + Color + Layers + Item for bottom navigation + Switch to the tool you want to use. + Shows the currently used tool and opens its options. + Shows the currently used color and opens the color picker. + Opens the layer menu and lets you manage your layers. + Current tool icon + Image is too big to load + The image is too big to load. Click OK to scale down the image automatically. + diff --git a/Paintroid/src/main/res/values-ko-rKR/string.xml b/Paintroid/src/main/res/values-ko-rKR/string.xml index ca9d313293..a8daf64459 100644 --- a/Paintroid/src/main/res/values-ko-rKR/string.xml +++ b/Paintroid/src/main/res/values-ko-rKR/string.xml @@ -143,8 +143,8 @@ 이 앱이 제대로 작동하려면 요청된 권한이 필요합니다. 이미지를 로컬 메모리에 저장하려면 앱에 읽기 및 쓰기 권한이 필요합니다. 이 앱이 제대로 작동하려면 요청된 권한이 필요합니다. 이미지를 로컬 메모리에 저장하려면 앱에 읽기 및 쓰기 권한이 필요합니다. 다시 묻지 않음으로 권한을 거부 했으므로 관련 기능을 사용하려면 휴대폰 설정으로 이동하여 필요한 권한을 부여하십시오. - Open navigation drawer - Close navigation drawer + 탐색 창 열기 + 탐색 창 닫기 새로운 위치로 가장자리를 끌고, 확대하거나 자르려면 탭하세요. 위치를 끌어 정하고, 시작하려면 터치하세요. 그리려면 끌고, 그리기를 중지하려면 다시 탭하세요. diff --git a/Paintroid/src/main/res/values-pa-rIN/string.xml b/Paintroid/src/main/res/values-pa-rIN/string.xml index 04da132c5c..3b82055e3f 100644 --- a/Paintroid/src/main/res/values-pa-rIN/string.xml +++ b/Paintroid/src/main/res/values-pa-rIN/string.xml @@ -101,8 +101,8 @@ ਵੱਧ ਤੋਂ ਵੱਧ ਚਿੱਤਰ ਰੈਜ਼ੋਲੇਸ਼ਨ ਪਹੁੰਚ ਗਿਆ ਤੁਹਾਡਾ ਟੈਕਸਟ: ਫਾਰਮੈਟ ਵਿਕਲਪ: - U - I + ਯੂ + ਆਈ B ਏਬੀਸੀ ਲਿਖਣ ਲਈ ਇੱਥੇ ਟੈਪ ਕਰੋ @@ -143,8 +143,8 @@ ਇਸ ਐਪ ਨੂੰ ਸਹੀ ਤਰ੍ਹਾਂ ਕੰਮ ਕਰਨ ਲਈ ਬੇਨਤੀ ਕੀਤੀ ਅਨੁਮਤੀ ਦੀ ਲੋੜ ਹੈ. ਸਥਾਨਕ ਮੈਮੋਰੀ ਵਿਚ ਚਿੱਤਰਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ, ਐਪ ਨੂੰ ਇਸ ਨੂੰ ਪੜ੍ਹਨ ਅਤੇ ਲਿਖਣ ਦੀ ਪਹੁੰਚ ਦੀ ਜ਼ਰੂਰਤ ਹੈ. ਇਸ ਐਪ ਨੂੰ ਸਹੀ ਤਰ੍ਹਾਂ ਕੰਮ ਕਰਨ ਲਈ ਬੇਨਤੀ ਕੀਤੀ ਅਨੁਮਤੀ ਦੀ ਲੋੜ ਹੈ. ਸਥਾਨਕ ਮੈਮੋਰੀ ਵਿਚ ਚਿੱਤਰਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ, ਐਪ ਨੂੰ ਇਸ ਨੂੰ ਪੜ੍ਹਨ ਅਤੇ ਲਿਖਣ ਦੀ ਪਹੁੰਚ ਦੀ ਜ਼ਰੂਰਤ ਹੈ. ਜਿਵੇਂ ਕਿ ਤੁਸੀਂ ਆਗਿਆ ਤੋਂ ਇਨਕਾਰ ਕਰ ਦਿੱਤਾ ਹੈ ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ, ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਫੋਨ ਸੈਟਿੰਗਾਂ ਤੇ ਜਾਓ ਅਤੇ ਜੇ ਤੁਸੀਂ ਸੰਬੰਧਿਤ ਕਾਰਜਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ ਤਾਂ ਲੋੜੀਂਦੀਆਂ ਆਗਿਆ ਦਿਓ. - Open navigation drawer - Close navigation drawer + ਨੈਵੀਗੇਸ਼ਨ ਦਰਾਜ਼ ਖੋਲ੍ਹੋ + ਨੇਵੀਗੇਸ਼ਨ ਦਰਾਜ਼ ਨੂੰ ਬੰਦ ਕਰੋ ਕਿਨਾਰਿਆਂ ਨੂੰ ਉਨ੍ਹਾਂ ਦੀ ਨਵੀਂ ਸਥਿਤੀ \'ਤੇ ਖਿੱਚੋ, ਚਿੱਤਰ ਖੇਤਰ ਨੂੰ ਵੱਡਾ ਕਰਨ ਜਾਂ ਫਸਣ ਲਈ ਚੈੱਕਮਾਰਕ\' ਤੇ ਟੈਪ ਕਰੋ. ਸਥਿਤੀ ਤੇ ਪੈਨ ਕਰੋ, ਫਿਰ ਪੇਂਟਿੰਗ ਨੂੰ ਅਰੰਭ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ. ਖਿੱਚਣ ਲਈ ਪੈਨ ਕਰੋ, ਫਿਰ ਪੇਂਟਿੰਗ ਨੂੰ ਰੋਕਣ ਲਈ ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ. diff --git a/Paintroid/src/main/res/values-pl-rPL/string.xml b/Paintroid/src/main/res/values-pl-rPL/string.xml index 7bc24aa142..7a6cdac8fb 100644 --- a/Paintroid/src/main/res/values-pl-rPL/string.xml +++ b/Paintroid/src/main/res/values-pl-rPL/string.xml @@ -41,7 +41,7 @@ Zrobione Galeria Nie można załadować naklejki - Coś poszło nie tak. + Wystąpił nieznany błąd. Koło Kwadrat Wklej diff --git a/Paintroid/src/main/res/values-ru-rRU/string.xml b/Paintroid/src/main/res/values-ru-rRU/string.xml index 8a65d75870..8bf6ddf1b4 100644 --- a/Paintroid/src/main/res/values-ru-rRU/string.xml +++ b/Paintroid/src/main/res/values-ru-rRU/string.xml @@ -41,7 +41,7 @@ Готово Галерея Не удалось загрузить стикер - Произошла неизвестная ошибка. + Что-то пошло не так. Круг Квадрат Вставить @@ -91,10 +91,10 @@ Картинка сохранена Копия сохранена в\n Копия сохранена - Выход + Уйти Сохранить Сброс - Отменить + Отмена Перезаписать нечего менять невозможно изменить размер до этого размера @@ -110,7 +110,7 @@ Эллипс Звезда Сердце - Заливка + Заполнить План Допустимое отклонение по цвету повернуть влево @@ -143,8 +143,8 @@ Этому приложению требуется запрошенное разрешение для правильной работы. Чтобы сохранять изображения в локальной памяти, приложению необходим доступ для чтения и записи. Этому приложению требуется запрашиваемое разрешение для правильной работы. Чтобы сохранить изображения в локальную память, приложению необходимо иметь доступ к ним для чтения и записи. Как вы отказали в разрешении не спрашивать снова, перейдите в настройки телефона и предоставьте необходимые разрешения, если вы хотите использовать соответствующие функции. - Open navigation drawer - Close navigation drawer + Открыть панель навигации + Закрыть панель навигации Перетащите края на их новое место, а затем нажмите, чтобы увеличить или обрезать изображение. Нажмите, чтобы начать рисование. Нажмите кнопку, чтобы рисовать, затем снова, чтобы остановить рисование. @@ -158,7 +158,7 @@ Все готово. Наслаждайтесь Pocket Paint. Начните и создайте новый шедевр. Начнем - Далее + Следующий Пропустить О программе Pocket Paint - это библиотека для редактирования изображений, являющаяся частью проекта Catrobat.\n\nCatrobat является визуальным языком программирования и набором инструментов креативности для смартфонов.\n\nИсходный код Pocket Paint в основном лицензирован под %s.\nПодробнее о лицензии см. ссылку ниже. diff --git a/Paintroid/src/main/res/values-si-rLK/string.xml b/Paintroid/src/main/res/values-si-rLK/string.xml index e1c57e0006..1c5d2ce03a 100644 --- a/Paintroid/src/main/res/values-si-rLK/string.xml +++ b/Paintroid/src/main/res/values-si-rLK/string.xml @@ -94,7 +94,7 @@ Quit Save Discard - Cancel + අවලංගු කරන්න Overwrite nothing to resize cannot resize to this size @@ -173,7 +173,7 @@ We are sorry to hear that. If you want to share your experience with us, please write to contact@catrobat.org Yes No - Cancel + අවලංගු කරන්න Not now Rate Pocket Paint Tools diff --git a/Paintroid/src/main/res/values-th-rTH/string.xml b/Paintroid/src/main/res/values-th-rTH/string.xml index b5cc62ba48..a07810cd30 100644 --- a/Paintroid/src/main/res/values-th-rTH/string.xml +++ b/Paintroid/src/main/res/values-th-rTH/string.xml @@ -87,9 +87,9 @@ ให้คะแนนเรา ส่งออก คำติชม - Image saved to\n + บันทึกภาพไปที่ \n บันทึกภาพแล้ว - Copy saved to\n + คัดลอกและบันทึกไปที่ \n บันทึกสำเนาแล้ว ออก บันทึก diff --git a/Paintroid/src/main/res/values-tr-rTR/string.xml b/Paintroid/src/main/res/values-tr-rTR/string.xml index 10f9e525a6..3b5827ee15 100644 --- a/Paintroid/src/main/res/values-tr-rTR/string.xml +++ b/Paintroid/src/main/res/values-tr-rTR/string.xml @@ -87,9 +87,9 @@ Bizi değerlendirin! Dışa aktar Geri bildirim - Görüntü kaydedildi\n + Görüntü şuraya kaydedildi\n Resim kaydedildi - Kopyala kaydedildi\n + Kopyası şuraya kaydedildi\n Kopyası kaydedildi Çık Kaydet @@ -142,8 +142,8 @@ Bu dosya biçimi katmanları hatırlar. Openraster formatını destekleyen uygulamalar tarafından açılabilir. Bu uygulamanın düzgün çalışması için istenen izne ihtiyacı var. Görüntüleri yerel belleğe kaydetmek için uygulamanın okuma ve yazma erişimine ihtiyacı vardır. Bu uygulamanın düzgün çalışması için istenen izne ihtiyacı var. Görüntüleri yerel belleğe kaydetmek için uygulamanın okuma ve yazma erişimine ihtiyacı vardır. İzninizi reddettiğiniz için bir daha sormayın. - Open navigation drawer - Close navigation drawer + Gezinme çekmecesini aç + Gezinme çekmecesini kapat Kenarları yeni konumlarına sürükleyin, görüntü alanını büyütmek veya kırpmak için onay işaretine dokunun. Konumlandırmak için kaydırın, ardından boyamaya başlamak için dokunun. Çizmek için kaydırın, ardından boyamayı durdurmak için tekrar dokunun. diff --git a/Paintroid/src/main/res/values-tw-rGH/string.xml b/Paintroid/src/main/res/values-tw-rGH/string.xml index ff7e3f1c98..2d37e2a9f6 100644 --- a/Paintroid/src/main/res/values-tw-rGH/string.xml +++ b/Paintroid/src/main/res/values-tw-rGH/string.xml @@ -25,6 +25,7 @@ Pipette Undo Redo + Information Stamp Import image Eraser @@ -34,10 +35,19 @@ Text Shapes Hand + Spray can Apply + Checkmark Done + Gallery + Could not load Sticker + Something went wrong. Circle Square + Paste + Copy + Cut + Stickers Tools Error load/save file Check image or SD-card! @@ -52,30 +62,40 @@ Tap on the image to fill an area with the selected color. Position the cursor where you want to draw. Tap to activate the cursor. Move your finger to draw. Tap again to deactivate. Use to transform the image. - Move and resize the rectangle to cover the area you want to stamp. Long press to select the area. Move and tap again to stamp. + Move and resize the rectangle to cover the area you want to stamp. Long press to select the area. Move it, then tap on the checkmark to stamp. Import an image from the gallery to the stamp tool. Draw a straight line. - Write text and format it. Resize the text box afterwards. Tap to insert the text on the image. - Choose a shape and tap it to insert the selected shape. + Write text and format it. Resize the text box afterwards. Tap on the checkmark to insert the text on the image. + Choose a shape and tap on the checkmark to insert the selected shape. Create new layers or modify existing ones. Select or adjust a color. Move your finger to move the canvas. + Move your finger on the image to create a spray can pattern. Back to project Quit Save changes? New image Discard image + You are only able to merge or reorder if all layers are visible + No tools are available on hidden layer Load image Save image Save copy Fullscreen + Share image + Send image via Rate us! Export + Feedback + Image saved to\n Image saved + Copy saved to\n Copy saved Quit Save Discard + Cancel + Overwrite nothing to resize cannot resize to this size max image resolution reached @@ -101,6 +121,7 @@ crop/enlarge Width Height + Auto px Long press to copy content Layers @@ -113,12 +134,18 @@ Error on loading image Not a valid image Settings + Image name + Image format + Quality: + Takes up minimal storage space. No transparency is remembered. + Lossless compression. Transparency is preserved. + This format remembers layers. It can be opened by apps that support the Openraster format. This app needs the requested permission to function properly. In order to save images to the local memory, the app needs read and write access to it. This app needs the requested permission to function properly. In order to save images to the local memory, the app needs read and write access to it. As you have denied permission with do not ask again, please go to your phone settings and grant the required permissions if you wish to use the associated functions. Open navigation drawer Close navigation drawer - Drag edges to their new position, then tap to enlarge or crop the image area. + Drag edges to their new position, tap on the checkmark to enlarge or crop the image area. Pan to position, then tap to start painting. Pan to draw, then tap again to stop painting. Welcome To Pocket Paint @@ -139,11 +166,14 @@ About Catrobat Intro Intro does not support split screen. + Overwrite File? + You are about to overwrite an existing image (hint: To save it as a new image, use the \"%s\" option). Save anyway? Do you like Pocket Paint? Would you like to rate Pocket Paint? We are sorry to hear that. If you want to share your experience with us, please write to contact@catrobat.org Yes No + Cancel Not now Rate Pocket Paint Tools @@ -156,4 +186,6 @@ Shows the currently used color and opens the color picker. Opens the layer menu and lets you manage your layers. Current tool icon + Image is too big to load + The image is too big to load. Click OK to scale down the image automatically. diff --git a/Paintroid/src/main/res/values-vi-rVN/string.xml b/Paintroid/src/main/res/values-vi-rVN/string.xml index 63c92f4edb..3ea27430a6 100644 --- a/Paintroid/src/main/res/values-vi-rVN/string.xml +++ b/Paintroid/src/main/res/values-vi-rVN/string.xml @@ -29,25 +29,25 @@ Con dấu Chuyển nhập hình ảnh Tẩy - Transform + Biến đổi Chèn kín Đường thẳng - Text - Shapes - Hand - Spray can - Apply - Checkmark + Bản văn + Hình dạng + Tay + Bình xịt + Ứng dụng + Đánh dấu Đã Thực hiện - Gallery - Could not load Sticker - Something went wrong. - Circle - Square - Paste + Bộ sưu tập + Không thể tải Hình dán + Đã xảy ra lỗi. + Vòng tròn + Quảng trường + Dán Sao chép - Cut - Stickers + Cắt + Hình dán Công cụ Lỗi tải/lưu tập tin Kiểm tra hình ảnh hoặc thẻ SD! @@ -61,62 +61,62 @@ Bấm vào để làm lại hành động chưa được hoàn thành. Nhấp vào hình ảnh để lấp đầy vùng với màu sắc được chọn. Hướng con trỏ chuột vào vị trí mà bạn muốn vẽ. Bấm vào để kích hoạt con trỏ. Di chuyển các ngón tay của bạn để vẽ. Bấm một lần nữa để tắt. - Use to transform the image. + Sử dụng để biến đổi hình ảnh. Move and resize the rectangle to cover the area you want to stamp. Long press to select the area. Move and tap again to stamp. Nhập hình ảnh từ thư viện lên công cụ tem. Vẽ một đường thẳng. Write text and format it. Resize the text box afterwards. Tap to insert the text on the image. Choose a shape and tap it to insert the selected shape. - Create new layers or modify existing ones. - Select or adjust a color. - Move your finger to move the canvas. - Move your finger on the image to create a spray can pattern. - Back to project + Tạo các lớp mới hoặc sửa đổi các lớp hiện có. + Chọn hoặc điều chỉnh màu. + Di chuyển ngón tay của bạn để di chuyển canvas. + Di chuyển ngón tay của bạn trên hình ảnh để tạo mẫu bình xịt. + Quay lại dự án Thoát Lưu thay đổi? Hình ảnh mới - Discard image - You are only able to merge or reorder if all layers are visible - No tools are available on hidden layer + Bỏ hình ảnh + Bạn chỉ có thể hợp nhất hoặc sắp xếp lại thứ tự nếu tất cả các lớp đều hiển thị + Không có công cụ nào trên lớp ẩn Tải hình ảnh Lưu ảnh Lưu bản sao Toàn màn hình - Share image - Send image via - Rate us! + Chia sẻ hình ảnh + Gửi hình ảnh qua + Đánh giá chúng tôi! Xuất - Feedback - Image saved to\n + Phản hồi + Đã lưu hình ảnh vào\n Đã lưu ảnh - Copy saved to\n + Sao chép được lưu vào\n Bản sao đã lưu Thoát Lưu Loại bỏ Hủy bỏ - Overwrite + Ghi đè không có gì để thay đổi kích cỡ - cannot resize to this size + không thể thay đổi kích thước thành kích thước này hình ảnh đã đạt độ phân giải tối đa - Your text: - Format options: + Văn bản của bạn: + Tùy chọn định dạng: U I B abc - Tap here to write - Rectangle - Ellipse - Star - Heart + Nhấn vào đây để viết + Hình chữ nhật + Hình elip + Ngôi sao + Tim Chèn kín - Outline - Color tolerance - rotate left - rotate right - flip vertical - flip horizontal + Đề cương + Dung sai màu + xoay trái + xoay phải + lật dọc + lật ngang resize crop/enlarge Width diff --git a/Paintroid/src/main/res/values-zh-rCN/string.xml b/Paintroid/src/main/res/values-zh-rCN/string.xml index 0dc04bd6e1..032779ca46 100644 --- a/Paintroid/src/main/res/values-zh-rCN/string.xml +++ b/Paintroid/src/main/res/values-zh-rCN/string.xml @@ -46,7 +46,7 @@ 正方型 粘贴 复制 - + 剪切 贴纸 工具 加载/保存文件时发生错误 @@ -101,9 +101,9 @@ 达到最大图像分辨率 您的文本: 格式选项: - U - I - B + + + abc 点击此处添加文本 矩形 @@ -143,8 +143,8 @@ 此应用需要所请求的权限才能正常运行。 为了将图像保存到本地内存,应用需要读写权限。 此应用需要所请求的权限才能正常运行。 为了将图像保存到本地内存,应用需要读写权限。 因为您拒绝了权限,所以不再询问。 如果您想要使用相关的功能,请前往您的手机设置并授予所需的权限。 - Open navigation drawer - Close navigation drawer + 打开导航抽屉 + 关闭导航抽屉 将边缘拖动到新位置,然后点击可放大或裁剪图像。 拖动到位置,点击开始绘画。 拖动作画,然后点击停止作画。 diff --git a/Paintroid/src/main/res/values-zh-rTW/string.xml b/Paintroid/src/main/res/values-zh-rTW/string.xml index bd1fa8db79..d3d27e200a 100644 --- a/Paintroid/src/main/res/values-zh-rTW/string.xml +++ b/Paintroid/src/main/res/values-zh-rTW/string.xml @@ -25,7 +25,7 @@ 吸管 復原 重做 - Information + 信息 圖章 匯入圖像 橡皮擦 @@ -34,20 +34,20 @@ 直線 文字 形狀 - Hand - Spray can - Apply - Checkmark + + 噴霧罐 + 申請 + 複選標記 完成 - Gallery - Could not load Sticker - Something went wrong. - Circle - Square - Paste + 畫廊 + 無法加載貼紙 + 出問題了。 + 圓圈 + 正方形 + 粘貼 複製 - Cut - Stickers + + 貼紙 工具 載入/存檔錯誤 檢查圖檔或 SD 卡! @@ -62,130 +62,130 @@ 點擊圖案以所選的顏色填滿。 移動游標到你要畫圖的位置,點擊並移動手指來開始畫,再次點擊即停止。 用於轉變圖像大小 - Move and resize the rectangle to cover the area you want to stamp. Long press to select the area. Move and tap again to stamp. + 移動矩形並調整其大小以覆蓋您要標記的區域。長按選擇區域。移動它,然後點擊複選標記以標記。 從圖庫匯入圖章的圖案。 畫直線 - Write text and format it. Resize the text box afterwards. Tap to insert the text on the image. - Choose a shape and tap it to insert the selected shape. - Create new layers or modify existing ones. - Select or adjust a color. - Move your finger to move the canvas. - Move your finger on the image to create a spray can pattern. - Back to project + 編寫文本並設置格式。之後調整文本框的大小。點擊複選標記以在圖像上插入文本。 + 選擇一個形狀並點擊複選標記以插入所選形狀。 + 創建新層或修改現有層。 + 選擇或調整顏色。 + 移動手指即可移動畫布。 + 在圖像上移動手指即可創建噴霧罐圖案。 + 返回專案 離開 儲存修改? 新圖檔 - Discard image - You are only able to merge or reorder if all layers are visible - No tools are available on hidden layer + 捨棄圖片 + 如果所有圖層均可見,則您只能合併或重新排序 + 隱藏層上沒有可用的工具 載入圖檔 儲存圖檔 儲存副本 全螢幕顯示 - Share image - Send image via + 分享圖像 + 通過發送圖像 對我們評分! 匯出 - Feedback - Image saved to\n + 反饋 + 圖片已保存到\n 圖檔已儲存 - Copy saved to\n + 複製保存到\n 副本已儲存 離開 存檔 取消 取消 - Overwrite + 覆寫 沒有改變大小 - cannot resize to this size + 無法調整為此大小 到達圖案最大解析度 - Your text: - Format options: - U - I - B + 您的文字: + 格式選項: + 剪切 + 一世 + abc - Tap here to write - Rectangle - Ellipse - Star - Heart + 點按此處撰寫 + 長方形 + 橢圓 + 星星 + 填滿 - Outline - Color tolerance - rotate left - rotate right - flip vertical - flip horizontal - resize - crop/enlarge - Width - Height - Auto - px - Long press to copy content - Layers - New layer - Delete layer - Too many layers - Layers merged - Layer background + 大綱 + 色差 + 向左旋轉 + 右旋 + 垂直翻轉 + 水平翻轉 + 調整大小 + 裁剪/放大 + 寬度 + 高度 + 汽車 + 像素 + 長按即可複制內容 + 層數 + 新層 + 刪除圖層 + 太多層 + 圖層合併 + 圖層背景 形狀 載入圖檔錯誤 - Not a valid image + 無效的圖片 設定 - Image name - Image format - Quality: - Takes up minimal storage space. No transparency is remembered. - Lossless compression. Transparency is preserved. - This format remembers layers. It can be opened by apps that support the Openraster format. - This app needs the requested permission to function properly. In order to save images to the local memory, the app needs read and write access to it. - This app needs the requested permission to function properly. In order to save images to the local memory, the app needs read and write access to it. - As you have denied permission with do not ask again, please go to your phone settings and grant the required permissions if you wish to use the associated functions. - Open navigation drawer - Close navigation drawer - Drag edges to their new position, then tap to enlarge or crop the image area. - Pan to position, then tap to start painting. - Pan to draw, then tap again to stop painting. - Welcome To Pocket Paint - With Pocket Paint there are no limits to your creativity. If you are new, start the intro, or skip it if you are already familiar with Pocket Paint. - Click on a tool to get more information - More possibilities - Use the top bar to open the main menu and undo or redo changes - Landscape - Pocket Paint also supports drawing in landscape mode to give you the best painting experience. - You are all set. Enjoy Pocket Paint. - Get started and create a new masterpiece. - Let\'s go + 圖片名稱 + 圖像格式 + 質量: + 佔用最小存儲空間沒有透明度被記住。 + 無損壓縮。透明度得以保留。 + 這種格式會記住圖層可以通過支持Openraster格式的應用程序將其打開。 + 此應用需要所請求的權限才能正常運行。為了將圖像保存到本地內存,應用程序需要對其進行讀寫訪問。 + 此應用需要所請求的權限才能正常運行。為了將圖像保存到本地內存,應用程序需要對其進行讀寫訪問。 + 由於您已拒絕的許可,請不要再詢問,因此,如果要使用關聯的功能,請進入手機設置並授予所需的許可權。 + 開啟導航抽屜 + 關閉導航抽屜 + 將邊緣拖動到新位置,點擊複選標記以放大或裁剪圖像區域。 + 平移至位置,然後點按以開始繪畫。 + 平移以繪畫,然後再次點擊以停止繪畫。 + 歡迎來到口袋漆 + 有了Pocket Paint,您的創造力將不受限制。如果您是新手,請開始介紹,如果您已經熟悉Pocket Paint,則跳過它。 + 單擊工具以獲取更多信息 + 更多可能性 + 使用頂部欄打開主菜單,然後撤消或重做更改 + 風景 + Pocket Paint還支持以橫向模式進行繪製,以為您提供最佳的繪畫體驗。 + 你們都準備好了。享受口袋漆。 + 開始創建新的傑作。 + 我們走吧 下一步 - Skip - About - Pocket Paint is a picture editing library that is part of the Catrobat project.\n\nCatrobat is a visual programming language and set of creativity tools for smartphones.\n\nThe source code of Pocket Paint is mainly licensed under the %s.\nFor precise details of the license see the link below. - Pocket Paint source code license + 跳過 + 關於 + Pocket Paint是圖片編輯庫,是Catrobat項目的一部分。\n\nCatrobat是一種可視化編程語言,是一套用於智能手機的創意工具。\n\nPocket Paint的源代碼主要在 %s下獲得許可。\n有關許可證的詳細信息,請參見下面的鏈接。 + Pocket Paint源代碼許可 關於 Catrobat - Intro - Intro does not support split screen. - Overwrite File? - You are about to overwrite an existing image (hint: To save it as a new image, use the \"%s\" option). Save anyway? - Do you like Pocket Paint? - Would you like to rate Pocket Paint? - We are sorry to hear that. If you want to share your experience with us, please write to contact@catrobat.org + 介紹 + 簡介不支持分屏顯示。 + 覆蓋文件? + 您將要覆蓋現有圖像(提示:要將其另存為新圖像,請使用 “%s” 選項)。還是要保存嗎? + 你喜歡Pocket Paint嗎? + 您想對Pocket Paint評分嗎? + 我們很抱歉聽到這個消息。如果您想與我們分享您的經驗,請寫信至contact@catrobat.org 取消 - Not now - Rate Pocket Paint + 現在不要 + 評價口袋漆 工具 - Current - Color - Layers - Item for bottom navigation - Switch to the tool you want to use. - Shows the currently used tool and opens its options. - Shows the currently used color and opens the color picker. - Opens the layer menu and lets you manage your layers. - Current tool icon - Image is too big to load - The image is too big to load. Click OK to scale down the image automatically. + 當前的 + 顏色 + 層數 + 底部導航項目 + 切換到您要使用的工具。 + 顯示當前使用的工具並打開其選項。 + 顯示當前使用的顏色並打開顏色​​選擇器。 + 打開圖層菜單,讓您管理圖層。 + 當前工具圖標 + 圖片太大,無法加載 + 圖片太大,無法加載。單擊確定以自動縮小圖像。 diff --git a/Paintroid/src/test/java/org/catrobat/paintroid/test/presenter/LayerPresenterTest.java b/Paintroid/src/test/java/org/catrobat/paintroid/test/presenter/LayerPresenterTest.java index ea7a4a929b..5c15ca3439 100644 --- a/Paintroid/src/test/java/org/catrobat/paintroid/test/presenter/LayerPresenterTest.java +++ b/Paintroid/src/test/java/org/catrobat/paintroid/test/presenter/LayerPresenterTest.java @@ -102,10 +102,10 @@ public void testOnBindLayerViewHolderAtSelectedPosition() { layerModel.setCurrentLayer(firstLayer); createPresenter(); - layerPresenter.onBindLayerViewHolderAtPosition(0, layerViewHolder); + layerPresenter.onBindLayerViewHolderAtPosition(0, layerViewHolder, false); verify(layerViewHolder).setSelected(0, null, null); - verify(layerViewHolder).setBitmap(firstLayerBitmap); + verify(layerViewHolder).updateImageView(firstLayerBitmap, false); verify(layerViewHolder).setCheckBox(false); verifyNoMoreInteractions(layerViewHolder); verifyZeroInteractions(commandManager, commandFactory, layerAdapter, @@ -124,10 +124,10 @@ public void testOnBindLayerViewHolderAtDeselectedPosition() { layerModel.setCurrentLayer(firstLayer); createPresenter(); - layerPresenter.onBindLayerViewHolderAtPosition(1, layerViewHolder); + layerPresenter.onBindLayerViewHolderAtPosition(1, layerViewHolder, false); verify(layerViewHolder).setDeselected(); - verify(layerViewHolder).setBitmap(secondLayer.getTransparentBitmap()); + verify(layerViewHolder).updateImageView(secondLayer.getTransparentBitmap(), false); verify(layerViewHolder).setCheckBox(false); verifyNoMoreInteractions(layerViewHolder); verifyZeroInteractions(firstLayer, commandManager, layerAdapter, diff --git a/build.gradle b/build.gradle index 7ed59935a9..15e6355587 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ ext { androidSupportLibraryVersion = '28.0.0' - androidVersionCode = 40 - androidVersionName = '2.7.3' + androidVersionCode = 41 + androidVersionName = '2.7.4' } if(project.hasProperty("snapshot")) { diff --git a/colorpicker/src/main/res/values-af-rZA/strings.xml b/colorpicker/src/main/res/values-af-rZA/strings.xml index 887319abb6..7a3316b29f 100644 --- a/colorpicker/src/main/res/values-af-rZA/strings.xml +++ b/colorpicker/src/main/res/values-af-rZA/strings.xml @@ -1,5 +1,4 @@ - - + Color Picker Color Picker tab icon Red @@ -28,4 +27,11 @@ HEX Apply Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-ar-rSA/strings.xml b/colorpicker/src/main/res/values-ar-rSA/strings.xml index 20129658c3..84a4d53fce 100644 --- a/colorpicker/src/main/res/values-ar-rSA/strings.xml +++ b/colorpicker/src/main/res/values-ar-rSA/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + منتقي الألوان أيقونة منتقي الألوان أحمر @@ -27,4 +27,11 @@ هيكس تطبيق إلغاء + current + new + التقاط اللون + حفظ التغييرات؟ + هل تريد حفظ التغييرات؟ + no + yes diff --git a/colorpicker/src/main/res/values-az-rAZ/strings.xml b/colorpicker/src/main/res/values-az-rAZ/strings.xml index 053e952c9c..ec735a2b47 100644 --- a/colorpicker/src/main/res/values-az-rAZ/strings.xml +++ b/colorpicker/src/main/res/values-az-rAZ/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply İmtina et + current + new + Pipetka + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-bg-rBG/strings.xml b/colorpicker/src/main/res/values-bg-rBG/strings.xml index ea4b2cf8b0..e09782f913 100644 --- a/colorpicker/src/main/res/values-bg-rBG/strings.xml +++ b/colorpicker/src/main/res/values-bg-rBG/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply Откажи + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-bn-rBD/strings.xml b/colorpicker/src/main/res/values-bn-rBD/strings.xml index a63a91d135..0f072103a2 100644 --- a/colorpicker/src/main/res/values-bn-rBD/strings.xml +++ b/colorpicker/src/main/res/values-bn-rBD/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + রং বাছাইকারী রঙ বাছাইকারী ট্যাব আইকন লাল @@ -27,4 +27,11 @@ হেক্স প্রয়োগ করুন বাতিল করুন + current + new + পিপেট + পরিবর্তনগুলোর সংরক্ষন? + আপনি কি আপনার পরিবর্তনগুলি সংরক্ষণ করতে চান? + no + yes diff --git a/colorpicker/src/main/res/values-bs-rBA/strings.xml b/colorpicker/src/main/res/values-bs-rBA/strings.xml index e655492503..52230f0a7a 100644 --- a/colorpicker/src/main/res/values-bs-rBA/strings.xml +++ b/colorpicker/src/main/res/values-bs-rBA/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Crvena @@ -27,4 +27,11 @@ HEX Apply Odustani + current + new + Pipeta + Sačuvaj promjene? + Da li želiš sačuvati promjene? + no + yes diff --git a/colorpicker/src/main/res/values-ca-rES/strings.xml b/colorpicker/src/main/res/values-ca-rES/strings.xml index 1a6039c6c5..09705324db 100644 --- a/colorpicker/src/main/res/values-ca-rES/strings.xml +++ b/colorpicker/src/main/res/values-ca-rES/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply Cancel·la + current + new + Pipeta + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-chr-rUS/strings.xml b/colorpicker/src/main/res/values-chr-rUS/strings.xml index 887319abb6..7a3316b29f 100644 --- a/colorpicker/src/main/res/values-chr-rUS/strings.xml +++ b/colorpicker/src/main/res/values-chr-rUS/strings.xml @@ -1,5 +1,4 @@ - - + Color Picker Color Picker tab icon Red @@ -28,4 +27,11 @@ HEX Apply Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-cs-rCZ/strings.xml b/colorpicker/src/main/res/values-cs-rCZ/strings.xml index 67a0684ecc..54e5e15489 100644 --- a/colorpicker/src/main/res/values-cs-rCZ/strings.xml +++ b/colorpicker/src/main/res/values-cs-rCZ/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Červená @@ -27,4 +27,11 @@ HEX Apply Zrušit + current + new + Pipeta + Chcete uložit změny? + Chcete uložit provedené změny? + no + yes diff --git a/colorpicker/src/main/res/values-da-rDK/strings.xml b/colorpicker/src/main/res/values-da-rDK/strings.xml index b3ef05d817..3dcf426732 100644 --- a/colorpicker/src/main/res/values-da-rDK/strings.xml +++ b/colorpicker/src/main/res/values-da-rDK/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply Slet + current + new + Pipette + Gem ændringer? + Ønsker du at gemme ændringerne? + no + yes diff --git a/colorpicker/src/main/res/values-de-rDE/strings.xml b/colorpicker/src/main/res/values-de-rDE/strings.xml index 9d796193d4..06034c96e7 100644 --- a/colorpicker/src/main/res/values-de-rDE/strings.xml +++ b/colorpicker/src/main/res/values-de-rDE/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Farbauswahl Farbauswahl-Tab-Symbol Rot @@ -27,4 +27,11 @@ HEX Anwenden Abbrechen + current + new + Pipette + Änderungen speichern? + Möchtest du deine Änderungen speichern? + no + yes diff --git a/colorpicker/src/main/res/values-el-rGR/strings.xml b/colorpicker/src/main/res/values-el-rGR/strings.xml index 671ad3d91b..515ec89e68 100644 --- a/colorpicker/src/main/res/values-el-rGR/strings.xml +++ b/colorpicker/src/main/res/values-el-rGR/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply Ακύρωση + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-en-rAU/strings.xml b/colorpicker/src/main/res/values-en-rAU/strings.xml index 1c8c54f4db..642d3890bc 100644 --- a/colorpicker/src/main/res/values-en-rAU/strings.xml +++ b/colorpicker/src/main/res/values-en-rAU/strings.xml @@ -17,9 +17,9 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - - Color Picker - Color Picker tab icon + + Colour picker + Colour picker tab icon Red Green Blue @@ -27,4 +27,11 @@ HEX Apply Cancel + current + new + Pipette + Save Changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-en-rCA/strings.xml b/colorpicker/src/main/res/values-en-rCA/strings.xml index 1c8c54f4db..7186abe209 100644 --- a/colorpicker/src/main/res/values-en-rCA/strings.xml +++ b/colorpicker/src/main/res/values-en-rCA/strings.xml @@ -17,9 +17,9 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - - Color Picker - Color Picker tab icon + + Colour picker + Colour picker tab icon Red Green Blue @@ -27,4 +27,11 @@ HEX Apply Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-en-rGB/strings.xml b/colorpicker/src/main/res/values-en-rGB/strings.xml index 1c8c54f4db..7186abe209 100644 --- a/colorpicker/src/main/res/values-en-rGB/strings.xml +++ b/colorpicker/src/main/res/values-en-rGB/strings.xml @@ -17,9 +17,9 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - - Color Picker - Color Picker tab icon + + Colour picker + Colour picker tab icon Red Green Blue @@ -27,4 +27,11 @@ HEX Apply Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-es-rES/strings.xml b/colorpicker/src/main/res/values-es-rES/strings.xml index 57b916b5e0..abc53b94ba 100644 --- a/colorpicker/src/main/res/values-es-rES/strings.xml +++ b/colorpicker/src/main/res/values-es-rES/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Selector de Color Icono de pestaña del selector de color Rojo @@ -27,4 +27,11 @@ HEX Aplicar Cancelar + current + new + Pipeta + ¿Desea guardar los cambios? + ¿Quieres guardar los cambios? + no + yes diff --git a/colorpicker/src/main/res/values-fa-rAF/strings.xml b/colorpicker/src/main/res/values-fa-rAF/strings.xml index 887319abb6..f3c652df41 100644 --- a/colorpicker/src/main/res/values-fa-rAF/strings.xml +++ b/colorpicker/src/main/res/values-fa-rAF/strings.xml @@ -1,5 +1,4 @@ - - - Color Picker - Color Picker tab icon - Red - Green - Blue - Alpha + + انتخاب کننده رنگ + آیکون انتخاب کننده رنگ + سرخ + سبز + آبی + آلفا HEX - Apply - Cancel + بکار ببر + لغو + current + new + پاپت + ذخیره تغییرات؟ + آیا می خواهید تغییرات خود را ذخیره کنید؟ + no + yes diff --git a/colorpicker/src/main/res/values-fa-rIR/strings.xml b/colorpicker/src/main/res/values-fa-rIR/strings.xml index 56c093540b..7bd64eff7a 100644 --- a/colorpicker/src/main/res/values-fa-rIR/strings.xml +++ b/colorpicker/src/main/res/values-fa-rIR/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon قرمز @@ -27,4 +27,11 @@ HEX Apply انصراف + current + new + انتخاب رنگ با قطره چکان + ذخیره‌ی تغییرات؟ + آیا مایلی تغییرات را ذخیره کنی؟ + no + yes diff --git a/colorpicker/src/main/res/values-fi-rFI/strings.xml b/colorpicker/src/main/res/values-fi-rFI/strings.xml index 887319abb6..7a3316b29f 100644 --- a/colorpicker/src/main/res/values-fi-rFI/strings.xml +++ b/colorpicker/src/main/res/values-fi-rFI/strings.xml @@ -1,5 +1,4 @@ - - + Color Picker Color Picker tab icon Red @@ -28,4 +27,11 @@ HEX Apply Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-fr-rFR/strings.xml b/colorpicker/src/main/res/values-fr-rFR/strings.xml index e2e5d8d757..da261db84d 100644 --- a/colorpicker/src/main/res/values-fr-rFR/strings.xml +++ b/colorpicker/src/main/res/values-fr-rFR/strings.xml @@ -17,14 +17,21 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - - Color Picker - Color Picker tab icon + + Sélecteur de couleur + Icône de sélection de couleur Rouge Vert Bleu Transparence HEX - Apply + Appliquer Annuler + current + new + Pipette + Enregistrer changements? + Voulez-vous enregistrer vos modifications? + no + yes diff --git a/colorpicker/src/main/res/values-gl-rES/strings.xml b/colorpicker/src/main/res/values-gl-rES/strings.xml index 6c6a337e07..b908f45765 100644 --- a/colorpicker/src/main/res/values-gl-rES/strings.xml +++ b/colorpicker/src/main/res/values-gl-rES/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Vermello @@ -27,4 +27,11 @@ HEX Apply Cancelar + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-gu-rIN/strings.xml b/colorpicker/src/main/res/values-gu-rIN/strings.xml index df42ca08bc..121f47f9c8 100644 --- a/colorpicker/src/main/res/values-gu-rIN/strings.xml +++ b/colorpicker/src/main/res/values-gu-rIN/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply રદ કરો + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-ha-rHG/strings.xml b/colorpicker/src/main/res/values-ha-rHG/strings.xml index 887319abb6..7a3316b29f 100644 --- a/colorpicker/src/main/res/values-ha-rHG/strings.xml +++ b/colorpicker/src/main/res/values-ha-rHG/strings.xml @@ -1,5 +1,4 @@ - - + Color Picker Color Picker tab icon Red @@ -28,4 +27,11 @@ HEX Apply Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-hi-rIN/strings.xml b/colorpicker/src/main/res/values-hi-rIN/strings.xml index f6214b36f1..a88f91adb9 100644 --- a/colorpicker/src/main/res/values-hi-rIN/strings.xml +++ b/colorpicker/src/main/res/values-hi-rIN/strings.xml @@ -17,14 +17,21 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - - Color Picker - Color Picker tab icon + + रंग चयन + रंग बीनने वाला टैब आइकन लाल हरा नीला अल्फा - HEX + हेक्स Apply रद्द करें + current + new + पिपेट + परिवर्तन सहेजें? + क्या आप अपने परिवर्तनों को सहेजना चाहते हैं? + no + yes diff --git a/colorpicker/src/main/res/values-hr-rHR/strings.xml b/colorpicker/src/main/res/values-hr-rHR/strings.xml index ed641cba54..fc88e8c932 100644 --- a/colorpicker/src/main/res/values-hr-rHR/strings.xml +++ b/colorpicker/src/main/res/values-hr-rHR/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Odabir boje Kartica za odabir boja Crvena @@ -27,4 +27,11 @@ HEX Primijeni Odustani + current + new + Pipeta + Spremi izmjene? + Želite li sačuvati izmjene? + no + yes diff --git a/colorpicker/src/main/res/values-hu-rHU/strings.xml b/colorpicker/src/main/res/values-hu-rHU/strings.xml index 332e3bbfc8..f8bf7f1604 100644 --- a/colorpicker/src/main/res/values-hu-rHU/strings.xml +++ b/colorpicker/src/main/res/values-hu-rHU/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Vörös @@ -27,4 +27,11 @@ HEX Apply Mégse + current + new + Pipetta + Módosítások mentése? + Szeretnéd menteni a módosításokat? + no + yes diff --git a/colorpicker/src/main/res/values-ig-rNG/strings.xml b/colorpicker/src/main/res/values-ig-rNG/strings.xml index 887319abb6..7a3316b29f 100644 --- a/colorpicker/src/main/res/values-ig-rNG/strings.xml +++ b/colorpicker/src/main/res/values-ig-rNG/strings.xml @@ -1,5 +1,4 @@ - - + Color Picker Color Picker tab icon Red @@ -28,4 +27,11 @@ HEX Apply Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-in-rID/strings.xml b/colorpicker/src/main/res/values-in-rID/strings.xml index e6b085f511..478f131a5f 100644 --- a/colorpicker/src/main/res/values-in-rID/strings.xml +++ b/colorpicker/src/main/res/values-in-rID/strings.xml @@ -17,14 +17,21 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - - Color Picker - Color Picker tab icon + + Pemilih warna + Ikon tab Color Picker Merah Hijau Biru Alfa HEX - Apply + Menerapkan Batalkan + current + new + Pipet + Simpan perubahan? + Apakah Anda ingin menyimpan perubahan? + no + yes diff --git a/colorpicker/src/main/res/values-it-rIT/strings.xml b/colorpicker/src/main/res/values-it-rIT/strings.xml index dc50115cd8..485b886fca 100644 --- a/colorpicker/src/main/res/values-it-rIT/strings.xml +++ b/colorpicker/src/main/res/values-it-rIT/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Selettore dei colori Icona scheda selettore colore Rosso @@ -27,4 +27,11 @@ HEX Applica Annulla + current + new + Pipetta + Salvare le modifiche? + Si desidera salvare le modifiche? + no + yes diff --git a/colorpicker/src/main/res/values-iw-rIL/strings.xml b/colorpicker/src/main/res/values-iw-rIL/strings.xml index efb54ef06f..18c03ee44a 100644 --- a/colorpicker/src/main/res/values-iw-rIL/strings.xml +++ b/colorpicker/src/main/res/values-iw-rIL/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon אדום @@ -27,4 +27,11 @@ HEX Apply בטל + current + new + שואב צבע + האם לשמור שינויים? + האם ברצונך לשמור את השינויים? + no + yes diff --git a/colorpicker/src/main/res/values-ja-rJP/strings.xml b/colorpicker/src/main/res/values-ja-rJP/strings.xml index b5639304fe..8553f11013 100644 --- a/colorpicker/src/main/res/values-ja-rJP/strings.xml +++ b/colorpicker/src/main/res/values-ja-rJP/strings.xml @@ -17,14 +17,21 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - - Color Picker - Color Picker tab icon + + 色の選択 + カラーピッカータブアイコン 透過度 HEX - Apply + 適用 キャンセル + current + new + ピペット + 変更を保存しますか? + 変更内容を保存しますか? + no + yes diff --git a/colorpicker/src/main/res/values-ka-rGE/strings.xml b/colorpicker/src/main/res/values-ka-rGE/strings.xml new file mode 100644 index 0000000000..7a3316b29f --- /dev/null +++ b/colorpicker/src/main/res/values-ka-rGE/strings.xml @@ -0,0 +1,37 @@ + + + + Color Picker + Color Picker tab icon + Red + Green + Blue + Alpha + HEX + Apply + Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes + diff --git a/colorpicker/src/main/res/values-kab-rDZ/strings.xml b/colorpicker/src/main/res/values-kab-rDZ/strings.xml new file mode 100644 index 0000000000..7a3316b29f --- /dev/null +++ b/colorpicker/src/main/res/values-kab-rDZ/strings.xml @@ -0,0 +1,37 @@ + + + + Color Picker + Color Picker tab icon + Red + Green + Blue + Alpha + HEX + Apply + Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes + diff --git a/colorpicker/src/main/res/values-kk-rKZ/strings.xml b/colorpicker/src/main/res/values-kk-rKZ/strings.xml index 887319abb6..7a3316b29f 100644 --- a/colorpicker/src/main/res/values-kk-rKZ/strings.xml +++ b/colorpicker/src/main/res/values-kk-rKZ/strings.xml @@ -1,5 +1,4 @@ - - + Color Picker Color Picker tab icon Red @@ -28,4 +27,11 @@ HEX Apply Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-kn-rIN/strings.xml b/colorpicker/src/main/res/values-kn-rIN/strings.xml index 758f7f99bf..54611341c9 100644 --- a/colorpicker/src/main/res/values-kn-rIN/strings.xml +++ b/colorpicker/src/main/res/values-kn-rIN/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply ರದ್ದುಮಾಡಿ + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-ko-rKR/strings.xml b/colorpicker/src/main/res/values-ko-rKR/strings.xml index 13b76f7636..bb9ede25e8 100644 --- a/colorpicker/src/main/res/values-ko-rKR/strings.xml +++ b/colorpicker/src/main/res/values-ko-rKR/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + 색상 선택기 색상 선택기 아이콘 빨강 @@ -27,4 +27,11 @@ 헥사편집기 사용하기 취소 + current + new + 색 고르기 + 변경사항을 저장하시겠습니까? + 변경 내용을 저장 하시겠습니까? + no + yes diff --git a/colorpicker/src/main/res/values-lt-rLT/strings.xml b/colorpicker/src/main/res/values-lt-rLT/strings.xml index fdfeb5dbbc..1bba74eeae 100644 --- a/colorpicker/src/main/res/values-lt-rLT/strings.xml +++ b/colorpicker/src/main/res/values-lt-rLT/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply Atšaukti + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-mk-rMK/strings.xml b/colorpicker/src/main/res/values-mk-rMK/strings.xml index ea4b2cf8b0..e09782f913 100644 --- a/colorpicker/src/main/res/values-mk-rMK/strings.xml +++ b/colorpicker/src/main/res/values-mk-rMK/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply Откажи + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-ml-rIN/strings.xml b/colorpicker/src/main/res/values-ml-rIN/strings.xml index d12cd8e29c..77b70fb833 100644 --- a/colorpicker/src/main/res/values-ml-rIN/strings.xml +++ b/colorpicker/src/main/res/values-ml-rIN/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply വേണ്ടെന്നു വയ്ക്കുക + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-ms-rMY/strings.xml b/colorpicker/src/main/res/values-ms-rMY/strings.xml index 275da795f3..5c1456f564 100644 --- a/colorpicker/src/main/res/values-ms-rMY/strings.xml +++ b/colorpicker/src/main/res/values-ms-rMY/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply Batal + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-nl-rNL/strings.xml b/colorpicker/src/main/res/values-nl-rNL/strings.xml index b819a89374..7bf3e2c9cc 100644 --- a/colorpicker/src/main/res/values-nl-rNL/strings.xml +++ b/colorpicker/src/main/res/values-nl-rNL/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Rood @@ -27,4 +27,11 @@ HEX Apply Annuleren + current + new + Pipet + Wijzigingen opslaan? + Wil je de wijzigingen opslaan? + no + yes diff --git a/colorpicker/src/main/res/values-no-rNO/strings.xml b/colorpicker/src/main/res/values-no-rNO/strings.xml index 6b62534bce..ad3c5d826a 100644 --- a/colorpicker/src/main/res/values-no-rNO/strings.xml +++ b/colorpicker/src/main/res/values-no-rNO/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Rød @@ -27,4 +27,11 @@ HEX Apply Avbryt + current + new + Pipette + Lagre endringer? + Vil du lagre endringene? + no + yes diff --git a/colorpicker/src/main/res/values-pa-rIN/strings.xml b/colorpicker/src/main/res/values-pa-rIN/strings.xml new file mode 100644 index 0000000000..7fde517a64 --- /dev/null +++ b/colorpicker/src/main/res/values-pa-rIN/strings.xml @@ -0,0 +1,37 @@ + + + + ਰੰਗ ਚੋਣਕਾਰ + ਰੰਗ ਚੋਣਕਾਰ ਟੈਬ ਆਈਕਾਨ + ਲਾਲ + ਹਰਾ + ਨੀਲਾ + ਅਲਫ਼ਾ + ਹੈਕਸ + ਲਾਗੂ ਕਰੋ + ਰੱਦ ਕਰੋ + current + new + ਪਾਈਪੇਟ + ਤਬਦੀਲੀ ਸੰਭਾਲੋ? + ਤੁਹਾਨੂੰ ਆਪਣੇ ਤਬਦੀਲੀ ਨੂੰ ਸੰਭਾਲਣ ਲਈ ਚਾਹੁੰਦੇ ਹੋ? + no + yes + diff --git a/colorpicker/src/main/res/values-pl-rPL/strings.xml b/colorpicker/src/main/res/values-pl-rPL/strings.xml index fc9bcba397..b7cadea639 100644 --- a/colorpicker/src/main/res/values-pl-rPL/strings.xml +++ b/colorpicker/src/main/res/values-pl-rPL/strings.xml @@ -17,14 +17,21 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Wybór kolorów Ikona zakładki Wyboru kolorów Czerwony (Red) Zielony (Green) - Niebieski - Alfa + Niebieski (Blue) + Przezroczyste HEX Zastosuj Anuluj + current + new + Pipeta + Zapisać zmiany? + Czy chcesz zapisać zmiany? + no + yes diff --git a/colorpicker/src/main/res/values-ps-rAF/strings.xml b/colorpicker/src/main/res/values-ps-rAF/strings.xml index 887319abb6..7a3316b29f 100644 --- a/colorpicker/src/main/res/values-ps-rAF/strings.xml +++ b/colorpicker/src/main/res/values-ps-rAF/strings.xml @@ -1,5 +1,4 @@ - - + Color Picker Color Picker tab icon Red @@ -28,4 +27,11 @@ HEX Apply Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-pt-rBR/strings.xml b/colorpicker/src/main/res/values-pt-rBR/strings.xml index 3200f80775..11d0ffce0b 100644 --- a/colorpicker/src/main/res/values-pt-rBR/strings.xml +++ b/colorpicker/src/main/res/values-pt-rBR/strings.xml @@ -17,14 +17,21 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - - Color Picker - Color Picker tab icon + + Seletor de cores + Ícone da aba de seleção de cores Vermelho Verde Azul Alfa HEX - Apply + Aplicar Cancelar + current + new + Pipeta + Salvar alterações? + Deseja salvar as alterações? + no + yes diff --git a/colorpicker/src/main/res/values-pt-rPT/strings.xml b/colorpicker/src/main/res/values-pt-rPT/strings.xml index 3200f80775..da9841977b 100644 --- a/colorpicker/src/main/res/values-pt-rPT/strings.xml +++ b/colorpicker/src/main/res/values-pt-rPT/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Vermelho @@ -27,4 +27,11 @@ HEX Apply Cancelar + current + new + Pipeta + Salvar alterações? + Deseja salvar as alterações? + no + yes diff --git a/colorpicker/src/main/res/values-ro-rRO/strings.xml b/colorpicker/src/main/res/values-ro-rRO/strings.xml index 5046eaa6e2..e8911bba65 100644 --- a/colorpicker/src/main/res/values-ro-rRO/strings.xml +++ b/colorpicker/src/main/res/values-ro-rRO/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply Anulare + current + new + Pipette + Salvaţi modificările? + Vrei să salvați modificările? + no + yes diff --git a/colorpicker/src/main/res/values-ru-rRU/strings.xml b/colorpicker/src/main/res/values-ru-rRU/strings.xml index 12ac062cff..357c45efa9 100644 --- a/colorpicker/src/main/res/values-ru-rRU/strings.xml +++ b/colorpicker/src/main/res/values-ru-rRU/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Палитра Значок вкладки палитры красный @@ -27,4 +27,11 @@ HEX Применить Отменить + current + new + Пипетка + Сохранить? + Хотите ли вы сохранить свои изменения? + no + yes diff --git a/colorpicker/src/main/res/values-sd-rPK/strings.xml b/colorpicker/src/main/res/values-sd-rPK/strings.xml index 84afc295e4..d4ae6b96dc 100644 --- a/colorpicker/src/main/res/values-sd-rPK/strings.xml +++ b/colorpicker/src/main/res/values-sd-rPK/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon ڳاڙهو @@ -27,4 +27,11 @@ HEX Apply رد ڪريو + current + new + چوسڻو + ڇا تبديليون محفوظ ٿين? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-si-rLK/strings.xml b/colorpicker/src/main/res/values-si-rLK/strings.xml index 887319abb6..b514093323 100644 --- a/colorpicker/src/main/res/values-si-rLK/strings.xml +++ b/colorpicker/src/main/res/values-si-rLK/strings.xml @@ -1,5 +1,4 @@ - - + Color Picker Color Picker tab icon Red @@ -27,5 +26,12 @@ Alpha HEX Apply - Cancel + අවලංගු කරන්න + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-sk-rSK/strings.xml b/colorpicker/src/main/res/values-sk-rSK/strings.xml index d208a3771e..dcac57d0c6 100644 --- a/colorpicker/src/main/res/values-sk-rSK/strings.xml +++ b/colorpicker/src/main/res/values-sk-rSK/strings.xml @@ -1,5 +1,4 @@ - - + Color Picker Color Picker tab icon Red @@ -28,4 +27,11 @@ HEX Apply Zrušiť + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-sl-rSI/strings.xml b/colorpicker/src/main/res/values-sl-rSI/strings.xml index b44cb2d328..6339d890f5 100644 --- a/colorpicker/src/main/res/values-sl-rSI/strings.xml +++ b/colorpicker/src/main/res/values-sl-rSI/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Rdeče @@ -27,4 +27,11 @@ HEX Apply Prekliči + current + new + Pipeta + Shrani spremembe? + Ali želite shraniti spremembe? + no + yes diff --git a/colorpicker/src/main/res/values-sq-rAL/strings.xml b/colorpicker/src/main/res/values-sq-rAL/strings.xml index 13b6559887..c78defd7d0 100644 --- a/colorpicker/src/main/res/values-sq-rAL/strings.xml +++ b/colorpicker/src/main/res/values-sq-rAL/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply Anulo + current + new + Pipette + Ruaji ndryshimet? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-sr-rCS/strings.xml b/colorpicker/src/main/res/values-sr-rCS/strings.xml index dc47366a80..c852db5543 100644 --- a/colorpicker/src/main/res/values-sr-rCS/strings.xml +++ b/colorpicker/src/main/res/values-sr-rCS/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Odabirač boja Kartica za odabir boja Crvena @@ -27,4 +27,11 @@ Hex Primeni Otkaži + current + new + cevčica + Spasi izmene? + Da li želite da sačuvate svoje izmene? + no + yes diff --git a/colorpicker/src/main/res/values-sr-rSP/strings.xml b/colorpicker/src/main/res/values-sr-rSP/strings.xml index 56c168f9a3..7c9d8f73e0 100644 --- a/colorpicker/src/main/res/values-sr-rSP/strings.xml +++ b/colorpicker/src/main/res/values-sr-rSP/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply Откажи + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-sv-rSE/strings.xml b/colorpicker/src/main/res/values-sv-rSE/strings.xml index 781fcb9dea..c81e506476 100644 --- a/colorpicker/src/main/res/values-sv-rSE/strings.xml +++ b/colorpicker/src/main/res/values-sv-rSE/strings.xml @@ -17,14 +17,21 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - - Color Picker - Color Picker tab icon + + Färgväljare + Ikon för Färgväljarfliken Röd Grön Blå Alfa HEX - Apply + Använd Avbryt + current + new + Pipett + Spara ändringar? + Vill du spara ändringarna? + no + yes diff --git a/colorpicker/src/main/res/values-sw-rKE/strings.xml b/colorpicker/src/main/res/values-sw-rKE/strings.xml index d3dfa5a2ab..da503227c7 100644 --- a/colorpicker/src/main/res/values-sw-rKE/strings.xml +++ b/colorpicker/src/main/res/values-sw-rKE/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Nyekunduu @@ -27,4 +27,11 @@ HEX Apply Sitisha + current + new + Pipette + Hifadhi mabadiliko? + Je, unataka kuhifadhi madiliko yako? + no + yes diff --git a/colorpicker/src/main/res/values-ta-rIN/strings.xml b/colorpicker/src/main/res/values-ta-rIN/strings.xml index 0e8cfdcac2..08c2c439ac 100644 --- a/colorpicker/src/main/res/values-ta-rIN/strings.xml +++ b/colorpicker/src/main/res/values-ta-rIN/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + வண்ண தேர்வு வண்ண தேர்வு தாவல் ஐகான் சிவப்பு @@ -27,4 +27,11 @@ எண்ம (ஹெக்ஸ்) அமல்படுத்து தவிர் + current + new + குழாயி + மாற்றங்களை சேமிக்க வேண்டுமா? + மாற்றங்களைச் சேமிக்க விரும்புகிறீர்களா? + no + yes diff --git a/colorpicker/src/main/res/values-te-rIN/strings.xml b/colorpicker/src/main/res/values-te-rIN/strings.xml index d873c34481..d0398e467d 100644 --- a/colorpicker/src/main/res/values-te-rIN/strings.xml +++ b/colorpicker/src/main/res/values-te-rIN/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Red @@ -27,4 +27,11 @@ HEX Apply రద్దు చేయు + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-th-rTH/strings.xml b/colorpicker/src/main/res/values-th-rTH/strings.xml index 1d27549934..3f016a8f91 100644 --- a/colorpicker/src/main/res/values-th-rTH/strings.xml +++ b/colorpicker/src/main/res/values-th-rTH/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + ตัวเลือกสี ไอคอนแท็บตัวเลือกสี สีแดง @@ -27,4 +27,11 @@ หลากหลาย นำไปใช้ ยกเลิก + current + new + ดูดสี + บันทึกการเปลี่ยนแปลงหรือไม่? + คุณต้องบันทึกการเปลี่ยนแปลงหรือไม่? + no + yes diff --git a/colorpicker/src/main/res/values-tl-rPH/strings.xml b/colorpicker/src/main/res/values-tl-rPH/strings.xml new file mode 100644 index 0000000000..7a3316b29f --- /dev/null +++ b/colorpicker/src/main/res/values-tl-rPH/strings.xml @@ -0,0 +1,37 @@ + + + + Color Picker + Color Picker tab icon + Red + Green + Blue + Alpha + HEX + Apply + Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes + diff --git a/colorpicker/src/main/res/values-tr-rTR/strings.xml b/colorpicker/src/main/res/values-tr-rTR/strings.xml index 076e904475..ebde4b5560 100644 --- a/colorpicker/src/main/res/values-tr-rTR/strings.xml +++ b/colorpicker/src/main/res/values-tr-rTR/strings.xml @@ -17,14 +17,21 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - - Color Picker - Color Picker tab icon + + Renk seçici + Renk Seçici sekme ikonu Kırmızı Yeşil Mavi - Alfa + Şefaflık HEX - Apply + Uygula İptal et + current + new + Renk Seçici + Değişiklikleri kaydet? + Değişiklikleri kaydetmek istiyor musunuz? + no + yes diff --git a/colorpicker/src/main/res/values-tw-rGH/strings.xml b/colorpicker/src/main/res/values-tw-rGH/strings.xml new file mode 100644 index 0000000000..7a3316b29f --- /dev/null +++ b/colorpicker/src/main/res/values-tw-rGH/strings.xml @@ -0,0 +1,37 @@ + + + + Color Picker + Color Picker tab icon + Red + Green + Blue + Alpha + HEX + Apply + Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes + diff --git a/colorpicker/src/main/res/values-uk-rUA/strings.xml b/colorpicker/src/main/res/values-uk-rUA/strings.xml index 887319abb6..7a3316b29f 100644 --- a/colorpicker/src/main/res/values-uk-rUA/strings.xml +++ b/colorpicker/src/main/res/values-uk-rUA/strings.xml @@ -1,5 +1,4 @@ - - + Color Picker Color Picker tab icon Red @@ -28,4 +27,11 @@ HEX Apply Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-ur-rPK/strings.xml b/colorpicker/src/main/res/values-ur-rPK/strings.xml index 3c13452627..a03534a31c 100644 --- a/colorpicker/src/main/res/values-ur-rPK/strings.xml +++ b/colorpicker/src/main/res/values-ur-rPK/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + رنگ چننا رنگ چننا ٹیب آئکن سرخ @@ -27,4 +27,11 @@ HEX لاگو کریں منسوخ + current + new + نعمونہ + تبدیلیاں محفوظ کریں؟ + کیا آپ تبدیلیاں محفوظ کرنا چاہتے ہیں? + no + yes diff --git a/colorpicker/src/main/res/values-uz-rUZ/strings.xml b/colorpicker/src/main/res/values-uz-rUZ/strings.xml index 887319abb6..7a3316b29f 100644 --- a/colorpicker/src/main/res/values-uz-rUZ/strings.xml +++ b/colorpicker/src/main/res/values-uz-rUZ/strings.xml @@ -1,5 +1,4 @@ - - + Color Picker Color Picker tab icon Red @@ -28,4 +27,11 @@ HEX Apply Cancel + current + new + Pipette + Save changes? + Do you want to save your changes? + no + yes diff --git a/colorpicker/src/main/res/values-vi-rVN/strings.xml b/colorpicker/src/main/res/values-vi-rVN/strings.xml index 6c3890b8a1..41b046dc48 100644 --- a/colorpicker/src/main/res/values-vi-rVN/strings.xml +++ b/colorpicker/src/main/res/values-vi-rVN/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + Color Picker Color Picker tab icon Đỏ @@ -27,4 +27,11 @@ HEX Apply Hủy bỏ + current + new + Pipette + Lưu thay đổi? + Bạn có muốn lưu thay đổi của mình? + no + yes diff --git a/colorpicker/src/main/res/values-zh-rCN/strings.xml b/colorpicker/src/main/res/values-zh-rCN/strings.xml index a607fc90d6..b92d67879a 100644 --- a/colorpicker/src/main/res/values-zh-rCN/strings.xml +++ b/colorpicker/src/main/res/values-zh-rCN/strings.xml @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - + 颜色选择器 颜色选择标签图标 红色 @@ -27,4 +27,11 @@ 十六进制 申请 取消 + current + new + 吸管 + 是否保存修改? + 您要保存这些更改吗? + no + yes diff --git a/colorpicker/src/main/res/values-zh-rTW/strings.xml b/colorpicker/src/main/res/values-zh-rTW/strings.xml index 83db665416..49c21bda27 100644 --- a/colorpicker/src/main/res/values-zh-rTW/strings.xml +++ b/colorpicker/src/main/res/values-zh-rTW/strings.xml @@ -17,14 +17,21 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . --> - - Color Picker - Color Picker tab icon + + 顏色選擇器 + 拾色器選項卡圖標 透明度 - HEX - Apply + 十六進制 + 申請 取消 + current + new + 吸管 + 儲存更改? + 你要儲存你的更改嗎? + no + yes diff --git a/crowdin_Paintroid.yml b/crowdin_Paintroid.yml index 8bd9f18f97..58633100ed 100644 --- a/crowdin_Paintroid.yml +++ b/crowdin_Paintroid.yml @@ -117,11 +117,12 @@ files: [ # Often software projects have custom names for the directories where translations are placed. crowdin-cli allows you # to map your own languages to be understandable by Crowdin. # - #"languages_mapping" : { - # "two_letters_code" : { - # "crowdin_language_code" : "local_name" - # } - #}, + "languages_mapping" : { + "android_code" : { + "kab" : "kab-rDZ", + "tw" : "tw-rGH" + } + }, # # Does the first line contain header? diff --git a/crowdin_colorpicker.yml b/crowdin_colorpicker.yml index 25763e16f1..9a4a6c3c65 100644 --- a/crowdin_colorpicker.yml +++ b/crowdin_colorpicker.yml @@ -21,13 +21,13 @@ files: [ # Source files filter # e.g. "/resources/en/*.json" # - "source" : "/colorpicker/src/main/res/values/string.xml", + "source" : "/colorpicker/src/main/res/values/strings.xml", # # Where translations will be placed # e.g. "/resources/%two_letters_code%/%original_file_name%" # - "translation" : "/colorpicker/src/main/res/values-%android_code%/string.xml", + "translation" : "/colorpicker/src/main/res/values-%android_code%/strings.xml", # # Files or directories for ignore @@ -39,7 +39,7 @@ files: [ # The dest allows you to specify a file name in Crowdin # e.g. "/messages.json" # - "dest" : "/paintroid/colorpicker/string.xml", + "dest" : "/paintroid/colorpicker/strings.xml", # # File type @@ -117,11 +117,12 @@ files: [ # Often software projects have custom names for the directories where translations are placed. crowdin-cli allows you # to map your own languages to be understandable by Crowdin. # - #"languages_mapping" : { - # "two_letters_code" : { - # "crowdin_language_code" : "local_name" - # } - #}, + "languages_mapping" : { + "android_code" : { + "kab" : "kab-rDZ", + "tw" : "tw-rGH" + } + }, # # Does the first line contain header? diff --git a/gradle.properties b/gradle.properties index 5465fec0ec..a6d3061fad 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,3 @@ android.enableJetifier=true -android.useAndroidX=true \ No newline at end of file +android.useAndroidX=true +org.gradle.jvmargs=-XX:MaxPermSize=1024m -Xmx4096m \ No newline at end of file