1
0
Fork 0

fixed inconsistent text case visualization and optimized the rendering speed

This commit is contained in:
sspanak 2025-06-11 18:02:22 +03:00 committed by Dimo Karaivanov
parent 903e756dc0
commit b26aba2273
8 changed files with 62 additions and 34 deletions

View file

@ -234,9 +234,7 @@ public abstract class HotkeyHandler extends CommandHandler {
mInputMode.onAcceptSuggestion(suggestionOps.acceptIncomplete());
resetKeyRepeat();
if (settings.isMainLayoutNumpad()) {
mainView.renderKeys();
}
mainView.renderDynamicKeys();
return true;
}
@ -273,9 +271,7 @@ public abstract class HotkeyHandler extends CommandHandler {
.loadSuggestions(filter);
}
if (settings.isMainLayoutNumpad()) {
mainView.renderKeys();
}
mainView.renderDynamicKeys();
return true;
}
@ -292,9 +288,7 @@ public abstract class HotkeyHandler extends CommandHandler {
backward = isLanguageRTL != backward;
scrollSuggestions(backward);
if (settings.isMainLayoutNumpad()) {
mainView.renderKeys();
}
mainView.renderDynamicKeys();
return true;
}

View file

@ -120,9 +120,7 @@ public abstract class TypingHandler extends KeyPadHandler {
if (appHacks.onBackspace(settings, mInputMode)) {
mInputMode.reset();
if (settings.isMainLayoutNumpad()) {
mainView.renderKeys();
}
mainView.renderDynamicKeys();
return false;
}
@ -147,6 +145,7 @@ public abstract class TypingHandler extends KeyPadHandler {
if (settings.getBackspaceRecomposing() && repeat == 0 && noTextSelection && suggestionOps.isEmpty() && !DictionaryLoader.getInstance(this).isRunning()) {
final String previousWord = mInputMode.recompose();
if (textField.recompose(previousWord)) {
mInputMode.setOnEndRecomposing(this::updateShiftState);
getSuggestions(previousWord);
} else {
mInputMode.reset();
@ -233,9 +232,7 @@ public abstract class TypingHandler extends KeyPadHandler {
autoCorrectSpace(text, true, -1);
forceShowWindow();
if (settings.isMainLayoutNumpad()) {
mainView.renderKeys();
}
mainView.renderDynamicKeys();
return true;
}
@ -375,9 +372,7 @@ public abstract class TypingHandler extends KeyPadHandler {
mInputMode.onAcceptSuggestion(word, true);
autoCorrectSpace(word, false, mInputMode.getSequence().isEmpty() ? -1 : mInputMode.getSequence().charAt(0) - '0');
mInputMode.determineNextWordTextCase(-1);
if (settings.isMainLayoutNumpad()) {
mainView.renderKeys();
}
updateShiftState();
}
private void onAcceptSuggestionsDelayed(String word) {
@ -390,9 +385,6 @@ public abstract class TypingHandler extends KeyPadHandler {
if (!word.isEmpty()) {
autoCorrectSpace(word, true, fromKey);
resetKeyRepeat();
if (settings.isMainLayoutNumpad()) {
mainView.renderKeys();
}
}
}
@ -439,13 +431,9 @@ public abstract class TypingHandler extends KeyPadHandler {
String trimmedWord = suggestionOps.getCurrent(mLanguage, mInputMode.getSequenceLength());
appHacks.setComposingTextWithHighlightedStem(trimmedWord, mInputMode);
if (new Text(suggestionOps.getCurrent()).isAlphabetic()) {
setStatusIcon(mInputMode, mLanguage);
if (settings.isMainLayoutNumpad()) {
mainView.renderKeys();
if (!suggestionOps.isEmpty() && new Text(suggestionOps.getCurrent()).isAlphabetic()) {
updateShiftState();
}
}
forceShowWindow();
}
@ -456,4 +444,13 @@ public abstract class TypingHandler extends KeyPadHandler {
mInputMode.setWordStem(suggestionOps.getCurrent(), true);
appHacks.setComposingTextWithHighlightedStem(suggestionOps.getCurrent(), mInputMode);
}
protected void updateShiftState() {
setStatusIcon(mInputMode, mLanguage);
mainView.renderDynamicKeys();
if (!mainView.isTextEditingPaletteShown() && !mainView.isCommandPaletteShown()) {
statusBar.setText(mInputMode);
}
}
}

View file

@ -79,6 +79,10 @@ abstract class UiHandler extends AbstractHandler {
protected void setStatusIcon(@Nullable InputMode mode, @Nullable Language language) {
if (!settings.isStatusIconEnabled()) {
return;
}
final int displayTextCase = getDisplayTextCase(language, mode != null ? mode.getTextCase() : InputMode.CASE_UNDEFINED);
final int resId = new StatusIcon(settings, mode, language, displayTextCase).resourceId;
if (resId == 0) {

View file

@ -39,6 +39,7 @@ abstract public class InputMode {
@NonNull protected String digitSequence = "";
protected final boolean isEmailMode;
@NonNull protected Language language = new NullLanguage();
@NonNull protected Runnable onEndRecomposing = () -> {};
protected final SettingsStore settings;
@NonNull protected final ArrayList<String> suggestions = new ArrayList<>();
@NonNull protected Runnable onSuggestionsUpdated = () -> {};
@ -164,6 +165,7 @@ abstract public class InputMode {
public void beforeDeleteText() {}
public String recompose() { return null; }
public void setOnEndRecomposing(Runnable r) { onEndRecomposing = r != null ? r : () -> {}; }
public void replaceLastLetter() {}
public void reset() {

View file

@ -33,6 +33,7 @@ class ModeWords extends ModeCheonjiin {
// text analysis tools
private final AutoTextCase autoTextCase;
private boolean isCursorDirectionForward = false;
private boolean isRecomposing = false;
private int textFieldTextCase;
@ -76,6 +77,7 @@ class ModeWords extends ModeCheonjiin {
if (digitSequence.isEmpty()) {
clearWordStem();
endRecomposing();
} else if (stem.length() > digitSequence.length()) {
stem = stem.substring(0, digitSequence.length());
}
@ -123,6 +125,7 @@ class ModeWords extends ModeCheonjiin {
@Override
public String recompose() {
isRecomposing = false;
if (!language.hasSpaceBetweenWords() || language.isTranscribed()) {
return null;
}
@ -144,6 +147,7 @@ class ModeWords extends ModeCheonjiin {
reset();
digitSequence = language.getDigitSequenceForWord(previousWord);
textCase = new Text(language, previousWord).getTextCase();
isRecomposing = true;
} catch (InvalidLanguageCharactersException e) {
Logger.d(LOG_TAG, "Not recomposing word: '" + previousWord + "'. " + e.getMessage());
return null;
@ -152,6 +156,14 @@ class ModeWords extends ModeCheonjiin {
return previousWord;
}
private void endRecomposing() {
if (isRecomposing) {
isRecomposing = false;
textCase = settings.getTextCase();
onEndRecomposing.run();
}
}
@Override
public void reset() {
basicReset();
@ -315,6 +327,7 @@ class ModeWords extends ModeCheonjiin {
clearLastAcceptedWord();
} else {
reset();
endRecomposing();
}
stem = "";

View file

@ -16,6 +16,7 @@ import androidx.annotation.RequiresApi;
import androidx.core.view.WindowInsetsCompat;
import java.util.ArrayList;
import java.util.HashSet;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.ime.TraditionalT9;
@ -32,6 +33,7 @@ abstract class BaseMainLayout {
protected View view = null;
@NonNull protected final ArrayList<SoftKey> keys = new ArrayList<>();
@NonNull protected final HashSet<Integer> dynamicKeys = new HashSet<>();
BaseMainLayout(TraditionalT9 tt9, int xml) {
@ -311,11 +313,26 @@ abstract class BaseMainLayout {
abstract void render();
/**
* Run render only on the keys, for example, to refresh their state.
* Render specific keys to update their state. If the list is empty, no keys are rendered. If the
* list is null, all keys are rendered.
*/
void renderKeys() {
private void renderKeys(@Nullable HashSet<Integer> keyIds) {
if (keyIds != null && keyIds.isEmpty()) {
return;
}
for (SoftKey key : getKeys()) {
if (keyIds == null || keyIds.contains(key.getId())) {
key.render();
}
}
}
void renderKeys() {
renderKeys(null);
}
void renderDynamicKeys() {
renderKeys(dynamicKeys);
}
}

View file

@ -30,6 +30,8 @@ class MainLayoutNumpad extends BaseMainLayout {
MainLayoutNumpad(TraditionalT9 tt9) {
super(tt9, R.layout.main_numpad);
dynamicKeys.add(R.id.soft_key_filter);
dynamicKeys.add(R.id.soft_key_shift);
}

View file

@ -18,7 +18,6 @@ public class MainView {
protected MainView(TraditionalT9 tt9) {
this.tt9 = tt9;
forceCreate();
}
@ -78,13 +77,13 @@ public class MainView {
main.render();
}
public void renderKeys() {
public void renderDynamicKeys() {
if (main == null) {
Logger.e(LOG_TAG, "Cannot render keys for a null MainView.");
Logger.e(LOG_TAG, "Cannot render dynamic keys for a null MainView.");
return;
}
main.renderKeys();
main.renderDynamicKeys();
}
public void showCommandPalette() {