Pith - wedge_android
wedge_android/app/src/main/java/com/vgmlr/wedge/WedgeSettings.kt [9.1 kb]
Modified: 19:18:28 63 026 (21 May 026)
9 Days Ago
package com.vgmlr.wedge

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.launch
import kotlinx.coroutines.delay

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsView(prefs: PreferenceManager, onBack: () -> Unit) {
    val context = LocalContext.current
    val scope = rememberCoroutineScope()
    val editorBg by prefs.bgColor.collectAsState(WedgeConfig.BG_COLOR_DEFAULT)
    val editorTxt by prefs.textColor.collectAsState(WedgeConfig.TEXT_COLOR_DEFAULT)

    val aTxt by prefs.textColor.collectAsState(WedgeConfig.TEXT_COLOR_DEFAULT)
    val aBg by prefs.bgColor.collectAsState(WedgeConfig.BG_COLOR_DEFAULT)
    val aWTxt by prefs.widgetTextColor.collectAsState(WedgeConfig.WIDGET_TEXT_COLOR_DEFAULT)
    val aWBg by prefs.widgetBgColor.collectAsState(WedgeConfig.WIDGET_BG_COLOR_DEFAULT)
    val aESize by prefs.editorFontSize.collectAsState(WedgeConfig.FONT_SIZE_DEFAULT)
    val aWSize by prefs.widgetFontSize.collectAsState(WedgeConfig.WIDGET_FONT_SIZE_DEFAULT)
    val aLHeight by prefs.lineHeight.collectAsState(WedgeConfig.LINE_HEIGHT_DEFAULT)
    val aBColor by prefs.boldColor.collectAsState(WedgeConfig.BOLD_COLOR_DEFAULT)
    val aIncognito by prefs.incognitoMode.collectAsState(false)

    var tTxt by remember(aTxt) { mutableStateOf(aTxt) }
    var tBg by remember(aBg) { mutableStateOf(aBg) }
    var tWTxt by remember(aWTxt) { mutableStateOf(aWTxt) }
    var tWBg by remember(aWBg) { mutableStateOf(aWBg) }
    var tBCol by remember(aBColor) { mutableStateOf(aBColor) }
    var tIncognito by remember(aIncognito) { mutableStateOf(aIncognito) }

    var tESize by remember(aESize) { mutableStateOf(aESize.toString()) }
    var tWSize by remember(aWSize) { mutableStateOf(aWSize.toString()) }
    var tLHeight by remember(aLHeight) { mutableStateOf(aLHeight.toString()) }

    val btnShape = RoundedCornerShape(7.dp)
    val btnColors = ButtonDefaults.buttonColors(containerColor = Color.Gray)

    var appSaved by remember { mutableStateOf(false) }
    
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("Settings", color = colorResource(id = R.color.title_color), fontSize = 18.sp) },
                colors = TopAppBarDefaults.topAppBarColors(containerColor = Color(0xFF486860)),
                navigationIcon = {
                    IconButton(onClick = onBack) { Icon(Icons.AutoMirrored.Filled.ArrowBack, null, tint = colorResource(id = R.color.title_color)) }
                }
            )
        }
    ) { p ->
        Column(Modifier.padding(p).fillMaxSize().imePadding().background(parseColor(editorBg)).padding(horizontal = 16.dp).verticalScroll(rememberScrollState())) {
            val labelCol = parseColor(editorTxt).copy(alpha = 0.6f)
            val fieldCol = OutlinedTextFieldDefaults.colors(
                focusedTextColor = parseColor(editorTxt),
                unfocusedTextColor = parseColor(editorTxt),
                focusedBorderColor = parseColor(editorTxt).copy(alpha = 0.5f),
                unfocusedBorderColor = parseColor(editorTxt).copy(alpha = 0.2f)
            )

            Spacer(Modifier.height(3.dp))
            val bCol = parseColor(editorTxt).copy(alpha = 0.2f)
            SetLabel("Text Color (Editor)", labelCol)
            SetField(tTxt, { tTxt = it }, WedgeConfig.TEXT_COLOR_DEFAULT, fieldCol, parseColor(tTxt), bCol)

            SetLabel("Ground Color (Editor)", labelCol)
            SetField(tBg, { tBg = it }, WedgeConfig.BG_COLOR_DEFAULT, fieldCol, parseColor(tBg), bCol)

            SetLabel("Font Size (Editor)", labelCol)
            OutlinedTextField(
                value = tESize,
                onValueChange = { if (it.all { char -> char.isDigit() || char == '.' }) tESize = it },
                modifier = Modifier.fillMaxWidth(),
                colors = fieldCol,
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
            )

            SetLabel("Text Color (Widget)", labelCol)
            SetField(tWTxt, { tWTxt = it }, WedgeConfig.WIDGET_TEXT_COLOR_DEFAULT, fieldCol, parseColor(tWTxt), bCol)

            SetLabel("Ground Color (Widget)", labelCol)
            SetField(tWBg, { tWBg = it }, WedgeConfig.WIDGET_BG_COLOR_DEFAULT, fieldCol, parseColor(tWBg), bCol)

            SetLabel("Font Size (Widget)", labelCol)
            OutlinedTextField(
                value = tWSize,
                onValueChange = { if (it.all { char -> char.isDigit() || char == '.' }) tWSize = it },
                modifier = Modifier.fillMaxWidth(),
                colors = fieldCol,
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
            )

            SetLabel("Line-Height", labelCol)
            OutlinedTextField(
                value = tLHeight,
                onValueChange = { if (it.all { char -> char.isDigit() || char == '.' }) tLHeight = it },
                modifier = Modifier.fillMaxWidth(),
                colors = fieldCol,
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal)
            )
            SetLabel("Focus Color", labelCol)
            SetField(tBCol, { tBCol = it }, WedgeConfig.BOLD_COLOR_DEFAULT, fieldCol, parseColor(tBCol), bCol)

            Spacer(Modifier.height(8.dp))
            Row(
                modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp),
                verticalAlignment = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.Start
            ) {
                Switch(
                    checked = tIncognito,
                    onCheckedChange = { tIncognito = it },
                    colors = SwitchDefaults.colors(
                        checkedThumbColor = Color.Gray,
                        checkedTrackColor = Color.Transparent,
                        checkedBorderColor = Color.Gray,
                        uncheckedThumbColor = Color.Gray,
                        uncheckedTrackColor = Color.Transparent,
                        uncheckedBorderColor = Color.Gray.copy(alpha = 0.5f)
                    )
                )
                Spacer(modifier = Modifier.width(12.dp))
                Text("Incognito Mode", color = labelCol, fontSize = 16.sp)
            }
            
            Spacer(Modifier.height(12.dp))
            Button(
                onClick = {
                    scope.launch {
                        prefs.setColors(tTxt, tBg, tWTxt, tWBg, tBCol)
                        prefs.setIncognito(tIncognito)
                        val finalE = tESize.toFloatOrNull()?.coerceIn(WedgeConfig.FONT_SIZE_MIN, WedgeConfig.FONT_SIZE_MAX) ?: WedgeConfig.FONT_SIZE_DEFAULT
                        val finalW = tWSize.toFloatOrNull()?.coerceIn(WedgeConfig.FONT_SIZE_MIN, WedgeConfig.FONT_SIZE_MAX) ?: WedgeConfig.WIDGET_FONT_SIZE_DEFAULT
                        val finalLH = tLHeight.toFloatOrNull() ?: WedgeConfig.LINE_HEIGHT_DEFAULT
                        prefs.setFontSettings(finalE, finalW, finalLH)
                        NoteWidgetProvider.triggerUpdate(context)
                        appSaved = true
                        delay(2000)
                        appSaved = false
                    }
                },
                modifier = Modifier.fillMaxWidth().height(48.dp),
                colors = btnColors,
                shape = btnShape
            ) {
                Text(if (appSaved) "Saved" else "Save", 
                    color = Color.Black, 
                    fontSize = 16.sp)
            }
            Spacer(Modifier.height(16.dp))
        }
    }
}

@Composable
fun SetLabel(text: String, color: Color) {
    Text(text, color = color, fontSize = 12.sp, fontWeight = FontWeight.Bold, modifier = Modifier.padding(top = 8.dp, bottom = 2.dp))
}

@Composable
fun SetField(value: String, onValueChange: (String) -> Unit, placeholder: String, colors: TextFieldColors, preview: Color? = null, bCol: Color = Color.Transparent) {
    Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
        preview?.let {
            Box(Modifier.size(56.dp)
                .background(it, RoundedCornerShape(4.dp))
                .border(1.dp, bCol, RoundedCornerShape(4.dp))
            )
            Spacer(Modifier.width(12.dp))
        }
        OutlinedTextField(value = value, onValueChange = onValueChange, placeholder = { Text(placeholder) }, modifier = Modifier.weight(1f), singleLine = true, colors = colors)
    }
}
Updates
Shim - Android 70.026.1
Wedge - Linux 68.026.1
Wedge - Android 68.026.1
Taper - Linux 64.026.1
Ayh Extension - Chrome 63.026.1
Dev
TVShow (227) 'CSA'
TVShow (228) 'APT'
TVProgram (83) 'BXT'
Miter Update(s)
Shim (Dictation)

Menu
Calendar
Project Tin (024/029)
Miter
RSS Feed
User Avatar
@vgmlr
=SUM(parts)