use a tuple in get_elem
This commit is contained in:
parent
32a57d5293
commit
8cecb57d93
@ -7,6 +7,7 @@ import fifo;
|
|||||||
import std::io;
|
import std::io;
|
||||||
import std::core::string;
|
import std::core::string;
|
||||||
import std::core::mem::allocator;
|
import std::core::mem::allocator;
|
||||||
|
import std::collections::pair;
|
||||||
|
|
||||||
|
|
||||||
macro println(...)
|
macro println(...)
|
||||||
@ -68,6 +69,9 @@ struct Elem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tuple of Element pointers, used when it is useful to get both parent and child
|
||||||
|
alias PElemTuple = pair::Pair{Elem*, Elem*};
|
||||||
|
|
||||||
|
|
||||||
// relationships between elements are stored in a tree, it stores just the ids
|
// relationships between elements are stored in a tree, it stores just the ids
|
||||||
alias IdTree = mtree::MTree{Id};
|
alias IdTree = mtree::MTree{Id};
|
||||||
@ -130,10 +134,8 @@ struct Ctx {
|
|||||||
// return a pointer to the parent of the current active div
|
// return a pointer to the parent of the current active div
|
||||||
fn Elem*? Ctx.get_parent(&ctx)
|
fn Elem*? Ctx.get_parent(&ctx)
|
||||||
{
|
{
|
||||||
Id parent_id = ctx.tree.get(ctx.active_div);
|
Id parent_id = ctx.tree[ctx.active_div]!;
|
||||||
Elem*? parent = ctx.cache.search(parent_id);
|
Elem* parent = ctx.cache.search(parent_id)!;
|
||||||
if (catch parent) return parent;
|
|
||||||
if (parent.type != ETYPE_DIV) return WRONG_ELEMENT_TYPE?;
|
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +148,7 @@ const uint GOLDEN_RATIO = 0x9E3779B9;
|
|||||||
fn Id? Ctx.gen_id(&ctx, Id id2)
|
fn Id? Ctx.gen_id(&ctx, Id id2)
|
||||||
{
|
{
|
||||||
// FIXME: this is SHIT
|
// FIXME: this is SHIT
|
||||||
Id id1 = ctx.tree.get(ctx.active_div);
|
Id id1 = ctx.tree.get(ctx.active_div)!;
|
||||||
// Mix the two IDs non-linearly
|
// Mix the two IDs non-linearly
|
||||||
Id mixed = id1 ^ id2.rotate_left(13);
|
Id mixed = id1 ^ id2.rotate_left(13);
|
||||||
mixed ^= id1.rotate_left(7);
|
mixed ^= id1.rotate_left(7);
|
||||||
@ -166,10 +168,13 @@ macro Id @compute_id(...)
|
|||||||
|
|
||||||
// get or push an element from the cache, return a pointer to it
|
// get or push an element from the cache, return a pointer to it
|
||||||
// resets all flags except is_new which is set accordingly
|
// resets all flags except is_new which is set accordingly
|
||||||
fn Elem*? Ctx.get_elem(&ctx, Id id, ElemType type)
|
fn PElemTuple? Ctx.get_elem(&ctx, Id id, ElemType type)
|
||||||
{
|
{
|
||||||
bool is_new;
|
bool is_new;
|
||||||
|
Elem* parent;
|
||||||
Elem* elem;
|
Elem* elem;
|
||||||
|
parent = ctx.get_parent() ?? &&(Elem){};
|
||||||
|
|
||||||
elem = ctx.cache.get_or_insert(&&(Elem){}, id, &is_new)!;
|
elem = ctx.cache.get_or_insert(&&(Elem){}, id, &is_new)!;
|
||||||
elem.flags = (ElemFlags)0;
|
elem.flags = (ElemFlags)0;
|
||||||
elem.flags.is_new = is_new;
|
elem.flags.is_new = is_new;
|
||||||
@ -180,13 +185,9 @@ fn Elem*? Ctx.get_elem(&ctx, Id id, ElemType type)
|
|||||||
} else {
|
} else {
|
||||||
elem.type = type;
|
elem.type = type;
|
||||||
}
|
}
|
||||||
// FIXME: this is crap
|
elem.z_index = parent.z_index;
|
||||||
if (ctx.tree.is_used(ctx.active_div)) {
|
|
||||||
elem.z_index = ctx.get_active_div()!.z_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
elem.tree_idx = ctx.tree.add(ctx.active_div, id);
|
elem.tree_idx = ctx.tree.add(ctx.active_div, id);
|
||||||
return elem;
|
return {elem, parent};
|
||||||
}
|
}
|
||||||
|
|
||||||
// find an element, does not allocate a new one in cache
|
// find an element, does not allocate a new one in cache
|
||||||
@ -203,7 +204,7 @@ macro Elem* Ctx.find_elem(&ctx, Id id)
|
|||||||
|
|
||||||
fn Elem*? Ctx.get_active_div(&ctx)
|
fn Elem*? Ctx.get_active_div(&ctx)
|
||||||
{
|
{
|
||||||
Id id = ctx.tree.get(ctx.active_div);
|
Id id = ctx.tree.get(ctx.active_div)!;
|
||||||
return ctx.cache.search(id);
|
return ctx.cache.search(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +241,7 @@ fn void? Ctx.frame_begin(&ctx)
|
|||||||
// 1. Reset the active div
|
// 1. Reset the active div
|
||||||
// 2. Get the root element from the cache and update it
|
// 2. Get the root element from the cache and update it
|
||||||
ctx.active_div = 0;
|
ctx.active_div = 0;
|
||||||
Elem* elem = ctx.get_elem(ROOT_ID, ETYPE_DIV)!;
|
Elem* elem = ctx.get_elem(ROOT_ID, ETYPE_DIV)!.first;
|
||||||
ctx.active_div = elem.tree_idx;
|
ctx.active_div = elem.tree_idx;
|
||||||
// The root should have the updated flag only if the size of the window
|
// The root should have the updated flag only if the size of the window
|
||||||
// was changed between frasmes, this propagates an element size recalculation
|
// was changed between frasmes, this propagates an element size recalculation
|
||||||
@ -279,7 +280,7 @@ fn void? Ctx.frame_end(&ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DO THE LAYOUT
|
// DO THE LAYOUT
|
||||||
ctx.layout_element_tree();
|
ctx.layout_element_tree()!;
|
||||||
|
|
||||||
// 1. clear the tree
|
// 1. clear the tree
|
||||||
ctx.tree.nuke();
|
ctx.tree.nuke();
|
||||||
|
@ -297,17 +297,17 @@ fn void resolve_placement(Elem* c, Elem* p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void Ctx.layout_element_tree(&ctx)
|
fn void? Ctx.layout_element_tree(&ctx)
|
||||||
{
|
{
|
||||||
int current;
|
int current;
|
||||||
for (int n; (current = ctx.tree.level_order_it(0, n)) >= 0; n++) {
|
for (int n; (current = ctx.tree.level_order_it(0, n)) >= 0; n++) {
|
||||||
Elem* p = ctx.find_elem(ctx.tree.get(current));
|
Elem* p = ctx.find_elem(ctx.tree.get(current))!;
|
||||||
p.layout.origin = -p.layout.scroll_offset;
|
p.layout.origin = -p.layout.scroll_offset;
|
||||||
|
|
||||||
int ch;
|
int ch;
|
||||||
// RESOLVE KNOWN DIMENSIONS
|
// RESOLVE KNOWN DIMENSIONS
|
||||||
for (int i; (ch = ctx.tree.children_it(current, i)) >= 0; i++) {
|
for (int i; (ch = ctx.tree.children_it(current, i)) >= 0; i++) {
|
||||||
Elem* c = ctx.find_elem(ctx.tree.get(ch));
|
Elem* c = ctx.find_elem(ctx.tree.get(ch))!;
|
||||||
if (ctx.tree.is_root(ch)) {
|
if (ctx.tree.is_root(ch)) {
|
||||||
resolve_dimensions(p, &&{});
|
resolve_dimensions(p, &&{});
|
||||||
} else {
|
} else {
|
||||||
@ -317,7 +317,7 @@ fn void Ctx.layout_element_tree(&ctx)
|
|||||||
|
|
||||||
// RESOLVE GROW CHILDREN
|
// RESOLVE GROW CHILDREN
|
||||||
for (int i; (ch = ctx.tree.children_it(current, i)) >= 0; i++) {
|
for (int i; (ch = ctx.tree.children_it(current, i)) >= 0; i++) {
|
||||||
Elem* c = ctx.find_elem(ctx.tree.get(ch));
|
Elem* c = ctx.find_elem(ctx.tree.get(ch))!;
|
||||||
if (ctx.tree.is_root(ch)) {
|
if (ctx.tree.is_root(ch)) {
|
||||||
resolve_grow_elements(p, &&{});
|
resolve_grow_elements(p, &&{});
|
||||||
} else {
|
} else {
|
||||||
@ -327,7 +327,7 @@ fn void Ctx.layout_element_tree(&ctx)
|
|||||||
|
|
||||||
// RESOLVE CHILDREN PLACEMENT
|
// RESOLVE CHILDREN PLACEMENT
|
||||||
for (int i; (ch = ctx.tree.children_it(current, i)) >= 0; i++) {
|
for (int i; (ch = ctx.tree.children_it(current, i)) >= 0; i++) {
|
||||||
Elem* c = ctx.find_elem(ctx.tree.get(ch));
|
Elem* c = ctx.find_elem(ctx.tree.get(ch))!;
|
||||||
if (ctx.tree.is_root(ch)) {
|
if (ctx.tree.is_root(ch)) {
|
||||||
resolve_placement(p, &&{});
|
resolve_placement(p, &&{});
|
||||||
update_children_bounds(p, &&{});
|
update_children_bounds(p, &&{});
|
||||||
|
@ -312,8 +312,12 @@ fn void MTree.prune(&tree, int parent)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<* @require tree.is_used(ref) *>
|
<* @require ref >= 0 , ref < tree.elem_vec.len *>
|
||||||
fn Type MTree.get(&tree, int ref) => tree.elem_vec[ref];
|
fn Type? MTree.get(&tree, int ref) @operator([])
|
||||||
|
{
|
||||||
|
if (tree.is_used(ref)) return tree.elem_vec[ref];
|
||||||
|
return NOT_FOUND?;
|
||||||
|
}
|
||||||
|
|
||||||
<* @require tree.is_used(ref) *>
|
<* @require tree.is_used(ref) *>
|
||||||
fn Type MTree.parentof(&tree, int ref) => tree.refs_vec[ref].parent;
|
fn Type MTree.parentof(&tree, int ref) => tree.refs_vec[ref].parent;
|
||||||
|
@ -13,8 +13,8 @@ macro Ctx.button(&ctx, String label = "", String icon = "", ...)
|
|||||||
fn ElemEvents? Ctx.button_id(&ctx, Id id, String label, String icon)
|
fn ElemEvents? Ctx.button_id(&ctx, Id id, String label, String icon)
|
||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
Elem *parent = ctx.get_parent()!;
|
Elem* parent, elem;
|
||||||
Elem *elem = ctx.get_elem(id, ETYPE_BUTTON)!;
|
ctx.get_elem(id, ETYPE_BUTTON)!.unpack(&elem, &parent);
|
||||||
Style* style = ctx.styles.get_style(@str_hash("button"));
|
Style* style = ctx.styles.get_style(@str_hash("button"));
|
||||||
|
|
||||||
Sprite* sprite = icon != "" ? ctx.sprite_atlas.get(icon)! : &&(Sprite){};
|
Sprite* sprite = icon != "" ? ctx.sprite_atlas.get(icon)! : &&(Sprite){};
|
||||||
@ -89,8 +89,8 @@ macro Ctx.checkbox(&ctx, String desc, bool* active, String tick_sprite = "", ...
|
|||||||
fn void? Ctx.checkbox_id(&ctx, Id id, String description, bool* active, String tick_sprite)
|
fn void? Ctx.checkbox_id(&ctx, Id id, String description, bool* active, String tick_sprite)
|
||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
Elem *parent = ctx.get_parent()!;
|
Elem* parent, elem;
|
||||||
Elem *elem = ctx.get_elem(id, ETYPE_BUTTON)!;
|
ctx.get_elem(id, ETYPE_BUTTON)!.unpack(&elem, &parent);
|
||||||
Style* style = ctx.styles.get_style(@str_hash("checkbox"));
|
Style* style = ctx.styles.get_style(@str_hash("checkbox"));
|
||||||
|
|
||||||
short inner_pad = description != "" ? style.size/2 : 0;
|
short inner_pad = description != "" ? style.size/2 : 0;
|
||||||
@ -163,8 +163,8 @@ fn void? Ctx.toggle_id(&ctx, Id id, String description, bool* active)
|
|||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
|
|
||||||
Elem *parent = ctx.get_parent()!;
|
Elem* parent, elem;
|
||||||
Elem *elem = ctx.get_elem(id, ETYPE_BUTTON)!;
|
ctx.get_elem(id, ETYPE_BUTTON)!.unpack(&elem, &parent);
|
||||||
Style* style = ctx.styles.get_style(@str_hash("toggle"));
|
Style* style = ctx.styles.get_style(@str_hash("toggle"));
|
||||||
|
|
||||||
short inner_pad = description != "" ? style.size/2 : 0;
|
short inner_pad = description != "" ? style.size/2 : 0;
|
||||||
|
@ -72,8 +72,8 @@ fn void? Ctx.div_begin_id(&ctx,
|
|||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
|
|
||||||
Elem* elem = ctx.get_elem(id, ETYPE_DIV)!;
|
Elem* parent, elem;
|
||||||
Elem* parent = ctx.get_parent()!;
|
ctx.get_elem(id, ETYPE_DIV)!.unpack(&elem, &parent);
|
||||||
ctx.active_div = elem.tree_idx;
|
ctx.active_div = elem.tree_idx;
|
||||||
|
|
||||||
Style* style = ctx.styles.get_style(@str_hash("div"));
|
Style* style = ctx.styles.get_style(@str_hash("div"));
|
||||||
@ -183,8 +183,8 @@ fn bool? Ctx.popup_begin_id(&ctx,
|
|||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
|
|
||||||
Elem* elem = ctx.get_elem(id, ETYPE_DIV)!;
|
Elem* parent, elem;
|
||||||
Elem* parent = ctx.find_elem(ctx.active_div); // pop-up parent is always root
|
ctx.get_elem(id, ETYPE_DIV)!.unpack(&elem, &parent);
|
||||||
ctx.active_div = elem.tree_idx;
|
ctx.active_div = elem.tree_idx;
|
||||||
|
|
||||||
Style* style = ctx.styles.get_style(@str_hash("popup"));
|
Style* style = ctx.styles.get_style(@str_hash("popup"));
|
||||||
|
@ -6,8 +6,8 @@ macro Ctx.separator(&ctx, int width, int height, ...)
|
|||||||
fn void? Ctx.separator_id(&ctx, Id id, int width, int height)
|
fn void? Ctx.separator_id(&ctx, Id id, int width, int height)
|
||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
Elem *parent = ctx.get_parent()!;
|
Elem* parent, elem;
|
||||||
Elem *elem = ctx.get_elem(id, ETYPE_NONE)!;
|
ctx.get_elem(id, ETYPE_NONE)!.unpack(&elem, &parent);
|
||||||
|
|
||||||
elem.layout.w = @exact((short)width);
|
elem.layout.w = @exact((short)width);
|
||||||
elem.layout.h = @exact((short)height);
|
elem.layout.h = @exact((short)height);
|
||||||
|
@ -22,8 +22,8 @@ fn ElemEvents? Ctx.slider_hor_id(&ctx, Id id, Size w, Size h, float* value, floa
|
|||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
|
|
||||||
Elem* parent = ctx.get_parent()!;
|
Elem* parent, elem;
|
||||||
Elem* elem = ctx.get_elem(id, ETYPE_SLIDER)!;
|
ctx.get_elem(id, ETYPE_SLIDER)!.unpack(&elem, &parent);
|
||||||
Style* style = ctx.styles.get_style(@str_hash("slider"));
|
Style* style = ctx.styles.get_style(@str_hash("slider"));
|
||||||
|
|
||||||
elem.layout.w = w;
|
elem.layout.w = w;
|
||||||
@ -85,8 +85,8 @@ fn ElemEvents? Ctx.slider_ver_id(&ctx, Id id, Size w, Size h, float* value, floa
|
|||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
|
|
||||||
Elem *parent = ctx.get_parent()!;
|
Elem* parent, elem;
|
||||||
Elem *elem = ctx.get_elem(id, ETYPE_SLIDER)!;
|
ctx.get_elem(id, ETYPE_SLIDER)!.unpack(&elem, &parent);
|
||||||
Style* style = ctx.styles.get_style(@str_hash("slider"));
|
Style* style = ctx.styles.get_style(@str_hash("slider"));
|
||||||
|
|
||||||
elem.layout.w = w;
|
elem.layout.w = w;
|
||||||
@ -135,8 +135,8 @@ fn void? Ctx.scrollbar(&ctx, Id id, float *value, float handle_percent, bool ver
|
|||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
|
|
||||||
Elem *parent = ctx.get_parent()!;
|
Elem* parent, elem;
|
||||||
Elem *elem = ctx.get_elem(id, ETYPE_SLIDER)!;
|
ctx.get_elem(id, ETYPE_SLIDER)!.unpack(&elem, &parent);
|
||||||
Style* style = ctx.styles.get_style(@str_hash("scrollbar"));
|
Style* style = ctx.styles.get_style(@str_hash("scrollbar"));
|
||||||
|
|
||||||
Rect pb = parent.bounds.pad(parent.layout.content_offset);
|
Rect pb = parent.bounds.pad(parent.layout.content_offset);
|
||||||
|
@ -9,8 +9,8 @@ macro Ctx.sprite(&ctx, String name, ...)
|
|||||||
fn void? Ctx.sprite_id(&ctx, Id id, String name)
|
fn void? Ctx.sprite_id(&ctx, Id id, String name)
|
||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
Elem *parent = ctx.get_parent()!;
|
Elem* parent, elem;
|
||||||
Elem *elem = ctx.get_elem(id, ETYPE_SPRITE)!;
|
ctx.get_elem(id, ETYPE_SPRITE)!.unpack(&elem, &parent);
|
||||||
|
|
||||||
Style* style = ctx.styles.get_style(@str_hash("sprite"));
|
Style* style = ctx.styles.get_style(@str_hash("sprite"));
|
||||||
Sprite* sprite = ctx.sprite_atlas.get(name)!;
|
Sprite* sprite = ctx.sprite_atlas.get(name)!;
|
||||||
|
@ -18,8 +18,8 @@ fn void? Ctx.text_id(&ctx, Id id, String text)
|
|||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
|
|
||||||
Elem *parent = ctx.get_parent()!;
|
Elem* parent, elem;
|
||||||
Elem *elem = ctx.get_elem(id, ETYPE_TEXT)!;
|
ctx.get_elem(id, ETYPE_TEXT)!.unpack(&elem, &parent);
|
||||||
Style* style = ctx.styles.get_style(@str_hash("text"));
|
Style* style = ctx.styles.get_style(@str_hash("text"));
|
||||||
|
|
||||||
Id text_hash = text.hash();
|
Id text_hash = text.hash();
|
||||||
@ -45,8 +45,8 @@ fn ElemEvents? Ctx.text_box_id(&ctx, Id id, Size w, Size h, TextEdit* te, Anchor
|
|||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
|
|
||||||
Elem *parent = ctx.get_parent()!;
|
Elem* parent, elem;
|
||||||
Elem *elem = ctx.get_elem(id, ETYPE_TEXT)!;
|
ctx.get_elem(id, ETYPE_TEXT)!.unpack(&elem, &parent);
|
||||||
Style* style = ctx.styles.get_style(@str_hash("text-box"));
|
Style* style = ctx.styles.get_style(@str_hash("text-box"));
|
||||||
|
|
||||||
elem.text.te = te;
|
elem.text.te = te;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user