Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 57 additions & 30 deletions app/src/main/java/de/berlindroid/zepatch/WizardViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import com.embroidermodder.punching.Histogram
import com.embroidermodder.punching.reduceColors
import de.berlindroid.zepatch.WizardViewModel.UiState
import de.berlindroid.zepatch.WizardViewModel.UiState.Done
import de.berlindroid.zepatch.WizardViewModel.UiState.EmbroiderBitmap
import de.berlindroid.zepatch.WizardViewModel.UiState.ReduceBitmap
import de.berlindroid.zepatch.WizardViewModel.UiState.SelectPatchable
import de.berlindroid.zepatch.WizardViewModel.UiState.SetupBitmap
import de.berlindroid.zepatch.WizardViewModel.UiState.SetupComposable
import de.berlindroid.zepatch.WizardViewModel.UiState.SetupEmbroidery
import de.berlindroid.zepatch.stiches.StitchToPES
import de.berlindroid.zepatch.utils.multiLet
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -74,14 +74,14 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)
) : UiState(error) {
override fun previous(): UiState = SelectPatchable()

override fun next(): UiState = SetupBitmap(name, image!!)
override fun next(): UiState = ReduceBitmap(name, image!!)

override fun isCompleted(): Boolean = image != null

override fun copyWithError(error: String): UiState = copy(error = error)
}

data class SetupBitmap(
data class ReduceBitmap(
// input
val name: String,
val image: ImageBitmap,
Expand All @@ -100,7 +100,7 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)
) : UiState(error) {
override fun previous(): UiState = SetupComposable(name)

override fun next(): UiState = SetupEmbroidery(
override fun next(): UiState = EmbroiderBitmap(
name,
image,
colorCount,
Expand All @@ -114,7 +114,7 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)
override fun copyWithError(error: String): UiState = copy(error = error)
}

data class SetupEmbroidery(
data class EmbroiderBitmap(
// input
val name: String,
val image: ImageBitmap,
Expand All @@ -123,8 +123,12 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)
val reducedHistogram: Histogram,

// configurable
// TODO
// density
val size: Float = 50f,
val densityX: Float = 0.4f,
val densityY: Float = 0.4f,
val borderThickness: Float = 2f,
val borderDensity: Float = 0.5f,

// satin border yes no
// sizes
// colors?
Expand All @@ -137,7 +141,7 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)

override val error: String? = null
) : UiState(error) {
override fun previous(): UiState = SetupBitmap(name, image, colorCount)
override fun previous(): UiState = ReduceBitmap(name, image, colorCount)

override fun next(): UiState {
embroideryData?.multiLet(launcher) { data, launcher ->
Expand Down Expand Up @@ -184,7 +188,7 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)
val embroideryPreviewImage: ImageBitmap,
override val error: String? = null
) : UiState(error) {
override fun previous(): UiState = SetupEmbroidery(name, image, colorCount, reducedBitmap, reducedHistogram)
override fun previous(): UiState = EmbroiderBitmap(name, image, colorCount, reducedBitmap, reducedHistogram)

override fun next(): UiState = SelectPatchable()

Expand Down Expand Up @@ -239,28 +243,50 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)
fun updateColorCount(count: Int) {
_uiState.update {
when (it) {
is SetupBitmap -> it.copy(colorCount = count)
is ReduceBitmap -> it.copy(colorCount = count)
else -> it.copyWithError("Colors could not be updated in state ${it.javaClass.simpleName}.")
}
}
}

fun updateEmbroideryConfig(
densityX: Float,
densityY: Float,
size: Float,
borderThickness: Float,
borderDensity: Float
) {
_uiState.update {
when (it) {
is EmbroiderBitmap -> it.copy(
densityX = densityX,
densityY = densityY,
size = size,
borderThickness = borderThickness,
borderDensity = borderDensity,
)

else -> it.copyWithError("Cannot update embroidery in state ${it.javaClass.simpleName}.")
}
}
}

fun computeReducedBitmap() {
if (_uiState.value !is SetupBitmap) {
if (_uiState.value !is ReduceBitmap) {
_uiState.update { it.copyWithError("Cannot create reduced bitmap in state ${it.javaClass.simpleName}.") }
return
}

_uiState.update {
(it as? SetupBitmap)?.copy(
(it as? ReduceBitmap)?.copy(
reducedBitmap = null,
reducedHistogram = null,
currentlyReducingColors = true
) ?: it.copyWithError("Inbetween change, we keep on trucking")
}

viewModelScope.launch(Dispatchers.IO) {
val state = _uiState.value as SetupBitmap
val state = _uiState.value as ReduceBitmap
val aspect = state.image.width / state.image.height.toFloat()
val (reducedBmp, histogram) = state.image.asAndroidBitmap()
.copy(Bitmap.Config.ARGB_8888, false)
Expand All @@ -272,7 +298,7 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)

_uiState.update {
when (it) {
is SetupBitmap -> it.copy(
is ReduceBitmap -> it.copy(
reducedBitmap = reducedBmp.asImageBitmap(),
reducedHistogram = histogram,
currentlyReducingColors = false,
Expand All @@ -285,15 +311,15 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)
}

fun createEmbroidery() {
if (_uiState.value !is SetupEmbroidery) {
if (_uiState.value !is EmbroiderBitmap) {
_uiState.update {
it.copyWithError("No, sadly you have to be in embroidery mode!")
}
return
}

_uiState.update {
(it as? SetupEmbroidery)?.copy(
(it as? EmbroiderBitmap)?.copy(
embroideryData = null,
embroideryPreviewImage = null,
currentlyEmbroidering = true
Expand All @@ -302,18 +328,19 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)

viewModelScope.launch(Dispatchers.IO) {
try {
val state = _uiState.value as SetupEmbroidery
val state = _uiState.value as EmbroiderBitmap

val aspect = state.reducedBitmap.width / state.reducedBitmap.height.toFloat()
val embroidery = StitchToPES.createEmbroideryFromBitmap(
name = state.name,
bitmap = state.reducedBitmap.asAndroidBitmap(),
histogram = state.reducedHistogram,
mmWidth = 50f * aspect,
mmHeight = 50f,
mmDensityX = 0.5f,
mmDensityY = 0.2f,
satinBorderThickness = 10f,
mmWidth = state.size * aspect,
mmHeight = state.size,
mmDensityX = state.densityX,
mmDensityY = state.densityY,
satinBorderThickness = state.borderThickness,
satinBorderDensity = state.borderDensity,
)

val context = getApplication<Application>().applicationContext
Expand All @@ -328,7 +355,7 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)
}

_uiState.update {
(it as? SetupEmbroidery)?.copy(
(it as? EmbroiderBitmap)?.copy(
embroideryData = pes,
embroideryPreviewImage = previewImage,
currentlyEmbroidering = false,
Expand All @@ -337,7 +364,7 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)
} catch (th: Throwable) {
_uiState.update {
val message = "Throwable thrown: ${th}."
(it as? SetupEmbroidery)?.copy(
(it as? EmbroiderBitmap)?.copy(
embroideryData = null,
embroideryPreviewImage = null,
currentlyEmbroidering = false,
Expand All @@ -356,7 +383,7 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)
}

val bytes = when (state) {
is SetupEmbroidery -> state.embroideryData
is EmbroiderBitmap -> state.embroideryData
is Done -> state.embroideryData
else -> null
}
Expand Down Expand Up @@ -388,16 +415,16 @@ class WizardViewModel(application: Application) : AndroidViewModel(application)
}

fun setLauncher(launcher: ManagedActivityResultLauncher<Intent, ActivityResult>) {
if (_uiState.value is SetupEmbroidery) {
_uiState.update { (it as SetupEmbroidery).copy(launcher = launcher) }
if (_uiState.value is EmbroiderBitmap) {
_uiState.update { (it as EmbroiderBitmap).copy(launcher = launcher) }
}
}
}

fun UiState.isBusy(): Boolean = when (this) {
is Done -> false
is SelectPatchable -> false
is SetupBitmap -> currentlyReducingColors
is ReduceBitmap -> currentlyReducingColors
is SetupComposable -> false
is SetupEmbroidery -> currentlyEmbroidering
is EmbroiderBitmap -> currentlyEmbroidering
}
Loading
Loading