Skip to content

Commit d4413d7

Browse files
Merge pull request #34 from gdg-berlin-android/feature/wizard-state-hoist
State hoist and prep for Wizard UI
2 parents 383fb58 + 747ed3c commit d4413d7

7 files changed

Lines changed: 161 additions & 98 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@
88
.externalNativeBuild
99
.cxx
1010
local.properties
11+
12+
# Ignore Junie working files
13+
.junie/guidelines.md

app/src/main/java/de/berlindroid/zepatch/MainActivity.kt

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,13 @@ import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaf
4141
import androidx.compose.material3.rememberTopAppBarState
4242
import androidx.compose.runtime.Composable
4343
import androidx.compose.runtime.getValue
44+
import androidx.compose.runtime.mutableIntStateOf
4445
import androidx.compose.runtime.mutableStateOf
4546
import androidx.compose.runtime.remember
4647
import androidx.compose.runtime.rememberCoroutineScope
4748
import androidx.compose.runtime.setValue
4849
import androidx.compose.ui.Modifier
50+
import androidx.compose.ui.graphics.ImageBitmap
4951
import androidx.compose.ui.input.nestedscroll.nestedScroll
5052
import androidx.compose.ui.unit.dp
5153
import de.berlindroid.zepatch.PatchablePreviewMode.*
@@ -173,6 +175,10 @@ private fun PatchableDetail(
173175
onBackClick: () -> Unit,
174176
patchable: @Composable () -> Unit,
175177
) {
178+
var imageBitmap by remember { mutableStateOf<ImageBitmap?>(null) }
179+
var reducedImageBitmap by remember { mutableStateOf<ImageBitmap?>(null) }
180+
var colorCount by remember { mutableIntStateOf(3) }
181+
176182
Scaffold(
177183
modifier = modifier,
178184
topBar = {
@@ -224,13 +230,22 @@ private fun PatchableDetail(
224230
when (currentMode) {
225231
COMPOSABLE -> PatchableBoundingBox(patchable = patchable)
226232

227-
BITMAP -> PatchableToBitmap(patchable = patchable)
233+
BITMAP -> PatchableToBitmap(
234+
onBitmap = { img -> imageBitmap = img },
235+
patchable = patchable
236+
)
228237

229238
REDUCED_BITMAP -> PatchableToReducedBitmap(
230-
patchable = patchable
239+
image = imageBitmap,
240+
colorCount = colorCount,
241+
onColorCountChanged = { count -> colorCount = count },
242+
onReducedBitmap = { img -> reducedImageBitmap = img },
231243
)
232244

233-
STITCHES -> BitmapToStitches(patchable = patchable, name = name)
245+
STITCHES -> BitmapToStitches(
246+
reducedImageBitmap = reducedImageBitmap,
247+
name = name
248+
)
234249
}
235250
}
236251
}

app/src/main/java/de/berlindroid/zepatch/patchable/Demo.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
1010
import androidx.compose.foundation.layout.size
1111
import androidx.compose.foundation.shape.RoundedCornerShape
1212
import androidx.compose.material3.ExperimentalMaterial3Api
13-
import androidx.compose.material3.Icon
1413
import androidx.compose.material3.Text
1514
import androidx.compose.runtime.Composable
1615
import androidx.compose.ui.Modifier
@@ -23,7 +22,6 @@ import androidx.compose.ui.text.font.FontFamily
2322
import androidx.compose.ui.text.font.FontStyle
2423
import androidx.compose.ui.text.font.FontWeight
2524
import androidx.compose.ui.text.style.TextAlign
26-
import androidx.compose.ui.text.style.TextDecoration
2725
import androidx.compose.ui.tooling.preview.Preview
2826
import androidx.compose.ui.unit.dp
2927
import androidx.compose.ui.unit.sp

app/src/main/java/de/berlindroid/zepatch/ui/BitmapToStitches.kt

Lines changed: 57 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package de.berlindroid.zepatch.ui
22

33
import android.content.Context
44
import android.content.Intent
5-
import android.graphics.Bitmap
65
import android.graphics.BitmapFactory
76
import android.net.Uri
87
import android.util.Log
@@ -11,90 +10,91 @@ import androidx.activity.compose.rememberLauncherForActivityResult
1110
import androidx.activity.result.ActivityResult
1211
import androidx.activity.result.contract.ActivityResultContracts
1312
import androidx.compose.foundation.Image
14-
import androidx.compose.foundation.layout.Box
13+
import androidx.compose.foundation.layout.Column
1514
import androidx.compose.foundation.layout.fillMaxWidth
15+
import androidx.compose.material3.Button
1616
import androidx.compose.material3.CircularProgressIndicator
1717
import androidx.compose.material3.Icon
1818
import androidx.compose.material3.IconButton
19+
import androidx.compose.material3.Text
1920
import androidx.compose.runtime.Composable
2021
import androidx.compose.runtime.getValue
2122
import androidx.compose.runtime.mutableStateOf
2223
import androidx.compose.runtime.remember
24+
import androidx.compose.runtime.rememberCoroutineScope
2325
import androidx.compose.runtime.setValue
2426
import androidx.compose.ui.Modifier
2527
import androidx.compose.ui.graphics.ImageBitmap
2628
import androidx.compose.ui.graphics.asAndroidBitmap
2729
import androidx.compose.ui.graphics.asImageBitmap
2830
import androidx.compose.ui.platform.LocalContext
2931
import androidx.compose.ui.res.painterResource
32+
import androidx.compose.ui.tooling.preview.Preview
3033
import androidx.core.graphics.scale
31-
import com.embroidermodder.punching.reduceColors
3234
import de.berlindroid.zepatch.stiches.StitchToPES
3335
import de.berlindroid.zepatch.stiches.StitchToPES.createEmbroideryFromBitmap
34-
import de.berlindroid.zepatch.utils.CaptureToBitmap
35-
36+
import kotlinx.coroutines.launch
3637

3738
@Composable
3839
fun BitmapToStitches(
3940
modifier: Modifier = Modifier,
40-
name: String,
41-
patchable: @Composable () -> Unit,
41+
reducedImageBitmap: ImageBitmap? = null,
42+
name: String
4243
) {
4344
val context = LocalContext.current
4445
var bytes by remember { mutableStateOf<ByteArray?>(null) }
46+
var displayImage by remember { mutableStateOf<ImageBitmap?>(null) }
47+
val coroutineScope = rememberCoroutineScope()
4548

4649
val launcher = rememberLauncherForActivityResult(
4750
contract = ActivityResultContracts.StartActivityForResult()
4851
) { result ->
4952
savePesAfterSelection(context, result, bytes)
5053
}
5154

52-
var image by remember { mutableStateOf<ImageBitmap?>(null) }
53-
54-
Box(modifier = modifier.fillMaxWidth()) {
55-
// Compose the content through the composable utility; it will invoke the callback when ready.
56-
CaptureToBitmap(
57-
modifier = Modifier.fillMaxWidth(),
58-
onBitmap = { img ->
59-
// TODO: PARRALELEIZE & VMIZE
60-
val aspect = img.width / img.height.toFloat()
61-
62-
val reduced =
63-
img.asAndroidBitmap()
64-
.copy(Bitmap.Config.ARGB_8888, false)
65-
.scale((512 * aspect).toInt(), 512, false)
66-
.reduceColors(3) // TODO UI For color count selection
67-
68-
val embroidery = createEmbroideryFromBitmap(
69-
name,
70-
reduced,
71-
mmWidth = 30f * aspect,
72-
mmHeight = 30f,
73-
mmDensity = 0.5f
74-
)
75-
76-
val pes = StitchToPES.convert(context, embroidery)
77-
if (pes == null || pes.isEmpty()) {
78-
Log.e("EMBNO", "No pes found.")
79-
} else {
80-
bytes = pes
55+
Column(modifier = modifier.fillMaxWidth()) {
56+
reducedImageBitmap?.let {
57+
Image(
58+
bitmap = it,
59+
contentDescription = "patch bitmap",
60+
modifier = Modifier.fillMaxWidth()
61+
)
62+
}
63+
Button(onClick = {
64+
coroutineScope.launch {
65+
reducedImageBitmap?.let {
66+
val aspect = it.width / it.height.toFloat()
67+
val embroidery = createEmbroideryFromBitmap(
68+
name,
69+
bitmap = it.asAndroidBitmap(),
70+
mmWidth = 30f * aspect,
71+
mmHeight = 30f,
72+
mmDensity = 0.5f
73+
)
74+
75+
val pes = StitchToPES.convert(context, embroidery)
76+
if (pes == null || pes.isEmpty()) {
77+
Log.e("EMBNO", "No pes found.")
78+
} else {
79+
bytes = pes
80+
}
81+
82+
val png = StitchToPES.convert(context, embroidery, "png")
83+
if (png == null || png.isEmpty()) {
84+
Log.e("PNGNO", "No png returned.")
85+
} else {
86+
val decoded = BitmapFactory.decodeByteArray(png, 0, png.size)
87+
88+
displayImage = decoded
89+
.scale(decoded.width * 2, decoded.height * 2)
90+
.asImageBitmap()
91+
}
8192
}
93+
}
8294

83-
val png = StitchToPES.convert(context, embroidery, "png")
84-
if (png == null || png.isEmpty()) {
85-
Log.e("PNGNO", "No png returned.")
86-
} else {
87-
val decoded = BitmapFactory.decodeByteArray(png, 0, png.size)
88-
89-
image = decoded
90-
.scale(decoded.width * 2, decoded.height * 2)
91-
.asImageBitmap()
92-
}
93-
},
94-
content = patchable
95-
)
95+
}) { Text("Do it") } // Compose the content through the composable utility; it will invoke the callback when ready.
9696

97-
image?.let {
97+
displayImage?.let {
9898
Image(
9999
bitmap = it,
100100
contentDescription = "patch bitmap",
@@ -129,7 +129,6 @@ fun BitmapToStitches(
129129
}
130130
}
131131

132-
133132
private fun savePesAfterSelection(context: Context, result: ActivityResult, bytes: ByteArray?) {
134133
// TODO MOVE ME INTO VM
135134

@@ -164,3 +163,10 @@ private fun savePesAfterSelection(context: Context, result: ActivityResult, byte
164163
}
165164
}
166165

166+
@Preview
167+
@Composable
168+
fun BitmapToStitchesPreview() {
169+
val imageBitmap = ImageBitmap(width = 100, height = 100) // Replace with a real ImageBitmap if needed
170+
BitmapToStitches(reducedImageBitmap = imageBitmap, name = "MyPatch")
171+
}
172+

app/src/main/java/de/berlindroid/zepatch/ui/PatchableToBitmap.kt

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package de.berlindroid.zepatch.ui
22

33
import androidx.compose.foundation.Image
4-
import androidx.compose.foundation.layout.Box
4+
import androidx.compose.foundation.layout.Column
55
import androidx.compose.foundation.layout.fillMaxWidth
6+
import androidx.compose.material3.Button
67
import androidx.compose.material3.CircularProgressIndicator
8+
import androidx.compose.material3.Text
79
import androidx.compose.runtime.Composable
810
import androidx.compose.runtime.getValue
911
import androidx.compose.runtime.mutableStateOf
@@ -20,15 +22,25 @@ import de.berlindroid.zepatch.utils.CaptureToBitmap
2022
@Composable
2123
fun PatchableToBitmap(
2224
modifier: Modifier = Modifier,
25+
onBitmap: (ImageBitmap) -> Unit = {},
2326
patchable: @Composable () -> Unit,
2427
) {
2528
var image by remember { mutableStateOf<ImageBitmap?>(null) }
29+
var shouldCapture by remember { mutableStateOf(false) }
2630

27-
Box(modifier = modifier.fillMaxWidth()) {
31+
Column(modifier = modifier.fillMaxWidth()) {
32+
Button(onClick = {
33+
image = null
34+
shouldCapture = true
35+
}) { Text("Do it") }
2836
// Compose the content through the composable utility; it will invoke the callback when ready.
2937
CaptureToBitmap(
3038
modifier = Modifier.fillMaxWidth(),
31-
onBitmap = { img -> image = img },
39+
shouldCapture = shouldCapture,
40+
onBitmap = { img ->
41+
image = img
42+
shouldCapture = false
43+
},
3244
content = patchable
3345
)
3446

@@ -38,7 +50,10 @@ fun PatchableToBitmap(
3850
contentDescription = "patch bitmap",
3951
modifier = Modifier.fillMaxWidth()
4052
)
53+
onBitmap(it)
4154
} ?: CircularProgressIndicator()
4255

4356
}
4457
}
58+
59+

0 commit comments

Comments
 (0)