Refactor: Restrict sliders to new 'Slider' key kind

Setting 'slider="true"' on a key is no longer enough to make a slider,
the key must also be of kind 'Slider'.

Only the KeyValue that started sliding is now considered, they can be
generated with negative values. This allows keys that don't have the
complementary cursor movement key on the opposite direction.

This will help implement other kind of sliders as well as up/down
sliders.
This commit is contained in:
Jules Aguillon 2025-01-11 16:00:08 +01:00
parent 4f8b5fa6ce
commit 1783dcdb35
3 changed files with 61 additions and 58 deletions

View File

@ -99,7 +99,7 @@ public final class KeyEventHandler
case Compose_pending:
_recv.set_compose_pending(true);
break;
case Cursor_move: move_cursor(key.getCursorMove()); break;
case Slider: handle_slider(key.getSlider(), key.getSliderRepeat()); break;
case Complex: send_complex_key(key.getComplexKind(), key.getComplex()); break;
}
update_meta_state(old_mods);
@ -262,6 +262,15 @@ public final class KeyEventHandler
return conn.getExtractedText(_move_cursor_req, 0);
}
void handle_slider(KeyValue.Slider s, int repeatition)
{
switch (s)
{
case Cursor_left: move_cursor(-repeatition); break;
case Cursor_right: move_cursor(repeatition); break;
}
}
/** Move the cursor right or left, if possible without sending key events.
Unlike arrow keys, the selection is not removed even if shift is not on.
Falls back to sending arrow keys events if the editor do not support

View File

@ -92,7 +92,7 @@ public final class KeyValue implements Comparable<KeyValue>
{
Char, String, Keyevent, Event, Compose_pending, Hangul_initial,
Hangul_medial, Modifier, Editing, Placeholder,
Cursor_move, // Value is encoded as a 16-bit integer.
Slider, // [_payload] is a [KeyValue.Slider], value is slider repeatition.
Complex, // [_payload] is a [KeyValue.Complex], value is [Complex.Kind].
}
@ -211,10 +211,16 @@ public final class KeyValue implements Comparable<KeyValue>
return (_code & VALUE_BITS);
}
/** Defined only when [getKind() == Kind.Cursor_move]. */
public short getCursorMove()
/** Defined only when [getKind() == Kind.Slider]. */
public Slider getSlider()
{
return (short)(_code & VALUE_BITS);
return (Slider)_payload;
}
/** Defined only when [getKind() == Kind.Slider]. */
public int getSliderRepeat()
{
return ((int)(short)(_code & VALUE_BITS));
}
/** Defined only when [getKind() == Kind.Complex]. */
@ -284,6 +290,7 @@ public final class KeyValue implements Comparable<KeyValue>
return "[KeyValue " + getKind().toString() + "+" + getFlags() + "+" + value + " \"" + getString() + "\"]";
}
/** [value] is an unsigned integer. */
private KeyValue(Comparable p, int kind, int value, int flags)
{
if (p == null)
@ -367,13 +374,12 @@ public final class KeyValue implements Comparable<KeyValue>
return editingKey(String.valueOf((char)symbol), action, FLAG_KEY_FONT);
}
/** A key that moves the cursor [d] times to the right. If [d] is negative,
it moves the cursor [abs(d)] times to the left. */
public static KeyValue cursorMoveKey(int d)
/** A key that slides the property specified by [s] by the amount specified
with [repeatition]. */
public static KeyValue sliderKey(Slider s, int repeatition)
{
int symbol = (d < 0) ? 0xE008 : 0xE006;
return new KeyValue(String.valueOf((char)symbol), Kind.Cursor_move,
((short)d) & 0xFFFF,
// Casting to a short then back to a int to preserve the sign bit.
return new KeyValue(s, Kind.Slider, (short)repeatition & 0xFFFF,
FLAG_SPECIAL | FLAG_SECONDARY | FLAG_KEY_FONT);
}
@ -679,8 +685,8 @@ public final class KeyValue implements Comparable<KeyValue>
case "pasteAsPlainText": return editingKey(0xE035, Editing.PASTE_PLAIN);
case "undo": return editingKey(0xE036, Editing.UNDO);
case "redo": return editingKey(0xE037, Editing.REDO);
case "cursor_left": return cursorMoveKey(-1);
case "cursor_right": return cursorMoveKey(1);
case "cursor_left": return sliderKey(Slider.Cursor_left, 1);
case "cursor_right": return sliderKey(Slider.Cursor_right, 1);
// These keys are not used
case "replaceText": return editingKey("repl", Editing.REPLACE);
case "textAssist": return editingKey(0xE038, Editing.ASSIST);
@ -795,4 +801,20 @@ public final class KeyValue implements Comparable<KeyValue>
}
}
};
public static enum Slider
{
Cursor_left(0xE008),
Cursor_right(0xE006);
final String symbol;
Slider(int symbol_)
{
symbol = String.valueOf((char)symbol_);
}
@Override
public String toString() { return symbol; }
};
}

View File

@ -294,13 +294,9 @@ public final class Pointers implements Handler.Callback
ptr.value = new_value;
ptr.flags = pointer_flags_of_kv(new_value);
// Sliding mode is entered when key5 or key6 is down on a slider key.
if (ptr.key.slider &&
(new_value.equals(ptr.key.getKeyValue(5))
|| new_value.equals(ptr.key.getKeyValue(6))))
{
startSliding(ptr, x, dx < 0 ? -1 : 1);
}
// Start sliding mode
if (ptr.key.slider && new_value.getKind() == KeyValue.Kind.Slider)
startSliding(ptr, x, (dx < 0 ? -1 : 1), new_value);
_handler.onPointerDown(new_value, true);
}
@ -453,12 +449,13 @@ public final class Pointers implements Handler.Callback
// Sliding
void startSliding(Pointer ptr, float x, int dir)
/** [kv] must be of kind [Slider]. */
void startSliding(Pointer ptr, float x, int dir, KeyValue kv)
{
stopLongPress(ptr);
ptr.flags |= FLAG_P_SLIDING;
ptr.sliding = new Sliding(x);
ptr.sliding.move(ptr, dir);
ptr.sliding = new Sliding(x, dir * kv.getSliderRepeat(), kv.getSlider());
_handler.onPointerHold(kv, ptr.modifiers);
}
/** Return the [FLAG_P_*] flags that correspond to pressing [kv]. */
@ -574,10 +571,17 @@ public final class Pointers implements Handler.Callback
/** [System.currentTimeMillis()] at the time of the last move. Equals to
[-1] when the sliding hasn't started yet. */
long last_move_ms = -1;
/** The property which is being slided. */
KeyValue.Slider slider;
/** Direction of the initial movement, positive if sliding to the right and
negative if sliding to the left. */
int direction;
public Sliding(float x)
public Sliding(float x, int dir, KeyValue.Slider s)
{
last_x = x;
slider = s;
direction = dir;
}
static final float SPEED_SMOOTHING = 0.7f;
@ -602,7 +606,8 @@ public final class Pointers implements Handler.Callback
if (d_ != 0)
{
d -= d_;
move(ptr, d_);
_handler.onPointerHold(KeyValue.sliderKey(slider, d_ * direction),
ptr.modifiers);
}
}
@ -615,39 +620,6 @@ public final class Pointers implements Handler.Callback
_handler.onPointerFlagsChanged(false);
}
public void move(Pointer ptr, int d_)
{
int key_index = (d_ < 0) ? 5 : 6;
ptr.value = _handler.modifyKey(ptr.key.keys[key_index], ptr.modifiers);
send_key(ptr, Math.abs(d_));
}
/** Send the pressed key [n] times. */
void send_key(Pointer ptr, int n)
{
if (ptr.value == null)
return;
// Avoid looping if possible to avoid lag while sliding fast
KeyValue multiplied = multiply_key(ptr.value, n);
if (multiplied != null)
_handler.onPointerHold(multiplied, ptr.modifiers);
else
for (int i = 0; i < n; i++)
_handler.onPointerHold(ptr.value, ptr.modifiers);
}
/** Return a key performing the same action as [kv] but [n] times. Returns
[null] if [kv] cannot be multiplied. */
KeyValue multiply_key(KeyValue kv, int n)
{
switch (kv.getKind())
{
case Cursor_move:
return KeyValue.cursorMoveKey(kv.getCursorMove() * n);
}
return null;
}
/** [speed] is computed from the elapsed time and distance traveled
between two move events. Exponential smoothing is used to smooth out
the noise. Sets [last_move_ms] and [last_x]. */