On-screen keyboard improvements (#323)
* holding a number key to type a number in text modes is now possible using the on-screen keyboard * accented letters are no longer displayed on the on-screen keyboard, just plain A-Z * the on-screen keyboard is now more compact; * improved color scheme and other small visual enhancements
This commit is contained in:
parent
d4c6467da3
commit
c6edb5a726
8 changed files with 121 additions and 87 deletions
|
|
@ -2,7 +2,7 @@
|
|||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<gradient
|
||||
android:startColor="#929492"
|
||||
android:endColor="#E3E7E3"
|
||||
android:startColor="#989A98"
|
||||
android:endColor="#E7EBE7"
|
||||
android:angle="90" />
|
||||
</shape>
|
||||
|
|
|
|||
|
|
@ -5,28 +5,65 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
<View
|
||||
android:id="@+id/separator_top"
|
||||
style="@style/numRowSeparator" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/status_bar_container"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="@dimen/numpad_candidate_height">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:textStyle="italic"
|
||||
tools:text="@tools:sample/lorem" />
|
||||
<io.github.sspanak.tt9.ui.main.keys.SoftKey
|
||||
android:id="@+id/soft_key_left_arrow"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="@dimen/numpad_arrow_key_width"
|
||||
android:layout_height="fill_parent"
|
||||
android:text="@string/key_dpad_left"
|
||||
android:textSize="@dimen/soft_key_icon_size" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/suggestions_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:scrollbars="none" />
|
||||
<View
|
||||
android:id="@+id/separator_candidates_1"
|
||||
style="@style/numSeparator" />
|
||||
|
||||
</FrameLayout>
|
||||
<FrameLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="fill_parent">
|
||||
<TextView
|
||||
android:id="@+id/status_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:textStyle="italic"
|
||||
tools:text="@tools:sample/lorem" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/suggestions_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:scrollbars="none" />
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/separator_candidates_2"
|
||||
style="@style/numSeparator" />
|
||||
|
||||
<io.github.sspanak.tt9.ui.main.keys.SoftKey
|
||||
android:id="@+id/soft_key_right_arrow"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="@dimen/numpad_arrow_key_width"
|
||||
android:layout_height="fill_parent"
|
||||
android:text="@string/key_dpad_right"
|
||||
android:textSize="@dimen/soft_key_icon_size" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/separator_candidates_bottom"
|
||||
style="@style/numRowSeparator" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/main_soft_keys"
|
||||
|
|
@ -35,50 +72,6 @@
|
|||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/numpad_padding_bottom">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="HardcodedText,KeyboardInaccessibleWidget">
|
||||
|
||||
<io.github.sspanak.tt9.ui.main.keys.SoftKey
|
||||
android:id="@+id/soft_key_left_arrow"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/key_dpad_left"
|
||||
android:textSize="@dimen/soft_key_icon_size" />
|
||||
|
||||
<io.github.sspanak.tt9.ui.main.keys.SoftKey
|
||||
android:id="@+id/soft_key_clear_filter"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Clear" />
|
||||
|
||||
<io.github.sspanak.tt9.ui.main.keys.SoftKey
|
||||
android:id="@+id/soft_key_filter_suggestions"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Filter" />
|
||||
|
||||
<io.github.sspanak.tt9.ui.main.keys.SoftKey
|
||||
android:id="@+id/soft_key_right_arrow"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/key_dpad_right"
|
||||
android:textSize="@dimen/soft_key_icon_size" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/separator_0"
|
||||
style="@style/numRowSeparator" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/numpad_key_height"
|
||||
|
|
@ -89,7 +82,7 @@
|
|||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_weight="@dimen/numpad_control_key_layout_weight"
|
||||
android:text="⚙"
|
||||
android:textSize="@dimen/soft_key_icon_size" />
|
||||
|
||||
|
|
@ -129,7 +122,7 @@
|
|||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_weight="@dimen/numpad_control_key_layout_weight"
|
||||
android:text="⌫"
|
||||
android:textSize="@dimen/soft_key_icon_size" />
|
||||
|
||||
|
|
@ -145,7 +138,7 @@
|
|||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_weight="@dimen/numpad_control_key_layout_weight"
|
||||
android:text="+"
|
||||
android:textStyle="bold" />
|
||||
|
||||
|
|
@ -184,7 +177,7 @@
|
|||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
android:layout_weight="@dimen/numpad_control_key_layout_weight" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
@ -198,7 +191,7 @@
|
|||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_weight="@dimen/numpad_control_key_layout_weight"
|
||||
android:text="⌨️"
|
||||
android:textSize="@dimen/soft_key_icon_size" />
|
||||
|
||||
|
|
@ -234,10 +227,13 @@
|
|||
android:id="@+id/separator_3_2"
|
||||
style="@style/numSeparator" />
|
||||
|
||||
<View
|
||||
<io.github.sspanak.tt9.ui.main.keys.SoftKey
|
||||
android:id="@+id/soft_key_filter_suggestions"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="@dimen/numpad_control_key_layout_weight"
|
||||
android:text="Fltr" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
@ -252,7 +248,7 @@
|
|||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_weight="@dimen/numpad_control_key_layout_weight"
|
||||
android:text="🌐" />
|
||||
|
||||
<View
|
||||
|
|
@ -292,7 +288,7 @@
|
|||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_weight="@dimen/numpad_control_key_layout_weight"
|
||||
android:text="@android:string/ok"
|
||||
tools:ignore="ButtonOrder" />
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
<!-- Light theme -->
|
||||
<color name="button_text">#242424</color>
|
||||
|
||||
<color name="candidate_background">#CECECE</color>
|
||||
<color name="candidate_background">#D3D3D3</color>
|
||||
<color name="candidate_color">#202020</color>
|
||||
<color name="candidate_selected">#AAAAAA</color>
|
||||
<color name="candidate_selected">#B8B8B8</color>
|
||||
<color name="candidate_separator">#888888</color>
|
||||
|
||||
<color name="numpad_background">#E7F0E7</color>
|
||||
<color name="numpad_background">#E7E7E7</color>
|
||||
<color name="numpad_separator">#CCC</color>
|
||||
|
||||
<!-- Dark theme -->
|
||||
|
|
|
|||
|
|
@ -15,11 +15,14 @@
|
|||
<dimen name="pref_summary_size">19sp</dimen>
|
||||
|
||||
<!-- Numpad -->
|
||||
<dimen name="numpad_padding_bottom">15dp</dimen>
|
||||
<dimen name="numpad_padding_bottom">2dp</dimen>
|
||||
<dimen name="numpad_row_separator_margin">0dp</dimen>
|
||||
|
||||
<dimen name="numpad_key_height">56dp</dimen>
|
||||
<dimen name="numpad_row_separator_margin">10dp</dimen>
|
||||
<dimen name="numpad_arrow_key_width">36dp</dimen>
|
||||
<dimen name="numpad_control_key_layout_weight">0.85</dimen>
|
||||
|
||||
<dimen name="numpad_candidate_font_size">17sp</dimen>
|
||||
<dimen name="numpad_candidate_height">32dp</dimen>
|
||||
<dimen name="numpad_candidate_height">38dp</dimen>
|
||||
<dimen name="numpad_candidate_min_width">36dp</dimen>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -12,13 +12,11 @@ public class Language {
|
|||
protected String name;
|
||||
protected Locale locale;
|
||||
protected String dictionaryFile;
|
||||
protected boolean hasUpperCase = true;
|
||||
protected String abcString;
|
||||
protected final ArrayList<ArrayList<String>> layout = new ArrayList<>();
|
||||
private final HashMap<Character, String> characterKeyMap = new HashMap<>();
|
||||
|
||||
// settings
|
||||
protected boolean hasUpperCase = true;
|
||||
|
||||
|
||||
public static Language fromDefinition(LanguageDefinition definition) throws Exception {
|
||||
if (definition.dictionaryFile.isEmpty()) {
|
||||
|
|
@ -149,6 +147,25 @@ public class Language {
|
|||
return hasUpperCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* isLatinBased
|
||||
* Returns "true" when the language is based on the Latin alphabet or "false" otherwise.
|
||||
* WARNING: This performs somewhat resource-intensive operations every time, so consider
|
||||
* caching the result.
|
||||
*/
|
||||
public boolean isLatinBased() {
|
||||
ArrayList<String> letters = getKeyCharacters(2, false);
|
||||
return letters.contains("a");
|
||||
}
|
||||
|
||||
/**
|
||||
* isGreek
|
||||
* Similar to "isLatinBased()", this returns "true" when the language is based on the Greek alphabet.
|
||||
*/
|
||||
public boolean isGreek() {
|
||||
ArrayList<String> letters = getKeyCharacters(2, false);
|
||||
return letters.contains("α");
|
||||
}
|
||||
|
||||
/* ************ utility ************ */
|
||||
|
||||
|
|
|
|||
|
|
@ -72,13 +72,19 @@ class MainLayoutNumpad extends BaseMainLayout {
|
|||
}
|
||||
}
|
||||
|
||||
ViewGroup statusBarContainer = view.findViewById(R.id.status_bar_container);
|
||||
keys.addAll(getKeysFromContainer(statusBarContainer));
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
protected ArrayList<View> getSeparators() {
|
||||
// it's fine... it's shorter, faster and easier to read than searching with 3 nested loops
|
||||
return new ArrayList<>(Arrays.asList(
|
||||
view.findViewById(R.id.separator_0),
|
||||
view.findViewById(R.id.separator_top),
|
||||
view.findViewById(R.id.separator_candidates_1),
|
||||
view.findViewById(R.id.separator_candidates_2),
|
||||
view.findViewById(R.id.separator_candidates_bottom),
|
||||
view.findViewById(R.id.separator_1_1),
|
||||
view.findViewById(R.id.separator_1_2),
|
||||
view.findViewById(R.id.separator_2_1),
|
||||
|
|
|
|||
|
|
@ -136,7 +136,6 @@ public class SoftKey extends androidx.appcompat.widget.AppCompatButton implement
|
|||
int keyId = getId();
|
||||
|
||||
if (keyId == R.id.soft_key_add_word) return tt9.onKeyAddWord();
|
||||
if (keyId == R.id.soft_key_clear_filter) return tt9.onKeyFilterClear();
|
||||
if (keyId == R.id.soft_key_filter_suggestions) return tt9.onKeyFilterSuggestions(repeat);
|
||||
if (keyId == R.id.soft_key_left_arrow) return tt9.onKeyPreviousSuggestion();
|
||||
if (keyId == R.id.soft_key_right_arrow) return tt9.onKeyNextSuggestion();
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ public class SoftNumberKey extends SoftKey {
|
|||
|
||||
@Override
|
||||
protected boolean handleHold() {
|
||||
if (tt9 == null || tt9.getInputMode() != InputMode.MODE_123 || getId() != R.id.soft_key_0) {
|
||||
if (tt9 == null) {
|
||||
return super.handleHold();
|
||||
}
|
||||
|
||||
preventRepeat();
|
||||
int zeroCode = Key.numberToCode(0);
|
||||
tt9.onKeyLongPress(zeroCode, new KeyEvent(KeyEvent.ACTION_DOWN, zeroCode));
|
||||
int keyCode = Key.numberToCode(getNumber(getId()));
|
||||
tt9.onKeyLongPress(keyCode, new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -95,11 +95,24 @@ public class SoftNumberKey extends SoftKey {
|
|||
return "";
|
||||
}
|
||||
|
||||
boolean isLatinBased = language.isLatinBased();
|
||||
boolean isGreekBased = language.isGreek();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
ArrayList<String> chars = language.getKeyCharacters(number, false);
|
||||
for (int i = 0; i < 5 && i < chars.size(); i++) {
|
||||
String currentLetter = chars.get(i);
|
||||
if (
|
||||
(isLatinBased && currentLetter.charAt(0) > 'z')
|
||||
|| (isGreekBased && (currentLetter.charAt(0) < 'α' || currentLetter.charAt(0) > 'ω'))
|
||||
) {
|
||||
// As suggested by the community, there is no need to display the accented letters.
|
||||
// People are used to seeing just A-Z.
|
||||
continue;
|
||||
}
|
||||
|
||||
sb.append(
|
||||
tt9.getTextCase() == InputMode.CASE_UPPER ? chars.get(i).toUpperCase(language.getLocale()) : chars.get(i)
|
||||
tt9.getTextCase() == InputMode.CASE_UPPER ? currentLetter.toUpperCase(language.getLocale()) : currentLetter
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue