WIP GUI_Layer, at partial working state
This commit is contained in:
1 parent
c32e0cee2c
commit
eeb0430300
1 file changed
+185
-40
@@ -127,7 +127,6 @@ typedef enum {
|
||||
} GUI_Layout_Direction;
|
||||
|
||||
typedef struct GUI_Node {
|
||||
#define RDIC_GUI_NODE_MEMBER_NAME rdic_node
|
||||
RDIC_Node rdic_node;
|
||||
GUI_Style *style;
|
||||
GUI_String text_string; // Optional.
|
||||
@@ -156,18 +155,19 @@ typedef struct GUI_Node {
|
||||
#define GUI_NODE_FIRST_CHILD(node) ((GUI_Node*)(node)->rdic_node.first_child)
|
||||
|
||||
typedef union GUI_Node_Reference {
|
||||
RDIC_Node_Reference rdic;
|
||||
RDIC_Node_Reference rdic_ref;
|
||||
struct {
|
||||
GUI_Node *node;
|
||||
unsigned int generation;
|
||||
};
|
||||
} GUI_Node_Reference;
|
||||
#define gui_node_references_equal(n, m) rdic_node_references_equal((n).rdic,(m).rdic)
|
||||
#if 0
|
||||
#define gui_node_references_equal(n, m) rdic_node_references_equal((n).rdic_ref,(m).rdic_ref)
|
||||
#else
|
||||
// NOTE(Zelaven): This was just for debugging with better debug messages.
|
||||
int _gui_node_references_equal(GUI_Node_Reference n, GUI_Node_Reference m)
|
||||
int gui_node_references_equal(GUI_Node_Reference n, GUI_Node_Reference m)
|
||||
{
|
||||
return rdic_node_references_equal(n.rdic,m.rdic);
|
||||
return rdic_node_references_equal(n.rdic_ref, m.rdic_ref);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -183,10 +183,10 @@ typedef struct {
|
||||
|
||||
typedef struct GUI_Subtree GUI_Subtree;
|
||||
struct GUI_Subtree {
|
||||
// NOTE(Zelaven): We are maintaining an immediate interface of subtrees too.
|
||||
RDIC_Node rdic_node;
|
||||
|
||||
RDIC_Context rdic;
|
||||
GUI_Subtree *prev;
|
||||
GUI_Subtree *next;
|
||||
GUI_Subtree *structural_parent;
|
||||
|
||||
// TODO(Zelaven):
|
||||
// GUI_Rectangle cliprect;
|
||||
@@ -199,13 +199,23 @@ struct GUI_Subtree {
|
||||
int offset_own_size_percentage_x;
|
||||
int offset_own_size_percentage_y;
|
||||
};
|
||||
typedef union GUI_Subtree_Reference {
|
||||
RDIC_Node_Reference rdic_ref;
|
||||
struct {
|
||||
GUI_Subtree *node;
|
||||
unsigned int generation;
|
||||
};
|
||||
} GUI_Subtree_Reference;
|
||||
|
||||
|
||||
typedef struct {
|
||||
GUI_Subtree *first_subtree;
|
||||
RDIC_Context subtree_rdic;
|
||||
//GUI_Subtree *first_subtree;
|
||||
//GUI_Subtree *last_subtree;
|
||||
//GUI_Subtree *current_subtree;
|
||||
|
||||
GUI_Subtree_Reference root_subtree;
|
||||
|
||||
GUI_Draw_Command *first_draw_command;
|
||||
int num_draw_commands;
|
||||
Pixel_Buffer pixel_buffer;
|
||||
@@ -217,11 +227,13 @@ typedef struct {
|
||||
|
||||
//GUI_Subtree *first_subtree;
|
||||
//GUI_Subtree *last_subtree;
|
||||
GUI_Subtree *current_subtree;
|
||||
//GUI_Subtree *current_subtree;
|
||||
|
||||
GUI_Layer background_layer;
|
||||
GUI_Layer top_layer;
|
||||
|
||||
GUI_Layer *current_layer;
|
||||
|
||||
GUI_Node_Reference focused_node;
|
||||
GUI_Node_Reference hovered_node;
|
||||
GUI_Node_Reference top_node_under_cursor;
|
||||
@@ -231,7 +243,8 @@ typedef struct {
|
||||
int mouse_y;
|
||||
|
||||
// TODO: An allocator for the nodes.
|
||||
RDIC_Node *node_freelist;
|
||||
RDIC_Freelist *node_freelist;
|
||||
RDIC_Freelist *subtree_freelist;
|
||||
|
||||
Memory_Arena *draw_command_arena;
|
||||
int num_draw_commands;
|
||||
@@ -328,6 +341,13 @@ void gui_apply_input(
|
||||
GUI_Context *context,
|
||||
int mouse_x,
|
||||
int mouse_y)
|
||||
{
|
||||
(void)context;
|
||||
(void)mouse_x;
|
||||
(void)mouse_y;
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
// --- Mouse Input ---
|
||||
// NOTE(Zelaven): First hit test against layers.
|
||||
@@ -371,6 +391,7 @@ void gui_apply_input(
|
||||
top_node_under_cursor->debug_string.length,
|
||||
top_node_under_cursor->debug_string.cstring);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
GUI_Node_Reference gui_get_node(
|
||||
@@ -380,10 +401,17 @@ GUI_Node_Reference gui_get_node(
|
||||
GUI_Style *style,
|
||||
GUI_Size size[static 2])
|
||||
{
|
||||
GUI_Layer *current_layer = context->current_layer;
|
||||
if(current_layer == NULL) {
|
||||
return (GUI_Node_Reference){0};
|
||||
}
|
||||
GUI_Subtree *current_subtree =
|
||||
(GUI_Subtree*)current_layer->subtree_rdic.frame_current_node;
|
||||
int get_node_flags = 0;
|
||||
GUI_Node_Reference new_reference = {
|
||||
.rdic = rdic_get_node(
|
||||
&context->current_subtree->rdic, last_reference.rdic, &get_node_flags),
|
||||
.rdic_ref = rdic_get_node(
|
||||
//&context->current_subtree->rdic, last_reference.rdic, &get_node_flags),
|
||||
¤t_subtree->rdic, last_reference.rdic_ref, &get_node_flags),
|
||||
};
|
||||
GUI_Node *node = new_reference.node;
|
||||
node->layout_direction = direction;
|
||||
@@ -409,6 +437,67 @@ GUI_Node_Reference gui_get_node(
|
||||
|
||||
return new_reference;
|
||||
}
|
||||
GUI_Subtree_Reference gui_get_subtree(
|
||||
GUI_Context *context,
|
||||
GUI_Subtree_Reference last_reference)
|
||||
{
|
||||
GUI_Layer *current_layer = context->current_layer;
|
||||
if(current_layer == NULL) {
|
||||
return (GUI_Subtree_Reference){0};
|
||||
}
|
||||
RDIC_Context *subtree_rdic = ¤t_layer->subtree_rdic;
|
||||
RDIC_Node *old_subtree_freelist_head = subtree_rdic->freelist->head;
|
||||
int get_node_flags = 0;
|
||||
GUI_Subtree_Reference new_reference = {
|
||||
.rdic_ref = rdic_get_node(
|
||||
//&context->current_subtree->rdic, last_reference.rdic, &get_node_flags),
|
||||
subtree_rdic, last_reference.rdic_ref, &get_node_flags),
|
||||
};
|
||||
GUI_Subtree *subtree = new_reference.node;
|
||||
subtree->rdic = (RDIC_Context){0};
|
||||
subtree->relative_to = (GUI_Node_Reference){0};
|
||||
subtree->flat_offset_x = 0;
|
||||
subtree->flat_offset_y = 0;
|
||||
subtree->offset_relative_node_percentage_x = 0;
|
||||
subtree->offset_relative_node_percentage_y = 0;
|
||||
subtree->offset_own_size_percentage_x = 0;
|
||||
subtree->offset_own_size_percentage_y = 0;
|
||||
|
||||
// TODO(Zelaven):
|
||||
// get_node_flags & RDIC_GET_NODE__OUT_OF_FREELIST
|
||||
// ^ This should result in an attempt to allocate more nodes for the freelist.
|
||||
// Then rdic_get_node should be retried.
|
||||
|
||||
if(get_node_flags & RDIC_GET_NODE__NODES_COLLECTED)
|
||||
{
|
||||
// NOTE(Zelaven): Some subtrees were collected, which means that their RDIC
|
||||
// node trees should be collected too.
|
||||
for(
|
||||
RDIC_Node *i = subtree_rdic->freelist->head;
|
||||
i != old_subtree_freelist_head;
|
||||
i = i->sibling)
|
||||
{
|
||||
GUI_Subtree *subtree = (GUI_Subtree*)i;
|
||||
rdic_cull_subtrees(&subtree->rdic, subtree->rdic.root);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if(get_node_flags & RDIC_GET_NODE__NODES_COLLECTED)
|
||||
{
|
||||
GUI_NODE_PARENT(node)->dirty = true;
|
||||
}
|
||||
if(get_node_flags & RDIC_GET_NODE__NODE_ALLOCATED)
|
||||
{
|
||||
GUI_NODE_PARENT(node)->dirty = true;
|
||||
}
|
||||
node->dirty = (get_node_flags & RDIC_GET_NODE__NODE_ALLOCATED) != 0;
|
||||
#endif
|
||||
|
||||
|
||||
return new_reference;
|
||||
}
|
||||
|
||||
|
||||
#undef ENABLE_DEBUG
|
||||
#define ENABLE_DEBUG 0
|
||||
@@ -438,16 +527,34 @@ GUI_Node_Reference gui_context_start_frame(
|
||||
context->mouse_x, context->mouse_y,
|
||||
context->mouse_pressed, context->mouse_down);
|
||||
|
||||
static GUI_Subtree background_subtree = {0};
|
||||
background_subtree.rdic.node_freelist = context->node_freelist;
|
||||
context->background_layer.first_subtree = &background_subtree;
|
||||
context->current_layer = &context->background_layer;
|
||||
|
||||
GUI_Subtree_Reference root_subtree = context->current_layer->root_subtree;
|
||||
//root_subtree = gui_get_subtree(context, root_subtree);
|
||||
root_subtree.rdic_ref = rdic_context_start_frame(
|
||||
&context->current_layer->subtree_rdic, root_subtree.rdic_ref);
|
||||
if(root_subtree.node == NULL)
|
||||
{
|
||||
return (GUI_Node_Reference){0};
|
||||
}
|
||||
context->current_layer->root_subtree = root_subtree;
|
||||
root_subtree.node->rdic.freelist = context->node_freelist;
|
||||
|
||||
//static GUI_Subtree background_subtree = {0};
|
||||
//background_subtree.rdic.freelist = context->node_freelist;
|
||||
//context->background_layer.first_subtree = &background_subtree;
|
||||
//context->background_layer.last_subtree = &background_subtree;
|
||||
context->current_subtree = &background_subtree;
|
||||
//context->current_subtree = &background_subtree;
|
||||
|
||||
GUI_Node_Reference new_root_reference = {
|
||||
.rdic = rdic_context_start_frame(
|
||||
&background_subtree.rdic, last_root_reference.rdic)
|
||||
.rdic_ref = rdic_context_start_frame(
|
||||
//&background_subtree.rdic, last_root_reference.rdic)
|
||||
&root_subtree.node->rdic, last_root_reference.rdic_ref)
|
||||
};
|
||||
if(new_root_reference.node == NULL)
|
||||
{
|
||||
return (GUI_Node_Reference){0};
|
||||
}
|
||||
//RDIC_Node_Reference new_root_reference = rdic_context_start_frame(
|
||||
// &background_subtree.rdic,
|
||||
// last_root_reference);
|
||||
@@ -475,35 +582,38 @@ GUI_Node_Reference gui_context_start_frame(
|
||||
void gui_context_finish_frame(
|
||||
GUI_Context *context)
|
||||
{
|
||||
rdic_context_finish_frame(&context->background_layer.first_subtree->rdic);
|
||||
context->node_freelist =
|
||||
context->background_layer.first_subtree->rdic.node_freelist;
|
||||
//rdic_context_finish_frame(&context->background_layer.first_subtree->rdic);
|
||||
rdic_context_finish_frame(&context->background_layer.root_subtree.node->rdic);
|
||||
//context->node_freelist =
|
||||
// context->background_layer.first_subtree->rdic.node_freelist;
|
||||
}
|
||||
|
||||
GUI_Node_Reference gui_push_subtree(
|
||||
GUI_Context *context,
|
||||
GUI_Subtree *subtree,
|
||||
GUI_Subtree_Reference subtree,
|
||||
GUI_Node_Reference last_root_reference,
|
||||
GUI_Layout_Direction layout_direction,
|
||||
GUI_Style *style,
|
||||
GUI_Size size[static 2],
|
||||
GUI_Node_Reference relative_to)
|
||||
{
|
||||
context->node_freelist = context->current_subtree->rdic.node_freelist;
|
||||
subtree->rdic.node_freelist = context->node_freelist;
|
||||
RDIC_Context *layer_rdic_context = &context->current_layer->subtree_rdic;
|
||||
rdic_push_parent(layer_rdic_context, subtree.rdic_ref);
|
||||
//context->node_freelist = context->current_subtree->rdic.node_freelist;
|
||||
//subtree->rdic.node_freelist = context->node_freelist;
|
||||
|
||||
// NOTE(Zelaven): Well, not being able to do this is a problem...
|
||||
//context->last_subtree->next = subtree;
|
||||
//subtree->prev = context->last_subtree;
|
||||
//context->last_subtree = subtree;
|
||||
|
||||
subtree->structural_parent = context->current_subtree;
|
||||
context->current_subtree = subtree;
|
||||
subtree->relative_to = relative_to;
|
||||
//subtree->structural_parent = context->current_subtree;
|
||||
//context->current_subtree = subtree;
|
||||
subtree.node->relative_to = relative_to;
|
||||
|
||||
GUI_Node_Reference new_root_reference = {
|
||||
.rdic = rdic_context_start_frame(
|
||||
&subtree->rdic, last_root_reference.rdic)
|
||||
.rdic_ref = rdic_context_start_frame(
|
||||
&subtree.node->rdic, last_root_reference.rdic_ref)
|
||||
};
|
||||
GUI_Node *root = (GUI_Node*)new_root_reference.node;
|
||||
root->dirty = false;
|
||||
@@ -526,9 +636,12 @@ GUI_Node_Reference gui_push_subtree(
|
||||
void gui_pop_subtree(
|
||||
GUI_Context *context)
|
||||
{
|
||||
context->node_freelist = context->current_subtree->rdic.node_freelist;
|
||||
context->current_subtree = context->current_subtree->structural_parent;
|
||||
context->current_subtree->rdic.node_freelist = context->node_freelist;
|
||||
//context->node_freelist = context->current_subtree->rdic.node_freelist;
|
||||
//context->current_subtree = context->current_subtree->structural_parent;
|
||||
//context->current_subtree->rdic.node_freelist = context->node_freelist;
|
||||
|
||||
RDIC_Context *layer_rdic_context = &context->current_layer->subtree_rdic;
|
||||
rdic_pop_parent(layer_rdic_context);
|
||||
}
|
||||
|
||||
|
||||
@@ -536,13 +649,19 @@ void gui_push_parent(
|
||||
GUI_Context *context,
|
||||
GUI_Node_Reference parent)
|
||||
{
|
||||
rdic_push_parent(&context->current_subtree->rdic, parent.rdic);
|
||||
GUI_Layer *current_layer = context->current_layer;
|
||||
GUI_Subtree *current_subtree =
|
||||
(GUI_Subtree*)current_layer->subtree_rdic.frame_current_node;
|
||||
rdic_push_parent(¤t_subtree->rdic, parent.rdic_ref);
|
||||
}
|
||||
|
||||
void gui_pop_parent(
|
||||
GUI_Context *context)
|
||||
{
|
||||
rdic_pop_parent(&context->current_subtree->rdic);
|
||||
GUI_Layer *current_layer = context->current_layer;
|
||||
GUI_Subtree *current_subtree =
|
||||
(GUI_Subtree*)current_layer->subtree_rdic.frame_current_node;
|
||||
rdic_pop_parent(¤t_subtree->rdic);
|
||||
}
|
||||
|
||||
|
||||
@@ -1431,6 +1550,7 @@ void test_gui__draw_command_using_sliders(
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void test_gui__subtree(
|
||||
GUI_Context *context,
|
||||
GUI_Rectangle full_gui_rectangle)
|
||||
@@ -1544,6 +1664,7 @@ void test_gui__subtree(
|
||||
|
||||
gui_context_finish_frame(context);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
@@ -2749,8 +2870,21 @@ void init_node_freelist(GUI_Node *nodes, int node_count)
|
||||
}
|
||||
nodes[node_count-1].rdic_node = (RDIC_Node){0};
|
||||
}
|
||||
void init_subtree_freelist(GUI_Subtree *nodes, int subtree_count)
|
||||
{
|
||||
// NOTE(Zelaven): We special-case the last node.
|
||||
for(int i = 0; i < subtree_count -1; i++)
|
||||
{
|
||||
nodes[i] = (GUI_Subtree){0};
|
||||
nodes[i].rdic_node = (RDIC_Node){
|
||||
.sibling = &((nodes+i+1)->rdic_node),
|
||||
};
|
||||
}
|
||||
nodes[subtree_count-1].rdic_node = (RDIC_Node){0};
|
||||
}
|
||||
|
||||
GUI_Node g_gui_node_freelist[128];
|
||||
GUI_Subtree g_gui_subtree_freelist[16];
|
||||
|
||||
|
||||
|
||||
@@ -3026,11 +3160,11 @@ int main(void)
|
||||
|
||||
// GUI initializaiton.
|
||||
|
||||
//gui = test_gui;
|
||||
gui = test_gui;
|
||||
//gui = test_gui__calculator;
|
||||
//gui = test_gui__scrollbars;
|
||||
//gui = test_gui__draw_command_using_sliders;
|
||||
gui = test_gui__subtree;
|
||||
//gui = test_gui__subtree;
|
||||
|
||||
X11_Window xwindow = {0};
|
||||
int xinit_status = init_x11(&xwindow);
|
||||
@@ -3050,7 +3184,18 @@ int main(void)
|
||||
context.rdic.node_freelist = &g_gui_node_freelist[0].rdic_node;
|
||||
#else
|
||||
init_node_freelist(g_gui_node_freelist, ARRAYLENGTH(g_gui_node_freelist));
|
||||
context.node_freelist = &g_gui_node_freelist[0].rdic_node;
|
||||
RDIC_Freelist node_freelist = {&g_gui_node_freelist[0].rdic_node};
|
||||
context.node_freelist = &node_freelist;
|
||||
init_subtree_freelist(g_gui_subtree_freelist, ARRAYLENGTH(g_gui_subtree_freelist));
|
||||
RDIC_Freelist subtree_freelist = {&g_gui_subtree_freelist[0].rdic_node};
|
||||
context.subtree_freelist = &subtree_freelist;
|
||||
|
||||
context.background_layer = (GUI_Layer){
|
||||
.subtree_rdic.freelist = &subtree_freelist,
|
||||
};
|
||||
context.top_layer = (GUI_Layer){
|
||||
.subtree_rdic.freelist = &subtree_freelist,
|
||||
};
|
||||
#endif
|
||||
|
||||
context.draw_command_arena = &draw_command_arena;
|
||||
@@ -3190,9 +3335,9 @@ int main(void)
|
||||
//gui_layout_nodes(&context);
|
||||
#if 1
|
||||
for(
|
||||
GUI_Subtree *current = context.background_layer.first_subtree;
|
||||
GUI_Subtree *current = (GUI_Subtree*)context.background_layer.subtree_rdic.root;
|
||||
current != NULL;
|
||||
current = current->next)
|
||||
current = NULL)//current->next)
|
||||
{
|
||||
gui_layout_nodes((GUI_Node*)current->rdic.root);
|
||||
gui_generate_draw_commands(
|
||||
|
||||
Reference in new issue
Block a user