@@ -7,7 +7,7 @@ module gui
77
88const ns_inspector = 'gui.inspector'
99const ns_inspector_width = 'gui.inspector.w'
10- const cap_inspector = 5
10+ const cap_inspector = 8
1111const inspector_id_focus = u32 (0xFFF00000 )
1212const inspector_id_scroll_panel = u32 (0xFFF00001 )
1313const inspector_tree_id = '__inspector_tree__'
@@ -24,6 +24,13 @@ const inspector_icon_style = TextStyle{
2424 color: Color{220 , 220 , 220 , 255 }
2525}
2626
27+ // InspectorStackFrame is a stack entry for iterative tree walk.
28+ struct InspectorStackFrame {
29+ nodes []TreeNodeCfg
30+ mut :
31+ pos int
32+ }
33+
2734// InspectorNodeProps snapshots shape properties as values
2835// so the properties panel can display them after layout_clear.
2936struct InspectorNodeProps {
@@ -182,8 +189,11 @@ fn inspector_select(path string, mut w Window) {
182189 // Expand selected node and all ancestors.
183190 tree_map[path] = true
184191 parts := path.split ('.' )
192+ mut prefix := parts[0 ]
193+ tree_map[prefix] = true
185194 for i in 1 .. parts.len {
186- tree_map[parts[..i].join ('.' )] = true
195+ prefix + = '.${parts [i ]}'
196+ tree_map[prefix] = true
187197 }
188198 w.view_state.tree_state.set (inspector_tree_id, tree_map)
189199 }
@@ -202,7 +212,7 @@ fn inspector_pick_path(layout &Layout, x f32, y f32) string {
202212}
203213
204214// inspector_pick_recurse depth-first reverse-child walk.
205- fn inspector_pick_recurse (layout Layout, path string , x f32 , y f32 ) string {
215+ fn inspector_pick_recurse (layout & Layout, path string , x f32 , y f32 ) string {
206216 if layout.shape == unsafe { nil } {
207217 return ''
208218 }
@@ -242,7 +252,7 @@ fn inspector_build_tree_nodes(layout &Layout, selected string, mut props map[str
242252// subtree into tree nodes, caching props for each node.
243253// When path matches selected, property leaf nodes are
244254// appended as children.
245- fn inspector_layout_to_tree (layout Layout, path string , selected string , mut props map [string ]InspectorNodeProps) []TreeNodeCfg {
255+ fn inspector_layout_to_tree (layout & Layout, path string , selected string , mut props map [string ]InspectorNodeProps) []TreeNodeCfg {
246256 label := inspector_node_label (layout.shape)
247257 p := inspector_snapshot_props (layout)
248258 props[path] = p
@@ -412,7 +422,7 @@ fn inspector_props_nodes(p InspectorNodeProps) []TreeNodeCfg {
412422
413423// inspector_snapshot_props captures shape properties as
414424// plain values for the properties panel.
415- fn inspector_snapshot_props (layout Layout) InspectorNodeProps {
425+ fn inspector_snapshot_props (layout & Layout) InspectorNodeProps {
416426 shape := layout.shape
417427 if shape == unsafe { nil } {
418428 return InspectorNodeProps{}
@@ -541,8 +551,8 @@ fn inspector_inject_wireframe(mut w Window) {
541551 w.renderers << Renderer (DrawStrokeRect{
542552 x: shape.x + shape.padding.left
543553 y: shape.y + shape.padding.top
544- w: shape.width - shape.padding.left - shape.padding.right
545- h: shape.height - shape.padding.top - shape.padding.bottom
554+ w: f32_max ( 0 , shape.width - shape.padding.left - shape.padding.right)
555+ h: f32_max ( 0 , shape.height - shape.padding.top - shape.padding.bottom)
546556 radius: 0
547557 color: rgba (0 , 200 , 0 , 150 ).to_gx_color ()
548558 thickness: 1
@@ -619,22 +629,33 @@ fn inspector_apply_scroll_to(panel_h f32, mut w Window) {
619629}
620630
621631// inspector_flat_row_index returns the flat row index of
622- // target in the tree, respecting expanded state. Returns -1
623- // if not found.
632+ // target in the visible tree. Returns -1 if not found.
633+ // Walks depth-first, counting visible rows until target
634+ // is found, avoiding array allocation.
624635fn inspector_flat_row_index (nodes []TreeNodeCfg, tree_map map [string ]bool , target string ) int {
625- mut ids := []string {cap: 64 }
626- inspector_collect_flat_ids (nodes, tree_map, mut ids)
627- return ids.index (target)
628- }
629-
630- // inspector_collect_flat_ids walks tree nodes depth-first,
631- // collecting visible node IDs in display order.
632- fn inspector_collect_flat_ids (nodes []TreeNodeCfg, tree_map map [string ]bool , mut ids []string ) {
633- for node in nodes {
636+ mut stack := []InspectorStackFrame{cap: 16 }
637+ stack << InspectorStackFrame{
638+ nodes: nodes
639+ }
640+ mut idx := 0
641+ for stack.len > 0 {
642+ si := stack.len - 1
643+ if stack[si].pos > = stack[si].nodes.len {
644+ stack.delete_last ()
645+ continue
646+ }
647+ node := stack[si].nodes[stack[si].pos]
648+ stack[si].pos++
634649 id := if node.id.len == 0 { node.text } else { node.id }
635- ids << id
650+ if id == target {
651+ return idx
652+ }
653+ idx++
636654 if tree_map[id] && node.nodes.len > 0 {
637- inspector_collect_flat_ids (node.nodes, tree_map, mut ids)
655+ stack << InspectorStackFrame{
656+ nodes: node.nodes
657+ }
638658 }
639659 }
660+ return - 1
640661}
0 commit comments