added dynamically growing panels with fixed maximum height

This commit is contained in:
vurtun 2015-08-11 14:44:53 +02:00
parent bfa81e57b1
commit 3b8ea32982
2 changed files with 314 additions and 300 deletions

240
gui.c
View File

@ -3040,7 +3040,6 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel)
gui_bool inpanel;
gui_float x, y, w, h;
struct gui_command_buffer_list *s = &panel->queue->list;
x = panel->x; y = panel->y; w = panel->w; h = panel->h;
inpanel = GUI_INBOX(in->mouse_prev.x, in->mouse_prev.y, x, y, w, h);
if (in->mouse_down && in->mouse_clicked && inpanel && &panel->buffer != s->end) {
@ -3076,30 +3075,13 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel)
const gui_float move_w = panel->w;
const gui_float move_h = layout->header.h;
incursor = GUI_INBOX(in->mouse_prev.x, in->mouse_prev.y,
move_x, move_y, move_w, move_h);
move_x, move_y, move_w, move_h);
if (in->mouse_down && incursor) {
panel->x = MAX(0, panel->x + in->mouse_delta.x);
panel->y = MAX(0, panel->y + in->mouse_delta.y);
}
}
/* scale panel size if requested */
if (panel->flags & GUI_PANEL_SCALEABLE && !(panel->flags & GUI_PANEL_ROM)) {
gui_bool incursor;
gui_float scaler_w = MAX(0, scaler_size.x - item_padding.x);
gui_float scaler_h = MAX(0, scaler_size.y - item_padding.y);
gui_float scaler_x = (panel->x + panel->w) - (item_padding.x + scaler_w);
gui_float scaler_y = panel->y + panel->h - scaler_size.y;
gui_float prev_x = in->mouse_prev.x;
gui_float prev_y = in->mouse_prev.y;
incursor = GUI_INBOX(prev_x,prev_y,scaler_x,scaler_y,scaler_w,scaler_h);
if (in->mouse_down && incursor) {
panel->w = MAX(panel_size.x, panel->w + in->mouse_delta.x);
panel->h = MAX(panel_size.y, panel->h + in->mouse_delta.y);
}
}
/* setup panel layout */
layout->input = in;
layout->x = panel->x;
@ -3134,30 +3116,21 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel)
}
layout->flags = panel->flags;
layout->valid = !(panel->flags & GUI_PANEL_HIDDEN) && !(panel->flags & GUI_PANEL_MINIMIZED);
/* calculate the panel footer bounds */
layout->footer_h = scaler_size.y + item_padding.y;
if (!(layout->flags & GUI_PANEL_MINIMIZED)) {
gui_float footer_x, footer_y, footer_w;
footer_x = panel->x;
footer_w = panel->w;
footer_y = panel->y + panel->h - layout->footer_h;
gui_command_buffer_push_rect(out, footer_x, footer_y, footer_w, layout->footer_h,
0, c->colors[GUI_COLOR_PANEL]);
}
{
/* draw panel background */
const struct gui_color *color = &c->colors[GUI_COLOR_PANEL];
layout->width = panel->w - scrollbar_size;
layout->height = panel->h - (layout->header.h + 2 * item_spacing.y);
if (layout->flags & GUI_PANEL_SCALEABLE) layout->height -= layout->footer_h;
if (layout->valid)
gui_command_buffer_push_rect(out, layout->x, layout->y,
layout->w, layout->h, 0, *color);
}
/* calculate the panel size and panel footer height */
layout->width = panel->w - scrollbar_size;
layout->height = panel->h - (layout->header.h + 2 * item_spacing.y);
if (layout->flags & GUI_PANEL_SCALEABLE)
layout->height -= layout->footer_h;
/* draw top border line */
/* draw panel background if not a dynamic panel */
if (!(layout->flags & GUI_PANEL_DYNAMIC) && layout->valid) {
gui_command_buffer_push_rect(out, layout->x, layout->y,
layout->w, layout->h, 0, c->colors[GUI_COLOR_PANEL]);
} else layout->footer_h = scaler_size.y + item_padding.y;
/* draw top header border line */
if (layout->flags & GUI_PANEL_BORDER) {
gui_command_buffer_push_line(out, layout->x, layout->y,
layout->x + layout->w, layout->y, c->colors[GUI_COLOR_BORDER]);
@ -3253,7 +3226,6 @@ gui_panel_begin_tiled(struct gui_panel_layout *tile, struct gui_panel *panel,
scaler.h = config->scaler_width;
/* update bottom slot bounds by user input */
if (!(panel->flags & GUI_PANEL_ROM) &&
s->state != GUI_LOCKED && layout->active &&
GUI_INBOX(mpos.x, mpos.y, scaler.x, scaler.y, scaler.w, scaler.h) &&
@ -3403,11 +3375,11 @@ gui_panel_end(struct gui_panel_layout *layout, struct gui_panel *panel)
struct gui_vec2 item_spacing;
struct gui_vec2 panel_padding;
struct gui_vec2 scaler_size;
gui_float footer_x, footer_y, footer_w;
GUI_ASSERT(layout);
GUI_ASSERT(panel);
if (!panel || !layout) return;
layout->at_y += layout->row.height;
config = layout->config;
out = layout->buffer;
@ -3428,86 +3400,122 @@ gui_panel_end(struct gui_panel_layout *layout, struct gui_panel *panel)
scrollbar_size = gui_config_property(config, GUI_PROPERTY_SCROLLBAR_SIZE).x;
scaler_size = gui_config_property(config, GUI_PROPERTY_SCALER_SIZE);
/* vertical scrollbar */
/* update the current Y-position to point over the last added widget */
layout->at_y += layout->row.height;
if (layout->valid && layout->flags & GUI_PANEL_DYNAMIC) {
struct gui_rect bounds;
/* calculate the dynamic panel footer bounds */
layout->height = MIN(layout->at_y - layout->y, layout->h);
/* draw the correct footer */
footer_x = panel->x;
footer_w = panel->w;
footer_y = panel->y + layout->height + layout->footer_h;
gui_command_buffer_push_rect(out, footer_x, footer_y, footer_w, layout->footer_h,
0, config->colors[GUI_COLOR_PANEL]);
/* draw the space between the last widget and the end of the dynamic panel */
bounds.x = layout->x;
bounds.y = panel->y + layout->height;
bounds.w = layout->width;
bounds.h = layout->row.height;
gui_command_buffer_push_rect(out, bounds.x, bounds.y, bounds.w, bounds.h,
0, config->colors[GUI_COLOR_PANEL]);
}
/* scrollbars */
if (layout->valid) {
struct gui_scrollbar scroll;
gui_float scroll_x, scroll_y;
gui_float scroll_w, scroll_h;
gui_float scroll_target, scroll_offset, scroll_step;
/* calculate scollbar bounds */
scroll_x = layout->x + layout->width;
scroll_y = (layout->flags & GUI_PANEL_BORDER) ? layout->y + 1 : layout->y;
scroll_y += layout->header.h + layout->menu.h;
scroll_w = scrollbar_size;
scroll_h = layout->height;
if (layout->flags & GUI_PANEL_BORDER) scroll_h -= 1;
/* execute scrollbar widget */
scroll_offset = layout->offset.y;
scroll_step = layout->height * 0.10f;
struct gui_scrollbar scroll;
scroll.rounding = config->rounding[GUI_ROUNDING_SCROLLBAR];
scroll.background = config->colors[GUI_COLOR_SCROLLBAR];
scroll.foreground = config->colors[GUI_COLOR_SCROLLBAR_CURSOR];
scroll.border = config->colors[GUI_COLOR_SCROLLBAR_BORDER];
scroll_target = (layout->at_y-layout->y)-(layout->header.h+2*item_spacing.y);
scroll.has_scrolling = (layout->flags & GUI_PANEL_ACTIVE);
panel->offset.y = gui_scrollbar_vertical(out, scroll_x, scroll_y,
scroll_w, scroll_h, scroll_offset, scroll_target,
scroll_step, &scroll, in);
{
/* vertical scollbar */
scroll_x = layout->x + layout->width;
scroll_y = (layout->flags & GUI_PANEL_BORDER) ? layout->y + 1 : layout->y;
scroll_y += layout->header.h + layout->menu.h;
scroll_w = scrollbar_size;
scroll_h = layout->height;
if (layout->flags & GUI_PANEL_DYNAMIC) scroll_h -= scrollbar_size;
if (layout->flags & GUI_PANEL_BORDER) scroll_h -= 1;
scroll_offset = layout->offset.y;
scroll_step = layout->height * 0.10f;
scroll_target = (layout->at_y-layout->y)-(layout->header.h+2*item_spacing.y);
scroll.has_scrolling = (layout->flags & GUI_PANEL_ACTIVE);
panel->offset.y = gui_scrollbar_vertical(out, scroll_x, scroll_y,
scroll_w, scroll_h, scroll_offset, scroll_target,
scroll_step, &scroll, in);
}
{
/* horizontal scrollbar */
scroll_x = layout->x + panel_padding.x;
if (layout->flags & GUI_PANEL_TAB) {
scroll_h = scrollbar_size;
scroll_y = (layout->flags & GUI_PANEL_BORDER) ? layout->y + 1 : layout->y;
scroll_y += layout->header.h + layout->menu.h + layout->height;
scroll_w = layout->width - scrollbar_size;
} else if (layout->flags & GUI_PANEL_DYNAMIC) {
scroll_h = MIN(scrollbar_size, layout->footer_h);
scroll_w = layout->width - 2 * panel_padding.x;
scroll_y = footer_y;
} else {
scroll_h = MIN(scrollbar_size, layout->footer_h);
scroll_y = layout->y + panel->h - MAX(layout->footer_h, scrollbar_size);
scroll_w = layout->width - 2 * panel_padding.x;
}
scroll_offset = layout->offset.x;
scroll_step = layout->max_x * 0.05f;
scroll_target = (layout->max_x - layout->at_x) - 2 * panel_padding.x;
scroll.has_scrolling = gui_false;
panel->offset.x = gui_scrollbar_horizontal(out, scroll_x, scroll_y,
scroll_w, scroll_h, scroll_offset, scroll_target,
scroll_step, &scroll, in);
}
};
/* horizontal scrollbar */
if (layout->valid) {
struct gui_scrollbar scroll;
gui_float scroll_x, scroll_y;
gui_float scroll_w, scroll_h;
gui_float scroll_target, scroll_offset, scroll_step;
/* calculate scollbar bounds */
scroll_x = layout->x + panel_padding.x;
if (layout->flags & GUI_PANEL_TAB) {
scroll_h = scrollbar_size;
scroll_y = (layout->flags & GUI_PANEL_BORDER) ? layout->y + 1 : layout->y;
scroll_y += layout->header.h + layout->menu.h + layout->height;
scroll_w = layout->width - scrollbar_size;
} else {
scroll_h = MIN(scrollbar_size, layout->footer_h);
scroll_y = panel->y + panel->h - MAX(layout->footer_h, scrollbar_size);
scroll_w = layout->width - 2 * panel_padding.x;
}
/* execute scrollbar widget */
scroll_offset = layout->offset.x;
scroll_step = layout->max_x * 0.10f;
scroll.rounding = config->rounding[GUI_ROUNDING_SCROLLBAR];
scroll.background = config->colors[GUI_COLOR_SCROLLBAR];
scroll.foreground = config->colors[GUI_COLOR_SCROLLBAR_CURSOR];
scroll.border = config->colors[GUI_COLOR_SCROLLBAR_BORDER];
scroll_target = (layout->max_x - layout->at_x) - 2 * panel_padding.x;
scroll.has_scrolling = gui_false;
panel->offset.x = gui_scrollbar_horizontal(out, scroll_x, scroll_y,
scroll_w, scroll_h, scroll_offset, scroll_target,
scroll_step, &scroll, in);
} else layout->height = layout->at_y - layout->y;
/* draw the panel scaler into the right corner of the panel footer */
/* draw the panel scaler into the right corner of the panel footer and
* update panel size if user drags the scaler */
if ((layout->flags & GUI_PANEL_SCALEABLE) && layout->valid) {
gui_float scaler_y;
struct gui_color col = config->colors[GUI_COLOR_SCALER];
gui_float scaler_w = MAX(0, scaler_size.x - item_padding.x);
gui_float scaler_h = MAX(0, scaler_size.y - item_padding.y);
gui_float scaler_x = (layout->x + layout->w) - (item_padding.x + scaler_w);
gui_float scaler_y = layout->y + layout->h - scaler_size.y;
if (layout->flags & GUI_PANEL_DYNAMIC)
scaler_y = footer_y + layout->footer_h - scaler_size.y;
else scaler_y = layout->y + layout->h - scaler_size.y;
gui_command_buffer_push_triangle(out, scaler_x + scaler_w, scaler_y,
scaler_x + scaler_w, scaler_y + scaler_h, scaler_x, scaler_y + scaler_h, col);
if (!(panel->flags & GUI_PANEL_ROM)) {
gui_bool incursor;
gui_float prev_x = in->mouse_prev.x;
gui_float prev_y = in->mouse_prev.y;
struct gui_vec2 panel_size = gui_config_property(config, GUI_PROPERTY_SIZE);
incursor = GUI_INBOX(prev_x,prev_y,scaler_x,scaler_y,scaler_w,scaler_h);
if (in->mouse_down && incursor) {
panel->w = MAX(panel_size.x, panel->w + in->mouse_delta.x);
/* draging in y-direction is only possible if static panel */
if (!(layout->flags & GUI_PANEL_DYNAMIC))
panel->h = MAX(panel_size.y, panel->h + in->mouse_delta.y);
}
}
}
if (layout->flags & GUI_PANEL_BORDER) {
/* draw the border around the complete panel */
const gui_float width = layout->width + scrollbar_size;
const gui_float padding_y = (!layout->valid) ?
panel->y + layout->header.h: layout->y + layout->h;
panel->y + layout->header.h:
(layout->flags & GUI_PANEL_DYNAMIC) ?
layout->footer_h + footer_y:
layout->y + layout->h;
if (panel->flags & GUI_PANEL_BORDER_HEADER)
gui_command_buffer_push_line(out, panel->x, panel->y + layout->header.h,
@ -3564,7 +3572,9 @@ gui_panel_header_begin(struct gui_panel_layout *layout)
/* update the header height and first row height */
layout->header.h = c->font.height + 4 * item_padding.y;
layout->header.h += panel_padding.y;
layout->row.height = layout->header.h + 2 * item_spacing.y;
layout->row.height += layout->header.h;
gui_command_buffer_push_rect(out, layout->x, layout->y + layout->header.h,
layout->w, layout->row.height, 0, c->colors[GUI_COLOR_PANEL]);
/* setup header bounds and growable icon space */
layout->header.x = layout->x + panel_padding.x;
@ -3573,18 +3583,11 @@ gui_panel_header_begin(struct gui_panel_layout *layout)
layout->header.w -= 2 * panel_padding.x;
layout->header.front = layout->header.x;
layout->header.back = layout->header.x + layout->header.w;
layout->height = layout->h - (layout->header.h + 2 * item_spacing.y);
layout->height -= layout->footer_h;
gui_command_buffer_push_rect(out, layout->x, layout->y, layout->w,
layout->header.h, 0, c->colors[GUI_COLOR_HEADER]);
{
/* setup and draw panel layout footer and header background */
const struct gui_color *color = &c->colors[GUI_COLOR_PANEL];
layout->height = layout->h - (layout->header.h + 2 * item_spacing.y);
layout->height -= layout->footer_h;
if (layout->valid)
gui_command_buffer_push_rect(out, layout->x, layout->y + layout->header.h,
layout->w, layout->h - layout->header.h, 0, *color);
}
gui_command_buffer_push_rect(out, layout->x, layout->y+1, layout->w,
layout->header.h-1, 0, c->colors[GUI_COLOR_HEADER]);
}
static gui_bool
@ -3835,6 +3838,7 @@ gui_panel_header_end(struct gui_panel_layout *layout)
panel_padding = gui_config_property(c, GUI_PROPERTY_PADDING);
item_padding = gui_config_property(c, GUI_PROPERTY_ITEM_PADDING);
#if 0
{
/* draw scrollbar panel footer */
const struct gui_color *color = &c->colors[GUI_COLOR_PANEL];
@ -3842,6 +3846,7 @@ gui_panel_header_end(struct gui_panel_layout *layout)
gui_command_buffer_push_rect(out, layout->x, layout->y + layout->header.h,
layout->w, layout->h - layout->header.h, 0, *color);
}
#endif
/* draw panel header border */
if (layout->flags & GUI_PANEL_BORDER) {
@ -3955,7 +3960,7 @@ gui_panel_menu_end(struct gui_panel_layout *layout)
/*
* -------------------------------------------------------------
*
* LAYOUT
* PANEL ROW LAYOUT
*
* --------------------------------------------------------------
*/
@ -3988,8 +3993,9 @@ gui_panel_layout(struct gui_panel_layout *layout, gui_float height, gui_size col
layout->row.columns = cols;
layout->row.height = height + item_spacing.y;
layout->row.item_offset = 0;
gui_command_buffer_push_rect(out, layout->at_x, layout->at_y,
layout->width, height + panel_padding.y, 0, *color);
if (layout->flags & GUI_PANEL_DYNAMIC)
gui_command_buffer_push_rect(out, layout->at_x, layout->at_y,
layout->width, height + panel_padding.y, 0, *color);
}
static void
@ -4139,7 +4145,6 @@ gui_panel_row_space_begin(struct gui_panel_layout *layout,
layout->row.type = GUI_PANEL_LAYOUT_STATIC_FREE;
layout->row.clip = layout->clip;
layout->clip = clip;
} else layout->row.type = GUI_PANEL_LAYOUT_DYNAMIC_FREE;
layout->row.ratio = 0;
@ -4262,7 +4267,7 @@ gui_panel_alloc_space(struct gui_rect *bounds, struct gui_panel_layout *layout)
item_offset = (gui_float)layout->row.index * item_width;
item_spacing = (gui_float)layout->row.index * spacing.x;
} break;
case GUI_PANEL_LAYOUT_STATIC_ROW:{
case GUI_PANEL_LAYOUT_STATIC_ROW: {
/* scaling single ratio widget width */
item_width = layout->row.item_width;
item_offset = layout->row.item_offset;
@ -4432,7 +4437,7 @@ gui_panel_layout_pop(struct gui_panel_layout *layout)
/*
* -------------------------------------------------------------
*
* Widgets
* PANEL WIDGETS
*
* --------------------------------------------------------------
*/
@ -5165,7 +5170,6 @@ gui_panel_graph_push_column(struct gui_panel_layout *layout,
selected = (in->mouse_down && in->mouse_clicked) ? (gui_int)graph->index: selected;
color = config->colors[GUI_COLOR_HISTO_HIGHLIGHT];
}
gui_command_buffer_push_rect(out, item_x, item_y, item_w, item_h, 0, color);
graph->index++;
return selected;
@ -5575,8 +5579,8 @@ gui_panel_tree_node(struct gui_tree *tree, enum gui_tree_node_symbol symbol,
gui_command_buffer_push_circle(layout->buffer, sym.x, sym.y, sym.w, sym.h, col);
}
/* node selection */
if (!(layout->flags & GUI_PANEL_ROM)) {
/* node selection */
if (gui_input_clicked(i, &label)) {
if (*state & GUI_NODE_SELECTED)
*state &= ~(gui_flags)GUI_NODE_SELECTED;

374
gui.h
View File

@ -68,7 +68,7 @@ typedef long gui_long;
typedef float gui_float;
typedef double gui_double;
typedef unsigned short gui_ushort;
ypedef unsigned int gui_uint;
typedef unsigned int gui_uint;
typedef unsigned long gui_ulong;
typedef unsigned int gui_flags;
typedef unsigned char gui_byte;
@ -1777,6 +1777,10 @@ enum gui_panel_flags {
/* marks the panel as minimized */
GUI_PANEL_ROM = 0x40,
/* sets the panel in to a read only mode and does not allow input changes */
GUI_PANEL_DYNAMIC = 0x80,
/* special type of panel which grows up in height while being filled to a
* certain maximum height. It is mainly used for combo boxes but can be
* used to create perfectly content fitting panels as well */
GUI_PANEL_ACTIVE = 0x10000,
/* INTERNAL ONLY!: marks the panel as active, used by the panel stack */
GUI_PANEL_TAB = 0x20000
@ -2006,9 +2010,9 @@ void gui_panel_end(struct gui_panel_layout*, struct gui_panel*);
The layout supported is hereby limited and custom button and icons cannot be
added. To achieve that you have to use the more extensive header API.
You start by calling `gui_panel_header_begin` after `gui_panel_begin` and
call the different `gui_panel_header_xxx` function to add icons or the title
either at the left or right side of the panel. Each function return if the
icon or button has been pressed or in the base of the toggle the current state.
call the different `gui_panel_header_xxx` functions to add icons or the title
either at the left or right side of the panel. Each function returns if the
icon or button has been pressed or in the case of the toggle the current state.
Finally if all button/icons/toggles have been added the process is finished
by calling `gui_panel_header_end`.
@ -2267,10 +2271,6 @@ void gui_panel_layout_pop(struct gui_panel_layout*);
gui_panel_text_colored -- colored text widget for printing colored text width length
gui_panel_label -- text widget for printing zero terminated strings
gui_panel_label_colored -- text widget for printing colored zero terminiated strings
gui_panle_image -- image widget for outputing a image to a panel
gui_panel_check -- add a checkbox widget with either active or inactive state
gui_panel_option -- radiobutton widget with either active or inactive state
gui_panel_option_group -- radiobutton group for automatic single selection
gui_panel_button_text -- button widget with text content
gui_panel_button_color -- colored button widget without content
gui_panel_button_triangle -- button with triangle pointing either up-/down-/left- or right
@ -2278,6 +2278,10 @@ void gui_panel_layout_pop(struct gui_panel_layout*);
gui_panel_button_toggle -- toggle button with either active or inactive state
gui_panel_button_text_image -- button widget with text and icon
gui_panel_button_text_triangle -- button widget with text and a triangle
gui_panle_image -- image widget for outputing a image to a panel
gui_panel_check -- add a checkbox widget with either active or inactive state
gui_panel_option -- radiobutton widget with either active or inactive state
gui_panel_option_group -- radiobutton group for automatic single selection
gui_panel_slider -- slider widget with min,max,step value
gui_panel_progress -- progressbar widget
gui_panel_edit -- edit textbox widget for text input
@ -2514,67 +2518,114 @@ gui_size gui_panel_selector(struct gui_panel_layout*, const char *items[],
*/
/*
* -------------------------------------------------------------
* COMPLEX
* GROUP
* --------------------------------------------------------------
COMPLEX
The complex widget API in contrast with the normal widget API implements
widgets that either need additional stack alloacted temporary object to build
up like in the case of the graph and tree widget implementation or require
a certain panel state to work like in the case of the table.
*
GROUP
USAGE
First in the case of the graph there are three different ways to create a
graph widget. The first one is on immediate mode fashion with `xxx_begin`,
`xxx_end` and `gui_panel_graph_push` for every value. This makes it more easy
to add data from static like sources like an array of object. Then there
is a retain mode version which uses an array of float values to draw the graph.
Finally there is a callback based solution which is mainly meant for math-like
graph generation over a math function (e.g: sin,cos,...).
The tree widget is standart immediate mode API and divides tree nodes into
parent nodes and leafes. Nodes have immediate mode function points, while
leafes are just normal functions. In addition there is a icon version for each
of the two node types which allows you to add images into a tree node.
The tree widget supports in contrast to the tree layout a back channel
for each node and leaf. This allows to return commands back to the user
to declare what to do with the tree node. This includes cloning which is
copying the selected node and pasting it in the same parent node, cuting
which removes nodes from its parents and copyies it into a paste buffer,
pasting to take all nodes inside the paste buffer and copy it into a node and
finally removing a tree node.
Finally the table API which is rather limited at the moment and needs/will
be rewritten to support scaling table and columns bounds. At the moment a table
is nothing more than a fixed table layout with lines between each widget.
Complex widget Panel API
gui_panel_graph_begin -- immediate mode graph building begin sequence point
gui_panel_graph_push -- push a value into a graph
gui_panel_graph_end -- immediate mode graph building end sequence point
gui_panel_graph -- retained mode graph with array of values
gui_panel_graph_ex -- ratained mode graph with getter callback
gui_panel_table_begin -- begin table build up process
gui_panel_table_row -- seperates tables rows
gui_panel_table_end -- ends the table build up process
gui_panel_tree_begin -- begins the tree build up processs
gui_panel_tree_begin_node -- adds and opens a normal node to the tree
gui_panel_tree_begin_node_icon -- adds a opens a node with an icon to the tree
gui_panel_tree_end_node -- ends and closes a previously added node
gui_panel_tree_leaf -- adds a leaf node to a prev opened node
gui_panel_tree_leaf_icon -- adds a leaf icon node to a prev opended node
gui_panel_tree_end -- ends the tree build up process
Panel group API
gui_panel_group_begin -- adds a scrollable fixed space inside the panel
gui_panel_group_end -- ends the scrollable space
*/
enum gui_table_lines {
GUI_TABLE_HHEADER = 0x01,
/* Horizontal table header lines */
GUI_TABLE_VHEADER = 0x02,
/* Vertical table header lines */
GUI_TABLE_HBODY = 0x04,
/* Horizontal table body lines */
GUI_TABLE_VBODY = 0x08
/* Vertical table body lines */
};
void gui_panel_group_begin(struct gui_panel_layout*, struct gui_panel_layout *tab,
const char *title, struct gui_vec2 offset);
/* this function adds a grouped subpanel into the parent panel
IMPORTANT: You need to set the height of the group with panel_row_layout
Input:
- group title to write into the header
- group scrollbar offset
Output:
- group layout to fill with widgets
*/
struct gui_vec2 gui_panel_group_end(struct gui_panel_layout*, struct gui_panel_layout* tab);
/* this function finishes the previously started group layout
Output:
- The from user input updated group scrollbar pixel offset
*/
/*
* -------------------------------------------------------------
* POPUP
* --------------------------------------------------------------
*
GROUP
USAGE
Panel popup API
gui_panel_shelf_begin -- begins a shelf with a number of selectable tabs
gui_panel_shelf_end -- ends a previously started shelf build up process
*/
gui_flags gui_panel_popup_begin(struct gui_panel_layout *parent, struct gui_panel_layout *popup,
struct gui_rect bounds, struct gui_vec2 scrollbar);
/* this function adds a grouped subpanel into the parent panel
Input:
- popup position and size of the popup (NOTE: local position)
- scrollbar pixel offsets for the popup
Output:
- popup layout to fill with widgets
*/
void gui_panel_popup_close(struct gui_panel_layout *popup);
/* this functions closes a previously opened popup */
struct gui_vec2 gui_panel_popup_end(struct gui_panel_layout *parent,
struct gui_panel_layout *popup);
/* this function finishes the previously started popup layout
Output:
- The from user input updated popup scrollbar pixel offset
*/
/*
* -------------------------------------------------------------
* SHELF
* --------------------------------------------------------------
*
SHELF
USAGE
Panel shelf API
gui_panel_popup_begin -- adds a popup inside a panel
gui_panel_popup_end -- ends the popup building process
*/
gui_size gui_panel_shelf_begin(struct gui_panel_layout*, struct gui_panel_layout*,
const char *tabs[], gui_size size,
gui_size active, struct gui_vec2 offset);
/* this function adds a shelf subpanel into the parent panel
IMPORTANT: You need to set the height of the shelf with panel_row_layout
Input:
- all possible selectible tabs of the shelf with names as a string array
- number of seletectible tabs
- current active tab array index
- scrollbar pixel offset for the shelf
Output:
- group layout to fill with widgets
- the from user input updated current shelf tab index
*/
struct gui_vec2 gui_panel_shelf_end(struct gui_panel_layout*, struct gui_panel_layout*);
/* this function finishes the previously started shelf layout
Input:
- previously started group layout
Output:
- The from user input updated shelf scrollbar pixel offset
*/
/*
* -------------------------------------------------------------
* GRAPH
* --------------------------------------------------------------
GRAPH
USAGE
graph widget API
gui_panel_graph_begin -- immediate mode graph building begin sequence point
gui_panel_graph_push -- push a value into a graph
gui_panel_graph_end -- immediate mode graph building end sequence point
gui_panel_graph -- retained mode graph with array of values
gui_panel_graph_ex -- ratained mode graph with getter callback
*/
enum gui_graph_type {
GUI_GRAPH_LINES,
/* Line graph with each data point being connected with its previous and next node */
@ -2602,38 +2653,6 @@ struct gui_graph {
/* number of values inside the graph */
};
typedef gui_flags gui_tree_node_state;
enum gui_tree_nodes_states {
GUI_NODE_ACTIVE = 0x01,
/* the node is currently opened */
GUI_NODE_SELECTED = 0x02
/* the node has been seleted by the user */
};
enum gui_tree_node_operation {
GUI_NODE_NOP,
/* node did not receive a command */
GUI_NODE_CUT,
/* cut the node from the current tree and add into a buffer */
GUI_NODE_CLONE,
/* copy current node and add copy into the parent node */
GUI_NODE_PASTE,
/* paste all node in the buffer into the tree */
GUI_NODE_DELETE
/* remove the node from the parent tree */
};
struct gui_tree {
struct gui_panel_layout group;
/* panel to add the tree into */
gui_float x_off, at_x;
/* current x position of the next node */
gui_int skip;
/* flag that indicates that a node will be skipped */
gui_int depth;
/* current depth of the tree */
};
void gui_panel_graph_begin(struct gui_panel_layout*, struct gui_graph*,
enum gui_graph_type, gui_size count,
gui_float min, gui_float max);
@ -2673,22 +2692,55 @@ gui_int gui_panel_graph_callback(struct gui_panel_layout*, enum gui_graph_type,
- callback to access the values inside your datastrucutre
- userdata to pull the graph values from
*/
void gui_panel_table_begin(struct gui_panel_layout*, gui_flags flags,
gui_size row_height, gui_size cols);
/* this function set the panel to a table state which enable you to create a
table with the standart panel row layout
Input:
- table row and column line seperator flags
- height of each table row
- number of columns inside the table
*/
void gui_panel_table_row(struct gui_panel_layout*);
/* this function add a row with line seperator into asa table marked table
*/
void gui_panel_table_end(struct gui_panel_layout*);
/* this function finished the table build up process and reverts the panel back
to its normal state.
/*
* -------------------------------------------------------------
* TREE
* --------------------------------------------------------------
TREE
USAGE
tree widget API
gui_panel_tree_begin -- begins the tree build up processs
gui_panel_tree_begin_node -- adds and opens a normal node to the tree
gui_panel_tree_begin_node_icon -- adds a opens a node with an icon to the tree
gui_panel_tree_end_node -- ends and closes a previously added node
gui_panel_tree_leaf -- adds a leaf node to a prev opened node
gui_panel_tree_leaf_icon -- adds a leaf icon node to a prev opended node
gui_panel_tree_end -- ends the tree build up process
*/
typedef gui_flags gui_tree_node_state;
enum gui_tree_nodes_states {
GUI_NODE_ACTIVE = 0x01,
/* the node is currently opened */
GUI_NODE_SELECTED = 0x02
/* the node has been seleted by the user */
};
enum gui_tree_node_operation {
GUI_NODE_NOP,
/* node did not receive a command */
GUI_NODE_CUT,
/* cut the node from the current tree and add into a buffer */
GUI_NODE_CLONE,
/* copy current node and add copy into the parent node */
GUI_NODE_PASTE,
/* paste all node in the buffer into the tree */
GUI_NODE_DELETE
/* remove the node from the parent tree */
};
struct gui_tree {
struct gui_panel_layout group;
/* panel to add the tree into */
gui_float x_off, at_x;
/* current x position of the next node */
gui_int skip;
/* flag that indicates that a node will be skipped */
gui_int depth;
/* current depth of the tree */
};
void gui_panel_tree_begin(struct gui_panel_layout*, struct gui_tree*,
const char*, gui_float row_height, struct gui_vec2 offset);
/* this function begins the tree building process
@ -2745,85 +2797,43 @@ struct gui_vec2 gui_panel_tree_end(struct gui_panel_layout*, struct gui_tree*);
/* this function ends a the tree building process */
/*
* -------------------------------------------------------------
* GROUP
* TABLE
* --------------------------------------------------------------
*
GROUP
The group API is based on grouping of widget inside a panel. This in term
means a scaleable space inside a panel which can be filled widgets. There are
two different types of scaleable spaces the first a groups with normal
filling behavior and the other is a shelf with different content depending
on the selected tab inside the shelf.
TABLE
USAGE
For grouping you need a additional panel layout for the group/shelf to work.
With it the scrollbar offsets of the panel layout need to be managed by the
user, since the panel does not store any state. The group panel layout is
created by the `gui_panel_group_begin` and `gui_panel_shelf_begin` calls.
After their creaton widget can be added the the group/shelf by just using the
new panel layout. In case of the shelf the `gui_panel_shelf_begin` call returns
a index as well indiciation which tab needs to filled inside the group.
Panel group API
gui_panel_popup_begin -- adds a popup inside a panel
gui_panel_popup_end -- ends the popup building process
gui_panel_group_begin -- adds a scrollable fixed space inside the panel
gui_panel_group_end -- ends the scrollable space
gui_panel_shelf_begin -- begins a shelf with a number of selectable tabs
gui_panel_shelf_end -- ends a previously started shelf build up process
Table widget API
gui_panel_table_begin -- begin table build up process
gui_panel_table_row -- seperates tables rows
gui_panel_table_end -- ends the table build up process
*/
gui_flags gui_panel_popup_begin(struct gui_panel_layout *parent, struct gui_panel_layout *popup,
struct gui_rect bounds, struct gui_vec2 scrollbar);
/* this function adds a grouped subpanel into the parent panel
enum gui_table_lines {
GUI_TABLE_HHEADER = 0x01,
/* Horizontal table header lines */
GUI_TABLE_VHEADER = 0x02,
/* Vertical table header lines */
GUI_TABLE_HBODY = 0x04,
/* Horizontal table body lines */
GUI_TABLE_VBODY = 0x08
/* Vertical table body lines */
};
void gui_panel_table_begin(struct gui_panel_layout*, gui_flags flags,
gui_size row_height, gui_size cols);
/* this function set the panel to a table state which enable you to create a
table with the standart panel row layout
Input:
- popup position and size of the popup (NOTE: local position)
- scrollbar pixel offsets for the popup
Output:
- popup layout to fill with widgets
- table row and column line seperator flags
- height of each table row
- number of columns inside the table
*/
void gui_panel_popup_close(struct gui_panel_layout *popup);
/* this functions closes a previously opened popup */
struct gui_vec2 gui_panel_popup_end(struct gui_panel_layout *parent,
struct gui_panel_layout *popup);
/* this function finishes the previously started popup layout
Output:
- The from user input updated popup scrollbar pixel offset
void gui_panel_table_row(struct gui_panel_layout*);
/* this function add a row with line seperator into asa table marked table
*/
void gui_panel_group_begin(struct gui_panel_layout*, struct gui_panel_layout *tab,
const char *title, struct gui_vec2 offset);
/* this function adds a grouped subpanel into the parent panel
IMPORTANT: You need to set the height of the group with panel_row_layout
Input:
- group title to write into the header
- group scrollbar offset
Output:
- group layout to fill with widgets
*/
struct gui_vec2 gui_panel_group_end(struct gui_panel_layout*, struct gui_panel_layout* tab);
/* this function finishes the previously started group layout
Output:
- The from user input updated group scrollbar pixel offset
*/
gui_size gui_panel_shelf_begin(struct gui_panel_layout*, struct gui_panel_layout*,
const char *tabs[], gui_size size,
gui_size active, struct gui_vec2 offset);
/* this function adds a shelf subpanel into the parent panel
IMPORTANT: You need to set the height of the shelf with panel_row_layout
Input:
- all possible selectible tabs of the shelf with names as a string array
- number of seletectible tabs
- current active tab array index
- scrollbar pixel offset for the shelf
Output:
- group layout to fill with widgets
- the from user input updated current shelf tab index
*/
struct gui_vec2 gui_panel_shelf_end(struct gui_panel_layout*, struct gui_panel_layout*);
/* this function finishes the previously started shelf layout
Input:
- previously started group layout
Output:
- The from user input updated shelf scrollbar pixel offset
void gui_panel_table_end(struct gui_panel_layout*);
/* this function finished the table build up process and reverts the panel back
to its normal state.
*/
/*
* ==============================================================
@ -2834,7 +2844,7 @@ struct gui_vec2 gui_panel_shelf_end(struct gui_panel_layout*, struct gui_panel_l
*/
/* LAYOUT
----------------------------
The tiled layout provides a way to divide the os window into slots which
The tiled layout provides a way to divide the screen into slots which
again can be divided into either horizontal or vertical panels or another
tiled layout. This is especially usefull for more complex application which
need more than just fixed or overlapping panels. There are five slots