UX: Placement 자동스캔 + Stop/Resume 삭제 + Placement Complete
Placement: - 화면 진입 시 자동 스캔 시작 (isContinuousMode=true) - 초기 힌트: "센서를 부착해주세요" - Stop/Resume Scanning 버튼 삭제 - Start Measurement → "Placement Complete" (Green 또는 4+ch 감지 시 활성화) - Skip 버튼 TextButton으로 유지 Algorithm: - LATERAL 조건: (ch4&&ch5) OR 제거 → lrSymmetry >= 0.7 필수 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+13
-58
@@ -59,10 +59,10 @@ fun PlacementGuideView(appState: AppState) {
|
||||
val analyzer = remember { PiezoEchoAnalyzer.shared }
|
||||
|
||||
var isScanning by remember { mutableStateOf(false) }
|
||||
var isContinuousMode by remember { mutableStateOf(false) }
|
||||
var isContinuousMode by remember { mutableStateOf(true) }
|
||||
val channelDetected = remember { mutableStateListOf(false, false, false, false, false, false) }
|
||||
val channelUrineLen = remember { mutableStateListOf(0, 0, 0, 0, 0, 0) }
|
||||
var directionHint by remember { mutableStateOf("치골 위에 센서를 올려놓으세요") }
|
||||
var directionHint by remember { mutableStateOf("센서를 부착해주세요") }
|
||||
var directionIcon by remember { mutableStateOf("") }
|
||||
var placementScore by remember { mutableIntStateOf(0) }
|
||||
var scanCount by remember { mutableIntStateOf(0) }
|
||||
@@ -82,7 +82,7 @@ fun PlacementGuideView(appState: AppState) {
|
||||
isLocked = false
|
||||
scanCount = 0
|
||||
placementScore = 0
|
||||
directionHint = "치골 위에 센서를 올려놓으세요"
|
||||
directionHint = "센서를 부착해주세요"
|
||||
directionIcon = ""
|
||||
for (i in 0 until 6) { channelDetected[i] = false; channelUrineLen[i] = 0 }
|
||||
}
|
||||
@@ -573,75 +573,30 @@ fun PlacementGuideView(appState: AppState) {
|
||||
}
|
||||
}
|
||||
|
||||
// Start/Stop button
|
||||
// Placement Complete button
|
||||
Button(
|
||||
onClick = {
|
||||
if (isContinuousMode) {
|
||||
isContinuousMode = false
|
||||
} else {
|
||||
isContinuousMode = true
|
||||
}
|
||||
appState.placementComplete()
|
||||
},
|
||||
enabled = isLocked || detectedCount >= 4,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(52.dp),
|
||||
shape = RoundedCornerShape(14.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = if (isContinuousMode) Color.Red else MlPrimary
|
||||
containerColor = if (isLocked) Color(0xFF4CAF50) else MlPrimary,
|
||||
disabledContainerColor = Color.Gray.copy(alpha = 0.3f)
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = when {
|
||||
isContinuousMode -> "Stop Scanning"
|
||||
scanCount == 0 -> "Start Scanning"
|
||||
else -> "Resume Scanning"
|
||||
},
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = Color.White
|
||||
)
|
||||
}
|
||||
|
||||
// Start Measurement button (when 4+ channels detected)
|
||||
if (isLocked || detectedCount >= 4) {
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
Button(
|
||||
onClick = { appState.placementComplete() },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(52.dp),
|
||||
shape = RoundedCornerShape(14.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Color(0xFF4CAF50)
|
||||
)
|
||||
) {
|
||||
Icon(
|
||||
Icons.Filled.PlayArrow,
|
||||
contentDescription = null,
|
||||
tint = Color.White
|
||||
)
|
||||
Icon(Icons.Filled.CheckCircle, contentDescription = null, tint = Color.White)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = "Start Measurement",
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = Color.White
|
||||
)
|
||||
}
|
||||
Text("Placement Complete", fontSize = 16.sp, fontWeight = FontWeight.Bold, color = Color.White)
|
||||
}
|
||||
|
||||
// Skip button
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
Button(
|
||||
onClick = { appState.placementComplete() },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(48.dp),
|
||||
shape = RoundedCornerShape(14.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = MlSecondaryText.copy(alpha = 0.15f)
|
||||
)
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
TextButton(onClick = { isContinuousMode = false; appState.placementComplete() }) {
|
||||
Text(
|
||||
text = "Skip",
|
||||
fontSize = 15.sp,
|
||||
@@ -1036,7 +991,7 @@ private fun computePlacementGuide(
|
||||
val lrMax = maxOf(len4, len5, 1)
|
||||
val lrSymmetry = 1.0 - kotlin.math.abs(len4 - len5).toDouble() / lrMax
|
||||
|
||||
if (lrSymmetry >= 0.7 || (ch4 && ch5)) {
|
||||
if (lrSymmetry >= 0.7) {
|
||||
return PlacementGuideResult(
|
||||
"좌우 대칭 OK! 최종 확인 중...",
|
||||
"checkmark.circle", 60,
|
||||
|
||||
Reference in New Issue
Block a user