|
|
b53a5c |
|
|
|
b53a5c |
#include <gl gl.h=""></gl>
|
|
|
b53a5c |
|
|
|
b53a5c |
#include "drawing.h"
|
|
|
b53a5c |
#include "font.h"
|
|
|
b53a5c |
#include "window.h"
|
|
|
b53a5c |
#include "nuklear-heli.h"
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
#define NK_IMPLEMENTATION
|
|
|
b53a5c |
#include "nuklear-full.inc.h"
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
static float nk_heli_text_width(nk_handle handle, float height, const char *text, int len) {
|
|
|
b53a5c |
saveStateEx(STATE_TEXT_SIZE);
|
|
|
b53a5c |
|
|
|
b53a5c |
TextLayout l = createTextLayoutEx(text, len);
|
|
|
b53a5c |
textSize(height);
|
|
|
b53a5c |
//float w = textLayoutGetWidth(l);
|
|
|
b53a5c |
float w = textLayoutCursorGetX(l, len);
|
|
|
b53a5c |
textLayoutDestroy(l);
|
|
|
b53a5c |
|
|
|
b53a5c |
restoreState();
|
|
|
b53a5c |
return w;
|
|
|
b53a5c |
}
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
static void nk_heli_clipboard_paste(nk_handle handle, struct nk_text_edit *edit) {
|
|
|
b53a5c |
const char *t = windowGetClipboardText();
|
|
|
b53a5c |
if (*t) nk_textedit_paste(edit, t, nk_utf_len(t, strlen(t)));
|
|
|
b53a5c |
}
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
static void nk_heli_clipboard_copy(nk_handle handle, const char *text, int len) {
|
|
|
b53a5c |
int glyph_len;
|
|
|
b53a5c |
nk_rune unicode;
|
|
|
b53a5c |
int l = nk_utf_at(text, len*4, len, &unicode, &glyph_len) - text;
|
|
|
b53a5c |
windowSetClipboardTextEx(text, l);
|
|
|
b53a5c |
}
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
unsigned int nk_color_to_heli(struct nk_color c)
|
|
|
b53a5c |
{ return colorByRGBA(c.r/255.0, c.g/255.0, c.b/255.0, c.a/255.0); }
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
struct nk_color nk_color_from_heli(unsigned int c)
|
|
|
b53a5c |
{ struct nk_color cc = { c & 0xff, (c >> 8) & 0xff, (c >> 16) & 0xff, c >> 24 }; return cc; }
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
nk_bool nk_heli_init(nk_heli *n, double fontSize) {
|
|
|
b53a5c |
memset(n, 0, sizeof(*n));
|
|
|
b53a5c |
n->font.height = fontSize;
|
|
|
b53a5c |
n->font.width = &nk_heli_text_width;
|
|
|
b53a5c |
if (!nk_init_default(&n->context, &n->font))
|
|
|
b53a5c |
return 0;
|
|
|
b53a5c |
struct nk_context *c = &n->context;
|
|
|
b53a5c |
c->clip.paste = &nk_heli_clipboard_paste;
|
|
|
b53a5c |
c->clip.copy = &nk_heli_clipboard_copy;
|
|
|
b53a5c |
return 1;
|
|
|
b53a5c |
}
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
void nk_heli_deinit(nk_heli *n)
|
|
|
b53a5c |
{ nk_free(&n->context); }
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
struct nk_image nk_heli_image(Animation anim, int width, int height) {
|
|
|
b53a5c |
struct nk_image img = nk_image_ptr(anim);
|
|
|
b53a5c |
img.w = width;
|
|
|
b53a5c |
img.h = height;
|
|
|
b53a5c |
return img;
|
|
|
b53a5c |
}
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
void nk_heli_input(nk_heli *n) {
|
|
|
b53a5c |
struct {
|
|
|
b53a5c |
enum nk_buttons nk;
|
|
|
b53a5c |
const char *hl;
|
|
|
b53a5c |
} buttons[] = {
|
|
|
b53a5c |
{ NK_BUTTON_LEFT , "left" },
|
|
|
b53a5c |
{ NK_BUTTON_MIDDLE , "middle" },
|
|
|
b53a5c |
{ NK_BUTTON_RIGHT , "right" } };
|
|
|
b53a5c |
const int buttonsCnt = sizeof(buttons)/sizeof(*buttons);
|
|
|
b53a5c |
|
|
|
b53a5c |
struct {
|
|
|
b53a5c |
enum nk_keys nk;
|
|
|
b53a5c |
const char *hl;
|
|
|
b53a5c |
int ctrl;
|
|
|
b53a5c |
} keys[] = {
|
|
|
b53a5c |
{ NK_KEY_SHIFT , "any shift" },
|
|
|
b53a5c |
{ NK_KEY_CTRL , "any ctrl" },
|
|
|
b53a5c |
{ NK_KEY_DEL , "delete" },
|
|
|
b53a5c |
{ NK_KEY_ENTER , "any return" },
|
|
|
b53a5c |
{ NK_KEY_TAB , "tab" },
|
|
|
b53a5c |
{ NK_KEY_BACKSPACE , "backspace" },
|
|
|
b53a5c |
{ NK_KEY_COPY , "c", 1 },
|
|
|
b53a5c |
{ NK_KEY_CUT , "x", 1 },
|
|
|
b53a5c |
{ NK_KEY_PASTE , "v", 1 },
|
|
|
b53a5c |
{ NK_KEY_UP , "up" },
|
|
|
b53a5c |
{ NK_KEY_DOWN , "down" },
|
|
|
b53a5c |
{ NK_KEY_LEFT , "left", -1 },
|
|
|
b53a5c |
{ NK_KEY_RIGHT , "right", -1 },
|
|
|
b53a5c |
{ NK_KEY_TEXT_LINE_START , "home", -1 },
|
|
|
b53a5c |
{ NK_KEY_TEXT_LINE_END , "end", -1 },
|
|
|
b53a5c |
{ NK_KEY_TEXT_START , "home", 1 },
|
|
|
b53a5c |
{ NK_KEY_TEXT_END , "end", 1 },
|
|
|
b53a5c |
{ NK_KEY_TEXT_UNDO , "z", 1 },
|
|
|
b53a5c |
{ NK_KEY_TEXT_REDO , "y", 1 },
|
|
|
b53a5c |
{ NK_KEY_TEXT_SELECT_ALL , "a", 1 },
|
|
|
b53a5c |
{ NK_KEY_TEXT_WORD_LEFT , "left", 1 },
|
|
|
b53a5c |
{ NK_KEY_TEXT_WORD_RIGHT , "right", 1 },
|
|
|
b53a5c |
{ NK_KEY_SCROLL_START , "home", 1 },
|
|
|
b53a5c |
{ NK_KEY_SCROLL_END , "end", 1 },
|
|
|
b53a5c |
{ NK_KEY_SCROLL_DOWN , "page down" },
|
|
|
b53a5c |
{ NK_KEY_SCROLL_UP , "page up" } };
|
|
|
b53a5c |
const int keysCnt = sizeof(keys)/sizeof(*keys);
|
|
|
b53a5c |
|
|
|
b53a5c |
struct nk_context *c = &n->context;
|
|
|
b53a5c |
double mx = mouseTransformedX();
|
|
|
b53a5c |
double my = mouseTransformedY();
|
|
|
b53a5c |
|
|
|
b53a5c |
nk_input_begin(c);
|
|
|
b53a5c |
|
|
|
b53a5c |
nk_input_motion(c, mx, my);
|
|
|
b53a5c |
|
|
|
b53a5c |
struct nk_vec2 scroll = {};
|
|
|
b53a5c |
scroll.x = mouseScrolledX();
|
|
|
b53a5c |
scroll.y = mouseScrolledY();
|
|
|
b53a5c |
if (scroll.x || scroll.y)
|
|
|
b53a5c |
nk_input_scroll(c, scroll);
|
|
|
b53a5c |
|
|
|
b53a5c |
for(int i = 0; i < buttonsCnt; ++i) {
|
|
|
b53a5c |
if (mouseWentDown(buttons[i].hl))
|
|
|
b53a5c |
nk_input_button(c, buttons[i].nk, mx, my, 1);
|
|
|
b53a5c |
if (mouseWentUp(buttons[i].hl))
|
|
|
b53a5c |
nk_input_button(c, buttons[i].nk, mx, my, 0);
|
|
|
b53a5c |
}
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
int modes[] = { KEYEVENT_KEY_WENTUP, KEYEVENT_KEY_WENTDOWN };
|
|
|
b53a5c |
int ctrl = keyDown("any ctrl") || keyWentDown("any ctrl");
|
|
|
b53a5c |
for(int down = 1; down >= 0; --down)
|
|
|
b53a5c |
for(int i = 0; i < keyEventGetCount(modes[down]); ++i) {
|
|
|
b53a5c |
const char *k = keyEventGet(modes[down], i);
|
|
|
b53a5c |
for(int j = 0; j < keysCnt; ++j) {
|
|
|
b53a5c |
int ct = keys[j].ctrl;
|
|
|
b53a5c |
if ( (ct > 0 && !ctrl)
|
|
|
b53a5c |
|| (ct < 0 && ctrl)
|
|
|
b53a5c |
|| 0 != strcmp(k, keys[j].hl) )
|
|
|
b53a5c |
continue;
|
|
|
b53a5c |
nk_input_key(c, keys[j].nk, down);
|
|
|
b53a5c |
}
|
|
|
b53a5c |
}
|
|
|
b53a5c |
|
|
|
b53a5c |
const char *t = textInputGet();
|
|
|
b53a5c |
while(*t) {
|
|
|
b53a5c |
int len = (t[1] & 0xC0) == 0x80 ? 2
|
|
|
b53a5c |
: (t[0] & 0xF0) == 0xE0
|
|
|
b53a5c |
&& (t[1] & 0xC0) == 0x80
|
|
|
b53a5c |
&& (t[2] & 0xC0) == 0x80 ? 3
|
|
|
b53a5c |
: (t[0] & 0xF8) == 0xF0
|
|
|
b53a5c |
&& (t[1] & 0xC0) == 0x80
|
|
|
b53a5c |
&& (t[2] & 0xC0) == 0x80
|
|
|
b53a5c |
&& (t[3] & 0xC0) == 0x80 ? 4 : 1;
|
|
|
b53a5c |
nk_glyph g = {};
|
|
|
b53a5c |
memcpy(g, t, len);
|
|
|
b53a5c |
nk_input_glyph(c, g);
|
|
|
b53a5c |
t += len;
|
|
|
b53a5c |
}
|
|
|
b53a5c |
textInputClear();
|
|
|
b53a5c |
|
|
|
b53a5c |
nk_input_end(c);
|
|
|
b53a5c |
}
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
void nk_heli_draw(nk_heli *n) {
|
|
|
b53a5c |
saveState();
|
|
|
b53a5c |
|
|
|
b53a5c |
struct nk_context *c = &n->context;
|
|
|
b53a5c |
const struct nk_command *cmd;
|
|
|
b53a5c |
nk_foreach(cmd, c) {
|
|
|
b53a5c |
switch (cmd->type) {
|
|
|
b53a5c |
case NK_COMMAND_SCISSOR: {
|
|
|
b53a5c |
const struct nk_command_scissor *s = (const struct nk_command_scissor*)cmd;
|
|
|
b53a5c |
cliprect(s->x, s->y, s->w, s->h);
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_LINE: {
|
|
|
b53a5c |
const struct nk_command_line *l = (const struct nk_command_line *)cmd;
|
|
|
b53a5c |
strokeWidth(l->line_thickness);
|
|
|
b53a5c |
stroke( nk_color_to_heli(l->color) );
|
|
|
b53a5c |
line(l->begin.x, l->begin.y, l->end.x, l->end.y);
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_RECT: {
|
|
|
b53a5c |
const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
|
|
|
b53a5c |
strokeWidth(r->line_thickness);
|
|
|
b53a5c |
stroke( nk_color_to_heli(r->color) );
|
|
|
b53a5c |
noFill();
|
|
|
b53a5c |
rectRounded(r->x, r->y, r->w, r->h, r->rounding);
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_RECT_FILLED: {
|
|
|
b53a5c |
const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd;
|
|
|
b53a5c |
noStroke();
|
|
|
b53a5c |
fill( nk_color_to_heli(r->color) );
|
|
|
b53a5c |
rectRounded(r->x, r->y, r->w, r->h, r->rounding);
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_RECT_MULTI_COLOR: {
|
|
|
b53a5c |
const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color *)cmd;
|
|
|
b53a5c |
glBegin(GL_QUADS);
|
|
|
b53a5c |
glColor4ubv( &r->left.r ); glVertex2i( r->x , r->y );
|
|
|
b53a5c |
glColor4ubv( &r->top.r ); glVertex2i( r->x + r->w , r->y );
|
|
|
b53a5c |
glColor4ubv( &r->right.r ); glVertex2i( r->x + r->w , r->y + r->h );
|
|
|
b53a5c |
glColor4ubv( &r->bottom.r ); glVertex2i( r->x , r->y + r->h );
|
|
|
b53a5c |
glEnd();
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_CIRCLE: {
|
|
|
b53a5c |
const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
|
|
|
b53a5c |
strokeWidth(c->line_thickness);
|
|
|
b53a5c |
stroke( nk_color_to_heli(c->color) );
|
|
|
b53a5c |
noFill();
|
|
|
b53a5c |
ellipse(c->x, c->y, c->w, c->h);
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_CIRCLE_FILLED: {
|
|
|
b53a5c |
const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
|
|
|
b53a5c |
noStroke();
|
|
|
b53a5c |
fill( nk_color_to_heli(c->color) );
|
|
|
b53a5c |
ellipse(c->x, c->y, c->w, c->h);
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_ARC: {
|
|
|
b53a5c |
const struct nk_command_arc *a = (const struct nk_command_arc *)cmd;
|
|
|
b53a5c |
strokeWidth(a->line_thickness);
|
|
|
b53a5c |
stroke( nk_color_to_heli(a->color) );
|
|
|
b53a5c |
noFill();
|
|
|
b53a5c |
arc(a->cx - a->r, a->cy - a->r, a->r*2, a->r*2, a->a[0], a->a[1]);
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_ARC_FILLED: {
|
|
|
b53a5c |
const struct nk_command_arc_filled *a = (const struct nk_command_arc_filled *)cmd;
|
|
|
b53a5c |
noStroke();
|
|
|
b53a5c |
fill( nk_color_to_heli(a->color) );
|
|
|
b53a5c |
moveTo(a->cx, a->cy);
|
|
|
b53a5c |
arcPath(a->cx - a->r, a->cy - a->r, a->r*2, a->r*2, a->a[0], a->a[1]);
|
|
|
b53a5c |
closePath();
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_TRIANGLE: {
|
|
|
b53a5c |
const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
|
|
|
b53a5c |
strokeWidth(t->line_thickness);
|
|
|
b53a5c |
stroke( nk_color_to_heli(t->color) );
|
|
|
b53a5c |
noFill();
|
|
|
b53a5c |
moveTo(t->a.x, t->a.y);
|
|
|
b53a5c |
lineTo(t->b.x, t->b.y);
|
|
|
b53a5c |
lineTo(t->c.x, t->c.y);
|
|
|
b53a5c |
closePath();
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_TRIANGLE_FILLED: {
|
|
|
b53a5c |
const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd;
|
|
|
b53a5c |
noStroke();
|
|
|
b53a5c |
fill( nk_color_to_heli(t->color) );
|
|
|
b53a5c |
moveTo(t->a.x, t->a.y);
|
|
|
b53a5c |
lineTo(t->b.x, t->b.y);
|
|
|
b53a5c |
lineTo(t->c.x, t->c.y);
|
|
|
b53a5c |
closePath();
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_POLYGON: {
|
|
|
b53a5c |
const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd;
|
|
|
b53a5c |
strokeWidth(p->line_thickness);
|
|
|
b53a5c |
stroke( nk_color_to_heli(p->color) );
|
|
|
b53a5c |
noFill();
|
|
|
b53a5c |
moveTo(p->points[0].x, p->points[0].y);
|
|
|
b53a5c |
for(int i = 1; i < p->point_count; ++i)
|
|
|
b53a5c |
lineTo(p->points[i].x, p->points[i].y);
|
|
|
b53a5c |
closePath();
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_POLYGON_FILLED: {
|
|
|
b53a5c |
const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd;
|
|
|
b53a5c |
noStroke();
|
|
|
b53a5c |
fill( nk_color_to_heli(p->color) );
|
|
|
b53a5c |
moveTo(p->points[0].x, p->points[0].y);
|
|
|
b53a5c |
for(int i = 1; i < p->point_count; ++i)
|
|
|
b53a5c |
lineTo(p->points[i].x, p->points[i].y);
|
|
|
b53a5c |
closePath();
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_POLYLINE: {
|
|
|
b53a5c |
const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
|
|
|
b53a5c |
strokeWidth(p->line_thickness);
|
|
|
b53a5c |
stroke( nk_color_to_heli(p->color) );
|
|
|
b53a5c |
noFill();
|
|
|
b53a5c |
moveTo(p->points[0].x, p->points[0].y);
|
|
|
b53a5c |
for(int i = 1; i < p->point_count; ++i)
|
|
|
b53a5c |
lineTo(p->points[i].x, p->points[i].y);
|
|
|
b53a5c |
strokePath();
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_TEXT: {
|
|
|
b53a5c |
const struct nk_command_text *t = (const struct nk_command_text*)cmd;
|
|
|
b53a5c |
//noStroke();
|
|
|
b53a5c |
//fill( nk_color_to_heli(t->background) );
|
|
|
b53a5c |
//rect( t->x, t->y, t->w, t->h );
|
|
|
b53a5c |
|
|
|
b53a5c |
stroke( nk_color_to_heli(t->foreground) );
|
|
|
b53a5c |
noFill();
|
|
|
b53a5c |
textSize(t->height);
|
|
|
b53a5c |
textAlign(HALIGN_LEFT, VALIGN_TOP);
|
|
|
b53a5c |
|
|
|
b53a5c |
TextLayout l = createTextLayoutEx(t->string, t->length);
|
|
|
b53a5c |
textLayoutDraw(l, t->x, t->y - 0.2*t->height);
|
|
|
b53a5c |
textLayoutDestroy(l);
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_CURVE: {
|
|
|
b53a5c |
const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
|
|
|
b53a5c |
strokeWidth(q->line_thickness);
|
|
|
b53a5c |
stroke( nk_color_to_heli(q->color) );
|
|
|
b53a5c |
noFill();
|
|
|
b53a5c |
line(q->begin.x, q->begin.y, q->end.x, q->end.y);
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
case NK_COMMAND_IMAGE: {
|
|
|
b53a5c |
const struct nk_command_image *i = (const struct nk_command_image *)cmd;
|
|
|
b53a5c |
noStroke();
|
|
|
b53a5c |
fill( nk_color_to_heli(i->col) );
|
|
|
b53a5c |
if (i->img.handle.ptr)
|
|
|
b53a5c |
rectTextured((Animation)i->img.handle.ptr, i->x, i->y, i->w, i->h);
|
|
|
b53a5c |
} break;
|
|
|
b53a5c |
default: break;
|
|
|
b53a5c |
}
|
|
|
b53a5c |
}
|
|
|
b53a5c |
nk_clear(c);
|
|
|
b53a5c |
|
|
|
b53a5c |
restoreState();
|
|
|
b53a5c |
}
|
|
|
b53a5c |
|
|
|
b53a5c |
|
|
|
b53a5c |
void nk_heli_process(nk_heli *n) {
|
|
|
b53a5c |
nk_heli_input(n);
|
|
|
b53a5c |
nk_heli_draw(n);
|
|
|
b53a5c |
}
|
|
|
b53a5c |
|