export let graph_node_ports = (row, side) => {
let single_key = side == "left" ? "left_port" : "right_port"
let multi_key = side == "left" ? "left_ports" : "right_ports"
let single = attr_or(row, single_key, "")
let multi = attr_or(row, multi_key, "")
multi != "" ? split(",", multi) : (single != "" ? [single] : [])
}
export let graph_node_port_shapes = (ports, side, w, row_y, row_h, port_r, port_fill, unused_port_fill, port_stroke, port_stroke_width, connected_ports) => {
let n = len(ports)
map(range(0, n), (i) => {
kind = "circle",
id = trim(ports[i]),
x = side == "left" ? -port_r : w - port_r,
y = row_y + ((i + 1) * row_h / (n + 1)) - port_r,
width = port_r * 2,
height = port_r * 2,
fill = contains(connected_ports, trim(ports[i])) ? port_fill : unused_port_fill,
stroke = port_stroke,
stroke_width = port_stroke_width
})
}
export let graph_node_is_item = (item) => {
let is_item = item.kind == "wdoc::draw::graph_row" || item.kind == "wdoc::draw::graph_divider"
is_item
}
export let graph_node_item_height = (item, row_h) => {
let h = item.kind == "wdoc::draw::graph_divider" ? attr_or(item, "height", 12) : row_h
h
}
export let graph_node_item_y = (items, i, header_h, row_h) => {
let y = header_h + sum(map(range(0, i), (j) => wdoc::graph_node_item_height(items[j], row_h)))
y
}
export let graph_node_divider_shapes = (divider, y, w, separator_stroke) => {
let h = attr_or(divider, "height", 12)
let inset = attr_or(divider, "inset", 0)
let stroke = attr_or(divider, "stroke", separator_stroke)
let stroke_width = attr_or(divider, "stroke_width", 2)
let opacity = attr_or(divider, "opacity", 0.9)
[
{ kind = "line", x1 = inset, y1 = y + h / 2, x2 = w - inset, y2 = y + h / 2,
stroke = stroke, stroke_width = stroke_width, opacity = opacity }
]
}
export let graph_node_row_shapes = (row, row_y, w, row_h, show_separator, label_fill, muted_fill, separator_stroke, port_r, port_fill, unused_port_fill, port_stroke, port_stroke_width, connected_ports) => {
let label = attr_or(row, "label", row.id)
let detail = attr_or(row, "detail", "")
let left_ports = wdoc::graph_node_ports(row, "left")
let right_ports = wdoc::graph_node_ports(row, "right")
let label_w = w - 34
let separator_part = show_separator ? [
{ kind = "line", x1 = 0, y1 = row_y, x2 = w, y2 = row_y,
stroke = separator_stroke, stroke_width = 1, opacity = 0.72 }
] : []
let detail_part = detail != "" ? [
{ kind = "text", x = 14, y = row_y + row_h - 14, width = label_w, height = 10,
content = detail, font_size = 9, anchor = "start", fill = muted_fill, opacity = 0.78 }
] : []
concat(concat(concat(concat(concat(separator_part, [
{ kind = "text", x = 14, y = row_y + (detail != "" ? 4 : 0), width = label_w,
height = detail != "" ? row_h - 10 : row_h, content = label, font_size = 11,
anchor = "start", fill = label_fill }
]), detail_part), wdoc::graph_node_port_shapes(left_ports, "left", w, row_y, row_h, port_r, port_fill, unused_port_fill, port_stroke, port_stroke_width, connected_ports)), wdoc::graph_node_port_shapes(right_ports, "right", w, row_y, row_h, port_r, port_fill, unused_port_fill, port_stroke, port_stroke_width, connected_ports)), [])
}
export let graph_node_item_shapes = (items, i, w, header_h, row_h, label_fill, muted_fill, separator_stroke, port_r, port_fill, unused_port_fill, port_stroke, port_stroke_width, connected_ports) => {
let item = items[i]
let y = wdoc::graph_node_item_y(items, i, header_h, row_h)
let follows_divider = i > 0 && items[i - 1].kind == "wdoc::draw::graph_divider"
let shapes = item.kind == "wdoc::draw::graph_divider" ? wdoc::graph_node_divider_shapes(item, y, w, separator_stroke) : wdoc::graph_node_row_shapes(item, y, w, row_h, !follows_divider, label_fill, muted_fill, separator_stroke, port_r, port_fill, unused_port_fill, port_stroke, port_stroke_width, connected_ports)
shapes
}
export let widget_graph_node = (b) => {
let items = filter(children(b), (item) => wdoc::graph_node_is_item(item))
let item_count = len(items)
let w = attr_or(b, "width", 240)
let header_h = attr_or(b, "header_height", 34)
let row_h = attr_or(b, "row_height", 28)
let h = attr_or(b, "height", header_h + sum(map(items, (item) => wdoc::graph_node_item_height(item, row_h))))
let title = attr_or(b, "title", attr_or(b, "label", b.id))
let subtitle = attr_or(b, "subtitle", "")
let surface_fill = attr_or(b, "surface_fill", "var(--color-bg)")
let header_fill = attr_or(b, "header_fill", "var(--color-nav-bg)")
let border_stroke = attr_or(b, "border_stroke", "var(--color-nav-border)")
let label_fill = attr_or(b, "label_fill", "currentColor")
let header_label_fill = attr_or(b, "header_label_fill", label_fill)
let muted_fill = attr_or(b, "muted_fill", "currentColor")
let separator_stroke = attr_or(b, "separator_stroke", border_stroke)
let port_fill = attr_or(b, "port_fill", "var(--color-link)")
let unused_port_fill = attr_or(b, "unused_port_fill", "none")
let port_stroke = attr_or(b, "port_stroke", surface_fill)
let connected_ports_attr = attr_or(b, "_wdoc_connected_ports", "")
let connected_ports = connected_ports_attr != "" ? split(",", connected_ports_attr) : []
let radius = attr_or(b, "radius", 8)
let border_width = attr_or(b, "border_width", 1.5)
let port_r = attr_or(b, "port_radius", 5)
let port_stroke_width = attr_or(b, "port_stroke_width", 1.5)
let subtitle_part = subtitle != "" ? [
{ kind = "text", x = 14, y = 18, width = w - 28, height = 12,
content = subtitle, font_size = 9, anchor = "start", fill = header_label_fill, opacity = 0.75 }
] : []
let item_shapes = map(range(0, item_count), (i) => wdoc::graph_node_item_shapes(items, i, w, header_h, row_h, label_fill, muted_fill, separator_stroke, port_r, port_fill, unused_port_fill, port_stroke, port_stroke_width, connected_ports))
concat(concat(concat([
{ kind = "rect", id = "surface", x = 0, y = 0, width = w, height = h, rx = radius,
fill = surface_fill, stroke = border_stroke, stroke_width = border_width,
_wdoc_full_container = "true" },
{ kind = "rect", x = 0, y = 0, width = w, height = header_h, rx = radius,
fill = header_fill },
{ kind = "rect", x = 0, y = header_h - radius, width = w, height = radius,
fill = header_fill },
{ kind = "text", x = 14, y = subtitle != "" ? 5 : 0, width = w - 28,
height = subtitle != "" ? 16 : header_h, content = title, font_size = 13,
font_weight = "600", anchor = "start", fill = header_label_fill }
], subtitle_part), flatten(item_shapes)), [
{ kind = "rect", x = 0, y = 0, width = w, height = h, rx = radius,
fill = "none", stroke = border_stroke, stroke_width = border_width,
_wdoc_full_container = "true" }
])
}