expanding the special chars now works
This commit is contained in:
parent
aecc350b91
commit
fb90217610
20 changed files with 111 additions and 87 deletions
|
|
@ -17,6 +17,7 @@ import io.github.sspanak.tt9.ui.main.ResizableMainView;
|
|||
import io.github.sspanak.tt9.ui.tray.SuggestionsBar;
|
||||
import io.github.sspanak.tt9.util.ConsumerCompat;
|
||||
import io.github.sspanak.tt9.util.Text;
|
||||
import io.github.sspanak.tt9.util.chars.Characters;
|
||||
|
||||
public class SuggestionOps {
|
||||
@NonNull private final Handler delayedAcceptHandler;
|
||||
|
|
@ -112,6 +113,10 @@ public class SuggestionOps {
|
|||
|
||||
public String acceptCurrent() {
|
||||
String word = getCurrent();
|
||||
if (Characters.PLACEHOLDER.equals(word)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!word.isEmpty()) {
|
||||
commitCurrent(true, true);
|
||||
}
|
||||
|
|
@ -122,6 +127,10 @@ public class SuggestionOps {
|
|||
|
||||
public String acceptIncomplete() {
|
||||
String currentWord = this.getCurrent();
|
||||
if (Characters.PLACEHOLDER.equals(currentWord)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
commitCurrent(false, true);
|
||||
|
||||
return currentWord;
|
||||
|
|
@ -129,6 +138,10 @@ public class SuggestionOps {
|
|||
|
||||
|
||||
public String acceptIncompleteAndKeepList() {
|
||||
if (Characters.PLACEHOLDER.equals(this.getCurrent())) {
|
||||
return "";
|
||||
}
|
||||
|
||||
commitCurrent(false, false);
|
||||
return this.getCurrent();
|
||||
}
|
||||
|
|
@ -140,6 +153,9 @@ public class SuggestionOps {
|
|||
}
|
||||
|
||||
String lastComposingText = getCurrent(language, sequenceLength - 1);
|
||||
if (Characters.PLACEHOLDER.equals(lastComposingText)) {
|
||||
return "";
|
||||
}
|
||||
commitCurrent(false, true);
|
||||
return lastComposingText;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,14 +86,23 @@ abstract public class InputMode {
|
|||
public void onAcceptSuggestion(@NonNull String word) { onAcceptSuggestion(word, false); }
|
||||
public void onAcceptSuggestion(@NonNull String word, boolean preserveWordList) {}
|
||||
public void onCursorMove(@NonNull String word) { if (!digitSequence.isEmpty()) onAcceptSuggestion(word); }
|
||||
public void onReplaceSuggestion(@NonNull String rawWord) {
|
||||
if (SuggestionsBar.SHOW_SPECIAL_CHARS_SUGGESTION.equals(rawWord)) {
|
||||
Logger.d("InputMode", "Loading special characters for: " + seq.SPECIAL_CHAR_SEQUENCE);
|
||||
public boolean onReplaceSuggestion(@NonNull String rawWord) {
|
||||
reset();
|
||||
|
||||
boolean result = false;
|
||||
|
||||
if (rawWord.equals(SuggestionsBar.SHOW_SPECIAL_CHARS_SUGGESTION)) {
|
||||
digitSequence = seq.SPECIAL_CHAR_SEQUENCE;
|
||||
loadSpecialCharacters();
|
||||
result = true;
|
||||
} else if (rawWord.equals(SuggestionsBar.SHOW_CURRENCIES_SUGGESTION)) {
|
||||
digitSequence = seq.CURRENCY_SEQUENCE;
|
||||
loadSpecialCharacters();
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (SuggestionsBar.SHOW_CURRENCIES_SUGGESTION.equals(rawWord)) {
|
||||
Logger.d("InputMode", "Loading special characters for: " + seq.CURRENCY_SEQUENCE);
|
||||
}
|
||||
onSuggestionsUpdated.run();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -208,9 +217,20 @@ abstract public class InputMode {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads the special characters for 0-key or 1-key. For 0-key, this could be a minimized (show more)
|
||||
* special character list, or the whitespace list.
|
||||
*/
|
||||
protected boolean loadSpecialCharacters() {
|
||||
suggestions.clear();
|
||||
suggestions.addAll(settings.getOrderedKeyChars(language, digitSequence.charAt(0) - '0'));
|
||||
|
||||
if (digitSequence.equals(seq.SPECIAL_CHAR_SEQUENCE) || digitSequence.equals(seq.PUNCTUATION_SEQUENCE)) {
|
||||
suggestions.addAll(settings.getOrderedKeyChars(language, digitSequence.charAt(0) - '0'));
|
||||
} else if (digitSequence.equals(seq.CURRENCY_SEQUENCE)) {
|
||||
suggestions.addAll(Characters.getCurrencies(language));
|
||||
} else {
|
||||
suggestions.addAll(getAbbreviatedSpecialChars());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,9 +70,9 @@ public class ModeBopomofo extends ModePinyin {
|
|||
|
||||
@Override
|
||||
protected void onNumberPress(int nextNumber) {
|
||||
if (digitSequence.startsWith(seq.PUNCTUATION_SEQUENCE)) {
|
||||
if (seq.startsWithEmojiSequence(digitSequence)) {
|
||||
digitSequence = EmojiLanguage.validateEmojiSequence(seq, digitSequence, nextNumber);
|
||||
} else {
|
||||
} else if (!seq.SPECIAL_CHAR_SEQUENCE.equals(digitSequence) && !seq.CURRENCY_SEQUENCE.equals(digitSequence)) {
|
||||
digitSequence += String.valueOf(nextNumber);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,9 @@ class ModeCheonjiin extends InputMode {
|
|||
|
||||
@Override
|
||||
public boolean onBackspace() {
|
||||
if (digitSequence.equals(seq.PUNCTUATION_SEQUENCE)) {
|
||||
if (digitSequence.equals(seq.CURRENCY_SEQUENCE) || digitSequence.equals(seq.SPECIAL_CHAR_SEQUENCE)) {
|
||||
digitSequence = seq.WHITESPACE_SEQUENCE;
|
||||
} else if (digitSequence.equals(seq.PUNCTUATION_SEQUENCE)) {
|
||||
digitSequence = "";
|
||||
} else if (digitSequence.equals(seq.WHITESPACE_SEQUENCE) || (!digitSequence.startsWith(seq.PUNCTUATION_SEQUENCE) && Cheonjiin.isSingleJamo(digitSequence))) {
|
||||
digitSequence = "";
|
||||
|
|
@ -148,23 +150,27 @@ class ModeCheonjiin extends InputMode {
|
|||
digitSequence = digitSequence.substring(0, digitSequence.length() - rewindAmount);
|
||||
}
|
||||
|
||||
if (digitSequence.startsWith(seq.PUNCTUATION_SEQUENCE)) {
|
||||
if (seq.startsWithEmojiSequence(digitSequence)) {
|
||||
digitSequence = EmojiLanguage.validateEmojiSequence(seq, digitSequence, nextNumber);
|
||||
} else {
|
||||
} else if (!seq.SPECIAL_CHAR_SEQUENCE.equals(digitSequence) && !seq.CURRENCY_SEQUENCE.equals(digitSequence)) {
|
||||
digitSequence += String.valueOf(nextNumber);
|
||||
}
|
||||
|
||||
if (seq.PREFERRED_CHAR_SEQUENCE.equals(digitSequence)) {
|
||||
autoAcceptTimeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int shouldRewindRepeatingNumbers(int nextNumber) {
|
||||
protected int shouldRewindRepeatingNumbers(int nextNumber) {
|
||||
if (seq.isAnySpecialCharSequence(digitSequence)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final int nextChar = nextNumber + '0';
|
||||
final int repeatingDigits = digitSequence.length() > 1 && digitSequence.charAt(digitSequence.length() - 1) == nextChar ? Cheonjiin.getRepeatingEndingDigits(digitSequence) : 0;
|
||||
final int keyCharsCount = nextNumber == 0 ? 2 : language.getKeyCharacters(nextNumber).size();
|
||||
|
||||
if (seq.WHITESPACE_SEQUENCE.equals(digitSequence)) {
|
||||
return seq.WHITESPACE_SEQUENCE.length();
|
||||
}
|
||||
|
||||
if (repeatingDigits == 0 || keyCharsCount < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -246,11 +252,13 @@ class ModeCheonjiin extends InputMode {
|
|||
return false;
|
||||
}
|
||||
|
||||
int number = digitSequence.isEmpty() ? Integer.MAX_VALUE : digitSequence.charAt(digitSequence.length() - 1) - '0';
|
||||
if (KEY_CHARACTERS.size() > number) {
|
||||
suggestions.clear();
|
||||
suggestions.addAll(KEY_CHARACTERS.get(number));
|
||||
return true;
|
||||
if (digitSequence.equals(seq.WHITESPACE_SEQUENCE) || digitSequence.equals(seq.PUNCTUATION_SEQUENCE)) {
|
||||
int number = digitSequence.isEmpty() ? Integer.MAX_VALUE : digitSequence.charAt(digitSequence.length() - 1) - '0';
|
||||
if (KEY_CHARACTERS.size() > number) {
|
||||
suggestions.clear();
|
||||
suggestions.addAll(KEY_CHARACTERS.get(number));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.loadSpecialCharacters();
|
||||
|
|
@ -258,7 +266,11 @@ class ModeCheonjiin extends InputMode {
|
|||
|
||||
|
||||
protected boolean shouldDisplaySpecialCharacters() {
|
||||
return digitSequence.equals(seq.PUNCTUATION_SEQUENCE) || digitSequence.equals(seq.WHITESPACE_SEQUENCE);
|
||||
return
|
||||
digitSequence.equals(seq.PUNCTUATION_SEQUENCE)
|
||||
|| digitSequence.equals(seq.WHITESPACE_SEQUENCE)
|
||||
|| digitSequence.equals(seq.CURRENCY_SEQUENCE)
|
||||
|| digitSequence.equals(seq.SPECIAL_CHAR_SEQUENCE);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -324,8 +336,8 @@ class ModeCheonjiin extends InputMode {
|
|||
public boolean shouldAcceptPreviousSuggestion(int nextKey, boolean hold) {
|
||||
return
|
||||
(hold && !digitSequence.isEmpty())
|
||||
|| (digitSequence.equals(seq.WHITESPACE_SEQUENCE) && nextKey != 0)
|
||||
|| (digitSequence.startsWith(seq.PUNCTUATION_SEQUENCE) && nextKey != 1);
|
||||
|| (nextKey != Sequences.SPECIAL_CHAR_KEY && digitSequence.startsWith(seq.WHITESPACE_SEQUENCE))
|
||||
|| (nextKey != Sequences.PUNCTUATION_KEY && digitSequence.startsWith(seq.PUNCTUATION_SEQUENCE));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -176,16 +176,21 @@ public class ModeIdeograms extends ModeWords {
|
|||
* the given Latin word.
|
||||
*/
|
||||
@Override
|
||||
public void onReplaceSuggestion(@NonNull String word) {
|
||||
public boolean onReplaceSuggestion(@NonNull String word) {
|
||||
if (word.isEmpty() || new Text(word).isNumeric()) {
|
||||
reset();
|
||||
Logger.i(LOG_TAG, "Can not replace an empty or numeric word.");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (super.onReplaceSuggestion(word)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
isFiltering = false;
|
||||
stem = word;
|
||||
loadSuggestions("");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public class ModePinyin extends ModeIdeograms {
|
|||
// In East Asian languages, Space must accept the current word, or type a space when there is no word.
|
||||
// Here, we handle the case when 0-key is Space, unlike the Space hotkey in HotkeyHandler,
|
||||
// which could be a different key, assigned by the user.
|
||||
if (!digitSequence.isEmpty() && !digitSequence.endsWith(seq.WHITESPACE_SEQUENCE) && nextKey == Sequences.SPECIAL_CHAR_KEY) {
|
||||
if (!digitSequence.isEmpty() && !digitSequence.equals(seq.WHITESPACE_SEQUENCE) && nextKey == Sequences.SPECIAL_CHAR_KEY) {
|
||||
ignoreNextSpace = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import io.github.sspanak.tt9.preferences.settings.SettingsStore;
|
|||
import io.github.sspanak.tt9.util.Logger;
|
||||
import io.github.sspanak.tt9.util.Text;
|
||||
import io.github.sspanak.tt9.util.TextTools;
|
||||
import io.github.sspanak.tt9.util.chars.Characters;
|
||||
|
||||
class ModeWords extends ModeCheonjiin {
|
||||
private final String LOG_TAG = getClass().getSimpleName();
|
||||
|
|
@ -68,7 +69,12 @@ class ModeWords extends ModeCheonjiin {
|
|||
return false;
|
||||
}
|
||||
|
||||
digitSequence = digitSequence.substring(0, digitSequence.length() - 1);
|
||||
if (digitSequence.equals(seq.CURRENCY_SEQUENCE) || digitSequence.equals(seq.SPECIAL_CHAR_SEQUENCE)) {
|
||||
digitSequence = seq.WHITESPACE_SEQUENCE;
|
||||
} else {
|
||||
digitSequence = digitSequence.substring(0, digitSequence.length() - 1);
|
||||
}
|
||||
|
||||
if (digitSequence.isEmpty()) {
|
||||
clearWordStem();
|
||||
} else if (stem.length() > digitSequence.length()) {
|
||||
|
|
@ -93,16 +99,6 @@ class ModeWords extends ModeCheonjiin {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onNumberPress(int number) {
|
||||
digitSequence = EmojiLanguage.validateEmojiSequence(seq, digitSequence, number);
|
||||
|
||||
if (digitSequence.equals(seq.PREFERRED_CHAR_SEQUENCE)) {
|
||||
autoAcceptTimeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean changeLanguage(@Nullable Language newLanguage) {
|
||||
if (newLanguage != null && newLanguage.isTranscribed()) {
|
||||
|
|
@ -222,7 +218,7 @@ class ModeWords extends ModeCheonjiin {
|
|||
}
|
||||
|
||||
try {
|
||||
digitSequence = language.getDigitSequenceForWord(newStem);
|
||||
digitSequence = Characters.getWhitespaces(language).contains(newStem) ? seq.WHITESPACE_SEQUENCE : language.getDigitSequenceForWord(newStem);
|
||||
isStemFuzzy = !exact;
|
||||
stem = newStem.toLowerCase(language.getLocale());
|
||||
|
||||
|
|
@ -287,7 +283,7 @@ class ModeWords extends ModeCheonjiin {
|
|||
|
||||
|
||||
protected boolean loadPreferredChar() {
|
||||
if (digitSequence.startsWith(seq.PREFERRED_CHAR_SEQUENCE)) {
|
||||
if (digitSequence.equals(seq.PREFERRED_CHAR_SEQUENCE)) {
|
||||
suggestions.clear();
|
||||
suggestions.add(getPreferredChar());
|
||||
return true;
|
||||
|
|
@ -408,7 +404,9 @@ class ModeWords extends ModeCheonjiin {
|
|||
// Prevent typing the preferred character when the user has scrolled the special char suggestions.
|
||||
// For example, it makes more sense to allow typing "+ " with 0 + scroll + 0, instead of clearing
|
||||
// the "+" and replacing it with the preferred character.
|
||||
if (!stem.isEmpty() && nextKey == Sequences.SPECIAL_CHAR_KEY && digitSequence.charAt(0) == Sequences.SPECIAL_CHAR_CODE) {
|
||||
boolean specialOrCurrency = digitSequence.equals(seq.SPECIAL_CHAR_SEQUENCE) || digitSequence.equals(seq.CURRENCY_SEQUENCE);
|
||||
boolean isWhitespaceAndScrolled = digitSequence.equals(seq.WHITESPACE_SEQUENCE) && !stem.isEmpty();
|
||||
if (nextKey == Sequences.SPECIAL_CHAR_KEY && (isWhitespaceAndScrolled || specialOrCurrency)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -466,6 +464,9 @@ class ModeWords extends ModeCheonjiin {
|
|||
}
|
||||
|
||||
|
||||
@Override protected int shouldRewindRepeatingNumbers(int nextNumber) { return 0; }
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,12 @@ public class Sequences {
|
|||
CURRENCY_SEQUENCE = SPECIAL_CHAR_SEQUENCE + SPECIAL_CHAR_KEY;
|
||||
}
|
||||
|
||||
public boolean startsWithEmojiSequence(String sequence) {
|
||||
return
|
||||
sequence != null
|
||||
&& (sequence.startsWith(EMOJI_SEQUENCE) || sequence.startsWith(CUSTOM_EMOJI_SEQUENCE));
|
||||
}
|
||||
|
||||
public boolean isAnySpecialCharSequence(String sequence) {
|
||||
if (sequence == null) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -109,10 +109,10 @@ public class SoftKeyNumber2to9 extends SoftKeyNumber {
|
|||
*/
|
||||
private String abbreviateCharList(String chars, String abbreviationSign, Locale locale, boolean isUppercase) {
|
||||
String firstLetter = chars.substring(0, 1);
|
||||
firstLetter = TextTools.isCombining(firstLetter) ? Characters.PLACEHOLDER + firstLetter : firstLetter;
|
||||
firstLetter = TextTools.isCombining(firstLetter) ? Characters.COMBINING_BASE + firstLetter : firstLetter;
|
||||
|
||||
String lastLetter = chars.substring(chars.length() - 1);
|
||||
lastLetter = TextTools.isCombining(lastLetter) ? Characters.PLACEHOLDER + lastLetter : lastLetter;
|
||||
lastLetter = TextTools.isCombining(lastLetter) ? Characters.COMBINING_BASE + lastLetter : lastLetter;
|
||||
|
||||
String list = firstLetter + abbreviationSign + lastLetter;
|
||||
return isUppercase ? list.toUpperCase(locale) : list;
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ import io.github.sspanak.tt9.util.TextTools;
|
|||
import io.github.sspanak.tt9.util.chars.Characters;
|
||||
|
||||
public class SuggestionsBar {
|
||||
public static final String SHOW_SPECIAL_CHARS_SUGGESTION = "(@#*…)";
|
||||
public static final String SHOW_CURRENCIES_SUGGESTION = "($€£…)";
|
||||
public static final String SHOW_SPECIAL_CHARS_SUGGESTION = "#%…";
|
||||
public static final String SHOW_CURRENCIES_SUGGESTION = "$€…";
|
||||
|
||||
private final String SHOW_MORE_SUGGESTION = "(...)";
|
||||
private final String STEM_SUFFIX = "… +";
|
||||
|
|
@ -165,7 +165,7 @@ public class SuggestionsBar {
|
|||
|
||||
// "..." prefix
|
||||
int startIndex = 0;
|
||||
String[] prefixes = {STEM_VARIATION_PREFIX, STEM_PUNCTUATION_VARIATION_PREFIX, Characters.PLACEHOLDER};
|
||||
String[] prefixes = {STEM_VARIATION_PREFIX, STEM_PUNCTUATION_VARIATION_PREFIX, Characters.COMBINING_BASE};
|
||||
for (String prefix : prefixes) {
|
||||
int prefixIndex = suggestion.indexOf(prefix) + 1;
|
||||
if (prefixIndex < endIndex) { // do not match the prefix chars when they are part of STEM_SUFFIX
|
||||
|
|
@ -324,7 +324,7 @@ public class SuggestionsBar {
|
|||
|
||||
private String formatUnreadableSuggestion(String suggestion) {
|
||||
if (TextTools.isCombining(suggestion)) {
|
||||
return Characters.PLACEHOLDER + suggestion;
|
||||
return Characters.COMBINING_BASE + suggestion;
|
||||
}
|
||||
|
||||
return switch (suggestion) {
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@ import io.github.sspanak.tt9.languages.Language;
|
|||
import io.github.sspanak.tt9.languages.LanguageKind;
|
||||
|
||||
public class Characters extends Emoji {
|
||||
public static final String PLACEHOLDER = "◌";
|
||||
public static final String COMBINING_BASE = "◌";
|
||||
public static final String IDEOGRAPHIC_SPACE = " ";
|
||||
public static final String TAB = "↹";
|
||||
public static final String PLACEHOLDER = "\u200A";
|
||||
public static final String TAB = "Tab";
|
||||
|
||||
|
||||
public static final ArrayList<String> Currency = new ArrayList<>(Arrays.asList(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue