mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-06-08 23:57:41 +00:00
Add MultiSliderDialog (#1580)
This commit is contained in:
parent
d951a1dbdd
commit
7dbf5ea86d
11 changed files with 367 additions and 109 deletions
|
@ -482,7 +482,11 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
|||
// Implements {@link KeyboardState.SwitchActions}.
|
||||
@Override
|
||||
public void setOneHandedModeEnabled(boolean enabled) {
|
||||
if (mKeyboardViewWrapper.getOneHandedModeEnabled() == enabled) {
|
||||
setOneHandedModeEnabled(enabled, false);
|
||||
}
|
||||
|
||||
public void setOneHandedModeEnabled(boolean enabled, boolean force) {
|
||||
if (!force && mKeyboardViewWrapper.getOneHandedModeEnabled() == enabled) {
|
||||
return;
|
||||
}
|
||||
final Settings settings = Settings.getInstance();
|
||||
|
@ -515,6 +519,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
|||
!settings.getCurrent().mIsSplitKeyboardEnabled,
|
||||
mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE
|
||||
);
|
||||
setOneHandedModeEnabled(settings.getCurrent().mOneHandedModeEnabled, true);
|
||||
reloadKeyboard();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import helium314.keyboard.latin.settings.Defaults
|
|||
import helium314.keyboard.latin.settings.Settings
|
||||
import helium314.keyboard.latin.settings.SettingsSubtype
|
||||
import helium314.keyboard.latin.settings.SettingsSubtype.Companion.toSettingsSubtype
|
||||
import helium314.keyboard.latin.settings.createPrefKeyForBooleanSettings
|
||||
import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
||||
import helium314.keyboard.latin.utils.DictionaryInfoUtils
|
||||
import helium314.keyboard.latin.utils.DictionaryInfoUtils.USER_DICTIONARY_SUFFIX
|
||||
|
@ -562,6 +563,45 @@ fun checkVersionUpgrade(context: Context) {
|
|||
prefs.edit().putString(it.key, newValue).apply()
|
||||
}
|
||||
}
|
||||
if (oldVersion <= 3101) {
|
||||
val e = prefs.edit()
|
||||
prefs.all.toMap().forEach { (key, value) ->
|
||||
if (key == "side_padding_scale") {
|
||||
e.putFloat(createPrefKeyForBooleanSettings(Settings.PREF_SIDE_PADDING_SCALE_PREFIX, 0, 2), value as Float)
|
||||
e.putFloat(createPrefKeyForBooleanSettings(Settings.PREF_SIDE_PADDING_SCALE_PREFIX, 2, 2), value)
|
||||
} else if (key == "side_padding_scale_landscape") {
|
||||
e.putFloat(createPrefKeyForBooleanSettings(Settings.PREF_SIDE_PADDING_SCALE_PREFIX, 1, 2), value as Float)
|
||||
e.putFloat(createPrefKeyForBooleanSettings(Settings.PREF_SIDE_PADDING_SCALE_PREFIX, 3, 2), value)
|
||||
} else if (key == "bottom_padding_scale") {
|
||||
e.putFloat(createPrefKeyForBooleanSettings(Settings.PREF_BOTTOM_PADDING_SCALE_PREFIX, 0, 1), value as Float)
|
||||
} else if (key == "bottom_padding_scale_landscape") {
|
||||
e.putFloat(createPrefKeyForBooleanSettings(Settings.PREF_BOTTOM_PADDING_SCALE_PREFIX, 1, 1), value as Float)
|
||||
} else if (key == "split_spacer_scale") {
|
||||
e.putFloat(createPrefKeyForBooleanSettings(Settings.PREF_SPLIT_SPACER_SCALE_PREFIX, 0, 1), value as Float)
|
||||
} else if (key == "split_spacer_scale_landscape") {
|
||||
e.putFloat(createPrefKeyForBooleanSettings(Settings.PREF_SPLIT_SPACER_SCALE_PREFIX, 1, 1), value as Float)
|
||||
} else if (key == "one_handed_mode_enabled_p_true") {
|
||||
e.putBoolean(createPrefKeyForBooleanSettings(Settings.PREF_ONE_HANDED_MODE_PREFIX, 0, 2), value as Boolean)
|
||||
} else if (key == "one_handed_mode_enabled_p_false") {
|
||||
e.putBoolean(createPrefKeyForBooleanSettings(Settings.PREF_ONE_HANDED_MODE_PREFIX, 1, 2), value as Boolean)
|
||||
} else if (key == "one_handed_mode_scale_p_true") {
|
||||
e.putFloat(createPrefKeyForBooleanSettings(Settings.PREF_ONE_HANDED_SCALE_PREFIX, 0, 2), value as Float)
|
||||
} else if (key == "one_handed_mode_scale_p_false") {
|
||||
e.putFloat(createPrefKeyForBooleanSettings(Settings.PREF_ONE_HANDED_SCALE_PREFIX, 1, 2), value as Float)
|
||||
} else if (key == "one_handed_mode_gravity_p_true") {
|
||||
e.putInt(createPrefKeyForBooleanSettings(Settings.PREF_ONE_HANDED_GRAVITY_PREFIX, 0, 2), value as Int)
|
||||
} else if (key == "one_handed_mode_gravity_p_false") {
|
||||
e.putInt(createPrefKeyForBooleanSettings(Settings.PREF_ONE_HANDED_GRAVITY_PREFIX, 1, 2), value as Int)
|
||||
} else if (key == "keyboard_height_scale") {
|
||||
e.putFloat(createPrefKeyForBooleanSettings(Settings.PREF_KEYBOARD_HEIGHT_SCALE_PREFIX, 1, 1), value as Float)
|
||||
e.putFloat(createPrefKeyForBooleanSettings(Settings.PREF_KEYBOARD_HEIGHT_SCALE_PREFIX, 1, 1), value)
|
||||
} else {
|
||||
return@forEach
|
||||
}
|
||||
e.remove(key)
|
||||
}
|
||||
e.apply()
|
||||
}
|
||||
upgradeToolbarPrefs(prefs)
|
||||
LayoutUtilsCustom.onLayoutFileChanged() // just to be sure
|
||||
prefs.edit { putInt(Settings.PREF_VERSION_CODE, BuildConfig.VERSION_CODE) }
|
||||
|
|
|
@ -78,12 +78,13 @@ class KeyboardWrapperView @JvmOverloads constructor(
|
|||
val changePercent = 2 * sign * (x - motionEvent.rawX) / context.resources.displayMetrics.density
|
||||
if (abs(changePercent) < 1) return@setOnTouchListener true
|
||||
x = motionEvent.rawX
|
||||
val oldScale = Settings.readOneHandedModeScale(context.prefs(), Settings.getValues().mDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE)
|
||||
val landscape = Settings.getValues().mDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE
|
||||
val split = Settings.getValues().mIsSplitKeyboardEnabled
|
||||
val oldScale = Settings.readOneHandedModeScale(context.prefs(), landscape, split)
|
||||
val newScale = (oldScale + changePercent / 100f).coerceAtMost(2.5f).coerceAtLeast(0.5f)
|
||||
if (newScale == oldScale) return@setOnTouchListener true
|
||||
Settings.getInstance().writeOneHandedModeScale(newScale)
|
||||
oneHandedModeEnabled = false // intentionally putting wrong value, so KeyboardSwitcher.setOneHandedModeEnabled does actually reload
|
||||
KeyboardSwitcher.getInstance().setOneHandedModeEnabled(true)
|
||||
KeyboardSwitcher.getInstance().setOneHandedModeEnabled(true, true)
|
||||
}
|
||||
else -> x = 0f
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ object Defaults {
|
|||
LayoutType.CLIPBOARD_BOTTOM -> "clip_bottom_row"
|
||||
}
|
||||
|
||||
private const val DEFAULT_SIZE_SCALE = 1.0f // 100%
|
||||
const val PREF_THEME_STYLE = KeyboardTheme.STYLE_MATERIAL
|
||||
const val PREF_ICON_STYLE = KeyboardTheme.STYLE_MATERIAL
|
||||
const val PREF_THEME_COLORS = KeyboardTheme.THEME_LIGHT
|
||||
|
@ -80,15 +81,16 @@ object Defaults {
|
|||
"hu${Separators.SET}${ExtraValue.KEYBOARD_LAYOUT_SET}=MAIN:qwerty"
|
||||
const val PREF_ENABLE_SPLIT_KEYBOARD = false
|
||||
const val PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE = false
|
||||
const val PREF_SPLIT_SPACER_SCALE = SettingsValues.DEFAULT_SIZE_SCALE
|
||||
const val PREF_SPLIT_SPACER_SCALE_LANDSCAPE = SettingsValues.DEFAULT_SIZE_SCALE
|
||||
const val PREF_KEYBOARD_HEIGHT_SCALE = SettingsValues.DEFAULT_SIZE_SCALE
|
||||
const val PREF_BOTTOM_PADDING_SCALE = SettingsValues.DEFAULT_SIZE_SCALE
|
||||
const val PREF_BOTTOM_PADDING_SCALE_LANDSCAPE = 0f
|
||||
const val PREF_SIDE_PADDING_SCALE = 0f
|
||||
const val PREF_SIDE_PADDING_SCALE_LANDSCAPE = 0f
|
||||
const val PREF_FONT_SCALE = SettingsValues.DEFAULT_SIZE_SCALE
|
||||
const val PREF_EMOJI_FONT_SCALE = SettingsValues.DEFAULT_SIZE_SCALE
|
||||
@JvmField
|
||||
val PREF_SPLIT_SPACER_SCALE = Array(2) { DEFAULT_SIZE_SCALE }
|
||||
@JvmField
|
||||
val PREF_KEYBOARD_HEIGHT_SCALE = Array(2) { DEFAULT_SIZE_SCALE }
|
||||
@JvmField
|
||||
val PREF_BOTTOM_PADDING_SCALE = arrayOf(DEFAULT_SIZE_SCALE, 0f)
|
||||
@JvmField
|
||||
val PREF_SIDE_PADDING_SCALE = Array(4) { 0f }
|
||||
const val PREF_FONT_SCALE = DEFAULT_SIZE_SCALE
|
||||
const val PREF_EMOJI_FONT_SCALE = DEFAULT_SIZE_SCALE
|
||||
const val PREF_EMOJI_KEY_FIT = true
|
||||
const val PREF_EMOJI_SKIN_TONE = ""
|
||||
const val PREF_SPACE_HORIZONTAL_SWIPE = "move_cursor"
|
||||
|
|
|
@ -87,13 +87,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
public static final String PREF_ADDITIONAL_SUBTYPES = "additional_subtypes";
|
||||
public static final String PREF_ENABLE_SPLIT_KEYBOARD = "split_keyboard";
|
||||
public static final String PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE = "split_keyboard_landscape";
|
||||
public static final String PREF_SPLIT_SPACER_SCALE = "split_spacer_scale";
|
||||
public static final String PREF_SPLIT_SPACER_SCALE_LANDSCAPE = "split_spacer_scale_landscape";
|
||||
public static final String PREF_KEYBOARD_HEIGHT_SCALE = "keyboard_height_scale";
|
||||
public static final String PREF_BOTTOM_PADDING_SCALE = "bottom_padding_scale";
|
||||
public static final String PREF_BOTTOM_PADDING_SCALE_LANDSCAPE = "bottom_padding_scale_landscape";
|
||||
public static final String PREF_SIDE_PADDING_SCALE = "side_padding_scale";
|
||||
public static final String PREF_SIDE_PADDING_SCALE_LANDSCAPE = "side_padding_scale_landscape";
|
||||
public static final String PREF_SPLIT_SPACER_SCALE_PREFIX = "split_spacer_scale";
|
||||
public static final String PREF_KEYBOARD_HEIGHT_SCALE_PREFIX = "keyboard_height_scale";
|
||||
public static final String PREF_BOTTOM_PADDING_SCALE_PREFIX = "bottom_padding_scale";
|
||||
public static final String PREF_SIDE_PADDING_SCALE_PREFIX = "side_padding_scale";
|
||||
public static final String PREF_FONT_SCALE = "font_scale";
|
||||
public static final String PREF_EMOJI_FONT_SCALE = "emoji_font_scale";
|
||||
public static final String PREF_EMOJI_KEY_FIT = "emoji_key_fit";
|
||||
|
@ -126,10 +123,9 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
public static final String PREF_USE_APPS = "use_apps";
|
||||
public static final String PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD = "long_press_symbols_for_numpad";
|
||||
|
||||
// one-handed mode gravity, enablement and scale, stored separately per orientation
|
||||
public static final String PREF_ONE_HANDED_MODE_PREFIX = "one_handed_mode_enabled_p_";
|
||||
public static final String PREF_ONE_HANDED_GRAVITY_PREFIX = "one_handed_mode_gravity_p_";
|
||||
public static final String PREF_ONE_HANDED_SCALE_PREFIX = "one_handed_mode_scale_p_";
|
||||
public static final String PREF_ONE_HANDED_MODE_PREFIX = "one_handed_mode_enabled";
|
||||
public static final String PREF_ONE_HANDED_GRAVITY_PREFIX = "one_handed_mode_gravity";
|
||||
public static final String PREF_ONE_HANDED_SCALE_PREFIX = "one_handed_mode_scale";
|
||||
|
||||
public static final String PREF_SHOW_NUMBER_ROW = "show_number_row";
|
||||
public static final String PREF_LOCALIZED_NUMBER_ROW = "localized_number_row";
|
||||
|
@ -365,31 +361,43 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
return prefs.getBoolean(PREF_SHOW_SETUP_WIZARD_ICON, Defaults.PREF_SHOW_SETUP_WIZARD_ICON);
|
||||
}
|
||||
|
||||
public static boolean readOneHandedModeEnabled(final SharedPreferences prefs, final boolean isLandscape) {
|
||||
return prefs.getBoolean(PREF_ONE_HANDED_MODE_PREFIX + !isLandscape, Defaults.PREF_ONE_HANDED_MODE);
|
||||
public static boolean readOneHandedModeEnabled(final SharedPreferences prefs, final boolean landscape, final boolean split) {
|
||||
final int index = SettingsKt.findIndexOfDefaultSetting(landscape, split);
|
||||
final String key = SettingsKt.createPrefKeyForBooleanSettings(PREF_ONE_HANDED_MODE_PREFIX, index, 2);
|
||||
return prefs.getBoolean(key, Defaults.PREF_ONE_HANDED_MODE);
|
||||
}
|
||||
|
||||
public void writeOneHandedModeEnabled(final boolean enabled) {
|
||||
mPrefs.edit().putBoolean(PREF_ONE_HANDED_MODE_PREFIX +
|
||||
(mSettingsValues.mDisplayOrientation != Configuration.ORIENTATION_LANDSCAPE), enabled).apply();
|
||||
final boolean landscape = mSettingsValues.mDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE;
|
||||
final int index = SettingsKt.findIndexOfDefaultSetting(landscape, mSettingsValues.mIsSplitKeyboardEnabled);
|
||||
final String key = SettingsKt.createPrefKeyForBooleanSettings(PREF_ONE_HANDED_MODE_PREFIX, index, 2);
|
||||
mPrefs.edit().putBoolean(key, enabled).apply();
|
||||
}
|
||||
|
||||
public static float readOneHandedModeScale(final SharedPreferences prefs, final boolean isLandscape) {
|
||||
return prefs.getFloat(PREF_ONE_HANDED_SCALE_PREFIX + !isLandscape, Defaults.PREF_ONE_HANDED_SCALE);
|
||||
public static float readOneHandedModeScale(final SharedPreferences prefs, final boolean landscape, final boolean split) {
|
||||
final int index = SettingsKt.findIndexOfDefaultSetting(landscape, split);
|
||||
final String key = SettingsKt.createPrefKeyForBooleanSettings(PREF_ONE_HANDED_SCALE_PREFIX, index, 2);
|
||||
return prefs.getFloat(key, Defaults.PREF_ONE_HANDED_SCALE);
|
||||
}
|
||||
|
||||
public void writeOneHandedModeScale(final Float scale) {
|
||||
mPrefs.edit().putFloat(PREF_ONE_HANDED_SCALE_PREFIX +
|
||||
(mSettingsValues.mDisplayOrientation != Configuration.ORIENTATION_LANDSCAPE), scale).apply();
|
||||
final boolean landscape = mSettingsValues.mDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE;
|
||||
final int index = SettingsKt.findIndexOfDefaultSetting(landscape, mSettingsValues.mIsSplitKeyboardEnabled);
|
||||
final String key = SettingsKt.createPrefKeyForBooleanSettings(PREF_ONE_HANDED_SCALE_PREFIX, index, 2);
|
||||
mPrefs.edit().putFloat(key, scale).apply();
|
||||
}
|
||||
|
||||
public static int readOneHandedModeGravity(final SharedPreferences prefs, final boolean isLandscape) {
|
||||
return prefs.getInt(PREF_ONE_HANDED_GRAVITY_PREFIX + !isLandscape, Defaults.PREF_ONE_HANDED_GRAVITY);
|
||||
public static int readOneHandedModeGravity(final SharedPreferences prefs, final boolean landscape, final boolean split) {
|
||||
final int index = SettingsKt.findIndexOfDefaultSetting(landscape, split);
|
||||
final String key = SettingsKt.createPrefKeyForBooleanSettings(PREF_ONE_HANDED_GRAVITY_PREFIX, index, 2);
|
||||
return prefs.getInt(key, Defaults.PREF_ONE_HANDED_GRAVITY);
|
||||
}
|
||||
|
||||
public void writeOneHandedModeGravity(final int gravity) {
|
||||
mPrefs.edit().putInt(PREF_ONE_HANDED_GRAVITY_PREFIX +
|
||||
(mSettingsValues.mDisplayOrientation != Configuration.ORIENTATION_LANDSCAPE), gravity).apply();
|
||||
final boolean landscape = mSettingsValues.mDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE;
|
||||
final int index = SettingsKt.findIndexOfDefaultSetting(landscape, mSettingsValues.mIsSplitKeyboardEnabled);
|
||||
final String key = SettingsKt.createPrefKeyForBooleanSettings(PREF_ONE_HANDED_GRAVITY_PREFIX, index, 2);
|
||||
mPrefs.edit().putInt(key, gravity).apply();
|
||||
}
|
||||
|
||||
public void writeSplitKeyboardEnabled(final boolean enabled, final boolean isLandscape) {
|
||||
|
@ -402,21 +410,32 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
return prefs.getBoolean(pref, isLandscape ? Defaults.PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE : Defaults.PREF_ENABLE_SPLIT_KEYBOARD);
|
||||
}
|
||||
|
||||
public static float readSplitSpacerScale(final SharedPreferences prefs, final boolean isLandscape) {
|
||||
final String pref = isLandscape ? PREF_SPLIT_SPACER_SCALE_LANDSCAPE : PREF_SPLIT_SPACER_SCALE;
|
||||
return prefs.getFloat(pref, isLandscape ? Defaults.PREF_SPLIT_SPACER_SCALE_LANDSCAPE : Defaults.PREF_SPLIT_SPACER_SCALE);
|
||||
public static float readSplitSpacerScale(final SharedPreferences prefs, final boolean landscape) {
|
||||
final int index = SettingsKt.findIndexOfDefaultSetting(landscape);
|
||||
final Float[] defaults = Defaults.PREF_SPLIT_SPACER_SCALE;
|
||||
final float defaultValue = defaults[index];
|
||||
return prefs.getFloat(SettingsKt.createPrefKeyForBooleanSettings(PREF_SPLIT_SPACER_SCALE_PREFIX, index, 1), defaultValue);
|
||||
}
|
||||
|
||||
public static float readBottomPaddingScale(final SharedPreferences prefs, final boolean landscape) {
|
||||
if (landscape)
|
||||
return prefs.getFloat(PREF_BOTTOM_PADDING_SCALE_LANDSCAPE, Defaults.PREF_BOTTOM_PADDING_SCALE_LANDSCAPE);
|
||||
return prefs.getFloat(PREF_BOTTOM_PADDING_SCALE, Defaults.PREF_BOTTOM_PADDING_SCALE);
|
||||
final int index = SettingsKt.findIndexOfDefaultSetting(landscape);
|
||||
final Float[] defaults = Defaults.PREF_BOTTOM_PADDING_SCALE;
|
||||
final float defaultValue = defaults[index];
|
||||
return prefs.getFloat(SettingsKt.createPrefKeyForBooleanSettings(PREF_BOTTOM_PADDING_SCALE_PREFIX, index, 1), defaultValue);
|
||||
}
|
||||
|
||||
public static float readSidePaddingScale(final SharedPreferences prefs, final boolean landscape) {
|
||||
if (landscape)
|
||||
return prefs.getFloat(PREF_SIDE_PADDING_SCALE_LANDSCAPE, Defaults.PREF_SIDE_PADDING_SCALE_LANDSCAPE);
|
||||
return prefs.getFloat(PREF_SIDE_PADDING_SCALE, Defaults.PREF_SIDE_PADDING_SCALE);
|
||||
public static float readSidePaddingScale(final SharedPreferences prefs, final boolean landscape, final boolean split) {
|
||||
final int index = SettingsKt.findIndexOfDefaultSetting(landscape, split);
|
||||
final Float[] defaults = Defaults.PREF_SIDE_PADDING_SCALE;
|
||||
final float defaultValue = defaults[index];
|
||||
return prefs.getFloat(SettingsKt.createPrefKeyForBooleanSettings(PREF_SIDE_PADDING_SCALE_PREFIX, index, 2), defaultValue);
|
||||
}
|
||||
|
||||
public static float readHeightScale(final SharedPreferences prefs, final boolean landscape) {
|
||||
final int index = SettingsKt.findIndexOfDefaultSetting(landscape);
|
||||
final Float[] defaults = Defaults.PREF_KEYBOARD_HEIGHT_SCALE;
|
||||
final float defaultValue = defaults[index];
|
||||
return prefs.getFloat(SettingsKt.createPrefKeyForBooleanSettings(PREF_KEYBOARD_HEIGHT_SCALE_PREFIX, index, 1), defaultValue);
|
||||
}
|
||||
|
||||
public static boolean readHasHardwareKeyboard(final Configuration conf) {
|
||||
|
|
|
@ -14,3 +14,13 @@ fun customIconIds(context: Context, prefs: SharedPreferences) = customIconNames(
|
|||
val id = runCatching { context.resources.getIdentifier(entry.value, "drawable", context.packageName) }.getOrNull()
|
||||
id?.let { entry.key to it }
|
||||
}
|
||||
|
||||
/** Derive an index from a number of boolean [settingValues], used to access the matching default value in a defaults arraY */
|
||||
fun findIndexOfDefaultSetting(vararg settingValues: Boolean): Int {
|
||||
var i = -1
|
||||
return settingValues.sumOf { i++; if (it) 1.shl(i) else 0 }
|
||||
}
|
||||
|
||||
/** Create pref key that is derived from a [number] of boolean conditions. The [index] is as created by [findIndexOfDefaultSetting]. */
|
||||
fun createPrefKeyForBooleanSettings(prefix: String, index: Int, number: Int): String =
|
||||
"${prefix}_${Array(number) { index.shr(it) % 2 == 1 }.joinToString("_")}"
|
||||
|
|
|
@ -42,8 +42,6 @@ import java.util.Locale;
|
|||
*/
|
||||
// Non-final for testing via mock library.
|
||||
public class SettingsValues {
|
||||
public static final float DEFAULT_SIZE_SCALE = 1.0f; // 100%
|
||||
|
||||
// From resources:
|
||||
public final SpacingAndPunctuations mSpacingAndPunctuations;
|
||||
public final long mDoubleSpacePeriodTimeout;
|
||||
|
@ -242,7 +240,7 @@ public class SettingsValues {
|
|||
mSecondaryStripVisible = mToolbarMode != ToolbarMode.HIDDEN || ! mToolbarHidingGlobal;
|
||||
mIncognitoModeEnabled = prefs.getBoolean(Settings.PREF_ALWAYS_INCOGNITO_MODE, Defaults.PREF_ALWAYS_INCOGNITO_MODE) || mInputAttributes.mNoLearning
|
||||
|| mInputAttributes.mIsPasswordField;
|
||||
mKeyboardHeightScale = prefs.getFloat(Settings.PREF_KEYBOARD_HEIGHT_SCALE, Defaults.PREF_KEYBOARD_HEIGHT_SCALE);
|
||||
mKeyboardHeightScale = Settings.readHeightScale(prefs, isLandscape);
|
||||
mSpaceSwipeHorizontal = Settings.readHorizontalSpaceSwipe(prefs);
|
||||
mSpaceSwipeVertical = Settings.readVerticalSpaceSwipe(prefs);
|
||||
mLanguageSwipeDistance = prefs.getInt(Settings.PREF_LANGUAGE_SWIPE_DISTANCE, Defaults.PREF_LANGUAGE_SWIPE_DISTANCE);
|
||||
|
@ -255,11 +253,11 @@ public class SettingsValues {
|
|||
mClipboardHistoryEnabled = prefs.getBoolean(Settings.PREF_ENABLE_CLIPBOARD_HISTORY, Defaults.PREF_ENABLE_CLIPBOARD_HISTORY);
|
||||
mClipboardHistoryRetentionTime = prefs.getInt(Settings.PREF_CLIPBOARD_HISTORY_RETENTION_TIME, Defaults.PREF_CLIPBOARD_HISTORY_RETENTION_TIME);
|
||||
|
||||
mOneHandedModeEnabled = Settings.readOneHandedModeEnabled(prefs, isLandscape);
|
||||
mOneHandedModeGravity = Settings.readOneHandedModeGravity(prefs, isLandscape);
|
||||
mOneHandedModeEnabled = Settings.readOneHandedModeEnabled(prefs, isLandscape, mIsSplitKeyboardEnabled);
|
||||
mOneHandedModeGravity = Settings.readOneHandedModeGravity(prefs, isLandscape, mIsSplitKeyboardEnabled);
|
||||
if (mOneHandedModeEnabled) {
|
||||
final float baseScale = res.getFraction(R.fraction.config_one_handed_mode_width, 1, 1);
|
||||
final float extraScale = Settings.readOneHandedModeScale(prefs, isLandscape);
|
||||
final float extraScale = Settings.readOneHandedModeScale(prefs, isLandscape, mIsSplitKeyboardEnabled);
|
||||
mOneHandedModeScale = 1 - (1 - baseScale) * extraScale;
|
||||
} else
|
||||
mOneHandedModeScale = 1f;
|
||||
|
@ -282,7 +280,7 @@ public class SettingsValues {
|
|||
);
|
||||
mSpacingAndPunctuations = new SpacingAndPunctuations(res, mUrlDetectionEnabled);
|
||||
mBottomPaddingScale = Settings.readBottomPaddingScale(prefs, isLandscape);
|
||||
mSidePaddingScale = Settings.readSidePaddingScale(prefs, isLandscape);
|
||||
mSidePaddingScale = Settings.readSidePaddingScale(prefs, isLandscape, mIsSplitKeyboardEnabled);
|
||||
mLongPressSymbolsForNumpad = prefs.getBoolean(Settings.PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD, Defaults.PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD);
|
||||
mAutoShowToolbar = mToolbarMode == ToolbarMode.EXPANDABLE && prefs.getBoolean(Settings.PREF_AUTO_SHOW_TOOLBAR, Defaults.PREF_AUTO_SHOW_TOOLBAR);
|
||||
mAutoHideToolbar = mSuggestionsEnabledPerUserSettings && prefs.getBoolean(Settings.PREF_AUTO_HIDE_TOOLBAR, Defaults.PREF_AUTO_HIDE_TOOLBAR);
|
||||
|
|
|
@ -109,7 +109,8 @@ private fun DictionaryDetails(dict: File) {
|
|||
DeleteButton { showDeleteDialog = true }
|
||||
ExpandButton { showDetails = !showDetails }
|
||||
}
|
||||
AnimatedVisibility(showDetails, enter = fadeIn(), exit = fadeOut()) { // default animation looks better, but makes the dialog flash
|
||||
// default animations look better but make the dialog flash, see also MultiSliderPreference
|
||||
AnimatedVisibility(showDetails, enter = fadeIn(), exit = fadeOut()) {
|
||||
Text(
|
||||
header.info(LocalConfiguration.current.locale()),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package helium314.keyboard.settings.preferences
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Slider
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import helium314.keyboard.latin.R
|
||||
import helium314.keyboard.latin.settings.createPrefKeyForBooleanSettings
|
||||
import helium314.keyboard.latin.utils.prefs
|
||||
import helium314.keyboard.settings.Theme
|
||||
import helium314.keyboard.settings.WithSmallTitle
|
||||
import helium314.keyboard.settings.dialogs.ThreeButtonAlertDialog
|
||||
import helium314.keyboard.settings.previewDark
|
||||
|
||||
// too specialized for using a more generic dialog
|
||||
// actual key for each setting is baseKey with one _true/_false appended per dimension (need to keep order!)
|
||||
// todo: possible adjustments, maybe depending on user feedback
|
||||
// should dimension checkboxes have any other effect than just showing / hiding sliders?
|
||||
// one could argue that e.g. when disabling the split checkbox, then split mode should not affect the setting
|
||||
// store checkbox states?
|
||||
// if so, per setting or global?
|
||||
// show a description? currently commented because it could get long, even without showing the variations
|
||||
// maybe if we store the checkbox state in a setting, we could use it for determining what to show
|
||||
@Composable
|
||||
fun MultiSliderPreference(
|
||||
name: String,
|
||||
baseKey: String,
|
||||
dimensions: List<String>,
|
||||
defaults: Array<Float>,
|
||||
range: ClosedFloatingPointRange<Float>,
|
||||
description: (Float) -> String,
|
||||
onDone: () -> Unit
|
||||
) {
|
||||
if (defaults.size != 1.shl(dimensions.size))
|
||||
throw ArithmeticException("defaults size does not match with dimensions, expected ${1.shl(dimensions.size)}, got ${defaults.size}")
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
//val (_, keys) = remember { createVariantsAndKeys(dimensions, baseKey) }
|
||||
//val prefs = LocalContext.current.prefs()
|
||||
Preference(
|
||||
name = name,
|
||||
onClick = { showDialog = true },
|
||||
//description = keys.mapIndexed { i, it -> description(prefs.getFloat(it, defaults[i])) }.joinToString(" $SPLIT ")
|
||||
)
|
||||
if (showDialog)
|
||||
MultiSliderDialog(
|
||||
onDismissRequest = { showDialog = false },
|
||||
title = { Text(name) },
|
||||
baseKey = baseKey,
|
||||
onDone = onDone,
|
||||
defaultValues = defaults,
|
||||
range = range,
|
||||
dimensions = dimensions,
|
||||
positionString = description
|
||||
)
|
||||
}
|
||||
|
||||
// SliderDialog, but for multiple sliders with same range, each with a different setting and title
|
||||
@Composable
|
||||
private fun MultiSliderDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
title: @Composable () -> Unit,
|
||||
baseKey: String,
|
||||
onDone: () -> Unit,
|
||||
defaultValues: Array<Float>,
|
||||
range: ClosedFloatingPointRange<Float>,
|
||||
dimensions: List<String>,
|
||||
modifier: Modifier = Modifier,
|
||||
positionString: (Float) -> String,
|
||||
) {
|
||||
val (variants, keys) = createVariantsAndKeys(dimensions, baseKey)
|
||||
var checked by remember { mutableStateOf(List(variants.size) { true }) }
|
||||
val prefs = LocalContext.current.prefs()
|
||||
val done = remember { mutableMapOf<String, () -> Unit>() }
|
||||
|
||||
ThreeButtonAlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
onConfirmed = { done.values.forEach { it.invoke() }; onDone() },
|
||||
modifier = modifier,
|
||||
title = title,
|
||||
content = {
|
||||
CompositionLocalProvider(
|
||||
LocalTextStyle provides MaterialTheme.typography.bodyLarge
|
||||
) {
|
||||
val state = rememberScrollState()
|
||||
Column(Modifier.verticalScroll(state)) {
|
||||
if (dimensions.size > 1) {
|
||||
dimensions.forEachIndexed { i, dimension ->
|
||||
DimensionCheckbox(checked[i], dimension) {
|
||||
checked = checked.mapIndexed { j, c -> if (i == j) it else c }
|
||||
}
|
||||
}
|
||||
}
|
||||
variants.forEachIndexed { i, variant ->
|
||||
val key = keys[i]
|
||||
var sliderPosition by remember { mutableFloatStateOf(prefs.getFloat(key, defaultValues[i])) }
|
||||
if (!done.contains(variant))
|
||||
done[variant] = {
|
||||
if (sliderPosition == defaultValues[i])
|
||||
prefs.edit().remove(key).apply()
|
||||
else
|
||||
prefs.edit().putFloat(key, sliderPosition).apply()
|
||||
}
|
||||
val forbiddenDimensions = dimensions.filterIndexed { index, _ -> !checked[index] }
|
||||
val visible = variant.split(SPLIT).none { it in forbiddenDimensions }
|
||||
// default animations make the dialog flash (see also DictionaryDialog)
|
||||
AnimatedVisibility(visible, exit = fadeOut(), enter = fadeIn()) {
|
||||
WithSmallTitle(variant.ifEmpty { stringResource(R.string.button_default) }) {
|
||||
Slider(
|
||||
value = sliderPosition,
|
||||
onValueChange = { sliderPosition = it },
|
||||
valueRange = range,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(positionString(sliderPosition))
|
||||
TextButton({ sliderPosition = defaultValues[i] }) { Text(stringResource(R.string.button_default)) }
|
||||
}
|
||||
Spacer(Modifier.height(6.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DimensionCheckbox(checked: Boolean, dimension: String, onCheckedChange: (Boolean) -> Unit) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.fillMaxWidth().clickable { onCheckedChange(!checked) }
|
||||
) {
|
||||
Checkbox(
|
||||
checked = checked,
|
||||
onCheckedChange = { onCheckedChange(it) }
|
||||
)
|
||||
Text(dimension)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createVariantsAndKeys(dimensions: List<String>, baseKey: String): Pair<List<String>, List<String>> {
|
||||
val variants = mutableListOf("")
|
||||
val keys = mutableListOf(createPrefKeyForBooleanSettings(baseKey, 0, dimensions.size))
|
||||
var i = 1
|
||||
dimensions.forEach { dimension ->
|
||||
variants.toList().forEach { variant ->
|
||||
if (variant.isEmpty()) variants.add(dimension)
|
||||
else variants.add(variant + SPLIT + dimension)
|
||||
keys.add(createPrefKeyForBooleanSettings(baseKey, i, dimensions.size))
|
||||
i++
|
||||
}
|
||||
}
|
||||
return variants to keys
|
||||
}
|
||||
|
||||
private const val SPLIT = " / "
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
Theme(previewDark) {
|
||||
MultiSliderDialog(
|
||||
onDismissRequest = { },
|
||||
onDone = { },
|
||||
positionString = { "${it.toInt()}%"},
|
||||
defaultValues = Array(8) { 100f - it % 2 * 50f },
|
||||
range = 0f..500f,
|
||||
title = { Text("bottom padding scale") },
|
||||
dimensions = listOf("landscape", "unfolded", "split"),
|
||||
baseKey = ""
|
||||
)
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ import helium314.keyboard.settings.dialogs.CustomizeIconsDialog
|
|||
import helium314.keyboard.settings.initPreview
|
||||
import helium314.keyboard.settings.preferences.BackgroundImagePref
|
||||
import helium314.keyboard.settings.preferences.CustomFontPreference
|
||||
import helium314.keyboard.settings.preferences.MultiSliderPreference
|
||||
import helium314.keyboard.settings.preferences.TextInputPreference
|
||||
import helium314.keyboard.settings.previewDark
|
||||
|
||||
|
@ -65,18 +66,15 @@ fun AppearanceScreen(
|
|||
SettingsWithoutKey.BACKGROUND_IMAGE_LANDSCAPE,
|
||||
R.string.settings_category_miscellaneous,
|
||||
Settings.PREF_ENABLE_SPLIT_KEYBOARD,
|
||||
if (prefs.getBoolean(Settings.PREF_ENABLE_SPLIT_KEYBOARD, Defaults.PREF_ENABLE_SPLIT_KEYBOARD))
|
||||
Settings.PREF_SPLIT_SPACER_SCALE else null,
|
||||
Settings.PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE,
|
||||
if (prefs.getBoolean(Settings.PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE, Defaults.PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE))
|
||||
Settings.PREF_SPLIT_SPACER_SCALE_LANDSCAPE else null,
|
||||
if (prefs.getBoolean(Settings.PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE, Defaults.PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE)
|
||||
|| prefs.getBoolean(Settings.PREF_ENABLE_SPLIT_KEYBOARD, Defaults.PREF_ENABLE_SPLIT_KEYBOARD))
|
||||
Settings.PREF_SPLIT_SPACER_SCALE_PREFIX else null,
|
||||
if (prefs.getBoolean(Settings.PREF_THEME_KEY_BORDERS, Defaults.PREF_THEME_KEY_BORDERS))
|
||||
Settings.PREF_NARROW_KEY_GAPS else null,
|
||||
Settings.PREF_KEYBOARD_HEIGHT_SCALE,
|
||||
Settings.PREF_BOTTOM_PADDING_SCALE,
|
||||
Settings.PREF_BOTTOM_PADDING_SCALE_LANDSCAPE,
|
||||
Settings.PREF_SIDE_PADDING_SCALE,
|
||||
Settings.PREF_SIDE_PADDING_SCALE_LANDSCAPE,
|
||||
Settings.PREF_KEYBOARD_HEIGHT_SCALE_PREFIX,
|
||||
Settings.PREF_BOTTOM_PADDING_SCALE_PREFIX,
|
||||
Settings.PREF_SIDE_PADDING_SCALE_PREFIX,
|
||||
Settings.PREF_SPACE_BAR_TEXT,
|
||||
SettingsWithoutKey.CUSTOM_FONT,
|
||||
Settings.PREF_FONT_SCALE,
|
||||
|
@ -196,11 +194,12 @@ fun createAppearanceSettings(context: Context) = listOf(
|
|||
Setting(context, Settings.PREF_ENABLE_SPLIT_KEYBOARD, R.string.enable_split_keyboard) {
|
||||
SwitchPreference(it, Defaults.PREF_ENABLE_SPLIT_KEYBOARD) { KeyboardSwitcher.getInstance().reloadKeyboard() }
|
||||
},
|
||||
Setting(context, Settings.PREF_SPLIT_SPACER_SCALE, R.string.split_spacer_scale) { setting ->
|
||||
SliderPreference(
|
||||
Setting(context, Settings.PREF_SPLIT_SPACER_SCALE_PREFIX, R.string.split_spacer_scale) { setting ->
|
||||
MultiSliderPreference(
|
||||
name = setting.title,
|
||||
key = setting.key,
|
||||
default = Defaults.PREF_SPLIT_SPACER_SCALE,
|
||||
baseKey = setting.key,
|
||||
dimensions = listOf(stringResource(R.string.landscape)),
|
||||
defaults = Defaults.PREF_SPLIT_SPACER_SCALE,
|
||||
range = 0.5f..2f,
|
||||
description = { "${(100 * it).toInt()}%" }
|
||||
) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
||||
|
@ -208,59 +207,35 @@ fun createAppearanceSettings(context: Context) = listOf(
|
|||
Setting(context, Settings.PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE, R.string.enable_split_keyboard_landscape) {
|
||||
SwitchPreference(it, Defaults.PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE) { KeyboardSwitcher.getInstance().reloadKeyboard() }
|
||||
},
|
||||
Setting(context, Settings.PREF_SPLIT_SPACER_SCALE_LANDSCAPE, R.string.split_spacer_scale_landscape) { setting ->
|
||||
SliderPreference(
|
||||
name = setting.title,
|
||||
key = setting.key,
|
||||
default = Defaults.PREF_SPLIT_SPACER_SCALE_LANDSCAPE,
|
||||
range = 0.5f..2f,
|
||||
description = { "${(100 * it).toInt()}%" }
|
||||
) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
||||
},
|
||||
Setting(context, Settings.PREF_NARROW_KEY_GAPS, R.string.prefs_narrow_key_gaps) {
|
||||
SwitchPreference(it, Defaults.PREF_NARROW_KEY_GAPS) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
||||
},
|
||||
Setting(context, Settings.PREF_KEYBOARD_HEIGHT_SCALE, R.string.prefs_keyboard_height_scale) { setting ->
|
||||
SliderPreference(
|
||||
Setting(context, Settings.PREF_KEYBOARD_HEIGHT_SCALE_PREFIX, R.string.prefs_keyboard_height_scale) { setting ->
|
||||
MultiSliderPreference(
|
||||
name = setting.title,
|
||||
key = setting.key,
|
||||
default = Defaults.PREF_KEYBOARD_HEIGHT_SCALE,
|
||||
baseKey = setting.key,
|
||||
dimensions = listOf(stringResource(R.string.landscape)),
|
||||
defaults = Defaults.PREF_KEYBOARD_HEIGHT_SCALE,
|
||||
range = 0.3f..1.5f,
|
||||
description = { "${(100 * it).toInt()}%" }
|
||||
) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
||||
},
|
||||
Setting(context, Settings.PREF_BOTTOM_PADDING_SCALE, R.string.prefs_bottom_padding_scale) { setting ->
|
||||
SliderPreference(
|
||||
Setting(context, Settings.PREF_BOTTOM_PADDING_SCALE_PREFIX, R.string.prefs_bottom_padding_scale) { setting ->
|
||||
MultiSliderPreference(
|
||||
name = setting.title,
|
||||
key = setting.key,
|
||||
default = Defaults.PREF_BOTTOM_PADDING_SCALE,
|
||||
baseKey = setting.key,
|
||||
dimensions = listOf(stringResource(R.string.landscape)),
|
||||
defaults = Defaults.PREF_BOTTOM_PADDING_SCALE,
|
||||
range = 0f..5f,
|
||||
description = { "${(100 * it).toInt()}%" }
|
||||
) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
||||
},
|
||||
Setting(context, Settings.PREF_BOTTOM_PADDING_SCALE_LANDSCAPE, R.string.prefs_bottom_padding_scale_landscape) { setting ->
|
||||
SliderPreference(
|
||||
Setting(context, Settings.PREF_SIDE_PADDING_SCALE_PREFIX, R.string.prefs_side_padding_scale) { setting ->
|
||||
MultiSliderPreference(
|
||||
name = setting.title,
|
||||
key = setting.key,
|
||||
default = Defaults.PREF_BOTTOM_PADDING_SCALE_LANDSCAPE,
|
||||
range = 0f..5f,
|
||||
description = { "${(100 * it).toInt()}%" }
|
||||
) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
||||
},
|
||||
Setting(context, Settings.PREF_SIDE_PADDING_SCALE, R.string.prefs_side_padding_scale) { setting ->
|
||||
SliderPreference(
|
||||
name = setting.title,
|
||||
key = setting.key,
|
||||
default = Defaults.PREF_SIDE_PADDING_SCALE,
|
||||
range = 0f..3f,
|
||||
description = { "${(100 * it).toInt()}%" }
|
||||
) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
||||
},
|
||||
Setting(context, Settings.PREF_SIDE_PADDING_SCALE_LANDSCAPE, R.string.prefs_side_padding_scale_landscape) { setting ->
|
||||
SliderPreference(
|
||||
name = setting.title,
|
||||
key = setting.key,
|
||||
default = Defaults.PREF_SIDE_PADDING_SCALE_LANDSCAPE,
|
||||
baseKey = setting.key,
|
||||
dimensions = listOf(stringResource(R.string.landscape), stringResource(R.string.split)),
|
||||
defaults = Defaults.PREF_SIDE_PADDING_SCALE,
|
||||
range = 0f..3f,
|
||||
description = { "${(100 * it).toInt()}%" }
|
||||
) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue