88 lines
4.9 KiB
Text
88 lines
4.9 KiB
Text
# attr.ludic - what a property sets, by its CSS name or the short one (width or w, background or
|
|
# bg, font-size or size, ...). An attribute on an element is the same property, applied last.
|
|
const AT_UNDRAWN: string = " font-weight font-family font-style box-shadow cursor transition animation letter-spacing text-decoration "
|
|
# a stylesheet's property: one that means nothing is said
|
|
function el_attr(ui_st: mut UiState, n: UiNode, key: string, v: Val) -> void {
|
|
if el_apply(ui_st, n, key, v) { return }
|
|
if lk_in(AT_UNDRAWN, at_alias(key)) { ui_err(ui_st, `{key}: this renderer does not draw it`) } else { ui_err(ui_st, `{key}: there is no such property`) }
|
|
}
|
|
# an element's attribute: a property when it names one, otherwise only there for [selectors]
|
|
function el_apply(ui_st: mut UiState, n: UiNode, key: string, v0: Val) -> bool {
|
|
let k = at_alias(key)
|
|
ui_st.el_cur = n
|
|
ui_st.el_key = k
|
|
if len(k) > 2 and sat(k, 0, "--") {
|
|
cs_var_set(n, k, vl_text_u(ui_st, v0))
|
|
return true
|
|
}
|
|
let v = cs_vars_in(ui_st, n, v0)
|
|
return el_size(ui_st, n, k, v) or el_box(ui_st, n, k, v) or el_flex(ui_st, n, k, v) or el_look(ui_st, n, k, v) or el_place_prop(ui_st, n, k, v) or el_edge(ui_st, n, k, v) or el_more(ui_st, n, k, v)
|
|
}
|
|
function at_alias(key: string) -> string {
|
|
# the CSS name to the short one; literals, so asking allocates nothing (asked per rule per element)
|
|
if key == "width" { return "w" }
|
|
if key == "height" { return "h" }
|
|
if key == "min-width" { return "min-w" }
|
|
if key == "max-width" { return "max-w" }
|
|
if key == "min-height" { return "min-h" }
|
|
if key == "max-height" { return "max-h" }
|
|
if key == "padding" { return "pad" }
|
|
if key == "background" { return "bg" }
|
|
if key == "background-color" { return "bg" }
|
|
if key == "font-size" { return "size" }
|
|
if key == "opacity" { return "alpha" }
|
|
if key == "flex-grow" { return "grow" }
|
|
if key == "flex-shrink" { return "shrink" }
|
|
if key == "flex-direction" { return "dir" }
|
|
if key == "flex-wrap" { return "wrap" }
|
|
if key == "justify-content" { return "justify" }
|
|
if key == "align-items" { return "align" }
|
|
if key == "align-self" { return "self" }
|
|
if key == "row-gap" { return "gap" }
|
|
if key == "column-gap" { return "gap" }
|
|
if key == "text-align" { return "talign" }
|
|
return key
|
|
}
|
|
function el_size(ui_st: mut UiState, n: UiNode, key: string, v: Val) -> bool {
|
|
if key == "w" or key == "h" { el_dim(ui_st, n, key == "w", v) } else if key == "min-w" { n.min_w = el_len(ui_st, v) } else if key == "max-w" { n.max_w = el_len(ui_st, v) } else if key == "min-h" { n.min_h = el_len(ui_st, v) } else if key == "max-h" { n.max_h = el_len(ui_st, v) } else if key == "gap" { n.gap = el_len(ui_st, v) } else { return false }
|
|
return true
|
|
}
|
|
function el_flex(ui_st: mut UiState, n: UiNode, key: string, v: Val) -> bool {
|
|
let s = vl_text_u(ui_st, v)
|
|
if key == "dir" {
|
|
n.dir = UI_COL
|
|
if s == "row" { n.dir = UI_ROW }
|
|
} else if key == "grow" { n.grow = el_num(s) } else if key == "flex" { el_flex_short(ui_st, n, s) } else if key == "wrap" { n.wrap = s == "wrap" or (vl_truthy(v) and s != "false" and s != "nowrap") } else if key == "align" { n.align = el_place(v) } else if key == "self" { n.self = el_place(v) } else if key == "justify" { n.justify = el_place(v) } else if key == "talign" { n.talign = el_place(v) } else if key == "display" { n.hidden = s == "none" } else { return false }
|
|
return true
|
|
}
|
|
function el_look(ui_st: mut UiState, n: UiNode, key: string, v: Val) -> bool {
|
|
let s = vl_text_u(ui_st, v)
|
|
if key == "size" { n.size = el_len(ui_st, v) } else if key == "color" {
|
|
n.fg = ui_color(ui_st, s)
|
|
n.fg_a = ui_st.cl_alpha
|
|
} else if key == "bg" {
|
|
if gr_is(tw(ui_st, s)) { nx(n).grad = gr_parse(ui_st, s) } else if len(s) > 4 and sat(s, 0, "url(") { n.bg_img = el_url_u(ui_st, s) } else if tw(ui_st, s) == "transparent" {
|
|
n.bg = 0
|
|
n.bg_a = 0.0
|
|
} else {
|
|
n.bg = ui_color(ui_st, s)
|
|
n.bg_a = ui_st.cl_alpha
|
|
}
|
|
} else if key == "alpha" { n.alpha = el_num(s) } else if key == "enabled" { n.enabled = vl_truthy(v) and s != "false" } else if key == "border-color" {
|
|
n.border_c = ui_color(ui_st, s)
|
|
n.border_a = ui_st.cl_alpha
|
|
} else if key == "border-width" { el_sides_border(n, el_len(ui_st, v)) } else if key == "border" { el_border(ui_st, n, s) } else if key == "border-top" or key == "border-right" or key == "border-bottom" or key == "border-left" { el_border_side(ui_st, n, key, s) } else { return false }
|
|
return true
|
|
}
|
|
# border: 1 #ffcc00, or 1px solid accent
|
|
function el_border(ui_st: mut UiState, n: UiNode, s: string) -> void {
|
|
let parts = mm_split(ui_st, s, 32)
|
|
for i in 0 .. len(parts) {
|
|
let p = parts[i]
|
|
if len(p) > 0 and ((p[0] >= 48 and p[0] <= 57) or p[0] == 46) { el_sides_border(n, el_unit(ui_st, p)) } else if p == "none" { el_sides_border(n, 0.0) } else if len(p) > 0 and p != "solid" {
|
|
n.border_c = ui_color(ui_st, p)
|
|
n.border_a = ui_st.cl_alpha
|
|
}
|
|
}
|
|
if n.border_c == UI_NONE { n.border_c = n.rfg }
|
|
}
|