changed stack to use hook instead of panel
This commit is contained in:
parent
c9666d1151
commit
43f492c34a
37
Readme.md
37
Readme.md
|
@ -37,14 +37,16 @@ Summary: It is only responsible for the actual user interface
|
|||
|
||||
## Example
|
||||
```c
|
||||
struct gui_input input = {0};
|
||||
struct gui_font font = {...};
|
||||
/* allocate memory to hold output */
|
||||
struct gui_memory memory = {...};
|
||||
struct gui_command_buffer buffer;
|
||||
gui_buffer_init_fixed(buffer, &memory, 0);
|
||||
|
||||
struct gui_panel panel;
|
||||
/* initialize panel */
|
||||
struct gui_config config;
|
||||
struct gui_input input = {0};
|
||||
struct gui_font font = {...};
|
||||
struct gui_panel panel;
|
||||
gui_default_config(&config);
|
||||
gui_panel_init(&panel, 50, 50, 220, 170,
|
||||
GUI_PANEL_BORDER|GUI_PANEL_MOVEABLE|
|
||||
|
@ -344,17 +346,15 @@ While using basic panels is fine for a single movable panel or a big number of
|
|||
static panels, it has rather limited support for overlapping movable panels. For
|
||||
that to change the panel stack was introduced. The panel stack holds the basic
|
||||
drawing order of each panel so instead of drawing each panel individually they
|
||||
have to be drawn in a certain order. The biggest problem while creating the API
|
||||
was that the buffer has to saved with the panel, but the type of the buffer is
|
||||
not known beforehand since it is possible to create your own buffer type.
|
||||
Therefore just the sequence of panels is managed and you either have to cast
|
||||
from the panel to your own type, use inheritance in C++ or use the `container_of`
|
||||
macro from the Linux kernel. For the standard buffer there is already a type
|
||||
`gui_panel_hook` which contains the panel and the buffer output `gui_command_list`,
|
||||
which can be used to implement overlapping panels.
|
||||
have to be drawn in a certain order.
|
||||
|
||||
```c
|
||||
struct gui_panel_hook hook;
|
||||
struct your_window {
|
||||
struct gui_panel_hook hook;
|
||||
/* your data */
|
||||
}
|
||||
|
||||
struct your_window win;
|
||||
struct gui_memory memory = {...};
|
||||
struct gui_memory_status status;
|
||||
struct gui_command_buffer buffer;
|
||||
|
@ -365,30 +365,29 @@ struct gui_stack stack;
|
|||
|
||||
gui_buffer_init_fixed(buffer, &memory);
|
||||
gui_default_config(&config);
|
||||
gui_hook_init(&hook, 50, 50, 300, 200, 0, &config, &font);
|
||||
gui_hook_init(&win.hook, 50, 50, 300, 200, 0, &config, &font);
|
||||
gui_stack_clear(&stack);
|
||||
gui_stack_push_hook(&stack, &hook);
|
||||
gui_stack_push(&stack, &win.hook);
|
||||
|
||||
while (1) {
|
||||
struct gui_panel_layout layout;
|
||||
struct gui_canvas canvas;
|
||||
|
||||
gui_buffer_begin(&canvas, &buffer, window_width, window_height);
|
||||
gui_hook_begin(&layout, &hook, &stack, "Demo", &canvas, &input);
|
||||
gui_hook_begin(&layout, &win.hook, &stack, "Demo", &canvas, &input);
|
||||
gui_panel_row(&layout, 30, 1);
|
||||
if (gui_panel_button_text(&layout, "button", GUI_BUTTON_DEFAULT))
|
||||
fprintf(stdout, "button pressed!\n");
|
||||
gui_hook_end(&layout, &hook);
|
||||
gui_buffer_end(gui_hook_list(&hook), buffer, &status);
|
||||
gui_hook_end(&layout, &win.hook);
|
||||
gui_buffer_end(gui_hook_list(&win.hook), buffer, &status);
|
||||
|
||||
/* draw each panel */
|
||||
struct gui_panel *iter = stack.begin;
|
||||
while (iter) {
|
||||
struct gui_panel_hook *h = gui_hook(iter);
|
||||
const struct gui_command *cmd = gui_list_begin(gui_hook_list(h));
|
||||
while (cmd) {
|
||||
/* execute command */
|
||||
cmd = gui_list_next(gui_hook_list(h), cmd);
|
||||
cmd = gui_list_next(gui_hook_output(iter), cmd);
|
||||
}
|
||||
iter = iter->next;
|
||||
}
|
||||
|
|
35
demo/demo.c
35
demo/demo.c
|
@ -3,6 +3,8 @@
|
|||
|
||||
struct show_window {
|
||||
struct gui_panel_hook hook;
|
||||
|
||||
/* widget data */
|
||||
gui_char in_buf[MAX_BUFFER];
|
||||
gui_size in_len;
|
||||
gui_bool in_act;
|
||||
|
@ -16,22 +18,30 @@ struct show_window {
|
|||
gui_bool spin_act;
|
||||
gui_size item_cur;
|
||||
gui_size cur;
|
||||
gui_bool diff_min;
|
||||
gui_bool wid_min;
|
||||
gui_bool tbl_min;
|
||||
gui_float shelf_off;
|
||||
gui_float tbl_off;
|
||||
gui_int combo_sel;
|
||||
gui_bool toggle;
|
||||
gui_int option;
|
||||
|
||||
/* tabs */
|
||||
gui_bool diff_min;
|
||||
gui_bool wid_min;
|
||||
gui_bool tbl_min;
|
||||
|
||||
/* scrollbars */
|
||||
gui_float shelf_off;
|
||||
gui_float tbl_off;
|
||||
};
|
||||
|
||||
struct control_window {
|
||||
struct gui_panel_hook hook;
|
||||
gui_flags show_flags;
|
||||
|
||||
/* tabs */
|
||||
gui_bool flag_min;
|
||||
gui_bool style_min;
|
||||
gui_bool color_min;
|
||||
|
||||
/* color picker */
|
||||
gui_bool picker_act;
|
||||
gui_bool col_r_act;
|
||||
gui_bool col_g_act;
|
||||
|
@ -79,7 +89,7 @@ graph_panel(struct gui_panel_layout *panel, struct show_window *demo)
|
|||
enum {HISTO, PLOT};
|
||||
struct gui_panel_layout tab;
|
||||
static const char *shelfs[] = {"Histogram", "Lines"};
|
||||
static const gui_float values[] = {8.0f, 15.0f, 20.0f, 12.0f, 30.0f, 12.0f, 35.0f, 40.0f, 20.0f};
|
||||
static const gui_float values[] = {8.0f,15.0f,20.0f,12.0f,30.0f,12.0f,35.0f,40.0f,20.0f};
|
||||
gui_panel_row(panel, 180, 1);
|
||||
demo->cur = gui_panel_shelf_begin(panel,&tab,shelfs,LEN(shelfs),demo->cur,demo->shelf_off);
|
||||
gui_panel_row(&tab, 100, 1);
|
||||
|
@ -169,7 +179,8 @@ flags_tab(struct gui_panel_layout *panel, struct control_window *control)
|
|||
control->flag_min = gui_panel_tab_begin(panel, &tab, "Options", control->flag_min);
|
||||
gui_panel_row(&tab, 30, 2);
|
||||
do {
|
||||
if (gui_panel_check(&tab, options[n++], (control->show_flags & i) ? gui_true : gui_false)) res |= i;
|
||||
if (gui_panel_check(&tab, options[n++], (control->show_flags & i) ? gui_true : gui_false))
|
||||
res |= i;
|
||||
i = i << 1;
|
||||
} while (i <= GUI_PANEL_SCALEABLE);
|
||||
control->show_flags = res;
|
||||
|
@ -305,9 +316,9 @@ init_demo(struct show_window *show, struct control_window *control,
|
|||
GUI_PANEL_BORDER|GUI_PANEL_MOVEABLE|
|
||||
GUI_PANEL_CLOSEABLE|GUI_PANEL_SCALEABLE|
|
||||
GUI_PANEL_MINIMIZABLE, config, font);
|
||||
gui_stack_push_hook(stack, &show->hook);
|
||||
gui_stack_push(stack, &show->hook);
|
||||
|
||||
/*show->wid_min = gui_true;*/
|
||||
show->wid_min = gui_true;
|
||||
show->diff_min = gui_true;
|
||||
show->slider = 5.0f;
|
||||
show->prog = 50;
|
||||
|
@ -316,7 +327,7 @@ init_demo(struct show_window *show, struct control_window *control,
|
|||
memset(control, 0, sizeof(*control));
|
||||
gui_hook_init(&control->hook, 380, 50, 400, 350,
|
||||
GUI_PANEL_BORDER|GUI_PANEL_MOVEABLE|GUI_PANEL_CLOSEABLE|GUI_PANEL_SCALEABLE, config, font);
|
||||
gui_stack_push_hook(stack, &control->hook);
|
||||
gui_stack_push(stack, &control->hook);
|
||||
control->show_flags = gui_hook_panel(&show->hook)->flags;
|
||||
control->style_min = gui_true;
|
||||
control->color_min = gui_true;
|
||||
|
@ -334,14 +345,14 @@ run_demo(struct show_window *show, struct control_window *control, struct gui_pa
|
|||
gui_buffer_begin(NULL, buffer, width, height);
|
||||
gui_buffer_lock(&canvas, buffer, &sub, 0, width, height);
|
||||
running = control_panel(control, stack, in, &canvas, config);
|
||||
gui_buffer_unlock(gui_hook_list(&control->hook), buffer, &sub, &canvas, NULL);
|
||||
gui_buffer_unlock(gui_hook_output(&control->hook), buffer, &sub, &canvas, NULL);
|
||||
|
||||
gui_hook_panel(&show->hook)->flags = control->show_flags;
|
||||
gui_buffer_lock(&canvas, buffer, &sub, 0, width, height);
|
||||
show_panel(show, stack, in, &canvas);
|
||||
if (gui_hook_panel(&show->hook)->flags & GUI_PANEL_HIDDEN)
|
||||
control->show_flags |= GUI_PANEL_HIDDEN;
|
||||
gui_buffer_unlock(gui_hook_list(&show->hook), buffer, &sub, &canvas, NULL);
|
||||
gui_buffer_unlock(gui_hook_output(&show->hook), buffer, &sub, &canvas, NULL);
|
||||
gui_buffer_end(NULL, buffer, NULL, NULL);
|
||||
return running;
|
||||
}
|
||||
|
|
|
@ -480,11 +480,10 @@ execute(struct gui_command_list *list, int width, int height)
|
|||
static void
|
||||
draw(struct gui_panel_stack *stack, int width, int height)
|
||||
{
|
||||
struct gui_panel *iter = stack->begin;
|
||||
struct gui_panel_hook *iter = stack->begin;
|
||||
if (!stack->count) return;
|
||||
while (iter) {
|
||||
struct gui_panel_hook *hook = gui_hook(iter);
|
||||
execute(&hook->list, width, height);
|
||||
execute(gui_hook_output(iter), width, height);
|
||||
iter = iter->next;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ static void
|
|||
font_del(XFont *font)
|
||||
{
|
||||
if (font->handle)
|
||||
DeleteObject(font->handle);
|
||||
DeleteObject(font->handle);
|
||||
free(font);
|
||||
}
|
||||
|
||||
|
@ -334,11 +334,10 @@ execute(XSurface *surf, struct gui_command_list *list)
|
|||
static void
|
||||
draw(XSurface *surf, struct gui_panel_stack *stack)
|
||||
{
|
||||
struct gui_panel *iter = stack->begin;
|
||||
struct gui_panel_hook *iter = stack->begin;
|
||||
if (!stack->count) return;
|
||||
while (iter) {
|
||||
struct gui_panel_hook *hook = gui_hook(iter);
|
||||
execute(surf, gui_hook_list(hook));
|
||||
execute(surf, gui_hook_output(iter));
|
||||
iter = iter->next;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -345,11 +345,10 @@ execute(XSurface *surf, struct gui_command_list *list)
|
|||
static void
|
||||
draw(XSurface *surf, struct gui_panel_stack *stack)
|
||||
{
|
||||
struct gui_panel *iter = stack->begin;
|
||||
struct gui_panel_hook *iter = stack->begin;
|
||||
if (!stack->count) return;
|
||||
while (iter) {
|
||||
struct gui_panel_hook *hook = gui_hook(iter);
|
||||
execute(surf, gui_hook_list(hook));
|
||||
execute(surf, gui_hook_output(iter));
|
||||
iter = iter->next;
|
||||
}
|
||||
}
|
||||
|
|
21
gui.c
21
gui.c
|
@ -1546,6 +1546,7 @@ gui_panel_begin_stacked(struct gui_panel_layout *layout, struct gui_panel *panel
|
|||
const struct gui_input *in)
|
||||
{
|
||||
gui_bool inpanel;
|
||||
struct gui_panel_hook *hook;
|
||||
ASSERT(layout);
|
||||
ASSERT(panel);
|
||||
ASSERT(stack);
|
||||
|
@ -1553,20 +1554,22 @@ gui_panel_begin_stacked(struct gui_panel_layout *layout, struct gui_panel *panel
|
|||
if (!layout || !panel || !stack || !canvas)
|
||||
return gui_false;
|
||||
|
||||
hook = (struct gui_panel_hook*)panel;
|
||||
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;
|
||||
if (in->mouse_down && in->mouse_clicked && inpanel && hook != stack->end) {
|
||||
const struct gui_panel_hook *iter = hook->next;
|
||||
while (iter) {
|
||||
if (INBOX(in->mouse_prev.x, in->mouse_prev.y, iter->x, iter->y, iter->w, iter->h) &&
|
||||
!iter->minimized) break;
|
||||
const struct gui_panel *cur = gui_hook_panel(iter);
|
||||
if (INBOX(in->mouse_prev.x, in->mouse_prev.y, cur->x, cur->y, cur->w, cur->h) &&
|
||||
!cur->minimized) break;
|
||||
iter = iter->next;
|
||||
}
|
||||
if (!iter) {
|
||||
gui_stack_pop(stack, panel);
|
||||
gui_stack_push(stack, panel);
|
||||
gui_stack_pop(stack, hook);
|
||||
gui_stack_push(stack, hook);
|
||||
}
|
||||
}
|
||||
return gui_panel_begin(layout, panel, title, canvas, (stack->end == panel) ? in : NULL);
|
||||
return gui_panel_begin(layout, panel, title, canvas, (stack->end == hook) ? in : NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2741,7 +2744,7 @@ gui_stack_clear(struct gui_panel_stack *stack)
|
|||
}
|
||||
|
||||
void
|
||||
gui_stack_push(struct gui_panel_stack *stack, struct gui_panel *panel)
|
||||
gui_stack_push(struct gui_panel_stack *stack, struct gui_panel_hook *panel)
|
||||
{
|
||||
if (!stack->begin) {
|
||||
panel->next = NULL;
|
||||
|
@ -2760,7 +2763,7 @@ gui_stack_push(struct gui_panel_stack *stack, struct gui_panel *panel)
|
|||
}
|
||||
|
||||
void
|
||||
gui_stack_pop(struct gui_panel_stack *stack, struct gui_panel *panel)
|
||||
gui_stack_pop(struct gui_panel_stack *stack, struct gui_panel_hook *panel)
|
||||
{
|
||||
if (panel->prev)
|
||||
panel->prev->next = panel->next;
|
||||
|
|
35
gui.h
35
gui.h
|
@ -15,9 +15,9 @@ extern "C" {
|
|||
#define GUI_INPUT_MAX 16
|
||||
#define GUI_UTF_INVALID 0xFFFD
|
||||
#define GUI_HOOK_PANEL_NAME panel
|
||||
#define GUI_HOOK_LIST_NAME list
|
||||
#define GUI_HOOK_OUTPUT_NAME list
|
||||
#define GUI_HOOK_ATTR(T, name) struct T name
|
||||
#define GUI_HOOK_OUT gui_command_list
|
||||
#define GUI_HOOK_OUTPUT gui_command_list
|
||||
|
||||
/* Types */
|
||||
#ifdef GUI_USE_FIXED_TYPES
|
||||
|
@ -415,8 +415,6 @@ 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 {
|
||||
|
@ -439,16 +437,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_panel_hook {
|
||||
GUI_HOOK_ATTR(gui_panel, GUI_HOOK_PANEL_NAME);
|
||||
GUI_HOOK_ATTR(GUI_HOOK_OUT, GUI_HOOK_LIST_NAME);
|
||||
GUI_HOOK_ATTR(GUI_HOOK_OUTPUT, GUI_HOOK_OUTPUT_NAME);
|
||||
struct gui_panel_hook *next;
|
||||
struct gui_panel_hook *prev;
|
||||
};
|
||||
|
||||
struct gui_panel_stack {
|
||||
gui_size count;
|
||||
struct gui_panel_hook *begin;
|
||||
struct gui_panel_hook *end;
|
||||
};
|
||||
|
||||
/* Input */
|
||||
|
@ -606,25 +605,19 @@ 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*);
|
||||
void gui_stack_push(struct gui_panel_stack*, struct gui_panel_hook*);
|
||||
void gui_stack_pop(struct gui_panel_stack*, struct gui_panel_hook*);
|
||||
|
||||
|
||||
/* Hook */
|
||||
#define gui_hook(p) ((struct gui_panel_hook*)(p))
|
||||
#define gui_hook_panel(h) (&((h)->GUI_HOOK_PANEL_NAME))
|
||||
#define gui_hook_list(h) (&((h)->GUI_HOOK_LIST_NAME))
|
||||
#define gui_hook_output(h) (&((h)->GUI_HOOK_OUTPUT_NAME))
|
||||
#define gui_hook_init(hook, x, y, w, h, flags, config, font)\
|
||||
gui_panel_init(&(*(hook)).GUI_HOOK_PANEL_NAME, x, y, w, h, flags, config, font)
|
||||
#define gui_hook_begin(layout, hook, stack, title, canvas, in)\
|
||||
gui_panel_begin_stacked(layout, &(*(hook)).GUI_HOOK_PANEL_NAME, stack, title, canvas, in)
|
||||
#define gui_hook_end(layout, hook)\
|
||||
gui_panel_end((layout), &(hook)->GUI_HOOK_PANEL_NAME)
|
||||
#define gui_stack_push_hook(stack, hook)\
|
||||
gui_stack_push(stack, &(*(hook)).GUI_HOOK_PANEL_NAME)
|
||||
#define gui_stack_pop_hook(stack, hook)\
|
||||
gui_stack_pop(stack, &(*(hook)).GUI_HOOK_PANEL_NAME)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue