From the fence's kept frames in 22 minutes of play: - A component field that is a record or a list of records was `value_put(o, k, view_val_T(x))`, a whole new tree every frame (HudPrompt's notifications). view_fill.ludic generates view_set_T / view_set_list_T / view_fill_T that fill the object and list under the key in place. - value_list_fit dropped the items it cut off and value_item made new ones as the list grew back, a Value per item per regrowth (value_item / value_set_strs); the cut-off items are now the list's spares (Val.spare), and an item of another kind is turned rather than replaced. - ludic.ui: a scroll box's "scroll" and a slider's "change" fired a fresh Value.float a frame (sc_walk, scroll.ludic:36); ui_fire_float takes one from a ring kept with the state (fired.ludic). ui_object_fit_into is exported, for a draw that keeps its list. - Json.read_file(path): read, parsed, and the file's text given back - Json.parse(Fs.read_text()) kept the whole file on every read (Maroon Lake's settings peeks). Golden value_list_regrow: a list alternating 6 and 2 items every frame keeps nothing (the toolchain before this fails it: +128 B new Val from value_item). Game compiles; ludic.i18n/settings/hints/ base tests pass (ludic.ui has none); arena and fence goldens unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
40 lines
1.6 KiB
Text
40 lines
1.6 KiB
Text
# layout_fit.ludic - aspect-ratio in layout: a width (fixed, a share, or fill) makes the height, a
|
|
# height the width, and neither the height from the content's width; object-fit in drawing: where a
|
|
# picture (or a native's content) of a natural size goes in the element's content box
|
|
function ly_ratio(n: UiNode, fixed_w: float, avail: float) -> void {
|
|
if n.ex == null or n.ex.ratio <= 0.0 { return }
|
|
let r = n.ex.ratio
|
|
if n.h < 0.0 and n.h_pct <= 0.0 {
|
|
var w = n.mw
|
|
if fixed_w >= 0.0 { w = fixed_w } else if n.w == UI_FILL { w = avail - n.ml - n.mr }
|
|
n.mw = w
|
|
n.mh = w / r
|
|
} else if fixed_w < 0.0 and n.w != UI_FILL and n.h >= 0.0 { n.mw = n.h * r }
|
|
}
|
|
# x, y, w, h: a `nat_w` x `nat_h` picture in the node's content box by its object-fit
|
|
export function ui_object_fit(n: UiNode, nat_w: float, nat_h: float) -> []float { return ui_object_fit_into(new []float, n, nat_w, nat_h) }
|
|
# ... into the caller's kept list (a draw every frame should: ui_object_fit makes one a call)
|
|
export function ui_object_fit_into(out: []float, n: UiNode, nat_w: float, nat_h: float) -> []float {
|
|
let bx = n.x + n.pl + n.bl
|
|
let by = n.y + n.pt + n.bt
|
|
let bw = n.cw - ly_hin(n)
|
|
let bh = n.ch - ly_vin(n)
|
|
var k = 0
|
|
if n.ex != null { k = n.ex.fit_obj }
|
|
var w = bw
|
|
var h = bh
|
|
if k != 0 and nat_w > 0.0 and nat_h > 0.0 {
|
|
var s = Math.min(bw / nat_w, bh / nat_h)
|
|
if k == 2 { s = Math.max(bw / nat_w, bh / nat_h) }
|
|
if k == 3 { s = 1.0 }
|
|
if k == 4 { s = Math.min(s, 1.0) }
|
|
w = nat_w * s
|
|
h = nat_h * s
|
|
}
|
|
List.clear(out)
|
|
ui_kept(out, bx + (bw - w) / 2.0)
|
|
ui_kept(out, by + (bh - h) / 2.0)
|
|
ui_kept(out, w)
|
|
ui_kept(out, h)
|
|
return out
|
|
}
|