fixed some stuff + created extensive demo
This commit is contained in:
parent
5f9b1aef0f
commit
24380a2dcf
64
Readme.md
64
Readme.md
|
@ -18,48 +18,12 @@ possible with fast streamlined development speed in mind.
|
|||
- Configurable
|
||||
- UTF-8 support
|
||||
|
||||
## Functionality
|
||||
+ Label
|
||||
+ Buttons
|
||||
+ Slider
|
||||
+ Progressbar
|
||||
+ Checkbox
|
||||
+ Radiobutton
|
||||
+ Input
|
||||
+ Shell
|
||||
+ Spinner
|
||||
+ Selector
|
||||
+ Linegraph
|
||||
+ Histogram
|
||||
+ Table
|
||||
+ Panel
|
||||
+ Tab
|
||||
+ Group
|
||||
+ Shelf
|
||||
|
||||
## Limitations
|
||||
- Does NOT provide os window/input management
|
||||
- Does NOT provide a renderer backend
|
||||
- Does NOT implement a font library
|
||||
Summary: It is only responsible for the actual user interface
|
||||
|
||||
## IMGUIs
|
||||
Immediate mode in contrast to classical retained mode GUIs store as little state as possible
|
||||
by using procedural function calls as "widgets" instead of storing objects.
|
||||
Each "widget" function call takes hereby all its necessary data and immediately returns
|
||||
the through the user modified state back to the caller. Immediate mode graphical
|
||||
user interfaces therefore combine drawing and input handling into one unit
|
||||
instead of separating them like retain mode GUIs.
|
||||
|
||||
Since there is no to minimal internal state in immediate mode user interfaces,
|
||||
updates have to occur every frame which on one hand is more drawing expensive than classic
|
||||
retained GUI implementations but on the other hand grants a lot more flexibility and
|
||||
support for overall layout changes. In addition without any state there is no
|
||||
duplicated state between your program, the gui and the user which greatly
|
||||
simplifies code. Further traits of immediate mode graphic user interfaces are a
|
||||
code driven style, centralized flow control, easy extensibility and
|
||||
understandability.
|
||||
|
||||
## Example
|
||||
```c
|
||||
struct gui_input input = {0};
|
||||
|
@ -111,14 +75,22 @@ while (1) {
|
|||
```
|
||||
![gui screenshot](/screen.png?raw=true)
|
||||
|
||||
## API
|
||||
The API for this gui toolkit is divided into two different layers. There
|
||||
is the widget layer and the panel layer. The widget layer provides a number of
|
||||
classical widgets in functional immediate mode form without any kind of internal
|
||||
state. Each widget can be placed anywhere on the screen but there is no direct
|
||||
way provided to group widgets together. For this to change there is the panel
|
||||
layer which is build on top of the widget layer and uses most of the widget API
|
||||
internally to form groups of widgets into a layout.
|
||||
## IMGUIs
|
||||
Immediate mode in contrast to classical retained mode GUIs store as little state as possible
|
||||
by using procedural function calls as "widgets" instead of storing objects.
|
||||
Each "widget" function call takes hereby all its necessary data and immediately returns
|
||||
the through the user modified state back to the caller. Immediate mode graphical
|
||||
user interfaces therefore combine drawing and input handling into one unit
|
||||
instead of separating them like retain mode GUIs.
|
||||
|
||||
Since there is no to minimal internal state in immediate mode user interfaces,
|
||||
updates have to occur every frame which on one hand is more drawing expensive than classic
|
||||
retained GUI implementations but on the other hand grants a lot more flexibility and
|
||||
support for overall layout changes. In addition without any state there is no
|
||||
duplicated state between your program, the gui and the user which greatly
|
||||
simplifies code. Further traits of immediate mode graphic user interfaces are a
|
||||
code driven style, centralized flow control, easy extensibility and
|
||||
understandability.
|
||||
|
||||
### Input
|
||||
The `gui_input` struct holds the user input over the course of the frame and
|
||||
|
@ -198,9 +170,9 @@ while (1) {
|
|||
}
|
||||
|
||||
```
|
||||
For the purpose of implementing overlapping panels sub buffers were implemented.
|
||||
For the purpose of implementing multible panels, sub buffers were implemented.
|
||||
With sub buffers you can create one global buffer which owns the allocated memory
|
||||
and sub buffers which directly reference the global buffer. Biggest
|
||||
and sub buffers which directly reference the global buffer. The biggest
|
||||
advantage is that you do not have to allocate a buffer for each panel and boil
|
||||
down the memory management to a single buffer.
|
||||
|
||||
|
|
127
demo/xlib.c
127
demo/xlib.c
|
@ -12,9 +12,6 @@
|
|||
#include "../gui.h"
|
||||
|
||||
/* macros */
|
||||
#define MAX_BUFFER 64
|
||||
#define MAX_MEMORY (8 * 1024)
|
||||
#define MAX_PANELS 4
|
||||
#define WIN_WIDTH 800
|
||||
#define WIN_HEIGHT 600
|
||||
#define DTIME 16
|
||||
|
@ -25,6 +22,8 @@
|
|||
#define LEN(a) (sizeof(a)/sizeof(a)[0])
|
||||
#define UNUSED(a) ((void)(a))
|
||||
|
||||
#include "demo.c"
|
||||
|
||||
typedef struct XFont XFont;
|
||||
typedef struct XSurface XSurface;
|
||||
typedef struct XWindow XWindow;
|
||||
|
@ -62,27 +61,6 @@ struct XWindow {
|
|||
unsigned int height;
|
||||
};
|
||||
|
||||
struct demo {
|
||||
gui_char in_buf[MAX_BUFFER];
|
||||
gui_size in_len;
|
||||
gui_bool in_act;
|
||||
gui_char cmd_buf[MAX_BUFFER];
|
||||
gui_size cmd_len;
|
||||
gui_bool cmd_act;
|
||||
gui_bool check;
|
||||
gui_int option;
|
||||
gui_float slider;
|
||||
gui_size prog;
|
||||
gui_int spinner;
|
||||
gui_bool spin_act;
|
||||
gui_size item_cur;
|
||||
gui_size cur;
|
||||
gui_bool tab_min;
|
||||
gui_float group_off;
|
||||
gui_float shelf_off;
|
||||
gui_bool toggle;
|
||||
};
|
||||
|
||||
static void
|
||||
die(const char *fmt, ...)
|
||||
{
|
||||
|
@ -320,7 +298,7 @@ surface_del(XSurface *surf)
|
|||
}
|
||||
|
||||
static void
|
||||
draw(XSurface *surf, struct gui_command_list *list)
|
||||
execute(XSurface *surf, struct gui_command_list *list)
|
||||
{
|
||||
const struct gui_command *cmd;
|
||||
if (!list->count) return;
|
||||
|
@ -355,12 +333,26 @@ draw(XSurface *surf, struct gui_command_list *list)
|
|||
surface_draw_text(surf, t->x, t->y, t->w, t->h, (const char*)t->string,
|
||||
t->length, t->font, t->bg, t->fg);
|
||||
} break;
|
||||
case GUI_COMMAND_IMAGE:
|
||||
case GUI_COMMAND_MAX:
|
||||
default: break;
|
||||
}
|
||||
cmd = gui_list_next(list, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw(XSurface *surf, struct gui_panel_stack *stack)
|
||||
{
|
||||
struct gui_panel *iter = stack->begin;
|
||||
if (!stack->count) return;
|
||||
while (iter) {
|
||||
struct gui_window *win = (void*)iter;
|
||||
execute(surf, &win->list);
|
||||
iter = iter->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
key(struct XWindow *xw, struct gui_input *in, XEvent *evt, gui_bool down)
|
||||
{
|
||||
|
@ -412,55 +404,6 @@ resize(struct XWindow *xw, XSurface *surf)
|
|||
surface_resize(surf, xw->width, xw->height);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_panel(struct gui_panel_layout *panel, struct demo *demo)
|
||||
{
|
||||
gui_int i = 0;
|
||||
enum {HISTO, PLOT};
|
||||
const char *shelfs[] = {"Histogram", "Lines"};
|
||||
const gui_float values[] = {8.0f, 15.0f, 20.0f, 12.0f, 30.0f};
|
||||
const char *items[] = {"Fist", "Pistol", "Shotgun", "Railgun", "BFG"};
|
||||
const char *options[] = {"easy", "normal", "hard", "hell", "doom", "godlike"};
|
||||
struct gui_panel_layout tab;
|
||||
|
||||
/* Tabs */
|
||||
demo->tab_min = gui_panel_tab_begin(panel, &tab, "Difficulty", demo->tab_min);
|
||||
gui_panel_row(&tab, 30, 3);
|
||||
for (i = 0; i < (gui_int)LEN(options); i++) {
|
||||
if (gui_panel_option(&tab, options[i], demo->option == i))
|
||||
demo->option = i;
|
||||
}
|
||||
gui_panel_tab_end(panel, &tab);
|
||||
|
||||
/* Shelf */
|
||||
gui_panel_row(panel, 200, 2);
|
||||
demo->cur = gui_panel_shelf_begin(panel,&tab,shelfs,LEN(shelfs),demo->cur,demo->shelf_off);
|
||||
gui_panel_row(&tab, 100, 1);
|
||||
if (demo->cur == HISTO) {
|
||||
gui_panel_graph(&tab, GUI_GRAPH_HISTO, values, LEN(values));
|
||||
} else {
|
||||
gui_panel_graph(&tab, GUI_GRAPH_LINES, values, LEN(values));
|
||||
}
|
||||
demo->shelf_off = gui_panel_shelf_end(panel, &tab);
|
||||
|
||||
/* Group */
|
||||
gui_panel_group_begin(panel, &tab, "Options", demo->group_off);
|
||||
gui_panel_row(&tab, 30, 1);
|
||||
if (gui_panel_button_text(&tab, "button", GUI_BUTTON_DEFAULT))
|
||||
fprintf(stdout, "button pressed!\n");
|
||||
demo->toggle = gui_panel_button_toggle(&tab, "toggle", demo->toggle);
|
||||
demo->check = gui_panel_check(&tab, "advanced", demo->check);
|
||||
demo->slider = gui_panel_slider(&tab, 0, demo->slider, 10, 1.0f);
|
||||
demo->prog = gui_panel_progress(&tab, demo->prog, 100, gui_true);
|
||||
demo->item_cur = gui_panel_selector(&tab, items, LEN(items), demo->item_cur);
|
||||
demo->spinner = gui_panel_spinner(&tab, 0, demo->spinner, 250, 10, &demo->spin_act);
|
||||
if (gui_panel_shell(&tab, demo->cmd_buf, &demo->cmd_len, MAX_BUFFER, &demo->cmd_act))
|
||||
demo->cmd_len = 0;
|
||||
demo->in_len = gui_panel_edit(&tab, demo->in_buf, demo->in_len,
|
||||
MAX_BUFFER, &demo->in_act, GUI_INPUT_DEFAULT);
|
||||
demo->group_off = gui_panel_group_end(panel, &tab);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -469,24 +412,16 @@ main(int argc, char *argv[])
|
|||
long started;
|
||||
XWindow xw;
|
||||
gui_bool running = gui_true;
|
||||
struct demo demo;
|
||||
|
||||
/* GUI */
|
||||
struct gui_input in;
|
||||
struct gui_font font;
|
||||
struct gui_memory memory;
|
||||
struct gui_memory_status status;
|
||||
struct gui_config config;
|
||||
struct gui_canvas canvas;
|
||||
struct gui_command_buffer buffer;
|
||||
struct gui_command_list list;
|
||||
struct gui_panel_layout layout;
|
||||
struct gui_panel panel;
|
||||
|
||||
gui_size option = 0;
|
||||
gui_char buf[256];
|
||||
gui_size len = 0;
|
||||
gui_bool active;
|
||||
struct gui_panel_stack stack;
|
||||
struct show_window show;
|
||||
struct control_window control;
|
||||
|
||||
/* Window */
|
||||
UNUSED(argc); UNUSED(argv);
|
||||
|
@ -521,18 +456,8 @@ main(int argc, char *argv[])
|
|||
font.height = (gui_float)xw.font->height;
|
||||
font.width = font_get_text_width;
|
||||
gui_default_config(&config);
|
||||
gui_panel_init(&panel, 50, 50, 400, 320,
|
||||
GUI_PANEL_BORDER|GUI_PANEL_MOVEABLE|
|
||||
GUI_PANEL_CLOSEABLE|GUI_PANEL_SCALEABLE|
|
||||
GUI_PANEL_MINIMIZABLE, &config, &font);
|
||||
|
||||
/* Demo */
|
||||
memset(&demo, 0, sizeof(demo));
|
||||
demo.tab_min = gui_true;
|
||||
demo.spinner = 100;
|
||||
demo.slider = 2.0f;
|
||||
demo.prog = 60;
|
||||
demo.cur = 1;
|
||||
gui_stack_clear(&stack);
|
||||
init_demo(&show, &control, &stack, &config, &font);
|
||||
|
||||
while (running) {
|
||||
/* Input */
|
||||
|
@ -551,16 +476,12 @@ main(int argc, char *argv[])
|
|||
gui_input_end(&in);
|
||||
|
||||
/* GUI */
|
||||
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_end(&list, &buffer, &canvas, &status);
|
||||
running = run_demo(&show, &control, &stack, &config, &in, &buffer, xw.width, xw.height);
|
||||
|
||||
/* Draw */
|
||||
XClearWindow(xw.dpy, xw.win);
|
||||
surface_clear(xw.surf, 0x00646464);
|
||||
draw(xw.surf, &list);
|
||||
draw(xw.surf, &stack);
|
||||
surface_blit(xw.win, xw.surf, xw.width, xw.height);
|
||||
XFlush(xw.dpy);
|
||||
|
||||
|
|
55
gui.c
55
gui.c
|
@ -843,6 +843,7 @@ gui_buffer_push(struct gui_command_buffer* buffer,
|
|||
cap = (gui_size)((gui_float)buffer->capacity * buffer->grow_factor);
|
||||
buffer->memory = buffer->allocator.realloc(buffer->allocator.userdata,buffer->memory, cap);
|
||||
if (!buffer->memory) return NULL;
|
||||
|
||||
buffer->capacity = cap;
|
||||
buffer->begin = buffer->memory;
|
||||
buffer->end = (void*)((gui_byte*)buffer->begin + buffer->allocated);
|
||||
|
@ -1006,7 +1007,8 @@ gui_buffer_push_image(struct gui_command_buffer *buffer, gui_float x, gui_float
|
|||
return;
|
||||
}
|
||||
}
|
||||
cmd = gui_buffer_push(buffer, GUI_COMMAND_RECT, sizeof(*cmd));
|
||||
|
||||
cmd = gui_buffer_push(buffer, GUI_COMMAND_IMAGE, sizeof(*cmd));
|
||||
if (!cmd) return;
|
||||
cmd->x = (gui_short)x;
|
||||
cmd->y = (gui_short)y;
|
||||
|
@ -1035,6 +1037,7 @@ gui_buffer_push_text(struct gui_command_buffer *buffer, gui_float x, gui_float y
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cmd = gui_buffer_push(buffer, GUI_COMMAND_TEXT, sizeof(*cmd) + length + 1);
|
||||
if (!cmd) return;
|
||||
cmd->x = (gui_short)x;
|
||||
|
@ -1285,7 +1288,6 @@ gui_panel_init(struct gui_panel *panel, gui_float x, gui_float y, gui_float w,
|
|||
panel->y = y;
|
||||
panel->w = w;
|
||||
panel->h = h;
|
||||
panel->flags = 0;
|
||||
panel->flags = flags;
|
||||
panel->config = config;
|
||||
panel->font = *font;
|
||||
|
@ -1312,8 +1314,13 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel,
|
|||
|
||||
if (!panel || !canvas || !layout)
|
||||
return gui_false;
|
||||
if (panel->flags & GUI_PANEL_HIDDEN)
|
||||
if (panel->flags & GUI_PANEL_HIDDEN) {
|
||||
zero(layout, sizeof(*layout));
|
||||
layout->valid = gui_false;
|
||||
layout->config = panel->config;
|
||||
layout->canvas = canvas;
|
||||
return gui_false;
|
||||
}
|
||||
|
||||
config = panel->config;
|
||||
layout->header_height = panel->font.height + 3 * config->item_padding.y;
|
||||
|
@ -1323,7 +1330,6 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel,
|
|||
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;
|
||||
|
||||
|
@ -1345,8 +1351,8 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel,
|
|||
gui_bool incursor;
|
||||
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);
|
||||
gui_float scaler_x = (layout->x + layout->w) - (config->item_padding.x + scaler_w);
|
||||
gui_float scaler_y = layout->y + layout->h - config->scaler_size.y;
|
||||
gui_float scaler_x = (panel->x + panel->w) - (config->item_padding.x + scaler_w);
|
||||
gui_float scaler_y = panel->y + panel->h - config->scaler_size.y;
|
||||
|
||||
incursor = in && INBOX(prev_x, prev_y, scaler_x, scaler_y, scaler_w, scaler_h);
|
||||
if (in && in->mouse_down && incursor) {
|
||||
|
@ -1423,7 +1429,7 @@ gui_panel_begin(struct gui_panel_layout *layout, struct gui_panel *panel,
|
|||
if (INBOX(mouse_x, mouse_y, close_x, close_y, close_w, close_h)) {
|
||||
if (INBOX(clicked_x, clicked_y, close_x, close_y, close_w, close_h)) {
|
||||
ret = !(in->mouse_down && in->mouse_clicked);
|
||||
if (ret) panel->flags |= GUI_PANEL_HIDDEN;
|
||||
if (!ret) panel->flags |= GUI_PANEL_HIDDEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1509,9 +1515,8 @@ gui_panel_begin_stacked(struct gui_panel_layout *layout, struct gui_panel *panel
|
|||
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;
|
||||
if (INBOX(in->mouse_prev.x, in->mouse_prev.y, iter->x, iter->y, iter->w, iter->h) &&
|
||||
!iter->minimized) break;
|
||||
iter = iter->next;
|
||||
}
|
||||
if (!iter) {
|
||||
|
@ -1574,6 +1579,8 @@ gui_panel_alloc_space(struct gui_rect *bounds, struct gui_panel_layout *layout)
|
|||
ASSERT(layout);
|
||||
ASSERT(layout->config);
|
||||
ASSERT(bounds);
|
||||
if (!layout || !layout->config || !bounds)
|
||||
return;
|
||||
|
||||
config = layout->config;
|
||||
if (layout->index >= layout->row_columns) {
|
||||
|
@ -1644,7 +1651,6 @@ gui_panel_label(struct gui_panel_layout *layout, const char *text, enum gui_text
|
|||
gui_panel_text(layout, text, len, align);
|
||||
}
|
||||
|
||||
|
||||
gui_bool
|
||||
gui_panel_button_text(struct gui_panel_layout *layout, const char *str,
|
||||
enum gui_button_behavior behavior)
|
||||
|
@ -1704,7 +1710,7 @@ gui_bool gui_panel_button_color(struct gui_panel_layout *layout,
|
|||
button.background = color;
|
||||
button.foreground = color;
|
||||
button.highlight = color;
|
||||
button.highlight_content = config->colors[GUI_COLOR_BUTTON_HOVER_FONT];
|
||||
button.highlight_content = color;
|
||||
return gui_do_button(layout->canvas, bounds.x, bounds.y, bounds.w, bounds.h,
|
||||
&button, layout->input, behavior);
|
||||
}
|
||||
|
@ -2054,18 +2060,18 @@ gui_panel_spinner(struct gui_panel_layout *layout, gui_int min, gui_int value,
|
|||
ASSERT(layout->config);
|
||||
ASSERT(layout->canvas);
|
||||
|
||||
if (!layout || !layout->config || !layout->canvas) return 0;
|
||||
if (!layout->valid) return 0;
|
||||
if (!layout || !layout->config || !layout->canvas) return value;
|
||||
if (!layout->valid) return value;
|
||||
gui_panel_alloc_space(&bounds, layout);
|
||||
config = layout->config;
|
||||
canvas = layout->canvas;
|
||||
c = &layout->clip;
|
||||
if (!INTERSECT(c->x, c->y, c->w, c->h, bounds.x, bounds.y, bounds.w, bounds.h))
|
||||
return 0;
|
||||
return value;
|
||||
|
||||
value = CLAMP(min, value, max);
|
||||
len = itos(string, value);
|
||||
is_active = *active;
|
||||
is_active = (active) ? *active : gui_false;
|
||||
old_len = len;
|
||||
|
||||
button.border = 1;
|
||||
|
@ -2105,7 +2111,7 @@ gui_panel_spinner(struct gui_panel_layout *layout, gui_int min, gui_int value,
|
|||
len, MAX_NUMBER_BUFFER, &is_active, &field, layout->input, &layout->font);
|
||||
if (old_len != len)
|
||||
strtoi(&value, string, len);
|
||||
*active = is_active;
|
||||
if (active) *active = is_active;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -2160,11 +2166,11 @@ gui_panel_selector(struct gui_panel_layout *layout, const char *items[],
|
|||
button.content = config->colors[GUI_COLOR_TEXT];
|
||||
button.highlight = config->colors[GUI_COLOR_BUTTON];
|
||||
button.highlight_content = config->colors[GUI_COLOR_TEXT];
|
||||
button_up_clicked = gui_button_triangle(canvas, button_x, button_y, button_w,
|
||||
button_down_clicked = gui_button_triangle(canvas, button_x, button_y, button_w,
|
||||
button_h, GUI_UP, GUI_BUTTON_DEFAULT, &button, layout->input);
|
||||
|
||||
button_y = bounds.y + button_h;
|
||||
button_down_clicked = gui_button_triangle(canvas, button_x, button_y, button_w,
|
||||
button_up_clicked = gui_button_triangle(canvas, button_x, button_y, button_w,
|
||||
button_h, GUI_DOWN, GUI_BUTTON_DEFAULT, &button, layout->input);
|
||||
item_current = (button_down_clicked && item_current < item_count-1) ?
|
||||
item_current+1 : (button_up_clicked && item_current > 0) ? item_current-1 : item_current;
|
||||
|
@ -2342,14 +2348,13 @@ gui_panel_graph(struct gui_panel_layout *layout, enum gui_graph_type type,
|
|||
struct gui_rect bounds;
|
||||
gui_float min_value;
|
||||
gui_float max_value;
|
||||
const struct gui_config *config;
|
||||
struct gui_graph graph;
|
||||
|
||||
ASSERT(layout);
|
||||
ASSERT(layout->config);
|
||||
ASSERT(layout->canvas);
|
||||
ASSERT(values);
|
||||
ASSERT(count);
|
||||
if (!layout || !values || !count)
|
||||
return -1;
|
||||
|
||||
max_value = values[0];
|
||||
min_value = values[0];
|
||||
|
@ -2378,13 +2383,13 @@ gui_panel_graph_ex(struct gui_panel_layout *layout, enum gui_graph_type type,
|
|||
struct gui_rect bounds;
|
||||
gui_float min_value;
|
||||
gui_float max_value;
|
||||
const struct gui_config *config;
|
||||
struct gui_graph graph;
|
||||
|
||||
ASSERT(layout);
|
||||
ASSERT(layout->config);
|
||||
ASSERT(layout->canvas);
|
||||
ASSERT(get_value);
|
||||
ASSERT(count);
|
||||
if (!layout || !get_value || !count)
|
||||
return -1;
|
||||
|
||||
max_value = get_value(userdata, 0);
|
||||
min_value = max_value;
|
||||
|
|
14
gui.h
14
gui.h
|
@ -228,7 +228,9 @@ enum gui_command_type {
|
|||
GUI_COMMAND_RECT,
|
||||
GUI_COMMAND_CIRCLE,
|
||||
GUI_COMMAND_TRIANGLE,
|
||||
GUI_COMMAND_TEXT
|
||||
GUI_COMMAND_TEXT,
|
||||
GUI_COMMAND_IMAGE,
|
||||
GUI_COMMAND_MAX
|
||||
};
|
||||
|
||||
struct gui_command {
|
||||
|
@ -399,11 +401,6 @@ struct gui_panel {
|
|||
struct gui_panel *prev;
|
||||
};
|
||||
|
||||
struct gui_window {
|
||||
struct gui_panel panel;
|
||||
struct gui_command_list list;
|
||||
};
|
||||
|
||||
struct gui_panel_layout {
|
||||
gui_float x, y, w, h;
|
||||
gui_float offset;
|
||||
|
@ -430,6 +427,11 @@ struct gui_panel_stack {
|
|||
struct gui_panel *end;
|
||||
};
|
||||
|
||||
struct gui_window {
|
||||
struct gui_panel panel;
|
||||
struct gui_command_list list;
|
||||
};
|
||||
|
||||
/* Input */
|
||||
gui_size gui_utf_decode(const gui_char*, gui_long*, gui_size);
|
||||
gui_size gui_utf_encode(gui_long, gui_char*, gui_size);
|
||||
|
|
Loading…
Reference in New Issue