Compare commits

...

31 Commits

Author SHA1 Message Date
Jules Aguillon
96c4b165ac Release 1.11.0 (14) 2022-01-16 23:50:11 +01:00
Jules Aguillon
40897f2c26 Update and improve the description
Explain better what the app is and mention some of the features.

Unfortunately, the German translation needs to be dropped because I
can't maintain it.
2022-01-16 23:44:04 +01:00
Moini
133b6ec2c1 German keyboard added (#20)
* Add German metadata translation

* Add German keyboard

Co-authored-by: Jules Aguillon <jules@j3s.fr>
2022-01-15 20:56:08 +01:00
Jules Aguillon
833dfa31bb Fix miscalculation of the space between the keys
'keyVerticalInterval' was mistakenly used to compute the height of the
keyboard and the vertical position of keys.
While the code handling pointers did not use this value, the hit box of
the bottom row was shifted by several pixels.

Make sure 'keyVerticalInterval' is only used for rendering and not for
placing the keys.
2022-01-15 20:24:27 +01:00
Jules Aguillon
fa9250a89e Contributing: Mention enabling the virtual keyboard 2022-01-15 19:51:40 +01:00
Jules Aguillon
854eb431f3 CONTRIBUTING: Document debug installation failure 2022-01-15 19:03:53 +01:00
Jules Aguillon
d4eef00a8a Add a CONTRIBUTING guide 2022-01-15 18:55:05 +01:00
Jules Aguillon
f22d040eda Update screenshots 2022-01-10 01:02:14 +01:00
Jules Aguillon
dfec26a93b Swap the Enter and Action keys when needed
When IME_FLAG_NO_ENTER_ACTION is set.
2022-01-10 00:27:22 +01:00
Jules Aguillon
53113cadd9 Add the Action key
It is placed on the top-right of the enter key on every layouts.
It sends a special event (performEditorAction) instead of writing a
newline.

The "actionId" is passed through the EditorInfo object in an obfuscated
way so it's not clear whether it's using the right one.
2022-01-09 20:26:06 +01:00
Moini
4b43645c4b Fix a few strings 2022-01-09 12:53:14 +01:00
Jules Aguillon
93e84ba7e9 Add the German language
Add the 'ß' character on the bottom-left corner of the 's' key, which is
hidden for other languages.

Co-authored-by: Moini <moini@noreply.invalid>
2022-01-09 12:49:28 +01:00
Jules Aguillon
23e59c6b09 Allow to hide more keys than just accents
Add the "FLAGS_LANGS" set of flags, which will be used to hide
individual keys that are not accents.
2022-01-09 12:47:47 +01:00
Jules Aguillon
2764e96eb1 Change the key combination for °
To Fn+*

Was previously accent^+*, which was not available for most languages.
2022-01-01 19:00:27 +01:00
Jules Aguillon
9c82c9cfdc Improve the "precision" option
Now named "swiping distance". Changed to a dropdown.
2021-12-30 22:22:25 +01:00
Jules Aguillon
8bef0728ae Turn the "precision" option to dp instead of px 2021-12-30 21:59:48 +01:00
Jules Aguillon
b05f6e8447 Simplify string definitions
Inline constants in settings.xml, strings.xml is only for strings that
can be translated.
2021-12-30 21:37:34 +01:00
Jules Aguillon
f69a0605a8 Add the Black theme
Friendly to Amoled screens.
The background of keys is the same as the background of the whole
keyboard: pure black.
Colors are also slightly stronger.
2021-12-30 00:53:48 +01:00
Jules Aguillon
29367f127d Move the border radius from Config to Theme
Also, draw activated keys with a round border too.
2021-12-30 00:52:50 +01:00
Jules Aguillon
093a00c572 Add themes
Add a "Theme" option to choose between a dark and light theme.
The light theme uses the colors of the dark theme with the luminance
inversed.

The reloading after a configuration change is changed slightly:
- Special handling is needed when the Theme is changed (recreate the views)
- The default implementation of 'onConfigurationChanged' is used
  Which triggers more refresh (but don't recreate the views)
- 'onCreateInputView' is no longer needed
2021-12-30 00:26:05 +01:00
Jules Aguillon
40b1ec63a9 Use the themes abstraction
Themes replace 'colors.xml' and soon will replace 'dimens.xml'.
2021-12-28 19:12:50 +01:00
Jules Aguillon
93704cca0a Reference the "special key font" in the Theme object
Remove the last cast of the context.
2021-12-28 17:53:58 +01:00
Jules Aguillon
15ce200ce3 Separate "handler" code
As with the previous commit, remove casts of the context.
The "handler" object is referenced in the "config" object for now.
2021-12-28 17:47:18 +01:00
Jules Aguillon
0190cfc29a Turn Config into a singleton object
The goal is to remove a cast of the 'context' into 'Keyboard2'.
2021-12-28 16:47:19 +01:00
Jules Aguillon
dd24ad323b Move Theme code to its own class 2021-12-26 23:55:18 +01:00
Jules Aguillon
86655d4959 Always send the keycode for the tab key
Don't write the tab character and always send the keycode, which is most
probably handled by applications.
2021-12-22 20:40:39 +01:00
Jules Aguillon
3e332dbf54 Use the right keycode for the home key
The previous keycode wasn't the classical "home" movement key but
Android's actual home key, which has no effect when generated from the
keyboard.
2021-12-22 20:19:59 +01:00
Jules Aguillon
d721cc86d1 Avoid crash when removing a layout
Might happen when downgrading the app.
2021-12-19 20:04:17 +01:00
Jules Aguillon
1cfecbdf48 Auto-format Java and XML files
Use xmllint.
Re-indent Java files using spaces.
2021-12-19 19:44:27 +01:00
Jules Aguillon
988d8db7e8 Use apksigner for signing the apk
The Play Store now requires the "Signing Scheme V2", which is
implemented by apksigner.
2021-12-14 00:13:34 +01:00
Jules Aguillon
e5fa23e1f7 Upgrade to Android SDK version 30 2021-12-12 23:48:05 +01:00
52 changed files with 1736 additions and 1413 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
*.keystore
_build
/*-keystore.conf

View File

@@ -1,38 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="juloo.keyboard2"
android:versionCode="13"
android:versionName="1.10.0"
android:hardwareAccelerated="false">
<uses-sdk android:minSdkVersion="4"
android:targetSdkVersion="29" />
<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">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="juloo.keyboard2" android:versionCode="14" android:versionName="1.11.0" 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">
<intent-filter>
<action android:name="android.view.InputMethod" />
<action android:name="android.view.InputMethod"/>
</intent-filter>
<meta-data android:name="android.view.im"
android:resource="@xml/method" />
<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">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.VIBRATE"/>
</manifest>

62
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,62 @@
# Contributing
Thanks for contributing :)
## Building the app
The application doesn't use Gradle and it might be hard to use some features of
Android Studio.
Fortunately, there's not many dependencies:
- OpenJDK 8
- Android SDK: build tools `30.0.3`, 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.
Building the debug apk:
```sh
make
```
If the build succeed, the debug apk is located in
`_build/juloo.keyboard2.debug.apk`.
## Debugging on your phone
You need to have *USB debugging* enabled on your phone, see [Android's doc](https://developer.android.com/studio/debug/dev-options#enable).
It is also possible to enable *ADB over network* in the settings and connect
with `adb connect <ip of the phone>`. Make sure to be connected to a local
network that you trust.
Install the application with:
```sh
make installd
```
The debug version of the application won't be removed, both versions will stay
installed at the same time.
The application must be enabled in the settings:
System Settings > System > Languages & Input > Virtual keyboard > Manage keyboards.
## Debugging the application: INSTALL_FAILED_UPDATE_INCOMPATIBLE
`make installd` can fail with the following error message:
```
adb: failed to install _build/juloo.keyboard2.debug.apk: Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package juloo.keyboard2.debug signatures do not match previously installed version; ignoring!]
make: *** [Makefile:20: installd] Error 1
```
The application can't be "updated" because the temporary certificate has been
lost. The solution is to uninstall and install again.
The application must be enabled again in the settings.
```sh
adb uninstall juloo.keyboard2.debug
make installd
```

View File

@@ -2,7 +2,7 @@
PACKAGE_NAME = juloo.keyboard2
ANDROID_PLATFORM_VERSION = android-29
ANDROID_PLATFORM_VERSION = android-30
JAVA_VERSION = 1.7
SRC_DIR = srcs
@@ -44,11 +44,6 @@ JAVA_FILES = $(shell find $(SRC_DIR) -name '*.java')
RES_FILES = $(shell find $(RES_DIR) -type f)
ASSETS_FILES = $(shell find $(ASSETS_DIR) -type f 2>/dev/null)
# Align
_build/%.apk: _build/%.signed-apk
$(ANDROID_BUILD_TOOLS)/zipalign -fp 4 "$<" "$@"
# Debug signing
DEBUG_KEYSTORE = _build/debug.keystore
@@ -59,7 +54,7 @@ $(DEBUG_KEYSTORE):
-alias debug -keypass $(DEBUG_PASSWD) -keystore "$@" \
-keyalg rsa -storepass $(DEBUG_PASSWD) -validity 10000
_build/%.debug.signed-apk: _build/%.debug.unsigned-apk $(DEBUG_KEYSTORE)
_build/%.debug.apk: _build/%.debug.unsigned-apk $(DEBUG_KEYSTORE)
jarsigner -keystore $(DEBUG_KEYSTORE) \
-storepass $(DEBUG_PASSWD) -keypass $(DEBUG_PASSWD) \
-signedjar "$@" "$<" debug
@@ -70,16 +65,19 @@ _build/$(PACKAGE_NAME).debug.unsigned-apk: AAPT_PACKAGE_FLAGS+=--rename-manifest
# Release signing
# %-keystore.conf should declare KEYSTORE, KEYNAME and OPTS
# %-keystore.conf should declare KEYSTORE, KEYNAME and KEYSTOREPASS
# it is interpreted as a shell script
# OPTS can be used to pass -storepass or -keypass options to jarsigner
_build/%.signed-apk: _build/%.unsigned-apk %-keystore.conf
_build/%.apk: _build/%.unsigned-apk %-keystore.conf
eval `cat $(word 2,$^)` && \
jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore "$$KEYSTORE" $$OPTS -signedjar "$@" "$<" "$$KEYNAME"
apksigner sign --in "$<" --out "$@" \
--ks "$$KEYSTORE" --ks-key-alias "$$KEYNAME" --ks-pass "pass:$$KEYSTOREPASS"
# Package
_build/%.unsigned-apk: _build/classes.dex $(MANIFEST_FILE) $(ASSETS_FILES)
_build/%.unsigned-apk: _build/%.unaligned-apk
$(ANDROID_BUILD_TOOLS)/zipalign -fp 4 "$<" "$@"
_build/%.unaligned-apk: _build/classes.dex $(MANIFEST_FILE) $(ASSETS_FILES)
$(ANDROID_BUILD_TOOLS)/aapt package -f -M $(MANIFEST_FILE) -S $(RES_DIR) \
-I $(ANDROID_PLATFORM)/android.jar -F "$@" $(AAPT_PACKAGE_FLAGS)
[ -z "$(ASSETS_FILES)" ] || $(ANDROID_BUILD_TOOLS)/aapt add "$@" $(ASSETS_FILES)

View File

@@ -2,15 +2,32 @@
A lightweight virtual keyboard for developers.
![Unexpected Keyboard](play_store/capture1.png)
![Unexpected Keyboard](metadata/android/en-US/images/featureGraphic.png)
All the characters you might need are available on a single screen, as well as control, alt, escape and many others.
This app is a virtual keyboard for Android. The main features are easy typing of every ASCII character using the swipe gesture, dead keys for accents and modifier keys and the presence of special keys (tab, esc, arrows, etc..).
Several characters are displayed on each key. Get the one in the middle with a press and the ones in the corners by sliding your finger.
The keyboard shows up to 4 extra characters in the corners of each key. These extra characters are hit by swiping the finger on the key.
Like any other keyboard app, you will need to activate it in the system settings to be able to use it.
This can be found in the System Settings > System > Languages & Input > Virtual keyboard > Manage keyboards.
Highlight of some of the features:
- Every character and special keys that are also available on a PC keyboard. This is perfect for using applications like Termux.
- This includes Tab, Esc, the arrows and function keys, but also Ctrl and Alt !
- Accented keys are accessible using dead keys. First activate the accent, then type the accented letter.
- Very light and fast. Use 500x times less space than Google's keyboard and 15x times less than the default keyboard. No ad, no tracking.
- Multiple layouts: QWERTY, QWERTZ, AZERTY. Themes: White, Dark, OLED Black. And many other options.
Like any other virtual keyboards, it must be enabled in the system settings. Open the System Settings and go to:
System > Languages & Input > Virtual keyboard > Manage 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/)
## Contributing
For instructions on building the application, see
[Contributing](Contributing.md).

View File

@@ -0,0 +1 @@
Eine schlanke Bildschirmtastatur für Entwickler

View File

@@ -0,0 +1 @@
Unexpected Keyboard

View File

@@ -1 +1 @@
First open-source release !
First open-source release!

View File

@@ -0,0 +1,8 @@
New languages: German
New keyboard layouts: QWERTZ
Added themes: White, Dark and OLED Black
Added the Action key near the Enter key, required for some app.
Improved some options and fixed a few bugs.

View File

@@ -1,6 +1,18 @@
All the characters you might need are available on a single screen, as well as control, alt, escape and many others.
This app is a virtual keyboard for Android. The main features are easy typing of every ASCII character using the swipe gesture, dead keys for accents and modifier keys and the presence of special keys (tab, esc, arrows, etc..).
Several characters are displayed on each key. Get the one in the middle with a press and the ones in the corners by sliding your finger.
The keyboard shows up to 4 extra characters in the corners of each key. These extra characters are hit by swiping the finger on the key.
Like any other keyboard app, you will need to activate it in the system settings to be able to use it.
This can be found in the System Settings > System > Languages & Input > Virtual keyboard > Manage keyboards.
Highlight of some of the features:
- Every character and special keys that are also available on a PC keyboard. This is perfect for using applications like Termux.
- This includes Tab, Esc, the arrows and function keys, but also Ctrl and Alt !
- Accented keys are accessible using dead keys. First activate the accent, then type the accented letter.
- Very light and fast. Use 500x times less space than Google's keyboard and 15x times less than the default keyboard. No ad, no tracking.
- Multiple layouts: QWERTY, QWERTZ, AZERTY. Themes: White, Dark, OLED Black. And many other options.
Like any other virtual keyboards, it must be enabled in the system settings. Open the System Settings and go to:
System > Languages & Input > Virtual keyboard > Manage keyboards.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@@ -0,0 +1,8 @@
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.

View File

@@ -1,3 +1,18 @@
Tous les caractères dont vous pourriez avoir besoin sont disponibles sur un seul écran, ainsi que les touches control, alt, escape et bien d'autres.
Cette application est un clavier virtuel pour Android. Les fonctionnalités principales sont l'accès rapide à tous les caractères ASCII en glissant le doigt, les touches mortes pour les accents et la présence des touches spéciales (Tab, Esc, les flèches, etc..).
Plusieurs caractères sont affichés sur chaque touche. Tapez celui du milieu par une simple pression et ceux des coins en faisant glisser votre doigt.
Il peut y avoir un caractère supplémentaire dans chaque coin de chaque touche. Ces caractères sont tapés en glissant le doigt sur la touche.
Quelques fonctionnalités:
- Tous les caractères et toutes les touches spéciales d'un clavier PC. Idéal pour utiliser une application comme Termux.
- Cela comprend les touches Tab, Esc, les flèches et les touches fonctions mais aussi Ctrl et Alt !
- Les accents sont des touches mortes. Activez d'abord l'accent et tapez ensuite la lettre accentuée.
- Léger et rapide. Utilise 500x fois moins d'espace que le clavier de Google et 15x fois moins que le clavier de base. Pas de pub, pas de traqueur.
- Plusieurs configurations: QWERTY, QWERTZ, AZERTY. Thèmes: Clair, Sombre, Noir OLED. Et beaucoup d'autres options.
Comme tous les claviers virtuels, il doit être activé dans les paramètres systèmes. Ouvrez les paramètres et allez dans:
Système > Langue & Saisie > Clavier virtuel > Gérer.

View File

@@ -1,38 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:hardwareAccelerated="false">
<juloo.keyboard2.EmojiGroupButtonsBar
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<juloo.keyboard2.EmojiGridView
android:id="@+id/emoji_grid"
android:background="@color/bg"
android:layout_width="fill_parent"
android:layout_height="@dimen/emoji_grid_height"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<juloo.keyboard2.EmojiKeyButton
style="@style/emojiKeyButton"
key="switch_back_emoji"
/>
<juloo.keyboard2.EmojiKeyButton
style="@style/emojiKeyButton"
android:layout_weight="4"
key="space"
/>
<juloo.keyboard2.EmojiKeyButton
style="@style/emojiKeyButton"
key="backspace"
/>
<juloo.keyboard2.EmojiKeyButton
style="@style/emojiKeyButton"
key="enter"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:hardwareAccelerated="false">
<juloo.keyboard2.EmojiGroupButtonsBar android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
<juloo.keyboard2.EmojiGridView android:id="@+id/emoji_grid" android:background="?attr/colorKeyboard" android:layout_width="fill_parent" android:layout_height="@dimen/emoji_grid_height"/>
<LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content">
<juloo.keyboard2.EmojiKeyButton style="@style/emojiKeyButton" key="switch_back_emoji"/>
<juloo.keyboard2.EmojiKeyButton style="@style/emojiKeyButton" android:layout_weight="4" key="space"/>
<juloo.keyboard2.EmojiKeyButton style="@style/emojiKeyButton" key="backspace"/>
<juloo.keyboard2.EmojiKeyButton style="@style/emojiKeyButton" key="enter"/>
</LinearLayout>
</LinearLayout>

View File

@@ -1,5 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<juloo.keyboard2.Keyboard2View xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/bg"
android:hardwareAccelerated="false"
/>
<juloo.keyboard2.Keyboard2View xmlns:android="http://schemas.android.com/apk/res/android" android:hardwareAccelerated="false" android:background="?attr/colorKeyboard"/>

View File

@@ -4,10 +4,14 @@
<item>system</item>
<item>azerty</item>
<item>qwerty</item>
<item>qwertz</item>
</string-array>
<string-array name="pref_layout_entries">
<item>@string/pref_layout_e_system</item>
<item>AZERTY</item>
<item>QWERTY</item>
<item>QWERTZ</item>
</string-array>
<string name="pref_accents_default">1</string>
<string-array name="pref_accents_entries">
<item>@string/pref_accents_e_all_installed</item>
<item>@string/pref_accents_e_selected</item>
@@ -20,4 +24,28 @@
<item>3</item>
<item>4</item>
</string-array>
<string-array name="pref_theme_entries">
<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>dark</item>
<item>light</item>
<item>black</item>
</string-array>
<string-array name="pref_swipe_dist_entries">
<item>@string/pref_swipe_dist_e_very_short</item>
<item>@string/pref_swipe_dist_e_short</item>
<item>@string/pref_swipe_dist_e_default</item>
<item>@string/pref_swipe_dist_e_far</item>
<item>@string/pref_swipe_dist_e_very_far</item>
</string-array>
<string-array name="pref_swipe_dist_values">
<item>5</item>
<item>7.5</item>
<item>15</item>
<item>25</item>
<item>35</item>
</string-array>
</resources>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="bg" type="color">#1B1B1B</item>
<item name="key_bg" type="color">#303030</item>
<item name="key_down_bg" type="color">#1B1B1B</item>
<item name="key_label" type="color">#FFFFFF</item>
<item name="key_label_locked" type="color">#229933</item>
<item name="key_label_activated" type="color">#226b99</item>
<item name="key_sub_label" type="color">#A0A0A0</item>
<item name="emoji_button_bg" type="color">#202020</item>
<item name="emoji_color" type="color">#FFFFFF</item>
<item name="emoji_key_bg" type="color">@color/emoji_button_bg</item>
<item name="emoji_key_text" type="color">@color/key_label</item>
</resources>

View File

@@ -7,9 +7,9 @@
<dimen name="key_vertical_interval">2dp</dimen>
<dimen name="key_horizontal_interval">2dp</dimen>
<dimen name="key_height">51dp</dimen>
<dimen name="key_round">5dp</dimen>
<dimen name="label_text_size">18dp</dimen>
<dimen name="sublabel_text_size">12dp</dimen>
<dimen name="emoji_type_button_height">56dp</dimen>
<dimen name="emoji_grid_height">250dp</dimen>
<dimen name="emoji_text_size">28dp</dimen>
</resources>

View File

@@ -1,51 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Unexpected Keyboard</string>
<string name="settings_activity_label">Unexpected Keyboard Settings</string>
<string name="subtype_label">%s</string>
<string name="pref_category_layout">Layout</string>
<string name="pref_layout_title">Change keyboard layout</string>
<string name="pref_layout_summary">%s</string>
<string-array name="pref_layout_entries">
<item>System settings</item>
<item>Azerty</item>
<item>Qwerty</item>
</string-array>
<string name="pref_layout_e_system">System settings</string>
<string name="pref_accents_title">Accents</string>
<string name="pref_accents_summary">%s</string>
<string name="pref_accents_e_all_installed">Show accents for all the installed languages</string>
<string name="pref_accents_e_selected">Show accents for the selected language</string>
<string name="pref_accents_e_all">Show every accents</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_preci_title">Precision</string>
<string name="pref_preci_summary">Distance of corner values (%spx)</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_timeout_summary">%sms</string>
<string name="pref_long_interval_title">Long press interval</string>
<string name="pref_long_interval_summary">%sms</string>
<string name="pref_category_vibrate">Vibration</string>
<string name="pref_vibrate_title">Vibration</string>
<string name="pref_vibrate_summary">Enable/Disable vibrations on key down</string>
<string name="pref_vibrate_summary">Enable/disable vibration on keypress</string>
<string name="pref_vibrate_duration_title">Duration</string>
<string name="pref_vibrate_duration_summary">%sms</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_category_style">Style</string>
<string name="pref_margin_bottom_title">Margin bottom</string>
<string name="pref_margin_bottom_summary">%sdp</string>
<string name="pref_key_height_title">Key height</string>
<string name="pref_key_height_summary">%sdp</string>
<string name="pref_horizontal_margin_title">Horizontal margin</string>
<string name="pref_horizontal_margin_summary">%sdp</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_dark">Dark</string>
<string name="pref_theme_e_light">Light</string>
<string name="pref_theme_e_black">Black</string>
<string name="pref_swipe_dist_e_very_short">Very short</string>
<string name="pref_swipe_dist_e_short">Short</string>
<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>
</resources>

View File

@@ -4,8 +4,8 @@
<item name="android:padding">1px</item>
<item name="android:gravity">center</item>
<item name="android:minHeight">@dimen/label_text_size</item>
<item name="android:background">@color/emoji_button_bg</item>
<item name="android:textColor">@color/emoji_key_text</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>
</style>
<style name="emojiKeyButton">
@@ -13,8 +13,13 @@
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1</item>
<item name="android:padding">0px</item>
<item name="android:background">@color/emoji_key_bg</item>
<item name="android:textColor">@color/emoji_key_text</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>
</style>
<!-- Passed to TextView.setTextAppearance -->
<style name="emojiGridButton">
<item name="android:textSize">@dimen/emoji_text_size</item>
<item name="android:textColor">?attr/emoji_color</item>
</style>
</resources>

66
res/values/themes.xml Normal file
View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="keyboard">
<!-- The background of the keyboard -->
<attr name="colorKeyboard" format="color"/>
<!-- Background of the keys -->
<attr name="colorKey" format="color"/>
<!-- Background of the keys when pressed -->
<attr name="colorKeyActivated" format="color"/>
<!-- Label colors -->
<attr name="colorLabel" format="color"/>
<attr name="colorLabelActivated" format="color"/>
<attr name="colorLabelLocked" format="color"/>
<!-- Corner labels -->
<attr name="colorSubLabel" format="color"/>
<!-- Dimens -->
<attr name="keyBorderRadius" format="dimension"/>
<!-- Emoji panel -->
<attr name="emoji_button_bg" type="color" format="color"/>
<attr name="emoji_color" type="color" format="color"/>
<attr name="emoji_key_bg" type="color" format="color"/>
<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="keyBorderRadius">5dp</item>
<item name="emoji_button_bg" type="color">#202020</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="colorKeyboard">#e3e3e3</item>
<item name="colorKey">#cfcfcf</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="keyBorderRadius">5dp</item>
<item name="emoji_button_bg" type="color">#dedede</item>
<item name="emoji_color" type="color">#000000</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="Black">
<item name="colorKeyboard">#000000</item>
<item name="colorKey">#000000</item>
<item name="colorKeyActivated">#333333</item>
<item name="colorLabel">#eeeeee</item>
<item name="colorLabelActivated">#009dff</item>
<item name="colorLabelLocked">#00ff26</item>
<item name="colorSubLabel">#bbbbbb</item>
<item name="keyBorderRadius">1dp</item>
<item name="emoji_button_bg" type="color">#000000</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>
</resources>

View File

@@ -1,44 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<keyboard>
<row>
<key key0="a" key1="esc" key2="1" key3="&amp;" />
<key key0="z" key2="2" key4="~" />
<key key0="e" key2="3" key3="&quot;" key4="\#" />
<key key0="r" key2="4" key3="'" />
<key key0="t" key2="5" key3="(" key4=")" />
<key key0="y" key2="6" key3="-" key4="|" />
<key key0="u" key2="7" key4="`" />
<key key0="i" key2="8" key3="_" key4="\\" />
<key key0="o" key2="9" />
<key key0="p" key2="0" key4="\@" />
<key key0="a" key1="esc" key2="1" key3="&amp;"/>
<key key0="z" key2="2" key4="~"/>
<key key0="e" key2="3" key3="&quot;" key4="\#"/>
<key key0="r" key2="4" key3="'"/>
<key key0="t" key2="5" key3="(" key4=")"/>
<key key0="y" key2="6" key3="-" key4="|"/>
<key key0="u" key2="7" key4="`"/>
<key key0="i" key2="8" key3="_" key4="\\"/>
<key key0="o" key2="9"/>
<key key0="p" key2="0" key4="\@"/>
</row>
<row>
<key key0="q" key1="tab" />
<key key0="s" key1="accent_ring" />
<key key0="d" key1="accent_grave" key3="accent_aigu" />
<key key0="f" key3="{" key4="}" />
<key key0="g" key3="[" key4="]" />
<key key0="h" key3="=" key4="+" />
<key key0="j" key1="accent_trema" key2="accent_circonflexe" key3="^" />
<key key0="k" key2="€" key3="$" key4="£" />
<key key0="l" key2="%" />
<key key0="m" key4="*" />
<key key0="q" key1="tab"/>
<key key0="s" key1="accent_ring" key3="ß"/>
<key key0="d" key1="accent_grave" key3="accent_aigu"/>
<key key0="f" key3="{" key4="}"/>
<key key0="g" key3="[" key4="]"/>
<key key0="h" key3="=" key4="+"/>
<key key0="j" key1="accent_trema" key2="accent_circonflexe" key3="^"/>
<key key0="k" key2="€" key3="$" key4="£"/>
<key key0="l" key2="%"/>
<key key0="m" key4="*"/>
</row>
<row>
<key width="2.0" key0="shift" />
<key key0="w" key3="&lt;" key4="&gt;" />
<key key0="x" />
<key key0="c" key1="accent_cedille" key3="," key4="\?" />
<key key0="v" key3=";" key4="." />
<key key0="b" key3=":" key4="/" />
<key key0="n" key1="accent_tilde" key2="§" key4="!" />
<key width="2.0" key0="backspace" key2="delete" />
<key width="2.0" key0="shift"/>
<key key0="w" key3="&lt;" key4="&gt;"/>
<key key0="x"/>
<key key0="c" key1="accent_cedille" key3="," key4="\?"/>
<key key0="v" key3=";" key4="."/>
<key key0="b" key3=":" key4="/"/>
<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" />
<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>

View File

@@ -1,40 +1,9 @@
<?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="@string/subtype_label"
android:languageTag="en"
android:imeSubtypeLocale="en_US"
android:imeSubtypeMode="keyboard"
android:isAsciiCapable="true"
android:imeSubtypeExtraValue="default_layout=qwerty"
/>
<subtype android:label="@string/subtype_label"
android:languageTag="fr"
android:imeSubtypeLocale="fr_FR"
android:imeSubtypeMode="keyboard"
android:isAsciiCapable="true"
android:imeSubtypeExtraValue="default_layout=azerty,accents=grave|aigu|circonflexe|cedille|trema"
/>
<subtype android:label="@string/subtype_label"
android:languageTag="es"
android:imeSubtypeLocale="es_ES"
android:imeSubtypeMode="keyboard"
android:isAsciiCapable="true"
android:imeSubtypeExtraValue="default_layout=qwerty,accents=aigu|tilde|trema"
/>
<subtype android:label="@string/subtype_label"
android:languageTag="it"
android:imeSubtypeLocale="it_IT"
android:imeSubtypeMode="keyboard"
android:isAsciiCapable="true"
android:imeSubtypeExtraValue="default_layout=qwerty,accents=grave|aigu"
/>
<subtype android:label="@string/subtype_label"
android:languageTag="sv"
android:imeSubtypeLocale="sv_SE"
android:imeSubtypeMode="keyboard"
android:isAsciiCapable="true"
android:imeSubtypeExtraValue="default_layout=qwerty,accents=aigu|trema|ring"
/>
<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"/>
</input-method>

View File

@@ -1,35 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<keyboard>
<row>
<key width="0.75" key0="esc" key2="~" key4="!" />
<key width="0.75" key0="(" key2="[" key4="{" />
<key key0="7" key3="&lt;" key4="&gt;" />
<key key0="8" key2="∞" />
<key key0="9" key2="π" />
<key width="0.75" key0="*" key1="√" key2="×" />
<key width="0.75" key0="/" key1="%" key3="÷" />
<key width="0.75" key0="esc" key2="~" key4="!"/>
<key width="0.75" key0="(" key2="[" key4="{"/>
<key key0="7" key3="&lt;" key4="&gt;"/>
<key key0="8" key2="∞"/>
<key key0="9" key2="π"/>
<key width="0.75" key0="*" key1="√" key2="×"/>
<key width="0.75" key0="/" key1="%" key3="÷"/>
</row>
<row>
<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="6" />
<key width="0.75" key0="+" key1="Σ" key2="$" />
<key width="0.75" key0="-" key2="^" />
<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="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="2" />
<key key0="3" />
<key width="1.15" key0="backspace" key2="delete" />
<key shift="0.35" width="1.15" key0="shift" key2="fn" key4="alt"/>
<key key0="1" key1="superscript" key3="subscript"/>
<key key0="2"/>
<key key0="3"/>
<key width="1.15" key0="backspace" key2="delete"/>
</row>
<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="space" key1="&quot;" key2="'" key4="_" />
<key width="1.5" key0="enter" key2=" key3="=" />
<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="space" key1="&quot;" key2="'" key4="_"/>
<key width="1.5" key0="enter" key1="±" key2="action" key3="="/>
</row>
</keyboard>

View File

@@ -1,44 +1,44 @@
<?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="\#" />
<key key0="r" key2="4" key3="$" />
<key key0="t" key2="5" key3="%" />
<key key0="y" key2="6" key3="^" />
<key key0="u" key2="7" key3="&amp;" />
<key key0="i" key2="8" key3="*" />
<key key0="o" key2="9" key3="(" key4=")" />
<key key0="p" key2="0" />
<key key0="q" key1="esc" key2="1" key3="~" key4="!"/>
<key key0="w" key2="2" key3="\@"/>
<key key0="e" key2="3" key3="\#"/>
<key key0="r" key2="4" key3="$"/>
<key key0="t" key2="5" key3="%"/>
<key key0="y" key2="6" key3="^"/>
<key key0="u" key2="7" key3="&amp;"/>
<key key0="i" key2="8" key3="*"/>
<key key0="o" 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" />
<key key0="d" key1="accent_grave" key3="accent_aigu" />
<key key0="f" />
<key key0="g" 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="l" key2="|" key3="\\" />
<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="f"/>
<key key0="g" 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="l" key2="|" key3="\\"/>
</row>
<row>
<key width="1.5" key0="shift" />
<key key0="z" />
<key key0="x" />
<key key0="c" key1="accent_cedille" key2="&lt;" key3="." />
<key key0="v" key2="&gt;" key3="," />
<key key0="b" key2="\?" key3="/" />
<key key0="n" key1="accent_tilde" key2=":" key3=";" />
<key key0="m" key2="&quot;" key3="'" />
<key width="1.5" key0="backspace" key2="delete" />
<key width="1.5" key0="shift"/>
<key key0="z"/>
<key key0="x"/>
<key key0="c" key1="accent_cedille" key2="&lt;" key3="."/>
<key key0="v" key2="&gt;" key3=","/>
<key key0="b" key2="\?" key3="/"/>
<key key0="n" key1="accent_tilde" key2=":" key3=";"/>
<key key0="m" key2="&quot;" 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" />
<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>

44
res/xml/qwertz.xml Normal file
View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<keyboard>
<row>
<key key0="q" key1="esc" key2="1" key3="\@" key4="!"/>
<key key0="w" key1="^" key2="2" key3="&quot;"/>
<key key0="e" key1="§" key2="3" key4="€"/>
<key key0="r" key2="4" key3="$"/>
<key key0="t" key2="5" key3="%"/>
<key key0="z" key2="6" key3="&amp;" key4="{"/>
<key key0="u" key2="7" key4="}"/>
<key key0="i" key1="(" key2="8" key4="["/>
<key key0="o" key1=")" key2="9" key4="]"/>
<key key0="p" key1="=" key2="0" key4="\?"/>
</row>
<row>
<key shift="0.5" key0="a" key1="tab" key2="`"/>
<key key0="s" key3="ß"/>
<key key0="d" key1="accent_grave" key2="accent_aigu" key3="accent_ring"/>
<key key0="f" key1="~"/>
<key key0="g" key3="-"/>
<key key0="h" key3="+"/>
<key key0="j" key1="accent_trema" key2="accent_circonflexe" key3="*"/>
<key key0="k" key3="/" key4="\\"/>
<key key0="l" key1="'" key3="\#"/>
</row>
<row>
<key width="1.5" key0="shift"/>
<key key0="y" key1="&gt;" key2="|" key3="&lt;"/>
<key key0="x"/>
<key key0="c" key1="accent_cedille"/>
<key key0="v" />
<key key0="b" key1=";" key3=","/>
<key key0="n" key1=":" key3="." key4="accent_tilde"/>
<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>

View File

@@ -1,102 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/pref_category_layout">
<ListPreference
android:key="layout"
android:title="@string/pref_layout_title"
android:summary="@string/pref_layout_summary"
android:defaultValue="system"
android:entries="@array/pref_layout_entries"
android:entryValues="@array/pref_layout_values" />
/>
<ListPreference
android:key="accents"
android:title="@string/pref_accents_title"
android:summary="@string/pref_accents_summary"
android:defaultValue="@string/pref_accents_default"
android:entries="@array/pref_accents_entries"
android:entryValues="@array/pref_accents_values" />
<ListPreference android:key="layout" android:title="@string/pref_layout_title" android:summary="%s" android:defaultValue="system" android:entries="@array/pref_layout_entries" android:entryValues="@array/pref_layout_values"/>
<ListPreference android:key="accents" android:title="@string/pref_accents_title" android:summary="%s" android:defaultValue="1" android:entries="@array/pref_accents_entries" android:entryValues="@array/pref_accents_values"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_category_typing">
<juloo.common.SlideBarPreference
android:key="sub_value_dist"
android:title="@string/pref_preci_title"
android:summary="@string/pref_preci_summary"
android:defaultValue="10.0"
min="5.0"
max="25.0"
/>
<juloo.common.IntSlideBarPreference
android:key="longpress_timeout"
android:title="@string/pref_long_timeout_title"
android:summary="@string/pref_long_timeout_summary"
android:defaultValue="600"
min="50"
max="2000"
/>
<juloo.common.IntSlideBarPreference
android:key="longpress_interval"
android:title="@string/pref_long_interval_title"
android:summary="@string/pref_long_interval_summary"
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"
/>
<ListPreference android:key="swipe_dist" android:title="@string/pref_swipe_dist_title" android:summary="@string/pref_swipe_dist_summary" android:defaultValue="15" android:entries="@array/pref_swipe_dist_entries" android:entryValues="@array/pref_swipe_dist_values"/>
<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"/>
</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="@string/pref_vibrate_duration_summary"
android:defaultValue="20"
min="5"
max="50"
/>
<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">
<juloo.common.IntSlideBarPreference
android:key="margin_bottom"
android:title="@string/pref_margin_bottom_title"
android:summary="@string/pref_margin_bottom_summary"
android:defaultValue="5"
min="0"
max="100"
/>
<juloo.common.IntSlideBarPreference
android:key="key_height"
android:title="@string/pref_key_height_title"
android:summary="@string/pref_key_height_summary"
android:defaultValue="50"
min="30"
max="90"
/>
<juloo.common.IntSlideBarPreference
android:key="horizontal_margin"
android:title="@string/pref_horizontal_margin_title"
android:summary="@string/pref_horizontal_margin_summary"
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"
/>
<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"/>
<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="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"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -4,18 +4,20 @@
} }:
let
jdk = pkgs.openjdk8;
android = pkgs.androidenv.composeAndroidPackages {
buildToolsVersions = [ "30.0.3" ];
platformVersions = [ "29" ];
platformVersions = [ "30" ];
abiVersions = [ "armeabi-v7a" ];
};
in
apksigner = pkgs.apksigner.override {
inherit (jdk) jre;
inherit (android) build-tools;
};
pkgs.mkShell {
buildInputs = with pkgs; [
findutils openjdk8 android.androidsdk
];
in pkgs.mkShell {
buildInputs = [ pkgs.findutils jdk android.androidsdk apksigner ];
ANDROID_HOME = "${android.androidsdk}/libexec/android-sdk";
}

View File

@@ -11,17 +11,17 @@ import android.widget.TextView;
import android.widget.SeekBar;
/*
** IntSlideBarPreference
** -
** Open a dialog showing a seekbar
** -
** xml attrs:
** android:defaultValue Default value (int)
** min min value (int)
** max max value (int)
** -
** Summary field allow to show the current value using %s flag
*/
** IntSlideBarPreference
** -
** Open a dialog showing a seekbar
** -
** xml attrs:
** android:defaultValue Default value (int)
** min min value (int)
** max max value (int)
** -
** Summary field allow to show the current value using %s flag
*/
public class IntSlideBarPreference extends DialogPreference
implements SeekBar.OnSeekBarChangeListener
{

View File

@@ -11,17 +11,17 @@ import android.widget.TextView;
import android.widget.SeekBar;
/*
** SideBarPreference
** -
** Open a dialog showing a seekbar
** -
** xml attrs:
** android:defaultValue Default value (float)
** min min value (float)
** max max value (float)
** -
** Summary field allow to show the current value using %f or %s flag
*/
** SideBarPreference
** -
** Open a dialog showing a seekbar
** -
** xml attrs:
** android:defaultValue Default value (float)
** min min value (float)
** max max value (float)
** -
** Summary field allow to show the current value using %f or %s flag
*/
public class SlideBarPreference extends DialogPreference
implements SeekBar.OnSeekBarChangeListener
{

View File

@@ -1,24 +1,24 @@
package juloo.keyboard2;
import android.content.Context;
import android.content.res.Resources;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
import android.util.TypedValue;
class Config
final class Config
{
private Keyboard2 _context;
// From resources
public final float marginTop;
public final float keyPadding;
public final float keyVerticalInterval;
public final float keyHorizontalInterval;
public final float keyRound;
// From preferences
public int layout; // Or '-1' for the system defaults
public float subValueDist;
private float swipe_dist_dp;
public float swipe_dist_px;
public boolean vibrateEnabled;
public long vibrateDuration;
public long longPressTimeout;
@@ -29,25 +29,27 @@ class Config
public boolean preciseRepeat;
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 accent_flags_to_remove;
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 Config(Keyboard2 context)
public final IKeyEventHandler handler;
private Config(Context context, IKeyEventHandler h)
{
Resources res = context.getResources();
_context = context;
// 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);
keyRound = res.getDimension(R.dimen.key_round);
// default values
layout = -1;
subValueDist = 10f;
vibrateEnabled = true;
vibrateDuration = 20;
longPressTimeout = 600;
@@ -59,41 +61,47 @@ class Config
characterSize = 1.f;
accents = 1;
// from prefs
refresh();
refresh(context);
// initialized later
shouldOfferSwitchingToNextInputMethod = false;
accent_flags_to_remove = 0;
key_flags_to_remove = 0;
actionLabel = null;
actionId = 0;
swapEnterActionKey = false;
handler = h;
}
/*
** Reload prefs
*/
public void refresh()
public void refresh(Context context)
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(_context);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
DisplayMetrics dm = context.getResources().getDisplayMetrics();
layout = layoutId_of_string(prefs.getString("layout", "system"));
subValueDist = prefs.getFloat("sub_value_dist", subValueDist);
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);
vibrateDuration = prefs.getInt("vibrate_duration", (int)vibrateDuration);
longPressTimeout = prefs.getInt("longpress_timeout", (int)longPressTimeout);
longPressInterval = prefs.getInt("longpress_interval", (int)longPressInterval);
marginBottom = getDipPref(prefs, "margin_bottom", marginBottom);
keyHeight = getDipPref(prefs, "key_height", keyHeight);
horizontalMargin = getDipPref(prefs, "horizontal_margin", horizontalMargin);
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);
preciseRepeat = prefs.getBoolean("precise_repeat", preciseRepeat);
characterSize = prefs.getFloat("character_size", characterSize);
accents = Integer.valueOf(prefs.getString("accents", "1"));
theme = themeId_of_string(prefs.getString("theme", ""));
}
private float getDipPref(SharedPreferences prefs, String pref_name, float def)
private float getDipPref(DisplayMetrics dm, SharedPreferences prefs, String pref_name, float def)
{
int value = prefs.getInt(pref_name, -1);
if (value < 0)
return (def);
return (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value,
_context.getResources().getDisplayMetrics()));
return (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, dm));
}
public static int layoutId_of_string(String name)
@@ -102,13 +110,13 @@ class Config
{
case "azerty": return R.xml.azerty;
case "qwerty": return R.xml.qwerty;
case "system": return -1;
default: throw new IllegalArgumentException();
case "qwertz": return R.xml.qwertz;
case "system": default: return -1;
}
}
/* Used for the accents option. */
public static int accentFlag_of_name(String name)
public static int extra_key_flag_of_name(String name)
{
switch (name)
{
@@ -119,7 +127,35 @@ class Config
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)
{
case "light": return R.style.Light;
case "black": return R.style.Black;
default: case "dark": return R.style.Dark;
}
}
private static Config _globalConfig = null;
public static void initGlobalConfig(Context context, IKeyEventHandler handler)
{
_globalConfig = new Config(context, handler);
}
public static Config globalConfig()
{
return _globalConfig;
}
public static interface IKeyEventHandler
{
public void handleKeyUp(KeyValue value, int flags);
}
}

View File

@@ -24,7 +24,6 @@ public class EmojiGridView extends GridView
public static final int GROUP_LAST_USE = -1;
public static final int COLUMN_WIDTH = 192;
public static final float EMOJI_SIZE = 32.f;
private static final String LAST_USE_PREF = "emoji_last_use";
@@ -48,16 +47,15 @@ public class EmojiGridView extends GridView
public void setEmojiGroup(int group)
{
_emojiArray = (group == GROUP_LAST_USE) ? getLastEmojis() : Emoji.getEmojisByGroup(group);
setAdapter(new EmojiViewAdpater((Keyboard2)getContext(), _emojiArray));
setAdapter(new EmojiViewAdpater(getContext(), _emojiArray));
}
public void onItemClick(AdapterView<?> parent, View v, int pos, long id)
{
Keyboard2 main = (Keyboard2)getContext();
Config config = Config.globalConfig();
Integer used = _lastUsed.get(_emojiArray[pos]);
_lastUsed.put(_emojiArray[pos], (used == null) ? 1 : used.intValue() + 1);
main.handleKeyUp(_emojiArray[pos], 0);
config.handler.handleKeyUp(_emojiArray[pos], 0);
saveLastUsed(); // TODO: opti
}
@@ -118,13 +116,11 @@ public class EmojiGridView extends GridView
private static class EmojiView extends TextView
{
public EmojiView(Keyboard2 context)
public EmojiView(Context context)
{
super(context);
setTextSize(EMOJI_SIZE);
setTextAppearance(context, R.style.emojiGridButton);
setGravity(Gravity.CENTER);
setBackgroundColor(0x0);
setTextColor(getResources().getColor(R.color.emoji_color));
setLayoutParams(new GridView.LayoutParams(GridView.LayoutParams.WRAP_CONTENT, GridView.LayoutParams.WRAP_CONTENT));
}
@@ -136,13 +132,13 @@ public class EmojiGridView extends GridView
private static class EmojiViewAdpater extends BaseAdapter
{
private Keyboard2 _main;
private Context _context;
private Emoji[] _emojiArray;
public EmojiViewAdpater(Keyboard2 main, Emoji[] emojiArray)
public EmojiViewAdpater(Context context, Emoji[] emojiArray)
{
_main = main;
_context = context;
_emojiArray = emojiArray;
}
@@ -168,7 +164,7 @@ public class EmojiGridView extends GridView
EmojiView view = (EmojiView)convertView;
if (view == null)
view = new EmojiView(_main);
view = new EmojiView(_context);
view.setEmoji(_emojiArray[pos]);
return (view);
}

View File

@@ -17,13 +17,12 @@ public class EmojiKeyButton extends Button
_key = KeyValue.getKeyByName(attrs.getAttributeValue(null, "key"));
setText(_key.symbol);
if ((_key.flags & KeyValue.FLAG_KEY_FONT) != 0)
setTypeface(((Keyboard2)context).getSpecialKeyFont());
setTypeface(Theme.getSpecialKeyFont(context));
}
public void onClick(View v)
{
Keyboard2 main = (Keyboard2)getContext();
main.handleKeyUp(_key, 0);
Config config = Config.globalConfig();
config.handler.handleKeyUp(_key, 0);
}
}

View File

@@ -0,0 +1,78 @@
package juloo.keyboard2;
import android.view.KeyEvent;
class KeyEventHandler implements Config.IKeyEventHandler
{
private IReceiver _recv;
public KeyEventHandler(IReceiver recv)
{
_recv = recv;
}
public void handleKeyUp(KeyValue key, int flags)
{
key = KeyModifier.handleFlags(key, flags);
switch (key.eventCode)
{
case KeyValue.EVENT_CONFIG: _recv.showKeyboardConfig(); return;
case KeyValue.EVENT_SWITCH_TEXT: _recv.setLayout(-1); return;
case KeyValue.EVENT_SWITCH_NUMERIC: _recv.setLayout(R.xml.numeric); return;
case KeyValue.EVENT_SWITCH_EMOJI: _recv.setPane_emoji(); return;
case KeyValue.EVENT_SWITCH_BACK_EMOJI: _recv.setPane_normal(); return;
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);
else if (key.char_ != KeyValue.CHAR_NONE)
_recv.commitChar(key.char_);
else if (key.eventCode != KeyValue.EVENT_NONE)
handleMetaKeyUp(key, flags);
else
_recv.commitText(key.symbol);
}
}
// private void handleDelKey(int before, int after)
// {
// CharSequence selection = getCurrentInputConnection().getSelectedText(0);
// if (selection != null && selection.length() > 0)
// getCurrentInputConnection().commitText("", 1);
// else
// getCurrentInputConnection().deleteSurroundingText(before, after);
// }
private void handleMetaKeyUp(KeyValue key, int flags)
{
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);
}
public static interface IReceiver
{
public void switchToNextInputMethod();
public void setPane_emoji();
public void setPane_normal();
public void showKeyboardConfig();
public void performAction();
/** 'res_id' is '-1' for the currently selected layout. */
public void setLayout(int res_id);
public void sendKeyEvent(int eventCode, int meta);
public void commitText(String text);
public void commitChar(char c);
}
}

View File

@@ -73,11 +73,7 @@ class KeyModifier
default: return (char)KeyCharacterMap.getDeadChar('\u00B4', c);
}
case KeyValue.FLAG_ACCENT3:
switch (c)
{
case '*': return '°';
default: return (char)KeyCharacterMap.getDeadChar('\u02C6', c);
}
return (char)KeyCharacterMap.getDeadChar('\u02C6', c);
case KeyValue.FLAG_ACCENT4:
switch (c)
{
@@ -186,6 +182,7 @@ class KeyModifier
case "esc": name = "insert"; break;
case "$": name = ""; break;
case "#": name = "£"; break;
case "*": name = "°"; break;
default: return k;
}
return KeyValue.getKeyByName(name);

View File

@@ -13,6 +13,7 @@ class KeyValue
public static final int EVENT_SWITCH_EMOJI = -5;
public static final int EVENT_SWITCH_BACK_EMOJI = -6;
public static final int EVENT_CHANGE_METHOD = -7;
public static final int EVENT_ACTION = -8;
public static final char CHAR_NONE = '\0';
// Behavior flags
@@ -47,6 +48,17 @@ class KeyValue
FLAG_ACCENT3 | FLAG_ACCENT4 | FLAG_ACCENT5 | FLAG_ACCENT6 |
FLAG_ACCENT_SUPERSCRIPT | FLAG_ACCENT_SUBSCRIPT | 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;
public final String name;
public final String symbol;
public final char char_;
@@ -90,10 +102,15 @@ class KeyValue
keys.put(name, new KeyValue(name, symbol, c, event, flags));
}
private static void addCharKey(char c, int event)
private static void addCharKey(char c, int event, int flags)
{
String name = String.valueOf(c);
addKey(name, name, c, event, 0);
addKey(name, name, c, event, flags);
}
private static void addCharKey(char c, int event)
{
addCharKey(c, event, 0);
}
private static void addModifierKey(String name, String symbol, int extra_flags)
@@ -190,6 +207,7 @@ class KeyValue
addCharKey('#', KeyEvent.KEYCODE_POUND);
addCharKey('(', KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN);
addCharKey(')', KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN);
addCharKey('ß', EVENT_NONE, FLAG_LANG_SZLIG);
addSpecialKey("config", "Conf", EVENT_CONFIG);
addSpecialKey("switch_text", "ABC", EVENT_SWITCH_TEXT);
@@ -197,6 +215,7 @@ class KeyValue
addSpecialKey("switch_emoji", ":)", EVENT_SWITCH_EMOJI);
addSpecialKey("switch_back_emoji", "ABC", EVENT_SWITCH_BACK_EMOJI);
addSpecialKey("change_method", "", EVENT_CHANGE_METHOD);
addSpecialKey("action", "Action", EVENT_ACTION); // Will always be replaced
addEventKey("esc", "Esc", KeyEvent.KEYCODE_ESCAPE);
addEventKey("enter", "\uE800", KeyEvent.KEYCODE_ENTER, FLAG_KEY_FONT);
@@ -206,7 +225,7 @@ class KeyValue
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_HOME);
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);
@@ -221,8 +240,8 @@ class KeyValue
addEventKey("f8", "F8", KeyEvent.KEYCODE_F8);
addEventKey("f9", "F9", KeyEvent.KEYCODE_F9);
addEventKey("f10", "F10", KeyEvent.KEYCODE_F10);
addEventKey("tab", "", KeyEvent.KEYCODE_TAB);
addKey("tab", "", '\t', KeyEvent.KEYCODE_TAB, 0);
addKey("space", " ", ' ', KeyEvent.KEYCODE_SPACE, 0);
}
}

View File

@@ -12,9 +12,11 @@ import android.os.IBinder;
import android.text.InputType;
import android.preference.PreferenceManager;
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;
@@ -30,7 +32,6 @@ public class Keyboard2 extends InputMethodService
private Keyboard2View _keyboardView;
private int _currentTextLayout;
private ViewGroup _emojiPane = null;
private Typeface _specialKeyFont = null;
private Config _config;
@@ -51,24 +52,14 @@ public class Keyboard2 extends InputMethodService
public void onCreate()
{
super.onCreate();
_specialKeyFont = Typeface.createFromAsset(getAssets(), "fonts/keys.ttf");
PreferenceManager.setDefaultValues(this, R.xml.settings, false);
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
_config = new Config(this);
_keyboardView = (Keyboard2View)getLayoutInflater().inflate(R.layout.keyboard, null);
Config.initGlobalConfig(this, new KeyEventHandler(this.new Receiver()));
_config = Config.globalConfig();
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
_keyboardView.reset();
}
public Config getConfig()
{
return (_config);
}
public Typeface getSpecialKeyFont()
{
return (_specialKeyFont);
}
private List<InputMethodSubtype> getEnabledSubtypes(InputMethodManager imm)
{
String pkg = getPackageName();
@@ -80,7 +71,7 @@ public class Keyboard2 extends InputMethodService
private void refreshSubtypeLayout(InputMethodSubtype subtype)
{
int l = _config.layout;;
int l = _config.layout;
if (l == -1)
{
String s = subtype.getExtraValueOf("default_layout");
@@ -90,33 +81,32 @@ public class Keyboard2 extends InputMethodService
_currentTextLayout = l;
}
private int accents_of_subtype(InputMethodSubtype subtype)
private int extra_keys_of_subtype(InputMethodSubtype subtype)
{
String accents_option = subtype.getExtraValueOf("accents");
String extra_keys = subtype.getExtraValueOf("extra_keys");
int flags = 0;
if (accents_option != null)
for (String acc : accents_option.split("\\|"))
flags |= Config.accentFlag_of_name(acc);
if (extra_keys != null)
for (String acc : extra_keys.split("\\|"))
flags |= Config.extra_key_flag_of_name(acc);
return flags;
}
private void refreshAccentsOption(InputMethodManager imm, InputMethodSubtype subtype)
{
final int DONT_REMOVE = KeyValue.FLAG_ACCENT_SUPERSCRIPT | KeyValue.FLAG_ACCENT_SUBSCRIPT;
int to_keep = DONT_REMOVE;
int to_keep = 0;
switch (_config.accents)
{
case 1:
to_keep |= accents_of_subtype(subtype);
to_keep |= extra_keys_of_subtype(subtype);
for (InputMethodSubtype s : getEnabledSubtypes(imm))
to_keep |= accents_of_subtype(s);
to_keep |= extra_keys_of_subtype(s);
break;
case 2: to_keep |= accents_of_subtype(subtype); break;
case 3: to_keep = KeyValue.FLAGS_ACCENTS; break;
case 2: to_keep |= extra_keys_of_subtype(subtype); break;
case 3: to_keep = KeyValue.FLAGS_HIDDEN_KEYS; break;
case 4: break;
default: throw new IllegalArgumentException();
}
_config.accent_flags_to_remove = ~to_keep & KeyValue.FLAGS_ACCENTS;
_config.key_flags_to_remove = ~to_keep & KeyValue.FLAGS_HIDDEN_KEYS;
}
private void refreshSubtypeLegacyFallback()
@@ -124,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.accent_flags_to_remove = 0; break;
case 4: _config.accent_flags_to_remove = KeyValue.FLAGS_ACCENTS; break;
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;
}
// Fallback for the layout option: Use qwerty in the "system settings" case
_currentTextLayout = (_config.layout == -1) ? R.xml.qwerty : _config.layout;
@@ -148,25 +138,54 @@ public class Keyboard2 extends InputMethodService
}
}
@Override
public View onCreateInputView()
private String actionLabel_of_imeAction(int action)
{
ViewGroup parent = (ViewGroup)_keyboardView.getParent();
switch (action)
{
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;
}
}
if (parent != null)
parent.removeView(_keyboardView);
return (_keyboardView);
private void refreshEditorInfo(EditorInfo info)
{
// First try to look at 'info.actionLabel', if it isn't set, look at
// 'imeOptions'.
if (info.actionLabel != null)
{
_config.actionLabel = info.actionLabel.toString();
_config.actionId = info.actionId;
_config.swapEnterActionKey = false;
}
else
{
int action = info.imeOptions & EditorInfo.IME_MASK_ACTION;
_config.actionLabel = actionLabel_of_imeAction(action); // Might be null
_config.actionId = action;
_config.swapEnterActionKey =
(info.imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0;
}
}
@Override
public void onStartInputView(EditorInfo info, boolean restarting)
{
// Update '_config' before calling 'KeyboardView.setKeyboard'
refreshSubtypeImm();
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);
}
@Override
@@ -186,92 +205,89 @@ public class Keyboard2 extends InputMethodService
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
_config.refresh();
int prev_theme = _config.theme;
_config.refresh(this);
refreshSubtypeImm();
_keyboardView.refreshConfig(_config, getLayout(_currentTextLayout));
_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;
}
}
@Override
public void onConfigurationChanged(Configuration newConfig)
/** Not static */
public class Receiver implements KeyEventHandler.IReceiver
{
_keyboardView.reset();
}
public void handleKeyUp(KeyValue key, int flags)
{
if (getCurrentInputConnection() == null)
return ;
key = KeyModifier.handleFlags(key, flags);
if (key.eventCode == KeyValue.EVENT_CONFIG)
{
Intent intent = new Intent(this, SettingsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
else if (key.eventCode == KeyValue.EVENT_SWITCH_TEXT)
_keyboardView.setKeyboard(getLayout(_currentTextLayout));
else if (key.eventCode == KeyValue.EVENT_SWITCH_NUMERIC)
_keyboardView.setKeyboard(getLayout(R.xml.numeric));
else if (key.eventCode == KeyValue.EVENT_SWITCH_EMOJI)
{
if (_emojiPane == null)
_emojiPane = (ViewGroup)getLayoutInflater().inflate(R.layout.emoji_pane, null);
setInputView(_emojiPane);
}
else if (key.eventCode == KeyValue.EVENT_SWITCH_BACK_EMOJI)
setInputView(_keyboardView);
else if (key.eventCode == KeyValue.EVENT_CHANGE_METHOD)
public void switchToNextInputMethod()
{
InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
imm.switchToNextInputMethod(getConnectionToken(), false);
}
else if ((flags & (KeyValue.FLAG_CTRL | KeyValue.FLAG_ALT)) != 0)
handleMetaKeyUp(key, flags);
// else if (eventCode == KeyEvent.KEYCODE_DEL)
// handleDelKey(1, 0);
// else if (eventCode == KeyEvent.KEYCODE_FORWARD_DEL)
// handleDelKey(0, 1);
else if (key.char_ == KeyValue.CHAR_NONE)
public void setPane_emoji()
{
if (key.eventCode != KeyValue.EVENT_NONE)
handleMetaKeyUp(key, flags);
else
getCurrentInputConnection().commitText(key.symbol, 1);
}
else
sendKeyChar(key.char_);
if (_emojiPane == null)
_emojiPane = (ViewGroup)inflate_view(R.layout.emoji_pane);
setInputView(_emojiPane);
}
// private void handleDelKey(int before, int after)
// {
// CharSequence selection = getCurrentInputConnection().getSelectedText(0);
// if (selection != null && selection.length() > 0)
// getCurrentInputConnection().commitText("", 1);
// else
// getCurrentInputConnection().deleteSurroundingText(before, after);
// }
private void handleMetaKeyUp(KeyValue key, int flags)
public void setPane_normal()
{
int metaState = 0;
KeyEvent event;
setInputView(_keyboardView);
}
if (key.eventCode == KeyValue.EVENT_NONE)
return ;
if ((flags & KeyValue.FLAG_CTRL) != 0)
metaState |= KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON;
if ((flags & KeyValue.FLAG_ALT) != 0)
metaState |= KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_ON;
if ((flags & KeyValue.FLAG_SHIFT) != 0)
metaState |= KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON;
event = new KeyEvent(1, 1, KeyEvent.ACTION_DOWN, key.eventCode, 0, metaState);
getCurrentInputConnection().sendKeyEvent(event);
getCurrentInputConnection().sendKeyEvent(KeyEvent.changeAction(event, KeyEvent.ACTION_UP));
public void performAction()
{
InputConnection conn = getCurrentInputConnection();
if (conn == null)
return;
conn.performEditorAction(_config.actionId);
}
public void setLayout(int res_id)
{
if (res_id == -1)
res_id = _currentTextLayout;
_keyboardView.setKeyboard(getLayout(res_id));
}
public void sendKeyEvent(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));
}
public void showKeyboardConfig()
{
Intent intent = new Intent(Keyboard2.this, SettingsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
public void commitText(String text)
{
getCurrentInputConnection().commitText(text, 1);
}
public void commitChar(char c)
{
sendKeyChar(c);
}
}
private IBinder getConnectionToken()
{
return getWindow().getWindow().getAttributes().token;
}
private View inflate_view(int layout)
{
return View.inflate(new ContextThemeWrapper(this, _config.theme), layout, null);
}
}

View File

@@ -1,16 +1,15 @@
package juloo.keyboard2;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
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;
@@ -37,18 +36,7 @@ public class Keyboard2View extends View
private float _keyWidth;
private Paint _keyBgPaint = new Paint();
private Paint _keyDownBgPaint = new Paint();
private Paint _keyLabelPaint;
private Paint _keySubLabelPaint;
private Paint _specialKeyLabelPaint;
private Paint _specialKeySubLabelPaint;
private int _lockedColor;
private int _activatedColor;
private int _labelColor;
private int _subLabelColor;
private float _labelTextSize;
private float _sublabelTextSize;
private Theme _theme;
private static RectF _tmpRect = new RectF();
@@ -57,47 +45,42 @@ public class Keyboard2View extends View
super(context, attrs);
_vibratorService = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
_handler = new Handler(this);
refreshConfig(((Keyboard2)context).getConfig(), null);
_theme = new Theme(getContext(), attrs);
_config = Config.globalConfig();
refreshConfig(null);
setOnTouchListener(this);
}
/* Internally calls [reset()]. */
public void refreshConfig(Config config, KeyboardData kw)
public void refreshConfig(KeyboardData kw)
{
Resources res = getResources();
_config = config;
_lockedColor = res.getColor(R.color.key_label_locked);
_activatedColor = res.getColor(R.color.key_label_activated);
_labelColor = res.getColor(R.color.key_label);
_subLabelColor = res.getColor(R.color.key_sub_label);
_labelTextSize = res.getDimension(R.dimen.label_text_size) * config.characterSize;
_sublabelTextSize = res.getDimension(R.dimen.sublabel_text_size) * config.characterSize;
_keyBgPaint.setColor(res.getColor(R.color.key_bg));
_keyDownBgPaint.setColor(res.getColor(R.color.key_down_bg));
_keyLabelPaint = initLabelPaint(Paint.Align.CENTER, null);
_keySubLabelPaint = initLabelPaint(Paint.Align.LEFT, null);
Typeface specialKeysFont = ((Keyboard2)getContext()).getSpecialKeyFont();
_specialKeyLabelPaint = initLabelPaint(Paint.Align.CENTER, specialKeysFont);
_specialKeySubLabelPaint = initLabelPaint(Paint.Align.LEFT, specialKeysFont);
if (kw != null)
setKeyboard(kw); // handle layout options then calls reset().
}
private Paint initLabelPaint(Paint.Align align, Typeface font)
{
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setTextAlign(align);
if (font != null)
paint.setTypeface(font);
return (paint);
}
public void setKeyboard(KeyboardData kw)
{
if (!_config.shouldOfferSwitchingToNextInputMethod)
kw = kw.removeKeys(new KeyboardData.RemoveKeysByEvent(KeyValue.EVENT_CHANGE_METHOD));
if (_config.accent_flags_to_remove != 0)
kw = kw.removeKeys(new KeyboardData.RemoveKeysByFlags(_config.accent_flags_to_remove));
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;
reset();
}
@@ -180,7 +163,7 @@ public class Keyboard2View extends View
moveY -= key.downY;
float absDist = Math.abs(moveX) + Math.abs(moveY);
key.ptrDist = absDist;
if (absDist < _config.subValueDist)
if (absDist < _config.swipe_dist_px)
newValue = key.key.key0;
else if (moveX < 0)
newValue = (moveY < 0) ? key.key.key1 : key.key.key3;
@@ -301,7 +284,7 @@ public class Keyboard2View extends View
private void handleKeyUp(KeyDown key)
{
if (key.value != null && (key.flags & (KeyValue.FLAG_LOCKED | KeyValue.FLAG_NOCHAR)) == 0)
((Keyboard2)getContext()).handleKeyUp(key.value, _flags);
_config.handler.handleKeyUp(key.value, _flags);
}
private void handleKeyDown(KeyValue key)
@@ -348,11 +331,11 @@ public class Keyboard2View extends View
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.subValueDist * 15.f)));
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);
((Keyboard2)getContext()).handleKeyUp(key.value, _flags);
_config.handler.handleKeyUp(key.value, _flags);
return (true);
}
}
@@ -366,7 +349,7 @@ public class Keyboard2View extends View
int width = dm.widthPixels;
int height =
(int)(_config.keyHeight * _keyboard.keysHeight
+ _keyboard.rows.size() * _config.keyVerticalInterval
+ _keyboard.rows.size()
+ _config.marginTop + _config.marginBottom);
setMeasuredDimension(width, height);
_keyWidth = (width - (_config.horizontalMargin * 2)) / _keyboard.keysWidth;
@@ -375,24 +358,22 @@ public class Keyboard2View extends View
@Override
protected void onDraw(Canvas canvas)
{
float y = _config.marginTop;
float y = _config.marginTop + _config.keyVerticalInterval / 2;
for (KeyboardData.Row row : _keyboard.rows)
{
y += row.shift * _config.keyHeight;
float x = _config.horizontalMargin;
float keyH = row.height * _config.keyHeight;
float x = _config.horizontalMargin + _config.keyHorizontalInterval / 2;
float keyH = row.height * _config.keyHeight - _config.keyVerticalInterval;
for (KeyboardData.Key k : row.keys)
{
x += k.shift * _keyWidth + _config.keyHorizontalInterval;
x += k.shift * _keyWidth;
float keyW = _keyWidth * k.width - _config.keyHorizontalInterval;
KeyDown keyDown = getKeyDown(k);
_tmpRect.set(x, y, x + keyW, y + keyH);
if (keyDown != null)
canvas.drawRect(_tmpRect, _keyDownBgPaint);
else
canvas.drawRoundRect(_tmpRect, _config.keyRound, _config.keyRound, _keyBgPaint);
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 + _labelTextSize) / 2f + y, keyDown);
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);
@@ -402,9 +383,9 @@ public class Keyboard2View extends View
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);
x += keyW;
x += _keyWidth * k.width;
}
y += keyH + _config.keyVerticalInterval;
y += row.height * _config.keyHeight;
}
}
@@ -422,9 +403,9 @@ public class Keyboard2View extends View
if (kd != null)
{
if ((kd.flags & KeyValue.FLAG_LOCKED) != 0)
return _lockedColor;
return _theme.lockedColor;
if (kd.pointerId == -1)
return _activatedColor;
return _theme.activatedColor;
}
}
return defaultColor;
@@ -433,26 +414,25 @@ public class Keyboard2View extends View
private void drawLabel(Canvas canvas, KeyValue k, float x, float y, KeyDown keyDown)
{
k = KeyModifier.handleFlags(k, _flags);
Paint p = ((k.flags & KeyValue.FLAG_KEY_FONT) != 0) ? _specialKeyLabelPaint : _keyLabelPaint;
p.setColor(labelColor(k, keyDown, _labelColor));
p.setTextSize(_labelTextSize * scaleTextSize(k));
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);
}
private void drawSubLabel(Canvas canvas, KeyValue k, float x, float y, boolean right, boolean up, KeyDown keyDown)
{
k = KeyModifier.handleFlags(k, _flags);
Paint p = ((k.flags & KeyValue.FLAG_KEY_FONT) != 0) ? _specialKeySubLabelPaint : _keySubLabelPaint;
p.setColor(labelColor(k, keyDown, _subLabelColor));
p.setTextAlign(right ? Paint.Align.RIGHT : Paint.Align.LEFT);
p.setTextSize(_sublabelTextSize * scaleTextSize(k));
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();
canvas.drawText(k.symbol, x, y, p);
}
private float scaleTextSize(KeyValue k)
{
return (k.symbol.length() < 2) ? 1.f : 0.8f;
return ((k.symbol.length() < 2) ? 1.f : 0.8f) * _config.characterSize;
}
private static class KeyDown

View File

@@ -57,11 +57,11 @@ class KeyboardData
return new KeyboardData(rows);
}
public KeyboardData removeKeys(MapKeys f)
public KeyboardData replaceKeys(MapKeys f)
{
ArrayList<Row> rows_ = new ArrayList<Row>();
for (Row r : rows)
rows_.add(r.removeKeys(f));
rows_.add(r.replaceKeys(f));
return new KeyboardData(rows_);
}
@@ -105,11 +105,11 @@ class KeyboardData
return new Row(keys, h, shift);
}
public Row removeKeys(MapKeys f)
public Row replaceKeys(MapKeys f)
{
ArrayList<Key> keys_ = new ArrayList<Key>();
for (Key k : keys)
keys_.add(k.removeKeys(f));
keys_.add(k.replaceKeys(f));
return new Row(keys_, height, shift);
}
}
@@ -157,7 +157,7 @@ class KeyboardData
return new Key(k0, k1, k2, k3, k4, width, shift);
}
public Key removeKeys(MapKeys f)
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);
}
@@ -168,27 +168,63 @@ class KeyboardData
public abstract KeyValue map(KeyValue k);
}
public static class RemoveKeysByFlags implements MapKeys
public static class ReplaceKeysByFlags implements MapKeys
{
private final int _flags;
private final KeyValue _replacement;
public RemoveKeysByFlags(int flags) { _flags = flags; }
public ReplaceKeysByFlags(int flags, KeyValue r)
{
_flags = flags;
_replacement = r;
}
public KeyValue map(KeyValue k)
{
return (k == null || (k.flags & _flags) != 0) ? null : k;
return (k != null && (k.flags & _flags) != 0) ? _replacement : k;
}
}
public static class RemoveKeysByEvent implements MapKeys
public static class ReplaceKeysByEvent implements MapKeys
{
private final int _eventCode;
private final KeyValue _replacement;
public RemoveKeysByEvent(int ev) { _eventCode = ev; }
public ReplaceKeysByEvent(int ev, KeyValue r)
{
_eventCode = ev;
_replacement = r;
}
public KeyValue map(KeyValue k)
{
return (k == null || k.eventCode == _eventCode) ? null : 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;
}
}
}

View File

@@ -0,0 +1,83 @@
package juloo.keyboard2;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
public class Theme
{
public final Paint keyBgPaint = new Paint();
public final Paint keyDownBgPaint = new Paint();
public final int lockedColor;
public final int activatedColor;
public final int labelColor;
public final int subLabelColor;
public final float labelTextSize;
public final float sublabelTextSize;
public final float keyBorderRadius;
private final Paint _keyLabelPaint;
private final Paint _specialKeyLabelPaint;
private final Paint _keySubLabelPaint;
private final Paint _specialKeySubLabelPaint;
public Theme(Context context, AttributeSet attrs)
{
TypedArray s = context.getTheme().obtainStyledAttributes(attrs, R.styleable.keyboard, 0, 0);
keyBgPaint.setColor(s.getColor(R.styleable.keyboard_colorKey, 0));
keyDownBgPaint.setColor(s.getColor(R.styleable.keyboard_colorKeyActivated, 0));
// colorKeyboard = s.getColor(R.styleable.keyboard_colorKeyboard, 0);
labelColor = s.getColor(R.styleable.keyboard_colorLabel, 0);
activatedColor = s.getColor(R.styleable.keyboard_colorLabelActivated, 0);
lockedColor = s.getColor(R.styleable.keyboard_colorLabelLocked, 0);
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);
_specialKeyLabelPaint = initLabelPaint(Paint.Align.CENTER, specialKeyFont);
_specialKeySubLabelPaint = initLabelPaint(Paint.Align.LEFT, specialKeyFont);
}
public Paint labelPaint(boolean special_font)
{
Paint p = special_font ? _specialKeyLabelPaint : _keyLabelPaint;
return p;
}
public Paint subLabelPaint(boolean special_font, boolean align_right)
{
Paint p = special_font ? _specialKeySubLabelPaint : _keySubLabelPaint;
p.setTextAlign(align_right ? Paint.Align.RIGHT : Paint.Align.LEFT);
return p;
}
private Paint initLabelPaint(Paint.Align align, Typeface font)
{
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setTextAlign(align);
if (font != null)
paint.setTypeface(font);
return (paint);
}
private static Typeface _specialKeyFont = null;
static public Typeface getSpecialKeyFont(Context context)
{
if (_specialKeyFont == null)
{
_specialKeyFont = Typeface.createFromAsset(context.getAssets(), "fonts/keys.ttf");
}
return _specialKeyFont;
}
}