Skip to content

Commit 2c8a5ae

Browse files
authored
Merge pull request #2341 from switchifyapp/feature/polish-pc-control-grid-ui-2340
Polish scanned PC control grid UI
2 parents e1934aa + 77a36eb commit 2c8a5ae

4 files changed

Lines changed: 274 additions & 62 deletions

File tree

app/src/main/java/com/enaboapps/switchify/screens/pc/PcMouseCommandGrid.kt

Lines changed: 231 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@ package com.enaboapps.switchify.screens.pc
22

33
import androidx.annotation.StringRes
44
import androidx.compose.foundation.layout.Arrangement
5-
import androidx.compose.foundation.layout.PaddingValues
6-
import androidx.compose.foundation.layout.fillMaxSize
5+
import androidx.compose.foundation.layout.Column
76
import androidx.compose.foundation.layout.fillMaxWidth
87
import androidx.compose.foundation.layout.heightIn
9-
import androidx.compose.foundation.lazy.grid.GridCells
10-
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
11-
import androidx.compose.foundation.lazy.grid.items
8+
import androidx.compose.foundation.layout.Row
9+
import androidx.compose.foundation.layout.Spacer
1210
import androidx.compose.material3.Button
1311
import androidx.compose.material3.MaterialTheme
1412
import androidx.compose.material3.SegmentedButton
@@ -36,30 +34,221 @@ fun PcMouseCommandGrid(
3634
onCommandSelected: (PcMouseCommand) -> Unit,
3735
modifier: Modifier = Modifier
3836
) {
39-
LazyVerticalGrid(
40-
columns = GridCells.Fixed(3),
41-
modifier = modifier.fillMaxSize(),
42-
contentPadding = PaddingValues(bottom = 16.dp),
43-
verticalArrangement = Arrangement.spacedBy(12.dp),
44-
horizontalArrangement = Arrangement.spacedBy(12.dp)
37+
PcMouseCommandSections(
38+
connected = connected,
39+
movementStep = movementStep,
40+
busyCommand = busyCommand,
41+
onCommandSelected = onCommandSelected,
42+
modifier = modifier
43+
)
44+
}
45+
46+
@Composable
47+
fun PcControlStatusStrip(
48+
connectedDisplayName: String?,
49+
message: String?,
50+
modifier: Modifier = Modifier
51+
) {
52+
Column(
53+
modifier = modifier.fillMaxWidth(),
54+
verticalArrangement = Arrangement.spacedBy(6.dp)
4555
) {
46-
items(pcMouseControlSpecs(movementStep)) { control ->
47-
Button(
48-
onClick = { onCommandSelected(control.command) },
49-
enabled = connected && busyCommand == null,
50-
modifier = Modifier
51-
.fillMaxWidth()
52-
.heightIn(min = 84.dp)
53-
) {
54-
Text(
55-
text = stringResource(control.labelResId),
56-
textAlign = TextAlign.Center
57-
)
58-
}
56+
Text(
57+
text = connectedDisplayName?.let {
58+
stringResource(R.string.pc_mouse_control_connected, it)
59+
} ?: stringResource(R.string.pc_control_connect_first),
60+
style = MaterialTheme.typography.bodyLarge,
61+
color = MaterialTheme.colorScheme.onSurfaceVariant
62+
)
63+
message?.let {
64+
Text(
65+
text = it,
66+
style = MaterialTheme.typography.bodyMedium,
67+
color = MaterialTheme.colorScheme.onSurfaceVariant
68+
)
69+
}
70+
}
71+
}
72+
73+
@Composable
74+
fun PcMovementSizeSection(
75+
selectedSize: PcMouseMovementSize,
76+
onSizeSelected: (PcMouseMovementSize) -> Unit,
77+
modifier: Modifier = Modifier
78+
) {
79+
Column(
80+
modifier = modifier.fillMaxWidth(),
81+
verticalArrangement = Arrangement.spacedBy(8.dp)
82+
) {
83+
PcCommandSectionTitle(R.string.pc_mouse_movement_size)
84+
PcMouseMovementSizeSelector(
85+
selectedSize = selectedSize,
86+
onSizeSelected = onSizeSelected
87+
)
88+
}
89+
}
90+
91+
@Composable
92+
fun PcMouseCommandSections(
93+
connected: Boolean,
94+
movementStep: Int,
95+
busyCommand: PcMouseCommand?,
96+
onCommandSelected: (PcMouseCommand) -> Unit,
97+
modifier: Modifier = Modifier
98+
) {
99+
Column(
100+
modifier = modifier.fillMaxWidth(),
101+
verticalArrangement = Arrangement.spacedBy(18.dp)
102+
) {
103+
PcMovementCommandSection(
104+
connected = connected,
105+
movementStep = movementStep,
106+
busyCommand = busyCommand,
107+
onCommandSelected = onCommandSelected
108+
)
109+
PcButtonCommandSection(
110+
titleResId = R.string.pc_mouse_section_clicks,
111+
specs = pcClickControlSpecs(),
112+
connected = connected,
113+
busyCommand = busyCommand,
114+
onCommandSelected = onCommandSelected
115+
)
116+
PcButtonCommandSection(
117+
titleResId = R.string.pc_mouse_section_scroll,
118+
specs = pcScrollControlSpecs(),
119+
connected = connected,
120+
busyCommand = busyCommand,
121+
onCommandSelected = onCommandSelected
122+
)
123+
}
124+
}
125+
126+
@Composable
127+
private fun PcMovementCommandSection(
128+
connected: Boolean,
129+
movementStep: Int,
130+
busyCommand: PcMouseCommand?,
131+
onCommandSelected: (PcMouseCommand) -> Unit
132+
) {
133+
val controls = pcMovementControlSpecs(movementStep)
134+
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
135+
PcCommandSectionTitle(R.string.pc_mouse_section_movement)
136+
PcCommandButtonRow(
137+
specs = controls.take(3),
138+
connected = connected,
139+
busyCommand = busyCommand,
140+
onCommandSelected = onCommandSelected,
141+
minHeightDp = 76
142+
)
143+
Row(
144+
modifier = Modifier.fillMaxWidth(),
145+
horizontalArrangement = Arrangement.spacedBy(10.dp)
146+
) {
147+
PcCommandButton(
148+
spec = controls[3],
149+
connected = connected,
150+
busyCommand = busyCommand,
151+
onCommandSelected = onCommandSelected,
152+
minHeightDp = 76,
153+
modifier = Modifier.weight(1f)
154+
)
155+
Spacer(modifier = Modifier.weight(1f))
156+
PcCommandButton(
157+
spec = controls[4],
158+
connected = connected,
159+
busyCommand = busyCommand,
160+
onCommandSelected = onCommandSelected,
161+
minHeightDp = 76,
162+
modifier = Modifier.weight(1f)
163+
)
164+
}
165+
PcCommandButtonRow(
166+
specs = controls.drop(5),
167+
connected = connected,
168+
busyCommand = busyCommand,
169+
onCommandSelected = onCommandSelected,
170+
minHeightDp = 76
171+
)
172+
}
173+
}
174+
175+
@Composable
176+
private fun PcButtonCommandSection(
177+
@StringRes titleResId: Int,
178+
specs: List<PcMouseControlSpec>,
179+
connected: Boolean,
180+
busyCommand: PcMouseCommand?,
181+
onCommandSelected: (PcMouseCommand) -> Unit
182+
) {
183+
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
184+
PcCommandSectionTitle(titleResId)
185+
PcCommandButtonRow(
186+
specs = specs,
187+
connected = connected,
188+
busyCommand = busyCommand,
189+
onCommandSelected = onCommandSelected,
190+
minHeightDp = 72
191+
)
192+
}
193+
}
194+
195+
@Composable
196+
private fun PcCommandSectionTitle(@StringRes titleResId: Int) {
197+
Text(
198+
text = stringResource(titleResId),
199+
style = MaterialTheme.typography.titleMedium,
200+
color = MaterialTheme.colorScheme.onSurface
201+
)
202+
}
203+
204+
@Composable
205+
private fun PcCommandButtonRow(
206+
specs: List<PcMouseControlSpec>,
207+
connected: Boolean,
208+
busyCommand: PcMouseCommand?,
209+
onCommandSelected: (PcMouseCommand) -> Unit,
210+
minHeightDp: Int
211+
) {
212+
Row(
213+
modifier = Modifier.fillMaxWidth(),
214+
horizontalArrangement = Arrangement.spacedBy(10.dp)
215+
) {
216+
specs.forEach { spec ->
217+
PcCommandButton(
218+
spec = spec,
219+
connected = connected,
220+
busyCommand = busyCommand,
221+
onCommandSelected = onCommandSelected,
222+
minHeightDp = minHeightDp,
223+
modifier = Modifier.weight(1f)
224+
)
59225
}
60226
}
61227
}
62228

229+
@Composable
230+
private fun PcCommandButton(
231+
spec: PcMouseControlSpec,
232+
connected: Boolean,
233+
busyCommand: PcMouseCommand?,
234+
onCommandSelected: (PcMouseCommand) -> Unit,
235+
minHeightDp: Int,
236+
modifier: Modifier = Modifier
237+
) {
238+
Button(
239+
onClick = { onCommandSelected(spec.command) },
240+
enabled = connected && busyCommand == null,
241+
modifier = modifier
242+
.fillMaxWidth()
243+
.heightIn(min = minHeightDp.dp)
244+
) {
245+
Text(
246+
text = stringResource(spec.labelResId),
247+
textAlign = TextAlign.Center
248+
)
249+
}
250+
}
251+
63252
@Composable
64253
fun PcMouseMovementSizeSelector(
65254
selectedSize: PcMouseMovementSize,
@@ -91,20 +280,34 @@ fun PcMouseMovementSizeSelector(
91280
}
92281

93282
fun pcMouseControlSpecs(moveStep: Int): List<PcMouseControlSpec> {
283+
return pcMovementControlSpecs(moveStep) + pcClickControlSpecs() + pcScrollControlSpecs()
284+
}
285+
286+
fun pcMovementControlSpecs(moveStep: Int): List<PcMouseControlSpec> {
94287
val step = moveStep.coerceAtLeast(1)
95-
val scrollStep = 5
96288
return listOf(
97289
PcMouseControlSpec(R.string.pc_mouse_up_left, PcMouseCommand.Move(-step, -step)),
98290
PcMouseControlSpec(R.string.pc_mouse_up, PcMouseCommand.Move(0, -step)),
99291
PcMouseControlSpec(R.string.pc_mouse_up_right, PcMouseCommand.Move(step, -step)),
100292
PcMouseControlSpec(R.string.pc_mouse_left, PcMouseCommand.Move(-step, 0)),
101-
PcMouseControlSpec(R.string.pc_mouse_click, PcMouseCommand.LeftClick),
102293
PcMouseControlSpec(R.string.pc_mouse_right, PcMouseCommand.Move(step, 0)),
103294
PcMouseControlSpec(R.string.pc_mouse_down_left, PcMouseCommand.Move(-step, step)),
104295
PcMouseControlSpec(R.string.pc_mouse_down, PcMouseCommand.Move(0, step)),
105-
PcMouseControlSpec(R.string.pc_mouse_down_right, PcMouseCommand.Move(step, step)),
106-
PcMouseControlSpec(R.string.pc_mouse_right_click, PcMouseCommand.RightClick),
296+
PcMouseControlSpec(R.string.pc_mouse_down_right, PcMouseCommand.Move(step, step))
297+
)
298+
}
299+
300+
fun pcClickControlSpecs(): List<PcMouseControlSpec> {
301+
return listOf(
302+
PcMouseControlSpec(R.string.pc_mouse_click, PcMouseCommand.LeftClick),
107303
PcMouseControlSpec(R.string.pc_mouse_double_click, PcMouseCommand.DoubleClick),
304+
PcMouseControlSpec(R.string.pc_mouse_right_click, PcMouseCommand.RightClick)
305+
)
306+
}
307+
308+
fun pcScrollControlSpecs(): List<PcMouseControlSpec> {
309+
val scrollStep = 5
310+
return listOf(
108311
PcMouseControlSpec(R.string.pc_mouse_scroll_up, PcMouseCommand.Scroll(0, scrollStep)),
109312
PcMouseControlSpec(R.string.pc_mouse_scroll_down, PcMouseCommand.Scroll(0, -scrollStep))
110313
)

app/src/main/java/com/enaboapps/switchify/screens/pc/PcMouseControlActivity.kt

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ import androidx.compose.foundation.layout.Arrangement
1010
import androidx.compose.foundation.layout.Column
1111
import androidx.compose.foundation.layout.fillMaxSize
1212
import androidx.compose.foundation.layout.padding
13+
import androidx.compose.foundation.rememberScrollState
14+
import androidx.compose.foundation.verticalScroll
1315
import androidx.compose.material3.MaterialTheme
1416
import androidx.compose.material3.Scaffold
1517
import androidx.compose.material3.Surface
16-
import androidx.compose.material3.Text
1718
import androidx.compose.runtime.Composable
1819
import androidx.compose.runtime.collectAsState
1920
import androidx.compose.runtime.getValue
@@ -99,33 +100,19 @@ private fun PcMouseControlScreen(
99100
Column(
100101
modifier = Modifier
101102
.fillMaxSize()
103+
.verticalScroll(rememberScrollState())
102104
.padding(16.dp),
103-
verticalArrangement = Arrangement.spacedBy(16.dp)
105+
verticalArrangement = Arrangement.spacedBy(18.dp)
104106
) {
105-
Text(
106-
text = uiState.connectedDisplayName?.let {
107-
stringResource(R.string.pc_mouse_control_connected, it)
108-
} ?: stringResource(R.string.pc_control_connect_first),
109-
style = MaterialTheme.typography.bodyLarge,
110-
color = MaterialTheme.colorScheme.onSurfaceVariant
107+
PcControlStatusStrip(
108+
connectedDisplayName = uiState.connectedDisplayName,
109+
message = uiState.message
111110
)
112-
uiState.message?.let {
113-
Text(
114-
text = it,
115-
style = MaterialTheme.typography.bodyMedium,
116-
color = MaterialTheme.colorScheme.onSurfaceVariant
117-
)
118-
}
119-
Text(
120-
text = stringResource(R.string.pc_mouse_movement_size),
121-
style = MaterialTheme.typography.titleMedium,
122-
color = MaterialTheme.colorScheme.onSurface
123-
)
124-
PcMouseMovementSizeSelector(
111+
PcMovementSizeSection(
125112
selectedSize = uiState.selectedMovementSize,
126113
onSizeSelected = viewModel::selectMovementSize
127114
)
128-
PcMouseCommandGrid(
115+
PcMouseCommandSections(
129116
connected = uiState.connectedDisplayName != null,
130117
movementStep = uiState.movementStep,
131118
busyCommand = uiState.busyCommand,

app/src/main/res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,9 @@
281281
<string name="pc_mouse_movement_small">Small</string>
282282
<string name="pc_mouse_movement_medium">Medium</string>
283283
<string name="pc_mouse_movement_large">Large</string>
284+
<string name="pc_mouse_section_movement">Movement</string>
285+
<string name="pc_mouse_section_clicks">Clicks</string>
286+
<string name="pc_mouse_section_scroll">Scroll</string>
284287
<string name="request_rejected">Request rejected.</string>
285288
<string name="request_expired_try_again">Request expired. Try again.</string>
286289
<string name="pc_mouse_up_left">Up left</string>

0 commit comments

Comments
 (0)