mirror of
https://github.com/Julow/Unexpected-Keyboard.git
synced 2024-12-23 22:48:54 +01:00
Hold any modifier to lock
Modifiers can be locked with a long press. The key repeat mechanism is re-used and the press timeout is the same. Every modifiers can be locked that way, not only the "lockable" ones. The previous behavior can be enabled in the settings (for shift only) but the default is changed.
This commit is contained in:
parent
081e9a6e53
commit
53b9afa973
@ -25,6 +25,8 @@
|
||||
<string name="pref_precise_repeat_summary">Modulate key repeat speed by swiping more or less</string>
|
||||
<string name="pref_lockable_keys_title">Lockable modifiers</string>
|
||||
<string name="pref_lockable_keys_summary">Modifiers that can be locked by typing them twice</string>
|
||||
<string name="pref_lock_double_tap_title">Double tap on shift for caps lock</string>
|
||||
<string name="pref_lock_double_tap_summary">Instead of holding modifiers for a time</string>
|
||||
<string name="pref_category_style">Style</string>
|
||||
<string name="pref_margin_bottom_title">Margin bottom</string>
|
||||
<string name="pref_keyboard_height_title">Keyboard height</string>
|
||||
|
@ -11,8 +11,8 @@
|
||||
<juloo.common.IntSlideBarPreference android:key="longpress_timeout" android:title="@string/pref_long_timeout_title" android:summary="%sms" android:defaultValue="600" min="50" max="2000"/>
|
||||
<juloo.common.IntSlideBarPreference android:key="longpress_interval" android:title="@string/pref_long_interval_title" android:summary="%sms" android:defaultValue="25" min="5" max="100"/>
|
||||
<CheckBoxPreference android:key="precise_repeat" android:title="@string/pref_precise_repeat_title" android:summary="@string/pref_precise_repeat_summary" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:key="lock_double_tap" android:title="@string/pref_lock_double_tap_title" android:summary="@string/pref_lock_double_tap_summary" android:defaultValue="false"/>
|
||||
<PreferenceScreen android:title="@string/pref_lockable_keys_title" android:summary="@string/pref_lockable_keys_summary">
|
||||
<CheckBoxPreference android:key="lockable_shift" android:title="Shift" android:defaultValue="true"/>
|
||||
<CheckBoxPreference android:key="lockable_ctrl" android:title="Ctrl" android:defaultValue="false"/>
|
||||
<CheckBoxPreference android:key="lockable_alt" android:title="Alt" android:defaultValue="false"/>
|
||||
<CheckBoxPreference android:key="lockable_fn" android:title="Fn" android:defaultValue="false"/>
|
||||
|
@ -134,7 +134,8 @@ final class Config
|
||||
+ res.getDimension(R.dimen.extra_horizontal_margin);
|
||||
preciseRepeat = prefs.getBoolean("precise_repeat", preciseRepeat);
|
||||
lockable_modifiers.clear();
|
||||
if (prefs.getBoolean("lockable_shift", true)) lockable_modifiers.add(KeyValue.Modifier.SHIFT);
|
||||
if (prefs.getBoolean("lock_double_tap", false))
|
||||
lockable_modifiers.add(KeyValue.Modifier.SHIFT);
|
||||
if (prefs.getBoolean("lockable_ctrl", false)) lockable_modifiers.add(KeyValue.Modifier.CTRL);
|
||||
if (prefs.getBoolean("lockable_alt", false)) lockable_modifiers.add(KeyValue.Modifier.ALT);
|
||||
if (prefs.getBoolean("lockable_fn", false)) lockable_modifiers.add(KeyValue.Modifier.FN);
|
||||
|
@ -133,9 +133,11 @@ public class Keyboard2View extends View
|
||||
_config.handler.handleKeyUp(k, mods);
|
||||
}
|
||||
|
||||
public void onPointerFlagsChanged()
|
||||
public void onPointerFlagsChanged(boolean shouldVibrate)
|
||||
{
|
||||
invalidate();
|
||||
if (shouldVibrate)
|
||||
vibrate();
|
||||
}
|
||||
|
||||
private void updateFlags()
|
||||
|
@ -104,11 +104,8 @@ public final class Pointers implements Handler.Callback
|
||||
if (latched != null) // Already latched
|
||||
{
|
||||
removePtr(ptr); // Remove dupplicate
|
||||
if ((latched.flags & KeyValue.FLAG_LOCK) != 0) // Locking key, toggle lock
|
||||
{
|
||||
latched.flags = (latched.flags & ~KeyValue.FLAG_LOCK) | KeyValue.FLAG_LOCKED;
|
||||
_handler.onPointerFlagsChanged();
|
||||
}
|
||||
if ((latched.flags & KeyValue.FLAG_LOCK) != 0) // Toggle lockable key
|
||||
lockPointer(latched, false);
|
||||
else // Otherwise, unlatch
|
||||
{
|
||||
removePtr(latched);
|
||||
@ -119,7 +116,7 @@ public final class Pointers implements Handler.Callback
|
||||
{
|
||||
ptr.flags &= ~KeyValue.FLAG_LATCH;
|
||||
ptr.pointerId = -1; // Latch
|
||||
_handler.onPointerFlagsChanged();
|
||||
_handler.onPointerFlagsChanged(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -136,7 +133,7 @@ public final class Pointers implements Handler.Callback
|
||||
return;
|
||||
stopKeyRepeat(ptr);
|
||||
removePtr(ptr);
|
||||
_handler.onPointerFlagsChanged();
|
||||
_handler.onPointerFlagsChanged(true);
|
||||
}
|
||||
|
||||
/* Whether an other pointer is down on a non-special key. */
|
||||
@ -161,8 +158,7 @@ public final class Pointers implements Handler.Callback
|
||||
KeyValue value = handleKV(key.key0, mods);
|
||||
Pointer ptr = new Pointer(pointerId, key, value, x, y, mods);
|
||||
_ptrs.add(ptr);
|
||||
if (value != null && !value.hasFlags(KeyValue.FLAG_SPECIAL))
|
||||
startKeyRepeat(ptr);
|
||||
startKeyRepeat(ptr);
|
||||
_handler.onPointerDown(false);
|
||||
}
|
||||
|
||||
@ -245,8 +241,7 @@ public final class Pointers implements Handler.Callback
|
||||
if ((old_flags & ptr.flags & KeyValue.FLAG_PRECISE_REPEAT) == 0)
|
||||
{
|
||||
stopKeyRepeat(ptr);
|
||||
if ((ptr.flags & KeyValue.FLAG_SPECIAL) == 0)
|
||||
startKeyRepeat(ptr);
|
||||
startKeyRepeat(ptr);
|
||||
}
|
||||
_handler.onPointerDown(true);
|
||||
}
|
||||
@ -291,12 +286,19 @@ public final class Pointers implements Handler.Callback
|
||||
// Latched and not locked, remove
|
||||
if (ptr.pointerId == -1 && (ptr.flags & KeyValue.FLAG_LOCKED) == 0)
|
||||
_ptrs.remove(i);
|
||||
// Not latched but pressed, don't latch once released
|
||||
// Not latched but pressed, don't latch once released and stop long press.
|
||||
else if ((ptr.flags & KeyValue.FLAG_LATCH) != 0)
|
||||
ptr.flags &= ~KeyValue.FLAG_LATCH;
|
||||
}
|
||||
}
|
||||
|
||||
/** Make a pointer into the locked state. */
|
||||
private void lockPointer(Pointer ptr, boolean shouldVibrate)
|
||||
{
|
||||
ptr.flags = (ptr.flags & ~KeyValue.FLAG_LOCK) | KeyValue.FLAG_LOCKED;
|
||||
_handler.onPointerFlagsChanged(shouldVibrate);
|
||||
}
|
||||
|
||||
private boolean isModulatedKeyPressed()
|
||||
{
|
||||
for (Pointer ptr : _ptrs)
|
||||
@ -317,26 +319,33 @@ public final class Pointers implements Handler.Callback
|
||||
{
|
||||
if (ptr.timeoutWhat == msg.what)
|
||||
{
|
||||
long nextInterval = _config.longPressInterval;
|
||||
if (_config.preciseRepeat && (ptr.flags & KeyValue.FLAG_PRECISE_REPEAT) != 0)
|
||||
{
|
||||
// Slower repeat for modulated keys
|
||||
nextInterval *= 2;
|
||||
// Modulate repeat interval depending on the distance of the pointer
|
||||
nextInterval = (long)((float)nextInterval / modulatePreciseRepeat(ptr));
|
||||
}
|
||||
_keyrepeat_handler.sendEmptyMessageDelayed(msg.what, nextInterval);
|
||||
_handler.onPointerHold(ptr.value, ptr.modifiers);
|
||||
return (true);
|
||||
if (handleKeyRepeat(ptr))
|
||||
_keyrepeat_handler.sendEmptyMessageDelayed(msg.what, nextRepeatInterval(ptr));
|
||||
else
|
||||
ptr.timeoutWhat = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
return false;
|
||||
}
|
||||
|
||||
private long nextRepeatInterval(Pointer ptr)
|
||||
{
|
||||
long t = _config.longPressInterval;
|
||||
if (_config.preciseRepeat && (ptr.flags & KeyValue.FLAG_PRECISE_REPEAT) != 0)
|
||||
{
|
||||
// Modulate repeat interval depending on the distance of the pointer
|
||||
t = (long)((float)t * 2.f / modulatePreciseRepeat(ptr));
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
private static int uniqueTimeoutWhat = 0;
|
||||
|
||||
private void startKeyRepeat(Pointer ptr)
|
||||
{
|
||||
if (ptr.value == null)
|
||||
return;
|
||||
int what = (uniqueTimeoutWhat++);
|
||||
ptr.timeoutWhat = what;
|
||||
long timeout = _config.longPressTimeout;
|
||||
@ -356,6 +365,22 @@ public final class Pointers implements Handler.Callback
|
||||
}
|
||||
}
|
||||
|
||||
/** A pointer is repeating. Returns [true] if repeat should continue. */
|
||||
private boolean handleKeyRepeat(Pointer ptr)
|
||||
{
|
||||
// Long press toggle lock on modifiers
|
||||
if ((ptr.flags & KeyValue.FLAG_LATCH) != 0)
|
||||
{
|
||||
lockPointer(ptr, true);
|
||||
return false;
|
||||
}
|
||||
// Stop repeating: Latched key, special keys
|
||||
if (ptr.pointerId == -1 || (ptr.flags & KeyValue.FLAG_SPECIAL) != 0)
|
||||
return false;
|
||||
_handler.onPointerHold(ptr.value, ptr.modifiers);
|
||||
return true;
|
||||
}
|
||||
|
||||
private float modulatePreciseRepeat(Pointer ptr)
|
||||
{
|
||||
if (ptr.repeatingPtrDist < 0.f)
|
||||
@ -468,7 +493,7 @@ public final class Pointers implements Handler.Callback
|
||||
public void onPointerUp(KeyValue k, Modifiers flags);
|
||||
|
||||
/** Flags changed because latched or locked keys or cancelled pointers. */
|
||||
public void onPointerFlagsChanged();
|
||||
public void onPointerFlagsChanged(boolean shouldVibrate);
|
||||
|
||||
/** Key is repeating. */
|
||||
public void onPointerHold(KeyValue k, Modifiers flags);
|
||||
|
Loading…
Reference in New Issue
Block a user