1 Commits

Author SHA1 Message Date
areumwoo
1fc9640e38 Gradient 슬라이더 계산 로직 수정 2026-03-02 16:27:04 +09:00
5 changed files with 21 additions and 90 deletions

View File

@@ -88,7 +88,4 @@ interface Preference {
suspend fun getPowerSupplySerialListFromPreference(): Flow<List<String>>
/////
suspend fun saveInfoChartLineStates(states: Map<String, Boolean>)
suspend fun getInfoChartLineStates(): Flow<Map<String, Boolean>>
}
}

View File

@@ -68,9 +68,6 @@ class PreferenceRepository(private val context: Context) : Preference {
val PRODUCT_SERIAL = stringPreferencesKey("PRODUCT_SERIAL")
val LASER_HAND_SERIAL = stringPreferencesKey("LASER_HAND_SERIAL")
val POWER_SUPPLY_SERIAL = stringPreferencesKey("POWER_SUPPLY_SERIAL")
// InfoScreen Chart Checkboxes
val INFO_CHART_LINE_STATES = stringPreferencesKey("INFO_CHART_LINE_STATES")
}
override suspend fun clearAllPreferences() {
@@ -562,31 +559,4 @@ class PreferenceRepository(private val context: Context) : Preference {
emit(listOf("B", "U", "O", "C", "L", "D"))
}
}
override suspend fun saveInfoChartLineStates(states: Map<String, Boolean>) {
try {
val stateJson = gson.toJson(states)
context.datastore.edit { preferences ->
preferences[INFO_CHART_LINE_STATES] = stateJson
}
} catch (e: Exception) {
Timber.e(e, "Failed to serialize INFO_CHART_LINE_STATES to JSON.")
}
}
override suspend fun getInfoChartLineStates(): Flow<Map<String, Boolean>> {
return context.datastore.data.map { preferences ->
preferences[INFO_CHART_LINE_STATES]
}.distinctUntilChanged().map { jsonString ->
if (!jsonString.isNullOrBlank()) {
val type = object : TypeToken<Map<String, Boolean>>() {}.type
gson.fromJson<Map<String, Boolean>>(jsonString, type) ?: emptyMap()
} else {
emptyMap()
}
}.catch { e ->
Timber.e(e, "Failed to get or parse INFO_CHART_LINE_STATES. Emitting default.")
emit(emptyMap())
}
}
}
}

View File

@@ -334,7 +334,7 @@ fun DcdSettingPopup(
modifier = Modifier
.fillMaxHeight()
.size(40.px.dp, 210.px.dp),
chargeRate = gasChargeRate.toInt()
chargeRate = gasChargeRate
)
// Icon

View File

@@ -28,14 +28,26 @@ import com.laseroptek.raman.ui.screens.main.MainViewModel
import com.laseroptek.raman.utils.DefaultDispatcherProvider
import com.laseroptek.raman.utils.ext.px
import timber.log.Timber
import kotlin.math.abs
import kotlin.math.ceil
@Composable
fun GradientSlider(
modifier: Modifier = Modifier,
chargeRate: Int = 0, // Value from (0 .. 100)
chargeRate: Float = 0f,
) {
val chargeIndex = ((chargeRate.coerceIn(0, 100) + 4) / 5).toInt() // 0..19
val normalizedRate = chargeRate.coerceIn(0f, 100f)
val bucket = normalizedRate / 5f
val remainder = normalizedRate % 5f
val isExactMultiple = abs(remainder) < 0.0001f
val chargeIndex = when {
normalizedRate == 0f -> -1
isExactMultiple -> (bucket - 1f).toInt().coerceAtLeast(-1)
else -> (ceil(bucket.toDouble()).toInt() - 1)
}.coerceIn(-1, 19)
Timber.d("chargeRate: $chargeRate, chargeIndex: $chargeIndex")
Box(
@@ -103,6 +115,6 @@ fun GradientSliderPreview(
//mainViewModel = mainViewModel
modifier = Modifier
.size(40.px.dp, 210.px.dp),
chargeRate = 20
chargeRate = 20f
)
}

View File

@@ -1,14 +1,10 @@
package com.laseroptek.raman.ui.screens.info
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import com.laseroptek.raman.repository.PreferenceRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@@ -29,13 +25,10 @@ data class ChartUiState(
val chamber2State: Boolean = true,
val basePlateState: Boolean = true,
val waterState: Boolean = true,
) {
companion object
}
)
@HiltViewModel
class InfoViewModel @Inject constructor(
private val preferenceRepository: PreferenceRepository,
) : ViewModel() {
// This is the single source of truth for the checkbox states.
@@ -46,7 +39,7 @@ class InfoViewModel @Inject constructor(
fun toggleLine(line: ChartLine) {
// .update is a thread-safe way to update the state.
_chartUiState.update { currentState ->
val updatedState = when (line) {
when (line) {
ChartLine.INT_TEMP -> currentState.copy(intTempState = !currentState.intTempState)
ChartLine.EXT_TEMP -> currentState.copy(extTempState = !currentState.extTempState)
ChartLine.INT_HUMIDITY -> currentState.copy(intHumidityState = !currentState.intHumidityState)
@@ -57,51 +50,10 @@ class InfoViewModel @Inject constructor(
ChartLine.BASE_PLATE -> currentState.copy(basePlateState = !currentState.basePlateState)
ChartLine.WATER -> currentState.copy(waterState = !currentState.waterState)
}
persistChartUiState(updatedState)
updatedState
}
}
init {
Timber.d("InfoViewModel init")
viewModelScope.launch {
preferenceRepository.getInfoChartLineStates().collectLatest { savedStates ->
if (savedStates.isEmpty()) return@collectLatest
_chartUiState.update { ChartUiState.fromPreference(savedStates) }
}
}
}
private fun persistChartUiState(state: ChartUiState) {
viewModelScope.launch {
preferenceRepository.saveInfoChartLineStates(state.toPreferenceMap())
}
}
}
private fun ChartUiState.toPreferenceMap(): Map<String, Boolean> = mapOf(
ChartLine.INT_TEMP.name to intTempState,
ChartLine.EXT_TEMP.name to extTempState,
ChartLine.INT_HUMIDITY.name to intHumidityState,
ChartLine.EXT_HUMIDITY.name to extHumidityState,
ChartLine.KTP.name to ktpState,
ChartLine.CHAMBER1.name to chamber1State,
ChartLine.CHAMBER2.name to chamber2State,
ChartLine.BASE_PLATE.name to basePlateState,
ChartLine.WATER.name to waterState,
)
private fun ChartUiState.Companion.fromPreference(savedStates: Map<String, Boolean>): ChartUiState {
val defaults = ChartUiState()
return ChartUiState(
intTempState = savedStates[ChartLine.INT_TEMP.name] ?: defaults.intTempState,
extTempState = savedStates[ChartLine.EXT_TEMP.name] ?: defaults.extTempState,
intHumidityState = savedStates[ChartLine.INT_HUMIDITY.name] ?: defaults.intHumidityState,
extHumidityState = savedStates[ChartLine.EXT_HUMIDITY.name] ?: defaults.extHumidityState,
ktpState = savedStates[ChartLine.KTP.name] ?: defaults.ktpState,
chamber1State = savedStates[ChartLine.CHAMBER1.name] ?: defaults.chamber1State,
chamber2State = savedStates[ChartLine.CHAMBER2.name] ?: defaults.chamber2State,
basePlateState = savedStates[ChartLine.BASE_PLATE.name] ?: defaults.basePlateState,
waterState = savedStates[ChartLine.WATER.name] ?: defaults.waterState,
)
}
}