1 /*
2 Copyright (c) 2019-2020 Mateusz Muszyński
3 
4 Boost Software License - Version 1.0 - August 17th, 2003
5 Permission is hereby granted, free of charge, to any person or organization
6 obtaining a copy of the software and accompanying documentation covered by
7 this license (the "Software") to use, reproduce, display, distribute,
8 execute, and transmit the Software, and to prepare derivative works of the
9 Software, and to permit third-parties to whom the Software is furnished to
10 do so, all subject to the following:
11 
12 The copyright notices in the Software and this entire statement, including
13 the above license grant, this restriction and the following disclaimer,
14 must be included in all copies of the Software, in whole or in part, and
15 all derivative works of the Software, unless such copies or derivative
16 works are solely in the form of machine-executable object code generated by
17 a source language processor.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 */
27 
28 module dagon.ext.nuklear;
29 
30 import std.stdio;
31 import core.stdc.stdarg;
32 
33 import dlib.core.ownership;
34 import dlib.image.color;
35 import dlib.container.array;
36 import dlib.text.utf8;
37 import dlib.text.str;
38 
39 import dagon.core.application;
40 import dagon.core.time;
41 import dagon.core.event;
42 import dagon.core.keycodes;
43 import dagon.core.locale;
44 import dagon.graphics.drawable;
45 import dagon.graphics.updateable;
46 import dagon.graphics.shaderloader;
47 import dagon.graphics.texture;
48 import dagon.graphics.shader;
49 
50 import dagon.core.bindings;
51 public import bindbc.nuklear;
52 
53 import dagon.ext.ftfont;
54 
55 __gshared NuklearSupport nuklearSupport;
56 
57 void initNuklear()
58 {
59     nuklearSupport = loadNuklear();
60     if (nuklearSupport != NuklearSupport.Nuklear4)
61     {
62         if (nuklearSupport == NuklearSupport.badLibrary)
63             writeln("Warning: failed to load some Nuklear functions. It seems that you have an old version of Nuklear. Dagon will try to use it, but it is recommended to install Nuklear 4.01");
64         else
65             writeln("Error: Nuklear library is not found. Please, install Nuklear 4.01");
66     }
67 }
68 
69 static this()
70 {
71     initNuklear();
72 }
73 
74 alias nk_color NKColor;
75 alias nk_colorf NKColorf;
76 alias nk_rect NKRect;
77 alias nk_rect NKRecti;
78 alias nk_vec2 NKVec2;
79 alias nk_vec2i NKVec2i;
80 alias nk_cursor NKCursor;
81 alias nk_font NKFont;
82 alias nk_flags NKFlags;
83 alias nk_size NKSize;
84 alias nk_image NKImage;
85 alias nk_rune NKRune;
86 alias nk_handle NKHandle;
87 alias nk_window NKWindow;
88 alias nk_panel NKPanel;
89 
90 NKColor toNKColor(Color4f col)
91 {
92     auto c = col.convert(8);
93     return NKColor(
94         cast(ubyte)c.r,
95         cast(ubyte)c.g,
96         cast(ubyte)c.b,
97         cast(ubyte)c.a);
98 }
99 
100 NKImage toNKImage(Texture texture)
101 {
102     NKImage img;
103     img.handle.id = cast(int)texture.tex;
104     img.w = cast(short)texture.width;
105     img.h = cast(short)texture.height;
106     img.region[2] = cast(short)texture.width;
107     img.region[3] = cast(short)texture.height;
108     return img;
109 }
110 
111 private extern(C) void clipboardPaste(nk_handle usr, nk_text_edit* edit)
112 {
113     char* text = SDL_GetClipboardText();
114     if (text)
115     {
116         // Determine how many codepoints do we have
117         uint numCharacters = 0;
118         size_t offset = 0;
119         while(true)
120         {
121             UTF8Decoder dec = UTF8Decoder(cast(string)text[offset..offset+4]);
122             auto code = dec.decodeNext();
123             if (code == 0)
124                 break;
125             offset += dec.index;
126             numCharacters++;
127         }
128 
129         nk_textedit_paste(edit, text, numCharacters); //nk_strlen(text)
130         SDL_free(text);
131     }
132 }
133 
134 private extern(C) void clipboardCopy(nk_handle usr, const(char)* text, int len)
135 {
136     import core.stdc.stdio;
137     import core.stdc.string;
138     import core.stdc.stdlib;
139     char *str = null;
140     if (!len) return;
141 
142     // Decode len codepoints and determine byte length
143     size_t byteLen = 0;
144     for(int pos = 0; pos < len; pos++)
145     {
146         UTF8Decoder dec = UTF8Decoder(cast(string)text[byteLen..byteLen+4]);
147         dec.decodeNext();
148         byteLen += dec.index;
149     }
150 
151     str = cast(char*)malloc(byteLen+1);
152     if (!str) return;
153     memcpy(str, text, byteLen);
154     str[byteLen] = '\0';
155     SDL_SetClipboardText(str);
156     free(str);
157 }
158 
159 enum NuklearEventType
160 {
161     MouseMotion,
162     MouseButton,
163     MouseScroll,
164     TextInput,
165     Key
166 }
167 
168 struct NuklearEvent
169 {
170     NuklearEventType type;
171     int x;
172     int y;
173     union
174     {
175         int button;
176         dchar unicode;
177         int key;
178     }
179     int down;
180 }
181 
182 class NuklearGUI: Owner, Updateable, Drawable
183 {
184     NuklearEvent[10] events;
185     int eventsCount = 0;
186 
187     nk_context ctx;
188     nk_buffer cmds;
189     nk_draw_null_texture nullTexture;
190 
191     Array!nk_font_atlas atlases;
192     Array!GLuint fontsTextures;
193 
194     GLuint vbo;
195     GLuint vao;
196     GLuint ebo;
197 
198     GLuint shaderProgram;
199     GLuint vertexShader;
200     GLuint fragmentShader;
201 
202     GLint positionLoc;
203     GLint texcoordLoc;
204     GLint colorLoc;
205 
206     GLint textureLoc;
207     GLint projectionMatrixLoc;
208 
209     String vs, fs;
210 
211     EventManager eventManager; // Needed for mouse position
212 
213     this(EventManager em, Owner o)
214     {
215         super(o);
216 
217         eventManager = em;
218 
219         nk_init_default(&ctx, null);
220 
221         ctx.clip.copy = cast(nk_plugin_copy)&clipboardCopy;
222         ctx.clip.paste = cast(nk_plugin_paste)&clipboardPaste;
223         ctx.clip.userdata = nk_handle_ptr(null);
224 
225         nk_buffer_init_default(&cmds);
226 
227         prepareVAO();
228 
229         addFont(null, 0, 13.0f); // load default font
230     }
231 
232     ~this()
233     {
234         if (vs.length) vs.free();
235         if (fs.length) fs.free();
236 
237         foreach(atlas; atlases)
238             nk_font_atlas_clear(&atlas);
239         atlases.free();
240 
241         foreach(tex; fontsTextures)
242             glDeleteTextures(1, &tex);
243         fontsTextures.free();
244 
245         nk_free(&ctx);
246         nk_buffer_free(&cmds);
247 
248         glDeleteProgram(shaderProgram);
249 
250         glDeleteBuffers(1, &vbo);
251         glDeleteBuffers(1, &ebo);
252     }
253 
254     void prepareVAO()
255     {
256         vs = Shader.load("data/__internal/shaders/Nuklear/Nuklear.vert.glsl");
257         fs = Shader.load("data/__internal/shaders/Nuklear/Nuklear.frag.glsl");
258 
259         vertexShader = compileShader(vs, ShaderStage.vertex);
260         fragmentShader = compileShader(fs, ShaderStage.fragment);
261         if (vertexShader != 0 && fragmentShader != 0)
262             shaderProgram = linkShaders(vertexShader, fragmentShader);
263 
264         debug writeln("NuklearShader: program ", shaderProgram);
265 
266         if (shaderProgram != 0)
267         {
268             textureLoc = glGetUniformLocation(shaderProgram, "Texture");
269             projectionMatrixLoc = glGetUniformLocation(shaderProgram, "ProjMtx");
270             positionLoc = glGetAttribLocation(shaderProgram, "va_Vertex");
271             texcoordLoc = glGetAttribLocation(shaderProgram, "va_Texcoord");
272             colorLoc = glGetAttribLocation(shaderProgram, "va_Color");
273         }
274 
275         // buffer setup
276         glGenBuffers(1, &vbo);
277         glGenBuffers(1, &ebo);
278         glGenVertexArrays(1, &vao);
279 
280         glBindVertexArray(vao);
281         glBindBuffer(GL_ARRAY_BUFFER, vbo);
282         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
283 
284         glEnableVertexAttribArray(positionLoc);
285         glEnableVertexAttribArray(texcoordLoc);
286         glEnableVertexAttribArray(colorLoc);
287 
288         glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 20, cast(void*)0);
289         glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, GL_FALSE, 20, cast(void*)8);
290         glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 20, cast(void*)16);
291 
292         glBindTexture(GL_TEXTURE_2D, 0);
293         glBindBuffer(GL_ARRAY_BUFFER, 0);
294         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
295         glBindVertexArray(0);
296     }
297 
298     override void update(Time t)
299     {
300         nk_clear(&ctx);
301 
302         nk_input_begin(&ctx);
303         nk_input_motion(&ctx, eventManager.mouseX, eventManager.mouseY);
304 
305         // perform all inputs
306         while (eventsCount != 0)
307         {
308             auto e = events[--eventsCount];
309             switch (e.type)
310             {
311                 case NuklearEventType.Key:
312                     nk_input_key(&ctx, cast(nk_keys)e.key, e.down);
313                     break;
314                 case NuklearEventType.MouseButton:
315                     nk_input_button(&ctx, cast(nk_buttons)e.button, e.x, e.y, e.down);
316                     break;
317                 case NuklearEventType.MouseScroll:
318                     nk_input_scroll(&ctx, nk_vec2(e.x, e.y));
319                     break;
320                 case NuklearEventType.TextInput:
321                     nk_input_unicode(&ctx, e.unicode);
322                     break;
323                 default:
324                     break;
325             }
326         }
327 
328         nk_input_end(&ctx);
329     }
330 
331     override void render(GraphicsState* state)
332     {
333         const(int) maxVertexBuffer = 512 * 1024;
334         const(int) maxElementBuffer = 128 * 1024;
335 
336         glEnable(GL_SCISSOR_TEST);
337         glEnable(GL_BLEND);
338         glBlendEquation(GL_FUNC_ADD);
339         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
340         glDisable(GL_DEPTH_TEST);
341         glDepthMask(GL_FALSE);
342         glActiveTexture(GL_TEXTURE0);
343 
344         glUseProgram(shaderProgram);
345         glUniform1i(textureLoc, 0);
346         glUniformMatrix4fv(projectionMatrixLoc, 1, GL_FALSE, state.projectionMatrix.arrayof.ptr);
347 
348         //const(nk_draw_command) *cmd;
349         void *vertices;
350         void *elements;
351         nk_draw_index* offset = null;
352         nk_buffer vbuf;
353         nk_buffer ebuf;
354 
355         // allocate vertex and element buffer
356         glBindVertexArray(vao);
357         glBindBuffer(GL_ARRAY_BUFFER, vbo);
358         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
359 
360         glBufferData(GL_ARRAY_BUFFER, maxVertexBuffer, null, GL_STREAM_DRAW);
361         glBufferData(GL_ELEMENT_ARRAY_BUFFER, maxElementBuffer, null, GL_STREAM_DRAW);
362 
363         // load vertices/elements directly into vertex/element buffer
364         vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
365         elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
366         {
367             // fill convert configuration
368             nk_convert_config config;
369             nk_draw_vertex_layout_element[4] vertex_layout =
370             [
371                 { NK_VERTEX_POSITION, NK_FORMAT_FLOAT, 0 },
372                     { NK_VERTEX_TEXCOORD,  NK_FORMAT_FLOAT, 8 },
373                         { NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, 16 },
374                             NK_VERTEX_LAYOUT_END
375             ];
376             config.vertex_layout = vertex_layout.ptr;
377             config.vertex_size = 20;
378             config.vertex_alignment = 0;
379             config.null_ = nullTexture;
380             config.circle_segment_count = 16;
381             config.curve_segment_count = 16;
382             config.arc_segment_count = 16;
383             config.global_alpha = 1.0f;
384             config.shape_AA = NK_ANTI_ALIASING_ON;
385             config.line_AA = NK_ANTI_ALIASING_ON;
386 
387             // setup buffers to load vertices and elements
388             nk_buffer_init_fixed(&vbuf, vertices, cast(nk_size)maxVertexBuffer);
389             nk_buffer_init_fixed(&ebuf, elements, cast(nk_size)maxElementBuffer);
390             nk_convert(&ctx, &cmds, &vbuf, &ebuf, &config);
391         }
392         glUnmapBuffer(GL_ARRAY_BUFFER);
393         glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
394 
395         // iterate over and execute each draw command
396         for (auto c = nk__draw_begin(&ctx, &cmds); c != null; c = nk__draw_next(c, &cmds, &ctx))
397         {
398             if (!c.elem_count)
399                 continue;
400             glBindTexture(GL_TEXTURE_2D, c.texture.id);
401             glScissor(cast(GLint)(c.clip_rect.x),
402                 cast(GLint)((eventManager.windowHeight - cast(GLint)(c.clip_rect.y + c.clip_rect.h))),
403                 cast(GLint)(c.clip_rect.w),
404                 cast(GLint)(c.clip_rect.h));
405             glDrawElements(GL_TRIANGLES, c.elem_count, GL_UNSIGNED_INT, offset);
406             offset += c.elem_count;
407         }
408 
409         glDepthMask(GL_TRUE);
410         glEnable(GL_DEPTH_TEST);
411         glDisable(GL_BLEND);
412         glDisable(GL_SCISSOR_TEST);
413 
414         glUseProgram(0);
415     }
416 
417     // TODO: move this to a separate module for easier extending?
418     static const(NKRune[]) fontDefaultGlyphRanges = [ 0x0020, 0x00FF, 0 ];
419     static const(NKRune[]) fontLatinExtendedAGlyphRanges = [ 0x0020, 0x017F, 0 ];
420     static const(NKRune[]) fontLatinExtendedBGlyphRanges = [ 0x0020, 0x024F, 0 ];
421     static const(NKRune[]) fontCyrillicGlyphRanges = [ 0x0020, 0x00FF,  0x0400, 0x052F, 0x2DE0, 0x2DFF, 0xA640, 0xA69F, 0 ];
422     static const(NKRune[]) fontGreekGlyphRanges = [ 0x0020, 0x00FF, 0x0370, 0x03FF, 0 ];
423     static const(NKRune[]) fontChineseGlyphRanges = [ 0x0020, 0x00FF, 0x3000, 0x30FF, 0x31F0, 0x31FF, 0xFF00, 0xFFEF, 0x4E00, 0x9FAF, 0 ];
424     static const(NKRune[]) fontJapaneseGlyphRanges = [ 0x0020, 0x00FF, 0x3000, 0x303F, 0x3040, 0x309F, 0x30A0, 0x30FF, 0 ];
425     static const(NKRune[]) fontKoreanGlyphRanges = [ 0x0020, 0x00FF, 0x3131, 0x3163,  0xAC00, 0xD79D, 0 ];
426     static const(NKRune[]) fontHebrewGlyphRanges = [ 0x0020, 0x00FF, 0x0590, 0x05FF, 0 ];
427     static const(NKRune[]) fontArabicGlyphRanges = [ 0x0020, 0x00FF, 0x0600, 0x06FF, 0 ];
428     static const(NKRune[]) fontArmenianGlyphRanges = [ 0x0020, 0x00FF, 0x0530, 0x058F, 0 ];
429     static const(NKRune[]) fontGeorgianGlyphRanges = [ 0x0020, 0x00FF, 0x10A0, 0x10FF, 0 ];
430 
431     static const(NKRune[]) localeGlyphRanges(string locale = systemLocale())
432     {
433         if (locale == "ru_RU" || // Russian
434             locale == "tt_RU")   // Tatar
435             return fontCyrillicGlyphRanges;
436 
437         else if (locale == "fr_FR" || // French
438                  locale == "de_DE" || // German
439                  locale == "is_IS" || // Icelandic
440                  locale == "es_ES" || // Spanish
441                  locale == "ca_ES" || // Catalan
442                  locale == "pl_PL" || // Polish
443                  locale == "cs_CZ" || // Czech
444                  locale == "lv_LV" || // Latvian
445                  locale == "lt_LT" || // Lithuanian
446                  locale == "sk_SK" || // Slovak
447                  locale == "tr_TR" || // Turkish
448                  locale == "cy_GB")   // Welsh
449             return fontLatinExtendedAGlyphRanges;
450 
451         else if (locale == "el_GR") // Greek
452             return fontGreekGlyphRanges;
453 
454         else if (locale == "zh_CN") // Chinese
455             return fontChineseGlyphRanges;
456 
457         else if (locale == "ja_JP") // Japanese
458             return fontJapaneseGlyphRanges;
459 
460         else if (locale == "ko_KR") // Korean
461             return fontKoreanGlyphRanges;
462 
463         else if (locale == "he_IL") // Hebrew
464             return fontHebrewGlyphRanges;
465 
466         else if (locale == "ar_AE" || // Arabic (United Arab Emirates)
467                  locale == "ar_DZ" || // Arabic (Algeria)
468                  locale == "ar_BH" || // Arabic (Bahrain)
469                  locale == "ar_EG" || // Arabic (Egypt)
470                  locale == "ar_IQ" || // Arabic (Iraq)
471                  locale == "ar_JO" || // Arabic (Jordan)
472                  locale == "ar_KW" || // Arabic (Kuwait)
473                  locale == "ar_LB" || // Arabic (Lebanon)
474                  locale == "ar_LY" || // Arabic (Libya)
475                  locale == "ar_MA" || // Arabic (Morocco)
476                  locale == "ar_OM" || // Arabic (Oman)
477                  locale == "ar_QA" || // Arabic (Qatar)
478                  locale == "ar_SA" || // Arabic (Saudi Arabia)
479                  locale == "ar_SD" || // Arabic (Sudan)
480                  locale == "ar_SY" || // Arabic (Syria)
481                  locale == "ar_TN" || // Arabic (Tunisia)
482                  locale == "ar_YE")   // Arabic (Yemen)
483             return fontArabicGlyphRanges;
484 
485         else if (locale == "hy_AM") // Armenian
486             return fontArmenianGlyphRanges;
487 
488         else if (locale == "ka_GE") // Georgian
489             return fontArmenianGlyphRanges;
490 
491         else // Assume English
492             return fontDefaultGlyphRanges;
493     }
494 
495     NKFont* addFont(FontAsset font, float height = 13, const(NKRune[]) range = fontDefaultGlyphRanges)
496     {
497         return addFont(font.buffer.ptr, font.buffer.length, height, range);
498     }
499 /*
500     NKFont* addFont(string filename, float height = 13, const(NKRune[]) range = fontDefaultGlyphRanges)
501     {
502         import std.file;
503         ubyte[] buffer = cast(ubyte[])std.file.read(filename);
504         return addFont(buffer.ptr, buffer.length, height, range);
505     }
506 */
507     NKFont* addFont(ubyte* buffer, ulong len, float height = 13, const(NKRune[]) range = fontDefaultGlyphRanges)
508     {
509         nk_font_config cfg = nk_font_config_(0);
510         cfg.range = range.ptr;
511 
512         nk_font_atlas atlas;
513         nk_font_atlas_init_default(&atlas);
514         nk_font_atlas_begin(&atlas);
515 
516         nk_font* nkfont;
517         if(buffer)
518             nkfont = nk_font_atlas_add_from_memory(&atlas, buffer, cast(int)len, height, &cfg);
519         else
520             nkfont = nk_font_atlas_add_default(&atlas, height, &cfg);
521 
522         atlas.default_font = nkfont;
523 
524         int w = 0;
525         int h = 0;
526         const(void)* image = nk_font_atlas_bake(&atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
527 
528         GLuint texture;
529         glGenTextures(1, &texture);
530         glBindTexture(GL_TEXTURE_2D, texture);
531         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
532         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
533         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cast(GLsizei)w, cast(GLsizei)h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
534 
535         nk_font_atlas_end(&atlas, nk_handle_id(cast(int)texture), &nullTexture);
536         nk_style_set_font(&ctx, &atlas.default_font.handle);
537 
538         atlases.insertBack(atlas);
539         fontsTextures.insertBack(texture);
540 
541         return nkfont;
542     }
543 
544     //deprecated("No need to call generateFontAtlas()") void generateFontAtlas() {}
545 
546     NKFont* getFont(uint index)
547     {
548         if(index >= atlases.length)
549             return atlases[0].default_font;
550 
551         return atlases[index].default_font;
552     }
553 
554     float textWidth(const(char)* txt, int len)
555     {
556         const(nk_user_font) *f = ctx.style.font;
557         return f.width(cast(nk_handle)f.userdata, f.height, txt, len);
558     }
559 
560     float textWidth(NKFont* font, const(char)* txt, int len)
561     {
562         const(nk_user_font) *f = &font.handle;
563         return f.width(cast(nk_handle)f.userdata, f.height, txt, len);
564     }
565 
566     void inputKey(nk_keys key, int down)
567     {
568         auto e = NuklearEvent(NuklearEventType.Key);
569         e.key = key;
570         e.down = down;
571         if (eventsCount < 10)
572             events[eventsCount++] = e;
573     }
574 
575     void inputKeyDown(nk_keys key)
576     {
577         inputKey(key, 1);
578     }
579 
580     void inputKeyUp(nk_keys key)
581     {
582         inputKey(key, 0);
583     }
584 
585     void inputButton(int button, int down)
586     {
587         auto e = NuklearEvent(NuklearEventType.MouseButton);
588         switch (button)
589         {
590             case MB_LEFT: e.button = nk_buttons.NK_BUTTON_LEFT; break;
591             case MB_MIDDLE: e.button = nk_buttons.NK_BUTTON_MIDDLE; break;
592             case MB_RIGHT: e.button = nk_buttons.NK_BUTTON_RIGHT; break;
593             default:
594                 break;
595         }
596         e.x = eventManager.mouseX;
597         e.y = eventManager.mouseY;
598         e.down = down;
599         if (eventsCount < 10)
600             events[eventsCount++] = e;
601     }
602 
603     void inputButtonDown(int button)
604     {
605         inputButton(button, 1);
606     }
607 
608     void inputButtonUp(int button)
609     {
610         inputButton(button, 0);
611     }
612 
613     void inputScroll(int x, int y)
614     {
615         auto e = NuklearEvent(NuklearEventType.MouseScroll);
616         e.x = x;
617         e.y = y;
618         if (eventsCount < 10)
619             events[eventsCount++] = e;
620     }
621 
622     void inputUnicode(dchar key)
623     {
624         auto e = NuklearEvent(NuklearEventType.TextInput);
625         e.unicode = key;
626         if (eventsCount < 10)
627             events[eventsCount++] = e;
628     }
629 
630     int begin(const(char)* title, NKRect bounds, NKFlags flags)
631     {
632         return nk_begin(&ctx, title, bounds, flags);
633     }
634 
635     int beginTitled(const(char)* name, const(char)* title, NKRect bounds, NKFlags flags)
636     {
637         return nk_begin_titled(&ctx, name, title, bounds, flags);
638     }
639 
640     void end()
641     {
642         nk_end(&ctx);
643     }
644 
645     nk_style_window oldWindowStyle;
646 
647     int canvasBegin(const(char)* title, NKRect bounds, NKColor background = NKColor(255,255,255,255))
648     {
649         oldWindowStyle = ctx.style.window;
650 
651         ctx.style.window.spacing = nk_vec2(0, 0);
652         ctx.style.window.padding = nk_vec2(0, 0);
653         ctx.style.window.fixed_background = nk_style_item_color(background);
654 
655         nk_begin(&ctx, title, bounds, NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BACKGROUND | NK_WINDOW_NO_INPUT);
656 
657         nk_rect totalSpace = nk_window_get_content_region(&ctx);
658         nk_layout_row_dynamic(&ctx, totalSpace.h, 1);
659         nk_widget(&totalSpace, &ctx);
660 
661         return 1;
662     }
663 
664     void canvasEnd()
665     {
666         nk_end(&ctx);
667         ctx.style.window = oldWindowStyle;
668     }
669 
670     NKWindow* windowFind(const(char)* name)
671     {
672         return nk_window_find(&ctx, name);
673     }
674 
675     NKPanel* windowGetPanel()
676     {
677         return nk_window_get_panel(&ctx);
678     }
679 
680     NKRect windowGetContentRegion()
681     {
682         return nk_window_get_content_region(&ctx);
683     }
684 
685     NKVec2 windowGetContentRegionMin()
686     {
687         return nk_window_get_content_region_min(&ctx);
688     }
689 
690     NKVec2 windowGetContentRegionMax()
691     {
692         return nk_window_get_content_region_max(&ctx);
693     }
694 
695     NKVec2 windowGetContentRegionSize()
696     {
697         return nk_window_get_content_region_size(&ctx);
698     }
699 
700     nk_command_buffer* windowGetCanvas()
701     {
702         return nk_window_get_canvas(&ctx);
703     }
704 
705     int windowIsHovered()
706     {
707         return nk_window_is_hovered(&ctx);
708     }
709 
710     int windowIsCollapsed(const(char)* name)
711     {
712         return nk_window_is_collapsed(&ctx, name);
713     }
714 
715     int windowIsClosed(const(char)* name)
716     {
717         return nk_window_is_closed(&ctx,  name);
718     }
719 
720     int windowIsHidden(const(char)* name)
721     {
722         return nk_window_is_hidden(&ctx,  name);
723     }
724 
725     int windowIsActive(const(char)* name)
726     {
727         return nk_window_is_active(&ctx, name);
728     }
729 
730     int windowIsAnyHovered()
731     {
732         return nk_window_is_any_hovered(&ctx);
733     }
734 
735     int itemIsAnyActive()
736     {
737         return nk_item_is_any_active(&ctx);
738     }
739 
740     void windowSetBounds(const(char)* name, NKRect bounds)
741     {
742         nk_window_set_bounds(&ctx, name, bounds);
743     }
744 
745     void windowSetPosition(const(char)* name, NKVec2 pos)
746     {
747         nk_window_set_position(&ctx, name, pos);
748     }
749 
750     void windowSetSize(const(char)* name, NKVec2 size)
751     {
752         nk_window_set_size(&ctx, name, size);
753     }
754 
755     void windowSetFocus(const(char)* name)
756     {
757         nk_window_set_focus(&ctx, name);
758     }
759 
760     void windowClose(const(char)* name)
761     {
762         nk_window_close(&ctx, name);
763     }
764 
765     void windowCollapse(const(char)* name, nk_collapse_states state)
766     {
767         nk_window_collapse(&ctx, name, state);
768     }
769 
770     void windowCollapseIf(const(char)* name, nk_collapse_states state, int cond)
771     {
772         nk_window_collapse_if (&ctx, name, state, cond);
773     }
774 
775     void windowShow(const(char)* name, nk_show_states state)
776     {
777         nk_window_show(&ctx, name, state);
778     }
779 
780     void windowShowIf(const(char)* name, nk_show_states state, int cond)
781     {
782         nk_window_show_if (&ctx, name, state, cond);
783     }
784 
785     void layoutSetMinRowHeight(float height)
786     {
787         nk_layout_set_min_row_height(&ctx, height);
788     }
789 
790     void layoutResetMinRowHeight()
791     {
792         nk_layout_reset_min_row_height(&ctx);
793     }
794 
795     NKRect layoutWidgetBounds()
796     {
797         return nk_layout_widget_bounds(&ctx);
798     }
799 
800     float layoutRatioFromPixel(float pixel_width)
801     {
802         return nk_layout_ratio_from_pixel(&ctx, pixel_width);
803     }
804 
805     void layoutRowDynamic(float height, int cols)
806     {
807         nk_layout_row_dynamic(&ctx, height, cols);
808     }
809 
810     void layoutRowStatic(float height, int item_width, int cols)
811     {
812         nk_layout_row_static(&ctx, height, item_width, cols);
813     }
814 
815     void layoutRowBegin(nk_layout_format fmt, float row_height, int cols)
816     {
817         nk_layout_row_begin(&ctx, fmt, row_height, cols);
818     }
819 
820     void layoutRowPush(float value)
821     {
822         nk_layout_row_push(&ctx, value);
823     }
824 
825     void layoutRowEnd()
826     {
827         nk_layout_row_end(&ctx);
828     }
829 
830     void layoutRow(nk_layout_format format, float height, int cols, const(float)* ratio)
831     {
832         nk_layout_row(&ctx, format, height, cols, ratio);
833     }
834 
835     void layoutRowTemplateBegin(float row_height)
836     {
837         nk_layout_row_template_begin(&ctx, row_height);
838     }
839 
840     void layoutRowTemplatePushDynamic()
841     {
842         nk_layout_row_template_push_dynamic(&ctx);
843     }
844 
845     void layoutRowTemplatePushVariable(float min_width)
846     {
847         nk_layout_row_template_push_variable(&ctx, min_width);
848     }
849 
850     void layoutRowTemplatePushStatic(float width)
851     {
852         nk_layout_row_template_push_static(&ctx, width);
853     }
854 
855     void layoutRowTemplateEnd()
856     {
857         nk_layout_row_template_end(&ctx);
858     }
859 
860     void layoutSpaceBegin(nk_layout_format foramt, float height, int widget_count)
861     {
862         nk_layout_space_begin(&ctx, foramt, height, widget_count);
863     }
864 
865     void layoutSpacePush(NKRect bounds)
866     {
867         nk_layout_space_push(&ctx, bounds);
868     }
869 
870     void layoutSpaceEnd()
871     {
872         nk_layout_space_end(&ctx);
873     }
874 
875     NKRect layoutSpaceBounds()
876     {
877         return nk_layout_space_bounds(&ctx);
878     }
879 
880     NKVec2 layoutSpaceToScreen(NKVec2 a)
881     {
882         return nk_layout_space_to_screen(&ctx, a);
883     }
884 
885     NKVec2 layoutSpaceToLocal(NKVec2 a)
886     {
887         return nk_layout_space_to_local(&ctx, a);
888     }
889 
890     NKRect layoutSpaceRectToScreen(NKRect a)
891     {
892         return nk_layout_space_rect_to_screen(&ctx, a);
893     }
894 
895     NKRect layoutSpaceRectToLocal(NKRect a)
896     {
897         return nk_layout_space_rect_to_local(&ctx, a);
898     }
899 
900     int groupBegin(const(char)* title, NKFlags flags)
901     {
902         return nk_group_begin(&ctx, title, flags);
903     }
904 
905     int groupBeginTitled(const(char)* name, const(char)* title, NKFlags flags)
906     {
907         return nk_group_begin_titled(&ctx, name, title, flags);
908     }
909 
910     void groupEnd()
911     {
912         nk_group_end(&ctx);
913     }
914 
915     int groupScrolledOffsetBegin(nk_uint* x_offset, nk_uint* y_offset, const(char)* title, NKFlags flags)
916     {
917         return nk_group_scrolled_offset_begin(&ctx, x_offset, y_offset, title, flags);
918     }
919 
920     int groupScrolledBegin(nk_scroll* off, const(char)* title, NKFlags flags)
921     {
922         return nk_group_scrolled_begin(&ctx, off, title, flags);
923     }
924 
925     void groupScrolledEnd()
926     {
927         nk_group_scrolled_end(&ctx);
928     }
929 
930     int treePush(size_t line = __LINE__)(nk_tree_type type, const(char) *title, nk_collapse_states state)
931     {
932         return nk_tree_push_hashed(&ctx, type, title, state, null, 0, line);
933     }
934 
935     int treePushId(nk_tree_type type, const(char) *title, nk_collapse_states state, int id)
936     {
937         return nk_tree_push_hashed(&ctx, type, title, state, null, 0, id);
938     }
939 
940     void treePop()
941     {
942         nk_tree_pop(&ctx);
943     }
944 
945     int treeStatePush(nk_tree_type type, const(char)* title, nk_collapse_states* state)
946     {
947         return nk_tree_state_push(&ctx, type, title, state);
948     }
949 
950     int treeStateImagePush(nk_tree_type type, NKImage image, const(char)* title, nk_collapse_states* state)
951     {
952         return nk_tree_state_image_push(&ctx, type, image, title, state);
953     }
954 
955     void treeStatePop()
956     {
957         nk_tree_state_pop(&ctx);
958     }
959 
960     auto treeElementPush(size_t line = __LINE__)(nk_tree_type type, const(char) *title, nk_collapse_states state, int* selected)
961     {
962         return nk_tree_element_push_hashed(&ctx, type, title, state, selected, null, 0, line);
963     }
964 
965     auto treeElementPushId(nk_tree_type type, const(char) *title, nk_collapse_states state, int* selected, int id)
966     {
967         return nk_tree_element_push_hashed(&ctx, type, title, state, selected, null, 0, id);
968     }
969 
970     auto treeElementImagePush(size_t line = __LINE__)(nk_tree_type type, NKImage img, const(char) *title, nk_collapse_states state)
971     {
972         return nk_tree_image_push_hashed(&ctx, type, img, title, state, null, 0, line);
973     }
974 
975     auto treeElementImagePushId(nk_tree_type type, NKImage img, const(char) *title, nk_collapse_states state, int id)
976     {
977         return nk_tree_image_push_hashed(&ctx, type, img, title, state, null, 0, id);
978     }
979 
980     void treeElementPop()
981     {
982         nk_tree_element_pop(&ctx);
983     }
984 
985     int listViewBegin(nk_list_view* out_, const(char)* id, NKFlags flags, int row_height, int row_count)
986     {
987         return nk_list_view_begin(&ctx, out_, id, flags, row_height, row_count);
988     }
989 
990     NKRect widgetBounds()
991     {
992         return nk_widget_bounds(&ctx);
993     }
994 
995     NKVec2 widgetPosition()
996     {
997         return nk_widget_position(&ctx);
998     }
999 
1000     NKVec2 widgetSize()
1001     {
1002         return nk_widget_size(&ctx);
1003     }
1004 
1005     float widgetWidth()
1006     {
1007         return nk_widget_width(&ctx);
1008     }
1009 
1010     float widgetHeight()
1011     {
1012         return nk_widget_height(&ctx);
1013     }
1014 
1015     int widgetIsHovered()
1016     {
1017         return nk_widget_is_hovered(&ctx);
1018     }
1019 
1020     int widgetIsMouseClicked(nk_buttons buttons)
1021     {
1022         return nk_widget_is_mouse_clicked(&ctx, buttons);
1023     }
1024 
1025     int widgetHasMouseClickDown(nk_buttons buttons, int down)
1026     {
1027         return nk_widget_has_mouse_click_down(&ctx, buttons, down);
1028     }
1029 
1030     void spacing(int cols)
1031     {
1032         nk_spacing(&ctx, cols);
1033     }
1034 
1035     void text(const(char)* txt, int len, NKFlags flags)
1036     {
1037         nk_text(&ctx, txt, len, flags);
1038     }
1039 
1040     void textColored(const(char)* txt, int len, NKFlags flags, NKColor color)
1041     {
1042         nk_text_colored(&ctx, txt, len, flags, color);
1043     }
1044 
1045     void textWrap(const(char)* txt, int len)
1046     {
1047         nk_text_wrap(&ctx, txt, len);
1048     }
1049 
1050     void textWrapColored(const(char)* txt, int len, NKColor color)
1051     {
1052         nk_text_wrap_colored(&ctx, txt, len, color);
1053     }
1054 
1055     void label(const(char)* txt, NKFlags align__)
1056     {
1057         nk_label(&ctx, txt, align__);
1058     }
1059 
1060     void labelColored(const(char)* txt, NKFlags align__, NKColor color)
1061     {
1062         nk_label_colored(&ctx, txt, align__, color);
1063     }
1064 
1065     void labelWrap(const(char)* txt)
1066     {
1067         nk_label_wrap(&ctx, txt);
1068     }
1069 
1070     void labelColoredWrap(const(char)* txt, NKColor color)
1071     {
1072         nk_label_colored_wrap(&ctx, txt, color);
1073     }
1074 
1075     void image(NKImage img)
1076     {
1077         nk_image_(&ctx, img);
1078     }
1079 
1080     void imageColor(NKImage img, NKColor color)
1081     {
1082         nk_image_color(&ctx, img, color);
1083     }
1084 
1085     void labelf(NKFlags align_, const(char)* format, ...)
1086     {
1087         va_list args;
1088         va_start(args, format);
1089         nk_labelfv(&ctx, align_, format, args);
1090     }
1091 
1092     void labelfColored(NKFlags align_, NKColor color, const(char)* format, ...)
1093     {
1094         va_list args;
1095         va_start(args, format);
1096         nk_labelf_colored(&ctx, align_, color, format, args);
1097     }
1098 
1099     void labelfWrap(const(char)* format, ...)
1100     {
1101         va_list args;
1102         va_start(args, format);
1103         nk_labelf_wrap(&ctx, format, args);
1104     }
1105 
1106     void labelfColoredWrap(NKColor color, const(char)* format, ...)
1107     {
1108         va_list args;
1109         va_start(args, format);
1110         nk_labelf_colored_wrap(&ctx, color, format, args);
1111     }
1112 
1113     void valueBool(const(char)* prefix, int value)
1114     {
1115         nk_value_bool(&ctx, prefix, value);
1116     }
1117 
1118     void valueInt(const(char)* prefix, int value)
1119     {
1120         nk_value_int(&ctx, prefix, value);
1121     }
1122 
1123     void valueUint(const(char)* prefix, uint value)
1124     {
1125         nk_value_uint(&ctx, prefix, value);
1126     }
1127 
1128     void valueFloat(const(char)* prefix, float value)
1129     {
1130         nk_value_float(&ctx, prefix, value);
1131     }
1132 
1133     void valueColorByte(const(char)* prefix, NKColor value)
1134     {
1135         nk_value_color_byte(&ctx, prefix, value);
1136     }
1137 
1138     void valueColorFloat(const(char)* prefix, NKColor value)
1139     {
1140         nk_value_color_float(&ctx, prefix, value);
1141     }
1142 
1143     void valueColorHex(const(char)* prefix, NKColor value)
1144     {
1145         nk_value_color_hex(&ctx, prefix, value);
1146     }
1147 
1148     int buttonText(const(char)* title, int len)
1149     {
1150         return nk_button_text(&ctx, title, len);
1151     }
1152 
1153     int buttonLabel(const(char)* title)
1154     {
1155         return nk_button_label(&ctx, title);
1156     }
1157 
1158     int buttonColor(Color4f color)
1159     {
1160         return nk_button_color(&ctx, color.toNKColor);
1161     }
1162 
1163     int buttonColor(NKColor color)
1164     {
1165         return nk_button_color(&ctx, color);
1166     }
1167 
1168     int buttonSymbol(nk_symbol_type type)
1169     {
1170         return nk_button_symbol(&ctx, type);
1171     }
1172 
1173     int buttonImage(NKImage img)
1174     {
1175         return nk_button_image(&ctx, img);
1176     }
1177 
1178     int buttonSymbolLabel(nk_symbol_type type, const(char)* label, NKFlags text_alignment)
1179     {
1180         return nk_button_symbol_label(&ctx, type, label, text_alignment);
1181     }
1182 
1183     int buttonSymbolText(nk_symbol_type type, const(char)* txt, int len, NKFlags align_ment)
1184     {
1185         return nk_button_symbol_text(&ctx, type, txt, len, align_ment);
1186     }
1187 
1188     int buttonImageLabel(NKImage img, const(char)* txt, NKFlags text_alignment)
1189     {
1190         return nk_button_image_label(&ctx, img, txt, text_alignment);
1191     }
1192 
1193     int buttonImageText(NKImage img, const(char)* txt, int len, NKFlags align_ment)
1194     {
1195         return nk_button_image_text(&ctx, img, txt, len, align_ment);
1196     }
1197 
1198     int buttonTextStyled(const(nk_style_button)* style, const(char)* title, int len)
1199     {
1200         return nk_button_text_styled(&ctx, style, title, len);
1201     }
1202 
1203     int buttonLabelStyled(const(nk_style_button)* style, const(char)* title)
1204     {
1205         return nk_button_label_styled(&ctx, style, title);
1206     }
1207 
1208     int buttonSymbolStyled(const(nk_style_button)* style, nk_symbol_type type)
1209     {
1210         return nk_button_symbol_styled(&ctx, style, type);
1211     }
1212 
1213     int buttonImageStyled(const(nk_style_button)* style, NKImage img)
1214     {
1215         return nk_button_image_styled(&ctx, style, img);
1216     }
1217 
1218     int buttonSymbolTextStyled(const(nk_style_button)* style, nk_symbol_type type, const(char)* txt, int len, NKFlags align_ment)
1219     {
1220         return nk_button_symbol_text_styled(&ctx, style, type, txt, len, align_ment);
1221     }
1222 
1223     int buttonSymbolLabelStyled(const(nk_style_button)* style, nk_symbol_type symbol, const(char)* title, NKFlags align_)
1224     {
1225         return nk_button_symbol_label_styled(&ctx, style, symbol, title, align_);
1226     }
1227 
1228     int buttonImageLabelStyled(const(nk_style_button)* style, NKImage img, const(char)* label, NKFlags text_alignment)
1229     {
1230         return nk_button_image_label_styled(&ctx, style, img, label, text_alignment);
1231     }
1232 
1233     int buttonImageTextStyled(const(nk_style_button)* style, NKImage img, const(char)* txt, int len, NKFlags align_ment)
1234     {
1235         return nk_button_image_text_styled(&ctx, style, img, txt, len, align_ment);
1236     }
1237 
1238     void buttonSetBehavior(nk_button_behavior beh)
1239     {
1240         nk_button_set_behavior(&ctx, beh);
1241     }
1242 
1243     int buttonPushBehavior(nk_button_behavior beh)
1244     {
1245         return nk_button_push_behavior(&ctx, beh);
1246     }
1247 
1248     int buttonPopBehavior()
1249     {
1250         return nk_button_pop_behavior(&ctx);
1251     }
1252 
1253     int checkLabel(const(char)* label, int active)
1254     {
1255         return nk_check_label(&ctx, label, active);
1256     }
1257 
1258     int checkText(const(char)* txt, int len, int active)
1259     {
1260         return nk_check_text(&ctx, txt, len, active);
1261     }
1262 
1263     uint checkFlagsLabel(const(char)* label, uint flags, uint value)
1264     {
1265         return nk_check_flags_label(&ctx, label, flags, value);
1266     }
1267 
1268     uint checkFlagsText(const(char)* txt, int len, uint flags, uint value)
1269     {
1270         return nk_check_flags_text(&ctx, txt, len, flags, value);
1271     }
1272 
1273     int checkboxLabel(const(char)* label, int* active)
1274     {
1275         return nk_checkbox_label(&ctx, label, active);
1276     }
1277 
1278     int checkboxText(const(char)* txt, int len, int* active)
1279     {
1280         return nk_checkbox_text(&ctx, txt, len, active);
1281     }
1282 
1283     int checkboxFlagsLabel(const(char)* label, uint* flags, uint value)
1284     {
1285         return nk_checkbox_flags_label(&ctx, label, flags, value);
1286     }
1287 
1288     int checkboxFlagsText(const(char)* txt, int len, uint* flags, uint value)
1289     {
1290         return nk_checkbox_flags_text(&ctx, txt, len, flags, value);
1291     }
1292 
1293     int radioLabel(const(char)* label, int* active)
1294     {
1295         return nk_radio_label(&ctx, label, active);
1296     }
1297 
1298     int radioText(const(char)* txt, int len, int* active)
1299     {
1300         return nk_radio_text(&ctx, txt, len, active);
1301     }
1302 
1303     int optionLabel(const(char)* label, int active)
1304     {
1305         return nk_option_label(&ctx, label, active);
1306     }
1307 
1308     int optionText(const(char)* txt, int len, int active)
1309     {
1310         return nk_option_text(&ctx, txt, len, active);
1311     }
1312 
1313     int selectableLabel(const(char)* label, NKFlags align_, int* value)
1314     {
1315         return nk_selectable_label(&ctx, label, align_, value);
1316     }
1317 
1318     int selectableText(const(char)* txt, int len, NKFlags align_, int* value)
1319     {
1320         return nk_selectable_text(&ctx, txt, len, align_, value);
1321     }
1322 
1323     int selectableImageLabel(NKImage img, const(char)* label, NKFlags align_, int* value)
1324     {
1325         return nk_selectable_image_label(&ctx, img, label, align_, value);
1326     }
1327 
1328     int selectableImageText(NKImage img, const(char)* text, int len, NKFlags align_, int* value)
1329     {
1330         return nk_selectable_image_text(&ctx, img, text, len, align_, value);
1331     }
1332 
1333     int selectableSymbolLabel(nk_symbol_type type, const(char)* label, NKFlags align_, int* value)
1334     {
1335         return nk_selectable_symbol_label(&ctx, type, label, align_, value);
1336     }
1337 
1338     int selectableSymbolText(nk_symbol_type type, const(char)* txt, int len, NKFlags align_, int* value)
1339     {
1340         return nk_selectable_symbol_text(&ctx, type, txt, len, align_, value);
1341     }
1342 
1343     int selectLabel(const(char)* label, NKFlags align_, int value)
1344     {
1345         return nk_select_label(&ctx, label, align_, value);
1346     }
1347 
1348     int selectText(const(char)* txt, int len, NKFlags align_, int value)
1349     {
1350         return nk_select_text(&ctx, txt, len, align_, value);
1351     }
1352 
1353     int selectImageLabel(NKImage img, const(char)* label, NKFlags align_, int value)
1354     {
1355         return nk_select_image_label(&ctx, img, label, align_, value);
1356     }
1357 
1358     int selectImageText(NKImage img, const(char)* txt, int len, NKFlags align_, int value)
1359     {
1360         return nk_select_image_text(&ctx, img, txt, len, align_, value);
1361     }
1362 
1363     int selectSymbolLabel(nk_symbol_type type, const(char)* label, NKFlags align_, int value)
1364     {
1365         return nk_select_symbol_label(&ctx, type, label, align_, value);
1366     }
1367 
1368     int selectSymbolText(nk_symbol_type type, const(char)* txt, int len, NKFlags align_, int value)
1369     {
1370         return nk_select_symbol_text(&ctx, type, txt, len, align_, value);
1371     }
1372 
1373     float slide(float min, float val, float max, float step)
1374     {
1375         return nk_slide_float(&ctx,min, val, max, step);
1376     }
1377 
1378     int slide(int min, int val, int max, int step)
1379     {
1380         return nk_slide_int(&ctx,min, val, max, step);
1381     }
1382 
1383     int slider(float min, float* val, float max, float step)
1384     {
1385         return nk_slider_float(&ctx, min, val, max, step);
1386     }
1387 
1388     int slider(int min, int* val, int max, int step)
1389     {
1390         return nk_slider_int(&ctx, min, val, max, step);
1391     }
1392 
1393     int progress(NKSize* cur, NKSize max, int modifyable)
1394     {
1395         return nk_progress(&ctx, cur, max, modifyable);
1396     }
1397 
1398     NKSize prog(NKSize cur, NKSize max, int modifyable)
1399     {
1400         return nk_prog(&ctx, cur, max, modifyable);
1401     }
1402 
1403     NKColorf colorPicker(NKColorf color, nk_color_format format)
1404     {
1405         return nk_color_picker(&ctx, color, format);
1406     }
1407 
1408     Color4f colorPicker(Color4f color, nk_color_format format)
1409     {
1410         nk_colorf tmp = nk_colorf(color.r, color.g, color.b, color.a);
1411         tmp = nk_color_picker(&ctx, tmp, format);
1412         return Color4f(tmp.r, tmp.g, tmp.b, tmp.a);
1413     }
1414 
1415     int colorPick(NKColorf* color, nk_color_format format)
1416     {
1417         return nk_color_pick(&ctx, color, format);
1418     }
1419 
1420     int colorPick(Color4f* color, nk_color_format format)
1421     {
1422         nk_colorf tmp = nk_colorf(color.r, color.g, color.b, color.a);
1423         int res = nk_color_pick(&ctx, &tmp, format);
1424         *color = Color4f(tmp.r, tmp.g, tmp.b, tmp.a);
1425         return res;
1426     }
1427 
1428     void property(const(char)* name, int min, int* val, int max, int step, float inc_per_pixel)
1429     {
1430         nk_property_int(&ctx, name, min, val, max, step, inc_per_pixel);
1431     }
1432 
1433     void property(const(char)* name, float min, float* val, float max, float step, float inc_per_pixel)
1434     {
1435         nk_property_float(&ctx, name, min, val, max, step, inc_per_pixel);
1436     }
1437 
1438     void property(const(char)* name, double min, double* val, double max, double step, float inc_per_pixel)
1439     {
1440         nk_property_double(&ctx, name, min, val, max, step, inc_per_pixel);
1441     }
1442 
1443     int property(const(char)* name, int min, int val, int max, int step, float inc_per_pixel)
1444     {
1445         return nk_propertyi(&ctx, name, min, val, max, step, inc_per_pixel);
1446     }
1447 
1448     float property(const(char)* name, float min, float val, float max, float step, float inc_per_pixel)
1449     {
1450         return nk_propertyf(&ctx, name, min, val, max, step, inc_per_pixel);
1451     }
1452 
1453     double property(const(char)* name, double min, double val, double max, double step, float inc_per_pixel)
1454     {
1455         return nk_propertyd(&ctx, name, min, val, max, step, inc_per_pixel);
1456     }
1457 
1458     alias nk_filter_default_fptr filterDefault;
1459     alias nk_filter_ascii_fptr filterAscii;
1460     alias nk_filter_float_fptr filterFloat;
1461     alias nk_filter_decimal_fptr filterDecimal;
1462     alias nk_filter_hex_fptr filterHex;
1463     alias nk_filter_oct_fptr filterOct;
1464     alias nk_filter_binary_fptr filterBinary;
1465 
1466     NKFlags editString(NKFlags flags, char* buffer, int* len, int max, nk_plugin_filter filter = filterDefault)
1467     {
1468         return nk_edit_string(&ctx, flags, buffer, len, max, filter);
1469     }
1470 
1471     NKFlags editStringZeroTerminated(NKFlags flags, char* buffer, int max, nk_plugin_filter filter = filterDefault)
1472     {
1473         return nk_edit_string_zero_terminated(&ctx, flags, buffer, max, filter);
1474     }
1475 
1476     NKFlags editBuffer(NKFlags flags, nk_text_edit* edit, nk_plugin_filter filter = filterDefault)
1477     {
1478         return nk_edit_buffer(&ctx, flags, edit, filter);
1479     }
1480 
1481     void editFocus(NKFlags flags)
1482     {
1483         nk_edit_focus(&ctx, flags);
1484     }
1485 
1486     void editUnfocus()
1487     {
1488         nk_edit_unfocus(&ctx);
1489     }
1490 
1491     int chartBegin(nk_chart_type type, int num, float min, float max)
1492     {
1493         return nk_chart_begin(&ctx, type, num, min, max);
1494     }
1495 
1496     int chartBeginColored(nk_chart_type type, NKColor color, NKColor active, int num, float min, float max)
1497     {
1498         return nk_chart_begin_colored(&ctx, type, color, active, num, min, max);
1499     }
1500 
1501     void chartAddSlot(const(nk_chart_type) type, int count, float min_value, float max_value)
1502     {
1503         nk_chart_add_slot(&ctx, type, count, min_value, max_value);
1504     }
1505 
1506     void chartAddSlotColored(const(nk_chart_type) type, NKColor color, NKColor active, int count, float min_value, float max_value)
1507     {
1508         nk_chart_add_slot_colored(&ctx, type, color, active, count, min_value, max_value);
1509     }
1510 
1511     NKFlags chartPush(float value)
1512     {
1513         return nk_chart_push(&ctx, value);
1514     }
1515 
1516     NKFlags chartPushSlot(float value, int slot)
1517     {
1518         return nk_chart_push_slot(&ctx, value, slot);
1519     }
1520 
1521     void chartEnd()
1522     {
1523         nk_chart_end(&ctx);
1524     }
1525 
1526     void plot(nk_chart_type type, const(float)* values, int count, int offset)
1527     {
1528         nk_plot(&ctx, type, values, count, offset);
1529     }
1530 
1531     void plotFunction(nk_chart_type type, float function(int index) fn, int count, int offset)
1532     {
1533         import std.algorithm : min, max;
1534         int i = 0;
1535         float min_value;
1536         float max_value;
1537 
1538         if (count == 0) return;
1539 
1540         max_value = min_value = fn(offset);
1541         for (i = 0; i < count; ++i)
1542         {
1543             float value = fn(i + offset);
1544             min_value = min(value, min_value);
1545             max_value = max(value, max_value);
1546         }
1547 
1548         if (nk_chart_begin(&ctx, type, count, min_value, max_value))
1549         {
1550             for (i = 0; i < count; ++i)
1551                 nk_chart_push(&ctx, fn(i + offset));
1552             nk_chart_end(&ctx);
1553         }
1554     }
1555 
1556     int popupBegin(nk_popup_type type, const(char)* title, NKFlags flags, NKRect bounds)
1557     {
1558         return nk_popup_begin(&ctx, type, title, flags, bounds);
1559     }
1560 
1561     void popupClose()
1562     {
1563         nk_popup_close(&ctx);
1564     }
1565 
1566     void popupEnd()
1567     {
1568         nk_popup_end(&ctx);
1569     }
1570 
1571     int combo(const(char)** items, int count, int selected, int item_height, NKVec2 size)
1572     {
1573         return nk_combo(&ctx, items, count, selected, item_height, size);
1574     }
1575 
1576     int comboSeparator(const(char)* items_separated_by_separator, int separator, int selected, int count, int item_height, NKVec2 size)
1577     {
1578         return nk_combo_separator(&ctx, items_separated_by_separator, separator, selected, count, item_height, size);
1579     }
1580 
1581     int comboString(const(char)* items_separated_by_zeros, int selected, int count, int item_height, NKVec2 size)
1582     {
1583         return nk_combo_string(&ctx, items_separated_by_zeros, selected, count, item_height, size);
1584     }
1585 
1586     /*int comboCallback(void func(void*, int, const(char) **) fn, void *userdata, int selected, int count, int item_height, NKVec2 size)
1587     {
1588     return nk_combo_callback(&ctx, fn, userdata, selected, count, item_height, size);
1589     }*/
1590 
1591     void combobox(const(char)** items, int count, int* selected, int item_height, NKVec2 size)
1592     {
1593         nk_combobox(&ctx, items, count, selected, item_height, size);
1594     }
1595 
1596     void comboboxString(const(char)* items_separated_by_zeros, int* selected, int count, int item_height, NKVec2 size)
1597     {
1598         nk_combobox_string(&ctx, items_separated_by_zeros, selected, count, item_height, size);
1599     }
1600 
1601     void comboboxSeparator(const(char)* items_separated_by_separator, int separator, int* selected, int count, int item_height, NKVec2 size)
1602     {
1603         nk_combobox_separator(&ctx, items_separated_by_separator, separator, selected, count, item_height, size);
1604     }
1605 
1606     /*void comboboxCallback(void function(void*, int, const(char) **), void*, int *selected, int count, int item_height, NKVec2 size)
1607     {
1608     nk_combobox_callback(&ctx);
1609     }*/
1610 
1611     int comboBeginText(const(char)* selected, int len, NKVec2 size)
1612     {
1613         return nk_combo_begin_text(&ctx, selected, len, size);
1614     }
1615 
1616     int comboBeginLabel(const(char)* selected, NKVec2 size)
1617     {
1618         return nk_combo_begin_label(&ctx, selected, size);
1619     }
1620 
1621     int comboBeginColor(NKColor color, NKVec2 size)
1622     {
1623         return nk_combo_begin_color(&ctx, color, size);
1624     }
1625 
1626     int comboBeginSymbol(nk_symbol_type type, NKVec2 size)
1627     {
1628         return nk_combo_begin_symbol(&ctx, type, size);
1629     }
1630 
1631     int comboBeginSymbolLabel(const(char)* selected, nk_symbol_type type, NKVec2 size)
1632     {
1633         return nk_combo_begin_symbol_label(&ctx, selected, type, size);
1634     }
1635 
1636     int comboBeginSymbolText(const(char)* selected, int len, nk_symbol_type type, NKVec2 size)
1637     {
1638         return nk_combo_begin_symbol_text(&ctx, selected, len, type, size);
1639     }
1640 
1641     int comboBeginImage(NKImage img, NKVec2 size)
1642     {
1643         return nk_combo_begin_image(&ctx, img, size);
1644     }
1645 
1646     int comboBeginImageLabel(const(char)* selected, NKImage img, NKVec2 size)
1647     {
1648         return nk_combo_begin_image_label(&ctx, selected, img, size);
1649     }
1650 
1651     int comboBeginImageText(const(char)* selected, int len, NKImage img, NKVec2 size)
1652     {
1653         return nk_combo_begin_image_text(&ctx, selected, len, img, size);
1654     }
1655 
1656     int comboItemLabel(const(char)* label, NKFlags align_ment)
1657     {
1658         return nk_combo_item_label(&ctx, label, align_ment);
1659     }
1660 
1661     int comboItemText(const(char)* txt, int len, NKFlags align_ment)
1662     {
1663         return nk_combo_item_text(&ctx, txt, len, align_ment);
1664     }
1665 
1666     int comboItemImageLabel(NKImage img, const(char)* label, NKFlags align_ment)
1667     {
1668         return nk_combo_item_image_label(&ctx, img, label, align_ment);
1669     }
1670 
1671     int comboItemImageText(NKImage img, const(char)* txt, int len, NKFlags align_ment)
1672     {
1673         return nk_combo_item_image_text(&ctx, img, txt, len, align_ment);
1674     }
1675 
1676     int comboItemSymbolLabel(nk_symbol_type type, const(char)* label, NKFlags align_ment)
1677     {
1678         return nk_combo_item_symbol_label(&ctx, type, label, align_ment);
1679     }
1680 
1681     int comboItemSymbolText(nk_symbol_type type, const(char)* txt, int len, NKFlags align_ment)
1682     {
1683         return nk_combo_item_symbol_text(&ctx, type, txt, len, align_ment);
1684     }
1685 
1686     void comboClose()
1687     {
1688         nk_combo_close(&ctx);
1689     }
1690 
1691     void comboEnd()
1692     {
1693         nk_combo_end(&ctx);
1694     }
1695 
1696     int contextualBegin(NKFlags flags, NKVec2 size, NKRect trigger_bounds)
1697     {
1698         return nk_contextual_begin(&ctx, flags, size, trigger_bounds);
1699     }
1700 
1701     int contextualItemText(const(char)* txt, int len, NKFlags align_)
1702     {
1703         return nk_contextual_item_text(&ctx, txt, len, align_);
1704     }
1705 
1706     int contextualItemLabel(const(char)* label, NKFlags align_)
1707     {
1708         return nk_contextual_item_label(&ctx, label, align_);
1709     }
1710 
1711     int contextualItemImageLabel(NKImage img, const(char)* label, NKFlags align_ment)
1712     {
1713         return nk_contextual_item_image_label(&ctx, img, label, align_ment);
1714     }
1715 
1716     int contextualItemImageText(NKImage img, const(char)* txt, int len, NKFlags align_ment)
1717     {
1718         return nk_contextual_item_image_text(&ctx, img, txt, len, align_ment);
1719     }
1720 
1721     int contextualItemSymbolLabel(nk_symbol_type type, const(char)* label, NKFlags align_ment)
1722     {
1723         return nk_contextual_item_symbol_label(&ctx, type, label, align_ment);
1724     }
1725 
1726     int contextualItemSymbolText(nk_symbol_type type, const(char)* txt, int len, NKFlags align_ment)
1727     {
1728         return nk_contextual_item_symbol_text(&ctx, type, txt, len, align_ment);
1729     }
1730 
1731     void contextualClose()
1732     {
1733         nk_contextual_close(&ctx);
1734     }
1735 
1736     void contextualEnd()
1737     {
1738         nk_contextual_end(&ctx);
1739     }
1740 
1741     void tooltip(const(char)* txt)
1742     {
1743         nk_tooltip(&ctx, txt);
1744     }
1745 
1746     void tooltipf(const(char)* format, ...)
1747     {
1748         va_list args;
1749         va_start(args, format);
1750         nk_tooltipfv(&ctx, format, args);
1751     }
1752 
1753     int tooltipBegin(float width)
1754     {
1755         return nk_tooltip_begin(&ctx, width);
1756     }
1757 
1758     void tooltipEnd()
1759     {
1760         nk_tooltip_end(&ctx);
1761     }
1762 
1763     void menubarBegin()
1764     {
1765         nk_menubar_begin(&ctx);
1766     }
1767 
1768     void menubarEnd()
1769     {
1770         nk_menubar_end(&ctx);
1771     }
1772 
1773     int menuBeginText(const(char)* title, int title_len, NKFlags align_, NKVec2 size)
1774     {
1775         return nk_menu_begin_text(&ctx, title, title_len, align_, size);
1776     }
1777 
1778     int menuBeginLabel(const(char)* label, NKFlags align_, NKVec2 size)
1779     {
1780         return nk_menu_begin_label(&ctx, label, align_, size);
1781     }
1782 
1783     int menuBeginImage(const(char)* label, NKImage img, NKVec2 size)
1784     {
1785         return nk_menu_begin_image(&ctx, label, img, size);
1786     }
1787 
1788     int menuBeginImageText(const(char)* txt, int len, NKFlags align_, NKImage img, NKVec2 size)
1789     {
1790         return nk_menu_begin_image_text(&ctx, txt, len, align_, img, size);
1791     }
1792 
1793     int menuBeginImageLabel(const(char)* label, NKFlags align_, NKImage img, NKVec2 size)
1794     {
1795         return nk_menu_begin_image_label(&ctx, label, align_, img, size);
1796     }
1797 
1798     int menuBeginSymbol(const(char)* label, nk_symbol_type type, NKVec2 size)
1799     {
1800         return nk_menu_begin_symbol(&ctx, label, type, size);
1801     }
1802 
1803     int menuBeginSymbolText(const(char)* txt, int len, NKFlags align_, nk_symbol_type type, NKVec2 size)
1804     {
1805         return nk_menu_begin_symbol_text(&ctx, txt, len, align_, type, size);
1806     }
1807 
1808     int menuBeginSymbolLabel(const(char)* label, NKFlags align_, nk_symbol_type type, NKVec2 size)
1809     {
1810         return nk_menu_begin_symbol_label(&ctx, label, align_, type, size);
1811     }
1812 
1813     int menuItemText(const(char)* txt, int len, NKFlags align_)
1814     {
1815         return nk_menu_item_text(&ctx, txt, len, align_);
1816     }
1817 
1818     int menuItemLabel(const(char)* label, NKFlags align_ment)
1819     {
1820         return nk_menu_item_label(&ctx, label, align_ment);
1821     }
1822 
1823     int menuItemImageLabel(NKImage img, const(char)* label, NKFlags align_ment)
1824     {
1825         return nk_menu_item_image_label(&ctx, img, label, align_ment);
1826     }
1827 
1828     int menuItemImageText(NKImage img, const(char)* txt, int len, NKFlags align_ment)
1829     {
1830         return nk_menu_item_image_text(&ctx, img, txt, len, align_ment);
1831     }
1832 
1833     int menuItemSymbolText(nk_symbol_type type, const(char)* txt, int len, NKFlags align_ment)
1834     {
1835         return nk_menu_item_symbol_text(&ctx, type, txt, len, align_ment);
1836     }
1837 
1838     int menuItemSymbolLabel(nk_symbol_type type, const(char)* label, NKFlags align_ment)
1839     {
1840         return nk_menu_item_symbol_label(&ctx, type, label, align_ment);
1841     }
1842 
1843     void menuClose()
1844     {
1845         nk_menu_close(&ctx);
1846     }
1847 
1848     void menuEnd()
1849     {
1850         nk_menu_end(&ctx);
1851     }
1852 
1853     void styleDefault()
1854     {
1855         nk_style_default(&ctx);
1856     }
1857 
1858     void styleFromTable(const(NKColor)* colors)
1859     {
1860         nk_style_from_table(&ctx, colors);
1861     }
1862 
1863     void styleLoadCursor(nk_style_cursor cursor, const(NKCursor)* c)
1864     {
1865         nk_style_load_cursor(&ctx, cursor, c);
1866     }
1867 
1868     void styleLoadAllCursors(NKCursor* cursor)
1869     {
1870         nk_style_load_all_cursors(&ctx, cursor);
1871     }
1872 
1873     void styleSetFont(uint index)
1874     {
1875         nk_style_set_font(&ctx, &(getFont(index)).handle);
1876     }
1877 
1878     void styleSetFont(const(NKFont)* font)
1879     {
1880         nk_style_set_font(&ctx, &font.handle);
1881     }
1882 
1883     void styleSetFont(const(nk_user_font)* font)
1884     {
1885         nk_style_set_font(&ctx, font);
1886     }
1887 
1888     int styleSetCursor(nk_style_cursor cursor)
1889     {
1890         return nk_style_set_cursor(&ctx, cursor);
1891     }
1892 
1893     void styleShowCursor()
1894     {
1895         nk_style_show_cursor(&ctx);
1896     }
1897 
1898     void styleHideCursor()
1899     {
1900         nk_style_hide_cursor(&ctx);
1901     }
1902 
1903     int stylePushFont(const(nk_user_font)* font)
1904     {
1905         return nk_style_push_font(&ctx, font);
1906     }
1907 
1908     int stylePushFloat(float* address, float value)
1909     {
1910         return nk_style_push_float(&ctx, address, value);
1911     }
1912 
1913     int stylePushVec2(NKVec2* address, NKVec2 value)
1914     {
1915         return nk_style_push_vec2(&ctx, address, value);
1916     }
1917 
1918     int stylePushStyleItem(nk_style_item* address, nk_style_item value)
1919     {
1920         return nk_style_push_style_item(&ctx, address, value);
1921     }
1922 
1923     int stylePushFlags(NKFlags* address, NKFlags value)
1924     {
1925         return nk_style_push_flags(&ctx, address, value);
1926     }
1927 
1928     int stylePushColor(NKColor* address, NKColor value)
1929     {
1930         return nk_style_push_color(&ctx, address, value);
1931     }
1932 
1933     int stylePopFont()
1934     {
1935         return nk_style_pop_font(&ctx);
1936     }
1937 
1938     int stylePopFloat()
1939     {
1940         return nk_style_pop_float(&ctx);
1941     }
1942 
1943     int stylePopVec2()
1944     {
1945         return nk_style_pop_vec2(&ctx);
1946     }
1947 
1948     int stylePopStyleItem()
1949     {
1950         return nk_style_pop_style_item(&ctx);
1951     }
1952 
1953     int stylePopFlags()
1954     {
1955         return nk_style_pop_flags(&ctx);
1956     }
1957 
1958     int stylePopColor()
1959     {
1960         return nk_style_pop_color(&ctx);
1961     }
1962 
1963     // Primitives
1964 
1965     void strokeLine(float x0, float y0, float x1, float y1, float line_thickness, NKColor color)
1966     {
1967         if(ctx.current)
1968             nk_stroke_line(&ctx.current.buffer, x0, y0, x1, y1, line_thickness, color);
1969     }
1970 
1971     void strokeCurve(float ax, float ay, float ctrl0x, float ctrl0y, float ctrl1x, float ctrl1y, float bx, float by, float line_thickness, NKColor color)
1972     {
1973         if(ctx.current)
1974             nk_stroke_curve(&ctx.current.buffer, ax, ay, ctrl0x, ctrl0y, ctrl1x, ctrl1y, bx, by, line_thickness, color);
1975     }
1976 
1977     void strokeRect(NKRect rect, float rounding, float line_thickness, NKColor color)
1978     {
1979         if(ctx.current)
1980             nk_stroke_rect(&ctx.current.buffer, rect, rounding, line_thickness, color);
1981     }
1982 
1983     void strokeCircle(NKRect rect, float line_thickness, NKColor color)
1984     {
1985         if(ctx.current)
1986             nk_stroke_circle(&ctx.current.buffer, rect, line_thickness, color);
1987     }
1988 
1989     void strokeArc(float cx, float cy, float radius, float a_min, float a_max, float line_thickness, NKColor color)
1990     {
1991         if(ctx.current)
1992             nk_stroke_arc(&ctx.current.buffer, cx, cy, radius, a_min, a_max, line_thickness, color);
1993     }
1994 
1995     void strokeTriangle(float x0, float y0, float x1, float y1, float x2, float y2, float line_thichness, NKColor color)
1996     {
1997         if(ctx.current)
1998             nk_stroke_triangle(&ctx.current.buffer, x0, y0, x1, y1, x2, y2, line_thichness, color);
1999     }
2000 
2001     void strokePolyline(float* points, int point_count, float line_thickness, NKColor color)
2002     {
2003         if(ctx.current)
2004             nk_stroke_polyline(&ctx.current.buffer, points, point_count, line_thickness, color);
2005     }
2006 
2007     void strokePolygon(float* points, int point_count, float line_thickness, NKColor color)
2008     {
2009         if(ctx.current)
2010             nk_stroke_polygon(&ctx.current.buffer, points, point_count, line_thickness, color);
2011     }
2012 
2013     void fillRect(NKRect rect, float rounding, NKColor color)
2014     {
2015         if(ctx.current)
2016             nk_fill_rect(&ctx.current.buffer, rect, rounding, color);
2017     }
2018 
2019     void fillRectMultiColor(NKRect rect, NKColor left, NKColor top, NKColor right, NKColor bottom)
2020     {
2021         if(ctx.current)
2022             nk_fill_rect_multi_color(&ctx.current.buffer, rect, left, top, right, bottom);
2023     }
2024 
2025     void fillCircle(NKRect rect, NKColor color)
2026     {
2027         if(ctx.current)
2028             nk_fill_circle(&ctx.current.buffer, rect, color);
2029     }
2030 
2031     void fillArc(float cx, float cy, float radius, float a_min, float a_max, NKColor color)
2032     {
2033         if(ctx.current)
2034             nk_fill_arc(&ctx.current.buffer, cx, cy, radius, a_min, a_max, color);
2035     }
2036 
2037     void fillTriangle(float x0, float y0, float x1, float y1, float x2, float y2, NKColor color)
2038     {
2039         if(ctx.current)
2040             nk_fill_triangle(&ctx.current.buffer, x0, y0, x1, y1, x2, y2, color);
2041     }
2042 
2043     void fillPolygon(float* points, int point_count, NKColor color)
2044     {
2045         if(ctx.current)
2046             nk_fill_polygon(&ctx.current.buffer, points, point_count, color);
2047     }
2048 
2049     void drawImage(NKRect rect, const(NKImage)* image, NKColor color)
2050     {
2051         if(ctx.current)
2052             nk_draw_image(&ctx.current.buffer, rect, image, color);
2053     }
2054 
2055     void drawText(NKRect rect, const(char)* txt, int len, const(NKFont)* font, NKColor bg, NKColor fg)
2056     {
2057         drawText(rect, txt, len, &font.handle, bg, fg);
2058     }
2059 
2060     void drawText(NKRect rect, const(char)* txt, int len, const(nk_user_font)* font, NKColor bg, NKColor fg)
2061     {
2062         if(!font)
2063             font = &atlases[0].default_font.handle;
2064         if(ctx.current)
2065             nk_draw_text(&ctx.current.buffer, rect, txt, len, font, bg, fg);
2066     }
2067 
2068     void pushScissor(NKRect rect)
2069     {
2070         if(ctx.current)
2071             nk_push_scissor(&ctx.current.buffer, rect);
2072     }
2073 
2074     // Colors
2075 
2076     NKColor rgb(int r, int g, int b)
2077     {
2078         return nk_rgb(r, g, b);
2079     }
2080 
2081     NKColor rgb(float r, float g, float b)
2082     {
2083         return nk_rgb_f(r, g, b);
2084     }
2085 
2086     NKColor rgb(char* hex)
2087     {
2088         return nk_rgb_hex(hex);
2089     }
2090 
2091     NKColor rgba(int r, int g, int b, int a)
2092     {
2093         return nk_rgba(r, g, b, a);
2094     }
2095 
2096     NKColor rgba(float r, float g, float b, float a)
2097     {
2098         return nk_rgba_f(r, g, b, a);
2099     }
2100 
2101     NKColor rgba(char* hex)
2102     {
2103         return nk_rgba_hex(hex);
2104     }
2105 
2106     NKColor hsv(int h, int s, int v)
2107     {
2108         return nk_hsv(h, s, v);
2109     }
2110 
2111     NKColor hsv(float h, float s, float v)
2112     {
2113         return nk_hsv_f(h, s, v);
2114     }
2115 
2116     NKColor hsva(int h, int s, int v, int a)
2117     {
2118         return nk_hsva(h, s, v, a);
2119     }
2120 
2121     NKColor hsva(float h, float s, float v, float a)
2122     {
2123         return nk_hsva_f(h, s, v, a);
2124     }
2125 }