From efe609b07683194d2c36d3cf81f9de69ec21732d Mon Sep 17 00:00:00 2001 From: Shubert Munthali Date: Thu, 1 Feb 2024 11:08:43 +0200 Subject: [PATCH] #97: Complete refactoring with best practices (#105) * Remove context from shareImage * Delete getCachedImageUri * Extract image loading from EditViewModel file * Move all state to EditingState * Clarify Serialization in ImageDefaults * Fix Share --- .scripts/ktlint.gradle | 6 +- .../java/dev/arkbuilders/arkretouch/App.kt | 4 +- .../arkretouch/{edition => di}/EditModule.kt | 6 +- .../{ => di}/common/CommonModule.kt | 5 +- .../{ => di}/common/InjectionModule.kt | 2 +- .../dispatchers/CoroutinesDispatchers.kt | 2 +- .../manager/EditManager.kt | 20 +- .../arkretouch/editing/manager/EditingMode.kt | 9 + .../{edition => editing}/model/DrawPath.kt | 2 +- .../arkretouch/editing/model/EditingState.kt | 26 ++ .../model/ImageViewParams.kt | 2 +- .../{edition => editing}/model/Operation.kt | 2 +- .../repository/FilesRepository.kt | 2 +- .../ui/blur/BlurIntensityPopup.kt | 4 +- .../ui/blur/BlurOperation.kt | 6 +- .../ui/canvas/BackgroundCanvas.kt | 4 +- .../ui/canvas/DrawCanvas.kt | 8 +- .../ui/canvas/EditCanvas.kt | 4 +- .../ui/crop/CropAspectRatiosMenu.kt | 16 +- .../ui/crop/CropOperation.kt | 6 +- .../ui/crop/CropWindow.kt | 22 +- .../ui/main/EditScreen.kt | 154 ++++++----- .../ui/main/EditViewModel.kt | 252 +++++++----------- .../arkretouch/edition/manager/EditionMode.kt | 9 - .../arkretouch/edition/model/EditionState.kt | 12 - .../arkbuilders/arkretouch/main/MainScreen.kt | 2 +- .../presentation/edit/ConfirmClearDialog.kt | 12 +- .../edit/NewImageOptionsDialog.kt | 2 +- .../edit/TransparencyChessBoard.kt | 2 +- .../presentation/edit/draw/DrawOperation.kt | 4 +- .../presentation/edit/resize/ResizeInput.kt | 2 +- .../edit/resize/ResizeOperation.kt | 4 +- .../edit/rotate/RotateOperation.kt | 4 +- .../arkretouch/storage/ImageDefaults.kt | 7 +- .../arkretouch/utils/ImageHelper.kt | 2 +- .../arkretouch/utils/ImageLoading.kt | 60 +++++ 36 files changed, 357 insertions(+), 329 deletions(-) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => di}/EditModule.kt (79%) rename app/src/main/java/dev/arkbuilders/arkretouch/{ => di}/common/CommonModule.kt (65%) rename app/src/main/java/dev/arkbuilders/arkretouch/{ => di}/common/InjectionModule.kt (67%) rename app/src/main/java/dev/arkbuilders/arkretouch/{ => di}/common/dispatchers/CoroutinesDispatchers.kt (90%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/manager/EditManager.kt (96%) create mode 100644 app/src/main/java/dev/arkbuilders/arkretouch/editing/manager/EditingMode.kt rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/model/DrawPath.kt (74%) create mode 100644 app/src/main/java/dev/arkbuilders/arkretouch/editing/model/EditingState.kt rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/model/ImageViewParams.kt (80%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/model/Operation.kt (59%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/repository/FilesRepository.kt (94%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/ui/blur/BlurIntensityPopup.kt (94%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/ui/blur/BlurOperation.kt (97%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/ui/canvas/BackgroundCanvas.kt (92%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/ui/canvas/DrawCanvas.kt (96%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/ui/canvas/EditCanvas.kt (97%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/ui/crop/CropAspectRatiosMenu.kt (94%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/ui/crop/CropOperation.kt (89%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/ui/crop/CropWindow.kt (95%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/ui/main/EditScreen.kt (88%) rename app/src/main/java/dev/arkbuilders/arkretouch/{edition => editing}/ui/main/EditViewModel.kt (70%) delete mode 100644 app/src/main/java/dev/arkbuilders/arkretouch/edition/manager/EditionMode.kt delete mode 100644 app/src/main/java/dev/arkbuilders/arkretouch/edition/model/EditionState.kt create mode 100644 app/src/main/java/dev/arkbuilders/arkretouch/utils/ImageLoading.kt diff --git a/.scripts/ktlint.gradle b/.scripts/ktlint.gradle index f580d5b..59a98f4 100644 --- a/.scripts/ktlint.gradle +++ b/.scripts/ktlint.gradle @@ -6,7 +6,7 @@ dependencies { ktlint "com.pinterest:ktlint:0.45.2" } -tasks.register('ktlintFormat', JavaExec) { +tasks.register('ktlint', JavaExec) { mainClass = "com.pinterest.ktlint.Main" classpath = configurations.ktlint args("$rootDir/**/*.kt", "!$rootDir/**/build/**") @@ -26,6 +26,6 @@ tasks.register('ktlintCheck', JavaExec) { args "src/**/*.kt", "**.kts", "!**/build/**" } -tasks.preBuild.dependsOn ktlintFormat +tasks.preBuild.dependsOn ktlintCheck -tasks.ktlintFormat.dependsOn ktlintCheck \ No newline at end of file +tasks.ktlintCheck.dependsOn ktlint \ No newline at end of file diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/App.kt b/app/src/main/java/dev/arkbuilders/arkretouch/App.kt index 54a70f0..25a4bca 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/App.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/App.kt @@ -2,8 +2,8 @@ package dev.arkbuilders.arkretouch import android.app.Application import dev.arkbuilders.arkfilepicker.folders.FoldersRepo -import dev.arkbuilders.arkretouch.common.CommonModule -import dev.arkbuilders.arkretouch.edition.EditModule +import dev.arkbuilders.arkretouch.di.EditModule +import dev.arkbuilders.arkretouch.di.common.CommonModule import org.acra.config.dialog import org.acra.config.httpSender import org.acra.data.StringFormat diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/EditModule.kt b/app/src/main/java/dev/arkbuilders/arkretouch/di/EditModule.kt similarity index 79% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/EditModule.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/di/EditModule.kt index cd138bf..8e1d2bb 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/EditModule.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/di/EditModule.kt @@ -1,7 +1,7 @@ -package dev.arkbuilders.arkretouch.edition +package dev.arkbuilders.arkretouch.di -import com.etherean.app.common.di.InjectionModule -import dev.arkbuilders.arkretouch.edition.ui.main.EditViewModel +import dev.arkbuilders.arkretouch.di.common.InjectionModule +import dev.arkbuilders.arkretouch.editing.ui.main.EditViewModel import dev.arkbuilders.arkretouch.storage.Resolution import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/common/CommonModule.kt b/app/src/main/java/dev/arkbuilders/arkretouch/di/common/CommonModule.kt similarity index 65% rename from app/src/main/java/dev/arkbuilders/arkretouch/common/CommonModule.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/di/common/CommonModule.kt index 1dc9e4f..8cb72b2 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/common/CommonModule.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/di/common/CommonModule.kt @@ -1,7 +1,6 @@ -package dev.arkbuilders.arkretouch.common +package dev.arkbuilders.arkretouch.di.common -import com.etherean.app.common.di.InjectionModule -import dev.arkbuilders.arkretouch.edition.repository.FilesRepository +import dev.arkbuilders.arkretouch.editing.repository.FilesRepository import dev.arkbuilders.arkretouch.storage.OldStorageRepository import org.koin.core.module.dsl.singleOf import org.koin.dsl.module diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/common/InjectionModule.kt b/app/src/main/java/dev/arkbuilders/arkretouch/di/common/InjectionModule.kt similarity index 67% rename from app/src/main/java/dev/arkbuilders/arkretouch/common/InjectionModule.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/di/common/InjectionModule.kt index e5635cd..ec485f6 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/common/InjectionModule.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/di/common/InjectionModule.kt @@ -1,4 +1,4 @@ -package com.etherean.app.common.di +package dev.arkbuilders.arkretouch.di.common import org.koin.core.module.Module diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/common/dispatchers/CoroutinesDispatchers.kt b/app/src/main/java/dev/arkbuilders/arkretouch/di/common/dispatchers/CoroutinesDispatchers.kt similarity index 90% rename from app/src/main/java/dev/arkbuilders/arkretouch/common/dispatchers/CoroutinesDispatchers.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/di/common/dispatchers/CoroutinesDispatchers.kt index 2f952f7..960326a 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/common/dispatchers/CoroutinesDispatchers.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/di/common/dispatchers/CoroutinesDispatchers.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.common.dispatchers +package dev.arkbuilders.arkretouch.di.common.dispatchers import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/manager/EditManager.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/manager/EditManager.kt similarity index 96% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/manager/EditManager.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/manager/EditManager.kt index 34bb199..5537212 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/manager/EditManager.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/manager/EditManager.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.manager +package dev.arkbuilders.arkretouch.editing.manager import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -14,14 +14,14 @@ import androidx.compose.ui.graphics.PaintingStyle import androidx.compose.ui.graphics.Path import androidx.compose.ui.unit.IntSize import android.graphics.Matrix -import dev.arkbuilders.arkretouch.edition.model.DrawPath -import dev.arkbuilders.arkretouch.edition.model.ImageViewParams -import dev.arkbuilders.arkretouch.edition.model.Operation -import dev.arkbuilders.arkretouch.edition.ui.blur.BlurOperation -import dev.arkbuilders.arkretouch.edition.ui.crop.CropOperation -import dev.arkbuilders.arkretouch.edition.ui.crop.CropWindow -import dev.arkbuilders.arkretouch.edition.ui.main.fitBackground -import dev.arkbuilders.arkretouch.edition.ui.main.fitImage +import dev.arkbuilders.arkretouch.editing.model.DrawPath +import dev.arkbuilders.arkretouch.editing.model.ImageViewParams +import dev.arkbuilders.arkretouch.editing.model.Operation +import dev.arkbuilders.arkretouch.editing.ui.blur.BlurOperation +import dev.arkbuilders.arkretouch.editing.ui.crop.CropOperation +import dev.arkbuilders.arkretouch.editing.ui.crop.CropWindow +import dev.arkbuilders.arkretouch.editing.ui.main.fitBackground +import dev.arkbuilders.arkretouch.editing.ui.main.fitImage import dev.arkbuilders.arkretouch.presentation.edit.draw.DrawOperation import dev.arkbuilders.arkretouch.presentation.edit.resize.ResizeOperation import dev.arkbuilders.arkretouch.presentation.edit.rotate.RotateOperation @@ -168,7 +168,7 @@ class EditManager { private val _isCropMode = mutableStateOf(false) val isCropMode = _isCropMode - var editionMode: EditionMode by mutableStateOf(EditionMode.IDLE) + var editingMode: EditingMode by mutableStateOf(EditingMode.IDLE) val cropStack = Stack() val redoCropStack = Stack() diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/editing/manager/EditingMode.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/manager/EditingMode.kt new file mode 100644 index 0000000..01db834 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/manager/EditingMode.kt @@ -0,0 +1,9 @@ +package dev.arkbuilders.arkretouch.editing.manager + +enum class EditingMode { + IDLE, + CROP, + RESIZE, + ROTATE, + ZOOM +} \ No newline at end of file diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/model/DrawPath.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/model/DrawPath.kt similarity index 74% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/model/DrawPath.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/model/DrawPath.kt index 4bb03e8..d3835ac 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/model/DrawPath.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/model/DrawPath.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.model +package dev.arkbuilders.arkretouch.editing.model import androidx.compose.ui.graphics.Paint import androidx.compose.ui.graphics.Path diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/editing/model/EditingState.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/model/EditingState.kt new file mode 100644 index 0000000..e168b01 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/model/EditingState.kt @@ -0,0 +1,26 @@ +package dev.arkbuilders.arkretouch.editing.model + +import androidx.compose.ui.graphics.Color + +data class EditingState( + val strokeSliderExpanded: Boolean = false, + val strokeWidth: Float = 5f, + val menusVisible: Boolean = true, + val showSavePathDialog: Boolean = false, + val showExitDialog: Boolean = false, + val showMoreOptionsPopup: Boolean = false, + val imageSaved: Boolean = false, + val isSavingImage: Boolean = false, + val showEyeDropperHint: Boolean = false, + val showConfirmClearDialog: Boolean = false, + val isLoaded: Boolean = false, + val exitConfirmed: Boolean = false, + val bottomButtonsScrollIsAtStart: Boolean = false, + val bottomButtonsScrollIsAtEnd: Boolean = false, + val usedColors: List = listOf() +) { + + companion object { + val DEFAULT = EditingState() + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/model/ImageViewParams.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/model/ImageViewParams.kt similarity index 80% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/model/ImageViewParams.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/model/ImageViewParams.kt index 02a9ca8..84f676b 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/model/ImageViewParams.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/model/ImageViewParams.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.model +package dev.arkbuilders.arkretouch.editing.model import androidx.compose.ui.unit.IntSize import dev.arkbuilders.arkretouch.presentation.edit.resize.ResizeOperation diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/model/Operation.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/model/Operation.kt similarity index 59% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/model/Operation.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/model/Operation.kt index 1b17994..76f478b 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/model/Operation.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/model/Operation.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.model +package dev.arkbuilders.arkretouch.editing.model interface Operation { fun apply() diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/repository/FilesRepository.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/repository/FilesRepository.kt similarity index 94% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/repository/FilesRepository.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/repository/FilesRepository.kt index 974cb0d..f3224ed 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/repository/FilesRepository.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/repository/FilesRepository.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.repository +package dev.arkbuilders.arkretouch.editing.repository import androidx.core.content.FileProvider import android.content.Context diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/blur/BlurIntensityPopup.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/blur/BlurIntensityPopup.kt similarity index 94% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/blur/BlurIntensityPopup.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/blur/BlurIntensityPopup.kt index c185504..d86ab25 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/blur/BlurIntensityPopup.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/blur/BlurIntensityPopup.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.ui.blur +package dev.arkbuilders.arkretouch.editing.ui.blur import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth @@ -12,7 +12,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import dev.arkbuilders.arkretouch.R -import dev.arkbuilders.arkretouch.edition.manager.EditManager +import dev.arkbuilders.arkretouch.editing.manager.EditManager @Composable fun BlurIntensityPopup( diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/blur/BlurOperation.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/blur/BlurOperation.kt similarity index 97% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/blur/BlurOperation.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/blur/BlurOperation.kt index a1f188b..1abd2a8 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/blur/BlurOperation.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/blur/BlurOperation.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.ui.blur +package dev.arkbuilders.arkretouch.editing.ui.blur import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.geometry.Offset @@ -12,8 +12,8 @@ import androidx.compose.ui.unit.IntOffset import android.content.Context import android.graphics.Bitmap import com.hoko.blur.processor.HokoBlurBuild -import dev.arkbuilders.arkretouch.edition.manager.EditManager -import dev.arkbuilders.arkretouch.edition.model.Operation +import dev.arkbuilders.arkretouch.editing.manager.EditManager +import dev.arkbuilders.arkretouch.editing.model.Operation import java.util.Stack class BlurOperation( diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/canvas/BackgroundCanvas.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/canvas/BackgroundCanvas.kt similarity index 92% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/canvas/BackgroundCanvas.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/canvas/BackgroundCanvas.kt index 3c7c761..98e4492 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/canvas/BackgroundCanvas.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/canvas/BackgroundCanvas.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.ui.canvas +package dev.arkbuilders.arkretouch.editing.ui.canvas import androidx.compose.foundation.Canvas import androidx.compose.runtime.Composable @@ -10,7 +10,7 @@ import androidx.compose.ui.graphics.asAndroidBitmap import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.graphics.nativeCanvas import androidx.compose.ui.unit.toSize -import dev.arkbuilders.arkretouch.edition.manager.EditManager +import dev.arkbuilders.arkretouch.editing.manager.EditManager @Composable fun BackgroundCanvas(modifier: Modifier, editManager: EditManager) { diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/canvas/DrawCanvas.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/canvas/DrawCanvas.kt similarity index 96% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/canvas/DrawCanvas.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/canvas/DrawCanvas.kt index 77edb26..646b442 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/canvas/DrawCanvas.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/canvas/DrawCanvas.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.ui.canvas +package dev.arkbuilders.arkretouch.editing.ui.canvas import androidx.compose.foundation.Canvas import androidx.compose.foundation.layout.fillMaxSize @@ -19,9 +19,9 @@ import androidx.compose.ui.unit.toSize import android.graphics.Matrix import android.graphics.PointF import android.view.MotionEvent -import dev.arkbuilders.arkretouch.edition.ui.crop.CropWindow.Companion.computeDeltaX -import dev.arkbuilders.arkretouch.edition.ui.crop.CropWindow.Companion.computeDeltaY -import dev.arkbuilders.arkretouch.edition.ui.main.EditViewModel +import dev.arkbuilders.arkretouch.editing.ui.crop.CropWindow.Companion.computeDeltaX +import dev.arkbuilders.arkretouch.editing.ui.crop.CropWindow.Companion.computeDeltaY +import dev.arkbuilders.arkretouch.editing.ui.main.EditViewModel @OptIn(ExperimentalComposeUiApi::class) @Composable diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/canvas/EditCanvas.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/canvas/EditCanvas.kt similarity index 97% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/canvas/EditCanvas.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/canvas/EditCanvas.kt index 715b624..0097906 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/canvas/EditCanvas.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/canvas/EditCanvas.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.ui.canvas +package dev.arkbuilders.arkretouch.editing.ui.canvas import androidx.compose.foundation.Canvas import androidx.compose.foundation.gestures.awaitFirstDown @@ -18,7 +18,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.input.pointer.pointerInput -import dev.arkbuilders.arkretouch.edition.ui.main.EditViewModel +import dev.arkbuilders.arkretouch.editing.ui.main.EditViewModel import dev.arkbuilders.arkretouch.picker.toDp import dev.arkbuilders.arkretouch.presentation.edit.TransparencyChessBoardCanvas import dev.arkbuilders.arkretouch.utils.calculateRotationFromOneFingerGesture diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/crop/CropAspectRatiosMenu.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/crop/CropAspectRatiosMenu.kt similarity index 94% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/crop/CropAspectRatiosMenu.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/crop/CropAspectRatiosMenu.kt index d55d295..8b16d2e 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/crop/CropAspectRatiosMenu.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/crop/CropAspectRatiosMenu.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.ui.crop +package dev.arkbuilders.arkretouch.editing.ui.crop import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -26,13 +26,13 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.unit.dp import dev.arkbuilders.arkretouch.R -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.aspectRatios -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.isChanged -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.isCropFree -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.isCropSquare -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.isCrop_2_3 -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.isCrop_4_5 -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.isCrop_9_16 +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.aspectRatios +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.isChanged +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.isCropFree +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.isCropSquare +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.isCrop_2_3 +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.isCrop_4_5 +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.isCrop_9_16 @Composable fun CropAspectRatiosMenu( diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/crop/CropOperation.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/crop/CropOperation.kt similarity index 89% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/crop/CropOperation.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/crop/CropOperation.kt index 5a2b89d..6d0b6fb 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/crop/CropOperation.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/crop/CropOperation.kt @@ -1,8 +1,8 @@ -package dev.arkbuilders.arkretouch.edition.ui.crop +package dev.arkbuilders.arkretouch.editing.ui.crop import androidx.compose.ui.graphics.asImageBitmap -import dev.arkbuilders.arkretouch.edition.manager.EditManager -import dev.arkbuilders.arkretouch.edition.model.Operation +import dev.arkbuilders.arkretouch.editing.manager.EditManager +import dev.arkbuilders.arkretouch.editing.model.Operation import dev.arkbuilders.arkretouch.utils.crop class CropOperation( diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/crop/CropWindow.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/crop/CropWindow.kt similarity index 95% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/crop/CropWindow.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/crop/CropWindow.kt index fb6acf6..1d22d65 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/crop/CropWindow.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/crop/CropWindow.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.ui.crop +package dev.arkbuilders.arkretouch.editing.ui.crop import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.geometry.Offset @@ -9,16 +9,16 @@ import androidx.compose.ui.graphics.Paint import androidx.compose.ui.graphics.PaintingStyle import androidx.compose.ui.unit.IntSize import android.graphics.Bitmap -import dev.arkbuilders.arkretouch.edition.manager.EditManager -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.CROP_2_3 -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.CROP_4_5 -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.CROP_9_16 -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.CROP_SQUARE -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.isCropFree -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.isCropSquare -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.isCrop_2_3 -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.isCrop_4_5 -import dev.arkbuilders.arkretouch.edition.ui.crop.AspectRatio.isCrop_9_16 +import dev.arkbuilders.arkretouch.editing.manager.EditManager +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.CROP_2_3 +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.CROP_4_5 +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.CROP_9_16 +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.CROP_SQUARE +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.isCropFree +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.isCropSquare +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.isCrop_2_3 +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.isCrop_4_5 +import dev.arkbuilders.arkretouch.editing.ui.crop.AspectRatio.isCrop_9_16 import dev.arkbuilders.arkretouch.presentation.edit.resize.ResizeOperation import timber.log.Timber diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/main/EditScreen.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/main/EditScreen.kt similarity index 88% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/main/EditScreen.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/main/EditScreen.kt index 3324d2b..f7e9ea5 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/main/EditScreen.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/main/EditScreen.kt @@ -1,6 +1,6 @@ @file:OptIn(ExperimentalComposeUiApi::class) -package dev.arkbuilders.arkretouch.edition.ui.main +package dev.arkbuilders.arkretouch.editing.ui.main import androidx.activity.compose.BackHandler import androidx.compose.animation.AnimatedVisibility @@ -58,15 +58,17 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.core.content.FileProvider import androidx.fragment.app.FragmentManager import android.content.Context +import android.content.Intent import android.view.MotionEvent import android.widget.Toast import dev.arkbuilders.arkretouch.R -import dev.arkbuilders.arkretouch.edition.model.EditionState -import dev.arkbuilders.arkretouch.edition.ui.blur.BlurIntensityPopup -import dev.arkbuilders.arkretouch.edition.ui.canvas.EditCanvasScreen -import dev.arkbuilders.arkretouch.edition.ui.crop.CropAspectRatiosMenu +import dev.arkbuilders.arkretouch.editing.model.EditingState +import dev.arkbuilders.arkretouch.editing.ui.blur.BlurIntensityPopup +import dev.arkbuilders.arkretouch.editing.ui.canvas.EditCanvasScreen +import dev.arkbuilders.arkretouch.editing.ui.crop.CropAspectRatiosMenu import dev.arkbuilders.arkretouch.picker.toPx import dev.arkbuilders.arkretouch.presentation.edit.ColorPickerDialog import dev.arkbuilders.arkretouch.presentation.edit.ConfirmClearDialog @@ -80,6 +82,8 @@ import dev.arkbuilders.arkretouch.presentation.edit.resize.delayHidingHint import dev.arkbuilders.arkretouch.storage.Resolution import dev.arkbuilders.arkretouch.ui.theme.Gray import dev.arkbuilders.arkretouch.utils.getActivity +import dev.arkbuilders.arkretouch.utils.loadImageWithPath +import dev.arkbuilders.arkretouch.utils.loadImageWithUri import dev.arkbuilders.arkretouch.utils.permission.isWritePermissionGranted import dev.arkbuilders.arkretouch.utils.permission.requestWritePermissions import org.koin.androidx.compose.koinViewModel @@ -100,12 +104,12 @@ fun EditScreen( parametersOf(primaryColor, launchedFromIntent, imagePath, imageUri, maxResolution) } - val editionState = viewModel.editionState + val editingState = viewModel.editingState val context = LocalContext.current val showDefaultsDialog = remember { mutableStateOf( - imagePath == null && imageUri == null && !viewModel.isLoaded + imagePath == null && imageUri == null && !editingState.isLoaded ) } @@ -132,7 +136,7 @@ fun EditScreen( viewModel = viewModel, navigateBack = { navigateBack() - viewModel.isLoaded = false + viewModel.setIsLoaded(false) }, launchedFromIntent = launchedFromIntent, ) @@ -159,14 +163,14 @@ fun EditScreen( editManager.undo() return@BackHandler } - if (viewModel.exitConfirmed) { + if (viewModel.editingState.exitConfirmed) { if (launchedFromIntent) context.getActivity()?.finish() else navigateBack() return@BackHandler } - if (!viewModel.exitConfirmed) { + if (!viewModel.editingState.exitConfirmed) { Toast.makeText(context, "Tap back again to exit", Toast.LENGTH_SHORT) .show() viewModel.confirmExit() @@ -184,24 +188,24 @@ fun EditScreen( fragmentManager, viewModel, launchedFromIntent, - editionState, + editingState, navigateBack ) - if (viewModel.isSavingImage) { + if (viewModel.editingState.isSavingImage) { SaveProgress() } - if (viewModel.showEyeDropperHint) { + if (viewModel.editingState.showEyeDropperHint) { Box( Modifier.fillMaxSize(), contentAlignment = Alignment.TopCenter ) { Hint(stringResource(R.string.pick_color)) { delayHidingHint(it) { - viewModel.showEyeDropperHint = false + viewModel.showEyeDropperHint(false) } - viewModel.showEyeDropperHint + viewModel.editingState.showEyeDropperHint } } } @@ -213,7 +217,7 @@ private fun Menus( fragmentManager: FragmentManager, viewModel: EditViewModel, launchedFromIntent: Boolean, - editionState: EditionState, + editingState: EditingState, navigateBack: () -> Unit, ) { Box( @@ -275,7 +279,7 @@ private fun Menus( ) } - EditMenuContainer(viewModel, editionState, navigateBack) + EditMenuContainer(viewModel, editingState, navigateBack) } } } @@ -306,9 +310,9 @@ private fun DrawContainer( } .onSizeChanged { newSize -> if (newSize == IntSize.Zero) return@onSizeChanged - if (viewModel.showSavePathDialog) return@onSizeChanged + if (viewModel.editingState.showSavePathDialog) return@onSizeChanged viewModel.editManager.drawAreaSize.value = newSize - if (viewModel.isLoaded) { + if (viewModel.editingState.isLoaded) { viewModel.editManager.apply { when (true) { isCropMode.value -> { @@ -351,7 +355,10 @@ private fun DrawContainer( } } } - viewModel.loadImage(context = context) + viewModel.loadImage( + loadByPath = { path, editManager -> loadImageWithPath(context, path, editManager) }, + loadByUri = { uri, editManager -> loadImageWithUri(context, uri, editManager) } + ) }, contentAlignment = Alignment.Center ) { @@ -369,40 +376,55 @@ private fun BoxScope.TopMenu( ) { val context = LocalContext.current - if (viewModel.showSavePathDialog) + if (viewModel.editingState.showSavePathDialog) SavePathDialog( initialImagePath = imagePath, fragmentManager = fragmentManager, - onDismissClick = { viewModel.showSavePathDialog = false }, + onDismissClick = { viewModel.showSavePathDialog(false) }, onPositiveClick = { savePath -> viewModel.saveImage(savePath) - viewModel.showSavePathDialog = false + viewModel.showSavePathDialog(false) } ) - if (viewModel.showMoreOptionsPopup) + if (viewModel.editingState.showMoreOptionsPopup) MoreOptionsPopup( onDismissClick = { - viewModel.showMoreOptionsPopup = false + viewModel.showMoreOptions(false) }, onShareClick = { - viewModel.shareImage(context) - viewModel.showMoreOptionsPopup = false + viewModel.shareImage( + context.cacheDir.toPath(), + provideUri = { file -> + FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file) + }, + startShare = { intent -> + context.apply { + startActivity( + Intent.createChooser( + intent, + getString(R.string.share) + ) + ) + } + } + ) + viewModel.showMoreOptions(false) }, onSaveClick = { if (!context.isWritePermissionGranted()) { context.requestWritePermissions() return@MoreOptionsPopup } - viewModel.showSavePathDialog = true + viewModel.showSavePathDialog(true) }, onClearEdits = { - viewModel.showConfirmClearDialog.value = true - viewModel.showMoreOptionsPopup = false + viewModel.showConfirmClearDialog(true) + viewModel.showMoreOptions(false) } ) ConfirmClearDialog( - viewModel.showConfirmClearDialog, + viewModel.editingState.showConfirmClearDialog, onConfirm = { viewModel.editManager.apply { if ( @@ -412,11 +434,14 @@ private fun BoxScope.TopMenu( !isEyeDropperMode.value ) clearEdits() } + }, + onDismiss = { + viewModel.showConfirmClearDialog(false) } ) if ( - !viewModel.menusVisible && + !viewModel.editingState.menusVisible && !viewModel.editManager.isRotateMode.value && !viewModel.editManager.isResizeMode.value && !viewModel.editManager.isCropMode.value && @@ -458,7 +483,7 @@ private fun BoxScope.TopMenu( navigateBack() } } else { - viewModel.showExitDialog = true + viewModel.showExitDialog(true) } } }, @@ -486,7 +511,7 @@ private fun BoxScope.TopMenu( return@clickable } } - viewModel.showMoreOptionsPopup = true + viewModel.showMoreOptions(true) }, imageVector = if ( viewModel.editManager.isCropMode.value || @@ -506,10 +531,10 @@ private fun BoxScope.TopMenu( private fun StrokeWidthPopup( modifier: Modifier, viewModel: EditViewModel, - editionState: EditionState + editionState: EditingState ) { val editManager = viewModel.editManager - editManager.setPaintStrokeWidth(viewModel.strokeWidth.dp.toPx()) + editManager.setPaintStrokeWidth(viewModel.editingState.strokeWidth.dp.toPx()) if (editionState.strokeSliderExpanded) { Column( modifier = modifier @@ -529,7 +554,7 @@ private fun StrokeWidthPopup( ) .align(Alignment.Center) .fillMaxWidth() - .height(viewModel.strokeWidth.dp) + .height(viewModel.editingState.strokeWidth.dp) .clip(RoundedCornerShape(30)) .background(editManager.paintColor.value) ) @@ -538,9 +563,9 @@ private fun StrokeWidthPopup( Slider( modifier = Modifier .fillMaxWidth(), - value = viewModel.strokeWidth, + value = viewModel.editingState.strokeWidth, onValueChange = { - viewModel.strokeWidth = it + viewModel.setStrokeWidth(it) }, valueRange = 0.5f..50f, ) @@ -551,7 +576,7 @@ private fun StrokeWidthPopup( @Composable private fun EditMenuContainer( viewModel: EditViewModel, - editionState: EditionState, + editingState: EditingState, navigateBack: () -> Unit ) { Column( @@ -575,26 +600,26 @@ private fun EditMenuContainer( .clip(RoundedCornerShape(topStartPercent = 30, topEndPercent = 30)) .background(Gray) .clickable { - viewModel.menusVisible = !viewModel.menusVisible + viewModel.toggleMenus() }, contentAlignment = Alignment.Center ) { Icon( - if (viewModel.menusVisible) Icons.Filled.KeyboardArrowDown + if (viewModel.editingState.menusVisible) Icons.Filled.KeyboardArrowDown else Icons.Filled.KeyboardArrowUp, contentDescription = "", modifier = Modifier.size(32.dp), ) } AnimatedVisibility( - visible = viewModel.menusVisible, + visible = viewModel.editingState.menusVisible, enter = expandVertically(expandFrom = Alignment.Bottom), exit = shrinkVertically(shrinkTowards = Alignment.Top) ) { - EditMenuContent(viewModel, editionState) + EditMenuContent(viewModel, editingState) EditMenuFlowHint( - viewModel.bottomButtonsScrollIsAtStart.value, - viewModel.bottomButtonsScrollIsAtEnd.value + viewModel.editingState.bottomButtonsScrollIsAtStart, + viewModel.editingState.bottomButtonsScrollIsAtEnd ) } } @@ -603,7 +628,7 @@ private fun EditMenuContainer( @Composable private fun EditMenuContent( viewModel: EditViewModel, - editionState: EditionState + editingState: EditingState ) { val colorDialogExpanded = remember { mutableStateOf(false) } val scrollState = rememberScrollState() @@ -613,7 +638,7 @@ private fun EditMenuContent( .fillMaxWidth() .background(Gray) ) { - StrokeWidthPopup(Modifier, viewModel, editionState) + StrokeWidthPopup(Modifier, viewModel, editingState) BlurIntensityPopup(editManager) @@ -705,7 +730,7 @@ private fun EditMenuContent( ColorPickerDialog( isVisible = colorDialogExpanded, initialColor = editManager.paintColor.value, - usedColors = viewModel.usedColors, + usedColors = viewModel.editingState.usedColors, enableEyeDropper = true, onToggleEyeDropper = { viewModel.toggleEyeDropper() @@ -728,7 +753,7 @@ private fun EditMenuContent( !editManager.isEyeDropperMode.value && !editManager.isBlurMode.value ) - viewModel.setStrokeSliderExpanded(isExpanded = !editionState.strokeSliderExpanded) + viewModel.setStrokeSliderExpanded(isExpanded = !editingState.strokeSliderExpanded) }, imageVector = ImageVector.vectorResource(R.drawable.ic_line_weight), @@ -831,8 +856,7 @@ private fun EditMenuContent( !isBlurMode.value ) { toggleCropMode() - viewModel.menusVisible = - !editManager.isCropMode.value + viewModel.showMenus(!editManager.isCropMode.value) if (isCropMode.value) { val bitmap = viewModel.getEditedImage() setBackgroundImage2() @@ -873,8 +897,7 @@ private fun EditMenuContent( toggleRotateMode() if (isRotateMode.value) { setBackgroundImage2() - viewModel.menusVisible = - !editManager.isRotateMode.value + viewModel.showMenus(!editManager.isRotateMode.value) scaleToFitOnEdit() return@clickable } @@ -907,7 +930,7 @@ private fun EditMenuContent( ) toggleResizeMode() else return@clickable - viewModel.menusVisible = !isResizeMode.value + viewModel.showMenus(!isResizeMode.value) if (isResizeMode.value) { setBackgroundImage2() val imgBitmap = viewModel.getEditedImage() @@ -942,7 +965,7 @@ private fun EditMenuContent( !isEyeDropperMode.value && !isResizeMode.value && !isEraseMode.value && - !editionState.strokeSliderExpanded + !editingState.strokeSliderExpanded ) toggleBlurMode() if (isBlurMode.value) { setBackgroundImage2() @@ -964,9 +987,10 @@ private fun EditMenuContent( ) } } - viewModel.bottomButtonsScrollIsAtStart.value = scrollState.value == 0 - viewModel.bottomButtonsScrollIsAtEnd.value = + viewModel.setBottomButtonsScrollIsAtStart(scrollState.value == 0) + viewModel.setBottomButtonsScrollIsAtEnd( scrollState.value == scrollState.maxValue + ) } @Composable @@ -1015,8 +1039,8 @@ private fun HandleImageSavedEffect( navigateBack: () -> Unit, ) { val context = LocalContext.current - LaunchedEffect(viewModel.imageSaved) { - if (!viewModel.imageSaved) + LaunchedEffect(viewModel.editingState.imageSaved) { + if (!viewModel.editingState.imageSaved) return@LaunchedEffect if (launchedFromIntent) context.getActivity()?.finish() @@ -1031,13 +1055,13 @@ private fun ExitDialog( navigateBack: () -> Unit, launchedFromIntent: Boolean ) { - if (!viewModel.showExitDialog) return + if (!viewModel.editingState.showExitDialog) return val context = LocalContext.current AlertDialog( onDismissRequest = { - viewModel.showExitDialog = false + viewModel.showExitDialog(false) }, title = { Text( @@ -1049,8 +1073,8 @@ private fun ExitDialog( confirmButton = { Button( onClick = { - viewModel.showExitDialog = false - viewModel.showSavePathDialog = true + viewModel.showExitDialog(false) + viewModel.showSavePathDialog(true) } ) { Text("Save") @@ -1059,7 +1083,7 @@ private fun ExitDialog( dismissButton = { TextButton( onClick = { - viewModel.showExitDialog = false + viewModel.showExitDialog(false) if (launchedFromIntent) { context.getActivity()?.finish() } else { diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/main/EditViewModel.kt b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/main/EditViewModel.kt similarity index 70% rename from app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/main/EditViewModel.kt rename to app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/main/EditViewModel.kt index 3ccef50..79b67e2 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/ui/main/EditViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/editing/ui/main/EditViewModel.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.arkretouch.edition.ui.main +package dev.arkbuilders.arkretouch.editing.ui.main import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -15,32 +15,24 @@ import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.nativeCanvas import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.toSize -import androidx.core.content.FileProvider -import androidx.core.net.toUri import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import android.content.Context import android.content.Intent import android.graphics.Bitmap import android.graphics.Matrix -import android.graphics.drawable.Drawable import android.net.Uri import android.view.MotionEvent -import com.bumptech.glide.Glide -import com.bumptech.glide.RequestBuilder -import com.bumptech.glide.load.engine.DiskCacheStrategy -import com.bumptech.glide.request.target.CustomTarget -import com.bumptech.glide.request.transition.Transition -import dev.arkbuilders.arkretouch.R -import dev.arkbuilders.arkretouch.edition.manager.EditManager -import dev.arkbuilders.arkretouch.edition.model.EditionState -import dev.arkbuilders.arkretouch.edition.model.ImageViewParams +import dev.arkbuilders.arkretouch.editing.manager.EditManager +import dev.arkbuilders.arkretouch.editing.model.EditingState +import dev.arkbuilders.arkretouch.editing.model.ImageViewParams import dev.arkbuilders.arkretouch.presentation.edit.resize.ResizeOperation import dev.arkbuilders.arkretouch.storage.OldStorageRepository import dev.arkbuilders.arkretouch.storage.Resolution import timber.log.Timber import java.io.File import java.nio.file.Path +import kotlin.io.path.createTempDirectory +import kotlin.io.path.createTempFile import kotlin.io.path.outputStream import kotlin.system.measureTimeMillis import kotlinx.coroutines.Dispatchers @@ -56,29 +48,12 @@ class EditViewModel( private val prefs: OldStorageRepository ) : ViewModel() { - var editionState: EditionState by mutableStateOf(EditionState.DEFAULT) - - val editManager = EditManager() + private val _usedColors = mutableListOf() - // TODO: Move each field into [EditionState] in next PRs - var menusVisible by mutableStateOf(true) - var strokeWidth by mutableStateOf(5f) - var showSavePathDialog by mutableStateOf(false) - val showOverwriteCheckbox = mutableStateOf(imagePath != null) - var showExitDialog by mutableStateOf(false) - var showMoreOptionsPopup by mutableStateOf(false) - var imageSaved by mutableStateOf(false) - var isSavingImage by mutableStateOf(false) - var showEyeDropperHint by mutableStateOf(false) - val showConfirmClearDialog = mutableStateOf(false) - var isLoaded by mutableStateOf(false) - var exitConfirmed = false - private set - val bottomButtonsScrollIsAtStart = mutableStateOf(true) - val bottomButtonsScrollIsAtEnd = mutableStateOf(false) + private var _editingState: EditingState by mutableStateOf(EditingState.DEFAULT.copy(usedColors = _usedColors)) + val editingState: EditingState get() = _editingState - private val _usedColors = mutableListOf() - val usedColors: List = _usedColors + val editManager = EditManager() init { if (imageUri == null && imagePath == null) { @@ -92,40 +67,61 @@ class EditViewModel( loadDefaultPaintColor() } - private fun loadDefaultPaintColor() { - viewModelScope.launch { - _usedColors.addAll(prefs.readUsedColors()) + fun toggleMenus() { + _editingState = editingState.copy(menusVisible = !editingState.menusVisible) + } - val color = if (_usedColors.isNotEmpty()) { - _usedColors.last() - } else { - Color(primaryColor.toULong()).also { _usedColors.add(it) } - } + fun showMenus(bool: Boolean) { + _editingState = editingState.copy(menusVisible = bool) + } - editManager.setPaintColor(color) - } + fun setStrokeWidth(width: Float) { + _editingState = editingState.copy(strokeWidth = width) + } + + fun showSavePathDialog(bool: Boolean) { + _editingState = editingState.copy(showSavePathDialog = bool) + } + + fun showExitDialog(bool: Boolean) { + _editingState = editingState.copy(showExitDialog = bool) + } + + fun showMoreOptions(bool: Boolean) { + _editingState = editingState.copy(showMoreOptionsPopup = bool) + } + + fun showEyeDropperHint(bool: Boolean) { + _editingState = editingState.copy(showEyeDropperHint = bool) + } + + fun showConfirmClearDialog(bool: Boolean) { + _editingState = editingState.copy(showConfirmClearDialog = bool) + } + + fun setIsLoaded(bool: Boolean) { + _editingState = editingState.copy(isLoaded = bool) + } + + fun setBottomButtonsScrollIsAtStart(bool: Boolean) { + _editingState = editingState.copy(bottomButtonsScrollIsAtStart = bool) + } + fun setBottomButtonsScrollIsAtEnd(bool: Boolean) { + _editingState = editingState.copy(bottomButtonsScrollIsAtEnd = bool) } fun setStrokeSliderExpanded(isExpanded: Boolean) { - editionState = editionState.copy(strokeSliderExpanded = isExpanded) + _editingState = editingState.copy(strokeSliderExpanded = isExpanded) } - fun loadImage(context: Context) { - isLoaded = true + fun loadImage(loadByPath: (Path, EditManager) -> Unit, loadByUri: (String, EditManager) -> Unit) { + _editingState = editingState.copy(isLoaded = true) imagePath?.let { - loadImageWithPath( - context, - imagePath, - editManager - ) + loadByPath(it, editManager) return } imageUri?.let { - loadImageWithUri( - context, - imageUri, - editManager - ) + loadByUri(it, editManager) return } editManager.scaleToFit() @@ -133,60 +129,28 @@ class EditViewModel( fun saveImage(savePath: Path) = viewModelScope.launch(Dispatchers.IO) { - isSavingImage = true + _editingState = editingState.copy(isSavingImage = true) val combinedBitmap = getEditedImage() savePath.outputStream().use { out -> combinedBitmap.asAndroidBitmap() .compress(Bitmap.CompressFormat.PNG, 100, out) } - imageSaved = true - isSavingImage = false + _editingState = editingState.copy(imageSaved = true, isSavingImage = false) } - // FIXME: Remove context or this function from here - fun shareImage(context: Context) = + fun shareImage(root: Path, provideUri: (File) -> Uri, startShare: (Intent) -> Unit) { viewModelScope.launch(Dispatchers.IO) { val intent = Intent(Intent.ACTION_SEND) - val uri = getCachedImageUri(context) - intent.type = "image/*" - intent.putExtra(Intent.EXTRA_STREAM, uri) - context.apply { - startActivity( - Intent.createChooser( - intent, - getString(R.string.share) - ) - ) - } - } - - // FIXME: Remove context or this function from here - private fun getCachedImageUri( - context: Context, - bitmap: Bitmap? = null, - name: String = "" - ): Uri { - var uri: Uri? = null - val imageCacheFolder = File(context.cacheDir, "images") - val imgBitmap = bitmap ?: getEditedImage().asAndroidBitmap() - try { - imageCacheFolder.mkdirs() - val file = File(imageCacheFolder, "image$name.png") - file.outputStream().use { out -> - imgBitmap - .compress(Bitmap.CompressFormat.PNG, 100, out) + val tempPath = createTempFile(createTempDirectory(root.resolve("images/")), suffix = ".png") + val bitmap = getEditedImage().asAndroidBitmap() + tempPath.outputStream().use { out -> + bitmap.compress(Bitmap.CompressFormat.PNG, 100, out) } - Timber.tag("Cached image path").d(file.path.toString()) - uri = FileProvider.getUriForFile( - context, - "${context.packageName}.fileprovider", - file - ) - } catch (e: Exception) { - e.printStackTrace() + intent.type = "image/*" + intent.putExtra(Intent.EXTRA_STREAM, provideUri(tempPath.toFile())) + startShare(intent) } - return uri!! } fun trackColor(color: Color) { @@ -199,7 +163,7 @@ class EditViewModel( } viewModelScope.launch { - prefs.persistUsedColors(usedColors) + prefs.persistUsedColors(editingState.usedColors) } } @@ -208,7 +172,7 @@ class EditViewModel( } fun cancelEyeDropper() { - editManager.setPaintColor(usedColors.last()) + editManager.setPaintColor(editingState.usedColors.last()) } fun applyEyeDropper(action: Int, x: Int, y: Int) { @@ -219,14 +183,14 @@ class EditViewModel( val pixel = bitmap.getPixel(imageX, imageY) val color = Color(pixel) if (color == Color.Transparent) { - showEyeDropperHint = true + showEyeDropperHint(true) return } when (action) { MotionEvent.ACTION_DOWN, MotionEvent.ACTION_UP -> { trackColor(color) toggleEyeDropper() - menusVisible = true + showMenus(true) } } editManager.setPaintColor(color) @@ -363,16 +327,14 @@ class EditViewModel( } fun confirmExit() = viewModelScope.launch { - exitConfirmed = true - isLoaded = false + _editingState = editingState.copy(exitConfirmed = true, isLoaded = false) delay(2_000) - exitConfirmed = false - isLoaded = true + _editingState = editingState.copy(exitConfirmed = false, isLoaded = true) } fun applyOperation() { editManager.applyOperation() - menusVisible = true + _editingState = editingState.copy(menusVisible = true) } fun cancelOperation() { @@ -380,27 +342,27 @@ class EditViewModel( if (isRotateMode.value) { toggleRotateMode() cancelRotateMode() - menusVisible = true + _editingState = editingState.copy(menusVisible = true) } if (isCropMode.value) { toggleCropMode() cancelCropMode() - menusVisible = true + _editingState = editingState.copy(menusVisible = true) } if (isResizeMode.value) { toggleResizeMode() cancelResizeMode() - menusVisible = true + _editingState = editingState.copy(menusVisible = true) } if (isEyeDropperMode.value) { toggleEyeDropper() cancelEyeDropper() - menusVisible = true + _editingState = editingState.copy(menusVisible = true) } if (isBlurMode.value) { toggleBlurMode() blurOperation.cancel() - menusVisible = true + _editingState = editingState.copy(menusVisible = true) } scaleToFit() } @@ -412,59 +374,23 @@ class EditViewModel( } } - companion object { - private const val KEEP_USED_COLORS = 20 - } -} - -// FIXME: Remove context or this function from here -private fun loadImageWithPath( - context: Context, - image: Path, - editManager: EditManager -) { - initGlideBuilder(context) - .load(image.toFile()) - .loadInto(editManager) -} - -// FIXME: Remove context or this function from here -private fun loadImageWithUri( - context: Context, - uri: String, - editManager: EditManager -) { - initGlideBuilder(context) - .load(uri.toUri()) - .loadInto(editManager) -} + private fun loadDefaultPaintColor() { + viewModelScope.launch { + _usedColors.addAll(prefs.readUsedColors()) -// FIXME: Remove context or this function from here -private fun initGlideBuilder(context: Context) = Glide - .with(context) - .asBitmap() - .skipMemoryCache(true) - .diskCacheStrategy(DiskCacheStrategy.NONE) - -// FIXME: Remove context or this function from here -private fun RequestBuilder.loadInto( - editManager: EditManager -) { - into(object : CustomTarget() { - override fun onResourceReady( - bitmap: Bitmap, - transition: Transition? - ) { - editManager.apply { - val image = bitmap.asImageBitmap() - backgroundImage.value = image - setOriginalBackgroundImage(image) - scaleToFit() + val color = if (_usedColors.isNotEmpty()) { + _usedColors.last() + } else { + Color(primaryColor.toULong()).also { _usedColors.add(it) } } + + editManager.setPaintColor(color) } + } - override fun onLoadCleared(placeholder: Drawable?) {} - }) + companion object { + private const val KEEP_USED_COLORS = 20 + } } fun resize( diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/manager/EditionMode.kt b/app/src/main/java/dev/arkbuilders/arkretouch/edition/manager/EditionMode.kt deleted file mode 100644 index 52f484e..0000000 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/manager/EditionMode.kt +++ /dev/null @@ -1,9 +0,0 @@ -package dev.arkbuilders.arkretouch.edition.manager - -enum class EditionMode { - IDLE, - CROP, - RESIZE, - ROTATE, - ZOOM -} \ No newline at end of file diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/edition/model/EditionState.kt b/app/src/main/java/dev/arkbuilders/arkretouch/edition/model/EditionState.kt deleted file mode 100644 index 8302b71..0000000 --- a/app/src/main/java/dev/arkbuilders/arkretouch/edition/model/EditionState.kt +++ /dev/null @@ -1,12 +0,0 @@ -package dev.arkbuilders.arkretouch.edition.model - -data class EditionState( - val strokeSliderExpanded: Boolean -) { - - companion object { - val DEFAULT = EditionState( - strokeSliderExpanded = false - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/main/MainScreen.kt b/app/src/main/java/dev/arkbuilders/arkretouch/main/MainScreen.kt index de001f1..b8500c0 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/main/MainScreen.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/main/MainScreen.kt @@ -14,7 +14,7 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument -import dev.arkbuilders.arkretouch.edition.ui.main.EditScreen +import dev.arkbuilders.arkretouch.editing.ui.main.EditScreen import dev.arkbuilders.arkretouch.picker.PickerScreen import dev.arkbuilders.arkretouch.storage.Resolution import dev.arkbuilders.arkretouch.utils.permission.PermissionsHelper diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/ConfirmClearDialog.kt b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/ConfirmClearDialog.kt index 4c1a209..0e4b466 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/ConfirmClearDialog.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/ConfirmClearDialog.kt @@ -6,21 +6,21 @@ import androidx.compose.material.Button import androidx.compose.material.Text import androidx.compose.material.TextButton import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @Composable fun ConfirmClearDialog( - show: MutableState, + show: Boolean, + onDismiss: () -> Unit, onConfirm: () -> Unit ) { - if (!show.value) return + if (!show) return AlertDialog( onDismissRequest = { - show.value = false + onDismiss() }, title = { Text( @@ -32,8 +32,8 @@ fun ConfirmClearDialog( confirmButton = { Button( onClick = { - show.value = false onConfirm() + onDismiss() } ) { Text("Clear") @@ -42,7 +42,7 @@ fun ConfirmClearDialog( dismissButton = { TextButton( onClick = { - show.value = false + onDismiss() } ) { Text("Cancel") diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/NewImageOptionsDialog.kt b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/NewImageOptionsDialog.kt index bd924dc..7831018 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/NewImageOptionsDialog.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/NewImageOptionsDialog.kt @@ -35,7 +35,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.core.text.isDigitsOnly import dev.arkbuilders.arkretouch.R -import dev.arkbuilders.arkretouch.edition.manager.EditManager +import dev.arkbuilders.arkretouch.editing.manager.EditManager import dev.arkbuilders.arkretouch.presentation.edit.resize.Hint import dev.arkbuilders.arkretouch.presentation.edit.resize.delayHidingHint import dev.arkbuilders.arkretouch.storage.Resolution diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/TransparencyChessBoard.kt b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/TransparencyChessBoard.kt index aaab58b..ceda2c7 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/TransparencyChessBoard.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/TransparencyChessBoard.kt @@ -14,7 +14,7 @@ import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.graphics.nativeCanvas import androidx.compose.ui.unit.toSize import android.graphics.Matrix -import dev.arkbuilders.arkretouch.edition.manager.EditManager +import dev.arkbuilders.arkretouch.editing.manager.EditManager private class TransparencyChessBoard { fun create(boardSize: Size, canvas: Canvas, matrix: Matrix) { diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/draw/DrawOperation.kt b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/draw/DrawOperation.kt index 3b4a90a..5785583 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/draw/DrawOperation.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/draw/DrawOperation.kt @@ -1,8 +1,8 @@ package dev.arkbuilders.arkretouch.presentation.edit.draw import androidx.compose.ui.graphics.Path -import dev.arkbuilders.arkretouch.edition.manager.EditManager -import dev.arkbuilders.arkretouch.edition.model.Operation +import dev.arkbuilders.arkretouch.editing.manager.EditManager +import dev.arkbuilders.arkretouch.editing.model.Operation class DrawOperation(private val editManager: EditManager) : Operation { private var path = Path() diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/resize/ResizeInput.kt b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/resize/ResizeInput.kt index b9792bb..37bb215 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/resize/ResizeInput.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/resize/ResizeInput.kt @@ -32,7 +32,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.core.text.isDigitsOnly import dev.arkbuilders.arkretouch.R -import dev.arkbuilders.arkretouch.edition.manager.EditManager +import dev.arkbuilders.arkretouch.editing.manager.EditManager import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/resize/ResizeOperation.kt b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/resize/ResizeOperation.kt index b2f2e0e..1e74b56 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/resize/ResizeOperation.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/resize/ResizeOperation.kt @@ -5,8 +5,8 @@ import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.unit.IntSize import android.graphics.Bitmap -import dev.arkbuilders.arkretouch.edition.manager.EditManager -import dev.arkbuilders.arkretouch.edition.model.Operation +import dev.arkbuilders.arkretouch.editing.manager.EditManager +import dev.arkbuilders.arkretouch.editing.model.Operation import dev.arkbuilders.arkretouch.utils.resize import java.lang.NullPointerException diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/rotate/RotateOperation.kt b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/rotate/RotateOperation.kt index cc14ddf..14802c7 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/rotate/RotateOperation.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/presentation/edit/rotate/RotateOperation.kt @@ -1,8 +1,8 @@ package dev.arkbuilders.arkretouch.presentation.edit.rotate import android.graphics.Matrix -import dev.arkbuilders.arkretouch.edition.manager.EditManager -import dev.arkbuilders.arkretouch.edition.model.Operation +import dev.arkbuilders.arkretouch.editing.manager.EditManager +import dev.arkbuilders.arkretouch.editing.model.Operation import dev.arkbuilders.arkretouch.utils.rotate class RotateOperation(private val editManager: EditManager) : Operation { diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/storage/ImageDefaults.kt b/app/src/main/java/dev/arkbuilders/arkretouch/storage/ImageDefaults.kt index db85cb5..ddbf911 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/storage/ImageDefaults.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/storage/ImageDefaults.kt @@ -4,7 +4,12 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.IntSize import kotlinx.serialization.Serializable -// FIXME: Replace with Parcelable +/** + * We use serialization for these classes because we write them to storage as JSON text, + * To convert them correctly we use [kotlinx.serialization.encodeToString] and [kotlinx.serialization.decodeFromString] which requires an object to be [@Serializable] + * Refer here [dev.arkbuilders.arkretouch.storage.OldStorageRepository.persistDefaults] +*/ + @Serializable data class ImageDefaults( val colorValue: ULong = Color.White.value, diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/utils/ImageHelper.kt b/app/src/main/java/dev/arkbuilders/arkretouch/utils/ImageHelper.kt index 9c9c224..3ebd027 100644 --- a/app/src/main/java/dev/arkbuilders/arkretouch/utils/ImageHelper.kt +++ b/app/src/main/java/dev/arkbuilders/arkretouch/utils/ImageHelper.kt @@ -2,7 +2,7 @@ package dev.arkbuilders.arkretouch.utils import android.graphics.Bitmap import android.graphics.Matrix -import dev.arkbuilders.arkretouch.edition.ui.crop.CropWindow +import dev.arkbuilders.arkretouch.editing.ui.crop.CropWindow import dev.arkbuilders.arkretouch.presentation.edit.resize.ResizeOperation import dev.arkbuilders.arkretouch.presentation.edit.rotate.RotateOperation diff --git a/app/src/main/java/dev/arkbuilders/arkretouch/utils/ImageLoading.kt b/app/src/main/java/dev/arkbuilders/arkretouch/utils/ImageLoading.kt new file mode 100644 index 0000000..16b73c6 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/arkretouch/utils/ImageLoading.kt @@ -0,0 +1,60 @@ +package dev.arkbuilders.arkretouch.utils + +import androidx.compose.ui.graphics.asImageBitmap +import androidx.core.net.toUri +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import com.bumptech.glide.Glide +import com.bumptech.glide.RequestBuilder +import com.bumptech.glide.load.engine.DiskCacheStrategy +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import dev.arkbuilders.arkretouch.editing.manager.EditManager +import java.nio.file.Path + +fun loadImageWithPath( + context: Context, + image: Path, + editManager: EditManager +) { + initGlideBuilder(context) + .load(image.toFile()) + .loadInto(editManager) +} + +fun loadImageWithUri( + context: Context, + uri: String, + editManager: EditManager +) { + initGlideBuilder(context) + .load(uri.toUri()) + .loadInto(editManager) +} + +private fun initGlideBuilder(context: Context) = Glide + .with(context) + .asBitmap() + .skipMemoryCache(true) + .diskCacheStrategy(DiskCacheStrategy.NONE) + +private fun RequestBuilder.loadInto( + editManager: EditManager +) { + into(object : CustomTarget() { + override fun onResourceReady( + bitmap: Bitmap, + transition: Transition? + ) { + editManager.apply { + val image = bitmap.asImageBitmap() + backgroundImage.value = image + setOriginalBackgroundImage(image) + scaleToFit() + } + } + + override fun onLoadCleared(placeholder: Drawable?) {} + }) +} \ No newline at end of file