@@ -17,6 +17,8 @@ import androidx.compose.foundation.layout.padding
17
17
import androidx.compose.foundation.layout.width
18
18
import androidx.compose.foundation.lazy.LazyColumn
19
19
import androidx.compose.foundation.lazy.items
20
+ import androidx.compose.foundation.rememberScrollState
21
+ import androidx.compose.foundation.verticalScroll
20
22
import androidx.compose.material.icons.Icons
21
23
import androidx.compose.material.icons.rounded.ErrorOutline
22
24
import androidx.compose.material3.BottomAppBar
@@ -27,6 +29,7 @@ import androidx.compose.material3.OutlinedCard
27
29
import androidx.compose.material3.Scaffold
28
30
import androidx.compose.material3.Surface
29
31
import androidx.compose.material3.Text
32
+ import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
30
33
import androidx.compose.runtime.Composable
31
34
import androidx.compose.runtime.getValue
32
35
import androidx.compose.runtime.mutableStateOf
@@ -41,14 +44,18 @@ import androidx.compose.ui.text.font.FontWeight
41
44
import androidx.compose.ui.text.style.TextAlign
42
45
import androidx.compose.ui.text.style.TextOverflow
43
46
import androidx.compose.ui.text.withStyle
47
+ import androidx.compose.ui.tooling.preview.Devices
44
48
import androidx.compose.ui.tooling.preview.Preview
45
49
import androidx.compose.ui.unit.dp
50
+ import androidx.window.core.layout.WindowHeightSizeClass
51
+ import androidx.window.core.layout.WindowWidthSizeClass
46
52
import io.github.sds100.keymapper.R
47
53
import io.github.sds100.keymapper.compose.KeyMapperTheme
48
54
import io.github.sds100.keymapper.util.State
49
55
import io.github.sds100.keymapper.util.ui.compose.CheckBoxText
50
56
import io.github.sds100.keymapper.util.ui.compose.KeyMapperDropdownMenu
51
57
import io.github.sds100.keymapper.util.ui.compose.SearchAppBarActions
58
+ import io.github.sds100.keymapper.util.ui.compose.WindowSizeClassExt.compareTo
52
59
53
60
@Composable
54
61
fun ChooseElementScreen (
@@ -62,7 +69,9 @@ fun ChooseElementScreen(
62
69
onSelectInteractionType : (NodeInteractionType ? ) -> Unit = {},
63
70
onAdditionalElementsCheckedChange : (Boolean ) -> Unit = {},
64
71
) {
65
- var interactionTypeExpanded by rememberSaveable { mutableStateOf(false ) }
72
+ val windowAdaptiveInfo = currentWindowAdaptiveInfo()
73
+ val widthSizeClass = windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass
74
+ val heightSizeClass = windowAdaptiveInfo.windowSizeClass.windowHeightSizeClass
66
75
67
76
Scaffold (
68
77
modifier.displayCutoutPadding(),
@@ -107,82 +116,137 @@ fun ChooseElementScreen(
107
116
style = MaterialTheme .typography.titleLarge,
108
117
)
109
118
110
- Text (
111
- modifier = Modifier .padding(horizontal = 16 .dp),
112
- text = stringResource(R .string.action_interact_ui_element_choose_element_text),
113
- style = MaterialTheme .typography.bodyMedium,
114
- )
115
-
116
- Spacer (modifier = Modifier .height(8 .dp))
119
+ if (heightSizeClass == WindowHeightSizeClass .COMPACT || widthSizeClass >= WindowWidthSizeClass .EXPANDED ) {
120
+ Row {
121
+ InfoSection (
122
+ modifier = Modifier
123
+ .verticalScroll(rememberScrollState())
124
+ .weight(1f ),
125
+ state = state,
126
+ onSelectInteractionType = onSelectInteractionType,
127
+ onAdditionalElementsCheckedChange = onAdditionalElementsCheckedChange,
128
+ )
117
129
118
- Row (
119
- modifier = Modifier .padding(horizontal = 16 .dp),
120
- verticalAlignment = Alignment .CenterVertically ,
121
- ) {
122
- Icon (
123
- imageVector = Icons .Rounded .ErrorOutline ,
124
- contentDescription = null ,
125
- tint = MaterialTheme .colorScheme.error,
130
+ ListSection (
131
+ modifier = Modifier .weight(1f ),
132
+ state = state,
133
+ onClickElement = onClickElement,
134
+ )
135
+ }
136
+ } else {
137
+ InfoSection (
138
+ state = state,
139
+ onSelectInteractionType = onSelectInteractionType,
140
+ onAdditionalElementsCheckedChange = onAdditionalElementsCheckedChange,
126
141
)
127
- Spacer (modifier = Modifier .width( 8 .dp))
128
- Text (
129
- text = stringResource( R .string.action_interact_ui_element_choose_element_not_found_subtitle ),
130
- color = MaterialTheme .colorScheme.error ,
131
- style = MaterialTheme .typography.titleSmall ,
142
+
143
+ ListSection (
144
+ modifier = Modifier .fillMaxSize( ),
145
+ state = state ,
146
+ onClickElement = onClickElement ,
132
147
)
133
148
}
149
+ }
150
+ }
151
+ }
152
+ }
134
153
135
- Spacer (modifier = Modifier .height(8 .dp))
154
+ @Composable
155
+ private fun InfoSection (
156
+ modifier : Modifier = Modifier ,
157
+ state : State <SelectUiElementState >,
158
+ onSelectInteractionType : (NodeInteractionType ? ) -> Unit ,
159
+ onAdditionalElementsCheckedChange : (Boolean ) -> Unit ,
160
+ ) {
161
+ Column (modifier = modifier) {
162
+ Text (
163
+ modifier = Modifier .padding(horizontal = 16 .dp),
164
+ text = stringResource(R .string.action_interact_ui_element_choose_element_text),
165
+ style = MaterialTheme .typography.bodyMedium,
166
+ )
136
167
137
- Text (
138
- modifier = Modifier .padding(horizontal = 16 .dp),
139
- text = stringResource(R .string.action_interact_ui_element_choose_element_not_found_text),
140
- style = MaterialTheme .typography.bodyMedium,
141
- )
142
- Spacer (modifier = Modifier .height(8 .dp))
168
+ Spacer (modifier = Modifier .height(8 .dp))
143
169
144
- when (state) {
145
- State .Loading -> LoadingList (modifier = Modifier .fillMaxSize())
146
- is State .Data -> {
147
- val listItems = state.data.listItems
170
+ Row (
171
+ modifier = Modifier .padding(horizontal = 16 .dp),
172
+ verticalAlignment = Alignment .CenterVertically ,
173
+ ) {
174
+ Icon (
175
+ imageVector = Icons .Rounded .ErrorOutline ,
176
+ contentDescription = null ,
177
+ tint = MaterialTheme .colorScheme.error,
178
+ )
179
+ Spacer (modifier = Modifier .width(8 .dp))
180
+ Text (
181
+ text = stringResource(R .string.action_interact_ui_element_choose_element_not_found_subtitle),
182
+ color = MaterialTheme .colorScheme.error,
183
+ style = MaterialTheme .typography.titleSmall,
184
+ )
185
+ }
148
186
149
- CheckBoxText (
150
- modifier = Modifier
151
- .fillMaxWidth()
152
- .padding(horizontal = 8 .dp),
153
- text = stringResource(R .string.action_interact_ui_element_checkbox_additional_elements),
154
- isChecked = state.data.showAdditionalElements,
155
- onCheckedChange = onAdditionalElementsCheckedChange,
156
- )
187
+ Spacer (modifier = Modifier .height(8 .dp))
157
188
158
- Spacer (modifier = Modifier .height(8 .dp))
159
-
160
- if (listItems.isEmpty()) {
161
- EmptyList (
162
- modifier = Modifier
163
- .fillMaxSize()
164
- .padding(16 .dp),
165
- )
166
- } else {
167
- KeyMapperDropdownMenu (
168
- modifier = Modifier .padding(horizontal = 16 .dp),
169
- expanded = interactionTypeExpanded,
170
- onExpandedChange = { interactionTypeExpanded = it },
171
- label = { Text (stringResource(R .string.action_interact_ui_element_filter_interaction_type_dropdown)) },
172
- values = state.data.interactionTypes,
173
- selectedValue = state.data.selectedInteractionType,
174
- onValueChanged = onSelectInteractionType,
175
- )
176
-
177
- Spacer (modifier = Modifier .height(8 .dp))
178
-
179
- LoadedList (
180
- modifier = Modifier .fillMaxSize(),
181
- listItems = listItems,
182
- onClick = onClickElement,
183
- )
184
- }
185
- }
189
+ Text (
190
+ modifier = Modifier .padding(horizontal = 16 .dp),
191
+ text = stringResource(R .string.action_interact_ui_element_choose_element_not_found_text),
192
+ style = MaterialTheme .typography.bodyMedium,
193
+ )
194
+
195
+ Spacer (modifier = Modifier .height(8 .dp))
196
+
197
+ if (state is State .Data ) {
198
+ var interactionTypeExpanded by rememberSaveable { mutableStateOf(false ) }
199
+
200
+ CheckBoxText (
201
+ modifier = Modifier
202
+ .fillMaxWidth()
203
+ .padding(horizontal = 8 .dp),
204
+ text = stringResource(R .string.action_interact_ui_element_checkbox_additional_elements),
205
+ isChecked = state.data.showAdditionalElements,
206
+ onCheckedChange = onAdditionalElementsCheckedChange,
207
+ )
208
+
209
+ Spacer (modifier = Modifier .height(8 .dp))
210
+
211
+ KeyMapperDropdownMenu (
212
+ modifier = Modifier .padding(horizontal = 16 .dp),
213
+ expanded = interactionTypeExpanded,
214
+ onExpandedChange = { interactionTypeExpanded = it },
215
+ label = { Text (stringResource(R .string.action_interact_ui_element_filter_interaction_type_dropdown)) },
216
+ values = state.data.interactionTypes,
217
+ selectedValue = state.data.selectedInteractionType,
218
+ onValueChanged = onSelectInteractionType,
219
+ )
220
+
221
+ Spacer (modifier = Modifier .height(8 .dp))
222
+ }
223
+ }
224
+ }
225
+
226
+ @Composable
227
+ private fun ListSection (
228
+ modifier : Modifier = Modifier ,
229
+ state : State <SelectUiElementState >,
230
+ onClickElement : (Long ) -> Unit ,
231
+ ) {
232
+ when (state) {
233
+ State .Loading -> LoadingList (modifier = modifier.fillMaxSize())
234
+ is State .Data -> {
235
+ val listItems = state.data.listItems
236
+
237
+ Column (modifier = modifier) {
238
+ if (listItems.isEmpty()) {
239
+ EmptyList (
240
+ modifier = Modifier
241
+ .fillMaxSize()
242
+ .padding(16 .dp),
243
+ )
244
+ } else {
245
+ LoadedList (
246
+ modifier = Modifier .fillMaxSize(),
247
+ listItems = listItems,
248
+ onClick = onClickElement,
249
+ )
186
250
}
187
251
}
188
252
}
@@ -352,41 +416,74 @@ private fun Loading() {
352
416
}
353
417
}
354
418
419
+ private val listItems = listOf (
420
+ UiElementListItemModel (
421
+ id = 1L ,
422
+ nodeText = " Open Settings" ,
423
+ nodeClassName = " android.widget.ImageButton" ,
424
+ nodeViewResourceId = " menu_button" ,
425
+ nodeUniqueId = " 123456789" ,
426
+ nodeTooltipHint = " Open menu" ,
427
+ interactionTypesText = " Tap, Tap and hold, Scroll forward" ,
428
+ interactionTypes = setOf (
429
+ NodeInteractionType .CLICK ,
430
+ NodeInteractionType .LONG_CLICK ,
431
+ NodeInteractionType .SCROLL_FORWARD ,
432
+ ),
433
+ interacted = true ,
434
+ ),
435
+ )
436
+
437
+ private val loadedState = SelectUiElementState (
438
+ listItems = listItems,
439
+ interactionTypes = listOf (
440
+ null to " Any" ,
441
+ NodeInteractionType .CLICK to " Tap" ,
442
+ NodeInteractionType .LONG_CLICK to " Tap and hold" ,
443
+ ),
444
+ selectedInteractionType = null ,
445
+ showAdditionalElements = true ,
446
+ )
447
+
355
448
@Preview
356
449
@Composable
357
- private fun Loaded () {
358
- val listItems = listOf (
359
- UiElementListItemModel (
360
- id = 1L ,
361
- nodeText = " Open Settings" ,
362
- nodeClassName = " android.widget.ImageButton" ,
363
- nodeViewResourceId = " menu_button" ,
364
- nodeUniqueId = " 123456789" ,
365
- nodeTooltipHint = " Open menu" ,
366
- interactionTypesText = " Tap, Tap and hold, Scroll forward" ,
367
- interactionTypes = setOf (
368
- NodeInteractionType .CLICK ,
369
- NodeInteractionType .LONG_CLICK ,
370
- NodeInteractionType .SCROLL_FORWARD ,
371
- ),
372
- interacted = true ,
373
- ),
374
- )
450
+ private fun LoadedPortrait () {
451
+ KeyMapperTheme {
452
+ ChooseElementScreen (
453
+ state = State .Data (loadedState),
454
+ query = " Key Mapper" ,
455
+ )
456
+ }
457
+ }
375
458
376
- val state = SelectUiElementState (
377
- listItems = listItems,
378
- interactionTypes = listOf (
379
- null to " Any " ,
380
- NodeInteractionType . CLICK to " Tap " ,
381
- NodeInteractionType . LONG_CLICK to " Tap and hold " ,
382
- ) ,
383
- selectedInteractionType = null ,
384
- showAdditionalElements = true ,
385
- )
459
+ @Preview(widthDp = 800 , heightDp = 300 )
460
+ @Composable
461
+ private fun LoadedPhoneLandscape () {
462
+ KeyMapperTheme {
463
+ ChooseElementScreen (
464
+ state = State . Data (loadedState) ,
465
+ query = " Key Mapper " ,
466
+ )
467
+ }
468
+ }
386
469
470
+ @Preview(device = Devices .TABLET )
471
+ @Composable
472
+ private fun LoadedTablet () {
473
+ KeyMapperTheme {
474
+ ChooseElementScreen (
475
+ state = State .Data (loadedState),
476
+ query = " Key Mapper" ,
477
+ )
478
+ }
479
+ }
480
+
481
+ @Preview(device = Devices .NEXUS_7 )
482
+ @Composable
483
+ private fun LoadedTabletVertical () {
387
484
KeyMapperTheme {
388
485
ChooseElementScreen (
389
- state = State .Data (state ),
486
+ state = State .Data (loadedState ),
390
487
query = " Key Mapper" ,
391
488
)
392
489
}
0 commit comments