PumpkinBrush
nuklear.h
Go to the documentation of this file.
1 /*
215 */
216 #ifndef NK_SINGLE_FILE
217  #define NK_SINGLE_FILE
218 #endif
219 
220 #ifndef NK_NUKLEAR_H_
221 #define NK_NUKLEAR_H_
222 
223 #ifdef __cplusplus
224 extern "C" {
225 #endif
226 /*
227  * ==============================================================
228  *
229  * CONSTANTS
230  *
231  * ===============================================================
232  */
233 #define NK_UNDEFINED (-1.0f)
234 #define NK_UTF_INVALID 0xFFFD /* internal invalid utf8 rune */
235 #define NK_UTF_SIZE 4 /* describes the number of bytes a glyph consists of*/
236 #ifndef NK_INPUT_MAX
237  #define NK_INPUT_MAX 16
238 #endif
239 #ifndef NK_MAX_NUMBER_BUFFER
240  #define NK_MAX_NUMBER_BUFFER 64
241 #endif
242 #ifndef NK_SCROLLBAR_HIDING_TIMEOUT
243  #define NK_SCROLLBAR_HIDING_TIMEOUT 4.0f
244 #endif
245 /*
246  * ==============================================================
247  *
248  * HELPER
249  *
250  * ===============================================================
251  */
252 #ifndef NK_API
253  #ifdef NK_PRIVATE
254  #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199409L))
255  #define NK_API static inline
256  #elif defined(__cplusplus)
257  #define NK_API static inline
258  #else
259  #define NK_API static
260  #endif
261  #else
262  #define NK_API extern
263  #endif
264 #endif
265 #ifndef NK_LIB
266  #ifdef NK_SINGLE_FILE
267  #define NK_LIB static
268  #else
269  #define NK_LIB extern
270  #endif
271 #endif
272 
273 #define NK_INTERN static
274 #define NK_STORAGE static
275 #define NK_GLOBAL static
276 
277 #define NK_FLAG(x) (1 << (x))
278 #define NK_STRINGIFY(x) #x
279 #define NK_MACRO_STRINGIFY(x) NK_STRINGIFY(x)
280 #define NK_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2
281 #define NK_STRING_JOIN_DELAY(arg1, arg2) NK_STRING_JOIN_IMMEDIATE(arg1, arg2)
282 #define NK_STRING_JOIN(arg1, arg2) NK_STRING_JOIN_DELAY(arg1, arg2)
283 
284 #ifdef _MSC_VER
285  #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__COUNTER__)
286 #else
287  #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__LINE__)
288 #endif
289 
290 #ifndef NK_STATIC_ASSERT
291  #define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1]
292 #endif
293 
294 #ifndef NK_FILE_LINE
295 #ifdef _MSC_VER
296  #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__COUNTER__)
297 #else
298  #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__LINE__)
299 #endif
300 #endif
301 
302 #define NK_MIN(a,b) ((a) < (b) ? (a) : (b))
303 #define NK_MAX(a,b) ((a) < (b) ? (b) : (a))
304 #define NK_CLAMP(i,v,x) (NK_MAX(NK_MIN(v,x), i))
305 
306 #ifdef NK_INCLUDE_STANDARD_VARARGS
307  #if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */
308  #include <sal.h>
309  #define NK_PRINTF_FORMAT_STRING _Printf_format_string_
310  #else
311  #define NK_PRINTF_FORMAT_STRING
312  #endif
313  #if defined(__GNUC__)
314  #define NK_PRINTF_VARARG_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, fmtargnumber+1)))
315  #define NK_PRINTF_VALIST_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, 0)))
316  #else
317  #define NK_PRINTF_VARARG_FUNC(fmtargnumber)
318  #define NK_PRINTF_VALIST_FUNC(fmtargnumber)
319  #endif
320 #endif
321 
322 /*
323  * ===============================================================
324  *
325  * BASIC
326  *
327  * ===============================================================
328  */
329 #ifdef NK_INCLUDE_FIXED_TYPES
330  #include <stdint.h>
331  #define NK_INT8 int8_t
332  #define NK_UINT8 uint8_t
333  #define NK_INT16 int16_t
334  #define NK_UINT16 uint16_t
335  #define NK_INT32 int32_t
336  #define NK_UINT32 uint32_t
337  #define NK_SIZE_TYPE uintptr_t
338  #define NK_POINTER_TYPE uintptr_t
339 #else
340  #ifndef NK_INT8
341  #define NK_INT8 signed char
342  #endif
343  #ifndef NK_UINT8
344  #define NK_UINT8 unsigned char
345  #endif
346  #ifndef NK_INT16
347  #define NK_INT16 signed short
348  #endif
349  #ifndef NK_UINT16
350  #define NK_UINT16 unsigned short
351  #endif
352  #ifndef NK_INT32
353  #if defined(_MSC_VER)
354  #define NK_INT32 __int32
355  #else
356  #define NK_INT32 signed int
357  #endif
358  #endif
359  #ifndef NK_UINT32
360  #if defined(_MSC_VER)
361  #define NK_UINT32 unsigned __int32
362  #else
363  #define NK_UINT32 unsigned int
364  #endif
365  #endif
366  #ifndef NK_SIZE_TYPE
367  #if defined(_WIN64) && defined(_MSC_VER)
368  #define NK_SIZE_TYPE unsigned __int64
369  #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
370  #define NK_SIZE_TYPE unsigned __int32
371  #elif defined(__GNUC__) || defined(__clang__)
372  #if defined(__x86_64__) || defined(__ppc64__)
373  #define NK_SIZE_TYPE unsigned long
374  #else
375  #define NK_SIZE_TYPE unsigned int
376  #endif
377  #else
378  #define NK_SIZE_TYPE unsigned long
379  #endif
380  #endif
381  #ifndef NK_POINTER_TYPE
382  #if defined(_WIN64) && defined(_MSC_VER)
383  #define NK_POINTER_TYPE unsigned __int64
384  #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
385  #define NK_POINTER_TYPE unsigned __int32
386  #elif defined(__GNUC__) || defined(__clang__)
387  #if defined(__x86_64__) || defined(__ppc64__)
388  #define NK_POINTER_TYPE unsigned long
389  #else
390  #define NK_POINTER_TYPE unsigned int
391  #endif
392  #else
393  #define NK_POINTER_TYPE unsigned long
394  #endif
395  #endif
396 #endif
397 
398 typedef NK_INT8 nk_char;
403 typedef NK_INT32 nk_int;
407 
408 typedef nk_uint nk_hash;
410 typedef nk_uint nk_rune;
411 
412 /* Make sure correct type size:
413  * This will fire with a negative subscript error if the type sizes
414  * are set incorrectly by the compiler, and compile out if not */
415 NK_STATIC_ASSERT(sizeof(nk_short) == 2);
416 NK_STATIC_ASSERT(sizeof(nk_ushort) == 2);
417 NK_STATIC_ASSERT(sizeof(nk_uint) == 4);
418 NK_STATIC_ASSERT(sizeof(nk_int) == 4);
419 NK_STATIC_ASSERT(sizeof(nk_byte) == 1);
420 NK_STATIC_ASSERT(sizeof(nk_flags) >= 4);
421 NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
422 NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
423 NK_STATIC_ASSERT(sizeof(nk_ptr) >= sizeof(void*));
424 
425 /* ============================================================================
426  *
427  * API
428  *
429  * =========================================================================== */
430 struct nk_buffer;
431 struct nk_allocator;
432 struct nk_command_buffer;
433 struct nk_draw_command;
434 struct nk_convert_config;
435 struct nk_style_item;
436 struct nk_text_edit;
437 struct nk_draw_list;
438 struct nk_user_font;
439 struct nk_panel;
440 struct nk_context;
441 struct nk_draw_vertex_layout_element;
442 struct nk_style_button;
443 struct nk_style_toggle;
444 struct nk_style_selectable;
445 struct nk_style_slide;
446 struct nk_style_progress;
447 struct nk_style_scrollbar;
448 struct nk_style_edit;
449 struct nk_style_property;
450 struct nk_style_chart;
451 struct nk_style_combo;
452 struct nk_style_tab;
454 struct nk_style_window;
455 
457 struct nk_color {nk_byte r,g,b,a;};
458 struct nk_colorf {float r,g,b,a;};
459 struct nk_vec2 {float x,y;};
460 struct nk_vec2i {short x, y;};
461 struct nk_rect {float x,y,w,h;};
462 struct nk_recti {short x,y,w,h;};
463 typedef char nk_glyph[NK_UTF_SIZE];
464 typedef union {void *ptr; int id;} nk_handle;
465 struct nk_image {nk_handle handle;unsigned short w,h;unsigned short region[4];};
466 struct nk_cursor {struct nk_image img; struct nk_vec2 size, offset;};
467 struct nk_scroll {nk_uint x, y;};
468 
481 
482 typedef void*(*nk_plugin_alloc)(nk_handle, void *old, nk_size);
483 typedef void (*nk_plugin_free)(nk_handle, void *old);
484 typedef int(*nk_plugin_filter)(const struct nk_text_edit*, nk_rune unicode);
485 typedef void(*nk_plugin_paste)(nk_handle, struct nk_text_edit*);
486 typedef void(*nk_plugin_copy)(nk_handle, const char*, int len);
487 
488 struct nk_allocator {
492 };
508 };
509 /* =============================================================================
510  *
511  * CONTEXT
512  *
513  * =============================================================================*/
514 /*/// ### Context
546  */
547 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
548 /*/// #### nk_init_default
563 */
564 NK_API int nk_init_default(struct nk_context*, const struct nk_user_font*);
565 #endif
566 /*/// #### nk_init_fixed
588 */
589 NK_API int nk_init_fixed(struct nk_context*, void *memory, nk_size size, const struct nk_user_font*);
590 /*/// #### nk_init
606 */
607 NK_API int nk_init(struct nk_context*, struct nk_allocator*, const struct nk_user_font*);
608 /*/// #### nk_init_custom
625 */
626 NK_API int nk_init_custom(struct nk_context*, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font*);
627 /*/// #### nk_clear
639 */
640 NK_API void nk_clear(struct nk_context*);
641 /*/// #### nk_free
652 */
653 NK_API void nk_free(struct nk_context*);
654 #ifdef NK_INCLUDE_COMMAND_USERDATA
655 /*/// #### nk_set_user_data
666 */
667 NK_API void nk_set_user_data(struct nk_context*, nk_handle handle);
668 #endif
669 /* =============================================================================
670  *
671  * INPUT
672  *
673  * =============================================================================*/
674 /*/// ### Input
734 */
735 enum nk_keys {
750  /* Shortcuts: text field */
763  /* Shortcuts: scrollbar */
769 };
776 };
777 /*/// #### nk_input_begin
788 */
789 NK_API void nk_input_begin(struct nk_context*);
790 /*/// #### nk_input_motion
802 */
803 NK_API void nk_input_motion(struct nk_context*, int x, int y);
804 /*/// #### nk_input_key
816 */
817 NK_API void nk_input_key(struct nk_context*, enum nk_keys, int down);
818 /*/// #### nk_input_button
832 */
833 NK_API void nk_input_button(struct nk_context*, enum nk_buttons, int x, int y, int down);
834 /*/// #### nk_input_scroll
847 */
848 NK_API void nk_input_scroll(struct nk_context*, struct nk_vec2 val);
849 /*/// #### nk_input_char
865 */
866 NK_API void nk_input_char(struct nk_context*, char);
867 /*/// #### nk_input_glyph
882 */
883 NK_API void nk_input_glyph(struct nk_context*, const nk_glyph);
884 /*/// #### nk_input_unicode
898 */
900 /*/// #### nk_input_end
911 */
912 NK_API void nk_input_end(struct nk_context*);
913 /* =============================================================================
914  *
915  * DRAWING
916  *
917  * =============================================================================*/
918 /*/// ### Drawing
1141 */
1149 };
1151  nk_handle texture; /* texture handle to a texture with a white pixel */
1152  struct nk_vec2 uv; /* coordinates to a white pixel in the texture */
1153 };
1155  float global_alpha; /* global alpha value */
1156  enum nk_anti_aliasing line_AA; /* line anti-aliasing flag can be turned off if you are tight on memory */
1157  enum nk_anti_aliasing shape_AA; /* shape anti-aliasing flag can be turned off if you are tight on memory */
1158  unsigned circle_segment_count; /* number of segments used for circles: default to 22 */
1159  unsigned arc_segment_count; /* number of segments used for arcs: default to 22 */
1160  unsigned curve_segment_count; /* number of segments used for curves: default to 22 */
1161  struct nk_draw_null_texture null; /* handle to texture with a white pixel for shape drawing */
1162  const struct nk_draw_vertex_layout_element *vertex_layout; /* describes the vertex output format and packing */
1163  nk_size vertex_size; /* sizeof one vertex for vertex packing */
1164  nk_size vertex_alignment; /* vertex alignment: Can be obtained by NK_ALIGNOF */
1165 };
1166 /*/// #### nk__begin
1179 */
1180 NK_API const struct nk_command* nk__begin(struct nk_context*);
1181 /*/// #### nk__next
1194 */
1195 NK_API const struct nk_command* nk__next(struct nk_context*, const struct nk_command*);
1196 /*/// #### nk_foreach
1209 */
1210 #define nk_foreach(c, ctx) for((c) = nk__begin(ctx); (c) != 0; (c) = nk__next(ctx,c))
1211 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
1212 /*/// #### nk_convert
1240 */
1241 NK_API nk_flags nk_convert(struct nk_context*, struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements, const struct nk_convert_config*);
1242 /*/// #### nk__draw_begin
1255 */
1256 NK_API const struct nk_draw_command* nk__draw_begin(const struct nk_context*, const struct nk_buffer*);
1257 /*/// #### nk__draw_end
1270 */
1271 NK_API const struct nk_draw_command* nk__draw_end(const struct nk_context*, const struct nk_buffer*);
1272 /*/// #### nk__draw_next
1286 */
1287 NK_API const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*, const struct nk_buffer*, const struct nk_context*);
1288 /*/// #### nk_draw_foreach
1300 */
1301 #define nk_draw_foreach(cmd,ctx, b) for((cmd)=nk__draw_begin(ctx, b); (cmd)!=0; (cmd)=nk__draw_next(cmd, b, ctx))
1302 #endif
1303 /* =============================================================================
1304  *
1305  * WINDOW
1306  *
1307  * =============================================================================
1392 //
1414 //
1420 //
1426 */
1427 /*
1449 */
1462 };
1463 /*/// #### nk_begin
1480 */
1481 NK_API int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags);
1482 /*/// #### nk_begin_titled
1500 */
1501 NK_API int nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags);
1502 /*/// #### nk_end
1513 */
1514 NK_API void nk_end(struct nk_context *ctx);
1515 /*/// #### nk_window_find
1529 */
1530 NK_API struct nk_window *nk_window_find(struct nk_context *ctx, const char *name);
1531 /*/// #### nk_window_get_bounds
1545 */
1546 NK_API struct nk_rect nk_window_get_bounds(const struct nk_context *ctx);
1547 /*/// #### nk_window_get_position
1561 */
1562 NK_API struct nk_vec2 nk_window_get_position(const struct nk_context *ctx);
1563 /*/// #### nk_window_get_size
1577 */
1578 NK_API struct nk_vec2 nk_window_get_size(const struct nk_context*);
1579 /*/// #### nk_window_get_width
1593 */
1594 NK_API float nk_window_get_width(const struct nk_context*);
1595 /*/// #### nk_window_get_height
1609 */
1610 NK_API float nk_window_get_height(const struct nk_context*);
1611 /*/// #### nk_window_get_panel
1627 */
1629 /*/// #### nk_window_get_content_region
1646 */
1648 /*/// #### nk_window_get_content_region_min
1665 */
1667 /*/// #### nk_window_get_content_region_max
1684 */
1686 /*/// #### nk_window_get_content_region_size
1702 */
1704 /*/// #### nk_window_get_canvas
1721 */
1723 /*/// #### nk_window_get_scroll
1737 */
1738 NK_API void nk_window_get_scroll(struct nk_context*, nk_uint *offset_x, nk_uint *offset_y);
1739 /*/// #### nk_window_has_focus
1752 */
1753 NK_API int nk_window_has_focus(const struct nk_context*);
1754 /*/// #### nk_window_is_hovered
1767 */
1769 /*/// #### nk_window_is_collapsed
1782 */
1783 NK_API int nk_window_is_collapsed(struct nk_context *ctx, const char *name);
1784 /*/// #### nk_window_is_closed
1796 */
1797 NK_API int nk_window_is_closed(struct nk_context*, const char*);
1798 /*/// #### nk_window_is_hidden
1810 */
1811 NK_API int nk_window_is_hidden(struct nk_context*, const char*);
1812 /*/// #### nk_window_is_active
1824 */
1825 NK_API int nk_window_is_active(struct nk_context*, const char*);
1826 /*/// #### nk_window_is_any_hovered
1837 */
1839 /*/// #### nk_item_is_any_active
1852 */
1854 /*/// #### nk_window_set_bounds
1865 */
1866 NK_API void nk_window_set_bounds(struct nk_context*, const char *name, struct nk_rect bounds);
1867 /*/// #### nk_window_set_position
1878 */
1879 NK_API void nk_window_set_position(struct nk_context*, const char *name, struct nk_vec2 pos);
1880 /*/// #### nk_window_set_size
1891 */
1892 NK_API void nk_window_set_size(struct nk_context*, const char *name, struct nk_vec2);
1893 /*/// #### nk_window_set_focus
1903 */
1904 NK_API void nk_window_set_focus(struct nk_context*, const char *name);
1905 /*/// #### nk_window_set_scroll
1919 */
1920 NK_API void nk_window_set_scroll(struct nk_context*, nk_uint offset_x, nk_uint offset_y);
1921 /*/// #### nk_window_close
1931 */
1932 NK_API void nk_window_close(struct nk_context *ctx, const char *name);
1933 /*/// #### nk_window_collapse
1944 */
1945 NK_API void nk_window_collapse(struct nk_context*, const char *name, enum nk_collapse_states state);
1946 /*/// #### nk_window_collapse_if
1958 */
1959 NK_API void nk_window_collapse_if(struct nk_context*, const char *name, enum nk_collapse_states, int cond);
1960 /*/// #### nk_window_show
1971 */
1972 NK_API void nk_window_show(struct nk_context*, const char *name, enum nk_show_states);
1973 /*/// #### nk_window_show_if
1985 */
1986 NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show_states, int cond);
1987 /* =============================================================================
1988  *
1989  * LAYOUT
1990  *
1991  * =============================================================================
2236 //
2243 //
2249 //
2253 //
2259 */
2260 /*/// #### nk_layout_set_min_row_height
2274 */
2275 NK_API void nk_layout_set_min_row_height(struct nk_context*, float height);
2276 /*/// #### nk_layout_reset_min_row_height
2285 */
2287 /*/// #### nk_layout_widget_bounds
2298 */
2300 /*/// #### nk_layout_ratio_from_pixel
2312 */
2313 NK_API float nk_layout_ratio_from_pixel(struct nk_context*, float pixel_width);
2314 /*/// #### nk_layout_row_dynamic
2327 */
2328 NK_API void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols);
2329 /*/// #### nk_layout_row_static
2343 */
2344 NK_API void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols);
2345 /*/// #### nk_layout_row_begin
2357 */
2358 NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols);
2359 /*/// #### nk_layout_row_push
2369 */
2370 NK_API void nk_layout_row_push(struct nk_context*, float value);
2371 /*/// #### nk_layout_row_end
2380 */
2381 NK_API void nk_layout_row_end(struct nk_context*);
2382 /*/// #### nk_layout_row
2394 */
2395 NK_API void nk_layout_row(struct nk_context*, enum nk_layout_format, float height, int cols, const float *ratio);
2396 /*/// #### nk_layout_row_template_begin
2406 */
2407 NK_API void nk_layout_row_template_begin(struct nk_context*, float row_height);
2408 /*/// #### nk_layout_row_template_push_dynamic
2418 */
2420 /*/// #### nk_layout_row_template_push_variable
2430 */
2431 NK_API void nk_layout_row_template_push_variable(struct nk_context*, float min_width);
2432 /*/// #### nk_layout_row_template_push_static
2442 */
2443 NK_API void nk_layout_row_template_push_static(struct nk_context*, float width);
2444 /*/// #### nk_layout_row_template_end
2453 */
2455 /*/// #### nk_layout_space_begin
2467 */
2468 NK_API void nk_layout_space_begin(struct nk_context*, enum nk_layout_format, float height, int widget_count);
2469 /*/// #### nk_layout_space_push
2479 */
2480 NK_API void nk_layout_space_push(struct nk_context*, struct nk_rect bounds);
2481 /*/// #### nk_layout_space_end
2490 */
2491 NK_API void nk_layout_space_end(struct nk_context*);
2492 /*/// #### nk_layout_space_bounds
2503 */
2505 /*/// #### nk_layout_space_to_screen
2517 */
2519 /*/// #### nk_layout_space_to_local
2531 */
2532 NK_API struct nk_vec2 nk_layout_space_to_local(struct nk_context*, struct nk_vec2);
2533 /*/// #### nk_layout_space_rect_to_screen
2545 */
2547 /*/// #### nk_layout_space_rect_to_local
2559 */
2561 /* =============================================================================
2562  *
2563  * GROUP
2564  *
2565  * =============================================================================
2648 */
2649 /*/// #### nk_group_begin
2662 */
2663 NK_API int nk_group_begin(struct nk_context*, const char *title, nk_flags);
2664 /*/// #### nk_group_begin_titled
2678 */
2679 NK_API int nk_group_begin_titled(struct nk_context*, const char *name, const char *title, nk_flags);
2680 /*/// #### nk_group_end
2689 */
2690 NK_API void nk_group_end(struct nk_context*);
2691 /*/// #### nk_group_scrolled_offset_begin
2707 */
2708 NK_API int nk_group_scrolled_offset_begin(struct nk_context*, nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags);
2709 /*/// #### nk_group_scrolled_begin
2724 */
2725 NK_API int nk_group_scrolled_begin(struct nk_context*, struct nk_scroll *off, const char *title, nk_flags);
2726 /*/// #### nk_group_scrolled_end
2735 */
2737 /*/// #### nk_group_get_scroll
2749 */
2750 NK_API void nk_group_get_scroll(struct nk_context*, const char *id, nk_uint *x_offset, nk_uint *y_offset);
2751 /*/// #### nk_group_set_scroll
2763 */
2764 NK_API void nk_group_set_scroll(struct nk_context*, const char *id, nk_uint x_offset, nk_uint y_offset);
2765 /* =============================================================================
2766  *
2767  * TREE
2768  *
2769  * =============================================================================
2824 //
2834 */
2835 /*/// #### nk_tree_push
2855 */
2856 #define nk_tree_push(ctx, type, title, state) nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
2857 /*/// #### nk_tree_push_id
2872 */
2873 #define nk_tree_push_id(ctx, type, title, state, id) nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
2874 /*/// #### nk_tree_push_hashed
2892 */
2893 NK_API int nk_tree_push_hashed(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, const char *hash, int len,int seed);
2894 /*/// #### nk_tree_image_push
2905 //
2915 */
2916 #define nk_tree_image_push(ctx, type, img, title, state) nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
2917 /*/// #### nk_tree_image_push_id
2935 */
2936 #define nk_tree_image_push_id(ctx, type, img, title, state, id) nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
2937 /*/// #### nk_tree_image_push_hashed
2956 */
2957 NK_API int nk_tree_image_push_hashed(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, const char *hash, int len,int seed);
2958 /*/// #### nk_tree_pop
2967 */
2968 NK_API void nk_tree_pop(struct nk_context*);
2969 /*/// #### nk_tree_state_push
2983 */
2984 NK_API int nk_tree_state_push(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states *state);
2985 /*/// #### nk_tree_state_image_push
3000 */
3001 NK_API int nk_tree_state_image_push(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states *state);
3002 /*/// #### nk_tree_state_pop
3011 */
3012 NK_API void nk_tree_state_pop(struct nk_context*);
3013 
3014 #define nk_tree_element_push(ctx, type, title, state, sel) nk_tree_element_push_hashed(ctx, type, title, state, sel, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
3015 #define nk_tree_element_push_id(ctx, type, title, state, sel, id) nk_tree_element_push_hashed(ctx, type, title, state, sel, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
3016 NK_API int nk_tree_element_push_hashed(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, int *selected, const char *hash, int len, int seed);
3017 NK_API int nk_tree_element_image_push_hashed(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, int *selected, const char *hash, int len,int seed);
3018 NK_API void nk_tree_element_pop(struct nk_context*);
3019 
3020 /* =============================================================================
3021  *
3022  * LIST VIEW
3023  *
3024  * ============================================================================= */
3026 /* public: */
3027  int begin, end, count;
3028 /* private: */
3030  struct nk_context *ctx;
3033 };
3034 NK_API int nk_list_view_begin(struct nk_context*, struct nk_list_view *out, const char *id, nk_flags, int row_height, int row_count);
3035 NK_API void nk_list_view_end(struct nk_list_view*);
3036 /* =============================================================================
3037  *
3038  * WIDGET
3039  *
3040  * ============================================================================= */
3042  NK_WIDGET_INVALID, /* The widget cannot be seen and is completely out of view */
3043  NK_WIDGET_VALID, /* The widget is completely inside the window and can be updated and drawn */
3044  NK_WIDGET_ROM /* The widget is partially visible and cannot be updated */
3045 };
3048  NK_WIDGET_STATE_INACTIVE = NK_FLAG(2), /* widget is neither active nor hovered */
3049  NK_WIDGET_STATE_ENTERED = NK_FLAG(3), /* widget has been hovered on the current frame */
3050  NK_WIDGET_STATE_HOVER = NK_FLAG(4), /* widget is being hovered */
3051  NK_WIDGET_STATE_ACTIVED = NK_FLAG(5),/* widget is currently activated */
3052  NK_WIDGET_STATE_LEFT = NK_FLAG(6), /* widget is from this frame on not hovered anymore */
3055 };
3056 NK_API enum nk_widget_layout_states nk_widget(struct nk_rect*, const struct nk_context*);
3058 NK_API struct nk_rect nk_widget_bounds(struct nk_context*);
3060 NK_API struct nk_vec2 nk_widget_size(struct nk_context*);
3061 NK_API float nk_widget_width(struct nk_context*);
3062 NK_API float nk_widget_height(struct nk_context*);
3065 NK_API int nk_widget_has_mouse_click_down(struct nk_context*, enum nk_buttons, int down);
3066 NK_API void nk_spacing(struct nk_context*, int cols);
3067 /* =============================================================================
3068  *
3069  * TEXT
3070  *
3071  * ============================================================================= */
3079 };
3084 };
3085 NK_API void nk_text(struct nk_context*, const char*, int, nk_flags);
3086 NK_API void nk_text_colored(struct nk_context*, const char*, int, nk_flags, struct nk_color);
3087 NK_API void nk_text_wrap(struct nk_context*, const char*, int);
3088 NK_API void nk_text_wrap_colored(struct nk_context*, const char*, int, struct nk_color);
3089 NK_API void nk_label(struct nk_context*, const char*, nk_flags align);
3090 NK_API void nk_label_colored(struct nk_context*, const char*, nk_flags align, struct nk_color);
3091 NK_API void nk_label_wrap(struct nk_context*, const char*);
3092 NK_API void nk_label_colored_wrap(struct nk_context*, const char*, struct nk_color);
3093 NK_API void nk_image(struct nk_context*, struct nk_image);
3094 NK_API void nk_image_color(struct nk_context*, struct nk_image, struct nk_color);
3095 #ifdef NK_INCLUDE_STANDARD_VARARGS
3096 NK_API void nk_labelf(struct nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(3);
3097 NK_API void nk_labelf_colored(struct nk_context*, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(4);
3098 NK_API void nk_labelf_wrap(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(2);
3099 NK_API void nk_labelf_colored_wrap(struct nk_context*, struct nk_color, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(3);
3100 NK_API void nk_labelfv(struct nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(3);
3101 NK_API void nk_labelfv_colored(struct nk_context*, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(4);
3102 NK_API void nk_labelfv_wrap(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3103 NK_API void nk_labelfv_colored_wrap(struct nk_context*, struct nk_color, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(3);
3104 NK_API void nk_value_bool(struct nk_context*, const char *prefix, int);
3105 NK_API void nk_value_int(struct nk_context*, const char *prefix, int);
3106 NK_API void nk_value_uint(struct nk_context*, const char *prefix, unsigned int);
3107 NK_API void nk_value_float(struct nk_context*, const char *prefix, float);
3108 NK_API void nk_value_color_byte(struct nk_context*, const char *prefix, struct nk_color);
3109 NK_API void nk_value_color_float(struct nk_context*, const char *prefix, struct nk_color);
3110 NK_API void nk_value_color_hex(struct nk_context*, const char *prefix, struct nk_color);
3111 #endif
3112 /* =============================================================================
3113  *
3114  * BUTTON
3115  *
3116  * ============================================================================= */
3117 NK_API int nk_button_text(struct nk_context*, const char *title, int len);
3118 NK_API int nk_button_label(struct nk_context*, const char *title);
3119 NK_API int nk_button_color(struct nk_context*, struct nk_color);
3121 NK_API int nk_button_image(struct nk_context*, struct nk_image img);
3122 NK_API int nk_button_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags text_alignment);
3123 NK_API int nk_button_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3124 NK_API int nk_button_image_label(struct nk_context*, struct nk_image img, const char*, nk_flags text_alignment);
3125 NK_API int nk_button_image_text(struct nk_context*, struct nk_image img, const char*, int, nk_flags alignment);
3126 NK_API int nk_button_text_styled(struct nk_context*, const struct nk_style_button*, const char *title, int len);
3127 NK_API int nk_button_label_styled(struct nk_context*, const struct nk_style_button*, const char *title);
3128 NK_API int nk_button_symbol_styled(struct nk_context*, const struct nk_style_button*, enum nk_symbol_type);
3129 NK_API int nk_button_image_styled(struct nk_context*, const struct nk_style_button*, struct nk_image img);
3130 NK_API int nk_button_symbol_text_styled(struct nk_context*,const struct nk_style_button*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3131 NK_API int nk_button_symbol_label_styled(struct nk_context *ctx, const struct nk_style_button *style, enum nk_symbol_type symbol, const char *title, nk_flags align);
3132 NK_API int nk_button_image_label_styled(struct nk_context*,const struct nk_style_button*, struct nk_image img, const char*, nk_flags text_alignment);
3133 NK_API int nk_button_image_text_styled(struct nk_context*,const struct nk_style_button*, struct nk_image img, const char*, int, nk_flags alignment);
3137 /* =============================================================================
3138  *
3139  * CHECKBOX
3140  *
3141  * ============================================================================= */
3142 NK_API int nk_check_label(struct nk_context*, const char*, int active);
3143 NK_API int nk_check_text(struct nk_context*, const char*, int,int active);
3144 NK_API unsigned nk_check_flags_label(struct nk_context*, const char*, unsigned int flags, unsigned int value);
3145 NK_API unsigned nk_check_flags_text(struct nk_context*, const char*, int, unsigned int flags, unsigned int value);
3146 NK_API int nk_checkbox_label(struct nk_context*, const char*, int *active);
3147 NK_API int nk_checkbox_text(struct nk_context*, const char*, int, int *active);
3148 NK_API int nk_checkbox_flags_label(struct nk_context*, const char*, unsigned int *flags, unsigned int value);
3149 NK_API int nk_checkbox_flags_text(struct nk_context*, const char*, int, unsigned int *flags, unsigned int value);
3150 /* =============================================================================
3151  *
3152  * RADIO BUTTON
3153  *
3154  * ============================================================================= */
3155 NK_API int nk_radio_label(struct nk_context*, const char*, int *active);
3156 NK_API int nk_radio_text(struct nk_context*, const char*, int, int *active);
3157 NK_API int nk_option_label(struct nk_context*, const char*, int active);
3158 NK_API int nk_option_text(struct nk_context*, const char*, int, int active);
3159 /* =============================================================================
3160  *
3161  * SELECTABLE
3162  *
3163  * ============================================================================= */
3164 NK_API int nk_selectable_label(struct nk_context*, const char*, nk_flags align, int *value);
3165 NK_API int nk_selectable_text(struct nk_context*, const char*, int, nk_flags align, int *value);
3166 NK_API int nk_selectable_image_label(struct nk_context*,struct nk_image, const char*, nk_flags align, int *value);
3167 NK_API int nk_selectable_image_text(struct nk_context*,struct nk_image, const char*, int, nk_flags align, int *value);
3168 NK_API int nk_selectable_symbol_label(struct nk_context*,enum nk_symbol_type, const char*, nk_flags align, int *value);
3169 NK_API int nk_selectable_symbol_text(struct nk_context*,enum nk_symbol_type, const char*, int, nk_flags align, int *value);
3170 
3171 NK_API int nk_select_label(struct nk_context*, const char*, nk_flags align, int value);
3172 NK_API int nk_select_text(struct nk_context*, const char*, int, nk_flags align, int value);
3173 NK_API int nk_select_image_label(struct nk_context*, struct nk_image,const char*, nk_flags align, int value);
3174 NK_API int nk_select_image_text(struct nk_context*, struct nk_image,const char*, int, nk_flags align, int value);
3175 NK_API int nk_select_symbol_label(struct nk_context*,enum nk_symbol_type, const char*, nk_flags align, int value);
3176 NK_API int nk_select_symbol_text(struct nk_context*,enum nk_symbol_type, const char*, int, nk_flags align, int value);
3177 
3178 /* =============================================================================
3179  *
3180  * SLIDER
3181  *
3182  * ============================================================================= */
3183 NK_API float nk_slide_float(struct nk_context*, float min, float val, float max, float step);
3184 NK_API int nk_slide_int(struct nk_context*, int min, int val, int max, int step);
3185 NK_API int nk_slider_float(struct nk_context*, float min, float *val, float max, float step);
3186 NK_API int nk_slider_int(struct nk_context*, int min, int *val, int max, int step);
3187 /* =============================================================================
3188  *
3189  * PROGRESSBAR
3190  *
3191  * ============================================================================= */
3192 NK_API int nk_progress(struct nk_context*, nk_size *cur, nk_size max, int modifyable);
3193 NK_API nk_size nk_prog(struct nk_context*, nk_size cur, nk_size max, int modifyable);
3194 
3195 /* =============================================================================
3196  *
3197  * COLOR PICKER
3198  *
3199  * ============================================================================= */
3200 NK_API struct nk_colorf nk_color_picker(struct nk_context*, struct nk_colorf, enum nk_color_format);
3201 NK_API int nk_color_pick(struct nk_context*, struct nk_colorf*, enum nk_color_format);
3202 /* =============================================================================
3203  *
3204  * PROPERTIES
3205  *
3206  * =============================================================================
3277 */
3278 /*/// #### nk_property_int
3297 */
3298 NK_API void nk_property_int(struct nk_context*, const char *name, int min, int *val, int max, int step, float inc_per_pixel);
3299 /*/// #### nk_property_float
3318 */
3319 NK_API void nk_property_float(struct nk_context*, const char *name, float min, float *val, float max, float step, float inc_per_pixel);
3320 /*/// #### nk_property_double
3339 */
3340 NK_API void nk_property_double(struct nk_context*, const char *name, double min, double *val, double max, double step, float inc_per_pixel);
3341 /*/// #### nk_propertyi
3362 */
3363 NK_API int nk_propertyi(struct nk_context*, const char *name, int min, int val, int max, int step, float inc_per_pixel);
3364 /*/// #### nk_propertyf
3385 */
3386 NK_API float nk_propertyf(struct nk_context*, const char *name, float min, float val, float max, float step, float inc_per_pixel);
3387 /*/// #### nk_propertyd
3408 */
3409 NK_API double nk_propertyd(struct nk_context*, const char *name, double min, double val, double max, double step, float inc_per_pixel);
3410 /* =============================================================================
3411  *
3412  * TEXT EDIT
3413  *
3414  * ============================================================================= */
3429 };
3435 };
3437  NK_EDIT_ACTIVE = NK_FLAG(0), /* edit widget is currently being modified */
3438  NK_EDIT_INACTIVE = NK_FLAG(1), /* edit widget is not active and is not being modified */
3439  NK_EDIT_ACTIVATED = NK_FLAG(2), /* edit widget went from state inactive to state active */
3440  NK_EDIT_DEACTIVATED = NK_FLAG(3), /* edit widget went from state active to state inactive */
3441  NK_EDIT_COMMITED = NK_FLAG(4) /* edit widget has received an enter and lost focus */
3442 };
3443 NK_API nk_flags nk_edit_string(struct nk_context*, nk_flags, char *buffer, int *len, int max, nk_plugin_filter);
3446 NK_API void nk_edit_focus(struct nk_context*, nk_flags flags);
3447 NK_API void nk_edit_unfocus(struct nk_context*);
3448 /* =============================================================================
3449  *
3450  * CHART
3451  *
3452  * ============================================================================= */
3453 NK_API int nk_chart_begin(struct nk_context*, enum nk_chart_type, int num, float min, float max);
3454 NK_API int nk_chart_begin_colored(struct nk_context*, enum nk_chart_type, struct nk_color, struct nk_color active, int num, float min, float max);
3455 NK_API void nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type, int count, float min_value, float max_value);
3456 NK_API void nk_chart_add_slot_colored(struct nk_context *ctx, const enum nk_chart_type, struct nk_color, struct nk_color active, int count, float min_value, float max_value);
3457 NK_API nk_flags nk_chart_push(struct nk_context*, float);
3458 NK_API nk_flags nk_chart_push_slot(struct nk_context*, float, int);
3459 NK_API void nk_chart_end(struct nk_context*);
3460 NK_API void nk_plot(struct nk_context*, enum nk_chart_type, const float *values, int count, int offset);
3461 NK_API void nk_plot_function(struct nk_context*, enum nk_chart_type, void *userdata, float(*value_getter)(void* user, int index), int count, int offset);
3462 /* =============================================================================
3463  *
3464  * POPUP
3465  *
3466  * ============================================================================= */
3467 NK_API int nk_popup_begin(struct nk_context*, enum nk_popup_type, const char*, nk_flags, struct nk_rect bounds);
3468 NK_API void nk_popup_close(struct nk_context*);
3469 NK_API void nk_popup_end(struct nk_context*);
3470 NK_API void nk_popup_get_scroll(struct nk_context*, nk_uint *offset_x, nk_uint *offset_y);
3471 NK_API void nk_popup_set_scroll(struct nk_context*, nk_uint offset_x, nk_uint offset_y);
3472 /* =============================================================================
3473  *
3474  * COMBOBOX
3475  *
3476  * ============================================================================= */
3477 NK_API int nk_combo(struct nk_context*, const char **items, int count, int selected, int item_height, struct nk_vec2 size);
3478 NK_API int nk_combo_separator(struct nk_context*, const char *items_separated_by_separator, int separator, int selected, int count, int item_height, struct nk_vec2 size);
3479 NK_API int nk_combo_string(struct nk_context*, const char *items_separated_by_zeros, int selected, int count, int item_height, struct nk_vec2 size);
3480 NK_API int nk_combo_callback(struct nk_context*, void(*item_getter)(void*, int, const char**), void *userdata, int selected, int count, int item_height, struct nk_vec2 size);
3481 NK_API void nk_combobox(struct nk_context*, const char **items, int count, int *selected, int item_height, struct nk_vec2 size);
3482 NK_API void nk_combobox_string(struct nk_context*, const char *items_separated_by_zeros, int *selected, int count, int item_height, struct nk_vec2 size);
3483 NK_API void nk_combobox_separator(struct nk_context*, const char *items_separated_by_separator, int separator,int *selected, int count, int item_height, struct nk_vec2 size);
3484 NK_API void nk_combobox_callback(struct nk_context*, void(*item_getter)(void*, int, const char**), void*, int *selected, int count, int item_height, struct nk_vec2 size);
3485 /* =============================================================================
3486  *
3487  * ABSTRACT COMBOBOX
3488  *
3489  * ============================================================================= */
3490 NK_API int nk_combo_begin_text(struct nk_context*, const char *selected, int, struct nk_vec2 size);
3491 NK_API int nk_combo_begin_label(struct nk_context*, const char *selected, struct nk_vec2 size);
3492 NK_API int nk_combo_begin_color(struct nk_context*, struct nk_color color, struct nk_vec2 size);
3494 NK_API int nk_combo_begin_symbol_label(struct nk_context*, const char *selected, enum nk_symbol_type, struct nk_vec2 size);
3495 NK_API int nk_combo_begin_symbol_text(struct nk_context*, const char *selected, int, enum nk_symbol_type, struct nk_vec2 size);
3496 NK_API int nk_combo_begin_image(struct nk_context*, struct nk_image img, struct nk_vec2 size);
3497 NK_API int nk_combo_begin_image_label(struct nk_context*, const char *selected, struct nk_image, struct nk_vec2 size);
3498 NK_API int nk_combo_begin_image_text(struct nk_context*, const char *selected, int, struct nk_image, struct nk_vec2 size);
3499 NK_API int nk_combo_item_label(struct nk_context*, const char*, nk_flags alignment);
3500 NK_API int nk_combo_item_text(struct nk_context*, const char*,int, nk_flags alignment);
3501 NK_API int nk_combo_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
3502 NK_API int nk_combo_item_image_text(struct nk_context*, struct nk_image, const char*, int,nk_flags alignment);
3503 NK_API int nk_combo_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
3504 NK_API int nk_combo_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3505 NK_API void nk_combo_close(struct nk_context*);
3506 NK_API void nk_combo_end(struct nk_context*);
3507 /* =============================================================================
3508  *
3509  * CONTEXTUAL
3510  *
3511  * ============================================================================= */
3512 NK_API int nk_contextual_begin(struct nk_context*, nk_flags, struct nk_vec2, struct nk_rect trigger_bounds);
3513 NK_API int nk_contextual_item_text(struct nk_context*, const char*, int,nk_flags align);
3514 NK_API int nk_contextual_item_label(struct nk_context*, const char*, nk_flags align);
3515 NK_API int nk_contextual_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
3516 NK_API int nk_contextual_item_image_text(struct nk_context*, struct nk_image, const char*, int len, nk_flags alignment);
3517 NK_API int nk_contextual_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
3518 NK_API int nk_contextual_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3519 NK_API void nk_contextual_close(struct nk_context*);
3520 NK_API void nk_contextual_end(struct nk_context*);
3521 /* =============================================================================
3522  *
3523  * TOOLTIP
3524  *
3525  * ============================================================================= */
3526 NK_API void nk_tooltip(struct nk_context*, const char*);
3527 #ifdef NK_INCLUDE_STANDARD_VARARGS
3528 NK_API void nk_tooltipf(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(2);
3529 NK_API void nk_tooltipfv(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3530 #endif
3531 NK_API int nk_tooltip_begin(struct nk_context*, float width);
3532 NK_API void nk_tooltip_end(struct nk_context*);
3533 /* =============================================================================
3534  *
3535  * MENU
3536  *
3537  * ============================================================================= */
3538 NK_API void nk_menubar_begin(struct nk_context*);
3539 NK_API void nk_menubar_end(struct nk_context*);
3540 NK_API int nk_menu_begin_text(struct nk_context*, const char* title, int title_len, nk_flags align, struct nk_vec2 size);
3541 NK_API int nk_menu_begin_label(struct nk_context*, const char*, nk_flags align, struct nk_vec2 size);
3542 NK_API int nk_menu_begin_image(struct nk_context*, const char*, struct nk_image, struct nk_vec2 size);
3543 NK_API int nk_menu_begin_image_text(struct nk_context*, const char*, int,nk_flags align,struct nk_image, struct nk_vec2 size);
3544 NK_API int nk_menu_begin_image_label(struct nk_context*, const char*, nk_flags align,struct nk_image, struct nk_vec2 size);
3545 NK_API int nk_menu_begin_symbol(struct nk_context*, const char*, enum nk_symbol_type, struct nk_vec2 size);
3546 NK_API int nk_menu_begin_symbol_text(struct nk_context*, const char*, int,nk_flags align,enum nk_symbol_type, struct nk_vec2 size);
3547 NK_API int nk_menu_begin_symbol_label(struct nk_context*, const char*, nk_flags align,enum nk_symbol_type, struct nk_vec2 size);
3548 NK_API int nk_menu_item_text(struct nk_context*, const char*, int,nk_flags align);
3549 NK_API int nk_menu_item_label(struct nk_context*, const char*, nk_flags alignment);
3550 NK_API int nk_menu_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
3551 NK_API int nk_menu_item_image_text(struct nk_context*, struct nk_image, const char*, int len, nk_flags alignment);
3552 NK_API int nk_menu_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3553 NK_API int nk_menu_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
3554 NK_API void nk_menu_close(struct nk_context*);
3555 NK_API void nk_menu_end(struct nk_context*);
3556 /* =============================================================================
3557  *
3558  * STYLE
3559  *
3560  * ============================================================================= */
3591 };
3601 };
3602 NK_API void nk_style_default(struct nk_context*);
3603 NK_API void nk_style_from_table(struct nk_context*, const struct nk_color*);
3604 NK_API void nk_style_load_cursor(struct nk_context*, enum nk_style_cursor, const struct nk_cursor*);
3605 NK_API void nk_style_load_all_cursors(struct nk_context*, struct nk_cursor*);
3607 NK_API void nk_style_set_font(struct nk_context*, const struct nk_user_font*);
3609 NK_API void nk_style_show_cursor(struct nk_context*);
3610 NK_API void nk_style_hide_cursor(struct nk_context*);
3611 
3612 NK_API int nk_style_push_font(struct nk_context*, const struct nk_user_font*);
3613 NK_API int nk_style_push_float(struct nk_context*, float*, float);
3614 NK_API int nk_style_push_vec2(struct nk_context*, struct nk_vec2*, struct nk_vec2);
3617 NK_API int nk_style_push_color(struct nk_context*, struct nk_color*, struct nk_color);
3618 
3619 NK_API int nk_style_pop_font(struct nk_context*);
3620 NK_API int nk_style_pop_float(struct nk_context*);
3621 NK_API int nk_style_pop_vec2(struct nk_context*);
3623 NK_API int nk_style_pop_flags(struct nk_context*);
3624 NK_API int nk_style_pop_color(struct nk_context*);
3625 /* =============================================================================
3626  *
3627  * COLOR
3628  *
3629  * ============================================================================= */
3630 NK_API struct nk_color nk_rgb(int r, int g, int b);
3631 NK_API struct nk_color nk_rgb_iv(const int *rgb);
3632 NK_API struct nk_color nk_rgb_bv(const nk_byte* rgb);
3633 NK_API struct nk_color nk_rgb_f(float r, float g, float b);
3634 NK_API struct nk_color nk_rgb_fv(const float *rgb);
3635 NK_API struct nk_color nk_rgb_cf(struct nk_colorf c);
3636 NK_API struct nk_color nk_rgb_hex(const char *rgb);
3637 
3638 NK_API struct nk_color nk_rgba(int r, int g, int b, int a);
3640 NK_API struct nk_color nk_rgba_iv(const int *rgba);
3641 NK_API struct nk_color nk_rgba_bv(const nk_byte *rgba);
3642 NK_API struct nk_color nk_rgba_f(float r, float g, float b, float a);
3643 NK_API struct nk_color nk_rgba_fv(const float *rgba);
3644 NK_API struct nk_color nk_rgba_cf(struct nk_colorf c);
3645 NK_API struct nk_color nk_rgba_hex(const char *rgb);
3646 
3647 NK_API struct nk_colorf nk_hsva_colorf(float h, float s, float v, float a);
3648 NK_API struct nk_colorf nk_hsva_colorfv(float *c);
3649 NK_API void nk_colorf_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_colorf in);
3650 NK_API void nk_colorf_hsva_fv(float *hsva, struct nk_colorf in);
3651 
3652 NK_API struct nk_color nk_hsv(int h, int s, int v);
3653 NK_API struct nk_color nk_hsv_iv(const int *hsv);
3654 NK_API struct nk_color nk_hsv_bv(const nk_byte *hsv);
3655 NK_API struct nk_color nk_hsv_f(float h, float s, float v);
3656 NK_API struct nk_color nk_hsv_fv(const float *hsv);
3657 
3658 NK_API struct nk_color nk_hsva(int h, int s, int v, int a);
3659 NK_API struct nk_color nk_hsva_iv(const int *hsva);
3660 NK_API struct nk_color nk_hsva_bv(const nk_byte *hsva);
3661 NK_API struct nk_color nk_hsva_f(float h, float s, float v, float a);
3662 NK_API struct nk_color nk_hsva_fv(const float *hsva);
3663 
3664 /* color (conversion nuklear --> user) */
3665 NK_API void nk_color_f(float *r, float *g, float *b, float *a, struct nk_color);
3666 NK_API void nk_color_fv(float *rgba_out, struct nk_color);
3667 NK_API struct nk_colorf nk_color_cf(struct nk_color);
3668 NK_API void nk_color_d(double *r, double *g, double *b, double *a, struct nk_color);
3669 NK_API void nk_color_dv(double *rgba_out, struct nk_color);
3670 
3672 NK_API void nk_color_hex_rgba(char *output, struct nk_color);
3673 NK_API void nk_color_hex_rgb(char *output, struct nk_color);
3674 
3675 NK_API void nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color);
3676 NK_API void nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color);
3677 NK_API void nk_color_hsv_iv(int *hsv_out, struct nk_color);
3678 NK_API void nk_color_hsv_bv(nk_byte *hsv_out, struct nk_color);
3679 NK_API void nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color);
3680 NK_API void nk_color_hsv_fv(float *hsv_out, struct nk_color);
3681 
3682 NK_API void nk_color_hsva_i(int *h, int *s, int *v, int *a, struct nk_color);
3683 NK_API void nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color);
3684 NK_API void nk_color_hsva_iv(int *hsva_out, struct nk_color);
3685 NK_API void nk_color_hsva_bv(nk_byte *hsva_out, struct nk_color);
3686 NK_API void nk_color_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_color);
3687 NK_API void nk_color_hsva_fv(float *hsva_out, struct nk_color);
3688 /* =============================================================================
3689  *
3690  * IMAGE
3691  *
3692  * ============================================================================= */
3696 NK_API struct nk_image nk_image_ptr(void*);
3697 NK_API struct nk_image nk_image_id(int);
3698 NK_API int nk_image_is_subimage(const struct nk_image* img);
3699 NK_API struct nk_image nk_subimage_ptr(void*, unsigned short w, unsigned short h, struct nk_rect sub_region);
3700 NK_API struct nk_image nk_subimage_id(int, unsigned short w, unsigned short h, struct nk_rect sub_region);
3701 NK_API struct nk_image nk_subimage_handle(nk_handle, unsigned short w, unsigned short h, struct nk_rect sub_region);
3702 /* =============================================================================
3703  *
3704  * MATH
3705  *
3706  * ============================================================================= */
3707 NK_API nk_hash nk_murmur_hash(const void *key, int len, nk_hash seed);
3708 NK_API void nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r, float pad_x, float pad_y, enum nk_heading);
3709 
3710 NK_API struct nk_vec2 nk_vec2(float x, float y);
3711 NK_API struct nk_vec2 nk_vec2i(int x, int y);
3712 NK_API struct nk_vec2 nk_vec2v(const float *xy);
3713 NK_API struct nk_vec2 nk_vec2iv(const int *xy);
3714 
3715 NK_API struct nk_rect nk_get_null_rect(void);
3716 NK_API struct nk_rect nk_rect(float x, float y, float w, float h);
3717 NK_API struct nk_rect nk_recti(int x, int y, int w, int h);
3718 NK_API struct nk_rect nk_recta(struct nk_vec2 pos, struct nk_vec2 size);
3719 NK_API struct nk_rect nk_rectv(const float *xywh);
3720 NK_API struct nk_rect nk_rectiv(const int *xywh);
3721 NK_API struct nk_vec2 nk_rect_pos(struct nk_rect);
3722 NK_API struct nk_vec2 nk_rect_size(struct nk_rect);
3723 /* =============================================================================
3724  *
3725  * STRING
3726  *
3727  * ============================================================================= */
3728 NK_API int nk_strlen(const char *str);
3729 NK_API int nk_stricmp(const char *s1, const char *s2);
3730 NK_API int nk_stricmpn(const char *s1, const char *s2, int n);
3731 NK_API int nk_strtoi(const char *str, const char **endptr);
3732 NK_API float nk_strtof(const char *str, const char **endptr);
3733 NK_API double nk_strtod(const char *str, const char **endptr);
3734 NK_API int nk_strfilter(const char *text, const char *regexp);
3735 NK_API int nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score);
3736 NK_API int nk_strmatch_fuzzy_text(const char *txt, int txt_len, const char *pattern, int *out_score);
3737 /* =============================================================================
3738  *
3739  * UTF-8
3740  *
3741  * ============================================================================= */
3742 NK_API int nk_utf_decode(const char*, nk_rune*, int);
3743 NK_API int nk_utf_encode(nk_rune, char*, int);
3744 NK_API int nk_utf_len(const char*, int byte_len);
3745 NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune *unicode, int *len);
3746 /* ===============================================================
3747  *
3748  * FONT
3749  *
3750  * ===============================================================*/
3751 /* Font handling in this library was designed to be quite customizable and lets
3752  you decide what you want to use and what you want to provide. There are three
3753  different ways to use the font atlas. The first two will use your font
3754  handling scheme and only requires essential data to run nuklear. The next
3755  slightly more advanced features is font handling with vertex buffer output.
3756  Finally the most complex API wise is using nuklear's font baking API.
3757 
3758  1.) Using your own implementation without vertex buffer output
3759  --------------------------------------------------------------
3760  So first up the easiest way to do font handling is by just providing a
3761  `nk_user_font` struct which only requires the height in pixel of the used
3762  font and a callback to calculate the width of a string. This way of handling
3763  fonts is best fitted for using the normal draw shape command API where you
3764  do all the text drawing yourself and the library does not require any kind
3765  of deeper knowledge about which font handling mechanism you use.
3766  IMPORTANT: the `nk_user_font` pointer provided to nuklear has to persist
3767  over the complete life time! I know this sucks but it is currently the only
3768  way to switch between fonts.
3769 
3770  float your_text_width_calculation(nk_handle handle, float height, const char *text, int len)
3771  {
3772  your_font_type *type = handle.ptr;
3773  float text_width = ...;
3774  return text_width;
3775  }
3776 
3777  struct nk_user_font font;
3778  font.userdata.ptr = &your_font_class_or_struct;
3779  font.height = your_font_height;
3780  font.width = your_text_width_calculation;
3781 
3782  struct nk_context ctx;
3783  nk_init_default(&ctx, &font);
3784 
3785  2.) Using your own implementation with vertex buffer output
3786  --------------------------------------------------------------
3787  While the first approach works fine if you don't want to use the optional
3788  vertex buffer output it is not enough if you do. To get font handling working
3789  for these cases you have to provide two additional parameters inside the
3790  `nk_user_font`. First a texture atlas handle used to draw text as subimages
3791  of a bigger font atlas texture and a callback to query a character's glyph
3792  information (offset, size, ...). So it is still possible to provide your own
3793  font and use the vertex buffer output.
3794 
3795  float your_text_width_calculation(nk_handle handle, float height, const char *text, int len)
3796  {
3797  your_font_type *type = handle.ptr;
3798  float text_width = ...;
3799  return text_width;
3800  }
3801  void query_your_font_glyph(nk_handle handle, float font_height, struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
3802  {
3803  your_font_type *type = handle.ptr;
3804  glyph.width = ...;
3805  glyph.height = ...;
3806  glyph.xadvance = ...;
3807  glyph.uv[0].x = ...;
3808  glyph.uv[0].y = ...;
3809  glyph.uv[1].x = ...;
3810  glyph.uv[1].y = ...;
3811  glyph.offset.x = ...;
3812  glyph.offset.y = ...;
3813  }
3814 
3815  struct nk_user_font font;
3816  font.userdata.ptr = &your_font_class_or_struct;
3817  font.height = your_font_height;
3818  font.width = your_text_width_calculation;
3819  font.query = query_your_font_glyph;
3820  font.texture.id = your_font_texture;
3821 
3822  struct nk_context ctx;
3823  nk_init_default(&ctx, &font);
3824 
3825  3.) Nuklear font baker
3826  ------------------------------------
3827  The final approach if you do not have a font handling functionality or don't
3828  want to use it in this library is by using the optional font baker.
3829  The font baker APIs can be used to create a font plus font atlas texture
3830  and can be used with or without the vertex buffer output.
3831 
3832  It still uses the `nk_user_font` struct and the two different approaches
3833  previously stated still work. The font baker is not located inside
3834  `nk_context` like all other systems since it can be understood as more of
3835  an extension to nuklear and does not really depend on any `nk_context` state.
3836 
3837  Font baker need to be initialized first by one of the nk_font_atlas_init_xxx
3838  functions. If you don't care about memory just call the default version
3839  `nk_font_atlas_init_default` which will allocate all memory from the standard library.
3840  If you want to control memory allocation but you don't care if the allocated
3841  memory is temporary and therefore can be freed directly after the baking process
3842  is over or permanent you can call `nk_font_atlas_init`.
3843 
3844  After successfully initializing the font baker you can add Truetype(.ttf) fonts from
3845  different sources like memory or from file by calling one of the `nk_font_atlas_add_xxx`.
3846  functions. Adding font will permanently store each font, font config and ttf memory block(!)
3847  inside the font atlas and allows to reuse the font atlas. If you don't want to reuse
3848  the font baker by for example adding additional fonts you can call
3849  `nk_font_atlas_cleanup` after the baking process is over (after calling nk_font_atlas_end).
3850 
3851  As soon as you added all fonts you wanted you can now start the baking process
3852  for every selected glyph to image by calling `nk_font_atlas_bake`.
3853  The baking process returns image memory, width and height which can be used to
3854  either create your own image object or upload it to any graphics library.
3855  No matter which case you finally have to call `nk_font_atlas_end` which
3856  will free all temporary memory including the font atlas image so make sure
3857  you created our texture beforehand. `nk_font_atlas_end` requires a handle
3858  to your font texture or object and optionally fills a `struct nk_draw_null_texture`
3859  which can be used for the optional vertex output. If you don't want it just
3860  set the argument to `NULL`.
3861 
3862  At this point you are done and if you don't want to reuse the font atlas you
3863  can call `nk_font_atlas_cleanup` to free all truetype blobs and configuration
3864  memory. Finally if you don't use the font atlas and any of it's fonts anymore
3865  you need to call `nk_font_atlas_clear` to free all memory still being used.
3866 
3867  struct nk_font_atlas atlas;
3868  nk_font_atlas_init_default(&atlas);
3869  nk_font_atlas_begin(&atlas);
3870  nk_font *font = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font.ttf", 13, 0);
3871  nk_font *font2 = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font2.ttf", 16, 0);
3872  const void* img = nk_font_atlas_bake(&atlas, &img_width, &img_height, NK_FONT_ATLAS_RGBA32);
3873  nk_font_atlas_end(&atlas, nk_handle_id(texture), 0);
3874 
3875  struct nk_context ctx;
3876  nk_init_default(&ctx, &font->handle);
3877  while (1) {
3878 
3879  }
3880  nk_font_atlas_clear(&atlas);
3881 
3882  The font baker API is probably the most complex API inside this library and
3883  I would suggest reading some of my examples `example/` to get a grip on how
3884  to use the font atlas. There are a number of details I left out. For example
3885  how to merge fonts, configure a font with `nk_font_config` to use other languages,
3886  use another texture coordinate format and a lot more:
3887 
3888  struct nk_font_config cfg = nk_font_config(font_pixel_height);
3889  cfg.merge_mode = nk_false or nk_true;
3890  cfg.range = nk_font_korean_glyph_ranges();
3891  cfg.coord_type = NK_COORD_PIXEL;
3892  nk_font *font = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font.ttf", 13, &cfg);
3893 
3894 */
3895 struct nk_user_font_glyph;
3896 typedef float(*nk_text_width_f)(nk_handle, float h, const char*, int len);
3897 typedef void(*nk_query_font_glyph_f)(nk_handle handle, float font_height,
3898  struct nk_user_font_glyph *glyph,
3899  nk_rune codepoint, nk_rune next_codepoint);
3900 
3901 #if defined(NK_INCLUDE_VERTEX_BUFFER_OUTPUT) || defined(NK_INCLUDE_SOFTWARE_FONT)
3902 struct nk_user_font_glyph {
3903  struct nk_vec2 uv[2];
3904  /* texture coordinates */
3905  struct nk_vec2 offset;
3906  /* offset between top left and glyph */
3907  float width, height;
3908  /* size of the glyph */
3909  float xadvance;
3910  /* offset to the next glyph */
3911 };
3912 #endif
3913 
3916  /* user provided font handle */
3917  float height;
3918  /* max height of the font */
3920  /* font string width in pixel callback */
3921 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
3922  nk_query_font_glyph_f query;
3923  /* font glyph callback to query drawing info */
3924  nk_handle texture;
3925  /* texture handle to the used font atlas or texture */
3926 #endif
3927 };
3928 
3929 #ifdef NK_INCLUDE_FONT_BAKING
3930 enum nk_font_coord_type {
3931  NK_COORD_UV, /* texture coordinates inside font glyphs are clamped between 0-1 */
3932  NK_COORD_PIXEL /* texture coordinates inside font glyphs are in absolute pixel */
3933 };
3934 
3935 struct nk_font;
3936 struct nk_baked_font {
3937  float height;
3938  /* height of the font */
3939  float ascent, descent;
3940  /* font glyphs ascent and descent */
3941  nk_rune glyph_offset;
3942  /* glyph array offset inside the font glyph baking output array */
3943  nk_rune glyph_count;
3944  /* number of glyphs of this font inside the glyph baking array output */
3945  const nk_rune *ranges;
3946  /* font codepoint ranges as pairs of (from/to) and 0 as last element */
3947 };
3948 
3949 struct nk_font_config {
3950  struct nk_font_config *next;
3951  /* NOTE: only used internally */
3952  void *ttf_blob;
3953  /* pointer to loaded TTF file memory block.
3954  * NOTE: not needed for nk_font_atlas_add_from_memory and nk_font_atlas_add_from_file. */
3955  nk_size ttf_size;
3956  /* size of the loaded TTF file memory block
3957  * NOTE: not needed for nk_font_atlas_add_from_memory and nk_font_atlas_add_from_file. */
3958 
3959  unsigned char ttf_data_owned_by_atlas;
3960  /* used inside font atlas: default to: 0*/
3961  unsigned char merge_mode;
3962  /* merges this font into the last font */
3963  unsigned char pixel_snap;
3964  /* align every character to pixel boundary (if true set oversample (1,1)) */
3965  unsigned char oversample_v, oversample_h;
3966  /* rasterize at hight quality for sub-pixel position */
3967  unsigned char padding[3];
3968 
3969  float size;
3970  /* baked pixel height of the font */
3971  enum nk_font_coord_type coord_type;
3972  /* texture coordinate format with either pixel or UV coordinates */
3973  struct nk_vec2 spacing;
3974  /* extra pixel spacing between glyphs */
3975  const nk_rune *range;
3976  /* list of unicode ranges (2 values per range, zero terminated) */
3977  struct nk_baked_font *font;
3978  /* font to setup in the baking process: NOTE: not needed for font atlas */
3979  nk_rune fallback_glyph;
3980  /* fallback glyph to use if a given rune is not found */
3981  struct nk_font_config *n;
3982  struct nk_font_config *p;
3983 };
3984 
3985 struct nk_font_glyph {
3986  nk_rune codepoint;
3987  float xadvance;
3988  float x0, y0, x1, y1, w, h;
3989  float u0, v0, u1, v1;
3990 };
3991 
3992 struct nk_font {
3993  struct nk_font *next;
3994  struct nk_user_font handle;
3995  struct nk_baked_font info;
3996  float scale;
3997  struct nk_font_glyph *glyphs;
3998  const struct nk_font_glyph *fallback;
3999  nk_rune fallback_codepoint;
4000  nk_handle texture;
4001  struct nk_font_config *config;
4002 };
4003 
4004 enum nk_font_atlas_format {
4005  NK_FONT_ATLAS_ALPHA8,
4006  NK_FONT_ATLAS_RGBA32
4007 };
4008 
4009 struct nk_font_atlas {
4010  void *pixel;
4011  int tex_width;
4012  int tex_height;
4013 
4014  struct nk_allocator permanent;
4015  struct nk_allocator temporary;
4016 
4017  struct nk_recti custom;
4018  struct nk_cursor cursors[NK_CURSOR_COUNT];
4019 
4020  int glyph_count;
4021  struct nk_font_glyph *glyphs;
4022  struct nk_font *default_font;
4023  struct nk_font *fonts;
4024  struct nk_font_config *config;
4025  int font_num;
4026 };
4027 
4028 /* some language glyph codepoint ranges */
4029 NK_API const nk_rune *nk_font_default_glyph_ranges(void);
4030 NK_API const nk_rune *nk_font_chinese_glyph_ranges(void);
4031 NK_API const nk_rune *nk_font_cyrillic_glyph_ranges(void);
4032 NK_API const nk_rune *nk_font_korean_glyph_ranges(void);
4033 
4034 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4035 NK_API void nk_font_atlas_init_default(struct nk_font_atlas*);
4036 #endif
4037 NK_API void nk_font_atlas_init(struct nk_font_atlas*, struct nk_allocator*);
4038 NK_API void nk_font_atlas_init_custom(struct nk_font_atlas*, struct nk_allocator *persistent, struct nk_allocator *transient);
4039 NK_API void nk_font_atlas_begin(struct nk_font_atlas*);
4040 NK_API struct nk_font_config nk_font_config(float pixel_height);
4041 NK_API struct nk_font *nk_font_atlas_add(struct nk_font_atlas*, const struct nk_font_config*);
4042 #ifdef NK_INCLUDE_DEFAULT_FONT
4043 NK_API struct nk_font* nk_font_atlas_add_default(struct nk_font_atlas*, float height, const struct nk_font_config*);
4044 #endif
4045 NK_API struct nk_font* nk_font_atlas_add_from_memory(struct nk_font_atlas *atlas, void *memory, nk_size size, float height, const struct nk_font_config *config);
4046 #ifdef NK_INCLUDE_STANDARD_IO
4047 NK_API struct nk_font* nk_font_atlas_add_from_file(struct nk_font_atlas *atlas, const char *file_path, float height, const struct nk_font_config*);
4048 #endif
4049 NK_API struct nk_font *nk_font_atlas_add_compressed(struct nk_font_atlas*, void *memory, nk_size size, float height, const struct nk_font_config*);
4050 NK_API struct nk_font* nk_font_atlas_add_compressed_base85(struct nk_font_atlas*, const char *data, float height, const struct nk_font_config *config);
4051 NK_API const void* nk_font_atlas_bake(struct nk_font_atlas*, int *width, int *height, enum nk_font_atlas_format);
4052 NK_API void nk_font_atlas_end(struct nk_font_atlas*, nk_handle tex, struct nk_draw_null_texture*);
4053 NK_API const struct nk_font_glyph* nk_font_find_glyph(struct nk_font*, nk_rune unicode);
4054 NK_API void nk_font_atlas_cleanup(struct nk_font_atlas *atlas);
4055 NK_API void nk_font_atlas_clear(struct nk_font_atlas*);
4056 
4057 #endif
4058 
4059 /* ==============================================================
4060  *
4061  * MEMORY BUFFER
4062  *
4063  * ===============================================================*/
4064 /* A basic (double)-buffer with linear allocation and resetting as only
4065  freeing policy. The buffer's main purpose is to control all memory management
4066  inside the GUI toolkit and still leave memory control as much as possible in
4067  the hand of the user while also making sure the library is easy to use if
4068  not as much control is needed.
4069  In general all memory inside this library can be provided from the user in
4070  three different ways.
4071 
4072  The first way and the one providing most control is by just passing a fixed
4073  size memory block. In this case all control lies in the hand of the user
4074  since he can exactly control where the memory comes from and how much memory
4075  the library should consume. Of course using the fixed size API removes the
4076  ability to automatically resize a buffer if not enough memory is provided so
4077  you have to take over the resizing. While being a fixed sized buffer sounds
4078  quite limiting, it is very effective in this library since the actual memory
4079  consumption is quite stable and has a fixed upper bound for a lot of cases.
4080 
4081  If you don't want to think about how much memory the library should allocate
4082  at all time or have a very dynamic UI with unpredictable memory consumption
4083  habits but still want control over memory allocation you can use the dynamic
4084  allocator based API. The allocator consists of two callbacks for allocating
4085  and freeing memory and optional userdata so you can plugin your own allocator.
4086 
4087  The final and easiest way can be used by defining
4088  NK_INCLUDE_DEFAULT_ALLOCATOR which uses the standard library memory
4089  allocation functions malloc and free and takes over complete control over
4090  memory in this library.
4091 */
4093  void *memory;
4094  unsigned int type;
4099 };
4100 
4104 };
4105 
4110 };
4111 
4113  int active;
4115 };
4116 
4117 struct nk_memory {void *ptr;nk_size size;};
4118 struct nk_buffer {
4120  /* buffer marker to free a buffer to a certain offset */
4122  /* allocator callback for dynamic buffers */
4124  /* memory management type */
4126  /* memory and size of the current memory block */
4128  /* growing factor for dynamic memory management */
4130  /* total amount of memory allocated */
4132  /* totally consumed memory given that enough memory is present */
4134  /* number of allocation calls */
4136  /* current size of the buffer */
4137 };
4138 
4139 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4140 NK_API void nk_buffer_init_default(struct nk_buffer*);
4141 #endif
4142 NK_API void nk_buffer_init(struct nk_buffer*, const struct nk_allocator*, nk_size size);
4143 NK_API void nk_buffer_init_fixed(struct nk_buffer*, void *memory, nk_size size);
4144 NK_API void nk_buffer_info(struct nk_memory_status*, struct nk_buffer*);
4145 NK_API void nk_buffer_push(struct nk_buffer*, enum nk_buffer_allocation_type type, const void *memory, nk_size size, nk_size align);
4146 NK_API void nk_buffer_mark(struct nk_buffer*, enum nk_buffer_allocation_type type);
4148 NK_API void nk_buffer_clear(struct nk_buffer*);
4149 NK_API void nk_buffer_free(struct nk_buffer*);
4150 NK_API void *nk_buffer_memory(struct nk_buffer*);
4151 NK_API const void *nk_buffer_memory_const(const struct nk_buffer*);
4153 
4154 /* ==============================================================
4155  *
4156  * STRING
4157  *
4158  * ===============================================================*/
4159 /* Basic string buffer which is only used in context with the text editor
4160  * to manage and manipulate dynamic or fixed size string content. This is _NOT_
4161  * the default string handling method. The only instance you should have any contact
4162  * with this API is if you interact with an `nk_text_edit` object inside one of the
4163  * copy and paste functions and even there only for more advanced cases. */
4164 struct nk_str {
4166  int len; /* in codepoints/runes/glyphs */
4167 };
4168 
4169 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4170 NK_API void nk_str_init_default(struct nk_str*);
4171 #endif
4172 NK_API void nk_str_init(struct nk_str*, const struct nk_allocator*, nk_size size);
4173 NK_API void nk_str_init_fixed(struct nk_str*, void *memory, nk_size size);
4174 NK_API void nk_str_clear(struct nk_str*);
4175 NK_API void nk_str_free(struct nk_str*);
4176 
4177 NK_API int nk_str_append_text_char(struct nk_str*, const char*, int);
4178 NK_API int nk_str_append_str_char(struct nk_str*, const char*);
4179 NK_API int nk_str_append_text_utf8(struct nk_str*, const char*, int);
4180 NK_API int nk_str_append_str_utf8(struct nk_str*, const char*);
4181 NK_API int nk_str_append_text_runes(struct nk_str*, const nk_rune*, int);
4182 NK_API int nk_str_append_str_runes(struct nk_str*, const nk_rune*);
4183 
4184 NK_API int nk_str_insert_at_char(struct nk_str*, int pos, const char*, int);
4185 NK_API int nk_str_insert_at_rune(struct nk_str*, int pos, const char*, int);
4186 
4187 NK_API int nk_str_insert_text_char(struct nk_str*, int pos, const char*, int);
4188 NK_API int nk_str_insert_str_char(struct nk_str*, int pos, const char*);
4189 NK_API int nk_str_insert_text_utf8(struct nk_str*, int pos, const char*, int);
4190 NK_API int nk_str_insert_str_utf8(struct nk_str*, int pos, const char*);
4191 NK_API int nk_str_insert_text_runes(struct nk_str*, int pos, const nk_rune*, int);
4192 NK_API int nk_str_insert_str_runes(struct nk_str*, int pos, const nk_rune*);
4193 
4194 NK_API void nk_str_remove_chars(struct nk_str*, int len);
4195 NK_API void nk_str_remove_runes(struct nk_str *str, int len);
4196 NK_API void nk_str_delete_chars(struct nk_str*, int pos, int len);
4197 NK_API void nk_str_delete_runes(struct nk_str*, int pos, int len);
4198 
4199 NK_API char *nk_str_at_char(struct nk_str*, int pos);
4200 NK_API char *nk_str_at_rune(struct nk_str*, int pos, nk_rune *unicode, int *len);
4201 NK_API nk_rune nk_str_rune_at(const struct nk_str*, int pos);
4202 NK_API const char *nk_str_at_char_const(const struct nk_str*, int pos);
4203 NK_API const char *nk_str_at_const(const struct nk_str*, int pos, nk_rune *unicode, int *len);
4204 
4205 NK_API char *nk_str_get(struct nk_str*);
4206 NK_API const char *nk_str_get_const(const struct nk_str*);
4207 NK_API int nk_str_len(struct nk_str*);
4208 NK_API int nk_str_len_char(struct nk_str*);
4209 
4210 /*===============================================================
4211  *
4212  * TEXT EDITOR
4213  *
4214  * ===============================================================*/
4215 /* Editing text in this library is handled by either `nk_edit_string` or
4216  * `nk_edit_buffer`. But like almost everything in this library there are multiple
4217  * ways of doing it and a balance between control and ease of use with memory
4218  * as well as functionality controlled by flags.
4219  *
4220  * This library generally allows three different levels of memory control:
4221  * First of is the most basic way of just providing a simple char array with
4222  * string length. This method is probably the easiest way of handling simple
4223  * user text input. Main upside is complete control over memory while the biggest
4224  * downside in comparison with the other two approaches is missing undo/redo.
4225  *
4226  * For UIs that require undo/redo the second way was created. It is based on
4227  * a fixed size nk_text_edit struct, which has an internal undo/redo stack.
4228  * This is mainly useful if you want something more like a text editor but don't want
4229  * to have a dynamically growing buffer.
4230  *
4231  * The final way is using a dynamically growing nk_text_edit struct, which
4232  * has both a default version if you don't care where memory comes from and an
4233  * allocator version if you do. While the text editor is quite powerful for its
4234  * complexity I would not recommend editing gigabytes of data with it.
4235  * It is rather designed for uses cases which make sense for a GUI library not for
4236  * an full blown text editor.
4237  */
4238 #ifndef NK_TEXTEDIT_UNDOSTATECOUNT
4239 #define NK_TEXTEDIT_UNDOSTATECOUNT 99
4240 #endif
4241 
4242 #ifndef NK_TEXTEDIT_UNDOCHARCOUNT
4243 #define NK_TEXTEDIT_UNDOCHARCOUNT 999
4244 #endif
4245 
4246 struct nk_text_edit;
4251 };
4252 
4254  int where;
4258 };
4259 
4263  short undo_point;
4264  short redo_point;
4267 };
4268 
4272 };
4273 
4278 };
4279 
4282  struct nk_str string;
4285 
4286  int cursor;
4289  unsigned char mode;
4290  unsigned char cursor_at_end_of_line;
4291  unsigned char initialized;
4292  unsigned char has_preferred_x;
4293  unsigned char single_line;
4294  unsigned char active;
4295  unsigned char padding1;
4298 };
4299 
4300 /* filter function */
4301 NK_API int nk_filter_default(const struct nk_text_edit*, nk_rune unicode);
4302 NK_API int nk_filter_ascii(const struct nk_text_edit*, nk_rune unicode);
4303 NK_API int nk_filter_float(const struct nk_text_edit*, nk_rune unicode);
4304 NK_API int nk_filter_decimal(const struct nk_text_edit*, nk_rune unicode);
4305 NK_API int nk_filter_hex(const struct nk_text_edit*, nk_rune unicode);
4306 NK_API int nk_filter_oct(const struct nk_text_edit*, nk_rune unicode);
4307 NK_API int nk_filter_binary(const struct nk_text_edit*, nk_rune unicode);
4308 
4309 /* text editor */
4310 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4311 NK_API void nk_textedit_init_default(struct nk_text_edit*);
4312 #endif
4314 NK_API void nk_textedit_init_fixed(struct nk_text_edit*, void *memory, nk_size size);
4315 NK_API void nk_textedit_free(struct nk_text_edit*);
4316 NK_API void nk_textedit_text(struct nk_text_edit*, const char*, int total_len);
4317 NK_API void nk_textedit_delete(struct nk_text_edit*, int where, int len);
4320 NK_API int nk_textedit_cut(struct nk_text_edit*);
4321 NK_API int nk_textedit_paste(struct nk_text_edit*, char const*, int len);
4322 NK_API void nk_textedit_undo(struct nk_text_edit*);
4323 NK_API void nk_textedit_redo(struct nk_text_edit*);
4324 
4325 /* ===============================================================
4326  *
4327  * DRAWING
4328  *
4329  * ===============================================================*/
4330 /* This library was designed to be render backend agnostic so it does
4331  not draw anything to screen. Instead all drawn shapes, widgets
4332  are made of, are buffered into memory and make up a command queue.
4333  Each frame therefore fills the command buffer with draw commands
4334  that then need to be executed by the user and his own render backend.
4335  After that the command buffer needs to be cleared and a new frame can be
4336  started. It is probably important to note that the command buffer is the main
4337  drawing API and the optional vertex buffer API only takes this format and
4338  converts it into a hardware accessible format.
4339 
4340  To use the command queue to draw your own widgets you can access the
4341  command buffer of each window by calling `nk_window_get_canvas` after
4342  previously having called `nk_begin`:
4343 
4344  void draw_red_rectangle_widget(struct nk_context *ctx)
4345  {
4346  struct nk_command_buffer *canvas;
4347  struct nk_input *input = &ctx->input;
4348  canvas = nk_window_get_canvas(ctx);
4349 
4350  struct nk_rect space;
4351  enum nk_widget_layout_states state;
4352  state = nk_widget(&space, ctx);
4353  if (!state) return;
4354 
4355  if (state != NK_WIDGET_ROM)
4356  update_your_widget_by_user_input(...);
4357  nk_fill_rect(canvas, space, 0, nk_rgb(255,0,0));
4358  }
4359 
4360  if (nk_begin(...)) {
4361  nk_layout_row_dynamic(ctx, 25, 1);
4362  draw_red_rectangle_widget(ctx);
4363  }
4364  nk_end(..)
4365 
4366  Important to know if you want to create your own widgets is the `nk_widget`
4367  call. It allocates space on the panel reserved for this widget to be used,
4368  but also returns the state of the widget space. If your widget is not seen and does
4369  not have to be updated it is '0' and you can just return. If it only has
4370  to be drawn the state will be `NK_WIDGET_ROM` otherwise you can do both
4371  update and draw your widget. The reason for separating is to only draw and
4372  update what is actually necessary which is crucial for performance.
4373 */
4394 };
4395 
4396 /* command base and header of every command inside the buffer */
4397 struct nk_command {
4400 #ifdef NK_INCLUDE_COMMAND_USERDATA
4401  nk_handle userdata;
4402 #endif
4403 };
4404 
4407  short x, y;
4408  unsigned short w, h;
4409 };
4410 
4413  unsigned short line_thickness;
4414  struct nk_vec2i begin;
4415  struct nk_vec2i end;
4416  struct nk_color color;
4417 };
4418 
4421  unsigned short line_thickness;
4422  struct nk_vec2i begin;
4423  struct nk_vec2i end;
4424  struct nk_vec2i ctrl[2];
4425  struct nk_color color;
4426 };
4427 
4430  unsigned short rounding;
4431  unsigned short line_thickness;
4432  short x, y;
4433  unsigned short w, h;
4434  struct nk_color color;
4435 };
4436 
4439  unsigned short rounding;
4440  short x, y;
4441  unsigned short w, h;
4442  struct nk_color color;
4443 };
4444 
4447  short x, y;
4448  unsigned short w, h;
4449  struct nk_color left;
4450  struct nk_color top;
4452  struct nk_color right;
4453 };
4454 
4457  unsigned short line_thickness;
4458  struct nk_vec2i a;
4459  struct nk_vec2i b;
4460  struct nk_vec2i c;
4461  struct nk_color color;
4462 };
4463 
4466  struct nk_vec2i a;
4467  struct nk_vec2i b;
4468  struct nk_vec2i c;
4469  struct nk_color color;
4470 };
4471 
4474  short x, y;
4475  unsigned short line_thickness;
4476  unsigned short w, h;
4477  struct nk_color color;
4478 };
4479 
4482  short x, y;
4483  unsigned short w, h;
4484  struct nk_color color;
4485 };
4486 
4489  short cx, cy;
4490  unsigned short r;
4491  unsigned short line_thickness;
4492  float a[2];
4493  struct nk_color color;
4494 };
4495 
4498  short cx, cy;
4499  unsigned short r;
4500  float a[2];
4501  struct nk_color color;
4502 };
4503 
4506  struct nk_color color;
4507  unsigned short line_thickness;
4508  unsigned short point_count;
4509  struct nk_vec2i points[1];
4510 };
4511 
4514  struct nk_color color;
4515  unsigned short point_count;
4516  struct nk_vec2i points[1];
4517 };
4518 
4521  struct nk_color color;
4522  unsigned short line_thickness;
4523  unsigned short point_count;
4524  struct nk_vec2i points[1];
4525 };
4526 
4529  short x, y;
4530  unsigned short w, h;
4531  struct nk_image img;
4532  struct nk_color col;
4533 };
4534 
4535 typedef void (*nk_command_custom_callback)(void *canvas, short x,short y,
4536  unsigned short w, unsigned short h, nk_handle callback_data);
4539  short x, y;
4540  unsigned short w, h;
4543 };
4544 
4547  const struct nk_user_font *font;
4550  short x, y;
4551  unsigned short w, h;
4552  float height;
4553  int length;
4554  char string[1];
4555 };
4556 
4560 };
4561 
4563  struct nk_buffer *base;
4564  struct nk_rect clip;
4568 };
4569 
4570 /* shape outlines */
4571 NK_API void nk_stroke_line(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float line_thickness, struct nk_color);
4572 NK_API void nk_stroke_curve(struct nk_command_buffer*, float, float, float, float, float, float, float, float, float line_thickness, struct nk_color);
4573 NK_API void nk_stroke_rect(struct nk_command_buffer*, struct nk_rect, float rounding, float line_thickness, struct nk_color);
4574 NK_API void nk_stroke_circle(struct nk_command_buffer*, struct nk_rect, float line_thickness, struct nk_color);
4575 NK_API void nk_stroke_arc(struct nk_command_buffer*, float cx, float cy, float radius, float a_min, float a_max, float line_thickness, struct nk_color);
4576 NK_API void nk_stroke_triangle(struct nk_command_buffer*, float, float, float, float, float, float, float line_thichness, struct nk_color);
4577 NK_API void nk_stroke_polyline(struct nk_command_buffer*, float *points, int point_count, float line_thickness, struct nk_color col);
4578 NK_API void nk_stroke_polygon(struct nk_command_buffer*, float*, int point_count, float line_thickness, struct nk_color);
4579 
4580 /* filled shades */
4581 NK_API void nk_fill_rect(struct nk_command_buffer*, struct nk_rect, float rounding, struct nk_color);
4582 NK_API void nk_fill_rect_multi_color(struct nk_command_buffer*, struct nk_rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom);
4583 NK_API void nk_fill_circle(struct nk_command_buffer*, struct nk_rect, struct nk_color);
4584 NK_API void nk_fill_arc(struct nk_command_buffer*, float cx, float cy, float radius, float a_min, float a_max, struct nk_color);
4585 NK_API void nk_fill_triangle(struct nk_command_buffer*, float x0, float y0, float x1, float y1, float x2, float y2, struct nk_color);
4586 NK_API void nk_fill_polygon(struct nk_command_buffer*, float*, int point_count, struct nk_color);
4587 
4588 /* misc */
4589 NK_API void nk_draw_image(struct nk_command_buffer*, struct nk_rect, const struct nk_image*, struct nk_color);
4590 NK_API void nk_draw_text(struct nk_command_buffer*, struct nk_rect, const char *text, int len, const struct nk_user_font*, struct nk_color, struct nk_color);
4591 NK_API void nk_push_scissor(struct nk_command_buffer*, struct nk_rect);
4593 
4594 /* ===============================================================
4595  *
4596  * INPUT
4597  *
4598  * ===============================================================*/
4600  int down;
4601  unsigned int clicked;
4603 };
4604 struct nk_mouse {
4606  struct nk_vec2 pos;
4607  struct nk_vec2 prev;
4608  struct nk_vec2 delta;
4610  unsigned char grab;
4611  unsigned char grabbed;
4612  unsigned char ungrab;
4613 };
4614 
4615 struct nk_key {
4616  int down;
4617  unsigned int clicked;
4618 };
4619 struct nk_keyboard {
4623 };
4624 
4625 struct nk_input {
4627  struct nk_mouse mouse;
4628 };
4629 
4630 NK_API int nk_input_has_mouse_click(const struct nk_input*, enum nk_buttons);
4631 NK_API int nk_input_has_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect);
4632 NK_API int nk_input_has_mouse_click_down_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect, int down);
4633 NK_API int nk_input_is_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect);
4634 NK_API int nk_input_is_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id, struct nk_rect b, int down);
4635 NK_API int nk_input_any_mouse_click_in_rect(const struct nk_input*, struct nk_rect);
4636 NK_API int nk_input_is_mouse_prev_hovering_rect(const struct nk_input*, struct nk_rect);
4637 NK_API int nk_input_is_mouse_hovering_rect(const struct nk_input*, struct nk_rect);
4638 NK_API int nk_input_mouse_clicked(const struct nk_input*, enum nk_buttons, struct nk_rect);
4639 NK_API int nk_input_is_mouse_down(const struct nk_input*, enum nk_buttons);
4640 NK_API int nk_input_is_mouse_pressed(const struct nk_input*, enum nk_buttons);
4641 NK_API int nk_input_is_mouse_released(const struct nk_input*, enum nk_buttons);
4642 NK_API int nk_input_is_key_pressed(const struct nk_input*, enum nk_keys);
4643 NK_API int nk_input_is_key_released(const struct nk_input*, enum nk_keys);
4644 NK_API int nk_input_is_key_down(const struct nk_input*, enum nk_keys);
4645 
4646 /* ===============================================================
4647  *
4648  * DRAW LIST
4649  *
4650  * ===============================================================*/
4651 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
4652 /* The optional vertex buffer draw list provides a 2D drawing context
4653  with antialiasing functionality which takes basic filled or outlined shapes
4654  or a path and outputs vertexes, elements and draw commands.
4655  The actual draw list API is not required to be used directly while using this
4656  library since converting the default library draw command output is done by
4657  just calling `nk_convert` but I decided to still make this library accessible
4658  since it can be useful.
4659 
4660  The draw list is based on a path buffering and polygon and polyline
4661  rendering API which allows a lot of ways to draw 2D content to screen.
4662  In fact it is probably more powerful than needed but allows even more crazy
4663  things than this library provides by default.
4664 */
4665 #ifdef NK_UINT_DRAW_INDEX
4666 typedef nk_uint nk_draw_index;
4667 #else
4668 typedef nk_ushort nk_draw_index;
4669 #endif
4670 enum nk_draw_list_stroke {
4671  NK_STROKE_OPEN = nk_false,
4672  /* build up path has no connection back to the beginning */
4673  NK_STROKE_CLOSED = nk_true
4674  /* build up path has a connection back to the beginning */
4675 };
4676 
4677 enum nk_draw_vertex_layout_attribute {
4678  NK_VERTEX_POSITION,
4679  NK_VERTEX_COLOR,
4680  NK_VERTEX_TEXCOORD,
4681  NK_VERTEX_ATTRIBUTE_COUNT
4682 };
4683 
4684 enum nk_draw_vertex_layout_format {
4685  NK_FORMAT_SCHAR,
4686  NK_FORMAT_SSHORT,
4687  NK_FORMAT_SINT,
4688  NK_FORMAT_UCHAR,
4689  NK_FORMAT_USHORT,
4690  NK_FORMAT_UINT,
4691  NK_FORMAT_FLOAT,
4692  NK_FORMAT_DOUBLE,
4693 
4694 NK_FORMAT_COLOR_BEGIN,
4695  NK_FORMAT_R8G8B8 = NK_FORMAT_COLOR_BEGIN,
4696  NK_FORMAT_R16G15B16,
4697  NK_FORMAT_R32G32B32,
4698 
4699  NK_FORMAT_R8G8B8A8,
4700  NK_FORMAT_B8G8R8A8,
4701  NK_FORMAT_R16G15B16A16,
4702  NK_FORMAT_R32G32B32A32,
4703  NK_FORMAT_R32G32B32A32_FLOAT,
4704  NK_FORMAT_R32G32B32A32_DOUBLE,
4705 
4706  NK_FORMAT_RGB32,
4707  NK_FORMAT_RGBA32,
4708 NK_FORMAT_COLOR_END = NK_FORMAT_RGBA32,
4709  NK_FORMAT_COUNT
4710 };
4711 
4712 #define NK_VERTEX_LAYOUT_END NK_VERTEX_ATTRIBUTE_COUNT,NK_FORMAT_COUNT,0
4713 struct nk_draw_vertex_layout_element {
4714  enum nk_draw_vertex_layout_attribute attribute;
4715  enum nk_draw_vertex_layout_format format;
4716  nk_size offset;
4717 };
4718 
4719 struct nk_draw_command {
4720  unsigned int elem_count;
4721  /* number of elements in the current draw batch */
4722  struct nk_rect clip_rect;
4723  /* current screen clipping rectangle */
4724  nk_handle texture;
4725  /* current texture to set */
4726 #ifdef NK_INCLUDE_COMMAND_USERDATA
4727  nk_handle userdata;
4728 #endif
4729 };
4730 
4731 struct nk_draw_list {
4732  struct nk_rect clip_rect;
4733  struct nk_vec2 circle_vtx[12];
4734  struct nk_convert_config config;
4735 
4736  struct nk_buffer *buffer;
4737  struct nk_buffer *vertices;
4738  struct nk_buffer *elements;
4739 
4740  unsigned int element_count;
4741  unsigned int vertex_count;
4742  unsigned int cmd_count;
4743  nk_size cmd_offset;
4744 
4745  unsigned int path_count;
4746  unsigned int path_offset;
4747 
4748  enum nk_anti_aliasing line_AA;
4749  enum nk_anti_aliasing shape_AA;
4750 
4751 #ifdef NK_INCLUDE_COMMAND_USERDATA
4752  nk_handle userdata;
4753 #endif
4754 };
4755 
4756 /* draw list */
4757 NK_API void nk_draw_list_init(struct nk_draw_list*);
4758 NK_API void nk_draw_list_setup(struct nk_draw_list*, const struct nk_convert_config*, struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements, enum nk_anti_aliasing line_aa,enum nk_anti_aliasing shape_aa);
4759 
4760 /* drawing */
4761 #define nk_draw_list_foreach(cmd, can, b) for((cmd)=nk__draw_list_begin(can, b); (cmd)!=0; (cmd)=nk__draw_list_next(cmd, b, can))
4762 NK_API const struct nk_draw_command* nk__draw_list_begin(const struct nk_draw_list*, const struct nk_buffer*);
4763 NK_API const struct nk_draw_command* nk__draw_list_next(const struct nk_draw_command*, const struct nk_buffer*, const struct nk_draw_list*);
4764 NK_API const struct nk_draw_command* nk__draw_list_end(const struct nk_draw_list*, const struct nk_buffer*);
4765 
4766 /* path */
4767 NK_API void nk_draw_list_path_clear(struct nk_draw_list*);
4768 NK_API void nk_draw_list_path_line_to(struct nk_draw_list*, struct nk_vec2 pos);
4769 NK_API void nk_draw_list_path_arc_to_fast(struct nk_draw_list*, struct nk_vec2 center, float radius, int a_min, int a_max);
4770 NK_API void nk_draw_list_path_arc_to(struct nk_draw_list*, struct nk_vec2 center, float radius, float a_min, float a_max, unsigned int segments);
4771 NK_API void nk_draw_list_path_rect_to(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, float rounding);
4772 NK_API void nk_draw_list_path_curve_to(struct nk_draw_list*, struct nk_vec2 p2, struct nk_vec2 p3, struct nk_vec2 p4, unsigned int num_segments);
4773 NK_API void nk_draw_list_path_fill(struct nk_draw_list*, struct nk_color);
4774 NK_API void nk_draw_list_path_stroke(struct nk_draw_list*, struct nk_color, enum nk_draw_list_stroke closed, float thickness);
4775 
4776 /* stroke */
4777 NK_API void nk_draw_list_stroke_line(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, struct nk_color, float thickness);
4778 NK_API void nk_draw_list_stroke_rect(struct nk_draw_list*, struct nk_rect rect, struct nk_color, float rounding, float thickness);
4779 NK_API void nk_draw_list_stroke_triangle(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, struct nk_vec2 c, struct nk_color, float thickness);
4780 NK_API void nk_draw_list_stroke_circle(struct nk_draw_list*, struct nk_vec2 center, float radius, struct nk_color, unsigned int segs, float thickness);
4781 NK_API void nk_draw_list_stroke_curve(struct nk_draw_list*, struct nk_vec2 p0, struct nk_vec2 cp0, struct nk_vec2 cp1, struct nk_vec2 p1, struct nk_color, unsigned int segments, float thickness);
4782 NK_API void nk_draw_list_stroke_poly_line(struct nk_draw_list*, const struct nk_vec2 *pnts, const unsigned int cnt, struct nk_color, enum nk_draw_list_stroke, float thickness, enum nk_anti_aliasing);
4783 
4784 /* fill */
4785 NK_API void nk_draw_list_fill_rect(struct nk_draw_list*, struct nk_rect rect, struct nk_color, float rounding);
4786 NK_API void nk_draw_list_fill_rect_multi_color(struct nk_draw_list*, struct nk_rect rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom);
4787 NK_API void nk_draw_list_fill_triangle(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, struct nk_vec2 c, struct nk_color);
4788 NK_API void nk_draw_list_fill_circle(struct nk_draw_list*, struct nk_vec2 center, float radius, struct nk_color col, unsigned int segs);
4789 NK_API void nk_draw_list_fill_poly_convex(struct nk_draw_list*, const struct nk_vec2 *points, const unsigned int count, struct nk_color, enum nk_anti_aliasing);
4790 
4791 /* misc */
4792 NK_API void nk_draw_list_add_image(struct nk_draw_list*, struct nk_image texture, struct nk_rect rect, struct nk_color);
4793 NK_API void nk_draw_list_add_text(struct nk_draw_list*, const struct nk_user_font*, struct nk_rect, const char *text, int len, float font_height, struct nk_color);
4794 #ifdef NK_INCLUDE_COMMAND_USERDATA
4795 NK_API void nk_draw_list_push_userdata(struct nk_draw_list*, nk_handle userdata);
4796 #endif
4797 
4798 #endif
4799 
4800 /* ===============================================================
4801  *
4802  * GUI
4803  *
4804  * ===============================================================*/
4808 };
4809 
4811  struct nk_image image;
4812  struct nk_color color;
4813 };
4814 
4818 };
4819 
4821  struct nk_color color;
4823 };
4824 
4826  /* background */
4831 
4832  /* text */
4838 
4839  /* properties */
4840  float border;
4841  float rounding;
4845 
4846  /* optional user callbacks */
4850 };
4851 
4853  /* background */
4858 
4859  /* cursor */
4862 
4863  /* text */
4869 
4870  /* properties */
4873  float spacing;
4874  float border;
4875 
4876  /* optional user callbacks */
4880 };
4881 
4883  /* background (inactive) */
4887 
4888  /* background (active) */
4892 
4893  /* text color (inactive) */
4897 
4898  /* text color (active) */
4904 
4905  /* properties */
4906  float rounding;
4910 
4911  /* optional user callbacks */
4915 };
4916 
4918  /* background */
4923 
4924  /* background bar */
4929 
4930  /* cursor */
4934 
4935  /* properties */
4936  float border;
4937  float rounding;
4938  float bar_height;
4942 
4943  /* optional buttons */
4949 
4950  /* optional user callbacks */
4954 };
4955 
4957  /* background */
4962 
4963  /* cursor */
4968 
4969  /* properties */
4970  float rounding;
4971  float border;
4975 
4976  /* optional user callbacks */
4980 };
4981 
4983  /* background */
4988 
4989  /* cursor */
4994 
4995  /* properties */
4996  float border;
4997  float rounding;
5001 
5002  /* optional buttons */
5008 
5009  /* optional user callbacks */
5013 };
5014 
5016  /* background */
5022 
5023  /* cursor */
5028 
5029  /* text (unselected) */
5033 
5034  /* text (selected) */
5039 
5040  /* properties */
5041  float border;
5042  float rounding;
5047 };
5048 
5050  /* background */
5055 
5056  /* text */
5060 
5061  /* symbols */
5064 
5065  /* properties */
5066  float border;
5067  float rounding;
5069 
5073 
5074  /* optional user callbacks */
5078 };
5079 
5081  /* colors */
5085  struct nk_color color;
5086 
5087  /* properties */
5088  float border;
5089  float rounding;
5091 };
5092 
5094  /* background */
5099 
5100  /* label */
5104 
5105  /* symbol */
5109 
5110  /* button */
5115 
5116  /* properties */
5117  float border;
5118  float rounding;
5122 };
5123 
5125  /* background */
5128  struct nk_color text;
5129 
5130  /* button */
5137 
5138  /* properties */
5139  float border;
5140  float rounding;
5141  float indent;
5144 };
5145 
5149 };
5151  /* background */
5155 
5156  /* button */
5162 
5163  /* title */
5167 
5168  /* properties */
5173 };
5174 
5179 
5188 
5189  float border;
5197 
5198  float rounding;
5202 
5210 };
5211 
5212 struct nk_style {
5213  const struct nk_user_font *font;
5215  const struct nk_cursor *cursor_active;
5218 
5236 };
5237 
5241 
5242 /*==============================================================
5243  * PANEL
5244  * =============================================================*/
5245 #ifndef NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
5246 #define NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS 16
5247 #endif
5248 #ifndef NK_CHART_MAX_SLOT
5249 #define NK_CHART_MAX_SLOT 4
5250 #endif
5251 
5261 };
5266 };
5267 
5270  struct nk_color color;
5272  float min, max, range;
5273  int count;
5274  struct nk_vec2 last;
5275  int index;
5276 };
5277 
5278 struct nk_chart {
5279  int slot;
5280  float x, y, w, h;
5282 };
5283 
5295 };
5298  int index;
5299  float height;
5300  float min_height;
5301  int columns;
5302  const float *ratio;
5303  float item_width;
5306  float filled;
5307  struct nk_rect item;
5310 };
5311 
5317  int active;
5318 };
5319 
5321  float x, y, w, h;
5323 };
5324 
5325 struct nk_panel {
5328  struct nk_rect bounds;
5331  float at_x, at_y, max_x;
5334  float border;
5335  unsigned int has_scrolling;
5336  struct nk_rect clip;
5339  struct nk_chart chart;
5341  struct nk_panel *parent;
5342 };
5343 
5344 /*==============================================================
5345  * WINDOW
5346  * =============================================================*/
5347 #ifndef NK_WINDOW_MAX_NAME
5348 #define NK_WINDOW_MAX_NAME 64
5349 #endif
5350 
5351 struct nk_table;
5355  /* special window type growing up in height while being filled to a certain maximum height */
5357  /* sets window widgets into a read only mode and does not allow input changes */
5359  /* prevents all interaction caused by input to either window or widgets inside */
5361  /* Hides window and stops any window interaction and drawing */
5363  /* Directly closes and frees the window at the end of the frame */
5365  /* marks the window as minimized */
5367  /* Removes read only mode at the end of the window */
5368 };
5369 
5371  struct nk_window *win;
5375  int active;
5376  unsigned combo_count;
5377  unsigned con_count, con_old;
5378  unsigned active_con;
5379  struct nk_rect header;
5380 };
5381 
5384  unsigned int seq;
5385  unsigned int old;
5386  int active, prev;
5387  int cursor;
5389  int sel_end;
5391  unsigned char mode;
5392  unsigned char single_line;
5393 };
5394 
5396  int active, prev;
5398  int length;
5399  int cursor;
5403  unsigned int seq;
5404  unsigned int old;
5405  int state;
5406 };
5407 
5408 struct nk_window {
5409  unsigned int seq;
5413 
5414  struct nk_rect bounds;
5417  struct nk_panel *layout;
5419 
5420  /* persistent widget state */
5424  unsigned int scrolled;
5425 
5426  struct nk_table *tables;
5427  unsigned int table_count;
5428 
5429  /* window list hooks */
5430  struct nk_window *next;
5431  struct nk_window *prev;
5433 };
5434 
5435 /*==============================================================
5436  * STACK
5437  * =============================================================*/
5438 /* The style modifier stack can be used to temporarily change a
5439  * property inside `nk_style`. For example if you want a special
5440  * red button you can temporarily push the old button color onto a stack
5441  * draw the button with a red color and then you just pop the old color
5442  * back from the stack:
5443  *
5444  * nk_style_push_style_item(ctx, &ctx->style.button.normal, nk_style_item_color(nk_rgb(255,0,0)));
5445  * nk_style_push_style_item(ctx, &ctx->style.button.hover, nk_style_item_color(nk_rgb(255,0,0)));
5446  * nk_style_push_style_item(ctx, &ctx->style.button.active, nk_style_item_color(nk_rgb(255,0,0)));
5447  * nk_style_push_vec2(ctx, &cx->style.button.padding, nk_vec2(2,2));
5448  *
5449  * nk_button(...);
5450  *
5451  * nk_style_pop_style_item(ctx);
5452  * nk_style_pop_style_item(ctx);
5453  * nk_style_pop_style_item(ctx);
5454  * nk_style_pop_vec2(ctx);
5455  *
5456  * Nuklear has a stack for style_items, float properties, vector properties,
5457  * flags, colors, fonts and for button_behavior. Each has it's own fixed size stack
5458  * which can be changed at compile time.
5459  */
5460 #ifndef NK_BUTTON_BEHAVIOR_STACK_SIZE
5461 #define NK_BUTTON_BEHAVIOR_STACK_SIZE 8
5462 #endif
5463 
5464 #ifndef NK_FONT_STACK_SIZE
5465 #define NK_FONT_STACK_SIZE 8
5466 #endif
5467 
5468 #ifndef NK_STYLE_ITEM_STACK_SIZE
5469 #define NK_STYLE_ITEM_STACK_SIZE 16
5470 #endif
5471 
5472 #ifndef NK_FLOAT_STACK_SIZE
5473 #define NK_FLOAT_STACK_SIZE 32
5474 #endif
5475 
5476 #ifndef NK_VECTOR_STACK_SIZE
5477 #define NK_VECTOR_STACK_SIZE 16
5478 #endif
5479 
5480 #ifndef NK_FLAGS_STACK_SIZE
5481 #define NK_FLAGS_STACK_SIZE 32
5482 #endif
5483 
5484 #ifndef NK_COLOR_STACK_SIZE
5485 #define NK_COLOR_STACK_SIZE 32
5486 #endif
5487 
5488 #define NK_CONFIGURATION_STACK_TYPE(prefix, name, type)\
5489  struct nk_config_stack_##name##_element {\
5490  prefix##_##type *address;\
5491  prefix##_##type old_value;\
5492  }
5493 #define NK_CONFIG_STACK(type,size)\
5494  struct nk_config_stack_##type {\
5495  int head;\
5496  struct nk_config_stack_##type##_element elements[size];\
5497  }
5498 
5499 #define nk_float float
5500 NK_CONFIGURATION_STACK_TYPE(struct nk, style_item, style_item);
5501 NK_CONFIGURATION_STACK_TYPE(nk ,float, float);
5502 NK_CONFIGURATION_STACK_TYPE(struct nk, vec2, vec2);
5504 NK_CONFIGURATION_STACK_TYPE(struct nk, color, color);
5505 NK_CONFIGURATION_STACK_TYPE(const struct nk, user_font, user_font*);
5506 NK_CONFIGURATION_STACK_TYPE(enum nk, button_behavior, button_behavior);
5507 
5515 
5517  struct nk_config_stack_style_item style_items;
5518  struct nk_config_stack_float floats;
5519  struct nk_config_stack_vec2 vectors;
5520  struct nk_config_stack_flags flags;
5521  struct nk_config_stack_color colors;
5522  struct nk_config_stack_user_font fonts;
5523  struct nk_config_stack_button_behavior button_behaviors;
5524 };
5525 
5526 /*==============================================================
5527  * CONTEXT
5528  * =============================================================*/
5529 #define NK_VALUE_PAGE_CAPACITY \
5530  (((NK_MAX(sizeof(struct nk_window),sizeof(struct nk_panel)) / sizeof(nk_uint))) / 2)
5531 
5532 struct nk_table {
5533  unsigned int seq;
5534  unsigned int size;
5537  struct nk_table *next, *prev;
5538 };
5539 
5541  struct nk_table tbl;
5542  struct nk_panel pan;
5543  struct nk_window win;
5544 };
5545 
5550 };
5551 
5552 struct nk_page {
5553  unsigned int size;
5554  struct nk_page *next;
5556 };
5557 
5558 struct nk_pool {
5561  unsigned int page_count;
5562  struct nk_page *pages;
5564  unsigned capacity;
5567 };
5568 
5569 struct nk_context {
5570 /* public: can be accessed freely */
5571  struct nk_input input;
5572  struct nk_style style;
5579 
5580 /* private:
5581  should only be accessed if you
5582  know what you are doing */
5583 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
5584  struct nk_draw_list draw_list;
5585 #endif
5586 #ifdef NK_INCLUDE_COMMAND_USERDATA
5587  nk_handle userdata;
5588 #endif
5589  /* text editor objects are quite big because of an internal
5590  * undo/redo stack. Therefore it does not make sense to have one for
5591  * each window for temporary use cases, so I only provide *one* instance
5592  * for all windows. This works because the content is cleared anyway */
5594  /* draw buffer used for overlay drawing operation like cursor */
5596 
5597  /* windows */
5598  int build;
5600  struct nk_pool pool;
5601  struct nk_window *begin;
5602  struct nk_window *end;
5606  unsigned int count;
5607  unsigned int seq;
5608 };
5609 
5610 /* ==============================================================
5611  * MATH
5612  * =============================================================== */
5613 #define NK_PI 3.141592654f
5614 #define NK_UTF_INVALID 0xFFFD
5615 #define NK_MAX_FLOAT_PRECISION 2
5616 
5617 #define NK_UNUSED(x) ((void)(x))
5618 #define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
5619 #define NK_LEN(a) (sizeof(a)/sizeof(a)[0])
5620 #define NK_ABS(a) (((a) < 0) ? -(a) : (a))
5621 #define NK_BETWEEN(x, a, b) ((a) <= (x) && (x) < (b))
5622 #define NK_INBOX(px, py, x, y, w, h)\
5623  (NK_BETWEEN(px,x,x+w) && NK_BETWEEN(py,y,y+h))
5624 #define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1) \
5625  (!(((x1 > (x0 + w0)) || ((x1 + w1) < x0) || (y1 > (y0 + h0)) || (y1 + h1) < y0)))
5626 #define NK_CONTAINS(x, y, w, h, bx, by, bw, bh)\
5627  (NK_INBOX(x,y, bx, by, bw, bh) && NK_INBOX(x+w,y+h, bx, by, bw, bh))
5628 
5629 #define nk_vec2_sub(a, b) nk_vec2((a).x - (b).x, (a).y - (b).y)
5630 #define nk_vec2_add(a, b) nk_vec2((a).x + (b).x, (a).y + (b).y)
5631 #define nk_vec2_len_sqr(a) ((a).x*(a).x+(a).y*(a).y)
5632 #define nk_vec2_muls(a, t) nk_vec2((a).x * (t), (a).y * (t))
5633 
5634 #define nk_ptr_add(t, p, i) ((t*)((void*)((nk_byte*)(p) + (i))))
5635 #define nk_ptr_add_const(t, p, i) ((const t*)((const void*)((const nk_byte*)(p) + (i))))
5636 #define nk_zero_struct(s) nk_zero(&s, sizeof(s))
5637 
5638 /* ==============================================================
5639  * ALIGNMENT
5640  * =============================================================== */
5641 /* Pointer to Integer type conversion for pointer alignment */
5642 #if defined(__PTRDIFF_TYPE__) /* This case should work for GCC*/
5643 # define NK_UINT_TO_PTR(x) ((void*)(__PTRDIFF_TYPE__)(x))
5644 # define NK_PTR_TO_UINT(x) ((nk_size)(__PTRDIFF_TYPE__)(x))
5645 #elif !defined(__GNUC__) /* works for compilers other than LLVM */
5646 # define NK_UINT_TO_PTR(x) ((void*)&((char*)0)[x])
5647 # define NK_PTR_TO_UINT(x) ((nk_size)(((char*)x)-(char*)0))
5648 #elif defined(NK_USE_FIXED_TYPES) /* used if we have <stdint.h> */
5649 # define NK_UINT_TO_PTR(x) ((void*)(uintptr_t)(x))
5650 # define NK_PTR_TO_UINT(x) ((uintptr_t)(x))
5651 #else /* generates warning but works */
5652 # define NK_UINT_TO_PTR(x) ((void*)(x))
5653 # define NK_PTR_TO_UINT(x) ((nk_size)(x))
5654 #endif
5655 
5656 #define NK_ALIGN_PTR(x, mask)\
5657  (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x) + (mask-1)) & ~(mask-1))))
5658 #define NK_ALIGN_PTR_BACK(x, mask)\
5659  (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x)) & ~(mask-1))))
5660 
5661 #define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m))
5662 #define NK_CONTAINER_OF(ptr,type,member)\
5663  (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))
5664 
5665 #ifdef __cplusplus
5666 }
5667 #endif
5668 
5669 #ifdef __cplusplus
5670 template<typename T> struct nk_alignof;
5671 template<typename T, int size_diff> struct nk_helper{enum {value = size_diff};};
5672 template<typename T> struct nk_helper<T,0>{enum {value = nk_alignof<T>::value};};
5673 template<typename T> struct nk_alignof{struct Big {T x; char c;}; enum {
5674  diff = sizeof(Big) - sizeof(T), value = nk_helper<Big, diff>::value};};
5675 #define NK_ALIGNOF(t) (nk_alignof<t>::value)
5676 #elif defined(_MSC_VER)
5677 #define NK_ALIGNOF(t) (__alignof(t))
5678 #else
5679 #define NK_ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0)
5680 #endif
5681 
5682 #endif /* NK_NUKLEAR_H_ */
5683 
5684 #ifdef NK_IMPLEMENTATION
5685 
5686 #ifndef NK_INTERNAL_H
5687 #define NK_INTERNAL_H
5688 
5689 #ifndef NK_POOL_DEFAULT_CAPACITY
5690 #define NK_POOL_DEFAULT_CAPACITY 16
5691 #endif
5692 
5693 #ifndef NK_DEFAULT_COMMAND_BUFFER_SIZE
5694 #define NK_DEFAULT_COMMAND_BUFFER_SIZE (4*1024)
5695 #endif
5696 
5697 #ifndef NK_BUFFER_DEFAULT_INITIAL_SIZE
5698 #define NK_BUFFER_DEFAULT_INITIAL_SIZE (4*1024)
5699 #endif
5700 
5701 /* standard library headers */
5702 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
5703 #include <stdlib.h> /* malloc, free */
5704 #endif
5705 #ifdef NK_INCLUDE_STANDARD_IO
5706 #include <stdio.h> /* fopen, fclose,... */
5707 #endif
5708 #ifdef NK_INCLUDE_STANDARD_VARARGS
5709 #include <stdarg.h> /* valist, va_start, va_end, ... */
5710 #endif
5711 #ifndef NK_ASSERT
5712 #include <assert.h>
5713 #define NK_ASSERT(expr) assert(expr)
5714 #endif
5715 
5716 #ifndef NK_MEMSET
5717 #define NK_MEMSET nk_memset
5718 #endif
5719 #ifndef NK_MEMCPY
5720 #define NK_MEMCPY nk_memcopy
5721 #endif
5722 #ifndef NK_SQRT
5723 #define NK_SQRT nk_sqrt
5724 #endif
5725 #ifndef NK_SIN
5726 #define NK_SIN nk_sin
5727 #endif
5728 #ifndef NK_COS
5729 #define NK_COS nk_cos
5730 #endif
5731 #ifndef NK_STRTOD
5732 #define NK_STRTOD nk_strtod
5733 #endif
5734 #ifndef NK_DTOA
5735 #define NK_DTOA nk_dtoa
5736 #endif
5737 
5738 #define NK_DEFAULT (-1)
5739 
5740 #ifndef NK_VSNPRINTF
5741 /* If your compiler does support `vsnprintf` I would highly recommend
5742  * defining this to vsnprintf instead since `vsprintf` is basically
5743  * unbelievable unsafe and should *NEVER* be used. But I have to support
5744  * it since C89 only provides this unsafe version. */
5745  #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) ||\
5746  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
5747  (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) ||\
5748  (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) ||\
5749  defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE)
5750  #define NK_VSNPRINTF(s,n,f,a) vsnprintf(s,n,f,a)
5751  #else
5752  #define NK_VSNPRINTF(s,n,f,a) vsprintf(s,f,a)
5753  #endif
5754 #endif
5755 
5756 #define NK_SCHAR_MIN (-127)
5757 #define NK_SCHAR_MAX 127
5758 #define NK_UCHAR_MIN 0
5759 #define NK_UCHAR_MAX 256
5760 #define NK_SSHORT_MIN (-32767)
5761 #define NK_SSHORT_MAX 32767
5762 #define NK_USHORT_MIN 0
5763 #define NK_USHORT_MAX 65535
5764 #define NK_SINT_MIN (-2147483647)
5765 #define NK_SINT_MAX 2147483647
5766 #define NK_UINT_MIN 0
5767 #define NK_UINT_MAX 4294967295u
5768 
5769 /* Make sure correct type size:
5770  * This will fire with a negative subscript error if the type sizes
5771  * are set incorrectly by the compiler, and compile out if not */
5772 NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
5773 NK_STATIC_ASSERT(sizeof(nk_ptr) == sizeof(void*));
5774 NK_STATIC_ASSERT(sizeof(nk_flags) >= 4);
5775 NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
5776 NK_STATIC_ASSERT(sizeof(nk_ushort) == 2);
5777 NK_STATIC_ASSERT(sizeof(nk_short) == 2);
5778 NK_STATIC_ASSERT(sizeof(nk_uint) == 4);
5779 NK_STATIC_ASSERT(sizeof(nk_int) == 4);
5780 NK_STATIC_ASSERT(sizeof(nk_byte) == 1);
5781 
5782 NK_GLOBAL const struct nk_rect nk_null_rect = {-8192.0f, -8192.0f, 16384, 16384};
5783 #define NK_FLOAT_PRECISION 0.00000000000001
5784 
5785 NK_GLOBAL const struct nk_color nk_red = {255,0,0,255};
5786 NK_GLOBAL const struct nk_color nk_green = {0,255,0,255};
5787 NK_GLOBAL const struct nk_color nk_blue = {0,0,255,255};
5788 NK_GLOBAL const struct nk_color nk_white = {255,255,255,255};
5789 NK_GLOBAL const struct nk_color nk_black = {0,0,0,255};
5790 NK_GLOBAL const struct nk_color nk_yellow = {255,255,0,255};
5791 
5792 /* widget */
5793 #define nk_widget_state_reset(s)\
5794  if ((*(s)) & NK_WIDGET_STATE_MODIFIED)\
5795  (*(s)) = NK_WIDGET_STATE_INACTIVE|NK_WIDGET_STATE_MODIFIED;\
5796  else (*(s)) = NK_WIDGET_STATE_INACTIVE;
5797 
5798 /* math */
5799 NK_LIB float nk_inv_sqrt(float n);
5800 NK_LIB float nk_sqrt(float x);
5801 NK_LIB float nk_sin(float x);
5802 NK_LIB float nk_cos(float x);
5803 NK_LIB nk_uint nk_round_up_pow2(nk_uint v);
5804 NK_LIB struct nk_rect nk_shrink_rect(struct nk_rect r, float amount);
5805 NK_LIB struct nk_rect nk_pad_rect(struct nk_rect r, struct nk_vec2 pad);
5806 NK_LIB void nk_unify(struct nk_rect *clip, const struct nk_rect *a, float x0, float y0, float x1, float y1);
5807 NK_LIB double nk_pow(double x, int n);
5808 NK_LIB int nk_ifloord(double x);
5809 NK_LIB int nk_ifloorf(float x);
5810 NK_LIB int nk_iceilf(float x);
5811 NK_LIB int nk_log10(double n);
5812 
5813 /* util */
5814 enum {NK_DO_NOT_STOP_ON_NEW_LINE, NK_STOP_ON_NEW_LINE};
5815 NK_LIB int nk_is_lower(int c);
5816 NK_LIB int nk_is_upper(int c);
5817 NK_LIB int nk_to_upper(int c);
5818 NK_LIB int nk_to_lower(int c);
5819 NK_LIB void* nk_memcopy(void *dst, const void *src, nk_size n);
5820 NK_LIB void nk_memset(void *ptr, int c0, nk_size size);
5821 NK_LIB void nk_zero(void *ptr, nk_size size);
5822 NK_LIB char *nk_itoa(char *s, long n);
5823 NK_LIB int nk_string_float_limit(char *string, int prec);
5824 NK_LIB char *nk_dtoa(char *s, double n);
5825 NK_LIB int nk_text_clamp(const struct nk_user_font *font, const char *text, int text_len, float space, int *glyphs, float *text_width, nk_rune *sep_list, int sep_count);
5826 NK_LIB struct nk_vec2 nk_text_calculate_text_bounds(const struct nk_user_font *font, const char *begin, int byte_len, float row_height, const char **remaining, struct nk_vec2 *out_offset, int *glyphs, int op);
5827 #ifdef NK_INCLUDE_STANDARD_VARARGS
5828 NK_LIB int nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args);
5829 #endif
5830 #ifdef NK_INCLUDE_STANDARD_IO
5831 NK_LIB char *nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc);
5832 #endif
5833 
5834 /* buffer */
5835 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
5836 NK_LIB void* nk_malloc(nk_handle unused, void *old,nk_size size);
5837 NK_LIB void nk_mfree(nk_handle unused, void *ptr);
5838 #endif
5839 NK_LIB void* nk_buffer_align(void *unaligned, nk_size align, nk_size *alignment, enum nk_buffer_allocation_type type);
5840 NK_LIB void* nk_buffer_alloc(struct nk_buffer *b, enum nk_buffer_allocation_type type, nk_size size, nk_size align);
5841 NK_LIB void* nk_buffer_realloc(struct nk_buffer *b, nk_size capacity, nk_size *size);
5842 
5843 /* draw */
5844 NK_LIB void nk_command_buffer_init(struct nk_command_buffer *cb, struct nk_buffer *b, enum nk_command_clipping clip);
5845 NK_LIB void nk_command_buffer_reset(struct nk_command_buffer *b);
5846 NK_LIB void* nk_command_buffer_push(struct nk_command_buffer* b, enum nk_command_type t, nk_size size);
5847 NK_LIB void nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type, struct nk_rect content, struct nk_color background, struct nk_color foreground, float border_width, const struct nk_user_font *font);
5848 
5849 /* buffering */
5850 NK_LIB void nk_start_buffer(struct nk_context *ctx, struct nk_command_buffer *b);
5851 NK_LIB void nk_start(struct nk_context *ctx, struct nk_window *win);
5852 NK_LIB void nk_start_popup(struct nk_context *ctx, struct nk_window *win);
5853 NK_LIB void nk_finish_popup(struct nk_context *ctx, struct nk_window*);
5854 NK_LIB void nk_finish_buffer(struct nk_context *ctx, struct nk_command_buffer *b);
5855 NK_LIB void nk_finish(struct nk_context *ctx, struct nk_window *w);
5856 NK_LIB void nk_build(struct nk_context *ctx);
5857 
5858 /* text editor */
5859 NK_LIB void nk_textedit_clear_state(struct nk_text_edit *state, enum nk_text_edit_type type, nk_plugin_filter filter);
5860 NK_LIB void nk_textedit_click(struct nk_text_edit *state, float x, float y, const struct nk_user_font *font, float row_height);
5861 NK_LIB void nk_textedit_drag(struct nk_text_edit *state, float x, float y, const struct nk_user_font *font, float row_height);
5862 NK_LIB void nk_textedit_key(struct nk_text_edit *state, enum nk_keys key, int shift_mod, const struct nk_user_font *font, float row_height);
5863 
5864 /* window */
5865 enum nk_window_insert_location {
5866  NK_INSERT_BACK, /* inserts window into the back of list (front of screen) */
5867  NK_INSERT_FRONT /* inserts window into the front of list (back of screen) */
5868 };
5869 NK_LIB void *nk_create_window(struct nk_context *ctx);
5870 NK_LIB void nk_remove_window(struct nk_context*, struct nk_window*);
5871 NK_LIB void nk_free_window(struct nk_context *ctx, struct nk_window *win);
5872 NK_LIB struct nk_window *nk_find_window(struct nk_context *ctx, nk_hash hash, const char *name);
5873 NK_LIB void nk_insert_window(struct nk_context *ctx, struct nk_window *win, enum nk_window_insert_location loc);
5874 
5875 /* pool */
5876 NK_LIB void nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc, unsigned int capacity);
5877 NK_LIB void nk_pool_free(struct nk_pool *pool);
5878 NK_LIB void nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size);
5879 NK_LIB struct nk_page_element *nk_pool_alloc(struct nk_pool *pool);
5880 
5881 /* page-element */
5882 NK_LIB struct nk_page_element* nk_create_page_element(struct nk_context *ctx);
5883 NK_LIB void nk_link_page_element_into_freelist(struct nk_context *ctx, struct nk_page_element *elem);
5884 NK_LIB void nk_free_page_element(struct nk_context *ctx, struct nk_page_element *elem);
5885 
5886 /* table */
5887 NK_LIB struct nk_table* nk_create_table(struct nk_context *ctx);
5888 NK_LIB void nk_remove_table(struct nk_window *win, struct nk_table *tbl);
5889 NK_LIB void nk_free_table(struct nk_context *ctx, struct nk_table *tbl);
5890 NK_LIB void nk_push_table(struct nk_window *win, struct nk_table *tbl);
5891 NK_LIB nk_uint *nk_add_value(struct nk_context *ctx, struct nk_window *win, nk_hash name, nk_uint value);
5892 NK_LIB nk_uint *nk_find_value(struct nk_window *win, nk_hash name);
5893 
5894 /* panel */
5895 NK_LIB void *nk_create_panel(struct nk_context *ctx);
5896 NK_LIB void nk_free_panel(struct nk_context*, struct nk_panel *pan);
5897 NK_LIB int nk_panel_has_header(nk_flags flags, const char *title);
5898 NK_LIB struct nk_vec2 nk_panel_get_padding(const struct nk_style *style, enum nk_panel_type type);
5899 NK_LIB float nk_panel_get_border(const struct nk_style *style, nk_flags flags, enum nk_panel_type type);
5900 NK_LIB struct nk_color nk_panel_get_border_color(const struct nk_style *style, enum nk_panel_type type);
5901 NK_LIB int nk_panel_is_sub(enum nk_panel_type type);
5902 NK_LIB int nk_panel_is_nonblock(enum nk_panel_type type);
5903 NK_LIB int nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type panel_type);
5904 NK_LIB void nk_panel_end(struct nk_context *ctx);
5905 
5906 /* layout */
5907 NK_LIB float nk_layout_row_calculate_usable_space(const struct nk_style *style, enum nk_panel_type type, float total_space, int columns);
5908 NK_LIB void nk_panel_layout(const struct nk_context *ctx, struct nk_window *win, float height, int cols);
5909 NK_LIB void nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt, float height, int cols, int width);
5910 NK_LIB void nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win);
5911 NK_LIB void nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx, struct nk_window *win, int modify);
5912 NK_LIB void nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx);
5913 NK_LIB void nk_layout_peek(struct nk_rect *bounds, struct nk_context *ctx);
5914 
5915 /* popup */
5916 NK_LIB int nk_nonblock_begin(struct nk_context *ctx, nk_flags flags, struct nk_rect body, struct nk_rect header, enum nk_panel_type panel_type);
5917 
5918 /* text */
5919 struct nk_text {
5920  struct nk_vec2 padding;
5921  struct nk_color background;
5922  struct nk_color text;
5923 };
5924 NK_LIB void nk_widget_text(struct nk_command_buffer *o, struct nk_rect b, const char *string, int len, const struct nk_text *t, nk_flags a, const struct nk_user_font *f);
5925 NK_LIB void nk_widget_text_wrap(struct nk_command_buffer *o, struct nk_rect b, const char *string, int len, const struct nk_text *t, const struct nk_user_font *f);
5926 
5927 /* button */
5928 NK_LIB int nk_button_behavior(nk_flags *state, struct nk_rect r, const struct nk_input *i, enum nk_button_behavior behavior);
5929 NK_LIB const struct nk_style_item* nk_draw_button(struct nk_command_buffer *out, const struct nk_rect *bounds, nk_flags state, const struct nk_style_button *style);
5930 NK_LIB int nk_do_button(nk_flags *state, struct nk_command_buffer *out, struct nk_rect r, const struct nk_style_button *style, const struct nk_input *in, enum nk_button_behavior behavior, struct nk_rect *content);
5931 NK_LIB void nk_draw_button_text(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state, const struct nk_style_button *style, const char *txt, int len, nk_flags text_alignment, const struct nk_user_font *font);
5932 NK_LIB int nk_do_button_text(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, const char *string, int len, nk_flags align, enum nk_button_behavior behavior, const struct nk_style_button *style, const struct nk_input *in, const struct nk_user_font *font);
5933 NK_LIB void nk_draw_button_symbol(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state, const struct nk_style_button *style, enum nk_symbol_type type, const struct nk_user_font *font);
5934 NK_LIB int nk_do_button_symbol(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, enum nk_symbol_type symbol, enum nk_button_behavior behavior, const struct nk_style_button *style, const struct nk_input *in, const struct nk_user_font *font);
5935 NK_LIB void nk_draw_button_image(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state, const struct nk_style_button *style, const struct nk_image *img);
5936 NK_LIB int nk_do_button_image(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, struct nk_image img, enum nk_button_behavior b, const struct nk_style_button *style, const struct nk_input *in);
5937 NK_LIB void nk_draw_button_text_symbol(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *label, const struct nk_rect *symbol, nk_flags state, const struct nk_style_button *style, const char *str, int len, enum nk_symbol_type type, const struct nk_user_font *font);
5938 NK_LIB int nk_do_button_text_symbol(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, enum nk_symbol_type symbol, const char *str, int len, nk_flags align, enum nk_button_behavior behavior, const struct nk_style_button *style, const struct nk_user_font *font, const struct nk_input *in);
5939 NK_LIB void nk_draw_button_text_image(struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *label, const struct nk_rect *image, nk_flags state, const struct nk_style_button *style, const char *str, int len, const struct nk_user_font *font, const struct nk_image *img);
5940 NK_LIB int nk_do_button_text_image(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, struct nk_image img, const char* str, int len, nk_flags align, enum nk_button_behavior behavior, const struct nk_style_button *style, const struct nk_user_font *font, const struct nk_input *in);
5941 
5942 /* toggle */
5943 enum nk_toggle_type {
5944  NK_TOGGLE_CHECK,
5945  NK_TOGGLE_OPTION
5946 };
5947 NK_LIB int nk_toggle_behavior(const struct nk_input *in, struct nk_rect select, nk_flags *state, int active);
5948 NK_LIB void nk_draw_checkbox(struct nk_command_buffer *out, nk_flags state, const struct nk_style_toggle *style, int active, const struct nk_rect *label, const struct nk_rect *selector, const struct nk_rect *cursors, const char *string, int len, const struct nk_user_font *font);
5949 NK_LIB void nk_draw_option(struct nk_command_buffer *out, nk_flags state, const struct nk_style_toggle *style, int active, const struct nk_rect *label, const struct nk_rect *selector, const struct nk_rect *cursors, const char *string, int len, const struct nk_user_font *font);
5950 NK_LIB int nk_do_toggle(nk_flags *state, struct nk_command_buffer *out, struct nk_rect r, int *active, const char *str, int len, enum nk_toggle_type type, const struct nk_style_toggle *style, const struct nk_input *in, const struct nk_user_font *font);
5951 
5952 /* progress */
5953 NK_LIB nk_size nk_progress_behavior(nk_flags *state, struct nk_input *in, struct nk_rect r, struct nk_rect cursor, nk_size max, nk_size value, int modifiable);
5954 NK_LIB void nk_draw_progress(struct nk_command_buffer *out, nk_flags state, const struct nk_style_progress *style, const struct nk_rect *bounds, const struct nk_rect *scursor, nk_size value, nk_size max);
5955 NK_LIB nk_size nk_do_progress(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, nk_size value, nk_size max, int modifiable, const struct nk_style_progress *style, struct nk_input *in);
5956 
5957 /* slider */
5958 NK_LIB float nk_slider_behavior(nk_flags *state, struct nk_rect *logical_cursor, struct nk_rect *visual_cursor, struct nk_input *in, struct nk_rect bounds, float slider_min, float slider_max, float slider_value, float slider_step, float slider_steps);
5959 NK_LIB void nk_draw_slider(struct nk_command_buffer *out, nk_flags state, const struct nk_style_slider *style, const struct nk_rect *bounds, const struct nk_rect *visual_cursor, float min, float value, float max);
5960 NK_LIB float nk_do_slider(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, float min, float val, float max, float step, const struct nk_style_slider *style, struct nk_input *in, const struct nk_user_font *font);
5961 
5962 /* scrollbar */
5963 NK_LIB float nk_scrollbar_behavior(nk_flags *state, struct nk_input *in, int has_scrolling, const struct nk_rect *scroll, const struct nk_rect *cursor, const struct nk_rect *empty0, const struct nk_rect *empty1, float scroll_offset, float target, float scroll_step, enum nk_orientation o);
5964 NK_LIB void nk_draw_scrollbar(struct nk_command_buffer *out, nk_flags state, const struct nk_style_scrollbar *style, const struct nk_rect *bounds, const struct nk_rect *scroll);
5965 NK_LIB float nk_do_scrollbarv(nk_flags *state, struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling, float offset, float target, float step, float button_pixel_inc, const struct nk_style_scrollbar *style, struct nk_input *in, const struct nk_user_font *font);
5966 NK_LIB float nk_do_scrollbarh(nk_flags *state, struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling, float offset, float target, float step, float button_pixel_inc, const struct nk_style_scrollbar *style, struct nk_input *in, const struct nk_user_font *font);
5967 
5968 /* selectable */
5969 NK_LIB void nk_draw_selectable(struct nk_command_buffer *out, nk_flags state, const struct nk_style_selectable *style, int active, const struct nk_rect *bounds, const struct nk_rect *icon, const struct nk_image *img, enum nk_symbol_type sym, const char *string, int len, nk_flags align, const struct nk_user_font *font);
5970 NK_LIB int nk_do_selectable(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, const char *str, int len, nk_flags align, int *value, const struct nk_style_selectable *style, const struct nk_input *in, const struct nk_user_font *font);
5971 NK_LIB int nk_do_selectable_image(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, const char *str, int len, nk_flags align, int *value, const struct nk_image *img, const struct nk_style_selectable *style, const struct nk_input *in, const struct nk_user_font *font);
5972 
5973 /* edit */
5974 NK_LIB void nk_edit_draw_text(struct nk_command_buffer *out, const struct nk_style_edit *style, float pos_x, float pos_y, float x_offset, const char *text, int byte_len, float row_height, const struct nk_user_font *font, struct nk_color background, struct nk_color foreground, int is_selected);
5975 NK_LIB nk_flags nk_do_edit(nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, nk_flags flags, nk_plugin_filter filter, struct nk_text_edit *edit, const struct nk_style_edit *style, struct nk_input *in, const struct nk_user_font *font);
5976 
5977 /* color-picker */
5978 NK_LIB int nk_color_picker_behavior(nk_flags *state, const struct nk_rect *bounds, const struct nk_rect *matrix, const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar, struct nk_colorf *color, const struct nk_input *in);
5979 NK_LIB void nk_draw_color_picker(struct nk_command_buffer *o, const struct nk_rect *matrix, const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar, struct nk_colorf col);
5980 NK_LIB int nk_do_color_picker(nk_flags *state, struct nk_command_buffer *out, struct nk_colorf *col, enum nk_color_format fmt, struct nk_rect bounds, struct nk_vec2 padding, const struct nk_input *in, const struct nk_user_font *font);
5981 
5982 /* property */
5983 enum nk_property_status {
5984  NK_PROPERTY_DEFAULT,
5985  NK_PROPERTY_EDIT,
5986  NK_PROPERTY_DRAG
5987 };
5988 enum nk_property_filter {
5989  NK_FILTER_INT,
5990  NK_FILTER_FLOAT
5991 };
5992 enum nk_property_kind {
5993  NK_PROPERTY_INT,
5994  NK_PROPERTY_FLOAT,
5995  NK_PROPERTY_DOUBLE
5996 };
5997 union nk_property {
5998  int i;
5999  float f;
6000  double d;
6001 };
6002 struct nk_property_variant {
6003  enum nk_property_kind kind;
6004  union nk_property value;
6005  union nk_property min_value;
6006  union nk_property max_value;
6007  union nk_property step;
6008 };
6009 NK_LIB struct nk_property_variant nk_property_variant_int(int value, int min_value, int max_value, int step);
6010 NK_LIB struct nk_property_variant nk_property_variant_float(float value, float min_value, float max_value, float step);
6011 NK_LIB struct nk_property_variant nk_property_variant_double(double value, double min_value, double max_value, double step);
6012 
6013 NK_LIB void nk_drag_behavior(nk_flags *state, const struct nk_input *in, struct nk_rect drag, struct nk_property_variant *variant, float inc_per_pixel);
6014 NK_LIB void nk_property_behavior(nk_flags *ws, const struct nk_input *in, struct nk_rect property, struct nk_rect label, struct nk_rect edit, struct nk_rect empty, int *state, struct nk_property_variant *variant, float inc_per_pixel);
6015 NK_LIB void nk_draw_property(struct nk_command_buffer *out, const struct nk_style_property *style, const struct nk_rect *bounds, const struct nk_rect *label, nk_flags state, const char *name, int len, const struct nk_user_font *font);
6016 NK_LIB void nk_do_property(nk_flags *ws, struct nk_command_buffer *out, struct nk_rect property, const char *name, struct nk_property_variant *variant, float inc_per_pixel, char *buffer, int *len, int *state, int *cursor, int *select_begin, int *select_end, const struct nk_style_property *style, enum nk_property_filter filter, struct nk_input *in, const struct nk_user_font *font, struct nk_text_edit *text_edit, enum nk_button_behavior behavior);
6017 NK_LIB void nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant *variant, float inc_per_pixel, const enum nk_property_filter filter);
6018 
6019 #endif
6020 
6021 
6022 
6023 
6024 
6025 /* ===============================================================
6026  *
6027  * MATH
6028  *
6029  * ===============================================================*/
6030 /* Since nuklear is supposed to work on all systems providing floating point
6031  math without any dependencies I also had to implement my own math functions
6032  for sqrt, sin and cos. Since the actual highly accurate implementations for
6033  the standard library functions are quite complex and I do not need high
6034  precision for my use cases I use approximations.
6035 
6036  Sqrt
6037  ----
6038  For square root nuklear uses the famous fast inverse square root:
6039  https://en.wikipedia.org/wiki/Fast_inverse_square_root with
6040  slightly tweaked magic constant. While on today's hardware it is
6041  probably not faster it is still fast and accurate enough for
6042  nuklear's use cases. IMPORTANT: this requires float format IEEE 754
6043 
6044  Sine/Cosine
6045  -----------
6046  All constants inside both function are generated Remez's minimax
6047  approximations for value range 0...2*PI. The reason why I decided to
6048  approximate exactly that range is that nuklear only needs sine and
6049  cosine to generate circles which only requires that exact range.
6050  In addition I used Remez instead of Taylor for additional precision:
6051  www.lolengine.net/blog/2011/12/21/better-function-approximations.
6052 
6053  The tool I used to generate constants for both sine and cosine
6054  (it can actually approximate a lot more functions) can be
6055  found here: www.lolengine.net/wiki/oss/lolremez
6056 */
6057 NK_LIB float
6058 nk_inv_sqrt(float n)
6059 {
6060  float x2;
6061  const float threehalfs = 1.5f;
6062  union {nk_uint i; float f;} conv = {0};
6063  conv.f = n;
6064  x2 = n * 0.5f;
6065  conv.i = 0x5f375A84 - (conv.i >> 1);
6066  conv.f = conv.f * (threehalfs - (x2 * conv.f * conv.f));
6067  return conv.f;
6068 }
6069 NK_LIB float
6070 nk_sqrt(float x)
6071 {
6072  return x * nk_inv_sqrt(x);
6073 }
6074 NK_LIB float
6075 nk_sin(float x)
6076 {
6077  NK_STORAGE const float a0 = +1.91059300966915117e-31f;
6078  NK_STORAGE const float a1 = +1.00086760103908896f;
6079  NK_STORAGE const float a2 = -1.21276126894734565e-2f;
6080  NK_STORAGE const float a3 = -1.38078780785773762e-1f;
6081  NK_STORAGE const float a4 = -2.67353392911981221e-2f;
6082  NK_STORAGE const float a5 = +2.08026600266304389e-2f;
6083  NK_STORAGE const float a6 = -3.03996055049204407e-3f;
6084  NK_STORAGE const float a7 = +1.38235642404333740e-4f;
6085  return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7))))));
6086 }
6087 NK_LIB float
6088 nk_cos(float x)
6089 {
6090  /* New implementation. Also generated using lolremez. */
6091  /* Old version significantly deviated from expected results. */
6092  NK_STORAGE const float a0 = 9.9995999154986614e-1f;
6093  NK_STORAGE const float a1 = 1.2548995793001028e-3f;
6094  NK_STORAGE const float a2 = -5.0648546280678015e-1f;
6095  NK_STORAGE const float a3 = 1.2942246466519995e-2f;
6096  NK_STORAGE const float a4 = 2.8668384702547972e-2f;
6097  NK_STORAGE const float a5 = 7.3726485210586547e-3f;
6098  NK_STORAGE const float a6 = -3.8510875386947414e-3f;
6099  NK_STORAGE const float a7 = 4.7196604604366623e-4f;
6100  NK_STORAGE const float a8 = -1.8776444013090451e-5f;
6101  return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*(a7 + x*a8)))))));
6102 }
6104 nk_round_up_pow2(nk_uint v)
6105 {
6106  v--;
6107  v |= v >> 1;
6108  v |= v >> 2;
6109  v |= v >> 4;
6110  v |= v >> 8;
6111  v |= v >> 16;
6112  v++;
6113  return v;
6114 }
6115 NK_LIB double
6116 nk_pow(double x, int n)
6117 {
6118  /* check the sign of n */
6119  double r = 1;
6120  int plus = n >= 0;
6121  n = (plus) ? n : -n;
6122  while (n > 0) {
6123  if ((n & 1) == 1)
6124  r *= x;
6125  n /= 2;
6126  x *= x;
6127  }
6128  return plus ? r : 1.0 / r;
6129 }
6130 NK_LIB int
6131 nk_ifloord(double x)
6132 {
6133  x = (double)((int)x - ((x < 0.0) ? 1 : 0));
6134  return (int)x;
6135 }
6136 NK_LIB int
6137 nk_ifloorf(float x)
6138 {
6139  x = (float)((int)x - ((x < 0.0f) ? 1 : 0));
6140  return (int)x;
6141 }
6142 NK_LIB int
6143 nk_iceilf(float x)
6144 {
6145  if (x >= 0) {
6146  int i = (int)x;
6147  return (x > i) ? i+1: i;
6148  } else {
6149  int t = (int)x;
6150  float r = x - (float)t;
6151  return (r > 0.0f) ? t+1: t;
6152  }
6153 }
6154 NK_LIB int
6155 nk_log10(double n)
6156 {
6157  int neg;
6158  int ret;
6159  int exp = 0;
6160 
6161  neg = (n < 0) ? 1 : 0;
6162  ret = (neg) ? (int)-n : (int)n;
6163  while ((ret / 10) > 0) {
6164  ret /= 10;
6165  exp++;
6166  }
6167  if (neg) exp = -exp;
6168  return exp;
6169 }
6170 NK_API struct nk_rect
6171 nk_get_null_rect(void)
6172 {
6173  return nk_null_rect;
6174 }
6175 NK_API struct nk_rect
6176 nk_rect(float x, float y, float w, float h)
6177 {
6178  struct nk_rect r;
6179  r.x = x; r.y = y;
6180  r.w = w; r.h = h;
6181  return r;
6182 }
6183 NK_API struct nk_rect
6184 nk_recti(int x, int y, int w, int h)
6185 {
6186  struct nk_rect r;
6187  r.x = (float)x;
6188  r.y = (float)y;
6189  r.w = (float)w;
6190  r.h = (float)h;
6191  return r;
6192 }
6193 NK_API struct nk_rect
6194 nk_recta(struct nk_vec2 pos, struct nk_vec2 size)
6195 {
6196  return nk_rect(pos.x, pos.y, size.x, size.y);
6197 }
6198 NK_API struct nk_rect
6199 nk_rectv(const float *r)
6200 {
6201  return nk_rect(r[0], r[1], r[2], r[3]);
6202 }
6203 NK_API struct nk_rect
6204 nk_rectiv(const int *r)
6205 {
6206  return nk_recti(r[0], r[1], r[2], r[3]);
6207 }
6208 NK_API struct nk_vec2
6209 nk_rect_pos(struct nk_rect r)
6210 {
6211  struct nk_vec2 ret;
6212  ret.x = r.x; ret.y = r.y;
6213  return ret;
6214 }
6215 NK_API struct nk_vec2
6216 nk_rect_size(struct nk_rect r)
6217 {
6218  struct nk_vec2 ret;
6219  ret.x = r.w; ret.y = r.h;
6220  return ret;
6221 }
6222 NK_LIB struct nk_rect
6223 nk_shrink_rect(struct nk_rect r, float amount)
6224 {
6225  struct nk_rect res;
6226  r.w = NK_MAX(r.w, 2 * amount);
6227  r.h = NK_MAX(r.h, 2 * amount);
6228  res.x = r.x + amount;
6229  res.y = r.y + amount;
6230  res.w = r.w - 2 * amount;
6231  res.h = r.h - 2 * amount;
6232  return res;
6233 }
6234 NK_LIB struct nk_rect
6235 nk_pad_rect(struct nk_rect r, struct nk_vec2 pad)
6236 {
6237  r.w = NK_MAX(r.w, 2 * pad.x);
6238  r.h = NK_MAX(r.h, 2 * pad.y);
6239  r.x += pad.x; r.y += pad.y;
6240  r.w -= 2 * pad.x;
6241  r.h -= 2 * pad.y;
6242  return r;
6243 }
6244 NK_API struct nk_vec2
6245 nk_vec2(float x, float y)
6246 {
6247  struct nk_vec2 ret;
6248  ret.x = x; ret.y = y;
6249  return ret;
6250 }
6251 NK_API struct nk_vec2
6252 nk_vec2i(int x, int y)
6253 {
6254  struct nk_vec2 ret;
6255  ret.x = (float)x;
6256  ret.y = (float)y;
6257  return ret;
6258 }
6259 NK_API struct nk_vec2
6260 nk_vec2v(const float *v)
6261 {
6262  return nk_vec2(v[0], v[1]);
6263 }
6264 NK_API struct nk_vec2
6265 nk_vec2iv(const int *v)
6266 {
6267  return nk_vec2i(v[0], v[1]);
6268 }
6269 NK_LIB void
6270 nk_unify(struct nk_rect *clip, const struct nk_rect *a, float x0, float y0,
6271  float x1, float y1)
6272 {
6273  NK_ASSERT(a);
6274  NK_ASSERT(clip);
6275  clip->x = NK_MAX(a->x, x0);
6276  clip->y = NK_MAX(a->y, y0);
6277  clip->w = NK_MIN(a->x + a->w, x1) - clip->x;
6278  clip->h = NK_MIN(a->y + a->h, y1) - clip->y;
6279  clip->w = NK_MAX(0, clip->w);
6280  clip->h = NK_MAX(0, clip->h);
6281 }
6282 
6283 NK_API void
6284 nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r,
6285  float pad_x, float pad_y, enum nk_heading direction)
6286 {
6287  float w_half, h_half;
6288  NK_ASSERT(result);
6289 
6290  r.w = NK_MAX(2 * pad_x, r.w);
6291  r.h = NK_MAX(2 * pad_y, r.h);
6292  r.w = r.w - 2 * pad_x;
6293  r.h = r.h - 2 * pad_y;
6294 
6295  r.x = r.x + pad_x;
6296  r.y = r.y + pad_y;
6297 
6298  w_half = r.w / 2.0f;
6299  h_half = r.h / 2.0f;
6300 
6301  if (direction == NK_UP) {
6302  result[0] = nk_vec2(r.x + w_half, r.y);
6303  result[1] = nk_vec2(r.x + r.w, r.y + r.h);
6304  result[2] = nk_vec2(r.x, r.y + r.h);
6305  } else if (direction == NK_RIGHT) {
6306  result[0] = nk_vec2(r.x, r.y);
6307  result[1] = nk_vec2(r.x + r.w, r.y + h_half);
6308  result[2] = nk_vec2(r.x, r.y + r.h);
6309  } else if (direction == NK_DOWN) {
6310  result[0] = nk_vec2(r.x, r.y);
6311  result[1] = nk_vec2(r.x + r.w, r.y);
6312  result[2] = nk_vec2(r.x + w_half, r.y + r.h);
6313  } else {
6314  result[0] = nk_vec2(r.x, r.y + h_half);
6315  result[1] = nk_vec2(r.x + r.w, r.y);
6316  result[2] = nk_vec2(r.x + r.w, r.y + r.h);
6317  }
6318 }
6319 
6320 
6321 
6322 
6323 
6324 /* ===============================================================
6325  *
6326  * UTIL
6327  *
6328  * ===============================================================*/
6329 NK_INTERN int nk_str_match_here(const char *regexp, const char *text);
6330 NK_INTERN int nk_str_match_star(int c, const char *regexp, const char *text);
6331 NK_LIB int nk_is_lower(int c) {return (c >= 'a' && c <= 'z') || (c >= 0xE0 && c <= 0xFF);}
6332 NK_LIB int nk_is_upper(int c){return (c >= 'A' && c <= 'Z') || (c >= 0xC0 && c <= 0xDF);}
6333 NK_LIB int nk_to_upper(int c) {return (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;}
6334 NK_LIB int nk_to_lower(int c) {return (c >= 'A' && c <= 'Z') ? (c - ('a' + 'A')) : c;}
6335 
6336 NK_LIB void*
6337 nk_memcopy(void *dst0, const void *src0, nk_size length)
6338 {
6339  nk_ptr t;
6340  char *dst = (char*)dst0;
6341  const char *src = (const char*)src0;
6342  if (length == 0 || dst == src)
6343  goto done;
6344 
6345  #define nk_word int
6346  #define nk_wsize sizeof(nk_word)
6347  #define nk_wmask (nk_wsize-1)
6348  #define NK_TLOOP(s) if (t) NK_TLOOP1(s)
6349  #define NK_TLOOP1(s) do { s; } while (--t)
6350 
6351  if (dst < src) {
6352  t = (nk_ptr)src; /* only need low bits */
6353  if ((t | (nk_ptr)dst) & nk_wmask) {
6354  if ((t ^ (nk_ptr)dst) & nk_wmask || length < nk_wsize)
6355  t = length;
6356  else
6357  t = nk_wsize - (t & nk_wmask);
6358  length -= t;
6359  NK_TLOOP1(*dst++ = *src++);
6360  }
6361  t = length / nk_wsize;
6362  NK_TLOOP(*(nk_word*)(void*)dst = *(const nk_word*)(const void*)src;
6363  src += nk_wsize; dst += nk_wsize);
6364  t = length & nk_wmask;
6365  NK_TLOOP(*dst++ = *src++);
6366  } else {
6367  src += length;
6368  dst += length;
6369  t = (nk_ptr)src;
6370  if ((t | (nk_ptr)dst) & nk_wmask) {
6371  if ((t ^ (nk_ptr)dst) & nk_wmask || length <= nk_wsize)
6372  t = length;
6373  else
6374  t &= nk_wmask;
6375  length -= t;
6376  NK_TLOOP1(*--dst = *--src);
6377  }
6378  t = length / nk_wsize;
6379  NK_TLOOP(src -= nk_wsize; dst -= nk_wsize;
6380  *(nk_word*)(void*)dst = *(const nk_word*)(const void*)src);
6381  t = length & nk_wmask;
6382  NK_TLOOP(*--dst = *--src);
6383  }
6384  #undef nk_word
6385  #undef nk_wsize
6386  #undef nk_wmask
6387  #undef NK_TLOOP
6388  #undef NK_TLOOP1
6389 done:
6390  return (dst0);
6391 }
6392 NK_LIB void
6393 nk_memset(void *ptr, int c0, nk_size size)
6394 {
6395  #define nk_word unsigned
6396  #define nk_wsize sizeof(nk_word)
6397  #define nk_wmask (nk_wsize - 1)
6398  nk_byte *dst = (nk_byte*)ptr;
6399  unsigned c = 0;
6400  nk_size t = 0;
6401 
6402  if ((c = (nk_byte)c0) != 0) {
6403  c = (c << 8) | c; /* at least 16-bits */
6404  if (sizeof(unsigned int) > 2)
6405  c = (c << 16) | c; /* at least 32-bits*/
6406  }
6407 
6408  /* too small of a word count */
6409  dst = (nk_byte*)ptr;
6410  if (size < 3 * nk_wsize) {
6411  while (size--) *dst++ = (nk_byte)c0;
6412  return;
6413  }
6414 
6415  /* align destination */
6416  if ((t = NK_PTR_TO_UINT(dst) & nk_wmask) != 0) {
6417  t = nk_wsize -t;
6418  size -= t;
6419  do {
6420  *dst++ = (nk_byte)c0;
6421  } while (--t != 0);
6422  }
6423 
6424  /* fill word */
6425  t = size / nk_wsize;
6426  do {
6427  *(nk_word*)((void*)dst) = c;
6428  dst += nk_wsize;
6429  } while (--t != 0);
6430 
6431  /* fill trailing bytes */
6432  t = (size & nk_wmask);
6433  if (t != 0) {
6434  do {
6435  *dst++ = (nk_byte)c0;
6436  } while (--t != 0);
6437  }
6438 
6439  #undef nk_word
6440  #undef nk_wsize
6441  #undef nk_wmask
6442 }
6443 NK_LIB void
6444 nk_zero(void *ptr, nk_size size)
6445 {
6446  NK_ASSERT(ptr);
6447  NK_MEMSET(ptr, 0, size);
6448 }
6449 NK_API int
6450 nk_strlen(const char *str)
6451 {
6452  int siz = 0;
6453  NK_ASSERT(str);
6454  while (str && *str++ != '\0') siz++;
6455  return siz;
6456 }
6457 NK_API int
6458 nk_strtoi(const char *str, const char **endptr)
6459 {
6460  int neg = 1;
6461  const char *p = str;
6462  int value = 0;
6463 
6464  NK_ASSERT(str);
6465  if (!str) return 0;
6466 
6467  /* skip whitespace */
6468  while (*p == ' ') p++;
6469  if (*p == '-') {
6470  neg = -1;
6471  p++;
6472  }
6473  while (*p && *p >= '0' && *p <= '9') {
6474  value = value * 10 + (int) (*p - '0');
6475  p++;
6476  }
6477  if (endptr)
6478  *endptr = p;
6479  return neg*value;
6480 }
6481 NK_API double
6482 nk_strtod(const char *str, const char **endptr)
6483 {
6484  double m;
6485  double neg = 1.0;
6486  const char *p = str;
6487  double value = 0;
6488  double number = 0;
6489 
6490  NK_ASSERT(str);
6491  if (!str) return 0;
6492 
6493  /* skip whitespace */
6494  while (*p == ' ') p++;
6495  if (*p == '-') {
6496  neg = -1.0;
6497  p++;
6498  }
6499 
6500  while (*p && *p != '.' && *p != 'e') {
6501  value = value * 10.0 + (double) (*p - '0');
6502  p++;
6503  }
6504 
6505  if (*p == '.') {
6506  p++;
6507  for(m = 0.1; *p && *p != 'e'; p++ ) {
6508  value = value + (double) (*p - '0') * m;
6509  m *= 0.1;
6510  }
6511  }
6512  if (*p == 'e') {
6513  int i, pow, div;
6514  p++;
6515  if (*p == '-') {
6516  div = nk_true;
6517  p++;
6518  } else if (*p == '+') {
6519  div = nk_false;
6520  p++;
6521  } else div = nk_false;
6522 
6523  for (pow = 0; *p; p++)
6524  pow = pow * 10 + (int) (*p - '0');
6525 
6526  for (m = 1.0, i = 0; i < pow; i++)
6527  m *= 10.0;
6528 
6529  if (div)
6530  value /= m;
6531  else value *= m;
6532  }
6533  number = value * neg;
6534  if (endptr)
6535  *endptr = p;
6536  return number;
6537 }
6538 NK_API float
6539 nk_strtof(const char *str, const char **endptr)
6540 {
6541  float float_value;
6542  double double_value;
6543  double_value = NK_STRTOD(str, endptr);
6544  float_value = (float)double_value;
6545  return float_value;
6546 }
6547 NK_API int
6548 nk_stricmp(const char *s1, const char *s2)
6549 {
6550  nk_int c1,c2,d;
6551  do {
6552  c1 = *s1++;
6553  c2 = *s2++;
6554  d = c1 - c2;
6555  while (d) {
6556  if (c1 <= 'Z' && c1 >= 'A') {
6557  d += ('a' - 'A');
6558  if (!d) break;
6559  }
6560  if (c2 <= 'Z' && c2 >= 'A') {
6561  d -= ('a' - 'A');
6562  if (!d) break;
6563  }
6564  return ((d >= 0) << 1) - 1;
6565  }
6566  } while (c1);
6567  return 0;
6568 }
6569 NK_API int
6570 nk_stricmpn(const char *s1, const char *s2, int n)
6571 {
6572  int c1,c2,d;
6573  NK_ASSERT(n >= 0);
6574  do {
6575  c1 = *s1++;
6576  c2 = *s2++;
6577  if (!n--) return 0;
6578 
6579  d = c1 - c2;
6580  while (d) {
6581  if (c1 <= 'Z' && c1 >= 'A') {
6582  d += ('a' - 'A');
6583  if (!d) break;
6584  }
6585  if (c2 <= 'Z' && c2 >= 'A') {
6586  d -= ('a' - 'A');
6587  if (!d) break;
6588  }
6589  return ((d >= 0) << 1) - 1;
6590  }
6591  } while (c1);
6592  return 0;
6593 }
6594 NK_INTERN int
6595 nk_str_match_here(const char *regexp, const char *text)
6596 {
6597  if (regexp[0] == '\0')
6598  return 1;
6599  if (regexp[1] == '*')
6600  return nk_str_match_star(regexp[0], regexp+2, text);
6601  if (regexp[0] == '$' && regexp[1] == '\0')
6602  return *text == '\0';
6603  if (*text!='\0' && (regexp[0]=='.' || regexp[0]==*text))
6604  return nk_str_match_here(regexp+1, text+1);
6605  return 0;
6606 }
6607 NK_INTERN int
6608 nk_str_match_star(int c, const char *regexp, const char *text)
6609 {
6610  do {/* a '* matches zero or more instances */
6611  if (nk_str_match_here(regexp, text))
6612  return 1;
6613  } while (*text != '\0' && (*text++ == c || c == '.'));
6614  return 0;
6615 }
6616 NK_API int
6617 nk_strfilter(const char *text, const char *regexp)
6618 {
6619  /*
6620  c matches any literal character c
6621  . matches any single character
6622  ^ matches the beginning of the input string
6623  $ matches the end of the input string
6624  * matches zero or more occurrences of the previous character*/
6625  if (regexp[0] == '^')
6626  return nk_str_match_here(regexp+1, text);
6627  do { /* must look even if string is empty */
6628  if (nk_str_match_here(regexp, text))
6629  return 1;
6630  } while (*text++ != '\0');
6631  return 0;
6632 }
6633 NK_API int
6634 nk_strmatch_fuzzy_text(const char *str, int str_len,
6635  const char *pattern, int *out_score)
6636 {
6637  /* Returns true if each character in pattern is found sequentially within str
6638  * if found then out_score is also set. Score value has no intrinsic meaning.
6639  * Range varies with pattern. Can only compare scores with same search pattern. */
6640 
6641  /* bonus for adjacent matches */
6642  #define NK_ADJACENCY_BONUS 5
6643  /* bonus if match occurs after a separator */
6644  #define NK_SEPARATOR_BONUS 10
6645  /* bonus if match is uppercase and prev is lower */
6646  #define NK_CAMEL_BONUS 10
6647  /* penalty applied for every letter in str before the first match */
6648  #define NK_LEADING_LETTER_PENALTY (-3)
6649  /* maximum penalty for leading letters */
6650  #define NK_MAX_LEADING_LETTER_PENALTY (-9)
6651  /* penalty for every letter that doesn't matter */
6652  #define NK_UNMATCHED_LETTER_PENALTY (-1)
6653 
6654  /* loop variables */
6655  int score = 0;
6656  char const * pattern_iter = pattern;
6657  int str_iter = 0;
6658  int prev_matched = nk_false;
6659  int prev_lower = nk_false;
6660  /* true so if first letter match gets separator bonus*/
6661  int prev_separator = nk_true;
6662 
6663  /* use "best" matched letter if multiple string letters match the pattern */
6664  char const * best_letter = 0;
6665  int best_letter_score = 0;
6666 
6667  /* loop over strings */
6668  NK_ASSERT(str);
6669  NK_ASSERT(pattern);
6670  if (!str || !str_len || !pattern) return 0;
6671  while (str_iter < str_len)
6672  {
6673  const char pattern_letter = *pattern_iter;
6674  const char str_letter = str[str_iter];
6675 
6676  int next_match = *pattern_iter != '\0' &&
6677  nk_to_lower(pattern_letter) == nk_to_lower(str_letter);
6678  int rematch = best_letter && nk_to_upper(*best_letter) == nk_to_upper(str_letter);
6679 
6680  int advanced = next_match && best_letter;
6681  int pattern_repeat = best_letter && *pattern_iter != '\0';
6682  pattern_repeat = pattern_repeat &&
6683  nk_to_lower(*best_letter) == nk_to_lower(pattern_letter);
6684 
6685  if (advanced || pattern_repeat) {
6686  score += best_letter_score;
6687  best_letter = 0;
6688  best_letter_score = 0;
6689  }
6690 
6691  if (next_match || rematch)
6692  {
6693  int new_score = 0;
6694  /* Apply penalty for each letter before the first pattern match */
6695  if (pattern_iter == pattern) {
6696  int count = (int)(&str[str_iter] - str);
6697  int penalty = NK_LEADING_LETTER_PENALTY * count;
6698  if (penalty < NK_MAX_LEADING_LETTER_PENALTY)
6699  penalty = NK_MAX_LEADING_LETTER_PENALTY;
6700 
6701  score += penalty;
6702  }
6703 
6704  /* apply bonus for consecutive bonuses */
6705  if (prev_matched)
6706  new_score += NK_ADJACENCY_BONUS;
6707 
6708  /* apply bonus for matches after a separator */
6709  if (prev_separator)
6710  new_score += NK_SEPARATOR_BONUS;
6711 
6712  /* apply bonus across camel case boundaries */
6713  if (prev_lower && nk_is_upper(str_letter))
6714  new_score += NK_CAMEL_BONUS;
6715 
6716  /* update pattern iter IFF the next pattern letter was matched */
6717  if (next_match)
6718  ++pattern_iter;
6719 
6720  /* update best letter in str which may be for a "next" letter or a rematch */
6721  if (new_score >= best_letter_score) {
6722  /* apply penalty for now skipped letter */
6723  if (best_letter != 0)
6724  score += NK_UNMATCHED_LETTER_PENALTY;
6725 
6726  best_letter = &str[str_iter];
6727  best_letter_score = new_score;
6728  }
6729  prev_matched = nk_true;
6730  } else {
6731  score += NK_UNMATCHED_LETTER_PENALTY;
6732  prev_matched = nk_false;
6733  }
6734 
6735  /* separators should be more easily defined */
6736  prev_lower = nk_is_lower(str_letter) != 0;
6737  prev_separator = str_letter == '_' || str_letter == ' ';
6738 
6739  ++str_iter;
6740  }
6741 
6742  /* apply score for last match */
6743  if (best_letter)
6744  score += best_letter_score;
6745 
6746  /* did not match full pattern */
6747  if (*pattern_iter != '\0')
6748  return nk_false;
6749 
6750  if (out_score)
6751  *out_score = score;
6752  return nk_true;
6753 }
6754 NK_API int
6755 nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score)
6756 {
6757  return nk_strmatch_fuzzy_text(str, nk_strlen(str), pattern, out_score);
6758 }
6759 NK_LIB int
6760 nk_string_float_limit(char *string, int prec)
6761 {
6762  int dot = 0;
6763  char *c = string;
6764  while (*c) {
6765  if (*c == '.') {
6766  dot = 1;
6767  c++;
6768  continue;
6769  }
6770  if (dot == (prec+1)) {
6771  *c = 0;
6772  break;
6773  }
6774  if (dot > 0) dot++;
6775  c++;
6776  }
6777  return (int)(c - string);
6778 }
6779 NK_INTERN void
6780 nk_strrev_ascii(char *s)
6781 {
6782  int len = nk_strlen(s);
6783  int end = len / 2;
6784  int i = 0;
6785  char t;
6786  for (; i < end; ++i) {
6787  t = s[i];
6788  s[i] = s[len - 1 - i];
6789  s[len -1 - i] = t;
6790  }
6791 }
6792 NK_LIB char*
6793 nk_itoa(char *s, long n)
6794 {
6795  long i = 0;
6796  if (n == 0) {
6797  s[i++] = '0';
6798  s[i] = 0;
6799  return s;
6800  }
6801  if (n < 0) {
6802  s[i++] = '-';
6803  n = -n;
6804  }
6805  while (n > 0) {
6806  s[i++] = (char)('0' + (n % 10));
6807  n /= 10;
6808  }
6809  s[i] = 0;
6810  if (s[0] == '-')
6811  ++s;
6812 
6813  nk_strrev_ascii(s);
6814  return s;
6815 }
6816 NK_LIB char*
6817 nk_dtoa(char *s, double n)
6818 {
6819  int useExp = 0;
6820  int digit = 0, m = 0, m1 = 0;
6821  char *c = s;
6822  int neg = 0;
6823 
6824  NK_ASSERT(s);
6825  if (!s) return 0;
6826 
6827  if (n == 0.0) {
6828  s[0] = '0'; s[1] = '\0';
6829  return s;
6830  }
6831 
6832  neg = (n < 0);
6833  if (neg) n = -n;
6834 
6835  /* calculate magnitude */
6836  m = nk_log10(n);
6837  useExp = (m >= 14 || (neg && m >= 9) || m <= -9);
6838  if (neg) *(c++) = '-';
6839 
6840  /* set up for scientific notation */
6841  if (useExp) {
6842  if (m < 0)
6843  m -= 1;
6844  n = n / (double)nk_pow(10.0, m);
6845  m1 = m;
6846  m = 0;
6847  }
6848  if (m < 1.0) {
6849  m = 0;
6850  }
6851 
6852  /* convert the number */
6853  while (n > NK_FLOAT_PRECISION || m >= 0) {
6854  double weight = nk_pow(10.0, m);
6855  if (weight > 0) {
6856  double t = (double)n / weight;
6857  digit = nk_ifloord(t);
6858  n -= ((double)digit * weight);
6859  *(c++) = (char)('0' + (char)digit);
6860  }
6861  if (m == 0 && n > 0)
6862  *(c++) = '.';
6863  m--;
6864  }
6865 
6866  if (useExp) {
6867  /* convert the exponent */
6868  int i, j;
6869  *(c++) = 'e';
6870  if (m1 > 0) {
6871  *(c++) = '+';
6872  } else {
6873  *(c++) = '-';
6874  m1 = -m1;
6875  }
6876  m = 0;
6877  while (m1 > 0) {
6878  *(c++) = (char)('0' + (char)(m1 % 10));
6879  m1 /= 10;
6880  m++;
6881  }
6882  c -= m;
6883  for (i = 0, j = m-1; i<j; i++, j--) {
6884  /* swap without temporary */
6885  c[i] ^= c[j];
6886  c[j] ^= c[i];
6887  c[i] ^= c[j];
6888  }
6889  c += m;
6890  }
6891  *(c) = '\0';
6892  return s;
6893 }
6894 #ifdef NK_INCLUDE_STANDARD_VARARGS
6895 #ifndef NK_INCLUDE_STANDARD_IO
6896 NK_INTERN int
6897 nk_vsnprintf(char *buf, int buf_size, const char *fmt, va_list args)
6898 {
6899  enum nk_arg_type {
6900  NK_ARG_TYPE_CHAR,
6901  NK_ARG_TYPE_SHORT,
6902  NK_ARG_TYPE_DEFAULT,
6903  NK_ARG_TYPE_LONG
6904  };
6905  enum nk_arg_flags {
6906  NK_ARG_FLAG_LEFT = 0x01,
6907  NK_ARG_FLAG_PLUS = 0x02,
6908  NK_ARG_FLAG_SPACE = 0x04,
6909  NK_ARG_FLAG_NUM = 0x10,
6910  NK_ARG_FLAG_ZERO = 0x20
6911  };
6912 
6913  char number_buffer[NK_MAX_NUMBER_BUFFER];
6914  enum nk_arg_type arg_type = NK_ARG_TYPE_DEFAULT;
6915  int precision = NK_DEFAULT;
6916  int width = NK_DEFAULT;
6917  nk_flags flag = 0;
6918 
6919  int len = 0;
6920  int result = -1;
6921  const char *iter = fmt;
6922 
6923  NK_ASSERT(buf);
6924  NK_ASSERT(buf_size);
6925  if (!buf || !buf_size || !fmt) return 0;
6926  for (iter = fmt; *iter && len < buf_size; iter++) {
6927  /* copy all non-format characters */
6928  while (*iter && (*iter != '%') && (len < buf_size))
6929  buf[len++] = *iter++;
6930  if (!(*iter) || len >= buf_size) break;
6931  iter++;
6932 
6933  /* flag arguments */
6934  while (*iter) {
6935  if (*iter == '-') flag |= NK_ARG_FLAG_LEFT;
6936  else if (*iter == '+') flag |= NK_ARG_FLAG_PLUS;
6937  else if (*iter == ' ') flag |= NK_ARG_FLAG_SPACE;
6938  else if (*iter == '#') flag |= NK_ARG_FLAG_NUM;
6939  else if (*iter == '0') flag |= NK_ARG_FLAG_ZERO;
6940  else break;
6941  iter++;
6942  }
6943 
6944  /* width argument */
6945  width = NK_DEFAULT;
6946  if (*iter >= '1' && *iter <= '9') {
6947  const char *end;
6948  width = nk_strtoi(iter, &end);
6949  if (end == iter)
6950  width = -1;
6951  else iter = end;
6952  } else if (*iter == '*') {
6953  width = va_arg(args, int);
6954  iter++;
6955  }
6956 
6957  /* precision argument */
6958  precision = NK_DEFAULT;
6959  if (*iter == '.') {
6960  iter++;
6961  if (*iter == '*') {
6962  precision = va_arg(args, int);
6963  iter++;
6964  } else {
6965  const char *end;
6966  precision = nk_strtoi(iter, &end);
6967  if (end == iter)
6968  precision = -1;
6969  else iter = end;
6970  }
6971  }
6972 
6973  /* length modifier */
6974  if (*iter == 'h') {
6975  if (*(iter+1) == 'h') {
6976  arg_type = NK_ARG_TYPE_CHAR;
6977  iter++;
6978  } else arg_type = NK_ARG_TYPE_SHORT;
6979  iter++;
6980  } else if (*iter == 'l') {
6981  arg_type = NK_ARG_TYPE_LONG;
6982  iter++;
6983  } else arg_type = NK_ARG_TYPE_DEFAULT;
6984 
6985  /* specifier */
6986  if (*iter == '%') {
6987  NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
6988  NK_ASSERT(precision == NK_DEFAULT);
6989  NK_ASSERT(width == NK_DEFAULT);
6990  if (len < buf_size)
6991  buf[len++] = '%';
6992  } else if (*iter == 's') {
6993  /* string */
6994  const char *str = va_arg(args, const char*);
6995  NK_ASSERT(str != buf && "buffer and argument are not allowed to overlap!");
6996  NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
6997  NK_ASSERT(precision == NK_DEFAULT);
6998  NK_ASSERT(width == NK_DEFAULT);
6999  if (str == buf) return -1;
7000  while (str && *str && len < buf_size)
7001  buf[len++] = *str++;
7002  } else if (*iter == 'n') {
7003  /* current length callback */
7004  signed int *n = va_arg(args, int*);
7005  NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7006  NK_ASSERT(precision == NK_DEFAULT);
7007  NK_ASSERT(width == NK_DEFAULT);
7008  if (n) *n = len;
7009  } else if (*iter == 'c' || *iter == 'i' || *iter == 'd') {
7010  /* signed integer */
7011  long value = 0;
7012  const char *num_iter;
7013  int num_len, num_print, padding;
7014  int cur_precision = NK_MAX(precision, 1);
7015  int cur_width = NK_MAX(width, 0);
7016 
7017  /* retrieve correct value type */
7018  if (arg_type == NK_ARG_TYPE_CHAR)
7019  value = (signed char)va_arg(args, int);
7020  else if (arg_type == NK_ARG_TYPE_SHORT)
7021  value = (signed short)va_arg(args, int);
7022  else if (arg_type == NK_ARG_TYPE_LONG)
7023  value = va_arg(args, signed long);
7024  else if (*iter == 'c')
7025  value = (unsigned char)va_arg(args, int);
7026  else value = va_arg(args, signed int);
7027 
7028  /* convert number to string */
7029  nk_itoa(number_buffer, value);
7030  num_len = nk_strlen(number_buffer);
7031  padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
7032  if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
7033  padding = NK_MAX(padding-1, 0);
7034 
7035  /* fill left padding up to a total of `width` characters */
7036  if (!(flag & NK_ARG_FLAG_LEFT)) {
7037  while (padding-- > 0 && (len < buf_size)) {
7038  if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
7039  buf[len++] = '0';
7040  else buf[len++] = ' ';
7041  }
7042  }
7043 
7044  /* copy string value representation into buffer */
7045  if ((flag & NK_ARG_FLAG_PLUS) && value >= 0 && len < buf_size)
7046  buf[len++] = '+';
7047  else if ((flag & NK_ARG_FLAG_SPACE) && value >= 0 && len < buf_size)
7048  buf[len++] = ' ';
7049 
7050  /* fill up to precision number of digits with '0' */
7051  num_print = NK_MAX(cur_precision, num_len);
7052  while (precision && (num_print > num_len) && (len < buf_size)) {
7053  buf[len++] = '0';
7054  num_print--;
7055  }
7056 
7057  /* copy string value representation into buffer */
7058  num_iter = number_buffer;
7059  while (precision && *num_iter && len < buf_size)
7060  buf[len++] = *num_iter++;
7061 
7062  /* fill right padding up to width characters */
7063  if (flag & NK_ARG_FLAG_LEFT) {
7064  while ((padding-- > 0) && (len < buf_size))
7065  buf[len++] = ' ';
7066  }
7067  } else if (*iter == 'o' || *iter == 'x' || *iter == 'X' || *iter == 'u') {
7068  /* unsigned integer */
7069  unsigned long value = 0;
7070  int num_len = 0, num_print, padding = 0;
7071  int cur_precision = NK_MAX(precision, 1);
7072  int cur_width = NK_MAX(width, 0);
7073  unsigned int base = (*iter == 'o') ? 8: (*iter == 'u')? 10: 16;
7074 
7075  /* print oct/hex/dec value */
7076  const char *upper_output_format = "0123456789ABCDEF";
7077  const char *lower_output_format = "0123456789abcdef";
7078  const char *output_format = (*iter == 'x') ?
7079  lower_output_format: upper_output_format;
7080 
7081  /* retrieve correct value type */
7082  if (arg_type == NK_ARG_TYPE_CHAR)
7083  value = (unsigned char)va_arg(args, int);
7084  else if (arg_type == NK_ARG_TYPE_SHORT)
7085  value = (unsigned short)va_arg(args, int);
7086  else if (arg_type == NK_ARG_TYPE_LONG)
7087  value = va_arg(args, unsigned long);
7088  else value = va_arg(args, unsigned int);
7089 
7090  do {
7091  /* convert decimal number into hex/oct number */
7092  int digit = output_format[value % base];
7093  if (num_len < NK_MAX_NUMBER_BUFFER)
7094  number_buffer[num_len++] = (char)digit;
7095  value /= base;
7096  } while (value > 0);
7097 
7098  num_print = NK_MAX(cur_precision, num_len);
7099  padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
7100  if (flag & NK_ARG_FLAG_NUM)
7101  padding = NK_MAX(padding-1, 0);
7102 
7103  /* fill left padding up to a total of `width` characters */
7104  if (!(flag & NK_ARG_FLAG_LEFT)) {
7105  while ((padding-- > 0) && (len < buf_size)) {
7106  if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
7107  buf[len++] = '0';
7108  else buf[len++] = ' ';
7109  }
7110  }
7111 
7112  /* fill up to precision number of digits */
7113  if (num_print && (flag & NK_ARG_FLAG_NUM)) {
7114  if ((*iter == 'o') && (len < buf_size)) {
7115  buf[len++] = '0';
7116  } else if ((*iter == 'x') && ((len+1) < buf_size)) {
7117  buf[len++] = '0';
7118  buf[len++] = 'x';
7119  } else if ((*iter == 'X') && ((len+1) < buf_size)) {
7120  buf[len++] = '0';
7121  buf[len++] = 'X';
7122  }
7123  }
7124  while (precision && (num_print > num_len) && (len < buf_size)) {
7125  buf[len++] = '0';
7126  num_print--;
7127  }
7128 
7129  /* reverse number direction */
7130  while (num_len > 0) {
7131  if (precision && (len < buf_size))
7132  buf[len++] = number_buffer[num_len-1];
7133  num_len--;
7134  }
7135 
7136  /* fill right padding up to width characters */
7137  if (flag & NK_ARG_FLAG_LEFT) {
7138  while ((padding-- > 0) && (len < buf_size))
7139  buf[len++] = ' ';
7140  }
7141  } else if (*iter == 'f') {
7142  /* floating point */
7143  const char *num_iter;
7144  int cur_precision = (precision < 0) ? 6: precision;
7145  int prefix, cur_width = NK_MAX(width, 0);
7146  double value = va_arg(args, double);
7147  int num_len = 0, frac_len = 0, dot = 0;
7148  int padding = 0;
7149 
7150  NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7151  NK_DTOA(number_buffer, value);
7152  num_len = nk_strlen(number_buffer);
7153 
7154  /* calculate padding */
7155  num_iter = number_buffer;
7156  while (*num_iter && *num_iter != '.')
7157  num_iter++;
7158 
7159  prefix = (*num_iter == '.')?(int)(num_iter - number_buffer)+1:0;
7160  padding = NK_MAX(cur_width - (prefix + NK_MIN(cur_precision, num_len - prefix)) , 0);
7161  if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
7162  padding = NK_MAX(padding-1, 0);
7163 
7164  /* fill left padding up to a total of `width` characters */
7165  if (!(flag & NK_ARG_FLAG_LEFT)) {
7166  while (padding-- > 0 && (len < buf_size)) {
7167  if (flag & NK_ARG_FLAG_ZERO)
7168  buf[len++] = '0';
7169  else buf[len++] = ' ';
7170  }
7171  }
7172 
7173  /* copy string value representation into buffer */
7174  num_iter = number_buffer;
7175  if ((flag & NK_ARG_FLAG_PLUS) && (value >= 0) && (len < buf_size))
7176  buf[len++] = '+';
7177  else if ((flag & NK_ARG_FLAG_SPACE) && (value >= 0) && (len < buf_size))
7178  buf[len++] = ' ';
7179  while (*num_iter) {
7180  if (dot) frac_len++;
7181  if (len < buf_size)
7182  buf[len++] = *num_iter;
7183  if (*num_iter == '.') dot = 1;
7184  if (frac_len >= cur_precision) break;
7185  num_iter++;
7186  }
7187 
7188  /* fill number up to precision */
7189  while (frac_len < cur_precision) {
7190  if (!dot && len < buf_size) {
7191  buf[len++] = '.';
7192  dot = 1;
7193  }
7194  if (len < buf_size)
7195  buf[len++] = '0';
7196  frac_len++;
7197  }
7198 
7199  /* fill right padding up to width characters */
7200  if (flag & NK_ARG_FLAG_LEFT) {
7201  while ((padding-- > 0) && (len < buf_size))
7202  buf[len++] = ' ';
7203  }
7204  } else {
7205  /* Specifier not supported: g,G,e,E,p,z */
7206  NK_ASSERT(0 && "specifier is not supported!");
7207  return result;
7208  }
7209  }
7210  buf[(len >= buf_size)?(buf_size-1):len] = 0;
7211  result = (len >= buf_size)?-1:len;
7212  return result;
7213 }
7214 #endif
7215 NK_LIB int
7216 nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args)
7217 {
7218  int result = -1;
7219  NK_ASSERT(buf);
7220  NK_ASSERT(buf_size);
7221  if (!buf || !buf_size || !fmt) return 0;
7222 #ifdef NK_INCLUDE_STANDARD_IO
7223  result = NK_VSNPRINTF(buf, (nk_size)buf_size, fmt, args);
7224  result = (result >= buf_size) ? -1: result;
7225  buf[buf_size-1] = 0;
7226 #else
7227  result = nk_vsnprintf(buf, buf_size, fmt, args);
7228 #endif
7229  return result;
7230 }
7231 #endif
7233 nk_murmur_hash(const void * key, int len, nk_hash seed)
7234 {
7235  /* 32-Bit MurmurHash3: https://code.google.com/p/smhasher/wiki/MurmurHash3*/
7236  #define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r)))
7237 
7238  nk_uint h1 = seed;
7239  nk_uint k1;
7240  const nk_byte *data = (const nk_byte*)key;
7241  const nk_byte *keyptr = data;
7242  nk_byte *k1ptr;
7243  const int bsize = sizeof(k1);
7244  const int nblocks = len/4;
7245 
7246  const nk_uint c1 = 0xcc9e2d51;
7247  const nk_uint c2 = 0x1b873593;
7248  const nk_byte *tail;
7249  int i;
7250 
7251  /* body */
7252  if (!key) return 0;
7253  for (i = 0; i < nblocks; ++i, keyptr += bsize) {
7254  k1ptr = (nk_byte*)&k1;
7255  k1ptr[0] = keyptr[0];
7256  k1ptr[1] = keyptr[1];
7257  k1ptr[2] = keyptr[2];
7258  k1ptr[3] = keyptr[3];
7259 
7260  k1 *= c1;
7261  k1 = NK_ROTL(k1,15);
7262  k1 *= c2;
7263 
7264  h1 ^= k1;
7265  h1 = NK_ROTL(h1,13);
7266  h1 = h1*5+0xe6546b64;
7267  }
7268 
7269  /* tail */
7270  tail = (const nk_byte*)(data + nblocks*4);
7271  k1 = 0;
7272  switch (len & 3) {
7273  case 3: k1 ^= (nk_uint)(tail[2] << 16); /* fallthrough */
7274  case 2: k1 ^= (nk_uint)(tail[1] << 8u); /* fallthrough */
7275  case 1: k1 ^= tail[0];
7276  k1 *= c1;
7277  k1 = NK_ROTL(k1,15);
7278  k1 *= c2;
7279  h1 ^= k1;
7280  break;
7281  default: break;
7282  }
7283 
7284  /* finalization */
7285  h1 ^= (nk_uint)len;
7286  /* fmix32 */
7287  h1 ^= h1 >> 16;
7288  h1 *= 0x85ebca6b;
7289  h1 ^= h1 >> 13;
7290  h1 *= 0xc2b2ae35;
7291  h1 ^= h1 >> 16;
7292 
7293  #undef NK_ROTL
7294  return h1;
7295 }
7296 #ifdef NK_INCLUDE_STANDARD_IO
7297 NK_LIB char*
7298 nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc)
7299 {
7300  char *buf;
7301  FILE *fd;
7302  long ret;
7303 
7304  NK_ASSERT(path);
7305  NK_ASSERT(siz);
7306  NK_ASSERT(alloc);
7307  if (!path || !siz || !alloc)
7308  return 0;
7309 
7310  fd = fopen(path, "rb");
7311  if (!fd) return 0;
7312  fseek(fd, 0, SEEK_END);
7313  ret = ftell(fd);
7314  if (ret < 0) {
7315  fclose(fd);
7316  return 0;
7317  }
7318  *siz = (nk_size)ret;
7319  fseek(fd, 0, SEEK_SET);
7320  buf = (char*)alloc->alloc(alloc->userdata,0, *siz);
7321  NK_ASSERT(buf);
7322  if (!buf) {
7323  fclose(fd);
7324  return 0;
7325  }
7326  *siz = (nk_size)fread(buf, 1,*siz, fd);
7327  fclose(fd);
7328  return buf;
7329 }
7330 #endif
7331 NK_LIB int
7332 nk_text_clamp(const struct nk_user_font *font, const char *text,
7333  int text_len, float space, int *glyphs, float *text_width,
7334  nk_rune *sep_list, int sep_count)
7335 {
7336  int i = 0;
7337  int glyph_len = 0;
7338  float last_width = 0;
7339  nk_rune unicode = 0;
7340  float width = 0;
7341  int len = 0;
7342  int g = 0;
7343  float s;
7344 
7345  int sep_len = 0;
7346  int sep_g = 0;
7347  float sep_width = 0;
7348  sep_count = NK_MAX(sep_count,0);
7349 
7350  glyph_len = nk_utf_decode(text, &unicode, text_len);
7351  while (glyph_len && (width < space) && (len < text_len)) {
7352  len += glyph_len;
7353  s = font->width(font->userdata, font->height, text, len);
7354  for (i = 0; i < sep_count; ++i) {
7355  if (unicode != sep_list[i]) continue;
7356  sep_width = last_width = width;
7357  sep_g = g+1;
7358  sep_len = len;
7359  break;
7360  }
7361  if (i == sep_count){
7362  last_width = sep_width = width;
7363  sep_g = g+1;
7364  }
7365  width = s;
7366  glyph_len = nk_utf_decode(&text[len], &unicode, text_len - len);
7367  g++;
7368  }
7369  if (len >= text_len) {
7370  *glyphs = g;
7371  *text_width = last_width;
7372  return len;
7373  } else {
7374  *glyphs = sep_g;
7375  *text_width = sep_width;
7376  return (!sep_len) ? len: sep_len;
7377  }
7378 }
7379 NK_LIB struct nk_vec2
7380 nk_text_calculate_text_bounds(const struct nk_user_font *font,
7381  const char *begin, int byte_len, float row_height, const char **remaining,
7382  struct nk_vec2 *out_offset, int *glyphs, int op)
7383 {
7384  float line_height = row_height;
7385  struct nk_vec2 text_size = nk_vec2(0,0);
7386  float line_width = 0.0f;
7387 
7388  float glyph_width;
7389  int glyph_len = 0;
7390  nk_rune unicode = 0;
7391  int text_len = 0;
7392  if (!begin || byte_len <= 0 || !font)
7393  return nk_vec2(0,row_height);
7394 
7395  glyph_len = nk_utf_decode(begin, &unicode, byte_len);
7396  if (!glyph_len) return text_size;
7397  glyph_width = font->width(font->userdata, font->height, begin, glyph_len);
7398 
7399  *glyphs = 0;
7400  while ((text_len < byte_len) && glyph_len) {
7401  if (unicode == '\n') {
7402  text_size.x = NK_MAX(text_size.x, line_width);
7403  text_size.y += line_height;
7404  line_width = 0;
7405  *glyphs+=1;
7406  if (op == NK_STOP_ON_NEW_LINE)
7407  break;
7408 
7409  text_len++;
7410  glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7411  continue;
7412  }
7413 
7414  if (unicode == '\r') {
7415  text_len++;
7416  *glyphs+=1;
7417  glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7418  continue;
7419  }
7420 
7421  *glyphs = *glyphs + 1;
7422  text_len += glyph_len;
7423  line_width += (float)glyph_width;
7424  glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7425  glyph_width = font->width(font->userdata, font->height, begin+text_len, glyph_len);
7426  continue;
7427  }
7428 
7429  if (text_size.x < line_width)
7430  text_size.x = line_width;
7431  if (out_offset)
7432  *out_offset = nk_vec2(line_width, text_size.y + line_height);
7433  if (line_width > 0 || text_size.y == 0.0f)
7434  text_size.y += line_height;
7435  if (remaining)
7436  *remaining = begin+text_len;
7437  return text_size;
7438 }
7439 
7440 
7441 
7442 
7443 
7444 /* ==============================================================
7445  *
7446  * COLOR
7447  *
7448  * ===============================================================*/
7449 NK_INTERN int
7450 nk_parse_hex(const char *p, int length)
7451 {
7452  int i = 0;
7453  int len = 0;
7454  while (len < length) {
7455  i <<= 4;
7456  if (p[len] >= 'a' && p[len] <= 'f')
7457  i += ((p[len] - 'a') + 10);
7458  else if (p[len] >= 'A' && p[len] <= 'F')
7459  i += ((p[len] - 'A') + 10);
7460  else i += (p[len] - '0');
7461  len++;
7462  }
7463  return i;
7464 }
7465 NK_API struct nk_color
7466 nk_rgba(int r, int g, int b, int a)
7467 {
7468  struct nk_color ret;
7469  ret.r = (nk_byte)NK_CLAMP(0, r, 255);
7470  ret.g = (nk_byte)NK_CLAMP(0, g, 255);
7471  ret.b = (nk_byte)NK_CLAMP(0, b, 255);
7472  ret.a = (nk_byte)NK_CLAMP(0, a, 255);
7473  return ret;
7474 }
7475 NK_API struct nk_color
7476 nk_rgb_hex(const char *rgb)
7477 {
7478  struct nk_color col;
7479  const char *c = rgb;
7480  if (*c == '#') c++;
7481  col.r = (nk_byte)nk_parse_hex(c, 2);
7482  col.g = (nk_byte)nk_parse_hex(c+2, 2);
7483  col.b = (nk_byte)nk_parse_hex(c+4, 2);
7484  col.a = 255;
7485  return col;
7486 }
7487 NK_API struct nk_color
7488 nk_rgba_hex(const char *rgb)
7489 {
7490  struct nk_color col;
7491  const char *c = rgb;
7492  if (*c == '#') c++;
7493  col.r = (nk_byte)nk_parse_hex(c, 2);
7494  col.g = (nk_byte)nk_parse_hex(c+2, 2);
7495  col.b = (nk_byte)nk_parse_hex(c+4, 2);
7496  col.a = (nk_byte)nk_parse_hex(c+6, 2);
7497  return col;
7498 }
7499 NK_API void
7500 nk_color_hex_rgba(char *output, struct nk_color col)
7501 {
7502  #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
7503  output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
7504  output[1] = (char)NK_TO_HEX((col.r & 0x0F));
7505  output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
7506  output[3] = (char)NK_TO_HEX((col.g & 0x0F));
7507  output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
7508  output[5] = (char)NK_TO_HEX((col.b & 0x0F));
7509  output[6] = (char)NK_TO_HEX((col.a & 0xF0) >> 4);
7510  output[7] = (char)NK_TO_HEX((col.a & 0x0F));
7511  output[8] = '\0';
7512  #undef NK_TO_HEX
7513 }
7514 NK_API void
7515 nk_color_hex_rgb(char *output, struct nk_color col)
7516 {
7517  #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
7518  output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
7519  output[1] = (char)NK_TO_HEX((col.r & 0x0F));
7520  output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
7521  output[3] = (char)NK_TO_HEX((col.g & 0x0F));
7522  output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
7523  output[5] = (char)NK_TO_HEX((col.b & 0x0F));
7524  output[6] = '\0';
7525  #undef NK_TO_HEX
7526 }
7527 NK_API struct nk_color
7528 nk_rgba_iv(const int *c)
7529 {
7530  return nk_rgba(c[0], c[1], c[2], c[3]);
7531 }
7532 NK_API struct nk_color
7533 nk_rgba_bv(const nk_byte *c)
7534 {
7535  return nk_rgba(c[0], c[1], c[2], c[3]);
7536 }
7537 NK_API struct nk_color
7538 nk_rgb(int r, int g, int b)
7539 {
7540  struct nk_color ret;
7541  ret.r = (nk_byte)NK_CLAMP(0, r, 255);
7542  ret.g = (nk_byte)NK_CLAMP(0, g, 255);
7543  ret.b = (nk_byte)NK_CLAMP(0, b, 255);
7544  ret.a = (nk_byte)255;
7545  return ret;
7546 }
7547 NK_API struct nk_color
7548 nk_rgb_iv(const int *c)
7549 {
7550  return nk_rgb(c[0], c[1], c[2]);
7551 }
7552 NK_API struct nk_color
7553 nk_rgb_bv(const nk_byte* c)
7554 {
7555  return nk_rgb(c[0], c[1], c[2]);
7556 }
7557 NK_API struct nk_color
7558 nk_rgba_u32(nk_uint in)
7559 {
7560  struct nk_color ret;
7561  ret.r = (in & 0xFF);
7562  ret.g = ((in >> 8) & 0xFF);
7563  ret.b = ((in >> 16) & 0xFF);
7564  ret.a = (nk_byte)((in >> 24) & 0xFF);
7565  return ret;
7566 }
7567 NK_API struct nk_color
7568 nk_rgba_f(float r, float g, float b, float a)
7569 {
7570  struct nk_color ret;
7571  ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
7572  ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
7573  ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
7574  ret.a = (nk_byte)(NK_SATURATE(a) * 255.0f);
7575  return ret;
7576 }
7577 NK_API struct nk_color
7578 nk_rgba_fv(const float *c)
7579 {
7580  return nk_rgba_f(c[0], c[1], c[2], c[3]);
7581 }
7582 NK_API struct nk_color
7583 nk_rgba_cf(struct nk_colorf c)
7584 {
7585  return nk_rgba_f(c.r, c.g, c.b, c.a);
7586 }
7587 NK_API struct nk_color
7588 nk_rgb_f(float r, float g, float b)
7589 {
7590  struct nk_color ret;
7591  ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
7592  ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
7593  ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
7594  ret.a = 255;
7595  return ret;
7596 }
7597 NK_API struct nk_color
7598 nk_rgb_fv(const float *c)
7599 {
7600  return nk_rgb_f(c[0], c[1], c[2]);
7601 }
7602 NK_API struct nk_color
7603 nk_rgb_cf(struct nk_colorf c)
7604 {
7605  return nk_rgb_f(c.r, c.g, c.b);
7606 }
7607 NK_API struct nk_color
7608 nk_hsv(int h, int s, int v)
7609 {
7610  return nk_hsva(h, s, v, 255);
7611 }
7612 NK_API struct nk_color
7613 nk_hsv_iv(const int *c)
7614 {
7615  return nk_hsv(c[0], c[1], c[2]);
7616 }
7617 NK_API struct nk_color
7618 nk_hsv_bv(const nk_byte *c)
7619 {
7620  return nk_hsv(c[0], c[1], c[2]);
7621 }
7622 NK_API struct nk_color
7623 nk_hsv_f(float h, float s, float v)
7624 {
7625  return nk_hsva_f(h, s, v, 1.0f);
7626 }
7627 NK_API struct nk_color
7628 nk_hsv_fv(const float *c)
7629 {
7630  return nk_hsv_f(c[0], c[1], c[2]);
7631 }
7632 NK_API struct nk_color
7633 nk_hsva(int h, int s, int v, int a)
7634 {
7635  float hf = ((float)NK_CLAMP(0, h, 255)) / 255.0f;
7636  float sf = ((float)NK_CLAMP(0, s, 255)) / 255.0f;
7637  float vf = ((float)NK_CLAMP(0, v, 255)) / 255.0f;
7638  float af = ((float)NK_CLAMP(0, a, 255)) / 255.0f;
7639  return nk_hsva_f(hf, sf, vf, af);
7640 }
7641 NK_API struct nk_color
7642 nk_hsva_iv(const int *c)
7643 {
7644  return nk_hsva(c[0], c[1], c[2], c[3]);
7645 }
7646 NK_API struct nk_color
7647 nk_hsva_bv(const nk_byte *c)
7648 {
7649  return nk_hsva(c[0], c[1], c[2], c[3]);
7650 }
7651 NK_API struct nk_colorf
7652 nk_hsva_colorf(float h, float s, float v, float a)
7653 {
7654  int i;
7655  float p, q, t, f;
7656  struct nk_colorf out = {0,0,0,0};
7657  if (s <= 0.0f) {
7658  out.r = v; out.g = v; out.b = v; out.a = a;
7659  return out;
7660  }
7661  h = h / (60.0f/360.0f);
7662  i = (int)h;
7663  f = h - (float)i;
7664  p = v * (1.0f - s);
7665  q = v * (1.0f - (s * f));
7666  t = v * (1.0f - s * (1.0f - f));
7667 
7668  switch (i) {
7669  case 0: default: out.r = v; out.g = t; out.b = p; break;
7670  case 1: out.r = q; out.g = v; out.b = p; break;
7671  case 2: out.r = p; out.g = v; out.b = t; break;
7672  case 3: out.r = p; out.g = q; out.b = v; break;
7673  case 4: out.r = t; out.g = p; out.b = v; break;
7674  case 5: out.r = v; out.g = p; out.b = q; break;}
7675  out.a = a;
7676  return out;
7677 }
7678 NK_API struct nk_colorf
7679 nk_hsva_colorfv(float *c)
7680 {
7681  return nk_hsva_colorf(c[0], c[1], c[2], c[3]);
7682 }
7683 NK_API struct nk_color
7684 nk_hsva_f(float h, float s, float v, float a)
7685 {
7686  struct nk_colorf c = nk_hsva_colorf(h, s, v, a);
7687  return nk_rgba_f(c.r, c.g, c.b, c.a);
7688 }
7689 NK_API struct nk_color
7690 nk_hsva_fv(const float *c)
7691 {
7692  return nk_hsva_f(c[0], c[1], c[2], c[3]);
7693 }
7695 nk_color_u32(struct nk_color in)
7696 {
7697  nk_uint out = (nk_uint)in.r;
7698  out |= ((nk_uint)in.g << 8);
7699  out |= ((nk_uint)in.b << 16);
7700  out |= ((nk_uint)in.a << 24);
7701  return out;
7702 }
7703 NK_API void
7704 nk_color_f(float *r, float *g, float *b, float *a, struct nk_color in)
7705 {
7706  NK_STORAGE const float s = 1.0f/255.0f;
7707  *r = (float)in.r * s;
7708  *g = (float)in.g * s;
7709  *b = (float)in.b * s;
7710  *a = (float)in.a * s;
7711 }
7712 NK_API void
7713 nk_color_fv(float *c, struct nk_color in)
7714 {
7715  nk_color_f(&c[0], &c[1], &c[2], &c[3], in);
7716 }
7717 NK_API struct nk_colorf
7718 nk_color_cf(struct nk_color in)
7719 {
7720  struct nk_colorf o;
7721  nk_color_f(&o.r, &o.g, &o.b, &o.a, in);
7722  return o;
7723 }
7724 NK_API void
7725 nk_color_d(double *r, double *g, double *b, double *a, struct nk_color in)
7726 {
7727  NK_STORAGE const double s = 1.0/255.0;
7728  *r = (double)in.r * s;
7729  *g = (double)in.g * s;
7730  *b = (double)in.b * s;
7731  *a = (double)in.a * s;
7732 }
7733 NK_API void
7734 nk_color_dv(double *c, struct nk_color in)
7735 {
7736  nk_color_d(&c[0], &c[1], &c[2], &c[3], in);
7737 }
7738 NK_API void
7739 nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color in)
7740 {
7741  float a;
7742  nk_color_hsva_f(out_h, out_s, out_v, &a, in);
7743 }
7744 NK_API void
7745 nk_color_hsv_fv(float *out, struct nk_color in)
7746 {
7747  float a;
7748  nk_color_hsva_f(&out[0], &out[1], &out[2], &a, in);
7749 }
7750 NK_API void
7751 nk_colorf_hsva_f(float *out_h, float *out_s,
7752  float *out_v, float *out_a, struct nk_colorf in)
7753 {
7754  float chroma;
7755  float K = 0.0f;
7756  if (in.g < in.b) {
7757  const float t = in.g; in.g = in.b; in.b = t;
7758  K = -1.f;
7759  }
7760  if (in.r < in.g) {
7761  const float t = in.r; in.r = in.g; in.g = t;
7762  K = -2.f/6.0f - K;
7763  }
7764  chroma = in.r - ((in.g < in.b) ? in.g: in.b);
7765  *out_h = NK_ABS(K + (in.g - in.b)/(6.0f * chroma + 1e-20f));
7766  *out_s = chroma / (in.r + 1e-20f);
7767  *out_v = in.r;
7768  *out_a = in.a;
7769 
7770 }
7771 NK_API void
7772 nk_colorf_hsva_fv(float *hsva, struct nk_colorf in)
7773 {
7774  nk_colorf_hsva_f(&hsva[0], &hsva[1], &hsva[2], &hsva[3], in);
7775 }
7776 NK_API void
7777 nk_color_hsva_f(float *out_h, float *out_s,
7778  float *out_v, float *out_a, struct nk_color in)
7779 {
7780  struct nk_colorf col;
7781  nk_color_f(&col.r,&col.g,&col.b,&col.a, in);
7782  nk_colorf_hsva_f(out_h, out_s, out_v, out_a, col);
7783 }
7784 NK_API void
7785 nk_color_hsva_fv(float *out, struct nk_color in)
7786 {
7787  nk_color_hsva_f(&out[0], &out[1], &out[2], &out[3], in);
7788 }
7789 NK_API void
7790 nk_color_hsva_i(int *out_h, int *out_s, int *out_v,
7791  int *out_a, struct nk_color in)
7792 {
7793  float h,s,v,a;
7794  nk_color_hsva_f(&h, &s, &v, &a, in);
7795  *out_h = (nk_byte)(h * 255.0f);
7796  *out_s = (nk_byte)(s * 255.0f);
7797  *out_v = (nk_byte)(v * 255.0f);
7798  *out_a = (nk_byte)(a * 255.0f);
7799 }
7800 NK_API void
7801 nk_color_hsva_iv(int *out, struct nk_color in)
7802 {
7803  nk_color_hsva_i(&out[0], &out[1], &out[2], &out[3], in);
7804 }
7805 NK_API void
7806 nk_color_hsva_bv(nk_byte *out, struct nk_color in)
7807 {
7808  int tmp[4];
7809  nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
7810  out[0] = (nk_byte)tmp[0];
7811  out[1] = (nk_byte)tmp[1];
7812  out[2] = (nk_byte)tmp[2];
7813  out[3] = (nk_byte)tmp[3];
7814 }
7815 NK_API void
7816 nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color in)
7817 {
7818  int tmp[4];
7819  nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
7820  *h = (nk_byte)tmp[0];
7821  *s = (nk_byte)tmp[1];
7822  *v = (nk_byte)tmp[2];
7823  *a = (nk_byte)tmp[3];
7824 }
7825 NK_API void
7826 nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color in)
7827 {
7828  int a;
7829  nk_color_hsva_i(out_h, out_s, out_v, &a, in);
7830 }
7831 NK_API void
7832 nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color in)
7833 {
7834  int tmp[4];
7835  nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
7836  *out_h = (nk_byte)tmp[0];
7837  *out_s = (nk_byte)tmp[1];
7838  *out_v = (nk_byte)tmp[2];
7839 }
7840 NK_API void
7841 nk_color_hsv_iv(int *out, struct nk_color in)
7842 {
7843  nk_color_hsv_i(&out[0], &out[1], &out[2], in);
7844 }
7845 NK_API void
7846 nk_color_hsv_bv(nk_byte *out, struct nk_color in)
7847 {
7848  int tmp[4];
7849  nk_color_hsv_i(&tmp[0], &tmp[1], &tmp[2], in);
7850  out[0] = (nk_byte)tmp[0];
7851  out[1] = (nk_byte)tmp[1];
7852  out[2] = (nk_byte)tmp[2];
7853 }
7854 
7855 
7856 
7857 
7858 
7859 /* ===============================================================
7860  *
7861  * UTF-8
7862  *
7863  * ===============================================================*/
7864 NK_GLOBAL const nk_byte nk_utfbyte[NK_UTF_SIZE+1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
7865 NK_GLOBAL const nk_byte nk_utfmask[NK_UTF_SIZE+1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
7866 NK_GLOBAL const nk_uint nk_utfmin[NK_UTF_SIZE+1] = {0, 0, 0x80, 0x800, 0x10000};
7867 NK_GLOBAL const nk_uint nk_utfmax[NK_UTF_SIZE+1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
7868 
7869 NK_INTERN int
7870 nk_utf_validate(nk_rune *u, int i)
7871 {
7872  NK_ASSERT(u);
7873  if (!u) return 0;
7874  if (!NK_BETWEEN(*u, nk_utfmin[i], nk_utfmax[i]) ||
7875  NK_BETWEEN(*u, 0xD800, 0xDFFF))
7876  *u = NK_UTF_INVALID;
7877  for (i = 1; *u > nk_utfmax[i]; ++i);
7878  return i;
7879 }
7881 nk_utf_decode_byte(char c, int *i)
7882 {
7883  NK_ASSERT(i);
7884  if (!i) return 0;
7885  for(*i = 0; *i < (int)NK_LEN(nk_utfmask); ++(*i)) {
7886  if (((nk_byte)c & nk_utfmask[*i]) == nk_utfbyte[*i])
7887  return (nk_byte)(c & ~nk_utfmask[*i]);
7888  }
7889  return 0;
7890 }
7891 NK_API int
7892 nk_utf_decode(const char *c, nk_rune *u, int clen)
7893 {
7894  int i, j, len, type=0;
7895  nk_rune udecoded;
7896 
7897  NK_ASSERT(c);
7898  NK_ASSERT(u);
7899 
7900  if (!c || !u) return 0;
7901  if (!clen) return 0;
7902  *u = NK_UTF_INVALID;
7903 
7904  udecoded = nk_utf_decode_byte(c[0], &len);
7905  if (!NK_BETWEEN(len, 1, NK_UTF_SIZE))
7906  return 1;
7907 
7908  for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
7909  udecoded = (udecoded << 6) | nk_utf_decode_byte(c[i], &type);
7910  if (type != 0)
7911  return j;
7912  }
7913  if (j < len)
7914  return 0;
7915  *u = udecoded;
7916  nk_utf_validate(u, len);
7917  return len;
7918 }
7919 NK_INTERN char
7920 nk_utf_encode_byte(nk_rune u, int i)
7921 {
7922  return (char)((nk_utfbyte[i]) | ((nk_byte)u & ~nk_utfmask[i]));
7923 }
7924 NK_API int
7925 nk_utf_encode(nk_rune u, char *c, int clen)
7926 {
7927  int len, i;
7928  len = nk_utf_validate(&u, 0);
7929  if (clen < len || !len || len > NK_UTF_SIZE)
7930  return 0;
7931 
7932  for (i = len - 1; i != 0; --i) {
7933  c[i] = nk_utf_encode_byte(u, 0);
7934  u >>= 6;
7935  }
7936  c[0] = nk_utf_encode_byte(u, len);
7937  return len;
7938 }
7939 NK_API int
7940 nk_utf_len(const char *str, int len)
7941 {
7942  const char *text;
7943  int glyphs = 0;
7944  int text_len;
7945  int glyph_len;
7946  int src_len = 0;
7947  nk_rune unicode;
7948 
7949  NK_ASSERT(str);
7950  if (!str || !len) return 0;
7951 
7952  text = str;
7953  text_len = len;
7954  glyph_len = nk_utf_decode(text, &unicode, text_len);
7955  while (glyph_len && src_len < len) {
7956  glyphs++;
7957  src_len = src_len + glyph_len;
7958  glyph_len = nk_utf_decode(text + src_len, &unicode, text_len - src_len);
7959  }
7960  return glyphs;
7961 }
7962 NK_API const char*
7963 nk_utf_at(const char *buffer, int length, int index,
7964  nk_rune *unicode, int *len)
7965 {
7966  int i = 0;
7967  int src_len = 0;
7968  int glyph_len = 0;
7969  const char *text;
7970  int text_len;
7971 
7972  NK_ASSERT(buffer);
7973  NK_ASSERT(unicode);
7974  NK_ASSERT(len);
7975 
7976  if (!buffer || !unicode || !len) return 0;
7977  if (index < 0) {
7978  *unicode = NK_UTF_INVALID;
7979  *len = 0;
7980  return 0;
7981  }
7982 
7983  text = buffer;
7984  text_len = length;
7985  glyph_len = nk_utf_decode(text, unicode, text_len);
7986  while (glyph_len) {
7987  if (i == index) {
7988  *len = glyph_len;
7989  break;
7990  }
7991 
7992  i++;
7993  src_len = src_len + glyph_len;
7994  glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
7995  }
7996  if (i != index) return 0;
7997  return buffer + src_len;
7998 }
7999 
8000 
8001 
8002 
8003 
8004 /* ==============================================================
8005  *
8006  * BUFFER
8007  *
8008  * ===============================================================*/
8009 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
8010 NK_LIB void*
8011 nk_malloc(nk_handle unused, void *old,nk_size size)
8012 {
8013  NK_UNUSED(unused);
8014  NK_UNUSED(old);
8015  return malloc(size);
8016 }
8017 NK_LIB void
8018 nk_mfree(nk_handle unused, void *ptr)
8019 {
8020  NK_UNUSED(unused);
8021  free(ptr);
8022 }
8023 NK_API void
8024 nk_buffer_init_default(struct nk_buffer *buffer)
8025 {
8026  struct nk_allocator alloc;
8027  alloc.userdata.ptr = 0;
8028  alloc.alloc = nk_malloc;
8029  alloc.free = nk_mfree;
8030  nk_buffer_init(buffer, &alloc, NK_BUFFER_DEFAULT_INITIAL_SIZE);
8031 }
8032 #endif
8033 
8034 NK_API void
8035 nk_buffer_init(struct nk_buffer *b, const struct nk_allocator *a,
8036  nk_size initial_size)
8037 {
8038  NK_ASSERT(b);
8039  NK_ASSERT(a);
8040  NK_ASSERT(initial_size);
8041  if (!b || !a || !initial_size) return;
8042 
8043  nk_zero(b, sizeof(*b));
8044  b->type = NK_BUFFER_DYNAMIC;
8045  b->memory.ptr = a->alloc(a->userdata,0, initial_size);
8046  b->memory.size = initial_size;
8047  b->size = initial_size;
8048  b->grow_factor = 2.0f;
8049  b->pool = *a;
8050 }
8051 NK_API void
8052 nk_buffer_init_fixed(struct nk_buffer *b, void *m, nk_size size)
8053 {
8054  NK_ASSERT(b);
8055  NK_ASSERT(m);
8056  NK_ASSERT(size);
8057  if (!b || !m || !size) return;
8058 
8059  nk_zero(b, sizeof(*b));
8060  b->type = NK_BUFFER_FIXED;
8061  b->memory.ptr = m;
8062  b->memory.size = size;
8063  b->size = size;
8064 }
8065 NK_LIB void*
8066 nk_buffer_align(void *unaligned,
8067  nk_size align, nk_size *alignment,
8068  enum nk_buffer_allocation_type type)
8069 {
8070  void *memory = 0;
8071  switch (type) {
8072  default:
8073  case NK_BUFFER_MAX:
8074  case NK_BUFFER_FRONT:
8075  if (align) {
8076  memory = NK_ALIGN_PTR(unaligned, align);
8077  *alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
8078  } else {
8079  memory = unaligned;
8080  *alignment = 0;
8081  }
8082  break;
8083  case NK_BUFFER_BACK:
8084  if (align) {
8085  memory = NK_ALIGN_PTR_BACK(unaligned, align);
8086  *alignment = (nk_size)((nk_byte*)unaligned - (nk_byte*)memory);
8087  } else {
8088  memory = unaligned;
8089  *alignment = 0;
8090  }
8091  break;
8092  }
8093  return memory;
8094 }
8095 NK_LIB void*
8096 nk_buffer_realloc(struct nk_buffer *b, nk_size capacity, nk_size *size)
8097 {
8098  void *temp;
8099  nk_size buffer_size;
8100 
8101  NK_ASSERT(b);
8102  NK_ASSERT(size);
8103  if (!b || !size || !b->pool.alloc || !b->pool.free)
8104  return 0;
8105 
8106  buffer_size = b->memory.size;
8107  temp = b->pool.alloc(b->pool.userdata, b->memory.ptr, capacity);
8108  NK_ASSERT(temp);
8109  if (!temp) return 0;
8110 
8111  *size = capacity;
8112  if (temp != b->memory.ptr) {
8113  NK_MEMCPY(temp, b->memory.ptr, buffer_size);
8114  b->pool.free(b->pool.userdata, b->memory.ptr);
8115  }
8116 
8117  if (b->size == buffer_size) {
8118  /* no back buffer so just set correct size */
8119  b->size = capacity;
8120  return temp;
8121  } else {
8122  /* copy back buffer to the end of the new buffer */
8123  void *dst, *src;
8124  nk_size back_size;
8125  back_size = buffer_size - b->size;
8126  dst = nk_ptr_add(void, temp, capacity - back_size);
8127  src = nk_ptr_add(void, temp, b->size);
8128  NK_MEMCPY(dst, src, back_size);
8129  b->size = capacity - back_size;
8130  }
8131  return temp;
8132 }
8133 NK_LIB void*
8134 nk_buffer_alloc(struct nk_buffer *b, enum nk_buffer_allocation_type type,
8135  nk_size size, nk_size align)
8136 {
8137  int full;
8138  nk_size alignment;
8139  void *unaligned;
8140  void *memory;
8141 
8142  NK_ASSERT(b);
8143  NK_ASSERT(size);
8144  if (!b || !size) return 0;
8145  b->needed += size;
8146 
8147  /* calculate total size with needed alignment + size */
8148  if (type == NK_BUFFER_FRONT)
8149  unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated);
8150  else unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size);
8151  memory = nk_buffer_align(unaligned, align, &alignment, type);
8152 
8153  /* check if buffer has enough memory*/
8154  if (type == NK_BUFFER_FRONT)
8155  full = ((b->allocated + size + alignment) > b->size);
8156  else full = ((b->size - NK_MIN(b->size,(size + alignment))) <= b->allocated);
8157 
8158  if (full) {
8159  nk_size capacity;
8160  if (b->type != NK_BUFFER_DYNAMIC)
8161  return 0;
8162  NK_ASSERT(b->pool.alloc && b->pool.free);
8163  if (b->type != NK_BUFFER_DYNAMIC || !b->pool.alloc || !b->pool.free)
8164  return 0;
8165 
8166  /* buffer is full so allocate bigger buffer if dynamic */
8167  capacity = (nk_size)((float)b->memory.size * b->grow_factor);
8168  capacity = NK_MAX(capacity, nk_round_up_pow2((nk_uint)(b->allocated + size)));
8169  b->memory.ptr = nk_buffer_realloc(b, capacity, &b->memory.size);
8170  if (!b->memory.ptr) return 0;
8171 
8172  /* align newly allocated pointer */
8173  if (type == NK_BUFFER_FRONT)
8174  unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated);
8175  else unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size);
8176  memory = nk_buffer_align(unaligned, align, &alignment, type);
8177  }
8178  if (type == NK_BUFFER_FRONT)
8179  b->allocated += size + alignment;
8180  else b->size -= (size + alignment);
8181  b->needed += alignment;
8182  b->calls++;
8183  return memory;
8184 }
8185 NK_API void
8187  const void *memory, nk_size size, nk_size align)
8188 {
8189  void *mem = nk_buffer_alloc(b, type, size, align);
8190  if (!mem) return;
8191  NK_MEMCPY(mem, memory, size);
8192 }
8193 NK_API void
8194 nk_buffer_mark(struct nk_buffer *buffer, enum nk_buffer_allocation_type type)
8195 {
8196  NK_ASSERT(buffer);
8197  if (!buffer) return;
8198  buffer->marker[type].active = nk_true;
8199  if (type == NK_BUFFER_BACK)
8200  buffer->marker[type].offset = buffer->size;
8201  else buffer->marker[type].offset = buffer->allocated;
8202 }
8203 NK_API void
8204 nk_buffer_reset(struct nk_buffer *buffer, enum nk_buffer_allocation_type type)
8205 {
8206  NK_ASSERT(buffer);
8207  if (!buffer) return;
8208  if (type == NK_BUFFER_BACK) {
8209  /* reset back buffer either back to marker or empty */
8210  buffer->needed -= (buffer->memory.size - buffer->marker[type].offset);
8211  if (buffer->marker[type].active)
8212  buffer->size = buffer->marker[type].offset;
8213  else buffer->size = buffer->memory.size;
8214  buffer->marker[type].active = nk_false;
8215  } else {
8216  /* reset front buffer either back to back marker or empty */
8217  buffer->needed -= (buffer->allocated - buffer->marker[type].offset);
8218  if (buffer->marker[type].active)
8219  buffer->allocated = buffer->marker[type].offset;
8220  else buffer->allocated = 0;
8221  buffer->marker[type].active = nk_false;
8222  }
8223 }
8224 NK_API void
8225 nk_buffer_clear(struct nk_buffer *b)
8226 {
8227  NK_ASSERT(b);
8228  if (!b) return;
8229  b->allocated = 0;
8230  b->size = b->memory.size;
8231  b->calls = 0;
8232  b->needed = 0;
8233 }
8234 NK_API void
8235 nk_buffer_free(struct nk_buffer *b)
8236 {
8237  NK_ASSERT(b);
8238  if (!b || !b->memory.ptr) return;
8239  if (b->type == NK_BUFFER_FIXED) return;
8240  if (!b->pool.free) return;
8241  NK_ASSERT(b->pool.free);
8242  b->pool.free(b->pool.userdata, b->memory.ptr);
8243 }
8244 NK_API void
8245 nk_buffer_info(struct nk_memory_status *s, struct nk_buffer *b)
8246 {
8247  NK_ASSERT(b);
8248  NK_ASSERT(s);
8249  if (!s || !b) return;
8250  s->allocated = b->allocated;
8251  s->size = b->memory.size;
8252  s->needed = b->needed;
8253  s->memory = b->memory.ptr;
8254  s->calls = b->calls;
8255 }
8256 NK_API void*
8257 nk_buffer_memory(struct nk_buffer *buffer)
8258 {
8259  NK_ASSERT(buffer);
8260  if (!buffer) return 0;
8261  return buffer->memory.ptr;
8262 }
8263 NK_API const void*
8264 nk_buffer_memory_const(const struct nk_buffer *buffer)
8265 {
8266  NK_ASSERT(buffer);
8267  if (!buffer) return 0;
8268  return buffer->memory.ptr;
8269 }
8271 nk_buffer_total(struct nk_buffer *buffer)
8272 {
8273  NK_ASSERT(buffer);
8274  if (!buffer) return 0;
8275  return buffer->memory.size;
8276 }
8277 
8278 
8279 
8280 
8281 
8282 /* ===============================================================
8283  *
8284  * STRING
8285  *
8286  * ===============================================================*/
8287 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
8288 NK_API void
8289 nk_str_init_default(struct nk_str *str)
8290 {
8291  struct nk_allocator alloc;
8292  alloc.userdata.ptr = 0;
8293  alloc.alloc = nk_malloc;
8294  alloc.free = nk_mfree;
8295  nk_buffer_init(&str->buffer, &alloc, 32);
8296  str->len = 0;
8297 }
8298 #endif
8299 
8300 NK_API void
8301 nk_str_init(struct nk_str *str, const struct nk_allocator *alloc, nk_size size)
8302 {
8303  nk_buffer_init(&str->buffer, alloc, size);
8304  str->len = 0;
8305 }
8306 NK_API void
8307 nk_str_init_fixed(struct nk_str *str, void *memory, nk_size size)
8308 {
8309  nk_buffer_init_fixed(&str->buffer, memory, size);
8310  str->len = 0;
8311 }
8312 NK_API int
8313 nk_str_append_text_char(struct nk_str *s, const char *str, int len)
8314 {
8315  char *mem;
8316  NK_ASSERT(s);
8317  NK_ASSERT(str);
8318  if (!s || !str || !len) return 0;
8319  mem = (char*)nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0);
8320  if (!mem) return 0;
8321  NK_MEMCPY(mem, str, (nk_size)len * sizeof(char));
8322  s->len += nk_utf_len(str, len);
8323  return len;
8324 }
8325 NK_API int
8326 nk_str_append_str_char(struct nk_str *s, const char *str)
8327 {
8328  return nk_str_append_text_char(s, str, nk_strlen(str));
8329 }
8330 NK_API int
8331 nk_str_append_text_utf8(struct nk_str *str, const char *text, int len)
8332 {
8333  int i = 0;
8334  int byte_len = 0;
8335  nk_rune unicode;
8336  if (!str || !text || !len) return 0;
8337  for (i = 0; i < len; ++i)
8338  byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
8339  nk_str_append_text_char(str, text, byte_len);
8340  return len;
8341 }
8342 NK_API int
8343 nk_str_append_str_utf8(struct nk_str *str, const char *text)
8344 {
8345  int runes = 0;
8346  int byte_len = 0;
8347  int num_runes = 0;
8348  int glyph_len = 0;
8349  nk_rune unicode;
8350  if (!str || !text) return 0;
8351 
8352  glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
8353  while (unicode != '\0' && glyph_len) {
8354  glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
8355  byte_len += glyph_len;
8356  num_runes++;
8357  }
8358  nk_str_append_text_char(str, text, byte_len);
8359  return runes;
8360 }
8361 NK_API int
8362 nk_str_append_text_runes(struct nk_str *str, const nk_rune *text, int len)
8363 {
8364  int i = 0;
8365  int byte_len = 0;
8366  nk_glyph glyph;
8367 
8368  NK_ASSERT(str);
8369  if (!str || !text || !len) return 0;
8370  for (i = 0; i < len; ++i) {
8371  byte_len = nk_utf_encode(text[i], glyph, NK_UTF_SIZE);
8372  if (!byte_len) break;
8373  nk_str_append_text_char(str, glyph, byte_len);
8374  }
8375  return len;
8376 }
8377 NK_API int
8378 nk_str_append_str_runes(struct nk_str *str, const nk_rune *runes)
8379 {
8380  int i = 0;
8381  nk_glyph glyph;
8382  int byte_len;
8383  NK_ASSERT(str);
8384  if (!str || !runes) return 0;
8385  while (runes[i] != '\0') {
8386  byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
8387  nk_str_append_text_char(str, glyph, byte_len);
8388  i++;
8389  }
8390  return i;
8391 }
8392 NK_API int
8393 nk_str_insert_at_char(struct nk_str *s, int pos, const char *str, int len)
8394 {
8395  int i;
8396  void *mem;
8397  char *src;
8398  char *dst;
8399 
8400  int copylen;
8401  NK_ASSERT(s);
8402  NK_ASSERT(str);
8403  NK_ASSERT(len >= 0);
8404  if (!s || !str || !len || (nk_size)pos > s->buffer.allocated) return 0;
8405  if ((s->buffer.allocated + (nk_size)len >= s->buffer.memory.size) &&
8406  (s->buffer.type == NK_BUFFER_FIXED)) return 0;
8407 
8408  copylen = (int)s->buffer.allocated - pos;
8409  if (!copylen) {
8410  nk_str_append_text_char(s, str, len);
8411  return 1;
8412  }
8413  mem = nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0);
8414  if (!mem) return 0;
8415 
8416  /* memmove */
8417  NK_ASSERT(((int)pos + (int)len + ((int)copylen - 1)) >= 0);
8418  NK_ASSERT(((int)pos + ((int)copylen - 1)) >= 0);
8419  dst = nk_ptr_add(char, s->buffer.memory.ptr, pos + len + (copylen - 1));
8420  src = nk_ptr_add(char, s->buffer.memory.ptr, pos + (copylen-1));
8421  for (i = 0; i < copylen; ++i) *dst-- = *src--;
8422  mem = nk_ptr_add(void, s->buffer.memory.ptr, pos);
8423  NK_MEMCPY(mem, str, (nk_size)len * sizeof(char));
8424  s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
8425  return 1;
8426 }
8427 NK_API int
8428 nk_str_insert_at_rune(struct nk_str *str, int pos, const char *cstr, int len)
8429 {
8430  int glyph_len;
8431  nk_rune unicode;
8432  const char *begin;
8433  const char *buffer;
8434 
8435  NK_ASSERT(str);
8436  NK_ASSERT(cstr);
8437  NK_ASSERT(len);
8438  if (!str || !cstr || !len) return 0;
8439  begin = nk_str_at_rune(str, pos, &unicode, &glyph_len);
8440  if (!str->len)
8441  return nk_str_append_text_char(str, cstr, len);
8442  buffer = nk_str_get_const(str);
8443  if (!begin) return 0;
8444  return nk_str_insert_at_char(str, (int)(begin - buffer), cstr, len);
8445 }
8446 NK_API int
8447 nk_str_insert_text_char(struct nk_str *str, int pos, const char *text, int len)
8448 {
8449  return nk_str_insert_text_utf8(str, pos, text, len);
8450 }
8451 NK_API int
8452 nk_str_insert_str_char(struct nk_str *str, int pos, const char *text)
8453 {
8454  return nk_str_insert_text_utf8(str, pos, text, nk_strlen(text));
8455 }
8456 NK_API int
8457 nk_str_insert_text_utf8(struct nk_str *str, int pos, const char *text, int len)
8458 {
8459  int i = 0;
8460  int byte_len = 0;
8461  nk_rune unicode;
8462 
8463  NK_ASSERT(str);
8464  NK_ASSERT(text);
8465  if (!str || !text || !len) return 0;
8466  for (i = 0; i < len; ++i)
8467  byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
8468  nk_str_insert_at_rune(str, pos, text, byte_len);
8469  return len;
8470 }
8471 NK_API int
8472 nk_str_insert_str_utf8(struct nk_str *str, int pos, const char *text)
8473 {
8474  int runes = 0;
8475  int byte_len = 0;
8476  int num_runes = 0;
8477  int glyph_len = 0;
8478  nk_rune unicode;
8479  if (!str || !text) return 0;
8480 
8481  glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
8482  while (unicode != '\0' && glyph_len) {
8483  glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
8484  byte_len += glyph_len;
8485  num_runes++;
8486  }
8487  nk_str_insert_at_rune(str, pos, text, byte_len);
8488  return runes;
8489 }
8490 NK_API int
8491 nk_str_insert_text_runes(struct nk_str *str, int pos, const nk_rune *runes, int len)
8492 {
8493  int i = 0;
8494  int byte_len = 0;
8495  nk_glyph glyph;
8496 
8497  NK_ASSERT(str);
8498  if (!str || !runes || !len) return 0;
8499  for (i = 0; i < len; ++i) {
8500  byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
8501  if (!byte_len) break;
8502  nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
8503  }
8504  return len;
8505 }
8506 NK_API int
8507 nk_str_insert_str_runes(struct nk_str *str, int pos, const nk_rune *runes)
8508 {
8509  int i = 0;
8510  nk_glyph glyph;
8511  int byte_len;
8512  NK_ASSERT(str);
8513  if (!str || !runes) return 0;
8514  while (runes[i] != '\0') {
8515  byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
8516  nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
8517  i++;
8518  }
8519  return i;
8520 }
8521 NK_API void
8522 nk_str_remove_chars(struct nk_str *s, int len)
8523 {
8524  NK_ASSERT(s);
8525  NK_ASSERT(len >= 0);
8526  if (!s || len < 0 || (nk_size)len > s->buffer.allocated) return;
8527  NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0);
8528  s->buffer.allocated -= (nk_size)len;
8529  s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
8530 }
8531 NK_API void
8532 nk_str_remove_runes(struct nk_str *str, int len)
8533 {
8534  int index;
8535  const char *begin;
8536  const char *end;
8537  nk_rune unicode;
8538 
8539  NK_ASSERT(str);
8540  NK_ASSERT(len >= 0);
8541  if (!str || len < 0) return;
8542  if (len >= str->len) {
8543  str->len = 0;
8544  return;
8545  }
8546 
8547  index = str->len - len;
8548  begin = nk_str_at_rune(str, index, &unicode, &len);
8549  end = (const char*)str->buffer.memory.ptr + str->buffer.allocated;
8550  nk_str_remove_chars(str, (int)(end-begin)+1);
8551 }
8552 NK_API void
8553 nk_str_delete_chars(struct nk_str *s, int pos, int len)
8554 {
8555  NK_ASSERT(s);
8556  if (!s || !len || (nk_size)pos > s->buffer.allocated ||
8557  (nk_size)(pos + len) > s->buffer.allocated) return;
8558 
8559  if ((nk_size)(pos + len) < s->buffer.allocated) {
8560  /* memmove */
8561  char *dst = nk_ptr_add(char, s->buffer.memory.ptr, pos);
8562  char *src = nk_ptr_add(char, s->buffer.memory.ptr, pos + len);
8563  NK_MEMCPY(dst, src, s->buffer.allocated - (nk_size)(pos + len));
8564  NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0);
8565  s->buffer.allocated -= (nk_size)len;
8566  } else nk_str_remove_chars(s, len);
8567  s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
8568 }
8569 NK_API void
8570 nk_str_delete_runes(struct nk_str *s, int pos, int len)
8571 {
8572  char *temp;
8573  nk_rune unicode;
8574  char *begin;
8575  char *end;
8576  int unused;
8577 
8578  NK_ASSERT(s);
8579  NK_ASSERT(s->len >= pos + len);
8580  if (s->len < pos + len)
8581  len = NK_CLAMP(0, (s->len - pos), s->len);
8582  if (!len) return;
8583 
8584  temp = (char *)s->buffer.memory.ptr;
8585  begin = nk_str_at_rune(s, pos, &unicode, &unused);
8586  if (!begin) return;
8587  s->buffer.memory.ptr = begin;
8588  end = nk_str_at_rune(s, len, &unicode, &unused);
8589  s->buffer.memory.ptr = temp;
8590  if (!end) return;
8591  nk_str_delete_chars(s, (int)(begin - temp), (int)(end - begin));
8592 }
8593 NK_API char*
8594 nk_str_at_char(struct nk_str *s, int pos)
8595 {
8596  NK_ASSERT(s);
8597  if (!s || pos > (int)s->buffer.allocated) return 0;
8598  return nk_ptr_add(char, s->buffer.memory.ptr, pos);
8599 }
8600 NK_API char*
8601 nk_str_at_rune(struct nk_str *str, int pos, nk_rune *unicode, int *len)
8602 {
8603  int i = 0;
8604  int src_len = 0;
8605  int glyph_len = 0;
8606  char *text;
8607  int text_len;
8608 
8609  NK_ASSERT(str);
8610  NK_ASSERT(unicode);
8611  NK_ASSERT(len);
8612 
8613  if (!str || !unicode || !len) return 0;
8614  if (pos < 0) {
8615  *unicode = 0;
8616  *len = 0;
8617  return 0;
8618  }
8619 
8620  text = (char*)str->buffer.memory.ptr;
8621  text_len = (int)str->buffer.allocated;
8622  glyph_len = nk_utf_decode(text, unicode, text_len);
8623  while (glyph_len) {
8624  if (i == pos) {
8625  *len = glyph_len;
8626  break;
8627  }
8628 
8629  i++;
8630  src_len = src_len + glyph_len;
8631  glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
8632  }
8633  if (i != pos) return 0;
8634  return text + src_len;
8635 }
8636 NK_API const char*
8637 nk_str_at_char_const(const struct nk_str *s, int pos)
8638 {
8639  NK_ASSERT(s);
8640  if (!s || pos > (int)s->buffer.allocated) return 0;
8641  return nk_ptr_add(char, s->buffer.memory.ptr, pos);
8642 }
8643 NK_API const char*
8644 nk_str_at_const(const struct nk_str *str, int pos, nk_rune *unicode, int *len)
8645 {
8646  int i = 0;
8647  int src_len = 0;
8648  int glyph_len = 0;
8649  char *text;
8650  int text_len;
8651 
8652  NK_ASSERT(str);
8653  NK_ASSERT(unicode);
8654  NK_ASSERT(len);
8655 
8656  if (!str || !unicode || !len) return 0;
8657  if (pos < 0) {
8658  *unicode = 0;
8659  *len = 0;
8660  return 0;
8661  }
8662 
8663  text = (char*)str->buffer.memory.ptr;
8664  text_len = (int)str->buffer.allocated;
8665  glyph_len = nk_utf_decode(text, unicode, text_len);
8666  while (glyph_len) {
8667  if (i == pos) {
8668  *len = glyph_len;
8669  break;
8670  }
8671 
8672  i++;
8673  src_len = src_len + glyph_len;
8674  glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
8675  }
8676  if (i != pos) return 0;
8677  return text + src_len;
8678 }
8680 nk_str_rune_at(const struct nk_str *str, int pos)
8681 {
8682  int len;
8683  nk_rune unicode = 0;
8684  nk_str_at_const(str, pos, &unicode, &len);
8685  return unicode;
8686 }
8687 NK_API char*
8688 nk_str_get(struct nk_str *s)
8689 {
8690  NK_ASSERT(s);
8691  if (!s || !s->len || !s->buffer.allocated) return 0;
8692  return (char*)s->buffer.memory.ptr;
8693 }
8694 NK_API const char*
8695 nk_str_get_const(const struct nk_str *s)
8696 {
8697  NK_ASSERT(s);
8698  if (!s || !s->len || !s->buffer.allocated) return 0;
8699  return (const char*)s->buffer.memory.ptr;
8700 }
8701 NK_API int
8702 nk_str_len(struct nk_str *s)
8703 {
8704  NK_ASSERT(s);
8705  if (!s || !s->len || !s->buffer.allocated) return 0;
8706  return s->len;
8707 }
8708 NK_API int
8709 nk_str_len_char(struct nk_str *s)
8710 {
8711  NK_ASSERT(s);
8712  if (!s || !s->len || !s->buffer.allocated) return 0;
8713  return (int)s->buffer.allocated;
8714 }
8715 NK_API void
8716 nk_str_clear(struct nk_str *str)
8717 {
8718  NK_ASSERT(str);
8719  nk_buffer_clear(&str->buffer);
8720  str->len = 0;
8721 }
8722 NK_API void
8723 nk_str_free(struct nk_str *str)
8724 {
8725  NK_ASSERT(str);
8726  nk_buffer_free(&str->buffer);
8727  str->len = 0;
8728 }
8729 
8730 
8731 
8732 
8733 
8734 /* ==============================================================
8735  *
8736  * DRAW
8737  *
8738  * ===============================================================*/
8739 NK_LIB void
8740 nk_command_buffer_init(struct nk_command_buffer *cb,
8741  struct nk_buffer *b, enum nk_command_clipping clip)
8742 {
8743  NK_ASSERT(cb);
8744  NK_ASSERT(b);
8745  if (!cb || !b) return;
8746  cb->base = b;
8747  cb->use_clipping = (int)clip;
8748  cb->begin = b->allocated;
8749  cb->end = b->allocated;
8750  cb->last = b->allocated;
8751 }
8752 NK_LIB void
8753 nk_command_buffer_reset(struct nk_command_buffer *b)
8754 {
8755  NK_ASSERT(b);
8756  if (!b) return;
8757  b->begin = 0;
8758  b->end = 0;
8759  b->last = 0;
8760  b->clip = nk_null_rect;
8761 #ifdef NK_INCLUDE_COMMAND_USERDATA
8762  b->userdata.ptr = 0;
8763 #endif
8764 }
8765 NK_LIB void*
8766 nk_command_buffer_push(struct nk_command_buffer* b,
8767  enum nk_command_type t, nk_size size)
8768 {
8769  NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_command);
8770  struct nk_command *cmd;
8771  nk_size alignment;
8772  void *unaligned;
8773  void *memory;
8774 
8775  NK_ASSERT(b);
8776  NK_ASSERT(b->base);
8777  if (!b) return 0;
8778  cmd = (struct nk_command*)nk_buffer_alloc(b->base,NK_BUFFER_FRONT,size,align);
8779  if (!cmd) return 0;
8780 
8781  /* make sure the offset to the next command is aligned */
8782  b->last = (nk_size)((nk_byte*)cmd - (nk_byte*)b->base->memory.ptr);
8783  unaligned = (nk_byte*)cmd + size;
8784  memory = NK_ALIGN_PTR(unaligned, align);
8785  alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
8786 #ifdef NK_ZERO_COMMAND_MEMORY
8787  NK_MEMSET(cmd, 0, size + alignment);
8788 #endif
8789 
8790  cmd->type = t;
8791  cmd->next = b->base->allocated + alignment;
8792 #ifdef NK_INCLUDE_COMMAND_USERDATA
8793  cmd->userdata = b->userdata;
8794 #endif
8795  b->end = cmd->next;
8796  return cmd;
8797 }
8798 NK_API void
8799 nk_push_scissor(struct nk_command_buffer *b, struct nk_rect r)
8800 {
8801  struct nk_command_scissor *cmd;
8802  NK_ASSERT(b);
8803  if (!b) return;
8804 
8805  b->clip.x = r.x;
8806  b->clip.y = r.y;
8807  b->clip.w = r.w;
8808  b->clip.h = r.h;
8809  cmd = (struct nk_command_scissor*)
8810  nk_command_buffer_push(b, NK_COMMAND_SCISSOR, sizeof(*cmd));
8811 
8812  if (!cmd) return;
8813  cmd->x = (short)r.x;
8814  cmd->y = (short)r.y;
8815  cmd->w = (unsigned short)NK_MAX(0, r.w);
8816  cmd->h = (unsigned short)NK_MAX(0, r.h);
8817 }
8818 NK_API void
8819 nk_stroke_line(struct nk_command_buffer *b, float x0, float y0,
8820  float x1, float y1, float line_thickness, struct nk_color c)
8821 {
8822  struct nk_command_line *cmd;
8823  NK_ASSERT(b);
8824  if (!b || line_thickness <= 0) return;
8825  cmd = (struct nk_command_line*)
8826  nk_command_buffer_push(b, NK_COMMAND_LINE, sizeof(*cmd));
8827  if (!cmd) return;
8828  cmd->line_thickness = (unsigned short)line_thickness;
8829  cmd->begin.x = (short)x0;
8830  cmd->begin.y = (short)y0;
8831  cmd->end.x = (short)x1;
8832  cmd->end.y = (short)y1;
8833  cmd->color = c;
8834 }
8835 NK_API void
8836 nk_stroke_curve(struct nk_command_buffer *b, float ax, float ay,
8837  float ctrl0x, float ctrl0y, float ctrl1x, float ctrl1y,
8838  float bx, float by, float line_thickness, struct nk_color col)
8839 {
8840  struct nk_command_curve *cmd;
8841  NK_ASSERT(b);
8842  if (!b || col.a == 0 || line_thickness <= 0) return;
8843 
8844  cmd = (struct nk_command_curve*)
8845  nk_command_buffer_push(b, NK_COMMAND_CURVE, sizeof(*cmd));
8846  if (!cmd) return;
8847  cmd->line_thickness = (unsigned short)line_thickness;
8848  cmd->begin.x = (short)ax;
8849  cmd->begin.y = (short)ay;
8850  cmd->ctrl[0].x = (short)ctrl0x;
8851  cmd->ctrl[0].y = (short)ctrl0y;
8852  cmd->ctrl[1].x = (short)ctrl1x;
8853  cmd->ctrl[1].y = (short)ctrl1y;
8854  cmd->end.x = (short)bx;
8855  cmd->end.y = (short)by;
8856  cmd->color = col;
8857 }
8858 NK_API void
8859 nk_stroke_rect(struct nk_command_buffer *b, struct nk_rect rect,
8860  float rounding, float line_thickness, struct nk_color c)
8861 {
8862  struct nk_command_rect *cmd;
8863  NK_ASSERT(b);
8864  if (!b || c.a == 0 || rect.w == 0 || rect.h == 0 || line_thickness <= 0) return;
8865  if (b->use_clipping) {
8866  const struct nk_rect *clip = &b->clip;
8867  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
8868  clip->x, clip->y, clip->w, clip->h)) return;
8869  }
8870  cmd = (struct nk_command_rect*)
8871  nk_command_buffer_push(b, NK_COMMAND_RECT, sizeof(*cmd));
8872  if (!cmd) return;
8873  cmd->rounding = (unsigned short)rounding;
8874  cmd->line_thickness = (unsigned short)line_thickness;
8875  cmd->x = (short)rect.x;
8876  cmd->y = (short)rect.y;
8877  cmd->w = (unsigned short)NK_MAX(0, rect.w);
8878  cmd->h = (unsigned short)NK_MAX(0, rect.h);
8879  cmd->color = c;
8880 }
8881 NK_API void
8882 nk_fill_rect(struct nk_command_buffer *b, struct nk_rect rect,
8883  float rounding, struct nk_color c)
8884 {
8885  struct nk_command_rect_filled *cmd;
8886  NK_ASSERT(b);
8887  if (!b || c.a == 0 || rect.w == 0 || rect.h == 0) return;
8888  if (b->use_clipping) {
8889  const struct nk_rect *clip = &b->clip;
8890  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
8891  clip->x, clip->y, clip->w, clip->h)) return;
8892  }
8893 
8894  cmd = (struct nk_command_rect_filled*)
8895  nk_command_buffer_push(b, NK_COMMAND_RECT_FILLED, sizeof(*cmd));
8896  if (!cmd) return;
8897  cmd->rounding = (unsigned short)rounding;
8898  cmd->x = (short)rect.x;
8899  cmd->y = (short)rect.y;
8900  cmd->w = (unsigned short)NK_MAX(0, rect.w);
8901  cmd->h = (unsigned short)NK_MAX(0, rect.h);
8902  cmd->color = c;
8903 }
8904 NK_API void
8905 nk_fill_rect_multi_color(struct nk_command_buffer *b, struct nk_rect rect,
8906  struct nk_color left, struct nk_color top, struct nk_color right,
8907  struct nk_color bottom)
8908 {
8909  struct nk_command_rect_multi_color *cmd;
8910  NK_ASSERT(b);
8911  if (!b || rect.w == 0 || rect.h == 0) return;
8912  if (b->use_clipping) {
8913  const struct nk_rect *clip = &b->clip;
8914  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
8915  clip->x, clip->y, clip->w, clip->h)) return;
8916  }
8917 
8918  cmd = (struct nk_command_rect_multi_color*)
8919  nk_command_buffer_push(b, NK_COMMAND_RECT_MULTI_COLOR, sizeof(*cmd));
8920  if (!cmd) return;
8921  cmd->x = (short)rect.x;
8922  cmd->y = (short)rect.y;
8923  cmd->w = (unsigned short)NK_MAX(0, rect.w);
8924  cmd->h = (unsigned short)NK_MAX(0, rect.h);
8925  cmd->left = left;
8926  cmd->top = top;
8927  cmd->right = right;
8928  cmd->bottom = bottom;
8929 }
8930 NK_API void
8931 nk_stroke_circle(struct nk_command_buffer *b, struct nk_rect r,
8932  float line_thickness, struct nk_color c)
8933 {
8934  struct nk_command_circle *cmd;
8935  if (!b || r.w == 0 || r.h == 0 || line_thickness <= 0) return;
8936  if (b->use_clipping) {
8937  const struct nk_rect *clip = &b->clip;
8938  if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
8939  return;
8940  }
8941 
8942  cmd = (struct nk_command_circle*)
8943  nk_command_buffer_push(b, NK_COMMAND_CIRCLE, sizeof(*cmd));
8944  if (!cmd) return;
8945  cmd->line_thickness = (unsigned short)line_thickness;
8946  cmd->x = (short)r.x;
8947  cmd->y = (short)r.y;
8948  cmd->w = (unsigned short)NK_MAX(r.w, 0);
8949  cmd->h = (unsigned short)NK_MAX(r.h, 0);
8950  cmd->color = c;
8951 }
8952 NK_API void
8953 nk_fill_circle(struct nk_command_buffer *b, struct nk_rect r, struct nk_color c)
8954 {
8955  struct nk_command_circle_filled *cmd;
8956  NK_ASSERT(b);
8957  if (!b || c.a == 0 || r.w == 0 || r.h == 0) return;
8958  if (b->use_clipping) {
8959  const struct nk_rect *clip = &b->clip;
8960  if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
8961  return;
8962  }
8963 
8964  cmd = (struct nk_command_circle_filled*)
8965  nk_command_buffer_push(b, NK_COMMAND_CIRCLE_FILLED, sizeof(*cmd));
8966  if (!cmd) return;
8967  cmd->x = (short)r.x;
8968  cmd->y = (short)r.y;
8969  cmd->w = (unsigned short)NK_MAX(r.w, 0);
8970  cmd->h = (unsigned short)NK_MAX(r.h, 0);
8971  cmd->color = c;
8972 }
8973 NK_API void
8974 nk_stroke_arc(struct nk_command_buffer *b, float cx, float cy, float radius,
8975  float a_min, float a_max, float line_thickness, struct nk_color c)
8976 {
8977  struct nk_command_arc *cmd;
8978  if (!b || c.a == 0 || line_thickness <= 0) return;
8979  cmd = (struct nk_command_arc*)
8980  nk_command_buffer_push(b, NK_COMMAND_ARC, sizeof(*cmd));
8981  if (!cmd) return;
8982  cmd->line_thickness = (unsigned short)line_thickness;
8983  cmd->cx = (short)cx;
8984  cmd->cy = (short)cy;
8985  cmd->r = (unsigned short)radius;
8986  cmd->a[0] = a_min;
8987  cmd->a[1] = a_max;
8988  cmd->color = c;
8989 }
8990 NK_API void
8991 nk_fill_arc(struct nk_command_buffer *b, float cx, float cy, float radius,
8992  float a_min, float a_max, struct nk_color c)
8993 {
8994  struct nk_command_arc_filled *cmd;
8995  NK_ASSERT(b);
8996  if (!b || c.a == 0) return;
8997  cmd = (struct nk_command_arc_filled*)
8998  nk_command_buffer_push(b, NK_COMMAND_ARC_FILLED, sizeof(*cmd));
8999  if (!cmd) return;
9000  cmd->cx = (short)cx;
9001  cmd->cy = (short)cy;
9002  cmd->r = (unsigned short)radius;
9003  cmd->a[0] = a_min;
9004  cmd->a[1] = a_max;
9005  cmd->color = c;
9006 }
9007 NK_API void
9008 nk_stroke_triangle(struct nk_command_buffer *b, float x0, float y0, float x1,
9009  float y1, float x2, float y2, float line_thickness, struct nk_color c)
9010 {
9011  struct nk_command_triangle *cmd;
9012  NK_ASSERT(b);
9013  if (!b || c.a == 0 || line_thickness <= 0) return;
9014  if (b->use_clipping) {
9015  const struct nk_rect *clip = &b->clip;
9016  if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
9017  !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
9018  !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
9019  return;
9020  }
9021 
9022  cmd = (struct nk_command_triangle*)
9023  nk_command_buffer_push(b, NK_COMMAND_TRIANGLE, sizeof(*cmd));
9024  if (!cmd) return;
9025  cmd->line_thickness = (unsigned short)line_thickness;
9026  cmd->a.x = (short)x0;
9027  cmd->a.y = (short)y0;
9028  cmd->b.x = (short)x1;
9029  cmd->b.y = (short)y1;
9030  cmd->c.x = (short)x2;
9031  cmd->c.y = (short)y2;
9032  cmd->color = c;
9033 }
9034 NK_API void
9035 nk_fill_triangle(struct nk_command_buffer *b, float x0, float y0, float x1,
9036  float y1, float x2, float y2, struct nk_color c)
9037 {
9038  struct nk_command_triangle_filled *cmd;
9039  NK_ASSERT(b);
9040  if (!b || c.a == 0) return;
9041  if (!b) return;
9042  if (b->use_clipping) {
9043  const struct nk_rect *clip = &b->clip;
9044  if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
9045  !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
9046  !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
9047  return;
9048  }
9049 
9050  cmd = (struct nk_command_triangle_filled*)
9051  nk_command_buffer_push(b, NK_COMMAND_TRIANGLE_FILLED, sizeof(*cmd));
9052  if (!cmd) return;
9053  cmd->a.x = (short)x0;
9054  cmd->a.y = (short)y0;
9055  cmd->b.x = (short)x1;
9056  cmd->b.y = (short)y1;
9057  cmd->c.x = (short)x2;
9058  cmd->c.y = (short)y2;
9059  cmd->color = c;
9060 }
9061 NK_API void
9062 nk_stroke_polygon(struct nk_command_buffer *b, float *points, int point_count,
9063  float line_thickness, struct nk_color col)
9064 {
9065  int i;
9066  nk_size size = 0;
9067  struct nk_command_polygon *cmd;
9068 
9069  NK_ASSERT(b);
9070  if (!b || col.a == 0 || line_thickness <= 0) return;
9071  size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
9072  cmd = (struct nk_command_polygon*) nk_command_buffer_push(b, NK_COMMAND_POLYGON, size);
9073  if (!cmd) return;
9074  cmd->color = col;
9075  cmd->line_thickness = (unsigned short)line_thickness;
9076  cmd->point_count = (unsigned short)point_count;
9077  for (i = 0; i < point_count; ++i) {
9078  cmd->points[i].x = (short)points[i*2];
9079  cmd->points[i].y = (short)points[i*2+1];
9080  }
9081 }
9082 NK_API void
9083 nk_fill_polygon(struct nk_command_buffer *b, float *points, int point_count,
9084  struct nk_color col)
9085 {
9086  int i;
9087  nk_size size = 0;
9088  struct nk_command_polygon_filled *cmd;
9089 
9090  NK_ASSERT(b);
9091  if (!b || col.a == 0) return;
9092  size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
9093  cmd = (struct nk_command_polygon_filled*)
9094  nk_command_buffer_push(b, NK_COMMAND_POLYGON_FILLED, size);
9095  if (!cmd) return;
9096  cmd->color = col;
9097  cmd->point_count = (unsigned short)point_count;
9098  for (i = 0; i < point_count; ++i) {
9099  cmd->points[i].x = (short)points[i*2+0];
9100  cmd->points[i].y = (short)points[i*2+1];
9101  }
9102 }
9103 NK_API void
9105  float line_thickness, struct nk_color col)
9106 {
9107  int i;
9108  nk_size size = 0;
9109  struct nk_command_polyline *cmd;
9110 
9111  NK_ASSERT(b);
9112  if (!b || col.a == 0 || line_thickness <= 0) return;
9113  size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
9114  cmd = (struct nk_command_polyline*) nk_command_buffer_push(b, NK_COMMAND_POLYLINE, size);
9115  if (!cmd) return;
9116  cmd->color = col;
9117  cmd->point_count = (unsigned short)point_count;
9118  cmd->line_thickness = (unsigned short)line_thickness;
9119  for (i = 0; i < point_count; ++i) {
9120  cmd->points[i].x = (short)points[i*2];
9121  cmd->points[i].y = (short)points[i*2+1];
9122  }
9123 }
9124 NK_API void
9125 nk_draw_image(struct nk_command_buffer *b, struct nk_rect r,
9126  const struct nk_image *img, struct nk_color col)
9127 {
9128  struct nk_command_image *cmd;
9129  NK_ASSERT(b);
9130  if (!b) return;
9131  if (b->use_clipping) {
9132  const struct nk_rect *c = &b->clip;
9133  if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
9134  return;
9135  }
9136 
9137  cmd = (struct nk_command_image*)
9138  nk_command_buffer_push(b, NK_COMMAND_IMAGE, sizeof(*cmd));
9139  if (!cmd) return;
9140  cmd->x = (short)r.x;
9141  cmd->y = (short)r.y;
9142  cmd->w = (unsigned short)NK_MAX(0, r.w);
9143  cmd->h = (unsigned short)NK_MAX(0, r.h);
9144  cmd->img = *img;
9145  cmd->col = col;
9146 }
9147 NK_API void
9148 nk_push_custom(struct nk_command_buffer *b, struct nk_rect r,
9150 {
9151  struct nk_command_custom *cmd;
9152  NK_ASSERT(b);
9153  if (!b) return;
9154  if (b->use_clipping) {
9155  const struct nk_rect *c = &b->clip;
9156  if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
9157  return;
9158  }
9159 
9160  cmd = (struct nk_command_custom*)
9161  nk_command_buffer_push(b, NK_COMMAND_CUSTOM, sizeof(*cmd));
9162  if (!cmd) return;
9163  cmd->x = (short)r.x;
9164  cmd->y = (short)r.y;
9165  cmd->w = (unsigned short)NK_MAX(0, r.w);
9166  cmd->h = (unsigned short)NK_MAX(0, r.h);
9167  cmd->callback_data = usr;
9168  cmd->callback = cb;
9169 }
9170 NK_API void
9171 nk_draw_text(struct nk_command_buffer *b, struct nk_rect r,
9172  const char *string, int length, const struct nk_user_font *font,
9173  struct nk_color bg, struct nk_color fg)
9174 {
9175  float text_width = 0;
9176  struct nk_command_text *cmd;
9177 
9178  NK_ASSERT(b);
9179  NK_ASSERT(font);
9180  if (!b || !string || !length || (bg.a == 0 && fg.a == 0)) return;
9181  if (b->use_clipping) {
9182  const struct nk_rect *c = &b->clip;
9183  if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
9184  return;
9185  }
9186 
9187  /* make sure text fits inside bounds */
9188  text_width = font->width(font->userdata, font->height, string, length);
9189  if (text_width > r.w){
9190  int glyphs = 0;
9191  float txt_width = (float)text_width;
9192  length = nk_text_clamp(font, string, length, r.w, &glyphs, &txt_width, 0,0);
9193  }
9194 
9195  if (!length) return;
9196  cmd = (struct nk_command_text*)
9197  nk_command_buffer_push(b, NK_COMMAND_TEXT, sizeof(*cmd) + (nk_size)(length + 1));
9198  if (!cmd) return;
9199  cmd->x = (short)r.x;
9200  cmd->y = (short)r.y;
9201  cmd->w = (unsigned short)r.w;
9202  cmd->h = (unsigned short)r.h;
9203  cmd->background = bg;
9204  cmd->foreground = fg;
9205  cmd->font = font;
9206  cmd->length = length;
9207  cmd->height = font->height;
9208  NK_MEMCPY(cmd->string, string, (nk_size)length);
9209  cmd->string[length] = '\0';
9210 }
9211 
9212 
9213 
9214 
9215 
9216 /* ===============================================================
9217  *
9218  * VERTEX
9219  *
9220  * ===============================================================*/
9221 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
9222 NK_API void
9223 nk_draw_list_init(struct nk_draw_list *list)
9224 {
9225  nk_size i = 0;
9226  NK_ASSERT(list);
9227  if (!list) return;
9228  nk_zero(list, sizeof(*list));
9229  for (i = 0; i < NK_LEN(list->circle_vtx); ++i) {
9230  const float a = ((float)i / (float)NK_LEN(list->circle_vtx)) * 2 * NK_PI;
9231  list->circle_vtx[i].x = (float)NK_COS(a);
9232  list->circle_vtx[i].y = (float)NK_SIN(a);
9233  }
9234 }
9235 NK_API void
9236 nk_draw_list_setup(struct nk_draw_list *canvas, const struct nk_convert_config *config,
9237  struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements,
9238  enum nk_anti_aliasing line_aa, enum nk_anti_aliasing shape_aa)
9239 {
9240  NK_ASSERT(canvas);
9241  NK_ASSERT(config);
9242  NK_ASSERT(cmds);
9243  NK_ASSERT(vertices);
9244  NK_ASSERT(elements);
9245  if (!canvas || !config || !cmds || !vertices || !elements)
9246  return;
9247 
9248  canvas->buffer = cmds;
9249  canvas->config = *config;
9250  canvas->elements = elements;
9251  canvas->vertices = vertices;
9252  canvas->line_AA = line_aa;
9253  canvas->shape_AA = shape_aa;
9254  canvas->clip_rect = nk_null_rect;
9255 
9256  canvas->cmd_offset = 0;
9257  canvas->element_count = 0;
9258  canvas->vertex_count = 0;
9259  canvas->cmd_offset = 0;
9260  canvas->cmd_count = 0;
9261  canvas->path_count = 0;
9262 }
9263 NK_API const struct nk_draw_command*
9264 nk__draw_list_begin(const struct nk_draw_list *canvas, const struct nk_buffer *buffer)
9265 {
9266  nk_byte *memory;
9267  nk_size offset;
9268  const struct nk_draw_command *cmd;
9269 
9270  NK_ASSERT(buffer);
9271  if (!buffer || !buffer->size || !canvas->cmd_count)
9272  return 0;
9273 
9274  memory = (nk_byte*)buffer->memory.ptr;
9275  offset = buffer->memory.size - canvas->cmd_offset;
9276  cmd = nk_ptr_add(const struct nk_draw_command, memory, offset);
9277  return cmd;
9278 }
9279 NK_API const struct nk_draw_command*
9280 nk__draw_list_end(const struct nk_draw_list *canvas, const struct nk_buffer *buffer)
9281 {
9282  nk_size size;
9283  nk_size offset;
9284  nk_byte *memory;
9285  const struct nk_draw_command *end;
9286 
9287  NK_ASSERT(buffer);
9288  NK_ASSERT(canvas);
9289  if (!buffer || !canvas)
9290  return 0;
9291 
9292  memory = (nk_byte*)buffer->memory.ptr;
9293  size = buffer->memory.size;
9294  offset = size - canvas->cmd_offset;
9295  end = nk_ptr_add(const struct nk_draw_command, memory, offset);
9296  end -= (canvas->cmd_count-1);
9297  return end;
9298 }
9299 NK_API const struct nk_draw_command*
9300 nk__draw_list_next(const struct nk_draw_command *cmd,
9301  const struct nk_buffer *buffer, const struct nk_draw_list *canvas)
9302 {
9303  const struct nk_draw_command *end;
9304  NK_ASSERT(buffer);
9305  NK_ASSERT(canvas);
9306  if (!cmd || !buffer || !canvas)
9307  return 0;
9308 
9309  end = nk__draw_list_end(canvas, buffer);
9310  if (cmd <= end) return 0;
9311  return (cmd-1);
9312 }
9313 NK_INTERN struct nk_vec2*
9314 nk_draw_list_alloc_path(struct nk_draw_list *list, int count)
9315 {
9316  struct nk_vec2 *points;
9317  NK_STORAGE const nk_size point_align = NK_ALIGNOF(struct nk_vec2);
9318  NK_STORAGE const nk_size point_size = sizeof(struct nk_vec2);
9319  points = (struct nk_vec2*)
9320  nk_buffer_alloc(list->buffer, NK_BUFFER_FRONT,
9321  point_size * (nk_size)count, point_align);
9322 
9323  if (!points) return 0;
9324  if (!list->path_offset) {
9325  void *memory = nk_buffer_memory(list->buffer);
9326  list->path_offset = (unsigned int)((nk_byte*)points - (nk_byte*)memory);
9327  }
9328  list->path_count += (unsigned int)count;
9329  return points;
9330 }
9331 NK_INTERN struct nk_vec2
9332 nk_draw_list_path_last(struct nk_draw_list *list)
9333 {
9334  void *memory;
9335  struct nk_vec2 *point;
9336  NK_ASSERT(list->path_count);
9337  memory = nk_buffer_memory(list->buffer);
9338  point = nk_ptr_add(struct nk_vec2, memory, list->path_offset);
9339  point += (list->path_count-1);
9340  return *point;
9341 }
9342 NK_INTERN struct nk_draw_command*
9343 nk_draw_list_push_command(struct nk_draw_list *list, struct nk_rect clip,
9344  nk_handle texture)
9345 {
9346  NK_STORAGE const nk_size cmd_align = NK_ALIGNOF(struct nk_draw_command);
9347  NK_STORAGE const nk_size cmd_size = sizeof(struct nk_draw_command);
9348  struct nk_draw_command *cmd;
9349 
9350  NK_ASSERT(list);
9351  cmd = (struct nk_draw_command*)
9352  nk_buffer_alloc(list->buffer, NK_BUFFER_BACK, cmd_size, cmd_align);
9353 
9354  if (!cmd) return 0;
9355  if (!list->cmd_count) {
9356  nk_byte *memory = (nk_byte*)nk_buffer_memory(list->buffer);
9357  nk_size total = nk_buffer_total(list->buffer);
9358  memory = nk_ptr_add(nk_byte, memory, total);
9359  list->cmd_offset = (nk_size)(memory - (nk_byte*)cmd);
9360  }
9361 
9362  cmd->elem_count = 0;
9363  cmd->clip_rect = clip;
9364  cmd->texture = texture;
9365 #ifdef NK_INCLUDE_COMMAND_USERDATA
9366  cmd->userdata = list->userdata;
9367 #endif
9368 
9369  list->cmd_count++;
9370  list->clip_rect = clip;
9371  return cmd;
9372 }
9373 NK_INTERN struct nk_draw_command*
9374 nk_draw_list_command_last(struct nk_draw_list *list)
9375 {
9376  void *memory;
9377  nk_size size;
9378  struct nk_draw_command *cmd;
9379  NK_ASSERT(list->cmd_count);
9380 
9381  memory = nk_buffer_memory(list->buffer);
9382  size = nk_buffer_total(list->buffer);
9383  cmd = nk_ptr_add(struct nk_draw_command, memory, size - list->cmd_offset);
9384  return (cmd - (list->cmd_count-1));
9385 }
9386 NK_INTERN void
9387 nk_draw_list_add_clip(struct nk_draw_list *list, struct nk_rect rect)
9388 {
9389  NK_ASSERT(list);
9390  if (!list) return;
9391  if (!list->cmd_count) {
9392  nk_draw_list_push_command(list, rect, list->config.null.texture);
9393  } else {
9394  struct nk_draw_command *prev = nk_draw_list_command_last(list);
9395  if (prev->elem_count == 0)
9396  prev->clip_rect = rect;
9397  nk_draw_list_push_command(list, rect, prev->texture);
9398  }
9399 }
9400 NK_INTERN void
9401 nk_draw_list_push_image(struct nk_draw_list *list, nk_handle texture)
9402 {
9403  NK_ASSERT(list);
9404  if (!list) return;
9405  if (!list->cmd_count) {
9406  nk_draw_list_push_command(list, nk_null_rect, texture);
9407  } else {
9408  struct nk_draw_command *prev = nk_draw_list_command_last(list);
9409  if (prev->elem_count == 0) {
9410  prev->texture = texture;
9411  #ifdef NK_INCLUDE_COMMAND_USERDATA
9412  prev->userdata = list->userdata;
9413  #endif
9414  } else if (prev->texture.id != texture.id
9415  #ifdef NK_INCLUDE_COMMAND_USERDATA
9416  || prev->userdata.id != list->userdata.id
9417  #endif
9418  ) nk_draw_list_push_command(list, prev->clip_rect, texture);
9419  }
9420 }
9421 #ifdef NK_INCLUDE_COMMAND_USERDATA
9422 NK_API void
9423 nk_draw_list_push_userdata(struct nk_draw_list *list, nk_handle userdata)
9424 {
9425  list->userdata = userdata;
9426 }
9427 #endif
9428 NK_INTERN void*
9429 nk_draw_list_alloc_vertices(struct nk_draw_list *list, nk_size count)
9430 {
9431  void *vtx;
9432  NK_ASSERT(list);
9433  if (!list) return 0;
9434  vtx = nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT,
9435  list->config.vertex_size*count, list->config.vertex_alignment);
9436  if (!vtx) return 0;
9437  list->vertex_count += (unsigned int)count;
9438 
9439  /* This assert triggers because your are drawing a lot of stuff and nuklear
9440  * defined `nk_draw_index` as `nk_ushort` to safe space be default.
9441  *
9442  * So you reached the maximum number of indicies or rather vertexes.
9443  * To solve this issue please change typdef `nk_draw_index` to `nk_uint`
9444  * and don't forget to specify the new element size in your drawing
9445  * backend (OpenGL, DirectX, ...). For example in OpenGL for `glDrawElements`
9446  * instead of specifing `GL_UNSIGNED_SHORT` you have to define `GL_UNSIGNED_INT`.
9447  * Sorry for the inconvenience. */
9448  if(sizeof(nk_draw_index)==2) NK_ASSERT((list->vertex_count < NK_USHORT_MAX &&
9449  "To many verticies for 16-bit vertex indicies. Please read comment above on how to solve this problem"));
9450  return vtx;
9451 }
9452 NK_INTERN nk_draw_index*
9453 nk_draw_list_alloc_elements(struct nk_draw_list *list, nk_size count)
9454 {
9455  nk_draw_index *ids;
9456  struct nk_draw_command *cmd;
9457  NK_STORAGE const nk_size elem_align = NK_ALIGNOF(nk_draw_index);
9458  NK_STORAGE const nk_size elem_size = sizeof(nk_draw_index);
9459  NK_ASSERT(list);
9460  if (!list) return 0;
9461 
9462  ids = (nk_draw_index*)
9463  nk_buffer_alloc(list->elements, NK_BUFFER_FRONT, elem_size*count, elem_align);
9464  if (!ids) return 0;
9465  cmd = nk_draw_list_command_last(list);
9466  list->element_count += (unsigned int)count;
9467  cmd->elem_count += (unsigned int)count;
9468  return ids;
9469 }
9470 NK_INTERN int
9471 nk_draw_vertex_layout_element_is_end_of_layout(
9472  const struct nk_draw_vertex_layout_element *element)
9473 {
9474  return (element->attribute == NK_VERTEX_ATTRIBUTE_COUNT ||
9475  element->format == NK_FORMAT_COUNT);
9476 }
9477 NK_INTERN void
9478 nk_draw_vertex_color(void *attr, const float *vals,
9479  enum nk_draw_vertex_layout_format format)
9480 {
9481  /* if this triggers you tried to provide a value format for a color */
9482  float val[4];
9483  NK_ASSERT(format >= NK_FORMAT_COLOR_BEGIN);
9484  NK_ASSERT(format <= NK_FORMAT_COLOR_END);
9485  if (format < NK_FORMAT_COLOR_BEGIN || format > NK_FORMAT_COLOR_END) return;
9486 
9487  val[0] = NK_SATURATE(vals[0]);
9488  val[1] = NK_SATURATE(vals[1]);
9489  val[2] = NK_SATURATE(vals[2]);
9490  val[3] = NK_SATURATE(vals[3]);
9491 
9492  switch (format) {
9493  default: NK_ASSERT(0 && "Invalid vertex layout color format"); break;
9494  case NK_FORMAT_R8G8B8A8:
9495  case NK_FORMAT_R8G8B8: {
9496  struct nk_color col = nk_rgba_fv(val);
9497  NK_MEMCPY(attr, &col.r, sizeof(col));
9498  } break;
9499  case NK_FORMAT_B8G8R8A8: {
9500  struct nk_color col = nk_rgba_fv(val);
9501  struct nk_color bgra = nk_rgba(col.b, col.g, col.r, col.a);
9502  NK_MEMCPY(attr, &bgra, sizeof(bgra));
9503  } break;
9504  case NK_FORMAT_R16G15B16: {
9505  nk_ushort col[3];
9506  col[0] = (nk_ushort)(val[0]*(float)NK_USHORT_MAX);
9507  col[1] = (nk_ushort)(val[1]*(float)NK_USHORT_MAX);
9508  col[2] = (nk_ushort)(val[2]*(float)NK_USHORT_MAX);
9509  NK_MEMCPY(attr, col, sizeof(col));
9510  } break;
9511  case NK_FORMAT_R16G15B16A16: {
9512  nk_ushort col[4];
9513  col[0] = (nk_ushort)(val[0]*(float)NK_USHORT_MAX);
9514  col[1] = (nk_ushort)(val[1]*(float)NK_USHORT_MAX);
9515  col[2] = (nk_ushort)(val[2]*(float)NK_USHORT_MAX);
9516  col[3] = (nk_ushort)(val[3]*(float)NK_USHORT_MAX);
9517  NK_MEMCPY(attr, col, sizeof(col));
9518  } break;
9519  case NK_FORMAT_R32G32B32: {
9520  nk_uint col[3];
9521  col[0] = (nk_uint)(val[0]*(float)NK_UINT_MAX);
9522  col[1] = (nk_uint)(val[1]*(float)NK_UINT_MAX);
9523  col[2] = (nk_uint)(val[2]*(float)NK_UINT_MAX);
9524  NK_MEMCPY(attr, col, sizeof(col));
9525  } break;
9526  case NK_FORMAT_R32G32B32A32: {
9527  nk_uint col[4];
9528  col[0] = (nk_uint)(val[0]*(float)NK_UINT_MAX);
9529  col[1] = (nk_uint)(val[1]*(float)NK_UINT_MAX);
9530  col[2] = (nk_uint)(val[2]*(float)NK_UINT_MAX);
9531  col[3] = (nk_uint)(val[3]*(float)NK_UINT_MAX);
9532  NK_MEMCPY(attr, col, sizeof(col));
9533  } break;
9534  case NK_FORMAT_R32G32B32A32_FLOAT:
9535  NK_MEMCPY(attr, val, sizeof(float)*4);
9536  break;
9537  case NK_FORMAT_R32G32B32A32_DOUBLE: {
9538  double col[4];
9539  col[0] = (double)val[0];
9540  col[1] = (double)val[1];
9541  col[2] = (double)val[2];
9542  col[3] = (double)val[3];
9543  NK_MEMCPY(attr, col, sizeof(col));
9544  } break;
9545  case NK_FORMAT_RGB32:
9546  case NK_FORMAT_RGBA32: {
9547  struct nk_color col = nk_rgba_fv(val);
9548  nk_uint color = nk_color_u32(col);
9549  NK_MEMCPY(attr, &color, sizeof(color));
9550  } break; }
9551 }
9552 NK_INTERN void
9553 nk_draw_vertex_element(void *dst, const float *values, int value_count,
9554  enum nk_draw_vertex_layout_format format)
9555 {
9556  int value_index;
9557  void *attribute = dst;
9558  /* if this triggers you tried to provide a color format for a value */
9559  NK_ASSERT(format < NK_FORMAT_COLOR_BEGIN);
9560  if (format >= NK_FORMAT_COLOR_BEGIN && format <= NK_FORMAT_COLOR_END) return;
9561  for (value_index = 0; value_index < value_count; ++value_index) {
9562  switch (format) {
9563  default: NK_ASSERT(0 && "invalid vertex layout format"); break;
9564  case NK_FORMAT_SCHAR: {
9565  char value = (char)NK_CLAMP((float)NK_SCHAR_MIN, values[value_index], (float)NK_SCHAR_MAX);
9566  NK_MEMCPY(attribute, &value, sizeof(value));
9567  attribute = (void*)((char*)attribute + sizeof(char));
9568  } break;
9569  case NK_FORMAT_SSHORT: {
9570  nk_short value = (nk_short)NK_CLAMP((float)NK_SSHORT_MIN, values[value_index], (float)NK_SSHORT_MAX);
9571  NK_MEMCPY(attribute, &value, sizeof(value));
9572  attribute = (void*)((char*)attribute + sizeof(value));
9573  } break;
9574  case NK_FORMAT_SINT: {
9575  nk_int value = (nk_int)NK_CLAMP((float)NK_SINT_MIN, values[value_index], (float)NK_SINT_MAX);
9576  NK_MEMCPY(attribute, &value, sizeof(value));
9577  attribute = (void*)((char*)attribute + sizeof(nk_int));
9578  } break;
9579  case NK_FORMAT_UCHAR: {
9580  unsigned char value = (unsigned char)NK_CLAMP((float)NK_UCHAR_MIN, values[value_index], (float)NK_UCHAR_MAX);
9581  NK_MEMCPY(attribute, &value, sizeof(value));
9582  attribute = (void*)((char*)attribute + sizeof(unsigned char));
9583  } break;
9584  case NK_FORMAT_USHORT: {
9585  nk_ushort value = (nk_ushort)NK_CLAMP((float)NK_USHORT_MIN, values[value_index], (float)NK_USHORT_MAX);
9586  NK_MEMCPY(attribute, &value, sizeof(value));
9587  attribute = (void*)((char*)attribute + sizeof(value));
9588  } break;
9589  case NK_FORMAT_UINT: {
9590  nk_uint value = (nk_uint)NK_CLAMP((float)NK_UINT_MIN, values[value_index], (float)NK_UINT_MAX);
9591  NK_MEMCPY(attribute, &value, sizeof(value));
9592  attribute = (void*)((char*)attribute + sizeof(nk_uint));
9593  } break;
9594  case NK_FORMAT_FLOAT:
9595  NK_MEMCPY(attribute, &values[value_index], sizeof(values[value_index]));
9596  attribute = (void*)((char*)attribute + sizeof(float));
9597  break;
9598  case NK_FORMAT_DOUBLE: {
9599  double value = (double)values[value_index];
9600  NK_MEMCPY(attribute, &value, sizeof(value));
9601  attribute = (void*)((char*)attribute + sizeof(double));
9602  } break;
9603  }
9604  }
9605 }
9606 NK_INTERN void*
9607 nk_draw_vertex(void *dst, const struct nk_convert_config *config,
9608  struct nk_vec2 pos, struct nk_vec2 uv, struct nk_colorf color)
9609 {
9610  void *result = (void*)((char*)dst + config->vertex_size);
9611  const struct nk_draw_vertex_layout_element *elem_iter = config->vertex_layout;
9612  while (!nk_draw_vertex_layout_element_is_end_of_layout(elem_iter)) {
9613  void *address = (void*)((char*)dst + elem_iter->offset);
9614  switch (elem_iter->attribute) {
9615  case NK_VERTEX_ATTRIBUTE_COUNT:
9616  default: NK_ASSERT(0 && "wrong element attribute"); break;
9617  case NK_VERTEX_POSITION: nk_draw_vertex_element(address, &pos.x, 2, elem_iter->format); break;
9618  case NK_VERTEX_TEXCOORD: nk_draw_vertex_element(address, &uv.x, 2, elem_iter->format); break;
9619  case NK_VERTEX_COLOR: nk_draw_vertex_color(address, &color.r, elem_iter->format); break;
9620  }
9621  elem_iter++;
9622  }
9623  return result;
9624 }
9625 NK_API void
9626 nk_draw_list_stroke_poly_line(struct nk_draw_list *list, const struct nk_vec2 *points,
9627  const unsigned int points_count, struct nk_color color, enum nk_draw_list_stroke closed,
9628  float thickness, enum nk_anti_aliasing aliasing)
9629 {
9630  nk_size count;
9631  int thick_line;
9632  struct nk_colorf col;
9633  struct nk_colorf col_trans;
9634  NK_ASSERT(list);
9635  if (!list || points_count < 2) return;
9636 
9637  color.a = (nk_byte)((float)color.a * list->config.global_alpha);
9638  count = points_count;
9639  if (!closed) count = points_count-1;
9640  thick_line = thickness > 1.0f;
9641 
9642 #ifdef NK_INCLUDE_COMMAND_USERDATA
9643  nk_draw_list_push_userdata(list, list->userdata);
9644 #endif
9645 
9646  color.a = (nk_byte)((float)color.a * list->config.global_alpha);
9647  nk_color_fv(&col.r, color);
9648  col_trans = col;
9649  col_trans.a = 0;
9650 
9651  if (aliasing == NK_ANTI_ALIASING_ON) {
9652  /* ANTI-ALIASED STROKE */
9653  const float AA_SIZE = 1.0f;
9654  NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2);
9655  NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2);
9656 
9657  /* allocate vertices and elements */
9658  nk_size i1 = 0;
9659  nk_size vertex_offset;
9660  nk_size index = list->vertex_count;
9661 
9662  const nk_size idx_count = (thick_line) ? (count * 18) : (count * 12);
9663  const nk_size vtx_count = (thick_line) ? (points_count * 4): (points_count *3);
9664 
9665  void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9666  nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9667 
9668  nk_size size;
9669  struct nk_vec2 *normals, *temp;
9670  if (!vtx || !ids) return;
9671 
9672  /* temporary allocate normals + points */
9673  vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
9674  nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
9675  size = pnt_size * ((thick_line) ? 5 : 3) * points_count;
9676  normals = (struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
9677  if (!normals) return;
9678  temp = normals + points_count;
9679 
9680  /* make sure vertex pointer is still correct */
9681  vtx = (void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
9682 
9683  /* calculate normals */
9684  for (i1 = 0; i1 < count; ++i1) {
9685  const nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
9686  struct nk_vec2 diff = nk_vec2_sub(points[i2], points[i1]);
9687  float len;
9688 
9689  /* vec2 inverted length */
9690  len = nk_vec2_len_sqr(diff);
9691  if (len != 0.0f)
9692  len = nk_inv_sqrt(len);
9693  else len = 1.0f;
9694 
9695  diff = nk_vec2_muls(diff, len);
9696  normals[i1].x = diff.y;
9697  normals[i1].y = -diff.x;
9698  }
9699 
9700  if (!closed)
9701  normals[points_count-1] = normals[points_count-2];
9702 
9703  if (!thick_line) {
9704  nk_size idx1, i;
9705  if (!closed) {
9706  struct nk_vec2 d;
9707  temp[0] = nk_vec2_add(points[0], nk_vec2_muls(normals[0], AA_SIZE));
9708  temp[1] = nk_vec2_sub(points[0], nk_vec2_muls(normals[0], AA_SIZE));
9709  d = nk_vec2_muls(normals[points_count-1], AA_SIZE);
9710  temp[(points_count-1) * 2 + 0] = nk_vec2_add(points[points_count-1], d);
9711  temp[(points_count-1) * 2 + 1] = nk_vec2_sub(points[points_count-1], d);
9712  }
9713 
9714  /* fill elements */
9715  idx1 = index;
9716  for (i1 = 0; i1 < count; i1++) {
9717  struct nk_vec2 dm;
9718  float dmr2;
9719  nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
9720  nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 3);
9721 
9722  /* average normals */
9723  dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
9724  dmr2 = dm.x * dm.x + dm.y* dm.y;
9725  if (dmr2 > 0.000001f) {
9726  float scale = 1.0f/dmr2;
9727  scale = NK_MIN(100.0f, scale);
9728  dm = nk_vec2_muls(dm, scale);
9729  }
9730 
9731  dm = nk_vec2_muls(dm, AA_SIZE);
9732  temp[i2*2+0] = nk_vec2_add(points[i2], dm);
9733  temp[i2*2+1] = nk_vec2_sub(points[i2], dm);
9734 
9735  ids[0] = (nk_draw_index)(idx2 + 0); ids[1] = (nk_draw_index)(idx1+0);
9736  ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
9737  ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+0);
9738  ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
9739  ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
9740  ids[10]= (nk_draw_index)(idx2 + 0); ids[11]= (nk_draw_index)(idx2+1);
9741  ids += 12;
9742  idx1 = idx2;
9743  }
9744 
9745  /* fill vertices */
9746  for (i = 0; i < points_count; ++i) {
9747  const struct nk_vec2 uv = list->config.null.uv;
9748  vtx = nk_draw_vertex(vtx, &list->config, points[i], uv, col);
9749  vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+0], uv, col_trans);
9750  vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+1], uv, col_trans);
9751  }
9752  } else {
9753  nk_size idx1, i;
9754  const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f;
9755  if (!closed) {
9756  struct nk_vec2 d1 = nk_vec2_muls(normals[0], half_inner_thickness + AA_SIZE);
9757  struct nk_vec2 d2 = nk_vec2_muls(normals[0], half_inner_thickness);
9758 
9759  temp[0] = nk_vec2_add(points[0], d1);
9760  temp[1] = nk_vec2_add(points[0], d2);
9761  temp[2] = nk_vec2_sub(points[0], d2);
9762  temp[3] = nk_vec2_sub(points[0], d1);
9763 
9764  d1 = nk_vec2_muls(normals[points_count-1], half_inner_thickness + AA_SIZE);
9765  d2 = nk_vec2_muls(normals[points_count-1], half_inner_thickness);
9766 
9767  temp[(points_count-1)*4+0] = nk_vec2_add(points[points_count-1], d1);
9768  temp[(points_count-1)*4+1] = nk_vec2_add(points[points_count-1], d2);
9769  temp[(points_count-1)*4+2] = nk_vec2_sub(points[points_count-1], d2);
9770  temp[(points_count-1)*4+3] = nk_vec2_sub(points[points_count-1], d1);
9771  }
9772 
9773  /* add all elements */
9774  idx1 = index;
9775  for (i1 = 0; i1 < count; ++i1) {
9776  struct nk_vec2 dm_out, dm_in;
9777  const nk_size i2 = ((i1+1) == points_count) ? 0: (i1 + 1);
9778  nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 4);
9779 
9780  /* average normals */
9781  struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
9782  float dmr2 = dm.x * dm.x + dm.y* dm.y;
9783  if (dmr2 > 0.000001f) {
9784  float scale = 1.0f/dmr2;
9785  scale = NK_MIN(100.0f, scale);
9786  dm = nk_vec2_muls(dm, scale);
9787  }
9788 
9789  dm_out = nk_vec2_muls(dm, ((half_inner_thickness) + AA_SIZE));
9790  dm_in = nk_vec2_muls(dm, half_inner_thickness);
9791  temp[i2*4+0] = nk_vec2_add(points[i2], dm_out);
9792  temp[i2*4+1] = nk_vec2_add(points[i2], dm_in);
9793  temp[i2*4+2] = nk_vec2_sub(points[i2], dm_in);
9794  temp[i2*4+3] = nk_vec2_sub(points[i2], dm_out);
9795 
9796  /* add indexes */
9797  ids[0] = (nk_draw_index)(idx2 + 1); ids[1] = (nk_draw_index)(idx1+1);
9798  ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
9799  ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+1);
9800  ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
9801  ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
9802  ids[10]= (nk_draw_index)(idx2 + 0); ids[11] = (nk_draw_index)(idx2+1);
9803  ids[12]= (nk_draw_index)(idx2 + 2); ids[13] = (nk_draw_index)(idx1+2);
9804  ids[14]= (nk_draw_index)(idx1 + 3); ids[15] = (nk_draw_index)(idx1+3);
9805  ids[16]= (nk_draw_index)(idx2 + 3); ids[17] = (nk_draw_index)(idx2+2);
9806  ids += 18;
9807  idx1 = idx2;
9808  }
9809 
9810  /* add vertices */
9811  for (i = 0; i < points_count; ++i) {
9812  const struct nk_vec2 uv = list->config.null.uv;
9813  vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+0], uv, col_trans);
9814  vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+1], uv, col);
9815  vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+2], uv, col);
9816  vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+3], uv, col_trans);
9817  }
9818  }
9819  /* free temporary normals + points */
9820  nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
9821  } else {
9822  /* NON ANTI-ALIASED STROKE */
9823  nk_size i1 = 0;
9824  nk_size idx = list->vertex_count;
9825  const nk_size idx_count = count * 6;
9826  const nk_size vtx_count = count * 4;
9827  void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9828  nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9829  if (!vtx || !ids) return;
9830 
9831  for (i1 = 0; i1 < count; ++i1) {
9832  float dx, dy;
9833  const struct nk_vec2 uv = list->config.null.uv;
9834  const nk_size i2 = ((i1+1) == points_count) ? 0 : i1 + 1;
9835  const struct nk_vec2 p1 = points[i1];
9836  const struct nk_vec2 p2 = points[i2];
9837  struct nk_vec2 diff = nk_vec2_sub(p2, p1);
9838  float len;
9839 
9840  /* vec2 inverted length */
9841  len = nk_vec2_len_sqr(diff);
9842  if (len != 0.0f)
9843  len = nk_inv_sqrt(len);
9844  else len = 1.0f;
9845  diff = nk_vec2_muls(diff, len);
9846 
9847  /* add vertices */
9848  dx = diff.x * (thickness * 0.5f);
9849  dy = diff.y * (thickness * 0.5f);
9850 
9851  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x + dy, p1.y - dx), uv, col);
9852  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x + dy, p2.y - dx), uv, col);
9853  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x - dy, p2.y + dx), uv, col);
9854  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x - dy, p1.y + dx), uv, col);
9855 
9856  ids[0] = (nk_draw_index)(idx+0); ids[1] = (nk_draw_index)(idx+1);
9857  ids[2] = (nk_draw_index)(idx+2); ids[3] = (nk_draw_index)(idx+0);
9858  ids[4] = (nk_draw_index)(idx+2); ids[5] = (nk_draw_index)(idx+3);
9859 
9860  ids += 6;
9861  idx += 4;
9862  }
9863  }
9864 }
9865 NK_API void
9866 nk_draw_list_fill_poly_convex(struct nk_draw_list *list,
9867  const struct nk_vec2 *points, const unsigned int points_count,
9868  struct nk_color color, enum nk_anti_aliasing aliasing)
9869 {
9870  struct nk_colorf col;
9871  struct nk_colorf col_trans;
9872 
9873  NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2);
9874  NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2);
9875  NK_ASSERT(list);
9876  if (!list || points_count < 3) return;
9877 
9878 #ifdef NK_INCLUDE_COMMAND_USERDATA
9879  nk_draw_list_push_userdata(list, list->userdata);
9880 #endif
9881 
9882  color.a = (nk_byte)((float)color.a * list->config.global_alpha);
9883  nk_color_fv(&col.r, color);
9884  col_trans = col;
9885  col_trans.a = 0;
9886 
9887  if (aliasing == NK_ANTI_ALIASING_ON) {
9888  nk_size i = 0;
9889  nk_size i0 = 0;
9890  nk_size i1 = 0;
9891 
9892  const float AA_SIZE = 1.0f;
9893  nk_size vertex_offset = 0;
9894  nk_size index = list->vertex_count;
9895 
9896  const nk_size idx_count = (points_count-2)*3 + points_count*6;
9897  const nk_size vtx_count = (points_count*2);
9898 
9899  void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9900  nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9901 
9902  nk_size size = 0;
9903  struct nk_vec2 *normals = 0;
9904  unsigned int vtx_inner_idx = (unsigned int)(index + 0);
9905  unsigned int vtx_outer_idx = (unsigned int)(index + 1);
9906  if (!vtx || !ids) return;
9907 
9908  /* temporary allocate normals */
9909  vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
9910  nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
9911  size = pnt_size * points_count;
9912  normals = (struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
9913  if (!normals) return;
9914  vtx = (void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
9915 
9916  /* add elements */
9917  for (i = 2; i < points_count; i++) {
9918  ids[0] = (nk_draw_index)(vtx_inner_idx);
9919  ids[1] = (nk_draw_index)(vtx_inner_idx + ((i-1) << 1));
9920  ids[2] = (nk_draw_index)(vtx_inner_idx + (i << 1));
9921  ids += 3;
9922  }
9923 
9924  /* compute normals */
9925  for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
9926  struct nk_vec2 p0 = points[i0];
9927  struct nk_vec2 p1 = points[i1];
9928  struct nk_vec2 diff = nk_vec2_sub(p1, p0);
9929 
9930  /* vec2 inverted length */
9931  float len = nk_vec2_len_sqr(diff);
9932  if (len != 0.0f)
9933  len = nk_inv_sqrt(len);
9934  else len = 1.0f;
9935  diff = nk_vec2_muls(diff, len);
9936 
9937  normals[i0].x = diff.y;
9938  normals[i0].y = -diff.x;
9939  }
9940 
9941  /* add vertices + indexes */
9942  for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
9943  const struct nk_vec2 uv = list->config.null.uv;
9944  struct nk_vec2 n0 = normals[i0];
9945  struct nk_vec2 n1 = normals[i1];
9946  struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(n0, n1), 0.5f);
9947  float dmr2 = dm.x*dm.x + dm.y*dm.y;
9948  if (dmr2 > 0.000001f) {
9949  float scale = 1.0f / dmr2;
9950  scale = NK_MIN(scale, 100.0f);
9951  dm = nk_vec2_muls(dm, scale);
9952  }
9953  dm = nk_vec2_muls(dm, AA_SIZE * 0.5f);
9954 
9955  /* add vertices */
9956  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_sub(points[i1], dm), uv, col);
9957  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_add(points[i1], dm), uv, col_trans);
9958 
9959  /* add indexes */
9960  ids[0] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
9961  ids[1] = (nk_draw_index)(vtx_inner_idx+(i0<<1));
9962  ids[2] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
9963  ids[3] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
9964  ids[4] = (nk_draw_index)(vtx_outer_idx+(i1<<1));
9965  ids[5] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
9966  ids += 6;
9967  }
9968  /* free temporary normals + points */
9969  nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
9970  } else {
9971  nk_size i = 0;
9972  nk_size index = list->vertex_count;
9973  const nk_size idx_count = (points_count-2)*3;
9974  const nk_size vtx_count = points_count;
9975  void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9976  nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9977 
9978  if (!vtx || !ids) return;
9979  for (i = 0; i < vtx_count; ++i)
9980  vtx = nk_draw_vertex(vtx, &list->config, points[i], list->config.null.uv, col);
9981  for (i = 2; i < points_count; ++i) {
9982  ids[0] = (nk_draw_index)index;
9983  ids[1] = (nk_draw_index)(index+ i - 1);
9984  ids[2] = (nk_draw_index)(index+i);
9985  ids += 3;
9986  }
9987  }
9988 }
9989 NK_API void
9990 nk_draw_list_path_clear(struct nk_draw_list *list)
9991 {
9992  NK_ASSERT(list);
9993  if (!list) return;
9994  nk_buffer_reset(list->buffer, NK_BUFFER_FRONT);
9995  list->path_count = 0;
9996  list->path_offset = 0;
9997 }
9998 NK_API void
9999 nk_draw_list_path_line_to(struct nk_draw_list *list, struct nk_vec2 pos)
10000 {
10001  struct nk_vec2 *points = 0;
10002  struct nk_draw_command *cmd = 0;
10003  NK_ASSERT(list);
10004  if (!list) return;
10005  if (!list->cmd_count)
10006  nk_draw_list_add_clip(list, nk_null_rect);
10007 
10008  cmd = nk_draw_list_command_last(list);
10009  if (cmd && cmd->texture.ptr != list->config.null.texture.ptr)
10010  nk_draw_list_push_image(list, list->config.null.texture);
10011 
10012  points = nk_draw_list_alloc_path(list, 1);
10013  if (!points) return;
10014  points[0] = pos;
10015 }
10016 NK_API void
10017 nk_draw_list_path_arc_to_fast(struct nk_draw_list *list, struct nk_vec2 center,
10018  float radius, int a_min, int a_max)
10019 {
10020  int a = 0;
10021  NK_ASSERT(list);
10022  if (!list) return;
10023  if (a_min <= a_max) {
10024  for (a = a_min; a <= a_max; a++) {
10025  const struct nk_vec2 c = list->circle_vtx[(nk_size)a % NK_LEN(list->circle_vtx)];
10026  const float x = center.x + c.x * radius;
10027  const float y = center.y + c.y * radius;
10028  nk_draw_list_path_line_to(list, nk_vec2(x, y));
10029  }
10030  }
10031 }
10032 NK_API void
10033 nk_draw_list_path_arc_to(struct nk_draw_list *list, struct nk_vec2 center,
10034  float radius, float a_min, float a_max, unsigned int segments)
10035 {
10036  unsigned int i = 0;
10037  NK_ASSERT(list);
10038  if (!list) return;
10039  if (radius == 0.0f) return;
10040 
10041  /* This algorithm for arc drawing relies on these two trigonometric identities[1]:
10042  sin(a + b) = sin(a) * cos(b) + cos(a) * sin(b)
10043  cos(a + b) = cos(a) * cos(b) - sin(a) * sin(b)
10044 
10045  Two coordinates (x, y) of a point on a circle centered on
10046  the origin can be written in polar form as:
10047  x = r * cos(a)
10048  y = r * sin(a)
10049  where r is the radius of the circle,
10050  a is the angle between (x, y) and the origin.
10051 
10052  This allows us to rotate the coordinates around the
10053  origin by an angle b using the following transformation:
10054  x' = r * cos(a + b) = x * cos(b) - y * sin(b)
10055  y' = r * sin(a + b) = y * cos(b) + x * sin(b)
10056 
10057  [1] https://en.wikipedia.org/wiki/List_of_trigonometric_identities#Angle_sum_and_difference_identities
10058  */
10059  {const float d_angle = (a_max - a_min) / (float)segments;
10060  const float sin_d = (float)NK_SIN(d_angle);
10061  const float cos_d = (float)NK_COS(d_angle);
10062 
10063  float cx = (float)NK_COS(a_min) * radius;
10064  float cy = (float)NK_SIN(a_min) * radius;
10065  for(i = 0; i <= segments; ++i) {
10066  float new_cx, new_cy;
10067  const float x = center.x + cx;
10068  const float y = center.y + cy;
10069  nk_draw_list_path_line_to(list, nk_vec2(x, y));
10070 
10071  new_cx = cx * cos_d - cy * sin_d;
10072  new_cy = cy * cos_d + cx * sin_d;
10073  cx = new_cx;
10074  cy = new_cy;
10075  }}
10076 }
10077 NK_API void
10078 nk_draw_list_path_rect_to(struct nk_draw_list *list, struct nk_vec2 a,
10079  struct nk_vec2 b, float rounding)
10080 {
10081  float r;
10082  NK_ASSERT(list);
10083  if (!list) return;
10084  r = rounding;
10085  r = NK_MIN(r, ((b.x-a.x) < 0) ? -(b.x-a.x): (b.x-a.x));
10086  r = NK_MIN(r, ((b.y-a.y) < 0) ? -(b.y-a.y): (b.y-a.y));
10087 
10088  if (r == 0.0f) {
10089  nk_draw_list_path_line_to(list, a);
10090  nk_draw_list_path_line_to(list, nk_vec2(b.x,a.y));
10091  nk_draw_list_path_line_to(list, b);
10092  nk_draw_list_path_line_to(list, nk_vec2(a.x,b.y));
10093  } else {
10094  nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, a.y + r), r, 6, 9);
10095  nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, a.y + r), r, 9, 12);
10096  nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, b.y - r), r, 0, 3);
10097  nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, b.y - r), r, 3, 6);
10098  }
10099 }
10100 NK_API void
10101 nk_draw_list_path_curve_to(struct nk_draw_list *list, struct nk_vec2 p2,
10102  struct nk_vec2 p3, struct nk_vec2 p4, unsigned int num_segments)
10103 {
10104  float t_step;
10105  unsigned int i_step;
10106  struct nk_vec2 p1;
10107 
10108  NK_ASSERT(list);
10109  NK_ASSERT(list->path_count);
10110  if (!list || !list->path_count) return;
10111  num_segments = NK_MAX(num_segments, 1);
10112 
10113  p1 = nk_draw_list_path_last(list);
10114  t_step = 1.0f/(float)num_segments;
10115  for (i_step = 1; i_step <= num_segments; ++i_step) {
10116  float t = t_step * (float)i_step;
10117  float u = 1.0f - t;
10118  float w1 = u*u*u;
10119  float w2 = 3*u*u*t;
10120  float w3 = 3*u*t*t;
10121  float w4 = t * t *t;
10122  float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
10123  float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
10124  nk_draw_list_path_line_to(list, nk_vec2(x,y));
10125  }
10126 }
10127 NK_API void
10128 nk_draw_list_path_fill(struct nk_draw_list *list, struct nk_color color)
10129 {
10130  struct nk_vec2 *points;
10131  NK_ASSERT(list);
10132  if (!list) return;
10133  points = (struct nk_vec2*)nk_buffer_memory(list->buffer);
10134  nk_draw_list_fill_poly_convex(list, points, list->path_count, color, list->config.shape_AA);
10135  nk_draw_list_path_clear(list);
10136 }
10137 NK_API void
10138 nk_draw_list_path_stroke(struct nk_draw_list *list, struct nk_color color,
10139  enum nk_draw_list_stroke closed, float thickness)
10140 {
10141  struct nk_vec2 *points;
10142  NK_ASSERT(list);
10143  if (!list) return;
10144  points = (struct nk_vec2*)nk_buffer_memory(list->buffer);
10145  nk_draw_list_stroke_poly_line(list, points, list->path_count, color,
10146  closed, thickness, list->config.line_AA);
10147  nk_draw_list_path_clear(list);
10148 }
10149 NK_API void
10150 nk_draw_list_stroke_line(struct nk_draw_list *list, struct nk_vec2 a,
10151  struct nk_vec2 b, struct nk_color col, float thickness)
10152 {
10153  NK_ASSERT(list);
10154  if (!list || !col.a) return;
10155  if (list->line_AA == NK_ANTI_ALIASING_ON) {
10156  nk_draw_list_path_line_to(list, a);
10157  nk_draw_list_path_line_to(list, b);
10158  } else {
10159  nk_draw_list_path_line_to(list, nk_vec2_sub(a,nk_vec2(0.5f,0.5f)));
10160  nk_draw_list_path_line_to(list, nk_vec2_sub(b,nk_vec2(0.5f,0.5f)));
10161  }
10162  nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
10163 }
10164 NK_API void
10165 nk_draw_list_fill_rect(struct nk_draw_list *list, struct nk_rect rect,
10166  struct nk_color col, float rounding)
10167 {
10168  NK_ASSERT(list);
10169  if (!list || !col.a) return;
10170 
10171  if (list->line_AA == NK_ANTI_ALIASING_ON) {
10172  nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y),
10173  nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10174  } else {
10175  nk_draw_list_path_rect_to(list, nk_vec2(rect.x-0.5f, rect.y-0.5f),
10176  nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10177  } nk_draw_list_path_fill(list, col);
10178 }
10179 NK_API void
10180 nk_draw_list_stroke_rect(struct nk_draw_list *list, struct nk_rect rect,
10181  struct nk_color col, float rounding, float thickness)
10182 {
10183  NK_ASSERT(list);
10184  if (!list || !col.a) return;
10185  if (list->line_AA == NK_ANTI_ALIASING_ON) {
10186  nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y),
10187  nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10188  } else {
10189  nk_draw_list_path_rect_to(list, nk_vec2(rect.x-0.5f, rect.y-0.5f),
10190  nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10191  } nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10192 }
10193 NK_API void
10194 nk_draw_list_fill_rect_multi_color(struct nk_draw_list *list, struct nk_rect rect,
10195  struct nk_color left, struct nk_color top, struct nk_color right,
10196  struct nk_color bottom)
10197 {
10198  void *vtx;
10199  struct nk_colorf col_left, col_top;
10200  struct nk_colorf col_right, col_bottom;
10201  nk_draw_index *idx;
10202  nk_draw_index index;
10203 
10204  nk_color_fv(&col_left.r, left);
10205  nk_color_fv(&col_right.r, right);
10206  nk_color_fv(&col_top.r, top);
10207  nk_color_fv(&col_bottom.r, bottom);
10208 
10209  NK_ASSERT(list);
10210  if (!list) return;
10211 
10212  nk_draw_list_push_image(list, list->config.null.texture);
10213  index = (nk_draw_index)list->vertex_count;
10214  vtx = nk_draw_list_alloc_vertices(list, 4);
10215  idx = nk_draw_list_alloc_elements(list, 6);
10216  if (!vtx || !idx) return;
10217 
10218  idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
10219  idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
10220  idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
10221 
10222  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y), list->config.null.uv, col_left);
10223  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y), list->config.null.uv, col_top);
10224  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y + rect.h), list->config.null.uv, col_right);
10225  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y + rect.h), list->config.null.uv, col_bottom);
10226 }
10227 NK_API void
10228 nk_draw_list_fill_triangle(struct nk_draw_list *list, struct nk_vec2 a,
10229  struct nk_vec2 b, struct nk_vec2 c, struct nk_color col)
10230 {
10231  NK_ASSERT(list);
10232  if (!list || !col.a) return;
10233  nk_draw_list_path_line_to(list, a);
10234  nk_draw_list_path_line_to(list, b);
10235  nk_draw_list_path_line_to(list, c);
10236  nk_draw_list_path_fill(list, col);
10237 }
10238 NK_API void
10239 nk_draw_list_stroke_triangle(struct nk_draw_list *list, struct nk_vec2 a,
10240  struct nk_vec2 b, struct nk_vec2 c, struct nk_color col, float thickness)
10241 {
10242  NK_ASSERT(list);
10243  if (!list || !col.a) return;
10244  nk_draw_list_path_line_to(list, a);
10245  nk_draw_list_path_line_to(list, b);
10246  nk_draw_list_path_line_to(list, c);
10247  nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10248 }
10249 NK_API void
10250 nk_draw_list_fill_circle(struct nk_draw_list *list, struct nk_vec2 center,
10251  float radius, struct nk_color col, unsigned int segs)
10252 {
10253  float a_max;
10254  NK_ASSERT(list);
10255  if (!list || !col.a) return;
10256  a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
10257  nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
10258  nk_draw_list_path_fill(list, col);
10259 }
10260 NK_API void
10261 nk_draw_list_stroke_circle(struct nk_draw_list *list, struct nk_vec2 center,
10262  float radius, struct nk_color col, unsigned int segs, float thickness)
10263 {
10264  float a_max;
10265  NK_ASSERT(list);
10266  if (!list || !col.a) return;
10267  a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
10268  nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
10269  nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10270 }
10271 NK_API void
10272 nk_draw_list_stroke_curve(struct nk_draw_list *list, struct nk_vec2 p0,
10273  struct nk_vec2 cp0, struct nk_vec2 cp1, struct nk_vec2 p1,
10274  struct nk_color col, unsigned int segments, float thickness)
10275 {
10276  NK_ASSERT(list);
10277  if (!list || !col.a) return;
10278  nk_draw_list_path_line_to(list, p0);
10279  nk_draw_list_path_curve_to(list, cp0, cp1, p1, segments);
10280  nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
10281 }
10282 NK_INTERN void
10283 nk_draw_list_push_rect_uv(struct nk_draw_list *list, struct nk_vec2 a,
10284  struct nk_vec2 c, struct nk_vec2 uva, struct nk_vec2 uvc,
10285  struct nk_color color)
10286 {
10287  void *vtx;
10288  struct nk_vec2 uvb;
10289  struct nk_vec2 uvd;
10290  struct nk_vec2 b;
10291  struct nk_vec2 d;
10292 
10293  struct nk_colorf col;
10294  nk_draw_index *idx;
10295  nk_draw_index index;
10296  NK_ASSERT(list);
10297  if (!list) return;
10298 
10299  nk_color_fv(&col.r, color);
10300  uvb = nk_vec2(uvc.x, uva.y);
10301  uvd = nk_vec2(uva.x, uvc.y);
10302  b = nk_vec2(c.x, a.y);
10303  d = nk_vec2(a.x, c.y);
10304 
10305  index = (nk_draw_index)list->vertex_count;
10306  vtx = nk_draw_list_alloc_vertices(list, 4);
10307  idx = nk_draw_list_alloc_elements(list, 6);
10308  if (!vtx || !idx) return;
10309 
10310  idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
10311  idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
10312  idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
10313 
10314  vtx = nk_draw_vertex(vtx, &list->config, a, uva, col);
10315  vtx = nk_draw_vertex(vtx, &list->config, b, uvb, col);
10316  vtx = nk_draw_vertex(vtx, &list->config, c, uvc, col);
10317  vtx = nk_draw_vertex(vtx, &list->config, d, uvd, col);
10318 }
10319 NK_API void
10320 nk_draw_list_add_image(struct nk_draw_list *list, struct nk_image texture,
10321  struct nk_rect rect, struct nk_color color)
10322 {
10323  NK_ASSERT(list);
10324  if (!list) return;
10325  /* push new command with given texture */
10326  nk_draw_list_push_image(list, texture.handle);
10327  if (nk_image_is_subimage(&texture)) {
10328  /* add region inside of the texture */
10329  struct nk_vec2 uv[2];
10330  uv[0].x = (float)texture.region[0]/(float)texture.w;
10331  uv[0].y = (float)texture.region[1]/(float)texture.h;
10332  uv[1].x = (float)(texture.region[0] + texture.region[2])/(float)texture.w;
10333  uv[1].y = (float)(texture.region[1] + texture.region[3])/(float)texture.h;
10334  nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y),
10335  nk_vec2(rect.x + rect.w, rect.y + rect.h), uv[0], uv[1], color);
10336  } else nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y),
10337  nk_vec2(rect.x + rect.w, rect.y + rect.h),
10338  nk_vec2(0.0f, 0.0f), nk_vec2(1.0f, 1.0f),color);
10339 }
10340 NK_API void
10341 nk_draw_list_add_text(struct nk_draw_list *list, const struct nk_user_font *font,
10342  struct nk_rect rect, const char *text, int len, float font_height,
10343  struct nk_color fg)
10344 {
10345  float x = 0;
10346  int text_len = 0;
10347  nk_rune unicode = 0;
10348  nk_rune next = 0;
10349  int glyph_len = 0;
10350  int next_glyph_len = 0;
10351  struct nk_user_font_glyph g;
10352 
10353  NK_ASSERT(list);
10354  if (!list || !len || !text) return;
10355  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
10356  list->clip_rect.x, list->clip_rect.y, list->clip_rect.w, list->clip_rect.h)) return;
10357 
10358  nk_draw_list_push_image(list, font->texture);
10359  x = rect.x;
10360  glyph_len = nk_utf_decode(text, &unicode, len);
10361  if (!glyph_len) return;
10362 
10363  /* draw every glyph image */
10364  fg.a = (nk_byte)((float)fg.a * list->config.global_alpha);
10365  while (text_len < len && glyph_len) {
10366  float gx, gy, gh, gw;
10367  float char_width = 0;
10368  if (unicode == NK_UTF_INVALID) break;
10369 
10370  /* query currently drawn glyph information */
10371  next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (int)len - text_len);
10372  font->query(font->userdata, font_height, &g, unicode,
10373  (next == NK_UTF_INVALID) ? '\0' : next);
10374 
10375  /* calculate and draw glyph drawing rectangle and image */
10376  gx = x + g.offset.x;
10377  gy = rect.y + g.offset.y;
10378  gw = g.width; gh = g.height;
10379  char_width = g.xadvance;
10380  nk_draw_list_push_rect_uv(list, nk_vec2(gx,gy), nk_vec2(gx + gw, gy+ gh),
10381  g.uv[0], g.uv[1], fg);
10382 
10383  /* offset next glyph */
10384  text_len += glyph_len;
10385  x += char_width;
10386  glyph_len = next_glyph_len;
10387  unicode = next;
10388  }
10389 }
10391 nk_convert(struct nk_context *ctx, struct nk_buffer *cmds,
10392  struct nk_buffer *vertices, struct nk_buffer *elements,
10393  const struct nk_convert_config *config)
10394 {
10396  const struct nk_command *cmd;
10397  NK_ASSERT(ctx);
10398  NK_ASSERT(cmds);
10399  NK_ASSERT(vertices);
10400  NK_ASSERT(elements);
10401  NK_ASSERT(config);
10402  NK_ASSERT(config->vertex_layout);
10403  NK_ASSERT(config->vertex_size);
10404  if (!ctx || !cmds || !vertices || !elements || !config || !config->vertex_layout)
10405  return NK_CONVERT_INVALID_PARAM;
10406 
10407  nk_draw_list_setup(&ctx->draw_list, config, cmds, vertices, elements,
10408  config->line_AA, config->shape_AA);
10409  nk_foreach(cmd, ctx)
10410  {
10411 #ifdef NK_INCLUDE_COMMAND_USERDATA
10412  ctx->draw_list.userdata = cmd->userdata;
10413 #endif
10414  switch (cmd->type) {
10415  case NK_COMMAND_NOP: break;
10416  case NK_COMMAND_SCISSOR: {
10417  const struct nk_command_scissor *s = (const struct nk_command_scissor*)cmd;
10418  nk_draw_list_add_clip(&ctx->draw_list, nk_rect(s->x, s->y, s->w, s->h));
10419  } break;
10420  case NK_COMMAND_LINE: {
10421  const struct nk_command_line *l = (const struct nk_command_line*)cmd;
10422  nk_draw_list_stroke_line(&ctx->draw_list, nk_vec2(l->begin.x, l->begin.y),
10423  nk_vec2(l->end.x, l->end.y), l->color, l->line_thickness);
10424  } break;
10425  case NK_COMMAND_CURVE: {
10426  const struct nk_command_curve *q = (const struct nk_command_curve*)cmd;
10427  nk_draw_list_stroke_curve(&ctx->draw_list, nk_vec2(q->begin.x, q->begin.y),
10428  nk_vec2(q->ctrl[0].x, q->ctrl[0].y), nk_vec2(q->ctrl[1].x,
10429  q->ctrl[1].y), nk_vec2(q->end.x, q->end.y), q->color,
10430  config->curve_segment_count, q->line_thickness);
10431  } break;
10432  case NK_COMMAND_RECT: {
10433  const struct nk_command_rect *r = (const struct nk_command_rect*)cmd;
10434  nk_draw_list_stroke_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
10435  r->color, (float)r->rounding, r->line_thickness);
10436  } break;
10437  case NK_COMMAND_RECT_FILLED: {
10438  const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled*)cmd;
10439  nk_draw_list_fill_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
10440  r->color, (float)r->rounding);
10441  } break;
10443  const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color*)cmd;
10444  nk_draw_list_fill_rect_multi_color(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
10445  r->left, r->top, r->right, r->bottom);
10446  } break;
10447  case NK_COMMAND_CIRCLE: {
10448  const struct nk_command_circle *c = (const struct nk_command_circle*)cmd;
10449  nk_draw_list_stroke_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w/2,
10450  (float)c->y + (float)c->h/2), (float)c->w/2, c->color,
10451  config->circle_segment_count, c->line_thickness);
10452  } break;
10453  case NK_COMMAND_CIRCLE_FILLED: {
10454  const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
10455  nk_draw_list_fill_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w/2,
10456  (float)c->y + (float)c->h/2), (float)c->w/2, c->color,
10457  config->circle_segment_count);
10458  } break;
10459  case NK_COMMAND_ARC: {
10460  const struct nk_command_arc *c = (const struct nk_command_arc*)cmd;
10461  nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy));
10462  nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r,
10463  c->a[0], c->a[1], config->arc_segment_count);
10464  nk_draw_list_path_stroke(&ctx->draw_list, c->color, NK_STROKE_CLOSED, c->line_thickness);
10465  } break;
10466  case NK_COMMAND_ARC_FILLED: {
10467  const struct nk_command_arc_filled *c = (const struct nk_command_arc_filled*)cmd;
10468  nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy));
10469  nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r,
10470  c->a[0], c->a[1], config->arc_segment_count);
10471  nk_draw_list_path_fill(&ctx->draw_list, c->color);
10472  } break;
10473  case NK_COMMAND_TRIANGLE: {
10474  const struct nk_command_triangle *t = (const struct nk_command_triangle*)cmd;
10475  nk_draw_list_stroke_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y),
10476  nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color,
10477  t->line_thickness);
10478  } break;
10480  const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled*)cmd;
10481  nk_draw_list_fill_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y),
10482  nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color);
10483  } break;
10484  case NK_COMMAND_POLYGON: {
10485  int i;
10486  const struct nk_command_polygon*p = (const struct nk_command_polygon*)cmd;
10487  for (i = 0; i < p->point_count; ++i) {
10488  struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
10489  nk_draw_list_path_line_to(&ctx->draw_list, pnt);
10490  }
10491  nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_CLOSED, p->line_thickness);
10492  } break;
10494  int i;
10495  const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled*)cmd;
10496  for (i = 0; i < p->point_count; ++i) {
10497  struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
10498  nk_draw_list_path_line_to(&ctx->draw_list, pnt);
10499  }
10500  nk_draw_list_path_fill(&ctx->draw_list, p->color);
10501  } break;
10502  case NK_COMMAND_POLYLINE: {
10503  int i;
10504  const struct nk_command_polyline *p = (const struct nk_command_polyline*)cmd;
10505  for (i = 0; i < p->point_count; ++i) {
10506  struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
10507  nk_draw_list_path_line_to(&ctx->draw_list, pnt);
10508  }
10509  nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_OPEN, p->line_thickness);
10510  } break;
10511  case NK_COMMAND_TEXT: {
10512  const struct nk_command_text *t = (const struct nk_command_text*)cmd;
10513  nk_draw_list_add_text(&ctx->draw_list, t->font, nk_rect(t->x, t->y, t->w, t->h),
10514  t->string, t->length, t->height, t->foreground);
10515  } break;
10516  case NK_COMMAND_IMAGE: {
10517  const struct nk_command_image *i = (const struct nk_command_image*)cmd;
10518  nk_draw_list_add_image(&ctx->draw_list, i->img, nk_rect(i->x, i->y, i->w, i->h), i->col);
10519  } break;
10520  case NK_COMMAND_CUSTOM: {
10521  const struct nk_command_custom *c = (const struct nk_command_custom*)cmd;
10522  c->callback(&ctx->draw_list, c->x, c->y, c->w, c->h, c->callback_data);
10523  } break;
10524  default: break;
10525  }
10526  }
10527  res |= (cmds->needed > cmds->allocated + (cmds->memory.size - cmds->size)) ? NK_CONVERT_COMMAND_BUFFER_FULL: 0;
10528  res |= (vertices->needed > vertices->allocated) ? NK_CONVERT_VERTEX_BUFFER_FULL: 0;
10529  res |= (elements->needed > elements->allocated) ? NK_CONVERT_ELEMENT_BUFFER_FULL: 0;
10530  return res;
10531 }
10532 NK_API const struct nk_draw_command*
10533 nk__draw_begin(const struct nk_context *ctx,
10534  const struct nk_buffer *buffer)
10535 {
10536  return nk__draw_list_begin(&ctx->draw_list, buffer);
10537 }
10538 NK_API const struct nk_draw_command*
10539 nk__draw_end(const struct nk_context *ctx, const struct nk_buffer *buffer)
10540 {
10541  return nk__draw_list_end(&ctx->draw_list, buffer);
10542 }
10543 NK_API const struct nk_draw_command*
10544 nk__draw_next(const struct nk_draw_command *cmd,
10545  const struct nk_buffer *buffer, const struct nk_context *ctx)
10546 {
10547  return nk__draw_list_next(cmd, buffer, &ctx->draw_list);
10548 }
10549 #endif
10550 
10551 
10552 
10553 
10554 
10555 #ifdef NK_INCLUDE_FONT_BAKING
10556 /* -------------------------------------------------------------
10557  *
10558  * RECT PACK
10559  *
10560  * --------------------------------------------------------------*/
10561 /* stb_rect_pack.h - v0.05 - public domain - rectangle packing */
10562 /* Sean Barrett 2014 */
10563 #define NK_RP__MAXVAL 0xffff
10564 typedef unsigned short nk_rp_coord;
10565 
10566 struct nk_rp_rect {
10567  /* reserved for your use: */
10568  int id;
10569  /* input: */
10570  nk_rp_coord w, h;
10571  /* output: */
10572  nk_rp_coord x, y;
10573  int was_packed;
10574  /* non-zero if valid packing */
10575 }; /* 16 bytes, nominally */
10576 
10577 struct nk_rp_node {
10578  nk_rp_coord x,y;
10579  struct nk_rp_node *next;
10580 };
10581 
10582 struct nk_rp_context {
10583  int width;
10584  int height;
10585  int align;
10586  int init_mode;
10587  int heuristic;
10588  int num_nodes;
10589  struct nk_rp_node *active_head;
10590  struct nk_rp_node *free_head;
10591  struct nk_rp_node extra[2];
10592  /* we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' */
10593 };
10594 
10595 struct nk_rp__findresult {
10596  int x,y;
10597  struct nk_rp_node **prev_link;
10598 };
10599 
10600 enum NK_RP_HEURISTIC {
10601  NK_RP_HEURISTIC_Skyline_default=0,
10602  NK_RP_HEURISTIC_Skyline_BL_sortHeight = NK_RP_HEURISTIC_Skyline_default,
10603  NK_RP_HEURISTIC_Skyline_BF_sortHeight
10604 };
10605 enum NK_RP_INIT_STATE{NK_RP__INIT_skyline = 1};
10606 
10607 NK_INTERN void
10608 nk_rp_setup_allow_out_of_mem(struct nk_rp_context *context, int allow_out_of_mem)
10609 {
10610  if (allow_out_of_mem)
10611  /* if it's ok to run out of memory, then don't bother aligning them; */
10612  /* this gives better packing, but may fail due to OOM (even though */
10613  /* the rectangles easily fit). @TODO a smarter approach would be to only */
10614  /* quantize once we've hit OOM, then we could get rid of this parameter. */
10615  context->align = 1;
10616  else {
10617  /* if it's not ok to run out of memory, then quantize the widths */
10618  /* so that num_nodes is always enough nodes. */
10619  /* */
10620  /* I.e. num_nodes * align >= width */
10621  /* align >= width / num_nodes */
10622  /* align = ceil(width/num_nodes) */
10623  context->align = (context->width + context->num_nodes-1) / context->num_nodes;
10624  }
10625 }
10626 NK_INTERN void
10627 nk_rp_init_target(struct nk_rp_context *context, int width, int height,
10628  struct nk_rp_node *nodes, int num_nodes)
10629 {
10630  int i;
10631 #ifndef STBRP_LARGE_RECTS
10632  NK_ASSERT(width <= 0xffff && height <= 0xffff);
10633 #endif
10634 
10635  for (i=0; i < num_nodes-1; ++i)
10636  nodes[i].next = &nodes[i+1];
10637  nodes[i].next = 0;
10638  context->init_mode = NK_RP__INIT_skyline;
10639  context->heuristic = NK_RP_HEURISTIC_Skyline_default;
10640  context->free_head = &nodes[0];
10641  context->active_head = &context->extra[0];
10642  context->width = width;
10643  context->height = height;
10644  context->num_nodes = num_nodes;
10645  nk_rp_setup_allow_out_of_mem(context, 0);
10646 
10647  /* node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) */
10648  context->extra[0].x = 0;
10649  context->extra[0].y = 0;
10650  context->extra[0].next = &context->extra[1];
10651  context->extra[1].x = (nk_rp_coord) width;
10652  context->extra[1].y = 65535;
10653  context->extra[1].next = 0;
10654 }
10655 /* find minimum y position if it starts at x1 */
10656 NK_INTERN int
10657 nk_rp__skyline_find_min_y(struct nk_rp_context *c, struct nk_rp_node *first,
10658  int x0, int width, int *pwaste)
10659 {
10660  struct nk_rp_node *node = first;
10661  int x1 = x0 + width;
10662  int min_y, visited_width, waste_area;
10663  NK_ASSERT(first->x <= x0);
10664  NK_UNUSED(c);
10665 
10666  NK_ASSERT(node->next->x > x0);
10667  /* we ended up handling this in the caller for efficiency */
10668  NK_ASSERT(node->x <= x0);
10669 
10670  min_y = 0;
10671  waste_area = 0;
10672  visited_width = 0;
10673  while (node->x < x1)
10674  {
10675  if (node->y > min_y) {
10676  /* raise min_y higher. */
10677  /* we've accounted for all waste up to min_y, */
10678  /* but we'll now add more waste for everything we've visited */
10679  waste_area += visited_width * (node->y - min_y);
10680  min_y = node->y;
10681  /* the first time through, visited_width might be reduced */
10682  if (node->x < x0)
10683  visited_width += node->next->x - x0;
10684  else
10685  visited_width += node->next->x - node->x;
10686  } else {
10687  /* add waste area */
10688  int under_width = node->next->x - node->x;
10689  if (under_width + visited_width > width)
10690  under_width = width - visited_width;
10691  waste_area += under_width * (min_y - node->y);
10692  visited_width += under_width;
10693  }
10694  node = node->next;
10695  }
10696  *pwaste = waste_area;
10697  return min_y;
10698 }
10699 NK_INTERN struct nk_rp__findresult
10700 nk_rp__skyline_find_best_pos(struct nk_rp_context *c, int width, int height)
10701 {
10702  int best_waste = (1<<30), best_x, best_y = (1 << 30);
10703  struct nk_rp__findresult fr;
10704  struct nk_rp_node **prev, *node, *tail, **best = 0;
10705 
10706  /* align to multiple of c->align */
10707  width = (width + c->align - 1);
10708  width -= width % c->align;
10709  NK_ASSERT(width % c->align == 0);
10710 
10711  node = c->active_head;
10712  prev = &c->active_head;
10713  while (node->x + width <= c->width) {
10714  int y,waste;
10715  y = nk_rp__skyline_find_min_y(c, node, node->x, width, &waste);
10716  /* actually just want to test BL */
10717  if (c->heuristic == NK_RP_HEURISTIC_Skyline_BL_sortHeight) {
10718  /* bottom left */
10719  if (y < best_y) {
10720  best_y = y;
10721  best = prev;
10722  }
10723  } else {
10724  /* best-fit */
10725  if (y + height <= c->height) {
10726  /* can only use it if it first vertically */
10727  if (y < best_y || (y == best_y && waste < best_waste)) {
10728  best_y = y;
10729  best_waste = waste;
10730  best = prev;
10731  }
10732  }
10733  }
10734  prev = &node->next;
10735  node = node->next;
10736  }
10737  best_x = (best == 0) ? 0 : (*best)->x;
10738 
10739  /* if doing best-fit (BF), we also have to try aligning right edge to each node position */
10740  /* */
10741  /* e.g, if fitting */
10742  /* */
10743  /* ____________________ */
10744  /* |____________________| */
10745  /* */
10746  /* into */
10747  /* */
10748  /* | | */
10749  /* | ____________| */
10750  /* |____________| */
10751  /* */
10752  /* then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned */
10753  /* */
10754  /* This makes BF take about 2x the time */
10755  if (c->heuristic == NK_RP_HEURISTIC_Skyline_BF_sortHeight)
10756  {
10757  tail = c->active_head;
10758  node = c->active_head;
10759  prev = &c->active_head;
10760  /* find first node that's admissible */
10761  while (tail->x < width)
10762  tail = tail->next;
10763  while (tail)
10764  {
10765  int xpos = tail->x - width;
10766  int y,waste;
10767  NK_ASSERT(xpos >= 0);
10768  /* find the left position that matches this */
10769  while (node->next->x <= xpos) {
10770  prev = &node->next;
10771  node = node->next;
10772  }
10773  NK_ASSERT(node->next->x > xpos && node->x <= xpos);
10774  y = nk_rp__skyline_find_min_y(c, node, xpos, width, &waste);
10775  if (y + height < c->height) {
10776  if (y <= best_y) {
10777  if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
10778  best_x = xpos;
10779  NK_ASSERT(y <= best_y);
10780  best_y = y;
10781  best_waste = waste;
10782  best = prev;
10783  }
10784  }
10785  }
10786  tail = tail->next;
10787  }
10788  }
10789  fr.prev_link = best;
10790  fr.x = best_x;
10791  fr.y = best_y;
10792  return fr;
10793 }
10794 NK_INTERN struct nk_rp__findresult
10795 nk_rp__skyline_pack_rectangle(struct nk_rp_context *context, int width, int height)
10796 {
10797  /* find best position according to heuristic */
10798  struct nk_rp__findresult res = nk_rp__skyline_find_best_pos(context, width, height);
10799  struct nk_rp_node *node, *cur;
10800 
10801  /* bail if: */
10802  /* 1. it failed */
10803  /* 2. the best node doesn't fit (we don't always check this) */
10804  /* 3. we're out of memory */
10805  if (res.prev_link == 0 || res.y + height > context->height || context->free_head == 0) {
10806  res.prev_link = 0;
10807  return res;
10808  }
10809 
10810  /* on success, create new node */
10811  node = context->free_head;
10812  node->x = (nk_rp_coord) res.x;
10813  node->y = (nk_rp_coord) (res.y + height);
10814 
10815  context->free_head = node->next;
10816 
10817  /* insert the new node into the right starting point, and */
10818  /* let 'cur' point to the remaining nodes needing to be */
10819  /* stitched back in */
10820  cur = *res.prev_link;
10821  if (cur->x < res.x) {
10822  /* preserve the existing one, so start testing with the next one */
10823  struct nk_rp_node *next = cur->next;
10824  cur->next = node;
10825  cur = next;
10826  } else {
10827  *res.prev_link = node;
10828  }
10829 
10830  /* from here, traverse cur and free the nodes, until we get to one */
10831  /* that shouldn't be freed */
10832  while (cur->next && cur->next->x <= res.x + width) {
10833  struct nk_rp_node *next = cur->next;
10834  /* move the current node to the free list */
10835  cur->next = context->free_head;
10836  context->free_head = cur;
10837  cur = next;
10838  }
10839  /* stitch the list back in */
10840  node->next = cur;
10841 
10842  if (cur->x < res.x + width)
10843  cur->x = (nk_rp_coord) (res.x + width);
10844  return res;
10845 }
10846 NK_INTERN int
10847 nk_rect_height_compare(const void *a, const void *b)
10848 {
10849  const struct nk_rp_rect *p = (const struct nk_rp_rect *) a;
10850  const struct nk_rp_rect *q = (const struct nk_rp_rect *) b;
10851  if (p->h > q->h)
10852  return -1;
10853  if (p->h < q->h)
10854  return 1;
10855  return (p->w > q->w) ? -1 : (p->w < q->w);
10856 }
10857 NK_INTERN int
10858 nk_rect_original_order(const void *a, const void *b)
10859 {
10860  const struct nk_rp_rect *p = (const struct nk_rp_rect *) a;
10861  const struct nk_rp_rect *q = (const struct nk_rp_rect *) b;
10862  return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
10863 }
10864 NK_INTERN void
10865 nk_rp_qsort(struct nk_rp_rect *array, unsigned int len, int(*cmp)(const void*,const void*))
10866 {
10867  /* iterative quick sort */
10868  #define NK_MAX_SORT_STACK 64
10869  unsigned right, left = 0, stack[NK_MAX_SORT_STACK], pos = 0;
10870  unsigned seed = len/2 * 69069+1;
10871  for (;;) {
10872  for (; left+1 < len; len++) {
10873  struct nk_rp_rect pivot, tmp;
10874  if (pos == NK_MAX_SORT_STACK) len = stack[pos = 0];
10875  pivot = array[left+seed%(len-left)];
10876  seed = seed * 69069 + 1;
10877  stack[pos++] = len;
10878  for (right = left-1;;) {
10879  while (cmp(&array[++right], &pivot) < 0);
10880  while (cmp(&pivot, &array[--len]) < 0);
10881  if (right >= len) break;
10882  tmp = array[right];
10883  array[right] = array[len];
10884  array[len] = tmp;
10885  }
10886  }
10887  if (pos == 0) break;
10888  left = len;
10889  len = stack[--pos];
10890  }
10891  #undef NK_MAX_SORT_STACK
10892 }
10893 NK_INTERN void
10894 nk_rp_pack_rects(struct nk_rp_context *context, struct nk_rp_rect *rects, int num_rects)
10895 {
10896  int i;
10897  /* we use the 'was_packed' field internally to allow sorting/unsorting */
10898  for (i=0; i < num_rects; ++i) {
10899  rects[i].was_packed = i;
10900  }
10901 
10902  /* sort according to heuristic */
10903  nk_rp_qsort(rects, (unsigned)num_rects, nk_rect_height_compare);
10904 
10905  for (i=0; i < num_rects; ++i) {
10906  struct nk_rp__findresult fr = nk_rp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
10907  if (fr.prev_link) {
10908  rects[i].x = (nk_rp_coord) fr.x;
10909  rects[i].y = (nk_rp_coord) fr.y;
10910  } else {
10911  rects[i].x = rects[i].y = NK_RP__MAXVAL;
10912  }
10913  }
10914 
10915  /* unsort */
10916  nk_rp_qsort(rects, (unsigned)num_rects, nk_rect_original_order);
10917 
10918  /* set was_packed flags */
10919  for (i=0; i < num_rects; ++i)
10920  rects[i].was_packed = !(rects[i].x == NK_RP__MAXVAL && rects[i].y == NK_RP__MAXVAL);
10921 }
10922 
10923 /*
10924  * ==============================================================
10925  *
10926  * TRUETYPE
10927  *
10928  * ===============================================================
10929  */
10930 /* stb_truetype.h - v1.07 - public domain */
10931 #define NK_TT_MAX_OVERSAMPLE 8
10932 #define NK_TT__OVER_MASK (NK_TT_MAX_OVERSAMPLE-1)
10933 
10934 struct nk_tt_bakedchar {
10935  unsigned short x0,y0,x1,y1;
10936  /* coordinates of bbox in bitmap */
10937  float xoff,yoff,xadvance;
10938 };
10939 
10940 struct nk_tt_aligned_quad{
10941  float x0,y0,s0,t0; /* top-left */
10942  float x1,y1,s1,t1; /* bottom-right */
10943 };
10944 
10945 struct nk_tt_packedchar {
10946  unsigned short x0,y0,x1,y1;
10947  /* coordinates of bbox in bitmap */
10948  float xoff,yoff,xadvance;
10949  float xoff2,yoff2;
10950 };
10951 
10952 struct nk_tt_pack_range {
10953  float font_size;
10954  int first_unicode_codepoint_in_range;
10955  /* if non-zero, then the chars are continuous, and this is the first codepoint */
10956  int *array_of_unicode_codepoints;
10957  /* if non-zero, then this is an array of unicode codepoints */
10958  int num_chars;
10959  struct nk_tt_packedchar *chardata_for_range; /* output */
10960  unsigned char h_oversample, v_oversample;
10961  /* don't set these, they're used internally */
10962 };
10963 
10964 struct nk_tt_pack_context {
10965  void *pack_info;
10966  int width;
10967  int height;
10968  int stride_in_bytes;
10969  int padding;
10970  unsigned int h_oversample, v_oversample;
10971  unsigned char *pixels;
10972  void *nodes;
10973 };
10974 
10975 struct nk_tt_fontinfo {
10976  const unsigned char* data; /* pointer to .ttf file */
10977  int fontstart;/* offset of start of font */
10978  int numGlyphs;/* number of glyphs, needed for range checking */
10979  int loca,head,glyf,hhea,hmtx,kern; /* table locations as offset from start of .ttf */
10980  int index_map; /* a cmap mapping for our chosen character encoding */
10981  int indexToLocFormat; /* format needed to map from glyph index to glyph */
10982 };
10983 
10984 enum {
10985  NK_TT_vmove=1,
10986  NK_TT_vline,
10987  NK_TT_vcurve
10988 };
10989 
10990 struct nk_tt_vertex {
10991  short x,y,cx,cy;
10992  unsigned char type,padding;
10993 };
10994 
10995 struct nk_tt__bitmap{
10996  int w,h,stride;
10997  unsigned char *pixels;
10998 };
10999 
11000 struct nk_tt__hheap_chunk {
11001  struct nk_tt__hheap_chunk *next;
11002 };
11003 struct nk_tt__hheap {
11004  struct nk_allocator alloc;
11005  struct nk_tt__hheap_chunk *head;
11006  void *first_free;
11007  int num_remaining_in_head_chunk;
11008 };
11009 
11010 struct nk_tt__edge {
11011  float x0,y0, x1,y1;
11012  int invert;
11013 };
11014 
11015 struct nk_tt__active_edge {
11016  struct nk_tt__active_edge *next;
11017  float fx,fdx,fdy;
11018  float direction;
11019  float sy;
11020  float ey;
11021 };
11022 struct nk_tt__point {float x,y;};
11023 
11024 #define NK_TT_MACSTYLE_DONTCARE 0
11025 #define NK_TT_MACSTYLE_BOLD 1
11026 #define NK_TT_MACSTYLE_ITALIC 2
11027 #define NK_TT_MACSTYLE_UNDERSCORE 4
11028 #define NK_TT_MACSTYLE_NONE 8
11029 /* <= not same as 0, this makes us check the bitfield is 0 */
11030 
11031 enum { /* platformID */
11032  NK_TT_PLATFORM_ID_UNICODE =0,
11033  NK_TT_PLATFORM_ID_MAC =1,
11034  NK_TT_PLATFORM_ID_ISO =2,
11035  NK_TT_PLATFORM_ID_MICROSOFT =3
11036 };
11037 
11038 enum { /* encodingID for NK_TT_PLATFORM_ID_UNICODE */
11039  NK_TT_UNICODE_EID_UNICODE_1_0 =0,
11040  NK_TT_UNICODE_EID_UNICODE_1_1 =1,
11041  NK_TT_UNICODE_EID_ISO_10646 =2,
11042  NK_TT_UNICODE_EID_UNICODE_2_0_BMP=3,
11043  NK_TT_UNICODE_EID_UNICODE_2_0_FULL=4
11044 };
11045 
11046 enum { /* encodingID for NK_TT_PLATFORM_ID_MICROSOFT */
11047  NK_TT_MS_EID_SYMBOL =0,
11048  NK_TT_MS_EID_UNICODE_BMP =1,
11049  NK_TT_MS_EID_SHIFTJIS =2,
11050  NK_TT_MS_EID_UNICODE_FULL =10
11051 };
11052 
11053 enum { /* encodingID for NK_TT_PLATFORM_ID_MAC; same as Script Manager codes */
11054  NK_TT_MAC_EID_ROMAN =0, NK_TT_MAC_EID_ARABIC =4,
11055  NK_TT_MAC_EID_JAPANESE =1, NK_TT_MAC_EID_HEBREW =5,
11056  NK_TT_MAC_EID_CHINESE_TRAD =2, NK_TT_MAC_EID_GREEK =6,
11057  NK_TT_MAC_EID_KOREAN =3, NK_TT_MAC_EID_RUSSIAN =7
11058 };
11059 
11060 enum { /* languageID for NK_TT_PLATFORM_ID_MICROSOFT; same as LCID... */
11061  /* problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs */
11062  NK_TT_MS_LANG_ENGLISH =0x0409, NK_TT_MS_LANG_ITALIAN =0x0410,
11063  NK_TT_MS_LANG_CHINESE =0x0804, NK_TT_MS_LANG_JAPANESE =0x0411,
11064  NK_TT_MS_LANG_DUTCH =0x0413, NK_TT_MS_LANG_KOREAN =0x0412,
11065  NK_TT_MS_LANG_FRENCH =0x040c, NK_TT_MS_LANG_RUSSIAN =0x0419,
11066  NK_TT_MS_LANG_GERMAN =0x0407, NK_TT_MS_LANG_SPANISH =0x0409,
11067  NK_TT_MS_LANG_HEBREW =0x040d, NK_TT_MS_LANG_SWEDISH =0x041D
11068 };
11069 
11070 enum { /* languageID for NK_TT_PLATFORM_ID_MAC */
11071  NK_TT_MAC_LANG_ENGLISH =0 , NK_TT_MAC_LANG_JAPANESE =11,
11072  NK_TT_MAC_LANG_ARABIC =12, NK_TT_MAC_LANG_KOREAN =23,
11073  NK_TT_MAC_LANG_DUTCH =4 , NK_TT_MAC_LANG_RUSSIAN =32,
11074  NK_TT_MAC_LANG_FRENCH =1 , NK_TT_MAC_LANG_SPANISH =6 ,
11075  NK_TT_MAC_LANG_GERMAN =2 , NK_TT_MAC_LANG_SWEDISH =5 ,
11076  NK_TT_MAC_LANG_HEBREW =10, NK_TT_MAC_LANG_CHINESE_SIMPLIFIED =33,
11077  NK_TT_MAC_LANG_ITALIAN =3 , NK_TT_MAC_LANG_CHINESE_TRAD =19
11078 };
11079 
11080 #define nk_ttBYTE(p) (* (const nk_byte *) (p))
11081 #define nk_ttCHAR(p) (* (const char *) (p))
11082 
11083 #if defined(NK_BIGENDIAN) && !defined(NK_ALLOW_UNALIGNED_TRUETYPE)
11084  #define nk_ttUSHORT(p) (* (nk_ushort *) (p))
11085  #define nk_ttSHORT(p) (* (nk_short *) (p))
11086  #define nk_ttULONG(p) (* (nk_uint *) (p))
11087  #define nk_ttLONG(p) (* (nk_int *) (p))
11088 #else
11089  static nk_ushort nk_ttUSHORT(const nk_byte *p) { return (nk_ushort)(p[0]*256 + p[1]); }
11090  static nk_short nk_ttSHORT(const nk_byte *p) { return (nk_short)(p[0]*256 + p[1]); }
11091  static nk_uint nk_ttULONG(const nk_byte *p) { return (nk_uint)((p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]); }
11092 #endif
11093 
11094 #define nk_tt_tag4(p,c0,c1,c2,c3)\
11095  ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
11096 #define nk_tt_tag(p,str) nk_tt_tag4(p,str[0],str[1],str[2],str[3])
11097 
11098 NK_INTERN int nk_tt_GetGlyphShape(const struct nk_tt_fontinfo *info, struct nk_allocator *alloc,
11099  int glyph_index, struct nk_tt_vertex **pvertices);
11100 
11102 nk_tt__find_table(const nk_byte *data, nk_uint fontstart, const char *tag)
11103 {
11104  /* @OPTIMIZE: binary search */
11105  nk_int num_tables = nk_ttUSHORT(data+fontstart+4);
11106  nk_uint tabledir = fontstart + 12;
11107  nk_int i;
11108  for (i = 0; i < num_tables; ++i) {
11109  nk_uint loc = tabledir + (nk_uint)(16*i);
11110  if (nk_tt_tag(data+loc+0, tag))
11111  return nk_ttULONG(data+loc+8);
11112  }
11113  return 0;
11114 }
11115 NK_INTERN int
11116 nk_tt_InitFont(struct nk_tt_fontinfo *info, const unsigned char *data2, int fontstart)
11117 {
11118  nk_uint cmap, t;
11119  nk_int i,numTables;
11120  const nk_byte *data = (const nk_byte *) data2;
11121 
11122  info->data = data;
11123  info->fontstart = fontstart;
11124 
11125  cmap = nk_tt__find_table(data, (nk_uint)fontstart, "cmap"); /* required */
11126  info->loca = (int)nk_tt__find_table(data, (nk_uint)fontstart, "loca"); /* required */
11127  info->head = (int)nk_tt__find_table(data, (nk_uint)fontstart, "head"); /* required */
11128  info->glyf = (int)nk_tt__find_table(data, (nk_uint)fontstart, "glyf"); /* required */
11129  info->hhea = (int)nk_tt__find_table(data, (nk_uint)fontstart, "hhea"); /* required */
11130  info->hmtx = (int)nk_tt__find_table(data, (nk_uint)fontstart, "hmtx"); /* required */
11131  info->kern = (int)nk_tt__find_table(data, (nk_uint)fontstart, "kern"); /* not required */
11132  if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx)
11133  return 0;
11134 
11135  t = nk_tt__find_table(data, (nk_uint)fontstart, "maxp");
11136  if (t) info->numGlyphs = nk_ttUSHORT(data+t+4);
11137  else info->numGlyphs = 0xffff;
11138 
11139  /* find a cmap encoding table we understand *now* to avoid searching */
11140  /* later. (todo: could make this installable) */
11141  /* the same regardless of glyph. */
11142  numTables = nk_ttUSHORT(data + cmap + 2);
11143  info->index_map = 0;
11144  for (i=0; i < numTables; ++i)
11145  {
11146  nk_uint encoding_record = cmap + 4 + 8 * (nk_uint)i;
11147  /* find an encoding we understand: */
11148  switch(nk_ttUSHORT(data+encoding_record)) {
11149  case NK_TT_PLATFORM_ID_MICROSOFT:
11150  switch (nk_ttUSHORT(data+encoding_record+2)) {
11151  case NK_TT_MS_EID_UNICODE_BMP:
11152  case NK_TT_MS_EID_UNICODE_FULL:
11153  /* MS/Unicode */
11154  info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4));
11155  break;
11156  default: break;
11157  } break;
11158  case NK_TT_PLATFORM_ID_UNICODE:
11159  /* Mac/iOS has these */
11160  /* all the encodingIDs are unicode, so we don't bother to check it */
11161  info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4));
11162  break;
11163  default: break;
11164  }
11165  }
11166  if (info->index_map == 0)
11167  return 0;
11168  info->indexToLocFormat = nk_ttUSHORT(data+info->head + 50);
11169  return 1;
11170 }
11171 NK_INTERN int
11172 nk_tt_FindGlyphIndex(const struct nk_tt_fontinfo *info, int unicode_codepoint)
11173 {
11174  const nk_byte *data = info->data;
11175  nk_uint index_map = (nk_uint)info->index_map;
11176 
11177  nk_ushort format = nk_ttUSHORT(data + index_map + 0);
11178  if (format == 0) { /* apple byte encoding */
11179  nk_int bytes = nk_ttUSHORT(data + index_map + 2);
11180  if (unicode_codepoint < bytes-6)
11181  return nk_ttBYTE(data + index_map + 6 + unicode_codepoint);
11182  return 0;
11183  } else if (format == 6) {
11184  nk_uint first = nk_ttUSHORT(data + index_map + 6);
11185  nk_uint count = nk_ttUSHORT(data + index_map + 8);
11186  if ((nk_uint) unicode_codepoint >= first && (nk_uint) unicode_codepoint < first+count)
11187  return nk_ttUSHORT(data + index_map + 10 + (unicode_codepoint - (int)first)*2);
11188  return 0;
11189  } else if (format == 2) {
11190  NK_ASSERT(0); /* @TODO: high-byte mapping for japanese/chinese/korean */
11191  return 0;
11192  } else if (format == 4) { /* standard mapping for windows fonts: binary search collection of ranges */
11193  nk_ushort segcount = nk_ttUSHORT(data+index_map+6) >> 1;
11194  nk_ushort searchRange = nk_ttUSHORT(data+index_map+8) >> 1;
11195  nk_ushort entrySelector = nk_ttUSHORT(data+index_map+10);
11196  nk_ushort rangeShift = nk_ttUSHORT(data+index_map+12) >> 1;
11197 
11198  /* do a binary search of the segments */
11199  nk_uint endCount = index_map + 14;
11200  nk_uint search = endCount;
11201 
11202  if (unicode_codepoint > 0xffff)
11203  return 0;
11204 
11205  /* they lie from endCount .. endCount + segCount */
11206  /* but searchRange is the nearest power of two, so... */
11207  if (unicode_codepoint >= nk_ttUSHORT(data + search + rangeShift*2))
11208  search += (nk_uint)(rangeShift*2);
11209 
11210  /* now decrement to bias correctly to find smallest */
11211  search -= 2;
11212  while (entrySelector) {
11213  nk_ushort end;
11214  searchRange >>= 1;
11215  end = nk_ttUSHORT(data + search + searchRange*2);
11216  if (unicode_codepoint > end)
11217  search += (nk_uint)(searchRange*2);
11218  --entrySelector;
11219  }
11220  search += 2;
11221 
11222  {
11223  nk_ushort offset, start;
11224  nk_ushort item = (nk_ushort) ((search - endCount) >> 1);
11225 
11226  NK_ASSERT(unicode_codepoint <= nk_ttUSHORT(data + endCount + 2*item));
11227  start = nk_ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
11228  if (unicode_codepoint < start)
11229  return 0;
11230 
11231  offset = nk_ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
11232  if (offset == 0)
11233  return (nk_ushort) (unicode_codepoint + nk_ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
11234 
11235  return nk_ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
11236  }
11237  } else if (format == 12 || format == 13) {
11238  nk_uint ngroups = nk_ttULONG(data+index_map+12);
11239  nk_int low,high;
11240  low = 0; high = (nk_int)ngroups;
11241  /* Binary search the right group. */
11242  while (low < high) {
11243  nk_int mid = low + ((high-low) >> 1); /* rounds down, so low <= mid < high */
11244  nk_uint start_char = nk_ttULONG(data+index_map+16+mid*12);
11245  nk_uint end_char = nk_ttULONG(data+index_map+16+mid*12+4);
11246  if ((nk_uint) unicode_codepoint < start_char)
11247  high = mid;
11248  else if ((nk_uint) unicode_codepoint > end_char)
11249  low = mid+1;
11250  else {
11251  nk_uint start_glyph = nk_ttULONG(data+index_map+16+mid*12+8);
11252  if (format == 12)
11253  return (int)start_glyph + (int)unicode_codepoint - (int)start_char;
11254  else /* format == 13 */
11255  return (int)start_glyph;
11256  }
11257  }
11258  return 0; /* not found */
11259  }
11260  /* @TODO */
11261  NK_ASSERT(0);
11262  return 0;
11263 }
11264 NK_INTERN void
11265 nk_tt_setvertex(struct nk_tt_vertex *v, nk_byte type, nk_int x, nk_int y, nk_int cx, nk_int cy)
11266 {
11267  v->type = type;
11268  v->x = (nk_short) x;
11269  v->y = (nk_short) y;
11270  v->cx = (nk_short) cx;
11271  v->cy = (nk_short) cy;
11272 }
11273 NK_INTERN int
11274 nk_tt__GetGlyfOffset(const struct nk_tt_fontinfo *info, int glyph_index)
11275 {
11276  int g1,g2;
11277  if (glyph_index >= info->numGlyphs) return -1; /* glyph index out of range */
11278  if (info->indexToLocFormat >= 2) return -1; /* unknown index->glyph map format */
11279 
11280  if (info->indexToLocFormat == 0) {
11281  g1 = info->glyf + nk_ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
11282  g2 = info->glyf + nk_ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
11283  } else {
11284  g1 = info->glyf + (int)nk_ttULONG (info->data + info->loca + glyph_index * 4);
11285  g2 = info->glyf + (int)nk_ttULONG (info->data + info->loca + glyph_index * 4 + 4);
11286  }
11287  return g1==g2 ? -1 : g1; /* if length is 0, return -1 */
11288 }
11289 NK_INTERN int
11290 nk_tt_GetGlyphBox(const struct nk_tt_fontinfo *info, int glyph_index,
11291  int *x0, int *y0, int *x1, int *y1)
11292 {
11293  int g = nk_tt__GetGlyfOffset(info, glyph_index);
11294  if (g < 0) return 0;
11295 
11296  if (x0) *x0 = nk_ttSHORT(info->data + g + 2);
11297  if (y0) *y0 = nk_ttSHORT(info->data + g + 4);
11298  if (x1) *x1 = nk_ttSHORT(info->data + g + 6);
11299  if (y1) *y1 = nk_ttSHORT(info->data + g + 8);
11300  return 1;
11301 }
11302 NK_INTERN int
11303 nk_tt__close_shape(struct nk_tt_vertex *vertices, int num_vertices, int was_off,
11304  int start_off, nk_int sx, nk_int sy, nk_int scx, nk_int scy, nk_int cx, nk_int cy)
11305 {
11306  if (start_off) {
11307  if (was_off)
11308  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
11309  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, sx,sy,scx,scy);
11310  } else {
11311  if (was_off)
11312  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve,sx,sy,cx,cy);
11313  else
11314  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vline,sx,sy,0,0);
11315  }
11316  return num_vertices;
11317 }
11318 NK_INTERN int
11319 nk_tt_GetGlyphShape(const struct nk_tt_fontinfo *info, struct nk_allocator *alloc,
11320  int glyph_index, struct nk_tt_vertex **pvertices)
11321 {
11322  nk_short numberOfContours;
11323  const nk_byte *endPtsOfContours;
11324  const nk_byte *data = info->data;
11325  struct nk_tt_vertex *vertices=0;
11326  int num_vertices=0;
11327  int g = nk_tt__GetGlyfOffset(info, glyph_index);
11328  *pvertices = 0;
11329 
11330  if (g < 0) return 0;
11331  numberOfContours = nk_ttSHORT(data + g);
11332  if (numberOfContours > 0) {
11333  nk_byte flags=0,flagcount;
11334  nk_int ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
11335  nk_int x,y,cx,cy,sx,sy, scx,scy;
11336  const nk_byte *points;
11337  endPtsOfContours = (data + g + 10);
11338  ins = nk_ttUSHORT(data + g + 10 + numberOfContours * 2);
11339  points = data + g + 10 + numberOfContours * 2 + 2 + ins;
11340 
11341  n = 1+nk_ttUSHORT(endPtsOfContours + numberOfContours*2-2);
11342  m = n + 2*numberOfContours; /* a loose bound on how many vertices we might need */
11343  vertices = (struct nk_tt_vertex *)alloc->alloc(alloc->userdata, 0, (nk_size)m * sizeof(vertices[0]));
11344  if (vertices == 0)
11345  return 0;
11346 
11347  next_move = 0;
11348  flagcount=0;
11349 
11350  /* in first pass, we load uninterpreted data into the allocated array */
11351  /* above, shifted to the end of the array so we won't overwrite it when */
11352  /* we create our final data starting from the front */
11353  off = m - n; /* starting offset for uninterpreted data, regardless of how m ends up being calculated */
11354 
11355  /* first load flags */
11356  for (i=0; i < n; ++i) {
11357  if (flagcount == 0) {
11358  flags = *points++;
11359  if (flags & 8)
11360  flagcount = *points++;
11361  } else --flagcount;
11362  vertices[off+i].type = flags;
11363  }
11364 
11365  /* now load x coordinates */
11366  x=0;
11367  for (i=0; i < n; ++i) {
11368  flags = vertices[off+i].type;
11369  if (flags & 2) {
11370  nk_short dx = *points++;
11371  x += (flags & 16) ? dx : -dx; /* ??? */
11372  } else {
11373  if (!(flags & 16)) {
11374  x = x + (nk_short) (points[0]*256 + points[1]);
11375  points += 2;
11376  }
11377  }
11378  vertices[off+i].x = (nk_short) x;
11379  }
11380 
11381  /* now load y coordinates */
11382  y=0;
11383  for (i=0; i < n; ++i) {
11384  flags = vertices[off+i].type;
11385  if (flags & 4) {
11386  nk_short dy = *points++;
11387  y += (flags & 32) ? dy : -dy; /* ??? */
11388  } else {
11389  if (!(flags & 32)) {
11390  y = y + (nk_short) (points[0]*256 + points[1]);
11391  points += 2;
11392  }
11393  }
11394  vertices[off+i].y = (nk_short) y;
11395  }
11396 
11397  /* now convert them to our format */
11398  num_vertices=0;
11399  sx = sy = cx = cy = scx = scy = 0;
11400  for (i=0; i < n; ++i)
11401  {
11402  flags = vertices[off+i].type;
11403  x = (nk_short) vertices[off+i].x;
11404  y = (nk_short) vertices[off+i].y;
11405 
11406  if (next_move == i) {
11407  if (i != 0)
11408  num_vertices = nk_tt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
11409 
11410  /* now start the new one */
11411  start_off = !(flags & 1);
11412  if (start_off) {
11413  /* if we start off with an off-curve point, then when we need to find a point on the curve */
11414  /* where we can start, and we need to save some state for when we wraparound. */
11415  scx = x;
11416  scy = y;
11417  if (!(vertices[off+i+1].type & 1)) {
11418  /* next point is also a curve point, so interpolate an on-point curve */
11419  sx = (x + (nk_int) vertices[off+i+1].x) >> 1;
11420  sy = (y + (nk_int) vertices[off+i+1].y) >> 1;
11421  } else {
11422  /* otherwise just use the next point as our start point */
11423  sx = (nk_int) vertices[off+i+1].x;
11424  sy = (nk_int) vertices[off+i+1].y;
11425  ++i; /* we're using point i+1 as the starting point, so skip it */
11426  }
11427  } else {
11428  sx = x;
11429  sy = y;
11430  }
11431  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vmove,sx,sy,0,0);
11432  was_off = 0;
11433  next_move = 1 + nk_ttUSHORT(endPtsOfContours+j*2);
11434  ++j;
11435  } else {
11436  if (!(flags & 1))
11437  { /* if it's a curve */
11438  if (was_off) /* two off-curve control points in a row means interpolate an on-curve midpoint */
11439  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
11440  cx = x;
11441  cy = y;
11442  was_off = 1;
11443  } else {
11444  if (was_off)
11445  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, x,y, cx, cy);
11446  else nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vline, x,y,0,0);
11447  was_off = 0;
11448  }
11449  }
11450  }
11451  num_vertices = nk_tt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
11452  } else if (numberOfContours == -1) {
11453  /* Compound shapes. */
11454  int more = 1;
11455  const nk_byte *comp = data + g + 10;
11456  num_vertices = 0;
11457  vertices = 0;
11458 
11459  while (more)
11460  {
11461  nk_ushort flags, gidx;
11462  int comp_num_verts = 0, i;
11463  struct nk_tt_vertex *comp_verts = 0, *tmp = 0;
11464  float mtx[6] = {1,0,0,1,0,0}, m, n;
11465 
11466  flags = (nk_ushort)nk_ttSHORT(comp); comp+=2;
11467  gidx = (nk_ushort)nk_ttSHORT(comp); comp+=2;
11468 
11469  if (flags & 2) { /* XY values */
11470  if (flags & 1) { /* shorts */
11471  mtx[4] = nk_ttSHORT(comp); comp+=2;
11472  mtx[5] = nk_ttSHORT(comp); comp+=2;
11473  } else {
11474  mtx[4] = nk_ttCHAR(comp); comp+=1;
11475  mtx[5] = nk_ttCHAR(comp); comp+=1;
11476  }
11477  } else {
11478  /* @TODO handle matching point */
11479  NK_ASSERT(0);
11480  }
11481  if (flags & (1<<3)) { /* WE_HAVE_A_SCALE */
11482  mtx[0] = mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11483  mtx[1] = mtx[2] = 0;
11484  } else if (flags & (1<<6)) { /* WE_HAVE_AN_X_AND_YSCALE */
11485  mtx[0] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11486  mtx[1] = mtx[2] = 0;
11487  mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11488  } else if (flags & (1<<7)) { /* WE_HAVE_A_TWO_BY_TWO */
11489  mtx[0] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11490  mtx[1] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11491  mtx[2] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11492  mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11493  }
11494 
11495  /* Find transformation scales. */
11496  m = (float) NK_SQRT(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
11497  n = (float) NK_SQRT(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
11498 
11499  /* Get indexed glyph. */
11500  comp_num_verts = nk_tt_GetGlyphShape(info, alloc, gidx, &comp_verts);
11501  if (comp_num_verts > 0)
11502  {
11503  /* Transform vertices. */
11504  for (i = 0; i < comp_num_verts; ++i) {
11505  struct nk_tt_vertex* v = &comp_verts[i];
11506  short x,y;
11507  x=v->x; y=v->y;
11508  v->x = (short)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
11509  v->y = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
11510  x=v->cx; y=v->cy;
11511  v->cx = (short)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
11512  v->cy = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
11513  }
11514  /* Append vertices. */
11515  tmp = (struct nk_tt_vertex*)alloc->alloc(alloc->userdata, 0,
11516  (nk_size)(num_vertices+comp_num_verts)*sizeof(struct nk_tt_vertex));
11517  if (!tmp) {
11518  if (vertices) alloc->free(alloc->userdata, vertices);
11519  if (comp_verts) alloc->free(alloc->userdata, comp_verts);
11520  return 0;
11521  }
11522  if (num_vertices > 0) NK_MEMCPY(tmp, vertices, (nk_size)num_vertices*sizeof(struct nk_tt_vertex));
11523  NK_MEMCPY(tmp+num_vertices, comp_verts, (nk_size)comp_num_verts*sizeof(struct nk_tt_vertex));
11524  if (vertices) alloc->free(alloc->userdata,vertices);
11525  vertices = tmp;
11526  alloc->free(alloc->userdata,comp_verts);
11527  num_vertices += comp_num_verts;
11528  }
11529  /* More components ? */
11530  more = flags & (1<<5);
11531  }
11532  } else if (numberOfContours < 0) {
11533  /* @TODO other compound variations? */
11534  NK_ASSERT(0);
11535  } else {
11536  /* numberOfCounters == 0, do nothing */
11537  }
11538  *pvertices = vertices;
11539  return num_vertices;
11540 }
11541 NK_INTERN void
11542 nk_tt_GetGlyphHMetrics(const struct nk_tt_fontinfo *info, int glyph_index,
11543  int *advanceWidth, int *leftSideBearing)
11544 {
11545  nk_ushort numOfLongHorMetrics = nk_ttUSHORT(info->data+info->hhea + 34);
11546  if (glyph_index < numOfLongHorMetrics) {
11547  if (advanceWidth)
11548  *advanceWidth = nk_ttSHORT(info->data + info->hmtx + 4*glyph_index);
11549  if (leftSideBearing)
11550  *leftSideBearing = nk_ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
11551  } else {
11552  if (advanceWidth)
11553  *advanceWidth = nk_ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
11554  if (leftSideBearing)
11555  *leftSideBearing = nk_ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
11556  }
11557 }
11558 NK_INTERN void
11559 nk_tt_GetFontVMetrics(const struct nk_tt_fontinfo *info,
11560  int *ascent, int *descent, int *lineGap)
11561 {
11562  if (ascent ) *ascent = nk_ttSHORT(info->data+info->hhea + 4);
11563  if (descent) *descent = nk_ttSHORT(info->data+info->hhea + 6);
11564  if (lineGap) *lineGap = nk_ttSHORT(info->data+info->hhea + 8);
11565 }
11566 NK_INTERN float
11567 nk_tt_ScaleForPixelHeight(const struct nk_tt_fontinfo *info, float height)
11568 {
11569  int fheight = nk_ttSHORT(info->data + info->hhea + 4) - nk_ttSHORT(info->data + info->hhea + 6);
11570  return (float) height / (float)fheight;
11571 }
11572 NK_INTERN float
11573 nk_tt_ScaleForMappingEmToPixels(const struct nk_tt_fontinfo *info, float pixels)
11574 {
11575  int unitsPerEm = nk_ttUSHORT(info->data + info->head + 18);
11576  return pixels / (float)unitsPerEm;
11577 }
11578 
11579 /*-------------------------------------------------------------
11580  * antialiasing software rasterizer
11581  * --------------------------------------------------------------*/
11582 NK_INTERN void
11583 nk_tt_GetGlyphBitmapBoxSubpixel(const struct nk_tt_fontinfo *font,
11584  int glyph, float scale_x, float scale_y,float shift_x, float shift_y,
11585  int *ix0, int *iy0, int *ix1, int *iy1)
11586 {
11587  int x0,y0,x1,y1;
11588  if (!nk_tt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
11589  /* e.g. space character */
11590  if (ix0) *ix0 = 0;
11591  if (iy0) *iy0 = 0;
11592  if (ix1) *ix1 = 0;
11593  if (iy1) *iy1 = 0;
11594  } else {
11595  /* move to integral bboxes (treating pixels as little squares, what pixels get touched)? */
11596  if (ix0) *ix0 = nk_ifloorf((float)x0 * scale_x + shift_x);
11597  if (iy0) *iy0 = nk_ifloorf((float)-y1 * scale_y + shift_y);
11598  if (ix1) *ix1 = nk_iceilf ((float)x1 * scale_x + shift_x);
11599  if (iy1) *iy1 = nk_iceilf ((float)-y0 * scale_y + shift_y);
11600  }
11601 }
11602 NK_INTERN void
11603 nk_tt_GetGlyphBitmapBox(const struct nk_tt_fontinfo *font, int glyph,
11604  float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
11605 {
11606  nk_tt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
11607 }
11608 
11609 /*-------------------------------------------------------------
11610  * Rasterizer
11611  * --------------------------------------------------------------*/
11612 NK_INTERN void*
11613 nk_tt__hheap_alloc(struct nk_tt__hheap *hh, nk_size size)
11614 {
11615  if (hh->first_free) {
11616  void *p = hh->first_free;
11617  hh->first_free = * (void **) p;
11618  return p;
11619  } else {
11620  if (hh->num_remaining_in_head_chunk == 0) {
11621  int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
11622  struct nk_tt__hheap_chunk *c = (struct nk_tt__hheap_chunk *)
11623  hh->alloc.alloc(hh->alloc.userdata, 0,
11624  sizeof(struct nk_tt__hheap_chunk) + size * (nk_size)count);
11625  if (c == 0) return 0;
11626  c->next = hh->head;
11627  hh->head = c;
11628  hh->num_remaining_in_head_chunk = count;
11629  }
11630  --hh->num_remaining_in_head_chunk;
11631  return (char *) (hh->head) + size * (nk_size)hh->num_remaining_in_head_chunk;
11632  }
11633 }
11634 NK_INTERN void
11635 nk_tt__hheap_free(struct nk_tt__hheap *hh, void *p)
11636 {
11637  *(void **) p = hh->first_free;
11638  hh->first_free = p;
11639 }
11640 NK_INTERN void
11641 nk_tt__hheap_cleanup(struct nk_tt__hheap *hh)
11642 {
11643  struct nk_tt__hheap_chunk *c = hh->head;
11644  while (c) {
11645  struct nk_tt__hheap_chunk *n = c->next;
11646  hh->alloc.free(hh->alloc.userdata, c);
11647  c = n;
11648  }
11649 }
11650 NK_INTERN struct nk_tt__active_edge*
11651 nk_tt__new_active(struct nk_tt__hheap *hh, struct nk_tt__edge *e,
11652  int off_x, float start_point)
11653 {
11654  struct nk_tt__active_edge *z = (struct nk_tt__active_edge *)
11655  nk_tt__hheap_alloc(hh, sizeof(*z));
11656  float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
11657  /*STBTT_assert(e->y0 <= start_point); */
11658  if (!z) return z;
11659  z->fdx = dxdy;
11660  z->fdy = (dxdy != 0) ? (1/dxdy): 0;
11661  z->fx = e->x0 + dxdy * (start_point - e->y0);
11662  z->fx -= (float)off_x;
11663  z->direction = e->invert ? 1.0f : -1.0f;
11664  z->sy = e->y0;
11665  z->ey = e->y1;
11666  z->next = 0;
11667  return z;
11668 }
11669 NK_INTERN void
11670 nk_tt__handle_clipped_edge(float *scanline, int x, struct nk_tt__active_edge *e,
11671  float x0, float y0, float x1, float y1)
11672 {
11673  if (y0 == y1) return;
11674  NK_ASSERT(y0 < y1);
11675  NK_ASSERT(e->sy <= e->ey);
11676  if (y0 > e->ey) return;
11677  if (y1 < e->sy) return;
11678  if (y0 < e->sy) {
11679  x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
11680  y0 = e->sy;
11681  }
11682  if (y1 > e->ey) {
11683  x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
11684  y1 = e->ey;
11685  }
11686 
11687  if (x0 == x) NK_ASSERT(x1 <= x+1);
11688  else if (x0 == x+1) NK_ASSERT(x1 >= x);
11689  else if (x0 <= x) NK_ASSERT(x1 <= x);
11690  else if (x0 >= x+1) NK_ASSERT(x1 >= x+1);
11691  else NK_ASSERT(x1 >= x && x1 <= x+1);
11692 
11693  if (x0 <= x && x1 <= x)
11694  scanline[x] += e->direction * (y1-y0);
11695  else if (x0 >= x+1 && x1 >= x+1);
11696  else {
11697  NK_ASSERT(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
11698  /* coverage = 1 - average x position */
11699  scanline[x] += (float)e->direction * (float)(y1-y0) * (1.0f-((x0-(float)x)+(x1-(float)x))/2.0f);
11700  }
11701 }
11702 NK_INTERN void
11703 nk_tt__fill_active_edges_new(float *scanline, float *scanline_fill, int len,
11704  struct nk_tt__active_edge *e, float y_top)
11705 {
11706  float y_bottom = y_top+1;
11707  while (e)
11708  {
11709  /* brute force every pixel */
11710  /* compute intersection points with top & bottom */
11711  NK_ASSERT(e->ey >= y_top);
11712  if (e->fdx == 0) {
11713  float x0 = e->fx;
11714  if (x0 < len) {
11715  if (x0 >= 0) {
11716  nk_tt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom);
11717  nk_tt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom);
11718  } else {
11719  nk_tt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
11720  }
11721  }
11722  } else {
11723  float x0 = e->fx;
11724  float dx = e->fdx;
11725  float xb = x0 + dx;
11726  float x_top, x_bottom;
11727  float y0,y1;
11728  float dy = e->fdy;
11729  NK_ASSERT(e->sy <= y_bottom && e->ey >= y_top);
11730 
11731  /* compute endpoints of line segment clipped to this scanline (if the */
11732  /* line segment starts on this scanline. x0 is the intersection of the */
11733  /* line with y_top, but that may be off the line segment. */
11734  if (e->sy > y_top) {
11735  x_top = x0 + dx * (e->sy - y_top);
11736  y0 = e->sy;
11737  } else {
11738  x_top = x0;
11739  y0 = y_top;
11740  }
11741 
11742  if (e->ey < y_bottom) {
11743  x_bottom = x0 + dx * (e->ey - y_top);
11744  y1 = e->ey;
11745  } else {
11746  x_bottom = xb;
11747  y1 = y_bottom;
11748  }
11749 
11750  if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len)
11751  {
11752  /* from here on, we don't have to range check x values */
11753  if ((int) x_top == (int) x_bottom) {
11754  float height;
11755  /* simple case, only spans one pixel */
11756  int x = (int) x_top;
11757  height = y1 - y0;
11758  NK_ASSERT(x >= 0 && x < len);
11759  scanline[x] += e->direction * (1.0f-(((float)x_top - (float)x) + ((float)x_bottom-(float)x))/2.0f) * (float)height;
11760  scanline_fill[x] += e->direction * (float)height; /* everything right of this pixel is filled */
11761  } else {
11762  int x,x1,x2;
11763  float y_crossing, step, sign, area;
11764  /* covers 2+ pixels */
11765  if (x_top > x_bottom)
11766  {
11767  /* flip scanline vertically; signed area is the same */
11768  float t;
11769  y0 = y_bottom - (y0 - y_top);
11770  y1 = y_bottom - (y1 - y_top);
11771  t = y0; y0 = y1; y1 = t;
11772  t = x_bottom; x_bottom = x_top; x_top = t;
11773  dx = -dx;
11774  dy = -dy;
11775  t = x0; x0 = xb; xb = t;
11776  }
11777 
11778  x1 = (int) x_top;
11779  x2 = (int) x_bottom;
11780  /* compute intersection with y axis at x1+1 */
11781  y_crossing = ((float)x1+1 - (float)x0) * (float)dy + (float)y_top;
11782 
11783  sign = e->direction;
11784  /* area of the rectangle covered from y0..y_crossing */
11785  area = sign * (y_crossing-y0);
11786  /* area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) */
11787  scanline[x1] += area * (1.0f-((float)((float)x_top - (float)x1)+(float)(x1+1-x1))/2.0f);
11788 
11789  step = sign * dy;
11790  for (x = x1+1; x < x2; ++x) {
11791  scanline[x] += area + step/2;
11792  area += step;
11793  }
11794  y_crossing += (float)dy * (float)(x2 - (x1+1));
11795 
11796  scanline[x2] += area + sign * (1.0f-((float)(x2-x2)+((float)x_bottom-(float)x2))/2.0f) * (y1-y_crossing);
11797  scanline_fill[x2] += sign * (y1-y0);
11798  }
11799  }
11800  else
11801  {
11802  /* if edge goes outside of box we're drawing, we require */
11803  /* clipping logic. since this does not match the intended use */
11804  /* of this library, we use a different, very slow brute */
11805  /* force implementation */
11806  int x;
11807  for (x=0; x < len; ++x)
11808  {
11809  /* cases: */
11810  /* */
11811  /* there can be up to two intersections with the pixel. any intersection */
11812  /* with left or right edges can be handled by splitting into two (or three) */
11813  /* regions. intersections with top & bottom do not necessitate case-wise logic. */
11814  /* */
11815  /* the old way of doing this found the intersections with the left & right edges, */
11816  /* then used some simple logic to produce up to three segments in sorted order */
11817  /* from top-to-bottom. however, this had a problem: if an x edge was epsilon */
11818  /* across the x border, then the corresponding y position might not be distinct */
11819  /* from the other y segment, and it might ignored as an empty segment. to avoid */
11820  /* that, we need to explicitly produce segments based on x positions. */
11821 
11822  /* rename variables to clear pairs */
11823  float ya = y_top;
11824  float x1 = (float) (x);
11825  float x2 = (float) (x+1);
11826  float x3 = xb;
11827  float y3 = y_bottom;
11828  float yb,y2;
11829 
11830  yb = ((float)x - x0) / dx + y_top;
11831  y2 = ((float)x+1 - x0) / dx + y_top;
11832 
11833  if (x0 < x1 && x3 > x2) { /* three segments descending down-right */
11834  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
11835  nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x2,y2);
11836  nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
11837  } else if (x3 < x1 && x0 > x2) { /* three segments descending down-left */
11838  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
11839  nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x1,yb);
11840  nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
11841  } else if (x0 < x1 && x3 > x1) { /* two segments across x, down-right */
11842  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
11843  nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
11844  } else if (x3 < x1 && x0 > x1) { /* two segments across x, down-left */
11845  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
11846  nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
11847  } else if (x0 < x2 && x3 > x2) { /* two segments across x+1, down-right */
11848  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
11849  nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
11850  } else if (x3 < x2 && x0 > x2) { /* two segments across x+1, down-left */
11851  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
11852  nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
11853  } else { /* one segment */
11854  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x3,y3);
11855  }
11856  }
11857  }
11858  }
11859  e = e->next;
11860  }
11861 }
11862 NK_INTERN void
11863 nk_tt__rasterize_sorted_edges(struct nk_tt__bitmap *result, struct nk_tt__edge *e,
11864  int n, int vsubsample, int off_x, int off_y, struct nk_allocator *alloc)
11865 {
11866  /* directly AA rasterize edges w/o supersampling */
11867  struct nk_tt__hheap hh;
11868  struct nk_tt__active_edge *active = 0;
11869  int y,j=0, i;
11870  float scanline_data[129], *scanline, *scanline2;
11871 
11872  NK_UNUSED(vsubsample);
11873  nk_zero_struct(hh);
11874  hh.alloc = *alloc;
11875 
11876  if (result->w > 64)
11877  scanline = (float *) alloc->alloc(alloc->userdata,0, (nk_size)(result->w*2+1) * sizeof(float));
11878  else scanline = scanline_data;
11879 
11880  scanline2 = scanline + result->w;
11881  y = off_y;
11882  e[n].y0 = (float) (off_y + result->h) + 1;
11883 
11884  while (j < result->h)
11885  {
11886  /* find center of pixel for this scanline */
11887  float scan_y_top = (float)y + 0.0f;
11888  float scan_y_bottom = (float)y + 1.0f;
11889  struct nk_tt__active_edge **step = &active;
11890 
11891  NK_MEMSET(scanline , 0, (nk_size)result->w*sizeof(scanline[0]));
11892  NK_MEMSET(scanline2, 0, (nk_size)(result->w+1)*sizeof(scanline[0]));
11893 
11894  /* update all active edges; */
11895  /* remove all active edges that terminate before the top of this scanline */
11896  while (*step) {
11897  struct nk_tt__active_edge * z = *step;
11898  if (z->ey <= scan_y_top) {
11899  *step = z->next; /* delete from list */
11900  NK_ASSERT(z->direction);
11901  z->direction = 0;
11902  nk_tt__hheap_free(&hh, z);
11903  } else {
11904  step = &((*step)->next); /* advance through list */
11905  }
11906  }
11907 
11908  /* insert all edges that start before the bottom of this scanline */
11909  while (e->y0 <= scan_y_bottom) {
11910  if (e->y0 != e->y1) {
11911  struct nk_tt__active_edge *z = nk_tt__new_active(&hh, e, off_x, scan_y_top);
11912  if (z != 0) {
11913  NK_ASSERT(z->ey >= scan_y_top);
11914  /* insert at front */
11915  z->next = active;
11916  active = z;
11917  }
11918  }
11919  ++e;
11920  }
11921 
11922  /* now process all active edges */
11923  if (active)
11924  nk_tt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top);
11925 
11926  {
11927  float sum = 0;
11928  for (i=0; i < result->w; ++i) {
11929  float k;
11930  int m;
11931  sum += scanline2[i];
11932  k = scanline[i] + sum;
11933  k = (float) NK_ABS(k) * 255.0f + 0.5f;
11934  m = (int) k;
11935  if (m > 255) m = 255;
11936  result->pixels[j*result->stride + i] = (unsigned char) m;
11937  }
11938  }
11939  /* advance all the edges */
11940  step = &active;
11941  while (*step) {
11942  struct nk_tt__active_edge *z = *step;
11943  z->fx += z->fdx; /* advance to position for current scanline */
11944  step = &((*step)->next); /* advance through list */
11945  }
11946  ++y;
11947  ++j;
11948  }
11949  nk_tt__hheap_cleanup(&hh);
11950  if (scanline != scanline_data)
11951  alloc->free(alloc->userdata, scanline);
11952 }
11953 NK_INTERN void
11954 nk_tt__sort_edges_ins_sort(struct nk_tt__edge *p, int n)
11955 {
11956  int i,j;
11957  #define NK_TT__COMPARE(a,b) ((a)->y0 < (b)->y0)
11958  for (i=1; i < n; ++i) {
11959  struct nk_tt__edge t = p[i], *a = &t;
11960  j = i;
11961  while (j > 0) {
11962  struct nk_tt__edge *b = &p[j-1];
11963  int c = NK_TT__COMPARE(a,b);
11964  if (!c) break;
11965  p[j] = p[j-1];
11966  --j;
11967  }
11968  if (i != j)
11969  p[j] = t;
11970  }
11971 }
11972 NK_INTERN void
11973 nk_tt__sort_edges_quicksort(struct nk_tt__edge *p, int n)
11974 {
11975  /* threshold for transitioning to insertion sort */
11976  while (n > 12) {
11977  struct nk_tt__edge t;
11978  int c01,c12,c,m,i,j;
11979 
11980  /* compute median of three */
11981  m = n >> 1;
11982  c01 = NK_TT__COMPARE(&p[0],&p[m]);
11983  c12 = NK_TT__COMPARE(&p[m],&p[n-1]);
11984 
11985  /* if 0 >= mid >= end, or 0 < mid < end, then use mid */
11986  if (c01 != c12) {
11987  /* otherwise, we'll need to swap something else to middle */
11988  int z;
11989  c = NK_TT__COMPARE(&p[0],&p[n-1]);
11990  /* 0>mid && mid<n: 0>n => n; 0<n => 0 */
11991  /* 0<mid && mid>n: 0>n => 0; 0<n => n */
11992  z = (c == c12) ? 0 : n-1;
11993  t = p[z];
11994  p[z] = p[m];
11995  p[m] = t;
11996  }
11997 
11998  /* now p[m] is the median-of-three */
11999  /* swap it to the beginning so it won't move around */
12000  t = p[0];
12001  p[0] = p[m];
12002  p[m] = t;
12003 
12004  /* partition loop */
12005  i=1;
12006  j=n-1;
12007  for(;;) {
12008  /* handling of equality is crucial here */
12009  /* for sentinels & efficiency with duplicates */
12010  for (;;++i) {
12011  if (!NK_TT__COMPARE(&p[i], &p[0])) break;
12012  }
12013  for (;;--j) {
12014  if (!NK_TT__COMPARE(&p[0], &p[j])) break;
12015  }
12016 
12017  /* make sure we haven't crossed */
12018  if (i >= j) break;
12019  t = p[i];
12020  p[i] = p[j];
12021  p[j] = t;
12022 
12023  ++i;
12024  --j;
12025 
12026  }
12027 
12028  /* recurse on smaller side, iterate on larger */
12029  if (j < (n-i)) {
12030  nk_tt__sort_edges_quicksort(p,j);
12031  p = p+i;
12032  n = n-i;
12033  } else {
12034  nk_tt__sort_edges_quicksort(p+i, n-i);
12035  n = j;
12036  }
12037  }
12038 }
12039 NK_INTERN void
12040 nk_tt__sort_edges(struct nk_tt__edge *p, int n)
12041 {
12042  nk_tt__sort_edges_quicksort(p, n);
12043  nk_tt__sort_edges_ins_sort(p, n);
12044 }
12045 NK_INTERN void
12046 nk_tt__rasterize(struct nk_tt__bitmap *result, struct nk_tt__point *pts,
12047  int *wcount, int windings, float scale_x, float scale_y,
12048  float shift_x, float shift_y, int off_x, int off_y, int invert,
12049  struct nk_allocator *alloc)
12050 {
12051  float y_scale_inv = invert ? -scale_y : scale_y;
12052  struct nk_tt__edge *e;
12053  int n,i,j,k,m;
12054  int vsubsample = 1;
12055  /* vsubsample should divide 255 evenly; otherwise we won't reach full opacity */
12056 
12057  /* now we have to blow out the windings into explicit edge lists */
12058  n = 0;
12059  for (i=0; i < windings; ++i)
12060  n += wcount[i];
12061 
12062  e = (struct nk_tt__edge*)
12063  alloc->alloc(alloc->userdata, 0,(sizeof(*e) * (nk_size)(n+1)));
12064  if (e == 0) return;
12065  n = 0;
12066 
12067  m=0;
12068  for (i=0; i < windings; ++i)
12069  {
12070  struct nk_tt__point *p = pts + m;
12071  m += wcount[i];
12072  j = wcount[i]-1;
12073  for (k=0; k < wcount[i]; j=k++) {
12074  int a=k,b=j;
12075  /* skip the edge if horizontal */
12076  if (p[j].y == p[k].y)
12077  continue;
12078 
12079  /* add edge from j to k to the list */
12080  e[n].invert = 0;
12081  if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
12082  e[n].invert = 1;
12083  a=j,b=k;
12084  }
12085  e[n].x0 = p[a].x * scale_x + shift_x;
12086  e[n].y0 = (p[a].y * y_scale_inv + shift_y) * (float)vsubsample;
12087  e[n].x1 = p[b].x * scale_x + shift_x;
12088  e[n].y1 = (p[b].y * y_scale_inv + shift_y) * (float)vsubsample;
12089  ++n;
12090  }
12091  }
12092 
12093  /* now sort the edges by their highest point (should snap to integer, and then by x) */
12094  /*STBTT_sort(e, n, sizeof(e[0]), nk_tt__edge_compare); */
12095  nk_tt__sort_edges(e, n);
12096  /* now, traverse the scanlines and find the intersections on each scanline, use xor winding rule */
12097  nk_tt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, alloc);
12098  alloc->free(alloc->userdata, e);
12099 }
12100 NK_INTERN void
12101 nk_tt__add_point(struct nk_tt__point *points, int n, float x, float y)
12102 {
12103  if (!points) return; /* during first pass, it's unallocated */
12104  points[n].x = x;
12105  points[n].y = y;
12106 }
12107 NK_INTERN int
12108 nk_tt__tesselate_curve(struct nk_tt__point *points, int *num_points,
12109  float x0, float y0, float x1, float y1, float x2, float y2,
12110  float objspace_flatness_squared, int n)
12111 {
12112  /* tesselate until threshold p is happy...
12113  * @TODO warped to compensate for non-linear stretching */
12114  /* midpoint */
12115  float mx = (x0 + 2*x1 + x2)/4;
12116  float my = (y0 + 2*y1 + y2)/4;
12117  /* versus directly drawn line */
12118  float dx = (x0+x2)/2 - mx;
12119  float dy = (y0+y2)/2 - my;
12120  if (n > 16) /* 65536 segments on one curve better be enough! */
12121  return 1;
12122 
12123  /* half-pixel error allowed... need to be smaller if AA */
12124  if (dx*dx+dy*dy > objspace_flatness_squared) {
12125  nk_tt__tesselate_curve(points, num_points, x0,y0,
12126  (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
12127  nk_tt__tesselate_curve(points, num_points, mx,my,
12128  (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
12129  } else {
12130  nk_tt__add_point(points, *num_points,x2,y2);
12131  *num_points = *num_points+1;
12132  }
12133  return 1;
12134 }
12135 NK_INTERN struct nk_tt__point*
12136 nk_tt_FlattenCurves(struct nk_tt_vertex *vertices, int num_verts,
12137  float objspace_flatness, int **contour_lengths, int *num_contours,
12138  struct nk_allocator *alloc)
12139 {
12140  /* returns number of contours */
12141  struct nk_tt__point *points=0;
12142  int num_points=0;
12143  float objspace_flatness_squared = objspace_flatness * objspace_flatness;
12144  int i;
12145  int n=0;
12146  int start=0;
12147  int pass;
12148 
12149  /* count how many "moves" there are to get the contour count */
12150  for (i=0; i < num_verts; ++i)
12151  if (vertices[i].type == NK_TT_vmove) ++n;
12152 
12153  *num_contours = n;
12154  if (n == 0) return 0;
12155 
12156  *contour_lengths = (int *)
12157  alloc->alloc(alloc->userdata,0, (sizeof(**contour_lengths) * (nk_size)n));
12158  if (*contour_lengths == 0) {
12159  *num_contours = 0;
12160  return 0;
12161  }
12162 
12163  /* make two passes through the points so we don't need to realloc */
12164  for (pass=0; pass < 2; ++pass)
12165  {
12166  float x=0,y=0;
12167  if (pass == 1) {
12168  points = (struct nk_tt__point *)
12169  alloc->alloc(alloc->userdata,0, (nk_size)num_points * sizeof(points[0]));
12170  if (points == 0) goto error;
12171  }
12172  num_points = 0;
12173  n= -1;
12174 
12175  for (i=0; i < num_verts; ++i)
12176  {
12177  switch (vertices[i].type) {
12178  case NK_TT_vmove:
12179  /* start the next contour */
12180  if (n >= 0)
12181  (*contour_lengths)[n] = num_points - start;
12182  ++n;
12183  start = num_points;
12184 
12185  x = vertices[i].x, y = vertices[i].y;
12186  nk_tt__add_point(points, num_points++, x,y);
12187  break;
12188  case NK_TT_vline:
12189  x = vertices[i].x, y = vertices[i].y;
12190  nk_tt__add_point(points, num_points++, x, y);
12191  break;
12192  case NK_TT_vcurve:
12193  nk_tt__tesselate_curve(points, &num_points, x,y,
12194  vertices[i].cx, vertices[i].cy,
12195  vertices[i].x, vertices[i].y,
12196  objspace_flatness_squared, 0);
12197  x = vertices[i].x, y = vertices[i].y;
12198  break;
12199  default: break;
12200  }
12201  }
12202  (*contour_lengths)[n] = num_points - start;
12203  }
12204  return points;
12205 
12206 error:
12207  alloc->free(alloc->userdata, points);
12208  alloc->free(alloc->userdata, *contour_lengths);
12209  *contour_lengths = 0;
12210  *num_contours = 0;
12211  return 0;
12212 }
12213 NK_INTERN void
12214 nk_tt_Rasterize(struct nk_tt__bitmap *result, float flatness_in_pixels,
12215  struct nk_tt_vertex *vertices, int num_verts,
12216  float scale_x, float scale_y, float shift_x, float shift_y,
12217  int x_off, int y_off, int invert, struct nk_allocator *alloc)
12218 {
12219  float scale = scale_x > scale_y ? scale_y : scale_x;
12220  int winding_count, *winding_lengths;
12221  struct nk_tt__point *windings = nk_tt_FlattenCurves(vertices, num_verts,
12222  flatness_in_pixels / scale, &winding_lengths, &winding_count, alloc);
12223 
12224  NK_ASSERT(alloc);
12225  if (windings) {
12226  nk_tt__rasterize(result, windings, winding_lengths, winding_count,
12227  scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, alloc);
12228  alloc->free(alloc->userdata, winding_lengths);
12229  alloc->free(alloc->userdata, windings);
12230  }
12231 }
12232 NK_INTERN void
12233 nk_tt_MakeGlyphBitmapSubpixel(const struct nk_tt_fontinfo *info, unsigned char *output,
12234  int out_w, int out_h, int out_stride, float scale_x, float scale_y,
12235  float shift_x, float shift_y, int glyph, struct nk_allocator *alloc)
12236 {
12237  int ix0,iy0;
12238  struct nk_tt_vertex *vertices;
12239  int num_verts = nk_tt_GetGlyphShape(info, alloc, glyph, &vertices);
12240  struct nk_tt__bitmap gbm;
12241 
12242  nk_tt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x,
12243  shift_y, &ix0,&iy0,0,0);
12244  gbm.pixels = output;
12245  gbm.w = out_w;
12246  gbm.h = out_h;
12247  gbm.stride = out_stride;
12248 
12249  if (gbm.w && gbm.h)
12250  nk_tt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y,
12251  shift_x, shift_y, ix0,iy0, 1, alloc);
12252  alloc->free(alloc->userdata, vertices);
12253 }
12254 
12255 /*-------------------------------------------------------------
12256  * Bitmap baking
12257  * --------------------------------------------------------------*/
12258 NK_INTERN int
12259 nk_tt_PackBegin(struct nk_tt_pack_context *spc, unsigned char *pixels,
12260  int pw, int ph, int stride_in_bytes, int padding, struct nk_allocator *alloc)
12261 {
12262  int num_nodes = pw - padding;
12263  struct nk_rp_context *context = (struct nk_rp_context *)
12264  alloc->alloc(alloc->userdata,0, sizeof(*context));
12265  struct nk_rp_node *nodes = (struct nk_rp_node*)
12266  alloc->alloc(alloc->userdata,0, (sizeof(*nodes ) * (nk_size)num_nodes));
12267 
12268  if (context == 0 || nodes == 0) {
12269  if (context != 0) alloc->free(alloc->userdata, context);
12270  if (nodes != 0) alloc->free(alloc->userdata, nodes);
12271  return 0;
12272  }
12273 
12274  spc->width = pw;
12275  spc->height = ph;
12276  spc->pixels = pixels;
12277  spc->pack_info = context;
12278  spc->nodes = nodes;
12279  spc->padding = padding;
12280  spc->stride_in_bytes = (stride_in_bytes != 0) ? stride_in_bytes : pw;
12281  spc->h_oversample = 1;
12282  spc->v_oversample = 1;
12283 
12284  nk_rp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
12285  if (pixels)
12286  NK_MEMSET(pixels, 0, (nk_size)(pw*ph)); /* background of 0 around pixels */
12287  return 1;
12288 }
12289 NK_INTERN void
12290 nk_tt_PackEnd(struct nk_tt_pack_context *spc, struct nk_allocator *alloc)
12291 {
12292  alloc->free(alloc->userdata, spc->nodes);
12293  alloc->free(alloc->userdata, spc->pack_info);
12294 }
12295 NK_INTERN void
12296 nk_tt_PackSetOversampling(struct nk_tt_pack_context *spc,
12297  unsigned int h_oversample, unsigned int v_oversample)
12298 {
12299  NK_ASSERT(h_oversample <= NK_TT_MAX_OVERSAMPLE);
12300  NK_ASSERT(v_oversample <= NK_TT_MAX_OVERSAMPLE);
12301  if (h_oversample <= NK_TT_MAX_OVERSAMPLE)
12302  spc->h_oversample = h_oversample;
12303  if (v_oversample <= NK_TT_MAX_OVERSAMPLE)
12304  spc->v_oversample = v_oversample;
12305 }
12306 NK_INTERN void
12307 nk_tt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes,
12308  int kernel_width)
12309 {
12310  unsigned char buffer[NK_TT_MAX_OVERSAMPLE];
12311  int safe_w = w - kernel_width;
12312  int j;
12313 
12314  for (j=0; j < h; ++j)
12315  {
12316  int i;
12317  unsigned int total;
12318  NK_MEMSET(buffer, 0, (nk_size)kernel_width);
12319 
12320  total = 0;
12321 
12322  /* make kernel_width a constant in common cases so compiler can optimize out the divide */
12323  switch (kernel_width) {
12324  case 2:
12325  for (i=0; i <= safe_w; ++i) {
12326  total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12327  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12328  pixels[i] = (unsigned char) (total / 2);
12329  }
12330  break;
12331  case 3:
12332  for (i=0; i <= safe_w; ++i) {
12333  total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12334  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12335  pixels[i] = (unsigned char) (total / 3);
12336  }
12337  break;
12338  case 4:
12339  for (i=0; i <= safe_w; ++i) {
12340  total += (unsigned int)pixels[i] - buffer[i & NK_TT__OVER_MASK];
12341  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12342  pixels[i] = (unsigned char) (total / 4);
12343  }
12344  break;
12345  case 5:
12346  for (i=0; i <= safe_w; ++i) {
12347  total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12348  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12349  pixels[i] = (unsigned char) (total / 5);
12350  }
12351  break;
12352  default:
12353  for (i=0; i <= safe_w; ++i) {
12354  total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12355  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12356  pixels[i] = (unsigned char) (total / (unsigned int)kernel_width);
12357  }
12358  break;
12359  }
12360 
12361  for (; i < w; ++i) {
12362  NK_ASSERT(pixels[i] == 0);
12363  total -= (unsigned int)(buffer[i & NK_TT__OVER_MASK]);
12364  pixels[i] = (unsigned char) (total / (unsigned int)kernel_width);
12365  }
12366  pixels += stride_in_bytes;
12367  }
12368 }
12369 NK_INTERN void
12370 nk_tt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes,
12371  int kernel_width)
12372 {
12373  unsigned char buffer[NK_TT_MAX_OVERSAMPLE];
12374  int safe_h = h - kernel_width;
12375  int j;
12376 
12377  for (j=0; j < w; ++j)
12378  {
12379  int i;
12380  unsigned int total;
12381  NK_MEMSET(buffer, 0, (nk_size)kernel_width);
12382 
12383  total = 0;
12384 
12385  /* make kernel_width a constant in common cases so compiler can optimize out the divide */
12386  switch (kernel_width) {
12387  case 2:
12388  for (i=0; i <= safe_h; ++i) {
12389  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12390  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12391  pixels[i*stride_in_bytes] = (unsigned char) (total / 2);
12392  }
12393  break;
12394  case 3:
12395  for (i=0; i <= safe_h; ++i) {
12396  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12397  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12398  pixels[i*stride_in_bytes] = (unsigned char) (total / 3);
12399  }
12400  break;
12401  case 4:
12402  for (i=0; i <= safe_h; ++i) {
12403  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12404  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12405  pixels[i*stride_in_bytes] = (unsigned char) (total / 4);
12406  }
12407  break;
12408  case 5:
12409  for (i=0; i <= safe_h; ++i) {
12410  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12411  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12412  pixels[i*stride_in_bytes] = (unsigned char) (total / 5);
12413  }
12414  break;
12415  default:
12416  for (i=0; i <= safe_h; ++i) {
12417  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12418  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12419  pixels[i*stride_in_bytes] = (unsigned char) (total / (unsigned int)kernel_width);
12420  }
12421  break;
12422  }
12423 
12424  for (; i < h; ++i) {
12425  NK_ASSERT(pixels[i*stride_in_bytes] == 0);
12426  total -= (unsigned int)(buffer[i & NK_TT__OVER_MASK]);
12427  pixels[i*stride_in_bytes] = (unsigned char) (total / (unsigned int)kernel_width);
12428  }
12429  pixels += 1;
12430  }
12431 }
12432 NK_INTERN float
12433 nk_tt__oversample_shift(int oversample)
12434 {
12435  if (!oversample)
12436  return 0.0f;
12437 
12438  /* The prefilter is a box filter of width "oversample", */
12439  /* which shifts phase by (oversample - 1)/2 pixels in */
12440  /* oversampled space. We want to shift in the opposite */
12441  /* direction to counter this. */
12442  return (float)-(oversample - 1) / (2.0f * (float)oversample);
12443 }
12444 NK_INTERN int
12445 nk_tt_PackFontRangesGatherRects(struct nk_tt_pack_context *spc,
12446  struct nk_tt_fontinfo *info, struct nk_tt_pack_range *ranges,
12447  int num_ranges, struct nk_rp_rect *rects)
12448 {
12449  /* rects array must be big enough to accommodate all characters in the given ranges */
12450  int i,j,k;
12451  k = 0;
12452 
12453  for (i=0; i < num_ranges; ++i) {
12454  float fh = ranges[i].font_size;
12455  float scale = (fh > 0) ? nk_tt_ScaleForPixelHeight(info, fh):
12456  nk_tt_ScaleForMappingEmToPixels(info, -fh);
12457  ranges[i].h_oversample = (unsigned char) spc->h_oversample;
12458  ranges[i].v_oversample = (unsigned char) spc->v_oversample;
12459  for (j=0; j < ranges[i].num_chars; ++j) {
12460  int x0,y0,x1,y1;
12461  int codepoint = ranges[i].first_unicode_codepoint_in_range ?
12462  ranges[i].first_unicode_codepoint_in_range + j :
12463  ranges[i].array_of_unicode_codepoints[j];
12464 
12465  int glyph = nk_tt_FindGlyphIndex(info, codepoint);
12466  nk_tt_GetGlyphBitmapBoxSubpixel(info,glyph, scale * (float)spc->h_oversample,
12467  scale * (float)spc->v_oversample, 0,0, &x0,&y0,&x1,&y1);
12468  rects[k].w = (nk_rp_coord) (x1-x0 + spc->padding + (int)spc->h_oversample-1);
12469  rects[k].h = (nk_rp_coord) (y1-y0 + spc->padding + (int)spc->v_oversample-1);
12470  ++k;
12471  }
12472  }
12473  return k;
12474 }
12475 NK_INTERN int
12476 nk_tt_PackFontRangesRenderIntoRects(struct nk_tt_pack_context *spc,
12477  struct nk_tt_fontinfo *info, struct nk_tt_pack_range *ranges,
12478  int num_ranges, struct nk_rp_rect *rects, struct nk_allocator *alloc)
12479 {
12480  int i,j,k, return_value = 1;
12481  /* save current values */
12482  int old_h_over = (int)spc->h_oversample;
12483  int old_v_over = (int)spc->v_oversample;
12484  /* rects array must be big enough to accommodate all characters in the given ranges */
12485 
12486  k = 0;
12487  for (i=0; i < num_ranges; ++i)
12488  {
12489  float fh = ranges[i].font_size;
12490  float recip_h,recip_v,sub_x,sub_y;
12491  float scale = fh > 0 ? nk_tt_ScaleForPixelHeight(info, fh):
12492  nk_tt_ScaleForMappingEmToPixels(info, -fh);
12493 
12494  spc->h_oversample = ranges[i].h_oversample;
12495  spc->v_oversample = ranges[i].v_oversample;
12496 
12497  recip_h = 1.0f / (float)spc->h_oversample;
12498  recip_v = 1.0f / (float)spc->v_oversample;
12499 
12500  sub_x = nk_tt__oversample_shift((int)spc->h_oversample);
12501  sub_y = nk_tt__oversample_shift((int)spc->v_oversample);
12502 
12503  for (j=0; j < ranges[i].num_chars; ++j)
12504  {
12505  struct nk_rp_rect *r = &rects[k];
12506  if (r->was_packed)
12507  {
12508  struct nk_tt_packedchar *bc = &ranges[i].chardata_for_range[j];
12509  int advance, lsb, x0,y0,x1,y1;
12510  int codepoint = ranges[i].first_unicode_codepoint_in_range ?
12511  ranges[i].first_unicode_codepoint_in_range + j :
12512  ranges[i].array_of_unicode_codepoints[j];
12513  int glyph = nk_tt_FindGlyphIndex(info, codepoint);
12514  nk_rp_coord pad = (nk_rp_coord) spc->padding;
12515 
12516  /* pad on left and top */
12517  r->x = (nk_rp_coord)((int)r->x + (int)pad);
12518  r->y = (nk_rp_coord)((int)r->y + (int)pad);
12519  r->w = (nk_rp_coord)((int)r->w - (int)pad);
12520  r->h = (nk_rp_coord)((int)r->h - (int)pad);
12521 
12522  nk_tt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
12523  nk_tt_GetGlyphBitmapBox(info, glyph, scale * (float)spc->h_oversample,
12524  (scale * (float)spc->v_oversample), &x0,&y0,&x1,&y1);
12525  nk_tt_MakeGlyphBitmapSubpixel(info, spc->pixels + r->x + r->y*spc->stride_in_bytes,
12526  (int)(r->w - spc->h_oversample+1), (int)(r->h - spc->v_oversample+1),
12527  spc->stride_in_bytes, scale * (float)spc->h_oversample,
12528  scale * (float)spc->v_oversample, 0,0, glyph, alloc);
12529 
12530  if (spc->h_oversample > 1)
12531  nk_tt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
12532  r->w, r->h, spc->stride_in_bytes, (int)spc->h_oversample);
12533 
12534  if (spc->v_oversample > 1)
12535  nk_tt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
12536  r->w, r->h, spc->stride_in_bytes, (int)spc->v_oversample);
12537 
12538  bc->x0 = (nk_ushort) r->x;
12539  bc->y0 = (nk_ushort) r->y;
12540  bc->x1 = (nk_ushort) (r->x + r->w);
12541  bc->y1 = (nk_ushort) (r->y + r->h);
12542  bc->xadvance = scale * (float)advance;
12543  bc->xoff = (float) x0 * recip_h + sub_x;
12544  bc->yoff = (float) y0 * recip_v + sub_y;
12545  bc->xoff2 = ((float)x0 + r->w) * recip_h + sub_x;
12546  bc->yoff2 = ((float)y0 + r->h) * recip_v + sub_y;
12547  } else {
12548  return_value = 0; /* if any fail, report failure */
12549  }
12550  ++k;
12551  }
12552  }
12553  /* restore original values */
12554  spc->h_oversample = (unsigned int)old_h_over;
12555  spc->v_oversample = (unsigned int)old_v_over;
12556  return return_value;
12557 }
12558 NK_INTERN void
12559 nk_tt_GetPackedQuad(struct nk_tt_packedchar *chardata, int pw, int ph,
12560  int char_index, float *xpos, float *ypos, struct nk_tt_aligned_quad *q,
12561  int align_to_integer)
12562 {
12563  float ipw = 1.0f / (float)pw, iph = 1.0f / (float)ph;
12564  struct nk_tt_packedchar *b = (struct nk_tt_packedchar*)(chardata + char_index);
12565  if (align_to_integer) {
12566  int tx = nk_ifloorf((*xpos + b->xoff) + 0.5f);
12567  int ty = nk_ifloorf((*ypos + b->yoff) + 0.5f);
12568 
12569  float x = (float)tx;
12570  float y = (float)ty;
12571 
12572  q->x0 = x;
12573  q->y0 = y;
12574  q->x1 = x + b->xoff2 - b->xoff;
12575  q->y1 = y + b->yoff2 - b->yoff;
12576  } else {
12577  q->x0 = *xpos + b->xoff;
12578  q->y0 = *ypos + b->yoff;
12579  q->x1 = *xpos + b->xoff2;
12580  q->y1 = *ypos + b->yoff2;
12581  }
12582  q->s0 = b->x0 * ipw;
12583  q->t0 = b->y0 * iph;
12584  q->s1 = b->x1 * ipw;
12585  q->t1 = b->y1 * iph;
12586  *xpos += b->xadvance;
12587 }
12588 
12589 /* -------------------------------------------------------------
12590  *
12591  * FONT BAKING
12592  *
12593  * --------------------------------------------------------------*/
12594 struct nk_font_bake_data {
12595  struct nk_tt_fontinfo info;
12596  struct nk_rp_rect *rects;
12597  struct nk_tt_pack_range *ranges;
12598  nk_rune range_count;
12599 };
12600 
12601 struct nk_font_baker {
12602  struct nk_allocator alloc;
12603  struct nk_tt_pack_context spc;
12604  struct nk_font_bake_data *build;
12605  struct nk_tt_packedchar *packed_chars;
12606  struct nk_rp_rect *rects;
12607  struct nk_tt_pack_range *ranges;
12608 };
12609 
12610 NK_GLOBAL const nk_size nk_rect_align = NK_ALIGNOF(struct nk_rp_rect);
12611 NK_GLOBAL const nk_size nk_range_align = NK_ALIGNOF(struct nk_tt_pack_range);
12612 NK_GLOBAL const nk_size nk_char_align = NK_ALIGNOF(struct nk_tt_packedchar);
12613 NK_GLOBAL const nk_size nk_build_align = NK_ALIGNOF(struct nk_font_bake_data);
12614 NK_GLOBAL const nk_size nk_baker_align = NK_ALIGNOF(struct nk_font_baker);
12615 
12616 NK_INTERN int
12617 nk_range_count(const nk_rune *range)
12618 {
12619  const nk_rune *iter = range;
12620  NK_ASSERT(range);
12621  if (!range) return 0;
12622  while (*(iter++) != 0);
12623  return (iter == range) ? 0 : (int)((iter - range)/2);
12624 }
12625 NK_INTERN int
12626 nk_range_glyph_count(const nk_rune *range, int count)
12627 {
12628  int i = 0;
12629  int total_glyphs = 0;
12630  for (i = 0; i < count; ++i) {
12631  int diff;
12632  nk_rune f = range[(i*2)+0];
12633  nk_rune t = range[(i*2)+1];
12634  NK_ASSERT(t >= f);
12635  diff = (int)((t - f) + 1);
12636  total_glyphs += diff;
12637  }
12638  return total_glyphs;
12639 }
12640 NK_API const nk_rune*
12641 nk_font_default_glyph_ranges(void)
12642 {
12643  NK_STORAGE const nk_rune ranges[] = {0x0020, 0x00FF, 0};
12644  return ranges;
12645 }
12646 NK_API const nk_rune*
12647 nk_font_chinese_glyph_ranges(void)
12648 {
12649  NK_STORAGE const nk_rune ranges[] = {
12650  0x0020, 0x00FF,
12651  0x3000, 0x30FF,
12652  0x31F0, 0x31FF,
12653  0xFF00, 0xFFEF,
12654  0x4e00, 0x9FAF,
12655  0
12656  };
12657  return ranges;
12658 }
12659 NK_API const nk_rune*
12660 nk_font_cyrillic_glyph_ranges(void)
12661 {
12662  NK_STORAGE const nk_rune ranges[] = {
12663  0x0020, 0x00FF,
12664  0x0400, 0x052F,
12665  0x2DE0, 0x2DFF,
12666  0xA640, 0xA69F,
12667  0
12668  };
12669  return ranges;
12670 }
12671 NK_API const nk_rune*
12672 nk_font_korean_glyph_ranges(void)
12673 {
12674  NK_STORAGE const nk_rune ranges[] = {
12675  0x0020, 0x00FF,
12676  0x3131, 0x3163,
12677  0xAC00, 0xD79D,
12678  0
12679  };
12680  return ranges;
12681 }
12682 NK_INTERN void
12683 nk_font_baker_memory(nk_size *temp, int *glyph_count,
12684  struct nk_font_config *config_list, int count)
12685 {
12686  int range_count = 0;
12687  int total_range_count = 0;
12688  struct nk_font_config *iter, *i;
12689 
12690  NK_ASSERT(config_list);
12691  NK_ASSERT(glyph_count);
12692  if (!config_list) {
12693  *temp = 0;
12694  *glyph_count = 0;
12695  return;
12696  }
12697  *glyph_count = 0;
12698  for (iter = config_list; iter; iter = iter->next) {
12699  i = iter;
12700  do {if (!i->range) iter->range = nk_font_default_glyph_ranges();
12701  range_count = nk_range_count(i->range);
12702  total_range_count += range_count;
12703  *glyph_count += nk_range_glyph_count(i->range, range_count);
12704  } while ((i = i->n) != iter);
12705  }
12706  *temp = (nk_size)*glyph_count * sizeof(struct nk_rp_rect);
12707  *temp += (nk_size)total_range_count * sizeof(struct nk_tt_pack_range);
12708  *temp += (nk_size)*glyph_count * sizeof(struct nk_tt_packedchar);
12709  *temp += (nk_size)count * sizeof(struct nk_font_bake_data);
12710  *temp += sizeof(struct nk_font_baker);
12711  *temp += nk_rect_align + nk_range_align + nk_char_align;
12712  *temp += nk_build_align + nk_baker_align;
12713 }
12714 NK_INTERN struct nk_font_baker*
12715 nk_font_baker(void *memory, int glyph_count, int count, struct nk_allocator *alloc)
12716 {
12717  struct nk_font_baker *baker;
12718  if (!memory) return 0;
12719  /* setup baker inside a memory block */
12720  baker = (struct nk_font_baker*)NK_ALIGN_PTR(memory, nk_baker_align);
12721  baker->build = (struct nk_font_bake_data*)NK_ALIGN_PTR((baker + 1), nk_build_align);
12722  baker->packed_chars = (struct nk_tt_packedchar*)NK_ALIGN_PTR((baker->build + count), nk_char_align);
12723  baker->rects = (struct nk_rp_rect*)NK_ALIGN_PTR((baker->packed_chars + glyph_count), nk_rect_align);
12724  baker->ranges = (struct nk_tt_pack_range*)NK_ALIGN_PTR((baker->rects + glyph_count), nk_range_align);
12725  baker->alloc = *alloc;
12726  return baker;
12727 }
12728 NK_INTERN int
12729 nk_font_bake_pack(struct nk_font_baker *baker,
12730  nk_size *image_memory, int *width, int *height, struct nk_recti *custom,
12731  const struct nk_font_config *config_list, int count,
12732  struct nk_allocator *alloc)
12733 {
12734  NK_STORAGE const nk_size max_height = 1024 * 32;
12735  const struct nk_font_config *config_iter, *it;
12736  int total_glyph_count = 0;
12737  int total_range_count = 0;
12738  int range_count = 0;
12739  int i = 0;
12740 
12741  NK_ASSERT(image_memory);
12742  NK_ASSERT(width);
12743  NK_ASSERT(height);
12744  NK_ASSERT(config_list);
12745  NK_ASSERT(count);
12746  NK_ASSERT(alloc);
12747 
12748  if (!image_memory || !width || !height || !config_list || !count) return nk_false;
12749  for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
12750  it = config_iter;
12751  do {range_count = nk_range_count(it->range);
12752  total_range_count += range_count;
12753  total_glyph_count += nk_range_glyph_count(it->range, range_count);
12754  } while ((it = it->n) != config_iter);
12755  }
12756  /* setup font baker from temporary memory */
12757  for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
12758  it = config_iter;
12759  do {if (!nk_tt_InitFont(&baker->build[i++].info, (const unsigned char*)it->ttf_blob, 0))
12760  return nk_false;
12761  } while ((it = it->n) != config_iter);
12762  }
12763  *height = 0;
12764  *width = (total_glyph_count > 1000) ? 1024 : 512;
12765  nk_tt_PackBegin(&baker->spc, 0, (int)*width, (int)max_height, 0, 1, alloc);
12766  {
12767  int input_i = 0;
12768  int range_n = 0;
12769  int rect_n = 0;
12770  int char_n = 0;
12771 
12772  if (custom) {
12773  /* pack custom user data first so it will be in the upper left corner*/
12774  struct nk_rp_rect custom_space;
12775  nk_zero(&custom_space, sizeof(custom_space));
12776  custom_space.w = (nk_rp_coord)(custom->w);
12777  custom_space.h = (nk_rp_coord)(custom->h);
12778 
12779  nk_tt_PackSetOversampling(&baker->spc, 1, 1);
12780  nk_rp_pack_rects((struct nk_rp_context*)baker->spc.pack_info, &custom_space, 1);
12781  *height = NK_MAX(*height, (int)(custom_space.y + custom_space.h));
12782 
12783  custom->x = (short)custom_space.x;
12784  custom->y = (short)custom_space.y;
12785  custom->w = (short)custom_space.w;
12786  custom->h = (short)custom_space.h;
12787  }
12788 
12789  /* first font pass: pack all glyphs */
12790  for (input_i = 0, config_iter = config_list; input_i < count && config_iter;
12791  config_iter = config_iter->next) {
12792  it = config_iter;
12793  do {int n = 0;
12794  int glyph_count;
12795  const nk_rune *in_range;
12796  const struct nk_font_config *cfg = it;
12797  struct nk_font_bake_data *tmp = &baker->build[input_i++];
12798 
12799  /* count glyphs + ranges in current font */
12800  glyph_count = 0; range_count = 0;
12801  for (in_range = cfg->range; in_range[0] && in_range[1]; in_range += 2) {
12802  glyph_count += (int)(in_range[1] - in_range[0]) + 1;
12803  range_count++;
12804  }
12805 
12806  /* setup ranges */
12807  tmp->ranges = baker->ranges + range_n;
12808  tmp->range_count = (nk_rune)range_count;
12809  range_n += range_count;
12810  for (i = 0; i < range_count; ++i) {
12811  in_range = &cfg->range[i * 2];
12812  tmp->ranges[i].font_size = cfg->size;
12813  tmp->ranges[i].first_unicode_codepoint_in_range = (int)in_range[0];
12814  tmp->ranges[i].num_chars = (int)(in_range[1]- in_range[0]) + 1;
12815  tmp->ranges[i].chardata_for_range = baker->packed_chars + char_n;
12816  char_n += tmp->ranges[i].num_chars;
12817  }
12818 
12819  /* pack */
12820  tmp->rects = baker->rects + rect_n;
12821  rect_n += glyph_count;
12822  nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
12823  n = nk_tt_PackFontRangesGatherRects(&baker->spc, &tmp->info,
12824  tmp->ranges, (int)tmp->range_count, tmp->rects);
12825  nk_rp_pack_rects((struct nk_rp_context*)baker->spc.pack_info, tmp->rects, (int)n);
12826 
12827  /* texture height */
12828  for (i = 0; i < n; ++i) {
12829  if (tmp->rects[i].was_packed)
12830  *height = NK_MAX(*height, tmp->rects[i].y + tmp->rects[i].h);
12831  }
12832  } while ((it = it->n) != config_iter);
12833  }
12834  NK_ASSERT(rect_n == total_glyph_count);
12835  NK_ASSERT(char_n == total_glyph_count);
12836  NK_ASSERT(range_n == total_range_count);
12837  }
12838  *height = (int)nk_round_up_pow2((nk_uint)*height);
12839  *image_memory = (nk_size)(*width) * (nk_size)(*height);
12840  return nk_true;
12841 }
12842 NK_INTERN void
12843 nk_font_bake(struct nk_font_baker *baker, void *image_memory, int width, int height,
12844  struct nk_font_glyph *glyphs, int glyphs_count,
12845  const struct nk_font_config *config_list, int font_count)
12846 {
12847  int input_i = 0;
12848  nk_rune glyph_n = 0;
12849  const struct nk_font_config *config_iter;
12850  const struct nk_font_config *it;
12851 
12852  NK_ASSERT(image_memory);
12853  NK_ASSERT(width);
12854  NK_ASSERT(height);
12855  NK_ASSERT(config_list);
12856  NK_ASSERT(baker);
12857  NK_ASSERT(font_count);
12858  NK_ASSERT(glyphs_count);
12859  if (!image_memory || !width || !height || !config_list ||
12860  !font_count || !glyphs || !glyphs_count)
12861  return;
12862 
12863  /* second font pass: render glyphs */
12864  nk_zero(image_memory, (nk_size)((nk_size)width * (nk_size)height));
12865  baker->spc.pixels = (unsigned char*)image_memory;
12866  baker->spc.height = (int)height;
12867  for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
12868  config_iter = config_iter->next) {
12869  it = config_iter;
12870  do {const struct nk_font_config *cfg = it;
12871  struct nk_font_bake_data *tmp = &baker->build[input_i++];
12872  nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
12873  nk_tt_PackFontRangesRenderIntoRects(&baker->spc, &tmp->info, tmp->ranges,
12874  (int)tmp->range_count, tmp->rects, &baker->alloc);
12875  } while ((it = it->n) != config_iter);
12876  } nk_tt_PackEnd(&baker->spc, &baker->alloc);
12877 
12878  /* third pass: setup font and glyphs */
12879  for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
12880  config_iter = config_iter->next) {
12881  it = config_iter;
12882  do {nk_size i = 0;
12883  int char_idx = 0;
12884  nk_rune glyph_count = 0;
12885  const struct nk_font_config *cfg = it;
12886  struct nk_font_bake_data *tmp = &baker->build[input_i++];
12887  struct nk_baked_font *dst_font = cfg->font;
12888 
12889  float font_scale = nk_tt_ScaleForPixelHeight(&tmp->info, cfg->size);
12890  int unscaled_ascent, unscaled_descent, unscaled_line_gap;
12891  nk_tt_GetFontVMetrics(&tmp->info, &unscaled_ascent, &unscaled_descent,
12892  &unscaled_line_gap);
12893 
12894  /* fill baked font */
12895  if (!cfg->merge_mode) {
12896  dst_font->ranges = cfg->range;
12897  dst_font->height = cfg->size;
12898  dst_font->ascent = ((float)unscaled_ascent * font_scale);
12899  dst_font->descent = ((float)unscaled_descent * font_scale);
12900  dst_font->glyph_offset = glyph_n;
12901  // Need to zero this, or it will carry over from a previous
12902  // bake, and cause a segfault when accessing glyphs[].
12903  dst_font->glyph_count = 0;
12904  }
12905 
12906  /* fill own baked font glyph array */
12907  for (i = 0; i < tmp->range_count; ++i) {
12908  struct nk_tt_pack_range *range = &tmp->ranges[i];
12909  for (char_idx = 0; char_idx < range->num_chars; char_idx++)
12910  {
12911  nk_rune codepoint = 0;
12912  float dummy_x = 0, dummy_y = 0;
12913  struct nk_tt_aligned_quad q;
12914  struct nk_font_glyph *glyph;
12915 
12916  /* query glyph bounds from stb_truetype */
12917  const struct nk_tt_packedchar *pc = &range->chardata_for_range[char_idx];
12918  if (!pc->x0 && !pc->x1 && !pc->y0 && !pc->y1) continue;
12919  codepoint = (nk_rune)(range->first_unicode_codepoint_in_range + char_idx);
12920  nk_tt_GetPackedQuad(range->chardata_for_range, (int)width,
12921  (int)height, char_idx, &dummy_x, &dummy_y, &q, 0);
12922 
12923  /* fill own glyph type with data */
12924  glyph = &glyphs[dst_font->glyph_offset + dst_font->glyph_count + (unsigned int)glyph_count];
12925  glyph->codepoint = codepoint;
12926  glyph->x0 = q.x0; glyph->y0 = q.y0;
12927  glyph->x1 = q.x1; glyph->y1 = q.y1;
12928  glyph->y0 += (dst_font->ascent + 0.5f);
12929  glyph->y1 += (dst_font->ascent + 0.5f);
12930  glyph->w = glyph->x1 - glyph->x0 + 0.5f;
12931  glyph->h = glyph->y1 - glyph->y0;
12932 
12933  if (cfg->coord_type == NK_COORD_PIXEL) {
12934  glyph->u0 = q.s0 * (float)width;
12935  glyph->v0 = q.t0 * (float)height;
12936  glyph->u1 = q.s1 * (float)width;
12937  glyph->v1 = q.t1 * (float)height;
12938  } else {
12939  glyph->u0 = q.s0;
12940  glyph->v0 = q.t0;
12941  glyph->u1 = q.s1;
12942  glyph->v1 = q.t1;
12943  }
12944  glyph->xadvance = (pc->xadvance + cfg->spacing.x);
12945  if (cfg->pixel_snap)
12946  glyph->xadvance = (float)(int)(glyph->xadvance + 0.5f);
12947  glyph_count++;
12948  }
12949  }
12950  dst_font->glyph_count += glyph_count;
12951  glyph_n += glyph_count;
12952  } while ((it = it->n) != config_iter);
12953  }
12954 }
12955 NK_INTERN void
12956 nk_font_bake_custom_data(void *img_memory, int img_width, int img_height,
12957  struct nk_recti img_dst, const char *texture_data_mask, int tex_width,
12958  int tex_height, char white, char black)
12959 {
12960  nk_byte *pixels;
12961  int y = 0;
12962  int x = 0;
12963  int n = 0;
12964 
12965  NK_ASSERT(img_memory);
12966  NK_ASSERT(img_width);
12967  NK_ASSERT(img_height);
12968  NK_ASSERT(texture_data_mask);
12969  NK_UNUSED(tex_height);
12970  if (!img_memory || !img_width || !img_height || !texture_data_mask)
12971  return;
12972 
12973  pixels = (nk_byte*)img_memory;
12974  for (y = 0, n = 0; y < tex_height; ++y) {
12975  for (x = 0; x < tex_width; ++x, ++n) {
12976  const int off0 = ((img_dst.x + x) + (img_dst.y + y) * img_width);
12977  const int off1 = off0 + 1 + tex_width;
12978  pixels[off0] = (texture_data_mask[n] == white) ? 0xFF : 0x00;
12979  pixels[off1] = (texture_data_mask[n] == black) ? 0xFF : 0x00;
12980  }
12981  }
12982 }
12983 NK_INTERN void
12984 nk_font_bake_convert(void *out_memory, int img_width, int img_height,
12985  const void *in_memory)
12986 {
12987  int n = 0;
12988  nk_rune *dst;
12989  const nk_byte *src;
12990 
12991  NK_ASSERT(out_memory);
12992  NK_ASSERT(in_memory);
12993  NK_ASSERT(img_width);
12994  NK_ASSERT(img_height);
12995  if (!out_memory || !in_memory || !img_height || !img_width) return;
12996 
12997  dst = (nk_rune*)out_memory;
12998  src = (const nk_byte*)in_memory;
12999  for (n = (int)(img_width * img_height); n > 0; n--)
13000  *dst++ = ((nk_rune)(*src++) << 24) | 0x00FFFFFF;
13001 }
13002 
13003 /* -------------------------------------------------------------
13004  *
13005  * FONT
13006  *
13007  * --------------------------------------------------------------*/
13008 NK_INTERN float
13009 nk_font_text_width(nk_handle handle, float height, const char *text, int len)
13010 {
13011  nk_rune unicode;
13012  int text_len = 0;
13013  float text_width = 0;
13014  int glyph_len = 0;
13015  float scale = 0;
13016 
13017  struct nk_font *font = (struct nk_font*)handle.ptr;
13018  NK_ASSERT(font);
13019  NK_ASSERT(font->glyphs);
13020  if (!font || !text || !len)
13021  return 0;
13022 
13023  scale = height/font->info.height;
13024  glyph_len = text_len = nk_utf_decode(text, &unicode, (int)len);
13025  if (!glyph_len) return 0;
13026  while (text_len <= (int)len && glyph_len) {
13027  const struct nk_font_glyph *g;
13028  if (unicode == NK_UTF_INVALID) break;
13029 
13030  /* query currently drawn glyph information */
13031  g = nk_font_find_glyph(font, unicode);
13032  text_width += g->xadvance * scale;
13033 
13034  /* offset next glyph */
13035  glyph_len = nk_utf_decode(text + text_len, &unicode, (int)len - text_len);
13036  text_len += glyph_len;
13037  }
13038  return text_width;
13039 }
13040 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
13041 NK_INTERN void
13042 nk_font_query_font_glyph(nk_handle handle, float height,
13043  struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
13044 {
13045  float scale;
13046  const struct nk_font_glyph *g;
13047  struct nk_font *font;
13048 
13049  NK_ASSERT(glyph);
13050  NK_UNUSED(next_codepoint);
13051 
13052  font = (struct nk_font*)handle.ptr;
13053  NK_ASSERT(font);
13054  NK_ASSERT(font->glyphs);
13055  if (!font || !glyph)
13056  return;
13057 
13058  scale = height/font->info.height;
13059  g = nk_font_find_glyph(font, codepoint);
13060  glyph->width = (g->x1 - g->x0) * scale;
13061  glyph->height = (g->y1 - g->y0) * scale;
13062  glyph->offset = nk_vec2(g->x0 * scale, g->y0 * scale);
13063  glyph->xadvance = (g->xadvance * scale);
13064  glyph->uv[0] = nk_vec2(g->u0, g->v0);
13065  glyph->uv[1] = nk_vec2(g->u1, g->v1);
13066 }
13067 #endif
13068 NK_API const struct nk_font_glyph*
13069 nk_font_find_glyph(struct nk_font *font, nk_rune unicode)
13070 {
13071  int i = 0;
13072  int count;
13073  int total_glyphs = 0;
13074  const struct nk_font_glyph *glyph = 0;
13075  const struct nk_font_config *iter = 0;
13076 
13077  NK_ASSERT(font);
13078  NK_ASSERT(font->glyphs);
13079  NK_ASSERT(font->info.ranges);
13080  if (!font || !font->glyphs) return 0;
13081 
13082  glyph = font->fallback;
13083  iter = font->config;
13084  do {count = nk_range_count(iter->range);
13085  for (i = 0; i < count; ++i) {
13086  nk_rune f = iter->range[(i*2)+0];
13087  nk_rune t = iter->range[(i*2)+1];
13088  int diff = (int)((t - f) + 1);
13089  if (unicode >= f && unicode <= t)
13090  return &font->glyphs[((nk_rune)total_glyphs + (unicode - f))];
13091  total_glyphs += diff;
13092  }
13093  } while ((iter = iter->n) != font->config);
13094  return glyph;
13095 }
13096 NK_INTERN void
13097 nk_font_init(struct nk_font *font, float pixel_height,
13098  nk_rune fallback_codepoint, struct nk_font_glyph *glyphs,
13099  const struct nk_baked_font *baked_font, nk_handle atlas)
13100 {
13101  struct nk_baked_font baked;
13102  NK_ASSERT(font);
13103  NK_ASSERT(glyphs);
13104  NK_ASSERT(baked_font);
13105  if (!font || !glyphs || !baked_font)
13106  return;
13107 
13108  baked = *baked_font;
13109  font->fallback = 0;
13110  font->info = baked;
13111  font->scale = (float)pixel_height / (float)font->info.height;
13112  font->glyphs = &glyphs[baked_font->glyph_offset];
13113  font->texture = atlas;
13114  font->fallback_codepoint = fallback_codepoint;
13115  font->fallback = nk_font_find_glyph(font, fallback_codepoint);
13116 
13117  font->handle.height = font->info.height * font->scale;
13118  font->handle.width = nk_font_text_width;
13119  font->handle.userdata.ptr = font;
13120 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
13121  font->handle.query = nk_font_query_font_glyph;
13122  font->handle.texture = font->texture;
13123 #endif
13124 }
13125 
13126 /* ---------------------------------------------------------------------------
13127  *
13128  * DEFAULT FONT
13129  *
13130  * ProggyClean.ttf
13131  * Copyright (c) 2004, 2005 Tristan Grimmer
13132  * MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip)
13133  * Download and more information at http://upperbounds.net
13134  *-----------------------------------------------------------------------------*/
13135 #ifdef __clang__
13136 #pragma clang diagnostic push
13137 #pragma clang diagnostic ignored "-Woverlength-strings"
13138 #elif defined(__GNUC__) || defined(__GNUG__)
13139 #pragma GCC diagnostic push
13140 #pragma GCC diagnostic ignored "-Woverlength-strings"
13141 #endif
13142 
13143 #ifdef NK_INCLUDE_DEFAULT_FONT
13144 
13145 NK_GLOBAL const char nk_proggy_clean_ttf_compressed_data_base85[11980+1] =
13146  "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/"
13147  "2*>]b(MC;$jPfY.;h^`IWM9<Lh2TlS+f-s$o6Q<BWH`YiU.xfLq$N;$0iR/GX:U(jcW2p/W*q?-qmnUCI;jHSAiFWM.R*kU@C=GH?a9wp8f$e.-4^Qg1)Q-GL(lf(r/7GrRgwV%MS=C#"
13148  "`8ND>Qo#t'X#(v#Y9w0#1D$CIf;W'#pWUPXOuxXuU(H9M(1<q-UE31#^-V'8IRUo7Qf./L>=Ke$$'5F%)]0^#0X@U.a<r:QLtFsLcL6##lOj)#.Y5<-R&KgLwqJfLgN&;Q?gI^#DY2uL"
13149  "i@^rMl9t=cWq6##weg>$FBjVQTSDgEKnIS7EM9>ZY9w0#L;>>#Mx&4Mvt//L[MkA#W@lK.N'[0#7RL_&#w+F%HtG9M#XL`N&.,GM4Pg;-<nLENhvx>-VsM.M0rJfLH2eTM`*oJMHRC`N"
13150  "kfimM2J,W-jXS:)r0wK#@Fge$U>`w'N7G#$#fB#$E^$#:9:hk+eOe--6x)F7*E%?76%^GMHePW-Z5l'&GiF#$956:rS?dA#fiK:)Yr+`&#0j@'DbG&#^$PG.Ll+DNa<XCMKEV*N)LN/N"
13151  "*b=%Q6pia-Xg8I$<MR&,VdJe$<(7G;Ckl'&hF;;$<_=X(b.RS%%)###MPBuuE1V:v&cX&#2m#(&cV]`k9OhLMbn%s$G2,B$BfD3X*sp5#l,$R#]x_X1xKX%b5U*[r5iMfUo9U`N99hG)"
13152  "tm+/Us9pG)XPu`<0s-)WTt(gCRxIg(%6sfh=ktMKn3j)<6<b5Sk_/0(^]AaN#(p/L>&VZ>1i%h1S9u5o@YaaW$e+b<TWFn/Z:Oh(Cx2$lNEoN^e)#CFY@@I;BOQ*sRwZtZxRcU7uW6CX"
13153  "ow0i(?$Q[cjOd[P4d)]>ROPOpxTO7Stwi1::iB1q)C_=dV26J;2,]7op$]uQr@_V7$q^%lQwtuHY]=DX,n3L#0PHDO4f9>dC@O>HBuKPpP*E,N+b3L#lpR/MrTEH.IAQk.a>D[.e;mc."
13154  "x]Ip.PH^'/aqUO/$1WxLoW0[iLA<QT;5HKD+@qQ'NQ(3_PLhE48R.qAPSwQ0/WK?Z,[x?-J;jQTWA0X@KJ(_Y8N-:/M74:/-ZpKrUss?d#dZq]DAbkU*JqkL+nwX@@47`5>w=4h(9.`G"
13155  "CRUxHPeR`5Mjol(dUWxZa(>STrPkrJiWx`5U7F#.g*jrohGg`cg:lSTvEY/EV_7H4Q9[Z%cnv;JQYZ5q.l7Zeas:HOIZOB?G<Nald$qs]@]L<J7bR*>gv:[7MI2k).'2($5FNP&EQ(,)"
13156  "U]W]+fh18.vsai00);D3@4ku5P?DP8aJt+;qUM]=+b'8@;mViBKx0DE[-auGl8:PJ&Dj+M6OC]O^((##]`0i)drT;-7X`=-H3[igUnPG-NZlo.#k@h#=Ork$m>a>$-?Tm$UV(?#P6YY#"
13157  "'/###xe7q.73rI3*pP/$1>s9)W,JrM7SN]'/4C#v$U`0#V.[0>xQsH$fEmPMgY2u7Kh(G%siIfLSoS+MK2eTM$=5,M8p`A.;_R%#u[K#$x4AG8.kK/HSB==-'Ie/QTtG?-.*^N-4B/ZM"
13158  "_3YlQC7(p7q)&](`6_c)$/*JL(L-^(]$wIM`dPtOdGA,U3:w2M-0<q-]L_?^)1vw'.,MRsqVr.L;aN&#/EgJ)PBc[-f>+WomX2u7lqM2iEumMTcsF?-aT=Z-97UEnXglEn1K-bnEO`gu"
13159  "Ft(c%=;Am_Qs@jLooI&NX;]0#j4#F14;gl8-GQpgwhrq8'=l_f-b49'UOqkLu7-##oDY2L(te+Mch&gLYtJ,MEtJfLh'x'M=$CS-ZZ%P]8bZ>#S?YY#%Q&q'3^Fw&?D)UDNrocM3A76/"
13160  "/oL?#h7gl85[qW/NDOk%16ij;+:1a'iNIdb-ou8.P*w,v5#EI$TWS>Pot-R*H'-SEpA:g)f+O$%%`kA#G=8RMmG1&O`>to8bC]T&$,n.LoO>29sp3dt-52U%VM#q7'DHpg+#Z9%H[K<L"
13161  "%a2E-grWVM3@2=-k22tL]4$##6We'8UJCKE[d_=%wI;'6X-GsLX4j^SgJ$##R*w,vP3wK#iiW&#*h^D&R?jp7+/u&#(AP##XU8c$fSYW-J95_-Dp[g9wcO&#M-h1OcJlc-*vpw0xUX&#"
13162  "OQFKNX@QI'IoPp7nb,QU//MQ&ZDkKP)X<WSVL(68uVl&#c'[0#(s1X&xm$Y%B7*K:eDA323j998GXbA#pwMs-jgD$9QISB-A_(aN4xoFM^@C58D0+Q+q3n0#3U1InDjF682-SjMXJK)("
13163  "h$hxua_K]ul92%'BOU&#BRRh-slg8KDlr:%L71Ka:.A;%YULjDPmL<LYs8i#XwJOYaKPKc1h:'9Ke,g)b),78=I39B;xiY$bgGw-&.Zi9InXDuYa%G*f2Bq7mn9^#p1vv%#(Wi-;/Z5h"
13164  "o;#2:;%d&#x9v68C5g?ntX0X)pT`;%pB3q7mgGN)3%(P8nTd5L7GeA-GL@+%J3u2:(Yf>et`e;)f#Km8&+DC$I46>#Kr]]u-[=99tts1.qb#q72g1WJO81q+eN'03'eM>&1XxY-caEnO"
13165  "j%2n8)),?ILR5^.Ibn<-X-Mq7[a82Lq:F&#ce+S9wsCK*x`569E8ew'He]h:sI[2LM$[guka3ZRd6:t%IG:;$%YiJ:Nq=?eAw;/:nnDq0(CYcMpG)qLN4$##&J<j$UpK<Q4a1]MupW^-"
13166  "sj_$%[HK%'F####QRZJ::Y3EGl4'@%FkiAOg#p[##O`gukTfBHagL<LHw%q&OV0##F=6/:chIm0@eCP8X]:kFI%hl8hgO@RcBhS-@Qb$%+m=hPDLg*%K8ln(wcf3/'DW-$.lR?n[nCH-"
13167  "eXOONTJlh:.RYF%3'p6sq:UIMA945&^HFS87@$EP2iG<-lCO$%c`uKGD3rC$x0BL8aFn--`ke%#HMP'vh1/R&O_J9'um,.<tx[@%wsJk&bUT2`0uMv7gg#qp/ij.L56'hl;.s5CUrxjO"
13168  "M7-##.l+Au'A&O:-T72L]P`&=;ctp'XScX*rU.>-XTt,%OVU4)S1+R-#dg0/Nn?Ku1^0f$B*P:Rowwm-`0PKjYDDM'3]d39VZHEl4,.j']Pk-M.h^&:0FACm$maq-&sgw0t7/6(^xtk%"
13169  "LuH88Fj-ekm>GA#_>568x6(OFRl-IZp`&b,_P'$M<Jnq79VsJW/mWS*PUiq76;]/NM_>hLbxfc$mj`,O;&%W2m`Zh:/)Uetw:aJ%]K9h:TcF]u_-Sj9,VK3M.*'&0D[Ca]J9gp8,kAW]"
13170  "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et"
13171  "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$<M-SGZ':+Q_k+uvOSLiEo(<aD/K<CCc`'Lx>'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:"
13172  "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@F%q7c#4XAXN-U&VB<HFF*qL("
13173  "$/V,;(kXZejWO`<[5?\?ewY(*9=%wDc;,u<'9t3W-(H1th3+G]ucQ]kLs7df($/*JL]@*t7Bu_G3_7mp7<iaQjO@.kLg;x3B0lqp7Hf,^Ze7-##@/c58Mo(3;knp0%)A7?-W+eI'o8)b<"
13174  "nKnw'Ho8C=Y>pqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<<aG/1N$#FX$0V5Y6x'aErI3I$7x%E`v<-BY,)%-?Psf*l?%C3.mM(=/M0:JxG'?"
13175  "7WhH%o'a<-80g0NBxoO(GH<dM]n.+%q@jH?f.UsJ2Ggs&4<-e47&Kl+f//9@`b+?.TeN_&B8Ss?v;^Trk;f#YvJkl&w$]>-+k?'(<S:68tq*WoDfZu';mM?8X[ma8W%*`-=;D.(nc7/;"
13176  ")g:T1=^J$&BRV(-lTmNB6xqB[@0*o.erM*<SWF]u2=st-*(6v>^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-KMQ%rP/Xri.LRcB##=YL3BgM/3M"
13177  "D?@f&1'BW-)Ju<L25gl8uhVm1hL$##*8###'A3/LkKW+(^rWX?5W_8g)a(m&K8P>#bmmWCMkk&#TR`C,5d>g)F;t,4:@_l8G/5h4vUd%&%950:VXD'QdWoY-F$BtUwmfe$YqL'8(PWX("
13178  "P?^@Po3$##`MSs?DWBZ/S>+4%>fX,VWv/w'KD`LP5IbH;rTV>n3cEK8U#bX]l-/V+^lj3;vlMb&[5YQ8#pekX9JP3XUC72L,,?+Ni&co7ApnO*5NK,((W-i:$,kp'UDAO(G0Sq7MVjJs"
13179  "bIu)'Z,*[>br5fX^:FPAWr-m2KgL<LUN098kTF&#lvo58=/vjDo;.;)Ka*hLR#/k=rKbxuV`>Q_nN6'8uTG&#1T5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q"
13180  "h4CB/5OvmA&,Q&QbUoi$a_%3M01H)4x7I^&KQVgtFnV+;[Pc>[m4k//,]1?#`VY[Jr*3&&slRfLiVZJ:]?=K3Sw=[$=uRB?3xk48@aeg<Z'<$#4H)6,>e0jT6'N#(q%.O=?2S]u*(m<-"
13181  "V8J'(1)G][68hW$5'q[GC&5j`TE?m'esFGNRM)j,ffZ?-qx8;->g4t*:CIP/[Qap7/9'#(1sao7w-.qNUdkJ)tCF&#B^;xGvn2r9FEPFFFcL@.iFNkTve$m%#QvQS8U@)2Z+3K:AKM5i"
13182  "sZ88+dKQ)W6>J%CL<KE>`.d*(B`-n8D9oK<Up]c$X$(,)M8Zt7/[rdkqTgl-0cuGMv'?>-XV1q['-5k'cAZ69e;D_?$ZPP&s^+7])$*$#@QYi9,5P&#9r+$%CE=68>K8r0=dSC%%(@p7"
13183  ".m7jilQ02'0-VWAg<a/''3u.=4L$Y)6k/K:_[3=&jvL<L0C/2'v:^;-DIBW,B4E68:kZ;%?8(Q8BH=kO65BW?xSG&#@uU,DS*,?.+(o(#1vCS8#CHF>TlGW'b)Tq7VT9q^*^$$.:&N@@"
13184  "$&)WHtPm*5_rO0&e%K&#-30j(E4#'Zb.o/(Tpm$>K'f@[PvFl,hfINTNU6u'0pao7%XUp9]5.>%h`8_=VYbxuel.NTSsJfLacFu3B'lQSu/m6-Oqem8T+oE--$0a/k]uj9EwsG>%veR*"
13185  "hv^BFpQj:K'#SJ,sB-'#](j.Lg92rTw-*n%@/;39rrJF,l#qV%OrtBeC6/,;qB3ebNW[?,Hqj2L.1NP&GjUR=1D8QaS3Up&@*9wP?+lo7b?@%'k4`p0Z$22%K3+iCZj?XJN4Nm&+YF]u"
13186  "@-W$U%VEQ/,,>>#)D<h#`)h0:<Q6909ua+&VU%n2:cG3FJ-%@Bj-DgLr`Hw&HAKjKjseK</xKT*)B,N9X3]krc12t'pgTV(Lv-tL[xg_%=M_q7a^x?7Ubd>#%8cY#YZ?=,`Wdxu/ae&#"
13187  "w6)R89tI#6@s'(6Bf7a&?S=^ZI_kS&ai`&=tE72L_D,;^R)7[$s<Eh#c&)q.MXI%#v9ROa5FZO%sF7q7Nwb&#ptUJ:aqJe$Sl68%.D###EC><?-aF&#RNQv>o8lKN%5/$(vdfq7+ebA#"
13188  "u1p]ovUKW&Y%q]'>$1@-[xfn$7ZTp7mM,G,Ko7a&Gu%G[RMxJs[0MM%wci.LFDK)(<c`Q8N)jEIF*+?P2a8g%)$q]o2aH8C&<SibC/q,(e:v;-b#6[$NtDZ84Je2KNvB#$P5?tQ3nt(0"
13189  "d=j.LQf./Ll33+(;q3L-w=8dX$#WF&uIJ@-bfI>%:_i2B5CsR8&9Z&#=mPEnm0f`<&c)QL5uJ#%u%lJj+D-r;BoF&#4DoS97h5g)E#o:&S4weDF,9^Hoe`h*L+_a*NrLW-1pG_&2UdB8"
13190  "6e%B/:=>)N4xeW.*wft-;$'58-ESqr<b?UI(_%@[P46>#U`'6AQ]m&6/`Z>#S?YY#Vc;r7U2&326d=w&H####?TZ`*4?&.MK?LP8Vxg>$[QXc%QJv92.(Db*B)gb*BM9dM*hJMAo*c&#"
13191  "b0v=Pjer]$gG&JXDf->'StvU7505l9$AFvgYRI^&<^b68?j#q9QX4SM'RO#&sL1IM.rJfLUAj221]d##DW=m83u5;'bYx,*Sl0hL(W;;$doB&O/TQ:(Z^xBdLjL<Lni;''X.`$#8+1GD"
13192  ":k$YUWsbn8ogh6rxZ2Z9]%nd+>V#*8U_72Lh+2Q8Cj0i:6hp&$C/:p(HK>T8Y[gHQ4`4)'$Ab(Nof%V'8hL&#<NEdtg(n'=S1A(Q1/I&4([%dM`,Iu'1:_hL>SfD07&6D<fp8dHM7/g+"
13193  "tlPN9J*rKaPct&?'uBCem^jn%9_K)<,C5K3s=5g&GmJb*[SYq7K;TRLGCsM-$$;S%:Y@r7AK0pprpL<Lrh,q7e/%KWK:50I^+m'vi`3?%Zp+<-d+$L-Sv:@.o19n$s0&39;kn;S%BSq*"
13194  "$3WoJSCLweV[aZ'MQIjO<7;X-X;&+dMLvu#^UsGEC9WEc[X(wI7#2.(F0jV*eZf<-Qv3J-c+J5AlrB#$p(H68LvEA'q3n0#m,[`*8Ft)FcYgEud]CWfm68,(aLA$@EFTgLXoBq/UPlp7"
13195  ":d[/;r_ix=:TF`S5H-b<LI&HY(K=h#)]Lk$K14lVfm:x$H<3^Ql<M`$OhapBnkup'D#L$Pb_`N*g]2e;X/Dtg,bsj&K#2[-:iYr'_wgH)NUIR8a1n#S?Yej'h8^58UbZd+^FKD*T@;6A"
13196  "7aQC[K8d-(v6GI$x:T<&'Gp5Uf>@M.*J:;$-rv29'M]8qMv-tLp,'886iaC=Hb*YJoKJ,(j%K=H`K.v9HggqBIiZu'QvBT.#=)0ukruV&.)3=(^1`o*Pj4<-<aN((^7('#Z0wK#5GX@7"
13197  "u][`*S^43933A4rl][`*O4CgLEl]v$1Q3AeF37dbXk,.)vj#x'd`;qgbQR%FW,2(?LO=s%Sc68%NP'##Aotl8x=BE#j1UD([3$M(]UI2LX3RpKN@;/#f'f/&_mt&F)XdF<9t4)Qa.*kT"
13198  "LwQ'(TTB9.xH'>#MJ+gLq9-##@HuZPN0]u:h7.T..G:;$/Usj(T7`Q8tT72LnYl<-qx8;-HV7Q-&Xdx%1a,hC=0u+HlsV>nuIQL-5<N?)NBS)QN*_I,?&)2'IM%L3I)X((e/dl2&8'<M"
13199  ":^#M*Q+[T.Xri.LYS3v%fF`68h;b-X[/En'CR.q7E)p'/kle2HM,u;^%OKC-N+Ll%F9CF<Nf'^#t2L,;27W:0O@6##U6W7:$rJfLWHj$#)woqBefIZ.PK<b*t7ed;p*_m;4ExK#h@&]>"
13200  "_>@kXQtMacfD.m-VAb8;IReM3$wf0''hra*so568'Ip&vRs849'MRYSp%:t:h5qSgwpEr$B>Q,;s(C#$)`svQuF$##-D,##,g68@2[T;.XSdN9Qe)rpt._K-#5wF)sP'##p#C0c%-Gb%"
13201  "hd+<-j'Ai*x&&HMkT]C'OSl##5RG[JXaHN;d'uA#x._U;.`PU@(Z3dt4r152@:v,'R.Sj'w#0<-;kPI)FfJ&#AYJ&#//)>-k=m=*XnK$>=)72L]0I%>.G690a:$##<,);?;72#?x9+d;"
13202  "^V'9;jY@;)br#q^YQpx:X#Te$Z^'=-=bGhLf:D6&bNwZ9-ZD#n^9HhLMr5G;']d&6'wYmTFmL<LD)F^%[tC'8;+9E#C$g%#5Y>q9wI>P(9mI[>kC-ekLC/R&CH+s'B;K-M6$EB%is00:"
13203  "+A4[7xks.LrNk0&E)wILYF@2L'0Nb$+pv<(2.768/FrY&h$^3i&@+G%JT'<-,v`3;_)I9M^AE]CN?Cl2AZg+%4iTpT3<n-&%H%b<FDj2M<hH=&Eh<2Len$b*aTX=-8QxN)k11IM1c^j%"
13204  "9s<L<NFSo)B?+<-(GxsF,^-Eh@$4dXhN$+#rxK8'je'D7k`e;)2pYwPA'_p9&@^18ml1^[@g4t*[JOa*[=Qp7(qJ_oOL^('7fB&Hq-:sf,sNj8xq^>$U4O]GKx'm9)b@p7YsvK3w^YR-"
13205  "CdQ*:Ir<($u&)#(&?L9Rg3H)4fiEp^iI9O8KnTj,]H?D*r7'M;PwZ9K0E^k&-cpI;.p/6_vwoFMV<->#%Xi.LxVnrU(4&8/P+:hLSKj$#U%]49t'I:rgMi'FL@a:0Y-uA[39',(vbma*"
13206  "hU%<-SRF`Tt:542R_VV$p@[p8DV[A,?1839FWdF<TddF<9Ah-6&9tWoDlh]&1SpGMq>Ti1O*H&#(AL8[_P%.M>v^-))qOT*F5Cq0`Ye%+$B6i:7@0IX<N+T+0MlMBPQ*Vj>SsD<U4JHY"
13207  "8kD2)2fU/M#$e.)T4,_=8hLim[&);?UkK'-x?'(:siIfL<$pFM`i<?%W(mGDHM%>iWP,##P`%/L<eXi:@Z9C.7o=@(pXdAO/NLQ8lPl+HPOQa8wD8=^GlPa8TKI1CjhsCTSLJM'/Wl>-"
13208  "S(qw%sf/@%#B6;/U7K]uZbi^Oc^2n<bhPmUkMw>%t<)'mEVE''n`WnJra$^TKvX5B>;_aSEK',(hwa0:i4G?.Bci.(X[?b*($,=-n<.Q%`(X=?+@Am*Js0&=3bh8K]mL<LoNs'6,'85`"
13209  "0?t/'_U59@]ddF<#LdF<eWdF<OuN/45rY<-L@&#+fm>69=Lb,OcZV/);TTm8VI;?%OtJ<(b4mq7M6:u?KRdF<gR@2L=FNU-<b[(9c/ML3m;Z[$oF3g)GAWqpARc=<ROu7cL5l;-[A]%/"
13210  "+fsd;l#SafT/f*W]0=O'$(Tb<[)*@e775R-:Yob%g*>l*:xP?Yb.5)%w_I?7uk5JC+FS(m#i'k.'a0i)9<7b'fs'59hq$*5Uhv##pi^8+hIEBF`nvo`;'l0.^S1<-wUK2/Coh58KKhLj"
13211  "M=SO*rfO`+qC`W-On.=AJ56>>i2@2LH6A:&5q`?9I3@@'04&p2/LVa*T-4<-i3;M9UvZd+N7>b*eIwg:CC)c<>nO&#<IGe;__.thjZl<%w(Wk2xmp4Q@I#I9,DF]u7-P=.-_:YJ]aS@V"
13212  "?6*C()dOp7:WL,b&3Rg/.cmM9&r^>$(>.Z-I&J(Q0Hd5Q%7Co-b`-c<N(6r@ip+AurK<m86QIth*#v;-OBqi+L7wDE-Ir8K['m+DDSLwK&/.?-V%U_%3:qKNu$_b*B-kp7NaD'QdWQPK"
13213  "Yq[@>P)hI;*_F]u`Rb[.j8_Q/<&>uu+VsH$sM9TA%?)(vmJ80),P7E>)tjD%2L=-t#fK[%`v=Q8<FfNkgg^oIbah*#8/Qt$F&:K*-(N/'+1vMB,u()-a.VUU*#[e%gAAO(S>WlA2);Sa"
13214  ">gXm8YB`1d@K#n]76-a$U,mF<fX]idqd)<3,]J7JmW4`6]uks=4-72L(jEk+:bJ0M^q-8Dm_Z?0olP1C9Sa&H[d&c$ooQUj]Exd*3ZM@-WGW2%s',B-_M%>%Ul:#/'xoFM9QX-$.QN'>"
13215  "[%$Z$uF6pA6Ki2O5:8w*vP1<-1`[G,)-m#>0`P&#eb#.3i)rtB61(o'$?X3B</R90;eZ]%Ncq;-Tl]#F>2Qft^ae_5tKL9MUe9b*sLEQ95C&`=G?@Mj=wh*'3E>=-<)Gt*Iw)'QG:`@I"
13216  "wOf7&]1i'S01B+Ev/Nac#9S;=;YQpg_6U`*kVY39xK,[/6Aj7:'1Bm-_1EYfa1+o&o4hp7KN_Q(OlIo@S%;jVdn0'1<Vc52=u`3^o-n1'g4v58Hj&6_t7$##?M)c<$bgQ_'SY((-xkA#"
13217  "Y(,p'H9rIVY-b,'%bCPF7.J<Up^,(dU1VY*5#WkTU>h19w,WQhLI)3S#f$2(eb,jr*b;3Vw]*7NH%$c4Vs,eD9>XW8?N]o+(*pgC%/72LV-u<Hp,3@e^9UB1J+ak9-TN/mhKPg+AJYd$"
13218  "MlvAF_jCK*.O-^(63adMT->W%iewS8W6m2rtCpo'RS1R84=@paTKt)>=%&1[)*vp'u+x,VrwN;&]kuO9JDbg=pO$J*.jVe;u'm0dr9l,<*wMK*Oe=g8lV_KEBFkO'oU]^=[-792#ok,)"
13219  "i]lR8qQ2oA8wcRCZ^7w/Njh;?.stX?Q1>S1q4Bn$)K1<-rGdO'$Wr.Lc.CG)$/*JL4tNR/,SVO3,aUw'DJN:)Ss;wGn9A32ijw%FL+Z0Fn.U9;reSq)bmI32U==5ALuG&#Vf1398/pVo"
13220  "1*c-(aY168o<`JsSbk-,1N;$>0:OUas(3:8Z972LSfF8eb=c-;>SPw7.6hn3m`9^Xkn(r.qS[0;T%&Qc=+STRxX'q1BNk3&*eu2;&8q$&x>Q#Q7^Tf+6<(d%ZVmj2bDi%.3L2n+4W'$P"
13221  "iDDG)g,r%+?,$@?uou5tSe2aN_AQU*<h`e-GI7)?OK2A.d7_c)?wQ5AS@DL3r#7fSkgl6-++D:'A,uq7SvlB$pcpH'q3n0#_%dY#xCpr-l<F0NR@-##FEV6NTF6##$l84N1w?AO>'IAO"
13222  "URQ##V^Fv-XFbGM7Fl(N<3DhLGF%q.1rC$#:T__&Pi68%0xi_&[qFJ(77j_&JWoF.V735&T,[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&n`kr-#GJcM6X;uM6X;uM(.a..^2TkL%oR(#"
13223  ";u.T%fAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFY>>^8p,KKF.W]L29uLkLlu/+4T<XoIB&hx=T1PcDaB&;HH+-AFr?(m9HZV)FKS8JCw;SD=6[^/DZUL`EUDf]GGlG&>"
13224  "w$)F./^n3+rlo+DB;5sIYGNk+i1t-69Jg--0pao7Sm#K)pdHW&;LuDNH@H>#/X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#<xU?#@.i?#D:%@#HF7@#LRI@#P_[@#Tkn@#Xw*A#]-=A#a9OA#"
13225  "d<F&#*;G##.GY##2Sl##6`($#:l:$#>xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4&#3^Rh%Sflr-k'MS.o?.5/sWel/wpEM0%3'/1)K^f1-d>G21&v(35>V`39V7A4=onx4"
13226  "A1OY5EI0;6Ibgr6M$HS7Q<)58C5w,;WoA*#[%T*#`1g*#d=#+#hI5+#lUG+#pbY+#tnl+#x$),#&1;,#*=M,#.I`,#2Ur,#6b.-#;w[H#iQtA#m^0B#qjBB#uvTB##-hB#'9$C#+E6C#"
13227  "/QHC#3^ZC#7jmC#;v)D#?,<D#C8ND#GDaD#KPsD#O]/E#g1A5#KA*1#gC17#MGd;#8(02#L-d3#rWM4#Hga1#,<w0#T.j<#O#'2#CYN1#qa^:#_4m3#o@/=#eG8=#t8J5#`+78#4uI-#"
13228  "m3B2#SB[8#Q0@8#i[*9#iOn8#1Nm;#^sN9#qh<9#:=x-#P;K2#$%X9#bC+.#Rg;<#mN=.#MTF.#RZO.#2?)4#Y#(/#[)1/#b;L/#dAU/#0Sv;#lY$0#n`-0#sf60#(F24#wrH0#%/e0#"
13229  "TmD<#%JSMFove:CTBEXI:<eh2g)B,3h2^G3i;#d3jD>)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP"
13230  "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp"
13231  "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#";
13232 
13233 #endif /* NK_INCLUDE_DEFAULT_FONT */
13234 
13235 #define NK_CURSOR_DATA_W 90
13236 #define NK_CURSOR_DATA_H 27
13237 NK_GLOBAL const char nk_custom_cursor_data[NK_CURSOR_DATA_W * NK_CURSOR_DATA_H + 1] =
13238 {
13239  "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX"
13240  "..- -X.....X- X.X - X.X -X.....X - X.....X"
13241  "--- -XXX.XXX- X...X - X...X -X....X - X....X"
13242  "X - X.X - X.....X - X.....X -X...X - X...X"
13243  "XX - X.X -X.......X- X.......X -X..X.X - X.X..X"
13244  "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X"
13245  "X..X - X.X - X.X - X.X -XX X.X - X.X XX"
13246  "X...X - X.X - X.X - XX X.X XX - X.X - X.X "
13247  "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X "
13248  "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X "
13249  "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X "
13250  "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X "
13251  "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X "
13252  "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X "
13253  "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X "
13254  "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X "
13255  "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX "
13256  "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------"
13257  "X.X X..X - -X.......X- X.......X - XX XX - "
13258  "XX X..X - - X.....X - X.....X - X.X X.X - "
13259  " X..X - X...X - X...X - X..X X..X - "
13260  " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - "
13261  "------------ - X - X -X.....................X- "
13262  " ----------------------------------- X...XXXXXXXXXXXXX...X - "
13263  " - X..X X..X - "
13264  " - X.X X.X - "
13265  " - XX XX - "
13266 };
13267 
13268 #ifdef __clang__
13269 #pragma clang diagnostic pop
13270 #elif defined(__GNUC__) || defined(__GNUG__)
13271 #pragma GCC diagnostic pop
13272 #endif
13273 
13274 NK_GLOBAL unsigned char *nk__barrier;
13275 NK_GLOBAL unsigned char *nk__barrier2;
13276 NK_GLOBAL unsigned char *nk__barrier3;
13277 NK_GLOBAL unsigned char *nk__barrier4;
13278 NK_GLOBAL unsigned char *nk__dout;
13279 
13280 NK_INTERN unsigned int
13281 nk_decompress_length(unsigned char *input)
13282 {
13283  return (unsigned int)((input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]);
13284 }
13285 NK_INTERN void
13286 nk__match(unsigned char *data, unsigned int length)
13287 {
13288  /* INVERSE of memmove... write each byte before copying the next...*/
13289  NK_ASSERT (nk__dout + length <= nk__barrier);
13290  if (nk__dout + length > nk__barrier) { nk__dout += length; return; }
13291  if (data < nk__barrier4) { nk__dout = nk__barrier+1; return; }
13292  while (length--) *nk__dout++ = *data++;
13293 }
13294 NK_INTERN void
13295 nk__lit(unsigned char *data, unsigned int length)
13296 {
13297  NK_ASSERT (nk__dout + length <= nk__barrier);
13298  if (nk__dout + length > nk__barrier) { nk__dout += length; return; }
13299  if (data < nk__barrier2) { nk__dout = nk__barrier+1; return; }
13300  NK_MEMCPY(nk__dout, data, length);
13301  nk__dout += length;
13302 }
13303 NK_INTERN unsigned char*
13304 nk_decompress_token(unsigned char *i)
13305 {
13306  #define nk__in2(x) ((i[x] << 8) + i[(x)+1])
13307  #define nk__in3(x) ((i[x] << 16) + nk__in2((x)+1))
13308  #define nk__in4(x) ((i[x] << 24) + nk__in3((x)+1))
13309 
13310  if (*i >= 0x20) { /* use fewer if's for cases that expand small */
13311  if (*i >= 0x80) nk__match(nk__dout-i[1]-1, (unsigned int)i[0] - 0x80 + 1), i += 2;
13312  else if (*i >= 0x40) nk__match(nk__dout-(nk__in2(0) - 0x4000 + 1), (unsigned int)i[2]+1), i += 3;
13313  else /* *i >= 0x20 */ nk__lit(i+1, (unsigned int)i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1);
13314  } else { /* more ifs for cases that expand large, since overhead is amortized */
13315  if (*i >= 0x18) nk__match(nk__dout-(unsigned int)(nk__in3(0) - 0x180000 + 1), (unsigned int)i[3]+1), i += 4;
13316  else if (*i >= 0x10) nk__match(nk__dout-(unsigned int)(nk__in3(0) - 0x100000 + 1), (unsigned int)nk__in2(3)+1), i += 5;
13317  else if (*i >= 0x08) nk__lit(i+2, (unsigned int)nk__in2(0) - 0x0800 + 1), i += 2 + (nk__in2(0) - 0x0800 + 1);
13318  else if (*i == 0x07) nk__lit(i+3, (unsigned int)nk__in2(1) + 1), i += 3 + (nk__in2(1) + 1);
13319  else if (*i == 0x06) nk__match(nk__dout-(unsigned int)(nk__in3(1)+1), i[4]+1u), i += 5;
13320  else if (*i == 0x04) nk__match(nk__dout-(unsigned int)(nk__in3(1)+1), (unsigned int)nk__in2(4)+1u), i += 6;
13321  }
13322  return i;
13323 }
13324 NK_INTERN unsigned int
13325 nk_adler32(unsigned int adler32, unsigned char *buffer, unsigned int buflen)
13326 {
13327  const unsigned long ADLER_MOD = 65521;
13328  unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
13329  unsigned long blocklen, i;
13330 
13331  blocklen = buflen % 5552;
13332  while (buflen) {
13333  for (i=0; i + 7 < blocklen; i += 8) {
13334  s1 += buffer[0]; s2 += s1;
13335  s1 += buffer[1]; s2 += s1;
13336  s1 += buffer[2]; s2 += s1;
13337  s1 += buffer[3]; s2 += s1;
13338  s1 += buffer[4]; s2 += s1;
13339  s1 += buffer[5]; s2 += s1;
13340  s1 += buffer[6]; s2 += s1;
13341  s1 += buffer[7]; s2 += s1;
13342  buffer += 8;
13343  }
13344  for (; i < blocklen; ++i) {
13345  s1 += *buffer++; s2 += s1;
13346  }
13347 
13348  s1 %= ADLER_MOD; s2 %= ADLER_MOD;
13349  buflen -= (unsigned int)blocklen;
13350  blocklen = 5552;
13351  }
13352  return (unsigned int)(s2 << 16) + (unsigned int)s1;
13353 }
13354 NK_INTERN unsigned int
13355 nk_decompress(unsigned char *output, unsigned char *i, unsigned int length)
13356 {
13357  unsigned int olen;
13358  if (nk__in4(0) != 0x57bC0000) return 0;
13359  if (nk__in4(4) != 0) return 0; /* error! stream is > 4GB */
13360  olen = nk_decompress_length(i);
13361  nk__barrier2 = i;
13362  nk__barrier3 = i+length;
13363  nk__barrier = output + olen;
13364  nk__barrier4 = output;
13365  i += 16;
13366 
13367  nk__dout = output;
13368  for (;;) {
13369  unsigned char *old_i = i;
13370  i = nk_decompress_token(i);
13371  if (i == old_i) {
13372  if (*i == 0x05 && i[1] == 0xfa) {
13373  NK_ASSERT(nk__dout == output + olen);
13374  if (nk__dout != output + olen) return 0;
13375  if (nk_adler32(1, output, olen) != (unsigned int) nk__in4(2))
13376  return 0;
13377  return olen;
13378  } else {
13379  NK_ASSERT(0); /* NOTREACHED */
13380  return 0;
13381  }
13382  }
13383  NK_ASSERT(nk__dout <= output + olen);
13384  if (nk__dout > output + olen)
13385  return 0;
13386  }
13387 }
13388 NK_INTERN unsigned int
13389 nk_decode_85_byte(char c)
13390 {
13391  return (unsigned int)((c >= '\\') ? c-36 : c-35);
13392 }
13393 NK_INTERN void
13394 nk_decode_85(unsigned char* dst, const unsigned char* src)
13395 {
13396  while (*src)
13397  {
13398  unsigned int tmp =
13399  nk_decode_85_byte((char)src[0]) +
13400  85 * (nk_decode_85_byte((char)src[1]) +
13401  85 * (nk_decode_85_byte((char)src[2]) +
13402  85 * (nk_decode_85_byte((char)src[3]) +
13403  85 * nk_decode_85_byte((char)src[4]))));
13404 
13405  /* we can't assume little-endianess. */
13406  dst[0] = (unsigned char)((tmp >> 0) & 0xFF);
13407  dst[1] = (unsigned char)((tmp >> 8) & 0xFF);
13408  dst[2] = (unsigned char)((tmp >> 16) & 0xFF);
13409  dst[3] = (unsigned char)((tmp >> 24) & 0xFF);
13410 
13411  src += 5;
13412  dst += 4;
13413  }
13414 }
13415 
13416 /* -------------------------------------------------------------
13417  *
13418  * FONT ATLAS
13419  *
13420  * --------------------------------------------------------------*/
13421 NK_API struct nk_font_config
13422 nk_font_config(float pixel_height)
13423 {
13424  struct nk_font_config cfg;
13425  nk_zero_struct(cfg);
13426  cfg.ttf_blob = 0;
13427  cfg.ttf_size = 0;
13428  cfg.ttf_data_owned_by_atlas = 0;
13429  cfg.size = pixel_height;
13430  cfg.oversample_h = 3;
13431  cfg.oversample_v = 1;
13432  cfg.pixel_snap = 0;
13433  cfg.coord_type = NK_COORD_UV;
13434  cfg.spacing = nk_vec2(0,0);
13435  cfg.range = nk_font_default_glyph_ranges();
13436  cfg.merge_mode = 0;
13437  cfg.fallback_glyph = '?';
13438  cfg.font = 0;
13439  cfg.n = 0;
13440  return cfg;
13441 }
13442 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
13443 NK_API void
13444 nk_font_atlas_init_default(struct nk_font_atlas *atlas)
13445 {
13446  NK_ASSERT(atlas);
13447  if (!atlas) return;
13448  nk_zero_struct(*atlas);
13449  atlas->temporary.userdata.ptr = 0;
13450  atlas->temporary.alloc = nk_malloc;
13451  atlas->temporary.free = nk_mfree;
13452  atlas->permanent.userdata.ptr = 0;
13453  atlas->permanent.alloc = nk_malloc;
13454  atlas->permanent.free = nk_mfree;
13455 }
13456 #endif
13457 NK_API void
13458 nk_font_atlas_init(struct nk_font_atlas *atlas, struct nk_allocator *alloc)
13459 {
13460  NK_ASSERT(atlas);
13461  NK_ASSERT(alloc);
13462  if (!atlas || !alloc) return;
13463  nk_zero_struct(*atlas);
13464  atlas->permanent = *alloc;
13465  atlas->temporary = *alloc;
13466 }
13467 NK_API void
13468 nk_font_atlas_init_custom(struct nk_font_atlas *atlas,
13469  struct nk_allocator *permanent, struct nk_allocator *temporary)
13470 {
13471  NK_ASSERT(atlas);
13472  NK_ASSERT(permanent);
13473  NK_ASSERT(temporary);
13474  if (!atlas || !permanent || !temporary) return;
13475  nk_zero_struct(*atlas);
13476  atlas->permanent = *permanent;
13477  atlas->temporary = *temporary;
13478 }
13479 NK_API void
13480 nk_font_atlas_begin(struct nk_font_atlas *atlas)
13481 {
13482  NK_ASSERT(atlas);
13483  NK_ASSERT(atlas->temporary.alloc && atlas->temporary.free);
13484  NK_ASSERT(atlas->permanent.alloc && atlas->permanent.free);
13485  if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free ||
13486  !atlas->temporary.alloc || !atlas->temporary.free) return;
13487  if (atlas->glyphs) {
13488  atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
13489  atlas->glyphs = 0;
13490  }
13491  if (atlas->pixel) {
13492  atlas->permanent.free(atlas->permanent.userdata, atlas->pixel);
13493  atlas->pixel = 0;
13494  }
13495 }
13496 NK_API struct nk_font*
13497 nk_font_atlas_add(struct nk_font_atlas *atlas, const struct nk_font_config *config)
13498 {
13499  struct nk_font *font = 0;
13500  struct nk_font_config *cfg;
13501 
13502  NK_ASSERT(atlas);
13503  NK_ASSERT(atlas->permanent.alloc);
13504  NK_ASSERT(atlas->permanent.free);
13505  NK_ASSERT(atlas->temporary.alloc);
13506  NK_ASSERT(atlas->temporary.free);
13507 
13508  NK_ASSERT(config);
13509  NK_ASSERT(config->ttf_blob);
13510  NK_ASSERT(config->ttf_size);
13511  NK_ASSERT(config->size > 0.0f);
13512 
13513  if (!atlas || !config || !config->ttf_blob || !config->ttf_size || config->size <= 0.0f||
13514  !atlas->permanent.alloc || !atlas->permanent.free ||
13515  !atlas->temporary.alloc || !atlas->temporary.free)
13516  return 0;
13517 
13518  /* allocate font config */
13519  cfg = (struct nk_font_config*)
13520  atlas->permanent.alloc(atlas->permanent.userdata,0, sizeof(struct nk_font_config));
13521  NK_MEMCPY(cfg, config, sizeof(*config));
13522  cfg->n = cfg;
13523  cfg->p = cfg;
13524 
13525  if (!config->merge_mode) {
13526  /* insert font config into list */
13527  if (!atlas->config) {
13528  atlas->config = cfg;
13529  cfg->next = 0;
13530  } else {
13531  struct nk_font_config *i = atlas->config;
13532  while (i->next) i = i->next;
13533  i->next = cfg;
13534  cfg->next = 0;
13535  }
13536  /* allocate new font */
13537  font = (struct nk_font*)
13538  atlas->permanent.alloc(atlas->permanent.userdata,0, sizeof(struct nk_font));
13539  NK_ASSERT(font);
13540  nk_zero(font, sizeof(*font));
13541  if (!font) return 0;
13542  font->config = cfg;
13543 
13544  /* insert font into list */
13545  if (!atlas->fonts) {
13546  atlas->fonts = font;
13547  font->next = 0;
13548  } else {
13549  struct nk_font *i = atlas->fonts;
13550  while (i->next) i = i->next;
13551  i->next = font;
13552  font->next = 0;
13553  }
13554  cfg->font = &font->info;
13555  } else {
13556  /* extend previously added font */
13557  struct nk_font *f = 0;
13558  struct nk_font_config *c = 0;
13559  NK_ASSERT(atlas->font_num);
13560  f = atlas->fonts;
13561  c = f->config;
13562  cfg->font = &f->info;
13563 
13564  cfg->n = c;
13565  cfg->p = c->p;
13566  c->p->n = cfg;
13567  c->p = cfg;
13568  }
13569  /* create own copy of .TTF font blob */
13570  if (!config->ttf_data_owned_by_atlas) {
13571  cfg->ttf_blob = atlas->permanent.alloc(atlas->permanent.userdata,0, cfg->ttf_size);
13572  NK_ASSERT(cfg->ttf_blob);
13573  if (!cfg->ttf_blob) {
13574  atlas->font_num++;
13575  return 0;
13576  }
13577  NK_MEMCPY(cfg->ttf_blob, config->ttf_blob, cfg->ttf_size);
13578  cfg->ttf_data_owned_by_atlas = 1;
13579  }
13580  atlas->font_num++;
13581  return font;
13582 }
13583 NK_API struct nk_font*
13584 nk_font_atlas_add_from_memory(struct nk_font_atlas *atlas, void *memory,
13585  nk_size size, float height, const struct nk_font_config *config)
13586 {
13587  struct nk_font_config cfg;
13588  NK_ASSERT(memory);
13589  NK_ASSERT(size);
13590 
13591  NK_ASSERT(atlas);
13592  NK_ASSERT(atlas->temporary.alloc);
13593  NK_ASSERT(atlas->temporary.free);
13594  NK_ASSERT(atlas->permanent.alloc);
13595  NK_ASSERT(atlas->permanent.free);
13596  if (!atlas || !atlas->temporary.alloc || !atlas->temporary.free || !memory || !size ||
13597  !atlas->permanent.alloc || !atlas->permanent.free)
13598  return 0;
13599 
13600  cfg = (config) ? *config: nk_font_config(height);
13601  cfg.ttf_blob = memory;
13602  cfg.ttf_size = size;
13603  cfg.size = height;
13604  cfg.ttf_data_owned_by_atlas = 0;
13605  return nk_font_atlas_add(atlas, &cfg);
13606 }
13607 #ifdef NK_INCLUDE_STANDARD_IO
13608 NK_API struct nk_font*
13609 nk_font_atlas_add_from_file(struct nk_font_atlas *atlas, const char *file_path,
13610  float height, const struct nk_font_config *config)
13611 {
13612  nk_size size;
13613  char *memory;
13614  struct nk_font_config cfg;
13615 
13616  NK_ASSERT(atlas);
13617  NK_ASSERT(atlas->temporary.alloc);
13618  NK_ASSERT(atlas->temporary.free);
13619  NK_ASSERT(atlas->permanent.alloc);
13620  NK_ASSERT(atlas->permanent.free);
13621 
13622  if (!atlas || !file_path) return 0;
13623  memory = nk_file_load(file_path, &size, &atlas->permanent);
13624  if (!memory) return 0;
13625 
13626  cfg = (config) ? *config: nk_font_config(height);
13627  cfg.ttf_blob = memory;
13628  cfg.ttf_size = size;
13629  cfg.size = height;
13630  cfg.ttf_data_owned_by_atlas = 1;
13631  return nk_font_atlas_add(atlas, &cfg);
13632 }
13633 #endif
13634 NK_API struct nk_font*
13635 nk_font_atlas_add_compressed(struct nk_font_atlas *atlas,
13636  void *compressed_data, nk_size compressed_size, float height,
13637  const struct nk_font_config *config)
13638 {
13639  unsigned int decompressed_size;
13640  void *decompressed_data;
13641  struct nk_font_config cfg;
13642 
13643  NK_ASSERT(atlas);
13644  NK_ASSERT(atlas->temporary.alloc);
13645  NK_ASSERT(atlas->temporary.free);
13646  NK_ASSERT(atlas->permanent.alloc);
13647  NK_ASSERT(atlas->permanent.free);
13648 
13649  NK_ASSERT(compressed_data);
13650  NK_ASSERT(compressed_size);
13651  if (!atlas || !compressed_data || !atlas->temporary.alloc || !atlas->temporary.free ||
13652  !atlas->permanent.alloc || !atlas->permanent.free)
13653  return 0;
13654 
13655  decompressed_size = nk_decompress_length((unsigned char*)compressed_data);
13656  decompressed_data = atlas->permanent.alloc(atlas->permanent.userdata,0,decompressed_size);
13657  NK_ASSERT(decompressed_data);
13658  if (!decompressed_data) return 0;
13659  nk_decompress((unsigned char*)decompressed_data, (unsigned char*)compressed_data,
13660  (unsigned int)compressed_size);
13661 
13662  cfg = (config) ? *config: nk_font_config(height);
13663  cfg.ttf_blob = decompressed_data;
13664  cfg.ttf_size = decompressed_size;
13665  cfg.size = height;
13666  cfg.ttf_data_owned_by_atlas = 1;
13667  return nk_font_atlas_add(atlas, &cfg);
13668 }
13669 NK_API struct nk_font*
13670 nk_font_atlas_add_compressed_base85(struct nk_font_atlas *atlas,
13671  const char *data_base85, float height, const struct nk_font_config *config)
13672 {
13673  int compressed_size;
13674  void *compressed_data;
13675  struct nk_font *font;
13676 
13677  NK_ASSERT(atlas);
13678  NK_ASSERT(atlas->temporary.alloc);
13679  NK_ASSERT(atlas->temporary.free);
13680  NK_ASSERT(atlas->permanent.alloc);
13681  NK_ASSERT(atlas->permanent.free);
13682 
13683  NK_ASSERT(data_base85);
13684  if (!atlas || !data_base85 || !atlas->temporary.alloc || !atlas->temporary.free ||
13685  !atlas->permanent.alloc || !atlas->permanent.free)
13686  return 0;
13687 
13688  compressed_size = (((int)nk_strlen(data_base85) + 4) / 5) * 4;
13689  compressed_data = atlas->temporary.alloc(atlas->temporary.userdata,0, (nk_size)compressed_size);
13690  NK_ASSERT(compressed_data);
13691  if (!compressed_data) return 0;
13692  nk_decode_85((unsigned char*)compressed_data, (const unsigned char*)data_base85);
13693  font = nk_font_atlas_add_compressed(atlas, compressed_data,
13694  (nk_size)compressed_size, height, config);
13695  atlas->temporary.free(atlas->temporary.userdata, compressed_data);
13696  return font;
13697 }
13698 
13699 #ifdef NK_INCLUDE_DEFAULT_FONT
13700 NK_API struct nk_font*
13701 nk_font_atlas_add_default(struct nk_font_atlas *atlas,
13702  float pixel_height, const struct nk_font_config *config)
13703 {
13704  NK_ASSERT(atlas);
13705  NK_ASSERT(atlas->temporary.alloc);
13706  NK_ASSERT(atlas->temporary.free);
13707  NK_ASSERT(atlas->permanent.alloc);
13708  NK_ASSERT(atlas->permanent.free);
13709  return nk_font_atlas_add_compressed_base85(atlas,
13710  nk_proggy_clean_ttf_compressed_data_base85, pixel_height, config);
13711 }
13712 #endif
13713 NK_API const void*
13714 nk_font_atlas_bake(struct nk_font_atlas *atlas, int *width, int *height,
13715  enum nk_font_atlas_format fmt)
13716 {
13717  int i = 0;
13718  void *tmp = 0;
13719  nk_size tmp_size, img_size;
13720  struct nk_font *font_iter;
13721  struct nk_font_baker *baker;
13722 
13723  NK_ASSERT(atlas);
13724  NK_ASSERT(atlas->temporary.alloc);
13725  NK_ASSERT(atlas->temporary.free);
13726  NK_ASSERT(atlas->permanent.alloc);
13727  NK_ASSERT(atlas->permanent.free);
13728 
13729  NK_ASSERT(width);
13730  NK_ASSERT(height);
13731  if (!atlas || !width || !height ||
13732  !atlas->temporary.alloc || !atlas->temporary.free ||
13733  !atlas->permanent.alloc || !atlas->permanent.free)
13734  return 0;
13735 
13736 #ifdef NK_INCLUDE_DEFAULT_FONT
13737  /* no font added so just use default font */
13738  if (!atlas->font_num)
13739  atlas->default_font = nk_font_atlas_add_default(atlas, 13.0f, 0);
13740 #endif
13741  NK_ASSERT(atlas->font_num);
13742  if (!atlas->font_num) return 0;
13743 
13744  /* allocate temporary baker memory required for the baking process */
13745  nk_font_baker_memory(&tmp_size, &atlas->glyph_count, atlas->config, atlas->font_num);
13746  tmp = atlas->temporary.alloc(atlas->temporary.userdata,0, tmp_size);
13747  NK_ASSERT(tmp);
13748  if (!tmp) goto failed;
13749 
13750  /* allocate glyph memory for all fonts */
13751  baker = nk_font_baker(tmp, atlas->glyph_count, atlas->font_num, &atlas->temporary);
13752  atlas->glyphs = (struct nk_font_glyph*)atlas->permanent.alloc(
13753  atlas->permanent.userdata,0, sizeof(struct nk_font_glyph)*(nk_size)atlas->glyph_count);
13754  NK_ASSERT(atlas->glyphs);
13755  if (!atlas->glyphs)
13756  goto failed;
13757 
13758  /* pack all glyphs into a tight fit space */
13759  atlas->custom.w = (NK_CURSOR_DATA_W*2)+1;
13760  atlas->custom.h = NK_CURSOR_DATA_H + 1;
13761  if (!nk_font_bake_pack(baker, &img_size, width, height, &atlas->custom,
13762  atlas->config, atlas->font_num, &atlas->temporary))
13763  goto failed;
13764 
13765  /* allocate memory for the baked image font atlas */
13766  atlas->pixel = atlas->temporary.alloc(atlas->temporary.userdata,0, img_size);
13767  NK_ASSERT(atlas->pixel);
13768  if (!atlas->pixel)
13769  goto failed;
13770 
13771  /* bake glyphs and custom white pixel into image */
13772  nk_font_bake(baker, atlas->pixel, *width, *height,
13773  atlas->glyphs, atlas->glyph_count, atlas->config, atlas->font_num);
13774  nk_font_bake_custom_data(atlas->pixel, *width, *height, atlas->custom,
13775  nk_custom_cursor_data, NK_CURSOR_DATA_W, NK_CURSOR_DATA_H, '.', 'X');
13776 
13777  if (fmt == NK_FONT_ATLAS_RGBA32) {
13778  /* convert alpha8 image into rgba32 image */
13779  void *img_rgba = atlas->temporary.alloc(atlas->temporary.userdata,0,
13780  (nk_size)(*width * *height * 4));
13781  NK_ASSERT(img_rgba);
13782  if (!img_rgba) goto failed;
13783  nk_font_bake_convert(img_rgba, *width, *height, atlas->pixel);
13784  atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
13785  atlas->pixel = img_rgba;
13786  }
13787  atlas->tex_width = *width;
13788  atlas->tex_height = *height;
13789 
13790  /* initialize each font */
13791  for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
13792  struct nk_font *font = font_iter;
13793  struct nk_font_config *config = font->config;
13794  nk_font_init(font, config->size, config->fallback_glyph, atlas->glyphs,
13795  config->font, nk_handle_ptr(0));
13796  }
13797 
13798  /* initialize each cursor */
13799  {NK_STORAGE const struct nk_vec2 nk_cursor_data[NK_CURSOR_COUNT][3] = {
13800  /* Pos Size Offset */
13801  {{ 0, 3}, {12,19}, { 0, 0}},
13802  {{13, 0}, { 7,16}, { 4, 8}},
13803  {{31, 0}, {23,23}, {11,11}},
13804  {{21, 0}, { 9, 23}, { 5,11}},
13805  {{55,18}, {23, 9}, {11, 5}},
13806  {{73, 0}, {17,17}, { 9, 9}},
13807  {{55, 0}, {17,17}, { 9, 9}}
13808  };
13809  for (i = 0; i < NK_CURSOR_COUNT; ++i) {
13810  struct nk_cursor *cursor = &atlas->cursors[i];
13811  cursor->img.w = (unsigned short)*width;
13812  cursor->img.h = (unsigned short)*height;
13813  cursor->img.region[0] = (unsigned short)(atlas->custom.x + nk_cursor_data[i][0].x);
13814  cursor->img.region[1] = (unsigned short)(atlas->custom.y + nk_cursor_data[i][0].y);
13815  cursor->img.region[2] = (unsigned short)nk_cursor_data[i][1].x;
13816  cursor->img.region[3] = (unsigned short)nk_cursor_data[i][1].y;
13817  cursor->size = nk_cursor_data[i][1];
13818  cursor->offset = nk_cursor_data[i][2];
13819  }}
13820  /* free temporary memory */
13821  atlas->temporary.free(atlas->temporary.userdata, tmp);
13822  return atlas->pixel;
13823 
13824 failed:
13825  /* error so cleanup all memory */
13826  if (tmp) atlas->temporary.free(atlas->temporary.userdata, tmp);
13827  if (atlas->glyphs) {
13828  atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
13829  atlas->glyphs = 0;
13830  }
13831  if (atlas->pixel) {
13832  atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
13833  atlas->pixel = 0;
13834  }
13835  return 0;
13836 }
13837 NK_API void
13838 nk_font_atlas_end(struct nk_font_atlas *atlas, nk_handle texture,
13839  struct nk_draw_null_texture *null)
13840 {
13841  int i = 0;
13842  struct nk_font *font_iter;
13843  NK_ASSERT(atlas);
13844  if (!atlas) {
13845  if (!null) return;
13846  null->texture = texture;
13847  null->uv = nk_vec2(0.5f,0.5f);
13848  }
13849  if (null) {
13850  null->texture = texture;
13851  null->uv.x = (atlas->custom.x + 0.5f)/(float)atlas->tex_width;
13852  null->uv.y = (atlas->custom.y + 0.5f)/(float)atlas->tex_height;
13853  }
13854  for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
13855  font_iter->texture = texture;
13856 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
13857  font_iter->handle.texture = texture;
13858 #endif
13859  }
13860  for (i = 0; i < NK_CURSOR_COUNT; ++i)
13861  atlas->cursors[i].img.handle = texture;
13862 
13863  atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
13864  atlas->pixel = 0;
13865  atlas->tex_width = 0;
13866  atlas->tex_height = 0;
13867  atlas->custom.x = 0;
13868  atlas->custom.y = 0;
13869  atlas->custom.w = 0;
13870  atlas->custom.h = 0;
13871 }
13872 NK_API void
13873 nk_font_atlas_cleanup(struct nk_font_atlas *atlas)
13874 {
13875  NK_ASSERT(atlas);
13876  NK_ASSERT(atlas->temporary.alloc);
13877  NK_ASSERT(atlas->temporary.free);
13878  NK_ASSERT(atlas->permanent.alloc);
13879  NK_ASSERT(atlas->permanent.free);
13880  if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return;
13881  if (atlas->config) {
13882  struct nk_font_config *iter;
13883  for (iter = atlas->config; iter; iter = iter->next) {
13884  struct nk_font_config *i;
13885  for (i = iter->n; i != iter; i = i->n) {
13886  atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
13887  i->ttf_blob = 0;
13888  }
13889  atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
13890  iter->ttf_blob = 0;
13891  }
13892  }
13893 }
13894 NK_API void
13895 nk_font_atlas_clear(struct nk_font_atlas *atlas)
13896 {
13897  NK_ASSERT(atlas);
13898  NK_ASSERT(atlas->temporary.alloc);
13899  NK_ASSERT(atlas->temporary.free);
13900  NK_ASSERT(atlas->permanent.alloc);
13901  NK_ASSERT(atlas->permanent.free);
13902  if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return;
13903 
13904  if (atlas->config) {
13905  struct nk_font_config *iter, *next;
13906  for (iter = atlas->config; iter; iter = next) {
13907  struct nk_font_config *i, *n;
13908  for (i = iter->n; i != iter; i = n) {
13909  n = i->n;
13910  if (i->ttf_blob)
13911  atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
13912  atlas->permanent.free(atlas->permanent.userdata, i);
13913  }
13914  next = iter->next;
13915  if (i->ttf_blob)
13916  atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
13917  atlas->permanent.free(atlas->permanent.userdata, iter);
13918  }
13919  atlas->config = 0;
13920  }
13921  if (atlas->fonts) {
13922  struct nk_font *iter, *next;
13923  for (iter = atlas->fonts; iter; iter = next) {
13924  next = iter->next;
13925  atlas->permanent.free(atlas->permanent.userdata, iter);
13926  }
13927  atlas->fonts = 0;
13928  }
13929  if (atlas->glyphs)
13930  atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
13931  nk_zero_struct(*atlas);
13932 }
13933 #endif
13934 
13935 
13936 
13937 
13938 
13939 /* ===============================================================
13940  *
13941  * INPUT
13942  *
13943  * ===============================================================*/
13944 NK_API void
13945 nk_input_begin(struct nk_context *ctx)
13946 {
13947  int i;
13948  struct nk_input *in;
13949  NK_ASSERT(ctx);
13950  if (!ctx) return;
13951  in = &ctx->input;
13952  for (i = 0; i < NK_BUTTON_MAX; ++i)
13953  in->mouse.buttons[i].clicked = 0;
13954 
13955  in->keyboard.text_len = 0;
13956  in->mouse.scroll_delta = nk_vec2(0,0);
13957  in->mouse.prev.x = in->mouse.pos.x;
13958  in->mouse.prev.y = in->mouse.pos.y;
13959  in->mouse.delta.x = 0;
13960  in->mouse.delta.y = 0;
13961  for (i = 0; i < NK_KEY_MAX; i++)
13962  in->keyboard.keys[i].clicked = 0;
13963 }
13964 NK_API void
13965 nk_input_end(struct nk_context *ctx)
13966 {
13967  struct nk_input *in;
13968  NK_ASSERT(ctx);
13969  if (!ctx) return;
13970  in = &ctx->input;
13971  if (in->mouse.grab)
13972  in->mouse.grab = 0;
13973  if (in->mouse.ungrab) {
13974  in->mouse.grabbed = 0;
13975  in->mouse.ungrab = 0;
13976  in->mouse.grab = 0;
13977  }
13978 }
13979 NK_API void
13980 nk_input_motion(struct nk_context *ctx, int x, int y)
13981 {
13982  struct nk_input *in;
13983  NK_ASSERT(ctx);
13984  if (!ctx) return;
13985  in = &ctx->input;
13986  in->mouse.pos.x = (float)x;
13987  in->mouse.pos.y = (float)y;
13988  in->mouse.delta.x = in->mouse.pos.x - in->mouse.prev.x;
13989  in->mouse.delta.y = in->mouse.pos.y - in->mouse.prev.y;
13990 }
13991 NK_API void
13992 nk_input_key(struct nk_context *ctx, enum nk_keys key, int down)
13993 {
13994  struct nk_input *in;
13995  NK_ASSERT(ctx);
13996  if (!ctx) return;
13997  in = &ctx->input;
13998 #ifdef NK_KEYSTATE_BASED_INPUT
13999  if (in->keyboard.keys[key].down != down)
14000  in->keyboard.keys[key].clicked++;
14001 #else
14002  in->keyboard.keys[key].clicked++;
14003 #endif
14004  in->keyboard.keys[key].down = down;
14005 }
14006 NK_API void
14007 nk_input_button(struct nk_context *ctx, enum nk_buttons id, int x, int y, int down)
14008 {
14009  struct nk_mouse_button *btn;
14010  struct nk_input *in;
14011  NK_ASSERT(ctx);
14012  if (!ctx) return;
14013  in = &ctx->input;
14014  if (in->mouse.buttons[id].down == down) return;
14015 
14016  btn = &in->mouse.buttons[id];
14017  btn->clicked_pos.x = (float)x;
14018  btn->clicked_pos.y = (float)y;
14019  btn->down = down;
14020  btn->clicked++;
14021 }
14022 NK_API void
14023 nk_input_scroll(struct nk_context *ctx, struct nk_vec2 val)
14024 {
14025  NK_ASSERT(ctx);
14026  if (!ctx) return;
14027  ctx->input.mouse.scroll_delta.x += val.x;
14028  ctx->input.mouse.scroll_delta.y += val.y;
14029 }
14030 NK_API void
14031 nk_input_glyph(struct nk_context *ctx, const nk_glyph glyph)
14032 {
14033  int len = 0;
14034  nk_rune unicode;
14035  struct nk_input *in;
14036 
14037  NK_ASSERT(ctx);
14038  if (!ctx) return;
14039  in = &ctx->input;
14040 
14041  len = nk_utf_decode(glyph, &unicode, NK_UTF_SIZE);
14042  if (len && ((in->keyboard.text_len + len) < NK_INPUT_MAX)) {
14043  nk_utf_encode(unicode, &in->keyboard.text[in->keyboard.text_len],
14045  in->keyboard.text_len += len;
14046  }
14047 }
14048 NK_API void
14049 nk_input_char(struct nk_context *ctx, char c)
14050 {
14051  nk_glyph glyph;
14052  NK_ASSERT(ctx);
14053  if (!ctx) return;
14054  glyph[0] = c;
14055  nk_input_glyph(ctx, glyph);
14056 }
14057 NK_API void
14058 nk_input_unicode(struct nk_context *ctx, nk_rune unicode)
14059 {
14060  nk_glyph rune;
14061  NK_ASSERT(ctx);
14062  if (!ctx) return;
14063  nk_utf_encode(unicode, rune, NK_UTF_SIZE);
14064  nk_input_glyph(ctx, rune);
14065 }
14066 NK_API int
14067 nk_input_has_mouse_click(const struct nk_input *i, enum nk_buttons id)
14068 {
14069  const struct nk_mouse_button *btn;
14070  if (!i) return nk_false;
14071  btn = &i->mouse.buttons[id];
14072  return (btn->clicked && btn->down == nk_false) ? nk_true : nk_false;
14073 }
14074 NK_API int
14075 nk_input_has_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id,
14076  struct nk_rect b)
14077 {
14078  const struct nk_mouse_button *btn;
14079  if (!i) return nk_false;
14080  btn = &i->mouse.buttons[id];
14081  if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h))
14082  return nk_false;
14083  return nk_true;
14084 }
14085 NK_API int
14087  struct nk_rect b, int down)
14088 {
14089  const struct nk_mouse_button *btn;
14090  if (!i) return nk_false;
14091  btn = &i->mouse.buttons[id];
14092  return nk_input_has_mouse_click_in_rect(i, id, b) && (btn->down == down);
14093 }
14094 NK_API int
14095 nk_input_is_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id,
14096  struct nk_rect b)
14097 {
14098  const struct nk_mouse_button *btn;
14099  if (!i) return nk_false;
14100  btn = &i->mouse.buttons[id];
14101  return (nk_input_has_mouse_click_down_in_rect(i, id, b, nk_false) &&
14102  btn->clicked) ? nk_true : nk_false;
14103 }
14104 NK_API int
14106  struct nk_rect b, int down)
14107 {
14108  const struct nk_mouse_button *btn;
14109  if (!i) return nk_false;
14110  btn = &i->mouse.buttons[id];
14111  return (nk_input_has_mouse_click_down_in_rect(i, id, b, down) &&
14112  btn->clicked) ? nk_true : nk_false;
14113 }
14114 NK_API int
14115 nk_input_any_mouse_click_in_rect(const struct nk_input *in, struct nk_rect b)
14116 {
14117  int i, down = 0;
14118  for (i = 0; i < NK_BUTTON_MAX; ++i)
14119  down = down || nk_input_is_mouse_click_in_rect(in, (enum nk_buttons)i, b);
14120  return down;
14121 }
14122 NK_API int
14123 nk_input_is_mouse_hovering_rect(const struct nk_input *i, struct nk_rect rect)
14124 {
14125  if (!i) return nk_false;
14126  return NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h);
14127 }
14128 NK_API int
14129 nk_input_is_mouse_prev_hovering_rect(const struct nk_input *i, struct nk_rect rect)
14130 {
14131  if (!i) return nk_false;
14132  return NK_INBOX(i->mouse.prev.x, i->mouse.prev.y, rect.x, rect.y, rect.w, rect.h);
14133 }
14134 NK_API int
14135 nk_input_mouse_clicked(const struct nk_input *i, enum nk_buttons id, struct nk_rect rect)
14136 {
14137  if (!i) return nk_false;
14138  if (!nk_input_is_mouse_hovering_rect(i, rect)) return nk_false;
14139  return nk_input_is_mouse_click_in_rect(i, id, rect);
14140 }
14141 NK_API int
14142 nk_input_is_mouse_down(const struct nk_input *i, enum nk_buttons id)
14143 {
14144  if (!i) return nk_false;
14145  return i->mouse.buttons[id].down;
14146 }
14147 NK_API int
14148 nk_input_is_mouse_pressed(const struct nk_input *i, enum nk_buttons id)
14149 {
14150  const struct nk_mouse_button *b;
14151  if (!i) return nk_false;
14152  b = &i->mouse.buttons[id];
14153  if (b->down && b->clicked)
14154  return nk_true;
14155  return nk_false;
14156 }
14157 NK_API int
14158 nk_input_is_mouse_released(const struct nk_input *i, enum nk_buttons id)
14159 {
14160  if (!i) return nk_false;
14161  return (!i->mouse.buttons[id].down && i->mouse.buttons[id].clicked);
14162 }
14163 NK_API int
14164 nk_input_is_key_pressed(const struct nk_input *i, enum nk_keys key)
14165 {
14166  const struct nk_key *k;
14167  if (!i) return nk_false;
14168  k = &i->keyboard.keys[key];
14169  if ((k->down && k->clicked) || (!k->down && k->clicked >= 2))
14170  return nk_true;
14171  return nk_false;
14172 }
14173 NK_API int
14174 nk_input_is_key_released(const struct nk_input *i, enum nk_keys key)
14175 {
14176  const struct nk_key *k;
14177  if (!i) return nk_false;
14178  k = &i->keyboard.keys[key];
14179  if ((!k->down && k->clicked) || (k->down && k->clicked >= 2))
14180  return nk_true;
14181  return nk_false;
14182 }
14183 NK_API int
14184 nk_input_is_key_down(const struct nk_input *i, enum nk_keys key)
14185 {
14186  const struct nk_key *k;
14187  if (!i) return nk_false;
14188  k = &i->keyboard.keys[key];
14189  if (k->down) return nk_true;
14190  return nk_false;
14191 }
14192 
14193 
14194 
14195 
14196 
14197 /* ===============================================================
14198  *
14199  * STYLE
14200  *
14201  * ===============================================================*/
14202 NK_API void nk_style_default(struct nk_context *ctx){nk_style_from_table(ctx, 0);}
14203 #define NK_COLOR_MAP(NK_COLOR)\
14204  NK_COLOR(NK_COLOR_TEXT, 175,175,175,255) \
14205  NK_COLOR(NK_COLOR_WINDOW, 45, 45, 45, 255) \
14206  NK_COLOR(NK_COLOR_HEADER, 40, 40, 40, 255) \
14207  NK_COLOR(NK_COLOR_BORDER, 65, 65, 65, 255) \
14208  NK_COLOR(NK_COLOR_BUTTON, 50, 50, 50, 255) \
14209  NK_COLOR(NK_COLOR_BUTTON_HOVER, 40, 40, 40, 255) \
14210  NK_COLOR(NK_COLOR_BUTTON_ACTIVE, 35, 35, 35, 255) \
14211  NK_COLOR(NK_COLOR_TOGGLE, 100,100,100,255) \
14212  NK_COLOR(NK_COLOR_TOGGLE_HOVER, 120,120,120,255) \
14213  NK_COLOR(NK_COLOR_TOGGLE_CURSOR, 45, 45, 45, 255) \
14214  NK_COLOR(NK_COLOR_SELECT, 45, 45, 45, 255) \
14215  NK_COLOR(NK_COLOR_SELECT_ACTIVE, 35, 35, 35,255) \
14216  NK_COLOR(NK_COLOR_SLIDER, 38, 38, 38, 255) \
14217  NK_COLOR(NK_COLOR_SLIDER_CURSOR, 100,100,100,255) \
14218  NK_COLOR(NK_COLOR_SLIDER_CURSOR_HOVER, 120,120,120,255) \
14219  NK_COLOR(NK_COLOR_SLIDER_CURSOR_ACTIVE, 150,150,150,255) \
14220  NK_COLOR(NK_COLOR_PROPERTY, 38, 38, 38, 255) \
14221  NK_COLOR(NK_COLOR_EDIT, 38, 38, 38, 255) \
14222  NK_COLOR(NK_COLOR_EDIT_CURSOR, 175,175,175,255) \
14223  NK_COLOR(NK_COLOR_COMBO, 45, 45, 45, 255) \
14224  NK_COLOR(NK_COLOR_CHART, 120,120,120,255) \
14225  NK_COLOR(NK_COLOR_CHART_COLOR, 45, 45, 45, 255) \
14226  NK_COLOR(NK_COLOR_CHART_COLOR_HIGHLIGHT, 255, 0, 0, 255) \
14227  NK_COLOR(NK_COLOR_SCROLLBAR, 40, 40, 40, 255) \
14228  NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR, 100,100,100,255) \
14229  NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_HOVER, 120,120,120,255) \
14230  NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_ACTIVE, 150,150,150,255) \
14231  NK_COLOR(NK_COLOR_TAB_HEADER, 40, 40, 40,255)
14232 
14233 NK_GLOBAL const struct nk_color
14234 nk_default_color_style[NK_COLOR_COUNT] = {
14235 #define NK_COLOR(a,b,c,d,e) {b,c,d,e},
14236  NK_COLOR_MAP(NK_COLOR)
14237 #undef NK_COLOR
14238 };
14239 NK_GLOBAL const char *nk_color_names[NK_COLOR_COUNT] = {
14240 #define NK_COLOR(a,b,c,d,e) #a,
14241  NK_COLOR_MAP(NK_COLOR)
14242 #undef NK_COLOR
14243 };
14244 
14245 NK_API const char*
14247 {
14248  return nk_color_names[c];
14249 }
14250 NK_API struct nk_style_item
14251 nk_style_item_image(struct nk_image img)
14252 {
14253  struct nk_style_item i;
14254  i.type = NK_STYLE_ITEM_IMAGE;
14255  i.data.image = img;
14256  return i;
14257 }
14258 NK_API struct nk_style_item
14259 nk_style_item_color(struct nk_color col)
14260 {
14261  struct nk_style_item i;
14262  i.type = NK_STYLE_ITEM_COLOR;
14263  i.data.color = col;
14264  return i;
14265 }
14266 NK_API struct nk_style_item
14267 nk_style_item_hide(void)
14268 {
14269  struct nk_style_item i;
14270  i.type = NK_STYLE_ITEM_COLOR;
14271  i.data.color = nk_rgba(0,0,0,0);
14272  return i;
14273 }
14274 NK_API void
14275 nk_style_from_table(struct nk_context *ctx, const struct nk_color *table)
14276 {
14277  struct nk_style *style;
14278  struct nk_style_text *text;
14279  struct nk_style_button *button;
14280  struct nk_style_toggle *toggle;
14281  struct nk_style_selectable *select;
14282  struct nk_style_slider *slider;
14283  struct nk_style_progress *prog;
14284  struct nk_style_scrollbar *scroll;
14285  struct nk_style_edit *edit;
14286  struct nk_style_property *property;
14287  struct nk_style_combo *combo;
14288  struct nk_style_chart *chart;
14289  struct nk_style_tab *tab;
14290  struct nk_style_window *win;
14291 
14292  NK_ASSERT(ctx);
14293  if (!ctx) return;
14294  style = &ctx->style;
14295  table = (!table) ? nk_default_color_style: table;
14296 
14297  /* default text */
14298  text = &style->text;
14299  text->color = table[NK_COLOR_TEXT];
14300  text->padding = nk_vec2(0,0);
14301 
14302  /* default button */
14303  button = &style->button;
14304  nk_zero_struct(*button);
14305  button->normal = nk_style_item_color(table[NK_COLOR_BUTTON]);
14308  button->border_color = table[NK_COLOR_BORDER];
14309  button->text_background = table[NK_COLOR_BUTTON];
14310  button->text_normal = table[NK_COLOR_TEXT];
14311  button->text_hover = table[NK_COLOR_TEXT];
14312  button->text_active = table[NK_COLOR_TEXT];
14313  button->padding = nk_vec2(2.0f,2.0f);
14314  button->image_padding = nk_vec2(0.0f,0.0f);
14315  button->touch_padding = nk_vec2(0.0f, 0.0f);
14316  button->userdata = nk_handle_ptr(0);
14317  button->text_alignment = NK_TEXT_CENTERED;
14318  button->border = 1.0f;
14319  button->rounding = 4.0f;
14320  button->draw_begin = 0;
14321  button->draw_end = 0;
14322 
14323  /* contextual button */
14324  button = &style->contextual_button;
14325  nk_zero_struct(*button);
14326  button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
14329  button->border_color = table[NK_COLOR_WINDOW];
14330  button->text_background = table[NK_COLOR_WINDOW];
14331  button->text_normal = table[NK_COLOR_TEXT];
14332  button->text_hover = table[NK_COLOR_TEXT];
14333  button->text_active = table[NK_COLOR_TEXT];
14334  button->padding = nk_vec2(2.0f,2.0f);
14335  button->touch_padding = nk_vec2(0.0f,0.0f);
14336  button->userdata = nk_handle_ptr(0);
14337  button->text_alignment = NK_TEXT_CENTERED;
14338  button->border = 0.0f;
14339  button->rounding = 0.0f;
14340  button->draw_begin = 0;
14341  button->draw_end = 0;
14342 
14343  /* menu button */
14344  button = &style->menu_button;
14345  nk_zero_struct(*button);
14346  button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
14347  button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]);
14348  button->active = nk_style_item_color(table[NK_COLOR_WINDOW]);
14349  button->border_color = table[NK_COLOR_WINDOW];
14350  button->text_background = table[NK_COLOR_WINDOW];
14351  button->text_normal = table[NK_COLOR_TEXT];
14352  button->text_hover = table[NK_COLOR_TEXT];
14353  button->text_active = table[NK_COLOR_TEXT];
14354  button->padding = nk_vec2(2.0f,2.0f);
14355  button->touch_padding = nk_vec2(0.0f,0.0f);
14356  button->userdata = nk_handle_ptr(0);
14357  button->text_alignment = NK_TEXT_CENTERED;
14358  button->border = 0.0f;
14359  button->rounding = 1.0f;
14360  button->draw_begin = 0;
14361  button->draw_end = 0;
14362 
14363  /* checkbox toggle */
14364  toggle = &style->checkbox;
14365  nk_zero_struct(*toggle);
14366  toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]);
14371  toggle->userdata = nk_handle_ptr(0);
14372  toggle->text_background = table[NK_COLOR_WINDOW];
14373  toggle->text_normal = table[NK_COLOR_TEXT];
14374  toggle->text_hover = table[NK_COLOR_TEXT];
14375  toggle->text_active = table[NK_COLOR_TEXT];
14376  toggle->padding = nk_vec2(2.0f, 2.0f);
14377  toggle->touch_padding = nk_vec2(0,0);
14378  toggle->border_color = nk_rgba(0,0,0,0);
14379  toggle->border = 0.0f;
14380  toggle->spacing = 4;
14381 
14382  /* option toggle */
14383  toggle = &style->option;
14384  nk_zero_struct(*toggle);
14385  toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]);
14390  toggle->userdata = nk_handle_ptr(0);
14391  toggle->text_background = table[NK_COLOR_WINDOW];
14392  toggle->text_normal = table[NK_COLOR_TEXT];
14393  toggle->text_hover = table[NK_COLOR_TEXT];
14394  toggle->text_active = table[NK_COLOR_TEXT];
14395  toggle->padding = nk_vec2(3.0f, 3.0f);
14396  toggle->touch_padding = nk_vec2(0,0);
14397  toggle->border_color = nk_rgba(0,0,0,0);
14398  toggle->border = 0.0f;
14399  toggle->spacing = 4;
14400 
14401  /* selectable */
14402  select = &style->selectable;
14403  nk_zero_struct(*select);
14404  select->normal = nk_style_item_color(table[NK_COLOR_SELECT]);
14405  select->hover = nk_style_item_color(table[NK_COLOR_SELECT]);
14406  select->pressed = nk_style_item_color(table[NK_COLOR_SELECT]);
14410  select->text_normal = table[NK_COLOR_TEXT];
14411  select->text_hover = table[NK_COLOR_TEXT];
14412  select->text_pressed = table[NK_COLOR_TEXT];
14413  select->text_normal_active = table[NK_COLOR_TEXT];
14414  select->text_hover_active = table[NK_COLOR_TEXT];
14415  select->text_pressed_active = table[NK_COLOR_TEXT];
14416  select->padding = nk_vec2(2.0f,2.0f);
14417  select->image_padding = nk_vec2(2.0f,2.0f);
14418  select->touch_padding = nk_vec2(0,0);
14419  select->userdata = nk_handle_ptr(0);
14420  select->rounding = 0.0f;
14421  select->draw_begin = 0;
14422  select->draw_end = 0;
14423 
14424  /* slider */
14425  slider = &style->slider;
14426  nk_zero_struct(*slider);
14427  slider->normal = nk_style_item_hide();
14428  slider->hover = nk_style_item_hide();
14429  slider->active = nk_style_item_hide();
14430  slider->bar_normal = table[NK_COLOR_SLIDER];
14431  slider->bar_hover = table[NK_COLOR_SLIDER];
14432  slider->bar_active = table[NK_COLOR_SLIDER];
14433  slider->bar_filled = table[NK_COLOR_SLIDER_CURSOR];
14439  slider->cursor_size = nk_vec2(16,16);
14440  slider->padding = nk_vec2(2,2);
14441  slider->spacing = nk_vec2(2,2);
14442  slider->userdata = nk_handle_ptr(0);
14443  slider->show_buttons = nk_false;
14444  slider->bar_height = 8;
14445  slider->rounding = 0;
14446  slider->draw_begin = 0;
14447  slider->draw_end = 0;
14448 
14449  /* slider buttons */
14450  button = &style->slider.inc_button;
14451  button->normal = nk_style_item_color(nk_rgb(40,40,40));
14452  button->hover = nk_style_item_color(nk_rgb(42,42,42));
14453  button->active = nk_style_item_color(nk_rgb(44,44,44));
14454  button->border_color = nk_rgb(65,65,65);
14455  button->text_background = nk_rgb(40,40,40);
14456  button->text_normal = nk_rgb(175,175,175);
14457  button->text_hover = nk_rgb(175,175,175);
14458  button->text_active = nk_rgb(175,175,175);
14459  button->padding = nk_vec2(8.0f,8.0f);
14460  button->touch_padding = nk_vec2(0.0f,0.0f);
14461  button->userdata = nk_handle_ptr(0);
14462  button->text_alignment = NK_TEXT_CENTERED;
14463  button->border = 1.0f;
14464  button->rounding = 0.0f;
14465  button->draw_begin = 0;
14466  button->draw_end = 0;
14467  style->slider.dec_button = style->slider.inc_button;
14468 
14469  /* progressbar */
14470  prog = &style->progress;
14471  nk_zero_struct(*prog);
14472  prog->normal = nk_style_item_color(table[NK_COLOR_SLIDER]);
14473  prog->hover = nk_style_item_color(table[NK_COLOR_SLIDER]);
14474  prog->active = nk_style_item_color(table[NK_COLOR_SLIDER]);
14478  prog->border_color = nk_rgba(0,0,0,0);
14479  prog->cursor_border_color = nk_rgba(0,0,0,0);
14480  prog->userdata = nk_handle_ptr(0);
14481  prog->padding = nk_vec2(4,4);
14482  prog->rounding = 0;
14483  prog->border = 0;
14484  prog->cursor_rounding = 0;
14485  prog->cursor_border = 0;
14486  prog->draw_begin = 0;
14487  prog->draw_end = 0;
14488 
14489  /* scrollbars */
14490  scroll = &style->scrollh;
14491  nk_zero_struct(*scroll);
14492  scroll->normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
14493  scroll->hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
14494  scroll->active = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
14500  scroll->userdata = nk_handle_ptr(0);
14501  scroll->border_color = table[NK_COLOR_SCROLLBAR];
14502  scroll->cursor_border_color = table[NK_COLOR_SCROLLBAR];
14503  scroll->padding = nk_vec2(0,0);
14504  scroll->show_buttons = nk_false;
14505  scroll->border = 0;
14506  scroll->rounding = 0;
14507  scroll->border_cursor = 0;
14508  scroll->rounding_cursor = 0;
14509  scroll->draw_begin = 0;
14510  scroll->draw_end = 0;
14511  style->scrollv = style->scrollh;
14512 
14513  /* scrollbars buttons */
14514  button = &style->scrollh.inc_button;
14515  button->normal = nk_style_item_color(nk_rgb(40,40,40));
14516  button->hover = nk_style_item_color(nk_rgb(42,42,42));
14517  button->active = nk_style_item_color(nk_rgb(44,44,44));
14518  button->border_color = nk_rgb(65,65,65);
14519  button->text_background = nk_rgb(40,40,40);
14520  button->text_normal = nk_rgb(175,175,175);
14521  button->text_hover = nk_rgb(175,175,175);
14522  button->text_active = nk_rgb(175,175,175);
14523  button->padding = nk_vec2(4.0f,4.0f);
14524  button->touch_padding = nk_vec2(0.0f,0.0f);
14525  button->userdata = nk_handle_ptr(0);
14526  button->text_alignment = NK_TEXT_CENTERED;
14527  button->border = 1.0f;
14528  button->rounding = 0.0f;
14529  button->draw_begin = 0;
14530  button->draw_end = 0;
14531  style->scrollh.dec_button = style->scrollh.inc_button;
14532  style->scrollv.inc_button = style->scrollh.inc_button;
14533  style->scrollv.dec_button = style->scrollh.inc_button;
14534 
14535  /* edit */
14536  edit = &style->edit;
14537  nk_zero_struct(*edit);
14538  edit->normal = nk_style_item_color(table[NK_COLOR_EDIT]);
14539  edit->hover = nk_style_item_color(table[NK_COLOR_EDIT]);
14540  edit->active = nk_style_item_color(table[NK_COLOR_EDIT]);
14541  edit->cursor_normal = table[NK_COLOR_TEXT];
14542  edit->cursor_hover = table[NK_COLOR_TEXT];
14543  edit->cursor_text_normal= table[NK_COLOR_EDIT];
14544  edit->cursor_text_hover = table[NK_COLOR_EDIT];
14545  edit->border_color = table[NK_COLOR_BORDER];
14546  edit->text_normal = table[NK_COLOR_TEXT];
14547  edit->text_hover = table[NK_COLOR_TEXT];
14548  edit->text_active = table[NK_COLOR_TEXT];
14549  edit->selected_normal = table[NK_COLOR_TEXT];
14550  edit->selected_hover = table[NK_COLOR_TEXT];
14551  edit->selected_text_normal = table[NK_COLOR_EDIT];
14552  edit->selected_text_hover = table[NK_COLOR_EDIT];
14553  edit->scrollbar_size = nk_vec2(10,10);
14554  edit->scrollbar = style->scrollv;
14555  edit->padding = nk_vec2(4,4);
14556  edit->row_padding = 2;
14557  edit->cursor_size = 4;
14558  edit->border = 1;
14559  edit->rounding = 0;
14560 
14561  /* property */
14562  property = &style->property;
14563  nk_zero_struct(*property);
14564  property->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14565  property->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14566  property->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14567  property->border_color = table[NK_COLOR_BORDER];
14568  property->label_normal = table[NK_COLOR_TEXT];
14569  property->label_hover = table[NK_COLOR_TEXT];
14570  property->label_active = table[NK_COLOR_TEXT];
14571  property->sym_left = NK_SYMBOL_TRIANGLE_LEFT;
14572  property->sym_right = NK_SYMBOL_TRIANGLE_RIGHT;
14573  property->userdata = nk_handle_ptr(0);
14574  property->padding = nk_vec2(4,4);
14575  property->border = 1;
14576  property->rounding = 10;
14577  property->draw_begin = 0;
14578  property->draw_end = 0;
14579 
14580  /* property buttons */
14581  button = &style->property.dec_button;
14582  nk_zero_struct(*button);
14583  button->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14584  button->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14585  button->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14586  button->border_color = nk_rgba(0,0,0,0);
14587  button->text_background = table[NK_COLOR_PROPERTY];
14588  button->text_normal = table[NK_COLOR_TEXT];
14589  button->text_hover = table[NK_COLOR_TEXT];
14590  button->text_active = table[NK_COLOR_TEXT];
14591  button->padding = nk_vec2(0.0f,0.0f);
14592  button->touch_padding = nk_vec2(0.0f,0.0f);
14593  button->userdata = nk_handle_ptr(0);
14594  button->text_alignment = NK_TEXT_CENTERED;
14595  button->border = 0.0f;
14596  button->rounding = 0.0f;
14597  button->draw_begin = 0;
14598  button->draw_end = 0;
14599  style->property.inc_button = style->property.dec_button;
14600 
14601  /* property edit */
14602  edit = &style->property.edit;
14603  nk_zero_struct(*edit);
14607  edit->border_color = nk_rgba(0,0,0,0);
14608  edit->cursor_normal = table[NK_COLOR_TEXT];
14609  edit->cursor_hover = table[NK_COLOR_TEXT];
14610  edit->cursor_text_normal= table[NK_COLOR_EDIT];
14611  edit->cursor_text_hover = table[NK_COLOR_EDIT];
14612  edit->text_normal = table[NK_COLOR_TEXT];
14613  edit->text_hover = table[NK_COLOR_TEXT];
14614  edit->text_active = table[NK_COLOR_TEXT];
14615  edit->selected_normal = table[NK_COLOR_TEXT];
14616  edit->selected_hover = table[NK_COLOR_TEXT];
14617  edit->selected_text_normal = table[NK_COLOR_EDIT];
14618  edit->selected_text_hover = table[NK_COLOR_EDIT];
14619  edit->padding = nk_vec2(0,0);
14620  edit->cursor_size = 8;
14621  edit->border = 0;
14622  edit->rounding = 0;
14623 
14624  /* chart */
14625  chart = &style->chart;
14626  nk_zero_struct(*chart);
14628  chart->border_color = table[NK_COLOR_BORDER];
14630  chart->color = table[NK_COLOR_CHART_COLOR];
14631  chart->padding = nk_vec2(4,4);
14632  chart->border = 0;
14633  chart->rounding = 0;
14634 
14635  /* combo */
14636  combo = &style->combo;
14637  combo->normal = nk_style_item_color(table[NK_COLOR_COMBO]);
14638  combo->hover = nk_style_item_color(table[NK_COLOR_COMBO]);
14639  combo->active = nk_style_item_color(table[NK_COLOR_COMBO]);
14640  combo->border_color = table[NK_COLOR_BORDER];
14641  combo->label_normal = table[NK_COLOR_TEXT];
14642  combo->label_hover = table[NK_COLOR_TEXT];
14643  combo->label_active = table[NK_COLOR_TEXT];
14647  combo->content_padding = nk_vec2(4,4);
14648  combo->button_padding = nk_vec2(0,4);
14649  combo->spacing = nk_vec2(4,0);
14650  combo->border = 1;
14651  combo->rounding = 0;
14652 
14653  /* combo button */
14654  button = &style->combo.button;
14655  nk_zero_struct(*button);
14656  button->normal = nk_style_item_color(table[NK_COLOR_COMBO]);
14657  button->hover = nk_style_item_color(table[NK_COLOR_COMBO]);
14658  button->active = nk_style_item_color(table[NK_COLOR_COMBO]);
14659  button->border_color = nk_rgba(0,0,0,0);
14660  button->text_background = table[NK_COLOR_COMBO];
14661  button->text_normal = table[NK_COLOR_TEXT];
14662  button->text_hover = table[NK_COLOR_TEXT];
14663  button->text_active = table[NK_COLOR_TEXT];
14664  button->padding = nk_vec2(2.0f,2.0f);
14665  button->touch_padding = nk_vec2(0.0f,0.0f);
14666  button->userdata = nk_handle_ptr(0);
14667  button->text_alignment = NK_TEXT_CENTERED;
14668  button->border = 0.0f;
14669  button->rounding = 0.0f;
14670  button->draw_begin = 0;
14671  button->draw_end = 0;
14672 
14673  /* tab */
14674  tab = &style->tab;
14676  tab->border_color = table[NK_COLOR_BORDER];
14677  tab->text = table[NK_COLOR_TEXT];
14680  tab->padding = nk_vec2(4,4);
14681  tab->spacing = nk_vec2(4,4);
14682  tab->indent = 10.0f;
14683  tab->border = 1;
14684  tab->rounding = 0;
14685 
14686  /* tab button */
14687  button = &style->tab.tab_minimize_button;
14688  nk_zero_struct(*button);
14690  button->hover = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
14692  button->border_color = nk_rgba(0,0,0,0);
14693  button->text_background = table[NK_COLOR_TAB_HEADER];
14694  button->text_normal = table[NK_COLOR_TEXT];
14695  button->text_hover = table[NK_COLOR_TEXT];
14696  button->text_active = table[NK_COLOR_TEXT];
14697  button->padding = nk_vec2(2.0f,2.0f);
14698  button->touch_padding = nk_vec2(0.0f,0.0f);
14699  button->userdata = nk_handle_ptr(0);
14700  button->text_alignment = NK_TEXT_CENTERED;
14701  button->border = 0.0f;
14702  button->rounding = 0.0f;
14703  button->draw_begin = 0;
14704  button->draw_end = 0;
14705  style->tab.tab_maximize_button =*button;
14706 
14707  /* node button */
14708  button = &style->tab.node_minimize_button;
14709  nk_zero_struct(*button);
14710  button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
14711  button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]);
14712  button->active = nk_style_item_color(table[NK_COLOR_WINDOW]);
14713  button->border_color = nk_rgba(0,0,0,0);
14714  button->text_background = table[NK_COLOR_TAB_HEADER];
14715  button->text_normal = table[NK_COLOR_TEXT];
14716  button->text_hover = table[NK_COLOR_TEXT];
14717  button->text_active = table[NK_COLOR_TEXT];
14718  button->padding = nk_vec2(2.0f,2.0f);
14719  button->touch_padding = nk_vec2(0.0f,0.0f);
14720  button->userdata = nk_handle_ptr(0);
14721  button->text_alignment = NK_TEXT_CENTERED;
14722  button->border = 0.0f;
14723  button->rounding = 0.0f;
14724  button->draw_begin = 0;
14725  button->draw_end = 0;
14726  style->tab.node_maximize_button =*button;
14727 
14728  /* window header */
14729  win = &style->window;
14730  win->header.align = NK_HEADER_RIGHT;
14731  win->header.close_symbol = NK_SYMBOL_X;
14732  win->header.minimize_symbol = NK_SYMBOL_MINUS;
14733  win->header.maximize_symbol = NK_SYMBOL_PLUS;
14734  win->header.normal = nk_style_item_color(table[NK_COLOR_HEADER]);
14735  win->header.hover = nk_style_item_color(table[NK_COLOR_HEADER]);
14736  win->header.active = nk_style_item_color(table[NK_COLOR_HEADER]);
14737  win->header.label_normal = table[NK_COLOR_TEXT];
14738  win->header.label_hover = table[NK_COLOR_TEXT];
14739  win->header.label_active = table[NK_COLOR_TEXT];
14740  win->header.label_padding = nk_vec2(4,4);
14741  win->header.padding = nk_vec2(4,4);
14742  win->header.spacing = nk_vec2(0,0);
14743 
14744  /* window header close button */
14745  button = &style->window.header.close_button;
14746  nk_zero_struct(*button);
14747  button->normal = nk_style_item_color(table[NK_COLOR_HEADER]);
14748  button->hover = nk_style_item_color(table[NK_COLOR_HEADER]);
14749  button->active = nk_style_item_color(table[NK_COLOR_HEADER]);
14750  button->border_color = nk_rgba(0,0,0,0);
14751  button->text_background = table[NK_COLOR_HEADER];
14752  button->text_normal = table[NK_COLOR_TEXT];
14753  button->text_hover = table[NK_COLOR_TEXT];
14754  button->text_active = table[NK_COLOR_TEXT];
14755  button->padding = nk_vec2(0.0f,0.0f);
14756  button->touch_padding = nk_vec2(0.0f,0.0f);
14757  button->userdata = nk_handle_ptr(0);
14758  button->text_alignment = NK_TEXT_CENTERED;
14759  button->border = 0.0f;
14760  button->rounding = 0.0f;
14761  button->draw_begin = 0;
14762  button->draw_end = 0;
14763 
14764  /* window header minimize button */
14765  button = &style->window.header.minimize_button;
14766  nk_zero_struct(*button);
14767  button->normal = nk_style_item_color(table[NK_COLOR_HEADER]);
14768  button->hover = nk_style_item_color(table[NK_COLOR_HEADER]);
14769  button->active = nk_style_item_color(table[NK_COLOR_HEADER]);
14770  button->border_color = nk_rgba(0,0,0,0);
14771  button->text_background = table[NK_COLOR_HEADER];
14772  button->text_normal = table[NK_COLOR_TEXT];
14773  button->text_hover = table[NK_COLOR_TEXT];
14774  button->text_active = table[NK_COLOR_TEXT];
14775  button->padding = nk_vec2(0.0f,0.0f);
14776  button->touch_padding = nk_vec2(0.0f,0.0f);
14777  button->userdata = nk_handle_ptr(0);
14778  button->text_alignment = NK_TEXT_CENTERED;
14779  button->border = 0.0f;
14780  button->rounding = 0.0f;
14781  button->draw_begin = 0;
14782  button->draw_end = 0;
14783 
14784  /* window */
14785  win->background = table[NK_COLOR_WINDOW];
14786  win->fixed_background = nk_style_item_color(table[NK_COLOR_WINDOW]);
14787  win->border_color = table[NK_COLOR_BORDER];
14788  win->popup_border_color = table[NK_COLOR_BORDER];
14789  win->combo_border_color = table[NK_COLOR_BORDER];
14790  win->contextual_border_color = table[NK_COLOR_BORDER];
14791  win->menu_border_color = table[NK_COLOR_BORDER];
14792  win->group_border_color = table[NK_COLOR_BORDER];
14793  win->tooltip_border_color = table[NK_COLOR_BORDER];
14794  win->scaler = nk_style_item_color(table[NK_COLOR_TEXT]);
14795 
14796  win->rounding = 0.0f;
14797  win->spacing = nk_vec2(4,4);
14798  win->scrollbar_size = nk_vec2(10,10);
14799  win->min_size = nk_vec2(64,64);
14800 
14801  win->combo_border = 1.0f;
14802  win->contextual_border = 1.0f;
14803  win->menu_border = 1.0f;
14804  win->group_border = 1.0f;
14805  win->tooltip_border = 1.0f;
14806  win->popup_border = 1.0f;
14807  win->border = 2.0f;
14808  win->min_row_height_padding = 8;
14809 
14810  win->padding = nk_vec2(4,4);
14811  win->group_padding = nk_vec2(4,4);
14812  win->popup_padding = nk_vec2(4,4);
14813  win->combo_padding = nk_vec2(4,4);
14814  win->contextual_padding = nk_vec2(4,4);
14815  win->menu_padding = nk_vec2(4,4);
14816  win->tooltip_padding = nk_vec2(4,4);
14817 }
14818 NK_API void
14819 nk_style_set_font(struct nk_context *ctx, const struct nk_user_font *font)
14820 {
14821  struct nk_style *style;
14822  NK_ASSERT(ctx);
14823 
14824  if (!ctx) return;
14825  style = &ctx->style;
14826  style->font = font;
14827  ctx->stacks.fonts.head = 0;
14828  if (ctx->current)
14830 }
14831 NK_API int
14832 nk_style_push_font(struct nk_context *ctx, const struct nk_user_font *font)
14833 {
14834  struct nk_config_stack_user_font *font_stack;
14835  struct nk_config_stack_user_font_element *element;
14836 
14837  NK_ASSERT(ctx);
14838  if (!ctx) return 0;
14839 
14840  font_stack = &ctx->stacks.fonts;
14841  NK_ASSERT(font_stack->head < (int)NK_LEN(font_stack->elements));
14842  if (font_stack->head >= (int)NK_LEN(font_stack->elements))
14843  return 0;
14844 
14845  element = &font_stack->elements[font_stack->head++];
14846  element->address = &ctx->style.font;
14847  element->old_value = ctx->style.font;
14848  ctx->style.font = font;
14849  return 1;
14850 }
14851 NK_API int
14852 nk_style_pop_font(struct nk_context *ctx)
14853 {
14854  struct nk_config_stack_user_font *font_stack;
14855  struct nk_config_stack_user_font_element *element;
14856 
14857  NK_ASSERT(ctx);
14858  if (!ctx) return 0;
14859 
14860  font_stack = &ctx->stacks.fonts;
14861  NK_ASSERT(font_stack->head > 0);
14862  if (font_stack->head < 1)
14863  return 0;
14864 
14865  element = &font_stack->elements[--font_stack->head];
14866  *element->address = element->old_value;
14867  return 1;
14868 }
14869 #define NK_STYLE_PUSH_IMPLEMENATION(prefix, type, stack) \
14870 nk_style_push_##type(struct nk_context *ctx, prefix##_##type *address, prefix##_##type value)\
14871 {\
14872  struct nk_config_stack_##type * type_stack;\
14873  struct nk_config_stack_##type##_element *element;\
14874  NK_ASSERT(ctx);\
14875  if (!ctx) return 0;\
14876  type_stack = &ctx->stacks.stack;\
14877  NK_ASSERT(type_stack->head < (int)NK_LEN(type_stack->elements));\
14878  if (type_stack->head >= (int)NK_LEN(type_stack->elements))\
14879  return 0;\
14880  element = &type_stack->elements[type_stack->head++];\
14881  element->address = address;\
14882  element->old_value = *address;\
14883  *address = value;\
14884  return 1;\
14885 }
14886 #define NK_STYLE_POP_IMPLEMENATION(type, stack) \
14887 nk_style_pop_##type(struct nk_context *ctx)\
14888 {\
14889  struct nk_config_stack_##type *type_stack;\
14890  struct nk_config_stack_##type##_element *element;\
14891  NK_ASSERT(ctx);\
14892  if (!ctx) return 0;\
14893  type_stack = &ctx->stacks.stack;\
14894  NK_ASSERT(type_stack->head > 0);\
14895  if (type_stack->head < 1)\
14896  return 0;\
14897  element = &type_stack->elements[--type_stack->head];\
14898  *element->address = element->old_value;\
14899  return 1;\
14900 }
14901 NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk, style_item, style_items)
14902 NK_API int NK_STYLE_PUSH_IMPLEMENATION(nk,float, floats)
14903 NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk, vec2, vectors)
14904 NK_API int NK_STYLE_PUSH_IMPLEMENATION(nk,flags, flags)
14905 NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk,color, colors)
14906 
14907 NK_API int NK_STYLE_POP_IMPLEMENATION(style_item, style_items)
14908 NK_API int NK_STYLE_POP_IMPLEMENATION(float,floats)
14909 NK_API int NK_STYLE_POP_IMPLEMENATION(vec2, vectors)
14910 NK_API int NK_STYLE_POP_IMPLEMENATION(flags,flags)
14911 NK_API int NK_STYLE_POP_IMPLEMENATION(color,colors)
14912 
14913 NK_API int
14914 nk_style_set_cursor(struct nk_context *ctx, enum nk_style_cursor c)
14915 {
14916  struct nk_style *style;
14917  NK_ASSERT(ctx);
14918  if (!ctx) return 0;
14919  style = &ctx->style;
14920  if (style->cursors[c]) {
14921  style->cursor_active = style->cursors[c];
14922  return 1;
14923  }
14924  return 0;
14925 }
14926 NK_API void
14927 nk_style_show_cursor(struct nk_context *ctx)
14928 {
14929  ctx->style.cursor_visible = nk_true;
14930 }
14931 NK_API void
14932 nk_style_hide_cursor(struct nk_context *ctx)
14933 {
14934  ctx->style.cursor_visible = nk_false;
14935 }
14936 NK_API void
14937 nk_style_load_cursor(struct nk_context *ctx, enum nk_style_cursor cursor,
14938  const struct nk_cursor *c)
14939 {
14940  struct nk_style *style;
14941  NK_ASSERT(ctx);
14942  if (!ctx) return;
14943  style = &ctx->style;
14944  style->cursors[cursor] = c;
14945 }
14946 NK_API void
14948 {
14949  int i = 0;
14950  struct nk_style *style;
14951  NK_ASSERT(ctx);
14952  if (!ctx) return;
14953  style = &ctx->style;
14954  for (i = 0; i < NK_CURSOR_COUNT; ++i)
14955  style->cursors[i] = &cursors[i];
14956  style->cursor_visible = nk_true;
14957 }
14958 
14959 
14960 
14961 
14962 
14963 /* ==============================================================
14964  *
14965  * CONTEXT
14966  *
14967  * ===============================================================*/
14968 NK_INTERN void
14969 nk_setup(struct nk_context *ctx, const struct nk_user_font *font)
14970 {
14971  NK_ASSERT(ctx);
14972  if (!ctx) return;
14973  nk_zero_struct(*ctx);
14974  nk_style_default(ctx);
14975  ctx->seq = 1;
14976  if (font) ctx->style.font = font;
14977 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
14978  nk_draw_list_init(&ctx->draw_list);
14979 #endif
14980 }
14981 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
14982 NK_API int
14983 nk_init_default(struct nk_context *ctx, const struct nk_user_font *font)
14984 {
14985  struct nk_allocator alloc;
14986  alloc.userdata.ptr = 0;
14987  alloc.alloc = nk_malloc;
14988  alloc.free = nk_mfree;
14989  return nk_init(ctx, &alloc, font);
14990 }
14991 #endif
14992 NK_API int
14993 nk_init_fixed(struct nk_context *ctx, void *memory, nk_size size,
14994  const struct nk_user_font *font)
14995 {
14996  NK_ASSERT(memory);
14997  if (!memory) return 0;
14998  nk_setup(ctx, font);
14999  nk_buffer_init_fixed(&ctx->memory, memory, size);
15000  ctx->use_pool = nk_false;
15001  return 1;
15002 }
15003 NK_API int
15004 nk_init_custom(struct nk_context *ctx, struct nk_buffer *cmds,
15005  struct nk_buffer *pool, const struct nk_user_font *font)
15006 {
15007  NK_ASSERT(cmds);
15008  NK_ASSERT(pool);
15009  if (!cmds || !pool) return 0;
15010 
15011  nk_setup(ctx, font);
15012  ctx->memory = *cmds;
15013  if (pool->type == NK_BUFFER_FIXED) {
15014  /* take memory from buffer and alloc fixed pool */
15015  nk_pool_init_fixed(&ctx->pool, pool->memory.ptr, pool->memory.size);
15016  } else {
15017  /* create dynamic pool from buffer allocator */
15018  struct nk_allocator *alloc = &pool->pool;
15019  nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
15020  }
15021  ctx->use_pool = nk_true;
15022  return 1;
15023 }
15024 NK_API int
15025 nk_init(struct nk_context *ctx, struct nk_allocator *alloc,
15026  const struct nk_user_font *font)
15027 {
15028  NK_ASSERT(alloc);
15029  if (!alloc) return 0;
15030  nk_setup(ctx, font);
15031  nk_buffer_init(&ctx->memory, alloc, NK_DEFAULT_COMMAND_BUFFER_SIZE);
15032  nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
15033  ctx->use_pool = nk_true;
15034  return 1;
15035 }
15036 #ifdef NK_INCLUDE_COMMAND_USERDATA
15037 NK_API void
15038 nk_set_user_data(struct nk_context *ctx, nk_handle handle)
15039 {
15040  if (!ctx) return;
15041  ctx->userdata = handle;
15042  if (ctx->current)
15043  ctx->current->buffer.userdata = handle;
15044 }
15045 #endif
15046 NK_API void
15047 nk_free(struct nk_context *ctx)
15048 {
15049  NK_ASSERT(ctx);
15050  if (!ctx) return;
15051  nk_buffer_free(&ctx->memory);
15052  if (ctx->use_pool)
15053  nk_pool_free(&ctx->pool);
15054 
15055  nk_zero(&ctx->input, sizeof(ctx->input));
15056  nk_zero(&ctx->style, sizeof(ctx->style));
15057  nk_zero(&ctx->memory, sizeof(ctx->memory));
15058 
15059  ctx->seq = 0;
15060  ctx->build = 0;
15061  ctx->begin = 0;
15062  ctx->end = 0;
15063  ctx->active = 0;
15064  ctx->current = 0;
15065  ctx->freelist = 0;
15066  ctx->count = 0;
15067 }
15068 NK_API void
15069 nk_clear(struct nk_context *ctx)
15070 {
15071  struct nk_window *iter;
15072  struct nk_window *next;
15073  NK_ASSERT(ctx);
15074 
15075  if (!ctx) return;
15076  if (ctx->use_pool)
15077  nk_buffer_clear(&ctx->memory);
15078  else nk_buffer_reset(&ctx->memory, NK_BUFFER_FRONT);
15079 
15080  ctx->build = 0;
15081  ctx->memory.calls = 0;
15082  ctx->last_widget_state = 0;
15084  NK_MEMSET(&ctx->overlay, 0, sizeof(ctx->overlay));
15085 
15086  /* garbage collector */
15087  iter = ctx->begin;
15088  while (iter) {
15089  /* make sure valid minimized windows do not get removed */
15090  if ((iter->flags & NK_WINDOW_MINIMIZED) &&
15091  !(iter->flags & NK_WINDOW_CLOSED) &&
15092  iter->seq == ctx->seq) {
15093  iter = iter->next;
15094  continue;
15095  }
15096  /* remove hotness from hidden or closed windows*/
15097  if (((iter->flags & NK_WINDOW_HIDDEN) ||
15098  (iter->flags & NK_WINDOW_CLOSED)) &&
15099  iter == ctx->active) {
15100  ctx->active = iter->prev;
15101  ctx->end = iter->prev;
15102  if (!ctx->end)
15103  ctx->begin = 0;
15104  if (ctx->active)
15105  ctx->active->flags &= ~(unsigned)NK_WINDOW_ROM;
15106  }
15107  /* free unused popup windows */
15108  if (iter->popup.win && iter->popup.win->seq != ctx->seq) {
15109  nk_free_window(ctx, iter->popup.win);
15110  iter->popup.win = 0;
15111  }
15112  /* remove unused window state tables */
15113  {struct nk_table *n, *it = iter->tables;
15114  while (it) {
15115  n = it->next;
15116  if (it->seq != ctx->seq) {
15117  nk_remove_table(iter, it);
15118  nk_zero(it, sizeof(union nk_page_data));
15119  nk_free_table(ctx, it);
15120  if (it == iter->tables)
15121  iter->tables = n;
15122  } it = n;
15123  }}
15124  /* window itself is not used anymore so free */
15125  if (iter->seq != ctx->seq || iter->flags & NK_WINDOW_CLOSED) {
15126  next = iter->next;
15127  nk_remove_window(ctx, iter);
15128  nk_free_window(ctx, iter);
15129  iter = next;
15130  } else iter = iter->next;
15131  }
15132  ctx->seq++;
15133 }
15134 NK_LIB void
15135 nk_start_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer)
15136 {
15137  NK_ASSERT(ctx);
15138  NK_ASSERT(buffer);
15139  if (!ctx || !buffer) return;
15140  buffer->begin = ctx->memory.allocated;
15141  buffer->end = buffer->begin;
15142  buffer->last = buffer->begin;
15143  buffer->clip = nk_null_rect;
15144 }
15145 NK_LIB void
15146 nk_start(struct nk_context *ctx, struct nk_window *win)
15147 {
15148  NK_ASSERT(ctx);
15149  NK_ASSERT(win);
15150  nk_start_buffer(ctx, &win->buffer);
15151 }
15152 NK_LIB void
15153 nk_start_popup(struct nk_context *ctx, struct nk_window *win)
15154 {
15155  struct nk_popup_buffer *buf;
15156  NK_ASSERT(ctx);
15157  NK_ASSERT(win);
15158  if (!ctx || !win) return;
15159 
15160  /* save buffer fill state for popup */
15161  buf = &win->popup.buf;
15162  buf->begin = win->buffer.end;
15163  buf->end = win->buffer.end;
15164  buf->parent = win->buffer.last;
15165  buf->last = buf->begin;
15166  buf->active = nk_true;
15167 }
15168 NK_LIB void
15169 nk_finish_popup(struct nk_context *ctx, struct nk_window *win)
15170 {
15171  struct nk_popup_buffer *buf;
15172  NK_ASSERT(ctx);
15173  NK_ASSERT(win);
15174  if (!ctx || !win) return;
15175 
15176  buf = &win->popup.buf;
15177  buf->last = win->buffer.last;
15178  buf->end = win->buffer.end;
15179 }
15180 NK_LIB void
15181 nk_finish_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer)
15182 {
15183  NK_ASSERT(ctx);
15184  NK_ASSERT(buffer);
15185  if (!ctx || !buffer) return;
15186  buffer->end = ctx->memory.allocated;
15187 }
15188 NK_LIB void
15189 nk_finish(struct nk_context *ctx, struct nk_window *win)
15190 {
15191  struct nk_popup_buffer *buf;
15192  struct nk_command *parent_last;
15193  void *memory;
15194 
15195  NK_ASSERT(ctx);
15196  NK_ASSERT(win);
15197  if (!ctx || !win) return;
15198  nk_finish_buffer(ctx, &win->buffer);
15199  if (!win->popup.buf.active) return;
15200 
15201  buf = &win->popup.buf;
15202  memory = ctx->memory.memory.ptr;
15203  parent_last = nk_ptr_add(struct nk_command, memory, buf->parent);
15204  parent_last->next = buf->end;
15205 }
15206 NK_LIB void
15207 nk_build(struct nk_context *ctx)
15208 {
15209  struct nk_window *it = 0;
15210  struct nk_command *cmd = 0;
15211  nk_byte *buffer = 0;
15212 
15213  /* draw cursor overlay */
15214  if (!ctx->style.cursor_active)
15216  if (ctx->style.cursor_active && !ctx->input.mouse.grabbed && ctx->style.cursor_visible) {
15217  struct nk_rect mouse_bounds;
15218  const struct nk_cursor *cursor = ctx->style.cursor_active;
15219  nk_command_buffer_init(&ctx->overlay, &ctx->memory, NK_CLIPPING_OFF);
15220  nk_start_buffer(ctx, &ctx->overlay);
15221 
15222  mouse_bounds.x = ctx->input.mouse.pos.x - cursor->offset.x;
15223  mouse_bounds.y = ctx->input.mouse.pos.y - cursor->offset.y;
15224  mouse_bounds.w = cursor->size.x;
15225  mouse_bounds.h = cursor->size.y;
15226 
15227  nk_draw_image(&ctx->overlay, mouse_bounds, &cursor->img, nk_white);
15228  nk_finish_buffer(ctx, &ctx->overlay);
15229  }
15230  /* build one big draw command list out of all window buffers */
15231  it = ctx->begin;
15232  buffer = (nk_byte*)ctx->memory.memory.ptr;
15233  while (it != 0) {
15234  struct nk_window *next = it->next;
15235  if (it->buffer.last == it->buffer.begin || (it->flags & NK_WINDOW_HIDDEN)||
15236  it->seq != ctx->seq)
15237  goto cont;
15238 
15239  cmd = nk_ptr_add(struct nk_command, buffer, it->buffer.last);
15240  while (next && ((next->buffer.last == next->buffer.begin) ||
15241  (next->flags & NK_WINDOW_HIDDEN) || next->seq != ctx->seq))
15242  next = next->next; /* skip empty command buffers */
15243 
15244  if (next) cmd->next = next->buffer.begin;
15245  cont: it = next;
15246  }
15247  /* append all popup draw commands into lists */
15248  it = ctx->begin;
15249  while (it != 0) {
15250  struct nk_window *next = it->next;
15251  struct nk_popup_buffer *buf;
15252  if (!it->popup.buf.active)
15253  goto skip;
15254 
15255  buf = &it->popup.buf;
15256  cmd->next = buf->begin;
15257  cmd = nk_ptr_add(struct nk_command, buffer, buf->last);
15258  buf->active = nk_false;
15259  skip: it = next;
15260  }
15261  if (cmd) {
15262  /* append overlay commands */
15263  if (ctx->overlay.end != ctx->overlay.begin)
15264  cmd->next = ctx->overlay.begin;
15265  else cmd->next = ctx->memory.allocated;
15266  }
15267 }
15268 NK_API const struct nk_command*
15269 nk__begin(struct nk_context *ctx)
15270 {
15271  struct nk_window *iter;
15272  nk_byte *buffer;
15273  NK_ASSERT(ctx);
15274  if (!ctx) return 0;
15275  if (!ctx->count) return 0;
15276 
15277  buffer = (nk_byte*)ctx->memory.memory.ptr;
15278  if (!ctx->build) {
15279  nk_build(ctx);
15280  ctx->build = nk_true;
15281  }
15282  iter = ctx->begin;
15283  while (iter && ((iter->buffer.begin == iter->buffer.end) ||
15284  (iter->flags & NK_WINDOW_HIDDEN) || iter->seq != ctx->seq))
15285  iter = iter->next;
15286  if (!iter) return 0;
15287  return nk_ptr_add_const(struct nk_command, buffer, iter->buffer.begin);
15288 }
15289 
15290 NK_API const struct nk_command*
15291 nk__next(struct nk_context *ctx, const struct nk_command *cmd)
15292 {
15293  nk_byte *buffer;
15294  const struct nk_command *next;
15295  NK_ASSERT(ctx);
15296  if (!ctx || !cmd || !ctx->count) return 0;
15297  if (cmd->next >= ctx->memory.allocated) return 0;
15298  buffer = (nk_byte*)ctx->memory.memory.ptr;
15299  next = nk_ptr_add_const(struct nk_command, buffer, cmd->next);
15300  return next;
15301 }
15302 
15303 
15304 
15305 
15306 
15307 
15308 /* ===============================================================
15309  *
15310  * POOL
15311  *
15312  * ===============================================================*/
15313 NK_LIB void
15314 nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc,
15315  unsigned int capacity)
15316 {
15317  nk_zero(pool, sizeof(*pool));
15318  pool->alloc = *alloc;
15319  pool->capacity = capacity;
15320  pool->type = NK_BUFFER_DYNAMIC;
15321  pool->pages = 0;
15322 }
15323 NK_LIB void
15324 nk_pool_free(struct nk_pool *pool)
15325 {
15326  struct nk_page *iter = pool->pages;
15327  if (!pool) return;
15328  if (pool->type == NK_BUFFER_FIXED) return;
15329  while (iter) {
15330  struct nk_page *next = iter->next;
15331  pool->alloc.free(pool->alloc.userdata, iter);
15332  iter = next;
15333  }
15334 }
15335 NK_LIB void
15336 nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size)
15337 {
15338  nk_zero(pool, sizeof(*pool));
15339  NK_ASSERT(size >= sizeof(struct nk_page));
15340  if (size < sizeof(struct nk_page)) return;
15341  pool->capacity = (unsigned)(size - sizeof(struct nk_page)) / sizeof(struct nk_page_element);
15342  pool->pages = (struct nk_page*)memory;
15343  pool->type = NK_BUFFER_FIXED;
15344  pool->size = size;
15345 }
15346 NK_LIB struct nk_page_element*
15347 nk_pool_alloc(struct nk_pool *pool)
15348 {
15349  if (!pool->pages || pool->pages->size >= pool->capacity) {
15350  /* allocate new page */
15351  struct nk_page *page;
15352  if (pool->type == NK_BUFFER_FIXED) {
15353  NK_ASSERT(pool->pages);
15354  if (!pool->pages) return 0;
15355  NK_ASSERT(pool->pages->size < pool->capacity);
15356  return 0;
15357  } else {
15358  nk_size size = sizeof(struct nk_page);
15359  size += NK_POOL_DEFAULT_CAPACITY * sizeof(union nk_page_data);
15360  page = (struct nk_page*)pool->alloc.alloc(pool->alloc.userdata,0, size);
15361  page->next = pool->pages;
15362  pool->pages = page;
15363  page->size = 0;
15364  }
15365  } return &pool->pages->win[pool->pages->size++];
15366 }
15367 
15368 
15369 
15370 
15371 
15372 /* ===============================================================
15373  *
15374  * PAGE ELEMENT
15375  *
15376  * ===============================================================*/
15377 NK_LIB struct nk_page_element*
15378 nk_create_page_element(struct nk_context *ctx)
15379 {
15380  struct nk_page_element *elem;
15381  if (ctx->freelist) {
15382  /* unlink page element from free list */
15383  elem = ctx->freelist;
15384  ctx->freelist = elem->next;
15385  } else if (ctx->use_pool) {
15386  /* allocate page element from memory pool */
15387  elem = nk_pool_alloc(&ctx->pool);
15388  NK_ASSERT(elem);
15389  if (!elem) return 0;
15390  } else {
15391  /* allocate new page element from back of fixed size memory buffer */
15392  NK_STORAGE const nk_size size = sizeof(struct nk_page_element);
15393  NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_page_element);
15394  elem = (struct nk_page_element*)nk_buffer_alloc(&ctx->memory, NK_BUFFER_BACK, size, align);
15395  NK_ASSERT(elem);
15396  if (!elem) return 0;
15397  }
15398  nk_zero_struct(*elem);
15399  elem->next = 0;
15400  elem->prev = 0;
15401  return elem;
15402 }
15403 NK_LIB void
15404 nk_link_page_element_into_freelist(struct nk_context *ctx,
15405  struct nk_page_element *elem)
15406 {
15407  /* link table into freelist */
15408  if (!ctx->freelist) {
15409  ctx->freelist = elem;
15410  } else {
15411  elem->next = ctx->freelist;
15412  ctx->freelist = elem;
15413  }
15414 }
15415 NK_LIB void
15416 nk_free_page_element(struct nk_context *ctx, struct nk_page_element *elem)
15417 {
15418  /* we have a pool so just add to free list */
15419  if (ctx->use_pool) {
15420  nk_link_page_element_into_freelist(ctx, elem);
15421  return;
15422  }
15423  /* if possible remove last element from back of fixed memory buffer */
15424  {void *elem_end = (void*)(elem + 1);
15425  void *buffer_end = (nk_byte*)ctx->memory.memory.ptr + ctx->memory.size;
15426  if (elem_end == buffer_end)
15427  ctx->memory.size -= sizeof(struct nk_page_element);
15428  else nk_link_page_element_into_freelist(ctx, elem);}
15429 }
15430 
15431 
15432 
15433 
15434 
15435 /* ===============================================================
15436  *
15437  * TABLE
15438  *
15439  * ===============================================================*/
15440 NK_LIB struct nk_table*
15441 nk_create_table(struct nk_context *ctx)
15442 {
15443  struct nk_page_element *elem;
15444  elem = nk_create_page_element(ctx);
15445  if (!elem) return 0;
15446  nk_zero_struct(*elem);
15447  return &elem->data.tbl;
15448 }
15449 NK_LIB void
15450 nk_free_table(struct nk_context *ctx, struct nk_table *tbl)
15451 {
15452  union nk_page_data *pd = NK_CONTAINER_OF(tbl, union nk_page_data, tbl);
15453  struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
15454  nk_free_page_element(ctx, pe);
15455 }
15456 NK_LIB void
15457 nk_push_table(struct nk_window *win, struct nk_table *tbl)
15458 {
15459  if (!win->tables) {
15460  win->tables = tbl;
15461  tbl->next = 0;
15462  tbl->prev = 0;
15463  tbl->size = 0;
15464  win->table_count = 1;
15465  return;
15466  }
15467  win->tables->prev = tbl;
15468  tbl->next = win->tables;
15469  tbl->prev = 0;
15470  tbl->size = 0;
15471  win->tables = tbl;
15472  win->table_count++;
15473 }
15474 NK_LIB void
15475 nk_remove_table(struct nk_window *win, struct nk_table *tbl)
15476 {
15477  if (win->tables == tbl)
15478  win->tables = tbl->next;
15479  if (tbl->next)
15480  tbl->next->prev = tbl->prev;
15481  if (tbl->prev)
15482  tbl->prev->next = tbl->next;
15483  tbl->next = 0;
15484  tbl->prev = 0;
15485 }
15486 NK_LIB nk_uint*
15487 nk_add_value(struct nk_context *ctx, struct nk_window *win,
15488  nk_hash name, nk_uint value)
15489 {
15490  NK_ASSERT(ctx);
15491  NK_ASSERT(win);
15492  if (!win || !ctx) return 0;
15493  if (!win->tables || win->tables->size >= NK_VALUE_PAGE_CAPACITY) {
15494  struct nk_table *tbl = nk_create_table(ctx);
15495  NK_ASSERT(tbl);
15496  if (!tbl) return 0;
15497  nk_push_table(win, tbl);
15498  }
15499  win->tables->seq = win->seq;
15500  win->tables->keys[win->tables->size] = name;
15501  win->tables->values[win->tables->size] = value;
15502  return &win->tables->values[win->tables->size++];
15503 }
15504 NK_LIB nk_uint*
15505 nk_find_value(struct nk_window *win, nk_hash name)
15506 {
15507  struct nk_table *iter = win->tables;
15508  while (iter) {
15509  unsigned int i = 0;
15510  unsigned int size = iter->size;
15511  for (i = 0; i < size; ++i) {
15512  if (iter->keys[i] == name) {
15513  iter->seq = win->seq;
15514  return &iter->values[i];
15515  }
15517  iter = iter->next;
15518  }
15519  return 0;
15520 }
15521 
15522 
15523 
15524 
15525 
15526 /* ===============================================================
15527  *
15528  * PANEL
15529  *
15530  * ===============================================================*/
15531 NK_LIB void*
15532 nk_create_panel(struct nk_context *ctx)
15533 {
15534  struct nk_page_element *elem;
15535  elem = nk_create_page_element(ctx);
15536  if (!elem) return 0;
15537  nk_zero_struct(*elem);
15538  return &elem->data.pan;
15539 }
15540 NK_LIB void
15541 nk_free_panel(struct nk_context *ctx, struct nk_panel *pan)
15542 {
15543  union nk_page_data *pd = NK_CONTAINER_OF(pan, union nk_page_data, pan);
15544  struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
15545  nk_free_page_element(ctx, pe);
15546 }
15547 NK_LIB int
15548 nk_panel_has_header(nk_flags flags, const char *title)
15549 {
15550  int active = 0;
15551  active = (flags & (NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE));
15552  active = active || (flags & NK_WINDOW_TITLE);
15553  active = active && !(flags & NK_WINDOW_HIDDEN) && title;
15554  return active;
15555 }
15556 NK_LIB struct nk_vec2
15557 nk_panel_get_padding(const struct nk_style *style, enum nk_panel_type type)
15558 {
15559  switch (type) {
15560  default:
15561  case NK_PANEL_WINDOW: return style->window.padding;
15562  case NK_PANEL_GROUP: return style->window.group_padding;
15563  case NK_PANEL_POPUP: return style->window.popup_padding;
15564  case NK_PANEL_CONTEXTUAL: return style->window.contextual_padding;
15565  case NK_PANEL_COMBO: return style->window.combo_padding;
15566  case NK_PANEL_MENU: return style->window.menu_padding;
15567  case NK_PANEL_TOOLTIP: return style->window.menu_padding;}
15568 }
15569 NK_LIB float
15570 nk_panel_get_border(const struct nk_style *style, nk_flags flags,
15571  enum nk_panel_type type)
15572 {
15573  if (flags & NK_WINDOW_BORDER) {
15574  switch (type) {
15575  default:
15576  case NK_PANEL_WINDOW: return style->window.border;
15577  case NK_PANEL_GROUP: return style->window.group_border;
15578  case NK_PANEL_POPUP: return style->window.popup_border;
15579  case NK_PANEL_CONTEXTUAL: return style->window.contextual_border;
15580  case NK_PANEL_COMBO: return style->window.combo_border;
15581  case NK_PANEL_MENU: return style->window.menu_border;
15582  case NK_PANEL_TOOLTIP: return style->window.menu_border;
15583  }} else return 0;
15584 }
15585 NK_LIB struct nk_color
15586 nk_panel_get_border_color(const struct nk_style *style, enum nk_panel_type type)
15587 {
15588  switch (type) {
15589  default:
15590  case NK_PANEL_WINDOW: return style->window.border_color;
15591  case NK_PANEL_GROUP: return style->window.group_border_color;
15592  case NK_PANEL_POPUP: return style->window.popup_border_color;
15593  case NK_PANEL_CONTEXTUAL: return style->window.contextual_border_color;
15594  case NK_PANEL_COMBO: return style->window.combo_border_color;
15595  case NK_PANEL_MENU: return style->window.menu_border_color;
15596  case NK_PANEL_TOOLTIP: return style->window.menu_border_color;}
15597 }
15598 NK_LIB int
15599 nk_panel_is_sub(enum nk_panel_type type)
15600 {
15601  return (type & NK_PANEL_SET_SUB)?1:0;
15602 }
15603 NK_LIB int
15604 nk_panel_is_nonblock(enum nk_panel_type type)
15605 {
15606  return (type & NK_PANEL_SET_NONBLOCK)?1:0;
15607 }
15608 NK_LIB int
15609 nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type panel_type)
15610 {
15611  struct nk_input *in;
15612  struct nk_window *win;
15613  struct nk_panel *layout;
15614  struct nk_command_buffer *out;
15615  const struct nk_style *style;
15616  const struct nk_user_font *font;
15617 
15618  struct nk_vec2 scrollbar_size;
15619  struct nk_vec2 panel_padding;
15620 
15621  NK_ASSERT(ctx);
15622  NK_ASSERT(ctx->current);
15623  NK_ASSERT(ctx->current->layout);
15624  if (!ctx || !ctx->current || !ctx->current->layout) return 0;
15625  nk_zero(ctx->current->layout, sizeof(*ctx->current->layout));
15626  if ((ctx->current->flags & NK_WINDOW_HIDDEN) || (ctx->current->flags & NK_WINDOW_CLOSED)) {
15627  nk_zero(ctx->current->layout, sizeof(struct nk_panel));
15628  ctx->current->layout->type = panel_type;
15629  return 0;
15630  }
15631  /* pull state into local stack */
15632  style = &ctx->style;
15633  font = style->font;
15634  win = ctx->current;
15635  layout = win->layout;
15636  out = &win->buffer;
15637  in = (win->flags & NK_WINDOW_NO_INPUT) ? 0: &ctx->input;
15638 #ifdef NK_INCLUDE_COMMAND_USERDATA
15639  win->buffer.userdata = ctx->userdata;
15640 #endif
15641  /* pull style configuration into local stack */
15642  scrollbar_size = style->window.scrollbar_size;
15643  panel_padding = nk_panel_get_padding(style, panel_type);
15644 
15645  /* window movement */
15646  if ((win->flags & NK_WINDOW_MOVABLE) && !(win->flags & NK_WINDOW_ROM)) {
15647  int left_mouse_down;
15648  int left_mouse_clicked;
15649  int left_mouse_click_in_cursor;
15650 
15651  /* calculate draggable window space */
15652  struct nk_rect header;
15653  header.x = win->bounds.x;
15654  header.y = win->bounds.y;
15655  header.w = win->bounds.w;
15656  if (nk_panel_has_header(win->flags, title)) {
15657  header.h = font->height + 2.0f * style->window.header.padding.y;
15658  header.h += 2.0f * style->window.header.label_padding.y;
15659  } else header.h = panel_padding.y;
15660 
15661  /* window movement by dragging */
15662  left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
15663  left_mouse_clicked = (int)in->mouse.buttons[NK_BUTTON_LEFT].clicked;
15664  left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
15665  NK_BUTTON_LEFT, header, nk_true);
15666  if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) {
15667  win->bounds.x = win->bounds.x + in->mouse.delta.x;
15668  win->bounds.y = win->bounds.y + in->mouse.delta.y;
15672  }
15673  }
15674 
15675  /* setup panel */
15676  layout->type = panel_type;
15677  layout->flags = win->flags;
15678  layout->bounds = win->bounds;
15679  layout->bounds.x += panel_padding.x;
15680  layout->bounds.w -= 2*panel_padding.x;
15681  if (win->flags & NK_WINDOW_BORDER) {
15682  layout->border = nk_panel_get_border(style, win->flags, panel_type);
15683  layout->bounds = nk_shrink_rect(layout->bounds, layout->border);
15684  } else layout->border = 0;
15685  layout->at_y = layout->bounds.y;
15686  layout->at_x = layout->bounds.x;
15687  layout->max_x = 0;
15688  layout->header_height = 0;
15689  layout->footer_height = 0;
15691  layout->row.index = 0;
15692  layout->row.columns = 0;
15693  layout->row.ratio = 0;
15694  layout->row.item_width = 0;
15695  layout->row.tree_depth = 0;
15696  layout->row.height = panel_padding.y;
15697  layout->has_scrolling = nk_true;
15698  if (!(win->flags & NK_WINDOW_NO_SCROLLBAR))
15699  layout->bounds.w -= scrollbar_size.x;
15700  if (!nk_panel_is_nonblock(panel_type)) {
15701  layout->footer_height = 0;
15703  layout->footer_height = scrollbar_size.y;
15704  layout->bounds.h -= layout->footer_height;
15705  }
15706 
15707  /* panel header */
15708  if (nk_panel_has_header(win->flags, title))
15709  {
15710  struct nk_text text;
15711  struct nk_rect header;
15712  const struct nk_style_item *background = 0;
15713 
15714  /* calculate header bounds */
15715  header.x = win->bounds.x;
15716  header.y = win->bounds.y;
15717  header.w = win->bounds.w;
15718  header.h = font->height + 2.0f * style->window.header.padding.y;
15719  header.h += (2.0f * style->window.header.label_padding.y);
15720 
15721  /* shrink panel by header */
15722  layout->header_height = header.h;
15723  layout->bounds.y += header.h;
15724  layout->bounds.h -= header.h;
15725  layout->at_y += header.h;
15726 
15727  /* select correct header background and text color */
15728  if (ctx->active == win) {
15729  background = &style->window.header.active;
15730  text.text = style->window.header.label_active;
15731  } else if (nk_input_is_mouse_hovering_rect(&ctx->input, header)) {
15732  background = &style->window.header.hover;
15733  text.text = style->window.header.label_hover;
15734  } else {
15735  background = &style->window.header.normal;
15736  text.text = style->window.header.label_normal;
15737  }
15738 
15739  /* draw header background */
15740  header.h += 1.0f;
15741  if (background->type == NK_STYLE_ITEM_IMAGE) {
15742  text.background = nk_rgba(0,0,0,0);
15743  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
15744  } else {
15745  text.background = background->data.color;
15746  nk_fill_rect(out, header, 0, background->data.color);
15747  }
15748 
15749  /* window close button */
15750  {struct nk_rect button;
15751  button.y = header.y + style->window.header.padding.y;
15752  button.h = header.h - 2 * style->window.header.padding.y;
15753  button.w = button.h;
15754  if (win->flags & NK_WINDOW_CLOSABLE) {
15755  nk_flags ws = 0;
15756  if (style->window.header.align == NK_HEADER_RIGHT) {
15757  button.x = (header.w + header.x) - (button.w + style->window.header.padding.x);
15758  header.w -= button.w + style->window.header.spacing.x + style->window.header.padding.x;
15759  } else {
15760  button.x = header.x + style->window.header.padding.x;
15761  header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
15762  }
15763 
15764  if (nk_do_button_symbol(&ws, &win->buffer, button,
15766  &style->window.header.close_button, in, style->font) && !(win->flags & NK_WINDOW_ROM))
15767  {
15768  layout->flags |= NK_WINDOW_HIDDEN;
15769  layout->flags &= (nk_flags)~NK_WINDOW_MINIMIZED;
15770  }
15771  }
15772 
15773  /* window minimize button */
15774  if (win->flags & NK_WINDOW_MINIMIZABLE) {
15775  nk_flags ws = 0;
15776  if (style->window.header.align == NK_HEADER_RIGHT) {
15777  button.x = (header.w + header.x) - button.w;
15778  if (!(win->flags & NK_WINDOW_CLOSABLE)) {
15779  button.x -= style->window.header.padding.x;
15780  header.w -= style->window.header.padding.x;
15781  }
15782  header.w -= button.w + style->window.header.spacing.x;
15783  } else {
15784  button.x = header.x;
15785  header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
15786  }
15787  if (nk_do_button_symbol(&ws, &win->buffer, button, (layout->flags & NK_WINDOW_MINIMIZED)?
15789  NK_BUTTON_DEFAULT, &style->window.header.minimize_button, in, style->font) && !(win->flags & NK_WINDOW_ROM))
15790  layout->flags = (layout->flags & NK_WINDOW_MINIMIZED) ?
15791  layout->flags & (nk_flags)~NK_WINDOW_MINIMIZED:
15792  layout->flags | NK_WINDOW_MINIMIZED;
15793  }}
15794 
15795  {/* window header title */
15796  int text_len = nk_strlen(title);
15797  struct nk_rect label = {0,0,0,0};
15798  float t = font->width(font->userdata, font->height, title, text_len);
15799  text.padding = nk_vec2(0,0);
15800 
15801  label.x = header.x + style->window.header.padding.x;
15802  label.x += style->window.header.label_padding.x;
15803  label.y = header.y + style->window.header.label_padding.y;
15804  label.h = font->height + 2 * style->window.header.label_padding.y;
15805  label.w = t + 2 * style->window.header.spacing.x;
15806  label.w = NK_CLAMP(0, label.w, header.x + header.w - label.x);
15807  nk_widget_text(out, label,(const char*)title, text_len, &text, NK_TEXT_LEFT, font);}
15808  }
15809 
15810  /* draw window background */
15811  if (!(layout->flags & NK_WINDOW_MINIMIZED) && !(layout->flags & NK_WINDOW_DYNAMIC)) {
15812  struct nk_rect body;
15813  body.x = win->bounds.x;
15814  body.w = win->bounds.w;
15815  body.y = (win->bounds.y + layout->header_height);
15816  body.h = (win->bounds.h - layout->header_height);
15818  nk_draw_image(out, body, &style->window.fixed_background.data.image, nk_white);
15819  else nk_fill_rect(out, body, 0, style->window.fixed_background.data.color);
15820  }
15821 
15822  /* set clipping rectangle */
15823  {struct nk_rect clip;
15824  layout->clip = layout->bounds;
15825  nk_unify(&clip, &win->buffer.clip, layout->clip.x, layout->clip.y,
15826  layout->clip.x + layout->clip.w, layout->clip.y + layout->clip.h);
15827  nk_push_scissor(out, clip);
15828  layout->clip = clip;}
15829  return !(layout->flags & NK_WINDOW_HIDDEN) && !(layout->flags & NK_WINDOW_MINIMIZED);
15830 }
15831 NK_LIB void
15832 nk_panel_end(struct nk_context *ctx)
15833 {
15834  struct nk_input *in;
15835  struct nk_window *window;
15836  struct nk_panel *layout;
15837  const struct nk_style *style;
15838  struct nk_command_buffer *out;
15839 
15840  struct nk_vec2 scrollbar_size;
15841  struct nk_vec2 panel_padding;
15842 
15843  NK_ASSERT(ctx);
15844  NK_ASSERT(ctx->current);
15845  NK_ASSERT(ctx->current->layout);
15846  if (!ctx || !ctx->current || !ctx->current->layout)
15847  return;
15848 
15849  window = ctx->current;
15850  layout = window->layout;
15851  style = &ctx->style;
15852  out = &window->buffer;
15853  in = (layout->flags & NK_WINDOW_ROM || layout->flags & NK_WINDOW_NO_INPUT) ? 0 :&ctx->input;
15854  if (!nk_panel_is_sub(layout->type))
15855  nk_push_scissor(out, nk_null_rect);
15856 
15857  /* cache configuration data */
15858  scrollbar_size = style->window.scrollbar_size;
15859  panel_padding = nk_panel_get_padding(style, layout->type);
15860 
15861  /* update the current cursor Y-position to point over the last added widget */
15862  layout->at_y += layout->row.height;
15863 
15864  /* dynamic panels */
15865  if (layout->flags & NK_WINDOW_DYNAMIC && !(layout->flags & NK_WINDOW_MINIMIZED))
15866  {
15867  /* update panel height to fit dynamic growth */
15868  struct nk_rect empty_space;
15869  if (layout->at_y < (layout->bounds.y + layout->bounds.h))
15870  layout->bounds.h = layout->at_y - layout->bounds.y;
15871 
15872  /* fill top empty space */
15873  empty_space.x = window->bounds.x;
15874  empty_space.y = layout->bounds.y;
15875  empty_space.h = panel_padding.y;
15876  empty_space.w = window->bounds.w;
15877  nk_fill_rect(out, empty_space, 0, style->window.background);
15878 
15879  /* fill left empty space */
15880  empty_space.x = window->bounds.x;
15881  empty_space.y = layout->bounds.y;
15882  empty_space.w = panel_padding.x + layout->border;
15883  empty_space.h = layout->bounds.h;
15884  nk_fill_rect(out, empty_space, 0, style->window.background);
15885 
15886  /* fill right empty space */
15887  empty_space.x = layout->bounds.x + layout->bounds.w;
15888  empty_space.y = layout->bounds.y;
15889  empty_space.w = panel_padding.x + layout->border;
15890  empty_space.h = layout->bounds.h;
15891  if (*layout->offset_y == 0 && !(layout->flags & NK_WINDOW_NO_SCROLLBAR))
15892  empty_space.w += scrollbar_size.x;
15893  nk_fill_rect(out, empty_space, 0, style->window.background);
15894 
15895  /* fill bottom empty space */
15896  if (layout->footer_height > 0) {
15897  empty_space.x = window->bounds.x;
15898  empty_space.y = layout->bounds.y + layout->bounds.h;
15899  empty_space.w = window->bounds.w;
15900  empty_space.h = layout->footer_height;
15901  nk_fill_rect(out, empty_space, 0, style->window.background);
15902  }
15903  }
15904 
15905  /* scrollbars */
15906  if (!(layout->flags & NK_WINDOW_NO_SCROLLBAR) &&
15907  !(layout->flags & NK_WINDOW_MINIMIZED) &&
15909  {
15910  struct nk_rect scroll;
15911  int scroll_has_scrolling;
15912  float scroll_target;
15913  float scroll_offset;
15914  float scroll_step;
15915  float scroll_inc;
15916 
15917  /* mouse wheel scrolling */
15918  if (nk_panel_is_sub(layout->type))
15919  {
15920  /* sub-window mouse wheel scrolling */
15921  struct nk_window *root_window = window;
15922  struct nk_panel *root_panel = window->layout;
15923  while (root_panel->parent)
15924  root_panel = root_panel->parent;
15925  while (root_window->parent)
15926  root_window = root_window->parent;
15927 
15928  /* only allow scrolling if parent window is active */
15929  scroll_has_scrolling = 0;
15930  if ((root_window == ctx->active) && layout->has_scrolling) {
15931  /* and panel is being hovered and inside clip rect*/
15932  if (nk_input_is_mouse_hovering_rect(in, layout->bounds) &&
15933  NK_INTERSECT(layout->bounds.x, layout->bounds.y, layout->bounds.w, layout->bounds.h,
15934  root_panel->clip.x, root_panel->clip.y, root_panel->clip.w, root_panel->clip.h))
15935  {
15936  /* deactivate all parent scrolling */
15937  root_panel = window->layout;
15938  while (root_panel->parent) {
15939  root_panel->has_scrolling = nk_false;
15940  root_panel = root_panel->parent;
15941  }
15942  root_panel->has_scrolling = nk_false;
15943  scroll_has_scrolling = nk_true;
15944  }
15945  }
15946  } else if (!nk_panel_is_sub(layout->type)) {
15947  /* window mouse wheel scrolling */
15948  scroll_has_scrolling = (window == ctx->active) && layout->has_scrolling;
15949  if (in && (in->mouse.scroll_delta.y > 0 || in->mouse.scroll_delta.x > 0) && scroll_has_scrolling)
15950  window->scrolled = nk_true;
15951  else window->scrolled = nk_false;
15952  } else scroll_has_scrolling = nk_false;
15953 
15954  {
15955  /* vertical scrollbar */
15956  nk_flags state = 0;
15957  scroll.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
15958  scroll.y = layout->bounds.y;
15959  scroll.w = scrollbar_size.x;
15960  scroll.h = layout->bounds.h;
15961 
15962  scroll_offset = (float)*layout->offset_y;
15963  scroll_step = scroll.h * 0.10f;
15964  scroll_inc = scroll.h * 0.01f;
15965  scroll_target = (float)(int)(layout->at_y - scroll.y);
15966  scroll_offset = nk_do_scrollbarv(&state, out, scroll, scroll_has_scrolling,
15967  scroll_offset, scroll_target, scroll_step, scroll_inc,
15968  &ctx->style.scrollv, in, style->font);
15969  *layout->offset_y = (nk_uint)scroll_offset;
15970  if (in && scroll_has_scrolling)
15971  in->mouse.scroll_delta.y = 0;
15972  }
15973  {
15974  /* horizontal scrollbar */
15975  nk_flags state = 0;
15976  scroll.x = layout->bounds.x;
15977  scroll.y = layout->bounds.y + layout->bounds.h;
15978  scroll.w = layout->bounds.w;
15979  scroll.h = scrollbar_size.y;
15980 
15981  scroll_offset = (float)*layout->offset_x;
15982  scroll_target = (float)(int)(layout->max_x - scroll.x);
15983  scroll_step = layout->max_x * 0.05f;
15984  scroll_inc = layout->max_x * 0.005f;
15985  scroll_offset = nk_do_scrollbarh(&state, out, scroll, scroll_has_scrolling,
15986  scroll_offset, scroll_target, scroll_step, scroll_inc,
15987  &ctx->style.scrollh, in, style->font);
15988  *layout->offset_x = (nk_uint)scroll_offset;
15989  }
15990  }
15991 
15992  /* hide scroll if no user input */
15993  if (window->flags & NK_WINDOW_SCROLL_AUTO_HIDE) {
15994  int has_input = ctx->input.mouse.delta.x != 0 || ctx->input.mouse.delta.y != 0 || ctx->input.mouse.scroll_delta.y != 0;
15995  int is_window_hovered = nk_window_is_hovered(ctx);
15996  int any_item_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
15997  if ((!has_input && is_window_hovered) || (!is_window_hovered && !any_item_active))
15999  else window->scrollbar_hiding_timer = 0;
16000  } else window->scrollbar_hiding_timer = 0;
16001 
16002  /* window border */
16003  if (layout->flags & NK_WINDOW_BORDER)
16004  {
16005  struct nk_color border_color = nk_panel_get_border_color(style, layout->type);
16006  const float padding_y = (layout->flags & NK_WINDOW_MINIMIZED)
16007  ? (style->window.border + window->bounds.y + layout->header_height)
16008  : ((layout->flags & NK_WINDOW_DYNAMIC)
16009  ? (layout->bounds.y + layout->bounds.h + layout->footer_height)
16010  : (window->bounds.y + window->bounds.h));
16011  struct nk_rect b = window->bounds;
16012  b.h = padding_y - window->bounds.y;
16013  nk_stroke_rect(out, b, 0, layout->border, border_color);
16014  }
16015 
16016  /* scaler */
16017  if ((layout->flags & NK_WINDOW_SCALABLE) && in && !(layout->flags & NK_WINDOW_MINIMIZED))
16018  {
16019  /* calculate scaler bounds */
16020  struct nk_rect scaler;
16021  scaler.w = scrollbar_size.x;
16022  scaler.h = scrollbar_size.y;
16023  scaler.y = layout->bounds.y + layout->bounds.h;
16024  if (layout->flags & NK_WINDOW_SCALE_LEFT)
16025  scaler.x = layout->bounds.x - panel_padding.x * 0.5f;
16026  else scaler.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
16027  if (layout->flags & NK_WINDOW_NO_SCROLLBAR)
16028  scaler.x -= scaler.w;
16029 
16030  /* draw scaler */
16031  {const struct nk_style_item *item = &style->window.scaler;
16032  if (item->type == NK_STYLE_ITEM_IMAGE)
16033  nk_draw_image(out, scaler, &item->data.image, nk_white);
16034  else {
16035  if (layout->flags & NK_WINDOW_SCALE_LEFT) {
16036  nk_fill_triangle(out, scaler.x, scaler.y, scaler.x,
16037  scaler.y + scaler.h, scaler.x + scaler.w,
16038  scaler.y + scaler.h, item->data.color);
16039  } else {
16040  nk_fill_triangle(out, scaler.x + scaler.w, scaler.y, scaler.x + scaler.w,
16041  scaler.y + scaler.h, scaler.x, scaler.y + scaler.h, item->data.color);
16042  }
16043  }}
16044 
16045  /* do window scaling */
16046  if (!(window->flags & NK_WINDOW_ROM)) {
16047  struct nk_vec2 window_size = style->window.min_size;
16048  int left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
16049  int left_mouse_click_in_scaler = nk_input_has_mouse_click_down_in_rect(in,
16050  NK_BUTTON_LEFT, scaler, nk_true);
16051 
16052  if (left_mouse_down && left_mouse_click_in_scaler) {
16053  float delta_x = in->mouse.delta.x;
16054  if (layout->flags & NK_WINDOW_SCALE_LEFT) {
16055  delta_x = -delta_x;
16056  window->bounds.x += in->mouse.delta.x;
16057  }
16058  /* dragging in x-direction */
16059  if (window->bounds.w + delta_x >= window_size.x) {
16060  if ((delta_x < 0) || (delta_x > 0 && in->mouse.pos.x >= scaler.x)) {
16061  window->bounds.w = window->bounds.w + delta_x;
16062  scaler.x += in->mouse.delta.x;
16063  }
16064  }
16065  /* dragging in y-direction (only possible if static window) */
16066  if (!(layout->flags & NK_WINDOW_DYNAMIC)) {
16067  if (window_size.y < window->bounds.h + in->mouse.delta.y) {
16068  if ((in->mouse.delta.y < 0) || (in->mouse.delta.y > 0 && in->mouse.pos.y >= scaler.y)) {
16069  window->bounds.h = window->bounds.h + in->mouse.delta.y;
16070  scaler.y += in->mouse.delta.y;
16071  }
16072  }
16073  }
16075  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = scaler.x + scaler.w/2.0f;
16076  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = scaler.y + scaler.h/2.0f;
16077  }
16078  }
16079  }
16080  if (!nk_panel_is_sub(layout->type)) {
16081  /* window is hidden so clear command buffer */
16082  if (layout->flags & NK_WINDOW_HIDDEN)
16083  nk_command_buffer_reset(&window->buffer);
16084  /* window is visible and not tab */
16085  else nk_finish(ctx, window);
16086  }
16087 
16088  /* NK_WINDOW_REMOVE_ROM flag was set so remove NK_WINDOW_ROM */
16089  if (layout->flags & NK_WINDOW_REMOVE_ROM) {
16090  layout->flags &= ~(nk_flags)NK_WINDOW_ROM;
16091  layout->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM;
16092  }
16093  window->flags = layout->flags;
16094 
16095  /* property garbage collector */
16096  if (window->property.active && window->property.old != window->property.seq &&
16097  window->property.active == window->property.prev) {
16098  nk_zero(&window->property, sizeof(window->property));
16099  } else {
16100  window->property.old = window->property.seq;
16101  window->property.prev = window->property.active;
16102  window->property.seq = 0;
16103  }
16104  /* edit garbage collector */
16105  if (window->edit.active && window->edit.old != window->edit.seq &&
16106  window->edit.active == window->edit.prev) {
16107  nk_zero(&window->edit, sizeof(window->edit));
16108  } else {
16109  window->edit.old = window->edit.seq;
16110  window->edit.prev = window->edit.active;
16111  window->edit.seq = 0;
16112  }
16113  /* contextual garbage collector */
16114  if (window->popup.active_con && window->popup.con_old != window->popup.con_count) {
16115  window->popup.con_count = 0;
16116  window->popup.con_old = 0;
16117  window->popup.active_con = 0;
16118  } else {
16119  window->popup.con_old = window->popup.con_count;
16120  window->popup.con_count = 0;
16121  }
16122  window->popup.combo_count = 0;
16123  /* helper to make sure you have a 'nk_tree_push' for every 'nk_tree_pop' */
16124  NK_ASSERT(!layout->row.tree_depth);
16125 }
16126 
16127 
16128 
16129 
16130 
16131 /* ===============================================================
16132  *
16133  * WINDOW
16134  *
16135  * ===============================================================*/
16136 NK_LIB void*
16137 nk_create_window(struct nk_context *ctx)
16138 {
16139  struct nk_page_element *elem;
16140  elem = nk_create_page_element(ctx);
16141  if (!elem) return 0;
16142  elem->data.win.seq = ctx->seq;
16143  return &elem->data.win;
16144 }
16145 NK_LIB void
16146 nk_free_window(struct nk_context *ctx, struct nk_window *win)
16147 {
16148  /* unlink windows from list */
16149  struct nk_table *it = win->tables;
16150  if (win->popup.win) {
16151  nk_free_window(ctx, win->popup.win);
16152  win->popup.win = 0;
16153  }
16154  win->next = 0;
16155  win->prev = 0;
16156 
16157  while (it) {
16158  /*free window state tables */
16159  struct nk_table *n = it->next;
16160  nk_remove_table(win, it);
16161  nk_free_table(ctx, it);
16162  if (it == win->tables)
16163  win->tables = n;
16164  it = n;
16165  }
16166 
16167  /* link windows into freelist */
16168  {union nk_page_data *pd = NK_CONTAINER_OF(win, union nk_page_data, win);
16169  struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
16170  nk_free_page_element(ctx, pe);}
16171 }
16172 NK_LIB struct nk_window*
16173 nk_find_window(struct nk_context *ctx, nk_hash hash, const char *name)
16174 {
16175  struct nk_window *iter;
16176  iter = ctx->begin;
16177  while (iter) {
16178  NK_ASSERT(iter != iter->next);
16179  if (iter->name == hash) {
16180  int max_len = nk_strlen(iter->name_string);
16181  if (!nk_stricmpn(iter->name_string, name, max_len))
16182  return iter;
16183  }
16184  iter = iter->next;
16185  }
16186  return 0;
16187 }
16188 NK_LIB void
16189 nk_insert_window(struct nk_context *ctx, struct nk_window *win,
16190  enum nk_window_insert_location loc)
16191 {
16192  const struct nk_window *iter;
16193  NK_ASSERT(ctx);
16194  NK_ASSERT(win);
16195  if (!win || !ctx) return;
16196 
16197  iter = ctx->begin;
16198  while (iter) {
16199  NK_ASSERT(iter != iter->next);
16200  NK_ASSERT(iter != win);
16201  if (iter == win) return;
16202  iter = iter->next;
16203  }
16204 
16205  if (!ctx->begin) {
16206  win->next = 0;
16207  win->prev = 0;
16208  ctx->begin = win;
16209  ctx->end = win;
16210  ctx->count = 1;
16211  return;
16212  }
16213  if (loc == NK_INSERT_BACK) {
16214  struct nk_window *end;
16215  end = ctx->end;
16216  end->flags |= NK_WINDOW_ROM;
16217  end->next = win;
16218  win->prev = ctx->end;
16219  win->next = 0;
16220  ctx->end = win;
16221  ctx->active = ctx->end;
16222  ctx->end->flags &= ~(nk_flags)NK_WINDOW_ROM;
16223  } else {
16224  /*ctx->end->flags |= NK_WINDOW_ROM;*/
16225  ctx->begin->prev = win;
16226  win->next = ctx->begin;
16227  win->prev = 0;
16228  ctx->begin = win;
16229  ctx->begin->flags &= ~(nk_flags)NK_WINDOW_ROM;
16230  }
16231  ctx->count++;
16232 }
16233 NK_LIB void
16234 nk_remove_window(struct nk_context *ctx, struct nk_window *win)
16235 {
16236  if (win == ctx->begin || win == ctx->end) {
16237  if (win == ctx->begin) {
16238  ctx->begin = win->next;
16239  if (win->next)
16240  win->next->prev = 0;
16241  }
16242  if (win == ctx->end) {
16243  ctx->end = win->prev;
16244  if (win->prev)
16245  win->prev->next = 0;
16246  }
16247  } else {
16248  if (win->next)
16249  win->next->prev = win->prev;
16250  if (win->prev)
16251  win->prev->next = win->next;
16252  }
16253  if (win == ctx->active || !ctx->active) {
16254  ctx->active = ctx->end;
16255  if (ctx->end)
16256  ctx->end->flags &= ~(nk_flags)NK_WINDOW_ROM;
16257  }
16258  win->next = 0;
16259  win->prev = 0;
16260  ctx->count--;
16261 }
16262 NK_API int
16263 nk_begin(struct nk_context *ctx, const char *title,
16264  struct nk_rect bounds, nk_flags flags)
16265 {
16266  return nk_begin_titled(ctx, title, title, bounds, flags);
16267 }
16268 NK_API int
16269 nk_begin_titled(struct nk_context *ctx, const char *name, const char *title,
16270  struct nk_rect bounds, nk_flags flags)
16271 {
16272  struct nk_window *win;
16273  struct nk_style *style;
16274  nk_hash name_hash;
16275  int name_len;
16276  int ret = 0;
16277 
16278  NK_ASSERT(ctx);
16279  NK_ASSERT(name);
16280  NK_ASSERT(title);
16281  NK_ASSERT(ctx->style.font && ctx->style.font->width && "if this triggers you forgot to add a font");
16282  NK_ASSERT(!ctx->current && "if this triggers you missed a `nk_end` call");
16283  if (!ctx || ctx->current || !title || !name)
16284  return 0;
16285 
16286  /* find or create window */
16287  style = &ctx->style;
16288  name_len = (int)nk_strlen(name);
16289  name_hash = nk_murmur_hash(name, (int)name_len, NK_WINDOW_TITLE);
16290  win = nk_find_window(ctx, name_hash, name);
16291  if (!win) {
16292  /* create new window */
16293  nk_size name_length = (nk_size)name_len;
16294  win = (struct nk_window*)nk_create_window(ctx);
16295  NK_ASSERT(win);
16296  if (!win) return 0;
16297 
16299  nk_insert_window(ctx, win, NK_INSERT_FRONT);
16300  else nk_insert_window(ctx, win, NK_INSERT_BACK);
16301  nk_command_buffer_init(&win->buffer, &ctx->memory, NK_CLIPPING_ON);
16302 
16303  win->flags = flags;
16304  win->bounds = bounds;
16305  win->name = name_hash;
16306  name_length = NK_MIN(name_length, NK_WINDOW_MAX_NAME-1);
16307  NK_MEMCPY(win->name_string, name, name_length);
16308  win->name_string[name_length] = 0;
16309  win->popup.win = 0;
16310  if (!ctx->active)
16311  ctx->active = win;
16312  } else {
16313  /* update window */
16314  win->flags &= ~(nk_flags)(NK_WINDOW_PRIVATE-1);
16315  win->flags |= flags;
16317  win->bounds = bounds;
16318  /* If this assert triggers you either:
16319  *
16320  * I.) Have more than one window with the same name or
16321  * II.) You forgot to actually draw the window.
16322  * More specific you did not call `nk_clear` (nk_clear will be
16323  * automatically called for you if you are using one of the
16324  * provided demo backends). */
16325  NK_ASSERT(win->seq != ctx->seq);
16326  win->seq = ctx->seq;
16327  if (!ctx->active && !(win->flags & NK_WINDOW_HIDDEN)) {
16328  ctx->active = win;
16329  ctx->end = win;
16330  }
16331  }
16332  if (win->flags & NK_WINDOW_HIDDEN) {
16333  ctx->current = win;
16334  win->layout = 0;
16335  return 0;
16336  } else nk_start(ctx, win);
16337 
16338  /* window overlapping */
16340  {
16341  int inpanel, ishovered;
16342  struct nk_window *iter = win;
16343  float h = ctx->style.font->height + 2.0f * style->window.header.padding.y +
16344  (2.0f * style->window.header.label_padding.y);
16345  struct nk_rect win_bounds = (!(win->flags & NK_WINDOW_MINIMIZED))?
16347 
16348  /* activate window if hovered and no other window is overlapping this window */
16349  inpanel = nk_input_has_mouse_click_down_in_rect(&ctx->input, NK_BUTTON_LEFT, win_bounds, nk_true);
16350  inpanel = inpanel && ctx->input.mouse.buttons[NK_BUTTON_LEFT].clicked;
16351  ishovered = nk_input_is_mouse_hovering_rect(&ctx->input, win_bounds);
16352  if ((win != ctx->active) && ishovered && !ctx->input.mouse.buttons[NK_BUTTON_LEFT].down) {
16353  iter = win->next;
16354  while (iter) {
16355  struct nk_rect iter_bounds = (!(iter->flags & NK_WINDOW_MINIMIZED))?
16356  iter->bounds: nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
16357  if (NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
16358  iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
16359  (!(iter->flags & NK_WINDOW_HIDDEN)))
16360  break;
16361 
16362  if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) &&
16363  NK_INTERSECT(win->bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
16364  iter->popup.win->bounds.x, iter->popup.win->bounds.y,
16365  iter->popup.win->bounds.w, iter->popup.win->bounds.h))
16366  break;
16367  iter = iter->next;
16368  }
16369  }
16370 
16371  /* activate window if clicked */
16372  if (iter && inpanel && (win != ctx->end)) {
16373  iter = win->next;
16374  while (iter) {
16375  /* try to find a panel with higher priority in the same position */
16376  struct nk_rect iter_bounds = (!(iter->flags & NK_WINDOW_MINIMIZED))?
16377  iter->bounds: nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
16378  if (NK_INBOX(ctx->input.mouse.pos.x, ctx->input.mouse.pos.y,
16379  iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
16380  !(iter->flags & NK_WINDOW_HIDDEN))
16381  break;
16382  if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) &&
16383  NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
16384  iter->popup.win->bounds.x, iter->popup.win->bounds.y,
16385  iter->popup.win->bounds.w, iter->popup.win->bounds.h))
16386  break;
16387  iter = iter->next;
16388  }
16389  }
16390  if (iter && !(win->flags & NK_WINDOW_ROM) && (win->flags & NK_WINDOW_BACKGROUND)) {
16392  iter->flags &= ~(nk_flags)NK_WINDOW_ROM;
16393  ctx->active = iter;
16394  if (!(iter->flags & NK_WINDOW_BACKGROUND)) {
16395  /* current window is active in that position so transfer to top
16396  * at the highest priority in stack */
16397  nk_remove_window(ctx, iter);
16398  nk_insert_window(ctx, iter, NK_INSERT_BACK);
16399  }
16400  } else {
16401  if (!iter && ctx->end != win) {
16402  if (!(win->flags & NK_WINDOW_BACKGROUND)) {
16403  /* current window is active in that position so transfer to top
16404  * at the highest priority in stack */
16405  nk_remove_window(ctx, win);
16406  nk_insert_window(ctx, win, NK_INSERT_BACK);
16407  }
16409  ctx->active = win;
16410  }
16411  if (ctx->end != win && !(win->flags & NK_WINDOW_BACKGROUND))
16412  win->flags |= NK_WINDOW_ROM;
16413  }
16414  }
16415  win->layout = (struct nk_panel*)nk_create_panel(ctx);
16416  ctx->current = win;
16417  ret = nk_panel_begin(ctx, title, NK_PANEL_WINDOW);
16418  win->layout->offset_x = &win->scrollbar.x;
16419  win->layout->offset_y = &win->scrollbar.y;
16420  return ret;
16421 }
16422 NK_API void
16423 nk_end(struct nk_context *ctx)
16424 {
16425  struct nk_panel *layout;
16426  NK_ASSERT(ctx);
16427  NK_ASSERT(ctx->current && "if this triggers you forgot to call `nk_begin`");
16428  if (!ctx || !ctx->current)
16429  return;
16430 
16431  layout = ctx->current->layout;
16432  if (!layout || (layout->type == NK_PANEL_WINDOW && (ctx->current->flags & NK_WINDOW_HIDDEN))) {
16433  ctx->current = 0;
16434  return;
16435  }
16436  nk_panel_end(ctx);
16437  nk_free_panel(ctx, ctx->current->layout);
16438  ctx->current = 0;
16439 }
16440 NK_API struct nk_rect
16441 nk_window_get_bounds(const struct nk_context *ctx)
16442 {
16443  NK_ASSERT(ctx);
16444  NK_ASSERT(ctx->current);
16445  if (!ctx || !ctx->current) return nk_rect(0,0,0,0);
16446  return ctx->current->bounds;
16447 }
16448 NK_API struct nk_vec2
16449 nk_window_get_position(const struct nk_context *ctx)
16450 {
16451  NK_ASSERT(ctx);
16452  NK_ASSERT(ctx->current);
16453  if (!ctx || !ctx->current) return nk_vec2(0,0);
16454  return nk_vec2(ctx->current->bounds.x, ctx->current->bounds.y);
16455 }
16456 NK_API struct nk_vec2
16457 nk_window_get_size(const struct nk_context *ctx)
16458 {
16459  NK_ASSERT(ctx);
16460  NK_ASSERT(ctx->current);
16461  if (!ctx || !ctx->current) return nk_vec2(0,0);
16462  return nk_vec2(ctx->current->bounds.w, ctx->current->bounds.h);
16463 }
16464 NK_API float
16465 nk_window_get_width(const struct nk_context *ctx)
16466 {
16467  NK_ASSERT(ctx);
16468  NK_ASSERT(ctx->current);
16469  if (!ctx || !ctx->current) return 0;
16470  return ctx->current->bounds.w;
16471 }
16472 NK_API float
16473 nk_window_get_height(const struct nk_context *ctx)
16474 {
16475  NK_ASSERT(ctx);
16476  NK_ASSERT(ctx->current);
16477  if (!ctx || !ctx->current) return 0;
16478  return ctx->current->bounds.h;
16479 }
16480 NK_API struct nk_rect
16482 {
16483  NK_ASSERT(ctx);
16484  NK_ASSERT(ctx->current);
16485  if (!ctx || !ctx->current) return nk_rect(0,0,0,0);
16486  return ctx->current->layout->clip;
16487 }
16488 NK_API struct nk_vec2
16490 {
16491  NK_ASSERT(ctx);
16492  NK_ASSERT(ctx->current);
16493  NK_ASSERT(ctx->current->layout);
16494  if (!ctx || !ctx->current) return nk_vec2(0,0);
16495  return nk_vec2(ctx->current->layout->clip.x, ctx->current->layout->clip.y);
16496 }
16497 NK_API struct nk_vec2
16499 {
16500  NK_ASSERT(ctx);
16501  NK_ASSERT(ctx->current);
16502  NK_ASSERT(ctx->current->layout);
16503  if (!ctx || !ctx->current) return nk_vec2(0,0);
16504  return nk_vec2(ctx->current->layout->clip.x + ctx->current->layout->clip.w,
16505  ctx->current->layout->clip.y + ctx->current->layout->clip.h);
16506 }
16507 NK_API struct nk_vec2
16509 {
16510  NK_ASSERT(ctx);
16511  NK_ASSERT(ctx->current);
16512  NK_ASSERT(ctx->current->layout);
16513  if (!ctx || !ctx->current) return nk_vec2(0,0);
16514  return nk_vec2(ctx->current->layout->clip.w, ctx->current->layout->clip.h);
16515 }
16516 NK_API struct nk_command_buffer*
16517 nk_window_get_canvas(struct nk_context *ctx)
16518 {
16519  NK_ASSERT(ctx);
16520  NK_ASSERT(ctx->current);
16521  NK_ASSERT(ctx->current->layout);
16522  if (!ctx || !ctx->current) return 0;
16523  return &ctx->current->buffer;
16524 }
16525 NK_API struct nk_panel*
16526 nk_window_get_panel(struct nk_context *ctx)
16527 {
16528  NK_ASSERT(ctx);
16529  NK_ASSERT(ctx->current);
16530  if (!ctx || !ctx->current) return 0;
16531  return ctx->current->layout;
16532 }
16533 NK_API void
16535 {
16536  struct nk_window *win;
16537  NK_ASSERT(ctx);
16538  NK_ASSERT(ctx->current);
16539  if (!ctx || !ctx->current)
16540  return ;
16541  win = ctx->current;
16542  if (offset_x)
16543  *offset_x = win->scrollbar.x;
16544  if (offset_y)
16545  *offset_y = win->scrollbar.y;
16546 }
16547 NK_API int
16548 nk_window_has_focus(const struct nk_context *ctx)
16549 {
16550  NK_ASSERT(ctx);
16551  NK_ASSERT(ctx->current);
16552  NK_ASSERT(ctx->current->layout);
16553  if (!ctx || !ctx->current) return 0;
16554  return ctx->current == ctx->active;
16555 }
16556 NK_API int
16557 nk_window_is_hovered(struct nk_context *ctx)
16558 {
16559  NK_ASSERT(ctx);
16560  NK_ASSERT(ctx->current);
16561  if (!ctx || !ctx->current) return 0;
16562  if(ctx->current->flags & NK_WINDOW_HIDDEN)
16563  return 0;
16564  return nk_input_is_mouse_hovering_rect(&ctx->input, ctx->current->bounds);
16565 }
16566 NK_API int
16568 {
16569  struct nk_window *iter;
16570  NK_ASSERT(ctx);
16571  if (!ctx) return 0;
16572  iter = ctx->begin;
16573  while (iter) {
16574  /* check if window is being hovered */
16575  if(!(iter->flags & NK_WINDOW_HIDDEN)) {
16576  /* check if window popup is being hovered */
16577  if (iter->popup.active && iter->popup.win && nk_input_is_mouse_hovering_rect(&ctx->input, iter->popup.win->bounds))
16578  return 1;
16579 
16580  if (iter->flags & NK_WINDOW_MINIMIZED) {
16581  struct nk_rect header = iter->bounds;
16582  header.h = ctx->style.font->height + 2 * ctx->style.window.header.padding.y;
16583  if (nk_input_is_mouse_hovering_rect(&ctx->input, header))
16584  return 1;
16585  } else if (nk_input_is_mouse_hovering_rect(&ctx->input, iter->bounds)) {
16586  return 1;
16587  }
16588  }
16589  iter = iter->next;
16590  }
16591  return 0;
16592 }
16593 NK_API int
16594 nk_item_is_any_active(struct nk_context *ctx)
16595 {
16596  int any_hovered = nk_window_is_any_hovered(ctx);
16597  int any_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
16598  return any_hovered || any_active;
16599 }
16600 NK_API int
16601 nk_window_is_collapsed(struct nk_context *ctx, const char *name)
16602 {
16603  int title_len;
16604  nk_hash title_hash;
16605  struct nk_window *win;
16606  NK_ASSERT(ctx);
16607  if (!ctx) return 0;
16608 
16609  title_len = (int)nk_strlen(name);
16610  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16611  win = nk_find_window(ctx, title_hash, name);
16612  if (!win) return 0;
16613  return win->flags & NK_WINDOW_MINIMIZED;
16614 }
16615 NK_API int
16616 nk_window_is_closed(struct nk_context *ctx, const char *name)
16617 {
16618  int title_len;
16619  nk_hash title_hash;
16620  struct nk_window *win;
16621  NK_ASSERT(ctx);
16622  if (!ctx) return 1;
16623 
16624  title_len = (int)nk_strlen(name);
16625  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16626  win = nk_find_window(ctx, title_hash, name);
16627  if (!win) return 1;
16628  return (win->flags & NK_WINDOW_CLOSED);
16629 }
16630 NK_API int
16631 nk_window_is_hidden(struct nk_context *ctx, const char *name)
16632 {
16633  int title_len;
16634  nk_hash title_hash;
16635  struct nk_window *win;
16636  NK_ASSERT(ctx);
16637  if (!ctx) return 1;
16638 
16639  title_len = (int)nk_strlen(name);
16640  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16641  win = nk_find_window(ctx, title_hash, name);
16642  if (!win) return 1;
16643  return (win->flags & NK_WINDOW_HIDDEN);
16644 }
16645 NK_API int
16646 nk_window_is_active(struct nk_context *ctx, const char *name)
16647 {
16648  int title_len;
16649  nk_hash title_hash;
16650  struct nk_window *win;
16651  NK_ASSERT(ctx);
16652  if (!ctx) return 0;
16653 
16654  title_len = (int)nk_strlen(name);
16655  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16656  win = nk_find_window(ctx, title_hash, name);
16657  if (!win) return 0;
16658  return win == ctx->active;
16659 }
16660 NK_API struct nk_window*
16661 nk_window_find(struct nk_context *ctx, const char *name)
16662 {
16663  int title_len;
16664  nk_hash title_hash;
16665  title_len = (int)nk_strlen(name);
16666  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16667  return nk_find_window(ctx, title_hash, name);
16668 }
16669 NK_API void
16670 nk_window_close(struct nk_context *ctx, const char *name)
16671 {
16672  struct nk_window *win;
16673  NK_ASSERT(ctx);
16674  if (!ctx) return;
16675  win = nk_window_find(ctx, name);
16676  if (!win) return;
16677  NK_ASSERT(ctx->current != win && "You cannot close a currently active window");
16678  if (ctx->current == win) return;
16681 }
16682 NK_API void
16683 nk_window_set_bounds(struct nk_context *ctx,
16684  const char *name, struct nk_rect bounds)
16685 {
16686  struct nk_window *win;
16687  NK_ASSERT(ctx);
16688  if (!ctx) return;
16689  win = nk_window_find(ctx, name);
16690  if (!win) return;
16691  NK_ASSERT(ctx->current != win && "You cannot update a currently in procecss window");
16692  win->bounds = bounds;
16693 }
16694 NK_API void
16696  const char *name, struct nk_vec2 pos)
16697 {
16698  struct nk_window *win = nk_window_find(ctx, name);
16699  if (!win) return;
16700  win->bounds.x = pos.x;
16701  win->bounds.y = pos.y;
16702 }
16703 NK_API void
16704 nk_window_set_size(struct nk_context *ctx,
16705  const char *name, struct nk_vec2 size)
16706 {
16707  struct nk_window *win = nk_window_find(ctx, name);
16708  if (!win) return;
16709  win->bounds.w = size.x;
16710  win->bounds.h = size.y;
16711 }
16712 NK_API void
16713 nk_window_set_scroll(struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y)
16714 {
16715  struct nk_window *win;
16716  NK_ASSERT(ctx);
16717  NK_ASSERT(ctx->current);
16718  if (!ctx || !ctx->current)
16719  return;
16720  win = ctx->current;
16721  win->scrollbar.x = offset_x;
16722  win->scrollbar.y = offset_y;
16723 }
16724 NK_API void
16725 nk_window_collapse(struct nk_context *ctx, const char *name,
16726  enum nk_collapse_states c)
16727 {
16728  int title_len;
16729  nk_hash title_hash;
16730  struct nk_window *win;
16731  NK_ASSERT(ctx);
16732  if (!ctx) return;
16733 
16734  title_len = (int)nk_strlen(name);
16735  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16736  win = nk_find_window(ctx, title_hash, name);
16737  if (!win) return;
16738  if (c == NK_MINIMIZED)
16741 }
16742 NK_API void
16743 nk_window_collapse_if(struct nk_context *ctx, const char *name,
16744  enum nk_collapse_states c, int cond)
16745 {
16746  NK_ASSERT(ctx);
16747  if (!ctx || !cond) return;
16748  nk_window_collapse(ctx, name, c);
16749 }
16750 NK_API void
16751 nk_window_show(struct nk_context *ctx, const char *name, enum nk_show_states s)
16752 {
16753  int title_len;
16754  nk_hash title_hash;
16755  struct nk_window *win;
16756  NK_ASSERT(ctx);
16757  if (!ctx) return;
16758 
16759  title_len = (int)nk_strlen(name);
16760  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16761  win = nk_find_window(ctx, title_hash, name);
16762  if (!win) return;
16763  if (s == NK_HIDDEN) {
16765  } else win->flags &= ~(nk_flags)NK_WINDOW_HIDDEN;
16766 }
16767 NK_API void
16768 nk_window_show_if(struct nk_context *ctx, const char *name,
16769  enum nk_show_states s, int cond)
16770 {
16771  NK_ASSERT(ctx);
16772  if (!ctx || !cond) return;
16773  nk_window_show(ctx, name, s);
16774 }
16775 
16776 NK_API void
16777 nk_window_set_focus(struct nk_context *ctx, const char *name)
16778 {
16779  int title_len;
16780  nk_hash title_hash;
16781  struct nk_window *win;
16782  NK_ASSERT(ctx);
16783  if (!ctx) return;
16784 
16785  title_len = (int)nk_strlen(name);
16786  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16787  win = nk_find_window(ctx, title_hash, name);
16788  if (win && ctx->end != win) {
16789  nk_remove_window(ctx, win);
16790  nk_insert_window(ctx, win, NK_INSERT_BACK);
16791  }
16792  ctx->active = win;
16793 }
16794 
16795 
16796 
16797 
16798 /* ===============================================================
16799  *
16800  * POPUP
16801  *
16802  * ===============================================================*/
16803 NK_API int
16804 nk_popup_begin(struct nk_context *ctx, enum nk_popup_type type,
16805  const char *title, nk_flags flags, struct nk_rect rect)
16806 {
16807  struct nk_window *popup;
16808  struct nk_window *win;
16809  struct nk_panel *panel;
16810 
16811  int title_len;
16812  nk_hash title_hash;
16813  nk_size allocated;
16814 
16815  NK_ASSERT(ctx);
16816  NK_ASSERT(title);
16817  NK_ASSERT(ctx->current);
16818  NK_ASSERT(ctx->current->layout);
16819  if (!ctx || !ctx->current || !ctx->current->layout)
16820  return 0;
16821 
16822  win = ctx->current;
16823  panel = win->layout;
16824  NK_ASSERT(!(panel->type & NK_PANEL_SET_POPUP) && "popups are not allowed to have popups");
16825  (void)panel;
16826  title_len = (int)nk_strlen(title);
16827  title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_POPUP);
16828 
16829  popup = win->popup.win;
16830  if (!popup) {
16831  popup = (struct nk_window*)nk_create_window(ctx);
16832  popup->parent = win;
16833  win->popup.win = popup;
16834  win->popup.active = 0;
16836  }
16837 
16838  /* make sure we have correct popup */
16839  if (win->popup.name != title_hash) {
16840  if (!win->popup.active) {
16841  nk_zero(popup, sizeof(*popup));
16842  win->popup.name = title_hash;
16843  win->popup.active = 1;
16845  } else return 0;
16846  }
16847 
16848  /* popup position is local to window */
16849  ctx->current = popup;
16850  rect.x += win->layout->clip.x;
16851  rect.y += win->layout->clip.y;
16852 
16853  /* setup popup data */
16854  popup->parent = win;
16855  popup->bounds = rect;
16856  popup->seq = ctx->seq;
16857  popup->layout = (struct nk_panel*)nk_create_panel(ctx);
16858  popup->flags = flags;
16859  popup->flags |= NK_WINDOW_BORDER;
16860  if (type == NK_POPUP_DYNAMIC)
16861  popup->flags |= NK_WINDOW_DYNAMIC;
16862 
16863  popup->buffer = win->buffer;
16864  nk_start_popup(ctx, win);
16865  allocated = ctx->memory.allocated;
16866  nk_push_scissor(&popup->buffer, nk_null_rect);
16867 
16868  if (nk_panel_begin(ctx, title, NK_PANEL_POPUP)) {
16869  /* popup is running therefore invalidate parent panels */
16870  struct nk_panel *root;
16871  root = win->layout;
16872  while (root) {
16873  root->flags |= NK_WINDOW_ROM;
16874  root->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM;
16875  root = root->parent;
16876  }
16877  win->popup.active = 1;
16878  popup->layout->offset_x = &popup->scrollbar.x;
16879  popup->layout->offset_y = &popup->scrollbar.y;
16880  popup->layout->parent = win->layout;
16881  return 1;
16882  } else {
16883  /* popup was closed/is invalid so cleanup */
16884  struct nk_panel *root;
16885  root = win->layout;
16886  while (root) {
16887  root->flags |= NK_WINDOW_REMOVE_ROM;
16888  root = root->parent;
16889  }
16890  win->popup.buf.active = 0;
16891  win->popup.active = 0;
16892  ctx->memory.allocated = allocated;
16893  ctx->current = win;
16894  nk_free_panel(ctx, popup->layout);
16895  popup->layout = 0;
16896  return 0;
16897  }
16898 }
16899 NK_LIB int
16900 nk_nonblock_begin(struct nk_context *ctx,
16901  nk_flags flags, struct nk_rect body, struct nk_rect header,
16902  enum nk_panel_type panel_type)
16903 {
16904  struct nk_window *popup;
16905  struct nk_window *win;
16906  struct nk_panel *panel;
16907  int is_active = nk_true;
16908 
16909  NK_ASSERT(ctx);
16910  NK_ASSERT(ctx->current);
16911  NK_ASSERT(ctx->current->layout);
16912  if (!ctx || !ctx->current || !ctx->current->layout)
16913  return 0;
16914 
16915  /* popups cannot have popups */
16916  win = ctx->current;
16917  panel = win->layout;
16918  NK_ASSERT(!(panel->type & NK_PANEL_SET_POPUP));
16919  (void)panel;
16920  popup = win->popup.win;
16921  if (!popup) {
16922  /* create window for nonblocking popup */
16923  popup = (struct nk_window*)nk_create_window(ctx);
16924  popup->parent = win;
16925  win->popup.win = popup;
16926  win->popup.type = panel_type;
16927  nk_command_buffer_init(&popup->buffer, &ctx->memory, NK_CLIPPING_ON);
16928  } else {
16929  /* close the popup if user pressed outside or in the header */
16930  int pressed, in_body, in_header;
16931 #ifdef NK_BUTTON_TRIGGER_ON_RELEASE
16933 #else
16935 #endif
16936  in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
16937  in_header = nk_input_is_mouse_hovering_rect(&ctx->input, header);
16938  if (pressed && (!in_body || in_header))
16939  is_active = nk_false;
16940  }
16941  win->popup.header = header;
16942 
16943  if (!is_active) {
16944  /* remove read only mode from all parent panels */
16945  struct nk_panel *root = win->layout;
16946  while (root) {
16947  root->flags |= NK_WINDOW_REMOVE_ROM;
16948  root = root->parent;
16949  }
16950  return is_active;
16951  }
16952  popup->bounds = body;
16953  popup->parent = win;
16954  popup->layout = (struct nk_panel*)nk_create_panel(ctx);
16955  popup->flags = flags;
16956  popup->flags |= NK_WINDOW_BORDER;
16957  popup->flags |= NK_WINDOW_DYNAMIC;
16958  popup->seq = ctx->seq;
16959  win->popup.active = 1;
16960  NK_ASSERT(popup->layout);
16961 
16962  nk_start_popup(ctx, win);
16963  popup->buffer = win->buffer;
16964  nk_push_scissor(&popup->buffer, nk_null_rect);
16965  ctx->current = popup;
16966 
16967  nk_panel_begin(ctx, 0, panel_type);
16968  win->buffer = popup->buffer;
16969  popup->layout->parent = win->layout;
16970  popup->layout->offset_x = &popup->scrollbar.x;
16971  popup->layout->offset_y = &popup->scrollbar.y;
16972 
16973  /* set read only mode to all parent panels */
16974  {struct nk_panel *root;
16975  root = win->layout;
16976  while (root) {
16977  root->flags |= NK_WINDOW_ROM;
16978  root = root->parent;
16979  }}
16980  return is_active;
16981 }
16982 NK_API void
16983 nk_popup_close(struct nk_context *ctx)
16984 {
16985  struct nk_window *popup;
16986  NK_ASSERT(ctx);
16987  if (!ctx || !ctx->current) return;
16988 
16989  popup = ctx->current;
16990  NK_ASSERT(popup->parent);
16991  NK_ASSERT(popup->layout->type & NK_PANEL_SET_POPUP);
16992  popup->flags |= NK_WINDOW_HIDDEN;
16993 }
16994 NK_API void
16995 nk_popup_end(struct nk_context *ctx)
16996 {
16997  struct nk_window *win;
16998  struct nk_window *popup;
16999 
17000  NK_ASSERT(ctx);
17001  NK_ASSERT(ctx->current);
17002  NK_ASSERT(ctx->current->layout);
17003  if (!ctx || !ctx->current || !ctx->current->layout)
17004  return;
17005 
17006  popup = ctx->current;
17007  if (!popup->parent) return;
17008  win = popup->parent;
17009  if (popup->flags & NK_WINDOW_HIDDEN) {
17010  struct nk_panel *root;
17011  root = win->layout;
17012  while (root) {
17013  root->flags |= NK_WINDOW_REMOVE_ROM;
17014  root = root->parent;
17015  }
17016  win->popup.active = 0;
17017  }
17018  nk_push_scissor(&popup->buffer, nk_null_rect);
17019  nk_end(ctx);
17020 
17021  win->buffer = popup->buffer;
17022  nk_finish_popup(ctx, win);
17023  ctx->current = win;
17025 }
17026 NK_API void
17028 {
17029  struct nk_window *popup;
17030 
17031  NK_ASSERT(ctx);
17032  NK_ASSERT(ctx->current);
17033  NK_ASSERT(ctx->current->layout);
17034  if (!ctx || !ctx->current || !ctx->current->layout)
17035  return;
17036 
17037  popup = ctx->current;
17038  if (offset_x)
17039  *offset_x = popup->scrollbar.x;
17040  if (offset_y)
17041  *offset_y = popup->scrollbar.y;
17042 }
17043 NK_API void
17044 nk_popup_set_scroll(struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y)
17045 {
17046  struct nk_window *popup;
17047 
17048  NK_ASSERT(ctx);
17049  NK_ASSERT(ctx->current);
17050  NK_ASSERT(ctx->current->layout);
17051  if (!ctx || !ctx->current || !ctx->current->layout)
17052  return;
17053 
17054  popup = ctx->current;
17055  popup->scrollbar.x = offset_x;
17056  popup->scrollbar.y = offset_y;
17057 }
17058 
17059 
17060 
17061 
17062 /* ==============================================================
17063  *
17064  * CONTEXTUAL
17065  *
17066  * ===============================================================*/
17067 NK_API int
17069  struct nk_rect trigger_bounds)
17070 {
17071  struct nk_window *win;
17072  struct nk_window *popup;
17073  struct nk_rect body;
17074 
17075  NK_STORAGE const struct nk_rect null_rect = {-1,-1,0,0};
17076  int is_clicked = 0;
17077  int is_open = 0;
17078  int ret = 0;
17079 
17080  NK_ASSERT(ctx);
17081  NK_ASSERT(ctx->current);
17082  NK_ASSERT(ctx->current->layout);
17083  if (!ctx || !ctx->current || !ctx->current->layout)
17084  return 0;
17085 
17086  win = ctx->current;
17087  ++win->popup.con_count;
17088  if (ctx->current != ctx->active)
17089  return 0;
17090 
17091  /* check if currently active contextual is active */
17092  popup = win->popup.win;
17093  is_open = (popup && win->popup.type == NK_PANEL_CONTEXTUAL);
17094  is_clicked = nk_input_mouse_clicked(&ctx->input, NK_BUTTON_RIGHT, trigger_bounds);
17096  return 0;
17097  if (!is_open && win->popup.active_con)
17098  win->popup.active_con = 0;
17099  if ((!is_open && !is_clicked))
17100  return 0;
17101 
17102  /* calculate contextual position on click */
17104  if (is_clicked) {
17105  body.x = ctx->input.mouse.pos.x;
17106  body.y = ctx->input.mouse.pos.y;
17107  } else {
17108  body.x = popup->bounds.x;
17109  body.y = popup->bounds.y;
17110  }
17111  body.w = size.x;
17112  body.h = size.y;
17113 
17114  /* start nonblocking contextual popup */
17115  ret = nk_nonblock_begin(ctx, flags|NK_WINDOW_NO_SCROLLBAR, body,
17116  null_rect, NK_PANEL_CONTEXTUAL);
17117  if (ret) win->popup.type = NK_PANEL_CONTEXTUAL;
17118  else {
17119  win->popup.active_con = 0;
17121  if (win->popup.win)
17122  win->popup.win->flags = 0;
17123  }
17124  return ret;
17125 }
17126 NK_API int
17127 nk_contextual_item_text(struct nk_context *ctx, const char *text, int len,
17128  nk_flags alignment)
17129 {
17130  struct nk_window *win;
17131  const struct nk_input *in;
17132  const struct nk_style *style;
17133 
17134  struct nk_rect bounds;
17135  enum nk_widget_layout_states state;
17136 
17137  NK_ASSERT(ctx);
17138  NK_ASSERT(ctx->current);
17139  NK_ASSERT(ctx->current->layout);
17140  if (!ctx || !ctx->current || !ctx->current->layout)
17141  return 0;
17142 
17143  win = ctx->current;
17144  style = &ctx->style;
17145  state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
17146  if (!state) return nk_false;
17147 
17148  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17149  if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
17150  text, len, alignment, NK_BUTTON_DEFAULT, &style->contextual_button, in, style->font)) {
17151  nk_contextual_close(ctx);
17152  return nk_true;
17153  }
17154  return nk_false;
17155 }
17156 NK_API int
17157 nk_contextual_item_label(struct nk_context *ctx, const char *label, nk_flags align)
17158 {
17159  return nk_contextual_item_text(ctx, label, nk_strlen(label), align);
17160 }
17161 NK_API int
17162 nk_contextual_item_image_text(struct nk_context *ctx, struct nk_image img,
17163  const char *text, int len, nk_flags align)
17164 {
17165  struct nk_window *win;
17166  const struct nk_input *in;
17167  const struct nk_style *style;
17168 
17169  struct nk_rect bounds;
17170  enum nk_widget_layout_states state;
17171 
17172  NK_ASSERT(ctx);
17173  NK_ASSERT(ctx->current);
17174  NK_ASSERT(ctx->current->layout);
17175  if (!ctx || !ctx->current || !ctx->current->layout)
17176  return 0;
17177 
17178  win = ctx->current;
17179  style = &ctx->style;
17180  state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
17181  if (!state) return nk_false;
17182 
17183  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17184  if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, bounds,
17185  img, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)){
17186  nk_contextual_close(ctx);
17187  return nk_true;
17188  }
17189  return nk_false;
17190 }
17191 NK_API int
17192 nk_contextual_item_image_label(struct nk_context *ctx, struct nk_image img,
17193  const char *label, nk_flags align)
17194 {
17195  return nk_contextual_item_image_text(ctx, img, label, nk_strlen(label), align);
17196 }
17197 NK_API int
17199  const char *text, int len, nk_flags align)
17200 {
17201  struct nk_window *win;
17202  const struct nk_input *in;
17203  const struct nk_style *style;
17204 
17205  struct nk_rect bounds;
17206  enum nk_widget_layout_states state;
17207 
17208  NK_ASSERT(ctx);
17209  NK_ASSERT(ctx->current);
17210  NK_ASSERT(ctx->current->layout);
17211  if (!ctx || !ctx->current || !ctx->current->layout)
17212  return 0;
17213 
17214  win = ctx->current;
17215  style = &ctx->style;
17216  state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
17217  if (!state) return nk_false;
17218 
17219  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17220  if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
17221  symbol, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)) {
17222  nk_contextual_close(ctx);
17223  return nk_true;
17224  }
17225  return nk_false;
17226 }
17227 NK_API int
17229  const char *text, nk_flags align)
17230 {
17231  return nk_contextual_item_symbol_text(ctx, symbol, text, nk_strlen(text), align);
17232 }
17233 NK_API void
17234 nk_contextual_close(struct nk_context *ctx)
17235 {
17236  NK_ASSERT(ctx);
17237  NK_ASSERT(ctx->current);
17238  NK_ASSERT(ctx->current->layout);
17239  if (!ctx || !ctx->current || !ctx->current->layout) return;
17240  nk_popup_close(ctx);
17241 }
17242 NK_API void
17243 nk_contextual_end(struct nk_context *ctx)
17244 {
17245  struct nk_window *popup;
17246  struct nk_panel *panel;
17247  NK_ASSERT(ctx);
17248  NK_ASSERT(ctx->current);
17249  if (!ctx || !ctx->current) return;
17250 
17251  popup = ctx->current;
17252  panel = popup->layout;
17253  NK_ASSERT(popup->parent);
17254  NK_ASSERT(panel->type & NK_PANEL_SET_POPUP);
17255  if (panel->flags & NK_WINDOW_DYNAMIC) {
17256  /* Close behavior
17257  This is a bit of a hack solution since we do not know before we end our popup
17258  how big it will be. We therefore do not directly know when a
17259  click outside the non-blocking popup must close it at that direct frame.
17260  Instead it will be closed in the next frame.*/
17261  struct nk_rect body = {0,0,0,0};
17262  if (panel->at_y < (panel->bounds.y + panel->bounds.h)) {
17263  struct nk_vec2 padding = nk_panel_get_padding(&ctx->style, panel->type);
17264  body = panel->bounds;
17265  body.y = (panel->at_y + panel->footer_height + panel->border + padding.y + panel->row.height);
17266  body.h = (panel->bounds.y + panel->bounds.h) - body.y;
17267  }
17268  {int pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT);
17269  int in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
17270  if (pressed && in_body)
17271  popup->flags |= NK_WINDOW_HIDDEN;
17272  }
17273  }
17274  if (popup->flags & NK_WINDOW_HIDDEN)
17275  popup->seq = 0;
17276  nk_popup_end(ctx);
17277  return;
17278 }
17279 
17280 
17281 
17282 
17283 
17284 /* ===============================================================
17285  *
17286  * MENU
17287  *
17288  * ===============================================================*/
17289 NK_API void
17290 nk_menubar_begin(struct nk_context *ctx)
17291 {
17292  struct nk_panel *layout;
17293  NK_ASSERT(ctx);
17294  NK_ASSERT(ctx->current);
17295  NK_ASSERT(ctx->current->layout);
17296  if (!ctx || !ctx->current || !ctx->current->layout)
17297  return;
17298 
17299  layout = ctx->current->layout;
17300  NK_ASSERT(layout->at_y == layout->bounds.y);
17301  /* if this assert triggers you allocated space between nk_begin and nk_menubar_begin.
17302  If you want a menubar the first nuklear function after `nk_begin` has to be a
17303  `nk_menubar_begin` call. Inside the menubar you then have to allocate space for
17304  widgets (also supports multiple rows).
17305  Example:
17306  if (nk_begin(...)) {
17307  nk_menubar_begin(...);
17308  nk_layout_xxxx(...);
17309  nk_button(...);
17310  nk_layout_xxxx(...);
17311  nk_button(...);
17312  nk_menubar_end(...);
17313  }
17314  nk_end(...);
17315  */
17316  if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED)
17317  return;
17318 
17319  layout->menu.x = layout->at_x;
17320  layout->menu.y = layout->at_y + layout->row.height;
17321  layout->menu.w = layout->bounds.w;
17322  layout->menu.offset.x = *layout->offset_x;
17323  layout->menu.offset.y = *layout->offset_y;
17324  *layout->offset_y = 0;
17325 }
17326 NK_API void
17327 nk_menubar_end(struct nk_context *ctx)
17328 {
17329  struct nk_window *win;
17330  struct nk_panel *layout;
17331  struct nk_command_buffer *out;
17332 
17333  NK_ASSERT(ctx);
17334  NK_ASSERT(ctx->current);
17335  NK_ASSERT(ctx->current->layout);
17336  if (!ctx || !ctx->current || !ctx->current->layout)
17337  return;
17338 
17339  win = ctx->current;
17340  out = &win->buffer;
17341  layout = win->layout;
17342  if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED)
17343  return;
17344 
17345  layout->menu.h = layout->at_y - layout->menu.y;
17346  layout->bounds.y += layout->menu.h + ctx->style.window.spacing.y + layout->row.height;
17347  layout->bounds.h -= layout->menu.h + ctx->style.window.spacing.y + layout->row.height;
17348 
17349  *layout->offset_x = layout->menu.offset.x;
17350  *layout->offset_y = layout->menu.offset.y;
17351  layout->at_y = layout->bounds.y - layout->row.height;
17352 
17353  layout->clip.y = layout->bounds.y;
17354  layout->clip.h = layout->bounds.h;
17355  nk_push_scissor(out, layout->clip);
17356 }
17357 NK_INTERN int
17358 nk_menu_begin(struct nk_context *ctx, struct nk_window *win,
17359  const char *id, int is_clicked, struct nk_rect header, struct nk_vec2 size)
17360 {
17361  int is_open = 0;
17362  int is_active = 0;
17363  struct nk_rect body;
17364  struct nk_window *popup;
17365  nk_hash hash = nk_murmur_hash(id, (int)nk_strlen(id), NK_PANEL_MENU);
17366 
17367  NK_ASSERT(ctx);
17368  NK_ASSERT(ctx->current);
17369  NK_ASSERT(ctx->current->layout);
17370  if (!ctx || !ctx->current || !ctx->current->layout)
17371  return 0;
17372 
17373  body.x = header.x;
17374  body.w = size.x;
17375  body.y = header.y + header.h;
17376  body.h = size.y;
17377 
17378  popup = win->popup.win;
17379  is_open = popup ? nk_true : nk_false;
17380  is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_MENU);
17381  if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
17382  (!is_open && !is_active && !is_clicked)) return 0;
17383  if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR, body, header, NK_PANEL_MENU))
17384  return 0;
17385 
17387  win->popup.name = hash;
17388  return 1;
17389 }
17390 NK_API int
17391 nk_menu_begin_text(struct nk_context *ctx, const char *title, int len,
17392  nk_flags align, struct nk_vec2 size)
17393 {
17394  struct nk_window *win;
17395  const struct nk_input *in;
17396  struct nk_rect header;
17397  int is_clicked = nk_false;
17398  nk_flags state;
17399 
17400  NK_ASSERT(ctx);
17401  NK_ASSERT(ctx->current);
17402  NK_ASSERT(ctx->current->layout);
17403  if (!ctx || !ctx->current || !ctx->current->layout)
17404  return 0;
17405 
17406  win = ctx->current;
17407  state = nk_widget(&header, ctx);
17408  if (!state) return 0;
17409  in = (state == NK_WIDGET_ROM || win->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17410  if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, header,
17411  title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
17412  is_clicked = nk_true;
17413  return nk_menu_begin(ctx, win, title, is_clicked, header, size);
17414 }
17415 NK_API int nk_menu_begin_label(struct nk_context *ctx,
17416  const char *text, nk_flags align, struct nk_vec2 size)
17417 {
17418  return nk_menu_begin_text(ctx, text, nk_strlen(text), align, size);
17419 }
17420 NK_API int
17421 nk_menu_begin_image(struct nk_context *ctx, const char *id, struct nk_image img,
17422  struct nk_vec2 size)
17423 {
17424  struct nk_window *win;
17425  struct nk_rect header;
17426  const struct nk_input *in;
17427  int is_clicked = nk_false;
17428  nk_flags state;
17429 
17430  NK_ASSERT(ctx);
17431  NK_ASSERT(ctx->current);
17432  NK_ASSERT(ctx->current->layout);
17433  if (!ctx || !ctx->current || !ctx->current->layout)
17434  return 0;
17435 
17436  win = ctx->current;
17437  state = nk_widget(&header, ctx);
17438  if (!state) return 0;
17439  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17440  if (nk_do_button_image(&ctx->last_widget_state, &win->buffer, header,
17441  img, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in))
17442  is_clicked = nk_true;
17443  return nk_menu_begin(ctx, win, id, is_clicked, header, size);
17444 }
17445 NK_API int
17446 nk_menu_begin_symbol(struct nk_context *ctx, const char *id,
17447  enum nk_symbol_type sym, struct nk_vec2 size)
17448 {
17449  struct nk_window *win;
17450  const struct nk_input *in;
17451  struct nk_rect header;
17452  int is_clicked = nk_false;
17453  nk_flags state;
17454 
17455  NK_ASSERT(ctx);
17456  NK_ASSERT(ctx->current);
17457  NK_ASSERT(ctx->current->layout);
17458  if (!ctx || !ctx->current || !ctx->current->layout)
17459  return 0;
17460 
17461  win = ctx->current;
17462  state = nk_widget(&header, ctx);
17463  if (!state) return 0;
17464  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17465  if (nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, header,
17466  sym, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
17467  is_clicked = nk_true;
17468  return nk_menu_begin(ctx, win, id, is_clicked, header, size);
17469 }
17470 NK_API int
17471 nk_menu_begin_image_text(struct nk_context *ctx, const char *title, int len,
17472  nk_flags align, struct nk_image img, struct nk_vec2 size)
17473 {
17474  struct nk_window *win;
17475  struct nk_rect header;
17476  const struct nk_input *in;
17477  int is_clicked = nk_false;
17478  nk_flags state;
17479 
17480  NK_ASSERT(ctx);
17481  NK_ASSERT(ctx->current);
17482  NK_ASSERT(ctx->current->layout);
17483  if (!ctx || !ctx->current || !ctx->current->layout)
17484  return 0;
17485 
17486  win = ctx->current;
17487  state = nk_widget(&header, ctx);
17488  if (!state) return 0;
17489  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17490  if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
17491  header, img, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
17492  ctx->style.font, in))
17493  is_clicked = nk_true;
17494  return nk_menu_begin(ctx, win, title, is_clicked, header, size);
17495 }
17496 NK_API int
17498  const char *title, nk_flags align, struct nk_image img, struct nk_vec2 size)
17499 {
17500  return nk_menu_begin_image_text(ctx, title, nk_strlen(title), align, img, size);
17501 }
17502 NK_API int
17503 nk_menu_begin_symbol_text(struct nk_context *ctx, const char *title, int len,
17504  nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size)
17505 {
17506  struct nk_window *win;
17507  struct nk_rect header;
17508  const struct nk_input *in;
17509  int is_clicked = nk_false;
17510  nk_flags state;
17511 
17512  NK_ASSERT(ctx);
17513  NK_ASSERT(ctx->current);
17514  NK_ASSERT(ctx->current->layout);
17515  if (!ctx || !ctx->current || !ctx->current->layout)
17516  return 0;
17517 
17518  win = ctx->current;
17519  state = nk_widget(&header, ctx);
17520  if (!state) return 0;
17521 
17522  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17523  if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer,
17524  header, sym, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
17525  ctx->style.font, in)) is_clicked = nk_true;
17526  return nk_menu_begin(ctx, win, title, is_clicked, header, size);
17527 }
17528 NK_API int
17530  const char *title, nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size )
17531 {
17532  return nk_menu_begin_symbol_text(ctx, title, nk_strlen(title), align,sym,size);
17533 }
17534 NK_API int
17535 nk_menu_item_text(struct nk_context *ctx, const char *title, int len, nk_flags align)
17536 {
17537  return nk_contextual_item_text(ctx, title, len, align);
17538 }
17539 NK_API int
17540 nk_menu_item_label(struct nk_context *ctx, const char *label, nk_flags align)
17541 {
17542  return nk_contextual_item_label(ctx, label, align);
17543 }
17544 NK_API int
17545 nk_menu_item_image_label(struct nk_context *ctx, struct nk_image img,
17546  const char *label, nk_flags align)
17547 {
17548  return nk_contextual_item_image_label(ctx, img, label, align);
17549 }
17550 NK_API int
17551 nk_menu_item_image_text(struct nk_context *ctx, struct nk_image img,
17552  const char *text, int len, nk_flags align)
17553 {
17554  return nk_contextual_item_image_text(ctx, img, text, len, align);
17555 }
17556 NK_API int nk_menu_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym,
17557  const char *text, int len, nk_flags align)
17558 {
17559  return nk_contextual_item_symbol_text(ctx, sym, text, len, align);
17560 }
17561 NK_API int nk_menu_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym,
17562  const char *label, nk_flags align)
17563 {
17564  return nk_contextual_item_symbol_label(ctx, sym, label, align);
17565 }
17566 NK_API void nk_menu_close(struct nk_context *ctx)
17567 {
17568  nk_contextual_close(ctx);
17569 }
17570 NK_API void
17571 nk_menu_end(struct nk_context *ctx)
17572 {
17573  nk_contextual_end(ctx);
17574 }
17575 
17576 
17577 
17578 
17579 
17580 /* ===============================================================
17581  *
17582  * LAYOUT
17583  *
17584  * ===============================================================*/
17585 NK_API void
17586 nk_layout_set_min_row_height(struct nk_context *ctx, float height)
17587 {
17588  struct nk_window *win;
17589  struct nk_panel *layout;
17590 
17591  NK_ASSERT(ctx);
17592  NK_ASSERT(ctx->current);
17593  NK_ASSERT(ctx->current->layout);
17594  if (!ctx || !ctx->current || !ctx->current->layout)
17595  return;
17596 
17597  win = ctx->current;
17598  layout = win->layout;
17599  layout->row.min_height = height;
17600 }
17601 NK_API void
17603 {
17604  struct nk_window *win;
17605  struct nk_panel *layout;
17606 
17607  NK_ASSERT(ctx);
17608  NK_ASSERT(ctx->current);
17609  NK_ASSERT(ctx->current->layout);
17610  if (!ctx || !ctx->current || !ctx->current->layout)
17611  return;
17612 
17613  win = ctx->current;
17614  layout = win->layout;
17615  layout->row.min_height = ctx->style.font->height;
17616  layout->row.min_height += ctx->style.text.padding.y*2;
17617  layout->row.min_height += ctx->style.window.min_row_height_padding*2;
17618 }
17619 NK_LIB float
17620 nk_layout_row_calculate_usable_space(const struct nk_style *style, enum nk_panel_type type,
17621  float total_space, int columns)
17622 {
17623  float panel_padding;
17624  float panel_spacing;
17625  float panel_space;
17626 
17627  struct nk_vec2 spacing;
17628  struct nk_vec2 padding;
17629 
17630  spacing = style->window.spacing;
17631  padding = nk_panel_get_padding(style, type);
17632 
17633  /* calculate the usable panel space */
17634  panel_padding = 2 * padding.x;
17635  panel_spacing = (float)NK_MAX(columns - 1, 0) * spacing.x;
17636  panel_space = total_space - panel_padding - panel_spacing;
17637  return panel_space;
17638 }
17639 NK_LIB void
17640 nk_panel_layout(const struct nk_context *ctx, struct nk_window *win,
17641  float height, int cols)
17642 {
17643  struct nk_panel *layout;
17644  const struct nk_style *style;
17645  struct nk_command_buffer *out;
17646 
17647  struct nk_vec2 item_spacing;
17648  struct nk_color color;
17649 
17650  NK_ASSERT(ctx);
17651  NK_ASSERT(ctx->current);
17652  NK_ASSERT(ctx->current->layout);
17653  if (!ctx || !ctx->current || !ctx->current->layout)
17654  return;
17655 
17656  /* prefetch some configuration data */
17657  layout = win->layout;
17658  style = &ctx->style;
17659  out = &win->buffer;
17660  color = style->window.background;
17661  item_spacing = style->window.spacing;
17662 
17663  /* if one of these triggers you forgot to add an `if` condition around either
17664  a window, group, popup, combobox or contextual menu `begin` and `end` block.
17665  Example:
17666  if (nk_begin(...) {...} nk_end(...); or
17667  if (nk_group_begin(...) { nk_group_end(...);} */
17668  NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED));
17669  NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN));
17670  NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED));
17671 
17672  /* update the current row and set the current row layout */
17673  layout->row.index = 0;
17674  layout->at_y += layout->row.height;
17675  layout->row.columns = cols;
17676  if (height == 0.0f)
17677  layout->row.height = NK_MAX(height, layout->row.min_height) + item_spacing.y;
17678  else layout->row.height = height + item_spacing.y;
17679 
17680  layout->row.item_offset = 0;
17681  if (layout->flags & NK_WINDOW_DYNAMIC) {
17682  /* draw background for dynamic panels */
17683  struct nk_rect background;
17684  background.x = win->bounds.x;
17685  background.w = win->bounds.w;
17686  background.y = layout->at_y - 1.0f;
17687  background.h = layout->row.height + 1.0f;
17688  nk_fill_rect(out, background, 0, color);
17689  }
17690 }
17691 NK_LIB void
17692 nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt,
17693  float height, int cols, int width)
17694 {
17695  /* update the current row and set the current row layout */
17696  struct nk_window *win;
17697  NK_ASSERT(ctx);
17698  NK_ASSERT(ctx->current);
17699  NK_ASSERT(ctx->current->layout);
17700  if (!ctx || !ctx->current || !ctx->current->layout)
17701  return;
17702 
17703  win = ctx->current;
17704  nk_panel_layout(ctx, win, height, cols);
17705  if (fmt == NK_DYNAMIC)
17708 
17709  win->layout->row.ratio = 0;
17710  win->layout->row.filled = 0;
17711  win->layout->row.item_offset = 0;
17712  win->layout->row.item_width = (float)width;
17713 }
17714 NK_API float
17715 nk_layout_ratio_from_pixel(struct nk_context *ctx, float pixel_width)
17716 {
17717  struct nk_window *win;
17718  NK_ASSERT(ctx);
17719  NK_ASSERT(pixel_width);
17720  if (!ctx || !ctx->current || !ctx->current->layout) return 0;
17721  win = ctx->current;
17722  return NK_CLAMP(0.0f, pixel_width/win->bounds.x, 1.0f);
17723 }
17724 NK_API void
17725 nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols)
17726 {
17727  nk_row_layout(ctx, NK_DYNAMIC, height, cols, 0);
17728 }
17729 NK_API void
17730 nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols)
17731 {
17732  nk_row_layout(ctx, NK_STATIC, height, cols, item_width);
17733 }
17734 NK_API void
17735 nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt,
17736  float row_height, int cols)
17737 {
17738  struct nk_window *win;
17739  struct nk_panel *layout;
17740 
17741  NK_ASSERT(ctx);
17742  NK_ASSERT(ctx->current);
17743  NK_ASSERT(ctx->current->layout);
17744  if (!ctx || !ctx->current || !ctx->current->layout)
17745  return;
17746 
17747  win = ctx->current;
17748  layout = win->layout;
17749  nk_panel_layout(ctx, win, row_height, cols);
17750  if (fmt == NK_DYNAMIC)
17751  layout->row.type = NK_LAYOUT_DYNAMIC_ROW;
17752  else layout->row.type = NK_LAYOUT_STATIC_ROW;
17753 
17754  layout->row.ratio = 0;
17755  layout->row.filled = 0;
17756  layout->row.item_width = 0;
17757  layout->row.item_offset = 0;
17758  layout->row.columns = cols;
17759 }
17760 NK_API void
17761 nk_layout_row_push(struct nk_context *ctx, float ratio_or_width)
17762 {
17763  struct nk_window *win;
17764  struct nk_panel *layout;
17765 
17766  NK_ASSERT(ctx);
17767  NK_ASSERT(ctx->current);
17768  NK_ASSERT(ctx->current->layout);
17769  if (!ctx || !ctx->current || !ctx->current->layout)
17770  return;
17771 
17772  win = ctx->current;
17773  layout = win->layout;
17774  NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
17775  if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
17776  return;
17777 
17778  if (layout->row.type == NK_LAYOUT_DYNAMIC_ROW) {
17779  float ratio = ratio_or_width;
17780  if ((ratio + layout->row.filled) > 1.0f) return;
17781  if (ratio > 0.0f)
17782  layout->row.item_width = NK_SATURATE(ratio);
17783  else layout->row.item_width = 1.0f - layout->row.filled;
17784  } else layout->row.item_width = ratio_or_width;
17785 }
17786 NK_API void
17787 nk_layout_row_end(struct nk_context *ctx)
17788 {
17789  struct nk_window *win;
17790  struct nk_panel *layout;
17791 
17792  NK_ASSERT(ctx);
17793  NK_ASSERT(ctx->current);
17794  NK_ASSERT(ctx->current->layout);
17795  if (!ctx || !ctx->current || !ctx->current->layout)
17796  return;
17797 
17798  win = ctx->current;
17799  layout = win->layout;
17800  NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
17801  if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
17802  return;
17803  layout->row.item_width = 0;
17804  layout->row.item_offset = 0;
17805 }
17806 NK_API void
17807 nk_layout_row(struct nk_context *ctx, enum nk_layout_format fmt,
17808  float height, int cols, const float *ratio)
17809 {
17810  int i;
17811  int n_undef = 0;
17812  struct nk_window *win;
17813  struct nk_panel *layout;
17814 
17815  NK_ASSERT(ctx);
17816  NK_ASSERT(ctx->current);
17817  NK_ASSERT(ctx->current->layout);
17818  if (!ctx || !ctx->current || !ctx->current->layout)
17819  return;
17820 
17821  win = ctx->current;
17822  layout = win->layout;
17823  nk_panel_layout(ctx, win, height, cols);
17824  if (fmt == NK_DYNAMIC) {
17825  /* calculate width of undefined widget ratios */
17826  float r = 0;
17827  layout->row.ratio = ratio;
17828  for (i = 0; i < cols; ++i) {
17829  if (ratio[i] < 0.0f)
17830  n_undef++;
17831  else r += ratio[i];
17832  }
17833  r = NK_SATURATE(1.0f - r);
17834  layout->row.type = NK_LAYOUT_DYNAMIC;
17835  layout->row.item_width = (r > 0 && n_undef > 0) ? (r / (float)n_undef):0;
17836  } else {
17837  layout->row.ratio = ratio;
17838  layout->row.type = NK_LAYOUT_STATIC;
17839  layout->row.item_width = 0;
17840  layout->row.item_offset = 0;
17841  }
17842  layout->row.item_offset = 0;
17843  layout->row.filled = 0;
17844 }
17845 NK_API void
17846 nk_layout_row_template_begin(struct nk_context *ctx, float height)
17847 {
17848  struct nk_window *win;
17849  struct nk_panel *layout;
17850 
17851  NK_ASSERT(ctx);
17852  NK_ASSERT(ctx->current);
17853  NK_ASSERT(ctx->current->layout);
17854  if (!ctx || !ctx->current || !ctx->current->layout)
17855  return;
17856 
17857  win = ctx->current;
17858  layout = win->layout;
17859  nk_panel_layout(ctx, win, height, 1);
17860  layout->row.type = NK_LAYOUT_TEMPLATE;
17861  layout->row.columns = 0;
17862  layout->row.ratio = 0;
17863  layout->row.item_width = 0;
17864  layout->row.item_height = 0;
17865  layout->row.item_offset = 0;
17866  layout->row.filled = 0;
17867  layout->row.item.x = 0;
17868  layout->row.item.y = 0;
17869  layout->row.item.w = 0;
17870  layout->row.item.h = 0;
17871 }
17872 NK_API void
17874 {
17875  struct nk_window *win;
17876  struct nk_panel *layout;
17877 
17878  NK_ASSERT(ctx);
17879  NK_ASSERT(ctx->current);
17880  NK_ASSERT(ctx->current->layout);
17881  if (!ctx || !ctx->current || !ctx->current->layout)
17882  return;
17883 
17884  win = ctx->current;
17885  layout = win->layout;
17886  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
17887  NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
17888  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
17889  if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
17890  layout->row.templates[layout->row.columns++] = -1.0f;
17891 }
17892 NK_API void
17893 nk_layout_row_template_push_variable(struct nk_context *ctx, float min_width)
17894 {
17895  struct nk_window *win;
17896  struct nk_panel *layout;
17897 
17898  NK_ASSERT(ctx);
17899  NK_ASSERT(ctx->current);
17900  NK_ASSERT(ctx->current->layout);
17901  if (!ctx || !ctx->current || !ctx->current->layout)
17902  return;
17903 
17904  win = ctx->current;
17905  layout = win->layout;
17906  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
17907  NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
17908  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
17909  if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
17910  layout->row.templates[layout->row.columns++] = -min_width;
17911 }
17912 NK_API void
17913 nk_layout_row_template_push_static(struct nk_context *ctx, float width)
17914 {
17915  struct nk_window *win;
17916  struct nk_panel *layout;
17917 
17918  NK_ASSERT(ctx);
17919  NK_ASSERT(ctx->current);
17920  NK_ASSERT(ctx->current->layout);
17921  if (!ctx || !ctx->current || !ctx->current->layout)
17922  return;
17923 
17924  win = ctx->current;
17925  layout = win->layout;
17926  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
17927  NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
17928  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
17929  if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
17930  layout->row.templates[layout->row.columns++] = width;
17931 }
17932 NK_API void
17934 {
17935  struct nk_window *win;
17936  struct nk_panel *layout;
17937 
17938  int i = 0;
17939  int variable_count = 0;
17940  int min_variable_count = 0;
17941  float min_fixed_width = 0.0f;
17942  float total_fixed_width = 0.0f;
17943  float max_variable_width = 0.0f;
17944 
17945  NK_ASSERT(ctx);
17946  NK_ASSERT(ctx->current);
17947  NK_ASSERT(ctx->current->layout);
17948  if (!ctx || !ctx->current || !ctx->current->layout)
17949  return;
17950 
17951  win = ctx->current;
17952  layout = win->layout;
17953  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
17954  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
17955  for (i = 0; i < layout->row.columns; ++i) {
17956  float width = layout->row.templates[i];
17957  if (width >= 0.0f) {
17958  total_fixed_width += width;
17959  min_fixed_width += width;
17960  } else if (width < -1.0f) {
17961  width = -width;
17962  total_fixed_width += width;
17963  max_variable_width = NK_MAX(max_variable_width, width);
17964  variable_count++;
17965  } else {
17966  min_variable_count++;
17967  variable_count++;
17968  }
17969  }
17970  if (variable_count) {
17971  float space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
17972  layout->bounds.w, layout->row.columns);
17973  float var_width = (NK_MAX(space-min_fixed_width,0.0f)) / (float)variable_count;
17974  int enough_space = var_width >= max_variable_width;
17975  if (!enough_space)
17976  var_width = (NK_MAX(space-total_fixed_width,0)) / (float)min_variable_count;
17977  for (i = 0; i < layout->row.columns; ++i) {
17978  float *width = &layout->row.templates[i];
17979  *width = (*width >= 0.0f)? *width: (*width < -1.0f && !enough_space)? -(*width): var_width;
17980  }
17981  }
17982 }
17983 NK_API void
17984 nk_layout_space_begin(struct nk_context *ctx, enum nk_layout_format fmt,
17985  float height, int widget_count)
17986 {
17987  struct nk_window *win;
17988  struct nk_panel *layout;
17989 
17990  NK_ASSERT(ctx);
17991  NK_ASSERT(ctx->current);
17992  NK_ASSERT(ctx->current->layout);
17993  if (!ctx || !ctx->current || !ctx->current->layout)
17994  return;
17995 
17996  win = ctx->current;
17997  layout = win->layout;
17998  nk_panel_layout(ctx, win, height, widget_count);
17999  if (fmt == NK_STATIC)
18000  layout->row.type = NK_LAYOUT_STATIC_FREE;
18001  else layout->row.type = NK_LAYOUT_DYNAMIC_FREE;
18002 
18003  layout->row.ratio = 0;
18004  layout->row.filled = 0;
18005  layout->row.item_width = 0;
18006  layout->row.item_offset = 0;
18007 }
18008 NK_API void
18009 nk_layout_space_end(struct nk_context *ctx)
18010 {
18011  struct nk_window *win;
18012  struct nk_panel *layout;
18013 
18014  NK_ASSERT(ctx);
18015  NK_ASSERT(ctx->current);
18016  NK_ASSERT(ctx->current->layout);
18017  if (!ctx || !ctx->current || !ctx->current->layout)
18018  return;
18019 
18020  win = ctx->current;
18021  layout = win->layout;
18022  layout->row.item_width = 0;
18023  layout->row.item_height = 0;
18024  layout->row.item_offset = 0;
18025  nk_zero(&layout->row.item, sizeof(layout->row.item));
18026 }
18027 NK_API void
18028 nk_layout_space_push(struct nk_context *ctx, struct nk_rect rect)
18029 {
18030  struct nk_window *win;
18031  struct nk_panel *layout;
18032 
18033  NK_ASSERT(ctx);
18034  NK_ASSERT(ctx->current);
18035  NK_ASSERT(ctx->current->layout);
18036  if (!ctx || !ctx->current || !ctx->current->layout)
18037  return;
18038 
18039  win = ctx->current;
18040  layout = win->layout;
18041  layout->row.item = rect;
18042 }
18043 NK_API struct nk_rect
18045 {
18046  struct nk_rect ret;
18047  struct nk_window *win;
18048  struct nk_panel *layout;
18049 
18050  NK_ASSERT(ctx);
18051  NK_ASSERT(ctx->current);
18052  NK_ASSERT(ctx->current->layout);
18053  win = ctx->current;
18054  layout = win->layout;
18055 
18056  ret.x = layout->clip.x;
18057  ret.y = layout->clip.y;
18058  ret.w = layout->clip.w;
18059  ret.h = layout->row.height;
18060  return ret;
18061 }
18062 NK_API struct nk_rect
18064 {
18065  struct nk_rect ret;
18066  struct nk_window *win;
18067  struct nk_panel *layout;
18068 
18069  NK_ASSERT(ctx);
18070  NK_ASSERT(ctx->current);
18071  NK_ASSERT(ctx->current->layout);
18072  win = ctx->current;
18073  layout = win->layout;
18074 
18075  ret.x = layout->at_x;
18076  ret.y = layout->at_y;
18077  ret.w = layout->bounds.w - NK_MAX(layout->at_x - layout->bounds.x,0);
18078  ret.h = layout->row.height;
18079  return ret;
18080 }
18081 NK_API struct nk_vec2
18082 nk_layout_space_to_screen(struct nk_context *ctx, struct nk_vec2 ret)
18083 {
18084  struct nk_window *win;
18085  struct nk_panel *layout;
18086 
18087  NK_ASSERT(ctx);
18088  NK_ASSERT(ctx->current);
18089  NK_ASSERT(ctx->current->layout);
18090  win = ctx->current;
18091  layout = win->layout;
18092 
18093  ret.x += layout->at_x - (float)*layout->offset_x;
18094  ret.y += layout->at_y - (float)*layout->offset_y;
18095  return ret;
18096 }
18097 NK_API struct nk_vec2
18098 nk_layout_space_to_local(struct nk_context *ctx, struct nk_vec2 ret)
18099 {
18100  struct nk_window *win;
18101  struct nk_panel *layout;
18102 
18103  NK_ASSERT(ctx);
18104  NK_ASSERT(ctx->current);
18105  NK_ASSERT(ctx->current->layout);
18106  win = ctx->current;
18107  layout = win->layout;
18108 
18109  ret.x += -layout->at_x + (float)*layout->offset_x;
18110  ret.y += -layout->at_y + (float)*layout->offset_y;
18111  return ret;
18112 }
18113 NK_API struct nk_rect
18114 nk_layout_space_rect_to_screen(struct nk_context *ctx, struct nk_rect ret)
18115 {
18116  struct nk_window *win;
18117  struct nk_panel *layout;
18118 
18119  NK_ASSERT(ctx);
18120  NK_ASSERT(ctx->current);
18121  NK_ASSERT(ctx->current->layout);
18122  win = ctx->current;
18123  layout = win->layout;
18124 
18125  ret.x += layout->at_x - (float)*layout->offset_x;
18126  ret.y += layout->at_y - (float)*layout->offset_y;
18127  return ret;
18128 }
18129 NK_API struct nk_rect
18130 nk_layout_space_rect_to_local(struct nk_context *ctx, struct nk_rect ret)
18131 {
18132  struct nk_window *win;
18133  struct nk_panel *layout;
18134 
18135  NK_ASSERT(ctx);
18136  NK_ASSERT(ctx->current);
18137  NK_ASSERT(ctx->current->layout);
18138  win = ctx->current;
18139  layout = win->layout;
18140 
18141  ret.x += -layout->at_x + (float)*layout->offset_x;
18142  ret.y += -layout->at_y + (float)*layout->offset_y;
18143  return ret;
18144 }
18145 NK_LIB void
18146 nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win)
18147 {
18148  struct nk_panel *layout = win->layout;
18149  struct nk_vec2 spacing = ctx->style.window.spacing;
18150  const float row_height = layout->row.height - spacing.y;
18151  nk_panel_layout(ctx, win, row_height, layout->row.columns);
18152 }
18153 NK_LIB void
18154 nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx,
18155  struct nk_window *win, int modify)
18156 {
18157  struct nk_panel *layout;
18158  const struct nk_style *style;
18159 
18160  struct nk_vec2 spacing;
18161  struct nk_vec2 padding;
18162 
18163  float item_offset = 0;
18164  float item_width = 0;
18165  float item_spacing = 0;
18166  float panel_space = 0;
18167 
18168  NK_ASSERT(ctx);
18169  NK_ASSERT(ctx->current);
18170  NK_ASSERT(ctx->current->layout);
18171  if (!ctx || !ctx->current || !ctx->current->layout)
18172  return;
18173 
18174  win = ctx->current;
18175  layout = win->layout;
18176  style = &ctx->style;
18177  NK_ASSERT(bounds);
18178 
18179  spacing = style->window.spacing;
18180  padding = nk_panel_get_padding(style, layout->type);
18181  panel_space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
18182  layout->bounds.w, layout->row.columns);
18183 
18184  #define NK_FRAC(x) (x - (int)x) /* will be used to remove fookin gaps */
18185  /* calculate the width of one item inside the current layout space */
18186  switch (layout->row.type) {
18187  case NK_LAYOUT_DYNAMIC_FIXED: {
18188  /* scaling fixed size widgets item width */
18189  float w = NK_MAX(1.0f,panel_space) / (float)layout->row.columns;
18190  item_offset = (float)layout->row.index * w;
18191  item_width = w + NK_FRAC(item_offset);
18192  item_spacing = (float)layout->row.index * spacing.x;
18193  } break;
18194  case NK_LAYOUT_DYNAMIC_ROW: {
18195  /* scaling single ratio widget width */
18196  float w = layout->row.item_width * panel_space;
18197  item_offset = layout->row.item_offset;
18198  item_width = w + NK_FRAC(item_offset);
18199  item_spacing = 0;
18200 
18201  if (modify) {
18202  layout->row.item_offset += w + spacing.x;
18203  layout->row.filled += layout->row.item_width;
18204  layout->row.index = 0;
18205  }
18206  } break;
18207  case NK_LAYOUT_DYNAMIC_FREE: {
18208  /* panel width depended free widget placing */
18209  bounds->x = layout->at_x + (layout->bounds.w * layout->row.item.x);
18210  bounds->x -= (float)*layout->offset_x;
18211  bounds->y = layout->at_y + (layout->row.height * layout->row.item.y);
18212  bounds->y -= (float)*layout->offset_y;
18213  bounds->w = layout->bounds.w * layout->row.item.w + NK_FRAC(bounds->x);
18214  bounds->h = layout->row.height * layout->row.item.h + NK_FRAC(bounds->y);
18215  return;
18216  }
18217  case NK_LAYOUT_DYNAMIC: {
18218  /* scaling arrays of panel width ratios for every widget */
18219  float ratio, w;
18220  NK_ASSERT(layout->row.ratio);
18221  ratio = (layout->row.ratio[layout->row.index] < 0) ?
18222  layout->row.item_width : layout->row.ratio[layout->row.index];
18223 
18224  w = (ratio * panel_space);
18225  item_spacing = (float)layout->row.index * spacing.x;
18226  item_offset = layout->row.item_offset;
18227  item_width = w + NK_FRAC(item_offset);
18228 
18229  if (modify) {
18230  layout->row.item_offset += w;
18231  layout->row.filled += ratio;
18232  }
18233  } break;
18234  case NK_LAYOUT_STATIC_FIXED: {
18235  /* non-scaling fixed widgets item width */
18236  item_width = layout->row.item_width;
18237  item_offset = (float)layout->row.index * item_width;
18238  item_spacing = (float)layout->row.index * spacing.x;
18239  } break;
18240  case NK_LAYOUT_STATIC_ROW: {
18241  /* scaling single ratio widget width */
18242  item_width = layout->row.item_width;
18243  item_offset = layout->row.item_offset;
18244  item_spacing = (float)layout->row.index * spacing.x;
18245  if (modify) layout->row.item_offset += item_width;
18246  } break;
18247  case NK_LAYOUT_STATIC_FREE: {
18248  /* free widget placing */
18249  bounds->x = layout->at_x + layout->row.item.x;
18250  bounds->w = layout->row.item.w;
18251  if (((bounds->x + bounds->w) > layout->max_x) && modify)
18252  layout->max_x = (bounds->x + bounds->w);
18253  bounds->x -= (float)*layout->offset_x;
18254  bounds->y = layout->at_y + layout->row.item.y;
18255  bounds->y -= (float)*layout->offset_y;
18256  bounds->h = layout->row.item.h;
18257  return;
18258  }
18259  case NK_LAYOUT_STATIC: {
18260  /* non-scaling array of panel pixel width for every widget */
18261  item_spacing = (float)layout->row.index * spacing.x;
18262  item_width = layout->row.ratio[layout->row.index];
18263  item_offset = layout->row.item_offset;
18264  if (modify) layout->row.item_offset += item_width;
18265  } break;
18266  case NK_LAYOUT_TEMPLATE: {
18267  /* stretchy row layout with combined dynamic/static widget width*/
18268  float w;
18269  NK_ASSERT(layout->row.index < layout->row.columns);
18270  NK_ASSERT(layout->row.index < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
18271  w = layout->row.templates[layout->row.index];
18272  item_offset = layout->row.item_offset;
18273  item_width = w + NK_FRAC(item_offset);
18274  item_spacing = (float)layout->row.index * spacing.x;
18275  if (modify) layout->row.item_offset += w;
18276  } break;
18277  #undef NK_FRAC
18278  default: NK_ASSERT(0); break;
18279  };
18280 
18281  /* set the bounds of the newly allocated widget */
18282  bounds->w = item_width;
18283  bounds->h = layout->row.height - spacing.y;
18284  bounds->y = layout->at_y - (float)*layout->offset_y;
18285  bounds->x = layout->at_x + item_offset + item_spacing + padding.x;
18286  if (((bounds->x + bounds->w) > layout->max_x) && modify)
18287  layout->max_x = bounds->x + bounds->w;
18288  bounds->x -= (float)*layout->offset_x;
18289 }
18290 NK_LIB void
18291 nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx)
18292 {
18293  struct nk_window *win;
18294  struct nk_panel *layout;
18295 
18296  NK_ASSERT(ctx);
18297  NK_ASSERT(ctx->current);
18298  NK_ASSERT(ctx->current->layout);
18299  if (!ctx || !ctx->current || !ctx->current->layout)
18300  return;
18301 
18302  /* check if the end of the row has been hit and begin new row if so */
18303  win = ctx->current;
18304  layout = win->layout;
18305  if (layout->row.index >= layout->row.columns)
18306  nk_panel_alloc_row(ctx, win);
18307 
18308  /* calculate widget position and size */
18309  nk_layout_widget_space(bounds, ctx, win, nk_true);
18310  layout->row.index++;
18311 }
18312 NK_LIB void
18313 nk_layout_peek(struct nk_rect *bounds, struct nk_context *ctx)
18314 {
18315  float y;
18316  int index;
18317  struct nk_window *win;
18318  struct nk_panel *layout;
18319 
18320  NK_ASSERT(ctx);
18321  NK_ASSERT(ctx->current);
18322  NK_ASSERT(ctx->current->layout);
18323  if (!ctx || !ctx->current || !ctx->current->layout)
18324  return;
18325 
18326  win = ctx->current;
18327  layout = win->layout;
18328  y = layout->at_y;
18329  index = layout->row.index;
18330  if (layout->row.index >= layout->row.columns) {
18331  layout->at_y += layout->row.height;
18332  layout->row.index = 0;
18333  }
18334  nk_layout_widget_space(bounds, ctx, win, nk_false);
18335  if (!layout->row.index) {
18336  bounds->x -= layout->row.item_offset;
18337  }
18338  layout->at_y = y;
18339  layout->row.index = index;
18340 }
18341 
18342 
18343 
18344 
18345 
18346 /* ===============================================================
18347  *
18348  * TREE
18349  *
18350  * ===============================================================*/
18351 NK_INTERN int
18352 nk_tree_state_base(struct nk_context *ctx, enum nk_tree_type type,
18353  struct nk_image *img, const char *title, enum nk_collapse_states *state)
18354 {
18355  struct nk_window *win;
18356  struct nk_panel *layout;
18357  const struct nk_style *style;
18358  struct nk_command_buffer *out;
18359  const struct nk_input *in;
18360  const struct nk_style_button *button;
18361  enum nk_symbol_type symbol;
18362  float row_height;
18363 
18364  struct nk_vec2 item_spacing;
18365  struct nk_rect header = {0,0,0,0};
18366  struct nk_rect sym = {0,0,0,0};
18367  struct nk_text text;
18368 
18369  nk_flags ws = 0;
18370  enum nk_widget_layout_states widget_state;
18371 
18372  NK_ASSERT(ctx);
18373  NK_ASSERT(ctx->current);
18374  NK_ASSERT(ctx->current->layout);
18375  if (!ctx || !ctx->current || !ctx->current->layout)
18376  return 0;
18377 
18378  /* cache some data */
18379  win = ctx->current;
18380  layout = win->layout;
18381  out = &win->buffer;
18382  style = &ctx->style;
18383  item_spacing = style->window.spacing;
18384 
18385  /* calculate header bounds and draw background */
18386  row_height = style->font->height + 2 * style->tab.padding.y;
18387  nk_layout_set_min_row_height(ctx, row_height);
18388  nk_layout_row_dynamic(ctx, row_height, 1);
18390 
18391  widget_state = nk_widget(&header, ctx);
18392  if (type == NK_TREE_TAB) {
18393  const struct nk_style_item *background = &style->tab.background;
18394  if (background->type == NK_STYLE_ITEM_IMAGE) {
18395  nk_draw_image(out, header, &background->data.image, nk_white);
18396  text.background = nk_rgba(0,0,0,0);
18397  } else {
18398  text.background = background->data.color;
18399  nk_fill_rect(out, header, 0, style->tab.border_color);
18400  nk_fill_rect(out, nk_shrink_rect(header, style->tab.border),
18401  style->tab.rounding, background->data.color);
18402  }
18403  } else text.background = style->window.background;
18404 
18405  /* update node state */
18406  in = (!(layout->flags & NK_WINDOW_ROM)) ? &ctx->input: 0;
18407  in = (in && widget_state == NK_WIDGET_VALID) ? &ctx->input : 0;
18408  if (nk_button_behavior(&ws, header, in, NK_BUTTON_DEFAULT))
18409  *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED;
18410 
18411  /* select correct button style */
18412  if (*state == NK_MAXIMIZED) {
18413  symbol = style->tab.sym_maximize;
18414  if (type == NK_TREE_TAB)
18415  button = &style->tab.tab_maximize_button;
18416  else button = &style->tab.node_maximize_button;
18417  } else {
18418  symbol = style->tab.sym_minimize;
18419  if (type == NK_TREE_TAB)
18420  button = &style->tab.tab_minimize_button;
18421  else button = &style->tab.node_minimize_button;
18422  }
18423 
18424  {/* draw triangle button */
18425  sym.w = sym.h = style->font->height;
18426  sym.y = header.y + style->tab.padding.y;
18427  sym.x = header.x + style->tab.padding.x;
18428  nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT,
18429  button, 0, style->font);
18430 
18431  if (img) {
18432  /* draw optional image icon */
18433  sym.x = sym.x + sym.w + 4 * item_spacing.x;
18434  nk_draw_image(&win->buffer, sym, img, nk_white);
18435  sym.w = style->font->height + style->tab.spacing.x;}
18436  }
18437 
18438  {/* draw label */
18439  struct nk_rect label;
18440  header.w = NK_MAX(header.w, sym.w + item_spacing.x);
18441  label.x = sym.x + sym.w + item_spacing.x;
18442  label.y = sym.y;
18443  label.w = header.w - (sym.w + item_spacing.y + style->tab.indent);
18444  label.h = style->font->height;
18445  text.text = style->tab.text;
18446  text.padding = nk_vec2(0,0);
18447  nk_widget_text(out, label, title, nk_strlen(title), &text,
18448  NK_TEXT_LEFT, style->font);}
18449 
18450  /* increase x-axis cursor widget position pointer */
18451  if (*state == NK_MAXIMIZED) {
18452  layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent;
18453  layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent);
18454  layout->bounds.w -= (style->tab.indent + style->window.padding.x);
18455  layout->row.tree_depth++;
18456  return nk_true;
18457  } else return nk_false;
18458 }
18459 NK_INTERN int
18460 nk_tree_base(struct nk_context *ctx, enum nk_tree_type type,
18461  struct nk_image *img, const char *title, enum nk_collapse_states initial_state,
18462  const char *hash, int len, int line)
18463 {
18464  struct nk_window *win = ctx->current;
18465  int title_len = 0;
18466  nk_hash tree_hash = 0;
18467  nk_uint *state = 0;
18468 
18469  /* retrieve tree state from internal widget state tables */
18470  if (!hash) {
18471  title_len = (int)nk_strlen(title);
18472  tree_hash = nk_murmur_hash(title, (int)title_len, (nk_hash)line);
18473  } else tree_hash = nk_murmur_hash(hash, len, (nk_hash)line);
18474  state = nk_find_value(win, tree_hash);
18475  if (!state) {
18476  state = nk_add_value(ctx, win, tree_hash, 0);
18477  *state = initial_state;
18478  }
18479  return nk_tree_state_base(ctx, type, img, title, (enum nk_collapse_states*)state);
18480 }
18481 NK_API int
18482 nk_tree_state_push(struct nk_context *ctx, enum nk_tree_type type,
18483  const char *title, enum nk_collapse_states *state)
18484 {
18485  return nk_tree_state_base(ctx, type, 0, title, state);
18486 }
18487 NK_API int
18488 nk_tree_state_image_push(struct nk_context *ctx, enum nk_tree_type type,
18489  struct nk_image img, const char *title, enum nk_collapse_states *state)
18490 {
18491  return nk_tree_state_base(ctx, type, &img, title, state);
18492 }
18493 NK_API void
18494 nk_tree_state_pop(struct nk_context *ctx)
18495 {
18496  struct nk_window *win = 0;
18497  struct nk_panel *layout = 0;
18498 
18499  NK_ASSERT(ctx);
18500  NK_ASSERT(ctx->current);
18501  NK_ASSERT(ctx->current->layout);
18502  if (!ctx || !ctx->current || !ctx->current->layout)
18503  return;
18504 
18505  win = ctx->current;
18506  layout = win->layout;
18507  layout->at_x -= ctx->style.tab.indent + ctx->style.window.padding.x;
18508  layout->bounds.w += ctx->style.tab.indent + ctx->style.window.padding.x;
18509  NK_ASSERT(layout->row.tree_depth);
18510  layout->row.tree_depth--;
18511 }
18512 NK_API int
18514  const char *title, enum nk_collapse_states initial_state,
18515  const char *hash, int len, int line)
18516 {
18517  return nk_tree_base(ctx, type, 0, title, initial_state, hash, len, line);
18518 }
18519 NK_API int
18521  struct nk_image img, const char *title, enum nk_collapse_states initial_state,
18522  const char *hash, int len,int seed)
18523 {
18524  return nk_tree_base(ctx, type, &img, title, initial_state, hash, len, seed);
18525 }
18526 NK_API void
18527 nk_tree_pop(struct nk_context *ctx)
18528 {
18529  nk_tree_state_pop(ctx);
18530 }
18531 NK_INTERN int
18532 nk_tree_element_image_push_hashed_base(struct nk_context *ctx, enum nk_tree_type type,
18533  struct nk_image *img, const char *title, int title_len,
18534  enum nk_collapse_states *state, int *selected)
18535 {
18536  struct nk_window *win;
18537  struct nk_panel *layout;
18538  const struct nk_style *style;
18539  struct nk_command_buffer *out;
18540  const struct nk_input *in;
18541  const struct nk_style_button *button;
18542  enum nk_symbol_type symbol;
18543  float row_height;
18544  struct nk_vec2 padding;
18545 
18546  int text_len;
18547  float text_width;
18548 
18549  struct nk_vec2 item_spacing;
18550  struct nk_rect header = {0,0,0,0};
18551  struct nk_rect sym = {0,0,0,0};
18552  struct nk_text text;
18553 
18554  nk_flags ws = 0;
18555  enum nk_widget_layout_states widget_state;
18556 
18557  NK_ASSERT(ctx);
18558  NK_ASSERT(ctx->current);
18559  NK_ASSERT(ctx->current->layout);
18560  if (!ctx || !ctx->current || !ctx->current->layout)
18561  return 0;
18562 
18563  /* cache some data */
18564  win = ctx->current;
18565  layout = win->layout;
18566  out = &win->buffer;
18567  style = &ctx->style;
18568  item_spacing = style->window.spacing;
18569  padding = style->selectable.padding;
18570 
18571  /* calculate header bounds and draw background */
18572  row_height = style->font->height + 2 * style->tab.padding.y;
18573  nk_layout_set_min_row_height(ctx, row_height);
18574  nk_layout_row_dynamic(ctx, row_height, 1);
18576 
18577  widget_state = nk_widget(&header, ctx);
18578  if (type == NK_TREE_TAB) {
18579  const struct nk_style_item *background = &style->tab.background;
18580  if (background->type == NK_STYLE_ITEM_IMAGE) {
18581  nk_draw_image(out, header, &background->data.image, nk_white);
18582  text.background = nk_rgba(0,0,0,0);
18583  } else {
18584  text.background = background->data.color;
18585  nk_fill_rect(out, header, 0, style->tab.border_color);
18586  nk_fill_rect(out, nk_shrink_rect(header, style->tab.border),
18587  style->tab.rounding, background->data.color);
18588  }
18589  } else text.background = style->window.background;
18590 
18591  in = (!(layout->flags & NK_WINDOW_ROM)) ? &ctx->input: 0;
18592  in = (in && widget_state == NK_WIDGET_VALID) ? &ctx->input : 0;
18593 
18594  /* select correct button style */
18595  if (*state == NK_MAXIMIZED) {
18596  symbol = style->tab.sym_maximize;
18597  if (type == NK_TREE_TAB)
18598  button = &style->tab.tab_maximize_button;
18599  else button = &style->tab.node_maximize_button;
18600  } else {
18601  symbol = style->tab.sym_minimize;
18602  if (type == NK_TREE_TAB)
18603  button = &style->tab.tab_minimize_button;
18604  else button = &style->tab.node_minimize_button;
18605  }
18606  {/* draw triangle button */
18607  sym.w = sym.h = style->font->height;
18608  sym.y = header.y + style->tab.padding.y;
18609  sym.x = header.x + style->tab.padding.x;
18610  if (nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT, button, in, style->font))
18611  *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED;}
18612 
18613  /* draw label */
18614  {nk_flags dummy = 0;
18615  struct nk_rect label;
18616  /* calculate size of the text and tooltip */
18617  text_len = nk_strlen(title);
18618  text_width = style->font->width(style->font->userdata, style->font->height, title, text_len);
18619  text_width += (4 * padding.x);
18620 
18621  header.w = NK_MAX(header.w, sym.w + item_spacing.x);
18622  label.x = sym.x + sym.w + item_spacing.x;
18623  label.y = sym.y;
18624  label.w = NK_MIN(header.w - (sym.w + item_spacing.y + style->tab.indent), text_width);
18625  label.h = style->font->height;
18626 
18627  if (img) {
18628  nk_do_selectable_image(&dummy, &win->buffer, label, title, title_len, NK_TEXT_LEFT,
18629  selected, img, &style->selectable, in, style->font);
18630  } else nk_do_selectable(&dummy, &win->buffer, label, title, title_len, NK_TEXT_LEFT,
18631  selected, &style->selectable, in, style->font);
18632  }
18633  /* increase x-axis cursor widget position pointer */
18634  if (*state == NK_MAXIMIZED) {
18635  layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent;
18636  layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent);
18637  layout->bounds.w -= (style->tab.indent + style->window.padding.x);
18638  layout->row.tree_depth++;
18639  return nk_true;
18640  } else return nk_false;
18641 }
18642 NK_INTERN int
18643 nk_tree_element_base(struct nk_context *ctx, enum nk_tree_type type,
18644  struct nk_image *img, const char *title, enum nk_collapse_states initial_state,
18645  int *selected, const char *hash, int len, int line)
18646 {
18647  struct nk_window *win = ctx->current;
18648  int title_len = 0;
18649  nk_hash tree_hash = 0;
18650  nk_uint *state = 0;
18651 
18652  /* retrieve tree state from internal widget state tables */
18653  if (!hash) {
18654  title_len = (int)nk_strlen(title);
18655  tree_hash = nk_murmur_hash(title, (int)title_len, (nk_hash)line);
18656  } else tree_hash = nk_murmur_hash(hash, len, (nk_hash)line);
18657  state = nk_find_value(win, tree_hash);
18658  if (!state) {
18659  state = nk_add_value(ctx, win, tree_hash, 0);
18660  *state = initial_state;
18661  } return nk_tree_element_image_push_hashed_base(ctx, type, img, title,
18662  nk_strlen(title), (enum nk_collapse_states*)state, selected);
18663 }
18664 NK_API int
18665 nk_tree_element_push_hashed(struct nk_context *ctx, enum nk_tree_type type,
18666  const char *title, enum nk_collapse_states initial_state,
18667  int *selected, const char *hash, int len, int seed)
18668 {
18669  return nk_tree_element_base(ctx, type, 0, title, initial_state, selected, hash, len, seed);
18670 }
18671 NK_API int
18673  struct nk_image img, const char *title, enum nk_collapse_states initial_state,
18674  int *selected, const char *hash, int len,int seed)
18675 {
18676  return nk_tree_element_base(ctx, type, &img, title, initial_state, selected, hash, len, seed);
18677 }
18678 NK_API void
18679 nk_tree_element_pop(struct nk_context *ctx)
18680 {
18681  nk_tree_state_pop(ctx);
18682 }
18683 
18684 
18685 
18686 
18687 
18688 /* ===============================================================
18689  *
18690  * GROUP
18691  *
18692  * ===============================================================*/
18693 NK_API int
18695  nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags)
18696 {
18697  struct nk_rect bounds;
18698  struct nk_window panel;
18699  struct nk_window *win;
18700 
18701  win = ctx->current;
18702  nk_panel_alloc_space(&bounds, ctx);
18703  {const struct nk_rect *c = &win->layout->clip;
18704  if (!NK_INTERSECT(c->x, c->y, c->w, c->h, bounds.x, bounds.y, bounds.w, bounds.h) &&
18705  !(flags & NK_WINDOW_MOVABLE)) {
18706  return 0;
18707  }}
18708  if (win->flags & NK_WINDOW_ROM)
18709  flags |= NK_WINDOW_ROM;
18710 
18711  /* initialize a fake window to create the panel from */
18712  nk_zero(&panel, sizeof(panel));
18713  panel.bounds = bounds;
18714  panel.flags = flags;
18715  panel.scrollbar.x = *x_offset;
18716  panel.scrollbar.y = *y_offset;
18717  panel.buffer = win->buffer;
18718  panel.layout = (struct nk_panel*)nk_create_panel(ctx);
18719  ctx->current = &panel;
18720  nk_panel_begin(ctx, (flags & NK_WINDOW_TITLE) ? title: 0, NK_PANEL_GROUP);
18721 
18722  win->buffer = panel.buffer;
18723  win->buffer.clip = panel.layout->clip;
18724  panel.layout->offset_x = x_offset;
18725  panel.layout->offset_y = y_offset;
18726  panel.layout->parent = win->layout;
18727  win->layout = panel.layout;
18728 
18729  ctx->current = win;
18730  if ((panel.layout->flags & NK_WINDOW_CLOSED) ||
18731  (panel.layout->flags & NK_WINDOW_MINIMIZED))
18732  {
18733  nk_flags f = panel.layout->flags;
18734  nk_group_scrolled_end(ctx);
18735  if (f & NK_WINDOW_CLOSED)
18736  return NK_WINDOW_CLOSED;
18737  if (f & NK_WINDOW_MINIMIZED)
18738  return NK_WINDOW_MINIMIZED;
18739  }
18740  return 1;
18741 }
18742 NK_API void
18743 nk_group_scrolled_end(struct nk_context *ctx)
18744 {
18745  struct nk_window *win;
18746  struct nk_panel *parent;
18747  struct nk_panel *g;
18748 
18749  struct nk_rect clip;
18750  struct nk_window pan;
18751  struct nk_vec2 panel_padding;
18752 
18753  NK_ASSERT(ctx);
18754  NK_ASSERT(ctx->current);
18755  if (!ctx || !ctx->current)
18756  return;
18757 
18758  /* make sure nk_group_begin was called correctly */
18759  NK_ASSERT(ctx->current);
18760  win = ctx->current;
18761  NK_ASSERT(win->layout);
18762  g = win->layout;
18763  NK_ASSERT(g->parent);
18764  parent = g->parent;
18765 
18766  /* dummy window */
18767  nk_zero_struct(pan);
18768  panel_padding = nk_panel_get_padding(&ctx->style, NK_PANEL_GROUP);
18769  pan.bounds.y = g->bounds.y - (g->header_height + g->menu.h);
18770  pan.bounds.x = g->bounds.x - panel_padding.x;
18771  pan.bounds.w = g->bounds.w + 2 * panel_padding.x;
18772  pan.bounds.h = g->bounds.h + g->header_height + g->menu.h;
18773  if (g->flags & NK_WINDOW_BORDER) {
18774  pan.bounds.x -= g->border;
18775  pan.bounds.y -= g->border;
18776  pan.bounds.w += 2*g->border;
18777  pan.bounds.h += 2*g->border;
18778  }
18779  if (!(g->flags & NK_WINDOW_NO_SCROLLBAR)) {
18780  pan.bounds.w += ctx->style.window.scrollbar_size.x;
18781  pan.bounds.h += ctx->style.window.scrollbar_size.y;
18782  }
18783  pan.scrollbar.x = *g->offset_x;
18784  pan.scrollbar.y = *g->offset_y;
18785  pan.flags = g->flags;
18786  pan.buffer = win->buffer;
18787  pan.layout = g;
18788  pan.parent = win;
18789  ctx->current = &pan;
18790 
18791  /* make sure group has correct clipping rectangle */
18792  nk_unify(&clip, &parent->clip, pan.bounds.x, pan.bounds.y,
18793  pan.bounds.x + pan.bounds.w, pan.bounds.y + pan.bounds.h + panel_padding.x);
18794  nk_push_scissor(&pan.buffer, clip);
18795  nk_end(ctx);
18796 
18797  win->buffer = pan.buffer;
18798  nk_push_scissor(&win->buffer, parent->clip);
18799  ctx->current = win;
18800  win->layout = parent;
18801  g->bounds = pan.bounds;
18802  return;
18803 }
18804 NK_API int
18806  struct nk_scroll *scroll, const char *title, nk_flags flags)
18807 {
18808  return nk_group_scrolled_offset_begin(ctx, &scroll->x, &scroll->y, title, flags);
18809 }
18810 NK_API int
18811 nk_group_begin_titled(struct nk_context *ctx, const char *id,
18812  const char *title, nk_flags flags)
18813 {
18814  int id_len;
18815  nk_hash id_hash;
18816  struct nk_window *win;
18817  nk_uint *x_offset;
18818  nk_uint *y_offset;
18819 
18820  NK_ASSERT(ctx);
18821  NK_ASSERT(id);
18822  NK_ASSERT(ctx->current);
18823  NK_ASSERT(ctx->current->layout);
18824  if (!ctx || !ctx->current || !ctx->current->layout || !id)
18825  return 0;
18826 
18827  /* find persistent group scrollbar value */
18828  win = ctx->current;
18829  id_len = (int)nk_strlen(id);
18830  id_hash = nk_murmur_hash(id, (int)id_len, NK_PANEL_GROUP);
18831  x_offset = nk_find_value(win, id_hash);
18832  if (!x_offset) {
18833  x_offset = nk_add_value(ctx, win, id_hash, 0);
18834  y_offset = nk_add_value(ctx, win, id_hash+1, 0);
18835 
18836  NK_ASSERT(x_offset);
18837  NK_ASSERT(y_offset);
18838  if (!x_offset || !y_offset) return 0;
18839  *x_offset = *y_offset = 0;
18840  } else y_offset = nk_find_value(win, id_hash+1);
18841  return nk_group_scrolled_offset_begin(ctx, x_offset, y_offset, title, flags);
18842 }
18843 NK_API int
18844 nk_group_begin(struct nk_context *ctx, const char *title, nk_flags flags)
18845 {
18846  return nk_group_begin_titled(ctx, title, title, flags);
18847 }
18848 NK_API void
18849 nk_group_end(struct nk_context *ctx)
18850 {
18851  nk_group_scrolled_end(ctx);
18852 }
18853 NK_API void
18854 nk_group_get_scroll(struct nk_context *ctx, const char *id, nk_uint *x_offset, nk_uint *y_offset)
18855 {
18856  int id_len;
18857  nk_hash id_hash;
18858  struct nk_window *win;
18859  nk_uint *x_offset_ptr;
18860  nk_uint *y_offset_ptr;
18861 
18862  NK_ASSERT(ctx);
18863  NK_ASSERT(id);
18864  NK_ASSERT(ctx->current);
18865  NK_ASSERT(ctx->current->layout);
18866  if (!ctx || !ctx->current || !ctx->current->layout || !id)
18867  return;
18868 
18869  /* find persistent group scrollbar value */
18870  win = ctx->current;
18871  id_len = (int)nk_strlen(id);
18872  id_hash = nk_murmur_hash(id, (int)id_len, NK_PANEL_GROUP);
18873  x_offset_ptr = nk_find_value(win, id_hash);
18874  if (!x_offset_ptr) {
18875  x_offset_ptr = nk_add_value(ctx, win, id_hash, 0);
18876  y_offset_ptr = nk_add_value(ctx, win, id_hash+1, 0);
18877 
18878  NK_ASSERT(x_offset_ptr);
18879  NK_ASSERT(y_offset_ptr);
18880  if (!x_offset_ptr || !y_offset_ptr) return;
18881  *x_offset_ptr = *y_offset_ptr = 0;
18882  } else y_offset_ptr = nk_find_value(win, id_hash+1);
18883  if (x_offset)
18884  *x_offset = *x_offset_ptr;
18885  if (y_offset)
18886  *y_offset = *y_offset_ptr;
18887 }
18888 NK_API void
18889 nk_group_set_scroll(struct nk_context *ctx, const char *id, nk_uint x_offset, nk_uint y_offset)
18890 {
18891  int id_len;
18892  nk_hash id_hash;
18893  struct nk_window *win;
18894  nk_uint *x_offset_ptr;
18895  nk_uint *y_offset_ptr;
18896 
18897  NK_ASSERT(ctx);
18898  NK_ASSERT(id);
18899  NK_ASSERT(ctx->current);
18900  NK_ASSERT(ctx->current->layout);
18901  if (!ctx || !ctx->current || !ctx->current->layout || !id)
18902  return;
18903 
18904  /* find persistent group scrollbar value */
18905  win = ctx->current;
18906  id_len = (int)nk_strlen(id);
18907  id_hash = nk_murmur_hash(id, (int)id_len, NK_PANEL_GROUP);
18908  x_offset_ptr = nk_find_value(win, id_hash);
18909  if (!x_offset_ptr) {
18910  x_offset_ptr = nk_add_value(ctx, win, id_hash, 0);
18911  y_offset_ptr = nk_add_value(ctx, win, id_hash+1, 0);
18912 
18913  NK_ASSERT(x_offset_ptr);
18914  NK_ASSERT(y_offset_ptr);
18915  if (!x_offset_ptr || !y_offset_ptr) return;
18916  *x_offset_ptr = *y_offset_ptr = 0;
18917  } else y_offset_ptr = nk_find_value(win, id_hash+1);
18918  *x_offset_ptr = x_offset;
18919  *y_offset_ptr = y_offset;
18920 }
18921 
18922 
18923 
18924 
18925 /* ===============================================================
18926  *
18927  * LIST VIEW
18928  *
18929  * ===============================================================*/
18930 NK_API int
18931 nk_list_view_begin(struct nk_context *ctx, struct nk_list_view *view,
18932  const char *title, nk_flags flags, int row_height, int row_count)
18933 {
18934  int title_len;
18935  nk_hash title_hash;
18936  nk_uint *x_offset;
18937  nk_uint *y_offset;
18938 
18939  int result;
18940  struct nk_window *win;
18941  struct nk_panel *layout;
18942  const struct nk_style *style;
18943  struct nk_vec2 item_spacing;
18944 
18945  NK_ASSERT(ctx);
18946  NK_ASSERT(view);
18947  NK_ASSERT(title);
18948  if (!ctx || !view || !title) return 0;
18949 
18950  win = ctx->current;
18951  style = &ctx->style;
18952  item_spacing = style->window.spacing;
18953  row_height += NK_MAX(0, (int)item_spacing.y);
18954 
18955  /* find persistent list view scrollbar offset */
18956  title_len = (int)nk_strlen(title);
18957  title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_GROUP);
18958  x_offset = nk_find_value(win, title_hash);
18959  if (!x_offset) {
18960  x_offset = nk_add_value(ctx, win, title_hash, 0);
18961  y_offset = nk_add_value(ctx, win, title_hash+1, 0);
18962 
18963  NK_ASSERT(x_offset);
18964  NK_ASSERT(y_offset);
18965  if (!x_offset || !y_offset) return 0;
18966  *x_offset = *y_offset = 0;
18967  } else y_offset = nk_find_value(win, title_hash+1);
18968  view->scroll_value = *y_offset;
18969  view->scroll_pointer = y_offset;
18970 
18971  *y_offset = 0;
18972  result = nk_group_scrolled_offset_begin(ctx, x_offset, y_offset, title, flags);
18973  win = ctx->current;
18974  layout = win->layout;
18975 
18976  view->total_height = row_height * NK_MAX(row_count,1);
18977  view->begin = (int)NK_MAX(((float)view->scroll_value / (float)row_height), 0.0f);
18978  view->count = (int)NK_MAX(nk_iceilf((layout->clip.h)/(float)row_height),0);
18979  view->count = NK_MIN(view->count, row_count - view->begin);
18980  view->end = view->begin + view->count;
18981  view->ctx = ctx;
18982  return result;
18983 }
18984 NK_API void
18985 nk_list_view_end(struct nk_list_view *view)
18986 {
18987  struct nk_context *ctx;
18988  struct nk_window *win;
18989  struct nk_panel *layout;
18990 
18991  NK_ASSERT(view);
18992  NK_ASSERT(view->ctx);
18993  NK_ASSERT(view->scroll_pointer);
18994  if (!view || !view->ctx) return;
18995 
18996  ctx = view->ctx;
18997  win = ctx->current;
18998  layout = win->layout;
18999  layout->at_y = layout->bounds.y + (float)view->total_height;
19000  *view->scroll_pointer = *view->scroll_pointer + view->scroll_value;
19001  nk_group_end(view->ctx);
19002 }
19003 
19004 
19005 
19006 
19007 
19008 /* ===============================================================
19009  *
19010  * WIDGET
19011  *
19012  * ===============================================================*/
19013 NK_API struct nk_rect
19014 nk_widget_bounds(struct nk_context *ctx)
19015 {
19016  struct nk_rect bounds;
19017  NK_ASSERT(ctx);
19018  NK_ASSERT(ctx->current);
19019  if (!ctx || !ctx->current)
19020  return nk_rect(0,0,0,0);
19021  nk_layout_peek(&bounds, ctx);
19022  return bounds;
19023 }
19024 NK_API struct nk_vec2
19025 nk_widget_position(struct nk_context *ctx)
19026 {
19027  struct nk_rect bounds;
19028  NK_ASSERT(ctx);
19029  NK_ASSERT(ctx->current);
19030  if (!ctx || !ctx->current)
19031  return nk_vec2(0,0);
19032 
19033  nk_layout_peek(&bounds, ctx);
19034  return nk_vec2(bounds.x, bounds.y);
19035 }
19036 NK_API struct nk_vec2
19037 nk_widget_size(struct nk_context *ctx)
19038 {
19039  struct nk_rect bounds;
19040  NK_ASSERT(ctx);
19041  NK_ASSERT(ctx->current);
19042  if (!ctx || !ctx->current)
19043  return nk_vec2(0,0);
19044 
19045  nk_layout_peek(&bounds, ctx);
19046  return nk_vec2(bounds.w, bounds.h);
19047 }
19048 NK_API float
19049 nk_widget_width(struct nk_context *ctx)
19050 {
19051  struct nk_rect bounds;
19052  NK_ASSERT(ctx);
19053  NK_ASSERT(ctx->current);
19054  if (!ctx || !ctx->current)
19055  return 0;
19056 
19057  nk_layout_peek(&bounds, ctx);
19058  return bounds.w;
19059 }
19060 NK_API float
19061 nk_widget_height(struct nk_context *ctx)
19062 {
19063  struct nk_rect bounds;
19064  NK_ASSERT(ctx);
19065  NK_ASSERT(ctx->current);
19066  if (!ctx || !ctx->current)
19067  return 0;
19068 
19069  nk_layout_peek(&bounds, ctx);
19070  return bounds.h;
19071 }
19072 NK_API int
19073 nk_widget_is_hovered(struct nk_context *ctx)
19074 {
19075  struct nk_rect c, v;
19076  struct nk_rect bounds;
19077  NK_ASSERT(ctx);
19078  NK_ASSERT(ctx->current);
19079  if (!ctx || !ctx->current || ctx->active != ctx->current)
19080  return 0;
19081 
19082  c = ctx->current->layout->clip;
19083  c.x = (float)((int)c.x);
19084  c.y = (float)((int)c.y);
19085  c.w = (float)((int)c.w);
19086  c.h = (float)((int)c.h);
19087 
19088  nk_layout_peek(&bounds, ctx);
19089  nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
19090  if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
19091  return 0;
19092  return nk_input_is_mouse_hovering_rect(&ctx->input, bounds);
19093 }
19094 NK_API int
19095 nk_widget_is_mouse_clicked(struct nk_context *ctx, enum nk_buttons btn)
19096 {
19097  struct nk_rect c, v;
19098  struct nk_rect bounds;
19099  NK_ASSERT(ctx);
19100  NK_ASSERT(ctx->current);
19101  if (!ctx || !ctx->current || ctx->active != ctx->current)
19102  return 0;
19103 
19104  c = ctx->current->layout->clip;
19105  c.x = (float)((int)c.x);
19106  c.y = (float)((int)c.y);
19107  c.w = (float)((int)c.w);
19108  c.h = (float)((int)c.h);
19109 
19110  nk_layout_peek(&bounds, ctx);
19111  nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
19112  if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
19113  return 0;
19114  return nk_input_mouse_clicked(&ctx->input, btn, bounds);
19115 }
19116 NK_API int
19117 nk_widget_has_mouse_click_down(struct nk_context *ctx, enum nk_buttons btn, int down)
19118 {
19119  struct nk_rect c, v;
19120  struct nk_rect bounds;
19121  NK_ASSERT(ctx);
19122  NK_ASSERT(ctx->current);
19123  if (!ctx || !ctx->current || ctx->active != ctx->current)
19124  return 0;
19125 
19126  c = ctx->current->layout->clip;
19127  c.x = (float)((int)c.x);
19128  c.y = (float)((int)c.y);
19129  c.w = (float)((int)c.w);
19130  c.h = (float)((int)c.h);
19131 
19132  nk_layout_peek(&bounds, ctx);
19133  nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
19134  if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
19135  return 0;
19136  return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down);
19137 }
19139 nk_widget(struct nk_rect *bounds, const struct nk_context *ctx)
19140 {
19141  struct nk_rect c, v;
19142  struct nk_window *win;
19143  struct nk_panel *layout;
19144  const struct nk_input *in;
19145 
19146  NK_ASSERT(ctx);
19147  NK_ASSERT(ctx->current);
19148  NK_ASSERT(ctx->current->layout);
19149  if (!ctx || !ctx->current || !ctx->current->layout)
19150  return NK_WIDGET_INVALID;
19151 
19152  /* allocate space and check if the widget needs to be updated and drawn */
19153  nk_panel_alloc_space(bounds, ctx);
19154  win = ctx->current;
19155  layout = win->layout;
19156  in = &ctx->input;
19157  c = layout->clip;
19158 
19159  /* if one of these triggers you forgot to add an `if` condition around either
19160  a window, group, popup, combobox or contextual menu `begin` and `end` block.
19161  Example:
19162  if (nk_begin(...) {...} nk_end(...); or
19163  if (nk_group_begin(...) { nk_group_end(...);} */
19164  NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED));
19165  NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN));
19166  NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED));
19167 
19168  /* need to convert to int here to remove floating point errors */
19169  bounds->x = (float)((int)bounds->x);
19170  bounds->y = (float)((int)bounds->y);
19171  bounds->w = (float)((int)bounds->w);
19172  bounds->h = (float)((int)bounds->h);
19173 
19174  c.x = (float)((int)c.x);
19175  c.y = (float)((int)c.y);
19176  c.w = (float)((int)c.w);
19177  c.h = (float)((int)c.h);
19178 
19179  nk_unify(&v, &c, bounds->x, bounds->y, bounds->x + bounds->w, bounds->y + bounds->h);
19180  if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds->x, bounds->y, bounds->w, bounds->h))
19181  return NK_WIDGET_INVALID;
19182  if (!NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, v.x, v.y, v.w, v.h))
19183  return NK_WIDGET_ROM;
19184  return NK_WIDGET_VALID;
19185 }
19187 nk_widget_fitting(struct nk_rect *bounds, struct nk_context *ctx,
19188  struct nk_vec2 item_padding)
19189 {
19190  /* update the bounds to stand without padding */
19191  struct nk_window *win;
19192  struct nk_style *style;
19193  struct nk_panel *layout;
19194  enum nk_widget_layout_states state;
19195  struct nk_vec2 panel_padding;
19196 
19197  NK_ASSERT(ctx);
19198  NK_ASSERT(ctx->current);
19199  NK_ASSERT(ctx->current->layout);
19200  if (!ctx || !ctx->current || !ctx->current->layout)
19201  return NK_WIDGET_INVALID;
19202 
19203  win = ctx->current;
19204  style = &ctx->style;
19205  layout = win->layout;
19206  state = nk_widget(bounds, ctx);
19207 
19208  panel_padding = nk_panel_get_padding(style, layout->type);
19209  if (layout->row.index == 1) {
19210  bounds->w += panel_padding.x;
19211  bounds->x -= panel_padding.x;
19212  } else bounds->x -= item_padding.x;
19213 
19214  if (layout->row.index == layout->row.columns)
19215  bounds->w += panel_padding.x;
19216  else bounds->w += item_padding.x;
19217  return state;
19218 }
19219 NK_API void
19220 nk_spacing(struct nk_context *ctx, int cols)
19221 {
19222  struct nk_window *win;
19223  struct nk_panel *layout;
19224  struct nk_rect none;
19225  int i, index, rows;
19226 
19227  NK_ASSERT(ctx);
19228  NK_ASSERT(ctx->current);
19229  NK_ASSERT(ctx->current->layout);
19230  if (!ctx || !ctx->current || !ctx->current->layout)
19231  return;
19232 
19233  /* spacing over row boundaries */
19234  win = ctx->current;
19235  layout = win->layout;
19236  index = (layout->row.index + cols) % layout->row.columns;
19237  rows = (layout->row.index + cols) / layout->row.columns;
19238  if (rows) {
19239  for (i = 0; i < rows; ++i)
19240  nk_panel_alloc_row(ctx, win);
19241  cols = index;
19242  }
19243  /* non table layout need to allocate space */
19244  if (layout->row.type != NK_LAYOUT_DYNAMIC_FIXED &&
19245  layout->row.type != NK_LAYOUT_STATIC_FIXED) {
19246  for (i = 0; i < cols; ++i)
19247  nk_panel_alloc_space(&none, ctx);
19248  } layout->row.index = index;
19249 }
19250 
19251 
19252 
19253 
19254 
19255 /* ===============================================================
19256  *
19257  * TEXT
19258  *
19259  * ===============================================================*/
19260 NK_LIB void
19261 nk_widget_text(struct nk_command_buffer *o, struct nk_rect b,
19262  const char *string, int len, const struct nk_text *t,
19263  nk_flags a, const struct nk_user_font *f)
19264 {
19265  struct nk_rect label;
19266  float text_width;
19267 
19268  NK_ASSERT(o);
19269  NK_ASSERT(t);
19270  if (!o || !t) return;
19271 
19272  b.h = NK_MAX(b.h, 2 * t->padding.y);
19273  label.x = 0; label.w = 0;
19274  label.y = b.y + t->padding.y;
19275  label.h = NK_MIN(f->height, b.h - 2 * t->padding.y);
19276 
19277  text_width = f->width(f->userdata, f->height, (const char*)string, len);
19278  text_width += (2.0f * t->padding.x);
19279 
19280  /* align in x-axis */
19281  if (a & NK_TEXT_ALIGN_LEFT) {
19282  label.x = b.x + t->padding.x;
19283  label.w = NK_MAX(0, b.w - 2 * t->padding.x);
19284  } else if (a & NK_TEXT_ALIGN_CENTERED) {
19285  label.w = NK_MAX(1, 2 * t->padding.x + (float)text_width);
19286  label.x = (b.x + t->padding.x + ((b.w - 2 * t->padding.x) - label.w) / 2);
19287  label.x = NK_MAX(b.x + t->padding.x, label.x);
19288  label.w = NK_MIN(b.x + b.w, label.x + label.w);
19289  if (label.w >= label.x) label.w -= label.x;
19290  } else if (a & NK_TEXT_ALIGN_RIGHT) {
19291  label.x = NK_MAX(b.x + t->padding.x, (b.x + b.w) - (2 * t->padding.x + (float)text_width));
19292  label.w = (float)text_width + 2 * t->padding.x;
19293  } else return;
19294 
19295  /* align in y-axis */
19296  if (a & NK_TEXT_ALIGN_MIDDLE) {
19297  label.y = b.y + b.h/2.0f - (float)f->height/2.0f;
19298  label.h = NK_MAX(b.h/2.0f, b.h - (b.h/2.0f + f->height/2.0f));
19299  } else if (a & NK_TEXT_ALIGN_BOTTOM) {
19300  label.y = b.y + b.h - f->height;
19301  label.h = f->height;
19302  }
19303  nk_draw_text(o, label, (const char*)string, len, f, t->background, t->text);
19304 }
19305 NK_LIB void
19306 nk_widget_text_wrap(struct nk_command_buffer *o, struct nk_rect b,
19307  const char *string, int len, const struct nk_text *t,
19308  const struct nk_user_font *f)
19309 {
19310  float width;
19311  int glyphs = 0;
19312  int fitting = 0;
19313  int done = 0;
19314  struct nk_rect line;
19315  struct nk_text text;
19316  NK_INTERN nk_rune seperator[] = {' '};
19317 
19318  NK_ASSERT(o);
19319  NK_ASSERT(t);
19320  if (!o || !t) return;
19321 
19322  text.padding = nk_vec2(0,0);
19323  text.background = t->background;
19324  text.text = t->text;
19325 
19326  b.w = NK_MAX(b.w, 2 * t->padding.x);
19327  b.h = NK_MAX(b.h, 2 * t->padding.y);
19328  b.h = b.h - 2 * t->padding.y;
19329 
19330  line.x = b.x + t->padding.x;
19331  line.y = b.y + t->padding.y;
19332  line.w = b.w - 2 * t->padding.x;
19333  line.h = 2 * t->padding.y + f->height;
19334 
19335  fitting = nk_text_clamp(f, string, len, line.w, &glyphs, &width, seperator,NK_LEN(seperator));
19336  while (done < len) {
19337  if (!fitting || line.y + line.h >= (b.y + b.h)) break;
19338  nk_widget_text(o, line, &string[done], fitting, &text, NK_TEXT_LEFT, f);
19339  done += fitting;
19340  line.y += f->height + 2 * t->padding.y;
19341  fitting = nk_text_clamp(f, &string[done], len - done, line.w, &glyphs, &width, seperator,NK_LEN(seperator));
19342  }
19343 }
19344 NK_API void
19345 nk_text_colored(struct nk_context *ctx, const char *str, int len,
19346  nk_flags alignment, struct nk_color color)
19347 {
19348  struct nk_window *win;
19349  const struct nk_style *style;
19350 
19351  struct nk_vec2 item_padding;
19352  struct nk_rect bounds;
19353  struct nk_text text;
19354 
19355  NK_ASSERT(ctx);
19356  NK_ASSERT(ctx->current);
19357  NK_ASSERT(ctx->current->layout);
19358  if (!ctx || !ctx->current || !ctx->current->layout) return;
19359 
19360  win = ctx->current;
19361  style = &ctx->style;
19362  nk_panel_alloc_space(&bounds, ctx);
19363  item_padding = style->text.padding;
19364 
19365  text.padding.x = item_padding.x;
19366  text.padding.y = item_padding.y;
19367  text.background = style->window.background;
19368  text.text = color;
19369  nk_widget_text(&win->buffer, bounds, str, len, &text, alignment, style->font);
19370 }
19371 NK_API void
19372 nk_text_wrap_colored(struct nk_context *ctx, const char *str,
19373  int len, struct nk_color color)
19374 {
19375  struct nk_window *win;
19376  const struct nk_style *style;
19377 
19378  struct nk_vec2 item_padding;
19379  struct nk_rect bounds;
19380  struct nk_text text;
19381 
19382  NK_ASSERT(ctx);
19383  NK_ASSERT(ctx->current);
19384  NK_ASSERT(ctx->current->layout);
19385  if (!ctx || !ctx->current || !ctx->current->layout) return;
19386 
19387  win = ctx->current;
19388  style = &ctx->style;
19389  nk_panel_alloc_space(&bounds, ctx);
19390  item_padding = style->text.padding;
19391 
19392  text.padding.x = item_padding.x;
19393  text.padding.y = item_padding.y;
19394  text.background = style->window.background;
19395  text.text = color;
19396  nk_widget_text_wrap(&win->buffer, bounds, str, len, &text, style->font);
19397 }
19398 #ifdef NK_INCLUDE_STANDARD_VARARGS
19399 NK_API void
19400 nk_labelf_colored(struct nk_context *ctx, nk_flags flags,
19401  struct nk_color color, const char *fmt, ...)
19402 {
19403  va_list args;
19404  va_start(args, fmt);
19405  nk_labelfv_colored(ctx, flags, color, fmt, args);
19406  va_end(args);
19407 }
19408 NK_API void
19409 nk_labelf_colored_wrap(struct nk_context *ctx, struct nk_color color,
19410  const char *fmt, ...)
19411 {
19412  va_list args;
19413  va_start(args, fmt);
19414  nk_labelfv_colored_wrap(ctx, color, fmt, args);
19415  va_end(args);
19416 }
19417 NK_API void
19418 nk_labelf(struct nk_context *ctx, nk_flags flags, const char *fmt, ...)
19419 {
19420  va_list args;
19421  va_start(args, fmt);
19422  nk_labelfv(ctx, flags, fmt, args);
19423  va_end(args);
19424 }
19425 NK_API void
19426 nk_labelf_wrap(struct nk_context *ctx, const char *fmt,...)
19427 {
19428  va_list args;
19429  va_start(args, fmt);
19430  nk_labelfv_wrap(ctx, fmt, args);
19431  va_end(args);
19432 }
19433 NK_API void
19434 nk_labelfv_colored(struct nk_context *ctx, nk_flags flags,
19435  struct nk_color color, const char *fmt, va_list args)
19436 {
19437  char buf[256];
19438  nk_strfmt(buf, NK_LEN(buf), fmt, args);
19439  nk_label_colored(ctx, buf, flags, color);
19440 }
19441 
19442 NK_API void
19443 nk_labelfv_colored_wrap(struct nk_context *ctx, struct nk_color color,
19444  const char *fmt, va_list args)
19445 {
19446  char buf[256];
19447  nk_strfmt(buf, NK_LEN(buf), fmt, args);
19448  nk_label_colored_wrap(ctx, buf, color);
19449 }
19450 
19451 NK_API void
19452 nk_labelfv(struct nk_context *ctx, nk_flags flags, const char *fmt, va_list args)
19453 {
19454  char buf[256];
19455  nk_strfmt(buf, NK_LEN(buf), fmt, args);
19456  nk_label(ctx, buf, flags);
19457 }
19458 
19459 NK_API void
19460 nk_labelfv_wrap(struct nk_context *ctx, const char *fmt, va_list args)
19461 {
19462  char buf[256];
19463  nk_strfmt(buf, NK_LEN(buf), fmt, args);
19464  nk_label_wrap(ctx, buf);
19465 }
19466 
19467 NK_API void
19468 nk_value_bool(struct nk_context *ctx, const char *prefix, int value)
19469 {
19470  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %s", prefix, ((value) ? "true": "false"));
19471 }
19472 NK_API void
19473 nk_value_int(struct nk_context *ctx, const char *prefix, int value)
19474 {
19475  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %d", prefix, value);
19476 }
19477 NK_API void
19478 nk_value_uint(struct nk_context *ctx, const char *prefix, unsigned int value)
19479 {
19480  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %u", prefix, value);
19481 }
19482 NK_API void
19483 nk_value_float(struct nk_context *ctx, const char *prefix, float value)
19484 {
19485  double double_value = (double)value;
19486  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %.3f", prefix, double_value);
19487 }
19488 NK_API void
19489 nk_value_color_byte(struct nk_context *ctx, const char *p, struct nk_color c)
19490 {
19491  nk_labelf(ctx, NK_TEXT_LEFT, "%s: (%d, %d, %d, %d)", p, c.r, c.g, c.b, c.a);
19492 }
19493 NK_API void
19494 nk_value_color_float(struct nk_context *ctx, const char *p, struct nk_color color)
19495 {
19496  double c[4]; nk_color_dv(c, color);
19497  nk_labelf(ctx, NK_TEXT_LEFT, "%s: (%.2f, %.2f, %.2f, %.2f)",
19498  p, c[0], c[1], c[2], c[3]);
19499 }
19500 NK_API void
19501 nk_value_color_hex(struct nk_context *ctx, const char *prefix, struct nk_color color)
19502 {
19503  char hex[16];
19504  nk_color_hex_rgba(hex, color);
19505  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %s", prefix, hex);
19506 }
19507 #endif
19508 NK_API void
19509 nk_text(struct nk_context *ctx, const char *str, int len, nk_flags alignment)
19510 {
19511  NK_ASSERT(ctx);
19512  if (!ctx) return;
19513  nk_text_colored(ctx, str, len, alignment, ctx->style.text.color);
19514 }
19515 NK_API void
19516 nk_text_wrap(struct nk_context *ctx, const char *str, int len)
19517 {
19518  NK_ASSERT(ctx);
19519  if (!ctx) return;
19520  nk_text_wrap_colored(ctx, str, len, ctx->style.text.color);
19521 }
19522 NK_API void
19523 nk_label(struct nk_context *ctx, const char *str, nk_flags alignment)
19524 {
19525  nk_text(ctx, str, nk_strlen(str), alignment);
19526 }
19527 NK_API void
19528 nk_label_colored(struct nk_context *ctx, const char *str, nk_flags align,
19529  struct nk_color color)
19530 {
19531  nk_text_colored(ctx, str, nk_strlen(str), align, color);
19532 }
19533 NK_API void
19534 nk_label_wrap(struct nk_context *ctx, const char *str)
19535 {
19536  nk_text_wrap(ctx, str, nk_strlen(str));
19537 }
19538 NK_API void
19539 nk_label_colored_wrap(struct nk_context *ctx, const char *str, struct nk_color color)
19540 {
19541  nk_text_wrap_colored(ctx, str, nk_strlen(str), color);
19542 }
19543 
19544 
19545 
19546 
19547 
19548 /* ===============================================================
19549  *
19550  * IMAGE
19551  *
19552  * ===============================================================*/
19554 nk_handle_ptr(void *ptr)
19555 {
19556  nk_handle handle = {0};
19557  handle.ptr = ptr;
19558  return handle;
19559 }
19561 nk_handle_id(int id)
19562 {
19563  nk_handle handle;
19564  nk_zero_struct(handle);
19565  handle.id = id;
19566  return handle;
19567 }
19568 NK_API struct nk_image
19569 nk_subimage_ptr(void *ptr, unsigned short w, unsigned short h, struct nk_rect r)
19570 {
19571  struct nk_image s;
19572  nk_zero(&s, sizeof(s));
19573  s.handle.ptr = ptr;
19574  s.w = w; s.h = h;
19575  s.region[0] = (unsigned short)r.x;
19576  s.region[1] = (unsigned short)r.y;
19577  s.region[2] = (unsigned short)r.w;
19578  s.region[3] = (unsigned short)r.h;
19579  return s;
19580 }
19581 NK_API struct nk_image
19582 nk_subimage_id(int id, unsigned short w, unsigned short h, struct nk_rect r)
19583 {
19584  struct nk_image s;
19585  nk_zero(&s, sizeof(s));
19586  s.handle.id = id;
19587  s.w = w; s.h = h;
19588  s.region[0] = (unsigned short)r.x;
19589  s.region[1] = (unsigned short)r.y;
19590  s.region[2] = (unsigned short)r.w;
19591  s.region[3] = (unsigned short)r.h;
19592  return s;
19593 }
19594 NK_API struct nk_image
19595 nk_subimage_handle(nk_handle handle, unsigned short w, unsigned short h,
19596  struct nk_rect r)
19597 {
19598  struct nk_image s;
19599  nk_zero(&s, sizeof(s));
19600  s.handle = handle;
19601  s.w = w; s.h = h;
19602  s.region[0] = (unsigned short)r.x;
19603  s.region[1] = (unsigned short)r.y;
19604  s.region[2] = (unsigned short)r.w;
19605  s.region[3] = (unsigned short)r.h;
19606  return s;
19607 }
19608 NK_API struct nk_image
19610 {
19611  struct nk_image s;
19612  nk_zero(&s, sizeof(s));
19613  s.handle = handle;
19614  s.w = 0; s.h = 0;
19615  s.region[0] = 0;
19616  s.region[1] = 0;
19617  s.region[2] = 0;
19618  s.region[3] = 0;
19619  return s;
19620 }
19621 NK_API struct nk_image
19622 nk_image_ptr(void *ptr)
19623 {
19624  struct nk_image s;
19625  nk_zero(&s, sizeof(s));
19626  NK_ASSERT(ptr);
19627  s.handle.ptr = ptr;
19628  s.w = 0; s.h = 0;
19629  s.region[0] = 0;
19630  s.region[1] = 0;
19631  s.region[2] = 0;
19632  s.region[3] = 0;
19633  return s;
19634 }
19635 NK_API struct nk_image
19636 nk_image_id(int id)
19637 {
19638  struct nk_image s;
19639  nk_zero(&s, sizeof(s));
19640  s.handle.id = id;
19641  s.w = 0; s.h = 0;
19642  s.region[0] = 0;
19643  s.region[1] = 0;
19644  s.region[2] = 0;
19645  s.region[3] = 0;
19646  return s;
19647 }
19648 NK_API int
19649 nk_image_is_subimage(const struct nk_image* img)
19650 {
19651  NK_ASSERT(img);
19652  return !(img->w == 0 && img->h == 0);
19653 }
19654 NK_API void
19655 nk_image(struct nk_context *ctx, struct nk_image img)
19656 {
19657  struct nk_window *win;
19658  struct nk_rect bounds;
19659 
19660  NK_ASSERT(ctx);
19661  NK_ASSERT(ctx->current);
19662  NK_ASSERT(ctx->current->layout);
19663  if (!ctx || !ctx->current || !ctx->current->layout) return;
19664 
19665  win = ctx->current;
19666  if (!nk_widget(&bounds, ctx)) return;
19667  nk_draw_image(&win->buffer, bounds, &img, nk_white);
19668 }
19669 NK_API void
19670 nk_image_color(struct nk_context *ctx, struct nk_image img, struct nk_color col)
19671 {
19672  struct nk_window *win;
19673  struct nk_rect bounds;
19674 
19675  NK_ASSERT(ctx);
19676  NK_ASSERT(ctx->current);
19677  NK_ASSERT(ctx->current->layout);
19678  if (!ctx || !ctx->current || !ctx->current->layout) return;
19679 
19680  win = ctx->current;
19681  if (!nk_widget(&bounds, ctx)) return;
19682  nk_draw_image(&win->buffer, bounds, &img, col);
19683 }
19684 
19685 
19686 
19687 
19688 
19689 /* ==============================================================
19690  *
19691  * BUTTON
19692  *
19693  * ===============================================================*/
19694 NK_LIB void
19695 nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type,
19696  struct nk_rect content, struct nk_color background, struct nk_color foreground,
19697  float border_width, const struct nk_user_font *font)
19698 {
19699  switch (type) {
19700  case NK_SYMBOL_X:
19701  case NK_SYMBOL_UNDERSCORE:
19702  case NK_SYMBOL_PLUS:
19703  case NK_SYMBOL_MINUS: {
19704  /* single character text symbol */
19705  const char *X = (type == NK_SYMBOL_X) ? "x":
19706  (type == NK_SYMBOL_UNDERSCORE) ? "_":
19707  (type == NK_SYMBOL_PLUS) ? "+": "-";
19708  struct nk_text text;
19709  text.padding = nk_vec2(0,0);
19710  text.background = background;
19711  text.text = foreground;
19712  nk_widget_text(out, content, X, 1, &text, NK_TEXT_CENTERED, font);
19713  } break;
19716  case NK_SYMBOL_RECT_SOLID:
19717  case NK_SYMBOL_RECT_OUTLINE: {
19718  /* simple empty/filled shapes */
19719  if (type == NK_SYMBOL_RECT_SOLID || type == NK_SYMBOL_RECT_OUTLINE) {
19720  nk_fill_rect(out, content, 0, foreground);
19721  if (type == NK_SYMBOL_RECT_OUTLINE)
19722  nk_fill_rect(out, nk_shrink_rect(content, border_width), 0, background);
19723  } else {
19724  nk_fill_circle(out, content, foreground);
19725  if (type == NK_SYMBOL_CIRCLE_OUTLINE)
19726  nk_fill_circle(out, nk_shrink_rect(content, 1), background);
19727  }
19728  } break;
19729  case NK_SYMBOL_TRIANGLE_UP:
19732  case NK_SYMBOL_TRIANGLE_RIGHT: {
19733  enum nk_heading heading;
19734  struct nk_vec2 points[3];
19735  heading = (type == NK_SYMBOL_TRIANGLE_RIGHT) ? NK_RIGHT :
19736  (type == NK_SYMBOL_TRIANGLE_LEFT) ? NK_LEFT:
19737  (type == NK_SYMBOL_TRIANGLE_UP) ? NK_UP: NK_DOWN;
19738  nk_triangle_from_direction(points, content, 0, 0, heading);
19739  nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
19740  points[2].x, points[2].y, foreground);
19741  } break;
19742  default:
19743  case NK_SYMBOL_NONE:
19744  case NK_SYMBOL_MAX: break;
19745  }
19746 }
19747 NK_LIB int
19748 nk_button_behavior(nk_flags *state, struct nk_rect r,
19749  const struct nk_input *i, enum nk_button_behavior behavior)
19750 {
19751  int ret = 0;
19752  nk_widget_state_reset(state);
19753  if (!i) return 0;
19754  if (nk_input_is_mouse_hovering_rect(i, r)) {
19755  *state = NK_WIDGET_STATE_HOVERED;
19757  *state = NK_WIDGET_STATE_ACTIVE;
19759  ret = (behavior != NK_BUTTON_DEFAULT) ?
19761 #ifdef NK_BUTTON_TRIGGER_ON_RELEASE
19763 #else
19765 #endif
19766  }
19767  }
19769  *state |= NK_WIDGET_STATE_ENTERED;
19770  else if (nk_input_is_mouse_prev_hovering_rect(i, r))
19771  *state |= NK_WIDGET_STATE_LEFT;
19772  return ret;
19773 }
19774 NK_LIB const struct nk_style_item*
19775 nk_draw_button(struct nk_command_buffer *out,
19776  const struct nk_rect *bounds, nk_flags state,
19777  const struct nk_style_button *style)
19778 {
19779  const struct nk_style_item *background;
19780  if (state & NK_WIDGET_STATE_HOVER)
19781  background = &style->hover;
19782  else if (state & NK_WIDGET_STATE_ACTIVED)
19783  background = &style->active;
19784  else background = &style->normal;
19785 
19786  if (background->type == NK_STYLE_ITEM_IMAGE) {
19787  nk_draw_image(out, *bounds, &background->data.image, nk_white);
19788  } else {
19789  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
19790  nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
19791  }
19792  return background;
19793 }
19794 NK_LIB int
19795 nk_do_button(nk_flags *state, struct nk_command_buffer *out, struct nk_rect r,
19796  const struct nk_style_button *style, const struct nk_input *in,
19797  enum nk_button_behavior behavior, struct nk_rect *content)
19798 {
19799  struct nk_rect bounds;
19800  NK_ASSERT(style);
19801  NK_ASSERT(state);
19802  NK_ASSERT(out);
19803  if (!out || !style)
19804  return nk_false;
19805 
19806  /* calculate button content space */
19807  content->x = r.x + style->padding.x + style->border + style->rounding;
19808  content->y = r.y + style->padding.y + style->border + style->rounding;
19809  content->w = r.w - (2 * style->padding.x + style->border + style->rounding*2);
19810  content->h = r.h - (2 * style->padding.y + style->border + style->rounding*2);
19811 
19812  /* execute button behavior */
19813  bounds.x = r.x - style->touch_padding.x;
19814  bounds.y = r.y - style->touch_padding.y;
19815  bounds.w = r.w + 2 * style->touch_padding.x;
19816  bounds.h = r.h + 2 * style->touch_padding.y;
19817  return nk_button_behavior(state, bounds, in, behavior);
19818 }
19819 NK_LIB void
19820 nk_draw_button_text(struct nk_command_buffer *out,
19821  const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state,
19822  const struct nk_style_button *style, const char *txt, int len,
19823  nk_flags text_alignment, const struct nk_user_font *font)
19824 {
19825  struct nk_text text;
19826  const struct nk_style_item *background;
19827  background = nk_draw_button(out, bounds, state, style);
19828 
19829  /* select correct colors/images */
19830  if (background->type == NK_STYLE_ITEM_COLOR)
19831  text.background = background->data.color;
19832  else text.background = style->text_background;
19833  if (state & NK_WIDGET_STATE_HOVER)
19834  text.text = style->text_hover;
19835  else if (state & NK_WIDGET_STATE_ACTIVED)
19836  text.text = style->text_active;
19837  else text.text = style->text_normal;
19838 
19839  text.padding = nk_vec2(0,0);
19840  nk_widget_text(out, *content, txt, len, &text, text_alignment, font);
19841 }
19842 NK_LIB int
19843 nk_do_button_text(nk_flags *state,
19844  struct nk_command_buffer *out, struct nk_rect bounds,
19845  const char *string, int len, nk_flags align, enum nk_button_behavior behavior,
19846  const struct nk_style_button *style, const struct nk_input *in,
19847  const struct nk_user_font *font)
19848 {
19849  struct nk_rect content;
19850  int ret = nk_false;
19851 
19852  NK_ASSERT(state);
19853  NK_ASSERT(style);
19854  NK_ASSERT(out);
19855  NK_ASSERT(string);
19856  NK_ASSERT(font);
19857  if (!out || !style || !font || !string)
19858  return nk_false;
19859 
19860  ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19861  if (style->draw_begin) style->draw_begin(out, style->userdata);
19862  nk_draw_button_text(out, &bounds, &content, *state, style, string, len, align, font);
19863  if (style->draw_end) style->draw_end(out, style->userdata);
19864  return ret;
19865 }
19866 NK_LIB void
19867 nk_draw_button_symbol(struct nk_command_buffer *out,
19868  const struct nk_rect *bounds, const struct nk_rect *content,
19869  nk_flags state, const struct nk_style_button *style,
19870  enum nk_symbol_type type, const struct nk_user_font *font)
19871 {
19872  struct nk_color sym, bg;
19873  const struct nk_style_item *background;
19874 
19875  /* select correct colors/images */
19876  background = nk_draw_button(out, bounds, state, style);
19877  if (background->type == NK_STYLE_ITEM_COLOR)
19878  bg = background->data.color;
19879  else bg = style->text_background;
19880 
19881  if (state & NK_WIDGET_STATE_HOVER)
19882  sym = style->text_hover;
19883  else if (state & NK_WIDGET_STATE_ACTIVED)
19884  sym = style->text_active;
19885  else sym = style->text_normal;
19886  nk_draw_symbol(out, type, *content, bg, sym, 1, font);
19887 }
19888 NK_LIB int
19889 nk_do_button_symbol(nk_flags *state,
19890  struct nk_command_buffer *out, struct nk_rect bounds,
19891  enum nk_symbol_type symbol, enum nk_button_behavior behavior,
19892  const struct nk_style_button *style, const struct nk_input *in,
19893  const struct nk_user_font *font)
19894 {
19895  int ret;
19896  struct nk_rect content;
19897 
19898  NK_ASSERT(state);
19899  NK_ASSERT(style);
19900  NK_ASSERT(font);
19901  NK_ASSERT(out);
19902  if (!out || !style || !font || !state)
19903  return nk_false;
19904 
19905  ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19906  if (style->draw_begin) style->draw_begin(out, style->userdata);
19907  nk_draw_button_symbol(out, &bounds, &content, *state, style, symbol, font);
19908  if (style->draw_end) style->draw_end(out, style->userdata);
19909  return ret;
19910 }
19911 NK_LIB void
19912 nk_draw_button_image(struct nk_command_buffer *out,
19913  const struct nk_rect *bounds, const struct nk_rect *content,
19914  nk_flags state, const struct nk_style_button *style, const struct nk_image *img)
19915 {
19916  nk_draw_button(out, bounds, state, style);
19917  nk_draw_image(out, *content, img, nk_white);
19918 }
19919 NK_LIB int
19920 nk_do_button_image(nk_flags *state,
19921  struct nk_command_buffer *out, struct nk_rect bounds,
19922  struct nk_image img, enum nk_button_behavior b,
19923  const struct nk_style_button *style, const struct nk_input *in)
19924 {
19925  int ret;
19926  struct nk_rect content;
19927 
19928  NK_ASSERT(state);
19929  NK_ASSERT(style);
19930  NK_ASSERT(out);
19931  if (!out || !style || !state)
19932  return nk_false;
19933 
19934  ret = nk_do_button(state, out, bounds, style, in, b, &content);
19935  content.x += style->image_padding.x;
19936  content.y += style->image_padding.y;
19937  content.w -= 2 * style->image_padding.x;
19938  content.h -= 2 * style->image_padding.y;
19939 
19940  if (style->draw_begin) style->draw_begin(out, style->userdata);
19941  nk_draw_button_image(out, &bounds, &content, *state, style, &img);
19942  if (style->draw_end) style->draw_end(out, style->userdata);
19943  return ret;
19944 }
19945 NK_LIB void
19946 nk_draw_button_text_symbol(struct nk_command_buffer *out,
19947  const struct nk_rect *bounds, const struct nk_rect *label,
19948  const struct nk_rect *symbol, nk_flags state, const struct nk_style_button *style,
19949  const char *str, int len, enum nk_symbol_type type,
19950  const struct nk_user_font *font)
19951 {
19952  struct nk_color sym;
19953  struct nk_text text;
19954  const struct nk_style_item *background;
19955 
19956  /* select correct background colors/images */
19957  background = nk_draw_button(out, bounds, state, style);
19958  if (background->type == NK_STYLE_ITEM_COLOR)
19959  text.background = background->data.color;
19960  else text.background = style->text_background;
19961 
19962  /* select correct text colors */
19963  if (state & NK_WIDGET_STATE_HOVER) {
19964  sym = style->text_hover;
19965  text.text = style->text_hover;
19966  } else if (state & NK_WIDGET_STATE_ACTIVED) {
19967  sym = style->text_active;
19968  text.text = style->text_active;
19969  } else {
19970  sym = style->text_normal;
19971  text.text = style->text_normal;
19972  }
19973 
19974  text.padding = nk_vec2(0,0);
19975  nk_draw_symbol(out, type, *symbol, style->text_background, sym, 0, font);
19976  nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
19977 }
19978 NK_LIB int
19979 nk_do_button_text_symbol(nk_flags *state,
19980  struct nk_command_buffer *out, struct nk_rect bounds,
19981  enum nk_symbol_type symbol, const char *str, int len, nk_flags align,
19982  enum nk_button_behavior behavior, const struct nk_style_button *style,
19983  const struct nk_user_font *font, const struct nk_input *in)
19984 {
19985  int ret;
19986  struct nk_rect tri = {0,0,0,0};
19987  struct nk_rect content;
19988 
19989  NK_ASSERT(style);
19990  NK_ASSERT(out);
19991  NK_ASSERT(font);
19992  if (!out || !style || !font)
19993  return nk_false;
19994 
19995  ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19996  tri.y = content.y + (content.h/2) - font->height/2;
19997  tri.w = font->height; tri.h = font->height;
19998  if (align & NK_TEXT_ALIGN_LEFT) {
19999  tri.x = (content.x + content.w) - (2 * style->padding.x + tri.w);
20000  tri.x = NK_MAX(tri.x, 0);
20001  } else tri.x = content.x + 2 * style->padding.x;
20002 
20003  /* draw button */
20004  if (style->draw_begin) style->draw_begin(out, style->userdata);
20005  nk_draw_button_text_symbol(out, &bounds, &content, &tri,
20006  *state, style, str, len, symbol, font);
20007  if (style->draw_end) style->draw_end(out, style->userdata);
20008  return ret;
20009 }
20010 NK_LIB void
20011 nk_draw_button_text_image(struct nk_command_buffer *out,
20012  const struct nk_rect *bounds, const struct nk_rect *label,
20013  const struct nk_rect *image, nk_flags state, const struct nk_style_button *style,
20014  const char *str, int len, const struct nk_user_font *font,
20015  const struct nk_image *img)
20016 {
20017  struct nk_text text;
20018  const struct nk_style_item *background;
20019  background = nk_draw_button(out, bounds, state, style);
20020 
20021  /* select correct colors */
20022  if (background->type == NK_STYLE_ITEM_COLOR)
20023  text.background = background->data.color;
20024  else text.background = style->text_background;
20025  if (state & NK_WIDGET_STATE_HOVER)
20026  text.text = style->text_hover;
20027  else if (state & NK_WIDGET_STATE_ACTIVED)
20028  text.text = style->text_active;
20029  else text.text = style->text_normal;
20030 
20031  text.padding = nk_vec2(0,0);
20032  nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
20033  nk_draw_image(out, *image, img, nk_white);
20034 }
20035 NK_LIB int
20036 nk_do_button_text_image(nk_flags *state,
20037  struct nk_command_buffer *out, struct nk_rect bounds,
20038  struct nk_image img, const char* str, int len, nk_flags align,
20039  enum nk_button_behavior behavior, const struct nk_style_button *style,
20040  const struct nk_user_font *font, const struct nk_input *in)
20041 {
20042  int ret;
20043  struct nk_rect icon;
20044  struct nk_rect content;
20045 
20046  NK_ASSERT(style);
20047  NK_ASSERT(state);
20048  NK_ASSERT(font);
20049  NK_ASSERT(out);
20050  if (!out || !font || !style || !str)
20051  return nk_false;
20052 
20053  ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
20054  icon.y = bounds.y + style->padding.y;
20055  icon.w = icon.h = bounds.h - 2 * style->padding.y;
20056  if (align & NK_TEXT_ALIGN_LEFT) {
20057  icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
20058  icon.x = NK_MAX(icon.x, 0);
20059  } else icon.x = bounds.x + 2 * style->padding.x;
20060 
20061  icon.x += style->image_padding.x;
20062  icon.y += style->image_padding.y;
20063  icon.w -= 2 * style->image_padding.x;
20064  icon.h -= 2 * style->image_padding.y;
20065 
20066  if (style->draw_begin) style->draw_begin(out, style->userdata);
20067  nk_draw_button_text_image(out, &bounds, &content, &icon, *state, style, str, len, font, &img);
20068  if (style->draw_end) style->draw_end(out, style->userdata);
20069  return ret;
20070 }
20071 NK_API void
20072 nk_button_set_behavior(struct nk_context *ctx, enum nk_button_behavior behavior)
20073 {
20074  NK_ASSERT(ctx);
20075  if (!ctx) return;
20076  ctx->button_behavior = behavior;
20077 }
20078 NK_API int
20079 nk_button_push_behavior(struct nk_context *ctx, enum nk_button_behavior behavior)
20080 {
20081  struct nk_config_stack_button_behavior *button_stack;
20082  struct nk_config_stack_button_behavior_element *element;
20083 
20084  NK_ASSERT(ctx);
20085  if (!ctx) return 0;
20086 
20087  button_stack = &ctx->stacks.button_behaviors;
20088  NK_ASSERT(button_stack->head < (int)NK_LEN(button_stack->elements));
20089  if (button_stack->head >= (int)NK_LEN(button_stack->elements))
20090  return 0;
20091 
20092  element = &button_stack->elements[button_stack->head++];
20093  element->address = &ctx->button_behavior;
20094  element->old_value = ctx->button_behavior;
20095  ctx->button_behavior = behavior;
20096  return 1;
20097 }
20098 NK_API int
20100 {
20101  struct nk_config_stack_button_behavior *button_stack;
20102  struct nk_config_stack_button_behavior_element *element;
20103 
20104  NK_ASSERT(ctx);
20105  if (!ctx) return 0;
20106 
20107  button_stack = &ctx->stacks.button_behaviors;
20108  NK_ASSERT(button_stack->head > 0);
20109  if (button_stack->head < 1)
20110  return 0;
20111 
20112  element = &button_stack->elements[--button_stack->head];
20113  *element->address = element->old_value;
20114  return 1;
20115 }
20116 NK_API int
20117 nk_button_text_styled(struct nk_context *ctx,
20118  const struct nk_style_button *style, const char *title, int len)
20119 {
20120  struct nk_window *win;
20121  struct nk_panel *layout;
20122  const struct nk_input *in;
20123 
20124  struct nk_rect bounds;
20125  enum nk_widget_layout_states state;
20126 
20127  NK_ASSERT(ctx);
20128  NK_ASSERT(style);
20129  NK_ASSERT(ctx->current);
20130  NK_ASSERT(ctx->current->layout);
20131  if (!style || !ctx || !ctx->current || !ctx->current->layout) return 0;
20132 
20133  win = ctx->current;
20134  layout = win->layout;
20135  state = nk_widget(&bounds, ctx);
20136 
20137  if (!state) return 0;
20138  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20139  return nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
20140  title, len, style->text_alignment, ctx->button_behavior,
20141  style, in, ctx->style.font);
20142 }
20143 NK_API int
20144 nk_button_text(struct nk_context *ctx, const char *title, int len)
20145 {
20146  NK_ASSERT(ctx);
20147  if (!ctx) return 0;
20148  return nk_button_text_styled(ctx, &ctx->style.button, title, len);
20149 }
20150 NK_API int nk_button_label_styled(struct nk_context *ctx,
20151  const struct nk_style_button *style, const char *title)
20152 {
20153  return nk_button_text_styled(ctx, style, title, nk_strlen(title));
20154 }
20155 NK_API int nk_button_label(struct nk_context *ctx, const char *title)
20156 {
20157  return nk_button_text(ctx, title, nk_strlen(title));
20158 }
20159 NK_API int
20160 nk_button_color(struct nk_context *ctx, struct nk_color color)
20161 {
20162  struct nk_window *win;
20163  struct nk_panel *layout;
20164  const struct nk_input *in;
20165  struct nk_style_button button;
20166 
20167  int ret = 0;
20168  struct nk_rect bounds;
20169  struct nk_rect content;
20170  enum nk_widget_layout_states state;
20171 
20172  NK_ASSERT(ctx);
20173  NK_ASSERT(ctx->current);
20174  NK_ASSERT(ctx->current->layout);
20175  if (!ctx || !ctx->current || !ctx->current->layout)
20176  return 0;
20177 
20178  win = ctx->current;
20179  layout = win->layout;
20180 
20181  state = nk_widget(&bounds, ctx);
20182  if (!state) return 0;
20183  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20184 
20185  button = ctx->style.button;
20186  button.normal = nk_style_item_color(color);
20187  button.hover = nk_style_item_color(color);
20188  button.active = nk_style_item_color(color);
20189  ret = nk_do_button(&ctx->last_widget_state, &win->buffer, bounds,
20190  &button, in, ctx->button_behavior, &content);
20191  nk_draw_button(&win->buffer, &bounds, ctx->last_widget_state, &button);
20192  return ret;
20193 }
20194 NK_API int
20196  const struct nk_style_button *style, enum nk_symbol_type symbol)
20197 {
20198  struct nk_window *win;
20199  struct nk_panel *layout;
20200  const struct nk_input *in;
20201 
20202  struct nk_rect bounds;
20203  enum nk_widget_layout_states state;
20204 
20205  NK_ASSERT(ctx);
20206  NK_ASSERT(ctx->current);
20207  NK_ASSERT(ctx->current->layout);
20208  if (!ctx || !ctx->current || !ctx->current->layout)
20209  return 0;
20210 
20211  win = ctx->current;
20212  layout = win->layout;
20213  state = nk_widget(&bounds, ctx);
20214  if (!state) return 0;
20215  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20216  return nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, bounds,
20217  symbol, ctx->button_behavior, style, in, ctx->style.font);
20218 }
20219 NK_API int
20220 nk_button_symbol(struct nk_context *ctx, enum nk_symbol_type symbol)
20221 {
20222  NK_ASSERT(ctx);
20223  if (!ctx) return 0;
20224  return nk_button_symbol_styled(ctx, &ctx->style.button, symbol);
20225 }
20226 NK_API int
20227 nk_button_image_styled(struct nk_context *ctx, const struct nk_style_button *style,
20228  struct nk_image img)
20229 {
20230  struct nk_window *win;
20231  struct nk_panel *layout;
20232  const struct nk_input *in;
20233 
20234  struct nk_rect bounds;
20235  enum nk_widget_layout_states state;
20236 
20237  NK_ASSERT(ctx);
20238  NK_ASSERT(ctx->current);
20239  NK_ASSERT(ctx->current->layout);
20240  if (!ctx || !ctx->current || !ctx->current->layout)
20241  return 0;
20242 
20243  win = ctx->current;
20244  layout = win->layout;
20245 
20246  state = nk_widget(&bounds, ctx);
20247  if (!state) return 0;
20248  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20249  return nk_do_button_image(&ctx->last_widget_state, &win->buffer, bounds,
20250  img, ctx->button_behavior, style, in);
20251 }
20252 NK_API int
20253 nk_button_image(struct nk_context *ctx, struct nk_image img)
20254 {
20255  NK_ASSERT(ctx);
20256  if (!ctx) return 0;
20257  return nk_button_image_styled(ctx, &ctx->style.button, img);
20258 }
20259 NK_API int
20261  const struct nk_style_button *style, enum nk_symbol_type symbol,
20262  const char *text, int len, nk_flags align)
20263 {
20264  struct nk_window *win;
20265  struct nk_panel *layout;
20266  const struct nk_input *in;
20267 
20268  struct nk_rect bounds;
20269  enum nk_widget_layout_states state;
20270 
20271  NK_ASSERT(ctx);
20272  NK_ASSERT(ctx->current);
20273  NK_ASSERT(ctx->current->layout);
20274  if (!ctx || !ctx->current || !ctx->current->layout)
20275  return 0;
20276 
20277  win = ctx->current;
20278  layout = win->layout;
20279 
20280  state = nk_widget(&bounds, ctx);
20281  if (!state) return 0;
20282  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20283  return nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
20284  symbol, text, len, align, ctx->button_behavior,
20285  style, ctx->style.font, in);
20286 }
20287 NK_API int
20288 nk_button_symbol_text(struct nk_context *ctx, enum nk_symbol_type symbol,
20289  const char* text, int len, nk_flags align)
20290 {
20291  NK_ASSERT(ctx);
20292  if (!ctx) return 0;
20293  return nk_button_symbol_text_styled(ctx, &ctx->style.button, symbol, text, len, align);
20294 }
20295 NK_API int nk_button_symbol_label(struct nk_context *ctx, enum nk_symbol_type symbol,
20296  const char *label, nk_flags align)
20297 {
20298  return nk_button_symbol_text(ctx, symbol, label, nk_strlen(label), align);
20299 }
20301  const struct nk_style_button *style, enum nk_symbol_type symbol,
20302  const char *title, nk_flags align)
20303 {
20304  return nk_button_symbol_text_styled(ctx, style, symbol, title, nk_strlen(title), align);
20305 }
20306 NK_API int
20308  const struct nk_style_button *style, struct nk_image img, const char *text,
20309  int len, nk_flags align)
20310 {
20311  struct nk_window *win;
20312  struct nk_panel *layout;
20313  const struct nk_input *in;
20314 
20315  struct nk_rect bounds;
20316  enum nk_widget_layout_states state;
20317 
20318  NK_ASSERT(ctx);
20319  NK_ASSERT(ctx->current);
20320  NK_ASSERT(ctx->current->layout);
20321  if (!ctx || !ctx->current || !ctx->current->layout)
20322  return 0;
20323 
20324  win = ctx->current;
20325  layout = win->layout;
20326 
20327  state = nk_widget(&bounds, ctx);
20328  if (!state) return 0;
20329  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20330  return nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
20331  bounds, img, text, len, align, ctx->button_behavior,
20332  style, ctx->style.font, in);
20333 }
20334 NK_API int
20335 nk_button_image_text(struct nk_context *ctx, struct nk_image img,
20336  const char *text, int len, nk_flags align)
20337 {
20338  return nk_button_image_text_styled(ctx, &ctx->style.button,img, text, len, align);
20339 }
20340 NK_API int nk_button_image_label(struct nk_context *ctx, struct nk_image img,
20341  const char *label, nk_flags align)
20342 {
20343  return nk_button_image_text(ctx, img, label, nk_strlen(label), align);
20344 }
20346  const struct nk_style_button *style, struct nk_image img,
20347  const char *label, nk_flags text_alignment)
20348 {
20349  return nk_button_image_text_styled(ctx, style, img, label, nk_strlen(label), text_alignment);
20350 }
20351 
20352 
20353 
20354 
20355 
20356 /* ===============================================================
20357  *
20358  * TOGGLE
20359  *
20360  * ===============================================================*/
20361 NK_LIB int
20362 nk_toggle_behavior(const struct nk_input *in, struct nk_rect select,
20363  nk_flags *state, int active)
20364 {
20365  nk_widget_state_reset(state);
20366  if (nk_button_behavior(state, select, in, NK_BUTTON_DEFAULT)) {
20367  *state = NK_WIDGET_STATE_ACTIVE;
20368  active = !active;
20369  }
20370  if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, select))
20371  *state |= NK_WIDGET_STATE_ENTERED;
20372  else if (nk_input_is_mouse_prev_hovering_rect(in, select))
20373  *state |= NK_WIDGET_STATE_LEFT;
20374  return active;
20375 }
20376 NK_LIB void
20377 nk_draw_checkbox(struct nk_command_buffer *out,
20378  nk_flags state, const struct nk_style_toggle *style, int active,
20379  const struct nk_rect *label, const struct nk_rect *selector,
20380  const struct nk_rect *cursors, const char *string, int len,
20381  const struct nk_user_font *font)
20382 {
20383  const struct nk_style_item *background;
20384  const struct nk_style_item *cursor;
20385  struct nk_text text;
20386 
20387  /* select correct colors/images */
20388  if (state & NK_WIDGET_STATE_HOVER) {
20389  background = &style->hover;
20390  cursor = &style->cursor_hover;
20391  text.text = style->text_hover;
20392  } else if (state & NK_WIDGET_STATE_ACTIVED) {
20393  background = &style->hover;
20394  cursor = &style->cursor_hover;
20395  text.text = style->text_active;
20396  } else {
20397  background = &style->normal;
20398  cursor = &style->cursor_normal;
20399  text.text = style->text_normal;
20400  }
20401 
20402  /* draw background and cursor */
20403  if (background->type == NK_STYLE_ITEM_COLOR) {
20404  nk_fill_rect(out, *selector, 0, style->border_color);
20405  nk_fill_rect(out, nk_shrink_rect(*selector, style->border), 0, background->data.color);
20406  } else nk_draw_image(out, *selector, &background->data.image, nk_white);
20407  if (active) {
20408  if (cursor->type == NK_STYLE_ITEM_IMAGE)
20409  nk_draw_image(out, *cursors, &cursor->data.image, nk_white);
20410  else nk_fill_rect(out, *cursors, 0, cursor->data.color);
20411  }
20412 
20413  text.padding.x = 0;
20414  text.padding.y = 0;
20415  text.background = style->text_background;
20416  nk_widget_text(out, *label, string, len, &text, NK_TEXT_LEFT, font);
20417 }
20418 NK_LIB void
20419 nk_draw_option(struct nk_command_buffer *out,
20420  nk_flags state, const struct nk_style_toggle *style, int active,
20421  const struct nk_rect *label, const struct nk_rect *selector,
20422  const struct nk_rect *cursors, const char *string, int len,
20423  const struct nk_user_font *font)
20424 {
20425  const struct nk_style_item *background;
20426  const struct nk_style_item *cursor;
20427  struct nk_text text;
20428 
20429  /* select correct colors/images */
20430  if (state & NK_WIDGET_STATE_HOVER) {
20431  background = &style->hover;
20432  cursor = &style->cursor_hover;
20433  text.text = style->text_hover;
20434  } else if (state & NK_WIDGET_STATE_ACTIVED) {
20435  background = &style->hover;
20436  cursor = &style->cursor_hover;
20437  text.text = style->text_active;
20438  } else {
20439  background = &style->normal;
20440  cursor = &style->cursor_normal;
20441  text.text = style->text_normal;
20442  }
20443 
20444  /* draw background and cursor */
20445  if (background->type == NK_STYLE_ITEM_COLOR) {
20446  nk_fill_circle(out, *selector, style->border_color);
20447  nk_fill_circle(out, nk_shrink_rect(*selector, style->border), background->data.color);
20448  } else nk_draw_image(out, *selector, &background->data.image, nk_white);
20449  if (active) {
20450  if (cursor->type == NK_STYLE_ITEM_IMAGE)
20451  nk_draw_image(out, *cursors, &cursor->data.image, nk_white);
20452  else nk_fill_circle(out, *cursors, cursor->data.color);
20453  }
20454 
20455  text.padding.x = 0;
20456  text.padding.y = 0;
20457  text.background = style->text_background;
20458  nk_widget_text(out, *label, string, len, &text, NK_TEXT_LEFT, font);
20459 }
20460 NK_LIB int
20461 nk_do_toggle(nk_flags *state,
20462  struct nk_command_buffer *out, struct nk_rect r,
20463  int *active, const char *str, int len, enum nk_toggle_type type,
20464  const struct nk_style_toggle *style, const struct nk_input *in,
20465  const struct nk_user_font *font)
20466 {
20467  int was_active;
20468  struct nk_rect bounds;
20469  struct nk_rect select;
20470  struct nk_rect cursor;
20471  struct nk_rect label;
20472 
20473  NK_ASSERT(style);
20474  NK_ASSERT(out);
20475  NK_ASSERT(font);
20476  if (!out || !style || !font || !active)
20477  return 0;
20478 
20479  r.w = NK_MAX(r.w, font->height + 2 * style->padding.x);
20480  r.h = NK_MAX(r.h, font->height + 2 * style->padding.y);
20481 
20482  /* add additional touch padding for touch screen devices */
20483  bounds.x = r.x - style->touch_padding.x;
20484  bounds.y = r.y - style->touch_padding.y;
20485  bounds.w = r.w + 2 * style->touch_padding.x;
20486  bounds.h = r.h + 2 * style->touch_padding.y;
20487 
20488  /* calculate the selector space */
20489  select.w = font->height;
20490  select.h = select.w;
20491  select.y = r.y + r.h/2.0f - select.h/2.0f;
20492  select.x = r.x;
20493 
20494  /* calculate the bounds of the cursor inside the selector */
20495  cursor.x = select.x + style->padding.x + style->border;
20496  cursor.y = select.y + style->padding.y + style->border;
20497  cursor.w = select.w - (2 * style->padding.x + 2 * style->border);
20498  cursor.h = select.h - (2 * style->padding.y + 2 * style->border);
20499 
20500  /* label behind the selector */
20501  label.x = select.x + select.w + style->spacing;
20502  label.y = select.y;
20503  label.w = NK_MAX(r.x + r.w, label.x) - label.x;
20504  label.h = select.w;
20505 
20506  /* update selector */
20507  was_active = *active;
20508  *active = nk_toggle_behavior(in, bounds, state, *active);
20509 
20510  /* draw selector */
20511  if (style->draw_begin)
20512  style->draw_begin(out, style->userdata);
20513  if (type == NK_TOGGLE_CHECK) {
20514  nk_draw_checkbox(out, *state, style, *active, &label, &select, &cursor, str, len, font);
20515  } else {
20516  nk_draw_option(out, *state, style, *active, &label, &select, &cursor, str, len, font);
20517  }
20518  if (style->draw_end)
20519  style->draw_end(out, style->userdata);
20520  return (was_active != *active);
20521 }
20522 /*----------------------------------------------------------------
20523  *
20524  * CHECKBOX
20525  *
20526  * --------------------------------------------------------------*/
20527 NK_API int
20528 nk_check_text(struct nk_context *ctx, const char *text, int len, int active)
20529 {
20530  struct nk_window *win;
20531  struct nk_panel *layout;
20532  const struct nk_input *in;
20533  const struct nk_style *style;
20534 
20535  struct nk_rect bounds;
20536  enum nk_widget_layout_states state;
20537 
20538  NK_ASSERT(ctx);
20539  NK_ASSERT(ctx->current);
20540  NK_ASSERT(ctx->current->layout);
20541  if (!ctx || !ctx->current || !ctx->current->layout)
20542  return active;
20543 
20544  win = ctx->current;
20545  style = &ctx->style;
20546  layout = win->layout;
20547 
20548  state = nk_widget(&bounds, ctx);
20549  if (!state) return active;
20550  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20551  nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &active,
20552  text, len, NK_TOGGLE_CHECK, &style->checkbox, in, style->font);
20553  return active;
20554 }
20555 NK_API unsigned int
20556 nk_check_flags_text(struct nk_context *ctx, const char *text, int len,
20557  unsigned int flags, unsigned int value)
20558 {
20559  int old_active;
20560  NK_ASSERT(ctx);
20561  NK_ASSERT(text);
20562  if (!ctx || !text) return flags;
20563  old_active = (int)((flags & value) & value);
20564  if (nk_check_text(ctx, text, len, old_active))
20565  flags |= value;
20566  else flags &= ~value;
20567  return flags;
20568 }
20569 NK_API int
20570 nk_checkbox_text(struct nk_context *ctx, const char *text, int len, int *active)
20571 {
20572  int old_val;
20573  NK_ASSERT(ctx);
20574  NK_ASSERT(text);
20575  NK_ASSERT(active);
20576  if (!ctx || !text || !active) return 0;
20577  old_val = *active;
20578  *active = nk_check_text(ctx, text, len, *active);
20579  return old_val != *active;
20580 }
20581 NK_API int
20582 nk_checkbox_flags_text(struct nk_context *ctx, const char *text, int len,
20583  unsigned int *flags, unsigned int value)
20584 {
20585  int active;
20586  NK_ASSERT(ctx);
20587  NK_ASSERT(text);
20588  NK_ASSERT(flags);
20589  if (!ctx || !text || !flags) return 0;
20590 
20591  active = (int)((*flags & value) & value);
20592  if (nk_checkbox_text(ctx, text, len, &active)) {
20593  if (active) *flags |= value;
20594  else *flags &= ~value;
20595  return 1;
20596  }
20597  return 0;
20598 }
20599 NK_API int nk_check_label(struct nk_context *ctx, const char *label, int active)
20600 {
20601  return nk_check_text(ctx, label, nk_strlen(label), active);
20602 }
20603 NK_API unsigned int nk_check_flags_label(struct nk_context *ctx, const char *label,
20604  unsigned int flags, unsigned int value)
20605 {
20606  return nk_check_flags_text(ctx, label, nk_strlen(label), flags, value);
20607 }
20608 NK_API int nk_checkbox_label(struct nk_context *ctx, const char *label, int *active)
20609 {
20610  return nk_checkbox_text(ctx, label, nk_strlen(label), active);
20611 }
20612 NK_API int nk_checkbox_flags_label(struct nk_context *ctx, const char *label,
20613  unsigned int *flags, unsigned int value)
20614 {
20615  return nk_checkbox_flags_text(ctx, label, nk_strlen(label), flags, value);
20616 }
20617 /*----------------------------------------------------------------
20618  *
20619  * OPTION
20620  *
20621  * --------------------------------------------------------------*/
20622 NK_API int
20623 nk_option_text(struct nk_context *ctx, const char *text, int len, int is_active)
20624 {
20625  struct nk_window *win;
20626  struct nk_panel *layout;
20627  const struct nk_input *in;
20628  const struct nk_style *style;
20629 
20630  struct nk_rect bounds;
20631  enum nk_widget_layout_states state;
20632 
20633  NK_ASSERT(ctx);
20634  NK_ASSERT(ctx->current);
20635  NK_ASSERT(ctx->current->layout);
20636  if (!ctx || !ctx->current || !ctx->current->layout)
20637  return is_active;
20638 
20639  win = ctx->current;
20640  style = &ctx->style;
20641  layout = win->layout;
20642 
20643  state = nk_widget(&bounds, ctx);
20644  if (!state) return (int)state;
20645  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20646  nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &is_active,
20647  text, len, NK_TOGGLE_OPTION, &style->option, in, style->font);
20648  return is_active;
20649 }
20650 NK_API int
20651 nk_radio_text(struct nk_context *ctx, const char *text, int len, int *active)
20652 {
20653  int old_value;
20654  NK_ASSERT(ctx);
20655  NK_ASSERT(text);
20656  NK_ASSERT(active);
20657  if (!ctx || !text || !active) return 0;
20658  old_value = *active;
20659  *active = nk_option_text(ctx, text, len, old_value);
20660  return old_value != *active;
20661 }
20662 NK_API int
20663 nk_option_label(struct nk_context *ctx, const char *label, int active)
20664 {
20665  return nk_option_text(ctx, label, nk_strlen(label), active);
20666 }
20667 NK_API int
20668 nk_radio_label(struct nk_context *ctx, const char *label, int *active)
20669 {
20670  return nk_radio_text(ctx, label, nk_strlen(label), active);
20671 }
20672 
20673 
20674 
20675 
20676 
20677 /* ===============================================================
20678  *
20679  * SELECTABLE
20680  *
20681  * ===============================================================*/
20682 NK_LIB void
20683 nk_draw_selectable(struct nk_command_buffer *out,
20684  nk_flags state, const struct nk_style_selectable *style, int active,
20685  const struct nk_rect *bounds,
20686  const struct nk_rect *icon, const struct nk_image *img, enum nk_symbol_type sym,
20687  const char *string, int len, nk_flags align, const struct nk_user_font *font)
20688 {
20689  const struct nk_style_item *background;
20690  struct nk_text text;
20691  text.padding = style->padding;
20692 
20693  /* select correct colors/images */
20694  if (!active) {
20695  if (state & NK_WIDGET_STATE_ACTIVED) {
20696  background = &style->pressed;
20697  text.text = style->text_pressed;
20698  } else if (state & NK_WIDGET_STATE_HOVER) {
20699  background = &style->hover;
20700  text.text = style->text_hover;
20701  } else {
20702  background = &style->normal;
20703  text.text = style->text_normal;
20704  }
20705  } else {
20706  if (state & NK_WIDGET_STATE_ACTIVED) {
20707  background = &style->pressed_active;
20708  text.text = style->text_pressed_active;
20709  } else if (state & NK_WIDGET_STATE_HOVER) {
20710  background = &style->hover_active;
20711  text.text = style->text_hover_active;
20712  } else {
20713  background = &style->normal_active;
20714  text.text = style->text_normal_active;
20715  }
20716  }
20717  /* draw selectable background and text */
20718  if (background->type == NK_STYLE_ITEM_IMAGE) {
20719  nk_draw_image(out, *bounds, &background->data.image, nk_white);
20720  text.background = nk_rgba(0,0,0,0);
20721  } else {
20722  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
20723  text.background = background->data.color;
20724  }
20725  if (icon) {
20726  if (img) nk_draw_image(out, *icon, img, nk_white);
20727  else nk_draw_symbol(out, sym, *icon, text.background, text.text, 1, font);
20728  }
20729  nk_widget_text(out, *bounds, string, len, &text, align, font);
20730 }
20731 NK_LIB int
20732 nk_do_selectable(nk_flags *state, struct nk_command_buffer *out,
20733  struct nk_rect bounds, const char *str, int len, nk_flags align, int *value,
20734  const struct nk_style_selectable *style, const struct nk_input *in,
20735  const struct nk_user_font *font)
20736 {
20737  int old_value;
20738  struct nk_rect touch;
20739 
20740  NK_ASSERT(state);
20741  NK_ASSERT(out);
20742  NK_ASSERT(str);
20743  NK_ASSERT(len);
20744  NK_ASSERT(value);
20745  NK_ASSERT(style);
20746  NK_ASSERT(font);
20747 
20748  if (!state || !out || !str || !len || !value || !style || !font) return 0;
20749  old_value = *value;
20750 
20751  /* remove padding */
20752  touch.x = bounds.x - style->touch_padding.x;
20753  touch.y = bounds.y - style->touch_padding.y;
20754  touch.w = bounds.w + style->touch_padding.x * 2;
20755  touch.h = bounds.h + style->touch_padding.y * 2;
20756 
20757  /* update button */
20758  if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
20759  *value = !(*value);
20760 
20761  /* draw selectable */
20762  if (style->draw_begin) style->draw_begin(out, style->userdata);
20763  nk_draw_selectable(out, *state, style, *value, &bounds, 0,0,NK_SYMBOL_NONE, str, len, align, font);
20764  if (style->draw_end) style->draw_end(out, style->userdata);
20765  return old_value != *value;
20766 }
20767 NK_LIB int
20768 nk_do_selectable_image(nk_flags *state, struct nk_command_buffer *out,
20769  struct nk_rect bounds, const char *str, int len, nk_flags align, int *value,
20770  const struct nk_image *img, const struct nk_style_selectable *style,
20771  const struct nk_input *in, const struct nk_user_font *font)
20772 {
20773  int old_value;
20774  struct nk_rect touch;
20775  struct nk_rect icon;
20776 
20777  NK_ASSERT(state);
20778  NK_ASSERT(out);
20779  NK_ASSERT(str);
20780  NK_ASSERT(len);
20781  NK_ASSERT(value);
20782  NK_ASSERT(style);
20783  NK_ASSERT(font);
20784 
20785  if (!state || !out || !str || !len || !value || !style || !font) return 0;
20786  old_value = *value;
20787 
20788  /* toggle behavior */
20789  touch.x = bounds.x - style->touch_padding.x;
20790  touch.y = bounds.y - style->touch_padding.y;
20791  touch.w = bounds.w + style->touch_padding.x * 2;
20792  touch.h = bounds.h + style->touch_padding.y * 2;
20793  if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
20794  *value = !(*value);
20795 
20796  icon.y = bounds.y + style->padding.y;
20797  icon.w = icon.h = bounds.h - 2 * style->padding.y;
20798  if (align & NK_TEXT_ALIGN_LEFT) {
20799  icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
20800  icon.x = NK_MAX(icon.x, 0);
20801  } else icon.x = bounds.x + 2 * style->padding.x;
20802 
20803  icon.x += style->image_padding.x;
20804  icon.y += style->image_padding.y;
20805  icon.w -= 2 * style->image_padding.x;
20806  icon.h -= 2 * style->image_padding.y;
20807 
20808  /* draw selectable */
20809  if (style->draw_begin) style->draw_begin(out, style->userdata);
20810  nk_draw_selectable(out, *state, style, *value, &bounds, &icon, img, NK_SYMBOL_NONE, str, len, align, font);
20811  if (style->draw_end) style->draw_end(out, style->userdata);
20812  return old_value != *value;
20813 }
20814 NK_LIB int
20815 nk_do_selectable_symbol(nk_flags *state, struct nk_command_buffer *out,
20816  struct nk_rect bounds, const char *str, int len, nk_flags align, int *value,
20817  enum nk_symbol_type sym, const struct nk_style_selectable *style,
20818  const struct nk_input *in, const struct nk_user_font *font)
20819 {
20820  int old_value;
20821  struct nk_rect touch;
20822  struct nk_rect icon;
20823 
20824  NK_ASSERT(state);
20825  NK_ASSERT(out);
20826  NK_ASSERT(str);
20827  NK_ASSERT(len);
20828  NK_ASSERT(value);
20829  NK_ASSERT(style);
20830  NK_ASSERT(font);
20831 
20832  if (!state || !out || !str || !len || !value || !style || !font) return 0;
20833  old_value = *value;
20834 
20835  /* toggle behavior */
20836  touch.x = bounds.x - style->touch_padding.x;
20837  touch.y = bounds.y - style->touch_padding.y;
20838  touch.w = bounds.w + style->touch_padding.x * 2;
20839  touch.h = bounds.h + style->touch_padding.y * 2;
20840  if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
20841  *value = !(*value);
20842 
20843  icon.y = bounds.y + style->padding.y;
20844  icon.w = icon.h = bounds.h - 2 * style->padding.y;
20845  if (align & NK_TEXT_ALIGN_LEFT) {
20846  icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
20847  icon.x = NK_MAX(icon.x, 0);
20848  } else icon.x = bounds.x + 2 * style->padding.x;
20849 
20850  icon.x += style->image_padding.x;
20851  icon.y += style->image_padding.y;
20852  icon.w -= 2 * style->image_padding.x;
20853  icon.h -= 2 * style->image_padding.y;
20854 
20855  /* draw selectable */
20856  if (style->draw_begin) style->draw_begin(out, style->userdata);
20857  nk_draw_selectable(out, *state, style, *value, &bounds, &icon, 0, sym, str, len, align, font);
20858  if (style->draw_end) style->draw_end(out, style->userdata);
20859  return old_value != *value;
20860 }
20861 
20862 NK_API int
20863 nk_selectable_text(struct nk_context *ctx, const char *str, int len,
20864  nk_flags align, int *value)
20865 {
20866  struct nk_window *win;
20867  struct nk_panel *layout;
20868  const struct nk_input *in;
20869  const struct nk_style *style;
20870 
20871  enum nk_widget_layout_states state;
20872  struct nk_rect bounds;
20873 
20874  NK_ASSERT(ctx);
20875  NK_ASSERT(value);
20876  NK_ASSERT(ctx->current);
20877  NK_ASSERT(ctx->current->layout);
20878  if (!ctx || !ctx->current || !ctx->current->layout || !value)
20879  return 0;
20880 
20881  win = ctx->current;
20882  layout = win->layout;
20883  style = &ctx->style;
20884 
20885  state = nk_widget(&bounds, ctx);
20886  if (!state) return 0;
20887  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20888  return nk_do_selectable(&ctx->last_widget_state, &win->buffer, bounds,
20889  str, len, align, value, &style->selectable, in, style->font);
20890 }
20891 NK_API int
20892 nk_selectable_image_text(struct nk_context *ctx, struct nk_image img,
20893  const char *str, int len, nk_flags align, int *value)
20894 {
20895  struct nk_window *win;
20896  struct nk_panel *layout;
20897  const struct nk_input *in;
20898  const struct nk_style *style;
20899 
20900  enum nk_widget_layout_states state;
20901  struct nk_rect bounds;
20902 
20903  NK_ASSERT(ctx);
20904  NK_ASSERT(value);
20905  NK_ASSERT(ctx->current);
20906  NK_ASSERT(ctx->current->layout);
20907  if (!ctx || !ctx->current || !ctx->current->layout || !value)
20908  return 0;
20909 
20910  win = ctx->current;
20911  layout = win->layout;
20912  style = &ctx->style;
20913 
20914  state = nk_widget(&bounds, ctx);
20915  if (!state) return 0;
20916  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20917  return nk_do_selectable_image(&ctx->last_widget_state, &win->buffer, bounds,
20918  str, len, align, value, &img, &style->selectable, in, style->font);
20919 }
20920 NK_API int
20922  const char *str, int len, nk_flags align, int *value)
20923 {
20924  struct nk_window *win;
20925  struct nk_panel *layout;
20926  const struct nk_input *in;
20927  const struct nk_style *style;
20928 
20929  enum nk_widget_layout_states state;
20930  struct nk_rect bounds;
20931 
20932  NK_ASSERT(ctx);
20933  NK_ASSERT(value);
20934  NK_ASSERT(ctx->current);
20935  NK_ASSERT(ctx->current->layout);
20936  if (!ctx || !ctx->current || !ctx->current->layout || !value)
20937  return 0;
20938 
20939  win = ctx->current;
20940  layout = win->layout;
20941  style = &ctx->style;
20942 
20943  state = nk_widget(&bounds, ctx);
20944  if (!state) return 0;
20945  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20946  return nk_do_selectable_symbol(&ctx->last_widget_state, &win->buffer, bounds,
20947  str, len, align, value, sym, &style->selectable, in, style->font);
20948 }
20949 NK_API int
20951  const char *title, nk_flags align, int *value)
20952 {
20953  return nk_selectable_symbol_text(ctx, sym, title, nk_strlen(title), align, value);
20954 }
20955 NK_API int nk_select_text(struct nk_context *ctx, const char *str, int len,
20956  nk_flags align, int value)
20957 {
20958  nk_selectable_text(ctx, str, len, align, &value);return value;
20959 }
20960 NK_API int nk_selectable_label(struct nk_context *ctx, const char *str, nk_flags align, int *value)
20961 {
20962  return nk_selectable_text(ctx, str, nk_strlen(str), align, value);
20963 }
20964 NK_API int nk_selectable_image_label(struct nk_context *ctx,struct nk_image img,
20965  const char *str, nk_flags align, int *value)
20966 {
20967  return nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, value);
20968 }
20969 NK_API int nk_select_label(struct nk_context *ctx, const char *str, nk_flags align, int value)
20970 {
20971  nk_selectable_text(ctx, str, nk_strlen(str), align, &value);return value;
20972 }
20973 NK_API int nk_select_image_label(struct nk_context *ctx, struct nk_image img,
20974  const char *str, nk_flags align, int value)
20975 {
20976  nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, &value);return value;
20977 }
20978 NK_API int nk_select_image_text(struct nk_context *ctx, struct nk_image img,
20979  const char *str, int len, nk_flags align, int value)
20980 {
20981  nk_selectable_image_text(ctx, img, str, len, align, &value);return value;
20982 }
20983 NK_API int
20984 nk_select_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym,
20985  const char *title, int title_len, nk_flags align, int value)
20986 {
20987  nk_selectable_symbol_text(ctx, sym, title, title_len, align, &value);return value;
20988 }
20989 NK_API int
20990 nk_select_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym,
20991  const char *title, nk_flags align, int value)
20992 {
20993  return nk_select_symbol_text(ctx, sym, title, nk_strlen(title), align, value);
20994 }
20995 
20996 
20997 
20998 
20999 
21000 /* ===============================================================
21001  *
21002  * SLIDER
21003  *
21004  * ===============================================================*/
21005 NK_LIB float
21006 nk_slider_behavior(nk_flags *state, struct nk_rect *logical_cursor,
21007  struct nk_rect *visual_cursor, struct nk_input *in,
21008  struct nk_rect bounds, float slider_min, float slider_max, float slider_value,
21009  float slider_step, float slider_steps)
21010 {
21011  int left_mouse_down;
21012  int left_mouse_click_in_cursor;
21013 
21014  /* check if visual cursor is being dragged */
21015  nk_widget_state_reset(state);
21016  left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
21017  left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
21018  NK_BUTTON_LEFT, *visual_cursor, nk_true);
21019 
21020  if (left_mouse_down && left_mouse_click_in_cursor) {
21021  float ratio = 0;
21022  const float d = in->mouse.pos.x - (visual_cursor->x+visual_cursor->w*0.5f);
21023  const float pxstep = bounds.w / slider_steps;
21024 
21025  /* only update value if the next slider step is reached */
21026  *state = NK_WIDGET_STATE_ACTIVE;
21027  if (NK_ABS(d) >= pxstep) {
21028  const float steps = (float)((int)(NK_ABS(d) / pxstep));
21029  slider_value += (d > 0) ? (slider_step*steps) : -(slider_step*steps);
21030  slider_value = NK_CLAMP(slider_min, slider_value, slider_max);
21031  ratio = (slider_value - slider_min)/slider_step;
21032  logical_cursor->x = bounds.x + (logical_cursor->w * ratio);
21033  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = logical_cursor->x;
21034  }
21035  }
21036 
21037  /* slider widget state */
21038  if (nk_input_is_mouse_hovering_rect(in, bounds))
21039  *state = NK_WIDGET_STATE_HOVERED;
21040  if (*state & NK_WIDGET_STATE_HOVER &&
21042  *state |= NK_WIDGET_STATE_ENTERED;
21043  else if (nk_input_is_mouse_prev_hovering_rect(in, bounds))
21044  *state |= NK_WIDGET_STATE_LEFT;
21045  return slider_value;
21046 }
21047 NK_LIB void
21048 nk_draw_slider(struct nk_command_buffer *out, nk_flags state,
21049  const struct nk_style_slider *style, const struct nk_rect *bounds,
21050  const struct nk_rect *visual_cursor, float min, float value, float max)
21051 {
21052  struct nk_rect fill;
21053  struct nk_rect bar;
21054  const struct nk_style_item *background;
21055 
21056  /* select correct slider images/colors */
21057  struct nk_color bar_color;
21058  const struct nk_style_item *cursor;
21059 
21060  NK_UNUSED(min);
21061  NK_UNUSED(max);
21062  NK_UNUSED(value);
21063 
21064  if (state & NK_WIDGET_STATE_ACTIVED) {
21065  background = &style->active;
21066  bar_color = style->bar_active;
21067  cursor = &style->cursor_active;
21068  } else if (state & NK_WIDGET_STATE_HOVER) {
21069  background = &style->hover;
21070  bar_color = style->bar_hover;
21071  cursor = &style->cursor_hover;
21072  } else {
21073  background = &style->normal;
21074  bar_color = style->bar_normal;
21075  cursor = &style->cursor_normal;
21076  }
21077  /* calculate slider background bar */
21078  bar.x = bounds->x;
21079  bar.y = (visual_cursor->y + visual_cursor->h/2) - bounds->h/12;
21080  bar.w = bounds->w;
21081  bar.h = bounds->h/6;
21082 
21083  /* filled background bar style */
21084  fill.w = (visual_cursor->x + (visual_cursor->w/2.0f)) - bar.x;
21085  fill.x = bar.x;
21086  fill.y = bar.y;
21087  fill.h = bar.h;
21088 
21089  /* draw background */
21090  if (background->type == NK_STYLE_ITEM_IMAGE) {
21091  nk_draw_image(out, *bounds, &background->data.image, nk_white);
21092  } else {
21093  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
21094  nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
21095  }
21096 
21097  /* draw slider bar */
21098  nk_fill_rect(out, bar, style->rounding, bar_color);
21099  nk_fill_rect(out, fill, style->rounding, style->bar_filled);
21100 
21101  /* draw cursor */
21102  if (cursor->type == NK_STYLE_ITEM_IMAGE)
21103  nk_draw_image(out, *visual_cursor, &cursor->data.image, nk_white);
21104  else nk_fill_circle(out, *visual_cursor, cursor->data.color);
21105 }
21106 NK_LIB float
21107 nk_do_slider(nk_flags *state,
21108  struct nk_command_buffer *out, struct nk_rect bounds,
21109  float min, float val, float max, float step,
21110  const struct nk_style_slider *style, struct nk_input *in,
21111  const struct nk_user_font *font)
21112 {
21113  float slider_range;
21114  float slider_min;
21115  float slider_max;
21116  float slider_value;
21117  float slider_steps;
21118  float cursor_offset;
21119 
21120  struct nk_rect visual_cursor;
21121  struct nk_rect logical_cursor;
21122 
21123  NK_ASSERT(style);
21124  NK_ASSERT(out);
21125  if (!out || !style)
21126  return 0;
21127 
21128  /* remove padding from slider bounds */
21129  bounds.x = bounds.x + style->padding.x;
21130  bounds.y = bounds.y + style->padding.y;
21131  bounds.h = NK_MAX(bounds.h, 2*style->padding.y);
21132  bounds.w = NK_MAX(bounds.w, 2*style->padding.x + style->cursor_size.x);
21133  bounds.w -= 2 * style->padding.x;
21134  bounds.h -= 2 * style->padding.y;
21135 
21136  /* optional buttons */
21137  if (style->show_buttons) {
21138  nk_flags ws;
21139  struct nk_rect button;
21140  button.y = bounds.y;
21141  button.w = bounds.h;
21142  button.h = bounds.h;
21143 
21144  /* decrement button */
21145  button.x = bounds.x;
21146  if (nk_do_button_symbol(&ws, out, button, style->dec_symbol, NK_BUTTON_DEFAULT,
21147  &style->dec_button, in, font))
21148  val -= step;
21149 
21150  /* increment button */
21151  button.x = (bounds.x + bounds.w) - button.w;
21152  if (nk_do_button_symbol(&ws, out, button, style->inc_symbol, NK_BUTTON_DEFAULT,
21153  &style->inc_button, in, font))
21154  val += step;
21155 
21156  bounds.x = bounds.x + button.w + style->spacing.x;
21157  bounds.w = bounds.w - (2*button.w + 2*style->spacing.x);
21158  }
21159 
21160  /* remove one cursor size to support visual cursor */
21161  bounds.x += style->cursor_size.x*0.5f;
21162  bounds.w -= style->cursor_size.x;
21163 
21164  /* make sure the provided values are correct */
21165  slider_max = NK_MAX(min, max);
21166  slider_min = NK_MIN(min, max);
21167  slider_value = NK_CLAMP(slider_min, val, slider_max);
21168  slider_range = slider_max - slider_min;
21169  slider_steps = slider_range / step;
21170  cursor_offset = (slider_value - slider_min) / step;
21171 
21172  /* calculate cursor
21173  Basically you have two cursors. One for visual representation and interaction
21174  and one for updating the actual cursor value. */
21175  logical_cursor.h = bounds.h;
21176  logical_cursor.w = bounds.w / slider_steps;
21177  logical_cursor.x = bounds.x + (logical_cursor.w * cursor_offset);
21178  logical_cursor.y = bounds.y;
21179 
21180  visual_cursor.h = style->cursor_size.y;
21181  visual_cursor.w = style->cursor_size.x;
21182  visual_cursor.y = (bounds.y + bounds.h*0.5f) - visual_cursor.h*0.5f;
21183  visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f;
21184 
21185  slider_value = nk_slider_behavior(state, &logical_cursor, &visual_cursor,
21186  in, bounds, slider_min, slider_max, slider_value, step, slider_steps);
21187  visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f;
21188 
21189  /* draw slider */
21190  if (style->draw_begin) style->draw_begin(out, style->userdata);
21191  nk_draw_slider(out, *state, style, &bounds, &visual_cursor, slider_min, slider_value, slider_max);
21192  if (style->draw_end) style->draw_end(out, style->userdata);
21193  return slider_value;
21194 }
21195 NK_API int
21196 nk_slider_float(struct nk_context *ctx, float min_value, float *value, float max_value,
21197  float value_step)
21198 {
21199  struct nk_window *win;
21200  struct nk_panel *layout;
21201  struct nk_input *in;
21202  const struct nk_style *style;
21203 
21204  int ret = 0;
21205  float old_value;
21206  struct nk_rect bounds;
21207  enum nk_widget_layout_states state;
21208 
21209  NK_ASSERT(ctx);
21210  NK_ASSERT(ctx->current);
21211  NK_ASSERT(ctx->current->layout);
21212  NK_ASSERT(value);
21213  if (!ctx || !ctx->current || !ctx->current->layout || !value)
21214  return ret;
21215 
21216  win = ctx->current;
21217  style = &ctx->style;
21218  layout = win->layout;
21219 
21220  state = nk_widget(&bounds, ctx);
21221  if (!state) return ret;
21222  in = (/*state == NK_WIDGET_ROM || */ layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
21223 
21224  old_value = *value;
21225  *value = nk_do_slider(&ctx->last_widget_state, &win->buffer, bounds, min_value,
21226  old_value, max_value, value_step, &style->slider, in, style->font);
21227  return (old_value > *value || old_value < *value);
21228 }
21229 NK_API float
21230 nk_slide_float(struct nk_context *ctx, float min, float val, float max, float step)
21231 {
21232  nk_slider_float(ctx, min, &val, max, step); return val;
21233 }
21234 NK_API int
21235 nk_slide_int(struct nk_context *ctx, int min, int val, int max, int step)
21236 {
21237  float value = (float)val;
21238  nk_slider_float(ctx, (float)min, &value, (float)max, (float)step);
21239  return (int)value;
21240 }
21241 NK_API int
21242 nk_slider_int(struct nk_context *ctx, int min, int *val, int max, int step)
21243 {
21244  int ret;
21245  float value = (float)*val;
21246  ret = nk_slider_float(ctx, (float)min, &value, (float)max, (float)step);
21247  *val = (int)value;
21248  return ret;
21249 }
21250 
21251 
21252 
21253 
21254 
21255 /* ===============================================================
21256  *
21257  * PROGRESS
21258  *
21259  * ===============================================================*/
21261 nk_progress_behavior(nk_flags *state, struct nk_input *in,
21262  struct nk_rect r, struct nk_rect cursor, nk_size max, nk_size value, int modifiable)
21263 {
21264  int left_mouse_down = 0;
21265  int left_mouse_click_in_cursor = 0;
21266 
21267  nk_widget_state_reset(state);
21268  if (!in || !modifiable) return value;
21269  left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
21270  left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
21271  NK_BUTTON_LEFT, cursor, nk_true);
21273  *state = NK_WIDGET_STATE_HOVERED;
21274 
21275  if (in && left_mouse_down && left_mouse_click_in_cursor) {
21276  if (left_mouse_down && left_mouse_click_in_cursor) {
21277  float ratio = NK_MAX(0, (float)(in->mouse.pos.x - cursor.x)) / (float)cursor.w;
21278  value = (nk_size)NK_CLAMP(0, (float)max * ratio, (float)max);
21279  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor.x + cursor.w/2.0f;
21280  *state |= NK_WIDGET_STATE_ACTIVE;
21281  }
21282  }
21283  /* set progressbar widget state */
21285  *state |= NK_WIDGET_STATE_ENTERED;
21286  else if (nk_input_is_mouse_prev_hovering_rect(in, r))
21287  *state |= NK_WIDGET_STATE_LEFT;
21288  return value;
21289 }
21290 NK_LIB void
21291 nk_draw_progress(struct nk_command_buffer *out, nk_flags state,
21292  const struct nk_style_progress *style, const struct nk_rect *bounds,
21293  const struct nk_rect *scursor, nk_size value, nk_size max)
21294 {
21295  const struct nk_style_item *background;
21296  const struct nk_style_item *cursor;
21297 
21298  NK_UNUSED(max);
21299  NK_UNUSED(value);
21300 
21301  /* select correct colors/images to draw */
21302  if (state & NK_WIDGET_STATE_ACTIVED) {
21303  background = &style->active;
21304  cursor = &style->cursor_active;
21305  } else if (state & NK_WIDGET_STATE_HOVER){
21306  background = &style->hover;
21307  cursor = &style->cursor_hover;
21308  } else {
21309  background = &style->normal;
21310  cursor = &style->cursor_normal;
21311  }
21312 
21313  /* draw background */
21314  if (background->type == NK_STYLE_ITEM_COLOR) {
21315  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
21316  nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
21317  } else nk_draw_image(out, *bounds, &background->data.image, nk_white);
21318 
21319  /* draw cursor */
21320  if (cursor->type == NK_STYLE_ITEM_COLOR) {
21321  nk_fill_rect(out, *scursor, style->rounding, cursor->data.color);
21322  nk_stroke_rect(out, *scursor, style->rounding, style->border, style->border_color);
21323  } else nk_draw_image(out, *scursor, &cursor->data.image, nk_white);
21324 }
21326 nk_do_progress(nk_flags *state,
21327  struct nk_command_buffer *out, struct nk_rect bounds,
21328  nk_size value, nk_size max, int modifiable,
21329  const struct nk_style_progress *style, struct nk_input *in)
21330 {
21331  float prog_scale;
21332  nk_size prog_value;
21333  struct nk_rect cursor;
21334 
21335  NK_ASSERT(style);
21336  NK_ASSERT(out);
21337  if (!out || !style) return 0;
21338 
21339  /* calculate progressbar cursor */
21340  cursor.w = NK_MAX(bounds.w, 2 * style->padding.x + 2 * style->border);
21341  cursor.h = NK_MAX(bounds.h, 2 * style->padding.y + 2 * style->border);
21342  cursor = nk_pad_rect(bounds, nk_vec2(style->padding.x + style->border, style->padding.y + style->border));
21343  prog_scale = (float)value / (float)max;
21344 
21345  /* update progressbar */
21346  prog_value = NK_MIN(value, max);
21347  prog_value = nk_progress_behavior(state, in, bounds, cursor,max, prog_value, modifiable);
21348  cursor.w = cursor.w * prog_scale;
21349 
21350  /* draw progressbar */
21351  if (style->draw_begin) style->draw_begin(out, style->userdata);
21352  nk_draw_progress(out, *state, style, &bounds, &cursor, value, max);
21353  if (style->draw_end) style->draw_end(out, style->userdata);
21354  return prog_value;
21355 }
21356 NK_API int
21357 nk_progress(struct nk_context *ctx, nk_size *cur, nk_size max, int is_modifyable)
21358 {
21359  struct nk_window *win;
21360  struct nk_panel *layout;
21361  const struct nk_style *style;
21362  struct nk_input *in;
21363 
21364  struct nk_rect bounds;
21365  enum nk_widget_layout_states state;
21366  nk_size old_value;
21367 
21368  NK_ASSERT(ctx);
21369  NK_ASSERT(cur);
21370  NK_ASSERT(ctx->current);
21371  NK_ASSERT(ctx->current->layout);
21372  if (!ctx || !ctx->current || !ctx->current->layout || !cur)
21373  return 0;
21374 
21375  win = ctx->current;
21376  style = &ctx->style;
21377  layout = win->layout;
21378  state = nk_widget(&bounds, ctx);
21379  if (!state) return 0;
21380 
21381  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
21382  old_value = *cur;
21383  *cur = nk_do_progress(&ctx->last_widget_state, &win->buffer, bounds,
21384  *cur, max, is_modifyable, &style->progress, in);
21385  return (*cur != old_value);
21386 }
21388 nk_prog(struct nk_context *ctx, nk_size cur, nk_size max, int modifyable)
21389 {
21390  nk_progress(ctx, &cur, max, modifyable);
21391  return cur;
21392 }
21393 
21394 
21395 
21396 
21397 
21398 /* ===============================================================
21399  *
21400  * SCROLLBAR
21401  *
21402  * ===============================================================*/
21403 NK_LIB float
21404 nk_scrollbar_behavior(nk_flags *state, struct nk_input *in,
21405  int has_scrolling, const struct nk_rect *scroll,
21406  const struct nk_rect *cursor, const struct nk_rect *empty0,
21407  const struct nk_rect *empty1, float scroll_offset,
21408  float target, float scroll_step, enum nk_orientation o)
21409 {
21410  nk_flags ws = 0;
21411  int left_mouse_down;
21412  int left_mouse_clicked;
21413  int left_mouse_click_in_cursor;
21414  float scroll_delta;
21415 
21416  nk_widget_state_reset(state);
21417  if (!in) return scroll_offset;
21418 
21419  left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
21420  left_mouse_clicked = in->mouse.buttons[NK_BUTTON_LEFT].clicked;
21421  left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
21422  NK_BUTTON_LEFT, *cursor, nk_true);
21423  if (nk_input_is_mouse_hovering_rect(in, *scroll))
21424  *state = NK_WIDGET_STATE_HOVERED;
21425 
21426  scroll_delta = (o == NK_VERTICAL) ? in->mouse.scroll_delta.y: in->mouse.scroll_delta.x;
21427  if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) {
21428  /* update cursor by mouse dragging */
21429  float pixel, delta;
21430  *state = NK_WIDGET_STATE_ACTIVE;
21431  if (o == NK_VERTICAL) {
21432  float cursor_y;
21433  pixel = in->mouse.delta.y;
21434  delta = (pixel / scroll->h) * target;
21435  scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->h);
21436  cursor_y = scroll->y + ((scroll_offset/target) * scroll->h);
21437  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = cursor_y + cursor->h/2.0f;
21438  } else {
21439  float cursor_x;
21440  pixel = in->mouse.delta.x;
21441  delta = (pixel / scroll->w) * target;
21442  scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->w);
21443  cursor_x = scroll->x + ((scroll_offset/target) * scroll->w);
21444  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor_x + cursor->w/2.0f;
21445  }
21446  } else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_UP) && o == NK_VERTICAL && has_scrolling)||
21447  nk_button_behavior(&ws, *empty0, in, NK_BUTTON_DEFAULT)) {
21448  /* scroll page up by click on empty space or shortcut */
21449  if (o == NK_VERTICAL)
21450  scroll_offset = NK_MAX(0, scroll_offset - scroll->h);
21451  else scroll_offset = NK_MAX(0, scroll_offset - scroll->w);
21452  } else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_DOWN) && o == NK_VERTICAL && has_scrolling) ||
21453  nk_button_behavior(&ws, *empty1, in, NK_BUTTON_DEFAULT)) {
21454  /* scroll page down by click on empty space or shortcut */
21455  if (o == NK_VERTICAL)
21456  scroll_offset = NK_MIN(scroll_offset + scroll->h, target - scroll->h);
21457  else scroll_offset = NK_MIN(scroll_offset + scroll->w, target - scroll->w);
21458  } else if (has_scrolling) {
21459  if ((scroll_delta < 0 || (scroll_delta > 0))) {
21460  /* update cursor by mouse scrolling */
21461  scroll_offset = scroll_offset + scroll_step * (-scroll_delta);
21462  if (o == NK_VERTICAL)
21463  scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->h);
21464  else scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->w);
21465  } else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_START)) {
21466  /* update cursor to the beginning */
21467  if (o == NK_VERTICAL) scroll_offset = 0;
21468  } else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_END)) {
21469  /* update cursor to the end */
21470  if (o == NK_VERTICAL) scroll_offset = target - scroll->h;
21471  }
21472  }
21473  if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *scroll))
21474  *state |= NK_WIDGET_STATE_ENTERED;
21475  else if (nk_input_is_mouse_prev_hovering_rect(in, *scroll))
21476  *state |= NK_WIDGET_STATE_LEFT;
21477  return scroll_offset;
21478 }
21479 NK_LIB void
21480 nk_draw_scrollbar(struct nk_command_buffer *out, nk_flags state,
21481  const struct nk_style_scrollbar *style, const struct nk_rect *bounds,
21482  const struct nk_rect *scroll)
21483 {
21484  const struct nk_style_item *background;
21485  const struct nk_style_item *cursor;
21486 
21487  /* select correct colors/images to draw */
21488  if (state & NK_WIDGET_STATE_ACTIVED) {
21489  background = &style->active;
21490  cursor = &style->cursor_active;
21491  } else if (state & NK_WIDGET_STATE_HOVER) {
21492  background = &style->hover;
21493  cursor = &style->cursor_hover;
21494  } else {
21495  background = &style->normal;
21496  cursor = &style->cursor_normal;
21497  }
21498 
21499  /* draw background */
21500  if (background->type == NK_STYLE_ITEM_COLOR) {
21501  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
21502  nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
21503  } else {
21504  nk_draw_image(out, *bounds, &background->data.image, nk_white);
21505  }
21506 
21507  /* draw cursor */
21508  if (cursor->type == NK_STYLE_ITEM_COLOR) {
21509  nk_fill_rect(out, *scroll, style->rounding_cursor, cursor->data.color);
21510  nk_stroke_rect(out, *scroll, style->rounding_cursor, style->border_cursor, style->cursor_border_color);
21511  } else nk_draw_image(out, *scroll, &cursor->data.image, nk_white);
21512 }
21513 NK_LIB float
21514 nk_do_scrollbarv(nk_flags *state,
21515  struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling,
21516  float offset, float target, float step, float button_pixel_inc,
21517  const struct nk_style_scrollbar *style, struct nk_input *in,
21518  const struct nk_user_font *font)
21519 {
21520  struct nk_rect empty_north;
21521  struct nk_rect empty_south;
21522  struct nk_rect cursor;
21523 
21524  float scroll_step;
21525  float scroll_offset;
21526  float scroll_off;
21527  float scroll_ratio;
21528 
21529  NK_ASSERT(out);
21530  NK_ASSERT(style);
21531  NK_ASSERT(state);
21532  if (!out || !style) return 0;
21533 
21534  scroll.w = NK_MAX(scroll.w, 1);
21535  scroll.h = NK_MAX(scroll.h, 0);
21536  if (target <= scroll.h) return 0;
21537 
21538  /* optional scrollbar buttons */
21539  if (style->show_buttons) {
21540  nk_flags ws;
21541  float scroll_h;
21542  struct nk_rect button;
21543 
21544  button.x = scroll.x;
21545  button.w = scroll.w;
21546  button.h = scroll.w;
21547 
21548  scroll_h = NK_MAX(scroll.h - 2 * button.h,0);
21549  scroll_step = NK_MIN(step, button_pixel_inc);
21550 
21551  /* decrement button */
21552  button.y = scroll.y;
21553  if (nk_do_button_symbol(&ws, out, button, style->dec_symbol,
21554  NK_BUTTON_REPEATER, &style->dec_button, in, font))
21555  offset = offset - scroll_step;
21556 
21557  /* increment button */
21558  button.y = scroll.y + scroll.h - button.h;
21559  if (nk_do_button_symbol(&ws, out, button, style->inc_symbol,
21560  NK_BUTTON_REPEATER, &style->inc_button, in, font))
21561  offset = offset + scroll_step;
21562 
21563  scroll.y = scroll.y + button.h;
21564  scroll.h = scroll_h;
21565  }
21566 
21567  /* calculate scrollbar constants */
21568  scroll_step = NK_MIN(step, scroll.h);
21569  scroll_offset = NK_CLAMP(0, offset, target - scroll.h);
21570  scroll_ratio = scroll.h / target;
21571  scroll_off = scroll_offset / target;
21572 
21573  /* calculate scrollbar cursor bounds */
21574  cursor.h = NK_MAX((scroll_ratio * scroll.h) - (2*style->border + 2*style->padding.y), 0);
21575  cursor.y = scroll.y + (scroll_off * scroll.h) + style->border + style->padding.y;
21576  cursor.w = scroll.w - (2 * style->border + 2 * style->padding.x);
21577  cursor.x = scroll.x + style->border + style->padding.x;
21578 
21579  /* calculate empty space around cursor */
21580  empty_north.x = scroll.x;
21581  empty_north.y = scroll.y;
21582  empty_north.w = scroll.w;
21583  empty_north.h = NK_MAX(cursor.y - scroll.y, 0);
21584 
21585  empty_south.x = scroll.x;
21586  empty_south.y = cursor.y + cursor.h;
21587  empty_south.w = scroll.w;
21588  empty_south.h = NK_MAX((scroll.y + scroll.h) - (cursor.y + cursor.h), 0);
21589 
21590  /* update scrollbar */
21591  scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
21592  &empty_north, &empty_south, scroll_offset, target, scroll_step, NK_VERTICAL);
21593  scroll_off = scroll_offset / target;
21594  cursor.y = scroll.y + (scroll_off * scroll.h) + style->border_cursor + style->padding.y;
21595 
21596  /* draw scrollbar */
21597  if (style->draw_begin) style->draw_begin(out, style->userdata);
21598  nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
21599  if (style->draw_end) style->draw_end(out, style->userdata);
21600  return scroll_offset;
21601 }
21602 NK_LIB float
21603 nk_do_scrollbarh(nk_flags *state,
21604  struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling,
21605  float offset, float target, float step, float button_pixel_inc,
21606  const struct nk_style_scrollbar *style, struct nk_input *in,
21607  const struct nk_user_font *font)
21608 {
21609  struct nk_rect cursor;
21610  struct nk_rect empty_west;
21611  struct nk_rect empty_east;
21612 
21613  float scroll_step;
21614  float scroll_offset;
21615  float scroll_off;
21616  float scroll_ratio;
21617 
21618  NK_ASSERT(out);
21619  NK_ASSERT(style);
21620  if (!out || !style) return 0;
21621 
21622  /* scrollbar background */
21623  scroll.h = NK_MAX(scroll.h, 1);
21624  scroll.w = NK_MAX(scroll.w, 2 * scroll.h);
21625  if (target <= scroll.w) return 0;
21626 
21627  /* optional scrollbar buttons */
21628  if (style->show_buttons) {
21629  nk_flags ws;
21630  float scroll_w;
21631  struct nk_rect button;
21632  button.y = scroll.y;
21633  button.w = scroll.h;
21634  button.h = scroll.h;
21635 
21636  scroll_w = scroll.w - 2 * button.w;
21637  scroll_step = NK_MIN(step, button_pixel_inc);
21638 
21639  /* decrement button */
21640  button.x = scroll.x;
21641  if (nk_do_button_symbol(&ws, out, button, style->dec_symbol,
21642  NK_BUTTON_REPEATER, &style->dec_button, in, font))
21643  offset = offset - scroll_step;
21644 
21645  /* increment button */
21646  button.x = scroll.x + scroll.w - button.w;
21647  if (nk_do_button_symbol(&ws, out, button, style->inc_symbol,
21648  NK_BUTTON_REPEATER, &style->inc_button, in, font))
21649  offset = offset + scroll_step;
21650 
21651  scroll.x = scroll.x + button.w;
21652  scroll.w = scroll_w;
21653  }
21654 
21655  /* calculate scrollbar constants */
21656  scroll_step = NK_MIN(step, scroll.w);
21657  scroll_offset = NK_CLAMP(0, offset, target - scroll.w);
21658  scroll_ratio = scroll.w / target;
21659  scroll_off = scroll_offset / target;
21660 
21661  /* calculate cursor bounds */
21662  cursor.w = (scroll_ratio * scroll.w) - (2*style->border + 2*style->padding.x);
21663  cursor.x = scroll.x + (scroll_off * scroll.w) + style->border + style->padding.x;
21664  cursor.h = scroll.h - (2 * style->border + 2 * style->padding.y);
21665  cursor.y = scroll.y + style->border + style->padding.y;
21666 
21667  /* calculate empty space around cursor */
21668  empty_west.x = scroll.x;
21669  empty_west.y = scroll.y;
21670  empty_west.w = cursor.x - scroll.x;
21671  empty_west.h = scroll.h;
21672 
21673  empty_east.x = cursor.x + cursor.w;
21674  empty_east.y = scroll.y;
21675  empty_east.w = (scroll.x + scroll.w) - (cursor.x + cursor.w);
21676  empty_east.h = scroll.h;
21677 
21678  /* update scrollbar */
21679  scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
21680  &empty_west, &empty_east, scroll_offset, target, scroll_step, NK_HORIZONTAL);
21681  scroll_off = scroll_offset / target;
21682  cursor.x = scroll.x + (scroll_off * scroll.w);
21683 
21684  /* draw scrollbar */
21685  if (style->draw_begin) style->draw_begin(out, style->userdata);
21686  nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
21687  if (style->draw_end) style->draw_end(out, style->userdata);
21688  return scroll_offset;
21689 }
21690 
21691 
21692 
21693 
21694 
21695 /* ===============================================================
21696  *
21697  * TEXT EDITOR
21698  *
21699  * ===============================================================*/
21700 /* stb_textedit.h - v1.8 - public domain - Sean Barrett */
21701 struct nk_text_find {
21702  float x,y; /* position of n'th character */
21703  float height; /* height of line */
21704  int first_char, length; /* first char of row, and length */
21705  int prev_first; /*_ first char of previous row */
21706 };
21707 
21708 struct nk_text_edit_row {
21709  float x0,x1;
21710  /* starting x location, end x location (allows for align=right, etc) */
21711  float baseline_y_delta;
21712  /* position of baseline relative to previous row's baseline*/
21713  float ymin,ymax;
21714  /* height of row above and below baseline */
21715  int num_chars;
21716 };
21717 
21718 /* forward declarations */
21719 NK_INTERN void nk_textedit_makeundo_delete(struct nk_text_edit*, int, int);
21720 NK_INTERN void nk_textedit_makeundo_insert(struct nk_text_edit*, int, int);
21721 NK_INTERN void nk_textedit_makeundo_replace(struct nk_text_edit*, int, int, int);
21722 #define NK_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
21723 
21724 NK_INTERN float
21725 nk_textedit_get_width(const struct nk_text_edit *edit, int line_start, int char_id,
21726  const struct nk_user_font *font)
21727 {
21728  int len = 0;
21729  nk_rune unicode = 0;
21730  const char *str = nk_str_at_const(&edit->string, line_start + char_id, &unicode, &len);
21731  return font->width(font->userdata, font->height, str, len);
21732 }
21733 NK_INTERN void
21734 nk_textedit_layout_row(struct nk_text_edit_row *r, struct nk_text_edit *edit,
21735  int line_start_id, float row_height, const struct nk_user_font *font)
21736 {
21737  int l;
21738  int glyphs = 0;
21739  nk_rune unicode;
21740  const char *remaining;
21741  int len = nk_str_len_char(&edit->string);
21742  const char *end = nk_str_get_const(&edit->string) + len;
21743  const char *text = nk_str_at_const(&edit->string, line_start_id, &unicode, &l);
21744  const struct nk_vec2 size = nk_text_calculate_text_bounds(font,
21745  text, (int)(end - text), row_height, &remaining, 0, &glyphs, NK_STOP_ON_NEW_LINE);
21746 
21747  r->x0 = 0.0f;
21748  r->x1 = size.x;
21749  r->baseline_y_delta = size.y;
21750  r->ymin = 0.0f;
21751  r->ymax = size.y;
21752  r->num_chars = glyphs;
21753 }
21754 NK_INTERN int
21755 nk_textedit_locate_coord(struct nk_text_edit *edit, float x, float y,
21756  const struct nk_user_font *font, float row_height)
21757 {
21758  struct nk_text_edit_row r;
21759  int n = edit->string.len;
21760  float base_y = 0, prev_x;
21761  int i=0, k;
21762 
21763  r.x0 = r.x1 = 0;
21764  r.ymin = r.ymax = 0;
21765  r.num_chars = 0;
21766 
21767  /* search rows to find one that straddles 'y' */
21768  while (i < n) {
21769  nk_textedit_layout_row(&r, edit, i, row_height, font);
21770  if (r.num_chars <= 0)
21771  return n;
21772 
21773  if (i==0 && y < base_y + r.ymin)
21774  return 0;
21775 
21776  if (y < base_y + r.ymax)
21777  break;
21778 
21779  i += r.num_chars;
21780  base_y += r.baseline_y_delta;
21781  }
21782 
21783  /* below all text, return 'after' last character */
21784  if (i >= n)
21785  return n;
21786 
21787  /* check if it's before the beginning of the line */
21788  if (x < r.x0)
21789  return i;
21790 
21791  /* check if it's before the end of the line */
21792  if (x < r.x1) {
21793  /* search characters in row for one that straddles 'x' */
21794  k = i;
21795  prev_x = r.x0;
21796  for (i=0; i < r.num_chars; ++i) {
21797  float w = nk_textedit_get_width(edit, k, i, font);
21798  if (x < prev_x+w) {
21799  if (x < prev_x+w/2)
21800  return k+i;
21801  else return k+i+1;
21802  }
21803  prev_x += w;
21804  }
21805  /* shouldn't happen, but if it does, fall through to end-of-line case */
21806  }
21807 
21808  /* if the last character is a newline, return that.
21809  * otherwise return 'after' the last character */
21810  if (nk_str_rune_at(&edit->string, i+r.num_chars-1) == '\n')
21811  return i+r.num_chars-1;
21812  else return i+r.num_chars;
21813 }
21814 NK_LIB void
21815 nk_textedit_click(struct nk_text_edit *state, float x, float y,
21816  const struct nk_user_font *font, float row_height)
21817 {
21818  /* API click: on mouse down, move the cursor to the clicked location,
21819  * and reset the selection */
21820  state->cursor = nk_textedit_locate_coord(state, x, y, font, row_height);
21821  state->select_start = state->cursor;
21822  state->select_end = state->cursor;
21823  state->has_preferred_x = 0;
21824 }
21825 NK_LIB void
21826 nk_textedit_drag(struct nk_text_edit *state, float x, float y,
21827  const struct nk_user_font *font, float row_height)
21828 {
21829  /* API drag: on mouse drag, move the cursor and selection endpoint
21830  * to the clicked location */
21831  int p = nk_textedit_locate_coord(state, x, y, font, row_height);
21832  if (state->select_start == state->select_end)
21833  state->select_start = state->cursor;
21834  state->cursor = state->select_end = p;
21835 }
21836 NK_INTERN void
21837 nk_textedit_find_charpos(struct nk_text_find *find, struct nk_text_edit *state,
21838  int n, int single_line, const struct nk_user_font *font, float row_height)
21839 {
21840  /* find the x/y location of a character, and remember info about the previous
21841  * row in case we get a move-up event (for page up, we'll have to rescan) */
21842  struct nk_text_edit_row r;
21843  int prev_start = 0;
21844  int z = state->string.len;
21845  int i=0, first;
21846 
21847  nk_zero_struct(r);
21848  if (n == z) {
21849  /* if it's at the end, then find the last line -- simpler than trying to
21850  explicitly handle this case in the regular code */
21851  nk_textedit_layout_row(&r, state, 0, row_height, font);
21852  if (single_line) {
21853  find->first_char = 0;
21854  find->length = z;
21855  } else {
21856  while (i < z) {
21857  prev_start = i;
21858  i += r.num_chars;
21859  nk_textedit_layout_row(&r, state, i, row_height, font);
21860  }
21861 
21862  find->first_char = i;
21863  find->length = r.num_chars;
21864  }
21865  find->x = r.x1;
21866  find->y = r.ymin;
21867  find->height = r.ymax - r.ymin;
21868  find->prev_first = prev_start;
21869  return;
21870  }
21871 
21872  /* search rows to find the one that straddles character n */
21873  find->y = 0;
21874 
21875  for(;;) {
21876  nk_textedit_layout_row(&r, state, i, row_height, font);
21877  if (n < i + r.num_chars) break;
21878  prev_start = i;
21879  i += r.num_chars;
21880  find->y += r.baseline_y_delta;
21881  }
21882 
21883  find->first_char = first = i;
21884  find->length = r.num_chars;
21885  find->height = r.ymax - r.ymin;
21886  find->prev_first = prev_start;
21887 
21888  /* now scan to find xpos */
21889  find->x = r.x0;
21890  for (i=0; first+i < n; ++i)
21891  find->x += nk_textedit_get_width(state, first, i, font);
21892 }
21893 NK_INTERN void
21894 nk_textedit_clamp(struct nk_text_edit *state)
21895 {
21896  /* make the selection/cursor state valid if client altered the string */
21897  int n = state->string.len;
21898  if (NK_TEXT_HAS_SELECTION(state)) {
21899  if (state->select_start > n) state->select_start = n;
21900  if (state->select_end > n) state->select_end = n;
21901  /* if clamping forced them to be equal, move the cursor to match */
21902  if (state->select_start == state->select_end)
21903  state->cursor = state->select_start;
21904  }
21905  if (state->cursor > n) state->cursor = n;
21906 }
21907 NK_API void
21908 nk_textedit_delete(struct nk_text_edit *state, int where, int len)
21909 {
21910  /* delete characters while updating undo */
21911  nk_textedit_makeundo_delete(state, where, len);
21912  nk_str_delete_runes(&state->string, where, len);
21913  state->has_preferred_x = 0;
21914 }
21915 NK_API void
21917 {
21918  /* delete the section */
21919  nk_textedit_clamp(state);
21920  if (NK_TEXT_HAS_SELECTION(state)) {
21921  if (state->select_start < state->select_end) {
21922  nk_textedit_delete(state, state->select_start,
21923  state->select_end - state->select_start);
21924  state->select_end = state->cursor = state->select_start;
21925  } else {
21926  nk_textedit_delete(state, state->select_end,
21927  state->select_start - state->select_end);
21928  state->select_start = state->cursor = state->select_end;
21929  }
21930  state->has_preferred_x = 0;
21931  }
21932 }
21933 NK_INTERN void
21934 nk_textedit_sortselection(struct nk_text_edit *state)
21935 {
21936  /* canonicalize the selection so start <= end */
21937  if (state->select_end < state->select_start) {
21938  int temp = state->select_end;
21939  state->select_end = state->select_start;
21940  state->select_start = temp;
21941  }
21942 }
21943 NK_INTERN void
21944 nk_textedit_move_to_first(struct nk_text_edit *state)
21945 {
21946  /* move cursor to first character of selection */
21947  if (NK_TEXT_HAS_SELECTION(state)) {
21948  nk_textedit_sortselection(state);
21949  state->cursor = state->select_start;
21950  state->select_end = state->select_start;
21951  state->has_preferred_x = 0;
21952  }
21953 }
21954 NK_INTERN void
21955 nk_textedit_move_to_last(struct nk_text_edit *state)
21956 {
21957  /* move cursor to last character of selection */
21958  if (NK_TEXT_HAS_SELECTION(state)) {
21959  nk_textedit_sortselection(state);
21960  nk_textedit_clamp(state);
21961  state->cursor = state->select_end;
21962  state->select_start = state->select_end;
21963  state->has_preferred_x = 0;
21964  }
21965 }
21966 NK_INTERN int
21967 nk_is_word_boundary( struct nk_text_edit *state, int idx)
21968 {
21969  int len;
21970  nk_rune c;
21971  if (idx <= 0) return 1;
21972  if (!nk_str_at_rune(&state->string, idx, &c, &len)) return 1;
21973  return (c == ' ' || c == '\t' ||c == 0x3000 || c == ',' || c == ';' ||
21974  c == '(' || c == ')' || c == '{' || c == '}' || c == '[' || c == ']' ||
21975  c == '|');
21976 }
21977 NK_INTERN int
21978 nk_textedit_move_to_word_previous(struct nk_text_edit *state)
21979 {
21980  int c = state->cursor - 1;
21981  while( c >= 0 && !nk_is_word_boundary(state, c))
21982  --c;
21983 
21984  if( c < 0 )
21985  c = 0;
21986 
21987  return c;
21988 }
21989 NK_INTERN int
21990 nk_textedit_move_to_word_next(struct nk_text_edit *state)
21991 {
21992  const int len = state->string.len;
21993  int c = state->cursor+1;
21994  while( c < len && !nk_is_word_boundary(state, c))
21995  ++c;
21996 
21997  if( c > len )
21998  c = len;
21999 
22000  return c;
22001 }
22002 NK_INTERN void
22003 nk_textedit_prep_selection_at_cursor(struct nk_text_edit *state)
22004 {
22005  /* update selection and cursor to match each other */
22006  if (!NK_TEXT_HAS_SELECTION(state))
22007  state->select_start = state->select_end = state->cursor;
22008  else state->cursor = state->select_end;
22009 }
22010 NK_API int
22011 nk_textedit_cut(struct nk_text_edit *state)
22012 {
22013  /* API cut: delete selection */
22014  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
22015  return 0;
22016  if (NK_TEXT_HAS_SELECTION(state)) {
22017  nk_textedit_delete_selection(state); /* implicitly clamps */
22018  state->has_preferred_x = 0;
22019  return 1;
22020  }
22021  return 0;
22022 }
22023 NK_API int
22024 nk_textedit_paste(struct nk_text_edit *state, char const *ctext, int len)
22025 {
22026  /* API paste: replace existing selection with passed-in text */
22027  int glyphs;
22028  const char *text = (const char *) ctext;
22029  if (state->mode == NK_TEXT_EDIT_MODE_VIEW) return 0;
22030 
22031  /* if there's a selection, the paste should delete it */
22032  nk_textedit_clamp(state);
22034 
22035  /* try to insert the characters */
22036  glyphs = nk_utf_len(ctext, len);
22037  if (nk_str_insert_text_char(&state->string, state->cursor, text, len)) {
22038  nk_textedit_makeundo_insert(state, state->cursor, glyphs);
22039  state->cursor += len;
22040  state->has_preferred_x = 0;
22041  return 1;
22042  }
22043  /* remove the undo since we didn't actually insert the characters */
22044  if (state->undo.undo_point)
22045  --state->undo.undo_point;
22046  return 0;
22047 }
22048 NK_API void
22049 nk_textedit_text(struct nk_text_edit *state, const char *text, int total_len)
22050 {
22051  nk_rune unicode;
22052  int glyph_len;
22053  int text_len = 0;
22054 
22055  NK_ASSERT(state);
22056  NK_ASSERT(text);
22057  if (!text || !total_len || state->mode == NK_TEXT_EDIT_MODE_VIEW) return;
22058 
22059  glyph_len = nk_utf_decode(text, &unicode, total_len);
22060  while ((text_len < total_len) && glyph_len)
22061  {
22062  /* don't insert a backward delete, just process the event */
22063  if (unicode == 127) goto next;
22064  /* can't add newline in single-line mode */
22065  if (unicode == '\n' && state->single_line) goto next;
22066  /* filter incoming text */
22067  if (state->filter && !state->filter(state, unicode)) goto next;
22068 
22069  if (!NK_TEXT_HAS_SELECTION(state) &&
22070  state->cursor < state->string.len)
22071  {
22072  if (state->mode == NK_TEXT_EDIT_MODE_REPLACE) {
22073  nk_textedit_makeundo_replace(state, state->cursor, 1, 1);
22074  nk_str_delete_runes(&state->string, state->cursor, 1);
22075  }
22076  if (nk_str_insert_text_utf8(&state->string, state->cursor,
22077  text+text_len, 1))
22078  {
22079  ++state->cursor;
22080  state->has_preferred_x = 0;
22081  }
22082  } else {
22083  nk_textedit_delete_selection(state); /* implicitly clamps */
22084  if (nk_str_insert_text_utf8(&state->string, state->cursor,
22085  text+text_len, 1))
22086  {
22087  nk_textedit_makeundo_insert(state, state->cursor, 1);
22088  ++state->cursor;
22089  state->has_preferred_x = 0;
22090  }
22091  }
22092  next:
22093  text_len += glyph_len;
22094  glyph_len = nk_utf_decode(text + text_len, &unicode, total_len-text_len);
22095  }
22096 }
22097 NK_LIB void
22098 nk_textedit_key(struct nk_text_edit *state, enum nk_keys key, int shift_mod,
22099  const struct nk_user_font *font, float row_height)
22100 {
22101 retry:
22102  switch (key)
22103  {
22104  case NK_KEY_NONE:
22105  case NK_KEY_CTRL:
22106  case NK_KEY_ENTER:
22107  case NK_KEY_SHIFT:
22108  case NK_KEY_TAB:
22109  case NK_KEY_COPY:
22110  case NK_KEY_CUT:
22111  case NK_KEY_PASTE:
22112  case NK_KEY_MAX:
22113  default: break;
22114  case NK_KEY_TEXT_UNDO:
22115  nk_textedit_undo(state);
22116  state->has_preferred_x = 0;
22117  break;
22118 
22119  case NK_KEY_TEXT_REDO:
22120  nk_textedit_redo(state);
22121  state->has_preferred_x = 0;
22122  break;
22123 
22125  nk_textedit_select_all(state);
22126  state->has_preferred_x = 0;
22127  break;
22128 
22130  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
22131  state->mode = NK_TEXT_EDIT_MODE_INSERT;
22132  break;
22134  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
22136  break;
22138  if (state->mode == NK_TEXT_EDIT_MODE_INSERT ||
22139  state->mode == NK_TEXT_EDIT_MODE_REPLACE)
22140  state->mode = NK_TEXT_EDIT_MODE_VIEW;
22141  break;
22142 
22143  case NK_KEY_LEFT:
22144  if (shift_mod) {
22145  nk_textedit_clamp(state);
22146  nk_textedit_prep_selection_at_cursor(state);
22147  /* move selection left */
22148  if (state->select_end > 0)
22149  --state->select_end;
22150  state->cursor = state->select_end;
22151  state->has_preferred_x = 0;
22152  } else {
22153  /* if currently there's a selection,
22154  * move cursor to start of selection */
22155  if (NK_TEXT_HAS_SELECTION(state))
22156  nk_textedit_move_to_first(state);
22157  else if (state->cursor > 0)
22158  --state->cursor;
22159  state->has_preferred_x = 0;
22160  } break;
22161 
22162  case NK_KEY_RIGHT:
22163  if (shift_mod) {
22164  nk_textedit_prep_selection_at_cursor(state);
22165  /* move selection right */
22166  ++state->select_end;
22167  nk_textedit_clamp(state);
22168  state->cursor = state->select_end;
22169  state->has_preferred_x = 0;
22170  } else {
22171  /* if currently there's a selection,
22172  * move cursor to end of selection */
22173  if (NK_TEXT_HAS_SELECTION(state))
22174  nk_textedit_move_to_last(state);
22175  else ++state->cursor;
22176  nk_textedit_clamp(state);
22177  state->has_preferred_x = 0;
22178  } break;
22179 
22180  case NK_KEY_TEXT_WORD_LEFT:
22181  if (shift_mod) {
22182  if( !NK_TEXT_HAS_SELECTION( state ) )
22183  nk_textedit_prep_selection_at_cursor(state);
22184  state->cursor = nk_textedit_move_to_word_previous(state);
22185  state->select_end = state->cursor;
22186  nk_textedit_clamp(state );
22187  } else {
22188  if (NK_TEXT_HAS_SELECTION(state))
22189  nk_textedit_move_to_first(state);
22190  else {
22191  state->cursor = nk_textedit_move_to_word_previous(state);
22192  nk_textedit_clamp(state );
22193  }
22194  } break;
22195 
22197  if (shift_mod) {
22198  if( !NK_TEXT_HAS_SELECTION( state ) )
22199  nk_textedit_prep_selection_at_cursor(state);
22200  state->cursor = nk_textedit_move_to_word_next(state);
22201  state->select_end = state->cursor;
22202  nk_textedit_clamp(state);
22203  } else {
22204  if (NK_TEXT_HAS_SELECTION(state))
22205  nk_textedit_move_to_last(state);
22206  else {
22207  state->cursor = nk_textedit_move_to_word_next(state);
22208  nk_textedit_clamp(state );
22209  }
22210  } break;
22211 
22212  case NK_KEY_DOWN: {
22213  struct nk_text_find find;
22214  struct nk_text_edit_row row;
22215  int i, sel = shift_mod;
22216 
22217  if (state->single_line) {
22218  /* on windows, up&down in single-line behave like left&right */
22219  key = NK_KEY_RIGHT;
22220  goto retry;
22221  }
22222 
22223  if (sel)
22224  nk_textedit_prep_selection_at_cursor(state);
22225  else if (NK_TEXT_HAS_SELECTION(state))
22226  nk_textedit_move_to_last(state);
22227 
22228  /* compute current position of cursor point */
22229  nk_textedit_clamp(state);
22230  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22231  font, row_height);
22232 
22233  /* now find character position down a row */
22234  if (find.length)
22235  {
22236  float x;
22237  float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
22238  int start = find.first_char + find.length;
22239 
22240  state->cursor = start;
22241  nk_textedit_layout_row(&row, state, state->cursor, row_height, font);
22242  x = row.x0;
22243 
22244  for (i=0; i < row.num_chars && x < row.x1; ++i) {
22245  float dx = nk_textedit_get_width(state, start, i, font);
22246  x += dx;
22247  if (x > goal_x)
22248  break;
22249  ++state->cursor;
22250  }
22251  nk_textedit_clamp(state);
22252 
22253  state->has_preferred_x = 1;
22254  state->preferred_x = goal_x;
22255  if (sel)
22256  state->select_end = state->cursor;
22257  }
22258  } break;
22259 
22260  case NK_KEY_UP: {
22261  struct nk_text_find find;
22262  struct nk_text_edit_row row;
22263  int i, sel = shift_mod;
22264 
22265  if (state->single_line) {
22266  /* on windows, up&down become left&right */
22267  key = NK_KEY_LEFT;
22268  goto retry;
22269  }
22270 
22271  if (sel)
22272  nk_textedit_prep_selection_at_cursor(state);
22273  else if (NK_TEXT_HAS_SELECTION(state))
22274  nk_textedit_move_to_first(state);
22275 
22276  /* compute current position of cursor point */
22277  nk_textedit_clamp(state);
22278  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22279  font, row_height);
22280 
22281  /* can only go up if there's a previous row */
22282  if (find.prev_first != find.first_char) {
22283  /* now find character position up a row */
22284  float x;
22285  float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
22286 
22287  state->cursor = find.prev_first;
22288  nk_textedit_layout_row(&row, state, state->cursor, row_height, font);
22289  x = row.x0;
22290 
22291  for (i=0; i < row.num_chars && x < row.x1; ++i) {
22292  float dx = nk_textedit_get_width(state, find.prev_first, i, font);
22293  x += dx;
22294  if (x > goal_x)
22295  break;
22296  ++state->cursor;
22297  }
22298  nk_textedit_clamp(state);
22299 
22300  state->has_preferred_x = 1;
22301  state->preferred_x = goal_x;
22302  if (sel) state->select_end = state->cursor;
22303  }
22304  } break;
22305 
22306  case NK_KEY_DEL:
22307  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
22308  break;
22309  if (NK_TEXT_HAS_SELECTION(state))
22311  else {
22312  int n = state->string.len;
22313  if (state->cursor < n)
22314  nk_textedit_delete(state, state->cursor, 1);
22315  }
22316  state->has_preferred_x = 0;
22317  break;
22318 
22319  case NK_KEY_BACKSPACE:
22320  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
22321  break;
22322  if (NK_TEXT_HAS_SELECTION(state))
22324  else {
22325  nk_textedit_clamp(state);
22326  if (state->cursor > 0) {
22327  nk_textedit_delete(state, state->cursor-1, 1);
22328  --state->cursor;
22329  }
22330  }
22331  state->has_preferred_x = 0;
22332  break;
22333 
22334  case NK_KEY_TEXT_START:
22335  if (shift_mod) {
22336  nk_textedit_prep_selection_at_cursor(state);
22337  state->cursor = state->select_end = 0;
22338  state->has_preferred_x = 0;
22339  } else {
22340  state->cursor = state->select_start = state->select_end = 0;
22341  state->has_preferred_x = 0;
22342  }
22343  break;
22344 
22345  case NK_KEY_TEXT_END:
22346  if (shift_mod) {
22347  nk_textedit_prep_selection_at_cursor(state);
22348  state->cursor = state->select_end = state->string.len;
22349  state->has_preferred_x = 0;
22350  } else {
22351  state->cursor = state->string.len;
22352  state->select_start = state->select_end = 0;
22353  state->has_preferred_x = 0;
22354  }
22355  break;
22356 
22357  case NK_KEY_TEXT_LINE_START: {
22358  if (shift_mod) {
22359  struct nk_text_find find;
22360  nk_textedit_clamp(state);
22361  nk_textedit_prep_selection_at_cursor(state);
22362  if (state->string.len && state->cursor == state->string.len)
22363  --state->cursor;
22364  nk_textedit_find_charpos(&find, state,state->cursor, state->single_line,
22365  font, row_height);
22366  state->cursor = state->select_end = find.first_char;
22367  state->has_preferred_x = 0;
22368  } else {
22369  struct nk_text_find find;
22370  if (state->string.len && state->cursor == state->string.len)
22371  --state->cursor;
22372  nk_textedit_clamp(state);
22373  nk_textedit_move_to_first(state);
22374  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22375  font, row_height);
22376  state->cursor = find.first_char;
22377  state->has_preferred_x = 0;
22378  }
22379  } break;
22380 
22381  case NK_KEY_TEXT_LINE_END: {
22382  if (shift_mod) {
22383  struct nk_text_find find;
22384  nk_textedit_clamp(state);
22385  nk_textedit_prep_selection_at_cursor(state);
22386  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22387  font, row_height);
22388  state->has_preferred_x = 0;
22389  state->cursor = find.first_char + find.length;
22390  if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) == '\n')
22391  --state->cursor;
22392  state->select_end = state->cursor;
22393  } else {
22394  struct nk_text_find find;
22395  nk_textedit_clamp(state);
22396  nk_textedit_move_to_first(state);
22397  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22398  font, row_height);
22399 
22400  state->has_preferred_x = 0;
22401  state->cursor = find.first_char + find.length;
22402  if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) == '\n')
22403  --state->cursor;
22404  }} break;
22405  }
22406 }
22407 NK_INTERN void
22408 nk_textedit_flush_redo(struct nk_text_undo_state *state)
22409 {
22412 }
22413 NK_INTERN void
22414 nk_textedit_discard_undo(struct nk_text_undo_state *state)
22415 {
22416  /* discard the oldest entry in the undo list */
22417  if (state->undo_point > 0) {
22418  /* if the 0th undo state has characters, clean those up */
22419  if (state->undo_rec[0].char_storage >= 0) {
22420  int n = state->undo_rec[0].insert_length, i;
22421  /* delete n characters from all other records */
22422  state->undo_char_point = (short)(state->undo_char_point - n);
22423  NK_MEMCPY(state->undo_char, state->undo_char + n,
22424  (nk_size)state->undo_char_point*sizeof(nk_rune));
22425  for (i=0; i < state->undo_point; ++i) {
22426  if (state->undo_rec[i].char_storage >= 0)
22427  state->undo_rec[i].char_storage = (short)
22428  (state->undo_rec[i].char_storage - n);
22429  }
22430  }
22431  --state->undo_point;
22432  NK_MEMCPY(state->undo_rec, state->undo_rec+1,
22433  (nk_size)((nk_size)state->undo_point * sizeof(state->undo_rec[0])));
22434  }
22435 }
22436 NK_INTERN void
22437 nk_textedit_discard_redo(struct nk_text_undo_state *state)
22438 {
22439 /* discard the oldest entry in the redo list--it's bad if this
22440  ever happens, but because undo & redo have to store the actual
22441  characters in different cases, the redo character buffer can
22442  fill up even though the undo buffer didn't */
22443  nk_size num;
22444  int k = NK_TEXTEDIT_UNDOSTATECOUNT-1;
22445  if (state->redo_point <= k) {
22446  /* if the k'th undo state has characters, clean those up */
22447  if (state->undo_rec[k].char_storage >= 0) {
22448  int n = state->undo_rec[k].insert_length, i;
22449  /* delete n characters from all other records */
22450  state->redo_char_point = (short)(state->redo_char_point + n);
22452  NK_MEMCPY(state->undo_char + state->redo_char_point,
22453  state->undo_char + state->redo_char_point-n, num * sizeof(char));
22454  for (i = state->redo_point; i < k; ++i) {
22455  if (state->undo_rec[i].char_storage >= 0) {
22456  state->undo_rec[i].char_storage = (short)
22457  (state->undo_rec[i].char_storage + n);
22458  }
22459  }
22460  }
22461  ++state->redo_point;
22462  num = (nk_size)(NK_TEXTEDIT_UNDOSTATECOUNT - state->redo_point);
22463  if (num) NK_MEMCPY(state->undo_rec + state->redo_point-1,
22464  state->undo_rec + state->redo_point, num * sizeof(state->undo_rec[0]));
22465  }
22466 }
22468 nk_textedit_create_undo_record(struct nk_text_undo_state *state, int numchars)
22469 {
22470  /* any time we create a new undo record, we discard redo*/
22471  nk_textedit_flush_redo(state);
22472 
22473  /* if we have no free records, we have to make room,
22474  * by sliding the existing records down */
22475  if (state->undo_point == NK_TEXTEDIT_UNDOSTATECOUNT)
22476  nk_textedit_discard_undo(state);
22477 
22478  /* if the characters to store won't possibly fit in the buffer,
22479  * we can't undo */
22480  if (numchars > NK_TEXTEDIT_UNDOCHARCOUNT) {
22481  state->undo_point = 0;
22482  state->undo_char_point = 0;
22483  return 0;
22484  }
22485 
22486  /* if we don't have enough free characters in the buffer,
22487  * we have to make room */
22488  while (state->undo_char_point + numchars > NK_TEXTEDIT_UNDOCHARCOUNT)
22489  nk_textedit_discard_undo(state);
22490  return &state->undo_rec[state->undo_point++];
22491 }
22493 nk_textedit_createundo(struct nk_text_undo_state *state, int pos,
22494  int insert_len, int delete_len)
22495 {
22496  struct nk_text_undo_record *r = nk_textedit_create_undo_record(state, insert_len);
22497  if (r == 0)
22498  return 0;
22499 
22500  r->where = pos;
22501  r->insert_length = (short) insert_len;
22502  r->delete_length = (short) delete_len;
22503 
22504  if (insert_len == 0) {
22505  r->char_storage = -1;
22506  return 0;
22507  } else {
22508  r->char_storage = state->undo_char_point;
22509  state->undo_char_point = (short)(state->undo_char_point + insert_len);
22510  return &state->undo_char[r->char_storage];
22511  }
22512 }
22513 NK_API void
22514 nk_textedit_undo(struct nk_text_edit *state)
22515 {
22516  struct nk_text_undo_state *s = &state->undo;
22517  struct nk_text_undo_record u, *r;
22518  if (s->undo_point == 0)
22519  return;
22520 
22521  /* we need to do two things: apply the undo record, and create a redo record */
22522  u = s->undo_rec[s->undo_point-1];
22523  r = &s->undo_rec[s->redo_point-1];
22524  r->char_storage = -1;
22525 
22526  r->insert_length = u.delete_length;
22527  r->delete_length = u.insert_length;
22528  r->where = u.where;
22529 
22530  if (u.delete_length)
22531  {
22532  /* if the undo record says to delete characters, then the redo record will
22533  need to re-insert the characters that get deleted, so we need to store
22534  them.
22535  there are three cases:
22536  - there's enough room to store the characters
22537  - characters stored for *redoing* don't leave room for redo
22538  - characters stored for *undoing* don't leave room for redo
22539  if the last is true, we have to bail */
22540  if (s->undo_char_point + u.delete_length >= NK_TEXTEDIT_UNDOCHARCOUNT) {
22541  /* the undo records take up too much character space; there's no space
22542  * to store the redo characters */
22543  r->insert_length = 0;
22544  } else {
22545  int i;
22546  /* there's definitely room to store the characters eventually */
22547  while (s->undo_char_point + u.delete_length > s->redo_char_point) {
22548  /* there's currently not enough room, so discard a redo record */
22549  nk_textedit_discard_redo(s);
22550  /* should never happen: */
22552  return;
22553  }
22554 
22555  r = &s->undo_rec[s->redo_point-1];
22556  r->char_storage = (short)(s->redo_char_point - u.delete_length);
22557  s->redo_char_point = (short)(s->redo_char_point - u.delete_length);
22558 
22559  /* now save the characters */
22560  for (i=0; i < u.delete_length; ++i)
22561  s->undo_char[r->char_storage + i] =
22562  nk_str_rune_at(&state->string, u.where + i);
22563  }
22564  /* now we can carry out the deletion */
22565  nk_str_delete_runes(&state->string, u.where, u.delete_length);
22566  }
22567 
22568  /* check type of recorded action: */
22569  if (u.insert_length) {
22570  /* easy case: was a deletion, so we need to insert n characters */
22571  nk_str_insert_text_runes(&state->string, u.where,
22572  &s->undo_char[u.char_storage], u.insert_length);
22573  s->undo_char_point = (short)(s->undo_char_point - u.insert_length);
22574  }
22575  state->cursor = (short)(u.where + u.insert_length);
22576 
22577  s->undo_point--;
22578  s->redo_point--;
22579 }
22580 NK_API void
22581 nk_textedit_redo(struct nk_text_edit *state)
22582 {
22583  struct nk_text_undo_state *s = &state->undo;
22584  struct nk_text_undo_record *u, r;
22586  return;
22587 
22588  /* we need to do two things: apply the redo record, and create an undo record */
22589  u = &s->undo_rec[s->undo_point];
22590  r = s->undo_rec[s->redo_point];
22591 
22592  /* we KNOW there must be room for the undo record, because the redo record
22593  was derived from an undo record */
22596  u->where = r.where;
22597  u->char_storage = -1;
22598 
22599  if (r.delete_length) {
22600  /* the redo record requires us to delete characters, so the undo record
22601  needs to store the characters */
22602  if (s->undo_char_point + u->insert_length > s->redo_char_point) {
22603  u->insert_length = 0;
22604  u->delete_length = 0;
22605  } else {
22606  int i;
22607  u->char_storage = s->undo_char_point;
22608  s->undo_char_point = (short)(s->undo_char_point + u->insert_length);
22609 
22610  /* now save the characters */
22611  for (i=0; i < u->insert_length; ++i) {
22612  s->undo_char[u->char_storage + i] =
22613  nk_str_rune_at(&state->string, u->where + i);
22614  }
22615  }
22617  }
22618 
22619  if (r.insert_length) {
22620  /* easy case: need to insert n characters */
22623  }
22624  state->cursor = r.where + r.insert_length;
22625 
22626  s->undo_point++;
22627  s->redo_point++;
22628 }
22629 NK_INTERN void
22630 nk_textedit_makeundo_insert(struct nk_text_edit *state, int where, int length)
22631 {
22632  nk_textedit_createundo(&state->undo, where, 0, length);
22633 }
22634 NK_INTERN void
22635 nk_textedit_makeundo_delete(struct nk_text_edit *state, int where, int length)
22636 {
22637  int i;
22638  nk_rune *p = nk_textedit_createundo(&state->undo, where, length, 0);
22639  if (p) {
22640  for (i=0; i < length; ++i)
22641  p[i] = nk_str_rune_at(&state->string, where+i);
22642  }
22643 }
22644 NK_INTERN void
22645 nk_textedit_makeundo_replace(struct nk_text_edit *state, int where,
22646  int old_length, int new_length)
22647 {
22648  int i;
22649  nk_rune *p = nk_textedit_createundo(&state->undo, where, old_length, new_length);
22650  if (p) {
22651  for (i=0; i < old_length; ++i)
22652  p[i] = nk_str_rune_at(&state->string, where+i);
22653  }
22654 }
22655 NK_LIB void
22656 nk_textedit_clear_state(struct nk_text_edit *state, enum nk_text_edit_type type,
22657  nk_plugin_filter filter)
22658 {
22659  /* reset the state to default */
22660  state->undo.undo_point = 0;
22661  state->undo.undo_char_point = 0;
22664  state->select_end = state->select_start = 0;
22665  state->cursor = 0;
22666  state->has_preferred_x = 0;
22667  state->preferred_x = 0;
22668  state->cursor_at_end_of_line = 0;
22669  state->initialized = 1;
22670  state->single_line = (unsigned char)(type == NK_TEXT_EDIT_SINGLE_LINE);
22671  state->mode = NK_TEXT_EDIT_MODE_VIEW;
22672  state->filter = filter;
22673  state->scrollbar = nk_vec2(0,0);
22674 }
22675 NK_API void
22676 nk_textedit_init_fixed(struct nk_text_edit *state, void *memory, nk_size size)
22677 {
22678  NK_ASSERT(state);
22679  NK_ASSERT(memory);
22680  if (!state || !memory || !size) return;
22681  NK_MEMSET(state, 0, sizeof(struct nk_text_edit));
22682  nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
22683  nk_str_init_fixed(&state->string, memory, size);
22684 }
22685 NK_API void
22686 nk_textedit_init(struct nk_text_edit *state, struct nk_allocator *alloc, nk_size size)
22687 {
22688  NK_ASSERT(state);
22689  NK_ASSERT(alloc);
22690  if (!state || !alloc) return;
22691  NK_MEMSET(state, 0, sizeof(struct nk_text_edit));
22692  nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
22693  nk_str_init(&state->string, alloc, size);
22694 }
22695 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
22696 NK_API void
22697 nk_textedit_init_default(struct nk_text_edit *state)
22698 {
22699  NK_ASSERT(state);
22700  if (!state) return;
22701  NK_MEMSET(state, 0, sizeof(struct nk_text_edit));
22702  nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
22703  nk_str_init_default(&state->string);
22704 }
22705 #endif
22706 NK_API void
22707 nk_textedit_select_all(struct nk_text_edit *state)
22708 {
22709  NK_ASSERT(state);
22710  state->select_start = 0;
22711  state->select_end = state->string.len;
22712 }
22713 NK_API void
22714 nk_textedit_free(struct nk_text_edit *state)
22715 {
22716  NK_ASSERT(state);
22717  if (!state) return;
22718  nk_str_free(&state->string);
22719 }
22720 
22721 
22722 
22723 
22724 
22725 /* ===============================================================
22726  *
22727  * FILTER
22728  *
22729  * ===============================================================*/
22730 NK_API int
22731 nk_filter_default(const struct nk_text_edit *box, nk_rune unicode)
22732 {
22733  NK_UNUSED(unicode);
22734  NK_UNUSED(box);
22735  return nk_true;
22736 }
22737 NK_API int
22738 nk_filter_ascii(const struct nk_text_edit *box, nk_rune unicode)
22739 {
22740  NK_UNUSED(box);
22741  if (unicode > 128) return nk_false;
22742  else return nk_true;
22743 }
22744 NK_API int
22745 nk_filter_float(const struct nk_text_edit *box, nk_rune unicode)
22746 {
22747  NK_UNUSED(box);
22748  if ((unicode < '0' || unicode > '9') && unicode != '.' && unicode != '-')
22749  return nk_false;
22750  else return nk_true;
22751 }
22752 NK_API int
22753 nk_filter_decimal(const struct nk_text_edit *box, nk_rune unicode)
22754 {
22755  NK_UNUSED(box);
22756  if ((unicode < '0' || unicode > '9') && unicode != '-')
22757  return nk_false;
22758  else return nk_true;
22759 }
22760 NK_API int
22761 nk_filter_hex(const struct nk_text_edit *box, nk_rune unicode)
22762 {
22763  NK_UNUSED(box);
22764  if ((unicode < '0' || unicode > '9') &&
22765  (unicode < 'a' || unicode > 'f') &&
22766  (unicode < 'A' || unicode > 'F'))
22767  return nk_false;
22768  else return nk_true;
22769 }
22770 NK_API int
22771 nk_filter_oct(const struct nk_text_edit *box, nk_rune unicode)
22772 {
22773  NK_UNUSED(box);
22774  if (unicode < '0' || unicode > '7')
22775  return nk_false;
22776  else return nk_true;
22777 }
22778 NK_API int
22779 nk_filter_binary(const struct nk_text_edit *box, nk_rune unicode)
22780 {
22781  NK_UNUSED(box);
22782  if (unicode != '0' && unicode != '1')
22783  return nk_false;
22784  else return nk_true;
22785 }
22786 
22787 /* ===============================================================
22788  *
22789  * EDIT
22790  *
22791  * ===============================================================*/
22792 NK_LIB void
22793 nk_edit_draw_text(struct nk_command_buffer *out,
22794  const struct nk_style_edit *style, float pos_x, float pos_y,
22795  float x_offset, const char *text, int byte_len, float row_height,
22796  const struct nk_user_font *font, struct nk_color background,
22797  struct nk_color foreground, int is_selected)
22798 {
22799  NK_ASSERT(out);
22800  NK_ASSERT(font);
22801  NK_ASSERT(style);
22802  if (!text || !byte_len || !out || !style) return;
22803 
22804  {int glyph_len = 0;
22805  nk_rune unicode = 0;
22806  int text_len = 0;
22807  float line_width = 0;
22808  float glyph_width;
22809  const char *line = text;
22810  float line_offset = 0;
22811  int line_count = 0;
22812 
22813  struct nk_text txt;
22814  txt.padding = nk_vec2(0,0);
22815  txt.background = background;
22816  txt.text = foreground;
22817 
22818  glyph_len = nk_utf_decode(text+text_len, &unicode, byte_len-text_len);
22819  if (!glyph_len) return;
22820  while ((text_len < byte_len) && glyph_len)
22821  {
22822  if (unicode == '\n') {
22823  /* new line separator so draw previous line */
22824  struct nk_rect label;
22825  label.y = pos_y + line_offset;
22826  label.h = row_height;
22827  label.w = line_width;
22828  label.x = pos_x;
22829  if (!line_count)
22830  label.x += x_offset;
22831 
22832  if (is_selected) /* selection needs to draw different background color */
22833  nk_fill_rect(out, label, 0, background);
22834  nk_widget_text(out, label, line, (int)((text + text_len) - line),
22835  &txt, NK_TEXT_CENTERED, font);
22836 
22837  text_len++;
22838  line_count++;
22839  line_width = 0;
22840  line = text + text_len;
22841  line_offset += row_height;
22842  glyph_len = nk_utf_decode(text + text_len, &unicode, (int)(byte_len-text_len));
22843  continue;
22844  }
22845  if (unicode == '\r') {
22846  text_len++;
22847  glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
22848  continue;
22849  }
22850  glyph_width = font->width(font->userdata, font->height, text+text_len, glyph_len);
22851  line_width += (float)glyph_width;
22852  text_len += glyph_len;
22853  glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
22854  continue;
22855  }
22856  if (line_width > 0) {
22857  /* draw last line */
22858  struct nk_rect label;
22859  label.y = pos_y + line_offset;
22860  label.h = row_height;
22861  label.w = line_width;
22862  label.x = pos_x;
22863  if (!line_count)
22864  label.x += x_offset;
22865 
22866  if (is_selected)
22867  nk_fill_rect(out, label, 0, background);
22868  nk_widget_text(out, label, line, (int)((text + text_len) - line),
22869  &txt, NK_TEXT_LEFT, font);
22870  }}
22871 }
22873 nk_do_edit(nk_flags *state, struct nk_command_buffer *out,
22874  struct nk_rect bounds, nk_flags flags, nk_plugin_filter filter,
22875  struct nk_text_edit *edit, const struct nk_style_edit *style,
22876  struct nk_input *in, const struct nk_user_font *font)
22877 {
22878  struct nk_rect area;
22879  nk_flags ret = 0;
22880  float row_height;
22881  char prev_state = 0;
22882  char is_hovered = 0;
22883  char select_all = 0;
22884  char cursor_follow = 0;
22885  struct nk_rect old_clip;
22886  struct nk_rect clip;
22887 
22888  NK_ASSERT(state);
22889  NK_ASSERT(out);
22890  NK_ASSERT(style);
22891  if (!state || !out || !style)
22892  return ret;
22893 
22894  /* visible text area calculation */
22895  area.x = bounds.x + style->padding.x + style->border;
22896  area.y = bounds.y + style->padding.y + style->border;
22897  area.w = bounds.w - (2.0f * style->padding.x + 2 * style->border);
22898  area.h = bounds.h - (2.0f * style->padding.y + 2 * style->border);
22899  if (flags & NK_EDIT_MULTILINE)
22900  area.w = NK_MAX(0, area.w - style->scrollbar_size.x);
22901  row_height = (flags & NK_EDIT_MULTILINE)? font->height + style->row_padding: area.h;
22902 
22903  /* calculate clipping rectangle */
22904  old_clip = out->clip;
22905  nk_unify(&clip, &old_clip, area.x, area.y, area.x + area.w, area.y + area.h);
22906 
22907  /* update edit state */
22908  prev_state = (char)edit->active;
22909  is_hovered = (char)nk_input_is_mouse_hovering_rect(in, bounds);
22911  edit->active = NK_INBOX(in->mouse.pos.x, in->mouse.pos.y,
22912  bounds.x, bounds.y, bounds.w, bounds.h);
22913  }
22914 
22915  /* (de)activate text editor */
22916  if (!prev_state && edit->active) {
22917  const enum nk_text_edit_type type = (flags & NK_EDIT_MULTILINE) ?
22919  nk_textedit_clear_state(edit, type, filter);
22920  if (flags & NK_EDIT_AUTO_SELECT)
22921  select_all = nk_true;
22922  if (flags & NK_EDIT_GOTO_END_ON_ACTIVATE) {
22923  edit->cursor = edit->string.len;
22924  in = 0;
22925  }
22926  } else if (!edit->active) edit->mode = NK_TEXT_EDIT_MODE_VIEW;
22927  if (flags & NK_EDIT_READ_ONLY)
22928  edit->mode = NK_TEXT_EDIT_MODE_VIEW;
22929  else if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
22931 
22932  ret = (edit->active) ? NK_EDIT_ACTIVE: NK_EDIT_INACTIVE;
22933  if (prev_state != edit->active)
22934  ret |= (edit->active) ? NK_EDIT_ACTIVATED: NK_EDIT_DEACTIVATED;
22935 
22936  /* handle user input */
22937  if (edit->active && in)
22938  {
22939  int shift_mod = in->keyboard.keys[NK_KEY_SHIFT].down;
22940  const float mouse_x = (in->mouse.pos.x - area.x) + edit->scrollbar.x;
22941  const float mouse_y = (in->mouse.pos.y - area.y) + edit->scrollbar.y;
22942 
22943  /* mouse click handler */
22944  is_hovered = (char)nk_input_is_mouse_hovering_rect(in, area);
22945  if (select_all) {
22946  nk_textedit_select_all(edit);
22947  } else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
22949  nk_textedit_click(edit, mouse_x, mouse_y, font, row_height);
22950  } else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
22951  (in->mouse.delta.x != 0.0f || in->mouse.delta.y != 0.0f)) {
22952  nk_textedit_drag(edit, mouse_x, mouse_y, font, row_height);
22953  cursor_follow = nk_true;
22954  } else if (is_hovered && in->mouse.buttons[NK_BUTTON_RIGHT].clicked &&
22956  nk_textedit_key(edit, NK_KEY_TEXT_WORD_LEFT, nk_false, font, row_height);
22957  nk_textedit_key(edit, NK_KEY_TEXT_WORD_RIGHT, nk_true, font, row_height);
22958  cursor_follow = nk_true;
22959  }
22960 
22961  {int i; /* keyboard input */
22962  int old_mode = edit->mode;
22963  for (i = 0; i < NK_KEY_MAX; ++i) {
22964  if (i == NK_KEY_ENTER || i == NK_KEY_TAB) continue; /* special case */
22965  if (nk_input_is_key_pressed(in, (enum nk_keys)i)) {
22966  nk_textedit_key(edit, (enum nk_keys)i, shift_mod, font, row_height);
22967  cursor_follow = nk_true;
22968  }
22969  }
22970  if (old_mode != edit->mode) {
22971  in->keyboard.text_len = 0;
22972  }}
22973 
22974  /* text input */
22975  edit->filter = filter;
22976  if (in->keyboard.text_len) {
22978  cursor_follow = nk_true;
22979  in->keyboard.text_len = 0;
22980  }
22981 
22982  /* enter key handler */
22984  cursor_follow = nk_true;
22985  if (flags & NK_EDIT_CTRL_ENTER_NEWLINE && shift_mod)
22986  nk_textedit_text(edit, "\n", 1);
22987  else if (flags & NK_EDIT_SIG_ENTER)
22988  ret |= NK_EDIT_COMMITED;
22989  else nk_textedit_text(edit, "\n", 1);
22990  }
22991 
22992  /* cut & copy handler */
22993  {int copy= nk_input_is_key_pressed(in, NK_KEY_COPY);
22994  int cut = nk_input_is_key_pressed(in, NK_KEY_CUT);
22995  if ((copy || cut) && (flags & NK_EDIT_CLIPBOARD))
22996  {
22997  int glyph_len;
22998  nk_rune unicode;
22999  const char *text;
23000  int b = edit->select_start;
23001  int e = edit->select_end;
23002 
23003  int begin = NK_MIN(b, e);
23004  int end = NK_MAX(b, e);
23005  text = nk_str_at_const(&edit->string, begin, &unicode, &glyph_len);
23006  if (edit->clip.copy)
23007  edit->clip.copy(edit->clip.userdata, text, end - begin);
23008  if (cut && !(flags & NK_EDIT_READ_ONLY)){
23009  nk_textedit_cut(edit);
23010  cursor_follow = nk_true;
23011  }
23012  }}
23013 
23014  /* paste handler */
23015  {int paste = nk_input_is_key_pressed(in, NK_KEY_PASTE);
23016  if (paste && (flags & NK_EDIT_CLIPBOARD) && edit->clip.paste) {
23017  edit->clip.paste(edit->clip.userdata, edit);
23018  cursor_follow = nk_true;
23019  }}
23020 
23021  /* tab handler */
23022  {int tab = nk_input_is_key_pressed(in, NK_KEY_TAB);
23023  if (tab && (flags & NK_EDIT_ALLOW_TAB)) {
23024  nk_textedit_text(edit, " ", 4);
23025  cursor_follow = nk_true;
23026  }}
23027  }
23028 
23029  /* set widget state */
23030  if (edit->active)
23031  *state = NK_WIDGET_STATE_ACTIVE;
23032  else nk_widget_state_reset(state);
23033 
23034  if (is_hovered)
23035  *state |= NK_WIDGET_STATE_HOVERED;
23036 
23037  /* DRAW EDIT */
23038  {const char *text = nk_str_get_const(&edit->string);
23039  int len = nk_str_len_char(&edit->string);
23040 
23041  {/* select background colors/images */
23042  const struct nk_style_item *background;
23043  if (*state & NK_WIDGET_STATE_ACTIVED)
23044  background = &style->active;
23045  else if (*state & NK_WIDGET_STATE_HOVER)
23046  background = &style->hover;
23047  else background = &style->normal;
23048 
23049  /* draw background frame */
23050  if (background->type == NK_STYLE_ITEM_COLOR) {
23051  nk_stroke_rect(out, bounds, style->rounding, style->border, style->border_color);
23052  nk_fill_rect(out, bounds, style->rounding, background->data.color);
23053  } else nk_draw_image(out, bounds, &background->data.image, nk_white);}
23054 
23055  area.w = NK_MAX(0, area.w - style->cursor_size);
23056  if (edit->active)
23057  {
23058  int total_lines = 1;
23059  struct nk_vec2 text_size = nk_vec2(0,0);
23060 
23061  /* text pointer positions */
23062  const char *cursor_ptr = 0;
23063  const char *select_begin_ptr = 0;
23064  const char *select_end_ptr = 0;
23065 
23066  /* 2D pixel positions */
23067  struct nk_vec2 cursor_pos = nk_vec2(0,0);
23068  struct nk_vec2 selection_offset_start = nk_vec2(0,0);
23069  struct nk_vec2 selection_offset_end = nk_vec2(0,0);
23070 
23071  int selection_begin = NK_MIN(edit->select_start, edit->select_end);
23072  int selection_end = NK_MAX(edit->select_start, edit->select_end);
23073 
23074  /* calculate total line count + total space + cursor/selection position */
23075  float line_width = 0.0f;
23076  if (text && len)
23077  {
23078  /* utf8 encoding */
23079  float glyph_width;
23080  int glyph_len = 0;
23081  nk_rune unicode = 0;
23082  int text_len = 0;
23083  int glyphs = 0;
23084  int row_begin = 0;
23085 
23086  glyph_len = nk_utf_decode(text, &unicode, len);
23087  glyph_width = font->width(font->userdata, font->height, text, glyph_len);
23088  line_width = 0;
23089 
23090  /* iterate all lines */
23091  while ((text_len < len) && glyph_len)
23092  {
23093  /* set cursor 2D position and line */
23094  if (!cursor_ptr && glyphs == edit->cursor)
23095  {
23096  int glyph_offset;
23097  struct nk_vec2 out_offset;
23098  struct nk_vec2 row_size;
23099  const char *remaining;
23100 
23101  /* calculate 2d position */
23102  cursor_pos.y = (float)(total_lines-1) * row_height;
23103  row_size = nk_text_calculate_text_bounds(font, text+row_begin,
23104  text_len-row_begin, row_height, &remaining,
23105  &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
23106  cursor_pos.x = row_size.x;
23107  cursor_ptr = text + text_len;
23108  }
23109 
23110  /* set start selection 2D position and line */
23111  if (!select_begin_ptr && edit->select_start != edit->select_end &&
23112  glyphs == selection_begin)
23113  {
23114  int glyph_offset;
23115  struct nk_vec2 out_offset;
23116  struct nk_vec2 row_size;
23117  const char *remaining;
23118 
23119  /* calculate 2d position */
23120  selection_offset_start.y = (float)(NK_MAX(total_lines-1,0)) * row_height;
23121  row_size = nk_text_calculate_text_bounds(font, text+row_begin,
23122  text_len-row_begin, row_height, &remaining,
23123  &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
23124  selection_offset_start.x = row_size.x;
23125  select_begin_ptr = text + text_len;
23126  }
23127 
23128  /* set end selection 2D position and line */
23129  if (!select_end_ptr && edit->select_start != edit->select_end &&
23130  glyphs == selection_end)
23131  {
23132  int glyph_offset;
23133  struct nk_vec2 out_offset;
23134  struct nk_vec2 row_size;
23135  const char *remaining;
23136 
23137  /* calculate 2d position */
23138  selection_offset_end.y = (float)(total_lines-1) * row_height;
23139  row_size = nk_text_calculate_text_bounds(font, text+row_begin,
23140  text_len-row_begin, row_height, &remaining,
23141  &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
23142  selection_offset_end.x = row_size.x;
23143  select_end_ptr = text + text_len;
23144  }
23145  if (unicode == '\n') {
23146  text_size.x = NK_MAX(text_size.x, line_width);
23147  total_lines++;
23148  line_width = 0;
23149  text_len++;
23150  glyphs++;
23151  row_begin = text_len;
23152  glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
23153  glyph_width = font->width(font->userdata, font->height, text+text_len, glyph_len);
23154  continue;
23155  }
23156 
23157  glyphs++;
23158  text_len += glyph_len;
23159  line_width += (float)glyph_width;
23160 
23161  glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
23162  glyph_width = font->width(font->userdata, font->height,
23163  text+text_len, glyph_len);
23164  continue;
23165  }
23166  text_size.y = (float)total_lines * row_height;
23167 
23168  /* handle case when cursor is at end of text buffer */
23169  if (!cursor_ptr && edit->cursor == edit->string.len) {
23170  cursor_pos.x = line_width;
23171  cursor_pos.y = text_size.y - row_height;
23172  }
23173  }
23174  {
23175  /* scrollbar */
23176  if (cursor_follow)
23177  {
23178  /* update scrollbar to follow cursor */
23179  if (!(flags & NK_EDIT_NO_HORIZONTAL_SCROLL)) {
23180  /* horizontal scroll */
23181  const float scroll_increment = area.w * 0.25f;
23182  if (cursor_pos.x < edit->scrollbar.x)
23183  edit->scrollbar.x = (float)(int)NK_MAX(0.0f, cursor_pos.x - scroll_increment);
23184  if (cursor_pos.x >= edit->scrollbar.x + area.w)
23185  edit->scrollbar.x = (float)(int)NK_MAX(0.0f, edit->scrollbar.x + scroll_increment);
23186  } else edit->scrollbar.x = 0;
23187 
23188  if (flags & NK_EDIT_MULTILINE) {
23189  /* vertical scroll */
23190  if (cursor_pos.y < edit->scrollbar.y)
23191  edit->scrollbar.y = NK_MAX(0.0f, cursor_pos.y - row_height);
23192  if (cursor_pos.y >= edit->scrollbar.y + area.h)
23193  edit->scrollbar.y = edit->scrollbar.y + row_height;
23194  } else edit->scrollbar.y = 0;
23195  }
23196 
23197  /* scrollbar widget */
23198  if (flags & NK_EDIT_MULTILINE)
23199  {
23200  nk_flags ws;
23201  struct nk_rect scroll;
23202  float scroll_target;
23203  float scroll_offset;
23204  float scroll_step;
23205  float scroll_inc;
23206 
23207  scroll = area;
23208  scroll.x = (bounds.x + bounds.w - style->border) - style->scrollbar_size.x;
23209  scroll.w = style->scrollbar_size.x;
23210 
23211  scroll_offset = edit->scrollbar.y;
23212  scroll_step = scroll.h * 0.10f;
23213  scroll_inc = scroll.h * 0.01f;
23214  scroll_target = text_size.y;
23215  edit->scrollbar.y = nk_do_scrollbarv(&ws, out, scroll, 0,
23216  scroll_offset, scroll_target, scroll_step, scroll_inc,
23217  &style->scrollbar, in, font);
23218  }
23219  }
23220 
23221  /* draw text */
23222  {struct nk_color background_color;
23223  struct nk_color text_color;
23224  struct nk_color sel_background_color;
23225  struct nk_color sel_text_color;
23226  struct nk_color cursor_color;
23227  struct nk_color cursor_text_color;
23228  const struct nk_style_item *background;
23229  nk_push_scissor(out, clip);
23230 
23231  /* select correct colors to draw */
23232  if (*state & NK_WIDGET_STATE_ACTIVED) {
23233  background = &style->active;
23234  text_color = style->text_active;
23235  sel_text_color = style->selected_text_hover;
23236  sel_background_color = style->selected_hover;
23237  cursor_color = style->cursor_hover;
23238  cursor_text_color = style->cursor_text_hover;
23239  } else if (*state & NK_WIDGET_STATE_HOVER) {
23240  background = &style->hover;
23241  text_color = style->text_hover;
23242  sel_text_color = style->selected_text_hover;
23243  sel_background_color = style->selected_hover;
23244  cursor_text_color = style->cursor_text_hover;
23245  cursor_color = style->cursor_hover;
23246  } else {
23247  background = &style->normal;
23248  text_color = style->text_normal;
23249  sel_text_color = style->selected_text_normal;
23250  sel_background_color = style->selected_normal;
23251  cursor_color = style->cursor_normal;
23252  cursor_text_color = style->cursor_text_normal;
23253  }
23254  if (background->type == NK_STYLE_ITEM_IMAGE)
23255  background_color = nk_rgba(0,0,0,0);
23256  else background_color = background->data.color;
23257 
23258 
23259  if (edit->select_start == edit->select_end) {
23260  /* no selection so just draw the complete text */
23261  const char *begin = nk_str_get_const(&edit->string);
23262  int l = nk_str_len_char(&edit->string);
23263  nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
23264  area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
23265  background_color, text_color, nk_false);
23266  } else {
23267  /* edit has selection so draw 1-3 text chunks */
23268  if (edit->select_start != edit->select_end && selection_begin > 0){
23269  /* draw unselected text before selection */
23270  const char *begin = nk_str_get_const(&edit->string);
23271  NK_ASSERT(select_begin_ptr);
23272  nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
23273  area.y - edit->scrollbar.y, 0, begin, (int)(select_begin_ptr - begin),
23274  row_height, font, background_color, text_color, nk_false);
23275  }
23276  if (edit->select_start != edit->select_end) {
23277  /* draw selected text */
23278  NK_ASSERT(select_begin_ptr);
23279  if (!select_end_ptr) {
23280  const char *begin = nk_str_get_const(&edit->string);
23281  select_end_ptr = begin + nk_str_len_char(&edit->string);
23282  }
23283  nk_edit_draw_text(out, style,
23284  area.x - edit->scrollbar.x,
23285  area.y + selection_offset_start.y - edit->scrollbar.y,
23286  selection_offset_start.x,
23287  select_begin_ptr, (int)(select_end_ptr - select_begin_ptr),
23288  row_height, font, sel_background_color, sel_text_color, nk_true);
23289  }
23290  if ((edit->select_start != edit->select_end &&
23291  selection_end < edit->string.len))
23292  {
23293  /* draw unselected text after selected text */
23294  const char *begin = select_end_ptr;
23295  const char *end = nk_str_get_const(&edit->string) +
23296  nk_str_len_char(&edit->string);
23297  NK_ASSERT(select_end_ptr);
23298  nk_edit_draw_text(out, style,
23299  area.x - edit->scrollbar.x,
23300  area.y + selection_offset_end.y - edit->scrollbar.y,
23301  selection_offset_end.x,
23302  begin, (int)(end - begin), row_height, font,
23303  background_color, text_color, nk_true);
23304  }
23305  }
23306 
23307  /* cursor */
23308  if (edit->select_start == edit->select_end)
23309  {
23310  if (edit->cursor >= nk_str_len(&edit->string) ||
23311  (cursor_ptr && *cursor_ptr == '\n')) {
23312  /* draw cursor at end of line */
23313  struct nk_rect cursor;
23314  cursor.w = style->cursor_size;
23315  cursor.h = font->height;
23316  cursor.x = area.x + cursor_pos.x - edit->scrollbar.x;
23317  cursor.y = area.y + cursor_pos.y + row_height/2.0f - cursor.h/2.0f;
23318  cursor.y -= edit->scrollbar.y;
23319  nk_fill_rect(out, cursor, 0, cursor_color);
23320  } else {
23321  /* draw cursor inside text */
23322  int glyph_len;
23323  struct nk_rect label;
23324  struct nk_text txt;
23325 
23326  nk_rune unicode;
23327  NK_ASSERT(cursor_ptr);
23328  glyph_len = nk_utf_decode(cursor_ptr, &unicode, 4);
23329 
23330  label.x = area.x + cursor_pos.x - edit->scrollbar.x;
23331  label.y = area.y + cursor_pos.y - edit->scrollbar.y;
23332  label.w = font->width(font->userdata, font->height, cursor_ptr, glyph_len);
23333  label.h = row_height;
23334 
23335  txt.padding = nk_vec2(0,0);
23336  txt.background = cursor_color;;
23337  txt.text = cursor_text_color;
23338  nk_fill_rect(out, label, 0, cursor_color);
23339  nk_widget_text(out, label, cursor_ptr, glyph_len, &txt, NK_TEXT_LEFT, font);
23340  }
23341  }}
23342  } else {
23343  /* not active so just draw text */
23344  int l = nk_str_len_char(&edit->string);
23345  const char *begin = nk_str_get_const(&edit->string);
23346 
23347  const struct nk_style_item *background;
23348  struct nk_color background_color;
23349  struct nk_color text_color;
23350  nk_push_scissor(out, clip);
23351  if (*state & NK_WIDGET_STATE_ACTIVED) {
23352  background = &style->active;
23353  text_color = style->text_active;
23354  } else if (*state & NK_WIDGET_STATE_HOVER) {
23355  background = &style->hover;
23356  text_color = style->text_hover;
23357  } else {
23358  background = &style->normal;
23359  text_color = style->text_normal;
23360  }
23361  if (background->type == NK_STYLE_ITEM_IMAGE)
23362  background_color = nk_rgba(0,0,0,0);
23363  else background_color = background->data.color;
23364  nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
23365  area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
23366  background_color, text_color, nk_false);
23367  }
23368  nk_push_scissor(out, old_clip);}
23369  return ret;
23370 }
23371 NK_API void
23372 nk_edit_focus(struct nk_context *ctx, nk_flags flags)
23373 {
23374  nk_hash hash;
23375  struct nk_window *win;
23376 
23377  NK_ASSERT(ctx);
23378  NK_ASSERT(ctx->current);
23379  if (!ctx || !ctx->current) return;
23380 
23381  win = ctx->current;
23382  hash = win->edit.seq;
23383  win->edit.active = nk_true;
23384  win->edit.name = hash;
23387 }
23388 NK_API void
23389 nk_edit_unfocus(struct nk_context *ctx)
23390 {
23391  struct nk_window *win;
23392  NK_ASSERT(ctx);
23393  NK_ASSERT(ctx->current);
23394  if (!ctx || !ctx->current) return;
23395 
23396  win = ctx->current;
23397  win->edit.active = nk_false;
23398  win->edit.name = 0;
23399 }
23402  char *memory, int *len, int max, nk_plugin_filter filter)
23403 {
23404  nk_hash hash;
23405  nk_flags state;
23406  struct nk_text_edit *edit;
23407  struct nk_window *win;
23408 
23409  NK_ASSERT(ctx);
23410  NK_ASSERT(memory);
23411  NK_ASSERT(len);
23412  if (!ctx || !memory || !len)
23413  return 0;
23414 
23415  filter = (!filter) ? nk_filter_default: filter;
23416  win = ctx->current;
23417  hash = win->edit.seq;
23418  edit = &ctx->text_edit;
23419  nk_textedit_clear_state(&ctx->text_edit, (flags & NK_EDIT_MULTILINE)?
23421 
23422  if (win->edit.active && hash == win->edit.name) {
23423  if (flags & NK_EDIT_NO_CURSOR)
23424  edit->cursor = nk_utf_len(memory, *len);
23425  else edit->cursor = win->edit.cursor;
23426  if (!(flags & NK_EDIT_SELECTABLE)) {
23427  edit->select_start = win->edit.cursor;
23428  edit->select_end = win->edit.cursor;
23429  } else {
23430  edit->select_start = win->edit.sel_start;
23431  edit->select_end = win->edit.sel_end;
23432  }
23433  edit->mode = win->edit.mode;
23434  edit->scrollbar.x = (float)win->edit.scrollbar.x;
23435  edit->scrollbar.y = (float)win->edit.scrollbar.y;
23436  edit->active = nk_true;
23437  } else edit->active = nk_false;
23438 
23439  max = NK_MAX(1, max);
23440  *len = NK_MIN(*len, max-1);
23441  nk_str_init_fixed(&edit->string, memory, (nk_size)max);
23442  edit->string.buffer.allocated = (nk_size)*len;
23443  edit->string.len = nk_utf_len(memory, *len);
23444  state = nk_edit_buffer(ctx, flags, edit, filter);
23445  *len = (int)edit->string.buffer.allocated;
23446 
23447  if (edit->active) {
23448  win->edit.cursor = edit->cursor;
23449  win->edit.sel_start = edit->select_start;
23450  win->edit.sel_end = edit->select_end;
23451  win->edit.mode = edit->mode;
23454  } return state;
23455 }
23458  struct nk_text_edit *edit, nk_plugin_filter filter)
23459 {
23460  struct nk_window *win;
23461  struct nk_style *style;
23462  struct nk_input *in;
23463 
23464  enum nk_widget_layout_states state;
23465  struct nk_rect bounds;
23466 
23467  nk_flags ret_flags = 0;
23468  unsigned char prev_state;
23469  nk_hash hash;
23470 
23471  /* make sure correct values */
23472  NK_ASSERT(ctx);
23473  NK_ASSERT(edit);
23474  NK_ASSERT(ctx->current);
23475  NK_ASSERT(ctx->current->layout);
23476  if (!ctx || !ctx->current || !ctx->current->layout)
23477  return 0;
23478 
23479  win = ctx->current;
23480  style = &ctx->style;
23481  state = nk_widget(&bounds, ctx);
23482  if (!state) return state;
23483  in = (win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
23484 
23485  /* check if edit is currently hot item */
23486  hash = win->edit.seq++;
23487  if (win->edit.active && hash == win->edit.name) {
23488  if (flags & NK_EDIT_NO_CURSOR)
23489  edit->cursor = edit->string.len;
23490  if (!(flags & NK_EDIT_SELECTABLE)) {
23491  edit->select_start = edit->cursor;
23492  edit->select_end = edit->cursor;
23493  }
23494  if (flags & NK_EDIT_CLIPBOARD)
23495  edit->clip = ctx->clip;
23496  edit->active = (unsigned char)win->edit.active;
23497  } else edit->active = nk_false;
23498  edit->mode = win->edit.mode;
23499 
23500  filter = (!filter) ? nk_filter_default: filter;
23501  prev_state = (unsigned char)edit->active;
23502  in = (flags & NK_EDIT_READ_ONLY) ? 0: in;
23503  ret_flags = nk_do_edit(&ctx->last_widget_state, &win->buffer, bounds, flags,
23504  filter, edit, &style->edit, in, style->font);
23505 
23508  if (edit->active && prev_state != edit->active) {
23509  /* current edit is now hot */
23510  win->edit.active = nk_true;
23511  win->edit.name = hash;
23512  } else if (prev_state && !edit->active) {
23513  /* current edit is now cold */
23514  win->edit.active = nk_false;
23515  } return ret_flags;
23516 }
23519  char *buffer, int max, nk_plugin_filter filter)
23520 {
23521  nk_flags result;
23522  int len = nk_strlen(buffer);
23523  result = nk_edit_string(ctx, flags, buffer, &len, max, filter);
23524  buffer[NK_MIN(NK_MAX(max-1,0), len)] = '\0';
23525  return result;
23526 }
23527 
23528 
23529 
23530 
23531 
23532 /* ===============================================================
23533  *
23534  * PROPERTY
23535  *
23536  * ===============================================================*/
23537 NK_LIB void
23538 nk_drag_behavior(nk_flags *state, const struct nk_input *in,
23539  struct nk_rect drag, struct nk_property_variant *variant,
23540  float inc_per_pixel)
23541 {
23542  int left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
23543  int left_mouse_click_in_cursor = in &&
23545 
23546  nk_widget_state_reset(state);
23547  if (nk_input_is_mouse_hovering_rect(in, drag))
23548  *state = NK_WIDGET_STATE_HOVERED;
23549 
23550  if (left_mouse_down && left_mouse_click_in_cursor) {
23551  float delta, pixels;
23552  pixels = in->mouse.delta.x;
23553  delta = pixels * inc_per_pixel;
23554  switch (variant->kind) {
23555  default: break;
23556  case NK_PROPERTY_INT:
23557  variant->value.i = variant->value.i + (int)delta;
23558  variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
23559  break;
23560  case NK_PROPERTY_FLOAT:
23561  variant->value.f = variant->value.f + (float)delta;
23562  variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
23563  break;
23564  case NK_PROPERTY_DOUBLE:
23565  variant->value.d = variant->value.d + (double)delta;
23566  variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
23567  break;
23568  }
23569  *state = NK_WIDGET_STATE_ACTIVE;
23570  }
23572  *state |= NK_WIDGET_STATE_ENTERED;
23573  else if (nk_input_is_mouse_prev_hovering_rect(in, drag))
23574  *state |= NK_WIDGET_STATE_LEFT;
23575 }
23576 NK_LIB void
23577 nk_property_behavior(nk_flags *ws, const struct nk_input *in,
23578  struct nk_rect property, struct nk_rect label, struct nk_rect edit,
23579  struct nk_rect empty, int *state, struct nk_property_variant *variant,
23580  float inc_per_pixel)
23581 {
23582  if (in && *state == NK_PROPERTY_DEFAULT) {
23583  if (nk_button_behavior(ws, edit, in, NK_BUTTON_DEFAULT))
23584  *state = NK_PROPERTY_EDIT;
23586  *state = NK_PROPERTY_DRAG;
23588  *state = NK_PROPERTY_DRAG;
23589  }
23590  if (*state == NK_PROPERTY_DRAG) {
23591  nk_drag_behavior(ws, in, property, variant, inc_per_pixel);
23592  if (!(*ws & NK_WIDGET_STATE_ACTIVED)) *state = NK_PROPERTY_DEFAULT;
23593  }
23594 }
23595 NK_LIB void
23596 nk_draw_property(struct nk_command_buffer *out, const struct nk_style_property *style,
23597  const struct nk_rect *bounds, const struct nk_rect *label, nk_flags state,
23598  const char *name, int len, const struct nk_user_font *font)
23599 {
23600  struct nk_text text;
23601  const struct nk_style_item *background;
23602 
23603  /* select correct background and text color */
23604  if (state & NK_WIDGET_STATE_ACTIVED) {
23605  background = &style->active;
23606  text.text = style->label_active;
23607  } else if (state & NK_WIDGET_STATE_HOVER) {
23608  background = &style->hover;
23609  text.text = style->label_hover;
23610  } else {
23611  background = &style->normal;
23612  text.text = style->label_normal;
23613  }
23614 
23615  /* draw background */
23616  if (background->type == NK_STYLE_ITEM_IMAGE) {
23617  nk_draw_image(out, *bounds, &background->data.image, nk_white);
23618  text.background = nk_rgba(0,0,0,0);
23619  } else {
23620  text.background = background->data.color;
23621  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
23622  nk_stroke_rect(out, *bounds, style->rounding, style->border, background->data.color);
23623  }
23624 
23625  /* draw label */
23626  text.padding = nk_vec2(0,0);
23627  nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font);
23628 }
23629 NK_LIB void
23630 nk_do_property(nk_flags *ws,
23631  struct nk_command_buffer *out, struct nk_rect property,
23632  const char *name, struct nk_property_variant *variant,
23633  float inc_per_pixel, char *buffer, int *len,
23634  int *state, int *cursor, int *select_begin, int *select_end,
23635  const struct nk_style_property *style,
23636  enum nk_property_filter filter, struct nk_input *in,
23637  const struct nk_user_font *font, struct nk_text_edit *text_edit,
23638  enum nk_button_behavior behavior)
23639 {
23640  const nk_plugin_filter filters[] = {
23643  };
23644  int active, old;
23645  int num_len, name_len;
23646  char string[NK_MAX_NUMBER_BUFFER];
23647  float size;
23648 
23649  char *dst = 0;
23650  int *length;
23651 
23652  struct nk_rect left;
23653  struct nk_rect right;
23654  struct nk_rect label;
23655  struct nk_rect edit;
23656  struct nk_rect empty;
23657 
23658  /* left decrement button */
23659  left.h = font->height/2;
23660  left.w = left.h;
23661  left.x = property.x + style->border + style->padding.x;
23662  left.y = property.y + style->border + property.h/2.0f - left.h/2;
23663 
23664  /* text label */
23665  name_len = nk_strlen(name);
23666  size = font->width(font->userdata, font->height, name, name_len);
23667  label.x = left.x + left.w + style->padding.x;
23668  label.w = (float)size + 2 * style->padding.x;
23669  label.y = property.y + style->border + style->padding.y;
23670  label.h = property.h - (2 * style->border + 2 * style->padding.y);
23671 
23672  /* right increment button */
23673  right.y = left.y;
23674  right.w = left.w;
23675  right.h = left.h;
23676  right.x = property.x + property.w - (right.w + style->padding.x);
23677 
23678  /* edit */
23679  if (*state == NK_PROPERTY_EDIT) {
23680  size = font->width(font->userdata, font->height, buffer, *len);
23681  size += style->edit.cursor_size;
23682  length = len;
23683  dst = buffer;
23684  } else {
23685  switch (variant->kind) {
23686  default: break;
23687  case NK_PROPERTY_INT:
23688  nk_itoa(string, variant->value.i);
23689  num_len = nk_strlen(string);
23690  break;
23691  case NK_PROPERTY_FLOAT:
23692  NK_DTOA(string, (double)variant->value.f);
23693  num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
23694  break;
23695  case NK_PROPERTY_DOUBLE:
23696  NK_DTOA(string, variant->value.d);
23697  num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
23698  break;
23699  }
23700  size = font->width(font->userdata, font->height, string, num_len);
23701  dst = string;
23702  length = &num_len;
23703  }
23704 
23705  edit.w = (float)size + 2 * style->padding.x;
23706  edit.w = NK_MIN(edit.w, right.x - (label.x + label.w));
23707  edit.x = right.x - (edit.w + style->padding.x);
23708  edit.y = property.y + style->border;
23709  edit.h = property.h - (2 * style->border);
23710 
23711  /* empty left space activator */
23712  empty.w = edit.x - (label.x + label.w);
23713  empty.x = label.x + label.w;
23714  empty.y = property.y;
23715  empty.h = property.h;
23716 
23717  /* update property */
23718  old = (*state == NK_PROPERTY_EDIT);
23719  nk_property_behavior(ws, in, property, label, edit, empty, state, variant, inc_per_pixel);
23720 
23721  /* draw property */
23722  if (style->draw_begin) style->draw_begin(out, style->userdata);
23723  nk_draw_property(out, style, &property, &label, *ws, name, name_len, font);
23724  if (style->draw_end) style->draw_end(out, style->userdata);
23725 
23726  /* execute right button */
23727  if (nk_do_button_symbol(ws, out, left, style->sym_left, behavior, &style->dec_button, in, font)) {
23728  switch (variant->kind) {
23729  default: break;
23730  case NK_PROPERTY_INT:
23731  variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i - variant->step.i, variant->max_value.i); break;
23732  case NK_PROPERTY_FLOAT:
23733  variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f - variant->step.f, variant->max_value.f); break;
23734  case NK_PROPERTY_DOUBLE:
23735  variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d - variant->step.d, variant->max_value.d); break;
23736  }
23737  }
23738  /* execute left button */
23739  if (nk_do_button_symbol(ws, out, right, style->sym_right, behavior, &style->inc_button, in, font)) {
23740  switch (variant->kind) {
23741  default: break;
23742  case NK_PROPERTY_INT:
23743  variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i + variant->step.i, variant->max_value.i); break;
23744  case NK_PROPERTY_FLOAT:
23745  variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f + variant->step.f, variant->max_value.f); break;
23746  case NK_PROPERTY_DOUBLE:
23747  variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d + variant->step.d, variant->max_value.d); break;
23748  }
23749  }
23750  if (old != NK_PROPERTY_EDIT && (*state == NK_PROPERTY_EDIT)) {
23751  /* property has been activated so setup buffer */
23752  NK_MEMCPY(buffer, dst, (nk_size)*length);
23753  *cursor = nk_utf_len(buffer, *length);
23754  *len = *length;
23755  length = len;
23756  dst = buffer;
23757  active = 0;
23758  } else active = (*state == NK_PROPERTY_EDIT);
23759 
23760  /* execute and run text edit field */
23761  nk_textedit_clear_state(text_edit, NK_TEXT_EDIT_SINGLE_LINE, filters[filter]);
23762  text_edit->active = (unsigned char)active;
23763  text_edit->string.len = *length;
23764  text_edit->cursor = NK_CLAMP(0, *cursor, *length);
23765  text_edit->select_start = NK_CLAMP(0,*select_begin, *length);
23766  text_edit->select_end = NK_CLAMP(0,*select_end, *length);
23767  text_edit->string.buffer.allocated = (nk_size)*length;
23769  text_edit->string.buffer.memory.ptr = dst;
23770  text_edit->string.buffer.size = NK_MAX_NUMBER_BUFFER;
23771  text_edit->mode = NK_TEXT_EDIT_MODE_INSERT;
23772  nk_do_edit(ws, out, edit, NK_EDIT_FIELD|NK_EDIT_AUTO_SELECT,
23773  filters[filter], text_edit, &style->edit, (*state == NK_PROPERTY_EDIT) ? in: 0, font);
23774 
23775  *length = text_edit->string.len;
23776  *cursor = text_edit->cursor;
23777  *select_begin = text_edit->select_start;
23778  *select_end = text_edit->select_end;
23779  if (text_edit->active && nk_input_is_key_pressed(in, NK_KEY_ENTER))
23780  text_edit->active = nk_false;
23781 
23782  if (active && !text_edit->active) {
23783  /* property is now not active so convert edit text to value*/
23784  *state = NK_PROPERTY_DEFAULT;
23785  buffer[*len] = '\0';
23786  switch (variant->kind) {
23787  default: break;
23788  case NK_PROPERTY_INT:
23789  variant->value.i = nk_strtoi(buffer, 0);
23790  variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
23791  break;
23792  case NK_PROPERTY_FLOAT:
23793  nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
23794  variant->value.f = nk_strtof(buffer, 0);
23795  variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
23796  break;
23797  case NK_PROPERTY_DOUBLE:
23798  nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
23799  variant->value.d = nk_strtod(buffer, 0);
23800  variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
23801  break;
23802  }
23803  }
23804 }
23805 NK_LIB struct nk_property_variant
23806 nk_property_variant_int(int value, int min_value, int max_value, int step)
23807 {
23808  struct nk_property_variant result;
23809  result.kind = NK_PROPERTY_INT;
23810  result.value.i = value;
23811  result.min_value.i = min_value;
23812  result.max_value.i = max_value;
23813  result.step.i = step;
23814  return result;
23815 }
23816 NK_LIB struct nk_property_variant
23817 nk_property_variant_float(float value, float min_value, float max_value, float step)
23818 {
23819  struct nk_property_variant result;
23820  result.kind = NK_PROPERTY_FLOAT;
23821  result.value.f = value;
23822  result.min_value.f = min_value;
23823  result.max_value.f = max_value;
23824  result.step.f = step;
23825  return result;
23826 }
23827 NK_LIB struct nk_property_variant
23828 nk_property_variant_double(double value, double min_value, double max_value,
23829  double step)
23830 {
23831  struct nk_property_variant result;
23832  result.kind = NK_PROPERTY_DOUBLE;
23833  result.value.d = value;
23834  result.min_value.d = min_value;
23835  result.max_value.d = max_value;
23836  result.step.d = step;
23837  return result;
23838 }
23839 NK_LIB void
23840 nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant *variant,
23841  float inc_per_pixel, const enum nk_property_filter filter)
23842 {
23843  struct nk_window *win;
23844  struct nk_panel *layout;
23845  struct nk_input *in;
23846  const struct nk_style *style;
23847 
23848  struct nk_rect bounds;
23849  enum nk_widget_layout_states s;
23850 
23851  int *state = 0;
23852  nk_hash hash = 0;
23853  char *buffer = 0;
23854  int *len = 0;
23855  int *cursor = 0;
23856  int *select_begin = 0;
23857  int *select_end = 0;
23858  int old_state;
23859 
23860  char dummy_buffer[NK_MAX_NUMBER_BUFFER];
23861  int dummy_state = NK_PROPERTY_DEFAULT;
23862  int dummy_length = 0;
23863  int dummy_cursor = 0;
23864  int dummy_select_begin = 0;
23865  int dummy_select_end = 0;
23866 
23867  NK_ASSERT(ctx);
23868  NK_ASSERT(ctx->current);
23869  NK_ASSERT(ctx->current->layout);
23870  if (!ctx || !ctx->current || !ctx->current->layout)
23871  return;
23872 
23873  win = ctx->current;
23874  layout = win->layout;
23875  style = &ctx->style;
23876  s = nk_widget(&bounds, ctx);
23877  if (!s) return;
23878 
23879  /* calculate hash from name */
23880  if (name[0] == '#') {
23881  hash = nk_murmur_hash(name, (int)nk_strlen(name), win->property.seq++);
23882  name++; /* special number hash */
23883  } else hash = nk_murmur_hash(name, (int)nk_strlen(name), 42);
23884 
23885  /* check if property is currently hot item */
23886  if (win->property.active && hash == win->property.name) {
23887  buffer = win->property.buffer;
23888  len = &win->property.length;
23889  cursor = &win->property.cursor;
23890  state = &win->property.state;
23891  select_begin = &win->property.select_start;
23892  select_end = &win->property.select_end;
23893  } else {
23894  buffer = dummy_buffer;
23895  len = &dummy_length;
23896  cursor = &dummy_cursor;
23897  state = &dummy_state;
23898  select_begin = &dummy_select_begin;
23899  select_end = &dummy_select_end;
23900  }
23901 
23902  /* execute property widget */
23903  old_state = *state;
23904  ctx->text_edit.clip = ctx->clip;
23905  in = ((s == NK_WIDGET_ROM && !win->property.active) ||
23906  layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
23907  nk_do_property(&ctx->last_widget_state, &win->buffer, bounds, name,
23908  variant, inc_per_pixel, buffer, len, state, cursor, select_begin,
23909  select_end, &style->property, filter, in, style->font, &ctx->text_edit,
23910  ctx->button_behavior);
23911 
23912  if (in && *state != NK_PROPERTY_DEFAULT && !win->property.active) {
23913  /* current property is now hot */
23914  win->property.active = 1;
23915  NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len);
23916  win->property.length = *len;
23917  win->property.cursor = *cursor;
23918  win->property.state = *state;
23919  win->property.name = hash;
23920  win->property.select_start = *select_begin;
23921  win->property.select_end = *select_end;
23922  if (*state == NK_PROPERTY_DRAG) {
23923  ctx->input.mouse.grab = nk_true;
23924  ctx->input.mouse.grabbed = nk_true;
23925  }
23926  }
23927  /* check if previously active property is now inactive */
23928  if (*state == NK_PROPERTY_DEFAULT && old_state != NK_PROPERTY_DEFAULT) {
23929  if (old_state == NK_PROPERTY_DRAG) {
23930  ctx->input.mouse.grab = nk_false;
23931  ctx->input.mouse.grabbed = nk_false;
23932  ctx->input.mouse.ungrab = nk_true;
23933  }
23934  win->property.select_start = 0;
23935  win->property.select_end = 0;
23936  win->property.active = 0;
23937  }
23938 }
23939 NK_API void
23940 nk_property_int(struct nk_context *ctx, const char *name,
23941  int min, int *val, int max, int step, float inc_per_pixel)
23942 {
23943  struct nk_property_variant variant;
23944  NK_ASSERT(ctx);
23945  NK_ASSERT(name);
23946  NK_ASSERT(val);
23947 
23948  if (!ctx || !ctx->current || !name || !val) return;
23949  variant = nk_property_variant_int(*val, min, max, step);
23950  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
23951  *val = variant.value.i;
23952 }
23953 NK_API void
23954 nk_property_float(struct nk_context *ctx, const char *name,
23955  float min, float *val, float max, float step, float inc_per_pixel)
23956 {
23957  struct nk_property_variant variant;
23958  NK_ASSERT(ctx);
23959  NK_ASSERT(name);
23960  NK_ASSERT(val);
23961 
23962  if (!ctx || !ctx->current || !name || !val) return;
23963  variant = nk_property_variant_float(*val, min, max, step);
23964  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
23965  *val = variant.value.f;
23966 }
23967 NK_API void
23968 nk_property_double(struct nk_context *ctx, const char *name,
23969  double min, double *val, double max, double step, float inc_per_pixel)
23970 {
23971  struct nk_property_variant variant;
23972  NK_ASSERT(ctx);
23973  NK_ASSERT(name);
23974  NK_ASSERT(val);
23975 
23976  if (!ctx || !ctx->current || !name || !val) return;
23977  variant = nk_property_variant_double(*val, min, max, step);
23978  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
23979  *val = variant.value.d;
23980 }
23981 NK_API int
23982 nk_propertyi(struct nk_context *ctx, const char *name, int min, int val,
23983  int max, int step, float inc_per_pixel)
23984 {
23985  struct nk_property_variant variant;
23986  NK_ASSERT(ctx);
23987  NK_ASSERT(name);
23988 
23989  if (!ctx || !ctx->current || !name) return val;
23990  variant = nk_property_variant_int(val, min, max, step);
23991  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
23992  val = variant.value.i;
23993  return val;
23994 }
23995 NK_API float
23996 nk_propertyf(struct nk_context *ctx, const char *name, float min,
23997  float val, float max, float step, float inc_per_pixel)
23998 {
23999  struct nk_property_variant variant;
24000  NK_ASSERT(ctx);
24001  NK_ASSERT(name);
24002 
24003  if (!ctx || !ctx->current || !name) return val;
24004  variant = nk_property_variant_float(val, min, max, step);
24005  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
24006  val = variant.value.f;
24007  return val;
24008 }
24009 NK_API double
24010 nk_propertyd(struct nk_context *ctx, const char *name, double min,
24011  double val, double max, double step, float inc_per_pixel)
24012 {
24013  struct nk_property_variant variant;
24014  NK_ASSERT(ctx);
24015  NK_ASSERT(name);
24016 
24017  if (!ctx || !ctx->current || !name) return val;
24018  variant = nk_property_variant_double(val, min, max, step);
24019  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
24020  val = variant.value.d;
24021  return val;
24022 }
24023 
24024 
24025 
24026 
24027 
24028 /* ==============================================================
24029  *
24030  * CHART
24031  *
24032  * ===============================================================*/
24033 NK_API int
24034 nk_chart_begin_colored(struct nk_context *ctx, enum nk_chart_type type,
24035  struct nk_color color, struct nk_color highlight,
24036  int count, float min_value, float max_value)
24037 {
24038  struct nk_window *win;
24039  struct nk_chart *chart;
24040  const struct nk_style *config;
24041  const struct nk_style_chart *style;
24042 
24043  const struct nk_style_item *background;
24044  struct nk_rect bounds = {0, 0, 0, 0};
24045 
24046  NK_ASSERT(ctx);
24047  NK_ASSERT(ctx->current);
24048  NK_ASSERT(ctx->current->layout);
24049 
24050  if (!ctx || !ctx->current || !ctx->current->layout) return 0;
24051  if (!nk_widget(&bounds, ctx)) {
24052  chart = &ctx->current->layout->chart;
24053  nk_zero(chart, sizeof(*chart));
24054  return 0;
24055  }
24056 
24057  win = ctx->current;
24058  config = &ctx->style;
24059  chart = &win->layout->chart;
24060  style = &config->chart;
24061 
24062  /* setup basic generic chart */
24063  nk_zero(chart, sizeof(*chart));
24064  chart->x = bounds.x + style->padding.x;
24065  chart->y = bounds.y + style->padding.y;
24066  chart->w = bounds.w - 2 * style->padding.x;
24067  chart->h = bounds.h - 2 * style->padding.y;
24068  chart->w = NK_MAX(chart->w, 2 * style->padding.x);
24069  chart->h = NK_MAX(chart->h, 2 * style->padding.y);
24070 
24071  /* add first slot into chart */
24072  {struct nk_chart_slot *slot = &chart->slots[chart->slot++];
24073  slot->type = type;
24074  slot->count = count;
24075  slot->color = color;
24076  slot->highlight = highlight;
24077  slot->min = NK_MIN(min_value, max_value);
24078  slot->max = NK_MAX(min_value, max_value);
24079  slot->range = slot->max - slot->min;}
24080 
24081  /* draw chart background */
24082  background = &style->background;
24083  if (background->type == NK_STYLE_ITEM_IMAGE) {
24084  nk_draw_image(&win->buffer, bounds, &background->data.image, nk_white);
24085  } else {
24086  nk_fill_rect(&win->buffer, bounds, style->rounding, style->border_color);
24087  nk_fill_rect(&win->buffer, nk_shrink_rect(bounds, style->border),
24088  style->rounding, style->background.data.color);
24089  }
24090  return 1;
24091 }
24092 NK_API int
24093 nk_chart_begin(struct nk_context *ctx, const enum nk_chart_type type,
24094  int count, float min_value, float max_value)
24095 {
24096  return nk_chart_begin_colored(ctx, type, ctx->style.chart.color,
24097  ctx->style.chart.selected_color, count, min_value, max_value);
24098 }
24099 NK_API void
24100 nk_chart_add_slot_colored(struct nk_context *ctx, const enum nk_chart_type type,
24101  struct nk_color color, struct nk_color highlight,
24102  int count, float min_value, float max_value)
24103 {
24104  NK_ASSERT(ctx);
24105  NK_ASSERT(ctx->current);
24106  NK_ASSERT(ctx->current->layout);
24107  NK_ASSERT(ctx->current->layout->chart.slot < NK_CHART_MAX_SLOT);
24108  if (!ctx || !ctx->current || !ctx->current->layout) return;
24109  if (ctx->current->layout->chart.slot >= NK_CHART_MAX_SLOT) return;
24110 
24111  /* add another slot into the graph */
24112  {struct nk_chart *chart = &ctx->current->layout->chart;
24113  struct nk_chart_slot *slot = &chart->slots[chart->slot++];
24114  slot->type = type;
24115  slot->count = count;
24116  slot->color = color;
24117  slot->highlight = highlight;
24118  slot->min = NK_MIN(min_value, max_value);
24119  slot->max = NK_MAX(min_value, max_value);
24120  slot->range = slot->max - slot->min;}
24121 }
24122 NK_API void
24123 nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type type,
24124  int count, float min_value, float max_value)
24125 {
24127  ctx->style.chart.selected_color, count, min_value, max_value);
24128 }
24130 nk_chart_push_line(struct nk_context *ctx, struct nk_window *win,
24131  struct nk_chart *g, float value, int slot)
24132 {
24133  struct nk_panel *layout = win->layout;
24134  const struct nk_input *i = &ctx->input;
24135  struct nk_command_buffer *out = &win->buffer;
24136 
24137  nk_flags ret = 0;
24138  struct nk_vec2 cur;
24139  struct nk_rect bounds;
24140  struct nk_color color;
24141  float step;
24142  float range;
24143  float ratio;
24144 
24145  NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
24146  step = g->w / (float)g->slots[slot].count;
24147  range = g->slots[slot].max - g->slots[slot].min;
24148  ratio = (value - g->slots[slot].min) / range;
24149 
24150  if (g->slots[slot].index == 0) {
24151  /* first data point does not have a connection */
24152  g->slots[slot].last.x = g->x;
24153  g->slots[slot].last.y = (g->y + g->h) - ratio * (float)g->h;
24154 
24155  bounds.x = g->slots[slot].last.x - 2;
24156  bounds.y = g->slots[slot].last.y - 2;
24157  bounds.w = bounds.h = 4;
24158 
24159  color = g->slots[slot].color;
24160  if (!(layout->flags & NK_WINDOW_ROM) &&
24161  NK_INBOX(i->mouse.pos.x,i->mouse.pos.y, g->slots[slot].last.x-3, g->slots[slot].last.y-3, 6, 6)){
24162  ret = nk_input_is_mouse_hovering_rect(i, bounds) ? NK_CHART_HOVERING : 0;
24163  ret |= (i->mouse.buttons[NK_BUTTON_LEFT].down &&
24165  color = g->slots[slot].highlight;
24166  }
24167  nk_fill_rect(out, bounds, 0, color);
24168  g->slots[slot].index += 1;
24169  return ret;
24170  }
24171 
24172  /* draw a line between the last data point and the new one */
24173  color = g->slots[slot].color;
24174  cur.x = g->x + (float)(step * (float)g->slots[slot].index);
24175  cur.y = (g->y + g->h) - (ratio * (float)g->h);
24176  nk_stroke_line(out, g->slots[slot].last.x, g->slots[slot].last.y, cur.x, cur.y, 1.0f, color);
24177 
24178  bounds.x = cur.x - 3;
24179  bounds.y = cur.y - 3;
24180  bounds.w = bounds.h = 6;
24181 
24182  /* user selection of current data point */
24183  if (!(layout->flags & NK_WINDOW_ROM)) {
24184  if (nk_input_is_mouse_hovering_rect(i, bounds)) {
24185  ret = NK_CHART_HOVERING;
24186  ret |= (!i->mouse.buttons[NK_BUTTON_LEFT].down &&
24188  color = g->slots[slot].highlight;
24189  }
24190  }
24191  nk_fill_rect(out, nk_rect(cur.x - 2, cur.y - 2, 4, 4), 0, color);
24192 
24193  /* save current data point position */
24194  g->slots[slot].last.x = cur.x;
24195  g->slots[slot].last.y = cur.y;
24196  g->slots[slot].index += 1;
24197  return ret;
24198 }
24200 nk_chart_push_column(const struct nk_context *ctx, struct nk_window *win,
24201  struct nk_chart *chart, float value, int slot)
24202 {
24203  struct nk_command_buffer *out = &win->buffer;
24204  const struct nk_input *in = &ctx->input;
24205  struct nk_panel *layout = win->layout;
24206 
24207  float ratio;
24208  nk_flags ret = 0;
24209  struct nk_color color;
24210  struct nk_rect item = {0,0,0,0};
24211 
24212  NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
24213  if (chart->slots[slot].index >= chart->slots[slot].count)
24214  return nk_false;
24215  if (chart->slots[slot].count) {
24216  float padding = (float)(chart->slots[slot].count-1);
24217  item.w = (chart->w - padding) / (float)(chart->slots[slot].count);
24218  }
24219 
24220  /* calculate bounds of current bar chart entry */
24221  color = chart->slots[slot].color;;
24222  item.h = chart->h * NK_ABS((value/chart->slots[slot].range));
24223  if (value >= 0) {
24224  ratio = (value + NK_ABS(chart->slots[slot].min)) / NK_ABS(chart->slots[slot].range);
24225  item.y = (chart->y + chart->h) - chart->h * ratio;
24226  } else {
24227  ratio = (value - chart->slots[slot].max) / chart->slots[slot].range;
24228  item.y = chart->y + (chart->h * NK_ABS(ratio)) - item.h;
24229  }
24230  item.x = chart->x + ((float)chart->slots[slot].index * item.w);
24231  item.x = item.x + ((float)chart->slots[slot].index);
24232 
24233  /* user chart bar selection */
24234  if (!(layout->flags & NK_WINDOW_ROM) &&
24235  NK_INBOX(in->mouse.pos.x,in->mouse.pos.y,item.x,item.y,item.w,item.h)) {
24236  ret = NK_CHART_HOVERING;
24237  ret |= (!in->mouse.buttons[NK_BUTTON_LEFT].down &&
24239  color = chart->slots[slot].highlight;
24240  }
24241  nk_fill_rect(out, item, 0, color);
24242  chart->slots[slot].index += 1;
24243  return ret;
24244 }
24246 nk_chart_push_slot(struct nk_context *ctx, float value, int slot)
24247 {
24248  nk_flags flags;
24249  struct nk_window *win;
24250 
24251  NK_ASSERT(ctx);
24252  NK_ASSERT(ctx->current);
24253  NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
24254  NK_ASSERT(slot < ctx->current->layout->chart.slot);
24255  if (!ctx || !ctx->current || slot >= NK_CHART_MAX_SLOT) return nk_false;
24256  if (slot >= ctx->current->layout->chart.slot) return nk_false;
24257 
24258  win = ctx->current;
24259  if (win->layout->chart.slot < slot) return nk_false;
24260  switch (win->layout->chart.slots[slot].type) {
24261  case NK_CHART_LINES:
24262  flags = nk_chart_push_line(ctx, win, &win->layout->chart, value, slot); break;
24263  case NK_CHART_COLUMN:
24264  flags = nk_chart_push_column(ctx, win, &win->layout->chart, value, slot); break;
24265  default:
24266  case NK_CHART_MAX:
24267  flags = 0;
24268  }
24269  return flags;
24270 }
24272 nk_chart_push(struct nk_context *ctx, float value)
24273 {
24274  return nk_chart_push_slot(ctx, value, 0);
24275 }
24276 NK_API void
24277 nk_chart_end(struct nk_context *ctx)
24278 {
24279  struct nk_window *win;
24280  struct nk_chart *chart;
24281 
24282  NK_ASSERT(ctx);
24283  NK_ASSERT(ctx->current);
24284  if (!ctx || !ctx->current)
24285  return;
24286 
24287  win = ctx->current;
24288  chart = &win->layout->chart;
24289  NK_MEMSET(chart, 0, sizeof(*chart));
24290  return;
24291 }
24292 NK_API void
24293 nk_plot(struct nk_context *ctx, enum nk_chart_type type, const float *values,
24294  int count, int offset)
24295 {
24296  int i = 0;
24297  float min_value;
24298  float max_value;
24299 
24300  NK_ASSERT(ctx);
24301  NK_ASSERT(values);
24302  if (!ctx || !values || !count) return;
24303 
24304  min_value = values[offset];
24305  max_value = values[offset];
24306  for (i = 0; i < count; ++i) {
24307  min_value = NK_MIN(values[i + offset], min_value);
24308  max_value = NK_MAX(values[i + offset], max_value);
24309  }
24310 
24311  if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
24312  for (i = 0; i < count; ++i)
24313  nk_chart_push(ctx, values[i + offset]);
24314  nk_chart_end(ctx);
24315  }
24316 }
24317 NK_API void
24318 nk_plot_function(struct nk_context *ctx, enum nk_chart_type type, void *userdata,
24319  float(*value_getter)(void* user, int index), int count, int offset)
24320 {
24321  int i = 0;
24322  float min_value;
24323  float max_value;
24324 
24325  NK_ASSERT(ctx);
24326  NK_ASSERT(value_getter);
24327  if (!ctx || !value_getter || !count) return;
24328 
24329  max_value = min_value = value_getter(userdata, offset);
24330  for (i = 0; i < count; ++i) {
24331  float value = value_getter(userdata, i + offset);
24332  min_value = NK_MIN(value, min_value);
24333  max_value = NK_MAX(value, max_value);
24334  }
24335 
24336  if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
24337  for (i = 0; i < count; ++i)
24338  nk_chart_push(ctx, value_getter(userdata, i + offset));
24339  nk_chart_end(ctx);
24340  }
24341 }
24342 
24343 
24344 
24345 
24346 
24347 /* ==============================================================
24348  *
24349  * COLOR PICKER
24350  *
24351  * ===============================================================*/
24352 NK_LIB int
24353 nk_color_picker_behavior(nk_flags *state,
24354  const struct nk_rect *bounds, const struct nk_rect *matrix,
24355  const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar,
24356  struct nk_colorf *color, const struct nk_input *in)
24357 {
24358  float hsva[4];
24359  int value_changed = 0;
24360  int hsv_changed = 0;
24361 
24362  NK_ASSERT(state);
24363  NK_ASSERT(matrix);
24364  NK_ASSERT(hue_bar);
24365  NK_ASSERT(color);
24366 
24367  /* color matrix */
24368  nk_colorf_hsva_fv(hsva, *color);
24369  if (nk_button_behavior(state, *matrix, in, NK_BUTTON_REPEATER)) {
24370  hsva[1] = NK_SATURATE((in->mouse.pos.x - matrix->x) / (matrix->w-1));
24371  hsva[2] = 1.0f - NK_SATURATE((in->mouse.pos.y - matrix->y) / (matrix->h-1));
24372  value_changed = hsv_changed = 1;
24373  }
24374  /* hue bar */
24375  if (nk_button_behavior(state, *hue_bar, in, NK_BUTTON_REPEATER)) {
24376  hsva[0] = NK_SATURATE((in->mouse.pos.y - hue_bar->y) / (hue_bar->h-1));
24377  value_changed = hsv_changed = 1;
24378  }
24379  /* alpha bar */
24380  if (alpha_bar) {
24381  if (nk_button_behavior(state, *alpha_bar, in, NK_BUTTON_REPEATER)) {
24382  hsva[3] = 1.0f - NK_SATURATE((in->mouse.pos.y - alpha_bar->y) / (alpha_bar->h-1));
24383  value_changed = 1;
24384  }
24385  }
24386  nk_widget_state_reset(state);
24387  if (hsv_changed) {
24388  *color = nk_hsva_colorfv(hsva);
24389  *state = NK_WIDGET_STATE_ACTIVE;
24390  }
24391  if (value_changed) {
24392  color->a = hsva[3];
24393  *state = NK_WIDGET_STATE_ACTIVE;
24394  }
24395  /* set color picker widget state */
24396  if (nk_input_is_mouse_hovering_rect(in, *bounds))
24397  *state = NK_WIDGET_STATE_HOVERED;
24398  if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *bounds))
24399  *state |= NK_WIDGET_STATE_ENTERED;
24400  else if (nk_input_is_mouse_prev_hovering_rect(in, *bounds))
24401  *state |= NK_WIDGET_STATE_LEFT;
24402  return value_changed;
24403 }
24404 NK_LIB void
24405 nk_draw_color_picker(struct nk_command_buffer *o, const struct nk_rect *matrix,
24406  const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar,
24407  struct nk_colorf col)
24408 {
24409  NK_STORAGE const struct nk_color black = {0,0,0,255};
24410  NK_STORAGE const struct nk_color white = {255, 255, 255, 255};
24411  NK_STORAGE const struct nk_color black_trans = {0,0,0,0};
24412 
24413  const float crosshair_size = 7.0f;
24414  struct nk_color temp;
24415  float hsva[4];
24416  float line_y;
24417  int i;
24418 
24419  NK_ASSERT(o);
24420  NK_ASSERT(matrix);
24421  NK_ASSERT(hue_bar);
24422 
24423  /* draw hue bar */
24424  nk_colorf_hsva_fv(hsva, col);
24425  for (i = 0; i < 6; ++i) {
24426  NK_GLOBAL const struct nk_color hue_colors[] = {
24427  {255, 0, 0, 255}, {255,255,0,255}, {0,255,0,255}, {0, 255,255,255},
24428  {0,0,255,255}, {255, 0, 255, 255}, {255, 0, 0, 255}
24429  };
24431  nk_rect(hue_bar->x, hue_bar->y + (float)i * (hue_bar->h/6.0f) + 0.5f,
24432  hue_bar->w, (hue_bar->h/6.0f) + 0.5f), hue_colors[i], hue_colors[i],
24433  hue_colors[i+1], hue_colors[i+1]);
24434  }
24435  line_y = (float)(int)(hue_bar->y + hsva[0] * matrix->h + 0.5f);
24436  nk_stroke_line(o, hue_bar->x-1, line_y, hue_bar->x + hue_bar->w + 2,
24437  line_y, 1, nk_rgb(255,255,255));
24438 
24439  /* draw alpha bar */
24440  if (alpha_bar) {
24441  float alpha = NK_SATURATE(col.a);
24442  line_y = (float)(int)(alpha_bar->y + (1.0f - alpha) * matrix->h + 0.5f);
24443 
24444  nk_fill_rect_multi_color(o, *alpha_bar, white, white, black, black);
24445  nk_stroke_line(o, alpha_bar->x-1, line_y, alpha_bar->x + alpha_bar->w + 2,
24446  line_y, 1, nk_rgb(255,255,255));
24447  }
24448 
24449  /* draw color matrix */
24450  temp = nk_hsv_f(hsva[0], 1.0f, 1.0f);
24451  nk_fill_rect_multi_color(o, *matrix, white, temp, temp, white);
24452  nk_fill_rect_multi_color(o, *matrix, black_trans, black_trans, black, black);
24453 
24454  /* draw cross-hair */
24455  {struct nk_vec2 p; float S = hsva[1]; float V = hsva[2];
24456  p.x = (float)(int)(matrix->x + S * matrix->w);
24457  p.y = (float)(int)(matrix->y + (1.0f - V) * matrix->h);
24458  nk_stroke_line(o, p.x - crosshair_size, p.y, p.x-2, p.y, 1.0f, white);
24459  nk_stroke_line(o, p.x + crosshair_size + 1, p.y, p.x+3, p.y, 1.0f, white);
24460  nk_stroke_line(o, p.x, p.y + crosshair_size + 1, p.x, p.y+3, 1.0f, white);
24461  nk_stroke_line(o, p.x, p.y - crosshair_size, p.x, p.y-2, 1.0f, white);}
24462 }
24463 NK_LIB int
24464 nk_do_color_picker(nk_flags *state,
24465  struct nk_command_buffer *out, struct nk_colorf *col,
24466  enum nk_color_format fmt, struct nk_rect bounds,
24467  struct nk_vec2 padding, const struct nk_input *in,
24468  const struct nk_user_font *font)
24469 {
24470  int ret = 0;
24471  struct nk_rect matrix;
24472  struct nk_rect hue_bar;
24473  struct nk_rect alpha_bar;
24474  float bar_w;
24475 
24476  NK_ASSERT(out);
24477  NK_ASSERT(col);
24478  NK_ASSERT(state);
24479  NK_ASSERT(font);
24480  if (!out || !col || !state || !font)
24481  return ret;
24482 
24483  bar_w = font->height;
24484  bounds.x += padding.x;
24485  bounds.y += padding.x;
24486  bounds.w -= 2 * padding.x;
24487  bounds.h -= 2 * padding.y;
24488 
24489  matrix.x = bounds.x;
24490  matrix.y = bounds.y;
24491  matrix.h = bounds.h;
24492  matrix.w = bounds.w - (3 * padding.x + 2 * bar_w);
24493 
24494  hue_bar.w = bar_w;
24495  hue_bar.y = bounds.y;
24496  hue_bar.h = matrix.h;
24497  hue_bar.x = matrix.x + matrix.w + padding.x;
24498 
24499  alpha_bar.x = hue_bar.x + hue_bar.w + padding.x;
24500  alpha_bar.y = bounds.y;
24501  alpha_bar.w = bar_w;
24502  alpha_bar.h = matrix.h;
24503 
24504  ret = nk_color_picker_behavior(state, &bounds, &matrix, &hue_bar,
24505  (fmt == NK_RGBA) ? &alpha_bar:0, col, in);
24506  nk_draw_color_picker(out, &matrix, &hue_bar, (fmt == NK_RGBA) ? &alpha_bar:0, *col);
24507  return ret;
24508 }
24509 NK_API int
24510 nk_color_pick(struct nk_context * ctx, struct nk_colorf *color,
24511  enum nk_color_format fmt)
24512 {
24513  struct nk_window *win;
24514  struct nk_panel *layout;
24515  const struct nk_style *config;
24516  const struct nk_input *in;
24517 
24518  enum nk_widget_layout_states state;
24519  struct nk_rect bounds;
24520 
24521  NK_ASSERT(ctx);
24522  NK_ASSERT(color);
24523  NK_ASSERT(ctx->current);
24524  NK_ASSERT(ctx->current->layout);
24525  if (!ctx || !ctx->current || !ctx->current->layout || !color)
24526  return 0;
24527 
24528  win = ctx->current;
24529  config = &ctx->style;
24530  layout = win->layout;
24531  state = nk_widget(&bounds, ctx);
24532  if (!state) return 0;
24533  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
24534  return nk_do_color_picker(&ctx->last_widget_state, &win->buffer, color, fmt, bounds,
24535  nk_vec2(0,0), in, config->font);
24536 }
24537 NK_API struct nk_colorf
24538 nk_color_picker(struct nk_context *ctx, struct nk_colorf color,
24539  enum nk_color_format fmt)
24540 {
24541  nk_color_pick(ctx, &color, fmt);
24542  return color;
24543 }
24544 
24545 
24546 
24547 
24548 
24549 /* ==============================================================
24550  *
24551  * COMBO
24552  *
24553  * ===============================================================*/
24554 NK_INTERN int
24555 nk_combo_begin(struct nk_context *ctx, struct nk_window *win,
24556  struct nk_vec2 size, int is_clicked, struct nk_rect header)
24557 {
24558  struct nk_window *popup;
24559  int is_open = 0;
24560  int is_active = 0;
24561  struct nk_rect body;
24562  nk_hash hash;
24563 
24564  NK_ASSERT(ctx);
24565  NK_ASSERT(ctx->current);
24566  NK_ASSERT(ctx->current->layout);
24567  if (!ctx || !ctx->current || !ctx->current->layout)
24568  return 0;
24569 
24570  popup = win->popup.win;
24571  body.x = header.x;
24572  body.w = size.x;
24573  body.y = header.y + header.h-ctx->style.window.combo_border;
24574  body.h = size.y;
24575 
24576  hash = win->popup.combo_count++;
24577  is_open = (popup) ? nk_true:nk_false;
24578  is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_COMBO);
24579  if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
24580  (!is_open && !is_active && !is_clicked)) return 0;
24581  if (!nk_nonblock_begin(ctx, 0, body,
24582  (is_clicked && is_open)?nk_rect(0,0,0,0):header, NK_PANEL_COMBO)) return 0;
24583 
24585  win->popup.name = hash;
24586  return 1;
24587 }
24588 NK_API int
24589 nk_combo_begin_text(struct nk_context *ctx, const char *selected, int len,
24590  struct nk_vec2 size)
24591 {
24592  const struct nk_input *in;
24593  struct nk_window *win;
24594  struct nk_style *style;
24595 
24596  enum nk_widget_layout_states s;
24597  int is_clicked = nk_false;
24598  struct nk_rect header;
24599  const struct nk_style_item *background;
24600  struct nk_text text;
24601 
24602  NK_ASSERT(ctx);
24603  NK_ASSERT(selected);
24604  NK_ASSERT(ctx->current);
24605  NK_ASSERT(ctx->current->layout);
24606  if (!ctx || !ctx->current || !ctx->current->layout || !selected)
24607  return 0;
24608 
24609  win = ctx->current;
24610  style = &ctx->style;
24611  s = nk_widget(&header, ctx);
24612  if (s == NK_WIDGET_INVALID)
24613  return 0;
24614 
24615  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24616  if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
24617  is_clicked = nk_true;
24618 
24619  /* draw combo box header background and border */
24621  background = &style->combo.active;
24622  text.text = style->combo.label_active;
24623  } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
24624  background = &style->combo.hover;
24625  text.text = style->combo.label_hover;
24626  } else {
24627  background = &style->combo.normal;
24628  text.text = style->combo.label_normal;
24629  }
24630  if (background->type == NK_STYLE_ITEM_IMAGE) {
24631  text.background = nk_rgba(0,0,0,0);
24632  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24633  } else {
24634  text.background = background->data.color;
24635  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24636  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24637  }
24638  {
24639  /* print currently selected text item */
24640  struct nk_rect label;
24641  struct nk_rect button;
24642  struct nk_rect content;
24643 
24644  enum nk_symbol_type sym;
24646  sym = style->combo.sym_hover;
24647  else if (is_clicked)
24648  sym = style->combo.sym_active;
24649  else sym = style->combo.sym_normal;
24650 
24651  /* calculate button */
24652  button.w = header.h - 2 * style->combo.button_padding.y;
24653  button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
24654  button.y = header.y + style->combo.button_padding.y;
24655  button.h = button.w;
24656 
24657  content.x = button.x + style->combo.button.padding.x;
24658  content.y = button.y + style->combo.button.padding.y;
24659  content.w = button.w - 2 * style->combo.button.padding.x;
24660  content.h = button.h - 2 * style->combo.button.padding.y;
24661 
24662  /* draw selected label */
24663  text.padding = nk_vec2(0,0);
24664  label.x = header.x + style->combo.content_padding.x;
24665  label.y = header.y + style->combo.content_padding.y;
24666  label.w = button.x - (style->combo.content_padding.x + style->combo.spacing.x) - label.x;;
24667  label.h = header.h - 2 * style->combo.content_padding.y;
24668  nk_widget_text(&win->buffer, label, selected, len, &text,
24669  NK_TEXT_LEFT, ctx->style.font);
24670 
24671  /* draw open/close button */
24672  nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
24673  &ctx->style.combo.button, sym, style->font);
24674  }
24675  return nk_combo_begin(ctx, win, size, is_clicked, header);
24676 }
24677 NK_API int
24678 nk_combo_begin_label(struct nk_context *ctx, const char *selected, struct nk_vec2 size)
24679 {
24680  return nk_combo_begin_text(ctx, selected, nk_strlen(selected), size);
24681 }
24682 NK_API int
24683 nk_combo_begin_color(struct nk_context *ctx, struct nk_color color, struct nk_vec2 size)
24684 {
24685  struct nk_window *win;
24686  struct nk_style *style;
24687  const struct nk_input *in;
24688 
24689  struct nk_rect header;
24690  int is_clicked = nk_false;
24691  enum nk_widget_layout_states s;
24692  const struct nk_style_item *background;
24693 
24694  NK_ASSERT(ctx);
24695  NK_ASSERT(ctx->current);
24696  NK_ASSERT(ctx->current->layout);
24697  if (!ctx || !ctx->current || !ctx->current->layout)
24698  return 0;
24699 
24700  win = ctx->current;
24701  style = &ctx->style;
24702  s = nk_widget(&header, ctx);
24703  if (s == NK_WIDGET_INVALID)
24704  return 0;
24705 
24706  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24707  if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
24708  is_clicked = nk_true;
24709 
24710  /* draw combo box header background and border */
24712  background = &style->combo.active;
24713  else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
24714  background = &style->combo.hover;
24715  else background = &style->combo.normal;
24716 
24717  if (background->type == NK_STYLE_ITEM_IMAGE) {
24718  nk_draw_image(&win->buffer, header, &background->data.image,nk_white);
24719  } else {
24720  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24721  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24722  }
24723  {
24724  struct nk_rect content;
24725  struct nk_rect button;
24726  struct nk_rect bounds;
24727 
24728  enum nk_symbol_type sym;
24730  sym = style->combo.sym_hover;
24731  else if (is_clicked)
24732  sym = style->combo.sym_active;
24733  else sym = style->combo.sym_normal;
24734 
24735  /* calculate button */
24736  button.w = header.h - 2 * style->combo.button_padding.y;
24737  button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
24738  button.y = header.y + style->combo.button_padding.y;
24739  button.h = button.w;
24740 
24741  content.x = button.x + style->combo.button.padding.x;
24742  content.y = button.y + style->combo.button.padding.y;
24743  content.w = button.w - 2 * style->combo.button.padding.x;
24744  content.h = button.h - 2 * style->combo.button.padding.y;
24745 
24746  /* draw color */
24747  bounds.h = header.h - 4 * style->combo.content_padding.y;
24748  bounds.y = header.y + 2 * style->combo.content_padding.y;
24749  bounds.x = header.x + 2 * style->combo.content_padding.x;
24750  bounds.w = (button.x - (style->combo.content_padding.x + style->combo.spacing.x)) - bounds.x;
24751  nk_fill_rect(&win->buffer, bounds, 0, color);
24752 
24753  /* draw open/close button */
24754  nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
24755  &ctx->style.combo.button, sym, style->font);
24756  }
24757  return nk_combo_begin(ctx, win, size, is_clicked, header);
24758 }
24759 NK_API int
24760 nk_combo_begin_symbol(struct nk_context *ctx, enum nk_symbol_type symbol, struct nk_vec2 size)
24761 {
24762  struct nk_window *win;
24763  struct nk_style *style;
24764  const struct nk_input *in;
24765 
24766  struct nk_rect header;
24767  int is_clicked = nk_false;
24768  enum nk_widget_layout_states s;
24769  const struct nk_style_item *background;
24770  struct nk_color sym_background;
24771  struct nk_color symbol_color;
24772 
24773  NK_ASSERT(ctx);
24774  NK_ASSERT(ctx->current);
24775  NK_ASSERT(ctx->current->layout);
24776  if (!ctx || !ctx->current || !ctx->current->layout)
24777  return 0;
24778 
24779  win = ctx->current;
24780  style = &ctx->style;
24781  s = nk_widget(&header, ctx);
24782  if (s == NK_WIDGET_INVALID)
24783  return 0;
24784 
24785  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24786  if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
24787  is_clicked = nk_true;
24788 
24789  /* draw combo box header background and border */
24791  background = &style->combo.active;
24792  symbol_color = style->combo.symbol_active;
24793  } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
24794  background = &style->combo.hover;
24795  symbol_color = style->combo.symbol_hover;
24796  } else {
24797  background = &style->combo.normal;
24798  symbol_color = style->combo.symbol_hover;
24799  }
24800 
24801  if (background->type == NK_STYLE_ITEM_IMAGE) {
24802  sym_background = nk_rgba(0,0,0,0);
24803  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24804  } else {
24805  sym_background = background->data.color;
24806  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24807  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24808  }
24809  {
24810  struct nk_rect bounds = {0,0,0,0};
24811  struct nk_rect content;
24812  struct nk_rect button;
24813 
24814  enum nk_symbol_type sym;
24816  sym = style->combo.sym_hover;
24817  else if (is_clicked)
24818  sym = style->combo.sym_active;
24819  else sym = style->combo.sym_normal;
24820 
24821  /* calculate button */
24822  button.w = header.h - 2 * style->combo.button_padding.y;
24823  button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
24824  button.y = header.y + style->combo.button_padding.y;
24825  button.h = button.w;
24826 
24827  content.x = button.x + style->combo.button.padding.x;
24828  content.y = button.y + style->combo.button.padding.y;
24829  content.w = button.w - 2 * style->combo.button.padding.x;
24830  content.h = button.h - 2 * style->combo.button.padding.y;
24831 
24832  /* draw symbol */
24833  bounds.h = header.h - 2 * style->combo.content_padding.y;
24834  bounds.y = header.y + style->combo.content_padding.y;
24835  bounds.x = header.x + style->combo.content_padding.x;
24836  bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
24837  nk_draw_symbol(&win->buffer, symbol, bounds, sym_background, symbol_color,
24838  1.0f, style->font);
24839 
24840  /* draw open/close button */
24841  nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
24842  &ctx->style.combo.button, sym, style->font);
24843  }
24844  return nk_combo_begin(ctx, win, size, is_clicked, header);
24845 }
24846 NK_API int
24847 nk_combo_begin_symbol_text(struct nk_context *ctx, const char *selected, int len,
24848  enum nk_symbol_type symbol, struct nk_vec2 size)
24849 {
24850  struct nk_window *win;
24851  struct nk_style *style;
24852  struct nk_input *in;
24853 
24854  struct nk_rect header;
24855  int is_clicked = nk_false;
24856  enum nk_widget_layout_states s;
24857  const struct nk_style_item *background;
24858  struct nk_color symbol_color;
24859  struct nk_text text;
24860 
24861  NK_ASSERT(ctx);
24862  NK_ASSERT(ctx->current);
24863  NK_ASSERT(ctx->current->layout);
24864  if (!ctx || !ctx->current || !ctx->current->layout)
24865  return 0;
24866 
24867  win = ctx->current;
24868  style = &ctx->style;
24869  s = nk_widget(&header, ctx);
24870  if (!s) return 0;
24871 
24872  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24873  if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
24874  is_clicked = nk_true;
24875 
24876  /* draw combo box header background and border */
24878  background = &style->combo.active;
24879  symbol_color = style->combo.symbol_active;
24880  text.text = style->combo.label_active;
24881  } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
24882  background = &style->combo.hover;
24883  symbol_color = style->combo.symbol_hover;
24884  text.text = style->combo.label_hover;
24885  } else {
24886  background = &style->combo.normal;
24887  symbol_color = style->combo.symbol_normal;
24888  text.text = style->combo.label_normal;
24889  }
24890  if (background->type == NK_STYLE_ITEM_IMAGE) {
24891  text.background = nk_rgba(0,0,0,0);
24892  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24893  } else {
24894  text.background = background->data.color;
24895  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24896  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24897  }
24898  {
24899  struct nk_rect content;
24900  struct nk_rect button;
24901  struct nk_rect label;
24902  struct nk_rect image;
24903 
24904  enum nk_symbol_type sym;
24906  sym = style->combo.sym_hover;
24907  else if (is_clicked)
24908  sym = style->combo.sym_active;
24909  else sym = style->combo.sym_normal;
24910 
24911  /* calculate button */
24912  button.w = header.h - 2 * style->combo.button_padding.y;
24913  button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
24914  button.y = header.y + style->combo.button_padding.y;
24915  button.h = button.w;
24916 
24917  content.x = button.x + style->combo.button.padding.x;
24918  content.y = button.y + style->combo.button.padding.y;
24919  content.w = button.w - 2 * style->combo.button.padding.x;
24920  content.h = button.h - 2 * style->combo.button.padding.y;
24921  nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
24922  &ctx->style.combo.button, sym, style->font);
24923 
24924  /* draw symbol */
24925  image.x = header.x + style->combo.content_padding.x;
24926  image.y = header.y + style->combo.content_padding.y;
24927  image.h = header.h - 2 * style->combo.content_padding.y;
24928  image.w = image.h;
24929  nk_draw_symbol(&win->buffer, symbol, image, text.background, symbol_color,
24930  1.0f, style->font);
24931 
24932  /* draw label */
24933  text.padding = nk_vec2(0,0);
24934  label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
24935  label.y = header.y + style->combo.content_padding.y;
24936  label.w = (button.x - style->combo.content_padding.x) - label.x;
24937  label.h = header.h - 2 * style->combo.content_padding.y;
24938  nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
24939  }
24940  return nk_combo_begin(ctx, win, size, is_clicked, header);
24941 }
24942 NK_API int
24943 nk_combo_begin_image(struct nk_context *ctx, struct nk_image img, struct nk_vec2 size)
24944 {
24945  struct nk_window *win;
24946  struct nk_style *style;
24947  const struct nk_input *in;
24948 
24949  struct nk_rect header;
24950  int is_clicked = nk_false;
24951  enum nk_widget_layout_states s;
24952  const struct nk_style_item *background;
24953 
24954  NK_ASSERT(ctx);
24955  NK_ASSERT(ctx->current);
24956  NK_ASSERT(ctx->current->layout);
24957  if (!ctx || !ctx->current || !ctx->current->layout)
24958  return 0;
24959 
24960  win = ctx->current;
24961  style = &ctx->style;
24962  s = nk_widget(&header, ctx);
24963  if (s == NK_WIDGET_INVALID)
24964  return 0;
24965 
24966  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24967  if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
24968  is_clicked = nk_true;
24969 
24970  /* draw combo box header background and border */
24972  background = &style->combo.active;
24973  else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
24974  background = &style->combo.hover;
24975  else background = &style->combo.normal;
24976 
24977  if (background->type == NK_STYLE_ITEM_IMAGE) {
24978  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24979  } else {
24980  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24981  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24982  }
24983  {
24984  struct nk_rect bounds = {0,0,0,0};
24985  struct nk_rect content;
24986  struct nk_rect button;
24987 
24988  enum nk_symbol_type sym;
24990  sym = style->combo.sym_hover;
24991  else if (is_clicked)
24992  sym = style->combo.sym_active;
24993  else sym = style->combo.sym_normal;
24994 
24995  /* calculate button */
24996  button.w = header.h - 2 * style->combo.button_padding.y;
24997  button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
24998  button.y = header.y + style->combo.button_padding.y;
24999  button.h = button.w;
25000 
25001  content.x = button.x + style->combo.button.padding.x;
25002  content.y = button.y + style->combo.button.padding.y;
25003  content.w = button.w - 2 * style->combo.button.padding.x;
25004  content.h = button.h - 2 * style->combo.button.padding.y;
25005 
25006  /* draw image */
25007  bounds.h = header.h - 2 * style->combo.content_padding.y;
25008  bounds.y = header.y + style->combo.content_padding.y;
25009  bounds.x = header.x + style->combo.content_padding.x;
25010  bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
25011  nk_draw_image(&win->buffer, bounds, &img, nk_white);
25012 
25013  /* draw open/close button */
25014  nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
25015  &ctx->style.combo.button, sym, style->font);
25016  }
25017  return nk_combo_begin(ctx, win, size, is_clicked, header);
25018 }
25019 NK_API int
25020 nk_combo_begin_image_text(struct nk_context *ctx, const char *selected, int len,
25021  struct nk_image img, struct nk_vec2 size)
25022 {
25023  struct nk_window *win;
25024  struct nk_style *style;
25025  struct nk_input *in;
25026 
25027  struct nk_rect header;
25028  int is_clicked = nk_false;
25029  enum nk_widget_layout_states s;
25030  const struct nk_style_item *background;
25031  struct nk_text text;
25032 
25033  NK_ASSERT(ctx);
25034  NK_ASSERT(ctx->current);
25035  NK_ASSERT(ctx->current->layout);
25036  if (!ctx || !ctx->current || !ctx->current->layout)
25037  return 0;
25038 
25039  win = ctx->current;
25040  style = &ctx->style;
25041  s = nk_widget(&header, ctx);
25042  if (!s) return 0;
25043 
25044  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
25045  if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
25046  is_clicked = nk_true;
25047 
25048  /* draw combo box header background and border */
25050  background = &style->combo.active;
25051  text.text = style->combo.label_active;
25052  } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
25053  background = &style->combo.hover;
25054  text.text = style->combo.label_hover;
25055  } else {
25056  background = &style->combo.normal;
25057  text.text = style->combo.label_normal;
25058  }
25059  if (background->type == NK_STYLE_ITEM_IMAGE) {
25060  text.background = nk_rgba(0,0,0,0);
25061  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
25062  } else {
25063  text.background = background->data.color;
25064  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
25065  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
25066  }
25067  {
25068  struct nk_rect content;
25069  struct nk_rect button;
25070  struct nk_rect label;
25071  struct nk_rect image;
25072 
25073  enum nk_symbol_type sym;
25075  sym = style->combo.sym_hover;
25076  else if (is_clicked)
25077  sym = style->combo.sym_active;
25078  else sym = style->combo.sym_normal;
25079 
25080  /* calculate button */
25081  button.w = header.h - 2 * style->combo.button_padding.y;
25082  button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
25083  button.y = header.y + style->combo.button_padding.y;
25084  button.h = button.w;
25085 
25086  content.x = button.x + style->combo.button.padding.x;
25087  content.y = button.y + style->combo.button.padding.y;
25088  content.w = button.w - 2 * style->combo.button.padding.x;
25089  content.h = button.h - 2 * style->combo.button.padding.y;
25090  nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
25091  &ctx->style.combo.button, sym, style->font);
25092 
25093  /* draw image */
25094  image.x = header.x + style->combo.content_padding.x;
25095  image.y = header.y + style->combo.content_padding.y;
25096  image.h = header.h - 2 * style->combo.content_padding.y;
25097  image.w = image.h;
25098  nk_draw_image(&win->buffer, image, &img, nk_white);
25099 
25100  /* draw label */
25101  text.padding = nk_vec2(0,0);
25102  label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
25103  label.y = header.y + style->combo.content_padding.y;
25104  label.w = (button.x - style->combo.content_padding.x) - label.x;
25105  label.h = header.h - 2 * style->combo.content_padding.y;
25106  nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
25107  }
25108  return nk_combo_begin(ctx, win, size, is_clicked, header);
25109 }
25110 NK_API int
25112  const char *selected, enum nk_symbol_type type, struct nk_vec2 size)
25113 {
25114  return nk_combo_begin_symbol_text(ctx, selected, nk_strlen(selected), type, size);
25115 }
25116 NK_API int
25118  const char *selected, struct nk_image img, struct nk_vec2 size)
25119 {
25120  return nk_combo_begin_image_text(ctx, selected, nk_strlen(selected), img, size);
25121 }
25122 NK_API int
25123 nk_combo_item_text(struct nk_context *ctx, const char *text, int len,nk_flags align)
25124 {
25125  return nk_contextual_item_text(ctx, text, len, align);
25126 }
25127 NK_API int
25128 nk_combo_item_label(struct nk_context *ctx, const char *label, nk_flags align)
25129 {
25130  return nk_contextual_item_label(ctx, label, align);
25131 }
25132 NK_API int
25133 nk_combo_item_image_text(struct nk_context *ctx, struct nk_image img, const char *text,
25134  int len, nk_flags alignment)
25135 {
25136  return nk_contextual_item_image_text(ctx, img, text, len, alignment);
25137 }
25138 NK_API int
25139 nk_combo_item_image_label(struct nk_context *ctx, struct nk_image img,
25140  const char *text, nk_flags alignment)
25141 {
25142  return nk_contextual_item_image_label(ctx, img, text, alignment);
25143 }
25144 NK_API int
25146  const char *text, int len, nk_flags alignment)
25147 {
25148  return nk_contextual_item_symbol_text(ctx, sym, text, len, alignment);
25149 }
25150 NK_API int
25152  const char *label, nk_flags alignment)
25153 {
25154  return nk_contextual_item_symbol_label(ctx, sym, label, alignment);
25155 }
25156 NK_API void nk_combo_end(struct nk_context *ctx)
25157 {
25158  nk_contextual_end(ctx);
25159 }
25160 NK_API void nk_combo_close(struct nk_context *ctx)
25161 {
25162  nk_contextual_close(ctx);
25163 }
25164 NK_API int
25165 nk_combo(struct nk_context *ctx, const char **items, int count,
25166  int selected, int item_height, struct nk_vec2 size)
25167 {
25168  int i = 0;
25169  int max_height;
25170  struct nk_vec2 item_spacing;
25171  struct nk_vec2 window_padding;
25172 
25173  NK_ASSERT(ctx);
25174  NK_ASSERT(items);
25175  NK_ASSERT(ctx->current);
25176  if (!ctx || !items ||!count)
25177  return selected;
25178 
25179  item_spacing = ctx->style.window.spacing;
25180  window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
25181  max_height = count * item_height + count * (int)item_spacing.y;
25182  max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
25183  size.y = NK_MIN(size.y, (float)max_height);
25184  if (nk_combo_begin_label(ctx, items[selected], size)) {
25185  nk_layout_row_dynamic(ctx, (float)item_height, 1);
25186  for (i = 0; i < count; ++i) {
25187  if (nk_combo_item_label(ctx, items[i], NK_TEXT_LEFT))
25188  selected = i;
25189  }
25190  nk_combo_end(ctx);
25191  }
25192  return selected;
25193 }
25194 NK_API int
25195 nk_combo_separator(struct nk_context *ctx, const char *items_separated_by_separator,
25196  int separator, int selected, int count, int item_height, struct nk_vec2 size)
25197 {
25198  int i;
25199  int max_height;
25200  struct nk_vec2 item_spacing;
25201  struct nk_vec2 window_padding;
25202  const char *current_item;
25203  const char *iter;
25204  int length = 0;
25205 
25206  NK_ASSERT(ctx);
25207  NK_ASSERT(items_separated_by_separator);
25208  if (!ctx || !items_separated_by_separator)
25209  return selected;
25210 
25211  /* calculate popup window */
25212  item_spacing = ctx->style.window.spacing;
25213  window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
25214  max_height = count * item_height + count * (int)item_spacing.y;
25215  max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
25216  size.y = NK_MIN(size.y, (float)max_height);
25217 
25218  /* find selected item */
25219  current_item = items_separated_by_separator;
25220  for (i = 0; i < count; ++i) {
25221  iter = current_item;
25222  while (*iter && *iter != separator) iter++;
25223  length = (int)(iter - current_item);
25224  if (i == selected) break;
25225  current_item = iter + 1;
25226  }
25227 
25228  if (nk_combo_begin_text(ctx, current_item, length, size)) {
25229  current_item = items_separated_by_separator;
25230  nk_layout_row_dynamic(ctx, (float)item_height, 1);
25231  for (i = 0; i < count; ++i) {
25232  iter = current_item;
25233  while (*iter && *iter != separator) iter++;
25234  length = (int)(iter - current_item);
25235  if (nk_combo_item_text(ctx, current_item, length, NK_TEXT_LEFT))
25236  selected = i;
25237  current_item = current_item + length + 1;
25238  }
25239  nk_combo_end(ctx);
25240  }
25241  return selected;
25242 }
25243 NK_API int
25244 nk_combo_string(struct nk_context *ctx, const char *items_separated_by_zeros,
25245  int selected, int count, int item_height, struct nk_vec2 size)
25246 {
25247  return nk_combo_separator(ctx, items_separated_by_zeros, '\0', selected, count, item_height, size);
25248 }
25249 NK_API int
25250 nk_combo_callback(struct nk_context *ctx, void(*item_getter)(void*, int, const char**),
25251  void *userdata, int selected, int count, int item_height, struct nk_vec2 size)
25252 {
25253  int i;
25254  int max_height;
25255  struct nk_vec2 item_spacing;
25256  struct nk_vec2 window_padding;
25257  const char *item;
25258 
25259  NK_ASSERT(ctx);
25260  NK_ASSERT(item_getter);
25261  if (!ctx || !item_getter)
25262  return selected;
25263 
25264  /* calculate popup window */
25265  item_spacing = ctx->style.window.spacing;
25266  window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
25267  max_height = count * item_height + count * (int)item_spacing.y;
25268  max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
25269  size.y = NK_MIN(size.y, (float)max_height);
25270 
25271  item_getter(userdata, selected, &item);
25272  if (nk_combo_begin_label(ctx, item, size)) {
25273  nk_layout_row_dynamic(ctx, (float)item_height, 1);
25274  for (i = 0; i < count; ++i) {
25275  item_getter(userdata, i, &item);
25276  if (nk_combo_item_label(ctx, item, NK_TEXT_LEFT))
25277  selected = i;
25278  }
25279  nk_combo_end(ctx);
25280  } return selected;
25281 }
25282 NK_API void
25283 nk_combobox(struct nk_context *ctx, const char **items, int count,
25284  int *selected, int item_height, struct nk_vec2 size)
25285 {
25286  *selected = nk_combo(ctx, items, count, *selected, item_height, size);
25287 }
25288 NK_API void
25289 nk_combobox_string(struct nk_context *ctx, const char *items_separated_by_zeros,
25290  int *selected, int count, int item_height, struct nk_vec2 size)
25291 {
25292  *selected = nk_combo_string(ctx, items_separated_by_zeros, *selected, count, item_height, size);
25293 }
25294 NK_API void
25295 nk_combobox_separator(struct nk_context *ctx, const char *items_separated_by_separator,
25296  int separator,int *selected, int count, int item_height, struct nk_vec2 size)
25297 {
25298  *selected = nk_combo_separator(ctx, items_separated_by_separator, separator,
25299  *selected, count, item_height, size);
25300 }
25301 NK_API void
25302 nk_combobox_callback(struct nk_context *ctx,
25303  void(*item_getter)(void* data, int id, const char **out_text),
25304  void *userdata, int *selected, int count, int item_height, struct nk_vec2 size)
25305 {
25306  *selected = nk_combo_callback(ctx, item_getter, userdata, *selected, count, item_height, size);
25307 }
25308 
25309 
25310 
25311 
25312 
25313 /* ===============================================================
25314  *
25315  * TOOLTIP
25316  *
25317  * ===============================================================*/
25318 NK_API int
25319 nk_tooltip_begin(struct nk_context *ctx, float width)
25320 {
25321  int x,y,w,h;
25322  struct nk_window *win;
25323  const struct nk_input *in;
25324  struct nk_rect bounds;
25325  int ret;
25326 
25327  NK_ASSERT(ctx);
25328  NK_ASSERT(ctx->current);
25329  NK_ASSERT(ctx->current->layout);
25330  if (!ctx || !ctx->current || !ctx->current->layout)
25331  return 0;
25332 
25333  /* make sure that no nonblocking popup is currently active */
25334  win = ctx->current;
25335  in = &ctx->input;
25337  return 0;
25338 
25339  w = nk_iceilf(width);
25340  h = nk_iceilf(nk_null_rect.h);
25341  x = nk_ifloorf(in->mouse.pos.x + 1) - (int)win->layout->clip.x;
25342  y = nk_ifloorf(in->mouse.pos.y + 1) - (int)win->layout->clip.y;
25343 
25344  bounds.x = (float)x;
25345  bounds.y = (float)y;
25346  bounds.w = (float)w;
25347  bounds.h = (float)h;
25348 
25349  ret = nk_popup_begin(ctx, NK_POPUP_DYNAMIC,
25350  "__##Tooltip##__", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER, bounds);
25351  if (ret) win->layout->flags &= ~(nk_flags)NK_WINDOW_ROM;
25354  return ret;
25355 }
25356 
25357 NK_API void
25358 nk_tooltip_end(struct nk_context *ctx)
25359 {
25360  NK_ASSERT(ctx);
25361  NK_ASSERT(ctx->current);
25362  if (!ctx || !ctx->current) return;
25363  ctx->current->seq--;
25364  nk_popup_close(ctx);
25365  nk_popup_end(ctx);
25366 }
25367 NK_API void
25368 nk_tooltip(struct nk_context *ctx, const char *text)
25369 {
25370  const struct nk_style *style;
25371  struct nk_vec2 padding;
25372 
25373  int text_len;
25374  float text_width;
25375  float text_height;
25376 
25377  NK_ASSERT(ctx);
25378  NK_ASSERT(ctx->current);
25379  NK_ASSERT(ctx->current->layout);
25380  NK_ASSERT(text);
25381  if (!ctx || !ctx->current || !ctx->current->layout || !text)
25382  return;
25383 
25384  /* fetch configuration data */
25385  style = &ctx->style;
25386  padding = style->window.padding;
25387 
25388  /* calculate size of the text and tooltip */
25389  text_len = nk_strlen(text);
25390  text_width = style->font->width(style->font->userdata,
25391  style->font->height, text, text_len);
25392  text_width += (4 * padding.x);
25393  text_height = (style->font->height + 2 * padding.y);
25394 
25395  /* execute tooltip and fill with text */
25396  if (nk_tooltip_begin(ctx, (float)text_width)) {
25397  nk_layout_row_dynamic(ctx, (float)text_height, 1);
25398  nk_text(ctx, text, text_len, NK_TEXT_LEFT);
25399  nk_tooltip_end(ctx);
25400  }
25401 }
25402 #ifdef NK_INCLUDE_STANDARD_VARARGS
25403 NK_API void
25404 nk_tooltipf(struct nk_context *ctx, const char *fmt, ...)
25405 {
25406  va_list args;
25407  va_start(args, fmt);
25408  nk_tooltipfv(ctx, fmt, args);
25409  va_end(args);
25410 }
25411 NK_API void
25412 nk_tooltipfv(struct nk_context *ctx, const char *fmt, va_list args)
25413 {
25414  char buf[256];
25415  nk_strfmt(buf, NK_LEN(buf), fmt, args);
25416  nk_tooltip(ctx, buf);
25417 }
25418 #endif
25419 
25420 
25421 
25422 #endif /* NK_IMPLEMENTATION */
25423 
25424 /*
25467 
25779 */
25780 
nk_edit_state::sel_start
int sel_start
Definition: nuklear.h:5388
nk_color_hex_rgb
NK_API void nk_color_hex_rgb(char *output, struct nk_color)
NK_COMMAND_RECT
@ NK_COMMAND_RECT
Definition: nuklear.h:4379
nk_command_custom::callback_data
nk_handle callback_data
Definition: nuklear.h:4541
nk_command_clipping
nk_command_clipping
Definition: nuklear.h:4557
nk_rect_size
NK_API struct nk_vec2 nk_rect_size(struct nk_rect)
nk_keyboard::text_len
int text_len
Definition: nuklear.h:4622
nk_group_end
NK_API void nk_group_end(struct nk_context *)
nk_str
Definition: nuklear.h:4164
NK_INT32
#define NK_INT32
Definition: nuklear.h:356
NK_WINDOW_BORDER
@ NK_WINDOW_BORDER
Definition: nuklear.h:1451
NK_COMMAND_CIRCLE_FILLED
@ NK_COMMAND_CIRCLE_FILLED
Definition: nuklear.h:4383
NK_TEXT_ALIGN_MIDDLE
@ NK_TEXT_ALIGN_MIDDLE
Definition: nuklear.h:3077
nk_style_toggle::cursor_normal
struct nk_style_item cursor_normal
Definition: nuklear.h:4860
nk_menu_close
NK_API void nk_menu_close(struct nk_context *)
nk_memory_status::type
unsigned int type
Definition: nuklear.h:4094
nk_style_tab::border
float border
Definition: nuklear.h:5139
NK_WIDGET_ROM
@ NK_WIDGET_ROM
Definition: nuklear.h:3044
nk_style_text::color
struct nk_color color
Definition: nuklear.h:4821
nk_style_header_align
nk_style_header_align
Definition: nuklear.h:5146
NK_TEXT_ALIGN_CENTERED
@ NK_TEXT_ALIGN_CENTERED
Definition: nuklear.h:3074
nk_style_selectable::pressed_active
struct nk_style_item pressed_active
Definition: nuklear.h:4891
nk_style_property::rounding
float rounding
Definition: nuklear.h:5067
nk_command_polygon_filled::point_count
unsigned short point_count
Definition: nuklear.h:4515
nk_configuration_stacks::vectors
struct nk_config_stack_vec2 vectors
Definition: nuklear.h:5519
nk_style_window::spacing
struct nk_vec2 spacing
Definition: nuklear.h:5199
nk_command_polygon::color
struct nk_color color
Definition: nuklear.h:4506
NK_WINDOW_MINIMIZABLE
@ NK_WINDOW_MINIMIZABLE
Definition: nuklear.h:1455
nk_command_image::col
struct nk_color col
Definition: nuklear.h:4532
nk_style_pop_font
NK_API int nk_style_pop_font(struct nk_context *)
NK_RGB
@ NK_RGB
Definition: nuklear.h:477
nk_int
NK_INT32 nk_int
Definition: nuklear.h:403
nk_select_label
NK_API int nk_select_label(struct nk_context *, const char *, nk_flags align, int value)
nk_button_color
NK_API int nk_button_color(struct nk_context *, struct nk_color)
nk_pool::cap
nk_size cap
Definition: nuklear.h:5566
nk_combobox_callback
NK_API void nk_combobox_callback(struct nk_context *, void(*item_getter)(void *, int, const char **), void *, int *selected, int count, int item_height, struct nk_vec2 size)
nk_command_rect_filled::x
short x
Definition: nuklear.h:4440
nk_window_get_panel
NK_API struct nk_panel * nk_window_get_panel(struct nk_context *)
nk_style_combo::label_hover
struct nk_color label_hover
Definition: nuklear.h:5102
nk_window
Definition: nuklear.h:5408
nk_style_window::group_border
float group_border
Definition: nuklear.h:5193
NK_CONVERT_COMMAND_BUFFER_FULL
@ NK_CONVERT_COMMAND_BUFFER_FULL
Definition: nuklear.h:1146
nk_style_chart::background
struct nk_style_item background
Definition: nuklear.h:5082
nk_combo_begin_image
NK_API int nk_combo_begin_image(struct nk_context *, struct nk_image img, struct nk_vec2 size)
nk_style_progress::padding
struct nk_vec2 padding
Definition: nuklear.h:4974
nk_style_scrollbar::border
float border
Definition: nuklear.h:4996
nk_window_get_content_region_min
NK_API struct nk_vec2 nk_window_get_content_region_min(struct nk_context *)
NK_COLOR_BUTTON_HOVER
@ NK_COLOR_BUTTON_HOVER
Definition: nuklear.h:3567
nk_buffer_memory_const
const NK_API void * nk_buffer_memory_const(const struct nk_buffer *)
nk_style_selectable::text_hover_active
struct nk_color text_hover_active
Definition: nuklear.h:4900
nk_row_layout::item_width
float item_width
Definition: nuklear.h:5303
nk_hsv_bv
NK_API struct nk_color nk_hsv_bv(const nk_byte *hsv)
nk_handle::ptr
void * ptr
Definition: nuklear.h:464
nk_image_id
NK_API struct nk_image nk_image_id(int)
nk_style_slider::inc_button
struct nk_style_button inc_button
Definition: nuklear.h:4945
nk_context::button_behavior
enum nk_button_behavior button_behavior
Definition: nuklear.h:5576
NK_KEY_CUT
@ NK_KEY_CUT
Definition: nuklear.h:744
nk_row_layout::min_height
float min_height
Definition: nuklear.h:5300
NK_ALIGN_PTR_BACK
#define NK_ALIGN_PTR_BACK(x, mask)
Definition: nuklear.h:5658
NK_EDIT_READ_ONLY
@ NK_EDIT_READ_ONLY
Definition: nuklear.h:3417
nk_command_triangle_filled::color
struct nk_color color
Definition: nuklear.h:4469
nk_color_hsv_iv
NK_API void nk_color_hsv_iv(int *hsv_out, struct nk_color)
NK_COMMAND_NOP
@ NK_COMMAND_NOP
Definition: nuklear.h:4375
NK_KEY_NONE
@ NK_KEY_NONE
Definition: nuklear.h:736
NK_CONVERT_VERTEX_BUFFER_FULL
@ NK_CONVERT_VERTEX_BUFFER_FULL
Definition: nuklear.h:1147
nk_edit_state::sel_end
int sel_end
Definition: nuklear.h:5389
nk_command_polygon::point_count
unsigned short point_count
Definition: nuklear.h:4508
nk_vec2v
NK_API struct nk_vec2 nk_vec2v(const float *xy)
nk_menu_item_label
NK_API int nk_menu_item_label(struct nk_context *, const char *, nk_flags alignment)
nk_str_init_fixed
NK_API void nk_str_init_fixed(struct nk_str *, void *memory, nk_size size)
nk_command_triangle
Definition: nuklear.h:4455
nk_command_arc_filled
Definition: nuklear.h:4496
nk_style_slider::active
struct nk_style_item active
Definition: nuklear.h:4921
nk_command_polyline::point_count
unsigned short point_count
Definition: nuklear.h:4523
nk_menu_item_text
NK_API int nk_menu_item_text(struct nk_context *, const char *, int, nk_flags align)
nk_recti
Definition: nuklear.h:462
nk_panel::menu
struct nk_menu_state menu
Definition: nuklear.h:5337
nk_command_scissor::x
short x
Definition: nuklear.h:4407
nk_command_circle
Definition: nuklear.h:4472
nk_style_slider::rounding
float rounding
Definition: nuklear.h:4937
nk_command_polygon
Definition: nuklear.h:4504
nk_edit_string_zero_terminated
NK_API nk_flags nk_edit_string_zero_terminated(struct nk_context *, nk_flags, char *buffer, int max, nk_plugin_filter)
nk_colorf
Definition: nuklear.h:458
nk_rgba_bv
NK_API struct nk_color nk_rgba_bv(const nk_byte *rgba)
NK_TEXT_EDIT_MODE_INSERT
@ NK_TEXT_EDIT_MODE_INSERT
Definition: nuklear.h:4276
nk_command_text::w
unsigned short w
Definition: nuklear.h:4551
nk_rgb_iv
NK_API struct nk_color nk_rgb_iv(const int *rgb)
nk_layout_space_rect_to_local
NK_API struct nk_rect nk_layout_space_rect_to_local(struct nk_context *, struct nk_rect)
NK_BUTTON_MIDDLE
@ NK_BUTTON_MIDDLE
Definition: nuklear.h:772
nk_style_edit::text_active
struct nk_color text_active
Definition: nuklear.h:5032
NK_COLOR_CHART_COLOR_HIGHLIGHT
@ NK_COLOR_CHART_COLOR_HIGHLIGHT
Definition: nuklear.h:3584
nk_layout_widget_bounds
NK_API struct nk_rect nk_layout_widget_bounds(struct nk_context *)
nk_chart_event
nk_chart_event
Definition: nuklear.h:476
nk_rectv
NK_API struct nk_rect nk_rectv(const float *xywh)
nk_window::edit
struct nk_edit_state edit
Definition: nuklear.h:5423
nk_memory_status::calls
nk_size calls
Definition: nuklear.h:4098
NK_CHART_MAX_SLOT
#define NK_CHART_MAX_SLOT
Definition: nuklear.h:5249
nk_command_rect::w
unsigned short w
Definition: nuklear.h:4433
nk_buffer
Definition: nuklear.h:4118
nk_command_line
Definition: nuklear.h:4411
NK_COLOR_TEXT
@ NK_COLOR_TEXT
Definition: nuklear.h:3562
nk_pool::capacity
unsigned capacity
Definition: nuklear.h:5564
nk_str_delete_chars
NK_API void nk_str_delete_chars(struct nk_str *, int pos, int len)
nk_edit_state::name
nk_hash name
Definition: nuklear.h:5383
nk_rgba_fv
NK_API struct nk_color nk_rgba_fv(const float *rgba)
nk_style_push_float
NK_API int nk_style_push_float(struct nk_context *, float *, float)
nk_combo_item_label
NK_API int nk_combo_item_label(struct nk_context *, const char *, nk_flags alignment)
nk_vec2i::x
short x
Definition: nuklear.h:460
nk_ptr
NK_POINTER_TYPE nk_ptr
Definition: nuklear.h:406
nk_byte
NK_UINT8 nk_byte
Definition: nuklear.h:400
nk_command_polygon_filled::points
struct nk_vec2i points[1]
Definition: nuklear.h:4516
nk_table
Definition: nuklear.h:5532
nk_contextual_item_image_text
NK_API int nk_contextual_item_image_text(struct nk_context *, struct nk_image, const char *, int len, nk_flags alignment)
nk_style_slider::bar_active
struct nk_color bar_active
Definition: nuklear.h:4927
nk_command_circle_filled::y
short y
Definition: nuklear.h:4482
nk_str_insert_str_utf8
NK_API int nk_str_insert_str_utf8(struct nk_str *, int pos, const char *)
nk_convert_result
nk_convert_result
Definition: nuklear.h:1143
NK_BUFFER_FIXED
@ NK_BUFFER_FIXED
Definition: nuklear.h:4102
NK_EDIT_INACTIVE
@ NK_EDIT_INACTIVE
Definition: nuklear.h:3438
nk_panel_flags
nk_panel_flags
Definition: nuklear.h:1450
nk_style::combo
struct nk_style_combo combo
Definition: nuklear.h:5234
nk_convert_config::null
struct nk_draw_null_texture null
Definition: nuklear.h:1161
NK_COLOR_SELECT_ACTIVE
@ NK_COLOR_SELECT_ACTIVE
Definition: nuklear.h:3573
NK_FONT_STACK_SIZE
#define NK_FONT_STACK_SIZE
Definition: nuklear.h:5465
nk_style_text::padding
struct nk_vec2 padding
Definition: nuklear.h:4822
nk_command_rect_filled::w
unsigned short w
Definition: nuklear.h:4441
nk_style_toggle
Definition: nuklear.h:4852
nk_rgba_u32
NK_API struct nk_color nk_rgba_u32(nk_uint)
nk_style_from_table
NK_API void nk_style_from_table(struct nk_context *, const struct nk_color *)
NK_UTF_INVALID
#define NK_UTF_INVALID
Definition: nuklear.h:5614
nk_command_text::h
unsigned short h
Definition: nuklear.h:4551
nk_input_is_key_pressed
NK_API int nk_input_is_key_pressed(const struct nk_input *, enum nk_keys)
NK_STYLE_ITEM_IMAGE
@ NK_STYLE_ITEM_IMAGE
Definition: nuklear.h:4807
nk_context::clip
struct nk_clipboard clip
Definition: nuklear.h:5574
nk_rgb_bv
NK_API struct nk_color nk_rgb_bv(const nk_byte *rgb)
nk_tree_state_push
NK_API int nk_tree_state_push(struct nk_context *, enum nk_tree_type, const char *title, enum nk_collapse_states *state)
NK_WINDOW_NO_SCROLLBAR
@ NK_WINDOW_NO_SCROLLBAR
Definition: nuklear.h:1456
nk_window_collapse
NK_API void nk_window_collapse(struct nk_context *, const char *name, enum nk_collapse_states state)
nk_style_selectable::text_pressed
struct nk_color text_pressed
Definition: nuklear.h:4896
nk_symbol_type
nk_symbol_type
Definition: nuklear.h:493
nk_textedit_select_all
NK_API void nk_textedit_select_all(struct nk_text_edit *)
nk_style_scrollbar::dec_button
struct nk_style_button dec_button
Definition: nuklear.h:5005
NK_EDIT_SELECTABLE
@ NK_EDIT_SELECTABLE
Definition: nuklear.h:3422
nk_command_rect::rounding
unsigned short rounding
Definition: nuklear.h:4430
nk_button_image_label
NK_API int nk_button_image_label(struct nk_context *, struct nk_image img, const char *, nk_flags text_alignment)
nk_popup_buffer::active
int active
Definition: nuklear.h:5317
NK_COLOR_WINDOW
@ NK_COLOR_WINDOW
Definition: nuklear.h:3563
nk_combo_item_symbol_text
NK_API int nk_combo_item_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment)
nk_page::win
struct nk_page_element win[1]
Definition: nuklear.h:5555
nk_layout_row_end
NK_API void nk_layout_row_end(struct nk_context *)
nk_str_insert_at_rune
NK_API int nk_str_insert_at_rune(struct nk_str *, int pos, const char *, int)
NK_COMMAND_TRIANGLE_FILLED
@ NK_COMMAND_TRIANGLE_FILLED
Definition: nuklear.h:4387
nk_style::cursor_visible
int cursor_visible
Definition: nuklear.h:5217
nk_style_slider::dec_button
struct nk_style_button dec_button
Definition: nuklear.h:4946
nk_fill_circle
NK_API void nk_fill_circle(struct nk_command_buffer *, struct nk_rect, struct nk_color)
NK_TEXT_ALIGN_BOTTOM
@ NK_TEXT_ALIGN_BOTTOM
Definition: nuklear.h:3078
nk_command_polygon_filled::header
struct nk_command header
Definition: nuklear.h:4513
NK_TREE_TAB
@ NK_TREE_TAB
Definition: nuklear.h:480
nk_style_edit::selected_text_hover
struct nk_color selected_text_hover
Definition: nuklear.h:5038
NK_WINDOW_MINIMIZED
@ NK_WINDOW_MINIMIZED
Definition: nuklear.h:5364
nk_text_undo_record::insert_length
short insert_length
Definition: nuklear.h:4255
nk_window::property
struct nk_property_state property
Definition: nuklear.h:5421
nk_color_hsv_fv
NK_API void nk_color_hsv_fv(float *hsv_out, struct nk_color)
nk_chart::x
float x
Definition: nuklear.h:5280
nk_panel_type
nk_panel_type
Definition: nuklear.h:5252
NK_LAYOUT_DYNAMIC_ROW
@ NK_LAYOUT_DYNAMIC_ROW
Definition: nuklear.h:5286
nk_text_width_f
float(* nk_text_width_f)(nk_handle, float h, const char *, int len)
Definition: nuklear.h:3896
nk_style::scrollv
struct nk_style_scrollbar scrollv
Definition: nuklear.h:5232
nk_style_window::menu_border_color
struct nk_color menu_border_color
Definition: nuklear.h:5184
nk_property_float
NK_API void nk_property_float(struct nk_context *, const char *name, float min, float *val, float max, float step, float inc_per_pixel)
nk_widget_is_hovered
NK_API int nk_widget_is_hovered(struct nk_context *)
nk_command_buffer::userdata
nk_handle userdata
Definition: nuklear.h:4566
nk_style_window::fixed_background
struct nk_style_item fixed_background
Definition: nuklear.h:5177
nk_button_text_styled
NK_API int nk_button_text_styled(struct nk_context *, const struct nk_style_button *, const char *title, int len)
nk_style_edit::selected_hover
struct nk_color selected_hover
Definition: nuklear.h:5036
nk_stroke_circle
NK_API void nk_stroke_circle(struct nk_command_buffer *, struct nk_rect, float line_thickness, struct nk_color)
nk_command_scissor::header
struct nk_command header
Definition: nuklear.h:4406
nk_style_scrollbar::dec_symbol
enum nk_symbol_type dec_symbol
Definition: nuklear.h:5007
nk_style_combo::hover
struct nk_style_item hover
Definition: nuklear.h:5096
nk_user_font::height
float height
Definition: nuklear.h:3917
nk_command
Definition: nuklear.h:4397
NK_TEXT_EDIT_SINGLE_LINE
@ NK_TEXT_EDIT_SINGLE_LINE
Definition: nuklear.h:4270
nk_context::delta_time_seconds
float delta_time_seconds
Definition: nuklear.h:5578
NK_EDIT_DEACTIVATED
@ NK_EDIT_DEACTIVATED
Definition: nuklear.h:3440
NK_COLOR_SLIDER_CURSOR_HOVER
@ NK_COLOR_SLIDER_CURSOR_HOVER
Definition: nuklear.h:3576
nk_allocator::alloc
nk_plugin_alloc alloc
Definition: nuklear.h:490
nk_buffer::needed
nk_size needed
Definition: nuklear.h:4131
NK_WINDOW_DYNAMIC
@ NK_WINDOW_DYNAMIC
Definition: nuklear.h:5354
nk_style_progress::cursor_hover
struct nk_style_item cursor_hover
Definition: nuklear.h:4965
nk_edit_state::cursor
int cursor
Definition: nuklear.h:5387
nk_style_progress::cursor_border
float cursor_border
Definition: nuklear.h:4972
NK_WINDOW_SCROLL_AUTO_HIDE
@ NK_WINDOW_SCROLL_AUTO_HIDE
Definition: nuklear.h:1458
nk_style::property
struct nk_style_property property
Definition: nuklear.h:5228
NK_POPUP_STATIC
@ NK_POPUP_STATIC
Definition: nuklear.h:478
nk_style_window::group_padding
struct nk_vec2 group_padding
Definition: nuklear.h:5204
nk_style_window::menu_border
float menu_border
Definition: nuklear.h:5192
nk_keyboard
Definition: nuklear.h:4619
NK_KEY_TEXT_REPLACE_MODE
@ NK_KEY_TEXT_REPLACE_MODE
Definition: nuklear.h:752
nk_window_set_size
NK_API void nk_window_set_size(struct nk_context *, const char *name, struct nk_vec2)
NK_BUTTON_BEHAVIOR_STACK_SIZE
#define NK_BUTTON_BEHAVIOR_STACK_SIZE
Definition: nuklear.h:5461
nk_input_has_mouse_click_down_in_rect
NK_API int nk_input_has_mouse_click_down_in_rect(const struct nk_input *, enum nk_buttons, struct nk_rect, int down)
nk_style_edit::active
struct nk_style_item active
Definition: nuklear.h:5019
nk_mouse_button
Definition: nuklear.h:4599
NK_KEY_BACKSPACE
@ NK_KEY_BACKSPACE
Definition: nuklear.h:742
nk_vec2_muls
#define nk_vec2_muls(a, t)
Definition: nuklear.h:5632
nk_style_cursor
nk_style_cursor
Definition: nuklear.h:3592
nk_image::region
unsigned short region[4]
Definition: nuklear.h:465
nk_style_window_header::hover
struct nk_style_item hover
Definition: nuklear.h:5153
nk_style_button
Definition: nuklear.h:4825
nk_vec2iv
NK_API struct nk_vec2 nk_vec2iv(const int *xy)
nk_property_state::old
unsigned int old
Definition: nuklear.h:5404
nk_str_delete_runes
NK_API void nk_str_delete_runes(struct nk_str *, int pos, int len)
nk_combo_end
NK_API void nk_combo_end(struct nk_context *)
nk_style_scrollbar::inc_symbol
enum nk_symbol_type inc_symbol
Definition: nuklear.h:5006
nk_edit_state::scrollbar
struct nk_scroll scrollbar
Definition: nuklear.h:5390
nk_heading
nk_heading
Definition: nuklear.h:469
nk_glyph
char nk_glyph[NK_UTF_SIZE]
Definition: nuklear.h:463
nk_window_is_any_hovered
NK_API int nk_window_is_any_hovered(struct nk_context *)
nk_command_buffer::end
nk_size end
Definition: nuklear.h:4567
nk_buffer::calls
nk_size calls
Definition: nuklear.h:4133
nk_panel::offset_y
nk_uint * offset_y
Definition: nuklear.h:5330
nk_style_default
NK_API void nk_style_default(struct nk_context *)
nk_propertyi
NK_API int nk_propertyi(struct nk_context *, const char *name, int min, int val, int max, int step, float inc_per_pixel)
nk_style_window::combo_padding
struct nk_vec2 combo_padding
Definition: nuklear.h:5206
nk_strtod
NK_API double nk_strtod(const char *str, const char **endptr)
nk_layout_space_to_local
NK_API struct nk_vec2 nk_layout_space_to_local(struct nk_context *, struct nk_vec2)
nk_style_tab::rounding
float rounding
Definition: nuklear.h:5140
nk_style_toggle::userdata
nk_handle userdata
Definition: nuklear.h:4877
NK_ALIGNOF
#define NK_ALIGNOF(t)
Definition: nuklear.h:5679
nk_command_custom::h
unsigned short h
Definition: nuklear.h:4540
NK_CHART_HOVERING
@ NK_CHART_HOVERING
Definition: nuklear.h:476
nk_style_progress::userdata
nk_handle userdata
Definition: nuklear.h:4977
nk_command_polyline::header
struct nk_command header
Definition: nuklear.h:4520
nk_combo_item_text
NK_API int nk_combo_item_text(struct nk_context *, const char *, int, nk_flags alignment)
nk_command_circle_filled::header
struct nk_command header
Definition: nuklear.h:4481
nk_style_window::contextual_padding
struct nk_vec2 contextual_padding
Definition: nuklear.h:5207
nk_contextual_begin
NK_API int nk_contextual_begin(struct nk_context *, nk_flags, struct nk_vec2, struct nk_rect trigger_bounds)
nk_chart_slot::type
enum nk_chart_type type
Definition: nuklear.h:5269
nk_handle::id
int id
Definition: nuklear.h:464
nk_memory_status::needed
nk_size needed
Definition: nuklear.h:4097
nk_command_triangle::color
struct nk_color color
Definition: nuklear.h:4461
nk_command_circle::color
struct nk_color color
Definition: nuklear.h:4477
nk_command_rect_multi_color::w
unsigned short w
Definition: nuklear.h:4448
nk_style_slider::inc_symbol
enum nk_symbol_type inc_symbol
Definition: nuklear.h:4947
nk_combobox_separator
NK_API void nk_combobox_separator(struct nk_context *, const char *items_separated_by_separator, int separator, int *selected, int count, int item_height, struct nk_vec2 size)
NK_CLIPPING_OFF
@ NK_CLIPPING_OFF
Definition: nuklear.h:4558
NK_UINT32
#define NK_UINT32
Definition: nuklear.h:363
NK_SYMBOL_PLUS
@ NK_SYMBOL_PLUS
Definition: nuklear.h:505
nk_style_window::contextual_border
float contextual_border
Definition: nuklear.h:5191
nk_style_window::tooltip_border
float tooltip_border
Definition: nuklear.h:5194
nk_widget_position
NK_API struct nk_vec2 nk_widget_position(struct nk_context *)
nk_style::checkbox
struct nk_style_toggle checkbox
Definition: nuklear.h:5224
nk_input
Definition: nuklear.h:4625
nk_style_slider::border_color
struct nk_color border_color
Definition: nuklear.h:4922
nk_style_combo::sym_normal
enum nk_symbol_type sym_normal
Definition: nuklear.h:5112
nk_popup_buffer
Definition: nuklear.h:5312
nk_popup_state::name
nk_hash name
Definition: nuklear.h:5374
nk_panel::bounds
struct nk_rect bounds
Definition: nuklear.h:5328
nk_style_tab::spacing
struct nk_vec2 spacing
Definition: nuklear.h:5143
nk_style_property::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:5077
nk_command_circle_filled::w
unsigned short w
Definition: nuklear.h:4483
nk_command_triangle_filled::c
struct nk_vec2i c
Definition: nuklear.h:4468
NK_CONFIG_STACK
#define NK_CONFIG_STACK(type, size)
Definition: nuklear.h:5493
NK_CLIPPING_ON
@ NK_CLIPPING_ON
Definition: nuklear.h:4559
NK_COLOR_CHART_COLOR
@ NK_COLOR_CHART_COLOR
Definition: nuklear.h:3583
nk_mouse::prev
struct nk_vec2 prev
Definition: nuklear.h:4607
NK_HEADER_RIGHT
@ NK_HEADER_RIGHT
Definition: nuklear.h:5148
nk_style_combo::label_normal
struct nk_color label_normal
Definition: nuklear.h:5101
nk_page_element::next
struct nk_page_element * next
Definition: nuklear.h:5548
nk_contextual_item_text
NK_API int nk_contextual_item_text(struct nk_context *, const char *, int, nk_flags align)
nk_strtoi
NK_API int nk_strtoi(const char *str, const char **endptr)
nk_property_state::name
nk_hash name
Definition: nuklear.h:5402
nk_configuration_stacks::flags
struct nk_config_stack_flags flags
Definition: nuklear.h:5520
nk_style_toggle::border
float border
Definition: nuklear.h:4874
nk_select_text
NK_API int nk_select_text(struct nk_context *, const char *, int, nk_flags align, int value)
nk_chart_slot::color
struct nk_color color
Definition: nuklear.h:5270
nk_memory_status::size
nk_size size
Definition: nuklear.h:4095
nk_style_scrollbar::cursor_border_color
struct nk_color cursor_border_color
Definition: nuklear.h:4993
nk_style_window::contextual_border_color
struct nk_color contextual_border_color
Definition: nuklear.h:5183
nk_select_image_text
NK_API int nk_select_image_text(struct nk_context *, struct nk_image, const char *, int, nk_flags align, int value)
NK_COMMAND_CUSTOM
@ NK_COMMAND_CUSTOM
Definition: nuklear.h:4393
nk_buffer_marker
Definition: nuklear.h:4112
nk_style_window_header::label_padding
struct nk_vec2 label_padding
Definition: nuklear.h:5171
nk_contextual_item_symbol_text
NK_API int nk_contextual_item_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment)
nk_style_button::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle userdata)
Definition: nuklear.h:4848
NK_WINDOW_HIDDEN
@ NK_WINDOW_HIDDEN
Definition: nuklear.h:5360
nk_text_undo_state::undo_point
short undo_point
Definition: nuklear.h:4263
nk_plot
NK_API void nk_plot(struct nk_context *, enum nk_chart_type, const float *values, int count, int offset)
nk_text_undo_record::where
int where
Definition: nuklear.h:4254
nk_image::w
unsigned short w
Definition: nuklear.h:465
nk_style_toggle::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4878
nk_style_property::padding
struct nk_vec2 padding
Definition: nuklear.h:5068
nk_input_is_mouse_prev_hovering_rect
NK_API int nk_input_is_mouse_prev_hovering_rect(const struct nk_input *, struct nk_rect)
NK_SHOWN
@ NK_SHOWN
Definition: nuklear.h:474
nk_buffer_init
NK_API void nk_buffer_init(struct nk_buffer *, const struct nk_allocator *, nk_size size)
nk_list_view::begin
int begin
Definition: nuklear.h:3027
nk_key::clicked
unsigned int clicked
Definition: nuklear.h:4617
nk_style_progress::active
struct nk_style_item active
Definition: nuklear.h:4960
nk_begin
NK_API int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags)
nk_chart::slot
int slot
Definition: nuklear.h:5279
NK_MAX_NUMBER_BUFFER
#define NK_MAX_NUMBER_BUFFER
Definition: nuklear.h:240
NK_MAXIMIZED
@ NK_MAXIMIZED
Definition: nuklear.h:473
nk_configuration_stacks::style_items
struct nk_config_stack_style_item style_items
Definition: nuklear.h:5517
nk_vec2
NK_API struct nk_vec2 nk_vec2(float x, float y)
nk_style::option
struct nk_style_toggle option
Definition: nuklear.h:5223
nk_context::build
int build
Definition: nuklear.h:5598
NK_KEY_TEXT_SELECT_ALL
@ NK_KEY_TEXT_SELECT_ALL
Definition: nuklear.h:760
nk_command_scissor::y
short y
Definition: nuklear.h:4407
nk_layout_row_template_push_dynamic
NK_API void nk_layout_row_template_push_dynamic(struct nk_context *)
nk_label
NK_API void nk_label(struct nk_context *, const char *, nk_flags align)
nk_style_progress::cursor_rounding
float cursor_rounding
Definition: nuklear.h:4973
nk_style_property::label_active
struct nk_color label_active
Definition: nuklear.h:5059
nk_command_polyline::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4522
nk_window::tables
struct nk_table * tables
Definition: nuklear.h:5426
nk_text_edit::clip
struct nk_clipboard clip
Definition: nuklear.h:4281
NK_KEY_TEXT_RESET_MODE
@ NK_KEY_TEXT_RESET_MODE
Definition: nuklear.h:753
NK_KEY_TEXT_REDO
@ NK_KEY_TEXT_REDO
Definition: nuklear.h:759
nk_style::cursors
const struct nk_cursor * cursors[NK_CURSOR_COUNT]
Definition: nuklear.h:5214
nk_str_insert_str_runes
NK_API int nk_str_insert_str_runes(struct nk_str *, int pos, const nk_rune *)
nk_stroke_triangle
NK_API void nk_stroke_triangle(struct nk_command_buffer *, float, float, float, float, float, float, float line_thichness, struct nk_color)
nk_edit_types
nk_edit_types
Definition: nuklear.h:3430
nk_text_edit::mode
unsigned char mode
Definition: nuklear.h:4289
nk_row_layout::filled
float filled
Definition: nuklear.h:5306
NK_COMMAND_POLYGON
@ NK_COMMAND_POLYGON
Definition: nuklear.h:4388
nk_context::input
struct nk_input input
Definition: nuklear.h:5571
nk_panel_row_layout_type
nk_panel_row_layout_type
Definition: nuklear.h:5284
nk_cursor
Definition: nuklear.h:466
nk_table::next
struct nk_table * next
Definition: nuklear.h:5537
nk_recti::x
short x
Definition: nuklear.h:462
nk_style_window_header::close_button
struct nk_style_button close_button
Definition: nuklear.h:5157
nk_window_find
NK_API struct nk_window * nk_window_find(struct nk_context *ctx, const char *name)
NK_EDIT_MULTILINE
@ NK_EDIT_MULTILINE
Definition: nuklear.h:3427
nk_style_item_data
Definition: nuklear.h:4810
nk_command_image::x
short x
Definition: nuklear.h:4529
nk_style_item_hide
NK_API struct nk_style_item nk_style_item_hide(void)
nk_keys
nk_keys
Definition: nuklear.h:735
nk_style_selectable::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4914
nk_command_triangle_filled
Definition: nuklear.h:4464
NK_KEY_TEXT_WORD_LEFT
@ NK_KEY_TEXT_WORD_LEFT
Definition: nuklear.h:761
nk_str_append_text_char
NK_API int nk_str_append_text_char(struct nk_str *, const char *, int)
NK_COMMAND_POLYGON_FILLED
@ NK_COMMAND_POLYGON_FILLED
Definition: nuklear.h:4389
nk_style_scrollbar::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:5011
nk_style_combo::normal
struct nk_style_item normal
Definition: nuklear.h:5095
nk_style_selectable::hover_active
struct nk_style_item hover_active
Definition: nuklear.h:4890
nk_command_image::h
unsigned short h
Definition: nuklear.h:4530
nk_allocator::userdata
nk_handle userdata
Definition: nuklear.h:489
nk_configuration_stacks::button_behaviors
struct nk_config_stack_button_behavior button_behaviors
Definition: nuklear.h:5523
nk_strtof
NK_API float nk_strtof(const char *str, const char **endptr)
nk_chart_slot
Definition: nuklear.h:5268
NK_DYNAMIC
@ NK_DYNAMIC
Definition: nuklear.h:479
nk_widget_fitting
NK_API enum nk_widget_layout_states nk_widget_fitting(struct nk_rect *, struct nk_context *, struct nk_vec2)
nk_plugin_filter
int(* nk_plugin_filter)(const struct nk_text_edit *, nk_rune unicode)
Definition: nuklear.h:484
nk_utf_encode
NK_API int nk_utf_encode(nk_rune, char *, int)
nk_cursor::img
struct nk_image img
Definition: nuklear.h:466
nk_style_toggle::touch_padding
struct nk_vec2 touch_padding
Definition: nuklear.h:4872
nk_window::flags
nk_flags flags
Definition: nuklear.h:5412
nk_modify
nk_modify
Definition: nuklear.h:471
nk_allocator
Definition: nuklear.h:488
nk_str_at_char
NK_API char * nk_str_at_char(struct nk_str *, int pos)
nk_window::parent
struct nk_window * parent
Definition: nuklear.h:5432
nk_style_button::hover
struct nk_style_item hover
Definition: nuklear.h:4828
nk_init_custom
NK_API int nk_init_custom(struct nk_context *, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font *)
nk_row_layout::type
enum nk_panel_row_layout_type type
Definition: nuklear.h:5297
nk_button_symbol_text
NK_API int nk_button_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment)
nk_style_property::border_color
struct nk_color border_color
Definition: nuklear.h:5054
NK_EDIT_ALWAYS_INSERT_MODE
@ NK_EDIT_ALWAYS_INSERT_MODE
Definition: nuklear.h:3426
NK_SYMBOL_TRIANGLE_UP
@ NK_SYMBOL_TRIANGLE_UP
Definition: nuklear.h:501
nk_pool::pages
struct nk_page * pages
Definition: nuklear.h:5562
nk_user_font::userdata
nk_handle userdata
Definition: nuklear.h:3915
nk_menubar_end
NK_API void nk_menubar_end(struct nk_context *)
nk_combo_callback
NK_API int nk_combo_callback(struct nk_context *, void(*item_getter)(void *, int, const char **), void *userdata, int selected, int count, int item_height, struct nk_vec2 size)
nk_text_edit::single_line
unsigned char single_line
Definition: nuklear.h:4293
nk_style_combo::border_color
struct nk_color border_color
Definition: nuklear.h:5098
NK_SYMBOL_MINUS
@ NK_SYMBOL_MINUS
Definition: nuklear.h:506
nk_command_line::header
struct nk_command header
Definition: nuklear.h:4412
nk_button_symbol_styled
NK_API int nk_button_symbol_styled(struct nk_context *, const struct nk_style_button *, enum nk_symbol_type)
nk_chart_slot::range
float range
Definition: nuklear.h:5272
nk_style_button::text_alignment
nk_flags text_alignment
Definition: nuklear.h:4837
nk_command_rect_multi_color::right
struct nk_color right
Definition: nuklear.h:4452
nk_stroke_curve
NK_API void nk_stroke_curve(struct nk_command_buffer *, float, float, float, float, float, float, float, float, float line_thickness, struct nk_color)
nk_layout_space_bounds
NK_API struct nk_rect nk_layout_space_bounds(struct nk_context *)
nk_style_window::rounding
float rounding
Definition: nuklear.h:5198
nk_subimage_handle
NK_API struct nk_image nk_subimage_handle(nk_handle, unsigned short w, unsigned short h, struct nk_rect sub_region)
nk_window_is_collapsed
NK_API int nk_window_is_collapsed(struct nk_context *ctx, const char *name)
NK_KEY_CTRL
@ NK_KEY_CTRL
Definition: nuklear.h:738
NK_HIDDEN
@ NK_HIDDEN
Definition: nuklear.h:474
nk_popup_begin
NK_API int nk_popup_begin(struct nk_context *, enum nk_popup_type, const char *, nk_flags, struct nk_rect bounds)
nk_group_set_scroll
NK_API void nk_group_set_scroll(struct nk_context *, const char *id, nk_uint x_offset, nk_uint y_offset)
nk_text_align
nk_text_align
Definition: nuklear.h:3072
nk_style_scrollbar::padding
struct nk_vec2 padding
Definition: nuklear.h:5000
nk_color_hsv_f
NK_API void nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color)
nk_window_set_focus
NK_API void nk_window_set_focus(struct nk_context *, const char *name)
nk_popup_get_scroll
NK_API void nk_popup_get_scroll(struct nk_context *, nk_uint *offset_x, nk_uint *offset_y)
nk_command_arc::color
struct nk_color color
Definition: nuklear.h:4493
nk_text
NK_API void nk_text(struct nk_context *, const char *, int, nk_flags)
nk_input::mouse
struct nk_mouse mouse
Definition: nuklear.h:4627
nk_tree_element_pop
NK_API void nk_tree_element_pop(struct nk_context *)
nk_hsv
NK_API struct nk_color nk_hsv(int h, int s, int v)
nk_style_scrollbar::hover
struct nk_style_item hover
Definition: nuklear.h:4985
nk_style_selectable::normal
struct nk_style_item normal
Definition: nuklear.h:4884
nk_style_push_flags
NK_API int nk_style_push_flags(struct nk_context *, nk_flags *, nk_flags)
nk_style_property::hover
struct nk_style_item hover
Definition: nuklear.h:5052
nk_style_property::edit
struct nk_style_edit edit
Definition: nuklear.h:5070
NK_EDIT_EDITOR
@ NK_EDIT_EDITOR
Definition: nuklear.h:3434
nk_style_tab::sym_minimize
enum nk_symbol_type sym_minimize
Definition: nuklear.h:5135
nk_style_combo::border
float border
Definition: nuklear.h:5117
nk_text_edit_type
nk_text_edit_type
Definition: nuklear.h:4269
nk_layout_reset_min_row_height
NK_API void nk_layout_reset_min_row_height(struct nk_context *)
NK_MAX_FLOAT_PRECISION
#define NK_MAX_FLOAT_PRECISION
Definition: nuklear.h:5615
nk_scroll::y
nk_uint y
Definition: nuklear.h:467
NK_POINTER_TYPE
#define NK_POINTER_TYPE
Definition: nuklear.h:393
nk_style_window::padding
struct nk_vec2 padding
Definition: nuklear.h:5203
nk_pool::freelist
struct nk_page_element * freelist
Definition: nuklear.h:5563
nk_hsva_colorfv
NK_API struct nk_colorf nk_hsva_colorfv(float *c)
nk_window_collapse_if
NK_API void nk_window_collapse_if(struct nk_context *, const char *name, enum nk_collapse_states, int cond)
nk_fill_rect_multi_color
NK_API void nk_fill_rect_multi_color(struct nk_command_buffer *, struct nk_rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom)
nk_anti_aliasing
nk_anti_aliasing
Definition: nuklear.h:1142
nk_list_view_end
NK_API void nk_list_view_end(struct nk_list_view *)
nk_free
NK_API void nk_free(struct nk_context *)
nk_style_button::text_active
struct nk_color text_active
Definition: nuklear.h:4836
nk_page_data::tbl
struct nk_table tbl
Definition: nuklear.h:5541
nk_style_window_header::normal
struct nk_style_item normal
Definition: nuklear.h:5152
nk_style_window::scaler
struct nk_style_item scaler
Definition: nuklear.h:5187
nk_ptr_add_const
#define nk_ptr_add_const(t, p, i)
Definition: nuklear.h:5635
nk_textedit_delete_selection
NK_API void nk_textedit_delete_selection(struct nk_text_edit *)
nk_hsv_fv
NK_API struct nk_color nk_hsv_fv(const float *hsv)
nk_style_edit::text_normal
struct nk_color text_normal
Definition: nuklear.h:5030
nk_convert_config::curve_segment_count
unsigned curve_segment_count
Definition: nuklear.h:1160
nk_text_colored
NK_API void nk_text_colored(struct nk_context *, const char *, int, nk_flags, struct nk_color)
nk_command_curve::color
struct nk_color color
Definition: nuklear.h:4425
NK_SYMBOL_TRIANGLE_DOWN
@ NK_SYMBOL_TRIANGLE_DOWN
Definition: nuklear.h:502
NK_TEXT_CENTERED
@ NK_TEXT_CENTERED
Definition: nuklear.h:3082
nk_str_append_text_utf8
NK_API int nk_str_append_text_utf8(struct nk_str *, const char *, int)
nk_command_arc_filled::r
unsigned short r
Definition: nuklear.h:4499
size
size
Definition: GeneralBrush.hpp:8
nk_color_f
NK_API void nk_color_f(float *r, float *g, float *b, float *a, struct nk_color)
nk_popup_state::buf
struct nk_popup_buffer buf
Definition: nuklear.h:5373
nk_style_set_cursor
NK_API int nk_style_set_cursor(struct nk_context *, enum nk_style_cursor)
nk_context::pool
struct nk_pool pool
Definition: nuklear.h:5600
nk_command_rect_multi_color::x
short x
Definition: nuklear.h:4447
nk_button_set_behavior
NK_API void nk_button_set_behavior(struct nk_context *, enum nk_button_behavior)
nk_style_selectable::text_alignment
nk_flags text_alignment
Definition: nuklear.h:4903
NK_LIB
#define NK_LIB
Definition: nuklear.h:267
nk_group_get_scroll
NK_API void nk_group_get_scroll(struct nk_context *, const char *id, nk_uint *x_offset, nk_uint *y_offset)
nk_widget_is_mouse_clicked
NK_API int nk_widget_is_mouse_clicked(struct nk_context *, enum nk_buttons)
NK_SATURATE
#define NK_SATURATE(x)
Definition: nuklear.h:5618
NK_WINDOW_CLOSED
@ NK_WINDOW_CLOSED
Definition: nuklear.h:5362
NK_GLOBAL
#define NK_GLOBAL
Definition: nuklear.h:275
nk_page_data::pan
struct nk_panel pan
Definition: nuklear.h:5542
nk_style_chart::color
struct nk_color color
Definition: nuklear.h:5085
nk_style_tab::tab_minimize_button
struct nk_style_button tab_minimize_button
Definition: nuklear.h:5132
nk_command_curve::header
struct nk_command header
Definition: nuklear.h:4420
nk_menu_state::x
float x
Definition: nuklear.h:5321
NK_CHART_CLICKED
@ NK_CHART_CLICKED
Definition: nuklear.h:476
nk_context::end
struct nk_window * end
Definition: nuklear.h:5602
nk_style_edit
Definition: nuklear.h:5015
NK_PANEL_MENU
@ NK_PANEL_MENU
Definition: nuklear.h:5259
NK_EDIT_CLIPBOARD
@ NK_EDIT_CLIPBOARD
Definition: nuklear.h:3423
NK_BUTTON_DEFAULT
@ NK_BUTTON_DEFAULT
Definition: nuklear.h:470
nk_style_slider::normal
struct nk_style_item normal
Definition: nuklear.h:4919
nk_page_data::win
struct nk_window win
Definition: nuklear.h:5543
NK_ABS
#define NK_ABS(a)
Definition: nuklear.h:5620
nk_command_circle_filled
Definition: nuklear.h:4480
nk_command_circle::w
unsigned short w
Definition: nuklear.h:4476
NK_WIDGET_STATE_LEFT
@ NK_WIDGET_STATE_LEFT
Definition: nuklear.h:3052
nk_style_property::border
float border
Definition: nuklear.h:5066
nk_menu_state::offset
struct nk_scroll offset
Definition: nuklear.h:5322
NK_KEY_TEXT_LINE_START
@ NK_KEY_TEXT_LINE_START
Definition: nuklear.h:754
nk__next
NK_API const struct nk_command * nk__next(struct nk_context *, const struct nk_command *)
nk_color_picker
NK_API struct nk_colorf nk_color_picker(struct nk_context *, struct nk_colorf, enum nk_color_format)
nk_layout_set_min_row_height
NK_API void nk_layout_set_min_row_height(struct nk_context *, float height)
nk_convert_config::line_AA
enum nk_anti_aliasing line_AA
Definition: nuklear.h:1156
nk_tree_element_image_push_hashed
NK_API int nk_tree_element_image_push_hashed(struct nk_context *, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, int *selected, const char *hash, int len, int seed)
NK_INT8
#define NK_INT8
Definition: nuklear.h:341
nk_page_data
Definition: nuklear.h:5540
nk_list_view::count
int count
Definition: nuklear.h:3027
nk_size
NK_SIZE_TYPE nk_size
Definition: nuklear.h:405
nk_command_custom::callback
nk_command_custom_callback callback
Definition: nuklear.h:4542
nk_image
NK_API void nk_image(struct nk_context *, struct nk_image)
nk_image
Definition: nuklear.h:465
NK_WIDGET_STATE_MODIFIED
@ NK_WIDGET_STATE_MODIFIED
Definition: nuklear.h:3047
nk_contextual_end
NK_API void nk_contextual_end(struct nk_context *)
nk_input_glyph
NK_API void nk_input_glyph(struct nk_context *, const nk_glyph)
nk_style_slider::spacing
struct nk_vec2 spacing
Definition: nuklear.h:4940
nk_text_edit
Definition: nuklear.h:4280
nk_window::next
struct nk_window * next
Definition: nuklear.h:5430
nk_key
Definition: nuklear.h:4615
nk_style_slider::bar_height
float bar_height
Definition: nuklear.h:4938
nk_command_rect_multi_color::left
struct nk_color left
Definition: nuklear.h:4449
nk_color::g
nk_byte g
Definition: nuklear.h:457
nk_command_custom::header
struct nk_command header
Definition: nuklear.h:4538
nk_combo_item_symbol_label
NK_API int nk_combo_item_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags alignment)
nk_push_scissor
NK_API void nk_push_scissor(struct nk_command_buffer *, struct nk_rect)
nk_style_edit::text_hover
struct nk_color text_hover
Definition: nuklear.h:5031
nk_style_button::text_normal
struct nk_color text_normal
Definition: nuklear.h:4834
NK_KEY_LEFT
@ NK_KEY_LEFT
Definition: nuklear.h:748
NK_CLAMP
#define NK_CLAMP(i, v, x)
Definition: nuklear.h:304
NK_SIZE_TYPE
#define NK_SIZE_TYPE
Definition: nuklear.h:378
nk_progress
NK_API int nk_progress(struct nk_context *, nk_size *cur, nk_size max, int modifyable)
nk_style_item_data::color
struct nk_color color
Definition: nuklear.h:4812
NK_FLAG
#define NK_FLAG(x)
Definition: nuklear.h:277
nk_style_edit::padding
struct nk_vec2 padding
Definition: nuklear.h:5045
NK_WIDGET_INVALID
@ NK_WIDGET_INVALID
Definition: nuklear.h:3042
nk_style_tab::background
struct nk_style_item background
Definition: nuklear.h:5126
nk_configuration_stacks::colors
struct nk_config_stack_color colors
Definition: nuklear.h:5521
nk_button_image_text_styled
NK_API int nk_button_image_text_styled(struct nk_context *, const struct nk_style_button *, struct nk_image img, const char *, int, nk_flags alignment)
NK_KEY_TEXT_END
@ NK_KEY_TEXT_END
Definition: nuklear.h:757
nk_style_scrollbar
Definition: nuklear.h:4982
nk_plugin_paste
void(* nk_plugin_paste)(nk_handle, struct nk_text_edit *)
Definition: nuklear.h:485
nk_stricmp
NK_API int nk_stricmp(const char *s1, const char *s2)
nk_vec2i::y
short y
Definition: nuklear.h:460
nk_command_text::string
char string[1]
Definition: nuklear.h:4554
nk_str_at_rune
NK_API char * nk_str_at_rune(struct nk_str *, int pos, nk_rune *unicode, int *len)
nk_vec2_sub
#define nk_vec2_sub(a, b)
Definition: nuklear.h:5629
nk_style_toggle::text_active
struct nk_color text_active
Definition: nuklear.h:4866
nk_table::seq
unsigned int seq
Definition: nuklear.h:5533
nk_style_window::border
float border
Definition: nuklear.h:5189
NK_ALIGN_PTR
#define NK_ALIGN_PTR(x, mask)
Definition: nuklear.h:5656
nk_layout_space_end
NK_API void nk_layout_space_end(struct nk_context *)
nk_input_scroll
NK_API void nk_input_scroll(struct nk_context *, struct nk_vec2 val)
NK_UP
@ NK_UP
Definition: nuklear.h:469
nk_hsva_bv
NK_API struct nk_color nk_hsva_bv(const nk_byte *hsva)
NK_WIDGET_STATE_HOVERED
@ NK_WIDGET_STATE_HOVERED
Definition: nuklear.h:3053
nk_draw_null_texture::uv
struct nk_vec2 uv
Definition: nuklear.h:1152
nk_menu_state::y
float y
Definition: nuklear.h:5321
nk_input_is_key_down
NK_API int nk_input_is_key_down(const struct nk_input *, enum nk_keys)
nk_label_wrap
NK_API void nk_label_wrap(struct nk_context *, const char *)
nk_vec2::y
float y
Definition: nuklear.h:459
nk_layout_space_rect_to_screen
NK_API struct nk_rect nk_layout_space_rect_to_screen(struct nk_context *, struct nk_rect)
nk_style_progress::border
float border
Definition: nuklear.h:4971
NK_CHART_LINES
@ NK_CHART_LINES
Definition: nuklear.h:475
nk_popup_state::con_old
unsigned con_old
Definition: nuklear.h:5377
nk_popup_buffer::parent
nk_size parent
Definition: nuklear.h:5314
NK_PI
#define NK_PI
Definition: nuklear.h:5613
nk_command_rect_multi_color
Definition: nuklear.h:4445
nk_color_hsva_bv
NK_API void nk_color_hsva_bv(nk_byte *hsva_out, struct nk_color)
nk_style_window_header
Definition: nuklear.h:5150
nk_text_edit::filter
nk_plugin_filter filter
Definition: nuklear.h:4283
nk_style_scrollbar::cursor_active
struct nk_style_item cursor_active
Definition: nuklear.h:4992
NK_COMMAND_RECT_MULTI_COLOR
@ NK_COMMAND_RECT_MULTI_COLOR
Definition: nuklear.h:4381
nk_window::seq
unsigned int seq
Definition: nuklear.h:5409
nk_tree_state_pop
NK_API void nk_tree_state_pop(struct nk_context *)
nk_strlen
NK_API int nk_strlen(const char *str)
nk_text_undo_record
Definition: nuklear.h:4253
nk_textedit_text
NK_API void nk_textedit_text(struct nk_text_edit *, const char *, int total_len)
nk_command_scissor::w
unsigned short w
Definition: nuklear.h:4408
nk_popup_type
nk_popup_type
Definition: nuklear.h:478
nk_contextual_close
NK_API void nk_contextual_close(struct nk_context *)
NK_KEY_DEL
@ NK_KEY_DEL
Definition: nuklear.h:739
nk_style_property::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:5076
nk_color::r
nk_byte r
Definition: nuklear.h:457
nk_style_property::inc_button
struct nk_style_button inc_button
Definition: nuklear.h:5071
nk_strmatch_fuzzy_text
NK_API int nk_strmatch_fuzzy_text(const char *txt, int txt_len, const char *pattern, int *out_score)
nk_style_tab::padding
struct nk_vec2 padding
Definition: nuklear.h:5142
nk_command_arc::cx
short cx
Definition: nuklear.h:4489
nk_combo_begin_label
NK_API int nk_combo_begin_label(struct nk_context *, const char *selected, struct nk_vec2 size)
NK_COMMAND_TRIANGLE
@ NK_COMMAND_TRIANGLE
Definition: nuklear.h:4386
nk_select_symbol_text
NK_API int nk_select_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags align, int value)
nk_command_polygon::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4507
nk_chart
Definition: nuklear.h:5278
nk_buffer::memory
struct nk_memory memory
Definition: nuklear.h:4125
nk_rgb
NK_API struct nk_color nk_rgb(int r, int g, int b)
nk_style_edit::normal
struct nk_style_item normal
Definition: nuklear.h:5017
nk_layout_space_push
NK_API void nk_layout_space_push(struct nk_context *, struct nk_rect bounds)
nk_table::values
nk_uint values[NK_VALUE_PAGE_CAPACITY]
Definition: nuklear.h:5536
nk_color::a
nk_byte a
Definition: nuklear.h:457
nk_char
NK_INT8 nk_char
Definition: nuklear.h:398
nk_style_button::image_padding
struct nk_vec2 image_padding
Definition: nuklear.h:4843
NK_LAYOUT_STATIC_FIXED
@ NK_LAYOUT_STATIC_FIXED
Definition: nuklear.h:5289
nk_style_button::touch_padding
struct nk_vec2 touch_padding
Definition: nuklear.h:4844
nk_popup_buffer::begin
nk_size begin
Definition: nuklear.h:5313
nk_panel::type
enum nk_panel_type type
Definition: nuklear.h:5326
nk_text_edit::cursor
int cursor
Definition: nuklear.h:4286
nk_color_u32
NK_API nk_uint nk_color_u32(struct nk_color)
nk_str_insert_text_char
NK_API int nk_str_insert_text_char(struct nk_str *, int pos, const char *, int)
nk_fill_arc
NK_API void nk_fill_arc(struct nk_command_buffer *, float cx, float cy, float radius, float a_min, float a_max, struct nk_color)
NK_UTF_SIZE
#define NK_UTF_SIZE
Definition: nuklear.h:235
nk_filter_ascii
NK_API int nk_filter_ascii(const struct nk_text_edit *, nk_rune unicode)
nk_combo
NK_API int nk_combo(struct nk_context *, const char **items, int count, int selected, int item_height, struct nk_vec2 size)
NK_INBOX
#define NK_INBOX(px, py, x, y, w, h)
Definition: nuklear.h:5622
nk_rgba
NK_API struct nk_color nk_rgba(int r, int g, int b, int a)
nk_style_progress::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4979
nk_style_text
Definition: nuklear.h:4820
nk_command_line::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4413
nk_rect::w
float w
Definition: nuklear.h:461
nk_style_get_color_by_name
const NK_API char * nk_style_get_color_by_name(enum nk_style_colors)
nk_style_load_cursor
NK_API void nk_style_load_cursor(struct nk_context *, enum nk_style_cursor, const struct nk_cursor *)
nk_style_slider::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4953
nk_style_chart::rounding
float rounding
Definition: nuklear.h:5089
nk_flags
nk_uint nk_flags
Definition: nuklear.h:409
nk_popup_close
NK_API void nk_popup_close(struct nk_context *)
nk_text_edit::string
struct nk_str string
Definition: nuklear.h:4282
NK_INT16
#define NK_INT16
Definition: nuklear.h:347
nk_property_state::buffer
char buffer[NK_MAX_NUMBER_BUFFER]
Definition: nuklear.h:5397
nk_style_property::sym_right
enum nk_symbol_type sym_right
Definition: nuklear.h:5063
nk_mouse_button::clicked
unsigned int clicked
Definition: nuklear.h:4601
NK_SYMBOL_RECT_SOLID
@ NK_SYMBOL_RECT_SOLID
Definition: nuklear.h:499
nk_style_progress::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4978
nk_str_append_text_runes
NK_API int nk_str_append_text_runes(struct nk_str *, const nk_rune *, int)
nk_color_fv
NK_API void nk_color_fv(float *rgba_out, struct nk_color)
nk_style::font
const struct nk_user_font * font
Definition: nuklear.h:5213
nk_stricmpn
NK_API int nk_stricmpn(const char *s1, const char *s2, int n)
nk_style_progress::rounding
float rounding
Definition: nuklear.h:4970
nk_button_label_styled
NK_API int nk_button_label_styled(struct nk_context *, const struct nk_style_button *, const char *title)
nk_edit_state
Definition: nuklear.h:5382
nk_str_clear
NK_API void nk_str_clear(struct nk_str *)
nk_style_item
Definition: nuklear.h:4815
nk_buffer_push
NK_API void nk_buffer_push(struct nk_buffer *, enum nk_buffer_allocation_type type, const void *memory, nk_size size, nk_size align)
NK_WINDOW_BACKGROUND
@ NK_WINDOW_BACKGROUND
Definition: nuklear.h:1459
nk_group_scrolled_end
NK_API void nk_group_scrolled_end(struct nk_context *)
nk_command_rect_multi_color::bottom
struct nk_color bottom
Definition: nuklear.h:4451
nk_list_view::scroll_pointer
nk_uint * scroll_pointer
Definition: nuklear.h:3031
nk_textedit_init
NK_API void nk_textedit_init(struct nk_text_edit *, struct nk_allocator *, nk_size size)
nk_context::active
struct nk_window * active
Definition: nuklear.h:5603
nk_rect
NK_API struct nk_rect nk_rect(float x, float y, float w, float h)
nk_textedit_cut
NK_API int nk_textedit_cut(struct nk_text_edit *)
nk_style_window_header::label_normal
struct nk_color label_normal
Definition: nuklear.h:5164
nk_color_hsv_bv
NK_API void nk_color_hsv_bv(nk_byte *hsv_out, struct nk_color)
NK_CURSOR_COUNT
@ NK_CURSOR_COUNT
Definition: nuklear.h:3600
NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT
@ NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT
Definition: nuklear.h:3599
NK_TEXTEDIT_UNDOCHARCOUNT
#define NK_TEXTEDIT_UNDOCHARCOUNT
Definition: nuklear.h:4243
nk_property_int
NK_API void nk_property_int(struct nk_context *, const char *name, int min, int *val, int max, int step, float inc_per_pixel)
NK_SYMBOL_TRIANGLE_LEFT
@ NK_SYMBOL_TRIANGLE_LEFT
Definition: nuklear.h:503
nk_page_element::data
union nk_page_data data
Definition: nuklear.h:5547
nk_text_wrap
NK_API void nk_text_wrap(struct nk_context *, const char *, int)
nk_stroke_line
NK_API void nk_stroke_line(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float line_thickness, struct nk_color)
nk_true
@ nk_true
Definition: nuklear.h:456
nk_style_scrollbar::normal
struct nk_style_item normal
Definition: nuklear.h:4984
nk_stroke_arc
NK_API void nk_stroke_arc(struct nk_command_buffer *, float cx, float cy, float radius, float a_min, float a_max, float line_thickness, struct nk_color)
nk_style_window_header::active
struct nk_style_item active
Definition: nuklear.h:5154
nk_input_is_mouse_released
NK_API int nk_input_is_mouse_released(const struct nk_input *, enum nk_buttons)
NK_CHART_MAX
@ NK_CHART_MAX
Definition: nuklear.h:475
nk_row_layout::columns
int columns
Definition: nuklear.h:5301
nk_push_custom
NK_API void nk_push_custom(struct nk_command_buffer *, struct nk_rect, nk_command_custom_callback, nk_handle usr)
nk_popup_state::active_con
unsigned active_con
Definition: nuklear.h:5378
nk_layout_row_template_begin
NK_API void nk_layout_row_template_begin(struct nk_context *, float row_height)
nk_color_cf
NK_API struct nk_colorf nk_color_cf(struct nk_color)
nk_buffer_mark
NK_API void nk_buffer_mark(struct nk_buffer *, enum nk_buffer_allocation_type type)
nk_style_window::min_row_height_padding
float min_row_height_padding
Definition: nuklear.h:5196
nk_command_rect_filled::h
unsigned short h
Definition: nuklear.h:4441
NK_COLOR_PROPERTY
@ NK_COLOR_PROPERTY
Definition: nuklear.h:3578
nk_style_window_header::minimize_button
struct nk_style_button minimize_button
Definition: nuklear.h:5158
nk_style_item::type
enum nk_style_item_type type
Definition: nuklear.h:4816
nk_rune
nk_uint nk_rune
Definition: nuklear.h:410
nk_button_image_styled
NK_API int nk_button_image_styled(struct nk_context *, const struct nk_style_button *, struct nk_image img)
nk_input_is_mouse_click_in_rect
NK_API int nk_input_is_mouse_click_in_rect(const struct nk_input *, enum nk_buttons, struct nk_rect)
nk_draw_null_texture
Definition: nuklear.h:1150
nk_uint
NK_UINT32 nk_uint
Definition: nuklear.h:404
nk_style_toggle::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4879
NK_VECTOR_STACK_SIZE
#define NK_VECTOR_STACK_SIZE
Definition: nuklear.h:5477
NK_EDIT_GOTO_END_ON_ACTIVATE
@ NK_EDIT_GOTO_END_ON_ACTIVATE
Definition: nuklear.h:3428
nk_color
Definition: nuklear.h:457
nk_style_window::border_color
struct nk_color border_color
Definition: nuklear.h:5180
nk_mouse::grab
unsigned char grab
Definition: nuklear.h:4610
nk_style_scrollbar::rounding
float rounding
Definition: nuklear.h:4997
nk_button_behavior
nk_button_behavior
Definition: nuklear.h:470
nk_draw_text
NK_API void nk_draw_text(struct nk_command_buffer *, struct nk_rect, const char *text, int len, const struct nk_user_font *, struct nk_color, struct nk_color)
NK_CURSOR_TEXT
@ NK_CURSOR_TEXT
Definition: nuklear.h:3594
nk_tree_type
nk_tree_type
Definition: nuklear.h:480
nk_command::next
nk_size next
Definition: nuklear.h:4399
nk_image_ptr
NK_API struct nk_image nk_image_ptr(void *)
NK_LAYOUT_STATIC_ROW
@ NK_LAYOUT_STATIC_ROW
Definition: nuklear.h:5290
nk_style_push_font
NK_API int nk_style_push_font(struct nk_context *, const struct nk_user_font *)
nk_widget_layout_states
nk_widget_layout_states
Definition: nuklear.h:3041
NK_KEY_TEXT_WORD_RIGHT
@ NK_KEY_TEXT_WORD_RIGHT
Definition: nuklear.h:762
NK_CURSOR_MOVE
@ NK_CURSOR_MOVE
Definition: nuklear.h:3595
nk_command_custom::w
unsigned short w
Definition: nuklear.h:4540
NK_EDIT_DEFAULT
@ NK_EDIT_DEFAULT
Definition: nuklear.h:3416
nk_style_selectable::rounding
float rounding
Definition: nuklear.h:4906
NK_WINDOW_PRIVATE
@ NK_WINDOW_PRIVATE
Definition: nuklear.h:5353
nk_combo_begin_text
NK_API int nk_combo_begin_text(struct nk_context *, const char *selected, int, struct nk_vec2 size)
NK_KEY_TEXT_START
@ NK_KEY_TEXT_START
Definition: nuklear.h:756
nk_command_line::color
struct nk_color color
Definition: nuklear.h:4416
nk_command_rect_multi_color::y
short y
Definition: nuklear.h:4447
NK_LEFT
@ NK_LEFT
Definition: nuklear.h:469
NK_EDIT_ACTIVATED
@ NK_EDIT_ACTIVATED
Definition: nuklear.h:3439
nk_chart_add_slot_colored
NK_API void nk_chart_add_slot_colored(struct nk_context *ctx, const enum nk_chart_type, struct nk_color, struct nk_color active, int count, float min_value, float max_value)
nk_layout_row_dynamic
NK_API void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols)
nk_style_window::menu_padding
struct nk_vec2 menu_padding
Definition: nuklear.h:5208
nk_layout_space_to_screen
NK_API struct nk_vec2 nk_layout_space_to_screen(struct nk_context *, struct nk_vec2)
nk_contextual_item_symbol_label
NK_API int nk_contextual_item_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags alignment)
nk_style_progress::hover
struct nk_style_item hover
Definition: nuklear.h:4959
nk_table::prev
struct nk_table * prev
Definition: nuklear.h:5537
nk_buffer_marker::active
int active
Definition: nuklear.h:4113
nk_command_text::y
short y
Definition: nuklear.h:4550
nk_command_custom_callback
void(* nk_command_custom_callback)(void *canvas, short x, short y, unsigned short w, unsigned short h, nk_handle callback_data)
Definition: nuklear.h:4535
NK_SYMBOL_X
@ NK_SYMBOL_X
Definition: nuklear.h:495
nk_popup_end
NK_API void nk_popup_end(struct nk_context *)
nk_style_chart::selected_color
struct nk_color selected_color
Definition: nuklear.h:5084
nk_buffer_reset
NK_API void nk_buffer_reset(struct nk_buffer *, enum nk_buffer_allocation_type type)
nk_style_slider::bar_hover
struct nk_color bar_hover
Definition: nuklear.h:4926
nk_mouse_button::down
int down
Definition: nuklear.h:4600
nk_page_element::prev
struct nk_page_element * prev
Definition: nuklear.h:5549
nk_text_undo_state::undo_char
nk_rune undo_char[NK_TEXTEDIT_UNDOCHARCOUNT]
Definition: nuklear.h:4262
nk_filter_binary
NK_API int nk_filter_binary(const struct nk_text_edit *, nk_rune unicode)
nk_color_pick
NK_API int nk_color_pick(struct nk_context *, struct nk_colorf *, enum nk_color_format)
nk_command_polyline::color
struct nk_color color
Definition: nuklear.h:4521
nk_style_pop_float
NK_API int nk_style_pop_float(struct nk_context *)
nk_command_circle::h
unsigned short h
Definition: nuklear.h:4476
nk_window_close
NK_API void nk_window_close(struct nk_context *ctx, const char *name)
NK_BUFFER_DYNAMIC
@ NK_BUFFER_DYNAMIC
Definition: nuklear.h:4103
nk_table::size
unsigned int size
Definition: nuklear.h:5534
nk_style_button::text_background
struct nk_color text_background
Definition: nuklear.h:4833
nk_style_combo::sym_hover
enum nk_symbol_type sym_hover
Definition: nuklear.h:5113
nk_tree_push_hashed
NK_API int nk_tree_push_hashed(struct nk_context *, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, const char *hash, int len, int seed)
nk_style_tab
Definition: nuklear.h:5124
nk_configuration_stacks::fonts
struct nk_config_stack_user_font fonts
Definition: nuklear.h:5522
nk_stroke_polyline
NK_API void nk_stroke_polyline(struct nk_command_buffer *, float *points, int point_count, float line_thickness, struct nk_color col)
nk_command_line::end
struct nk_vec2i end
Definition: nuklear.h:4415
nk_command_curve::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4421
nk_clipboard::paste
nk_plugin_paste paste
Definition: nuklear.h:4249
NK_COLOR_SCROLLBAR
@ NK_COLOR_SCROLLBAR
Definition: nuklear.h:3585
nk_page::next
struct nk_page * next
Definition: nuklear.h:5554
nk_pool::page_count
unsigned int page_count
Definition: nuklear.h:5561
nk_colorf::b
float b
Definition: nuklear.h:458
NK_COLOR_COMBO
@ NK_COLOR_COMBO
Definition: nuklear.h:3581
nk_command_rect_filled::color
struct nk_color color
Definition: nuklear.h:4442
nk_buffer_memory
NK_API void * nk_buffer_memory(struct nk_buffer *)
nk_style_slider::border
float border
Definition: nuklear.h:4936
nk_style_scrollbar::active
struct nk_style_item active
Definition: nuklear.h:4986
nk_convert_config
Definition: nuklear.h:1154
nk_style_window::background
struct nk_color background
Definition: nuklear.h:5178
nk_command_custom::x
short x
Definition: nuklear.h:4539
nk_text_edit::undo
struct nk_text_undo_state undo
Definition: nuklear.h:4297
nk_init_fixed
NK_API int nk_init_fixed(struct nk_context *, void *memory, nk_size size, const struct nk_user_font *)
NK_FLOAT_STACK_SIZE
#define NK_FLOAT_STACK_SIZE
Definition: nuklear.h:5473
nk_edit_state::prev
int prev
Definition: nuklear.h:5386
nk_rect::y
float y
Definition: nuklear.h:461
nk_style_slider::cursor_normal
struct nk_style_item cursor_normal
Definition: nuklear.h:4931
nk_style_toggle::text_hover
struct nk_color text_hover
Definition: nuklear.h:4865
nk_chart_slot::last
struct nk_vec2 last
Definition: nuklear.h:5274
nk_color_hsva_i
NK_API void nk_color_hsva_i(int *h, int *s, int *v, int *a, struct nk_color)
nk_uchar
NK_UINT8 nk_uchar
Definition: nuklear.h:399
nk_style_combo::sym_active
enum nk_symbol_type sym_active
Definition: nuklear.h:5114
nk_chart_add_slot
NK_API void nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type, int count, float min_value, float max_value)
nk_textedit_init_fixed
NK_API void nk_textedit_init_fixed(struct nk_text_edit *, void *memory, nk_size size)
NK_EDIT_COMMITED
@ NK_EDIT_COMMITED
Definition: nuklear.h:3441
NK_PANEL_CONTEXTUAL
@ NK_PANEL_CONTEXTUAL
Definition: nuklear.h:5257
nk_window_is_hovered
NK_API int nk_window_is_hovered(struct nk_context *)
nk_menu_item_image_label
NK_API int nk_menu_item_image_label(struct nk_context *, struct nk_image, const char *, nk_flags alignment)
nk_style_scrollbar::rounding_cursor
float rounding_cursor
Definition: nuklear.h:4999
nk_page
Definition: nuklear.h:5552
nk_init
NK_API int nk_init(struct nk_context *, struct nk_allocator *, const struct nk_user_font *)
nk_select_symbol_label
NK_API int nk_select_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags align, int value)
nk_command_rect::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4431
nk_style_selectable::userdata
nk_handle userdata
Definition: nuklear.h:4912
NK_COLOR_BORDER
@ NK_COLOR_BORDER
Definition: nuklear.h:3565
NK_KEY_COPY
@ NK_KEY_COPY
Definition: nuklear.h:743
nk_style_combo
Definition: nuklear.h:5093
nk_style_window::combo_border_color
struct nk_color combo_border_color
Definition: nuklear.h:5182
nk_mouse_button::clicked_pos
struct nk_vec2 clicked_pos
Definition: nuklear.h:4602
nk_command_curve::begin
struct nk_vec2i begin
Definition: nuklear.h:4422
NK_COLOR_EDIT_CURSOR
@ NK_COLOR_EDIT_CURSOR
Definition: nuklear.h:3580
nk_input_has_mouse_click_in_rect
NK_API int nk_input_has_mouse_click_in_rect(const struct nk_input *, enum nk_buttons, struct nk_rect)
nk_combo_separator
NK_API int nk_combo_separator(struct nk_context *, const char *items_separated_by_separator, int separator, int selected, int count, int item_height, struct nk_vec2 size)
nk_text_wrap_colored
NK_API void nk_text_wrap_colored(struct nk_context *, const char *, int, struct nk_color)
nk_pool::type
enum nk_allocation_type type
Definition: nuklear.h:5560
nk_window_set_scroll
NK_API void nk_window_set_scroll(struct nk_context *, nk_uint offset_x, nk_uint offset_y)
nk_style_selectable::normal_active
struct nk_style_item normal_active
Definition: nuklear.h:4889
nk_key::down
int down
Definition: nuklear.h:4616
NK_SCROLLBAR_HIDING_TIMEOUT
#define NK_SCROLLBAR_HIDING_TIMEOUT
Definition: nuklear.h:243
nk_str_len_char
NK_API int nk_str_len_char(struct nk_str *)
nk_buffer_init_fixed
NK_API void nk_buffer_init_fixed(struct nk_buffer *, void *memory, nk_size size)
NK_SYMBOL_NONE
@ NK_SYMBOL_NONE
Definition: nuklear.h:494
nk_style_edit::rounding
float rounding
Definition: nuklear.h:5042
NK_COMMAND_ARC
@ NK_COMMAND_ARC
Definition: nuklear.h:4384
nk_window_get_position
NK_API struct nk_vec2 nk_window_get_position(const struct nk_context *ctx)
nk_command_buffer::last
nk_size last
Definition: nuklear.h:4567
nk_command_arc::header
struct nk_command header
Definition: nuklear.h:4488
NK_PANEL_NONE
@ NK_PANEL_NONE
Definition: nuklear.h:5253
nk_color_hex_rgba
NK_API void nk_color_hex_rgba(char *output, struct nk_color)
NK_BUFFER_MAX
@ NK_BUFFER_MAX
Definition: nuklear.h:4109
nk_layout_row_begin
NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols)
nk_style_window_header::close_symbol
enum nk_symbol_type close_symbol
Definition: nuklear.h:5159
nk_foreach
#define nk_foreach(c, ctx)
Definition: nuklear.h:1210
nk_command_buffer::begin
nk_size begin
Definition: nuklear.h:4567
nk_label_colored_wrap
NK_API void nk_label_colored_wrap(struct nk_context *, const char *, struct nk_color)
NK_PANEL_TOOLTIP
@ NK_PANEL_TOOLTIP
Definition: nuklear.h:5260
nk_style_toggle::border_color
struct nk_color border_color
Definition: nuklear.h:4857
nk_window::prev
struct nk_window * prev
Definition: nuklear.h:5431
nk_style::contextual_button
struct nk_style_button contextual_button
Definition: nuklear.h:5221
nk_vec2
Definition: nuklear.h:459
nk_text_undo_state
Definition: nuklear.h:4260
nk_style_selectable::touch_padding
struct nk_vec2 touch_padding
Definition: nuklear.h:4908
nk_user_font::width
nk_text_width_f width
Definition: nuklear.h:3919
NK_COLOR_COUNT
@ NK_COLOR_COUNT
Definition: nuklear.h:3590
nk_window::table_count
unsigned int table_count
Definition: nuklear.h:5427
nk_style_combo::button_padding
struct nk_vec2 button_padding
Definition: nuklear.h:5120
nk_recta
NK_API struct nk_rect nk_recta(struct nk_vec2 pos, struct nk_vec2 size)
nk_checkbox_flags_text
NK_API int nk_checkbox_flags_text(struct nk_context *, const char *, int, unsigned int *flags, unsigned int value)
nk_plugin_free
void(* nk_plugin_free)(nk_handle, void *old)
Definition: nuklear.h:483
nk_collapse_states
nk_collapse_states
Definition: nuklear.h:473
nk_widget_width
NK_API float nk_widget_width(struct nk_context *)
nk_str_at_const
const NK_API char * nk_str_at_const(const struct nk_str *, int pos, nk_rune *unicode, int *len)
nk_style_combo::active
struct nk_style_item active
Definition: nuklear.h:5097
NK_POPUP_DYNAMIC
@ NK_POPUP_DYNAMIC
Definition: nuklear.h:478
nk_style_edit::scrollbar_size
struct nk_vec2 scrollbar_size
Definition: nuklear.h:5044
NK_CONVERT_SUCCESS
@ NK_CONVERT_SUCCESS
Definition: nuklear.h:1144
nk_style_item_type
nk_style_item_type
Definition: nuklear.h:4805
nk_rgba_f
NK_API struct nk_color nk_rgba_f(float r, float g, float b, float a)
nk_style_property
Definition: nuklear.h:5049
nk_layout_row_static
NK_API void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols)
nk_command_image::w
unsigned short w
Definition: nuklear.h:4530
nk_hsva
NK_API struct nk_color nk_hsva(int h, int s, int v, int a)
NK_TEXT_EDIT_MODE_REPLACE
@ NK_TEXT_EDIT_MODE_REPLACE
Definition: nuklear.h:4277
nk_mouse::delta
struct nk_vec2 delta
Definition: nuklear.h:4608
nk_command_triangle_filled::b
struct nk_vec2i b
Definition: nuklear.h:4467
nk_clipboard::userdata
nk_handle userdata
Definition: nuklear.h:4248
nk_context::seq
unsigned int seq
Definition: nuklear.h:5607
nk_window::buffer
struct nk_command_buffer buffer
Definition: nuklear.h:5416
NK_KEY_TEXT_UNDO
@ NK_KEY_TEXT_UNDO
Definition: nuklear.h:758
NK_COLOR_TOGGLE
@ NK_COLOR_TOGGLE
Definition: nuklear.h:3569
nk_memory_status::memory
void * memory
Definition: nuklear.h:4093
nk_mouse::scroll_delta
struct nk_vec2 scroll_delta
Definition: nuklear.h:4609
nk_popup_buffer::end
nk_size end
Definition: nuklear.h:5316
nk_popup_state::con_count
unsigned con_count
Definition: nuklear.h:5377
nk_window_is_hidden
NK_API int nk_window_is_hidden(struct nk_context *, const char *)
nk_style_button::rounding
float rounding
Definition: nuklear.h:4841
nk_style_scrollbar::show_buttons
int show_buttons
Definition: nuklear.h:5003
nk_panel::buffer
struct nk_command_buffer * buffer
Definition: nuklear.h:5340
nk_style_progress::normal
struct nk_style_item normal
Definition: nuklear.h:4958
NK_COLOR_SLIDER_CURSOR_ACTIVE
@ NK_COLOR_SLIDER_CURSOR_ACTIVE
Definition: nuklear.h:3577
NK_STATIC_ASSERT
#define NK_STATIC_ASSERT(exp)
Definition: nuklear.h:291
nk_draw_null_texture::texture
nk_handle texture
Definition: nuklear.h:1151
NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
#define NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
Definition: nuklear.h:5246
NK_COLOR_TAB_HEADER
@ NK_COLOR_TAB_HEADER
Definition: nuklear.h:3589
nk_style_selectable::text_normal
struct nk_color text_normal
Definition: nuklear.h:4894
nk_subimage_ptr
NK_API struct nk_image nk_subimage_ptr(void *, unsigned short w, unsigned short h, struct nk_rect sub_region)
nk_command::type
enum nk_command_type type
Definition: nuklear.h:4398
nk_context::freelist
struct nk_page_element * freelist
Definition: nuklear.h:5605
nk_style_show_cursor
NK_API void nk_style_show_cursor(struct nk_context *)
nk_convert_config::circle_segment_count
unsigned circle_segment_count
Definition: nuklear.h:1158
NK_COLOR_TOGGLE_HOVER
@ NK_COLOR_TOGGLE_HOVER
Definition: nuklear.h:3570
nk_style_edit::cursor_text_normal
struct nk_color cursor_text_normal
Definition: nuklear.h:5026
NK_WINDOW_MAX_NAME
#define NK_WINDOW_MAX_NAME
Definition: nuklear.h:5348
nk_item_is_any_active
NK_API int nk_item_is_any_active(struct nk_context *)
NK_WIDGET_STATE_ACTIVE
@ NK_WIDGET_STATE_ACTIVE
Definition: nuklear.h:3054
nk_combo_begin_symbol
NK_API int nk_combo_begin_symbol(struct nk_context *, enum nk_symbol_type, struct nk_vec2 size)
nk_draw_image
NK_API void nk_draw_image(struct nk_command_buffer *, struct nk_rect, const struct nk_image *, struct nk_color)
nk_chart::h
float h
Definition: nuklear.h:5280
nk_str_append_str_char
NK_API int nk_str_append_str_char(struct nk_str *, const char *)
nk_image::h
unsigned short h
Definition: nuklear.h:465
nk_text_undo_state::redo_point
short redo_point
Definition: nuklear.h:4264
nk_chart_begin_colored
NK_API int nk_chart_begin_colored(struct nk_context *, enum nk_chart_type, struct nk_color, struct nk_color active, int num, float min, float max)
NK_EDIT_CTRL_ENTER_NEWLINE
@ NK_EDIT_CTRL_ENTER_NEWLINE
Definition: nuklear.h:3424
nk_chart_push_slot
NK_API nk_flags nk_chart_push_slot(struct nk_context *, float, int)
nk_tooltip
NK_API void nk_tooltip(struct nk_context *, const char *)
NK_PANEL_POPUP
@ NK_PANEL_POPUP
Definition: nuklear.h:5256
nk_context::begin
struct nk_window * begin
Definition: nuklear.h:5601
nk_panel::row
struct nk_row_layout row
Definition: nuklear.h:5338
NK_COMMAND_LINE
@ NK_COMMAND_LINE
Definition: nuklear.h:4377
nk_input_begin
NK_API void nk_input_begin(struct nk_context *)
nk_combobox
NK_API void nk_combobox(struct nk_context *, const char **items, int count, int *selected, int item_height, struct nk_vec2 size)
NK_CURSOR_RESIZE_VERTICAL
@ NK_CURSOR_RESIZE_VERTICAL
Definition: nuklear.h:3596
nk_command_text::background
struct nk_color background
Definition: nuklear.h:4548
nk_command_circle_filled::x
short x
Definition: nuklear.h:4482
nk_window_show
NK_API void nk_window_show(struct nk_context *, const char *name, enum nk_show_states)
nk_clipboard
Definition: nuklear.h:4247
nk_window_get_size
NK_API struct nk_vec2 nk_window_get_size(const struct nk_context *)
nk_style_slider::cursor_size
struct nk_vec2 cursor_size
Definition: nuklear.h:4941
nk_stroke_polygon
NK_API void nk_stroke_polygon(struct nk_command_buffer *, float *, int point_count, float line_thickness, struct nk_color)
nk_command_circle_filled::h
unsigned short h
Definition: nuklear.h:4483
nk_radio_text
NK_API int nk_radio_text(struct nk_context *, const char *, int, int *active)
nk_command_scissor::h
unsigned short h
Definition: nuklear.h:4408
nk_style_window_header::label_hover
struct nk_color label_hover
Definition: nuklear.h:5165
nk_widget_has_mouse_click_down
NK_API int nk_widget_has_mouse_click_down(struct nk_context *, enum nk_buttons, int down)
nk_style_slider::userdata
nk_handle userdata
Definition: nuklear.h:4951
nk_style_selectable::text_hover
struct nk_color text_hover
Definition: nuklear.h:4895
nk_property_double
NK_API void nk_property_double(struct nk_context *, const char *name, double min, double *val, double max, double step, float inc_per_pixel)
nk_hsva_iv
NK_API struct nk_color nk_hsva_iv(const int *hsva)
nk_style_button::text_hover
struct nk_color text_hover
Definition: nuklear.h:4835
nk_textedit_paste
NK_API int nk_textedit_paste(struct nk_text_edit *, char const *, int len)
nk_popup_state::win
struct nk_window * win
Definition: nuklear.h:5371
nk_checkbox_flags_label
NK_API int nk_checkbox_flags_label(struct nk_context *, const char *, unsigned int *flags, unsigned int value)
nk_chart::slots
struct nk_chart_slot slots[NK_CHART_MAX_SLOT]
Definition: nuklear.h:5281
nk_command_arc
Definition: nuklear.h:4487
nk_style_combo::spacing
struct nk_vec2 spacing
Definition: nuklear.h:5121
nk_command_circle::x
short x
Definition: nuklear.h:4474
nk_str_insert_text_runes
NK_API int nk_str_insert_text_runes(struct nk_str *, int pos, const nk_rune *, int)
nk_rgb_fv
NK_API struct nk_color nk_rgb_fv(const float *rgb)
nk_radio_label
NK_API int nk_radio_label(struct nk_context *, const char *, int *active)
nk_style_progress::cursor_border_color
struct nk_color cursor_border_color
Definition: nuklear.h:4967
NK_EDIT_BOX
@ NK_EDIT_BOX
Definition: nuklear.h:3433
nk_colorf::g
float g
Definition: nuklear.h:458
nk_input::keyboard
struct nk_keyboard keyboard
Definition: nuklear.h:4626
NK_WINDOW_REMOVE_ROM
@ NK_WINDOW_REMOVE_ROM
Definition: nuklear.h:5366
nk_option_text
NK_API int nk_option_text(struct nk_context *, const char *, int, int active)
nk_combo_begin_color
NK_API int nk_combo_begin_color(struct nk_context *, struct nk_color color, struct nk_vec2 size)
NK_LAYOUT_TEMPLATE
@ NK_LAYOUT_TEMPLATE
Definition: nuklear.h:5293
nk_memory
Definition: nuklear.h:4117
nk_keyboard::text
char text[NK_INPUT_MAX]
Definition: nuklear.h:4621
nk_color::b
nk_byte b
Definition: nuklear.h:457
nk_option_label
NK_API int nk_option_label(struct nk_context *, const char *, int active)
NK_CONFIGURATION_STACK_TYPE
#define NK_CONFIGURATION_STACK_TYPE(prefix, name, type)
Definition: nuklear.h:5488
nk_context
Definition: nuklear.h:5569
nk_contextual_item_label
NK_API int nk_contextual_item_label(struct nk_context *, const char *, nk_flags align)
nk_text_edit::select_start
int select_start
Definition: nuklear.h:4287
NK_TEXT_RIGHT
@ NK_TEXT_RIGHT
Definition: nuklear.h:3083
nk_filter_decimal
NK_API int nk_filter_decimal(const struct nk_text_edit *, nk_rune unicode)
nk_widget
NK_API enum nk_widget_layout_states nk_widget(struct nk_rect *, const struct nk_context *)
nk_panel::max_x
float max_x
Definition: nuklear.h:5331
nk_style_push_color
NK_API int nk_style_push_color(struct nk_context *, struct nk_color *, struct nk_color)
nk_mouse::grabbed
unsigned char grabbed
Definition: nuklear.h:4611
NK_API
#define NK_API
Definition: nuklear.h:262
nk_style_property::label_normal
struct nk_color label_normal
Definition: nuklear.h:5057
nk_panel_set
nk_panel_set
Definition: nuklear.h:5262
nk_command_curve::end
struct nk_vec2i end
Definition: nuklear.h:4423
nk_buffer_free
NK_API void nk_buffer_free(struct nk_buffer *)
NK_RGBA
@ NK_RGBA
Definition: nuklear.h:477
nk_style_chart::border_color
struct nk_color border_color
Definition: nuklear.h:5083
nk_utf_len
NK_API int nk_utf_len(const char *, int byte_len)
NK_SYMBOL_RECT_OUTLINE
@ NK_SYMBOL_RECT_OUTLINE
Definition: nuklear.h:500
nk_style_window::tooltip_border_color
struct nk_color tooltip_border_color
Definition: nuklear.h:5186
NK_LEN
#define NK_LEN(a)
Definition: nuklear.h:5619
nk_input_motion
NK_API void nk_input_motion(struct nk_context *, int x, int y)
NK_WINDOW_TITLE
@ NK_WINDOW_TITLE
Definition: nuklear.h:1457
nk_panel::border
float border
Definition: nuklear.h:5334
nk_str_len
NK_API int nk_str_len(struct nk_str *)
NK_PANEL_WINDOW
@ NK_PANEL_WINDOW
Definition: nuklear.h:5254
nk_style::edit
struct nk_style_edit edit
Definition: nuklear.h:5229
nk_command_polygon_filled::color
struct nk_color color
Definition: nuklear.h:4514
nk_style_slider::hover
struct nk_style_item hover
Definition: nuklear.h:4920
nk_command_rect_filled::y
short y
Definition: nuklear.h:4440
nk_command_rect::h
unsigned short h
Definition: nuklear.h:4433
NK_MIN
#define NK_MIN(a, b)
Definition: nuklear.h:302
nk_button_symbol_label
NK_API int nk_button_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags text_alignment)
nk_rgba_hex
NK_API struct nk_color nk_rgba_hex(const char *rgb)
nk_text_undo_record::delete_length
short delete_length
Definition: nuklear.h:4256
nk_button_image
NK_API int nk_button_image(struct nk_context *, struct nk_image img)
nk_input_has_mouse_click
NK_API int nk_input_has_mouse_click(const struct nk_input *, enum nk_buttons)
nk_button_image_label_styled
NK_API int nk_button_image_label_styled(struct nk_context *, const struct nk_style_button *, struct nk_image img, const char *, nk_flags text_alignment)
nk_vec2i
Definition: nuklear.h:460
nk_text_undo_state::redo_char_point
short redo_char_point
Definition: nuklear.h:4266
nk_orientation
nk_orientation
Definition: nuklear.h:472
NK_TEXT_ALIGN_RIGHT
@ NK_TEXT_ALIGN_RIGHT
Definition: nuklear.h:3075
nk_text_edit::has_preferred_x
unsigned char has_preferred_x
Definition: nuklear.h:4292
NK_UINT16
#define NK_UINT16
Definition: nuklear.h:350
nk_str::buffer
struct nk_buffer buffer
Definition: nuklear.h:4165
nk_tooltip_end
NK_API void nk_tooltip_end(struct nk_context *)
nk_color_hsva_fv
NK_API void nk_color_hsva_fv(float *hsva_out, struct nk_color)
NK_KEY_UP
@ NK_KEY_UP
Definition: nuklear.h:746
nk_hsva_fv
NK_API struct nk_color nk_hsva_fv(const float *hsva)
nk_input_button
NK_API void nk_input_button(struct nk_context *, enum nk_buttons, int x, int y, int down)
NK_COLOR_BUTTON
@ NK_COLOR_BUTTON
Definition: nuklear.h:3566
nk_menu_begin_symbol_label
NK_API int nk_menu_begin_symbol_label(struct nk_context *, const char *, nk_flags align, enum nk_symbol_type, struct nk_vec2 size)
NK_LAYOUT_STATIC_FREE
@ NK_LAYOUT_STATIC_FREE
Definition: nuklear.h:5291
nk_button_push_behavior
NK_API int nk_button_push_behavior(struct nk_context *, enum nk_button_behavior)
nk_color_hsva_iv
NK_API void nk_color_hsva_iv(int *hsva_out, struct nk_color)
nk_spacing
NK_API void nk_spacing(struct nk_context *, int cols)
nk_input_any_mouse_click_in_rect
NK_API int nk_input_any_mouse_click_in_rect(const struct nk_input *, struct nk_rect)
nk_memory::ptr
void * ptr
Definition: nuklear.h:4117
nk_page::size
unsigned int size
Definition: nuklear.h:5553
nk_image::handle
nk_handle handle
Definition: nuklear.h:465
nk_image_is_subimage
NK_API int nk_image_is_subimage(const struct nk_image *img)
nk_input_key
NK_API void nk_input_key(struct nk_context *, enum nk_keys, int down)
nk_command_rect_multi_color::h
unsigned short h
Definition: nuklear.h:4448
nk_page_element
Definition: nuklear.h:5546
nk_style_tab::text
struct nk_color text
Definition: nuklear.h:5128
nk_context::use_pool
int use_pool
Definition: nuklear.h:5599
nk_property_state::state
int state
Definition: nuklear.h:5405
nk_buffer_clear
NK_API void nk_buffer_clear(struct nk_buffer *)
nk_style_pop_vec2
NK_API int nk_style_pop_vec2(struct nk_context *)
nk_style_combo::rounding
float rounding
Definition: nuklear.h:5118
nk_window_get_height
NK_API float nk_window_get_height(const struct nk_context *)
nk_context::text_edit
struct nk_text_edit text_edit
Definition: nuklear.h:5593
nk_propertyf
NK_API float nk_propertyf(struct nk_context *, const char *name, float min, float val, float max, float step, float inc_per_pixel)
nk_window_get_width
NK_API float nk_window_get_width(const struct nk_context *)
nk_chart_slot::min
float min
Definition: nuklear.h:5272
NK_COMMAND_RECT_FILLED
@ NK_COMMAND_RECT_FILLED
Definition: nuklear.h:4380
nk_text_undo_state::undo_char_point
short undo_char_point
Definition: nuklear.h:4265
nk_configuration_stacks::floats
struct nk_config_stack_float floats
Definition: nuklear.h:5518
nk_command_buffer::base
struct nk_buffer * base
Definition: nuklear.h:4563
nk_panel::clip
struct nk_rect clip
Definition: nuklear.h:5336
NK_TEXT_ALIGN_LEFT
@ NK_TEXT_ALIGN_LEFT
Definition: nuklear.h:3073
nk_combo_close
NK_API void nk_combo_close(struct nk_context *)
nk_menu_end
NK_API void nk_menu_end(struct nk_context *)
nk_style_slider::bar_normal
struct nk_color bar_normal
Definition: nuklear.h:4925
NK_CURSOR_RESIZE_HORIZONTAL
@ NK_CURSOR_RESIZE_HORIZONTAL
Definition: nuklear.h:3597
nk_fill_rect
NK_API void nk_fill_rect(struct nk_command_buffer *, struct nk_rect, float rounding, struct nk_color)
nk_convert_config::vertex_alignment
nk_size vertex_alignment
Definition: nuklear.h:1164
nk_menu_state
Definition: nuklear.h:5320
nk_style_item_data::image
struct nk_image image
Definition: nuklear.h:4811
nk_style_property::normal
struct nk_style_item normal
Definition: nuklear.h:5051
nk_selectable_label
NK_API int nk_selectable_label(struct nk_context *, const char *, nk_flags align, int *value)
nk_edit_flags
nk_edit_flags
Definition: nuklear.h:3415
NK_ANTI_ALIASING_ON
@ NK_ANTI_ALIASING_ON
Definition: nuklear.h:1142
nk_memory::size
nk_size size
Definition: nuklear.h:4117
nk_style_progress::cursor_normal
struct nk_style_item cursor_normal
Definition: nuklear.h:4964
nk_recti::h
short h
Definition: nuklear.h:462
nk_command_polygon::points
struct nk_vec2i points[1]
Definition: nuklear.h:4509
nk_menu_begin_image_text
NK_API int nk_menu_begin_image_text(struct nk_context *, const char *, int, nk_flags align, struct nk_image, struct nk_vec2 size)
nk_style_window::popup_border
float popup_border
Definition: nuklear.h:5195
nk_mouse::pos
struct nk_vec2 pos
Definition: nuklear.h:4606
nk_command_text
Definition: nuklear.h:4545
nk_property_state::select_end
int select_end
Definition: nuklear.h:5401
nk_style_button::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle userdata)
Definition: nuklear.h:4849
NK_WIDGET_STATE_ENTERED
@ NK_WIDGET_STATE_ENTERED
Definition: nuklear.h:3049
nk_style_button::border_color
struct nk_color border_color
Definition: nuklear.h:4830
nk_text_edit::cursor_at_end_of_line
unsigned char cursor_at_end_of_line
Definition: nuklear.h:4290
nk_allocator::free
nk_plugin_free free
Definition: nuklear.h:491
nk_hsv_iv
NK_API struct nk_color nk_hsv_iv(const int *hsv)
nk_window::popup
struct nk_popup_state popup
Definition: nuklear.h:5422
nk_convert_config::vertex_layout
const struct nk_draw_vertex_layout_element * vertex_layout
Definition: nuklear.h:1162
nk_style_slider
Definition: nuklear.h:4917
nk_menu_begin_symbol_text
NK_API int nk_menu_begin_symbol_text(struct nk_context *, const char *, int, nk_flags align, enum nk_symbol_type, struct nk_vec2 size)
nk_check_flags_text
NK_API unsigned nk_check_flags_text(struct nk_context *, const char *, int, unsigned int flags, unsigned int value)
nk_tree_pop
NK_API void nk_tree_pop(struct nk_context *)
NK_CHART_COLUMN
@ NK_CHART_COLUMN
Definition: nuklear.h:475
NK_STYLE_ITEM_STACK_SIZE
#define NK_STYLE_ITEM_STACK_SIZE
Definition: nuklear.h:5469
nk_window_get_scroll
NK_API void nk_window_get_scroll(struct nk_context *, nk_uint *offset_x, nk_uint *offset_y)
nk_table::keys
nk_hash keys[NK_VALUE_PAGE_CAPACITY]
Definition: nuklear.h:5535
nk_command_rect::x
short x
Definition: nuklear.h:4432
nk_buffer::size
nk_size size
Definition: nuklear.h:4135
nk_style_button::normal
struct nk_style_item normal
Definition: nuklear.h:4827
nk_row_layout::index
int index
Definition: nuklear.h:5298
nk_convert_config::vertex_size
nk_size vertex_size
Definition: nuklear.h:1163
nk_group_scrolled_offset_begin
NK_API int nk_group_scrolled_offset_begin(struct nk_context *, nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags)
NK_DOWN
@ NK_DOWN
Definition: nuklear.h:469
nk_text_edit::initialized
unsigned char initialized
Definition: nuklear.h:4291
nk_row_layout::item_height
float item_height
Definition: nuklear.h:5304
nk_utf_at
const NK_API char * nk_utf_at(const char *buffer, int length, int index, nk_rune *unicode, int *len)
nk__begin
NK_API const struct nk_command * nk__begin(struct nk_context *)
nk_style_hide_cursor
NK_API void nk_style_hide_cursor(struct nk_context *)
nk_str_insert_text_utf8
NK_API int nk_str_insert_text_utf8(struct nk_str *, int pos, const char *, int)
NK_WIDGET_STATE_ACTIVED
@ NK_WIDGET_STATE_ACTIVED
Definition: nuklear.h:3051
nk_window::scrollbar_hiding_timer
float scrollbar_hiding_timer
Definition: nuklear.h:5418
nk_plugin_alloc
void *(* nk_plugin_alloc)(nk_handle, void *old, nk_size)
Definition: nuklear.h:482
nk_style_selectable::image_padding
struct nk_vec2 image_padding
Definition: nuklear.h:4909
nk_panel::header_height
float header_height
Definition: nuklear.h:5333
nk_style_combo::symbol_active
struct nk_color symbol_active
Definition: nuklear.h:5108
nk_command_rect::y
short y
Definition: nuklear.h:4432
nk_selectable_text
NK_API int nk_selectable_text(struct nk_context *, const char *, int, nk_flags align, int *value)
nk_convert_config::arc_segment_count
unsigned arc_segment_count
Definition: nuklear.h:1159
nk_str_remove_runes
NK_API void nk_str_remove_runes(struct nk_str *str, int len)
nk_popup_state::active
int active
Definition: nuklear.h:5375
nk_input_end
NK_API void nk_input_end(struct nk_context *)
nk_window_set_bounds
NK_API void nk_window_set_bounds(struct nk_context *, const char *name, struct nk_rect bounds)
nk_mouse::buttons
struct nk_mouse_button buttons[NK_BUTTON_MAX]
Definition: nuklear.h:4605
nk_tree_image_push_hashed
NK_API int nk_tree_image_push_hashed(struct nk_context *, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, const char *hash, int len, int seed)
nk_style_edit::cursor_text_hover
struct nk_color cursor_text_hover
Definition: nuklear.h:5027
nk_widget_bounds
NK_API struct nk_rect nk_widget_bounds(struct nk_context *)
nk_colorf::r
float r
Definition: nuklear.h:458
nk_chart_slot::count
int count
Definition: nuklear.h:5273
nk_style_window_header::minimize_symbol
enum nk_symbol_type minimize_symbol
Definition: nuklear.h:5160
nk_allocation_type
nk_allocation_type
Definition: nuklear.h:4101
nk_edit_events
nk_edit_events
Definition: nuklear.h:3436
nk_style_progress
Definition: nuklear.h:4956
nk_command_text::foreground
struct nk_color foreground
Definition: nuklear.h:4549
nk_stroke_rect
NK_API void nk_stroke_rect(struct nk_command_buffer *, struct nk_rect, float rounding, float line_thickness, struct nk_color)
nk_style_scrollbar::cursor_normal
struct nk_style_item cursor_normal
Definition: nuklear.h:4990
nk_rect_pos
NK_API struct nk_vec2 nk_rect_pos(struct nk_rect)
nk_window::name_string
char name_string[NK_WINDOW_MAX_NAME]
Definition: nuklear.h:5411
nk_panel::chart
struct nk_chart chart
Definition: nuklear.h:5339
nk_combo_begin_image_text
NK_API int nk_combo_begin_image_text(struct nk_context *, const char *selected, int, struct nk_image, struct nk_vec2 size)
NK_COLOR_SELECT
@ NK_COLOR_SELECT
Definition: nuklear.h:3572
nk_style_edit::scrollbar
struct nk_style_scrollbar scrollbar
Definition: nuklear.h:5021
nk_command_triangle_filled::header
struct nk_command header
Definition: nuklear.h:4465
nk_buffer::marker
struct nk_buffer_marker marker[NK_BUFFER_MAX]
Definition: nuklear.h:4119
nk_panel::at_y
float at_y
Definition: nuklear.h:5331
nk_command_triangle::c
struct nk_vec2i c
Definition: nuklear.h:4460
nk_user_font
Definition: nuklear.h:3914
nk_window::bounds
struct nk_rect bounds
Definition: nuklear.h:5414
nk_rgb_f
NK_API struct nk_color nk_rgb_f(float r, float g, float b)
nk_buffer::type
enum nk_allocation_type type
Definition: nuklear.h:4123
nk_style::selectable
struct nk_style_selectable selectable
Definition: nuklear.h:5225
nk_cursor::offset
struct nk_vec2 size offset
Definition: nuklear.h:466
nk_style_selectable::text_pressed_active
struct nk_color text_pressed_active
Definition: nuklear.h:4901
NK_CURSOR_ARROW
@ NK_CURSOR_ARROW
Definition: nuklear.h:3593
nk_memory_status
Definition: nuklear.h:4092
nk_style_scrollbar::border_color
struct nk_color border_color
Definition: nuklear.h:4987
nk_style_combo::symbol_hover
struct nk_color symbol_hover
Definition: nuklear.h:5107
nk_button_pop_behavior
NK_API int nk_button_pop_behavior(struct nk_context *)
nk_chart_slot::max
float max
Definition: nuklear.h:5272
nk_list_view::scroll_value
nk_uint scroll_value
Definition: nuklear.h:3032
nk_layout_row
NK_API void nk_layout_row(struct nk_context *, enum nk_layout_format, float height, int cols, const float *ratio)
nk_filter_oct
NK_API int nk_filter_oct(const struct nk_text_edit *, nk_rune unicode)
nk_style_button::userdata
nk_handle userdata
Definition: nuklear.h:4847
nk_style_edit::cursor_normal
struct nk_color cursor_normal
Definition: nuklear.h:5024
nk_propertyd
NK_API double nk_propertyd(struct nk_context *, const char *name, double min, double val, double max, double step, float inc_per_pixel)
nk_rgb_cf
NK_API struct nk_color nk_rgb_cf(struct nk_colorf c)
nk_command_type
nk_command_type
Definition: nuklear.h:4374
nk_command_buffer
Definition: nuklear.h:4562
nk_hsva_colorf
NK_API struct nk_colorf nk_hsva_colorf(float h, float s, float v, float a)
nk_textedit_free
NK_API void nk_textedit_free(struct nk_text_edit *)
NK_VALUE_PAGE_CAPACITY
#define NK_VALUE_PAGE_CAPACITY
Definition: nuklear.h:5529
nk_style_toggle::hover
struct nk_style_item hover
Definition: nuklear.h:4855
nk_prog
NK_API nk_size nk_prog(struct nk_context *, nk_size cur, nk_size max, int modifyable)
NK_BUFFER_FRONT
@ NK_BUFFER_FRONT
Definition: nuklear.h:4107
NK_INTERN
#define NK_INTERN
Definition: nuklear.h:273
nk_style_property::dec_button
struct nk_style_button dec_button
Definition: nuklear.h:5072
nk_slider_int
NK_API int nk_slider_int(struct nk_context *, int min, int *val, int max, int step)
NK_WINDOW_MOVABLE
@ NK_WINDOW_MOVABLE
Definition: nuklear.h:1452
nk_style_combo::button
struct nk_style_button button
Definition: nuklear.h:5111
nk_edit_state::seq
unsigned int seq
Definition: nuklear.h:5384
nk_combo_begin_image_label
NK_API int nk_combo_begin_image_label(struct nk_context *, const char *selected, struct nk_image, struct nk_vec2 size)
nk_widget_height
NK_API float nk_widget_height(struct nk_context *)
nk_convert_config::global_alpha
float global_alpha
Definition: nuklear.h:1155
nk_rect
Definition: nuklear.h:461
nk_style_property::userdata
nk_handle userdata
Definition: nuklear.h:5075
nk_hsv_f
NK_API struct nk_color nk_hsv_f(float h, float s, float v)
nk_ptr_add
#define nk_ptr_add(t, p, i)
Definition: nuklear.h:5634
NK_COLOR_BUTTON_ACTIVE
@ NK_COLOR_BUTTON_ACTIVE
Definition: nuklear.h:3568
nk_style_toggle::cursor_hover
struct nk_style_item cursor_hover
Definition: nuklear.h:4861
NK_COMMAND_CURVE
@ NK_COMMAND_CURVE
Definition: nuklear.h:4378
NK_COLOR_HEADER
@ NK_COLOR_HEADER
Definition: nuklear.h:3564
nk_style::window
struct nk_style_window window
Definition: nuklear.h:5235
nk_command_polygon_filled
Definition: nuklear.h:4512
nk_popup_state
Definition: nuklear.h:5370
nk_pool::size
nk_size size
Definition: nuklear.h:5565
NK_WINDOW_SCALE_LEFT
@ NK_WINDOW_SCALE_LEFT
Definition: nuklear.h:1460
NK_EDIT_NO_CURSOR
@ NK_EDIT_NO_CURSOR
Definition: nuklear.h:3421
nk_str::len
int len
Definition: nuklear.h:4166
nk_edit_string
NK_API nk_flags nk_edit_string(struct nk_context *, nk_flags, char *buffer, int *len, int max, nk_plugin_filter)
nk_buffer_marker::offset
nk_size offset
Definition: nuklear.h:4114
nk_textedit_delete
NK_API void nk_textedit_delete(struct nk_text_edit *, int where, int len)
nk_panel::flags
nk_flags flags
Definition: nuklear.h:5327
nk_slide_float
NK_API float nk_slide_float(struct nk_context *, float min, float val, float max, float step)
nk_command_rect::header
struct nk_command header
Definition: nuklear.h:4429
nk_hash
nk_uint nk_hash
Definition: nuklear.h:408
nk_slide_int
NK_API int nk_slide_int(struct nk_context *, int min, int val, int max, int step)
nk_selectable_image_text
NK_API int nk_selectable_image_text(struct nk_context *, struct nk_image, const char *, int, nk_flags align, int *value)
nk_text_edit::preferred_x
float preferred_x
Definition: nuklear.h:4296
nk_context::current
struct nk_window * current
Definition: nuklear.h:5604
nk_style_selectable::text_background
struct nk_color text_background
Definition: nuklear.h:4902
nk_checkbox_label
NK_API int nk_checkbox_label(struct nk_context *, const char *, int *active)
nk_input_is_mouse_pressed
NK_API int nk_input_is_mouse_pressed(const struct nk_input *, enum nk_buttons)
NK_KEY_PASTE
@ NK_KEY_PASTE
Definition: nuklear.h:745
NK_KEY_TAB
@ NK_KEY_TAB
Definition: nuklear.h:741
nk_command_buffer::use_clipping
int use_clipping
Definition: nuklear.h:4565
nk_command_image::y
short y
Definition: nuklear.h:4529
nk_command_custom
Definition: nuklear.h:4537
nk_vec2_add
#define nk_vec2_add(a, b)
Definition: nuklear.h:5630
nk_command_rect_filled::header
struct nk_command header
Definition: nuklear.h:4438
nk_style_item_color
NK_API struct nk_style_item nk_style_item_color(struct nk_color)
nk_window_get_bounds
NK_API struct nk_rect nk_window_get_bounds(const struct nk_context *ctx)
nk_slider_float
NK_API int nk_slider_float(struct nk_context *, float min, float *val, float max, float step)
nk_false
@ nk_false
Definition: nuklear.h:456
nk_selectable_symbol_text
NK_API int nk_selectable_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags align, int *value)
nk_style_selectable
Definition: nuklear.h:4882
nk_text_edit::select_end
int select_end
Definition: nuklear.h:4288
NK_CURSOR_RESIZE_TOP_LEFT_DOWN_RIGHT
@ NK_CURSOR_RESIZE_TOP_LEFT_DOWN_RIGHT
Definition: nuklear.h:3598
nk_style::menu_button
struct nk_style_button menu_button
Definition: nuklear.h:5222
nk_row_layout::height
float height
Definition: nuklear.h:5299
nk_style_window_header::maximize_symbol
enum nk_symbol_type maximize_symbol
Definition: nuklear.h:5161
NK_WINDOW_NOT_INTERACTIVE
@ NK_WINDOW_NOT_INTERACTIVE
Definition: nuklear.h:5358
nk_handle_ptr
NK_API nk_handle nk_handle_ptr(void *)
nk_menu_begin_image
NK_API int nk_menu_begin_image(struct nk_context *, const char *, struct nk_image, struct nk_vec2 size)
nk_style_slider::cursor_hover
struct nk_style_item cursor_hover
Definition: nuklear.h:4932
nk_color_format
nk_color_format
Definition: nuklear.h:477
nk_input_is_key_released
NK_API int nk_input_is_key_released(const struct nk_input *, enum nk_keys)
NK_WIDGET_VALID
@ NK_WIDGET_VALID
Definition: nuklear.h:3043
nk_command_triangle::header
struct nk_command header
Definition: nuklear.h:4456
nk_style_window::popup_padding
struct nk_vec2 popup_padding
Definition: nuklear.h:5205
nk_chart::w
float w
Definition: nuklear.h:5280
nk_convert_config::shape_AA
enum nk_anti_aliasing shape_AA
Definition: nuklear.h:1157
NK_COLOR_SLIDER_CURSOR
@ NK_COLOR_SLIDER_CURSOR
Definition: nuklear.h:3575
nk_command_arc::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4491
nk_mouse
Definition: nuklear.h:4604
nk_chart_type
nk_chart_type
Definition: nuklear.h:475
NK_BETWEEN
#define NK_BETWEEN(x, a, b)
Definition: nuklear.h:5621
nk_begin_titled
NK_API int nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags)
nk_command_custom::y
short y
Definition: nuklear.h:4539
nk_command_polygon::header
struct nk_command header
Definition: nuklear.h:4505
nk_text_edit::scrollbar
struct nk_vec2 scrollbar
Definition: nuklear.h:4284
nk_text_edit::active
unsigned char active
Definition: nuklear.h:4294
nk_group_begin
NK_API int nk_group_begin(struct nk_context *, const char *title, nk_flags)
nk_textedit_undo
NK_API void nk_textedit_undo(struct nk_text_edit *)
nk_strfilter
NK_API int nk_strfilter(const char *text, const char *regexp)
nk_image_handle
NK_API struct nk_image nk_image_handle(nk_handle)
nk_style_window_header::align
enum nk_style_header_align align
Definition: nuklear.h:5169
nk_style_window::scrollbar_size
struct nk_vec2 scrollbar_size
Definition: nuklear.h:5200
nk_style
Definition: nuklear.h:5212
nk_clear
NK_API void nk_clear(struct nk_context *)
nk_style::cursor_active
const struct nk_cursor * cursor_active
Definition: nuklear.h:5215
nk_style_toggle::normal
struct nk_style_item normal
Definition: nuklear.h:4854
nk_style_item::data
union nk_style_item_data data
Definition: nuklear.h:4817
nk_context::memory
struct nk_buffer memory
Definition: nuklear.h:5573
nk_style_tab::node_maximize_button
struct nk_style_button node_maximize_button
Definition: nuklear.h:5133
nk_input_is_mouse_hovering_rect
NK_API int nk_input_is_mouse_hovering_rect(const struct nk_input *, struct nk_rect)
NK_COMMAND_TEXT
@ NK_COMMAND_TEXT
Definition: nuklear.h:4391
nk_layout_ratio_from_pixel
NK_API float nk_layout_ratio_from_pixel(struct nk_context *, float pixel_width)
nk_command_arc_filled::cy
short cy
Definition: nuklear.h:4498
NK_WINDOW_ROM
@ NK_WINDOW_ROM
Definition: nuklear.h:5356
nk_style_selectable::hover
struct nk_style_item hover
Definition: nuklear.h:4885
nk_context::style
struct nk_style style
Definition: nuklear.h:5572
NK_KEY_TEXT_INSERT_MODE
@ NK_KEY_TEXT_INSERT_MODE
Definition: nuklear.h:751
nk_button_text
NK_API int nk_button_text(struct nk_context *, const char *title, int len)
nk_handle_id
NK_API nk_handle nk_handle_id(int)
nk_str_append_str_runes
NK_API int nk_str_append_str_runes(struct nk_str *, const nk_rune *)
nk_chart_begin
NK_API int nk_chart_begin(struct nk_context *, enum nk_chart_type, int num, float min, float max)
nk_combo_item_image_label
NK_API int nk_combo_item_image_label(struct nk_context *, struct nk_image, const char *, nk_flags alignment)
nk_window_set_position
NK_API void nk_window_set_position(struct nk_context *, const char *name, struct nk_vec2 pos)
NK_UINT8
#define NK_UINT8
Definition: nuklear.h:344
nk_style_chart::padding
struct nk_vec2 padding
Definition: nuklear.h:5090
nk_style_window::tooltip_padding
struct nk_vec2 tooltip_padding
Definition: nuklear.h:5209
nk_triangle_from_direction
NK_API void nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r, float pad_x, float pad_y, enum nk_heading)
nk_str_free
NK_API void nk_str_free(struct nk_str *)
nk_edit_buffer
NK_API nk_flags nk_edit_buffer(struct nk_context *, nk_flags, struct nk_text_edit *, nk_plugin_filter)
nk_window_show_if
NK_API void nk_window_show_if(struct nk_context *, const char *name, enum nk_show_states, int cond)
nk_menubar_begin
NK_API void nk_menubar_begin(struct nk_context *)
nk_command_image::img
struct nk_image img
Definition: nuklear.h:4531
NK_PANEL_GROUP
@ NK_PANEL_GROUP
Definition: nuklear.h:5255
nk_panel::at_x
float at_x
Definition: nuklear.h:5331
nk_strmatch_fuzzy_string
NK_API int nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score)
nk_short
NK_INT16 nk_short
Definition: nuklear.h:401
nk_chart_slot::highlight
struct nk_color highlight
Definition: nuklear.h:5271
NK_EDIT_NO_HORIZONTAL_SCROLL
@ NK_EDIT_NO_HORIZONTAL_SCROLL
Definition: nuklear.h:3425
nk_style_edit::cursor_hover
struct nk_color cursor_hover
Definition: nuklear.h:5025
NK_MINIMIZED
@ NK_MINIMIZED
Definition: nuklear.h:473
nk_menu_begin_label
NK_API int nk_menu_begin_label(struct nk_context *, const char *, nk_flags align, struct nk_vec2 size)
nk_filter_float
NK_API int nk_filter_float(const struct nk_text_edit *, nk_rune unicode)
NK_COLOR_SLIDER
@ NK_COLOR_SLIDER
Definition: nuklear.h:3574
nk_edit_state::old
unsigned int old
Definition: nuklear.h:5385
NK_KEY_DOWN
@ NK_KEY_DOWN
Definition: nuklear.h:747
NK_SYMBOL_MAX
@ NK_SYMBOL_MAX
Definition: nuklear.h:507
nk_style_toggle::spacing
float spacing
Definition: nuklear.h:4873
nk_style::text
struct nk_style_text text
Definition: nuklear.h:5219
nk_layout_row_template_end
NK_API void nk_layout_row_template_end(struct nk_context *)
nk_group_begin_titled
NK_API int nk_group_begin_titled(struct nk_context *, const char *name, const char *title, nk_flags)
nk_command_arc_filled::header
struct nk_command header
Definition: nuklear.h:4497
nk_recti::y
short y
Definition: nuklear.h:462
nk_property_state::seq
unsigned int seq
Definition: nuklear.h:5403
NK_EDIT_ALLOW_TAB
@ NK_EDIT_ALLOW_TAB
Definition: nuklear.h:3420
nk_window_flags
nk_window_flags
Definition: nuklear.h:5352
NK_SYMBOL_CIRCLE_SOLID
@ NK_SYMBOL_CIRCLE_SOLID
Definition: nuklear.h:497
nk_window_is_active
NK_API int nk_window_is_active(struct nk_context *, const char *)
nk_style_slider::dec_symbol
enum nk_symbol_type dec_symbol
Definition: nuklear.h:4948
NK_ANTI_ALIASING_OFF
@ NK_ANTI_ALIASING_OFF
Definition: nuklear.h:1142
nk_command_text::font
const struct nk_user_font * font
Definition: nuklear.h:4547
NK_COMMAND_CIRCLE
@ NK_COMMAND_CIRCLE
Definition: nuklear.h:4382
nk_popup_state::combo_count
unsigned combo_count
Definition: nuklear.h:5376
nk_combo_string
NK_API int nk_combo_string(struct nk_context *, const char *items_separated_by_zeros, int selected, int count, int item_height, struct nk_vec2 size)
nk_menu_state::w
float w
Definition: nuklear.h:5321
nk_group_scrolled_begin
NK_API int nk_group_scrolled_begin(struct nk_context *, struct nk_scroll *off, const char *title, nk_flags)
nk_rect::x
float x
Definition: nuklear.h:461
nk_command_rect_multi_color::header
struct nk_command header
Definition: nuklear.h:4446
nk_list_view_begin
NK_API int nk_list_view_begin(struct nk_context *, struct nk_list_view *out, const char *id, nk_flags, int row_height, int row_count)
nk_color_hsva_b
NK_API void nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color)
NK_TEXT_ALIGN_TOP
@ NK_TEXT_ALIGN_TOP
Definition: nuklear.h:3076
nk_style_slider::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4952
NK_MODIFIABLE
@ NK_MODIFIABLE
Definition: nuklear.h:471
nk_plot_function
NK_API void nk_plot_function(struct nk_context *, enum nk_chart_type, void *userdata, float(*value_getter)(void *user, int index), int count, int offset)
NK_COLOR_SCROLLBAR_CURSOR
@ NK_COLOR_SCROLLBAR_CURSOR
Definition: nuklear.h:3586
nk_panel
Definition: nuklear.h:5325
nk_style::progress
struct nk_style_progress progress
Definition: nuklear.h:5227
nk_input_is_mouse_down
NK_API int nk_input_is_mouse_down(const struct nk_input *, enum nk_buttons)
nk_style_selectable::draw_begin
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4913
NK_WINDOW_SCALABLE
@ NK_WINDOW_SCALABLE
Definition: nuklear.h:1453
nk_style_toggle::text_alignment
nk_flags text_alignment
Definition: nuklear.h:4868
nk_command_arc_filled::a
float a[2]
Definition: nuklear.h:4500
NK_TEXTEDIT_UNDOSTATECOUNT
#define NK_TEXTEDIT_UNDOSTATECOUNT
Definition: nuklear.h:4239
nk_plugin_copy
void(* nk_plugin_copy)(nk_handle, const char *, int len)
Definition: nuklear.h:486
nk_input_unicode
NK_API void nk_input_unicode(struct nk_context *, nk_rune)
nk_property_state::active
int active
Definition: nuklear.h:5396
nk_button_symbol_text_styled
NK_API int nk_button_symbol_text_styled(struct nk_context *, const struct nk_style_button *, enum nk_symbol_type, const char *, int, nk_flags alignment)
nk_row_layout::templates
float templates[NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS]
Definition: nuklear.h:5309
NK_INPUT_MAX
#define NK_INPUT_MAX
Definition: nuklear.h:237
nk_style_toggle::padding
struct nk_vec2 padding
Definition: nuklear.h:4871
nk_command_triangle::a
struct nk_vec2i a
Definition: nuklear.h:4458
nk_recti
NK_API struct nk_rect nk_recti(int x, int y, int w, int h)
nk_command_triangle::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4457
nk_style_load_all_cursors
NK_API void nk_style_load_all_cursors(struct nk_context *, struct nk_cursor *)
NK_BUTTON_REPEATER
@ NK_BUTTON_REPEATER
Definition: nuklear.h:470
nk_style_button::active
struct nk_style_item active
Definition: nuklear.h:4829
nk_style_push_style_item
NK_API int nk_style_push_style_item(struct nk_context *, struct nk_style_item *, struct nk_style_item)
nk_button_symbol
NK_API int nk_button_symbol(struct nk_context *, enum nk_symbol_type)
nk_property_state
Definition: nuklear.h:5395
nk_popup_state::header
struct nk_rect header
Definition: nuklear.h:5379
nk_row_layout
Definition: nuklear.h:5296
NK_BUFFER_BACK
@ NK_BUFFER_BACK
Definition: nuklear.h:4108
nk_popup_buffer::last
nk_size last
Definition: nuklear.h:5315
nk_configuration_stacks
Definition: nuklear.h:5516
NK_CONVERT_ELEMENT_BUFFER_FULL
@ NK_CONVERT_ELEMENT_BUFFER_FULL
Definition: nuklear.h:1148
NK_SYMBOL_TRIANGLE_RIGHT
@ NK_SYMBOL_TRIANGLE_RIGHT
Definition: nuklear.h:504
nk_style_edit::selected_normal
struct nk_color selected_normal
Definition: nuklear.h:5035
NK_COLOR_SCROLLBAR_CURSOR_HOVER
@ NK_COLOR_SCROLLBAR_CURSOR_HOVER
Definition: nuklear.h:3587
nk_fill_triangle
NK_API void nk_fill_triangle(struct nk_command_buffer *, float x0, float y0, float x1, float y1, float x2, float y2, struct nk_color)
nk_style_edit::row_padding
float row_padding
Definition: nuklear.h:5046
nk_property_state::cursor
int cursor
Definition: nuklear.h:5399
nk_vec2_len_sqr
#define nk_vec2_len_sqr(a)
Definition: nuklear.h:5631
nk_style_property::sym_left
enum nk_symbol_type sym_left
Definition: nuklear.h:5062
nk_command_circle::y
short y
Definition: nuklear.h:4474
nk_str_get
NK_API char * nk_str_get(struct nk_str *)
nk_command_arc::r
unsigned short r
Definition: nuklear.h:4490
nk_property_state::prev
int prev
Definition: nuklear.h:5396
nk_selectable_symbol_label
NK_API int nk_selectable_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags align, int *value)
NK_BUTTON_DOUBLE
@ NK_BUTTON_DOUBLE
Definition: nuklear.h:774
nk_text_undo_state::undo_rec
struct nk_text_undo_record undo_rec[NK_TEXTEDIT_UNDOSTATECOUNT]
Definition: nuklear.h:4261
nk_style_push_vec2
NK_API int nk_style_push_vec2(struct nk_context *, struct nk_vec2 *, struct nk_vec2)
nk_style_button::padding
struct nk_vec2 padding
Definition: nuklear.h:4842
nk_popup_set_scroll
NK_API void nk_popup_set_scroll(struct nk_context *, nk_uint offset_x, nk_uint offset_y)
nk_command_circle::line_thickness
unsigned short line_thickness
Definition: nuklear.h:4475
nk_buffer_info
NK_API void nk_buffer_info(struct nk_memory_status *, struct nk_buffer *)
nk_tree_element_push_hashed
NK_API int nk_tree_element_push_hashed(struct nk_context *, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, int *selected, const char *hash, int len, int seed)
nk_style_window
Definition: nuklear.h:5175
nk_menu_begin_symbol
NK_API int nk_menu_begin_symbol(struct nk_context *, const char *, enum nk_symbol_type, struct nk_vec2 size)
NK_EDIT_SIG_ENTER
@ NK_EDIT_SIG_ENTER
Definition: nuklear.h:3419
nk_window_has_focus
NK_API int nk_window_has_focus(const struct nk_context *)
nk_style::button
struct nk_style_button button
Definition: nuklear.h:5220
nk_style_edit::cursor_size
float cursor_size
Definition: nuklear.h:5043
nk_command_arc_filled::cx
short cx
Definition: nuklear.h:4498
nk_rectiv
NK_API struct nk_rect nk_rectiv(const int *xywh)
NK_LAYOUT_DYNAMIC
@ NK_LAYOUT_DYNAMIC
Definition: nuklear.h:5288
nk_color_hsv_i
NK_API void nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color)
NK_INTERSECT
#define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1)
Definition: nuklear.h:5624
NK_TREE_NODE
@ NK_TREE_NODE
Definition: nuklear.h:480
NK_WIDGET_STATE_HOVER
@ NK_WIDGET_STATE_HOVER
Definition: nuklear.h:3050
nk_end
NK_API void nk_end(struct nk_context *ctx)
NK_CONTAINER_OF
#define NK_CONTAINER_OF(ptr, type, member)
Definition: nuklear.h:5662
nk_clipboard::copy
nk_plugin_copy copy
Definition: nuklear.h:4250
NK_STATIC
@ NK_STATIC
Definition: nuklear.h:479
nk_keyboard::keys
struct nk_key keys[NK_KEY_MAX]
Definition: nuklear.h:4620
NK_KEY_SCROLL_END
@ NK_KEY_SCROLL_END
Definition: nuklear.h:765
nk_style_selectable::padding
struct nk_vec2 padding
Definition: nuklear.h:4907
NK_STYLE_ITEM_COLOR
@ NK_STYLE_ITEM_COLOR
Definition: nuklear.h:4806
nk_property_state::select_start
int select_start
Definition: nuklear.h:5400
NK_TEXT_EDIT_MODE_VIEW
@ NK_TEXT_EDIT_MODE_VIEW
Definition: nuklear.h:4275
nk_command_rect_filled
Definition: nuklear.h:4437
nk_command_triangle::b
struct nk_vec2i b
Definition: nuklear.h:4459
nk_text_edit_mode
nk_text_edit_mode
Definition: nuklear.h:4274
nk_list_view::end
int end
Definition: nuklear.h:3027
NK_KEY_SCROLL_UP
@ NK_KEY_SCROLL_UP
Definition: nuklear.h:767
nk_fill_polygon
NK_API void nk_fill_polygon(struct nk_command_buffer *, float *, int point_count, struct nk_color)
nk_style_pop_style_item
NK_API int nk_style_pop_style_item(struct nk_context *)
nk_style_colors
nk_style_colors
Definition: nuklear.h:3561
nk_pool::alloc
struct nk_allocator alloc
Definition: nuklear.h:5559
NK_COMMAND_SCISSOR
@ NK_COMMAND_SCISSOR
Definition: nuklear.h:4376
nk_style_window_header::padding
struct nk_vec2 padding
Definition: nuklear.h:5170
nk_style_edit::selected_text_normal
struct nk_color selected_text_normal
Definition: nuklear.h:5037
NK_VERTICAL
@ NK_VERTICAL
Definition: nuklear.h:472
nk_style_combo::symbol_normal
struct nk_color symbol_normal
Definition: nuklear.h:5106
nk_style_toggle::text_normal
struct nk_color text_normal
Definition: nuklear.h:4864
nk_style_window::header
struct nk_style_window_header header
Definition: nuklear.h:5176
nk_contextual_item_image_label
NK_API int nk_contextual_item_image_label(struct nk_context *, struct nk_image, const char *, nk_flags alignment)
nk_combobox_string
NK_API void nk_combobox_string(struct nk_context *, const char *items_separated_by_zeros, int *selected, int count, int item_height, struct nk_vec2 size)
NK_SYMBOL_CIRCLE_OUTLINE
@ NK_SYMBOL_CIRCLE_OUTLINE
Definition: nuklear.h:498
nk_layout_row_push
NK_API void nk_layout_row_push(struct nk_context *, float value)
nk_ushort
NK_UINT16 nk_ushort
Definition: nuklear.h:402
nk_style_slider::show_buttons
int show_buttons
Definition: nuklear.h:4944
NK_PANEL_SET_POPUP
@ NK_PANEL_SET_POPUP
Definition: nuklear.h:5264
win
nk_window * win
Definition: Gui.cpp:24
nk_command_arc_filled::color
struct nk_color color
Definition: nuklear.h:4501
NK_COMMAND_POLYLINE
@ NK_COMMAND_POLYLINE
Definition: nuklear.h:4390
nk_chart::y
float y
Definition: nuklear.h:5280
nk_str_get_const
const NK_API char * nk_str_get_const(const struct nk_str *)
nk_style_progress::cursor_active
struct nk_style_item cursor_active
Definition: nuklear.h:4966
nk_style::cursor_last
struct nk_cursor * cursor_last
Definition: nuklear.h:5216
nk_panel::has_scrolling
unsigned int has_scrolling
Definition: nuklear.h:5335
nk_buffer_total
NK_API nk_size nk_buffer_total(struct nk_buffer *)
nk_style_scrollbar::userdata
nk_handle userdata
Definition: nuklear.h:5010
nk_menu_begin_text
NK_API int nk_menu_begin_text(struct nk_context *, const char *title, int title_len, nk_flags align, struct nk_vec2 size)
nk_style_slider::padding
struct nk_vec2 padding
Definition: nuklear.h:4939
nk_style_window::group_border_color
struct nk_color group_border_color
Definition: nuklear.h:5185
nk_style_scrollbar::inc_button
struct nk_style_button inc_button
Definition: nuklear.h:5004
nk_str_at_char_const
const NK_API char * nk_str_at_char_const(const struct nk_str *, int pos)
NK_CONVERT_INVALID_PARAM
@ NK_CONVERT_INVALID_PARAM
Definition: nuklear.h:1145
NK_PTR_TO_UINT
#define NK_PTR_TO_UINT(x)
Definition: nuklear.h:5647
NK_KEY_SCROLL_START
@ NK_KEY_SCROLL_START
Definition: nuklear.h:764
nk_text_alignment
nk_text_alignment
Definition: nuklear.h:3080
nk_scroll
Definition: nuklear.h:467
NK_LAYOUT_DYNAMIC_FREE
@ NK_LAYOUT_DYNAMIC_FREE
Definition: nuklear.h:5287
nk_vec2i
NK_API struct nk_vec2 nk_vec2i(int x, int y)
nk_style_toggle::active
struct nk_style_item active
Definition: nuklear.h:4856
NK_COLOR_CHART
@ NK_COLOR_CHART
Definition: nuklear.h:3582
nk_buffer::pool
struct nk_allocator pool
Definition: nuklear.h:4121
NK_BUTTON_LEFT
@ NK_BUTTON_LEFT
Definition: nuklear.h:771
nk_button_image_text
NK_API int nk_button_image_text(struct nk_context *, struct nk_image img, const char *, int, nk_flags alignment)
nk_select_image_label
NK_API int nk_select_image_label(struct nk_context *, struct nk_image, const char *, nk_flags align, int value)
NK_KEY_SCROLL_DOWN
@ NK_KEY_SCROLL_DOWN
Definition: nuklear.h:766
nk_command_line::begin
struct nk_vec2i begin
Definition: nuklear.h:4414
nk_row_layout::item
struct nk_rect item
Definition: nuklear.h:5307
nk_filter_hex
NK_API int nk_filter_hex(const struct nk_text_edit *, nk_rune unicode)
nk_window_get_content_region
NK_API struct nk_rect nk_window_get_content_region(struct nk_context *)
nk_window::scrollbar
struct nk_scroll scrollbar
Definition: nuklear.h:5415
NK_LAYOUT_STATIC
@ NK_LAYOUT_STATIC
Definition: nuklear.h:5292
NK_KEY_ENTER
@ NK_KEY_ENTER
Definition: nuklear.h:740
nk_style_edit::hover
struct nk_style_item hover
Definition: nuklear.h:5018
nk_utf_decode
NK_API int nk_utf_decode(const char *, nk_rune *, int)
NK_LAYOUT_DYNAMIC_FIXED
@ NK_LAYOUT_DYNAMIC_FIXED
Definition: nuklear.h:5285
nk_buffer_allocation_type
nk_buffer_allocation_type
Definition: nuklear.h:4106
nk_layout_space_begin
NK_API void nk_layout_space_begin(struct nk_context *, enum nk_layout_format, float height, int widget_count)
nk_style_pop_flags
NK_API int nk_style_pop_flags(struct nk_context *)
nk_image_color
NK_API void nk_image_color(struct nk_context *, struct nk_image, struct nk_color)
nk_widget_states
nk_widget_states
Definition: nuklear.h:3046
nk_str_insert_at_char
NK_API int nk_str_insert_at_char(struct nk_str *, int pos, const char *, int)
NK_KEY_TEXT_LINE_END
@ NK_KEY_TEXT_LINE_END
Definition: nuklear.h:755
nk_command_image
Definition: nuklear.h:4527
nk_menu_begin_image_label
NK_API int nk_menu_begin_image_label(struct nk_context *, const char *, nk_flags align, struct nk_image, struct nk_vec2 size)
nk_style_slider::cursor_active
struct nk_style_item cursor_active
Definition: nuklear.h:4933
nk_property_state::length
int length
Definition: nuklear.h:5398
nk_str_init
NK_API void nk_str_init(struct nk_str *, const struct nk_allocator *, nk_size size)
nk_button_symbol_label_styled
NK_API int nk_button_symbol_label_styled(struct nk_context *ctx, const struct nk_style_button *style, enum nk_symbol_type symbol, const char *title, nk_flags align)
nk_str_append_str_utf8
NK_API int nk_str_append_str_utf8(struct nk_str *, const char *)
nk_query_font_glyph_f
void(* nk_query_font_glyph_f)(nk_handle handle, float font_height, struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
Definition: nuklear.h:3897
nk_command_arc::a
float a[2]
Definition: nuklear.h:4492
nk_rgb_hex
NK_API struct nk_color nk_rgb_hex(const char *rgb)
nk_chart_slot::index
int index
Definition: nuklear.h:5275
NK_COMMAND_IMAGE
@ NK_COMMAND_IMAGE
Definition: nuklear.h:4392
NK_WINDOW_CLOSABLE
@ NK_WINDOW_CLOSABLE
Definition: nuklear.h:1454
nk_style_window_header::spacing
struct nk_vec2 spacing
Definition: nuklear.h:5172
NK_STORAGE
#define NK_STORAGE
Definition: nuklear.h:274
NK_PANEL_SET_NONBLOCK
@ NK_PANEL_SET_NONBLOCK
Definition: nuklear.h:5263
nk_context::count
unsigned int count
Definition: nuklear.h:5606
nk_style::chart
struct nk_style_chart chart
Definition: nuklear.h:5230
nk_text_edit::padding1
unsigned char padding1
Definition: nuklear.h:4295
nk_command_triangle_filled::a
struct nk_vec2i a
Definition: nuklear.h:4466
nk_command_rect_multi_color::top
struct nk_color top
Definition: nuklear.h:4450
nk_style_slider::bar_filled
struct nk_color bar_filled
Definition: nuklear.h:4928
nk_handle
Definition: nuklear.h:464
nk_text_undo_record::char_storage
short char_storage
Definition: nuklear.h:4257
nk_style_chart
Definition: nuklear.h:5080
nk_input_is_mouse_click_down_in_rect
NK_API int nk_input_is_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id, struct nk_rect b, int down)
nk_command_text::header
struct nk_command header
Definition: nuklear.h:4546
nk_menu_state::h
float h
Definition: nuklear.h:5321
nk_window_get_canvas
NK_API struct nk_command_buffer * nk_window_get_canvas(struct nk_context *)
nk_list_view::ctx
struct nk_context * ctx
Definition: nuklear.h:3030
nk_edit_state::mode
unsigned char mode
Definition: nuklear.h:5391
nk_window_is_closed
NK_API int nk_window_is_closed(struct nk_context *, const char *)
nk_style_selectable::pressed
struct nk_style_item pressed
Definition: nuklear.h:4886
nk_label_colored
NK_API void nk_label_colored(struct nk_context *, const char *, nk_flags align, struct nk_color)
nk_command_curve
Definition: nuklear.h:4419
nk_combo_item_image_text
NK_API int nk_combo_item_image_text(struct nk_context *, struct nk_image, const char *, int, nk_flags alignment)
nk_colorf_hsva_fv
NK_API void nk_colorf_hsva_fv(float *hsva, struct nk_colorf in)
nk_color_dv
NK_API void nk_color_dv(double *rgba_out, struct nk_color)
nk_context::overlay
struct nk_command_buffer overlay
Definition: nuklear.h:5595
nk_checkbox_text
NK_API int nk_checkbox_text(struct nk_context *, const char *, int, int *active)
NK_KEY_SHIFT
@ NK_KEY_SHIFT
Definition: nuklear.h:737
nk_buffer::allocated
nk_size allocated
Definition: nuklear.h:4129
nk_subimage_id
NK_API struct nk_image nk_subimage_id(int, unsigned short w, unsigned short h, struct nk_rect sub_region)
nk_window::layout
struct nk_panel * layout
Definition: nuklear.h:5417
nk_menu_item_image_text
NK_API int nk_menu_item_image_text(struct nk_context *, struct nk_image, const char *, int len, nk_flags alignment)
nk_style_window::popup_border_color
struct nk_color popup_border_color
Definition: nuklear.h:5181
nk_style_edit::border_color
struct nk_color border_color
Definition: nuklear.h:5020
nk_recti::w
short w
Definition: nuklear.h:462
nk_rect::h
float h
Definition: nuklear.h:461
nk_style_toggle::text_background
struct nk_color text_background
Definition: nuklear.h:4867
nk_command_text::height
float height
Definition: nuklear.h:4552
nk_selectable_image_label
NK_API int nk_selectable_image_label(struct nk_context *, struct nk_image, const char *, nk_flags align, int *value)
NK_TEXT_EDIT_MULTI_LINE
@ NK_TEXT_EDIT_MULTI_LINE
Definition: nuklear.h:4271
NK_BUTTON_RIGHT
@ NK_BUTTON_RIGHT
Definition: nuklear.h:773
NK_SYMBOL_UNDERSCORE
@ NK_SYMBOL_UNDERSCORE
Definition: nuklear.h:496
NK_COLOR_EDIT
@ NK_COLOR_EDIT
Definition: nuklear.h:3579
nk_command_polyline
Definition: nuklear.h:4519
nk_tooltip_begin
NK_API int nk_tooltip_begin(struct nk_context *, float width)
nk_style_tab::tab_maximize_button
struct nk_style_button tab_maximize_button
Definition: nuklear.h:5131
nk_row_layout::ratio
const float * ratio
Definition: nuklear.h:5302
nk_str_rune_at
NK_API nk_rune nk_str_rune_at(const struct nk_str *, int pos)
nk_panel::parent
struct nk_panel * parent
Definition: nuklear.h:5341
nk_textedit_redo
NK_API void nk_textedit_redo(struct nk_text_edit *)
nk_murmur_hash
NK_API nk_hash nk_murmur_hash(const void *key, int len, nk_hash seed)
NK_LAYOUT_COUNT
@ NK_LAYOUT_COUNT
Definition: nuklear.h:5294
NK_COLOR_SCROLLBAR_CURSOR_ACTIVE
@ NK_COLOR_SCROLLBAR_CURSOR_ACTIVE
Definition: nuklear.h:3588
NK_HEADER_LEFT
@ NK_HEADER_LEFT
Definition: nuklear.h:5147
nk_colorf_hsva_f
NK_API void nk_colorf_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_colorf in)
nk_zero_struct
#define nk_zero_struct(s)
Definition: nuklear.h:5636
nk_style::scrollh
struct nk_style_scrollbar scrollh
Definition: nuklear.h:5231
nk_check_label
NK_API int nk_check_label(struct nk_context *, const char *, int active)
NK_KEY_RIGHT
@ NK_KEY_RIGHT
Definition: nuklear.h:749
nk_pool
Definition: nuklear.h:5558
nk_rgba_cf
NK_API struct nk_color nk_rgba_cf(struct nk_colorf c)
nk_layout_row_template_push_variable
NK_API void nk_layout_row_template_push_variable(struct nk_context *, float min_width)
nk_layout_format
nk_layout_format
Definition: nuklear.h:479
nk_panel::footer_height
float footer_height
Definition: nuklear.h:5332
nk_command_scissor
Definition: nuklear.h:4405
NK_FLAGS_STACK_SIZE
#define NK_FLAGS_STACK_SIZE
Definition: nuklear.h:5481
nk_edit_unfocus
NK_API void nk_edit_unfocus(struct nk_context *)
nk_window::name
nk_hash name
Definition: nuklear.h:5410
nk_style_button::border
float border
Definition: nuklear.h:4840
nk_combo_begin_symbol_text
NK_API int nk_combo_begin_symbol_text(struct nk_context *, const char *selected, int, enum nk_symbol_type, struct nk_vec2 size)
nk_style_set_font
NK_API void nk_style_set_font(struct nk_context *, const struct nk_user_font *)
nk_popup_state::type
enum nk_panel_type type
Definition: nuklear.h:5372
nk_color_d
NK_API void nk_color_d(double *r, double *g, double *b, double *a, struct nk_color)
nk_style_edit::border
float border
Definition: nuklear.h:5041
nk_scroll::x
nk_uint x
Definition: nuklear.h:467
NK_RIGHT
@ NK_RIGHT
Definition: nuklear.h:469
nk_command_buffer::clip
struct nk_rect clip
Definition: nuklear.h:4564
nk_style_property::label_hover
struct nk_color label_hover
Definition: nuklear.h:5058
nk_context::last_widget_state
nk_flags last_widget_state
Definition: nuklear.h:5575
nk_window_get_content_region_max
NK_API struct nk_vec2 nk_window_get_content_region_max(struct nk_context *)
nk_input_char
NK_API void nk_input_char(struct nk_context *, char)
NK_PANEL_COMBO
@ NK_PANEL_COMBO
Definition: nuklear.h:5258
nk_color_hsv_b
NK_API void nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color)
NK_KEY_MAX
@ NK_KEY_MAX
Definition: nuklear.h:768
nk_style_pop_color
NK_API int nk_style_pop_color(struct nk_context *)
nk_list_view::total_height
int total_height
Definition: nuklear.h:3029
nk_panel::offset_x
nk_uint * offset_x
Definition: nuklear.h:5329
nk_command_rect
Definition: nuklear.h:4428
nk_style_property::active
struct nk_style_item active
Definition: nuklear.h:5053
NK_BUTTON_MAX
@ NK_BUTTON_MAX
Definition: nuklear.h:775
nk_chart_end
NK_API void nk_chart_end(struct nk_context *)
nk_style_combo::content_padding
struct nk_vec2 content_padding
Definition: nuklear.h:5119
nk_menu_item_symbol_text
NK_API int nk_menu_item_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment)
nk_show_states
nk_show_states
Definition: nuklear.h:474
nk_tree_state_image_push
NK_API int nk_tree_state_image_push(struct nk_context *, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states *state)
nk_layout_row_template_push_static
NK_API void nk_layout_row_template_push_static(struct nk_context *, float width)
NK_COLOR_TOGGLE_CURSOR
@ NK_COLOR_TOGGLE_CURSOR
Definition: nuklear.h:3571
NK_COLOR_STACK_SIZE
#define NK_COLOR_STACK_SIZE
Definition: nuklear.h:5485
nk_combo_begin_symbol_label
NK_API int nk_combo_begin_symbol_label(struct nk_context *, const char *selected, enum nk_symbol_type, struct nk_vec2 size)
nk_vec2::x
float x
Definition: nuklear.h:459
nk_widget_size
NK_API struct nk_vec2 nk_widget_size(struct nk_context *)
nk_colorf::a
float a
Definition: nuklear.h:458
nk_row_layout::tree_depth
int tree_depth
Definition: nuklear.h:5308
nk_style::tab
struct nk_style_tab tab
Definition: nuklear.h:5233
nk_rgba_iv
NK_API struct nk_color nk_rgba_iv(const int *rgba)
nk_chart_push
NK_API nk_flags nk_chart_push(struct nk_context *, float)
nk_command_text::x
short x
Definition: nuklear.h:4550
nk_style::slider
struct nk_style_slider slider
Definition: nuklear.h:5226
nk_buffer::grow_factor
float grow_factor
Definition: nuklear.h:4127
NK_TEXT_LEFT
@ NK_TEXT_LEFT
Definition: nuklear.h:3081
nk_style_tab::indent
float indent
Definition: nuklear.h:5141
nk_style_window::combo_border
float combo_border
Definition: nuklear.h:5190
nk_menu_item_symbol_label
NK_API int nk_menu_item_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags alignment)
nk_edit_state::single_line
unsigned char single_line
Definition: nuklear.h:5392
NK_EDIT_SIMPLE
@ NK_EDIT_SIMPLE
Definition: nuklear.h:3431
nk_check_flags_label
NK_API unsigned nk_check_flags_label(struct nk_context *, const char *, unsigned int flags, unsigned int value)
nk_context::stacks
struct nk_configuration_stacks stacks
Definition: nuklear.h:5577
nk_edit_state::active
int active
Definition: nuklear.h:5386
nk_style_tab::sym_maximize
enum nk_symbol_type sym_maximize
Definition: nuklear.h:5136
NK_UNUSED
#define NK_UNUSED(x)
Definition: nuklear.h:5617
nk_style_chart::border
float border
Definition: nuklear.h:5088
nk_command_circle::header
struct nk_command header
Definition: nuklear.h:4473
nk_input_mouse_clicked
NK_API int nk_input_mouse_clicked(const struct nk_input *, enum nk_buttons, struct nk_rect)
nk_str_insert_str_char
NK_API int nk_str_insert_str_char(struct nk_str *, int pos, const char *)
nk_style_window_header::label_active
struct nk_color label_active
Definition: nuklear.h:5166
nk_command_polyline::points
struct nk_vec2i points[1]
Definition: nuklear.h:4524
nk_button_label
NK_API int nk_button_label(struct nk_context *, const char *title)
nk_memory_status::allocated
nk_size allocated
Definition: nuklear.h:4096
nk_window::scrolled
unsigned int scrolled
Definition: nuklear.h:5424
nk_command_text::length
int length
Definition: nuklear.h:4553
nk_window_get_content_region_size
NK_API struct nk_vec2 nk_window_get_content_region_size(struct nk_context *)
nk_row_layout::item_offset
float item_offset
Definition: nuklear.h:5305
nk_edit_focus
NK_API void nk_edit_focus(struct nk_context *, nk_flags flags)
NK_MAX
#define NK_MAX(a, b)
Definition: nuklear.h:303
nk_get_null_rect
NK_API struct nk_rect nk_get_null_rect(void)
nk_command_rect::color
struct nk_color color
Definition: nuklear.h:4434
nk_style_combo::label_active
struct nk_color label_active
Definition: nuklear.h:5103
NK_PANEL_SET_SUB
@ NK_PANEL_SET_SUB
Definition: nuklear.h:5265
nk_style_progress::border_color
struct nk_color border_color
Definition: nuklear.h:4961
nk_style_tab::border_color
struct nk_color border_color
Definition: nuklear.h:5127
nk_buttons
nk_buttons
Definition: nuklear.h:770
nk_style_tab::node_minimize_button
struct nk_style_button node_minimize_button
Definition: nuklear.h:5134
nk_style_window::min_size
struct nk_vec2 min_size
Definition: nuklear.h:5201
nk_list_view
Definition: nuklear.h:3025
nk_style_scrollbar::draw_end
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:5012
nk_check_text
NK_API int nk_check_text(struct nk_context *, const char *, int, int active)
nk_command_arc::cy
short cy
Definition: nuklear.h:4489
NK_WIDGET_STATE_INACTIVE
@ NK_WIDGET_STATE_INACTIVE
Definition: nuklear.h:3048
nk_command_image::header
struct nk_command header
Definition: nuklear.h:4528
NK_EDIT_ACTIVE
@ NK_EDIT_ACTIVE
Definition: nuklear.h:3437
nk_style_scrollbar::border_cursor
float border_cursor
Definition: nuklear.h:4998
nk_str_remove_chars
NK_API void nk_str_remove_chars(struct nk_str *, int len)
NK_HORIZONTAL
@ NK_HORIZONTAL
Definition: nuklear.h:472
nk_style_selectable::text_normal_active
struct nk_color text_normal_active
Definition: nuklear.h:4899
nk_hsva_f
NK_API struct nk_color nk_hsva_f(float h, float s, float v, float a)
nk_mouse::ungrab
unsigned char ungrab
Definition: nuklear.h:4612
nk_command_rect_filled::rounding
unsigned short rounding
Definition: nuklear.h:4439
nk_style_item_image
NK_API struct nk_style_item nk_style_item_image(struct nk_image img)
NK_FIXED
@ NK_FIXED
Definition: nuklear.h:471
nk_command_curve::ctrl
struct nk_vec2i ctrl[2]
Definition: nuklear.h:4424
nk_style_scrollbar::cursor_hover
struct nk_style_item cursor_hover
Definition: nuklear.h:4991
NK_EDIT_FIELD
@ NK_EDIT_FIELD
Definition: nuklear.h:3432
nk_filter_default
NK_API int nk_filter_default(const struct nk_text_edit *, nk_rune unicode)
nk_color_hsva_f
NK_API void nk_color_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_color)
NK_EDIT_AUTO_SELECT
@ NK_EDIT_AUTO_SELECT
Definition: nuklear.h:3418
nk_command_circle_filled::color
struct nk_color color
Definition: nuklear.h:4484
NK_COMMAND_ARC_FILLED
@ NK_COMMAND_ARC_FILLED
Definition: nuklear.h:4385
NK_WINDOW_NO_INPUT
@ NK_WINDOW_NO_INPUT
Definition: nuklear.h:1461