|
|
@ -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; |
|
|
|