Skip to content

Commit 0f277d6

Browse files
committed
float panels into config layer
1 parent 7844761 commit 0f277d6

File tree

7 files changed

+525
-501
lines changed

7 files changed

+525
-501
lines changed

src/config/config_inc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license (https://opensource.org/license/mit/)
33

44
#include "config_core.c"
5+
#include "config_panels.c"
56
#if defined(OS_GFX_H)
67
# include "config_bindings.c"
78
#endif

src/config/config_inc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define CONFIG_INC_H
66

77
#include "config_core.h"
8+
#include "config_panels.h"
89
#if defined(OS_GFX_H)
910
# include "config_bindings.h"
1011
#endif

src/config/config_panels.c

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
// Copyright (c) Epic Games Tools
2+
// Licensed under the MIT license (https://opensource.org/license/mit/)
3+
4+
internal CFG_Node *
5+
cfg_window_from_cfg(CFG_Node *cfg)
6+
{
7+
CFG_Node *result = &cfg_nil_node;
8+
for(CFG_Node *c = cfg; c != &cfg_nil_node; c = c->parent)
9+
{
10+
if(c->parent->parent == cfg_node_root() && str8_match(c->string, str8_lit("window"), 0))
11+
{
12+
result = c;
13+
break;
14+
}
15+
}
16+
return result;
17+
}
18+
19+
internal CFG_PanelTree
20+
cfg_panel_tree_from_cfg(Arena *arena, CFG_Node *cfg_root)
21+
{
22+
Temp scratch = scratch_begin(&arena, 1);
23+
CFG_Node *wcfg = cfg_window_from_cfg(cfg_root);
24+
CFG_Node *src_root = cfg_node_child_from_string(wcfg, str8_lit("panels"));
25+
CFG_PanelNode *dst_root = &cfg_nil_panel_node;
26+
CFG_PanelNode *dst_focused = &cfg_nil_panel_node;
27+
{
28+
Axis2 active_split_axis = cfg_node_child_from_string(wcfg, str8_lit("split_x")) != &cfg_nil_node ? Axis2_X : Axis2_Y;
29+
CFG_NodeRec rec = {0};
30+
CFG_PanelNode *dst_active_parent = &cfg_nil_panel_node;
31+
for(CFG_Node *src = src_root; src != &cfg_nil_node; src = rec.next)
32+
{
33+
// rjf: build a panel node
34+
CFG_PanelNode *dst = push_array(arena, CFG_PanelNode, 1);
35+
MemoryCopyStruct(dst, &cfg_nil_panel_node);
36+
dst->parent = dst_active_parent;
37+
if(dst_active_parent != &cfg_nil_panel_node)
38+
{
39+
DLLPushBack_NPZ(&cfg_nil_panel_node, dst_active_parent->first, dst_active_parent->last, dst, next, prev);
40+
dst_active_parent->child_count += 1;
41+
}
42+
if(dst_root == &cfg_nil_panel_node)
43+
{
44+
dst_root = dst;
45+
}
46+
47+
// rjf: extract cfg info
48+
B32 panel_has_children = 0;
49+
dst->cfg = src;
50+
dst->pct_of_parent = (src == src_root ? 1.f : (F32)f64_from_str8(src->string));
51+
dst->tab_side = (cfg_node_child_from_string(src, str8_lit("tabs_on_bottom")) != &cfg_nil_node ? Side_Max : Side_Min);
52+
dst->split_axis = active_split_axis;
53+
for(CFG_Node *src_child = src->first; src_child != &cfg_nil_node; src_child = src_child->next)
54+
{
55+
MD_TokenizeResult tokenize = md_tokenize_from_text(scratch.arena, src_child->string);
56+
if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Numeric)
57+
{
58+
panel_has_children = 1;
59+
}
60+
else if(str8_match(src_child->string, str8_lit("tabs_on_bottom"), 0))
61+
{
62+
// NOTE(rjf): skip - this is a panel option.
63+
}
64+
else if(str8_match(src_child->string, str8_lit("selected"), 0))
65+
{
66+
dst_focused = dst;
67+
}
68+
else if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Identifier)
69+
{
70+
cfg_node_ptr_list_push(arena, &dst->tabs, src_child);
71+
if(cfg_node_child_from_string(src_child, str8_lit("selected")) != &cfg_nil_node)
72+
{
73+
dst->selected_tab = src_child;
74+
}
75+
}
76+
}
77+
78+
// rjf: recurse
79+
rec = cfg_node_rec__depth_first(src_root, src);
80+
if(!panel_has_children)
81+
{
82+
MemoryZeroStruct(&rec);
83+
rec.next = &cfg_nil_node;
84+
for(CFG_Node *p = src; p != src_root && p != &cfg_nil_node; p = p->parent, rec.pop_count += 1)
85+
{
86+
if(p->next != &cfg_nil_node)
87+
{
88+
rec.next = p->next;
89+
break;
90+
}
91+
}
92+
}
93+
if(rec.push_count > 0)
94+
{
95+
dst_active_parent = dst;
96+
active_split_axis = axis2_flip(active_split_axis);
97+
}
98+
else for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1)
99+
{
100+
dst_active_parent = dst_active_parent->parent;
101+
active_split_axis = axis2_flip(active_split_axis);
102+
}
103+
}
104+
}
105+
scratch_end(scratch);
106+
CFG_PanelTree tree = {dst_root, dst_focused};
107+
return tree;
108+
}
109+
110+
internal CFG_PanelNodeRec
111+
cfg_panel_node_rec__depth_first(CFG_PanelNode *root, CFG_PanelNode *panel, U64 sib_off, U64 child_off)
112+
{
113+
CFG_PanelNodeRec rec = {&cfg_nil_panel_node};
114+
if(*MemberFromOffset(CFG_PanelNode **, panel, child_off) != &cfg_nil_panel_node)
115+
{
116+
rec.next = *MemberFromOffset(CFG_PanelNode **, panel, child_off);
117+
rec.push_count += 1;
118+
}
119+
else for(CFG_PanelNode *p = panel; p != &cfg_nil_panel_node && p != root; p = p->parent, rec.pop_count += 1)
120+
{
121+
if(*MemberFromOffset(CFG_PanelNode **, p, sib_off) != &cfg_nil_panel_node)
122+
{
123+
rec.next = *MemberFromOffset(CFG_PanelNode **, p, sib_off);
124+
break;
125+
}
126+
}
127+
return rec;
128+
}
129+
130+
internal CFG_PanelNode *
131+
cfg_panel_node_from_tree_cfg(CFG_PanelNode *root, CFG_Node *cfg)
132+
{
133+
CFG_PanelNode *result = &cfg_nil_panel_node;
134+
for(CFG_PanelNode *p = root;
135+
p != &cfg_nil_panel_node;
136+
p = cfg_panel_node_rec__depth_first_pre(root, p).next)
137+
{
138+
if(p->cfg == cfg)
139+
{
140+
result = p;
141+
break;
142+
}
143+
}
144+
return result;
145+
}
146+
147+
internal Rng2F32
148+
cfg_target_rect_from_panel_node_child(Rng2F32 parent_rect, CFG_PanelNode *parent, CFG_PanelNode *panel)
149+
{
150+
Rng2F32 rect = parent_rect;
151+
if(parent != &cfg_nil_panel_node)
152+
{
153+
Vec2F32 parent_rect_size = dim_2f32(parent_rect);
154+
Axis2 axis = parent->split_axis;
155+
rect.p1.v[axis] = rect.p0.v[axis];
156+
for(CFG_PanelNode *child = parent->first; child != &cfg_nil_panel_node; child = child->next)
157+
{
158+
rect.p1.v[axis] += parent_rect_size.v[axis] * child->pct_of_parent;
159+
if(child == panel)
160+
{
161+
break;
162+
}
163+
rect.p0.v[axis] = rect.p1.v[axis];
164+
}
165+
//rect.p0.v[axis] += parent_rect_size.v[axis] * panel->off_pct_of_parent.v[axis];
166+
//rect.p0.v[axis2_flip(axis)] += parent_rect_size.v[axis2_flip(axis)] * panel->off_pct_of_parent.v[axis2_flip(axis)];
167+
}
168+
rect.x0 = round_f32(rect.x0);
169+
rect.x1 = round_f32(rect.x1);
170+
rect.y0 = round_f32(rect.y0);
171+
rect.y1 = round_f32(rect.y1);
172+
return rect;
173+
}
174+
175+
internal Rng2F32
176+
cfg_target_rect_from_panel_node(Rng2F32 root_rect, CFG_PanelNode *root, CFG_PanelNode *panel)
177+
{
178+
Temp scratch = scratch_begin(0, 0);
179+
180+
// rjf: count ancestors
181+
U64 ancestor_count = 0;
182+
for(CFG_PanelNode *p = panel->parent; p != &cfg_nil_panel_node; p = p->parent)
183+
{
184+
ancestor_count += 1;
185+
}
186+
187+
// rjf: gather ancestors
188+
CFG_PanelNode **ancestors = push_array(scratch.arena, CFG_PanelNode *, ancestor_count);
189+
{
190+
U64 ancestor_idx = 0;
191+
for(CFG_PanelNode *p = panel->parent; p != &cfg_nil_panel_node; p = p->parent)
192+
{
193+
ancestors[ancestor_idx] = p;
194+
ancestor_idx += 1;
195+
}
196+
}
197+
198+
// rjf: go from highest ancestor => panel and calculate rect
199+
Rng2F32 parent_rect = root_rect;
200+
for(S64 ancestor_idx = (S64)ancestor_count-1;
201+
0 <= ancestor_idx && ancestor_idx < ancestor_count;
202+
ancestor_idx -= 1)
203+
{
204+
CFG_PanelNode *ancestor = ancestors[ancestor_idx];
205+
CFG_PanelNode *parent = ancestor->parent;
206+
if(parent != &cfg_nil_panel_node)
207+
{
208+
parent_rect = cfg_target_rect_from_panel_node_child(parent_rect, parent, ancestor);
209+
}
210+
}
211+
212+
// rjf: calculate final rect
213+
Rng2F32 rect = cfg_target_rect_from_panel_node_child(parent_rect, panel->parent, panel);
214+
215+
scratch_end(scratch);
216+
return rect;
217+
}

src/config/config_panels.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) Epic Games Tools
2+
// Licensed under the MIT license (https://opensource.org/license/mit/)
3+
4+
#ifndef CONFIG_PANELS_H
5+
#define CONFIG_PANELS_H
6+
7+
typedef struct CFG_PanelNode CFG_PanelNode;
8+
struct CFG_PanelNode
9+
{
10+
// rjf: links data
11+
CFG_PanelNode *first;
12+
CFG_PanelNode *last;
13+
CFG_PanelNode *next;
14+
CFG_PanelNode *prev;
15+
CFG_PanelNode *parent;
16+
U64 child_count;
17+
CFG_Node *cfg;
18+
19+
// rjf: split data
20+
Axis2 split_axis;
21+
F32 pct_of_parent;
22+
23+
// rjf: tab params
24+
Side tab_side;
25+
26+
// rjf: which tabs are attached
27+
CFG_NodePtrList tabs;
28+
CFG_Node *selected_tab;
29+
};
30+
31+
typedef struct CFG_PanelTree CFG_PanelTree;
32+
struct CFG_PanelTree
33+
{
34+
CFG_PanelNode *root;
35+
CFG_PanelNode *focused;
36+
};
37+
38+
typedef struct CFG_PanelNodeRec CFG_PanelNodeRec;
39+
struct CFG_PanelNodeRec
40+
{
41+
CFG_PanelNode *next;
42+
S32 push_count;
43+
S32 pop_count;
44+
};
45+
46+
read_only global CFG_PanelNode cfg_nil_panel_node =
47+
{
48+
&cfg_nil_panel_node,
49+
&cfg_nil_panel_node,
50+
&cfg_nil_panel_node,
51+
&cfg_nil_panel_node,
52+
&cfg_nil_panel_node,
53+
0,
54+
&cfg_nil_node,
55+
.selected_tab = &cfg_nil_node,
56+
};
57+
58+
internal CFG_Node *cfg_window_from_cfg(CFG_Node *cfg);
59+
internal CFG_PanelTree cfg_panel_tree_from_cfg(Arena *arena, CFG_Node *cfg_root);
60+
internal CFG_PanelNodeRec cfg_panel_node_rec__depth_first(CFG_PanelNode *root, CFG_PanelNode *panel, U64 sib_off, U64 child_off);
61+
#define cfg_panel_node_rec__depth_first_pre(root, p) cfg_panel_node_rec__depth_first((root), (p), OffsetOf(CFG_PanelNode, next), OffsetOf(CFG_PanelNode, first))
62+
#define cfg_panel_node_rec__depth_first_pre_rev(root, p) cfg_panel_node_rec__depth_first((root), (p), OffsetOf(CFG_PanelNode, prev), OffsetOf(CFG_PanelNode, last))
63+
internal CFG_PanelNode *cfg_panel_node_from_tree_cfg(CFG_PanelNode *root, CFG_Node *cfg);
64+
internal Rng2F32 cfg_target_rect_from_panel_node_child(Rng2F32 parent_rect, CFG_PanelNode *parent, CFG_PanelNode *panel);
65+
internal Rng2F32 cfg_target_rect_from_panel_node(Rng2F32 root_rect, CFG_PanelNode *root, CFG_PanelNode *panel);
66+
67+
#endif // CONFIG_PANELS_H

0 commit comments

Comments
 (0)