# inspect.ludic - what an inspector asks of the last frame shown (ludic ui-preview, a developer's # tools): a screen's root, an element by id, the rules that style it, and whether a build is running # the root of the screen `screen` as it was last shown, or null export function ui_root(ui_st: UiState, screen: string) -> UiNode { for i in 0 .. len(ui_st.fb_roots) { if ui_st.fb_roots[i].key == screen { return ui_st.fb_roots[i] } } return null } # the element with that id (or key) on any screen shown, or null export function ui_find(ui_st: UiState, id: string) -> UiNode { for i in 0 .. len(ui_st.fb_roots) { let n = fb_find(ui_st.fb_roots[i], id) if n != null { return n } } return null } # true while a frame's tree is being built (a model read), false while an action runs (a press) export function ui_building(ui_st: UiState) -> bool { return ui_st.uv_on } # the rules that match the element now, in the order the cascade applies them: the default sheet's, # then its file's (merged with each user's sheet for a component's root); its style="..." is not one @alloc_ok("an inspector's question, never a frame") export function ui_rules_of(ui_st: mut UiState, n: UiNode, out: []UiRule) -> void { List.clear(out) ir_sheet(ui_st, n, ua_sheet(ui_st), out) if n.ups == null { if n.sheet != null { ir_sheet(ui_st, n, n.sheet, out) } return } let at = len(out) if n.sheet != null { ir_sheet(ui_st, n, n.sheet, out) } for i in 0 .. len(n.ups) { if n.ups[i].sheet != null and n.ups[i].sheet != n.sheet { ir_sheet(ui_st, n, n.ups[i].sheet, out) } } for i in at + 1 .. len(out) { # one order by specificity, stable, as cs_merged applies them let r = out[i] var j = i while j > at and out[j - 1].spec > r.spec { out[j] = out[j - 1] j -= 1 } out[j] = r } } @alloc_ok("an inspector's question, never a frame") function ir_sheet(ui_st: mut UiState, n: UiNode, sh: UiSheet, out: []UiRule) -> void { for i in 0 .. len(sh.rules) { let r = sh.rules[i] if md_ok(ui_st, r) and sel_match(ui_st, r.sel, n) { push(out, r) } } } # a declaration's value as written, when it is plain text (else "" - an expression, read per element) export function ui_rule_value(r: UiRule, k: int) -> string { let x = r.vals[k] if x.op == X_LIT { return vl_text(x.v) } return "" } # a class's template and styles read now (else at its first show), so a host hears their errors at once export function ui_class_load(ui_st: mut UiState, k: UiClass) -> void { uc_load(ui_st, k) } # a file read again the next time anything imports it (a host changed its text): every class too @alloc_ok("an inspector's edit, never a frame") export function ui_file_forget(ui_st: mut UiState, path: string) -> void { let keep = new []UiFile for i in 0 .. len(ui_st.lib_files) { if ui_st.lib_files[i].path != path { push(keep, ui_st.lib_files[i]) } } ui_st.lib_files = keep uc_invalidate(ui_st) } # every error forgotten, so each is said again the next time it is made (a host that reloads a class) export function ui_errors_clear(ui_st: mut UiState) -> void { List.clear(ui_st.ui_errs) }