Blame src/nuklear-heli.c

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