added tiled layout for widget and windows

This commit is contained in:
vurtun 2015-09-09 13:54:20 +02:00
parent 8a7f19fef3
commit fc8969dfd5
4 changed files with 475 additions and 51 deletions

View File

@ -14,7 +14,7 @@ application and does not have any direct dependencies.
- No direct dependencies (not even libc!)
- Configurable style and colors
- UTF-8 support
- Optional vertex output
- Optional vertex buffer output
## Gallery
![gui demo](/screen/demo.png?raw=true)
@ -23,11 +23,6 @@ application and does not have any direct dependencies.
## Example
```c
/* allocate memory to hold the draw commands */
struct gui_command_queue queue;
void *memory = malloc(MEMORY_SIZE);
gui_command_queue_init_fixed(&queue, memory, MEMORY_SIZE);
/* setup configuration */
struct gui_font font;
struct gui_style style;
@ -36,6 +31,11 @@ font.height = your_font_data.height;
font.width = your_font_string_width_callback_function;
gui_style_default(&style, GUI_DEFAULT_ALL, &font);
/* allocate memory to hold draw commands */
struct gui_command_queue queue;
void *memory = malloc(MEMORY_SIZE);
gui_command_queue_init_fixed(&queue, memory, MEMORY_SIZE);
/* initialize panel */
struct gui_window panel;
gui_window_init(&panel, 50, 50, 220, 180,

View File

@ -289,10 +289,11 @@ color_picker(struct gui_context *panel, struct color_picker* control,
iter = &control->color.r;
gui_layout_row_dynamic(&popup, 30, 2);
for (i = 0; i < 4; ++i, iter++) {
gui_float t = *iter;
gui_float t;
*iter = (gui_byte)gui_spinner(&popup, 0, *iter, 255, 1, NULL);
t = *iter;
t = gui_slider(&popup, 0, t, 255, 10);
*iter = (gui_byte)t;
*iter = (gui_byte)gui_spinner(&popup, 0, *iter, 255, 1, NULL);
}
gui_layout_row_dynamic(&popup, 30, 3);
@ -444,6 +445,7 @@ struct state {
struct test_tree test;
/* widgets state */
gui_bool list[4];
gui_size prog_values[4];
gui_bool check_values[WEAPON_MAX];
gui_bool scaleable;
@ -528,7 +530,7 @@ widget_panel(struct gui_context *panel, struct state *demo)
/* custom row layout by array */
const gui_float ratio[] = {0.8f, 0.2f};
const gui_float pixel[] = {150.0f, 30.0f};
enum gui_row_layout_format fmt = (demo->scaleable) ? GUI_DYNAMIC : GUI_STATIC;
enum gui_layout_format fmt = (demo->scaleable) ? GUI_DYNAMIC : GUI_STATIC;
gui_layout_row(panel, fmt, 30, 2, (fmt == GUI_DYNAMIC) ? ratio: pixel);
demo->slider = gui_slider(panel, 0, demo->slider, 10, 1.0f);
gui_labelf(panel, GUI_TEXT_LEFT, "%.2f", demo->slider);
@ -536,8 +538,41 @@ widget_panel(struct gui_context *panel, struct state *demo)
gui_labelf(panel, GUI_TEXT_LEFT, "%lu", demo->progressbar);
}
{
/* tiled widgets layout */
gui_uint i = 0;
struct gui_tiled_layout tiled;
const char *items[] = {"item0", "item1", "item2", "item3"};
enum gui_layout_format fmt = (demo->scaleable) ? GUI_DYNAMIC : GUI_STATIC;
/* setup tiled layout */
gui_tiled_begin(&tiled, fmt, 300, 150);
if (!demo->scaleable) {
gui_tiled_slot(&tiled, GUI_SLOT_LEFT, 150, GUI_SLOT_VERTICAL, 4);
gui_tiled_slot(&tiled, GUI_SLOT_RIGHT, 150, GUI_SLOT_VERTICAL, 4);
} else {
gui_tiled_slot(&tiled, GUI_SLOT_LEFT, 0.50, GUI_SLOT_VERTICAL, 4);
gui_tiled_slot(&tiled, GUI_SLOT_RIGHT, 0.50, GUI_SLOT_VERTICAL, 4);
}
gui_tiled_end(&tiled);
/* setup widgets with tiled layout */
gui_layout_row_tiled_begin(panel, &tiled);
{
for (i = 0; i < 4; ++i) {
gui_layout_row_tiled_push(panel, GUI_SLOT_LEFT, i);
demo->list[i] = gui_button_toggle(panel, items[i], demo->list[i]);
}
gui_layout_row_tiled_push(panel, GUI_SLOT_RIGHT, 1);
gui_label(panel, "Test0", GUI_TEXT_CENTERED);
gui_layout_row_tiled_push(panel, GUI_SLOT_RIGHT, 2);
gui_label(panel, "Test1", GUI_TEXT_CENTERED);
}
gui_layout_row_tiled_end(panel);
}
/* item selection */
if (!demo->scaleable) gui_layout_row_static(panel, 30, 150, 1);
if (!demo->scaleable) gui_layout_row_static(panel, 30, 30, 1);
else gui_layout_row_dynamic(panel, 30, 1);
demo->spinner = gui_spinner(panel, 0, demo->spinner, 250, 10, &demo->spinner_active);
@ -551,7 +586,7 @@ widget_panel(struct gui_context *panel, struct state *demo)
{
/* immediate mode custom row layout */
enum gui_row_layout_format fmt = (demo->scaleable) ? GUI_DYNAMIC : GUI_STATIC;
enum gui_layout_format fmt = (demo->scaleable) ? GUI_DYNAMIC : GUI_STATIC;
gui_layout_row_begin(panel, fmt, 30, 2);
{
gui_layout_row_push(panel,(fmt == GUI_DYNAMIC) ? 0.7f : 100);
@ -705,6 +740,7 @@ init_demo(struct demo_gui *gui)
win->slider = 2.0f;
win->progressbar = 50;
win->spinner = 100;
}
/* -----------------------------------------------------------------

280
gui.c
View File

@ -3826,7 +3826,6 @@ gui_widget_spinner_base(struct gui_command_buffer *out, struct gui_rect r,
bounds.h = r.h / 2;
bounds.w = r.h - s->padding.x;
bounds.x = r.x + r.w - bounds.w;
button_up_clicked = gui_widget_button_symbol(out, bounds, GUI_SYMBOL_TRIANGLE_UP,
GUI_BUTTON_DEFAULT, &s->button, in, font);
if (button_up_clicked) ret = 1;
@ -4089,7 +4088,124 @@ gui_style_reset(struct gui_style *style)
gui_style_reset_colors(style);
gui_style_reset_properties(style);
}
/*
* ==============================================================
*
* Tiling
*
* ===============================================================
*/
void
gui_tiled_begin(struct gui_tiled_layout *layout, enum gui_layout_format fmt,
gui_float width, gui_float height)
{
GUI_ASSERT(layout);
if (!layout) return;
gui_zero(layout->slots, sizeof(layout->slots));
layout->fmt = fmt;
layout->width = width;
layout->height = height;
}
void
gui_tiled_slot(struct gui_tiled_layout *layout,
enum gui_tiled_layout_slot_index slot, gui_float ratio,
enum gui_tiled_slot_format fmt, gui_uint widget_count)
{
GUI_ASSERT(layout);
if (!layout) return;
layout->slots[slot].capacity = widget_count;
layout->slots[slot].format = fmt;
layout->slots[slot].value = ratio;
}
void
gui_tiled_slot_bounds(struct gui_rect *bounds,
const struct gui_tiled_layout *layout, enum gui_tiled_layout_slot_index slot)
{
gui_float width, height;
const struct gui_tiled_slot *s;
GUI_ASSERT(layout);
if (!layout) return;
s = &layout->slots[slot];
if (layout->fmt == GUI_DYNAMIC) {
bounds->x = s->pos.x * (gui_float)layout->width;
bounds->y = s->pos.y * (gui_float)layout->height;
bounds->w = s->size.x * (gui_float)layout->width;
bounds->h = s->size.y * (gui_float)layout->height;
} else {
bounds->x = s->pos.x;
bounds->y = s->pos.y;
bounds->w = s->size.x;
bounds->h = s->size.y;
}
}
void
gui_tiled_bounds(struct gui_rect *bounds, const struct gui_tiled_layout *layout,
enum gui_tiled_layout_slot_index slot, gui_uint index)
{
struct gui_rect slot_bounds;
const struct gui_tiled_slot *s;
GUI_ASSERT(layout);
if (!layout) return;
GUI_ASSERT(slot < GUI_SLOT_MAX);
s = &layout->slots[slot];
GUI_ASSERT(index < s->capacity);
gui_tiled_slot_bounds(&slot_bounds, layout, slot);
if (s->format == GUI_SLOT_HORIZONTAL) {
bounds->h = slot_bounds.h;
bounds->y = slot_bounds.y;
bounds->w = slot_bounds.w / (gui_float)s->capacity;
bounds->x = slot_bounds.x + (gui_float)index * bounds->w;
} else {
bounds->x = slot_bounds.x;
bounds->w = slot_bounds.w;
bounds->h = slot_bounds.h/(gui_float)s->capacity;
bounds->y = slot_bounds.y + (gui_float)index * bounds->h;
}
}
void
gui_tiled_end(struct gui_tiled_layout *layout)
{
gui_float w;
gui_float centerh, centerv;
const struct gui_tiled_slot *top, *bottom;
const struct gui_tiled_slot *left, *right;
GUI_ASSERT(layout);
if (!layout) return;
top = &layout->slots[GUI_SLOT_TOP];
bottom = &layout->slots[GUI_SLOT_BOTTOM];
left = &layout->slots[GUI_SLOT_LEFT];
right = &layout->slots[GUI_SLOT_RIGHT];
if (layout->fmt == GUI_DYNAMIC) {
layout->width = 1.0f;
centerh = MAX(0.0f, 1.0f - (left->value + right->value));
centerv = MAX(0.0f, 1.0f - (top->value + bottom->value));
} else {
centerh = MAX(0.0f, layout->width - (left->value + right->value));
centerv = MAX(0.0f, layout->height - (top->value + bottom->value));
}
/* calculate the slot size */
layout->slots[GUI_SLOT_CENTER].size = gui_vec2(centerh, centerv);
layout->slots[GUI_SLOT_TOP].size = gui_vec2(layout->width, top->value);
layout->slots[GUI_SLOT_LEFT].size = gui_vec2(left->value, centerv);
layout->slots[GUI_SLOT_BOTTOM].size = gui_vec2(layout->width, bottom->value);
layout->slots[GUI_SLOT_RIGHT].size = gui_vec2(right->value, centerv);
/* calculate the slot window position */
layout->slots[GUI_SLOT_TOP].pos = gui_vec2(0.0f, 0.0f);
layout->slots[GUI_SLOT_LEFT].pos = gui_vec2(0.0f, top->value);
layout->slots[GUI_SLOT_BOTTOM].pos = gui_vec2(0.0f, top->value + centerv);
layout->slots[GUI_SLOT_RIGHT].pos = gui_vec2(left->value + centerh, top->value);
layout->slots[GUI_SLOT_CENTER].pos = gui_vec2(left->value, top->value);
}
/*
* ==============================================================
*
@ -4222,7 +4338,7 @@ gui_window_is_minimized(struct gui_window *panel)
/*
* ==============================================================
*
* Window
* Context
*
* ===============================================================
*/
@ -4381,6 +4497,31 @@ gui_begin(struct gui_context *context, struct gui_window *window)
gui_command_buffer_push_scissor(out, context->clip);
}
void
gui_begin_tiled(struct gui_context *context, struct gui_window *window,
struct gui_tiled_layout *tiled, enum gui_tiled_layout_slot_index slot,
gui_uint index)
{
struct gui_command_queue *queue;
GUI_ASSERT(context);
GUI_ASSERT(window);
GUI_ASSERT(tiled);
GUI_ASSERT(slot < GUI_SLOT_MAX);
GUI_ASSERT(index < tiled->slots[slot].capacity);
if (!context || !window || !tiled) return;
/* make sure that correct flags are set */
window->flags &= (gui_flags)~GUI_WINDOW_MOVEABLE;
window->flags &= (gui_flags)~GUI_WINDOW_SCALEABLE;
window->flags &= (gui_flags)~GUI_WINDOW_DYNAMIC;
/* place window inside layout and set window to background */
gui_tiled_bounds(&window->bounds, tiled, slot, index);
gui_begin(context, window);
gui_command_queue_remove(window->queue, &window->buffer);
gui_command_queue_insert_front(window->queue, &window->buffer);
}
void
gui_end(struct gui_context *layout, struct gui_window *window)
{
@ -4740,10 +4881,10 @@ gui_header_button(struct gui_context *layout,
/* check if the icon has been pressed */
if (!(layout->flags & GUI_WINDOW_ROM)) {
gui_float clicked_x = layout->input->mouse.buttons[GUI_BUTTON_LEFT].clicked_pos.x;
gui_float clicked_y = layout->input->mouse.buttons[GUI_BUTTON_LEFT].clicked_pos.y;
gui_float mouse_x = layout->input->mouse.pos.x;
gui_float mouse_y = layout->input->mouse.pos.y;
gui_float clicked_x = layout->input->mouse.buttons[GUI_BUTTON_LEFT].clicked_pos.x;
gui_float clicked_y = layout->input->mouse.buttons[GUI_BUTTON_LEFT].clicked_pos.y;
if (GUI_INBOX(mouse_x, mouse_y, sym.x, sym.y, sym_bw, sym.h)) {
if (GUI_INBOX(clicked_x, clicked_y, sym.x, sym.y, sym_bw, sym.h))
ret = (layout->input->mouse.buttons[GUI_BUTTON_LEFT].down &&
@ -4883,7 +5024,6 @@ gui_header(struct gui_context *layout, const char *title,
{
gui_flags ret = 0;
gui_flags old = layout->flags;
GUI_ASSERT(layout);
if (!layout || layout->flags & GUI_WINDOW_HIDDEN)
return gui_false;
@ -4957,7 +5097,6 @@ gui_menubar_end(struct gui_context *layout)
layout->clip.h -= (panel_padding.y + item_padding.y);
gui_command_buffer_push_scissor(out, layout->clip);
}
/*
* -------------------------------------------------------------
*
@ -5001,7 +5140,7 @@ gui_panel_layout(struct gui_context *layout, gui_float height, gui_size cols)
static void
gui_row_layout(struct gui_context *layout,
enum gui_row_layout_format fmt, gui_float height, gui_size cols,
enum gui_layout_format fmt, gui_float height, gui_size cols,
gui_size width)
{
GUI_ASSERT(layout);
@ -5034,7 +5173,7 @@ gui_layout_row_static(struct gui_context *layout, gui_float height,
void
gui_layout_row_begin(struct gui_context *layout,
enum gui_row_layout_format fmt, gui_float row_height, gui_size cols)
enum gui_layout_format fmt, gui_float row_height, gui_size cols)
{
GUI_ASSERT(layout);
GUI_ASSERT(layout->style);
@ -5082,7 +5221,7 @@ gui_layout_row_end(struct gui_context *layout)
}
void
gui_layout_row(struct gui_context *layout, enum gui_row_layout_format fmt,
gui_layout_row(struct gui_context *layout, enum gui_layout_format fmt,
gui_float height, gui_size cols, const gui_float *ratio)
{
gui_size i;
@ -5121,7 +5260,7 @@ gui_layout_row(struct gui_context *layout, enum gui_row_layout_format fmt,
void
gui_layout_row_space_begin(struct gui_context *layout,
enum gui_row_layout_format fmt, gui_float height, gui_size widget_count)
enum gui_layout_format fmt, gui_float height, gui_size widget_count)
{
GUI_ASSERT(layout);
GUI_ASSERT(layout->style);
@ -5223,10 +5362,107 @@ gui_layout_row_space_end(struct gui_context *layout)
layout->row.item_width = 0;
layout->row.item_height = 0;
layout->row.item_offset = 0;
gui_zero(&layout->row.item, sizeof(layout->row.item));
if (layout->row.type == GUI_LAYOUT_STATIC_FREE)
gui_command_buffer_push_scissor(layout->buffer, layout->clip);
}
void
gui_layout_row_tiled_begin(struct gui_context *layout,
struct gui_tiled_layout *tiled)
{
GUI_ASSERT(layout);
if (!layout) return;
if (!layout->valid) return;
layout->row.tiled = tiled;
gui_panel_layout(layout, (gui_size)tiled->height, 2);
if (tiled->fmt == GUI_STATIC) {
/* calculate bounds of the tiled layout */
struct gui_rect clip, space;
space.x = layout->at_x;
space.y = layout->at_y;
space.w = layout->width;
space.h = layout->row.height;
/* setup clipping rect for the free space to prevent overdraw */
gui_unify(&clip, &layout->clip, space.x, space.y, space.x + space.w, space.y + space.h);
gui_command_buffer_push_scissor(layout->buffer, clip);
layout->row.clip = layout->clip;
layout->clip = clip;
layout->row.type = GUI_LAYOUT_STATIC_TILED;
} else layout->row.type = GUI_LAYOUT_DYNAMIC_TILED;
layout->row.ratio = 0;
layout->row.item_width = 0;
layout->row.item_offset = 0;
layout->row.filled = 0;
}
void
gui_layout_row_tiled_push(struct gui_context *layout,
enum gui_tiled_layout_slot_index slot, gui_uint index)
{
struct gui_rect slot_bounds;
const struct gui_tiled_slot *s;
struct gui_vec2 spacing;
const struct gui_style *config;
struct gui_tiled_layout *tiled;
GUI_ASSERT(layout);
GUI_ASSERT(layout->style);
GUI_ASSERT(layout->buffer);
GUI_ASSERT(layout->row.tiled);
if (!layout) return;
if (!layout->valid) return;
GUI_ASSERT(layout);
if (!layout) return;
tiled = layout->row.tiled;
s = &tiled->slots[slot];
GUI_ASSERT(index < s->capacity);
if (tiled->fmt == GUI_DYNAMIC)
tiled->width = layout->width;
gui_tiled_slot_bounds(&slot_bounds, tiled, slot);
config = layout->style;
spacing = config->properties[GUI_PROPERTY_ITEM_SPACING];
if (s->format == GUI_SLOT_HORIZONTAL) {
slot_bounds.h -= (2 * spacing.y);
slot_bounds.w -= s->capacity * spacing.x;
layout->row.item.h = slot_bounds.h;
layout->row.item.y = slot_bounds.y;
layout->row.item.w = slot_bounds.w / (gui_float)s->capacity;
layout->row.item.x = slot_bounds.x + (gui_float)index * layout->row.item.w;
} else {
layout->row.item.x = slot_bounds.x + spacing.x;
layout->row.item.w = slot_bounds.w - (2 * spacing.x);
layout->row.item.h = (slot_bounds.h - s->capacity * spacing.y)/(gui_float)s->capacity;
layout->row.item.y = slot_bounds.y + (gui_float)index * layout->row.item.h;
layout->row.item.y += (index * spacing.y);
}
}
void
gui_layout_row_tiled_end(struct gui_context *layout)
{
GUI_ASSERT(layout);
GUI_ASSERT(layout->style);
if (!layout) return;
if (!layout->valid) return;
layout->row.item_width = 0;
layout->row.item_height = 0;
layout->row.item_offset = 0;
gui_zero(&layout->row.item, sizeof(layout->row.item));
if (layout->row.tiled->fmt == GUI_STATIC)
gui_command_buffer_push_scissor(layout->buffer, layout->clip);
layout->row.tiled = 0;
}
static void
gui_panel_alloc_row(struct gui_context *layout)
{
@ -5283,8 +5519,21 @@ gui_panel_alloc_space(struct gui_rect *bounds, struct gui_context *layout)
layout->row.filled += layout->row.item_width;
layout->row.index = 0;
} break;
case GUI_LAYOUT_DYNAMIC_TILED: {
/* dynamic tiled layout widget placing */
bounds->x = layout->at_x + layout->row.item.x + padding.x;
bounds->x -= layout->offset.x;
bounds->y = layout->at_y + layout->row.item.y;
bounds->y -= layout->offset.y;
bounds->w = layout->row.item.w;
bounds->h = layout->row.item.h;
layout->row.index = 0;
if ((bounds->x + bounds->w) > layout->max_x)
layout->max_x = bounds->x + bounds->w;
return;
} break;
case GUI_LAYOUT_DYNAMIC_FREE: {
/*panel width depended free widget placing */
/* panel width depended free widget placing */
bounds->x = layout->at_x + (layout->width * layout->row.item.x);
bounds->x -= layout->offset.x;
bounds->y = layout->at_y + (layout->row.height * layout->row.item.y);
@ -5322,6 +5571,9 @@ gui_panel_alloc_space(struct gui_rect *bounds, struct gui_context *layout)
layout->row.item_offset += item_width + spacing.x;
layout->row.index = 0;
} break;
case GUI_LAYOUT_STATIC_TILED:
/* static tiled layout widget placing */
layout->row.index = 0;
case GUI_LAYOUT_STATIC_FREE: {
/* free widget placing */
bounds->x = layout->clip.x + layout->row.item.x;
@ -5428,10 +5680,10 @@ gui_layout_push(struct gui_context *layout,
/* update node state */
if (!(layout->flags & GUI_WINDOW_ROM)) {
gui_float clicked_x = layout->input->mouse.buttons[GUI_BUTTON_LEFT].clicked_pos.x;
gui_float clicked_y = layout->input->mouse.buttons[GUI_BUTTON_LEFT].clicked_pos.y;
gui_float mouse_x = layout->input->mouse.pos.x;
gui_float mouse_y = layout->input->mouse.pos.y;
gui_float clicked_x = layout->input->mouse.buttons[GUI_BUTTON_LEFT].clicked_pos.x;
gui_float clicked_y = layout->input->mouse.buttons[GUI_BUTTON_LEFT].clicked_pos.y;
if (GUI_INBOX(mouse_x, mouse_y, sym.x, sym.y, sym.w, sym.h)) {
if (GUI_INBOX(clicked_x, clicked_y, sym.x, sym.y, sym.w, sym.h)) {
if (layout->input->mouse.buttons[GUI_BUTTON_LEFT].down &&
@ -5479,7 +5731,6 @@ gui_layout_pop(struct gui_context *layout)
layout->at_x -= panel_padding.x;
layout->width += 2 * panel_padding.x;
}
/*
* -------------------------------------------------------------
*
@ -7248,3 +7499,4 @@ gui_shelf_end(struct gui_context *p, struct gui_context *s)
return pan.offset;
}

188
gui.h
View File

@ -2234,6 +2234,103 @@ void gui_style_reset(struct gui_style*);
Input:
- Configuration structure to pop the change from and to
*/
/*
* ==============================================================
*
* Tiling
*
* ===============================================================
TILING
tiling API
----------------------------
gui_tiled_begin -- starts the definition of a tiled layout
gui_tiled_slot_bounds -- returns the bounds of a slot in the tiled layout
gui_tiled_bounds -- returns the bounds of a widget in the tiled layout
gui_tiled_slot -- activates and setups a slot inside the tile layout
gui_tiled_end -- ends the definiition of the tiled layout slots
*/
enum gui_tiled_layout_slot_index {
GUI_SLOT_TOP,
GUI_SLOT_BOTTOM,
GUI_SLOT_LEFT,
GUI_SLOT_CENTER,
GUI_SLOT_RIGHT,
GUI_SLOT_MAX
};
enum gui_layout_format {
GUI_DYNAMIC, /* row layout which scales with the window */
GUI_STATIC /* row layout with fixed pixel width */
};
enum gui_tiled_slot_format {
GUI_SLOT_HORIZONTAL,
/* widgets in slots are added left to right */
GUI_SLOT_VERTICAL
/* widgets in slots are added top to bottom */
};
struct gui_tiled_slot {
gui_uint capacity;
/* number of widget inside the slot */
gui_float value;
/* temp value for layout build up */
struct gui_vec2 size;
/* horizontal and vertical window (ratio/width) */
struct gui_vec2 pos;
/* position of the slot in the window */
enum gui_tiled_slot_format format;
/* layout filling format */
};
struct gui_tiled_layout {
struct gui_tiled_slot slots[GUI_SLOT_MAX];
/* tiled layout slots */
enum gui_layout_format fmt;
/* row layout format */
gui_float width, height;
/* width/height of the layout */
};
void gui_tiled_begin(struct gui_tiled_layout*, enum gui_layout_format,
gui_float width, gui_float height);
/* this functions begins the definitions of a tiled layout
Input:
- layout format with either dynamic ratio based or fixed pixel based slots
- pixel width of the tiled layout space
- pixel height of the tiled layout space
*/
void gui_tiled_slot_bounds(struct gui_rect*, const struct gui_tiled_layout*,
enum gui_tiled_layout_slot_index);
/* this functions queries the bounds (position + size) of a tiled layout slot
Input:
- slot identifier
Output:
- rectangle with position and size of the slot
*/
void gui_tiled_bounds(struct gui_rect*, const struct gui_tiled_layout*,
enum gui_tiled_layout_slot_index, gui_uint);
/* this functions queries the bounds (position + size) of a tiled layout slot entry
Input:
- slot identifier
- index of the widget inside the slot
Output:
- rectangle with position and size of the slot entry
*/
void gui_tiled_slot(struct gui_tiled_layout *layout,
enum gui_tiled_layout_slot_index, gui_float ratio,
enum gui_tiled_slot_format, gui_uint widget_count);
/* this functions defines a slot in the tiled layout which then can be filled
* with widgets
Input:
- slot identifier
- either ratio or pixel size of the slot
- slot filling format with either horizontal or vertical filling
- number of widgets inside the slot
*/
void gui_tiled_end(struct gui_tiled_layout*);
/* this functions ends the definitions of the tiled layout slots */
/*
* ==============================================================
*
@ -2433,6 +2530,8 @@ enum gui_row_layout_type {
/* immediate mode widget specific widget width ratio layout */
GUI_LAYOUT_DYNAMIC_FREE,
/* free ratio based placing of widget in a local space */
GUI_LAYOUT_DYNAMIC_TILED,
/* dynamic Border layout */
GUI_LAYOUT_DYNAMIC,
/* retain mode widget specific widget ratio width*/
GUI_LAYOUT_STATIC_FIXED,
@ -2441,17 +2540,12 @@ enum gui_row_layout_type {
/* immediate mode widget specific widget pixel width layout */
GUI_LAYOUT_STATIC_FREE,
/* free pixel based placing of widget in a local space */
GUI_LAYOUT_STATIC_TILED,
/* static Border layout */
GUI_LAYOUT_STATIC
/* retain mode widget specific widget pixel width layout */
};
enum gui_layout_node_type {
GUI_LAYOUT_NODE,
/* a node is a space which can be minimized or maximized */
GUI_LAYOUT_TAB
/* a tab is a node with a header */
};
#define GUI_UNDEFINED (-1.0f)
struct gui_row_layout {
enum gui_row_layout_type type;
@ -2474,6 +2568,8 @@ struct gui_row_layout {
/* item bounds */
struct gui_rect clip;
/* temporary clipping rect */
struct gui_tiled_layout *tiled;
/* tiled border layout */
};
struct gui_header {
@ -2524,7 +2620,16 @@ struct gui_context {
};
void gui_begin(struct gui_context*, struct gui_window*);
/* this function begins the window build up process by creating context to fill
/* this function begins the window build up process by creating a context to fill
Input:
- input structure holding all user generated state changes
Output:
- window context to fill up with widgets
*/
void gui_begin_tiled(struct gui_context*, struct gui_window*, struct gui_tiled_layout*,
enum gui_tiled_layout_slot_index slot, gui_uint index);
/* this function begins the window build up process by creating a context to fill
and placing the window inside a tiled layout on the screen.
Input:
- input structure holding all user generated state changes
Output:
@ -2654,13 +2759,14 @@ void gui_menubar_begin(struct gui_context*);
/* this function begins the window menubar build up process */
void gui_menubar_end(struct gui_context*);
/* this function ends the window menubar build up process */
/*
* --------------------------------------------------------------
* LAYOUT
* Layout
* --------------------------------------------------------------
LAYOUT
The layout API is for positioning of widget inside a window context. In general there
are three different ways to position widget. The first one is a table with
are four different ways to position widget. The first one is a table with
fixed size columns. This like the other three comes in two flavors. First
the scaleable width as a ratio of the window width and the other is a
non-scaleable fixed pixel value for static windows.
@ -2669,34 +2775,49 @@ void gui_menubar_end(struct gui_context*);
in an immediate mode API which sets each size of a widget directly before
it is called or a retain mode API which stores the size of every widget as
an array.
The final way to position widgets is by allocating a fixed space from
The third way to position widgets is by allocating a fixed space from
the window and directly positioning each widget with position and size.
This requires the least amount of work for the API and the most for the user,
but offers the most positioning freedom.
The final row layout is a tiled layout which divides a space in the panel
into a Top, Left, Center, Right and Bottom slot. Each slot can be filled
with widgets either horizontally or vertically.
window layout function API
gui_layout_row -- user defined widget row layout
fixed width widget layout API
gui_layout_row_dynamic -- scaling fixed column row layout
gui_layout_row_static -- fixed width fixed column row layout
custom width widget layout API
gui_layout_row -- user defined widget row layout
gui_layout_row_begin -- begins the row build up process
gui_layout_row_push -- pushes the next widget width
gui_layout_row_end -- ends the row build up process
custom widget placing layout API
gui_layout_row_space_begin -- creates a free placing space in the window
gui_layout_row_space_widget -- pushes a widget into the space
gui_layout_row_space_to_screen -- converts from local space to screen
gui_layout_row_space_to_local -- conversts from screen to local space
gui_layout_row_space_rect_to_screen -- converts from local space to screen
gui_layout_row_space_rect_to_local -- conversts from screen to local space
gui_layout_row_space_to_local -- converts from screen to local space
gui_layout_row_space_rect_to_screen -- converts rect from local space to screen
gui_layout_row_space_rect_to_local -- converts rect from screen to local space
gui_layout_row_space_push -- pushes a widget into the space
gui_layout_row_space_end -- finishes the free drawingp process
window tree layout function API
gui_layout_push -- pushes a new node/collapseable header/tab
gui_layout_pop -- pops the the previously added node
tiled widget placing layout API
gui_layout_row_tiled_begin -- begins tiled layout based placing of widgets
gui_layout_row_tiled_slot_bounds -- returns the bounds of a slot in the tiled layout
gui_layout_row_tiled_bounds -- returns the bounds of a widget in the tiled layout
gui_layout_row_tiled_push -- pushes a widget into a slot in the tiled layout
gui_layout_row_tiled_end -- ends tiled layout based placing of widgets
window tree layout function API
gui_layout_push -- pushes a new node/collapseable header/tab
gui_layout_pop -- pops the the previously added node
*/
enum gui_row_layout_format {
GUI_DYNAMIC, /* row layout which scales with the window */
GUI_STATIC /* row layout with fixed pixel width */
enum gui_layout_node_type {
GUI_LAYOUT_NODE,
/* a node is a space which can be minimized or maximized */
GUI_LAYOUT_TAB
/* a tab is a node with a header */
};
void gui_layout_row_dynamic(struct gui_context*, gui_float height, gui_size cols);
@ -2714,7 +2835,7 @@ void gui_layout_row_static(struct gui_context*, gui_float row_height,
- number of widget inside the row that will divide the space
*/
void gui_layout_row_begin(struct gui_context*,
enum gui_row_layout_format,
enum gui_layout_format,
gui_float row_height, gui_size cols);
/* this function start a new scaleable row that can be filled with different
sized widget
@ -2731,7 +2852,7 @@ void gui_layout_row_push(struct gui_context*, gui_float value);
*/
void gui_layout_row_end(struct gui_context*);
/* this function ends the previously started scaleable row */
void gui_layout_row(struct gui_context*, enum gui_row_layout_format,
void gui_layout_row(struct gui_context*, enum gui_layout_format,
gui_float height, gui_size cols, const gui_float *ratio);
/* this function sets the row layout as an array of ratios/width for
every widget that will be inserted into that row
@ -2742,7 +2863,7 @@ void gui_layout_row(struct gui_context*, enum gui_row_layout_format,
- window ratio/pixel width array for each widget
*/
void gui_layout_row_space_begin(struct gui_context*,
enum gui_row_layout_format,
enum gui_layout_format,
gui_float height, gui_size widget_count);
/* this functions starts a space where widgets can be added
at any given position and the user has to make sure no overlap occures
@ -2788,6 +2909,20 @@ struct gui_rect gui_layout_row_space_rect_to_local(struct gui_context*, struct g
*/
void gui_layout_row_space_end(struct gui_context*);
/* this functions finishes the scaleable space filling process */
void gui_layout_row_tiled_begin(struct gui_context*, struct gui_tiled_layout*);
/* this functions begins the tiled layout
Input:
- row height of the complete layout to allocate from the window
*/
void gui_layout_row_tiled_push(struct gui_context*, enum gui_tiled_layout_slot_index,
gui_uint index);
/* this functions pushes a widget into a tiled layout slot
Input:
- slot identifier
- widget index in the slot
*/
void gui_layout_row_tiled_end(struct gui_context*);
/* this functions ends the tiled layout */
gui_bool gui_layout_push(struct gui_context*, enum gui_layout_node_type,
const char *title, gui_state*);
/* this functions pushes either a tree node or collapseable header into
@ -3190,6 +3325,7 @@ enum gui_popup_type {
GUI_POPUP_DYNAMIC
/* dynamically growing popup with maximum height */
};
gui_flags gui_popup_begin(struct gui_context *parent,
struct gui_context *popup, enum gui_popup_type,
gui_flags, struct gui_rect bounds,