Merge pull request #231 from ilya-pevzner/handle-double-clicks

Handle double clicks
This commit is contained in:
Aran-Fey
2025-03-21 23:01:36 +01:00
committed by GitHub
2 changed files with 58 additions and 2 deletions

View File

@@ -9,6 +9,8 @@ export type PointerEventListenerState = ComponentState & {
_type_: "PointerEventListener-builtin";
content: ComponentId;
reportPress: MouseButton[];
reportDoublePress: MouseButton[];
doublePressDelay: number;
reportPointerDown: MouseButton[];
reportPointerUp: MouseButton[];
reportPointerMove: boolean;
@@ -21,6 +23,7 @@ export type PointerEventListenerState = ComponentState & {
export class PointerEventListenerComponent extends ComponentBase<PointerEventListenerState> {
private _dragHandler: DragHandler | null = null;
private _pressTimeout: number | null = null;
createElement(): HTMLElement {
let element = document.createElement("div");
@@ -40,15 +43,52 @@ export class PointerEventListenerComponent extends ComponentBase<PointerEventLis
if (deltaState.reportPress.length > 0) {
this.element.onclick = (e) => {
if (eventMatchesButton(e, deltaState.reportPress!)) {
if (this._pressTimeout !== null) {
clearTimeout(this._pressTimeout);
}
if (deltaState.reportDoublePress) {
this._pressTimeout = window.setTimeout(() => {
this._sendEventToBackend(
"press",
e as PointerEvent,
false
);
this._pressTimeout = null;
}, deltaState.doublePressDelay * 1000);
} else {
this._sendEventToBackend(
"press",
e as PointerEvent,
false
);
}
}
};
} else {
this.element.onclick = null;
}
}
if (deltaState.reportDoublePress) {
if (deltaState.reportDoublePress.length > 0) {
this.element.ondblclick = (e) => {
if (this._pressTimeout !== null) {
clearTimeout(this._pressTimeout);
}
if (
this._pressTimeout !== null ||
!deltaState.reportPress
) {
this._pressTimeout = null;
this._sendEventToBackend(
"press",
"doublePress",
e as PointerEvent,
false
);
}
};
} else {
this.element.onclick = null;
this.element.ondblclick = null;
}
}

View File

@@ -135,6 +135,12 @@ class PointerEventListener(FundamentalComponent):
`on_press`: Similar to `on_pointer_up`, but performs additional subtle
checks, such as that the pressed mouse button was the left one.
`on_double_press`: Similar to `on_press`, but triggered when the mouse
button is double-pressed.
`double_press_delay`: The maximum time in seconds between two presses that
should be considered a double press.
`on_pointer_down`: Triggered when a pointer button is pressed down while
the pointer is placed over the child component.
@@ -164,6 +170,8 @@ class PointerEventListener(FundamentalComponent):
content: rio.Component
_: dataclasses.KW_ONLY
on_press: rio.EventHandler[PointerEvent] = None
on_double_press: rio.EventHandler[PointerEvent] = None
double_press_delay: float = 0.3
on_pointer_down: rio.EventHandler[PointerEvent] = None
on_pointer_up: rio.EventHandler[PointerEvent] = None
on_pointer_move: rio.EventHandler[PointerMoveEvent] = None
@@ -176,6 +184,8 @@ class PointerEventListener(FundamentalComponent):
def _custom_serialize_(self) -> JsonDoc:
return {
"reportPress": _list_buttons_to_report(self.on_press),
"reportDoublePress": _list_buttons_to_report(self.on_double_press),
"doublePressDelay": self.double_press_delay,
"reportPointerDown": _list_buttons_to_report(self.on_pointer_down),
"reportPointerUp": _list_buttons_to_report(self.on_pointer_up),
"reportPointerMove": self.on_pointer_move is not None,
@@ -200,6 +210,12 @@ class PointerEventListener(FundamentalComponent):
PointerEvent._from_message(msg),
)
elif msg_type == "doublePress":
await self.call_event_handler(
self.on_double_press,
PointerEvent._from_message(msg),
)
elif msg_type == "pointerDown":
await self._call_appropriate_event_handler(
self.on_pointer_down,