feat(ui): a scrollbar held where it was taken, a popover that keeps the mouse, easing that lands

- the scrollbar is .ui-scrollbar with a .ui-thumb, styled by the default sheet or a theme; a press
  on the thumb holds it at the point it was taken and the pointer moves it in proportion, a press on
  the track jumps the thumb's middle there and holds it, and neither presses what is under the bar
  (it used to centre the thumb on the pointer and press the row beneath as well);
- while a popover is up only scroll boxes inside it take the pointer, and a press outside it that
  closes it forgets any press in progress;
- a transition ends exactly on its value (it stopped a rounding error short, at every frame rate).

Tests: ui_popover_mouse, ui_scrollbar, ui_ease (60/120/180/240 Hz).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-24 21:39:28 +03:00
parent 9f59000f5b
commit a4c7a756f0
19 changed files with 299 additions and 29 deletions

View file

@ -1,6 +1,6 @@
# pointer.ludic - the pointer: what it is over is :hover (the element and all around it, as in CSS),
# a press on a control focuses it and makes it :active, and letting go over it is a click. The
# control being dragged (a range's thumb, a scrollbar) keeps the pointer until it is let go.
# pointer.ludic - the pointer: what it is over is :hover (and all around it, as in CSS), a press on a
# control focuses it and makes it :active, letting go over it is a click. A dragged thumb or scrollbar
# keeps the pointer until let go; a press that takes a scrollbar or closes a popover presses nothing else.
var fr_hover: []string = new []string
var fr_press_key: string = ""
var fr_down_now: bool = false
@ -16,6 +16,7 @@ function fr_pointer(root: UiNode) -> void {
fr_hover = keys
tt_track(scope, i.x, i.y)
if top != null and pp_pointer(top) { return }
if sc_drag != "" { return }
let hit = fr_hit(scope, i.x, i.y)
if i.down and not in_was_down {
ct_key_pressed_away(hit)