feat(ui): scroll-top holds a scroll box at an offset, on-scroll, and ui_scroll_set
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
cf8b9e425e
commit
abf45ef9db
10 changed files with 85 additions and 1 deletions
|
|
@ -25,6 +25,7 @@ import "input_pad.ludic"
|
|||
import "focus.ludic"
|
||||
import "scroll.ludic"
|
||||
import "scroll_bar.ludic"
|
||||
import "scroll_held.ludic"
|
||||
import "popover.ludic"
|
||||
import "popover_anchor.ludic"
|
||||
import "popover_within.ludic"
|
||||
|
|
|
|||
|
|
@ -32,9 +32,11 @@ function sc_walk(n: UiNode, live: bool) -> void {
|
|||
if n.kind == UI_SCROLL {
|
||||
let room = n.ch - ly_vin(n)
|
||||
let most = Math.max(n.content_h - ly_vin(n) - room, 0.0)
|
||||
var off = sc_get(n.key)
|
||||
let held = sc_held(n, sc_get(n.key), live)
|
||||
var off = held
|
||||
if live { off = sc_input(n, off, room, most) }
|
||||
off = Math.clamp(off, 0.0, most)
|
||||
if live and off != Math.clamp(held, 0.0, most) { ui_fire(n, "scroll", Value.float(off / ui_px(1.0))) }
|
||||
sc_put(n.key, off)
|
||||
n.scroll_y = off
|
||||
if off != 0.0 {
|
||||
|
|
|
|||
29
packages/ludic.ui/scroll_held.ludic
Normal file
29
packages/ludic.ui/scroll_held.ludic
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# scroll_held.ludic - a scroll box held at an offset: scroll-top="{px}" puts it there every frame
|
||||
# (the wheel, the bar and the focus still move it, and say so with on-scroll and event.value, for
|
||||
# the program to keep or not), and ui_scroll_set(id or key, px) moves it once
|
||||
var sc_want_keys: []string = new []string
|
||||
var sc_want_px: []float = new []float
|
||||
export function ui_scroll_set(key: string, px: float) -> void {
|
||||
push(sc_want_keys, key)
|
||||
push(sc_want_px, px)
|
||||
}
|
||||
# how far a box is scrolled before this frame's input: what it was, what ui_scroll_set asked for,
|
||||
# or what its scroll-top says
|
||||
function sc_held(n: UiNode, off: float, live: bool) -> float {
|
||||
var at = off
|
||||
if live {
|
||||
let keys = new []string
|
||||
let pxs = new []float
|
||||
for i in 0 .. len(sc_want_keys) {
|
||||
if sc_want_keys[i] == n.key or (n.id != "" and sc_want_keys[i] == n.id) { at = ui_px(sc_want_px[i]) } else {
|
||||
push(keys, sc_want_keys[i])
|
||||
push(pxs, sc_want_px[i])
|
||||
}
|
||||
}
|
||||
sc_want_keys = keys
|
||||
sc_want_px = pxs
|
||||
}
|
||||
let v = ui_attr(n, "scroll-top")
|
||||
if Value.kind(v) != 0 { at = ui_px(el_num(vl_text(v))) }
|
||||
return at
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue