mirror of
https://gitlab.futo.org/keyboard/latinime.git
synced 2024-09-28 14:54:30 +01:00
Update text edit mode
This commit is contained in:
parent
b237e49ece
commit
adfab75086
20
java/res/drawable/copy.xml
Normal file
20
java/res/drawable/copy.xml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M11,9L20,9A2,2 0,0 1,22 11L22,20A2,2 0,0 1,20 22L11,22A2,2 0,0 1,9 20L9,11A2,2 0,0 1,11 9z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M5,15H4a2,2 0,0 1,-2 -2V4a2,2 0,0 1,2 -2h9a2,2 0,0 1,2 2v1"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
27
java/res/drawable/ctrl.xml
Normal file
27
java/res/drawable/ctrl.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<vector android:height="24dp" android:viewportHeight="26"
|
||||||
|
android:viewportWidth="26" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#00000000"
|
||||||
|
android:pathData="M1.995,15.995L23.995,15.995"
|
||||||
|
android:strokeColor="#FFFFFF" android:strokeLineCap="round"
|
||||||
|
android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
<path android:fillColor="#00000000"
|
||||||
|
android:pathData="M24.005,11.995L24.005,15.995"
|
||||||
|
android:strokeColor="#FFFFFF" android:strokeLineCap="round"
|
||||||
|
android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
<path android:fillColor="#00000000"
|
||||||
|
android:pathData="M5.995,10.995a1,1 0,1 0,2 0a1,1 0,1 0,-2 0z"
|
||||||
|
android:strokeColor="#FFFFFF" android:strokeLineCap="round"
|
||||||
|
android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
<path android:fillColor="#00000000"
|
||||||
|
android:pathData="M11.995,10.995a1,1 0,1 0,2 0a1,1 0,1 0,-2 0z"
|
||||||
|
android:strokeColor="#FFFFFF" android:strokeLineCap="round"
|
||||||
|
android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
<path android:fillColor="#00000000"
|
||||||
|
android:pathData="M2.005,11.995L2.005,15.995"
|
||||||
|
android:strokeColor="#FFFFFF" android:strokeLineCap="round"
|
||||||
|
android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
<path android:fillColor="#00000000"
|
||||||
|
android:pathData="M17.995,10.995a1,1 0,1 0,2 0a1,1 0,1 0,-2 0z"
|
||||||
|
android:strokeColor="#FFFFFF" android:strokeLineCap="round"
|
||||||
|
android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
</vector>
|
41
java/res/drawable/cut.xml
Normal file
41
java/res/drawable/cut.xml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M6,6m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M6,18m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M20,4L8.12,15.88"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M14.47,14.48L20,20"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M8.12,8.12L12,12"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
@ -3,29 +3,26 @@ package org.futo.inputmethod.latin.uix.actions
|
|||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
|
import androidx.compose.foundation.LocalIndication
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.ButtonDefaults
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
@ -36,6 +33,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import org.futo.inputmethod.latin.R
|
import org.futo.inputmethod.latin.R
|
||||||
|
import org.futo.inputmethod.latin.common.Constants
|
||||||
import org.futo.inputmethod.latin.uix.Action
|
import org.futo.inputmethod.latin.uix.Action
|
||||||
import org.futo.inputmethod.latin.uix.ActionWindow
|
import org.futo.inputmethod.latin.uix.ActionWindow
|
||||||
|
|
||||||
@ -61,9 +59,43 @@ fun IconWithColor(@DrawableRes iconId: Int, iconColor: Color, modifier: Modifier
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RepeatableActionKey(
|
fun TogglableKey(
|
||||||
|
onToggle: (Boolean) -> Unit,
|
||||||
|
toggled: Boolean,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
contents: @Composable (color: Color) -> Unit
|
||||||
|
) {
|
||||||
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
val isPressed by interactionSource.collectIsPressedAsState()
|
||||||
|
|
||||||
|
LaunchedEffect(isPressed) {
|
||||||
|
if(isPressed) {
|
||||||
|
onToggle(!toggled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Surface(
|
||||||
|
modifier = modifier
|
||||||
|
.padding(4.dp)
|
||||||
|
.clickable(
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
indication = LocalIndication.current,
|
||||||
|
onClick = { }
|
||||||
|
),
|
||||||
|
shape = RoundedCornerShape(8.dp),
|
||||||
|
color = if(toggled) { MaterialTheme.colorScheme.secondary } else { MaterialTheme.colorScheme.secondaryContainer }
|
||||||
|
) {
|
||||||
|
contents(if(toggled) { MaterialTheme.colorScheme.onSecondary } else { MaterialTheme.colorScheme.onSecondaryContainer })
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ActionKey(
|
||||||
onTrigger: () -> Unit,
|
onTrigger: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
repeatable: Boolean = true,
|
||||||
|
color: Color = MaterialTheme.colorScheme.primary,
|
||||||
contents: @Composable () -> Unit
|
contents: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
val interactionSource = remember { MutableInteractionSource() }
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
@ -72,217 +104,235 @@ fun RepeatableActionKey(
|
|||||||
LaunchedEffect(isPressed) {
|
LaunchedEffect(isPressed) {
|
||||||
if(isPressed) {
|
if(isPressed) {
|
||||||
onTrigger()
|
onTrigger()
|
||||||
delay(670L)
|
if(repeatable) {
|
||||||
while(isPressed) {
|
delay(670L)
|
||||||
onTrigger()
|
while (isPressed) {
|
||||||
delay(50L)
|
onTrigger()
|
||||||
|
delay(50L)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Surface(
|
Surface(
|
||||||
modifier = modifier.clickable(
|
modifier = modifier
|
||||||
interactionSource = interactionSource,
|
.padding(4.dp)
|
||||||
indication = null,
|
.clickable(
|
||||||
onClick = { }
|
interactionSource = interactionSource,
|
||||||
),
|
indication = LocalIndication.current,
|
||||||
color = MaterialTheme.colorScheme.primary
|
onClick = { }
|
||||||
|
),
|
||||||
|
shape = RoundedCornerShape(8.dp),
|
||||||
|
color = color
|
||||||
) {
|
) {
|
||||||
contents()
|
contents()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@Preview(showBackground = true)
|
fun ArrowKeys(modifier: Modifier, sendEvent: (Int) -> Unit) {
|
||||||
fun TextEditScreen(onCodePoint: (Int) -> Unit = { _ -> }, onEvent: (Int, Int) -> Unit = { _, _ -> }) {
|
Row(modifier = modifier) {
|
||||||
var shiftState by remember { mutableStateOf(false) }
|
ActionKey(
|
||||||
var ctrlState by remember { mutableStateOf(false) }
|
modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxHeight(),
|
||||||
|
onTrigger = { sendEvent(KeyEvent.KEYCODE_DPAD_LEFT) }
|
||||||
|
) {
|
||||||
|
IconWithColor(
|
||||||
|
iconId = R.drawable.arrow_left,
|
||||||
|
iconColor = MaterialTheme.colorScheme.onPrimary
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxHeight()) {
|
||||||
|
ActionKey(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
onTrigger = { sendEvent(KeyEvent.KEYCODE_DPAD_UP) }
|
||||||
|
) {
|
||||||
|
IconWithColor(
|
||||||
|
iconId = R.drawable.arrow_up,
|
||||||
|
iconColor = MaterialTheme.colorScheme.onPrimary
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ActionKey(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
onTrigger = { sendEvent(KeyEvent.KEYCODE_DPAD_DOWN) }
|
||||||
|
) {
|
||||||
|
IconWithColor(
|
||||||
|
iconId = R.drawable.arrow_down,
|
||||||
|
iconColor = MaterialTheme.colorScheme.onPrimary
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionKey(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxHeight(),
|
||||||
|
onTrigger = { sendEvent(KeyEvent.KEYCODE_DPAD_RIGHT) }
|
||||||
|
) {
|
||||||
|
IconWithColor(
|
||||||
|
iconId = R.drawable.arrow_right,
|
||||||
|
iconColor = MaterialTheme.colorScheme.onPrimary
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CtrlShiftMetaKeys(modifier: Modifier, ctrlState: MutableState<Boolean>, shiftState: MutableState<Boolean>) {
|
||||||
|
Row(modifier = modifier) {
|
||||||
|
TogglableKey(
|
||||||
|
onToggle = { ctrlState.value = it },
|
||||||
|
toggled = ctrlState.value,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxHeight()
|
||||||
|
) {
|
||||||
|
IconWithColor(
|
||||||
|
iconId = R.drawable.ctrl,
|
||||||
|
iconColor = it
|
||||||
|
)
|
||||||
|
}
|
||||||
|
TogglableKey(
|
||||||
|
onToggle = { shiftState.value = it },
|
||||||
|
toggled = shiftState.value,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxHeight()
|
||||||
|
) {
|
||||||
|
IconWithColor(
|
||||||
|
iconId = R.drawable.shift,
|
||||||
|
iconColor = it
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SideKeys(modifier: Modifier, onEvent: (Int, Int) -> Unit, onCodePoint: (Int) -> Unit) {
|
||||||
|
Column(modifier = modifier) {
|
||||||
|
ActionKey(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
repeatable = false,
|
||||||
|
color = MaterialTheme.colorScheme.primaryContainer,
|
||||||
|
onTrigger = { onEvent(KeyEvent.KEYCODE_C, KeyEvent.META_CTRL_ON) }
|
||||||
|
) {
|
||||||
|
IconWithColor(
|
||||||
|
iconId = R.drawable.copy,
|
||||||
|
iconColor = MaterialTheme.colorScheme.onPrimaryContainer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionKey(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
repeatable = false,
|
||||||
|
color = MaterialTheme.colorScheme.primaryContainer,
|
||||||
|
onTrigger = { onEvent(KeyEvent.KEYCODE_V, KeyEvent.META_CTRL_ON) }
|
||||||
|
) {
|
||||||
|
IconWithColor(
|
||||||
|
iconId = R.drawable.clipboard,
|
||||||
|
iconColor = MaterialTheme.colorScheme.onPrimaryContainer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionKey(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
repeatable = true,
|
||||||
|
color = MaterialTheme.colorScheme.primaryContainer,
|
||||||
|
onTrigger = { onCodePoint(Constants.CODE_DELETE) }
|
||||||
|
) {
|
||||||
|
IconWithColor(
|
||||||
|
iconId = R.drawable.delete,
|
||||||
|
iconColor = MaterialTheme.colorScheme.onPrimaryContainer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Row(modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxWidth()) {
|
||||||
|
ActionKey(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxHeight(),
|
||||||
|
repeatable = false,
|
||||||
|
color = MaterialTheme.colorScheme.primaryContainer,
|
||||||
|
onTrigger = { onEvent(KeyEvent.KEYCODE_Z, KeyEvent.META_CTRL_ON) }
|
||||||
|
) {
|
||||||
|
IconWithColor(
|
||||||
|
iconId = R.drawable.undo,
|
||||||
|
iconColor = MaterialTheme.colorScheme.onPrimaryContainer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionKey(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1.0f)
|
||||||
|
.fillMaxHeight(),
|
||||||
|
repeatable = false,
|
||||||
|
color = MaterialTheme.colorScheme.primaryContainer,
|
||||||
|
onTrigger = { onEvent(KeyEvent.KEYCODE_Y, KeyEvent.META_CTRL_ON) }
|
||||||
|
) {
|
||||||
|
IconWithColor(
|
||||||
|
iconId = R.drawable.redo,
|
||||||
|
iconColor = MaterialTheme.colorScheme.onPrimaryContainer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TextEditScreen(onCodePoint: (Int) -> Unit, onEvent: (Int, Int) -> Unit) {
|
||||||
|
val shiftState = remember { mutableStateOf(false) }
|
||||||
|
val ctrlState = remember { mutableStateOf(false) }
|
||||||
|
|
||||||
val metaState = 0 or
|
val metaState = 0 or
|
||||||
(if(shiftState) { KeyEvent.META_SHIFT_ON } else { 0 }) or
|
(if(shiftState.value) { KeyEvent.META_SHIFT_ON } else { 0 }) or
|
||||||
(if(ctrlState) { KeyEvent.META_CTRL_ON } else { 0 })
|
(if(ctrlState.value) { KeyEvent.META_CTRL_ON } else { 0 })
|
||||||
|
|
||||||
|
|
||||||
val buttonColorsUntoggled = ButtonDefaults.buttonColors(
|
|
||||||
containerColor = MaterialTheme.colorScheme.secondaryContainer,
|
|
||||||
contentColor = MaterialTheme.colorScheme.onSecondaryContainer
|
|
||||||
)
|
|
||||||
|
|
||||||
val buttonColorsToggled = ButtonDefaults.buttonColors(
|
|
||||||
containerColor = MaterialTheme.colorScheme.secondary,
|
|
||||||
contentColor = MaterialTheme.colorScheme.onSecondary
|
|
||||||
)
|
|
||||||
|
|
||||||
val sendEvent = { keycode: Int -> onEvent(keycode, metaState) }
|
val sendEvent = { keycode: Int -> onEvent(keycode, metaState) }
|
||||||
|
|
||||||
val keySize = 48.dp
|
Row(modifier = Modifier.fillMaxSize()) {
|
||||||
|
Column(modifier = Modifier
|
||||||
Column {
|
.fillMaxHeight()
|
||||||
Row(modifier = Modifier.fillMaxWidth()) {
|
.weight(3.0f)) {
|
||||||
Spacer(modifier = Modifier.weight(1.0f))
|
ArrowKeys(
|
||||||
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.height(keySize * 2)
|
.weight(3.0f)
|
||||||
.width(keySize * 3)
|
.fillMaxWidth(),
|
||||||
) {
|
sendEvent = sendEvent
|
||||||
RepeatableActionKey(
|
)
|
||||||
modifier = Modifier
|
CtrlShiftMetaKeys(
|
||||||
.align(Alignment.TopStart)
|
|
||||||
.width(keySize)
|
|
||||||
.height(keySize),
|
|
||||||
onTrigger = { sendEvent(KeyEvent.KEYCODE_INSERT) }
|
|
||||||
) {
|
|
||||||
Text("Ins", modifier = Modifier.padding(4.dp))
|
|
||||||
}
|
|
||||||
|
|
||||||
RepeatableActionKey(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.BottomStart)
|
|
||||||
.width(keySize)
|
|
||||||
.height(keySize),
|
|
||||||
onTrigger = { sendEvent(KeyEvent.KEYCODE_DEL) }
|
|
||||||
) {
|
|
||||||
Text("Del", modifier = Modifier.padding(4.dp))
|
|
||||||
}
|
|
||||||
|
|
||||||
RepeatableActionKey(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.TopCenter)
|
|
||||||
.width(keySize)
|
|
||||||
.height(keySize),
|
|
||||||
onTrigger = { sendEvent(KeyEvent.KEYCODE_MOVE_HOME) }
|
|
||||||
) {
|
|
||||||
Text("Home", modifier = Modifier.padding(4.dp))
|
|
||||||
}
|
|
||||||
|
|
||||||
RepeatableActionKey(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.BottomCenter)
|
|
||||||
.width(keySize)
|
|
||||||
.height(keySize),
|
|
||||||
onTrigger = { sendEvent(KeyEvent.KEYCODE_MOVE_END) }
|
|
||||||
) {
|
|
||||||
Text("End", modifier = Modifier.padding(4.dp))
|
|
||||||
}
|
|
||||||
|
|
||||||
RepeatableActionKey(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.TopEnd)
|
|
||||||
.width(keySize)
|
|
||||||
.height(keySize),
|
|
||||||
onTrigger = { sendEvent(KeyEvent.KEYCODE_PAGE_UP) }
|
|
||||||
) {
|
|
||||||
Text("PgUp", modifier = Modifier.padding(4.dp))
|
|
||||||
}
|
|
||||||
|
|
||||||
RepeatableActionKey(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.BottomEnd)
|
|
||||||
.width(keySize)
|
|
||||||
.height(keySize),
|
|
||||||
onTrigger = { sendEvent(KeyEvent.KEYCODE_PAGE_DOWN) }
|
|
||||||
) {
|
|
||||||
Text("PgDn", modifier = Modifier.padding(4.dp))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(32.dp))
|
|
||||||
Row(modifier = Modifier.fillMaxWidth()) {
|
|
||||||
Box(modifier = Modifier.height(92.dp)) {
|
|
||||||
Button(
|
|
||||||
onClick = { shiftState = !shiftState },
|
|
||||||
colors = if (shiftState) {
|
|
||||||
buttonColorsToggled
|
|
||||||
} else {
|
|
||||||
buttonColorsUntoggled
|
|
||||||
},
|
|
||||||
modifier = Modifier.align(Alignment.TopStart).width(keySize * 3)
|
|
||||||
) {
|
|
||||||
Row {
|
|
||||||
Text("Shift")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Button(
|
|
||||||
onClick = { ctrlState = !ctrlState },
|
|
||||||
colors = if (ctrlState) {
|
|
||||||
buttonColorsToggled
|
|
||||||
} else {
|
|
||||||
buttonColorsUntoggled
|
|
||||||
},
|
|
||||||
modifier = Modifier.align(Alignment.BottomStart).width(keySize * 2)
|
|
||||||
) {
|
|
||||||
Text("Ctrl")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.weight(1.0f))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.height(keySize * 2)
|
.weight(1.0f)
|
||||||
.width(keySize * 3)
|
.fillMaxWidth(),
|
||||||
) {
|
ctrlState = ctrlState,
|
||||||
RepeatableActionKey(
|
shiftState = shiftState
|
||||||
modifier = Modifier
|
)
|
||||||
.align(Alignment.TopCenter)
|
|
||||||
.width(keySize)
|
|
||||||
.height(keySize),
|
|
||||||
onTrigger = { sendEvent(KeyEvent.KEYCODE_DPAD_UP) }
|
|
||||||
) {
|
|
||||||
IconWithColor(
|
|
||||||
iconId = R.drawable.arrow_up,
|
|
||||||
iconColor = MaterialTheme.colorScheme.onPrimary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RepeatableActionKey(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.BottomCenter)
|
|
||||||
.width(keySize)
|
|
||||||
.height(keySize),
|
|
||||||
onTrigger = { sendEvent(KeyEvent.KEYCODE_DPAD_DOWN) }
|
|
||||||
) {
|
|
||||||
IconWithColor(
|
|
||||||
iconId = R.drawable.arrow_down,
|
|
||||||
iconColor = MaterialTheme.colorScheme.onPrimary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
RepeatableActionKey(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.BottomStart)
|
|
||||||
.width(keySize)
|
|
||||||
.height(keySize),
|
|
||||||
onTrigger = { sendEvent(KeyEvent.KEYCODE_DPAD_LEFT) }
|
|
||||||
) {
|
|
||||||
IconWithColor(
|
|
||||||
iconId = R.drawable.arrow_left,
|
|
||||||
iconColor = MaterialTheme.colorScheme.onPrimary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
RepeatableActionKey(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.BottomEnd)
|
|
||||||
.width(keySize)
|
|
||||||
.height(keySize),
|
|
||||||
onTrigger = { sendEvent(KeyEvent.KEYCODE_DPAD_RIGHT) }
|
|
||||||
) {
|
|
||||||
IconWithColor(
|
|
||||||
iconId = R.drawable.arrow_right,
|
|
||||||
iconColor = MaterialTheme.colorScheme.onPrimary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
SideKeys(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxHeight()
|
||||||
|
.weight(1.0f),
|
||||||
|
onEvent = onEvent,
|
||||||
|
onCodePoint = onCodePoint
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,4 +357,12 @@ val TextEditAction = Action(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
fun TextEditScreenPreview() {
|
||||||
|
Surface(modifier = Modifier.height(256.dp)) {
|
||||||
|
TextEditScreen(onCodePoint = { }, onEvent = { _, _ -> })
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user