From fd9078f9a17e1d52a6edcf4daab1f4073a2996f7 Mon Sep 17 00:00:00 2001 From: jjangddu Date: Tue, 9 Jun 2026 14:45:12 +0900 Subject: [PATCH] =?UTF-8?q?ClinicalLive:=206=EC=B1=84=EB=84=90=201?= =?UTF-8?q?=EC=97=B4=206=ED=96=89=20=EC=84=B8=EB=A1=9C=20=EC=9D=BC?= =?UTF-8?q?=EB=A0=AC=20+=20Capture/Auto=20Capture=20=ED=86=A0=EA=B8=80=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 회의 결정 2건: 1. 6채널 그래프 layout: 2×3 grid → 1열 6행 세로 일렬 - 각 그래프가 화면 width 가득 (가독성 ↑) - 부모 Column이 이미 verticalScroll을 가지므로 자체 scroll 미적용 (nested scroll 회피) - SixChannelGrid 내부 Row 분기 제거 → 단순 Column에 ChannelChart × 6 + 4dp spacing 2. Capture 기능 제거 (필요 없음) - autoCapture = true 기본 + 매 사이클 자동 저장이라 Capture 버튼은 사실상 무용 - 하단 'Capture' 버튼 제거 (이전엔 Pause/Resume 옆에 위치) - 'Auto Capture 매 사이클 자동 저장' Switch 토글 제거 - var autoCapture 상태 → val autoCapture = true 고정 - 콜백 자동 저장 로직(imuCollector.onComplete 안)은 그대로 — 토글이 없으니 항상 true 경로 - 상단 doc 코멘트도 'Pause/Resume / Capture / End' → 'Pause/Resume / Discard / End'로 갱신 Co-Authored-By: Claude Opus 4.7 (1M context) --- .../ui/views/clinical/ClinicalLiveView.kt | 76 +++++-------------- 1 file changed, 18 insertions(+), 58 deletions(-) diff --git a/app/src/main/java/com/example/medilightv2android/ui/views/clinical/ClinicalLiveView.kt b/app/src/main/java/com/example/medilightv2android/ui/views/clinical/ClinicalLiveView.kt index 8dc4413..2b34eb6 100644 --- a/app/src/main/java/com/example/medilightv2android/ui/views/clinical/ClinicalLiveView.kt +++ b/app/src/main/java/com/example/medilightv2android/ui/views/clinical/ClinicalLiveView.kt @@ -48,9 +48,8 @@ import kotlin.math.min * - 2×3 grid 로 채널별 실시간 raw ADC 그래프 * - 상단: 세션 정보 (Subject ID / Posture / Step / True Vol / Abdomen) * - 측정 상태 (cycle 번호, 6/6 채널 도착률, IMU 자세/흔들림) - * - 하단 컨트롤: Pause/Resume / Capture / End - * - Capture: 현재 시점 1 사이클을 Clinical 폴더에 저장 - * - 자동 Capture 모드: 사이클마다 자동 저장 토글 + * - 하단 컨트롤: Pause/Resume / Discard / End + * - 측정 중 매 사이클 자동 저장 (autoCapture=true 고정, 회의 결정으로 토글 제거) * - End: 세션 finalize → ClinicalHome 복귀 */ @Composable @@ -67,7 +66,8 @@ fun ClinicalLiveView(appState: AppState) { // 측정 state var isMeasuring by remember { mutableStateOf(true) } // 시작 시 자동 측정 - var autoCapture by remember { mutableStateOf(true) } // 매 사이클 자동 저장 + // autoCapture는 항상 true — 토글 UI 제거됨 (회의 결정) + val autoCapture = true var cycleCount by remember { mutableIntStateOf(0) } var capturedCount by remember { mutableIntStateOf(0) } var lastChannels by remember { mutableStateOf>(emptyList()) } @@ -229,44 +229,6 @@ fun ClinicalLiveView(appState: AppState) { Text(if (isMeasuring) "Pause" else "Resume", color = Color.White, fontWeight = FontWeight.SemiBold) } - // Manual Capture (Auto OFF일 때 의미 있음) - Button( - onClick = { - if (lastChannels.isNotEmpty()) { - ClinicalSessionStore.addCycle(lastChannels, lastImu) - val rawADC = lastChannels.sortedBy { it.channel }.map { it.buffer } - AdcCsvLogger.log(rawADC, null) - if (lastImu.isNotEmpty()) ImuCsvLogger.log(lastImu) - capturedCount++ - Toast.makeText(context, "Captured #${capturedCount}", - Toast.LENGTH_SHORT).show() - } - }, - enabled = lastChannels.isNotEmpty(), - modifier = Modifier.weight(1f).height(48.dp), - colors = ButtonDefaults.buttonColors(containerColor = MlPrimary) - ) { - Icon(Icons.Default.Save, null, tint = Color.White) - Spacer(modifier = Modifier.width(4.dp)) - Text("Capture", color = Color.White, fontWeight = FontWeight.SemiBold) - } - } - - Spacer(modifier = Modifier.height(4.dp)) - - // 자동 캡쳐 토글 - Row( - modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Switch( - checked = autoCapture, - onCheckedChange = { autoCapture = it }, - colors = SwitchDefaults.colors(checkedTrackColor = MlPrimary) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text("Auto Capture (매 사이클 자동 저장)", - fontSize = 12.sp, color = MlSecondaryText) } Spacer(modifier = Modifier.height(8.dp)) @@ -344,22 +306,20 @@ private fun SixChannelGrid( Color(0xFF1976D2), Color(0xFF388E3C), Color(0xFFE64A19), Color(0xFF7B1FA2), Color(0xFF00838F), Color(0xFFD81B60), ) - Column(modifier = modifier) { - for (row in 0 until 2) { - Row(modifier = Modifier.fillMaxWidth()) { - for (col in 0 until 3) { - val ch = row * 3 + col - val data = channels.find { it.channel == ch } - Box(modifier = Modifier.weight(1f).padding(2.dp)) { - ChannelChart( - channelIdx = ch, - buffer = data?.buffer ?: emptyList(), - color = channelColors[ch], - walls = walls.getOrNull(ch), - ) - } - } - } + // 회의 결정: 1열 6행 세로 일렬 — 각 채널이 화면 width 가득. + // 외부 부모 Column이 이미 verticalScroll을 가지므로 여기선 nested scroll 피함. + Column( + modifier = modifier, + verticalArrangement = Arrangement.spacedBy(4.dp) + ) { + for (ch in 0 until 6) { + val data = channels.find { it.channel == ch } + ChannelChart( + channelIdx = ch, + buffer = data?.buffer ?: emptyList(), + color = channelColors[ch], + walls = walls.getOrNull(ch), + ) } } }