From 9b8888a1252438eca415eb037223bf98178ba561 Mon Sep 17 00:00:00 2001 From: therealbluepandabear Date: Tue, 9 Aug 2022 19:00:08 +1200 Subject: [PATCH] Added the ability to extract projects to their raw dimensions (the user also has the options of extracting to scaled dimensions as well). This closes issue #184 (fix #184). More changes are needed to be done in future commits to stabilize this feature and improve the user interface. 'Save as' has been transitioned into a single menu item titled 'Export'. When the user clicks 'Export', a dialog is shown from which the user can input values such as the file's title, the file's type, and the file's resolution (raw or scaled). --- .../menu/CanvasActivity+onMenuItemSelected.kt | 95 ++++++++--- .../PixelGridView+saveAsImage.kt | 19 ++- .../pixelgridview/PixelGridView.kt | 10 +- .../pixapencil/enums/BitmapResolution.kt | 6 + .../res/drawable/radio_button_selected.xml | 10 ++ .../res/drawable/radio_button_unselected.xml | 11 ++ .../drawable/radio_button_unselected_last.xml | 10 ++ .../main/res/drawable/radiobuttonselector.xml | 7 + .../res/drawable/radiobuttonselectorlast.xml | 7 + .../res/drawable/radiobuttontextselector.xml | 5 + .../layout/export_project_dialog_layout.xml | 148 ++++++++++++++++++ .../res/menu/activity_canvas_top_app_menu.xml | 100 ++++++------ 12 files changed, 350 insertions(+), 78 deletions(-) create mode 100644 app/src/main/java/com/therealbluepandabear/pixapencil/enums/BitmapResolution.kt create mode 100644 app/src/main/res/drawable/radio_button_selected.xml create mode 100644 app/src/main/res/drawable/radio_button_unselected.xml create mode 100644 app/src/main/res/drawable/radio_button_unselected_last.xml create mode 100644 app/src/main/res/drawable/radiobuttonselector.xml create mode 100644 app/src/main/res/drawable/radiobuttonselectorlast.xml create mode 100644 app/src/main/res/drawable/radiobuttontextselector.xml create mode 100644 app/src/main/res/layout/export_project_dialog_layout.xml diff --git a/app/src/main/java/com/therealbluepandabear/pixapencil/activities/canvas/oncreate/menu/CanvasActivity+onMenuItemSelected.kt b/app/src/main/java/com/therealbluepandabear/pixapencil/activities/canvas/oncreate/menu/CanvasActivity+onMenuItemSelected.kt index 53448a53..519cc16f 100644 --- a/app/src/main/java/com/therealbluepandabear/pixapencil/activities/canvas/oncreate/menu/CanvasActivity+onMenuItemSelected.kt +++ b/app/src/main/java/com/therealbluepandabear/pixapencil/activities/canvas/oncreate/menu/CanvasActivity+onMenuItemSelected.kt @@ -1,13 +1,21 @@ package com.therealbluepandabear.pixapencil.activities.canvas.oncreate.menu import android.graphics.Color -import android.os.Build +import android.util.Log import android.view.MenuItem +import android.view.ViewGroup +import android.widget.RadioButton +import android.widget.RadioGroup +import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.doOnLayout +import androidx.core.view.doOnPreDraw +import androidx.core.view.marginTop import com.android.volley.Request import com.android.volley.toolbox.StringRequest import com.android.volley.toolbox.Volley import com.google.android.material.textfield.TextInputEditText +import com.google.android.material.textfield.TextInputLayout import com.google.gson.Gson import com.google.gson.JsonParser import com.therealbluepandabear.pixapencil.R @@ -18,10 +26,7 @@ import com.therealbluepandabear.pixapencil.activities.canvas.onoptionsitemselect import com.therealbluepandabear.pixapencil.activities.canvas.selectedColorPaletteIndex import com.therealbluepandabear.pixapencil.converters.JsonConverter import com.therealbluepandabear.pixapencil.database.AppData -import com.therealbluepandabear.pixapencil.enums.BitmapCompressFormat -import com.therealbluepandabear.pixapencil.enums.FlipValue -import com.therealbluepandabear.pixapencil.enums.SnackbarDuration -import com.therealbluepandabear.pixapencil.enums.SymmetryMode +import com.therealbluepandabear.pixapencil.enums.* import com.therealbluepandabear.pixapencil.extensions.activity import com.therealbluepandabear.pixapencil.extensions.showDialog import com.therealbluepandabear.pixapencil.extensions.showSnackbarWithAction @@ -64,28 +69,74 @@ fun CanvasActivity.onMenuItemSelected(item: MenuItem): Boolean { onPixelPerfectOptionsItemSelected() } - R.id.activityCanvasTopAppMenu_export_to_png_item -> { - binding.activityCanvasPixelGridView.saveAsImage(BitmapCompressFormat.PNG, binding.activityCanvasCoordinatorLayout, projectTitle, viewModel.flipMatrix) - } + R.id.activityCanvasTopAppMenu_export_item -> { + val exportRootLayout: ConstraintLayout = + layoutInflater.inflate(R.layout.export_project_dialog_layout, findViewById(android.R.id.content),false) + as ConstraintLayout - R.id.activityCanvasTopAppMenu_export_to_jpg_item -> { - binding.activityCanvasPixelGridView.saveAsImage(BitmapCompressFormat.JPEG, binding.activityCanvasCoordinatorLayout, projectTitle, viewModel.flipMatrix) - } + exportRootLayout.post { + // We do this so that there is no default top margin, which I personally find it ugly + (exportRootLayout.layoutParams as ViewGroup.MarginLayoutParams).topMargin = 0 - R.id.activityCanvasTopAppMenu_export_to_webp_item -> { - if (Build.VERSION.SDK_INT >= 30) { - binding.activityCanvasPixelGridView.saveAsImage(BitmapCompressFormat.WEBP_LOSSLESS, binding.activityCanvasCoordinatorLayout, projectTitle, viewModel.flipMatrix) - } else { - binding.activityCanvasPixelGridView.saveAsImage(BitmapCompressFormat.WEBP, binding.activityCanvasCoordinatorLayout, projectTitle, viewModel.flipMatrix) + exportRootLayout.findViewById(R.id.exportProjectDialogLayout_fileName_textInputEditText).setText(projectTitle) } - } - R.id.activityCanvasTopAppMenu_export_to_tiff_item -> { - binding.activityCanvasPixelGridView.saveAsImage(BitmapCompressFormat.TIFF, binding.activityCanvasCoordinatorLayout, projectTitle, viewModel.flipMatrix) - } + showDialog( + "Export", + null, + getString(R.string.generic_ok), + { _, _ -> + val format: BitmapCompressFormat = + when (exportRootLayout.findViewById(R.id.exportProjectDialogLayout_radioGroup_fileType).checkedRadioButtonId) { + R.id.exportProjectDialogLayout_radioButton_PNG -> { + BitmapCompressFormat.PNG + } + + R.id.exportProjectDialogLayout_radioButton_JPG -> { + BitmapCompressFormat.JPEG + } + + R.id.exportProjectDialogLayout_radioButton_WEBP -> { + BitmapCompressFormat.WEBP + } - R.id.activityCanvasTopAppMenu_export_to_bmp_item -> { - binding.activityCanvasPixelGridView.saveAsImage(BitmapCompressFormat.BMP, binding.activityCanvasCoordinatorLayout, projectTitle, viewModel.flipMatrix) + R.id.exportProjectDialogLayout_radioButton_TIF -> { + BitmapCompressFormat.TIFF + } + + R.id.exportProjectDialogLayout_radioButton_BMP -> { + BitmapCompressFormat.BMP + } + + else -> { + BitmapCompressFormat.PNG + } + } + + val resolution: BitmapResolution = + when (exportRootLayout.findViewById(R.id.exportProjectDialogLayout_radioGroup_resolutionType).checkedRadioButtonId) { + R.id.exportProjectDialogLayout_radioButton_Raw -> { + BitmapResolution.Raw + } + + R.id.exportProjectDialogLayout_radioButton_Scaled -> { + BitmapResolution.Scaled + } + + else -> { + BitmapResolution.Raw + } + } + + binding.activityCanvasPixelGridView.saveAsImage( + format, + resolution, + binding.activityCanvasCoordinatorLayout, + "Hijk", + viewModel.flipMatrix) + }, + getString(R.string.generic_cancel), { _, _ -> }, + exportRootLayout) } R.id.appMenu_rotate_90_degrees_clockwise_subItem -> { diff --git a/app/src/main/java/com/therealbluepandabear/pixapencil/customviews/pixelgridview/PixelGridView+saveAsImage.kt b/app/src/main/java/com/therealbluepandabear/pixapencil/customviews/pixelgridview/PixelGridView+saveAsImage.kt index a1aff1d7..e7e5bedc 100644 --- a/app/src/main/java/com/therealbluepandabear/pixapencil/customviews/pixelgridview/PixelGridView+saveAsImage.kt +++ b/app/src/main/java/com/therealbluepandabear/pixapencil/customviews/pixelgridview/PixelGridView+saveAsImage.kt @@ -6,10 +6,7 @@ import android.view.View import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.drawToBitmap import com.therealbluepandabear.pixapencil.R -import com.therealbluepandabear.pixapencil.enums.BitmapCompressFormat -import com.therealbluepandabear.pixapencil.enums.FlipValue -import com.therealbluepandabear.pixapencil.enums.OutputCode -import com.therealbluepandabear.pixapencil.enums.SnackbarDuration +import com.therealbluepandabear.pixapencil.enums.* import com.therealbluepandabear.pixapencil.extensions.rotate import com.therealbluepandabear.pixapencil.extensions.showSimpleInfoDialog import com.therealbluepandabear.pixapencil.extensions.showSnackbar @@ -20,10 +17,20 @@ import java.io.File lateinit var file: File -fun PixelGridView.extendedSaveAsImage(format: BitmapCompressFormat, coordinatorLayout: CoordinatorLayout, projectTitle: String, flipMatrix: List) { +fun PixelGridView.extendedSaveAsImage( + format: BitmapCompressFormat, + resolution: BitmapResolution, + coordinatorLayout: CoordinatorLayout, + projectTitle: String, + flipMatrix: List) { val formatName = BitmapCompressFormatUtilities.getFormattedName(format) - val bitmap = this.drawToBitmap().rotate((parent as View).rotation.toInt(), flipMatrix) + val bitmap = if (resolution == BitmapResolution.Scaled) { + this.drawToBitmap().rotate((parent as View).rotation.toInt(), flipMatrix) + } else { + pixelGridViewBitmap + } + val fileHelperUtilitiesInstance = FileHelperUtilities.createInstance(context) fileHelperUtilitiesInstance.saveBitmapAsImage(bitmap, projectTitle,90, format) { outputCode, _file, exceptionMessage_1 -> diff --git a/app/src/main/java/com/therealbluepandabear/pixapencil/customviews/pixelgridview/PixelGridView.kt b/app/src/main/java/com/therealbluepandabear/pixapencil/customviews/pixelgridview/PixelGridView.kt index 03a64696..1fd6328d 100644 --- a/app/src/main/java/com/therealbluepandabear/pixapencil/customviews/pixelgridview/PixelGridView.kt +++ b/app/src/main/java/com/therealbluepandabear/pixapencil/customviews/pixelgridview/PixelGridView.kt @@ -8,6 +8,7 @@ import android.view.MotionEvent import android.view.View import androidx.coordinatorlayout.widget.CoordinatorLayout import com.therealbluepandabear.pixapencil.enums.BitmapCompressFormat +import com.therealbluepandabear.pixapencil.enums.BitmapResolution import com.therealbluepandabear.pixapencil.enums.FlipValue import com.therealbluepandabear.pixapencil.extensions.calculateMatrix import com.therealbluepandabear.pixapencil.listeners.CanvasFragmentListener @@ -116,8 +117,13 @@ class PixelGridView(context: Context, attributeSet: AttributeSet): View(context, return extendedOnTouchEvent(event) } - fun saveAsImage(format: BitmapCompressFormat, coordinatorLayout: CoordinatorLayout, projectTitle: String, flipMatrix: List) { - extendedSaveAsImage(format, coordinatorLayout, projectTitle, flipMatrix) + fun saveAsImage( + format: BitmapCompressFormat, + resolution: BitmapResolution, + coordinatorLayout: CoordinatorLayout, + projectTitle: String, + flipMatrix: List) { + extendedSaveAsImage(format, resolution, coordinatorLayout, projectTitle, flipMatrix) } /** Use this code only in onMeasure **/ diff --git a/app/src/main/java/com/therealbluepandabear/pixapencil/enums/BitmapResolution.kt b/app/src/main/java/com/therealbluepandabear/pixapencil/enums/BitmapResolution.kt new file mode 100644 index 00000000..53448355 --- /dev/null +++ b/app/src/main/java/com/therealbluepandabear/pixapencil/enums/BitmapResolution.kt @@ -0,0 +1,6 @@ +package com.therealbluepandabear.pixapencil.enums + +enum class BitmapResolution { + Raw, + Scaled +} \ No newline at end of file diff --git a/app/src/main/res/drawable/radio_button_selected.xml b/app/src/main/res/drawable/radio_button_selected.xml new file mode 100644 index 00000000..2db22415 --- /dev/null +++ b/app/src/main/res/drawable/radio_button_selected.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/radio_button_unselected.xml b/app/src/main/res/drawable/radio_button_unselected.xml new file mode 100644 index 00000000..eaf1f4f2 --- /dev/null +++ b/app/src/main/res/drawable/radio_button_unselected.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/radio_button_unselected_last.xml b/app/src/main/res/drawable/radio_button_unselected_last.xml new file mode 100644 index 00000000..b0e40f01 --- /dev/null +++ b/app/src/main/res/drawable/radio_button_unselected_last.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/radiobuttonselector.xml b/app/src/main/res/drawable/radiobuttonselector.xml new file mode 100644 index 00000000..02e80199 --- /dev/null +++ b/app/src/main/res/drawable/radiobuttonselector.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/radiobuttonselectorlast.xml b/app/src/main/res/drawable/radiobuttonselectorlast.xml new file mode 100644 index 00000000..e11827a9 --- /dev/null +++ b/app/src/main/res/drawable/radiobuttonselectorlast.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/radiobuttontextselector.xml b/app/src/main/res/drawable/radiobuttontextselector.xml new file mode 100644 index 00000000..6e17186a --- /dev/null +++ b/app/src/main/res/drawable/radiobuttontextselector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/export_project_dialog_layout.xml b/app/src/main/res/layout/export_project_dialog_layout.xml new file mode 100644 index 00000000..06b4d283 --- /dev/null +++ b/app/src/main/res/layout/export_project_dialog_layout.xml @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/activity_canvas_top_app_menu.xml b/app/src/main/res/menu/activity_canvas_top_app_menu.xml index 1411a800..ee33d408 100644 --- a/app/src/main/res/menu/activity_canvas_top_app_menu.xml +++ b/app/src/main/res/menu/activity_canvas_top_app_menu.xml @@ -3,52 +3,63 @@ - - - - - - - - - - - @@ -59,13 +70,15 @@ android:icon="@android:drawable/ic_menu_save" android:title="@string/activityCanvasTopAppMenu_flip" > - - - - - + - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file