2 #include "nuklear_internal.h"
17 nk_filter_ascii(
const struct nk_text_edit *box, nk_rune unicode)
20 if (unicode > 128)
return nk_false;
24 nk_filter_float(
const struct nk_text_edit *box, nk_rune unicode)
27 if ((unicode < '0' || unicode >
'9') && unicode !=
'.' && unicode !=
'-')
32 nk_filter_decimal(
const struct nk_text_edit *box, nk_rune unicode)
35 if ((unicode < '0' || unicode >
'9') && unicode !=
'-')
40 nk_filter_hex(
const struct nk_text_edit *box, nk_rune unicode)
43 if ((unicode < '0' || unicode >
'9') &&
44 (unicode < 'a' || unicode >
'f') &&
45 (unicode < 'A' || unicode >
'F'))
50 nk_filter_oct(
const struct nk_text_edit *box, nk_rune unicode)
53 if (unicode < '0' || unicode >
'7')
58 nk_filter_binary(
const struct nk_text_edit *box, nk_rune unicode)
61 if (unicode !=
'0' && unicode !=
'1')
74 float x_offset,
const char *text,
int byte_len,
float row_height,
76 struct nk_color foreground, nk_bool is_selected)
81 if (!text || !byte_len || !out || !style)
return;
88 const char *line = text;
89 float line_offset = 0;
94 txt.background = background;
95 txt.text = foreground;
97 foreground = nk_rgb_factor(foreground, style->color_factor);
98 background = nk_rgb_factor(background, style->color_factor);
100 glyph_len = nk_utf_decode(text+text_len, &unicode, byte_len-text_len);
101 if (!glyph_len)
return;
102 while ((text_len < byte_len) && glyph_len)
104 if (unicode ==
'\n') {
107 label.y = pos_y + line_offset;
108 label.h = row_height;
109 label.w = line_width;
116 nk_widget_text(out, label, line, (
int)((text + text_len) - line),
117 &txt, NK_TEXT_CENTERED, font);
122 line = text + text_len;
123 line_offset += row_height;
124 glyph_len = nk_utf_decode(text + text_len, &unicode, (
int)(byte_len-text_len));
127 if (unicode ==
'\r') {
129 glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
132 glyph_width = font->
width(font->userdata, font->
height, text+text_len, glyph_len);
133 line_width += (float)glyph_width;
134 text_len += glyph_len;
135 glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
138 if (line_width > 0) {
141 label.y = pos_y + line_offset;
142 label.h = row_height;
143 label.w = line_width;
150 nk_widget_text(out, label, line, (
int)((text + text_len) - line),
151 &txt, NK_TEXT_LEFT, font);
156 struct nk_rect bounds, nk_flags flags, nk_plugin_filter filter,
166 char cursor_follow = 0;
173 if (!state || !out || !style)
177 area.x = bounds.x + style->padding.x + style->border;
178 area.y = bounds.y + style->padding.y + style->border;
179 area.w = bounds.w - (2.0f * style->padding.x + 2 * style->border);
180 area.h = bounds.h - (2.0f * style->padding.y + 2 * style->border);
181 if (flags & NK_EDIT_MULTILINE)
182 area.w = NK_MAX(0, area.w - style->scrollbar_size.x);
183 row_height = (flags & NK_EDIT_MULTILINE)? font->
height + style->row_padding: area.h;
186 old_clip = out->clip;
187 nk_unify(&clip, &old_clip, area.x, area.y, area.x + area.w, area.y + area.h);
190 prev_state = (char)edit->active;
191 is_hovered = (
char)nk_input_is_mouse_hovering_rect(in, bounds);
192 if (in && in->mouse.buttons[NK_BUTTON_LEFT].clicked && in->mouse.buttons[NK_BUTTON_LEFT].down) {
193 edit->active = NK_INBOX(in->mouse.pos.x, in->mouse.pos.y,
194 bounds.x, bounds.y, bounds.w, bounds.h);
198 if (!prev_state && edit->active) {
199 const enum nk_text_edit_type type = (flags & NK_EDIT_MULTILINE) ?
200 NK_TEXT_EDIT_MULTI_LINE: NK_TEXT_EDIT_SINGLE_LINE;
202 struct nk_vec2 oldscrollbar = edit->scrollbar;
203 nk_textedit_clear_state(edit, type, filter);
204 edit->scrollbar = oldscrollbar;
205 if (flags & NK_EDIT_AUTO_SELECT)
206 select_all = nk_true;
207 if (flags & NK_EDIT_GOTO_END_ON_ACTIVATE) {
208 edit->cursor = edit->string.len;
211 }
else if (!edit->active) edit->mode = NK_TEXT_EDIT_MODE_VIEW;
212 if (flags & NK_EDIT_READ_ONLY)
213 edit->mode = NK_TEXT_EDIT_MODE_VIEW;
214 else if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
215 edit->mode = NK_TEXT_EDIT_MODE_INSERT;
218 if (prev_state != edit->active)
222 if (edit->active && in)
224 int shift_mod = in->keyboard.keys[NK_KEY_SHIFT].down;
225 const float mouse_x = (in->mouse.pos.x - area.x) + edit->scrollbar.x;
226 const float mouse_y = (in->mouse.pos.y - area.y) + edit->scrollbar.y;
229 is_hovered = (char)nk_input_is_mouse_hovering_rect(in, area);
231 nk_textedit_select_all(edit);
232 }
else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
233 in->mouse.buttons[NK_BUTTON_LEFT].clicked) {
234 nk_textedit_click(edit, mouse_x, mouse_y, font, row_height);
235 }
else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
236 (in->mouse.delta.x != 0.0f || in->mouse.delta.y != 0.0f)) {
237 nk_textedit_drag(edit, mouse_x, mouse_y, font, row_height);
238 cursor_follow = nk_true;
239 }
else if (is_hovered && in->mouse.buttons[NK_BUTTON_RIGHT].clicked &&
240 in->mouse.buttons[NK_BUTTON_RIGHT].down) {
241 nk_textedit_key(edit, NK_KEY_TEXT_WORD_LEFT, nk_false, font, row_height);
242 nk_textedit_key(edit, NK_KEY_TEXT_WORD_RIGHT, nk_true, font, row_height);
243 cursor_follow = nk_true;
247 int old_mode = edit->mode;
248 for (i = 0; i < NK_KEY_MAX; ++i) {
249 if (i == NK_KEY_ENTER || i == NK_KEY_TAB)
continue;
250 if (nk_input_is_key_pressed(in, (
enum nk_keys)i)) {
251 nk_textedit_key(edit, (
enum nk_keys)i, shift_mod, font, row_height);
252 cursor_follow = nk_true;
255 if (old_mode != edit->mode) {
256 in->keyboard.text_len = 0;
260 edit->filter = filter;
261 if (in->keyboard.text_len) {
262 nk_textedit_text(edit, in->keyboard.text, in->keyboard.text_len);
263 cursor_follow = nk_true;
264 in->keyboard.text_len = 0;
268 if (nk_input_is_key_pressed(in, NK_KEY_ENTER)) {
269 cursor_follow = nk_true;
270 if (flags & NK_EDIT_CTRL_ENTER_NEWLINE && shift_mod)
271 nk_textedit_text(edit,
"\n", 1);
272 else if (flags & NK_EDIT_SIG_ENTER)
274 else nk_textedit_text(edit,
"\n", 1);
278 {
int copy= nk_input_is_key_pressed(in, NK_KEY_COPY);
279 int cut = nk_input_is_key_pressed(in, NK_KEY_CUT);
280 if ((copy || cut) && (flags & NK_EDIT_CLIPBOARD))
285 int b = edit->select_start;
286 int e = edit->select_end;
288 int begin = NK_MIN(b, e);
289 int end = NK_MAX(b, e);
290 text = nk_str_at_const(&edit->string, begin, &unicode, &glyph_len);
292 edit->clip.copy(edit->clip.userdata, text, end - begin);
293 if (cut && !(flags & NK_EDIT_READ_ONLY)){
294 nk_textedit_cut(edit);
295 cursor_follow = nk_true;
300 {
int paste = nk_input_is_key_pressed(in, NK_KEY_PASTE);
301 if (paste && (flags & NK_EDIT_CLIPBOARD) && edit->clip.paste) {
302 edit->clip.paste(edit->clip.userdata, edit);
303 cursor_follow = nk_true;
307 {
int tab = nk_input_is_key_pressed(in, NK_KEY_TAB);
308 if (tab && (flags & NK_EDIT_ALLOW_TAB)) {
309 nk_textedit_text(edit,
" ", 4);
310 cursor_follow = nk_true;
317 else nk_widget_state_reset(state);
323 {
const char *text = nk_str_get_const(&edit->string);
324 int len = nk_str_len_char(&edit->string);
329 background = &style->active;
331 background = &style->hover;
332 else background = &style->normal;
335 switch(background->type) {
336 case NK_STYLE_ITEM_IMAGE:
337 nk_draw_image(out, bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
339 case NK_STYLE_ITEM_NINE_SLICE:
340 nk_draw_nine_slice(out, bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
342 case NK_STYLE_ITEM_COLOR:
343 nk_fill_rect(out, bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor));
344 nk_stroke_rect(out, bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor));
349 area.w = NK_MAX(0, area.w - style->cursor_size);
356 const char *cursor_ptr = 0;
357 const char *select_begin_ptr = 0;
358 const char *select_end_ptr = 0;
365 int selection_begin = NK_MIN(edit->select_start, edit->select_end);
366 int selection_end = NK_MAX(edit->select_start, edit->select_end);
369 float line_width = 0.0f;
380 glyph_len = nk_utf_decode(text, &unicode, len);
381 glyph_width = font->
width(font->userdata, font->
height, text, glyph_len);
385 while ((text_len < len) && glyph_len)
388 if (!cursor_ptr && glyphs == edit->cursor)
393 const char *remaining;
396 cursor_pos.y = (float)(total_lines-1) * row_height;
397 row_size = nk_text_calculate_text_bounds(font, text+row_begin,
398 text_len-row_begin, row_height, &remaining,
399 &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
400 cursor_pos.x = row_size.x;
401 cursor_ptr = text + text_len;
405 if (!select_begin_ptr && edit->select_start != edit->select_end &&
406 glyphs == selection_begin)
411 const char *remaining;
414 selection_offset_start.y = (float)(NK_MAX(total_lines-1,0)) * row_height;
415 row_size = nk_text_calculate_text_bounds(font, text+row_begin,
416 text_len-row_begin, row_height, &remaining,
417 &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
418 selection_offset_start.x = row_size.x;
419 select_begin_ptr = text + text_len;
423 if (!select_end_ptr && edit->select_start != edit->select_end &&
424 glyphs == selection_end)
429 const char *remaining;
432 selection_offset_end.y = (float)(total_lines-1) * row_height;
433 row_size = nk_text_calculate_text_bounds(font, text+row_begin,
434 text_len-row_begin, row_height, &remaining,
435 &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
436 selection_offset_end.x = row_size.x;
437 select_end_ptr = text + text_len;
439 if (unicode ==
'\n') {
440 text_size.x = NK_MAX(text_size.x, line_width);
445 row_begin = text_len;
446 glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
447 glyph_width = font->
width(font->userdata, font->
height, text+text_len, glyph_len);
452 text_len += glyph_len;
453 line_width += (float)glyph_width;
455 glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
456 glyph_width = font->
width(font->userdata, font->
height,
457 text+text_len, glyph_len);
460 text_size.y = (float)total_lines * row_height;
463 if (!cursor_ptr && edit->cursor == edit->string.len) {
464 cursor_pos.x = line_width;
465 cursor_pos.y = text_size.y - row_height;
473 if (!(flags & NK_EDIT_NO_HORIZONTAL_SCROLL)) {
475 const float scroll_increment = area.w * 0.25f;
476 if (cursor_pos.x < edit->scrollbar.x)
477 edit->scrollbar.x = (float)(
int)NK_MAX(0.0f, cursor_pos.x - scroll_increment);
478 if (cursor_pos.x >= edit->scrollbar.x + area.w)
479 edit->scrollbar.x = (float)(
int)NK_MAX(0.0f, cursor_pos.x - area.w + scroll_increment);
480 }
else edit->scrollbar.x = 0;
482 if (flags & NK_EDIT_MULTILINE) {
484 if (cursor_pos.y < edit->scrollbar.y)
485 edit->scrollbar.y = NK_MAX(0.0f, cursor_pos.y - row_height);
486 if (cursor_pos.y >= edit->scrollbar.y + row_height)
487 edit->scrollbar.y = edit->scrollbar.y + row_height;
488 }
else edit->scrollbar.y = 0;
492 if (flags & NK_EDIT_MULTILINE)
502 scroll.x = (bounds.x + bounds.w - style->border) - style->scrollbar_size.x;
503 scroll.w = style->scrollbar_size.x;
505 scroll_offset = edit->scrollbar.y;
506 scroll_step = scroll.h * 0.10f;
507 scroll_inc = scroll.h * 0.01f;
508 scroll_target = text_size.y;
509 edit->scrollbar.y = nk_do_scrollbarv(&ws, out, scroll, 0,
510 scroll_offset, scroll_target, scroll_step, scroll_inc,
511 &style->scrollbar, in, font);
518 struct nk_color sel_background_color;
523 nk_push_scissor(out, clip);
527 background = &style->active;
528 text_color = style->text_active;
529 sel_text_color = style->selected_text_hover;
530 sel_background_color = style->selected_hover;
531 cursor_color = style->cursor_hover;
532 cursor_text_color = style->cursor_text_hover;
534 background = &style->hover;
535 text_color = style->text_hover;
536 sel_text_color = style->selected_text_hover;
537 sel_background_color = style->selected_hover;
538 cursor_text_color = style->cursor_text_hover;
539 cursor_color = style->cursor_hover;
541 background = &style->normal;
542 text_color = style->text_normal;
543 sel_text_color = style->selected_text_normal;
544 sel_background_color = style->selected_normal;
545 cursor_color = style->cursor_normal;
546 cursor_text_color = style->cursor_text_normal;
548 if (background->type == NK_STYLE_ITEM_IMAGE)
549 background_color = nk_rgba(0,0,0,0);
551 background_color = background->data.color;
553 cursor_color = nk_rgb_factor(cursor_color, style->color_factor);
554 cursor_text_color = nk_rgb_factor(cursor_text_color, style->color_factor);
556 if (edit->select_start == edit->select_end) {
558 const char *begin = nk_str_get_const(&edit->string);
559 int l = nk_str_len_char(&edit->string);
560 nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
561 area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
562 background_color, text_color, nk_false);
565 if (edit->select_start != edit->select_end && selection_begin > 0){
567 const char *begin = nk_str_get_const(&edit->string);
568 NK_ASSERT(select_begin_ptr);
569 nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
570 area.y - edit->scrollbar.y, 0, begin, (
int)(select_begin_ptr - begin),
571 row_height, font, background_color, text_color, nk_false);
573 if (edit->select_start != edit->select_end) {
575 NK_ASSERT(select_begin_ptr);
576 if (!select_end_ptr) {
577 const char *begin = nk_str_get_const(&edit->string);
578 select_end_ptr = begin + nk_str_len_char(&edit->string);
580 nk_edit_draw_text(out, style,
581 area.x - edit->scrollbar.x,
582 area.y + selection_offset_start.y - edit->scrollbar.y,
583 selection_offset_start.x,
584 select_begin_ptr, (
int)(select_end_ptr - select_begin_ptr),
585 row_height, font, sel_background_color, sel_text_color, nk_true);
587 if ((edit->select_start != edit->select_end &&
588 selection_end < edit->
string.len))
591 const char *begin = select_end_ptr;
592 const char *end = nk_str_get_const(&edit->string) +
593 nk_str_len_char(&edit->string);
594 NK_ASSERT(select_end_ptr);
595 nk_edit_draw_text(out, style,
596 area.x - edit->scrollbar.x,
597 area.y + selection_offset_end.y - edit->scrollbar.y,
598 selection_offset_end.x,
599 begin, (
int)(end - begin), row_height, font,
600 background_color, text_color, nk_true);
605 if (edit->select_start == edit->select_end)
607 if (edit->cursor >= nk_str_len(&edit->string) ||
608 (cursor_ptr && *cursor_ptr ==
'\n')) {
611 cursor.w = style->cursor_size;
613 cursor.x = area.x + cursor_pos.x - edit->scrollbar.x;
614 cursor.y = area.y + cursor_pos.y + row_height/2.0f - cursor.h/2.0f;
615 cursor.y -= edit->scrollbar.y;
624 NK_ASSERT(cursor_ptr);
625 glyph_len = nk_utf_decode(cursor_ptr, &unicode, 4);
627 label.x = area.x + cursor_pos.x - edit->scrollbar.x;
628 label.y = area.y + cursor_pos.y - edit->scrollbar.y;
629 label.w = font->
width(font->userdata, font->
height, cursor_ptr, glyph_len);
630 label.h = row_height;
633 txt.background = cursor_color;;
634 txt.text = cursor_text_color;
636 nk_widget_text(out, label, cursor_ptr, glyph_len, &txt, NK_TEXT_LEFT, font);
641 int l = nk_str_len_char(&edit->string);
642 const char *begin = nk_str_get_const(&edit->string);
647 nk_push_scissor(out, clip);
649 background = &style->active;
650 text_color = style->text_active;
652 background = &style->hover;
653 text_color = style->text_hover;
655 background = &style->normal;
656 text_color = style->text_normal;
658 if (background->type == NK_STYLE_ITEM_IMAGE)
659 background_color = nk_rgba(0,0,0,0);
661 background_color = background->data.color;
663 background_color = nk_rgb_factor(background_color, style->color_factor);
664 text_color = nk_rgb_factor(text_color, style->color_factor);
666 nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
667 area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
668 background_color, text_color, nk_false);
670 nk_push_scissor(out, old_clip);}
674 nk_edit_focus(
struct nk_context *ctx, nk_flags flags)
680 NK_ASSERT(ctx->current);
681 if (!ctx || !ctx->current)
return;
684 hash = win->edit.seq;
685 win->edit.active = nk_true;
686 win->edit.name = hash;
687 if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
688 win->edit.mode = NK_TEXT_EDIT_MODE_INSERT;
695 NK_ASSERT(ctx->current);
696 if (!ctx || !ctx->current)
return;
699 win->edit.active = nk_false;
703 nk_edit_string(
struct nk_context *ctx, nk_flags flags,
704 char *memory,
int *len,
int max, nk_plugin_filter filter)
714 if (!ctx || !memory || !len)
719 hash = win->edit.seq;
721 nk_textedit_clear_state(&ctx->
text_edit, (flags & NK_EDIT_MULTILINE)?
722 NK_TEXT_EDIT_MULTI_LINE: NK_TEXT_EDIT_SINGLE_LINE, filter);
724 if (win->edit.active && hash == win->edit.name) {
725 if (flags & NK_EDIT_NO_CURSOR)
726 edit->cursor = nk_utf_len(memory, *len);
727 else edit->cursor = win->edit.cursor;
728 if (!(flags & NK_EDIT_SELECTABLE)) {
729 edit->select_start = win->edit.cursor;
730 edit->select_end = win->edit.cursor;
732 edit->select_start = win->edit.sel_start;
733 edit->select_end = win->edit.sel_end;
735 edit->mode = win->edit.mode;
736 edit->scrollbar.x = (float)win->edit.scrollbar.x;
737 edit->scrollbar.y = (
float)win->edit.scrollbar.y;
738 edit->active = nk_true;
739 }
else edit->active = nk_false;
741 max = NK_MAX(1, max);
742 *len = NK_MIN(*len, max-1);
743 nk_str_init_fixed(&edit->string, memory, (nk_size)max);
744 edit->string.buffer.
allocated = (nk_size)*len;
745 edit->string.len = nk_utf_len(memory, *len);
746 state = nk_edit_buffer(ctx, flags, edit, filter);
747 *len = (int)edit->string.buffer.
allocated;
750 win->edit.cursor = edit->cursor;
751 win->edit.sel_start = edit->select_start;
752 win->edit.sel_end = edit->select_end;
753 win->edit.mode = edit->mode;
754 win->edit.scrollbar.x = (nk_uint)edit->scrollbar.x;
755 win->edit.scrollbar.y = (nk_uint)edit->scrollbar.y;
759 nk_edit_buffer(
struct nk_context *ctx, nk_flags flags,
769 nk_flags ret_flags = 0;
770 unsigned char prev_state;
776 NK_ASSERT(ctx->current);
777 NK_ASSERT(ctx->current->layout);
778 if (!ctx || !ctx->current || !ctx->current->layout)
783 state = nk_widget(&bounds, ctx);
784 if (!state)
return state;
786 flags |= NK_EDIT_READ_ONLY;
790 hash = win->edit.seq++;
791 if (win->edit.active && hash == win->edit.name) {
792 if (flags & NK_EDIT_NO_CURSOR)
793 edit->cursor = edit->string.len;
794 if (!(flags & NK_EDIT_SELECTABLE)) {
795 edit->select_start = edit->cursor;
796 edit->select_end = edit->cursor;
798 if (flags & NK_EDIT_CLIPBOARD)
799 edit->clip = ctx->clip;
800 edit->active = (
unsigned char)win->edit.active;
801 }
else edit->active = nk_false;
802 edit->mode = win->edit.mode;
805 prev_state = (
unsigned char)edit->active;
806 in = (flags & NK_EDIT_READ_ONLY) ? 0: in;
807 ret_flags = nk_do_edit(&ctx->last_widget_state, &win->buffer, bounds, flags,
808 filter, edit, &style->edit, in, style->font);
811 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_TEXT];
812 if (edit->active && prev_state != edit->active) {
814 win->edit.active = nk_true;
815 win->edit.name = hash;
816 }
else if (prev_state && !edit->active) {
818 win->edit.active = nk_false;
822 nk_edit_string_zero_terminated(
struct nk_context *ctx, nk_flags flags,
823 char *buffer,
int max, nk_plugin_filter filter)
826 int len = nk_strlen(buffer);
827 result = nk_edit_string(ctx, flags, buffer, &len, max, filter);
828 buffer[NK_MIN(NK_MAX(max-1,0), len)] =
'\0';
main API and documentation file
@ NK_WINDOW_ROM
sets window widgets into a read only mode and does not allow input changes
NK_API void nk_draw_image(struct nk_command_buffer *, struct nk_rect, const struct nk_image *, struct nk_color)
misc
NK_API void nk_fill_rect(struct nk_command_buffer *, struct nk_rect, float rounding, struct nk_color)
filled shades
NK_API nk_bool nk_filter_default(const struct nk_text_edit *, nk_rune unicode)
filter function
@ NK_WIDGET_STATE_ACTIVED
!< widget is being hovered
@ NK_WIDGET_STATE_HOVER
!< widget has been hovered on the current frame
@ NK_WIDGET_STATE_ACTIVE
!< widget is being hovered
@ NK_WIDGET_STATE_HOVERED
!< widget is from this frame on not hovered anymore
@ NK_WIDGET_DISABLED
The widget is manually disabled and acts like NK_WIDGET_ROM.
@ NK_EDIT_INACTIVE
!< edit widget is currently being modified
@ NK_EDIT_DEACTIVATED
!< edit widget went from state inactive to state active
@ NK_EDIT_COMMITED
!< edit widget went from state active to state inactive
@ NK_EDIT_ACTIVATED
!< edit widget is not active and is not being modified
nk_size allocated
!< growing factor for dynamic memory management
struct nk_text_edit text_edit
text editor objects are quite big because of an internal undo/redo stack.
nk_text_width_f width
!< max height of the font
float height
!< user provided font handle