diff --git a/gui/gui.c b/gui/gui.c index c9d0149..17d8c5c 100644 --- a/gui/gui.c +++ b/gui/gui.c @@ -1116,6 +1116,8 @@ bool gui_slider( inner->text_string = (GUI_String){0}; assert(*value <= 1.0f); //inner->semantic_size[GUI_AXIS2_X].value = last_frame_width*(*value); + inner->semantic_size[GUI_AXIS2_Y] = + (GUI_Size){GUI_SIZERULE_PERCENTOFPARENT, 100, 100}; inner->semantic_size[GUI_AXIS2_X].size_rule = GUI_SIZERULE_PERCENTOFPARENT; inner->semantic_size[GUI_AXIS2_X].value = 100 * (*value); gui_pop_parent(context); @@ -1128,6 +1130,109 @@ bool gui_slider( return value_changed; } +#undef ENABLE_DEBUG +#define ENABLE_DEBUG 0 +bool gui_vertical_slider( + GUI_Context *context, + GUI_Node_Reference *last_reference, + GUI_Node_Reference *inner_box_reference, + float *value, + GUI_Style *background_style, + GUI_Style *bar_style, + GUI_Size size[static 2]) +{ + GUI_Node_Reference new_reference = gui_get_node( + context, *last_reference, GUI_LAYOUT_NONE, background_style, size); + GUI_Node *node = new_reference.node; + node->debug_string = GUI_STRING("gui_slider"); + node->text_string = (GUI_String){0}; + + // NOTE(Zelaven): We need a handle to this node, but we set its values later. + gui_push_parent(context, new_reference); + GUI_Node_Reference new_inner_reference = gui_get_node( + context, *inner_box_reference, GUI_LAYOUT_NONE, bar_style, size); + + bool value_changed = false; + bool new_ref_is_top = gui_node_references_equal( + new_reference, context->top_node_under_cursor); + bool inner_ref_is_top = gui_node_references_equal( + new_inner_reference, context->top_node_under_cursor); + DEBUG("%p\n | %p %p\n | %p %p\n", + context->top_node_under_cursor.node, + last_reference->node, inner_box_reference->node, + new_reference.node, new_inner_reference.node); + if(new_ref_is_top || inner_ref_is_top) + { + DEBUG("\n%s: reference is the top node under cursor.\n", __func__); + if(context->mouse_pressed) + { + DEBUG(" Mouse pressed on node\n"); + context->focused_node = new_reference; + } + else if(!context->mouse_down) + { + DEBUG(" Mouse released on node\n"); + if(gui_node_references_equal(new_reference, context->focused_node)) + { + DEBUG(" Mouse released over same node as pressed\n"); + context->focused_node.node = NULL; + } + } + } + else if(gui_node_references_equal(new_reference, context->focused_node) + && !context->mouse_down) + { + context->focused_node.node = NULL; + } + + if(gui_node_references_equal(new_reference, context->focused_node)) + { + int last_frame_height = node->computed_size[GUI_AXIS2_Y]; + if(last_frame_height == 0) + { + DEBUG( + " last_frame_height is 0." + " This shouldn't really happen as the user shouldn't be able to focus" + " a node that hasn't been displayed on the screen yet." + " Not going to change the slider value."); + } + else + { + int offset_y = context->mouse_y - node->rect.y0; + float before_value = *value; + float new_value = ((float)offset_y) / ((float)last_frame_height); + if(new_value < 0.0f) + { + new_value = 0.0f; + } + else if(new_value >= 1.0f) + { + new_value = 1.0f; + } + *value = new_value; + DEBUG(" Value before: %f - Value after: %f\n", before_value, *value); + value_changed = (before_value != new_value); + } + } + + // NOTE(Zelaven): Modified by input, so handle input first. + GUI_Node *inner = new_inner_reference.node; + inner->debug_string = GUI_STRING("gui_slider - inner node"); + inner->text_string = (GUI_String){0}; + assert(*value <= 1.0f); + inner->semantic_size[GUI_AXIS2_X] = + (GUI_Size){GUI_SIZERULE_PERCENTOFPARENT, 100, 100}; + inner->semantic_size[GUI_AXIS2_Y].size_rule = GUI_SIZERULE_PERCENTOFPARENT; + inner->semantic_size[GUI_AXIS2_Y].value = 100 * (*value); + gui_pop_parent(context); + + + *last_reference = new_reference; + *inner_box_reference = new_inner_reference; + if(value_changed) {node->dirty = true;} + return value_changed; +} + @@ -1441,14 +1546,16 @@ void test_gui__scrollbars( middle = gui_layout( context, middle, GUI_LAYOUT_HORIZONTAL, &outer_style, middle_size); - gui_push_parent(context, middle); { + gui_push_parent(context, middle); + { static GUI_Node_Reference left = {0}; static GUI_Node_Reference center = {0}; static GUI_Node_Reference right = {0}; left = gui_dumb_block(context, left, &outer_style, side_size); center = gui_dumb_block(context, center, &outer_style, center_size); - gui_push_parent(context, center); { + gui_push_parent(context, center); + { static GUI_Node_Reference scrollbox_layout = {0}; static GUI_Size full_size[2] = { {GUI_SIZERULE_PERCENTOFPARENT, 100, 100}, @@ -1456,7 +1563,8 @@ void test_gui__scrollbars( scrollbox_layout = gui_layout( context, scrollbox_layout, GUI_LAYOUT_HORIZONTAL, &outer_style, full_size); - gui_push_parent(context, scrollbox_layout); { + gui_push_parent(context, scrollbox_layout); + { static GUI_Node_Reference scrollregion_layout = {0}; static GUI_Node_Reference scrollbar_layout = {0}; static GUI_Size scrollregion_size[2] = { @@ -1465,17 +1573,46 @@ void test_gui__scrollbars( static GUI_Size scrollbar_size[2] = { {GUI_SIZERULE_PERCENTOFPARENT, 10, 100}, {GUI_SIZERULE_PERCENTOFPARENT, 100, 100}}; +#if 0 scrollregion_layout = gui_layout( context, scrollregion_layout, GUI_LAYOUT_VERTICAL, &outer_style, scrollregion_size); - gui_push_parent(context, scrollregion_layout); { + gui_push_parent(context, scrollregion_layout); + { static GUI_Node_Reference elements[6] = {0}; - for(size_t i = 0; i < ARRAYLENGTH(elements); i++) - { + for(size_t i = 0; i < ARRAYLENGTH(elements); i++) { elements[i] = gui_dumb_block( context, elements[i], &element_style, element_size); } } gui_pop_parent(context); +#else + scrollregion_layout = gui_dumb_block( + context, scrollregion_layout, &outer_style, scrollregion_size); + static GUI_Subtree_Reference scrollregion_subtree = {0}; + scrollregion_subtree = gui_get_subtree(context, scrollregion_subtree); + static GUI_Node_Reference scrollregion_root = {0}; + static GUI_Size scrollregion_inner_size[2] = { + {GUI_SIZERULE_PERCENTOFPARENT, 100, 100}, + //{GUI_SIZERULE_PIXELS, 100, 100}, + {GUI_SIZERULE_PIXELS, 880, 100}}; + scrollregion_root = gui_push_subtree( + context, scrollregion_subtree, scrollregion_root, + GUI_LAYOUT_VERTICAL, &outer_style, scrollregion_inner_size, + scrollbox_layout); + // TODO(Zelaven): Instead of this hack, add to the layout code that it + // can set the size of the root relative to the size of its relative + // node. + scrollregion_root.rdic_ref.node->parent = scrollregion_layout.rdic_ref.node; + { + static GUI_Node_Reference elements[6] = {0}; + for(size_t i = 0; i < ARRAYLENGTH(elements); i++) { + elements[i] = gui_dumb_block( + context, elements[i], &element_style, element_size); + } + + } gui_pop_subtree(context); +#endif +#if 0 scrollbar_layout = gui_layout( context, scrollbar_layout, GUI_LAYOUT_VERTICAL, &outer_style, scrollbar_size); @@ -1483,7 +1620,8 @@ void test_gui__scrollbars( int spacer_total = 90; int spacer_upper = scroll_position * spacer_total; int spacer_lower = spacer_total - spacer_upper; - gui_push_parent(context, scrollbar_layout); { + gui_push_parent(context, scrollbar_layout); + { static GUI_Size bar_knob_size[2] = { {GUI_SIZERULE_PERCENTOFPARENT, 100, 100}, {GUI_SIZERULE_PERCENTOFPARENT, 10, 100}}; @@ -1507,14 +1645,22 @@ void test_gui__scrollbars( scrollbar_lower_spacer = gui_dumb_block( context, scrollbar_lower_spacer, &outer_style, bar_lower_spacer_size); } gui_pop_parent(context); // scrollbar_layout. - #if 0 - float contents_height_ratio = 0.0f; - if(scrollbox_layout.node->computed_size[GUI_AXIS2_Y] > 0) { - float layout_height = - (float)scrollbox_layout.node->computed_size[GUI_AXIS2_Y]; - float contents_height = 600.0f; // TODO(Zelaven): take from scrollregion_layout. (dependency on CHILDRENSUM). - } - #endif +#else + static float slider_value = 0.0f; + static GUI_Style slider_background = {0, 0, 0, 0,0,0}; + static GUI_Style slider_bar = {255, 0, 0, 0,0,0}; + static GUI_Node_Reference slider = {0}; + static GUI_Node_Reference slider_inner = {0}; + gui_vertical_slider(context, &slider, &slider_inner, + &slider_value, &slider_background, &slider_bar, scrollbar_size); + scrollregion_subtree.node->offset_relative_node_percentage_y = + slider_value*100; + scrollregion_subtree.node->offset_own_size_percentage_y = + slider_value*-100; + scrollregion_root.node->dirty = true; + //((GUI_Node*)slider.node)->dirty; + //printf("Slider value: %f\n", slider_value); +#endif } gui_pop_parent(context); // scrollbox_layout. } gui_pop_parent(context); // center. right = gui_dumb_block(context, right, &outer_style, side_size); @@ -1688,11 +1834,6 @@ void test_gui__subtree( {GUI_SIZERULE_PIXELS, 40, 100}}; //static GUI_Node_Reference slider = {0}; static GUI_Node_Reference slider_inner = {0}; - // NOTE(Zelaven): This line is not good because it causes jankyness when - // using the slider, and the slider behaves properly without it. - // NOTE(Zelaven): This line is actually necessary if the value is writable - // by anything other than the slider. If border_thickness is a float - // variable, then there is no issue, though. gui_slider(context, &slider, &slider_inner, &slider_value, &slider_background, &slider_bar, slider_size); @@ -1773,7 +1914,7 @@ void test_gui__subtree( middle_subtree.node->offset_relative_node_percentage_y = slider_value*100; middle_subtree.node->offset_own_size_percentage_y = slider_value*-100; #endif - ((GUI_Node*)middle_subtree_root.node)->dirty = ((GUI_Node*)slider.node)->dirty; + middle_subtree_root.node->dirty = ((GUI_Node*)slider.node)->dirty; bottom = gui_dumb_block(context, bottom, &element_style, top_bottom_size); @@ -3499,9 +3640,9 @@ int main(void) //gui = test_gui; //gui = test_gui__calculator; - //gui = test_gui__scrollbars; + gui = test_gui__scrollbars; //gui = test_gui__draw_command_using_sliders; - gui = test_gui__subtree; + //gui = test_gui__subtree; //gui = test_gui__tmp; X11_Window xwindow = {0}; @@ -3676,6 +3817,7 @@ int main(void) //gui_layout_nodes(&context); #if 1 gui_layout_and_draw(&context); + SET_PIXEL(&xwindow.pixel_buffer, 239, 259, 0x00ff0000); #else for( GUI_Subtree *current = (GUI_Subtree*)context.background_layer.subtree_rdic.root;