Pith - stave
stave/app/src/main/kotlin/com/vgmlr/stave/StaveTheme.kt [4.0 kb]
Modified: 20:14:55 158 026 (24 Aug 026)
0 Days Ago
package com.vgmlr.stave

import android.content.Context
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Typography
import androidx.compose.material3.darkColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.Color
import androidx.core.content.edit
import androidx.core.graphics.toColorInt

@Composable
fun StaveTheme(
    themeManager: StaveThemeManager,
    content: @Composable () -> Unit
) {
    val colorScheme = darkColorScheme(
        primary = Color(0xFF486860),
        background = themeManager.backgroundColor.value,
        onBackground = themeManager.textColor.value,
        surface = themeManager.backgroundColor.value,
        onSurface = themeManager.textColor.value
    )

    MaterialTheme(
        colorScheme = colorScheme,
        typography = Typography(),
        content = content
    )
}

class StaveThemeManager(private val context: Context) {
    private val prefs = context.getSharedPreferences("stave_prefs", Context.MODE_PRIVATE)

    var backgroundColor = mutableStateOf(Color(context.getColor(R.color.background_color)))
    var textColor = mutableStateOf(Color(context.getColor(R.color.text_color)))
    var accentColor = mutableStateOf(Color(context.getColor(R.color.accent_color)))
    var fontSize = mutableFloatStateOf(15.5f)
    var lineSpacing = mutableFloatStateOf(0.2f)
    var isMonospace = mutableStateOf(false)
    var isNewestFirst = mutableStateOf(true)

    var hexBgColor = hexOf(context.getColor(R.color.background_color))
    var hexTextColor = hexOf(context.getColor(R.color.text_color))
    var hexAccentColor = hexOf(context.getColor(R.color.accent_color))

    init {
        refresh()
    }
    
    fun lineHeightSp(): Float = fontSize.floatValue * (LINE_HEIGHT + lineSpacing.floatValue)

    fun rowGapDp(): Float = fontSize.floatValue * lineSpacing.floatValue
    
    private fun getSafeString(key: String, default: String): String =
        prefs.getString(key, default) ?: default

    private fun formatHex(hex: String): String = if (hex.startsWith("#")) hex else "#$hex"
    private fun formatNum(num: String): String = num.replace(Regex("[^0-9.]"), "")

    fun saveTheme(
        bg: String,
        text: String,
        accent: String,
        mono: Boolean,
        size: String,
        newestFirst: Boolean
    ) {
        prefs.edit {
            putString("main_background", formatHex(bg))
            putString("main_color", formatHex(text))
            putString("accent_color", formatHex(accent))
            putBoolean("is_monospace", mono)
            putString("main_size", formatNum(size))
            putBoolean("newest_first", newestFirst)
        }
        refresh()
    }

    fun refresh() {
        val defaultBg = hexOf(context.getColor(R.color.background_color))
        val defaultText = hexOf(context.getColor(R.color.text_color))
        val defaultAccent = hexOf(context.getColor(R.color.accent_color))

        hexBgColor = getSafeString("main_background", defaultBg)
        hexTextColor = getSafeString("main_color", defaultText)
        hexAccentColor = getSafeString("accent_color", defaultAccent)

        backgroundColor.value = parse(hexBgColor, R.color.background_color)
        textColor.value = parse(hexTextColor, R.color.text_color)
        accentColor.value = parse(hexAccentColor, R.color.accent_color)

        isMonospace.value = prefs.getBoolean("is_monospace", false)
        isNewestFirst.value = prefs.getBoolean("newest_first", true)
        fontSize.floatValue = getSafeString("main_size", "15.5").toFloatOrNull() ?: 15.5f
        lineSpacing.floatValue = getSafeString("line_spacing", "0.2").toFloatOrNull() ?: 0.2f
    }

    private fun parse(hex: String, fallback: Int): Color =
        try { Color(hex.toColorInt()) } catch (_: Exception) { Color(context.getColor(fallback)) }

    private fun hexOf(argb: Int): String = "#%06X".format(0xFFFFFF and argb)

    companion object {
        const val LINE_HEIGHT = 1.35f
    }
}
Updates
Stave - Android 158.026
Kerf - Android 157.026
Kiln - Android 157.026
Wedge - Android 156.026
Whittle - Linux 155.026

Menu
Calendar
Project Tin (024/029)
Miter
RSS Feed
User Avatar
@vgmlr
=SUM(parts)
0.00237
257,432 (+42)