浏览代码

WIP GUI_Layer, at partial working state

master
Patrick Jakobsen 7 个月前
父节点
当前提交
eeb0430300
共有 1 个文件被更改,包括 185 次插入40 次删除
  1. +185
    -40
      gui/gui.c

+ 185
- 40
gui/gui.c 查看文件

@ -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),
&current_subtree->rdic, last_reference.rdic_ref, &get_node_flags),
};
GUI_Node *node = new_reference.node;
node->layout_direction = direction;
@ -407,9 +435,70 @@ GUI_Node_Reference gui_get_node(
node->dirty = (get_node_flags & RDIC_GET_NODE__NODE_ALLOCATED) != 0;
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 = &current_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
// TODO(Zelaven): Make this cause redrawing of root on parameter change.
@ -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(&current_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(&current_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(

正在加载...
取消
保存