Giter Club home page Giter Club logo

thumb-key's Introduction

GitHub tag (latest SemVer) status-badge GitHub issues License GitHub stars

phone_screen

A privacy-conscious keyboard made for your thumbs

Report Bug · Request Feature · Releases

Get it on IzzyOnDroid Get it on F-Droid

About Thumb-Key

Thumb-Key is a privacy-conscious smart keyboard, made specifically for your thumbs.

It features a 3x3 grid layout, and uses swipes for the less common letters. Its easy to learn, and designed for fast typing speeds.

Instead of relying on profit-driven, privacy-offending word and sentence prediction for accuracy, as do most popular phone keyboards like Gboard and Swiftkey, Thumb-Key uses large keys with predictable positions, to prevent your eyes from hunting and pecking for letters.

As the key positions get ingrained into your muscle memory, eventually you'll be able to approximate the fast speeds of touch-typing, your eyes never having to leave the text edit area.

This project is a follow-up to the now unmaintained (and closed-source) MessagEase Keyboard, which is its main inspiration.

Features

  • Highly configurable.
  • Customizeable sizing, ThumbKey and MessagEase layouts, dynamic / Material v3 themes, animations, haptic feedback, and audio feedback.
  • Open-source, AGPL License.

User Guide

  • Tap, or swipe to type a letter.
  • Swipe up or down on A to capitalize. (If you changed the layout, the button next to #)
  • Double tap the space bar to type a comma, triple tap to type a period. More taps have more punctuation.
  • Swipe left or long press on the backspace key to delete whole words to the left of the cursor.
  • Swipe right on the backspace key to delete whole words to the right of the cursor.
  • Swipe left or right on the spacebar to move the cursor by 1 character.
  • Long press the return key to insert a line break

Emoji Key

  • Tap to access the emoji picker.
  • Swipe up to configure Thumb-key.
  • Swipe right to change keyboard position.
  • Swipe down to access IME switcher (switch between Thumb-key and other keyboards).
  • Swipe left to cycle between selected layouts (languages).
  • Swipe to bottom-left to toggle voice input. Requires FUTO Voice Input.

Symbols / Letters Key

  • Tap to access numbers & symbols. Tap again to return to letters.
  • Swipe to top-left to select all.
  • Swipe up to copy - If nothing is selected, all the text will be copied.
  • Swipe to top-right to cut - If nothing is selected, all the text will be selected and cut.
  • Swipe right to redo.
  • Swipe down to paste.
  • Swipe left to undo.

Slide gestures

Enabling Slide gestures in keyboard settings will enable the following continuous sliding gestures:

  • Slide spacebar horizontally to move cursor position left and right.
  • Slide upwards while sliding the spacebar to select text.
  • Slide backspace to the left to select text to be deleted. Text will be deleted when key is released.

Enabling Spacebar: Allow normal swipes to work with slide gestures, in keyboard settings will enable the following:

  • Swipe left and right to move the cursor by a single character.
  • Swipe up and down to move the cursor up or down a line.
  • Allow us to use the other characters on the spacebars in the typesplit layouts.

Enabling Backspace: Allow normal swipes to work with slide gestures, in keyboard settings will enable the following:

  • Swipe left to delete whole words to the left of the cursor.
  • Swipe right to delete whole words to the right of the cursor.

Drag-and-return

  • You can type the opposite-case letter by dragging away from, then back to the original key.
  • Clockwise and counter-clockwise drags can be configured to type the opposite-case letter, or the equivalent center key on the numeric layout.

Ghost keys

Enabling Ghost keys in keyboard settings will enable swiping hidden symbol keys without switching to the numeric layout.

Coming from MessagEase Keyboard Tips

  • For those use to tapping on the hand key to hide the MessagEase Keyboard and make more screen real estate available, this can be done by using the Android back key or on Android 10 and higher using the guesture navigation for back.

Other

  • Practice typing, and check your words per minute, using monkeytype.com

Thumb-Key Design

A History of Phone Keyboards

Physical keyboards, with the full-size QWERTY layout, were not designed for use on small devices like phones; they were designed specifically for 10 fingers resting on a keybed, sitting on a secure surface. Phones must be held with the fore-fingers and palm, or held with one hand and typed with the other, leaving only 1 or 2 thumbs (as opposed to 10 fingers) free to perform key-presses. As texting came into being, word prediction came to be seen as the best solution to slow input speeds.

On phones that used the 9-key numeric layout, T9 predictive text was used. Other phones used the full-hand layout with the familiar QWERTY layout, with other proprietary predictive methods.

When phone keyboards became Keyloggers

As phones moved from physical buttons to soft-keyboards, key sizes became smaller and taps more imprecise and error-prone, with better predictive technology picking up the slack.

Smartphone companies like Apple and Google, in an attempt to better their word prediction algorithms, as well as collect potentially profitable information on what their users were typing, began submitting and aggregating all their user's key-taps to their servers, violating user's privacy in the process. Known as Keyloggers, and seen as universally malicious programs on desktop computers, these apps unfortunately became normalized and seen as a necessity on phones.

The lack of innovation on phone keyboard design, is best explained by the potential profitability these companies stand to gain by collecting and aggregating everything a user types; including the commodification of this data directly, or information and trends about you learned from this data, that they can sell to advertisers and 3rd parties. These could include your buying preferences, preferred websites, what you most commonly talk about with friends, and everything you type into search bars and text boxes.

As of today, phone keyboards are in such an abysmal state of privacy, that there aren't many keyboards left that can guarantee not to be logging all of your keystrokes.

MessagEase

As a testament to the stunning lack of innovation on both desktop and phone keyboards, the QWERTY layout from the 1880s is still the dominant layout, even on smartphones in the 21st century.

One company named Exideas created a keyboard app called MessagEase, which relied on the original large 9-key grid of old phones, and managed to achieve comparable fast typing speeds to other keyboards, without relying on big-data-powered word-prediction.

Much research went into MessagEase's design, and many of its users can do > 50 words per minute.

MessagEase is unfortunately unmaintained, and Thumb-Key uses a better alternating-thumb layout letter position (although the original MessagEase Keyboard layout is available in the settings).

Thumb-Key Letter Positions

  • Large keys are in a predictable 9-key grid. Eventually, you should be able to keep your eyes on the text input area, rather than hunting-and-pecking for letters, approximating touch-typing.
  • Letter positions are based on English text letter frequency. The most common letters are: ETAOINSHR. These 9 letters alone make up ~70% of all English text.
  • First 9 letters by frequency are the 9 center key taps. The next 8 are swipes to the center. The next 8 are swipes on the center hub key. Z is last.
  • Alternate thumbs for vowels and consonants (Vowels on right side of keyboard, consonants on left). This naturally results in fast digram speeds.
  • Prioritize bottom, and right side of keyboard. So EAO should be on the right side, and bottom to top, while TNS is on the left side.

Built With

Installation / Releases

How do I add my language or layout?

I'd be happy to accept additions to add more languages, and layouts. To start:

  • Read the letter position guidelines above. This means you'll likely need a letter frequency chart for text written in your language.
    • The general rule is: popular vowels on the right, bottom to top, consonants on the left.
  • Copy this file, or another sample keyboard from the same folder.
    • The title of the new layout should be lowercase and follow the following format: [languages] [base] [qualifiers]? [version]? (see also #702).
    • Change the characters to whatever you'd like.
    • This file contains both a shifted, and non-shifted keyboard, so make sure you take care of both.
    • You can also add or subtract columns if you want, but the layout must remain a grid. I highly recommend sticking with the 3x3 layout.
  • Add the new keyboard to the end of KeyboardLayout.kt file. If you don't know how to do this, skip to the next step.
  • Either open a pull request, or an issue, linking your new keyboard file. I'll handle the rest of the work.

Theming guide

To add a custom theme:

  • Use google's Material 3 custom theme generator, and save your Theme.kt file.
  • Copy the theme into Color.kt like the others.
  • Add the theme to the ThemeColor enum in Types.kt
  • Add a translation string in strings.xml for your theme name.
  • Add the theme to the colorPairs in Theme.kt

If you want to tweak your theme more precisely, these are the colours that are used. Please keep the theme in line with Material Design Guidelines where feasibe.

Coloured element Material colour used
Normal key background surface
Special key (space, emoji etc) background surfaceVariant
Main key colour primary
Key animated after press tertiary
Swipe letter colour secondary
Swipe symbol colour secondary, but at 50% alpha
Keypress flash colour on tap/hold inversePrimary
Keypress flash colour on release tertiaryContainer
Key outline outline
Backdrop background

Support / Donate

Thumb-Key will always remain free, open-source software. We've seen many keyboards (and open-source projects in general) go unmaintained after a few years. Recurring donations have proven to be the only way these projects can stay alive.

Your donations directly support full-time development, and help keep this maintained. If you find yourself using Thumb-Key every day, consider donating:

Crypto

  • bitcoin: 1Hefs7miXS5ff5Ck5xvmjKjXf5242KzRtK
  • ethereum: 0x400c96c96acbC6E7B3B43B1dc1BB446540a88A01
  • monero: 41taVyY6e1xApqKyMVDRVxJ76sPkfZhALLTjRvVKpaAh2pBd4wv9RgYj1tSPrx8wc6iE1uWUfjtQdTmTy2FGMeChGVKPQuV

Social / Contact

Android IME Resources

thumb-key's People

Contributors

asdkant avatar bluedrink9 avatar breversa avatar crandel avatar dessalines avatar domportera avatar flauta avatar franciscotrigo avatar glm4610 avatar k0bau avatar knockofffeline avatar kommynct avatar kraxen72 avatar lavin-tom avatar limfjorden avatar locrianz avatar lysalana avatar mockballed avatar morellik avatar mpice-mn avatar mpsijm avatar ondrachwiedziuk avatar pxeemo avatar renovate[bot] avatar sphh avatar sslater11 avatar storvik avatar wadewt avatar yehoshuapw avatar zgll2022 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

thumb-key's Issues

Brainstorming idea regarding bigrams/digraphs

According to this wiki:

https://en.m.wikipedia.org/wiki/Frequency_analysis

"Likewise, TH, ER, ON, and AN are the most common pairs of letters (termed bigrams or digraphs), and SS, EE, TT, and FF are the most common repeats."

Since you have extra space on some of the keys like T, E, A, and O, this would provide space to put bigrams and repeats in the corners of those letters if you wanted.

This non-FOSS keyboard does something similar, although some of the options are hidden until you actually slide the key, so I don't know if you can actually see it based off the play store description:
https://play.google.com/store/apps/details?id=com.combokey.plus

Thank you.

Fixes and ideas

Please fix double 'г' in Ukrainian layout, pasting 'E' letter after changing to lover case in Russian layout, and, if it possible, fully rewrite system of keys for loading here from json like this: {"ru":{{}{}{}{}{}{}}{{}{}{}{}{}{}{}{}{}}}} or someone else (I'm bad in json), just implement this idea. And please, add key for changing keyboard layout, I use it now, but going to program settings and changing layout is very uncomfortable. Many thanks and good luck!

Tap and hold to repeat backspace.

I tried using this as my daily keyboard for the last 2 days, this is probably the only thing I consider a real "issue" preventing me from using it further rather than an "enhancement"

After ~300ms (Normal 'long press') of holding the backspace, it should be repeated every ~40ms.

Swiping to erase words isn't my thing.

Portuguese Layout

I made it based in this frequency list and following the position guidelines. It looks like that:
layout

package com.dessalines.thumbkey.keyboards

import android.view.KeyEvent
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowDropDown
import androidx.compose.material.icons.outlined.ArrowDropUp
import androidx.compose.material.icons.outlined.KeyboardBackspace
import androidx.compose.material.icons.outlined.KeyboardReturn
import androidx.compose.material.icons.outlined.Numbers
import androidx.compose.material.icons.outlined.Settings
import com.dessalines.thumbkey.utils.ColorVariant
import com.dessalines.thumbkey.utils.FontSizeVariant
import com.dessalines.thumbkey.utils.KeyAction
import com.dessalines.thumbkey.utils.KeyC
import com.dessalines.thumbkey.utils.KeyDisplay
import com.dessalines.thumbkey.utils.KeyItemC
import com.dessalines.thumbkey.utils.KeyboardC
import com.dessalines.thumbkey.utils.KeyboardMode
import com.dessalines.thumbkey.utils.SwipeDirection

val thumbkeyV4Keyboard = KeyboardC(
    arrayOf(
        arrayOf(
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("n"),
                    action = KeyAction.CommitText("n"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.BOTTOM_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("v"),
                        action = KeyAction.CommitText("v")
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("m"),
                    action = KeyAction.CommitText("m"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.BOTTOM to KeyC(
                        display = KeyDisplay.TextDisplay("h"),
                        action = KeyAction.CommitText("h")
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("o"),
                    action = KeyAction.CommitText("o"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.BOTTOM_LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("c"),
                        action = KeyAction.CommitText("c")
                    ),
                    SwipeDirection.LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("ç"),
                        action = KeyAction.CommitText("ç"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.TOP_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("ó"),
                        action = KeyAction.CommitText("ó"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("õ"),
                        action = KeyAction.CommitText("õ"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.BOTTOM to KeyC(
                        display = KeyDisplay.TextDisplay("ô"),
                        action = KeyAction.CommitText("ô"),
                        color = ColorVariant.MUTED
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.IconDisplay(Icons.Outlined.Settings),
                    action = KeyAction.GotoSettings,
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.SECONDARY
                ),
                backgroundColor = ColorVariant.SURFACE_VARIANT
            )
        ),
        arrayOf(
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("r"),
                    action = KeyAction.CommitText("r"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("p"),
                        action = KeyAction.CommitText("p")
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("d"),
                    action = KeyAction.CommitText("d"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.TOP_LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("x"),
                        action = KeyAction.CommitText("x")
                    ),
                    SwipeDirection.TOP to KeyC(
                        display = KeyDisplay.TextDisplay("w"),
                        action = KeyAction.CommitText("w")
                    ),
                    SwipeDirection.TOP_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("f"),
                        action = KeyAction.CommitText("f")
                    ),
                    SwipeDirection.RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("b"),
                        action = KeyAction.CommitText("b")
                    ),
                    SwipeDirection.BOTTOM_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("q"),
                        action = KeyAction.CommitText("q")
                    ),
                    SwipeDirection.BOTTOM to KeyC(
                        display = KeyDisplay.TextDisplay("k"),
                        action = KeyAction.CommitText("k")
                    ),
                    SwipeDirection.BOTTOM_LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("z"),
                        action = KeyAction.CommitText("z")
                    ),
                    SwipeDirection.LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("j"),
                        action = KeyAction.CommitText("j")
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("e"),
                    action = KeyAction.CommitText("e"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("t"),
                        action = KeyAction.CommitText("t")
                    ),
                    SwipeDirection.TOP to KeyC(
                        display = KeyDisplay.IconDisplay(Icons.Outlined.ArrowDropUp),
                        action = KeyAction.ToggleShiftMode(true),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.TOP_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("é"),
                        action = KeyAction.CommitText("é"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.BOTTOM to KeyC(
                        display = KeyDisplay.TextDisplay("ê"),
                        action = KeyAction.CommitText("ê"),
                        color = ColorVariant.MUTED
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.IconDisplay(Icons.Outlined.Numbers),
                    action = KeyAction.ToggleNumericMode(true),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.SECONDARY
                ),
                backgroundColor = ColorVariant.SURFACE_VARIANT
            )
        ),
        arrayOf(
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("s"),
                    action = KeyAction.CommitText("s"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.TOP_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("l"),
                        action = KeyAction.CommitText("l")
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("i"),
                    action = KeyAction.CommitText("i"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.TOP to KeyC(
                        display = KeyDisplay.TextDisplay("g"),
                        action = KeyAction.CommitText("g")
                    ),
                    SwipeDirection.TOP_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("í"),
                        action = KeyAction.CommitText("í"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("y"),
                        action = KeyAction.CommitText("y")
                    ),
                    SwipeDirection.BOTTOM_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("'"),
                        action = KeyAction.CommitText("'"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.BOTTOM to KeyC(
                        display = KeyDisplay.TextDisplay("."),
                        action = KeyAction.CommitText("."),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.BOTTOM_LEFT to KeyC(
                        display = KeyDisplay.TextDisplay(","),
                        action = KeyAction.CommitText(","),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("-"),
                        action = KeyAction.CommitText("-"),
                        color = ColorVariant.MUTED
                    ),
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("a"),
                    action = KeyAction.CommitText("a"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.TOP_LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("u"),
                        action = KeyAction.CommitText("u")
                    ),
                    SwipeDirection.TOP to KeyC(
                        display = KeyDisplay.TextDisplay("ú"),
                        action = KeyAction.CommitText("ú"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.TOP_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("á"),
                        action = KeyAction.CommitText("á"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("ã"),
                        action = KeyAction.CommitText("ã"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.BOTTOM_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("à"),
                        action = KeyAction.CommitText("à"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.BOTTOM to KeyC(
                        display = KeyDisplay.TextDisplay("â"),
                        action = KeyAction.CommitText("â"),
                        color = ColorVariant.MUTED
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.IconDisplay(Icons.Outlined.KeyboardBackspace),
                    action = KeyAction.SendEvent(
                        KeyEvent(
                            KeyEvent.ACTION_DOWN,
                            KeyEvent
                                .KEYCODE_DEL
                        )
                    ),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.SECONDARY
                ),
                swipes = mapOf(
                    SwipeDirection.LEFT to KeyC(
                        action = KeyAction.DeleteLastWord,
                        display = null
                    ),
                    SwipeDirection.TOP_LEFT to KeyC(
                        action = KeyAction.DeleteLastWord,
                        display = null
                    ),
                    SwipeDirection.BOTTOM_LEFT to KeyC(
                        action = KeyAction.DeleteLastWord,
                        display = null
                    )
                ),
                backgroundColor = ColorVariant.SURFACE_VARIANT
            )
        ),
        arrayOf(
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay(" "),
                    action = KeyAction.CommitText(" ")
                ),
                nextTapActions = arrayOf(
                    KeyAction.ReplaceLastText(", ", trimCount = 1),
                    KeyAction.ReplaceLastText(". "),
                    KeyAction.ReplaceLastText("? "),
                    KeyAction.ReplaceLastText("! "),
                    KeyAction.ReplaceLastText(": ")
                ),
                backgroundColor = ColorVariant.SURFACE_VARIANT,
                widthMultiplier = 3
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.IconDisplay(Icons.Outlined.KeyboardReturn),
                    action = KeyAction.IMECompleteAction,
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.SECONDARY
                ),
                backgroundColor = ColorVariant.SURFACE_VARIANT
            )
        )
    )
)

val thumbkeyV4KeyboardShifted = KeyboardC(
    arrayOf(
        arrayOf(
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("N"),
                    action = KeyAction.CommitText("N"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.BOTTOM_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("V"),
                        action = KeyAction.CommitText("V")
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("M"),
                    action = KeyAction.CommitText("M"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.BOTTOM to KeyC(
                        display = KeyDisplay.TextDisplay("H"),
                        action = KeyAction.CommitText("H")
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("O"),
                    action = KeyAction.CommitText("O"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.BOTTOM_LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("C"),
                        action = KeyAction.CommitText("C")
                    ),
                   SwipeDirection.LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("Ç"),
                        action = KeyAction.CommitText("Ç"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.TOP_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("Ó"),
                        action = KeyAction.CommitText("Ó"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("Õ"),
                        action = KeyAction.CommitText("Õ"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.BOTTOM to KeyC(
                        display = KeyDisplay.TextDisplay("Ô"),
                        action = KeyAction.CommitText("Ô"),
                        color = ColorVariant.MUTED
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.IconDisplay(Icons.Outlined.Settings),
                    action = KeyAction.GotoSettings,
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.SECONDARY
                ),
                backgroundColor = ColorVariant.SURFACE_VARIANT
            )
        ),
        arrayOf(
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("R"),
                    action = KeyAction.CommitText("R"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("P"),
                        action = KeyAction.CommitText("P")
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("D"),
                    action = KeyAction.CommitText("D"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.TOP_LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("X"),
                        action = KeyAction.CommitText("X")
                    ),
                    SwipeDirection.TOP to KeyC(
                        display = KeyDisplay.TextDisplay("W"),
                        action = KeyAction.CommitText("W")
                    ),
                    SwipeDirection.TOP_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("F"),
                        action = KeyAction.CommitText("F")
                    ),
                    SwipeDirection.RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("B"),
                        action = KeyAction.CommitText("B")
                    ),
                    SwipeDirection.BOTTOM_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("Q"),
                        action = KeyAction.CommitText("Q")
                    ),
                    SwipeDirection.BOTTOM to KeyC(
                        display = KeyDisplay.TextDisplay("K"),
                        action = KeyAction.CommitText("K")
                    ),
                    SwipeDirection.BOTTOM_LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("Z"),
                        action = KeyAction.CommitText("Z")
                    ),
                    SwipeDirection.LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("J"),
                        action = KeyAction.CommitText("J")
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("E"),
                    action = KeyAction.CommitText("E"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("T"),
                        action = KeyAction.CommitText("T")
                    ),
                    SwipeDirection.TOP to KeyC(
                        display = KeyDisplay.TextDisplay("Ê"),
                        action = KeyAction.CommitText("Ê"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.TOP_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("É"),
                        action = KeyAction.CommitText("É"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.BOTTOM to KeyC(
                        display = KeyDisplay.IconDisplay(Icons.Outlined.ArrowDropDown),
                        action = KeyAction.ToggleShiftMode(false),
                        color = ColorVariant.MUTED
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.IconDisplay(Icons.Outlined.Numbers),
                    action = KeyAction.ToggleNumericMode(true),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.SECONDARY
                ),
                backgroundColor = ColorVariant.SURFACE_VARIANT
            )
        ),
        arrayOf(
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("S"),
                    action = KeyAction.CommitText("S"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.TOP_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("L"),
                        action = KeyAction.CommitText("L")
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("I"),
                    action = KeyAction.CommitText("I"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.TOP to KeyC(
                        display = KeyDisplay.TextDisplay("G"),
                        action = KeyAction.CommitText("G")
                    ),
                    SwipeDirection.TOP_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("Í"),
                        action = KeyAction.CommitText("Í"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("Y"),
                        action = KeyAction.CommitText("Y")
                    ),
                    SwipeDirection.BOTTOM_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("'"),
                        action = KeyAction.CommitText("'"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.BOTTOM to KeyC(
                        display = KeyDisplay.TextDisplay("."),
                        action = KeyAction.CommitText("."),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.BOTTOM_LEFT to KeyC(
                        display = KeyDisplay.TextDisplay(","),
                        action = KeyAction.CommitText(","),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("-"),
                        action = KeyAction.CommitText("-"),
                        color = ColorVariant.MUTED
                    ),
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay("A"),
                    action = KeyAction.CommitText("A"),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.PRIMARY
                ),
                swipes = mapOf(
                    SwipeDirection.TOP_LEFT to KeyC(
                        display = KeyDisplay.TextDisplay("U"),
                        action = KeyAction.CommitText("U")
                    ),
                    SwipeDirection.TOP to KeyC(
                        display = KeyDisplay.TextDisplay("Ú"),
                        action = KeyAction.CommitText("Ú"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.TOP_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("Á"),
                        action = KeyAction.CommitText("Á"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("Ã"),
                        action = KeyAction.CommitText("Ã"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.BOTTOM_RIGHT to KeyC(
                        display = KeyDisplay.TextDisplay("À"),
                        action = KeyAction.CommitText("À"),
                        color = ColorVariant.MUTED
                    ),
                    SwipeDirection.BOTTOM to KeyC(
                        display = KeyDisplay.TextDisplay("Â"),
                        action = KeyAction.CommitText("Â"),
                        color = ColorVariant.MUTED
                    )
                )
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.IconDisplay(Icons.Outlined.KeyboardBackspace),
                    action = KeyAction.SendEvent(
                        KeyEvent(
                            KeyEvent.ACTION_DOWN,
                            KeyEvent
                                .KEYCODE_DEL
                        )
                    ),
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.SECONDARY
                ),
                swipes = mapOf(
                    SwipeDirection.LEFT to KeyC(
                        action = KeyAction.DeleteLastWord,
                        display = null
                    ),
                    SwipeDirection.TOP_LEFT to KeyC(
                        action = KeyAction.DeleteLastWord,
                        display = null
                    ),
                    SwipeDirection.BOTTOM_LEFT to KeyC(
                        action = KeyAction.DeleteLastWord,
                        display = null
                    )
                ),
                backgroundColor = ColorVariant.SURFACE_VARIANT
            )
        ),
        arrayOf(
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.TextDisplay(" "),
                    action = KeyAction.CommitText(" ")
                ),
                nextTapActions = arrayOf(
                    KeyAction.ReplaceLastText(", ", trimCount = 1),
                    KeyAction.ReplaceLastText(". "),
                    KeyAction.ReplaceLastText("? "),
                    KeyAction.ReplaceLastText("! "),
                    KeyAction.ReplaceLastText(": ")
                ),
                backgroundColor = ColorVariant.SURFACE_VARIANT,
                widthMultiplier = 3
            ),
            KeyItemC(
                center = KeyC(
                    display = KeyDisplay.IconDisplay(Icons.Outlined.KeyboardReturn),
                    action = KeyAction.IMECompleteAction,
                    size = FontSizeVariant.LARGE,
                    color = ColorVariant.SECONDARY
                ),
                backgroundColor = ColorVariant.SURFACE_VARIANT
            )
        )
    )
)

val THUMBKEY_V4_KEYBOARD_MODES: Map<KeyboardMode, KeyboardC> = mapOf(
    KeyboardMode.MAIN to thumbkeyV4Keyboard,
    KeyboardMode.SHIFTED to thumbkeyV4KeyboardShifted,
    KeyboardMode.NUMERIC to numericKeyboard
)

various improvements

hi! this really seems like a promising idea for a keyboard, but for me a few things are missing that are pretty essential, at least for me

ill list them and try to give ideas on tow to improve/add these things:

1 absolutely necessary

  • swiping on the space bar to move the text cursor left or right, florisboard does this and its definitely the thing i rely on the most, its great

  • an easy way to switch between layouts, i use two languages on my phone daily so to me this is pretty important, on florisboard i switch quickly by swiping across the whole keyboard

in thumbkey this could be done by setting maybe a main and a secondary language in the settings. then, when you swipe left on the enter key, the language would switch between them


  • a toggle to disable capitalization on the first letter, yes theres an autocap toggle in the settings, however with it disabled the keyboard still default to capital letters when typing
    (edit: seems this is only the case when switching to thumbkey from another keyboard, still being always lowercase would be cool lol)

2 would be pretty cool

  • more characters, i.e. i was looking for "+" yet couldnt find it, maybe im just blind

  • emoji keyboard (i know this was already mentioned)

  • swiping on the delete key not to delete words, but characters precisely, like florisboard

  • better theming, specifically for me the lines between keys dont really fit, maybe "corner radius" and "lines between keys" settings could improve the look a lot

thank you! i know this app is still in early developement but still i think with these changes it could turn into something even better :)

French layout

Hello,

Would be great to have keys optimised for french typing

Thanks

Add settings

  • Key size (limit this)
  • Position
  • Auto-capitalize
  • Layout (thumbkey, messageease)
  • Theme
  • Theme color

Emoji picker

This could either be done by implementing an already existing android emoji picker, or by trying to build a custom one into thumb key.

I'm leaning toward the former, so I don't have to maintain it, and solve all the emoji related issues that might come up.

edit:

Unfortunately the former solution isn't working for the existing 2 emoji picker libraries I've tried. There appear to be no good jetpack compose emoji pickers yet.

Auto switching to capital letters only happens after a period

Just tried this out, and something I noticed immediately was that it automatically switches to capital letters only after typing a period. Entering a question mark or exclamation point does not automatically transition the next key to an uppercase letter, even though those punctuations also end a sentence. (As an aside: it is also noticeably more work to type an exclamation point or question mark compared to a period, which felt inconvenient.)

Additionally, if you type one capital letter and then immediately delete it, it doesn't remember that you wanted to type a capital letter (after typing the capital letter, it switches to lowercase, but doesn't switch back to uppercase if you delete the letter because you want to type a different capital letter instead).

Lastly, it seems to start with a capital letter the first time you switch to the keyboard, but if you switch to another application without switching the keyboard, it doesn't default to a capital letter when focusing on a text field in that other application.

Just wanted to share some feedback, but overall I'm intrigued by the keyboard. I'm not sure how long it would take to get used to, yet, but improving the logic around automatic switching to uppercase would certainly make it easier for me to adopt even before the layout becomes familiar.

Either default or toggle option for different color letters

It would be nice, especially while learning this keyboard, to have different colored letters around the H-key and also the smaller letters around the other main keys.

So: J,Q,B,K,P,V,X,Y a different color from the main keys
And: W,G,U,M,L,C,F,D either the same color as the J,Q... set or another different color.

This would provide some additional contrast to make it easier when identifying the letters while learning the keyboard.

I figured you could either make this a default option, or allow a toggle switch to change the colors on those letters.

Thanks!

Move cursor by sliding space

I wonder if this would be possible. I don't know what it requires but I would guess Android has that capability builtin. I know rkkr/simple-keyboard has this functionality.

Auto-update

Add auto update feature as in LibreTube and other such open source apps. As it is really ineffective to download and install all the way round.

Inconsistency in taping space bar for punctuation while auto-capitalize is On

If you keep taping space bar, the results are different depending if the auto-capitalize is On or Off.

While Off: Double space will create a period. If you press it again, it will change the period for a comma, again for question mark, again for exclamation mark, again for colon. ( '.' → ',' → '?' → '!' → ':' )

While On: Double space will create a period. If you press it again, it will just create another space.

Configurable minimum swipe length

I'm finding swipes have trouble registering with my left thumb. (My swipes are bad in general due to limited finger dexterity, they often go in the wrong direction so I often upped minimum swipe length in MessagEase which helped)

I suspect having this configurable will help alleviate the problem just as it did in MessagEase.

German Layout

Hi,

I have tried to make the file with german layout. For the letter-frequency I just asked wikipedia. I had to add the "Umlaute" aka diphtongs i think and i decided to place near the ordinary letters, e.g. "Ö" near "O" etc. Same thing for the "ß".

I hope I did not destroy the syntax with the extra-letters. It was great if you could yous my proposal.

Greatings
Rick

https://adelheidi.de/nextcloud/index.php/s/H5CnabrMpQZ7DMG

Russian layout

Hi, I've created russian layout. I took frequency list from "Russian National Corpus" (НКРЯ). I suppose that at top left corner placed the most frequent letters (such а, о, е). Also, I placed "ъ" and "ё" at bottom right corner of bottom left corner because almost all natives write "е" instead of "ё", because of its identity to "е" (although, all official documents must write "ё" and not "е" instead). "ъ", because small group of words have it. E.g. "подъезд", "отъехать", etc. So, this way "ё" and "ъ" cannot be written accidentally.
It should looks like this:
It should looks like this

package com.dessalines.thumbkey.keyboards

import android.view.KeyEvent
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowDropDown
import androidx.compose.material.icons.outlined.ArrowDropUp
import androidx.compose.material.icons.outlined.KeyboardBackspace
import androidx.compose.material.icons.outlined.KeyboardReturn
import androidx.compose.material.icons.outlined.Numbers
import androidx.compose.material.icons.outlined.Settings
import com.dessalines.thumbkey.utils.ColorVariant
import com.dessalines.thumbkey.utils.FontSizeVariant
import com.dessalines.thumbkey.utils.KeyAction
import com.dessalines.thumbkey.utils.KeyC
import com.dessalines.thumbkey.utils.KeyDisplay
import com.dessalines.thumbkey.utils.KeyItemC
import com.dessalines.thumbkey.utils.KeyboardC
import com.dessalines.thumbkey.utils.KeyboardMode
import com.dessalines.thumbkey.utils.SwipeDirection

val thumbkeyV4Keyboard = KeyboardC(
arrayOf(
arrayOf(
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("н"),
action = KeyAction.CommitText("н"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.BOTTOM_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("щ"),
action = KeyAction.CommitText("щ")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("е"),
action = KeyAction.CommitText("е"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.BOTTOM to KeyC(
display = KeyDisplay.TextDisplay("й"),
action = KeyAction.CommitText("й")
),
SwipeDirection.BOTTOM_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("б"),
action = KeyAction.CommitText("б")
),
SwipeDirection.RIGHT to KeyC(
display = KeyDisplay.TextDisplay("э"),
action = KeyAction.CommitText("э")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("о"),
action = KeyAction.CommitText("о"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.BOTTOM to KeyC(
display = KeyDisplay.TextDisplay("з"),
action = KeyAction.CommitText("з")
),
SwipeDirection.BOTTOM_LEFT to KeyC(
display = KeyDisplay.TextDisplay("г"),
action = KeyAction.CommitText("г")
),
SwipeDirection.LEFT to KeyC(
display = KeyDisplay.TextDisplay("ь"),
action = KeyAction.CommitText("ь")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.IconDisplay(Icons.Outlined.Settings),
action = KeyAction.GotoSettings,
size = FontSizeVariant.LARGE,
color = ColorVariant.SECONDARY
),
backgroundColor = ColorVariant.SURFACE_VARIANT
)
),
arrayOf(
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("с"),
action = KeyAction.CommitText("с"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.RIGHT to KeyC(
display = KeyDisplay.TextDisplay("ю"),
action = KeyAction.CommitText("ю")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("т"),
action = KeyAction.CommitText("т"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.TOP_LEFT to KeyC(
display = KeyDisplay.TextDisplay("у"),
action = KeyAction.CommitText("у")
),
SwipeDirection.TOP to KeyC(
display = KeyDisplay.TextDisplay("д"),
action = KeyAction.CommitText("д")
),
SwipeDirection.TOP_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("л"),
action = KeyAction.CommitText("л")
),
SwipeDirection.RIGHT to KeyC(
display = KeyDisplay.TextDisplay("к"),
action = KeyAction.CommitText("к")
),
SwipeDirection.BOTTOM_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("м"),
action = KeyAction.CommitText("м")
),
SwipeDirection.BOTTOM to KeyC(
display = KeyDisplay.TextDisplay("п"),
action = KeyAction.CommitText("п")
),
SwipeDirection.BOTTOM_LEFT to KeyC(
display = KeyDisplay.TextDisplay("ы"),
action = KeyAction.CommitText("ы")
),
SwipeDirection.LEFT to KeyC(
display = KeyDisplay.TextDisplay("я"),
action = KeyAction.CommitText("я")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("а"),
action = KeyAction.CommitText("а"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.LEFT to KeyC(
display = KeyDisplay.TextDisplay("х"),
action = KeyAction.CommitText("х")
),
SwipeDirection.TOP_LEFT to KeyC(
display = KeyDisplay.TextDisplay("ч"),
action = KeyAction.CommitText("ч")
),
SwipeDirection.BOTTOM_LEFT to KeyC(
display = KeyDisplay.TextDisplay("ж"),
action = KeyAction.CommitText("ж")
),
SwipeDirection.TOP to KeyC(
display = KeyDisplay.IconDisplay(Icons.Outlined.ArrowDropUp),
action = KeyAction.ToggleShiftMode(true),
color = ColorVariant.MUTED
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.IconDisplay(Icons.Outlined.Numbers),
action = KeyAction.ToggleNumericMode(true),
size = FontSizeVariant.LARGE,
color = ColorVariant.SECONDARY
),
backgroundColor = ColorVariant.SURFACE_VARIANT
)
),
arrayOf(
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("в"),
action = KeyAction.CommitText("в"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.TOP_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("ф"),
action = KeyAction.CommitText("ф")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("р"),
action = KeyAction.CommitText("р"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.TOP to KeyC(
display = KeyDisplay.TextDisplay("ц"),
action = KeyAction.CommitText("ц")
),
SwipeDirection.TOP_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("'"),
action = KeyAction.CommitText("'"),
color = ColorVariant.MUTED
),
SwipeDirection.BOTTOM_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("-"),
action = KeyAction.CommitText("-"),
color = ColorVariant.MUTED
),
SwipeDirection.BOTTOM to KeyC(
display = KeyDisplay.TextDisplay("."),
action = KeyAction.CommitText("."),
color = ColorVariant.MUTED
),
SwipeDirection.BOTTOM_LEFT to KeyC(
display = KeyDisplay.TextDisplay(","),
action = KeyAction.CommitText(","),
color = ColorVariant.MUTED
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("и"),
action = KeyAction.CommitText("и"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.TOP_LEFT to KeyC(
display = KeyDisplay.TextDisplay("ш"),
action = KeyAction.CommitText("ш")
),
SwipeDirection.RIGHT to KeyC(
display = KeyDisplay.TextDisplay("ъ"),
action = KeyAction.CommitText("ъ")
),
SwipeDirection.BOTTOM_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("ё"),
action = KeyAction.CommitText("ё")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.IconDisplay(Icons.Outlined.KeyboardBackspace),
action = KeyAction.SendEvent(
KeyEvent(
KeyEvent.ACTION_DOWN,
KeyEvent
.KEYCODE_DEL
)
),
size = FontSizeVariant.LARGE,
color = ColorVariant.SECONDARY
),
swipes = mapOf(
SwipeDirection.LEFT to KeyC(
action = KeyAction.DeleteLastWord,
display = null
),
SwipeDirection.TOP_LEFT to KeyC(
action = KeyAction.DeleteLastWord,
display = null
),
SwipeDirection.BOTTOM_LEFT to KeyC(
action = KeyAction.DeleteLastWord,
display = null
)
),
backgroundColor = ColorVariant.SURFACE_VARIANT
)
),
arrayOf(
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay(" "),
action = KeyAction.CommitText(" ")
),
nextTapActions = arrayOf(
KeyAction.ReplaceLastText(", ", trimCount = 1),
KeyAction.ReplaceLastText(". "),
KeyAction.ReplaceLastText("? "),
KeyAction.ReplaceLastText("! "),
KeyAction.ReplaceLastText(": ")
),
backgroundColor = ColorVariant.SURFACE_VARIANT,
widthMultiplier = 3
),
KeyItemC(
center = KeyC(
display = KeyDisplay.IconDisplay(Icons.Outlined.KeyboardReturn),
action = KeyAction.IMECompleteAction,
size = FontSizeVariant.LARGE,
color = ColorVariant.SECONDARY
),
backgroundColor = ColorVariant.SURFACE_VARIANT
)
)
)
)

val thumbkeyV4KeyboardShifted = KeyboardC(
arrayOf(
arrayOf(
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("Н"),
action = KeyAction.CommitText("Н"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.BOTTOM_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("Щ"),
action = KeyAction.CommitText("Щ")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("Е"),
action = KeyAction.CommitText("Е"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.BOTTOM to KeyC(
display = KeyDisplay.TextDisplay("Й"),
action = KeyAction.CommitText("Й")
),
SwipeDirection.BOTTOM_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("Б"),
action = KeyAction.CommitText("Б")
),
SwipeDirection.RIGHT to KeyC(
display = KeyDisplay.TextDisplay("Э"),
action = KeyAction.CommitText("Э")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("О"),
action = KeyAction.CommitText("О"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.BOTTOM to KeyC(
display = KeyDisplay.TextDisplay("З"),
action = KeyAction.CommitText("З")
),
SwipeDirection.BOTTOM_LEFT to KeyC(
display = KeyDisplay.TextDisplay("Г"),
action = KeyAction.CommitText("Г")
),
SwipeDirection.LEFT to KeyC(
display = KeyDisplay.TextDisplay("Ь"),
action = KeyAction.CommitText("Ь")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.IconDisplay(Icons.Outlined.Settings),
action = KeyAction.GotoSettings,
size = FontSizeVariant.LARGE,
color = ColorVariant.SECONDARY
),
backgroundColor = ColorVariant.SURFACE_VARIANT
)
),
arrayOf(
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("С"),
action = KeyAction.CommitText("С"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.RIGHT to KeyC(
display = KeyDisplay.TextDisplay("Ю"),
action = KeyAction.CommitText("Ю")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("т"),
action = KeyAction.CommitText("Т"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.TOP_LEFT to KeyC(
display = KeyDisplay.TextDisplay("У"),
action = KeyAction.CommitText("У")
),
SwipeDirection.TOP to KeyC(
display = KeyDisplay.TextDisplay("Д"),
action = KeyAction.CommitText("Д")
),
SwipeDirection.TOP_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("Л"),
action = KeyAction.CommitText("Л")
),
SwipeDirection.RIGHT to KeyC(
display = KeyDisplay.TextDisplay("К"),
action = KeyAction.CommitText("К")
),
SwipeDirection.BOTTOM_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("М"),
action = KeyAction.CommitText("М")
),
SwipeDirection.BOTTOM to KeyC(
display = KeyDisplay.TextDisplay("П"),
action = KeyAction.CommitText("П")
),
SwipeDirection.BOTTOM_LEFT to KeyC(
display = KeyDisplay.TextDisplay("Ы"),
action = KeyAction.CommitText("Ы")
),
SwipeDirection.LEFT to KeyC(
display = KeyDisplay.TextDisplay("Я"),
action = KeyAction.CommitText("Я")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("А"),
action = KeyAction.CommitText("А"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.LEFT to KeyC(
display = KeyDisplay.TextDisplay("Х"),
action = KeyAction.CommitText("Х")
),
SwipeDirection.TOP_LEFT to KeyC(
display = KeyDisplay.TextDisplay("Ч"),
action = KeyAction.CommitText("Ч")
),
SwipeDirection.BOTTOM_LEFT to KeyC(
display = KeyDisplay.TextDisplay("Ж"),
action = KeyAction.CommitText("Ж")
),
SwipeDirection.BOTTOM to KeyC(
display = KeyDisplay.IconDisplay(Icons.Outlined.ArrowDropDown),
action = KeyAction.ToggleShiftMode(false),
color = ColorVariant.MUTED
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.IconDisplay(Icons.Outlined.Numbers),
action = KeyAction.ToggleNumericMode(true),
size = FontSizeVariant.LARGE,
color = ColorVariant.SECONDARY
),
backgroundColor = ColorVariant.SURFACE_VARIANT
)
),
arrayOf(
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("В"),
action = KeyAction.CommitText("В"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.TOP_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("Ф"),
action = KeyAction.CommitText("Ф")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("Р"),
action = KeyAction.CommitText("Р"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.TOP to KeyC(
display = KeyDisplay.TextDisplay("Ц"),
action = KeyAction.CommitText("Ц")
),
SwipeDirection.TOP_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("'"),
action = KeyAction.CommitText("'"),
color = ColorVariant.MUTED
),
SwipeDirection.BOTTOM_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("-"),
action = KeyAction.CommitText("-"),
color = ColorVariant.MUTED
),
SwipeDirection.BOTTOM to KeyC(
display = KeyDisplay.TextDisplay("."),
action = KeyAction.CommitText("."),
color = ColorVariant.MUTED
),
SwipeDirection.BOTTOM_LEFT to KeyC(
display = KeyDisplay.TextDisplay(","),
action = KeyAction.CommitText(","),
color = ColorVariant.MUTED
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay("И"),
action = KeyAction.CommitText("И"),
size = FontSizeVariant.LARGE,
color = ColorVariant.PRIMARY
),
swipes = mapOf(
SwipeDirection.TOP_LEFT to KeyC(
display = KeyDisplay.TextDisplay("Ш"),
action = KeyAction.CommitText("Ш")
),
SwipeDirection.RIGHT to KeyC(
display = KeyDisplay.TextDisplay("Ъ"),
action = KeyAction.CommitText("Ъ")
),
SwipeDirection.BOTTOM_RIGHT to KeyC(
display = KeyDisplay.TextDisplay("Ё"),
action = KeyAction.CommitText("Ё")
)
)
),
KeyItemC(
center = KeyC(
display = KeyDisplay.IconDisplay(Icons.Outlined.KeyboardBackspace),
action = KeyAction.SendEvent(
KeyEvent(
KeyEvent.ACTION_DOWN,
KeyEvent
.KEYCODE_DEL
)
),
size = FontSizeVariant.LARGE,
color = ColorVariant.SECONDARY
),
swipes = mapOf(
SwipeDirection.LEFT to KeyC(
action = KeyAction.DeleteLastWord,
display = null
),
SwipeDirection.TOP_LEFT to KeyC(
action = KeyAction.DeleteLastWord,
display = null
),
SwipeDirection.BOTTOM_LEFT to KeyC(
action = KeyAction.DeleteLastWord,
display = null
)
),
backgroundColor = ColorVariant.SURFACE_VARIANT
)
),
arrayOf(
KeyItemC(
center = KeyC(
display = KeyDisplay.TextDisplay(" "),
action = KeyAction.CommitText(" ")
),
nextTapActions = arrayOf(
KeyAction.ReplaceLastText(", ", trimCount = 1),
KeyAction.ReplaceLastText(". "),
KeyAction.ReplaceLastText("? "),
KeyAction.ReplaceLastText("! "),
KeyAction.ReplaceLastText(": ")
),
backgroundColor = ColorVariant.SURFACE_VARIANT,
widthMultiplier = 3
),
KeyItemC(
center = KeyC(
display = KeyDisplay.IconDisplay(Icons.Outlined.KeyboardReturn),
action = KeyAction.IMECompleteAction,
size = FontSizeVariant.LARGE,
color = ColorVariant.SECONDARY
),
backgroundColor = ColorVariant.SURFACE_VARIANT
)
)
)
)

val THUMBKEY_V4_KEYBOARD_MODES: Map<KeyboardMode, KeyboardC> = mapOf(
KeyboardMode.MAIN to thumbkeyV4Keyboard,
KeyboardMode.SHIFTED to thumbkeyV4KeyboardShifted,
KeyboardMode.NUMERIC to numericKeyboard
)

P.S. sorry, idk where I should attach the code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.