@@ -3,6 +3,7 @@ package helium314.keyboard.settings.dialogs
3
3
import android.content.Context
4
4
import android.view.inputmethod.InputMethodSubtype
5
5
import androidx.compose.foundation.clickable
6
+ import androidx.compose.foundation.layout.Arrangement
6
7
import androidx.compose.foundation.layout.Box
7
8
import androidx.compose.foundation.layout.Column
8
9
import androidx.compose.foundation.layout.Row
@@ -12,6 +13,7 @@ import androidx.compose.foundation.rememberScrollState
12
13
import androidx.compose.foundation.verticalScroll
13
14
import androidx.compose.material3.DropdownMenu
14
15
import androidx.compose.material3.DropdownMenuItem
16
+ import androidx.compose.material3.HorizontalDivider
15
17
import androidx.compose.material3.Icon
16
18
import androidx.compose.material3.IconButton
17
19
import androidx.compose.material3.MaterialTheme
@@ -58,20 +60,16 @@ import helium314.keyboard.latin.utils.SubtypeSettings
58
60
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
59
61
import helium314.keyboard.latin.utils.getDictionaryLocales
60
62
import helium314.keyboard.latin.utils.getStringResourceOrName
63
+ import helium314.keyboard.latin.utils.locale
61
64
import helium314.keyboard.latin.utils.prefs
62
65
import helium314.keyboard.settings.screens.GetIcon
63
66
import java.util.Locale
64
67
65
68
// todo:
66
69
// save when "editing" a resource subtypes is not working
67
- // default buttons missing
68
- // string resources
69
- // dialog doesn't look good...
70
70
// settings upgrade to move the override settings to extra values, and actually use them (via getSelectedSubtype, not RichIMM)
71
71
@Composable
72
72
fun SubtypeDialog (
73
- // could also use InputMethodSubtype if there is any advantage
74
- // but as soon as anything is changed we will need an additional subtype anyway...
75
73
onDismissRequest : () -> Unit ,
76
74
subtype : InputMethodSubtype ,
77
75
onConfirmed : (SettingsSubtype ) -> Unit ,
@@ -99,8 +97,9 @@ fun SubtypeDialog(
99
97
text = {
100
98
Column (
101
99
modifier = Modifier .verticalScroll(scrollState),
100
+ verticalArrangement = Arrangement .spacedBy(8 .dp),
102
101
) {
103
- WithSmallTitle (" main layout " ) {
102
+ WithSmallTitle (stringResource( R .string.keyboard_layout_set) ) {
104
103
val appLayouts = LayoutUtils .getAvailableLayouts(LayoutType .MAIN , ctx, currentSubtype.locale)
105
104
val customLayouts = LayoutUtilsCustom .getLayoutFiles(LayoutType .MAIN , ctx, currentSubtype.locale).map { it.name }
106
105
DropDownField (
@@ -110,18 +109,17 @@ fun SubtypeDialog(
110
109
currentSubtype = currentSubtype.withLayout(LayoutType .MAIN , it)
111
110
}
112
111
) {
113
- // todo: displayName can be complicated and may require an inputmethodsubtype...
114
- // maybe search for stuff in resource subtypes?
115
- Text (it)
112
+ Text (SubtypeLocaleUtils .getDisplayNameInSystemLocale(it, currentSubtype.locale))
116
113
// todo: edit button? or only for selected layout? and delete button?
114
+ // yes, even just to make clear what is custom
117
115
}
118
116
}
119
117
WithSmallTitle (stringResource(R .string.secondary_locale)) {
120
118
TextButton (onClick = { showSecondaryLocaleDialog = true }) {
121
119
val text = currentSubtype.getExtraValueOf(ExtraValue .SECONDARY_LOCALES )
122
120
?.split(Separators .KV )?.joinToString(" , " ) {
123
121
LocaleUtils .getLocaleDisplayNameInSystemLocale(it.constructLocale(), ctx)
124
- } ? : " none "
122
+ } ? : stringResource( R .string.action_none)
125
123
Text (text, Modifier .fillMaxWidth(), style = MaterialTheme .typography.bodyLarge)
126
124
}
127
125
}
@@ -131,32 +129,56 @@ fun SubtypeDialog(
131
129
Text (" not yet implemented" )
132
130
}
133
131
// todo: this looks strange without the title
134
- TextButton (onClick = { showKeyOrderDialog = true })
135
- { Text (stringResource(R .string.popup_order), Modifier .fillMaxWidth(), style = MaterialTheme .typography.bodyLarge) }
136
- TextButton (onClick = { showHintOrderDialog = true })
137
- { Text (stringResource(R .string.hint_source), Modifier .fillMaxWidth(), style = MaterialTheme .typography.bodyLarge) }
138
- if (currentSubtype.locale.script() == SCRIPT_LATIN )
132
+ Row {
133
+ TextButton (onClick = { showKeyOrderDialog = true }, Modifier .weight(1f ))
134
+ { Text (stringResource(R .string.popup_order), style = MaterialTheme .typography.bodyLarge) }
135
+ DefaultButton (
136
+ { currentSubtype = currentSubtype.without(ExtraValue .POPUP_ORDER ) },
137
+ currentSubtype.getExtraValueOf(ExtraValue .POPUP_ORDER ) == null
138
+ )
139
+ }
140
+ Row {
141
+ TextButton (onClick = { showHintOrderDialog = true }, Modifier .weight(1f ))
142
+ { Text (stringResource(R .string.hint_source), style = MaterialTheme .typography.bodyLarge) }
143
+ DefaultButton (
144
+ { currentSubtype = currentSubtype.without(ExtraValue .HINT_ORDER ) },
145
+ currentSubtype.getExtraValueOf(ExtraValue .HINT_ORDER ) == null
146
+ )
147
+ }
148
+ if (currentSubtype.locale.script() == SCRIPT_LATIN ) {
139
149
WithSmallTitle (stringResource(R .string.show_popup_keys_title)) {
140
150
val explicitValue = currentSubtype.getExtraValueOf(ExtraValue .MORE_POPUPS )
141
151
val value = explicitValue ? : prefs.getString(Settings .PREF_MORE_POPUP_KEYS , Defaults .PREF_MORE_POPUP_KEYS )!!
142
- TextButton (onClick = { showMorePopupsDialog = true }, Modifier .fillMaxWidth())
152
+ Row {
153
+ TextButton (onClick = { showMorePopupsDialog = true }, Modifier .weight(1f ))
143
154
{ Text (stringResource(morePopupKeysResId(value))) }
155
+ DefaultButton (
156
+ { currentSubtype = currentSubtype.without(ExtraValue .MORE_POPUPS ) },
157
+ explicitValue == null
158
+ )
159
+ }
144
160
}
145
- if (hasLocalizedNumberRow(currentSubtype.locale, ctx))
161
+ }
162
+ if (hasLocalizedNumberRow(currentSubtype.locale, ctx)) {
146
163
Row {
164
+ val checked = currentSubtype.getExtraValueOf(ExtraValue .LOCALIZED_NUMBER_ROW )?.toBoolean()
147
165
Text (stringResource(R .string.localized_number_row), Modifier .weight(1f ))
148
166
Switch (
149
- checked = currentSubtype.getExtraValueOf(ExtraValue .LOCALIZED_NUMBER_ROW )?.toBoolean()
150
- ? : prefs.getBoolean(Settings .PREF_LOCALIZED_NUMBER_ROW , Defaults .PREF_LOCALIZED_NUMBER_ROW ),
167
+ checked = checked ? : prefs.getBoolean(Settings .PREF_LOCALIZED_NUMBER_ROW , Defaults .PREF_LOCALIZED_NUMBER_ROW ),
151
168
onCheckedChange = {
152
169
currentSubtype = currentSubtype.with (ExtraValue .LOCALIZED_NUMBER_ROW , it.toString())
153
170
}
154
171
)
155
- // todo: default button?
172
+ DefaultButton (
173
+ { currentSubtype = currentSubtype.without(ExtraValue .LOCALIZED_NUMBER_ROW ) },
174
+ checked == null
175
+ )
156
176
}
177
+ }
178
+ HorizontalDivider ()
179
+ Text (stringResource(R .string.settings_screen_secondary_layouts), style = MaterialTheme .typography.titleMedium)
157
180
LayoutType .entries.forEach { type ->
158
181
if (type == LayoutType .MAIN ) return @forEach
159
- // todo: also some default button, to be shown when necessary, uses currentSubtype.withoutLayout(type)
160
182
WithSmallTitle (stringResource(type.displayNameId)) {
161
183
val explicitLayout = currentSubtype.layoutName(type)
162
184
val layout = explicitLayout ? : Settings .readDefaultLayoutName(type, prefs)
@@ -167,10 +189,12 @@ fun SubtypeDialog(
167
189
selectedItem = layout,
168
190
onSelected = {
169
191
currentSubtype = currentSubtype.withLayout(type, it)
170
- }
192
+ },
193
+ onDefault = { currentSubtype = currentSubtype.withoutLayout(type) },
194
+ isDefault = explicitLayout == null
171
195
) {
172
196
val displayName = if (LayoutUtilsCustom .isCustomLayout(it)) LayoutUtilsCustom .getDisplayName(it)
173
- else it.getStringResourceOrName(" layout_" , ctx)
197
+ else it.getStringResourceOrName(" layout_" , ctx)
174
198
Text (displayName)
175
199
// content is name, and if it's user layout there is an edit button
176
200
// also maybe there should be an "add" button similar to the old settings
@@ -183,8 +207,8 @@ fun SubtypeDialog(
183
207
if (showSecondaryLocaleDialog)
184
208
MultiListPickerDialog (
185
209
onDismissRequest = { showSecondaryLocaleDialog = false },
186
- onConfirmed = {
187
- val newValue = it .joinToString(Separators .KV ) { it.toLanguageTag() }
210
+ onConfirmed = { locales ->
211
+ val newValue = locales .joinToString(Separators .KV ) { it.toLanguageTag() }
188
212
currentSubtype = if (newValue.isEmpty()) currentSubtype.without(ExtraValue .SECONDARY_LOCALES )
189
213
else currentSubtype.with (ExtraValue .SECONDARY_LOCALES , newValue)
190
214
},
@@ -201,8 +225,8 @@ fun SubtypeDialog(
201
225
title = stringResource(R .string.popup_order),
202
226
showDefault = setting != null ,
203
227
onConfirmed = {
204
- if (it == null ) currentSubtype = currentSubtype.without(ExtraValue .POPUP_ORDER )
205
- else currentSubtype = currentSubtype.with (ExtraValue .POPUP_ORDER , it)
228
+ currentSubtype = if (it == null ) currentSubtype.without(ExtraValue .POPUP_ORDER )
229
+ else currentSubtype.with (ExtraValue .POPUP_ORDER , it)
206
230
}
207
231
)
208
232
}
@@ -214,13 +238,12 @@ fun SubtypeDialog(
214
238
title = stringResource(R .string.hint_source),
215
239
showDefault = setting != null ,
216
240
onConfirmed = {
217
- if (it == null ) currentSubtype = currentSubtype.without(ExtraValue .HINT_ORDER )
218
- else currentSubtype = currentSubtype.with (ExtraValue .HINT_ORDER , it)
241
+ currentSubtype = if (it == null ) currentSubtype.without(ExtraValue .HINT_ORDER )
242
+ else currentSubtype.with (ExtraValue .HINT_ORDER , it)
219
243
}
220
244
)
221
245
}
222
246
if (showMorePopupsDialog) {
223
- // todo: default button in here? or next to the pref?
224
247
val items = listOf (POPUP_KEYS_NORMAL , POPUP_KEYS_MAIN , POPUP_KEYS_MORE , POPUP_KEYS_ALL )
225
248
val explicitValue = currentSubtype.getExtraValueOf(ExtraValue .MORE_POPUPS )
226
249
val value = explicitValue ? : prefs.getString(Settings .PREF_MORE_POPUP_KEYS , Defaults .PREF_MORE_POPUP_KEYS )
@@ -262,7 +285,7 @@ private fun PopupOrderDialog(
262
285
var checked by rememberSaveable { mutableStateOf(item.state) }
263
286
Row (verticalAlignment = Alignment .CenterVertically ) {
264
287
KeyboardIconsSet .instance.GetIcon (item.name)
265
- val text = item.name.lowercase().getStringResourceOrName(" " , ctx)
288
+ val text = item.name.lowercase().getStringResourceOrName(" popup_keys_ " , ctx)
266
289
Text (text, Modifier .weight(1f ))
267
290
Switch (
268
291
checked = checked,
@@ -290,6 +313,8 @@ private fun <T>DropDownField(
290
313
items : List <T >,
291
314
selectedItem : T ,
292
315
onSelected : (T ) -> Unit ,
316
+ isDefault : Boolean? = null,
317
+ onDefault : () -> Unit = {},
293
318
itemContent : @Composable (T ) -> Unit ,
294
319
) {
295
320
var expanded by remember { mutableStateOf(false ) }
@@ -299,7 +324,7 @@ private fun <T>DropDownField(
299
324
) {
300
325
Row (
301
326
verticalAlignment = Alignment .CenterVertically ,
302
- modifier = Modifier .padding(start = 8 .dp, end = 8 .dp, bottom = 4 .dp)
327
+ modifier = Modifier .padding(start = 8 .dp, bottom = 4 .dp)
303
328
) {
304
329
Box (Modifier .weight(1f )) {
305
330
itemContent(selectedItem)
@@ -310,10 +335,12 @@ private fun <T>DropDownField(
310
335
) {
311
336
Icon (
312
337
painterResource(R .drawable.ic_arrow_left),
313
- null ,
338
+ " show dropdown " ,
314
339
Modifier .rotate(- 90f )
315
340
)
316
341
}
342
+ if (isDefault != null )
343
+ DefaultButton (onDefault, isDefault)
317
344
}
318
345
}
319
346
DropdownMenu (
@@ -329,16 +356,19 @@ private fun <T>DropDownField(
329
356
}
330
357
}
331
358
332
- // get locales with same script as main locale, but different language
333
- // todo: do we need any sort of force-ascii like in old variant?
334
- // now we use hi-Latn and sr-Latn for the relevant subtypes, so it should be fine
335
- // only potential issue is the Latn-default if we don't have the script for a locale,
336
- // but in that case we should rather add the script to ScriptUtils
337
- private fun getAvailableSecondaryLocales ( context : Context , mainLocale : Locale ): List < Locale > {
338
- val locales = getDictionaryLocales(context)
339
- locales.removeAll {
340
- // it.language == mainLocale.language || it.script() != mainLocale.script()
341
- it == mainLocale || it.script() != mainLocale.script( ) // todo: check whether this is fine, otherwise go back to the variant above
359
+ @Composable
360
+ private fun DefaultButton (
361
+ onDefault : () -> Unit ,
362
+ isDefault : Boolean
363
+ ) {
364
+ IconButton (
365
+ onClick = onDefault,
366
+ enabled = ! isDefault
367
+ ) {
368
+ Icon (painterResource( R .drawable.sym_keyboard_settings_holo), " default " ) // todo: more understandable icon!
342
369
}
343
- return locales.toList()
370
+
344
371
}
372
+
373
+ private fun getAvailableSecondaryLocales (context : Context , mainLocale : Locale ): List <Locale > =
374
+ getDictionaryLocales(context).filter { it != mainLocale && it.script() == mainLocale.script() }
0 commit comments