More visual options for gesture typing (#944)

This commit is contained in:
Devy Ballard 2024-07-24 23:08:50 -06:00 committed by GitHub
parent 28ba8a7a72
commit 83ae078cfa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
95 changed files with 171 additions and 127 deletions

View file

@ -115,7 +115,6 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
private PopupKeysPanel mPopupKeysPanel;
// Gesture floating preview text
// TODO: Make this parameter customizable by user via settings.
private final int mGestureFloatingPreviewTextLingerTimeout;
private final KeyDetector mKeyDetector;
@ -192,8 +191,8 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
mConfigShowPopupKeysKeyboardAtTouchedPoint = mainKeyboardViewAttr.getBoolean(
R.styleable.MainKeyboardView_showPopupKeysKeyboardAtTouchedPoint, false);
mGestureFloatingPreviewTextLingerTimeout = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureFloatingPreviewTextLingerTimeout, 0);
final int gestureTrailFadeoutDuration = Settings.getInstance().getCurrent().mGestureTrailFadeoutDuration;
mGestureFloatingPreviewTextLingerTimeout = gestureTrailFadeoutDuration / 4;
mGestureFloatingTextDrawingPreview = new GestureFloatingTextDrawingPreview(mainKeyboardViewAttr);
mGestureFloatingTextDrawingPreview.setDrawingView(drawingPreviewPlacerView);
@ -218,7 +217,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
mKeyboardActionListener = KeyboardActionListener.EMPTY_LISTENER;
mLanguageOnSpacebarHorizontalMargin = (int)getResources().getDimension(
mLanguageOnSpacebarHorizontalMargin = (int) getResources().getDimension(
R.dimen.config_language_on_spacebar_horizontal_margin);
}

View file

@ -30,6 +30,7 @@ import helium314.keyboard.latin.settings.Settings;
*/
public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
protected static final class GesturePreviewTextParams {
public final boolean mGesturePreviewDynamic;
public final int mGesturePreviewTextOffset;
public final int mGesturePreviewTextHeight;
public final float mGesturePreviewHorizontalPadding;
@ -46,6 +47,7 @@ public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
public GesturePreviewTextParams(final TypedArray mainKeyboardViewAttr) {
final Colors colors = Settings.getInstance().getCurrent().mColors;
mGesturePreviewDynamic = Settings.getInstance().getCurrent().mGestureFloatingPreviewDynamicEnabled;
mGesturePreviewTextSize = mainKeyboardViewAttr.getDimensionPixelSize(
R.styleable.MainKeyboardView_gestureFloatingPreviewTextSize, 0);
mGesturePreviewTextColor = colors.get(ColorType.KEY_TEXT);
@ -151,11 +153,13 @@ public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
final float rectWidth = textWidth + hPad * 2.0f;
final float rectHeight = textHeight + vPad * 2.0f;
final float rectX = Math.min(
final float rectX = mParams.mGesturePreviewDynamic ? Math.min(
Math.max(CoordinateUtils.x(mLastPointerCoords) - rectWidth / 2.0f, 0.0f),
mParams.mDisplayWidth - rectWidth);
final float rectY = CoordinateUtils.y(mLastPointerCoords)
- mParams.mGesturePreviewTextOffset - rectHeight;
mParams.mDisplayWidth - rectWidth)
: (mParams.mDisplayWidth - rectWidth) / 2.0f;
final float rectY = mParams.mGesturePreviewDynamic ? CoordinateUtils.y(mLastPointerCoords)
- mParams.mGesturePreviewTextOffset - rectHeight
: -mParams.mGesturePreviewTextOffset - rectHeight;
mGesturePreviewRectangle.set(rectX, rectY, rectX + rectWidth, rectY + rectHeight);
mPreviewTextX = (int)(rectX + hPad + textWidth / 2.0f);

View file

@ -55,8 +55,7 @@ final class GestureTrailDrawingParams {
R.styleable.MainKeyboardView_gestureTrailFadeoutStartDelay, 0);
mFadeoutDuration = GestureTrailDrawingPoints.DEBUG_SHOW_POINTS
? FADEOUT_DURATION_FOR_DEBUG
: mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureTrailFadeoutDuration, 0);
: Settings.getInstance().getCurrent().mGestureTrailFadeoutDuration;
mTrailLingerDuration = mFadeoutStartDelay + mFadeoutDuration;
mUpdateInterval = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureTrailUpdateInterval, 0);

View file

@ -10,6 +10,9 @@ import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Bundle;
import androidx.preference.SwitchPreference;
import helium314.keyboard.keyboard.KeyboardSwitcher;
import helium314.keyboard.latin.R;
/**
@ -22,14 +25,27 @@ import helium314.keyboard.latin.R;
* - Phrase gesture
*/
public final class GestureSettingsFragment extends SubScreenFragment {
private boolean needsReload = false;
@Override
public void onCreate(final Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.prefs_screen_gesture);
setupGestureDynamicPreviewPref();
setupGestureFastTypingCooldownPref();
setupGestureTrailFadeoutPref();
refreshSettingsEnablement();
}
@Override
public void onPause() {
super.onPause();
if (needsReload) {
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext());
needsReload = false;
}
}
@Override
public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
refreshSettingsEnablement();
@ -37,10 +53,34 @@ public final class GestureSettingsFragment extends SubScreenFragment {
private void refreshSettingsEnablement() {
final SharedPreferences prefs = getSharedPreferences();
setPreferenceVisible(Settings.PREF_GESTURE_PREVIEW_TRAIL, Settings.readGestureInputEnabled(prefs));
setPreferenceVisible(Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, Settings.readGestureInputEnabled(prefs));
setPreferenceVisible(Settings.PREF_GESTURE_SPACE_AWARE, Settings.readGestureInputEnabled(prefs));
setPreferenceVisible(Settings.PREF_GESTURE_FAST_TYPING_COOLDOWN, Settings.readGestureInputEnabled(prefs));
final boolean gestureInputEnabled = Settings.readGestureInputEnabled(prefs);
setPreferenceVisible(Settings.PREF_GESTURE_PREVIEW_TRAIL, gestureInputEnabled);
setPreferenceVisible(Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, gestureInputEnabled);
final boolean gesturePreviewEnabled = gestureInputEnabled
&& prefs.getBoolean(Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, true);
setPreferenceVisible(Settings.PREF_GESTURE_FLOATING_PREVIEW_DYNAMIC, gesturePreviewEnabled);
setPreferenceVisible(Settings.PREF_GESTURE_SPACE_AWARE, gestureInputEnabled);
setPreferenceVisible(Settings.PREF_GESTURE_FAST_TYPING_COOLDOWN, gestureInputEnabled);
final boolean gestureTrailEnabled = gestureInputEnabled
&& prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);
// This setting also affects the preview linger duration, so it's visible if either setting is enabled.
setPreferenceVisible(Settings.PREF_GESTURE_TRAIL_FADEOUT_DURATION, gestureTrailEnabled || gesturePreviewEnabled);
}
private void setupGestureDynamicPreviewPref() {
final SwitchPreference pref = findPreference(Settings.PREF_GESTURE_FLOATING_PREVIEW_DYNAMIC);
if (pref == null) return;
final SharedPreferences prefs = getSharedPreferences();
pref.setChecked(Settings.readGestureDynamicPreviewEnabled(prefs, requireContext()));
pref.setOnPreferenceChangeListener((preference, newValue) -> {
// default value is based on system reduced motion
final boolean defValue = Settings.readGestureDynamicPreviewDefault(requireContext());
final boolean followingSystem = newValue.equals(defValue);
// allow the default to be overridden
prefs.edit().putBoolean(Settings.PREF_GESTURE_DYNAMIC_PREVIEW_FOLLOW_SYSTEM, followingSystem).apply();
needsReload = true;
return true;
});
}
private void setupGestureFastTypingCooldownPref() {
@ -82,4 +122,44 @@ public final class GestureSettingsFragment extends SubScreenFragment {
public void feedbackValue(final int value) {}
});
}
private void setupGestureTrailFadeoutPref() {
final SeekBarDialogPreference pref = findPreference(Settings.PREF_GESTURE_TRAIL_FADEOUT_DURATION);
if (pref == null) return;
final SharedPreferences prefs = getSharedPreferences();
final Resources res = getResources();
pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
@Override
public void writeValue(final int value, final String key) {
prefs.edit().putInt(key, value).apply();
needsReload = true;
}
@Override
public void writeDefaultValue(final String key) {
prefs.edit().remove(key).apply();
needsReload = true;
}
@Override
public int readValue(final String key) {
return Settings.readGestureTrailFadeoutDuration(prefs, res);
}
@Override
public int readDefaultValue(final String key) {
return Settings.readDefaultGestureTrailFadeoutDuration(res);
}
@Override
public String getValueText(final int value) {
// fade-out has a constant start delay, value text is adjusted accordingly.
final int adjustedValue = res.getInteger(R.integer.config_gesture_trail_fadeout_start_delay) + value;
return res.getString(R.string.abbreviation_unit_milliseconds, String.valueOf(adjustedValue));
}
@Override
public void feedbackValue(final int value) {}
});
}
}

View file

@ -115,8 +115,11 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY = "enable_emoji_alt_physical_key";
public static final String PREF_GESTURE_PREVIEW_TRAIL = "gesture_preview_trail";
public static final String PREF_GESTURE_FLOATING_PREVIEW_TEXT = "gesture_floating_preview_text";
public static final String PREF_GESTURE_FLOATING_PREVIEW_DYNAMIC = "gesture_floating_preview_dynamic";
public static final String PREF_GESTURE_DYNAMIC_PREVIEW_FOLLOW_SYSTEM = "gesture_dynamic_preview_follow_system";
public static final String PREF_GESTURE_SPACE_AWARE = "gesture_space_aware";
public static final String PREF_GESTURE_FAST_TYPING_COOLDOWN = "gesture_fast_typing_cooldown";
public static final String PREF_GESTURE_TRAIL_FADEOUT_DURATION = "gesture_trail_fadeout_duration";
public static final String PREF_SHOW_SETUP_WIZARD_ICON = "show_setup_wizard_icon";
public static final String PREF_USE_CONTACTS = "use_contacts";
public static final String PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD = "long_press_symbols_for_numpad";
@ -311,6 +314,44 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
return JniUtils.sHaveGestureLib && prefs.getBoolean(PREF_GESTURE_INPUT, true);
}
public static boolean readGestureDynamicPreviewEnabled(final SharedPreferences prefs, final Context context) {
final boolean followSystem = prefs.getBoolean(PREF_GESTURE_DYNAMIC_PREVIEW_FOLLOW_SYSTEM, true);
final boolean defValue = readGestureDynamicPreviewDefault(context);
final boolean curValue = prefs.getBoolean(Settings.PREF_GESTURE_FLOATING_PREVIEW_DYNAMIC, defValue);
return followSystem ? defValue : curValue;
}
public static boolean readGestureDynamicPreviewDefault(final Context context) {
// if transitions are disabled for the system (reduced motion), moving preview should be disabled
return android.provider.Settings.System.getFloat(
context.getContentResolver(),
android.provider.Settings.Global.TRANSITION_ANIMATION_SCALE,
1.0f
) != 0.0f;
}
public static int readGestureFastTypingCooldown(final SharedPreferences prefs, final Resources res) {
final int milliseconds = prefs.getInt(
PREF_GESTURE_FAST_TYPING_COOLDOWN, UNDEFINED_PREFERENCE_VALUE_INT);
return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds
: readDefaultGestureFastTypingCooldown(res);
}
public static int readDefaultGestureFastTypingCooldown(final Resources res) {
return res.getInteger(R.integer.config_gesture_static_time_threshold_after_fast_typing);
}
public static int readGestureTrailFadeoutDuration(final SharedPreferences prefs, final Resources res) {
final int milliseconds = prefs.getInt(
PREF_GESTURE_TRAIL_FADEOUT_DURATION, UNDEFINED_PREFERENCE_VALUE_INT);
return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds
: readDefaultGestureTrailFadeoutDuration(res);
}
public static int readDefaultGestureTrailFadeoutDuration(final Resources res) {
return res.getInteger(R.integer.config_gesture_trail_fadeout_duration_default);
}
public static boolean readKeyPreviewPopupEnabled(final SharedPreferences prefs, final Resources res) {
final boolean defaultKeyPreviewPopup = res.getBoolean(R.bool.config_default_key_preview_popup);
return prefs.getBoolean(PREF_POPUP_ON, defaultKeyPreviewPopup);
@ -370,17 +411,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
return res.getInteger(R.integer.config_clipboard_history_retention_time);
}
public static int readGestureFastTypingCooldown(final SharedPreferences prefs, final Resources res) {
final int milliseconds = prefs.getInt(
PREF_GESTURE_FAST_TYPING_COOLDOWN, UNDEFINED_PREFERENCE_VALUE_INT);
return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds
: readDefaultGestureFastTypingCooldown(res);
}
public static int readDefaultGestureFastTypingCooldown(final Resources res) {
return res.getInteger(R.integer.config_gesture_static_time_threshold_after_fast_typing);
}
public static int readHorizontalSpaceSwipe(final SharedPreferences prefs) {
return switch (prefs.getString(PREF_SPACE_HORIZONTAL_SWIPE, "none")) {
case "move_cursor" -> KeyboardActionListener.SWIPE_MOVE_CURSOR;

View file

@ -95,7 +95,9 @@ public class SettingsValues {
public final boolean mGestureInputEnabled;
public final boolean mGestureTrailEnabled;
public final boolean mGestureFloatingPreviewTextEnabled;
public final boolean mGestureFloatingPreviewDynamicEnabled;
public final int mGestureFastTypingCooldown;
public final int mGestureTrailFadeoutDuration;
public final boolean mSlidingKeyInputPreviewEnabled;
public final int mKeyLongpressTimeout;
public final boolean mEnableEmojiAltPhysicalKey;
@ -203,10 +205,12 @@ public class SettingsValues {
mEnableEmojiAltPhysicalKey = prefs.getBoolean(Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY, true);
mGestureInputEnabled = Settings.readGestureInputEnabled(prefs);
mGestureTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);
mAccount = null; // remove? or can it be useful somewhere?
mGestureFloatingPreviewTextEnabled = !mInputAttributes.mDisableGestureFloatingPreviewText
&& prefs.getBoolean(Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, true);
mGestureFloatingPreviewDynamicEnabled = Settings.readGestureDynamicPreviewEnabled(prefs, context);
mGestureFastTypingCooldown = Settings.readGestureFastTypingCooldown(prefs, res);
mGestureTrailFadeoutDuration = Settings.readGestureTrailFadeoutDuration(prefs, res);
mAccount = null; // remove? or can it be useful somewhere?
mOverrideShowingSuggestions = mInputAttributes.mMayOverrideShowingSuggestions && readSuggestionsOverrideEnabled(prefs);
mSuggestionsEnabledPerUserSettings = (mInputAttributes.mShouldShowSuggestions && readSuggestionsEnabled(prefs))
|| mOverrideShowingSuggestions;