I’m trying to update the value of showErrorMode with a callback passed to my Canvas composable, but the callback doesn’t happen. I need this to show an adequate error to my user.
<code>fun CameraPreview(
viewModel: DcodeViewModel,
modifier: Modifier = Modifier,
controller: LifecycleCameraController,
navController: NavHostController,
) {
val isTorchOn by viewModel.isTorchOn.collectAsState()
val uiBoxes by viewModel.currentUiBoxes.collectAsState()
val foundDcode by viewModel.foundDcode.collectAsState()
val currentHex by viewModel.currentHex.collectAsState()
var showErrorMode by remember { mutableIntStateOf(0) }
Log.d(UI_TEST, "ERROR MODE : $showErrorMode") <-- shows zeros at the beginning of analysis
val error by remember {
derivedStateOf {
when (showErrorMode) {
1 -> "Phone is too close to Dcode"
2 -> "Phone is too far from Dcode"
else -> null
}
}
}
...
</code>
<code>fun CameraPreview(
viewModel: DcodeViewModel,
modifier: Modifier = Modifier,
controller: LifecycleCameraController,
navController: NavHostController,
) {
val isTorchOn by viewModel.isTorchOn.collectAsState()
val uiBoxes by viewModel.currentUiBoxes.collectAsState()
val foundDcode by viewModel.foundDcode.collectAsState()
val currentHex by viewModel.currentHex.collectAsState()
var showErrorMode by remember { mutableIntStateOf(0) }
Log.d(UI_TEST, "ERROR MODE : $showErrorMode") <-- shows zeros at the beginning of analysis
val error by remember {
derivedStateOf {
when (showErrorMode) {
1 -> "Phone is too close to Dcode"
2 -> "Phone is too far from Dcode"
else -> null
}
}
}
...
</code>
fun CameraPreview(
viewModel: DcodeViewModel,
modifier: Modifier = Modifier,
controller: LifecycleCameraController,
navController: NavHostController,
) {
val isTorchOn by viewModel.isTorchOn.collectAsState()
val uiBoxes by viewModel.currentUiBoxes.collectAsState()
val foundDcode by viewModel.foundDcode.collectAsState()
val currentHex by viewModel.currentHex.collectAsState()
var showErrorMode by remember { mutableIntStateOf(0) }
Log.d(UI_TEST, "ERROR MODE : $showErrorMode") <-- shows zeros at the beginning of analysis
val error by remember {
derivedStateOf {
when (showErrorMode) {
1 -> "Phone is too close to Dcode"
2 -> "Phone is too far from Dcode"
else -> null
}
}
}
...
<code>...
foundDcode?.let { dcode ->
DetectionCanvas(listOf(dcode)) { newMode ->
Log.d(UI_TEST, "SHOULD BE UPDATED TO $newMode") <- THIS ISNT CALLED
showErrorMode = newMode
}
} ?: DetectionCanvas(uiBoxes){}
...
</code>
<code>...
foundDcode?.let { dcode ->
DetectionCanvas(listOf(dcode)) { newMode ->
Log.d(UI_TEST, "SHOULD BE UPDATED TO $newMode") <- THIS ISNT CALLED
showErrorMode = newMode
}
} ?: DetectionCanvas(uiBoxes){}
...
</code>
...
foundDcode?.let { dcode ->
DetectionCanvas(listOf(dcode)) { newMode ->
Log.d(UI_TEST, "SHOULD BE UPDATED TO $newMode") <- THIS ISNT CALLED
showErrorMode = newMode
}
} ?: DetectionCanvas(uiBoxes){}
...
<code>@Composable
private fun DetectionCanvas(uiBoxes: List<UiBox>, setErrorMode: (Int) -> Unit ) {
val boxClosestToCenter = uiBoxes.firstOrNull { it.isClosestToCenter }
val remainingBoxes = uiBoxes.filterNot { it.isClosestToCenter }
Box {
boxClosestToCenter?.let { mainUiBox ->
if (mainUiBox.isTooBig) {
Log.d(UI_TEST,"TOO BIG") <- THIS IS CALLED
setErrorMode(1)
} else if (mainUiBox.isTooSmall) {
Log.d(UI_TEST,"TOO SMALL")
setErrorMode(2)
} else {
Log.d(UI_TEST,"NORMAL")
setErrorMode(0)
}
Canvas(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(1f)
.background(Color.Transparent)
.zIndex(2f)
) {
val color = Color.Red
val stroke = Stroke(width = 6f)
drawRect(
color = color,
topLeft = boxClosestToCenter.start,
size = boxClosestToCenter.size,
style = stroke
)
}
}
Canvas(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(1f)
.background(Color.Transparent)
) {
remainingBoxes.forEach { uiBox ->
val color = Color.Yellow
val stroke = Stroke(width = 3f)
drawRect(
color = color,
topLeft = uiBox.start,
size = uiBox.size,
style = stroke
)
}
}
}
}
</code>
<code>@Composable
private fun DetectionCanvas(uiBoxes: List<UiBox>, setErrorMode: (Int) -> Unit ) {
val boxClosestToCenter = uiBoxes.firstOrNull { it.isClosestToCenter }
val remainingBoxes = uiBoxes.filterNot { it.isClosestToCenter }
Box {
boxClosestToCenter?.let { mainUiBox ->
if (mainUiBox.isTooBig) {
Log.d(UI_TEST,"TOO BIG") <- THIS IS CALLED
setErrorMode(1)
} else if (mainUiBox.isTooSmall) {
Log.d(UI_TEST,"TOO SMALL")
setErrorMode(2)
} else {
Log.d(UI_TEST,"NORMAL")
setErrorMode(0)
}
Canvas(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(1f)
.background(Color.Transparent)
.zIndex(2f)
) {
val color = Color.Red
val stroke = Stroke(width = 6f)
drawRect(
color = color,
topLeft = boxClosestToCenter.start,
size = boxClosestToCenter.size,
style = stroke
)
}
}
Canvas(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(1f)
.background(Color.Transparent)
) {
remainingBoxes.forEach { uiBox ->
val color = Color.Yellow
val stroke = Stroke(width = 3f)
drawRect(
color = color,
topLeft = uiBox.start,
size = uiBox.size,
style = stroke
)
}
}
}
}
</code>
@Composable
private fun DetectionCanvas(uiBoxes: List<UiBox>, setErrorMode: (Int) -> Unit ) {
val boxClosestToCenter = uiBoxes.firstOrNull { it.isClosestToCenter }
val remainingBoxes = uiBoxes.filterNot { it.isClosestToCenter }
Box {
boxClosestToCenter?.let { mainUiBox ->
if (mainUiBox.isTooBig) {
Log.d(UI_TEST,"TOO BIG") <- THIS IS CALLED
setErrorMode(1)
} else if (mainUiBox.isTooSmall) {
Log.d(UI_TEST,"TOO SMALL")
setErrorMode(2)
} else {
Log.d(UI_TEST,"NORMAL")
setErrorMode(0)
}
Canvas(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(1f)
.background(Color.Transparent)
.zIndex(2f)
) {
val color = Color.Red
val stroke = Stroke(width = 6f)
drawRect(
color = color,
topLeft = boxClosestToCenter.start,
size = boxClosestToCenter.size,
style = stroke
)
}
}
Canvas(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(1f)
.background(Color.Transparent)
) {
remainingBoxes.forEach { uiBox ->
val color = Color.Yellow
val stroke = Stroke(width = 3f)
drawRect(
color = color,
topLeft = uiBox.start,
size = uiBox.size,
style = stroke
)
}
}
}
}
All the size checks in UiBox are correct. I have no idea what might be wrong since this approach worked for me in multiple composables. Is this some kind of scope issue ?