;; walks the tree in pre-order
(bind-func gui_render_subtree
(lambda (widget:Widget* bounds:Rect*)
(if (null? widget)
widget
(if (and (null? (Widget_left_child widget))
(null? (Widget_right_child widget)))
;; if a leaf node, set the nanovg transform matrix and
;; call the render callback
(let ((winWidth (GUI_width EXTEMPORE_GUI))
(winHeight (GUI_height EXTEMPORE_GUI))
(vg (GUI_context EXTEMPORE_GUI))
(cb (Widget_cb widget)))
;; (nvgResetTransform vg)
;; (nvgTranslate vg x y)
;; (nvgScale vg w h)
(cb widget bounds)
null)
;; otherwise recurse into the child widgets
(let ((split (Widget_split widget)))
;; recurse into children
(if (Widget_split_vertical_p widget)
;; split vertically
(begin
(let ((sub_bounds:Rect* (zalloc)))
(tfill! sub_bounds
(tref bounds 0)
(tref bounds 1)
(tref bounds 2)
(floor (* split (tref bounds 3))))
(gui_render_subtree (Widget_left_child widget)
sub_bounds))
(let ((sub_bounds:Rect* (zalloc)))
(tfill! sub_bounds
(tref bounds 0)
(floor (+ (tref bounds 1)
(* split (tref bounds 3))))
(tref bounds 2)
(ceil (* (- 1. split) (tref bounds 3))))
(gui_render_subtree (Widget_right_child widget)
sub_bounds)))
;; split horizontally
(begin
(let ((sub_bounds:Rect* (zalloc)))
(tfill! sub_bounds
(tref bounds 0)
(tref bounds 1)
(floor (* split (tref bounds 2)))
(tref bounds 3))
(gui_render_subtree (Widget_left_child widget)
sub_bounds))
(let ((sub_bounds:Rect* (zalloc)))
(tfill! sub_bounds
(floor (+ (tref bounds 0)
(* split (tref bounds 2))))
(tref bounds 1)
(ceil (* (- 1. split) (tref bounds 2)))
(tref bounds 3))
(gui_render_subtree (Widget_right_child widget)
sub_bounds)))))))))