Merge pull request #2875 from fr500/master

[zr] update to the new toolkit
This commit is contained in:
Twinaphex 2016-04-20 07:52:58 +02:00
commit 6fe8637f6a
21 changed files with 20128 additions and 21293 deletions

View File

@ -412,9 +412,8 @@ ifeq ($(HAVE_MATERIALUI), 1)
DEFINES += -DHAVE_MATERIALUI
endif
ifeq ($(HAVE_ZAHNRAD), 1)
OBJ += deps/zahnrad/zahnrad.o
OBJ += menu/drivers/zr_common.o
OBJ += menu/drivers/zr_menu.o
OBJ += menu/drivers/nk_common.o
OBJ += menu/drivers/nk_menu.o
OBJ += menu/drivers/zr.o
DEFINES += -DHAVE_ZAHNRAD
endif

View File

@ -1,43 +0,0 @@
CONTRIBUTING
============
## Submitting changes
Please send a GitHub Pull Request with a clear list of what you've done (read more about [pull requests](http://help.github.com/pull-requests/)).
## Features
If you have an idea for new features just [open an issue](https://github.com/vurtun/zahnrad/issues) with your suggestion.
* Find and correct spelling mistakes
* Add (insert your favorite platform or render backend here) demo implementation (some possibilities: DirectX 9/DirectX 10/DirectX 11 and win32 with OpenGL)
* Add clipboard user callbacks back into all demos
* Add additional widgets [some possible widgets](http://doc.qt.io/qt-5/widget-classes.html#the-widget-classes)
* Add support for multiple pointers for touch input devices (probably requires to rewrite mouse handling in `struct zr_input`)
* Extend xlib demo to support image drawing with arbitrary image width and height
* Change cursor in `zr_widget_edit_box` and `zr_widget_edit_field` to thin standard cursor version used in editors
* Extend piemenu to support submenus (another ring around the first ring or something like [this:](http://gdj.gdj.netdna-cdn.com/wp-content/uploads/2013/02/ui+concepts+13.gif)) and turn it into a default library widget.
* Add label describing the currently active piemenu entry
* Maybe write a piemenu text only version for platforms that do not want or can use images
* Rewrite the chart API to support a better range of charts (maybe take notes from Javascript chart frameworks)
* Create an API to allow scaling between groups (maybe extend and convert the demo example)
* Add multiple Tab support (maybe use `zr_group` and add a header)
* Come up with a better way to provide and create widget and window styles
* Add tables with scaleable column width
* Extend context to not only support overlapping windows but tiled windows as well
## Bugs
* Seperator widget is currently bugged and does not work as intended
* Text handling is still a little bit janky and probably needs to be further tested and polished
* `zr_edit_buffer` with multiline flag is bugged for '\n', need to differentiate between visible and non-visible characters
## Coding conventions
* Only use C89 (ANSI C)
* Do not use any compiler specific extensions
* For indent use four spaces
* Do not typedef structs, unions and enums
* Variable, object and function names should always be lowercase and use underscores instead of camel case
* Whitespace after for, while, if, do and switch
* Always use parentheses if you use the sizeof operator (e.g: sizeof(struct zr_context) and not sizeof struct zr_context)
* Beginning braces on the new line for functions and on the same line otherwise.
* If function becomes to big either a.) create a subblock inside the function and comment or b.) write a functional function
* Only use fixed size types (zr_uint, zr_size, ...) if you really need to and use basic types otherwise
* Do not include any header files in either zahnrad.h or zahnrad.c
* Do not add dependencies rather write your own version if possible
* Write correct commit messages: (http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)

17
deps/zahnrad/LICENSE vendored
View File

@ -1,17 +0,0 @@
Copyright (c) 2016 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.

View File

@ -1,89 +0,0 @@
# Zahnrad
[![Coverity Status](https://scan.coverity.com/projects/5863/badge.svg)](https://scan.coverity.com/projects/5863)
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,
a default renderbackend or OS window and input handling but instead provides a very modular
library approach by using simple input state for input and draw
commands describing primitive shapes as output. So instead of providing a
layered library that tries to abstract over a number of platform and
render backends it only focuses on the actual UI.
## Features
- Immediate mode graphical user interface toolkit
- Written in C89 (ANSI C)
- Small codebase (~9kLOC)
- Focus on portability, efficiency and simplicity
- No dependencies (not even the standard library)
- No global or hidden state
- Configurable style and colors
- UTF-8 support
## Optional
- Vertex buffer output
- Font handling
## Building
The library is self-contained within four different files that only have to be
copied and compiled into your application. Files zahnrad.c and zahnrad.h make up
the core of the library, while stb_rect_pack.h and stb_truetype.h are
for a optional font handling implementation and can be removed if not needed.
- zahnrad.c
- zahnrad.h
- stb_rect_pack.h (optional)
- stb_truetype.h (optional)
There are no dependencies or a particular building process required. You just have
to compile the .c file and #include zahnrad.h into your project. To actually
run you have to provide the input state, configuration style and memory
for draw commands to the library. After the GUI was executed all draw commands
have to be either executed or optionally converted into a vertex buffer to
draw the GUI.
## Gallery
![screenshot](https://cloud.githubusercontent.com/assets/8057201/11761525/ae06f0ca-a0c6-11e5-819d-5610b25f6ef4.gif)
![demo](https://cloud.githubusercontent.com/assets/8057201/11282359/3325e3c6-8eff-11e5-86cb-cf02b0596087.png)
![node](https://cloud.githubusercontent.com/assets/8057201/9976995/e81ac04a-5ef7-11e5-872b-acd54fbeee03.gif)
![transparency](https://cloud.githubusercontent.com/assets/8057201/12779619/2a20d72c-ca69-11e5-95fe-4edecf820d5c.png)
## Example
```c
/* init gui state */
struct zr_context ctx;
zr_init_fixed(&ctx, calloc(1, MAX_MEMORY), MAX_MEMORY, &font);
enum {EASY, HARD};
int op = EASY;
float value = 0.6f;
int i = 20;
struct zr_layout layout;
zr_begin(&ctx, &layout, "Show", zr_rect(50, 50, 220, 220),
ZR_WINDOW_BORDER|ZR_WINDOW_MOVEABLE|ZR_WINDOW_CLOSEABLE);
{
/* 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 ratio 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;
/* 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);
```
![example](https://cloud.githubusercontent.com/assets/8057201/10187981/584ecd68-675c-11e5-897c-822ef534a876.png)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

19493
deps/zahnrad/nuklear.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,545 +0,0 @@
/* stb_rect_pack.h - v0.05 - public domain - rectangle packing */
/* Sean Barrett 2014 */
/* */
/* Useful for e.g. packing rectangular textures into an atlas. */
/* Does not do rotation. */
/* */
/* Not necessarily the awesomest packing method, but better than */
/* the totally naive one in stb_truetype (which is primarily what */
/* this is meant to replace). */
/* */
/* Has only had a few tests run, may have issues. */
/* */
/* More docs to come. */
/* */
/* No memory allocations; uses qsort() and assert() from stdlib. */
/* */
/* This library currently uses the Skyline Bottom-Left algorithm. */
/* */
/* Please note: better rectangle packers are welcome! Please */
/* implement them to the same API, but with a different init */
/* function. */
/* */
/* Version history: */
/* */
/* 0.05: added STBRP_ASSERT to allow replacing assert */
/* 0.04: fixed minor bug in STBRP_LARGE_RECTS support */
/* 0.01: initial release */
/*//////////////////////////////////////////////////////////////////////////// */
/* */
/* INCLUDE SECTION */
#ifndef STB_INCLUDE_STB_RECT_PACK_H
#define STB_INCLUDE_STB_RECT_PACK_H
#define STB_RECT_PACK_VERSION 1
#ifdef STBRP_STATIC
#define STBRP_DEF static
#else
#define STBRP_DEF extern
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct stbrp_context stbrp_context;
typedef struct stbrp_node stbrp_node;
typedef struct stbrp_rect stbrp_rect;
#ifdef STBRP_LARGE_RECTS
typedef int stbrp_coord;
#else
typedef unsigned short stbrp_coord;
#endif
STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
/* Assign packed locations to rectangles. The rectangles are of type */
/* 'stbrp_rect' defined below, stored in the array 'rects', and there */
/* are 'num_rects' many of them. */
/* */
/* Rectangles which are successfully packed have the 'was_packed' flag */
/* set to a non-zero value and 'x' and 'y' store the minimum location */
/* on each axis (i.e. bottom-left in cartesian coordinates, top-left */
/* if you imagine y increasing downwards). Rectangles which do not fit */
/* have the 'was_packed' flag set to 0. */
/* */
/* You should not try to access the 'rects' array from another thread */
/* while this function is running, as the function temporarily reorders */
/* the array while it executes. */
/* */
/* To pack into another rectangle, you need to call stbrp_init_target */
/* again. To continue packing into the same rectangle, you can call */
/* this function again. Calling this multiple times with multiple rect */
/* arrays will probably produce worse packing results than calling it */
/* a single time with the full rectangle array, but the option is */
/* available. */
struct stbrp_rect
{
/* reserved for your use: */
int id;
/* input: */
stbrp_coord w, h;
/* output: */
stbrp_coord x, y;
int was_packed; /* non-zero if valid packing */
}; /* 16 bytes, nominally */
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
/* Initialize a rectangle packer to: */
/* pack a rectangle that is 'width' by 'height' in dimensions */
/* using temporary storage provided by the array 'nodes', which is 'num_nodes' long */
/* */
/* You must call this function every time you start packing into a new target. */
/* */
/* There is no "shutdown" function. The 'nodes' memory must stay valid for */
/* the following stbrp_pack_rects() call (or calls), but can be freed after */
/* the call (or calls) finish. */
/* */
/* Note: to guarantee best results, either: */
/* 1. make sure 'num_nodes' >= 'width' */
/* or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' */
/* */
/* If you don't do either of the above things, widths will be quantized to multiples */
/* of small integers to guarantee the algorithm doesn't run out of temporary storage. */
/* */
/* If you do #2, then the non-quantized algorithm will be used, but the algorithm */
/* may run out of temporary storage and be unable to pack some rectangles. */
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
/* Optionally call this function after init but before doing any packing to */
/* change the handling of the out-of-temp-memory scenario, described above. */
/* If you call init again, this will be reset to the default (false). */
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
/* Optionally select which packing heuristic the library should use. Different */
/* heuristics will produce better/worse results for different data sets. */
/* If you call init again, this will be reset to the default. */
enum
{
STBRP_HEURISTIC_Skyline_default=0,
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
STBRP_HEURISTIC_Skyline_BF_sortHeight
};
/*//////////////////////////////////////////////////////////////////////////// */
/* */
/* the details of the following structures don't matter to you, but they must */
/* be visible so you can handle the memory allocations for them */
struct stbrp_node
{
stbrp_coord x,y;
stbrp_node *next;
};
struct stbrp_context
{
int width;
int height;
int align;
int init_mode;
int heuristic;
int num_nodes;
stbrp_node *active_head;
stbrp_node *free_head;
stbrp_node extra[2]; /* we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' */
};
#ifdef __cplusplus
}
#endif
#endif
/*//////////////////////////////////////////////////////////////////////////// */
/* */
/* IMPLEMENTATION SECTION */
/* */
#ifdef STB_RECT_PACK_IMPLEMENTATION
#include <stdlib.h>
#ifndef STBRP_ASSERT
#include <assert.h>
#define STBRP_ASSERT assert
#endif
enum
{
STBRP__INIT_skyline = 1
};
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
{
switch (context->init_mode) {
case STBRP__INIT_skyline:
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
context->heuristic = heuristic;
break;
default:
STBRP_ASSERT(0);
}
}
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
{
if (allow_out_of_mem)
/* if it's ok to run out of memory, then don't bother aligning them; */
/* this gives better packing, but may fail due to OOM (even though */
/* the rectangles easily fit). @TODO a smarter approach would be to only */
/* quantize once we've hit OOM, then we could get rid of this parameter. */
context->align = 1;
else {
/* if it's not ok to run out of memory, then quantize the widths */
/* so that num_nodes is always enough nodes. */
/* */
/* I.e. num_nodes * align >= width */
/* align >= width / num_nodes */
/* align = ceil(width/num_nodes) */
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
}
}
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
{
int i;
#ifndef STBRP_LARGE_RECTS
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
#endif
for (i=0; i < num_nodes-1; ++i)
nodes[i].next = &nodes[i+1];
nodes[i].next = NULL;
context->init_mode = STBRP__INIT_skyline;
context->heuristic = STBRP_HEURISTIC_Skyline_default;
context->free_head = &nodes[0];
context->active_head = &context->extra[0];
context->width = width;
context->height = height;
context->num_nodes = num_nodes;
stbrp_setup_allow_out_of_mem(context, 0);
/* node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) */
context->extra[0].x = 0;
context->extra[0].y = 0;
context->extra[0].next = &context->extra[1];
context->extra[1].x = (stbrp_coord) width;
#ifdef STBRP_LARGE_RECTS
context->extra[1].y = (1<<30);
#else
context->extra[1].y = 65535;
#endif
context->extra[1].next = NULL;
}
/* find minimum y position if it starts at x1 */
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
{
stbrp_node *node = first;
int x1 = x0 + width;
int min_y, visited_width, waste_area;
STBRP_ASSERT(first->x <= x0);
(void)c;
#if 0
/* skip in case we're past the node */
while (node->next->x <= x0)
++node;
#else
STBRP_ASSERT(node->next->x > x0); /* we ended up handling this in the caller for efficiency */
#endif
STBRP_ASSERT(node->x <= x0);
min_y = 0;
waste_area = 0;
visited_width = 0;
while (node->x < x1) {
if (node->y > min_y) {
/* raise min_y higher. */
/* we've accounted for all waste up to min_y, */
/* but we'll now add more waste for everything we've visted */
waste_area += visited_width * (node->y - min_y);
min_y = node->y;
/* the first time through, visited_width might be reduced */
if (node->x < x0)
visited_width += node->next->x - x0;
else
visited_width += node->next->x - node->x;
} else {
/* add waste area */
int under_width = node->next->x - node->x;
if (under_width + visited_width > width)
under_width = width - visited_width;
waste_area += under_width * (min_y - node->y);
visited_width += under_width;
}
node = node->next;
}
*pwaste = waste_area;
return min_y;
}
typedef struct
{
int x,y;
stbrp_node **prev_link;
} stbrp__findresult;
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
{
int best_waste = (1<<30), best_x, best_y = (1 << 30);
stbrp__findresult fr;
stbrp_node **prev, *node, *tail, **best = NULL;
/* align to multiple of c->align */
width = (width + c->align - 1);
width -= width % c->align;
STBRP_ASSERT(width % c->align == 0);
node = c->active_head;
prev = &c->active_head;
while (node->x + width <= c->width) {
int y,waste;
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { /* actually just want to test BL */
/* bottom left */
if (y < best_y) {
best_y = y;
best = prev;
}
} else {
/* best-fit */
if (y + height <= c->height) {
/* can only use it if it first vertically */
if (y < best_y || (y == best_y && waste < best_waste)) {
best_y = y;
best_waste = waste;
best = prev;
}
}
}
prev = &node->next;
node = node->next;
}
best_x = (best == NULL) ? 0 : (*best)->x;
/* if doing best-fit (BF), we also have to try aligning right edge to each node position */
/* */
/* e.g, if fitting */
/* */
/* ____________________ */
/* |____________________| */
/* */
/* into */
/* */
/* | | */
/* | ____________| */
/* |____________| */
/* */
/* then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned */
/* */
/* This makes BF take about 2x the time */
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
tail = c->active_head;
node = c->active_head;
prev = &c->active_head;
/* find first node that's admissible */
while (tail->x < width)
tail = tail->next;
while (tail) {
int xpos = tail->x - width;
int y,waste;
STBRP_ASSERT(xpos >= 0);
/* find the left position that matches this */
while (node->next->x <= xpos) {
prev = &node->next;
node = node->next;
}
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
if (y + height < c->height) {
if (y <= best_y) {
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
best_x = xpos;
STBRP_ASSERT(y <= best_y);
best_y = y;
best_waste = waste;
best = prev;
}
}
}
tail = tail->next;
}
}
fr.prev_link = best;
fr.x = best_x;
fr.y = best_y;
return fr;
}
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
{
/* find best position according to heuristic */
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
stbrp_node *node, *cur;
/* bail if: */
/* 1. it failed */
/* 2. the best node doesn't fit (we don't always check this) */
/* 3. we're out of memory */
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
res.prev_link = NULL;
return res;
}
/* on success, create new node */
node = context->free_head;
node->x = (stbrp_coord) res.x;
node->y = (stbrp_coord) (res.y + height);
context->free_head = node->next;
/* insert the new node into the right starting point, and */
/* let 'cur' point to the remaining nodes needing to be */
/* stiched back in */
cur = *res.prev_link;
if (cur->x < res.x) {
/* preserve the existing one, so start testing with the next one */
stbrp_node *next = cur->next;
cur->next = node;
cur = next;
} else {
*res.prev_link = node;
}
/* from here, traverse cur and free the nodes, until we get to one */
/* that shouldn't be freed */
while (cur->next && cur->next->x <= res.x + width) {
stbrp_node *next = cur->next;
/* move the current node to the free list */
cur->next = context->free_head;
context->free_head = cur;
cur = next;
}
/* stitch the list back in */
node->next = cur;
if (cur->x < res.x + width)
cur->x = (stbrp_coord) (res.x + width);
#ifdef _DEBUG
cur = context->active_head;
while (cur->x < context->width) {
STBRP_ASSERT(cur->x < cur->next->x);
cur = cur->next;
}
STBRP_ASSERT(cur->next == NULL);
{
stbrp_node *L1 = NULL, *L2 = NULL;
int count=0;
cur = context->active_head;
while (cur) {
L1 = cur;
cur = cur->next;
++count;
}
cur = context->free_head;
while (cur) {
L2 = cur;
cur = cur->next;
++count;
}
STBRP_ASSERT(count == context->num_nodes+2);
}
#endif
return res;
}
static int rect_height_compare(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
if (p->h > q->h)
return -1;
if (p->h < q->h)
return 1;
return (p->w > q->w) ? -1 : (p->w < q->w);
}
static int rect_width_compare(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
if (p->w > q->w)
return -1;
if (p->w < q->w)
return 1;
return (p->h > q->h) ? -1 : (p->h < q->h);
}
static int rect_original_order(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
}
#ifdef STBRP_LARGE_RECTS
#define STBRP__MAXVAL 0xffffffff
#else
#define STBRP__MAXVAL 0xffff
#endif
STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
{
int i;
/* we use the 'was_packed' field internally to allow sorting/unsorting */
for (i=0; i < num_rects; ++i) {
rects[i].was_packed = i;
#ifndef STBRP_LARGE_RECTS
STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff);
#endif
}
/* sort according to heuristic */
qsort(rects, (size_t)num_rects, sizeof(rects[0]), rect_height_compare);
for (i=0; i < num_rects; ++i) {
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
if (fr.prev_link) {
rects[i].x = (stbrp_coord) fr.x;
rects[i].y = (stbrp_coord) fr.y;
} else {
rects[i].x = rects[i].y = STBRP__MAXVAL;
}
}
/* unsort */
qsort(rects, (size_t)num_rects, sizeof(rects[0]), rect_original_order);
/* set was_packed flags */
for (i=0; i < num_rects; ++i)
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
}
#endif

File diff suppressed because it is too large Load Diff

14266
deps/zahnrad/zahnrad.c vendored

File diff suppressed because it is too large Load Diff

2017
deps/zahnrad/zahnrad.h vendored

File diff suppressed because it is too large Load Diff

View File

@ -896,9 +896,8 @@ MENU
#endif
#ifdef HAVE_ZAHNRAD
#include "../deps/zahnrad/zahnrad.c"
#include "../menu/drivers/zr_common.c"
#include "../menu/drivers/zr_menu.c"
#include "../menu/drivers/nk_common.c"
#include "../menu/drivers/nk_menu.c"
#include "../menu/drivers/zr.c"
#endif

View File

@ -1,7 +1,7 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2011-2016 - Daniel De Matteis
* Copyright (C) 2014-2015 - Jean-André Santoni
* Copyright (C) 2016 - Andrés Suárez
* Copyright (C) 2014-2015 - Jean-Andr<EFBFBD> Santoni
* Copyright (C) 2016 - Andr<EFBFBD>s Su<EFBFBD>rez
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -17,7 +17,15 @@
#include <streams/file_stream.h>
#include "zr_common.h"
#define NK_INCLUDE_FIXED_TYPES
#define NK_INCLUDE_STANDARD_IO
#define NK_INCLUDE_DEFAULT_ALLOCATOR
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
#define NK_INCLUDE_FONT_BAKING
#define NK_INCLUDE_DEFAULT_FONT
#define NK_IMPLEMENTATION
#include "nk_common.h"
#include "../menu_display.h"
#include "../../gfx/video_shader_driver.h"
@ -25,12 +33,12 @@
#include "../../gfx/drivers/gl_shaders/pipeline_zahnrad.glsl.vert.h"
#include "../../gfx/drivers/gl_shaders/pipeline_zahnrad.glsl.frag.h"
struct zr_font font;
struct zr_user_font usrfnt;
struct zr_allocator zr_alloc;
struct zr_device device;
struct nk_font font;
struct nk_user_font usrfnt;
struct nk_allocator nk_alloc;
struct nk_device device;
struct zr_image zr_common_image_load(const char *filename)
struct nk_image nk_common_image_load(const char *filename)
{
int x,y,n;
GLuint tex;
@ -49,10 +57,10 @@ struct zr_image zr_common_image_load(const char *filename)
#endif
stbi_image_free(data);
return zr_image_id((int)tex);
return nk_image_id((int)tex);
}
char* zr_common_file_load(const char* path, size_t* size)
char* nk_common_file_load(const char* path, size_t* size)
{
void *buf;
ssize_t *length = (ssize_t*)size;
@ -60,7 +68,7 @@ char* zr_common_file_load(const char* path, size_t* size)
return (char*)buf;
}
void zr_common_device_init(struct zr_device *dev)
NK_API void nk_common_device_init(struct nk_device *dev)
{
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
GLint status;
@ -73,14 +81,11 @@ void zr_common_device_init(struct zr_device *dev)
glCompileShader(dev->vert_shdr);
glCompileShader(dev->frag_shdr);
glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status);
assert(status == GL_TRUE);
glGetShaderiv(dev->frag_shdr, GL_COMPILE_STATUS, &status);
assert(status == GL_TRUE);
glAttachShader(dev->prog, dev->vert_shdr);
glAttachShader(dev->prog, dev->frag_shdr);
glLinkProgram(dev->prog);
glGetProgramiv(dev->prog, GL_LINK_STATUS, &status);
assert(status == GL_TRUE);
dev->uniform_proj = glGetUniformLocation(dev->prog, "ProjMtx");
dev->attrib_pos = glGetAttribLocation(dev->prog, "Position");
@ -89,10 +94,10 @@ void zr_common_device_init(struct zr_device *dev)
{
/* buffer setup */
GLsizei vs = sizeof(struct zr_draw_vertex);
size_t vp = offsetof(struct zr_draw_vertex, position);
size_t vt = offsetof(struct zr_draw_vertex, uv);
size_t vc = offsetof(struct zr_draw_vertex, col);
GLsizei vs = sizeof(struct nk_draw_vertex);
size_t vp = offsetof(struct nk_draw_vertex, position);
size_t vt = offsetof(struct nk_draw_vertex, uv);
size_t vc = offsetof(struct nk_draw_vertex, col);
glGenBuffers(1, &dev->vbo);
glGenBuffers(1, &dev->ebo);
@ -118,19 +123,19 @@ void zr_common_device_init(struct zr_device *dev)
#endif
}
struct zr_user_font zr_common_font(
struct zr_device *dev,
struct zr_font *font,
struct nk_user_font nk_common_font(
struct nk_device *dev,
struct nk_font *font,
const char *path,
unsigned int font_height,
const zr_rune *range)
const nk_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;
struct nk_font_glyph *glyphes;
struct nk_baked_font baked_font;
struct nk_user_font user_font;
struct nk_recti custom;
memset(&baked_font, 0, sizeof(baked_font));
memset(&user_font, 0, sizeof(user_font));
@ -139,48 +144,48 @@ struct zr_user_font zr_common_font(
{
struct texture_image ti;
/* bake and upload font texture */
struct zr_font_config config;
struct nk_font_config config;
void *img, *tmp;
size_t ttf_size;
size_t tmp_size, img_size;
const char *custom_data = "....";
char *ttf_blob = zr_common_file_load(path, &ttf_size);
char *ttf_blob = nk_common_file_load(path, &ttf_size);
/* 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.coord_type = NK_COORD_UV;
config.range = range;
config.pixel_snap = zr_false;
config.pixel_snap = nk_false;
config.size = (float)font_height;
config.spacing = zr_vec2(0,0);
config.spacing = nk_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);
nk_font_bake_memory(&tmp_size, &glyph_count, &config, 1);
glyphes = (struct nk_font_glyph*)
calloc(sizeof(struct nk_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;
zr_font_bake_pack(&img_size,
&img_width,&img_height,&custom,tmp,tmp_size,&config, 1);
nk_font_bake_pack(&img_size,
&img_width,&img_height,&custom,tmp,tmp_size,&config, 1, &nk_alloc);
/* bake all glyphes and custom white pixel into image */
img = calloc(1, img_size);
zr_font_bake(img, img_width,
nk_font_bake(img, img_width,
img_height, tmp, tmp_size, glyphes, glyph_count, &config, 1);
zr_font_bake_custom_data(img,
nk_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);
nk_font_bake_convert(img_rgba, img_width, img_height, img);
free(img);
img = img_rgba;
}
@ -200,21 +205,21 @@ struct zr_user_font zr_common_font(
/* default white pixel in a texture which is needed to draw primitives */
dev->null.texture.id = (int)dev->font_tex;
dev->null.uv = zr_vec2((custom.x + 0.5f)/(float)img_width,
dev->null.uv = nk_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(font,
nk_font_init(font,
(float)font_height, '?', glyphes,
&baked_font, dev->null.texture);
user_font = zr_font_ref(font);
user_font = font->handle;
return user_font;
}
void zr_common_device_shutdown(struct zr_device *dev)
void nk_common_device_shutdown(struct nk_device *dev)
{
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
glDetachShader(dev->prog, dev->vert_shdr);
@ -228,18 +233,18 @@ void zr_common_device_shutdown(struct zr_device *dev)
#endif
}
void zr_common_device_draw(struct zr_device *dev,
struct zr_context *ctx, int width, int height,
enum zr_anti_aliasing AA)
void nk_common_device_draw(struct nk_device *dev,
struct nk_context *ctx, int width, int height,
enum nk_anti_aliasing AA)
{
video_shader_ctx_info_t shader_info;
struct zr_buffer vbuf, ebuf;
struct zr_convert_config config;
struct nk_buffer vbuf, ebuf;
struct nk_convert_config config;
uintptr_t last_prog;
const struct zr_draw_command *cmd = NULL;
const struct nk_draw_command *cmd = NULL;
void *vertices = NULL;
void *elements = NULL;
const zr_draw_index *offset = NULL;
const nk_draw_index *offset = NULL;
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
GLint last_tex;
GLint last_ebo, last_vbo, last_vao;
@ -297,13 +302,13 @@ void zr_common_device_draw(struct zr_device *dev,
config.shape_AA = AA;
config.line_AA = AA;
config.circle_segment_count = 22;
config.line_thickness = 1.0f;
//config.line_thickness = 1.0f;
config.null = dev->null;
/* setup buffers to load vertices and elements */
zr_buffer_init_fixed(&vbuf, vertices, MAX_VERTEX_MEMORY);
zr_buffer_init_fixed(&ebuf, elements, MAX_ELEMENT_MEMORY);
zr_convert(ctx, &dev->cmds, &vbuf, &ebuf, &config);
nk_buffer_init_fixed(&vbuf, vertices, MAX_VERTEX_MEMORY);
nk_buffer_init_fixed(&ebuf, elements, MAX_ELEMENT_MEMORY);
nk_convert(ctx, &dev->cmds, &vbuf, &ebuf, &config);
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
glUnmapBuffer(GL_ARRAY_BUFFER);
@ -311,7 +316,7 @@ void zr_common_device_draw(struct zr_device *dev,
#endif
/* iterate over and execute each draw command */
zr_draw_foreach(cmd, ctx, &dev->cmds)
nk_draw_foreach(cmd, ctx, &dev->cmds)
{
if (!cmd->elem_count)
continue;
@ -327,7 +332,7 @@ void zr_common_device_draw(struct zr_device *dev,
offset += cmd->elem_count;
}
zr_clear(ctx);
nk_clear(ctx);
/* restore old state */
shader_info.data = NULL;
@ -345,13 +350,14 @@ void zr_common_device_draw(struct zr_device *dev,
menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL);
}
void* zr_common_mem_alloc(zr_handle unused, size_t size)
//void nk_mem_alloc(nk_handle a, void *old, nk_size b);
void* nk_common_mem_alloc(nk_handle a, void *old, nk_size b)
{
(void)unused;
return calloc(1, size);
(void)a;
return calloc(1, b);
}
void zr_common_mem_free(zr_handle unused, void *ptr)
void nk_common_mem_free(nk_handle unused, void *ptr)
{
(void)unused;
free(ptr);

82
menu/drivers/nk_common.h Normal file
View File

@ -0,0 +1,82 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2011-2016 - Daniel De Matteis
* Copyright (C) 2014-2015 - Jean-André Santoni
* Copyright (C) 2016 - Andrés Suárez
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#define NK_INCLUDE_FIXED_TYPES
#define NK_INCLUDE_STANDARD_IO
#define NK_INCLUDE_DEFAULT_ALLOCATOR
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
#define NK_INCLUDE_FONT_BAKING
#define NK_INCLUDE_DEFAULT_FONT
#include "../../deps/zahnrad/nuklear.h"
#include "../../deps/stb/stb_image.h"
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
#include "../../gfx/common/gl_common.h"
#endif
#define MAX_VERTEX_MEMORY (512 * 1024)
#define MAX_ELEMENT_MEMORY (128 * 1024)
#define NK_SYSTEM_TAB_END NK_SYSTEM_TAB_SETTINGS
struct nk_device
{
struct nk_buffer cmds;
struct nk_draw_null_texture null;
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
GLuint vbo, vao, ebo;
GLuint prog;
GLuint vert_shdr;
GLuint frag_shdr;
GLint attrib_pos;
GLint attrib_uv;
GLint attrib_col;
GLint uniform_proj;
GLuint font_tex;
#endif
};
extern struct nk_font font;
extern struct nk_user_font usrfnt;
extern struct nk_allocator nk_alloc;
extern struct nk_device device;
struct nk_image nk_common_image_load(const char *filename);
char* nk_common_file_load(const char* path, size_t* size);
void nk_common_device_init(struct nk_device *dev);
struct nk_user_font nk_common_font(
struct nk_device *dev,
struct nk_font *font,
const char *path,
unsigned int font_height,
const nk_rune *range);
void nk_common_device_shutdown(struct nk_device *dev);
void nk_common_device_draw(struct nk_device *dev,
struct nk_context *ctx, int width, int height,
enum nk_anti_aliasing AA);
void* nk_common_mem_alloc(nk_handle a, void *old, nk_size b);
void nk_common_mem_free(nk_handle unused, void *ptr);

417
menu/drivers/nk_menu.c Normal file
View File

@ -0,0 +1,417 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2011-2016 - Daniel De Matteis
* Copyright (C) 2014-2015 - Jean-André Santoni
* Copyright (C) 2016 - Andrés Suárez
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "nk_menu.h"
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <file/file_path.h>
#include <string/stdstring.h>
#include <lists/string_list.h>
#include "../menu_driver.h"
#include "../menu_hash.h"
#include "../../gfx/common/gl_common.h"
#include "../../core_info.h"
#include "../../configuration.h"
#include "../../retroarch.h"
#define LEN(a) (sizeof(a)/sizeof(a)[0])
/* gamepad demo variables */
enum widget_id
{
WINDOW_MODE = 0,
MODEL_DETAIL,
TEXTURES,
SHADOWS,
LIGHTNING,
EFFECTS,
CONSOLE,
BRIGHTNESS,
VOLUME,
WIDGET_MAX
};
enum display_settings {
WINDOWED = 0, FULLSCREEN};
enum detail_settings {LOW, MEDIUM, HIGH, EXTRA_HIGH};
enum state_settings {OFF, ON};
const char *display[] = {"Windowed", "Fullscreen"};
const char *state[] = {"Off", "On"};
const char *detail[] = {"Low", "Medium", "High", "Extra High"};
static int window_mode = FULLSCREEN;
static int model_detail = HIGH;
static int texture_detail = EXTRA_HIGH;
static int shadow_detail = HIGH;
static int lighning_detail = LOW;
static int effects_detail = MEDIUM;
static int show_console = ON;
static int brightness = 90;
static int volume = 30;
static int active = WINDOW_MODE;
/* end of gamepad demo variables */
/*tatic int ui_selector(struct nk_context *ctx, const char *title, int *selected, const char *items[],
int max, int active)
{
struct nk_vec2 item_padding;
struct nk_rect bounds, label, content, tri, sel;
struct nk_panel *layout;
struct nk_command_buffer *out;
struct nk_color col;
struct nk_vec2 result[3];
nk_size text_len, text_width;
if (!ctx || !ctx->current)
return 0;
layout = nk_window_get_panel(ctx);
out = nk_window_get_canvas(ctx);
if (!nk_widget(&bounds, ctx))
return 0;
item_padding = nk_get_property(ctx, NK_PROPERTY_ITEM_PADDING);
bounds.x += item_padding.x;
bounds.y += item_padding.y;
bounds.w -= 2 * item_padding.x;
bounds.h -= 2 * item_padding.y;
label.h = bounds.h;
label.w = bounds.w / 2.0f;
label.x = bounds.x + item_padding.x;
label.y = bounds.y + label.h/2.0f - (float)ctx->style.font.height/2.0f;
content.x = bounds.x + bounds.w/2.0f;
content.y = bounds.y;
content.w = bounds.w / 2.0f;
content.h = bounds.h;
if (active) nk_draw_rect(out, bounds, 0, nk_rgba(220, 220, 220, 135));
text_len = strlen(title);
col = (active) ? nk_rgba(0, 0, 0, 255): nk_rgba(220,220,220,220);
nk_draw_text(out, label, title, text_len, &ctx->style.font, nk_rgba(0,0,0,0), col);
if (nk_input_is_key_pressed(&ctx->input, NK_KEY_RIGHT) && active)
*selected = MIN(*selected+1, max-1);
else if (nk_input_is_key_pressed(&ctx->input, NK_KEY_LEFT) && active)
*selected = MAX(0, *selected-1);
tri.h = ctx->style.font.height - 2 * item_padding.y;
tri.w = tri.h/2.0f;
tri.x = content.x + item_padding.x;
tri.y = content.y + content.h/2 - tri.h/2.0f;
sel.x = tri.x + item_padding.x;
sel.y = tri.y;
sel.h = content.h;
if (*selected > 0) {
nk_triangle_from_direction(result, tri, 0, 0, NK_LEFT);
nk_draw_triangle(out, result[0].x, result[0].y, result[1].x, result[1].y,
result[2].x, result[2].y, (active) ? nk_rgba(0, 0, 0, 255):
nk_rgba(100, 100, 100, 150));
}
tri.x = content.x + (content.w - item_padding.x) - tri.w;
sel.w = tri.x - sel.x;
if (*selected < max-1) {
nk_triangle_from_direction(result, tri, 0, 0, NK_RIGHT);
nk_draw_triangle(out, result[0].x, result[0].y, result[1].x, result[1].y,
result[2].x, result[2].y, (active) ? nk_rgba(0, 0, 0, 255):
nk_rgba(100, 100, 100, 150));
}
text_width = ctx->style.font.width(ctx->style.font.userdata,
ctx->style.font.height, items[*selected], strlen(items[*selected]));
label.w = MAX(1, (float)text_width);
label.x = (sel.x + (sel.w - label.w) / 2);
label.x = MAX(sel.x, label.x);
label.w = MIN(sel.x + sel.w, label.x + label.w);
if (label.w >= label.x) label.w -= label.x;
nk_draw_text(out, label, items[*selected], strlen(items[*selected]),
&ctx->style.font, nk_rgba(0,0,0,0), col);
return 0;
}
*/
/*
static void ui_slider(struct nk_context *ctx, const char *title, int *value, int max, int active)
{
struct nk_vec2 item_padding;
struct nk_rect bounds, label, content, bar, cursor, tri;
struct nk_panel *layout;
struct nk_command_buffer *out;
struct nk_color col;
nk_size text_len, text_width;
float prog_scale = (float)*value / (float)max;
struct nk_vec2 result[3];
if (!ctx || !ctx->current)
return;
layout = nk_window_get_panel(ctx);
out = nk_window_get_canvas(ctx);
if (!nk_widget(&bounds, ctx))
return;
item_padding = nk_get_property(ctx, NK_PROPERTY_ITEM_PADDING);
bounds.x += item_padding.x;
bounds.y += item_padding.y;
bounds.w -= 2 * item_padding.x;
bounds.h -= 2 * item_padding.y;
label.h = bounds.h;
label.w = bounds.w / 2.0f;
label.x = bounds.x + item_padding.x;
label.y = bounds.y + label.h/2.0f - (float)ctx->style.font.height/2.0f;
content.x = bounds.x + bounds.w/2.0f;
content.y = bounds.y;
content.w = bounds.w / 2.0f;
content.h = bounds.h;
if (active) nk_draw_rect(out, bounds, 0, nk_rgba(220, 220, 220, 135));
text_len = strlen(title);
col = (active) ? nk_rgba(0, 0, 0, 255): nk_rgba(220,220,220,220);
nk_draw_text(out, label, title, text_len, &ctx->style.font, nk_rgba(0,0,0,0), col);
if (nk_input_is_key_pressed(&ctx->input, NK_KEY_LEFT) && active)
*value = MAX(0, *value - 10);
if (nk_input_is_key_pressed(&ctx->input, NK_KEY_RIGHT) && active)
*value = MIN(*value + 10, max);
tri.h = ctx->style.font.height - 2 * item_padding.y;
tri.w = tri.h/2.0f;
tri.x = content.x + item_padding.x;
tri.y = content.y + content.h/2 - tri.h/2.0f;
bar.x = tri.x + 4 * item_padding.x + tri.w;
bar.h = tri.h / 4.0f;
bar.y = tri.y + tri.h/2.0f - bar.h/2.0f;
if (*value > 0) {
nk_triangle_from_direction(result, tri, 0, 0, NK_LEFT);
nk_draw_triangle(out, result[0].x, result[0].y, result[1].x, result[1].y,
result[2].x, result[2].y, (active) ? nk_rgba(0, 0, 0, 255):
nk_rgba(100, 100, 100, 150));
}
tri.x = content.x + (content.w - item_padding.x) - tri.w;
bar.w = (tri.x - bar.x) - 4 * item_padding.x;
if (*value < max)
{
nk_triangle_from_direction(result, tri, 0, 0, NK_RIGHT);
nk_draw_triangle(out, result[0].x, result[0].y, result[1].x, result[1].y,
result[2].x, result[2].y, (active) ? nk_rgba(0, 0, 0, 255):
nk_rgba(100, 100, 100, 150));
}
bar.w = (bar.w - tri.h/2.0f);
if (active)
{
nk_draw_rect(out, bar, 0, nk_rgba(0, 0, 0, 135));
bar.w = bar.w * prog_scale;
bar.y = tri.y; bar.x = bar.x + bar.w; bar.w = tri.h; bar.h = tri.h;
nk_draw_circle(out, bar, nk_rgba(220, 220, 220, 255));
}
else
{
nk_draw_rect(out, bar, 0, nk_rgba(220, 220, 220, 135));
bar.w = bar.w * prog_scale;
bar.y = tri.y; bar.x = bar.x + bar.w; bar.w = tri.h; bar.h = tri.h;
nk_draw_circle(out, bar, nk_rgba(190, 190, 190, 255));
}
}
*/
/*bool nk_checkbox_bool(struct nk_context* cx, const char* text, bool *active)
{
int x = *active;
bool ret = nk_check_text(cx, text, &x);
*active = x;
return ret;
}
float nk_checkbox_float(struct nk_context* cx, const char* text, float *active)
{
int x = *active;
float ret = nk_check_text(cx, text, &x);
*active = x;
return ret;
}*/
/*static void nk_labelf(struct nk_context *ctx,
enum nk_text_align align, const char *fmt, ...)
{
char buffer[1024];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
buffer[1023] = 0;
nk_label(ctx, buffer, align);
va_end(args);
}*/
void zrmenu_set_state(zrmenu_handle_t *zr, const int id,
struct nk_vec2 pos, struct nk_vec2 size)
{
zr->window[id].position = pos;
zr->window[id].size = size;
}
void zrmenu_get_state(zrmenu_handle_t *zr, const int id,
struct nk_vec2 *pos, struct nk_vec2 *size)
{
*pos = zr->window[id].position;
*size = zr->window[id].size;
}
void zrmenu_wnd_shader_parameters(zrmenu_handle_t *zr)
{
unsigned i;
video_shader_ctx_t shader_info;
struct nk_panel layout;
struct nk_context *ctx = &zr->ctx;
const int id = ZRMENU_WND_SHADER_PARAMETERS;
settings_t *settings = config_get_ptr();
if (nk_begin(ctx, &layout, "Shader Parameters", nk_rect(240, 10, 300, 400),
NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_MOVABLE|
NK_WINDOW_SCALABLE|NK_WINDOW_BORDER))
{
struct nk_panel combo;
static const char *themes[] = {"Dark", "Light"};
enum zrmenu_theme old = zr->theme;
nk_layout_row_dynamic(ctx, 30, 1);
video_shader_driver_ctl(SHADER_CTL_GET_CURRENT_SHADER, &shader_info);
if (shader_info.data)
{
for (i = 0; i < GFX_MAX_PARAMETERS; i++)
{
if (!string_is_empty(shader_info.data->parameters[i].desc))
{
/* if(shader_info.data->parameters[i].minimum == 0 &&
shader_info.data->parameters[i].maximum == 1 &&
shader_info.data->parameters[i].step == 1)
nk_checkbox_float(ctx, shader_info.data->parameters[i].desc,
&(shader_info.data->parameters[i].current));
else*/
nk_property_float(ctx, shader_info.data->parameters[i].desc,
shader_info.data->parameters[i].minimum,
&(shader_info.data->parameters[i].current),
shader_info.data->parameters[i].maximum,
shader_info.data->parameters[i].step, 1);
}
}
}
}
/* save position and size to restore after context reset */
zrmenu_set_state(zr, id, nk_window_get_position(ctx), nk_window_get_size(ctx));
nk_end(ctx);
}
void zrmenu_wnd_test(zrmenu_handle_t *zr)
{
struct nk_panel layout;
struct nk_context *ctx = &zr->ctx;
const int id = ZRMENU_WND_TEST;
settings_t *settings = config_get_ptr();
if (nk_begin(ctx, &layout, "Test", nk_rect(140, 90, 500, 600),
NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_MOVABLE|
NK_WINDOW_SCALABLE|NK_WINDOW_BORDER))
{
unsigned size;
struct nk_panel combo;
menu_entry_t entry;
static const char *themes[] = {"Dark", "Light"};
enum zrmenu_theme old = zr->theme;
nk_layout_row_dynamic(ctx, 30, 2);
nk_layout_row_dynamic(ctx, 30, 4);
//nk_checkbox_bool(ctx, "Show FPS", &(settings->fps_show));
//nk_checkbox_bool(ctx, "Show FPS", &(settings->fps_show));
//nk_checkbox_bool(ctx, "Show FPS", &(settings->fps_show));
//nk_checkbox_bool(ctx, "Show FPS", &(settings->fps_show));
nk_layout_row_dynamic(ctx, 30, 2);
nk_label(ctx, "Volume:", NK_TEXT_LEFT);
nk_slider_float(ctx, -80, &settings->audio.volume, 12, 0.5);
nk_layout_row_dynamic(ctx, 30, 1);
nk_property_int(ctx, "Max Users:", 1, (int*)&(settings->input.max_users),
MAX_USERS, 1, 1);
nk_label(ctx, "History:", NK_TEXT_LEFT);
size = menu_entries_get_size();
}
/* save position and size to restore after context reset */
zrmenu_set_state(zr, id, nk_window_get_position(ctx), nk_window_get_size(ctx));
nk_end(ctx);
}
void zrmenu_wnd_main(zrmenu_handle_t *zr)
{
struct nk_panel layout;
struct nk_context *ctx = &zr->ctx;
const int id = ZRMENU_WND_MAIN;
settings_t *settings = config_get_ptr();
if (nk_begin(ctx, &layout, "Main", nk_rect(-1, -1, 120, zr->size.x + 1),
NK_WINDOW_NO_SCROLLBAR))
{
struct nk_panel menu;
struct nk_panel node, context_menu;
/* context menu */
/* main menu */
nk_menubar_begin(ctx);
nk_layout_row_begin(ctx, NK_STATIC, 25, 1);
nk_layout_row_push(ctx, 100);
nk_layout_row_push(ctx, 60);
nk_menubar_end(ctx);
}
/* save position and size to restore after context reset */
zrmenu_set_state(zr, id, nk_window_get_position(ctx), nk_window_get_size(ctx));
if (zr->size_changed)
nk_window_set_size(ctx, nk_vec2(nk_window_get_size(ctx).x, zr->size.y));
nk_end(ctx);
}

View File

@ -15,23 +15,21 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "zr_common.h"
#include "nk_common.h"
#include "../menu_display.h"
#include "../menu_input.h"
enum
{
ZR_TEXTURE_POINTER = 0,
ZR_TEXTURE_LAST
NK_TEXTURE_POINTER = 0,
NK_TEXTURE_LAST
};
enum
{
ZRMENU_WND_MAIN = 0,
ZRMENU_WND_CONTROL,
ZRMENU_WND_SHADER_PARAMETERS,
ZRMENU_WND_TEST,
ZRMENU_WND_WIZARD
};
enum zrmenu_theme
@ -41,32 +39,32 @@ enum zrmenu_theme
};
struct icons {
struct zr_image folder;
struct zr_image monitor;
struct zr_image gamepad;
struct zr_image settings;
struct zr_image speaker;
struct zr_image invader;
struct zr_image page_on;
struct zr_image page_off;
struct nk_image folder;
struct nk_image monitor;
struct nk_image gamepad;
struct nk_image settings;
struct nk_image speaker;
struct nk_image invader;
struct nk_image page_on;
struct nk_image page_off;
};
struct window {
bool open;
struct zr_vec2 position;
struct zr_vec2 size;
struct nk_vec2 position;
struct nk_vec2 size;
};
typedef struct zrmenu_handle
{
/* zahnrad mandatory */
void *memory;
struct zr_context ctx;
struct zr_memory_status status;
struct nk_context ctx;
struct nk_memory_status status;
enum menu_action action;
/* window control variables */
struct zr_vec2 size;
struct nk_vec2 size;
bool size_changed;
struct window window[5];
@ -82,19 +80,13 @@ typedef struct zrmenu_handle
struct
{
menu_texture_item bg;
menu_texture_item list[ZR_TEXTURE_LAST];
menu_texture_item list[NK_TEXTURE_LAST];
} textures;
gfx_font_raster_block_t list_block;
} zrmenu_handle_t;
void zrmenu_set_style(struct zr_context *ctx, enum zrmenu_theme theme);
void zrmenu_wnd_wizard(zrmenu_handle_t *zr);
void zrmenu_wnd_shader_parameters(zrmenu_handle_t *zr);
void zrmenu_wnd_control(zrmenu_handle_t *zr);
void zrmenu_wnd_test(zrmenu_handle_t *zr);
void zrmenu_wnd_main(zrmenu_handle_t *zr);
static void ui_slider(struct zr_context *ctx, const char *title, int *value, int max, int active);
static int ui_selector(struct zr_context *ctx, const char *title, int *selected, const char *items[], int max, int active);

View File

@ -32,7 +32,7 @@
#include <lists/string_list.h>
#include "menu_generic.h"
#include "zr_menu.h"
#include "nk_menu.h"
#include "../menu_driver.h"
#include "../menu_animation.h"
@ -50,28 +50,19 @@
static void zrmenu_main(zrmenu_handle_t *zr)
{
struct zr_context *ctx = &zr->ctx;
struct nk_context *ctx = &zr->ctx;
if (zr->window[ZRMENU_WND_MAIN].open)
zrmenu_wnd_main(zr);
if (zr->window[ZRMENU_WND_CONTROL].open)
zrmenu_wnd_control(zr);
if (zr->window[ZRMENU_WND_SHADER_PARAMETERS].open)
zrmenu_wnd_shader_parameters(zr);
if (zr->window[ZRMENU_WND_TEST].open)
zrmenu_wnd_test(zr);
if (zr->window[ZRMENU_WND_WIZARD].open)
zrmenu_wnd_wizard(zr);
zr->window[ZRMENU_WND_CONTROL].open = !zr_window_is_closed(ctx, "Control");
zr->window[ZRMENU_WND_SHADER_PARAMETERS].open = !zr_window_is_closed(ctx, "Shader Parameters");
zr->window[ZRMENU_WND_TEST].open = !zr_window_is_closed(ctx, "Test");
zr->window[ZRMENU_WND_WIZARD].open = !zr_window_is_closed(ctx, "Setup Wizard");
zr->window[ZRMENU_WND_SHADER_PARAMETERS].open = !nk_window_is_closed(ctx, "Shader Parameters");
zr->window[ZRMENU_WND_TEST].open = !nk_window_is_closed(ctx, "Test");
if(zr_window_is_closed(ctx, "Setup Wizard"))
zr->window[ZRMENU_WND_MAIN].open = true;
zr_buffer_info(&zr->status, &zr->ctx.memory);
nk_buffer_info(&zr->status, &zr->ctx.memory);
}
static void zrmenu_input_gamepad(zrmenu_handle_t *zr)
@ -79,56 +70,56 @@ static void zrmenu_input_gamepad(zrmenu_handle_t *zr)
switch (zr->action)
{
case MENU_ACTION_LEFT:
zr_input_key(&zr->ctx, ZR_KEY_LEFT, 1);
nk_input_key(&zr->ctx, NK_KEY_LEFT, 1);
break;
case MENU_ACTION_RIGHT:
zr_input_key(&zr->ctx, ZR_KEY_RIGHT, 1);
nk_input_key(&zr->ctx, NK_KEY_RIGHT, 1);
break;
case MENU_ACTION_DOWN:
zr_input_key(&zr->ctx, ZR_KEY_DOWN, 1);
nk_input_key(&zr->ctx, NK_KEY_DOWN, 1);
break;
case MENU_ACTION_UP:
zr_input_key(&zr->ctx, ZR_KEY_UP, 1);
nk_input_key(&zr->ctx, NK_KEY_UP, 1);
break;
default:
zr_input_key(&zr->ctx, ZR_KEY_UP, 0);
zr_input_key(&zr->ctx, ZR_KEY_DOWN, 0);
zr_input_key(&zr->ctx, ZR_KEY_LEFT, 0);
zr_input_key(&zr->ctx, ZR_KEY_RIGHT, 0);
nk_input_key(&zr->ctx, NK_KEY_UP, 0);
nk_input_key(&zr->ctx, NK_KEY_DOWN, 0);
nk_input_key(&zr->ctx, NK_KEY_LEFT, 0);
nk_input_key(&zr->ctx, NK_KEY_RIGHT, 0);
break;
}
}
static void zrmenu_input_mouse_movement(struct zr_context *ctx)
static void zrmenu_input_mouse_movement(struct nk_context *ctx)
{
int16_t mouse_x = menu_input_mouse_state(MENU_MOUSE_X_AXIS);
int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS);
zr_input_motion(ctx, mouse_x, mouse_y);
zr_input_scroll(ctx, menu_input_mouse_state(MENU_MOUSE_WHEEL_UP) -
nk_input_motion(ctx, mouse_x, mouse_y);
nk_input_scroll(ctx, menu_input_mouse_state(MENU_MOUSE_WHEEL_UP) -
menu_input_mouse_state(MENU_MOUSE_WHEEL_DOWN));
}
static void zrmenu_input_mouse_button(struct zr_context *ctx)
static void zrmenu_input_mouse_button(struct nk_context *ctx)
{
int16_t mouse_x = menu_input_mouse_state(MENU_MOUSE_X_AXIS);
int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS);
zr_input_button(ctx, ZR_BUTTON_LEFT,
nk_input_button(ctx, NK_BUTTON_LEFT,
mouse_x, mouse_y, menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON));
zr_input_button(ctx, ZR_BUTTON_RIGHT,
nk_input_button(ctx, NK_BUTTON_RIGHT,
mouse_x, mouse_y, menu_input_mouse_state(MENU_MOUSE_RIGHT_BUTTON));
}
static void zrmenu_input_keyboard(struct zr_context *ctx)
static void zrmenu_input_keyboard(struct nk_context *ctx)
{
/* placeholder, it just presses 1 on right click
needs to be hooked up correctly
*/
if(menu_input_mouse_state(MENU_MOUSE_RIGHT_BUTTON))
zr_input_char(ctx, '1');
nk_input_char(ctx, '1');
}
static void zrmenu_context_reset_textures(zrmenu_handle_t *zr,
@ -136,14 +127,14 @@ static void zrmenu_context_reset_textures(zrmenu_handle_t *zr,
{
unsigned i;
for (i = 0; i < ZR_TEXTURE_LAST; i++)
for (i = 0; i < NK_TEXTURE_LAST; i++)
{
struct texture_image ti = {0};
char path[PATH_MAX_LENGTH] = {0};
switch(i)
{
case ZR_TEXTURE_POINTER:
case NK_TEXTURE_POINTER:
fill_pathname_join(path, iconpath,
"pointer.png", sizeof(path));
break;
@ -191,7 +182,7 @@ static void zrmenu_draw_cursor(zrmenu_handle_t *zr,
draw.height = 64;
draw.coords = &coords;
draw.matrix_data = NULL;
draw.texture = zr->textures.list[ZR_TEXTURE_POINTER];
draw.texture = zr->textures.list[NK_TEXTURE_POINTER];
draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP;
menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw);
@ -222,7 +213,7 @@ static void zrmenu_frame(void *data)
menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL);
zr_input_begin(&zr->ctx);
nk_input_begin(&zr->ctx);
zrmenu_input_gamepad(zr);
zrmenu_input_mouse_movement(&zr->ctx);
zrmenu_input_mouse_button(&zr->ctx);
@ -235,9 +226,11 @@ static void zrmenu_frame(void *data)
zr->size_changed = true;
}
zr_input_end(&zr->ctx);
nk_input_end(&zr->ctx);
zrmenu_main(zr);
zr_common_device_draw(&device, &zr->ctx, width, height, ZR_ANTI_ALIASING_ON);
if(nk_window_is_closed(&zr->ctx, "Shader Parameters"))
zrmenu_wnd_shader_parameters(zr);
nk_common_device_draw(&device, &zr->ctx, width, height, NK_ANTI_ALIASING_ON);
if (settings->menu.mouse.enable && (settings->video.fullscreen
|| !video_driver_ctl(RARCH_DISPLAY_CTL_HAS_WINDOWED, NULL)))
@ -272,33 +265,32 @@ static void zrmenu_init_device(zrmenu_handle_t *zr)
fill_pathname_join(buf, zr->assets_directory,
"DroidSans.ttf", sizeof(buf));
zr_alloc.userdata.ptr = NULL;
zr_alloc.alloc = zr_common_mem_alloc;
zr_alloc.free = zr_common_mem_free;
zr_buffer_init(&device.cmds, &zr_alloc, 1024);
usrfnt = zr_common_font(&device, &font, buf, 16,
zr_font_default_glyph_ranges());
zr_init(&zr->ctx, &zr_alloc, &usrfnt);
zr_common_device_init(&device);
nk_alloc.userdata.ptr = NULL;
nk_alloc.alloc = nk_common_mem_alloc;
nk_alloc.free = nk_common_mem_free;
nk_buffer_init(&device.cmds, &nk_alloc, 1024);
usrfnt = nk_common_font(&device, &font, buf, 16,
nk_font_default_glyph_ranges());
nk_init(&zr->ctx, &nk_alloc, &usrfnt);
nk_common_device_init(&device);
fill_pathname_join(buf, zr->assets_directory, "folder.png", sizeof(buf));
zr->icons.folder = zr_common_image_load(buf);
zr->icons.folder = nk_common_image_load(buf);
fill_pathname_join(buf, zr->assets_directory, "speaker.png", sizeof(buf));
zr->icons.speaker = zr_common_image_load(buf);
zr->icons.speaker = nk_common_image_load(buf);
fill_pathname_join(buf, zr->assets_directory, "gamepad.png", sizeof(buf));
zr->icons.gamepad = zr_common_image_load(buf);
zr->icons.gamepad = nk_common_image_load(buf);
fill_pathname_join(buf, zr->assets_directory, "monitor.png", sizeof(buf));
zr->icons.monitor = zr_common_image_load(buf);
zr->icons.monitor = nk_common_image_load(buf);
fill_pathname_join(buf, zr->assets_directory, "settings.png", sizeof(buf));
zr->icons.settings = zr_common_image_load(buf);
zr->icons.settings = nk_common_image_load(buf);
fill_pathname_join(buf, zr->assets_directory, "invader.png", sizeof(buf));
zr->icons.invader = zr_common_image_load(buf);
zr->icons.invader = nk_common_image_load(buf);
fill_pathname_join(buf, zr->assets_directory, "page_on.png", sizeof(buf));
zr->icons.page_on = zr_common_image_load(buf);
zr->icons.page_on = nk_common_image_load(buf);
fill_pathname_join(buf, zr->assets_directory, "page_off.png", sizeof(buf));
zr->icons.page_off = zr_common_image_load(buf);
zr->icons.page_off = nk_common_image_load(buf);
zrmenu_set_style(&zr->ctx, THEME_DARK);
zr->size_changed = true;
}
@ -329,8 +321,6 @@ static void *zrmenu_init(void **userdata)
"zahnrad", sizeof(zr->assets_directory));
zrmenu_init_device(zr);
zr->window[ZRMENU_WND_WIZARD].open = true;
return menu;
error:
if (menu)
@ -346,9 +336,9 @@ static void zrmenu_free(void *data)
return;
free(font.glyphs);
zr_free(&zr->ctx);
zr_buffer_free(&device.cmds);
zr_common_device_shutdown(&device);
nk_free(&zr->ctx);
nk_buffer_free(&device.cmds);
nk_common_device_shutdown(&device);
gfx_coord_array_free(&zr->list_block.carr);
font_driver_bind_block(NULL, NULL);
@ -369,7 +359,7 @@ static void zrmenu_context_destroy(void *data)
if (!zr)
return;
for (i = 0; i < ZR_TEXTURE_LAST; i++)
for (i = 0; i < NK_TEXTURE_LAST; i++)
video_driver_texture_unload((uintptr_t*)&zr->textures.list[i]);
menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_DEINIT, NULL);

View File

@ -1,76 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2011-2016 - Daniel De Matteis
* Copyright (C) 2014-2015 - Jean-André Santoni
* Copyright (C) 2016 - Andrés Suárez
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "../../deps/zahnrad/zahnrad.h"
#include "../../deps/stb/stb_image.h"
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
#include "../../gfx/common/gl_common.h"
#endif
#define MAX_VERTEX_MEMORY (512 * 1024)
#define MAX_ELEMENT_MEMORY (128 * 1024)
#define ZR_SYSTEM_TAB_END ZR_SYSTEM_TAB_SETTINGS
struct zr_device
{
struct zr_buffer cmds;
struct zr_draw_null_texture null;
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
GLuint vbo, vao, ebo;
GLuint prog;
GLuint vert_shdr;
GLuint frag_shdr;
GLint attrib_pos;
GLint attrib_uv;
GLint attrib_col;
GLint uniform_proj;
GLuint font_tex;
#endif
};
extern struct zr_font font;
extern struct zr_user_font usrfnt;
extern struct zr_allocator zr_alloc;
extern struct zr_device device;
struct zr_image zr_common_image_load(const char *filename);
char* zr_common_file_load(const char* path, size_t* size);
void zr_common_device_init(struct zr_device *dev);
struct zr_user_font zr_common_font(
struct zr_device *dev,
struct zr_font *font,
const char *path,
unsigned int font_height,
const zr_rune *range);
void zr_common_device_shutdown(struct zr_device *dev);
void zr_common_device_draw(struct zr_device *dev,
struct zr_context *ctx, int width, int height,
enum zr_anti_aliasing AA);
void* zr_common_mem_alloc(zr_handle unused, size_t size);
void zr_common_mem_free(zr_handle unused, void *ptr);

View File

@ -1,872 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2011-2016 - Daniel De Matteis
* Copyright (C) 2014-2015 - Jean-André Santoni
* Copyright (C) 2016 - Andrés Suárez
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "zr_menu.h"
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <file/file_path.h>
#include <string/stdstring.h>
#include <lists/string_list.h>
#include "../menu_driver.h"
#include "../menu_hash.h"
#include "../../gfx/common/gl_common.h"
#include "../../core_info.h"
#include "../../configuration.h"
#include "../../retroarch.h"
#define LEN(a) (sizeof(a)/sizeof(a)[0])
/* gamepad demo variables */
enum widget_id
{
WINDOW_MODE = 0,
MODEL_DETAIL,
TEXTURES,
SHADOWS,
LIGHTNING,
EFFECTS,
CONSOLE,
BRIGHTNESS,
VOLUME,
WIDGET_MAX
};
enum display_settings {
WINDOWED = 0, FULLSCREEN};
enum detail_settings {LOW, MEDIUM, HIGH, EXTRA_HIGH};
enum state_settings {OFF, ON};
const char *display[] = {"Windowed", "Fullscreen"};
const char *state[] = {"Off", "On"};
const char *detail[] = {"Low", "Medium", "High", "Extra High"};
static int window_mode = FULLSCREEN;
static int model_detail = HIGH;
static int texture_detail = EXTRA_HIGH;
static int shadow_detail = HIGH;
static int lighning_detail = LOW;
static int effects_detail = MEDIUM;
static int show_console = ON;
static int brightness = 90;
static int volume = 30;
static int active = WINDOW_MODE;
/* end of gamepad demo variables */
static int ui_selector(struct zr_context *ctx, const char *title, int *selected, const char *items[],
int max, int active)
{
struct zr_vec2 item_padding;
struct zr_rect bounds, label, content, tri, sel;
struct zr_panel *layout;
struct zr_command_buffer *out;
struct zr_color col;
struct zr_vec2 result[3];
zr_size text_len, text_width;
ZR_ASSERT(ctx);
ZR_ASSERT(ctx->current);
if (!ctx || !ctx->current)
return 0;
layout = zr_window_get_panel(ctx);
ZR_ASSERT(layout);
out = zr_window_get_canvas(ctx);
if (!zr_widget(&bounds, ctx))
return 0;
item_padding = zr_get_property(ctx, ZR_PROPERTY_ITEM_PADDING);
bounds.x += item_padding.x;
bounds.y += item_padding.y;
bounds.w -= 2 * item_padding.x;
bounds.h -= 2 * item_padding.y;
label.h = bounds.h;
label.w = bounds.w / 2.0f;
label.x = bounds.x + item_padding.x;
label.y = bounds.y + label.h/2.0f - (float)ctx->style.font.height/2.0f;
content.x = bounds.x + bounds.w/2.0f;
content.y = bounds.y;
content.w = bounds.w / 2.0f;
content.h = bounds.h;
if (active) zr_draw_rect(out, bounds, 0, zr_rgba(220, 220, 220, 135));
text_len = strlen(title);
col = (active) ? zr_rgba(0, 0, 0, 255): zr_rgba(220,220,220,220);
zr_draw_text(out, label, title, text_len, &ctx->style.font, zr_rgba(0,0,0,0), col);
if (zr_input_is_key_pressed(&ctx->input, ZR_KEY_RIGHT) && active)
*selected = MIN(*selected+1, max-1);
else if (zr_input_is_key_pressed(&ctx->input, ZR_KEY_LEFT) && active)
*selected = MAX(0, *selected-1);
tri.h = ctx->style.font.height - 2 * item_padding.y;
tri.w = tri.h/2.0f;
tri.x = content.x + item_padding.x;
tri.y = content.y + content.h/2 - tri.h/2.0f;
sel.x = tri.x + item_padding.x;
sel.y = tri.y;
sel.h = content.h;
if (*selected > 0) {
zr_triangle_from_direction(result, tri, 0, 0, ZR_LEFT);
zr_draw_triangle(out, result[0].x, result[0].y, result[1].x, result[1].y,
result[2].x, result[2].y, (active) ? zr_rgba(0, 0, 0, 255):
zr_rgba(100, 100, 100, 150));
}
tri.x = content.x + (content.w - item_padding.x) - tri.w;
sel.w = tri.x - sel.x;
if (*selected < max-1) {
zr_triangle_from_direction(result, tri, 0, 0, ZR_RIGHT);
zr_draw_triangle(out, result[0].x, result[0].y, result[1].x, result[1].y,
result[2].x, result[2].y, (active) ? zr_rgba(0, 0, 0, 255):
zr_rgba(100, 100, 100, 150));
}
text_width = ctx->style.font.width(ctx->style.font.userdata,
ctx->style.font.height, items[*selected], strlen(items[*selected]));
label.w = MAX(1, (float)text_width);
label.x = (sel.x + (sel.w - label.w) / 2);
label.x = MAX(sel.x, label.x);
label.w = MIN(sel.x + sel.w, label.x + label.w);
if (label.w >= label.x) label.w -= label.x;
zr_draw_text(out, label, items[*selected], strlen(items[*selected]),
&ctx->style.font, zr_rgba(0,0,0,0), col);
return 0;
}
static void ui_slider(struct zr_context *ctx, const char *title, int *value, int max, int active)
{
struct zr_vec2 item_padding;
struct zr_rect bounds, label, content, bar, cursor, tri;
struct zr_panel *layout;
struct zr_command_buffer *out;
struct zr_color col;
zr_size text_len, text_width;
float prog_scale = (float)*value / (float)max;
struct zr_vec2 result[3];
ZR_ASSERT(ctx);
ZR_ASSERT(ctx->current);
if (!ctx || !ctx->current)
return;
layout = zr_window_get_panel(ctx);
ZR_ASSERT(layout);
out = zr_window_get_canvas(ctx);
if (!zr_widget(&bounds, ctx))
return;
item_padding = zr_get_property(ctx, ZR_PROPERTY_ITEM_PADDING);
bounds.x += item_padding.x;
bounds.y += item_padding.y;
bounds.w -= 2 * item_padding.x;
bounds.h -= 2 * item_padding.y;
label.h = bounds.h;
label.w = bounds.w / 2.0f;
label.x = bounds.x + item_padding.x;
label.y = bounds.y + label.h/2.0f - (float)ctx->style.font.height/2.0f;
content.x = bounds.x + bounds.w/2.0f;
content.y = bounds.y;
content.w = bounds.w / 2.0f;
content.h = bounds.h;
if (active) zr_draw_rect(out, bounds, 0, zr_rgba(220, 220, 220, 135));
text_len = strlen(title);
col = (active) ? zr_rgba(0, 0, 0, 255): zr_rgba(220,220,220,220);
zr_draw_text(out, label, title, text_len, &ctx->style.font, zr_rgba(0,0,0,0), col);
if (zr_input_is_key_pressed(&ctx->input, ZR_KEY_LEFT) && active)
*value = MAX(0, *value - 10);
if (zr_input_is_key_pressed(&ctx->input, ZR_KEY_RIGHT) && active)
*value = MIN(*value + 10, max);
tri.h = ctx->style.font.height - 2 * item_padding.y;
tri.w = tri.h/2.0f;
tri.x = content.x + item_padding.x;
tri.y = content.y + content.h/2 - tri.h/2.0f;
bar.x = tri.x + 4 * item_padding.x + tri.w;
bar.h = tri.h / 4.0f;
bar.y = tri.y + tri.h/2.0f - bar.h/2.0f;
if (*value > 0) {
zr_triangle_from_direction(result, tri, 0, 0, ZR_LEFT);
zr_draw_triangle(out, result[0].x, result[0].y, result[1].x, result[1].y,
result[2].x, result[2].y, (active) ? zr_rgba(0, 0, 0, 255):
zr_rgba(100, 100, 100, 150));
}
tri.x = content.x + (content.w - item_padding.x) - tri.w;
bar.w = (tri.x - bar.x) - 4 * item_padding.x;
if (*value < max)
{
zr_triangle_from_direction(result, tri, 0, 0, ZR_RIGHT);
zr_draw_triangle(out, result[0].x, result[0].y, result[1].x, result[1].y,
result[2].x, result[2].y, (active) ? zr_rgba(0, 0, 0, 255):
zr_rgba(100, 100, 100, 150));
}
bar.w = (bar.w - tri.h/2.0f);
if (active)
{
zr_draw_rect(out, bar, 0, zr_rgba(0, 0, 0, 135));
bar.w = bar.w * prog_scale;
bar.y = tri.y; bar.x = bar.x + bar.w; bar.w = tri.h; bar.h = tri.h;
zr_draw_circle(out, bar, zr_rgba(220, 220, 220, 255));
}
else
{
zr_draw_rect(out, bar, 0, zr_rgba(220, 220, 220, 135));
bar.w = bar.w * prog_scale;
bar.y = tri.y; bar.x = bar.x + bar.w; bar.w = tri.h; bar.h = tri.h;
zr_draw_circle(out, bar, zr_rgba(190, 190, 190, 255));
}
}
bool zr_checkbox_bool(struct zr_context* cx, const char* text, bool *active)
{
int x = *active;
bool ret = zr_checkbox(cx, text, &x);
*active = x;
return ret;
}
float zr_checkbox_float(struct zr_context* cx, const char* text, float *active)
{
int x = *active;
float ret = zr_checkbox(cx, text, &x);
*active = x;
return ret;
}
static void zr_labelf(struct zr_context *ctx,
enum zr_text_align align, const char *fmt, ...)
{
char buffer[1024];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
buffer[1023] = 0;
zr_label(ctx, buffer, align);
va_end(args);
}
void zrmenu_set_style(struct zr_context *ctx, enum zrmenu_theme theme)
{
unsigned i;
for (i = 0; i < ZR_ROUNDING_MAX; ++i)
(ctx)->style.rounding[i] = 0;
switch (theme)
{
case THEME_LIGHT:
ctx->style.rounding[ZR_ROUNDING_SCROLLBAR] = 0;
ctx->style.properties[ZR_PROPERTY_SCROLLBAR_SIZE] = zr_vec2(10,10);
ctx->style.colors[ZR_COLOR_TEXT] = zr_rgba(20, 20, 20, 255);
ctx->style.colors[ZR_COLOR_TEXT_HOVERING] = zr_rgba(195, 195, 195, 255);
ctx->style.colors[ZR_COLOR_TEXT_ACTIVE] = zr_rgba(200, 200, 200, 255);
ctx->style.colors[ZR_COLOR_WINDOW] = zr_rgba(202, 212, 214, 215);
ctx->style.colors[ZR_COLOR_HEADER] = zr_rgba(137, 182, 224, 220);
ctx->style.colors[ZR_COLOR_BORDER] = zr_rgba(140, 159, 173, 0);
ctx->style.colors[ZR_COLOR_BUTTON] = zr_rgba(137, 182, 224, 255);
ctx->style.colors[ZR_COLOR_BUTTON_HOVER] = zr_rgba(142, 187, 229, 255);
ctx->style.colors[ZR_COLOR_BUTTON_ACTIVE] = zr_rgba(147, 192, 234, 255);
ctx->style.colors[ZR_COLOR_TOGGLE] = zr_rgba(177, 210, 210, 255);
ctx->style.colors[ZR_COLOR_TOGGLE_HOVER] = zr_rgba(245, 245, 245, 255);
ctx->style.colors[ZR_COLOR_TOGGLE_CURSOR] = zr_rgba(142, 187, 229, 255);
ctx->style.colors[ZR_COLOR_SELECTABLE] = zr_rgba(147, 192, 234, 255);
ctx->style.colors[ZR_COLOR_SELECTABLE_HOVER] = zr_rgba(150, 150, 150, 255);
ctx->style.colors[ZR_COLOR_SELECTABLE_TEXT] = zr_rgba(70, 70, 70, 255);
ctx->style.colors[ZR_COLOR_SLIDER] = zr_rgba(177, 210, 210, 255);
ctx->style.colors[ZR_COLOR_SLIDER_CURSOR] = zr_rgba(137, 182, 224, 245);
ctx->style.colors[ZR_COLOR_SLIDER_CURSOR_HOVER] = zr_rgba(142, 188, 229, 255);
ctx->style.colors[ZR_COLOR_SLIDER_CURSOR_ACTIVE] = zr_rgba(147, 193, 234, 255);
ctx->style.colors[ZR_COLOR_PROGRESS] = zr_rgba(177, 210, 210, 255);
ctx->style.colors[ZR_COLOR_PROGRESS_CURSOR] = zr_rgba(137, 182, 224, 255);
ctx->style.colors[ZR_COLOR_PROGRESS_CURSOR_HOVER] = zr_rgba(142, 188, 229, 255);
ctx->style.colors[ZR_COLOR_PROGRESS_CURSOR_ACTIVE] = zr_rgba(147, 193, 234, 255);
ctx->style.colors[ZR_COLOR_PROPERTY] = zr_rgba(210, 210, 210, 255);
ctx->style.colors[ZR_COLOR_PROPERTY_HOVER] = zr_rgba(235, 235, 235, 255);
ctx->style.colors[ZR_COLOR_PROPERTY_ACTIVE] = zr_rgba(230, 230, 230, 255);
ctx->style.colors[ZR_COLOR_INPUT] = zr_rgba(210, 210, 210, 225);
ctx->style.colors[ZR_COLOR_INPUT_CURSOR] = zr_rgba(20, 20, 20, 255);
ctx->style.colors[ZR_COLOR_INPUT_TEXT] = zr_rgba(20, 20, 20, 255);
ctx->style.colors[ZR_COLOR_COMBO] = zr_rgba(210, 210, 210, 255);
ctx->style.colors[ZR_COLOR_HISTO] = zr_rgba(210, 210, 210, 255);
ctx->style.colors[ZR_COLOR_HISTO_BARS] = zr_rgba(137, 182, 224, 255);
ctx->style.colors[ZR_COLOR_HISTO_HIGHLIGHT] = zr_rgba( 255, 0, 0, 255);
ctx->style.colors[ZR_COLOR_PLOT] = zr_rgba(210, 210, 210, 255);
ctx->style.colors[ZR_COLOR_PLOT_LINES] = zr_rgba(137, 182, 224, 255);
ctx->style.colors[ZR_COLOR_PLOT_HIGHLIGHT] = zr_rgba(255, 0, 0, 255);
ctx->style.colors[ZR_COLOR_SCROLLBAR] = zr_rgba(190, 200, 200, 255);
ctx->style.colors[ZR_COLOR_SCROLLBAR_CURSOR] = zr_rgba(64, 84, 95, 255);
ctx->style.colors[ZR_COLOR_SCROLLBAR_CURSOR_HOVER] = zr_rgba(70, 90, 100, 255);
ctx->style.colors[ZR_COLOR_SCROLLBAR_CURSOR_ACTIVE] = zr_rgba(75, 95, 105, 255);
ctx->style.colors[ZR_COLOR_TABLE_LINES] = zr_rgba(100, 100, 100, 255);
ctx->style.colors[ZR_COLOR_TAB_HEADER] = zr_rgba(156, 193, 220, 255);
ctx->style.colors[ZR_COLOR_SCALER] = zr_rgba(100, 100, 100, 255);
break;
case THEME_DARK:
ctx->style.rounding[ZR_ROUNDING_SCROLLBAR] = 0;
ctx->style.properties[ZR_PROPERTY_SCROLLBAR_SIZE] = zr_vec2(10,10);
ctx->style.colors[ZR_COLOR_TEXT] = zr_rgba(210, 210, 210, 255);
ctx->style.colors[ZR_COLOR_TEXT_HOVERING] = zr_rgba(195, 195, 195, 255);
ctx->style.colors[ZR_COLOR_TEXT_ACTIVE] = zr_rgba(200, 200, 200, 255);
ctx->style.colors[ZR_COLOR_WINDOW] = zr_rgba(45, 53, 56, 215);
ctx->style.colors[ZR_COLOR_HEADER] = zr_rgba(46, 46, 46, 255);
ctx->style.colors[ZR_COLOR_BORDER] = zr_rgba(46, 46, 46, 0);
ctx->style.colors[ZR_COLOR_BUTTON] = zr_rgba(48, 83, 111, 255);
ctx->style.colors[ZR_COLOR_BUTTON_HOVER] = zr_rgba(53, 88, 116, 255);
ctx->style.colors[ZR_COLOR_BUTTON_ACTIVE] = zr_rgba(58, 93, 121, 255);
ctx->style.colors[ZR_COLOR_TOGGLE] = zr_rgba(50, 58, 61, 255);
ctx->style.colors[ZR_COLOR_TOGGLE_HOVER] = zr_rgba(55, 63, 66, 255);
ctx->style.colors[ZR_COLOR_TOGGLE_CURSOR] = zr_rgba(48, 83, 111, 255);
ctx->style.colors[ZR_COLOR_SELECTABLE] = zr_rgba(48, 83, 111, 255);
ctx->style.colors[ZR_COLOR_SELECTABLE_HOVER] = zr_rgba(48, 83, 111, 255);
ctx->style.colors[ZR_COLOR_SELECTABLE_TEXT] = zr_rgba(210, 210, 210, 255);
ctx->style.colors[ZR_COLOR_SLIDER] = zr_rgba(50, 58, 61, 255);
ctx->style.colors[ZR_COLOR_SLIDER_CURSOR] = zr_rgba(48, 83, 111, 245);
ctx->style.colors[ZR_COLOR_SLIDER_CURSOR_HOVER] = zr_rgba(53, 88, 116, 255);
ctx->style.colors[ZR_COLOR_SLIDER_CURSOR_ACTIVE] = zr_rgba(58, 93, 121, 255);
ctx->style.colors[ZR_COLOR_PROGRESS] = zr_rgba(50, 58, 61, 255);
ctx->style.colors[ZR_COLOR_PROGRESS_CURSOR] = zr_rgba(48, 83, 111, 255);
ctx->style.colors[ZR_COLOR_PROGRESS_CURSOR_HOVER] = zr_rgba(53, 88, 116, 255);
ctx->style.colors[ZR_COLOR_PROGRESS_CURSOR_ACTIVE] = zr_rgba(58, 93, 121, 255);
ctx->style.colors[ZR_COLOR_PROPERTY] = zr_rgba(50, 58, 61, 255);
ctx->style.colors[ZR_COLOR_PROPERTY_HOVER] = zr_rgba(55, 63, 66, 255);
ctx->style.colors[ZR_COLOR_PROPERTY_ACTIVE] = zr_rgba(60, 68, 71, 255);
ctx->style.colors[ZR_COLOR_INPUT] = zr_rgba(50, 58, 61, 225);
ctx->style.colors[ZR_COLOR_INPUT_CURSOR] = zr_rgba(210, 210, 210, 255);
ctx->style.colors[ZR_COLOR_INPUT_TEXT] = zr_rgba(210, 210, 210, 255);
ctx->style.colors[ZR_COLOR_COMBO] = zr_rgba(50, 58, 61, 255);
ctx->style.colors[ZR_COLOR_HISTO] = zr_rgba(50, 58, 61, 255);
ctx->style.colors[ZR_COLOR_HISTO_BARS] = zr_rgba(48, 83, 111, 255);
ctx->style.colors[ZR_COLOR_HISTO_HIGHLIGHT] = zr_rgba(255, 0, 0, 255);
ctx->style.colors[ZR_COLOR_PLOT] = zr_rgba(50, 58, 61, 255);
ctx->style.colors[ZR_COLOR_PLOT_LINES] = zr_rgba(48, 83, 111, 255);
ctx->style.colors[ZR_COLOR_PLOT_HIGHLIGHT] = zr_rgba(255, 0, 0, 255);
ctx->style.colors[ZR_COLOR_SCROLLBAR] = zr_rgba(50, 58, 61, 255);
ctx->style.colors[ZR_COLOR_SCROLLBAR_CURSOR] = zr_rgba(48, 83, 111, 255);
ctx->style.colors[ZR_COLOR_SCROLLBAR_CURSOR_HOVER] = zr_rgba(53, 88, 116, 255);
ctx->style.colors[ZR_COLOR_SCROLLBAR_CURSOR_ACTIVE] = zr_rgba(58, 93, 121, 255);
ctx->style.colors[ZR_COLOR_TABLE_LINES] = zr_rgba(100, 100, 100, 255);
ctx->style.colors[ZR_COLOR_TAB_HEADER] = zr_rgba(48, 83, 111, 255);
ctx->style.colors[ZR_COLOR_SCALER] = zr_rgba(100, 100, 100, 255);
break;
default:
zr_load_default_style(ctx, ZR_DEFAULT_ALL);
}
}
void zrmenu_set_state(zrmenu_handle_t *zr, const int id,
struct zr_vec2 pos, struct zr_vec2 size)
{
zr->window[id].position = pos;
zr->window[id].size = size;
}
void zrmenu_get_state(zrmenu_handle_t *zr, const int id,
struct zr_vec2 *pos, struct zr_vec2 *size)
{
*pos = zr->window[id].position;
*size = zr->window[id].size;
}
void zrmenu_wnd_shader_parameters(zrmenu_handle_t *zr)
{
unsigned i;
video_shader_ctx_t shader_info;
struct zr_panel layout;
struct zr_context *ctx = &zr->ctx;
const int id = ZRMENU_WND_SHADER_PARAMETERS;
settings_t *settings = config_get_ptr();
if (zr_begin(ctx, &layout, "Shader Parameters", zr_rect(240, 10, 300, 400),
ZR_WINDOW_CLOSABLE|ZR_WINDOW_MINIMIZABLE|ZR_WINDOW_MOVABLE|
ZR_WINDOW_SCALABLE|ZR_WINDOW_BORDER))
{
struct zr_panel combo;
static const char *themes[] = {"Dark", "Light"};
enum zrmenu_theme old = zr->theme;
zr_layout_row_dynamic(ctx, 30, 1);
video_shader_driver_ctl(SHADER_CTL_GET_CURRENT_SHADER, &shader_info);
if (shader_info.data)
{
for (i = 0; i < GFX_MAX_PARAMETERS; i++)
{
if (!string_is_empty(shader_info.data->parameters[i].desc))
{
if(shader_info.data->parameters[i].minimum == 0 &&
shader_info.data->parameters[i].maximum == 1 &&
shader_info.data->parameters[i].step == 1)
zr_checkbox_float(ctx, shader_info.data->parameters[i].desc,
&(shader_info.data->parameters[i].current));
else
zr_property_float(ctx, shader_info.data->parameters[i].desc,
shader_info.data->parameters[i].minimum,
&(shader_info.data->parameters[i].current),
shader_info.data->parameters[i].maximum,
shader_info.data->parameters[i].step, 1);
}
}
}
}
/* save position and size to restore after context reset */
zrmenu_set_state(zr, id, zr_window_get_position(ctx), zr_window_get_size(ctx));
zr_end(ctx);
}
void zrmenu_wnd_control(zrmenu_handle_t *zr)
{
struct zr_panel layout;
struct zr_context *ctx = &zr->ctx;
const int id = ZRMENU_WND_CONTROL;
static int wnd_x = 900;
static int wnd_y = 60;
bool ret = (zr_begin(ctx, &layout, "Control",
zr_rect(wnd_x, wnd_y, 350, 520),
ZR_WINDOW_CLOSABLE|ZR_WINDOW_MINIMIZABLE|ZR_WINDOW_MOVABLE|
ZR_WINDOW_SCALABLE|ZR_WINDOW_BORDER));
if (ret)
{
unsigned i;
/* Style */
if (zr_layout_push(ctx, ZR_LAYOUT_TAB, "Metrics", ZR_MINIMIZED))
{
zr_layout_row_dynamic(ctx, 20, 2);
zr_label(ctx,"Total:", ZR_TEXT_LEFT);
zr_labelf(ctx, ZR_TEXT_LEFT, "%lu", zr->status.size);
zr_label(ctx,"Used:", ZR_TEXT_LEFT);
zr_labelf(ctx, ZR_TEXT_LEFT, "%lu", zr->status.allocated);
zr_label(ctx,"Required:", ZR_TEXT_LEFT);
zr_labelf(ctx, ZR_TEXT_LEFT, "%lu", zr->status.needed);
zr_label(ctx,"Calls:", ZR_TEXT_LEFT);
zr_labelf(ctx, ZR_TEXT_LEFT, "%lu", zr->status.calls);
zr_layout_pop(ctx);
}
if (zr_layout_push(ctx, ZR_LAYOUT_TAB, "Properties", ZR_MINIMIZED))
{
zr_layout_row_dynamic(ctx, 22, 3);
for (i = 0; i <= ZR_PROPERTY_SCROLLBAR_SIZE; ++i)
{
zr_label(ctx, zr_get_property_name((enum zr_style_properties)i), ZR_TEXT_LEFT);
zr_property_float(ctx, "#X:", 0, &ctx->style.properties[i].x, 20, 1, 1);
zr_property_float(ctx, "#Y:", 0, &ctx->style.properties[i].y, 20, 1, 1);
}
zr_layout_pop(ctx);
}
if (zr_layout_push(ctx, ZR_LAYOUT_TAB, "Rounding", ZR_MINIMIZED))
{
zr_layout_row_dynamic(ctx, 22, 2);
for (i = 0; i < ZR_ROUNDING_MAX; ++i)
{
zr_label(ctx, zr_get_rounding_name((enum zr_style_rounding)i), ZR_TEXT_LEFT);
zr_property_float(ctx, "#R:", 0, &ctx->style.rounding[i], 20, 1, 1);
}
zr_layout_pop(ctx);
}
}
/* save position and size to restore after context reset */
zrmenu_set_state(zr, id, zr_window_get_position(ctx), zr_window_get_size(ctx));
zr_end(ctx);
}
void zrmenu_wnd_test(zrmenu_handle_t *zr)
{
struct zr_panel layout;
struct zr_context *ctx = &zr->ctx;
const int id = ZRMENU_WND_TEST;
settings_t *settings = config_get_ptr();
if (zr_begin(ctx, &layout, "Test", zr_rect(140, 90, 500, 600),
ZR_WINDOW_CLOSABLE|ZR_WINDOW_MINIMIZABLE|ZR_WINDOW_MOVABLE|
ZR_WINDOW_SCALABLE|ZR_WINDOW_BORDER))
{
unsigned size;
struct zr_panel combo;
menu_entry_t entry;
static const char *themes[] = {"Dark", "Light"};
enum zrmenu_theme old = zr->theme;
zr_layout_row_dynamic(ctx, 30, 2);
if (zr_button_text(ctx, "Quit", ZR_BUTTON_DEFAULT))
{
/* event handling */
printf("Pressed Event\n");
rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL);
}
if (zr_button_text(ctx, "Quit", ZR_BUTTON_DEFAULT))
{
/* event handling */
printf("Pressed Event\n");
rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL);
}
zr_layout_row_dynamic(ctx, 30, 4);
zr_checkbox_bool(ctx, "Show FPS", &(settings->fps_show));
zr_checkbox_bool(ctx, "Show FPS", &(settings->fps_show));
zr_checkbox_bool(ctx, "Show FPS", &(settings->fps_show));
zr_checkbox_bool(ctx, "Show FPS", &(settings->fps_show));
zr_layout_row_dynamic(ctx, 30, 2);
zr_label(ctx, "Volume:", ZR_TEXT_LEFT);
zr_slider_float(ctx, -80, &settings->audio.volume, 12, 0.5);
zr_layout_row_dynamic(ctx, 30, 1);
zr_property_int(ctx, "Max Users:", 1, (int*)&(settings->input.max_users),
MAX_USERS, 1, 1);
if (zr_combo_begin_text(ctx, &combo, themes[zr->theme], 200))
{
zr_layout_row_dynamic(ctx, 25, 1);
zr->theme = zr_combo_item(ctx, themes[THEME_DARK], ZR_TEXT_CENTERED)
? THEME_DARK : zr->theme;
zr->theme = zr_combo_item(ctx, themes[THEME_LIGHT], ZR_TEXT_CENTERED)
? THEME_LIGHT : zr->theme;
if (old != zr->theme) zrmenu_set_style(ctx, zr->theme);
zr_combo_end(ctx);
}
zr_label(ctx, "History:", ZR_TEXT_LEFT);
size = menu_entries_get_size();
if (zr_combo_begin_text(ctx, &combo, "", 180))
{
unsigned i;
for (i = 0; i < size; i++)
{
menu_entry_get(&entry, 0, i, NULL, true);
zr_layout_row_dynamic(ctx, 25, 1);
zr_combo_item(ctx, entry.path, ZR_TEXT_LEFT);
}
zr_combo_end(ctx);
}
}
/* save position and size to restore after context reset */
zrmenu_set_state(zr, id, zr_window_get_position(ctx), zr_window_get_size(ctx));
zr_end(ctx);
}
void zrmenu_wnd_main(zrmenu_handle_t *zr)
{
struct zr_panel layout;
struct zr_context *ctx = &zr->ctx;
const int id = ZRMENU_WND_MAIN;
settings_t *settings = config_get_ptr();
if (zr_begin(ctx, &layout, "Main", zr_rect(-1, -1, 120, zr->size.x + 1),
ZR_WINDOW_NO_SCROLLBAR))
{
struct zr_panel menu;
struct zr_panel node, context_menu;
/* context menu */
if (zr_contextual_begin(ctx, &context_menu, 0, zr_vec2(100, 220),
zr_window_get_bounds(ctx)))
{
zr_layout_row_dynamic(ctx, 25, 1);
if (zr_contextual_item(ctx, "Test 1", ZR_TEXT_CENTERED))
printf("test \n");
if (zr_contextual_item(ctx, "Test 2",ZR_TEXT_CENTERED))
printf("test \n");
zr_contextual_end(ctx);
}
/* main menu */
zr_menubar_begin(ctx);
zr_layout_row_begin(ctx, ZR_STATIC, 25, 1);
zr_layout_row_push(ctx, 100);
if (zr_menu_text_begin(ctx, &menu, "Menu", ZR_TEXT_LEFT|ZR_TEXT_MIDDLE, 120))
{
zr_layout_row_dynamic(ctx, 25, 1);
if (zr_menu_item(ctx, ZR_TEXT_LEFT, "Test"))
printf("test \n");
if (zr_menu_item(ctx, ZR_TEXT_LEFT, "About"))
printf("test \n");
if (zr_menu_item(ctx, ZR_TEXT_LEFT, "Exit"))
rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL);
zr_menu_end(ctx);
}
if (zr_menu_text_begin(ctx, &menu, "Window", ZR_TEXT_LEFT|ZR_TEXT_MIDDLE, 120))
{
zr_layout_row_dynamic(ctx, 25, 1);
if (zr_menu_item(ctx, ZR_TEXT_LEFT, "Control"))
{
zr_window_close(ctx, "Control");
zr->window[ZRMENU_WND_CONTROL].open =
!zr->window[ZRMENU_WND_CONTROL].open;
}
if (zr_menu_item(ctx, ZR_TEXT_LEFT, "Shader Parameters"))
{
zr_window_close(ctx, "Shader Parameters");
zr->window[ZRMENU_WND_SHADER_PARAMETERS].open =
!zr->window[ZRMENU_WND_SHADER_PARAMETERS].open;
}
if (zr_menu_item(ctx, ZR_TEXT_LEFT, "Test Window"))
{
zr_window_close(ctx, "Test");
zr->window[ZRMENU_WND_TEST].open =
!zr->window[ZRMENU_WND_TEST].open;
}
if (zr_menu_item(ctx, ZR_TEXT_LEFT, "Wizard"))
{
zr_window_close(ctx, "Test");
zr->window[ZRMENU_WND_WIZARD].open =
!zr->window[ZRMENU_WND_WIZARD].open;
}
zr_menu_end(ctx);
}
zr_layout_row_push(ctx, 60);
zr_menubar_end(ctx);
}
/* save position and size to restore after context reset */
zrmenu_set_state(zr, id, zr_window_get_position(ctx), zr_window_get_size(ctx));
if (zr->size_changed)
zr_window_set_size(ctx, zr_vec2(zr_window_get_size(ctx).x, zr->size.y));
zr_end(ctx);
}
void zrmenu_wnd_wizard(zrmenu_handle_t *zr)
{
struct zr_panel layout;
struct zr_context *ctx = &zr->ctx;
const int id = ZRMENU_WND_WIZARD;
static int width = 800;
static int height = 600;
static int panel = 0;
settings_t *settings = config_get_ptr();
if (zr_begin(ctx, &layout, "Setup Wizard", zr_rect(zr->size.x/2 -width/2,
zr->size.y/2 - height/2, width, height),
ZR_WINDOW_CLOSABLE|ZR_WINDOW_MINIMIZABLE|ZR_WINDOW_MOVABLE|
ZR_WINDOW_BORDER|ZR_WINDOW_NO_SCROLLBAR))
{
/* uncomment this to hide the panel backgrounds
zr_push_color(ctx, ZR_COLOR_WINDOW, zr_rgba(0,0,0,0)); */
struct zr_panel sub;
switch (panel)
{
case 0:
zr_layout_row_begin(ctx, ZR_DYNAMIC, height * 0.80f, 2);
zr_layout_row_push(ctx, 0.15f);
if (zr_group_begin(ctx, &sub, "", ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_BORDER|ZR_WINDOW_NO_SCROLLBAR))
{
zr_layout_space_begin(ctx, ZR_STATIC, width * 0.15f, 1);
zr_layout_space_push(ctx, zr_rect(0, 0, width * 0.15f, width * 0.15f));
zr_image(ctx, zr->icons.invader);
zr_layout_space_end(ctx);
zr_group_end(ctx);
}
zr_layout_row_push(ctx, 0.85f);
if (zr_group_begin(ctx, &sub, "", ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_BORDER|ZR_WINDOW_NO_SCROLLBAR))
{
zr_layout_row_dynamic(ctx, 14, 15);
zr_image(ctx, zr->icons.page_on);
zr_image(ctx, zr->icons.page_off);
zr_image(ctx, zr->icons.page_off);
zr_image(ctx, zr->icons.page_off);
zr_image(ctx, zr->icons.page_off);
zr_layout_row_dynamic(ctx, 20, 1);
zr_label(ctx, "Label aligned left", ZR_TEXT_LEFT);
zr_label(ctx, "Label aligned centered", ZR_TEXT_CENTERED);
zr_label(ctx, "Label aligned right", ZR_TEXT_RIGHT);
zr_label_colored(ctx, "Blue text", ZR_TEXT_LEFT, zr_rgb(0,0,255));
zr_label_colored(ctx, "Yellow text", ZR_TEXT_LEFT, zr_rgb(255,255,0));
zr_text(ctx, "Text without /0", 15, ZR_TEXT_RIGHT);
zr_layout_row_dynamic(ctx, 100, 1);
zr_label_wrap(ctx, "This is a very long line to hopefully get this text to be wrapped into multiple lines to show line wrapping, someone should write some text welcoming users to retroarch or something like that in this window, I'm not really good at this");
zr_group_end(ctx);
}
zr_layout_row_end(ctx);
zr_layout_row_dynamic(ctx, 30, 4);
zr_label(ctx,"", ZR_TEXT_RIGHT);
zr_label(ctx,"", ZR_TEXT_RIGHT);
zr_label(ctx,"", ZR_TEXT_RIGHT);
if (zr_button_text(ctx, "Next", ZR_BUTTON_DEFAULT))
panel++;
break;
case 1:
zr_layout_row_begin(ctx, ZR_DYNAMIC, height * 0.80f, 2);
zr_layout_row_push(ctx, 0.15f);
if (zr_group_begin(ctx, &sub, "", ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_BORDER))
{
zr_layout_space_begin(ctx, ZR_STATIC, width * 0.15f, 1);
zr_layout_space_push(ctx, zr_rect(0, 0, width * 0.15f, width * 0.15f));
zr_layout_space_end(ctx);
zr_group_end(ctx);
}
zr_layout_row_push(ctx, 0.85f);
if (zr_group_begin(ctx, &sub, "", ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_BORDER|ZR_WINDOW_NO_SCROLLBAR))
{
zr_layout_row_dynamic(ctx, 14, 15);
zr_image(ctx, zr->icons.page_on);
zr_image(ctx, zr->icons.page_on);
zr_image(ctx, zr->icons.page_off);
zr_image(ctx, zr->icons.page_off);
zr_image(ctx, zr->icons.page_off);
zr_layout_row_dynamic(ctx, 40, 1);
zr_button_text_image(ctx, zr->icons.folder, settings->libretro, ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT);
zr_button_text_image(ctx, zr->icons.folder, settings->libretro, ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT);
zr_button_text_image(ctx, zr->icons.folder, settings->libretro, ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT);
zr_button_text_image(ctx, zr->icons.folder, settings->libretro, ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT);
zr_button_text_image(ctx, zr->icons.folder, settings->libretro, ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT);
zr_button_text_image(ctx, zr->icons.folder, settings->libretro, ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT);
zr_button_text_image(ctx, zr->icons.folder, settings->libretro, ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT);
zr_button_text_image(ctx, zr->icons.folder, settings->libretro, ZR_TEXT_CENTERED, ZR_BUTTON_DEFAULT);
zr_group_end(ctx);
}
zr_layout_row_end(ctx);
zr_layout_row_dynamic(ctx, 30, 4);
zr_label(ctx,"", ZR_TEXT_RIGHT);
zr_label(ctx,"", ZR_TEXT_RIGHT);
if (zr_button_text(ctx, "Previous", ZR_BUTTON_DEFAULT))
panel--;
if (zr_button_text(ctx, "Next", ZR_BUTTON_DEFAULT))
panel++;
break;
case 2:
zr_layout_row_begin(ctx, ZR_DYNAMIC, height * 0.80f, 2);
zr_layout_row_push(ctx, 0.15f);
if (zr_group_begin(ctx, &sub, "", ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_BORDER))
{
zr_layout_space_begin(ctx, ZR_STATIC, width * 0.15f, 1);
zr_layout_space_push(ctx, zr_rect(0, 0, width * 0.15f, width * 0.15f));
zr_layout_space_end(ctx);
zr_group_end(ctx);
}
zr_layout_row_push(ctx, 0.85f);
if (zr_group_begin(ctx, &sub, "", ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_BORDER|ZR_WINDOW_NO_SCROLLBAR))
{
zr_layout_row_dynamic(ctx, 14, 15);
zr_image(ctx, zr->icons.page_on);
zr_image(ctx, zr->icons.page_on);
zr_image(ctx, zr->icons.page_on);
zr_image(ctx, zr->icons.page_off);
zr_image(ctx, zr->icons.page_off);
zr_layout_row_dynamic(ctx, 50, 1);
ui_selector(ctx, "Windowed Mode", &window_mode, display, LEN(display), WINDOW_MODE == active);
ui_selector(ctx, "Model Detail", &model_detail, detail, LEN(detail), MODEL_DETAIL == active);
ui_selector(ctx, "Textures", &texture_detail, detail, LEN(detail), TEXTURES == active);
ui_selector(ctx, "Shadows", &shadow_detail, detail, LEN(detail), SHADOWS == active);
ui_selector(ctx, "Lighting", &lighning_detail, detail, LEN(detail), LIGHTNING == active);
ui_selector(ctx, "Effects", &effects_detail, detail, LEN(detail), EFFECTS == active);
ui_selector(ctx, "Console", &show_console, state, LEN(state), CONSOLE == active);
ui_slider(ctx, "Brightness", &brightness, 100, BRIGHTNESS == active);
ui_slider(ctx, "Volume", &volume, 100, VOLUME == active);
if (zr_input_is_key_pressed(&ctx->input, ZR_KEY_UP))
active = MAX(0, active-1);
if (zr_input_is_key_pressed(&ctx->input, ZR_KEY_DOWN))
active = MIN(active+1, WIDGET_MAX - 2);
zr_group_end(ctx);
}
zr_layout_row_end(ctx);
zr_layout_row_dynamic(ctx, 30, 4);
zr_label(ctx,"", ZR_TEXT_RIGHT);
zr_label(ctx,"", ZR_TEXT_RIGHT);
if (zr_button_text(ctx, "Previous", ZR_BUTTON_DEFAULT))
panel--;
if (zr_button_text(ctx, "Next", ZR_BUTTON_DEFAULT))
panel++;
break;
default:
zr_layout_row_begin(ctx, ZR_DYNAMIC, height * 0.80f, 2);
zr_layout_row_push(ctx, 0.15f);
if (zr_group_begin(ctx, &sub, "", ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_BORDER))
{
zr_layout_space_begin(ctx, ZR_STATIC, width * 0.15f, 1);
zr_layout_space_push(ctx, zr_rect(0, 0, width * 0.15f, width * 0.15f));
zr_layout_space_end(ctx);
zr_group_end(ctx);
}
zr_layout_row_push(ctx, 0.85f);
if (zr_group_begin(ctx, &sub, "", ZR_WINDOW_NO_SCROLLBAR|ZR_WINDOW_BORDER|ZR_WINDOW_NO_SCROLLBAR))
{
zr_layout_row_dynamic(ctx, 14, 15);
zr_image(ctx, zr->icons.page_on);
zr_image(ctx, zr->icons.page_on);
zr_image(ctx, zr->icons.page_on);
zr_image(ctx, zr->icons.page_off);
zr_image(ctx, zr->icons.page_off);
zr_layout_row_dynamic(ctx, 40, 1);
zr_group_end(ctx);
}
zr_layout_row_end(ctx);
zr_layout_row_dynamic(ctx, 30, 4);
zr_label(ctx,"", ZR_TEXT_RIGHT);
zr_label(ctx,"", ZR_TEXT_RIGHT);
if (zr_button_text(ctx, "Previous", ZR_BUTTON_DEFAULT))
panel--;
if (zr_button_text(ctx, "Next", ZR_BUTTON_DEFAULT))
panel++;
break;
}
zr_reset_colors(ctx);
}
/* save position and size to restore after context reset */
zrmenu_set_state(zr, id, zr_window_get_position(ctx), zr_window_get_size(ctx));
zr_end(ctx);
}