massive rewrite
This commit is contained in:
parent
4405db1731
commit
20b9d3cd45
64
Readme.md
64
Readme.md
|
@ -1,8 +1,6 @@
|
|||
# Zahnrad
|
||||
[![Coverity Status](https://scan.coverity.com/projects/5863/badge.svg)](https://scan.coverity.com/projects/5863)
|
||||
|
||||
# CURRENTLY UNDER HEAVY REFACTORING! (do not use at the moment)
|
||||
|
||||
This is a minimal state immediate mode graphical user interface toolkit
|
||||
written in ANSI C and licensed under zlib. It was designed as a simple embeddable user interface for
|
||||
application and does not have any direct dependencies,
|
||||
|
@ -50,25 +48,55 @@ draw the GUI.
|
|||
|
||||
## Example
|
||||
```c
|
||||
enum {EASY, HARD};
|
||||
int option = EASY;
|
||||
float value = 0.6f;
|
||||
/* init gui state */
|
||||
struct zr_context ctx;
|
||||
zr_init_fixed(&ctx, calloc(1, MAX_MEMORY), MAX_MEMORY, &font, sinf, cosf);
|
||||
|
||||
struct zr_context context;
|
||||
zr_begin(&context, &window, "Show");
|
||||
{
|
||||
zr_layout_row_static(&context, 30, 80, 1);
|
||||
if (zr_button_text(&context, "button", ZR_BUTTON_DEFAULT)) {
|
||||
/* event handling */
|
||||
enum {EASY, HARD};
|
||||
int op = EASY;
|
||||
float value = 0.6f;
|
||||
int i = 20;
|
||||
|
||||
while (1) {
|
||||
zr_input_begin(&ctx.input);
|
||||
/* generate input */
|
||||
zr_input_end(&ctx.input);
|
||||
|
||||
zr_begin(&ctx, "Show", zr_rect(50, 50, 220, 220),
|
||||
ZR_WINDOW_BORDER|ZR_WINDOW_MOVEABLE|ZR_WINDOW_SCALEABLE|
|
||||
ZR_WINDOW_CLOSEABLE|ZR_WINDOW_MINIMIZABLE);
|
||||
{
|
||||
/* fixed widget pixel width */
|
||||
zr_layout_row_static(&ctx, 30, 80, 1);
|
||||
if (zr_button_text(&ctx, "button", ZR_BUTTON_DEFAULT)) {
|
||||
/* event handling */
|
||||
}
|
||||
|
||||
/* fixed widget window ration width */
|
||||
zr_layout_row_dynamic(&ctx, 30, 2);
|
||||
if (zr_option(&ctx, "easy", op == EASY)) op = EASY;
|
||||
if (zr_option(&ctx, "hard", op == HARD)) op = HARD;
|
||||
|
||||
zr_layout_row_dynamic(&ctx, 30, 1);
|
||||
zr_property_int(&ctx, "Compression:", 0, &i, 100, 10, 1);
|
||||
|
||||
/* custom widget pixel width */
|
||||
zr_layout_row_begin(&ctx, ZR_STATIC, 30, 2);
|
||||
{
|
||||
zr_layout_row_push(&ctx, 50);
|
||||
zr_label(&ctx, "Volume:", ZR_TEXT_LEFT);
|
||||
zr_layout_row_push(&ctx, 110);
|
||||
zr_slider_float(&ctx, 0, &value, 1.0f, 0.1f);
|
||||
}
|
||||
zr_layout_row_end(&ctx);
|
||||
}
|
||||
zr_end(ctx);
|
||||
|
||||
struct zr_command *cmd;
|
||||
zr_foreach(cmd, &ctx) {
|
||||
/* execute draw command */
|
||||
}
|
||||
zr_layout_row_dynamic(&context, 30, 2);
|
||||
if (zr_option(&context, "easy", option == EASY)) option = EASY;
|
||||
if (zr_option(&context, "hard", option == HARD)) option = HARD;
|
||||
zr_label(&context, "Volume:", ZR_TEXT_LEFT);
|
||||
zr_slider_float(&context, 0, &value, 1.0f, 0.1f);
|
||||
zr_layout_row_end(&context);
|
||||
}
|
||||
zr_end(&context, &window);
|
||||
```
|
||||
![example](https://cloud.githubusercontent.com/assets/8057201/10187981/584ecd68-675c-11e5-897c-822ef534a876.png)
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Install
|
||||
BIN = demo
|
||||
|
||||
# Compiler
|
||||
CC = clang
|
||||
DCC = gcc
|
||||
|
||||
# Flags
|
||||
CFLAGS = -std=c89 -pedantic
|
||||
|
||||
SRC = ../../zahnrad.c allegro.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
BIN := $(BIN).exe
|
||||
LIBS = -lmingw32 -lallegro -lallegro_primitives -lm
|
||||
else
|
||||
LIBS = -lallegro -lallegro_primitives -lGL -lm -lGLU -lGLEW
|
||||
endif
|
||||
|
||||
# Modes
|
||||
.PHONY: gcc
|
||||
gcc: CC = gcc
|
||||
gcc: $(BIN)
|
||||
|
||||
.PHONY: clang
|
||||
clang: CC = clang
|
||||
clang: $(BIN)
|
||||
|
||||
$(BIN):
|
||||
@mkdir -p bin
|
||||
rm -f bin/$(BIN) $(OBJS)
|
||||
$(CC) $(SRC) $(CFLAGS) -o bin/$(BIN) $(LIBS)
|
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
Copyright (c) 2015 Micha Mettke
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <allegro5/allegro.h>
|
||||
#include <allegro5/allegro_primitives.h>
|
||||
|
||||
/* macros */
|
||||
#define DTIME 33
|
||||
#define MAX_DRAW_COMMAND_MEMORY (4 * 1024)
|
||||
#define MAX_VERTEX_MEMORY 128 * 1024
|
||||
#define MAX_ELEMENT_MEMORY 64 * 1024
|
||||
|
||||
#include "../../zahnrad.h"
|
||||
|
||||
#include "../demo.c"
|
||||
|
||||
struct device {
|
||||
ALLEGRO_DISPLAY *display;
|
||||
ALLEGRO_EVENT_QUEUE *queue;
|
||||
ALLEGRO_BITMAP *texture;
|
||||
ALLEGRO_VERTEX_DECL *vertex_decl;
|
||||
struct zr_draw_null_texture null;
|
||||
struct zr_buffer cmds;
|
||||
struct zr_font font;
|
||||
void *vertex_buffer;
|
||||
void *element_buffer;
|
||||
};
|
||||
|
||||
struct allegro_vertex {
|
||||
struct zr_vec2 pos;
|
||||
struct zr_vec2 uv;
|
||||
ALLEGRO_COLOR col;
|
||||
};
|
||||
|
||||
static void
|
||||
die(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
fputs("\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static char*
|
||||
file_load(const char* path, size_t* siz)
|
||||
{
|
||||
char *buf;
|
||||
FILE *fd = fopen(path, "rb");
|
||||
if (!fd) die("Failed to open file: %s\n", path);
|
||||
fseek(fd, 0, SEEK_END);
|
||||
*siz = (size_t)ftell(fd);
|
||||
fseek(fd, 0, SEEK_SET);
|
||||
buf = (char*)calloc(*siz, 1);
|
||||
fread(buf, *siz, 1, fd);
|
||||
fclose(fd);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static struct zr_user_font
|
||||
device_init(struct device *dev,
|
||||
const char *path, unsigned int font_height, const zr_rune *range)
|
||||
{
|
||||
int glyph_count;
|
||||
int img_width, img_height;
|
||||
struct zr_font_glyph *glyphes;
|
||||
struct zr_baked_font baked_font;
|
||||
struct zr_user_font user_font;
|
||||
struct zr_recti custom;
|
||||
|
||||
ALLEGRO_VERTEX_ELEMENT elems[] = {
|
||||
{ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(struct allegro_vertex, pos)},
|
||||
{ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(struct allegro_vertex, uv)},
|
||||
{ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(struct allegro_vertex, col)},
|
||||
{0,0,0}
|
||||
};
|
||||
dev->vertex_decl = al_create_vertex_decl(elems, sizeof(struct allegro_vertex));
|
||||
|
||||
memset(&baked_font, 0, sizeof(baked_font));
|
||||
memset(&user_font, 0, sizeof(user_font));
|
||||
memset(&custom, 0, sizeof(custom));
|
||||
{
|
||||
/* bake and upload font texture */
|
||||
void *img, *tmp;
|
||||
size_t ttf_size;
|
||||
size_t tmp_size, img_size;
|
||||
const char *custom_data = "....";
|
||||
struct zr_font_config config;
|
||||
char *ttf_blob = file_load(path, &ttf_size);
|
||||
if (!ttf_blob)
|
||||
die("[Font]: %s is not a file or cannot be found!\n", path);
|
||||
|
||||
/* setup font configuration */
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.ttf_blob = ttf_blob;
|
||||
config.ttf_size = ttf_size;
|
||||
config.font = &baked_font;
|
||||
config.coord_type = ZR_COORD_UV;
|
||||
config.range = range;
|
||||
config.pixel_snap = zr_false;
|
||||
config.size = (float)font_height;
|
||||
config.spacing = zr_vec2(0,0);
|
||||
config.oversample_h = 1;
|
||||
config.oversample_v = 1;
|
||||
|
||||
/* query needed amount of memory for the font baking process */
|
||||
zr_font_bake_memory(&tmp_size, &glyph_count, &config, 1);
|
||||
glyphes = (struct zr_font_glyph*)calloc(sizeof(struct zr_font_glyph), (size_t)glyph_count);
|
||||
tmp = calloc(1, tmp_size);
|
||||
|
||||
/* pack all glyphes and return needed image width, height and memory size*/
|
||||
custom.w = 2; custom.h = 2;
|
||||
if (!zr_font_bake_pack(&img_size, &img_width,&img_height,&custom,tmp,tmp_size,&config, 1))
|
||||
die("[Font]: failed to load font!\n");
|
||||
|
||||
/* bake all glyphes and custom white pixel into image */
|
||||
img = calloc(1, img_size);
|
||||
zr_font_bake(img, img_width, img_height, tmp, tmp_size, glyphes, glyph_count, &config, 1);
|
||||
zr_font_bake_custom_data(img, img_width, img_height, custom, custom_data, 2, 2, '.', 'X');
|
||||
{
|
||||
/* convert alpha8 image into rgba8 image */
|
||||
void *img_rgba = calloc(4, (size_t)(img_height * img_width));
|
||||
zr_font_bake_convert(img_rgba, img_width, img_height, img);
|
||||
free(img);
|
||||
img = img_rgba;
|
||||
}
|
||||
|
||||
{
|
||||
/* create allegro font bitmap */
|
||||
ALLEGRO_BITMAP *bitmap = 0;
|
||||
int flags = al_get_new_bitmap_flags();
|
||||
int fmt = al_get_new_bitmap_format();
|
||||
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP|ALLEGRO_MIN_LINEAR|ALLEGRO_MAG_LINEAR);
|
||||
al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
|
||||
bitmap = al_create_bitmap(img_width, img_height);
|
||||
al_set_new_bitmap_flags(flags);
|
||||
al_set_new_bitmap_format(fmt);
|
||||
assert(bitmap);
|
||||
|
||||
{
|
||||
/* copy font texture into bitmap */
|
||||
ALLEGRO_LOCKED_REGION * locked_img;
|
||||
locked_img = al_lock_bitmap(bitmap, al_get_bitmap_format(bitmap), ALLEGRO_LOCK_WRITEONLY);
|
||||
assert(locked_img);
|
||||
memcpy(locked_img->data, img, sizeof(uint32_t)*(size_t)(img_width*img_height));
|
||||
al_unlock_bitmap(bitmap);
|
||||
}
|
||||
|
||||
/* convert software texture into hardware texture */
|
||||
dev->texture = al_clone_bitmap(bitmap);
|
||||
al_destroy_bitmap(bitmap);
|
||||
assert(dev->texture);
|
||||
}
|
||||
free(ttf_blob);
|
||||
free(tmp);
|
||||
free(img);
|
||||
}
|
||||
|
||||
/* default white pixel in a texture which is needed to draw primitives */
|
||||
dev->null.texture.ptr = dev->texture;
|
||||
dev->null.uv = zr_vec2((custom.x + 0.5f)/(float)img_width,
|
||||
(custom.y + 0.5f)/(float)img_height);
|
||||
|
||||
/* setup font with glyphes. IMPORTANT: the font only references the glyphes
|
||||
this was done to have the possibility to have multible fonts with one
|
||||
total glyph array. Not quite sure if it is a good thing since the
|
||||
glyphes have to be freed as well. */
|
||||
zr_font_init(&dev->font, (float)font_height, '?', glyphes, &baked_font, dev->null.texture);
|
||||
user_font = zr_font_ref(&dev->font);
|
||||
|
||||
/* allocate memory for drawing process */
|
||||
dev->vertex_buffer = calloc(MAX_VERTEX_MEMORY, 1);
|
||||
dev->element_buffer = calloc(MAX_ELEMENT_MEMORY, 1);
|
||||
return user_font;
|
||||
}
|
||||
|
||||
static void
|
||||
device_shutdown(struct device *dev)
|
||||
{
|
||||
free(dev->font.glyphs);
|
||||
free(dev->vertex_buffer);
|
||||
free(dev->element_buffer);
|
||||
zr_buffer_free(&dev->cmds);
|
||||
}
|
||||
|
||||
static void
|
||||
device_draw(struct device *dev, struct zr_context *ctx, enum zr_anti_aliasing AA)
|
||||
{
|
||||
int op, src, dst;
|
||||
al_get_blender(&op, &src, &dst);
|
||||
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
|
||||
|
||||
{
|
||||
const struct zr_draw_command *cmd;
|
||||
struct zr_buffer vbuf, ebuf;
|
||||
int offset = 0;
|
||||
struct allegro_vertex *vertexes = 0;
|
||||
int *indicies = 0;
|
||||
|
||||
/* convert from command into hardware format */
|
||||
zr_buffer_init_fixed(&vbuf, dev->vertex_buffer, MAX_VERTEX_MEMORY);
|
||||
zr_buffer_init_fixed(&ebuf, dev->element_buffer, MAX_ELEMENT_MEMORY);
|
||||
zr_convert(ctx, &dev->cmds, &vbuf, &ebuf, dev->null, AA, 1.0f, 22);
|
||||
|
||||
{
|
||||
/* <sign> allegro does not support 32-bit packed color */
|
||||
unsigned int i = 0;
|
||||
struct zr_draw_vertex *verts = (struct zr_draw_vertex*)dev->vertex_buffer;
|
||||
vertexes = calloc(sizeof(struct allegro_vertex), ctx->canvas.vertex_count);
|
||||
for (i = 0; i < ctx->canvas.vertex_count; ++i) {
|
||||
zr_byte *c;
|
||||
vertexes[i].pos = verts[i].position;
|
||||
vertexes[i].uv = verts[i].uv;
|
||||
c = (zr_byte*)&verts[i].col;
|
||||
vertexes[i].col = al_map_rgba(c[0], c[1], c[2], c[3]);
|
||||
}
|
||||
}
|
||||
{
|
||||
/* <massive sign> allegro does not support 16-bit indicies:
|
||||
* @OPT: define zr_draw_index as int to fix this issue. */
|
||||
unsigned int i = 0;
|
||||
zr_draw_index *elements = (zr_draw_index*)dev->element_buffer;
|
||||
indicies = calloc(sizeof(int), ctx->canvas.element_count);
|
||||
for (i = 0; i < ctx->canvas.element_count; ++i)
|
||||
indicies[i] = elements[i];
|
||||
}
|
||||
|
||||
/* iterate over and execute each draw command */
|
||||
zr_draw_foreach(cmd, ctx, &dev->cmds)
|
||||
{
|
||||
ALLEGRO_BITMAP *texture = cmd->texture.ptr;
|
||||
if (!cmd->elem_count) continue;
|
||||
al_set_clipping_rectangle((int)cmd->clip_rect.x, (int)cmd->clip_rect.y,
|
||||
(int)cmd->clip_rect.w, (int)cmd->clip_rect.h);
|
||||
al_draw_indexed_prim(vertexes, dev->vertex_decl, texture, &indicies[offset],
|
||||
(int)cmd->elem_count, ALLEGRO_PRIM_TRIANGLE_LIST);
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
|
||||
free(vertexes);
|
||||
free(indicies);
|
||||
zr_clear(ctx);
|
||||
}
|
||||
al_set_blender(op, src, dst);
|
||||
al_set_clipping_rectangle(0,0,al_get_display_width(dev->display),
|
||||
al_get_display_height(dev->display));
|
||||
}
|
||||
|
||||
static void
|
||||
input_key(struct zr_input *in, ALLEGRO_EVENT *evt, int down)
|
||||
{
|
||||
int sym = evt->keyboard.keycode;
|
||||
if (sym == ALLEGRO_KEY_RSHIFT || sym == ALLEGRO_KEY_LSHIFT)
|
||||
zr_input_key(in, ZR_KEY_SHIFT, down);
|
||||
else if (sym == ALLEGRO_KEY_DELETE)
|
||||
zr_input_key(in, ZR_KEY_DEL, down);
|
||||
else if (sym == ALLEGRO_KEY_ENTER)
|
||||
zr_input_key(in, ZR_KEY_ENTER, down);
|
||||
else if (sym == ALLEGRO_KEY_TAB)
|
||||
zr_input_key(in, ZR_KEY_TAB, down);
|
||||
else if (sym == ALLEGRO_KEY_BACKSPACE)
|
||||
zr_input_key(in, ZR_KEY_BACKSPACE, down);
|
||||
else if (sym == ALLEGRO_KEY_LEFT)
|
||||
zr_input_key(in, ZR_KEY_LEFT, down);
|
||||
else if (sym == ALLEGRO_KEY_RIGHT)
|
||||
zr_input_key(in, ZR_KEY_RIGHT, down);
|
||||
else if (sym == ALLEGRO_KEY_C)
|
||||
zr_input_key(in, ZR_KEY_COPY, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_V)
|
||||
zr_input_key(in, ZR_KEY_PASTE, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_X)
|
||||
zr_input_key(in, ZR_KEY_CUT, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
}
|
||||
|
||||
static void
|
||||
input_button(struct zr_input *in, ALLEGRO_EVENT *evt, int down)
|
||||
{
|
||||
const int x = evt->mouse.x;
|
||||
const int y = evt->mouse.y;
|
||||
if (evt->mouse.button == 1)
|
||||
zr_input_button(in, ZR_BUTTON_LEFT, x, y, down);
|
||||
if (evt->mouse.button == 2)
|
||||
zr_input_button(in, ZR_BUTTON_RIGHT, x, y, down);
|
||||
}
|
||||
|
||||
static void* mem_alloc(zr_handle unused, size_t size)
|
||||
{UNUSED(unused); return calloc(1, size);}
|
||||
static void mem_free(zr_handle unused, void *ptr)
|
||||
{UNUSED(unused); free(ptr);}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
/* Platform */
|
||||
const char *font_path;
|
||||
int win_width, win_height;
|
||||
int width = 0, height = 0;
|
||||
int running = 1;
|
||||
|
||||
/* GUI */
|
||||
struct device dev;
|
||||
struct demo gui;
|
||||
|
||||
font_path = argv[1];
|
||||
if (argc < 2)
|
||||
die("Missing TTF Font file argument!");
|
||||
|
||||
/* Allegro */
|
||||
al_init();
|
||||
al_install_keyboard();
|
||||
al_install_mouse();
|
||||
al_init_primitives_addon();
|
||||
dev.display = al_create_display(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
al_set_window_title(dev.display, "Zahnrad");
|
||||
dev.queue = al_create_event_queue();
|
||||
al_register_event_source(dev.queue, al_get_display_event_source(dev.display));
|
||||
al_register_event_source(dev.queue, al_get_keyboard_event_source());
|
||||
al_register_event_source(dev.queue, al_get_mouse_event_source());
|
||||
|
||||
{
|
||||
/* GUI */
|
||||
struct zr_user_font usrfnt;
|
||||
struct zr_allocator alloc;
|
||||
alloc.userdata.ptr = NULL;
|
||||
alloc.alloc = mem_alloc;
|
||||
alloc.free = mem_free;
|
||||
zr_buffer_init(&dev.cmds, &alloc, 1024);
|
||||
|
||||
usrfnt = device_init(&dev, font_path, 14,
|
||||
zr_font_default_glyph_ranges());
|
||||
zr_init(&gui.ctx, &alloc, &usrfnt, sin, cos);
|
||||
}
|
||||
|
||||
while (running) {
|
||||
/* Input */
|
||||
ALLEGRO_EVENT evt;
|
||||
zr_input_begin(&gui.ctx.input);
|
||||
while (al_get_next_event(dev.queue, &evt)) {
|
||||
if (evt.type == ALLEGRO_EVENT_DISPLAY_CLOSE) goto cleanup;
|
||||
else if (evt.type == ALLEGRO_EVENT_KEY_UP && evt.keyboard.display == dev.display)
|
||||
input_key(&gui.ctx.input, &evt, zr_false);
|
||||
else if (evt.type == ALLEGRO_EVENT_KEY_DOWN && evt.keyboard.display == dev.display)
|
||||
input_key(&gui.ctx.input, &evt, zr_true);
|
||||
else if (evt.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||
input_button(&gui.ctx.input, &evt, zr_true);
|
||||
else if (evt.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP)
|
||||
input_button(&gui.ctx.input, &evt, zr_false);
|
||||
else if (evt.type == ALLEGRO_EVENT_MOUSE_AXES) {
|
||||
zr_input_scroll(&gui.ctx.input,(float)evt.mouse.z);
|
||||
zr_input_motion(&gui.ctx.input, evt.mouse.x, evt.mouse.y);
|
||||
} else if (evt.type == ALLEGRO_EVENT_KEY_CHAR) {
|
||||
if (evt.keyboard.display == dev.display)
|
||||
if (evt.keyboard.unichar > 0 && evt.keyboard.unichar < 0x10000)
|
||||
zr_input_unicode(&gui.ctx.input, (zr_rune)evt.keyboard.unichar);
|
||||
}
|
||||
}
|
||||
zr_input_end(&gui.ctx.input);
|
||||
|
||||
/* GUI */
|
||||
running = run_demo(&gui);
|
||||
|
||||
/* Draw */
|
||||
al_clear_to_color(al_map_rgba_f(0.2f, 0.2f, 0.2f, 1.0f));
|
||||
device_draw(&dev, &gui.ctx, ZR_ANTI_ALIASING_ON);
|
||||
al_flip_display();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
/* Cleanup */
|
||||
if (dev.texture)
|
||||
al_destroy_bitmap(dev.texture);
|
||||
if (dev.queue)
|
||||
al_destroy_event_queue(dev.queue);
|
||||
if (dev.display)
|
||||
al_destroy_display(dev.display);
|
||||
device_shutdown(&dev);
|
||||
zr_free(&gui.ctx);
|
||||
return 0;
|
||||
}
|
||||
|
1759
demo/demo.c
1759
demo/demo.c
File diff suppressed because it is too large
Load Diff
|
@ -84,18 +84,21 @@ file_load(const char* path, size_t* siz)
|
|||
}
|
||||
|
||||
struct device {
|
||||
struct zr_buffer cmds;
|
||||
struct zr_draw_null_texture null;
|
||||
GLuint vbo, vao, ebo;
|
||||
|
||||
GLuint prog;
|
||||
GLuint vert_shdr;
|
||||
GLuint frag_shdr;
|
||||
|
||||
GLint attrib_pos;
|
||||
GLint attrib_uv;
|
||||
GLint attrib_col;
|
||||
|
||||
GLint uniform_tex;
|
||||
GLint uniform_proj;
|
||||
GLuint font_tex;
|
||||
struct zr_draw_null_texture null;
|
||||
struct zr_buffer cmds;
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -280,12 +283,8 @@ device_shutdown(struct device *dev)
|
|||
glDeleteBuffers(1, &dev->ebo);
|
||||
}
|
||||
|
||||
/* this is stupid but needed for C89 since sinf and cosf do not exist */
|
||||
static float fsin(float f) {return (float)sin(f);}
|
||||
static float fcos(float f) {return (float)cos(f);}
|
||||
|
||||
static void
|
||||
device_draw(struct device *dev, struct zr_command_queue *queue, int width, int height,
|
||||
device_draw(struct device *dev, struct zr_context *ctx, int width, int height,
|
||||
enum zr_anti_aliasing AA)
|
||||
{
|
||||
GLint last_prog, last_tex;
|
||||
|
@ -307,7 +306,6 @@ device_draw(struct device *dev, struct zr_command_queue *queue, int width, int h
|
|||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vbo);
|
||||
|
||||
/* setup global state */
|
||||
glViewport(0, 0, width, height);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
@ -323,13 +321,11 @@ device_draw(struct device *dev, struct zr_command_queue *queue, int width, int h
|
|||
|
||||
{
|
||||
/* convert from command queue into draw list and draw to screen */
|
||||
struct zr_draw_list draw_list;
|
||||
const struct zr_draw_command *cmd;
|
||||
void *vertexes, *elements;
|
||||
const zr_draw_index *offset = NULL;
|
||||
|
||||
/* allocate vertex and element buffer */
|
||||
memset(&draw_list, 0, sizeof(draw_list));
|
||||
glBindVertexArray(dev->vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, dev->vbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo);
|
||||
|
@ -344,15 +340,13 @@ device_draw(struct device *dev, struct zr_command_queue *queue, int width, int h
|
|||
struct zr_buffer vbuf, ebuf;
|
||||
zr_buffer_init_fixed(&vbuf, vertexes, MAX_VERTEX_MEMORY);
|
||||
zr_buffer_init_fixed(&ebuf, elements, MAX_ELEMENT_MEMORY);
|
||||
zr_draw_list_init(&draw_list, &dev->cmds, &vbuf, &ebuf,
|
||||
fsin, fcos, dev->null, AA);
|
||||
zr_draw_list_load(&draw_list, queue, 1.0f, 22);
|
||||
zr_convert(ctx, &dev->cmds, &vbuf, &ebuf, dev->null, AA, 1.0f, 22);
|
||||
}
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
|
||||
/* iterate over and execute each draw command */
|
||||
zr_foreach_draw_command(cmd, &draw_list) {
|
||||
zr_draw_foreach(cmd, ctx, &dev->cmds) {
|
||||
if (!cmd->elem_count) continue;
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
|
||||
glScissor((GLint)cmd->clip_rect.x,
|
||||
|
@ -361,9 +355,7 @@ device_draw(struct device *dev, struct zr_command_queue *queue, int width, int h
|
|||
glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
|
||||
zr_command_queue_clear(queue);
|
||||
zr_draw_list_clear(&draw_list);
|
||||
zr_clear(ctx);
|
||||
}
|
||||
|
||||
/* restore old state */
|
||||
|
@ -388,25 +380,25 @@ input_key(GLFWwindow *window, int key, int scancode, int action, int mods)
|
|||
UNUSED(window);
|
||||
UNUSED(scancode);
|
||||
if (key == GLFW_KEY_RIGHT_SHIFT || key == GLFW_KEY_LEFT_SHIFT)
|
||||
zr_input_key(&gui.input, ZR_KEY_SHIFT, down);
|
||||
zr_input_key(&gui.ctx.input, ZR_KEY_SHIFT, down);
|
||||
else if (key == GLFW_KEY_DELETE)
|
||||
zr_input_key(&gui.input, ZR_KEY_DEL, down);
|
||||
zr_input_key(&gui.ctx.input, ZR_KEY_DEL, down);
|
||||
else if (key == GLFW_KEY_ENTER)
|
||||
zr_input_key(&gui.input, ZR_KEY_ENTER, down);
|
||||
zr_input_key(&gui.ctx.input, ZR_KEY_ENTER, down);
|
||||
else if (key == GLFW_KEY_TAB)
|
||||
zr_input_key(&gui.input, ZR_KEY_TAB, down);
|
||||
zr_input_key(&gui.ctx.input, ZR_KEY_TAB, down);
|
||||
else if (key == GLFW_KEY_BACKSPACE)
|
||||
zr_input_key(&gui.input, ZR_KEY_BACKSPACE, down);
|
||||
zr_input_key(&gui.ctx.input, ZR_KEY_BACKSPACE, down);
|
||||
else if (key == GLFW_KEY_LEFT)
|
||||
zr_input_key(&gui.input, ZR_KEY_LEFT, down);
|
||||
zr_input_key(&gui.ctx.input, ZR_KEY_LEFT, down);
|
||||
else if (key == GLFW_KEY_RIGHT)
|
||||
zr_input_key(&gui.input, ZR_KEY_RIGHT, down);
|
||||
zr_input_key(&gui.ctx.input, ZR_KEY_RIGHT, down);
|
||||
else if (key == GLFW_KEY_C)
|
||||
zr_input_key(&gui.input, ZR_KEY_COPY, down && (mods & GLFW_MOD_CONTROL));
|
||||
zr_input_key(&gui.ctx.input, ZR_KEY_COPY, down && (mods & GLFW_MOD_CONTROL));
|
||||
else if (key == GLFW_KEY_V)
|
||||
zr_input_key(&gui.input, ZR_KEY_PASTE, down && (mods & GLFW_MOD_CONTROL));
|
||||
zr_input_key(&gui.ctx.input, ZR_KEY_PASTE, down && (mods & GLFW_MOD_CONTROL));
|
||||
else if (key == GLFW_KEY_X)
|
||||
zr_input_key(&gui.input, ZR_KEY_CUT, down && (mods & GLFW_MOD_CONTROL));
|
||||
zr_input_key(&gui.ctx.input, ZR_KEY_CUT, down && (mods & GLFW_MOD_CONTROL));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -417,13 +409,13 @@ input_motion(GLFWwindow *window, double xpos, double ypos)
|
|||
UNUSED(window);
|
||||
mouse_pos_x = x;
|
||||
mouse_pos_y = y;
|
||||
zr_input_motion(&gui.input, x, y);
|
||||
zr_input_motion(&gui.ctx.input, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
input_button(GLFWwindow *window, int button, int action, int mods)
|
||||
{
|
||||
struct zr_input *in = &gui.input;
|
||||
struct zr_input *in = &gui.ctx.input;
|
||||
int x = mouse_pos_x;
|
||||
int y = mouse_pos_y;
|
||||
UNUSED(window);
|
||||
|
@ -438,7 +430,7 @@ static void
|
|||
input_text(GLFWwindow *window, unsigned int codepoint)
|
||||
{
|
||||
UNUSED(window);
|
||||
zr_input_unicode(&gui.input, codepoint);
|
||||
zr_input_unicode(&gui.ctx.input, codepoint);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -446,7 +438,7 @@ input_scroll(GLFWwindow *window, double xoffset, double yoffset)
|
|||
{
|
||||
UNUSED(window);
|
||||
UNUSED(xoffset);
|
||||
zr_input_scroll(&gui.input, (float)yoffset);
|
||||
zr_input_scroll(&gui.ctx.input, (float)yoffset);
|
||||
}
|
||||
|
||||
static void* mem_alloc(zr_handle unused, size_t size)
|
||||
|
@ -461,9 +453,9 @@ main(int argc, char *argv[])
|
|||
const char *font_path;
|
||||
int win_width, win_height;
|
||||
int width = 0, height = 0;
|
||||
int running = 1;
|
||||
|
||||
/* GUI */
|
||||
struct zr_allocator alloc;
|
||||
struct device device;
|
||||
struct zr_font font;
|
||||
|
||||
|
@ -497,43 +489,42 @@ main(int argc, char *argv[])
|
|||
if (glewInit() != GLEW_OK)
|
||||
die("Failed to setup GLEW\n");
|
||||
|
||||
/* GUI */
|
||||
alloc.userdata.ptr = NULL;
|
||||
alloc.alloc = mem_alloc;
|
||||
alloc.free = mem_free;
|
||||
memset(&gui, 0, sizeof gui);
|
||||
zr_buffer_init(&device.cmds, &alloc, 1024, 2.0f);
|
||||
zr_command_queue_init(&gui.queue, &alloc, 1024, 2.0f);
|
||||
gui.font = font_bake_and_upload(&device, &font, font_path, 14,
|
||||
zr_font_default_glyph_ranges());
|
||||
{
|
||||
/* GUI */
|
||||
struct zr_user_font usrfnt;
|
||||
struct zr_allocator alloc;
|
||||
alloc.userdata.ptr = NULL;
|
||||
alloc.alloc = mem_alloc;
|
||||
alloc.free = mem_free;
|
||||
zr_buffer_init(&device.cmds, &alloc, 1024);
|
||||
usrfnt = font_bake_and_upload(&device, &font, font_path, 14,
|
||||
zr_font_default_glyph_ranges());
|
||||
zr_init(&gui.ctx, &alloc, &usrfnt, sin, cos);
|
||||
}
|
||||
|
||||
init_demo(&gui);
|
||||
device_init(&device);
|
||||
|
||||
while (!glfwWindowShouldClose(win) && gui.running) {
|
||||
while (!glfwWindowShouldClose(win) && running) {
|
||||
/* Input */
|
||||
zr_input_begin(&gui.input);
|
||||
zr_input_begin(&gui.ctx.input);
|
||||
glfwPollEvents();
|
||||
zr_input_end(&gui.input);
|
||||
zr_input_end(&gui.ctx.input);
|
||||
|
||||
/* GUI */
|
||||
glfwGetWindowSize(win, &width, &height);
|
||||
gui.w = (size_t)width;
|
||||
gui.h = (size_t)height;
|
||||
run_demo(&gui);
|
||||
running = run_demo(&gui);
|
||||
|
||||
/* Draw */
|
||||
glViewport(0, 0, width, height);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.9f, 0.9f, 0.9f, 1.0f);
|
||||
device_draw(&device, &gui.queue, width, height, ZR_ANTI_ALIASING_ON);
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
device_draw(&device, &gui.ctx, width, height, ZR_ANTI_ALIASING_ON);
|
||||
glfwSwapBuffers(win);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
/* Cleanup */
|
||||
free(font.glyphs);
|
||||
zr_command_queue_free(&gui.queue);
|
||||
zr_free(&gui.ctx);
|
||||
zr_buffer_free(&device.cmds);
|
||||
device_shutdown(&device);
|
||||
glfwTerminate();
|
||||
|
|
|
@ -143,10 +143,6 @@ struct opengl {
|
|||
float version;
|
||||
int major_version;
|
||||
int minor_version;
|
||||
/* constants */
|
||||
int max_texture_size;
|
||||
int max_texture_coords;
|
||||
int max_texture_image_units;
|
||||
/* extensions */
|
||||
int glsl_available;
|
||||
int vertex_buffer_obj_available;
|
||||
|
@ -443,12 +439,8 @@ device_shutdown(struct device *dev)
|
|||
glDeleteVertexArrays(1, &dev->vao);
|
||||
}
|
||||
|
||||
/* this is stupid but needed for C89 since sinf and cosf do not exist */
|
||||
static float fsin(float f) {return (float)sin(f);}
|
||||
static float fcos(float f) {return (float)cos(f);}
|
||||
|
||||
static void
|
||||
device_draw(struct device *dev, struct zr_command_queue *queue, int width, int height,
|
||||
device_draw(struct device *dev, struct zr_context *ctx, int width, int height,
|
||||
enum zr_anti_aliasing AA)
|
||||
{
|
||||
GLint last_prog, last_tex;
|
||||
|
@ -485,13 +477,11 @@ device_draw(struct device *dev, struct zr_command_queue *queue, int width, int h
|
|||
|
||||
{
|
||||
/* convert from command queue into draw list and draw to screen */
|
||||
struct zr_draw_list draw_list;
|
||||
const struct zr_draw_command *cmd;
|
||||
void *vertexes, *elements;
|
||||
const struct zr_draw_command *cmd;
|
||||
const zr_draw_index *offset = NULL;
|
||||
|
||||
/* allocate vertex and element buffer */
|
||||
memset(&draw_list, 0, sizeof(draw_list));
|
||||
glBindVertexArray(dev->vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, dev->vbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo);
|
||||
|
@ -506,15 +496,13 @@ device_draw(struct device *dev, struct zr_command_queue *queue, int width, int h
|
|||
struct zr_buffer vbuf, ebuf;
|
||||
zr_buffer_init_fixed(&vbuf, vertexes, MAX_VERTEX_MEMORY);
|
||||
zr_buffer_init_fixed(&ebuf, elements, MAX_ELEMENT_MEMORY);
|
||||
zr_draw_list_init(&draw_list, &dev->cmds, &vbuf, &ebuf,
|
||||
fsin, fcos, dev->null, AA);
|
||||
zr_draw_list_load(&draw_list, queue, 1.0f, 22);
|
||||
zr_convert(ctx, &dev->cmds, &vbuf, &ebuf, dev->null, AA, 1.0f, 22);
|
||||
}
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
|
||||
/* iterate over and execute each draw command */
|
||||
zr_foreach_draw_command(cmd, &draw_list) {
|
||||
zr_draw_foreach(cmd, ctx, &dev->cmds) {
|
||||
if (!cmd->elem_count) continue;
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
|
||||
glScissor((GLint)cmd->clip_rect.x,
|
||||
|
@ -523,9 +511,7 @@ device_draw(struct device *dev, struct zr_command_queue *queue, int width, int h
|
|||
glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
|
||||
zr_command_queue_clear(queue);
|
||||
zr_draw_list_clear(&draw_list);
|
||||
zr_clear(ctx);
|
||||
}
|
||||
|
||||
/* restore old state */
|
||||
|
@ -602,14 +588,13 @@ static void mem_free(zr_handle unused, void *ptr)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int running = 1;
|
||||
const char *font_path;
|
||||
struct XWindow win;
|
||||
struct opengl gl;
|
||||
|
||||
struct zr_allocator alloc;
|
||||
struct device device;
|
||||
struct demo gui;
|
||||
struct zr_font font;
|
||||
struct XWindow win;
|
||||
|
||||
memset(&gl, 0, sizeof(gl));
|
||||
memset(&win, 0, sizeof(win));
|
||||
|
@ -692,7 +677,7 @@ int main(int argc, char **argv)
|
|||
win.vis->visual, CWBorderPixel|CWColormap|CWEventMask, &win.swa);
|
||||
if (!win.win) die("[X11]: Failed to create window\n");
|
||||
XFree(win.vis);
|
||||
XStoreName(win.dpy, win.win, "QuakEd");
|
||||
XStoreName(win.dpy, win.win, "Zahnrad");
|
||||
fprintf(stdout, "[X11]: Mapping window\n");
|
||||
XMapWindow(win.dpy, win.win);
|
||||
}
|
||||
|
@ -840,53 +825,59 @@ int main(int argc, char **argv)
|
|||
win.width = win.attr.width;
|
||||
win.height = win.attr.height;
|
||||
|
||||
/* GUI */
|
||||
alloc.userdata.ptr = NULL;
|
||||
alloc.alloc = mem_alloc;
|
||||
alloc.free = mem_free;
|
||||
zr_buffer_init(&device.cmds, &alloc, 1024, 2.0f);
|
||||
zr_command_queue_init(&gui.queue, &alloc, 1024, 2.0f);
|
||||
gui.font = font_bake_and_upload(&device, &font, font_path, 14,
|
||||
zr_font_default_glyph_ranges());
|
||||
{
|
||||
/* GUI */
|
||||
struct zr_user_font usrfnt;
|
||||
struct zr_allocator alloc;
|
||||
alloc.userdata.ptr = NULL;
|
||||
alloc.alloc = mem_alloc;
|
||||
alloc.free = mem_free;
|
||||
|
||||
zr_buffer_init(&device.cmds, &alloc, 4024);
|
||||
usrfnt = font_bake_and_upload(&device, &font, font_path, 14,
|
||||
zr_font_default_glyph_ranges());
|
||||
zr_init(&gui.ctx, &alloc, &usrfnt, sin, cos);
|
||||
}
|
||||
|
||||
init_demo(&gui);
|
||||
device_init(&device);
|
||||
|
||||
/* main loop */
|
||||
while (gui.running) {
|
||||
while (running) {
|
||||
/* input */
|
||||
XEvent evt;
|
||||
zr_input_begin(&gui.input);
|
||||
zr_input_begin(&gui.ctx.input);
|
||||
while (XCheckWindowEvent(win.dpy, win.win, win.swa.event_mask, &evt)) {
|
||||
if (evt.type == KeyPress)
|
||||
input_key(&win, &gui.input, &evt, zr_true);
|
||||
input_key(&win, &gui.ctx.input, &evt, zr_true);
|
||||
else if (evt.type == KeyRelease)
|
||||
input_key(&win, &gui.input, &evt, zr_false);
|
||||
input_key(&win, &gui.ctx.input, &evt, zr_false);
|
||||
else if (evt.type == ButtonPress)
|
||||
input_button(&gui.input, &evt, zr_true);
|
||||
input_button(&gui.ctx.input, &evt, zr_true);
|
||||
else if (evt.type == ButtonRelease)
|
||||
input_button(&gui.input, &evt, zr_false);
|
||||
input_button(&gui.ctx.input, &evt, zr_false);
|
||||
else if (evt.type == MotionNotify)
|
||||
input_motion(&gui.input, &evt);
|
||||
input_motion(&gui.ctx.input, &evt);
|
||||
else if (evt.type == Expose || evt.type == ConfigureNotify) {
|
||||
XGetWindowAttributes(win.dpy, win.win, &win.attr);
|
||||
win.width = win.attr.width;
|
||||
win.height = win.attr.height;
|
||||
}
|
||||
}
|
||||
zr_input_end(&gui.input);
|
||||
zr_input_end(&gui.ctx.input);
|
||||
|
||||
/* GUI */
|
||||
XGetWindowAttributes(win.dpy, win.win, &win.attr);
|
||||
gui.w = (size_t)win.width, gui.h = (size_t)win.height;
|
||||
run_demo(&gui);
|
||||
running = run_demo(&gui);
|
||||
|
||||
/* Draw */
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.9f, 0.9f, 0.9f, 1.0f);
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
glViewport(0, 0, win.width, win.height);
|
||||
device_draw(&device, &gui.queue, win.width, win.height, ZR_ANTI_ALIASING_ON);
|
||||
device_draw(&device, &gui.ctx, win.width, win.height, ZR_ANTI_ALIASING_ON);
|
||||
glXSwapBuffers(win.dpy, win.win);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
free(font.glyphs);
|
||||
zr_command_queue_free(&gui.queue);
|
||||
zr_free(&gui.ctx);
|
||||
zr_buffer_free(&device.cmds);
|
||||
device_shutdown(&device);
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ font_get_width(zr_handle handle, float height, const char *text, size_t len)
|
|||
}
|
||||
|
||||
static void
|
||||
draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
||||
draw(NVGcontext *nvg, struct zr_context *ctx, int width, int height)
|
||||
{
|
||||
const struct zr_command *cmd;
|
||||
glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT);
|
||||
|
@ -92,7 +92,7 @@ draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
|||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
nvgBeginFrame(nvg, width, height, ((float)width/(float)height));
|
||||
zr_foreach_command(cmd, queue) {
|
||||
zr_foreach(cmd, ctx) {
|
||||
switch (cmd->type) {
|
||||
case ZR_COMMAND_NOP: break;
|
||||
case ZR_COMMAND_SCISSOR: {
|
||||
|
@ -168,7 +168,7 @@ draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
|||
default: break;
|
||||
}
|
||||
}
|
||||
zr_command_queue_clear(queue);
|
||||
zr_clear(ctx);
|
||||
|
||||
nvgResetScissor(nvg);
|
||||
nvgEndFrame(nvg);
|
||||
|
@ -238,6 +238,7 @@ int
|
|||
main(int argc, char *argv[])
|
||||
{
|
||||
/* Platform */
|
||||
int running = 1;
|
||||
int width, height;
|
||||
const char *font_path;
|
||||
int font_height;
|
||||
|
@ -277,41 +278,45 @@ main(int argc, char *argv[])
|
|||
nvgFontSize(vg, font_height);
|
||||
nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE);
|
||||
|
||||
/* GUI */
|
||||
memset(&gui, 0, sizeof gui);
|
||||
zr_command_queue_init_fixed(&gui.queue, calloc(MAX_MEMORY, 1), MAX_MEMORY);
|
||||
gui.font.userdata = zr_handle_ptr(vg);
|
||||
gui.font.width = font_get_width;
|
||||
nvgTextMetrics(vg, NULL, NULL, &gui.font.height);
|
||||
init_demo(&gui);
|
||||
{
|
||||
/* GUI */
|
||||
struct zr_user_font usrfnt;
|
||||
usrfnt.userdata = zr_handle_ptr(vg);
|
||||
usrfnt.width = font_get_width;
|
||||
nvgTextMetrics(vg, NULL, NULL, &usrfnt.height);
|
||||
|
||||
while (gui.running) {
|
||||
memset(&gui, 0, sizeof gui);
|
||||
gui.memory = calloc(MAX_MEMORY, 1);
|
||||
zr_init_fixed(&gui.ctx, gui.memory, MAX_MEMORY, &usrfnt, sin, cos);
|
||||
}
|
||||
|
||||
while (running) {
|
||||
/* Input */
|
||||
SDL_Event evt;
|
||||
uint64_t dt, started = SDL_GetTicks();
|
||||
zr_input_begin(&gui.input);
|
||||
zr_input_begin(&gui.ctx.input);
|
||||
while (SDL_PollEvent(&evt)) {
|
||||
if (evt.type == SDL_WINDOWEVENT) resize(&evt);
|
||||
else if (evt.type == SDL_QUIT) goto cleanup;
|
||||
else if (evt.type == SDL_KEYUP) key(&gui.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_KEYDOWN) key(&gui.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONDOWN) btn(&gui.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONUP) btn(&gui.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_MOUSEMOTION) motion(&gui.input, &evt);
|
||||
else if (evt.type == SDL_TEXTINPUT) text(&gui.input, &evt);
|
||||
else if (evt.type == SDL_KEYUP) key(&gui.ctx.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_KEYDOWN) key(&gui.ctx.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONDOWN) btn(&gui.ctx.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONUP) btn(&gui.ctx.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_MOUSEMOTION) motion(&gui.ctx.input, &evt);
|
||||
else if (evt.type == SDL_TEXTINPUT) text(&gui.ctx.input, &evt);
|
||||
else if (evt.type == SDL_MOUSEWHEEL)
|
||||
zr_input_scroll(&gui.input,(float)evt.wheel.y);
|
||||
zr_input_scroll(&gui.ctx.input,(float)evt.wheel.y);
|
||||
}
|
||||
zr_input_end(&gui.input);
|
||||
zr_input_end(&gui.ctx.input);
|
||||
|
||||
/* GUI */
|
||||
SDL_GetWindowSize(win, &width, &height);
|
||||
run_demo(&gui);
|
||||
running = run_demo(&gui);
|
||||
|
||||
/* Draw */
|
||||
glClearColor(0.9f, 0.9f, 0.9f, 1.0f);
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
draw(vg, &gui.queue, width, height);
|
||||
draw(vg, &gui.ctx, width, height);
|
||||
dt = SDL_GetTicks() - started;
|
||||
/*fprintf(stdout, "%lu\n", dt);*/
|
||||
SDL_GL_SwapWindow(win);
|
||||
|
@ -319,7 +324,7 @@ main(int argc, char *argv[])
|
|||
|
||||
cleanup:
|
||||
/* Cleanup */
|
||||
free(zr_buffer_memory(&gui.queue.buffer));
|
||||
free(gui.memory);
|
||||
nvgDeleteGLES3(vg);
|
||||
SDL_GL_DeleteContext(glContext);
|
||||
SDL_DestroyWindow(win);
|
||||
|
|
|
@ -274,12 +274,8 @@ device_shutdown(struct device *dev)
|
|||
glDeleteVertexArrays(1, &dev->vao);
|
||||
}
|
||||
|
||||
/* this is stupid but needed for C89 since sinf and cosf do not exist */
|
||||
static float fsin(float f) {return (float)sin(f);}
|
||||
static float fcos(float f) {return (float)cos(f);}
|
||||
|
||||
static void
|
||||
device_draw(struct device *dev, struct zr_command_queue *queue, int width, int height,
|
||||
device_draw(struct device *dev, struct zr_context *ctx, int width, int height,
|
||||
enum zr_anti_aliasing AA)
|
||||
{
|
||||
GLint last_prog, last_tex;
|
||||
|
@ -301,7 +297,6 @@ device_draw(struct device *dev, struct zr_command_queue *queue, int width, int h
|
|||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vbo);
|
||||
|
||||
/* setup global state */
|
||||
glViewport(0, 0, width, height);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
@ -317,13 +312,11 @@ device_draw(struct device *dev, struct zr_command_queue *queue, int width, int h
|
|||
|
||||
{
|
||||
/* convert from command queue into draw list and draw to screen */
|
||||
struct zr_draw_list draw_list;
|
||||
const struct zr_draw_command *cmd;
|
||||
void *vertexes, *elements;
|
||||
const zr_draw_index *offset = NULL;
|
||||
|
||||
/* allocate vertex and element buffer */
|
||||
memset(&draw_list, 0, sizeof(draw_list));
|
||||
glBindVertexArray(dev->vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, dev->vbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dev->ebo);
|
||||
|
@ -338,15 +331,13 @@ device_draw(struct device *dev, struct zr_command_queue *queue, int width, int h
|
|||
struct zr_buffer vbuf, ebuf;
|
||||
zr_buffer_init_fixed(&vbuf, vertexes, MAX_VERTEX_MEMORY);
|
||||
zr_buffer_init_fixed(&ebuf, elements, MAX_ELEMENT_MEMORY);
|
||||
zr_draw_list_init(&draw_list, &dev->cmds, &vbuf, &ebuf,
|
||||
fsin, fcos, dev->null, AA);
|
||||
zr_draw_list_load(&draw_list, queue, 1.0f, 22);
|
||||
zr_convert(ctx, &dev->cmds, &vbuf, &ebuf, dev->null, AA, 1.0f, 22);
|
||||
}
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
|
||||
/* iterate over and execute each draw command */
|
||||
zr_foreach_draw_command(cmd, &draw_list) {
|
||||
zr_draw_foreach(cmd, ctx, &dev->cmds) {
|
||||
if (!cmd->elem_count) continue;
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
|
||||
glScissor((GLint)cmd->clip_rect.x,
|
||||
|
@ -355,9 +346,7 @@ device_draw(struct device *dev, struct zr_command_queue *queue, int width, int h
|
|||
glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
|
||||
zr_command_queue_clear(queue);
|
||||
zr_draw_list_clear(&draw_list);
|
||||
zr_clear(ctx);
|
||||
}
|
||||
|
||||
/* restore old state */
|
||||
|
@ -444,9 +433,9 @@ main(int argc, char *argv[])
|
|||
SDL_GLContext glContext;
|
||||
int win_width, win_height;
|
||||
int width = 0, height = 0;
|
||||
int running = 1;
|
||||
|
||||
/* GUI */
|
||||
struct zr_allocator alloc;
|
||||
struct device device;
|
||||
struct demo gui;
|
||||
struct zr_font font;
|
||||
|
@ -470,60 +459,59 @@ main(int argc, char *argv[])
|
|||
if (glewInit() != GLEW_OK)
|
||||
die("Failed to setup GLEW\n");
|
||||
|
||||
/* GUI */
|
||||
alloc.userdata.ptr = NULL;
|
||||
alloc.alloc = mem_alloc;
|
||||
alloc.free = mem_free;
|
||||
memset(&gui, 0, sizeof gui);
|
||||
zr_buffer_init(&device.cmds, &alloc, 1024, 2.0f);
|
||||
zr_command_queue_init(&gui.queue, &alloc, 1024, 2.0f);
|
||||
gui.font = font_bake_and_upload(&device, &font, font_path, 14,
|
||||
zr_font_default_glyph_ranges());
|
||||
{
|
||||
/* GUI */
|
||||
struct zr_user_font usrfnt;
|
||||
struct zr_allocator alloc;
|
||||
alloc.userdata.ptr = NULL;
|
||||
alloc.alloc = mem_alloc;
|
||||
alloc.free = mem_free;
|
||||
zr_buffer_init(&device.cmds, &alloc, 1024);
|
||||
usrfnt = font_bake_and_upload(&device, &font, font_path, 14,
|
||||
zr_font_default_glyph_ranges());
|
||||
zr_init(&gui.ctx, &alloc, &usrfnt, sin, cos);
|
||||
}
|
||||
|
||||
init_demo(&gui);
|
||||
device_init(&device);
|
||||
|
||||
while (gui.running) {
|
||||
while (running) {
|
||||
/* Input */
|
||||
SDL_Event evt;
|
||||
zr_input_begin(&gui.input);
|
||||
zr_input_begin(&gui.ctx.input);
|
||||
while (SDL_PollEvent(&evt)) {
|
||||
if (evt.type == SDL_WINDOWEVENT) resize(&evt);
|
||||
else if (evt.type == SDL_QUIT) goto cleanup;
|
||||
else if (evt.type == SDL_KEYUP)
|
||||
input_key(&gui.input, &evt, zr_false);
|
||||
input_key(&gui.ctx.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_KEYDOWN)
|
||||
input_key(&gui.input, &evt, zr_true);
|
||||
input_key(&gui.ctx.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONDOWN)
|
||||
input_button(&gui.input, &evt, zr_true);
|
||||
input_button(&gui.ctx.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONUP)
|
||||
input_button(&gui.input, &evt, zr_false);
|
||||
input_button(&gui.ctx.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_MOUSEMOTION)
|
||||
input_motion(&gui.input, &evt);
|
||||
input_motion(&gui.ctx.input, &evt);
|
||||
else if (evt.type == SDL_TEXTINPUT)
|
||||
input_text(&gui.input, &evt);
|
||||
input_text(&gui.ctx.input, &evt);
|
||||
else if (evt.type == SDL_MOUSEWHEEL)
|
||||
zr_input_scroll(&gui.input,(float)evt.wheel.y);
|
||||
zr_input_scroll(&gui.ctx.input,(float)evt.wheel.y);
|
||||
}
|
||||
zr_input_end(&gui.input);
|
||||
zr_input_end(&gui.ctx.input);
|
||||
|
||||
/* GUI */
|
||||
SDL_GetWindowSize(win, &width, &height);
|
||||
gui.w = (size_t)width;
|
||||
gui.h = (size_t)height;
|
||||
run_demo(&gui);
|
||||
running = run_demo(&gui);
|
||||
|
||||
/* Draw */
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.9f, 0.9f, 0.9f, 1.0f);
|
||||
device_draw(&device, &gui.queue, width, height, ZR_ANTI_ALIASING_ON);
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
device_draw(&device, &gui.ctx, width, height, ZR_ANTI_ALIASING_ON);
|
||||
SDL_GL_SwapWindow(win);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
/* Cleanup */
|
||||
free(font.glyphs);
|
||||
zr_command_queue_free(&gui.queue);
|
||||
zr_free(&gui.ctx);
|
||||
zr_buffer_free(&device.cmds);
|
||||
device_shutdown(&device);
|
||||
SDL_GL_DeleteContext(glContext);
|
||||
|
|
130
demo/x11/xlib.c
130
demo/x11/xlib.c
|
@ -25,13 +25,13 @@
|
|||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
/* macros */
|
||||
#define DTIME 16
|
||||
#define CURVE_STEPS 22
|
||||
#include "../../zahnrad.h"
|
||||
|
||||
#define UNUSED(a) ((void)(a))
|
||||
|
@ -158,7 +158,7 @@ font_get_text_width(zr_handle handle, float height, const char *text, zr_size le
|
|||
if(!font || !text)
|
||||
return 0;
|
||||
|
||||
height = 0;
|
||||
UNUSED(height);
|
||||
if(font->set) {
|
||||
XmbTextExtents(font->set, (const char*)text, (int)len, NULL, &r);
|
||||
return r.width;
|
||||
|
@ -221,8 +221,8 @@ surface_scissor(XSurface *surf, float x, float y, float w, float h)
|
|||
XRectangle clip_rect;
|
||||
clip_rect.x = (short)(x-1);
|
||||
clip_rect.y = (short)(y-1);
|
||||
clip_rect.width = (unsigned short)(w + 2);
|
||||
clip_rect.height = (unsigned short)(h + 2);
|
||||
clip_rect.width = (unsigned short)(w+2);
|
||||
clip_rect.height = (unsigned short)(h+2);
|
||||
XSetClipRectangles(surf->dpy, surf->gc, 0, 0, &clip_rect, 1, Unsorted);
|
||||
}
|
||||
|
||||
|
@ -313,49 +313,6 @@ surface_del(XSurface *surf)
|
|||
free(surf);
|
||||
}
|
||||
|
||||
static void
|
||||
draw(XSurface *surf, struct zr_command_queue *queue)
|
||||
{
|
||||
const struct zr_command *cmd;
|
||||
zr_foreach_command(cmd, queue) {
|
||||
switch (cmd->type) {
|
||||
case ZR_COMMAND_NOP: break;
|
||||
case ZR_COMMAND_SCISSOR: {
|
||||
const struct zr_command_scissor *s = zr_command(scissor, cmd);
|
||||
surface_scissor(surf, s->x, s->y, s->w, s->h);
|
||||
} break;
|
||||
case ZR_COMMAND_LINE: {
|
||||
const struct zr_command_line *l = zr_command(line, cmd);
|
||||
surface_draw_line(surf, l->begin.x, l->begin.y, l->end.x,
|
||||
l->end.y, l->color);
|
||||
} break;
|
||||
case ZR_COMMAND_RECT: {
|
||||
const struct zr_command_rect *r = zr_command(rect, cmd);
|
||||
surface_draw_rect(surf, r->x, r->y, r->w, r->h, r->color);
|
||||
} break;
|
||||
case ZR_COMMAND_CIRCLE: {
|
||||
const struct zr_command_circle *c = zr_command(circle, cmd);
|
||||
surface_draw_circle(surf, c->x, c->y, c->w, c->h, c->color);
|
||||
} break;
|
||||
case ZR_COMMAND_TRIANGLE: {
|
||||
const struct zr_command_triangle *t = zr_command(triangle, cmd);
|
||||
surface_draw_triangle(surf, t->a.x, t->a.y, t->b.x, t->b.y,
|
||||
t->c.x, t->c.y, t->color);
|
||||
} break;
|
||||
case ZR_COMMAND_TEXT: {
|
||||
const struct zr_command_text *t = zr_command(text, cmd);
|
||||
surface_draw_text(surf, t->x, t->y, t->w, t->h, (const char*)t->string,
|
||||
t->length, (XFont*)t->font->userdata.ptr, t->background, t->foreground);
|
||||
} break;
|
||||
case ZR_COMMAND_CURVE:
|
||||
case ZR_COMMAND_IMAGE:
|
||||
case ZR_COMMAND_ARC:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
zr_command_queue_clear(queue);
|
||||
}
|
||||
|
||||
static void
|
||||
input_key(struct XWindow *xw, struct zr_input *in, XEvent *evt, int down)
|
||||
{
|
||||
|
@ -429,8 +386,10 @@ main(int argc, char *argv[])
|
|||
long started;
|
||||
XWindow xw;
|
||||
struct demo gui;
|
||||
struct zr_user_font font;
|
||||
int running = 1;
|
||||
|
||||
/* Platform */
|
||||
/* X11 */
|
||||
UNUSED(argc); UNUSED(argv);
|
||||
memset(&xw, 0, sizeof xw);
|
||||
xw.dpy = XOpenDisplay(NULL);
|
||||
|
@ -456,41 +415,82 @@ main(int argc, char *argv[])
|
|||
xw.font = font_create(xw.dpy, "fixed");
|
||||
|
||||
/* GUI */
|
||||
font.userdata = zr_handle_ptr(xw.font);
|
||||
font.height = (float)xw.font->height;
|
||||
font.width = font_get_text_width;
|
||||
memset(&gui, 0, sizeof gui);
|
||||
zr_command_queue_init_fixed(&gui.queue, calloc(MAX_MEMORY, 1), MAX_MEMORY);
|
||||
gui.font.userdata = zr_handle_ptr(xw.font);
|
||||
gui.font.height = (float)xw.font->height;
|
||||
gui.font.width = font_get_text_width;
|
||||
init_demo(&gui);
|
||||
gui.memory = calloc(MAX_MEMORY, 1);
|
||||
zr_init_fixed(&gui.ctx, gui.memory, MAX_MEMORY, &font, sin, cos);
|
||||
|
||||
while (gui.running) {
|
||||
while (running) {
|
||||
/* Input */
|
||||
XEvent evt;
|
||||
started = timestamp();
|
||||
zr_input_begin(&gui.input);
|
||||
zr_input_begin(&gui.ctx.input);
|
||||
while (XCheckWindowEvent(xw.dpy, xw.win, xw.swa.event_mask, &evt)) {
|
||||
if (evt.type == KeyPress)
|
||||
input_key(&xw, &gui.input, &evt, zr_true);
|
||||
input_key(&xw, &gui.ctx.input, &evt, zr_true);
|
||||
else if (evt.type == KeyRelease)
|
||||
input_key(&xw, &gui.input, &evt, zr_false);
|
||||
input_key(&xw, &gui.ctx.input, &evt, zr_false);
|
||||
else if (evt.type == ButtonPress)
|
||||
input_button(&gui.input, &evt, zr_true);
|
||||
input_button(&gui.ctx.input, &evt, zr_true);
|
||||
else if (evt.type == ButtonRelease)
|
||||
input_button(&gui.input, &evt, zr_false);
|
||||
input_button(&gui.ctx.input, &evt, zr_false);
|
||||
else if (evt.type == MotionNotify)
|
||||
input_motion(&gui.input, &evt);
|
||||
input_motion(&gui.ctx.input, &evt);
|
||||
else if (evt.type == Expose || evt.type == ConfigureNotify)
|
||||
resize(&xw, xw.surf);
|
||||
}
|
||||
zr_input_end(&gui.input);
|
||||
zr_input_end(&gui.ctx.input);
|
||||
|
||||
/* GUI */
|
||||
run_demo(&gui);
|
||||
running = run_demo(&gui);
|
||||
|
||||
/* Draw */
|
||||
XClearWindow(xw.dpy, xw.win);
|
||||
surface_clear(xw.surf, 0x00FFFFFF);
|
||||
draw(xw.surf, &gui.queue);
|
||||
surface_clear(xw.surf, 0x00303030);
|
||||
{
|
||||
const struct zr_command *cmd;
|
||||
zr_foreach(cmd, &gui.ctx) {
|
||||
switch (cmd->type) {
|
||||
case ZR_COMMAND_NOP: break;
|
||||
case ZR_COMMAND_SCISSOR: {
|
||||
const struct zr_command_scissor *s = zr_command(scissor, cmd);
|
||||
surface_scissor(xw.surf, s->x, s->y, s->w, s->h);
|
||||
} break;
|
||||
case ZR_COMMAND_LINE: {
|
||||
const struct zr_command_line *l = zr_command(line, cmd);
|
||||
surface_draw_line(xw.surf, l->begin.x, l->begin.y, l->end.x,
|
||||
l->end.y, l->color);
|
||||
} break;
|
||||
case ZR_COMMAND_RECT: {
|
||||
const struct zr_command_rect *r = zr_command(rect, cmd);
|
||||
surface_draw_rect(xw.surf, r->x, r->y, r->w, r->h, r->color);
|
||||
} break;
|
||||
case ZR_COMMAND_CIRCLE: {
|
||||
const struct zr_command_circle *c = zr_command(circle, cmd);
|
||||
surface_draw_circle(xw.surf, c->x, c->y, c->w, c->h, c->color);
|
||||
} break;
|
||||
case ZR_COMMAND_TRIANGLE: {
|
||||
const struct zr_command_triangle *t = zr_command(triangle, cmd);
|
||||
surface_draw_triangle(xw.surf, t->a.x, t->a.y, t->b.x, t->b.y,
|
||||
t->c.x, t->c.y, t->color);
|
||||
} break;
|
||||
case ZR_COMMAND_TEXT: {
|
||||
const struct zr_command_text *t = zr_command(text, cmd);
|
||||
surface_draw_text(xw.surf, t->x, t->y, t->w, t->h,
|
||||
(const char*)t->string, t->length,
|
||||
(XFont*)t->font->userdata.ptr,
|
||||
t->background, t->foreground);
|
||||
} break;
|
||||
case ZR_COMMAND_CURVE:
|
||||
case ZR_COMMAND_IMAGE:
|
||||
case ZR_COMMAND_ARC:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
zr_clear(&gui.ctx);
|
||||
}
|
||||
surface_blit(xw.win, xw.surf, xw.width, xw.height);
|
||||
XFlush(xw.dpy);
|
||||
|
||||
|
@ -500,7 +500,7 @@ main(int argc, char *argv[])
|
|||
sleep_for(DTIME - dt);
|
||||
}
|
||||
|
||||
free(zr_buffer_memory(&gui.queue.buffer));
|
||||
free(gui.memory);
|
||||
font_del(xw.dpy, xw.font);
|
||||
surface_del(xw.surf);
|
||||
XUnmapWindow(xw.dpy, xw.win);
|
||||
|
|
|
@ -76,17 +76,6 @@ struct icons {
|
|||
int menu[6];
|
||||
};
|
||||
|
||||
struct gui {
|
||||
void *memory;
|
||||
struct zr_window button_demo;
|
||||
struct zr_window basic_demo;
|
||||
struct zr_window grid_demo;
|
||||
struct zr_input input;
|
||||
struct zr_command_queue queue;
|
||||
struct zr_style config;
|
||||
struct zr_user_font font;
|
||||
};
|
||||
|
||||
static void
|
||||
die(const char *fmt, ...)
|
||||
{
|
||||
|
@ -99,71 +88,72 @@ die(const char *fmt, ...)
|
|||
}
|
||||
|
||||
static void
|
||||
ui_header(struct zr_context *layout, struct zr_style *config, const char *title)
|
||||
ui_header(struct zr_context *ctx, const char *title)
|
||||
{
|
||||
zr_style_reset_font_height(config);
|
||||
zr_style_push_font_height(config, 18);
|
||||
zr_layout_row_dynamic(layout, 20, 1);
|
||||
zr_label(layout, title, ZR_TEXT_LEFT);
|
||||
zr_style_reset_font_height(&ctx->style);
|
||||
zr_style_push_font_height(&ctx->style, 18);
|
||||
zr_layout_row_dynamic(ctx, 20, 1);
|
||||
zr_label(ctx, title, ZR_TEXT_LEFT);
|
||||
}
|
||||
|
||||
static void
|
||||
ui_widget(struct zr_context *layout, struct zr_style *config, float height, float font_height)
|
||||
ui_widget(struct zr_context *ctx, float height, float font_height)
|
||||
{
|
||||
static const float ratio[] = {0.15f, 0.85f};
|
||||
zr_style_reset_font_height(config);
|
||||
zr_style_push_font_height(config, font_height);
|
||||
zr_layout_row(layout, ZR_DYNAMIC, height, 2, ratio);
|
||||
zr_spacing(layout, 1);
|
||||
zr_style_reset_font_height(&ctx->style);
|
||||
zr_style_push_font_height(&ctx->style, font_height);
|
||||
zr_layout_row(ctx, ZR_DYNAMIC, height, 2, ratio);
|
||||
zr_spacing(ctx, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
ui_widget_centered(struct zr_context *layout, struct zr_style *config, float height, float font_height)
|
||||
ui_widget_centered(struct zr_context *ctx, float height, float font_height)
|
||||
{
|
||||
static const float ratio[] = {0.15f, 0.50f, 0.35f};
|
||||
zr_style_reset_font_height(config);
|
||||
zr_style_push_font_height(config, font_height);
|
||||
zr_layout_row(layout, ZR_DYNAMIC, height, 3, ratio);
|
||||
zr_spacing(layout, 1);
|
||||
zr_style_reset_font_height(&ctx->style);
|
||||
zr_style_push_font_height(&ctx->style, font_height);
|
||||
zr_layout_row(ctx, ZR_DYNAMIC, height, 3, ratio);
|
||||
zr_spacing(ctx, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
ui_piemenu(struct zr_context *layout, struct zr_style *config,
|
||||
ui_piemenu(struct zr_context *ctx,
|
||||
struct zr_vec2 pos, float radius, int *icons, int item_count)
|
||||
{
|
||||
int ret = -1;
|
||||
struct zr_rect total_space;
|
||||
struct zr_context menu;
|
||||
struct zr_layout popup;
|
||||
struct zr_rect bounds;
|
||||
int active_item = 0;
|
||||
|
||||
/* hide popup background */
|
||||
struct zr_color border;
|
||||
zr_style_push_color(config, ZR_COLOR_WINDOW, zr_rgba(0,0,0,0));
|
||||
border = config->colors[ZR_COLOR_BORDER];
|
||||
zr_style_push_color(config, ZR_COLOR_BORDER, zr_rgba(0,0,0,0));
|
||||
zr_style_push_color(&ctx->style, ZR_COLOR_WINDOW, zr_rgba(0,0,0,0));
|
||||
border = ctx->style.colors[ZR_COLOR_BORDER];
|
||||
zr_style_push_color(&ctx->style, ZR_COLOR_BORDER, zr_rgba(0,0,0,0));
|
||||
|
||||
/* pie menu popup */
|
||||
zr_popup_begin(layout, &menu, ZR_POPUP_STATIC, 0, ZR_WINDOW_NO_SCROLLBAR,
|
||||
zr_rect(pos.x-layout->clip.x-radius,pos.y-radius-layout->clip.y,
|
||||
2*radius,2*radius), zr_vec2(0,0));
|
||||
total_space = zr_space(&menu);
|
||||
total_space = zr_window_get_content_region(ctx);
|
||||
zr_popup_begin(ctx, &popup, ZR_POPUP_STATIC, "piemenu", ZR_WINDOW_NO_SCROLLBAR,
|
||||
zr_rect(pos.x - total_space.x - radius, pos.y - radius - total_space.y,
|
||||
2*radius,2*radius));
|
||||
total_space = zr_window_get_content_region(ctx);
|
||||
|
||||
zr_layout_row_space_begin(&menu, ZR_STATIC, total_space.h, 1);
|
||||
zr_layout_space_begin(ctx, ZR_STATIC, total_space.h, 1);
|
||||
{
|
||||
int i = 0;
|
||||
struct zr_command_buffer* out = zr_canvas(&menu);
|
||||
const struct zr_input *in = zr_input(&menu);
|
||||
struct zr_command_buffer* out = zr_window_get_canvas(ctx);
|
||||
const struct zr_input *in = &ctx->input;
|
||||
{
|
||||
/* allocate complete popup space for the menu */
|
||||
enum zr_widget_state state;
|
||||
total_space = zr_space(&menu);
|
||||
total_space = zr_window_get_content_region(ctx);
|
||||
total_space.x = total_space.y = 0;
|
||||
zr_layout_row_space_push(&menu, total_space);
|
||||
state = zr_widget(&bounds, &menu);
|
||||
zr_layout_space_push(ctx, total_space);
|
||||
state = zr_widget(&bounds, ctx);
|
||||
}
|
||||
/* outer circle */
|
||||
zr_command_buffer_push_circle(out, bounds, zr_rgb(50,50,50));
|
||||
zr_draw_circle(out, bounds, zr_rgb(50,50,50));
|
||||
{
|
||||
/* circle buttons */
|
||||
float step = (2 * 3.141592654f) / (float)(MAX(1,item_count));
|
||||
|
@ -179,14 +169,14 @@ ui_piemenu(struct zr_context *layout, struct zr_style *config,
|
|||
struct zr_image img;
|
||||
struct zr_rect content;
|
||||
float rx, ry, dx, dy, a;
|
||||
zr_command_buffer_push_arc(out, center.x, center.y, (bounds.w/2.0f),
|
||||
zr_draw_arc(out, center.x, center.y, (bounds.w/2.0f),
|
||||
a_min, a_max, (active_item == i) ? zr_rgb(45,100,255) : zr_rgb(75,75,75));
|
||||
|
||||
/* seperator line */
|
||||
rx = bounds.w/2.0f; ry = 0;
|
||||
dx = rx * (float)cos(a_min) - ry * (float)sin(a_min);
|
||||
dy = rx * (float)sin(a_min) + ry * (float)cos(a_min);
|
||||
zr_command_buffer_push_line(out, center.x, center.y,
|
||||
zr_draw_line(out, center.x, center.y,
|
||||
center.x + dx, center.y + dy, zr_rgb(50,50,50));
|
||||
|
||||
/* button content */
|
||||
|
@ -196,7 +186,7 @@ ui_piemenu(struct zr_context *layout, struct zr_style *config,
|
|||
content.x = center.x + ((rx * (float)cos(a) - ry * (float)sin(a)) - content.w/2.0f);
|
||||
content.y = center.y + (rx * (float)sin(a) + ry * (float)cos(a) - content.h/2.0f);
|
||||
img = zr_image_id(icons[i]);
|
||||
zr_command_buffer_push_image(out, content, &img);
|
||||
zr_draw_image(out, content, &img);
|
||||
a_min = a_max; a_max += step;
|
||||
}
|
||||
}
|
||||
|
@ -207,7 +197,7 @@ ui_piemenu(struct zr_context *layout, struct zr_style *config,
|
|||
inner.x = bounds.x + bounds.w/2 - bounds.w/4;
|
||||
inner.y = bounds.y + bounds.h/2 - bounds.h/4;
|
||||
inner.w = bounds.w/2; inner.h = bounds.h/2;
|
||||
zr_command_buffer_push_circle(out, inner, zr_rgb(45,45,45));
|
||||
zr_draw_circle(out, inner, zr_rgb(45,45,45));
|
||||
|
||||
/* active icon content */
|
||||
bounds.w = inner.w / 2.0f;
|
||||
|
@ -215,143 +205,130 @@ ui_piemenu(struct zr_context *layout, struct zr_style *config,
|
|||
bounds.x = inner.x + inner.w/2 - bounds.w/2;
|
||||
bounds.y = inner.y + inner.h/2 - bounds.h/2;
|
||||
img = zr_image_id(icons[active_item]);
|
||||
zr_command_buffer_push_image(out, bounds, &img);
|
||||
zr_draw_image(out, bounds, &img);
|
||||
}
|
||||
}
|
||||
zr_layout_row_space_end(&menu);
|
||||
zr_popup_end(layout, &menu, 0);
|
||||
zr_style_reset_colors(config);
|
||||
zr_style_reset_properties(config);
|
||||
if (!zr_input_is_mouse_down(zr_input(layout), ZR_BUTTON_RIGHT))
|
||||
zr_layout_space_end(ctx);
|
||||
zr_popup_end(ctx);
|
||||
zr_style_reset_colors(&ctx->style);
|
||||
zr_style_reset_properties(&ctx->style);
|
||||
if (!zr_input_is_mouse_down(&ctx->input, ZR_BUTTON_RIGHT))
|
||||
return active_item;
|
||||
else return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
button_demo(struct zr_window *window, struct zr_style *config, struct icons *img)
|
||||
button_demo(struct zr_context *ctx, struct icons *img)
|
||||
{
|
||||
struct zr_context layout;
|
||||
struct zr_context menu;
|
||||
struct zr_layout layout;
|
||||
struct zr_layout menu;
|
||||
static int option = 1;
|
||||
static int toggle0 = 1;
|
||||
static int toggle1 = 0;
|
||||
static int toggle2 = 1;
|
||||
static int music_active = 0;
|
||||
static int contextual_active = 0;
|
||||
static struct zr_rect contextual_bounds;
|
||||
|
||||
config->font.height = 20;
|
||||
zr_begin(&layout, window, "Button Demo");
|
||||
ctx->style.font.height = 20;
|
||||
zr_begin(ctx, &layout, "Button Demo", zr_rect(50,50,255,610),
|
||||
ZR_WINDOW_BORDER|ZR_WINDOW_MOVEABLE|ZR_WINDOW_BORDER_HEADER|ZR_WINDOW_TITLE);
|
||||
|
||||
/*------------------------------------------------
|
||||
* MENU
|
||||
*------------------------------------------------*/
|
||||
zr_menubar_begin(&layout);
|
||||
zr_menubar_begin(ctx);
|
||||
{
|
||||
/* toolbar */
|
||||
zr_layout_row_static(&layout, 40, 40, 4);
|
||||
zr_menu_icon_begin(&layout, &menu, zr_image_id(img->play), 120, &music_active);
|
||||
zr_layout_row_static(ctx, 40, 40, 4);
|
||||
if (zr_menu_icon_begin(ctx, &menu, "Music", zr_image_id(img->play), 120))
|
||||
{
|
||||
/* settings */
|
||||
zr_layout_row_dynamic(&menu, 25, 1);
|
||||
if (zr_menu_item_icon(&menu, zr_image_id(img->play), "Play", ZR_TEXT_RIGHT))
|
||||
zr_menu_close(&menu, &music_active);
|
||||
if (zr_menu_item_icon(&menu, zr_image_id(img->stop), "Stop", ZR_TEXT_RIGHT))
|
||||
zr_menu_close(&menu, &music_active);
|
||||
if (zr_menu_item_icon(&menu, zr_image_id(img->pause), "Pause", ZR_TEXT_RIGHT))
|
||||
zr_menu_close(&menu, &music_active);
|
||||
if (zr_menu_item_icon(&menu, zr_image_id(img->next), "Next", ZR_TEXT_RIGHT))
|
||||
zr_menu_close(&menu, &music_active);
|
||||
if (zr_menu_item_icon(&menu, zr_image_id(img->prev), "Prev", ZR_TEXT_RIGHT))
|
||||
zr_menu_close(&menu, &music_active);
|
||||
zr_layout_row_dynamic(ctx, 25, 1);
|
||||
zr_menu_item_icon(ctx, zr_image_id(img->play), "Play", ZR_TEXT_RIGHT);
|
||||
zr_menu_item_icon(ctx, zr_image_id(img->stop), "Stop", ZR_TEXT_RIGHT);
|
||||
zr_menu_item_icon(ctx, zr_image_id(img->pause), "Pause", ZR_TEXT_RIGHT);
|
||||
zr_menu_item_icon(ctx, zr_image_id(img->next), "Next", ZR_TEXT_RIGHT);
|
||||
zr_menu_item_icon(ctx, zr_image_id(img->prev), "Prev", ZR_TEXT_RIGHT);
|
||||
zr_menu_end(ctx);
|
||||
}
|
||||
zr_menu_end(&layout, &menu);
|
||||
zr_button_image(&layout, zr_image_id(img->tools), ZR_BUTTON_DEFAULT);
|
||||
zr_button_image(&layout, zr_image_id(img->cloud), ZR_BUTTON_DEFAULT);
|
||||
zr_button_image(&layout, zr_image_id(img->pen), ZR_BUTTON_DEFAULT);
|
||||
zr_button_image(ctx, zr_image_id(img->tools), ZR_BUTTON_DEFAULT);
|
||||
zr_button_image(ctx, zr_image_id(img->cloud), ZR_BUTTON_DEFAULT);
|
||||
zr_button_image(ctx, zr_image_id(img->pen), ZR_BUTTON_DEFAULT);
|
||||
}
|
||||
zr_menubar_end(&layout);
|
||||
zr_menubar_end(ctx);
|
||||
|
||||
/*------------------------------------------------
|
||||
* BUTTON
|
||||
*------------------------------------------------*/
|
||||
ui_header(&layout, config, "Push buttons");
|
||||
ui_widget(&layout, config, 35, 22);
|
||||
if (zr_button_text(&layout, "Push me", ZR_BUTTON_DEFAULT))
|
||||
ui_header(ctx, "Push buttons");
|
||||
ui_widget(ctx, 35, 22);
|
||||
if (zr_button_text(ctx, "Push me", ZR_BUTTON_DEFAULT))
|
||||
fprintf(stdout, "pushed!\n");
|
||||
ui_widget(&layout, config, 35, 22);
|
||||
if (zr_button_text_image(&layout, zr_image_id(img->rocket),
|
||||
ui_widget(ctx, 35, 22);
|
||||
if (zr_button_text_image(ctx, zr_image_id(img->rocket),
|
||||
"Styled", ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT))
|
||||
fprintf(stdout, "rocket!\n");
|
||||
|
||||
/*------------------------------------------------
|
||||
* REPEATER
|
||||
*------------------------------------------------*/
|
||||
ui_header(&layout, config, "Repeater");
|
||||
ui_widget(&layout, config, 35, 22);
|
||||
if (zr_button_text(&layout, "Press me", ZR_BUTTON_REPEATER))
|
||||
ui_header(ctx, "Repeater");
|
||||
ui_widget(ctx, 35, 22);
|
||||
if (zr_button_text(ctx, "Press me", ZR_BUTTON_REPEATER))
|
||||
fprintf(stdout, "pressed!\n");
|
||||
|
||||
/*------------------------------------------------
|
||||
* TOGGLE
|
||||
*------------------------------------------------*/
|
||||
ui_header(&layout, config, "Toggle buttons");
|
||||
ui_widget(&layout, config, 35, 22);
|
||||
if (zr_button_text_image(&layout, (toggle0) ? zr_image_id(img->checked):
|
||||
ui_header(ctx, "Toggle buttons");
|
||||
ui_widget(ctx, 35, 22);
|
||||
if (zr_button_text_image(ctx, (toggle0) ? zr_image_id(img->checked):
|
||||
zr_image_id(img->unchecked), "Toggle", ZR_TEXT_LEFT, ZR_BUTTON_DEFAULT))
|
||||
toggle0 = !toggle0;
|
||||
|
||||
ui_widget(&layout, config, 35, 22);
|
||||
if (zr_button_text_image(&layout, (toggle1) ? zr_image_id(img->checked):
|
||||
ui_widget(ctx, 35, 22);
|
||||
if (zr_button_text_image(ctx, (toggle1) ? zr_image_id(img->checked):
|
||||
zr_image_id(img->unchecked), "Toggle", ZR_TEXT_LEFT, ZR_BUTTON_DEFAULT))
|
||||
toggle1 = !toggle1;
|
||||
|
||||
ui_widget(&layout, config, 35, 22);
|
||||
if (zr_button_text_image(&layout, (toggle2) ? zr_image_id(img->checked):
|
||||
ui_widget(ctx, 35, 22);
|
||||
if (zr_button_text_image(ctx, (toggle2) ? zr_image_id(img->checked):
|
||||
zr_image_id(img->unchecked), "Toggle", ZR_TEXT_LEFT, ZR_BUTTON_DEFAULT))
|
||||
toggle2 = !toggle2;
|
||||
|
||||
/*------------------------------------------------
|
||||
* RADIO
|
||||
*------------------------------------------------*/
|
||||
ui_header(&layout, config, "Radio buttons");
|
||||
ui_widget(&layout, config, 35, 22);
|
||||
if (zr_button_text_symbol(&layout, (option == 0)?ZR_SYMBOL_CIRCLE_FILLED:ZR_SYMBOL_CIRCLE,
|
||||
ui_header(ctx, "Radio buttons");
|
||||
ui_widget(ctx, 35, 22);
|
||||
if (zr_button_text_symbol(ctx, (option == 0)?ZR_SYMBOL_CIRCLE_FILLED:ZR_SYMBOL_CIRCLE,
|
||||
"Select", ZR_TEXT_LEFT, ZR_BUTTON_DEFAULT)) option = 0;
|
||||
ui_widget(&layout, config, 35, 22);
|
||||
if (zr_button_text_symbol(&layout, (option == 1)?ZR_SYMBOL_CIRCLE_FILLED:ZR_SYMBOL_CIRCLE,
|
||||
ui_widget(ctx, 35, 22);
|
||||
if (zr_button_text_symbol(ctx, (option == 1)?ZR_SYMBOL_CIRCLE_FILLED:ZR_SYMBOL_CIRCLE,
|
||||
"Select", ZR_TEXT_LEFT, ZR_BUTTON_DEFAULT)) option = 1;
|
||||
ui_widget(&layout, config, 35, 22);
|
||||
if (zr_button_text_symbol(&layout, (option == 2)?ZR_SYMBOL_CIRCLE_FILLED:ZR_SYMBOL_CIRCLE,
|
||||
ui_widget(ctx, 35, 22);
|
||||
if (zr_button_text_symbol(ctx, (option == 2)?ZR_SYMBOL_CIRCLE_FILLED:ZR_SYMBOL_CIRCLE,
|
||||
"Select", ZR_TEXT_LEFT, ZR_BUTTON_DEFAULT)) option = 2;
|
||||
|
||||
/*------------------------------------------------
|
||||
* CONTEXTUAL
|
||||
*------------------------------------------------*/
|
||||
if (zr_input_mouse_clicked(zr_input(&layout), ZR_BUTTON_RIGHT, layout.bounds) &&
|
||||
layout.flags & ZR_WINDOW_ACTIVE) {
|
||||
const struct zr_input *in = zr_input(&layout);
|
||||
contextual_bounds = zr_rect(in->mouse.pos.x, in->mouse.pos.y, 120, 200);
|
||||
contextual_active = zr_true;
|
||||
}
|
||||
if (contextual_active) {
|
||||
config->font.height = 18;
|
||||
zr_contextual_begin(&layout, &menu, ZR_WINDOW_NO_SCROLLBAR, &contextual_active, contextual_bounds);
|
||||
zr_layout_row_dynamic(&menu, 25, 1);
|
||||
if (zr_contextual_item_icon(&menu, zr_image_id(img->copy), "Clone", ZR_TEXT_RIGHT))
|
||||
if (zr_contextual_begin(ctx, &menu, ZR_WINDOW_NO_SCROLLBAR, zr_vec2(120, 200))) {
|
||||
ctx->style.font.height = 18;
|
||||
zr_layout_row_dynamic(ctx, 25, 1);
|
||||
if (zr_contextual_item_icon(ctx, zr_image_id(img->copy), "Clone", ZR_TEXT_RIGHT))
|
||||
fprintf(stdout, "pressed clone!\n");
|
||||
if (zr_contextual_item_icon(&menu, zr_image_id(img->delete), "Delete", ZR_TEXT_RIGHT))
|
||||
if (zr_contextual_item_icon(ctx, zr_image_id(img->delete), "Delete", ZR_TEXT_RIGHT))
|
||||
fprintf(stdout, "pressed delete!\n");
|
||||
if (zr_contextual_item_icon(&menu, zr_image_id(img->convert), "Convert", ZR_TEXT_RIGHT))
|
||||
if (zr_contextual_item_icon(ctx, zr_image_id(img->convert), "Convert", ZR_TEXT_RIGHT))
|
||||
fprintf(stdout, "pressed convert!\n");
|
||||
if (zr_contextual_item_icon(&menu, zr_image_id(img->edit), "Edit", ZR_TEXT_RIGHT))
|
||||
if (zr_contextual_item_icon(ctx, zr_image_id(img->edit), "Edit", ZR_TEXT_RIGHT))
|
||||
fprintf(stdout, "pressed edit!\n");
|
||||
zr_contextual_end(&layout, &menu, &contextual_active);
|
||||
zr_contextual_end(ctx);
|
||||
}
|
||||
zr_end(&layout, window);
|
||||
zr_end(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
basic_demo(struct zr_window *window, struct zr_style *config, struct icons *img)
|
||||
basic_demo(struct zr_context *ctx, struct icons *img)
|
||||
{
|
||||
static int image_active;
|
||||
static int check0 = 1;
|
||||
|
@ -367,106 +344,111 @@ basic_demo(struct zr_window *window, struct zr_style *config, struct icons *img)
|
|||
static int piemenu_active = 0;
|
||||
|
||||
int i = 0;
|
||||
struct zr_context layout;
|
||||
struct zr_context combo;
|
||||
config->font.height = 20;
|
||||
zr_begin(&layout, window, "Basic Demo");
|
||||
struct zr_layout layout;
|
||||
struct zr_layout combo;
|
||||
ctx->style.font.height = 20;
|
||||
zr_begin(ctx, &layout, "Basic Demo", zr_rect(320, 50, 275, 610),
|
||||
ZR_WINDOW_BORDER|ZR_WINDOW_MOVEABLE|ZR_WINDOW_BORDER_HEADER|ZR_WINDOW_TITLE);
|
||||
|
||||
/*------------------------------------------------
|
||||
* POPUP BUTTON
|
||||
*------------------------------------------------*/
|
||||
ui_header(&layout, config, "Popup & Scrollbar & Images");
|
||||
ui_widget(&layout, config, 35, 22);
|
||||
if (zr_button_text_image(&layout, zr_image_id(img->directory),
|
||||
ui_header(ctx, "Popup & Scrollbar & Images");
|
||||
ui_widget(ctx, 35, 22);
|
||||
if (zr_button_text_image(ctx, zr_image_id(img->directory),
|
||||
"Images", ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT))
|
||||
image_active = !image_active;
|
||||
|
||||
/*------------------------------------------------
|
||||
* SELECTED IMAGE
|
||||
*------------------------------------------------*/
|
||||
ui_header(&layout, config, "Selected Image");
|
||||
ui_widget_centered(&layout, config, 100, 22);
|
||||
zr_image(&layout, zr_image_id(img->images[selected_image]));
|
||||
ui_header(ctx, "Selected Image");
|
||||
ui_widget_centered(ctx, 100, 22);
|
||||
zr_image(ctx, zr_image_id(img->images[selected_image]));
|
||||
|
||||
/*------------------------------------------------
|
||||
* IMAGE POPUP
|
||||
*------------------------------------------------*/
|
||||
if (image_active) {
|
||||
struct zr_context popup;
|
||||
static struct zr_vec2 scrollbar;
|
||||
zr_popup_begin(&layout, &popup, ZR_POPUP_STATIC, 0, 0,
|
||||
zr_rect(265, 0, 300, 220), scrollbar);
|
||||
zr_layout_row_static(&popup, 82, 82, 3);
|
||||
struct zr_layout popup;
|
||||
zr_popup_begin(ctx, &popup, ZR_POPUP_STATIC, "Image Popup", 0,
|
||||
zr_rect(265, 0, 300, 220));
|
||||
zr_layout_row_static(ctx, 82, 82, 3);
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if (zr_button_image(&popup, zr_image_id(img->images[i]), ZR_BUTTON_DEFAULT)) {
|
||||
if (zr_button_image(ctx, zr_image_id(img->images[i]), ZR_BUTTON_DEFAULT)) {
|
||||
selected_image = i;
|
||||
image_active = 0;
|
||||
zr_popup_close(&popup);
|
||||
zr_popup_close(ctx);
|
||||
}
|
||||
}
|
||||
zr_popup_end(&layout, &popup, &scrollbar);
|
||||
zr_popup_end(ctx);
|
||||
}
|
||||
|
||||
/*------------------------------------------------
|
||||
* COMBOBOX
|
||||
*------------------------------------------------*/
|
||||
ui_header(&layout, config, "Combo box");
|
||||
ui_widget(&layout, config, 40, 22);
|
||||
zr_combo_begin_text(&layout, &combo, items[selected_item], &combo_active, 200, 0);
|
||||
zr_layout_row_dynamic(&combo, 35, 1);
|
||||
for (i = 0; i < 3; ++i)
|
||||
if (zr_combo_item(&combo, items[i], ZR_TEXT_LEFT))
|
||||
selected_item = i;
|
||||
zr_combo_end(&layout, &combo, &combo_active, 0);
|
||||
|
||||
ui_widget(&layout, config, 40, 22);
|
||||
zr_combo_begin_icon(&layout, &combo, items[selected_icon],
|
||||
zr_image_id(img->images[selected_icon]), &combo2_active, 200, 0);
|
||||
zr_layout_row_dynamic(&combo, 35, 1);
|
||||
for (i = 0; i < 3; ++i)
|
||||
if (zr_combo_item_icon(&combo, zr_image_id(img->images[i]), items[i], ZR_TEXT_RIGHT))
|
||||
selected_icon = i;
|
||||
zr_combo_end(&layout, &combo, &combo2_active, 0);
|
||||
ui_header(ctx, "Combo box");
|
||||
ui_widget(ctx, 40, 22);
|
||||
if (zr_combo_begin_text(ctx, &combo, "items", items[selected_item], 200)) {
|
||||
zr_layout_row_dynamic(ctx, 35, 1);
|
||||
for (i = 0; i < 3; ++i)
|
||||
if (zr_combo_item(ctx, items[i], ZR_TEXT_LEFT))
|
||||
selected_item = i;
|
||||
zr_combo_end(ctx);
|
||||
}
|
||||
|
||||
ui_widget(ctx, 40, 22);
|
||||
if (zr_combo_begin_icon(ctx, &combo, "pictures", items[selected_icon], zr_image_id(img->images[selected_icon]), 200)) {
|
||||
zr_layout_row_dynamic(ctx, 35, 1);
|
||||
for (i = 0; i < 3; ++i)
|
||||
if (zr_combo_item_icon(ctx, zr_image_id(img->images[i]), items[i], ZR_TEXT_RIGHT))
|
||||
selected_icon = i;
|
||||
zr_combo_end(ctx);
|
||||
}
|
||||
/*------------------------------------------------
|
||||
* CHECKBOX
|
||||
*------------------------------------------------*/
|
||||
ui_header(&layout, config, "Checkbox");
|
||||
ui_widget(&layout, config, 30, 22);
|
||||
zr_checkbox(&layout, "Flag 1", &check0);
|
||||
ui_widget(&layout, config, 30, 22);
|
||||
zr_checkbox(&layout, "Flag 2", &check1);
|
||||
ui_header(ctx, "Checkbox");
|
||||
ui_widget(ctx, 30, 22);
|
||||
zr_checkbox(ctx, "Flag 1", &check0);
|
||||
ui_widget(ctx, 30, 22);
|
||||
zr_checkbox(ctx, "Flag 2", &check1);
|
||||
|
||||
/*------------------------------------------------
|
||||
* PROGRESSBAR
|
||||
*------------------------------------------------*/
|
||||
ui_header(&layout, config, "Progressbar");
|
||||
ui_widget(&layout, config, 35, 22);
|
||||
zr_progress(&layout, &prog, 100, zr_true);
|
||||
ui_header(ctx, "Progressbar");
|
||||
ui_widget(ctx, 35, 22);
|
||||
zr_progress(ctx, &prog, 100, zr_true);
|
||||
|
||||
/*------------------------------------------------
|
||||
* SLIDER
|
||||
*------------------------------------------------*/
|
||||
ui_header(&layout, config, "Slider");
|
||||
ui_widget(&layout, config, 35, 22);
|
||||
zr_slider_int(&layout, 0, &slider, 100, 10);
|
||||
ui_header(ctx, "Slider");
|
||||
ui_widget(ctx, 35, 22);
|
||||
zr_slider_int(ctx, 0, &slider, 100, 10);
|
||||
|
||||
/*------------------------------------------------
|
||||
* PIEMENU
|
||||
*------------------------------------------------*/
|
||||
if (zr_input_is_mouse_down(zr_input(&layout), ZR_BUTTON_RIGHT) &&
|
||||
zr_input_is_mouse_hovering_rect(zr_input(&layout), layout.bounds))
|
||||
if (zr_input_is_mouse_down(&ctx->input, ZR_BUTTON_RIGHT) &&
|
||||
zr_input_is_mouse_hovering_rect(&ctx->input, layout.bounds))
|
||||
piemenu_active = 1;
|
||||
|
||||
if (piemenu_active) {
|
||||
int ret = ui_piemenu(&layout, config, zr_vec2(WINDOW_WIDTH/2-140, WINDOW_HEIGHT/2-140), 140, &img->menu[0], 6);
|
||||
int ret = ui_piemenu(ctx, zr_vec2(WINDOW_WIDTH/2-140, WINDOW_HEIGHT/2-140), 140, &img->menu[0], 6);
|
||||
if (ret != -1) {
|
||||
fprintf(stdout, "piemenu selected: %d\n", ret);
|
||||
piemenu_active = 0;
|
||||
}
|
||||
}
|
||||
zr_end(&layout, window);
|
||||
zr_end(ctx);
|
||||
}
|
||||
|
||||
#if 0
|
||||
zr_window_init(&gui.grid_demo, zr_rect(600, 350, 275, 250),
|
||||
ZR_WINDOW_BORDER|ZR_WINDOW_MOVEABLE|ZR_WINDOW_BORDER_HEADER|ZR_WINDOW_NO_SCROLLBAR,
|
||||
&gui.queue, &gui.config, &gui.input);
|
||||
|
||||
static void
|
||||
grid_demo(struct zr_window *window, struct zr_style *config)
|
||||
{
|
||||
|
@ -484,27 +466,28 @@ grid_demo(struct zr_window *window, struct zr_style *config)
|
|||
struct zr_context combo;
|
||||
|
||||
config->font.height = 20;
|
||||
zr_begin(&layout, window, "Grid Demo");
|
||||
zr_begin(ctx, window, "Grid Demo");
|
||||
|
||||
config->font.height = 18;
|
||||
zr_layout_row_dynamic(&layout, 30, 2);
|
||||
zr_label(&layout, "Floating point:", ZR_TEXT_RIGHT);
|
||||
zr_edit(&layout, text[0], &text_len[0], 64, &text_active[0], &text_cursor[0], ZR_INPUT_FLOAT);
|
||||
zr_label(&layout, "Hexadeximal:", ZR_TEXT_RIGHT);
|
||||
zr_edit(&layout, text[1], &text_len[1], 64, &text_active[1], &text_cursor[1], ZR_INPUT_HEX);
|
||||
zr_label(&layout, "Binary:", ZR_TEXT_RIGHT);
|
||||
zr_edit(&layout, text[2], &text_len[2], 64, &text_active[2], &text_cursor[2], ZR_INPUT_BIN);
|
||||
zr_label(&layout, "Checkbox:", ZR_TEXT_RIGHT);
|
||||
zr_checkbox(&layout, "Check me", &check);
|
||||
zr_label(&layout, "Combobox:", ZR_TEXT_RIGHT);
|
||||
zr_combo_begin_text(&layout, &combo, items[selected_item], &combo_active, 200, 0);
|
||||
zr_layout_row_dynamic(ctx, 30, 2);
|
||||
zr_label(ctx, "Floating point:", ZR_TEXT_RIGHT);
|
||||
zr_edit(ctx, text[0], &text_len[0], 64, &text_active[0], &text_cursor[0], ZR_INPUT_FLOAT);
|
||||
zr_label(ctx, "Hexadeximal:", ZR_TEXT_RIGHT);
|
||||
zr_edit(ctx, text[1], &text_len[1], 64, &text_active[1], &text_cursor[1], ZR_INPUT_HEX);
|
||||
zr_label(ctx, "Binary:", ZR_TEXT_RIGHT);
|
||||
zr_edit(ctx, text[2], &text_len[2], 64, &text_active[2], &text_cursor[2], ZR_INPUT_BIN);
|
||||
zr_label(ctx, "Checkbox:", ZR_TEXT_RIGHT);
|
||||
zr_checkbox(ctx, "Check me", &check);
|
||||
zr_label(ctx, "Combobox:", ZR_TEXT_RIGHT);
|
||||
zr_combo_begin_text(ctx, &combo, items[selected_item], &combo_active, 200, 0);
|
||||
zr_layout_row_dynamic(&combo, 30, 1);
|
||||
for (i = 0; i < 3; ++i)
|
||||
if (zr_combo_item(&combo, items[i], ZR_TEXT_LEFT))
|
||||
selected_item = i;
|
||||
zr_combo_end(&layout, &combo, &combo_active, 0);
|
||||
zr_end(&layout, window);
|
||||
zr_combo_end(ctx, &combo, &combo_active, 0);
|
||||
zr_end(ctx, window);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* =================================================================
|
||||
*
|
||||
|
@ -524,7 +507,7 @@ font_get_width(zr_handle handle, float height, const char *text, zr_size len)
|
|||
}
|
||||
|
||||
static void
|
||||
draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
||||
draw(NVGcontext *nvg, struct zr_context *ctx, int width, int height)
|
||||
{
|
||||
const struct zr_command *cmd;
|
||||
glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT);
|
||||
|
@ -536,7 +519,7 @@ draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
|||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
nvgBeginFrame(nvg, width, height, ((float)width/(float)height));
|
||||
zr_foreach_command(cmd, queue) {
|
||||
zr_foreach(cmd, ctx) {
|
||||
switch (cmd->type) {
|
||||
case ZR_COMMAND_NOP: break;
|
||||
case ZR_COMMAND_SCISSOR: {
|
||||
|
@ -548,17 +531,15 @@ draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
|||
nvgBeginPath(nvg);
|
||||
nvgMoveTo(nvg, l->begin.x, l->begin.y);
|
||||
nvgLineTo(nvg, l->end.x, l->end.y);
|
||||
nvgFillColor(nvg, nvgRGBA(l->color.r, l->color.g, l->color.b, l->color.a));
|
||||
nvgFill(nvg);
|
||||
nvgStrokeColor(nvg, nvgRGBA(l->color.r, l->color.g, l->color.b, l->color.a));
|
||||
nvgStroke(nvg);
|
||||
} break;
|
||||
case ZR_COMMAND_CURVE: {
|
||||
const struct zr_command_curve *q = zr_command(curve, cmd);
|
||||
nvgBeginPath(nvg);
|
||||
nvgMoveTo(nvg, q->begin.x, q->begin.y);
|
||||
nvgBezierTo(nvg, q->ctrl[0].x, q->ctrl[0].y, q->ctrl[1].x,
|
||||
q->ctrl[1].y, q->end.x, q->end.y);
|
||||
nvgBezierTo(nvg, q->ctrl[0].x, q->ctrl[0].y, q->ctrl[1].x, q->ctrl[1].y, q->end.x, q->end.y);
|
||||
nvgStrokeColor(nvg, nvgRGBA(q->color.r, q->color.g, q->color.b, q->color.a));
|
||||
nvgStrokeWidth(nvg, 3);
|
||||
nvgStroke(nvg);
|
||||
} break;
|
||||
case ZR_COMMAND_RECT: {
|
||||
|
@ -595,7 +576,6 @@ draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
|||
} break;
|
||||
case ZR_COMMAND_TEXT: {
|
||||
const struct zr_command_text *t = zr_command(text, cmd);
|
||||
const float font_height = t->height;
|
||||
nvgBeginPath(nvg);
|
||||
nvgRoundedRect(nvg, t->x, t->y, t->w, t->h, 0);
|
||||
nvgFillColor(nvg, nvgRGBA(t->background.r, t->background.g,
|
||||
|
@ -622,13 +602,14 @@ draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
|||
default: break;
|
||||
}
|
||||
}
|
||||
zr_command_queue_clear(queue);
|
||||
zr_clear(ctx);
|
||||
|
||||
nvgResetScissor(nvg);
|
||||
nvgEndFrame(nvg);
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
key(struct zr_input *in, SDL_Event *evt, int down)
|
||||
{
|
||||
|
@ -699,11 +680,11 @@ main(int argc, char *argv[])
|
|||
unsigned int dt;
|
||||
int i = 0;
|
||||
|
||||
/* images */
|
||||
struct icons icons;
|
||||
|
||||
/* GUI */
|
||||
struct gui gui;
|
||||
struct icons icons;
|
||||
struct zr_context ctx;
|
||||
void *memory;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stdout,"Missing TTF Font file argument: demo <path>\n");
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -761,70 +742,60 @@ main(int argc, char *argv[])
|
|||
icons.menu[4] = nvgCreateImage(vg, "../icon/settings.png", 0);
|
||||
icons.menu[5] = nvgCreateImage(vg, "../icon/volume.png", 0);
|
||||
for (i = 0; i < 9; ++i) {
|
||||
char buffer[64];
|
||||
char buffer[256];
|
||||
sprintf(buffer, "../images/image%d.jpg", (i+1));
|
||||
icons.images[i] = nvgCreateImage(vg, buffer, 0);
|
||||
}
|
||||
|
||||
/* GUI */
|
||||
memset(&gui, 0, sizeof gui);
|
||||
gui.memory = malloc(MAX_MEMORY);
|
||||
zr_command_queue_init_fixed(&gui.queue, gui.memory, MAX_MEMORY);
|
||||
{
|
||||
/* GUI */
|
||||
struct zr_user_font font;
|
||||
memset(&ctx, 0, sizeof ctx);
|
||||
memory = malloc(MAX_MEMORY);
|
||||
|
||||
gui.font.userdata.ptr = vg;
|
||||
nvgTextMetrics(vg, NULL, NULL, &gui.font.height);
|
||||
gui.font.width = font_get_width;
|
||||
gui.font.height = 20;
|
||||
zr_style_default(&gui.config, ZR_DEFAULT_ALL, &gui.font);
|
||||
gui.config.rounding[ZR_ROUNDING_BUTTON] = 3;
|
||||
|
||||
zr_window_init(&gui.button_demo, zr_rect(50, 50, 255, 600),
|
||||
ZR_WINDOW_BORDER|ZR_WINDOW_MOVEABLE|ZR_WINDOW_BORDER_HEADER,
|
||||
&gui.queue, &gui.config, &gui.input);
|
||||
zr_window_init(&gui.basic_demo, zr_rect(320, 50, 275, 610),
|
||||
ZR_WINDOW_BORDER|ZR_WINDOW_MOVEABLE|ZR_WINDOW_BORDER_HEADER,
|
||||
&gui.queue, &gui.config, &gui.input);
|
||||
zr_window_init(&gui.grid_demo, zr_rect(600, 350, 275, 250),
|
||||
ZR_WINDOW_BORDER|ZR_WINDOW_MOVEABLE|ZR_WINDOW_BORDER_HEADER|ZR_WINDOW_NO_SCROLLBAR,
|
||||
&gui.queue, &gui.config, &gui.input);
|
||||
font.userdata.ptr = vg;
|
||||
font.width = font_get_width;
|
||||
font.height = 20;
|
||||
zr_init_fixed(&ctx, memory, MAX_MEMORY, &font, sin, cos);
|
||||
ctx.style.rounding[ZR_ROUNDING_BUTTON] = 3;
|
||||
}
|
||||
|
||||
while (running) {
|
||||
/* Input */
|
||||
SDL_Event evt;
|
||||
started = SDL_GetTicks();
|
||||
zr_input_begin(&gui.input);
|
||||
zr_input_begin(&ctx.input);
|
||||
while (SDL_PollEvent(&evt)) {
|
||||
if (evt.type == SDL_WINDOWEVENT &&
|
||||
evt.window.event == SDL_WINDOWEVENT_RESIZED)
|
||||
glViewport(0, 0, evt.window.data1, evt.window.data2);
|
||||
else if (evt.type == SDL_QUIT) goto cleanup;
|
||||
else if (evt.type == SDL_KEYUP)
|
||||
key(&gui.input, &evt, zr_false);
|
||||
key(&ctx.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_KEYDOWN)
|
||||
key(&gui.input, &evt, zr_true);
|
||||
key(&ctx.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONDOWN)
|
||||
btn(&gui.input, &evt, zr_true);
|
||||
btn(&ctx.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONUP)
|
||||
btn(&gui.input, &evt, zr_false);
|
||||
btn(&ctx.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_MOUSEMOTION)
|
||||
motion(&gui.input, &evt);
|
||||
motion(&ctx.input, &evt);
|
||||
else if (evt.type == SDL_TEXTINPUT)
|
||||
text(&gui.input, &evt);
|
||||
text(&ctx.input, &evt);
|
||||
else if (evt.type == SDL_MOUSEWHEEL)
|
||||
zr_input_scroll(&gui.input, evt.wheel.y);
|
||||
zr_input_scroll(&ctx.input, evt.wheel.y);
|
||||
}
|
||||
zr_input_end(&gui.input);
|
||||
zr_input_end(&ctx.input);
|
||||
|
||||
/* GUI */
|
||||
button_demo(&gui.button_demo, &gui.config, &icons);
|
||||
basic_demo(&gui.basic_demo, &gui.config, &icons);
|
||||
grid_demo(&gui.grid_demo, &gui.config);
|
||||
button_demo(&ctx, &icons);
|
||||
basic_demo(&ctx, &icons);
|
||||
|
||||
/* Draw */
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
SDL_GetWindowSize(win, &width, &height);
|
||||
draw(vg, &gui.queue, width, height);
|
||||
draw(vg, &ctx, width, height);
|
||||
SDL_GL_SwapWindow(win);
|
||||
|
||||
/* Timing */
|
||||
|
@ -852,7 +823,7 @@ cleanup:
|
|||
for (i = 0; i < 6; ++i)
|
||||
nvgDeleteImage(vg, icons.menu[i]);
|
||||
|
||||
free(gui.memory);
|
||||
free(memory);
|
||||
nvgDeleteGLES2(vg);
|
||||
SDL_GL_DeleteContext(glContext);
|
||||
SDL_DestroyWindow(win);
|
||||
|
|
|
@ -386,13 +386,7 @@ struct file_browser {
|
|||
size_t dir_count;
|
||||
|
||||
/* gui */
|
||||
void *memory;
|
||||
struct media media;
|
||||
struct zr_input input;
|
||||
struct zr_command_queue queue;
|
||||
struct zr_style config;
|
||||
struct zr_user_font font;
|
||||
struct zr_window window;
|
||||
struct zr_vec2 dir;
|
||||
struct zr_vec2 sel;
|
||||
float ratio_dir;
|
||||
|
@ -410,21 +404,11 @@ file_browser_reload_directory_content(struct file_browser *browser, const char *
|
|||
}
|
||||
|
||||
static void
|
||||
file_browser_init(struct file_browser *browser, NVGcontext *vg,
|
||||
struct zr_user_font *font, int width, int height)
|
||||
file_browser_init(struct file_browser *browser, NVGcontext *vg)
|
||||
{
|
||||
memset(browser, 0, sizeof(*browser));
|
||||
browser->ratio_dir = 0.75; browser->ratio_sel = 0.25f;
|
||||
media_init(&browser->media, vg);
|
||||
{
|
||||
/* gui */
|
||||
browser->font = *font;
|
||||
browser->memory = calloc(1, MAX_COMMAND_MEMORY);
|
||||
memset(&browser->input, 0, sizeof(browser->input));
|
||||
zr_command_queue_init_fixed(&browser->queue, browser->memory, MAX_COMMAND_MEMORY);
|
||||
zr_style_default(&browser->config, ZR_DEFAULT_ALL, &browser->font);
|
||||
zr_window_init(&browser->window, zr_rect(0,0,width,height), 0, &browser->queue, &browser->config, &browser->input);
|
||||
browser->ratio_dir = 0.75; browser->ratio_sel = 0.25f;
|
||||
}
|
||||
{
|
||||
/* load files and sub-directory list */
|
||||
const char *home = getenv("HOME");
|
||||
|
@ -463,30 +447,28 @@ file_browser_free(struct file_browser *browser)
|
|||
}
|
||||
|
||||
static int
|
||||
file_browser_run(struct file_browser *browser, int width, int height)
|
||||
file_browser_run(struct file_browser *browser, struct zr_context *ctx, int width, int height)
|
||||
{
|
||||
struct zr_context context;
|
||||
struct zr_layout layout;
|
||||
struct media *media = &browser->media;
|
||||
struct icons *icons = &media->icons;
|
||||
struct zr_rect total_space;
|
||||
|
||||
browser->window.bounds.w = width;
|
||||
browser->window.bounds.h = height;
|
||||
zr_begin(&context, &browser->window, NULL);
|
||||
if (zr_begin(ctx, &layout, "File Browser", zr_rect(0,0,width,height), 0))
|
||||
{
|
||||
struct zr_context sub;
|
||||
struct zr_layout sub;
|
||||
float row_layout[3];
|
||||
/* output path directory selector in the menubar */
|
||||
zr_menubar_begin(&context);
|
||||
zr_menubar_begin(ctx);
|
||||
{
|
||||
char *d = browser->directory;
|
||||
char *begin = d + 1;
|
||||
zr_layout_row_dynamic(&context, 25, 6);
|
||||
zr_style_push_property(&browser->config, ZR_PROPERTY_ITEM_SPACING, zr_vec2(0, 4));
|
||||
zr_layout_row_dynamic(ctx, 25, 6);
|
||||
zr_style_push_property(&ctx->style, ZR_PROPERTY_ITEM_SPACING, zr_vec2(0, 4));
|
||||
while (*d++) {
|
||||
if (*d == '/') {
|
||||
*d = '\0';
|
||||
if (zr_button_text(&context, begin, ZR_BUTTON_DEFAULT)) {
|
||||
if (zr_button_text(ctx, begin, ZR_BUTTON_DEFAULT)) {
|
||||
*d++ = '/'; *d = '\0';
|
||||
file_browser_reload_directory_content(browser, browser->directory);
|
||||
break;
|
||||
|
@ -495,43 +477,43 @@ file_browser_run(struct file_browser *browser, int width, int height)
|
|||
begin = d + 1;
|
||||
}
|
||||
}
|
||||
zr_style_pop_property(&browser->config);
|
||||
zr_style_pop_property(&ctx->style);
|
||||
}
|
||||
zr_menubar_end(&context);
|
||||
zr_menubar_end(ctx);
|
||||
|
||||
/* window layout */
|
||||
total_space = zr_space(&context);
|
||||
total_space = zr_window_get_content_region(ctx);
|
||||
row_layout[0] = (total_space.w - 8) * browser->ratio_sel;
|
||||
row_layout[1] = 8;
|
||||
row_layout[2] = (total_space.w - 8) * browser->ratio_dir;
|
||||
zr_layout_row(&context, ZR_STATIC, total_space.h, 3, row_layout);
|
||||
zr_style_push_property(&browser->config, ZR_PROPERTY_ITEM_SPACING, zr_vec2(0, 4));
|
||||
zr_layout_row(ctx, ZR_STATIC, total_space.h, 3, row_layout);
|
||||
zr_style_push_property(&ctx->style, ZR_PROPERTY_ITEM_SPACING, zr_vec2(0, 4));
|
||||
|
||||
/* output special important directory list in own window */
|
||||
zr_group_begin(&context, &sub, NULL, ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_BORDER, browser->sel);
|
||||
zr_group_begin(ctx, &sub, "Special", ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_BORDER);
|
||||
{
|
||||
struct zr_image home = icons->home.img;
|
||||
struct zr_image desktop = icons->desktop.img;
|
||||
struct zr_image computer = icons->computer.img;
|
||||
|
||||
zr_layout_row_dynamic(&sub, 40, 1);
|
||||
zr_style_push_property(&browser->config, ZR_PROPERTY_ITEM_SPACING, zr_vec2(0, 0));
|
||||
if (zr_button_text_image(&sub, home, "home", ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT))
|
||||
zr_layout_row_dynamic(ctx, 40, 1);
|
||||
zr_style_push_property(&ctx->style, ZR_PROPERTY_ITEM_SPACING, zr_vec2(0, 0));
|
||||
if (zr_button_text_image(ctx, home, "home", ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT))
|
||||
file_browser_reload_directory_content(browser, browser->home);
|
||||
if (zr_button_text_image(&sub,desktop,"desktop",ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT))
|
||||
if (zr_button_text_image(ctx,desktop,"desktop",ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT))
|
||||
file_browser_reload_directory_content(browser, browser->desktop);
|
||||
if (zr_button_text_image(&sub,computer,"computer",ZR_TEXT_CENTERED,ZR_BUTTON_DEFAULT))
|
||||
if (zr_button_text_image(ctx,computer,"computer",ZR_TEXT_CENTERED,ZR_BUTTON_DEFAULT))
|
||||
file_browser_reload_directory_content(browser, "/");
|
||||
zr_style_pop_property(&browser->config);
|
||||
zr_style_pop_property(&ctx->style);
|
||||
zr_group_end(ctx);
|
||||
}
|
||||
zr_group_end(&context, &sub, &browser->sel);
|
||||
|
||||
{
|
||||
/* scaler */
|
||||
struct zr_rect bounds;
|
||||
struct zr_input *in = &browser->input;
|
||||
zr_layout_peek(&bounds, &context);
|
||||
zr_spacing(&context, 1);
|
||||
struct zr_input *in = &ctx->input;
|
||||
zr_layout_peek(&bounds, ctx);
|
||||
zr_spacing(ctx, 1);
|
||||
if ((zr_input_is_mouse_hovering_rect(in, bounds) ||
|
||||
zr_input_is_mouse_prev_hovering_rect(in, bounds)) &&
|
||||
zr_input_is_mouse_down(in, ZR_BUTTON_LEFT))
|
||||
|
@ -544,7 +526,7 @@ file_browser_run(struct file_browser *browser, int width, int height)
|
|||
}
|
||||
|
||||
/* output directory content window */
|
||||
zr_group_begin(&context, &sub, NULL, ZR_WINDOW_BORDER, browser->dir);
|
||||
zr_group_begin(ctx, &sub, "Content", ZR_WINDOW_BORDER);
|
||||
{
|
||||
int index = -1;
|
||||
size_t i = 0, j = 0, k = 0;
|
||||
|
@ -557,20 +539,20 @@ file_browser_run(struct file_browser *browser, int width, int height)
|
|||
{
|
||||
/* draw one row of icons */
|
||||
size_t n = j + cols;
|
||||
zr_layout_row_dynamic(&sub, 135, cols);
|
||||
zr_style_push_color(&browser->config, ZR_COLOR_BUTTON, zr_rgb(45, 45, 45));
|
||||
zr_style_push_color(&browser->config, ZR_COLOR_BORDER, zr_rgb(45, 45, 45));
|
||||
zr_layout_row_dynamic(ctx, 135, cols);
|
||||
zr_style_push_color(&ctx->style, ZR_COLOR_BUTTON, zr_rgb(45, 45, 45));
|
||||
zr_style_push_color(&ctx->style, ZR_COLOR_BORDER, zr_rgb(45, 45, 45));
|
||||
for (; j < count && j < n; ++j) {
|
||||
if (j < browser->dir_count) {
|
||||
/* draw and execute directory buttons */
|
||||
if (zr_button_image(&sub,icons->directory.img,ZR_BUTTON_DEFAULT))
|
||||
if (zr_button_image(ctx,icons->directory.img,ZR_BUTTON_DEFAULT))
|
||||
index = (int)j;
|
||||
} else {
|
||||
/* draw and execute files buttons */
|
||||
struct icon *icon;
|
||||
size_t fileIndex = ((size_t)j - browser->dir_count);
|
||||
icon = media_icon_for_file(media,browser->files[fileIndex]);
|
||||
if (zr_button_image(&sub, icon->img, ZR_BUTTON_DEFAULT)) {
|
||||
if (zr_button_image(ctx, icon->img, ZR_BUTTON_DEFAULT)) {
|
||||
strncpy(browser->file, browser->directory, MAX_PATH_LEN);
|
||||
n = strlen(browser->file);
|
||||
strncpy(browser->file + n, browser->files[fileIndex], MAX_PATH_LEN - n);
|
||||
|
@ -578,19 +560,19 @@ file_browser_run(struct file_browser *browser, int width, int height)
|
|||
}
|
||||
}
|
||||
}
|
||||
zr_style_pop_color(&browser->config);
|
||||
zr_style_pop_color(&browser->config);
|
||||
zr_style_pop_color(&ctx->style);
|
||||
zr_style_pop_color(&ctx->style);
|
||||
}
|
||||
{
|
||||
/* draw one row of labels */
|
||||
size_t n = k + cols;
|
||||
zr_layout_row_dynamic(&sub, 20, cols);
|
||||
zr_layout_row_dynamic(ctx, 20, cols);
|
||||
for (; k < count && k < n; k++) {
|
||||
if (k < browser->dir_count) {
|
||||
zr_label(&sub, browser->directories[k], ZR_TEXT_CENTERED);
|
||||
zr_label(ctx, browser->directories[k], ZR_TEXT_CENTERED);
|
||||
} else {
|
||||
size_t t = k-browser->dir_count;
|
||||
zr_label(&sub,browser->files[t],ZR_TEXT_CENTERED);
|
||||
zr_label(ctx,browser->files[t],ZR_TEXT_CENTERED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -606,11 +588,11 @@ file_browser_run(struct file_browser *browser, int width, int height)
|
|||
}
|
||||
file_browser_reload_directory_content(browser, browser->directory);
|
||||
}
|
||||
zr_group_end(ctx);
|
||||
}
|
||||
zr_group_end(&context, &sub, &browser->dir);
|
||||
zr_style_pop_property(&browser->config);
|
||||
zr_style_pop_property(&ctx->style);
|
||||
}
|
||||
zr_end(&context, &browser->window);
|
||||
zr_end(ctx);
|
||||
return 1;
|
||||
}
|
||||
/* =================================================================
|
||||
|
@ -631,7 +613,7 @@ font_get_width(zr_handle handle, float height, const char *text, size_t len)
|
|||
}
|
||||
|
||||
static void
|
||||
draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
||||
draw(NVGcontext *nvg, struct zr_context *ctx, int width, int height)
|
||||
{
|
||||
const struct zr_command *cmd;
|
||||
glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT);
|
||||
|
@ -643,7 +625,7 @@ draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
|||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
nvgBeginFrame(nvg, width, height, ((float)width/(float)height));
|
||||
zr_foreach_command(cmd, queue) {
|
||||
zr_foreach(cmd, ctx) {
|
||||
switch (cmd->type) {
|
||||
case ZR_COMMAND_NOP: break;
|
||||
case ZR_COMMAND_SCISSOR: {
|
||||
|
@ -724,7 +706,7 @@ draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
|||
default: break;
|
||||
}
|
||||
}
|
||||
zr_command_queue_clear(queue);
|
||||
zr_clear(ctx);
|
||||
|
||||
nvgResetScissor(nvg);
|
||||
nvgEndFrame(nvg);
|
||||
|
@ -795,15 +777,14 @@ resize(SDL_Event *evt)
|
|||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int x,y,width, height;
|
||||
int width, height;
|
||||
SDL_Window *win;
|
||||
SDL_GLContext glContext;
|
||||
NVGcontext *vg = NULL;
|
||||
struct zr_context ctx;
|
||||
void *memory;
|
||||
|
||||
int running = 1;
|
||||
unsigned int started;
|
||||
unsigned int dt;
|
||||
struct zr_user_font font;
|
||||
struct file_browser browser;
|
||||
const char *font_path;
|
||||
int icon_sheet;
|
||||
|
@ -820,7 +801,6 @@ main(int argc, char *argv[])
|
|||
WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN);
|
||||
glContext = SDL_GL_CreateContext(win);
|
||||
SDL_GetWindowSize(win, &width, &height);
|
||||
SDL_GetWindowPosition(win, &x, &y);
|
||||
|
||||
/* OpenGL */
|
||||
glewExperimental = 1;
|
||||
|
@ -836,44 +816,47 @@ main(int argc, char *argv[])
|
|||
nvgFontSize(vg, 14);
|
||||
nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE);
|
||||
|
||||
/* GUI */
|
||||
memset(&browser, 0, sizeof browser);
|
||||
font.userdata.ptr = vg;
|
||||
nvgTextMetrics(vg, NULL, NULL, &font.height);
|
||||
font.width = font_get_width;
|
||||
file_browser_init(&browser, vg, &font, width, height);
|
||||
{
|
||||
/* GUI */
|
||||
struct zr_user_font font;
|
||||
memory = malloc(MAX_MEMORY);
|
||||
font.userdata.ptr = vg;
|
||||
font.width = font_get_width;
|
||||
nvgTextMetrics(vg, NULL, NULL, &font.height);
|
||||
zr_init_fixed(&ctx, memory, MAX_MEMORY, &font, sin, cos);
|
||||
file_browser_init(&browser, vg);
|
||||
}
|
||||
|
||||
while (running) {
|
||||
/* Input */
|
||||
SDL_Event evt;
|
||||
started = SDL_GetTicks();
|
||||
zr_input_begin(&browser.input);
|
||||
zr_input_begin(&ctx.input);
|
||||
while (SDL_PollEvent(&evt)) {
|
||||
if (evt.type == SDL_WINDOWEVENT) resize(&evt);
|
||||
else if (evt.type == SDL_QUIT) goto cleanup;
|
||||
else if (evt.type == SDL_KEYUP) key(&browser.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_KEYDOWN) key(&browser.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONDOWN) btn(&browser.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONUP) btn(&browser.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_MOUSEMOTION) motion(&browser.input, &evt);
|
||||
else if (evt.type == SDL_TEXTINPUT) text(&browser.input, &evt);
|
||||
else if (evt.type == SDL_MOUSEWHEEL) zr_input_scroll(&browser.input, evt.wheel.y);
|
||||
else if (evt.type == SDL_KEYUP) key(&ctx.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_KEYDOWN) key(&ctx.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONDOWN) btn(&ctx.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONUP) btn(&ctx.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_MOUSEMOTION) motion(&ctx.input, &evt);
|
||||
else if (evt.type == SDL_TEXTINPUT) text(&ctx.input, &evt);
|
||||
else if (evt.type == SDL_MOUSEWHEEL) zr_input_scroll(&ctx.input, evt.wheel.y);
|
||||
}
|
||||
zr_input_end(&browser.input);
|
||||
zr_input_end(&ctx.input);
|
||||
|
||||
SDL_GetWindowSize(win, &width, &height);
|
||||
running = file_browser_run(&browser, width, height);
|
||||
running = file_browser_run(&browser, &ctx, width, height);
|
||||
|
||||
/* Draw */
|
||||
glClearColor(0.4f, 0.4f, 0.4f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
draw(vg, &browser.queue, width, height);
|
||||
draw(vg, &ctx, width, height);
|
||||
SDL_GL_SwapWindow(win);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
/* Cleanup */
|
||||
free(browser.memory);
|
||||
free(memory);
|
||||
nvgDeleteGLES2(vg);
|
||||
SDL_GL_DeleteContext(glContext);
|
||||
SDL_DestroyWindow(win);
|
||||
|
|
|
@ -90,7 +90,6 @@ struct node_editor {
|
|||
struct node *end;
|
||||
int node_count;
|
||||
int link_count;
|
||||
int menu;
|
||||
struct zr_rect bounds;
|
||||
struct node *selected;
|
||||
int show_grid;
|
||||
|
@ -98,15 +97,6 @@ struct node_editor {
|
|||
struct node_linking linking;
|
||||
};
|
||||
|
||||
struct gui {
|
||||
void *memory;
|
||||
struct zr_window window;
|
||||
struct zr_input input;
|
||||
struct zr_command_queue queue;
|
||||
struct zr_style config;
|
||||
struct zr_user_font font;
|
||||
};
|
||||
|
||||
/* =================================================================
|
||||
*
|
||||
* NODE EDITOR
|
||||
|
@ -191,22 +181,21 @@ node_editor_link(struct node_editor *editor, int in_id, int in_slot,
|
|||
}
|
||||
|
||||
static void
|
||||
node_editor_draw(struct zr_context *layout, struct node_editor *nodedit,
|
||||
struct zr_style *config)
|
||||
node_editor_draw(struct zr_context *ctx, struct node_editor *nodedit)
|
||||
{
|
||||
int i = 0, n = 0;
|
||||
struct zr_rect total_space;
|
||||
const struct zr_input *in = zr_input(layout);
|
||||
struct zr_command_buffer *canvas = zr_canvas(layout);
|
||||
const struct zr_input *in = &ctx->input;
|
||||
struct zr_command_buffer *canvas = zr_window_get_canvas(ctx);
|
||||
struct node *updated = 0;
|
||||
|
||||
/* allocate complete window space */
|
||||
total_space = zr_space(layout);
|
||||
zr_layout_row_space_begin(layout, ZR_STATIC, total_space.h, (zr_size)nodedit->node_count);
|
||||
total_space = zr_window_get_content_region(ctx);
|
||||
zr_layout_space_begin(ctx, ZR_STATIC, total_space.h, (zr_size)nodedit->node_count);
|
||||
{
|
||||
struct zr_context node;
|
||||
struct zr_layout node, menu;
|
||||
struct node *it = nodedit->begin;
|
||||
struct zr_rect size = zr_layout_row_space_bounds(layout);
|
||||
struct zr_rect size = zr_layout_space_bounds(ctx);
|
||||
|
||||
if (nodedit->show_grid) {
|
||||
/* display grid */
|
||||
|
@ -214,56 +203,52 @@ node_editor_draw(struct zr_context *layout, struct node_editor *nodedit,
|
|||
const float grid_size = 32.0f;
|
||||
const struct zr_color grid_color = zr_rgb(50, 50, 50);
|
||||
for (x = (float)fmod(size.x - nodedit->scrolling.x, grid_size); x < size.w; x += grid_size)
|
||||
zr_command_buffer_push_line(canvas, x+size.x, size.y, x+size.x, size.y+size.h, grid_color);
|
||||
zr_draw_line(canvas, x+size.x, size.y, x+size.x, size.y+size.h, grid_color);
|
||||
for (y = (float)fmod(size.y - nodedit->scrolling.y, grid_size); y < size.h; y += grid_size)
|
||||
zr_command_buffer_push_line(canvas, size.x, y+size.y, size.x+size.w, y+size.y, grid_color);
|
||||
zr_draw_line(canvas, size.x, y+size.y, size.x+size.w, y+size.y, grid_color);
|
||||
}
|
||||
|
||||
/* execute each node as a moveable group */
|
||||
zr_style_push_color(config, ZR_COLOR_WINDOW, zr_rgb(48, 48, 48));
|
||||
zr_style_push_color(&ctx->style, ZR_COLOR_WINDOW, zr_rgb(48, 48, 48));
|
||||
while (it) {
|
||||
/* calculate node group space */
|
||||
zr_layout_row_space_push(layout, zr_rect(it->bounds.x - nodedit->scrolling.x,
|
||||
|
||||
/* calculate scrolled node window position and size */
|
||||
zr_layout_space_push(ctx, zr_rect(it->bounds.x - nodedit->scrolling.x,
|
||||
it->bounds.y - nodedit->scrolling.y, it->bounds.w, it->bounds.h));
|
||||
|
||||
/* execute node window */
|
||||
zr_group_begin(layout, &node, it->name,
|
||||
ZR_WINDOW_MOVEABLE|ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_BORDER, zr_vec2(0,0));
|
||||
if (zr_group_begin(ctx, &node, it->name, ZR_WINDOW_MOVEABLE|ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_BORDER|ZR_WINDOW_TITLE))
|
||||
{
|
||||
int r,g,b;
|
||||
float ratio[] = {0.25f, 0.75f};
|
||||
|
||||
static const float ratio[] = {0.25f, 0.75f};
|
||||
/* always have last selected node on top */
|
||||
if (zr_input_mouse_clicked(in, ZR_BUTTON_LEFT, node.bounds) &&
|
||||
(!(it->prev && zr_input_mouse_clicked(in, ZR_BUTTON_LEFT,
|
||||
zr_layout_row_space_rect_to_screen(layout, node.bounds)))) &&
|
||||
zr_layout_space_rect_to_screen(ctx, node.bounds)))) &&
|
||||
nodedit->end != it)
|
||||
{
|
||||
updated = it;
|
||||
}
|
||||
|
||||
/* ================= NODE CONTENT =====================*/
|
||||
zr_layout_row_dynamic(&node, 30, 1);
|
||||
r = it->color.r, g = it->color.g, b = it->color.b;
|
||||
zr_button_color(&node, it->color, ZR_BUTTON_DEFAULT);
|
||||
zr_layout_row(&node, ZR_DYNAMIC, 30, 2, ratio);
|
||||
zr_layout_row_dynamic(ctx, 30, 1);
|
||||
zr_button_color(ctx, it->color, ZR_BUTTON_DEFAULT);
|
||||
zr_layout_row(ctx, ZR_DYNAMIC, 30, 2, ratio);
|
||||
|
||||
zr_label(&node, "R:", ZR_TEXT_LEFT);
|
||||
zr_slider_int(&node, 0, &r, 255, 10);
|
||||
zr_label(&node, "G:", ZR_TEXT_LEFT);
|
||||
zr_slider_int(&node, 0, &g, 255, 10);
|
||||
zr_label(&node, "B:", ZR_TEXT_LEFT);
|
||||
zr_slider_int(&node, 0, &b, 255, 10);
|
||||
it->color.r = (zr_byte)r; it->color.g = (zr_byte)g; it->color.b = (zr_byte)b;
|
||||
zr_label(ctx, "R:", ZR_TEXT_LEFT);
|
||||
it->color.r = (zr_byte)zr_slide_int(ctx, 0, it->color.r, 255, 10);
|
||||
zr_label(ctx, "G:", ZR_TEXT_LEFT);
|
||||
it->color.g = (zr_byte)zr_slide_int(ctx, 0, it->color.g, 255, 10);
|
||||
zr_label(ctx, "B:", ZR_TEXT_LEFT);
|
||||
it->color.b = (zr_byte)zr_slide_int(ctx, 0, it->color.b, 255, 10);
|
||||
/* ====================================================*/
|
||||
zr_group_end(ctx);
|
||||
}
|
||||
zr_group_end(layout, &node, NULL);
|
||||
|
||||
{
|
||||
/* node connector and linking */
|
||||
float space;
|
||||
struct zr_rect bounds;
|
||||
bounds = zr_layout_row_space_rect_to_local(layout, node.bounds);
|
||||
bounds = zr_layout_space_rect_to_local(ctx, node.bounds);
|
||||
bounds.x += nodedit->scrolling.x;
|
||||
bounds.y += nodedit->scrolling.y;
|
||||
it->bounds = bounds;
|
||||
|
@ -275,7 +260,7 @@ node_editor_draw(struct zr_context *layout, struct node_editor *nodedit,
|
|||
circle.x = node.bounds.x + node.bounds.w-4;
|
||||
circle.y = node.bounds.y + space * (n+1);
|
||||
circle.w = 8; circle.h = 8;
|
||||
zr_command_buffer_push_circle(canvas, circle, zr_rgb(100, 100, 100));
|
||||
zr_draw_circle(canvas, circle, zr_rgb(100, 100, 100));
|
||||
|
||||
/* start linking process */
|
||||
if (zr_input_is_mouse_click_in_rect(in, ZR_BUTTON_LEFT, circle)) {
|
||||
|
@ -290,7 +275,7 @@ node_editor_draw(struct zr_context *layout, struct node_editor *nodedit,
|
|||
nodedit->linking.input_slot == n) {
|
||||
struct zr_vec2 l0 = zr_vec2(circle.x + 3, circle.y + 3);
|
||||
struct zr_vec2 l1 = in->mouse.pos;
|
||||
zr_command_buffer_push_curve(canvas, l0.x, l0.y, l0.x + 50.0f, l0.y,
|
||||
zr_draw_curve(canvas, l0.x, l0.y, l0.x + 50.0f, l0.y,
|
||||
l1.x - 50.0f, l1.y, l1.x, l1.y, zr_rgb(100, 100, 100));
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +287,7 @@ node_editor_draw(struct zr_context *layout, struct node_editor *nodedit,
|
|||
circle.x = node.bounds.x-4;
|
||||
circle.y = node.bounds.y + space * (n+1);
|
||||
circle.w = 8; circle.h = 8;
|
||||
zr_command_buffer_push_circle(canvas, circle, zr_rgb(100, 100, 100));
|
||||
zr_draw_circle(canvas, circle, zr_rgb(100, 100, 100));
|
||||
if (zr_input_is_mouse_released(in, ZR_BUTTON_LEFT) &&
|
||||
zr_input_is_mouse_hovering_rect(in, circle) &&
|
||||
nodedit->linking.active && nodedit->linking.node != it) {
|
||||
|
@ -329,34 +314,33 @@ node_editor_draw(struct zr_context *layout, struct node_editor *nodedit,
|
|||
struct node *no = node_editor_find(nodedit, link->output_id);
|
||||
float spacei = node.bounds.h / ((ni->output_count) + 1);
|
||||
float spaceo = node.bounds.h / ((no->input_count) + 1);
|
||||
struct zr_vec2 l0 = zr_layout_row_space_to_screen(layout,
|
||||
struct zr_vec2 l0 = zr_layout_space_to_screen(ctx,
|
||||
zr_vec2(ni->bounds.x + ni->bounds.w, 3+ni->bounds.y + spacei * (link->input_slot+1)));
|
||||
struct zr_vec2 l1 = zr_layout_row_space_to_screen(layout,
|
||||
struct zr_vec2 l1 = zr_layout_space_to_screen(ctx,
|
||||
zr_vec2(no->bounds.x, 3 + no->bounds.y + spaceo * (link->output_slot+1)));
|
||||
|
||||
l0.x -= nodedit->scrolling.x;
|
||||
l0.y -= nodedit->scrolling.y;
|
||||
l1.x -= nodedit->scrolling.x;
|
||||
l1.y -= nodedit->scrolling.y;
|
||||
zr_command_buffer_push_curve(canvas, l0.x, l0.y, l0.x + 50.0f, l0.y,
|
||||
zr_draw_curve(canvas, l0.x, l0.y, l0.x + 50.0f, l0.y,
|
||||
l1.x - 50.0f, l1.y, l1.x, l1.y, zr_rgb(100, 100, 100));
|
||||
}
|
||||
zr_style_pop_color(config);
|
||||
zr_style_pop_color(&ctx->style);
|
||||
|
||||
if (updated) {
|
||||
/* reshuffle nodes to have last recently selected node on the top */
|
||||
/* reshuffle nodes to have last recently selected node on top */
|
||||
node_editor_pop(nodedit, updated);
|
||||
node_editor_push(nodedit, updated);
|
||||
}
|
||||
|
||||
/* node selection + right click popup context menu activation */
|
||||
if (!nodedit->menu && zr_input_mouse_clicked(in, ZR_BUTTON_RIGHT, zr_layout_row_space_bounds(layout))) {
|
||||
/* node selection */
|
||||
if (zr_input_mouse_clicked(in, ZR_BUTTON_LEFT, zr_layout_space_bounds(ctx))) {
|
||||
it = nodedit->begin;
|
||||
nodedit->selected = NULL;
|
||||
nodedit->menu = zr_true;
|
||||
nodedit->bounds = zr_rect(in->mouse.pos.x, in->mouse.pos.y, 100, 200);
|
||||
while (it) {
|
||||
struct zr_rect b = zr_layout_row_space_rect_to_screen(layout, it->bounds);
|
||||
struct zr_rect b = zr_layout_space_rect_to_screen(ctx, it->bounds);
|
||||
b.x -= nodedit->scrolling.x;
|
||||
b.y -= nodedit->scrolling.y;
|
||||
if (zr_input_is_mouse_hovering_rect(in, b))
|
||||
|
@ -365,35 +349,22 @@ node_editor_draw(struct zr_context *layout, struct node_editor *nodedit,
|
|||
}
|
||||
}
|
||||
|
||||
/* popup context menu */
|
||||
if (nodedit->menu) {
|
||||
struct zr_context menu;
|
||||
/* contextual menu */
|
||||
if (zr_contextual_begin(ctx, &menu, 0, zr_vec2(100, 220))) {
|
||||
const char *grid_option[] = {"Show Grid", "Hide Grid"};
|
||||
zr_contextual_begin(layout, &menu, ZR_WINDOW_NO_SCROLLBAR, &nodedit->menu, nodedit->bounds);
|
||||
zr_layout_row_dynamic(&menu, 25, 1);
|
||||
if (!nodedit->selected) {
|
||||
/* menu content if no selected node */
|
||||
if (zr_contextual_item(&menu, "New", ZR_TEXT_CENTERED))
|
||||
node_editor_add(nodedit, "New", zr_rect(400, 260, 180, 220),
|
||||
zr_rgb(255, 255, 255), 1, 2);
|
||||
if (zr_contextual_item(&menu, grid_option[nodedit->show_grid],ZR_TEXT_CENTERED))
|
||||
nodedit->show_grid = !nodedit->show_grid;
|
||||
} else {
|
||||
/* menu content if selected node */
|
||||
if (zr_contextual_item(&menu, "Delete", ZR_TEXT_CENTERED))
|
||||
fprintf(stdout, "pressed delete!\n");
|
||||
if (zr_contextual_item(&menu, "Rename", ZR_TEXT_CENTERED))
|
||||
fprintf(stdout, "pressed rename!\n");
|
||||
if (zr_contextual_item(&menu, "Copy", ZR_TEXT_CENTERED))
|
||||
fprintf(stdout, "pressed copy!\n");
|
||||
}
|
||||
zr_contextual_end(layout, &menu, &nodedit->menu);
|
||||
zr_layout_row_dynamic(ctx, 25, 1);
|
||||
if (zr_contextual_item(ctx, "New", ZR_TEXT_CENTERED))
|
||||
node_editor_add(nodedit, "New", zr_rect(400, 260, 180, 220),
|
||||
zr_rgb(255, 255, 255), 1, 2);
|
||||
if (zr_contextual_item(ctx, grid_option[nodedit->show_grid],ZR_TEXT_CENTERED))
|
||||
nodedit->show_grid = !nodedit->show_grid;
|
||||
zr_contextual_end(ctx);
|
||||
}
|
||||
}
|
||||
zr_layout_row_space_end(layout);
|
||||
zr_layout_space_end(ctx);
|
||||
|
||||
/* window content scrolling */
|
||||
if (zr_input_is_mouse_hovering_rect(in, layout->bounds) &&
|
||||
if (zr_input_is_mouse_hovering_rect(in, zr_window_get_bounds(ctx)) &&
|
||||
zr_input_is_mouse_down(in, ZR_BUTTON_MIDDLE)) {
|
||||
nodedit->scrolling.x += in->mouse.delta.x;
|
||||
nodedit->scrolling.y += in->mouse.delta.y;
|
||||
|
@ -444,7 +415,7 @@ font_get_width(zr_handle handle, float height, const char *text, size_t len)
|
|||
}
|
||||
|
||||
static void
|
||||
draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
||||
draw(NVGcontext *nvg, struct zr_context *ctx, int width, int height)
|
||||
{
|
||||
const struct zr_command *cmd;
|
||||
glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT);
|
||||
|
@ -456,7 +427,7 @@ draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
|||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
nvgBeginFrame(nvg, width, height, ((float)width/(float)height));
|
||||
zr_foreach_command(cmd, queue) {
|
||||
zr_foreach(cmd, ctx) {
|
||||
switch (cmd->type) {
|
||||
case ZR_COMMAND_NOP: break;
|
||||
case ZR_COMMAND_SCISSOR: {
|
||||
|
@ -468,17 +439,15 @@ draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
|||
nvgBeginPath(nvg);
|
||||
nvgMoveTo(nvg, l->begin.x, l->begin.y);
|
||||
nvgLineTo(nvg, l->end.x, l->end.y);
|
||||
nvgFillColor(nvg, nvgRGBA(l->color.r, l->color.g, l->color.b, l->color.a));
|
||||
nvgFill(nvg);
|
||||
nvgStrokeColor(nvg, nvgRGBA(l->color.r, l->color.g, l->color.b, l->color.a));
|
||||
nvgStroke(nvg);
|
||||
} break;
|
||||
case ZR_COMMAND_CURVE: {
|
||||
const struct zr_command_curve *q = zr_command(curve, cmd);
|
||||
nvgBeginPath(nvg);
|
||||
nvgMoveTo(nvg, q->begin.x, q->begin.y);
|
||||
nvgBezierTo(nvg, q->ctrl[0].x, q->ctrl[0].y, q->ctrl[1].x,
|
||||
q->ctrl[1].y, q->end.x, q->end.y);
|
||||
nvgBezierTo(nvg, q->ctrl[0].x, q->ctrl[0].y, q->ctrl[1].x, q->ctrl[1].y, q->end.x, q->end.y);
|
||||
nvgStrokeColor(nvg, nvgRGBA(q->color.r, q->color.g, q->color.b, q->color.a));
|
||||
nvgStrokeWidth(nvg, 3);
|
||||
nvgStroke(nvg);
|
||||
} break;
|
||||
case ZR_COMMAND_RECT: {
|
||||
|
@ -530,10 +499,11 @@ draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height)
|
|||
nvgFillPaint(nvg, imgpaint);
|
||||
nvgFill(nvg);
|
||||
} break;
|
||||
case ZR_COMMAND_ARC:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
zr_command_queue_clear(queue);
|
||||
zr_clear(ctx);
|
||||
|
||||
nvgResetScissor(nvg);
|
||||
nvgEndFrame(nvg);
|
||||
|
@ -608,17 +578,20 @@ main(int argc, char *argv[])
|
|||
int x, y, width, height;
|
||||
const char *font_path;
|
||||
zr_size font_height;
|
||||
|
||||
SDL_SysWMinfo info;
|
||||
SDL_Window *win;
|
||||
SDL_GLContext glContext;
|
||||
NVGcontext *vg = NULL;
|
||||
|
||||
int running = zr_true;
|
||||
unsigned int started;
|
||||
unsigned int dt;
|
||||
|
||||
/* GUI */
|
||||
struct node_editor nodedit;
|
||||
struct gui gui;
|
||||
struct zr_context ctx;
|
||||
void *memory;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stdout,"Missing TTF Font file argument: gui <path>\n");
|
||||
|
@ -653,67 +626,53 @@ main(int argc, char *argv[])
|
|||
nvgFontSize(vg, font_height);
|
||||
nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE);
|
||||
|
||||
/* GUI */
|
||||
memset(&gui, 0, sizeof gui);
|
||||
gui.memory = malloc(MAX_MEMORY);
|
||||
zr_command_queue_init_fixed(&gui.queue, gui.memory, MAX_MEMORY);
|
||||
{
|
||||
/* GUI */
|
||||
struct zr_user_font font;
|
||||
memset(&ctx, 0, sizeof ctx);
|
||||
memory = malloc(MAX_MEMORY);
|
||||
|
||||
gui.font.userdata.ptr = vg;
|
||||
nvgTextMetrics(vg, NULL, NULL, &gui.font.height);
|
||||
gui.font.width = font_get_width;
|
||||
zr_style_default(&gui.config, ZR_DEFAULT_ALL, &gui.font);
|
||||
gui.config.header.align = ZR_HEADER_RIGHT;
|
||||
|
||||
zr_window_init(&gui.window, zr_rect(0, 0, width, height),
|
||||
ZR_WINDOW_BORDER|ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_CLOSEABLE,
|
||||
&gui.queue, &gui.config, &gui.input);
|
||||
font.userdata.ptr = vg;
|
||||
nvgTextMetrics(vg, NULL, NULL, &font.height);
|
||||
font.width = font_get_width;
|
||||
zr_init_fixed(&ctx, memory, MAX_MEMORY, &font, sin, cos);
|
||||
ctx.style.header.align = ZR_HEADER_RIGHT;
|
||||
}
|
||||
node_editor_init(&nodedit);
|
||||
|
||||
while (running) {
|
||||
/* Input */
|
||||
SDL_Event evt;
|
||||
started = SDL_GetTicks();
|
||||
zr_input_begin(&gui.input);
|
||||
zr_input_begin(&ctx.input);
|
||||
while (SDL_PollEvent(&evt)) {
|
||||
if (evt.type == SDL_WINDOWEVENT) resize(&evt);
|
||||
else if (evt.type == SDL_QUIT) goto cleanup;
|
||||
else if (evt.type == SDL_KEYUP) key(&gui.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_KEYDOWN) key(&gui.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONDOWN) btn(&gui.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONUP) btn(&gui.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_MOUSEMOTION) motion(&gui.input, &evt);
|
||||
else if (evt.type == SDL_TEXTINPUT) text(&gui.input, &evt);
|
||||
else if (evt.type == SDL_MOUSEWHEEL) zr_input_scroll(&gui.input, evt.wheel.y);
|
||||
else if (evt.type == SDL_KEYUP) key(&ctx.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_KEYDOWN) key(&ctx.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONDOWN) btn(&ctx.input, &evt, zr_true);
|
||||
else if (evt.type == SDL_MOUSEBUTTONUP) btn(&ctx.input, &evt, zr_false);
|
||||
else if (evt.type == SDL_MOUSEMOTION) motion(&ctx.input, &evt);
|
||||
else if (evt.type == SDL_TEXTINPUT) text(&ctx.input, &evt);
|
||||
else if (evt.type == SDL_MOUSEWHEEL) zr_input_scroll(&ctx.input, evt.wheel.y);
|
||||
}
|
||||
zr_input_end(&gui.input);
|
||||
zr_input_end(&ctx.input);
|
||||
|
||||
{
|
||||
int incursor;
|
||||
struct zr_context layout;
|
||||
struct zr_rect bounds = gui.window.bounds;
|
||||
zr_flags ret;
|
||||
|
||||
ret = zr_begin(&layout, &gui.window, "Node Editor");
|
||||
if (ret & ZR_WINDOW_CLOSEABLE)
|
||||
goto cleanup;
|
||||
|
||||
/* borderless os window dragging */
|
||||
incursor = zr_input_is_mouse_hovering_rect(&gui.input,
|
||||
zr_rect(layout.bounds.x, layout.bounds.y, layout.bounds.w, layout.header_h));
|
||||
if (zr_input_is_mouse_down(&gui.input, ZR_BUTTON_LEFT) && incursor) {
|
||||
x += gui.input.mouse.delta.x;
|
||||
y += gui.input.mouse.delta.y;
|
||||
SDL_SetWindowPosition(win, x, y);
|
||||
}
|
||||
node_editor_draw(&layout, &nodedit, &gui.config);
|
||||
zr_end(&layout, &gui.window);
|
||||
struct zr_layout layout;
|
||||
if (zr_begin(&ctx, &layout, "Nodedit", zr_rect(0,0,width,height),
|
||||
ZR_WINDOW_BORDER|ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_CLOSEABLE))
|
||||
node_editor_draw(&ctx, &nodedit);
|
||||
else goto cleanup;
|
||||
zr_end(&ctx);
|
||||
}
|
||||
|
||||
/* GUI */
|
||||
glClearColor(0.4f, 0.4f, 0.4f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
SDL_GetWindowSize(win, &width, &height);
|
||||
draw(vg, &gui.queue, width, height);
|
||||
draw(vg, &ctx, width, height);
|
||||
SDL_GL_SwapWindow(win);
|
||||
|
||||
/* Timing */
|
||||
|
@ -724,7 +683,7 @@ main(int argc, char *argv[])
|
|||
|
||||
cleanup:
|
||||
/* Cleanup */
|
||||
free(gui.memory);
|
||||
free(memory);
|
||||
nvgDeleteGLES2(vg);
|
||||
SDL_GL_DeleteContext(glContext);
|
||||
SDL_DestroyWindow(win);
|
||||
|
|
Loading…
Reference in New Issue