added basic overlapping panel support

This commit is contained in:
vurtun 2015-04-28 11:56:12 +02:00
parent 2a941e84e2
commit ace72d41a9
4 changed files with 121 additions and 32 deletions

View File

@ -176,9 +176,9 @@ sequence point is undefined behavior.
```c
struct gui_memory memory = {...};
struct gui_memory_status status = {0};
struct gui_command_list out = {0};
struct gui_command_buffer buffer = {0};
struct gui_memory_status status;
struct gui_command_list list;
struct gui_command_buffer buffer;
gui_buffer_init_fixed(buffer, &memory);
while (1) {
@ -236,7 +236,7 @@ gui_panel_init(&panel, 50, 50, 300, 200, 0, &config, &font);
while (1) {
struct gui_panel_layout layout;
gui_panel_begin(&layout, &panel, "Demo", &canvas, &in);
gui_panel_begin(&layout, &panel, "Demo", &canvas, &input);
gui_panel_row(&layout, 30, 1);
if (gui_panel_button_text(&layout, "button", GUI_BUTTON_DEFAULT))
fprintf(stdout, "button pressed!\n");

View File

@ -458,6 +458,7 @@ demo_panel(struct gui_panel_layout *panel, struct demo *demo)
int
main(int argc, char *argv[])
{
/* Platform */
long dt;
long started;
XWindow xw;
@ -475,8 +476,10 @@ main(int argc, char *argv[])
struct gui_canvas canvas;
struct gui_command_buffer buffer;
struct gui_command_list list;
struct gui_panel panel;
struct gui_panel_stack stack;
struct gui_panel_layout layout;
struct gui_window win;
struct gui_window msg;
/* Window */
UNUSED(argc); UNUSED(argv);
@ -511,10 +514,12 @@ main(int argc, char *argv[])
font.height = (gui_float)xfont->height;
font.width = font_get_text_width;
gui_default_config(&config);
gui_panel_init(&panel, 50, 50, 420, 300,
gui_stack_clear(&stack);
gui_panel_init(&win.panel, 50, 50, 420, 300,
GUI_PANEL_BORDER|GUI_PANEL_MOVEABLE|
GUI_PANEL_CLOSEABLE|GUI_PANEL_SCALEABLE|
GUI_PANEL_MINIMIZABLE, &config, &font);
gui_stack_push(&stack, &win.panel);
/* Demo */
memset(&demo, 0, sizeof(demo));
@ -541,9 +546,9 @@ main(int argc, char *argv[])
/* GUI */
gui_buffer_begin(&canvas, &buffer, xw.width, xw.height);
running = gui_panel_begin(&layout, &panel , "Demo", &canvas, &in);
running = gui_panel_begin_stacked(&layout, &win.panel, &stack, "Demo", &canvas, &in);
demo_panel(&layout, &demo);
gui_panel_end(&layout, &panel);
gui_panel_end(&layout, &win.panel);
gui_buffer_end(&list, &buffer, &canvas, &status);
/* Draw */

99
gui.c
View File

@ -662,8 +662,7 @@ gui_input(const struct gui_canvas *canvas, gui_float x, gui_float y, gui_float w
assert(canvas);
assert(buffer);
assert(field);
assert(in);
if (!canvas || !buffer || !field || !in)
if (!canvas || !buffer || !field)
return 0;
input_w = MAX(w, 2 * field->padding.x);
@ -809,8 +808,7 @@ gui_histo(const struct gui_canvas *canvas, gui_float x, gui_float y, gui_float w
assert(canvas);
assert(histo);
assert(in);
if (!canvas || !histo || !in)
if (!canvas || !histo)
return selected;
histo_w = MAX(w, 2 * histo->padding.x);
@ -944,7 +942,7 @@ gui_buffer_push(struct gui_command_buffer* buffer,
if (!buffer->allocator.realloc) return NULL;
cap = (gui_size)((gui_float)buffer->capacity * buffer->grow_factor);
cap = cap + MAX(size, cap - buffer->capacity);
buffer->memory = buffer->allocator.realloc(buffer->memory, cap);
buffer->memory = buffer->allocator.realloc(buffer->allocator.userdata, buffer->memory, cap);
if (!buffer->memory) return NULL;
buffer->capacity = cap;
}
@ -1126,7 +1124,7 @@ gui_buffer_init(struct gui_command_buffer *buffer, const struct gui_allocator *m
gui_size initial_size, gui_float grow_factor, enum gui_clipping clipping)
{
zero(buffer, sizeof(*buffer));
buffer->memory = memory->alloc(initial_size);
buffer->memory = memory->alloc(memory->userdata, initial_size);
buffer->allocator = *memory;
buffer->capacity = initial_size;
buffer->begin = buffer->memory;
@ -1185,7 +1183,7 @@ gui_buffer_clear(struct gui_command_buffer *buffer)
{
assert(buffer);
if (!buffer || !buffer->memory || !buffer->allocator.free) return;
buffer->allocator.free(buffer->memory);
buffer->allocator.free(buffer->allocator.userdata, buffer->memory);
}
void
@ -1270,9 +1268,8 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel,
assert(panel);
assert(layout);
assert(canvas);
assert(in);
if (!panel || !canvas || !layout || !in)
if (!panel || !canvas || !layout)
return gui_false;
if (panel->flags & GUI_PANEL_HIDDEN)
return gui_false;
@ -1280,6 +1277,12 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel,
config = panel->config;
layout->header_height = panel->font.height + 3 * config->item_padding.y;
layout->header_height += config->panel_padding.y;
mouse_x = (in) ? in->mouse_pos.x : -1;
mouse_y = (in) ? in->mouse_pos.y : -1;
clicked_x = (in) ? in->mouse_clicked_pos.x : -1;
clicked_y = (in) ? in->mouse_clicked_pos.y : -1;
if (panel->flags & GUI_PANEL_MOVEABLE) {
gui_bool incursor;
const gui_float move_x = panel->x;
@ -1287,8 +1290,8 @@ 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_height;
incursor = INBOX(in->mouse_prev.x,in->mouse_prev.y, move_x, move_y, move_w, move_h);
if (in->mouse_down && incursor) {
incursor = in && INBOX(in->mouse_prev.x,in->mouse_prev.y, move_x, move_y, move_w, move_h);
if (in && in->mouse_down && incursor) {
panel->x = CLAMP(0, panel->x+in->mouse_delta.x, (gui_float)canvas->width-panel->w);
panel->y = CLAMP(0, panel->y+in->mouse_delta.y, (gui_float)canvas->height-panel->h);
}
@ -1301,8 +1304,8 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel,
gui_float scaler_w = MAX(0, config->scaler_size.x - config->item_padding.x);
gui_float scaler_h = MAX(0, config->scaler_size.y - config->item_padding.y);
incursor = INBOX(in->mouse_prev.x,in->mouse_prev.y,scaler_x, scaler_y, scaler_w, scaler_h);
if (in->mouse_down && incursor) {
incursor = in && INBOX(in->mouse_prev.x,in->mouse_prev.y,scaler_x, scaler_y, scaler_w, scaler_h);
if (in && in->mouse_down && incursor) {
gui_float min_x = config->panel_min_size.x;
gui_float min_y = config->panel_min_size.y;
panel->x = CLAMP(0, panel->x + in->mouse_delta.x, (gui_float)canvas->width-panel->w);
@ -1328,11 +1331,6 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel,
layout->row_height = 0;
layout->offset = panel->offset;
mouse_x = in->mouse_pos.x;
mouse_y = in->mouse_pos.y;
clicked_x = in->mouse_clicked_pos.x;
clicked_y = in->mouse_clicked_pos.y;
header = &config->colors[GUI_COLOR_TITLEBAR];
header_x = panel->x + config->panel_padding.x;
header_w = panel->w - 2 * config->panel_padding.x;
@ -1441,6 +1439,29 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel,
return ret;
}
gui_bool
gui_panel_begin_stacked(struct gui_panel_layout *layout, struct gui_panel *panel,
struct gui_panel_stack *stack, const char *title, const struct gui_canvas *canvas,
const struct gui_input *in)
{
gui_bool inpanel;
inpanel = INBOX(in->mouse_prev.x, in->mouse_prev.y, panel->x, panel->y, panel->w, panel->h);
if (in->mouse_down && in->mouse_clicked && inpanel && panel != stack->end) {
struct gui_panel *iter = panel->next;
while (iter) {
if (!iter->minimized)
if (INBOX(in->mouse_prev.x, in->mouse_prev.y, iter->x, iter->y,
iter->w, iter->h)) break;
iter = iter->next;
}
if (!iter) {
gui_stack_pop(stack, panel);
gui_stack_push(stack, panel);
}
}
return gui_panel_begin(layout, panel, title, canvas, (stack->end == panel) ? in : NULL);
}
void
gui_panel_row(struct gui_panel_layout *layout, gui_float height, gui_size cols)
{
@ -1553,7 +1574,6 @@ gui_panel_button_text(struct gui_panel_layout *layout, const char *str,
assert(layout);
assert(layout->config);
assert(layout->canvas);
assert(layout->input);
if (!layout || !layout->config || !layout->canvas) return 0;
if (!layout->valid) return 0;
@ -2281,3 +2301,44 @@ gui_panel_end(struct gui_panel_layout *layout, struct gui_panel *panel)
canvas->scissor(canvas->userdata, 0, 0, (gui_float)canvas->width, (gui_float)canvas->height);
}
void
gui_stack_clear(struct gui_panel_stack *stack)
{
stack->begin = NULL;
stack->end = NULL;
stack->count = 0;
}
void
gui_stack_push(struct gui_panel_stack *stack, struct gui_panel *panel)
{
if (!stack->begin) {
panel->next = NULL;
panel->prev = NULL;
stack->begin = panel;
stack->end = panel;
stack->count = 1;
return;
}
stack->end->next = panel;
panel->prev = stack->end;
panel->next = NULL;
stack->end = panel;
stack->count++;
}
void
gui_stack_pop(struct gui_panel_stack *stack, struct gui_panel *panel)
{
if (panel->prev)
panel->prev->next = panel->next;
if (panel->next)
panel->next->prev = panel->prev;
if (stack->begin == panel)
stack->begin = panel->next;
if (stack->end == panel)
stack->end = panel->prev;
panel->next = NULL;
panel->prev = NULL;
}

33
gui.h
View File

@ -194,9 +194,10 @@ struct gui_memory {
};
struct gui_allocator {
void*(*alloc)(gui_size);
void*(*realloc)(void*,gui_size);
void(*free)(void*);
void *userdata;
void*(*alloc)(void *usr, gui_size);
void*(*realloc)(void *usr, void*, gui_size);
void(*free)(void *usr, void*);
};
enum gui_command_type {
@ -251,12 +252,12 @@ struct gui_command_triangle {
struct gui_command_text {
struct gui_command header;
void *font;
gui_short x, y;
gui_ushort w, h;
gui_size length;
struct gui_color bg;
struct gui_color fg;
void *font;
gui_size length;
gui_char string[1];
};
@ -366,6 +367,8 @@ struct gui_panel {
gui_bool minimized;
struct gui_font font;
const struct gui_config *config;
struct gui_panel *next;
struct gui_panel *prev;
};
struct gui_panel_layout {
@ -386,6 +389,17 @@ struct gui_panel_layout {
const struct gui_canvas *canvas;
};
struct gui_panel_stack {
gui_size count;
struct gui_panel *begin;
struct gui_panel *end;
};
struct gui_window {
struct gui_panel panel;
struct gui_command_list list;
};
/* Input */
void gui_input_begin(struct gui_input*);
void gui_input_motion(struct gui_input*, gui_int x, gui_int y);
@ -461,6 +475,9 @@ void gui_panel_init(struct gui_panel*, gui_float x, gui_float y, gui_float w, gu
const struct gui_config *config, const struct gui_font*);
gui_bool gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel*,
const char *title, const struct gui_canvas*, const struct gui_input*);
gui_bool gui_panel_begin_stacked(struct gui_panel_layout *layout, struct gui_panel*,
struct gui_panel_stack*, const char *title, const struct gui_canvas*,
const struct gui_input*);
void gui_panel_row(struct gui_panel_layout*, gui_float height, gui_size cols);
void gui_panel_seperator(struct gui_panel_layout*, gui_size cols);
void gui_panel_text(struct gui_panel_layout*, const char *str, gui_size len, enum gui_text_align);
@ -495,6 +512,12 @@ gui_size gui_panel_shelf_begin(struct gui_panel_layout*, struct gui_panel_layout
gui_float gui_panel_shelf_end(struct gui_panel_layout*, struct gui_panel_layout *shelf);
void gui_panel_end(struct gui_panel_layout*, struct gui_panel*);
/* Stack */
void gui_stack_clear(struct gui_panel_stack*);
void gui_stack_push(struct gui_panel_stack*, struct gui_panel*);
void gui_stack_pop(struct gui_panel_stack*, struct gui_panel*);
#ifdef __cplusplus
}
#endif