mirror of
https://gitlab.futo.org/keyboard/latinime.git
synced 2024-09-28 14:54:30 +01:00
Add basic text edit mode
This commit is contained in:
parent
7f17d66072
commit
b237e49ece
20
java/res/drawable/arrow_down.xml
Normal file
20
java/res/drawable/arrow_down.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="M12,5L12,19"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M19,12l-7,7l-7,-7"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
@ -1,20 +1,20 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="26dp"
|
android:width="24dp"
|
||||||
android:height="26dp"
|
android:height="24dp"
|
||||||
android:viewportWidth="26"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="26">
|
android:viewportHeight="24">
|
||||||
<path
|
<path
|
||||||
android:pathData="M20,13L6,13"
|
android:pathData="M19,12L5,12"
|
||||||
android:strokeLineJoin="round"
|
android:strokeLineJoin="round"
|
||||||
android:strokeWidth="2"
|
android:strokeWidth="2"
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:strokeColor="#FFFFFF"
|
android:strokeColor="#ffffff"
|
||||||
android:strokeLineCap="round"/>
|
android:strokeLineCap="round"/>
|
||||||
<path
|
<path
|
||||||
android:pathData="M13,20L6,13L13,6"
|
android:pathData="M12,19l-7,-7l7,-7"
|
||||||
android:strokeLineJoin="round"
|
android:strokeLineJoin="round"
|
||||||
android:strokeWidth="2"
|
android:strokeWidth="2"
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
android:strokeColor="#FFFFFF"
|
android:strokeColor="#ffffff"
|
||||||
android:strokeLineCap="round"/>
|
android:strokeLineCap="round"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
20
java/res/drawable/arrow_left_26.xml
Normal file
20
java/res/drawable/arrow_left_26.xml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="26dp"
|
||||||
|
android:height="26dp"
|
||||||
|
android:viewportWidth="26"
|
||||||
|
android:viewportHeight="26">
|
||||||
|
<path
|
||||||
|
android:pathData="M20,13L6,13"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#FFFFFF"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M13,20L6,13L13,6"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#FFFFFF"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
20
java/res/drawable/arrow_right.xml
Normal file
20
java/res/drawable/arrow_right.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="M5,12L19,12"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M12,5l7,7l-7,7"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
20
java/res/drawable/arrow_up.xml
Normal file
20
java/res/drawable/arrow_up.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="M12,19L12,5"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M5,12l7,-7l7,7"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
20
java/res/drawable/edit_text.xml
Normal file
20
java/res/drawable/edit_text.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,4H4a2,2 0,0 0,-2 2v14a2,2 0,0 0,2 2h14a2,2 0,0 0,2 -2v-7"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M18.5,2.5a2.121,2.121 0,0 1,3 3L12,15l-4,1 1,-4 9.5,-9.5z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
@ -2,9 +2,11 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="voice_input_action_title">Voice Input</string>
|
<string name="voice_input_action_title">Voice Input</string>
|
||||||
<string name="theme_switcher_action_title">Theme Switcher</string>
|
<string name="theme_switcher_action_title">Theme Switcher</string>
|
||||||
|
<string name="emoji_action_title">Emojis</string>
|
||||||
<string name="clipboard_action_title">Paste from Clipboard</string>
|
<string name="clipboard_action_title">Paste from Clipboard</string>
|
||||||
<string name="undo_action_title">Undo</string>
|
<string name="undo_action_title">Undo</string>
|
||||||
<string name="redo_action_title">Redo</string>
|
<string name="redo_action_title">Redo</string>
|
||||||
|
<string name="text_edit_action_title">Text Editor</string>
|
||||||
|
|
||||||
<string name="amoled_dark_theme_name">AMOLED Dark Purple</string>
|
<string name="amoled_dark_theme_name">AMOLED Dark Purple</string>
|
||||||
<string name="classic_material_dark_theme_name">AOSP Material Dark</string>
|
<string name="classic_material_dark_theme_name">AOSP Material Dark</string>
|
||||||
|
@ -573,5 +573,4 @@ Tip: You can download and remove dictionaries by going to <b>Languages &
|
|||||||
This resource is copied from packages/apps/Settings/res/values/strings.xml -->
|
This resource is copied from packages/apps/Settings/res/values/strings.xml -->
|
||||||
<!-- This resource is corresponding to msgid="5433275485499039199" -->
|
<!-- This resource is corresponding to msgid="5433275485499039199" -->
|
||||||
<string name="user_dict_fast_scroll_alphabet">\u0020ABCDEFGHIJKLMNOPQRSTUVWXYZ</string>
|
<string name="user_dict_fast_scroll_alphabet">\u0020ABCDEFGHIJKLMNOPQRSTUVWXYZ</string>
|
||||||
<string name="title_emojis">Emojis</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -5,8 +5,6 @@ import android.content.res.Configuration
|
|||||||
import android.inputmethodservice.InputMethodService
|
import android.inputmethodservice.InputMethodService
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.SystemClock
|
|
||||||
import android.view.KeyCharacterMap
|
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.inputmethod.CompletionInfo
|
import android.view.inputmethod.CompletionInfo
|
||||||
@ -359,7 +357,7 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
|
|||||||
returnBackToMainKeyboardViewFromAction()
|
returnBackToMainKeyboardViewFromAction()
|
||||||
}) {
|
}) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(id = R.drawable.arrow_left),
|
painter = painterResource(id = R.drawable.arrow_left_26),
|
||||||
contentDescription = "Back"
|
contentDescription = "Back"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@ import org.futo.inputmethod.latin.suggestions.SuggestionStripView
|
|||||||
import org.futo.inputmethod.latin.uix.actions.ClipboardAction
|
import org.futo.inputmethod.latin.uix.actions.ClipboardAction
|
||||||
import org.futo.inputmethod.latin.uix.actions.EmojiAction
|
import org.futo.inputmethod.latin.uix.actions.EmojiAction
|
||||||
import org.futo.inputmethod.latin.uix.actions.RedoAction
|
import org.futo.inputmethod.latin.uix.actions.RedoAction
|
||||||
|
import org.futo.inputmethod.latin.uix.actions.TextEditAction
|
||||||
import org.futo.inputmethod.latin.uix.actions.ThemeAction
|
import org.futo.inputmethod.latin.uix.actions.ThemeAction
|
||||||
import org.futo.inputmethod.latin.uix.actions.UndoAction
|
import org.futo.inputmethod.latin.uix.actions.UndoAction
|
||||||
import org.futo.inputmethod.latin.uix.actions.VoiceInputAction
|
import org.futo.inputmethod.latin.uix.actions.VoiceInputAction
|
||||||
@ -324,6 +325,7 @@ fun RowScope.ActionItems(onSelect: (Action) -> Unit) {
|
|||||||
ActionItem(UndoAction, onSelect)
|
ActionItem(UndoAction, onSelect)
|
||||||
ActionItem(RedoAction, onSelect)
|
ActionItem(RedoAction, onSelect)
|
||||||
ActionItem(ClipboardAction, onSelect)
|
ActionItem(ClipboardAction, onSelect)
|
||||||
|
ActionItem(TextEditAction, onSelect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ class PersistentEmojiState: PersistentActionState {
|
|||||||
|
|
||||||
val EmojiAction = Action(
|
val EmojiAction = Action(
|
||||||
icon = R.drawable.smile,
|
icon = R.drawable.smile,
|
||||||
name = R.string.title_emojis,
|
name = R.string.emoji_action_title,
|
||||||
simplePressImpl = null,
|
simplePressImpl = null,
|
||||||
persistentState = { manager ->
|
persistentState = { manager ->
|
||||||
val state = PersistentEmojiState()
|
val state = PersistentEmojiState()
|
||||||
@ -283,7 +283,7 @@ val EmojiAction = Action(
|
|||||||
object : ActionWindow {
|
object : ActionWindow {
|
||||||
@Composable
|
@Composable
|
||||||
override fun windowName(): String {
|
override fun windowName(): String {
|
||||||
return stringResource(R.string.title_emojis)
|
return stringResource(R.string.emoji_action_title)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -0,0 +1,310 @@
|
|||||||
|
package org.futo.inputmethod.latin.uix.actions
|
||||||
|
|
||||||
|
import android.view.KeyEvent
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.compose.foundation.Canvas
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
|
import androidx.compose.ui.graphics.drawscope.translate
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import org.futo.inputmethod.latin.R
|
||||||
|
import org.futo.inputmethod.latin.uix.Action
|
||||||
|
import org.futo.inputmethod.latin.uix.ActionWindow
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun IconWithColor(@DrawableRes iconId: Int, iconColor: Color, modifier: Modifier = Modifier) {
|
||||||
|
val icon = painterResource(id = iconId)
|
||||||
|
|
||||||
|
Canvas(modifier = modifier) {
|
||||||
|
translate(
|
||||||
|
left = this.size.width / 2.0f - icon.intrinsicSize.width / 2.0f,
|
||||||
|
top = this.size.height / 2.0f - icon.intrinsicSize.height / 2.0f
|
||||||
|
) {
|
||||||
|
with(icon) {
|
||||||
|
draw(
|
||||||
|
icon.intrinsicSize,
|
||||||
|
colorFilter = ColorFilter.tint(
|
||||||
|
iconColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun RepeatableActionKey(
|
||||||
|
onTrigger: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
contents: @Composable () -> Unit
|
||||||
|
) {
|
||||||
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
val isPressed by interactionSource.collectIsPressedAsState()
|
||||||
|
|
||||||
|
LaunchedEffect(isPressed) {
|
||||||
|
if(isPressed) {
|
||||||
|
onTrigger()
|
||||||
|
delay(670L)
|
||||||
|
while(isPressed) {
|
||||||
|
onTrigger()
|
||||||
|
delay(50L)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Surface(
|
||||||
|
modifier = modifier.clickable(
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
indication = null,
|
||||||
|
onClick = { }
|
||||||
|
),
|
||||||
|
color = MaterialTheme.colorScheme.primary
|
||||||
|
) {
|
||||||
|
contents()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
fun TextEditScreen(onCodePoint: (Int) -> Unit = { _ -> }, onEvent: (Int, Int) -> Unit = { _, _ -> }) {
|
||||||
|
var shiftState by remember { mutableStateOf(false) }
|
||||||
|
var ctrlState by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val metaState = 0 or
|
||||||
|
(if(shiftState) { KeyEvent.META_SHIFT_ON } else { 0 }) or
|
||||||
|
(if(ctrlState) { 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 keySize = 48.dp
|
||||||
|
|
||||||
|
Column {
|
||||||
|
Row(modifier = Modifier.fillMaxWidth()) {
|
||||||
|
Spacer(modifier = Modifier.weight(1.0f))
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.height(keySize * 2)
|
||||||
|
.width(keySize * 3)
|
||||||
|
) {
|
||||||
|
RepeatableActionKey(
|
||||||
|
modifier = Modifier
|
||||||
|
.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
|
||||||
|
.height(keySize * 2)
|
||||||
|
.width(keySize * 3)
|
||||||
|
) {
|
||||||
|
RepeatableActionKey(
|
||||||
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val TextEditAction = Action(
|
||||||
|
icon = R.drawable.edit_text,
|
||||||
|
name = R.string.text_edit_action_title,
|
||||||
|
simplePressImpl = null,
|
||||||
|
persistentState = null,
|
||||||
|
windowImpl = { manager, persistentState ->
|
||||||
|
object : ActionWindow {
|
||||||
|
@Composable
|
||||||
|
override fun windowName(): String {
|
||||||
|
return stringResource(R.string.text_edit_action_title)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun WindowContents() {
|
||||||
|
TextEditScreen(onCodePoint = { a -> manager.sendCodePointEvent(a)}, onEvent = { a, b -> manager.sendKeyEvent(a, b) })
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user