multiple panels are working
This commit is contained in:
parent
5c2ffcae38
commit
1a83fff3e8
2
Makefile
2
Makefile
|
@ -31,5 +31,5 @@ clang: $(BIN)
|
||||||
$(BIN):
|
$(BIN):
|
||||||
@mkdir -p bin
|
@mkdir -p bin
|
||||||
rm -f bin/$(BIN) $(OBJS)
|
rm -f bin/$(BIN) $(OBJS)
|
||||||
$(CC) $(SRC) -D_POSIX_C_SOURCE=200809L $(CFLAGS) -o bin/$(BIN) -lX11 -lGL -lGLU
|
$(CC) $(SRC) -D_POSIX_C_SOURCE=200809L $(CFLAGS) -o bin/$(BIN) -lSDL2 -lGL -lGLU
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,8 @@
|
||||||
- Immediate graphical user interface
|
- Immediate graphical user interface
|
||||||
- Suited for embedding into graphical applications
|
- Suited for embedding into graphical applications
|
||||||
- Written in C89 (ANSI C)
|
- Written in C89 (ANSI C)
|
||||||
- Small (~1.5kLOC)
|
- Small (~2.5kLOC)
|
||||||
- Focus on portability and ease of use
|
- Focus on portability and ease of use
|
||||||
- Simplicity over extensive features
|
|
||||||
- no hidden states or global variables
|
- no hidden states or global variables
|
||||||
- Renderer independent
|
- Renderer independent
|
||||||
- No direct dependencies (not even libc)
|
- No direct dependencies (not even libc)
|
||||||
|
@ -17,10 +16,14 @@
|
||||||
|
|
||||||
## Gallery
|
## Gallery
|
||||||
|
|
||||||
|
## Panel
|
||||||
|
|
||||||
## Font
|
## Font
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
23
gui.c
23
gui.c
|
@ -15,7 +15,6 @@
|
||||||
#define SATURATE(x) (MAX(0, MIN(1.0f, x)))
|
#define SATURATE(x) (MAX(0, MIN(1.0f, x)))
|
||||||
#define LEN(a) (sizeof(a)/sizeof(a)[0])
|
#define LEN(a) (sizeof(a)/sizeof(a)[0])
|
||||||
#define ABS(a) (((a) < 0) ? -(a) : (a))
|
#define ABS(a) (((a) < 0) ? -(a) : (a))
|
||||||
#define UNUSED(a) ((void)(a))
|
|
||||||
#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
|
#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
|
||||||
#define INBOX(px, py, x, y, w, h) (BETWEEN(px, x, x+w) && BETWEEN(py, y, y+h))
|
#define INBOX(px, py, x, y, w, h) (BETWEEN(px, x, x+w) && BETWEEN(py, y, y+h))
|
||||||
#define ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0)
|
#define ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0)
|
||||||
|
@ -758,6 +757,7 @@ gui_widget_image(struct gui_draw_buffer *buffer, const struct gui_image *image)
|
||||||
gui_float image_w;
|
gui_float image_w;
|
||||||
gui_float image_h;
|
gui_float image_h;
|
||||||
if (!buffer || !image) return;
|
if (!buffer || !image) return;
|
||||||
|
|
||||||
image_x = image->x + image->pad_x;
|
image_x = image->x + image->pad_x;
|
||||||
image_y = image->y + image->pad_y;
|
image_y = image->y + image->pad_y;
|
||||||
image_w = MAX(0, image->w - 2 * image->pad_x);
|
image_w = MAX(0, image->w - 2 * image->pad_x);
|
||||||
|
@ -1321,6 +1321,7 @@ gui_widget_histo(struct gui_draw_buffer *buffer, const struct gui_histo *histo,
|
||||||
const gui_float item_y = (canvas_y + canvas_h) - item_h;
|
const gui_float item_y = (canvas_y + canvas_h) - item_h;
|
||||||
gui_float item_x = canvas_x + ((gui_float)i * item_w);
|
gui_float item_x = canvas_x + ((gui_float)i * item_w);
|
||||||
item_x = item_x + ((gui_float)i * histo->pad_y);
|
item_x = item_x + ((gui_float)i * histo->pad_y);
|
||||||
|
|
||||||
if (INBOX(in->mouse_pos.x, in->mouse_pos.y, item_x, item_y, item_w, item_h)) {
|
if (INBOX(in->mouse_pos.x, in->mouse_pos.y, item_x, item_y, item_w, item_h)) {
|
||||||
selected = (in->mouse_down && in->mouse_clicked) ? (gui_int)i: selected;
|
selected = (in->mouse_down && in->mouse_clicked) ? (gui_int)i: selected;
|
||||||
item_color = histo->highlight;
|
item_color = histo->highlight;
|
||||||
|
@ -1474,6 +1475,7 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out,
|
||||||
const struct gui_config *config;
|
const struct gui_config *config;
|
||||||
const struct gui_color *header;
|
const struct gui_color *header;
|
||||||
struct gui_rect clip;
|
struct gui_rect clip;
|
||||||
|
|
||||||
gui_float mouse_x, mouse_y;
|
gui_float mouse_x, mouse_y;
|
||||||
gui_float clicked_x, clicked_y;
|
gui_float clicked_x, clicked_y;
|
||||||
gui_float header_w = w;
|
gui_float header_w = w;
|
||||||
|
@ -1521,7 +1523,8 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out,
|
||||||
} else {
|
} else {
|
||||||
clip.x = x; clip.y = y;
|
clip.x = x; clip.y = y;
|
||||||
clip.w = w; clip.h = h;
|
clip.w = w; clip.h = h;
|
||||||
if (panel->flags & GUI_PANEL_SCROLLBAR) clip.h -= config->panel_padding.y;
|
if (panel->flags & GUI_PANEL_SCROLLBAR)
|
||||||
|
clip.h -= config->panel_padding.y;
|
||||||
panel->header_height = config->panel_padding.y + config->item_padding.y;
|
panel->header_height = config->panel_padding.y + config->item_padding.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1535,6 +1538,7 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out,
|
||||||
header_w -= ((gui_float)text_width + config->panel_padding.x);
|
header_w -= ((gui_float)text_width + config->panel_padding.x);
|
||||||
gui_draw_string(panel->out, panel->font, close_x, close_y, close_w, close_h,
|
gui_draw_string(panel->out, panel->font, close_x, close_y, close_w, close_h,
|
||||||
config->colors[GUI_COLOR_TEXT], X, 1);
|
config->colors[GUI_COLOR_TEXT], X, 1);
|
||||||
|
|
||||||
if (INBOX(mouse_x, mouse_y, close_x, close_y, close_w, close_h)) {
|
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))
|
if (INBOX(clicked_x, clicked_y, close_x, close_y, close_w, close_h))
|
||||||
ret = !(panel->in->mouse_down && panel->in->mouse_clicked);
|
ret = !(panel->in->mouse_down && panel->in->mouse_clicked);
|
||||||
|
@ -1555,6 +1559,7 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out,
|
||||||
min_h = panel->font->height + 2 * config->item_padding.y;
|
min_h = panel->font->height + 2 * config->item_padding.y;
|
||||||
gui_draw_string(panel->out, panel->font, min_x, min_y, min_w, min_h,
|
gui_draw_string(panel->out, panel->font, min_x, min_y, min_w, min_h,
|
||||||
config->colors[GUI_COLOR_TEXT], score, 1);
|
config->colors[GUI_COLOR_TEXT], score, 1);
|
||||||
|
|
||||||
if (INBOX(mouse_x, mouse_y, min_x, min_y, min_w, min_h)) {
|
if (INBOX(mouse_x, mouse_y, min_x, min_y, min_w, min_h)) {
|
||||||
if (INBOX(clicked_x, clicked_y, min_x, min_y, min_w, min_h))
|
if (INBOX(clicked_x, clicked_y, min_x, min_y, min_w, min_h))
|
||||||
if (panel->in->mouse_down && panel->in->mouse_clicked)
|
if (panel->in->mouse_down && panel->in->mouse_clicked)
|
||||||
|
@ -2284,6 +2289,7 @@ gui_panel_end(struct gui_panel *panel)
|
||||||
scroll.target = panel->at_y - panel->y;
|
scroll.target = panel->at_y - panel->y;
|
||||||
if (panel->flags & GUI_PANEL_HEADER)
|
if (panel->flags & GUI_PANEL_HEADER)
|
||||||
scroll.target -= panel->header_height;
|
scroll.target -= panel->header_height;
|
||||||
|
|
||||||
panel->offset = (gui_float)gui_widget_scroll(panel->out, &scroll, panel->in);
|
panel->offset = (gui_float)gui_widget_scroll(panel->out, &scroll, panel->in);
|
||||||
panel_y = panel->y + panel->height + panel->header_height - config->panel_padding.y;
|
panel_y = panel->y + panel->height + panel->header_height - config->panel_padding.y;
|
||||||
gui_draw_rectf(panel->out, panel->x, panel_y, panel->width, config->panel_padding.y,
|
gui_draw_rectf(panel->out, panel->x, panel_y, panel->width, config->panel_padding.y,
|
||||||
|
@ -2298,7 +2304,7 @@ gui_panel_end(struct gui_panel *panel)
|
||||||
panel->y + panel->header_height;
|
panel->y + panel->header_height;
|
||||||
|
|
||||||
gui_draw_line(panel->out, panel->x, padding_y, panel->x + width,
|
gui_draw_line(panel->out, panel->x, padding_y, panel->x + width,
|
||||||
padding_y, config->colors[GUI_COLOR_BORDER]);
|
padding_y, config->colors[GUI_COLOR_BORDER]);
|
||||||
gui_draw_line(panel->out, panel->x, panel->y, panel->x,
|
gui_draw_line(panel->out, panel->x, panel->y, panel->x,
|
||||||
padding_y, config->colors[GUI_COLOR_BORDER]);
|
padding_y, config->colors[GUI_COLOR_BORDER]);
|
||||||
gui_draw_line(panel->out, panel->x + width, panel->y, panel->x + width,
|
gui_draw_line(panel->out, panel->x + width, panel->y, panel->x + width,
|
||||||
|
@ -2449,7 +2455,6 @@ gui_begin_panel(struct gui_context *ctx, struct gui_panel *panel,
|
||||||
if (!ctx || !panel || !title)
|
if (!ctx || !panel || !title)
|
||||||
return gui_false;
|
return gui_false;
|
||||||
|
|
||||||
cpanel = CONTAINER_OF(panel, struct gui_context_panel, panel);
|
|
||||||
global = &ctx->global_buffer;
|
global = &ctx->global_buffer;
|
||||||
out = &ctx->buffer;
|
out = &ctx->buffer;
|
||||||
out->vertex_size = 0;
|
out->vertex_size = 0;
|
||||||
|
@ -2462,9 +2467,10 @@ gui_begin_panel(struct gui_context *ctx, struct gui_panel *panel,
|
||||||
out->vertex_capacity = global->vertex_capacity - global->vertex_size;
|
out->vertex_capacity = global->vertex_capacity - global->vertex_size;
|
||||||
out->commands = &global->commands[global->command_size];
|
out->commands = &global->commands[global->command_size];
|
||||||
out->command_capacity = global->command_capacity - global->command_size;
|
out->command_capacity = global->command_capacity - global->command_size;
|
||||||
out->clips = &global->clips[global->clip_size];
|
out->clips = global->clips;
|
||||||
out->clip_capacity = global->clip_capacity - global->clip_size;
|
out->clip_capacity = global->clip_capacity;
|
||||||
return gui_panel_begin(panel, &ctx->buffer, ctx->input, title,
|
cpanel = CONTAINER_OF(panel, struct gui_context_panel, panel);
|
||||||
|
return gui_panel_begin(panel, out, ctx->input, title,
|
||||||
cpanel->x, cpanel->y, cpanel->w, cpanel->h, flags);
|
cpanel->x, cpanel->y, cpanel->w, cpanel->h, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2475,13 +2481,12 @@ gui_end_panel(struct gui_context *ctx, struct gui_panel *panel,
|
||||||
struct gui_context_panel *cpanel;
|
struct gui_context_panel *cpanel;
|
||||||
struct gui_draw_buffer *global;
|
struct gui_draw_buffer *global;
|
||||||
if (!ctx || !panel) return;
|
if (!ctx || !panel) return;
|
||||||
|
|
||||||
cpanel = CONTAINER_OF(panel, struct gui_context_panel, panel);
|
cpanel = CONTAINER_OF(panel, struct gui_context_panel, panel);
|
||||||
gui_panel_end(panel);
|
gui_panel_end(panel);
|
||||||
|
|
||||||
global = &ctx->global_buffer;
|
global = &ctx->global_buffer;
|
||||||
global->vertex_size += ctx->buffer.vertex_size;
|
global->vertex_size += ctx->buffer.vertex_size;
|
||||||
global->command_size += ctx->buffer.command_size;
|
global->command_size += ctx->buffer.command_size;
|
||||||
global->clip_size += ctx->buffer.clip_size;
|
|
||||||
gui_output_end(&ctx->buffer, &cpanel->list, status);
|
gui_output_end(&ctx->buffer, &cpanel->list, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
gui.h
5
gui.h
|
@ -453,9 +453,8 @@ struct gui_context;
|
||||||
struct gui_context *gui_new(const struct gui_memory*, const struct gui_input*);
|
struct gui_context *gui_new(const struct gui_memory*, const struct gui_input*);
|
||||||
void gui_begin(struct gui_context*, gui_float width, gui_float height);
|
void gui_begin(struct gui_context*, gui_float width, gui_float height);
|
||||||
void gui_end(struct gui_context*, struct gui_output*, struct gui_memory_status*);
|
void gui_end(struct gui_context*, struct gui_output*, struct gui_memory_status*);
|
||||||
struct gui_panel *gui_panel_new(struct gui_context*,
|
struct gui_panel *gui_panel_new(struct gui_context*, gui_float x, gui_float y, gui_float w,
|
||||||
gui_float x, gui_float y, gui_float w, gui_float h, gui_flags,
|
gui_float h, gui_flags, const struct gui_config* , const struct gui_font*);
|
||||||
const struct gui_config* , const struct gui_font*);
|
|
||||||
void gui_panel_del(struct gui_context*, struct gui_panel*);
|
void gui_panel_del(struct gui_context*, struct gui_panel*);
|
||||||
gui_bool gui_begin_panel(struct gui_context*, struct gui_panel*, const char *title, gui_flags flags);
|
gui_bool gui_begin_panel(struct gui_context*, struct gui_panel*, const char *title, gui_flags flags);
|
||||||
void gui_end_panel(struct gui_context*, struct gui_panel*, struct gui_memory_status*);
|
void gui_end_panel(struct gui_context*, struct gui_panel*, struct gui_memory_status*);
|
||||||
|
|
13
opengl.c
13
opengl.c
|
@ -275,7 +275,6 @@ draw(int width, int height, struct gui_draw_call_list **list, gui_size count)
|
||||||
{
|
{
|
||||||
gui_size i = 0;
|
gui_size i = 0;
|
||||||
gui_size n = 0;
|
gui_size n = 0;
|
||||||
GLint offset = 0;
|
|
||||||
const gui_byte *vertexes;
|
const gui_byte *vertexes;
|
||||||
const struct gui_draw_command *cmd;
|
const struct gui_draw_command *cmd;
|
||||||
static const size_t v = sizeof(struct gui_vertex);
|
static const size_t v = sizeof(struct gui_vertex);
|
||||||
|
@ -304,6 +303,7 @@ draw(int width, int height, struct gui_draw_call_list **list, gui_size count)
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
for (n = 0; n < count; ++n) {
|
for (n = 0; n < count; ++n) {
|
||||||
|
GLint offset = 0;
|
||||||
vertexes = (const gui_char*)list[n]->vertexes;
|
vertexes = (const gui_char*)list[n]->vertexes;
|
||||||
glVertexPointer(2, GL_FLOAT, (GLsizei)v, (const void*)(vertexes + p));
|
glVertexPointer(2, GL_FLOAT, (GLsizei)v, (const void*)(vertexes + p));
|
||||||
glTexCoordPointer(2, GL_FLOAT, (GLsizei)v, (const void*)(vertexes + t));
|
glTexCoordPointer(2, GL_FLOAT, (GLsizei)v, (const void*)(vertexes + t));
|
||||||
|
@ -350,7 +350,6 @@ main(int argc, char *argv[])
|
||||||
struct gui_memory memory;
|
struct gui_memory memory;
|
||||||
struct gui_input input;
|
struct gui_input input;
|
||||||
struct gui_output output;
|
struct gui_output output;
|
||||||
gui_int id;
|
|
||||||
|
|
||||||
/* Window */
|
/* Window */
|
||||||
UNUSED(argc); UNUSED(argv);
|
UNUSED(argc); UNUSED(argv);
|
||||||
|
@ -374,15 +373,14 @@ main(int argc, char *argv[])
|
||||||
memory.clip_percentage = 0.01f;
|
memory.clip_percentage = 0.01f;
|
||||||
|
|
||||||
ctx = gui_new(&memory, &input);
|
ctx = gui_new(&memory, &input);
|
||||||
|
font = ldfont("mono.sdf", 16);
|
||||||
gui_default_config(&config);
|
gui_default_config(&config);
|
||||||
config.colors[GUI_COLOR_TEXT].r = 255;
|
config.colors[GUI_COLOR_TEXT].r = 255;
|
||||||
config.colors[GUI_COLOR_TEXT].g = 255;
|
config.colors[GUI_COLOR_TEXT].g = 255;
|
||||||
config.colors[GUI_COLOR_TEXT].b = 255;
|
config.colors[GUI_COLOR_TEXT].b = 255;
|
||||||
config.colors[GUI_COLOR_TEXT].a = 255;
|
config.colors[GUI_COLOR_TEXT].a = 255;
|
||||||
font = ldfont("mono.sdf", 16);
|
|
||||||
|
|
||||||
panel = gui_panel_new(ctx, 20, 20, 200, 200, 0, &config, font);
|
panel = gui_panel_new(ctx, 20, 20, 200, 200, 0, &config, font);
|
||||||
subpanel = gui_panel_new(ctx, 300, 20, 200, 200, 0, &config, font);
|
subpanel = gui_panel_new(ctx, 250, 20, 200, 200, 0, &config, font);
|
||||||
|
|
||||||
running = 1;
|
running = 1;
|
||||||
while (running) {
|
while (running) {
|
||||||
|
@ -409,8 +407,9 @@ main(int argc, char *argv[])
|
||||||
fprintf(stdout, "button pressed!\n");
|
fprintf(stdout, "button pressed!\n");
|
||||||
gui_end_panel(ctx, panel, NULL);
|
gui_end_panel(ctx, panel, NULL);
|
||||||
|
|
||||||
gui_begin_panel(ctx, subpanel, "Subdemo", GUI_PANEL_HEADER|GUI_PANEL_SCROLLBAR);
|
gui_begin_panel(ctx, subpanel, "Subdemo",
|
||||||
gui_panel_layout(panel, 30, 1);
|
GUI_PANEL_HEADER|GUI_PANEL_CLOSEABLE|GUI_PANEL_MINIMIZABLE|GUI_PANEL_SCROLLBAR);
|
||||||
|
gui_panel_layout(subpanel, 30, 1);
|
||||||
if (gui_panel_button_text(subpanel, "button", 6, GUI_BUTTON_SWITCH))
|
if (gui_panel_button_text(subpanel, "button", 6, GUI_BUTTON_SWITCH))
|
||||||
fprintf(stdout, "subbutton pressed!\n");
|
fprintf(stdout, "subbutton pressed!\n");
|
||||||
gui_end_panel(ctx, subpanel, NULL);
|
gui_end_panel(ctx, subpanel, NULL);
|
||||||
|
|
Loading…
Reference in New Issue