184 lines
6.0 KiB
Kotlin
184 lines
6.0 KiB
Kotlin
package com.racingapp.pitlog.ui
|
|
|
|
import androidx.compose.foundation.layout.Arrangement
|
|
import androidx.compose.foundation.layout.Column
|
|
import androidx.compose.foundation.layout.ColumnScope
|
|
import androidx.compose.foundation.layout.PaddingValues
|
|
import androidx.compose.foundation.layout.Row
|
|
import androidx.compose.foundation.layout.RowScope
|
|
import androidx.compose.foundation.layout.WindowInsets
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
import androidx.compose.foundation.layout.ime
|
|
import androidx.compose.foundation.layout.navigationBars
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.foundation.layout.union
|
|
import androidx.compose.foundation.layout.widthIn
|
|
import androidx.compose.foundation.layout.windowInsetsPadding
|
|
import androidx.compose.foundation.rememberScrollState
|
|
import androidx.compose.foundation.verticalScroll
|
|
import androidx.compose.material3.Button
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.OutlinedTextField
|
|
import androidx.compose.material3.Surface
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.text.font.FontWeight
|
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
|
import androidx.compose.ui.text.input.KeyboardType
|
|
import androidx.compose.ui.text.style.TextAlign
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.compose.foundation.text.KeyboardOptions
|
|
import com.racingapp.pitlog.model.Corner
|
|
import com.racingapp.pitlog.model.TireSheet
|
|
import com.racingapp.pitlog.model.formatTemp
|
|
|
|
@Composable
|
|
fun PitScroll(
|
|
padding: PaddingValues,
|
|
content: @Composable ColumnScope.() -> Unit,
|
|
) {
|
|
Column(
|
|
modifier = Modifier
|
|
.fillMaxSize()
|
|
.padding(padding)
|
|
.verticalScroll(rememberScrollState()),
|
|
horizontalAlignment = Alignment.CenterHorizontally,
|
|
) {
|
|
Column(
|
|
modifier = Modifier
|
|
.widthIn(max = 640.dp)
|
|
.fillMaxWidth()
|
|
.padding(horizontal = 16.dp, vertical = 8.dp),
|
|
content = content,
|
|
)
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun PitActionButton(
|
|
text: String,
|
|
onClick: () -> Unit,
|
|
enabled: Boolean = true,
|
|
) {
|
|
Surface(color = MaterialTheme.colorScheme.background) {
|
|
Button(
|
|
onClick = onClick,
|
|
enabled = enabled,
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.windowInsetsPadding(WindowInsets.navigationBars.union(WindowInsets.ime))
|
|
.padding(16.dp),
|
|
) {
|
|
Text(text)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun SectionLabel(text: String) {
|
|
Text(
|
|
text = text,
|
|
style = MaterialTheme.typography.titleMedium,
|
|
color = MaterialTheme.colorScheme.primary,
|
|
modifier = Modifier.padding(top = 20.dp, bottom = 8.dp),
|
|
)
|
|
}
|
|
|
|
@Composable
|
|
fun NumberField(
|
|
label: String,
|
|
value: String,
|
|
onValue: (String) -> Unit,
|
|
modifier: Modifier = Modifier,
|
|
decimal: Boolean = true,
|
|
) {
|
|
OutlinedTextField(
|
|
value = value,
|
|
onValueChange = onValue,
|
|
label = { Text(label) },
|
|
singleLine = true,
|
|
keyboardOptions = KeyboardOptions(
|
|
keyboardType = if (decimal) KeyboardType.Decimal else KeyboardType.Number,
|
|
),
|
|
textStyle = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.SemiBold),
|
|
modifier = modifier,
|
|
)
|
|
}
|
|
|
|
@Composable
|
|
fun WordsField(
|
|
label: String,
|
|
value: String,
|
|
onValue: (String) -> Unit,
|
|
modifier: Modifier = Modifier,
|
|
placeholder: String = "",
|
|
isError: Boolean = false,
|
|
supportingText: String? = null,
|
|
capitalization: KeyboardCapitalization = KeyboardCapitalization.Words,
|
|
keyboardType: KeyboardType = KeyboardType.Text,
|
|
) {
|
|
OutlinedTextField(
|
|
value = value,
|
|
onValueChange = onValue,
|
|
label = { Text(label) },
|
|
placeholder = if (placeholder.isEmpty()) null else ({ Text(placeholder) }),
|
|
singleLine = true,
|
|
isError = isError,
|
|
supportingText = supportingText?.let { message -> { Text(message) } },
|
|
keyboardOptions = KeyboardOptions(capitalization = capitalization, keyboardType = keyboardType),
|
|
modifier = modifier
|
|
.fillMaxWidth()
|
|
.padding(top = 8.dp),
|
|
)
|
|
}
|
|
|
|
@Composable
|
|
fun TireHeatLines(sheet: TireSheet) {
|
|
val corners = Corner.entries.filter { sheet.heatOf(it).any() }
|
|
if (corners.isEmpty()) return
|
|
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
|
|
Row(Modifier.fillMaxWidth()) {
|
|
Text(text = "", modifier = Modifier.weight(0.7f))
|
|
HeatCell("Inside", heading = true)
|
|
HeatCell("Middle", heading = true)
|
|
HeatCell("Outside", heading = true)
|
|
}
|
|
corners.forEach { corner ->
|
|
val heat = sheet.heatOf(corner)
|
|
Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
|
|
Text(
|
|
corner.short,
|
|
modifier = Modifier.weight(0.7f),
|
|
fontWeight = FontWeight.SemiBold,
|
|
)
|
|
HeatCell(formatTemp(heat.inside))
|
|
HeatCell(formatTemp(heat.middle))
|
|
HeatCell(formatTemp(heat.outside))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
private fun RowScope.HeatCell(value: String, heading: Boolean = false) {
|
|
Text(
|
|
value,
|
|
modifier = Modifier.weight(1f),
|
|
textAlign = TextAlign.End,
|
|
style = if (heading) MaterialTheme.typography.labelMedium else MaterialTheme.typography.titleMedium,
|
|
color = if (heading) MaterialTheme.colorScheme.onSurfaceVariant else MaterialTheme.colorScheme.onSurface,
|
|
)
|
|
}
|
|
|
|
@Composable
|
|
fun FieldRow(content: @Composable RowScope.() -> Unit) {
|
|
Row(
|
|
modifier = Modifier.fillMaxWidth(),
|
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
|
content = content,
|
|
)
|
|
}
|