Skip to content

Commit 7bc093e

Browse files
committed
Rewrite on screen controls using Compose
1 parent 362c42f commit 7bc093e

File tree

5 files changed

+319
-538
lines changed

5 files changed

+319
-538
lines changed
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
package rs.ruffle
2+
3+
import androidx.compose.foundation.layout.Arrangement
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.PaddingValues
6+
import androidx.compose.foundation.layout.Row
7+
import androidx.compose.foundation.layout.Spacer
8+
import androidx.compose.foundation.layout.fillMaxWidth
9+
import androidx.compose.foundation.layout.padding
10+
import androidx.compose.foundation.layout.width
11+
import androidx.compose.material.icons.Icons
12+
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
13+
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
14+
import androidx.compose.material.icons.filled.Check
15+
import androidx.compose.material.icons.filled.KeyboardArrowDown
16+
import androidx.compose.material.icons.filled.KeyboardArrowUp
17+
import androidx.compose.material3.Button
18+
import androidx.compose.material3.DropdownMenu
19+
import androidx.compose.material3.DropdownMenuItem
20+
import androidx.compose.material3.HorizontalDivider
21+
import androidx.compose.material3.Icon
22+
import androidx.compose.material3.Surface
23+
import androidx.compose.material3.Text
24+
import androidx.compose.runtime.Composable
25+
import androidx.compose.runtime.getValue
26+
import androidx.compose.runtime.mutableStateOf
27+
import androidx.compose.runtime.saveable.rememberSaveable
28+
import androidx.compose.ui.Modifier
29+
import androidx.compose.ui.graphics.RectangleShape
30+
import androidx.compose.ui.graphics.vector.ImageVector
31+
import androidx.compose.ui.tooling.preview.Preview
32+
import androidx.compose.ui.unit.dp
33+
import rs.ruffle.ui.theme.RuffleTheme
34+
35+
val BUTTON_ROWS = arrayOf(
36+
arrayOf(
37+
KeyboardButton(keyCode = 49, keyChar = '1'),
38+
KeyboardButton(keyCode = 50, keyChar = '2'),
39+
KeyboardButton(keyCode = 51, keyChar = '3'),
40+
KeyboardButton(keyCode = 52, keyChar = '4'),
41+
KeyboardButton(keyCode = 53, keyChar = '5'),
42+
KeyboardButton(keyCode = 54, keyChar = '6'),
43+
KeyboardButton(keyCode = 55, keyChar = '7'),
44+
KeyboardButton(keyCode = 56, keyChar = '8'),
45+
KeyboardButton(keyCode = 57, keyChar = '9'),
46+
KeyboardButton(keyCode = 48, keyChar = '0')
47+
),
48+
arrayOf(
49+
KeyboardButton(keyCode = 81, keyChar = 'q', text = "Q"),
50+
KeyboardButton(keyCode = 87, keyChar = 'w', text = "W"),
51+
KeyboardButton(keyCode = 69, keyChar = 'e', text = "E"),
52+
KeyboardButton(keyCode = 82, keyChar = 'r', text = "R"),
53+
KeyboardButton(keyCode = 84, keyChar = 't', text = "T"),
54+
KeyboardButton(keyCode = 89, keyChar = 'y', text = "Y"),
55+
KeyboardButton(keyCode = 85, keyChar = 'u', text = "U"),
56+
KeyboardButton(keyCode = 73, keyChar = 'i', text = "I"),
57+
KeyboardButton(keyCode = 79, keyChar = 'o', text = "O"),
58+
KeyboardButton(keyCode = 80, keyChar = 'p', text = "P")
59+
),
60+
arrayOf(
61+
KeyboardButton(keyCode = 65, keyChar = 'a', text = "A"),
62+
KeyboardButton(keyCode = 83, keyChar = 's', text = "S"),
63+
KeyboardButton(keyCode = 68, keyChar = 'd', text = "D"),
64+
KeyboardButton(keyCode = 70, keyChar = 'f', text = "F"),
65+
KeyboardButton(keyCode = 71, keyChar = 'g', text = "G"),
66+
KeyboardButton(keyCode = 72, keyChar = 'h', text = "H"),
67+
KeyboardButton(keyCode = 74, keyChar = 'j', text = "J"),
68+
KeyboardButton(keyCode = 75, keyChar = 'k', text = "K"),
69+
KeyboardButton(keyCode = 76, keyChar = 'l', text = "L")
70+
),
71+
arrayOf(
72+
KeyboardButton(keyCode = 90, keyChar = 'z', text = "Z"),
73+
KeyboardButton(keyCode = 88, keyChar = 'x', text = "X"),
74+
KeyboardButton(keyCode = 67, keyChar = 'c', text = "C"),
75+
KeyboardButton(keyCode = 86, keyChar = 'v', text = "V"),
76+
KeyboardButton(keyCode = 66, keyChar = 'b', text = "B"),
77+
KeyboardButton(keyCode = 78, keyChar = 'n', text = "N"),
78+
KeyboardButton(keyCode = 77, keyChar = 'm', text = "M")
79+
),
80+
arrayOf(
81+
KeyboardButton(keyCode = 17, text = "CTRL"),
82+
KeyboardButton(keyCode = 18, text = "ALT"),
83+
KeyboardButton(keyCode = 32, keyChar = ' ', text = ""),
84+
KeyboardButton(
85+
keyCode = 37,
86+
icon = Icons.AutoMirrored.Filled.KeyboardArrowLeft,
87+
text = "Left"
88+
),
89+
KeyboardButton(keyCode = 38, icon = Icons.Filled.KeyboardArrowUp, text = "Up"),
90+
KeyboardButton(keyCode = 40, icon = Icons.Filled.KeyboardArrowDown, text = "Down"),
91+
KeyboardButton(
92+
keyCode = 39,
93+
icon = Icons.AutoMirrored.Filled.KeyboardArrowRight,
94+
text = "Right"
95+
)
96+
)
97+
)
98+
99+
data class KeyboardButton(
100+
val keyCode: Byte,
101+
val keyChar: Char = '\u0000',
102+
val text: String = keyChar.toString(),
103+
val icon: ImageVector? = null
104+
)
105+
106+
class ContextMenuItem(
107+
val text: String,
108+
val separatorBefore: Boolean,
109+
val enabled: Boolean,
110+
val checked: Boolean,
111+
val onClick: () -> Unit
112+
)
113+
114+
@Composable
115+
fun OnScreenControls(
116+
onKeyClick: (code: Byte, char: Char) -> Unit,
117+
onShowContextMenu: () -> Unit,
118+
onHideContextMenu: () -> Unit,
119+
contextMenuItems: List<ContextMenuItem>
120+
) {
121+
val showKeyboard by rememberSaveable { mutableStateOf(true) }
122+
val menuHasAnyCheckmark = contextMenuItems.any { it.checked }
123+
124+
Surface {
125+
Column(modifier = Modifier.padding(horizontal = 1.dp)) {
126+
if (showKeyboard) {
127+
VirtualKeyboard(onKeyClick)
128+
}
129+
130+
BottomMenu(
131+
showKeyboard,
132+
onShowContextMenu,
133+
contextMenuItems,
134+
onHideContextMenu,
135+
menuHasAnyCheckmark
136+
)
137+
}
138+
}
139+
}
140+
141+
@Composable
142+
private fun BottomMenu(
143+
showKeyboard: Boolean,
144+
onShowContextMenu: () -> Unit,
145+
contextMenuItems: List<ContextMenuItem>,
146+
onHideContextMenu: () -> Unit,
147+
menuHasAnyCheckmark: Boolean
148+
) {
149+
var showKeyboard1 = showKeyboard
150+
Row(
151+
modifier = Modifier.fillMaxWidth(),
152+
horizontalArrangement = Arrangement.SpaceBetween
153+
) {
154+
Button(
155+
onClick = { showKeyboard1 = !showKeyboard1 },
156+
contentPadding = PaddingValues(1.dp),
157+
shape = RectangleShape
158+
) {
159+
Text("")
160+
}
161+
162+
Button(
163+
onClick = { onShowContextMenu() },
164+
contentPadding = PaddingValues(1.dp),
165+
shape = RectangleShape
166+
) {
167+
DropdownMenu(
168+
expanded = contextMenuItems.isNotEmpty(),
169+
onDismissRequest = { onHideContextMenu() }
170+
) {
171+
contextMenuItems.forEach {
172+
if (it.separatorBefore) {
173+
HorizontalDivider()
174+
}
175+
DropdownMenuItem(
176+
enabled = it.enabled,
177+
text = {
178+
Row {
179+
if (menuHasAnyCheckmark) {
180+
if (it.checked) {
181+
Icon(Icons.Filled.Check, "")
182+
} else {
183+
Spacer(
184+
modifier = Modifier.width(
185+
Icons.Filled.Check.defaultWidth
186+
)
187+
)
188+
}
189+
}
190+
Text(it.text)
191+
}
192+
},
193+
onClick = { it.onClick() }
194+
)
195+
}
196+
}
197+
Text("")
198+
}
199+
}
200+
}
201+
202+
@Composable
203+
private fun VirtualKeyboard(onKeyClick: (code: Byte, char: Char) -> Unit) {
204+
Column {
205+
BUTTON_ROWS.forEach {
206+
Row(
207+
modifier = Modifier.fillMaxWidth(),
208+
horizontalArrangement = Arrangement.spacedBy(3.dp)
209+
) {
210+
it.forEach {
211+
TextButton(
212+
modifier = Modifier.weight(1f),
213+
button = it,
214+
onKeyClick
215+
)
216+
}
217+
}
218+
}
219+
}
220+
}
221+
222+
@Composable
223+
fun TextButton(
224+
modifier: Modifier,
225+
button: KeyboardButton,
226+
onKeyClick: (code: Byte, char: Char) -> Unit
227+
) {
228+
Button(
229+
modifier = modifier,
230+
onClick = {
231+
onKeyClick(button.keyCode, button.keyChar)
232+
},
233+
contentPadding = PaddingValues(1.dp),
234+
shape = RectangleShape
235+
) {
236+
if (button.icon != null) {
237+
Icon(button.icon, contentDescription = button.text)
238+
} else {
239+
Text(text = button.text)
240+
}
241+
}
242+
}
243+
244+
@Preview
245+
@Composable
246+
fun OnScreenControlsPreview() {
247+
RuffleTheme {
248+
OnScreenControls(
249+
onKeyClick = { _: Byte, _: Char -> },
250+
onShowContextMenu = {},
251+
onHideContextMenu = {},
252+
contextMenuItems = listOf()
253+
)
254+
}
255+
}

0 commit comments

Comments
 (0)