From 5e070521bcd71d953c9790a83330f19b8f33d793 Mon Sep 17 00:00:00 2001 From: Patrick Jakobsen Date: Sun, 1 Oct 2023 16:00:10 +0200 Subject: [PATCH] Can click button inside scrollable --- gui/gui.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 12 deletions(-) diff --git a/gui/gui.c b/gui/gui.c index d86029b..0d3a582 100644 --- a/gui/gui.c +++ b/gui/gui.c @@ -421,6 +421,30 @@ void gui_apply_input( assert(hit_root_subtree != NULL); + GUI_Subtree *top_subtree_under_cursor = hit_root_subtree; + GUI_Subtree *current_subtree = GUI_SUBTREE_FIRST_CHILD(top_subtree_under_cursor); + int mouse_over_subtree = 0; + while(current_subtree != NULL) + { + // TODO(Zelaven): Should actually test against the rect-intersect between + // the clipnode and the subtree root. The clipnode is only a maximal bound. + mouse_over_subtree = point_in_rect_with_offset( + mouse_x, mouse_y, + // TODO(Zelaven): Test clipnode valid. + current_subtree->clipnode.node->rect, + hit_layer->offset_x, hit_layer->offset_y); + if(mouse_over_subtree) + { + top_subtree_under_cursor = current_subtree; + current_subtree = GUI_SUBTREE_FIRST_CHILD(current_subtree); + } + else + { + current_subtree = GUI_SUBTREE_SIBLING(current_subtree); + } + } + hit_root_subtree = top_subtree_under_cursor; + GUI_Node *top_node_under_cursor = (GUI_Node*)hit_root_subtree->rdic.root; GUI_Node *current_node = (GUI_Node*)top_node_under_cursor->rdic_node.first_child; int mouse_over_node = 0; @@ -870,8 +894,45 @@ void gui_layout_calculate_screen_rects( } } -void gui_layout_nodes(GUI_Node *root) +void gui_layout_nodes(GUI_Subtree *subtree) { +#if 1 + GUI_Node *root = (GUI_Node*)subtree->rdic.root; + assert(root != NULL); + for(GUI_Axis2 axis = 0; axis < GUI_AXIS2_COUNT; axis++) + { + gui_layout_calculate_standalone_sizes(root, axis); + gui_layout_calculate_parent_percent_sizes(root, axis); + } + + // TODO(Zelaven): Test reference validity. + // TODO(Zelaven): This probably can be done once and passed in. + int x_offset = 0; + int y_offset = 0; + GUI_Node *relative_node = (GUI_Node*)subtree->relative_to.node; + if(relative_node != NULL){ + GUI_Rectangle *relative_rectangle = &relative_node->rect; + x_offset = relative_rectangle->x0; + y_offset = relative_rectangle->y0; + //printf("%.*s: %d, %d\n", relative_node->debug_string.length, relative_node->debug_string.cstring, x_offset, y_offset); + int relative_width = relative_rectangle->x1 - relative_rectangle->x0; + int relative_height = relative_rectangle->y1 - relative_rectangle->y0; + x_offset += + (relative_width * subtree->offset_relative_node_percentage_x) / 100; + y_offset += + (relative_height * subtree->offset_relative_node_percentage_y) / 100; + } + x_offset += subtree->flat_offset_x; + y_offset += subtree->flat_offset_y; + + x_offset += + (root->computed_size[GUI_AXIS2_X] * subtree->offset_own_size_percentage_x) / 100; + y_offset += + (root->computed_size[GUI_AXIS2_Y] * subtree->offset_own_size_percentage_y) / 100; + + gui_layout_calculate_screen_rects(root, x_offset, y_offset, GUI_LAYOUT_NONE); +#else + //GUI_Node *root = (GUI_Node*)context->first_subtree->rdic.root; for(GUI_Axis2 axis = 0; axis < GUI_AXIS2_COUNT; axis++) { @@ -879,6 +940,7 @@ void gui_layout_nodes(GUI_Node *root) gui_layout_calculate_parent_percent_sizes(root, axis); } gui_layout_calculate_screen_rects(root, 0, 0, GUI_LAYOUT_NONE); +#endif } @@ -888,8 +950,8 @@ void gui_layout_nodes(GUI_Node *root) #undef ENABLE_DEBUG #define ENABLE_DEBUG 0 void gui_generate_draw_commands_inner( - int x_offset, - int y_offset, + //int x_offset, + //int y_offset, GUI_Node *node, bool dirty, //TODO(Zelaven): Better name. Memory_Arena *draw_command_arena, @@ -911,10 +973,12 @@ void gui_generate_draw_commands_inner( .text = node->text_string, .image = node->image, }; +#if 0 (*draw_command).rectangle.x0 += x_offset; (*draw_command).rectangle.x1 += x_offset; (*draw_command).rectangle.y0 += y_offset; (*draw_command).rectangle.y1 += y_offset; +#endif *out_num_draw_commands += 1; } @@ -922,7 +986,7 @@ void gui_generate_draw_commands_inner( if(sibling != NULL) { GUI_Node *parent = GUI_NODE_PARENT(node); gui_generate_draw_commands_inner( - x_offset, y_offset, + //x_offset, y_offset, sibling, parent->dirty || sibling->dirty, draw_command_arena, out_num_draw_commands); @@ -930,7 +994,7 @@ void gui_generate_draw_commands_inner( GUI_Node *first_child = GUI_NODE_FIRST_CHILD(node); if(node->rdic_node.first_child != NULL) { gui_generate_draw_commands_inner( - x_offset, y_offset, + //x_offset, y_offset, first_child, dirty || first_child->dirty, draw_command_arena, out_num_draw_commands); @@ -943,6 +1007,7 @@ void gui_generate_draw_commands( Memory_Arena *draw_command_arena, int *out_num_draw_commands) { +#if 0 // TODO(Zelaven): Test reference validity. // TODO(Zelaven): This probably can be done once and passed in. int x_offset = 0; @@ -969,6 +1034,10 @@ void gui_generate_draw_commands( (root->computed_size[GUI_AXIS2_X] * subtree->offset_own_size_percentage_x) / 100; y_offset += (root->computed_size[GUI_AXIS2_Y] * subtree->offset_own_size_percentage_y) / 100; +#else + GUI_Node *root = (GUI_Node*)subtree->rdic.root; + assert(root != NULL); +#endif assert(draw_command_arena != NULL); assert(out_num_draw_commands != NULL); @@ -980,7 +1049,7 @@ void gui_generate_draw_commands( dirtyness |= clipnode.node->dirty; } gui_generate_draw_commands_inner( - x_offset, y_offset, + //x_offset, y_offset, root, dirtyness, draw_command_arena, out_num_draw_commands); } @@ -1099,7 +1168,7 @@ bool gui_mouseover_box( } #undef ENABLE_DEBUG -#define ENABLE_DEBUG 1 +#define ENABLE_DEBUG 0 bool gui_slider( GUI_Context *context, GUI_Node_Reference *last_reference, @@ -1892,8 +1961,8 @@ void test_gui__subtree( context->top_layer.pixel_buffer->width, context->top_layer.pixel_buffer->height, GUI_LAYOUT_HORIZONTAL, &outer_style); - context->top_layer.offset_x = 50; - context->top_layer.offset_y = 250; + context->top_layer.offset_x = 70; + context->top_layer.offset_y = 20; static GUI_Node_Reference top = {0}; @@ -1928,6 +1997,7 @@ void test_gui__subtree( &button_style, button_size)) { should_dirty = true; + printf("Dirtying middle.\n"); } static GUI_Node_Reference dirty_button2 = {0}; if(gui_dumb_button( @@ -1944,6 +2014,7 @@ void test_gui__subtree( &button_style, button_size)) { tooltip_toggle = !tooltip_toggle; + printf("Toggling tooltip.\n"); } static GUI_Node_Reference dirty_button4 = {0}; if( @@ -2000,6 +2071,14 @@ void test_gui__subtree( static GUI_Node_Reference inner_top = {0}; inner_top = gui_dumb_block(context, inner_top, &outer_style, element_size); ((GUI_Node*)inner_top.node)->image = &test_image; + + static GUI_Node_Reference subtree_button = {0}; + if(gui_dumb_button( + context, &subtree_button, GUI_STRING("In subtree"), + &element_style, element_size)) + { + printf("Hi from subtree!\n"); + } } gui_pop_subtree(context); #endif #if 0 @@ -3652,7 +3731,8 @@ void gui_layout_and_draw_subtree( GUI_Subtree *subtree, Pixel_Buffer *pixel_buffer) { - gui_layout_nodes((GUI_Node*)subtree->rdic.root); + //gui_layout_nodes((GUI_Node*)subtree->rdic.root); + gui_layout_nodes(subtree); gui_generate_draw_commands( subtree, context->draw_command_arena, @@ -3817,9 +3897,9 @@ int main(void) .height = xwindow.pixel_buffer.height, }; Pixel_Buffer top_pixel_buffer = (Pixel_Buffer){ - .pixels = malloc(300*200*sizeof(GUI_Color)), + .pixels = malloc(300*400*sizeof(GUI_Color)), .width = 300, - .height = 200, + .height = 400, }; assert(background_pixel_buffer.pixels); assert(top_pixel_buffer.pixels); @@ -3953,6 +4033,7 @@ int main(void) #if 1 gui_layout_and_draw(&context); gui_compose_layers(&context, &xwindow.pixel_buffer); + //SET_PIXEL(&xwindow.pixel_buffer, 200, 388, 0x00ff0000); #else for( GUI_Subtree *current = (GUI_Subtree*)context.background_layer.subtree_rdic.root;