diff --git a/README.md b/README.md index 1e4fd0f6..1d8f2cc0 100644 --- a/README.md +++ b/README.md @@ -123,8 +123,6 @@ See [Contribution Guidelines](CONTRIBUTING.md) # To-do __Planned features and improvements:__ -* Customizable functional key layout - * Will likely result in having the same functional key layout for alphabet and symbols layouts * Improve support for modifier keys (_alt_, _ctrl_, _meta_ and _fn_), some ideas: * keep modifier keys on with long press * keep modifier keys on until the next key press diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.kt index a8a7a250..9c10953e 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.kt @@ -7,6 +7,7 @@ import helium314.keyboard.latin.R import helium314.keyboard.latin.utils.Log import helium314.keyboard.latin.utils.ToolbarKey import helium314.keyboard.latin.utils.getStyleableIconId +import java.util.Locale class KeyboardIconsSet { private val iconsByName = HashMap(styleableIdByName.size) @@ -94,6 +95,6 @@ class KeyboardIconsSet { NAME_START_ONEHANDED_KEY to R.styleable.Keyboard_iconStartOneHandedMode, NAME_STOP_ONEHANDED_KEY to R.styleable.Keyboard_iconStopOneHandedMode, NAME_SWITCH_ONEHANDED_KEY to R.styleable.Keyboard_iconSwitchOneHandedMode, - ).apply { ToolbarKey.entries.forEach { put(it.name, getStyleableIconId(it)) } } + ).apply { ToolbarKey.entries.forEach { put(it.name.lowercase(Locale.US), getStyleableIconId(it)) } } } } diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyLabel.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyLabel.kt index 01752b66..938f6598 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyLabel.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyLabel.kt @@ -24,6 +24,10 @@ object KeyLabel { const val CURRENCY3 = "$$$3" const val CURRENCY4 = "$$$4" const val CURRENCY5 = "$$$5" + const val CTRL = "ctrl" + const val ALT = "alt" + const val FN = "fn" + const val META = "meta" /** to make sure a FlorisBoard label works when reading a JSON layout */ // resulting special labels should be names of FunctionalKey enum, case insensitive diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt index 39f64a8e..002fa7aa 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt @@ -24,6 +24,10 @@ import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.spellcheck.AndroidSpellCheckerService import helium314.keyboard.latin.utils.InputTypeUtils import helium314.keyboard.latin.utils.Log +import helium314.keyboard.latin.utils.ToolbarKey +import helium314.keyboard.latin.utils.getCodeForToolbarKey +import helium314.keyboard.latin.utils.toolbarKeyStrings +import java.util.Locale // taken from FlorisBoard, small modifications (see also KeyData) // internal keys removed (currently no plan to support them) @@ -396,7 +400,8 @@ sealed interface KeyData : AbstractKeyData { // functional keys when (label) { // or use code? KeyLabel.SYMBOL_ALPHA, KeyLabel.SYMBOL, KeyLabel.ALPHA, KeyLabel.COMMA, KeyLabel.PERIOD, KeyLabel.DELETE, - KeyLabel.EMOJI, KeyLabel.COM, KeyLabel.LANGUAGE_SWITCH, KeyLabel.NUMPAD -> return Key.BACKGROUND_TYPE_FUNCTIONAL + KeyLabel.EMOJI, KeyLabel.COM, KeyLabel.LANGUAGE_SWITCH, KeyLabel.NUMPAD, KeyLabel.CTRL, KeyLabel.ALT, + KeyLabel.FN, KeyLabel.META -> return Key.BACKGROUND_TYPE_FUNCTIONAL KeyLabel.SPACE, KeyLabel.ZWNJ -> return Key.BACKGROUND_TYPE_SPACEBAR KeyLabel.ACTION -> return Key.BACKGROUND_TYPE_ACTION KeyLabel.SHIFT -> return getShiftBackground(params) @@ -445,7 +450,12 @@ sealed interface KeyData : AbstractKeyData { KeyLabel.CURRENCY3 -> params.mLocaleKeyboardInfos.currencyKey.second[2] KeyLabel.CURRENCY4 -> params.mLocaleKeyboardInfos.currencyKey.second[3] KeyLabel.CURRENCY5 -> params.mLocaleKeyboardInfos.currencyKey.second[4] - else -> label + KeyLabel.CTRL, KeyLabel.ALT, KeyLabel.FN, KeyLabel.META -> label.uppercase(Locale.US) + else -> { + if (label in toolbarKeyStrings) { + "!icon/$label|" + } else label + } } private fun processCode(): Int { @@ -454,7 +464,15 @@ sealed interface KeyData : AbstractKeyData { KeyLabel.SYMBOL_ALPHA -> KeyCode.SYMBOL_ALPHA KeyLabel.SYMBOL -> KeyCode.SYMBOL KeyLabel.ALPHA -> KeyCode.ALPHA - else -> code + KeyLabel.CTRL -> KeyCode.CTRL + KeyLabel.ALT -> KeyCode.ALT + KeyLabel.FN -> KeyCode.FN + KeyLabel.META -> KeyCode.META + else -> { + if (label in toolbarKeyStrings) { + getCodeForToolbarKey(ToolbarKey.valueOf(label.uppercase(Locale.US))) + } else code + } } } @@ -476,6 +494,7 @@ sealed interface KeyData : AbstractKeyData { KeyLabel.COM -> Key.LABEL_FLAGS_AUTO_X_SCALE or Key.LABEL_FLAGS_FONT_NORMAL or Key.LABEL_FLAGS_HAS_POPUP_HINT or Key.LABEL_FLAGS_PRESERVE_CASE KeyLabel.ZWNJ -> Key.LABEL_FLAGS_HAS_POPUP_HINT KeyLabel.CURRENCY -> Key.LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO + KeyLabel.CTRL, KeyLabel.ALT, KeyLabel.FN, KeyLabel.META -> Key.LABEL_FLAGS_PRESERVE_CASE else -> 0 } } diff --git a/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt index f3d78a80..8aac2046 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt @@ -14,6 +14,7 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode import helium314.keyboard.latin.R import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.utils.ToolbarKey.* +import java.util.Locale fun createToolbarKey(context: Context, keyboardAttr: TypedArray, key: ToolbarKey): ImageButton { val button = ImageButton(context, null, R.attr.suggestionWordStyle) @@ -56,7 +57,7 @@ fun getCodeForToolbarKey(key: ToolbarKey) = when (key) { FULL_LEFT -> KeyCode.MOVE_START_OF_LINE FULL_RIGHT -> KeyCode.MOVE_END_OF_LINE SELECT_WORD -> KeyCode.CLIPBOARD_SELECT_WORD - CLEAR_CLIPBOARD -> KeyCode.UNSPECIFIED // not managed via code input + CLEAR_CLIPBOARD -> KeyCode.UNSPECIFIED // not managed via code input. todo: probably it should be CLOSE_HISTORY -> KeyCode.ALPHA } @@ -111,6 +112,8 @@ enum class ToolbarKey { FULL_LEFT, FULL_RIGHT, INCOGNITO, AUTOCORRECT, CLEAR_CLIPBOARD, CLOSE_HISTORY } +val toolbarKeyStrings: Set = entries.mapTo(HashSet()) { it.toString().lowercase(Locale.US) } + fun toToolbarKeyString(keys: Collection) = keys.joinToString(";") { it.name } val defaultToolbarPref = entries.filterNot { it == CLEAR_CLIPBOARD || it == CLOSE_HISTORY }.joinToString(";") { diff --git a/layouts.md b/layouts.md index 13dd05dc..19c3e584 100644 --- a/layouts.md +++ b/layouts.md @@ -89,12 +89,16 @@ Usually the label is what is displayed on the key. However, there are some speci * _comma_: `,` key with special popups, will adapt to language-specific comma, or display `/` in URL fields and `@` in email fields * _space_: space key, with icon when using a number layout * _zwnj_: Zero-width non-joiner (automatically added next to space in alphabet layout for some languages) + * You can also use [toolbar keys](/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt#L109), e.g. _undo_. + * See [KeyLabel.kt](app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyLabel.kt) for more available labels +* In case a label clashes with text you want to add, put a `\` in front of the text you want, e.g. `\space` will write the label `space` instead of adding a space bar. + * Note that you need to escape the `\` in json files by adding a second `\`. * If you want different key label and input text, set the label to [label]|[text], e.g. `aa|bb` will show `aa`, but pressing the key will input `bb`. You can also specify special key codes like `a|!code/key_action_previous`, but it's cleaner to use a json layout and specify the code explicitly. Note that when specifying a code in the label, and a code in a json layout, the code in the label will be ignored. * It's also possible to specify an icon, like `!icon/previous_key|!code/key_action_previous`. * For normal keys, even if you specify a code, you will need to add a `|` to the label, e.g. `!icon/go_key|` or `!icon/go_key|ignored` (to be fixed). * For popups keys, you must _not_ add a `|` (to be fixed). - * You can find available icon names in [KeyboardIconsSet](/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.java). You can also use toolbar key icons using the uppercase name of the toolbar key, e.g. `!icon/REDO` + * You can find available icon names in [KeyboardIconsSet](/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.kt). You can also use toolbar key icons using the uppercase name of the [toolbar key](/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt#L109), e.g. `!icon/redo` ## Adding new layouts / languages * You need a layout file in one of the formats above, and add it to [layouts](app/src/main/assets/layouts)