Skip to content

Commit

Permalink
new theming part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
nift4 committed Aug 2, 2024
1 parent e6f712e commit b73597f
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 59 deletions.
4 changes: 2 additions & 2 deletions app/src/main/java/org/andbootmgr/app/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ fun AppContent(vm: MainActivityState, view: @Composable (PaddingValues) -> Unit)
scope.launch { drawerState.open() }
})
})
}, content = view, floatingActionButton = fab)
}, content = view, floatingActionButton = fab, modifier = Modifier.fillMaxWidth())
}
)
}
Expand All @@ -299,7 +299,7 @@ fun AppContent(vm: MainActivityState, view: @Composable (PaddingValues) -> Unit)

@Composable
private fun NavGraph(vm: MainActivityState, it: PaddingValues) {
NavHost(navController = vm.navController!!, startDestination = "start", modifier = Modifier.padding(it)) {
NavHost(navController = vm.navController!!, startDestination = "start", modifier = Modifier.padding(it).fillMaxSize()) {
composable("start") {
vm.currentNav = "start"
Start(vm)
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/java/org/andbootmgr/app/Simulator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.andbootmgr.app

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.os.Looper
Expand Down Expand Up @@ -65,6 +66,7 @@ class Simulator : AppCompatActivity() {
}
firstTime = false
}
canvas.drawColor(Color.BLACK)
canvas.drawBitmap(this@Simulator.bitmap, 0f, 0f, null)
}

Expand All @@ -82,12 +84,12 @@ class Simulator : AppCompatActivity() {
}
l.addView(v, LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT))
WindowCompat.setDecorFitsSystemWindows(window, false)
setContentView(l)
WindowCompat.setDecorFitsSystemWindows(window, true)
WindowInsetsControllerCompat(window, l).apply {
systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
hide(WindowInsetsCompat.Type.systemBars())
}
setContentView(l)
}

private fun blockCount(): Long {
Expand Down
134 changes: 90 additions & 44 deletions app/src/main/java/org/andbootmgr/app/Themes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,39 @@ import android.content.Intent
import android.widget.Toast
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.SnapshotStateMap
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.navigation.compose.rememberNavController
import org.andbootmgr.app.util.ConfigFile
import java.io.File
import java.util.Random

/*
uint32_t win_bg_color;
Expand All @@ -42,7 +53,8 @@ import java.util.Random
uint32_t button_unselected_text_color;
uint32_t button_selected_color;
uint32_t button_selected_text_color;
uint8_t button_radius;
uint8_t button_unselected_radius;
uint8_t button_selected_radius;
bool button_grow_default;
uint8_t button_border_unselected_size;
uint32_t button_border_unselected_color;
Expand All @@ -65,34 +77,37 @@ fun Themes(vm: MainActivityState) {
}
}
}
val e = remember { mutableStateMapOf<Long, Boolean>() }
val col = { it: String -> it.startsWith("0x") && (it.toIntOrNull(16) ?: -1) in 0..0xffffff }
Column {
ConfigTextField(c, e, stringResource(id = R.string.win_bg_color), "win_bg_color", validate = col)
ConfigTextField(c, e, stringResource(id = R.string.win_radius), "win_radius") { it.toShortOrNull() != null }
ConfigTextField(c, e, stringResource(id = R.string.win_border_size), "win_border_size") { it.toShortOrNull() != null }
ConfigTextField(c, e, stringResource(id = R.string.win_border_color), "win_border_color", validate = col)
ConfigTextField(c, e, stringResource(id = R.string.list_bg_color), "list_bg_color", validate = col)
ConfigTextField(c, e, stringResource(id = R.string.list_radius), "list_radius") { it.toShortOrNull() != null }
ConfigTextField(c, e, stringResource(id = R.string.list_border_size), "list_border_size") { it.toShortOrNull() != null }
ConfigTextField(c, e, stringResource(id = R.string.list_border_color), "list_border_color", validate = col)
ConfigTextField(c, e, stringResource(id = R.string.global_font_size), "global_font_size") { it.toIntOrNull() != null }
ConfigTextField(c, e, stringResource(id = R.string.global_font_name), "global_font_name") { true /* should check if exists later */ }
ConfigTextField(c, e, stringResource(id = R.string.button_unselected_color), "button_unselected_color", validate = col)
ConfigTextField(c, e, stringResource(id = R.string.button_unselected_text_color), "button_unselected_text_color", validate = col)
ConfigTextField(c, e, stringResource(id = R.string.button_unselected_size), "button_unselected_size") { it.toIntOrNull() != null }
ConfigTextField(c, e, stringResource(id = R.string.button_selected_color), "button_selected_color", validate = col)
ConfigTextField(c, e, stringResource(id = R.string.button_selected_text_color), "button_selected_text_color", validate = col)
ConfigTextField(c, e, stringResource(id = R.string.button_selected_size), "button_selected_size") { it.toIntOrNull() != null }
ConfigTextField(c, e, stringResource(id = R.string.button_radius), "button_radius") { it.toShortOrNull() != null }
ConfigTextField(c, e, stringResource(id = R.string.button_grow_default), "button_grow_default") { it.toBooleanStrictOrNull() != null } // TODO checkbox
ConfigTextField(c, e, stringResource(id = R.string.button_border_unselected_color), "button_border_unselected_color", validate = col)
ConfigTextField(c, e, stringResource(id = R.string.button_border_unselected_size), "button_border_unselected_size") { it.toIntOrNull() != null }
ConfigTextField(c, e, stringResource(id = R.string.button_border_selected_color), "button_border_selected_color", validate = col)
ConfigTextField(c, e, stringResource(id = R.string.button_border_selected_size), "button_border_selected_size") { it.toIntOrNull() != null }


Button(onClick = {
val e = remember { mutableStateMapOf<String, Boolean>() }
var resetCounter by remember { mutableIntStateOf(0) }
val col = { it: String -> it.startsWith("0x") && it.length == 8 && (it.substring(2).toIntOrNull(16) ?: -1) in 0..0xffffff }
val configs = listOf(
Config(stringResource(id = R.string.win_bg_color), "win_bg_color", "0x000000", col),
Config(stringResource(id = R.string.win_radius), "win_radius", "0") { it.toShortOrNull() != null },
Config(stringResource(id = R.string.win_border_size), "win_border_size", "0") { it.toShortOrNull() != null },
Config(stringResource(id = R.string.win_border_color), "win_border_color", "0xffffff", col),
Config(stringResource(id = R.string.list_bg_color), "list_bg_color", "0x000000", col),
Config(stringResource(id = R.string.list_radius), "list_radius", "0") { it.toShortOrNull() != null },
Config(stringResource(id = R.string.list_border_size), "list_border_size", "0") { it.toShortOrNull() != null },
Config(stringResource(id = R.string.list_border_color), "list_border_color", "0xffffff", col),
Config(stringResource(id = R.string.global_font_size), "global_font_size", "0") { it.toIntOrNull() != null },
Config(stringResource(id = R.string.global_font_name), "global_font_name", "") { true /* should check if exists later */ },
Config(stringResource(id = R.string.button_unselected_color), "button_unselected_color", "0x000000", col),
Config(stringResource(id = R.string.button_unselected_text_color), "button_unselected_text_color","0xffffff", col),
Config(stringResource(id = R.string.button_unselected_radius), "button_unselected_radius", "0") { it.toShortOrNull() != null },
Config(stringResource(id = R.string.button_selected_color), "button_selected_color", "0xff9800", col),
Config(stringResource(id = R.string.button_selected_text_color), "button_selected_text_color", "0x000000", col),
Config(stringResource(id = R.string.button_selected_radius), "button_selected_radius", "0") { it.toShortOrNull() != null },
Config(stringResource(id = R.string.button_grow_default), "button_grow_default", "true") { it.toBooleanStrictOrNull() != null }, // TODO checkbox
Config(stringResource(id = R.string.button_border_unselected_color), "button_border_unselected_color", "0xffffff", col),
Config(stringResource(id = R.string.button_border_unselected_size), "button_border_unselected_size", "1") { it.toIntOrNull() != null },
Config(stringResource(id = R.string.button_border_selected_color), "button_border_selected_color", "0xffffff", col),
Config(stringResource(id = R.string.button_border_selected_size), "button_border_selected_size", "1") { it.toIntOrNull() != null }
)
val state = rememberScrollState()
Column(modifier = Modifier
.verticalScroll(state)
.fillMaxSize()) {
val saveChanges = {
if (e.containsValue(false))
Toast.makeText(
vm.activity!!,
Expand All @@ -111,40 +126,71 @@ fun Themes(vm: MainActivityState) {
.show()
}
}
}, enabled = !e.containsValue(false)) {
Text(stringResource(R.string.save_changes))
}
Button(onClick = {
vm.activity!!.startActivity(Intent(vm.activity!!, Simulator::class.java).apply {
putExtra("sdCardBlock", vm.deviceInfo!!.bdev)
})
}) {
Text(text = stringResource(id = R.string.simulator))
Card(modifier = Modifier
.fillMaxWidth()
.padding(10.dp)) {
Column(modifier = Modifier.padding(10.dp)) {
Text(stringResource(id = R.string.simulator_info))
Button(onClick = {
saveChanges()
// sync does not work :/
vm.logic!!.unmountBootset()
vm.logic!!.mountBootset(vm.deviceInfo!!)
vm.activity!!.startActivity(Intent(vm.activity!!, Simulator::class.java).apply {
putExtra("sdCardBlock", vm.deviceInfo!!.bdev)
})
}) {
Text(text = stringResource(id = R.string.simulator))
}
}
}
Row {
Button(onClick = saveChanges, enabled = !e.containsValue(false)) {
Text(stringResource(R.string.save_changes))
}
Button(onClick = {
for (cfg in configs) {
c[cfg.configKey] = cfg.default
}
resetCounter++
saveChanges()
}) {
Text(stringResource(R.string.reset))
}
}
for (cfg in configs) {
ConfigTextField(c, e, resetCounter, cfg.text, cfg.configKey, cfg.default, cfg.validate)
}
}
}

@Composable
private fun ConfigTextField(c: ConfigFile, e: SnapshotStateMap<Long, Boolean>, text: String, configKey: String, default: String = "", validate: (String) -> Boolean) {
val id = remember { Random().nextLong() }
var value by remember { mutableStateOf(c[configKey] ?: default) }
private fun ConfigTextField(c: ConfigFile, e: SnapshotStateMap<String, Boolean>, resetCounter: Int, text: String, configKey: String, default: String, validate: (String) -> Boolean) {
var value by remember(key1 = configKey, key2 = resetCounter) {
if (!c.has(configKey)) c[configKey] = default
mutableStateOf(c[configKey] ?: default)
}
TextField(
value = value,
onValueChange = {
value = it
c[configKey] = it.trim()
e[id] = validate(text)
e[configKey] = validate(it)
},
label = { Text(text) },
isError = !(e[id] ?: true)
isError = !(e[configKey] ?: true)
)
if (e[id] == false) {
if (e[configKey] == false) {
Text(stringResource(id = R.string.invalid_in), color = MaterialTheme.colorScheme.error)
} else {
Text("") // Budget spacer
}
}

private data class Config(val text: String, val configKey: String, val default: String,
val validate: (String) -> Boolean)

@Preview
@Composable
fun ThemePreview() {
Expand Down
7 changes: 4 additions & 3 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,8 @@
<string name="button_unselected_text_color">Button text color (unselected)</string>
<string name="button_selected_color">Button color (selected)</string>
<string name="button_selected_text_color">Button text color (selected)</string>
<string name="button_unselected_size">Button size (unselected)</string>
<string name="button_selected_size">Button size (selected)</string>
<string name="button_radius">Button radius</string>
<string name="button_unselected_radius">Button radius (unselected)</string>
<string name="button_selected_radius">Button radius (selected)</string>
<string name="button_grow_default">Grow buttons when selected</string>
<string name="button_border_unselected_color">Button border color (unselected)</string>
<string name="button_border_unselected_size">Button border size (unselected)</string>
Expand All @@ -254,4 +253,6 @@
<string name="list_radius">List radius</string>
<string name="list_border_size">List border size</string>
<string name="list_border_color">List border color</string>
<string name="simulator_info">Simulator is an accurate preview of the boot menu. You can use volume keys to navigate. Instead of pressing the power button, simply tap anywhere on the display.</string>
<string name="reset">Reset</string>
</resources>
14 changes: 11 additions & 3 deletions app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,28 @@
<resources xmlns:tools="http://schemas.android.com/tools">

<style name="AppTheme" parent="@style/Theme.Material3.DynamicColors.DayNight.NoActionBar">
<item name="android:forceDarkAllowed" tools:targetApi="q">false</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="o_mr1">shortEdges</item>
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorSecondary">@color/colorSecondary</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="aboutLibrariesStyle">@style/CustomAboutLibrariesStyle</item>
<item name="android:statusBarColor">@color/colorAccent</item>
</style>
<style name="Simulator" parent="@style/Theme.Material3.DynamicColors.DayNight.NoActionBar">
<item name="android:background">@color/black</item>
<style name="Simulator" parent="@style/AppTheme">
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:enforceNavigationBarContrast" tools:targetApi="q">false</item>
<item name="android:enforceStatusBarContrast" tools:targetApi="q">false</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:background">@color/red</item>
</style>

<color name="colorPrimary">#FE9200</color>
<color name="colorSecondary">#FE9200</color>
<color name="colorAccent" tools:ignore="UnusedResources">#FE9F11</color>
<color name="black">#000000</color>
<color name="red">#ff0000</color>

<style name="CustomAboutLibrariesStyle" parent="AppTheme">
<!-- AboutLibraries specific values -->
Expand Down
4 changes: 0 additions & 4 deletions app/src/main/res/values/themes.xml

This file was deleted.

0 comments on commit b73597f

Please sign in to comment.