Scrollable region
This commit is contained in:
1 parent
44d375af29
commit
591a53e627
1 file changed
+165
-23
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user