diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/FileIO.kt b/Paintroid/src/main/java/org/catrobat/paintroid/FileIO.kt index 864f069b0c..045be32caf 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/FileIO.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/FileIO.kt @@ -104,7 +104,8 @@ object FileIO { PNG("png"), JPG("jpg"), ORA("ora"), - CATROBAT("catrobat-image"); + CATROBAT("catrobat-image"), + fun toExtension(): String = ".$value" } @@ -132,7 +133,7 @@ object FileIO { } @Throws(IOException::class) - fun saveBitmapToUri(uri: Uri, bitmap: Bitmap?, context: Context): Uri { + fun saveBitmapToUri(uri: Uri, bitmap: Bitmap?, context: Context): Uri { val uid = UUID.randomUUID() val cachedImageUri = saveBitmapToCache(bitmap, context as MainActivity, uid.toString()) var cachedFile: File? = null diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/PaintroidApplication.kt b/Paintroid/src/main/java/org/catrobat/paintroid/PaintroidApplication.kt index b93795d6d6..f697af06a8 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/PaintroidApplication.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/PaintroidApplication.kt @@ -18,17 +18,26 @@ */ package org.catrobat.paintroid + +import android.graphics.Bitmap import java.io.File import java.lang.IllegalArgumentException + @SuppressWarnings("ThrowingExceptionsWithoutMessageOrCause") class PaintroidApplication private constructor() { companion object { @JvmStatic var cacheDir: File? = null - } - init { - throw IllegalArgumentException() + init { + throw IllegalArgumentException() + } } } + + + + + + diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/contract/MainActivityContracts.kt b/Paintroid/src/main/java/org/catrobat/paintroid/contract/MainActivityContracts.kt index 84fef55bab..cec5631c1b 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/contract/MainActivityContracts.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/contract/MainActivityContracts.kt @@ -308,6 +308,7 @@ interface MainActivityContracts { fun checkForTemporaryFile(): Boolean fun setColorHistoryAfterLoadImage(colorHistory: ColorHistory?) + } interface Model { diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/dialog/SaveInformationDialog.kt b/Paintroid/src/main/java/org/catrobat/paintroid/dialog/SaveInformationDialog.kt index b58f914105..389680786d 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/dialog/SaveInformationDialog.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/dialog/SaveInformationDialog.kt @@ -22,6 +22,7 @@ import android.annotation.SuppressLint import android.app.Dialog import android.graphics.Bitmap import android.os.Bundle +import android.os.Environment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -41,14 +42,30 @@ import org.catrobat.paintroid.FileIO.FileType.PNG import org.catrobat.paintroid.FileIO.FileType.JPG import org.catrobat.paintroid.FileIO.FileType.CATROBAT import org.catrobat.paintroid.FileIO.FileType.ORA +import org.catrobat.paintroid.PaintroidApplication + + import org.catrobat.paintroid.R +import java.io.File +import java.io.FileOutputStream +import java.io.IOException import java.util.Locale + + + + + + + private const val STANDARD_FILE_NAME = "image" private const val SET_NAME = "setName" private const val PERMISSION = "permission" private const val IS_EXPORT = "isExport" + + + class SaveInformationDialog : MainActivityDialogFragment(), OnItemSelectedListener, @@ -118,6 +135,7 @@ class SaveInformationDialog : FileIO.storeImageUri = null if (FileIO.checkFileExists(FileIO.fileType, FileIO.defaultFileName, requireContext().contentResolver)) { presenter.showOverwriteDialog(permission, isExport) + } else { presenter.switchBetweenVersions(permission, isExport) } @@ -127,8 +145,12 @@ class SaveInformationDialog : .create() } + + private fun initViews(customLayout: View) { initSpecificFormatLayout(customLayout) + + initJpgView() initSeekBar() initPercentage() @@ -141,6 +163,10 @@ class SaveInformationDialog : specificFormatLayout = view.findViewById(R.id.pocketpaint_save_format_specific_options) } + + + + private fun initJpgView() { jpgView = inflater.inflate( R.layout.dialog_pocketpaint_save_jpg_sub_dialog, @@ -168,11 +194,14 @@ class SaveInformationDialog : JPG -> presenter.showJpgInformationDialog() ORA -> presenter.showOraInformationDialog() CATROBAT -> presenter.showCatrobatInformationDialog() + FileType.GIF -> presenter.showGifInformationDialog() else -> presenter.showPngInformationDialog() } } } + + private fun initSpinner(view: View) { spinner = view.findViewById(R.id.pocketpaint_save_dialog_spinner) val spinnerArray = FileType.values().map { it.value } @@ -204,6 +233,7 @@ class SaveInformationDialog : JPG -> spinner.setSelection(JPG.ordinal) ORA -> spinner.setSelection(ORA.ordinal) CATROBAT -> spinner.setSelection(CATROBAT.ordinal) + else -> spinner.setSelection(PNG.ordinal) } } @@ -212,8 +242,10 @@ class SaveInformationDialog : when (parent?.getItemAtPosition(position).toString().toLowerCase(Locale.getDefault())) { JPG.value -> setFileDetails(Bitmap.CompressFormat.JPEG, JPG) PNG.value -> setFileDetails(Bitmap.CompressFormat.PNG, PNG) + ORA.value -> setFileDetails(Bitmap.CompressFormat.PNG, ORA) CATROBAT.value -> setFileDetails(Bitmap.CompressFormat.PNG, CATROBAT) + } } @@ -226,3 +258,6 @@ class SaveInformationDialog : override fun onStartTrackingTouch(seekBar: SeekBar) = Unit override fun onStopTrackingTouch(seekBar: SeekBar) = Unit } + + + 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 index 0658b7e59d..ca32287827 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableFactory.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableFactory.kt @@ -25,6 +25,9 @@ class DrawableFactory { DrawableShape.OVAL -> OvalDrawable() DrawableShape.HEART -> HeartDrawable() DrawableShape.STAR -> StarDrawable() + DrawableShape.PENTAGON -> PentagonDrawable() + DrawableShape.TRIANGLE -> TriangleDrawable() + DrawableShape.HEXAGON -> HexagonDrawable() } } } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableShape.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableShape.kt index cc76fae877..30eed1cb17 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableShape.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/DrawableShape.kt @@ -19,5 +19,5 @@ package org.catrobat.paintroid.tools.drawable enum class DrawableShape { - RECTANGLE, OVAL, HEART, STAR + RECTANGLE, OVAL, HEART, STAR , PENTAGON, TRIANGLE, HEXAGON } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/HexagonDrawable.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/HexagonDrawable.kt new file mode 100644 index 0000000000..f48574fb96 --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/HexagonDrawable.kt @@ -0,0 +1,31 @@ +package org.catrobat.paintroid.tools.drawable +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path +import android.graphics.RectF + +private const val CONSTANT_1 = 2f +private const val CONSTANT_2 = 1.7f +class HexagonDrawable:ShapeDrawable { + private val path = Path() + override fun draw(canvas: Canvas, shapeRect: RectF, drawPaint: Paint) { + val midWidth = shapeRect.width() / 2 + val midHeight = shapeRect.height() / 2 + val height = shapeRect.height() / CONSTANT_2 + val width = shapeRect.width() / CONSTANT_1 + path.run { + reset() + moveTo(midWidth - width, midHeight) + lineTo(midWidth - width/2, midHeight - height) + lineTo(midWidth + width/2, midHeight - height) + lineTo(midWidth + width, midHeight) + lineTo(midWidth + width/2, midHeight + height) + lineTo(midWidth - width/2, midHeight + height) + lineTo(midWidth - width, midHeight) + close() + offset(shapeRect.left, shapeRect.top) + } + canvas.drawPath(path, drawPaint) + } +} + diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/PentagonDrawable.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/PentagonDrawable.kt new file mode 100644 index 0000000000..3da3ce9fcb --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/PentagonDrawable.kt @@ -0,0 +1,33 @@ +package org.catrobat.paintroid.tools.drawable + +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path +import android.graphics.RectF + +private const val CONSTANT_1 = 0.95f +private const val CONSTANT_2 = 0.31f +private const val CONSTANT_3 = 0.59f +class PentagonDrawable : ShapeDrawable{ + + private val path = Path() + + override fun draw(canvas: Canvas, shapeRect: RectF, drawPaint: Paint) { + 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 + CONSTANT_1 * width / 2, CONSTANT_2 * height) + lineTo(midWidth + CONSTANT_3 * width / 2, height) + lineTo(midWidth - CONSTANT_3 * width / 2, height) + lineTo(midWidth - CONSTANT_1 * width / 2, CONSTANT_2 * height) + lineTo(midWidth, 0f) + close() + offset(shapeRect.left, shapeRect.top) + } + canvas.drawPath(path, drawPaint) + } +} \ No newline at end of file diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/TriangleDrawable.kt b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/TriangleDrawable.kt new file mode 100644 index 0000000000..b5346bb1ea --- /dev/null +++ b/Paintroid/src/main/java/org/catrobat/paintroid/tools/drawable/TriangleDrawable.kt @@ -0,0 +1,22 @@ +package org.catrobat.paintroid.tools.drawable + +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path +import android.graphics.RectF +class TriangleDrawable :ShapeDrawable{ + private val path = Path() + + override fun draw(canvas: Canvas, shapeRect: RectF, drawPaint: Paint) { + path.run { + reset() + moveTo(shapeRect.left, shapeRect.bottom) + lineTo(shapeRect.right, shapeRect.bottom) + lineTo(shapeRect.centerX(), shapeRect.top) + lineTo(shapeRect.left, shapeRect.bottom) + close() + } + canvas.drawPath(path, drawPaint) + } + +} \ No newline at end of file diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/ui/DrawingSurface.kt b/Paintroid/src/main/java/org/catrobat/paintroid/ui/DrawingSurface.kt index 3a0eaecf3a..ae8512a08d 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/ui/DrawingSurface.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/ui/DrawingSurface.kt @@ -244,6 +244,10 @@ open class DrawingSurface : SurfaceView, SurfaceHolder.Callback { drawingThread?.stop() } + fun copyBitmap() { + + } + private inner class DrawLoop : Runnable { val holder: SurfaceHolder = getHolder() override fun run() { diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/ui/tools/DefaultShapeToolOptionsView.kt b/Paintroid/src/main/java/org/catrobat/paintroid/ui/tools/DefaultShapeToolOptionsView.kt index 44f78af782..097e12f197 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/ui/tools/DefaultShapeToolOptionsView.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/ui/tools/DefaultShapeToolOptionsView.kt @@ -57,6 +57,9 @@ class DefaultShapeToolOptionsView(rootView: ViewGroup) : ShapeToolOptionsView { private val outlineWidthEditText: AppCompatEditText private val shapeToolDialogTitle: AppCompatTextView private val shapeToolFillOutline: AppCompatTextView + private val triangleButton: AppCompatImageButton + private val pentagonButton: AppCompatImageButton + private val hexagonButton: AppCompatImageButton init { val inflater = LayoutInflater.from(rootView.context) @@ -74,6 +77,9 @@ class DefaultShapeToolOptionsView(rootView: ViewGroup) : ShapeToolOptionsView { outlineTextView = findViewById(R.id.pocketpaint_outline_view_text_view) outlineWidthSeekBar = findViewById(R.id.pocketpaint_shape_stroke_width_seek_bar) outlineWidthEditText = findViewById(R.id.pocketpaint_shape_outline_edit) + triangleButton = findViewById(R.id.pocketpaint_shapes_triangle_btn) + pentagonButton = findViewById(R.id.pocketpaint_shapes_pentagon_btn) + hexagonButton = findViewById(R.id.pocketpaint_shapes_hexagon_btn) } outlineWidthEditText.filters = arrayOf(DefaultNumberRangeFilter(MIN_VAL, MAX_VAL)) @@ -89,6 +95,10 @@ class DefaultShapeToolOptionsView(rootView: ViewGroup) : ShapeToolOptionsView { circleButton.setOnClickListener { onShapeClicked(DrawableShape.OVAL) } heartButton.setOnClickListener { onShapeClicked(DrawableShape.HEART) } starButton.setOnClickListener { onShapeClicked(DrawableShape.STAR) } + triangleButton.setOnClickListener { onShapeClicked(DrawableShape.TRIANGLE) } + pentagonButton.setOnClickListener { onShapeClicked(DrawableShape.PENTAGON) } + hexagonButton.setOnClickListener { onShapeClicked(DrawableShape.HEXAGON) } + fillButton.setOnClickListener { onDrawTypeClicked(DrawableStyle.FILL) } outlineButton.setOnClickListener { onDrawTypeClicked(DrawableStyle.STROKE) } outlineWidthSeekBar.setOnSeekBarChangeListener(object : OnSeekBarChangeListener { @@ -141,7 +151,16 @@ class DefaultShapeToolOptionsView(rootView: ViewGroup) : ShapeToolOptionsView { } private fun resetShapeActivated() { - val buttons = arrayOf(squareButton, circleButton, heartButton, starButton) + //val buttons = arrayOf(squareButton, circleButton, heartButton, starButton,) + val buttons = arrayOf( + squareButton, + circleButton, + heartButton, + starButton, + triangleButton, + pentagonButton, + hexagonButton + ) for (button in buttons) { button.isSelected = false } @@ -175,6 +194,18 @@ class DefaultShapeToolOptionsView(rootView: ViewGroup) : ShapeToolOptionsView { starButton.isSelected = true setShapeToolDialogTitle(R.string.shape_tool_dialog_star_title) } + DrawableShape.TRIANGLE -> { + triangleButton.isSelected = true + setShapeToolDialogTitle(R.string.shape_tool_dialog_triangle_title) + } + DrawableShape.PENTAGON -> { + pentagonButton.isSelected = true + setShapeToolDialogTitle(R.string.shape_tool_dialog_pentagon_title) + } + DrawableShape.HEXAGON -> { + hexagonButton.isSelected = true + setShapeToolDialogTitle(R.string.shape_tool_dialog_hexagon_title) + } } } @@ -184,6 +215,10 @@ class DefaultShapeToolOptionsView(rootView: ViewGroup) : ShapeToolOptionsView { circleButtonResource: Int, heartButtonResource: Int, starButtonResource: Int, + triangleButtonResource: Int, + pentagonButtonResource: Int, + hexagonButtonResource: Int, + visibility: Int ) { shapeToolFillOutline.setText(fillTitle) @@ -191,6 +226,10 @@ class DefaultShapeToolOptionsView(rootView: ViewGroup) : ShapeToolOptionsView { circleButton.setImageResource(circleButtonResource) heartButton.setImageResource(heartButtonResource) starButton.setImageResource(starButtonResource) + triangleButton.setImageResource(triangleButtonResource) + pentagonButton.setImageResource(pentagonButtonResource) + hexagonButton.setImageResource(hexagonButtonResource) + outlineWidthSeekBar.visibility = visibility outlineWidthEditText.visibility = visibility outlineView.visibility = visibility @@ -208,6 +247,9 @@ class DefaultShapeToolOptionsView(rootView: ViewGroup) : ShapeToolOptionsView { R.drawable.ic_pocketpaint_circle, R.drawable.ic_pocketpaint_heart, R.drawable.ic_pocketpaint_star, + R.drawable.ic_pocketpaint_triangle, + R.drawable.ic_pocketpaint_pentagon, + R.drawable.ic_pocketpaint_hexagon, View.GONE ) } @@ -219,6 +261,9 @@ class DefaultShapeToolOptionsView(rootView: ViewGroup) : ShapeToolOptionsView { R.drawable.ic_pocketpaint_circle_out, R.drawable.ic_pocketpaint_heart_out, R.drawable.ic_pocketpaint_star_out, + R.drawable.ic_pocketpaint_triangle_out, + R.drawable.ic_pocketpaint_pentagon_out, + R.drawable.ic_pocketpaint_hexagon_out, View.VISIBLE ) } diff --git a/Paintroid/src/main/res/drawable/ic_pocketpaint_hexagon.xml b/Paintroid/src/main/res/drawable/ic_pocketpaint_hexagon.xml new file mode 100644 index 0000000000..1d44f876f2 --- /dev/null +++ b/Paintroid/src/main/res/drawable/ic_pocketpaint_hexagon.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/Paintroid/src/main/res/drawable/ic_pocketpaint_hexagon_out.xml b/Paintroid/src/main/res/drawable/ic_pocketpaint_hexagon_out.xml new file mode 100644 index 0000000000..8751339730 --- /dev/null +++ b/Paintroid/src/main/res/drawable/ic_pocketpaint_hexagon_out.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/Paintroid/src/main/res/drawable/ic_pocketpaint_pentagon.xml b/Paintroid/src/main/res/drawable/ic_pocketpaint_pentagon.xml new file mode 100644 index 0000000000..cad4566cb4 --- /dev/null +++ b/Paintroid/src/main/res/drawable/ic_pocketpaint_pentagon.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/Paintroid/src/main/res/drawable/ic_pocketpaint_pentagon_out.xml b/Paintroid/src/main/res/drawable/ic_pocketpaint_pentagon_out.xml new file mode 100644 index 0000000000..3ce29057b6 --- /dev/null +++ b/Paintroid/src/main/res/drawable/ic_pocketpaint_pentagon_out.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/Paintroid/src/main/res/drawable/ic_pocketpaint_triangle.xml b/Paintroid/src/main/res/drawable/ic_pocketpaint_triangle.xml new file mode 100644 index 0000000000..425c02b54e --- /dev/null +++ b/Paintroid/src/main/res/drawable/ic_pocketpaint_triangle.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/Paintroid/src/main/res/drawable/ic_pocketpaint_triangle_out.xml b/Paintroid/src/main/res/drawable/ic_pocketpaint_triangle_out.xml new file mode 100644 index 0000000000..2b197abfc2 --- /dev/null +++ b/Paintroid/src/main/res/drawable/ic_pocketpaint_triangle_out.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/Paintroid/src/main/res/layout/dialog_pocketpaint_save.xml b/Paintroid/src/main/res/layout/dialog_pocketpaint_save.xml index 3cb7da04bf..f4d85ca548 100644 --- a/Paintroid/src/main/res/layout/dialog_pocketpaint_save.xml +++ b/Paintroid/src/main/res/layout/dialog_pocketpaint_save.xml @@ -98,4 +98,21 @@ android:clipChildren="false" android:clipToPadding="false" /> + + + + + + + + diff --git a/Paintroid/src/main/res/layout/dialog_pocketpaint_save_gif_sub_dialog.xml b/Paintroid/src/main/res/layout/dialog_pocketpaint_save_gif_sub_dialog.xml new file mode 100644 index 0000000000..1c85a6521f --- /dev/null +++ b/Paintroid/src/main/res/layout/dialog_pocketpaint_save_gif_sub_dialog.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + diff --git a/Paintroid/src/main/res/layout/dialog_pocketpaint_shapes.xml b/Paintroid/src/main/res/layout/dialog_pocketpaint_shapes.xml index 53849476ed..a0fc963140 100644 --- a/Paintroid/src/main/res/layout/dialog_pocketpaint_shapes.xml +++ b/Paintroid/src/main/res/layout/dialog_pocketpaint_shapes.xml @@ -139,6 +139,33 @@ android:layout_weight="1" android:contentDescription="@string/shape_tool_dialog_star_title" android:src="@drawable/ic_pocketpaint_star" /> + + + + + + diff --git a/Paintroid/src/main/res/values/string.xml b/Paintroid/src/main/res/values/string.xml index de2ea72fb6..2ec01f42de 100644 --- a/Paintroid/src/main/res/values/string.xml +++ b/Paintroid/src/main/res/values/string.xml @@ -128,6 +128,9 @@ Ellipse Star Heart + Triangle + Pentagon + Hexagon Fill Outline diff --git a/Paintroid/src/main/res/values/strings.xml b/Paintroid/src/main/res/values/strings.xml new file mode 100644 index 0000000000..9d4b18e6b9 --- /dev/null +++ b/Paintroid/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 2c7e76738b..dd08cd86b9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -102,4 +102,5 @@ dependencies { implementation project(':Paintroid') implementation 'com.android.support:support-core-utils:28.0.0' + }