that did not work
This commit is contained in:
parent
fa2c7a7c28
commit
90d536f7bf
56
Readme.md
56
Readme.md
|
@ -277,6 +277,62 @@ while (1) {
|
|||
}
|
||||
```
|
||||
|
||||
### Stack
|
||||
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_window` which contains the panel and the buffer output `gui_command_list`,
|
||||
which can be used to implement overlapping panels.
|
||||
|
||||
```c
|
||||
struct gui_window window;
|
||||
struct gui_memory memory = {...};
|
||||
struct gui_memory_status status;
|
||||
struct gui_command_buffer buffer;
|
||||
struct gui_config config;
|
||||
struct gui_font font = {...}
|
||||
struct gui_input input = {0};
|
||||
struct gui_stack stack;
|
||||
|
||||
gui_buffer_init_fixed(buffer, &memory);
|
||||
gui_default_config(&config);
|
||||
gui_panel_init(&win.panel, 50, 50, 300, 200, 0, &config, &font);
|
||||
gui_stack_clear(&stack);
|
||||
gui_stack_push(&stack, &win.panel);
|
||||
|
||||
while (1) {
|
||||
struct gui_panel_layout layout;
|
||||
struct gui_canvas canvas;
|
||||
|
||||
gui_buffer_begin(&canvas, &buffer, window_width, window_height);
|
||||
gui_panel_begin_stacked(&layout, &win.panel, &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_panel_end(&layout, &win.panel);
|
||||
gui_buffer_end(&win.list, buffer, &status);
|
||||
|
||||
/* draw each panel */
|
||||
struct gui_panel *iter = stack.begin;
|
||||
while (iter) {
|
||||
const struct gui_window *w = iter;
|
||||
const struct gui_command *cmd = gui_list_begin(&w->list);
|
||||
while (cmd) {
|
||||
/* execute command */
|
||||
cmd = gui_list_next(&w->list, cmd);
|
||||
}
|
||||
iter = iter->next;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## FAQ
|
||||
#### Where is the demo/example code?
|
||||
The demo and example code can be found in the demo folder.
|
||||
|
|
24
demo/xlib.c
24
demo/xlib.c
|
@ -479,12 +479,9 @@ main(int argc, char *argv[])
|
|||
struct gui_config config;
|
||||
struct gui_canvas canvas;
|
||||
struct gui_command_buffer buffer;
|
||||
struct gui_command_buffer sub;
|
||||
struct gui_command_list panel_list;
|
||||
struct gui_command_list msg_list;
|
||||
struct gui_command_list list;
|
||||
struct gui_panel_layout layout;
|
||||
struct gui_panel panel;
|
||||
struct gui_panel msg;
|
||||
|
||||
/* Window */
|
||||
UNUSED(argc); UNUSED(argv);
|
||||
|
@ -523,8 +520,6 @@ main(int argc, char *argv[])
|
|||
GUI_PANEL_BORDER|GUI_PANEL_MOVEABLE|
|
||||
GUI_PANEL_CLOSEABLE|GUI_PANEL_SCALEABLE|
|
||||
GUI_PANEL_MINIMIZABLE, &config, &font);
|
||||
gui_panel_init(&msg, 150, 150, 200, 80,
|
||||
GUI_PANEL_BORDER|GUI_PANEL_MOVEABLE, &config, &font);
|
||||
|
||||
/* Demo */
|
||||
memset(&demo, 0, sizeof(demo));
|
||||
|
@ -551,27 +546,16 @@ main(int argc, char *argv[])
|
|||
gui_input_end(&in);
|
||||
|
||||
/* GUI */
|
||||
gui_buffer_begin(NULL, &buffer, xw.width, xw.height);
|
||||
gui_buffer_lock(&canvas, &buffer, &sub, 0, xw.width, xw.height);
|
||||
gui_buffer_begin(&canvas, &buffer, xw.width, xw.height);
|
||||
running = gui_panel_begin(&layout, &panel, "Demo", &canvas, &in);
|
||||
demo_panel(&layout, &demo);
|
||||
gui_panel_end(&layout, &panel);
|
||||
gui_buffer_unlock(&panel_list, &buffer, &sub, &canvas, NULL);
|
||||
|
||||
gui_buffer_lock(&canvas, &buffer, &sub, 0, xw.width, xw.height);
|
||||
gui_panel_begin(&layout, &msg, "Demo", &canvas, &in);
|
||||
gui_panel_row(&layout, 30, 2);
|
||||
if (gui_panel_button_text(&layout, "ok", GUI_BUTTON_DEFAULT)) break;
|
||||
if (gui_panel_button_text(&layout, "cancel", GUI_BUTTON_DEFAULT)) break;
|
||||
gui_panel_end(&layout, &msg);
|
||||
gui_buffer_unlock(&msg_list, &buffer, &sub, &canvas, NULL);
|
||||
gui_buffer_end(NULL, &buffer, NULL, NULL);
|
||||
gui_buffer_end(&list, &buffer, &canvas, &status);
|
||||
|
||||
/* Draw */
|
||||
XClearWindow(xw.dpy, xw.win);
|
||||
surface_clear(xw.surf, 0x00646464);
|
||||
draw(xw.surf, &panel_list);
|
||||
draw(xw.surf, &msg_list);
|
||||
draw(xw.surf, &list);
|
||||
surface_blit(xw.win, xw.surf, xw.width, xw.height);
|
||||
XFlush(xw.dpy);
|
||||
|
||||
|
|
72
gui.c
72
gui.c
|
@ -1482,6 +1482,36 @@ 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;
|
||||
assert(layout);
|
||||
assert(panel);
|
||||
assert(stack);
|
||||
assert(canvas);
|
||||
if (!layout || !panel || !stack || !canvas)
|
||||
return gui_false;
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -2742,3 +2772,45 @@ 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;
|
||||
}
|
||||
|
||||
|
|
22
gui.h
22
gui.h
|
@ -395,6 +395,13 @@ 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_window {
|
||||
struct gui_panel panel;
|
||||
struct gui_command_list list;
|
||||
};
|
||||
|
||||
struct gui_panel_layout {
|
||||
|
@ -417,6 +424,12 @@ struct gui_panel_layout {
|
|||
const struct gui_canvas *canvas;
|
||||
};
|
||||
|
||||
struct gui_panel_stack {
|
||||
gui_size count;
|
||||
struct gui_panel *begin;
|
||||
struct gui_panel *end;
|
||||
};
|
||||
|
||||
/* Input */
|
||||
gui_size gui_utf_decode(const gui_char*, gui_long*, gui_size);
|
||||
gui_size gui_utf_encode(gui_long, gui_char*, gui_size);
|
||||
|
@ -505,6 +518,9 @@ void gui_panel_init(struct gui_panel*, gui_float x, gui_float y, gui_float w, gu
|
|||
gui_flags, 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*, struct gui_panel*,
|
||||
struct gui_panel_stack*, const char*, 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_alloc_space(struct gui_rect*, struct gui_panel_layout*);
|
||||
void gui_panel_seperator(struct gui_panel_layout*, gui_size cols);
|
||||
|
@ -559,6 +575,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
|
||||
|
|
Loading…
Reference in New Issue