mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-14 14:02:44 +00:00
add generic reorder dialog and prelimiary toolbar pref screen
This commit is contained in:
parent
d61963453f
commit
ce37888985
9 changed files with 203 additions and 14 deletions
|
@ -114,6 +114,7 @@ dependencies {
|
|||
implementation("androidx.compose.ui:ui-tooling-preview")
|
||||
debugImplementation("androidx.compose.ui:ui-tooling")
|
||||
implementation("androidx.navigation:navigation-compose:2.8.5")
|
||||
implementation("sh.calvin.reorderable:reorderable:2.4.2")
|
||||
|
||||
// color picker for user-defined colors
|
||||
implementation("com.github.martin-stone:hsv-alpha-color-picker-android:3.1.0")
|
||||
|
|
|
@ -9,6 +9,7 @@ import androidx.compose.runtime.Composable
|
|||
import helium314.keyboard.settings.screens.createAboutPrefs
|
||||
import helium314.keyboard.settings.screens.createCorrectionPrefs
|
||||
import helium314.keyboard.settings.screens.createPreferencesPrefs
|
||||
import helium314.keyboard.settings.screens.createToolbarPrefs
|
||||
|
||||
class AllPrefs(context: Context) {
|
||||
private val list = createPrefDefs(context)
|
||||
|
@ -51,7 +52,7 @@ class PrefDef(
|
|||
}
|
||||
|
||||
private fun createPrefDefs(context: Context) = createAboutPrefs(context) +
|
||||
createCorrectionPrefs(context) + createPreferencesPrefs(context)
|
||||
createCorrectionPrefs(context) + createPreferencesPrefs(context) + createToolbarPrefs(context)
|
||||
|
||||
// todo: move somewhere else
|
||||
fun Context.getActivity(): ComponentActivity? {
|
||||
|
|
|
@ -14,10 +14,13 @@ import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
|||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
// todo
|
||||
// add reorder / enable dialog (maybe not as dialog?)
|
||||
// add reorder / enable dialog
|
||||
// reorder part is already done
|
||||
// more pref screens, and other super-custom things
|
||||
// consider IME insets when searching
|
||||
// improve performance when loading screens with many settings (lazyColumn?)
|
||||
// screens could have a lazy column of preferences and category separators, and the list has an if-setting-then-null for hiding
|
||||
// lazyColumn also has the key, this should be used! and must be unique
|
||||
// consider that stuff in composables can get called quite often on any changes -> use remember for things that are slow (maybe add test logging)
|
||||
|
||||
// later
|
||||
|
@ -29,7 +32,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
// rename some classes
|
||||
// split the preferences in allPrefs.createDefs into multiple files, this will get horribly long
|
||||
// maybe have sub-lists in the pref screens using the settings?
|
||||
// spdx headers everywhere
|
||||
// spdx headers everywhere (except DragDropColumn, which is from stackoverflow without explicit license)
|
||||
// changes to anything but the compose settings package should not be in the initial PR
|
||||
// commit them separately if possible
|
||||
// though some might be necessary
|
||||
|
@ -43,6 +46,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
// show as disabled -> users confused
|
||||
// show (but change will not do anything because another setting needs to be enabled first)
|
||||
// -> users confused, but probably better than the 2 above
|
||||
// adjust layout a little, there is too much empty space
|
||||
|
||||
// maybe later
|
||||
// weird problem with app sometimes closing on back, but that's related to "old" settings (don't care if all are removed)
|
||||
|
@ -69,6 +73,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
// another 300 kb when switching material2 to material3
|
||||
// ca 150 kb reduction when removing androidx.preference
|
||||
// -> too much, but still ok if we can get nicer preference stuff
|
||||
// meh, and using a TextField adds another 300 kb... huge chunks for sth that seems so small
|
||||
|
||||
class SettingsActivity2 : AppCompatActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private val prefs by lazy { DeviceProtectedUtils.getSharedPreferences(this) }
|
||||
|
|
|
@ -14,6 +14,7 @@ import helium314.keyboard.settings.screens.AboutScreen
|
|||
import helium314.keyboard.settings.screens.MainSettingsScreen
|
||||
import helium314.keyboard.settings.screens.PreferencesScreen
|
||||
import helium314.keyboard.settings.screens.TextCorrectionScreen
|
||||
import helium314.keyboard.settings.screens.ToolbarScreen
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
|
@ -48,6 +49,7 @@ fun SettingsNavHost(
|
|||
onClickAbout = { navController.navigate(SettingsDestination.About) },
|
||||
onClickTextCorrection = { navController.navigate(SettingsDestination.TextCorrection) },
|
||||
onClickPreferences = { navController.navigate(SettingsDestination.Preferences) },
|
||||
onClickToolbar = { navController.navigate(SettingsDestination.Toolbar) },
|
||||
onClickBack = ::goBack,
|
||||
)
|
||||
}
|
||||
|
@ -66,6 +68,11 @@ fun SettingsNavHost(
|
|||
onClickBack = ::goBack
|
||||
)
|
||||
}
|
||||
composable(SettingsDestination.Toolbar) {
|
||||
ToolbarScreen (
|
||||
onClickBack = ::goBack
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,6 +81,7 @@ object SettingsDestination {
|
|||
const val About = "about"
|
||||
const val TextCorrection = "text_correction"
|
||||
const val Preferences = "preferences"
|
||||
const val Toolbar = "toolbar"
|
||||
val navTarget = MutableStateFlow(Settings)
|
||||
|
||||
private val navScope = CoroutineScope(Dispatchers.Default)
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
package helium314.keyboard.settings.dialogs
|
||||
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.contentColorFor
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import helium314.keyboard.latin.R
|
||||
import sh.calvin.reorderable.ReorderableItem
|
||||
import sh.calvin.reorderable.rememberReorderableLazyListState
|
||||
|
||||
@Composable
|
||||
fun <T: Any> ReorderDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
onConfirmed: (List<T>) -> Unit,
|
||||
items: List<T>,
|
||||
getKey: (T) -> Any, // actually it's not "Any", but "anything that can be stored in a bundle"
|
||||
displayItem: @Composable (T) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
title: @Composable (() -> Unit)? = null,
|
||||
confirmButtonText: String = stringResource(android.R.string.ok),
|
||||
cancelButtonText: String = stringResource(android.R.string.cancel),
|
||||
shape: Shape = MaterialTheme.shapes.medium,
|
||||
backgroundColor: Color = MaterialTheme.colorScheme.surface,
|
||||
contentColor: Color = contentColorFor(backgroundColor),
|
||||
properties: DialogProperties = DialogProperties(),
|
||||
) {
|
||||
var reorderableItems by remember(items) { mutableStateOf(items) }
|
||||
val listState = rememberLazyListState()
|
||||
|
||||
val dragDropState = rememberReorderableLazyListState(listState) { from, to ->
|
||||
reorderableItems = reorderableItems.toMutableList().apply {
|
||||
add(to.index, removeAt(from.index))
|
||||
}
|
||||
}
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
confirmButton = {
|
||||
TextButton(onClick = { onConfirmed(reorderableItems); onDismissRequest() }) { Text(confirmButtonText) }
|
||||
},
|
||||
modifier = modifier,
|
||||
dismissButton = { TextButton(onClick = onDismissRequest) { Text(cancelButtonText) } },
|
||||
title = title,
|
||||
text = {
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
items(reorderableItems, key = getKey) { item ->
|
||||
ReorderableItem(
|
||||
state = dragDropState,
|
||||
key = getKey(item)
|
||||
) { dragging ->
|
||||
val elevation by animateDpAsState(if (dragging) 4.dp else 0.dp)
|
||||
Surface(shadowElevation = elevation) {
|
||||
Row(modifier = Modifier.longPressDraggableHandle()) {
|
||||
Icon(painterResource(R.drawable.ic_drag_indicator), "Reorder")
|
||||
displayItem(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
shape = shape,
|
||||
containerColor = backgroundColor,
|
||||
textContentColor = contentColor,
|
||||
properties = properties,
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
ReorderDialog(
|
||||
onConfirmed = {},
|
||||
onDismissRequest = {},
|
||||
items = listOf(1, 2, 3),
|
||||
displayItem = { Text(it.toString(), Modifier.fillMaxWidth(), textAlign = TextAlign.Center) },
|
||||
getKey = { it.toString() }
|
||||
)
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
package helium314.keyboard.settings.dialogs
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.material3.AlertDialog
|
||||
|
@ -23,7 +21,6 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import helium314.keyboard.latin.R
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ fun MainSettingsScreen(
|
|||
onClickAbout: () -> Unit,
|
||||
onClickTextCorrection: () -> Unit,
|
||||
onClickPreferences: () -> Unit,
|
||||
onClickToolbar: () -> Unit,
|
||||
onClickBack: () -> Unit,
|
||||
) {
|
||||
val ctx = LocalContext.current
|
||||
|
@ -54,6 +55,17 @@ fun MainSettingsScreen(
|
|||
contentDescription = null
|
||||
)
|
||||
}
|
||||
Preference(
|
||||
name = stringResource(R.string.settings_screen_toolbar),
|
||||
onClick = onClickToolbar,
|
||||
icon = R.drawable.ic_settings_toolbar_foreground
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_arrow_left),
|
||||
modifier = Modifier.scale(-1f, 1f),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
Preference(
|
||||
name = stringResource(R.string.settings_screen_correction),
|
||||
onClick = onClickTextCorrection,
|
||||
|
@ -129,7 +141,7 @@ fun Activity.switchTo(fragment: androidx.fragment.app.Fragment) {
|
|||
private fun PreviewScreen() {
|
||||
Theme(true) {
|
||||
Surface {
|
||||
MainSettingsScreen({}, {}, {}, {})
|
||||
MainSettingsScreen({}, {}, {}, {}, {})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,25 +4,18 @@ import android.content.Context
|
|||
import android.media.AudioManager
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import helium314.keyboard.latin.AudioAndHapticFeedbackManager
|
||||
import helium314.keyboard.latin.R
|
||||
import helium314.keyboard.latin.settings.Settings
|
||||
import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
||||
import helium314.keyboard.settings.AllPrefs
|
||||
import helium314.keyboard.settings.PrefDef
|
||||
import helium314.keyboard.settings.Preference
|
||||
import helium314.keyboard.settings.SearchPrefScreen
|
||||
import helium314.keyboard.settings.SettingsActivity2
|
||||
import helium314.keyboard.settings.SliderPreference
|
||||
import helium314.keyboard.settings.Theme
|
||||
import helium314.keyboard.settings.dialogs.SliderDialog
|
||||
|
||||
@Composable
|
||||
fun PreferencesScreen(
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package helium314.keyboard.settings.screens
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import helium314.keyboard.latin.R
|
||||
import helium314.keyboard.latin.settings.Settings
|
||||
import helium314.keyboard.settings.AllPrefs
|
||||
import helium314.keyboard.settings.PrefDef
|
||||
import helium314.keyboard.settings.Preference
|
||||
import helium314.keyboard.settings.SearchPrefScreen
|
||||
import helium314.keyboard.settings.SettingsActivity2
|
||||
import helium314.keyboard.settings.Theme
|
||||
import helium314.keyboard.settings.dialogs.ReorderDialog
|
||||
|
||||
@Composable
|
||||
fun ToolbarScreen(
|
||||
onClickBack: () -> Unit,
|
||||
) {
|
||||
SearchPrefScreen(
|
||||
onClickBack = onClickBack,
|
||||
title = stringResource(R.string.settings_screen_toolbar),
|
||||
) {
|
||||
SettingsActivity2.allPrefs.map[Settings.PREF_PINNED_TOOLBAR_KEYS]!!.Preference()
|
||||
}
|
||||
}
|
||||
|
||||
fun createToolbarPrefs(context: Context) = listOf(
|
||||
PrefDef(context, Settings.PREF_PINNED_TOOLBAR_KEYS, R.string.pinned_toolbar_keys) { def ->
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
Preference(
|
||||
name = def.title,
|
||||
onClick = { showDialog = true },
|
||||
)
|
||||
if (showDialog) {
|
||||
ReorderDialog(
|
||||
onConfirmed = { },
|
||||
onDismissRequest = { showDialog = false },
|
||||
items = (1..40).toList(),
|
||||
displayItem = { Text(it.toString(), Modifier.fillMaxWidth(), textAlign = TextAlign.Center) },
|
||||
getKey = { it.hashCode() }
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
SettingsActivity2.allPrefs = AllPrefs(LocalContext.current)
|
||||
Theme(true) {
|
||||
Surface {
|
||||
ToolbarScreen { }
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue