UI: 설정 패널 폰/태블릿 자동 분기 — fontScale 활용
태블릿 시연용으로 키운 28sp가 폰에서 곱창나는 문제 해결. 이미 코드에 정의된 fontScale = (screenWidth / 360f).coerceIn(1.0, 1.8)를 활용해 자동 분기. - 폰(360dp): 14sp × 1.0 = 14sp (원본) - 태블릿(648dp+): 14sp × 1.8 = 25.2sp (시연 시인성) - HorizontalDivider padding: 태블릿(≥600dp)에서만 vertical=12dp 변경: - showSettings 블록에 isTablet/labelSize/rowSpacing/dividerPadding 변수 도입 - 9개 라벨 + 일부 값 fontSize = 14.sp → labelSize - 9개 HorizontalDivider에 dividerPadding 적용 - Column spacedBy 6.dp → rowSpacing (폰 6dp, 태블릿 ~10dp) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+27
-23
@@ -1307,17 +1307,22 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
.align(Alignment.TopCenter)
|
.align(Alignment.TopCenter)
|
||||||
.shadow(12.dp, RoundedCornerShape(16.dp))
|
.shadow(12.dp, RoundedCornerShape(16.dp))
|
||||||
) {
|
) {
|
||||||
|
// 폰/태블릿 자동 분기 — fontScale은 360dp 기준 1.0~1.8 (line 118 정의)
|
||||||
|
val isTablet = screenWidth >= 600
|
||||||
|
val labelSize = (14 * fontScale).sp
|
||||||
|
val rowSpacing = (6 * fontScale).dp
|
||||||
|
val dividerPadding = if (isTablet) 12.dp else 0.dp
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
.verticalScroll(rememberScrollState()), // Charles: dev panel 길어져도 Save 도달
|
.verticalScroll(rememberScrollState()), // Charles: dev panel 길어져도 Save 도달
|
||||||
verticalArrangement = Arrangement.spacedBy(6.dp),
|
verticalArrangement = Arrangement.spacedBy(rowSpacing),
|
||||||
) {
|
) {
|
||||||
// Max Volume
|
// Max Volume
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text("Bladder Capacity", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
Text("Bladder Capacity", fontSize = labelSize, fontWeight = FontWeight.SemiBold)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
Text("${appState.piezoSettings.maxVolume} mL", fontSize = 14.sp, fontWeight = FontWeight.Bold, color = MlPrimary)
|
Text("${appState.piezoSettings.maxVolume} mL", fontSize = labelSize, fontWeight = FontWeight.Bold, color = MlPrimary)
|
||||||
}
|
}
|
||||||
Slider(
|
Slider(
|
||||||
value = appState.piezoSettings.maxVolume.toFloat(),
|
value = appState.piezoSettings.maxVolume.toFloat(),
|
||||||
@@ -1329,12 +1334,12 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
|
|
||||||
// Charles 833c110: Ant Offset 개발자 입력 (BV 계산 시 전위벽 mm 보정, 0~20mm)
|
// Charles 833c110: Ant Offset 개발자 입력 (BV 계산 시 전위벽 mm 보정, 0~20mm)
|
||||||
if (appState.isDevMode) {
|
if (appState.isDevMode) {
|
||||||
HorizontalDivider()
|
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
||||||
var antOffsetText by remember {
|
var antOffsetText by remember {
|
||||||
mutableStateOf(appState.piezoSettings.antOffsetMm.toString())
|
mutableStateOf(appState.piezoSettings.antOffsetMm.toString())
|
||||||
}
|
}
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text("Ant Offset", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
Text("Ant Offset", fontSize = labelSize, fontWeight = FontWeight.SemiBold)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = antOffsetText,
|
value = antOffsetText,
|
||||||
@@ -1356,14 +1361,13 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
||||||
HorizontalDivider()
|
|
||||||
|
|
||||||
// Catheterization Threshold
|
// Catheterization Threshold
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text("Catheter Threshold", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
Text("Catheter Threshold", fontSize = labelSize, fontWeight = FontWeight.SemiBold)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
Text("Level ${appState.bladderLevel.catheterizationThreshold}", fontSize = 14.sp, fontWeight = FontWeight.Bold, color = MlPrimary)
|
Text("Level ${appState.bladderLevel.catheterizationThreshold}", fontSize = labelSize, fontWeight = FontWeight.Bold, color = MlPrimary)
|
||||||
}
|
}
|
||||||
Slider(
|
Slider(
|
||||||
value = appState.bladderLevel.catheterizationThreshold.toFloat(),
|
value = appState.bladderLevel.catheterizationThreshold.toFloat(),
|
||||||
@@ -1375,13 +1379,13 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
|
|
||||||
// ── 개발자 전용 설정 ──
|
// ── 개발자 전용 설정 ──
|
||||||
if (appState.isDevMode) {
|
if (appState.isDevMode) {
|
||||||
HorizontalDivider()
|
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
||||||
|
|
||||||
// Low Echo Threshold (Otsu / manual)
|
// Low Echo Threshold (Otsu / manual)
|
||||||
var otsuEnabled by remember { mutableStateOf(analyzer.useAdaptiveThreshold) }
|
var otsuEnabled by remember { mutableStateOf(analyzer.useAdaptiveThreshold) }
|
||||||
var currentThreshold by remember { mutableStateOf(GreenZoneConstants.lowEchoAmp) }
|
var currentThreshold by remember { mutableStateOf(GreenZoneConstants.lowEchoAmp) }
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text("Threshold", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
Text("Threshold", fontSize = labelSize, fontWeight = FontWeight.SemiBold)
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
Text(
|
Text(
|
||||||
if (otsuEnabled) "Otsu: ${"%.0f".format(analyzer.lastOtsuThreshold)}" else "${"%.0f".format(currentThreshold)}",
|
if (otsuEnabled) "Otsu: ${"%.0f".format(analyzer.lastOtsuThreshold)}" else "${"%.0f".format(currentThreshold)}",
|
||||||
@@ -1405,12 +1409,12 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalDivider()
|
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
||||||
|
|
||||||
// DPS
|
// DPS
|
||||||
var dpsText by remember { mutableStateOf("%.3f".format(PiezoHW.distancePerSample)) }
|
var dpsText by remember { mutableStateOf("%.3f".format(PiezoHW.distancePerSample)) }
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text("DPS", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
Text("DPS", fontSize = labelSize, fontWeight = FontWeight.SemiBold)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = dpsText,
|
value = dpsText,
|
||||||
@@ -1422,12 +1426,12 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalDivider()
|
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
||||||
|
|
||||||
// Detection Method A/B/C
|
// Detection Method A/B/C
|
||||||
var selectedMethod by remember { mutableStateOf(com.example.medilightv2android.managers.GreenZoneConstants.detectionMethod) }
|
var selectedMethod by remember { mutableStateOf(com.example.medilightv2android.managers.GreenZoneConstants.detectionMethod) }
|
||||||
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
|
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text("Detection", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
Text("Detection", fontSize = labelSize, fontWeight = FontWeight.SemiBold)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
val methods = listOf(
|
val methods = listOf(
|
||||||
com.example.medilightv2android.managers.DetectionMethod.METHOD_A to "A",
|
com.example.medilightv2android.managers.DetectionMethod.METHOD_A to "A",
|
||||||
@@ -1454,12 +1458,12 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalDivider()
|
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
||||||
|
|
||||||
// BV Method (Frustum / V41)
|
// BV Method (Frustum / V41)
|
||||||
var selectedBvMethod by remember { mutableStateOf(com.example.medilightv2android.managers.GreenZoneConstants.bvMethod) }
|
var selectedBvMethod by remember { mutableStateOf(com.example.medilightv2android.managers.GreenZoneConstants.bvMethod) }
|
||||||
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
|
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text("BV", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
Text("BV", fontSize = labelSize, fontWeight = FontWeight.SemiBold)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
val bvMethods = listOf(
|
val bvMethods = listOf(
|
||||||
com.example.medilightv2android.managers.BvMethod.FRUSTUM to "Frustum",
|
com.example.medilightv2android.managers.BvMethod.FRUSTUM to "Frustum",
|
||||||
@@ -1485,23 +1489,23 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalDivider()
|
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
||||||
|
|
||||||
// SG Filter
|
// SG Filter
|
||||||
var sgEnabled by remember { mutableStateOf(analyzer.useSgFilter) }
|
var sgEnabled by remember { mutableStateOf(analyzer.useSgFilter) }
|
||||||
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
|
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text("SG Filter", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
Text("SG Filter", fontSize = labelSize, fontWeight = FontWeight.SemiBold)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
Switch(checked = sgEnabled, onCheckedChange = { sgEnabled = it; analyzer.useSgFilter = it },
|
Switch(checked = sgEnabled, onCheckedChange = { sgEnabled = it; analyzer.useSgFilter = it },
|
||||||
colors = SwitchDefaults.colors(checkedTrackColor = MlPrimary))
|
colors = SwitchDefaults.colors(checkedTrackColor = MlPrimary))
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalDivider()
|
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
||||||
|
|
||||||
// Post Max Index (바닥반사 무시 경계)
|
// Post Max Index (바닥반사 무시 경계)
|
||||||
var postMaxVal by remember { mutableStateOf(GreenZoneConstants.postMaxIdx.toFloat()) }
|
var postMaxVal by remember { mutableStateOf(GreenZoneConstants.postMaxIdx.toFloat()) }
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text("Post Max", fontSize = 14.sp, fontWeight = FontWeight.SemiBold)
|
Text("Post Max", fontSize = labelSize, fontWeight = FontWeight.SemiBold)
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
Text("${postMaxVal.toInt()} / 100", fontSize = 13.sp, fontWeight = FontWeight.Bold, color = MlPrimary)
|
Text("${postMaxVal.toInt()} / 100", fontSize = 13.sp, fontWeight = FontWeight.Bold, color = MlPrimary)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
@@ -1515,7 +1519,7 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalDivider()
|
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
||||||
|
|
||||||
// Disconnect
|
// Disconnect
|
||||||
var showDisconnectConfirm by remember { mutableStateOf(false) }
|
var showDisconnectConfirm by remember { mutableStateOf(false) }
|
||||||
@@ -1545,7 +1549,7 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
HorizontalDivider()
|
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
// Version (BuildConfig.VERSION_NAME) — read-only
|
// Version (BuildConfig.VERSION_NAME) — read-only
|
||||||
|
|||||||
Reference in New Issue
Block a user