mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-06-18 23:20:54 +00:00
use simple list picker
This commit is contained in:
parent
80172665c0
commit
bc5b9b4efc
4 changed files with 147 additions and 10 deletions
|
@ -40,7 +40,7 @@ import helium314.keyboard.latin.R
|
||||||
import helium314.keyboard.latin.utils.Log
|
import helium314.keyboard.latin.utils.Log
|
||||||
import helium314.keyboard.latin.utils.getActivity
|
import helium314.keyboard.latin.utils.getActivity
|
||||||
import helium314.keyboard.latin.utils.prefs
|
import helium314.keyboard.latin.utils.prefs
|
||||||
import helium314.keyboard.settings.dialogs.ListPickerDialog
|
import helium314.keyboard.settings.dialogs.SimpleListPickerDialog
|
||||||
import helium314.keyboard.settings.dialogs.SliderDialog
|
import helium314.keyboard.settings.dialogs.SliderDialog
|
||||||
|
|
||||||
// taken from StreetComplete (and a bit SCEE)
|
// taken from StreetComplete (and a bit SCEE)
|
||||||
|
@ -82,14 +82,14 @@ fun Preference(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clickable { onClick() }
|
.clickable { onClick() }
|
||||||
.heightIn(min = 40.dp)
|
.heightIn(min = 44.dp)
|
||||||
.padding(12.dp),
|
.padding(12.dp),
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
if (icon != null)
|
if (icon != null)
|
||||||
Icon(painterResource(icon), name, modifier = Modifier.size(36.dp))
|
Icon(painterResource(icon), name, modifier = Modifier.size(36.dp))
|
||||||
Column(modifier = Modifier.weight(2 / 3f)) {
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
Text(text = name)
|
Text(text = name)
|
||||||
if (description != null) {
|
if (description != null) {
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
|
@ -117,7 +117,6 @@ fun Preference(
|
||||||
alignment = Alignment.End
|
alignment = Alignment.End
|
||||||
),
|
),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier.weight(1 / 3f)
|
|
||||||
) { value() }
|
) { value() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,7 +232,6 @@ fun <T: Any> ListPreference(
|
||||||
default: T,
|
default: T,
|
||||||
) {
|
) {
|
||||||
var showDialog by remember { mutableStateOf(false) }
|
var showDialog by remember { mutableStateOf(false) }
|
||||||
// todo: get rid of the arrays from old settings
|
|
||||||
val prefs = LocalContext.current.prefs()
|
val prefs = LocalContext.current.prefs()
|
||||||
val selected = items.firstOrNull { it.second == getPrefOfType(prefs, def.key, default) }
|
val selected = items.firstOrNull { it.second == getPrefOfType(prefs, def.key, default) }
|
||||||
Preference(
|
Preference(
|
||||||
|
@ -242,7 +240,7 @@ fun <T: Any> ListPreference(
|
||||||
onClick = { showDialog = true }
|
onClick = { showDialog = true }
|
||||||
)
|
)
|
||||||
if (showDialog) {
|
if (showDialog) {
|
||||||
ListPickerDialog(
|
SimpleListPickerDialog(
|
||||||
onDismissRequest = { showDialog = false },
|
onDismissRequest = { showDialog = false },
|
||||||
items = items,
|
items = items,
|
||||||
onItemSelected = {
|
onItemSelected = {
|
||||||
|
|
|
@ -33,7 +33,7 @@ import androidx.compose.ui.window.DialogProperties
|
||||||
|
|
||||||
// taken from StreetComplete
|
// taken from StreetComplete
|
||||||
@Composable
|
@Composable
|
||||||
fun <T> ListPickerDialog(
|
fun <T: Any> ListPickerDialog(
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
items: List<T>,
|
items: List<T>,
|
||||||
onItemSelected: (T) -> Unit,
|
onItemSelected: (T) -> Unit,
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
package helium314.keyboard.settings.dialogs
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
import androidx.compose.material3.LocalTextStyle
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.RadioButton
|
||||||
|
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.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
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.Dialog
|
||||||
|
import androidx.compose.ui.window.DialogProperties
|
||||||
|
|
||||||
|
// taken from StreetComplete
|
||||||
|
/** Similar to ListPickerDialog, but tapping on one item immediately closes the dialog
|
||||||
|
* (no OK button, no cancel button)
|
||||||
|
*
|
||||||
|
* This dialog doesn't have the caveat of the ListPickerDialog in that it takes as much width
|
||||||
|
* as possible */
|
||||||
|
@Composable
|
||||||
|
fun <T> SimpleListPickerDialog(
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
items: List<T>,
|
||||||
|
onItemSelected: (T) -> Unit,
|
||||||
|
title: (@Composable () -> Unit)? = null,
|
||||||
|
selectedItem: T? = null,
|
||||||
|
getItemName: (@Composable (T) -> String) = { it.toString() },
|
||||||
|
shape: Shape = MaterialTheme.shapes.medium,
|
||||||
|
backgroundColor: Color = MaterialTheme.colorScheme.surface,
|
||||||
|
contentColor: Color = contentColorFor(backgroundColor),
|
||||||
|
properties: DialogProperties = DialogProperties()
|
||||||
|
) {
|
||||||
|
val selected by remember { mutableStateOf(selectedItem) }
|
||||||
|
val state = rememberLazyListState()
|
||||||
|
|
||||||
|
fun select(item: T) {
|
||||||
|
onDismissRequest()
|
||||||
|
onItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(selectedItem) {
|
||||||
|
val index = items.indexOf(selectedItem)
|
||||||
|
if (index != -1) state.scrollToItem(index, -state.layoutInfo.viewportSize.height / 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog(
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
properties = properties
|
||||||
|
) {
|
||||||
|
Surface(
|
||||||
|
shape = shape,
|
||||||
|
color = backgroundColor,
|
||||||
|
contentColor = contentColor
|
||||||
|
) {
|
||||||
|
Column(Modifier.padding(vertical = 24.dp)) {
|
||||||
|
if (title != null) {
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalTextStyle provides MaterialTheme.typography.titleLarge
|
||||||
|
) {
|
||||||
|
Column(Modifier.padding(start = 24.dp, bottom = 16.dp, end = 24.dp)) {
|
||||||
|
title()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state.canScrollBackward) HorizontalDivider()
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalTextStyle provides MaterialTheme.typography.bodyLarge
|
||||||
|
) {
|
||||||
|
LazyColumn(state = state) {
|
||||||
|
items(items) { item ->
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable { select(item) }
|
||||||
|
.padding(horizontal = 24.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = getItemName(item),
|
||||||
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
)
|
||||||
|
RadioButton(
|
||||||
|
selected = selected == item,
|
||||||
|
onClick = { select(item) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state.canScrollForward) HorizontalDivider()
|
||||||
|
// todo: button not visible when there are many entries
|
||||||
|
Row(Modifier.padding(end = 24.dp)) {
|
||||||
|
Spacer(Modifier.weight(1f))
|
||||||
|
TextButton(
|
||||||
|
onClick = onDismissRequest,
|
||||||
|
) { Text(stringResource(android.R.string.cancel)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun PreviewSimpleListPickerDialog() {
|
||||||
|
val items = remember { (0..<5).toList() }
|
||||||
|
SimpleListPickerDialog(
|
||||||
|
onDismissRequest = {},
|
||||||
|
items = items,
|
||||||
|
onItemSelected = {},
|
||||||
|
title = { Text("Select something") },
|
||||||
|
selectedItem = 2,
|
||||||
|
getItemName = { "Item $it" },
|
||||||
|
)
|
||||||
|
}
|
|
@ -131,7 +131,6 @@ fun createCorrectionPrefs(context: Context) = listOf(
|
||||||
Settings.PREF_AUTO_CORRECTION_CONFIDENCE,
|
Settings.PREF_AUTO_CORRECTION_CONFIDENCE,
|
||||||
R.string.auto_correction_confidence,
|
R.string.auto_correction_confidence,
|
||||||
) { def ->
|
) { def ->
|
||||||
// todo: arrays are arranged in a rather absurd way... this should be improved
|
|
||||||
val items = listOf(
|
val items = listOf(
|
||||||
stringResource(R.string.auto_correction_threshold_mode_modest) to "0",
|
stringResource(R.string.auto_correction_threshold_mode_modest) to "0",
|
||||||
stringResource(R.string.auto_correction_threshold_mode_aggressive) to "1",
|
stringResource(R.string.auto_correction_threshold_mode_aggressive) to "1",
|
||||||
|
@ -225,14 +224,16 @@ fun createCorrectionPrefs(context: Context) = listOf(
|
||||||
Settings.PREF_USE_CONTACTS,
|
Settings.PREF_USE_CONTACTS,
|
||||||
R.string.use_contacts_dict,
|
R.string.use_contacts_dict,
|
||||||
R.string.use_contacts_dict_summary
|
R.string.use_contacts_dict_summary
|
||||||
) {
|
) { def ->
|
||||||
val activity = LocalContext.current.getActivity() ?: return@PrefDef
|
val activity = LocalContext.current.getActivity() ?: return@PrefDef
|
||||||
var granted by remember { mutableStateOf(PermissionsUtil.checkAllPermissionsGranted(activity, Manifest.permission.READ_CONTACTS)) }
|
var granted by remember { mutableStateOf(PermissionsUtil.checkAllPermissionsGranted(activity, Manifest.permission.READ_CONTACTS)) }
|
||||||
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {
|
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {
|
||||||
granted = it
|
granted = it
|
||||||
|
if (granted)
|
||||||
|
activity.prefs().edit().putBoolean(def.key, true).apply()
|
||||||
}
|
}
|
||||||
SwitchPreference(
|
SwitchPreference(
|
||||||
it,
|
def,
|
||||||
false,
|
false,
|
||||||
allowCheckedChange = {
|
allowCheckedChange = {
|
||||||
if (it && !granted) {
|
if (it && !granted) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue