diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/CommandHandler.java b/app/src/main/java/io/github/sspanak/tt9/ime/CommandHandler.java
index 73bf89c0..af9047f1 100644
--- a/app/src/main/java/io/github/sspanak/tt9/ime/CommandHandler.java
+++ b/app/src/main/java/io/github/sspanak/tt9/ime/CommandHandler.java
@@ -6,7 +6,6 @@ import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.db.DataStore;
import io.github.sspanak.tt9.db.words.DictionaryLoader;
import io.github.sspanak.tt9.ime.modes.InputMode;
-import io.github.sspanak.tt9.ime.modes.ModeABC;
import io.github.sspanak.tt9.languages.LanguageCollection;
import io.github.sspanak.tt9.ui.UI;
import io.github.sspanak.tt9.ui.dialogs.AddWordDialog;
@@ -135,28 +134,19 @@ abstract public class CommandHandler extends TextEditingHandler {
return;
} else if (allowedInputModes.size() == 1 && allowedInputModes.contains(InputMode.MODE_123)) {
mInputMode = !mInputMode.is123() ? InputMode.getInstance(settings, mLanguage, inputType, textField, InputMode.MODE_123) : mInputMode;
- }
- // when typing a word or viewing scrolling the suggestions, only change the case
- else if (!suggestionOps.isEmpty()) {
- nextTextCase();
- }
- // make "abc" and "ABC" separate modes from user perspective
- else if (mInputMode instanceof ModeABC && mLanguage.hasUpperCase() && mInputMode.getTextCase() == InputMode.CASE_LOWER) {
- mInputMode.nextTextCase();
} else {
+ suggestionOps.cancelDelayedAccept();
+ mInputMode.onAcceptSuggestion(suggestionOps.acceptIncomplete());
+ resetKeyRepeat();
+
int nextModeIndex = (allowedInputModes.indexOf(mInputMode.getId()) + 1) % allowedInputModes.size();
mInputMode = InputMode.getInstance(settings, mLanguage, inputType, textField, allowedInputModes.get(nextModeIndex));
mInputMode.setTextFieldCase(inputType.determineTextCase());
mInputMode.determineNextWordTextCase(textField.getStringBeforeCursor());
-
- resetKeyRepeat();
}
// save the settings for the next time
settings.saveInputMode(mInputMode.getId());
- settings.saveTextCase(mInputMode.getTextCase());
-
- statusBar.setText(mInputMode);
}
@@ -220,7 +210,7 @@ abstract public class CommandHandler extends TextEditingHandler {
}
suggestionOps.cancelDelayedAccept();
- suggestionOps.acceptIncomplete();
+ mInputMode.onAcceptSuggestion(suggestionOps.acceptIncomplete());
mInputMode.reset();
mainView.showCommandPalette();
diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/HotkeyHandler.java b/app/src/main/java/io/github/sspanak/tt9/ime/HotkeyHandler.java
index f37c3a78..db2caead 100644
--- a/app/src/main/java/io/github/sspanak/tt9/ime/HotkeyHandler.java
+++ b/app/src/main/java/io/github/sspanak/tt9/ime/HotkeyHandler.java
@@ -102,6 +102,10 @@ public abstract class HotkeyHandler extends CommandHandler {
return onKeySelectKeyboard(validateOnly);
}
+ if (keyCode == settings.getKeyShift()) {
+ return onKeyNextTextCase(validateOnly);
+ }
+
if (keyCode == settings.getKeyShowSettings()) {
return onKeyShowSettings(validateOnly);
}
@@ -283,6 +287,7 @@ public abstract class HotkeyHandler extends CommandHandler {
suggestionOps.scheduleDelayedAccept(mInputMode.getAutoAcceptTimeout()); // restart the timer
nextInputMode();
+ statusBar.setText(mInputMode);
mainView.render();
if (settings.isMainLayoutStealth()) {
@@ -294,6 +299,24 @@ public abstract class HotkeyHandler extends CommandHandler {
}
+ public boolean onKeyNextTextCase(boolean validateOnly) {
+ if (validateOnly) {
+ return true;
+ }
+
+ suggestionOps.scheduleDelayedAccept(mInputMode.getAutoAcceptTimeout()); // restart the timer
+ nextTextCase();
+ statusBar.setText(mInputMode);
+ mainView.render();
+
+ if (settings.isMainLayoutStealth()) {
+ UI.toastShortSingle(this, mInputMode.getClass().getSimpleName(), mInputMode.toString());
+ }
+
+ return true;
+ }
+
+
private boolean onKeySelectKeyboard(boolean validateOnly) {
if (!isInputViewShown() || shouldBeOff()) {
return false;
diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/helpers/Key.java b/app/src/main/java/io/github/sspanak/tt9/ime/helpers/Key.java
index e4f88de5..fb368b1c 100644
--- a/app/src/main/java/io/github/sspanak/tt9/ime/helpers/Key.java
+++ b/app/src/main/java/io/github/sspanak/tt9/ime/helpers/Key.java
@@ -55,7 +55,8 @@ public class Key {
|| keyCode == settings.getKeyPreviousSuggestion()
|| keyCode == settings.getKeyNextSuggestion()
|| keyCode == settings.getKeyNextInputMode()
- || keyCode == settings.getKeyNextLanguage();
+ || keyCode == settings.getKeyNextLanguage()
+ || keyCode == settings.getKeyShift();
}
diff --git a/app/src/main/java/io/github/sspanak/tt9/preferences/helpers/Hotkeys.java b/app/src/main/java/io/github/sspanak/tt9/preferences/helpers/Hotkeys.java
index 874ce1c8..ea08d64e 100644
--- a/app/src/main/java/io/github/sspanak/tt9/preferences/helpers/Hotkeys.java
+++ b/app/src/main/java/io/github/sspanak/tt9/preferences/helpers/Hotkeys.java
@@ -93,6 +93,7 @@ public class Hotkeys {
defaultKeys.put(SectionKeymap.ITEM_NEXT_INPUT_MODE, KeyEvent.KEYCODE_POUND);
defaultKeys.put(SectionKeymap.ITEM_NEXT_LANGUAGE, -KeyEvent.KEYCODE_POUND); // negative means "hold"
defaultKeys.put(SectionKeymap.ITEM_SELECT_KEYBOARD, KeyEvent.KEYCODE_UNKNOWN);
+ defaultKeys.put(SectionKeymap.ITEM_SHIFT, -KeyEvent.KEYCODE_STAR);
defaultKeys.put(SectionKeymap.ITEM_SHOW_SETTINGS, KeyEvent.KEYCODE_UNKNOWN);
defaultKeys.put(SectionKeymap.ITEM_VOICE_INPUT, KeyEvent.KEYCODE_UNKNOWN);
diff --git a/app/src/main/java/io/github/sspanak/tt9/preferences/screens/hotkeys/HotkeysScreen.java b/app/src/main/java/io/github/sspanak/tt9/preferences/screens/hotkeys/HotkeysScreen.java
index 28ebb559..cf38dd82 100644
--- a/app/src/main/java/io/github/sspanak/tt9/preferences/screens/hotkeys/HotkeysScreen.java
+++ b/app/src/main/java/io/github/sspanak/tt9/preferences/screens/hotkeys/HotkeysScreen.java
@@ -31,6 +31,7 @@ public class HotkeysScreen extends BaseScreenFragment {
findPreference(SectionKeymap.ITEM_NEXT_INPUT_MODE),
findPreference(SectionKeymap.ITEM_NEXT_LANGUAGE),
findPreference(SectionKeymap.ITEM_SELECT_KEYBOARD),
+ findPreference(SectionKeymap.ITEM_SHIFT),
findPreference(SectionKeymap.ITEM_SHOW_SETTINGS),
findPreference(SectionKeymap.ITEM_VOICE_INPUT),
};
diff --git a/app/src/main/java/io/github/sspanak/tt9/preferences/screens/hotkeys/SectionKeymap.java b/app/src/main/java/io/github/sspanak/tt9/preferences/screens/hotkeys/SectionKeymap.java
index bf2de572..ad76f329 100644
--- a/app/src/main/java/io/github/sspanak/tt9/preferences/screens/hotkeys/SectionKeymap.java
+++ b/app/src/main/java/io/github/sspanak/tt9/preferences/screens/hotkeys/SectionKeymap.java
@@ -24,6 +24,7 @@ public class SectionKeymap {
public static final String ITEM_NEXT_INPUT_MODE = "key_next_input_mode";
public static final String ITEM_NEXT_LANGUAGE = "key_next_language";
public static final String ITEM_SELECT_KEYBOARD = "key_select_keyboard";
+ public static final String ITEM_SHIFT = "key_shift";
public static final String ITEM_SHOW_SETTINGS = "key_show_settings";
public static final String ITEM_VOICE_INPUT = "key_voice_input";
diff --git a/app/src/main/java/io/github/sspanak/tt9/preferences/settings/SettingsHotkeys.java b/app/src/main/java/io/github/sspanak/tt9/preferences/settings/SettingsHotkeys.java
index 55650871..75629c8b 100644
--- a/app/src/main/java/io/github/sspanak/tt9/preferences/settings/SettingsHotkeys.java
+++ b/app/src/main/java/io/github/sspanak/tt9/preferences/settings/SettingsHotkeys.java
@@ -11,7 +11,7 @@ class SettingsHotkeys extends SettingsHacks {
SettingsHotkeys(Context context) { super(context); }
public boolean areHotkeysInitialized() {
- return !prefs.getBoolean("hotkeys_v3_initialized", false);
+ return !prefs.getBoolean("hotkeys_v4_initialized", false);
}
public void setDefaultKeys(HashMap defaultKeys) {
@@ -19,7 +19,7 @@ class SettingsHotkeys extends SettingsHacks {
prefsEditor.putString(key, String.valueOf(defaultKeys.get(key)));
}
- prefsEditor.putBoolean("hotkeys_v3_initialized", true).apply();
+ prefsEditor.putBoolean("hotkeys_v4_initialized", true).apply();
}
@@ -61,6 +61,9 @@ class SettingsHotkeys extends SettingsHacks {
public int getKeySelectKeyboard() {
return getFunctionKey(SectionKeymap.ITEM_SELECT_KEYBOARD);
}
+ public int getKeyShift() {
+ return getFunctionKey(SectionKeymap.ITEM_SHIFT);
+ }
public int getKeyShowSettings() {
return getFunctionKey(SectionKeymap.ITEM_SHOW_SETTINGS);
}
diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/main/MainLayoutNumpad.java b/app/src/main/java/io/github/sspanak/tt9/ui/main/MainLayoutNumpad.java
index 391e595a..42b5430e 100644
--- a/app/src/main/java/io/github/sspanak/tt9/ui/main/MainLayoutNumpad.java
+++ b/app/src/main/java/io/github/sspanak/tt9/ui/main/MainLayoutNumpad.java
@@ -113,8 +113,8 @@ class MainLayoutNumpad extends BaseMainLayout {
if (
keyId == R.id.soft_key_add_word
- || keyId == R.id.soft_key_input_mode
- || keyId == R.id.soft_key_language
+ || keyId == R.id.soft_key_lf3
+ || keyId == R.id.soft_key_lf4
|| keyId == R.id.soft_key_filter_suggestions
) {
key.setEnabled(false);
@@ -145,8 +145,8 @@ class MainLayoutNumpad extends BaseMainLayout {
if (
keyId == R.id.soft_key_add_word
- || keyId == R.id.soft_key_input_mode
- || keyId == R.id.soft_key_language
+ || keyId == R.id.soft_key_lf3
+ || keyId == R.id.soft_key_lf4
|| keyId == R.id.soft_key_filter_suggestions
) {
key.setEnabled(true);
diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKey.java b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKey.java
index 90213f2b..7bfa0fc3 100644
--- a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKey.java
+++ b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKey.java
@@ -262,7 +262,9 @@ public class SoftKey extends androidx.appcompat.widget.AppCompatButton implement
}
sb.setSpan(new RelativeSizeSpan(complexLabelTitleSize), 0, titleLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
- sb.setSpan(new StyleSpan(Typeface.ITALIC), 0, titleLength, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
+ if (!new Text(title).startsWithGraphic()) {
+ sb.setSpan(new StyleSpan(Typeface.ITALIC), 0, titleLength, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
+ }
sb.setSpan(new RelativeSizeSpan(padding), titleLength, titleLength + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
sb.setSpan(new RelativeSizeSpan(complexLabelSubTitleSize), titleLength + 1, sb.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyInputMode.java b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyInputMode.java
deleted file mode 100644
index 6f9f0219..00000000
--- a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyInputMode.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package io.github.sspanak.tt9.ui.main.keys;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import io.github.sspanak.tt9.R;
-import io.github.sspanak.tt9.ui.Vibration;
-
-public class SoftKeyInputMode extends SwipeableKey {
- public SoftKeyInputMode(Context context) {
- super(context);
- }
-
- public SoftKeyInputMode(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public SoftKeyInputMode(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @Override
- protected void handleHold() {
- preventRepeat();
-
- if (validateTT9Handler()) {
- vibrate(Vibration.getHoldVibration());
- tt9.selectKeyboard();
- }
- }
-
- @Override
- protected boolean handleRelease() {
- return notSwiped() && validateTT9Handler() && tt9.onKeyNextInputMode(false);
- }
-
- @Override
- protected void handleEndSwipeX(float position, float delta) {
- if (validateTT9Handler()) {
- tt9.nextKeyboard();
- }
- }
-
- @Override
- protected int getNoEmojiTitle() {
- return R.string.virtual_key_input_mode;
- }
-
- @Override
- public void render() {
- super.render();
- if (tt9 != null) {
- setEnabled(!tt9.isVoiceInputActive());
- }
- }
-}
diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyLF4.java b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyLF4.java
new file mode 100644
index 00000000..faf16bc5
--- /dev/null
+++ b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyLF4.java
@@ -0,0 +1,74 @@
+package io.github.sspanak.tt9.ui.main.keys;
+
+import android.content.Context;
+import android.graphics.Paint;
+import android.os.Build;
+import android.util.AttributeSet;
+
+import io.github.sspanak.tt9.R;
+import io.github.sspanak.tt9.ui.Vibration;
+
+public class SoftKeyLF4 extends SwipeableKey {
+ private final static float GLOBE_SIZE = 0.35f;
+
+ public SoftKeyLF4(Context context) {
+ super(context);
+ complexLabelTitleSize = GLOBE_SIZE;
+ }
+ public SoftKeyLF4(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ complexLabelTitleSize = GLOBE_SIZE;
+ }
+ public SoftKeyLF4(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ complexLabelTitleSize = GLOBE_SIZE;
+ }
+
+ @Override
+ protected void handleHold() {
+ preventRepeat();
+ if (validateTT9Handler() && tt9.onKeyNextLanguage(false)) {
+ vibrate(Vibration.getHoldVibration());
+ }
+ }
+
+ @Override
+ protected boolean handleRelease() {
+ return notSwiped() && validateTT9Handler() && tt9.onKeyNextInputMode(false);
+ }
+
+ @Override
+ protected void handleEndSwipeX(float position, float delta) {
+ if (validateTT9Handler()) {
+ tt9.nextKeyboard();
+ }
+ }
+
+ @Override
+ protected void handleEndSwipeY(float position, float delta) {
+ if (validateTT9Handler()) {
+ tt9.selectKeyboard();
+ }
+ }
+
+ @Override
+ protected String getTitle() {
+ return "🌐";
+ }
+
+ @Override
+ protected String getSubTitle() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && new Paint().hasGlyph("⌨")) {
+ return "⌨";
+ }
+
+ return getContext().getString(R.string.virtual_key_input_mode).toUpperCase();
+ }
+
+ @Override
+ public void render() {
+ setTextSize(28);
+ super.render();
+ setEnabled(tt9 != null && !tt9.isVoiceInputActive());
+ }
+}
diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyNextLanguage.java b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyNextLanguage.java
deleted file mode 100644
index d487e219..00000000
--- a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyNextLanguage.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package io.github.sspanak.tt9.ui.main.keys;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-public class SoftKeyNextLanguage extends SoftKey {
- public SoftKeyNextLanguage(Context context) { super(context); }
- public SoftKeyNextLanguage(Context context, AttributeSet attrs) { super(context, attrs); }
- public SoftKeyNextLanguage(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
-
- @Override
- protected boolean handleRelease() {
- return validateTT9Handler() && tt9.onKeyNextLanguage(false);
- }
-
- @Override
- public void render() {
- super.render();
- if (tt9 != null) {
- setEnabled(!tt9.isInputModeNumeric() && !tt9.isVoiceInputActive());
- }
- }
-}
diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyShift.java b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyShift.java
new file mode 100644
index 00000000..5d24e37c
--- /dev/null
+++ b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyShift.java
@@ -0,0 +1,37 @@
+package io.github.sspanak.tt9.ui.main.keys;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.util.AttributeSet;
+
+public class SoftKeyShift extends SoftKey {
+ public SoftKeyShift(Context context) {
+ super(context);
+ }
+
+ public SoftKeyShift(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SoftKeyShift(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ protected boolean handleRelease() {
+ return validateTT9Handler() && tt9.onKeyNextTextCase(false);
+ }
+
+ @Override
+ protected String getTitle() {
+ return "⇧";
+ }
+
+ @Override
+ public void render() {
+ setTextSize(30);
+ setTypeface(Typeface.DEFAULT_BOLD);
+ super.render();
+ setEnabled(tt9 != null && !tt9.isVoiceInputActive());
+ }
+}
diff --git a/app/src/main/res/layout/panel_numpad.xml b/app/src/main/res/layout/panel_numpad.xml
index 375ff259..28d15e30 100644
--- a/app/src/main/res/layout/panel_numpad.xml
+++ b/app/src/main/res/layout/panel_numpad.xml
@@ -62,7 +62,8 @@
style="@android:style/Widget.Holo.Button.Borderless"
android:layout_width="0dp"
android:layout_height="match_parent"
- android:layout_weight="@dimen/numpad_control_key_layout_weight" />
+ android:layout_weight="@dimen/numpad_control_key_layout_weight"
+ android:textSize="@dimen/soft_key_icon_size" />
-
+ android:layout_weight="@dimen/numpad_control_key_layout_weight" />
-
@@ -140,13 +138,12 @@
android:layout_height="@dimen/numpad_key_height"
android:layoutDirection="ltr">
-
+ android:layout_weight="@dimen/numpad_control_key_layout_weight" />
Del
Mode
Cfg
+ Shift
Copy
Speak
diff --git a/app/src/main/res/xml/prefs_screen_hotkeys.xml b/app/src/main/res/xml/prefs_screen_hotkeys.xml
index c27236c8..8fadf0c2 100644
--- a/app/src/main/res/xml/prefs_screen_hotkeys.xml
+++ b/app/src/main/res/xml/prefs_screen_hotkeys.xml
@@ -46,6 +46,10 @@
app:key="key_select_keyboard"
app:title="@string/function_select_keyboard" />
+
+