removed some things I am not happy with

This commit is contained in:
vurtun 2015-05-07 15:05:57 +02:00
parent 902bdc8e11
commit ee30d7efd7
4 changed files with 41 additions and 377 deletions

View File

@ -213,11 +213,11 @@ while (1) {
struct gui_canvas canvas;
struct gui_command_buffer sub;
gui_buffer_lock(&sub, &buffer);
gui_buffer_begin(&canvas, &sub, window_width, window_height);
gui_buffer_begin(NULL, &buffer, width, height);
gui_buffer_lock(&canvas, &buffer, &sub, 0, width, height);
/* add commands by using the canvas */
gui_buffer_end(&list, &sub, &status);
gui_buffer_unlock(&buffer, &sub);
gui_buffer_unlock(&list, &buffer, &sub, &canvas, NULL);
gui_buffer_end(NULL, &buffer, NULL, NULL);
}
```
@ -277,62 +277,6 @@ 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.

View File

@ -320,7 +320,7 @@ surface_del(XSurface *surf)
}
static void
execute(XSurface *surf, const struct gui_command_list *list)
draw(XSurface *surf, struct gui_command_list *list)
{
const struct gui_command *cmd;
if (!list->count) return;
@ -361,18 +361,6 @@ execute(XSurface *surf, const struct gui_command_list *list)
}
}
static void
draw(XSurface *surf, struct gui_output *out)
{
const struct gui_command_list *iter;
if (!out->size) return;
iter = out->begin;
while (iter) {
execute(surf, iter);
iter = iter->next;
}
}
static void
key(struct XWindow *xw, struct gui_input *in, XEvent *evt, gui_bool down)
{
@ -487,12 +475,16 @@ main(int argc, char *argv[])
struct gui_input in;
struct gui_font font;
struct gui_memory memory;
struct gui_memory_status status;
struct gui_config config;
struct gui_output_buffer buffer;
struct gui_output output;
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_panel_layout layout;
struct gui_window win;
struct gui_window msg;
struct gui_panel panel;
struct gui_panel msg;
/* Window */
UNUSED(argc); UNUSED(argv);
@ -517,26 +509,23 @@ main(int argc, char *argv[])
xw.surf = surface_create(xw.dpy, xw.screen, xw.win, xw.width, xw.height);
xw.font = font_create(xw.dpy, "fixed");
/* GUI */
memset(&in, 0, sizeof in);
memory.memory = calloc(MAX_MEMORY, 1);
memory.size = MAX_MEMORY;
gui_output_init_fixed(&buffer, &memory);
gui_buffer_init_fixed(&buffer, &memory, GUI_BUFFER_CLIPPING);
font.userdata = xw.font;
font.height = (gui_float)xw.font->height;
font.width = font_get_text_width;
gui_default_config(&config);
gui_panel_init(&win.panel, 50, 50, 420, 300,
gui_panel_init(&panel, 50, 50, 420, 300,
GUI_PANEL_BORDER|GUI_PANEL_MOVEABLE|
GUI_PANEL_CLOSEABLE|GUI_PANEL_SCALEABLE|
GUI_PANEL_MINIMIZABLE, &config, &font);
gui_panel_init(&msg.panel, 150, 150, 200, 80,
gui_panel_init(&msg, 150, 150, 200, 80,
GUI_PANEL_BORDER|GUI_PANEL_MOVEABLE, &config, &font);
/* Demo */
memset(&demo, 0, sizeof(demo));
demo.tab_min = gui_true;
@ -562,22 +551,27 @@ main(int argc, char *argv[])
gui_input_end(&in);
/* GUI */
gui_output_begin(&buffer, xw.width, xw.height);
running = gui_window_begin(&layout, &win, &buffer, "Demo", &in);
gui_buffer_begin(NULL, &buffer, xw.width, xw.height);
gui_buffer_lock(&canvas, &buffer, &sub, 0, xw.width, xw.height);
running = gui_panel_begin(&layout, &panel, "Demo", &canvas, &in);
demo_panel(&layout, &demo);
gui_window_end(&layout, &win, &buffer, NULL);
gui_panel_end(&layout, &panel);
gui_buffer_unlock(&panel_list, &buffer, &sub, &canvas, NULL);
gui_window_begin(&layout, &msg, &buffer, "Error", &in);
gui_buffer_lock(&canvas, &buffer, &sub, 0, xw.width, xw.height);
running = 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_window_end(&layout, &msg, &buffer, NULL);
gui_output_end(&output, &buffer, NULL);
gui_panel_end(&layout, &panel);
gui_buffer_unlock(&msg_list, &buffer, &sub, &canvas, NULL);
gui_buffer_end(NULL, &buffer, NULL, NULL);
/* Draw */
XClearWindow(xw.dpy, xw.win);
surface_clear(xw.surf, 0x00646464);
draw(xw.surf, &output);
draw(xw.surf, &panel_list);
draw(xw.surf, &msg_list);
surface_blit(xw.win, xw.surf, xw.width, xw.height);
XFlush(xw.dpy);
@ -597,4 +591,3 @@ main(int argc, char *argv[])
return 0;
}

243
gui.c
View File

@ -1140,7 +1140,6 @@ void
gui_buffer_begin(struct gui_canvas *canvas, struct gui_command_buffer *buffer,
gui_size width, gui_size height)
{
ASSERT(canvas);
ASSERT(buffer);
ASSERT(buffer->memory);
ASSERT(buffer->begin == buffer->end);
@ -1318,15 +1317,25 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel,
layout->header_height = panel->font.height + 3 * config->item_padding.y;
layout->header_height += config->panel_padding.y;
if (!(panel->flags & GUI_PANEL_TAB)) {
panel->flags |= GUI_PANEL_SCROLLBAR;
clicked_x = (in) ? in->mouse_clicked_pos.x : -1;
clicked_y = (in) ? in->mouse_clicked_pos.y : -1;
if (in && in->mouse_down) {
if (!INBOX(clicked_x, clicked_y, panel->x, panel->y, panel->w, panel->h))
panel->flags &= (gui_flag)~GUI_PANEL_ACTIVE;
else panel->flags |= GUI_PANEL_ACTIVE;
}
}
mouse_x = (in) ? in->mouse_pos.x : -1;
mouse_y = (in) ? in->mouse_pos.y : -1;
prev_x = (in) ? in->mouse_prev.x : -1;
prev_y = (in) ? in->mouse_prev.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) {
if ((panel->flags & GUI_PANEL_MOVEABLE) && (panel->flags & GUI_PANEL_ACTIVE)) {
gui_bool incursor;
const gui_float move_x = panel->x;
const gui_float move_y = panel->y;
@ -1340,7 +1349,7 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel,
}
}
if (panel->flags & GUI_PANEL_SCALEABLE) {
if ((panel->flags & GUI_PANEL_SCALEABLE) && (panel->flags & GUI_PANEL_ACTIVE)) {
gui_bool incursor;
gui_float scaler_x = panel->x + config->item_padding.x;
gui_float scaler_y = panel->y + panel->h - config->scaler_size.y;
@ -1380,15 +1389,6 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel,
canvas->draw_rect(canvas->userdata, panel->x, panel->y, panel->w,
layout->header_height, *header);
if (!(panel->flags & GUI_PANEL_TAB)) {
panel->flags |= GUI_PANEL_SCROLLBAR;
if (in && in->mouse_down) {
if (!INBOX(clicked_x, clicked_y, panel->x, panel->y, panel->w, panel->h))
panel->flags &= (gui_flag)~GUI_PANEL_ACTIVE;
else panel->flags |= GUI_PANEL_ACTIVE;
}
}
layout->clip.x = panel->x;
layout->clip.w = panel->w;
layout->clip.y = panel->y + layout->header_height - 1;
@ -1482,36 +1482,6 @@ 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)
{
@ -2772,49 +2742,6 @@ 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;
}
void
gui_pool_init(struct gui_pool *pool, const struct gui_allocator *allocator,
gui_size panel_size, gui_size offset, gui_size panels_per_page)
@ -2941,147 +2868,3 @@ gui_pool_clear(struct gui_pool *pool)
pool->allocator.free(pool->allocator.userdata, pool->base.memory);
}
void
gui_output_init(struct gui_output_buffer *out, const struct gui_allocator *alloc,
gui_size initial, gui_float grow_factor)
{
ASSERT(out);
ASSERT(initial);
if (!out || !initial) return;
zero(out, sizeof(*out));
gui_buffer_init(&out->global, alloc, initial, grow_factor, GUI_BUFFER_CLIPPING);
}
void
gui_output_init_fixed(struct gui_output_buffer *out, struct gui_memory *memory)
{
ASSERT(out);
ASSERT(memory);
if (!out || !memory) return;
zero(out, sizeof(*out));
gui_buffer_init_fixed(&out->global, memory, 0);
}
void
gui_output_begin(struct gui_output_buffer *buffer, gui_size width, gui_size height)
{
ASSERT(buffer);
if (!buffer) return;
buffer->width = width;
buffer->height = height;
buffer->out.begin = NULL;
buffer->out.end = NULL;
buffer->out.size = 0;
}
static void
gui_output_begin_window(struct gui_output_buffer *buffer, struct gui_window *win)
{
gui_buffer_lock(&buffer->canvas, &buffer->global, &buffer->current, 0, buffer->width, buffer->height);
if (!buffer->out.begin) {
buffer->out.begin = &win->list;
buffer->out.end = buffer->out.begin;
buffer->out.size++;
win->list.next = NULL;
} else {
buffer->out.end->next = &win->list;
buffer->out.end = &win->list;
win->list.next = NULL;
buffer->out.size++;
}
}
static void
gui_output_end_window(struct gui_output_buffer *buffer, struct gui_window *win,
struct gui_memory_status *status)
{
gui_buffer_unlock(&win->list, &buffer->global, &buffer->current, &buffer->canvas, status);
}
void
gui_output_end(struct gui_output *output, struct gui_output_buffer *buffer,
struct gui_memory_status *status)
{
ASSERT(output);
ASSERT(buffer);
if (!output || !buffer) return;
gui_buffer_end(NULL, &buffer->global, NULL, status);
*output = buffer->out;
}
static void
gui_output_sort(struct gui_output_buffer *buffer, struct gui_panel_stack *stack)
{
struct gui_window *win;
struct gui_panel *iter = stack->begin;
if (!iter) return;
win = (void*)stack->begin;
buffer->out.begin = &win->list;
buffer->out.end = buffer->out.begin;;
iter = iter->next;
while (iter) {
win = (void*)iter;
win->list.next = buffer->out.end;
buffer->out.end = &win->list;
iter = iter->next;
}
}
void
gui_output_end_ordered(struct gui_output *output, struct gui_output_buffer *buffer,
struct gui_panel_stack *stack, struct gui_memory_status *status)
{
ASSERT(output);
ASSERT(buffer);
ASSERT(stack);
if (!output || !buffer || !stack) return;
gui_buffer_end(NULL, &buffer->global, NULL, status);
gui_output_sort(buffer, stack);
*output = buffer->out;
}
void
gui_output_clear(struct gui_output_buffer *buffer)
{
ASSERT(buffer);
if (!buffer) return;
gui_buffer_clear(&buffer->global);
}
gui_bool
gui_window_begin(struct gui_panel_layout *layout, struct gui_window *win,
struct gui_output_buffer *buffer, const char *title, const struct gui_input *in)
{
ASSERT(win);
ASSERT(buffer);
if (!buffer | !win) return gui_false;
gui_output_begin_window(buffer, win);
return gui_panel_begin(layout, &win->panel, title, &buffer->canvas, in);
}
gui_bool
gui_window_begin_stacked(struct gui_panel_layout *layout, struct gui_window *win,
struct gui_output_buffer *buffer, struct gui_panel_stack *stack,
const char* title, const struct gui_input *in)
{
ASSERT(win);
ASSERT(buffer);
if (!buffer | !win) return gui_false;
gui_output_begin_window(buffer, win);
return gui_panel_begin_stacked(layout, &win->panel, stack, title, &buffer->canvas, in);
}
void
gui_window_end(struct gui_panel_layout *layout, struct gui_window *win,
struct gui_output_buffer *buffer, struct gui_memory_status *status)
{
ASSERT(buffer);
ASSERT(win);
if (!buffer || !win) return;
gui_panel_end(layout, &win->panel);
gui_output_end_window(buffer, win, status);
}

56
gui.h
View File

@ -419,17 +419,6 @@ struct gui_panel_layout {
const struct gui_canvas *canvas;
};
struct gui_window {
struct gui_panel panel;
struct gui_command_list list;
};
struct gui_panel_stack {
gui_size count;
struct gui_panel *begin;
struct gui_panel *end;
};
struct gui_pool_page {
struct gui_pool_page *next;
void *memory;
@ -448,20 +437,6 @@ struct gui_pool {
struct gui_panel *free_list;
};
struct gui_output {
struct gui_command_list *begin;
struct gui_command_list *end;
gui_size size;
};
struct gui_output_buffer {
gui_size width, height;
struct gui_canvas canvas;
struct gui_command_buffer global;
struct gui_command_buffer current;
struct gui_output out;
};
/* Input */
gui_size gui_utf_decode(const gui_char*, gui_long*, gui_size);
gui_size gui_utf_encode(gui_long, gui_char*, gui_size);
@ -550,9 +525,6 @@ 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 *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_alloc_space(struct gui_rect*, struct gui_panel_layout*);
void gui_panel_seperator(struct gui_panel_layout*, gui_size cols);
@ -608,12 +580,6 @@ gui_float gui_panel_shelf_end(struct gui_panel_layout*, struct gui_panel_layout
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*);
/* Pool */
void gui_pool_init(struct gui_pool*, const struct gui_allocator*,
gui_size panel_size, gui_size offset, gui_size panels_per_page);
@ -624,28 +590,6 @@ void gui_pool_free(struct gui_pool*, void*);
void gui_pool_clear(struct gui_pool*);
/* Output */
void gui_output_init(struct gui_output_buffer*, const struct gui_allocator*,
gui_size initial, gui_float grow_factor);
void gui_output_init_fixed(struct gui_output_buffer*, struct gui_memory *memory);
void gui_output_begin(struct gui_output_buffer*, gui_size width, gui_size height);
void gui_output_end(struct gui_output*, struct gui_output_buffer*,
struct gui_memory_status*);
void gui_output_end_ordered(struct gui_output*, struct gui_output_buffer*,
struct gui_panel_stack*, struct gui_memory_status*);
void gui_output_clear(struct gui_output_buffer*);
/* Window */
gui_bool gui_window_begin(struct gui_panel_layout *layout, struct gui_window *win,
struct gui_output_buffer *buffer, const char*, const struct gui_input *in);
gui_bool gui_window_begin_stacked(struct gui_panel_layout*, struct gui_window*,
struct gui_output_buffer*, struct gui_panel_stack*, const char*,
const struct gui_input*);
void gui_window_end(struct gui_panel_layout*, struct gui_window*,
struct gui_output_buffer*, struct gui_memory_status*);
#ifdef __cplusplus
}
#endif