mirror of
https://github.com/Julow/Unexpected-Keyboard.git
synced 2025-08-18 00:19:56 +02:00
Compare commits
84 Commits
1.11.1
...
repeat-sen
Author | SHA1 | Date | |
---|---|---|---|
|
8662f3afd4 | ||
|
2dae2105b2 | ||
|
d53ee811d9 | ||
|
fadedfd58f | ||
|
f9cd4ca2d8 | ||
|
9bb7c7e66f | ||
|
f4978f5266 | ||
|
a0d90496c1 | ||
|
7aa241b10a | ||
|
a57bdf8cfb | ||
|
ee6e892ef4 | ||
|
2ea256e769 | ||
|
5665d6a7c5 | ||
|
534e4cb843 | ||
|
e303008e66 | ||
|
5404e7432d | ||
|
e92504ae92 | ||
|
4964bfb87f | ||
|
39da035135 | ||
|
4ee29f355e | ||
|
87144fd3a8 | ||
|
f6d4554669 | ||
|
1451857c92 | ||
|
23685ddb3c | ||
|
ce5cee42a1 | ||
|
067ab90847 | ||
|
937d5d728e | ||
|
d6757019dc | ||
|
5581cf33f9 | ||
|
35058628c1 | ||
|
d581c8b1e4 | ||
|
44b1086be9 | ||
|
d277ed1a8a | ||
|
7aa280b888 | ||
|
14dabb6f51 | ||
|
84bce23fec | ||
|
583aa55259 | ||
|
4873b8e22a | ||
|
c85e9a91d1 | ||
|
51ff795be4 | ||
|
632a9ac590 | ||
|
d73be58c1a | ||
|
04c84a8f66 | ||
|
d2570bc2ea | ||
|
4b1a6e4b92 | ||
|
c05fdea765 | ||
|
4e98ab7515 | ||
|
fda6895dc8 | ||
|
b488c766b1 | ||
|
94fed03a67 | ||
|
adb77466f5 | ||
|
6ab6a6811b | ||
|
b1ef21f62f | ||
|
75c736709d | ||
|
1ff8526d24 | ||
|
a76541458d | ||
|
d014a7dd8c | ||
|
93edc4ac42 | ||
|
7383cc4b68 | ||
|
95c8acc31e | ||
|
e86173b895 | ||
|
be0f4a1fc9 | ||
|
b913d6842f | ||
|
93b4cc2e7b | ||
|
7a451d5a36 | ||
|
2d2f0dd51d | ||
|
8631dfb723 | ||
|
c9f7f2cfc8 | ||
|
f2893437d2 | ||
|
2f47d2400b | ||
|
348c278eae | ||
|
7af579a1bc | ||
|
4333575bb9 | ||
|
e0217c650d | ||
|
1723288f5d | ||
|
88e21758bc | ||
|
e031de6b57 | ||
|
baf867a9f9 | ||
|
04f15fbfee | ||
|
cb95e99f50 | ||
|
28f98cc129 | ||
|
3ab2228065 | ||
|
eda171d57a | ||
|
0bf7ff5f34 |
36
.github/workflows/make-apk.yml
vendored
Normal file
36
.github/workflows/make-apk.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: Make Apk CI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
Build-Apk:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install nix
|
||||
uses: cachix/install-nix-action@v15
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@v10
|
||||
with:
|
||||
name: julow
|
||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v2
|
||||
- name: Cache debug certificate
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: _build/debug.keystore
|
||||
key: debug-keystore
|
||||
- name: Run nix-shell and Make
|
||||
uses: ZenithalHourlyRate/nix-shell-action@v4
|
||||
with:
|
||||
file: shell.nix
|
||||
script: make
|
||||
- name: Save debug apk
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: debug apk
|
||||
path: _build/*.apk
|
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="juloo.keyboard2" android:versionCode="15" android:versionName="1.11.1" android:hardwareAccelerated="false">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="juloo.keyboard2" android:versionCode="18" android:versionName="1.13.1" android:hardwareAccelerated="false">
|
||||
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="30"/>
|
||||
<application android:label="@string/app_name" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:hardwareAccelerated="false">
|
||||
<service android:name="juloo.keyboard2.Keyboard2" android:label="@string/app_name" android:permission="android.permission.BIND_INPUT_METHOD">
|
||||
@@ -8,7 +8,7 @@
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.view.im" android:resource="@xml/method"/>
|
||||
</service>
|
||||
<activity android:name="juloo.keyboard2.SettingsActivity" android:icon="@drawable/ic_launcher" android:label="@string/settings_activity_label">
|
||||
<activity android:name="juloo.keyboard2.SettingsActivity" android:icon="@drawable/ic_launcher" android:label="@string/settings_activity_label" android:theme="@style/android:Theme.Material">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
</intent-filter>
|
||||
|
@@ -9,7 +9,7 @@ Android Studio.
|
||||
|
||||
Fortunately, there's not many dependencies:
|
||||
- OpenJDK 8
|
||||
- Android SDK: build tools `30.0.3`, platform `30`
|
||||
- Android SDK: build tools (minimum `28.0.1`), platform `30`
|
||||
- Make sure to have the `$ANDROID_HOME` environment variable set.
|
||||
|
||||
For Nix users, there's a `shell.nix` for setting-up the right environment.
|
||||
@@ -57,3 +57,29 @@ The application must be enabled again in the settings.
|
||||
adb uninstall juloo.keyboard2.debug
|
||||
make installd
|
||||
```
|
||||
|
||||
## Guidelines
|
||||
|
||||
### Add a localized layout
|
||||
|
||||
Localized layouts (a layout specific to a language) are generally accepted.
|
||||
See for example: 4333575 (Bulgarian), 88e2175 (Latvian), 133b6ec (German).
|
||||
|
||||
This keyboard is intended for programmers. If your language uses the Latin script, make sure it is possible to type every letters on the QWERTY keyboard.
|
||||
This is generally done using dead-keys, for example: 0bf7ff5 (Latvian), 573c13f (Swedish).
|
||||
It is also possible to add some characters that are hidden in other languages, for example 93e84ba (ß), though the space is limited.
|
||||
|
||||
### Add a programming layout
|
||||
|
||||
A programming layout must contains every ASCII characters as well as every dead-keys.
|
||||
Currently, the only example is QWERTY.
|
||||
|
||||
### Translations
|
||||
|
||||
Translations are always welcome ! See for example: 1723288 (Latvian), baf867a (French).
|
||||
The app can be translated by writing `res/values-<language code>/strings.xml` (for example `values-fr`, `values-lv`), based on the default: `res/values/strings.xml` (English).
|
||||
|
||||
The store description is found in `metadata/android/<locale>/`, `short_description.txt` and `full_description.txt`.
|
||||
The full description changes very infrequently (it was changed once in 6 years). But if it changes too much, outdated translation might be removed.
|
||||
|
||||
Translating changelogs is not useful because they evolve too fast. Changelogs are generally written entirely just before a release, translating them would delay releases too much. Old changelogs are not shown to anyone currently.
|
||||
|
16
Makefile
16
Makefile
@@ -3,7 +3,7 @@
|
||||
PACKAGE_NAME = juloo.keyboard2
|
||||
|
||||
ANDROID_PLATFORM_VERSION = android-30
|
||||
JAVA_VERSION = 1.7
|
||||
JAVA_VERSION = 1.8
|
||||
|
||||
SRC_DIR = srcs
|
||||
ASSETS_DIR = assets
|
||||
@@ -19,7 +19,11 @@ release: _build/$(PACKAGE_NAME).apk
|
||||
installd: _build/$(PACKAGE_NAME).debug.apk
|
||||
adb install "$<"
|
||||
|
||||
.PHONY: release debug installd
|
||||
clean:
|
||||
rm -rf _build/*.dex _build/class _build/gen _build/*.apk _build/*.unsigned-apk \
|
||||
_build/*.idsig
|
||||
|
||||
.PHONY: release debug installd clean
|
||||
|
||||
$(shell mkdir -p _build)
|
||||
|
||||
@@ -55,12 +59,12 @@ $(DEBUG_KEYSTORE):
|
||||
-keyalg rsa -storepass $(DEBUG_PASSWD) -validity 10000
|
||||
|
||||
_build/%.debug.apk: _build/%.debug.unsigned-apk $(DEBUG_KEYSTORE)
|
||||
apksigner sign --in "$<" --out "$@" \
|
||||
$(ANDROID_BUILD_TOOLS)/apksigner sign --in "$<" --out "$@" \
|
||||
--ks $(DEBUG_KEYSTORE) --ks-key-alias debug --ks-pass "pass:$(DEBUG_PASSWD)"
|
||||
|
||||
# Debug apk
|
||||
|
||||
_build/$(PACKAGE_NAME).debug.unsigned-apk: AAPT_PACKAGE_FLAGS+=--rename-manifest-package $(PACKAGE_NAME).debug
|
||||
_build/$(PACKAGE_NAME).debug.unsigned-apk: AAPT_PACKAGE_FLAGS+=--rename-manifest-package $(PACKAGE_NAME).debug --product debug
|
||||
|
||||
# Release signing
|
||||
|
||||
@@ -68,7 +72,7 @@ _build/$(PACKAGE_NAME).debug.unsigned-apk: AAPT_PACKAGE_FLAGS+=--rename-manifest
|
||||
# it is interpreted as a shell script
|
||||
_build/%.apk: _build/%.unsigned-apk %-keystore.conf
|
||||
eval `cat $(word 2,$^)` && \
|
||||
apksigner sign --in "$<" --out "$@" \
|
||||
$(ANDROID_BUILD_TOOLS)/apksigner sign --in "$<" --out "$@" \
|
||||
--ks "$$KEYSTORE" --ks-key-alias "$$KEYNAME" --ks-pass "pass:$$KEYSTOREPASS"
|
||||
|
||||
# Package
|
||||
@@ -105,4 +109,4 @@ _build/classes.dex: $(JAVA_FILES) $(R_FILE)
|
||||
-classpath $(ANDROID_PLATFORM)/android.jar:$(EXTRA_JARS) \
|
||||
-sourcepath $(SRC_DIR):$(GEN_DIR) \
|
||||
$^
|
||||
$(ANDROID_BUILD_TOOLS)/dx --dex --output="$@" $(OBJ_DIR) $(subst :, ,$(EXTRA_JARS))
|
||||
$(ANDROID_BUILD_TOOLS)/d8 --output $(@D) $(OBJ_DIR)/*/*/* $(subst :, ,$(EXTRA_JARS))
|
||||
|
@@ -26,6 +26,9 @@ System > Languages & input > On-screen keyboard > Manage on-screen keyboards.
|
||||
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||
alt="Get it on F-Droid"
|
||||
height="80">](https://f-droid.org/packages/juloo.keyboard2/)
|
||||
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png"
|
||||
alt="Get it on Google Play"
|
||||
height="80">](https://play.google.com/store/apps/details?id=juloo.keyboard2)
|
||||
|
||||
## Contributing
|
||||
|
||||
|
15
assets/fonts/README.md
Normal file
15
assets/fonts/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Fonts
|
||||
|
||||
The glyphs from this font are made by:
|
||||
|
||||
- Home and End
|
||||
Author: @sdrapha
|
||||
|
||||
- Cog
|
||||
Copyright (C) 2016 by Dave Gandy
|
||||
Author: Dave Gandy
|
||||
License: SIL ()
|
||||
|
||||
- Emoticon, PageUp and PageDown
|
||||
IcoMoon-Free is a free vector icon pack by Keyamoon.
|
||||
License: Attribution 4.0 International (CC BY 4.0)
|
Binary file not shown.
18
metadata/android/de-DE/full_description.txt
Normal file
18
metadata/android/de-DE/full_description.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
Diese App ist eine virtuelle Tastatur für Android. Hauptfunktionen sind das einfache Tippen eines jeden ASCII-Zeichens durch Wischgesten, Hilfstasten, Tottasten für Akzente, sowie das Vorhandensein spezieller Tasten (Tabulator, Esc, Pfeiltasten etc.).
|
||||
|
||||
Die Tastatur hat bis zu vier Extrazeichen in den Ecken jeder Taste. Diese Extrazeichen werden durch das Wischen mit dem Finger auf der Taste ausgewählt.
|
||||
|
||||
Highlights mancher Funktionen:
|
||||
|
||||
- Jedes Zeichen und jede spezielle Taste gibt es auch auf einer PC-Tastatur. Das ist perfekt für die Nutzung von Anwendungen wie Termux.
|
||||
|
||||
- Dies schließt auch Tab, Esc und die Pfeil- und Funktionstasten sowie Strg und Alt mit ein!
|
||||
|
||||
- Akzenttasten sind über Tottasten verfügbar. Nach Aktivieren des Akzents kan der akzentuierte Buchstabe getippt werden.
|
||||
|
||||
- Sehr schlank und schnell. Braucht 500x weniger Speicherplatz als Googles Tastatur und 15x weniger als die Standardtastatur. Keine Werbung, kein Tracking.
|
||||
|
||||
- Verschiedene Layouts: QWERTY, QWERTZ, AZERTY. Themes: Weiß, Dunkel, OLED Schwarz. Und viele weitere Optionen.
|
||||
|
||||
Wie jede andere virtuelle Tastatur muss diese Tastatur in den Systemeinstellungen aktiviert werden. Dazu Systemeinstellungen öffnen und wie folgt vorgehen:
|
||||
System > Sprachen und Eingabe > Bildschirmtastatur > Bildschirmtastaturen verwalten.
|
13
metadata/android/en-US/changelogs/16.txt
Normal file
13
metadata/android/en-US/changelogs/16.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
New languages: Latvian (thanks @eandersons), Bulgarian (thanks Zdravko Iskrenov)
|
||||
New layouts: Bulgarian traditional, Latvian
|
||||
|
||||
The application can now be translated.
|
||||
Translations: French, Latvian (thanks @eandersons)
|
||||
|
||||
Improve the behavior of the Action key.
|
||||
The globe key now opens the keyboard switching dialog.
|
||||
The literal tab character can be typed with Fn+Tab.
|
||||
Add options to control the spacing between the keys.
|
||||
Better integration with the system theme.
|
||||
|
||||
Thanks to all the contributors: @Moini, @sdrapha, @eandersons, @Poussinou, Zdravko Iskrenov
|
13
metadata/android/en-US/changelogs/17.txt
Normal file
13
metadata/android/en-US/changelogs/17.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
New languages: Portuguese (thanks @sdrapha), Russian (thanks @carrot-cookie), Spanish (thanks @gh0ste)
|
||||
New layouts: Dvorak (thanks @AlexandraAlter), Russian Jcuken, Spanish Qwerty
|
||||
|
||||
Added the Meta key (the equivalent of the Win on Windows)
|
||||
Added ordinal symbols on the number pane (thanks @sdrapha)
|
||||
Better position for the arrow keys (thanks @MaxGyver83)
|
||||
Improvements to some of the symbols (thanks @MaxGyver83, @Roy-Orbison)
|
||||
Improvements to the layouts
|
||||
Improvements to the key-repeat for arrows
|
||||
Fixed Shift+Arrows for selecting text
|
||||
Fixed dark theme bugs on Xiaomi phones
|
||||
|
||||
Thanks to all the contributors: @sdrapha, @MaxGyver83, @AlexandraAlter, @Roy-Orbison, @carrot-cookie, @gh0ste
|
5
metadata/android/en-US/changelogs/18.txt
Normal file
5
metadata/android/en-US/changelogs/18.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Improved text size, especially on large screens
|
||||
Increased contrasts
|
||||
Improved symbols (thanks @sdrapha)
|
||||
German translation (thanks @polyctena)
|
||||
Fix to some layouts.
|
Binary file not shown.
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 46 KiB |
1
metadata/android/es-ES/short_description.txt
Normal file
1
metadata/android/es-ES/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Un teclado virtual ligero para desarrolladores.
|
1
metadata/android/es-ES/title.txt
Normal file
1
metadata/android/es-ES/title.txt
Normal file
@@ -0,0 +1 @@
|
||||
Unexpected Keyboard
|
@@ -1,3 +0,0 @@
|
||||
- Ajout de l'Espagnol et l'Italien
|
||||
- Nouvel emplacement pour les accents (encore) et ajout de nouveaux caratères
|
||||
- Correction de bugs (un crash sur d'anciennes versions d'Android et un rare glitch graphique après une rotation)
|
@@ -1 +0,0 @@
|
||||
Première version open-source !
|
@@ -1,3 +0,0 @@
|
||||
- Nouvelle langue: Suédois
|
||||
- Les raccourcis clavier fonctionnent dans toutes les applications
|
||||
- Correction d'un bug graphique et quelques ajustements
|
@@ -1,8 +0,0 @@
|
||||
Nouvelle langue : Allemand
|
||||
|
||||
Nouvelle configuration du clavier : QWERTZ
|
||||
|
||||
Thèmes : Clair, Sombre et Noir OLED
|
||||
|
||||
Ajout de la touche Action, à côté de la touche Entrer, nécessaire pour certaines applications.
|
||||
Amélioration des options et résolution de bugs.
|
@@ -1,8 +0,0 @@
|
||||
Nouvelle langue : Allemand
|
||||
|
||||
Nouvelle configuration du clavier : QWERTZ
|
||||
|
||||
Thèmes : Clair, Sombre et Noir OLED
|
||||
|
||||
Ajout de la touche Action, à côté de la touche Entrer, nécessaire pour certaines applications.
|
||||
Amélioration des options et résolution de bugs.
|
18
metadata/android/lv-LV/full_description.txt
Normal file
18
metadata/android/lv-LV/full_description.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
Šī lietotne ir tastatūra Android tālruņiem. Galvenās iespējas ir ērta ASCII rakstzīmju ievadīšana ar pavilkšanas kustību, taustiņi piekļūšanai uzsvara zīmēm un pārveidošanas taustiņiem un īpašo taustiņu esamība (Tab, Esc, bultas utt.).
|
||||
|
||||
Tastatūrā ir redzamas līdz 4 papildus rakstzīmēm katra taustiņa stūros. Tām var piekļūt ar pirksta pavilkšanu uz taustiņa attiecīgajā virzienā.
|
||||
|
||||
Izceltās iespējas:
|
||||
|
||||
- Visas rakstzīmes un īpašie taustiņi, kas ir atrodami arī datora tastatūrā. Tas lieliski noder tādās lietotnēs kā, piemēram, Termux.
|
||||
|
||||
- Ir iekļauti Tab, Esc, bultas un darbību taustiņi, kā arī Ctrl un Alt.
|
||||
|
||||
- Uzsvara zīmju taustiņi ir pieejami ar īpašām pogām. Vispirms jāizvēlas uzsvara zīmes veids, tad jāievada vēlamais burts.
|
||||
|
||||
- Ļoti viegla un ātra. Izmanto 500 reižu mazāk vietas kā Google tastatūra un 15 reižu mazāk kā noklusējuma tastatūra. Bez reklāmām un izsekošanas.
|
||||
|
||||
- Dažādi izkārtojumi: QWERTY, QWERTZ, AZERTY. Izskats: Gaišs, Tumšs, OLED melns. Kā arī daudzas citas papildiespējas.
|
||||
|
||||
Kā jebkura cita tālruņa tastatūra, tā ir jāiespējo ierīces iestatījumos. Jāatver Iestatījumi un tad:
|
||||
Sistēma > Valodas un ievade > Virtuālā tastatūra > Pārvaldīt tastatūras.
|
1
metadata/android/lv-LV/short_description.txt
Normal file
1
metadata/android/lv-LV/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Viegla un ātra tālruņa tastatūra izstrādātājiem.
|
18
metadata/android/pt-BR/full_description.txt
Normal file
18
metadata/android/pt-BR/full_description.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
Um teclado virtual para aparelhos Android. Os recursos principais são facilidade de digitar todos os caracteres ASCII deslizando o dedo, teclas "mortas" para acentos e teclas modificadoras e a presença de teclas especiais (tab, esc, setas, etc..).
|
||||
|
||||
O teclado mostra até 4 caracteres extras nos cantos de cada tecla. Esses caracteres são digitáveis com o deslizar do dedo na tecla.
|
||||
|
||||
Alguns dos recursos interessantes:
|
||||
|
||||
- Todos caracteres e teclas especiais que também estão disponíveis num teclado de PC. Perfeito para usar com aplicativos como Termux.
|
||||
|
||||
- Incluindo Tab, Esc, as setas e teclas de função, e também Ctrl e Alt!
|
||||
|
||||
- Caracteres acentuados são digitáveis usando teclas "mortas". Primeiro ative o acento e depois digite a letra.
|
||||
|
||||
- Muito leve e rápido. Ocupa 500x menos espaço que o teclado da Google e 15x menos espaço que o teclado padrão. Sem propaganda, sem rastreio.
|
||||
|
||||
- Vários layouts: QWERTY, QWERTZ, AZERTY. Temas: Branco, Escuro, Preto OLED. E muitas outras opções.
|
||||
|
||||
Como qualquer outro teclado virtual, tem de ser ativado nas configurações de sistema. Abra as configurações e vá para:
|
||||
Sistema > Idioma e entrada > Teclado virtual > Gerenciar teclados virtuais.
|
1
metadata/android/pt-BR/short_description.txt
Normal file
1
metadata/android/pt-BR/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Um teclado virtual leve para desenvolvedores.
|
1
metadata/android/pt-BR/title.txt
Normal file
1
metadata/android/pt-BR/title.txt
Normal file
@@ -0,0 +1 @@
|
||||
Unexpected Keyboard
|
47
res/values-de/strings.xml
Normal file
47
res/values-de/strings.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="settings_activity_label">Unexpected Keyboard - Einstellungen</string>
|
||||
<string name="pref_category_layout">Layout</string>
|
||||
<string name="pref_layout_title">Tastaturlayout ändern</string>
|
||||
<string name="pref_layout_e_system">Systemeinstellung</string>
|
||||
<string name="pref_accents_title">Akzente</string>
|
||||
<string name="pref_accents_e_all_installed">Akzente für alle installierten Sprachen anzeigen</string>
|
||||
<string name="pref_accents_e_selected">Akzente nur für die gewählte Sprache anzeigen</string>
|
||||
<string name="pref_accents_e_all">Alle Akzente anzeigen</string>
|
||||
<string name="pref_accents_e_none">Akzente verbergen</string>
|
||||
<string name="pref_category_typing">Tippen</string>
|
||||
<string name="pref_swipe_dist_title">Länge der Wischgeste</string>
|
||||
<string name="pref_swipe_dist_summary">Abstand der Zeichen in den Ecken der Tasten (%s)</string>
|
||||
<string name="pref_long_timeout_title">Zeitüberschreitung bei Tastenwiederholung</string>
|
||||
<string name="pref_long_interval_title">Intervall der Tastenwiederholung</string>
|
||||
<string name="pref_category_vibrate">Vibration</string>
|
||||
<string name="pref_vibrate_title">Vibration</string>
|
||||
<string name="pref_vibrate_summary">Vibration bei Tastendruck ein-/ausschalten</string>
|
||||
<string name="pref_vibrate_duration_title">Dauer</string>
|
||||
<string name="pref_precise_repeat_title">Präzise Cursorsteuerung</string>
|
||||
<string name="pref_precise_repeat_summary">Geschwindigkeit der Tastenwiederholung durch weniger oder mehr Wischen anpassen</string>
|
||||
<string name="pref_category_style">Design</string>
|
||||
<string name="pref_margin_bottom_title">Unterer Abstand</string>
|
||||
<string name="pref_keyboard_height_title">Höhe der Tastatur</string>
|
||||
<string name="pref_horizontal_margin_title">Horizontaler Abstand</string>
|
||||
<string name="pref_character_size_title">Größe der Beschriftung</string>
|
||||
<string name="pref_character_size_summary">Größe der Buchstaben auf den Tasten (%.2fx)</string>
|
||||
<string name="pref_theme">Theme</string>
|
||||
<string name="pref_theme_e_system">Systemeinstellung</string>
|
||||
<string name="pref_theme_e_dark">Dunkel</string>
|
||||
<string name="pref_theme_e_light">Hell</string>
|
||||
<string name="pref_theme_e_black">Schwarz</string>
|
||||
<string name="pref_swipe_dist_e_very_short">Sehr kurz</string>
|
||||
<string name="pref_swipe_dist_e_short">Kurz</string>
|
||||
<string name="pref_swipe_dist_e_default">Normal</string>
|
||||
<string name="pref_swipe_dist_e_far">Weit</string>
|
||||
<string name="pref_swipe_dist_e_very_far">Sehr weit</string>
|
||||
<string name="pref_key_horizontal_space">Horizontaler Abstand zwischen den Tasten</string>
|
||||
<string name="pref_key_vertical_space">Vertikaler Abstand zwischen den Tasten</string>
|
||||
<string name="key_action_next">Nächstes</string>
|
||||
<string name="key_action_done">Fertig</string>
|
||||
<string name="key_action_go">Los</string>
|
||||
<string name="key_action_prev">Vorheriges</string>
|
||||
<string name="key_action_search">Suchen</string>
|
||||
<string name="key_action_send">Senden</string>
|
||||
</resources>
|
47
res/values-es/strings.xml
Normal file
47
res/values-es/strings.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="settings_activity_label">Ajustes de Unexpected Keyboard</string>
|
||||
<string name="pref_category_layout">Formato</string>
|
||||
<string name="pref_layout_title">Cambiar formato de teclado</string>
|
||||
<string name="pref_layout_e_system">Ajustes del sistema</string>
|
||||
<string name="pref_accents_title">Acentos</string>
|
||||
<string name="pref_accents_e_all_installed">Mostrar acentos para todos los lenguajes instalados</string>
|
||||
<string name="pref_accents_e_selected">Solo mostrar acentos para el lenguaje seleccionado</string>
|
||||
<string name="pref_accents_e_all">Mostrar todos los acentos</string>
|
||||
<string name="pref_accents_e_none">Ocultar acentos</string>
|
||||
<string name="pref_category_typing">Escribiendo</string>
|
||||
<string name="pref_swipe_dist_title">Distancia para deslizar</string>
|
||||
<string name="pref_swipe_dist_summary">Distancia de caractéres en las esquinas de las letras (%s)</string>
|
||||
<string name="pref_long_timeout_title">Tiempo de espera de repetición de tecla</string>
|
||||
<string name="pref_long_interval_title">Intervalo de repetición de tecla</string>
|
||||
<string name="pref_category_vibrate">Vibración</string>
|
||||
<string name="pref_vibrate_title">Vibración</string>
|
||||
<string name="pref_vibrate_summary">Habilitar/deshabilitar vibración al presionar una tecla</string>
|
||||
<string name="pref_vibrate_duration_title">Duración</string>
|
||||
<string name="pref_precise_repeat_title">Movimientos de cursor preciso</string>
|
||||
<string name="pref_precise_repeat_summary">Modular la velocidad de repetición de teclas según si se desliza más o menos</string>
|
||||
<string name="pref_category_style">Estilo</string>
|
||||
<string name="pref_margin_bottom_title">Margen del pie</string>
|
||||
<string name="pref_keyboard_height_title">Altura del teclado</string>
|
||||
<string name="pref_horizontal_margin_title">Margen horizontal</string>
|
||||
<string name="pref_character_size_title">Tamaño de etiqueta</string>
|
||||
<string name="pref_character_size_summary">Tamaño de caractéres mostrados en el teclado (%.2fx)</string>
|
||||
<string name="pref_theme">Tema</string>
|
||||
<string name="pref_theme_e_system">Ajustes de sistema</string>
|
||||
<string name="pref_theme_e_dark">Oscuro</string>
|
||||
<string name="pref_theme_e_light">Claro</string>
|
||||
<string name="pref_theme_e_black">Negro</string>
|
||||
<string name="pref_swipe_dist_e_very_short">Muy corto</string>
|
||||
<string name="pref_swipe_dist_e_short">Corto</string>
|
||||
<string name="pref_swipe_dist_e_default">Normal</string>
|
||||
<string name="pref_swipe_dist_e_far">Lejano</string>
|
||||
<string name="pref_swipe_dist_e_very_far">Muy lejano</string>
|
||||
<string name="pref_key_horizontal_space">Espaciado horizontal entre las teclas</string>
|
||||
<string name="pref_key_vertical_space">Espaciado vertical entre las teclas</string>
|
||||
<string name="key_action_next">Siguiente</string>
|
||||
<string name="key_action_done">Hecho</string>
|
||||
<string name="key_action_go">Ir</string>
|
||||
<string name="key_action_prev">Anterior</string>
|
||||
<string name="key_action_search">Buscar</string>
|
||||
<string name="key_action_send">Enviar</string>
|
||||
</resources>
|
47
res/values-fr/strings.xml
Normal file
47
res/values-fr/strings.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="settings_activity_label">Unexpected Keyboard Paramètres</string>
|
||||
<string name="pref_category_layout">Disposition</string>
|
||||
<string name="pref_layout_title">Disposition des touches</string>
|
||||
<string name="pref_layout_e_system">Paramètre système</string>
|
||||
<string name="pref_accents_title">Accents</string>
|
||||
<string name="pref_accents_e_all_installed">Afficher les accents pour les langues installées</string>
|
||||
<string name="pref_accents_e_selected">Afficher les accents pour la langue sélectionnée</string>
|
||||
<string name="pref_accents_e_all">Afficher tous les accents</string>
|
||||
<string name="pref_accents_e_none">Cacher les accents</string>
|
||||
<string name="pref_category_typing">Saisie</string>
|
||||
<string name="pref_swipe_dist_title">Distance de swipe</string>
|
||||
<string name="pref_swipe_dist_summary">La distance des caractères dans les coins (%s)</string>
|
||||
<string name="pref_long_timeout_title">Délai avant répétition</string>
|
||||
<string name="pref_long_interval_title">Écart entre répétitions</string>
|
||||
<string name="pref_category_vibrate">Vibration</string>
|
||||
<string name="pref_vibrate_title">Vibreur</string>
|
||||
<string name="pref_vibrate_summary">Vibration a chaque touche</string>
|
||||
<string name="pref_vibrate_duration_title">Durée</string>
|
||||
<string name="pref_precise_repeat_title">Mouvement précis du curseur</string>
|
||||
<string name="pref_precise_repeat_summary">Modifier la vitesse de répétition en bougeant le doigt</string>
|
||||
<string name="pref_category_style">Style</string>
|
||||
<string name="pref_margin_bottom_title">Marge du bas</string>
|
||||
<string name="pref_keyboard_height_title">Hauteur du clavier</string>
|
||||
<string name="pref_horizontal_margin_title">Marge des côtés</string>
|
||||
<string name="pref_character_size_title">Taille des labels</string>
|
||||
<string name="pref_character_size_summary">Taille des caractères affichés sur les touches (%.2fx)</string>
|
||||
<string name="pref_theme">Thème</string>
|
||||
<string name="pref_theme_e_system">Paramètre système</string>
|
||||
<string name="pref_theme_e_dark">Sombre</string>
|
||||
<string name="pref_theme_e_light">Clair</string>
|
||||
<string name="pref_theme_e_black">Noir</string>
|
||||
<string name="pref_swipe_dist_e_very_short">Très courte</string>
|
||||
<string name="pref_swipe_dist_e_short">Courte</string>
|
||||
<string name="pref_swipe_dist_e_default">Normale</string>
|
||||
<string name="pref_swipe_dist_e_far">Longue</string>
|
||||
<string name="pref_swipe_dist_e_very_far">Très longue</string>
|
||||
<string name="pref_key_horizontal_space">Espacement horizontal entre les touches</string>
|
||||
<string name="pref_key_vertical_space">Espacement vertical entre les touches</string>
|
||||
<string name="key_action_next">Suiv.</string>
|
||||
<string name="key_action_done">Fin</string>
|
||||
<string name="key_action_go">Aller</string>
|
||||
<string name="key_action_prev">Prec.</string>
|
||||
<string name="key_action_search">Chercher</string>
|
||||
<string name="key_action_send">Envoyer</string>
|
||||
</resources>
|
@@ -4,7 +4,8 @@
|
||||
<dimen name="margin_bottom">3dp</dimen>
|
||||
<dimen name="key_padding">3dp</dimen>
|
||||
<dimen name="key_height">36dp</dimen>
|
||||
<dimen name="label_text_size">18dp</dimen>
|
||||
<dimen name="sublabel_text_size">11dp</dimen>
|
||||
<item name="label_text_size" type="integer" format="float">0.4</item>
|
||||
<item name="sublabel_text_size" type="integer" format="float">0.3</item>
|
||||
<dimen name="emoji_type_button_height">48dp</dimen>
|
||||
<dimen name="extra_horizontal_margin">20dp</dimen>
|
||||
</resources>
|
||||
|
45
res/values-lv/strings.xml
Normal file
45
res/values-lv/strings.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="settings_activity_label">Unexpected Keyboard iestatījumi</string>
|
||||
<string name="pref_category_layout">Izkārtojums</string>
|
||||
<string name="pref_layout_title">Mainīt tastatūras izkārtojumu</string>
|
||||
<string name="pref_layout_e_system">Ierīces iestatījumi</string>
|
||||
<string name="pref_accents_title">Uzsvara zīmes</string>
|
||||
<string name="pref_accents_e_all_installed">Rādīt uzsvara zīmes visām uzstādītajām valodām</string>
|
||||
<string name="pref_accents_e_selected">Rādīt uzsvara zīmes tikai atlasītajām valodām</string>
|
||||
<string name="pref_accents_e_all">Rādīt visas uzsvara zīmes</string>
|
||||
<string name="pref_accents_e_none">Paslēpt uzsvara zīmes</string>
|
||||
<string name="pref_category_typing">Rakstīšana</string>
|
||||
<string name="pref_swipe_dist_title">Pavilkšanas attālums</string>
|
||||
<string name="pref_swipe_dist_summary">Taustiņu stūros esošo rakstzīmju attālums (%s)</string>
|
||||
<string name="pref_long_timeout_title">Taustiņa atkārtošanās ātrums</string>
|
||||
<string name="pref_long_interval_title">Taustiņa atkārtošanās aizture</string>
|
||||
<string name="pref_category_vibrate">Trīcēšana</string>
|
||||
<string name="pref_vibrate_title">Trīcēšana</string>
|
||||
<string name="pref_vibrate_summary">Iespējot/atspējot taustiņa piespiešanas trīcēšanu</string>
|
||||
<string name="pref_vibrate_duration_title">Ilgums</string>
|
||||
<string name="pref_precise_repeat_title">Pielāgojama kursora kustība</string>
|
||||
<string name="pref_precise_repeat_summary">Mainīt taustiņa atkārtošanās ātrumu ar pavilkšanas attālumu</string>
|
||||
<string name="pref_category_style">Izskata pielāgojumi</string>
|
||||
<string name="pref_margin_bottom_title">Apakšējā apmale</string>
|
||||
<string name="pref_keyboard_height_title">Tastatūras augstums</string>
|
||||
<string name="pref_horizontal_margin_title">Līmeniskā apmale</string>
|
||||
<string name="pref_character_size_title">Iezīmes izmērs</string>
|
||||
<string name="pref_character_size_summary">Tastatūrā attēloto rakstzīmju izmērs (%.2fx)</string>
|
||||
<string name="pref_theme">Izskats</string>
|
||||
<string name="pref_theme_e_system">Ierīces iestatījumi</string>
|
||||
<string name="pref_theme_e_dark">Tumšs</string>
|
||||
<string name="pref_theme_e_light">Gaišs</string>
|
||||
<string name="pref_theme_e_black">Melns</string>
|
||||
<string name="pref_swipe_dist_e_very_short">Ļoti tuvs</string>
|
||||
<string name="pref_swipe_dist_e_short">Tuvs</string>
|
||||
<string name="pref_swipe_dist_e_default">Vidējs</string>
|
||||
<string name="pref_swipe_dist_e_far">Tāls</string>
|
||||
<string name="pref_swipe_dist_e_very_far">Ļoti tāls</string>
|
||||
<string name="key_action_next">Nākamais</string>
|
||||
<string name="key_action_done">Darīts</string>
|
||||
<string name="key_action_go">Aiziet</string>
|
||||
<string name="key_action_prev">Iepriekšējais</string>
|
||||
<string name="key_action_search">Meklēt</string>
|
||||
<string name="key_action_send">Sūtīt</string>
|
||||
</resources>
|
49
res/values-pt/strings.xml
Normal file
49
res/values-pt/strings.xml
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="settings_activity_label">Configurações Unexpected Keyboard</string>
|
||||
<string name="pref_category_layout">Layout</string>
|
||||
<string name="pref_layout_title">Mudar layout do teclado</string>
|
||||
<string name="pref_layout_e_system">Mesmo do sistema</string>
|
||||
<string name="pref_accents_title">Acentos</string>
|
||||
<string name="pref_accents_e_all_installed">Mostrar acentos para todos idiomas instalados</string>
|
||||
<string name="pref_accents_e_selected">Mostrar acentos só para o idioma selecionado</string>
|
||||
<string name="pref_accents_e_all">Mostrar todos acentos</string>
|
||||
<string name="pref_accents_e_none">Esconder acentos</string>
|
||||
<string name="pref_category_typing">Digitação</string>
|
||||
<string name="pref_swipe_dist_title">Distância a deslizar</string>
|
||||
<string name="pref_swipe_dist_summary">Distância até acionar os cantos das teclas (%s)</string>
|
||||
<string name="pref_long_timeout_title">Tempo até repetir tecla</string>
|
||||
<string name="pref_long_interval_title">Intervalo para repetir tecla</string>
|
||||
<string name="pref_category_vibrate">Vibração</string>
|
||||
<string name="pref_vibrate_title">Vibração</string>
|
||||
<string name="pref_vibrate_summary">Ativar/desativar vibração ao digitar</string>
|
||||
<string name="pref_vibrate_duration_title">Duração</string>
|
||||
<string name="pref_precise_repeat_title">Precisão nos movimentos do cursor</string>
|
||||
<string name="pref_precise_repeat_summary">Varia a velocidade de repetição ao depender de quanto deslizar</string>
|
||||
<string name="pref_lockable_keys_title">Segurar teclas</string>
|
||||
<string name="pref_lockable_keys_summary">Teclas que podem ficar seguradas ao teclar duas vezes</string>
|
||||
<string name="pref_category_style">Estilo</string>
|
||||
<string name="pref_margin_bottom_title">Margem de baixo</string>
|
||||
<string name="pref_keyboard_height_title">Altura do teclado</string>
|
||||
<string name="pref_horizontal_margin_title">Margem horizontal</string>
|
||||
<string name="pref_character_size_title">Tamanho dos indicadores</string>
|
||||
<string name="pref_character_size_summary">Tamanho dos caracteres visíveis no teclado (%.2fx)</string>
|
||||
<string name="pref_theme">Tema</string>
|
||||
<string name="pref_theme_e_system">Mesmo do sistema</string>
|
||||
<string name="pref_theme_e_dark">Escuro</string>
|
||||
<string name="pref_theme_e_light">Claro</string>
|
||||
<string name="pref_theme_e_black">Preto</string>
|
||||
<string name="pref_swipe_dist_e_very_short">Muito curto</string>
|
||||
<string name="pref_swipe_dist_e_short">Curto</string>
|
||||
<string name="pref_swipe_dist_e_default">Normal</string>
|
||||
<string name="pref_swipe_dist_e_far">Longo</string>
|
||||
<string name="pref_swipe_dist_e_very_far">Muito longo</string>
|
||||
<string name="pref_key_horizontal_space">Distância horizontal entre teclas</string>
|
||||
<string name="pref_key_vertical_space">Distância vertical entre teclas</string>
|
||||
<string name="key_action_next">Próximo</string>
|
||||
<string name="key_action_done">Pronto</string>
|
||||
<string name="key_action_go">Ir</string>
|
||||
<string name="key_action_prev">Anterior</string>
|
||||
<string name="key_action_search">Buscar</string>
|
||||
<string name="key_action_send">Enviar</string>
|
||||
</resources>
|
@@ -4,13 +4,27 @@
|
||||
<item>system</item>
|
||||
<item>azerty</item>
|
||||
<item>qwerty</item>
|
||||
<item>qwerty_pt</item>
|
||||
<item>qwerty_es</item>
|
||||
<item>qwerty_lv</item>
|
||||
<item>qwerty_sv_se</item>
|
||||
<item>ru_jcuken</item>
|
||||
<item>qwertz</item>
|
||||
<item>bgph1</item>
|
||||
<item>dvorak</item>
|
||||
</string-array>
|
||||
<string-array name="pref_layout_entries">
|
||||
<item>@string/pref_layout_e_system</item>
|
||||
<item>AZERTY</item>
|
||||
<item>QWERTY</item>
|
||||
<item>QWERTY (Brasileiro)</item>
|
||||
<item>QWERTY (Español)</item>
|
||||
<item>QWERTY (Latvian)</item>
|
||||
<item>QWERTY (Swedish)</item>
|
||||
<item>ЙЦУКЕН (Русский)</item>
|
||||
<item>QWERTZ</item>
|
||||
<item>Bulgarian (Phonetic Traditional)</item>
|
||||
<item>Dvorak</item>
|
||||
</string-array>
|
||||
<string-array name="pref_accents_entries">
|
||||
<item>@string/pref_accents_e_all_installed</item>
|
||||
@@ -25,11 +39,13 @@
|
||||
<item>4</item>
|
||||
</string-array>
|
||||
<string-array name="pref_theme_entries">
|
||||
<item>@string/pref_theme_e_system</item>
|
||||
<item>@string/pref_theme_e_dark</item>
|
||||
<item>@string/pref_theme_e_light</item>
|
||||
<item>@string/pref_theme_e_black</item>
|
||||
</string-array>
|
||||
<string-array name="pref_theme_values">
|
||||
<item>system</item>
|
||||
<item>dark</item>
|
||||
<item>light</item>
|
||||
<item>black</item>
|
||||
|
@@ -1,33 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Unexpected Keyboard</string>
|
||||
<string name="app_name" product="debug">Unexpected Keyboard (debug)</string>
|
||||
<string name="app_name" product="default">Unexpected Keyboard</string>
|
||||
<string name="settings_activity_label">Unexpected Keyboard Settings</string>
|
||||
<string name="pref_category_layout">Layout</string>
|
||||
<string name="pref_layout_title">Change keyboard layout</string>
|
||||
<string name="pref_layout_e_system">System settings</string>
|
||||
<string name="pref_accents_title">Accents</string>
|
||||
<string name="pref_accents_e_all_installed">Show accents for all the installed languages</string>
|
||||
<string name="pref_accents_e_all_installed">Show accents for all installed languages</string>
|
||||
<string name="pref_accents_e_selected">Only show accents for the selected language</string>
|
||||
<string name="pref_accents_e_all">Show all accents</string>
|
||||
<string name="pref_accents_e_none">Hide accents</string>
|
||||
<string name="pref_category_typing">Typing</string>
|
||||
<string name="pref_swipe_dist_title">Swiping distance</string>
|
||||
<string name="pref_swipe_dist_summary">Distance of characters in the corners of the keys (%s)</string>
|
||||
<string name="pref_long_timeout_title">Long press timeout</string>
|
||||
<string name="pref_long_interval_title">Long press interval</string>
|
||||
<string name="pref_long_timeout_title">Key repeat timeout</string>
|
||||
<string name="pref_long_interval_title">Key repeat interval</string>
|
||||
<string name="pref_category_vibrate">Vibration</string>
|
||||
<string name="pref_vibrate_title">Vibration</string>
|
||||
<string name="pref_vibrate_summary">Enable/disable vibration on keypress</string>
|
||||
<string name="pref_vibrate_duration_title">Duration</string>
|
||||
<string name="pref_precise_repeat_title">Precise cursor movements</string>
|
||||
<string name="pref_precise_repeat_summary">Modulate the speed of movements by swiping more or less</string>
|
||||
<string name="pref_precise_repeat_summary">Modulate key repeat speed by swiping more or less</string>
|
||||
<string name="pref_lockable_keys_title">Lockable modifiers</string>
|
||||
<string name="pref_lockable_keys_summary">Modifier that can be locked by typing them twice</string>
|
||||
<string name="pref_category_style">Style</string>
|
||||
<string name="pref_margin_bottom_title">Margin bottom</string>
|
||||
<string name="pref_key_height_title">Key height</string>
|
||||
<string name="pref_keyboard_height_title">Keyboard height</string>
|
||||
<string name="pref_horizontal_margin_title">Horizontal margin</string>
|
||||
<string name="pref_character_size_title">Label size</string>
|
||||
<string name="pref_character_size_summary">Size of characters displayed on the keyboard (%.2fx)</string>
|
||||
<string name="pref_theme">Theme</string>
|
||||
<string name="pref_theme_e_system">System settings</string>
|
||||
<string name="pref_theme_e_dark">Dark</string>
|
||||
<string name="pref_theme_e_light">Light</string>
|
||||
<string name="pref_theme_e_black">Black</string>
|
||||
@@ -36,4 +40,12 @@
|
||||
<string name="pref_swipe_dist_e_default">Normal</string>
|
||||
<string name="pref_swipe_dist_e_far">Far</string>
|
||||
<string name="pref_swipe_dist_e_very_far">Very far</string>
|
||||
<string name="pref_key_horizontal_space">Horizontal spacing between the keys</string>
|
||||
<string name="pref_key_vertical_space">Vertical spacing between the keys</string>
|
||||
<string name="key_action_next">Next</string>
|
||||
<string name="key_action_done">Done</string>
|
||||
<string name="key_action_go">Go</string>
|
||||
<string name="key_action_prev">Prev</string>
|
||||
<string name="key_action_search">Search</string>
|
||||
<string name="key_action_send">Send</string>
|
||||
</resources>
|
||||
|
@@ -3,10 +3,10 @@
|
||||
<style name="emojiTypeButton">
|
||||
<item name="android:padding">1px</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:minHeight">@dimen/label_text_size</item>
|
||||
<item name="android:minHeight">18dp</item>
|
||||
<item name="android:background">?attr/emoji_button_bg</item>
|
||||
<item name="android:textColor">?attr/emoji_key_text</item>
|
||||
<item name="android:textSize">@dimen/label_text_size</item>
|
||||
<item name="android:textSize">18dp</item>
|
||||
</style>
|
||||
<style name="emojiKeyButton">
|
||||
<item name="android:layout_width">0px</item>
|
||||
@@ -15,7 +15,7 @@
|
||||
<item name="android:padding">0px</item>
|
||||
<item name="android:background">?attr/emoji_key_bg</item>
|
||||
<item name="android:textColor">?attr/emoji_key_text</item>
|
||||
<item name="android:textSize">@dimen/label_text_size</item>
|
||||
<item name="android:textSize">18dp</item>
|
||||
</style>
|
||||
<!-- Passed to TextView.setTextAppearance -->
|
||||
<style name="emojiGridButton">
|
||||
|
@@ -22,27 +22,31 @@
|
||||
<attr name="emoji_key_text" type="color" format="color"/>
|
||||
</declare-styleable>
|
||||
<style name="Dark">
|
||||
<item name="colorKeyboard">#1B1B1B</item>
|
||||
<item name="colorKey">#303030</item>
|
||||
<item name="colorKeyActivated">#1B1B1B</item>
|
||||
<item name="colorLabel">#FFFFFF</item>
|
||||
<item name="colorLabelActivated">#226b99</item>
|
||||
<item name="colorLabelLocked">#229933</item>
|
||||
<item name="colorSubLabel">#A0A0A0</item>
|
||||
<item name="android:isLightTheme">false</item>
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
<item name="colorKeyboard">#1b1b1b</item>
|
||||
<item name="colorKey">#333333</item>
|
||||
<item name="colorKeyActivated">#1b1b1b</item>
|
||||
<item name="colorLabel">#ffffff</item>
|
||||
<item name="colorLabelActivated">#3399ff</item>
|
||||
<item name="colorLabelLocked">#33cc33</item>
|
||||
<item name="colorSubLabel">#cccccc</item>
|
||||
<item name="keyBorderRadius">5dp</item>
|
||||
<item name="emoji_button_bg" type="color">#202020</item>
|
||||
<item name="emoji_color" type="color">#FFFFFF</item>
|
||||
<item name="emoji_color" type="color">#ffffff</item>
|
||||
<item name="emoji_key_bg" type="color">?attr/emoji_button_bg</item>
|
||||
<item name="emoji_key_text" type="color">?attr/colorLabel</item>
|
||||
</style>
|
||||
<style name="Light">
|
||||
<item name="android:isLightTheme">true</item>
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
<item name="colorKeyboard">#e3e3e3</item>
|
||||
<item name="colorKey">#cfcfcf</item>
|
||||
<item name="colorKey">#cccccc</item>
|
||||
<item name="colorKeyActivated">#e3e3e3</item>
|
||||
<item name="colorLabel">#000000</item>
|
||||
<item name="colorLabelActivated">#64afdd</item>
|
||||
<item name="colorLabelLocked">#64dd76</item>
|
||||
<item name="colorSubLabel">#5e5e5e</item>
|
||||
<item name="colorLabelActivated">#0066cc</item>
|
||||
<item name="colorLabelLocked">#33cc33</item>
|
||||
<item name="colorSubLabel">#333333</item>
|
||||
<item name="keyBorderRadius">5dp</item>
|
||||
<item name="emoji_button_bg" type="color">#dedede</item>
|
||||
<item name="emoji_color" type="color">#000000</item>
|
||||
@@ -50,6 +54,8 @@
|
||||
<item name="emoji_key_text" type="color">?attr/colorLabel</item>
|
||||
</style>
|
||||
<style name="Black">
|
||||
<item name="android:isLightTheme">false</item>
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
<item name="colorKeyboard">#000000</item>
|
||||
<item name="colorKey">#000000</item>
|
||||
<item name="colorKeyActivated">#333333</item>
|
||||
|
@@ -7,9 +7,13 @@
|
||||
<dimen name="key_vertical_interval">2dp</dimen>
|
||||
<dimen name="key_horizontal_interval">2dp</dimen>
|
||||
<dimen name="key_height">51dp</dimen>
|
||||
<dimen name="label_text_size">18dp</dimen>
|
||||
<dimen name="sublabel_text_size">12dp</dimen>
|
||||
<item name="label_text_size" type="integer" format="float">0.33</item>
|
||||
<item name="sublabel_text_size" type="integer" format="float">0.22</item>
|
||||
<dimen name="emoji_type_button_height">56dp</dimen>
|
||||
<dimen name="emoji_grid_height">250dp</dimen>
|
||||
<dimen name="emoji_text_size">28dp</dimen>
|
||||
<dimen name="extra_horizontal_margin">0dp</dimen>
|
||||
<bool name="debug_logs" product="debug">true</bool>
|
||||
<bool name="debug_logs" product="default">false</bool>
|
||||
<dimen name="pointer_too_close">10dp</dimen>
|
||||
</resources>
|
@@ -34,11 +34,4 @@
|
||||
<key key0="n" key1="accent_tilde" key2="§" key4="!"/>
|
||||
<key width="2.0" key0="backspace" key2="delete"/>
|
||||
</row>
|
||||
<row height="0.95">
|
||||
<key width="1.8" key0="ctrl" key3="switch_numeric"/>
|
||||
<key width="1.2" key0="alt" key1="fn" key2="change_method" key3="switch_emoji" key4="config"/>
|
||||
<key width="4.0" key0="space"/>
|
||||
<key width="1.2" key1="up" key2="right" key3="left" key4="down"/>
|
||||
<key width="1.8" key0="enter" key2="action"/>
|
||||
</row>
|
||||
</keyboard>
|
||||
|
8
res/xml/bottom_row.xml
Normal file
8
res/xml/bottom_row.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<row height="0.95">
|
||||
<key width="1.8" key0="ctrl" key2="meta" key3="switch_numeric"/>
|
||||
<key width="1.2" key0="alt" key1="fn" key2="change_method" key3="switch_emoji" key4="config"/>
|
||||
<key width="4.0" key0="space"/>
|
||||
<key width="1.2" key1="up" key2="right" key3="left" key4="down" edgekeys="true"/>
|
||||
<key width="1.8" key0="enter" key2="action"/>
|
||||
</row>
|
37
res/xml/dvorak.xml
Normal file
37
res/xml/dvorak.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<keyboard>
|
||||
<row>
|
||||
<key key0="shift" width="1.5" key1="esc" key2="tab"/>
|
||||
<key key0="p" key1="accent_ring" key2="." key3="<"/>
|
||||
<key key0="y" key1="accent_grave" key2="," key3=">"/>
|
||||
<key key0="f" key4="€"/>
|
||||
<key key0="g" key2="\\" key3="|"/>
|
||||
<key key0="c" key1="accent_trema" key2="accent_circonflexe" key3="{" key4="}"/>
|
||||
<key key0="r" key3="[" key4="]"/>
|
||||
<key key0="l" key2="=" key3="+" key4="£"/>
|
||||
<key key0="backspace" key2="delete" width="1.5"/>
|
||||
</row>
|
||||
<row>
|
||||
<key key0="a" key2="1" key3="!"/>
|
||||
<key key0="o" key1="accent_macron" key2="2" key3="\@"/>
|
||||
<key key0="e" key1="accent_caron" key2="3" key3="\#"/>
|
||||
<key key0="u" key2="4" key3="$"/>
|
||||
<key key0="i" key2="5" key3="%"/>
|
||||
<key key0="d" key2="6" key3="^"/>
|
||||
<key key0="h" key2="7" key3="&"/>
|
||||
<key key0="t" key2="8" key3="*"/>
|
||||
<key key0="n" key2="9" key3="(" key4=")"/>
|
||||
<key key0="s" key2="0" key3="ß"/>
|
||||
</row>
|
||||
<row>
|
||||
<key key0="q" shift="0.5" key1="accent_tilde" key2="`" key3="~"/>
|
||||
<key key0="j" key1="accent_aigu" key2="'" key3="""/>
|
||||
<key key0="k" key2=";" key3=":"/>
|
||||
<key key0="x" key1="accent_cedille"/>
|
||||
<key key0="b"/>
|
||||
<key key0="m" key2="/" key3="\?"/>
|
||||
<key key0="w"/>
|
||||
<key key0="v"/>
|
||||
<key key0="z" key2="-" key3="_"/>
|
||||
</row>
|
||||
</keyboard>
|
37
res/xml/local_bgph1.xml
Normal file
37
res/xml/local_bgph1.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<keyboard>
|
||||
<row>
|
||||
<key key0="я" key1="esc" key2="1" key3="ч" key4="!"/>
|
||||
<key key0="в" key2="2" key3="\@"/>
|
||||
<key key0="е" key2="3" key3="\#" key4="№"/>
|
||||
<key key0="р" key2="4" key3="$"/>
|
||||
<key key0="т" key2="5" key3="%"/>
|
||||
<key key0="ъ" key2="6" key3="^" key4="€"/>
|
||||
<key key0="у" key2="7" key3="&" key4="§"/>
|
||||
<key key0="и" key2="8" key3="*"/>
|
||||
<key key0="о" key1="accent_macron" key2="9" key3="(" key4=")"/>
|
||||
<key key0="п" key2="0" key3="ш" key4="щ"/>
|
||||
</row>
|
||||
<row>
|
||||
<key shift="0.5" key0="а" key1="tab" key2="`"/>
|
||||
<key key0="с" key2="£"/>
|
||||
<key key0="д" key1="accent_grave" key3="accent_aigu"/>
|
||||
<key key0="ф"/>
|
||||
<key key0="г" key1="accent_caron" key2="-" key3="_"/>
|
||||
<key key0="х" key2="=" key3="+"/>
|
||||
<key key0="й" key1="accent_trema" key2="accent_circonflexe" key4="}" key3="{"/>
|
||||
<key key0="к" key3="[" key4="]"/>
|
||||
<key key0="л" key2="|" key3="\\" key4="ю"/>
|
||||
</row>
|
||||
<row>
|
||||
<key width="1.5" key0="shift"/>
|
||||
<key key0="з"/>
|
||||
<key key0="ь" key1="accent_ring" key3="ѝ"/>
|
||||
<key key0="ц" key1="accent_cedille" key2="<" key3="."/>
|
||||
<key key0="ж" key2=">" key3=","/>
|
||||
<key key0="б" key2="\?" key3="/"/>
|
||||
<key key0="н" key1="accent_tilde" key2=":" key3=";"/>
|
||||
<key key0="м" key2=""" key3="'"/>
|
||||
<key width="1.5" key0="backspace" key2="delete"/>
|
||||
</row>
|
||||
</keyboard>
|
43
res/xml/local_ru_jcuken.xml
Normal file
43
res/xml/local_ru_jcuken.xml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<keyboard>
|
||||
<row>
|
||||
<key key0="й" key1="esc" key2="1" key3="~" key4="!"/>
|
||||
<key key0="ц" key2="2" key3="\@"/>
|
||||
<key key0="у" key2="3" key3="\#"/>
|
||||
<key key0="к" key2="4" key3="$"/>
|
||||
<key key0="е" key1="ё" key2="5" key3="%"/>
|
||||
<key key0="н" key2="6" key3="^"/>
|
||||
<key key0="г" key2="7" key3="&"/>
|
||||
<key key0="ш" key2="8" key3="*"/>
|
||||
<key key0="щ" key2="9" key3="(" key4=")"/>
|
||||
<key key0="з" key2="0"/>
|
||||
<key key0="х" key1="{" key2="}"/>
|
||||
<key key0="ъ" key1="[" key2="]" />
|
||||
</row>
|
||||
<row>
|
||||
<key shift="0.5" key0="ф" key1="tab" key2="`"/>
|
||||
<key key0="ы"/>
|
||||
<key key0="в"/>
|
||||
<key key0="а"/>
|
||||
<key key0="п"/>
|
||||
<key key0="р"/>
|
||||
<key key0="о"/>
|
||||
<key key0="л"/>
|
||||
<key key0="д" key2="-" key3="_"/>
|
||||
<key key0="ж" key2="=" key3="+"/>
|
||||
<key key0="э" key2="|" key3="\\"/>
|
||||
</row>
|
||||
<row>
|
||||
<key width="1.5" key0="shift"/>
|
||||
<key key0="я"/>
|
||||
<key key0="ч"/>
|
||||
<key key0="с"/>
|
||||
<key key0="м"/>
|
||||
<key key0="и" key2="<" key3="."/>
|
||||
<key key0="т" key2=">" key3=","/>
|
||||
<key key0="ь" key2="\?" key3="/"/>
|
||||
<key key0="б" key2=":" key3=";"/>
|
||||
<key key0="ю" key2=""" key3="'"/>
|
||||
<key width="1.5" key0="backspace" key2="delete"/>
|
||||
</row>
|
||||
</keyboard>
|
@@ -1,9 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="juloo.keyboard2.SettingsActivity" android:supportsSwitchingToNextInputMethod="true">
|
||||
<subtype android:label="%s" android:languageTag="en" android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty"/>
|
||||
<subtype android:label="%s" android:languageTag="fr" android:imeSubtypeLocale="fr_FR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=azerty,extra_keys=grave|aigu|circonflexe|cedille|trema"/>
|
||||
<subtype android:label="%s" android:languageTag="es" android:imeSubtypeLocale="es_ES" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=aigu|tilde|trema"/>
|
||||
<subtype android:label="%s" android:languageTag="de" android:imeSubtypeLocale="de_DE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwertz,extra_keys=trema|szlig"/>
|
||||
<subtype android:label="%s" android:languageTag="it" android:imeSubtypeLocale="it_IT" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=grave|aigu"/>
|
||||
<subtype android:label="%s" android:languageTag="sv" android:imeSubtypeLocale="sv_SE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=aigu|trema|ring"/>
|
||||
<subtype android:label="%s" android:languageTag="bg" android:imeSubtypeLocale="bg_BG" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=bgph1,extra_keys=€"/>
|
||||
<subtype android:label="%s" android:languageTag="de" android:imeSubtypeLocale="de_DE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwertz,extra_keys=accent_trema|ß|€"/>
|
||||
<subtype android:label="%s" android:languageTag="en-GB" android:imeSubtypeLocale="en_GB" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=£|€"/>
|
||||
<subtype android:label="%s" android:languageTag="en-US" android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty"/>
|
||||
<subtype android:label="%s" android:languageTag="es" android:imeSubtypeLocale="es_ES" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty_es,extra_keys=accent_grave|accent_aigu|accent_tilde|accent_trema|€"/>
|
||||
<subtype android:label="%s" android:languageTag="fr" android:imeSubtypeLocale="fr_FR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=azerty,extra_keys=accent_grave|accent_aigu|accent_circonflexe|accent_cedille|accent_trema|€"/>
|
||||
<subtype android:label="%s" android:languageTag="it" android:imeSubtypeLocale="it_IT" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=accent_grave|accent_aigu|€"/>
|
||||
<subtype android:label="%s" android:languageTag="lv" android:imeSubtypeLocale="lv_LV" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty_lv,extra_keys=accent_caron|accent_cedille|accent_macron|€"/>
|
||||
<subtype android:label="%s" android:languageTag="pt" android:imeSubtypeLocale="pt_BR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty_pt,extra_keys=accent_aigu|accent_cedille|accent_circonflexe|accent_grave|accent_tilde|€"/>
|
||||
<subtype android:label="%s" android:languageTag="ru" android:imeSubtypeLocale="ru_RU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=ru_jcuken"/>
|
||||
<subtype android:label="%s" android:languageTag="sv" android:imeSubtypeLocale="sv_SE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty_sv_se,extra_keys=accent_aigu|accent_trema|accent_ring|€"/>
|
||||
</input-method>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<keyboard>
|
||||
<keyboard bottom_row="false">
|
||||
<row>
|
||||
<key width="0.75" key0="esc" key2="~" key4="!"/>
|
||||
<key width="0.75" key0="(" key2="[" key4="{"/>
|
||||
@@ -13,14 +13,14 @@
|
||||
<key width="0.75" key0="tab" key1=";" key2="|" key4="\\"/>
|
||||
<key width="0.75" key0=")" key2="]" key4="}"/>
|
||||
<key key0="4"/>
|
||||
<key key0="5" key1="up" key2="right" key3="left" key4="down"/>
|
||||
<key key0="5" key1="up" key2="right" key3="left" key4="down" edgekeys="true"/>
|
||||
<key key0="6"/>
|
||||
<key width="0.75" key0="+" key1="Σ" key2="$"/>
|
||||
<key width="0.75" key0="-" key2="^"/>
|
||||
</row>
|
||||
<row>
|
||||
<key shift="0.35" width="1.15" key0="shift" key2="fn" key4="alt"/>
|
||||
<key key0="1" key1="superscript" key3="subscript"/>
|
||||
<key key0="1" key1="superscript" key2="ordinal" key3="subscript"/>
|
||||
<key key0="2"/>
|
||||
<key key0="3"/>
|
||||
<key width="1.15" key0="backspace" key2="delete"/>
|
||||
@@ -28,7 +28,7 @@
|
||||
<row height="0.95">
|
||||
<key width="1.5" key0="ctrl" key3="switch_text"/>
|
||||
<key width="1.5" key0="0"/>
|
||||
<key width="0.75" key0="." key2=","/>
|
||||
<key width="0.75" key0="." key1=":" key2=","/>
|
||||
<key width="0.75" key0="space" key1=""" key2="'" key4="_"/>
|
||||
<key width="1.5" key0="enter" key1="±" key2="action" key3="="/>
|
||||
</row>
|
||||
|
@@ -3,24 +3,24 @@
|
||||
<row>
|
||||
<key key0="q" key1="esc" key2="1" key3="~" key4="!"/>
|
||||
<key key0="w" key2="2" key3="\@"/>
|
||||
<key key0="e" key2="3" key3="\#"/>
|
||||
<key key0="e" key2="3" key3="\#" key4="€"/>
|
||||
<key key0="r" key2="4" key3="$"/>
|
||||
<key key0="t" key2="5" key3="%"/>
|
||||
<key key0="y" key2="6" key3="^"/>
|
||||
<key key0="u" key2="7" key3="&"/>
|
||||
<key key0="i" key2="8" key3="*"/>
|
||||
<key key0="o" key2="9" key3="(" key4=")"/>
|
||||
<key key0="o" key1="accent_macron" key2="9" key3="(" key4=")"/>
|
||||
<key key0="p" key2="0"/>
|
||||
</row>
|
||||
<row>
|
||||
<key shift="0.5" key0="a" key1="tab" key2="`"/>
|
||||
<key key0="s" key1="accent_ring" key3="ß"/>
|
||||
<key key0="d" key1="accent_grave" key3="accent_aigu"/>
|
||||
<key key0="d" key1="accent_grave" key2="£" key3="accent_aigu"/>
|
||||
<key key0="f"/>
|
||||
<key key0="g" key2="-" key3="_"/>
|
||||
<key key0="g" key1="accent_caron" key2="-" key3="_"/>
|
||||
<key key0="h" key2="=" key3="+"/>
|
||||
<key key0="j" key1="accent_trema" key2="accent_circonflexe" key4="}" key3="{"/>
|
||||
<key key0="k" key4="]" key3="["/>
|
||||
<key key0="k" key3="[" key4="]"/>
|
||||
<key key0="l" key2="|" key3="\\"/>
|
||||
</row>
|
||||
<row>
|
||||
@@ -34,11 +34,4 @@
|
||||
<key key0="m" key2=""" key3="'"/>
|
||||
<key width="1.5" key0="backspace" key2="delete"/>
|
||||
</row>
|
||||
<row height="0.95">
|
||||
<key width="1.8" key0="ctrl" key3="switch_numeric"/>
|
||||
<key width="1.2" key0="alt" key1="fn" key2="change_method" key3="switch_emoji" key4="config"/>
|
||||
<key width="4.0" key0="space"/>
|
||||
<key width="1.2" key1="up" key2="right" key3="left" key4="down"/>
|
||||
<key width="1.8" key0="enter" key2="action"/>
|
||||
</row>
|
||||
</keyboard>
|
||||
|
38
res/xml/qwerty_es.xml
Normal file
38
res/xml/qwerty_es.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<keyboard>
|
||||
<row>
|
||||
<key key0="q" key1="esc" key2="1" key3="~" key4="!"/>
|
||||
<key key0="w" key2="2" key3="\@"/>
|
||||
<key key0="e" key2="3" key3="\#" key4="€"/>
|
||||
<key key0="r" key2="4" key3="$"/>
|
||||
<key key0="t" key2="5" key3="%"/>
|
||||
<key key0="y" key2="6" key3="^"/>
|
||||
<key key0="u" key2="7" key3="&"/>
|
||||
<key key0="i" key2="8" key3="*"/>
|
||||
<key key0="o" key2="9" key3="(" key4=")"/>
|
||||
<key key0="p" key2="0"/>
|
||||
</row>
|
||||
<row>
|
||||
<key key0="a" key2="`" key3="tab" key4="¡"/>
|
||||
<key key0="s" key1="accent_ring" key3="ß"/>
|
||||
<key key0="d" key1="accent_grave" key2="£" key3="accent_aigu"/>
|
||||
<key key0="f"/>
|
||||
<key key0="g" key1="accent_caron" key2="-" key3="_"/>
|
||||
<key key0="h" key2="=" key3="+"/>
|
||||
<key key0="j" key1="accent_trema" key2="accent_circonflexe" key4="}" key3="{"/>
|
||||
<key key0="k" key3="[" key4="]"/>
|
||||
<key key0="l" key2="|" key3="\\"/>
|
||||
<key key0="ñ"/>
|
||||
</row>
|
||||
<row>
|
||||
<key width="1.5" key0="shift"/>
|
||||
<key key0="z"/>
|
||||
<key key0="x"/>
|
||||
<key key0="c" key1="accent_cedille" key2="<" key3="."/>
|
||||
<key key0="v" key2=">" key3=","/>
|
||||
<key key0="b" key2="\?" key3="/" key4="¿"/>
|
||||
<key key0="n" key1="accent_tilde" key2=":" key3=";"/>
|
||||
<key key0="m" key2=""" key3="'"/>
|
||||
<key width="1.5" key0="backspace" key2="delete"/>
|
||||
</row>
|
||||
</keyboard>
|
37
res/xml/qwerty_lv.xml
Normal file
37
res/xml/qwerty_lv.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<keyboard>
|
||||
<row>
|
||||
<key key0="q" key1="esc" key2="1" key3="~" key4="!"/>
|
||||
<key key0="w" key2="2" key3="\@"/>
|
||||
<key key0="e" key1="ē" key2="3" key3="\#" key4="€"/>
|
||||
<key key0="r" key1="ŗ" key2="4" key3="$"/>
|
||||
<key key0="t" key2="5" key3="%"/>
|
||||
<key key0="y" key2="6" key3="^"/>
|
||||
<key key0="u" key1="ū" key2="7" key3="&"/>
|
||||
<key key0="i" key1="ī" key2="8" key3="*"/>
|
||||
<key key0="o" key1="ō" key2="9" key3="(" key4=")"/>
|
||||
<key key0="p" key2="0" key3="{" key4="}"/>
|
||||
</row>
|
||||
<row>
|
||||
<key shift="0.5" key0="a" key1="ā"/>
|
||||
<key key0="s" key1="š" key3="ß"/>
|
||||
<key key0="d" key2="£"/>
|
||||
<key key0="f"/>
|
||||
<key key0="g" key1="ģ"/>
|
||||
<key key0="h" key2="accent_macron" key3="accent_caron" key4="accent_cedille"/>
|
||||
<key key0="j" key1="+" key2="=" key3="-" key4="_"/>
|
||||
<key key0="k" key1="ķ" key3="[" key4="]"/>
|
||||
<key key0="l" key1="ļ" key2="|" key3="/" key4="\\"/>
|
||||
</row>
|
||||
<row>
|
||||
<key width="1.5" key0="shift" key1="tab"/>
|
||||
<key key0="z" key1="ž"/>
|
||||
<key key0="x"/>
|
||||
<key key0="c" key1="č"/>
|
||||
<key key0="v"/>
|
||||
<key key0="b" key2="\?" key3="<" key4=">"/>
|
||||
<key key0="n" key1="ņ" key2="`" key3=":" key4=";"/>
|
||||
<key key0="m" key1="'" key2=""" key3="," key4="."/>
|
||||
<key width="1.5" key0="backspace" key2="delete"/>
|
||||
</row>
|
||||
</keyboard>
|
38
res/xml/qwerty_pt.xml
Normal file
38
res/xml/qwerty_pt.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<keyboard>
|
||||
<row>
|
||||
<key key0="q" key1="esc" key2="1" key3="~" key4="!"/>
|
||||
<key key0="w" key2="2" key3="\@"/>
|
||||
<key key0="e" key1="£" key2="3" key3="\#" key4="€"/>
|
||||
<key key0="r" key2="4" key3="$"/>
|
||||
<key key0="t" key2="5" key3="%"/>
|
||||
<key key0="y" key1="accent_caron" key2="6" key3="^" key4="accent_trema"/>
|
||||
<key key0="u" key2="7" key3="&"/>
|
||||
<key key0="i" key2="8" key3="*"/>
|
||||
<key key0="o" key2="9" key3="(" key4=")"/>
|
||||
<key key0="p" key2="0" key3="\\" key4="|"/>
|
||||
</row>
|
||||
<row>
|
||||
<key key0="a" key1="tab" key2="'" key3="`" key4="""/>
|
||||
<key key0="s" key1="accent_ring" key2="accent_caron" key3="ß" key4="accent_cedille"/>
|
||||
<key key0="d"/>
|
||||
<key key0="f"/>
|
||||
<key key0="g"/>
|
||||
<key key0="h"/>
|
||||
<key key0="j" key1="-" key2="=" key4="+" key3="_"/>
|
||||
<key key0="k" key1="accent_grave" key2="accent_aigu" key3="accent_tilde" key4="accent_circonflexe"/>
|
||||
<key key0="l" key1="[" key2="]" key3="{" key4="}"/>
|
||||
<key key0="ç"/>
|
||||
</row>
|
||||
<row>
|
||||
<key width="1.5" key0="shift"/>
|
||||
<key key0="z"/>
|
||||
<key key0="x"/>
|
||||
<key key0="c"/>
|
||||
<key key0="v"/>
|
||||
<key key0="b"/>
|
||||
<key key0="n" key1="<" key2=">" key3="," key4="."/>
|
||||
<key key0="m" key1=":" key2=";" key3="/" key4="\?"/>
|
||||
<key width="1.5" key0="backspace" key2="delete"/>
|
||||
</row>
|
||||
</keyboard>
|
42
res/xml/qwerty_sv_se.xml
Normal file
42
res/xml/qwerty_sv_se.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<keyboard>
|
||||
<row>
|
||||
<key key0="q" key1="esc" key2="1"/>
|
||||
<key key0="w" key2="2" key4="\@"/>
|
||||
<key key0="e" key2="3" key4="\#" key3="€"/>
|
||||
<key key0="r" key2="4" key4="$"/>
|
||||
<key key0="t" key2="5" key3="&" key4="|" />
|
||||
<key key0="y" key2="6" key3="^" key4="%"/>
|
||||
<key key0="u" key2="7" key3="~" key4="\\" />
|
||||
<key key0="i" key2="8" key3="*" key4="/" />
|
||||
<key key0="o" key2="9" key3="+" key4="-"/>
|
||||
<key key0="p" key2="0" key3="=" />
|
||||
<key key0="å" key1="\?" key3="!" key2="`" />
|
||||
</row>
|
||||
<row>
|
||||
<key key0="a" key1="tab" />
|
||||
<key key0="s" key1="accent_ring" key2="accent_cedille" key3="ß" key4="accent_tilde"/>
|
||||
<key key0="d" key1="accent_grave" key2="accent_caron" key3="accent_aigu"/>
|
||||
<key key0="f" key1="accent_trema" key2="accent_circonflexe"/>
|
||||
<key key0="g" />
|
||||
<key key0="h" />
|
||||
<key key0="j" key1="{" key4="}" />
|
||||
<key key0="k" key1="[" key4="]" />
|
||||
<key key0="l" key1="(" key4=")" />
|
||||
<key key0="ö" key1="<" key4=">" />
|
||||
<key key0="ä" key1="'" key3="""/>
|
||||
|
||||
</row>
|
||||
<row>
|
||||
<key width="1.5" key0="shift"/>
|
||||
<key key0="z" />
|
||||
<key key0="x" />
|
||||
<key key0="c" />
|
||||
<key key0="v" />
|
||||
<key key0="b" key2=";" key4=","/>
|
||||
<key key0="n" key2=":" key4="."/>
|
||||
<key key0="m" key2="-" key4="_"/>
|
||||
<key width="1.0" key0="." key1="!" key2="\?" key3="'" key4="," />
|
||||
<key width="1.5" key0="backspace" key2="delete"/>
|
||||
</row>
|
||||
</keyboard>
|
@@ -7,19 +7,19 @@
|
||||
<key key0="r" key2="4" key3="$"/>
|
||||
<key key0="t" key2="5" key3="%"/>
|
||||
<key key0="z" key2="6" key3="&" key4="{"/>
|
||||
<key key0="u" key2="7" key4="}"/>
|
||||
<key key0="u" key2="7" key3="ü" key4="}"/>
|
||||
<key key0="i" key1="(" key2="8" key4="["/>
|
||||
<key key0="o" key1=")" key2="9" key4="]"/>
|
||||
<key key0="p" key1="=" key2="0" key4="\?"/>
|
||||
<key key0="o" key1=")" key2="9" key3="ö" key4="]"/>
|
||||
<key key0="p" key1="=" key2="0" key3="\?"/>
|
||||
</row>
|
||||
<row>
|
||||
<key shift="0.5" key0="a" key1="tab" key2="`"/>
|
||||
<key shift="0.5" key0="a" key1="tab" key2="`" key3="ä"/>
|
||||
<key key0="s" key3="ß"/>
|
||||
<key key0="d" key1="accent_grave" key2="accent_aigu" key3="accent_ring"/>
|
||||
<key key0="d" key2="£"/>
|
||||
<key key0="f" key1="~"/>
|
||||
<key key0="g" key3="-"/>
|
||||
<key key0="h" key3="+"/>
|
||||
<key key0="j" key1="accent_trema" key2="accent_circonflexe" key3="*"/>
|
||||
<key key0="j" key3="*"/>
|
||||
<key key0="k" key3="/" key4="\\"/>
|
||||
<key key0="l" key1="'" key3="\#"/>
|
||||
</row>
|
||||
@@ -27,18 +27,11 @@
|
||||
<key width="1.5" key0="shift"/>
|
||||
<key key0="y" key1=">" key2="|" key3="<"/>
|
||||
<key key0="x"/>
|
||||
<key key0="c" key1="accent_cedille"/>
|
||||
<key key0="c"/>
|
||||
<key key0="v" />
|
||||
<key key0="b" key1=";" key3=","/>
|
||||
<key key0="n" key1=":" key3="." key4="accent_tilde"/>
|
||||
<key key0="n" key1=":" key3="."/>
|
||||
<key key0="m" key1="_" />
|
||||
<key width="1.5" key0="backspace" key2="delete"/>
|
||||
</row>
|
||||
<row height="0.95">
|
||||
<key width="1.8" key0="ctrl" key3="switch_numeric"/>
|
||||
<key width="1.2" key0="alt" key1="fn" key2="change_method" key3="switch_emoji" key4="config"/>
|
||||
<key width="4.0" key0="space"/>
|
||||
<key width="1.2" key1="up" key2="right" key3="left" key4="down"/>
|
||||
<key width="1.8" key0="enter"/>
|
||||
</row>
|
||||
</keyboard>
|
||||
|
@@ -9,16 +9,27 @@
|
||||
<juloo.common.IntSlideBarPreference android:key="longpress_timeout" android:title="@string/pref_long_timeout_title" android:summary="%sms" android:defaultValue="600" min="50" max="2000"/>
|
||||
<juloo.common.IntSlideBarPreference android:key="longpress_interval" android:title="@string/pref_long_interval_title" android:summary="%sms" android:defaultValue="25" min="5" max="100"/>
|
||||
<CheckBoxPreference android:key="precise_repeat" android:title="@string/pref_precise_repeat_title" android:summary="@string/pref_precise_repeat_summary" android:defaultValue="true"/>
|
||||
<PreferenceScreen android:title="@string/pref_lockable_keys_title" android:summary="@string/pref_lockable_keys_summary">
|
||||
<CheckBoxPreference android:key="lockable_shift" android:title="Shift" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:key="lockable_ctrl" android:title="Ctrl" android:defaultValue="false"/>
|
||||
<CheckBoxPreference android:key="lockable_alt" android:title="Alt" android:defaultValue="false"/>
|
||||
<CheckBoxPreference android:key="lockable_fn" android:title="Fn" android:defaultValue="false"/>
|
||||
<CheckBoxPreference android:key="lockable_meta" android:title="Meta" android:defaultValue="false"/>
|
||||
<CheckBoxPreference android:key="lockable_sup" android:title="Sup" android:defaultValue="false"/>
|
||||
<CheckBoxPreference android:key="lockable_sub" android:title="Sub" android:defaultValue="false"/>
|
||||
</PreferenceScreen>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/pref_category_vibrate">
|
||||
<CheckBoxPreference android:key="vibrate_enabled" android:title="@string/pref_vibrate_title" android:summary="@string/pref_vibrate_summary" android:defaultValue="true"/>
|
||||
<juloo.common.IntSlideBarPreference android:key="vibrate_duration" android:title="@string/pref_vibrate_duration_title" android:summary="%sms" android:defaultValue="20" min="5" max="50"/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/pref_category_style">
|
||||
<ListPreference android:key="theme" android:title="@string/pref_theme" android:summary="%s" android:defaultValue="dark" android:entries="@array/pref_theme_entries" android:entryValues="@array/pref_theme_values"/>
|
||||
<ListPreference android:key="theme" android:title="@string/pref_theme" android:summary="%s" android:defaultValue="system" android:entries="@array/pref_theme_entries" android:entryValues="@array/pref_theme_values"/>
|
||||
<juloo.common.IntSlideBarPreference android:key="margin_bottom" android:title="@string/pref_margin_bottom_title" android:summary="%sdp" android:defaultValue="5" min="0" max="100"/>
|
||||
<juloo.common.IntSlideBarPreference android:key="key_height" android:title="@string/pref_key_height_title" android:summary="%sdp" android:defaultValue="50" min="30" max="90"/>
|
||||
<juloo.common.IntSlideBarPreference android:key="keyboard_height" android:title="@string/pref_keyboard_height_title" android:summary="%s%%" android:defaultValue="35" min="25" max="50"/>
|
||||
<juloo.common.IntSlideBarPreference android:key="horizontal_margin" android:title="@string/pref_horizontal_margin_title" android:summary="%sdp" android:defaultValue="3" min="0" max="20"/>
|
||||
<juloo.common.SlideBarPreference android:key="character_size" android:title="@string/pref_character_size_title" android:summary="@string/pref_character_size_summary" android:defaultValue="1.0" min="0.8" max="1.2"/>
|
||||
<juloo.common.IntSlideBarPreference android:key="key_vertical_space" android:title="@string/pref_key_vertical_space" android:summary="%sdp" android:defaultValue="2" min="0" max="8"/>
|
||||
<juloo.common.IntSlideBarPreference android:key="key_horizontal_space" android:title="@string/pref_key_horizontal_space" android:summary="%sdp" android:defaultValue="2" min="0" max="8"/>
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
|
10
shell.nix
10
shell.nix
@@ -12,12 +12,8 @@ let
|
||||
abiVersions = [ "armeabi-v7a" ];
|
||||
};
|
||||
|
||||
apksigner = pkgs.apksigner.override {
|
||||
inherit (jdk) jre;
|
||||
inherit (android) build-tools;
|
||||
};
|
||||
|
||||
in pkgs.mkShell {
|
||||
buildInputs = [ pkgs.findutils jdk android.androidsdk apksigner ];
|
||||
in
|
||||
pkgs.mkShell {
|
||||
buildInputs = [ pkgs.findutils jdk android.androidsdk ];
|
||||
ANDROID_HOME = "${android.androidsdk}/libexec/android-sdk";
|
||||
}
|
||||
|
@@ -2,18 +2,25 @@ package juloo.keyboard2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.KeyEvent;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
final class Config
|
||||
{
|
||||
// From resources
|
||||
public final float marginTop;
|
||||
public final float keyPadding;
|
||||
public final float keyVerticalInterval;
|
||||
public final float keyHorizontalInterval;
|
||||
public final float labelTextSize;
|
||||
public final float sublabelTextSize;
|
||||
/** Presses within this radius of an other pointer are ignored */
|
||||
public final float pointerTooClose;
|
||||
|
||||
// From preferences
|
||||
public int layout; // Or '-1' for the system defaults
|
||||
@@ -26,17 +33,20 @@ final class Config
|
||||
public float marginBottom;
|
||||
public float keyHeight;
|
||||
public float horizontalMargin;
|
||||
public float keyVerticalInterval;
|
||||
public float keyHorizontalInterval;
|
||||
public boolean preciseRepeat;
|
||||
public int lockable_modifiers;
|
||||
public float characterSize; // Ratio
|
||||
public int accents; // Values are R.values.pref_accents_v_*
|
||||
public int theme; // Values are R.style.*
|
||||
|
||||
// Dynamically set
|
||||
public boolean shouldOfferSwitchingToNextInputMethod;
|
||||
public int key_flags_to_remove;
|
||||
public String actionLabel; // Might be 'null'
|
||||
public int actionId; // Meaningful only when 'actionLabel' isn't 'null'
|
||||
public boolean swapEnterActionKey; // Swap the "enter" and "action" keys
|
||||
public Set<String> extra_keys; // 'null' means all the keys
|
||||
|
||||
public final IKeyEventHandler handler;
|
||||
|
||||
@@ -46,8 +56,9 @@ final class Config
|
||||
// static values
|
||||
marginTop = res.getDimension(R.dimen.margin_top);
|
||||
keyPadding = res.getDimension(R.dimen.key_padding);
|
||||
keyVerticalInterval = res.getDimension(R.dimen.key_vertical_interval);
|
||||
keyHorizontalInterval = res.getDimension(R.dimen.key_horizontal_interval);
|
||||
labelTextSize = res.getFloat(R.integer.label_text_size);
|
||||
sublabelTextSize = res.getFloat(R.integer.sublabel_text_size);
|
||||
pointerTooClose = res.getDimension(R.dimen.pointer_too_close);
|
||||
// default values
|
||||
layout = -1;
|
||||
vibrateEnabled = true;
|
||||
@@ -57,6 +68,8 @@ final class Config
|
||||
marginBottom = res.getDimension(R.dimen.margin_bottom);
|
||||
keyHeight = res.getDimension(R.dimen.key_height);
|
||||
horizontalMargin = res.getDimension(R.dimen.horizontal_margin);
|
||||
keyVerticalInterval = res.getDimension(R.dimen.key_vertical_interval);
|
||||
keyHorizontalInterval = res.getDimension(R.dimen.key_horizontal_interval);
|
||||
preciseRepeat = true;
|
||||
characterSize = 1.f;
|
||||
accents = 1;
|
||||
@@ -64,10 +77,10 @@ final class Config
|
||||
refresh(context);
|
||||
// initialized later
|
||||
shouldOfferSwitchingToNextInputMethod = false;
|
||||
key_flags_to_remove = 0;
|
||||
actionLabel = null;
|
||||
actionId = 0;
|
||||
swapEnterActionKey = false;
|
||||
extra_keys = null;
|
||||
handler = h;
|
||||
}
|
||||
|
||||
@@ -77,8 +90,21 @@ final class Config
|
||||
public void refresh(Context context)
|
||||
{
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
layout = layoutId_of_string(prefs.getString("layout", "system"));
|
||||
Resources res = context.getResources();
|
||||
DisplayMetrics dm = res.getDisplayMetrics();
|
||||
// The height of the keyboard is relative to the height of the screen. This
|
||||
// is not the actual size of the keyboard, which will be bigger if the
|
||||
// layout has a fifth row.
|
||||
int keyboardHeightPercent;
|
||||
if (res.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) // Landscape mode
|
||||
{
|
||||
keyboardHeightPercent = 55;
|
||||
}
|
||||
else
|
||||
{
|
||||
keyboardHeightPercent = prefs.getInt("keyboard_height", 35);
|
||||
}
|
||||
layout = layoutId_of_string(prefs.getString("layout", "system"));
|
||||
swipe_dist_dp = Float.valueOf(prefs.getString("swipe_dist", "15"));
|
||||
swipe_dist_px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, swipe_dist_dp, dm);
|
||||
vibrateEnabled = prefs.getBoolean("vibrate_enabled", vibrateEnabled);
|
||||
@@ -86,52 +112,110 @@ final class Config
|
||||
longPressTimeout = prefs.getInt("longpress_timeout", (int)longPressTimeout);
|
||||
longPressInterval = prefs.getInt("longpress_interval", (int)longPressInterval);
|
||||
marginBottom = getDipPref(dm, prefs, "margin_bottom", marginBottom);
|
||||
// Add keyVerticalInterval to keyHeight because the space between the keys
|
||||
// is removed from the keys during rendering
|
||||
keyHeight = getDipPref(dm, prefs, "key_height", keyHeight) + keyVerticalInterval;
|
||||
horizontalMargin = getDipPref(dm, prefs, "horizontal_margin", horizontalMargin);
|
||||
keyVerticalInterval = getDipPref(dm, prefs, "key_vertical_space", keyVerticalInterval);
|
||||
keyHorizontalInterval = getDipPref(dm, prefs, "key_horizontal_space", keyHorizontalInterval);
|
||||
// Do not substract keyVerticalInterval from keyHeight because this is done
|
||||
// during rendered.
|
||||
keyHeight = dm.heightPixels * keyboardHeightPercent / 100 / 4;
|
||||
horizontalMargin = getDipPref(dm, prefs, "horizontal_margin", horizontalMargin) + res.getDimension(R.dimen.extra_horizontal_margin);
|
||||
preciseRepeat = prefs.getBoolean("precise_repeat", preciseRepeat);
|
||||
characterSize = prefs.getFloat("character_size", characterSize);
|
||||
lockable_modifiers =
|
||||
(prefs.getBoolean("lockable_shift", true) ? KeyValue.FLAG_SHIFT : 0)
|
||||
| (prefs.getBoolean("lockable_ctrl", false) ? KeyValue.FLAG_CTRL : 0)
|
||||
| (prefs.getBoolean("lockable_alt", false) ? KeyValue.FLAG_ALT : 0)
|
||||
| (prefs.getBoolean("lockable_fn", false) ? KeyValue.FLAG_FN : 0)
|
||||
| (prefs.getBoolean("lockable_meta", false) ? KeyValue.FLAG_META : 0)
|
||||
| (prefs.getBoolean("lockable_sup", false) ? KeyValue.FLAG_ACCENT_SUPERSCRIPT : 0)
|
||||
| (prefs.getBoolean("lockable_sub", false) ? KeyValue.FLAG_ACCENT_SUBSCRIPT : 0);
|
||||
characterSize = prefs.getFloat("character_size", characterSize);
|
||||
accents = Integer.valueOf(prefs.getString("accents", "1"));
|
||||
theme = themeId_of_string(prefs.getString("theme", ""));
|
||||
theme = getThemeId(res, prefs.getString("theme", ""));
|
||||
}
|
||||
|
||||
/** Update the layout according to the configuration.
|
||||
* - Remove the switching key if it isn't needed
|
||||
* - Remove keys from other locales (not in 'extra_keys')
|
||||
* - Replace the action key to show the right label
|
||||
* - Swap the enter and action keys
|
||||
*/
|
||||
public KeyboardData modify_layout(KeyboardData kw)
|
||||
{
|
||||
// Update the name to avoid caching in KeyModifier
|
||||
KeyValue action_key = (actionLabel == null) ? null :
|
||||
KeyValue.getKeyByName("action").withNameAndSymbol(actionLabel, actionLabel);
|
||||
return kw.replaceKeys(key -> {
|
||||
if (key == null)
|
||||
return null;
|
||||
switch (key.eventCode)
|
||||
{
|
||||
case KeyValue.EVENT_CHANGE_METHOD:
|
||||
return shouldOfferSwitchingToNextInputMethod ? key : null;
|
||||
case KeyEvent.KEYCODE_ENTER:
|
||||
return (swapEnterActionKey && action_key != null) ? action_key : key;
|
||||
case KeyValue.EVENT_ACTION:
|
||||
return (swapEnterActionKey && action_key != null) ?
|
||||
KeyValue.getKeyByName("enter") : action_key;
|
||||
default:
|
||||
if (key.flags != 0)
|
||||
{
|
||||
if ((key.flags & KeyValue.FLAG_LOCALIZED) != 0 &&
|
||||
extra_keys != null &&
|
||||
!extra_keys.contains(key.name))
|
||||
return null;
|
||||
if ((key.flags & lockable_modifiers) != 0)
|
||||
return key.withFlags(key.flags | KeyValue.FLAG_LOCK);
|
||||
}
|
||||
return key;
|
||||
}});
|
||||
}
|
||||
|
||||
private float getDipPref(DisplayMetrics dm, SharedPreferences prefs, String pref_name, float def)
|
||||
{
|
||||
int value = prefs.getInt(pref_name, -1);
|
||||
if (value < 0)
|
||||
float value;
|
||||
try { value = prefs.getInt(pref_name, -1); }
|
||||
catch (Exception e) { value = prefs.getFloat(pref_name, -1f); }
|
||||
if (value < 0f)
|
||||
return (def);
|
||||
return (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, dm));
|
||||
}
|
||||
|
||||
private int getThemeId(Resources res, String theme_name)
|
||||
{
|
||||
switch (theme_name)
|
||||
{
|
||||
case "light": return R.style.Light;
|
||||
case "black": return R.style.Black;
|
||||
case "dark": return R.style.Dark;
|
||||
default:
|
||||
case "system":
|
||||
if (Build.VERSION.SDK_INT >= 8)
|
||||
{
|
||||
int night_mode = res.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||
if ((night_mode & Configuration.UI_MODE_NIGHT_NO) != 0)
|
||||
return R.style.Light;
|
||||
}
|
||||
return R.style.Dark;
|
||||
}
|
||||
}
|
||||
|
||||
public static int layoutId_of_string(String name)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "azerty": return R.xml.azerty;
|
||||
case "bgph1": return R.xml.local_bgph1;
|
||||
case "dvorak": return R.xml.dvorak;
|
||||
case "qwerty_es": return R.xml.qwerty_es;
|
||||
case "qwerty_lv": return R.xml.qwerty_lv;
|
||||
case "qwerty_pt": return R.xml.qwerty_pt;
|
||||
case "qwerty": return R.xml.qwerty;
|
||||
case "qwerty_sv_se": return R.xml.qwerty_sv_se;
|
||||
case "qwertz": return R.xml.qwertz;
|
||||
case "ru_jcuken": return R.xml.local_ru_jcuken;
|
||||
case "system": default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Used for the accents option. */
|
||||
public static int extra_key_flag_of_name(String name)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "grave": return KeyValue.FLAG_ACCENT1;
|
||||
case "aigu": return KeyValue.FLAG_ACCENT2;
|
||||
case "circonflexe": return KeyValue.FLAG_ACCENT3;
|
||||
case "tilde": return KeyValue.FLAG_ACCENT4;
|
||||
case "cedille": return KeyValue.FLAG_ACCENT5;
|
||||
case "trema": return KeyValue.FLAG_ACCENT6;
|
||||
case "ring": return KeyValue.FLAG_ACCENT_RING;
|
||||
case "szlig": return KeyValue.FLAG_LANG_SZLIG;
|
||||
default: throw new RuntimeException(name);
|
||||
}
|
||||
}
|
||||
|
||||
public static int themeId_of_string(String name)
|
||||
{
|
||||
switch (name)
|
||||
|
@@ -14,6 +14,8 @@ class KeyEventHandler implements Config.IKeyEventHandler
|
||||
public void handleKeyUp(KeyValue key, int flags)
|
||||
{
|
||||
key = KeyModifier.handleFlags(key, flags);
|
||||
if (key == null || (key.flags & KeyValue.FLAG_NOCHAR) != 0)
|
||||
return;
|
||||
switch (key.eventCode)
|
||||
{
|
||||
case KeyValue.EVENT_CONFIG: _recv.showKeyboardConfig(); return;
|
||||
@@ -24,12 +26,12 @@ class KeyEventHandler implements Config.IKeyEventHandler
|
||||
case KeyValue.EVENT_CHANGE_METHOD: _recv.switchToNextInputMethod(); return;
|
||||
case KeyValue.EVENT_ACTION: _recv.performAction(); return;
|
||||
default:
|
||||
if ((flags & (KeyValue.FLAG_CTRL | KeyValue.FLAG_ALT)) != 0)
|
||||
handleMetaKeyUp(key, flags);
|
||||
if ((flags & (KeyValue.FLAG_CTRL | KeyValue.FLAG_ALT | KeyValue.FLAG_META)) != 0)
|
||||
handleKeyUpWithModifier(key, flags);
|
||||
else if (key.char_ != KeyValue.CHAR_NONE)
|
||||
_recv.commitChar(key.char_);
|
||||
else if (key.eventCode != KeyValue.EVENT_NONE)
|
||||
handleMetaKeyUp(key, flags);
|
||||
handleKeyUpWithModifier(key, flags);
|
||||
else
|
||||
_recv.commitText(key.symbol);
|
||||
}
|
||||
@@ -45,20 +47,43 @@ class KeyEventHandler implements Config.IKeyEventHandler
|
||||
// getCurrentInputConnection().deleteSurroundingText(before, after);
|
||||
// }
|
||||
|
||||
private void handleMetaKeyUp(KeyValue key, int flags)
|
||||
private int sendMetaKey(int eventCode, int metaFlags, int metaState, boolean down)
|
||||
{
|
||||
int meta = 0;
|
||||
if (key.eventCode == KeyValue.EVENT_NONE)
|
||||
return ;
|
||||
if ((flags & KeyValue.FLAG_CTRL) != 0)
|
||||
meta |= KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON;
|
||||
if ((flags & KeyValue.FLAG_ALT) != 0)
|
||||
meta |= KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_ON;
|
||||
if ((flags & KeyValue.FLAG_SHIFT) != 0)
|
||||
meta |= KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON;
|
||||
_recv.sendKeyEvent(key.eventCode, meta);
|
||||
int action;
|
||||
int updatedMetaState;
|
||||
if (down) { action = KeyEvent.ACTION_DOWN; updatedMetaState = metaState | metaFlags; }
|
||||
else { action = KeyEvent.ACTION_UP; updatedMetaState = metaState & ~metaFlags; }
|
||||
_recv.sendKeyEvent(action, eventCode, metaState);
|
||||
return updatedMetaState;
|
||||
}
|
||||
|
||||
/* Send key events corresponding to pressed modifier keys. */
|
||||
private int sendMetaKeys(int flags, int metaState, boolean down)
|
||||
{
|
||||
if ((flags & KeyValue.FLAG_CTRL) != 0)
|
||||
metaState = sendMetaKey(KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON, metaState, down);
|
||||
if ((flags & KeyValue.FLAG_ALT) != 0)
|
||||
metaState = sendMetaKey(KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_ON, metaState, down);
|
||||
if ((flags & KeyValue.FLAG_SHIFT) != 0)
|
||||
metaState = sendMetaKey(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON, metaState, down);
|
||||
if ((flags & KeyValue.FLAG_META) != 0)
|
||||
metaState = sendMetaKey(KeyEvent.KEYCODE_META_LEFT, KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_ON, metaState, down);
|
||||
return metaState;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't set KeyEvent.FLAG_SOFT_KEYBOARD.
|
||||
*/
|
||||
private void handleKeyUpWithModifier(KeyValue key, int flags)
|
||||
{
|
||||
if (key.eventCode == KeyValue.EVENT_NONE)
|
||||
return ;
|
||||
int metaState = sendMetaKeys(flags, 0, true);
|
||||
_recv.sendKeyEvent(KeyEvent.ACTION_DOWN, key.eventCode, metaState);
|
||||
_recv.sendKeyEvent(KeyEvent.ACTION_UP, key.eventCode, metaState);
|
||||
sendMetaKeys(flags, metaState, false);
|
||||
}
|
||||
|
||||
public static interface IReceiver
|
||||
{
|
||||
public void switchToNextInputMethod();
|
||||
@@ -70,7 +95,7 @@ class KeyEventHandler implements Config.IKeyEventHandler
|
||||
/** 'res_id' is '-1' for the currently selected layout. */
|
||||
public void setLayout(int res_id);
|
||||
|
||||
public void sendKeyEvent(int eventCode, int meta);
|
||||
public void sendKeyEvent(int eventAction, int eventCode, int meta);
|
||||
|
||||
public void commitText(String text);
|
||||
public void commitChar(char c);
|
||||
|
@@ -14,7 +14,7 @@ class KeyModifier
|
||||
/* Modify a key according to modifiers. */
|
||||
public static KeyValue handleFlags(KeyValue k, int flags)
|
||||
{
|
||||
if (flags == 0) // No modifier
|
||||
if (k == null || flags == 0) // No modifier
|
||||
return k;
|
||||
SparseArray<KeyValue> ks = cacheEntry(k);
|
||||
KeyValue r = ks.get(flags);
|
||||
@@ -22,8 +22,10 @@ class KeyModifier
|
||||
return r;
|
||||
r = k;
|
||||
r = handleFn(r, flags);
|
||||
r = handleShift(r, flags);
|
||||
r = handleAccents(r, flags);
|
||||
if (r != null)
|
||||
r = handleShift(r, flags);
|
||||
if (r != null)
|
||||
r = handleAccents(r, flags);
|
||||
ks.put(flags, r);
|
||||
return r;
|
||||
}
|
||||
@@ -98,11 +100,38 @@ class KeyModifier
|
||||
case '-': return '÷';
|
||||
default: return (char)KeyCharacterMap.getDeadChar('\u00A8', c);
|
||||
}
|
||||
case KeyValue.FLAG_ACCENT_CARON:
|
||||
switch (c)
|
||||
{
|
||||
default: return (char)KeyCharacterMap.getDeadChar('\u02C7', c);
|
||||
}
|
||||
case KeyValue.FLAG_ACCENT_RING:
|
||||
switch (c)
|
||||
{
|
||||
default: return (char)KeyCharacterMap.getDeadChar('\u02DA', c);
|
||||
}
|
||||
case KeyValue.FLAG_ACCENT_MACRON:
|
||||
switch (c)
|
||||
{
|
||||
default: return (char)KeyCharacterMap.getDeadChar('\u00AF', c);
|
||||
}
|
||||
case KeyValue.FLAG_ACCENT_ORDINAL:
|
||||
switch (c)
|
||||
{
|
||||
case 'a': return 'ª';
|
||||
case 'o': return 'º';
|
||||
case '1': return 'ª';
|
||||
case '2': return 'º';
|
||||
case '3': return 'ⁿ';
|
||||
case '4': return 'ᵈ';
|
||||
case '5': return 'ᵉ';
|
||||
case '6': return 'ʳ';
|
||||
case '7': return 'ˢ';
|
||||
case '8': return 'ᵗ';
|
||||
case '9': return 'ʰ';
|
||||
case '*': return '°';
|
||||
default: return c;
|
||||
}
|
||||
case KeyValue.FLAG_ACCENT_SUPERSCRIPT:
|
||||
switch (c)
|
||||
{
|
||||
@@ -183,6 +212,8 @@ class KeyModifier
|
||||
case "$": name = "€"; break;
|
||||
case "#": name = "£"; break;
|
||||
case "*": name = "°"; break;
|
||||
case "tab": name = "\\t"; break;
|
||||
case "€": case "£": return null; // Avoid showing these twice
|
||||
default: return k;
|
||||
}
|
||||
return KeyValue.getKeyByName(name);
|
||||
|
@@ -17,12 +17,15 @@ class KeyValue
|
||||
public static final char CHAR_NONE = '\0';
|
||||
|
||||
// Behavior flags
|
||||
public static final int FLAG_KEEP_ON = 1;
|
||||
public static final int FLAG_LATCH = 1;
|
||||
public static final int FLAG_LOCK = (1 << 1);
|
||||
public static final int FLAG_NOREPEAT = (1 << 2);
|
||||
public static final int FLAG_NOCHAR = (1 << 3);
|
||||
public static final int FLAG_PRECISE_REPEAT = (1 << 4);
|
||||
|
||||
// Rendering flags
|
||||
public static final int FLAG_KEY_FONT = (1 << 5);
|
||||
public static final int FLAG_SMALLER_FONT = (1 << 6);
|
||||
|
||||
// Internal flags
|
||||
public static final int FLAG_LOCKED = (1 << 8);
|
||||
@@ -32,6 +35,7 @@ class KeyValue
|
||||
public static final int FLAG_SHIFT = (1 << 11);
|
||||
public static final int FLAG_ALT = (1 << 12);
|
||||
public static final int FLAG_FN = (1 << 13);
|
||||
public static final int FLAG_META = (1 << 14);
|
||||
|
||||
// Accent flags
|
||||
public static final int FLAG_ACCENT1 = (1 << 16); // Grave
|
||||
@@ -43,21 +47,17 @@ class KeyValue
|
||||
public static final int FLAG_ACCENT_SUPERSCRIPT = (1 << 22);
|
||||
public static final int FLAG_ACCENT_SUBSCRIPT = (1 << 23);
|
||||
public static final int FLAG_ACCENT_RING = (1 << 24);
|
||||
public static final int FLAG_ACCENT_CARON = (1 << 26);
|
||||
public static final int FLAG_ACCENT_MACRON = (1 << 27);
|
||||
public static final int FLAG_ACCENT_ORDINAL = (1 << 28);
|
||||
|
||||
public static final int FLAGS_ACCENTS = FLAG_ACCENT1 | FLAG_ACCENT2 |
|
||||
FLAG_ACCENT3 | FLAG_ACCENT4 | FLAG_ACCENT5 | FLAG_ACCENT6 |
|
||||
FLAG_ACCENT_SUPERSCRIPT | FLAG_ACCENT_SUBSCRIPT | FLAG_ACCENT_RING;
|
||||
FLAG_ACCENT_CARON | FLAG_ACCENT_MACRON | FLAG_ACCENT_SUPERSCRIPT |
|
||||
FLAG_ACCENT_SUBSCRIPT | FLAG_ACCENT_ORDINAL | FLAG_ACCENT_RING;
|
||||
|
||||
// Language specific keys
|
||||
public static final int FLAG_LANG_SZLIG = (1 << 25);
|
||||
|
||||
public static final int FLAGS_LANGS = FLAG_LANG_SZLIG;
|
||||
|
||||
public static final int FLAGS_NOT_HIDDEN_ACCENTS = FLAG_ACCENT_SUPERSCRIPT |
|
||||
FLAG_ACCENT_SUBSCRIPT;
|
||||
// Keys that have to be enabled per language
|
||||
public static final int FLAGS_HIDDEN_KEYS =
|
||||
(FLAGS_ACCENTS & ~FLAGS_NOT_HIDDEN_ACCENTS) | FLAGS_LANGS;
|
||||
// Language specific keys that are removed from the keyboard by default
|
||||
public static final int FLAG_LOCALIZED = (1 << 25);
|
||||
|
||||
public final String name;
|
||||
public final String symbol;
|
||||
@@ -76,6 +76,16 @@ class KeyValue
|
||||
return new KeyValue(name, s, c, eventCode, flags);
|
||||
}
|
||||
|
||||
public KeyValue withNameAndSymbol(String n, String s)
|
||||
{
|
||||
return new KeyValue(n, s, char_, eventCode, flags);
|
||||
}
|
||||
|
||||
public KeyValue withFlags(int f)
|
||||
{
|
||||
return new KeyValue(name, symbol, char_, eventCode, f);
|
||||
}
|
||||
|
||||
private static HashMap<String, KeyValue> keys = new HashMap<String, KeyValue>();
|
||||
|
||||
public KeyValue(String n, String s, char c, int e, int f)
|
||||
@@ -94,7 +104,8 @@ class KeyValue
|
||||
KeyValue kv = KeyValue.keys.get(name);
|
||||
if (kv != null)
|
||||
return kv;
|
||||
return new KeyValue(name, name, CHAR_NONE, EVENT_NONE, 0);
|
||||
char c = (name.length() == 1) ? name.charAt(0) : CHAR_NONE;
|
||||
return new KeyValue(name, name, c, EVENT_NONE, 0);
|
||||
}
|
||||
|
||||
private static void addKey(String name, String symbol, char c, int event, int flags)
|
||||
@@ -116,12 +127,17 @@ class KeyValue
|
||||
private static void addModifierKey(String name, String symbol, int extra_flags)
|
||||
{
|
||||
addKey(name, symbol, CHAR_NONE, EVENT_NONE,
|
||||
FLAG_KEEP_ON | FLAG_NOCHAR | FLAG_NOREPEAT | extra_flags);
|
||||
FLAG_LATCH | FLAG_NOCHAR | FLAG_NOREPEAT | extra_flags);
|
||||
}
|
||||
|
||||
private static void addSpecialKey(String name, String symbol, int event)
|
||||
{
|
||||
addKey(name, symbol, CHAR_NONE, event, FLAG_NOREPEAT);
|
||||
addSpecialKey(name, symbol, event, 0);
|
||||
}
|
||||
|
||||
private static void addSpecialKey(String name, String symbol, int event, int flags)
|
||||
{
|
||||
addKey(name, symbol, CHAR_NONE, event, flags | FLAG_NOREPEAT);
|
||||
}
|
||||
|
||||
private static void addEventKey(String name, String symbol, int event)
|
||||
@@ -136,23 +152,24 @@ class KeyValue
|
||||
|
||||
static
|
||||
{
|
||||
String chars = "<>&\"_°~{|^}$*:!£%µ?.§€";
|
||||
for (int i = 0; i < chars.length(); i++)
|
||||
addCharKey(chars.charAt(i), EVENT_NONE);
|
||||
|
||||
addModifierKey("shift", "⇧", FLAG_LOCK | FLAG_SHIFT);
|
||||
addModifierKey("ctrl", "Ctrl", FLAG_CTRL);
|
||||
addModifierKey("alt", "Alt", FLAG_ALT);
|
||||
addModifierKey("accent_grave", "◌̀", FLAG_ACCENT1);
|
||||
addModifierKey("accent_aigu", "◌́", FLAG_ACCENT2);
|
||||
addModifierKey("accent_circonflexe", "◌̂", FLAG_ACCENT3);
|
||||
addModifierKey("accent_tilde", "◌̃", FLAG_ACCENT4);
|
||||
addModifierKey("accent_cedille", "◌̧", FLAG_ACCENT5);
|
||||
addModifierKey("accent_trema", "◌̈", FLAG_ACCENT6);
|
||||
addModifierKey("accent_ring", "◌̊", FLAG_ACCENT_RING);
|
||||
addModifierKey("superscript", "◌͆", FLAG_ACCENT_SUPERSCRIPT);
|
||||
addModifierKey("subscript", "◌̺", FLAG_ACCENT_SUBSCRIPT);
|
||||
addModifierKey("fn", "Fn", FLAG_FN);
|
||||
addModifierKey("shift", "\uE808",
|
||||
FLAG_SHIFT | FLAG_KEY_FONT | FLAG_SMALLER_FONT);
|
||||
addModifierKey("ctrl", "Ctrl", FLAG_CTRL | FLAG_SMALLER_FONT);
|
||||
addModifierKey("alt", "Alt", FLAG_ALT | FLAG_SMALLER_FONT);
|
||||
addModifierKey("accent_aigu", "◌́", FLAG_ACCENT2 | FLAG_LOCALIZED);
|
||||
addModifierKey("accent_caron", "◌̌", FLAG_ACCENT_CARON | FLAG_LOCALIZED);
|
||||
addModifierKey("accent_cedille", "◌̧", FLAG_ACCENT5 | FLAG_LOCALIZED);
|
||||
addModifierKey("accent_circonflexe", "◌̂", FLAG_ACCENT3 | FLAG_LOCALIZED);
|
||||
addModifierKey("accent_grave", "◌̀", FLAG_ACCENT1 | FLAG_LOCALIZED);
|
||||
addModifierKey("accent_macron", "◌̄", FLAG_ACCENT_MACRON | FLAG_LOCALIZED);
|
||||
addModifierKey("accent_tilde", "◌̃", FLAG_ACCENT4 | FLAG_LOCALIZED);
|
||||
addModifierKey("accent_trema", "◌̈", FLAG_ACCENT6 | FLAG_LOCALIZED);
|
||||
addModifierKey("accent_ring", "◌̊", FLAG_ACCENT_RING | FLAG_LOCALIZED);
|
||||
addModifierKey("superscript", "Sup", FLAG_ACCENT_SUPERSCRIPT | FLAG_SMALLER_FONT);
|
||||
addModifierKey("subscript", "Sub", FLAG_ACCENT_SUBSCRIPT | FLAG_SMALLER_FONT);
|
||||
addModifierKey("ordinal", "Ord", FLAG_ACCENT_ORDINAL | FLAG_SMALLER_FONT);
|
||||
addModifierKey("fn", "Fn", FLAG_FN | FLAG_SMALLER_FONT);
|
||||
addModifierKey("meta", "◆", FLAG_META);
|
||||
|
||||
addCharKey('a', KeyEvent.KEYCODE_A);
|
||||
addCharKey('b', KeyEvent.KEYCODE_B);
|
||||
@@ -207,29 +224,31 @@ class KeyValue
|
||||
addCharKey('#', KeyEvent.KEYCODE_POUND);
|
||||
addCharKey('(', KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN);
|
||||
addCharKey(')', KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN);
|
||||
addCharKey('ß', EVENT_NONE, FLAG_LANG_SZLIG);
|
||||
addCharKey('ß', EVENT_NONE, FLAG_LOCALIZED);
|
||||
addCharKey('€', EVENT_NONE, FLAG_LOCALIZED);
|
||||
addCharKey('£', EVENT_NONE, FLAG_LOCALIZED);
|
||||
|
||||
addSpecialKey("config", "Conf", EVENT_CONFIG);
|
||||
addSpecialKey("config", "\uE806", EVENT_CONFIG, FLAG_KEY_FONT | FLAG_SMALLER_FONT);
|
||||
addSpecialKey("switch_text", "ABC", EVENT_SWITCH_TEXT);
|
||||
addSpecialKey("switch_numeric", "123+", EVENT_SWITCH_NUMERIC);
|
||||
addSpecialKey("switch_emoji", ":)", EVENT_SWITCH_EMOJI);
|
||||
addSpecialKey("switch_emoji", "\uE812" , EVENT_SWITCH_EMOJI, FLAG_KEY_FONT | FLAG_SMALLER_FONT);
|
||||
addSpecialKey("switch_back_emoji", "ABC", EVENT_SWITCH_BACK_EMOJI);
|
||||
addSpecialKey("change_method", "⊞", EVENT_CHANGE_METHOD);
|
||||
addSpecialKey("action", "Action", EVENT_ACTION); // Will always be replaced
|
||||
addSpecialKey("change_method", "\ue807", EVENT_CHANGE_METHOD, FLAG_KEY_FONT | FLAG_SMALLER_FONT);
|
||||
addSpecialKey("action", "Action", EVENT_ACTION, FLAG_SMALLER_FONT); // Will always be replaced
|
||||
|
||||
addEventKey("esc", "Esc", KeyEvent.KEYCODE_ESCAPE);
|
||||
addEventKey("enter", "\uE800", KeyEvent.KEYCODE_ENTER, FLAG_KEY_FONT);
|
||||
addEventKey("esc", "Esc", KeyEvent.KEYCODE_ESCAPE, FLAG_SMALLER_FONT);
|
||||
addEventKey("enter", "\ue800", KeyEvent.KEYCODE_ENTER, FLAG_KEY_FONT);
|
||||
addEventKey("up", "\uE80B", KeyEvent.KEYCODE_DPAD_UP, FLAG_KEY_FONT | FLAG_PRECISE_REPEAT);
|
||||
addEventKey("right", "\uE80C", KeyEvent.KEYCODE_DPAD_RIGHT, FLAG_KEY_FONT | FLAG_PRECISE_REPEAT);
|
||||
addEventKey("down", "\uE809", KeyEvent.KEYCODE_DPAD_DOWN, FLAG_KEY_FONT | FLAG_PRECISE_REPEAT);
|
||||
addEventKey("left", "\uE80A", KeyEvent.KEYCODE_DPAD_LEFT, FLAG_KEY_FONT | FLAG_PRECISE_REPEAT);
|
||||
addEventKey("page_up", "⇞", KeyEvent.KEYCODE_PAGE_UP);
|
||||
addEventKey("page_down", "⇟", KeyEvent.KEYCODE_PAGE_DOWN);
|
||||
addEventKey("home", "↖", KeyEvent.KEYCODE_MOVE_HOME);
|
||||
addEventKey("end", "↗", KeyEvent.KEYCODE_MOVE_END);
|
||||
addEventKey("backspace", "⌫", KeyEvent.KEYCODE_DEL, FLAG_PRECISE_REPEAT);
|
||||
addEventKey("delete", "⌦", KeyEvent.KEYCODE_FORWARD_DEL, FLAG_PRECISE_REPEAT);
|
||||
addEventKey("insert", "Ins", KeyEvent.KEYCODE_INSERT);
|
||||
addEventKey("page_up", "\uE810", KeyEvent.KEYCODE_PAGE_UP, FLAG_KEY_FONT);
|
||||
addEventKey("page_down", "\uE811", KeyEvent.KEYCODE_PAGE_DOWN, FLAG_KEY_FONT);
|
||||
addEventKey("home", "\uE80E", KeyEvent.KEYCODE_MOVE_HOME, FLAG_KEY_FONT);
|
||||
addEventKey("end", "\uE80F", KeyEvent.KEYCODE_MOVE_END, FLAG_KEY_FONT);
|
||||
addEventKey("backspace", "⌫", KeyEvent.KEYCODE_DEL, FLAG_SMALLER_FONT);
|
||||
addEventKey("delete", "⌦", KeyEvent.KEYCODE_FORWARD_DEL, FLAG_SMALLER_FONT);
|
||||
addEventKey("insert", "Ins", KeyEvent.KEYCODE_INSERT, FLAG_SMALLER_FONT);
|
||||
addEventKey("f1", "F1", KeyEvent.KEYCODE_F1);
|
||||
addEventKey("f2", "F2", KeyEvent.KEYCODE_F2);
|
||||
addEventKey("f3", "F3", KeyEvent.KEYCODE_F3);
|
||||
@@ -242,6 +261,7 @@ class KeyValue
|
||||
addEventKey("f10", "F10", KeyEvent.KEYCODE_F10);
|
||||
addEventKey("tab", "↹", KeyEvent.KEYCODE_TAB);
|
||||
|
||||
addKey("space", " ", ' ', KeyEvent.KEYCODE_SPACE, 0);
|
||||
addKey("\\t", "\\t", '\t', EVENT_NONE, 0); // Send the tab character
|
||||
addKey("space", "\ue80d", ' ', KeyEvent.KEYCODE_SPACE, FLAG_KEY_FONT | FLAG_SMALLER_FONT);
|
||||
}
|
||||
}
|
||||
|
@@ -1,52 +1,45 @@
|
||||
package juloo.keyboard2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Typeface;
|
||||
import android.inputmethodservice.InputMethodService;
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.text.InputType;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.InputType;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
import android.view.inputmethod.InputMethodInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.util.Log;
|
||||
import java.util.HashMap;
|
||||
import android.util.LogPrinter;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Keyboard2 extends InputMethodService
|
||||
implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
{
|
||||
static private final String TAG = "Keyboard2";
|
||||
|
||||
private Keyboard2View _keyboardView;
|
||||
private int _currentTextLayout;
|
||||
private ViewGroup _emojiPane = null;
|
||||
|
||||
private Config _config;
|
||||
|
||||
private Map<Integer, KeyboardData> _layoutCache = new HashMap<Integer, KeyboardData>();
|
||||
private boolean _debug_logs = false;
|
||||
|
||||
private KeyboardData getLayout(int resId)
|
||||
{
|
||||
KeyboardData l = _layoutCache.get(resId);
|
||||
if (l == null)
|
||||
{
|
||||
l = KeyboardData.parse(getResources().getXml(resId));
|
||||
_layoutCache.put(resId, l);
|
||||
}
|
||||
return l;
|
||||
return KeyboardData.load(getResources(), resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,8 +50,10 @@ public class Keyboard2 extends InputMethodService
|
||||
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
|
||||
Config.initGlobalConfig(this, new KeyEventHandler(this.new Receiver()));
|
||||
_config = Config.globalConfig();
|
||||
_config.refresh(this);
|
||||
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
|
||||
_keyboardView.reset();
|
||||
_debug_logs = getResources().getBoolean(R.bool.debug_logs);
|
||||
}
|
||||
|
||||
private List<InputMethodSubtype> getEnabledSubtypes(InputMethodManager imm)
|
||||
@@ -78,36 +73,40 @@ public class Keyboard2 extends InputMethodService
|
||||
String s = subtype.getExtraValueOf("default_layout");
|
||||
if (s != null)
|
||||
l = Config.layoutId_of_string(s);
|
||||
else
|
||||
l = R.xml.qwerty;
|
||||
}
|
||||
_currentTextLayout = l;
|
||||
}
|
||||
|
||||
private int extra_keys_of_subtype(InputMethodSubtype subtype)
|
||||
private void extra_keys_of_subtype(Set<String> dst, InputMethodSubtype subtype)
|
||||
{
|
||||
String extra_keys = subtype.getExtraValueOf("extra_keys");
|
||||
int flags = 0;
|
||||
if (extra_keys != null)
|
||||
for (String acc : extra_keys.split("\\|"))
|
||||
flags |= Config.extra_key_flag_of_name(acc);
|
||||
return flags;
|
||||
if (extra_keys == null)
|
||||
return;
|
||||
String[] ks = extra_keys.split("\\|");
|
||||
for (int i = 0; i < ks.length; i++)
|
||||
dst.add(ks[i]);
|
||||
}
|
||||
|
||||
private void refreshAccentsOption(InputMethodManager imm, InputMethodSubtype subtype)
|
||||
{
|
||||
int to_keep = 0;
|
||||
HashSet<String> extra_keys = new HashSet<String>();
|
||||
switch (_config.accents)
|
||||
{
|
||||
case 1:
|
||||
to_keep |= extra_keys_of_subtype(subtype);
|
||||
extra_keys_of_subtype(extra_keys, subtype);
|
||||
for (InputMethodSubtype s : getEnabledSubtypes(imm))
|
||||
to_keep |= extra_keys_of_subtype(s);
|
||||
extra_keys_of_subtype(extra_keys, s);
|
||||
break;
|
||||
case 2: to_keep |= extra_keys_of_subtype(subtype); break;
|
||||
case 3: to_keep = KeyValue.FLAGS_HIDDEN_KEYS; break;
|
||||
case 2:
|
||||
extra_keys_of_subtype(extra_keys, subtype);
|
||||
break;
|
||||
case 3: extra_keys = null; break;
|
||||
case 4: break;
|
||||
default: throw new IllegalArgumentException();
|
||||
}
|
||||
_config.key_flags_to_remove = ~to_keep & KeyValue.FLAGS_HIDDEN_KEYS;
|
||||
_config.extra_keys = extra_keys;
|
||||
}
|
||||
|
||||
private void refreshSubtypeLegacyFallback()
|
||||
@@ -115,8 +114,8 @@ public class Keyboard2 extends InputMethodService
|
||||
// Fallback for the accents option: Only respect the "None" case
|
||||
switch (_config.accents)
|
||||
{
|
||||
case 1: case 2: case 3: _config.key_flags_to_remove = 0; break;
|
||||
case 4: _config.key_flags_to_remove = KeyValue.FLAGS_HIDDEN_KEYS; break;
|
||||
case 1: case 2: case 3: _config.extra_keys = null; break;
|
||||
case 4: _config.extra_keys = new HashSet<String>(); break;
|
||||
}
|
||||
// Fallback for the layout option: Use qwerty in the "system settings" case
|
||||
_currentTextLayout = (_config.layout == -1) ? R.xml.qwerty : _config.layout;
|
||||
@@ -141,18 +140,20 @@ public class Keyboard2 extends InputMethodService
|
||||
|
||||
private String actionLabel_of_imeAction(int action)
|
||||
{
|
||||
int res;
|
||||
switch (action)
|
||||
{
|
||||
case EditorInfo.IME_ACTION_NEXT: res = R.string.key_action_next; break;
|
||||
case EditorInfo.IME_ACTION_DONE: res = R.string.key_action_done; break;
|
||||
case EditorInfo.IME_ACTION_GO: res = R.string.key_action_go; break;
|
||||
case EditorInfo.IME_ACTION_PREVIOUS: res = R.string.key_action_prev; break;
|
||||
case EditorInfo.IME_ACTION_SEARCH: res = R.string.key_action_search; break;
|
||||
case EditorInfo.IME_ACTION_SEND: res = R.string.key_action_send; break;
|
||||
case EditorInfo.IME_ACTION_UNSPECIFIED:
|
||||
case EditorInfo.IME_ACTION_NEXT: return "Next";
|
||||
case EditorInfo.IME_ACTION_DONE: return "Done";
|
||||
case EditorInfo.IME_ACTION_GO: return "Go";
|
||||
case EditorInfo.IME_ACTION_PREVIOUS: return "Prev";
|
||||
case EditorInfo.IME_ACTION_SEARCH: return "Search";
|
||||
case EditorInfo.IME_ACTION_SEND: return "Send";
|
||||
case EditorInfo.IME_ACTION_NONE:
|
||||
default: return null;
|
||||
}
|
||||
return getResources().getString(res);
|
||||
}
|
||||
|
||||
private void refreshEditorInfo(EditorInfo info)
|
||||
@@ -171,22 +172,45 @@ public class Keyboard2 extends InputMethodService
|
||||
_config.actionLabel = actionLabel_of_imeAction(action); // Might be null
|
||||
_config.actionId = action;
|
||||
_config.swapEnterActionKey =
|
||||
(info.imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0;
|
||||
(info.imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshConfig()
|
||||
{
|
||||
int prev_theme = _config.theme;
|
||||
_config.refresh(this);
|
||||
refreshSubtypeImm();
|
||||
// Refreshing the theme config requires re-creating the views
|
||||
if (prev_theme != _config.theme)
|
||||
{
|
||||
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
|
||||
_emojiPane = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void log_editor_info(EditorInfo info)
|
||||
{
|
||||
LogPrinter p = new LogPrinter(Log.DEBUG, TAG);
|
||||
info.dump(p, "");
|
||||
if (info.extras != null)
|
||||
Log.d(TAG, "extras: "+info.extras.toString());
|
||||
Log.d(TAG, "swapEnterActionKey: "+_config.swapEnterActionKey);
|
||||
Log.d(TAG, "actionLabel: "+_config.actionLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartInputView(EditorInfo info, boolean restarting)
|
||||
{
|
||||
// Update '_config' before calling 'KeyboardView.setKeyboard'
|
||||
refreshSubtypeImm();
|
||||
refreshConfig();
|
||||
refreshEditorInfo(info);
|
||||
if ((info.inputType & InputType.TYPE_CLASS_NUMBER) != 0)
|
||||
_keyboardView.setKeyboard(getLayout(R.xml.numeric));
|
||||
else
|
||||
_keyboardView.setKeyboard(getLayout(_currentTextLayout));
|
||||
_keyboardView.reset(); // Layout might need to change due to rotation
|
||||
setInputView(_keyboardView);
|
||||
if (_debug_logs)
|
||||
log_editor_info(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -215,16 +239,7 @@ public class Keyboard2 extends InputMethodService
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
|
||||
{
|
||||
int prev_theme = _config.theme;
|
||||
_config.refresh(this);
|
||||
refreshSubtypeImm();
|
||||
_keyboardView.refreshConfig(getLayout(_currentTextLayout));
|
||||
// Refreshing the theme config requires re-creating the views
|
||||
if (prev_theme != _config.theme)
|
||||
{
|
||||
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
|
||||
_emojiPane = null;
|
||||
}
|
||||
refreshConfig();
|
||||
}
|
||||
|
||||
/** Not static */
|
||||
@@ -233,7 +248,9 @@ public class Keyboard2 extends InputMethodService
|
||||
public void switchToNextInputMethod()
|
||||
{
|
||||
InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
|
||||
imm.switchToNextInputMethod(getConnectionToken(), false);
|
||||
imm.showInputMethodPicker();
|
||||
// deprecated in version 28: imm.switchToNextInputMethod(getConnectionToken(), false);
|
||||
// added in version 28: switchToNextInputMethod(false);
|
||||
}
|
||||
|
||||
public void setPane_emoji()
|
||||
@@ -263,14 +280,12 @@ public class Keyboard2 extends InputMethodService
|
||||
_keyboardView.setKeyboard(getLayout(res_id));
|
||||
}
|
||||
|
||||
public void sendKeyEvent(int eventCode, int meta)
|
||||
public void sendKeyEvent(int eventAction, int eventCode, int meta)
|
||||
{
|
||||
InputConnection conn = getCurrentInputConnection();
|
||||
if (conn == null)
|
||||
return;
|
||||
KeyEvent event = new KeyEvent(1, 1, KeyEvent.ACTION_DOWN, eventCode, 0, meta);
|
||||
conn.sendKeyEvent(event);
|
||||
conn.sendKeyEvent(KeyEvent.changeAction(event, KeyEvent.ACTION_UP));
|
||||
conn.sendKeyEvent(new KeyEvent(1, 1, eventAction, eventCode, 0, meta));
|
||||
}
|
||||
|
||||
public void showKeyboardConfig()
|
||||
|
@@ -4,32 +4,27 @@ import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Vibrator;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.PopupWindow;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Keyboard2View extends View
|
||||
implements View.OnTouchListener, Handler.Callback
|
||||
implements View.OnTouchListener, Pointers.IPointerEventHandler
|
||||
{
|
||||
private static final long VIBRATE_MIN_INTERVAL = 100;
|
||||
|
||||
private KeyboardData _keyboard;
|
||||
|
||||
private ArrayList<KeyDown> _downKeys = new ArrayList<KeyDown>();
|
||||
private Pointers _pointers;
|
||||
|
||||
private int _flags = 0;
|
||||
|
||||
private Vibrator _vibratorService;
|
||||
private long _lastVibration = 0;
|
||||
|
||||
private Handler _handler;
|
||||
private static int _currentWhat = 0;
|
||||
|
||||
private Config _config;
|
||||
@@ -40,265 +35,136 @@ public class Keyboard2View extends View
|
||||
|
||||
private static RectF _tmpRect = new RectF();
|
||||
|
||||
enum Vertical
|
||||
{
|
||||
TOP,
|
||||
CENTER,
|
||||
BOTTOM
|
||||
}
|
||||
|
||||
public Keyboard2View(Context context, AttributeSet attrs)
|
||||
{
|
||||
super(context, attrs);
|
||||
_vibratorService = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
_handler = new Handler(this);
|
||||
_theme = new Theme(getContext(), attrs);
|
||||
_config = Config.globalConfig();
|
||||
refreshConfig(null);
|
||||
_pointers = new Pointers(this, _config);
|
||||
setOnTouchListener(this);
|
||||
}
|
||||
|
||||
/* Internally calls [reset()]. */
|
||||
public void refreshConfig(KeyboardData kw)
|
||||
{
|
||||
if (kw != null)
|
||||
setKeyboard(kw); // handle layout options then calls reset().
|
||||
reset();
|
||||
}
|
||||
|
||||
public void setKeyboard(KeyboardData kw)
|
||||
{
|
||||
if (!_config.shouldOfferSwitchingToNextInputMethod)
|
||||
kw = kw.replaceKeys(
|
||||
new KeyboardData.ReplaceKeysByEvent(KeyValue.EVENT_CHANGE_METHOD, null));
|
||||
if (_config.key_flags_to_remove != 0)
|
||||
kw = kw.replaceKeys(
|
||||
new KeyboardData.ReplaceKeysByFlags(_config.key_flags_to_remove, null));
|
||||
// Replace the action key to show the right label.
|
||||
KeyValue action_key = null;
|
||||
if (_config.actionLabel != null)
|
||||
{
|
||||
action_key = new KeyValue(_config.actionLabel, _config.actionLabel,
|
||||
KeyValue.CHAR_NONE, KeyValue.EVENT_ACTION, KeyValue.FLAG_NOREPEAT);
|
||||
}
|
||||
if (_config.swapEnterActionKey && action_key != null)
|
||||
kw = kw.replaceKeys(
|
||||
new KeyboardData.ReplaceKeysByEvent2(KeyEvent.KEYCODE_ENTER,
|
||||
action_key, KeyValue.EVENT_ACTION,
|
||||
KeyValue.getKeyByName("enter")));
|
||||
else
|
||||
kw = kw.replaceKeys(
|
||||
new KeyboardData.ReplaceKeysByEvent(KeyValue.EVENT_ACTION, action_key));
|
||||
_keyboard = kw;
|
||||
_keyboard = _config.modify_layout(kw);
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset()
|
||||
{
|
||||
_flags = 0;
|
||||
_downKeys.clear();
|
||||
_pointers.clear();
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void onPointerDown(KeyValue k)
|
||||
{
|
||||
updateFlags();
|
||||
invalidate();
|
||||
if (k != null)
|
||||
vibrate();
|
||||
}
|
||||
|
||||
public void onPointerSwipe(KeyValue k)
|
||||
{
|
||||
updateFlags();
|
||||
invalidate();
|
||||
if (k != null)
|
||||
vibrate();
|
||||
}
|
||||
|
||||
public void onPointerUp(KeyValue k)
|
||||
{
|
||||
_config.handler.handleKeyUp(k, _flags);
|
||||
updateFlags();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void onPointerHold(KeyValue k)
|
||||
{
|
||||
_config.handler.handleKeyUp(k, _flags);
|
||||
}
|
||||
|
||||
public void onPointerFlagsChanged()
|
||||
{
|
||||
updateFlags();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void updateFlags()
|
||||
{
|
||||
_flags = _pointers.getFlags();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event)
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float keyW;
|
||||
int p;
|
||||
|
||||
switch (event.getActionMasked())
|
||||
{
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
onTouchUp(event.getPointerId(event.getActionIndex()));
|
||||
break ;
|
||||
_pointers.onTouchUp(event.getPointerId(event.getActionIndex()));
|
||||
break;
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
p = event.getActionIndex();
|
||||
onTouchDown(event.getX(p), event.getY(p), event.getPointerId(p));
|
||||
break ;
|
||||
float tx = event.getX(p);
|
||||
float ty = event.getY(p);
|
||||
KeyboardData.Key key = getKeyAtPosition(tx, ty);
|
||||
if (key != null)
|
||||
_pointers.onTouchDown(tx, ty, event.getPointerId(p), key);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
for (p = 0; p < event.getPointerCount(); p++)
|
||||
onTouchMove(event.getX(p), event.getY(p), event.getPointerId(p));
|
||||
break ;
|
||||
_pointers.onTouchMove(event.getX(p), event.getY(p), event.getPointerId(p));
|
||||
break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
_pointers.onTouchCancel(event.getPointerId(event.getActionIndex()));
|
||||
break;
|
||||
default:
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
private KeyDown getKeyDown(int pointerId)
|
||||
private KeyboardData.Row getRowAtPosition(float ty)
|
||||
{
|
||||
for (KeyDown k : _downKeys)
|
||||
{
|
||||
if (k.pointerId == pointerId)
|
||||
return (k);
|
||||
}
|
||||
return (null);
|
||||
}
|
||||
|
||||
private KeyDown getKeyDown(KeyboardData.Key key)
|
||||
{
|
||||
for (KeyDown k : _downKeys)
|
||||
{
|
||||
if (k.key == key)
|
||||
return (k);
|
||||
}
|
||||
return (null);
|
||||
}
|
||||
|
||||
private KeyDown getKeyDown(KeyValue kv)
|
||||
{
|
||||
for (KeyDown k : _downKeys)
|
||||
{
|
||||
if (k.value == kv)
|
||||
return (k);
|
||||
}
|
||||
return (null);
|
||||
}
|
||||
|
||||
private void onTouchMove(float moveX, float moveY, int pointerId)
|
||||
{
|
||||
KeyDown key = getKeyDown(pointerId);
|
||||
KeyValue newValue;
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
moveX -= key.downX;
|
||||
moveY -= key.downY;
|
||||
float absDist = Math.abs(moveX) + Math.abs(moveY);
|
||||
key.ptrDist = absDist;
|
||||
if (absDist < _config.swipe_dist_px)
|
||||
newValue = key.key.key0;
|
||||
else if (moveX < 0)
|
||||
newValue = (moveY < 0) ? key.key.key1 : key.key.key3;
|
||||
else if (moveY < 0)
|
||||
newValue = key.key.key2;
|
||||
else
|
||||
newValue = key.key.key4;
|
||||
if (newValue != null && newValue != key.value)
|
||||
{
|
||||
if (key.timeoutWhat != -1)
|
||||
{
|
||||
_handler.removeMessages(key.timeoutWhat);
|
||||
if ((newValue.flags & KeyValue.FLAG_NOREPEAT) == 0)
|
||||
_handler.sendEmptyMessageDelayed(key.timeoutWhat, _config.longPressTimeout);
|
||||
}
|
||||
key.value = newValue;
|
||||
key.flags = newValue.flags;
|
||||
updateFlags();
|
||||
invalidate();
|
||||
handleKeyDown(newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onTouchDown(float touchX, float touchY, int pointerId)
|
||||
{
|
||||
float y = _config.marginTop - _config.keyHeight;
|
||||
float y = _config.marginTop;
|
||||
if (ty < y)
|
||||
return null;
|
||||
for (KeyboardData.Row row : _keyboard.rows)
|
||||
{
|
||||
y += _config.keyHeight;
|
||||
if (touchY < y || touchY >= (y + _config.keyHeight))
|
||||
continue ;
|
||||
float x = _config.horizontalMargin;
|
||||
for (KeyboardData.Key key : row.keys)
|
||||
{
|
||||
x += key.shift * _keyWidth;
|
||||
float keyW = _keyWidth * key.width;
|
||||
if (touchX >= x && touchX < (x + keyW))
|
||||
{
|
||||
int what = _currentWhat++;
|
||||
if (key.key0 != null && (key.key0.flags & KeyValue.FLAG_NOREPEAT) == 0)
|
||||
_handler.sendEmptyMessageDelayed(what, _config.longPressTimeout);
|
||||
_downKeys.add(new KeyDown(pointerId, key, touchX, touchY, what));
|
||||
handleKeyDown(key.key0);
|
||||
updateFlags();
|
||||
invalidate();
|
||||
return ;
|
||||
}
|
||||
x += keyW;
|
||||
}
|
||||
y += (row.shift + row.height) * _config.keyHeight;
|
||||
if (ty < y)
|
||||
return row;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Whether a key is already activated (key down but pointer up)
|
||||
private KeyDown getActivatedKey(KeyValue kv)
|
||||
private KeyboardData.Key getKeyAtPosition(float tx, float ty)
|
||||
{
|
||||
for (KeyDown k : _downKeys)
|
||||
KeyboardData.Row row = getRowAtPosition(ty);
|
||||
float x = _config.horizontalMargin;
|
||||
if (row == null || tx < x)
|
||||
return null;
|
||||
for (KeyboardData.Key key : row.keys)
|
||||
{
|
||||
if (k.value == kv && k.pointerId == -1)
|
||||
return (k);
|
||||
x += (key.shift + key.width) * _keyWidth;
|
||||
if (tx < x)
|
||||
return key;
|
||||
}
|
||||
return (null);
|
||||
}
|
||||
|
||||
private void onTouchUp(int pointerId)
|
||||
{
|
||||
KeyDown k = getKeyDown(pointerId);
|
||||
|
||||
if (k != null)
|
||||
{
|
||||
// Stop key repeat
|
||||
if (k.timeoutWhat != -1)
|
||||
{
|
||||
_handler.removeMessages(k.timeoutWhat);
|
||||
k.timeoutWhat = -1;
|
||||
}
|
||||
KeyDown k_on = getActivatedKey(k.value);
|
||||
if (k_on != null)
|
||||
{
|
||||
_downKeys.remove(k); // Remove dupplicate
|
||||
// Same key with FLAG_LOCK is already on, do lock
|
||||
if ((k_on.flags & KeyValue.FLAG_LOCK) != 0)
|
||||
{
|
||||
k_on.flags ^= KeyValue.FLAG_LOCK; // Next time, disable it
|
||||
k_on.flags |= KeyValue.FLAG_LOCKED;
|
||||
}
|
||||
// Otherwise, toggle it
|
||||
else
|
||||
{
|
||||
_downKeys.remove(k_on);
|
||||
}
|
||||
}
|
||||
// Key stay activated
|
||||
else if ((k.flags & KeyValue.FLAG_KEEP_ON) != 0)
|
||||
{
|
||||
k.pointerId = -1; // Set pointer up
|
||||
}
|
||||
else // Regular key up
|
||||
{
|
||||
for (int i = 0; i < _downKeys.size(); i++)
|
||||
{
|
||||
KeyDown downKey = _downKeys.get(i);
|
||||
// Disable other activated keys that aren't locked
|
||||
if (downKey.pointerId == -1 && (downKey.flags & KeyValue.FLAG_LOCKED) == 0)
|
||||
_downKeys.remove(i--);
|
||||
// Other keys currently down won't stay activated
|
||||
else if ((downKey.flags & KeyValue.FLAG_KEEP_ON) != 0)
|
||||
downKey.flags ^= KeyValue.FLAG_KEEP_ON;
|
||||
}
|
||||
_downKeys.remove(k);
|
||||
handleKeyUp(k);
|
||||
}
|
||||
updateFlags();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleKeyUp(KeyDown key)
|
||||
{
|
||||
if (key.value != null && (key.flags & (KeyValue.FLAG_LOCKED | KeyValue.FLAG_NOCHAR)) == 0)
|
||||
_config.handler.handleKeyUp(key.value, _flags);
|
||||
}
|
||||
|
||||
private void handleKeyDown(KeyValue key)
|
||||
{
|
||||
if (key == null)
|
||||
return ;
|
||||
vibrate();
|
||||
}
|
||||
|
||||
private void updateFlags()
|
||||
{
|
||||
_flags = 0;
|
||||
for (KeyDown k : _downKeys)
|
||||
_flags |= k.flags;
|
||||
return null;
|
||||
}
|
||||
|
||||
private void vibrate()
|
||||
@@ -320,28 +186,6 @@ public class Keyboard2View extends View
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMessage(Message msg)
|
||||
{
|
||||
for (KeyDown key : _downKeys)
|
||||
{
|
||||
if (key.timeoutWhat == msg.what)
|
||||
{
|
||||
long nextInterval = _config.longPressInterval;
|
||||
if (_config.preciseRepeat && (key.flags & KeyValue.FLAG_PRECISE_REPEAT) != 0)
|
||||
{
|
||||
// Modulate repeat interval depending on the distance of the pointer
|
||||
float accel = Math.min(4.f, Math.max(0.3f, key.ptrDist / (_config.swipe_dist_px * 15.f)));
|
||||
nextInterval = (long)((float)nextInterval / accel);
|
||||
}
|
||||
_handler.sendEmptyMessageDelayed(msg.what, nextInterval);
|
||||
_config.handler.handleKeyUp(key.value, _flags);
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMeasure(int wSpec, int hSpec)
|
||||
{
|
||||
@@ -368,21 +212,25 @@ public class Keyboard2View extends View
|
||||
{
|
||||
x += k.shift * _keyWidth;
|
||||
float keyW = _keyWidth * k.width - _config.keyHorizontalInterval;
|
||||
KeyDown keyDown = getKeyDown(k);
|
||||
boolean isKeyDown = _pointers.isKeyDown(k);
|
||||
_tmpRect.set(x, y, x + keyW, y + keyH);
|
||||
canvas.drawRoundRect(_tmpRect, _theme.keyBorderRadius, _theme.keyBorderRadius,
|
||||
(keyDown != null) ? _theme.keyDownBgPaint : _theme.keyBgPaint);
|
||||
if (k.key0 != null)
|
||||
drawLabel(canvas, k.key0, keyW / 2f + x, (keyH + _theme.labelTextSize) / 2f + y, keyDown);
|
||||
float subPadding = _config.keyPadding;
|
||||
if (k.key1 != null)
|
||||
drawSubLabel(canvas, k.key1, x + subPadding, y + subPadding, false, true, keyDown);
|
||||
if (k.key3 != null)
|
||||
drawSubLabel(canvas, k.key3, x + subPadding, y + keyH - subPadding, false, false, keyDown);
|
||||
if (k.key2 != null)
|
||||
drawSubLabel(canvas, k.key2, x + keyW - subPadding, y + subPadding, true, true, keyDown);
|
||||
if (k.key4 != null)
|
||||
drawSubLabel(canvas, k.key4, x + keyW - subPadding, y + keyH - subPadding, true, false, keyDown);
|
||||
isKeyDown ? _theme.keyDownBgPaint : _theme.keyBgPaint);
|
||||
drawLabel(canvas, k.key0, keyW / 2f + x, y, keyH, isKeyDown);
|
||||
if (k.edgekeys)
|
||||
{
|
||||
drawSubLabel(canvas, k.key1, x, y, keyW, keyH, Paint.Align.CENTER, Vertical.TOP, isKeyDown);
|
||||
drawSubLabel(canvas, k.key3, x, y, keyW, keyH, Paint.Align.LEFT, Vertical.CENTER, isKeyDown);
|
||||
drawSubLabel(canvas, k.key2, x, y, keyW, keyH, Paint.Align.RIGHT, Vertical.CENTER, isKeyDown);
|
||||
drawSubLabel(canvas, k.key4, x, y, keyW, keyH, Paint.Align.CENTER, Vertical.BOTTOM, isKeyDown);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawSubLabel(canvas, k.key1, x, y, keyW, keyH, Paint.Align.LEFT, Vertical.TOP, isKeyDown);
|
||||
drawSubLabel(canvas, k.key3, x, y, keyW, keyH, Paint.Align.LEFT, Vertical.BOTTOM, isKeyDown);
|
||||
drawSubLabel(canvas, k.key2, x, y, keyW, keyH, Paint.Align.RIGHT, Vertical.TOP, isKeyDown);
|
||||
drawSubLabel(canvas, k.key4, x, y, keyW, keyH, Paint.Align.RIGHT, Vertical.BOTTOM, isKeyDown);
|
||||
}
|
||||
x += _keyWidth * k.width;
|
||||
}
|
||||
y += row.height * _config.keyHeight;
|
||||
@@ -395,69 +243,58 @@ public class Keyboard2View extends View
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
private int labelColor(KeyValue k, KeyDown hasKeyDown, int defaultColor)
|
||||
private int labelColor(KeyValue k, boolean isKeyDown, int defaultColor)
|
||||
{
|
||||
if (hasKeyDown != null)
|
||||
if (isKeyDown && (k.flags & KeyValue.FLAG_LATCH) != 0)
|
||||
{
|
||||
KeyDown kd = getKeyDown(k);
|
||||
if (kd != null)
|
||||
int flags = _pointers.getKeyFlags(k);
|
||||
if (flags != -1)
|
||||
{
|
||||
if ((kd.flags & KeyValue.FLAG_LOCKED) != 0)
|
||||
if ((flags & KeyValue.FLAG_LOCKED) != 0)
|
||||
return _theme.lockedColor;
|
||||
if (kd.pointerId == -1)
|
||||
if ((flags & KeyValue.FLAG_LATCH) == 0)
|
||||
return _theme.activatedColor;
|
||||
}
|
||||
}
|
||||
return defaultColor;
|
||||
}
|
||||
|
||||
private void drawLabel(Canvas canvas, KeyValue k, float x, float y, KeyDown keyDown)
|
||||
private void drawLabel(Canvas canvas, KeyValue k, float x, float y, float keyH, boolean isKeyDown)
|
||||
{
|
||||
k = KeyModifier.handleFlags(k, _flags);
|
||||
if (k == null)
|
||||
return;
|
||||
float textSize = scaleTextSize(k, _config.labelTextSize, keyH);
|
||||
Paint p = _theme.labelPaint(((k.flags & KeyValue.FLAG_KEY_FONT) != 0));
|
||||
p.setColor(labelColor(k, keyDown, _theme.labelColor));
|
||||
p.setTextSize(_theme.labelTextSize * scaleTextSize(k));
|
||||
canvas.drawText(k.symbol, x, y, p);
|
||||
p.setColor(labelColor(k, isKeyDown, _theme.labelColor));
|
||||
p.setTextSize(textSize);
|
||||
canvas.drawText(k.symbol, x, (keyH - p.ascent() - p.descent()) / 2f + y, p);
|
||||
}
|
||||
|
||||
private void drawSubLabel(Canvas canvas, KeyValue k, float x, float y, boolean right, boolean up, KeyDown keyDown)
|
||||
private void drawSubLabel(Canvas canvas, KeyValue k, float x, float y, float keyW, float keyH, Paint.Align a, Vertical v, boolean isKeyDown)
|
||||
{
|
||||
k = KeyModifier.handleFlags(k, _flags);
|
||||
Paint p = _theme.subLabelPaint(((k.flags & KeyValue.FLAG_KEY_FONT) != 0), right);
|
||||
p.setColor(labelColor(k, keyDown, _theme.subLabelColor));
|
||||
p.setTextSize(_theme.sublabelTextSize * scaleTextSize(k));
|
||||
y -= up ? p.ascent() : p.descent();
|
||||
if (k == null)
|
||||
return;
|
||||
float textSize = scaleTextSize(k, _config.sublabelTextSize, keyH);
|
||||
Paint p = _theme.subLabelPaint(((k.flags & KeyValue.FLAG_KEY_FONT) != 0), a);
|
||||
p.setColor(labelColor(k, isKeyDown, _theme.subLabelColor));
|
||||
p.setTextSize(textSize);
|
||||
float subPadding = _config.keyPadding;
|
||||
if (v == Vertical.CENTER)
|
||||
y += (keyH - p.ascent() - p.descent()) / 2f;
|
||||
else
|
||||
y += (v == Vertical.TOP) ? subPadding - p.ascent() : keyH - subPadding - p.descent();
|
||||
if (a == Paint.Align.CENTER)
|
||||
x += keyW / 2f;
|
||||
else
|
||||
x += (a == Paint.Align.LEFT) ? subPadding : keyW - subPadding;
|
||||
canvas.drawText(k.symbol, x, y, p);
|
||||
}
|
||||
|
||||
private float scaleTextSize(KeyValue k)
|
||||
private float scaleTextSize(KeyValue k, float rel_size, float keyH)
|
||||
{
|
||||
return ((k.symbol.length() < 2) ? 1.f : 0.8f) * _config.characterSize;
|
||||
}
|
||||
|
||||
private static class KeyDown
|
||||
{
|
||||
/* -1 if pointer is up. */
|
||||
public int pointerId;
|
||||
public KeyValue value;
|
||||
public KeyboardData.Key key;
|
||||
public float downX;
|
||||
public float downY;
|
||||
/* Manhattan distance of the pointer to the center of the key */
|
||||
public float ptrDist;
|
||||
public int flags;
|
||||
public int timeoutWhat;
|
||||
|
||||
public KeyDown(int pointerId, KeyboardData.Key key, float x, float y, int what)
|
||||
{
|
||||
this.pointerId = pointerId;
|
||||
value = key.key0;
|
||||
this.key = key;
|
||||
downX = x;
|
||||
downY = y;
|
||||
ptrDist = 0.f;
|
||||
flags = (value == null) ? 0 : value.flags;
|
||||
timeoutWhat = what;
|
||||
}
|
||||
float smaller_font = ((k.flags & KeyValue.FLAG_SMALLER_FONT) == 0) ? 1.f : 0.75f;
|
||||
return keyH * rel_size * smaller_font * _config.characterSize;
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,12 @@
|
||||
package juloo.keyboard2;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
class KeyboardData
|
||||
{
|
||||
@@ -12,70 +16,87 @@ class KeyboardData
|
||||
/* Total height of the keyboard. Unit is abstract. */
|
||||
public final float keysHeight;
|
||||
|
||||
public KeyboardData(List<Row> rows_)
|
||||
{
|
||||
float kw = 0.f;
|
||||
float kh = 0.f;
|
||||
for (Row r : rows_)
|
||||
{
|
||||
kw = Math.max(kw, r.keysWidth);
|
||||
kh += r.height + r.shift;
|
||||
}
|
||||
rows = rows_;
|
||||
keysWidth = kw;
|
||||
keysHeight = kh;
|
||||
}
|
||||
|
||||
public static KeyboardData parse(XmlResourceParser parser)
|
||||
{
|
||||
ArrayList<Row> rows = new ArrayList<Row>();
|
||||
|
||||
try
|
||||
{
|
||||
int status;
|
||||
|
||||
while (parser.next() != XmlResourceParser.START_TAG)
|
||||
continue ;
|
||||
if (!parser.getName().equals("keyboard"))
|
||||
throw new Exception("Unknow tag: " + parser.getName());
|
||||
while ((status = parser.next()) != XmlResourceParser.END_DOCUMENT)
|
||||
{
|
||||
if (status == XmlResourceParser.START_TAG)
|
||||
{
|
||||
String tag = parser.getName();
|
||||
if (tag.equals("row"))
|
||||
rows.add(Row.parse(parser));
|
||||
else
|
||||
throw new Exception("Unknow keyboard tag: " + tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new KeyboardData(rows);
|
||||
}
|
||||
|
||||
public KeyboardData replaceKeys(MapKeys f)
|
||||
{
|
||||
ArrayList<Row> rows_ = new ArrayList<Row>();
|
||||
for (Row r : rows)
|
||||
rows_.add(r.replaceKeys(f));
|
||||
return new KeyboardData(rows_);
|
||||
return new KeyboardData(rows_, keysWidth);
|
||||
}
|
||||
|
||||
private static Row _bottomRow = null;
|
||||
private static Map<Integer, KeyboardData> _layoutCache = new HashMap<Integer, KeyboardData>();
|
||||
|
||||
public static KeyboardData load(Resources res, int id)
|
||||
{
|
||||
KeyboardData l = _layoutCache.get(id);
|
||||
if (l == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_bottomRow == null)
|
||||
_bottomRow = parse_bottom_row(res.getXml(R.xml.bottom_row));
|
||||
l = parse_keyboard(res.getXml(id));
|
||||
_layoutCache.put(id, l);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
private static KeyboardData parse_keyboard(XmlResourceParser parser) throws Exception
|
||||
{
|
||||
if (!expect_tag(parser, "keyboard"))
|
||||
throw new Exception("Empty layout file");
|
||||
boolean bottom_row = parser.getAttributeBooleanValue(null, "bottom_row", true);
|
||||
ArrayList<Row> rows = new ArrayList<Row>();
|
||||
while (expect_tag(parser, "row"))
|
||||
rows.add(Row.parse(parser));
|
||||
float kw = compute_max_width(rows);
|
||||
if (bottom_row)
|
||||
rows.add(_bottomRow.updateWidth(kw));
|
||||
return new KeyboardData(rows, kw);
|
||||
}
|
||||
|
||||
private static float compute_max_width(List<Row> rows)
|
||||
{
|
||||
float w = 0.f;
|
||||
for (Row r : rows)
|
||||
w = Math.max(w, r.keysWidth);
|
||||
return w;
|
||||
}
|
||||
|
||||
private static Row parse_bottom_row(XmlResourceParser parser) throws Exception
|
||||
{
|
||||
if (!expect_tag(parser, "row"))
|
||||
throw new Exception("Failed to parse bottom row");
|
||||
return Row.parse(parser);
|
||||
}
|
||||
|
||||
protected KeyboardData(List<Row> rows_, float kw)
|
||||
{
|
||||
float kh = 0.f;
|
||||
for (Row r : rows_)
|
||||
kh += r.height + r.shift;
|
||||
rows = rows_;
|
||||
keysWidth = kw;
|
||||
keysHeight = kh;
|
||||
}
|
||||
|
||||
public static class Row
|
||||
{
|
||||
public final List<Key> keys;
|
||||
/* Height of the row. Unit is abstract. */
|
||||
/* Height of the row, without 'shift'. Unit is abstract. */
|
||||
public final float height;
|
||||
/* Extra empty space on the top. */
|
||||
public final float shift;
|
||||
/* Total width of very keys. Unit is abstract. */
|
||||
/* Total width of the row. Unit is abstract. */
|
||||
private final float keysWidth;
|
||||
|
||||
public Row(List<Key> keys_, float h, float s)
|
||||
protected Row(List<Key> keys_, float h, float s)
|
||||
{
|
||||
float kw = 0.f;
|
||||
for (Key k : keys_) kw += k.width + k.shift;
|
||||
@@ -91,17 +112,8 @@ class KeyboardData
|
||||
int status;
|
||||
float h = parser.getAttributeFloatValue(null, "height", 1f);
|
||||
float shift = parser.getAttributeFloatValue(null, "shift", 0f);
|
||||
while ((status = parser.next()) != XmlResourceParser.END_TAG)
|
||||
{
|
||||
if (status == XmlResourceParser.START_TAG)
|
||||
{
|
||||
String tag = parser.getName();
|
||||
if (tag.equals("key"))
|
||||
keys.add(Key.parse(parser));
|
||||
else
|
||||
throw new Exception("Unknow row tag: " + tag);
|
||||
}
|
||||
}
|
||||
while (expect_tag(parser, "key"))
|
||||
keys.add(Key.parse(parser));
|
||||
return new Row(keys, h, shift);
|
||||
}
|
||||
|
||||
@@ -112,6 +124,16 @@ class KeyboardData
|
||||
keys_.add(k.replaceKeys(f));
|
||||
return new Row(keys_, height, shift);
|
||||
}
|
||||
|
||||
/** Change the width of every keys so that the row is 's' units wide. */
|
||||
public Row updateWidth(float newWidth)
|
||||
{
|
||||
float s = newWidth / keysWidth;
|
||||
ArrayList<Key> keys_ = new ArrayList<Key>();
|
||||
for (Key k : keys)
|
||||
keys_.add(k.scaleWidth(s));
|
||||
return new Row(keys_, height, shift);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Key
|
||||
@@ -131,8 +153,10 @@ class KeyboardData
|
||||
public final float width;
|
||||
/* Extra empty space on the left of the key. */
|
||||
public final float shift;
|
||||
/* Put keys 1 to 4 on the edges instead of the corners. */
|
||||
public final boolean edgekeys;
|
||||
|
||||
public Key(KeyValue k0, KeyValue k1, KeyValue k2, KeyValue k3, KeyValue k4, float w, float s)
|
||||
protected Key(KeyValue k0, KeyValue k1, KeyValue k2, KeyValue k3, KeyValue k4, float w, float s, boolean e)
|
||||
{
|
||||
key0 = k0;
|
||||
key1 = k1;
|
||||
@@ -141,6 +165,7 @@ class KeyboardData
|
||||
key4 = k4;
|
||||
width = w;
|
||||
shift = s;
|
||||
edgekeys = e;
|
||||
}
|
||||
|
||||
public static Key parse(XmlResourceParser parser) throws Exception
|
||||
@@ -152,79 +177,42 @@ class KeyboardData
|
||||
KeyValue k4 = KeyValue.getKeyByName(parser.getAttributeValue(null, "key4"));
|
||||
float width = parser.getAttributeFloatValue(null, "width", 1f);
|
||||
float shift = parser.getAttributeFloatValue(null, "shift", 0.f);
|
||||
boolean edgekeys = parser.getAttributeBooleanValue(null, "edgekeys", false);
|
||||
while (parser.next() != XmlResourceParser.END_TAG)
|
||||
continue ;
|
||||
return new Key(k0, k1, k2, k3, k4, width, shift);
|
||||
return new Key(k0, k1, k2, k3, k4, width, shift, edgekeys);
|
||||
}
|
||||
|
||||
public Key replaceKeys(MapKeys f)
|
||||
{
|
||||
return new Key(f.map(key0), f.map(key1), f.map(key2), f.map(key3), f.map(key4), width, shift);
|
||||
return new Key(f.apply(key0), f.apply(key1), f.apply(key2),
|
||||
f.apply(key3), f.apply(key4), width, shift, edgekeys);
|
||||
}
|
||||
|
||||
/** New key with the width multiplied by 's'. */
|
||||
public Key scaleWidth(float s)
|
||||
{
|
||||
return new Key(key0, key1, key2, key3, key4, width * s, shift, edgekeys);
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract interface MapKeys
|
||||
public static abstract interface MapKeys extends Function<KeyValue, KeyValue> { }
|
||||
|
||||
/** Parsing utils */
|
||||
|
||||
/** Returns [false] on [END_DOCUMENT] or [END_TAG], [true] otherwise. */
|
||||
private static boolean expect_tag(XmlResourceParser parser, String name) throws Exception
|
||||
{
|
||||
public abstract KeyValue map(KeyValue k);
|
||||
}
|
||||
|
||||
public static class ReplaceKeysByFlags implements MapKeys
|
||||
{
|
||||
private final int _flags;
|
||||
private final KeyValue _replacement;
|
||||
|
||||
public ReplaceKeysByFlags(int flags, KeyValue r)
|
||||
int status;
|
||||
do
|
||||
{
|
||||
_flags = flags;
|
||||
_replacement = r;
|
||||
}
|
||||
|
||||
public KeyValue map(KeyValue k)
|
||||
{
|
||||
return (k != null && (k.flags & _flags) != 0) ? _replacement : k;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ReplaceKeysByEvent implements MapKeys
|
||||
{
|
||||
private final int _eventCode;
|
||||
private final KeyValue _replacement;
|
||||
|
||||
public ReplaceKeysByEvent(int ev, KeyValue r)
|
||||
{
|
||||
_eventCode = ev;
|
||||
_replacement = r;
|
||||
}
|
||||
|
||||
public KeyValue map(KeyValue k)
|
||||
{
|
||||
return (k != null && k.eventCode == _eventCode) ? _replacement : k;
|
||||
}
|
||||
}
|
||||
|
||||
/* Replace two keys at the same time. Used for swaping keys. */
|
||||
public static class ReplaceKeysByEvent2 implements MapKeys
|
||||
{
|
||||
private final int _e1;
|
||||
private final KeyValue _r1;
|
||||
private final int _e2;
|
||||
private final KeyValue _r2;
|
||||
|
||||
public ReplaceKeysByEvent2(int e1, KeyValue r1, int e2, KeyValue r2)
|
||||
{
|
||||
_e1 = e1;
|
||||
_r1 = r1;
|
||||
_e2 = e2;
|
||||
_r2 = r2;
|
||||
}
|
||||
|
||||
public KeyValue map(KeyValue k)
|
||||
{
|
||||
if (k == null)
|
||||
return null;
|
||||
if (k.eventCode == _e1) return _r1;
|
||||
if (k.eventCode == _e2) return _r2;
|
||||
return k;
|
||||
status = parser.next();
|
||||
if (status == XmlResourceParser.END_DOCUMENT || status == XmlResourceParser.END_TAG)
|
||||
return false;
|
||||
}
|
||||
while (status != XmlResourceParser.START_TAG);
|
||||
if (!parser.getName().equals(name))
|
||||
throw new Exception("Unknow tag: " + parser.getName());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
322
srcs/juloo.keyboard2/Pointers.java
Normal file
322
srcs/juloo.keyboard2/Pointers.java
Normal file
@@ -0,0 +1,322 @@
|
||||
package juloo.keyboard2;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Manage pointers (fingers) on the screen and long presses.
|
||||
* Call back to IPointerEventHandler.
|
||||
*/
|
||||
public final class Pointers implements Handler.Callback
|
||||
{
|
||||
private Handler _keyrepeat_handler;
|
||||
private ArrayList<Pointer> _ptrs = new ArrayList<Pointer>();
|
||||
private IPointerEventHandler _handler;
|
||||
private Config _config;
|
||||
|
||||
public Pointers(IPointerEventHandler h, Config c)
|
||||
{
|
||||
_keyrepeat_handler = new Handler(this);
|
||||
_handler = h;
|
||||
_config = c;
|
||||
}
|
||||
|
||||
public int getFlags()
|
||||
{
|
||||
int flags = 0;
|
||||
for (Pointer p : _ptrs)
|
||||
flags |= p.flags;
|
||||
return flags;
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
_ptrs.clear();
|
||||
}
|
||||
|
||||
public boolean isKeyDown(KeyboardData.Key k)
|
||||
{
|
||||
for (Pointer p : _ptrs)
|
||||
if (p.key == k)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* These flags can be different:
|
||||
* FLAG_LOCK Removed when the key is locked
|
||||
* FLAG_LOCKED Added when the key is locked
|
||||
* FLAG_LATCH Removed when the key is latched (released but not consumed yet)
|
||||
* Returns [-1] if not found.
|
||||
*/
|
||||
public int getKeyFlags(KeyValue kv)
|
||||
{
|
||||
for (Pointer p : _ptrs)
|
||||
if (p.value != null && p.value.name == kv.name) // Physical equality
|
||||
return p.flags;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Receiving events
|
||||
|
||||
public void onTouchUp(int pointerId)
|
||||
{
|
||||
Pointer ptr = getPtr(pointerId);
|
||||
if (ptr == null)
|
||||
return;
|
||||
stopKeyRepeat(ptr);
|
||||
Pointer latched = getLatched(ptr.value);
|
||||
if (latched != null) // Already latched
|
||||
{
|
||||
removePtr(ptr); // Remove dupplicate
|
||||
if ((latched.flags & KeyValue.FLAG_LOCK) != 0) // Locking key, toggle lock
|
||||
{
|
||||
latched.flags = (latched.flags & ~KeyValue.FLAG_LOCK) | KeyValue.FLAG_LOCKED;
|
||||
_handler.onPointerFlagsChanged();
|
||||
}
|
||||
else // Otherwise, unlatch
|
||||
{
|
||||
removePtr(latched);
|
||||
_handler.onPointerUp(ptr.value);
|
||||
}
|
||||
}
|
||||
else if ((ptr.flags & KeyValue.FLAG_LATCH) != 0)
|
||||
{
|
||||
ptr.flags &= ~KeyValue.FLAG_LATCH;
|
||||
ptr.pointerId = -1; // Latch
|
||||
_handler.onPointerFlagsChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
clearLatched();
|
||||
removePtr(ptr);
|
||||
_handler.onPointerUp(ptr.value);
|
||||
}
|
||||
}
|
||||
|
||||
public void onTouchCancel(int pointerId)
|
||||
{
|
||||
Pointer ptr = getPtr(pointerId);
|
||||
if (ptr == null)
|
||||
return;
|
||||
stopKeyRepeat(ptr);
|
||||
removePtr(ptr);
|
||||
_handler.onPointerFlagsChanged();
|
||||
}
|
||||
|
||||
public void onTouchDown(float x, float y, int pointerId, KeyboardData.Key key)
|
||||
{
|
||||
// Ignore new pointers that are too close to an existing pointer. This
|
||||
// might be glitches.
|
||||
if (isPointerNearby(x, y))
|
||||
return;
|
||||
KeyValue value = key.key0;
|
||||
Pointer ptr = new Pointer(pointerId, key, value, x, y);
|
||||
_ptrs.add(ptr);
|
||||
if (value != null && (value.flags & KeyValue.FLAG_NOREPEAT) == 0)
|
||||
startKeyRepeat(ptr);
|
||||
_handler.onPointerDown(value);
|
||||
}
|
||||
|
||||
public void onTouchMove(float x, float y, int pointerId)
|
||||
{
|
||||
Pointer ptr = getPtr(pointerId);
|
||||
if (ptr == null)
|
||||
return;
|
||||
float dx = x - ptr.downX;
|
||||
float dy = y - ptr.downY;
|
||||
float dist = Math.abs(dx) + Math.abs(dy);
|
||||
ptr.ptrDistX = dx;
|
||||
ptr.ptrDistY = dy;
|
||||
KeyValue newValue;
|
||||
if (dist < _config.swipe_dist_px)
|
||||
{
|
||||
newValue = ptr.key.key0;
|
||||
}
|
||||
else if (ptr.key.edgekeys)
|
||||
{
|
||||
if (Math.abs(dy) > Math.abs(dx)) // vertical swipe
|
||||
newValue = (dy < 0) ? ptr.key.key1 : ptr.key.key4;
|
||||
else // horizontal swipe
|
||||
newValue = (dx < 0) ? ptr.key.key3 : ptr.key.key2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dx < 0) // left side
|
||||
newValue = (dy < 0) ? ptr.key.key1 : ptr.key.key3;
|
||||
else // right side
|
||||
newValue = (dy < 0) ? ptr.key.key2 : ptr.key.key4;
|
||||
}
|
||||
if (newValue != null && newValue != ptr.value)
|
||||
{
|
||||
int old_flags = (ptr.value != null) ? ptr.value.flags : 0;
|
||||
ptr.value = newValue;
|
||||
ptr.flags = newValue.flags;
|
||||
if ((old_flags & newValue.flags & KeyValue.FLAG_PRECISE_REPEAT) != 0)
|
||||
{
|
||||
// Keep the keyrepeat going between modulated keys.
|
||||
}
|
||||
else
|
||||
{
|
||||
stopKeyRepeat(ptr);
|
||||
if ((newValue.flags & KeyValue.FLAG_NOREPEAT) == 0)
|
||||
startKeyRepeat(ptr);
|
||||
_handler.onPointerSwipe(newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pointers management
|
||||
|
||||
private Pointer getPtr(int pointerId)
|
||||
{
|
||||
for (Pointer p : _ptrs)
|
||||
if (p.pointerId == pointerId)
|
||||
return p;
|
||||
return null;
|
||||
}
|
||||
|
||||
private void removePtr(Pointer ptr)
|
||||
{
|
||||
_ptrs.remove(ptr);
|
||||
}
|
||||
|
||||
private Pointer getLatched(KeyValue kv)
|
||||
{
|
||||
for (Pointer p : _ptrs)
|
||||
if (p.value == kv && p.pointerId == -1)
|
||||
return p;
|
||||
return null;
|
||||
}
|
||||
|
||||
private void clearLatched()
|
||||
{
|
||||
for (int i = _ptrs.size() - 1; i >= 0; i--)
|
||||
{
|
||||
Pointer ptr = _ptrs.get(i);
|
||||
// Latched and not locked, remove
|
||||
if (ptr.pointerId == -1 && (ptr.flags & KeyValue.FLAG_LOCKED) == 0)
|
||||
_ptrs.remove(i);
|
||||
// Not latched but pressed, don't latch once released
|
||||
else if ((ptr.flags & KeyValue.FLAG_LATCH) != 0)
|
||||
ptr.flags &= ~KeyValue.FLAG_LATCH;
|
||||
}
|
||||
}
|
||||
|
||||
/** Check if a pointer is within a radius of 'pointerTooClose' */
|
||||
private boolean isPointerNearby(float x, float y)
|
||||
{
|
||||
for (Pointer p : _ptrs)
|
||||
{
|
||||
float dx = p.downX + p.ptrDistX - x;
|
||||
float dy = p.downY + p.ptrDistY - y;
|
||||
float d = Math.abs(dx) + Math.abs(dy);
|
||||
if (d < _config.pointerTooClose)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Key repeat
|
||||
|
||||
/** Message from [_keyrepeat_handler]. */
|
||||
@Override
|
||||
public boolean handleMessage(Message msg)
|
||||
{
|
||||
for (Pointer ptr : _ptrs)
|
||||
{
|
||||
if (ptr.timeoutWhat == msg.what)
|
||||
{
|
||||
long nextInterval = _config.longPressInterval;
|
||||
if (_config.preciseRepeat && (ptr.flags & KeyValue.FLAG_PRECISE_REPEAT) != 0)
|
||||
{
|
||||
// Slower repeat for modulated keys
|
||||
nextInterval *= 2;
|
||||
// Modulate repeat interval depending on the distance of the pointer
|
||||
nextInterval = (long)((float)nextInterval / modulatePreciseRepeat(ptr));
|
||||
}
|
||||
_keyrepeat_handler.sendEmptyMessageDelayed(msg.what, nextInterval);
|
||||
_handler.onPointerHold(ptr.value);
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
private static int uniqueTimeoutWhat = 0;
|
||||
|
||||
private void startKeyRepeat(Pointer ptr)
|
||||
{
|
||||
int what = (uniqueTimeoutWhat++);
|
||||
ptr.timeoutWhat = what;
|
||||
long timeout = _config.longPressTimeout;
|
||||
// Faster repeat timeout for modulated keys
|
||||
if ((ptr.flags & KeyValue.FLAG_PRECISE_REPEAT) != 0)
|
||||
timeout /= 2;
|
||||
_keyrepeat_handler.sendEmptyMessageDelayed(what, timeout);
|
||||
}
|
||||
|
||||
private void stopKeyRepeat(Pointer ptr)
|
||||
{
|
||||
if (ptr.timeoutWhat != -1)
|
||||
{
|
||||
_keyrepeat_handler.removeMessages(ptr.timeoutWhat);
|
||||
ptr.timeoutWhat = -1;
|
||||
ptr.repeatingPtrDist = -1.f;
|
||||
}
|
||||
}
|
||||
|
||||
private float modulatePreciseRepeat(Pointer ptr)
|
||||
{
|
||||
float ptrDist = Math.abs(ptr.ptrDistX) + Math.abs(ptr.ptrDistY);
|
||||
if (ptr.repeatingPtrDist < 0.f)
|
||||
ptr.repeatingPtrDist = ptrDist; // First repeat
|
||||
if (ptrDist > ptr.repeatingPtrDist * 2.f)
|
||||
ptr.repeatingPtrDist = ptrDist / 2.f; // Large swipe, move the middle point
|
||||
float left = ptr.repeatingPtrDist / 2.f;
|
||||
float accel = (ptrDist - left) / (ptr.repeatingPtrDist - left);
|
||||
return Math.min(8.f, Math.max(0.1f, accel));
|
||||
}
|
||||
|
||||
private final class Pointer
|
||||
{
|
||||
/** -1 when latched. */
|
||||
public int pointerId;
|
||||
public KeyboardData.Key key;
|
||||
public KeyValue value;
|
||||
public float downX;
|
||||
public float downY;
|
||||
/** Distance of the pointer to the initial press. */
|
||||
public float ptrDistX;
|
||||
public float ptrDistY;
|
||||
public int flags;
|
||||
/** Identify timeout messages. */
|
||||
public int timeoutWhat;
|
||||
/** ptrDist at the first repeat, -1 otherwise. */
|
||||
public float repeatingPtrDist;
|
||||
|
||||
public Pointer(int p, KeyboardData.Key k, KeyValue v, float x, float y)
|
||||
{
|
||||
pointerId = p;
|
||||
key = k;
|
||||
value = v;
|
||||
downX = x;
|
||||
downY = y;
|
||||
ptrDistX = 0.f;
|
||||
ptrDistY = 0.f;
|
||||
flags = (v == null) ? 0 : v.flags;
|
||||
timeoutWhat = -1;
|
||||
repeatingPtrDist = -1.f;
|
||||
}
|
||||
}
|
||||
|
||||
public interface IPointerEventHandler
|
||||
{
|
||||
public void onPointerDown(KeyValue k);
|
||||
public void onPointerSwipe(KeyValue k);
|
||||
public void onPointerUp(KeyValue k);
|
||||
public void onPointerFlagsChanged();
|
||||
public void onPointerHold(KeyValue k);
|
||||
}
|
||||
}
|
@@ -16,9 +16,6 @@ public class Theme
|
||||
public final int labelColor;
|
||||
public final int subLabelColor;
|
||||
|
||||
public final float labelTextSize;
|
||||
public final float sublabelTextSize;
|
||||
|
||||
public final float keyBorderRadius;
|
||||
|
||||
private final Paint _keyLabelPaint;
|
||||
@@ -38,9 +35,6 @@ public class Theme
|
||||
subLabelColor = s.getColor(R.styleable.keyboard_colorSubLabel, 0);
|
||||
keyBorderRadius = s.getDimension(R.styleable.keyboard_keyBorderRadius, 0);
|
||||
s.recycle();
|
||||
Resources res = context.getResources();
|
||||
labelTextSize = res.getDimension(R.dimen.label_text_size);
|
||||
sublabelTextSize = res.getDimension(R.dimen.sublabel_text_size);
|
||||
_keyLabelPaint = initLabelPaint(Paint.Align.CENTER, null);
|
||||
_keySubLabelPaint = initLabelPaint(Paint.Align.LEFT, null);
|
||||
Typeface specialKeyFont = getSpecialKeyFont(context);
|
||||
@@ -54,10 +48,10 @@ public class Theme
|
||||
return p;
|
||||
}
|
||||
|
||||
public Paint subLabelPaint(boolean special_font, boolean align_right)
|
||||
public Paint subLabelPaint(boolean special_font, Paint.Align align)
|
||||
{
|
||||
Paint p = special_font ? _specialKeySubLabelPaint : _keySubLabelPaint;
|
||||
p.setTextAlign(align_right ? Paint.Align.RIGHT : Paint.Align.LEFT);
|
||||
p.setTextAlign(align);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user