12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788(******************************************************************************)(* *)(* SPDX-License-Identifier: MIT *)(* Copyright (c) 2026 Nomadic Labs <contact@nomadic-labs.com> *)(* *)(******************************************************************************)(** Mouse event parsing utilities for widgets.
Provides helpers to parse mouse key strings dispatched by drivers
(e.g., "Mouse:5:10", "MouseDrag:3:7", "WheelUp", "WheelDown"). *)(** Mouse click/drag event with coordinates. *)typemouse_event={row:int;col:int}(** Parse a "Mouse:row:col", "DoubleClick:row:col", "TripleClick:row:col",
or "MouseDrag:row:col" key string.
Returns [Some {row; col}] if valid, [None] otherwise. *)letparse_clickkey=lettry_parseprefix=letplen=String.lengthprefixinifString.lengthkey>plen&&String.subkey0plen=prefixthenletrest=String.subkeyplen(String.lengthkey-plen)inmatchString.split_on_char':'restwith|[row_s;col_s]->(trySome{row=int_of_stringrow_s;col=int_of_stringcol_s}withFailure_->None)|_->NoneelseNoneinmatchtry_parse"Mouse:"with|Someev->Someev|None->(matchtry_parse"DoubleClick:"with|Someev->Someev|None->(matchtry_parse"TripleClick:"with|Someev->Someev|None->try_parse"MouseDrag:"))(** Check if key is a mouse click event ("Mouse:..."). *)letis_clickkey=String.lengthkey>6&&String.subkey06="Mouse:"(** Check if key is a double-click event ("DoubleClick:..."). *)letis_double_clickkey=String.lengthkey>12&&String.subkey012="DoubleClick:"(** Check if key is a triple-click event ("TripleClick:..."). *)letis_triple_clickkey=String.lengthkey>12&&String.subkey012="TripleClick:"(** Check if key is a mouse drag event ("MouseDrag:..."). *)letis_dragkey=String.lengthkey>10&&String.subkey010="MouseDrag:"(** Check if key is a wheel up event. *)letis_wheel_upkey=key="WheelUp"(** Check if key is a wheel down event. *)letis_wheel_downkey=key="WheelDown"(** Check if key is any wheel event. *)letis_wheelkey=is_wheel_upkey||is_wheel_downkey(** Check if key is any mouse-related event. *)letis_mouse_eventkey=is_clickkey||is_double_clickkey||is_triple_clickkey||is_dragkey||is_wheelkey(** Scroll amount for wheel events (number of lines). *)letwheel_scroll_lines=3(** Translate mouse coordinates by subtracting offsets.
Used to convert screen-absolute coordinates to widget-relative coordinates.
For click/drag events: subtracts [row_offset] from row and [col_offset] from col.
For non-mouse or wheel events: returns the key unchanged. *)lettranslate_key~row_offset~col_offsetkey=matchparse_clickkeywith|Some{row;col}->letnew_row=row-row_offsetinletnew_col=col-col_offsetinletprefix=ifis_double_clickkeythen"DoubleClick:"elseifis_triple_clickkeythen"TripleClick:"elseifis_dragkeythen"MouseDrag:"else"Mouse:"inPrintf.sprintf"%s%d:%d"prefixnew_rownew_col|None->key