102 lines
4.7 KiB
Text
102 lines
4.7 KiB
Text
# attr_edge.ludic - border-radius, outline (and its width, colour and offset), scrollbar-color
|
|
const EL_KEYS_EDGE: string = " animation background-image border-image border-radius box-shadow outline outline-color outline-offset outline-width scrollbar-color transition "
|
|
function el_edge(ui_st: mut UiState, n: UiNode, key: string, v: Val) -> bool {
|
|
if not lk_in(EL_KEYS_EDGE, key) { return false } # not one of its keys: no text made for it
|
|
let s = vl_text_u(ui_st, v)
|
|
if key == "border-radius" { n.radius = el_len(ui_st, v) } else if key == "outline" { el_outline(ui_st, n, s) } else if key == "outline-width" { n.outline_w = el_len(ui_st, v) } else if key == "outline-offset" { n.outline_off = el_len(ui_st, v) } else if key == "outline-color" {
|
|
n.outline_c = ui_color(ui_st, s)
|
|
n.outline_a = ui_st.cl_alpha
|
|
} else if key == "scrollbar-color" {
|
|
let parts = mm_split(ui_st, s, 32)
|
|
if len(parts) > 0 { n.bar_c = ui_color(ui_st, parts[0]) }
|
|
if len(parts) > 1 { n.bar_track = ui_color(ui_st, parts[1]) }
|
|
} else if key == "background-image" and gr_is(tw(ui_st, s)) { nx(n).grad = gr_parse(ui_st, s) } else if key == "background-image" { n.bg_img = el_url_u(ui_st, s) } else if key == "border-image" { el_border_image(ui_st, n, s) } else if key == "box-shadow" { el_shadow(ui_st, n, s) } else if key == "animation" { el_animation(ui_st, n, s) } else if key == "transition" { n.tr_dur = el_secs(ui_st, s) } else { return false }
|
|
return true
|
|
}
|
|
# url(path) or url("path") -> path
|
|
@alloc_ok("a memo miss (el_url_u): once per text")
|
|
function el_url(s: string) -> string {
|
|
var t = tpl_words(s)
|
|
if len(t) > 5 and sat(t, 0, "url(") { t = tpl_words(t[4..len(t) - 1]) }
|
|
if len(t) >= 2 and (t[0] == 34 or t[0] == 39) { t = t[1..len(t) - 1] }
|
|
if t == "none" { return "" }
|
|
return t
|
|
}
|
|
# border-image: url(chip.png) 14 / 12px - the source's corner size, then how wide they are drawn
|
|
function el_border_image(ui_st: mut UiState, n: UiNode, s: string) -> void {
|
|
let m = mm_of(ui_st)
|
|
var at = mm_find(m, MM_BIMG, s)
|
|
if at < 0 { at = el_bimg_read(m, s) }
|
|
if at < 0 { return }
|
|
n.bi_src = m.texts[at]
|
|
let rest = m.lists[at]
|
|
n.bi_slice = el_num(tw(ui_st, rest[0]))
|
|
n.bi_width = el_px(ui_st, n.bi_slice)
|
|
if len(rest) > 1 { n.bi_width = el_unit(ui_st, tw(ui_st, rest[1])) }
|
|
}
|
|
# box-shadow: 6px 10px 0 rgba(0, 0, 0, 0.45) - x, y, a blur this renderer draws sharp, the colour
|
|
function el_shadow(ui_st: mut UiState, n: UiNode, s: string) -> void {
|
|
if tw(ui_st, s) == "none" {
|
|
n.sh_c = -2
|
|
return
|
|
}
|
|
let parts = mm_split(ui_st, s, 32)
|
|
var nums = 0
|
|
var col = ""
|
|
for i in 0 .. len(parts) {
|
|
let p = parts[i]
|
|
if len(p) == 0 { continue }
|
|
if col == "" and ((p[0] >= 48 and p[0] <= 57) or p[0] == 45 or p[0] == 46) {
|
|
if nums == 0 { n.sh_x = el_unit(ui_st, p) }
|
|
if nums == 1 { n.sh_y = el_unit(ui_st, p) }
|
|
nums += 1
|
|
} else if col == "" { col = p } else { col = mm_join(ui_st, col, " ", p) }
|
|
}
|
|
if col == "" { col = "rgba(0,0,0,0.5)" }
|
|
n.sh_c = ui_color(ui_st, col)
|
|
n.sh_a = ui_st.cl_alpha
|
|
}
|
|
# outline: 2px solid #ffcc00, or none
|
|
function el_outline(ui_st: mut UiState, n: UiNode, s: string) -> void {
|
|
let parts = mm_split(ui_st, s, 32)
|
|
n.outline_w = 0.0
|
|
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) { n.outline_w = el_unit(ui_st, p) } else if len(p) > 0 and p != "solid" and p != "none" {
|
|
n.outline_c = ui_color(ui_st, p)
|
|
n.outline_a = ui_st.cl_alpha
|
|
}
|
|
}
|
|
}
|
|
# animation: fade 0.25s infinite alternate
|
|
function el_animation(ui_st: mut UiState, n: UiNode, s: string) -> void {
|
|
let parts = mm_split(ui_st, s, 32)
|
|
n.anim = ""
|
|
for i in 0 .. len(parts) {
|
|
let p = parts[i]
|
|
if p == "infinite" { n.anim_loop = true } else if p == "alternate" { n.anim_alt = true } else if len(p) > 0 and ((p[0] >= 48 and p[0] <= 57) or p[0] == 46) { n.anim_dur = el_secs(ui_st, p) } else if len(p) > 0 and n.anim == "" and p != "none" { n.anim = p }
|
|
}
|
|
}
|
|
# the first time in `0.25s` or `250ms`
|
|
function el_secs(ui_st: mut UiState, s: string) -> float {
|
|
let parts = mm_split(ui_st, s, 32)
|
|
for i in 0 .. len(parts) {
|
|
let p = parts[i]
|
|
if len(p) > 1 and p[0] >= 48 and p[0] <= 57 or len(p) > 1 and p[0] == 46 {
|
|
if len(p) > 2 and sat(p, len(p) - 2, "ms") { return el_num(p) / 1000.0 }
|
|
return el_num(p)
|
|
}
|
|
}
|
|
return 0.0
|
|
}
|
|
|
|
@alloc_ok("a memo miss: once per border-image value, bounded by MM_CAP")
|
|
function el_bimg_read(m: UiMemo, s: string) -> int {
|
|
var close = 0
|
|
while close < len(s) and s[close] != 41 { close += 1 }
|
|
let at = mm_add(m, MM_BIMG, s)
|
|
if at < 0 { return -1 }
|
|
m.texts[at] = el_url(s[0..Math.min(close + 1, len(s))])
|
|
m.lists[at] = lss_split(s[Math.min(close + 1, len(s))..len(s)], 47)
|
|
return at
|
|
}
|