massive rewrite

This commit is contained in:
vurtun 2015-12-30 16:31:08 +01:00
parent 4405db1731
commit 20b9d3cd45
14 changed files with 5604 additions and 6745 deletions

View File

@ -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)

33
demo/allegro5/Makefile Normal file
View File

@ -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)

406
demo/allegro5/allegro.c Normal file
View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

5536
zahnrad.c

File diff suppressed because it is too large Load Diff

3311
zahnrad.h

File diff suppressed because it is too large Load Diff