Merge branch 'Immediate-Mode-UI:master' into master
|
@ -0,0 +1,14 @@
|
|||
# EditorConfig: https://EditorConfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[clib.json]
|
||||
indent_size = 2
|
|
@ -0,0 +1,16 @@
|
|||
name: Create Tag
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: butlerlogic/action-autotag@stable
|
||||
with:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
root: clib.json
|
|
@ -92,7 +92,7 @@ nk_end(&ctx);
|
|||
![example](https://cloud.githubusercontent.com/assets/8057201/10187981/584ecd68-675c-11e5-897c-822ef534a876.png)
|
||||
|
||||
## Bindings
|
||||
There are a number of nuklear bindings for different languges created by other authors.
|
||||
There are a number of nuklear bindings for different languages created by other authors.
|
||||
I cannot attest for their quality since I am not necessarily proficient in any of these
|
||||
languages. Furthermore there are no guarantee that all bindings will always be kept up to date:
|
||||
|
||||
|
@ -185,8 +185,8 @@ Reviewing changes to `src/*` and `nuklear.h`:
|
|||
* Variable/function name casing.
|
||||
* Indentation.
|
||||
* Curly bracket (`{}`) placement.
|
||||
* Ensure that the contributer have bumped the appropriate version in
|
||||
[package.json](https://github.com/Immediate-Mode-UI/Nuklear/blob/master/package.json)
|
||||
* Ensure that the contributor has bumped the appropriate version in
|
||||
[clib.json](https://github.com/Immediate-Mode-UI/Nuklear/blob/master/clib.json)
|
||||
and added their changes to the
|
||||
[CHANGELOG](https://github.com/Immediate-Mode-UI/Nuklear/blob/master/src/CHANGELOG).
|
||||
* Have at least one other person review the changes before merging.
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
{
|
||||
"name": "nuklear",
|
||||
"version": "4.09.0",
|
||||
"version": "4.10.1",
|
||||
"repo": "Immediate-Mode-UI/Nuklear",
|
||||
"description": "A small ANSI C gui toolkit",
|
||||
"keywords": ["gl", "ui", "toolkit"],
|
||||
"license": "MIT, Unlicense",
|
||||
"src": ["nuklear.h"]
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
BIN = demo
|
||||
|
||||
# Flags
|
||||
CFLAGS += -std=c99 -pedantic -O2
|
||||
CFLAGS += -std=c89 -Wall -Wextra -pedantic -Wno-unused-function -O2
|
||||
|
||||
SRC = main.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
|
|
@ -29,32 +29,57 @@
|
|||
#define MAX(a,b) ((a) < (b) ? (b) : (a))
|
||||
#define LEN(a) (sizeof(a)/sizeof(a)[0])
|
||||
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* ===============================================================*/
|
||||
/* This are some code examples to provide a small overview of what can be
|
||||
* done with this library. To try out an example uncomment the include
|
||||
* and the corresponding function. */
|
||||
/*#include "../style.c"*/
|
||||
/*#include "../calculator.c"*/
|
||||
#include "../overview.c"
|
||||
/*#include "../node_editor.c"*/
|
||||
* done with this library. To try out an example uncomment the defines */
|
||||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
#define INCLUDE_OVERVIEW
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* DEMO
|
||||
*
|
||||
* ===============================================================*/
|
||||
static void error_callback(int e, const char *d)
|
||||
{printf("Error %d: %s\n", e, d);}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Platform */
|
||||
ALLEGRO_DISPLAY *display = NULL;
|
||||
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
|
||||
NkAllegro5Font *font;
|
||||
struct nk_context *ctx;
|
||||
|
||||
if (!al_init()) {
|
||||
fprintf(stdout, "failed to initialize allegro5!\n");
|
||||
|
@ -85,25 +110,32 @@ int main(void)
|
|||
al_register_event_source(event_queue, al_get_mouse_event_source());
|
||||
al_register_event_source(event_queue, al_get_keyboard_event_source());
|
||||
|
||||
NkAllegro5Font *font;
|
||||
font = nk_allegro5_font_create_from_file("../../../extra_font/Roboto-Regular.ttf", 12, 0);
|
||||
struct nk_context *ctx;
|
||||
|
||||
ctx = nk_allegro5_init(font, display, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
|
||||
/* style.c */
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
#ifdef INCLUDE_STYLE
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
while(1)
|
||||
{
|
||||
bool get_event;
|
||||
ALLEGRO_EVENT ev;
|
||||
ALLEGRO_TIMEOUT timeout;
|
||||
al_init_timeout(&timeout, 0.06);
|
||||
|
||||
bool get_event = al_wait_for_event_until(event_queue, &ev, &timeout);
|
||||
get_event = al_wait_for_event_until(event_queue, &ev, &timeout);
|
||||
|
||||
if (get_event && ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
|
||||
break;
|
||||
|
@ -141,9 +173,18 @@ int main(void)
|
|||
nk_end(ctx);
|
||||
|
||||
/* -------------- EXAMPLES ---------------- */
|
||||
/*calculator(ctx);*/
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
/*node_editor(ctx);*/
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
node_editor(ctx);
|
||||
#endif
|
||||
/* ----------------------------------------- */
|
||||
|
||||
/* Draw */
|
||||
|
|
|
@ -70,18 +70,20 @@ static struct nk_allegro5 {
|
|||
|
||||
NK_API struct nk_image* nk_allegro5_create_image(const char* file_name)
|
||||
{
|
||||
ALLEGRO_BITMAP *bitmap;
|
||||
struct nk_image *image;
|
||||
if (!al_init_image_addon()) {
|
||||
fprintf(stdout, "Unable to initialize required allegro5 image addon\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ALLEGRO_BITMAP* bitmap = al_load_bitmap(file_name);
|
||||
bitmap = al_load_bitmap(file_name);
|
||||
if (bitmap == NULL) {
|
||||
fprintf(stdout, "Unable to load image file: %s\n", file_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct nk_image *image = (struct nk_image*)calloc(1, sizeof(struct nk_image));
|
||||
image = (struct nk_image*)calloc(1, sizeof(struct nk_image));
|
||||
image->handle.ptr = bitmap;
|
||||
image->w = al_get_bitmap_width(bitmap);
|
||||
image->h = al_get_bitmap_height(bitmap);
|
||||
|
@ -98,7 +100,10 @@ NK_API void nk_allegro5_del_image(struct nk_image* image)
|
|||
static float
|
||||
nk_allegro5_font_get_text_width(nk_handle handle, float height, const char *text, int len)
|
||||
{
|
||||
float width;
|
||||
char *strcpy;
|
||||
NkAllegro5Font *font = (NkAllegro5Font*)handle.ptr;
|
||||
NK_UNUSED(height);
|
||||
if (!font || !text) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -106,16 +111,19 @@ nk_allegro5_font_get_text_width(nk_handle handle, float height, const char *text
|
|||
as nuklear uses variable size buffers and al_get_text_width doesn't
|
||||
accept a length, it infers length from null-termination
|
||||
(which is unsafe API design by allegro devs!) */
|
||||
char strcpy[len+1];
|
||||
strncpy((char*)&strcpy, text, len);
|
||||
strcpy = malloc(len + 1);
|
||||
strncpy(strcpy, text, len);
|
||||
strcpy[len] = '\0';
|
||||
return al_get_text_width(font->font, strcpy);
|
||||
width = al_get_text_width(font->font, strcpy);
|
||||
free(strcpy);
|
||||
return width;
|
||||
}
|
||||
|
||||
/* Flags are identical to al_load_font() flags argument */
|
||||
NK_API NkAllegro5Font*
|
||||
nk_allegro5_font_create_from_file(const char *file_name, int font_size, int flags)
|
||||
{
|
||||
NkAllegro5Font *font;
|
||||
if (!al_init_image_addon()) {
|
||||
fprintf(stdout, "Unable to initialize required allegro5 image addon\n");
|
||||
exit(1);
|
||||
|
@ -128,7 +136,7 @@ nk_allegro5_font_create_from_file(const char *file_name, int font_size, int flag
|
|||
fprintf(stdout, "Unable to initialize required allegro5 TTF font addon\n");
|
||||
exit(1);
|
||||
}
|
||||
NkAllegro5Font *font = (NkAllegro5Font*)calloc(1, sizeof(NkAllegro5Font));
|
||||
font = (NkAllegro5Font*)calloc(1, sizeof(NkAllegro5Font));
|
||||
|
||||
font->font = al_load_font(file_name, font_size, flags);
|
||||
if (font->font == NULL) {
|
||||
|
@ -200,18 +208,18 @@ nk_allegro5_render()
|
|||
(float)r->rounding, color);
|
||||
} break;
|
||||
case NK_COMMAND_CIRCLE: {
|
||||
float xr, yr;
|
||||
const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
|
||||
color = nk_color_to_allegro_color(c->color);
|
||||
float xr, yr;
|
||||
xr = (float)c->w/2;
|
||||
yr = (float)c->h/2;
|
||||
al_draw_ellipse(((float)(c->x)) + xr, ((float)c->y) + yr,
|
||||
xr, yr, color, (float)c->line_thickness);
|
||||
} break;
|
||||
case NK_COMMAND_CIRCLE_FILLED: {
|
||||
float xr, yr;
|
||||
const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
|
||||
color = nk_color_to_allegro_color(c->color);
|
||||
float xr, yr;
|
||||
xr = (float)c->w/2;
|
||||
yr = (float)c->h/2;
|
||||
al_draw_filled_ellipse(((float)(c->x)) + xr, ((float)c->y) + yr,
|
||||
|
@ -230,54 +238,61 @@ nk_allegro5_render()
|
|||
(float)t->b.y, (float)t->c.x, (float)t->c.y, color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYGON: {
|
||||
const struct nk_command_polygon *p = (const struct nk_command_polygon*)cmd;
|
||||
color = nk_color_to_allegro_color(p->color);
|
||||
int i;
|
||||
float vertices[p->point_count * 2];
|
||||
float *vertices;
|
||||
const struct nk_command_polygon *p = (const struct nk_command_polygon*)cmd;
|
||||
vertices = calloc(p->point_count * 2, sizeof(float));
|
||||
color = nk_color_to_allegro_color(p->color);
|
||||
for (i = 0; i < p->point_count; i++) {
|
||||
vertices[i*2] = p->points[i].x;
|
||||
vertices[(i*2) + 1] = p->points[i].y;
|
||||
}
|
||||
al_draw_polyline((const float*)&vertices, (2 * sizeof(float)),
|
||||
al_draw_polyline(vertices, (2 * sizeof(float)),
|
||||
(int)p->point_count, ALLEGRO_LINE_JOIN_ROUND, ALLEGRO_LINE_CAP_CLOSED,
|
||||
color, (float)p->line_thickness, 0.0);
|
||||
free(vertices);
|
||||
} break;
|
||||
case NK_COMMAND_POLYGON_FILLED: {
|
||||
int i, j = 0;
|
||||
float *vertices;
|
||||
const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd;
|
||||
vertices = calloc(p->point_count * 2, sizeof(float));
|
||||
color = nk_color_to_allegro_color(p->color);
|
||||
int i;
|
||||
float vertices[p->point_count * 2];
|
||||
for (i = 0; i < p->point_count; i++) {
|
||||
vertices[i*2] = p->points[i].x;
|
||||
vertices[(i*2) + 1] = p->points[i].y;
|
||||
for (i = p->point_count - 1; i >= 0; i--) {
|
||||
vertices[j++] = p->points[i].x;
|
||||
vertices[j++] = p->points[i].y;
|
||||
}
|
||||
al_draw_filled_polygon((const float*)&vertices, (int)p->point_count, color);
|
||||
al_draw_filled_polygon(vertices, (int)p->point_count, color);
|
||||
free(vertices);
|
||||
} break;
|
||||
case NK_COMMAND_POLYLINE: {
|
||||
const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
|
||||
color = nk_color_to_allegro_color(p->color);
|
||||
int i;
|
||||
float vertices[p->point_count * 2];
|
||||
float *vertices;
|
||||
const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
|
||||
vertices = calloc(p->point_count * 2, sizeof(float));
|
||||
color = nk_color_to_allegro_color(p->color);
|
||||
for (i = 0; i < p->point_count; i++) {
|
||||
vertices[i*2] = p->points[i].x;
|
||||
vertices[(i*2) + 1] = p->points[i].y;
|
||||
}
|
||||
al_draw_polyline((const float*)&vertices, (2 * sizeof(float)),
|
||||
al_draw_polyline(vertices, (2 * sizeof(float)),
|
||||
(int)p->point_count, ALLEGRO_LINE_JOIN_ROUND, ALLEGRO_LINE_CAP_ROUND,
|
||||
color, (float)p->line_thickness, 0.0);
|
||||
free(vertices);
|
||||
} break;
|
||||
case NK_COMMAND_TEXT: {
|
||||
NkAllegro5Font *font;
|
||||
const struct nk_command_text *t = (const struct nk_command_text*)cmd;
|
||||
color = nk_color_to_allegro_color(t->foreground);
|
||||
NkAllegro5Font *font = (NkAllegro5Font*)t->font->userdata.ptr;
|
||||
font = (NkAllegro5Font*)t->font->userdata.ptr;
|
||||
al_draw_text(font->font,
|
||||
color, (float)t->x, (float)t->y, 0,
|
||||
(const char*)t->string);
|
||||
} break;
|
||||
case NK_COMMAND_CURVE: {
|
||||
float points[8];
|
||||
const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
|
||||
color = nk_color_to_allegro_color(q->color);
|
||||
float points[8];
|
||||
points[0] = (float)q->begin.x;
|
||||
points[1] = (float)q->begin.y;
|
||||
points[2] = (float)q->ctrl[0].x;
|
||||
|
@ -291,15 +306,20 @@ nk_allegro5_render()
|
|||
case NK_COMMAND_ARC: {
|
||||
const struct nk_command_arc *a = (const struct nk_command_arc *)cmd;
|
||||
color = nk_color_to_allegro_color(a->color);
|
||||
al_draw_arc((float)a->cx, (float)a->cy, (float)a->r, a->a[0],
|
||||
al_draw_pieslice((float)a->cx, (float)a->cy, (float)a->r, a->a[0],
|
||||
a->a[1], color, (float)a->line_thickness);
|
||||
} break;
|
||||
case NK_COMMAND_ARC_FILLED: {
|
||||
const struct nk_command_arc_filled *a = (const struct nk_command_arc_filled *)cmd;
|
||||
color = nk_color_to_allegro_color(a->color);
|
||||
al_draw_filled_pieslice((float)a->cx, (float)a->cy, (float)a->r, a->a[0],
|
||||
a->a[1], color);
|
||||
} break;
|
||||
case NK_COMMAND_IMAGE: {
|
||||
const struct nk_command_image *i = (const struct nk_command_image *)cmd;
|
||||
al_draw_bitmap_region(i->img.handle.ptr, 0, 0, i->w, i->h, i->x, i->y, 0);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_MULTI_COLOR:
|
||||
case NK_COMMAND_ARC_FILLED:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
@ -465,12 +485,13 @@ NK_API struct nk_context*
|
|||
nk_allegro5_init(NkAllegro5Font *allegro5font, ALLEGRO_DISPLAY *dsp,
|
||||
unsigned int width, unsigned int height)
|
||||
{
|
||||
struct nk_user_font *font;
|
||||
if (!al_init_primitives_addon()) {
|
||||
fprintf(stdout, "Unable to initialize required allegro5 primitives addon\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct nk_user_font *font = &allegro5font->nk;
|
||||
font = &allegro5font->nk;
|
||||
|
||||
allegro5.dsp = dsp;
|
||||
allegro5.width = width;
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/* nuklear - v1.05 - public domain */
|
||||
struct nk_canvas {
|
||||
struct nk_command_buffer *painter;
|
||||
struct nk_vec2 item_spacing;
|
||||
struct nk_vec2 panel_padding;
|
||||
struct nk_style_item window_background;
|
||||
};
|
||||
|
||||
static nk_bool
|
||||
canvas_begin(struct nk_context *ctx, struct nk_canvas *canvas, nk_flags flags,
|
||||
int x, int y, int width, int height, struct nk_color background_color)
|
||||
{
|
||||
/* save style properties which will be overwritten */
|
||||
canvas->panel_padding = ctx->style.window.padding;
|
||||
canvas->item_spacing = ctx->style.window.spacing;
|
||||
canvas->window_background = ctx->style.window.fixed_background;
|
||||
|
||||
/* use the complete window space and set background */
|
||||
ctx->style.window.spacing = nk_vec2(0,0);
|
||||
ctx->style.window.padding = nk_vec2(0,0);
|
||||
ctx->style.window.fixed_background = nk_style_item_color(background_color);
|
||||
|
||||
/* create/update window and set position + size */
|
||||
if (!nk_begin(ctx, "Canvas", nk_rect(x, y, width, height), NK_WINDOW_NO_SCROLLBAR|flags))
|
||||
return nk_false;
|
||||
|
||||
/* allocate the complete window space for drawing */
|
||||
{
|
||||
struct nk_rect total_space;
|
||||
total_space = nk_window_get_content_region(ctx);
|
||||
nk_layout_row_dynamic(ctx, total_space.h, 1);
|
||||
nk_widget(&total_space, ctx);
|
||||
canvas->painter = nk_window_get_canvas(ctx);
|
||||
}
|
||||
|
||||
return nk_true;
|
||||
}
|
||||
|
||||
static void
|
||||
canvas_end(struct nk_context *ctx, struct nk_canvas *canvas)
|
||||
{
|
||||
nk_end(ctx);
|
||||
ctx->style.window.spacing = canvas->panel_padding;
|
||||
ctx->style.window.padding = canvas->item_spacing;
|
||||
ctx->style.window.fixed_background = canvas->window_background;
|
||||
}
|
||||
|
||||
static void
|
||||
canvas(struct nk_context *ctx)
|
||||
{
|
||||
struct nk_canvas canvas;
|
||||
if (canvas_begin(ctx, &canvas, NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
|
||||
NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE, 10, 10, 500, 550, nk_rgb(250,250,250)))
|
||||
{
|
||||
float x = canvas.painter->clip.x, y = canvas.painter->clip.y;
|
||||
|
||||
nk_fill_rect(canvas.painter, nk_rect(x + 15, y + 15, 210, 210), 5, nk_rgb(247, 230, 154));
|
||||
nk_fill_rect(canvas.painter, nk_rect(x + 20, y + 20, 200, 200), 5, nk_rgb(188, 174, 118));
|
||||
/* nk_draw_text(canvas.painter, nk_rect(x + 30, y + 30, 150, 20), "Text to draw", 12, &font->handle, nk_rgb(188,174,118), nk_rgb(0,0,0)); */
|
||||
nk_fill_rect(canvas.painter, nk_rect(x + 250, y + 20, 100, 100), 0, nk_rgb(0,0,255));
|
||||
nk_fill_circle(canvas.painter, nk_rect(x + 20, y + 250, 100, 100), nk_rgb(255,0,0));
|
||||
nk_fill_triangle(canvas.painter, x + 250, y + 250, x + 350, y + 250, x + 300, y + 350, nk_rgb(0,255,0));
|
||||
nk_fill_arc(canvas.painter, x + 300, y + 420, 50, 0, 3.141592654f * 3.0f / 4.0f, nk_rgb(255,255,0));
|
||||
|
||||
{
|
||||
float points[12];
|
||||
points[0] = x + 200; points[1] = y + 250;
|
||||
points[2] = x + 250; points[3] = y + 350;
|
||||
points[4] = x + 225; points[5] = y + 350;
|
||||
points[6] = x + 200; points[7] = y + 300;
|
||||
points[8] = x + 175; points[9] = y + 350;
|
||||
points[10] = x + 150; points[11] = y + 350;
|
||||
nk_fill_polygon(canvas.painter, points, 6, nk_rgb(0,0,0));
|
||||
}
|
||||
|
||||
{
|
||||
float points[12];
|
||||
points[0] = x + 200; points[1] = y + 370;
|
||||
points[2] = x + 250; points[3] = y + 470;
|
||||
points[4] = x + 225; points[5] = y + 470;
|
||||
points[6] = x + 200; points[7] = y + 420;
|
||||
points[8] = x + 175; points[9] = y + 470;
|
||||
points[10] = x + 150; points[11] = y + 470;
|
||||
nk_stroke_polygon(canvas.painter, points, 6, 4, nk_rgb(0,0,0));
|
||||
}
|
||||
|
||||
{
|
||||
float points[8];
|
||||
points[0] = x + 250; points[1] = y + 200;
|
||||
points[2] = x + 275; points[3] = y + 220;
|
||||
points[4] = x + 325; points[5] = y + 170;
|
||||
points[6] = x + 350; points[7] = y + 200;
|
||||
nk_stroke_polyline(canvas.painter, points, 4, 2, nk_rgb(255,128,0));
|
||||
}
|
||||
|
||||
nk_stroke_line(canvas.painter, x + 15, y + 10, x + 200, y + 10, 2.0f, nk_rgb(189,45,75));
|
||||
nk_stroke_rect(canvas.painter, nk_rect(x + 370, y + 20, 100, 100), 10, 3, nk_rgb(0,0,255));
|
||||
nk_stroke_curve(canvas.painter, x + 380, y + 200, x + 405, y + 270, x + 455, y + 120, x + 480, y + 200, 2, nk_rgb(0,150,220));
|
||||
nk_stroke_circle(canvas.painter, nk_rect(x + 20, y + 370, 100, 100), 5, nk_rgb(0,255,120));
|
||||
nk_stroke_triangle(canvas.painter, x + 370, y + 250, x + 470, y + 250, x + 420, y + 350, 6, nk_rgb(255,0,143));
|
||||
nk_stroke_arc(canvas.painter, x + 420, y + 420, 50, 0, 3.141592654f * 3.0f / 4.0f, 5, nk_rgb(0,255,255));
|
||||
}
|
||||
canvas_end(ctx, &canvas);
|
||||
}
|
||||
|
|
@ -0,0 +1,511 @@
|
|||
#include <string.h> // strcpy, strlen
|
||||
|
||||
#ifdef __unix__
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <pwd.h>
|
||||
#endif
|
||||
|
||||
struct icons {
|
||||
struct nk_image desktop;
|
||||
struct nk_image home;
|
||||
struct nk_image computer;
|
||||
struct nk_image directory;
|
||||
|
||||
struct nk_image default_file;
|
||||
struct nk_image text_file;
|
||||
struct nk_image music_file;
|
||||
struct nk_image font_file;
|
||||
struct nk_image img_file;
|
||||
struct nk_image movie_file;
|
||||
};
|
||||
|
||||
enum file_groups {
|
||||
FILE_GROUP_DEFAULT,
|
||||
FILE_GROUP_TEXT,
|
||||
FILE_GROUP_MUSIC,
|
||||
FILE_GROUP_FONT,
|
||||
FILE_GROUP_IMAGE,
|
||||
FILE_GROUP_MOVIE,
|
||||
FILE_GROUP_MAX
|
||||
};
|
||||
|
||||
enum file_types {
|
||||
FILE_DEFAULT,
|
||||
FILE_TEXT,
|
||||
FILE_C_SOURCE,
|
||||
FILE_CPP_SOURCE,
|
||||
FILE_HEADER,
|
||||
FILE_CPP_HEADER,
|
||||
FILE_MP3,
|
||||
FILE_WAV,
|
||||
FILE_OGG,
|
||||
FILE_TTF,
|
||||
FILE_BMP,
|
||||
FILE_PNG,
|
||||
FILE_JPEG,
|
||||
FILE_PCX,
|
||||
FILE_TGA,
|
||||
FILE_GIF,
|
||||
FILE_MAX
|
||||
};
|
||||
|
||||
struct file_group {
|
||||
enum file_groups group;
|
||||
const char *name;
|
||||
struct nk_image *icon;
|
||||
};
|
||||
|
||||
struct file {
|
||||
enum file_types type;
|
||||
const char *suffix;
|
||||
enum file_groups group;
|
||||
};
|
||||
|
||||
struct media {
|
||||
int font;
|
||||
int icon_sheet;
|
||||
struct icons icons;
|
||||
struct file_group group[FILE_GROUP_MAX];
|
||||
struct file files[FILE_MAX];
|
||||
};
|
||||
|
||||
#define MAX_PATH_LEN 512
|
||||
struct file_browser {
|
||||
/* path */
|
||||
char file[MAX_PATH_LEN];
|
||||
char home[MAX_PATH_LEN];
|
||||
char desktop[MAX_PATH_LEN];
|
||||
char directory[MAX_PATH_LEN];
|
||||
|
||||
/* directory content */
|
||||
char **files;
|
||||
char **directories;
|
||||
size_t file_count;
|
||||
size_t dir_count;
|
||||
struct media *media;
|
||||
};
|
||||
|
||||
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 struct nk_image
|
||||
icon_load(const char *filename)
|
||||
{
|
||||
int x,y,n;
|
||||
GLuint tex;
|
||||
unsigned char *data = stbi_load(filename, &x, &y, &n, 0);
|
||||
if (!data) die("[SDL]: failed to load image: %s", filename);
|
||||
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
stbi_image_free(data);
|
||||
return nk_image_id((int)tex);
|
||||
}
|
||||
|
||||
#if 0
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char*
|
||||
str_duplicate(const char *src)
|
||||
{
|
||||
char *ret;
|
||||
size_t len = strlen(src);
|
||||
if (!len) return 0;
|
||||
ret = (char*)malloc(len+1);
|
||||
if (!ret) return 0;
|
||||
memcpy(ret, src, len);
|
||||
ret[len] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
dir_free_list(char **list, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < size; ++i)
|
||||
free(list[i]);
|
||||
free(list);
|
||||
}
|
||||
|
||||
static char**
|
||||
dir_list(const char *dir, int return_subdirs, size_t *count)
|
||||
{
|
||||
size_t n = 0;
|
||||
char buffer[MAX_PATH_LEN];
|
||||
char **results = NULL;
|
||||
const DIR *none = NULL;
|
||||
size_t capacity = 32;
|
||||
size_t size;
|
||||
DIR *z;
|
||||
|
||||
assert(dir);
|
||||
assert(count);
|
||||
strncpy(buffer, dir, MAX_PATH_LEN);
|
||||
buffer[MAX_PATH_LEN - 1] = 0;
|
||||
n = strlen(buffer);
|
||||
|
||||
if (n > 0 && (buffer[n-1] != '/'))
|
||||
buffer[n++] = '/';
|
||||
|
||||
size = 0;
|
||||
|
||||
z = opendir(dir);
|
||||
if (z != none) {
|
||||
int nonempty = 1;
|
||||
struct dirent *data = readdir(z);
|
||||
nonempty = (data != NULL);
|
||||
if (!nonempty) return NULL;
|
||||
|
||||
do {
|
||||
DIR *y;
|
||||
char *p;
|
||||
int is_subdir;
|
||||
if (data->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
strncpy(buffer + n, data->d_name, MAX_PATH_LEN-n);
|
||||
y = opendir(buffer);
|
||||
is_subdir = (y != NULL);
|
||||
if (y != NULL) closedir(y);
|
||||
|
||||
if ((return_subdirs && is_subdir) || (!is_subdir && !return_subdirs)){
|
||||
if (!size) {
|
||||
results = (char**)calloc(sizeof(char*), capacity);
|
||||
} else if (size >= capacity) {
|
||||
void *old = results;
|
||||
capacity = capacity * 2;
|
||||
results = (char**)realloc(results, capacity * sizeof(char*));
|
||||
assert(results);
|
||||
if (!results) free(old);
|
||||
}
|
||||
p = str_duplicate(data->d_name);
|
||||
results[size++] = p;
|
||||
}
|
||||
} while ((data = readdir(z)) != NULL);
|
||||
}
|
||||
|
||||
if (z) closedir(z);
|
||||
*count = size;
|
||||
return results;
|
||||
}
|
||||
|
||||
static struct file_group
|
||||
FILE_GROUP(enum file_groups group, const char *name, struct nk_image *icon)
|
||||
{
|
||||
struct file_group fg;
|
||||
fg.group = group;
|
||||
fg.name = name;
|
||||
fg.icon = icon;
|
||||
return fg;
|
||||
}
|
||||
|
||||
static struct file
|
||||
FILE_DEF(enum file_types type, const char *suffix, enum file_groups group)
|
||||
{
|
||||
struct file fd;
|
||||
fd.type = type;
|
||||
fd.suffix = suffix;
|
||||
fd.group = group;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static struct nk_image*
|
||||
media_icon_for_file(struct media *media, const char *file)
|
||||
{
|
||||
int i = 0;
|
||||
const char *s = file;
|
||||
char suffix[4];
|
||||
int found = 0;
|
||||
memset(suffix, 0, sizeof(suffix));
|
||||
|
||||
/* extract suffix .xxx from file */
|
||||
while (*s++ != '\0') {
|
||||
if (found && i < 3)
|
||||
suffix[i++] = *s;
|
||||
|
||||
if (*s == '.') {
|
||||
if (found){
|
||||
found = 0;
|
||||
break;
|
||||
}
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for all file definition of all groups for fitting suffix*/
|
||||
for (i = 0; i < FILE_MAX && found; ++i) {
|
||||
struct file *d = &media->files[i];
|
||||
{
|
||||
const char *f = d->suffix;
|
||||
s = suffix;
|
||||
while (f && *f && *s && *s == *f) {
|
||||
s++; f++;
|
||||
}
|
||||
|
||||
/* found correct file definition so */
|
||||
if (f && *s == '\0' && *f == '\0')
|
||||
return media->group[d->group].icon;
|
||||
}
|
||||
}
|
||||
return &media->icons.default_file;
|
||||
}
|
||||
|
||||
static void
|
||||
media_init(struct media *media)
|
||||
{
|
||||
/* file groups */
|
||||
struct icons *icons = &media->icons;
|
||||
media->group[FILE_GROUP_DEFAULT] = FILE_GROUP(FILE_GROUP_DEFAULT,"default",&icons->default_file);
|
||||
media->group[FILE_GROUP_TEXT] = FILE_GROUP(FILE_GROUP_TEXT, "textual", &icons->text_file);
|
||||
media->group[FILE_GROUP_MUSIC] = FILE_GROUP(FILE_GROUP_MUSIC, "music", &icons->music_file);
|
||||
media->group[FILE_GROUP_FONT] = FILE_GROUP(FILE_GROUP_FONT, "font", &icons->font_file);
|
||||
media->group[FILE_GROUP_IMAGE] = FILE_GROUP(FILE_GROUP_IMAGE, "image", &icons->img_file);
|
||||
media->group[FILE_GROUP_MOVIE] = FILE_GROUP(FILE_GROUP_MOVIE, "movie", &icons->movie_file);
|
||||
|
||||
/* files */
|
||||
media->files[FILE_DEFAULT] = FILE_DEF(FILE_DEFAULT, NULL, FILE_GROUP_DEFAULT);
|
||||
media->files[FILE_TEXT] = FILE_DEF(FILE_TEXT, "txt", FILE_GROUP_TEXT);
|
||||
media->files[FILE_C_SOURCE] = FILE_DEF(FILE_C_SOURCE, "c", FILE_GROUP_TEXT);
|
||||
media->files[FILE_CPP_SOURCE] = FILE_DEF(FILE_CPP_SOURCE, "cpp", FILE_GROUP_TEXT);
|
||||
media->files[FILE_HEADER] = FILE_DEF(FILE_HEADER, "h", FILE_GROUP_TEXT);
|
||||
media->files[FILE_CPP_HEADER] = FILE_DEF(FILE_HEADER, "hpp", FILE_GROUP_TEXT);
|
||||
media->files[FILE_MP3] = FILE_DEF(FILE_MP3, "mp3", FILE_GROUP_MUSIC);
|
||||
media->files[FILE_WAV] = FILE_DEF(FILE_WAV, "wav", FILE_GROUP_MUSIC);
|
||||
media->files[FILE_OGG] = FILE_DEF(FILE_OGG, "ogg", FILE_GROUP_MUSIC);
|
||||
media->files[FILE_TTF] = FILE_DEF(FILE_TTF, "ttf", FILE_GROUP_FONT);
|
||||
media->files[FILE_BMP] = FILE_DEF(FILE_BMP, "bmp", FILE_GROUP_IMAGE);
|
||||
media->files[FILE_PNG] = FILE_DEF(FILE_PNG, "png", FILE_GROUP_IMAGE);
|
||||
media->files[FILE_JPEG] = FILE_DEF(FILE_JPEG, "jpg", FILE_GROUP_IMAGE);
|
||||
media->files[FILE_PCX] = FILE_DEF(FILE_PCX, "pcx", FILE_GROUP_IMAGE);
|
||||
media->files[FILE_TGA] = FILE_DEF(FILE_TGA, "tga", FILE_GROUP_IMAGE);
|
||||
media->files[FILE_GIF] = FILE_DEF(FILE_GIF, "gif", FILE_GROUP_IMAGE);
|
||||
}
|
||||
|
||||
static void
|
||||
file_browser_reload_directory_content(struct file_browser *browser, const char *path)
|
||||
{
|
||||
strncpy(browser->directory, path, MAX_PATH_LEN);
|
||||
browser->directory[MAX_PATH_LEN - 1] = 0;
|
||||
dir_free_list(browser->files, browser->file_count);
|
||||
dir_free_list(browser->directories, browser->dir_count);
|
||||
browser->files = dir_list(path, 0, &browser->file_count);
|
||||
browser->directories = dir_list(path, 1, &browser->dir_count);
|
||||
}
|
||||
|
||||
static void
|
||||
file_browser_init(struct file_browser *browser, struct media *media)
|
||||
{
|
||||
memset(browser, 0, sizeof(*browser));
|
||||
browser->media = media;
|
||||
{
|
||||
/* load files and sub-directory list */
|
||||
const char *home = getenv("HOME");
|
||||
#ifdef _WIN32
|
||||
if (!home) home = getenv("USERPROFILE");
|
||||
#else
|
||||
if (!home) home = getpwuid(getuid())->pw_dir;
|
||||
{
|
||||
size_t l;
|
||||
strncpy(browser->home, home, MAX_PATH_LEN);
|
||||
browser->home[MAX_PATH_LEN - 1] = 0;
|
||||
l = strlen(browser->home);
|
||||
strcpy(browser->home + l, "/");
|
||||
strcpy(browser->directory, browser->home);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
size_t l;
|
||||
strcpy(browser->desktop, browser->home);
|
||||
l = strlen(browser->desktop);
|
||||
strcpy(browser->desktop + l, "desktop/");
|
||||
}
|
||||
browser->files = dir_list(browser->directory, 0, &browser->file_count);
|
||||
browser->directories = dir_list(browser->directory, 1, &browser->dir_count);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
file_browser_free(struct file_browser *browser)
|
||||
{
|
||||
if (browser->files)
|
||||
dir_free_list(browser->files, browser->file_count);
|
||||
if (browser->directories)
|
||||
dir_free_list(browser->directories, browser->dir_count);
|
||||
browser->files = NULL;
|
||||
browser->directories = NULL;
|
||||
memset(browser, 0, sizeof(*browser));
|
||||
}
|
||||
|
||||
int cmp_fn(const void *str1, const void *str2)
|
||||
{
|
||||
const char *str1_ret = *(const char **)str1;
|
||||
const char *str2_ret = *(const char **)str2;
|
||||
return nk_stricmp(str1_ret, str2_ret);
|
||||
}
|
||||
|
||||
static int
|
||||
file_browser_run(struct file_browser *browser, struct nk_context *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
struct media *media = browser->media;
|
||||
struct nk_rect total_space;
|
||||
static nk_bool file_browser_is_open = nk_true;
|
||||
|
||||
if (file_browser_is_open)
|
||||
{
|
||||
if (nk_begin(ctx, "File Browser", nk_rect(50, 50, 600, 400),
|
||||
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|NK_WINDOW_NO_SCROLLBAR|
|
||||
NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
|
||||
{
|
||||
static float ratio[] = {0.25f, NK_UNDEFINED};
|
||||
float spacing_x = ctx->style.window.spacing.x;
|
||||
|
||||
/* output path directory selector in the menubar */
|
||||
ctx->style.window.spacing.x = 0;
|
||||
nk_menubar_begin(ctx);
|
||||
{
|
||||
char *d = browser->directory;
|
||||
char *begin = d + 1;
|
||||
nk_layout_row_dynamic(ctx, 25, 6);
|
||||
while (*d++) {
|
||||
if (*d == '/') {
|
||||
*d = '\0';
|
||||
if (nk_button_label(ctx, begin)) {
|
||||
*d++ = '/'; *d = '\0';
|
||||
file_browser_reload_directory_content(browser, browser->directory);
|
||||
break;
|
||||
}
|
||||
*d = '/';
|
||||
begin = d + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
nk_menubar_end(ctx);
|
||||
ctx->style.window.spacing.x = spacing_x;
|
||||
|
||||
/* window layout */
|
||||
total_space = nk_window_get_content_region(ctx);
|
||||
nk_layout_row(ctx, NK_DYNAMIC, total_space.h - 40, 2, ratio);
|
||||
|
||||
nk_group_begin(ctx, "Special", NK_WINDOW_NO_SCROLLBAR);
|
||||
{
|
||||
struct nk_image home = media->icons.home;
|
||||
struct nk_image desktop = media->icons.desktop;
|
||||
struct nk_image computer = media->icons.computer;
|
||||
|
||||
nk_layout_row_dynamic(ctx, 40, 1);
|
||||
if (nk_button_image_label(ctx, home, "home", NK_TEXT_CENTERED))
|
||||
file_browser_reload_directory_content(browser, browser->home);
|
||||
if (nk_button_image_label(ctx,desktop,"desktop",NK_TEXT_CENTERED))
|
||||
file_browser_reload_directory_content(browser, browser->desktop);
|
||||
if (nk_button_image_label(ctx,computer,"computer",NK_TEXT_CENTERED))
|
||||
file_browser_reload_directory_content(browser, "/");
|
||||
nk_group_end(ctx);
|
||||
}
|
||||
|
||||
/* output directory content window */
|
||||
nk_group_begin(ctx, "Content", NK_WINDOW_BORDER);
|
||||
{
|
||||
int index = -1;
|
||||
size_t i = 0, j = 0;
|
||||
size_t rows = 0, cols = 0;
|
||||
size_t count = browser->dir_count + browser->file_count;
|
||||
|
||||
/* File icons layout */
|
||||
cols = 2;
|
||||
rows = count / cols;
|
||||
static float ratio2[] = {0.08f, NK_UNDEFINED};
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 30, 2, ratio2);
|
||||
for (i = 0; i <= rows; i += 1) {
|
||||
size_t n = j + cols;
|
||||
for (; j < count && j < n; ++j) {
|
||||
/* draw one column of icons */
|
||||
if (j < browser->dir_count) {
|
||||
/* draw and execute directory buttons */
|
||||
if (nk_button_image(ctx,media->icons.directory))
|
||||
index = (int)j;
|
||||
|
||||
qsort(browser->directories, browser->dir_count, sizeof(char *), cmp_fn);
|
||||
nk_label(ctx, browser->directories[j], NK_TEXT_LEFT);
|
||||
} else {
|
||||
/* draw and execute files buttons */
|
||||
struct nk_image *icon;
|
||||
size_t fileIndex = ((size_t)j - browser->dir_count);
|
||||
icon = media_icon_for_file(media,browser->files[fileIndex]);
|
||||
if (nk_button_image(ctx, *icon)) {
|
||||
strncpy(browser->file, browser->directory, MAX_PATH_LEN);
|
||||
n = strlen(browser->file);
|
||||
strncpy(browser->file + n, browser->files[fileIndex], MAX_PATH_LEN - n);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
/* draw one column of labels */
|
||||
if (j >= browser->dir_count) {
|
||||
size_t t = j - browser->dir_count;
|
||||
qsort(browser->files, browser->file_count, sizeof(char *), cmp_fn);
|
||||
nk_label(ctx,browser->files[t],NK_TEXT_LEFT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index != -1) {
|
||||
size_t n = strlen(browser->directory);
|
||||
strncpy(browser->directory + n, browser->directories[index], MAX_PATH_LEN - n);
|
||||
n = strlen(browser->directory);
|
||||
if (n < MAX_PATH_LEN - 1) {
|
||||
browser->directory[n] = '/';
|
||||
browser->directory[n+1] = '\0';
|
||||
}
|
||||
file_browser_reload_directory_content(browser, browser->directory);
|
||||
}
|
||||
nk_group_end(ctx);
|
||||
}
|
||||
|
||||
nk_layout_row_dynamic(ctx, 30, 5);
|
||||
nk_label(ctx,"",NK_TEXT_LEFT);
|
||||
nk_label(ctx,"",NK_TEXT_LEFT);
|
||||
nk_label(ctx,"",NK_TEXT_LEFT);
|
||||
if(nk_button_label(ctx, "Cancel"))
|
||||
{
|
||||
fprintf(stdout, "File dialog has been closed!\n");
|
||||
file_browser_is_open = nk_false;
|
||||
}
|
||||
if(nk_button_label(ctx, "Open"))
|
||||
fprintf(stdout, "Insert routine to open/save the file!\n");
|
||||
}
|
||||
nk_end(ctx);
|
||||
}
|
||||
return ret;
|
||||
}
|
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 620 B |
After Width: | Height: | Size: 655 B |
After Width: | Height: | Size: 460 B |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 583 B |
After Width: | Height: | Size: 533 B |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 561 B |
After Width: | Height: | Size: 819 B |
After Width: | Height: | Size: 648 B |
After Width: | Height: | Size: 626 B |
After Width: | Height: | Size: 610 B |
After Width: | Height: | Size: 703 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 566 B |
After Width: | Height: | Size: 701 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 520 B |
After Width: | Height: | Size: 601 B |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 18 KiB |
|
@ -199,7 +199,7 @@ overview(struct nk_context *ctx)
|
|||
/* Basic widgets */
|
||||
static int int_slider = 5;
|
||||
static float float_slider = 2.5f;
|
||||
static size_t prog_value = 40;
|
||||
static nk_size prog_value = 40;
|
||||
static float property_float = 2;
|
||||
static int property_int = 10;
|
||||
static int property_neg = 10;
|
||||
|
@ -226,7 +226,7 @@ overview(struct nk_context *ctx)
|
|||
|
||||
nk_label(ctx, "Slider float", NK_TEXT_LEFT);
|
||||
nk_slider_float(ctx, 0, &float_slider, 5.0, 0.5f);
|
||||
nk_labelf(ctx, NK_TEXT_LEFT, "Progressbar: %zu" , prog_value);
|
||||
nk_labelf(ctx, NK_TEXT_LEFT, "Progressbar: %u" , (int)prog_value);
|
||||
nk_progress(ctx, &prog_value, 100, NK_MODIFIABLE);
|
||||
|
||||
nk_layout_row(ctx, NK_STATIC, 25, 2, ratio);
|
||||
|
@ -623,13 +623,11 @@ overview(struct nk_context *ctx)
|
|||
|
||||
int i;
|
||||
int index = -1;
|
||||
struct nk_rect bounds;
|
||||
|
||||
/* line chart */
|
||||
id = 0;
|
||||
index = -1;
|
||||
nk_layout_row_dynamic(ctx, 100, 1);
|
||||
bounds = nk_widget_bounds(ctx);
|
||||
if (nk_chart_begin(ctx, NK_CHART_LINES, 32, -1.0f, 1.0f)) {
|
||||
for (i = 0; i < 32; ++i) {
|
||||
nk_flags res = nk_chart_push(ctx, (float)cos(id));
|
||||
|
@ -651,7 +649,6 @@ overview(struct nk_context *ctx)
|
|||
|
||||
/* column chart */
|
||||
nk_layout_row_dynamic(ctx, 100, 1);
|
||||
bounds = nk_widget_bounds(ctx);
|
||||
if (nk_chart_begin(ctx, NK_CHART_COLUMN, 32, 0.0f, 1.0f)) {
|
||||
for (i = 0; i < 32; ++i) {
|
||||
nk_flags res = nk_chart_push(ctx, (float)fabs(sin(id)));
|
||||
|
@ -672,7 +669,6 @@ overview(struct nk_context *ctx)
|
|||
|
||||
/* mixed chart */
|
||||
nk_layout_row_dynamic(ctx, 100, 1);
|
||||
bounds = nk_widget_bounds(ctx);
|
||||
if (nk_chart_begin(ctx, NK_CHART_COLUMN, 32, 0.0f, 1.0f)) {
|
||||
nk_chart_add_slot(ctx, NK_CHART_LINES, 32, -1.0f, 1.0f);
|
||||
nk_chart_add_slot(ctx, NK_CHART_LINES, 32, -1.0f, 1.0f);
|
||||
|
@ -687,7 +683,6 @@ overview(struct nk_context *ctx)
|
|||
|
||||
/* mixed colored chart */
|
||||
nk_layout_row_dynamic(ctx, 100, 1);
|
||||
bounds = nk_widget_bounds(ctx);
|
||||
if (nk_chart_begin_colored(ctx, NK_CHART_LINES, nk_rgb(255,0,0), nk_rgb(150,0,0), 32, 0.0f, 1.0f)) {
|
||||
nk_chart_add_slot_colored(ctx, NK_CHART_LINES, nk_rgb(0,0,255), nk_rgb(0,0,150),32, -1.0f, 1.0f);
|
||||
nk_chart_add_slot_colored(ctx, NK_CHART_LINES, nk_rgb(0,255,0), nk_rgb(0,150,0), 32, -1.0f, 1.0f);
|
||||
|
@ -765,7 +760,7 @@ overview(struct nk_context *ctx)
|
|||
if (nk_popup_begin(ctx, NK_POPUP_STATIC, "Error", 0, s))
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
nk_label(ctx, "A terrible error as occured", NK_TEXT_LEFT);
|
||||
nk_label(ctx, "A terrible error as occurred", NK_TEXT_LEFT);
|
||||
nk_layout_row_dynamic(ctx, 25, 2);
|
||||
if (nk_button_label(ctx, "OK")) {
|
||||
popup_active = 0;
|
||||
|
@ -946,7 +941,6 @@ overview(struct nk_context *ctx)
|
|||
if (nk_tree_push(ctx, NK_TREE_NODE, "Notebook", NK_MINIMIZED))
|
||||
{
|
||||
static int current_tab = 0;
|
||||
struct nk_rect bounds;
|
||||
float step = (2*3.141592654f) / 32;
|
||||
enum chart_type {CHART_LINE, CHART_HISTO, CHART_MIXED};
|
||||
const char *names[] = {"Lines", "Columns", "Mixed"};
|
||||
|
@ -982,7 +976,6 @@ overview(struct nk_context *ctx)
|
|||
default: break;
|
||||
case CHART_LINE:
|
||||
nk_layout_row_dynamic(ctx, 100, 1);
|
||||
bounds = nk_widget_bounds(ctx);
|
||||
if (nk_chart_begin_colored(ctx, NK_CHART_LINES, nk_rgb(255,0,0), nk_rgb(150,0,0), 32, 0.0f, 1.0f)) {
|
||||
nk_chart_add_slot_colored(ctx, NK_CHART_LINES, nk_rgb(0,0,255), nk_rgb(0,0,150),32, -1.0f, 1.0f);
|
||||
for (i = 0, id = 0; i < 32; ++i) {
|
||||
|
@ -995,7 +988,6 @@ overview(struct nk_context *ctx)
|
|||
break;
|
||||
case CHART_HISTO:
|
||||
nk_layout_row_dynamic(ctx, 100, 1);
|
||||
bounds = nk_widget_bounds(ctx);
|
||||
if (nk_chart_begin_colored(ctx, NK_CHART_COLUMN, nk_rgb(255,0,0), nk_rgb(150,0,0), 32, 0.0f, 1.0f)) {
|
||||
for (i = 0, id = 0; i < 32; ++i) {
|
||||
nk_chart_push_slot(ctx, (float)fabs(sin(id)), 0);
|
||||
|
@ -1006,7 +998,6 @@ overview(struct nk_context *ctx)
|
|||
break;
|
||||
case CHART_MIXED:
|
||||
nk_layout_row_dynamic(ctx, 100, 1);
|
||||
bounds = nk_widget_bounds(ctx);
|
||||
if (nk_chart_begin_colored(ctx, NK_CHART_LINES, nk_rgb(255,0,0), nk_rgb(150,0,0), 32, 0.0f, 1.0f)) {
|
||||
nk_chart_add_slot_colored(ctx, NK_CHART_LINES, nk_rgb(0,0,255), nk_rgb(0,0,150),32, -1.0f, 1.0f);
|
||||
nk_chart_add_slot_colored(ctx, NK_CHART_COLUMN, nk_rgb(0,255,0), nk_rgb(0,150,0), 32, 0.0f, 1.0f);
|
|
@ -36,27 +36,32 @@
|
|||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -205,10 +210,16 @@ int main(void)
|
|||
|
||||
/* style.c */
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
|
||||
|
@ -264,6 +275,9 @@ int main(void)
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
|
|
@ -61,7 +61,7 @@ static struct
|
|||
struct nk_font_atlas atlas;
|
||||
struct nk_buffer cmds;
|
||||
|
||||
struct nk_draw_null_texture null;
|
||||
struct nk_draw_null_texture tex_null;
|
||||
unsigned int max_vertex_buffer;
|
||||
unsigned int max_index_buffer;
|
||||
|
||||
|
@ -137,7 +137,7 @@ nk_d3d11_render(ID3D11DeviceContext *context, enum nk_anti_aliasing AA)
|
|||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
config.null = d3d11.null;
|
||||
config.tex_null = d3d11.tex_null;
|
||||
|
||||
{/* setup buffers to load vertices and elements */
|
||||
struct nk_buffer vbuf, ibuf;
|
||||
|
@ -179,11 +179,15 @@ nk_d3d11_get_projection_matrix(int width, int height, float *result)
|
|||
const float B = (float)height;
|
||||
float matrix[4][4] =
|
||||
{
|
||||
{ 2.0f / (R - L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f / (T - B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||
{ (R + L) / (L - R), (T + B) / (B - T), 0.5f, 1.0f },
|
||||
{ 0.0f, 0.0f, 0.5f, 1.0f },
|
||||
};
|
||||
matrix[0][0] = 2.0f / (R - L);
|
||||
matrix[1][1] = 2.0f / (T - B);
|
||||
matrix[3][0] = (R + L) / (L - R);
|
||||
matrix[3][1] = (T + B) / (B - T);
|
||||
memcpy(result, matrix, sizeof(matrix));
|
||||
}
|
||||
|
||||
|
@ -599,7 +603,7 @@ nk_d3d11_font_stash_end(void)
|
|||
assert(SUCCEEDED(hr));}
|
||||
ID3D11Texture2D_Release(font_texture);}
|
||||
|
||||
nk_font_atlas_end(&d3d11.atlas, nk_handle_ptr(d3d11.font_texture_view), &d3d11.null);
|
||||
nk_font_atlas_end(&d3d11.atlas, nk_handle_ptr(d3d11.font_texture_view), &d3d11.tex_null);
|
||||
if (d3d11.atlas.default_font)
|
||||
nk_style_set_font(&d3d11.ctx, &d3d11.atlas.default_font->handle);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
@echo off
|
||||
|
||||
rem This will use VS2015 for compiler... if you have vs 2015 and it is installed at this / the default path
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86
|
||||
|
||||
fxc.exe /nologo /T vs_5_1 /E vs /O3 /Zpc /Ges /Fh nuklear_d3d12_vertex_shader.h /Vn nk_d3d12_vertex_shader /Qstrip_reflect /Qstrip_debug /Qstrip_priv nuklear_d3d12.hlsl
|
||||
fxc.exe /nologo /T ps_5_1 /E ps /O3 /Zpc /Ges /Fh nuklear_d3d12_pixel_shader.h /Vn nk_d3d12_pixel_shader /Qstrip_reflect /Qstrip_debug /Qstrip_priv /enable_unbounded_descriptor_tables nuklear_d3d12.hlsl
|
||||
|
||||
cl /D_CRT_SECURE_NO_DEPRECATE /nologo /W3 /O2 /fp:fast /Gm- /Fedemo.exe main.c user32.lib dxguid.lib dxgi.lib d3d12.lib /link /incremental:no
|
|
@ -0,0 +1,445 @@
|
|||
/* nuklear - 1.32.0 - public domain */
|
||||
#define COBJMACROS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <combaseapi.h>
|
||||
#include <dxgi1_6.h>
|
||||
#include <d3d12.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
#define USER_TEXTURES 6
|
||||
|
||||
#define MAX_VERTEX_BUFFER 512 * 1024
|
||||
#define MAX_INDEX_BUFFER 128 * 1024
|
||||
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_STANDARD_VARARGS
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||
#define NK_INCLUDE_FONT_BAKING
|
||||
#define NK_INCLUDE_DEFAULT_FONT
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_D3D12_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include "nuklear_d3d12.h"
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* ===============================================================*/
|
||||
/* This are some code examples to provide a small overview of what can be
|
||||
* done with this library. To try out an example uncomment the defines */
|
||||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* DEMO
|
||||
*
|
||||
* ===============================================================*/
|
||||
/* DXGI & Window related device objects */
|
||||
static IDXGIFactory2 *dxgi_factory;
|
||||
static IDXGISwapChain1 *swap_chain;
|
||||
static ID3D12DescriptorHeap *rtv_descriptor_heap;
|
||||
static D3D12_CPU_DESCRIPTOR_HANDLE rtv_handles[2];
|
||||
static ID3D12Resource *rtv_buffers[2];
|
||||
static UINT rtv_desc_increment;
|
||||
static UINT rtv_index;
|
||||
/* DirectX common device objects */
|
||||
static ID3D12Device *device;
|
||||
static ID3D12CommandQueue *command_queue;
|
||||
static ID3D12Fence *queue_fence;
|
||||
static UINT64 fence_value;
|
||||
static ID3D12CommandAllocator *command_allocator;
|
||||
static ID3D12GraphicsCommandList *command_list;
|
||||
|
||||
static void signal_and_wait()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
/* Signal fence when execution finishes */
|
||||
hr = ID3D12CommandQueue_Signal(command_queue, queue_fence, ++fence_value);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
/* Wait for queue to finish */
|
||||
while(ID3D12Fence_GetCompletedValue(queue_fence) != fence_value)
|
||||
{
|
||||
SwitchToThread(); /* Allow windows to do other work */
|
||||
}
|
||||
}
|
||||
|
||||
static void execute_commands()
|
||||
{
|
||||
/* Prepare command list for execution */
|
||||
ID3D12GraphicsCommandList_Close(command_list);
|
||||
|
||||
/* Execute on command queue */
|
||||
ID3D12CommandList* cmd_lists[] = { (ID3D12CommandList*)command_list};
|
||||
ID3D12CommandQueue_ExecuteCommandLists(command_queue, 1, cmd_lists);
|
||||
|
||||
/* Wait for execution */
|
||||
signal_and_wait();
|
||||
|
||||
/* Reset command allocator and list */
|
||||
ID3D12CommandAllocator_Reset(command_allocator);
|
||||
ID3D12GraphicsCommandList_Reset(command_list, command_allocator, NULL);
|
||||
}
|
||||
|
||||
static void get_swap_chain_buffers()
|
||||
{
|
||||
HRESULT hr;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE descriptor_handle;
|
||||
|
||||
/* Get resource objects from swap chain */
|
||||
hr = IDXGISwapChain1_GetBuffer(swap_chain, 0, &IID_ID3D12Resource, &rtv_buffers[0]);
|
||||
assert(SUCCEEDED(hr));
|
||||
hr = IDXGISwapChain1_GetBuffer(swap_chain, 1, &IID_ID3D12Resource, &rtv_buffers[1]);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
/* Recreate render target views */
|
||||
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rtv_descriptor_heap, &descriptor_handle);
|
||||
ID3D12Device_CreateRenderTargetView(device, rtv_buffers[0], NULL, descriptor_handle);
|
||||
rtv_handles[0] = descriptor_handle;
|
||||
descriptor_handle.ptr += rtv_desc_increment;
|
||||
ID3D12Device_CreateRenderTargetView(device, rtv_buffers[1], NULL, descriptor_handle);
|
||||
rtv_handles[1] = descriptor_handle;
|
||||
}
|
||||
|
||||
static void
|
||||
set_swap_chain_size(int width, int height)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
/* Wait for pending work */
|
||||
signal_and_wait();
|
||||
signal_and_wait(); /* Two times because we have two buffers in flight */
|
||||
|
||||
/* Release all open refereces to the buffers */
|
||||
ID3D12Resource_Release(rtv_buffers[0]);
|
||||
ID3D12Resource_Release(rtv_buffers[1]);
|
||||
|
||||
/* DXGI can now perform resizing */
|
||||
hr = IDXGISwapChain1_ResizeBuffers(swap_chain, 2, width, height, DXGI_FORMAT_UNKNOWN, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
/* Get references for the new resized buffers */
|
||||
get_swap_chain_buffers();
|
||||
|
||||
/* Reset RTV index */
|
||||
rtv_index = 0;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK
|
||||
WindowProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
|
||||
case WM_SIZE:
|
||||
if (swap_chain)
|
||||
{
|
||||
int width = LOWORD(lparam);
|
||||
int height = HIWORD(lparam);
|
||||
set_swap_chain_size(width, height);
|
||||
nk_d3d12_resize(width, height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (nk_d3d12_handle_event(wnd, msg, wparam, lparam))
|
||||
return 0;
|
||||
|
||||
return DefWindowProcW(wnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct nk_context *ctx;
|
||||
struct nk_colorf bg;
|
||||
|
||||
WNDCLASSW wc;
|
||||
RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
|
||||
DWORD style = WS_OVERLAPPEDWINDOW;
|
||||
DWORD exstyle = WS_EX_APPWINDOW;
|
||||
HWND wnd;
|
||||
int running = 1;
|
||||
HRESULT hr;
|
||||
|
||||
D3D12_COMMAND_QUEUE_DESC command_queue_desc;
|
||||
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc;
|
||||
D3D12_DESCRIPTOR_HEAP_DESC rtv_desc_heap_desc;
|
||||
|
||||
/* Win32 */
|
||||
memset(&wc, 0, sizeof(wc));
|
||||
wc.style = CS_DBLCLKS;
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = GetModuleHandleW(0);
|
||||
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.lpszClassName = L"NuklearWindowClass";
|
||||
RegisterClassW(&wc);
|
||||
|
||||
AdjustWindowRectEx(&rect, style, FALSE, exstyle);
|
||||
|
||||
wnd = CreateWindowExW(exstyle, wc.lpszClassName, L"Nuklear Demo",
|
||||
style | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
rect.right - rect.left, rect.bottom - rect.top,
|
||||
NULL, NULL, wc.hInstance, NULL);
|
||||
|
||||
/* D3D12 setup */
|
||||
/* Create default Device */
|
||||
hr = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, &device);
|
||||
assert(SUCCEEDED(hr));
|
||||
/* Create a command queue */
|
||||
command_queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
command_queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
|
||||
command_queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
command_queue_desc.NodeMask = 0;
|
||||
hr = ID3D12Device_CreateCommandQueue(device, &command_queue_desc, &IID_ID3D12CommandQueue, &command_queue);
|
||||
assert(SUCCEEDED(hr));
|
||||
/* Create a fence for command queue executions */
|
||||
fence_value = 0;
|
||||
hr = ID3D12Device_CreateFence(device, fence_value, D3D12_FENCE_FLAG_NONE, &IID_ID3D12Fence, &queue_fence);
|
||||
assert(SUCCEEDED(hr));
|
||||
/* Create a command allocator */
|
||||
hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT, &IID_ID3D12CommandAllocator, &command_allocator);
|
||||
assert(SUCCEEDED(hr));
|
||||
/* Create a command list that will use our allocator */
|
||||
hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, command_allocator, NULL, &IID_ID3D12GraphicsCommandList1, &command_list);
|
||||
assert(SUCCEEDED(hr));
|
||||
|
||||
/* DXGI Setup (Swap chain & resources) */
|
||||
/* Create a descriptor heap for the back buffers */
|
||||
rtv_desc_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
rtv_desc_heap_desc.NumDescriptors = 2;
|
||||
rtv_desc_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
rtv_desc_heap_desc.NodeMask = 0;
|
||||
hr = ID3D12Device_CreateDescriptorHeap(device, &rtv_desc_heap_desc, &IID_ID3D12DescriptorHeap, &rtv_descriptor_heap);
|
||||
assert(SUCCEEDED(hr));
|
||||
/* Get descriptor increment */
|
||||
rtv_desc_increment = ID3D12Device_GetDescriptorHandleIncrementSize(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||
/* Get the DXGI factory */
|
||||
hr = CreateDXGIFactory1(&IID_IDXGIFactory2, &dxgi_factory);
|
||||
assert(SUCCEEDED(hr));
|
||||
/* Create the swap chain */
|
||||
swap_chain_desc.Width = WINDOW_WIDTH;
|
||||
swap_chain_desc.Height = WINDOW_HEIGHT;
|
||||
swap_chain_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
swap_chain_desc.Stereo = 0;
|
||||
swap_chain_desc.SampleDesc.Count = 1;
|
||||
swap_chain_desc.SampleDesc.Quality = 0;
|
||||
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swap_chain_desc.BufferCount = 2;
|
||||
swap_chain_desc.Scaling = DXGI_SCALING_STRETCH;
|
||||
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL ;
|
||||
swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
|
||||
swap_chain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
hr = IDXGIFactory2_CreateSwapChainForHwnd(dxgi_factory, (IUnknown*)command_queue, wnd, &swap_chain_desc, NULL, NULL, &swap_chain);
|
||||
assert(SUCCEEDED(hr));
|
||||
get_swap_chain_buffers();
|
||||
|
||||
/* GUI */
|
||||
ctx = nk_d3d12_init(device, WINDOW_WIDTH, WINDOW_HEIGHT, MAX_VERTEX_BUFFER, MAX_INDEX_BUFFER, USER_TEXTURES);
|
||||
|
||||
/* Load Fonts: if none of these are loaded a default font will be used */
|
||||
/* Load Cursor: if you uncomment cursor loading please hide the cursor */
|
||||
{
|
||||
struct nk_font_atlas *atlas;
|
||||
nk_d3d12_font_stash_begin(&atlas);
|
||||
/*struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "../../extra_font/DroidSans.ttf", 14, 0);*/
|
||||
/*struct nk_font *robot = nk_font_atlas_add_from_file(atlas, "../../extra_font/Roboto-Regular.ttf", 14, 0);*/
|
||||
/*struct nk_font *future = nk_font_atlas_add_from_file(atlas, "../../extra_font/kenvector_future_thin.ttf", 13, 0);*/
|
||||
/*struct nk_font *clean = nk_font_atlas_add_from_file(atlas, "../../extra_font/ProggyClean.ttf", 12, 0);*/
|
||||
/*struct nk_font *tiny = nk_font_atlas_add_from_file(atlas, "../../extra_font/ProggyTiny.ttf", 10, 0);*/
|
||||
/*struct nk_font *cousine = nk_font_atlas_add_from_file(atlas, "../../extra_font/Cousine-Regular.ttf", 13, 0);*/
|
||||
nk_d3d12_font_stash_end(command_list);
|
||||
/*nk_style_load_all_cursors(ctx, atlas->cursors);*/
|
||||
/*nk_style_set_font(ctx, &droid->handle)*/;
|
||||
}
|
||||
|
||||
/* Execute the command list to make sure all texture (font) data has been uploaded */
|
||||
execute_commands();
|
||||
/* Now we can cleanup all resources consumed by font stashing that are no longer used */
|
||||
nk_d3d12_font_stash_cleanup();
|
||||
|
||||
/* style.c */
|
||||
#ifdef INCLUDE_STYLE
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
|
||||
while (running)
|
||||
{
|
||||
/* Input */
|
||||
MSG msg;
|
||||
nk_input_begin(ctx);
|
||||
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.message == WM_QUIT)
|
||||
running = 0;
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
nk_input_end(ctx);
|
||||
|
||||
/* GUI */
|
||||
if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250),
|
||||
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
|
||||
NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
|
||||
{
|
||||
enum {EASY, HARD};
|
||||
static int op = EASY;
|
||||
static int property = 20;
|
||||
|
||||
nk_layout_row_static(ctx, 30, 80, 1);
|
||||
if (nk_button_label(ctx, "button"))
|
||||
fprintf(stdout, "button pressed\n");
|
||||
nk_layout_row_dynamic(ctx, 30, 2);
|
||||
if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
|
||||
if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;
|
||||
nk_layout_row_dynamic(ctx, 22, 1);
|
||||
nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 20, 1);
|
||||
nk_label(ctx, "background:", NK_TEXT_LEFT);
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
if (nk_combo_begin_color(ctx, nk_rgb_cf(bg), nk_vec2(nk_widget_width(ctx),400))) {
|
||||
nk_layout_row_dynamic(ctx, 120, 1);
|
||||
bg = nk_color_picker(ctx, bg, NK_RGBA);
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
bg.r = nk_propertyf(ctx, "#R:", 0, bg.r, 1.0f, 0.01f,0.005f);
|
||||
bg.g = nk_propertyf(ctx, "#G:", 0, bg.g, 1.0f, 0.01f,0.005f);
|
||||
bg.b = nk_propertyf(ctx, "#B:", 0, bg.b, 1.0f, 0.01f,0.005f);
|
||||
bg.a = nk_propertyf(ctx, "#A:", 0, bg.a, 1.0f, 0.01f,0.005f);
|
||||
nk_combo_end(ctx);
|
||||
}
|
||||
}
|
||||
nk_end(ctx);
|
||||
|
||||
/* -------------- EXAMPLES ---------------- */
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
node_editor(ctx);
|
||||
#endif
|
||||
/* ----------------------------------------- */
|
||||
|
||||
/* Set rtv resource state */
|
||||
D3D12_RESOURCE_BARRIER resource_barrier;
|
||||
resource_barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
resource_barrier.Transition.pResource = rtv_buffers[rtv_index];
|
||||
resource_barrier.Transition.Subresource = 0;
|
||||
resource_barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
||||
resource_barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
resource_barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
ID3D12GraphicsCommandList_ResourceBarrier(command_list, 1, &resource_barrier);
|
||||
|
||||
/* Clear and set the rtv */
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handles[rtv_index], &bg.r, 0, NULL);
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtv_handles[rtv_index], FALSE, NULL);
|
||||
|
||||
/* Draw */
|
||||
nk_d3d12_render(command_list, NK_ANTI_ALIASING_ON);
|
||||
|
||||
/* Bring the rtv resource back to present state */
|
||||
resource_barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
resource_barrier.Transition.pResource = rtv_buffers[rtv_index];
|
||||
resource_barrier.Transition.Subresource = 0;
|
||||
resource_barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
resource_barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
||||
resource_barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
ID3D12GraphicsCommandList_ResourceBarrier(command_list, 1, &resource_barrier);
|
||||
|
||||
/* Execute command list and wait */
|
||||
execute_commands();
|
||||
|
||||
/* Present frame */
|
||||
hr = IDXGISwapChain2_Present(swap_chain, 1, 0);
|
||||
rtv_index = (rtv_index + 1) % 2;
|
||||
if (hr == DXGI_ERROR_DEVICE_RESET || hr == DXGI_ERROR_DEVICE_REMOVED) {
|
||||
/* to recover from this, you'll need to recreate device and all the resources */
|
||||
MessageBoxW(NULL, L"D3D12 device is lost or removed!", L"Error", 0);
|
||||
break;
|
||||
} else if (hr == DXGI_STATUS_OCCLUDED) {
|
||||
/* window is not visible, so vsync won't work. Let's sleep a bit to reduce CPU usage */
|
||||
Sleep(10);
|
||||
}
|
||||
assert(SUCCEEDED(hr));
|
||||
}
|
||||
|
||||
/* Nuklear shutdown */
|
||||
nk_d3d12_shutdown();
|
||||
|
||||
/* D3D12 and DXGI shutdown */
|
||||
signal_and_wait();
|
||||
signal_and_wait(); /* Two times because we have two buffers in flight */
|
||||
ID3D12Resource_Release(rtv_buffers[0]);
|
||||
ID3D12Resource_Release(rtv_buffers[1]);
|
||||
ID3D12DescriptorHeap_Release(rtv_descriptor_heap);
|
||||
IDXGISwapChain1_Release(swap_chain);
|
||||
IDXGIFactory2_Release(dxgi_factory);
|
||||
ID3D12GraphicsCommandList_Release(command_list);
|
||||
ID3D12CommandAllocator_Release(command_allocator);
|
||||
ID3D12CommandQueue_Release(command_queue);
|
||||
ID3D12Fence_Release(queue_fence);
|
||||
ID3D12Device_Release(device);
|
||||
|
||||
/* win32 shutdown */
|
||||
UnregisterClassW(wc.lpszClassName, wc.hInstance);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,928 @@
|
|||
/*
|
||||
* Nuklear - 1.32.0 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2016 by Micha Mettke
|
||||
*
|
||||
* D3D12 backend created by Ludwig Fuechsl (2022)
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_D3D12_H_
|
||||
#define NK_D3D12_H_
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
/*
|
||||
* USAGE:
|
||||
* - This function will initialize a new nuklear rendering context. The context will be bound to a GLOBAL DirectX 12 rendering state.
|
||||
*/
|
||||
NK_API struct nk_context *nk_d3d12_init(ID3D12Device *device, int width, int height, unsigned int max_vertex_buffer, unsigned int max_index_buffer, unsigned int max_user_textures);
|
||||
/*
|
||||
* USAGE:
|
||||
* - A call to this function prepares the global nuklear d3d12 backend for receiving font information’s. Use the obtained atlas pointer to load all required fonts and do all required font setup.
|
||||
*/
|
||||
NK_API void nk_d3d12_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
/*
|
||||
* USAGE:
|
||||
* - Call this function after a call to nk_d3d12_font_stash_begin(...) when all fonts have been loaded and configured.
|
||||
* - This function will place commands on the supplied ID3D12GraphicsCommandList.
|
||||
* - This function will allocate temporary data that is required until the command list has finish executing. The temporary data can be free by calling nk_d3d12_font_stash_cleanup(...)
|
||||
*/
|
||||
NK_API void nk_d3d12_font_stash_end(ID3D12GraphicsCommandList *command_list);
|
||||
/*
|
||||
* USAGE:
|
||||
* - This function will free temporary data that was allocated by nk_d3d12_font_stash_begin(...)
|
||||
* - Only call this function after the command list used in the nk_d3d12_font_stash_begin(...) function call has finished executing.
|
||||
* - It is NOT required to call this function but highly recommended.
|
||||
*/
|
||||
NK_API void nk_d3d12_font_stash_cleanup();
|
||||
/*
|
||||
* USAGE:
|
||||
* - This function will setup the supplied texture (ID3D12Resource) for rendering custom images using the supplied D3D12_SHADER_RESOURCE_VIEW_DESC.
|
||||
* - This function may override any previous calls to nk_d3d12_set_user_texture(...) while using the same index.
|
||||
* - The returned handle can be used as texture handle to render custom images.
|
||||
* - The caller must keep track of the state of the texture when it comes to rendering with nk_d3d12_render(...).
|
||||
*/
|
||||
NK_API nk_bool nk_d3d12_set_user_texture(unsigned int index, ID3D12Resource* texture, const D3D12_SHADER_RESOURCE_VIEW_DESC* description, nk_handle* handle_out);
|
||||
/*
|
||||
* USAGE:
|
||||
* - This function should be called within the user window proc to allow nuklear to listen to window events
|
||||
*/
|
||||
NK_API int nk_d3d12_handle_event(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
/*
|
||||
* USAGE:
|
||||
* - A call to this function renders any previous placed nuklear draw calls and will flush all nuklear buffers for the next frame
|
||||
* - This function will place commands on the supplied ID3D12GraphicsCommandList.
|
||||
* - When using custom images for rendering make sure they are in the correct resource state (D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) when calling this function.
|
||||
* - This function will upload data to the gpu (64 + max_vertex_buffer + max_index_buffer BYTES).
|
||||
*/
|
||||
NK_API void nk_d3d12_render(ID3D12GraphicsCommandList *command_list, enum nk_anti_aliasing AA);
|
||||
/*
|
||||
* USAGE:
|
||||
* - This function will notify nuklear that the framebuffer dimensions have changed.
|
||||
*/
|
||||
NK_API void nk_d3d12_resize(int width, int height);
|
||||
/*
|
||||
* USAGE:
|
||||
* - This function will free the global d3d12 rendering state.
|
||||
*/
|
||||
NK_API void nk_d3d12_shutdown(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_D3D12_IMPLEMENTATION
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define COBJMACROS
|
||||
#include <d3d12.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "nuklear_d3d12_vertex_shader.h"
|
||||
#include "nuklear_d3d12_pixel_shader.h"
|
||||
|
||||
struct nk_d3d12_vertex
|
||||
{
|
||||
float position[2];
|
||||
float uv[2];
|
||||
nk_byte col[4];
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
struct nk_context ctx;
|
||||
struct nk_font_atlas atlas;
|
||||
struct nk_buffer cmds;
|
||||
|
||||
struct nk_draw_null_texture tex_null;
|
||||
unsigned int max_vertex_buffer;
|
||||
unsigned int max_index_buffer;
|
||||
unsigned int max_user_textures;
|
||||
|
||||
D3D12_HEAP_PROPERTIES heap_prop_default;
|
||||
D3D12_HEAP_PROPERTIES heap_prop_upload;
|
||||
|
||||
UINT cbv_srv_uav_desc_increment;
|
||||
|
||||
D3D12_VIEWPORT viewport;
|
||||
ID3D12Device *device;
|
||||
ID3D12RootSignature *root_signature;
|
||||
ID3D12PipelineState *pipeline_state;
|
||||
ID3D12DescriptorHeap *desc_heap;
|
||||
ID3D12Resource *font_texture;
|
||||
ID3D12Resource *font_upload_buffer;
|
||||
ID3D12Resource *upload_buffer;
|
||||
ID3D12Resource *const_buffer;
|
||||
ID3D12Resource *index_buffer;
|
||||
ID3D12Resource *vertex_buffer;
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE cpu_descriptor_handle;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE gpu_descriptor_handle;
|
||||
D3D12_GPU_VIRTUAL_ADDRESS gpu_vertex_buffer_address;
|
||||
D3D12_GPU_VIRTUAL_ADDRESS gpu_index_buffer_address;
|
||||
} d3d12;
|
||||
|
||||
NK_API void
|
||||
nk_d3d12_render(ID3D12GraphicsCommandList *command_list, enum nk_anti_aliasing AA)
|
||||
{
|
||||
HRESULT hr;
|
||||
#ifdef NK_UINT_DRAW_INDEX
|
||||
DXGI_FORMAT index_buffer_format = DXGI_FORMAT_R32_UINT;
|
||||
#else
|
||||
DXGI_FORMAT index_buffer_format = DXGI_FORMAT_R16_UINT;
|
||||
#endif
|
||||
const UINT stride = sizeof(struct nk_d3d12_vertex);
|
||||
const struct nk_draw_command *cmd;
|
||||
UINT offset = 0;
|
||||
D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view;
|
||||
D3D12_INDEX_BUFFER_VIEW index_buffer_view;
|
||||
unsigned char* ptr_data;
|
||||
D3D12_RANGE map_range;
|
||||
D3D12_RESOURCE_BARRIER resource_barriers[3];
|
||||
|
||||
/* Activate D3D12 pipeline state and config root signature */
|
||||
ID3D12GraphicsCommandList_SetPipelineState(command_list, d3d12.pipeline_state);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, d3d12.root_signature);
|
||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &d3d12.desc_heap);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, d3d12.gpu_descriptor_handle);
|
||||
|
||||
/* Configure rendering pipeline */
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
vertex_buffer_view.BufferLocation = d3d12.gpu_vertex_buffer_address;
|
||||
vertex_buffer_view.SizeInBytes = d3d12.max_vertex_buffer;
|
||||
vertex_buffer_view.StrideInBytes = stride;
|
||||
ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vertex_buffer_view);
|
||||
index_buffer_view.BufferLocation = d3d12.gpu_index_buffer_address;
|
||||
index_buffer_view.Format = index_buffer_format;
|
||||
index_buffer_view.SizeInBytes = d3d12.max_index_buffer;
|
||||
ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, &index_buffer_view);
|
||||
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &d3d12.viewport);
|
||||
|
||||
/* Map upload buffer to cpu accessible pointer */
|
||||
map_range.Begin = sizeof(float) * 4 * 4;
|
||||
map_range.End = map_range.Begin + d3d12.max_vertex_buffer + d3d12.max_index_buffer;
|
||||
hr = ID3D12Resource_Map(d3d12.upload_buffer, 0, &map_range, &ptr_data);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
/* Nuklear convert and copy to upload buffer */
|
||||
{
|
||||
struct nk_convert_config config;
|
||||
NK_STORAGE const struct nk_draw_vertex_layout_element vertex_layout[] = {
|
||||
{NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_d3d12_vertex, position)},
|
||||
{NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_d3d12_vertex, uv)},
|
||||
{NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_d3d12_vertex, col)},
|
||||
{NK_VERTEX_LAYOUT_END}
|
||||
};
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_d3d12_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_d3d12_vertex);
|
||||
config.global_alpha = 1.0f;
|
||||
config.shape_AA = AA;
|
||||
config.line_AA = AA;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
config.tex_null = d3d12.tex_null;
|
||||
|
||||
struct nk_buffer vbuf, ibuf;
|
||||
nk_buffer_init_fixed(&vbuf, &ptr_data[sizeof(float) * 4 * 4], (size_t)d3d12.max_vertex_buffer);
|
||||
nk_buffer_init_fixed(&ibuf, &ptr_data[sizeof(float) * 4 * 4 + d3d12.max_vertex_buffer], (size_t)d3d12.max_index_buffer);
|
||||
nk_convert(&d3d12.ctx, &d3d12.cmds, &vbuf, &ibuf, &config);
|
||||
}
|
||||
|
||||
/* Close mapping range */
|
||||
ID3D12Resource_Unmap(d3d12.upload_buffer, 0, &map_range);
|
||||
|
||||
/* Issue GPU resource change for copying */
|
||||
resource_barriers[0].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
resource_barriers[0].Transition.pResource = d3d12.const_buffer;
|
||||
resource_barriers[0].Transition.Subresource = 0;
|
||||
resource_barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
|
||||
resource_barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
resource_barriers[0].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
resource_barriers[1].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
resource_barriers[1].Transition.pResource = d3d12.vertex_buffer;
|
||||
resource_barriers[1].Transition.Subresource = 0;
|
||||
resource_barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
|
||||
resource_barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
resource_barriers[1].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
resource_barriers[2].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
resource_barriers[2].Transition.pResource = d3d12.index_buffer;
|
||||
resource_barriers[2].Transition.Subresource = 0;
|
||||
resource_barriers[2].Transition.StateBefore = D3D12_RESOURCE_STATE_INDEX_BUFFER;
|
||||
resource_barriers[2].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
resource_barriers[2].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
ID3D12GraphicsCommandList_ResourceBarrier(command_list, 3, resource_barriers);
|
||||
|
||||
/* Copy from upload buffer to gpu buffers */
|
||||
ID3D12GraphicsCommandList_CopyBufferRegion(command_list, d3d12.const_buffer, 0, d3d12.upload_buffer, 0, sizeof(float) * 4 * 4);
|
||||
ID3D12GraphicsCommandList_CopyBufferRegion(command_list, d3d12.vertex_buffer, 0, d3d12.upload_buffer, sizeof(float) * 4 * 4, d3d12.max_vertex_buffer);
|
||||
ID3D12GraphicsCommandList_CopyBufferRegion(command_list, d3d12.index_buffer, 0, d3d12.upload_buffer, sizeof(float) * 4 * 4 + d3d12.max_vertex_buffer, d3d12.max_index_buffer);
|
||||
|
||||
/* Issue GPU resource change for rendering */
|
||||
resource_barriers[0].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
resource_barriers[0].Transition.pResource = d3d12.const_buffer;
|
||||
resource_barriers[0].Transition.Subresource = 0;
|
||||
resource_barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
resource_barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
|
||||
resource_barriers[0].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
resource_barriers[1].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
resource_barriers[1].Transition.pResource = d3d12.vertex_buffer;
|
||||
resource_barriers[1].Transition.Subresource = 0;
|
||||
resource_barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
resource_barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
|
||||
resource_barriers[1].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
resource_barriers[2].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
resource_barriers[2].Transition.pResource = d3d12.index_buffer;
|
||||
resource_barriers[2].Transition.Subresource = 0;
|
||||
resource_barriers[2].Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
resource_barriers[2].Transition.StateAfter = D3D12_RESOURCE_STATE_INDEX_BUFFER;
|
||||
resource_barriers[2].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
ID3D12GraphicsCommandList_ResourceBarrier(command_list, 3, resource_barriers);
|
||||
|
||||
/* Issue draw commands */
|
||||
nk_draw_foreach(cmd, &d3d12.ctx, &d3d12.cmds)
|
||||
{
|
||||
D3D12_RECT scissor;
|
||||
UINT32 texture_id;
|
||||
|
||||
/* Only place a drawcall in case the command contains drawable data */
|
||||
if(cmd->elem_count)
|
||||
{
|
||||
/* Setup scissor rect */
|
||||
scissor.left = (LONG)cmd->clip_rect.x;
|
||||
scissor.right = (LONG)(cmd->clip_rect.x + cmd->clip_rect.w);
|
||||
scissor.top = (LONG)cmd->clip_rect.y;
|
||||
scissor.bottom = (LONG)(cmd->clip_rect.y + cmd->clip_rect.h);
|
||||
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &scissor);
|
||||
|
||||
/* Setup texture (index to descriptor heap table) to use for draw call */
|
||||
texture_id = (UINT32)cmd->texture.id;
|
||||
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 1, &texture_id, 0);
|
||||
|
||||
/* Dispatch draw call */
|
||||
ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, (UINT)cmd->elem_count, 1, offset, 0, 0);
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
}
|
||||
|
||||
/* Default nuklear context and command buffer clear */
|
||||
nk_clear(&d3d12.ctx);
|
||||
nk_buffer_clear(&d3d12.cmds);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_d3d12_get_projection_matrix(int width, int height, float *result)
|
||||
{
|
||||
const float L = 0.0f;
|
||||
const float R = (float)width;
|
||||
const float T = 0.0f;
|
||||
const float B = (float)height;
|
||||
float matrix[4][4] =
|
||||
{
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.5f, 1.0f },
|
||||
};
|
||||
matrix[0][0] = 2.0f / (R - L);
|
||||
matrix[1][1] = 2.0f / (T - B);
|
||||
matrix[3][0] = (R + L) / (L - R);
|
||||
matrix[3][1] = (T + B) / (B - T);
|
||||
memcpy(result, matrix, sizeof(matrix));
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_d3d12_resize(int width, int height)
|
||||
{
|
||||
D3D12_RANGE map_range;
|
||||
void* ptr_data;
|
||||
|
||||
/* Describe area to be mapped (the upload buffer region where the constant buffer / projection matrix) lives */
|
||||
map_range.Begin = 0;
|
||||
map_range.End = sizeof(float) * 4 * 4;
|
||||
|
||||
/* Map area to cpu accassible pointer (from upload buffer) */
|
||||
if (SUCCEEDED(ID3D12Resource_Map(d3d12.upload_buffer, 0, &map_range, &ptr_data)))
|
||||
{
|
||||
/* Compute projection matrix into upload buffer */
|
||||
nk_d3d12_get_projection_matrix(width, height, (float*)ptr_data);
|
||||
ID3D12Resource_Unmap(d3d12.upload_buffer, 0, &map_range);
|
||||
|
||||
/* Update internal viewport state to relect resize changes */
|
||||
d3d12.viewport.Width = (float)width;
|
||||
d3d12.viewport.Height = (float)height;
|
||||
}
|
||||
|
||||
/*
|
||||
NOTE:
|
||||
When mapping and copying succeeds, the data will still be in CPU sided memory
|
||||
copying to the GPU is done in the nk_d3d12_render function
|
||||
*/
|
||||
}
|
||||
|
||||
NK_API int
|
||||
nk_d3d12_handle_event(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
int down = !((lparam >> 31) & 1);
|
||||
int ctrl = GetKeyState(VK_CONTROL) & (1 << 15);
|
||||
|
||||
switch (wparam)
|
||||
{
|
||||
case VK_SHIFT:
|
||||
case VK_LSHIFT:
|
||||
case VK_RSHIFT:
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_SHIFT, down);
|
||||
return 1;
|
||||
|
||||
case VK_DELETE:
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_DEL, down);
|
||||
return 1;
|
||||
|
||||
case VK_RETURN:
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_ENTER, down);
|
||||
return 1;
|
||||
|
||||
case VK_TAB:
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_TAB, down);
|
||||
return 1;
|
||||
|
||||
case VK_LEFT:
|
||||
if (ctrl)
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_LEFT, down);
|
||||
return 1;
|
||||
|
||||
case VK_RIGHT:
|
||||
if (ctrl)
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_RIGHT, down);
|
||||
return 1;
|
||||
|
||||
case VK_BACK:
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_BACKSPACE, down);
|
||||
return 1;
|
||||
|
||||
case VK_HOME:
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_TEXT_START, down);
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_SCROLL_START, down);
|
||||
return 1;
|
||||
|
||||
case VK_END:
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_TEXT_END, down);
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_SCROLL_END, down);
|
||||
return 1;
|
||||
|
||||
case VK_NEXT:
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_SCROLL_DOWN, down);
|
||||
return 1;
|
||||
|
||||
case VK_PRIOR:
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_SCROLL_UP, down);
|
||||
return 1;
|
||||
|
||||
case 'C':
|
||||
if (ctrl) {
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_COPY, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
if (ctrl) {
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_PASTE, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
if (ctrl) {
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_CUT, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
if (ctrl) {
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_TEXT_UNDO, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
if (ctrl) {
|
||||
nk_input_key(&d3d12.ctx, NK_KEY_TEXT_REDO, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_CHAR:
|
||||
if (wparam >= 32)
|
||||
{
|
||||
nk_input_unicode(&d3d12.ctx, (nk_rune)wparam);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
nk_input_button(&d3d12.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
|
||||
SetCapture(wnd);
|
||||
return 1;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
nk_input_button(&d3d12.ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
|
||||
nk_input_button(&d3d12.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
|
||||
ReleaseCapture();
|
||||
return 1;
|
||||
|
||||
case WM_RBUTTONDOWN:
|
||||
nk_input_button(&d3d12.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
|
||||
SetCapture(wnd);
|
||||
return 1;
|
||||
|
||||
case WM_RBUTTONUP:
|
||||
nk_input_button(&d3d12.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
|
||||
ReleaseCapture();
|
||||
return 1;
|
||||
|
||||
case WM_MBUTTONDOWN:
|
||||
nk_input_button(&d3d12.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
|
||||
SetCapture(wnd);
|
||||
return 1;
|
||||
|
||||
case WM_MBUTTONUP:
|
||||
nk_input_button(&d3d12.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
|
||||
ReleaseCapture();
|
||||
return 1;
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
nk_input_scroll(&d3d12.ctx, nk_vec2(0,(float)(short)HIWORD(wparam) / WHEEL_DELTA));
|
||||
return 1;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
nk_input_motion(&d3d12.ctx, (short)LOWORD(lparam), (short)HIWORD(lparam));
|
||||
return 1;
|
||||
|
||||
case WM_LBUTTONDBLCLK:
|
||||
nk_input_button(&d3d12.ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nk_d3d12_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||
{
|
||||
(void)usr;
|
||||
if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL))
|
||||
{
|
||||
HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
|
||||
if (mem)
|
||||
{
|
||||
SIZE_T size = GlobalSize(mem) - 1;
|
||||
if (size)
|
||||
{
|
||||
LPCWSTR wstr = (LPCWSTR)GlobalLock(mem);
|
||||
if (wstr)
|
||||
{
|
||||
int utf8size = WideCharToMultiByte(CP_UTF8, 0, wstr, size / sizeof(wchar_t), NULL, 0, NULL, NULL);
|
||||
if (utf8size)
|
||||
{
|
||||
char* utf8 = (char*)malloc(utf8size);
|
||||
if (utf8)
|
||||
{
|
||||
WideCharToMultiByte(CP_UTF8, 0, wstr, size / sizeof(wchar_t), utf8, utf8size, NULL, NULL);
|
||||
nk_textedit_paste(edit, utf8, utf8size);
|
||||
free(utf8);
|
||||
}
|
||||
}
|
||||
GlobalUnlock(mem);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_d3d12_clipboard_copy(nk_handle usr, const char *text, int len)
|
||||
{
|
||||
(void)usr;
|
||||
if (OpenClipboard(NULL))
|
||||
{
|
||||
int wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
|
||||
if (wsize)
|
||||
{
|
||||
HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (wsize + 1) * sizeof(wchar_t));
|
||||
if (mem)
|
||||
{
|
||||
wchar_t* wstr = (wchar_t*)GlobalLock(mem);
|
||||
if (wstr)
|
||||
{
|
||||
MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
|
||||
wstr[wsize] = 0;
|
||||
GlobalUnlock(mem);
|
||||
SetClipboardData(CF_UNICODETEXT, mem);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
}
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_d3d12_init(ID3D12Device *device, int width, int height, unsigned int max_vertex_buffer, unsigned int max_index_buffer, unsigned int max_user_textures)
|
||||
{
|
||||
HRESULT hr;
|
||||
D3D12_CONSTANT_BUFFER_VIEW_DESC cbv;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE cbv_handle;
|
||||
|
||||
/* Do plain object / ref copys */
|
||||
d3d12.max_vertex_buffer = max_vertex_buffer;
|
||||
d3d12.max_index_buffer = max_index_buffer;
|
||||
d3d12.max_user_textures = max_user_textures;
|
||||
d3d12.device = device;
|
||||
ID3D12Device_AddRef(device);
|
||||
d3d12.font_texture = NULL;
|
||||
d3d12.font_upload_buffer = NULL;
|
||||
|
||||
/* Init nuklear context */
|
||||
nk_init_default(&d3d12.ctx, 0);
|
||||
d3d12.ctx.clip.copy = nk_d3d12_clipboard_copy;
|
||||
d3d12.ctx.clip.paste = nk_d3d12_clipboard_paste;
|
||||
d3d12.ctx.clip.userdata = nk_handle_ptr(0);
|
||||
|
||||
/* Init nuklear buffer */
|
||||
nk_buffer_init_default(&d3d12.cmds);
|
||||
|
||||
/* Define Heap properties */
|
||||
d3d12.heap_prop_default.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
d3d12.heap_prop_default.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
d3d12.heap_prop_default.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
d3d12.heap_prop_default.CreationNodeMask = 0;
|
||||
d3d12.heap_prop_default.VisibleNodeMask = 0;
|
||||
d3d12.heap_prop_upload.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||
d3d12.heap_prop_upload.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
d3d12.heap_prop_upload.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
d3d12.heap_prop_upload.CreationNodeMask = 0;
|
||||
d3d12.heap_prop_upload.VisibleNodeMask = 0;
|
||||
|
||||
/* Create data objects */
|
||||
/* Create upload buffer */
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
desc.Width = (sizeof(float) * 4 * 4) + max_vertex_buffer + max_index_buffer; /* Needs to hold matrix + vertices + indicies */
|
||||
desc.Height = 1;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = 1;
|
||||
desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
hr = ID3D12Device_CreateCommittedResource(device, &d3d12.heap_prop_upload, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COPY_SOURCE, NULL, &IID_ID3D12Resource, &d3d12.upload_buffer);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
/* Create constant buffer */
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
desc.Width = 256; /* Should be sizeof(float) * 4 * 4 - but this does not match how d3d12 works (min CBV size of 256) */
|
||||
desc.Height = 1;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = 1;
|
||||
desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
hr = ID3D12Device_CreateCommittedResource(device, &d3d12.heap_prop_default, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, &d3d12.const_buffer);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
/* Create vertex buffer */
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
desc.Width = max_vertex_buffer;
|
||||
desc.Height = 1;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = 1;
|
||||
desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
hr = ID3D12Device_CreateCommittedResource(device, &d3d12.heap_prop_default, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, &d3d12.vertex_buffer);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
/* Create index buffer */
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
desc.Width = max_index_buffer;
|
||||
desc.Height = 1;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = 1;
|
||||
desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
hr = ID3D12Device_CreateCommittedResource(device, &d3d12.heap_prop_default, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, &d3d12.index_buffer);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
|
||||
/* Create descriptor heap for shader root signature */
|
||||
{
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc;
|
||||
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
||||
desc.NumDescriptors = 2 + max_user_textures;
|
||||
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
||||
desc.NodeMask = 0;
|
||||
ID3D12Device_CreateDescriptorHeap(device, &desc, &IID_ID3D12DescriptorHeap, &d3d12.desc_heap);
|
||||
}
|
||||
|
||||
/* Get address of first handle (CPU and GPU) */
|
||||
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(d3d12.desc_heap, &d3d12.cpu_descriptor_handle);
|
||||
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(d3d12.desc_heap, &d3d12.gpu_descriptor_handle);
|
||||
|
||||
/* Get addresses of vertex & index buffers */
|
||||
d3d12.gpu_vertex_buffer_address = ID3D12Resource_GetGPUVirtualAddress(d3d12.vertex_buffer);
|
||||
d3d12.gpu_index_buffer_address = ID3D12Resource_GetGPUVirtualAddress(d3d12.index_buffer);
|
||||
|
||||
/* Get handle increment */
|
||||
d3d12.cbv_srv_uav_desc_increment = ID3D12Device_GetDescriptorHandleIncrementSize(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
|
||||
/* Create view to constant buffer */
|
||||
cbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(d3d12.const_buffer);
|
||||
cbv.SizeInBytes = 256;
|
||||
cbv_handle = d3d12.cpu_descriptor_handle;
|
||||
ID3D12Device_CreateConstantBufferView(device, &cbv, cbv_handle);
|
||||
|
||||
/* Create root signature */
|
||||
hr = ID3D12Device_CreateRootSignature(device, 0, nk_d3d12_vertex_shader, sizeof(nk_d3d12_vertex_shader), &IID_ID3D12RootSignature, &d3d12.root_signature);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
/* Create pipeline state */
|
||||
{
|
||||
/* Describe input layout */
|
||||
const D3D12_INPUT_ELEMENT_DESC layout[] = {
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, NK_OFFSETOF(struct nk_d3d12_vertex, position), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, NK_OFFSETOF(struct nk_d3d12_vertex, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, NK_OFFSETOF(struct nk_d3d12_vertex, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
|
||||
/* Describe pipeline state */
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC desc;
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.pRootSignature = d3d12.root_signature;
|
||||
desc.VS.pShaderBytecode = nk_d3d12_vertex_shader;
|
||||
desc.VS.BytecodeLength = sizeof(nk_d3d12_vertex_shader);
|
||||
desc.PS.pShaderBytecode = nk_d3d12_pixel_shader;
|
||||
desc.PS.BytecodeLength = sizeof(nk_d3d12_pixel_shader);
|
||||
desc.BlendState.RenderTarget[0].BlendEnable = TRUE;
|
||||
desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA;
|
||||
desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
|
||||
desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
|
||||
desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
|
||||
desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO;
|
||||
desc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
|
||||
desc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
|
||||
desc.SampleMask = UINT_MAX;
|
||||
desc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
|
||||
desc.RasterizerState.CullMode= D3D12_CULL_MODE_NONE;
|
||||
desc.RasterizerState.DepthClipEnable = TRUE;
|
||||
desc.InputLayout.NumElements = _countof(layout);
|
||||
desc.InputLayout.pInputElementDescs = layout;
|
||||
desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
desc.NumRenderTargets = 1;
|
||||
desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; /* NOTE: When using HDR rendering you might have a different framebuffer format */
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.NodeMask = 0;
|
||||
|
||||
/* Create PSO */
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(device, &desc, &IID_ID3D12PipelineState, &d3d12.pipeline_state);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
|
||||
/* First time const buffer init */
|
||||
nk_d3d12_resize(width, height);
|
||||
|
||||
/* viewport */
|
||||
d3d12.viewport.TopLeftX = 0.0f;
|
||||
d3d12.viewport.TopLeftY = 0.0f;
|
||||
d3d12.viewport.Width = (float)width;
|
||||
d3d12.viewport.Height = (float)height;
|
||||
d3d12.viewport.MinDepth = 0.0f;
|
||||
d3d12.viewport.MaxDepth = 1.0f;
|
||||
|
||||
return &d3d12.ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_d3d12_font_stash_begin(struct nk_font_atlas **atlas)
|
||||
{
|
||||
/* Default nuklear font stash */
|
||||
nk_font_atlas_init_default(&d3d12.atlas);
|
||||
nk_font_atlas_begin(&d3d12.atlas);
|
||||
*atlas = &d3d12.atlas;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_d3d12_font_stash_end(ID3D12GraphicsCommandList *command_list)
|
||||
{
|
||||
HRESULT hr;
|
||||
D3D12_TEXTURE_COPY_LOCATION cpy_src, cpy_dest;
|
||||
D3D12_BOX cpy_box;
|
||||
D3D12_RESOURCE_BARRIER resource_barrier;
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE srv_handle;
|
||||
const void *image;
|
||||
void* ptr_data;
|
||||
int w, h;
|
||||
|
||||
/* Bake nuklear font atlas */
|
||||
image = nk_font_atlas_bake(&d3d12.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
NK_ASSERT(image);
|
||||
|
||||
/* Create font texture */
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
desc.Width = w;
|
||||
desc.Height = h;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = 1;
|
||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
hr = ID3D12Device_CreateCommittedResource(d3d12.device, &d3d12.heap_prop_default, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COPY_DEST, NULL, &IID_ID3D12Resource, &d3d12.font_texture);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
|
||||
/* Create font upload buffer */
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
desc.Width = w * h * 4;
|
||||
desc.Height = 1;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = 1;
|
||||
desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
hr = ID3D12Device_CreateCommittedResource(d3d12.device, &d3d12.heap_prop_upload, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COPY_SOURCE, NULL, &IID_ID3D12Resource, &d3d12.font_upload_buffer);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
|
||||
/* Copy image data to upload buffer */
|
||||
hr = ID3D12Resource_Map(d3d12.font_upload_buffer, 0, NULL, &ptr_data);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
memcpy(ptr_data, image, w * h * 4);
|
||||
ID3D12Resource_Unmap(d3d12.font_upload_buffer, 0, NULL);
|
||||
|
||||
/* Execute copy operation */
|
||||
cpy_src.pResource = d3d12.font_upload_buffer;
|
||||
cpy_src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
cpy_src.PlacedFootprint.Offset = 0;
|
||||
cpy_src.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
cpy_src.PlacedFootprint.Footprint.Width = w;
|
||||
cpy_src.PlacedFootprint.Footprint.Height = h;
|
||||
cpy_src.PlacedFootprint.Footprint.Depth = 1;
|
||||
cpy_src.PlacedFootprint.Footprint.RowPitch = w * 4;
|
||||
cpy_dest.pResource = d3d12.font_texture;
|
||||
cpy_dest.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
cpy_dest.SubresourceIndex = 0;
|
||||
cpy_box.top = 0;
|
||||
cpy_box.left = 0;
|
||||
cpy_box.back = 1;
|
||||
cpy_box.bottom = h;
|
||||
cpy_box.right = w;
|
||||
cpy_box.front = 0;
|
||||
ID3D12GraphicsCommandList_CopyTextureRegion(command_list, &cpy_dest, 0, 0, 0, &cpy_src, &cpy_box);
|
||||
|
||||
/* Bring texture in the right state for rendering */
|
||||
resource_barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
resource_barrier.Transition.pResource = d3d12.font_texture;
|
||||
resource_barrier.Transition.Subresource = 0;
|
||||
resource_barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
resource_barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
resource_barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
ID3D12GraphicsCommandList_ResourceBarrier(command_list, 1, &resource_barrier);
|
||||
|
||||
/* Create the SRV for the font texture */
|
||||
srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
srv_desc.Texture2D.MipLevels = 1;
|
||||
srv_desc.Texture2D.MostDetailedMip = 0;
|
||||
srv_desc.Texture2D.PlaneSlice = 0;
|
||||
srv_desc.Texture2D.ResourceMinLODClamp = 0.0f;
|
||||
srv_handle.ptr = d3d12.cpu_descriptor_handle.ptr + d3d12.cbv_srv_uav_desc_increment;
|
||||
ID3D12Device_CreateShaderResourceView(d3d12.device, d3d12.font_texture, &srv_desc, srv_handle);
|
||||
|
||||
/* Done with nk atlas data. Atlas will be served with texture id 0 */
|
||||
nk_font_atlas_end(&d3d12.atlas, nk_handle_id(0), &d3d12.tex_null);
|
||||
|
||||
/* Setup default font */
|
||||
if (d3d12.atlas.default_font)
|
||||
nk_style_set_font(&d3d12.ctx, &d3d12.atlas.default_font->handle);
|
||||
}
|
||||
|
||||
NK_API
|
||||
void nk_d3d12_font_stash_cleanup()
|
||||
{
|
||||
if(d3d12.font_upload_buffer)
|
||||
{
|
||||
ID3D12Resource_Release(d3d12.font_upload_buffer);
|
||||
d3d12.font_upload_buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
NK_API
|
||||
nk_bool nk_d3d12_set_user_texture(unsigned int index, ID3D12Resource* texture, const D3D12_SHADER_RESOURCE_VIEW_DESC* description, nk_handle* handle_out)
|
||||
{
|
||||
nk_bool result = nk_false;
|
||||
if(index < d3d12.max_user_textures)
|
||||
{
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE srv_handle;
|
||||
|
||||
/* Get handle to texture (0 - Const Buffer; 1 - Font Texture; 2 - First user texture) */
|
||||
srv_handle.ptr = d3d12.cpu_descriptor_handle.ptr + ((2 + index) * d3d12.cbv_srv_uav_desc_increment);
|
||||
|
||||
/* Create SRV */
|
||||
ID3D12Device_CreateShaderResourceView(d3d12.device, texture, description, srv_handle);
|
||||
|
||||
/* Set nk handle (0 - Font Texture; 1 - First user texture) */
|
||||
*handle_out = nk_handle_id(1 + index);
|
||||
result = nk_true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NK_API
|
||||
void nk_d3d12_shutdown(void)
|
||||
{
|
||||
/* Nuklear cleanup */
|
||||
nk_font_atlas_clear(&d3d12.atlas);
|
||||
nk_buffer_free(&d3d12.cmds);
|
||||
nk_free(&d3d12.ctx);
|
||||
|
||||
/* DirectX 12 cleanup */
|
||||
ID3D12Device_Release(d3d12.device);
|
||||
ID3D12PipelineState_Release(d3d12.pipeline_state);
|
||||
ID3D12RootSignature_Release(d3d12.root_signature);
|
||||
ID3D12DescriptorHeap_Release(d3d12.desc_heap);
|
||||
ID3D12Resource_Release(d3d12.upload_buffer);
|
||||
ID3D12Resource_Release(d3d12.const_buffer);
|
||||
ID3D12Resource_Release(d3d12.index_buffer);
|
||||
ID3D12Resource_Release(d3d12.vertex_buffer);
|
||||
if(d3d12.font_texture)
|
||||
ID3D12Resource_Release(d3d12.font_texture);
|
||||
if(d3d12.font_upload_buffer)
|
||||
ID3D12Resource_Release(d3d12.font_upload_buffer);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,53 @@
|
|||
#define NK_ROOTSIGNATURE ""\
|
||||
"RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT),"\
|
||||
"DescriptorTable("\
|
||||
"CBV(b0, numDescriptors = 1, flags = DATA_VOLATILE),"\
|
||||
"SRV(t0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)"\
|
||||
"),"\
|
||||
"RootConstants(num32BitConstants = 1, b1),"\
|
||||
"StaticSampler(s0, "\
|
||||
"filter = FILTER_MIN_MAG_MIP_LINEAR,"\
|
||||
"addressU = TEXTURE_ADDRESS_CLAMP,"\
|
||||
"addressV = TEXTURE_ADDRESS_CLAMP,"\
|
||||
"addressW = TEXTURE_ADDRESS_CLAMP,"\
|
||||
"comparisonFunc = COMPARISON_ALWAYS"\
|
||||
")"
|
||||
|
||||
cbuffer buffer0 : register(b0)
|
||||
{
|
||||
float4x4 ProjectionMatrix;
|
||||
};
|
||||
static uint texture_index : register(b1);
|
||||
|
||||
sampler sampler0 : register(s0);
|
||||
Texture2D<float4> textures[] : register(t0);
|
||||
|
||||
struct VS_INPUT
|
||||
{
|
||||
float2 pos : POSITION;
|
||||
float4 col : COLOR0;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PS_INPUT
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float4 col : COLOR0;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
[RootSignature(NK_ROOTSIGNATURE)]
|
||||
PS_INPUT vs(VS_INPUT input)
|
||||
{
|
||||
PS_INPUT output;
|
||||
output.pos = mul(ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));
|
||||
output.col = input.col;
|
||||
output.uv = input.uv;
|
||||
return output;
|
||||
}
|
||||
|
||||
[RootSignature(NK_ROOTSIGNATURE)]
|
||||
float4 ps(PS_INPUT input) : SV_Target
|
||||
{
|
||||
return input.col * textures[texture_index].Sample(sampler0, input.uv);
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
#if 0
|
||||
//
|
||||
// Generated by Microsoft (R) D3D Shader Disassembler
|
||||
//
|
||||
//
|
||||
// Input signature:
|
||||
//
|
||||
// Name Index Mask Register SysValue Format Used
|
||||
// -------------------- ----- ------ -------- -------- ------- ------
|
||||
// SV_POSITION 0 xyzw 0 POS float
|
||||
// COLOR 0 xyzw 1 NONE float xyzw
|
||||
// TEXCOORD 0 xy 2 NONE float xy
|
||||
//
|
||||
//
|
||||
// Output signature:
|
||||
//
|
||||
// Name Index Mask Register SysValue Format Used
|
||||
// -------------------- ----- ------ -------- -------- ------- ------
|
||||
// SV_Target 0 xyzw 0 TARGET float xyzw
|
||||
//
|
||||
ps_5_1
|
||||
dcl_globalFlags refactoringAllowed
|
||||
dcl_sampler S0[0:0], mode_default, space=0
|
||||
dcl_resource_texture2d (float,float,float,float) T0[0:*], space=0
|
||||
dcl_input_ps linear v1.xyzw
|
||||
dcl_input_ps linear v2.xy
|
||||
dcl_output o0.xyzw
|
||||
dcl_temps 1
|
||||
sample r0.xyzw, v2.xyxx, T0[0].xyzw, S0[0]
|
||||
mul o0.xyzw, r0.xyzw, v1.xyzw
|
||||
ret
|
||||
// Approximately 0 instruction slots used
|
||||
#endif
|
||||
|
||||
const BYTE nk_d3d12_pixel_shader[] =
|
||||
{
|
||||
68, 88, 66, 67, 228, 128,
|
||||
250, 93, 94, 248, 174, 160,
|
||||
102, 133, 107, 228, 84, 49,
|
||||
109, 253, 1, 0, 0, 0,
|
||||
72, 2, 0, 0, 4, 0,
|
||||
0, 0, 48, 0, 0, 0,
|
||||
164, 0, 0, 0, 216, 0,
|
||||
0, 0, 152, 1, 0, 0,
|
||||
73, 83, 71, 78, 108, 0,
|
||||
0, 0, 3, 0, 0, 0,
|
||||
8, 0, 0, 0, 80, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 3, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
15, 0, 0, 0, 92, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 3, 0,
|
||||
0, 0, 1, 0, 0, 0,
|
||||
15, 15, 0, 0, 98, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 3, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
3, 3, 0, 0, 83, 86,
|
||||
95, 80, 79, 83, 73, 84,
|
||||
73, 79, 78, 0, 67, 79,
|
||||
76, 79, 82, 0, 84, 69,
|
||||
88, 67, 79, 79, 82, 68,
|
||||
0, 171, 79, 83, 71, 78,
|
||||
44, 0, 0, 0, 1, 0,
|
||||
0, 0, 8, 0, 0, 0,
|
||||
32, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
3, 0, 0, 0, 0, 0,
|
||||
0, 0, 15, 0, 0, 0,
|
||||
83, 86, 95, 84, 97, 114,
|
||||
103, 101, 116, 0, 171, 171,
|
||||
83, 72, 69, 88, 184, 0,
|
||||
0, 0, 81, 0, 0, 0,
|
||||
46, 0, 0, 0, 106, 8,
|
||||
0, 1, 90, 0, 0, 6,
|
||||
70, 110, 48, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 88, 24, 0, 7,
|
||||
70, 126, 48, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
255, 255, 255, 255, 85, 85,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
98, 16, 0, 3, 242, 16,
|
||||
16, 0, 1, 0, 0, 0,
|
||||
98, 16, 0, 3, 50, 16,
|
||||
16, 0, 2, 0, 0, 0,
|
||||
101, 0, 0, 3, 242, 32,
|
||||
16, 0, 0, 0, 0, 0,
|
||||
104, 0, 0, 2, 1, 0,
|
||||
0, 0, 69, 0, 0, 11,
|
||||
242, 0, 16, 0, 0, 0,
|
||||
0, 0, 70, 16, 16, 0,
|
||||
2, 0, 0, 0, 70, 126,
|
||||
32, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 96,
|
||||
32, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 56, 0,
|
||||
0, 7, 242, 32, 16, 0,
|
||||
0, 0, 0, 0, 70, 14,
|
||||
16, 0, 0, 0, 0, 0,
|
||||
70, 30, 16, 0, 1, 0,
|
||||
0, 0, 62, 0, 0, 1,
|
||||
82, 84, 83, 48, 168, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
2, 0, 0, 0, 24, 0,
|
||||
0, 0, 1, 0, 0, 0,
|
||||
116, 0, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 48, 0,
|
||||
0, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 104, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
56, 0, 0, 0, 2, 0,
|
||||
0, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
255, 255, 255, 255, 0, 0,
|
||||
0, 0, 255, 255, 255, 255,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 0, 0,
|
||||
255, 255, 255, 255, 1, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 21, 0,
|
||||
0, 0, 3, 0, 0, 0,
|
||||
3, 0, 0, 0, 3, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
16, 0, 0, 0, 8, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 255,
|
||||
127, 127, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0
|
||||
};
|
|
@ -0,0 +1,168 @@
|
|||
#if 0
|
||||
//
|
||||
// Generated by Microsoft (R) D3D Shader Disassembler
|
||||
//
|
||||
//
|
||||
// Input signature:
|
||||
//
|
||||
// Name Index Mask Register SysValue Format Used
|
||||
// -------------------- ----- ------ -------- -------- ------- ------
|
||||
// POSITION 0 xy 0 NONE float xy
|
||||
// COLOR 0 xyzw 1 NONE float xyzw
|
||||
// TEXCOORD 0 xy 2 NONE float xy
|
||||
//
|
||||
//
|
||||
// Output signature:
|
||||
//
|
||||
// Name Index Mask Register SysValue Format Used
|
||||
// -------------------- ----- ------ -------- -------- ------- ------
|
||||
// SV_POSITION 0 xyzw 0 POS float xyzw
|
||||
// COLOR 0 xyzw 1 NONE float xyzw
|
||||
// TEXCOORD 0 xy 2 NONE float xy
|
||||
//
|
||||
vs_5_1
|
||||
dcl_globalFlags refactoringAllowed
|
||||
dcl_constantbuffer CB0[0:0][4], immediateIndexed, space=0
|
||||
dcl_input v0.xy
|
||||
dcl_input v1.xyzw
|
||||
dcl_input v2.xy
|
||||
dcl_output_siv o0.xyzw, position
|
||||
dcl_output o1.xyzw
|
||||
dcl_output o2.xy
|
||||
dcl_temps 1
|
||||
mul r0.xyzw, v0.yyyy, CB0[0][1].xyzw
|
||||
mad r0.xyzw, CB0[0][0].xyzw, v0.xxxx, r0.xyzw
|
||||
add o0.xyzw, r0.xyzw, CB0[0][3].xyzw
|
||||
mov o1.xyzw, v1.xyzw
|
||||
mov o2.xy, v2.xyxx
|
||||
ret
|
||||
// Approximately 0 instruction slots used
|
||||
#endif
|
||||
|
||||
const BYTE nk_d3d12_vertex_shader[] =
|
||||
{
|
||||
68, 88, 66, 67, 187, 129,
|
||||
163, 57, 169, 94, 219, 158,
|
||||
174, 23, 30, 91, 108, 150,
|
||||
135, 141, 1, 0, 0, 0,
|
||||
232, 2, 0, 0, 4, 0,
|
||||
0, 0, 48, 0, 0, 0,
|
||||
160, 0, 0, 0, 20, 1,
|
||||
0, 0, 56, 2, 0, 0,
|
||||
73, 83, 71, 78, 104, 0,
|
||||
0, 0, 3, 0, 0, 0,
|
||||
8, 0, 0, 0, 80, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 3, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
3, 3, 0, 0, 89, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 3, 0,
|
||||
0, 0, 1, 0, 0, 0,
|
||||
15, 15, 0, 0, 95, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 3, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
3, 3, 0, 0, 80, 79,
|
||||
83, 73, 84, 73, 79, 78,
|
||||
0, 67, 79, 76, 79, 82,
|
||||
0, 84, 69, 88, 67, 79,
|
||||
79, 82, 68, 0, 79, 83,
|
||||
71, 78, 108, 0, 0, 0,
|
||||
3, 0, 0, 0, 8, 0,
|
||||
0, 0, 80, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 0,
|
||||
0, 0, 3, 0, 0, 0,
|
||||
0, 0, 0, 0, 15, 0,
|
||||
0, 0, 92, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 3, 0, 0, 0,
|
||||
1, 0, 0, 0, 15, 0,
|
||||
0, 0, 98, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 3, 0, 0, 0,
|
||||
2, 0, 0, 0, 3, 12,
|
||||
0, 0, 83, 86, 95, 80,
|
||||
79, 83, 73, 84, 73, 79,
|
||||
78, 0, 67, 79, 76, 79,
|
||||
82, 0, 84, 69, 88, 67,
|
||||
79, 79, 82, 68, 0, 171,
|
||||
83, 72, 69, 88, 28, 1,
|
||||
0, 0, 81, 0, 1, 0,
|
||||
71, 0, 0, 0, 106, 8,
|
||||
0, 1, 89, 0, 0, 7,
|
||||
70, 142, 48, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 4, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
95, 0, 0, 3, 50, 16,
|
||||
16, 0, 0, 0, 0, 0,
|
||||
95, 0, 0, 3, 242, 16,
|
||||
16, 0, 1, 0, 0, 0,
|
||||
95, 0, 0, 3, 50, 16,
|
||||
16, 0, 2, 0, 0, 0,
|
||||
103, 0, 0, 4, 242, 32,
|
||||
16, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 101, 0,
|
||||
0, 3, 242, 32, 16, 0,
|
||||
1, 0, 0, 0, 101, 0,
|
||||
0, 3, 50, 32, 16, 0,
|
||||
2, 0, 0, 0, 104, 0,
|
||||
0, 2, 1, 0, 0, 0,
|
||||
56, 0, 0, 9, 242, 0,
|
||||
16, 0, 0, 0, 0, 0,
|
||||
86, 21, 16, 0, 0, 0,
|
||||
0, 0, 70, 142, 48, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 0, 0,
|
||||
50, 0, 0, 11, 242, 0,
|
||||
16, 0, 0, 0, 0, 0,
|
||||
70, 142, 48, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 6, 16,
|
||||
16, 0, 0, 0, 0, 0,
|
||||
70, 14, 16, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 9,
|
||||
242, 32, 16, 0, 0, 0,
|
||||
0, 0, 70, 14, 16, 0,
|
||||
0, 0, 0, 0, 70, 142,
|
||||
48, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 3, 0,
|
||||
0, 0, 54, 0, 0, 5,
|
||||
242, 32, 16, 0, 1, 0,
|
||||
0, 0, 70, 30, 16, 0,
|
||||
1, 0, 0, 0, 54, 0,
|
||||
0, 5, 50, 32, 16, 0,
|
||||
2, 0, 0, 0, 70, 16,
|
||||
16, 0, 2, 0, 0, 0,
|
||||
62, 0, 0, 1, 82, 84,
|
||||
83, 48, 168, 0, 0, 0,
|
||||
2, 0, 0, 0, 2, 0,
|
||||
0, 0, 24, 0, 0, 0,
|
||||
1, 0, 0, 0, 116, 0,
|
||||
0, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 48, 0, 0, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 0, 104, 0, 0, 0,
|
||||
2, 0, 0, 0, 56, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
2, 0, 0, 0, 255, 255,
|
||||
255, 255, 0, 0, 0, 0,
|
||||
255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 255, 255,
|
||||
255, 255, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 0,
|
||||
0, 0, 21, 0, 0, 0,
|
||||
3, 0, 0, 0, 3, 0,
|
||||
0, 0, 3, 0, 0, 0,
|
||||
0, 0, 0, 0, 16, 0,
|
||||
0, 0, 8, 0, 0, 0,
|
||||
2, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 255, 127, 127,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0
|
||||
};
|
|
@ -33,27 +33,32 @@
|
|||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -82,10 +87,11 @@ WindowProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
|||
if (width != 0 && height != 0 &&
|
||||
(width != present.BackBufferWidth || height != present.BackBufferHeight))
|
||||
{
|
||||
HRESULT hr;
|
||||
nk_d3d9_release();
|
||||
present.BackBufferWidth = width;
|
||||
present.BackBufferHeight = height;
|
||||
HRESULT hr = IDirect3DDevice9_Reset(device, &present);
|
||||
hr = IDirect3DDevice9_Reset(device, &present);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
nk_d3d9_resize(width, height);
|
||||
}
|
||||
|
@ -210,10 +216,16 @@ int main(void)
|
|||
|
||||
/* style.c */
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
|
||||
|
@ -268,6 +280,9 @@ int main(void)
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
|
|
@ -58,7 +58,7 @@ static struct {
|
|||
struct nk_font_atlas atlas;
|
||||
struct nk_buffer cmds;
|
||||
|
||||
struct nk_draw_null_texture null;
|
||||
struct nk_draw_null_texture tex_null;
|
||||
|
||||
D3DVIEWPORT9 viewport;
|
||||
D3DMATRIX projection;
|
||||
|
@ -150,7 +150,7 @@ nk_d3d9_render(enum nk_anti_aliasing AA)
|
|||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
config.null = d3d9.null;
|
||||
config.tex_null = d3d9.tex_null;
|
||||
|
||||
/* convert shapes into vertexes */
|
||||
nk_buffer_init_default(&vbuf);
|
||||
|
@ -204,11 +204,15 @@ nk_d3d9_get_projection_matrix(int width, int height, float *result)
|
|||
const float T = 0.5f;
|
||||
const float B = (float)height + 0.5f;
|
||||
float matrix[4][4] = {
|
||||
{ 2.0f / (R - L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f / (T - B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ (R + L) / (L - R), (T + B) / (B - T), 0.0f, 1.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 1.0f },
|
||||
};
|
||||
matrix[0][0] = 2.0f / (R - L);
|
||||
matrix[1][1] = 2.0f / (T - B);
|
||||
matrix[3][0] = (R + L) / (L - R);
|
||||
matrix[3][1] = (T + B) / (B - T);
|
||||
memcpy(result, matrix, sizeof(matrix));
|
||||
}
|
||||
|
||||
|
@ -244,7 +248,7 @@ nk_d3d9_create_font_texture()
|
|||
hr = IDirect3DTexture9_UnlockRect(d3d9.texture, 0);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
nk_font_atlas_end(&d3d9.atlas, nk_handle_ptr(d3d9.texture), &d3d9.null);
|
||||
nk_font_atlas_end(&d3d9.atlas, nk_handle_ptr(d3d9.texture), &d3d9.tex_null);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
|
@ -426,30 +430,35 @@ nk_d3d9_handle_event(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
|||
static void
|
||||
nk_d3d9_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||
{
|
||||
HGLOBAL mem;
|
||||
SIZE_T size;
|
||||
LPCWSTR wstr;
|
||||
int utf8size;
|
||||
|
||||
(void)usr;
|
||||
if (!IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
|
||||
mem = GetClipboardData(CF_UNICODETEXT);
|
||||
if (!mem) {
|
||||
CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
SIZE_T size = GlobalSize(mem) - 1;
|
||||
size = GlobalSize(mem) - 1;
|
||||
if (!size) {
|
||||
CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
LPCWSTR wstr = (LPCWSTR)GlobalLock(mem);
|
||||
wstr = (LPCWSTR)GlobalLock(mem);
|
||||
if (!wstr) {
|
||||
CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
int utf8size = WideCharToMultiByte(CP_UTF8, 0, wstr, (int)size / sizeof(wchar_t), NULL, 0, NULL, NULL);
|
||||
utf8size = WideCharToMultiByte(CP_UTF8, 0, wstr, (int)size / sizeof(wchar_t), NULL, 0, NULL, NULL);
|
||||
if (utf8size) {
|
||||
char *utf8 = (char *)malloc(utf8size);
|
||||
if (utf8) {
|
||||
|
@ -466,12 +475,14 @@ nk_d3d9_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
|
|||
static void
|
||||
nk_d3d9_clipboard_copy(nk_handle usr, const char *text, int len)
|
||||
{
|
||||
int wsize;
|
||||
|
||||
(void)usr;
|
||||
if (!OpenClipboard(NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
|
||||
wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
|
||||
if (wsize) {
|
||||
HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (wsize + 1) * sizeof(wchar_t));
|
||||
if (mem) {
|
||||
|
|
|
@ -28,27 +28,32 @@
|
|||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -110,10 +115,16 @@ int main(void)
|
|||
|
||||
/* style.c */
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
while (running)
|
||||
|
@ -164,6 +175,9 @@ int main(void)
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <wingdi.h>
|
||||
|
||||
typedef struct GdiFont GdiFont;
|
||||
NK_API struct nk_context* nk_gdi_init(GdiFont *font, HDC window_dc, unsigned int width, unsigned int height);
|
||||
|
@ -62,6 +63,13 @@ nk_create_image(struct nk_image * image, const char * frame_buffer, const int wi
|
|||
{
|
||||
if (image && frame_buffer && (width > 0) && (height > 0))
|
||||
{
|
||||
const unsigned char * src = (const unsigned char *)frame_buffer;
|
||||
INT row = ((width * 3 + 3) & ~3);
|
||||
LPBYTE lpBuf, pb = NULL;
|
||||
BITMAPINFO bi = { 0 };
|
||||
HBITMAP hbm;
|
||||
int v, i;
|
||||
|
||||
image->w = width;
|
||||
image->h = height;
|
||||
image->region[0] = 0;
|
||||
|
@ -69,8 +77,6 @@ nk_create_image(struct nk_image * image, const char * frame_buffer, const int wi
|
|||
image->region[2] = width;
|
||||
image->region[3] = height;
|
||||
|
||||
INT row = ((width * 3 + 3) & ~3);
|
||||
BITMAPINFO bi = { 0 };
|
||||
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bi.bmiHeader.biWidth = width;
|
||||
bi.bmiHeader.biHeight = height;
|
||||
|
@ -79,15 +85,13 @@ nk_create_image(struct nk_image * image, const char * frame_buffer, const int wi
|
|||
bi.bmiHeader.biCompression = BI_RGB;
|
||||
bi.bmiHeader.biSizeImage = row * height;
|
||||
|
||||
LPBYTE lpBuf, pb = NULL;
|
||||
HBITMAP hbm = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**)&lpBuf, NULL, 0);
|
||||
hbm = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**)&lpBuf, NULL, 0);
|
||||
|
||||
pb = lpBuf + row * height;
|
||||
unsigned char * src = (unsigned char *)frame_buffer;
|
||||
for (int v = 0; v<height; v++)
|
||||
for (v = 0; v < height; v++)
|
||||
{
|
||||
pb -= row;
|
||||
for (int i = 0; i < row; i += 3)
|
||||
for (i = 0; i < row; i += 3)
|
||||
{
|
||||
pb[i + 0] = src[0];
|
||||
pb[i + 1] = src[1];
|
||||
|
@ -170,8 +174,9 @@ nk_gdi_stroke_rect(HDC dc, short x, short y, unsigned short w,
|
|||
unsigned short h, unsigned short r, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
|
||||
HGDIOBJ br;
|
||||
HPEN pen = NULL;
|
||||
|
||||
if (line_thickness == 1) {
|
||||
SetDCPenColor(dc, color);
|
||||
} else {
|
||||
|
@ -179,7 +184,7 @@ nk_gdi_stroke_rect(HDC dc, short x, short y, unsigned short w,
|
|||
SelectObject(dc, pen);
|
||||
}
|
||||
|
||||
HGDIOBJ br = SelectObject(dc, GetStockObject(NULL_BRUSH));
|
||||
br = SelectObject(dc, GetStockObject(NULL_BRUSH));
|
||||
if (r == 0) {
|
||||
Rectangle(dc, x, y, x + w, y + h);
|
||||
} else {
|
||||
|
@ -200,7 +205,8 @@ nk_gdi_fill_rect(HDC dc, short x, short y, unsigned short w,
|
|||
COLORREF color = convert_color(col);
|
||||
|
||||
if (r == 0) {
|
||||
RECT rect = { x, y, x + w, y + h };
|
||||
RECT rect;
|
||||
SetRect(&rect, x, y, x + w, y + h);
|
||||
SetBkColor(dc, color);
|
||||
ExtTextOutW(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
|
||||
} else {
|
||||
|
@ -262,16 +268,26 @@ nk_gdi_rect_multi_color(HDC dc, short x, short y, unsigned short w,
|
|||
|
||||
}
|
||||
|
||||
static BOOL
|
||||
SetPoint(POINT *p, LONG x, LONG y)
|
||||
{
|
||||
if (!p)
|
||||
return FALSE;
|
||||
p->x = x;
|
||||
p->y = y;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_fill_triangle(HDC dc, short x0, short y0, short x1,
|
||||
short y1, short x2, short y2, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
POINT points[] = {
|
||||
{ x0, y0 },
|
||||
{ x1, y1 },
|
||||
{ x2, y2 },
|
||||
};
|
||||
POINT points[3];
|
||||
|
||||
SetPoint(&points[0], x0, y0);
|
||||
SetPoint(&points[1], x1, y1);
|
||||
SetPoint(&points[2], x2, y2);
|
||||
|
||||
SetDCPenColor(dc, color);
|
||||
SetDCBrushColor(dc, color);
|
||||
|
@ -283,14 +299,14 @@ nk_gdi_stroke_triangle(HDC dc, short x0, short y0, short x1,
|
|||
short y1, short x2, short y2, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
POINT points[] = {
|
||||
{ x0, y0 },
|
||||
{ x1, y1 },
|
||||
{ x2, y2 },
|
||||
{ x0, y0 },
|
||||
};
|
||||
|
||||
POINT points[4];
|
||||
HPEN pen = NULL;
|
||||
|
||||
SetPoint(&points[0], x0, y0);
|
||||
SetPoint(&points[1], x1, y1);
|
||||
SetPoint(&points[2], x2, y2);
|
||||
SetPoint(&points[3], x0, y0);
|
||||
|
||||
if (line_thickness == 1) {
|
||||
SetDCPenColor(dc, color);
|
||||
} else {
|
||||
|
@ -376,6 +392,62 @@ nk_gdi_stroke_polyline(HDC dc, const struct nk_vec2i *pnts,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_stroke_arc(HDC dc, short cx, short cy, unsigned short r, float amin, float adelta, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
|
||||
/* setup pen */
|
||||
HPEN pen = NULL;
|
||||
if (line_thickness == 1)
|
||||
SetDCPenColor(dc, color);
|
||||
else
|
||||
{
|
||||
/* the flat endcap makes thick arcs look better */
|
||||
DWORD pen_style = PS_SOLID | PS_ENDCAP_FLAT | PS_GEOMETRIC;
|
||||
|
||||
LOGBRUSH brush;
|
||||
brush.lbStyle = BS_SOLID;
|
||||
brush.lbColor = color;
|
||||
brush.lbHatch = 0;
|
||||
|
||||
pen = ExtCreatePen(pen_style, line_thickness, &brush, 0, NULL);
|
||||
SelectObject(dc, pen);
|
||||
}
|
||||
|
||||
/* calculate arc and draw */
|
||||
int start_x = cx + (int) ((float)r*nk_cos(amin+adelta)),
|
||||
start_y = cy + (int) ((float)r*nk_sin(amin+adelta)),
|
||||
end_x = cx + (int) ((float)r*nk_cos(amin)),
|
||||
end_y = cy + (int) ((float)r*nk_sin(amin));
|
||||
|
||||
HGDIOBJ br = SelectObject(dc, GetStockObject(NULL_BRUSH));
|
||||
SetArcDirection(dc, AD_COUNTERCLOCKWISE);
|
||||
Pie(dc, cx-r, cy-r, cx+r, cy+r, start_x, start_y, end_x, end_y);
|
||||
SelectObject(dc, br);
|
||||
|
||||
if (pen)
|
||||
{
|
||||
SelectObject(dc, GetStockObject(DC_PEN));
|
||||
DeleteObject(pen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_fill_arc(HDC dc, short cx, short cy, unsigned short r, float amin, float adelta, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
SetDCBrushColor(dc, color);
|
||||
SetDCPenColor(dc, color);
|
||||
|
||||
int start_x = cx + (int) ((float)r*nk_cos(amin+adelta)),
|
||||
start_y = cy + (int) ((float)r*nk_sin(amin+adelta)),
|
||||
end_x = cx + (int) ((float)r*nk_cos(amin)),
|
||||
end_y = cy + (int) ((float)r*nk_sin(amin));
|
||||
|
||||
Pie(dc, cx-r, cy-r, cx+r, cy+r, start_x, start_y, end_x, end_y);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_fill_circle(HDC dc, short x, short y, unsigned short w,
|
||||
unsigned short h, struct nk_color col)
|
||||
|
@ -399,8 +471,10 @@ nk_gdi_stroke_circle(HDC dc, short x, short y, unsigned short w,
|
|||
SelectObject(dc, pen);
|
||||
}
|
||||
|
||||
HGDIOBJ br = SelectObject(dc, GetStockObject(NULL_BRUSH));
|
||||
SetDCBrushColor(dc, OPAQUE);
|
||||
Ellipse(dc, x, y, x + w, y + h);
|
||||
SelectObject(dc, br);
|
||||
|
||||
if (pen) {
|
||||
SelectObject(dc, GetStockObject(DC_PEN));
|
||||
|
@ -414,14 +488,14 @@ nk_gdi_stroke_curve(HDC dc, struct nk_vec2i p1,
|
|||
unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
POINT p[] = {
|
||||
{ p1.x, p1.y },
|
||||
{ p2.x, p2.y },
|
||||
{ p3.x, p3.y },
|
||||
{ p4.x, p4.y },
|
||||
};
|
||||
|
||||
POINT p[4];
|
||||
HPEN pen = NULL;
|
||||
|
||||
SetPoint(&p[0], p1.x, p1.y);
|
||||
SetPoint(&p[1], p2.x, p2.y);
|
||||
SetPoint(&p[2], p3.x, p3.y);
|
||||
SetPoint(&p[3], p4.x, p4.y);
|
||||
|
||||
if (line_thickness == 1) {
|
||||
SetDCPenColor(dc, color);
|
||||
} else {
|
||||
|
@ -462,7 +536,8 @@ static void
|
|||
nk_gdi_clear(HDC dc, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
RECT rect = { 0, 0, gdi.width, gdi.height };
|
||||
RECT rect;
|
||||
SetRect(&rect, 0, 0, gdi.width, gdi.height);
|
||||
SetBkColor(dc, color);
|
||||
|
||||
ExtTextOutW(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
|
||||
|
@ -701,6 +776,13 @@ nk_gdi_handle_event(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
|||
nk_input_key(&gdi.ctx, NK_KEY_SCROLL_UP, down);
|
||||
return 1;
|
||||
|
||||
case 'A':
|
||||
if (ctrl) {
|
||||
nk_input_key(&gdi.ctx, NK_KEY_TEXT_SELECT_ALL, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
if (ctrl) {
|
||||
nk_input_key(&gdi.ctx, NK_KEY_COPY, down);
|
||||
|
@ -843,6 +925,14 @@ nk_gdi_render(struct nk_color clear)
|
|||
const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
|
||||
nk_gdi_fill_circle(memory_dc, c->x, c->y, c->w, c->h, c->color);
|
||||
} break;
|
||||
case NK_COMMAND_ARC: {
|
||||
const struct nk_command_arc *q = (const struct nk_command_arc *)cmd;
|
||||
nk_gdi_stroke_arc(memory_dc, q->cx, q->cy, q->r, q->a[0], q->a[1], q->line_thickness, q->color);
|
||||
} break;
|
||||
case NK_COMMAND_ARC_FILLED: {
|
||||
const struct nk_command_arc_filled *q = (const struct nk_command_arc_filled *)cmd;
|
||||
nk_gdi_fill_arc(memory_dc, q->cx, q->cy, q->r, q->a[0], q->a[1], q->color);
|
||||
} break;
|
||||
case NK_COMMAND_TRIANGLE: {
|
||||
const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
|
||||
nk_gdi_stroke_triangle(memory_dc, t->a.x, t->a.y, t->b.x, t->b.y,
|
||||
|
@ -885,8 +975,7 @@ nk_gdi_render(struct nk_color clear)
|
|||
const struct nk_command_image *i = (const struct nk_command_image *)cmd;
|
||||
nk_gdi_draw_image(i->x, i->y, i->w, i->h, i->img, i->col);
|
||||
} break;
|
||||
case NK_COMMAND_ARC:
|
||||
case NK_COMMAND_ARC_FILLED:
|
||||
case NK_COMMAND_CUSTOM:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
@echo off
|
||||
|
||||
rem This will use VS2015 for compiler
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86
|
||||
|
||||
cl /nologo /W3 /O2 /fp:fast /Gm- /D_CRT_SECURE_NO_DEPRECATE /Fedemo.exe main.c user32.lib gdi32.lib Msimg32.lib /link /incremental:no
|
|
@ -0,0 +1,128 @@
|
|||
#include <windows.h>
|
||||
|
||||
#pragma comment(linker,"\"/manifestdependency:type='win32' \
|
||||
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
|
||||
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
|
||||
/* Includes the default nuklear implementation
|
||||
* Includes the modified GDI backend (No more global state to allow multiple hwnd's)
|
||||
*/
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_STANDARD_VARARGS
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_GDI_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include "nuklear_gdi.h"
|
||||
|
||||
/* Include the window framework (the new fancy code of this demo) */
|
||||
#define NKGDI_IMPLEMENT_WINDOW
|
||||
#include "window.h"
|
||||
|
||||
/* This callback will be called when the window is draw
|
||||
* You will NOT need to call nk_begin(...) and nk_end(...)
|
||||
* begin and end are handled by the parent code calling this
|
||||
* callback
|
||||
*/
|
||||
int drawCallback(struct nk_context* ctx)
|
||||
{
|
||||
/* Code is from ../calculator.c */
|
||||
static int set = 0, prev = 0, op = 0;
|
||||
static const char numbers[] = "789456123";
|
||||
static const char ops[] = "+-*/";
|
||||
static double a = 0, b = 0;
|
||||
static double *current = &a;
|
||||
|
||||
size_t i = 0;
|
||||
int solve = 0;
|
||||
{int len; char buffer[256];
|
||||
nk_layout_row_dynamic(ctx, 35, 1);
|
||||
len = snprintf(buffer, 256, "%.2f", *current);
|
||||
nk_edit_string(ctx, NK_EDIT_SIMPLE, buffer, &len, 255, nk_filter_float);
|
||||
buffer[len] = 0;
|
||||
*current = atof(buffer);}
|
||||
|
||||
nk_layout_row_dynamic(ctx, 35, 4);
|
||||
for (i = 0; i < 16; ++i) {
|
||||
if (i >= 12 && i < 15) {
|
||||
if (i > 12) continue;
|
||||
if (nk_button_label(ctx, "C")) {
|
||||
a = b = op = 0; current = &a; set = 0;
|
||||
} if (nk_button_label(ctx, "0")) {
|
||||
*current = *current*10.0f; set = 0;
|
||||
} if (nk_button_label(ctx, "=")) {
|
||||
solve = 1; prev = op; op = 0;
|
||||
}
|
||||
} else if (((i+1) % 4)) {
|
||||
if (nk_button_text(ctx, &numbers[(i/4)*3+i%4], 1)) {
|
||||
*current = *current * 10.0f + numbers[(i/4)*3+i%4] - '0';
|
||||
set = 0;
|
||||
}
|
||||
} else if (nk_button_text(ctx, &ops[i/4], 1)) {
|
||||
if (!set) {
|
||||
if (current != &b) {
|
||||
current = &b;
|
||||
} else {
|
||||
prev = op;
|
||||
solve = 1;
|
||||
}
|
||||
}
|
||||
op = ops[i/4];
|
||||
set = 1;
|
||||
}
|
||||
}
|
||||
if (solve) {
|
||||
if (prev == '+') a = a + b;
|
||||
if (prev == '-') a = a - b;
|
||||
if (prev == '*') a = a * b;
|
||||
if (prev == '/') a = a / b;
|
||||
current = &a;
|
||||
if (set) current = &b;
|
||||
b = 0; set = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Main entry point - wWinMain used for UNICODE
|
||||
* (You can also use _tWinMain(...) to automaticaly use the ASCII or WIDE char entry point base on your build)
|
||||
*/
|
||||
INT WINAPI wWinMain(HINSTANCE _In_ hInstance, HINSTANCE _In_opt_ hPrevInstance, PWSTR _In_ cmdArgs, INT _In_ cmdShow)
|
||||
{
|
||||
/* Call this first to setup all required prerequisites */
|
||||
nkgdi_window_init();
|
||||
|
||||
/* Preparing two window contexts */
|
||||
struct nkgdi_window w1, w2;
|
||||
memset(&w1, 0x0, sizeof(struct nkgdi_window));
|
||||
memset(&w2, 0x0, sizeof(struct nkgdi_window));
|
||||
|
||||
/* Configure and create window 1.
|
||||
* Note: You can allways change the direct accesible parameters later as well!
|
||||
*/
|
||||
w1.allow_sizing = 0;
|
||||
w1.allow_maximize = 0;
|
||||
w1.allow_move = 0;
|
||||
w1.has_titlebar = 0;
|
||||
w1.cb_on_draw = &drawCallback;
|
||||
nkgdi_window_create(&w1, 500, 500, "F1", 10, 10);
|
||||
|
||||
/* Configure and create window 2 */
|
||||
w2.allow_sizing = 1;
|
||||
w2.allow_maximize = 1;
|
||||
w2.allow_move = 1;
|
||||
w2.has_titlebar = 1;
|
||||
w2.cb_on_draw = &drawCallback;
|
||||
nkgdi_window_create(&w2, 500, 500, "F2", 520, 10);
|
||||
|
||||
/* As long as both windows are valid (nkgdi_window_update returning 1) */
|
||||
while (nkgdi_window_update(&w1) && nkgdi_window_update(&w2)) Sleep(20);
|
||||
|
||||
/* Destroy both windows context */
|
||||
nkgdi_window_destroy(&w1);
|
||||
nkgdi_window_destroy(&w2);
|
||||
|
||||
/* Call nkgdi_window_shutdown to properly shutdown the gdi window framework */
|
||||
nkgdi_window_shutdown();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,937 @@
|
|||
/*
|
||||
* Nuklear - 1.32.0 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2016 by Micha Mettke
|
||||
*
|
||||
* Modified GDI backend 2022
|
||||
* Now based on a context that is required for each API function call.
|
||||
* Removes the global state --> you can have multiple windows :-)
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_GDI_H_
|
||||
#define NK_GDI_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
typedef struct GdiFont GdiFont;
|
||||
struct _nk_gdi_ctx;
|
||||
typedef struct _nk_gdi_ctx* nk_gdi_ctx;
|
||||
|
||||
NK_API struct nk_context* nk_gdi_init(nk_gdi_ctx* gdi, GdiFont* font, HDC window_dc, unsigned int width, unsigned int height);
|
||||
NK_API int nk_gdi_handle_event(nk_gdi_ctx gdi, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
NK_API void nk_gdi_render(nk_gdi_ctx gdi, struct nk_color clear);
|
||||
NK_API void nk_gdi_shutdown(nk_gdi_ctx gdi);
|
||||
|
||||
/* font */
|
||||
NK_API GdiFont* nk_gdifont_create(const char* name, int size);
|
||||
NK_API void nk_gdifont_del(GdiFont* font);
|
||||
NK_API void nk_gdi_set_font(nk_gdi_ctx gdi, GdiFont* font);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_GDI_IMPLEMENTATION
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
|
||||
struct GdiFont {
|
||||
struct nk_user_font nk;
|
||||
int height;
|
||||
HFONT handle;
|
||||
HDC dc;
|
||||
};
|
||||
|
||||
struct _nk_gdi_ctx {
|
||||
HBITMAP bitmap;
|
||||
HDC window_dc;
|
||||
HDC memory_dc;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
struct nk_context ctx;
|
||||
};
|
||||
|
||||
static void
|
||||
nk_create_image(struct nk_image* image, const char* frame_buffer, const int width, const int height)
|
||||
{
|
||||
if (image && frame_buffer && (width > 0) && (height > 0))
|
||||
{
|
||||
const unsigned char* src = (const unsigned char*)frame_buffer;
|
||||
INT row = ((width * 3 + 3) & ~3);
|
||||
LPBYTE lpBuf, pb = NULL;
|
||||
BITMAPINFO bi = { 0 };
|
||||
HBITMAP hbm;
|
||||
int v, i;
|
||||
|
||||
image->w = width;
|
||||
image->h = height;
|
||||
image->region[0] = 0;
|
||||
image->region[1] = 0;
|
||||
image->region[2] = width;
|
||||
image->region[3] = height;
|
||||
|
||||
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bi.bmiHeader.biWidth = width;
|
||||
bi.bmiHeader.biHeight = height;
|
||||
bi.bmiHeader.biPlanes = 1;
|
||||
bi.bmiHeader.biBitCount = 24;
|
||||
bi.bmiHeader.biCompression = BI_RGB;
|
||||
bi.bmiHeader.biSizeImage = row * height;
|
||||
|
||||
hbm = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**)&lpBuf, NULL, 0);
|
||||
|
||||
pb = lpBuf + row * height;
|
||||
for (v = 0; v < height; v++)
|
||||
{
|
||||
pb -= row;
|
||||
for (i = 0; i < row; i += 3)
|
||||
{
|
||||
pb[i + 0] = src[0];
|
||||
pb[i + 1] = src[1];
|
||||
pb[i + 2] = src[2];
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
SetDIBits(NULL, hbm, 0, height, lpBuf, &bi, DIB_RGB_COLORS);
|
||||
image->handle.ptr = hbm;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_delete_image(struct nk_image* image)
|
||||
{
|
||||
if (image && image->handle.id != 0)
|
||||
{
|
||||
HBITMAP hbm = (HBITMAP)image->handle.ptr;
|
||||
DeleteObject(hbm);
|
||||
memset(image, 0, sizeof(struct nk_image));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_draw_image(nk_gdi_ctx gdi, short x, short y, unsigned short w, unsigned short h,
|
||||
struct nk_image img, struct nk_color col)
|
||||
{
|
||||
HBITMAP hbm = (HBITMAP)img.handle.ptr;
|
||||
HDC hDCBits;
|
||||
BITMAP bitmap;
|
||||
|
||||
if (!gdi->memory_dc || !hbm)
|
||||
return;
|
||||
|
||||
hDCBits = CreateCompatibleDC(gdi->memory_dc);
|
||||
GetObject(hbm, sizeof(BITMAP), (LPSTR)&bitmap);
|
||||
SelectObject(hDCBits, hbm);
|
||||
StretchBlt(gdi->memory_dc, x, y, w, h, hDCBits, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
|
||||
DeleteDC(hDCBits);
|
||||
}
|
||||
|
||||
static COLORREF
|
||||
convert_color(struct nk_color c)
|
||||
{
|
||||
return c.r | (c.g << 8) | (c.b << 16);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_scissor(HDC dc, float x, float y, float w, float h)
|
||||
{
|
||||
SelectClipRgn(dc, NULL);
|
||||
IntersectClipRect(dc, (int)x, (int)y, (int)(x + w + 1), (int)(y + h + 1));
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_stroke_line(HDC dc, short x0, short y0, short x1,
|
||||
short y1, unsigned int line_thickness, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
|
||||
HPEN pen = NULL;
|
||||
if (line_thickness == 1) {
|
||||
SetDCPenColor(dc, color);
|
||||
}
|
||||
else {
|
||||
pen = CreatePen(PS_SOLID, line_thickness, color);
|
||||
SelectObject(dc, pen);
|
||||
}
|
||||
|
||||
MoveToEx(dc, x0, y0, NULL);
|
||||
LineTo(dc, x1, y1);
|
||||
|
||||
if (pen) {
|
||||
SelectObject(dc, GetStockObject(DC_PEN));
|
||||
DeleteObject(pen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_stroke_rect(HDC dc, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short r, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
HGDIOBJ br;
|
||||
HPEN pen = NULL;
|
||||
|
||||
if (line_thickness == 1) {
|
||||
SetDCPenColor(dc, color);
|
||||
}
|
||||
else {
|
||||
pen = CreatePen(PS_SOLID, line_thickness, color);
|
||||
SelectObject(dc, pen);
|
||||
}
|
||||
|
||||
br = SelectObject(dc, GetStockObject(NULL_BRUSH));
|
||||
if (r == 0) {
|
||||
Rectangle(dc, x, y, x + w, y + h);
|
||||
}
|
||||
else {
|
||||
RoundRect(dc, x, y, x + w, y + h, r, r);
|
||||
}
|
||||
SelectObject(dc, br);
|
||||
|
||||
if (pen) {
|
||||
SelectObject(dc, GetStockObject(DC_PEN));
|
||||
DeleteObject(pen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_fill_rect(HDC dc, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short r, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
|
||||
if (r == 0) {
|
||||
RECT rect;
|
||||
SetRect(&rect, x, y, x + w, y + h);
|
||||
SetBkColor(dc, color);
|
||||
ExtTextOutW(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
|
||||
}
|
||||
else {
|
||||
SetDCPenColor(dc, color);
|
||||
SetDCBrushColor(dc, color);
|
||||
RoundRect(dc, x, y, x + w, y + h, r, r);
|
||||
}
|
||||
}
|
||||
static void
|
||||
nk_gdi_set_vertexColor(PTRIVERTEX tri, struct nk_color col)
|
||||
{
|
||||
tri->Red = col.r << 8;
|
||||
tri->Green = col.g << 8;
|
||||
tri->Blue = col.b << 8;
|
||||
tri->Alpha = 0xff << 8;
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_rect_multi_color(nk_gdi_ctx gdi, HDC dc, short x, short y, unsigned short w,
|
||||
unsigned short h, struct nk_color left, struct nk_color top,
|
||||
struct nk_color right, struct nk_color bottom)
|
||||
{
|
||||
BLENDFUNCTION alphaFunction;
|
||||
// GRADIENT_RECT gRect;
|
||||
GRADIENT_TRIANGLE gTri[2];
|
||||
TRIVERTEX vt[4];
|
||||
alphaFunction.BlendOp = AC_SRC_OVER;
|
||||
alphaFunction.BlendFlags = 0;
|
||||
alphaFunction.SourceConstantAlpha = 0;
|
||||
alphaFunction.AlphaFormat = AC_SRC_ALPHA;
|
||||
|
||||
/* TODO: This Case Needs Repair.*/
|
||||
/* Top Left Corner */
|
||||
vt[0].x = x;
|
||||
vt[0].y = y;
|
||||
nk_gdi_set_vertexColor(&vt[0], left);
|
||||
/* Top Right Corner */
|
||||
vt[1].x = x + w;
|
||||
vt[1].y = y;
|
||||
nk_gdi_set_vertexColor(&vt[1], top);
|
||||
/* Bottom Left Corner */
|
||||
vt[2].x = x;
|
||||
vt[2].y = y + h;
|
||||
nk_gdi_set_vertexColor(&vt[2], right);
|
||||
|
||||
/* Bottom Right Corner */
|
||||
vt[3].x = x + w;
|
||||
vt[3].y = y + h;
|
||||
nk_gdi_set_vertexColor(&vt[3], bottom);
|
||||
|
||||
gTri[0].Vertex1 = 0;
|
||||
gTri[0].Vertex2 = 1;
|
||||
gTri[0].Vertex3 = 2;
|
||||
gTri[1].Vertex1 = 2;
|
||||
gTri[1].Vertex2 = 1;
|
||||
gTri[1].Vertex3 = 3;
|
||||
GdiGradientFill(dc, vt, 4, gTri, 2, GRADIENT_FILL_TRIANGLE);
|
||||
AlphaBlend(gdi->window_dc, x, y, x + w, y + h, gdi->memory_dc, x, y, x + w, y + h, alphaFunction);
|
||||
|
||||
}
|
||||
|
||||
static BOOL
|
||||
SetPoint(POINT* p, LONG x, LONG y)
|
||||
{
|
||||
if (!p)
|
||||
return FALSE;
|
||||
p->x = x;
|
||||
p->y = y;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_fill_triangle(HDC dc, short x0, short y0, short x1,
|
||||
short y1, short x2, short y2, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
POINT points[3];
|
||||
|
||||
SetPoint(&points[0], x0, y0);
|
||||
SetPoint(&points[1], x1, y1);
|
||||
SetPoint(&points[2], x2, y2);
|
||||
|
||||
SetDCPenColor(dc, color);
|
||||
SetDCBrushColor(dc, color);
|
||||
Polygon(dc, points, 3);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_stroke_triangle(HDC dc, short x0, short y0, short x1,
|
||||
short y1, short x2, short y2, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
POINT points[4];
|
||||
HPEN pen = NULL;
|
||||
|
||||
SetPoint(&points[0], x0, y0);
|
||||
SetPoint(&points[1], x1, y1);
|
||||
SetPoint(&points[2], x2, y2);
|
||||
SetPoint(&points[3], x0, y0);
|
||||
|
||||
if (line_thickness == 1) {
|
||||
SetDCPenColor(dc, color);
|
||||
}
|
||||
else {
|
||||
pen = CreatePen(PS_SOLID, line_thickness, color);
|
||||
SelectObject(dc, pen);
|
||||
}
|
||||
|
||||
Polyline(dc, points, 4);
|
||||
|
||||
if (pen) {
|
||||
SelectObject(dc, GetStockObject(DC_PEN));
|
||||
DeleteObject(pen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_fill_polygon(HDC dc, const struct nk_vec2i* pnts, int count, struct nk_color col)
|
||||
{
|
||||
int i = 0;
|
||||
#define MAX_POINTS 64
|
||||
POINT points[MAX_POINTS];
|
||||
COLORREF color = convert_color(col);
|
||||
SetDCBrushColor(dc, color);
|
||||
SetDCPenColor(dc, color);
|
||||
for (i = 0; i < count && i < MAX_POINTS; ++i) {
|
||||
points[i].x = pnts[i].x;
|
||||
points[i].y = pnts[i].y;
|
||||
}
|
||||
Polygon(dc, points, i);
|
||||
#undef MAX_POINTS
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_stroke_polygon(HDC dc, const struct nk_vec2i* pnts, int count,
|
||||
unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
HPEN pen = NULL;
|
||||
if (line_thickness == 1) {
|
||||
SetDCPenColor(dc, color);
|
||||
}
|
||||
else {
|
||||
pen = CreatePen(PS_SOLID, line_thickness, color);
|
||||
SelectObject(dc, pen);
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
int i;
|
||||
MoveToEx(dc, pnts[0].x, pnts[0].y, NULL);
|
||||
for (i = 1; i < count; ++i)
|
||||
LineTo(dc, pnts[i].x, pnts[i].y);
|
||||
LineTo(dc, pnts[0].x, pnts[0].y);
|
||||
}
|
||||
|
||||
if (pen) {
|
||||
SelectObject(dc, GetStockObject(DC_PEN));
|
||||
DeleteObject(pen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_stroke_polyline(HDC dc, const struct nk_vec2i* pnts,
|
||||
int count, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
HPEN pen = NULL;
|
||||
if (line_thickness == 1) {
|
||||
SetDCPenColor(dc, color);
|
||||
}
|
||||
else {
|
||||
pen = CreatePen(PS_SOLID, line_thickness, color);
|
||||
SelectObject(dc, pen);
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
int i;
|
||||
MoveToEx(dc, pnts[0].x, pnts[0].y, NULL);
|
||||
for (i = 1; i < count; ++i)
|
||||
LineTo(dc, pnts[i].x, pnts[i].y);
|
||||
}
|
||||
|
||||
if (pen) {
|
||||
SelectObject(dc, GetStockObject(DC_PEN));
|
||||
DeleteObject(pen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_fill_circle(HDC dc, short x, short y, unsigned short w,
|
||||
unsigned short h, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
SetDCBrushColor(dc, color);
|
||||
SetDCPenColor(dc, color);
|
||||
Ellipse(dc, x, y, x + w, y + h);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_stroke_circle(HDC dc, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
HPEN pen = NULL;
|
||||
if (line_thickness == 1) {
|
||||
SetDCPenColor(dc, color);
|
||||
}
|
||||
else {
|
||||
pen = CreatePen(PS_SOLID, line_thickness, color);
|
||||
SelectObject(dc, pen);
|
||||
}
|
||||
|
||||
SetDCBrushColor(dc, OPAQUE);
|
||||
Ellipse(dc, x, y, x + w, y + h);
|
||||
|
||||
if (pen) {
|
||||
SelectObject(dc, GetStockObject(DC_PEN));
|
||||
DeleteObject(pen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_stroke_curve(HDC dc, struct nk_vec2i p1,
|
||||
struct nk_vec2i p2, struct nk_vec2i p3, struct nk_vec2i p4,
|
||||
unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
POINT p[4];
|
||||
HPEN pen = NULL;
|
||||
|
||||
SetPoint(&p[0], p1.x, p1.y);
|
||||
SetPoint(&p[1], p2.x, p2.y);
|
||||
SetPoint(&p[2], p3.x, p3.y);
|
||||
SetPoint(&p[3], p4.x, p4.y);
|
||||
|
||||
if (line_thickness == 1) {
|
||||
SetDCPenColor(dc, color);
|
||||
}
|
||||
else {
|
||||
pen = CreatePen(PS_SOLID, line_thickness, color);
|
||||
SelectObject(dc, pen);
|
||||
}
|
||||
|
||||
SetDCBrushColor(dc, OPAQUE);
|
||||
PolyBezier(dc, p, 4);
|
||||
|
||||
if (pen) {
|
||||
SelectObject(dc, GetStockObject(DC_PEN));
|
||||
DeleteObject(pen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_draw_text(HDC dc, short x, short y, unsigned short w, unsigned short h,
|
||||
const char* text, int len, GdiFont* font, struct nk_color cbg, struct nk_color cfg)
|
||||
{
|
||||
int wsize;
|
||||
WCHAR* wstr;
|
||||
|
||||
if (!text || !font || !len) return;
|
||||
|
||||
wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
|
||||
wstr = (WCHAR*)_alloca(wsize * sizeof(wchar_t));
|
||||
MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
|
||||
|
||||
SetBkColor(dc, convert_color(cbg));
|
||||
SetTextColor(dc, convert_color(cfg));
|
||||
|
||||
SelectObject(dc, font->handle);
|
||||
ExtTextOutW(dc, x, y, ETO_OPAQUE, NULL, wstr, wsize, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_clear(nk_gdi_ctx gdi, HDC dc, struct nk_color col)
|
||||
{
|
||||
COLORREF color = convert_color(col);
|
||||
RECT rect;
|
||||
SetRect(&rect, 0, 0, gdi->width, gdi->height);
|
||||
SetBkColor(dc, color);
|
||||
|
||||
ExtTextOutW(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_blit(nk_gdi_ctx gdi, HDC dc)
|
||||
{
|
||||
BitBlt(dc, 0, 0, gdi->width, gdi->height, gdi->memory_dc, 0, 0, SRCCOPY);
|
||||
|
||||
}
|
||||
|
||||
GdiFont*
|
||||
nk_gdifont_create(const char* name, int size)
|
||||
{
|
||||
TEXTMETRICW metric;
|
||||
GdiFont* font = (GdiFont*)calloc(1, sizeof(GdiFont));
|
||||
if (!font)
|
||||
return NULL;
|
||||
font->dc = CreateCompatibleDC(0);
|
||||
font->handle = CreateFontA(size, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, name);
|
||||
SelectObject(font->dc, font->handle);
|
||||
GetTextMetricsW(font->dc, &metric);
|
||||
font->height = metric.tmHeight;
|
||||
return font;
|
||||
}
|
||||
|
||||
static float
|
||||
nk_gdifont_get_text_width(nk_handle handle, float height, const char* text, int len)
|
||||
{
|
||||
GdiFont* font = (GdiFont*)handle.ptr;
|
||||
SIZE size;
|
||||
int wsize;
|
||||
WCHAR* wstr;
|
||||
if (!font || !text)
|
||||
return 0;
|
||||
|
||||
wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
|
||||
wstr = (WCHAR*)_alloca(wsize * sizeof(wchar_t));
|
||||
MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
|
||||
if (GetTextExtentPoint32W(font->dc, wstr, wsize, &size))
|
||||
return (float)size.cx;
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
void
|
||||
nk_gdifont_del(GdiFont* font)
|
||||
{
|
||||
if (!font) return;
|
||||
DeleteObject(font->handle);
|
||||
DeleteDC(font->dc);
|
||||
free(font);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_clipboard_paste(nk_handle usr, struct nk_text_edit* edit)
|
||||
{
|
||||
(void)usr;
|
||||
if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL))
|
||||
{
|
||||
HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
|
||||
if (mem)
|
||||
{
|
||||
SIZE_T size = GlobalSize(mem) - 1;
|
||||
if (size)
|
||||
{
|
||||
LPCWSTR wstr = (LPCWSTR)GlobalLock(mem);
|
||||
if (wstr)
|
||||
{
|
||||
int utf8size = WideCharToMultiByte(CP_UTF8, 0, wstr, (int)(size / sizeof(wchar_t)), NULL, 0, NULL, NULL);
|
||||
if (utf8size)
|
||||
{
|
||||
char* utf8 = (char*)malloc(utf8size);
|
||||
if (utf8)
|
||||
{
|
||||
WideCharToMultiByte(CP_UTF8, 0, wstr, (int)(size / sizeof(wchar_t)), utf8, utf8size, NULL, NULL);
|
||||
nk_textedit_paste(edit, utf8, utf8size);
|
||||
free(utf8);
|
||||
}
|
||||
}
|
||||
GlobalUnlock(mem);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdi_clipboard_copy(nk_handle usr, const char* text, int len)
|
||||
{
|
||||
if (OpenClipboard(NULL))
|
||||
{
|
||||
int wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
|
||||
if (wsize)
|
||||
{
|
||||
HGLOBAL mem = (HGLOBAL)GlobalAlloc(GMEM_MOVEABLE, (wsize + 1) * sizeof(wchar_t));
|
||||
if (mem)
|
||||
{
|
||||
wchar_t* wstr = (wchar_t*)GlobalLock(mem);
|
||||
if (wstr)
|
||||
{
|
||||
MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
|
||||
wstr[wsize] = 0;
|
||||
GlobalUnlock(mem);
|
||||
|
||||
SetClipboardData(CF_UNICODETEXT, mem);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
}
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_gdi_init(nk_gdi_ctx* gdi, GdiFont* gdifont, HDC window_dc, unsigned int width, unsigned int height)
|
||||
{
|
||||
*gdi = (nk_gdi_ctx)malloc(sizeof(struct _nk_gdi_ctx));
|
||||
|
||||
struct nk_user_font* font = &gdifont->nk;
|
||||
font->userdata = nk_handle_ptr(gdifont);
|
||||
font->height = (float)gdifont->height;
|
||||
font->width = nk_gdifont_get_text_width;
|
||||
|
||||
(*gdi)->bitmap = CreateCompatibleBitmap(window_dc, width, height);
|
||||
(*gdi)->window_dc = window_dc;
|
||||
(*gdi)->memory_dc = CreateCompatibleDC(window_dc);
|
||||
(*gdi)->width = width;
|
||||
(*gdi)->height = height;
|
||||
SelectObject((*gdi)->memory_dc, (*gdi)->bitmap);
|
||||
|
||||
nk_init_default(&(*gdi)->ctx, font);
|
||||
(*gdi)->ctx.clip.copy = nk_gdi_clipboard_copy;
|
||||
(*gdi)->ctx.clip.paste = nk_gdi_clipboard_paste;
|
||||
return &(*gdi)->ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_gdi_set_font(nk_gdi_ctx gdi, GdiFont* gdifont)
|
||||
{
|
||||
struct nk_user_font* font = &gdifont->nk;
|
||||
font->userdata = nk_handle_ptr(gdifont);
|
||||
font->height = (float)gdifont->height;
|
||||
font->width = nk_gdifont_get_text_width;
|
||||
nk_style_set_font(&gdi->ctx, font);
|
||||
}
|
||||
|
||||
NK_API int
|
||||
nk_gdi_handle_event(nk_gdi_ctx gdi, HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_SIZE:
|
||||
{
|
||||
unsigned width = LOWORD(lparam);
|
||||
unsigned height = HIWORD(lparam);
|
||||
if (width != gdi->width || height != gdi->height)
|
||||
{
|
||||
DeleteObject(gdi->bitmap);
|
||||
gdi->bitmap = CreateCompatibleBitmap(gdi->window_dc, width, height);
|
||||
gdi->width = width;
|
||||
gdi->height = height;
|
||||
SelectObject(gdi->memory_dc, gdi->bitmap);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT paint;
|
||||
HDC dc = BeginPaint(wnd, &paint);
|
||||
nk_gdi_blit(gdi, dc);
|
||||
EndPaint(wnd, &paint);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
int down = !((lparam >> 31) & 1);
|
||||
int ctrl = GetKeyState(VK_CONTROL) & (1 << 15);
|
||||
|
||||
switch (wparam)
|
||||
{
|
||||
case VK_SHIFT:
|
||||
case VK_LSHIFT:
|
||||
case VK_RSHIFT:
|
||||
nk_input_key(&gdi->ctx, NK_KEY_SHIFT, down);
|
||||
return 1;
|
||||
|
||||
case VK_DELETE:
|
||||
nk_input_key(&gdi->ctx, NK_KEY_DEL, down);
|
||||
return 1;
|
||||
|
||||
case VK_RETURN:
|
||||
nk_input_key(&gdi->ctx, NK_KEY_ENTER, down);
|
||||
return 1;
|
||||
|
||||
case VK_TAB:
|
||||
nk_input_key(&gdi->ctx, NK_KEY_TAB, down);
|
||||
return 1;
|
||||
|
||||
case VK_LEFT:
|
||||
if (ctrl)
|
||||
nk_input_key(&gdi->ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else
|
||||
nk_input_key(&gdi->ctx, NK_KEY_LEFT, down);
|
||||
return 1;
|
||||
|
||||
case VK_RIGHT:
|
||||
if (ctrl)
|
||||
nk_input_key(&gdi->ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else
|
||||
nk_input_key(&gdi->ctx, NK_KEY_RIGHT, down);
|
||||
return 1;
|
||||
|
||||
case VK_BACK:
|
||||
nk_input_key(&gdi->ctx, NK_KEY_BACKSPACE, down);
|
||||
return 1;
|
||||
|
||||
case VK_HOME:
|
||||
nk_input_key(&gdi->ctx, NK_KEY_TEXT_START, down);
|
||||
nk_input_key(&gdi->ctx, NK_KEY_SCROLL_START, down);
|
||||
return 1;
|
||||
|
||||
case VK_END:
|
||||
nk_input_key(&gdi->ctx, NK_KEY_TEXT_END, down);
|
||||
nk_input_key(&gdi->ctx, NK_KEY_SCROLL_END, down);
|
||||
return 1;
|
||||
|
||||
case VK_NEXT:
|
||||
nk_input_key(&gdi->ctx, NK_KEY_SCROLL_DOWN, down);
|
||||
return 1;
|
||||
|
||||
case VK_PRIOR:
|
||||
nk_input_key(&gdi->ctx, NK_KEY_SCROLL_UP, down);
|
||||
return 1;
|
||||
|
||||
case 'C':
|
||||
if (ctrl) {
|
||||
nk_input_key(&gdi->ctx, NK_KEY_COPY, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
if (ctrl) {
|
||||
nk_input_key(&gdi->ctx, NK_KEY_PASTE, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
if (ctrl) {
|
||||
nk_input_key(&gdi->ctx, NK_KEY_CUT, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
if (ctrl) {
|
||||
nk_input_key(&gdi->ctx, NK_KEY_TEXT_UNDO, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
if (ctrl) {
|
||||
nk_input_key(&gdi->ctx, NK_KEY_TEXT_REDO, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_CHAR:
|
||||
if (wparam >= 32)
|
||||
{
|
||||
nk_input_unicode(&gdi->ctx, (nk_rune)wparam);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
nk_input_button(&gdi->ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
|
||||
SetCapture(wnd);
|
||||
return 1;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
nk_input_button(&gdi->ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
|
||||
nk_input_button(&gdi->ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
|
||||
ReleaseCapture();
|
||||
return 1;
|
||||
|
||||
case WM_RBUTTONDOWN:
|
||||
nk_input_button(&gdi->ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
|
||||
SetCapture(wnd);
|
||||
return 1;
|
||||
|
||||
case WM_RBUTTONUP:
|
||||
nk_input_button(&gdi->ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
|
||||
ReleaseCapture();
|
||||
return 1;
|
||||
|
||||
case WM_MBUTTONDOWN:
|
||||
nk_input_button(&gdi->ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
|
||||
SetCapture(wnd);
|
||||
return 1;
|
||||
|
||||
case WM_MBUTTONUP:
|
||||
nk_input_button(&gdi->ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
|
||||
ReleaseCapture();
|
||||
return 1;
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
nk_input_scroll(&gdi->ctx, nk_vec2(0, (float)(short)HIWORD(wparam) / WHEEL_DELTA));
|
||||
return 1;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
nk_input_motion(&gdi->ctx, (short)LOWORD(lparam), (short)HIWORD(lparam));
|
||||
return 1;
|
||||
|
||||
case WM_LBUTTONDBLCLK:
|
||||
nk_input_button(&gdi->ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_gdi_shutdown(nk_gdi_ctx gdi)
|
||||
{
|
||||
DeleteObject(gdi->memory_dc);
|
||||
DeleteObject(gdi->bitmap);
|
||||
nk_free(&gdi->ctx);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_gdi_render(nk_gdi_ctx gdi, struct nk_color clear)
|
||||
{
|
||||
const struct nk_command* cmd;
|
||||
|
||||
HDC memory_dc = gdi->memory_dc;
|
||||
SelectObject(memory_dc, GetStockObject(DC_PEN));
|
||||
SelectObject(memory_dc, GetStockObject(DC_BRUSH));
|
||||
nk_gdi_clear(gdi, memory_dc, clear);
|
||||
|
||||
nk_foreach(cmd, &gdi->ctx)
|
||||
{
|
||||
switch (cmd->type) {
|
||||
case NK_COMMAND_NOP: break;
|
||||
case NK_COMMAND_SCISSOR: {
|
||||
const struct nk_command_scissor* s = (const struct nk_command_scissor*)cmd;
|
||||
nk_gdi_scissor(memory_dc, s->x, s->y, s->w, s->h);
|
||||
} break;
|
||||
case NK_COMMAND_LINE: {
|
||||
const struct nk_command_line* l = (const struct nk_command_line*)cmd;
|
||||
nk_gdi_stroke_line(memory_dc, l->begin.x, l->begin.y, l->end.x,
|
||||
l->end.y, l->line_thickness, l->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT: {
|
||||
const struct nk_command_rect* r = (const struct nk_command_rect*)cmd;
|
||||
nk_gdi_stroke_rect(memory_dc, r->x, r->y, r->w, r->h,
|
||||
(unsigned short)r->rounding, r->line_thickness, r->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_FILLED: {
|
||||
const struct nk_command_rect_filled* r = (const struct nk_command_rect_filled*)cmd;
|
||||
nk_gdi_fill_rect(memory_dc, r->x, r->y, r->w, r->h,
|
||||
(unsigned short)r->rounding, r->color);
|
||||
} break;
|
||||
case NK_COMMAND_CIRCLE: {
|
||||
const struct nk_command_circle* c = (const struct nk_command_circle*)cmd;
|
||||
nk_gdi_stroke_circle(memory_dc, c->x, c->y, c->w, c->h, c->line_thickness, c->color);
|
||||
} break;
|
||||
case NK_COMMAND_CIRCLE_FILLED: {
|
||||
const struct nk_command_circle_filled* c = (const struct nk_command_circle_filled*)cmd;
|
||||
nk_gdi_fill_circle(memory_dc, c->x, c->y, c->w, c->h, c->color);
|
||||
} break;
|
||||
case NK_COMMAND_TRIANGLE: {
|
||||
const struct nk_command_triangle* t = (const struct nk_command_triangle*)cmd;
|
||||
nk_gdi_stroke_triangle(memory_dc, t->a.x, t->a.y, t->b.x, t->b.y,
|
||||
t->c.x, t->c.y, t->line_thickness, t->color);
|
||||
} break;
|
||||
case NK_COMMAND_TRIANGLE_FILLED: {
|
||||
const struct nk_command_triangle_filled* t = (const struct nk_command_triangle_filled*)cmd;
|
||||
nk_gdi_fill_triangle(memory_dc, t->a.x, t->a.y, t->b.x, t->b.y,
|
||||
t->c.x, t->c.y, t->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYGON: {
|
||||
const struct nk_command_polygon* p = (const struct nk_command_polygon*)cmd;
|
||||
nk_gdi_stroke_polygon(memory_dc, p->points, p->point_count, p->line_thickness, p->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYGON_FILLED: {
|
||||
const struct nk_command_polygon_filled* p = (const struct nk_command_polygon_filled*)cmd;
|
||||
nk_gdi_fill_polygon(memory_dc, p->points, p->point_count, p->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYLINE: {
|
||||
const struct nk_command_polyline* p = (const struct nk_command_polyline*)cmd;
|
||||
nk_gdi_stroke_polyline(memory_dc, p->points, p->point_count, p->line_thickness, p->color);
|
||||
} break;
|
||||
case NK_COMMAND_TEXT: {
|
||||
const struct nk_command_text* t = (const struct nk_command_text*)cmd;
|
||||
nk_gdi_draw_text(memory_dc, t->x, t->y, t->w, t->h,
|
||||
(const char*)t->string, t->length,
|
||||
(GdiFont*)t->font->userdata.ptr,
|
||||
t->background, t->foreground);
|
||||
} break;
|
||||
case NK_COMMAND_CURVE: {
|
||||
const struct nk_command_curve* q = (const struct nk_command_curve*)cmd;
|
||||
nk_gdi_stroke_curve(memory_dc, q->begin, q->ctrl[0], q->ctrl[1],
|
||||
q->end, q->line_thickness, q->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_MULTI_COLOR: {
|
||||
const struct nk_command_rect_multi_color* r = (const struct nk_command_rect_multi_color*)cmd;
|
||||
nk_gdi_rect_multi_color(gdi, memory_dc, r->x, r->y, r->w, r->h, r->left, r->top, r->right, r->bottom);
|
||||
} break;
|
||||
case NK_COMMAND_IMAGE: {
|
||||
const struct nk_command_image* i = (const struct nk_command_image*)cmd;
|
||||
nk_gdi_draw_image(gdi, i->x, i->y, i->w, i->h, i->img, i->col);
|
||||
} break;
|
||||
case NK_COMMAND_ARC:
|
||||
case NK_COMMAND_ARC_FILLED:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
nk_gdi_blit(gdi, gdi->window_dc);
|
||||
nk_clear(&gdi->ctx);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,387 @@
|
|||
#ifndef NK_GDI_WINDOW
|
||||
#define NK_GDI_WINDOW
|
||||
|
||||
#define NK_GDI_WINDOW_CLS L"WNDCLS_NkGdi"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* Functin pointer types for window callbacks */
|
||||
typedef int(*nkgdi_window_func_close)(void);
|
||||
typedef int(*nkgdi_window_func_draw)(struct nk_context*);
|
||||
|
||||
/* Window container / context */
|
||||
struct nkgdi_window
|
||||
{
|
||||
/* The window can be sized */
|
||||
int allow_sizing;
|
||||
/* The window can be maximized by double clicking the titlebar */
|
||||
int allow_maximize;
|
||||
/* The window is allowed to be moved by the user */
|
||||
int allow_move;
|
||||
/* The window will render it's title bar */
|
||||
int has_titlebar;
|
||||
|
||||
/* Callbacks */
|
||||
/* Called when the user or os requests a window close (return 1 to accept the reqest)*/
|
||||
nkgdi_window_func_close cb_on_close;
|
||||
/* Called each time the window content should be drawn. Here you will do your nuklear drawing code
|
||||
* but WITHOUT nk_begin and nk_end. Return 1 to keep the window open.
|
||||
*/
|
||||
nkgdi_window_func_draw cb_on_draw;
|
||||
|
||||
/* Internal Data */
|
||||
struct
|
||||
{
|
||||
/* Window handle */
|
||||
HWND window_handle;
|
||||
|
||||
/* Nuklear & GDI context */
|
||||
nk_gdi_ctx nk_gdi_ctx;
|
||||
struct nk_context* nk_ctx;
|
||||
|
||||
/* GDI required objects */
|
||||
GdiFont* gdi_font;
|
||||
HDC window_dc;
|
||||
|
||||
/* Internally used state variables */
|
||||
int is_open;
|
||||
int is_draggin;
|
||||
int ws_override;
|
||||
int is_maximized;
|
||||
POINT drag_offset;
|
||||
int width;
|
||||
int height;
|
||||
}_internal;
|
||||
};
|
||||
|
||||
/* API */
|
||||
/* This function will init all resources used by the implementation */
|
||||
void nkgdi_window_init(void);
|
||||
/* This function will free all globally used resources */
|
||||
void nkgdi_window_shutdown(void);
|
||||
/* Creates a new window (for the wnd context) */
|
||||
void nkgdi_window_create(struct nkgdi_window* wnd, unsigned int width, unsigned int height, const char* name, int posX, int posY);
|
||||
/* Updates the window (Windows message loop, nuklear loop and drawing). Returns one as long as the window is valid and open */
|
||||
int nkgdi_window_update(struct nkgdi_window* wnd);
|
||||
/* Destroys the window context wnd */
|
||||
void nkgdi_window_destroy(struct nkgdi_window* wnd);
|
||||
|
||||
#ifdef NKGDI_IMPLEMENT_WINDOW
|
||||
|
||||
/* Predeclare the windows window message procs */
|
||||
/* This proc will setup the pointer to the window context */
|
||||
LRESULT nkgdi_window_proc_setup(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
/* This proc will take the window context pointer and performs operations on it*/
|
||||
LRESULT nkgdi_window_proc_run(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void nkgdi_window_init(void)
|
||||
{
|
||||
/* Describe the window class */
|
||||
WNDCLASSEXW cls;
|
||||
cls.cbSize = sizeof(WNDCLASSEXW);
|
||||
cls.style = CS_OWNDC | CS_DBLCLKS;
|
||||
cls.lpfnWndProc = &nkgdi_window_proc_setup;
|
||||
cls.cbClsExtra = 0;
|
||||
cls.cbWndExtra = 0;
|
||||
cls.hInstance = GetModuleHandle(NULL);
|
||||
cls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
cls.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
cls.hbrBackground = NULL;
|
||||
cls.lpszMenuName = NULL;
|
||||
cls.lpszClassName = NK_GDI_WINDOW_CLS;
|
||||
cls.hIconSm = NULL;
|
||||
|
||||
/* Register the window class */
|
||||
RegisterClassExW(&cls);
|
||||
}
|
||||
|
||||
void nkgdi_window_shutdown(void)
|
||||
{
|
||||
/* Windows class no longer required, unregister it */
|
||||
UnregisterClassW(NK_GDI_WINDOW_CLS, GetModuleHandle(NULL));
|
||||
}
|
||||
|
||||
void nkgdi_window_create(struct nkgdi_window* wnd, unsigned int width, unsigned int height, const char* name, int posX, int posY)
|
||||
{
|
||||
DWORD styleEx = WS_EX_WINDOWEDGE;
|
||||
DWORD style = WS_POPUP;
|
||||
|
||||
/* Adjust window size to fit selected window styles */
|
||||
RECT cr;
|
||||
cr.left = 0;
|
||||
cr.top = 0;
|
||||
cr.right = width;
|
||||
cr.bottom = height;
|
||||
AdjustWindowRectEx(&cr, style, FALSE, styleEx);
|
||||
|
||||
/* Create the new window */
|
||||
wnd->_internal.window_handle = CreateWindowExW(
|
||||
styleEx,
|
||||
NK_GDI_WINDOW_CLS,
|
||||
L"NkGdi",
|
||||
style | WS_VISIBLE,
|
||||
posX, posY,
|
||||
cr.right - cr.left, cr.bottom - cr.top,
|
||||
NULL, NULL,
|
||||
GetModuleHandleW(NULL),
|
||||
wnd
|
||||
);
|
||||
|
||||
/* Give the window the ascii char name */
|
||||
SetWindowTextA(wnd->_internal.window_handle, name);
|
||||
|
||||
/* Extract the window dc for gdi drawing */
|
||||
wnd->_internal.window_dc = GetWindowDC(wnd->_internal.window_handle);
|
||||
|
||||
/* Create the gdi font required to draw text */
|
||||
wnd->_internal.gdi_font = nk_gdifont_create("Arial", 16);
|
||||
|
||||
/* Init the gdi backend */
|
||||
wnd->_internal.nk_ctx = nk_gdi_init(&wnd->_internal.nk_gdi_ctx, wnd->_internal.gdi_font, wnd->_internal.window_dc, width, height);
|
||||
|
||||
/* Bring all internal variables to a defined and valid initial state */
|
||||
wnd->_internal.is_open = 1;
|
||||
wnd->_internal.is_draggin = 0;
|
||||
wnd->_internal.ws_override = 0;
|
||||
wnd->_internal.is_maximized = 0;
|
||||
wnd->_internal.drag_offset.x = 0;
|
||||
wnd->_internal.drag_offset.y = 0;
|
||||
wnd->_internal.width = width;
|
||||
wnd->_internal.height = height;
|
||||
}
|
||||
|
||||
void nkgdi_window_destroy(struct nkgdi_window* wnd)
|
||||
{
|
||||
/* Destroy all objects in reverse order */
|
||||
if (wnd->_internal.nk_gdi_ctx)
|
||||
{
|
||||
nk_gdi_shutdown(wnd->_internal.nk_gdi_ctx);
|
||||
}
|
||||
if (wnd->_internal.gdi_font)
|
||||
{
|
||||
nk_gdifont_del(wnd->_internal.gdi_font);
|
||||
}
|
||||
if (wnd->_internal.window_dc)
|
||||
{
|
||||
ReleaseDC(wnd->_internal.window_handle, wnd->_internal.window_dc);
|
||||
}
|
||||
if (wnd->_internal.window_handle)
|
||||
{
|
||||
CloseWindow(wnd->_internal.window_handle);
|
||||
DestroyWindow(wnd->_internal.window_handle);
|
||||
}
|
||||
}
|
||||
|
||||
int nkgdi_window_update(struct nkgdi_window* wnd)
|
||||
{
|
||||
/* The window will only be updated when it is open / valid */
|
||||
if (wnd->_internal.is_open)
|
||||
{
|
||||
/* First all pending window events will be processed */
|
||||
MSG msg;
|
||||
nk_input_begin(wnd->_internal.nk_ctx);
|
||||
while (PeekMessage(&msg, wnd->_internal.window_handle, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
nk_input_end(wnd->_internal.nk_ctx);
|
||||
|
||||
/* To setup the nuklear window we need the windows title */
|
||||
char title[1024];
|
||||
GetWindowTextA(wnd->_internal.window_handle, title, 1024);
|
||||
|
||||
/* The nk window flags are beeing create based on the context setup */
|
||||
nk_flags window_flags = NK_WINDOW_BORDER;
|
||||
if(wnd->has_titlebar)
|
||||
window_flags |= NK_WINDOW_CLOSABLE | NK_WINDOW_TITLE;
|
||||
if(!wnd->_internal.is_maximized && wnd->allow_sizing)
|
||||
window_flags |= NK_WINDOW_SCALABLE;
|
||||
|
||||
/* Override the nuklear windows size when required */
|
||||
if (wnd->_internal.ws_override)
|
||||
nk_window_set_bounds(wnd->_internal.nk_ctx, title, nk_rect(0, 0, wnd->_internal.width, wnd->_internal.height));
|
||||
|
||||
/* Start the nuklear window */
|
||||
if (nk_begin(wnd->_internal.nk_ctx, title, nk_rect(0, 0, wnd->_internal.width, wnd->_internal.height), window_flags))
|
||||
{
|
||||
/* Call user drawing callback */
|
||||
if(wnd->cb_on_draw && !wnd->cb_on_draw(wnd->_internal.nk_ctx))
|
||||
wnd->_internal.is_open = 0;
|
||||
|
||||
/* Update the windows window to reflect the nuklear windows size */
|
||||
struct nk_rect bounds = nk_window_get_bounds(wnd->_internal.nk_ctx);
|
||||
if(bounds.w != wnd->_internal.width || bounds.h != wnd->_internal.height)
|
||||
SetWindowPos(wnd->_internal.window_handle, NULL, 0, 0, bounds.w, bounds.h, SWP_NOMOVE | SWP_NOOWNERZORDER);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nuklear window was closed. Handle close internally */
|
||||
if(!wnd->cb_on_close || wnd->cb_on_close())
|
||||
wnd->_internal.is_open = 0;
|
||||
}
|
||||
nk_end(wnd->_internal.nk_ctx);
|
||||
|
||||
/* We no longer need the window size override flag to be set */
|
||||
wnd->_internal.ws_override = 0;
|
||||
|
||||
/* Pass context to the nuklear gdi renderer */
|
||||
nk_gdi_render(wnd->_internal.nk_gdi_ctx, nk_rgb(0, 0, 0));
|
||||
}
|
||||
|
||||
return wnd->_internal.is_open;
|
||||
}
|
||||
|
||||
LRESULT nkgdi_window_proc_setup(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
/* Waiting to receive the NCCREATE message with the custom window data */
|
||||
if (msg == WM_NCCREATE)
|
||||
{
|
||||
/* Extracting the window context from message parameters */
|
||||
CREATESTRUCT* ptrCr = (CREATESTRUCT*)lParam;
|
||||
struct nkgdi_window* nkgdi_wnd = (struct nkgdi_window*)ptrCr->lpCreateParams;
|
||||
|
||||
/* Store the context in the window and redirect any further message to the run window proc*/
|
||||
SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)nkgdi_wnd);
|
||||
SetWindowLongPtr(wnd, GWLP_WNDPROC, (LONG_PTR)&nkgdi_window_proc_run);
|
||||
|
||||
/* Already call the run proc so that it gets the chance to handle NCCREATE as well */
|
||||
return nkgdi_window_proc_run(wnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
/* Until we get WM_NCCREATE windows is going to handle the messages */
|
||||
return DefWindowProc(wnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
LRESULT nkgdi_window_proc_run(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
/* The window context is extracted from the window data */
|
||||
struct nkgdi_window* nkwnd = (struct nkgdi_window*)GetWindowLongPtrW(wnd, GWLP_USERDATA);
|
||||
|
||||
/* Switch on the message code to handle all required messages */
|
||||
switch (msg)
|
||||
{
|
||||
/* Window close event */
|
||||
case WM_CLOSE:
|
||||
/* Call custom close callback */
|
||||
if(!nkwnd->cb_on_close || nkwnd->cb_on_close())
|
||||
nkwnd->_internal.is_open = 0;
|
||||
return 0; /* No default behaviour. We do it our own way */
|
||||
|
||||
/* Window sizing event (is currently beeing sized) */
|
||||
case WM_SIZING:
|
||||
{
|
||||
/* Size of the client / active are is extracted and stored */
|
||||
RECT cr;
|
||||
GetClientRect(wnd, &cr);
|
||||
nkwnd->_internal.width = cr.right - cr.left;
|
||||
nkwnd->_internal.height = cr.bottom - cr.top;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Window size event (done sizing, maximize, minimize, ...) */
|
||||
case WM_SIZE:
|
||||
{
|
||||
/* Window was maximized */
|
||||
if (wParam == SIZE_MAXIMIZED)
|
||||
{
|
||||
/* Get the nearest monitor and retrive its details */
|
||||
HMONITOR monitor = MonitorFromWindow(wnd, MONITOR_DEFAULTTOPRIMARY);
|
||||
MONITORINFO monitorInfo;
|
||||
monitorInfo.cbSize = sizeof(MONITORINFO);
|
||||
if (GetMonitorInfoW(monitor, &monitorInfo))
|
||||
{
|
||||
/* Adjust the window size and position by the monitor working area (without taskbar) */
|
||||
nkwnd->_internal.height = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
|
||||
nkwnd->_internal.width = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
|
||||
nkwnd->_internal.ws_override = 1; /* Sizing was done without nuklear beeing aware. So we need to override it */
|
||||
nkwnd->_internal.is_maximized = 1;
|
||||
SetWindowPos(wnd, NULL, 0, 0, nkwnd->_internal.width, nkwnd->_internal.height, SWP_NOMOVE | SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
/* Window was restored (no longer maximized) */
|
||||
else if (wParam == SIZE_RESTORED)
|
||||
{
|
||||
nkwnd->_internal.is_maximized = 0;
|
||||
}
|
||||
|
||||
/* Always get the new bounds of the window */
|
||||
RECT cr;
|
||||
GetClientRect(wnd, &cr);
|
||||
nkwnd->_internal.width = cr.right - cr.left;
|
||||
nkwnd->_internal.height = cr.bottom - cr.top;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Mouse started left click */
|
||||
case WM_LBUTTONDOWN:
|
||||
{
|
||||
/* Handle dragging when allowed, has titlebar and mouse is in titlebar (Y <= 30) */
|
||||
if (HIWORD(lParam) <= 30 && nkwnd->allow_move && nkwnd->has_titlebar)
|
||||
{
|
||||
/* Mark dragging internally and store mouse click offset */
|
||||
nkwnd->_internal.is_draggin = 1;
|
||||
nkwnd->_internal.drag_offset.x = LOWORD(lParam);
|
||||
nkwnd->_internal.drag_offset.y = HIWORD(lParam);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Mouse stoped left click */
|
||||
case WM_LBUTTONUP:
|
||||
/* No longer dragging the window */
|
||||
nkwnd->_internal.is_draggin = 0;
|
||||
break;
|
||||
|
||||
/* Mouse is moving on the window */
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
/* When we are dragging and are not maximized process dragging */
|
||||
if (nkwnd->_internal.is_draggin && !nkwnd->_internal.is_maximized)
|
||||
{
|
||||
/* Get the current global position of the mouse */
|
||||
POINT cursorPos;
|
||||
GetCursorPos(&cursorPos);
|
||||
/* Substract the internal offset */
|
||||
cursorPos.x -= nkwnd->_internal.drag_offset.x;
|
||||
cursorPos.y -= nkwnd->_internal.drag_offset.y;
|
||||
/* Update position of out window and make sure window is in a movable state (= Restored) */
|
||||
ShowWindow(wnd, SW_RESTORE);
|
||||
SetWindowPos(wnd, NULL, cursorPos.x, cursorPos.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Mouse double clicked */
|
||||
case WM_LBUTTONDBLCLK:
|
||||
{
|
||||
/* Will only affect window when on the titlebar */
|
||||
if (HIWORD(lParam) <= 30 && nkwnd->allow_maximize && nkwnd->has_titlebar)
|
||||
{
|
||||
/* When the window is already maximized restore it */
|
||||
if (nkwnd->_internal.is_maximized)
|
||||
{
|
||||
ShowWindow(wnd, SW_RESTORE);
|
||||
}
|
||||
/* Else we gonna do maximize it*/
|
||||
else
|
||||
{
|
||||
ShowWindow(wnd, SW_MAXIMIZE);
|
||||
}
|
||||
/* We overrideed the window size, make sure to affect the nk window as well */
|
||||
nkwnd->_internal.ws_override = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Allow nuklear to handle the message as well */
|
||||
if (nkwnd->_internal.nk_gdi_ctx && nk_gdi_handle_event(nkwnd->_internal.nk_gdi_ctx, wnd, msg, wParam, lParam))
|
||||
return 0;
|
||||
|
||||
/* In case we reach this line our code and nuklear did not respond to the message. Allow windows to handle it s*/
|
||||
return DefWindowProc(wnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -28,27 +28,32 @@
|
|||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -106,10 +111,16 @@ int main(void)
|
|||
|
||||
/* style.c */
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
while (running)
|
||||
|
@ -159,6 +170,9 @@ int main(void)
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
|
|
@ -47,6 +47,8 @@ NK_API void nk_gdip_image_free(struct nk_image image);
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
/* manually declare everything GDI+ needs, because
|
||||
GDI+ headers are not usable from C */
|
||||
|
@ -319,6 +321,10 @@ GpStatus WINGDIPAPI
|
|||
GdipDrawArcI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
|
||||
INT width, INT height, REAL startAngle, REAL sweepAngle);
|
||||
|
||||
GpStatus WINGDIPAPI
|
||||
GdipDrawPieI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
|
||||
INT width, INT height, REAL startAngle, REAL sweepAngle);
|
||||
|
||||
GpStatus WINGDIPAPI
|
||||
GdipFillPieI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
|
||||
INT width, INT height, REAL startAngle, REAL sweepAngle);
|
||||
|
@ -471,15 +477,25 @@ nk_gdip_fill_rect(short x, short y, unsigned short w,
|
|||
}
|
||||
}
|
||||
|
||||
static BOOL
|
||||
SetPoint(POINT *p, LONG x, LONG y)
|
||||
{
|
||||
if (!p)
|
||||
return FALSE;
|
||||
p->x = x;
|
||||
p->y = y;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdip_fill_triangle(short x0, short y0, short x1,
|
||||
short y1, short x2, short y2, struct nk_color col)
|
||||
{
|
||||
POINT points[] = {
|
||||
{ x0, y0 },
|
||||
{ x1, y1 },
|
||||
{ x2, y2 },
|
||||
};
|
||||
POINT points[3];
|
||||
|
||||
SetPoint(&points[0], x0, y0);
|
||||
SetPoint(&points[1], x1, y1);
|
||||
SetPoint(&points[2], x2, y2);
|
||||
|
||||
GdipSetSolidFillColor(gdip.brush, convert_color(col));
|
||||
GdipFillPolygonI(gdip.memory, gdip.brush, points, 3, FillModeAlternate);
|
||||
|
@ -489,12 +505,13 @@ static void
|
|||
nk_gdip_stroke_triangle(short x0, short y0, short x1,
|
||||
short y1, short x2, short y2, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
POINT points[] = {
|
||||
{ x0, y0 },
|
||||
{ x1, y1 },
|
||||
{ x2, y2 },
|
||||
{ x0, y0 },
|
||||
};
|
||||
POINT points[4];
|
||||
|
||||
SetPoint(&points[0], x0, y0);
|
||||
SetPoint(&points[1], x1, y1);
|
||||
SetPoint(&points[2], x2, y2);
|
||||
SetPoint(&points[3], x0, y0);
|
||||
|
||||
GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
|
||||
GdipSetPenColor(gdip.pen, convert_color(col));
|
||||
GdipDrawPolygonI(gdip.memory, gdip.pen, points, 4);
|
||||
|
@ -569,13 +586,33 @@ nk_gdip_stroke_curve(struct nk_vec2i p1,
|
|||
GdipDrawBezierI(gdip.memory, gdip.pen, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdip_fill_arc(short cx, short cy, unsigned short r, float amin, float adelta, struct nk_color col)
|
||||
{
|
||||
GdipSetSolidFillColor(gdip.brush, convert_color(col));
|
||||
GdipFillPieI(gdip.memory, gdip.brush, cx - r, cy - r, r * 2, r * 2, amin * (180/M_PI), adelta * (180/M_PI));
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdip_stroke_arc(short cx, short cy, unsigned short r, float amin, float adelta, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
GdipSetPenWidth(gdip.pen, (REAL)line_thickness);
|
||||
GdipSetPenColor(gdip.pen, convert_color(col));
|
||||
GdipDrawPieI(gdip.memory, gdip.pen, cx - r, cy - r, r * 2, r * 2, amin * (180/M_PI), adelta * (180/M_PI));
|
||||
}
|
||||
|
||||
static void
|
||||
nk_gdip_draw_text(short x, short y, unsigned short w, unsigned short h,
|
||||
const char *text, int len, GdipFont *font, struct nk_color cbg, struct nk_color cfg)
|
||||
{
|
||||
int wsize;
|
||||
WCHAR* wstr;
|
||||
RectF layout = { (FLOAT)x, (FLOAT)y, (FLOAT)w, (FLOAT)h };
|
||||
RectF layout;
|
||||
|
||||
layout.X = x;
|
||||
layout.Y = y;
|
||||
layout.Width = w;
|
||||
layout.Height = h;
|
||||
|
||||
if(!text || !font || !len) return;
|
||||
|
||||
|
@ -1149,9 +1186,15 @@ nk_gdip_prerender_gui(enum nk_anti_aliasing AA)
|
|||
const struct nk_command_image *i = (const struct nk_command_image *)cmd;
|
||||
nk_gdip_draw_image(i->x, i->y, i->w, i->h, i->img, i->col);
|
||||
} break;
|
||||
case NK_COMMAND_ARC: {
|
||||
const struct nk_command_arc *i = (const struct nk_command_arc *)cmd;
|
||||
nk_gdip_stroke_arc(i->cx, i->cy, i->r, i->a[0], i->a[1], i->line_thickness, i->color);
|
||||
} break;
|
||||
case NK_COMMAND_ARC_FILLED: {
|
||||
const struct nk_command_arc_filled *i = (const struct nk_command_arc_filled *)cmd;
|
||||
nk_gdip_fill_arc(i->cx, i->cy, i->r, i->a[0], i->a[1], i->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_MULTI_COLOR:
|
||||
case NK_COMMAND_ARC:
|
||||
case NK_COMMAND_ARC_FILLED:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
BIN = demo
|
||||
|
||||
# Flags
|
||||
CFLAGS += -std=c99 -pedantic -O2
|
||||
CFLAGS += -std=c99 -Wall -Wextra -pedantic -O2
|
||||
|
||||
SRC = main.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
#include "../../nuklear.h"
|
||||
#include "nuklear_glfw_gl2.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "../../demo/common/filebrowser/stb_image.h"
|
||||
|
||||
#define WINDOW_WIDTH 1200
|
||||
#define WINDOW_HEIGHT 800
|
||||
|
||||
|
@ -34,30 +37,39 @@
|
|||
* ===============================================================*/
|
||||
/* This are some code examples to provide a small overview of what can be
|
||||
* done with this library. To try out an example uncomment the defines */
|
||||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
#define INCLUDE_OVERVIEW
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
/* #define INCLUDE_ALL */
|
||||
/* #define INCLUDE_STYLE */
|
||||
/* #define INCLUDE_CALCULATOR */
|
||||
#define INCLUDE_CANVAS
|
||||
/* #define INCLUDE_FILE_BROWSER */
|
||||
/* #define INCLUDE_OVERVIEW */
|
||||
/* #define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_FILE_BROWSER
|
||||
#include "../../demo/common/file_browser.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -73,8 +85,14 @@ int main(void)
|
|||
/* Platform */
|
||||
static GLFWwindow *win;
|
||||
int width = 0, height = 0;
|
||||
|
||||
/* GUI */
|
||||
struct nk_context *ctx;
|
||||
struct nk_colorf bg;
|
||||
#ifdef INCLUDE_FILE_BROWSER
|
||||
struct file_browser browser;
|
||||
struct media media;
|
||||
#endif
|
||||
|
||||
/* GLFW */
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
@ -103,13 +121,38 @@ int main(void)
|
|||
/*nk_style_set_font(ctx, &droid->handle);*/}
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
|
||||
|
||||
#ifdef INCLUDE_FILE_BROWSER
|
||||
/* icons */
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
media.icons.home = icon_load("../../demo/common/filebrowser/icon/home.png");
|
||||
media.icons.directory = icon_load("../../demo/common/filebrowser/icon/directory.png");
|
||||
media.icons.computer = icon_load("../../demo/common/filebrowser/icon/computer.png");
|
||||
media.icons.desktop = icon_load("../../demo/common/filebrowser/icon/desktop.png");
|
||||
media.icons.default_file = icon_load("../../demo/common/filebrowser/icon/default.png");
|
||||
media.icons.text_file = icon_load("../../demo/common/filebrowser/icon/text.png");
|
||||
media.icons.music_file = icon_load("../../demo/common/filebrowser/icon/music.png");
|
||||
media.icons.font_file = icon_load("../../demo/common/filebrowser/icon/font.png");
|
||||
media.icons.img_file = icon_load("../../demo/common/filebrowser/icon/img.png");
|
||||
media.icons.movie_file = icon_load("../../demo/common/filebrowser/icon/movie.png");
|
||||
media_init(&media);
|
||||
|
||||
file_browser_init(&browser, &media);
|
||||
#endif
|
||||
|
||||
while (!glfwWindowShouldClose(win))
|
||||
{
|
||||
/* Input */
|
||||
|
@ -155,6 +198,12 @@ int main(void)
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_FILE_BROWSER
|
||||
file_browser_run(&browser, ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
@ -175,8 +224,23 @@ int main(void)
|
|||
nk_glfw3_render(NK_ANTI_ALIASING_ON);
|
||||
glfwSwapBuffers(win);
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_FILE_BROWSER
|
||||
glDeleteTextures(1,(const GLuint*)&media.icons.home.handle.id);
|
||||
glDeleteTextures(1,(const GLuint*)&media.icons.directory.handle.id);
|
||||
glDeleteTextures(1,(const GLuint*)&media.icons.computer.handle.id);
|
||||
glDeleteTextures(1,(const GLuint*)&media.icons.desktop.handle.id);
|
||||
glDeleteTextures(1,(const GLuint*)&media.icons.default_file.handle.id);
|
||||
glDeleteTextures(1,(const GLuint*)&media.icons.text_file.handle.id);
|
||||
glDeleteTextures(1,(const GLuint*)&media.icons.music_file.handle.id);
|
||||
glDeleteTextures(1,(const GLuint*)&media.icons.font_file.handle.id);
|
||||
glDeleteTextures(1,(const GLuint*)&media.icons.img_file.handle.id);
|
||||
glDeleteTextures(1,(const GLuint*)&media.icons.movie_file.handle.id);
|
||||
|
||||
file_browser_free(&browser);
|
||||
#endif
|
||||
|
||||
nk_glfw3_shutdown();
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xof
|
|||
|
||||
struct nk_glfw_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
struct nk_draw_null_texture tex_null;
|
||||
GLuint font_tex;
|
||||
};
|
||||
|
||||
|
@ -140,7 +140,7 @@ nk_glfw3_render(enum nk_anti_aliasing AA)
|
|||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_glfw_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex);
|
||||
config.null = dev->null;
|
||||
config.tex_null = dev->tex_null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
|
@ -218,6 +218,7 @@ NK_API void
|
|||
nk_glfw3_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
double x, y;
|
||||
NK_UNUSED(mods);
|
||||
if (button != GLFW_MOUSE_BUTTON_LEFT) return;
|
||||
glfwGetCursorPos(window, &x, &y);
|
||||
if (action == GLFW_PRESS) {
|
||||
|
@ -287,7 +288,7 @@ nk_glfw3_font_stash_end(void)
|
|||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&glfw.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_glfw3_device_upload_atlas(image, w, h);
|
||||
nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex), &glfw.ogl.null);
|
||||
nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex), &glfw.ogl.tex_null);
|
||||
if (glfw.atlas.default_font)
|
||||
nk_style_set_font(&glfw.ctx, &glfw.atlas.default_font->handle);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
BIN = demo
|
||||
|
||||
# Flags
|
||||
CFLAGS += -std=c99 -pedantic -O2
|
||||
CFLAGS += -std=c89 -Wall -Wextra -pedantic -O2
|
||||
|
||||
SRC = main.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
|
|
@ -41,27 +41,32 @@
|
|||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
#define INCLUDE_OVERVIEW
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -121,10 +126,16 @@ int main(void)
|
|||
/*nk_style_set_font(ctx, &droid->handle);*/}
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
|
||||
|
@ -173,6 +184,9 @@ int main(void)
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
|
|
@ -26,7 +26,7 @@ enum nk_glfw_init_state{
|
|||
|
||||
struct nk_glfw_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
struct nk_draw_null_texture tex_null;
|
||||
GLuint vbo, vao, ebo;
|
||||
GLuint prog;
|
||||
GLuint vert_shdr;
|
||||
|
@ -266,7 +266,7 @@ nk_glfw3_render(struct nk_glfw* glfw, enum nk_anti_aliasing AA, int max_vertex_b
|
|||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_glfw_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex);
|
||||
config.null = dev->null;
|
||||
config.tex_null = dev->tex_null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
|
@ -328,9 +328,10 @@ nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff)
|
|||
NK_API void
|
||||
nk_glfw3_mouse_button_callback(GLFWwindow* win, int button, int action, int mods)
|
||||
{
|
||||
double x, y;
|
||||
if (button != GLFW_MOUSE_BUTTON_LEFT) return;
|
||||
struct nk_glfw* glfw = glfwGetWindowUserPointer(win);
|
||||
double x, y;
|
||||
NK_UNUSED(mods);
|
||||
if (button != GLFW_MOUSE_BUTTON_LEFT) return;
|
||||
glfwGetCursorPos(win, &x, &y);
|
||||
if (action == GLFW_PRESS) {
|
||||
double dt = glfwGetTime() - glfw->last_button_click;
|
||||
|
@ -345,7 +346,7 @@ nk_glfw3_mouse_button_callback(GLFWwindow* win, int button, int action, int mods
|
|||
NK_INTERN void
|
||||
nk_glfw3_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||
{
|
||||
struct nk_glfw* glfw = usr.ptr;
|
||||
struct nk_glfw* glfw = (struct nk_glfw*)usr.ptr;
|
||||
const char *text = glfwGetClipboardString(glfw->win);
|
||||
if (text) nk_textedit_paste(edit, text, nk_strlen(text));
|
||||
(void)usr;
|
||||
|
@ -354,13 +355,13 @@ nk_glfw3_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
|
|||
NK_INTERN void
|
||||
nk_glfw3_clipboard_copy(nk_handle usr, const char *text, int len)
|
||||
{
|
||||
struct nk_glfw* glfw = (struct nk_glfw*)usr.ptr;
|
||||
char *str = 0;
|
||||
if (!len) return;
|
||||
str = (char*)malloc((size_t)len+1);
|
||||
if (!str) return;
|
||||
memcpy(str, text, (size_t)len);
|
||||
str[len] = '\0';
|
||||
struct nk_glfw* glfw = usr.ptr;
|
||||
glfwSetClipboardString(glfw->win, str);
|
||||
free(str);
|
||||
}
|
||||
|
@ -402,7 +403,7 @@ nk_glfw3_font_stash_end(struct nk_glfw* glfw)
|
|||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&glfw->atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_glfw3_device_upload_atlas(glfw, image, w, h);
|
||||
nk_font_atlas_end(&glfw->atlas, nk_handle_id((int)glfw->ogl.font_tex), &glfw->ogl.null);
|
||||
nk_font_atlas_end(&glfw->atlas, nk_handle_id((int)glfw->ogl.font_tex), &glfw->ogl.tex_null);
|
||||
if (glfw->atlas.default_font)
|
||||
nk_style_set_font(&glfw->ctx, &glfw->atlas.default_font->handle);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
BIN = demo
|
||||
|
||||
# Flags
|
||||
CFLAGS += -std=c99 -pedantic -O2
|
||||
CFLAGS += -std=c89 -Wall -Wextra -pedantic -O2
|
||||
|
||||
SRC = main.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
|
|
@ -41,27 +41,32 @@
|
|||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
#define INCLUDE_OVERVIEW
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -121,10 +126,16 @@ int main(void)
|
|||
/*nk_style_set_font(ctx, &droid->handle);*/}
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Create bindless texture.
|
||||
|
@ -194,6 +205,9 @@ int main(void)
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
|
|
@ -72,7 +72,7 @@ struct nk_glfw_vertex {
|
|||
|
||||
struct nk_glfw_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
struct nk_draw_null_texture tex_null;
|
||||
GLuint vbo, vao, ebo;
|
||||
GLuint prog;
|
||||
GLuint vert_shdr;
|
||||
|
@ -116,6 +116,7 @@ NK_API void
|
|||
nk_glfw3_device_create()
|
||||
{
|
||||
GLint status;
|
||||
GLint len = 0;
|
||||
static const GLchar *vertex_shader =
|
||||
NK_SHADER_VERSION
|
||||
NK_SHADER_BINDLESS
|
||||
|
@ -156,7 +157,6 @@ nk_glfw3_device_create()
|
|||
glCompileShader(dev->frag_shdr);
|
||||
glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status);
|
||||
|
||||
GLint len = 0;
|
||||
glGetShaderiv(dev->vert_shdr, GL_INFO_LOG_LENGTH, &len);
|
||||
if (len > 1) {
|
||||
char *log = (char*)calloc((size_t)len, sizeof(char));
|
||||
|
@ -407,7 +407,7 @@ nk_glfw3_render(enum nk_anti_aliasing AA)
|
|||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_glfw_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex);
|
||||
config.null = dev->null;
|
||||
config.tex_null = dev->tex_null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
|
@ -477,6 +477,7 @@ NK_API void
|
|||
nk_glfw3_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
double x, y;
|
||||
NK_UNUSED(mods);
|
||||
if (button != GLFW_MOUSE_BUTTON_LEFT) return;
|
||||
glfwGetCursorPos(window, &x, &y);
|
||||
if (action == GLFW_PRESS) {
|
||||
|
@ -552,7 +553,7 @@ nk_glfw3_font_stash_end(void)
|
|||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&glfw.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_glfw3_device_upload_atlas(image, w, h);
|
||||
nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex_index), &glfw.ogl.null);
|
||||
nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex_index), &glfw.ogl.tex_null);
|
||||
if (glfw.atlas.default_font)
|
||||
nk_style_set_font(&glfw.ctx, &glfw.atlas.default_font->handle);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CFLAGS=`sdl2-config --cflags --libs` -std=c11 -Wall -O0 -g -fvisibility=hidden -Wno-unused `pkg-config SDL2_ttf --cflags --libs`
|
||||
CFLAGS=`sdl2-config --cflags --libs` -std=c89 -Wall -Wextra -pedantic -Wno-unused-function -O0 -g -fvisibility=hidden `pkg-config SDL2_ttf --cflags --libs`
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include <SDL_mouse.h>
|
||||
#include <SDL_keyboard.h>
|
||||
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
@ -23,9 +22,48 @@
|
|||
#define NK_SDLSURFACE_IMPLEMENTATION
|
||||
#include "sdl2surface_rawfb.h"
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* ===============================================================*/
|
||||
/* This are some code examples to provide a small overview of what can be
|
||||
* done with this library. To try out an example uncomment the defines */
|
||||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
static int translate_sdl_key(struct SDL_Keysym const *k)
|
||||
{
|
||||
/*keyboard handling left as an exercise for the reader */
|
||||
NK_UNUSED(k);
|
||||
|
||||
return NK_KEY_NONE;
|
||||
}
|
||||
|
@ -36,7 +74,7 @@ static int sdl_button_to_nk(int button)
|
|||
switch(button)
|
||||
{
|
||||
default:
|
||||
//ft
|
||||
/* ft */
|
||||
case SDL_BUTTON_LEFT:
|
||||
return NK_BUTTON_LEFT;
|
||||
break;
|
||||
|
@ -50,7 +88,7 @@ static int sdl_button_to_nk(int button)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void
|
||||
grid_demo(struct nk_context *ctx)
|
||||
{
|
||||
|
@ -85,7 +123,7 @@ grid_demo(struct nk_context *ctx)
|
|||
}
|
||||
nk_end(ctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -93,20 +131,28 @@ int main(int argc, char **argv)
|
|||
struct nk_color clear = {0,100,0,255};
|
||||
struct nk_vec2 vec;
|
||||
struct nk_rect bounds = {40,40,0,0};
|
||||
struct sdlsurface_context *context;
|
||||
|
||||
SDL_DisplayMode dm;
|
||||
SDL_Window *window;
|
||||
SDL_Renderer *renderer;
|
||||
SDL_Texture *tex;
|
||||
SDL_Surface *surface;
|
||||
|
||||
NK_UNUSED(argc);
|
||||
NK_UNUSED(argv);
|
||||
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
printf("sdl init called...\n");
|
||||
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
|
||||
|
||||
SDL_DisplayMode dm;
|
||||
|
||||
SDL_GetDesktopDisplayMode(0, &dm);
|
||||
|
||||
printf("desktop display mode %d %d\n", dm.w, dm.h);
|
||||
|
||||
|
||||
SDL_Window *window = SDL_CreateWindow("Puzzle", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, dm.w-200,dm.h-200, SDL_WINDOW_OPENGL);
|
||||
window = SDL_CreateWindow("Puzzle", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, dm.w-200,dm.h-200, SDL_WINDOW_OPENGL);
|
||||
if (!window)
|
||||
{
|
||||
printf("can't open window!\n");
|
||||
|
@ -114,18 +160,18 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
|
||||
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
|
||||
renderer = SDL_CreateRenderer(window, -1, 0);
|
||||
|
||||
SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, dm.w-200, dm.h-200, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
surface = SDL_CreateRGBSurfaceWithFormat(0, dm.w-200, dm.h-200, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
|
||||
|
||||
struct sdlsurface_context *context = nk_sdlsurface_init(surface, 13.0f);
|
||||
context = nk_sdlsurface_init(surface, 13.0f);
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
nk_input_begin(&(context->ctx));
|
||||
SDL_Event event;
|
||||
nk_input_begin(&(context->ctx));
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
switch(event.type)
|
||||
|
@ -177,14 +223,29 @@ int main(int argc, char **argv)
|
|||
}
|
||||
nk_end(&(context->ctx));
|
||||
|
||||
// grid_demo(&(context->ctx));
|
||||
/* grid_demo(&(context->ctx)); */
|
||||
|
||||
/* -------------- EXAMPLES ---------------- */
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(&(context->ctx));
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(&(context->ctx));
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(&(context->ctx));
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
node_editor(&(context->ctx));
|
||||
#endif
|
||||
/* ----------------------------------------- */
|
||||
|
||||
nk_sdlsurface_render(context, clear, 1);
|
||||
|
||||
|
||||
|
||||
|
||||
SDL_Texture *tex = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
tex = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
SDL_RenderCopy(renderer, tex, NULL, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
SDL_DestroyTexture(tex);
|
||||
|
|
|
@ -65,54 +65,18 @@ struct sdlsurface_context {
|
|||
#endif
|
||||
|
||||
static unsigned int
|
||||
nk_sdlsurface_color2int(const struct nk_color c, SDL_PixelFormatEnum pl)
|
||||
nk_sdlsurface_color2int(const struct nk_color c, const SDL_PixelFormat *format)
|
||||
{
|
||||
unsigned int res = 0;
|
||||
|
||||
switch (pl) {
|
||||
case SDL_PIXELFORMAT_RGBA8888:
|
||||
res |= c.r << 24;
|
||||
res |= c.g << 16;
|
||||
res |= c.b << 8;
|
||||
res |= c.a;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_ARGB8888:
|
||||
res |= c.a << 24;
|
||||
res |= c.r << 16;
|
||||
res |= c.g << 8;
|
||||
res |= c.b;
|
||||
break;
|
||||
|
||||
default:
|
||||
perror("nk_sdlsurface_color2int(): Unsupported pixel layout.\n");
|
||||
break;
|
||||
}
|
||||
return (res);
|
||||
return SDL_MapRGBA(format, c.r, c.g, c.b, c.a);
|
||||
}
|
||||
|
||||
static struct nk_color
|
||||
nk_sdlsurface_int2color(const unsigned int i, SDL_PixelFormatEnum pl)
|
||||
nk_sdlsurface_int2color(const unsigned int i, const SDL_PixelFormat *format)
|
||||
{
|
||||
struct nk_color col = {0,0,0,0};
|
||||
|
||||
switch (pl) {
|
||||
case SDL_PIXELFORMAT_RGBA8888:
|
||||
col.r = (i >> 24) & 0xff;
|
||||
col.g = (i >> 16) & 0xff;
|
||||
col.b = (i >> 8) & 0xff;
|
||||
col.a = i & 0xff;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_ARGB8888:
|
||||
col.a = (i >> 24) & 0xff;
|
||||
col.r = (i >> 16) & 0xff;
|
||||
col.g = (i >> 8) & 0xff;
|
||||
col.b = i & 0xff;
|
||||
break;
|
||||
SDL_GetRGBA(i, format, &col.r, &col.g, &col.b, &col.a);
|
||||
|
||||
default:
|
||||
perror("nk_sdlsurface_int2color(): Unsupported pixel layout.\n");
|
||||
break;
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
|
@ -120,16 +84,22 @@ static void
|
|||
nk_sdlsurface_ctx_setpixel(const struct sdlsurface_context *sdlsurface,
|
||||
const short x0, const short y0, const struct nk_color col)
|
||||
{
|
||||
unsigned int c = nk_sdlsurface_color2int(col, sdlsurface->fb->format->format);
|
||||
unsigned int c = nk_sdlsurface_color2int(col, sdlsurface->fb->format);
|
||||
unsigned char *pixels = sdlsurface->fb->pixels;
|
||||
unsigned int *ptr;
|
||||
|
||||
pixels += y0 * sdlsurface->fb->pitch;
|
||||
ptr = (unsigned int *)pixels + x0;
|
||||
|
||||
if (y0 < sdlsurface->scissors.h && y0 >= sdlsurface->scissors.y &&
|
||||
x0 >= sdlsurface->scissors.x && x0 < sdlsurface->scissors.w)
|
||||
*ptr = c;
|
||||
x0 >= sdlsurface->scissors.x && x0 < sdlsurface->scissors.w) {
|
||||
|
||||
if (sdlsurface->fb->format->BytesPerPixel == 4) {
|
||||
*((Uint32 *)pixels + x0) = c;
|
||||
} else if (sdlsurface->fb->format->BytesPerPixel == 2) {
|
||||
*((Uint16 *)pixels + x0) = c;
|
||||
} else {
|
||||
*((Uint8 *)pixels + x0) = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -140,40 +110,49 @@ nk_sdlsurface_line_horizontal(const struct sdlsurface_context *sdlsurface,
|
|||
* It does not check for scissors or image borders.
|
||||
* The caller has to make sure it does no exceed bounds. */
|
||||
unsigned int i, n;
|
||||
unsigned int c[16];
|
||||
unsigned char c[16 * 4];
|
||||
unsigned char *pixels = sdlsurface->fb->pixels;
|
||||
unsigned int *ptr;
|
||||
unsigned int bpp = sdlsurface->fb->format->BytesPerPixel;
|
||||
|
||||
pixels += y * sdlsurface->fb->pitch;
|
||||
ptr = (unsigned int *)pixels + x0;
|
||||
pixels += (y * sdlsurface->fb->pitch) + (x0 * bpp);
|
||||
|
||||
n = x1 - x0;
|
||||
for (i = 0; i < sizeof(c) / sizeof(c[0]); i++)
|
||||
c[i] = nk_sdlsurface_color2int(col, sdlsurface->fb->format->format);
|
||||
n = (x1 - x0) * bpp;
|
||||
if (bpp == 4) {
|
||||
for (i = 0; i < sizeof(c) / bpp; i++)
|
||||
((Uint32 *)c)[i] = nk_sdlsurface_color2int(col, sdlsurface->fb->format);
|
||||
} else if (bpp == 2) {
|
||||
for (i = 0; i < sizeof(c) / bpp; i++)
|
||||
((Uint16 *)c)[i] = nk_sdlsurface_color2int(col, sdlsurface->fb->format);
|
||||
} else {
|
||||
for (i = 0; i < sizeof(c) / bpp; i++)
|
||||
((Uint8 *)c)[i] = nk_sdlsurface_color2int(col, sdlsurface->fb->format);
|
||||
}
|
||||
|
||||
while (n > 16) {
|
||||
memcpy((void *)ptr, c, sizeof(c));
|
||||
n -= 16; ptr += 16;
|
||||
while (n > sizeof(c)) {
|
||||
memcpy((void*)pixels, c, sizeof(c));
|
||||
n -= sizeof(c); pixels += sizeof(c);
|
||||
} for (i = 0; i < n; i++)
|
||||
ptr[i] = c[i];
|
||||
pixels[i] = c[i];
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdlsurface_img_setpixel(const struct SDL_Surface *img,
|
||||
const int x0, const int y0, const struct nk_color col)
|
||||
{
|
||||
unsigned int c = nk_sdlsurface_color2int(col, img->format->format);
|
||||
unsigned int c = nk_sdlsurface_color2int(col, img->format);
|
||||
unsigned char *ptr;
|
||||
unsigned int *pixel;
|
||||
NK_ASSERT(img);
|
||||
if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
|
||||
ptr = img->pixels + (img->pitch * y0);
|
||||
pixel = (unsigned int *)ptr;
|
||||
ptr = (unsigned char *)img->pixels + (img->pitch * y0);
|
||||
|
||||
if (img->format == NK_FONT_ATLAS_ALPHA8) {
|
||||
ptr[x0] = col.a;
|
||||
} else if (img->format->BytesPerPixel == 4) {
|
||||
((Uint32 *)ptr)[x0] = c;
|
||||
} else if (img->format->BytesPerPixel == 2) {
|
||||
((Uint16 *)ptr)[x0] = c;
|
||||
} else {
|
||||
pixel[x0] = c;
|
||||
((Uint8 *)ptr)[x0] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,14 +165,20 @@ nk_sdlsurface_img_getpixel(const struct SDL_Surface *img, const int x0, const in
|
|||
unsigned int pixel;
|
||||
NK_ASSERT(img);
|
||||
if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
|
||||
ptr = img->pixels + (img->pitch * y0);
|
||||
ptr = (unsigned char *)img->pixels + (img->pitch * y0);
|
||||
|
||||
if (img->format == NK_FONT_ATLAS_ALPHA8) {
|
||||
col.a = ptr[x0];
|
||||
col.b = col.g = col.r = 0xff;
|
||||
} else if (img->format->BytesPerPixel == 4) {
|
||||
pixel = ((Uint32 *)ptr)[x0];
|
||||
col = nk_sdlsurface_int2color(pixel, img->format);
|
||||
} else if (img->format->BytesPerPixel == 2) {
|
||||
pixel = ((Uint16 *)ptr)[x0];
|
||||
col = nk_sdlsurface_int2color(pixel, img->format);
|
||||
} else {
|
||||
pixel = ((unsigned int *)ptr)[x0];
|
||||
col = nk_sdlsurface_int2color(pixel, img->format->format);
|
||||
pixel = ((Uint8 *)ptr)[x0];
|
||||
col = nk_sdlsurface_int2color(pixel, img->format);
|
||||
}
|
||||
} return col;
|
||||
}
|
||||
|
@ -235,6 +220,8 @@ nk_sdlsurface_stroke_line(const struct sdlsurface_context *sdlsurface,
|
|||
short tmp;
|
||||
int dy, dx, stepx, stepy;
|
||||
|
||||
NK_UNUSED(line_thickness);
|
||||
|
||||
dy = y1 - y0;
|
||||
dx = x1 - x0;
|
||||
|
||||
|
@ -369,6 +356,8 @@ nk_sdlsurface_stroke_arc(const struct sdlsurface_context *sdlsurface,
|
|||
const int fa2 = 4 * a2, fb2 = 4 * b2;
|
||||
int x, y, sigma;
|
||||
|
||||
NK_UNUSED(line_thickness);
|
||||
|
||||
if (s != 0 && s != 90 && s != 180 && s != 270) return;
|
||||
if (w < 1 || h < 1) return;
|
||||
|
||||
|
@ -735,6 +724,8 @@ nk_sdlsurface_stroke_circle(const struct sdlsurface_context *sdlsurface,
|
|||
const int fa2 = 4 * a2, fb2 = 4 * b2;
|
||||
int x, y, sigma;
|
||||
|
||||
NK_UNUSED(line_thickness);
|
||||
|
||||
/* Convert upper left to center */
|
||||
h = (h + 1) / 2;
|
||||
w = (w + 1) / 2;
|
||||
|
@ -802,13 +793,13 @@ nk_sdlsurface_clear(const struct sdlsurface_context *sdlsurface, const struct nk
|
|||
struct sdlsurface_context*
|
||||
nk_sdlsurface_init(SDL_Surface *fb, float fontSize)
|
||||
{
|
||||
SDL_assert((fb->format->format == SDL_PIXELFORMAT_ARGB8888)
|
||||
|| (fb->format->format == SDL_PIXELFORMAT_RGBA8888));
|
||||
|
||||
const void *tex;
|
||||
int texh, texw;
|
||||
struct sdlsurface_context *sdlsurface;
|
||||
|
||||
assert((fb->format->format == SDL_PIXELFORMAT_ARGB8888)
|
||||
|| (fb->format->format == SDL_PIXELFORMAT_RGBA8888));
|
||||
|
||||
sdlsurface = malloc(sizeof(struct sdlsurface_context));
|
||||
if (!sdlsurface)
|
||||
return NULL;
|
||||
|
@ -831,7 +822,7 @@ nk_sdlsurface_init(SDL_Surface *fb, float fontSize)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
sdlsurface->font_tex = SDL_CreateRGBSurfaceWithFormat(0, texw, texh, 32, fb->format->format);
|
||||
sdlsurface->font_tex = SDL_CreateRGBSurface(0, texw, texh, 32, 0xff, 0xff00, 0xff0000, 0xff000000);
|
||||
|
||||
memcpy(sdlsurface->font_tex->pixels, tex, texw * texh * 4);
|
||||
|
||||
|
@ -841,19 +832,6 @@ nk_sdlsurface_init(SDL_Surface *fb, float fontSize)
|
|||
nk_style_load_all_cursors(&sdlsurface->ctx, sdlsurface->atlas.cursors);
|
||||
nk_sdlsurface_scissor(sdlsurface, 0, 0, sdlsurface->fb->w, sdlsurface->fb->h);
|
||||
|
||||
if (fb->format->format == SDL_PIXELFORMAT_RGBA8888)
|
||||
{
|
||||
SDL_assert(sdlsurface->font_tex->pitch == sdlsurface->font_tex->w * 4);
|
||||
uint32_t *fontPixels = (uint32_t *)sdlsurface->font_tex->pixels;
|
||||
for (int i = 0; i < sdlsurface->font_tex->w * sdlsurface->font_tex->h; i++)
|
||||
{
|
||||
uint32_t col = fontPixels[i];
|
||||
fontPixels[i] &= 0xFFFF00;
|
||||
fontPixels[i] |= ((col & 0xFF000000) >> 24);
|
||||
fontPixels[i] |= ((col & 0xFF) << 24);
|
||||
}
|
||||
}
|
||||
|
||||
return sdlsurface;
|
||||
}
|
||||
|
||||
|
@ -961,8 +939,8 @@ nk_sdlsurface_draw_text(const struct sdlsurface_context *sdlsurface,
|
|||
|
||||
dst_rect.x = x + g.offset.x + rect.x;
|
||||
dst_rect.y = g.offset.y + rect.y;
|
||||
dst_rect.w = ceilf(g.width);
|
||||
dst_rect.h = ceilf(g.height);
|
||||
dst_rect.w = ceil(g.width);
|
||||
dst_rect.h = ceil(g.height);
|
||||
|
||||
/* Use software rescaling to blit glyph from font_text to framebuffer */
|
||||
nk_sdlsurface_stretch_image(sdlsurface->fb, sdlsurface->font_tex, &dst_rect, &src_rect, &sdlsurface->scissors, &fg);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
BIN = demo
|
||||
|
||||
# Flags
|
||||
CFLAGS += -std=c99 -pedantic -O2
|
||||
CFLAGS += -std=c89 -Wall -Wextra -pedantic -O2
|
||||
|
||||
SRC = main.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
|
|
@ -37,27 +37,32 @@
|
|||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -78,6 +83,9 @@ main(int argc, char *argv[])
|
|||
struct nk_context *ctx;
|
||||
struct nk_colorf bg;
|
||||
|
||||
NK_UNUSED(argc);
|
||||
NK_UNUSED(argv);
|
||||
|
||||
/* SDL setup */
|
||||
SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0");
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
|
@ -109,10 +117,16 @@ main(int argc, char *argv[])
|
|||
/*nk_style_set_font(ctx, &roboto->handle)*/;}
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
|
||||
|
@ -165,6 +179,9 @@ main(int argc, char *argv[])
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
|
|
@ -33,7 +33,7 @@ NK_API void nk_sdl_shutdown(void);
|
|||
|
||||
struct nk_sdl_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
struct nk_draw_null_texture tex_null;
|
||||
GLuint font_tex;
|
||||
};
|
||||
|
||||
|
@ -120,7 +120,7 @@ nk_sdl_render(enum nk_anti_aliasing AA)
|
|||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_sdl_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_sdl_vertex);
|
||||
config.null = dev->null;
|
||||
config.tex_null = dev->tex_null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
|
@ -226,7 +226,7 @@ nk_sdl_font_stash_end(void)
|
|||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&sdl.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_sdl_device_upload_atlas(image, w, h);
|
||||
nk_font_atlas_end(&sdl.atlas, nk_handle_id((int)sdl.ogl.font_tex), &sdl.ogl.null);
|
||||
nk_font_atlas_end(&sdl.atlas, nk_handle_id((int)sdl.ogl.font_tex), &sdl.ogl.tex_null);
|
||||
if (sdl.atlas.default_font)
|
||||
nk_style_set_font(&sdl.ctx, &sdl.atlas.default_font->handle);
|
||||
}
|
||||
|
@ -246,87 +246,85 @@ nk_sdl_handle_event(SDL_Event *evt)
|
|||
SDL_WarpMouseInWindow(sdl.win, x, y);
|
||||
ctx->input.mouse.ungrab = 0;
|
||||
}
|
||||
if (evt->type == SDL_KEYUP || evt->type == SDL_KEYDOWN) {
|
||||
/* key events */
|
||||
|
||||
switch(evt->type)
|
||||
{
|
||||
case SDL_KEYUP: /* KEYUP & KEYDOWN share same routine */
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
int down = evt->type == SDL_KEYDOWN;
|
||||
const Uint8* state = SDL_GetKeyboardState(0);
|
||||
SDL_Keycode sym = evt->key.keysym.sym;
|
||||
if (sym == SDLK_RSHIFT || sym == SDLK_LSHIFT)
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, down);
|
||||
else if (sym == SDLK_DELETE)
|
||||
nk_input_key(ctx, NK_KEY_DEL, down);
|
||||
else if (sym == SDLK_RETURN)
|
||||
nk_input_key(ctx, NK_KEY_ENTER, down);
|
||||
else if (sym == SDLK_TAB)
|
||||
nk_input_key(ctx, NK_KEY_TAB, down);
|
||||
else if (sym == SDLK_BACKSPACE)
|
||||
nk_input_key(ctx, NK_KEY_BACKSPACE, down);
|
||||
else if (sym == SDLK_HOME) {
|
||||
nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_START, down);
|
||||
} else if (sym == SDLK_END) {
|
||||
nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_END, down);
|
||||
} else if (sym == SDLK_PAGEDOWN) {
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down);
|
||||
} else if (sym == SDLK_PAGEUP) {
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_UP, down);
|
||||
} else if (sym == SDLK_z)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_r)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_c)
|
||||
nk_input_key(ctx, NK_KEY_COPY, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_v)
|
||||
nk_input_key(ctx, NK_KEY_PASTE, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_x)
|
||||
nk_input_key(ctx, NK_KEY_CUT, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_b)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_e)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_UP)
|
||||
nk_input_key(ctx, NK_KEY_UP, down);
|
||||
else if (sym == SDLK_DOWN)
|
||||
nk_input_key(ctx, NK_KEY_DOWN, down);
|
||||
else if (sym == SDLK_LEFT) {
|
||||
switch(evt->key.keysym.sym)
|
||||
{
|
||||
case SDLK_RSHIFT: /* RSHIFT & LSHIFT share same routine */
|
||||
case SDLK_LSHIFT: nk_input_key(ctx, NK_KEY_SHIFT, down); break;
|
||||
case SDLK_DELETE: nk_input_key(ctx, NK_KEY_DEL, down); break;
|
||||
case SDLK_RETURN: nk_input_key(ctx, NK_KEY_ENTER, down); break;
|
||||
case SDLK_TAB: nk_input_key(ctx, NK_KEY_TAB, down); break;
|
||||
case SDLK_BACKSPACE: nk_input_key(ctx, NK_KEY_BACKSPACE, down); break;
|
||||
case SDLK_HOME: nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_START, down); break;
|
||||
case SDLK_END: nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_END, down); break;
|
||||
case SDLK_PAGEDOWN: nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down); break;
|
||||
case SDLK_PAGEUP: nk_input_key(ctx, NK_KEY_SCROLL_UP, down); break;
|
||||
case SDLK_z: nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_r: nk_input_key(ctx, NK_KEY_TEXT_REDO, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_c: nk_input_key(ctx, NK_KEY_COPY, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_v: nk_input_key(ctx, NK_KEY_PASTE, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_x: nk_input_key(ctx, NK_KEY_CUT, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_b: nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_e: nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_UP: nk_input_key(ctx, NK_KEY_UP, down); break;
|
||||
case SDLK_DOWN: nk_input_key(ctx, NK_KEY_DOWN, down); break;
|
||||
case SDLK_LEFT:
|
||||
if (state[SDL_SCANCODE_LCTRL])
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else nk_input_key(ctx, NK_KEY_LEFT, down);
|
||||
} else if (sym == SDLK_RIGHT) {
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
if (state[SDL_SCANCODE_LCTRL])
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else nk_input_key(ctx, NK_KEY_RIGHT, down);
|
||||
} else return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
} else if (evt->type == SDL_MOUSEBUTTONDOWN || evt->type == SDL_MOUSEBUTTONUP) {
|
||||
/* mouse button */
|
||||
|
||||
case SDL_MOUSEBUTTONUP: /* MOUSEBUTTONUP & MOUSEBUTTONDOWN share same routine */
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
int down = evt->type == SDL_MOUSEBUTTONDOWN;
|
||||
const int x = evt->button.x, y = evt->button.y;
|
||||
if (evt->button.button == SDL_BUTTON_LEFT) {
|
||||
switch(evt->button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
if (evt->button.clicks > 1)
|
||||
nk_input_button(ctx, NK_BUTTON_DOUBLE, x, y, down);
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down);
|
||||
} else if (evt->button.button == SDL_BUTTON_MIDDLE)
|
||||
nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down);
|
||||
else if (evt->button.button == SDL_BUTTON_RIGHT)
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down);
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down); break;
|
||||
case SDL_BUTTON_MIDDLE: nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down); break;
|
||||
case SDL_BUTTON_RIGHT: nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down); break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
} else if (evt->type == SDL_MOUSEMOTION) {
|
||||
/* mouse motion */
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
if (ctx->input.mouse.grabbed) {
|
||||
int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y;
|
||||
nk_input_motion(ctx, x + evt->motion.xrel, y + evt->motion.yrel);
|
||||
} else nk_input_motion(ctx, evt->motion.x, evt->motion.y);
|
||||
}
|
||||
else nk_input_motion(ctx, evt->motion.x, evt->motion.y);
|
||||
return 1;
|
||||
} else if (evt->type == SDL_TEXTINPUT) {
|
||||
/* text input */
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
nk_glyph glyph;
|
||||
memcpy(glyph, evt->text.text, NK_UTF_SIZE);
|
||||
nk_input_glyph(ctx, glyph);
|
||||
}
|
||||
return 1;
|
||||
} else if (evt->type == SDL_MOUSEWHEEL) {
|
||||
/* mouse wheel */
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
nk_input_scroll(ctx,nk_vec2((float)evt->wheel.x,(float)evt->wheel.y));
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
BIN = demo
|
||||
|
||||
# Flags
|
||||
CFLAGS += -std=c99 -pedantic -O2
|
||||
CFLAGS += -std=c89 -Wall -Wextra -pedantic -O2
|
||||
|
||||
SRC = main.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
|
|
@ -41,27 +41,32 @@
|
|||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -81,6 +86,9 @@ int main(int argc, char *argv[])
|
|||
struct nk_context *ctx;
|
||||
struct nk_colorf bg;
|
||||
|
||||
NK_UNUSED(argc);
|
||||
NK_UNUSED(argv);
|
||||
|
||||
/* SDL setup */
|
||||
SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0");
|
||||
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_EVENTS);
|
||||
|
@ -120,10 +128,16 @@ int main(int argc, char *argv[])
|
|||
|
||||
/* style.c */
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
|
||||
|
@ -175,6 +189,9 @@ int main(int argc, char *argv[])
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
|
|
@ -40,7 +40,7 @@ NK_API void nk_sdl_device_create(void);
|
|||
|
||||
struct nk_sdl_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
struct nk_draw_null_texture tex_null;
|
||||
GLuint vbo, vao, ebo;
|
||||
GLuint prog;
|
||||
GLuint vert_shdr;
|
||||
|
@ -247,7 +247,7 @@ nk_sdl_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_b
|
|||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_sdl_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_sdl_vertex);
|
||||
config.null = dev->null;
|
||||
config.tex_null = dev->tex_null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
|
@ -334,7 +334,7 @@ nk_sdl_font_stash_end(void)
|
|||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&sdl.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_sdl_device_upload_atlas(image, w, h);
|
||||
nk_font_atlas_end(&sdl.atlas, nk_handle_id((int)sdl.ogl.font_tex), &sdl.ogl.null);
|
||||
nk_font_atlas_end(&sdl.atlas, nk_handle_id((int)sdl.ogl.font_tex), &sdl.ogl.tex_null);
|
||||
if (sdl.atlas.default_font)
|
||||
nk_style_set_font(&sdl.ctx, &sdl.atlas.default_font->handle);
|
||||
|
||||
|
@ -344,87 +344,96 @@ NK_API int
|
|||
nk_sdl_handle_event(SDL_Event *evt)
|
||||
{
|
||||
struct nk_context *ctx = &sdl.ctx;
|
||||
if (evt->type == SDL_KEYUP || evt->type == SDL_KEYDOWN) {
|
||||
/* key events */
|
||||
|
||||
/* optional grabbing behavior */
|
||||
if (ctx->input.mouse.grab) {
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
ctx->input.mouse.grab = 0;
|
||||
} else if (ctx->input.mouse.ungrab) {
|
||||
int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y;
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
SDL_WarpMouseInWindow(sdl.win, x, y);
|
||||
ctx->input.mouse.ungrab = 0;
|
||||
}
|
||||
|
||||
switch(evt->type)
|
||||
{
|
||||
case SDL_KEYUP: /* KEYUP & KEYDOWN share same routine */
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
int down = evt->type == SDL_KEYDOWN;
|
||||
const Uint8* state = SDL_GetKeyboardState(0);
|
||||
SDL_Keycode sym = evt->key.keysym.sym;
|
||||
if (sym == SDLK_RSHIFT || sym == SDLK_LSHIFT)
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, down);
|
||||
else if (sym == SDLK_DELETE)
|
||||
nk_input_key(ctx, NK_KEY_DEL, down);
|
||||
else if (sym == SDLK_RETURN)
|
||||
nk_input_key(ctx, NK_KEY_ENTER, down);
|
||||
else if (sym == SDLK_TAB)
|
||||
nk_input_key(ctx, NK_KEY_TAB, down);
|
||||
else if (sym == SDLK_BACKSPACE)
|
||||
nk_input_key(ctx, NK_KEY_BACKSPACE, down);
|
||||
else if (sym == SDLK_HOME) {
|
||||
nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_START, down);
|
||||
} else if (sym == SDLK_END) {
|
||||
nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_END, down);
|
||||
} else if (sym == SDLK_PAGEDOWN) {
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down);
|
||||
} else if (sym == SDLK_PAGEUP) {
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_UP, down);
|
||||
} else if (sym == SDLK_z)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_r)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_c)
|
||||
nk_input_key(ctx, NK_KEY_COPY, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_v)
|
||||
nk_input_key(ctx, NK_KEY_PASTE, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_x)
|
||||
nk_input_key(ctx, NK_KEY_CUT, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_b)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_e)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_UP)
|
||||
nk_input_key(ctx, NK_KEY_UP, down);
|
||||
else if (sym == SDLK_DOWN)
|
||||
nk_input_key(ctx, NK_KEY_DOWN, down);
|
||||
else if (sym == SDLK_LEFT) {
|
||||
switch(evt->key.keysym.sym)
|
||||
{
|
||||
case SDLK_RSHIFT: /* RSHIFT & LSHIFT share same routine */
|
||||
case SDLK_LSHIFT: nk_input_key(ctx, NK_KEY_SHIFT, down); break;
|
||||
case SDLK_DELETE: nk_input_key(ctx, NK_KEY_DEL, down); break;
|
||||
case SDLK_RETURN: nk_input_key(ctx, NK_KEY_ENTER, down); break;
|
||||
case SDLK_TAB: nk_input_key(ctx, NK_KEY_TAB, down); break;
|
||||
case SDLK_BACKSPACE: nk_input_key(ctx, NK_KEY_BACKSPACE, down); break;
|
||||
case SDLK_HOME: nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_START, down); break;
|
||||
case SDLK_END: nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_END, down); break;
|
||||
case SDLK_PAGEDOWN: nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down); break;
|
||||
case SDLK_PAGEUP: nk_input_key(ctx, NK_KEY_SCROLL_UP, down); break;
|
||||
case SDLK_z: nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_r: nk_input_key(ctx, NK_KEY_TEXT_REDO, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_c: nk_input_key(ctx, NK_KEY_COPY, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_v: nk_input_key(ctx, NK_KEY_PASTE, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_x: nk_input_key(ctx, NK_KEY_CUT, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_b: nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_e: nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_UP: nk_input_key(ctx, NK_KEY_UP, down); break;
|
||||
case SDLK_DOWN: nk_input_key(ctx, NK_KEY_DOWN, down); break;
|
||||
case SDLK_LEFT:
|
||||
if (state[SDL_SCANCODE_LCTRL])
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else nk_input_key(ctx, NK_KEY_LEFT, down);
|
||||
} else if (sym == SDLK_RIGHT) {
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
if (state[SDL_SCANCODE_LCTRL])
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else nk_input_key(ctx, NK_KEY_RIGHT, down);
|
||||
} else return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
} else if (evt->type == SDL_MOUSEBUTTONDOWN || evt->type == SDL_MOUSEBUTTONUP) {
|
||||
/* mouse button */
|
||||
|
||||
case SDL_MOUSEBUTTONUP: /* MOUSEBUTTONUP & MOUSEBUTTONDOWN share same routine */
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
int down = evt->type == SDL_MOUSEBUTTONDOWN;
|
||||
const int x = evt->button.x, y = evt->button.y;
|
||||
if (evt->button.button == SDL_BUTTON_LEFT) {
|
||||
switch(evt->button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
if (evt->button.clicks > 1)
|
||||
nk_input_button(ctx, NK_BUTTON_DOUBLE, x, y, down);
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down);
|
||||
} else if (evt->button.button == SDL_BUTTON_MIDDLE)
|
||||
nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down);
|
||||
else if (evt->button.button == SDL_BUTTON_RIGHT)
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down);
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down); break;
|
||||
case SDL_BUTTON_MIDDLE: nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down); break;
|
||||
case SDL_BUTTON_RIGHT: nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down); break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
} else if (evt->type == SDL_MOUSEMOTION) {
|
||||
/* mouse motion */
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
if (ctx->input.mouse.grabbed) {
|
||||
int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y;
|
||||
nk_input_motion(ctx, x + evt->motion.xrel, y + evt->motion.yrel);
|
||||
} else nk_input_motion(ctx, evt->motion.x, evt->motion.y);
|
||||
}
|
||||
else nk_input_motion(ctx, evt->motion.x, evt->motion.y);
|
||||
return 1;
|
||||
} else if (evt->type == SDL_TEXTINPUT) {
|
||||
/* text input */
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
nk_glyph glyph;
|
||||
memcpy(glyph, evt->text.text, NK_UTF_SIZE);
|
||||
nk_input_glyph(ctx, glyph);
|
||||
}
|
||||
return 1;
|
||||
} else if (evt->type == SDL_MOUSEWHEEL) {
|
||||
/* mouse wheel */
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
nk_input_scroll(ctx,nk_vec2((float)evt->wheel.x,(float)evt->wheel.y));
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
BIN = demo
|
||||
|
||||
# Flags
|
||||
CFLAGS += -std=c99 -pedantic -O2
|
||||
CFLAGS += -std=c89 -Wall -Wextra -pedantic -O2
|
||||
|
||||
SRC = main.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
|
|
@ -38,12 +38,37 @@
|
|||
*
|
||||
* ===============================================================*/
|
||||
/* This are some code examples to provide a small overview of what can be
|
||||
* done with this library. To try out an example uncomment the include
|
||||
* and the corresponding function. */
|
||||
/*#include "../style.c"*/
|
||||
/*#include "../calculator.c"*/
|
||||
/*#include "../overview.c"*/
|
||||
/*#include "../node_editor.c"*/
|
||||
* done with this library. To try out an example uncomment the defines */
|
||||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
|
@ -95,6 +120,7 @@ MainLoop(void* loopArg){
|
|||
nk_layout_row_end(ctx);
|
||||
nk_menubar_end(ctx);
|
||||
|
||||
{
|
||||
enum {EASY, HARD};
|
||||
static int op = EASY;
|
||||
static int property = 20;
|
||||
|
@ -107,12 +133,22 @@ MainLoop(void* loopArg){
|
|||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
|
||||
}
|
||||
}
|
||||
nk_end(ctx);
|
||||
|
||||
/* -------------- EXAMPLES ---------------- */
|
||||
/*calculator(ctx);*/
|
||||
/*overview(ctx);*/
|
||||
/*node_editor(ctx);*/
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
node_editor(ctx);
|
||||
#endif
|
||||
/* ----------------------------------------- */
|
||||
|
||||
/* Draw */
|
||||
|
@ -137,6 +173,10 @@ int main(int argc, char* argv[])
|
|||
/* GUI */
|
||||
struct nk_context *ctx;
|
||||
SDL_GLContext glContext;
|
||||
|
||||
NK_UNUSED(argc);
|
||||
NK_UNUSED(argv);
|
||||
|
||||
/* SDL setup */
|
||||
SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0");
|
||||
/*SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_EVENTS); // - do NOT init SDL on GL ES 2 */
|
||||
|
@ -169,10 +209,18 @@ int main(int argc, char* argv[])
|
|||
/*nk_style_set_font(ctx, &roboto->handle)*/;}
|
||||
|
||||
/* style.c */
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
#ifdef INCLUDE_STYLE
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#include <emscripten.h>
|
||||
|
|
|
@ -43,7 +43,7 @@ NK_API void nk_sdl_device_create(void);
|
|||
|
||||
struct nk_sdl_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
struct nk_draw_null_texture tex_null;
|
||||
GLuint vbo, ebo;
|
||||
GLuint prog;
|
||||
GLuint vert_shdr;
|
||||
|
@ -245,7 +245,7 @@ nk_sdl_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_b
|
|||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_sdl_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_sdl_vertex);
|
||||
config.null = dev->null;
|
||||
config.tex_null = dev->tex_null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
|
@ -335,7 +335,7 @@ nk_sdl_font_stash_end(void)
|
|||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&sdl.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_sdl_device_upload_atlas(image, w, h);
|
||||
nk_font_atlas_end(&sdl.atlas, nk_handle_id((int)sdl.ogl.font_tex), &sdl.ogl.null);
|
||||
nk_font_atlas_end(&sdl.atlas, nk_handle_id((int)sdl.ogl.font_tex), &sdl.ogl.tex_null);
|
||||
if (sdl.atlas.default_font)
|
||||
nk_style_set_font(&sdl.ctx, &sdl.atlas.default_font->handle);
|
||||
|
||||
|
@ -345,87 +345,96 @@ NK_API int
|
|||
nk_sdl_handle_event(SDL_Event *evt)
|
||||
{
|
||||
struct nk_context *ctx = &sdl.ctx;
|
||||
if (evt->type == SDL_KEYUP || evt->type == SDL_KEYDOWN) {
|
||||
/* key events */
|
||||
|
||||
/* optional grabbing behavior */
|
||||
if (ctx->input.mouse.grab) {
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
ctx->input.mouse.grab = 0;
|
||||
} else if (ctx->input.mouse.ungrab) {
|
||||
int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y;
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
SDL_WarpMouseInWindow(sdl.win, x, y);
|
||||
ctx->input.mouse.ungrab = 0;
|
||||
}
|
||||
|
||||
switch(evt->type)
|
||||
{
|
||||
case SDL_KEYUP: /* KEYUP & KEYDOWN share same routine */
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
int down = evt->type == SDL_KEYDOWN;
|
||||
const Uint8* state = SDL_GetKeyboardState(0);
|
||||
SDL_Keycode sym = evt->key.keysym.sym;
|
||||
if (sym == SDLK_RSHIFT || sym == SDLK_LSHIFT)
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, down);
|
||||
else if (sym == SDLK_DELETE)
|
||||
nk_input_key(ctx, NK_KEY_DEL, down);
|
||||
else if (sym == SDLK_RETURN)
|
||||
nk_input_key(ctx, NK_KEY_ENTER, down);
|
||||
else if (sym == SDLK_TAB)
|
||||
nk_input_key(ctx, NK_KEY_TAB, down);
|
||||
else if (sym == SDLK_BACKSPACE)
|
||||
nk_input_key(ctx, NK_KEY_BACKSPACE, down);
|
||||
else if (sym == SDLK_HOME) {
|
||||
nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_START, down);
|
||||
} else if (sym == SDLK_END) {
|
||||
nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_END, down);
|
||||
} else if (sym == SDLK_PAGEDOWN) {
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down);
|
||||
} else if (sym == SDLK_PAGEUP) {
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_UP, down);
|
||||
} else if (sym == SDLK_z)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_r)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_c)
|
||||
nk_input_key(ctx, NK_KEY_COPY, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_v)
|
||||
nk_input_key(ctx, NK_KEY_PASTE, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_x)
|
||||
nk_input_key(ctx, NK_KEY_CUT, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_b)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_e)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && state[SDL_SCANCODE_LCTRL]);
|
||||
else if (sym == SDLK_UP)
|
||||
nk_input_key(ctx, NK_KEY_UP, down);
|
||||
else if (sym == SDLK_DOWN)
|
||||
nk_input_key(ctx, NK_KEY_DOWN, down);
|
||||
else if (sym == SDLK_LEFT) {
|
||||
switch(evt->key.keysym.sym)
|
||||
{
|
||||
case SDLK_RSHIFT: /* RSHIFT & LSHIFT share same routine */
|
||||
case SDLK_LSHIFT: nk_input_key(ctx, NK_KEY_SHIFT, down); break;
|
||||
case SDLK_DELETE: nk_input_key(ctx, NK_KEY_DEL, down); break;
|
||||
case SDLK_RETURN: nk_input_key(ctx, NK_KEY_ENTER, down); break;
|
||||
case SDLK_TAB: nk_input_key(ctx, NK_KEY_TAB, down); break;
|
||||
case SDLK_BACKSPACE: nk_input_key(ctx, NK_KEY_BACKSPACE, down); break;
|
||||
case SDLK_HOME: nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_START, down); break;
|
||||
case SDLK_END: nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_END, down); break;
|
||||
case SDLK_PAGEDOWN: nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down); break;
|
||||
case SDLK_PAGEUP: nk_input_key(ctx, NK_KEY_SCROLL_UP, down); break;
|
||||
case SDLK_z: nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_r: nk_input_key(ctx, NK_KEY_TEXT_REDO, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_c: nk_input_key(ctx, NK_KEY_COPY, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_v: nk_input_key(ctx, NK_KEY_PASTE, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_x: nk_input_key(ctx, NK_KEY_CUT, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_b: nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_e: nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_UP: nk_input_key(ctx, NK_KEY_UP, down); break;
|
||||
case SDLK_DOWN: nk_input_key(ctx, NK_KEY_DOWN, down); break;
|
||||
case SDLK_LEFT:
|
||||
if (state[SDL_SCANCODE_LCTRL])
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else nk_input_key(ctx, NK_KEY_LEFT, down);
|
||||
} else if (sym == SDLK_RIGHT) {
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
if (state[SDL_SCANCODE_LCTRL])
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else nk_input_key(ctx, NK_KEY_RIGHT, down);
|
||||
} else return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
} else if (evt->type == SDL_MOUSEBUTTONDOWN || evt->type == SDL_MOUSEBUTTONUP) {
|
||||
/* mouse button */
|
||||
|
||||
case SDL_MOUSEBUTTONUP: /* MOUSEBUTTONUP & MOUSEBUTTONDOWN share same routine */
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
int down = evt->type == SDL_MOUSEBUTTONDOWN;
|
||||
const int x = evt->button.x, y = evt->button.y;
|
||||
if (evt->button.button == SDL_BUTTON_LEFT) {
|
||||
switch(evt->button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
if (evt->button.clicks > 1)
|
||||
nk_input_button(ctx, NK_BUTTON_DOUBLE, x, y, down);
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down);
|
||||
} else if (evt->button.button == SDL_BUTTON_MIDDLE)
|
||||
nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down);
|
||||
else if (evt->button.button == SDL_BUTTON_RIGHT)
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down);
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down); break;
|
||||
case SDL_BUTTON_MIDDLE: nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down); break;
|
||||
case SDL_BUTTON_RIGHT: nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down); break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
} else if (evt->type == SDL_MOUSEMOTION) {
|
||||
/* mouse motion */
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
if (ctx->input.mouse.grabbed) {
|
||||
int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y;
|
||||
nk_input_motion(ctx, x + evt->motion.xrel, y + evt->motion.yrel);
|
||||
} else nk_input_motion(ctx, evt->motion.x, evt->motion.y);
|
||||
}
|
||||
else nk_input_motion(ctx, evt->motion.x, evt->motion.y);
|
||||
return 1;
|
||||
} else if (evt->type == SDL_TEXTINPUT) {
|
||||
/* text input */
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
nk_glyph glyph;
|
||||
memcpy(glyph, evt->text.text, NK_UTF_SIZE);
|
||||
nk_input_glyph(ctx, glyph);
|
||||
}
|
||||
return 1;
|
||||
} else if (evt->type == SDL_MOUSEWHEEL) {
|
||||
/* mouse wheel */
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
nk_input_scroll(ctx,nk_vec2((float)evt->wheel.x,(float)evt->wheel.y));
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# Install
|
||||
BIN = demo
|
||||
|
||||
# Flags
|
||||
CFLAGS += -std=c89 -pedantic -O0
|
||||
CFLAGS += `sdl2-config --cflags`
|
||||
|
||||
SRC = main.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
#TODO
|
||||
#BIN := $(BIN).exe
|
||||
#LIBS = -lmingw32 -lSDL2main -lSDL2 -lopengl32 -lm -lGLU32
|
||||
else
|
||||
UNAME_S := $(shell uname -s)
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
#TODO LIBS = -lSDL2 -framework OpenGL -lm
|
||||
else
|
||||
LIBS += -lm -ldl `sdl2-config --libs`
|
||||
endif
|
||||
endif
|
||||
|
||||
$(BIN):
|
||||
@mkdir -p bin
|
||||
rm -f bin/$(BIN) $(OBJS)
|
||||
$(CC) $(SRC) $(CFLAGS) -o bin/$(BIN) $(LIBS)
|
|
@ -0,0 +1,245 @@
|
|||
/* nuklear - 1.32.0 - public domain */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_STANDARD_VARARGS
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||
#define NK_INCLUDE_FONT_BAKING
|
||||
#define NK_INCLUDE_DEFAULT_FONT
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_SDL_RENDERER_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include "nuklear_sdl_renderer.h"
|
||||
|
||||
#define WINDOW_WIDTH 1200
|
||||
#define WINDOW_HEIGHT 800
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* ===============================================================*/
|
||||
/* This are some code examples to provide a small overview of what can be
|
||||
* done with this library. To try out an example uncomment the defines */
|
||||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* DEMO
|
||||
*
|
||||
* ===============================================================*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
/* Platform */
|
||||
SDL_Window *win;
|
||||
SDL_Renderer *renderer;
|
||||
int running = 1;
|
||||
int flags = 0;
|
||||
float font_scale = 1;
|
||||
|
||||
/* GUI */
|
||||
struct nk_context *ctx;
|
||||
struct nk_colorf bg;
|
||||
|
||||
/* SDL setup */
|
||||
SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0");
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
|
||||
win = SDL_CreateWindow("Demo",
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN|SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
|
||||
if (win == NULL) {
|
||||
SDL_Log("Error SDL_CreateWindow %s", SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
flags |= SDL_RENDERER_ACCELERATED;
|
||||
flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
|
||||
#if 0
|
||||
SDL_SetHint(SDL_HINT_RENDER_BATCHING, "1");
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles2");
|
||||
#endif
|
||||
|
||||
renderer = SDL_CreateRenderer(win, -1, flags);
|
||||
|
||||
if (renderer == NULL) {
|
||||
SDL_Log("Error SDL_CreateRenderer %s", SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* scale the renderer output for High-DPI displays */
|
||||
{
|
||||
int render_w, render_h;
|
||||
int window_w, window_h;
|
||||
float scale_x, scale_y;
|
||||
SDL_GetRendererOutputSize(renderer, &render_w, &render_h);
|
||||
SDL_GetWindowSize(win, &window_w, &window_h);
|
||||
scale_x = (float)(render_w) / (float)(window_w);
|
||||
scale_y = (float)(render_h) / (float)(window_h);
|
||||
SDL_RenderSetScale(renderer, scale_x, scale_y);
|
||||
font_scale = scale_y;
|
||||
}
|
||||
|
||||
/* GUI */
|
||||
ctx = nk_sdl_init(win, renderer);
|
||||
/* Load Fonts: if none of these are loaded a default font will be used */
|
||||
/* Load Cursor: if you uncomment cursor loading please hide the cursor */
|
||||
{
|
||||
struct nk_font_atlas *atlas;
|
||||
struct nk_font_config config = nk_font_config(0);
|
||||
struct nk_font *font;
|
||||
|
||||
/* set up the font atlas and add desired font; note that font sizes are
|
||||
* multiplied by font_scale to produce better results at higher DPIs */
|
||||
nk_sdl_font_stash_begin(&atlas);
|
||||
font = nk_font_atlas_add_default(atlas, 13 * font_scale, &config);
|
||||
/*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14 * font_scale, &config);*/
|
||||
/*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Roboto-Regular.ttf", 16 * font_scale, &config);*/
|
||||
/*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13 * font_scale, &config);*/
|
||||
/*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12 * font_scale, &config);*/
|
||||
/*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10 * font_scale, &config);*/
|
||||
/*font = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13 * font_scale, &config);*/
|
||||
nk_sdl_font_stash_end();
|
||||
|
||||
/* this hack makes the font appear to be scaled down to the desired
|
||||
* size and is only necessary when font_scale > 1 */
|
||||
font->handle.height /= font_scale;
|
||||
/*nk_style_load_all_cursors(ctx, atlas->cursors);*/
|
||||
nk_style_set_font(ctx, &font->handle);
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
|
||||
while (running)
|
||||
{
|
||||
/* Input */
|
||||
SDL_Event evt;
|
||||
nk_input_begin(ctx);
|
||||
while (SDL_PollEvent(&evt)) {
|
||||
if (evt.type == SDL_QUIT) goto cleanup;
|
||||
nk_sdl_handle_event(&evt);
|
||||
}
|
||||
nk_input_end(ctx);
|
||||
|
||||
/* GUI */
|
||||
if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250),
|
||||
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
|
||||
NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
|
||||
{
|
||||
enum {EASY, HARD};
|
||||
static int op = EASY;
|
||||
static int property = 20;
|
||||
|
||||
nk_layout_row_static(ctx, 30, 80, 1);
|
||||
if (nk_button_label(ctx, "button"))
|
||||
fprintf(stdout, "button pressed\n");
|
||||
nk_layout_row_dynamic(ctx, 30, 2);
|
||||
if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
|
||||
if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 20, 1);
|
||||
nk_label(ctx, "background:", NK_TEXT_LEFT);
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
if (nk_combo_begin_color(ctx, nk_rgb_cf(bg), nk_vec2(nk_widget_width(ctx),400))) {
|
||||
nk_layout_row_dynamic(ctx, 120, 1);
|
||||
bg = nk_color_picker(ctx, bg, NK_RGBA);
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
bg.r = nk_propertyf(ctx, "#R:", 0, bg.r, 1.0f, 0.01f,0.005f);
|
||||
bg.g = nk_propertyf(ctx, "#G:", 0, bg.g, 1.0f, 0.01f,0.005f);
|
||||
bg.b = nk_propertyf(ctx, "#B:", 0, bg.b, 1.0f, 0.01f,0.005f);
|
||||
bg.a = nk_propertyf(ctx, "#A:", 0, bg.a, 1.0f, 0.01f,0.005f);
|
||||
nk_combo_end(ctx);
|
||||
}
|
||||
}
|
||||
nk_end(ctx);
|
||||
|
||||
/* -------------- EXAMPLES ---------------- */
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
node_editor(ctx);
|
||||
#endif
|
||||
/* ----------------------------------------- */
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, bg.r * 255, bg.g * 255, bg.b * 255, bg.a * 255);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
nk_sdl_render(NK_ANTI_ALIASING_ON);
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
nk_sdl_shutdown();
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(win);
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,379 @@
|
|||
/*
|
||||
* Nuklear - 4.9.4 - public domain
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_SDL_RENDERER_H_
|
||||
#define NK_SDL_RENDERER_H_
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
NK_API struct nk_context* nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer);
|
||||
NK_API void nk_sdl_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_sdl_font_stash_end(void);
|
||||
NK_API int nk_sdl_handle_event(SDL_Event *evt);
|
||||
NK_API void nk_sdl_render(enum nk_anti_aliasing);
|
||||
NK_API void nk_sdl_shutdown(void);
|
||||
|
||||
#if SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 22)
|
||||
/* Metal API does not support cliprects with negative coordinates or large
|
||||
* dimensions. The issue is fixed in SDL2 with version 2.0.22 but until
|
||||
* that version is released, the NK_SDL_CLAMP_CLIP_RECT flag can be used to
|
||||
* ensure the cliprect is itself clipped to the viewport.
|
||||
* See discussion at https://discourse.libsdl.org/t/rendergeometryraw-producing-different-results-in-metal-vs-opengl/34953
|
||||
*/
|
||||
#define NK_SDL_CLAMP_CLIP_RECT
|
||||
#endif
|
||||
|
||||
#endif /* NK_SDL_RENDERER_H_ */
|
||||
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_SDL_RENDERER_IMPLEMENTATION
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
struct nk_sdl_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture tex_null;
|
||||
SDL_Texture *font_tex;
|
||||
};
|
||||
|
||||
struct nk_sdl_vertex {
|
||||
float position[2];
|
||||
float uv[2];
|
||||
nk_byte col[4];
|
||||
};
|
||||
|
||||
static struct nk_sdl {
|
||||
SDL_Window *win;
|
||||
SDL_Renderer *renderer;
|
||||
struct nk_sdl_device ogl;
|
||||
struct nk_context ctx;
|
||||
struct nk_font_atlas atlas;
|
||||
} sdl;
|
||||
|
||||
|
||||
|
||||
NK_INTERN void
|
||||
nk_sdl_device_upload_atlas(const void *image, int width, int height)
|
||||
{
|
||||
struct nk_sdl_device *dev = &sdl.ogl;
|
||||
|
||||
SDL_Texture *g_SDLFontTexture = SDL_CreateTexture(sdl.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height);
|
||||
if (g_SDLFontTexture == NULL) {
|
||||
SDL_Log("error creating texture");
|
||||
return;
|
||||
}
|
||||
SDL_UpdateTexture(g_SDLFontTexture, NULL, image, 4 * width);
|
||||
SDL_SetTextureBlendMode(g_SDLFontTexture, SDL_BLENDMODE_BLEND);
|
||||
dev->font_tex = g_SDLFontTexture;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_sdl_render(enum nk_anti_aliasing AA)
|
||||
{
|
||||
/* setup global state */
|
||||
struct nk_sdl_device *dev = &sdl.ogl;
|
||||
|
||||
{
|
||||
SDL_Rect saved_clip;
|
||||
#ifdef NK_SDL_CLAMP_CLIP_RECT
|
||||
SDL_Rect viewport;
|
||||
#endif
|
||||
SDL_bool clipping_enabled;
|
||||
int vs = sizeof(struct nk_sdl_vertex);
|
||||
size_t vp = offsetof(struct nk_sdl_vertex, position);
|
||||
size_t vt = offsetof(struct nk_sdl_vertex, uv);
|
||||
size_t vc = offsetof(struct nk_sdl_vertex, col);
|
||||
|
||||
/* convert from command queue into draw list and draw to screen */
|
||||
const struct nk_draw_command *cmd;
|
||||
const nk_draw_index *offset = NULL;
|
||||
struct nk_buffer vbuf, ebuf;
|
||||
|
||||
/* fill converting configuration */
|
||||
struct nk_convert_config config;
|
||||
static const struct nk_draw_vertex_layout_element vertex_layout[] = {
|
||||
{NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, position)},
|
||||
{NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_sdl_vertex, uv)},
|
||||
{NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_sdl_vertex, col)},
|
||||
{NK_VERTEX_LAYOUT_END}
|
||||
};
|
||||
NK_MEMSET(&config, 0, sizeof(config));
|
||||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_sdl_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_sdl_vertex);
|
||||
config.tex_null = dev->tex_null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
config.global_alpha = 1.0f;
|
||||
config.shape_AA = AA;
|
||||
config.line_AA = AA;
|
||||
|
||||
/* convert shapes into vertexes */
|
||||
nk_buffer_init_default(&vbuf);
|
||||
nk_buffer_init_default(&ebuf);
|
||||
nk_convert(&sdl.ctx, &dev->cmds, &vbuf, &ebuf, &config);
|
||||
|
||||
/* iterate over and execute each draw command */
|
||||
offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf);
|
||||
|
||||
clipping_enabled = SDL_RenderIsClipEnabled(sdl.renderer);
|
||||
SDL_RenderGetClipRect(sdl.renderer, &saved_clip);
|
||||
#ifdef NK_SDL_CLAMP_CLIP_RECT
|
||||
SDL_RenderGetViewport(sdl.renderer, &viewport);
|
||||
#endif
|
||||
|
||||
nk_draw_foreach(cmd, &sdl.ctx, &dev->cmds)
|
||||
{
|
||||
if (!cmd->elem_count) continue;
|
||||
|
||||
{
|
||||
SDL_Rect r;
|
||||
r.x = cmd->clip_rect.x;
|
||||
r.y = cmd->clip_rect.y;
|
||||
r.w = cmd->clip_rect.w;
|
||||
r.h = cmd->clip_rect.h;
|
||||
#ifdef NK_SDL_CLAMP_CLIP_RECT
|
||||
if (r.x < 0) {
|
||||
r.w += r.x;
|
||||
r.x = 0;
|
||||
}
|
||||
if (r.y < 0) {
|
||||
r.h += r.y;
|
||||
r.y = 0;
|
||||
}
|
||||
if (r.h > viewport.h) {
|
||||
r.h = viewport.h;
|
||||
}
|
||||
if (r.w > viewport.w) {
|
||||
r.w = viewport.w;
|
||||
}
|
||||
#endif
|
||||
SDL_RenderSetClipRect(sdl.renderer, &r);
|
||||
}
|
||||
|
||||
{
|
||||
const void *vertices = nk_buffer_memory_const(&vbuf);
|
||||
|
||||
SDL_RenderGeometryRaw(sdl.renderer,
|
||||
(SDL_Texture *)cmd->texture.ptr,
|
||||
(const float*)((const nk_byte*)vertices + vp), vs,
|
||||
(const SDL_Color*)((const nk_byte*)vertices + vc), vs,
|
||||
(const float*)((const nk_byte*)vertices + vt), vs,
|
||||
(vbuf.needed / vs),
|
||||
(void *) offset, cmd->elem_count, 2);
|
||||
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_RenderSetClipRect(sdl.renderer, &saved_clip);
|
||||
if (!clipping_enabled) {
|
||||
SDL_RenderSetClipRect(sdl.renderer, NULL);
|
||||
}
|
||||
|
||||
nk_clear(&sdl.ctx);
|
||||
nk_buffer_clear(&dev->cmds);
|
||||
nk_buffer_free(&vbuf);
|
||||
nk_buffer_free(&ebuf);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||
{
|
||||
const char *text = SDL_GetClipboardText();
|
||||
if (text) nk_textedit_paste(edit, text, nk_strlen(text));
|
||||
(void)usr;
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_clipboard_copy(nk_handle usr, const char *text, int len)
|
||||
{
|
||||
char *str = 0;
|
||||
(void)usr;
|
||||
if (!len) return;
|
||||
str = (char*)malloc((size_t)len+1);
|
||||
if (!str) return;
|
||||
memcpy(str, text, (size_t)len);
|
||||
str[len] = '\0';
|
||||
SDL_SetClipboardText(str);
|
||||
free(str);
|
||||
}
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_sdl_init(SDL_Window *win, SDL_Renderer *renderer)
|
||||
{
|
||||
#ifndef NK_SDL_CLAMP_CLIP_RECT
|
||||
SDL_RendererInfo info;
|
||||
SDL_version runtimeVer;
|
||||
|
||||
/* warn for cases where NK_SDL_CLAMP_CLIP_RECT should have been set but isn't */
|
||||
SDL_GetRendererInfo(renderer, &info);
|
||||
SDL_GetVersion(&runtimeVer);
|
||||
if (strncmp("metal", info.name, 5) == 0 &&
|
||||
SDL_VERSIONNUM(runtimeVer.major, runtimeVer.minor, runtimeVer.patch) < SDL_VERSIONNUM(2, 0, 22))
|
||||
{
|
||||
SDL_LogWarn(
|
||||
SDL_LOG_CATEGORY_APPLICATION,
|
||||
"renderer is using Metal API but runtime SDL version %d.%d.%d is older than compiled version %d.%d.%d, "
|
||||
"which may cause issues with rendering",
|
||||
runtimeVer.major, runtimeVer.minor, runtimeVer.patch,
|
||||
SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL
|
||||
);
|
||||
}
|
||||
#endif
|
||||
sdl.win = win;
|
||||
sdl.renderer = renderer;
|
||||
nk_init_default(&sdl.ctx, 0);
|
||||
sdl.ctx.clip.copy = nk_sdl_clipboard_copy;
|
||||
sdl.ctx.clip.paste = nk_sdl_clipboard_paste;
|
||||
sdl.ctx.clip.userdata = nk_handle_ptr(0);
|
||||
nk_buffer_init_default(&sdl.ogl.cmds);
|
||||
return &sdl.ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_sdl_font_stash_begin(struct nk_font_atlas **atlas)
|
||||
{
|
||||
nk_font_atlas_init_default(&sdl.atlas);
|
||||
nk_font_atlas_begin(&sdl.atlas);
|
||||
*atlas = &sdl.atlas;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_sdl_font_stash_end(void)
|
||||
{
|
||||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&sdl.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_sdl_device_upload_atlas(image, w, h);
|
||||
nk_font_atlas_end(&sdl.atlas, nk_handle_ptr(sdl.ogl.font_tex), &sdl.ogl.tex_null);
|
||||
if (sdl.atlas.default_font)
|
||||
nk_style_set_font(&sdl.ctx, &sdl.atlas.default_font->handle);
|
||||
}
|
||||
|
||||
NK_API int
|
||||
nk_sdl_handle_event(SDL_Event *evt)
|
||||
{
|
||||
struct nk_context *ctx = &sdl.ctx;
|
||||
|
||||
/* optional grabbing behavior */
|
||||
if (ctx->input.mouse.grab) {
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
ctx->input.mouse.grab = 0;
|
||||
} else if (ctx->input.mouse.ungrab) {
|
||||
int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y;
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
SDL_WarpMouseInWindow(sdl.win, x, y);
|
||||
ctx->input.mouse.ungrab = 0;
|
||||
}
|
||||
|
||||
switch(evt->type)
|
||||
{
|
||||
case SDL_KEYUP: /* KEYUP & KEYDOWN share same routine */
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
int down = evt->type == SDL_KEYDOWN;
|
||||
const Uint8* state = SDL_GetKeyboardState(0);
|
||||
switch(evt->key.keysym.sym)
|
||||
{
|
||||
case SDLK_RSHIFT: /* RSHIFT & LSHIFT share same routine */
|
||||
case SDLK_LSHIFT: nk_input_key(ctx, NK_KEY_SHIFT, down); break;
|
||||
case SDLK_DELETE: nk_input_key(ctx, NK_KEY_DEL, down); break;
|
||||
case SDLK_RETURN: nk_input_key(ctx, NK_KEY_ENTER, down); break;
|
||||
case SDLK_TAB: nk_input_key(ctx, NK_KEY_TAB, down); break;
|
||||
case SDLK_BACKSPACE: nk_input_key(ctx, NK_KEY_BACKSPACE, down); break;
|
||||
case SDLK_HOME: nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_START, down); break;
|
||||
case SDLK_END: nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_END, down); break;
|
||||
case SDLK_PAGEDOWN: nk_input_key(ctx, NK_KEY_SCROLL_DOWN, down); break;
|
||||
case SDLK_PAGEUP: nk_input_key(ctx, NK_KEY_SCROLL_UP, down); break;
|
||||
case SDLK_z: nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_r: nk_input_key(ctx, NK_KEY_TEXT_REDO, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_c: nk_input_key(ctx, NK_KEY_COPY, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_v: nk_input_key(ctx, NK_KEY_PASTE, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_x: nk_input_key(ctx, NK_KEY_CUT, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_b: nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_e: nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && state[SDL_SCANCODE_LCTRL]); break;
|
||||
case SDLK_UP: nk_input_key(ctx, NK_KEY_UP, down); break;
|
||||
case SDLK_DOWN: nk_input_key(ctx, NK_KEY_DOWN, down); break;
|
||||
case SDLK_LEFT:
|
||||
if (state[SDL_SCANCODE_LCTRL])
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else nk_input_key(ctx, NK_KEY_LEFT, down);
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
if (state[SDL_SCANCODE_LCTRL])
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else nk_input_key(ctx, NK_KEY_RIGHT, down);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
case SDL_MOUSEBUTTONUP: /* MOUSEBUTTONUP & MOUSEBUTTONDOWN share same routine */
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
int down = evt->type == SDL_MOUSEBUTTONDOWN;
|
||||
const int x = evt->button.x, y = evt->button.y;
|
||||
switch(evt->button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
if (evt->button.clicks > 1)
|
||||
nk_input_button(ctx, NK_BUTTON_DOUBLE, x, y, down);
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down); break;
|
||||
case SDL_BUTTON_MIDDLE: nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down); break;
|
||||
case SDL_BUTTON_RIGHT: nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down); break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
if (ctx->input.mouse.grabbed) {
|
||||
int x = (int)ctx->input.mouse.prev.x, y = (int)ctx->input.mouse.prev.y;
|
||||
nk_input_motion(ctx, x + evt->motion.xrel, y + evt->motion.yrel);
|
||||
}
|
||||
else nk_input_motion(ctx, evt->motion.x, evt->motion.y);
|
||||
return 1;
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
nk_glyph glyph;
|
||||
memcpy(glyph, evt->text.text, NK_UTF_SIZE);
|
||||
nk_input_glyph(ctx, glyph);
|
||||
}
|
||||
return 1;
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
nk_input_scroll(ctx,nk_vec2((float)evt->wheel.x,(float)evt->wheel.y));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
NK_API
|
||||
void nk_sdl_shutdown(void)
|
||||
{
|
||||
struct nk_sdl_device *dev = &sdl.ogl;
|
||||
nk_font_atlas_clear(&sdl.atlas);
|
||||
nk_free(&sdl.ctx);
|
||||
SDL_DestroyTexture(dev->font_tex);
|
||||
/* glDeleteTextures(1, &dev->font_tex); */
|
||||
nk_buffer_free(&dev->cmds);
|
||||
memset(&sdl, 0, sizeof(sdl));
|
||||
}
|
||||
|
||||
#endif /* NK_SDL_RENDERER_IMPLEMENTATION */
|
|
@ -3,7 +3,7 @@ CC = g++
|
|||
BIN = demo
|
||||
|
||||
# Flags
|
||||
CFLAGS += -s -O2
|
||||
CFLAGS += -s -Wall -Wextra -pedantic -O2
|
||||
|
||||
SRC = main.cpp
|
||||
OBJ = $(SRC:.cpp=.o)
|
||||
|
|
|
@ -37,27 +37,32 @@
|
|||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -93,10 +98,16 @@ int main(void)
|
|||
|
||||
/* style.c */
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct nk_colorf bg;
|
||||
|
@ -154,6 +165,9 @@ int main(void)
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
|
|
@ -34,7 +34,7 @@ NK_API void nk_sfml_shutdown(void);
|
|||
|
||||
struct nk_sfml_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
struct nk_draw_null_texture tex_null;
|
||||
GLuint font_tex;
|
||||
};
|
||||
|
||||
|
@ -118,7 +118,7 @@ nk_sfml_render(enum nk_anti_aliasing AA)
|
|||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_sfml_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_sfml_vertex);
|
||||
config.null = dev->null;
|
||||
config.tex_null = dev->tex_null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
|
@ -189,6 +189,9 @@ nk_sfml_clipboard_paste(nk_handle usr, struct nk_text_edit* edit)
|
|||
if(text)
|
||||
nk_textedit_paste(edit, text, nk_strlen(text));
|
||||
(void)usr;
|
||||
#else
|
||||
NK_UNUSED(usr);
|
||||
NK_UNUSED(edit);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -208,6 +211,10 @@ nk_sfml_clipboard_copy(nk_handle usr, const char* text, int len)
|
|||
sf::Clipboard clipboard(sfml.window);
|
||||
clipboard.setText(str);
|
||||
free(str);
|
||||
#else
|
||||
NK_UNUSED(usr);
|
||||
NK_UNUSED(text);
|
||||
NK_UNUSED(len);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -238,7 +245,7 @@ nk_sfml_font_stash_end()
|
|||
const void* img;
|
||||
img = nk_font_atlas_bake(&sfml.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_sfml_device_upload_atlas(img, w, h);
|
||||
nk_font_atlas_end(&sfml.atlas, nk_handle_id((int)sfml.ogl.font_tex), &sfml.ogl.null);
|
||||
nk_font_atlas_end(&sfml.atlas, nk_handle_id((int)sfml.ogl.font_tex), &sfml.ogl.tex_null);
|
||||
if(sfml.atlas.default_font)
|
||||
nk_style_set_font(&sfml.ctx, &sfml.atlas.default_font->handle);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ CC = g++
|
|||
BIN = demo
|
||||
|
||||
# Flags
|
||||
CFLAGS += -s -O2
|
||||
CFLAGS += -s -Wall -Wextra -pedantic -O2
|
||||
|
||||
SRC = main.cpp
|
||||
OBJ = $(SRC:.cpp=.o)
|
||||
|
|
|
@ -39,27 +39,32 @@
|
|||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -99,10 +104,16 @@ int main(void)
|
|||
|
||||
/* style.c */
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct nk_colorf bg;
|
||||
|
@ -161,6 +172,9 @@ int main(void)
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
|
|
@ -43,7 +43,7 @@ NK_API void nk_sfml_device_destroy(void);
|
|||
|
||||
struct nk_sfml_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
struct nk_draw_null_texture tex_null;
|
||||
GLuint vbo, vao, ebo;
|
||||
GLuint prog;
|
||||
GLuint vert_shdr;
|
||||
|
@ -248,7 +248,7 @@ nk_sfml_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_
|
|||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_sfml_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_sfml_vertex);
|
||||
config.null = dev->null;
|
||||
config.tex_null = dev->tex_null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
|
@ -298,6 +298,9 @@ nk_sfml_clipboard_paste(nk_handle usr, struct nk_text_edit* edit)
|
|||
sf::Clipboard clipboard(sfml.window);
|
||||
const char* text = clipboard.getText();
|
||||
if(text) nk_textedit_paste(edit, text, nk_strlen(text));
|
||||
#else
|
||||
NK_UNUSED(usr);
|
||||
NK_UNUSED(edit);
|
||||
#endif
|
||||
}
|
||||
static void
|
||||
|
@ -316,6 +319,10 @@ nk_sfml_clipboard_copy(nk_handle usr, const char* text, int len)
|
|||
sf::Clipboard clipboard(sfml.window);
|
||||
clipboard.setText(str);
|
||||
free(str);
|
||||
#else
|
||||
NK_UNUSED(usr);
|
||||
NK_UNUSED(text);
|
||||
NK_UNUSED(len);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -346,7 +353,7 @@ nk_sfml_font_stash_end()
|
|||
int w, h;
|
||||
image = nk_font_atlas_bake(&sfml.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_sfml_device_upload_atlas(image, w, h);
|
||||
nk_font_atlas_end(&sfml.atlas, nk_handle_id((int)sfml.ogl.font_tex), &sfml.ogl.null);
|
||||
nk_font_atlas_end(&sfml.atlas, nk_handle_id((int)sfml.ogl.font_tex), &sfml.ogl.tex_null);
|
||||
if(sfml.atlas.default_font)
|
||||
nk_style_set_font(&sfml.ctx, &sfml.atlas.default_font->handle);
|
||||
}
|
||||
|
|
|
@ -2,12 +2,12 @@ WAYLAND=`pkg-config wayland-client --cflags --libs`
|
|||
WAYLAND_SCANNER=wayland-scanner
|
||||
WAYLAND_PROTOCOLS_DIR=/usr/share/wayland-protocols
|
||||
|
||||
CFLAGS?=-std=c11 -Wall -Werror -O3 -fvisibility=hidden
|
||||
CFLAGS?=-std=c99 -Wall -Wextra -pedantic -Wno-unused-function -O3 -fvisibility=hidden
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
demo: main.c xdg-shell.c xdg-shell.h
|
||||
$(CC) -o demo *.c $(WAYLAND) -lrt -lm
|
||||
$(CC) $(CFLAGS) -o demo *.c $(WAYLAND) -lrt -lm
|
||||
|
||||
xdg-shell.c:
|
||||
$(WAYLAND_SCANNER) code $(WAYLAND_PROTOCOLS_DIR)/stable/xdg-shell/xdg-shell.xml xdg-shell.c
|
||||
|
|
|
@ -28,25 +28,79 @@
|
|||
|
||||
#define DTIME 20
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* ===============================================================*/
|
||||
/* This are some code examples to provide a small overview of what can be
|
||||
* done with this library. To try out an example uncomment the defines */
|
||||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
|
||||
//WAYLAND OUTPUT INTERFACE
|
||||
static void nk_wayland_output_cb_geometry(void *data, struct wl_output *wl_output, int x, int y, int w, int h, int subpixel, const char *make, const char *model, int transform)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(wl_output);
|
||||
NK_UNUSED(subpixel);
|
||||
NK_UNUSED(make);
|
||||
NK_UNUSED(model);
|
||||
NK_UNUSED(transform);
|
||||
|
||||
printf("wl_output geometry x=%d, y=%d, w=%d, h=%d make=%s, model=%s \n", x,y,w,h, make, model);
|
||||
}
|
||||
|
||||
static void nk_wayland_output_cb_mode(void *data, struct wl_output *wl_output, unsigned int flags, int w, int h, int refresh)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(wl_output);
|
||||
NK_UNUSED(flags);
|
||||
NK_UNUSED(w);
|
||||
NK_UNUSED(h);
|
||||
NK_UNUSED(refresh);
|
||||
}
|
||||
|
||||
static void nk_wayland_output_cb_done(void *data, struct wl_output *output)
|
||||
{
|
||||
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(output);
|
||||
}
|
||||
|
||||
static void nk_wayland_output_cb_scale(void *data, struct wl_output *output, int scale)
|
||||
{
|
||||
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(output);
|
||||
NK_UNUSED(scale);
|
||||
}
|
||||
|
||||
static const struct wl_output_listener nk_wayland_output_listener =
|
||||
|
@ -61,15 +115,29 @@ static const struct wl_output_listener nk_wayland_output_listener =
|
|||
//WAYLAND POINTER INTERFACE (mouse/touchpad)
|
||||
static void nk_wayland_pointer_enter (void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(pointer);
|
||||
NK_UNUSED(serial);
|
||||
NK_UNUSED(surface);
|
||||
NK_UNUSED(surface_x);
|
||||
NK_UNUSED(surface_y);
|
||||
}
|
||||
|
||||
static void nk_wayland_pointer_leave (void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(pointer);
|
||||
NK_UNUSED(serial);
|
||||
NK_UNUSED(surface);
|
||||
}
|
||||
|
||||
static void nk_wayland_pointer_motion (void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y)
|
||||
{
|
||||
struct nk_wayland* win = (struct nk_wayland*)data;
|
||||
|
||||
NK_UNUSED(pointer);
|
||||
NK_UNUSED(time);
|
||||
|
||||
win->mouse_pointer_x = wl_fixed_to_int(x);
|
||||
win->mouse_pointer_y = wl_fixed_to_int(y);
|
||||
|
||||
|
@ -80,6 +148,10 @@ static void nk_wayland_pointer_button (void *data, struct wl_pointer *pointer, u
|
|||
{
|
||||
struct nk_wayland* win = (struct nk_wayland*)data;
|
||||
|
||||
NK_UNUSED(pointer);
|
||||
NK_UNUSED(serial);
|
||||
NK_UNUSED(time);
|
||||
|
||||
if (button == 272){ //left mouse button
|
||||
if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
|
||||
// printf("nk_input_button x=%d, y=%d press: 1 \n", win->mouse_pointer_x, win->mouse_pointer_y);
|
||||
|
@ -93,6 +165,11 @@ static void nk_wayland_pointer_button (void *data, struct wl_pointer *pointer, u
|
|||
|
||||
static void nk_wayland_pointer_axis (void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(pointer);
|
||||
NK_UNUSED(time);
|
||||
NK_UNUSED(axis);
|
||||
NK_UNUSED(value);
|
||||
}
|
||||
|
||||
static struct wl_pointer_listener nk_wayland_pointer_listener =
|
||||
|
@ -101,30 +178,60 @@ static struct wl_pointer_listener nk_wayland_pointer_listener =
|
|||
&nk_wayland_pointer_leave,
|
||||
&nk_wayland_pointer_motion,
|
||||
&nk_wayland_pointer_button,
|
||||
&nk_wayland_pointer_axis
|
||||
&nk_wayland_pointer_axis,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
//-------------------------------------------------------------------- endof WAYLAND POINTER INTERFACE
|
||||
|
||||
//WAYLAND KEYBOARD INTERFACE
|
||||
static void nk_wayland_keyboard_keymap (void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(keyboard);
|
||||
NK_UNUSED(format);
|
||||
NK_UNUSED(fd);
|
||||
NK_UNUSED(size);
|
||||
}
|
||||
|
||||
static void nk_wayland_keyboard_enter (void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(keyboard);
|
||||
NK_UNUSED(serial);
|
||||
NK_UNUSED(surface);
|
||||
NK_UNUSED(keys);
|
||||
}
|
||||
|
||||
static void nk_wayland_keyboard_leave (void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(keyboard);
|
||||
NK_UNUSED(serial);
|
||||
NK_UNUSED(surface);
|
||||
}
|
||||
|
||||
static void nk_wayland_keyboard_key (void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(keyboard);
|
||||
NK_UNUSED(serial);
|
||||
NK_UNUSED(time);
|
||||
NK_UNUSED(state);
|
||||
printf("key: %d \n", key);
|
||||
}
|
||||
|
||||
static void nk_wayland_keyboard_modifiers (void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(keyboard);
|
||||
NK_UNUSED(serial);
|
||||
NK_UNUSED(mods_depressed);
|
||||
NK_UNUSED(mods_latched);
|
||||
NK_UNUSED(mods_locked);
|
||||
NK_UNUSED(group);
|
||||
}
|
||||
|
||||
static struct wl_keyboard_listener nk_wayland_keyboard_listener =
|
||||
|
@ -133,7 +240,8 @@ static struct wl_keyboard_listener nk_wayland_keyboard_listener =
|
|||
&nk_wayland_keyboard_enter,
|
||||
&nk_wayland_keyboard_leave,
|
||||
&nk_wayland_keyboard_key,
|
||||
&nk_wayland_keyboard_modifiers
|
||||
&nk_wayland_keyboard_modifiers,
|
||||
NULL
|
||||
};
|
||||
//-------------------------------------------------------------------- endof WAYLAND KEYBOARD INTERFACE
|
||||
|
||||
|
@ -154,13 +262,15 @@ static void seat_capabilities (void *data, struct wl_seat *seat, uint32_t capabi
|
|||
|
||||
static struct wl_seat_listener seat_listener =
|
||||
{
|
||||
&seat_capabilities
|
||||
&seat_capabilities,
|
||||
NULL
|
||||
};
|
||||
//-------------------------------------------------------------------- endof WAYLAND SEAT INTERFACE
|
||||
|
||||
// WAYLAND SHELL INTERFACE
|
||||
static void nk_wayland_xdg_wm_base_ping (void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
xdg_wm_base_pong (xdg_wm_base, serial);
|
||||
}
|
||||
|
||||
|
@ -171,6 +281,7 @@ static struct xdg_wm_base_listener nk_wayland_xdg_wm_base_listener =
|
|||
|
||||
static void nk_wayland_xdg_surface_configure (void *data, struct xdg_surface *xdg_surface, uint32_t serial)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
xdg_surface_ack_configure(xdg_surface, serial);
|
||||
}
|
||||
|
||||
|
@ -181,10 +292,17 @@ static struct xdg_surface_listener nk_wayland_xdg_surface_listener =
|
|||
|
||||
static void nk_wayland_xdg_toplevel_configure (void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(xdg_toplevel);
|
||||
NK_UNUSED(width);
|
||||
NK_UNUSED(height);
|
||||
NK_UNUSED(states);
|
||||
}
|
||||
|
||||
static void nk_wayland_xdg_toplevel_close (void *data, struct xdg_toplevel *xdg_toplevel)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(xdg_toplevel);
|
||||
}
|
||||
|
||||
static struct xdg_toplevel_listener nk_wayland_xdg_toplevel_listener =
|
||||
|
@ -200,6 +318,8 @@ static void nk_wayland_registry_add_object (void *data, struct wl_registry *regi
|
|||
{
|
||||
struct nk_wayland* win = (struct nk_wayland*)data;
|
||||
|
||||
NK_UNUSED(version);
|
||||
|
||||
//printf("looking for %s interface \n", interface);
|
||||
if (!strcmp(interface,"wl_compositor")) {
|
||||
win->compositor = wl_registry_bind (registry, name, &wl_compositor_interface, 1);
|
||||
|
@ -222,6 +342,9 @@ static void nk_wayland_registry_add_object (void *data, struct wl_registry *regi
|
|||
|
||||
static void nk_wayland_registry_remove_object (void *data, struct wl_registry *registry, uint32_t name)
|
||||
{
|
||||
NK_UNUSED(data);
|
||||
NK_UNUSED(registry);
|
||||
NK_UNUSED(name);
|
||||
}
|
||||
|
||||
static struct wl_registry_listener nk_wayland_registry_listener =
|
||||
|
@ -314,8 +437,10 @@ static void redraw(void *data, struct wl_callback *callback, uint32_t time)
|
|||
{
|
||||
// printf("redrawing.. 1\n");
|
||||
struct nk_wayland* win = (struct nk_wayland*)data;
|
||||
struct nk_color col_red = {0xFF,0x00,0x00,0xA0}; //r,g,b,a
|
||||
struct nk_color col_green = {0x00,0xFF,0x00,0xA0}; //r,g,b,a
|
||||
|
||||
NK_UNUSED(callback);
|
||||
NK_UNUSED(time);
|
||||
|
||||
wl_callback_destroy(win->frame_callback);
|
||||
wl_surface_damage(win->surface, 0, 0, WIDTH, HEIGHT);
|
||||
|
||||
|
@ -338,7 +463,6 @@ int main ()
|
|||
long dt;
|
||||
long started;
|
||||
struct nk_wayland nk_wayland_ctx;
|
||||
struct wl_backend *backend;
|
||||
struct wl_registry *registry;
|
||||
int running = 1;
|
||||
|
||||
|
@ -418,17 +542,20 @@ int main ()
|
|||
|
||||
if (nk_window_is_closed(&(nk_wayland_ctx.ctx), "Demo")) break;
|
||||
|
||||
// -------------- EXAMPLES ----------------
|
||||
//#ifdef INCLUDE_CALCULATOR
|
||||
// calculator(&rawfb->ctx);
|
||||
//#endif
|
||||
// #ifdef INCLUDE_OVERVIEW
|
||||
// overview(&rawfb->ctx);
|
||||
// #endif
|
||||
// #ifdef INCLUDE_NODE_EDITOR
|
||||
// node_editor(&rawfb->ctx);
|
||||
//#endif
|
||||
// -----------------------------------------
|
||||
/* -------------- EXAMPLES ---------------- */
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(&(nk_wayland_ctx.ctx));
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(&(nk_wayland_ctx.ctx));
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(&(nk_wayland_ctx.ctx));
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
node_editor(&(nk_wayland_ctx.ctx));
|
||||
#endif
|
||||
/* ----------------------------------------- */
|
||||
|
||||
// Draw framebuffer
|
||||
nk_wayland_render(&nk_wayland_ctx, nk_rgb(30,30,30), 1);
|
||||
|
|
|
@ -110,7 +110,7 @@ static void nk_wayland_ctx_setpixel(const struct nk_wayland* win,
|
|||
const short x0, const short y0, const struct nk_color col)
|
||||
{
|
||||
uint32_t c = nk_color_to_xrgb8888(col);
|
||||
uint32_t *pixels = win->data;
|
||||
uint32_t *pixels = (uint32_t *)win->data;
|
||||
unsigned int *ptr;
|
||||
|
||||
pixels += (y0 * win->width);
|
||||
|
@ -252,7 +252,7 @@ static void nk_wayland_img_setpixel(const struct wayland_img *img, const int x0,
|
|||
unsigned int *pixel;
|
||||
NK_ASSERT(img);
|
||||
if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
|
||||
ptr = img->pixels + (img->pitch * y0);
|
||||
ptr = (unsigned char *)img->pixels + (img->pitch * y0);
|
||||
pixel = (unsigned int *)ptr;
|
||||
|
||||
if (img->format == NK_FONT_ATLAS_ALPHA8) {
|
||||
|
@ -267,10 +267,9 @@ static struct nk_color nk_wayland_getpixel(const struct nk_wayland* win, const i
|
|||
{
|
||||
struct nk_color col = {0, 0, 0, 0};
|
||||
uint32_t *ptr;
|
||||
unsigned int pixel;
|
||||
|
||||
if (y0 < win->height && y0 >= 0 && x0 >= 0 && x0 < win->width) {
|
||||
ptr = win->data + (y0 * win->width);
|
||||
ptr = (uint32_t *)win->data + (y0 * win->width);
|
||||
|
||||
col = nk_wayland_int2color(*ptr, PIXEL_LAYOUT_XRGB_8888);
|
||||
}
|
||||
|
@ -285,7 +284,7 @@ static struct nk_color nk_wayland_img_getpixel(const struct wayland_img *img, co
|
|||
unsigned int pixel;
|
||||
NK_ASSERT(img);
|
||||
if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
|
||||
ptr = img->pixels + (img->pitch * y0);
|
||||
ptr = (unsigned char *)img->pixels + (img->pitch * y0);
|
||||
|
||||
if (img->format == NK_FONT_ATLAS_ALPHA8) {
|
||||
col.a = ptr[x0];
|
||||
|
@ -365,6 +364,8 @@ static void nk_wayland_stroke_line(const struct nk_wayland* win, short x0, short
|
|||
short tmp;
|
||||
int dy, dx, stepx, stepy;
|
||||
|
||||
NK_UNUSED(line_thickness);
|
||||
|
||||
dy = y1 - y0;
|
||||
dx = x1 - x0;
|
||||
|
||||
|
@ -494,6 +495,8 @@ static void nk_wayland_stroke_arc(const struct nk_wayland* win,
|
|||
const int fa2 = 4 * a2, fb2 = 4 * b2;
|
||||
int x, y, sigma;
|
||||
|
||||
NK_UNUSED(line_thickness);
|
||||
|
||||
if (s != 0 && s != 90 && s != 180 && s != 270) return;
|
||||
if (w < 1 || h < 1) return;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
BIN = zahnrad
|
||||
|
||||
# Flags
|
||||
CFLAGS += -std=c89 -pedantic -O2
|
||||
CFLAGS += -std=c89 -Wall -Wextra -pedantic -Wno-unused-function -O2
|
||||
|
||||
SRC = main.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
|
|
@ -79,27 +79,32 @@ sleep_for(long t)
|
|||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -148,10 +153,16 @@ main(void)
|
|||
ctx = nk_xlib_init(xw.font, xw.dpy, xw.screen, xw.win, xw.width, xw.height);
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
while (running)
|
||||
|
@ -193,6 +204,9 @@ main(void)
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
|
|
@ -357,6 +357,29 @@ nk_xsurf_stroke_circle(XSurface *surf, short x, short y, unsigned short w,
|
|||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_xsurf_stroke_arc(XSurface *surf, short cx, short cy, unsigned short radius,
|
||||
float a_min, float a_max, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
unsigned long c = nk_color_from_byte(&col.r);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XDrawArc(surf->dpy, surf->drawable, surf->gc, (int)(cx - radius), (int)(cy - radius),
|
||||
(unsigned)(radius * 2), (unsigned)(radius * 2),
|
||||
(int)(a_min * 180 * 64 / NK_PI), (int)(a_max * 180 * 64 / NK_PI));
|
||||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_xsurf_fill_arc(XSurface *surf, short cx, short cy, unsigned short radius,
|
||||
float a_min, float a_max, struct nk_color col)
|
||||
{
|
||||
unsigned long c = nk_color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, (int)(cx - radius), (int)(cy - radius),
|
||||
(unsigned)(radius * 2), (unsigned)(radius * 2),
|
||||
(int)(a_min * 180 * 64 / NK_PI), (int)(a_max * 180 * 64 / NK_PI));
|
||||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_xsurf_stroke_curve(XSurface *surf, struct nk_vec2i p1,
|
||||
struct nk_vec2i p2, struct nk_vec2i p3, struct nk_vec2i p4,
|
||||
|
@ -385,15 +408,12 @@ nk_xsurf_stroke_curve(XSurface *surf, struct nk_vec2i p1,
|
|||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_xsurf_draw_text(XSurface *surf, short x, short y, unsigned short w, unsigned short h,
|
||||
const char *text, int len, XFont *font, struct nk_color cbg, struct nk_color cfg)
|
||||
nk_xsurf_draw_text(XSurface *surf, short x, short y, const char *text, int len,
|
||||
XFont *font, struct nk_color cfg)
|
||||
{
|
||||
int tx, ty;
|
||||
unsigned long bg = nk_color_from_byte(&cbg.r);
|
||||
unsigned long fg = nk_color_from_byte(&cfg.r);
|
||||
|
||||
XSetForeground(surf->dpy, surf->gc, bg);
|
||||
XFillRectangle(surf->dpy, surf->drawable, surf->gc, (int)x, (int)y, (unsigned)w, (unsigned)h);
|
||||
if(!text || !font || !len) return;
|
||||
|
||||
tx = (int)x;
|
||||
|
@ -497,6 +517,9 @@ nk_xsurf_draw_image(XSurface *surf, short x, short y, unsigned short w, unsigned
|
|||
struct nk_image img, struct nk_color col)
|
||||
{
|
||||
XImageWithAlpha *aimage = img.handle.ptr;
|
||||
|
||||
NK_UNUSED(col);
|
||||
|
||||
if (aimage){
|
||||
if (aimage->clipMask){
|
||||
XSetClipMask(surf->dpy, surf->gc, aimage->clipMask);
|
||||
|
@ -581,6 +604,9 @@ nk_xfont_get_text_width(nk_handle handle, float height, const char *text, int le
|
|||
{
|
||||
XFont *font = (XFont*)handle.ptr;
|
||||
XRectangle r;
|
||||
|
||||
NK_UNUSED(height);
|
||||
|
||||
if(!font || !text)
|
||||
return 0;
|
||||
|
||||
|
@ -687,6 +713,8 @@ nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt)
|
|||
{
|
||||
struct nk_context *ctx = &xlib.ctx;
|
||||
|
||||
NK_UNUSED(screen);
|
||||
|
||||
/* optional grabbing behavior */
|
||||
if (ctx->input.mouse.grab) {
|
||||
XDefineCursor(xlib.dpy, xlib.root, xlib.cursor);
|
||||
|
@ -907,6 +935,14 @@ nk_xlib_render(Drawable screen, struct nk_color clear)
|
|||
const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
|
||||
nk_xsurf_fill_circle(surf, c->x, c->y, c->w, c->h, c->color);
|
||||
} break;
|
||||
case NK_COMMAND_ARC: {
|
||||
const struct nk_command_arc *a = (const struct nk_command_arc *)cmd;
|
||||
nk_xsurf_stroke_arc(surf, a->cx, a->cy, a->r, a->a[0], a->a[1], a->line_thickness, a->color);
|
||||
} break;
|
||||
case NK_COMMAND_ARC_FILLED: {
|
||||
const struct nk_command_arc_filled *a = (const struct nk_command_arc_filled *)cmd;
|
||||
nk_xsurf_fill_arc(surf, a->cx, a->cy, a->r, a->a[0], a->a[1], a->color);
|
||||
} break;
|
||||
case NK_COMMAND_TRIANGLE: {
|
||||
const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
|
||||
nk_xsurf_stroke_triangle(surf, t->a.x, t->a.y, t->b.x, t->b.y,
|
||||
|
@ -931,10 +967,8 @@ nk_xlib_render(Drawable screen, struct nk_color clear)
|
|||
} break;
|
||||
case NK_COMMAND_TEXT: {
|
||||
const struct nk_command_text *t = (const struct nk_command_text*)cmd;
|
||||
nk_xsurf_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);
|
||||
nk_xsurf_draw_text(surf, t->x, t->y, (const char*)t->string, t->length,
|
||||
(XFont*)t->font->userdata.ptr, t->foreground);
|
||||
} break;
|
||||
case NK_COMMAND_CURVE: {
|
||||
const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
|
||||
|
@ -946,8 +980,6 @@ nk_xlib_render(Drawable screen, struct nk_color clear)
|
|||
nk_xsurf_draw_image(surf, i->x, i->y, i->w, i->h, i->img, i->col);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_MULTI_COLOR:
|
||||
case NK_COMMAND_ARC:
|
||||
case NK_COMMAND_ARC_FILLED:
|
||||
case NK_COMMAND_CUSTOM:
|
||||
default: break;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ CC = clang
|
|||
DCC = gcc
|
||||
|
||||
# Flags
|
||||
CFLAGS += -std=c99 -pedantic -O2
|
||||
CFLAGS += -std=c89 -Wall -Wextra -pedantic -O2
|
||||
|
||||
SRC = main.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
|
|
@ -40,27 +40,32 @@
|
|||
/*#define INCLUDE_ALL */
|
||||
/*#define INCLUDE_STYLE */
|
||||
/*#define INCLUDE_CALCULATOR */
|
||||
/*#define INCLUDE_CANVAS */
|
||||
/*#define INCLUDE_OVERVIEW */
|
||||
/*#define INCLUDE_NODE_EDITOR */
|
||||
|
||||
#ifdef INCLUDE_ALL
|
||||
#define INCLUDE_STYLE
|
||||
#define INCLUDE_CALCULATOR
|
||||
#define INCLUDE_CANVAS
|
||||
#define INCLUDE_OVERVIEW
|
||||
#define INCLUDE_NODE_EDITOR
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
#include "../style.c"
|
||||
#include "../../demo/common/style.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CALCULATOR
|
||||
#include "../calculator.c"
|
||||
#include "../../demo/common/calculator.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
#include "../../demo/common/canvas.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
#include "../overview.c"
|
||||
#include "../../demo/common/overview.c"
|
||||
#endif
|
||||
#ifdef INCLUDE_NODE_EDITOR
|
||||
#include "../node_editor.c"
|
||||
#include "../../demo/common/node_editor.c"
|
||||
#endif
|
||||
|
||||
/* ===============================================================
|
||||
|
@ -167,6 +172,7 @@ int main(void)
|
|||
glXGetFBConfigAttrib(win.dpy, fbc[i], GLX_SAMPLES, &samples);
|
||||
if ((fb_best < 0) || (sample_buffer && samples > best_num_samples))
|
||||
fb_best = i, best_num_samples = samples;
|
||||
XFree(vi);
|
||||
}
|
||||
}
|
||||
win.fbc = fbc[fb_best];
|
||||
|
@ -251,10 +257,16 @@ int main(void)
|
|||
/*nk_style_set_font(ctx, &droid->handle);*/}
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
/* ease regression testing during Nuklear release process; not needed for anything else */
|
||||
#ifdef STYLE_WHITE
|
||||
set_style(ctx, THEME_WHITE);
|
||||
#elif defined(STYLE_RED)
|
||||
set_style(ctx, THEME_RED);
|
||||
#elif defined(STYLE_BLUE)
|
||||
set_style(ctx, THEME_BLUE);
|
||||
#elif defined(STYLE_DARK)
|
||||
set_style(ctx, THEME_DARK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
|
||||
|
@ -309,6 +321,9 @@ int main(void)
|
|||
#ifdef INCLUDE_CALCULATOR
|
||||
calculator(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_CANVAS
|
||||
canvas(ctx);
|
||||
#endif
|
||||
#ifdef INCLUDE_OVERVIEW
|
||||
overview(ctx);
|
||||
#endif
|
||||
|
|