nuklear.h
Go to the documentation of this file.
1 /*
212 */
213 #ifndef NK_SINGLE_FILE
214  #define NK_SINGLE_FILE
215 #endif
216 
217 #ifndef NK_NUKLEAR_H_
218 #define NK_NUKLEAR_H_
219 
220 #ifdef __cplusplus
221 extern "C" {
222 #endif
223 /*
224  * ==============================================================
225  *
226  * CONSTANTS
227  *
228  * ===============================================================
229  */
230 #define NK_UNDEFINED (-1.0f)
231 #define NK_UTF_INVALID 0xFFFD /* internal invalid utf8 rune */
232 #define NK_UTF_SIZE 4 /* describes the number of bytes a glyph consists of*/
233 #ifndef NK_INPUT_MAX
234  #define NK_INPUT_MAX 16
235 #endif
236 #ifndef NK_MAX_NUMBER_BUFFER
237  #define NK_MAX_NUMBER_BUFFER 64
238 #endif
239 #ifndef NK_SCROLLBAR_HIDING_TIMEOUT
240  #define NK_SCROLLBAR_HIDING_TIMEOUT 4.0f
241 #endif
242 /*
243  * ==============================================================
244  *
245  * HELPER
246  *
247  * ===============================================================
248  */
249 #ifndef NK_API
250  #ifdef NK_PRIVATE
251  #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199409L))
252  #define NK_API static inline
253  #elif defined(__cplusplus)
254  #define NK_API static inline
255  #else
256  #define NK_API static
257  #endif
258  #else
259  #define NK_API extern
260  #endif
261 #endif
262 #ifndef NK_LIB
263  #ifdef NK_SINGLE_FILE
264  #define NK_LIB static
265  #else
266  #define NK_LIB extern
267  #endif
268 #endif
269 
270 #define NK_INTERN static
271 #define NK_STORAGE static
272 #define NK_GLOBAL static
273 
274 #define NK_FLAG(x) (1 << (x))
275 #define NK_STRINGIFY(x) #x
276 #define NK_MACRO_STRINGIFY(x) NK_STRINGIFY(x)
277 #define NK_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2
278 #define NK_STRING_JOIN_DELAY(arg1, arg2) NK_STRING_JOIN_IMMEDIATE(arg1, arg2)
279 #define NK_STRING_JOIN(arg1, arg2) NK_STRING_JOIN_DELAY(arg1, arg2)
280 
281 #ifdef _MSC_VER
282  #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__COUNTER__)
283 #else
284  #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__LINE__)
285 #endif
286 
287 #ifndef NK_STATIC_ASSERT
288  #define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1]
289 #endif
290 
291 #ifndef NK_FILE_LINE
292 #ifdef _MSC_VER
293  #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__COUNTER__)
294 #else
295  #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__LINE__)
296 #endif
297 #endif
298 
299 #define NK_MIN(a,b) ((a) < (b) ? (a) : (b))
300 #define NK_MAX(a,b) ((a) < (b) ? (b) : (a))
301 #define NK_CLAMP(i,v,x) (NK_MAX(NK_MIN(v,x), i))
302 
303 #ifdef NK_INCLUDE_STANDARD_VARARGS
304  #if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */
305  #include <sal.h>
306  #define NK_PRINTF_FORMAT_STRING _Printf_format_string_
307  #else
308  #define NK_PRINTF_FORMAT_STRING
309  #endif
310  #if defined(__GNUC__)
311  #define NK_PRINTF_VARARG_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, fmtargnumber+1)))
312  #define NK_PRINTF_VALIST_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, 0)))
313  #else
314  #define NK_PRINTF_VARARG_FUNC(fmtargnumber)
315  #define NK_PRINTF_VALIST_FUNC(fmtargnumber)
316  #endif
317  #include <stdarg.h> /* valist, va_start, va_end, ... */
318 #endif
319 
320 /*
321  * ===============================================================
322  *
323  * BASIC
324  *
325  * ===============================================================
326  */
327 #ifdef NK_INCLUDE_FIXED_TYPES
328  #include <stdint.h>
329  #define NK_INT8 int8_t
330  #define NK_UINT8 uint8_t
331  #define NK_INT16 int16_t
332  #define NK_UINT16 uint16_t
333  #define NK_INT32 int32_t
334  #define NK_UINT32 uint32_t
335  #define NK_SIZE_TYPE uintptr_t
336  #define NK_POINTER_TYPE uintptr_t
337 #else
338  #ifndef NK_INT8
339  #define NK_INT8 char
340  #endif
341  #ifndef NK_UINT8
342  #define NK_UINT8 unsigned char
343  #endif
344  #ifndef NK_INT16
345  #define NK_INT16 signed short
346  #endif
347  #ifndef NK_UINT16
348  #define NK_UINT16 unsigned short
349  #endif
350  #ifndef NK_INT32
351  #if defined(_MSC_VER)
352  #define NK_INT32 __int32
353  #else
354  #define NK_INT32 signed int
355  #endif
356  #endif
357  #ifndef NK_UINT32
358  #if defined(_MSC_VER)
359  #define NK_UINT32 unsigned __int32
360  #else
361  #define NK_UINT32 unsigned int
362  #endif
363  #endif
364  #ifndef NK_SIZE_TYPE
365  #if defined(_WIN64) && defined(_MSC_VER)
366  #define NK_SIZE_TYPE unsigned __int64
367  #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
368  #define NK_SIZE_TYPE unsigned __int32
369  #elif defined(__GNUC__) || defined(__clang__)
370  #if defined(__x86_64__) || defined(__ppc64__)
371  #define NK_SIZE_TYPE unsigned long
372  #else
373  #define NK_SIZE_TYPE unsigned int
374  #endif
375  #else
376  #define NK_SIZE_TYPE unsigned long
377  #endif
378  #endif
379  #ifndef NK_POINTER_TYPE
380  #if defined(_WIN64) && defined(_MSC_VER)
381  #define NK_POINTER_TYPE unsigned __int64
382  #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
383  #define NK_POINTER_TYPE unsigned __int32
384  #elif defined(__GNUC__) || defined(__clang__)
385  #if defined(__x86_64__) || defined(__ppc64__)
386  #define NK_POINTER_TYPE unsigned long
387  #else
388  #define NK_POINTER_TYPE unsigned int
389  #endif
390  #else
391  #define NK_POINTER_TYPE unsigned long
392  #endif
393  #endif
394 #endif
395 
396 typedef NK_INT8 nk_char;
401 typedef NK_INT32 nk_int;
405 
406 typedef nk_uint nk_hash;
407 typedef nk_uint nk_flags;
408 typedef nk_uint nk_rune;
409 
410 /* Make sure correct type size:
411  * This will fire with a negative subscript error if the type sizes
412  * are set incorrectly by the compiler, and compile out if not */
413 NK_STATIC_ASSERT(sizeof(nk_short) == 2);
414 NK_STATIC_ASSERT(sizeof(nk_ushort) == 2);
415 NK_STATIC_ASSERT(sizeof(nk_uint) == 4);
416 NK_STATIC_ASSERT(sizeof(nk_int) == 4);
417 NK_STATIC_ASSERT(sizeof(nk_byte) == 1);
418 NK_STATIC_ASSERT(sizeof(nk_flags) >= 4);
419 NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
420 NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
421 NK_STATIC_ASSERT(sizeof(nk_ptr) >= sizeof(void*));
422 
423 /* ============================================================================
424  *
425  * API
426  *
427  * =========================================================================== */
428 struct nk_buffer;
429 struct nk_allocator;
430 struct nk_command_buffer;
431 struct nk_draw_command;
432 struct nk_convert_config;
433 struct nk_style_item;
434 struct nk_text_edit;
435 struct nk_draw_list;
436 struct nk_user_font;
437 struct nk_panel;
438 struct nk_context;
439 struct nk_draw_vertex_layout_element;
440 struct nk_style_button;
441 struct nk_style_toggle;
442 struct nk_style_selectable;
443 struct nk_style_slide;
444 struct nk_style_progress;
445 struct nk_style_scrollbar;
446 struct nk_style_edit;
447 struct nk_style_property;
448 struct nk_style_chart;
449 struct nk_style_combo;
450 struct nk_style_tab;
452 struct nk_style_window;
453 
455 struct nk_color {nk_byte r,g,b,a;};
456 struct nk_colorf {float r,g,b,a;};
457 struct nk_vec2 {float x,y;};
458 struct nk_vec2i {short x, y;};
459 struct nk_rect {float x,y,w,h;};
460 struct nk_recti {short x,y,w,h;};
461 typedef char nk_glyph[NK_UTF_SIZE];
462 typedef union {void *ptr; int id;} nk_handle;
463 struct nk_image {nk_handle handle;unsigned short w,h;unsigned short region[4];};
464 struct nk_cursor {struct nk_image img; struct nk_vec2 size, offset;};
465 struct nk_scroll {nk_uint x, y;};
466 
479 
480 typedef void*(*nk_plugin_alloc)(nk_handle, void *old, nk_size);
481 typedef void (*nk_plugin_free)(nk_handle, void *old);
482 typedef int(*nk_plugin_filter)(const struct nk_text_edit*, nk_rune unicode);
483 typedef void(*nk_plugin_paste)(nk_handle, struct nk_text_edit*);
484 typedef void(*nk_plugin_copy)(nk_handle, const char*, int len);
485 
486 struct nk_allocator {
487  nk_handle userdata;
490 };
506 };
507 /* =============================================================================
508  *
509  * CONTEXT
510  *
511  * =============================================================================*/
512 /*/// ### Context
544  */
545 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
546 /*/// #### nk_init_default
561 */
562 NK_API int nk_init_default(struct nk_context*, const struct nk_user_font*);
563 #endif
564 /*/// #### nk_init_fixed
586 */
587 NK_API int nk_init_fixed(struct nk_context*, void *memory, nk_size size, const struct nk_user_font*);
588 /*/// #### nk_init
604 */
605 NK_API int nk_init(struct nk_context*, struct nk_allocator*, const struct nk_user_font*);
606 /*/// #### nk_init_custom
623 */
624 NK_API int nk_init_custom(struct nk_context*, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font*);
625 /*/// #### nk_clear
637 */
638 NK_API void nk_clear(struct nk_context*);
639 /*/// #### nk_free
650 */
651 NK_API void nk_free(struct nk_context*);
652 #ifdef NK_INCLUDE_COMMAND_USERDATA
653 /*/// #### nk_set_user_data
664 */
665 NK_API void nk_set_user_data(struct nk_context*, nk_handle handle);
666 #endif
667 /* =============================================================================
668  *
669  * INPUT
670  *
671  * =============================================================================*/
672 /*/// ### Input
732 */
733 enum nk_keys {
748  /* Shortcuts: text field */
761  /* Shortcuts: scrollbar */
767 };
774 };
775 /*/// #### nk_input_begin
786 */
787 NK_API void nk_input_begin(struct nk_context*);
788 /*/// #### nk_input_motion
800 */
801 NK_API void nk_input_motion(struct nk_context*, int x, int y);
802 /*/// #### nk_input_key
814 */
815 NK_API void nk_input_key(struct nk_context*, enum nk_keys, int down);
816 /*/// #### nk_input_button
830 */
831 NK_API void nk_input_button(struct nk_context*, enum nk_buttons, int x, int y, int down);
832 /*/// #### nk_input_scroll
845 */
846 NK_API void nk_input_scroll(struct nk_context*, struct nk_vec2 val);
847 /*/// #### nk_input_char
863 */
864 NK_API void nk_input_char(struct nk_context*, char);
865 /*/// #### nk_input_glyph
880 */
881 NK_API void nk_input_glyph(struct nk_context*, const nk_glyph);
882 /*/// #### nk_input_unicode
896 */
897 NK_API void nk_input_unicode(struct nk_context*, nk_rune);
898 /*/// #### nk_input_end
909 */
910 NK_API void nk_input_end(struct nk_context*);
911 /* =============================================================================
912  *
913  * DRAWING
914  *
915  * =============================================================================*/
916 /*/// ### Drawing
1133 */
1141 };
1143  nk_handle texture; /* texture handle to a texture with a white pixel */
1144  struct nk_vec2 uv; /* coordinates to a white pixel in the texture */
1145 };
1147  float global_alpha; /* global alpha value */
1148  enum nk_anti_aliasing line_AA; /* line anti-aliasing flag can be turned off if you are tight on memory */
1149  enum nk_anti_aliasing shape_AA; /* shape anti-aliasing flag can be turned off if you are tight on memory */
1150  unsigned circle_segment_count; /* number of segments used for circles: default to 22 */
1151  unsigned arc_segment_count; /* number of segments used for arcs: default to 22 */
1152  unsigned curve_segment_count; /* number of segments used for curves: default to 22 */
1153  struct nk_draw_null_texture null; /* handle to texture with a white pixel for shape drawing */
1154  const struct nk_draw_vertex_layout_element *vertex_layout; /* describes the vertex output format and packing */
1155  nk_size vertex_size; /* sizeof one vertex for vertex packing */
1156  nk_size vertex_alignment; /* vertex alignment: Can be obtained by NK_ALIGNOF */
1157 };
1158 /*/// #### nk__begin
1171 */
1172 NK_API const struct nk_command* nk__begin(struct nk_context*);
1173 /*/// #### nk__next
1186 */
1187 NK_API const struct nk_command* nk__next(struct nk_context*, const struct nk_command*);
1188 /*/// #### nk_foreach
1201 */
1202 #define nk_foreach(c, ctx) for((c) = nk__begin(ctx); (c) != 0; (c) = nk__next(ctx,c))
1203 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
1204 /*/// #### nk_convert
1212 // struct nk_buffer *vertices, struct nk_buffer *elements, const struct nk_convert_config*);
1232 */
1233 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*);
1234 /*/// #### nk__draw_begin
1247 */
1248 NK_API const struct nk_draw_command* nk__draw_begin(const struct nk_context*, const struct nk_buffer*);
1249 /*/// #### nk__draw_end
1262 */
1263 NK_API const struct nk_draw_command* nk__draw_end(const struct nk_context*, const struct nk_buffer*);
1264 /*/// #### nk__draw_next
1278 */
1279 NK_API const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*, const struct nk_buffer*, const struct nk_context*);
1280 /*/// #### nk_draw_foreach
1292 */
1293 #define nk_draw_foreach(cmd,ctx, b) for((cmd)=nk__draw_begin(ctx, b); (cmd)!=0; (cmd)=nk__draw_next(cmd, b, ctx))
1294 #endif
1295 /* =============================================================================
1296  *
1297  * WINDOW
1298  *
1299  * =============================================================================
1384 //
1405 //
1410 //
1416 */
1417 /*
1439 */
1452 };
1453 /*/// #### nk_begin
1470 */
1471 NK_API int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags);
1472 /*/// #### nk_begin_titled
1490 */
1491 NK_API int nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags);
1492 /*/// #### nk_end
1503 */
1504 NK_API void nk_end(struct nk_context *ctx);
1505 /*/// #### nk_window_find
1519 */
1520 NK_API struct nk_window *nk_window_find(struct nk_context *ctx, const char *name);
1521 /*/// #### nk_window_get_bounds
1535 */
1536 NK_API struct nk_rect nk_window_get_bounds(const struct nk_context *ctx);
1537 /*/// #### nk_window_get_position
1551 */
1552 NK_API struct nk_vec2 nk_window_get_position(const struct nk_context *ctx);
1553 /*/// #### nk_window_get_size
1567 */
1568 NK_API struct nk_vec2 nk_window_get_size(const struct nk_context*);
1569 /*/// #### nk_window_get_width
1583 */
1584 NK_API float nk_window_get_width(const struct nk_context*);
1585 /*/// #### nk_window_get_height
1599 */
1600 NK_API float nk_window_get_height(const struct nk_context*);
1601 /*/// #### nk_window_get_panel
1617 */
1619 /*/// #### nk_window_get_content_region
1636 */
1638 /*/// #### nk_window_get_content_region_min
1655 */
1657 /*/// #### nk_window_get_content_region_max
1674 */
1676 /*/// #### nk_window_get_content_region_size
1692 */
1694 /*/// #### nk_window_get_canvas
1711 */
1713 /*/// #### nk_window_has_focus
1726 */
1727 NK_API int nk_window_has_focus(const struct nk_context*);
1728 /*/// #### nk_window_is_hovered
1741 */
1743 /*/// #### nk_window_is_collapsed
1756 */
1757 NK_API int nk_window_is_collapsed(struct nk_context *ctx, const char *name);
1758 /*/// #### nk_window_is_closed
1770 */
1771 NK_API int nk_window_is_closed(struct nk_context*, const char*);
1772 /*/// #### nk_window_is_hidden
1784 */
1785 NK_API int nk_window_is_hidden(struct nk_context*, const char*);
1786 /*/// #### nk_window_is_active
1798 */
1799 NK_API int nk_window_is_active(struct nk_context*, const char*);
1800 /*/// #### nk_window_is_any_hovered
1811 */
1813 /*/// #### nk_item_is_any_active
1826 */
1828 /*/// #### nk_window_set_bounds
1839 */
1840 NK_API void nk_window_set_bounds(struct nk_context*, const char *name, struct nk_rect bounds);
1841 /*/// #### nk_window_set_position
1852 */
1853 NK_API void nk_window_set_position(struct nk_context*, const char *name, struct nk_vec2 pos);
1854 /*/// #### nk_window_set_size
1865 */
1866 NK_API void nk_window_set_size(struct nk_context*, const char *name, struct nk_vec2);
1867 /*/// #### nk_window_set_focus
1877 */
1878 NK_API void nk_window_set_focus(struct nk_context*, const char *name);
1879 /*/// #### nk_window_close
1889 */
1890 NK_API void nk_window_close(struct nk_context *ctx, const char *name);
1891 /*/// #### nk_window_collapse
1902 */
1903 NK_API void nk_window_collapse(struct nk_context*, const char *name, enum nk_collapse_states state);
1904 /*/// #### nk_window_collapse_if
1916 */
1917 NK_API void nk_window_collapse_if(struct nk_context*, const char *name, enum nk_collapse_states, int cond);
1918 /*/// #### nk_window_show
1929 */
1930 NK_API void nk_window_show(struct nk_context*, const char *name, enum nk_show_states);
1931 /*/// #### nk_window_show_if
1943 */
1944 NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show_states, int cond);
1945 /* =============================================================================
1946  *
1947  * LAYOUT
1948  *
1949  * =============================================================================
2194 //
2201 //
2207 //
2211 //
2217 */
2218 /*/// #### nk_layout_set_min_row_height
2232 */
2234 /*/// #### nk_layout_reset_min_row_height
2243 */
2245 /*/// #### nk_layout_widget_bounds
2256 */
2258 /*/// #### nk_layout_ratio_from_pixel
2270 */
2271 NK_API float nk_layout_ratio_from_pixel(struct nk_context*, float pixel_width);
2272 /*/// #### nk_layout_row_dynamic
2285 */
2286 NK_API void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols);
2287 /*/// #### nk_layout_row_static
2301 */
2302 NK_API void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols);
2303 /*/// #### nk_layout_row_begin
2315 */
2316 NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols);
2317 /*/// #### nk_layout_row_push
2327 */
2328 NK_API void nk_layout_row_push(struct nk_context*, float value);
2329 /*/// #### nk_layout_row_end
2338 */
2339 NK_API void nk_layout_row_end(struct nk_context*);
2340 /*/// #### nk_layout_row
2352 */
2353 NK_API void nk_layout_row(struct nk_context*, enum nk_layout_format, float height, int cols, const float *ratio);
2354 /*/// #### nk_layout_row_template_begin
2364 */
2365 NK_API void nk_layout_row_template_begin(struct nk_context*, float row_height);
2366 /*/// #### nk_layout_row_template_push_dynamic
2376 */
2378 /*/// #### nk_layout_row_template_push_variable
2388 */
2389 NK_API void nk_layout_row_template_push_variable(struct nk_context*, float min_width);
2390 /*/// #### nk_layout_row_template_push_static
2400 */
2402 /*/// #### nk_layout_row_template_end
2411 */
2413 /*/// #### nk_layout_space_begin
2425 */
2426 NK_API void nk_layout_space_begin(struct nk_context*, enum nk_layout_format, float height, int widget_count);
2427 /*/// #### nk_layout_space_push
2437 */
2438 NK_API void nk_layout_space_push(struct nk_context*, struct nk_rect bounds);
2439 /*/// #### nk_layout_space_end
2448 */
2449 NK_API void nk_layout_space_end(struct nk_context*);
2450 /*/// #### nk_layout_space_bounds
2461 */
2463 /*/// #### nk_layout_space_to_screen
2475 */
2477 /*/// #### nk_layout_space_to_local
2489 */
2490 NK_API struct nk_vec2 nk_layout_space_to_local(struct nk_context*, struct nk_vec2);
2491 /*/// #### nk_layout_space_rect_to_screen
2503 */
2505 /*/// #### nk_layout_space_rect_to_local
2517 */
2519 /* =============================================================================
2520  *
2521  * GROUP
2522  *
2523  * =============================================================================
2591 // nk_clear(&ctx);
2604 */
2605 /*/// #### nk_group_begin
2618 */
2619 NK_API int nk_group_begin(struct nk_context*, const char *title, nk_flags);
2620 /*/// #### nk_group_begin_titled
2634 */
2635 NK_API int nk_group_begin_titled(struct nk_context*, const char *name, const char *title, nk_flags);
2636 /*/// #### nk_group_end
2645 */
2646 NK_API void nk_group_end(struct nk_context*);
2647 /*/// #### nk_group_scrolled_offset_begin
2663 */
2664 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);
2665 /*/// #### nk_group_scrolled_begin
2680 */
2681 NK_API int nk_group_scrolled_begin(struct nk_context*, struct nk_scroll *off, const char *title, nk_flags);
2682 /*/// #### nk_group_scrolled_end
2691 */
2693 /* =============================================================================
2694  *
2695  * TREE
2696  *
2697  * =============================================================================
2752 //
2762 */
2763 /*/// #### nk_tree_push
2783 */
2784 #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__)
2785 /*/// #### nk_tree_push_id
2800 */
2801 #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)
2802 /*/// #### nk_tree_push_hashed
2820 */
2821 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);
2822 /*/// #### nk_tree_image_push
2833 //
2843 */
2844 #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__)
2845 /*/// #### nk_tree_image_push_id
2863 */
2864 #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)
2865 /*/// #### nk_tree_image_push_hashed
2884 */
2885 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);
2886 /*/// #### nk_tree_pop
2895 */
2896 NK_API void nk_tree_pop(struct nk_context*);
2897 /*/// #### nk_tree_state_push
2911 */
2912 NK_API int nk_tree_state_push(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states *state);
2913 /*/// #### nk_tree_state_image_push
2928 */
2929 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);
2930 /*/// #### nk_tree_state_pop
2939 */
2940 NK_API void nk_tree_state_pop(struct nk_context*);
2941 
2942 #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__)
2943 #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)
2944 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);
2945 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);
2946 NK_API void nk_tree_element_pop(struct nk_context*);
2947 
2948 /* =============================================================================
2949  *
2950  * LIST VIEW
2951  *
2952  * ============================================================================= */
2954 /* public: */
2955  int begin, end, count;
2956 /* private: */
2958  struct nk_context *ctx;
2959  nk_uint *scroll_pointer;
2960  nk_uint scroll_value;
2961 };
2962 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);
2963 NK_API void nk_list_view_end(struct nk_list_view*);
2964 /* =============================================================================
2965  *
2966  * WIDGET
2967  *
2968  * ============================================================================= */
2970  NK_WIDGET_INVALID, /* The widget cannot be seen and is completely out of view */
2971  NK_WIDGET_VALID, /* The widget is completely inside the window and can be updated and drawn */
2972  NK_WIDGET_ROM /* The widget is partially visible and cannot be updated */
2973 };
2976  NK_WIDGET_STATE_INACTIVE = NK_FLAG(2), /* widget is neither active nor hovered */
2977  NK_WIDGET_STATE_ENTERED = NK_FLAG(3), /* widget has been hovered on the current frame */
2978  NK_WIDGET_STATE_HOVER = NK_FLAG(4), /* widget is being hovered */
2979  NK_WIDGET_STATE_ACTIVED = NK_FLAG(5),/* widget is currently activated */
2980  NK_WIDGET_STATE_LEFT = NK_FLAG(6), /* widget is from this frame on not hovered anymore */
2983 };
2984 NK_API enum nk_widget_layout_states nk_widget(struct nk_rect*, const struct nk_context*);
2986 NK_API struct nk_rect nk_widget_bounds(struct nk_context*);
2988 NK_API struct nk_vec2 nk_widget_size(struct nk_context*);
2989 NK_API float nk_widget_width(struct nk_context*);
2990 NK_API float nk_widget_height(struct nk_context*);
2993 NK_API int nk_widget_has_mouse_click_down(struct nk_context*, enum nk_buttons, int down);
2994 NK_API void nk_spacing(struct nk_context*, int cols);
2995 /* =============================================================================
2996  *
2997  * TEXT
2998  *
2999  * ============================================================================= */
3007 };
3012 };
3013 NK_API void nk_text(struct nk_context*, const char*, int, nk_flags);
3014 NK_API void nk_text_colored(struct nk_context*, const char*, int, nk_flags, struct nk_color);
3015 NK_API void nk_text_wrap(struct nk_context*, const char*, int);
3016 NK_API void nk_text_wrap_colored(struct nk_context*, const char*, int, struct nk_color);
3017 NK_API void nk_label(struct nk_context*, const char*, nk_flags align);
3018 NK_API void nk_label_colored(struct nk_context*, const char*, nk_flags align, struct nk_color);
3019 NK_API void nk_label_wrap(struct nk_context*, const char*);
3020 NK_API void nk_label_colored_wrap(struct nk_context*, const char*, struct nk_color);
3021 NK_API void nk_image(struct nk_context*, struct nk_image);
3022 NK_API void nk_image_color(struct nk_context*, struct nk_image, struct nk_color);
3023 #ifdef NK_INCLUDE_STANDARD_VARARGS
3024 NK_API void nk_labelf(struct nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(3);
3025 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);
3026 NK_API void nk_labelf_wrap(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(2);
3027 NK_API void nk_labelf_colored_wrap(struct nk_context*, struct nk_color, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(3);
3028 NK_API void nk_labelfv(struct nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(3);
3029 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);
3030 NK_API void nk_labelfv_wrap(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3031 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);
3032 NK_API void nk_value_bool(struct nk_context*, const char *prefix, int);
3033 NK_API void nk_value_int(struct nk_context*, const char *prefix, int);
3034 NK_API void nk_value_uint(struct nk_context*, const char *prefix, unsigned int);
3035 NK_API void nk_value_float(struct nk_context*, const char *prefix, float);
3036 NK_API void nk_value_color_byte(struct nk_context*, const char *prefix, struct nk_color);
3037 NK_API void nk_value_color_float(struct nk_context*, const char *prefix, struct nk_color);
3038 NK_API void nk_value_color_hex(struct nk_context*, const char *prefix, struct nk_color);
3039 #endif
3040 /* =============================================================================
3041  *
3042  * BUTTON
3043  *
3044  * ============================================================================= */
3045 NK_API int nk_button_text(struct nk_context*, const char *title, int len);
3046 NK_API int nk_button_label(struct nk_context*, const char *title);
3047 NK_API int nk_button_color(struct nk_context*, struct nk_color);
3048 NK_API int nk_button_symbol(struct nk_context*, enum nk_symbol_type);
3049 NK_API int nk_button_image(struct nk_context*, struct nk_image img);
3050 NK_API int nk_button_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags text_alignment);
3051 NK_API int nk_button_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3052 NK_API int nk_button_image_label(struct nk_context*, struct nk_image img, const char*, nk_flags text_alignment);
3053 NK_API int nk_button_image_text(struct nk_context*, struct nk_image img, const char*, int, nk_flags alignment);
3054 NK_API int nk_button_text_styled(struct nk_context*, const struct nk_style_button*, const char *title, int len);
3055 NK_API int nk_button_label_styled(struct nk_context*, const struct nk_style_button*, const char *title);
3056 NK_API int nk_button_symbol_styled(struct nk_context*, const struct nk_style_button*, enum nk_symbol_type);
3057 NK_API int nk_button_image_styled(struct nk_context*, const struct nk_style_button*, struct nk_image img);
3058 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);
3059 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);
3060 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);
3061 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);
3062 NK_API void nk_button_set_behavior(struct nk_context*, enum nk_button_behavior);
3063 NK_API int nk_button_push_behavior(struct nk_context*, enum nk_button_behavior);
3064 NK_API int nk_button_pop_behavior(struct nk_context*);
3065 /* =============================================================================
3066  *
3067  * CHECKBOX
3068  *
3069  * ============================================================================= */
3070 NK_API int nk_check_label(struct nk_context*, const char*, int active);
3071 NK_API int nk_check_text(struct nk_context*, const char*, int,int active);
3072 NK_API unsigned nk_check_flags_label(struct nk_context*, const char*, unsigned int flags, unsigned int value);
3073 NK_API unsigned nk_check_flags_text(struct nk_context*, const char*, int, unsigned int flags, unsigned int value);
3074 NK_API int nk_checkbox_label(struct nk_context*, const char*, int *active);
3075 NK_API int nk_checkbox_text(struct nk_context*, const char*, int, int *active);
3076 NK_API int nk_checkbox_flags_label(struct nk_context*, const char*, unsigned int *flags, unsigned int value);
3077 NK_API int nk_checkbox_flags_text(struct nk_context*, const char*, int, unsigned int *flags, unsigned int value);
3078 /* =============================================================================
3079  *
3080  * RADIO BUTTON
3081  *
3082  * ============================================================================= */
3083 NK_API int nk_radio_label(struct nk_context*, const char*, int *active);
3084 NK_API int nk_radio_text(struct nk_context*, const char*, int, int *active);
3085 NK_API int nk_option_label(struct nk_context*, const char*, int active);
3086 NK_API int nk_option_text(struct nk_context*, const char*, int, int active);
3087 /* =============================================================================
3088  *
3089  * SELECTABLE
3090  *
3091  * ============================================================================= */
3092 NK_API int nk_selectable_label(struct nk_context*, const char*, nk_flags align, int *value);
3093 NK_API int nk_selectable_text(struct nk_context*, const char*, int, nk_flags align, int *value);
3094 NK_API int nk_selectable_image_label(struct nk_context*,struct nk_image, const char*, nk_flags align, int *value);
3095 NK_API int nk_selectable_image_text(struct nk_context*,struct nk_image, const char*, int, nk_flags align, int *value);
3096 NK_API int nk_selectable_symbol_label(struct nk_context*,enum nk_symbol_type, const char*, nk_flags align, int *value);
3097 NK_API int nk_selectable_symbol_text(struct nk_context*,enum nk_symbol_type, const char*, int, nk_flags align, int *value);
3098 
3099 NK_API int nk_select_label(struct nk_context*, const char*, nk_flags align, int value);
3100 NK_API int nk_select_text(struct nk_context*, const char*, int, nk_flags align, int value);
3101 NK_API int nk_select_image_label(struct nk_context*, struct nk_image,const char*, nk_flags align, int value);
3102 NK_API int nk_select_image_text(struct nk_context*, struct nk_image,const char*, int, nk_flags align, int value);
3103 NK_API int nk_select_symbol_label(struct nk_context*,enum nk_symbol_type, const char*, nk_flags align, int value);
3104 NK_API int nk_select_symbol_text(struct nk_context*,enum nk_symbol_type, const char*, int, nk_flags align, int value);
3105 
3106 /* =============================================================================
3107  *
3108  * SLIDER
3109  *
3110  * ============================================================================= */
3111 NK_API float nk_slide_float(struct nk_context*, float min, float val, float max, float step);
3112 NK_API int nk_slide_int(struct nk_context*, int min, int val, int max, int step);
3113 NK_API int nk_slider_float(struct nk_context*, float min, float *val, float max, float step);
3114 NK_API int nk_slider_int(struct nk_context*, int min, int *val, int max, int step);
3115 /* =============================================================================
3116  *
3117  * PROGRESSBAR
3118  *
3119  * ============================================================================= */
3120 NK_API int nk_progress(struct nk_context*, nk_size *cur, nk_size max, int modifyable);
3121 NK_API nk_size nk_prog(struct nk_context*, nk_size cur, nk_size max, int modifyable);
3122 
3123 /* =============================================================================
3124  *
3125  * COLOR PICKER
3126  *
3127  * ============================================================================= */
3128 NK_API struct nk_colorf nk_color_picker(struct nk_context*, struct nk_colorf, enum nk_color_format);
3129 NK_API int nk_color_pick(struct nk_context*, struct nk_colorf*, enum nk_color_format);
3130 /* =============================================================================
3131  *
3132  * PROPERTIES
3133  *
3134  * =============================================================================
3190 // nk_clear(&ctx);
3205 */
3206 /*/// #### nk_property_int
3225 */
3226 NK_API void nk_property_int(struct nk_context*, const char *name, int min, int *val, int max, int step, float inc_per_pixel);
3227 /*/// #### nk_property_float
3246 */
3247 NK_API void nk_property_float(struct nk_context*, const char *name, float min, float *val, float max, float step, float inc_per_pixel);
3248 /*/// #### nk_property_double
3267 */
3268 NK_API void nk_property_double(struct nk_context*, const char *name, double min, double *val, double max, double step, float inc_per_pixel);
3269 /*/// #### nk_propertyi
3290 */
3291 NK_API int nk_propertyi(struct nk_context*, const char *name, int min, int val, int max, int step, float inc_per_pixel);
3292 /*/// #### nk_propertyf
3313 */
3314 NK_API float nk_propertyf(struct nk_context*, const char *name, float min, float val, float max, float step, float inc_per_pixel);
3315 /*/// #### nk_propertyd
3336 */
3337 NK_API double nk_propertyd(struct nk_context*, const char *name, double min, double val, double max, double step, float inc_per_pixel);
3338 /* =============================================================================
3339  *
3340  * TEXT EDIT
3341  *
3342  * ============================================================================= */
3357 };
3363 };
3365  NK_EDIT_ACTIVE = NK_FLAG(0), /* edit widget is currently being modified */
3366  NK_EDIT_INACTIVE = NK_FLAG(1), /* edit widget is not active and is not being modified */
3367  NK_EDIT_ACTIVATED = NK_FLAG(2), /* edit widget went from state inactive to state active */
3368  NK_EDIT_DEACTIVATED = NK_FLAG(3), /* edit widget went from state active to state inactive */
3369  NK_EDIT_COMMITED = NK_FLAG(4) /* edit widget has received an enter and lost focus */
3370 };
3371 NK_API nk_flags nk_edit_string(struct nk_context*, nk_flags, char *buffer, int *len, int max, nk_plugin_filter);
3372 NK_API nk_flags nk_edit_string_zero_terminated(struct nk_context*, nk_flags, char *buffer, int max, nk_plugin_filter);
3373 NK_API nk_flags nk_edit_buffer(struct nk_context*, nk_flags, struct nk_text_edit*, nk_plugin_filter);
3374 NK_API void nk_edit_focus(struct nk_context*, nk_flags flags);
3375 NK_API void nk_edit_unfocus(struct nk_context*);
3376 /* =============================================================================
3377  *
3378  * CHART
3379  *
3380  * ============================================================================= */
3381 NK_API int nk_chart_begin(struct nk_context*, enum nk_chart_type, int num, float min, float max);
3382 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);
3383 NK_API void nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type, int count, float min_value, float max_value);
3384 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);
3385 NK_API nk_flags nk_chart_push(struct nk_context*, float);
3386 NK_API nk_flags nk_chart_push_slot(struct nk_context*, float, int);
3387 NK_API void nk_chart_end(struct nk_context*);
3388 NK_API void nk_plot(struct nk_context*, enum nk_chart_type, const float *values, int count, int offset);
3389 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);
3390 /* =============================================================================
3391  *
3392  * POPUP
3393  *
3394  * ============================================================================= */
3395 NK_API int nk_popup_begin(struct nk_context*, enum nk_popup_type, const char*, nk_flags, struct nk_rect bounds);
3396 NK_API void nk_popup_close(struct nk_context*);
3397 NK_API void nk_popup_end(struct nk_context*);
3398 /* =============================================================================
3399  *
3400  * COMBOBOX
3401  *
3402  * ============================================================================= */
3403 NK_API int nk_combo(struct nk_context*, const char **items, int count, int selected, int item_height, struct nk_vec2 size);
3404 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);
3405 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);
3406 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);
3407 NK_API void nk_combobox(struct nk_context*, const char **items, int count, int *selected, int item_height, struct nk_vec2 size);
3408 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);
3409 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);
3410 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);
3411 /* =============================================================================
3412  *
3413  * ABSTRACT COMBOBOX
3414  *
3415  * ============================================================================= */
3416 NK_API int nk_combo_begin_text(struct nk_context*, const char *selected, int, struct nk_vec2 size);
3417 NK_API int nk_combo_begin_label(struct nk_context*, const char *selected, struct nk_vec2 size);
3418 NK_API int nk_combo_begin_color(struct nk_context*, struct nk_color color, struct nk_vec2 size);
3419 NK_API int nk_combo_begin_symbol(struct nk_context*, enum nk_symbol_type, struct nk_vec2 size);
3420 NK_API int nk_combo_begin_symbol_label(struct nk_context*, const char *selected, enum nk_symbol_type, struct nk_vec2 size);
3421 NK_API int nk_combo_begin_symbol_text(struct nk_context*, const char *selected, int, enum nk_symbol_type, struct nk_vec2 size);
3422 NK_API int nk_combo_begin_image(struct nk_context*, struct nk_image img, struct nk_vec2 size);
3423 NK_API int nk_combo_begin_image_label(struct nk_context*, const char *selected, struct nk_image, struct nk_vec2 size);
3424 NK_API int nk_combo_begin_image_text(struct nk_context*, const char *selected, int, struct nk_image, struct nk_vec2 size);
3425 NK_API int nk_combo_item_label(struct nk_context*, const char*, nk_flags alignment);
3426 NK_API int nk_combo_item_text(struct nk_context*, const char*,int, nk_flags alignment);
3427 NK_API int nk_combo_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
3428 NK_API int nk_combo_item_image_text(struct nk_context*, struct nk_image, const char*, int,nk_flags alignment);
3429 NK_API int nk_combo_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
3430 NK_API int nk_combo_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3431 NK_API void nk_combo_close(struct nk_context*);
3432 NK_API void nk_combo_end(struct nk_context*);
3433 /* =============================================================================
3434  *
3435  * CONTEXTUAL
3436  *
3437  * ============================================================================= */
3438 NK_API int nk_contextual_begin(struct nk_context*, nk_flags, struct nk_vec2, struct nk_rect trigger_bounds);
3439 NK_API int nk_contextual_item_text(struct nk_context*, const char*, int,nk_flags align);
3440 NK_API int nk_contextual_item_label(struct nk_context*, const char*, nk_flags align);
3441 NK_API int nk_contextual_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
3442 NK_API int nk_contextual_item_image_text(struct nk_context*, struct nk_image, const char*, int len, nk_flags alignment);
3443 NK_API int nk_contextual_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
3444 NK_API int nk_contextual_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3445 NK_API void nk_contextual_close(struct nk_context*);
3446 NK_API void nk_contextual_end(struct nk_context*);
3447 /* =============================================================================
3448  *
3449  * TOOLTIP
3450  *
3451  * ============================================================================= */
3452 NK_API void nk_tooltip(struct nk_context*, const char*);
3453 #ifdef NK_INCLUDE_STANDARD_VARARGS
3454 NK_API void nk_tooltipf(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(2);
3455 NK_API void nk_tooltipfv(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3456 #endif
3457 NK_API int nk_tooltip_begin(struct nk_context*, float width);
3458 NK_API void nk_tooltip_end(struct nk_context*);
3459 /* =============================================================================
3460  *
3461  * MENU
3462  *
3463  * ============================================================================= */
3464 NK_API void nk_menubar_begin(struct nk_context*);
3465 NK_API void nk_menubar_end(struct nk_context*);
3466 NK_API int nk_menu_begin_text(struct nk_context*, const char* title, int title_len, nk_flags align, struct nk_vec2 size);
3467 NK_API int nk_menu_begin_label(struct nk_context*, const char*, nk_flags align, struct nk_vec2 size);
3468 NK_API int nk_menu_begin_image(struct nk_context*, const char*, struct nk_image, struct nk_vec2 size);
3469 NK_API int nk_menu_begin_image_text(struct nk_context*, const char*, int,nk_flags align,struct nk_image, struct nk_vec2 size);
3470 NK_API int nk_menu_begin_image_label(struct nk_context*, const char*, nk_flags align,struct nk_image, struct nk_vec2 size);
3471 NK_API int nk_menu_begin_symbol(struct nk_context*, const char*, enum nk_symbol_type, struct nk_vec2 size);
3472 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);
3473 NK_API int nk_menu_begin_symbol_label(struct nk_context*, const char*, nk_flags align,enum nk_symbol_type, struct nk_vec2 size);
3474 NK_API int nk_menu_item_text(struct nk_context*, const char*, int,nk_flags align);
3475 NK_API int nk_menu_item_label(struct nk_context*, const char*, nk_flags alignment);
3476 NK_API int nk_menu_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
3477 NK_API int nk_menu_item_image_text(struct nk_context*, struct nk_image, const char*, int len, nk_flags alignment);
3478 NK_API int nk_menu_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
3479 NK_API int nk_menu_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
3480 NK_API void nk_menu_close(struct nk_context*);
3481 NK_API void nk_menu_end(struct nk_context*);
3482 /* =============================================================================
3483  *
3484  * STYLE
3485  *
3486  * ============================================================================= */
3517 };
3527 };
3528 NK_API void nk_style_default(struct nk_context*);
3529 NK_API void nk_style_from_table(struct nk_context*, const struct nk_color*);
3530 NK_API void nk_style_load_cursor(struct nk_context*, enum nk_style_cursor, const struct nk_cursor*);
3531 NK_API void nk_style_load_all_cursors(struct nk_context*, struct nk_cursor*);
3533 NK_API void nk_style_set_font(struct nk_context*, const struct nk_user_font*);
3534 NK_API int nk_style_set_cursor(struct nk_context*, enum nk_style_cursor);
3535 NK_API void nk_style_show_cursor(struct nk_context*);
3536 NK_API void nk_style_hide_cursor(struct nk_context*);
3537 
3538 NK_API int nk_style_push_font(struct nk_context*, const struct nk_user_font*);
3539 NK_API int nk_style_push_float(struct nk_context*, float*, float);
3540 NK_API int nk_style_push_vec2(struct nk_context*, struct nk_vec2*, struct nk_vec2);
3541 NK_API int nk_style_push_style_item(struct nk_context*, struct nk_style_item*, struct nk_style_item);
3542 NK_API int nk_style_push_flags(struct nk_context*, nk_flags*, nk_flags);
3543 NK_API int nk_style_push_color(struct nk_context*, struct nk_color*, struct nk_color);
3544 
3545 NK_API int nk_style_pop_font(struct nk_context*);
3546 NK_API int nk_style_pop_float(struct nk_context*);
3547 NK_API int nk_style_pop_vec2(struct nk_context*);
3548 NK_API int nk_style_pop_style_item(struct nk_context*);
3549 NK_API int nk_style_pop_flags(struct nk_context*);
3550 NK_API int nk_style_pop_color(struct nk_context*);
3551 /* =============================================================================
3552  *
3553  * COLOR
3554  *
3555  * ============================================================================= */
3556 NK_API struct nk_color nk_rgb(int r, int g, int b);
3557 NK_API struct nk_color nk_rgb_iv(const int *rgb);
3558 NK_API struct nk_color nk_rgb_bv(const nk_byte* rgb);
3559 NK_API struct nk_color nk_rgb_f(float r, float g, float b);
3560 NK_API struct nk_color nk_rgb_fv(const float *rgb);
3561 NK_API struct nk_color nk_rgb_cf(struct nk_colorf c);
3562 NK_API struct nk_color nk_rgb_hex(const char *rgb);
3563 
3564 NK_API struct nk_color nk_rgba(int r, int g, int b, int a);
3565 NK_API struct nk_color nk_rgba_u32(nk_uint);
3566 NK_API struct nk_color nk_rgba_iv(const int *rgba);
3567 NK_API struct nk_color nk_rgba_bv(const nk_byte *rgba);
3568 NK_API struct nk_color nk_rgba_f(float r, float g, float b, float a);
3569 NK_API struct nk_color nk_rgba_fv(const float *rgba);
3570 NK_API struct nk_color nk_rgba_cf(struct nk_colorf c);
3571 NK_API struct nk_color nk_rgba_hex(const char *rgb);
3572 
3573 NK_API struct nk_colorf nk_hsva_colorf(float h, float s, float v, float a);
3574 NK_API struct nk_colorf nk_hsva_colorfv(float *c);
3575 NK_API void nk_colorf_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_colorf in);
3576 NK_API void nk_colorf_hsva_fv(float *hsva, struct nk_colorf in);
3577 
3578 NK_API struct nk_color nk_hsv(int h, int s, int v);
3579 NK_API struct nk_color nk_hsv_iv(const int *hsv);
3580 NK_API struct nk_color nk_hsv_bv(const nk_byte *hsv);
3581 NK_API struct nk_color nk_hsv_f(float h, float s, float v);
3582 NK_API struct nk_color nk_hsv_fv(const float *hsv);
3583 
3584 NK_API struct nk_color nk_hsva(int h, int s, int v, int a);
3585 NK_API struct nk_color nk_hsva_iv(const int *hsva);
3586 NK_API struct nk_color nk_hsva_bv(const nk_byte *hsva);
3587 NK_API struct nk_color nk_hsva_f(float h, float s, float v, float a);
3588 NK_API struct nk_color nk_hsva_fv(const float *hsva);
3589 
3590 /* color (conversion nuklear --> user) */
3591 NK_API void nk_color_f(float *r, float *g, float *b, float *a, struct nk_color);
3592 NK_API void nk_color_fv(float *rgba_out, struct nk_color);
3593 NK_API struct nk_colorf nk_color_cf(struct nk_color);
3594 NK_API void nk_color_d(double *r, double *g, double *b, double *a, struct nk_color);
3595 NK_API void nk_color_dv(double *rgba_out, struct nk_color);
3596 
3597 NK_API nk_uint nk_color_u32(struct nk_color);
3598 NK_API void nk_color_hex_rgba(char *output, struct nk_color);
3599 NK_API void nk_color_hex_rgb(char *output, struct nk_color);
3600 
3601 NK_API void nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color);
3602 NK_API void nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color);
3603 NK_API void nk_color_hsv_iv(int *hsv_out, struct nk_color);
3604 NK_API void nk_color_hsv_bv(nk_byte *hsv_out, struct nk_color);
3605 NK_API void nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color);
3606 NK_API void nk_color_hsv_fv(float *hsv_out, struct nk_color);
3607 
3608 NK_API void nk_color_hsva_i(int *h, int *s, int *v, int *a, struct nk_color);
3609 NK_API void nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color);
3610 NK_API void nk_color_hsva_iv(int *hsva_out, struct nk_color);
3611 NK_API void nk_color_hsva_bv(nk_byte *hsva_out, struct nk_color);
3612 NK_API void nk_color_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_color);
3613 NK_API void nk_color_hsva_fv(float *hsva_out, struct nk_color);
3614 /* =============================================================================
3615  *
3616  * IMAGE
3617  *
3618  * ============================================================================= */
3619 NK_API nk_handle nk_handle_ptr(void*);
3620 NK_API nk_handle nk_handle_id(int);
3621 NK_API struct nk_image nk_image_handle(nk_handle);
3622 NK_API struct nk_image nk_image_ptr(void*);
3623 NK_API struct nk_image nk_image_id(int);
3624 NK_API int nk_image_is_subimage(const struct nk_image* img);
3625 NK_API struct nk_image nk_subimage_ptr(void*, unsigned short w, unsigned short h, struct nk_rect sub_region);
3626 NK_API struct nk_image nk_subimage_id(int, unsigned short w, unsigned short h, struct nk_rect sub_region);
3627 NK_API struct nk_image nk_subimage_handle(nk_handle, unsigned short w, unsigned short h, struct nk_rect sub_region);
3628 /* =============================================================================
3629  *
3630  * MATH
3631  *
3632  * ============================================================================= */
3633 NK_API nk_hash nk_murmur_hash(const void *key, int len, nk_hash seed);
3634 NK_API void nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r, float pad_x, float pad_y, enum nk_heading);
3635 
3636 NK_API struct nk_vec2 nk_vec2(float x, float y);
3637 NK_API struct nk_vec2 nk_vec2i(int x, int y);
3638 NK_API struct nk_vec2 nk_vec2v(const float *xy);
3639 NK_API struct nk_vec2 nk_vec2iv(const int *xy);
3640 
3642 NK_API struct nk_rect nk_rect(float x, float y, float w, float h);
3643 NK_API struct nk_rect nk_recti(int x, int y, int w, int h);
3644 NK_API struct nk_rect nk_recta(struct nk_vec2 pos, struct nk_vec2 size);
3645 NK_API struct nk_rect nk_rectv(const float *xywh);
3646 NK_API struct nk_rect nk_rectiv(const int *xywh);
3647 NK_API struct nk_vec2 nk_rect_pos(struct nk_rect);
3648 NK_API struct nk_vec2 nk_rect_size(struct nk_rect);
3649 /* =============================================================================
3650  *
3651  * STRING
3652  *
3653  * ============================================================================= */
3654 NK_API int nk_strlen(const char *str);
3655 NK_API int nk_stricmp(const char *s1, const char *s2);
3656 NK_API int nk_stricmpn(const char *s1, const char *s2, int n);
3657 NK_API int nk_strtoi(const char *str, const char **endptr);
3658 NK_API float nk_strtof(const char *str, const char **endptr);
3659 NK_API double nk_strtod(const char *str, const char **endptr);
3660 NK_API int nk_strfilter(const char *text, const char *regexp);
3661 NK_API int nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score);
3662 NK_API int nk_strmatch_fuzzy_text(const char *txt, int txt_len, const char *pattern, int *out_score);
3663 /* =============================================================================
3664  *
3665  * UTF-8
3666  *
3667  * ============================================================================= */
3668 NK_API int nk_utf_decode(const char*, nk_rune*, int);
3669 NK_API int nk_utf_encode(nk_rune, char*, int);
3670 NK_API int nk_utf_len(const char*, int byte_len);
3671 NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune *unicode, int *len);
3672 /* ===============================================================
3673  *
3674  * FONT
3675  *
3676  * ===============================================================*/
3677 /* Font handling in this library was designed to be quite customizable and lets
3678  you decide what you want to use and what you want to provide. There are three
3679  different ways to use the font atlas. The first two will use your font
3680  handling scheme and only requires essential data to run nuklear. The next
3681  slightly more advanced features is font handling with vertex buffer output.
3682  Finally the most complex API wise is using nuklear's font baking API.
3683 
3684  1.) Using your own implementation without vertex buffer output
3685  --------------------------------------------------------------
3686  So first up the easiest way to do font handling is by just providing a
3687  `nk_user_font` struct which only requires the height in pixel of the used
3688  font and a callback to calculate the width of a string. This way of handling
3689  fonts is best fitted for using the normal draw shape command API where you
3690  do all the text drawing yourself and the library does not require any kind
3691  of deeper knowledge about which font handling mechanism you use.
3692  IMPORTANT: the `nk_user_font` pointer provided to nuklear has to persist
3693  over the complete life time! I know this sucks but it is currently the only
3694  way to switch between fonts.
3695 
3696  float your_text_width_calculation(nk_handle handle, float height, const char *text, int len)
3697  {
3698  your_font_type *type = handle.ptr;
3699  float text_width = ...;
3700  return text_width;
3701  }
3702 
3703  struct nk_user_font font;
3704  font.userdata.ptr = &your_font_class_or_struct;
3705  font.height = your_font_height;
3706  font.width = your_text_width_calculation;
3707 
3708  struct nk_context ctx;
3709  nk_init_default(&ctx, &font);
3710 
3711  2.) Using your own implementation with vertex buffer output
3712  --------------------------------------------------------------
3713  While the first approach works fine if you don't want to use the optional
3714  vertex buffer output it is not enough if you do. To get font handling working
3715  for these cases you have to provide two additional parameters inside the
3716  `nk_user_font`. First a texture atlas handle used to draw text as subimages
3717  of a bigger font atlas texture and a callback to query a character's glyph
3718  information (offset, size, ...). So it is still possible to provide your own
3719  font and use the vertex buffer output.
3720 
3721  float your_text_width_calculation(nk_handle handle, float height, const char *text, int len)
3722  {
3723  your_font_type *type = handle.ptr;
3724  float text_width = ...;
3725  return text_width;
3726  }
3727  void query_your_font_glyph(nk_handle handle, float font_height, struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
3728  {
3729  your_font_type *type = handle.ptr;
3730  glyph.width = ...;
3731  glyph.height = ...;
3732  glyph.xadvance = ...;
3733  glyph.uv[0].x = ...;
3734  glyph.uv[0].y = ...;
3735  glyph.uv[1].x = ...;
3736  glyph.uv[1].y = ...;
3737  glyph.offset.x = ...;
3738  glyph.offset.y = ...;
3739  }
3740 
3741  struct nk_user_font font;
3742  font.userdata.ptr = &your_font_class_or_struct;
3743  font.height = your_font_height;
3744  font.width = your_text_width_calculation;
3745  font.query = query_your_font_glyph;
3746  font.texture.id = your_font_texture;
3747 
3748  struct nk_context ctx;
3749  nk_init_default(&ctx, &font);
3750 
3751  3.) Nuklear font baker
3752  ------------------------------------
3753  The final approach if you do not have a font handling functionality or don't
3754  want to use it in this library is by using the optional font baker.
3755  The font baker APIs can be used to create a font plus font atlas texture
3756  and can be used with or without the vertex buffer output.
3757 
3758  It still uses the `nk_user_font` struct and the two different approaches
3759  previously stated still work. The font baker is not located inside
3760  `nk_context` like all other systems since it can be understood as more of
3761  an extension to nuklear and does not really depend on any `nk_context` state.
3762 
3763  Font baker need to be initialized first by one of the nk_font_atlas_init_xxx
3764  functions. If you don't care about memory just call the default version
3765  `nk_font_atlas_init_default` which will allocate all memory from the standard library.
3766  If you want to control memory allocation but you don't care if the allocated
3767  memory is temporary and therefore can be freed directly after the baking process
3768  is over or permanent you can call `nk_font_atlas_init`.
3769 
3770  After successfully initializing the font baker you can add Truetype(.ttf) fonts from
3771  different sources like memory or from file by calling one of the `nk_font_atlas_add_xxx`.
3772  functions. Adding font will permanently store each font, font config and ttf memory block(!)
3773  inside the font atlas and allows to reuse the font atlas. If you don't want to reuse
3774  the font baker by for example adding additional fonts you can call
3775  `nk_font_atlas_cleanup` after the baking process is over (after calling nk_font_atlas_end).
3776 
3777  As soon as you added all fonts you wanted you can now start the baking process
3778  for every selected glyph to image by calling `nk_font_atlas_bake`.
3779  The baking process returns image memory, width and height which can be used to
3780  either create your own image object or upload it to any graphics library.
3781  No matter which case you finally have to call `nk_font_atlas_end` which
3782  will free all temporary memory including the font atlas image so make sure
3783  you created our texture beforehand. `nk_font_atlas_end` requires a handle
3784  to your font texture or object and optionally fills a `struct nk_draw_null_texture`
3785  which can be used for the optional vertex output. If you don't want it just
3786  set the argument to `NULL`.
3787 
3788  At this point you are done and if you don't want to reuse the font atlas you
3789  can call `nk_font_atlas_cleanup` to free all truetype blobs and configuration
3790  memory. Finally if you don't use the font atlas and any of it's fonts anymore
3791  you need to call `nk_font_atlas_clear` to free all memory still being used.
3792 
3793  struct nk_font_atlas atlas;
3794  nk_font_atlas_init_default(&atlas);
3795  nk_font_atlas_begin(&atlas);
3796  nk_font *font = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font.ttf", 13, 0);
3797  nk_font *font2 = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font2.ttf", 16, 0);
3798  const void* img = nk_font_atlas_bake(&atlas, &img_width, &img_height, NK_FONT_ATLAS_RGBA32);
3799  nk_font_atlas_end(&atlas, nk_handle_id(texture), 0);
3800 
3801  struct nk_context ctx;
3802  nk_init_default(&ctx, &font->handle);
3803  while (1) {
3804 
3805  }
3806  nk_font_atlas_clear(&atlas);
3807 
3808  The font baker API is probably the most complex API inside this library and
3809  I would suggest reading some of my examples `example/` to get a grip on how
3810  to use the font atlas. There are a number of details I left out. For example
3811  how to merge fonts, configure a font with `nk_font_config` to use other languages,
3812  use another texture coordinate format and a lot more:
3813 
3814  struct nk_font_config cfg = nk_font_config(font_pixel_height);
3815  cfg.merge_mode = nk_false or nk_true;
3816  cfg.range = nk_font_korean_glyph_ranges();
3817  cfg.coord_type = NK_COORD_PIXEL;
3818  nk_font *font = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font.ttf", 13, &cfg);
3819 
3820 */
3821 struct nk_user_font_glyph;
3822 typedef float(*nk_text_width_f)(nk_handle, float h, const char*, int len);
3823 typedef void(*nk_query_font_glyph_f)(nk_handle handle, float font_height,
3824  struct nk_user_font_glyph *glyph,
3825  nk_rune codepoint, nk_rune next_codepoint);
3826 
3827 #if defined(NK_INCLUDE_VERTEX_BUFFER_OUTPUT) || defined(NK_INCLUDE_SOFTWARE_FONT)
3828 struct nk_user_font_glyph {
3829  struct nk_vec2 uv[2];
3830  /* texture coordinates */
3831  struct nk_vec2 offset;
3832  /* offset between top left and glyph */
3833  float width, height;
3834  /* size of the glyph */
3835  float xadvance;
3836  /* offset to the next glyph */
3837 };
3838 #endif
3839 
3841  nk_handle userdata;
3842  /* user provided font handle */
3843  float height;
3844  /* max height of the font */
3846  /* font string width in pixel callback */
3847 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
3849  /* font glyph callback to query drawing info */
3850  nk_handle texture;
3851  /* texture handle to the used font atlas or texture */
3852 #endif
3853 };
3854 
3855 #ifdef NK_INCLUDE_FONT_BAKING
3856 enum nk_font_coord_type {
3857  NK_COORD_UV, /* texture coordinates inside font glyphs are clamped between 0-1 */
3858  NK_COORD_PIXEL /* texture coordinates inside font glyphs are in absolute pixel */
3859 };
3860 
3861 struct nk_font;
3862 struct nk_baked_font {
3863  float height;
3864  /* height of the font */
3865  float ascent, descent;
3866  /* font glyphs ascent and descent */
3867  nk_rune glyph_offset;
3868  /* glyph array offset inside the font glyph baking output array */
3869  nk_rune glyph_count;
3870  /* number of glyphs of this font inside the glyph baking array output */
3871  const nk_rune *ranges;
3872  /* font codepoint ranges as pairs of (from/to) and 0 as last element */
3873 };
3874 
3875 struct nk_font_config {
3876  struct nk_font_config *next;
3877  /* NOTE: only used internally */
3878  void *ttf_blob;
3879  /* pointer to loaded TTF file memory block.
3880  * NOTE: not needed for nk_font_atlas_add_from_memory and nk_font_atlas_add_from_file. */
3881  nk_size ttf_size;
3882  /* size of the loaded TTF file memory block
3883  * NOTE: not needed for nk_font_atlas_add_from_memory and nk_font_atlas_add_from_file. */
3884 
3885  unsigned char ttf_data_owned_by_atlas;
3886  /* used inside font atlas: default to: 0*/
3887  unsigned char merge_mode;
3888  /* merges this font into the last font */
3889  unsigned char pixel_snap;
3890  /* align every character to pixel boundary (if true set oversample (1,1)) */
3891  unsigned char oversample_v, oversample_h;
3892  /* rasterize at hight quality for sub-pixel position */
3893  unsigned char padding[3];
3894 
3895  float size;
3896  /* baked pixel height of the font */
3897  enum nk_font_coord_type coord_type;
3898  /* texture coordinate format with either pixel or UV coordinates */
3899  struct nk_vec2 spacing;
3900  /* extra pixel spacing between glyphs */
3901  const nk_rune *range;
3902  /* list of unicode ranges (2 values per range, zero terminated) */
3903  struct nk_baked_font *font;
3904  /* font to setup in the baking process: NOTE: not needed for font atlas */
3905  nk_rune fallback_glyph;
3906  /* fallback glyph to use if a given rune is not found */
3907  struct nk_font_config *n;
3908  struct nk_font_config *p;
3909 };
3910 
3911 struct nk_font_glyph {
3912  nk_rune codepoint;
3913  float xadvance;
3914  float x0, y0, x1, y1, w, h;
3915  float u0, v0, u1, v1;
3916 };
3917 
3918 struct nk_font {
3919  struct nk_font *next;
3920  struct nk_user_font handle;
3921  struct nk_baked_font info;
3922  float scale;
3923  struct nk_font_glyph *glyphs;
3924  const struct nk_font_glyph *fallback;
3925  nk_rune fallback_codepoint;
3926  nk_handle texture;
3927  struct nk_font_config *config;
3928 };
3929 
3930 enum nk_font_atlas_format {
3931  NK_FONT_ATLAS_ALPHA8,
3932  NK_FONT_ATLAS_RGBA32
3933 };
3934 
3935 struct nk_font_atlas {
3936  void *pixel;
3937  int tex_width;
3938  int tex_height;
3939 
3940  struct nk_allocator permanent;
3941  struct nk_allocator temporary;
3942 
3943  struct nk_recti custom;
3944  struct nk_cursor cursors[NK_CURSOR_COUNT];
3945 
3946  int glyph_count;
3947  struct nk_font_glyph *glyphs;
3948  struct nk_font *default_font;
3949  struct nk_font *fonts;
3950  struct nk_font_config *config;
3951  int font_num;
3952 };
3953 
3954 /* some language glyph codepoint ranges */
3955 NK_API const nk_rune *nk_font_default_glyph_ranges(void);
3956 NK_API const nk_rune *nk_font_chinese_glyph_ranges(void);
3957 NK_API const nk_rune *nk_font_cyrillic_glyph_ranges(void);
3958 NK_API const nk_rune *nk_font_korean_glyph_ranges(void);
3959 
3960 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
3961 NK_API void nk_font_atlas_init_default(struct nk_font_atlas*);
3962 #endif
3963 NK_API void nk_font_atlas_init(struct nk_font_atlas*, struct nk_allocator*);
3964 NK_API void nk_font_atlas_init_custom(struct nk_font_atlas*, struct nk_allocator *persistent, struct nk_allocator *transient);
3965 NK_API void nk_font_atlas_begin(struct nk_font_atlas*);
3966 NK_API struct nk_font_config nk_font_config(float pixel_height);
3967 NK_API struct nk_font *nk_font_atlas_add(struct nk_font_atlas*, const struct nk_font_config*);
3968 #ifdef NK_INCLUDE_DEFAULT_FONT
3969 NK_API struct nk_font* nk_font_atlas_add_default(struct nk_font_atlas*, float height, const struct nk_font_config*);
3970 #endif
3971 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);
3972 #ifdef NK_INCLUDE_STANDARD_IO
3973 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*);
3974 #endif
3975 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*);
3976 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);
3977 NK_API const void* nk_font_atlas_bake(struct nk_font_atlas*, int *width, int *height, enum nk_font_atlas_format);
3978 NK_API void nk_font_atlas_end(struct nk_font_atlas*, nk_handle tex, struct nk_draw_null_texture*);
3979 NK_API const struct nk_font_glyph* nk_font_find_glyph(struct nk_font*, nk_rune unicode);
3980 NK_API void nk_font_atlas_cleanup(struct nk_font_atlas *atlas);
3981 NK_API void nk_font_atlas_clear(struct nk_font_atlas*);
3982 
3983 #endif
3984 
3985 /* ==============================================================
3986  *
3987  * MEMORY BUFFER
3988  *
3989  * ===============================================================*/
3990 /* A basic (double)-buffer with linear allocation and resetting as only
3991  freeing policy. The buffer's main purpose is to control all memory management
3992  inside the GUI toolkit and still leave memory control as much as possible in
3993  the hand of the user while also making sure the library is easy to use if
3994  not as much control is needed.
3995  In general all memory inside this library can be provided from the user in
3996  three different ways.
3997 
3998  The first way and the one providing most control is by just passing a fixed
3999  size memory block. In this case all control lies in the hand of the user
4000  since he can exactly control where the memory comes from and how much memory
4001  the library should consume. Of course using the fixed size API removes the
4002  ability to automatically resize a buffer if not enough memory is provided so
4003  you have to take over the resizing. While being a fixed sized buffer sounds
4004  quite limiting, it is very effective in this library since the actual memory
4005  consumption is quite stable and has a fixed upper bound for a lot of cases.
4006 
4007  If you don't want to think about how much memory the library should allocate
4008  at all time or have a very dynamic UI with unpredictable memory consumption
4009  habits but still want control over memory allocation you can use the dynamic
4010  allocator based API. The allocator consists of two callbacks for allocating
4011  and freeing memory and optional userdata so you can plugin your own allocator.
4012 
4013  The final and easiest way can be used by defining
4014  NK_INCLUDE_DEFAULT_ALLOCATOR which uses the standard library memory
4015  allocation functions malloc and free and takes over complete control over
4016  memory in this library.
4017 */
4019  void *memory;
4020  unsigned int type;
4021  nk_size size;
4022  nk_size allocated;
4023  nk_size needed;
4024  nk_size calls;
4025 };
4026 
4030 };
4031 
4036 };
4037 
4039  int active;
4040  nk_size offset;
4041 };
4042 
4043 struct nk_memory {void *ptr;nk_size size;};
4044 struct nk_buffer {
4046  /* buffer marker to free a buffer to a certain offset */
4047  struct nk_allocator pool;
4048  /* allocator callback for dynamic buffers */
4050  /* memory management type */
4051  struct nk_memory memory;
4052  /* memory and size of the current memory block */
4054  /* growing factor for dynamic memory management */
4055  nk_size allocated;
4056  /* total amount of memory allocated */
4057  nk_size needed;
4058  /* totally consumed memory given that enough memory is present */
4059  nk_size calls;
4060  /* number of allocation calls */
4061  nk_size size;
4062  /* current size of the buffer */
4063 };
4064 
4065 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4066 NK_API void nk_buffer_init_default(struct nk_buffer*);
4067 #endif
4068 NK_API void nk_buffer_init(struct nk_buffer*, const struct nk_allocator*, nk_size size);
4069 NK_API void nk_buffer_init_fixed(struct nk_buffer*, void *memory, nk_size size);
4070 NK_API void nk_buffer_info(struct nk_memory_status*, struct nk_buffer*);
4071 NK_API void nk_buffer_push(struct nk_buffer*, enum nk_buffer_allocation_type type, const void *memory, nk_size size, nk_size align);
4074 NK_API void nk_buffer_clear(struct nk_buffer*);
4075 NK_API void nk_buffer_free(struct nk_buffer*);
4076 NK_API void *nk_buffer_memory(struct nk_buffer*);
4077 NK_API const void *nk_buffer_memory_const(const struct nk_buffer*);
4078 NK_API nk_size nk_buffer_total(struct nk_buffer*);
4079 
4080 /* ==============================================================
4081  *
4082  * STRING
4083  *
4084  * ===============================================================*/
4085 /* Basic string buffer which is only used in context with the text editor
4086  * to manage and manipulate dynamic or fixed size string content. This is _NOT_
4087  * the default string handling method. The only instance you should have any contact
4088  * with this API is if you interact with an `nk_text_edit` object inside one of the
4089  * copy and paste functions and even there only for more advanced cases. */
4090 struct nk_str {
4092  int len; /* in codepoints/runes/glyphs */
4093 };
4094 
4095 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4096 NK_API void nk_str_init_default(struct nk_str*);
4097 #endif
4098 NK_API void nk_str_init(struct nk_str*, const struct nk_allocator*, nk_size size);
4099 NK_API void nk_str_init_fixed(struct nk_str*, void *memory, nk_size size);
4100 NK_API void nk_str_clear(struct nk_str*);
4101 NK_API void nk_str_free(struct nk_str*);
4102 
4103 NK_API int nk_str_append_text_char(struct nk_str*, const char*, int);
4104 NK_API int nk_str_append_str_char(struct nk_str*, const char*);
4105 NK_API int nk_str_append_text_utf8(struct nk_str*, const char*, int);
4106 NK_API int nk_str_append_str_utf8(struct nk_str*, const char*);
4107 NK_API int nk_str_append_text_runes(struct nk_str*, const nk_rune*, int);
4108 NK_API int nk_str_append_str_runes(struct nk_str*, const nk_rune*);
4109 
4110 NK_API int nk_str_insert_at_char(struct nk_str*, int pos, const char*, int);
4111 NK_API int nk_str_insert_at_rune(struct nk_str*, int pos, const char*, int);
4112 
4113 NK_API int nk_str_insert_text_char(struct nk_str*, int pos, const char*, int);
4114 NK_API int nk_str_insert_str_char(struct nk_str*, int pos, const char*);
4115 NK_API int nk_str_insert_text_utf8(struct nk_str*, int pos, const char*, int);
4116 NK_API int nk_str_insert_str_utf8(struct nk_str*, int pos, const char*);
4117 NK_API int nk_str_insert_text_runes(struct nk_str*, int pos, const nk_rune*, int);
4118 NK_API int nk_str_insert_str_runes(struct nk_str*, int pos, const nk_rune*);
4119 
4120 NK_API void nk_str_remove_chars(struct nk_str*, int len);
4121 NK_API void nk_str_remove_runes(struct nk_str *str, int len);
4122 NK_API void nk_str_delete_chars(struct nk_str*, int pos, int len);
4123 NK_API void nk_str_delete_runes(struct nk_str*, int pos, int len);
4124 
4125 NK_API char *nk_str_at_char(struct nk_str*, int pos);
4126 NK_API char *nk_str_at_rune(struct nk_str*, int pos, nk_rune *unicode, int *len);
4127 NK_API nk_rune nk_str_rune_at(const struct nk_str*, int pos);
4128 NK_API const char *nk_str_at_char_const(const struct nk_str*, int pos);
4129 NK_API const char *nk_str_at_const(const struct nk_str*, int pos, nk_rune *unicode, int *len);
4130 
4131 NK_API char *nk_str_get(struct nk_str*);
4132 NK_API const char *nk_str_get_const(const struct nk_str*);
4133 NK_API int nk_str_len(struct nk_str*);
4134 NK_API int nk_str_len_char(struct nk_str*);
4135 
4136 /*===============================================================
4137  *
4138  * TEXT EDITOR
4139  *
4140  * ===============================================================*/
4141 /* Editing text in this library is handled by either `nk_edit_string` or
4142  * `nk_edit_buffer`. But like almost everything in this library there are multiple
4143  * ways of doing it and a balance between control and ease of use with memory
4144  * as well as functionality controlled by flags.
4145  *
4146  * This library generally allows three different levels of memory control:
4147  * First of is the most basic way of just providing a simple char array with
4148  * string length. This method is probably the easiest way of handling simple
4149  * user text input. Main upside is complete control over memory while the biggest
4150  * downside in comparison with the other two approaches is missing undo/redo.
4151  *
4152  * For UIs that require undo/redo the second way was created. It is based on
4153  * a fixed size nk_text_edit struct, which has an internal undo/redo stack.
4154  * This is mainly useful if you want something more like a text editor but don't want
4155  * to have a dynamically growing buffer.
4156  *
4157  * The final way is using a dynamically growing nk_text_edit struct, which
4158  * has both a default version if you don't care where memory comes from and an
4159  * allocator version if you do. While the text editor is quite powerful for its
4160  * complexity I would not recommend editing gigabytes of data with it.
4161  * It is rather designed for uses cases which make sense for a GUI library not for
4162  * an full blown text editor.
4163  */
4164 #ifndef NK_TEXTEDIT_UNDOSTATECOUNT
4165 #define NK_TEXTEDIT_UNDOSTATECOUNT 99
4166 #endif
4167 
4168 #ifndef NK_TEXTEDIT_UNDOCHARCOUNT
4169 #define NK_TEXTEDIT_UNDOCHARCOUNT 999
4170 #endif
4171 
4172 struct nk_text_edit;
4174  nk_handle userdata;
4177 };
4178 
4180  int where;
4184 };
4185 
4188  nk_rune undo_char[NK_TEXTEDIT_UNDOCHARCOUNT];
4189  short undo_point;
4190  short redo_point;
4193 };
4194 
4198 };
4199 
4204 };
4205 
4207  struct nk_clipboard clip;
4208  struct nk_str string;
4210  struct nk_vec2 scrollbar;
4211 
4212  int cursor;
4215  unsigned char mode;
4216  unsigned char cursor_at_end_of_line;
4217  unsigned char initialized;
4218  unsigned char has_preferred_x;
4219  unsigned char single_line;
4220  unsigned char active;
4221  unsigned char padding1;
4223  struct nk_text_undo_state undo;
4224 };
4225 
4226 /* filter function */
4227 NK_API int nk_filter_default(const struct nk_text_edit*, nk_rune unicode);
4228 NK_API int nk_filter_ascii(const struct nk_text_edit*, nk_rune unicode);
4229 NK_API int nk_filter_float(const struct nk_text_edit*, nk_rune unicode);
4230 NK_API int nk_filter_decimal(const struct nk_text_edit*, nk_rune unicode);
4231 NK_API int nk_filter_hex(const struct nk_text_edit*, nk_rune unicode);
4232 NK_API int nk_filter_oct(const struct nk_text_edit*, nk_rune unicode);
4233 NK_API int nk_filter_binary(const struct nk_text_edit*, nk_rune unicode);
4234 
4235 /* text editor */
4236 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
4237 NK_API void nk_textedit_init_default(struct nk_text_edit*);
4238 #endif
4239 NK_API void nk_textedit_init(struct nk_text_edit*, struct nk_allocator*, nk_size size);
4240 NK_API void nk_textedit_init_fixed(struct nk_text_edit*, void *memory, nk_size size);
4241 NK_API void nk_textedit_free(struct nk_text_edit*);
4242 NK_API void nk_textedit_text(struct nk_text_edit*, const char*, int total_len);
4243 NK_API void nk_textedit_delete(struct nk_text_edit*, int where, int len);
4246 NK_API int nk_textedit_cut(struct nk_text_edit*);
4247 NK_API int nk_textedit_paste(struct nk_text_edit*, char const*, int len);
4248 NK_API void nk_textedit_undo(struct nk_text_edit*);
4249 NK_API void nk_textedit_redo(struct nk_text_edit*);
4250 
4251 /* ===============================================================
4252  *
4253  * DRAWING
4254  *
4255  * ===============================================================*/
4256 /* This library was designed to be render backend agnostic so it does
4257  not draw anything to screen. Instead all drawn shapes, widgets
4258  are made of, are buffered into memory and make up a command queue.
4259  Each frame therefore fills the command buffer with draw commands
4260  that then need to be executed by the user and his own render backend.
4261  After that the command buffer needs to be cleared and a new frame can be
4262  started. It is probably important to note that the command buffer is the main
4263  drawing API and the optional vertex buffer API only takes this format and
4264  converts it into a hardware accessible format.
4265 
4266  To use the command queue to draw your own widgets you can access the
4267  command buffer of each window by calling `nk_window_get_canvas` after
4268  previously having called `nk_begin`:
4269 
4270  void draw_red_rectangle_widget(struct nk_context *ctx)
4271  {
4272  struct nk_command_buffer *canvas;
4273  struct nk_input *input = &ctx->input;
4274  canvas = nk_window_get_canvas(ctx);
4275 
4276  struct nk_rect space;
4277  enum nk_widget_layout_states state;
4278  state = nk_widget(&space, ctx);
4279  if (!state) return;
4280 
4281  if (state != NK_WIDGET_ROM)
4282  update_your_widget_by_user_input(...);
4283  nk_fill_rect(canvas, space, 0, nk_rgb(255,0,0));
4284  }
4285 
4286  if (nk_begin(...)) {
4287  nk_layout_row_dynamic(ctx, 25, 1);
4288  draw_red_rectangle_widget(ctx);
4289  }
4290  nk_end(..)
4291 
4292  Important to know if you want to create your own widgets is the `nk_widget`
4293  call. It allocates space on the panel reserved for this widget to be used,
4294  but also returns the state of the widget space. If your widget is not seen and does
4295  not have to be updated it is '0' and you can just return. If it only has
4296  to be drawn the state will be `NK_WIDGET_ROM` otherwise you can do both
4297  update and draw your widget. The reason for separating is to only draw and
4298  update what is actually necessary which is crucial for performance.
4299 */
4320 };
4321 
4322 /* command base and header of every command inside the buffer */
4323 struct nk_command {
4325  nk_size next;
4326 #ifdef NK_INCLUDE_COMMAND_USERDATA
4327  nk_handle userdata;
4328 #endif
4329 };
4330 
4333  short x, y;
4334  unsigned short w, h;
4335 };
4336 
4339  unsigned short line_thickness;
4340  struct nk_vec2i begin;
4341  struct nk_vec2i end;
4342  struct nk_color color;
4343 };
4344 
4347  unsigned short line_thickness;
4348  struct nk_vec2i begin;
4349  struct nk_vec2i end;
4350  struct nk_vec2i ctrl[2];
4351  struct nk_color color;
4352 };
4353 
4356  unsigned short rounding;
4357  unsigned short line_thickness;
4358  short x, y;
4359  unsigned short w, h;
4360  struct nk_color color;
4361 };
4362 
4365  unsigned short rounding;
4366  short x, y;
4367  unsigned short w, h;
4368  struct nk_color color;
4369 };
4370 
4373  short x, y;
4374  unsigned short w, h;
4375  struct nk_color left;
4376  struct nk_color top;
4377  struct nk_color bottom;
4378  struct nk_color right;
4379 };
4380 
4383  unsigned short line_thickness;
4384  struct nk_vec2i a;
4385  struct nk_vec2i b;
4386  struct nk_vec2i c;
4387  struct nk_color color;
4388 };
4389 
4392  struct nk_vec2i a;
4393  struct nk_vec2i b;
4394  struct nk_vec2i c;
4395  struct nk_color color;
4396 };
4397 
4400  short x, y;
4401  unsigned short line_thickness;
4402  unsigned short w, h;
4403  struct nk_color color;
4404 };
4405 
4408  short x, y;
4409  unsigned short w, h;
4410  struct nk_color color;
4411 };
4412 
4415  short cx, cy;
4416  unsigned short r;
4417  unsigned short line_thickness;
4418  float a[2];
4419  struct nk_color color;
4420 };
4421 
4424  short cx, cy;
4425  unsigned short r;
4426  float a[2];
4427  struct nk_color color;
4428 };
4429 
4432  struct nk_color color;
4433  unsigned short line_thickness;
4434  unsigned short point_count;
4435  struct nk_vec2i points[1];
4436 };
4437 
4440  struct nk_color color;
4441  unsigned short point_count;
4442  struct nk_vec2i points[1];
4443 };
4444 
4447  struct nk_color color;
4448  unsigned short line_thickness;
4449  unsigned short point_count;
4450  struct nk_vec2i points[1];
4451 };
4452 
4455  short x, y;
4456  unsigned short w, h;
4457  struct nk_image img;
4458  struct nk_color col;
4459 };
4460 
4461 typedef void (*nk_command_custom_callback)(void *canvas, short x,short y,
4462  unsigned short w, unsigned short h, nk_handle callback_data);
4465  short x, y;
4466  unsigned short w, h;
4467  nk_handle callback_data;
4469 };
4470 
4473  const struct nk_user_font *font;
4474  struct nk_color background;
4475  struct nk_color foreground;
4476  short x, y;
4477  unsigned short w, h;
4478  float height;
4479  int length;
4480  char string[1];
4481 };
4482 
4485  NK_CLIPPING_ON = nk_true
4486 };
4487 
4489  struct nk_buffer *base;
4490  struct nk_rect clip;
4492  nk_handle userdata;
4493  nk_size begin, end, last;
4494 };
4495 
4496 /* shape outlines */
4497 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);
4498 NK_API void nk_stroke_curve(struct nk_command_buffer*, float, float, float, float, float, float, float, float, float line_thickness, struct nk_color);
4499 NK_API void nk_stroke_rect(struct nk_command_buffer*, struct nk_rect, float rounding, float line_thickness, struct nk_color);
4500 NK_API void nk_stroke_circle(struct nk_command_buffer*, struct nk_rect, float line_thickness, struct nk_color);
4501 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);
4502 NK_API void nk_stroke_triangle(struct nk_command_buffer*, float, float, float, float, float, float, float line_thichness, struct nk_color);
4503 NK_API void nk_stroke_polyline(struct nk_command_buffer*, float *points, int point_count, float line_thickness, struct nk_color col);
4504 NK_API void nk_stroke_polygon(struct nk_command_buffer*, float*, int point_count, float line_thickness, struct nk_color);
4505 
4506 /* filled shades */
4507 NK_API void nk_fill_rect(struct nk_command_buffer*, struct nk_rect, float rounding, struct nk_color);
4508 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);
4509 NK_API void nk_fill_circle(struct nk_command_buffer*, struct nk_rect, struct nk_color);
4510 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);
4511 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);
4512 NK_API void nk_fill_polygon(struct nk_command_buffer*, float*, int point_count, struct nk_color);
4513 
4514 /* misc */
4515 NK_API void nk_draw_image(struct nk_command_buffer*, struct nk_rect, const struct nk_image*, struct nk_color);
4516 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);
4517 NK_API void nk_push_scissor(struct nk_command_buffer*, struct nk_rect);
4518 NK_API void nk_push_custom(struct nk_command_buffer*, struct nk_rect, nk_command_custom_callback, nk_handle usr);
4519 
4520 /* ===============================================================
4521  *
4522  * INPUT
4523  *
4524  * ===============================================================*/
4526  int down;
4527  unsigned int clicked;
4528  struct nk_vec2 clicked_pos;
4529 };
4530 struct nk_mouse {
4532  struct nk_vec2 pos;
4533  struct nk_vec2 prev;
4534  struct nk_vec2 delta;
4535  struct nk_vec2 scroll_delta;
4536  unsigned char grab;
4537  unsigned char grabbed;
4538  unsigned char ungrab;
4539 };
4540 
4541 struct nk_key {
4542  int down;
4543  unsigned int clicked;
4544 };
4545 struct nk_keyboard {
4547  char text[NK_INPUT_MAX];
4549 };
4550 
4551 struct nk_input {
4552  struct nk_keyboard keyboard;
4553  struct nk_mouse mouse;
4554 };
4555 
4556 NK_API int nk_input_has_mouse_click(const struct nk_input*, enum nk_buttons);
4557 NK_API int nk_input_has_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect);
4558 NK_API int nk_input_has_mouse_click_down_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect, int down);
4559 NK_API int nk_input_is_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect);
4560 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);
4561 NK_API int nk_input_any_mouse_click_in_rect(const struct nk_input*, struct nk_rect);
4562 NK_API int nk_input_is_mouse_prev_hovering_rect(const struct nk_input*, struct nk_rect);
4563 NK_API int nk_input_is_mouse_hovering_rect(const struct nk_input*, struct nk_rect);
4564 NK_API int nk_input_mouse_clicked(const struct nk_input*, enum nk_buttons, struct nk_rect);
4565 NK_API int nk_input_is_mouse_down(const struct nk_input*, enum nk_buttons);
4566 NK_API int nk_input_is_mouse_pressed(const struct nk_input*, enum nk_buttons);
4567 NK_API int nk_input_is_mouse_released(const struct nk_input*, enum nk_buttons);
4568 NK_API int nk_input_is_key_pressed(const struct nk_input*, enum nk_keys);
4569 NK_API int nk_input_is_key_released(const struct nk_input*, enum nk_keys);
4570 NK_API int nk_input_is_key_down(const struct nk_input*, enum nk_keys);
4571 
4572 /* ===============================================================
4573  *
4574  * DRAW LIST
4575  *
4576  * ===============================================================*/
4577 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
4578 /* The optional vertex buffer draw list provides a 2D drawing context
4579  with antialiasing functionality which takes basic filled or outlined shapes
4580  or a path and outputs vertexes, elements and draw commands.
4581  The actual draw list API is not required to be used directly while using this
4582  library since converting the default library draw command output is done by
4583  just calling `nk_convert` but I decided to still make this library accessible
4584  since it can be useful.
4585 
4586  The draw list is based on a path buffering and polygon and polyline
4587  rendering API which allows a lot of ways to draw 2D content to screen.
4588  In fact it is probably more powerful than needed but allows even more crazy
4589  things than this library provides by default.
4590 */
4591 typedef nk_ushort nk_draw_index;
4592 enum nk_draw_list_stroke {
4593  NK_STROKE_OPEN = nk_false,
4594  /* build up path has no connection back to the beginning */
4595  NK_STROKE_CLOSED = nk_true
4596  /* build up path has a connection back to the beginning */
4597 };
4598 
4599 enum nk_draw_vertex_layout_attribute {
4600  NK_VERTEX_POSITION,
4601  NK_VERTEX_COLOR,
4602  NK_VERTEX_TEXCOORD,
4603  NK_VERTEX_ATTRIBUTE_COUNT
4604 };
4605 
4606 enum nk_draw_vertex_layout_format {
4607  NK_FORMAT_SCHAR,
4608  NK_FORMAT_SSHORT,
4609  NK_FORMAT_SINT,
4610  NK_FORMAT_UCHAR,
4611  NK_FORMAT_USHORT,
4612  NK_FORMAT_UINT,
4613  NK_FORMAT_FLOAT,
4614  NK_FORMAT_DOUBLE,
4615 
4616 NK_FORMAT_COLOR_BEGIN,
4617  NK_FORMAT_R8G8B8 = NK_FORMAT_COLOR_BEGIN,
4618  NK_FORMAT_R16G15B16,
4619  NK_FORMAT_R32G32B32,
4620 
4621  NK_FORMAT_R8G8B8A8,
4622  NK_FORMAT_B8G8R8A8,
4623  NK_FORMAT_R16G15B16A16,
4624  NK_FORMAT_R32G32B32A32,
4625  NK_FORMAT_R32G32B32A32_FLOAT,
4626  NK_FORMAT_R32G32B32A32_DOUBLE,
4627 
4628  NK_FORMAT_RGB32,
4629  NK_FORMAT_RGBA32,
4630 NK_FORMAT_COLOR_END = NK_FORMAT_RGBA32,
4631  NK_FORMAT_COUNT
4632 };
4633 
4634 #define NK_VERTEX_LAYOUT_END NK_VERTEX_ATTRIBUTE_COUNT,NK_FORMAT_COUNT,0
4635 struct nk_draw_vertex_layout_element {
4636  enum nk_draw_vertex_layout_attribute attribute;
4637  enum nk_draw_vertex_layout_format format;
4638  nk_size offset;
4639 };
4640 
4641 struct nk_draw_command {
4642  unsigned int elem_count;
4643  /* number of elements in the current draw batch */
4644  struct nk_rect clip_rect;
4645  /* current screen clipping rectangle */
4646  nk_handle texture;
4647  /* current texture to set */
4648 #ifdef NK_INCLUDE_COMMAND_USERDATA
4649  nk_handle userdata;
4650 #endif
4651 };
4652 
4653 struct nk_draw_list {
4654  struct nk_rect clip_rect;
4655  struct nk_vec2 circle_vtx[12];
4656  struct nk_convert_config config;
4657 
4658  struct nk_buffer *buffer;
4659  struct nk_buffer *vertices;
4660  struct nk_buffer *elements;
4661 
4662  unsigned int element_count;
4663  unsigned int vertex_count;
4664  unsigned int cmd_count;
4665  nk_size cmd_offset;
4666 
4667  unsigned int path_count;
4668  unsigned int path_offset;
4669 
4670  enum nk_anti_aliasing line_AA;
4671  enum nk_anti_aliasing shape_AA;
4672 
4673 #ifdef NK_INCLUDE_COMMAND_USERDATA
4674  nk_handle userdata;
4675 #endif
4676 };
4677 
4678 /* draw list */
4679 NK_API void nk_draw_list_init(struct nk_draw_list*);
4680 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);
4681 
4682 /* drawing */
4683 #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))
4684 NK_API const struct nk_draw_command* nk__draw_list_begin(const struct nk_draw_list*, const struct nk_buffer*);
4685 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*);
4686 NK_API const struct nk_draw_command* nk__draw_list_end(const struct nk_draw_list*, const struct nk_buffer*);
4687 
4688 /* path */
4689 NK_API void nk_draw_list_path_clear(struct nk_draw_list*);
4690 NK_API void nk_draw_list_path_line_to(struct nk_draw_list*, struct nk_vec2 pos);
4691 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);
4692 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);
4693 NK_API void nk_draw_list_path_rect_to(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, float rounding);
4694 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);
4695 NK_API void nk_draw_list_path_fill(struct nk_draw_list*, struct nk_color);
4696 NK_API void nk_draw_list_path_stroke(struct nk_draw_list*, struct nk_color, enum nk_draw_list_stroke closed, float thickness);
4697 
4698 /* stroke */
4699 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);
4700 NK_API void nk_draw_list_stroke_rect(struct nk_draw_list*, struct nk_rect rect, struct nk_color, float rounding, float thickness);
4701 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);
4702 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);
4703 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);
4704 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);
4705 
4706 /* fill */
4707 NK_API void nk_draw_list_fill_rect(struct nk_draw_list*, struct nk_rect rect, struct nk_color, float rounding);
4708 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);
4709 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);
4710 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);
4711 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);
4712 
4713 /* misc */
4714 NK_API void nk_draw_list_add_image(struct nk_draw_list*, struct nk_image texture, struct nk_rect rect, struct nk_color);
4715 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);
4716 #ifdef NK_INCLUDE_COMMAND_USERDATA
4717 NK_API void nk_draw_list_push_userdata(struct nk_draw_list*, nk_handle userdata);
4718 #endif
4719 
4720 #endif
4721 
4722 /* ===============================================================
4723  *
4724  * GUI
4725  *
4726  * ===============================================================*/
4730 };
4731 
4733  struct nk_image image;
4734  struct nk_color color;
4735 };
4736 
4740 };
4741 
4743  struct nk_color color;
4744  struct nk_vec2 padding;
4745 };
4746 
4748  /* background */
4750  struct nk_style_item hover;
4751  struct nk_style_item active;
4752  struct nk_color border_color;
4753 
4754  /* text */
4755  struct nk_color text_background;
4756  struct nk_color text_normal;
4757  struct nk_color text_hover;
4758  struct nk_color text_active;
4759  nk_flags text_alignment;
4760 
4761  /* properties */
4762  float border;
4763  float rounding;
4764  struct nk_vec2 padding;
4765  struct nk_vec2 image_padding;
4766  struct nk_vec2 touch_padding;
4767 
4768  /* optional user callbacks */
4769  nk_handle userdata;
4770  void(*draw_begin)(struct nk_command_buffer*, nk_handle userdata);
4771  void(*draw_end)(struct nk_command_buffer*, nk_handle userdata);
4772 };
4773 
4775  /* background */
4777  struct nk_style_item hover;
4778  struct nk_style_item active;
4779  struct nk_color border_color;
4780 
4781  /* cursor */
4782  struct nk_style_item cursor_normal;
4783  struct nk_style_item cursor_hover;
4784 
4785  /* text */
4786  struct nk_color text_normal;
4787  struct nk_color text_hover;
4788  struct nk_color text_active;
4789  struct nk_color text_background;
4790  nk_flags text_alignment;
4791 
4792  /* properties */
4793  struct nk_vec2 padding;
4794  struct nk_vec2 touch_padding;
4795  float spacing;
4796  float border;
4797 
4798  /* optional user callbacks */
4799  nk_handle userdata;
4800  void(*draw_begin)(struct nk_command_buffer*, nk_handle);
4801  void(*draw_end)(struct nk_command_buffer*, nk_handle);
4802 };
4803 
4805  /* background (inactive) */
4807  struct nk_style_item hover;
4808  struct nk_style_item pressed;
4809 
4810  /* background (active) */
4811  struct nk_style_item normal_active;
4812  struct nk_style_item hover_active;
4813  struct nk_style_item pressed_active;
4814 
4815  /* text color (inactive) */
4816  struct nk_color text_normal;
4817  struct nk_color text_hover;
4818  struct nk_color text_pressed;
4819 
4820  /* text color (active) */
4821  struct nk_color text_normal_active;
4822  struct nk_color text_hover_active;
4823  struct nk_color text_pressed_active;
4824  struct nk_color text_background;
4825  nk_flags text_alignment;
4826 
4827  /* properties */
4828  float rounding;
4829  struct nk_vec2 padding;
4830  struct nk_vec2 touch_padding;
4831  struct nk_vec2 image_padding;
4832 
4833  /* optional user callbacks */
4834  nk_handle userdata;
4835  void(*draw_begin)(struct nk_command_buffer*, nk_handle);
4836  void(*draw_end)(struct nk_command_buffer*, nk_handle);
4837 };
4838 
4840  /* background */
4842  struct nk_style_item hover;
4843  struct nk_style_item active;
4844  struct nk_color border_color;
4845 
4846  /* background bar */
4847  struct nk_color bar_normal;
4848  struct nk_color bar_hover;
4849  struct nk_color bar_active;
4850  struct nk_color bar_filled;
4851 
4852  /* cursor */
4853  struct nk_style_item cursor_normal;
4854  struct nk_style_item cursor_hover;
4855  struct nk_style_item cursor_active;
4856 
4857  /* properties */
4858  float border;
4859  float rounding;
4860  float bar_height;
4861  struct nk_vec2 padding;
4862  struct nk_vec2 spacing;
4863  struct nk_vec2 cursor_size;
4864 
4865  /* optional buttons */
4867  struct nk_style_button inc_button;
4868  struct nk_style_button dec_button;
4869  enum nk_symbol_type inc_symbol;
4870  enum nk_symbol_type dec_symbol;
4871 
4872  /* optional user callbacks */
4873  nk_handle userdata;
4874  void(*draw_begin)(struct nk_command_buffer*, nk_handle);
4875  void(*draw_end)(struct nk_command_buffer*, nk_handle);
4876 };
4877 
4879  /* background */
4881  struct nk_style_item hover;
4882  struct nk_style_item active;
4883  struct nk_color border_color;
4884 
4885  /* cursor */
4886  struct nk_style_item cursor_normal;
4887  struct nk_style_item cursor_hover;
4888  struct nk_style_item cursor_active;
4889  struct nk_color cursor_border_color;
4890 
4891  /* properties */
4892  float rounding;
4893  float border;
4896  struct nk_vec2 padding;
4897 
4898  /* optional user callbacks */
4899  nk_handle userdata;
4900  void(*draw_begin)(struct nk_command_buffer*, nk_handle);
4901  void(*draw_end)(struct nk_command_buffer*, nk_handle);
4902 };
4903 
4905  /* background */
4907  struct nk_style_item hover;
4908  struct nk_style_item active;
4909  struct nk_color border_color;
4910 
4911  /* cursor */
4912  struct nk_style_item cursor_normal;
4913  struct nk_style_item cursor_hover;
4914  struct nk_style_item cursor_active;
4915  struct nk_color cursor_border_color;
4916 
4917  /* properties */
4918  float border;
4919  float rounding;
4922  struct nk_vec2 padding;
4923 
4924  /* optional buttons */
4926  struct nk_style_button inc_button;
4927  struct nk_style_button dec_button;
4928  enum nk_symbol_type inc_symbol;
4929  enum nk_symbol_type dec_symbol;
4930 
4931  /* optional user callbacks */
4932  nk_handle userdata;
4933  void(*draw_begin)(struct nk_command_buffer*, nk_handle);
4934  void(*draw_end)(struct nk_command_buffer*, nk_handle);
4935 };
4936 
4938  /* background */
4940  struct nk_style_item hover;
4941  struct nk_style_item active;
4942  struct nk_color border_color;
4943  struct nk_style_scrollbar scrollbar;
4944 
4945  /* cursor */
4946  struct nk_color cursor_normal;
4947  struct nk_color cursor_hover;
4948  struct nk_color cursor_text_normal;
4949  struct nk_color cursor_text_hover;
4950 
4951  /* text (unselected) */
4952  struct nk_color text_normal;
4953  struct nk_color text_hover;
4954  struct nk_color text_active;
4955 
4956  /* text (selected) */
4957  struct nk_color selected_normal;
4958  struct nk_color selected_hover;
4959  struct nk_color selected_text_normal;
4960  struct nk_color selected_text_hover;
4961 
4962  /* properties */
4963  float border;
4964  float rounding;
4966  struct nk_vec2 scrollbar_size;
4967  struct nk_vec2 padding;
4969 };
4970 
4972  /* background */
4974  struct nk_style_item hover;
4975  struct nk_style_item active;
4976  struct nk_color border_color;
4977 
4978  /* text */
4979  struct nk_color label_normal;
4980  struct nk_color label_hover;
4981  struct nk_color label_active;
4982 
4983  /* symbols */
4984  enum nk_symbol_type sym_left;
4985  enum nk_symbol_type sym_right;
4986 
4987  /* properties */
4988  float border;
4989  float rounding;
4990  struct nk_vec2 padding;
4991 
4993  struct nk_style_button inc_button;
4994  struct nk_style_button dec_button;
4995 
4996  /* optional user callbacks */
4997  nk_handle userdata;
4998  void(*draw_begin)(struct nk_command_buffer*, nk_handle);
4999  void(*draw_end)(struct nk_command_buffer*, nk_handle);
5000 };
5001 
5003  /* colors */
5004  struct nk_style_item background;
5005  struct nk_color border_color;
5006  struct nk_color selected_color;
5007  struct nk_color color;
5008 
5009  /* properties */
5010  float border;
5011  float rounding;
5012  struct nk_vec2 padding;
5013 };
5014 
5016  /* background */
5018  struct nk_style_item hover;
5019  struct nk_style_item active;
5020  struct nk_color border_color;
5021 
5022  /* label */
5023  struct nk_color label_normal;
5024  struct nk_color label_hover;
5025  struct nk_color label_active;
5026 
5027  /* symbol */
5028  struct nk_color symbol_normal;
5029  struct nk_color symbol_hover;
5030  struct nk_color symbol_active;
5031 
5032  /* button */
5033  struct nk_style_button button;
5034  enum nk_symbol_type sym_normal;
5035  enum nk_symbol_type sym_hover;
5036  enum nk_symbol_type sym_active;
5037 
5038  /* properties */
5039  float border;
5040  float rounding;
5041  struct nk_vec2 content_padding;
5042  struct nk_vec2 button_padding;
5043  struct nk_vec2 spacing;
5044 };
5045 
5047  /* background */
5048  struct nk_style_item background;
5049  struct nk_color border_color;
5050  struct nk_color text;
5051 
5052  /* button */
5053  struct nk_style_button tab_maximize_button;
5054  struct nk_style_button tab_minimize_button;
5055  struct nk_style_button node_maximize_button;
5056  struct nk_style_button node_minimize_button;
5057  enum nk_symbol_type sym_minimize;
5058  enum nk_symbol_type sym_maximize;
5059 
5060  /* properties */
5061  float border;
5062  float rounding;
5063  float indent;
5064  struct nk_vec2 padding;
5065  struct nk_vec2 spacing;
5066 };
5067 
5071 };
5073  /* background */
5075  struct nk_style_item hover;
5076  struct nk_style_item active;
5077 
5078  /* button */
5079  struct nk_style_button close_button;
5080  struct nk_style_button minimize_button;
5081  enum nk_symbol_type close_symbol;
5082  enum nk_symbol_type minimize_symbol;
5083  enum nk_symbol_type maximize_symbol;
5084 
5085  /* title */
5086  struct nk_color label_normal;
5087  struct nk_color label_hover;
5088  struct nk_color label_active;
5089 
5090  /* properties */
5092  struct nk_vec2 padding;
5093  struct nk_vec2 label_padding;
5094  struct nk_vec2 spacing;
5095 };
5096 
5099  struct nk_style_item fixed_background;
5100  struct nk_color background;
5101 
5102  struct nk_color border_color;
5103  struct nk_color popup_border_color;
5104  struct nk_color combo_border_color;
5105  struct nk_color contextual_border_color;
5106  struct nk_color menu_border_color;
5107  struct nk_color group_border_color;
5108  struct nk_color tooltip_border_color;
5109  struct nk_style_item scaler;
5110 
5111  float border;
5119 
5120  float rounding;
5121  struct nk_vec2 spacing;
5122  struct nk_vec2 scrollbar_size;
5123  struct nk_vec2 min_size;
5124 
5125  struct nk_vec2 padding;
5126  struct nk_vec2 group_padding;
5127  struct nk_vec2 popup_padding;
5128  struct nk_vec2 combo_padding;
5129  struct nk_vec2 contextual_padding;
5130  struct nk_vec2 menu_padding;
5131  struct nk_vec2 tooltip_padding;
5132 };
5133 
5134 struct nk_style {
5135  const struct nk_user_font *font;
5136  const struct nk_cursor *cursors[NK_CURSOR_COUNT];
5137  const struct nk_cursor *cursor_active;
5140 
5141  struct nk_style_text text;
5142  struct nk_style_button button;
5143  struct nk_style_button contextual_button;
5144  struct nk_style_button menu_button;
5147  struct nk_style_selectable selectable;
5150  struct nk_style_property property;
5152  struct nk_style_chart chart;
5153  struct nk_style_scrollbar scrollh;
5154  struct nk_style_scrollbar scrollv;
5155  struct nk_style_tab tab;
5156  struct nk_style_combo combo;
5158 };
5159 
5161 NK_API struct nk_style_item nk_style_item_color(struct nk_color);
5163 
5164 /*==============================================================
5165  * PANEL
5166  * =============================================================*/
5167 #ifndef NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
5168 #define NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS 16
5169 #endif
5170 #ifndef NK_CHART_MAX_SLOT
5171 #define NK_CHART_MAX_SLOT 4
5172 #endif
5173 
5183 };
5188 };
5189 
5192  struct nk_color color;
5193  struct nk_color highlight;
5194  float min, max, range;
5195  int count;
5196  struct nk_vec2 last;
5197  int index;
5198 };
5199 
5200 struct nk_chart {
5201  int slot;
5202  float x, y, w, h;
5204 };
5205 
5217 };
5220  int index;
5221  float height;
5222  float min_height;
5223  int columns;
5224  const float *ratio;
5225  float item_width;
5228  float filled;
5229  struct nk_rect item;
5232 };
5233 
5235  nk_size begin;
5236  nk_size parent;
5237  nk_size last;
5238  nk_size end;
5239  int active;
5240 };
5241 
5243  float x, y, w, h;
5244  struct nk_scroll offset;
5245 };
5246 
5247 struct nk_panel {
5249  nk_flags flags;
5250  struct nk_rect bounds;
5251  nk_uint *offset_x;
5252  nk_uint *offset_y;
5253  float at_x, at_y, max_x;
5256  float border;
5257  unsigned int has_scrolling;
5258  struct nk_rect clip;
5259  struct nk_menu_state menu;
5261  struct nk_chart chart;
5263  struct nk_panel *parent;
5264 };
5265 
5266 /*==============================================================
5267  * WINDOW
5268  * =============================================================*/
5269 #ifndef NK_WINDOW_MAX_NAME
5270 #define NK_WINDOW_MAX_NAME 64
5271 #endif
5272 
5273 struct nk_table;
5277  /* special window type growing up in height while being filled to a certain maximum height */
5279  /* sets window widgets into a read only mode and does not allow input changes */
5281  /* prevents all interaction caused by input to either window or widgets inside */
5283  /* Hides window and stops any window interaction and drawing */
5285  /* Directly closes and frees the window at the end of the frame */
5287  /* marks the window as minimized */
5289  /* Removes read only mode at the end of the window */
5290 };
5291 
5293  struct nk_window *win;
5296  nk_hash name;
5297  int active;
5298  unsigned combo_count;
5299  unsigned con_count, con_old;
5300  unsigned active_con;
5301  struct nk_rect header;
5302 };
5303 
5305  nk_hash name;
5306  unsigned int seq;
5307  unsigned int old;
5308  int active, prev;
5309  int cursor;
5311  int sel_end;
5312  struct nk_scroll scrollbar;
5313  unsigned char mode;
5314  unsigned char single_line;
5315 };
5316 
5318  int active, prev;
5320  int length;
5321  int cursor;
5324  nk_hash name;
5325  unsigned int seq;
5326  unsigned int old;
5327  int state;
5328 };
5329 
5330 struct nk_window {
5331  unsigned int seq;
5332  nk_hash name;
5333  char name_string[NK_WINDOW_MAX_NAME];
5334  nk_flags flags;
5335 
5336  struct nk_rect bounds;
5337  struct nk_scroll scrollbar;
5339  struct nk_panel *layout;
5341 
5342  /* persistent widget state */
5343  struct nk_property_state property;
5344  struct nk_popup_state popup;
5346  unsigned int scrolled;
5347 
5348  struct nk_table *tables;
5349  unsigned int table_count;
5350 
5351  /* window list hooks */
5352  struct nk_window *next;
5353  struct nk_window *prev;
5355 };
5356 
5357 /*==============================================================
5358  * STACK
5359  * =============================================================*/
5360 /* The style modifier stack can be used to temporarily change a
5361  * property inside `nk_style`. For example if you want a special
5362  * red button you can temporarily push the old button color onto a stack
5363  * draw the button with a red color and then you just pop the old color
5364  * back from the stack:
5365  *
5366  * nk_style_push_style_item(ctx, &ctx->style.button.normal, nk_style_item_color(nk_rgb(255,0,0)));
5367  * nk_style_push_style_item(ctx, &ctx->style.button.hover, nk_style_item_color(nk_rgb(255,0,0)));
5368  * nk_style_push_style_item(ctx, &ctx->style.button.active, nk_style_item_color(nk_rgb(255,0,0)));
5369  * nk_style_push_vec2(ctx, &cx->style.button.padding, nk_vec2(2,2));
5370  *
5371  * nk_button(...);
5372  *
5373  * nk_style_pop_style_item(ctx);
5374  * nk_style_pop_style_item(ctx);
5375  * nk_style_pop_style_item(ctx);
5376  * nk_style_pop_vec2(ctx);
5377  *
5378  * Nuklear has a stack for style_items, float properties, vector properties,
5379  * flags, colors, fonts and for button_behavior. Each has it's own fixed size stack
5380  * which can be changed at compile time.
5381  */
5382 #ifndef NK_BUTTON_BEHAVIOR_STACK_SIZE
5383 #define NK_BUTTON_BEHAVIOR_STACK_SIZE 8
5384 #endif
5385 
5386 #ifndef NK_FONT_STACK_SIZE
5387 #define NK_FONT_STACK_SIZE 8
5388 #endif
5389 
5390 #ifndef NK_STYLE_ITEM_STACK_SIZE
5391 #define NK_STYLE_ITEM_STACK_SIZE 16
5392 #endif
5393 
5394 #ifndef NK_FLOAT_STACK_SIZE
5395 #define NK_FLOAT_STACK_SIZE 32
5396 #endif
5397 
5398 #ifndef NK_VECTOR_STACK_SIZE
5399 #define NK_VECTOR_STACK_SIZE 16
5400 #endif
5401 
5402 #ifndef NK_FLAGS_STACK_SIZE
5403 #define NK_FLAGS_STACK_SIZE 32
5404 #endif
5405 
5406 #ifndef NK_COLOR_STACK_SIZE
5407 #define NK_COLOR_STACK_SIZE 32
5408 #endif
5409 
5410 #define NK_CONFIGURATION_STACK_TYPE(prefix, name, type)\
5411  struct nk_config_stack_##name##_element {\
5412  prefix##_##type *address;\
5413  prefix##_##type old_value;\
5414  }
5415 #define NK_CONFIG_STACK(type,size)\
5416  struct nk_config_stack_##type {\
5417  int head;\
5418  struct nk_config_stack_##type##_element elements[size];\
5419  }
5420 
5421 #define nk_float float
5422 NK_CONFIGURATION_STACK_TYPE(struct nk, style_item, style_item);
5423 NK_CONFIGURATION_STACK_TYPE(nk ,float, float);
5424 NK_CONFIGURATION_STACK_TYPE(struct nk, vec2, vec2);
5426 NK_CONFIGURATION_STACK_TYPE(struct nk, color, color);
5427 NK_CONFIGURATION_STACK_TYPE(const struct nk, user_font, user_font*);
5428 NK_CONFIGURATION_STACK_TYPE(enum nk, button_behavior, button_behavior);
5429 
5437 
5439  struct nk_config_stack_style_item style_items;
5440  struct nk_config_stack_float floats;
5441  struct nk_config_stack_vec2 vectors;
5442  struct nk_config_stack_flags flags;
5443  struct nk_config_stack_color colors;
5444  struct nk_config_stack_user_font fonts;
5445  struct nk_config_stack_button_behavior button_behaviors;
5446 };
5447 
5448 /*==============================================================
5449  * CONTEXT
5450  * =============================================================*/
5451 #define NK_VALUE_PAGE_CAPACITY \
5452  (((NK_MAX(sizeof(struct nk_window),sizeof(struct nk_panel)) / sizeof(nk_uint))) / 2)
5453 
5454 struct nk_table {
5455  unsigned int seq;
5456  unsigned int size;
5459  struct nk_table *next, *prev;
5460 };
5461 
5463  struct nk_table tbl;
5464  struct nk_panel pan;
5465  struct nk_window win;
5466 };
5467 
5469  union nk_page_data data;
5472 };
5473 
5474 struct nk_page {
5475  unsigned int size;
5476  struct nk_page *next;
5477  struct nk_page_element win[1];
5478 };
5479 
5480 struct nk_pool {
5483  unsigned int page_count;
5484  struct nk_page *pages;
5486  unsigned capacity;
5487  nk_size size;
5488  nk_size cap;
5489 };
5490 
5491 struct nk_context {
5492 /* public: can be accessed freely */
5493  struct nk_input input;
5494  struct nk_style style;
5495  struct nk_buffer memory;
5496  struct nk_clipboard clip;
5498  enum nk_button_behavior button_behavior;
5501 
5502 /* private:
5503  should only be accessed if you
5504  know what you are doing */
5505 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
5506  struct nk_draw_list draw_list;
5507 #endif
5508 #ifdef NK_INCLUDE_COMMAND_USERDATA
5509  nk_handle userdata;
5510 #endif
5511  /* text editor objects are quite big because of an internal
5512  * undo/redo stack. Therefore it does not make sense to have one for
5513  * each window for temporary use cases, so I only provide *one* instance
5514  * for all windows. This works because the content is cleared anyway */
5515  struct nk_text_edit text_edit;
5516  /* draw buffer used for overlay drawing operation like cursor */
5517  struct nk_command_buffer overlay;
5518 
5519  /* windows */
5520  int build;
5522  struct nk_pool pool;
5523  struct nk_window *begin;
5524  struct nk_window *end;
5528  unsigned int count;
5529  unsigned int seq;
5530 };
5531 
5532 /* ==============================================================
5533  * MATH
5534  * =============================================================== */
5535 #define NK_PI 3.141592654f
5536 #define NK_UTF_INVALID 0xFFFD
5537 #define NK_MAX_FLOAT_PRECISION 2
5538 
5539 #define NK_UNUSED(x) ((void)(x))
5540 #define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
5541 #define NK_LEN(a) (sizeof(a)/sizeof(a)[0])
5542 #define NK_ABS(a) (((a) < 0) ? -(a) : (a))
5543 #define NK_BETWEEN(x, a, b) ((a) <= (x) && (x) < (b))
5544 #define NK_INBOX(px, py, x, y, w, h)\
5545  (NK_BETWEEN(px,x,x+w) && NK_BETWEEN(py,y,y+h))
5546 #define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1) \
5547  (!(((x1 > (x0 + w0)) || ((x1 + w1) < x0) || (y1 > (y0 + h0)) || (y1 + h1) < y0)))
5548 #define NK_CONTAINS(x, y, w, h, bx, by, bw, bh)\
5549  (NK_INBOX(x,y, bx, by, bw, bh) && NK_INBOX(x+w,y+h, bx, by, bw, bh))
5550 
5551 #define nk_vec2_sub(a, b) nk_vec2((a).x - (b).x, (a).y - (b).y)
5552 #define nk_vec2_add(a, b) nk_vec2((a).x + (b).x, (a).y + (b).y)
5553 #define nk_vec2_len_sqr(a) ((a).x*(a).x+(a).y*(a).y)
5554 #define nk_vec2_muls(a, t) nk_vec2((a).x * (t), (a).y * (t))
5555 
5556 #define nk_ptr_add(t, p, i) ((t*)((void*)((nk_byte*)(p) + (i))))
5557 #define nk_ptr_add_const(t, p, i) ((const t*)((const void*)((const nk_byte*)(p) + (i))))
5558 #define nk_zero_struct(s) nk_zero(&s, sizeof(s))
5559 
5560 /* ==============================================================
5561  * ALIGNMENT
5562  * =============================================================== */
5563 /* Pointer to Integer type conversion for pointer alignment */
5564 #if defined(__PTRDIFF_TYPE__) /* This case should work for GCC*/
5565 # define NK_UINT_TO_PTR(x) ((void*)(__PTRDIFF_TYPE__)(x))
5566 # define NK_PTR_TO_UINT(x) ((nk_size)(__PTRDIFF_TYPE__)(x))
5567 #elif !defined(__GNUC__) /* works for compilers other than LLVM */
5568 # define NK_UINT_TO_PTR(x) ((void*)&((char*)0)[x])
5569 # define NK_PTR_TO_UINT(x) ((nk_size)(((char*)x)-(char*)0))
5570 #elif defined(NK_USE_FIXED_TYPES) /* used if we have <stdint.h> */
5571 # define NK_UINT_TO_PTR(x) ((void*)(uintptr_t)(x))
5572 # define NK_PTR_TO_UINT(x) ((uintptr_t)(x))
5573 #else /* generates warning but works */
5574 # define NK_UINT_TO_PTR(x) ((void*)(x))
5575 # define NK_PTR_TO_UINT(x) ((nk_size)(x))
5576 #endif
5577 
5578 #define NK_ALIGN_PTR(x, mask)\
5579  (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x) + (mask-1)) & ~(mask-1))))
5580 #define NK_ALIGN_PTR_BACK(x, mask)\
5581  (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x)) & ~(mask-1))))
5582 
5583 #define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m))
5584 #define NK_CONTAINER_OF(ptr,type,member)\
5585  (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))
5586 
5587 #ifdef __cplusplus
5588 }
5589 #endif
5590 
5591 #ifdef __cplusplus
5592 template<typename T> struct nk_alignof;
5593 template<typename T, int size_diff> struct nk_helper{enum {value = size_diff};};
5594 template<typename T> struct nk_helper<T,0>{enum {value = nk_alignof<T>::value};};
5595 template<typename T> struct nk_alignof{struct Big {T x; char c;}; enum {
5596  diff = sizeof(Big) - sizeof(T), value = nk_helper<Big, diff>::value};};
5597 #define NK_ALIGNOF(t) (nk_alignof<t>::value)
5598 #elif defined(_MSC_VER)
5599 #define NK_ALIGNOF(t) (__alignof(t))
5600 #else
5601 #define NK_ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0)
5602 #endif
5603 
5604 #endif /* NK_NUKLEAR_H_ */
5605 
5606 
5607 #ifdef NK_IMPLEMENTATION
5608 
5609 #ifndef NK_INTERNAL_H
5610 #define NK_INTERNAL_H
5611 
5612 #ifndef NK_POOL_DEFAULT_CAPACITY
5613 #define NK_POOL_DEFAULT_CAPACITY 16
5614 #endif
5615 
5616 #ifndef NK_DEFAULT_COMMAND_BUFFER_SIZE
5617 #define NK_DEFAULT_COMMAND_BUFFER_SIZE (4*1024)
5618 #endif
5619 
5620 #ifndef NK_BUFFER_DEFAULT_INITIAL_SIZE
5621 #define NK_BUFFER_DEFAULT_INITIAL_SIZE (4*1024)
5622 #endif
5623 
5624 /* standard library headers */
5625 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
5626 #include <stdlib.h> /* malloc, free */
5627 #endif
5628 #ifdef NK_INCLUDE_STANDARD_IO
5629 #include <stdio.h> /* fopen, fclose,... */
5630 #endif
5631 #ifndef NK_ASSERT
5632 #include <assert.h>
5633 #define NK_ASSERT(expr) assert(expr)
5634 #endif
5635 
5636 #ifndef NK_MEMSET
5637 #define NK_MEMSET nk_memset
5638 #endif
5639 #ifndef NK_MEMCPY
5640 #define NK_MEMCPY nk_memcopy
5641 #endif
5642 #ifndef NK_SQRT
5643 #define NK_SQRT nk_sqrt
5644 #endif
5645 #ifndef NK_SIN
5646 #define NK_SIN nk_sin
5647 #endif
5648 #ifndef NK_COS
5649 #define NK_COS nk_cos
5650 #endif
5651 #ifndef NK_STRTOD
5652 #define NK_STRTOD nk_strtod
5653 #endif
5654 #ifndef NK_DTOA
5655 #define NK_DTOA nk_dtoa
5656 #endif
5657 
5658 #define NK_DEFAULT (-1)
5659 
5660 #ifndef NK_VSNPRINTF
5661 /* If your compiler does support `vsnprintf` I would highly recommend
5662  * defining this to vsnprintf instead since `vsprintf` is basically
5663  * unbelievable unsafe and should *NEVER* be used. But I have to support
5664  * it since C89 only provides this unsafe version. */
5665  #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) ||\
5666  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
5667  (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) ||\
5668  (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) ||\
5669  defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE)
5670  #define NK_VSNPRINTF(s,n,f,a) vsnprintf(s,n,f,a)
5671  #else
5672  #define NK_VSNPRINTF(s,n,f,a) vsprintf(s,f,a)
5673  #endif
5674 #endif
5675 
5676 #define NK_SCHAR_MIN (-127)
5677 #define NK_SCHAR_MAX 127
5678 #define NK_UCHAR_MIN 0
5679 #define NK_UCHAR_MAX 256
5680 #define NK_SSHORT_MIN (-32767)
5681 #define NK_SSHORT_MAX 32767
5682 #define NK_USHORT_MIN 0
5683 #define NK_USHORT_MAX 65535
5684 #define NK_SINT_MIN (-2147483647)
5685 #define NK_SINT_MAX 2147483647
5686 #define NK_UINT_MIN 0
5687 #define NK_UINT_MAX 4294967295u
5688 
5689 /* Make sure correct type size:
5690  * This will fire with a negative subscript error if the type sizes
5691  * are set incorrectly by the compiler, and compile out if not */
5692 NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
5693 NK_STATIC_ASSERT(sizeof(nk_ptr) == sizeof(void*));
5694 NK_STATIC_ASSERT(sizeof(nk_flags) >= 4);
5695 NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
5696 NK_STATIC_ASSERT(sizeof(nk_ushort) == 2);
5697 NK_STATIC_ASSERT(sizeof(nk_short) == 2);
5698 NK_STATIC_ASSERT(sizeof(nk_uint) == 4);
5699 NK_STATIC_ASSERT(sizeof(nk_int) == 4);
5700 NK_STATIC_ASSERT(sizeof(nk_byte) == 1);
5701 
5702 NK_GLOBAL const struct nk_rect nk_null_rect = {-8192.0f, -8192.0f, 16384, 16384};
5703 #define NK_FLOAT_PRECISION 0.00000000000001
5704 
5705 NK_GLOBAL const struct nk_color nk_red = {255,0,0,255};
5706 NK_GLOBAL const struct nk_color nk_green = {0,255,0,255};
5707 NK_GLOBAL const struct nk_color nk_blue = {0,0,255,255};
5708 NK_GLOBAL const struct nk_color nk_white = {255,255,255,255};
5709 NK_GLOBAL const struct nk_color nk_black = {0,0,0,255};
5710 NK_GLOBAL const struct nk_color nk_yellow = {255,255,0,255};
5711 
5712 /* widget */
5713 #define nk_widget_state_reset(s)\
5714  if ((*(s)) & NK_WIDGET_STATE_MODIFIED)\
5715  (*(s)) = NK_WIDGET_STATE_INACTIVE|NK_WIDGET_STATE_MODIFIED;\
5716  else (*(s)) = NK_WIDGET_STATE_INACTIVE;
5717 
5718 /* math */
5719 NK_LIB float nk_inv_sqrt(float n);
5720 NK_LIB float nk_sqrt(float x);
5721 NK_LIB float nk_sin(float x);
5722 NK_LIB float nk_cos(float x);
5723 NK_LIB nk_uint nk_round_up_pow2(nk_uint v);
5724 NK_LIB struct nk_rect nk_shrink_rect(struct nk_rect r, float amount);
5725 NK_LIB struct nk_rect nk_pad_rect(struct nk_rect r, struct nk_vec2 pad);
5726 NK_LIB void nk_unify(struct nk_rect *clip, const struct nk_rect *a, float x0, float y0, float x1, float y1);
5727 NK_LIB double nk_pow(double x, int n);
5728 NK_LIB int nk_ifloord(double x);
5729 NK_LIB int nk_ifloorf(float x);
5730 NK_LIB int nk_iceilf(float x);
5731 NK_LIB int nk_log10(double n);
5732 
5733 /* util */
5734 enum {NK_DO_NOT_STOP_ON_NEW_LINE, NK_STOP_ON_NEW_LINE};
5735 NK_LIB int nk_is_lower(int c);
5736 NK_LIB int nk_is_upper(int c);
5737 NK_LIB int nk_to_upper(int c);
5738 NK_LIB int nk_to_lower(int c);
5739 NK_LIB void* nk_memcopy(void *dst, const void *src, nk_size n);
5740 NK_LIB void nk_memset(void *ptr, int c0, nk_size size);
5741 NK_LIB void nk_zero(void *ptr, nk_size size);
5742 NK_LIB char *nk_itoa(char *s, long n);
5743 NK_LIB int nk_string_float_limit(char *string, int prec);
5744 NK_LIB char *nk_dtoa(char *s, double n);
5745 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);
5746 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);
5747 #ifdef NK_INCLUDE_STANDARD_VARARGS
5748 NK_LIB int nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args);
5749 #endif
5750 #ifdef NK_INCLUDE_STANDARD_IO
5751 NK_LIB char *nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc);
5752 #endif
5753 
5754 /* buffer */
5755 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
5756 NK_LIB void* nk_malloc(nk_handle unused, void *old,nk_size size);
5757 NK_LIB void nk_mfree(nk_handle unused, void *ptr);
5758 #endif
5759 NK_LIB void* nk_buffer_align(void *unaligned, nk_size align, nk_size *alignment, enum nk_buffer_allocation_type type);
5760 NK_LIB void* nk_buffer_alloc(struct nk_buffer *b, enum nk_buffer_allocation_type type, nk_size size, nk_size align);
5761 NK_LIB void* nk_buffer_realloc(struct nk_buffer *b, nk_size capacity, nk_size *size);
5762 
5763 /* draw */
5764 NK_LIB void nk_command_buffer_init(struct nk_command_buffer *cb, struct nk_buffer *b, enum nk_command_clipping clip);
5765 NK_LIB void nk_command_buffer_reset(struct nk_command_buffer *b);
5766 NK_LIB void* nk_command_buffer_push(struct nk_command_buffer* b, enum nk_command_type t, nk_size size);
5767 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);
5768 
5769 /* buffering */
5770 NK_LIB void nk_start_buffer(struct nk_context *ctx, struct nk_command_buffer *b);
5771 NK_LIB void nk_start(struct nk_context *ctx, struct nk_window *win);
5772 NK_LIB void nk_start_popup(struct nk_context *ctx, struct nk_window *win);
5773 NK_LIB void nk_finish_popup(struct nk_context *ctx, struct nk_window*);
5774 NK_LIB void nk_finish_buffer(struct nk_context *ctx, struct nk_command_buffer *b);
5775 NK_LIB void nk_finish(struct nk_context *ctx, struct nk_window *w);
5776 NK_LIB void nk_build(struct nk_context *ctx);
5777 
5778 /* text editor */
5779 NK_LIB void nk_textedit_clear_state(struct nk_text_edit *state, enum nk_text_edit_type type, nk_plugin_filter filter);
5780 NK_LIB void nk_textedit_click(struct nk_text_edit *state, float x, float y, const struct nk_user_font *font, float row_height);
5781 NK_LIB void nk_textedit_drag(struct nk_text_edit *state, float x, float y, const struct nk_user_font *font, float row_height);
5782 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);
5783 
5784 /* window */
5785 enum nk_window_insert_location {
5786  NK_INSERT_BACK, /* inserts window into the back of list (front of screen) */
5787  NK_INSERT_FRONT /* inserts window into the front of list (back of screen) */
5788 };
5789 NK_LIB void *nk_create_window(struct nk_context *ctx);
5790 NK_LIB void nk_remove_window(struct nk_context*, struct nk_window*);
5791 NK_LIB void nk_free_window(struct nk_context *ctx, struct nk_window *win);
5792 NK_LIB struct nk_window *nk_find_window(struct nk_context *ctx, nk_hash hash, const char *name);
5793 NK_LIB void nk_insert_window(struct nk_context *ctx, struct nk_window *win, enum nk_window_insert_location loc);
5794 
5795 /* pool */
5796 NK_LIB void nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc, unsigned int capacity);
5797 NK_LIB void nk_pool_free(struct nk_pool *pool);
5798 NK_LIB void nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size);
5799 NK_LIB struct nk_page_element *nk_pool_alloc(struct nk_pool *pool);
5800 
5801 /* page-element */
5802 NK_LIB struct nk_page_element* nk_create_page_element(struct nk_context *ctx);
5803 NK_LIB void nk_link_page_element_into_freelist(struct nk_context *ctx, struct nk_page_element *elem);
5804 NK_LIB void nk_free_page_element(struct nk_context *ctx, struct nk_page_element *elem);
5805 
5806 /* table */
5807 NK_LIB struct nk_table* nk_create_table(struct nk_context *ctx);
5808 NK_LIB void nk_remove_table(struct nk_window *win, struct nk_table *tbl);
5809 NK_LIB void nk_free_table(struct nk_context *ctx, struct nk_table *tbl);
5810 NK_LIB void nk_push_table(struct nk_window *win, struct nk_table *tbl);
5811 NK_LIB nk_uint *nk_add_value(struct nk_context *ctx, struct nk_window *win, nk_hash name, nk_uint value);
5812 NK_LIB nk_uint *nk_find_value(struct nk_window *win, nk_hash name);
5813 
5814 /* panel */
5815 NK_LIB void *nk_create_panel(struct nk_context *ctx);
5816 NK_LIB void nk_free_panel(struct nk_context*, struct nk_panel *pan);
5817 NK_LIB int nk_panel_has_header(nk_flags flags, const char *title);
5818 NK_LIB struct nk_vec2 nk_panel_get_padding(const struct nk_style *style, enum nk_panel_type type);
5819 NK_LIB float nk_panel_get_border(const struct nk_style *style, nk_flags flags, enum nk_panel_type type);
5820 NK_LIB struct nk_color nk_panel_get_border_color(const struct nk_style *style, enum nk_panel_type type);
5821 NK_LIB int nk_panel_is_sub(enum nk_panel_type type);
5822 NK_LIB int nk_panel_is_nonblock(enum nk_panel_type type);
5823 NK_LIB int nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type panel_type);
5824 NK_LIB void nk_panel_end(struct nk_context *ctx);
5825 
5826 /* layout */
5827 NK_LIB float nk_layout_row_calculate_usable_space(const struct nk_style *style, enum nk_panel_type type, float total_space, int columns);
5828 NK_LIB void nk_panel_layout(const struct nk_context *ctx, struct nk_window *win, float height, int cols);
5829 NK_LIB void nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt, float height, int cols, int width);
5830 NK_LIB void nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win);
5831 NK_LIB void nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx, struct nk_window *win, int modify);
5832 NK_LIB void nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx);
5833 NK_LIB void nk_layout_peek(struct nk_rect *bounds, struct nk_context *ctx);
5834 
5835 /* popup */
5836 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);
5837 
5838 /* text */
5839 struct nk_text {
5840  struct nk_vec2 padding;
5841  struct nk_color background;
5842  struct nk_color text;
5843 };
5844 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);
5845 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);
5846 
5847 /* button */
5848 NK_LIB int nk_button_behavior(nk_flags *state, struct nk_rect r, const struct nk_input *i, enum nk_button_behavior behavior);
5849 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);
5850 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);
5851 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);
5852 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);
5853 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);
5854 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);
5855 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);
5856 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);
5857 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);
5858 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);
5859 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);
5860 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);
5861 
5862 /* toggle */
5863 enum nk_toggle_type {
5864  NK_TOGGLE_CHECK,
5865  NK_TOGGLE_OPTION
5866 };
5867 NK_LIB int nk_toggle_behavior(const struct nk_input *in, struct nk_rect select, nk_flags *state, int active);
5868 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);
5869 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);
5870 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);
5871 
5872 /* progress */
5873 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);
5874 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);
5875 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);
5876 
5877 /* slider */
5878 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);
5879 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);
5880 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);
5881 
5882 /* scrollbar */
5883 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);
5884 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);
5885 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);
5886 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);
5887 
5888 /* selectable */
5889 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);
5890 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);
5891 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);
5892 
5893 /* edit */
5894 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);
5895 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);
5896 
5897 /* color-picker */
5898 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);
5899 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);
5900 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);
5901 
5902 /* property */
5903 enum nk_property_status {
5904  NK_PROPERTY_DEFAULT,
5905  NK_PROPERTY_EDIT,
5906  NK_PROPERTY_DRAG
5907 };
5908 enum nk_property_filter {
5909  NK_FILTER_INT,
5910  NK_FILTER_FLOAT
5911 };
5912 enum nk_property_kind {
5913  NK_PROPERTY_INT,
5914  NK_PROPERTY_FLOAT,
5915  NK_PROPERTY_DOUBLE
5916 };
5917 union nk_property {
5918  int i;
5919  float f;
5920  double d;
5921 };
5922 struct nk_property_variant {
5923  enum nk_property_kind kind;
5924  union nk_property value;
5925  union nk_property min_value;
5926  union nk_property max_value;
5927  union nk_property step;
5928 };
5929 NK_LIB struct nk_property_variant nk_property_variant_int(int value, int min_value, int max_value, int step);
5930 NK_LIB struct nk_property_variant nk_property_variant_float(float value, float min_value, float max_value, float step);
5931 NK_LIB struct nk_property_variant nk_property_variant_double(double value, double min_value, double max_value, double step);
5932 
5933 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);
5934 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);
5935 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);
5936 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);
5937 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);
5938 
5939 #endif
5940 
5941 
5942 
5943 
5944 
5945 /* ===============================================================
5946  *
5947  * MATH
5948  *
5949  * ===============================================================*/
5950 /* Since nuklear is supposed to work on all systems providing floating point
5951  math without any dependencies I also had to implement my own math functions
5952  for sqrt, sin and cos. Since the actual highly accurate implementations for
5953  the standard library functions are quite complex and I do not need high
5954  precision for my use cases I use approximations.
5955 
5956  Sqrt
5957  ----
5958  For square root nuklear uses the famous fast inverse square root:
5959  https://en.wikipedia.org/wiki/Fast_inverse_square_root with
5960  slightly tweaked magic constant. While on today's hardware it is
5961  probably not faster it is still fast and accurate enough for
5962  nuklear's use cases. IMPORTANT: this requires float format IEEE 754
5963 
5964  Sine/Cosine
5965  -----------
5966  All constants inside both function are generated Remez's minimax
5967  approximations for value range 0...2*PI. The reason why I decided to
5968  approximate exactly that range is that nuklear only needs sine and
5969  cosine to generate circles which only requires that exact range.
5970  In addition I used Remez instead of Taylor for additional precision:
5971  www.lolengine.net/blog/2011/12/21/better-function-approximations.
5972 
5973  The tool I used to generate constants for both sine and cosine
5974  (it can actually approximate a lot more functions) can be
5975  found here: www.lolengine.net/wiki/oss/lolremez
5976 */
5977 NK_LIB float
5978 nk_inv_sqrt(float n)
5979 {
5980  float x2;
5981  const float threehalfs = 1.5f;
5982  union {nk_uint i; float f;} conv = {0};
5983  conv.f = n;
5984  x2 = n * 0.5f;
5985  conv.i = 0x5f375A84 - (conv.i >> 1);
5986  conv.f = conv.f * (threehalfs - (x2 * conv.f * conv.f));
5987  return conv.f;
5988 }
5989 NK_LIB float
5990 nk_sqrt(float x)
5991 {
5992  return x * nk_inv_sqrt(x);
5993 }
5994 NK_LIB float
5995 nk_sin(float x)
5996 {
5997  NK_STORAGE const float a0 = +1.91059300966915117e-31f;
5998  NK_STORAGE const float a1 = +1.00086760103908896f;
5999  NK_STORAGE const float a2 = -1.21276126894734565e-2f;
6000  NK_STORAGE const float a3 = -1.38078780785773762e-1f;
6001  NK_STORAGE const float a4 = -2.67353392911981221e-2f;
6002  NK_STORAGE const float a5 = +2.08026600266304389e-2f;
6003  NK_STORAGE const float a6 = -3.03996055049204407e-3f;
6004  NK_STORAGE const float a7 = +1.38235642404333740e-4f;
6005  return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7))))));
6006 }
6007 NK_LIB float
6008 nk_cos(float x)
6009 {
6010  NK_STORAGE const float a0 = +1.00238601909309722f;
6011  NK_STORAGE const float a1 = -3.81919947353040024e-2f;
6012  NK_STORAGE const float a2 = -3.94382342128062756e-1f;
6013  NK_STORAGE const float a3 = -1.18134036025221444e-1f;
6014  NK_STORAGE const float a4 = +1.07123798512170878e-1f;
6015  NK_STORAGE const float a5 = -1.86637164165180873e-2f;
6016  NK_STORAGE const float a6 = +9.90140908664079833e-4f;
6017  NK_STORAGE const float a7 = -5.23022132118824778e-14f;
6018  return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7))))));
6019 }
6020 NK_LIB nk_uint
6021 nk_round_up_pow2(nk_uint v)
6022 {
6023  v--;
6024  v |= v >> 1;
6025  v |= v >> 2;
6026  v |= v >> 4;
6027  v |= v >> 8;
6028  v |= v >> 16;
6029  v++;
6030  return v;
6031 }
6032 NK_LIB double
6033 nk_pow(double x, int n)
6034 {
6035  /* check the sign of n */
6036  double r = 1;
6037  int plus = n >= 0;
6038  n = (plus) ? n : -n;
6039  while (n > 0) {
6040  if ((n & 1) == 1)
6041  r *= x;
6042  n /= 2;
6043  x *= x;
6044  }
6045  return plus ? r : 1.0 / r;
6046 }
6047 NK_LIB int
6048 nk_ifloord(double x)
6049 {
6050  x = (double)((int)x - ((x < 0.0) ? 1 : 0));
6051  return (int)x;
6052 }
6053 NK_LIB int
6054 nk_ifloorf(float x)
6055 {
6056  x = (float)((int)x - ((x < 0.0f) ? 1 : 0));
6057  return (int)x;
6058 }
6059 NK_LIB int
6060 nk_iceilf(float x)
6061 {
6062  if (x >= 0) {
6063  int i = (int)x;
6064  return (x > i) ? i+1: i;
6065  } else {
6066  int t = (int)x;
6067  float r = x - (float)t;
6068  return (r > 0.0f) ? t+1: t;
6069  }
6070 }
6071 NK_LIB int
6072 nk_log10(double n)
6073 {
6074  int neg;
6075  int ret;
6076  int exp = 0;
6077 
6078  neg = (n < 0) ? 1 : 0;
6079  ret = (neg) ? (int)-n : (int)n;
6080  while ((ret / 10) > 0) {
6081  ret /= 10;
6082  exp++;
6083  }
6084  if (neg) exp = -exp;
6085  return exp;
6086 }
6087 NK_API struct nk_rect
6089 {
6090  return nk_null_rect;
6091 }
6092 NK_API struct nk_rect
6093 nk_rect(float x, float y, float w, float h)
6094 {
6095  struct nk_rect r;
6096  r.x = x; r.y = y;
6097  r.w = w; r.h = h;
6098  return r;
6099 }
6100 NK_API struct nk_rect
6101 nk_recti(int x, int y, int w, int h)
6102 {
6103  struct nk_rect r;
6104  r.x = (float)x;
6105  r.y = (float)y;
6106  r.w = (float)w;
6107  r.h = (float)h;
6108  return r;
6109 }
6110 NK_API struct nk_rect
6111 nk_recta(struct nk_vec2 pos, struct nk_vec2 size)
6112 {
6113  return nk_rect(pos.x, pos.y, size.x, size.y);
6114 }
6115 NK_API struct nk_rect
6116 nk_rectv(const float *r)
6117 {
6118  return nk_rect(r[0], r[1], r[2], r[3]);
6119 }
6120 NK_API struct nk_rect
6121 nk_rectiv(const int *r)
6122 {
6123  return nk_recti(r[0], r[1], r[2], r[3]);
6124 }
6125 NK_API struct nk_vec2
6126 nk_rect_pos(struct nk_rect r)
6127 {
6128  struct nk_vec2 ret;
6129  ret.x = r.x; ret.y = r.y;
6130  return ret;
6131 }
6132 NK_API struct nk_vec2
6133 nk_rect_size(struct nk_rect r)
6134 {
6135  struct nk_vec2 ret;
6136  ret.x = r.w; ret.y = r.h;
6137  return ret;
6138 }
6139 NK_LIB struct nk_rect
6140 nk_shrink_rect(struct nk_rect r, float amount)
6141 {
6142  struct nk_rect res;
6143  r.w = NK_MAX(r.w, 2 * amount);
6144  r.h = NK_MAX(r.h, 2 * amount);
6145  res.x = r.x + amount;
6146  res.y = r.y + amount;
6147  res.w = r.w - 2 * amount;
6148  res.h = r.h - 2 * amount;
6149  return res;
6150 }
6151 NK_LIB struct nk_rect
6152 nk_pad_rect(struct nk_rect r, struct nk_vec2 pad)
6153 {
6154  r.w = NK_MAX(r.w, 2 * pad.x);
6155  r.h = NK_MAX(r.h, 2 * pad.y);
6156  r.x += pad.x; r.y += pad.y;
6157  r.w -= 2 * pad.x;
6158  r.h -= 2 * pad.y;
6159  return r;
6160 }
6161 NK_API struct nk_vec2
6162 nk_vec2(float x, float y)
6163 {
6164  struct nk_vec2 ret;
6165  ret.x = x; ret.y = y;
6166  return ret;
6167 }
6168 NK_API struct nk_vec2
6169 nk_vec2i(int x, int y)
6170 {
6171  struct nk_vec2 ret;
6172  ret.x = (float)x;
6173  ret.y = (float)y;
6174  return ret;
6175 }
6176 NK_API struct nk_vec2
6177 nk_vec2v(const float *v)
6178 {
6179  return nk_vec2(v[0], v[1]);
6180 }
6181 NK_API struct nk_vec2
6182 nk_vec2iv(const int *v)
6183 {
6184  return nk_vec2i(v[0], v[1]);
6185 }
6186 NK_LIB void
6187 nk_unify(struct nk_rect *clip, const struct nk_rect *a, float x0, float y0,
6188  float x1, float y1)
6189 {
6190  NK_ASSERT(a);
6191  NK_ASSERT(clip);
6192  clip->x = NK_MAX(a->x, x0);
6193  clip->y = NK_MAX(a->y, y0);
6194  clip->w = NK_MIN(a->x + a->w, x1) - clip->x;
6195  clip->h = NK_MIN(a->y + a->h, y1) - clip->y;
6196  clip->w = NK_MAX(0, clip->w);
6197  clip->h = NK_MAX(0, clip->h);
6198 }
6199 
6200 NK_API void
6202  float pad_x, float pad_y, enum nk_heading direction)
6203 {
6204  float w_half, h_half;
6205  NK_ASSERT(result);
6206 
6207  r.w = NK_MAX(2 * pad_x, r.w);
6208  r.h = NK_MAX(2 * pad_y, r.h);
6209  r.w = r.w - 2 * pad_x;
6210  r.h = r.h - 2 * pad_y;
6211 
6212  r.x = r.x + pad_x;
6213  r.y = r.y + pad_y;
6214 
6215  w_half = r.w / 2.0f;
6216  h_half = r.h / 2.0f;
6217 
6218  if (direction == NK_UP) {
6219  result[0] = nk_vec2(r.x + w_half, r.y);
6220  result[1] = nk_vec2(r.x + r.w, r.y + r.h);
6221  result[2] = nk_vec2(r.x, r.y + r.h);
6222  } else if (direction == NK_RIGHT) {
6223  result[0] = nk_vec2(r.x, r.y);
6224  result[1] = nk_vec2(r.x + r.w, r.y + h_half);
6225  result[2] = nk_vec2(r.x, r.y + r.h);
6226  } else if (direction == NK_DOWN) {
6227  result[0] = nk_vec2(r.x, r.y);
6228  result[1] = nk_vec2(r.x + r.w, r.y);
6229  result[2] = nk_vec2(r.x + w_half, r.y + r.h);
6230  } else {
6231  result[0] = nk_vec2(r.x, r.y + h_half);
6232  result[1] = nk_vec2(r.x + r.w, r.y);
6233  result[2] = nk_vec2(r.x + r.w, r.y + r.h);
6234  }
6235 }
6236 
6237 
6238 
6239 
6240 
6241 /* ===============================================================
6242  *
6243  * UTIL
6244  *
6245  * ===============================================================*/
6246 NK_INTERN int nk_str_match_here(const char *regexp, const char *text);
6247 NK_INTERN int nk_str_match_star(int c, const char *regexp, const char *text);
6248 NK_LIB int nk_is_lower(int c) {return (c >= 'a' && c <= 'z') || (c >= 0xE0 && c <= 0xFF);}
6249 NK_LIB int nk_is_upper(int c){return (c >= 'A' && c <= 'Z') || (c >= 0xC0 && c <= 0xDF);}
6250 NK_LIB int nk_to_upper(int c) {return (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;}
6251 NK_LIB int nk_to_lower(int c) {return (c >= 'A' && c <= 'Z') ? (c - ('a' + 'A')) : c;}
6252 
6253 NK_LIB void*
6254 nk_memcopy(void *dst0, const void *src0, nk_size length)
6255 {
6256  nk_ptr t;
6257  char *dst = (char*)dst0;
6258  const char *src = (const char*)src0;
6259  if (length == 0 || dst == src)
6260  goto done;
6261 
6262  #define nk_word int
6263  #define nk_wsize sizeof(nk_word)
6264  #define nk_wmask (nk_wsize-1)
6265  #define NK_TLOOP(s) if (t) NK_TLOOP1(s)
6266  #define NK_TLOOP1(s) do { s; } while (--t)
6267 
6268  if (dst < src) {
6269  t = (nk_ptr)src; /* only need low bits */
6270  if ((t | (nk_ptr)dst) & nk_wmask) {
6271  if ((t ^ (nk_ptr)dst) & nk_wmask || length < nk_wsize)
6272  t = length;
6273  else
6274  t = nk_wsize - (t & nk_wmask);
6275  length -= t;
6276  NK_TLOOP1(*dst++ = *src++);
6277  }
6278  t = length / nk_wsize;
6279  NK_TLOOP(*(nk_word*)(void*)dst = *(const nk_word*)(const void*)src;
6280  src += nk_wsize; dst += nk_wsize);
6281  t = length & nk_wmask;
6282  NK_TLOOP(*dst++ = *src++);
6283  } else {
6284  src += length;
6285  dst += length;
6286  t = (nk_ptr)src;
6287  if ((t | (nk_ptr)dst) & nk_wmask) {
6288  if ((t ^ (nk_ptr)dst) & nk_wmask || length <= nk_wsize)
6289  t = length;
6290  else
6291  t &= nk_wmask;
6292  length -= t;
6293  NK_TLOOP1(*--dst = *--src);
6294  }
6295  t = length / nk_wsize;
6296  NK_TLOOP(src -= nk_wsize; dst -= nk_wsize;
6297  *(nk_word*)(void*)dst = *(const nk_word*)(const void*)src);
6298  t = length & nk_wmask;
6299  NK_TLOOP(*--dst = *--src);
6300  }
6301  #undef nk_word
6302  #undef nk_wsize
6303  #undef nk_wmask
6304  #undef NK_TLOOP
6305  #undef NK_TLOOP1
6306 done:
6307  return (dst0);
6308 }
6309 NK_LIB void
6310 nk_memset(void *ptr, int c0, nk_size size)
6311 {
6312  #define nk_word unsigned
6313  #define nk_wsize sizeof(nk_word)
6314  #define nk_wmask (nk_wsize - 1)
6315  nk_byte *dst = (nk_byte*)ptr;
6316  unsigned c = 0;
6317  nk_size t = 0;
6318 
6319  if ((c = (nk_byte)c0) != 0) {
6320  c = (c << 8) | c; /* at least 16-bits */
6321  if (sizeof(unsigned int) > 2)
6322  c = (c << 16) | c; /* at least 32-bits*/
6323  }
6324 
6325  /* too small of a word count */
6326  dst = (nk_byte*)ptr;
6327  if (size < 3 * nk_wsize) {
6328  while (size--) *dst++ = (nk_byte)c0;
6329  return;
6330  }
6331 
6332  /* align destination */
6333  if ((t = NK_PTR_TO_UINT(dst) & nk_wmask) != 0) {
6334  t = nk_wsize -t;
6335  size -= t;
6336  do {
6337  *dst++ = (nk_byte)c0;
6338  } while (--t != 0);
6339  }
6340 
6341  /* fill word */
6342  t = size / nk_wsize;
6343  do {
6344  *(nk_word*)((void*)dst) = c;
6345  dst += nk_wsize;
6346  } while (--t != 0);
6347 
6348  /* fill trailing bytes */
6349  t = (size & nk_wmask);
6350  if (t != 0) {
6351  do {
6352  *dst++ = (nk_byte)c0;
6353  } while (--t != 0);
6354  }
6355 
6356  #undef nk_word
6357  #undef nk_wsize
6358  #undef nk_wmask
6359 }
6360 NK_LIB void
6361 nk_zero(void *ptr, nk_size size)
6362 {
6363  NK_ASSERT(ptr);
6364  NK_MEMSET(ptr, 0, size);
6365 }
6366 NK_API int
6367 nk_strlen(const char *str)
6368 {
6369  int siz = 0;
6370  NK_ASSERT(str);
6371  while (str && *str++ != '\0') siz++;
6372  return siz;
6373 }
6374 NK_API int
6375 nk_strtoi(const char *str, const char **endptr)
6376 {
6377  int neg = 1;
6378  const char *p = str;
6379  int value = 0;
6380 
6381  NK_ASSERT(str);
6382  if (!str) return 0;
6383 
6384  /* skip whitespace */
6385  while (*p == ' ') p++;
6386  if (*p == '-') {
6387  neg = -1;
6388  p++;
6389  }
6390  while (*p && *p >= '0' && *p <= '9') {
6391  value = value * 10 + (int) (*p - '0');
6392  p++;
6393  }
6394  if (endptr)
6395  *endptr = p;
6396  return neg*value;
6397 }
6398 NK_API double
6399 nk_strtod(const char *str, const char **endptr)
6400 {
6401  double m;
6402  double neg = 1.0;
6403  const char *p = str;
6404  double value = 0;
6405  double number = 0;
6406 
6407  NK_ASSERT(str);
6408  if (!str) return 0;
6409 
6410  /* skip whitespace */
6411  while (*p == ' ') p++;
6412  if (*p == '-') {
6413  neg = -1.0;
6414  p++;
6415  }
6416 
6417  while (*p && *p != '.' && *p != 'e') {
6418  value = value * 10.0 + (double) (*p - '0');
6419  p++;
6420  }
6421 
6422  if (*p == '.') {
6423  p++;
6424  for(m = 0.1; *p && *p != 'e'; p++ ) {
6425  value = value + (double) (*p - '0') * m;
6426  m *= 0.1;
6427  }
6428  }
6429  if (*p == 'e') {
6430  int i, pow, div;
6431  p++;
6432  if (*p == '-') {
6433  div = nk_true;
6434  p++;
6435  } else if (*p == '+') {
6436  div = nk_false;
6437  p++;
6438  } else div = nk_false;
6439 
6440  for (pow = 0; *p; p++)
6441  pow = pow * 10 + (int) (*p - '0');
6442 
6443  for (m = 1.0, i = 0; i < pow; i++)
6444  m *= 10.0;
6445 
6446  if (div)
6447  value /= m;
6448  else value *= m;
6449  }
6450  number = value * neg;
6451  if (endptr)
6452  *endptr = p;
6453  return number;
6454 }
6455 NK_API float
6456 nk_strtof(const char *str, const char **endptr)
6457 {
6458  float float_value;
6459  double double_value;
6460  double_value = NK_STRTOD(str, endptr);
6461  float_value = (float)double_value;
6462  return float_value;
6463 }
6464 NK_API int
6465 nk_stricmp(const char *s1, const char *s2)
6466 {
6467  nk_int c1,c2,d;
6468  do {
6469  c1 = *s1++;
6470  c2 = *s2++;
6471  d = c1 - c2;
6472  while (d) {
6473  if (c1 <= 'Z' && c1 >= 'A') {
6474  d += ('a' - 'A');
6475  if (!d) break;
6476  }
6477  if (c2 <= 'Z' && c2 >= 'A') {
6478  d -= ('a' - 'A');
6479  if (!d) break;
6480  }
6481  return ((d >= 0) << 1) - 1;
6482  }
6483  } while (c1);
6484  return 0;
6485 }
6486 NK_API int
6487 nk_stricmpn(const char *s1, const char *s2, int n)
6488 {
6489  int c1,c2,d;
6490  NK_ASSERT(n >= 0);
6491  do {
6492  c1 = *s1++;
6493  c2 = *s2++;
6494  if (!n--) return 0;
6495 
6496  d = c1 - c2;
6497  while (d) {
6498  if (c1 <= 'Z' && c1 >= 'A') {
6499  d += ('a' - 'A');
6500  if (!d) break;
6501  }
6502  if (c2 <= 'Z' && c2 >= 'A') {
6503  d -= ('a' - 'A');
6504  if (!d) break;
6505  }
6506  return ((d >= 0) << 1) - 1;
6507  }
6508  } while (c1);
6509  return 0;
6510 }
6511 NK_INTERN int
6512 nk_str_match_here(const char *regexp, const char *text)
6513 {
6514  if (regexp[0] == '\0')
6515  return 1;
6516  if (regexp[1] == '*')
6517  return nk_str_match_star(regexp[0], regexp+2, text);
6518  if (regexp[0] == '$' && regexp[1] == '\0')
6519  return *text == '\0';
6520  if (*text!='\0' && (regexp[0]=='.' || regexp[0]==*text))
6521  return nk_str_match_here(regexp+1, text+1);
6522  return 0;
6523 }
6524 NK_INTERN int
6525 nk_str_match_star(int c, const char *regexp, const char *text)
6526 {
6527  do {/* a '* matches zero or more instances */
6528  if (nk_str_match_here(regexp, text))
6529  return 1;
6530  } while (*text != '\0' && (*text++ == c || c == '.'));
6531  return 0;
6532 }
6533 NK_API int
6534 nk_strfilter(const char *text, const char *regexp)
6535 {
6536  /*
6537  c matches any literal character c
6538  . matches any single character
6539  ^ matches the beginning of the input string
6540  $ matches the end of the input string
6541  * matches zero or more occurrences of the previous character*/
6542  if (regexp[0] == '^')
6543  return nk_str_match_here(regexp+1, text);
6544  do { /* must look even if string is empty */
6545  if (nk_str_match_here(regexp, text))
6546  return 1;
6547  } while (*text++ != '\0');
6548  return 0;
6549 }
6550 NK_API int
6551 nk_strmatch_fuzzy_text(const char *str, int str_len,
6552  const char *pattern, int *out_score)
6553 {
6554  /* Returns true if each character in pattern is found sequentially within str
6555  * if found then out_score is also set. Score value has no intrinsic meaning.
6556  * Range varies with pattern. Can only compare scores with same search pattern. */
6557 
6558  /* bonus for adjacent matches */
6559  #define NK_ADJACENCY_BONUS 5
6560  /* bonus if match occurs after a separator */
6561  #define NK_SEPARATOR_BONUS 10
6562  /* bonus if match is uppercase and prev is lower */
6563  #define NK_CAMEL_BONUS 10
6564  /* penalty applied for every letter in str before the first match */
6565  #define NK_LEADING_LETTER_PENALTY (-3)
6566  /* maximum penalty for leading letters */
6567  #define NK_MAX_LEADING_LETTER_PENALTY (-9)
6568  /* penalty for every letter that doesn't matter */
6569  #define NK_UNMATCHED_LETTER_PENALTY (-1)
6570 
6571  /* loop variables */
6572  int score = 0;
6573  char const * pattern_iter = pattern;
6574  int str_iter = 0;
6575  int prev_matched = nk_false;
6576  int prev_lower = nk_false;
6577  /* true so if first letter match gets separator bonus*/
6578  int prev_separator = nk_true;
6579 
6580  /* use "best" matched letter if multiple string letters match the pattern */
6581  char const * best_letter = 0;
6582  int best_letter_score = 0;
6583 
6584  /* loop over strings */
6585  NK_ASSERT(str);
6586  NK_ASSERT(pattern);
6587  if (!str || !str_len || !pattern) return 0;
6588  while (str_iter < str_len)
6589  {
6590  const char pattern_letter = *pattern_iter;
6591  const char str_letter = str[str_iter];
6592 
6593  int next_match = *pattern_iter != '\0' &&
6594  nk_to_lower(pattern_letter) == nk_to_lower(str_letter);
6595  int rematch = best_letter && nk_to_upper(*best_letter) == nk_to_upper(str_letter);
6596 
6597  int advanced = next_match && best_letter;
6598  int pattern_repeat = best_letter && *pattern_iter != '\0';
6599  pattern_repeat = pattern_repeat &&
6600  nk_to_lower(*best_letter) == nk_to_lower(pattern_letter);
6601 
6602  if (advanced || pattern_repeat) {
6603  score += best_letter_score;
6604  best_letter = 0;
6605  best_letter_score = 0;
6606  }
6607 
6608  if (next_match || rematch)
6609  {
6610  int new_score = 0;
6611  /* Apply penalty for each letter before the first pattern match */
6612  if (pattern_iter == pattern) {
6613  int count = (int)(&str[str_iter] - str);
6614  int penalty = NK_LEADING_LETTER_PENALTY * count;
6615  if (penalty < NK_MAX_LEADING_LETTER_PENALTY)
6616  penalty = NK_MAX_LEADING_LETTER_PENALTY;
6617 
6618  score += penalty;
6619  }
6620 
6621  /* apply bonus for consecutive bonuses */
6622  if (prev_matched)
6623  new_score += NK_ADJACENCY_BONUS;
6624 
6625  /* apply bonus for matches after a separator */
6626  if (prev_separator)
6627  new_score += NK_SEPARATOR_BONUS;
6628 
6629  /* apply bonus across camel case boundaries */
6630  if (prev_lower && nk_is_upper(str_letter))
6631  new_score += NK_CAMEL_BONUS;
6632 
6633  /* update pattern iter IFF the next pattern letter was matched */
6634  if (next_match)
6635  ++pattern_iter;
6636 
6637  /* update best letter in str which may be for a "next" letter or a rematch */
6638  if (new_score >= best_letter_score) {
6639  /* apply penalty for now skipped letter */
6640  if (best_letter != 0)
6641  score += NK_UNMATCHED_LETTER_PENALTY;
6642 
6643  best_letter = &str[str_iter];
6644  best_letter_score = new_score;
6645  }
6646  prev_matched = nk_true;
6647  } else {
6648  score += NK_UNMATCHED_LETTER_PENALTY;
6649  prev_matched = nk_false;
6650  }
6651 
6652  /* separators should be more easily defined */
6653  prev_lower = nk_is_lower(str_letter) != 0;
6654  prev_separator = str_letter == '_' || str_letter == ' ';
6655 
6656  ++str_iter;
6657  }
6658 
6659  /* apply score for last match */
6660  if (best_letter)
6661  score += best_letter_score;
6662 
6663  /* did not match full pattern */
6664  if (*pattern_iter != '\0')
6665  return nk_false;
6666 
6667  if (out_score)
6668  *out_score = score;
6669  return nk_true;
6670 }
6671 NK_API int
6672 nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score)
6673 {
6674  return nk_strmatch_fuzzy_text(str, nk_strlen(str), pattern, out_score);
6675 }
6676 NK_LIB int
6677 nk_string_float_limit(char *string, int prec)
6678 {
6679  int dot = 0;
6680  char *c = string;
6681  while (*c) {
6682  if (*c == '.') {
6683  dot = 1;
6684  c++;
6685  continue;
6686  }
6687  if (dot == (prec+1)) {
6688  *c = 0;
6689  break;
6690  }
6691  if (dot > 0) dot++;
6692  c++;
6693  }
6694  return (int)(c - string);
6695 }
6696 NK_INTERN void
6697 nk_strrev_ascii(char *s)
6698 {
6699  int len = nk_strlen(s);
6700  int end = len / 2;
6701  int i = 0;
6702  char t;
6703  for (; i < end; ++i) {
6704  t = s[i];
6705  s[i] = s[len - 1 - i];
6706  s[len -1 - i] = t;
6707  }
6708 }
6709 NK_LIB char*
6710 nk_itoa(char *s, long n)
6711 {
6712  long i = 0;
6713  if (n == 0) {
6714  s[i++] = '0';
6715  s[i] = 0;
6716  return s;
6717  }
6718  if (n < 0) {
6719  s[i++] = '-';
6720  n = -n;
6721  }
6722  while (n > 0) {
6723  s[i++] = (char)('0' + (n % 10));
6724  n /= 10;
6725  }
6726  s[i] = 0;
6727  if (s[0] == '-')
6728  ++s;
6729 
6730  nk_strrev_ascii(s);
6731  return s;
6732 }
6733 NK_LIB char*
6734 nk_dtoa(char *s, double n)
6735 {
6736  int useExp = 0;
6737  int digit = 0, m = 0, m1 = 0;
6738  char *c = s;
6739  int neg = 0;
6740 
6741  NK_ASSERT(s);
6742  if (!s) return 0;
6743 
6744  if (n == 0.0) {
6745  s[0] = '0'; s[1] = '\0';
6746  return s;
6747  }
6748 
6749  neg = (n < 0);
6750  if (neg) n = -n;
6751 
6752  /* calculate magnitude */
6753  m = nk_log10(n);
6754  useExp = (m >= 14 || (neg && m >= 9) || m <= -9);
6755  if (neg) *(c++) = '-';
6756 
6757  /* set up for scientific notation */
6758  if (useExp) {
6759  if (m < 0)
6760  m -= 1;
6761  n = n / (double)nk_pow(10.0, m);
6762  m1 = m;
6763  m = 0;
6764  }
6765  if (m < 1.0) {
6766  m = 0;
6767  }
6768 
6769  /* convert the number */
6770  while (n > NK_FLOAT_PRECISION || m >= 0) {
6771  double weight = nk_pow(10.0, m);
6772  if (weight > 0) {
6773  double t = (double)n / weight;
6774  digit = nk_ifloord(t);
6775  n -= ((double)digit * weight);
6776  *(c++) = (char)('0' + (char)digit);
6777  }
6778  if (m == 0 && n > 0)
6779  *(c++) = '.';
6780  m--;
6781  }
6782 
6783  if (useExp) {
6784  /* convert the exponent */
6785  int i, j;
6786  *(c++) = 'e';
6787  if (m1 > 0) {
6788  *(c++) = '+';
6789  } else {
6790  *(c++) = '-';
6791  m1 = -m1;
6792  }
6793  m = 0;
6794  while (m1 > 0) {
6795  *(c++) = (char)('0' + (char)(m1 % 10));
6796  m1 /= 10;
6797  m++;
6798  }
6799  c -= m;
6800  for (i = 0, j = m-1; i<j; i++, j--) {
6801  /* swap without temporary */
6802  c[i] ^= c[j];
6803  c[j] ^= c[i];
6804  c[i] ^= c[j];
6805  }
6806  c += m;
6807  }
6808  *(c) = '\0';
6809  return s;
6810 }
6811 #ifdef NK_INCLUDE_STANDARD_VARARGS
6812 #ifndef NK_INCLUDE_STANDARD_IO
6813 NK_INTERN int
6814 nk_vsnprintf(char *buf, int buf_size, const char *fmt, va_list args)
6815 {
6816  enum nk_arg_type {
6817  NK_ARG_TYPE_CHAR,
6818  NK_ARG_TYPE_SHORT,
6819  NK_ARG_TYPE_DEFAULT,
6820  NK_ARG_TYPE_LONG
6821  };
6822  enum nk_arg_flags {
6823  NK_ARG_FLAG_LEFT = 0x01,
6824  NK_ARG_FLAG_PLUS = 0x02,
6825  NK_ARG_FLAG_SPACE = 0x04,
6826  NK_ARG_FLAG_NUM = 0x10,
6827  NK_ARG_FLAG_ZERO = 0x20
6828  };
6829 
6830  char number_buffer[NK_MAX_NUMBER_BUFFER];
6831  enum nk_arg_type arg_type = NK_ARG_TYPE_DEFAULT;
6832  int precision = NK_DEFAULT;
6833  int width = NK_DEFAULT;
6834  nk_flags flag = 0;
6835 
6836  int len = 0;
6837  int result = -1;
6838  const char *iter = fmt;
6839 
6840  NK_ASSERT(buf);
6841  NK_ASSERT(buf_size);
6842  if (!buf || !buf_size || !fmt) return 0;
6843  for (iter = fmt; *iter && len < buf_size; iter++) {
6844  /* copy all non-format characters */
6845  while (*iter && (*iter != '%') && (len < buf_size))
6846  buf[len++] = *iter++;
6847  if (!(*iter) || len >= buf_size) break;
6848  iter++;
6849 
6850  /* flag arguments */
6851  while (*iter) {
6852  if (*iter == '-') flag |= NK_ARG_FLAG_LEFT;
6853  else if (*iter == '+') flag |= NK_ARG_FLAG_PLUS;
6854  else if (*iter == ' ') flag |= NK_ARG_FLAG_SPACE;
6855  else if (*iter == '#') flag |= NK_ARG_FLAG_NUM;
6856  else if (*iter == '0') flag |= NK_ARG_FLAG_ZERO;
6857  else break;
6858  iter++;
6859  }
6860 
6861  /* width argument */
6862  width = NK_DEFAULT;
6863  if (*iter >= '1' && *iter <= '9') {
6864  const char *end;
6865  width = nk_strtoi(iter, &end);
6866  if (end == iter)
6867  width = -1;
6868  else iter = end;
6869  } else if (*iter == '*') {
6870  width = va_arg(args, int);
6871  iter++;
6872  }
6873 
6874  /* precision argument */
6875  precision = NK_DEFAULT;
6876  if (*iter == '.') {
6877  iter++;
6878  if (*iter == '*') {
6879  precision = va_arg(args, int);
6880  iter++;
6881  } else {
6882  const char *end;
6883  precision = nk_strtoi(iter, &end);
6884  if (end == iter)
6885  precision = -1;
6886  else iter = end;
6887  }
6888  }
6889 
6890  /* length modifier */
6891  if (*iter == 'h') {
6892  if (*(iter+1) == 'h') {
6893  arg_type = NK_ARG_TYPE_CHAR;
6894  iter++;
6895  } else arg_type = NK_ARG_TYPE_SHORT;
6896  iter++;
6897  } else if (*iter == 'l') {
6898  arg_type = NK_ARG_TYPE_LONG;
6899  iter++;
6900  } else arg_type = NK_ARG_TYPE_DEFAULT;
6901 
6902  /* specifier */
6903  if (*iter == '%') {
6904  NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
6905  NK_ASSERT(precision == NK_DEFAULT);
6906  NK_ASSERT(width == NK_DEFAULT);
6907  if (len < buf_size)
6908  buf[len++] = '%';
6909  } else if (*iter == 's') {
6910  /* string */
6911  const char *str = va_arg(args, const char*);
6912  NK_ASSERT(str != buf && "buffer and argument are not allowed to overlap!");
6913  NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
6914  NK_ASSERT(precision == NK_DEFAULT);
6915  NK_ASSERT(width == NK_DEFAULT);
6916  if (str == buf) return -1;
6917  while (str && *str && len < buf_size)
6918  buf[len++] = *str++;
6919  } else if (*iter == 'n') {
6920  /* current length callback */
6921  signed int *n = va_arg(args, int*);
6922  NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
6923  NK_ASSERT(precision == NK_DEFAULT);
6924  NK_ASSERT(width == NK_DEFAULT);
6925  if (n) *n = len;
6926  } else if (*iter == 'c' || *iter == 'i' || *iter == 'd') {
6927  /* signed integer */
6928  long value = 0;
6929  const char *num_iter;
6930  int num_len, num_print, padding;
6931  int cur_precision = NK_MAX(precision, 1);
6932  int cur_width = NK_MAX(width, 0);
6933 
6934  /* retrieve correct value type */
6935  if (arg_type == NK_ARG_TYPE_CHAR)
6936  value = (signed char)va_arg(args, int);
6937  else if (arg_type == NK_ARG_TYPE_SHORT)
6938  value = (signed short)va_arg(args, int);
6939  else if (arg_type == NK_ARG_TYPE_LONG)
6940  value = va_arg(args, signed long);
6941  else if (*iter == 'c')
6942  value = (unsigned char)va_arg(args, int);
6943  else value = va_arg(args, signed int);
6944 
6945  /* convert number to string */
6946  nk_itoa(number_buffer, value);
6947  num_len = nk_strlen(number_buffer);
6948  padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
6949  if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
6950  padding = NK_MAX(padding-1, 0);
6951 
6952  /* fill left padding up to a total of `width` characters */
6953  if (!(flag & NK_ARG_FLAG_LEFT)) {
6954  while (padding-- > 0 && (len < buf_size)) {
6955  if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
6956  buf[len++] = '0';
6957  else buf[len++] = ' ';
6958  }
6959  }
6960 
6961  /* copy string value representation into buffer */
6962  if ((flag & NK_ARG_FLAG_PLUS) && value >= 0 && len < buf_size)
6963  buf[len++] = '+';
6964  else if ((flag & NK_ARG_FLAG_SPACE) && value >= 0 && len < buf_size)
6965  buf[len++] = ' ';
6966 
6967  /* fill up to precision number of digits with '0' */
6968  num_print = NK_MAX(cur_precision, num_len);
6969  while (precision && (num_print > num_len) && (len < buf_size)) {
6970  buf[len++] = '0';
6971  num_print--;
6972  }
6973 
6974  /* copy string value representation into buffer */
6975  num_iter = number_buffer;
6976  while (precision && *num_iter && len < buf_size)
6977  buf[len++] = *num_iter++;
6978 
6979  /* fill right padding up to width characters */
6980  if (flag & NK_ARG_FLAG_LEFT) {
6981  while ((padding-- > 0) && (len < buf_size))
6982  buf[len++] = ' ';
6983  }
6984  } else if (*iter == 'o' || *iter == 'x' || *iter == 'X' || *iter == 'u') {
6985  /* unsigned integer */
6986  unsigned long value = 0;
6987  int num_len = 0, num_print, padding = 0;
6988  int cur_precision = NK_MAX(precision, 1);
6989  int cur_width = NK_MAX(width, 0);
6990  unsigned int base = (*iter == 'o') ? 8: (*iter == 'u')? 10: 16;
6991 
6992  /* print oct/hex/dec value */
6993  const char *upper_output_format = "0123456789ABCDEF";
6994  const char *lower_output_format = "0123456789abcdef";
6995  const char *output_format = (*iter == 'x') ?
6996  lower_output_format: upper_output_format;
6997 
6998  /* retrieve correct value type */
6999  if (arg_type == NK_ARG_TYPE_CHAR)
7000  value = (unsigned char)va_arg(args, int);
7001  else if (arg_type == NK_ARG_TYPE_SHORT)
7002  value = (unsigned short)va_arg(args, int);
7003  else if (arg_type == NK_ARG_TYPE_LONG)
7004  value = va_arg(args, unsigned long);
7005  else value = va_arg(args, unsigned int);
7006 
7007  do {
7008  /* convert decimal number into hex/oct number */
7009  int digit = output_format[value % base];
7010  if (num_len < NK_MAX_NUMBER_BUFFER)
7011  number_buffer[num_len++] = (char)digit;
7012  value /= base;
7013  } while (value > 0);
7014 
7015  num_print = NK_MAX(cur_precision, num_len);
7016  padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
7017  if (flag & NK_ARG_FLAG_NUM)
7018  padding = NK_MAX(padding-1, 0);
7019 
7020  /* fill left padding up to a total of `width` characters */
7021  if (!(flag & NK_ARG_FLAG_LEFT)) {
7022  while ((padding-- > 0) && (len < buf_size)) {
7023  if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
7024  buf[len++] = '0';
7025  else buf[len++] = ' ';
7026  }
7027  }
7028 
7029  /* fill up to precision number of digits */
7030  if (num_print && (flag & NK_ARG_FLAG_NUM)) {
7031  if ((*iter == 'o') && (len < buf_size)) {
7032  buf[len++] = '0';
7033  } else if ((*iter == 'x') && ((len+1) < buf_size)) {
7034  buf[len++] = '0';
7035  buf[len++] = 'x';
7036  } else if ((*iter == 'X') && ((len+1) < buf_size)) {
7037  buf[len++] = '0';
7038  buf[len++] = 'X';
7039  }
7040  }
7041  while (precision && (num_print > num_len) && (len < buf_size)) {
7042  buf[len++] = '0';
7043  num_print--;
7044  }
7045 
7046  /* reverse number direction */
7047  while (num_len > 0) {
7048  if (precision && (len < buf_size))
7049  buf[len++] = number_buffer[num_len-1];
7050  num_len--;
7051  }
7052 
7053  /* fill right padding up to width characters */
7054  if (flag & NK_ARG_FLAG_LEFT) {
7055  while ((padding-- > 0) && (len < buf_size))
7056  buf[len++] = ' ';
7057  }
7058  } else if (*iter == 'f') {
7059  /* floating point */
7060  const char *num_iter;
7061  int cur_precision = (precision < 0) ? 6: precision;
7062  int prefix, cur_width = NK_MAX(width, 0);
7063  double value = va_arg(args, double);
7064  int num_len = 0, frac_len = 0, dot = 0;
7065  int padding = 0;
7066 
7067  NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
7068  NK_DTOA(number_buffer, value);
7069  num_len = nk_strlen(number_buffer);
7070 
7071  /* calculate padding */
7072  num_iter = number_buffer;
7073  while (*num_iter && *num_iter != '.')
7074  num_iter++;
7075 
7076  prefix = (*num_iter == '.')?(int)(num_iter - number_buffer)+1:0;
7077  padding = NK_MAX(cur_width - (prefix + NK_MIN(cur_precision, num_len - prefix)) , 0);
7078  if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
7079  padding = NK_MAX(padding-1, 0);
7080 
7081  /* fill left padding up to a total of `width` characters */
7082  if (!(flag & NK_ARG_FLAG_LEFT)) {
7083  while (padding-- > 0 && (len < buf_size)) {
7084  if (flag & NK_ARG_FLAG_ZERO)
7085  buf[len++] = '0';
7086  else buf[len++] = ' ';
7087  }
7088  }
7089 
7090  /* copy string value representation into buffer */
7091  num_iter = number_buffer;
7092  if ((flag & NK_ARG_FLAG_PLUS) && (value >= 0) && (len < buf_size))
7093  buf[len++] = '+';
7094  else if ((flag & NK_ARG_FLAG_SPACE) && (value >= 0) && (len < buf_size))
7095  buf[len++] = ' ';
7096  while (*num_iter) {
7097  if (dot) frac_len++;
7098  if (len < buf_size)
7099  buf[len++] = *num_iter;
7100  if (*num_iter == '.') dot = 1;
7101  if (frac_len >= cur_precision) break;
7102  num_iter++;
7103  }
7104 
7105  /* fill number up to precision */
7106  while (frac_len < cur_precision) {
7107  if (!dot && len < buf_size) {
7108  buf[len++] = '.';
7109  dot = 1;
7110  }
7111  if (len < buf_size)
7112  buf[len++] = '0';
7113  frac_len++;
7114  }
7115 
7116  /* fill right padding up to width characters */
7117  if (flag & NK_ARG_FLAG_LEFT) {
7118  while ((padding-- > 0) && (len < buf_size))
7119  buf[len++] = ' ';
7120  }
7121  } else {
7122  /* Specifier not supported: g,G,e,E,p,z */
7123  NK_ASSERT(0 && "specifier is not supported!");
7124  return result;
7125  }
7126  }
7127  buf[(len >= buf_size)?(buf_size-1):len] = 0;
7128  result = (len >= buf_size)?-1:len;
7129  return result;
7130 }
7131 #endif
7132 NK_LIB int
7133 nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args)
7134 {
7135  int result = -1;
7136  NK_ASSERT(buf);
7137  NK_ASSERT(buf_size);
7138  if (!buf || !buf_size || !fmt) return 0;
7139 #ifdef NK_INCLUDE_STANDARD_IO
7140  result = NK_VSNPRINTF(buf, (nk_size)buf_size, fmt, args);
7141  result = (result >= buf_size) ? -1: result;
7142  buf[buf_size-1] = 0;
7143 #else
7144  result = nk_vsnprintf(buf, buf_size, fmt, args);
7145 #endif
7146  return result;
7147 }
7148 #endif
7149 NK_API nk_hash
7150 nk_murmur_hash(const void * key, int len, nk_hash seed)
7151 {
7152  /* 32-Bit MurmurHash3: https://code.google.com/p/smhasher/wiki/MurmurHash3*/
7153  #define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r)))
7154  union {const nk_uint *i; const nk_byte *b;} conv = {0};
7155  const nk_byte *data = (const nk_byte*)key;
7156  const int nblocks = len/4;
7157  nk_uint h1 = seed;
7158  const nk_uint c1 = 0xcc9e2d51;
7159  const nk_uint c2 = 0x1b873593;
7160  const nk_byte *tail;
7161  const nk_uint *blocks;
7162  nk_uint k1;
7163  int i;
7164 
7165  /* body */
7166  if (!key) return 0;
7167  conv.b = (data + nblocks*4);
7168  blocks = (const nk_uint*)conv.i;
7169  for (i = -nblocks; i; ++i) {
7170  k1 = blocks[i];
7171  k1 *= c1;
7172  k1 = NK_ROTL(k1,15);
7173  k1 *= c2;
7174 
7175  h1 ^= k1;
7176  h1 = NK_ROTL(h1,13);
7177  h1 = h1*5+0xe6546b64;
7178  }
7179 
7180  /* tail */
7181  tail = (const nk_byte*)(data + nblocks*4);
7182  k1 = 0;
7183  switch (len & 3) {
7184  case 3: k1 ^= (nk_uint)(tail[2] << 16); /* fallthrough */
7185  case 2: k1 ^= (nk_uint)(tail[1] << 8u); /* fallthrough */
7186  case 1: k1 ^= tail[0];
7187  k1 *= c1;
7188  k1 = NK_ROTL(k1,15);
7189  k1 *= c2;
7190  h1 ^= k1;
7191  break;
7192  default: break;
7193  }
7194 
7195  /* finalization */
7196  h1 ^= (nk_uint)len;
7197  /* fmix32 */
7198  h1 ^= h1 >> 16;
7199  h1 *= 0x85ebca6b;
7200  h1 ^= h1 >> 13;
7201  h1 *= 0xc2b2ae35;
7202  h1 ^= h1 >> 16;
7203 
7204  #undef NK_ROTL
7205  return h1;
7206 }
7207 #ifdef NK_INCLUDE_STANDARD_IO
7208 NK_LIB char*
7209 nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc)
7210 {
7211  char *buf;
7212  FILE *fd;
7213  long ret;
7214 
7215  NK_ASSERT(path);
7216  NK_ASSERT(siz);
7217  NK_ASSERT(alloc);
7218  if (!path || !siz || !alloc)
7219  return 0;
7220 
7221  fd = fopen(path, "rb");
7222  if (!fd) return 0;
7223  fseek(fd, 0, SEEK_END);
7224  ret = ftell(fd);
7225  if (ret < 0) {
7226  fclose(fd);
7227  return 0;
7228  }
7229  *siz = (nk_size)ret;
7230  fseek(fd, 0, SEEK_SET);
7231  buf = (char*)alloc->alloc(alloc->userdata,0, *siz);
7232  NK_ASSERT(buf);
7233  if (!buf) {
7234  fclose(fd);
7235  return 0;
7236  }
7237  *siz = (nk_size)fread(buf, 1,*siz, fd);
7238  fclose(fd);
7239  return buf;
7240 }
7241 #endif
7242 NK_LIB int
7243 nk_text_clamp(const struct nk_user_font *font, const char *text,
7244  int text_len, float space, int *glyphs, float *text_width,
7245  nk_rune *sep_list, int sep_count)
7246 {
7247  int i = 0;
7248  int glyph_len = 0;
7249  float last_width = 0;
7250  nk_rune unicode = 0;
7251  float width = 0;
7252  int len = 0;
7253  int g = 0;
7254  float s;
7255 
7256  int sep_len = 0;
7257  int sep_g = 0;
7258  float sep_width = 0;
7259  sep_count = NK_MAX(sep_count,0);
7260 
7261  glyph_len = nk_utf_decode(text, &unicode, text_len);
7262  while (glyph_len && (width < space) && (len < text_len)) {
7263  len += glyph_len;
7264  s = font->width(font->userdata, font->height, text, len);
7265  for (i = 0; i < sep_count; ++i) {
7266  if (unicode != sep_list[i]) continue;
7267  sep_width = last_width = width;
7268  sep_g = g+1;
7269  sep_len = len;
7270  break;
7271  }
7272  if (i == sep_count){
7273  last_width = sep_width = width;
7274  sep_g = g+1;
7275  }
7276  width = s;
7277  glyph_len = nk_utf_decode(&text[len], &unicode, text_len - len);
7278  g++;
7279  }
7280  if (len >= text_len) {
7281  *glyphs = g;
7282  *text_width = last_width;
7283  return len;
7284  } else {
7285  *glyphs = sep_g;
7286  *text_width = sep_width;
7287  return (!sep_len) ? len: sep_len;
7288  }
7289 }
7290 NK_LIB struct nk_vec2
7291 nk_text_calculate_text_bounds(const struct nk_user_font *font,
7292  const char *begin, int byte_len, float row_height, const char **remaining,
7293  struct nk_vec2 *out_offset, int *glyphs, int op)
7294 {
7295  float line_height = row_height;
7296  struct nk_vec2 text_size = nk_vec2(0,0);
7297  float line_width = 0.0f;
7298 
7299  float glyph_width;
7300  int glyph_len = 0;
7301  nk_rune unicode = 0;
7302  int text_len = 0;
7303  if (!begin || byte_len <= 0 || !font)
7304  return nk_vec2(0,row_height);
7305 
7306  glyph_len = nk_utf_decode(begin, &unicode, byte_len);
7307  if (!glyph_len) return text_size;
7308  glyph_width = font->width(font->userdata, font->height, begin, glyph_len);
7309 
7310  *glyphs = 0;
7311  while ((text_len < byte_len) && glyph_len) {
7312  if (unicode == '\n') {
7313  text_size.x = NK_MAX(text_size.x, line_width);
7314  text_size.y += line_height;
7315  line_width = 0;
7316  *glyphs+=1;
7317  if (op == NK_STOP_ON_NEW_LINE)
7318  break;
7319 
7320  text_len++;
7321  glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7322  continue;
7323  }
7324 
7325  if (unicode == '\r') {
7326  text_len++;
7327  *glyphs+=1;
7328  glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7329  continue;
7330  }
7331 
7332  *glyphs = *glyphs + 1;
7333  text_len += glyph_len;
7334  line_width += (float)glyph_width;
7335  glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
7336  glyph_width = font->width(font->userdata, font->height, begin+text_len, glyph_len);
7337  continue;
7338  }
7339 
7340  if (text_size.x < line_width)
7341  text_size.x = line_width;
7342  if (out_offset)
7343  *out_offset = nk_vec2(line_width, text_size.y + line_height);
7344  if (line_width > 0 || text_size.y == 0.0f)
7345  text_size.y += line_height;
7346  if (remaining)
7347  *remaining = begin+text_len;
7348  return text_size;
7349 }
7350 
7351 
7352 
7353 
7354 
7355 /* ==============================================================
7356  *
7357  * COLOR
7358  *
7359  * ===============================================================*/
7360 NK_INTERN int
7361 nk_parse_hex(const char *p, int length)
7362 {
7363  int i = 0;
7364  int len = 0;
7365  while (len < length) {
7366  i <<= 4;
7367  if (p[len] >= 'a' && p[len] <= 'f')
7368  i += ((p[len] - 'a') + 10);
7369  else if (p[len] >= 'A' && p[len] <= 'F')
7370  i += ((p[len] - 'A') + 10);
7371  else i += (p[len] - '0');
7372  len++;
7373  }
7374  return i;
7375 }
7376 NK_API struct nk_color
7377 nk_rgba(int r, int g, int b, int a)
7378 {
7379  struct nk_color ret;
7380  ret.r = (nk_byte)NK_CLAMP(0, r, 255);
7381  ret.g = (nk_byte)NK_CLAMP(0, g, 255);
7382  ret.b = (nk_byte)NK_CLAMP(0, b, 255);
7383  ret.a = (nk_byte)NK_CLAMP(0, a, 255);
7384  return ret;
7385 }
7386 NK_API struct nk_color
7387 nk_rgb_hex(const char *rgb)
7388 {
7389  struct nk_color col;
7390  const char *c = rgb;
7391  if (*c == '#') c++;
7392  col.r = (nk_byte)nk_parse_hex(c, 2);
7393  col.g = (nk_byte)nk_parse_hex(c+2, 2);
7394  col.b = (nk_byte)nk_parse_hex(c+4, 2);
7395  col.a = 255;
7396  return col;
7397 }
7398 NK_API struct nk_color
7399 nk_rgba_hex(const char *rgb)
7400 {
7401  struct nk_color col;
7402  const char *c = rgb;
7403  if (*c == '#') c++;
7404  col.r = (nk_byte)nk_parse_hex(c, 2);
7405  col.g = (nk_byte)nk_parse_hex(c+2, 2);
7406  col.b = (nk_byte)nk_parse_hex(c+4, 2);
7407  col.a = (nk_byte)nk_parse_hex(c+6, 2);
7408  return col;
7409 }
7410 NK_API void
7411 nk_color_hex_rgba(char *output, struct nk_color col)
7412 {
7413  #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
7414  output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
7415  output[1] = (char)NK_TO_HEX((col.r & 0x0F));
7416  output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
7417  output[3] = (char)NK_TO_HEX((col.g & 0x0F));
7418  output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
7419  output[5] = (char)NK_TO_HEX((col.b & 0x0F));
7420  output[6] = (char)NK_TO_HEX((col.a & 0xF0) >> 4);
7421  output[7] = (char)NK_TO_HEX((col.a & 0x0F));
7422  output[8] = '\0';
7423  #undef NK_TO_HEX
7424 }
7425 NK_API void
7426 nk_color_hex_rgb(char *output, struct nk_color col)
7427 {
7428  #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
7429  output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
7430  output[1] = (char)NK_TO_HEX((col.r & 0x0F));
7431  output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
7432  output[3] = (char)NK_TO_HEX((col.g & 0x0F));
7433  output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
7434  output[5] = (char)NK_TO_HEX((col.b & 0x0F));
7435  output[6] = '\0';
7436  #undef NK_TO_HEX
7437 }
7438 NK_API struct nk_color
7439 nk_rgba_iv(const int *c)
7440 {
7441  return nk_rgba(c[0], c[1], c[2], c[3]);
7442 }
7443 NK_API struct nk_color
7444 nk_rgba_bv(const nk_byte *c)
7445 {
7446  return nk_rgba(c[0], c[1], c[2], c[3]);
7447 }
7448 NK_API struct nk_color
7449 nk_rgb(int r, int g, int b)
7450 {
7451  struct nk_color ret;
7452  ret.r = (nk_byte)NK_CLAMP(0, r, 255);
7453  ret.g = (nk_byte)NK_CLAMP(0, g, 255);
7454  ret.b = (nk_byte)NK_CLAMP(0, b, 255);
7455  ret.a = (nk_byte)255;
7456  return ret;
7457 }
7458 NK_API struct nk_color
7459 nk_rgb_iv(const int *c)
7460 {
7461  return nk_rgb(c[0], c[1], c[2]);
7462 }
7463 NK_API struct nk_color
7464 nk_rgb_bv(const nk_byte* c)
7465 {
7466  return nk_rgb(c[0], c[1], c[2]);
7467 }
7468 NK_API struct nk_color
7469 nk_rgba_u32(nk_uint in)
7470 {
7471  struct nk_color ret;
7472  ret.r = (in & 0xFF);
7473  ret.g = ((in >> 8) & 0xFF);
7474  ret.b = ((in >> 16) & 0xFF);
7475  ret.a = (nk_byte)((in >> 24) & 0xFF);
7476  return ret;
7477 }
7478 NK_API struct nk_color
7479 nk_rgba_f(float r, float g, float b, float a)
7480 {
7481  struct nk_color ret;
7482  ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
7483  ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
7484  ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
7485  ret.a = (nk_byte)(NK_SATURATE(a) * 255.0f);
7486  return ret;
7487 }
7488 NK_API struct nk_color
7489 nk_rgba_fv(const float *c)
7490 {
7491  return nk_rgba_f(c[0], c[1], c[2], c[3]);
7492 }
7493 NK_API struct nk_color
7494 nk_rgba_cf(struct nk_colorf c)
7495 {
7496  return nk_rgba_f(c.r, c.g, c.b, c.a);
7497 }
7498 NK_API struct nk_color
7499 nk_rgb_f(float r, float g, float b)
7500 {
7501  struct nk_color ret;
7502  ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
7503  ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
7504  ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
7505  ret.a = 255;
7506  return ret;
7507 }
7508 NK_API struct nk_color
7509 nk_rgb_fv(const float *c)
7510 {
7511  return nk_rgb_f(c[0], c[1], c[2]);
7512 }
7513 NK_API struct nk_color
7514 nk_rgb_cf(struct nk_colorf c)
7515 {
7516  return nk_rgb_f(c.r, c.g, c.b);
7517 }
7518 NK_API struct nk_color
7519 nk_hsv(int h, int s, int v)
7520 {
7521  return nk_hsva(h, s, v, 255);
7522 }
7523 NK_API struct nk_color
7524 nk_hsv_iv(const int *c)
7525 {
7526  return nk_hsv(c[0], c[1], c[2]);
7527 }
7528 NK_API struct nk_color
7529 nk_hsv_bv(const nk_byte *c)
7530 {
7531  return nk_hsv(c[0], c[1], c[2]);
7532 }
7533 NK_API struct nk_color
7534 nk_hsv_f(float h, float s, float v)
7535 {
7536  return nk_hsva_f(h, s, v, 1.0f);
7537 }
7538 NK_API struct nk_color
7539 nk_hsv_fv(const float *c)
7540 {
7541  return nk_hsv_f(c[0], c[1], c[2]);
7542 }
7543 NK_API struct nk_color
7544 nk_hsva(int h, int s, int v, int a)
7545 {
7546  float hf = ((float)NK_CLAMP(0, h, 255)) / 255.0f;
7547  float sf = ((float)NK_CLAMP(0, s, 255)) / 255.0f;
7548  float vf = ((float)NK_CLAMP(0, v, 255)) / 255.0f;
7549  float af = ((float)NK_CLAMP(0, a, 255)) / 255.0f;
7550  return nk_hsva_f(hf, sf, vf, af);
7551 }
7552 NK_API struct nk_color
7553 nk_hsva_iv(const int *c)
7554 {
7555  return nk_hsva(c[0], c[1], c[2], c[3]);
7556 }
7557 NK_API struct nk_color
7558 nk_hsva_bv(const nk_byte *c)
7559 {
7560  return nk_hsva(c[0], c[1], c[2], c[3]);
7561 }
7562 NK_API struct nk_colorf
7563 nk_hsva_colorf(float h, float s, float v, float a)
7564 {
7565  int i;
7566  float p, q, t, f;
7567  struct nk_colorf out = {0,0,0,0};
7568  if (s <= 0.0f) {
7569  out.r = v; out.g = v; out.b = v; out.a = a;
7570  return out;
7571  }
7572  h = h / (60.0f/360.0f);
7573  i = (int)h;
7574  f = h - (float)i;
7575  p = v * (1.0f - s);
7576  q = v * (1.0f - (s * f));
7577  t = v * (1.0f - s * (1.0f - f));
7578 
7579  switch (i) {
7580  case 0: default: out.r = v; out.g = t; out.b = p; break;
7581  case 1: out.r = q; out.g = v; out.b = p; break;
7582  case 2: out.r = p; out.g = v; out.b = t; break;
7583  case 3: out.r = p; out.g = q; out.b = v; break;
7584  case 4: out.r = t; out.g = p; out.b = v; break;
7585  case 5: out.r = v; out.g = p; out.b = q; break;}
7586  out.a = a;
7587  return out;
7588 }
7589 NK_API struct nk_colorf
7590 nk_hsva_colorfv(float *c)
7591 {
7592  return nk_hsva_colorf(c[0], c[1], c[2], c[3]);
7593 }
7594 NK_API struct nk_color
7595 nk_hsva_f(float h, float s, float v, float a)
7596 {
7597  struct nk_colorf c = nk_hsva_colorf(h, s, v, a);
7598  return nk_rgba_f(c.r, c.g, c.b, c.a);
7599 }
7600 NK_API struct nk_color
7601 nk_hsva_fv(const float *c)
7602 {
7603  return nk_hsva_f(c[0], c[1], c[2], c[3]);
7604 }
7605 NK_API nk_uint
7606 nk_color_u32(struct nk_color in)
7607 {
7608  nk_uint out = (nk_uint)in.r;
7609  out |= ((nk_uint)in.g << 8);
7610  out |= ((nk_uint)in.b << 16);
7611  out |= ((nk_uint)in.a << 24);
7612  return out;
7613 }
7614 NK_API void
7615 nk_color_f(float *r, float *g, float *b, float *a, struct nk_color in)
7616 {
7617  NK_STORAGE const float s = 1.0f/255.0f;
7618  *r = (float)in.r * s;
7619  *g = (float)in.g * s;
7620  *b = (float)in.b * s;
7621  *a = (float)in.a * s;
7622 }
7623 NK_API void
7624 nk_color_fv(float *c, struct nk_color in)
7625 {
7626  nk_color_f(&c[0], &c[1], &c[2], &c[3], in);
7627 }
7628 NK_API struct nk_colorf
7629 nk_color_cf(struct nk_color in)
7630 {
7631  struct nk_colorf o;
7632  nk_color_f(&o.r, &o.g, &o.b, &o.a, in);
7633  return o;
7634 }
7635 NK_API void
7636 nk_color_d(double *r, double *g, double *b, double *a, struct nk_color in)
7637 {
7638  NK_STORAGE const double s = 1.0/255.0;
7639  *r = (double)in.r * s;
7640  *g = (double)in.g * s;
7641  *b = (double)in.b * s;
7642  *a = (double)in.a * s;
7643 }
7644 NK_API void
7645 nk_color_dv(double *c, struct nk_color in)
7646 {
7647  nk_color_d(&c[0], &c[1], &c[2], &c[3], in);
7648 }
7649 NK_API void
7650 nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color in)
7651 {
7652  float a;
7653  nk_color_hsva_f(out_h, out_s, out_v, &a, in);
7654 }
7655 NK_API void
7656 nk_color_hsv_fv(float *out, struct nk_color in)
7657 {
7658  float a;
7659  nk_color_hsva_f(&out[0], &out[1], &out[2], &a, in);
7660 }
7661 NK_API void
7662 nk_colorf_hsva_f(float *out_h, float *out_s,
7663  float *out_v, float *out_a, struct nk_colorf in)
7664 {
7665  float chroma;
7666  float K = 0.0f;
7667  if (in.g < in.b) {
7668  const float t = in.g; in.g = in.b; in.b = t;
7669  K = -1.f;
7670  }
7671  if (in.r < in.g) {
7672  const float t = in.r; in.r = in.g; in.g = t;
7673  K = -2.f/6.0f - K;
7674  }
7675  chroma = in.r - ((in.g < in.b) ? in.g: in.b);
7676  *out_h = NK_ABS(K + (in.g - in.b)/(6.0f * chroma + 1e-20f));
7677  *out_s = chroma / (in.r + 1e-20f);
7678  *out_v = in.r;
7679  *out_a = in.a;
7680 
7681 }
7682 NK_API void
7683 nk_colorf_hsva_fv(float *hsva, struct nk_colorf in)
7684 {
7685  nk_colorf_hsva_f(&hsva[0], &hsva[1], &hsva[2], &hsva[3], in);
7686 }
7687 NK_API void
7688 nk_color_hsva_f(float *out_h, float *out_s,
7689  float *out_v, float *out_a, struct nk_color in)
7690 {
7691  struct nk_colorf col;
7692  nk_color_f(&col.r,&col.g,&col.b,&col.a, in);
7693  nk_colorf_hsva_f(out_h, out_s, out_v, out_a, col);
7694 }
7695 NK_API void
7696 nk_color_hsva_fv(float *out, struct nk_color in)
7697 {
7698  nk_color_hsva_f(&out[0], &out[1], &out[2], &out[3], in);
7699 }
7700 NK_API void
7701 nk_color_hsva_i(int *out_h, int *out_s, int *out_v,
7702  int *out_a, struct nk_color in)
7703 {
7704  float h,s,v,a;
7705  nk_color_hsva_f(&h, &s, &v, &a, in);
7706  *out_h = (nk_byte)(h * 255.0f);
7707  *out_s = (nk_byte)(s * 255.0f);
7708  *out_v = (nk_byte)(v * 255.0f);
7709  *out_a = (nk_byte)(a * 255.0f);
7710 }
7711 NK_API void
7712 nk_color_hsva_iv(int *out, struct nk_color in)
7713 {
7714  nk_color_hsva_i(&out[0], &out[1], &out[2], &out[3], in);
7715 }
7716 NK_API void
7717 nk_color_hsva_bv(nk_byte *out, struct nk_color in)
7718 {
7719  int tmp[4];
7720  nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
7721  out[0] = (nk_byte)tmp[0];
7722  out[1] = (nk_byte)tmp[1];
7723  out[2] = (nk_byte)tmp[2];
7724  out[3] = (nk_byte)tmp[3];
7725 }
7726 NK_API void
7727 nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color in)
7728 {
7729  int tmp[4];
7730  nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
7731  *h = (nk_byte)tmp[0];
7732  *s = (nk_byte)tmp[1];
7733  *v = (nk_byte)tmp[2];
7734  *a = (nk_byte)tmp[3];
7735 }
7736 NK_API void
7737 nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color in)
7738 {
7739  int a;
7740  nk_color_hsva_i(out_h, out_s, out_v, &a, in);
7741 }
7742 NK_API void
7743 nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color in)
7744 {
7745  int tmp[4];
7746  nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
7747  *out_h = (nk_byte)tmp[0];
7748  *out_s = (nk_byte)tmp[1];
7749  *out_v = (nk_byte)tmp[2];
7750 }
7751 NK_API void
7752 nk_color_hsv_iv(int *out, struct nk_color in)
7753 {
7754  nk_color_hsv_i(&out[0], &out[1], &out[2], in);
7755 }
7756 NK_API void
7757 nk_color_hsv_bv(nk_byte *out, struct nk_color in)
7758 {
7759  int tmp[4];
7760  nk_color_hsv_i(&tmp[0], &tmp[1], &tmp[2], in);
7761  out[0] = (nk_byte)tmp[0];
7762  out[1] = (nk_byte)tmp[1];
7763  out[2] = (nk_byte)tmp[2];
7764 }
7765 
7766 
7767 
7768 
7769 
7770 /* ===============================================================
7771  *
7772  * UTF-8
7773  *
7774  * ===============================================================*/
7775 NK_GLOBAL const nk_byte nk_utfbyte[NK_UTF_SIZE+1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
7776 NK_GLOBAL const nk_byte nk_utfmask[NK_UTF_SIZE+1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
7777 NK_GLOBAL const nk_uint nk_utfmin[NK_UTF_SIZE+1] = {0, 0, 0x80, 0x800, 0x10000};
7778 NK_GLOBAL const nk_uint nk_utfmax[NK_UTF_SIZE+1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
7779 
7780 NK_INTERN int
7781 nk_utf_validate(nk_rune *u, int i)
7782 {
7783  NK_ASSERT(u);
7784  if (!u) return 0;
7785  if (!NK_BETWEEN(*u, nk_utfmin[i], nk_utfmax[i]) ||
7786  NK_BETWEEN(*u, 0xD800, 0xDFFF))
7787  *u = NK_UTF_INVALID;
7788  for (i = 1; *u > nk_utfmax[i]; ++i);
7789  return i;
7790 }
7791 NK_INTERN nk_rune
7792 nk_utf_decode_byte(char c, int *i)
7793 {
7794  NK_ASSERT(i);
7795  if (!i) return 0;
7796  for(*i = 0; *i < (int)NK_LEN(nk_utfmask); ++(*i)) {
7797  if (((nk_byte)c & nk_utfmask[*i]) == nk_utfbyte[*i])
7798  return (nk_byte)(c & ~nk_utfmask[*i]);
7799  }
7800  return 0;
7801 }
7802 NK_API int
7803 nk_utf_decode(const char *c, nk_rune *u, int clen)
7804 {
7805  int i, j, len, type=0;
7806  nk_rune udecoded;
7807 
7808  NK_ASSERT(c);
7809  NK_ASSERT(u);
7810 
7811  if (!c || !u) return 0;
7812  if (!clen) return 0;
7813  *u = NK_UTF_INVALID;
7814 
7815  udecoded = nk_utf_decode_byte(c[0], &len);
7816  if (!NK_BETWEEN(len, 1, NK_UTF_SIZE))
7817  return 1;
7818 
7819  for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
7820  udecoded = (udecoded << 6) | nk_utf_decode_byte(c[i], &type);
7821  if (type != 0)
7822  return j;
7823  }
7824  if (j < len)
7825  return 0;
7826  *u = udecoded;
7827  nk_utf_validate(u, len);
7828  return len;
7829 }
7830 NK_INTERN char
7831 nk_utf_encode_byte(nk_rune u, int i)
7832 {
7833  return (char)((nk_utfbyte[i]) | ((nk_byte)u & ~nk_utfmask[i]));
7834 }
7835 NK_API int
7836 nk_utf_encode(nk_rune u, char *c, int clen)
7837 {
7838  int len, i;
7839  len = nk_utf_validate(&u, 0);
7840  if (clen < len || !len || len > NK_UTF_SIZE)
7841  return 0;
7842 
7843  for (i = len - 1; i != 0; --i) {
7844  c[i] = nk_utf_encode_byte(u, 0);
7845  u >>= 6;
7846  }
7847  c[0] = nk_utf_encode_byte(u, len);
7848  return len;
7849 }
7850 NK_API int
7851 nk_utf_len(const char *str, int len)
7852 {
7853  const char *text;
7854  int glyphs = 0;
7855  int text_len;
7856  int glyph_len;
7857  int src_len = 0;
7858  nk_rune unicode;
7859 
7860  NK_ASSERT(str);
7861  if (!str || !len) return 0;
7862 
7863  text = str;
7864  text_len = len;
7865  glyph_len = nk_utf_decode(text, &unicode, text_len);
7866  while (glyph_len && src_len < len) {
7867  glyphs++;
7868  src_len = src_len + glyph_len;
7869  glyph_len = nk_utf_decode(text + src_len, &unicode, text_len - src_len);
7870  }
7871  return glyphs;
7872 }
7873 NK_API const char*
7874 nk_utf_at(const char *buffer, int length, int index,
7875  nk_rune *unicode, int *len)
7876 {
7877  int i = 0;
7878  int src_len = 0;
7879  int glyph_len = 0;
7880  const char *text;
7881  int text_len;
7882 
7883  NK_ASSERT(buffer);
7884  NK_ASSERT(unicode);
7885  NK_ASSERT(len);
7886 
7887  if (!buffer || !unicode || !len) return 0;
7888  if (index < 0) {
7889  *unicode = NK_UTF_INVALID;
7890  *len = 0;
7891  return 0;
7892  }
7893 
7894  text = buffer;
7895  text_len = length;
7896  glyph_len = nk_utf_decode(text, unicode, text_len);
7897  while (glyph_len) {
7898  if (i == index) {
7899  *len = glyph_len;
7900  break;
7901  }
7902 
7903  i++;
7904  src_len = src_len + glyph_len;
7905  glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
7906  }
7907  if (i != index) return 0;
7908  return buffer + src_len;
7909 }
7910 
7911 
7912 
7913 
7914 
7915 /* ==============================================================
7916  *
7917  * BUFFER
7918  *
7919  * ===============================================================*/
7920 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
7921 NK_LIB void*
7922 nk_malloc(nk_handle unused, void *old,nk_size size)
7923 {
7924  NK_UNUSED(unused);
7925  NK_UNUSED(old);
7926  return malloc(size);
7927 }
7928 NK_LIB void
7929 nk_mfree(nk_handle unused, void *ptr)
7930 {
7931  NK_UNUSED(unused);
7932  free(ptr);
7933 }
7934 NK_API void
7935 nk_buffer_init_default(struct nk_buffer *buffer)
7936 {
7937  struct nk_allocator alloc;
7938  alloc.userdata.ptr = 0;
7939  alloc.alloc = nk_malloc;
7940  alloc.free = nk_mfree;
7941  nk_buffer_init(buffer, &alloc, NK_BUFFER_DEFAULT_INITIAL_SIZE);
7942 }
7943 #endif
7944 
7945 NK_API void
7946 nk_buffer_init(struct nk_buffer *b, const struct nk_allocator *a,
7947  nk_size initial_size)
7948 {
7949  NK_ASSERT(b);
7950  NK_ASSERT(a);
7951  NK_ASSERT(initial_size);
7952  if (!b || !a || !initial_size) return;
7953 
7954  nk_zero(b, sizeof(*b));
7955  b->type = NK_BUFFER_DYNAMIC;
7956  b->memory.ptr = a->alloc(a->userdata,0, initial_size);
7957  b->memory.size = initial_size;
7958  b->size = initial_size;
7959  b->grow_factor = 2.0f;
7960  b->pool = *a;
7961 }
7962 NK_API void
7963 nk_buffer_init_fixed(struct nk_buffer *b, void *m, nk_size size)
7964 {
7965  NK_ASSERT(b);
7966  NK_ASSERT(m);
7967  NK_ASSERT(size);
7968  if (!b || !m || !size) return;
7969 
7970  nk_zero(b, sizeof(*b));
7971  b->type = NK_BUFFER_FIXED;
7972  b->memory.ptr = m;
7973  b->memory.size = size;
7974  b->size = size;
7975 }
7976 NK_LIB void*
7977 nk_buffer_align(void *unaligned,
7978  nk_size align, nk_size *alignment,
7979  enum nk_buffer_allocation_type type)
7980 {
7981  void *memory = 0;
7982  switch (type) {
7983  default:
7984  case NK_BUFFER_MAX:
7985  case NK_BUFFER_FRONT:
7986  if (align) {
7987  memory = NK_ALIGN_PTR(unaligned, align);
7988  *alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
7989  } else {
7990  memory = unaligned;
7991  *alignment = 0;
7992  }
7993  break;
7994  case NK_BUFFER_BACK:
7995  if (align) {
7996  memory = NK_ALIGN_PTR_BACK(unaligned, align);
7997  *alignment = (nk_size)((nk_byte*)unaligned - (nk_byte*)memory);
7998  } else {
7999  memory = unaligned;
8000  *alignment = 0;
8001  }
8002  break;
8003  }
8004  return memory;
8005 }
8006 NK_LIB void*
8007 nk_buffer_realloc(struct nk_buffer *b, nk_size capacity, nk_size *size)
8008 {
8009  void *temp;
8010  nk_size buffer_size;
8011 
8012  NK_ASSERT(b);
8013  NK_ASSERT(size);
8014  if (!b || !size || !b->pool.alloc || !b->pool.free)
8015  return 0;
8016 
8017  buffer_size = b->memory.size;
8018  temp = b->pool.alloc(b->pool.userdata, b->memory.ptr, capacity);
8019  NK_ASSERT(temp);
8020  if (!temp) return 0;
8021 
8022  *size = capacity;
8023  if (temp != b->memory.ptr) {
8024  NK_MEMCPY(temp, b->memory.ptr, buffer_size);
8025  b->pool.free(b->pool.userdata, b->memory.ptr);
8026  }
8027 
8028  if (b->size == buffer_size) {
8029  /* no back buffer so just set correct size */
8030  b->size = capacity;
8031  return temp;
8032  } else {
8033  /* copy back buffer to the end of the new buffer */
8034  void *dst, *src;
8035  nk_size back_size;
8036  back_size = buffer_size - b->size;
8037  dst = nk_ptr_add(void, temp, capacity - back_size);
8038  src = nk_ptr_add(void, temp, b->size);
8039  NK_MEMCPY(dst, src, back_size);
8040  b->size = capacity - back_size;
8041  }
8042  return temp;
8043 }
8044 NK_LIB void*
8045 nk_buffer_alloc(struct nk_buffer *b, enum nk_buffer_allocation_type type,
8046  nk_size size, nk_size align)
8047 {
8048  int full;
8049  nk_size alignment;
8050  void *unaligned;
8051  void *memory;
8052 
8053  NK_ASSERT(b);
8054  NK_ASSERT(size);
8055  if (!b || !size) return 0;
8056  b->needed += size;
8057 
8058  /* calculate total size with needed alignment + size */
8059  if (type == NK_BUFFER_FRONT)
8060  unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated);
8061  else unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size);
8062  memory = nk_buffer_align(unaligned, align, &alignment, type);
8063 
8064  /* check if buffer has enough memory*/
8065  if (type == NK_BUFFER_FRONT)
8066  full = ((b->allocated + size + alignment) > b->size);
8067  else full = ((b->size - NK_MIN(b->size,(size + alignment))) <= b->allocated);
8068 
8069  if (full) {
8070  nk_size capacity;
8071  if (b->type != NK_BUFFER_DYNAMIC)
8072  return 0;
8073  NK_ASSERT(b->pool.alloc && b->pool.free);
8074  if (b->type != NK_BUFFER_DYNAMIC || !b->pool.alloc || !b->pool.free)
8075  return 0;
8076 
8077  /* buffer is full so allocate bigger buffer if dynamic */
8078  capacity = (nk_size)((float)b->memory.size * b->grow_factor);
8079  capacity = NK_MAX(capacity, nk_round_up_pow2((nk_uint)(b->allocated + size)));
8080  b->memory.ptr = nk_buffer_realloc(b, capacity, &b->memory.size);
8081  if (!b->memory.ptr) return 0;
8082 
8083  /* align newly allocated pointer */
8084  if (type == NK_BUFFER_FRONT)
8085  unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated);
8086  else unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size);
8087  memory = nk_buffer_align(unaligned, align, &alignment, type);
8088  }
8089  if (type == NK_BUFFER_FRONT)
8090  b->allocated += size + alignment;
8091  else b->size -= (size + alignment);
8092  b->needed += alignment;
8093  b->calls++;
8094  return memory;
8095 }
8096 NK_API void
8098  const void *memory, nk_size size, nk_size align)
8099 {
8100  void *mem = nk_buffer_alloc(b, type, size, align);
8101  if (!mem) return;
8102  NK_MEMCPY(mem, memory, size);
8103 }
8104 NK_API void
8105 nk_buffer_mark(struct nk_buffer *buffer, enum nk_buffer_allocation_type type)
8106 {
8107  NK_ASSERT(buffer);
8108  if (!buffer) return;
8109  buffer->marker[type].active = nk_true;
8110  if (type == NK_BUFFER_BACK)
8111  buffer->marker[type].offset = buffer->size;
8112  else buffer->marker[type].offset = buffer->allocated;
8113 }
8114 NK_API void
8115 nk_buffer_reset(struct nk_buffer *buffer, enum nk_buffer_allocation_type type)
8116 {
8117  NK_ASSERT(buffer);
8118  if (!buffer) return;
8119  if (type == NK_BUFFER_BACK) {
8120  /* reset back buffer either back to marker or empty */
8121  buffer->needed -= (buffer->memory.size - buffer->marker[type].offset);
8122  if (buffer->marker[type].active)
8123  buffer->size = buffer->marker[type].offset;
8124  else buffer->size = buffer->memory.size;
8125  buffer->marker[type].active = nk_false;
8126  } else {
8127  /* reset front buffer either back to back marker or empty */
8128  buffer->needed -= (buffer->allocated - buffer->marker[type].offset);
8129  if (buffer->marker[type].active)
8130  buffer->allocated = buffer->marker[type].offset;
8131  else buffer->allocated = 0;
8132  buffer->marker[type].active = nk_false;
8133  }
8134 }
8135 NK_API void
8136 nk_buffer_clear(struct nk_buffer *b)
8137 {
8138  NK_ASSERT(b);
8139  if (!b) return;
8140  b->allocated = 0;
8141  b->size = b->memory.size;
8142  b->calls = 0;
8143  b->needed = 0;
8144 }
8145 NK_API void
8146 nk_buffer_free(struct nk_buffer *b)
8147 {
8148  NK_ASSERT(b);
8149  if (!b || !b->memory.ptr) return;
8150  if (b->type == NK_BUFFER_FIXED) return;
8151  if (!b->pool.free) return;
8152  NK_ASSERT(b->pool.free);
8153  b->pool.free(b->pool.userdata, b->memory.ptr);
8154 }
8155 NK_API void
8156 nk_buffer_info(struct nk_memory_status *s, struct nk_buffer *b)
8157 {
8158  NK_ASSERT(b);
8159  NK_ASSERT(s);
8160  if (!s || !b) return;
8161  s->allocated = b->allocated;
8162  s->size = b->memory.size;
8163  s->needed = b->needed;
8164  s->memory = b->memory.ptr;
8165  s->calls = b->calls;
8166 }
8167 NK_API void*
8168 nk_buffer_memory(struct nk_buffer *buffer)
8169 {
8170  NK_ASSERT(buffer);
8171  if (!buffer) return 0;
8172  return buffer->memory.ptr;
8173 }
8174 NK_API const void*
8175 nk_buffer_memory_const(const struct nk_buffer *buffer)
8176 {
8177  NK_ASSERT(buffer);
8178  if (!buffer) return 0;
8179  return buffer->memory.ptr;
8180 }
8181 NK_API nk_size
8182 nk_buffer_total(struct nk_buffer *buffer)
8183 {
8184  NK_ASSERT(buffer);
8185  if (!buffer) return 0;
8186  return buffer->memory.size;
8187 }
8188 
8189 
8190 
8191 
8192 
8193 /* ===============================================================
8194  *
8195  * STRING
8196  *
8197  * ===============================================================*/
8198 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
8199 NK_API void
8200 nk_str_init_default(struct nk_str *str)
8201 {
8202  struct nk_allocator alloc;
8203  alloc.userdata.ptr = 0;
8204  alloc.alloc = nk_malloc;
8205  alloc.free = nk_mfree;
8206  nk_buffer_init(&str->buffer, &alloc, 32);
8207  str->len = 0;
8208 }
8209 #endif
8210 
8211 NK_API void
8212 nk_str_init(struct nk_str *str, const struct nk_allocator *alloc, nk_size size)
8213 {
8214  nk_buffer_init(&str->buffer, alloc, size);
8215  str->len = 0;
8216 }
8217 NK_API void
8218 nk_str_init_fixed(struct nk_str *str, void *memory, nk_size size)
8219 {
8220  nk_buffer_init_fixed(&str->buffer, memory, size);
8221  str->len = 0;
8222 }
8223 NK_API int
8224 nk_str_append_text_char(struct nk_str *s, const char *str, int len)
8225 {
8226  char *mem;
8227  NK_ASSERT(s);
8228  NK_ASSERT(str);
8229  if (!s || !str || !len) return 0;
8230  mem = (char*)nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0);
8231  if (!mem) return 0;
8232  NK_MEMCPY(mem, str, (nk_size)len * sizeof(char));
8233  s->len += nk_utf_len(str, len);
8234  return len;
8235 }
8236 NK_API int
8237 nk_str_append_str_char(struct nk_str *s, const char *str)
8238 {
8239  return nk_str_append_text_char(s, str, nk_strlen(str));
8240 }
8241 NK_API int
8242 nk_str_append_text_utf8(struct nk_str *str, const char *text, int len)
8243 {
8244  int i = 0;
8245  int byte_len = 0;
8246  nk_rune unicode;
8247  if (!str || !text || !len) return 0;
8248  for (i = 0; i < len; ++i)
8249  byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
8250  nk_str_append_text_char(str, text, byte_len);
8251  return len;
8252 }
8253 NK_API int
8254 nk_str_append_str_utf8(struct nk_str *str, const char *text)
8255 {
8256  int runes = 0;
8257  int byte_len = 0;
8258  int num_runes = 0;
8259  int glyph_len = 0;
8260  nk_rune unicode;
8261  if (!str || !text) return 0;
8262 
8263  glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
8264  while (unicode != '\0' && glyph_len) {
8265  glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
8266  byte_len += glyph_len;
8267  num_runes++;
8268  }
8269  nk_str_append_text_char(str, text, byte_len);
8270  return runes;
8271 }
8272 NK_API int
8273 nk_str_append_text_runes(struct nk_str *str, const nk_rune *text, int len)
8274 {
8275  int i = 0;
8276  int byte_len = 0;
8277  nk_glyph glyph;
8278 
8279  NK_ASSERT(str);
8280  if (!str || !text || !len) return 0;
8281  for (i = 0; i < len; ++i) {
8282  byte_len = nk_utf_encode(text[i], glyph, NK_UTF_SIZE);
8283  if (!byte_len) break;
8284  nk_str_append_text_char(str, glyph, byte_len);
8285  }
8286  return len;
8287 }
8288 NK_API int
8289 nk_str_append_str_runes(struct nk_str *str, const nk_rune *runes)
8290 {
8291  int i = 0;
8292  nk_glyph glyph;
8293  int byte_len;
8294  NK_ASSERT(str);
8295  if (!str || !runes) return 0;
8296  while (runes[i] != '\0') {
8297  byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
8298  nk_str_append_text_char(str, glyph, byte_len);
8299  i++;
8300  }
8301  return i;
8302 }
8303 NK_API int
8304 nk_str_insert_at_char(struct nk_str *s, int pos, const char *str, int len)
8305 {
8306  int i;
8307  void *mem;
8308  char *src;
8309  char *dst;
8310 
8311  int copylen;
8312  NK_ASSERT(s);
8313  NK_ASSERT(str);
8314  NK_ASSERT(len >= 0);
8315  if (!s || !str || !len || (nk_size)pos > s->buffer.allocated) return 0;
8316  if ((s->buffer.allocated + (nk_size)len >= s->buffer.memory.size) &&
8317  (s->buffer.type == NK_BUFFER_FIXED)) return 0;
8318 
8319  copylen = (int)s->buffer.allocated - pos;
8320  if (!copylen) {
8321  nk_str_append_text_char(s, str, len);
8322  return 1;
8323  }
8324  mem = nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0);
8325  if (!mem) return 0;
8326 
8327  /* memmove */
8328  NK_ASSERT(((int)pos + (int)len + ((int)copylen - 1)) >= 0);
8329  NK_ASSERT(((int)pos + ((int)copylen - 1)) >= 0);
8330  dst = nk_ptr_add(char, s->buffer.memory.ptr, pos + len + (copylen - 1));
8331  src = nk_ptr_add(char, s->buffer.memory.ptr, pos + (copylen-1));
8332  for (i = 0; i < copylen; ++i) *dst-- = *src--;
8333  mem = nk_ptr_add(void, s->buffer.memory.ptr, pos);
8334  NK_MEMCPY(mem, str, (nk_size)len * sizeof(char));
8335  s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
8336  return 1;
8337 }
8338 NK_API int
8339 nk_str_insert_at_rune(struct nk_str *str, int pos, const char *cstr, int len)
8340 {
8341  int glyph_len;
8342  nk_rune unicode;
8343  const char *begin;
8344  const char *buffer;
8345 
8346  NK_ASSERT(str);
8347  NK_ASSERT(cstr);
8348  NK_ASSERT(len);
8349  if (!str || !cstr || !len) return 0;
8350  begin = nk_str_at_rune(str, pos, &unicode, &glyph_len);
8351  if (!str->len)
8352  return nk_str_append_text_char(str, cstr, len);
8353  buffer = nk_str_get_const(str);
8354  if (!begin) return 0;
8355  return nk_str_insert_at_char(str, (int)(begin - buffer), cstr, len);
8356 }
8357 NK_API int
8358 nk_str_insert_text_char(struct nk_str *str, int pos, const char *text, int len)
8359 {
8360  return nk_str_insert_text_utf8(str, pos, text, len);
8361 }
8362 NK_API int
8363 nk_str_insert_str_char(struct nk_str *str, int pos, const char *text)
8364 {
8365  return nk_str_insert_text_utf8(str, pos, text, nk_strlen(text));
8366 }
8367 NK_API int
8368 nk_str_insert_text_utf8(struct nk_str *str, int pos, const char *text, int len)
8369 {
8370  int i = 0;
8371  int byte_len = 0;
8372  nk_rune unicode;
8373 
8374  NK_ASSERT(str);
8375  NK_ASSERT(text);
8376  if (!str || !text || !len) return 0;
8377  for (i = 0; i < len; ++i)
8378  byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
8379  nk_str_insert_at_rune(str, pos, text, byte_len);
8380  return len;
8381 }
8382 NK_API int
8383 nk_str_insert_str_utf8(struct nk_str *str, int pos, const char *text)
8384 {
8385  int runes = 0;
8386  int byte_len = 0;
8387  int num_runes = 0;
8388  int glyph_len = 0;
8389  nk_rune unicode;
8390  if (!str || !text) return 0;
8391 
8392  glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
8393  while (unicode != '\0' && glyph_len) {
8394  glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
8395  byte_len += glyph_len;
8396  num_runes++;
8397  }
8398  nk_str_insert_at_rune(str, pos, text, byte_len);
8399  return runes;
8400 }
8401 NK_API int
8402 nk_str_insert_text_runes(struct nk_str *str, int pos, const nk_rune *runes, int len)
8403 {
8404  int i = 0;
8405  int byte_len = 0;
8406  nk_glyph glyph;
8407 
8408  NK_ASSERT(str);
8409  if (!str || !runes || !len) return 0;
8410  for (i = 0; i < len; ++i) {
8411  byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
8412  if (!byte_len) break;
8413  nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
8414  }
8415  return len;
8416 }
8417 NK_API int
8418 nk_str_insert_str_runes(struct nk_str *str, int pos, const nk_rune *runes)
8419 {
8420  int i = 0;
8421  nk_glyph glyph;
8422  int byte_len;
8423  NK_ASSERT(str);
8424  if (!str || !runes) return 0;
8425  while (runes[i] != '\0') {
8426  byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
8427  nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
8428  i++;
8429  }
8430  return i;
8431 }
8432 NK_API void
8433 nk_str_remove_chars(struct nk_str *s, int len)
8434 {
8435  NK_ASSERT(s);
8436  NK_ASSERT(len >= 0);
8437  if (!s || len < 0 || (nk_size)len > s->buffer.allocated) return;
8438  NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0);
8439  s->buffer.allocated -= (nk_size)len;
8440  s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
8441 }
8442 NK_API void
8443 nk_str_remove_runes(struct nk_str *str, int len)
8444 {
8445  int index;
8446  const char *begin;
8447  const char *end;
8448  nk_rune unicode;
8449 
8450  NK_ASSERT(str);
8451  NK_ASSERT(len >= 0);
8452  if (!str || len < 0) return;
8453  if (len >= str->len) {
8454  str->len = 0;
8455  return;
8456  }
8457 
8458  index = str->len - len;
8459  begin = nk_str_at_rune(str, index, &unicode, &len);
8460  end = (const char*)str->buffer.memory.ptr + str->buffer.allocated;
8461  nk_str_remove_chars(str, (int)(end-begin)+1);
8462 }
8463 NK_API void
8464 nk_str_delete_chars(struct nk_str *s, int pos, int len)
8465 {
8466  NK_ASSERT(s);
8467  if (!s || !len || (nk_size)pos > s->buffer.allocated ||
8468  (nk_size)(pos + len) > s->buffer.allocated) return;
8469 
8470  if ((nk_size)(pos + len) < s->buffer.allocated) {
8471  /* memmove */
8472  char *dst = nk_ptr_add(char, s->buffer.memory.ptr, pos);
8473  char *src = nk_ptr_add(char, s->buffer.memory.ptr, pos + len);
8474  NK_MEMCPY(dst, src, s->buffer.allocated - (nk_size)(pos + len));
8475  NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0);
8476  s->buffer.allocated -= (nk_size)len;
8477  } else nk_str_remove_chars(s, len);
8478  s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
8479 }
8480 NK_API void
8481 nk_str_delete_runes(struct nk_str *s, int pos, int len)
8482 {
8483  char *temp;
8484  nk_rune unicode;
8485  char *begin;
8486  char *end;
8487  int unused;
8488 
8489  NK_ASSERT(s);
8490  NK_ASSERT(s->len >= pos + len);
8491  if (s->len < pos + len)
8492  len = NK_CLAMP(0, (s->len - pos), s->len);
8493  if (!len) return;
8494 
8495  temp = (char *)s->buffer.memory.ptr;
8496  begin = nk_str_at_rune(s, pos, &unicode, &unused);
8497  if (!begin) return;
8498  s->buffer.memory.ptr = begin;
8499  end = nk_str_at_rune(s, len, &unicode, &unused);
8500  s->buffer.memory.ptr = temp;
8501  if (!end) return;
8502  nk_str_delete_chars(s, (int)(begin - temp), (int)(end - begin));
8503 }
8504 NK_API char*
8505 nk_str_at_char(struct nk_str *s, int pos)
8506 {
8507  NK_ASSERT(s);
8508  if (!s || pos > (int)s->buffer.allocated) return 0;
8509  return nk_ptr_add(char, s->buffer.memory.ptr, pos);
8510 }
8511 NK_API char*
8512 nk_str_at_rune(struct nk_str *str, int pos, nk_rune *unicode, int *len)
8513 {
8514  int i = 0;
8515  int src_len = 0;
8516  int glyph_len = 0;
8517  char *text;
8518  int text_len;
8519 
8520  NK_ASSERT(str);
8521  NK_ASSERT(unicode);
8522  NK_ASSERT(len);
8523 
8524  if (!str || !unicode || !len) return 0;
8525  if (pos < 0) {
8526  *unicode = 0;
8527  *len = 0;
8528  return 0;
8529  }
8530 
8531  text = (char*)str->buffer.memory.ptr;
8532  text_len = (int)str->buffer.allocated;
8533  glyph_len = nk_utf_decode(text, unicode, text_len);
8534  while (glyph_len) {
8535  if (i == pos) {
8536  *len = glyph_len;
8537  break;
8538  }
8539 
8540  i++;
8541  src_len = src_len + glyph_len;
8542  glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
8543  }
8544  if (i != pos) return 0;
8545  return text + src_len;
8546 }
8547 NK_API const char*
8548 nk_str_at_char_const(const struct nk_str *s, int pos)
8549 {
8550  NK_ASSERT(s);
8551  if (!s || pos > (int)s->buffer.allocated) return 0;
8552  return nk_ptr_add(char, s->buffer.memory.ptr, pos);
8553 }
8554 NK_API const char*
8555 nk_str_at_const(const struct nk_str *str, int pos, nk_rune *unicode, int *len)
8556 {
8557  int i = 0;
8558  int src_len = 0;
8559  int glyph_len = 0;
8560  char *text;
8561  int text_len;
8562 
8563  NK_ASSERT(str);
8564  NK_ASSERT(unicode);
8565  NK_ASSERT(len);
8566 
8567  if (!str || !unicode || !len) return 0;
8568  if (pos < 0) {
8569  *unicode = 0;
8570  *len = 0;
8571  return 0;
8572  }
8573 
8574  text = (char*)str->buffer.memory.ptr;
8575  text_len = (int)str->buffer.allocated;
8576  glyph_len = nk_utf_decode(text, unicode, text_len);
8577  while (glyph_len) {
8578  if (i == pos) {
8579  *len = glyph_len;
8580  break;
8581  }
8582 
8583  i++;
8584  src_len = src_len + glyph_len;
8585  glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
8586  }
8587  if (i != pos) return 0;
8588  return text + src_len;
8589 }
8590 NK_API nk_rune
8591 nk_str_rune_at(const struct nk_str *str, int pos)
8592 {
8593  int len;
8594  nk_rune unicode = 0;
8595  nk_str_at_const(str, pos, &unicode, &len);
8596  return unicode;
8597 }
8598 NK_API char*
8599 nk_str_get(struct nk_str *s)
8600 {
8601  NK_ASSERT(s);
8602  if (!s || !s->len || !s->buffer.allocated) return 0;
8603  return (char*)s->buffer.memory.ptr;
8604 }
8605 NK_API const char*
8606 nk_str_get_const(const struct nk_str *s)
8607 {
8608  NK_ASSERT(s);
8609  if (!s || !s->len || !s->buffer.allocated) return 0;
8610  return (const char*)s->buffer.memory.ptr;
8611 }
8612 NK_API int
8613 nk_str_len(struct nk_str *s)
8614 {
8615  NK_ASSERT(s);
8616  if (!s || !s->len || !s->buffer.allocated) return 0;
8617  return s->len;
8618 }
8619 NK_API int
8620 nk_str_len_char(struct nk_str *s)
8621 {
8622  NK_ASSERT(s);
8623  if (!s || !s->len || !s->buffer.allocated) return 0;
8624  return (int)s->buffer.allocated;
8625 }
8626 NK_API void
8627 nk_str_clear(struct nk_str *str)
8628 {
8629  NK_ASSERT(str);
8630  nk_buffer_clear(&str->buffer);
8631  str->len = 0;
8632 }
8633 NK_API void
8634 nk_str_free(struct nk_str *str)
8635 {
8636  NK_ASSERT(str);
8637  nk_buffer_free(&str->buffer);
8638  str->len = 0;
8639 }
8640 
8641 
8642 
8643 
8644 
8645 /* ==============================================================
8646  *
8647  * DRAW
8648  *
8649  * ===============================================================*/
8650 NK_LIB void
8651 nk_command_buffer_init(struct nk_command_buffer *cb,
8652  struct nk_buffer *b, enum nk_command_clipping clip)
8653 {
8654  NK_ASSERT(cb);
8655  NK_ASSERT(b);
8656  if (!cb || !b) return;
8657  cb->base = b;
8658  cb->use_clipping = (int)clip;
8659  cb->begin = b->allocated;
8660  cb->end = b->allocated;
8661  cb->last = b->allocated;
8662 }
8663 NK_LIB void
8664 nk_command_buffer_reset(struct nk_command_buffer *b)
8665 {
8666  NK_ASSERT(b);
8667  if (!b) return;
8668  b->begin = 0;
8669  b->end = 0;
8670  b->last = 0;
8671  b->clip = nk_null_rect;
8672 #ifdef NK_INCLUDE_COMMAND_USERDATA
8673  b->userdata.ptr = 0;
8674 #endif
8675 }
8676 NK_LIB void*
8677 nk_command_buffer_push(struct nk_command_buffer* b,
8678  enum nk_command_type t, nk_size size)
8679 {
8680  NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_command);
8681  struct nk_command *cmd;
8682  nk_size alignment;
8683  void *unaligned;
8684  void *memory;
8685 
8686  NK_ASSERT(b);
8687  NK_ASSERT(b->base);
8688  if (!b) return 0;
8689  cmd = (struct nk_command*)nk_buffer_alloc(b->base,NK_BUFFER_FRONT,size,align);
8690  if (!cmd) return 0;
8691 
8692  /* make sure the offset to the next command is aligned */
8693  b->last = (nk_size)((nk_byte*)cmd - (nk_byte*)b->base->memory.ptr);
8694  unaligned = (nk_byte*)cmd + size;
8695  memory = NK_ALIGN_PTR(unaligned, align);
8696  alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
8697 #ifdef NK_ZERO_COMMAND_MEMORY
8698  NK_MEMSET(cmd, 0, size + alignment);
8699 #endif
8700 
8701  cmd->type = t;
8702  cmd->next = b->base->allocated + alignment;
8703 #ifdef NK_INCLUDE_COMMAND_USERDATA
8704  cmd->userdata = b->userdata;
8705 #endif
8706  b->end = cmd->next;
8707  return cmd;
8708 }
8709 NK_API void
8710 nk_push_scissor(struct nk_command_buffer *b, struct nk_rect r)
8711 {
8712  struct nk_command_scissor *cmd;
8713  NK_ASSERT(b);
8714  if (!b) return;
8715 
8716  b->clip.x = r.x;
8717  b->clip.y = r.y;
8718  b->clip.w = r.w;
8719  b->clip.h = r.h;
8720  cmd = (struct nk_command_scissor*)
8721  nk_command_buffer_push(b, NK_COMMAND_SCISSOR, sizeof(*cmd));
8722 
8723  if (!cmd) return;
8724  cmd->x = (short)r.x;
8725  cmd->y = (short)r.y;
8726  cmd->w = (unsigned short)NK_MAX(0, r.w);
8727  cmd->h = (unsigned short)NK_MAX(0, r.h);
8728 }
8729 NK_API void
8730 nk_stroke_line(struct nk_command_buffer *b, float x0, float y0,
8731  float x1, float y1, float line_thickness, struct nk_color c)
8732 {
8733  struct nk_command_line *cmd;
8734  NK_ASSERT(b);
8735  if (!b || line_thickness <= 0) return;
8736  cmd = (struct nk_command_line*)
8737  nk_command_buffer_push(b, NK_COMMAND_LINE, sizeof(*cmd));
8738  if (!cmd) return;
8739  cmd->line_thickness = (unsigned short)line_thickness;
8740  cmd->begin.x = (short)x0;
8741  cmd->begin.y = (short)y0;
8742  cmd->end.x = (short)x1;
8743  cmd->end.y = (short)y1;
8744  cmd->color = c;
8745 }
8746 NK_API void
8747 nk_stroke_curve(struct nk_command_buffer *b, float ax, float ay,
8748  float ctrl0x, float ctrl0y, float ctrl1x, float ctrl1y,
8749  float bx, float by, float line_thickness, struct nk_color col)
8750 {
8751  struct nk_command_curve *cmd;
8752  NK_ASSERT(b);
8753  if (!b || col.a == 0 || line_thickness <= 0) return;
8754 
8755  cmd = (struct nk_command_curve*)
8756  nk_command_buffer_push(b, NK_COMMAND_CURVE, sizeof(*cmd));
8757  if (!cmd) return;
8758  cmd->line_thickness = (unsigned short)line_thickness;
8759  cmd->begin.x = (short)ax;
8760  cmd->begin.y = (short)ay;
8761  cmd->ctrl[0].x = (short)ctrl0x;
8762  cmd->ctrl[0].y = (short)ctrl0y;
8763  cmd->ctrl[1].x = (short)ctrl1x;
8764  cmd->ctrl[1].y = (short)ctrl1y;
8765  cmd->end.x = (short)bx;
8766  cmd->end.y = (short)by;
8767  cmd->color = col;
8768 }
8769 NK_API void
8770 nk_stroke_rect(struct nk_command_buffer *b, struct nk_rect rect,
8771  float rounding, float line_thickness, struct nk_color c)
8772 {
8773  struct nk_command_rect *cmd;
8774  NK_ASSERT(b);
8775  if (!b || c.a == 0 || rect.w == 0 || rect.h == 0 || line_thickness <= 0) return;
8776  if (b->use_clipping) {
8777  const struct nk_rect *clip = &b->clip;
8778  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
8779  clip->x, clip->y, clip->w, clip->h)) return;
8780  }
8781  cmd = (struct nk_command_rect*)
8782  nk_command_buffer_push(b, NK_COMMAND_RECT, sizeof(*cmd));
8783  if (!cmd) return;
8784  cmd->rounding = (unsigned short)rounding;
8785  cmd->line_thickness = (unsigned short)line_thickness;
8786  cmd->x = (short)rect.x;
8787  cmd->y = (short)rect.y;
8788  cmd->w = (unsigned short)NK_MAX(0, rect.w);
8789  cmd->h = (unsigned short)NK_MAX(0, rect.h);
8790  cmd->color = c;
8791 }
8792 NK_API void
8793 nk_fill_rect(struct nk_command_buffer *b, struct nk_rect rect,
8794  float rounding, struct nk_color c)
8795 {
8796  struct nk_command_rect_filled *cmd;
8797  NK_ASSERT(b);
8798  if (!b || c.a == 0 || rect.w == 0 || rect.h == 0) return;
8799  if (b->use_clipping) {
8800  const struct nk_rect *clip = &b->clip;
8801  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
8802  clip->x, clip->y, clip->w, clip->h)) return;
8803  }
8804 
8805  cmd = (struct nk_command_rect_filled*)
8806  nk_command_buffer_push(b, NK_COMMAND_RECT_FILLED, sizeof(*cmd));
8807  if (!cmd) return;
8808  cmd->rounding = (unsigned short)rounding;
8809  cmd->x = (short)rect.x;
8810  cmd->y = (short)rect.y;
8811  cmd->w = (unsigned short)NK_MAX(0, rect.w);
8812  cmd->h = (unsigned short)NK_MAX(0, rect.h);
8813  cmd->color = c;
8814 }
8815 NK_API void
8816 nk_fill_rect_multi_color(struct nk_command_buffer *b, struct nk_rect rect,
8817  struct nk_color left, struct nk_color top, struct nk_color right,
8818  struct nk_color bottom)
8819 {
8821  NK_ASSERT(b);
8822  if (!b || rect.w == 0 || rect.h == 0) return;
8823  if (b->use_clipping) {
8824  const struct nk_rect *clip = &b->clip;
8825  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
8826  clip->x, clip->y, clip->w, clip->h)) return;
8827  }
8828 
8829  cmd = (struct nk_command_rect_multi_color*)
8830  nk_command_buffer_push(b, NK_COMMAND_RECT_MULTI_COLOR, sizeof(*cmd));
8831  if (!cmd) return;
8832  cmd->x = (short)rect.x;
8833  cmd->y = (short)rect.y;
8834  cmd->w = (unsigned short)NK_MAX(0, rect.w);
8835  cmd->h = (unsigned short)NK_MAX(0, rect.h);
8836  cmd->left = left;
8837  cmd->top = top;
8838  cmd->right = right;
8839  cmd->bottom = bottom;
8840 }
8841 NK_API void
8842 nk_stroke_circle(struct nk_command_buffer *b, struct nk_rect r,
8843  float line_thickness, struct nk_color c)
8844 {
8845  struct nk_command_circle *cmd;
8846  if (!b || r.w == 0 || r.h == 0 || line_thickness <= 0) return;
8847  if (b->use_clipping) {
8848  const struct nk_rect *clip = &b->clip;
8849  if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
8850  return;
8851  }
8852 
8853  cmd = (struct nk_command_circle*)
8854  nk_command_buffer_push(b, NK_COMMAND_CIRCLE, sizeof(*cmd));
8855  if (!cmd) return;
8856  cmd->line_thickness = (unsigned short)line_thickness;
8857  cmd->x = (short)r.x;
8858  cmd->y = (short)r.y;
8859  cmd->w = (unsigned short)NK_MAX(r.w, 0);
8860  cmd->h = (unsigned short)NK_MAX(r.h, 0);
8861  cmd->color = c;
8862 }
8863 NK_API void
8864 nk_fill_circle(struct nk_command_buffer *b, struct nk_rect r, struct nk_color c)
8865 {
8866  struct nk_command_circle_filled *cmd;
8867  NK_ASSERT(b);
8868  if (!b || c.a == 0 || r.w == 0 || r.h == 0) return;
8869  if (b->use_clipping) {
8870  const struct nk_rect *clip = &b->clip;
8871  if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
8872  return;
8873  }
8874 
8875  cmd = (struct nk_command_circle_filled*)
8876  nk_command_buffer_push(b, NK_COMMAND_CIRCLE_FILLED, sizeof(*cmd));
8877  if (!cmd) return;
8878  cmd->x = (short)r.x;
8879  cmd->y = (short)r.y;
8880  cmd->w = (unsigned short)NK_MAX(r.w, 0);
8881  cmd->h = (unsigned short)NK_MAX(r.h, 0);
8882  cmd->color = c;
8883 }
8884 NK_API void
8885 nk_stroke_arc(struct nk_command_buffer *b, float cx, float cy, float radius,
8886  float a_min, float a_max, float line_thickness, struct nk_color c)
8887 {
8888  struct nk_command_arc *cmd;
8889  if (!b || c.a == 0 || line_thickness <= 0) return;
8890  cmd = (struct nk_command_arc*)
8891  nk_command_buffer_push(b, NK_COMMAND_ARC, sizeof(*cmd));
8892  if (!cmd) return;
8893  cmd->line_thickness = (unsigned short)line_thickness;
8894  cmd->cx = (short)cx;
8895  cmd->cy = (short)cy;
8896  cmd->r = (unsigned short)radius;
8897  cmd->a[0] = a_min;
8898  cmd->a[1] = a_max;
8899  cmd->color = c;
8900 }
8901 NK_API void
8902 nk_fill_arc(struct nk_command_buffer *b, float cx, float cy, float radius,
8903  float a_min, float a_max, struct nk_color c)
8904 {
8905  struct nk_command_arc_filled *cmd;
8906  NK_ASSERT(b);
8907  if (!b || c.a == 0) return;
8908  cmd = (struct nk_command_arc_filled*)
8909  nk_command_buffer_push(b, NK_COMMAND_ARC_FILLED, sizeof(*cmd));
8910  if (!cmd) return;
8911  cmd->cx = (short)cx;
8912  cmd->cy = (short)cy;
8913  cmd->r = (unsigned short)radius;
8914  cmd->a[0] = a_min;
8915  cmd->a[1] = a_max;
8916  cmd->color = c;
8917 }
8918 NK_API void
8919 nk_stroke_triangle(struct nk_command_buffer *b, float x0, float y0, float x1,
8920  float y1, float x2, float y2, float line_thickness, struct nk_color c)
8921 {
8922  struct nk_command_triangle *cmd;
8923  NK_ASSERT(b);
8924  if (!b || c.a == 0 || line_thickness <= 0) return;
8925  if (b->use_clipping) {
8926  const struct nk_rect *clip = &b->clip;
8927  if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
8928  !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
8929  !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
8930  return;
8931  }
8932 
8933  cmd = (struct nk_command_triangle*)
8934  nk_command_buffer_push(b, NK_COMMAND_TRIANGLE, sizeof(*cmd));
8935  if (!cmd) return;
8936  cmd->line_thickness = (unsigned short)line_thickness;
8937  cmd->a.x = (short)x0;
8938  cmd->a.y = (short)y0;
8939  cmd->b.x = (short)x1;
8940  cmd->b.y = (short)y1;
8941  cmd->c.x = (short)x2;
8942  cmd->c.y = (short)y2;
8943  cmd->color = c;
8944 }
8945 NK_API void
8946 nk_fill_triangle(struct nk_command_buffer *b, float x0, float y0, float x1,
8947  float y1, float x2, float y2, struct nk_color c)
8948 {
8950  NK_ASSERT(b);
8951  if (!b || c.a == 0) return;
8952  if (!b) return;
8953  if (b->use_clipping) {
8954  const struct nk_rect *clip = &b->clip;
8955  if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
8956  !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
8957  !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
8958  return;
8959  }
8960 
8961  cmd = (struct nk_command_triangle_filled*)
8962  nk_command_buffer_push(b, NK_COMMAND_TRIANGLE_FILLED, sizeof(*cmd));
8963  if (!cmd) return;
8964  cmd->a.x = (short)x0;
8965  cmd->a.y = (short)y0;
8966  cmd->b.x = (short)x1;
8967  cmd->b.y = (short)y1;
8968  cmd->c.x = (short)x2;
8969  cmd->c.y = (short)y2;
8970  cmd->color = c;
8971 }
8972 NK_API void
8973 nk_stroke_polygon(struct nk_command_buffer *b, float *points, int point_count,
8974  float line_thickness, struct nk_color col)
8975 {
8976  int i;
8977  nk_size size = 0;
8978  struct nk_command_polygon *cmd;
8979 
8980  NK_ASSERT(b);
8981  if (!b || col.a == 0 || line_thickness <= 0) return;
8982  size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
8983  cmd = (struct nk_command_polygon*) nk_command_buffer_push(b, NK_COMMAND_POLYGON, size);
8984  if (!cmd) return;
8985  cmd->color = col;
8986  cmd->line_thickness = (unsigned short)line_thickness;
8987  cmd->point_count = (unsigned short)point_count;
8988  for (i = 0; i < point_count; ++i) {
8989  cmd->points[i].x = (short)points[i*2];
8990  cmd->points[i].y = (short)points[i*2+1];
8991  }
8992 }
8993 NK_API void
8994 nk_fill_polygon(struct nk_command_buffer *b, float *points, int point_count,
8995  struct nk_color col)
8996 {
8997  int i;
8998  nk_size size = 0;
9000 
9001  NK_ASSERT(b);
9002  if (!b || col.a == 0) return;
9003  size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
9004  cmd = (struct nk_command_polygon_filled*)
9005  nk_command_buffer_push(b, NK_COMMAND_POLYGON_FILLED, size);
9006  if (!cmd) return;
9007  cmd->color = col;
9008  cmd->point_count = (unsigned short)point_count;
9009  for (i = 0; i < point_count; ++i) {
9010  cmd->points[i].x = (short)points[i*2+0];
9011  cmd->points[i].y = (short)points[i*2+1];
9012  }
9013 }
9014 NK_API void
9015 nk_stroke_polyline(struct nk_command_buffer *b, float *points, int point_count,
9016  float line_thickness, struct nk_color col)
9017 {
9018  int i;
9019  nk_size size = 0;
9020  struct nk_command_polyline *cmd;
9021 
9022  NK_ASSERT(b);
9023  if (!b || col.a == 0 || line_thickness <= 0) return;
9024  size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
9025  cmd = (struct nk_command_polyline*) nk_command_buffer_push(b, NK_COMMAND_POLYLINE, size);
9026  if (!cmd) return;
9027  cmd->color = col;
9028  cmd->point_count = (unsigned short)point_count;
9029  cmd->line_thickness = (unsigned short)line_thickness;
9030  for (i = 0; i < point_count; ++i) {
9031  cmd->points[i].x = (short)points[i*2];
9032  cmd->points[i].y = (short)points[i*2+1];
9033  }
9034 }
9035 NK_API void
9036 nk_draw_image(struct nk_command_buffer *b, struct nk_rect r,
9037  const struct nk_image *img, struct nk_color col)
9038 {
9039  struct nk_command_image *cmd;
9040  NK_ASSERT(b);
9041  if (!b) return;
9042  if (b->use_clipping) {
9043  const struct nk_rect *c = &b->clip;
9044  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))
9045  return;
9046  }
9047 
9048  cmd = (struct nk_command_image*)
9049  nk_command_buffer_push(b, NK_COMMAND_IMAGE, sizeof(*cmd));
9050  if (!cmd) return;
9051  cmd->x = (short)r.x;
9052  cmd->y = (short)r.y;
9053  cmd->w = (unsigned short)NK_MAX(0, r.w);
9054  cmd->h = (unsigned short)NK_MAX(0, r.h);
9055  cmd->img = *img;
9056  cmd->col = col;
9057 }
9058 NK_API void
9059 nk_push_custom(struct nk_command_buffer *b, struct nk_rect r,
9060  nk_command_custom_callback cb, nk_handle usr)
9061 {
9062  struct nk_command_custom *cmd;
9063  NK_ASSERT(b);
9064  if (!b) return;
9065  if (b->use_clipping) {
9066  const struct nk_rect *c = &b->clip;
9067  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))
9068  return;
9069  }
9070 
9071  cmd = (struct nk_command_custom*)
9072  nk_command_buffer_push(b, NK_COMMAND_CUSTOM, sizeof(*cmd));
9073  if (!cmd) return;
9074  cmd->x = (short)r.x;
9075  cmd->y = (short)r.y;
9076  cmd->w = (unsigned short)NK_MAX(0, r.w);
9077  cmd->h = (unsigned short)NK_MAX(0, r.h);
9078  cmd->callback_data = usr;
9079  cmd->callback = cb;
9080 }
9081 NK_API void
9082 nk_draw_text(struct nk_command_buffer *b, struct nk_rect r,
9083  const char *string, int length, const struct nk_user_font *font,
9084  struct nk_color bg, struct nk_color fg)
9085 {
9086  float text_width = 0;
9087  struct nk_command_text *cmd;
9088 
9089  NK_ASSERT(b);
9090  NK_ASSERT(font);
9091  if (!b || !string || !length || (bg.a == 0 && fg.a == 0)) return;
9092  if (b->use_clipping) {
9093  const struct nk_rect *c = &b->clip;
9094  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))
9095  return;
9096  }
9097 
9098  /* make sure text fits inside bounds */
9099  text_width = font->width(font->userdata, font->height, string, length);
9100  if (text_width > r.w){
9101  int glyphs = 0;
9102  float txt_width = (float)text_width;
9103  length = nk_text_clamp(font, string, length, r.w, &glyphs, &txt_width, 0,0);
9104  }
9105 
9106  if (!length) return;
9107  cmd = (struct nk_command_text*)
9108  nk_command_buffer_push(b, NK_COMMAND_TEXT, sizeof(*cmd) + (nk_size)(length + 1));
9109  if (!cmd) return;
9110  cmd->x = (short)r.x;
9111  cmd->y = (short)r.y;
9112  cmd->w = (unsigned short)r.w;
9113  cmd->h = (unsigned short)r.h;
9114  cmd->background = bg;
9115  cmd->foreground = fg;
9116  cmd->font = font;
9117  cmd->length = length;
9118  cmd->height = font->height;
9119  NK_MEMCPY(cmd->string, string, (nk_size)length);
9120  cmd->string[length] = '\0';
9121 }
9122 
9123 
9124 
9125 
9126 
9127 /* ===============================================================
9128  *
9129  * VERTEX
9130  *
9131  * ===============================================================*/
9132 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
9133 NK_API void
9134 nk_draw_list_init(struct nk_draw_list *list)
9135 {
9136  nk_size i = 0;
9137  NK_ASSERT(list);
9138  if (!list) return;
9139  nk_zero(list, sizeof(*list));
9140  for (i = 0; i < NK_LEN(list->circle_vtx); ++i) {
9141  const float a = ((float)i / (float)NK_LEN(list->circle_vtx)) * 2 * NK_PI;
9142  list->circle_vtx[i].x = (float)NK_COS(a);
9143  list->circle_vtx[i].y = (float)NK_SIN(a);
9144  }
9145 }
9146 NK_API void
9147 nk_draw_list_setup(struct nk_draw_list *canvas, const struct nk_convert_config *config,
9148  struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements,
9149  enum nk_anti_aliasing line_aa, enum nk_anti_aliasing shape_aa)
9150 {
9151  NK_ASSERT(canvas);
9152  NK_ASSERT(config);
9153  NK_ASSERT(cmds);
9154  NK_ASSERT(vertices);
9155  NK_ASSERT(elements);
9156  if (!canvas || !config || !cmds || !vertices || !elements)
9157  return;
9158 
9159  canvas->buffer = cmds;
9160  canvas->config = *config;
9161  canvas->elements = elements;
9162  canvas->vertices = vertices;
9163  canvas->line_AA = line_aa;
9164  canvas->shape_AA = shape_aa;
9165  canvas->clip_rect = nk_null_rect;
9166 
9167  canvas->cmd_offset = 0;
9168  canvas->element_count = 0;
9169  canvas->vertex_count = 0;
9170  canvas->cmd_offset = 0;
9171  canvas->cmd_count = 0;
9172  canvas->path_count = 0;
9173 }
9174 NK_API const struct nk_draw_command*
9175 nk__draw_list_begin(const struct nk_draw_list *canvas, const struct nk_buffer *buffer)
9176 {
9177  nk_byte *memory;
9178  nk_size offset;
9179  const struct nk_draw_command *cmd;
9180 
9181  NK_ASSERT(buffer);
9182  if (!buffer || !buffer->size || !canvas->cmd_count)
9183  return 0;
9184 
9185  memory = (nk_byte*)buffer->memory.ptr;
9186  offset = buffer->memory.size - canvas->cmd_offset;
9187  cmd = nk_ptr_add(const struct nk_draw_command, memory, offset);
9188  return cmd;
9189 }
9190 NK_API const struct nk_draw_command*
9191 nk__draw_list_end(const struct nk_draw_list *canvas, const struct nk_buffer *buffer)
9192 {
9193  nk_size size;
9194  nk_size offset;
9195  nk_byte *memory;
9196  const struct nk_draw_command *end;
9197 
9198  NK_ASSERT(buffer);
9199  NK_ASSERT(canvas);
9200  if (!buffer || !canvas)
9201  return 0;
9202 
9203  memory = (nk_byte*)buffer->memory.ptr;
9204  size = buffer->memory.size;
9205  offset = size - canvas->cmd_offset;
9206  end = nk_ptr_add(const struct nk_draw_command, memory, offset);
9207  end -= (canvas->cmd_count-1);
9208  return end;
9209 }
9210 NK_API const struct nk_draw_command*
9211 nk__draw_list_next(const struct nk_draw_command *cmd,
9212  const struct nk_buffer *buffer, const struct nk_draw_list *canvas)
9213 {
9214  const struct nk_draw_command *end;
9215  NK_ASSERT(buffer);
9216  NK_ASSERT(canvas);
9217  if (!cmd || !buffer || !canvas)
9218  return 0;
9219 
9220  end = nk__draw_list_end(canvas, buffer);
9221  if (cmd <= end) return 0;
9222  return (cmd-1);
9223 }
9224 NK_INTERN struct nk_vec2*
9225 nk_draw_list_alloc_path(struct nk_draw_list *list, int count)
9226 {
9227  struct nk_vec2 *points;
9228  NK_STORAGE const nk_size point_align = NK_ALIGNOF(struct nk_vec2);
9229  NK_STORAGE const nk_size point_size = sizeof(struct nk_vec2);
9230  points = (struct nk_vec2*)
9231  nk_buffer_alloc(list->buffer, NK_BUFFER_FRONT,
9232  point_size * (nk_size)count, point_align);
9233 
9234  if (!points) return 0;
9235  if (!list->path_offset) {
9236  void *memory = nk_buffer_memory(list->buffer);
9237  list->path_offset = (unsigned int)((nk_byte*)points - (nk_byte*)memory);
9238  }
9239  list->path_count += (unsigned int)count;
9240  return points;
9241 }
9242 NK_INTERN struct nk_vec2
9243 nk_draw_list_path_last(struct nk_draw_list *list)
9244 {
9245  void *memory;
9246  struct nk_vec2 *point;
9247  NK_ASSERT(list->path_count);
9248  memory = nk_buffer_memory(list->buffer);
9249  point = nk_ptr_add(struct nk_vec2, memory, list->path_offset);
9250  point += (list->path_count-1);
9251  return *point;
9252 }
9253 NK_INTERN struct nk_draw_command*
9254 nk_draw_list_push_command(struct nk_draw_list *list, struct nk_rect clip,
9255  nk_handle texture)
9256 {
9257  NK_STORAGE const nk_size cmd_align = NK_ALIGNOF(struct nk_draw_command);
9258  NK_STORAGE const nk_size cmd_size = sizeof(struct nk_draw_command);
9259  struct nk_draw_command *cmd;
9260 
9261  NK_ASSERT(list);
9262  cmd = (struct nk_draw_command*)
9263  nk_buffer_alloc(list->buffer, NK_BUFFER_BACK, cmd_size, cmd_align);
9264 
9265  if (!cmd) return 0;
9266  if (!list->cmd_count) {
9267  nk_byte *memory = (nk_byte*)nk_buffer_memory(list->buffer);
9268  nk_size total = nk_buffer_total(list->buffer);
9269  memory = nk_ptr_add(nk_byte, memory, total);
9270  list->cmd_offset = (nk_size)(memory - (nk_byte*)cmd);
9271  }
9272 
9273  cmd->elem_count = 0;
9274  cmd->clip_rect = clip;
9275  cmd->texture = texture;
9276 #ifdef NK_INCLUDE_COMMAND_USERDATA
9277  cmd->userdata = list->userdata;
9278 #endif
9279 
9280  list->cmd_count++;
9281  list->clip_rect = clip;
9282  return cmd;
9283 }
9284 NK_INTERN struct nk_draw_command*
9285 nk_draw_list_command_last(struct nk_draw_list *list)
9286 {
9287  void *memory;
9288  nk_size size;
9289  struct nk_draw_command *cmd;
9290  NK_ASSERT(list->cmd_count);
9291 
9292  memory = nk_buffer_memory(list->buffer);
9293  size = nk_buffer_total(list->buffer);
9294  cmd = nk_ptr_add(struct nk_draw_command, memory, size - list->cmd_offset);
9295  return (cmd - (list->cmd_count-1));
9296 }
9297 NK_INTERN void
9298 nk_draw_list_add_clip(struct nk_draw_list *list, struct nk_rect rect)
9299 {
9300  NK_ASSERT(list);
9301  if (!list) return;
9302  if (!list->cmd_count) {
9303  nk_draw_list_push_command(list, rect, list->config.null.texture);
9304  } else {
9305  struct nk_draw_command *prev = nk_draw_list_command_last(list);
9306  if (prev->elem_count == 0)
9307  prev->clip_rect = rect;
9308  nk_draw_list_push_command(list, rect, prev->texture);
9309  }
9310 }
9311 NK_INTERN void
9312 nk_draw_list_push_image(struct nk_draw_list *list, nk_handle texture)
9313 {
9314  NK_ASSERT(list);
9315  if (!list) return;
9316  if (!list->cmd_count) {
9317  nk_draw_list_push_command(list, nk_null_rect, texture);
9318  } else {
9319  struct nk_draw_command *prev = nk_draw_list_command_last(list);
9320  if (prev->elem_count == 0) {
9321  prev->texture = texture;
9322  #ifdef NK_INCLUDE_COMMAND_USERDATA
9323  prev->userdata = list->userdata;
9324  #endif
9325  } else if (prev->texture.id != texture.id
9326  #ifdef NK_INCLUDE_COMMAND_USERDATA
9327  || prev->userdata.id != list->userdata.id
9328  #endif
9329  ) nk_draw_list_push_command(list, prev->clip_rect, texture);
9330  }
9331 }
9332 #ifdef NK_INCLUDE_COMMAND_USERDATA
9333 NK_API void
9334 nk_draw_list_push_userdata(struct nk_draw_list *list, nk_handle userdata)
9335 {
9336  list->userdata = userdata;
9337 }
9338 #endif
9339 NK_INTERN void*
9340 nk_draw_list_alloc_vertices(struct nk_draw_list *list, nk_size count)
9341 {
9342  void *vtx;
9343  NK_ASSERT(list);
9344  if (!list) return 0;
9345  vtx = nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT,
9346  list->config.vertex_size*count, list->config.vertex_alignment);
9347  if (!vtx) return 0;
9348  list->vertex_count += (unsigned int)count;
9349 
9350  /* This assert triggers because your are drawing a lot of stuff and nuklear
9351  * defined `nk_draw_index` as `nk_ushort` to safe space be default.
9352  *
9353  * So you reached the maximum number of indicies or rather vertexes.
9354  * To solve this issue please change typdef `nk_draw_index` to `nk_uint`
9355  * and don't forget to specify the new element size in your drawing
9356  * backend (OpenGL, DirectX, ...). For example in OpenGL for `glDrawElements`
9357  * instead of specifing `GL_UNSIGNED_SHORT` you have to define `GL_UNSIGNED_INT`.
9358  * Sorry for the inconvenience. */
9359  NK_ASSERT((sizeof(nk_draw_index) == 2 && list->vertex_count < NK_USHORT_MAX &&
9360  "To many verticies for 16-bit vertex indicies. Please read comment above on how to solve this problem"));
9361  return vtx;
9362 }
9363 NK_INTERN nk_draw_index*
9364 nk_draw_list_alloc_elements(struct nk_draw_list *list, nk_size count)
9365 {
9366  nk_draw_index *ids;
9367  struct nk_draw_command *cmd;
9368  NK_STORAGE const nk_size elem_align = NK_ALIGNOF(nk_draw_index);
9369  NK_STORAGE const nk_size elem_size = sizeof(nk_draw_index);
9370  NK_ASSERT(list);
9371  if (!list) return 0;
9372 
9373  ids = (nk_draw_index*)
9374  nk_buffer_alloc(list->elements, NK_BUFFER_FRONT, elem_size*count, elem_align);
9375  if (!ids) return 0;
9376  cmd = nk_draw_list_command_last(list);
9377  list->element_count += (unsigned int)count;
9378  cmd->elem_count += (unsigned int)count;
9379  return ids;
9380 }
9381 NK_INTERN int
9382 nk_draw_vertex_layout_element_is_end_of_layout(
9383  const struct nk_draw_vertex_layout_element *element)
9384 {
9385  return (element->attribute == NK_VERTEX_ATTRIBUTE_COUNT ||
9386  element->format == NK_FORMAT_COUNT);
9387 }
9388 NK_INTERN void
9389 nk_draw_vertex_color(void *attr, const float *vals,
9390  enum nk_draw_vertex_layout_format format)
9391 {
9392  /* if this triggers you tried to provide a value format for a color */
9393  float val[4];
9394  NK_ASSERT(format >= NK_FORMAT_COLOR_BEGIN);
9395  NK_ASSERT(format <= NK_FORMAT_COLOR_END);
9396  if (format < NK_FORMAT_COLOR_BEGIN || format > NK_FORMAT_COLOR_END) return;
9397 
9398  val[0] = NK_SATURATE(vals[0]);
9399  val[1] = NK_SATURATE(vals[1]);
9400  val[2] = NK_SATURATE(vals[2]);
9401  val[3] = NK_SATURATE(vals[3]);
9402 
9403  switch (format) {
9404  default: NK_ASSERT(0 && "Invalid vertex layout color format"); break;
9405  case NK_FORMAT_R8G8B8A8:
9406  case NK_FORMAT_R8G8B8: {
9407  struct nk_color col = nk_rgba_fv(val);
9408  NK_MEMCPY(attr, &col.r, sizeof(col));
9409  } break;
9410  case NK_FORMAT_B8G8R8A8: {
9411  struct nk_color col = nk_rgba_fv(val);
9412  struct nk_color bgra = nk_rgba(col.b, col.g, col.r, col.a);
9413  NK_MEMCPY(attr, &bgra, sizeof(bgra));
9414  } break;
9415  case NK_FORMAT_R16G15B16: {
9416  nk_ushort col[3];
9417  col[0] = (nk_ushort)(val[0]*(float)NK_USHORT_MAX);
9418  col[1] = (nk_ushort)(val[1]*(float)NK_USHORT_MAX);
9419  col[2] = (nk_ushort)(val[2]*(float)NK_USHORT_MAX);
9420  NK_MEMCPY(attr, col, sizeof(col));
9421  } break;
9422  case NK_FORMAT_R16G15B16A16: {
9423  nk_ushort col[4];
9424  col[0] = (nk_ushort)(val[0]*(float)NK_USHORT_MAX);
9425  col[1] = (nk_ushort)(val[1]*(float)NK_USHORT_MAX);
9426  col[2] = (nk_ushort)(val[2]*(float)NK_USHORT_MAX);
9427  col[3] = (nk_ushort)(val[3]*(float)NK_USHORT_MAX);
9428  NK_MEMCPY(attr, col, sizeof(col));
9429  } break;
9430  case NK_FORMAT_R32G32B32: {
9431  nk_uint col[3];
9432  col[0] = (nk_uint)(val[0]*(float)NK_UINT_MAX);
9433  col[1] = (nk_uint)(val[1]*(float)NK_UINT_MAX);
9434  col[2] = (nk_uint)(val[2]*(float)NK_UINT_MAX);
9435  NK_MEMCPY(attr, col, sizeof(col));
9436  } break;
9437  case NK_FORMAT_R32G32B32A32: {
9438  nk_uint col[4];
9439  col[0] = (nk_uint)(val[0]*(float)NK_UINT_MAX);
9440  col[1] = (nk_uint)(val[1]*(float)NK_UINT_MAX);
9441  col[2] = (nk_uint)(val[2]*(float)NK_UINT_MAX);
9442  col[3] = (nk_uint)(val[3]*(float)NK_UINT_MAX);
9443  NK_MEMCPY(attr, col, sizeof(col));
9444  } break;
9445  case NK_FORMAT_R32G32B32A32_FLOAT:
9446  NK_MEMCPY(attr, val, sizeof(float)*4);
9447  break;
9448  case NK_FORMAT_R32G32B32A32_DOUBLE: {
9449  double col[4];
9450  col[0] = (double)val[0];
9451  col[1] = (double)val[1];
9452  col[2] = (double)val[2];
9453  col[3] = (double)val[3];
9454  NK_MEMCPY(attr, col, sizeof(col));
9455  } break;
9456  case NK_FORMAT_RGB32:
9457  case NK_FORMAT_RGBA32: {
9458  struct nk_color col = nk_rgba_fv(val);
9459  nk_uint color = nk_color_u32(col);
9460  NK_MEMCPY(attr, &color, sizeof(color));
9461  } break; }
9462 }
9463 NK_INTERN void
9464 nk_draw_vertex_element(void *dst, const float *values, int value_count,
9465  enum nk_draw_vertex_layout_format format)
9466 {
9467  int value_index;
9468  void *attribute = dst;
9469  /* if this triggers you tried to provide a color format for a value */
9470  NK_ASSERT(format < NK_FORMAT_COLOR_BEGIN);
9471  if (format >= NK_FORMAT_COLOR_BEGIN && format <= NK_FORMAT_COLOR_END) return;
9472  for (value_index = 0; value_index < value_count; ++value_index) {
9473  switch (format) {
9474  default: NK_ASSERT(0 && "invalid vertex layout format"); break;
9475  case NK_FORMAT_SCHAR: {
9476  char value = (char)NK_CLAMP((float)NK_SCHAR_MIN, values[value_index], (float)NK_SCHAR_MAX);
9477  NK_MEMCPY(attribute, &value, sizeof(value));
9478  attribute = (void*)((char*)attribute + sizeof(char));
9479  } break;
9480  case NK_FORMAT_SSHORT: {
9481  nk_short value = (nk_short)NK_CLAMP((float)NK_SSHORT_MIN, values[value_index], (float)NK_SSHORT_MAX);
9482  NK_MEMCPY(attribute, &value, sizeof(value));
9483  attribute = (void*)((char*)attribute + sizeof(value));
9484  } break;
9485  case NK_FORMAT_SINT: {
9486  nk_int value = (nk_int)NK_CLAMP((float)NK_SINT_MIN, values[value_index], (float)NK_SINT_MAX);
9487  NK_MEMCPY(attribute, &value, sizeof(value));
9488  attribute = (void*)((char*)attribute + sizeof(nk_int));
9489  } break;
9490  case NK_FORMAT_UCHAR: {
9491  unsigned char value = (unsigned char)NK_CLAMP((float)NK_UCHAR_MIN, values[value_index], (float)NK_UCHAR_MAX);
9492  NK_MEMCPY(attribute, &value, sizeof(value));
9493  attribute = (void*)((char*)attribute + sizeof(unsigned char));
9494  } break;
9495  case NK_FORMAT_USHORT: {
9496  nk_ushort value = (nk_ushort)NK_CLAMP((float)NK_USHORT_MIN, values[value_index], (float)NK_USHORT_MAX);
9497  NK_MEMCPY(attribute, &value, sizeof(value));
9498  attribute = (void*)((char*)attribute + sizeof(value));
9499  } break;
9500  case NK_FORMAT_UINT: {
9501  nk_uint value = (nk_uint)NK_CLAMP((float)NK_UINT_MIN, values[value_index], (float)NK_UINT_MAX);
9502  NK_MEMCPY(attribute, &value, sizeof(value));
9503  attribute = (void*)((char*)attribute + sizeof(nk_uint));
9504  } break;
9505  case NK_FORMAT_FLOAT:
9506  NK_MEMCPY(attribute, &values[value_index], sizeof(values[value_index]));
9507  attribute = (void*)((char*)attribute + sizeof(float));
9508  break;
9509  case NK_FORMAT_DOUBLE: {
9510  double value = (double)values[value_index];
9511  NK_MEMCPY(attribute, &value, sizeof(value));
9512  attribute = (void*)((char*)attribute + sizeof(double));
9513  } break;
9514  }
9515  }
9516 }
9517 NK_INTERN void*
9518 nk_draw_vertex(void *dst, const struct nk_convert_config *config,
9519  struct nk_vec2 pos, struct nk_vec2 uv, struct nk_colorf color)
9520 {
9521  void *result = (void*)((char*)dst + config->vertex_size);
9522  const struct nk_draw_vertex_layout_element *elem_iter = config->vertex_layout;
9523  while (!nk_draw_vertex_layout_element_is_end_of_layout(elem_iter)) {
9524  void *address = (void*)((char*)dst + elem_iter->offset);
9525  switch (elem_iter->attribute) {
9526  case NK_VERTEX_ATTRIBUTE_COUNT:
9527  default: NK_ASSERT(0 && "wrong element attribute"); break;
9528  case NK_VERTEX_POSITION: nk_draw_vertex_element(address, &pos.x, 2, elem_iter->format); break;
9529  case NK_VERTEX_TEXCOORD: nk_draw_vertex_element(address, &uv.x, 2, elem_iter->format); break;
9530  case NK_VERTEX_COLOR: nk_draw_vertex_color(address, &color.r, elem_iter->format); break;
9531  }
9532  elem_iter++;
9533  }
9534  return result;
9535 }
9536 NK_API void
9537 nk_draw_list_stroke_poly_line(struct nk_draw_list *list, const struct nk_vec2 *points,
9538  const unsigned int points_count, struct nk_color color, enum nk_draw_list_stroke closed,
9539  float thickness, enum nk_anti_aliasing aliasing)
9540 {
9541  nk_size count;
9542  int thick_line;
9543  struct nk_colorf col;
9544  struct nk_colorf col_trans;
9545  NK_ASSERT(list);
9546  if (!list || points_count < 2) return;
9547 
9548  color.a = (nk_byte)((float)color.a * list->config.global_alpha);
9549  count = points_count;
9550  if (!closed) count = points_count-1;
9551  thick_line = thickness > 1.0f;
9552 
9553 #ifdef NK_INCLUDE_COMMAND_USERDATA
9554  nk_draw_list_push_userdata(list, list->userdata);
9555 #endif
9556 
9557  color.a = (nk_byte)((float)color.a * list->config.global_alpha);
9558  nk_color_fv(&col.r, color);
9559  col_trans = col;
9560  col_trans.a = 0;
9561 
9562  if (aliasing == NK_ANTI_ALIASING_ON) {
9563  /* ANTI-ALIASED STROKE */
9564  const float AA_SIZE = 1.0f;
9565  NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2);
9566  NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2);
9567 
9568  /* allocate vertices and elements */
9569  nk_size i1 = 0;
9570  nk_size vertex_offset;
9571  nk_size index = list->vertex_count;
9572 
9573  const nk_size idx_count = (thick_line) ? (count * 18) : (count * 12);
9574  const nk_size vtx_count = (thick_line) ? (points_count * 4): (points_count *3);
9575 
9576  void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9577  nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9578 
9579  nk_size size;
9580  struct nk_vec2 *normals, *temp;
9581  if (!vtx || !ids) return;
9582 
9583  /* temporary allocate normals + points */
9584  vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
9585  nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
9586  size = pnt_size * ((thick_line) ? 5 : 3) * points_count;
9587  normals = (struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
9588  if (!normals) return;
9589  temp = normals + points_count;
9590 
9591  /* make sure vertex pointer is still correct */
9592  vtx = (void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
9593 
9594  /* calculate normals */
9595  for (i1 = 0; i1 < count; ++i1) {
9596  const nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
9597  struct nk_vec2 diff = nk_vec2_sub(points[i2], points[i1]);
9598  float len;
9599 
9600  /* vec2 inverted length */
9601  len = nk_vec2_len_sqr(diff);
9602  if (len != 0.0f)
9603  len = nk_inv_sqrt(len);
9604  else len = 1.0f;
9605 
9606  diff = nk_vec2_muls(diff, len);
9607  normals[i1].x = diff.y;
9608  normals[i1].y = -diff.x;
9609  }
9610 
9611  if (!closed)
9612  normals[points_count-1] = normals[points_count-2];
9613 
9614  if (!thick_line) {
9615  nk_size idx1, i;
9616  if (!closed) {
9617  struct nk_vec2 d;
9618  temp[0] = nk_vec2_add(points[0], nk_vec2_muls(normals[0], AA_SIZE));
9619  temp[1] = nk_vec2_sub(points[0], nk_vec2_muls(normals[0], AA_SIZE));
9620  d = nk_vec2_muls(normals[points_count-1], AA_SIZE);
9621  temp[(points_count-1) * 2 + 0] = nk_vec2_add(points[points_count-1], d);
9622  temp[(points_count-1) * 2 + 1] = nk_vec2_sub(points[points_count-1], d);
9623  }
9624 
9625  /* fill elements */
9626  idx1 = index;
9627  for (i1 = 0; i1 < count; i1++) {
9628  struct nk_vec2 dm;
9629  float dmr2;
9630  nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
9631  nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 3);
9632 
9633  /* average normals */
9634  dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
9635  dmr2 = dm.x * dm.x + dm.y* dm.y;
9636  if (dmr2 > 0.000001f) {
9637  float scale = 1.0f/dmr2;
9638  scale = NK_MIN(100.0f, scale);
9639  dm = nk_vec2_muls(dm, scale);
9640  }
9641 
9642  dm = nk_vec2_muls(dm, AA_SIZE);
9643  temp[i2*2+0] = nk_vec2_add(points[i2], dm);
9644  temp[i2*2+1] = nk_vec2_sub(points[i2], dm);
9645 
9646  ids[0] = (nk_draw_index)(idx2 + 0); ids[1] = (nk_draw_index)(idx1+0);
9647  ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
9648  ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+0);
9649  ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
9650  ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
9651  ids[10]= (nk_draw_index)(idx2 + 0); ids[11]= (nk_draw_index)(idx2+1);
9652  ids += 12;
9653  idx1 = idx2;
9654  }
9655 
9656  /* fill vertices */
9657  for (i = 0; i < points_count; ++i) {
9658  const struct nk_vec2 uv = list->config.null.uv;
9659  vtx = nk_draw_vertex(vtx, &list->config, points[i], uv, col);
9660  vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+0], uv, col_trans);
9661  vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+1], uv, col_trans);
9662  }
9663  } else {
9664  nk_size idx1, i;
9665  const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f;
9666  if (!closed) {
9667  struct nk_vec2 d1 = nk_vec2_muls(normals[0], half_inner_thickness + AA_SIZE);
9668  struct nk_vec2 d2 = nk_vec2_muls(normals[0], half_inner_thickness);
9669 
9670  temp[0] = nk_vec2_add(points[0], d1);
9671  temp[1] = nk_vec2_add(points[0], d2);
9672  temp[2] = nk_vec2_sub(points[0], d2);
9673  temp[3] = nk_vec2_sub(points[0], d1);
9674 
9675  d1 = nk_vec2_muls(normals[points_count-1], half_inner_thickness + AA_SIZE);
9676  d2 = nk_vec2_muls(normals[points_count-1], half_inner_thickness);
9677 
9678  temp[(points_count-1)*4+0] = nk_vec2_add(points[points_count-1], d1);
9679  temp[(points_count-1)*4+1] = nk_vec2_add(points[points_count-1], d2);
9680  temp[(points_count-1)*4+2] = nk_vec2_sub(points[points_count-1], d2);
9681  temp[(points_count-1)*4+3] = nk_vec2_sub(points[points_count-1], d1);
9682  }
9683 
9684  /* add all elements */
9685  idx1 = index;
9686  for (i1 = 0; i1 < count; ++i1) {
9687  struct nk_vec2 dm_out, dm_in;
9688  const nk_size i2 = ((i1+1) == points_count) ? 0: (i1 + 1);
9689  nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 4);
9690 
9691  /* average normals */
9692  struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
9693  float dmr2 = dm.x * dm.x + dm.y* dm.y;
9694  if (dmr2 > 0.000001f) {
9695  float scale = 1.0f/dmr2;
9696  scale = NK_MIN(100.0f, scale);
9697  dm = nk_vec2_muls(dm, scale);
9698  }
9699 
9700  dm_out = nk_vec2_muls(dm, ((half_inner_thickness) + AA_SIZE));
9701  dm_in = nk_vec2_muls(dm, half_inner_thickness);
9702  temp[i2*4+0] = nk_vec2_add(points[i2], dm_out);
9703  temp[i2*4+1] = nk_vec2_add(points[i2], dm_in);
9704  temp[i2*4+2] = nk_vec2_sub(points[i2], dm_in);
9705  temp[i2*4+3] = nk_vec2_sub(points[i2], dm_out);
9706 
9707  /* add indexes */
9708  ids[0] = (nk_draw_index)(idx2 + 1); ids[1] = (nk_draw_index)(idx1+1);
9709  ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
9710  ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+1);
9711  ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
9712  ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
9713  ids[10]= (nk_draw_index)(idx2 + 0); ids[11] = (nk_draw_index)(idx2+1);
9714  ids[12]= (nk_draw_index)(idx2 + 2); ids[13] = (nk_draw_index)(idx1+2);
9715  ids[14]= (nk_draw_index)(idx1 + 3); ids[15] = (nk_draw_index)(idx1+3);
9716  ids[16]= (nk_draw_index)(idx2 + 3); ids[17] = (nk_draw_index)(idx2+2);
9717  ids += 18;
9718  idx1 = idx2;
9719  }
9720 
9721  /* add vertices */
9722  for (i = 0; i < points_count; ++i) {
9723  const struct nk_vec2 uv = list->config.null.uv;
9724  vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+0], uv, col_trans);
9725  vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+1], uv, col);
9726  vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+2], uv, col);
9727  vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+3], uv, col_trans);
9728  }
9729  }
9730  /* free temporary normals + points */
9731  nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
9732  } else {
9733  /* NON ANTI-ALIASED STROKE */
9734  nk_size i1 = 0;
9735  nk_size idx = list->vertex_count;
9736  const nk_size idx_count = count * 6;
9737  const nk_size vtx_count = count * 4;
9738  void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9739  nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9740  if (!vtx || !ids) return;
9741 
9742  for (i1 = 0; i1 < count; ++i1) {
9743  float dx, dy;
9744  const struct nk_vec2 uv = list->config.null.uv;
9745  const nk_size i2 = ((i1+1) == points_count) ? 0 : i1 + 1;
9746  const struct nk_vec2 p1 = points[i1];
9747  const struct nk_vec2 p2 = points[i2];
9748  struct nk_vec2 diff = nk_vec2_sub(p2, p1);
9749  float len;
9750 
9751  /* vec2 inverted length */
9752  len = nk_vec2_len_sqr(diff);
9753  if (len != 0.0f)
9754  len = nk_inv_sqrt(len);
9755  else len = 1.0f;
9756  diff = nk_vec2_muls(diff, len);
9757 
9758  /* add vertices */
9759  dx = diff.x * (thickness * 0.5f);
9760  dy = diff.y * (thickness * 0.5f);
9761 
9762  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x + dy, p1.y - dx), uv, col);
9763  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x + dy, p2.y - dx), uv, col);
9764  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x - dy, p2.y + dx), uv, col);
9765  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x - dy, p1.y + dx), uv, col);
9766 
9767  ids[0] = (nk_draw_index)(idx+0); ids[1] = (nk_draw_index)(idx+1);
9768  ids[2] = (nk_draw_index)(idx+2); ids[3] = (nk_draw_index)(idx+0);
9769  ids[4] = (nk_draw_index)(idx+2); ids[5] = (nk_draw_index)(idx+3);
9770 
9771  ids += 6;
9772  idx += 4;
9773  }
9774  }
9775 }
9776 NK_API void
9777 nk_draw_list_fill_poly_convex(struct nk_draw_list *list,
9778  const struct nk_vec2 *points, const unsigned int points_count,
9779  struct nk_color color, enum nk_anti_aliasing aliasing)
9780 {
9781  struct nk_colorf col;
9782  struct nk_colorf col_trans;
9783 
9784  NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2);
9785  NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2);
9786  NK_ASSERT(list);
9787  if (!list || points_count < 3) return;
9788 
9789 #ifdef NK_INCLUDE_COMMAND_USERDATA
9790  nk_draw_list_push_userdata(list, list->userdata);
9791 #endif
9792 
9793  color.a = (nk_byte)((float)color.a * list->config.global_alpha);
9794  nk_color_fv(&col.r, color);
9795  col_trans = col;
9796  col_trans.a = 0;
9797 
9798  if (aliasing == NK_ANTI_ALIASING_ON) {
9799  nk_size i = 0;
9800  nk_size i0 = 0;
9801  nk_size i1 = 0;
9802 
9803  const float AA_SIZE = 1.0f;
9804  nk_size vertex_offset = 0;
9805  nk_size index = list->vertex_count;
9806 
9807  const nk_size idx_count = (points_count-2)*3 + points_count*6;
9808  const nk_size vtx_count = (points_count*2);
9809 
9810  void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9811  nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9812 
9813  nk_size size = 0;
9814  struct nk_vec2 *normals = 0;
9815  unsigned int vtx_inner_idx = (unsigned int)(index + 0);
9816  unsigned int vtx_outer_idx = (unsigned int)(index + 1);
9817  if (!vtx || !ids) return;
9818 
9819  /* temporary allocate normals */
9820  vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
9821  nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
9822  size = pnt_size * points_count;
9823  normals = (struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
9824  if (!normals) return;
9825  vtx = (void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
9826 
9827  /* add elements */
9828  for (i = 2; i < points_count; i++) {
9829  ids[0] = (nk_draw_index)(vtx_inner_idx);
9830  ids[1] = (nk_draw_index)(vtx_inner_idx + ((i-1) << 1));
9831  ids[2] = (nk_draw_index)(vtx_inner_idx + (i << 1));
9832  ids += 3;
9833  }
9834 
9835  /* compute normals */
9836  for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
9837  struct nk_vec2 p0 = points[i0];
9838  struct nk_vec2 p1 = points[i1];
9839  struct nk_vec2 diff = nk_vec2_sub(p1, p0);
9840 
9841  /* vec2 inverted length */
9842  float len = nk_vec2_len_sqr(diff);
9843  if (len != 0.0f)
9844  len = nk_inv_sqrt(len);
9845  else len = 1.0f;
9846  diff = nk_vec2_muls(diff, len);
9847 
9848  normals[i0].x = diff.y;
9849  normals[i0].y = -diff.x;
9850  }
9851 
9852  /* add vertices + indexes */
9853  for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
9854  const struct nk_vec2 uv = list->config.null.uv;
9855  struct nk_vec2 n0 = normals[i0];
9856  struct nk_vec2 n1 = normals[i1];
9857  struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(n0, n1), 0.5f);
9858  float dmr2 = dm.x*dm.x + dm.y*dm.y;
9859  if (dmr2 > 0.000001f) {
9860  float scale = 1.0f / dmr2;
9861  scale = NK_MIN(scale, 100.0f);
9862  dm = nk_vec2_muls(dm, scale);
9863  }
9864  dm = nk_vec2_muls(dm, AA_SIZE * 0.5f);
9865 
9866  /* add vertices */
9867  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_sub(points[i1], dm), uv, col);
9868  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_add(points[i1], dm), uv, col_trans);
9869 
9870  /* add indexes */
9871  ids[0] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
9872  ids[1] = (nk_draw_index)(vtx_inner_idx+(i0<<1));
9873  ids[2] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
9874  ids[3] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
9875  ids[4] = (nk_draw_index)(vtx_outer_idx+(i1<<1));
9876  ids[5] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
9877  ids += 6;
9878  }
9879  /* free temporary normals + points */
9880  nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
9881  } else {
9882  nk_size i = 0;
9883  nk_size index = list->vertex_count;
9884  const nk_size idx_count = (points_count-2)*3;
9885  const nk_size vtx_count = points_count;
9886  void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
9887  nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
9888 
9889  if (!vtx || !ids) return;
9890  for (i = 0; i < vtx_count; ++i)
9891  vtx = nk_draw_vertex(vtx, &list->config, points[i], list->config.null.uv, col);
9892  for (i = 2; i < points_count; ++i) {
9893  ids[0] = (nk_draw_index)index;
9894  ids[1] = (nk_draw_index)(index+ i - 1);
9895  ids[2] = (nk_draw_index)(index+i);
9896  ids += 3;
9897  }
9898  }
9899 }
9900 NK_API void
9901 nk_draw_list_path_clear(struct nk_draw_list *list)
9902 {
9903  NK_ASSERT(list);
9904  if (!list) return;
9905  nk_buffer_reset(list->buffer, NK_BUFFER_FRONT);
9906  list->path_count = 0;
9907  list->path_offset = 0;
9908 }
9909 NK_API void
9910 nk_draw_list_path_line_to(struct nk_draw_list *list, struct nk_vec2 pos)
9911 {
9912  struct nk_vec2 *points = 0;
9913  struct nk_draw_command *cmd = 0;
9914  NK_ASSERT(list);
9915  if (!list) return;
9916  if (!list->cmd_count)
9917  nk_draw_list_add_clip(list, nk_null_rect);
9918 
9919  cmd = nk_draw_list_command_last(list);
9920  if (cmd && cmd->texture.ptr != list->config.null.texture.ptr)
9921  nk_draw_list_push_image(list, list->config.null.texture);
9922 
9923  points = nk_draw_list_alloc_path(list, 1);
9924  if (!points) return;
9925  points[0] = pos;
9926 }
9927 NK_API void
9928 nk_draw_list_path_arc_to_fast(struct nk_draw_list *list, struct nk_vec2 center,
9929  float radius, int a_min, int a_max)
9930 {
9931  int a = 0;
9932  NK_ASSERT(list);
9933  if (!list) return;
9934  if (a_min <= a_max) {
9935  for (a = a_min; a <= a_max; a++) {
9936  const struct nk_vec2 c = list->circle_vtx[(nk_size)a % NK_LEN(list->circle_vtx)];
9937  const float x = center.x + c.x * radius;
9938  const float y = center.y + c.y * radius;
9939  nk_draw_list_path_line_to(list, nk_vec2(x, y));
9940  }
9941  }
9942 }
9943 NK_API void
9944 nk_draw_list_path_arc_to(struct nk_draw_list *list, struct nk_vec2 center,
9945  float radius, float a_min, float a_max, unsigned int segments)
9946 {
9947  unsigned int i = 0;
9948  NK_ASSERT(list);
9949  if (!list) return;
9950  if (radius == 0.0f) return;
9951 
9952  /* This algorithm for arc drawing relies on these two trigonometric identities[1]:
9953  sin(a + b) = sin(a) * cos(b) + cos(a) * sin(b)
9954  cos(a + b) = cos(a) * cos(b) - sin(a) * sin(b)
9955 
9956  Two coordinates (x, y) of a point on a circle centered on
9957  the origin can be written in polar form as:
9958  x = r * cos(a)
9959  y = r * sin(a)
9960  where r is the radius of the circle,
9961  a is the angle between (x, y) and the origin.
9962 
9963  This allows us to rotate the coordinates around the
9964  origin by an angle b using the following transformation:
9965  x' = r * cos(a + b) = x * cos(b) - y * sin(b)
9966  y' = r * sin(a + b) = y * cos(b) + x * sin(b)
9967 
9968  [1] https://en.wikipedia.org/wiki/List_of_trigonometric_identities#Angle_sum_and_difference_identities
9969  */
9970  {const float d_angle = (a_max - a_min) / (float)segments;
9971  const float sin_d = (float)NK_SIN(d_angle);
9972  const float cos_d = (float)NK_COS(d_angle);
9973 
9974  float cx = (float)NK_COS(a_min) * radius;
9975  float cy = (float)NK_SIN(a_min) * radius;
9976  for(i = 0; i <= segments; ++i) {
9977  float new_cx, new_cy;
9978  const float x = center.x + cx;
9979  const float y = center.y + cy;
9980  nk_draw_list_path_line_to(list, nk_vec2(x, y));
9981 
9982  new_cx = cx * cos_d - cy * sin_d;
9983  new_cy = cy * cos_d + cx * sin_d;
9984  cx = new_cx;
9985  cy = new_cy;
9986  }}
9987 }
9988 NK_API void
9989 nk_draw_list_path_rect_to(struct nk_draw_list *list, struct nk_vec2 a,
9990  struct nk_vec2 b, float rounding)
9991 {
9992  float r;
9993  NK_ASSERT(list);
9994  if (!list) return;
9995  r = rounding;
9996  r = NK_MIN(r, ((b.x-a.x) < 0) ? -(b.x-a.x): (b.x-a.x));
9997  r = NK_MIN(r, ((b.y-a.y) < 0) ? -(b.y-a.y): (b.y-a.y));
9998 
9999  if (r == 0.0f) {
10000  nk_draw_list_path_line_to(list, a);
10001  nk_draw_list_path_line_to(list, nk_vec2(b.x,a.y));
10002  nk_draw_list_path_line_to(list, b);
10003  nk_draw_list_path_line_to(list, nk_vec2(a.x,b.y));
10004  } else {
10005  nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, a.y + r), r, 6, 9);
10006  nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, a.y + r), r, 9, 12);
10007  nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, b.y - r), r, 0, 3);
10008  nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, b.y - r), r, 3, 6);
10009  }
10010 }
10011 NK_API void
10012 nk_draw_list_path_curve_to(struct nk_draw_list *list, struct nk_vec2 p2,
10013  struct nk_vec2 p3, struct nk_vec2 p4, unsigned int num_segments)
10014 {
10015  float t_step;
10016  unsigned int i_step;
10017  struct nk_vec2 p1;
10018 
10019  NK_ASSERT(list);
10020  NK_ASSERT(list->path_count);
10021  if (!list || !list->path_count) return;
10022  num_segments = NK_MAX(num_segments, 1);
10023 
10024  p1 = nk_draw_list_path_last(list);
10025  t_step = 1.0f/(float)num_segments;
10026  for (i_step = 1; i_step <= num_segments; ++i_step) {
10027  float t = t_step * (float)i_step;
10028  float u = 1.0f - t;
10029  float w1 = u*u*u;
10030  float w2 = 3*u*u*t;
10031  float w3 = 3*u*t*t;
10032  float w4 = t * t *t;
10033  float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
10034  float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
10035  nk_draw_list_path_line_to(list, nk_vec2(x,y));
10036  }
10037 }
10038 NK_API void
10039 nk_draw_list_path_fill(struct nk_draw_list *list, struct nk_color color)
10040 {
10041  struct nk_vec2 *points;
10042  NK_ASSERT(list);
10043  if (!list) return;
10044  points = (struct nk_vec2*)nk_buffer_memory(list->buffer);
10045  nk_draw_list_fill_poly_convex(list, points, list->path_count, color, list->config.shape_AA);
10046  nk_draw_list_path_clear(list);
10047 }
10048 NK_API void
10049 nk_draw_list_path_stroke(struct nk_draw_list *list, struct nk_color color,
10050  enum nk_draw_list_stroke closed, float thickness)
10051 {
10052  struct nk_vec2 *points;
10053  NK_ASSERT(list);
10054  if (!list) return;
10055  points = (struct nk_vec2*)nk_buffer_memory(list->buffer);
10056  nk_draw_list_stroke_poly_line(list, points, list->path_count, color,
10057  closed, thickness, list->config.line_AA);
10058  nk_draw_list_path_clear(list);
10059 }
10060 NK_API void
10061 nk_draw_list_stroke_line(struct nk_draw_list *list, struct nk_vec2 a,
10062  struct nk_vec2 b, struct nk_color col, float thickness)
10063 {
10064  NK_ASSERT(list);
10065  if (!list || !col.a) return;
10066  if (list->line_AA == NK_ANTI_ALIASING_ON) {
10067  nk_draw_list_path_line_to(list, a);
10068  nk_draw_list_path_line_to(list, b);
10069  } else {
10070  nk_draw_list_path_line_to(list, nk_vec2_sub(a,nk_vec2(0.5f,0.5f)));
10071  nk_draw_list_path_line_to(list, nk_vec2_sub(b,nk_vec2(0.5f,0.5f)));
10072  }
10073  nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
10074 }
10075 NK_API void
10076 nk_draw_list_fill_rect(struct nk_draw_list *list, struct nk_rect rect,
10077  struct nk_color col, float rounding)
10078 {
10079  NK_ASSERT(list);
10080  if (!list || !col.a) return;
10081 
10082  if (list->line_AA == NK_ANTI_ALIASING_ON) {
10083  nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y),
10084  nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10085  } else {
10086  nk_draw_list_path_rect_to(list, nk_vec2(rect.x-0.5f, rect.y-0.5f),
10087  nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10088  } nk_draw_list_path_fill(list, col);
10089 }
10090 NK_API void
10091 nk_draw_list_stroke_rect(struct nk_draw_list *list, struct nk_rect rect,
10092  struct nk_color col, float rounding, float thickness)
10093 {
10094  NK_ASSERT(list);
10095  if (!list || !col.a) return;
10096  if (list->line_AA == NK_ANTI_ALIASING_ON) {
10097  nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y),
10098  nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10099  } else {
10100  nk_draw_list_path_rect_to(list, nk_vec2(rect.x-0.5f, rect.y-0.5f),
10101  nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
10102  } nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10103 }
10104 NK_API void
10105 nk_draw_list_fill_rect_multi_color(struct nk_draw_list *list, struct nk_rect rect,
10106  struct nk_color left, struct nk_color top, struct nk_color right,
10107  struct nk_color bottom)
10108 {
10109  void *vtx;
10110  struct nk_colorf col_left, col_top;
10111  struct nk_colorf col_right, col_bottom;
10112  nk_draw_index *idx;
10113  nk_draw_index index;
10114 
10115  nk_color_fv(&col_left.r, left);
10116  nk_color_fv(&col_right.r, right);
10117  nk_color_fv(&col_top.r, top);
10118  nk_color_fv(&col_bottom.r, bottom);
10119 
10120  NK_ASSERT(list);
10121  if (!list) return;
10122 
10123  nk_draw_list_push_image(list, list->config.null.texture);
10124  index = (nk_draw_index)list->vertex_count;
10125  vtx = nk_draw_list_alloc_vertices(list, 4);
10126  idx = nk_draw_list_alloc_elements(list, 6);
10127  if (!vtx || !idx) return;
10128 
10129  idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
10130  idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
10131  idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
10132 
10133  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y), list->config.null.uv, col_left);
10134  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y), list->config.null.uv, col_top);
10135  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y + rect.h), list->config.null.uv, col_right);
10136  vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y + rect.h), list->config.null.uv, col_bottom);
10137 }
10138 NK_API void
10139 nk_draw_list_fill_triangle(struct nk_draw_list *list, struct nk_vec2 a,
10140  struct nk_vec2 b, struct nk_vec2 c, struct nk_color col)
10141 {
10142  NK_ASSERT(list);
10143  if (!list || !col.a) return;
10144  nk_draw_list_path_line_to(list, a);
10145  nk_draw_list_path_line_to(list, b);
10146  nk_draw_list_path_line_to(list, c);
10147  nk_draw_list_path_fill(list, col);
10148 }
10149 NK_API void
10150 nk_draw_list_stroke_triangle(struct nk_draw_list *list, struct nk_vec2 a,
10151  struct nk_vec2 b, struct nk_vec2 c, struct nk_color col, float thickness)
10152 {
10153  NK_ASSERT(list);
10154  if (!list || !col.a) return;
10155  nk_draw_list_path_line_to(list, a);
10156  nk_draw_list_path_line_to(list, b);
10157  nk_draw_list_path_line_to(list, c);
10158  nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10159 }
10160 NK_API void
10161 nk_draw_list_fill_circle(struct nk_draw_list *list, struct nk_vec2 center,
10162  float radius, struct nk_color col, unsigned int segs)
10163 {
10164  float a_max;
10165  NK_ASSERT(list);
10166  if (!list || !col.a) return;
10167  a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
10168  nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
10169  nk_draw_list_path_fill(list, col);
10170 }
10171 NK_API void
10172 nk_draw_list_stroke_circle(struct nk_draw_list *list, struct nk_vec2 center,
10173  float radius, struct nk_color col, unsigned int segs, float thickness)
10174 {
10175  float a_max;
10176  NK_ASSERT(list);
10177  if (!list || !col.a) return;
10178  a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
10179  nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
10180  nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
10181 }
10182 NK_API void
10183 nk_draw_list_stroke_curve(struct nk_draw_list *list, struct nk_vec2 p0,
10184  struct nk_vec2 cp0, struct nk_vec2 cp1, struct nk_vec2 p1,
10185  struct nk_color col, unsigned int segments, float thickness)
10186 {
10187  NK_ASSERT(list);
10188  if (!list || !col.a) return;
10189  nk_draw_list_path_line_to(list, p0);
10190  nk_draw_list_path_curve_to(list, cp0, cp1, p1, segments);
10191  nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
10192 }
10193 NK_INTERN void
10194 nk_draw_list_push_rect_uv(struct nk_draw_list *list, struct nk_vec2 a,
10195  struct nk_vec2 c, struct nk_vec2 uva, struct nk_vec2 uvc,
10196  struct nk_color color)
10197 {
10198  void *vtx;
10199  struct nk_vec2 uvb;
10200  struct nk_vec2 uvd;
10201  struct nk_vec2 b;
10202  struct nk_vec2 d;
10203 
10204  struct nk_colorf col;
10205  nk_draw_index *idx;
10206  nk_draw_index index;
10207  NK_ASSERT(list);
10208  if (!list) return;
10209 
10210  nk_color_fv(&col.r, color);
10211  uvb = nk_vec2(uvc.x, uva.y);
10212  uvd = nk_vec2(uva.x, uvc.y);
10213  b = nk_vec2(c.x, a.y);
10214  d = nk_vec2(a.x, c.y);
10215 
10216  index = (nk_draw_index)list->vertex_count;
10217  vtx = nk_draw_list_alloc_vertices(list, 4);
10218  idx = nk_draw_list_alloc_elements(list, 6);
10219  if (!vtx || !idx) return;
10220 
10221  idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
10222  idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
10223  idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
10224 
10225  vtx = nk_draw_vertex(vtx, &list->config, a, uva, col);
10226  vtx = nk_draw_vertex(vtx, &list->config, b, uvb, col);
10227  vtx = nk_draw_vertex(vtx, &list->config, c, uvc, col);
10228  vtx = nk_draw_vertex(vtx, &list->config, d, uvd, col);
10229 }
10230 NK_API void
10231 nk_draw_list_add_image(struct nk_draw_list *list, struct nk_image texture,
10232  struct nk_rect rect, struct nk_color color)
10233 {
10234  NK_ASSERT(list);
10235  if (!list) return;
10236  /* push new command with given texture */
10237  nk_draw_list_push_image(list, texture.handle);
10238  if (nk_image_is_subimage(&texture)) {
10239  /* add region inside of the texture */
10240  struct nk_vec2 uv[2];
10241  uv[0].x = (float)texture.region[0]/(float)texture.w;
10242  uv[0].y = (float)texture.region[1]/(float)texture.h;
10243  uv[1].x = (float)(texture.region[0] + texture.region[2])/(float)texture.w;
10244  uv[1].y = (float)(texture.region[1] + texture.region[3])/(float)texture.h;
10245  nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y),
10246  nk_vec2(rect.x + rect.w, rect.y + rect.h), uv[0], uv[1], color);
10247  } else nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y),
10248  nk_vec2(rect.x + rect.w, rect.y + rect.h),
10249  nk_vec2(0.0f, 0.0f), nk_vec2(1.0f, 1.0f),color);
10250 }
10251 NK_API void
10252 nk_draw_list_add_text(struct nk_draw_list *list, const struct nk_user_font *font,
10253  struct nk_rect rect, const char *text, int len, float font_height,
10254  struct nk_color fg)
10255 {
10256  float x = 0;
10257  int text_len = 0;
10258  nk_rune unicode = 0;
10259  nk_rune next = 0;
10260  int glyph_len = 0;
10261  int next_glyph_len = 0;
10262  struct nk_user_font_glyph g;
10263 
10264  NK_ASSERT(list);
10265  if (!list || !len || !text) return;
10266  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
10267  list->clip_rect.x, list->clip_rect.y, list->clip_rect.w, list->clip_rect.h)) return;
10268 
10269  nk_draw_list_push_image(list, font->texture);
10270  x = rect.x;
10271  glyph_len = nk_utf_decode(text, &unicode, len);
10272  if (!glyph_len) return;
10273 
10274  /* draw every glyph image */
10275  fg.a = (nk_byte)((float)fg.a * list->config.global_alpha);
10276  while (text_len < len && glyph_len) {
10277  float gx, gy, gh, gw;
10278  float char_width = 0;
10279  if (unicode == NK_UTF_INVALID) break;
10280 
10281  /* query currently drawn glyph information */
10282  next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (int)len - text_len);
10283  font->query(font->userdata, font_height, &g, unicode,
10284  (next == NK_UTF_INVALID) ? '\0' : next);
10285 
10286  /* calculate and draw glyph drawing rectangle and image */
10287  gx = x + g.offset.x;
10288  gy = rect.y + g.offset.y;
10289  gw = g.width; gh = g.height;
10290  char_width = g.xadvance;
10291  nk_draw_list_push_rect_uv(list, nk_vec2(gx,gy), nk_vec2(gx + gw, gy+ gh),
10292  g.uv[0], g.uv[1], fg);
10293 
10294  /* offset next glyph */
10295  text_len += glyph_len;
10296  x += char_width;
10297  glyph_len = next_glyph_len;
10298  unicode = next;
10299  }
10300 }
10301 NK_API nk_flags
10302 nk_convert(struct nk_context *ctx, struct nk_buffer *cmds,
10303  struct nk_buffer *vertices, struct nk_buffer *elements,
10304  const struct nk_convert_config *config)
10305 {
10306  nk_flags res = NK_CONVERT_SUCCESS;
10307  const struct nk_command *cmd;
10308  NK_ASSERT(ctx);
10309  NK_ASSERT(cmds);
10310  NK_ASSERT(vertices);
10311  NK_ASSERT(elements);
10312  NK_ASSERT(config);
10313  NK_ASSERT(config->vertex_layout);
10314  NK_ASSERT(config->vertex_size);
10315  if (!ctx || !cmds || !vertices || !elements || !config || !config->vertex_layout)
10316  return NK_CONVERT_INVALID_PARAM;
10317 
10318  nk_draw_list_setup(&ctx->draw_list, config, cmds, vertices, elements,
10319  config->line_AA, config->shape_AA);
10320  nk_foreach(cmd, ctx)
10321  {
10322 #ifdef NK_INCLUDE_COMMAND_USERDATA
10323  ctx->draw_list.userdata = cmd->userdata;
10324 #endif
10325  switch (cmd->type) {
10326  case NK_COMMAND_NOP: break;
10327  case NK_COMMAND_SCISSOR: {
10328  const struct nk_command_scissor *s = (const struct nk_command_scissor*)cmd;
10329  nk_draw_list_add_clip(&ctx->draw_list, nk_rect(s->x, s->y, s->w, s->h));
10330  } break;
10331  case NK_COMMAND_LINE: {
10332  const struct nk_command_line *l = (const struct nk_command_line*)cmd;
10333  nk_draw_list_stroke_line(&ctx->draw_list, nk_vec2(l->begin.x, l->begin.y),
10334  nk_vec2(l->end.x, l->end.y), l->color, l->line_thickness);
10335  } break;
10336  case NK_COMMAND_CURVE: {
10337  const struct nk_command_curve *q = (const struct nk_command_curve*)cmd;
10338  nk_draw_list_stroke_curve(&ctx->draw_list, nk_vec2(q->begin.x, q->begin.y),
10339  nk_vec2(q->ctrl[0].x, q->ctrl[0].y), nk_vec2(q->ctrl[1].x,
10340  q->ctrl[1].y), nk_vec2(q->end.x, q->end.y), q->color,
10341  config->curve_segment_count, q->line_thickness);
10342  } break;
10343  case NK_COMMAND_RECT: {
10344  const struct nk_command_rect *r = (const struct nk_command_rect*)cmd;
10345  nk_draw_list_stroke_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
10346  r->color, (float)r->rounding, r->line_thickness);
10347  } break;
10348  case NK_COMMAND_RECT_FILLED: {
10349  const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled*)cmd;
10350  nk_draw_list_fill_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
10351  r->color, (float)r->rounding);
10352  } break;
10354  const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color*)cmd;
10355  nk_draw_list_fill_rect_multi_color(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
10356  r->left, r->top, r->right, r->bottom);
10357  } break;
10358  case NK_COMMAND_CIRCLE: {
10359  const struct nk_command_circle *c = (const struct nk_command_circle*)cmd;
10360  nk_draw_list_stroke_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w/2,
10361  (float)c->y + (float)c->h/2), (float)c->w/2, c->color,
10362  config->circle_segment_count, c->line_thickness);
10363  } break;
10364  case NK_COMMAND_CIRCLE_FILLED: {
10365  const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
10366  nk_draw_list_fill_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w/2,
10367  (float)c->y + (float)c->h/2), (float)c->w/2, c->color,
10368  config->circle_segment_count);
10369  } break;
10370  case NK_COMMAND_ARC: {
10371  const struct nk_command_arc *c = (const struct nk_command_arc*)cmd;
10372  nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy));
10373  nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r,
10374  c->a[0], c->a[1], config->arc_segment_count);
10375  nk_draw_list_path_stroke(&ctx->draw_list, c->color, NK_STROKE_CLOSED, c->line_thickness);
10376  } break;
10377  case NK_COMMAND_ARC_FILLED: {
10378  const struct nk_command_arc_filled *c = (const struct nk_command_arc_filled*)cmd;
10379  nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy));
10380  nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r,
10381  c->a[0], c->a[1], config->arc_segment_count);
10382  nk_draw_list_path_fill(&ctx->draw_list, c->color);
10383  } break;
10384  case NK_COMMAND_TRIANGLE: {
10385  const struct nk_command_triangle *t = (const struct nk_command_triangle*)cmd;
10386  nk_draw_list_stroke_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y),
10387  nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color,
10388  t->line_thickness);
10389  } break;
10391  const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled*)cmd;
10392  nk_draw_list_fill_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y),
10393  nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color);
10394  } break;
10395  case NK_COMMAND_POLYGON: {
10396  int i;
10397  const struct nk_command_polygon*p = (const struct nk_command_polygon*)cmd;
10398  for (i = 0; i < p->point_count; ++i) {
10399  struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
10400  nk_draw_list_path_line_to(&ctx->draw_list, pnt);
10401  }
10402  nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_CLOSED, p->line_thickness);
10403  } break;
10405  int i;
10406  const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled*)cmd;
10407  for (i = 0; i < p->point_count; ++i) {
10408  struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
10409  nk_draw_list_path_line_to(&ctx->draw_list, pnt);
10410  }
10411  nk_draw_list_path_fill(&ctx->draw_list, p->color);
10412  } break;
10413  case NK_COMMAND_POLYLINE: {
10414  int i;
10415  const struct nk_command_polyline *p = (const struct nk_command_polyline*)cmd;
10416  for (i = 0; i < p->point_count; ++i) {
10417  struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
10418  nk_draw_list_path_line_to(&ctx->draw_list, pnt);
10419  }
10420  nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_OPEN, p->line_thickness);
10421  } break;
10422  case NK_COMMAND_TEXT: {
10423  const struct nk_command_text *t = (const struct nk_command_text*)cmd;
10424  nk_draw_list_add_text(&ctx->draw_list, t->font, nk_rect(t->x, t->y, t->w, t->h),
10425  t->string, t->length, t->height, t->foreground);
10426  } break;
10427  case NK_COMMAND_IMAGE: {
10428  const struct nk_command_image *i = (const struct nk_command_image*)cmd;
10429  nk_draw_list_add_image(&ctx->draw_list, i->img, nk_rect(i->x, i->y, i->w, i->h), i->col);
10430  } break;
10431  case NK_COMMAND_CUSTOM: {
10432  const struct nk_command_custom *c = (const struct nk_command_custom*)cmd;
10433  c->callback(&ctx->draw_list, c->x, c->y, c->w, c->h, c->callback_data);
10434  } break;
10435  default: break;
10436  }
10437  }
10438  res |= (cmds->needed > cmds->allocated + (cmds->memory.size - cmds->size)) ? NK_CONVERT_COMMAND_BUFFER_FULL: 0;
10439  res |= (vertices->needed > vertices->allocated) ? NK_CONVERT_VERTEX_BUFFER_FULL: 0;
10440  res |= (elements->needed > elements->allocated) ? NK_CONVERT_ELEMENT_BUFFER_FULL: 0;
10441  return res;
10442 }
10443 NK_API const struct nk_draw_command*
10444 nk__draw_begin(const struct nk_context *ctx,
10445  const struct nk_buffer *buffer)
10446 {
10447  return nk__draw_list_begin(&ctx->draw_list, buffer);
10448 }
10449 NK_API const struct nk_draw_command*
10450 nk__draw_end(const struct nk_context *ctx, const struct nk_buffer *buffer)
10451 {
10452  return nk__draw_list_end(&ctx->draw_list, buffer);
10453 }
10454 NK_API const struct nk_draw_command*
10455 nk__draw_next(const struct nk_draw_command *cmd,
10456  const struct nk_buffer *buffer, const struct nk_context *ctx)
10457 {
10458  return nk__draw_list_next(cmd, buffer, &ctx->draw_list);
10459 }
10460 #endif
10461 
10462 
10463 
10464 
10465 
10466 #ifdef NK_INCLUDE_FONT_BAKING
10467 /* -------------------------------------------------------------
10468  *
10469  * RECT PACK
10470  *
10471  * --------------------------------------------------------------*/
10472 /* stb_rect_pack.h - v0.05 - public domain - rectangle packing */
10473 /* Sean Barrett 2014 */
10474 #define NK_RP__MAXVAL 0xffff
10475 typedef unsigned short nk_rp_coord;
10476 
10477 struct nk_rp_rect {
10478  /* reserved for your use: */
10479  int id;
10480  /* input: */
10481  nk_rp_coord w, h;
10482  /* output: */
10483  nk_rp_coord x, y;
10484  int was_packed;
10485  /* non-zero if valid packing */
10486 }; /* 16 bytes, nominally */
10487 
10488 struct nk_rp_node {
10489  nk_rp_coord x,y;
10490  struct nk_rp_node *next;
10491 };
10492 
10493 struct nk_rp_context {
10494  int width;
10495  int height;
10496  int align;
10497  int init_mode;
10498  int heuristic;
10499  int num_nodes;
10500  struct nk_rp_node *active_head;
10501  struct nk_rp_node *free_head;
10502  struct nk_rp_node extra[2];
10503  /* we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' */
10504 };
10505 
10506 struct nk_rp__findresult {
10507  int x,y;
10508  struct nk_rp_node **prev_link;
10509 };
10510 
10511 enum NK_RP_HEURISTIC {
10512  NK_RP_HEURISTIC_Skyline_default=0,
10513  NK_RP_HEURISTIC_Skyline_BL_sortHeight = NK_RP_HEURISTIC_Skyline_default,
10514  NK_RP_HEURISTIC_Skyline_BF_sortHeight
10515 };
10516 enum NK_RP_INIT_STATE{NK_RP__INIT_skyline = 1};
10517 
10518 NK_INTERN void
10519 nk_rp_setup_allow_out_of_mem(struct nk_rp_context *context, int allow_out_of_mem)
10520 {
10521  if (allow_out_of_mem)
10522  /* if it's ok to run out of memory, then don't bother aligning them; */
10523  /* this gives better packing, but may fail due to OOM (even though */
10524  /* the rectangles easily fit). @TODO a smarter approach would be to only */
10525  /* quantize once we've hit OOM, then we could get rid of this parameter. */
10526  context->align = 1;
10527  else {
10528  /* if it's not ok to run out of memory, then quantize the widths */
10529  /* so that num_nodes is always enough nodes. */
10530  /* */
10531  /* I.e. num_nodes * align >= width */
10532  /* align >= width / num_nodes */
10533  /* align = ceil(width/num_nodes) */
10534  context->align = (context->width + context->num_nodes-1) / context->num_nodes;
10535  }
10536 }
10537 NK_INTERN void
10538 nk_rp_init_target(struct nk_rp_context *context, int width, int height,
10539  struct nk_rp_node *nodes, int num_nodes)
10540 {
10541  int i;
10542 #ifndef STBRP_LARGE_RECTS
10543  NK_ASSERT(width <= 0xffff && height <= 0xffff);
10544 #endif
10545 
10546  for (i=0; i < num_nodes-1; ++i)
10547  nodes[i].next = &nodes[i+1];
10548  nodes[i].next = 0;
10549  context->init_mode = NK_RP__INIT_skyline;
10550  context->heuristic = NK_RP_HEURISTIC_Skyline_default;
10551  context->free_head = &nodes[0];
10552  context->active_head = &context->extra[0];
10553  context->width = width;
10554  context->height = height;
10555  context->num_nodes = num_nodes;
10556  nk_rp_setup_allow_out_of_mem(context, 0);
10557 
10558  /* node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) */
10559  context->extra[0].x = 0;
10560  context->extra[0].y = 0;
10561  context->extra[0].next = &context->extra[1];
10562  context->extra[1].x = (nk_rp_coord) width;
10563  context->extra[1].y = 65535;
10564  context->extra[1].next = 0;
10565 }
10566 /* find minimum y position if it starts at x1 */
10567 NK_INTERN int
10568 nk_rp__skyline_find_min_y(struct nk_rp_context *c, struct nk_rp_node *first,
10569  int x0, int width, int *pwaste)
10570 {
10571  struct nk_rp_node *node = first;
10572  int x1 = x0 + width;
10573  int min_y, visited_width, waste_area;
10574  NK_ASSERT(first->x <= x0);
10575  NK_UNUSED(c);
10576 
10577  NK_ASSERT(node->next->x > x0);
10578  /* we ended up handling this in the caller for efficiency */
10579  NK_ASSERT(node->x <= x0);
10580 
10581  min_y = 0;
10582  waste_area = 0;
10583  visited_width = 0;
10584  while (node->x < x1)
10585  {
10586  if (node->y > min_y) {
10587  /* raise min_y higher. */
10588  /* we've accounted for all waste up to min_y, */
10589  /* but we'll now add more waste for everything we've visited */
10590  waste_area += visited_width * (node->y - min_y);
10591  min_y = node->y;
10592  /* the first time through, visited_width might be reduced */
10593  if (node->x < x0)
10594  visited_width += node->next->x - x0;
10595  else
10596  visited_width += node->next->x - node->x;
10597  } else {
10598  /* add waste area */
10599  int under_width = node->next->x - node->x;
10600  if (under_width + visited_width > width)
10601  under_width = width - visited_width;
10602  waste_area += under_width * (min_y - node->y);
10603  visited_width += under_width;
10604  }
10605  node = node->next;
10606  }
10607  *pwaste = waste_area;
10608  return min_y;
10609 }
10610 NK_INTERN struct nk_rp__findresult
10611 nk_rp__skyline_find_best_pos(struct nk_rp_context *c, int width, int height)
10612 {
10613  int best_waste = (1<<30), best_x, best_y = (1 << 30);
10614  struct nk_rp__findresult fr;
10615  struct nk_rp_node **prev, *node, *tail, **best = 0;
10616 
10617  /* align to multiple of c->align */
10618  width = (width + c->align - 1);
10619  width -= width % c->align;
10620  NK_ASSERT(width % c->align == 0);
10621 
10622  node = c->active_head;
10623  prev = &c->active_head;
10624  while (node->x + width <= c->width) {
10625  int y,waste;
10626  y = nk_rp__skyline_find_min_y(c, node, node->x, width, &waste);
10627  /* actually just want to test BL */
10628  if (c->heuristic == NK_RP_HEURISTIC_Skyline_BL_sortHeight) {
10629  /* bottom left */
10630  if (y < best_y) {
10631  best_y = y;
10632  best = prev;
10633  }
10634  } else {
10635  /* best-fit */
10636  if (y + height <= c->height) {
10637  /* can only use it if it first vertically */
10638  if (y < best_y || (y == best_y && waste < best_waste)) {
10639  best_y = y;
10640  best_waste = waste;
10641  best = prev;
10642  }
10643  }
10644  }
10645  prev = &node->next;
10646  node = node->next;
10647  }
10648  best_x = (best == 0) ? 0 : (*best)->x;
10649 
10650  /* if doing best-fit (BF), we also have to try aligning right edge to each node position */
10651  /* */
10652  /* e.g, if fitting */
10653  /* */
10654  /* ____________________ */
10655  /* |____________________| */
10656  /* */
10657  /* into */
10658  /* */
10659  /* | | */
10660  /* | ____________| */
10661  /* |____________| */
10662  /* */
10663  /* then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned */
10664  /* */
10665  /* This makes BF take about 2x the time */
10666  if (c->heuristic == NK_RP_HEURISTIC_Skyline_BF_sortHeight)
10667  {
10668  tail = c->active_head;
10669  node = c->active_head;
10670  prev = &c->active_head;
10671  /* find first node that's admissible */
10672  while (tail->x < width)
10673  tail = tail->next;
10674  while (tail)
10675  {
10676  int xpos = tail->x - width;
10677  int y,waste;
10678  NK_ASSERT(xpos >= 0);
10679  /* find the left position that matches this */
10680  while (node->next->x <= xpos) {
10681  prev = &node->next;
10682  node = node->next;
10683  }
10684  NK_ASSERT(node->next->x > xpos && node->x <= xpos);
10685  y = nk_rp__skyline_find_min_y(c, node, xpos, width, &waste);
10686  if (y + height < c->height) {
10687  if (y <= best_y) {
10688  if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
10689  best_x = xpos;
10690  NK_ASSERT(y <= best_y);
10691  best_y = y;
10692  best_waste = waste;
10693  best = prev;
10694  }
10695  }
10696  }
10697  tail = tail->next;
10698  }
10699  }
10700  fr.prev_link = best;
10701  fr.x = best_x;
10702  fr.y = best_y;
10703  return fr;
10704 }
10705 NK_INTERN struct nk_rp__findresult
10706 nk_rp__skyline_pack_rectangle(struct nk_rp_context *context, int width, int height)
10707 {
10708  /* find best position according to heuristic */
10709  struct nk_rp__findresult res = nk_rp__skyline_find_best_pos(context, width, height);
10710  struct nk_rp_node *node, *cur;
10711 
10712  /* bail if: */
10713  /* 1. it failed */
10714  /* 2. the best node doesn't fit (we don't always check this) */
10715  /* 3. we're out of memory */
10716  if (res.prev_link == 0 || res.y + height > context->height || context->free_head == 0) {
10717  res.prev_link = 0;
10718  return res;
10719  }
10720 
10721  /* on success, create new node */
10722  node = context->free_head;
10723  node->x = (nk_rp_coord) res.x;
10724  node->y = (nk_rp_coord) (res.y + height);
10725 
10726  context->free_head = node->next;
10727 
10728  /* insert the new node into the right starting point, and */
10729  /* let 'cur' point to the remaining nodes needing to be */
10730  /* stitched back in */
10731  cur = *res.prev_link;
10732  if (cur->x < res.x) {
10733  /* preserve the existing one, so start testing with the next one */
10734  struct nk_rp_node *next = cur->next;
10735  cur->next = node;
10736  cur = next;
10737  } else {
10738  *res.prev_link = node;
10739  }
10740 
10741  /* from here, traverse cur and free the nodes, until we get to one */
10742  /* that shouldn't be freed */
10743  while (cur->next && cur->next->x <= res.x + width) {
10744  struct nk_rp_node *next = cur->next;
10745  /* move the current node to the free list */
10746  cur->next = context->free_head;
10747  context->free_head = cur;
10748  cur = next;
10749  }
10750  /* stitch the list back in */
10751  node->next = cur;
10752 
10753  if (cur->x < res.x + width)
10754  cur->x = (nk_rp_coord) (res.x + width);
10755  return res;
10756 }
10757 NK_INTERN int
10758 nk_rect_height_compare(const void *a, const void *b)
10759 {
10760  const struct nk_rp_rect *p = (const struct nk_rp_rect *) a;
10761  const struct nk_rp_rect *q = (const struct nk_rp_rect *) b;
10762  if (p->h > q->h)
10763  return -1;
10764  if (p->h < q->h)
10765  return 1;
10766  return (p->w > q->w) ? -1 : (p->w < q->w);
10767 }
10768 NK_INTERN int
10769 nk_rect_original_order(const void *a, const void *b)
10770 {
10771  const struct nk_rp_rect *p = (const struct nk_rp_rect *) a;
10772  const struct nk_rp_rect *q = (const struct nk_rp_rect *) b;
10773  return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
10774 }
10775 NK_INTERN void
10776 nk_rp_qsort(struct nk_rp_rect *array, unsigned int len, int(*cmp)(const void*,const void*))
10777 {
10778  /* iterative quick sort */
10779  #define NK_MAX_SORT_STACK 64
10780  unsigned right, left = 0, stack[NK_MAX_SORT_STACK], pos = 0;
10781  unsigned seed = len/2 * 69069+1;
10782  for (;;) {
10783  for (; left+1 < len; len++) {
10784  struct nk_rp_rect pivot, tmp;
10785  if (pos == NK_MAX_SORT_STACK) len = stack[pos = 0];
10786  pivot = array[left+seed%(len-left)];
10787  seed = seed * 69069 + 1;
10788  stack[pos++] = len;
10789  for (right = left-1;;) {
10790  while (cmp(&array[++right], &pivot) < 0);
10791  while (cmp(&pivot, &array[--len]) < 0);
10792  if (right >= len) break;
10793  tmp = array[right];
10794  array[right] = array[len];
10795  array[len] = tmp;
10796  }
10797  }
10798  if (pos == 0) break;
10799  left = len;
10800  len = stack[--pos];
10801  }
10802  #undef NK_MAX_SORT_STACK
10803 }
10804 NK_INTERN void
10805 nk_rp_pack_rects(struct nk_rp_context *context, struct nk_rp_rect *rects, int num_rects)
10806 {
10807  int i;
10808  /* we use the 'was_packed' field internally to allow sorting/unsorting */
10809  for (i=0; i < num_rects; ++i) {
10810  rects[i].was_packed = i;
10811  }
10812 
10813  /* sort according to heuristic */
10814  nk_rp_qsort(rects, (unsigned)num_rects, nk_rect_height_compare);
10815 
10816  for (i=0; i < num_rects; ++i) {
10817  struct nk_rp__findresult fr = nk_rp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
10818  if (fr.prev_link) {
10819  rects[i].x = (nk_rp_coord) fr.x;
10820  rects[i].y = (nk_rp_coord) fr.y;
10821  } else {
10822  rects[i].x = rects[i].y = NK_RP__MAXVAL;
10823  }
10824  }
10825 
10826  /* unsort */
10827  nk_rp_qsort(rects, (unsigned)num_rects, nk_rect_original_order);
10828 
10829  /* set was_packed flags */
10830  for (i=0; i < num_rects; ++i)
10831  rects[i].was_packed = !(rects[i].x == NK_RP__MAXVAL && rects[i].y == NK_RP__MAXVAL);
10832 }
10833 
10834 /*
10835  * ==============================================================
10836  *
10837  * TRUETYPE
10838  *
10839  * ===============================================================
10840  */
10841 /* stb_truetype.h - v1.07 - public domain */
10842 #define NK_TT_MAX_OVERSAMPLE 8
10843 #define NK_TT__OVER_MASK (NK_TT_MAX_OVERSAMPLE-1)
10844 
10845 struct nk_tt_bakedchar {
10846  unsigned short x0,y0,x1,y1;
10847  /* coordinates of bbox in bitmap */
10848  float xoff,yoff,xadvance;
10849 };
10850 
10851 struct nk_tt_aligned_quad{
10852  float x0,y0,s0,t0; /* top-left */
10853  float x1,y1,s1,t1; /* bottom-right */
10854 };
10855 
10856 struct nk_tt_packedchar {
10857  unsigned short x0,y0,x1,y1;
10858  /* coordinates of bbox in bitmap */
10859  float xoff,yoff,xadvance;
10860  float xoff2,yoff2;
10861 };
10862 
10863 struct nk_tt_pack_range {
10864  float font_size;
10865  int first_unicode_codepoint_in_range;
10866  /* if non-zero, then the chars are continuous, and this is the first codepoint */
10867  int *array_of_unicode_codepoints;
10868  /* if non-zero, then this is an array of unicode codepoints */
10869  int num_chars;
10870  struct nk_tt_packedchar *chardata_for_range; /* output */
10871  unsigned char h_oversample, v_oversample;
10872  /* don't set these, they're used internally */
10873 };
10874 
10875 struct nk_tt_pack_context {
10876  void *pack_info;
10877  int width;
10878  int height;
10879  int stride_in_bytes;
10880  int padding;
10881  unsigned int h_oversample, v_oversample;
10882  unsigned char *pixels;
10883  void *nodes;
10884 };
10885 
10886 struct nk_tt_fontinfo {
10887  const unsigned char* data; /* pointer to .ttf file */
10888  int fontstart;/* offset of start of font */
10889  int numGlyphs;/* number of glyphs, needed for range checking */
10890  int loca,head,glyf,hhea,hmtx,kern; /* table locations as offset from start of .ttf */
10891  int index_map; /* a cmap mapping for our chosen character encoding */
10892  int indexToLocFormat; /* format needed to map from glyph index to glyph */
10893 };
10894 
10895 enum {
10896  NK_TT_vmove=1,
10897  NK_TT_vline,
10898  NK_TT_vcurve
10899 };
10900 
10901 struct nk_tt_vertex {
10902  short x,y,cx,cy;
10903  unsigned char type,padding;
10904 };
10905 
10906 struct nk_tt__bitmap{
10907  int w,h,stride;
10908  unsigned char *pixels;
10909 };
10910 
10911 struct nk_tt__hheap_chunk {
10912  struct nk_tt__hheap_chunk *next;
10913 };
10914 struct nk_tt__hheap {
10915  struct nk_allocator alloc;
10916  struct nk_tt__hheap_chunk *head;
10917  void *first_free;
10918  int num_remaining_in_head_chunk;
10919 };
10920 
10921 struct nk_tt__edge {
10922  float x0,y0, x1,y1;
10923  int invert;
10924 };
10925 
10926 struct nk_tt__active_edge {
10927  struct nk_tt__active_edge *next;
10928  float fx,fdx,fdy;
10929  float direction;
10930  float sy;
10931  float ey;
10932 };
10933 struct nk_tt__point {float x,y;};
10934 
10935 #define NK_TT_MACSTYLE_DONTCARE 0
10936 #define NK_TT_MACSTYLE_BOLD 1
10937 #define NK_TT_MACSTYLE_ITALIC 2
10938 #define NK_TT_MACSTYLE_UNDERSCORE 4
10939 #define NK_TT_MACSTYLE_NONE 8
10940 /* <= not same as 0, this makes us check the bitfield is 0 */
10941 
10942 enum { /* platformID */
10943  NK_TT_PLATFORM_ID_UNICODE =0,
10944  NK_TT_PLATFORM_ID_MAC =1,
10945  NK_TT_PLATFORM_ID_ISO =2,
10946  NK_TT_PLATFORM_ID_MICROSOFT =3
10947 };
10948 
10949 enum { /* encodingID for NK_TT_PLATFORM_ID_UNICODE */
10950  NK_TT_UNICODE_EID_UNICODE_1_0 =0,
10951  NK_TT_UNICODE_EID_UNICODE_1_1 =1,
10952  NK_TT_UNICODE_EID_ISO_10646 =2,
10953  NK_TT_UNICODE_EID_UNICODE_2_0_BMP=3,
10954  NK_TT_UNICODE_EID_UNICODE_2_0_FULL=4
10955 };
10956 
10957 enum { /* encodingID for NK_TT_PLATFORM_ID_MICROSOFT */
10958  NK_TT_MS_EID_SYMBOL =0,
10959  NK_TT_MS_EID_UNICODE_BMP =1,
10960  NK_TT_MS_EID_SHIFTJIS =2,
10961  NK_TT_MS_EID_UNICODE_FULL =10
10962 };
10963 
10964 enum { /* encodingID for NK_TT_PLATFORM_ID_MAC; same as Script Manager codes */
10965  NK_TT_MAC_EID_ROMAN =0, NK_TT_MAC_EID_ARABIC =4,
10966  NK_TT_MAC_EID_JAPANESE =1, NK_TT_MAC_EID_HEBREW =5,
10967  NK_TT_MAC_EID_CHINESE_TRAD =2, NK_TT_MAC_EID_GREEK =6,
10968  NK_TT_MAC_EID_KOREAN =3, NK_TT_MAC_EID_RUSSIAN =7
10969 };
10970 
10971 enum { /* languageID for NK_TT_PLATFORM_ID_MICROSOFT; same as LCID... */
10972  /* problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs */
10973  NK_TT_MS_LANG_ENGLISH =0x0409, NK_TT_MS_LANG_ITALIAN =0x0410,
10974  NK_TT_MS_LANG_CHINESE =0x0804, NK_TT_MS_LANG_JAPANESE =0x0411,
10975  NK_TT_MS_LANG_DUTCH =0x0413, NK_TT_MS_LANG_KOREAN =0x0412,
10976  NK_TT_MS_LANG_FRENCH =0x040c, NK_TT_MS_LANG_RUSSIAN =0x0419,
10977  NK_TT_MS_LANG_GERMAN =0x0407, NK_TT_MS_LANG_SPANISH =0x0409,
10978  NK_TT_MS_LANG_HEBREW =0x040d, NK_TT_MS_LANG_SWEDISH =0x041D
10979 };
10980 
10981 enum { /* languageID for NK_TT_PLATFORM_ID_MAC */
10982  NK_TT_MAC_LANG_ENGLISH =0 , NK_TT_MAC_LANG_JAPANESE =11,
10983  NK_TT_MAC_LANG_ARABIC =12, NK_TT_MAC_LANG_KOREAN =23,
10984  NK_TT_MAC_LANG_DUTCH =4 , NK_TT_MAC_LANG_RUSSIAN =32,
10985  NK_TT_MAC_LANG_FRENCH =1 , NK_TT_MAC_LANG_SPANISH =6 ,
10986  NK_TT_MAC_LANG_GERMAN =2 , NK_TT_MAC_LANG_SWEDISH =5 ,
10987  NK_TT_MAC_LANG_HEBREW =10, NK_TT_MAC_LANG_CHINESE_SIMPLIFIED =33,
10988  NK_TT_MAC_LANG_ITALIAN =3 , NK_TT_MAC_LANG_CHINESE_TRAD =19
10989 };
10990 
10991 #define nk_ttBYTE(p) (* (const nk_byte *) (p))
10992 #define nk_ttCHAR(p) (* (const char *) (p))
10993 
10994 #if defined(NK_BIGENDIAN) && !defined(NK_ALLOW_UNALIGNED_TRUETYPE)
10995  #define nk_ttUSHORT(p) (* (nk_ushort *) (p))
10996  #define nk_ttSHORT(p) (* (nk_short *) (p))
10997  #define nk_ttULONG(p) (* (nk_uint *) (p))
10998  #define nk_ttLONG(p) (* (nk_int *) (p))
10999 #else
11000  static nk_ushort nk_ttUSHORT(const nk_byte *p) { return (nk_ushort)(p[0]*256 + p[1]); }
11001  static nk_short nk_ttSHORT(const nk_byte *p) { return (nk_short)(p[0]*256 + p[1]); }
11002  static nk_uint nk_ttULONG(const nk_byte *p) { return (nk_uint)((p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]); }
11003 #endif
11004 
11005 #define nk_tt_tag4(p,c0,c1,c2,c3)\
11006  ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
11007 #define nk_tt_tag(p,str) nk_tt_tag4(p,str[0],str[1],str[2],str[3])
11008 
11009 NK_INTERN int nk_tt_GetGlyphShape(const struct nk_tt_fontinfo *info, struct nk_allocator *alloc,
11010  int glyph_index, struct nk_tt_vertex **pvertices);
11011 
11012 NK_INTERN nk_uint
11013 nk_tt__find_table(const nk_byte *data, nk_uint fontstart, const char *tag)
11014 {
11015  /* @OPTIMIZE: binary search */
11016  nk_int num_tables = nk_ttUSHORT(data+fontstart+4);
11017  nk_uint tabledir = fontstart + 12;
11018  nk_int i;
11019  for (i = 0; i < num_tables; ++i) {
11020  nk_uint loc = tabledir + (nk_uint)(16*i);
11021  if (nk_tt_tag(data+loc+0, tag))
11022  return nk_ttULONG(data+loc+8);
11023  }
11024  return 0;
11025 }
11026 NK_INTERN int
11027 nk_tt_InitFont(struct nk_tt_fontinfo *info, const unsigned char *data2, int fontstart)
11028 {
11029  nk_uint cmap, t;
11030  nk_int i,numTables;
11031  const nk_byte *data = (const nk_byte *) data2;
11032 
11033  info->data = data;
11034  info->fontstart = fontstart;
11035 
11036  cmap = nk_tt__find_table(data, (nk_uint)fontstart, "cmap"); /* required */
11037  info->loca = (int)nk_tt__find_table(data, (nk_uint)fontstart, "loca"); /* required */
11038  info->head = (int)nk_tt__find_table(data, (nk_uint)fontstart, "head"); /* required */
11039  info->glyf = (int)nk_tt__find_table(data, (nk_uint)fontstart, "glyf"); /* required */
11040  info->hhea = (int)nk_tt__find_table(data, (nk_uint)fontstart, "hhea"); /* required */
11041  info->hmtx = (int)nk_tt__find_table(data, (nk_uint)fontstart, "hmtx"); /* required */
11042  info->kern = (int)nk_tt__find_table(data, (nk_uint)fontstart, "kern"); /* not required */
11043  if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx)
11044  return 0;
11045 
11046  t = nk_tt__find_table(data, (nk_uint)fontstart, "maxp");
11047  if (t) info->numGlyphs = nk_ttUSHORT(data+t+4);
11048  else info->numGlyphs = 0xffff;
11049 
11050  /* find a cmap encoding table we understand *now* to avoid searching */
11051  /* later. (todo: could make this installable) */
11052  /* the same regardless of glyph. */
11053  numTables = nk_ttUSHORT(data + cmap + 2);
11054  info->index_map = 0;
11055  for (i=0; i < numTables; ++i)
11056  {
11057  nk_uint encoding_record = cmap + 4 + 8 * (nk_uint)i;
11058  /* find an encoding we understand: */
11059  switch(nk_ttUSHORT(data+encoding_record)) {
11060  case NK_TT_PLATFORM_ID_MICROSOFT:
11061  switch (nk_ttUSHORT(data+encoding_record+2)) {
11062  case NK_TT_MS_EID_UNICODE_BMP:
11063  case NK_TT_MS_EID_UNICODE_FULL:
11064  /* MS/Unicode */
11065  info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4));
11066  break;
11067  default: break;
11068  } break;
11069  case NK_TT_PLATFORM_ID_UNICODE:
11070  /* Mac/iOS has these */
11071  /* all the encodingIDs are unicode, so we don't bother to check it */
11072  info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4));
11073  break;
11074  default: break;
11075  }
11076  }
11077  if (info->index_map == 0)
11078  return 0;
11079  info->indexToLocFormat = nk_ttUSHORT(data+info->head + 50);
11080  return 1;
11081 }
11082 NK_INTERN int
11083 nk_tt_FindGlyphIndex(const struct nk_tt_fontinfo *info, int unicode_codepoint)
11084 {
11085  const nk_byte *data = info->data;
11086  nk_uint index_map = (nk_uint)info->index_map;
11087 
11088  nk_ushort format = nk_ttUSHORT(data + index_map + 0);
11089  if (format == 0) { /* apple byte encoding */
11090  nk_int bytes = nk_ttUSHORT(data + index_map + 2);
11091  if (unicode_codepoint < bytes-6)
11092  return nk_ttBYTE(data + index_map + 6 + unicode_codepoint);
11093  return 0;
11094  } else if (format == 6) {
11095  nk_uint first = nk_ttUSHORT(data + index_map + 6);
11096  nk_uint count = nk_ttUSHORT(data + index_map + 8);
11097  if ((nk_uint) unicode_codepoint >= first && (nk_uint) unicode_codepoint < first+count)
11098  return nk_ttUSHORT(data + index_map + 10 + (unicode_codepoint - (int)first)*2);
11099  return 0;
11100  } else if (format == 2) {
11101  NK_ASSERT(0); /* @TODO: high-byte mapping for japanese/chinese/korean */
11102  return 0;
11103  } else if (format == 4) { /* standard mapping for windows fonts: binary search collection of ranges */
11104  nk_ushort segcount = nk_ttUSHORT(data+index_map+6) >> 1;
11105  nk_ushort searchRange = nk_ttUSHORT(data+index_map+8) >> 1;
11106  nk_ushort entrySelector = nk_ttUSHORT(data+index_map+10);
11107  nk_ushort rangeShift = nk_ttUSHORT(data+index_map+12) >> 1;
11108 
11109  /* do a binary search of the segments */
11110  nk_uint endCount = index_map + 14;
11111  nk_uint search = endCount;
11112 
11113  if (unicode_codepoint > 0xffff)
11114  return 0;
11115 
11116  /* they lie from endCount .. endCount + segCount */
11117  /* but searchRange is the nearest power of two, so... */
11118  if (unicode_codepoint >= nk_ttUSHORT(data + search + rangeShift*2))
11119  search += (nk_uint)(rangeShift*2);
11120 
11121  /* now decrement to bias correctly to find smallest */
11122  search -= 2;
11123  while (entrySelector) {
11124  nk_ushort end;
11125  searchRange >>= 1;
11126  end = nk_ttUSHORT(data + search + searchRange*2);
11127  if (unicode_codepoint > end)
11128  search += (nk_uint)(searchRange*2);
11129  --entrySelector;
11130  }
11131  search += 2;
11132 
11133  {
11134  nk_ushort offset, start;
11135  nk_ushort item = (nk_ushort) ((search - endCount) >> 1);
11136 
11137  NK_ASSERT(unicode_codepoint <= nk_ttUSHORT(data + endCount + 2*item));
11138  start = nk_ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
11139  if (unicode_codepoint < start)
11140  return 0;
11141 
11142  offset = nk_ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
11143  if (offset == 0)
11144  return (nk_ushort) (unicode_codepoint + nk_ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
11145 
11146  return nk_ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
11147  }
11148  } else if (format == 12 || format == 13) {
11149  nk_uint ngroups = nk_ttULONG(data+index_map+12);
11150  nk_int low,high;
11151  low = 0; high = (nk_int)ngroups;
11152  /* Binary search the right group. */
11153  while (low < high) {
11154  nk_int mid = low + ((high-low) >> 1); /* rounds down, so low <= mid < high */
11155  nk_uint start_char = nk_ttULONG(data+index_map+16+mid*12);
11156  nk_uint end_char = nk_ttULONG(data+index_map+16+mid*12+4);
11157  if ((nk_uint) unicode_codepoint < start_char)
11158  high = mid;
11159  else if ((nk_uint) unicode_codepoint > end_char)
11160  low = mid+1;
11161  else {
11162  nk_uint start_glyph = nk_ttULONG(data+index_map+16+mid*12+8);
11163  if (format == 12)
11164  return (int)start_glyph + (int)unicode_codepoint - (int)start_char;
11165  else /* format == 13 */
11166  return (int)start_glyph;
11167  }
11168  }
11169  return 0; /* not found */
11170  }
11171  /* @TODO */
11172  NK_ASSERT(0);
11173  return 0;
11174 }
11175 NK_INTERN void
11176 nk_tt_setvertex(struct nk_tt_vertex *v, nk_byte type, nk_int x, nk_int y, nk_int cx, nk_int cy)
11177 {
11178  v->type = type;
11179  v->x = (nk_short) x;
11180  v->y = (nk_short) y;
11181  v->cx = (nk_short) cx;
11182  v->cy = (nk_short) cy;
11183 }
11184 NK_INTERN int
11185 nk_tt__GetGlyfOffset(const struct nk_tt_fontinfo *info, int glyph_index)
11186 {
11187  int g1,g2;
11188  if (glyph_index >= info->numGlyphs) return -1; /* glyph index out of range */
11189  if (info->indexToLocFormat >= 2) return -1; /* unknown index->glyph map format */
11190 
11191  if (info->indexToLocFormat == 0) {
11192  g1 = info->glyf + nk_ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
11193  g2 = info->glyf + nk_ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
11194  } else {
11195  g1 = info->glyf + (int)nk_ttULONG (info->data + info->loca + glyph_index * 4);
11196  g2 = info->glyf + (int)nk_ttULONG (info->data + info->loca + glyph_index * 4 + 4);
11197  }
11198  return g1==g2 ? -1 : g1; /* if length is 0, return -1 */
11199 }
11200 NK_INTERN int
11201 nk_tt_GetGlyphBox(const struct nk_tt_fontinfo *info, int glyph_index,
11202  int *x0, int *y0, int *x1, int *y1)
11203 {
11204  int g = nk_tt__GetGlyfOffset(info, glyph_index);
11205  if (g < 0) return 0;
11206 
11207  if (x0) *x0 = nk_ttSHORT(info->data + g + 2);
11208  if (y0) *y0 = nk_ttSHORT(info->data + g + 4);
11209  if (x1) *x1 = nk_ttSHORT(info->data + g + 6);
11210  if (y1) *y1 = nk_ttSHORT(info->data + g + 8);
11211  return 1;
11212 }
11213 NK_INTERN int
11214 nk_tt__close_shape(struct nk_tt_vertex *vertices, int num_vertices, int was_off,
11215  int start_off, nk_int sx, nk_int sy, nk_int scx, nk_int scy, nk_int cx, nk_int cy)
11216 {
11217  if (start_off) {
11218  if (was_off)
11219  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
11220  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, sx,sy,scx,scy);
11221  } else {
11222  if (was_off)
11223  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve,sx,sy,cx,cy);
11224  else
11225  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vline,sx,sy,0,0);
11226  }
11227  return num_vertices;
11228 }
11229 NK_INTERN int
11230 nk_tt_GetGlyphShape(const struct nk_tt_fontinfo *info, struct nk_allocator *alloc,
11231  int glyph_index, struct nk_tt_vertex **pvertices)
11232 {
11233  nk_short numberOfContours;
11234  const nk_byte *endPtsOfContours;
11235  const nk_byte *data = info->data;
11236  struct nk_tt_vertex *vertices=0;
11237  int num_vertices=0;
11238  int g = nk_tt__GetGlyfOffset(info, glyph_index);
11239  *pvertices = 0;
11240 
11241  if (g < 0) return 0;
11242  numberOfContours = nk_ttSHORT(data + g);
11243  if (numberOfContours > 0) {
11244  nk_byte flags=0,flagcount;
11245  nk_int ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
11246  nk_int x,y,cx,cy,sx,sy, scx,scy;
11247  const nk_byte *points;
11248  endPtsOfContours = (data + g + 10);
11249  ins = nk_ttUSHORT(data + g + 10 + numberOfContours * 2);
11250  points = data + g + 10 + numberOfContours * 2 + 2 + ins;
11251 
11252  n = 1+nk_ttUSHORT(endPtsOfContours + numberOfContours*2-2);
11253  m = n + 2*numberOfContours; /* a loose bound on how many vertices we might need */
11254  vertices = (struct nk_tt_vertex *)alloc->alloc(alloc->userdata, 0, (nk_size)m * sizeof(vertices[0]));
11255  if (vertices == 0)
11256  return 0;
11257 
11258  next_move = 0;
11259  flagcount=0;
11260 
11261  /* in first pass, we load uninterpreted data into the allocated array */
11262  /* above, shifted to the end of the array so we won't overwrite it when */
11263  /* we create our final data starting from the front */
11264  off = m - n; /* starting offset for uninterpreted data, regardless of how m ends up being calculated */
11265 
11266  /* first load flags */
11267  for (i=0; i < n; ++i) {
11268  if (flagcount == 0) {
11269  flags = *points++;
11270  if (flags & 8)
11271  flagcount = *points++;
11272  } else --flagcount;
11273  vertices[off+i].type = flags;
11274  }
11275 
11276  /* now load x coordinates */
11277  x=0;
11278  for (i=0; i < n; ++i) {
11279  flags = vertices[off+i].type;
11280  if (flags & 2) {
11281  nk_short dx = *points++;
11282  x += (flags & 16) ? dx : -dx; /* ??? */
11283  } else {
11284  if (!(flags & 16)) {
11285  x = x + (nk_short) (points[0]*256 + points[1]);
11286  points += 2;
11287  }
11288  }
11289  vertices[off+i].x = (nk_short) x;
11290  }
11291 
11292  /* now load y coordinates */
11293  y=0;
11294  for (i=0; i < n; ++i) {
11295  flags = vertices[off+i].type;
11296  if (flags & 4) {
11297  nk_short dy = *points++;
11298  y += (flags & 32) ? dy : -dy; /* ??? */
11299  } else {
11300  if (!(flags & 32)) {
11301  y = y + (nk_short) (points[0]*256 + points[1]);
11302  points += 2;
11303  }
11304  }
11305  vertices[off+i].y = (nk_short) y;
11306  }
11307 
11308  /* now convert them to our format */
11309  num_vertices=0;
11310  sx = sy = cx = cy = scx = scy = 0;
11311  for (i=0; i < n; ++i)
11312  {
11313  flags = vertices[off+i].type;
11314  x = (nk_short) vertices[off+i].x;
11315  y = (nk_short) vertices[off+i].y;
11316 
11317  if (next_move == i) {
11318  if (i != 0)
11319  num_vertices = nk_tt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
11320 
11321  /* now start the new one */
11322  start_off = !(flags & 1);
11323  if (start_off) {
11324  /* if we start off with an off-curve point, then when we need to find a point on the curve */
11325  /* where we can start, and we need to save some state for when we wraparound. */
11326  scx = x;
11327  scy = y;
11328  if (!(vertices[off+i+1].type & 1)) {
11329  /* next point is also a curve point, so interpolate an on-point curve */
11330  sx = (x + (nk_int) vertices[off+i+1].x) >> 1;
11331  sy = (y + (nk_int) vertices[off+i+1].y) >> 1;
11332  } else {
11333  /* otherwise just use the next point as our start point */
11334  sx = (nk_int) vertices[off+i+1].x;
11335  sy = (nk_int) vertices[off+i+1].y;
11336  ++i; /* we're using point i+1 as the starting point, so skip it */
11337  }
11338  } else {
11339  sx = x;
11340  sy = y;
11341  }
11342  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vmove,sx,sy,0,0);
11343  was_off = 0;
11344  next_move = 1 + nk_ttUSHORT(endPtsOfContours+j*2);
11345  ++j;
11346  } else {
11347  if (!(flags & 1))
11348  { /* if it's a curve */
11349  if (was_off) /* two off-curve control points in a row means interpolate an on-curve midpoint */
11350  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
11351  cx = x;
11352  cy = y;
11353  was_off = 1;
11354  } else {
11355  if (was_off)
11356  nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, x,y, cx, cy);
11357  else nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vline, x,y,0,0);
11358  was_off = 0;
11359  }
11360  }
11361  }
11362  num_vertices = nk_tt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
11363  } else if (numberOfContours == -1) {
11364  /* Compound shapes. */
11365  int more = 1;
11366  const nk_byte *comp = data + g + 10;
11367  num_vertices = 0;
11368  vertices = 0;
11369 
11370  while (more)
11371  {
11372  nk_ushort flags, gidx;
11373  int comp_num_verts = 0, i;
11374  struct nk_tt_vertex *comp_verts = 0, *tmp = 0;
11375  float mtx[6] = {1,0,0,1,0,0}, m, n;
11376 
11377  flags = (nk_ushort)nk_ttSHORT(comp); comp+=2;
11378  gidx = (nk_ushort)nk_ttSHORT(comp); comp+=2;
11379 
11380  if (flags & 2) { /* XY values */
11381  if (flags & 1) { /* shorts */
11382  mtx[4] = nk_ttSHORT(comp); comp+=2;
11383  mtx[5] = nk_ttSHORT(comp); comp+=2;
11384  } else {
11385  mtx[4] = nk_ttCHAR(comp); comp+=1;
11386  mtx[5] = nk_ttCHAR(comp); comp+=1;
11387  }
11388  } else {
11389  /* @TODO handle matching point */
11390  NK_ASSERT(0);
11391  }
11392  if (flags & (1<<3)) { /* WE_HAVE_A_SCALE */
11393  mtx[0] = mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11394  mtx[1] = mtx[2] = 0;
11395  } else if (flags & (1<<6)) { /* WE_HAVE_AN_X_AND_YSCALE */
11396  mtx[0] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11397  mtx[1] = mtx[2] = 0;
11398  mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11399  } else if (flags & (1<<7)) { /* WE_HAVE_A_TWO_BY_TWO */
11400  mtx[0] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11401  mtx[1] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11402  mtx[2] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11403  mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
11404  }
11405 
11406  /* Find transformation scales. */
11407  m = (float) NK_SQRT(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
11408  n = (float) NK_SQRT(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
11409 
11410  /* Get indexed glyph. */
11411  comp_num_verts = nk_tt_GetGlyphShape(info, alloc, gidx, &comp_verts);
11412  if (comp_num_verts > 0)
11413  {
11414  /* Transform vertices. */
11415  for (i = 0; i < comp_num_verts; ++i) {
11416  struct nk_tt_vertex* v = &comp_verts[i];
11417  short x,y;
11418  x=v->x; y=v->y;
11419  v->x = (short)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
11420  v->y = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
11421  x=v->cx; y=v->cy;
11422  v->cx = (short)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
11423  v->cy = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
11424  }
11425  /* Append vertices. */
11426  tmp = (struct nk_tt_vertex*)alloc->alloc(alloc->userdata, 0,
11427  (nk_size)(num_vertices+comp_num_verts)*sizeof(struct nk_tt_vertex));
11428  if (!tmp) {
11429  if (vertices) alloc->free(alloc->userdata, vertices);
11430  if (comp_verts) alloc->free(alloc->userdata, comp_verts);
11431  return 0;
11432  }
11433  if (num_vertices > 0) NK_MEMCPY(tmp, vertices, (nk_size)num_vertices*sizeof(struct nk_tt_vertex));
11434  NK_MEMCPY(tmp+num_vertices, comp_verts, (nk_size)comp_num_verts*sizeof(struct nk_tt_vertex));
11435  if (vertices) alloc->free(alloc->userdata,vertices);
11436  vertices = tmp;
11437  alloc->free(alloc->userdata,comp_verts);
11438  num_vertices += comp_num_verts;
11439  }
11440  /* More components ? */
11441  more = flags & (1<<5);
11442  }
11443  } else if (numberOfContours < 0) {
11444  /* @TODO other compound variations? */
11445  NK_ASSERT(0);
11446  } else {
11447  /* numberOfCounters == 0, do nothing */
11448  }
11449  *pvertices = vertices;
11450  return num_vertices;
11451 }
11452 NK_INTERN void
11453 nk_tt_GetGlyphHMetrics(const struct nk_tt_fontinfo *info, int glyph_index,
11454  int *advanceWidth, int *leftSideBearing)
11455 {
11456  nk_ushort numOfLongHorMetrics = nk_ttUSHORT(info->data+info->hhea + 34);
11457  if (glyph_index < numOfLongHorMetrics) {
11458  if (advanceWidth)
11459  *advanceWidth = nk_ttSHORT(info->data + info->hmtx + 4*glyph_index);
11460  if (leftSideBearing)
11461  *leftSideBearing = nk_ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
11462  } else {
11463  if (advanceWidth)
11464  *advanceWidth = nk_ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
11465  if (leftSideBearing)
11466  *leftSideBearing = nk_ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
11467  }
11468 }
11469 NK_INTERN void
11470 nk_tt_GetFontVMetrics(const struct nk_tt_fontinfo *info,
11471  int *ascent, int *descent, int *lineGap)
11472 {
11473  if (ascent ) *ascent = nk_ttSHORT(info->data+info->hhea + 4);
11474  if (descent) *descent = nk_ttSHORT(info->data+info->hhea + 6);
11475  if (lineGap) *lineGap = nk_ttSHORT(info->data+info->hhea + 8);
11476 }
11477 NK_INTERN float
11478 nk_tt_ScaleForPixelHeight(const struct nk_tt_fontinfo *info, float height)
11479 {
11480  int fheight = nk_ttSHORT(info->data + info->hhea + 4) - nk_ttSHORT(info->data + info->hhea + 6);
11481  return (float) height / (float)fheight;
11482 }
11483 NK_INTERN float
11484 nk_tt_ScaleForMappingEmToPixels(const struct nk_tt_fontinfo *info, float pixels)
11485 {
11486  int unitsPerEm = nk_ttUSHORT(info->data + info->head + 18);
11487  return pixels / (float)unitsPerEm;
11488 }
11489 
11490 /*-------------------------------------------------------------
11491  * antialiasing software rasterizer
11492  * --------------------------------------------------------------*/
11493 NK_INTERN void
11494 nk_tt_GetGlyphBitmapBoxSubpixel(const struct nk_tt_fontinfo *font,
11495  int glyph, float scale_x, float scale_y,float shift_x, float shift_y,
11496  int *ix0, int *iy0, int *ix1, int *iy1)
11497 {
11498  int x0,y0,x1,y1;
11499  if (!nk_tt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
11500  /* e.g. space character */
11501  if (ix0) *ix0 = 0;
11502  if (iy0) *iy0 = 0;
11503  if (ix1) *ix1 = 0;
11504  if (iy1) *iy1 = 0;
11505  } else {
11506  /* move to integral bboxes (treating pixels as little squares, what pixels get touched)? */
11507  if (ix0) *ix0 = nk_ifloorf((float)x0 * scale_x + shift_x);
11508  if (iy0) *iy0 = nk_ifloorf((float)-y1 * scale_y + shift_y);
11509  if (ix1) *ix1 = nk_iceilf ((float)x1 * scale_x + shift_x);
11510  if (iy1) *iy1 = nk_iceilf ((float)-y0 * scale_y + shift_y);
11511  }
11512 }
11513 NK_INTERN void
11514 nk_tt_GetGlyphBitmapBox(const struct nk_tt_fontinfo *font, int glyph,
11515  float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
11516 {
11517  nk_tt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
11518 }
11519 
11520 /*-------------------------------------------------------------
11521  * Rasterizer
11522  * --------------------------------------------------------------*/
11523 NK_INTERN void*
11524 nk_tt__hheap_alloc(struct nk_tt__hheap *hh, nk_size size)
11525 {
11526  if (hh->first_free) {
11527  void *p = hh->first_free;
11528  hh->first_free = * (void **) p;
11529  return p;
11530  } else {
11531  if (hh->num_remaining_in_head_chunk == 0) {
11532  int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
11533  struct nk_tt__hheap_chunk *c = (struct nk_tt__hheap_chunk *)
11534  hh->alloc.alloc(hh->alloc.userdata, 0,
11535  sizeof(struct nk_tt__hheap_chunk) + size * (nk_size)count);
11536  if (c == 0) return 0;
11537  c->next = hh->head;
11538  hh->head = c;
11539  hh->num_remaining_in_head_chunk = count;
11540  }
11541  --hh->num_remaining_in_head_chunk;
11542  return (char *) (hh->head) + size * (nk_size)hh->num_remaining_in_head_chunk;
11543  }
11544 }
11545 NK_INTERN void
11546 nk_tt__hheap_free(struct nk_tt__hheap *hh, void *p)
11547 {
11548  *(void **) p = hh->first_free;
11549  hh->first_free = p;
11550 }
11551 NK_INTERN void
11552 nk_tt__hheap_cleanup(struct nk_tt__hheap *hh)
11553 {
11554  struct nk_tt__hheap_chunk *c = hh->head;
11555  while (c) {
11556  struct nk_tt__hheap_chunk *n = c->next;
11557  hh->alloc.free(hh->alloc.userdata, c);
11558  c = n;
11559  }
11560 }
11561 NK_INTERN struct nk_tt__active_edge*
11562 nk_tt__new_active(struct nk_tt__hheap *hh, struct nk_tt__edge *e,
11563  int off_x, float start_point)
11564 {
11565  struct nk_tt__active_edge *z = (struct nk_tt__active_edge *)
11566  nk_tt__hheap_alloc(hh, sizeof(*z));
11567  float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
11568  /*STBTT_assert(e->y0 <= start_point); */
11569  if (!z) return z;
11570  z->fdx = dxdy;
11571  z->fdy = (dxdy != 0) ? (1/dxdy): 0;
11572  z->fx = e->x0 + dxdy * (start_point - e->y0);
11573  z->fx -= (float)off_x;
11574  z->direction = e->invert ? 1.0f : -1.0f;
11575  z->sy = e->y0;
11576  z->ey = e->y1;
11577  z->next = 0;
11578  return z;
11579 }
11580 NK_INTERN void
11581 nk_tt__handle_clipped_edge(float *scanline, int x, struct nk_tt__active_edge *e,
11582  float x0, float y0, float x1, float y1)
11583 {
11584  if (y0 == y1) return;
11585  NK_ASSERT(y0 < y1);
11586  NK_ASSERT(e->sy <= e->ey);
11587  if (y0 > e->ey) return;
11588  if (y1 < e->sy) return;
11589  if (y0 < e->sy) {
11590  x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
11591  y0 = e->sy;
11592  }
11593  if (y1 > e->ey) {
11594  x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
11595  y1 = e->ey;
11596  }
11597 
11598  if (x0 == x) NK_ASSERT(x1 <= x+1);
11599  else if (x0 == x+1) NK_ASSERT(x1 >= x);
11600  else if (x0 <= x) NK_ASSERT(x1 <= x);
11601  else if (x0 >= x+1) NK_ASSERT(x1 >= x+1);
11602  else NK_ASSERT(x1 >= x && x1 <= x+1);
11603 
11604  if (x0 <= x && x1 <= x)
11605  scanline[x] += e->direction * (y1-y0);
11606  else if (x0 >= x+1 && x1 >= x+1);
11607  else {
11608  NK_ASSERT(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
11609  /* coverage = 1 - average x position */
11610  scanline[x] += (float)e->direction * (float)(y1-y0) * (1.0f-((x0-(float)x)+(x1-(float)x))/2.0f);
11611  }
11612 }
11613 NK_INTERN void
11614 nk_tt__fill_active_edges_new(float *scanline, float *scanline_fill, int len,
11615  struct nk_tt__active_edge *e, float y_top)
11616 {
11617  float y_bottom = y_top+1;
11618  while (e)
11619  {
11620  /* brute force every pixel */
11621  /* compute intersection points with top & bottom */
11622  NK_ASSERT(e->ey >= y_top);
11623  if (e->fdx == 0) {
11624  float x0 = e->fx;
11625  if (x0 < len) {
11626  if (x0 >= 0) {
11627  nk_tt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom);
11628  nk_tt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom);
11629  } else {
11630  nk_tt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
11631  }
11632  }
11633  } else {
11634  float x0 = e->fx;
11635  float dx = e->fdx;
11636  float xb = x0 + dx;
11637  float x_top, x_bottom;
11638  float y0,y1;
11639  float dy = e->fdy;
11640  NK_ASSERT(e->sy <= y_bottom && e->ey >= y_top);
11641 
11642  /* compute endpoints of line segment clipped to this scanline (if the */
11643  /* line segment starts on this scanline. x0 is the intersection of the */
11644  /* line with y_top, but that may be off the line segment. */
11645  if (e->sy > y_top) {
11646  x_top = x0 + dx * (e->sy - y_top);
11647  y0 = e->sy;
11648  } else {
11649  x_top = x0;
11650  y0 = y_top;
11651  }
11652 
11653  if (e->ey < y_bottom) {
11654  x_bottom = x0 + dx * (e->ey - y_top);
11655  y1 = e->ey;
11656  } else {
11657  x_bottom = xb;
11658  y1 = y_bottom;
11659  }
11660 
11661  if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len)
11662  {
11663  /* from here on, we don't have to range check x values */
11664  if ((int) x_top == (int) x_bottom) {
11665  float height;
11666  /* simple case, only spans one pixel */
11667  int x = (int) x_top;
11668  height = y1 - y0;
11669  NK_ASSERT(x >= 0 && x < len);
11670  scanline[x] += e->direction * (1.0f-(((float)x_top - (float)x) + ((float)x_bottom-(float)x))/2.0f) * (float)height;
11671  scanline_fill[x] += e->direction * (float)height; /* everything right of this pixel is filled */
11672  } else {
11673  int x,x1,x2;
11674  float y_crossing, step, sign, area;
11675  /* covers 2+ pixels */
11676  if (x_top > x_bottom)
11677  {
11678  /* flip scanline vertically; signed area is the same */
11679  float t;
11680  y0 = y_bottom - (y0 - y_top);
11681  y1 = y_bottom - (y1 - y_top);
11682  t = y0; y0 = y1; y1 = t;
11683  t = x_bottom; x_bottom = x_top; x_top = t;
11684  dx = -dx;
11685  dy = -dy;
11686  t = x0; x0 = xb; xb = t;
11687  }
11688 
11689  x1 = (int) x_top;
11690  x2 = (int) x_bottom;
11691  /* compute intersection with y axis at x1+1 */
11692  y_crossing = ((float)x1+1 - (float)x0) * (float)dy + (float)y_top;
11693 
11694  sign = e->direction;
11695  /* area of the rectangle covered from y0..y_crossing */
11696  area = sign * (y_crossing-y0);
11697  /* area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) */
11698  scanline[x1] += area * (1.0f-((float)((float)x_top - (float)x1)+(float)(x1+1-x1))/2.0f);
11699 
11700  step = sign * dy;
11701  for (x = x1+1; x < x2; ++x) {
11702  scanline[x] += area + step/2;
11703  area += step;
11704  }
11705  y_crossing += (float)dy * (float)(x2 - (x1+1));
11706 
11707  scanline[x2] += area + sign * (1.0f-((float)(x2-x2)+((float)x_bottom-(float)x2))/2.0f) * (y1-y_crossing);
11708  scanline_fill[x2] += sign * (y1-y0);
11709  }
11710  }
11711  else
11712  {
11713  /* if edge goes outside of box we're drawing, we require */
11714  /* clipping logic. since this does not match the intended use */
11715  /* of this library, we use a different, very slow brute */
11716  /* force implementation */
11717  int x;
11718  for (x=0; x < len; ++x)
11719  {
11720  /* cases: */
11721  /* */
11722  /* there can be up to two intersections with the pixel. any intersection */
11723  /* with left or right edges can be handled by splitting into two (or three) */
11724  /* regions. intersections with top & bottom do not necessitate case-wise logic. */
11725  /* */
11726  /* the old way of doing this found the intersections with the left & right edges, */
11727  /* then used some simple logic to produce up to three segments in sorted order */
11728  /* from top-to-bottom. however, this had a problem: if an x edge was epsilon */
11729  /* across the x border, then the corresponding y position might not be distinct */
11730  /* from the other y segment, and it might ignored as an empty segment. to avoid */
11731  /* that, we need to explicitly produce segments based on x positions. */
11732 
11733  /* rename variables to clear pairs */
11734  float ya = y_top;
11735  float x1 = (float) (x);
11736  float x2 = (float) (x+1);
11737  float x3 = xb;
11738  float y3 = y_bottom;
11739  float yb,y2;
11740 
11741  yb = ((float)x - x0) / dx + y_top;
11742  y2 = ((float)x+1 - x0) / dx + y_top;
11743 
11744  if (x0 < x1 && x3 > x2) { /* three segments descending down-right */
11745  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
11746  nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x2,y2);
11747  nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
11748  } else if (x3 < x1 && x0 > x2) { /* three segments descending down-left */
11749  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
11750  nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x1,yb);
11751  nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
11752  } else if (x0 < x1 && x3 > x1) { /* two segments across x, down-right */
11753  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
11754  nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
11755  } else if (x3 < x1 && x0 > x1) { /* two segments across x, down-left */
11756  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
11757  nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
11758  } else if (x0 < x2 && x3 > x2) { /* two segments across x+1, down-right */
11759  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
11760  nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
11761  } else if (x3 < x2 && x0 > x2) { /* two segments across x+1, down-left */
11762  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
11763  nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
11764  } else { /* one segment */
11765  nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x3,y3);
11766  }
11767  }
11768  }
11769  }
11770  e = e->next;
11771  }
11772 }
11773 NK_INTERN void
11774 nk_tt__rasterize_sorted_edges(struct nk_tt__bitmap *result, struct nk_tt__edge *e,
11775  int n, int vsubsample, int off_x, int off_y, struct nk_allocator *alloc)
11776 {
11777  /* directly AA rasterize edges w/o supersampling */
11778  struct nk_tt__hheap hh;
11779  struct nk_tt__active_edge *active = 0;
11780  int y,j=0, i;
11781  float scanline_data[129], *scanline, *scanline2;
11782 
11783  NK_UNUSED(vsubsample);
11784  nk_zero_struct(hh);
11785  hh.alloc = *alloc;
11786 
11787  if (result->w > 64)
11788  scanline = (float *) alloc->alloc(alloc->userdata,0, (nk_size)(result->w*2+1) * sizeof(float));
11789  else scanline = scanline_data;
11790 
11791  scanline2 = scanline + result->w;
11792  y = off_y;
11793  e[n].y0 = (float) (off_y + result->h) + 1;
11794 
11795  while (j < result->h)
11796  {
11797  /* find center of pixel for this scanline */
11798  float scan_y_top = (float)y + 0.0f;
11799  float scan_y_bottom = (float)y + 1.0f;
11800  struct nk_tt__active_edge **step = &active;
11801 
11802  NK_MEMSET(scanline , 0, (nk_size)result->w*sizeof(scanline[0]));
11803  NK_MEMSET(scanline2, 0, (nk_size)(result->w+1)*sizeof(scanline[0]));
11804 
11805  /* update all active edges; */
11806  /* remove all active edges that terminate before the top of this scanline */
11807  while (*step) {
11808  struct nk_tt__active_edge * z = *step;
11809  if (z->ey <= scan_y_top) {
11810  *step = z->next; /* delete from list */
11811  NK_ASSERT(z->direction);
11812  z->direction = 0;
11813  nk_tt__hheap_free(&hh, z);
11814  } else {
11815  step = &((*step)->next); /* advance through list */
11816  }
11817  }
11818 
11819  /* insert all edges that start before the bottom of this scanline */
11820  while (e->y0 <= scan_y_bottom) {
11821  if (e->y0 != e->y1) {
11822  struct nk_tt__active_edge *z = nk_tt__new_active(&hh, e, off_x, scan_y_top);
11823  if (z != 0) {
11824  NK_ASSERT(z->ey >= scan_y_top);
11825  /* insert at front */
11826  z->next = active;
11827  active = z;
11828  }
11829  }
11830  ++e;
11831  }
11832 
11833  /* now process all active edges */
11834  if (active)
11835  nk_tt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top);
11836 
11837  {
11838  float sum = 0;
11839  for (i=0; i < result->w; ++i) {
11840  float k;
11841  int m;
11842  sum += scanline2[i];
11843  k = scanline[i] + sum;
11844  k = (float) NK_ABS(k) * 255.0f + 0.5f;
11845  m = (int) k;
11846  if (m > 255) m = 255;
11847  result->pixels[j*result->stride + i] = (unsigned char) m;
11848  }
11849  }
11850  /* advance all the edges */
11851  step = &active;
11852  while (*step) {
11853  struct nk_tt__active_edge *z = *step;
11854  z->fx += z->fdx; /* advance to position for current scanline */
11855  step = &((*step)->next); /* advance through list */
11856  }
11857  ++y;
11858  ++j;
11859  }
11860  nk_tt__hheap_cleanup(&hh);
11861  if (scanline != scanline_data)
11862  alloc->free(alloc->userdata, scanline);
11863 }
11864 NK_INTERN void
11865 nk_tt__sort_edges_ins_sort(struct nk_tt__edge *p, int n)
11866 {
11867  int i,j;
11868  #define NK_TT__COMPARE(a,b) ((a)->y0 < (b)->y0)
11869  for (i=1; i < n; ++i) {
11870  struct nk_tt__edge t = p[i], *a = &t;
11871  j = i;
11872  while (j > 0) {
11873  struct nk_tt__edge *b = &p[j-1];
11874  int c = NK_TT__COMPARE(a,b);
11875  if (!c) break;
11876  p[j] = p[j-1];
11877  --j;
11878  }
11879  if (i != j)
11880  p[j] = t;
11881  }
11882 }
11883 NK_INTERN void
11884 nk_tt__sort_edges_quicksort(struct nk_tt__edge *p, int n)
11885 {
11886  /* threshold for transitioning to insertion sort */
11887  while (n > 12) {
11888  struct nk_tt__edge t;
11889  int c01,c12,c,m,i,j;
11890 
11891  /* compute median of three */
11892  m = n >> 1;
11893  c01 = NK_TT__COMPARE(&p[0],&p[m]);
11894  c12 = NK_TT__COMPARE(&p[m],&p[n-1]);
11895 
11896  /* if 0 >= mid >= end, or 0 < mid < end, then use mid */
11897  if (c01 != c12) {
11898  /* otherwise, we'll need to swap something else to middle */
11899  int z;
11900  c = NK_TT__COMPARE(&p[0],&p[n-1]);
11901  /* 0>mid && mid<n: 0>n => n; 0<n => 0 */
11902  /* 0<mid && mid>n: 0>n => 0; 0<n => n */
11903  z = (c == c12) ? 0 : n-1;
11904  t = p[z];
11905  p[z] = p[m];
11906  p[m] = t;
11907  }
11908 
11909  /* now p[m] is the median-of-three */
11910  /* swap it to the beginning so it won't move around */
11911  t = p[0];
11912  p[0] = p[m];
11913  p[m] = t;
11914 
11915  /* partition loop */
11916  i=1;
11917  j=n-1;
11918  for(;;) {
11919  /* handling of equality is crucial here */
11920  /* for sentinels & efficiency with duplicates */
11921  for (;;++i) {
11922  if (!NK_TT__COMPARE(&p[i], &p[0])) break;
11923  }
11924  for (;;--j) {
11925  if (!NK_TT__COMPARE(&p[0], &p[j])) break;
11926  }
11927 
11928  /* make sure we haven't crossed */
11929  if (i >= j) break;
11930  t = p[i];
11931  p[i] = p[j];
11932  p[j] = t;
11933 
11934  ++i;
11935  --j;
11936 
11937  }
11938 
11939  /* recurse on smaller side, iterate on larger */
11940  if (j < (n-i)) {
11941  nk_tt__sort_edges_quicksort(p,j);
11942  p = p+i;
11943  n = n-i;
11944  } else {
11945  nk_tt__sort_edges_quicksort(p+i, n-i);
11946  n = j;
11947  }
11948  }
11949 }
11950 NK_INTERN void
11951 nk_tt__sort_edges(struct nk_tt__edge *p, int n)
11952 {
11953  nk_tt__sort_edges_quicksort(p, n);
11954  nk_tt__sort_edges_ins_sort(p, n);
11955 }
11956 NK_INTERN void
11957 nk_tt__rasterize(struct nk_tt__bitmap *result, struct nk_tt__point *pts,
11958  int *wcount, int windings, float scale_x, float scale_y,
11959  float shift_x, float shift_y, int off_x, int off_y, int invert,
11960  struct nk_allocator *alloc)
11961 {
11962  float y_scale_inv = invert ? -scale_y : scale_y;
11963  struct nk_tt__edge *e;
11964  int n,i,j,k,m;
11965  int vsubsample = 1;
11966  /* vsubsample should divide 255 evenly; otherwise we won't reach full opacity */
11967 
11968  /* now we have to blow out the windings into explicit edge lists */
11969  n = 0;
11970  for (i=0; i < windings; ++i)
11971  n += wcount[i];
11972 
11973  e = (struct nk_tt__edge*)
11974  alloc->alloc(alloc->userdata, 0,(sizeof(*e) * (nk_size)(n+1)));
11975  if (e == 0) return;
11976  n = 0;
11977 
11978  m=0;
11979  for (i=0; i < windings; ++i)
11980  {
11981  struct nk_tt__point *p = pts + m;
11982  m += wcount[i];
11983  j = wcount[i]-1;
11984  for (k=0; k < wcount[i]; j=k++) {
11985  int a=k,b=j;
11986  /* skip the edge if horizontal */
11987  if (p[j].y == p[k].y)
11988  continue;
11989 
11990  /* add edge from j to k to the list */
11991  e[n].invert = 0;
11992  if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
11993  e[n].invert = 1;
11994  a=j,b=k;
11995  }
11996  e[n].x0 = p[a].x * scale_x + shift_x;
11997  e[n].y0 = (p[a].y * y_scale_inv + shift_y) * (float)vsubsample;
11998  e[n].x1 = p[b].x * scale_x + shift_x;
11999  e[n].y1 = (p[b].y * y_scale_inv + shift_y) * (float)vsubsample;
12000  ++n;
12001  }
12002  }
12003 
12004  /* now sort the edges by their highest point (should snap to integer, and then by x) */
12005  /*STBTT_sort(e, n, sizeof(e[0]), nk_tt__edge_compare); */
12006  nk_tt__sort_edges(e, n);
12007  /* now, traverse the scanlines and find the intersections on each scanline, use xor winding rule */
12008  nk_tt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, alloc);
12009  alloc->free(alloc->userdata, e);
12010 }
12011 NK_INTERN void
12012 nk_tt__add_point(struct nk_tt__point *points, int n, float x, float y)
12013 {
12014  if (!points) return; /* during first pass, it's unallocated */
12015  points[n].x = x;
12016  points[n].y = y;
12017 }
12018 NK_INTERN int
12019 nk_tt__tesselate_curve(struct nk_tt__point *points, int *num_points,
12020  float x0, float y0, float x1, float y1, float x2, float y2,
12021  float objspace_flatness_squared, int n)
12022 {
12023  /* tesselate until threshold p is happy...
12024  * @TODO warped to compensate for non-linear stretching */
12025  /* midpoint */
12026  float mx = (x0 + 2*x1 + x2)/4;
12027  float my = (y0 + 2*y1 + y2)/4;
12028  /* versus directly drawn line */
12029  float dx = (x0+x2)/2 - mx;
12030  float dy = (y0+y2)/2 - my;
12031  if (n > 16) /* 65536 segments on one curve better be enough! */
12032  return 1;
12033 
12034  /* half-pixel error allowed... need to be smaller if AA */
12035  if (dx*dx+dy*dy > objspace_flatness_squared) {
12036  nk_tt__tesselate_curve(points, num_points, x0,y0,
12037  (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
12038  nk_tt__tesselate_curve(points, num_points, mx,my,
12039  (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
12040  } else {
12041  nk_tt__add_point(points, *num_points,x2,y2);
12042  *num_points = *num_points+1;
12043  }
12044  return 1;
12045 }
12046 NK_INTERN struct nk_tt__point*
12047 nk_tt_FlattenCurves(struct nk_tt_vertex *vertices, int num_verts,
12048  float objspace_flatness, int **contour_lengths, int *num_contours,
12049  struct nk_allocator *alloc)
12050 {
12051  /* returns number of contours */
12052  struct nk_tt__point *points=0;
12053  int num_points=0;
12054  float objspace_flatness_squared = objspace_flatness * objspace_flatness;
12055  int i;
12056  int n=0;
12057  int start=0;
12058  int pass;
12059 
12060  /* count how many "moves" there are to get the contour count */
12061  for (i=0; i < num_verts; ++i)
12062  if (vertices[i].type == NK_TT_vmove) ++n;
12063 
12064  *num_contours = n;
12065  if (n == 0) return 0;
12066 
12067  *contour_lengths = (int *)
12068  alloc->alloc(alloc->userdata,0, (sizeof(**contour_lengths) * (nk_size)n));
12069  if (*contour_lengths == 0) {
12070  *num_contours = 0;
12071  return 0;
12072  }
12073 
12074  /* make two passes through the points so we don't need to realloc */
12075  for (pass=0; pass < 2; ++pass)
12076  {
12077  float x=0,y=0;
12078  if (pass == 1) {
12079  points = (struct nk_tt__point *)
12080  alloc->alloc(alloc->userdata,0, (nk_size)num_points * sizeof(points[0]));
12081  if (points == 0) goto error;
12082  }
12083  num_points = 0;
12084  n= -1;
12085 
12086  for (i=0; i < num_verts; ++i)
12087  {
12088  switch (vertices[i].type) {
12089  case NK_TT_vmove:
12090  /* start the next contour */
12091  if (n >= 0)
12092  (*contour_lengths)[n] = num_points - start;
12093  ++n;
12094  start = num_points;
12095 
12096  x = vertices[i].x, y = vertices[i].y;
12097  nk_tt__add_point(points, num_points++, x,y);
12098  break;
12099  case NK_TT_vline:
12100  x = vertices[i].x, y = vertices[i].y;
12101  nk_tt__add_point(points, num_points++, x, y);
12102  break;
12103  case NK_TT_vcurve:
12104  nk_tt__tesselate_curve(points, &num_points, x,y,
12105  vertices[i].cx, vertices[i].cy,
12106  vertices[i].x, vertices[i].y,
12107  objspace_flatness_squared, 0);
12108  x = vertices[i].x, y = vertices[i].y;
12109  break;
12110  default: break;
12111  }
12112  }
12113  (*contour_lengths)[n] = num_points - start;
12114  }
12115  return points;
12116 
12117 error:
12118  alloc->free(alloc->userdata, points);
12119  alloc->free(alloc->userdata, *contour_lengths);
12120  *contour_lengths = 0;
12121  *num_contours = 0;
12122  return 0;
12123 }
12124 NK_INTERN void
12125 nk_tt_Rasterize(struct nk_tt__bitmap *result, float flatness_in_pixels,
12126  struct nk_tt_vertex *vertices, int num_verts,
12127  float scale_x, float scale_y, float shift_x, float shift_y,
12128  int x_off, int y_off, int invert, struct nk_allocator *alloc)
12129 {
12130  float scale = scale_x > scale_y ? scale_y : scale_x;
12131  int winding_count, *winding_lengths;
12132  struct nk_tt__point *windings = nk_tt_FlattenCurves(vertices, num_verts,
12133  flatness_in_pixels / scale, &winding_lengths, &winding_count, alloc);
12134 
12135  NK_ASSERT(alloc);
12136  if (windings) {
12137  nk_tt__rasterize(result, windings, winding_lengths, winding_count,
12138  scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, alloc);
12139  alloc->free(alloc->userdata, winding_lengths);
12140  alloc->free(alloc->userdata, windings);
12141  }
12142 }
12143 NK_INTERN void
12144 nk_tt_MakeGlyphBitmapSubpixel(const struct nk_tt_fontinfo *info, unsigned char *output,
12145  int out_w, int out_h, int out_stride, float scale_x, float scale_y,
12146  float shift_x, float shift_y, int glyph, struct nk_allocator *alloc)
12147 {
12148  int ix0,iy0;
12149  struct nk_tt_vertex *vertices;
12150  int num_verts = nk_tt_GetGlyphShape(info, alloc, glyph, &vertices);
12151  struct nk_tt__bitmap gbm;
12152 
12153  nk_tt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x,
12154  shift_y, &ix0,&iy0,0,0);
12155  gbm.pixels = output;
12156  gbm.w = out_w;
12157  gbm.h = out_h;
12158  gbm.stride = out_stride;
12159 
12160  if (gbm.w && gbm.h)
12161  nk_tt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y,
12162  shift_x, shift_y, ix0,iy0, 1, alloc);
12163  alloc->free(alloc->userdata, vertices);
12164 }
12165 
12166 /*-------------------------------------------------------------
12167  * Bitmap baking
12168  * --------------------------------------------------------------*/
12169 NK_INTERN int
12170 nk_tt_PackBegin(struct nk_tt_pack_context *spc, unsigned char *pixels,
12171  int pw, int ph, int stride_in_bytes, int padding, struct nk_allocator *alloc)
12172 {
12173  int num_nodes = pw - padding;
12174  struct nk_rp_context *context = (struct nk_rp_context *)
12175  alloc->alloc(alloc->userdata,0, sizeof(*context));
12176  struct nk_rp_node *nodes = (struct nk_rp_node*)
12177  alloc->alloc(alloc->userdata,0, (sizeof(*nodes ) * (nk_size)num_nodes));
12178 
12179  if (context == 0 || nodes == 0) {
12180  if (context != 0) alloc->free(alloc->userdata, context);
12181  if (nodes != 0) alloc->free(alloc->userdata, nodes);
12182  return 0;
12183  }
12184 
12185  spc->width = pw;
12186  spc->height = ph;
12187  spc->pixels = pixels;
12188  spc->pack_info = context;
12189  spc->nodes = nodes;
12190  spc->padding = padding;
12191  spc->stride_in_bytes = (stride_in_bytes != 0) ? stride_in_bytes : pw;
12192  spc->h_oversample = 1;
12193  spc->v_oversample = 1;
12194 
12195  nk_rp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
12196  if (pixels)
12197  NK_MEMSET(pixels, 0, (nk_size)(pw*ph)); /* background of 0 around pixels */
12198  return 1;
12199 }
12200 NK_INTERN void
12201 nk_tt_PackEnd(struct nk_tt_pack_context *spc, struct nk_allocator *alloc)
12202 {
12203  alloc->free(alloc->userdata, spc->nodes);
12204  alloc->free(alloc->userdata, spc->pack_info);
12205 }
12206 NK_INTERN void
12207 nk_tt_PackSetOversampling(struct nk_tt_pack_context *spc,
12208  unsigned int h_oversample, unsigned int v_oversample)
12209 {
12210  NK_ASSERT(h_oversample <= NK_TT_MAX_OVERSAMPLE);
12211  NK_ASSERT(v_oversample <= NK_TT_MAX_OVERSAMPLE);
12212  if (h_oversample <= NK_TT_MAX_OVERSAMPLE)
12213  spc->h_oversample = h_oversample;
12214  if (v_oversample <= NK_TT_MAX_OVERSAMPLE)
12215  spc->v_oversample = v_oversample;
12216 }
12217 NK_INTERN void
12218 nk_tt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes,
12219  int kernel_width)
12220 {
12221  unsigned char buffer[NK_TT_MAX_OVERSAMPLE];
12222  int safe_w = w - kernel_width;
12223  int j;
12224 
12225  for (j=0; j < h; ++j)
12226  {
12227  int i;
12228  unsigned int total;
12229  NK_MEMSET(buffer, 0, (nk_size)kernel_width);
12230 
12231  total = 0;
12232 
12233  /* make kernel_width a constant in common cases so compiler can optimize out the divide */
12234  switch (kernel_width) {
12235  case 2:
12236  for (i=0; i <= safe_w; ++i) {
12237  total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12238  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12239  pixels[i] = (unsigned char) (total / 2);
12240  }
12241  break;
12242  case 3:
12243  for (i=0; i <= safe_w; ++i) {
12244  total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12245  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12246  pixels[i] = (unsigned char) (total / 3);
12247  }
12248  break;
12249  case 4:
12250  for (i=0; i <= safe_w; ++i) {
12251  total += (unsigned int)pixels[i] - buffer[i & NK_TT__OVER_MASK];
12252  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12253  pixels[i] = (unsigned char) (total / 4);
12254  }
12255  break;
12256  case 5:
12257  for (i=0; i <= safe_w; ++i) {
12258  total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12259  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12260  pixels[i] = (unsigned char) (total / 5);
12261  }
12262  break;
12263  default:
12264  for (i=0; i <= safe_w; ++i) {
12265  total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
12266  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
12267  pixels[i] = (unsigned char) (total / (unsigned int)kernel_width);
12268  }
12269  break;
12270  }
12271 
12272  for (; i < w; ++i) {
12273  NK_ASSERT(pixels[i] == 0);
12274  total -= (unsigned int)(buffer[i & NK_TT__OVER_MASK]);
12275  pixels[i] = (unsigned char) (total / (unsigned int)kernel_width);
12276  }
12277  pixels += stride_in_bytes;
12278  }
12279 }
12280 NK_INTERN void
12281 nk_tt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes,
12282  int kernel_width)
12283 {
12284  unsigned char buffer[NK_TT_MAX_OVERSAMPLE];
12285  int safe_h = h - kernel_width;
12286  int j;
12287 
12288  for (j=0; j < w; ++j)
12289  {
12290  int i;
12291  unsigned int total;
12292  NK_MEMSET(buffer, 0, (nk_size)kernel_width);
12293 
12294  total = 0;
12295 
12296  /* make kernel_width a constant in common cases so compiler can optimize out the divide */
12297  switch (kernel_width) {
12298  case 2:
12299  for (i=0; i <= safe_h; ++i) {
12300  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12301  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12302  pixels[i*stride_in_bytes] = (unsigned char) (total / 2);
12303  }
12304  break;
12305  case 3:
12306  for (i=0; i <= safe_h; ++i) {
12307  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12308  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12309  pixels[i*stride_in_bytes] = (unsigned char) (total / 3);
12310  }
12311  break;
12312  case 4:
12313  for (i=0; i <= safe_h; ++i) {
12314  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12315  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12316  pixels[i*stride_in_bytes] = (unsigned char) (total / 4);
12317  }
12318  break;
12319  case 5:
12320  for (i=0; i <= safe_h; ++i) {
12321  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12322  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12323  pixels[i*stride_in_bytes] = (unsigned char) (total / 5);
12324  }
12325  break;
12326  default:
12327  for (i=0; i <= safe_h; ++i) {
12328  total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
12329  buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
12330  pixels[i*stride_in_bytes] = (unsigned char) (total / (unsigned int)kernel_width);
12331  }
12332  break;
12333  }
12334 
12335  for (; i < h; ++i) {
12336  NK_ASSERT(pixels[i*stride_in_bytes] == 0);
12337  total -= (unsigned int)(buffer[i & NK_TT__OVER_MASK]);
12338  pixels[i*stride_in_bytes] = (unsigned char) (total / (unsigned int)kernel_width);
12339  }
12340  pixels += 1;
12341  }
12342 }
12343 NK_INTERN float
12344 nk_tt__oversample_shift(int oversample)
12345 {
12346  if (!oversample)
12347  return 0.0f;
12348 
12349  /* The prefilter is a box filter of width "oversample", */
12350  /* which shifts phase by (oversample - 1)/2 pixels in */
12351  /* oversampled space. We want to shift in the opposite */
12352  /* direction to counter this. */
12353  return (float)-(oversample - 1) / (2.0f * (float)oversample);
12354 }
12355 NK_INTERN int
12356 nk_tt_PackFontRangesGatherRects(struct nk_tt_pack_context *spc,
12357  struct nk_tt_fontinfo *info, struct nk_tt_pack_range *ranges,
12358  int num_ranges, struct nk_rp_rect *rects)
12359 {
12360  /* rects array must be big enough to accommodate all characters in the given ranges */
12361  int i,j,k;
12362  k = 0;
12363 
12364  for (i=0; i < num_ranges; ++i) {
12365  float fh = ranges[i].font_size;
12366  float scale = (fh > 0) ? nk_tt_ScaleForPixelHeight(info, fh):
12367  nk_tt_ScaleForMappingEmToPixels(info, -fh);
12368  ranges[i].h_oversample = (unsigned char) spc->h_oversample;
12369  ranges[i].v_oversample = (unsigned char) spc->v_oversample;
12370  for (j=0; j < ranges[i].num_chars; ++j) {
12371  int x0,y0,x1,y1;
12372  int codepoint = ranges[i].first_unicode_codepoint_in_range ?
12373  ranges[i].first_unicode_codepoint_in_range + j :
12374  ranges[i].array_of_unicode_codepoints[j];
12375 
12376  int glyph = nk_tt_FindGlyphIndex(info, codepoint);
12377  nk_tt_GetGlyphBitmapBoxSubpixel(info,glyph, scale * (float)spc->h_oversample,
12378  scale * (float)spc->v_oversample, 0,0, &x0,&y0,&x1,&y1);
12379  rects[k].w = (nk_rp_coord) (x1-x0 + spc->padding + (int)spc->h_oversample-1);
12380  rects[k].h = (nk_rp_coord) (y1-y0 + spc->padding + (int)spc->v_oversample-1);
12381  ++k;
12382  }
12383  }
12384  return k;
12385 }
12386 NK_INTERN int
12387 nk_tt_PackFontRangesRenderIntoRects(struct nk_tt_pack_context *spc,
12388  struct nk_tt_fontinfo *info, struct nk_tt_pack_range *ranges,
12389  int num_ranges, struct nk_rp_rect *rects, struct nk_allocator *alloc)
12390 {
12391  int i,j,k, return_value = 1;
12392  /* save current values */
12393  int old_h_over = (int)spc->h_oversample;
12394  int old_v_over = (int)spc->v_oversample;
12395  /* rects array must be big enough to accommodate all characters in the given ranges */
12396 
12397  k = 0;
12398  for (i=0; i < num_ranges; ++i)
12399  {
12400  float fh = ranges[i].font_size;
12401  float recip_h,recip_v,sub_x,sub_y;
12402  float scale = fh > 0 ? nk_tt_ScaleForPixelHeight(info, fh):
12403  nk_tt_ScaleForMappingEmToPixels(info, -fh);
12404 
12405  spc->h_oversample = ranges[i].h_oversample;
12406  spc->v_oversample = ranges[i].v_oversample;
12407 
12408  recip_h = 1.0f / (float)spc->h_oversample;
12409  recip_v = 1.0f / (float)spc->v_oversample;
12410 
12411  sub_x = nk_tt__oversample_shift((int)spc->h_oversample);
12412  sub_y = nk_tt__oversample_shift((int)spc->v_oversample);
12413 
12414  for (j=0; j < ranges[i].num_chars; ++j)
12415  {
12416  struct nk_rp_rect *r = &rects[k];
12417  if (r->was_packed)
12418  {
12419  struct nk_tt_packedchar *bc = &ranges[i].chardata_for_range[j];
12420  int advance, lsb, x0,y0,x1,y1;
12421  int codepoint = ranges[i].first_unicode_codepoint_in_range ?
12422  ranges[i].first_unicode_codepoint_in_range + j :
12423  ranges[i].array_of_unicode_codepoints[j];
12424  int glyph = nk_tt_FindGlyphIndex(info, codepoint);
12425  nk_rp_coord pad = (nk_rp_coord) spc->padding;
12426 
12427  /* pad on left and top */
12428  r->x = (nk_rp_coord)((int)r->x + (int)pad);
12429  r->y = (nk_rp_coord)((int)r->y + (int)pad);
12430  r->w = (nk_rp_coord)((int)r->w - (int)pad);
12431  r->h = (nk_rp_coord)((int)r->h - (int)pad);
12432 
12433  nk_tt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
12434  nk_tt_GetGlyphBitmapBox(info, glyph, scale * (float)spc->h_oversample,
12435  (scale * (float)spc->v_oversample), &x0,&y0,&x1,&y1);
12436  nk_tt_MakeGlyphBitmapSubpixel(info, spc->pixels + r->x + r->y*spc->stride_in_bytes,
12437  (int)(r->w - spc->h_oversample+1), (int)(r->h - spc->v_oversample+1),
12438  spc->stride_in_bytes, scale * (float)spc->h_oversample,
12439  scale * (float)spc->v_oversample, 0,0, glyph, alloc);
12440 
12441  if (spc->h_oversample > 1)
12442  nk_tt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
12443  r->w, r->h, spc->stride_in_bytes, (int)spc->h_oversample);
12444 
12445  if (spc->v_oversample > 1)
12446  nk_tt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
12447  r->w, r->h, spc->stride_in_bytes, (int)spc->v_oversample);
12448 
12449  bc->x0 = (nk_ushort) r->x;
12450  bc->y0 = (nk_ushort) r->y;
12451  bc->x1 = (nk_ushort) (r->x + r->w);
12452  bc->y1 = (nk_ushort) (r->y + r->h);
12453  bc->xadvance = scale * (float)advance;
12454  bc->xoff = (float) x0 * recip_h + sub_x;
12455  bc->yoff = (float) y0 * recip_v + sub_y;
12456  bc->xoff2 = ((float)x0 + r->w) * recip_h + sub_x;
12457  bc->yoff2 = ((float)y0 + r->h) * recip_v + sub_y;
12458  } else {
12459  return_value = 0; /* if any fail, report failure */
12460  }
12461  ++k;
12462  }
12463  }
12464  /* restore original values */
12465  spc->h_oversample = (unsigned int)old_h_over;
12466  spc->v_oversample = (unsigned int)old_v_over;
12467  return return_value;
12468 }
12469 NK_INTERN void
12470 nk_tt_GetPackedQuad(struct nk_tt_packedchar *chardata, int pw, int ph,
12471  int char_index, float *xpos, float *ypos, struct nk_tt_aligned_quad *q,
12472  int align_to_integer)
12473 {
12474  float ipw = 1.0f / (float)pw, iph = 1.0f / (float)ph;
12475  struct nk_tt_packedchar *b = (struct nk_tt_packedchar*)(chardata + char_index);
12476  if (align_to_integer) {
12477  int tx = nk_ifloorf((*xpos + b->xoff) + 0.5f);
12478  int ty = nk_ifloorf((*ypos + b->yoff) + 0.5f);
12479 
12480  float x = (float)tx;
12481  float y = (float)ty;
12482 
12483  q->x0 = x;
12484  q->y0 = y;
12485  q->x1 = x + b->xoff2 - b->xoff;
12486  q->y1 = y + b->yoff2 - b->yoff;
12487  } else {
12488  q->x0 = *xpos + b->xoff;
12489  q->y0 = *ypos + b->yoff;
12490  q->x1 = *xpos + b->xoff2;
12491  q->y1 = *ypos + b->yoff2;
12492  }
12493  q->s0 = b->x0 * ipw;
12494  q->t0 = b->y0 * iph;
12495  q->s1 = b->x1 * ipw;
12496  q->t1 = b->y1 * iph;
12497  *xpos += b->xadvance;
12498 }
12499 
12500 /* -------------------------------------------------------------
12501  *
12502  * FONT BAKING
12503  *
12504  * --------------------------------------------------------------*/
12505 struct nk_font_bake_data {
12506  struct nk_tt_fontinfo info;
12507  struct nk_rp_rect *rects;
12508  struct nk_tt_pack_range *ranges;
12509  nk_rune range_count;
12510 };
12511 
12512 struct nk_font_baker {
12513  struct nk_allocator alloc;
12514  struct nk_tt_pack_context spc;
12515  struct nk_font_bake_data *build;
12516  struct nk_tt_packedchar *packed_chars;
12517  struct nk_rp_rect *rects;
12518  struct nk_tt_pack_range *ranges;
12519 };
12520 
12521 NK_GLOBAL const nk_size nk_rect_align = NK_ALIGNOF(struct nk_rp_rect);
12522 NK_GLOBAL const nk_size nk_range_align = NK_ALIGNOF(struct nk_tt_pack_range);
12523 NK_GLOBAL const nk_size nk_char_align = NK_ALIGNOF(struct nk_tt_packedchar);
12524 NK_GLOBAL const nk_size nk_build_align = NK_ALIGNOF(struct nk_font_bake_data);
12525 NK_GLOBAL const nk_size nk_baker_align = NK_ALIGNOF(struct nk_font_baker);
12526 
12527 NK_INTERN int
12528 nk_range_count(const nk_rune *range)
12529 {
12530  const nk_rune *iter = range;
12531  NK_ASSERT(range);
12532  if (!range) return 0;
12533  while (*(iter++) != 0);
12534  return (iter == range) ? 0 : (int)((iter - range)/2);
12535 }
12536 NK_INTERN int
12537 nk_range_glyph_count(const nk_rune *range, int count)
12538 {
12539  int i = 0;
12540  int total_glyphs = 0;
12541  for (i = 0; i < count; ++i) {
12542  int diff;
12543  nk_rune f = range[(i*2)+0];
12544  nk_rune t = range[(i*2)+1];
12545  NK_ASSERT(t >= f);
12546  diff = (int)((t - f) + 1);
12547  total_glyphs += diff;
12548  }
12549  return total_glyphs;
12550 }
12551 NK_API const nk_rune*
12552 nk_font_default_glyph_ranges(void)
12553 {
12554  NK_STORAGE const nk_rune ranges[] = {0x0020, 0x00FF, 0};
12555  return ranges;
12556 }
12557 NK_API const nk_rune*
12558 nk_font_chinese_glyph_ranges(void)
12559 {
12560  NK_STORAGE const nk_rune ranges[] = {
12561  0x0020, 0x00FF,
12562  0x3000, 0x30FF,
12563  0x31F0, 0x31FF,
12564  0xFF00, 0xFFEF,
12565  0x4e00, 0x9FAF,
12566  0
12567  };
12568  return ranges;
12569 }
12570 NK_API const nk_rune*
12571 nk_font_cyrillic_glyph_ranges(void)
12572 {
12573  NK_STORAGE const nk_rune ranges[] = {
12574  0x0020, 0x00FF,
12575  0x0400, 0x052F,
12576  0x2DE0, 0x2DFF,
12577  0xA640, 0xA69F,
12578  0
12579  };
12580  return ranges;
12581 }
12582 NK_API const nk_rune*
12583 nk_font_korean_glyph_ranges(void)
12584 {
12585  NK_STORAGE const nk_rune ranges[] = {
12586  0x0020, 0x00FF,
12587  0x3131, 0x3163,
12588  0xAC00, 0xD79D,
12589  0
12590  };
12591  return ranges;
12592 }
12593 NK_INTERN void
12594 nk_font_baker_memory(nk_size *temp, int *glyph_count,
12595  struct nk_font_config *config_list, int count)
12596 {
12597  int range_count = 0;
12598  int total_range_count = 0;
12599  struct nk_font_config *iter, *i;
12600 
12601  NK_ASSERT(config_list);
12602  NK_ASSERT(glyph_count);
12603  if (!config_list) {
12604  *temp = 0;
12605  *glyph_count = 0;
12606  return;
12607  }
12608  *glyph_count = 0;
12609  for (iter = config_list; iter; iter = iter->next) {
12610  i = iter;
12611  do {if (!i->range) iter->range = nk_font_default_glyph_ranges();
12612  range_count = nk_range_count(i->range);
12613  total_range_count += range_count;
12614  *glyph_count += nk_range_glyph_count(i->range, range_count);
12615  } while ((i = i->n) != iter);
12616  }
12617  *temp = (nk_size)*glyph_count * sizeof(struct nk_rp_rect);
12618  *temp += (nk_size)total_range_count * sizeof(struct nk_tt_pack_range);
12619  *temp += (nk_size)*glyph_count * sizeof(struct nk_tt_packedchar);
12620  *temp += (nk_size)count * sizeof(struct nk_font_bake_data);
12621  *temp += sizeof(struct nk_font_baker);
12622  *temp += nk_rect_align + nk_range_align + nk_char_align;
12623  *temp += nk_build_align + nk_baker_align;
12624 }
12625 NK_INTERN struct nk_font_baker*
12626 nk_font_baker(void *memory, int glyph_count, int count, struct nk_allocator *alloc)
12627 {
12628  struct nk_font_baker *baker;
12629  if (!memory) return 0;
12630  /* setup baker inside a memory block */
12631  baker = (struct nk_font_baker*)NK_ALIGN_PTR(memory, nk_baker_align);
12632  baker->build = (struct nk_font_bake_data*)NK_ALIGN_PTR((baker + 1), nk_build_align);
12633  baker->packed_chars = (struct nk_tt_packedchar*)NK_ALIGN_PTR((baker->build + count), nk_char_align);
12634  baker->rects = (struct nk_rp_rect*)NK_ALIGN_PTR((baker->packed_chars + glyph_count), nk_rect_align);
12635  baker->ranges = (struct nk_tt_pack_range*)NK_ALIGN_PTR((baker->rects + glyph_count), nk_range_align);
12636  baker->alloc = *alloc;
12637  return baker;
12638 }
12639 NK_INTERN int
12640 nk_font_bake_pack(struct nk_font_baker *baker,
12641  nk_size *image_memory, int *width, int *height, struct nk_recti *custom,
12642  const struct nk_font_config *config_list, int count,
12643  struct nk_allocator *alloc)
12644 {
12645  NK_STORAGE const nk_size max_height = 1024 * 32;
12646  const struct nk_font_config *config_iter, *it;
12647  int total_glyph_count = 0;
12648  int total_range_count = 0;
12649  int range_count = 0;
12650  int i = 0;
12651 
12652  NK_ASSERT(image_memory);
12653  NK_ASSERT(width);
12654  NK_ASSERT(height);
12655  NK_ASSERT(config_list);
12656  NK_ASSERT(count);
12657  NK_ASSERT(alloc);
12658 
12659  if (!image_memory || !width || !height || !config_list || !count) return nk_false;
12660  for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
12661  it = config_iter;
12662  do {range_count = nk_range_count(it->range);
12663  total_range_count += range_count;
12664  total_glyph_count += nk_range_glyph_count(it->range, range_count);
12665  } while ((it = it->n) != config_iter);
12666  }
12667  /* setup font baker from temporary memory */
12668  for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
12669  it = config_iter;
12670  do {if (!nk_tt_InitFont(&baker->build[i++].info, (const unsigned char*)it->ttf_blob, 0))
12671  return nk_false;
12672  } while ((it = it->n) != config_iter);
12673  }
12674  *height = 0;
12675  *width = (total_glyph_count > 1000) ? 1024 : 512;
12676  nk_tt_PackBegin(&baker->spc, 0, (int)*width, (int)max_height, 0, 1, alloc);
12677  {
12678  int input_i = 0;
12679  int range_n = 0;
12680  int rect_n = 0;
12681  int char_n = 0;
12682 
12683  if (custom) {
12684  /* pack custom user data first so it will be in the upper left corner*/
12685  struct nk_rp_rect custom_space;
12686  nk_zero(&custom_space, sizeof(custom_space));
12687  custom_space.w = (nk_rp_coord)(custom->w);
12688  custom_space.h = (nk_rp_coord)(custom->h);
12689 
12690  nk_tt_PackSetOversampling(&baker->spc, 1, 1);
12691  nk_rp_pack_rects((struct nk_rp_context*)baker->spc.pack_info, &custom_space, 1);
12692  *height = NK_MAX(*height, (int)(custom_space.y + custom_space.h));
12693 
12694  custom->x = (short)custom_space.x;
12695  custom->y = (short)custom_space.y;
12696  custom->w = (short)custom_space.w;
12697  custom->h = (short)custom_space.h;
12698  }
12699 
12700  /* first font pass: pack all glyphs */
12701  for (input_i = 0, config_iter = config_list; input_i < count && config_iter;
12702  config_iter = config_iter->next) {
12703  it = config_iter;
12704  do {int n = 0;
12705  int glyph_count;
12706  const nk_rune *in_range;
12707  const struct nk_font_config *cfg = it;
12708  struct nk_font_bake_data *tmp = &baker->build[input_i++];
12709 
12710  /* count glyphs + ranges in current font */
12711  glyph_count = 0; range_count = 0;
12712  for (in_range = cfg->range; in_range[0] && in_range[1]; in_range += 2) {
12713  glyph_count += (int)(in_range[1] - in_range[0]) + 1;
12714  range_count++;
12715  }
12716 
12717  /* setup ranges */
12718  tmp->ranges = baker->ranges + range_n;
12719  tmp->range_count = (nk_rune)range_count;
12720  range_n += range_count;
12721  for (i = 0; i < range_count; ++i) {
12722  in_range = &cfg->range[i * 2];
12723  tmp->ranges[i].font_size = cfg->size;
12724  tmp->ranges[i].first_unicode_codepoint_in_range = (int)in_range[0];
12725  tmp->ranges[i].num_chars = (int)(in_range[1]- in_range[0]) + 1;
12726  tmp->ranges[i].chardata_for_range = baker->packed_chars + char_n;
12727  char_n += tmp->ranges[i].num_chars;
12728  }
12729 
12730  /* pack */
12731  tmp->rects = baker->rects + rect_n;
12732  rect_n += glyph_count;
12733  nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
12734  n = nk_tt_PackFontRangesGatherRects(&baker->spc, &tmp->info,
12735  tmp->ranges, (int)tmp->range_count, tmp->rects);
12736  nk_rp_pack_rects((struct nk_rp_context*)baker->spc.pack_info, tmp->rects, (int)n);
12737 
12738  /* texture height */
12739  for (i = 0; i < n; ++i) {
12740  if (tmp->rects[i].was_packed)
12741  *height = NK_MAX(*height, tmp->rects[i].y + tmp->rects[i].h);
12742  }
12743  } while ((it = it->n) != config_iter);
12744  }
12745  NK_ASSERT(rect_n == total_glyph_count);
12746  NK_ASSERT(char_n == total_glyph_count);
12747  NK_ASSERT(range_n == total_range_count);
12748  }
12749  *height = (int)nk_round_up_pow2((nk_uint)*height);
12750  *image_memory = (nk_size)(*width) * (nk_size)(*height);
12751  return nk_true;
12752 }
12753 NK_INTERN void
12754 nk_font_bake(struct nk_font_baker *baker, void *image_memory, int width, int height,
12755  struct nk_font_glyph *glyphs, int glyphs_count,
12756  const struct nk_font_config *config_list, int font_count)
12757 {
12758  int input_i = 0;
12759  nk_rune glyph_n = 0;
12760  const struct nk_font_config *config_iter;
12761  const struct nk_font_config *it;
12762 
12763  NK_ASSERT(image_memory);
12764  NK_ASSERT(width);
12765  NK_ASSERT(height);
12766  NK_ASSERT(config_list);
12767  NK_ASSERT(baker);
12768  NK_ASSERT(font_count);
12769  NK_ASSERT(glyphs_count);
12770  if (!image_memory || !width || !height || !config_list ||
12771  !font_count || !glyphs || !glyphs_count)
12772  return;
12773 
12774  /* second font pass: render glyphs */
12775  nk_zero(image_memory, (nk_size)((nk_size)width * (nk_size)height));
12776  baker->spc.pixels = (unsigned char*)image_memory;
12777  baker->spc.height = (int)height;
12778  for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
12779  config_iter = config_iter->next) {
12780  it = config_iter;
12781  do {const struct nk_font_config *cfg = it;
12782  struct nk_font_bake_data *tmp = &baker->build[input_i++];
12783  nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
12784  nk_tt_PackFontRangesRenderIntoRects(&baker->spc, &tmp->info, tmp->ranges,
12785  (int)tmp->range_count, tmp->rects, &baker->alloc);
12786  } while ((it = it->n) != config_iter);
12787  } nk_tt_PackEnd(&baker->spc, &baker->alloc);
12788 
12789  /* third pass: setup font and glyphs */
12790  for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
12791  config_iter = config_iter->next) {
12792  it = config_iter;
12793  do {nk_size i = 0;
12794  int char_idx = 0;
12795  nk_rune glyph_count = 0;
12796  const struct nk_font_config *cfg = it;
12797  struct nk_font_bake_data *tmp = &baker->build[input_i++];
12798  struct nk_baked_font *dst_font = cfg->font;
12799 
12800  float font_scale = nk_tt_ScaleForPixelHeight(&tmp->info, cfg->size);
12801  int unscaled_ascent, unscaled_descent, unscaled_line_gap;
12802  nk_tt_GetFontVMetrics(&tmp->info, &unscaled_ascent, &unscaled_descent,
12803  &unscaled_line_gap);
12804 
12805  /* fill baked font */
12806  if (!cfg->merge_mode) {
12807  dst_font->ranges = cfg->range;
12808  dst_font->height = cfg->size;
12809  dst_font->ascent = ((float)unscaled_ascent * font_scale);
12810  dst_font->descent = ((float)unscaled_descent * font_scale);
12811  dst_font->glyph_offset = glyph_n;
12812  }
12813 
12814  /* fill own baked font glyph array */
12815  for (i = 0; i < tmp->range_count; ++i) {
12816  struct nk_tt_pack_range *range = &tmp->ranges[i];
12817  for (char_idx = 0; char_idx < range->num_chars; char_idx++)
12818  {
12819  nk_rune codepoint = 0;
12820  float dummy_x = 0, dummy_y = 0;
12821  struct nk_tt_aligned_quad q;
12822  struct nk_font_glyph *glyph;
12823 
12824  /* query glyph bounds from stb_truetype */
12825  const struct nk_tt_packedchar *pc = &range->chardata_for_range[char_idx];
12826  if (!pc->x0 && !pc->x1 && !pc->y0 && !pc->y1) continue;
12827  codepoint = (nk_rune)(range->first_unicode_codepoint_in_range + char_idx);
12828  nk_tt_GetPackedQuad(range->chardata_for_range, (int)width,
12829  (int)height, char_idx, &dummy_x, &dummy_y, &q, 0);
12830 
12831  /* fill own glyph type with data */
12832  glyph = &glyphs[dst_font->glyph_offset + dst_font->glyph_count + (unsigned int)glyph_count];
12833  glyph->codepoint = codepoint;
12834  glyph->x0 = q.x0; glyph->y0 = q.y0;
12835  glyph->x1 = q.x1; glyph->y1 = q.y1;
12836  glyph->y0 += (dst_font->ascent + 0.5f);
12837  glyph->y1 += (dst_font->ascent + 0.5f);
12838  glyph->w = glyph->x1 - glyph->x0 + 0.5f;
12839  glyph->h = glyph->y1 - glyph->y0;
12840 
12841  if (cfg->coord_type == NK_COORD_PIXEL) {
12842  glyph->u0 = q.s0 * (float)width;
12843  glyph->v0 = q.t0 * (float)height;
12844  glyph->u1 = q.s1 * (float)width;
12845  glyph->v1 = q.t1 * (float)height;
12846  } else {
12847  glyph->u0 = q.s0;
12848  glyph->v0 = q.t0;
12849  glyph->u1 = q.s1;
12850  glyph->v1 = q.t1;
12851  }
12852  glyph->xadvance = (pc->xadvance + cfg->spacing.x);
12853  if (cfg->pixel_snap)
12854  glyph->xadvance = (float)(int)(glyph->xadvance + 0.5f);
12855  glyph_count++;
12856  }
12857  }
12858  dst_font->glyph_count += glyph_count;
12859  glyph_n += glyph_count;
12860  } while ((it = it->n) != config_iter);
12861  }
12862 }
12863 NK_INTERN void
12864 nk_font_bake_custom_data(void *img_memory, int img_width, int img_height,
12865  struct nk_recti img_dst, const char *texture_data_mask, int tex_width,
12866  int tex_height, char white, char black)
12867 {
12868  nk_byte *pixels;
12869  int y = 0;
12870  int x = 0;
12871  int n = 0;
12872 
12873  NK_ASSERT(img_memory);
12874  NK_ASSERT(img_width);
12875  NK_ASSERT(img_height);
12876  NK_ASSERT(texture_data_mask);
12877  NK_UNUSED(tex_height);
12878  if (!img_memory || !img_width || !img_height || !texture_data_mask)
12879  return;
12880 
12881  pixels = (nk_byte*)img_memory;
12882  for (y = 0, n = 0; y < tex_height; ++y) {
12883  for (x = 0; x < tex_width; ++x, ++n) {
12884  const int off0 = ((img_dst.x + x) + (img_dst.y + y) * img_width);
12885  const int off1 = off0 + 1 + tex_width;
12886  pixels[off0] = (texture_data_mask[n] == white) ? 0xFF : 0x00;
12887  pixels[off1] = (texture_data_mask[n] == black) ? 0xFF : 0x00;
12888  }
12889  }
12890 }
12891 NK_INTERN void
12892 nk_font_bake_convert(void *out_memory, int img_width, int img_height,
12893  const void *in_memory)
12894 {
12895  int n = 0;
12896  nk_rune *dst;
12897  const nk_byte *src;
12898 
12899  NK_ASSERT(out_memory);
12900  NK_ASSERT(in_memory);
12901  NK_ASSERT(img_width);
12902  NK_ASSERT(img_height);
12903  if (!out_memory || !in_memory || !img_height || !img_width) return;
12904 
12905  dst = (nk_rune*)out_memory;
12906  src = (const nk_byte*)in_memory;
12907  for (n = (int)(img_width * img_height); n > 0; n--)
12908  *dst++ = ((nk_rune)(*src++) << 24) | 0x00FFFFFF;
12909 }
12910 
12911 /* -------------------------------------------------------------
12912  *
12913  * FONT
12914  *
12915  * --------------------------------------------------------------*/
12916 NK_INTERN float
12917 nk_font_text_width(nk_handle handle, float height, const char *text, int len)
12918 {
12919  nk_rune unicode;
12920  int text_len = 0;
12921  float text_width = 0;
12922  int glyph_len = 0;
12923  float scale = 0;
12924 
12925  struct nk_font *font = (struct nk_font*)handle.ptr;
12926  NK_ASSERT(font);
12927  NK_ASSERT(font->glyphs);
12928  if (!font || !text || !len)
12929  return 0;
12930 
12931  scale = height/font->info.height;
12932  glyph_len = text_len = nk_utf_decode(text, &unicode, (int)len);
12933  if (!glyph_len) return 0;
12934  while (text_len <= (int)len && glyph_len) {
12935  const struct nk_font_glyph *g;
12936  if (unicode == NK_UTF_INVALID) break;
12937 
12938  /* query currently drawn glyph information */
12939  g = nk_font_find_glyph(font, unicode);
12940  text_width += g->xadvance * scale;
12941 
12942  /* offset next glyph */
12943  glyph_len = nk_utf_decode(text + text_len, &unicode, (int)len - text_len);
12944  text_len += glyph_len;
12945  }
12946  return text_width;
12947 }
12948 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
12949 NK_INTERN void
12950 nk_font_query_font_glyph(nk_handle handle, float height,
12951  struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
12952 {
12953  float scale;
12954  const struct nk_font_glyph *g;
12955  struct nk_font *font;
12956 
12957  NK_ASSERT(glyph);
12958  NK_UNUSED(next_codepoint);
12959 
12960  font = (struct nk_font*)handle.ptr;
12961  NK_ASSERT(font);
12962  NK_ASSERT(font->glyphs);
12963  if (!font || !glyph)
12964  return;
12965 
12966  scale = height/font->info.height;
12967  g = nk_font_find_glyph(font, codepoint);
12968  glyph->width = (g->x1 - g->x0) * scale;
12969  glyph->height = (g->y1 - g->y0) * scale;
12970  glyph->offset = nk_vec2(g->x0 * scale, g->y0 * scale);
12971  glyph->xadvance = (g->xadvance * scale);
12972  glyph->uv[0] = nk_vec2(g->u0, g->v0);
12973  glyph->uv[1] = nk_vec2(g->u1, g->v1);
12974 }
12975 #endif
12976 NK_API const struct nk_font_glyph*
12977 nk_font_find_glyph(struct nk_font *font, nk_rune unicode)
12978 {
12979  int i = 0;
12980  int count;
12981  int total_glyphs = 0;
12982  const struct nk_font_glyph *glyph = 0;
12983  const struct nk_font_config *iter = 0;
12984 
12985  NK_ASSERT(font);
12986  NK_ASSERT(font->glyphs);
12987  NK_ASSERT(font->info.ranges);
12988  if (!font || !font->glyphs) return 0;
12989 
12990  glyph = font->fallback;
12991  iter = font->config;
12992  do {count = nk_range_count(iter->range);
12993  for (i = 0; i < count; ++i) {
12994  nk_rune f = iter->range[(i*2)+0];
12995  nk_rune t = iter->range[(i*2)+1];
12996  int diff = (int)((t - f) + 1);
12997  if (unicode >= f && unicode <= t)
12998  return &font->glyphs[((nk_rune)total_glyphs + (unicode - f))];
12999  total_glyphs += diff;
13000  }
13001  } while ((iter = iter->n) != font->config);
13002  return glyph;
13003 }
13004 NK_INTERN void
13005 nk_font_init(struct nk_font *font, float pixel_height,
13006  nk_rune fallback_codepoint, struct nk_font_glyph *glyphs,
13007  const struct nk_baked_font *baked_font, nk_handle atlas)
13008 {
13009  struct nk_baked_font baked;
13010  NK_ASSERT(font);
13011  NK_ASSERT(glyphs);
13012  NK_ASSERT(baked_font);
13013  if (!font || !glyphs || !baked_font)
13014  return;
13015 
13016  baked = *baked_font;
13017  font->fallback = 0;
13018  font->info = baked;
13019  font->scale = (float)pixel_height / (float)font->info.height;
13020  font->glyphs = &glyphs[baked_font->glyph_offset];
13021  font->texture = atlas;
13022  font->fallback_codepoint = fallback_codepoint;
13023  font->fallback = nk_font_find_glyph(font, fallback_codepoint);
13024 
13025  font->handle.height = font->info.height * font->scale;
13026  font->handle.width = nk_font_text_width;
13027  font->handle.userdata.ptr = font;
13028 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
13029  font->handle.query = nk_font_query_font_glyph;
13030  font->handle.texture = font->texture;
13031 #endif
13032 }
13033 
13034 /* ---------------------------------------------------------------------------
13035  *
13036  * DEFAULT FONT
13037  *
13038  * ProggyClean.ttf
13039  * Copyright (c) 2004, 2005 Tristan Grimmer
13040  * MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip)
13041  * Download and more information at http://upperbounds.net
13042  *-----------------------------------------------------------------------------*/
13043 #ifdef __clang__
13044 #pragma clang diagnostic push
13045 #pragma clang diagnostic ignored "-Woverlength-strings"
13046 #elif defined(__GNUC__) || defined(__GNUG__)
13047 #pragma GCC diagnostic push
13048 #pragma GCC diagnostic ignored "-Woverlength-strings"
13049 #endif
13050 
13051 #ifdef NK_INCLUDE_DEFAULT_FONT
13052 
13053 NK_GLOBAL const char nk_proggy_clean_ttf_compressed_data_base85[11980+1] =
13054  "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/"
13055  "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#"
13056  "`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"
13057  "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"
13058  "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"
13059  "*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)"
13060  "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"
13061  "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."
13062  "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"
13063  "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(,)"
13064  "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#"
13065  "'/###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"
13066  "_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"
13067  "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/"
13068  "/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"
13069  "%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&#"
13070  "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)("
13071  "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"
13072  "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"
13073  "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^-"
13074  "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-"
13075  "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"
13076  "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%"
13077  "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]"
13078  "%(?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"
13079  "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:"
13080  "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("
13081  "$/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<"
13082  "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'?"
13083  "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/;"
13084  ")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"
13085  "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("
13086  "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"
13087  "bIu)'Z,*[>br5fX^:FPAWr-m2KgL<LUN098kTF&#lvo58=/vjDo;.;)Ka*hLR#/k=rKbxuV`>Q_nN6'8uTG&#1T5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q"
13088  "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<-"
13089  "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"
13090  "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"
13091  ".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@@"
13092  "$&)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*"
13093  "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"
13094  "@-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&#"
13095  "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#"
13096  "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"
13097  "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"
13098  "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&#"
13099  "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"
13100  ":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+"
13101  "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*"
13102  "$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"
13103  ":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"
13104  "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"
13105  "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"
13106  "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"
13107  ":^#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@&]>"
13108  "_>@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%"
13109  "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;"
13110  "^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:"
13111  "+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%"
13112  "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-"
13113  "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*"
13114  "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"
13115  "8kD2)2fU/M#$e.)T4,_=8hLim[&);?UkK'-x?'(:siIfL<$pFM`i<?%W(mGDHM%>iWP,##P`%/L<eXi:@Z9C.7o=@(pXdAO/NLQ8lPl+HPOQa8wD8=^GlPa8TKI1CjhsCTSLJM'/Wl>-"
13116  "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`"
13117  "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]%/"
13118  "+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"
13119  "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"
13120  "?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"
13121  "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"
13122  ">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'>"
13123  "[%$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"
13124  "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#"
13125  "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$"
13126  "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,)"
13127  "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"
13128  "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"
13129  "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"
13130  "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(#"
13131  ";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&>"
13132  "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#"
13133  "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"
13134  "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#"
13135  "/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-#"
13136  "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#"
13137  "TmD<#%JSMFove:CTBEXI:<eh2g)B,3h2^G3i;#d3jD>)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP"
13138  "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp"
13139  "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#";
13140 
13141 #endif /* NK_INCLUDE_DEFAULT_FONT */
13142 
13143 #define NK_CURSOR_DATA_W 90
13144 #define NK_CURSOR_DATA_H 27
13145 NK_GLOBAL const char nk_custom_cursor_data[NK_CURSOR_DATA_W * NK_CURSOR_DATA_H + 1] =
13146 {
13147  "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX"
13148  "..- -X.....X- X.X - X.X -X.....X - X.....X"
13149  "--- -XXX.XXX- X...X - X...X -X....X - X....X"
13150  "X - X.X - X.....X - X.....X -X...X - X...X"
13151  "XX - X.X -X.......X- X.......X -X..X.X - X.X..X"
13152  "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X"
13153  "X..X - X.X - X.X - X.X -XX X.X - X.X XX"
13154  "X...X - X.X - X.X - XX X.X XX - X.X - X.X "
13155  "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X "
13156  "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X "
13157  "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X "
13158  "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X "
13159  "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X "
13160  "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X "
13161  "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X "
13162  "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X "
13163  "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX "
13164  "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------"
13165  "X.X X..X - -X.......X- X.......X - XX XX - "
13166  "XX X..X - - X.....X - X.....X - X.X X.X - "
13167  " X..X - X...X - X...X - X..X X..X - "
13168  " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - "
13169  "------------ - X - X -X.....................X- "
13170  " ----------------------------------- X...XXXXXXXXXXXXX...X - "
13171  " - X..X X..X - "
13172  " - X.X X.X - "
13173  " - XX XX - "
13174 };
13175 
13176 #ifdef __clang__
13177 #pragma clang diagnostic pop
13178 #elif defined(__GNUC__) || defined(__GNUG__)
13179 #pragma GCC diagnostic pop
13180 #endif
13181 
13182 NK_GLOBAL unsigned char *nk__barrier;
13183 NK_GLOBAL unsigned char *nk__barrier2;
13184 NK_GLOBAL unsigned char *nk__barrier3;
13185 NK_GLOBAL unsigned char *nk__barrier4;
13186 NK_GLOBAL unsigned char *nk__dout;
13187 
13188 NK_INTERN unsigned int
13189 nk_decompress_length(unsigned char *input)
13190 {
13191  return (unsigned int)((input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]);
13192 }
13193 NK_INTERN void
13194 nk__match(unsigned char *data, unsigned int length)
13195 {
13196  /* INVERSE of memmove... write each byte before copying the next...*/
13197  NK_ASSERT (nk__dout + length <= nk__barrier);
13198  if (nk__dout + length > nk__barrier) { nk__dout += length; return; }
13199  if (data < nk__barrier4) { nk__dout = nk__barrier+1; return; }
13200  while (length--) *nk__dout++ = *data++;
13201 }
13202 NK_INTERN void
13203 nk__lit(unsigned char *data, unsigned int length)
13204 {
13205  NK_ASSERT (nk__dout + length <= nk__barrier);
13206  if (nk__dout + length > nk__barrier) { nk__dout += length; return; }
13207  if (data < nk__barrier2) { nk__dout = nk__barrier+1; return; }
13208  NK_MEMCPY(nk__dout, data, length);
13209  nk__dout += length;
13210 }
13211 NK_INTERN unsigned char*
13212 nk_decompress_token(unsigned char *i)
13213 {
13214  #define nk__in2(x) ((i[x] << 8) + i[(x)+1])
13215  #define nk__in3(x) ((i[x] << 16) + nk__in2((x)+1))
13216  #define nk__in4(x) ((i[x] << 24) + nk__in3((x)+1))
13217 
13218  if (*i >= 0x20) { /* use fewer if's for cases that expand small */
13219  if (*i >= 0x80) nk__match(nk__dout-i[1]-1, (unsigned int)i[0] - 0x80 + 1), i += 2;
13220  else if (*i >= 0x40) nk__match(nk__dout-(nk__in2(0) - 0x4000 + 1), (unsigned int)i[2]+1), i += 3;
13221  else /* *i >= 0x20 */ nk__lit(i+1, (unsigned int)i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1);
13222  } else { /* more ifs for cases that expand large, since overhead is amortized */
13223  if (*i >= 0x18) nk__match(nk__dout-(unsigned int)(nk__in3(0) - 0x180000 + 1), (unsigned int)i[3]+1), i += 4;
13224  else if (*i >= 0x10) nk__match(nk__dout-(unsigned int)(nk__in3(0) - 0x100000 + 1), (unsigned int)nk__in2(3)+1), i += 5;
13225  else if (*i >= 0x08) nk__lit(i+2, (unsigned int)nk__in2(0) - 0x0800 + 1), i += 2 + (nk__in2(0) - 0x0800 + 1);
13226  else if (*i == 0x07) nk__lit(i+3, (unsigned int)nk__in2(1) + 1), i += 3 + (nk__in2(1) + 1);
13227  else if (*i == 0x06) nk__match(nk__dout-(unsigned int)(nk__in3(1)+1), i[4]+1u), i += 5;
13228  else if (*i == 0x04) nk__match(nk__dout-(unsigned int)(nk__in3(1)+1), (unsigned int)nk__in2(4)+1u), i += 6;
13229  }
13230  return i;
13231 }
13232 NK_INTERN unsigned int
13233 nk_adler32(unsigned int adler32, unsigned char *buffer, unsigned int buflen)
13234 {
13235  const unsigned long ADLER_MOD = 65521;
13236  unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
13237  unsigned long blocklen, i;
13238 
13239  blocklen = buflen % 5552;
13240  while (buflen) {
13241  for (i=0; i + 7 < blocklen; i += 8) {
13242  s1 += buffer[0]; s2 += s1;
13243  s1 += buffer[1]; s2 += s1;
13244  s1 += buffer[2]; s2 += s1;
13245  s1 += buffer[3]; s2 += s1;
13246  s1 += buffer[4]; s2 += s1;
13247  s1 += buffer[5]; s2 += s1;
13248  s1 += buffer[6]; s2 += s1;
13249  s1 += buffer[7]; s2 += s1;
13250  buffer += 8;
13251  }
13252  for (; i < blocklen; ++i) {
13253  s1 += *buffer++; s2 += s1;
13254  }
13255 
13256  s1 %= ADLER_MOD; s2 %= ADLER_MOD;
13257  buflen -= (unsigned int)blocklen;
13258  blocklen = 5552;
13259  }
13260  return (unsigned int)(s2 << 16) + (unsigned int)s1;
13261 }
13262 NK_INTERN unsigned int
13263 nk_decompress(unsigned char *output, unsigned char *i, unsigned int length)
13264 {
13265  unsigned int olen;
13266  if (nk__in4(0) != 0x57bC0000) return 0;
13267  if (nk__in4(4) != 0) return 0; /* error! stream is > 4GB */
13268  olen = nk_decompress_length(i);
13269  nk__barrier2 = i;
13270  nk__barrier3 = i+length;
13271  nk__barrier = output + olen;
13272  nk__barrier4 = output;
13273  i += 16;
13274 
13275  nk__dout = output;
13276  for (;;) {
13277  unsigned char *old_i = i;
13278  i = nk_decompress_token(i);
13279  if (i == old_i) {
13280  if (*i == 0x05 && i[1] == 0xfa) {
13281  NK_ASSERT(nk__dout == output + olen);
13282  if (nk__dout != output + olen) return 0;
13283  if (nk_adler32(1, output, olen) != (unsigned int) nk__in4(2))
13284  return 0;
13285  return olen;
13286  } else {
13287  NK_ASSERT(0); /* NOTREACHED */
13288  return 0;
13289  }
13290  }
13291  NK_ASSERT(nk__dout <= output + olen);
13292  if (nk__dout > output + olen)
13293  return 0;
13294  }
13295 }
13296 NK_INTERN unsigned int
13297 nk_decode_85_byte(char c)
13298 {
13299  return (unsigned int)((c >= '\\') ? c-36 : c-35);
13300 }
13301 NK_INTERN void
13302 nk_decode_85(unsigned char* dst, const unsigned char* src)
13303 {
13304  while (*src)
13305  {
13306  unsigned int tmp =
13307  nk_decode_85_byte((char)src[0]) +
13308  85 * (nk_decode_85_byte((char)src[1]) +
13309  85 * (nk_decode_85_byte((char)src[2]) +
13310  85 * (nk_decode_85_byte((char)src[3]) +
13311  85 * nk_decode_85_byte((char)src[4]))));
13312 
13313  /* we can't assume little-endianess. */
13314  dst[0] = (unsigned char)((tmp >> 0) & 0xFF);
13315  dst[1] = (unsigned char)((tmp >> 8) & 0xFF);
13316  dst[2] = (unsigned char)((tmp >> 16) & 0xFF);
13317  dst[3] = (unsigned char)((tmp >> 24) & 0xFF);
13318 
13319  src += 5;
13320  dst += 4;
13321  }
13322 }
13323 
13324 /* -------------------------------------------------------------
13325  *
13326  * FONT ATLAS
13327  *
13328  * --------------------------------------------------------------*/
13329 NK_API struct nk_font_config
13330 nk_font_config(float pixel_height)
13331 {
13332  struct nk_font_config cfg;
13333  nk_zero_struct(cfg);
13334  cfg.ttf_blob = 0;
13335  cfg.ttf_size = 0;
13336  cfg.ttf_data_owned_by_atlas = 0;
13337  cfg.size = pixel_height;
13338  cfg.oversample_h = 3;
13339  cfg.oversample_v = 1;
13340  cfg.pixel_snap = 0;
13341  cfg.coord_type = NK_COORD_UV;
13342  cfg.spacing = nk_vec2(0,0);
13343  cfg.range = nk_font_default_glyph_ranges();
13344  cfg.merge_mode = 0;
13345  cfg.fallback_glyph = '?';
13346  cfg.font = 0;
13347  cfg.n = 0;
13348  return cfg;
13349 }
13350 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
13351 NK_API void
13352 nk_font_atlas_init_default(struct nk_font_atlas *atlas)
13353 {
13354  NK_ASSERT(atlas);
13355  if (!atlas) return;
13356  nk_zero_struct(*atlas);
13357  atlas->temporary.userdata.ptr = 0;
13358  atlas->temporary.alloc = nk_malloc;
13359  atlas->temporary.free = nk_mfree;
13360  atlas->permanent.userdata.ptr = 0;
13361  atlas->permanent.alloc = nk_malloc;
13362  atlas->permanent.free = nk_mfree;
13363 }
13364 #endif
13365 NK_API void
13366 nk_font_atlas_init(struct nk_font_atlas *atlas, struct nk_allocator *alloc)
13367 {
13368  NK_ASSERT(atlas);
13369  NK_ASSERT(alloc);
13370  if (!atlas || !alloc) return;
13371  nk_zero_struct(*atlas);
13372  atlas->permanent = *alloc;
13373  atlas->temporary = *alloc;
13374 }
13375 NK_API void
13376 nk_font_atlas_init_custom(struct nk_font_atlas *atlas,
13377  struct nk_allocator *permanent, struct nk_allocator *temporary)
13378 {
13379  NK_ASSERT(atlas);
13380  NK_ASSERT(permanent);
13381  NK_ASSERT(temporary);
13382  if (!atlas || !permanent || !temporary) return;
13383  nk_zero_struct(*atlas);
13384  atlas->permanent = *permanent;
13385  atlas->temporary = *temporary;
13386 }
13387 NK_API void
13388 nk_font_atlas_begin(struct nk_font_atlas *atlas)
13389 {
13390  NK_ASSERT(atlas);
13391  NK_ASSERT(atlas->temporary.alloc && atlas->temporary.free);
13392  NK_ASSERT(atlas->permanent.alloc && atlas->permanent.free);
13393  if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free ||
13394  !atlas->temporary.alloc || !atlas->temporary.free) return;
13395  if (atlas->glyphs) {
13396  atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
13397  atlas->glyphs = 0;
13398  }
13399  if (atlas->pixel) {
13400  atlas->permanent.free(atlas->permanent.userdata, atlas->pixel);
13401  atlas->pixel = 0;
13402  }
13403 }
13404 NK_API struct nk_font*
13405 nk_font_atlas_add(struct nk_font_atlas *atlas, const struct nk_font_config *config)
13406 {
13407  struct nk_font *font = 0;
13408  struct nk_font_config *cfg;
13409 
13410  NK_ASSERT(atlas);
13411  NK_ASSERT(atlas->permanent.alloc);
13412  NK_ASSERT(atlas->permanent.free);
13413  NK_ASSERT(atlas->temporary.alloc);
13414  NK_ASSERT(atlas->temporary.free);
13415 
13416  NK_ASSERT(config);
13417  NK_ASSERT(config->ttf_blob);
13418  NK_ASSERT(config->ttf_size);
13419  NK_ASSERT(config->size > 0.0f);
13420 
13421  if (!atlas || !config || !config->ttf_blob || !config->ttf_size || config->size <= 0.0f||
13422  !atlas->permanent.alloc || !atlas->permanent.free ||
13423  !atlas->temporary.alloc || !atlas->temporary.free)
13424  return 0;
13425 
13426  /* allocate font config */
13427  cfg = (struct nk_font_config*)
13428  atlas->permanent.alloc(atlas->permanent.userdata,0, sizeof(struct nk_font_config));
13429  NK_MEMCPY(cfg, config, sizeof(*config));
13430  cfg->n = cfg;
13431  cfg->p = cfg;
13432 
13433  if (!config->merge_mode) {
13434  /* insert font config into list */
13435  if (!atlas->config) {
13436  atlas->config = cfg;
13437  cfg->next = 0;
13438  } else {
13439  struct nk_font_config *i = atlas->config;
13440  while (i->next) i = i->next;
13441  i->next = cfg;
13442  cfg->next = 0;
13443  }
13444  /* allocate new font */
13445  font = (struct nk_font*)
13446  atlas->permanent.alloc(atlas->permanent.userdata,0, sizeof(struct nk_font));
13447  NK_ASSERT(font);
13448  nk_zero(font, sizeof(*font));
13449  if (!font) return 0;
13450  font->config = cfg;
13451 
13452  /* insert font into list */
13453  if (!atlas->fonts) {
13454  atlas->fonts = font;
13455  font->next = 0;
13456  } else {
13457  struct nk_font *i = atlas->fonts;
13458  while (i->next) i = i->next;
13459  i->next = font;
13460  font->next = 0;
13461  }
13462  cfg->font = &font->info;
13463  } else {
13464  /* extend previously added font */
13465  struct nk_font *f = 0;
13466  struct nk_font_config *c = 0;
13467  NK_ASSERT(atlas->font_num);
13468  f = atlas->fonts;
13469  c = f->config;
13470  cfg->font = &f->info;
13471 
13472  cfg->n = c;
13473  cfg->p = c->p;
13474  c->p->n = cfg;
13475  c->p = cfg;
13476  }
13477  /* create own copy of .TTF font blob */
13478  if (!config->ttf_data_owned_by_atlas) {
13479  cfg->ttf_blob = atlas->permanent.alloc(atlas->permanent.userdata,0, cfg->ttf_size);
13480  NK_ASSERT(cfg->ttf_blob);
13481  if (!cfg->ttf_blob) {
13482  atlas->font_num++;
13483  return 0;
13484  }
13485  NK_MEMCPY(cfg->ttf_blob, config->ttf_blob, cfg->ttf_size);
13486  cfg->ttf_data_owned_by_atlas = 1;
13487  }
13488  atlas->font_num++;
13489  return font;
13490 }
13491 NK_API struct nk_font*
13492 nk_font_atlas_add_from_memory(struct nk_font_atlas *atlas, void *memory,
13493  nk_size size, float height, const struct nk_font_config *config)
13494 {
13495  struct nk_font_config cfg;
13496  NK_ASSERT(memory);
13497  NK_ASSERT(size);
13498 
13499  NK_ASSERT(atlas);
13500  NK_ASSERT(atlas->temporary.alloc);
13501  NK_ASSERT(atlas->temporary.free);
13502  NK_ASSERT(atlas->permanent.alloc);
13503  NK_ASSERT(atlas->permanent.free);
13504  if (!atlas || !atlas->temporary.alloc || !atlas->temporary.free || !memory || !size ||
13505  !atlas->permanent.alloc || !atlas->permanent.free)
13506  return 0;
13507 
13508  cfg = (config) ? *config: nk_font_config(height);
13509  cfg.ttf_blob = memory;
13510  cfg.ttf_size = size;
13511  cfg.size = height;
13512  cfg.ttf_data_owned_by_atlas = 0;
13513  return nk_font_atlas_add(atlas, &cfg);
13514 }
13515 #ifdef NK_INCLUDE_STANDARD_IO
13516 NK_API struct nk_font*
13517 nk_font_atlas_add_from_file(struct nk_font_atlas *atlas, const char *file_path,
13518  float height, const struct nk_font_config *config)
13519 {
13520  nk_size size;
13521  char *memory;
13522  struct nk_font_config cfg;
13523 
13524  NK_ASSERT(atlas);
13525  NK_ASSERT(atlas->temporary.alloc);
13526  NK_ASSERT(atlas->temporary.free);
13527  NK_ASSERT(atlas->permanent.alloc);
13528  NK_ASSERT(atlas->permanent.free);
13529 
13530  if (!atlas || !file_path) return 0;
13531  memory = nk_file_load(file_path, &size, &atlas->permanent);
13532  if (!memory) return 0;
13533 
13534  cfg = (config) ? *config: nk_font_config(height);
13535  cfg.ttf_blob = memory;
13536  cfg.ttf_size = size;
13537  cfg.size = height;
13538  cfg.ttf_data_owned_by_atlas = 1;
13539  return nk_font_atlas_add(atlas, &cfg);
13540 }
13541 #endif
13542 NK_API struct nk_font*
13543 nk_font_atlas_add_compressed(struct nk_font_atlas *atlas,
13544  void *compressed_data, nk_size compressed_size, float height,
13545  const struct nk_font_config *config)
13546 {
13547  unsigned int decompressed_size;
13548  void *decompressed_data;
13549  struct nk_font_config cfg;
13550 
13551  NK_ASSERT(atlas);
13552  NK_ASSERT(atlas->temporary.alloc);
13553  NK_ASSERT(atlas->temporary.free);
13554  NK_ASSERT(atlas->permanent.alloc);
13555  NK_ASSERT(atlas->permanent.free);
13556 
13557  NK_ASSERT(compressed_data);
13558  NK_ASSERT(compressed_size);
13559  if (!atlas || !compressed_data || !atlas->temporary.alloc || !atlas->temporary.free ||
13560  !atlas->permanent.alloc || !atlas->permanent.free)
13561  return 0;
13562 
13563  decompressed_size = nk_decompress_length((unsigned char*)compressed_data);
13564  decompressed_data = atlas->permanent.alloc(atlas->permanent.userdata,0,decompressed_size);
13565  NK_ASSERT(decompressed_data);
13566  if (!decompressed_data) return 0;
13567  nk_decompress((unsigned char*)decompressed_data, (unsigned char*)compressed_data,
13568  (unsigned int)compressed_size);
13569 
13570  cfg = (config) ? *config: nk_font_config(height);
13571  cfg.ttf_blob = decompressed_data;
13572  cfg.ttf_size = decompressed_size;
13573  cfg.size = height;
13574  cfg.ttf_data_owned_by_atlas = 1;
13575  return nk_font_atlas_add(atlas, &cfg);
13576 }
13577 NK_API struct nk_font*
13578 nk_font_atlas_add_compressed_base85(struct nk_font_atlas *atlas,
13579  const char *data_base85, float height, const struct nk_font_config *config)
13580 {
13581  int compressed_size;
13582  void *compressed_data;
13583  struct nk_font *font;
13584 
13585  NK_ASSERT(atlas);
13586  NK_ASSERT(atlas->temporary.alloc);
13587  NK_ASSERT(atlas->temporary.free);
13588  NK_ASSERT(atlas->permanent.alloc);
13589  NK_ASSERT(atlas->permanent.free);
13590 
13591  NK_ASSERT(data_base85);
13592  if (!atlas || !data_base85 || !atlas->temporary.alloc || !atlas->temporary.free ||
13593  !atlas->permanent.alloc || !atlas->permanent.free)
13594  return 0;
13595 
13596  compressed_size = (((int)nk_strlen(data_base85) + 4) / 5) * 4;
13597  compressed_data = atlas->temporary.alloc(atlas->temporary.userdata,0, (nk_size)compressed_size);
13598  NK_ASSERT(compressed_data);
13599  if (!compressed_data) return 0;
13600  nk_decode_85((unsigned char*)compressed_data, (const unsigned char*)data_base85);
13601  font = nk_font_atlas_add_compressed(atlas, compressed_data,
13602  (nk_size)compressed_size, height, config);
13603  atlas->temporary.free(atlas->temporary.userdata, compressed_data);
13604  return font;
13605 }
13606 
13607 #ifdef NK_INCLUDE_DEFAULT_FONT
13608 NK_API struct nk_font*
13609 nk_font_atlas_add_default(struct nk_font_atlas *atlas,
13610  float pixel_height, const struct nk_font_config *config)
13611 {
13612  NK_ASSERT(atlas);
13613  NK_ASSERT(atlas->temporary.alloc);
13614  NK_ASSERT(atlas->temporary.free);
13615  NK_ASSERT(atlas->permanent.alloc);
13616  NK_ASSERT(atlas->permanent.free);
13617  return nk_font_atlas_add_compressed_base85(atlas,
13618  nk_proggy_clean_ttf_compressed_data_base85, pixel_height, config);
13619 }
13620 #endif
13621 NK_API const void*
13622 nk_font_atlas_bake(struct nk_font_atlas *atlas, int *width, int *height,
13623  enum nk_font_atlas_format fmt)
13624 {
13625  int i = 0;
13626  void *tmp = 0;
13627  nk_size tmp_size, img_size;
13628  struct nk_font *font_iter;
13629  struct nk_font_baker *baker;
13630 
13631  NK_ASSERT(atlas);
13632  NK_ASSERT(atlas->temporary.alloc);
13633  NK_ASSERT(atlas->temporary.free);
13634  NK_ASSERT(atlas->permanent.alloc);
13635  NK_ASSERT(atlas->permanent.free);
13636 
13637  NK_ASSERT(width);
13638  NK_ASSERT(height);
13639  if (!atlas || !width || !height ||
13640  !atlas->temporary.alloc || !atlas->temporary.free ||
13641  !atlas->permanent.alloc || !atlas->permanent.free)
13642  return 0;
13643 
13644 #ifdef NK_INCLUDE_DEFAULT_FONT
13645  /* no font added so just use default font */
13646  if (!atlas->font_num)
13647  atlas->default_font = nk_font_atlas_add_default(atlas, 13.0f, 0);
13648 #endif
13649  NK_ASSERT(atlas->font_num);
13650  if (!atlas->font_num) return 0;
13651 
13652  /* allocate temporary baker memory required for the baking process */
13653  nk_font_baker_memory(&tmp_size, &atlas->glyph_count, atlas->config, atlas->font_num);
13654  tmp = atlas->temporary.alloc(atlas->temporary.userdata,0, tmp_size);
13655  NK_ASSERT(tmp);
13656  if (!tmp) goto failed;
13657 
13658  /* allocate glyph memory for all fonts */
13659  baker = nk_font_baker(tmp, atlas->glyph_count, atlas->font_num, &atlas->temporary);
13660  atlas->glyphs = (struct nk_font_glyph*)atlas->permanent.alloc(
13661  atlas->permanent.userdata,0, sizeof(struct nk_font_glyph)*(nk_size)atlas->glyph_count);
13662  NK_ASSERT(atlas->glyphs);
13663  if (!atlas->glyphs)
13664  goto failed;
13665 
13666  /* pack all glyphs into a tight fit space */
13667  atlas->custom.w = (NK_CURSOR_DATA_W*2)+1;
13668  atlas->custom.h = NK_CURSOR_DATA_H + 1;
13669  if (!nk_font_bake_pack(baker, &img_size, width, height, &atlas->custom,
13670  atlas->config, atlas->font_num, &atlas->temporary))
13671  goto failed;
13672 
13673  /* allocate memory for the baked image font atlas */
13674  atlas->pixel = atlas->temporary.alloc(atlas->temporary.userdata,0, img_size);
13675  NK_ASSERT(atlas->pixel);
13676  if (!atlas->pixel)
13677  goto failed;
13678 
13679  /* bake glyphs and custom white pixel into image */
13680  nk_font_bake(baker, atlas->pixel, *width, *height,
13681  atlas->glyphs, atlas->glyph_count, atlas->config, atlas->font_num);
13682  nk_font_bake_custom_data(atlas->pixel, *width, *height, atlas->custom,
13683  nk_custom_cursor_data, NK_CURSOR_DATA_W, NK_CURSOR_DATA_H, '.', 'X');
13684 
13685  if (fmt == NK_FONT_ATLAS_RGBA32) {
13686  /* convert alpha8 image into rgba32 image */
13687  void *img_rgba = atlas->temporary.alloc(atlas->temporary.userdata,0,
13688  (nk_size)(*width * *height * 4));
13689  NK_ASSERT(img_rgba);
13690  if (!img_rgba) goto failed;
13691  nk_font_bake_convert(img_rgba, *width, *height, atlas->pixel);
13692  atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
13693  atlas->pixel = img_rgba;
13694  }
13695  atlas->tex_width = *width;
13696  atlas->tex_height = *height;
13697 
13698  /* initialize each font */
13699  for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
13700  struct nk_font *font = font_iter;
13701  struct nk_font_config *config = font->config;
13702  nk_font_init(font, config->size, config->fallback_glyph, atlas->glyphs,
13703  config->font, nk_handle_ptr(0));
13704  }
13705 
13706  /* initialize each cursor */
13707  {NK_STORAGE const struct nk_vec2 nk_cursor_data[NK_CURSOR_COUNT][3] = {
13708  /* Pos Size Offset */
13709  {{ 0, 3}, {12,19}, { 0, 0}},
13710  {{13, 0}, { 7,16}, { 4, 8}},
13711  {{31, 0}, {23,23}, {11,11}},
13712  {{21, 0}, { 9, 23}, { 5,11}},
13713  {{55,18}, {23, 9}, {11, 5}},
13714  {{73, 0}, {17,17}, { 9, 9}},
13715  {{55, 0}, {17,17}, { 9, 9}}
13716  };
13717  for (i = 0; i < NK_CURSOR_COUNT; ++i) {
13718  struct nk_cursor *cursor = &atlas->cursors[i];
13719  cursor->img.w = (unsigned short)*width;
13720  cursor->img.h = (unsigned short)*height;
13721  cursor->img.region[0] = (unsigned short)(atlas->custom.x + nk_cursor_data[i][0].x);
13722  cursor->img.region[1] = (unsigned short)(atlas->custom.y + nk_cursor_data[i][0].y);
13723  cursor->img.region[2] = (unsigned short)nk_cursor_data[i][1].x;
13724  cursor->img.region[3] = (unsigned short)nk_cursor_data[i][1].y;
13725  cursor->size = nk_cursor_data[i][1];
13726  cursor->offset = nk_cursor_data[i][2];
13727  }}
13728  /* free temporary memory */
13729  atlas->temporary.free(atlas->temporary.userdata, tmp);
13730  return atlas->pixel;
13731 
13732 failed:
13733  /* error so cleanup all memory */
13734  if (tmp) atlas->temporary.free(atlas->temporary.userdata, tmp);
13735  if (atlas->glyphs) {
13736  atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
13737  atlas->glyphs = 0;
13738  }
13739  if (atlas->pixel) {
13740  atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
13741  atlas->pixel = 0;
13742  }
13743  return 0;
13744 }
13745 NK_API void
13746 nk_font_atlas_end(struct nk_font_atlas *atlas, nk_handle texture,
13747  struct nk_draw_null_texture *null)
13748 {
13749  int i = 0;
13750  struct nk_font *font_iter;
13751  NK_ASSERT(atlas);
13752  if (!atlas) {
13753  if (!null) return;
13754  null->texture = texture;
13755  null->uv = nk_vec2(0.5f,0.5f);
13756  }
13757  if (null) {
13758  null->texture = texture;
13759  null->uv.x = (atlas->custom.x + 0.5f)/(float)atlas->tex_width;
13760  null->uv.y = (atlas->custom.y + 0.5f)/(float)atlas->tex_height;
13761  }
13762  for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
13763  font_iter->texture = texture;
13764 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
13765  font_iter->handle.texture = texture;
13766 #endif
13767  }
13768  for (i = 0; i < NK_CURSOR_COUNT; ++i)
13769  atlas->cursors[i].img.handle = texture;
13770 
13771  atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
13772  atlas->pixel = 0;
13773  atlas->tex_width = 0;
13774  atlas->tex_height = 0;
13775  atlas->custom.x = 0;
13776  atlas->custom.y = 0;
13777  atlas->custom.w = 0;
13778  atlas->custom.h = 0;
13779 }
13780 NK_API void
13781 nk_font_atlas_cleanup(struct nk_font_atlas *atlas)
13782 {
13783  NK_ASSERT(atlas);
13784  NK_ASSERT(atlas->temporary.alloc);
13785  NK_ASSERT(atlas->temporary.free);
13786  NK_ASSERT(atlas->permanent.alloc);
13787  NK_ASSERT(atlas->permanent.free);
13788  if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return;
13789  if (atlas->config) {
13790  struct nk_font_config *iter;
13791  for (iter = atlas->config; iter; iter = iter->next) {
13792  struct nk_font_config *i;
13793  for (i = iter->n; i != iter; i = i->n) {
13794  atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
13795  i->ttf_blob = 0;
13796  }
13797  atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
13798  iter->ttf_blob = 0;
13799  }
13800  }
13801 }
13802 NK_API void
13803 nk_font_atlas_clear(struct nk_font_atlas *atlas)
13804 {
13805  NK_ASSERT(atlas);
13806  NK_ASSERT(atlas->temporary.alloc);
13807  NK_ASSERT(atlas->temporary.free);
13808  NK_ASSERT(atlas->permanent.alloc);
13809  NK_ASSERT(atlas->permanent.free);
13810  if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return;
13811 
13812  if (atlas->config) {
13813  struct nk_font_config *iter, *next;
13814  for (iter = atlas->config; iter; iter = next) {
13815  struct nk_font_config *i, *n;
13816  for (i = iter->n; i != iter; i = n) {
13817  n = i->n;
13818  if (i->ttf_blob)
13819  atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
13820  atlas->permanent.free(atlas->permanent.userdata, i);
13821  }
13822  next = iter->next;
13823  if (i->ttf_blob)
13824  atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
13825  atlas->permanent.free(atlas->permanent.userdata, iter);
13826  }
13827  atlas->config = 0;
13828  }
13829  if (atlas->fonts) {
13830  struct nk_font *iter, *next;
13831  for (iter = atlas->fonts; iter; iter = next) {
13832  next = iter->next;
13833  atlas->permanent.free(atlas->permanent.userdata, iter);
13834  }
13835  atlas->fonts = 0;
13836  }
13837  if (atlas->glyphs)
13838  atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
13839  nk_zero_struct(*atlas);
13840 }
13841 #endif
13842 
13843 
13844 
13845 
13846 
13847 /* ===============================================================
13848  *
13849  * INPUT
13850  *
13851  * ===============================================================*/
13852 NK_API void
13853 nk_input_begin(struct nk_context *ctx)
13854 {
13855  int i;
13856  struct nk_input *in;
13857  NK_ASSERT(ctx);
13858  if (!ctx) return;
13859  in = &ctx->input;
13860  for (i = 0; i < NK_BUTTON_MAX; ++i)
13861  in->mouse.buttons[i].clicked = 0;
13862 
13863  in->keyboard.text_len = 0;
13864  in->mouse.scroll_delta = nk_vec2(0,0);
13865  in->mouse.prev.x = in->mouse.pos.x;
13866  in->mouse.prev.y = in->mouse.pos.y;
13867  in->mouse.delta.x = 0;
13868  in->mouse.delta.y = 0;
13869  for (i = 0; i < NK_KEY_MAX; i++)
13870  in->keyboard.keys[i].clicked = 0;
13871 }
13872 NK_API void
13873 nk_input_end(struct nk_context *ctx)
13874 {
13875  struct nk_input *in;
13876  NK_ASSERT(ctx);
13877  if (!ctx) return;
13878  in = &ctx->input;
13879  if (in->mouse.grab)
13880  in->mouse.grab = 0;
13881  if (in->mouse.ungrab) {
13882  in->mouse.grabbed = 0;
13883  in->mouse.ungrab = 0;
13884  in->mouse.grab = 0;
13885  }
13886 }
13887 NK_API void
13888 nk_input_motion(struct nk_context *ctx, int x, int y)
13889 {
13890  struct nk_input *in;
13891  NK_ASSERT(ctx);
13892  if (!ctx) return;
13893  in = &ctx->input;
13894  in->mouse.pos.x = (float)x;
13895  in->mouse.pos.y = (float)y;
13896  in->mouse.delta.x = in->mouse.pos.x - in->mouse.prev.x;
13897  in->mouse.delta.y = in->mouse.pos.y - in->mouse.prev.y;
13898 }
13899 NK_API void
13900 nk_input_key(struct nk_context *ctx, enum nk_keys key, int down)
13901 {
13902  struct nk_input *in;
13903  NK_ASSERT(ctx);
13904  if (!ctx) return;
13905  in = &ctx->input;
13906  if (in->keyboard.keys[key].down != down)
13907  in->keyboard.keys[key].clicked++;
13908  in->keyboard.keys[key].down = down;
13909 }
13910 NK_API void
13911 nk_input_button(struct nk_context *ctx, enum nk_buttons id, int x, int y, int down)
13912 {
13913  struct nk_mouse_button *btn;
13914  struct nk_input *in;
13915  NK_ASSERT(ctx);
13916  if (!ctx) return;
13917  in = &ctx->input;
13918  if (in->mouse.buttons[id].down == down) return;
13919 
13920  btn = &in->mouse.buttons[id];
13921  btn->clicked_pos.x = (float)x;
13922  btn->clicked_pos.y = (float)y;
13923  btn->down = down;
13924  btn->clicked++;
13925 }
13926 NK_API void
13927 nk_input_scroll(struct nk_context *ctx, struct nk_vec2 val)
13928 {
13929  NK_ASSERT(ctx);
13930  if (!ctx) return;
13931  ctx->input.mouse.scroll_delta.x += val.x;
13932  ctx->input.mouse.scroll_delta.y += val.y;
13933 }
13934 NK_API void
13935 nk_input_glyph(struct nk_context *ctx, const nk_glyph glyph)
13936 {
13937  int len = 0;
13938  nk_rune unicode;
13939  struct nk_input *in;
13940 
13941  NK_ASSERT(ctx);
13942  if (!ctx) return;
13943  in = &ctx->input;
13944 
13945  len = nk_utf_decode(glyph, &unicode, NK_UTF_SIZE);
13946  if (len && ((in->keyboard.text_len + len) < NK_INPUT_MAX)) {
13947  nk_utf_encode(unicode, &in->keyboard.text[in->keyboard.text_len],
13949  in->keyboard.text_len += len;
13950  }
13951 }
13952 NK_API void
13953 nk_input_char(struct nk_context *ctx, char c)
13954 {
13955  nk_glyph glyph;
13956  NK_ASSERT(ctx);
13957  if (!ctx) return;
13958  glyph[0] = c;
13959  nk_input_glyph(ctx, glyph);
13960 }
13961 NK_API void
13962 nk_input_unicode(struct nk_context *ctx, nk_rune unicode)
13963 {
13964  nk_glyph rune;
13965  NK_ASSERT(ctx);
13966  if (!ctx) return;
13967  nk_utf_encode(unicode, rune, NK_UTF_SIZE);
13968  nk_input_glyph(ctx, rune);
13969 }
13970 NK_API int
13971 nk_input_has_mouse_click(const struct nk_input *i, enum nk_buttons id)
13972 {
13973  const struct nk_mouse_button *btn;
13974  if (!i) return nk_false;
13975  btn = &i->mouse.buttons[id];
13976  return (btn->clicked && btn->down == nk_false) ? nk_true : nk_false;
13977 }
13978 NK_API int
13979 nk_input_has_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id,
13980  struct nk_rect b)
13981 {
13982  const struct nk_mouse_button *btn;
13983  if (!i) return nk_false;
13984  btn = &i->mouse.buttons[id];
13985  if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h))
13986  return nk_false;
13987  return nk_true;
13988 }
13989 NK_API int
13991  struct nk_rect b, int down)
13992 {
13993  const struct nk_mouse_button *btn;
13994  if (!i) return nk_false;
13995  btn = &i->mouse.buttons[id];
13996  return nk_input_has_mouse_click_in_rect(i, id, b) && (btn->down == down);
13997 }
13998 NK_API int
13999 nk_input_is_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id,
14000  struct nk_rect b)
14001 {
14002  const struct nk_mouse_button *btn;
14003  if (!i) return nk_false;
14004  btn = &i->mouse.buttons[id];
14005  return (nk_input_has_mouse_click_down_in_rect(i, id, b, nk_false) &&
14006  btn->clicked) ? nk_true : nk_false;
14007 }
14008 NK_API int
14010  struct nk_rect b, int down)
14011 {
14012  const struct nk_mouse_button *btn;
14013  if (!i) return nk_false;
14014  btn = &i->mouse.buttons[id];
14015  return (nk_input_has_mouse_click_down_in_rect(i, id, b, down) &&
14016  btn->clicked) ? nk_true : nk_false;
14017 }
14018 NK_API int
14019 nk_input_any_mouse_click_in_rect(const struct nk_input *in, struct nk_rect b)
14020 {
14021  int i, down = 0;
14022  for (i = 0; i < NK_BUTTON_MAX; ++i)
14023  down = down || nk_input_is_mouse_click_in_rect(in, (enum nk_buttons)i, b);
14024  return down;
14025 }
14026 NK_API int
14027 nk_input_is_mouse_hovering_rect(const struct nk_input *i, struct nk_rect rect)
14028 {
14029  if (!i) return nk_false;
14030  return NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h);
14031 }
14032 NK_API int
14033 nk_input_is_mouse_prev_hovering_rect(const struct nk_input *i, struct nk_rect rect)
14034 {
14035  if (!i) return nk_false;
14036  return NK_INBOX(i->mouse.prev.x, i->mouse.prev.y, rect.x, rect.y, rect.w, rect.h);
14037 }
14038 NK_API int
14039 nk_input_mouse_clicked(const struct nk_input *i, enum nk_buttons id, struct nk_rect rect)
14040 {
14041  if (!i) return nk_false;
14042  if (!nk_input_is_mouse_hovering_rect(i, rect)) return nk_false;
14043  return nk_input_is_mouse_click_in_rect(i, id, rect);
14044 }
14045 NK_API int
14046 nk_input_is_mouse_down(const struct nk_input *i, enum nk_buttons id)
14047 {
14048  if (!i) return nk_false;
14049  return i->mouse.buttons[id].down;
14050 }
14051 NK_API int
14052 nk_input_is_mouse_pressed(const struct nk_input *i, enum nk_buttons id)
14053 {
14054  const struct nk_mouse_button *b;
14055  if (!i) return nk_false;
14056  b = &i->mouse.buttons[id];
14057  if (b->down && b->clicked)
14058  return nk_true;
14059  return nk_false;
14060 }
14061 NK_API int
14062 nk_input_is_mouse_released(const struct nk_input *i, enum nk_buttons id)
14063 {
14064  if (!i) return nk_false;
14065  return (!i->mouse.buttons[id].down && i->mouse.buttons[id].clicked);
14066 }
14067 NK_API int
14068 nk_input_is_key_pressed(const struct nk_input *i, enum nk_keys key)
14069 {
14070  const struct nk_key *k;
14071  if (!i) return nk_false;
14072  k = &i->keyboard.keys[key];
14073  if ((k->down && k->clicked) || (!k->down && k->clicked >= 2))
14074  return nk_true;
14075  return nk_false;
14076 }
14077 NK_API int
14078 nk_input_is_key_released(const struct nk_input *i, enum nk_keys key)
14079 {
14080  const struct nk_key *k;
14081  if (!i) return nk_false;
14082  k = &i->keyboard.keys[key];
14083  if ((!k->down && k->clicked) || (k->down && k->clicked >= 2))
14084  return nk_true;
14085  return nk_false;
14086 }
14087 NK_API int
14088 nk_input_is_key_down(const struct nk_input *i, enum nk_keys key)
14089 {
14090  const struct nk_key *k;
14091  if (!i) return nk_false;
14092  k = &i->keyboard.keys[key];
14093  if (k->down) return nk_true;
14094  return nk_false;
14095 }
14096 
14097 
14098 
14099 
14100 
14101 /* ===============================================================
14102  *
14103  * STYLE
14104  *
14105  * ===============================================================*/
14106 NK_API void nk_style_default(struct nk_context *ctx){nk_style_from_table(ctx, 0);}
14107 #define NK_COLOR_MAP(NK_COLOR)\
14108  NK_COLOR(NK_COLOR_TEXT, 175,175,175,255) \
14109  NK_COLOR(NK_COLOR_WINDOW, 45, 45, 45, 255) \
14110  NK_COLOR(NK_COLOR_HEADER, 40, 40, 40, 255) \
14111  NK_COLOR(NK_COLOR_BORDER, 65, 65, 65, 255) \
14112  NK_COLOR(NK_COLOR_BUTTON, 50, 50, 50, 255) \
14113  NK_COLOR(NK_COLOR_BUTTON_HOVER, 40, 40, 40, 255) \
14114  NK_COLOR(NK_COLOR_BUTTON_ACTIVE, 35, 35, 35, 255) \
14115  NK_COLOR(NK_COLOR_TOGGLE, 100,100,100,255) \
14116  NK_COLOR(NK_COLOR_TOGGLE_HOVER, 120,120,120,255) \
14117  NK_COLOR(NK_COLOR_TOGGLE_CURSOR, 45, 45, 45, 255) \
14118  NK_COLOR(NK_COLOR_SELECT, 45, 45, 45, 255) \
14119  NK_COLOR(NK_COLOR_SELECT_ACTIVE, 35, 35, 35,255) \
14120  NK_COLOR(NK_COLOR_SLIDER, 38, 38, 38, 255) \
14121  NK_COLOR(NK_COLOR_SLIDER_CURSOR, 100,100,100,255) \
14122  NK_COLOR(NK_COLOR_SLIDER_CURSOR_HOVER, 120,120,120,255) \
14123  NK_COLOR(NK_COLOR_SLIDER_CURSOR_ACTIVE, 150,150,150,255) \
14124  NK_COLOR(NK_COLOR_PROPERTY, 38, 38, 38, 255) \
14125  NK_COLOR(NK_COLOR_EDIT, 38, 38, 38, 255) \
14126  NK_COLOR(NK_COLOR_EDIT_CURSOR, 175,175,175,255) \
14127  NK_COLOR(NK_COLOR_COMBO, 45, 45, 45, 255) \
14128  NK_COLOR(NK_COLOR_CHART, 120,120,120,255) \
14129  NK_COLOR(NK_COLOR_CHART_COLOR, 45, 45, 45, 255) \
14130  NK_COLOR(NK_COLOR_CHART_COLOR_HIGHLIGHT, 255, 0, 0, 255) \
14131  NK_COLOR(NK_COLOR_SCROLLBAR, 40, 40, 40, 255) \
14132  NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR, 100,100,100,255) \
14133  NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_HOVER, 120,120,120,255) \
14134  NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_ACTIVE, 150,150,150,255) \
14135  NK_COLOR(NK_COLOR_TAB_HEADER, 40, 40, 40,255)
14136 
14137 NK_GLOBAL const struct nk_color
14138 nk_default_color_style[NK_COLOR_COUNT] = {
14139 #define NK_COLOR(a,b,c,d,e) {b,c,d,e},
14140  NK_COLOR_MAP(NK_COLOR)
14141 #undef NK_COLOR
14142 };
14143 NK_GLOBAL const char *nk_color_names[NK_COLOR_COUNT] = {
14144 #define NK_COLOR(a,b,c,d,e) #a,
14145  NK_COLOR_MAP(NK_COLOR)
14146 #undef NK_COLOR
14147 };
14148 
14149 NK_API const char*
14151 {
14152  return nk_color_names[c];
14153 }
14154 NK_API struct nk_style_item
14155 nk_style_item_image(struct nk_image img)
14156 {
14157  struct nk_style_item i;
14158  i.type = NK_STYLE_ITEM_IMAGE;
14159  i.data.image = img;
14160  return i;
14161 }
14162 NK_API struct nk_style_item
14163 nk_style_item_color(struct nk_color col)
14164 {
14165  struct nk_style_item i;
14166  i.type = NK_STYLE_ITEM_COLOR;
14167  i.data.color = col;
14168  return i;
14169 }
14170 NK_API struct nk_style_item
14172 {
14173  struct nk_style_item i;
14174  i.type = NK_STYLE_ITEM_COLOR;
14175  i.data.color = nk_rgba(0,0,0,0);
14176  return i;
14177 }
14178 NK_API void
14179 nk_style_from_table(struct nk_context *ctx, const struct nk_color *table)
14180 {
14181  struct nk_style *style;
14182  struct nk_style_text *text;
14183  struct nk_style_button *button;
14184  struct nk_style_toggle *toggle;
14185  struct nk_style_selectable *select;
14186  struct nk_style_slider *slider;
14187  struct nk_style_progress *prog;
14188  struct nk_style_scrollbar *scroll;
14189  struct nk_style_edit *edit;
14190  struct nk_style_property *property;
14191  struct nk_style_combo *combo;
14192  struct nk_style_chart *chart;
14193  struct nk_style_tab *tab;
14194  struct nk_style_window *win;
14195 
14196  NK_ASSERT(ctx);
14197  if (!ctx) return;
14198  style = &ctx->style;
14199  table = (!table) ? nk_default_color_style: table;
14200 
14201  /* default text */
14202  text = &style->text;
14203  text->color = table[NK_COLOR_TEXT];
14204  text->padding = nk_vec2(0,0);
14205 
14206  /* default button */
14207  button = &style->button;
14208  nk_zero_struct(*button);
14209  button->normal = nk_style_item_color(table[NK_COLOR_BUTTON]);
14212  button->border_color = table[NK_COLOR_BORDER];
14213  button->text_background = table[NK_COLOR_BUTTON];
14214  button->text_normal = table[NK_COLOR_TEXT];
14215  button->text_hover = table[NK_COLOR_TEXT];
14216  button->text_active = table[NK_COLOR_TEXT];
14217  button->padding = nk_vec2(2.0f,2.0f);
14218  button->image_padding = nk_vec2(0.0f,0.0f);
14219  button->touch_padding = nk_vec2(0.0f, 0.0f);
14220  button->userdata = nk_handle_ptr(0);
14221  button->text_alignment = NK_TEXT_CENTERED;
14222  button->border = 1.0f;
14223  button->rounding = 4.0f;
14224  button->draw_begin = 0;
14225  button->draw_end = 0;
14226 
14227  /* contextual button */
14228  button = &style->contextual_button;
14229  nk_zero_struct(*button);
14230  button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
14233  button->border_color = table[NK_COLOR_WINDOW];
14234  button->text_background = table[NK_COLOR_WINDOW];
14235  button->text_normal = table[NK_COLOR_TEXT];
14236  button->text_hover = table[NK_COLOR_TEXT];
14237  button->text_active = table[NK_COLOR_TEXT];
14238  button->padding = nk_vec2(2.0f,2.0f);
14239  button->touch_padding = nk_vec2(0.0f,0.0f);
14240  button->userdata = nk_handle_ptr(0);
14241  button->text_alignment = NK_TEXT_CENTERED;
14242  button->border = 0.0f;
14243  button->rounding = 0.0f;
14244  button->draw_begin = 0;
14245  button->draw_end = 0;
14246 
14247  /* menu button */
14248  button = &style->menu_button;
14249  nk_zero_struct(*button);
14250  button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
14251  button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]);
14252  button->active = nk_style_item_color(table[NK_COLOR_WINDOW]);
14253  button->border_color = table[NK_COLOR_WINDOW];
14254  button->text_background = table[NK_COLOR_WINDOW];
14255  button->text_normal = table[NK_COLOR_TEXT];
14256  button->text_hover = table[NK_COLOR_TEXT];
14257  button->text_active = table[NK_COLOR_TEXT];
14258  button->padding = nk_vec2(2.0f,2.0f);
14259  button->touch_padding = nk_vec2(0.0f,0.0f);
14260  button->userdata = nk_handle_ptr(0);
14261  button->text_alignment = NK_TEXT_CENTERED;
14262  button->border = 0.0f;
14263  button->rounding = 1.0f;
14264  button->draw_begin = 0;
14265  button->draw_end = 0;
14266 
14267  /* checkbox toggle */
14268  toggle = &style->checkbox;
14269  nk_zero_struct(*toggle);
14270  toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]);
14275  toggle->userdata = nk_handle_ptr(0);
14276  toggle->text_background = table[NK_COLOR_WINDOW];
14277  toggle->text_normal = table[NK_COLOR_TEXT];
14278  toggle->text_hover = table[NK_COLOR_TEXT];
14279  toggle->text_active = table[NK_COLOR_TEXT];
14280  toggle->padding = nk_vec2(2.0f, 2.0f);
14281  toggle->touch_padding = nk_vec2(0,0);
14282  toggle->border_color = nk_rgba(0,0,0,0);
14283  toggle->border = 0.0f;
14284  toggle->spacing = 4;
14285 
14286  /* option toggle */
14287  toggle = &style->option;
14288  nk_zero_struct(*toggle);
14289  toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]);
14294  toggle->userdata = nk_handle_ptr(0);
14295  toggle->text_background = table[NK_COLOR_WINDOW];
14296  toggle->text_normal = table[NK_COLOR_TEXT];
14297  toggle->text_hover = table[NK_COLOR_TEXT];
14298  toggle->text_active = table[NK_COLOR_TEXT];
14299  toggle->padding = nk_vec2(3.0f, 3.0f);
14300  toggle->touch_padding = nk_vec2(0,0);
14301  toggle->border_color = nk_rgba(0,0,0,0);
14302  toggle->border = 0.0f;
14303  toggle->spacing = 4;
14304 
14305  /* selectable */
14306  select = &style->selectable;
14307  nk_zero_struct(*select);
14308  select->normal = nk_style_item_color(table[NK_COLOR_SELECT]);
14309  select->hover = nk_style_item_color(table[NK_COLOR_SELECT]);
14310  select->pressed = nk_style_item_color(table[NK_COLOR_SELECT]);
14314  select->text_normal = table[NK_COLOR_TEXT];
14315  select->text_hover = table[NK_COLOR_TEXT];
14316  select->text_pressed = table[NK_COLOR_TEXT];
14317  select->text_normal_active = table[NK_COLOR_TEXT];
14318  select->text_hover_active = table[NK_COLOR_TEXT];
14319  select->text_pressed_active = table[NK_COLOR_TEXT];
14320  select->padding = nk_vec2(2.0f,2.0f);
14321  select->image_padding = nk_vec2(2.0f,2.0f);
14322  select->touch_padding = nk_vec2(0,0);
14323  select->userdata = nk_handle_ptr(0);
14324  select->rounding = 0.0f;
14325  select->draw_begin = 0;
14326  select->draw_end = 0;
14327 
14328  /* slider */
14329  slider = &style->slider;
14330  nk_zero_struct(*slider);
14331  slider->normal = nk_style_item_hide();
14332  slider->hover = nk_style_item_hide();
14333  slider->active = nk_style_item_hide();
14334  slider->bar_normal = table[NK_COLOR_SLIDER];
14335  slider->bar_hover = table[NK_COLOR_SLIDER];
14336  slider->bar_active = table[NK_COLOR_SLIDER];
14337  slider->bar_filled = table[NK_COLOR_SLIDER_CURSOR];
14343  slider->cursor_size = nk_vec2(16,16);
14344  slider->padding = nk_vec2(2,2);
14345  slider->spacing = nk_vec2(2,2);
14346  slider->userdata = nk_handle_ptr(0);
14347  slider->show_buttons = nk_false;
14348  slider->bar_height = 8;
14349  slider->rounding = 0;
14350  slider->draw_begin = 0;
14351  slider->draw_end = 0;
14352 
14353  /* slider buttons */
14354  button = &style->slider.inc_button;
14355  button->normal = nk_style_item_color(nk_rgb(40,40,40));
14356  button->hover = nk_style_item_color(nk_rgb(42,42,42));
14357  button->active = nk_style_item_color(nk_rgb(44,44,44));
14358  button->border_color = nk_rgb(65,65,65);
14359  button->text_background = nk_rgb(40,40,40);
14360  button->text_normal = nk_rgb(175,175,175);
14361  button->text_hover = nk_rgb(175,175,175);
14362  button->text_active = nk_rgb(175,175,175);
14363  button->padding = nk_vec2(8.0f,8.0f);
14364  button->touch_padding = nk_vec2(0.0f,0.0f);
14365  button->userdata = nk_handle_ptr(0);
14366  button->text_alignment = NK_TEXT_CENTERED;
14367  button->border = 1.0f;
14368  button->rounding = 0.0f;
14369  button->draw_begin = 0;
14370  button->draw_end = 0;
14371  style->slider.dec_button = style->slider.inc_button;
14372 
14373  /* progressbar */
14374  prog = &style->progress;
14375  nk_zero_struct(*prog);
14376  prog->normal = nk_style_item_color(table[NK_COLOR_SLIDER]);
14377  prog->hover = nk_style_item_color(table[NK_COLOR_SLIDER]);
14378  prog->active = nk_style_item_color(table[NK_COLOR_SLIDER]);
14382  prog->border_color = nk_rgba(0,0,0,0);
14383  prog->cursor_border_color = nk_rgba(0,0,0,0);
14384  prog->userdata = nk_handle_ptr(0);
14385  prog->padding = nk_vec2(4,4);
14386  prog->rounding = 0;
14387  prog->border = 0;
14388  prog->cursor_rounding = 0;
14389  prog->cursor_border = 0;
14390  prog->draw_begin = 0;
14391  prog->draw_end = 0;
14392 
14393  /* scrollbars */
14394  scroll = &style->scrollh;
14395  nk_zero_struct(*scroll);
14396  scroll->normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
14397  scroll->hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
14398  scroll->active = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
14404  scroll->userdata = nk_handle_ptr(0);
14405  scroll->border_color = table[NK_COLOR_SCROLLBAR];
14406  scroll->cursor_border_color = table[NK_COLOR_SCROLLBAR];
14407  scroll->padding = nk_vec2(0,0);
14408  scroll->show_buttons = nk_false;
14409  scroll->border = 0;
14410  scroll->rounding = 0;
14411  scroll->border_cursor = 0;
14412  scroll->rounding_cursor = 0;
14413  scroll->draw_begin = 0;
14414  scroll->draw_end = 0;
14415  style->scrollv = style->scrollh;
14416 
14417  /* scrollbars buttons */
14418  button = &style->scrollh.inc_button;
14419  button->normal = nk_style_item_color(nk_rgb(40,40,40));
14420  button->hover = nk_style_item_color(nk_rgb(42,42,42));
14421  button->active = nk_style_item_color(nk_rgb(44,44,44));
14422  button->border_color = nk_rgb(65,65,65);
14423  button->text_background = nk_rgb(40,40,40);
14424  button->text_normal = nk_rgb(175,175,175);
14425  button->text_hover = nk_rgb(175,175,175);
14426  button->text_active = nk_rgb(175,175,175);
14427  button->padding = nk_vec2(4.0f,4.0f);
14428  button->touch_padding = nk_vec2(0.0f,0.0f);
14429  button->userdata = nk_handle_ptr(0);
14430  button->text_alignment = NK_TEXT_CENTERED;
14431  button->border = 1.0f;
14432  button->rounding = 0.0f;
14433  button->draw_begin = 0;
14434  button->draw_end = 0;
14435  style->scrollh.dec_button = style->scrollh.inc_button;
14436  style->scrollv.inc_button = style->scrollh.inc_button;
14437  style->scrollv.dec_button = style->scrollh.inc_button;
14438 
14439  /* edit */
14440  edit = &style->edit;
14441  nk_zero_struct(*edit);
14442  edit->normal = nk_style_item_color(table[NK_COLOR_EDIT]);
14443  edit->hover = nk_style_item_color(table[NK_COLOR_EDIT]);
14444  edit->active = nk_style_item_color(table[NK_COLOR_EDIT]);
14445  edit->cursor_normal = table[NK_COLOR_TEXT];
14446  edit->cursor_hover = table[NK_COLOR_TEXT];
14447  edit->cursor_text_normal= table[NK_COLOR_EDIT];
14448  edit->cursor_text_hover = table[NK_COLOR_EDIT];
14449  edit->border_color = table[NK_COLOR_BORDER];
14450  edit->text_normal = table[NK_COLOR_TEXT];
14451  edit->text_hover = table[NK_COLOR_TEXT];
14452  edit->text_active = table[NK_COLOR_TEXT];
14453  edit->selected_normal = table[NK_COLOR_TEXT];
14454  edit->selected_hover = table[NK_COLOR_TEXT];
14455  edit->selected_text_normal = table[NK_COLOR_EDIT];
14456  edit->selected_text_hover = table[NK_COLOR_EDIT];
14457  edit->scrollbar_size = nk_vec2(10,10);
14458  edit->scrollbar = style->scrollv;
14459  edit->padding = nk_vec2(4,4);
14460  edit->row_padding = 2;
14461  edit->cursor_size = 4;
14462  edit->border = 1;
14463  edit->rounding = 0;
14464 
14465  /* property */
14466  property = &style->property;
14467  nk_zero_struct(*property);
14468  property->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14469  property->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14470  property->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14471  property->border_color = table[NK_COLOR_BORDER];
14472  property->label_normal = table[NK_COLOR_TEXT];
14473  property->label_hover = table[NK_COLOR_TEXT];
14474  property->label_active = table[NK_COLOR_TEXT];
14475  property->sym_left = NK_SYMBOL_TRIANGLE_LEFT;
14476  property->sym_right = NK_SYMBOL_TRIANGLE_RIGHT;
14477  property->userdata = nk_handle_ptr(0);
14478  property->padding = nk_vec2(4,4);
14479  property->border = 1;
14480  property->rounding = 10;
14481  property->draw_begin = 0;
14482  property->draw_end = 0;
14483 
14484  /* property buttons */
14485  button = &style->property.dec_button;
14486  nk_zero_struct(*button);
14487  button->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14488  button->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14489  button->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
14490  button->border_color = nk_rgba(0,0,0,0);
14491  button->text_background = table[NK_COLOR_PROPERTY];
14492  button->text_normal = table[NK_COLOR_TEXT];
14493  button->text_hover = table[NK_COLOR_TEXT];
14494  button->text_active = table[NK_COLOR_TEXT];
14495  button->padding = nk_vec2(0.0f,0.0f);
14496  button->touch_padding = nk_vec2(0.0f,0.0f);
14497  button->userdata = nk_handle_ptr(0);
14498  button->text_alignment = NK_TEXT_CENTERED;
14499  button->border = 0.0f;
14500  button->rounding = 0.0f;
14501  button->draw_begin = 0;
14502  button->draw_end = 0;
14503  style->property.inc_button = style->property.dec_button;
14504 
14505  /* property edit */
14506  edit = &style->property.edit;
14507  nk_zero_struct(*edit);
14511  edit->border_color = nk_rgba(0,0,0,0);
14512  edit->cursor_normal = table[NK_COLOR_TEXT];
14513  edit->cursor_hover = table[NK_COLOR_TEXT];
14514  edit->cursor_text_normal= table[NK_COLOR_EDIT];
14515  edit->cursor_text_hover = table[NK_COLOR_EDIT];
14516  edit->text_normal = table[NK_COLOR_TEXT];
14517  edit->text_hover = table[NK_COLOR_TEXT];
14518  edit->text_active = table[NK_COLOR_TEXT];
14519  edit->selected_normal = table[NK_COLOR_TEXT];
14520  edit->selected_hover = table[NK_COLOR_TEXT];
14521  edit->selected_text_normal = table[NK_COLOR_EDIT];
14522  edit->selected_text_hover = table[NK_COLOR_EDIT];
14523  edit->padding = nk_vec2(0,0);
14524  edit->cursor_size = 8;
14525  edit->border = 0;
14526  edit->rounding = 0;
14527 
14528  /* chart */
14529  chart = &style->chart;
14530  nk_zero_struct(*chart);
14532  chart->border_color = table[NK_COLOR_BORDER];
14534  chart->color = table[NK_COLOR_CHART_COLOR];
14535  chart->padding = nk_vec2(4,4);
14536  chart->border = 0;
14537  chart->rounding = 0;
14538 
14539  /* combo */
14540  combo = &style->combo;
14541  combo->normal = nk_style_item_color(table[NK_COLOR_COMBO]);
14542  combo->hover = nk_style_item_color(table[NK_COLOR_COMBO]);
14543  combo->active = nk_style_item_color(table[NK_COLOR_COMBO]);
14544  combo->border_color = table[NK_COLOR_BORDER];
14545  combo->label_normal = table[NK_COLOR_TEXT];
14546  combo->label_hover = table[NK_COLOR_TEXT];
14547  combo->label_active = table[NK_COLOR_TEXT];
14551  combo->content_padding = nk_vec2(4,4);
14552  combo->button_padding = nk_vec2(0,4);
14553  combo->spacing = nk_vec2(4,0);
14554  combo->border = 1;
14555  combo->rounding = 0;
14556 
14557  /* combo button */
14558  button = &style->combo.button;
14559  nk_zero_struct(*button);
14560  button->normal = nk_style_item_color(table[NK_COLOR_COMBO]);
14561  button->hover = nk_style_item_color(table[NK_COLOR_COMBO]);
14562  button->active = nk_style_item_color(table[NK_COLOR_COMBO]);
14563  button->border_color = nk_rgba(0,0,0,0);
14564  button->text_background = table[NK_COLOR_COMBO];
14565  button->text_normal = table[NK_COLOR_TEXT];
14566  button->text_hover = table[NK_COLOR_TEXT];
14567  button->text_active = table[NK_COLOR_TEXT];
14568  button->padding = nk_vec2(2.0f,2.0f);
14569  button->touch_padding = nk_vec2(0.0f,0.0f);
14570  button->userdata = nk_handle_ptr(0);
14571  button->text_alignment = NK_TEXT_CENTERED;
14572  button->border = 0.0f;
14573  button->rounding = 0.0f;
14574  button->draw_begin = 0;
14575  button->draw_end = 0;
14576 
14577  /* tab */
14578  tab = &style->tab;
14580  tab->border_color = table[NK_COLOR_BORDER];
14581  tab->text = table[NK_COLOR_TEXT];
14584  tab->padding = nk_vec2(4,4);
14585  tab->spacing = nk_vec2(4,4);
14586  tab->indent = 10.0f;
14587  tab->border = 1;
14588  tab->rounding = 0;
14589 
14590  /* tab button */
14591  button = &style->tab.tab_minimize_button;
14592  nk_zero_struct(*button);
14594  button->hover = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
14596  button->border_color = nk_rgba(0,0,0,0);
14597  button->text_background = table[NK_COLOR_TAB_HEADER];
14598  button->text_normal = table[NK_COLOR_TEXT];
14599  button->text_hover = table[NK_COLOR_TEXT];
14600  button->text_active = table[NK_COLOR_TEXT];
14601  button->padding = nk_vec2(2.0f,2.0f);
14602  button->touch_padding = nk_vec2(0.0f,0.0f);
14603  button->userdata = nk_handle_ptr(0);
14604  button->text_alignment = NK_TEXT_CENTERED;
14605  button->border = 0.0f;
14606  button->rounding = 0.0f;
14607  button->draw_begin = 0;
14608  button->draw_end = 0;
14609  style->tab.tab_maximize_button =*button;
14610 
14611  /* node button */
14612  button = &style->tab.node_minimize_button;
14613  nk_zero_struct(*button);
14614  button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
14615  button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]);
14616  button->active = nk_style_item_color(table[NK_COLOR_WINDOW]);
14617  button->border_color = nk_rgba(0,0,0,0);
14618  button->text_background = table[NK_COLOR_TAB_HEADER];
14619  button->text_normal = table[NK_COLOR_TEXT];
14620  button->text_hover = table[NK_COLOR_TEXT];
14621  button->text_active = table[NK_COLOR_TEXT];
14622  button->padding = nk_vec2(2.0f,2.0f);
14623  button->touch_padding = nk_vec2(0.0f,0.0f);
14624  button->userdata = nk_handle_ptr(0);
14625  button->text_alignment = NK_TEXT_CENTERED;
14626  button->border = 0.0f;
14627  button->rounding = 0.0f;
14628  button->draw_begin = 0;
14629  button->draw_end = 0;
14630  style->tab.node_maximize_button =*button;
14631 
14632  /* window header */
14633  win = &style->window;
14634  win->header.align = NK_HEADER_RIGHT;
14641  win->header.label_normal = table[NK_COLOR_TEXT];
14642  win->header.label_hover = table[NK_COLOR_TEXT];
14643  win->header.label_active = table[NK_COLOR_TEXT];
14644  win->header.label_padding = nk_vec2(4,4);
14645  win->header.padding = nk_vec2(4,4);
14646  win->header.spacing = nk_vec2(0,0);
14647 
14648  /* window header close button */
14649  button = &style->window.header.close_button;
14650  nk_zero_struct(*button);
14651  button->normal = nk_style_item_color(table[NK_COLOR_HEADER]);
14652  button->hover = nk_style_item_color(table[NK_COLOR_HEADER]);
14653  button->active = nk_style_item_color(table[NK_COLOR_HEADER]);
14654  button->border_color = nk_rgba(0,0,0,0);
14655  button->text_background = table[NK_COLOR_HEADER];
14656  button->text_normal = table[NK_COLOR_TEXT];
14657  button->text_hover = table[NK_COLOR_TEXT];
14658  button->text_active = table[NK_COLOR_TEXT];
14659  button->padding = nk_vec2(0.0f,0.0f);
14660  button->touch_padding = nk_vec2(0.0f,0.0f);
14661  button->userdata = nk_handle_ptr(0);
14662  button->text_alignment = NK_TEXT_CENTERED;
14663  button->border = 0.0f;
14664  button->rounding = 0.0f;
14665  button->draw_begin = 0;
14666  button->draw_end = 0;
14667 
14668  /* window header minimize button */
14669  button = &style->window.header.minimize_button;
14670  nk_zero_struct(*button);
14671  button->normal = nk_style_item_color(table[NK_COLOR_HEADER]);
14672  button->hover = nk_style_item_color(table[NK_COLOR_HEADER]);
14673  button->active = nk_style_item_color(table[NK_COLOR_HEADER]);
14674  button->border_color = nk_rgba(0,0,0,0);
14675  button->text_background = table[NK_COLOR_HEADER];
14676  button->text_normal = table[NK_COLOR_TEXT];
14677  button->text_hover = table[NK_COLOR_TEXT];
14678  button->text_active = table[NK_COLOR_TEXT];
14679  button->padding = nk_vec2(0.0f,0.0f);
14680  button->touch_padding = nk_vec2(0.0f,0.0f);
14681  button->userdata = nk_handle_ptr(0);
14682  button->text_alignment = NK_TEXT_CENTERED;
14683  button->border = 0.0f;
14684  button->rounding = 0.0f;
14685  button->draw_begin = 0;
14686  button->draw_end = 0;
14687 
14688  /* window */
14689  win->background = table[NK_COLOR_WINDOW];
14691  win->border_color = table[NK_COLOR_BORDER];
14692  win->popup_border_color = table[NK_COLOR_BORDER];
14693  win->combo_border_color = table[NK_COLOR_BORDER];
14695  win->menu_border_color = table[NK_COLOR_BORDER];
14696  win->group_border_color = table[NK_COLOR_BORDER];
14697  win->tooltip_border_color = table[NK_COLOR_BORDER];
14698  win->scaler = nk_style_item_color(table[NK_COLOR_TEXT]);
14699 
14700  win->rounding = 0.0f;
14701  win->spacing = nk_vec2(4,4);
14702  win->scrollbar_size = nk_vec2(10,10);
14703  win->min_size = nk_vec2(64,64);
14704 
14705  win->combo_border = 1.0f;
14706  win->contextual_border = 1.0f;
14707  win->menu_border = 1.0f;
14708  win->group_border = 1.0f;
14709  win->tooltip_border = 1.0f;
14710  win->popup_border = 1.0f;
14711  win->border = 2.0f;
14712  win->min_row_height_padding = 8;
14713 
14714  win->padding = nk_vec2(4,4);
14715  win->group_padding = nk_vec2(4,4);
14716  win->popup_padding = nk_vec2(4,4);
14717  win->combo_padding = nk_vec2(4,4);
14718  win->contextual_padding = nk_vec2(4,4);
14719  win->menu_padding = nk_vec2(4,4);
14720  win->tooltip_padding = nk_vec2(4,4);
14721 }
14722 NK_API void
14723 nk_style_set_font(struct nk_context *ctx, const struct nk_user_font *font)
14724 {
14725  struct nk_style *style;
14726  NK_ASSERT(ctx);
14727 
14728  if (!ctx) return;
14729  style = &ctx->style;
14730  style->font = font;
14731  ctx->stacks.fonts.head = 0;
14732  if (ctx->current)
14734 }
14735 NK_API int
14736 nk_style_push_font(struct nk_context *ctx, const struct nk_user_font *font)
14737 {
14738  struct nk_config_stack_user_font *font_stack;
14739  struct nk_config_stack_user_font_element *element;
14740 
14741  NK_ASSERT(ctx);
14742  if (!ctx) return 0;
14743 
14744  font_stack = &ctx->stacks.fonts;
14745  NK_ASSERT(font_stack->head < (int)NK_LEN(font_stack->elements));
14746  if (font_stack->head >= (int)NK_LEN(font_stack->elements))
14747  return 0;
14748 
14749  element = &font_stack->elements[font_stack->head++];
14750  element->address = &ctx->style.font;
14751  element->old_value = ctx->style.font;
14752  ctx->style.font = font;
14753  return 1;
14754 }
14755 NK_API int
14756 nk_style_pop_font(struct nk_context *ctx)
14757 {
14758  struct nk_config_stack_user_font *font_stack;
14759  struct nk_config_stack_user_font_element *element;
14760 
14761  NK_ASSERT(ctx);
14762  if (!ctx) return 0;
14763 
14764  font_stack = &ctx->stacks.fonts;
14765  NK_ASSERT(font_stack->head > 0);
14766  if (font_stack->head < 1)
14767  return 0;
14768 
14769  element = &font_stack->elements[--font_stack->head];
14770  *element->address = element->old_value;
14771  return 1;
14772 }
14773 #define NK_STYLE_PUSH_IMPLEMENATION(prefix, type, stack) \
14774 nk_style_push_##type(struct nk_context *ctx, prefix##_##type *address, prefix##_##type value)\
14775 {\
14776  struct nk_config_stack_##type * type_stack;\
14777  struct nk_config_stack_##type##_element *element;\
14778  NK_ASSERT(ctx);\
14779  if (!ctx) return 0;\
14780  type_stack = &ctx->stacks.stack;\
14781  NK_ASSERT(type_stack->head < (int)NK_LEN(type_stack->elements));\
14782  if (type_stack->head >= (int)NK_LEN(type_stack->elements))\
14783  return 0;\
14784  element = &type_stack->elements[type_stack->head++];\
14785  element->address = address;\
14786  element->old_value = *address;\
14787  *address = value;\
14788  return 1;\
14789 }
14790 #define NK_STYLE_POP_IMPLEMENATION(type, stack) \
14791 nk_style_pop_##type(struct nk_context *ctx)\
14792 {\
14793  struct nk_config_stack_##type *type_stack;\
14794  struct nk_config_stack_##type##_element *element;\
14795  NK_ASSERT(ctx);\
14796  if (!ctx) return 0;\
14797  type_stack = &ctx->stacks.stack;\
14798  NK_ASSERT(type_stack->head > 0);\
14799  if (type_stack->head < 1)\
14800  return 0;\
14801  element = &type_stack->elements[--type_stack->head];\
14802  *element->address = element->old_value;\
14803  return 1;\
14804 }
14805 NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk, style_item, style_items)
14806 NK_API int NK_STYLE_PUSH_IMPLEMENATION(nk,float, floats)
14807 NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk, vec2, vectors)
14808 NK_API int NK_STYLE_PUSH_IMPLEMENATION(nk,flags, flags)
14809 NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk,color, colors)
14810 
14811 NK_API int NK_STYLE_POP_IMPLEMENATION(style_item, style_items)
14812 NK_API int NK_STYLE_POP_IMPLEMENATION(float,floats)
14813 NK_API int NK_STYLE_POP_IMPLEMENATION(vec2, vectors)
14814 NK_API int NK_STYLE_POP_IMPLEMENATION(flags,flags)
14815 NK_API int NK_STYLE_POP_IMPLEMENATION(color,colors)
14816 
14817 NK_API int
14818 nk_style_set_cursor(struct nk_context *ctx, enum nk_style_cursor c)
14819 {
14820  struct nk_style *style;
14821  NK_ASSERT(ctx);
14822  if (!ctx) return 0;
14823  style = &ctx->style;
14824  if (style->cursors[c]) {
14825  style->cursor_active = style->cursors[c];
14826  return 1;
14827  }
14828  return 0;
14829 }
14830 NK_API void
14831 nk_style_show_cursor(struct nk_context *ctx)
14832 {
14833  ctx->style.cursor_visible = nk_true;
14834 }
14835 NK_API void
14836 nk_style_hide_cursor(struct nk_context *ctx)
14837 {
14838  ctx->style.cursor_visible = nk_false;
14839 }
14840 NK_API void
14841 nk_style_load_cursor(struct nk_context *ctx, enum nk_style_cursor cursor,
14842  const struct nk_cursor *c)
14843 {
14844  struct nk_style *style;
14845  NK_ASSERT(ctx);
14846  if (!ctx) return;
14847  style = &ctx->style;
14848  style->cursors[cursor] = c;
14849 }
14850 NK_API void
14851 nk_style_load_all_cursors(struct nk_context *ctx, struct nk_cursor *cursors)
14852 {
14853  int i = 0;
14854  struct nk_style *style;
14855  NK_ASSERT(ctx);
14856  if (!ctx) return;
14857  style = &ctx->style;
14858  for (i = 0; i < NK_CURSOR_COUNT; ++i)
14859  style->cursors[i] = &cursors[i];
14860  style->cursor_visible = nk_true;
14861 }
14862 
14863 
14864 
14865 
14866 
14867 /* ==============================================================
14868  *
14869  * CONTEXT
14870  *
14871  * ===============================================================*/
14872 NK_INTERN void
14873 nk_setup(struct nk_context *ctx, const struct nk_user_font *font)
14874 {
14875  NK_ASSERT(ctx);
14876  if (!ctx) return;
14877  nk_zero_struct(*ctx);
14878  nk_style_default(ctx);
14879  ctx->seq = 1;
14880  if (font) ctx->style.font = font;
14881 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
14882  nk_draw_list_init(&ctx->draw_list);
14883 #endif
14884 }
14885 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
14886 NK_API int
14887 nk_init_default(struct nk_context *ctx, const struct nk_user_font *font)
14888 {
14889  struct nk_allocator alloc;
14890  alloc.userdata.ptr = 0;
14891  alloc.alloc = nk_malloc;
14892  alloc.free = nk_mfree;
14893  return nk_init(ctx, &alloc, font);
14894 }
14895 #endif
14896 NK_API int
14897 nk_init_fixed(struct nk_context *ctx, void *memory, nk_size size,
14898  const struct nk_user_font *font)
14899 {
14900  NK_ASSERT(memory);
14901  if (!memory) return 0;
14902  nk_setup(ctx, font);
14903  nk_buffer_init_fixed(&ctx->memory, memory, size);
14904  ctx->use_pool = nk_false;
14905  return 1;
14906 }
14907 NK_API int
14908 nk_init_custom(struct nk_context *ctx, struct nk_buffer *cmds,
14909  struct nk_buffer *pool, const struct nk_user_font *font)
14910 {
14911  NK_ASSERT(cmds);
14912  NK_ASSERT(pool);
14913  if (!cmds || !pool) return 0;
14914 
14915  nk_setup(ctx, font);
14916  ctx->memory = *cmds;
14917  if (pool->type == NK_BUFFER_FIXED) {
14918  /* take memory from buffer and alloc fixed pool */
14919  nk_pool_init_fixed(&ctx->pool, pool->memory.ptr, pool->memory.size);
14920  } else {
14921  /* create dynamic pool from buffer allocator */
14922  struct nk_allocator *alloc = &pool->pool;
14923  nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
14924  }
14925  ctx->use_pool = nk_true;
14926  return 1;
14927 }
14928 NK_API int
14929 nk_init(struct nk_context *ctx, struct nk_allocator *alloc,
14930  const struct nk_user_font *font)
14931 {
14932  NK_ASSERT(alloc);
14933  if (!alloc) return 0;
14934  nk_setup(ctx, font);
14935  nk_buffer_init(&ctx->memory, alloc, NK_DEFAULT_COMMAND_BUFFER_SIZE);
14936  nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
14937  ctx->use_pool = nk_true;
14938  return 1;
14939 }
14940 #ifdef NK_INCLUDE_COMMAND_USERDATA
14941 NK_API void
14942 nk_set_user_data(struct nk_context *ctx, nk_handle handle)
14943 {
14944  if (!ctx) return;
14945  ctx->userdata = handle;
14946  if (ctx->current)
14947  ctx->current->buffer.userdata = handle;
14948 }
14949 #endif
14950 NK_API void
14951 nk_free(struct nk_context *ctx)
14952 {
14953  NK_ASSERT(ctx);
14954  if (!ctx) return;
14955  nk_buffer_free(&ctx->memory);
14956  if (ctx->use_pool)
14957  nk_pool_free(&ctx->pool);
14958 
14959  nk_zero(&ctx->input, sizeof(ctx->input));
14960  nk_zero(&ctx->style, sizeof(ctx->style));
14961  nk_zero(&ctx->memory, sizeof(ctx->memory));
14962 
14963  ctx->seq = 0;
14964  ctx->build = 0;
14965  ctx->begin = 0;
14966  ctx->end = 0;
14967  ctx->active = 0;
14968  ctx->current = 0;
14969  ctx->freelist = 0;
14970  ctx->count = 0;
14971 }
14972 NK_API void
14973 nk_clear(struct nk_context *ctx)
14974 {
14975  struct nk_window *iter;
14976  struct nk_window *next;
14977  NK_ASSERT(ctx);
14978 
14979  if (!ctx) return;
14980  if (ctx->use_pool)
14981  nk_buffer_clear(&ctx->memory);
14982  else nk_buffer_reset(&ctx->memory, NK_BUFFER_FRONT);
14983 
14984  ctx->build = 0;
14985  ctx->memory.calls = 0;
14986  ctx->last_widget_state = 0;
14988  NK_MEMSET(&ctx->overlay, 0, sizeof(ctx->overlay));
14989 
14990  /* garbage collector */
14991  iter = ctx->begin;
14992  while (iter) {
14993  /* make sure valid minimized windows do not get removed */
14994  if ((iter->flags & NK_WINDOW_MINIMIZED) &&
14995  !(iter->flags & NK_WINDOW_CLOSED) &&
14996  iter->seq == ctx->seq) {
14997  iter = iter->next;
14998  continue;
14999  }
15000  /* remove hotness from hidden or closed windows*/
15001  if (((iter->flags & NK_WINDOW_HIDDEN) ||
15002  (iter->flags & NK_WINDOW_CLOSED)) &&
15003  iter == ctx->active) {
15004  ctx->active = iter->prev;
15005  ctx->end = iter->prev;
15006  if (!ctx->end)
15007  ctx->begin = 0;
15008  if (ctx->active)
15009  ctx->active->flags &= ~(unsigned)NK_WINDOW_ROM;
15010  }
15011  /* free unused popup windows */
15012  if (iter->popup.win && iter->popup.win->seq != ctx->seq) {
15013  nk_free_window(ctx, iter->popup.win);
15014  iter->popup.win = 0;
15015  }
15016  /* remove unused window state tables */
15017  {struct nk_table *n, *it = iter->tables;
15018  while (it) {
15019  n = it->next;
15020  if (it->seq != ctx->seq) {
15021  nk_remove_table(iter, it);
15022  nk_zero(it, sizeof(union nk_page_data));
15023  nk_free_table(ctx, it);
15024  if (it == iter->tables)
15025  iter->tables = n;
15026  } it = n;
15027  }}
15028  /* window itself is not used anymore so free */
15029  if (iter->seq != ctx->seq || iter->flags & NK_WINDOW_CLOSED) {
15030  next = iter->next;
15031  nk_remove_window(ctx, iter);
15032  nk_free_window(ctx, iter);
15033  iter = next;
15034  } else iter = iter->next;
15035  }
15036  ctx->seq++;
15037 }
15038 NK_LIB void
15039 nk_start_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer)
15040 {
15041  NK_ASSERT(ctx);
15042  NK_ASSERT(buffer);
15043  if (!ctx || !buffer) return;
15044  buffer->begin = ctx->memory.allocated;
15045  buffer->end = buffer->begin;
15046  buffer->last = buffer->begin;
15047  buffer->clip = nk_null_rect;
15048 }
15049 NK_LIB void
15050 nk_start(struct nk_context *ctx, struct nk_window *win)
15051 {
15052  NK_ASSERT(ctx);
15053  NK_ASSERT(win);
15054  nk_start_buffer(ctx, &win->buffer);
15055 }
15056 NK_LIB void
15057 nk_start_popup(struct nk_context *ctx, struct nk_window *win)
15058 {
15059  struct nk_popup_buffer *buf;
15060  NK_ASSERT(ctx);
15061  NK_ASSERT(win);
15062  if (!ctx || !win) return;
15063 
15064  /* save buffer fill state for popup */
15065  buf = &win->popup.buf;
15066  buf->begin = win->buffer.end;
15067  buf->end = win->buffer.end;
15068  buf->parent = win->buffer.last;
15069  buf->last = buf->begin;
15070  buf->active = nk_true;
15071 }
15072 NK_LIB void
15073 nk_finish_popup(struct nk_context *ctx, struct nk_window *win)
15074 {
15075  struct nk_popup_buffer *buf;
15076  NK_ASSERT(ctx);
15077  NK_ASSERT(win);
15078  if (!ctx || !win) return;
15079 
15080  buf = &win->popup.buf;
15081  buf->last = win->buffer.last;
15082  buf->end = win->buffer.end;
15083 }
15084 NK_LIB void
15085 nk_finish_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer)
15086 {
15087  NK_ASSERT(ctx);
15088  NK_ASSERT(buffer);
15089  if (!ctx || !buffer) return;
15090  buffer->end = ctx->memory.allocated;
15091 }
15092 NK_LIB void
15093 nk_finish(struct nk_context *ctx, struct nk_window *win)
15094 {
15095  struct nk_popup_buffer *buf;
15096  struct nk_command *parent_last;
15097  void *memory;
15098 
15099  NK_ASSERT(ctx);
15100  NK_ASSERT(win);
15101  if (!ctx || !win) return;
15102  nk_finish_buffer(ctx, &win->buffer);
15103  if (!win->popup.buf.active) return;
15104 
15105  buf = &win->popup.buf;
15106  memory = ctx->memory.memory.ptr;
15107  parent_last = nk_ptr_add(struct nk_command, memory, buf->parent);
15108  parent_last->next = buf->end;
15109 }
15110 NK_LIB void
15111 nk_build(struct nk_context *ctx)
15112 {
15113  struct nk_window *it = 0;
15114  struct nk_command *cmd = 0;
15115  nk_byte *buffer = 0;
15116 
15117  /* draw cursor overlay */
15118  if (!ctx->style.cursor_active)
15120  if (ctx->style.cursor_active && !ctx->input.mouse.grabbed && ctx->style.cursor_visible) {
15121  struct nk_rect mouse_bounds;
15122  const struct nk_cursor *cursor = ctx->style.cursor_active;
15123  nk_command_buffer_init(&ctx->overlay, &ctx->memory, NK_CLIPPING_OFF);
15124  nk_start_buffer(ctx, &ctx->overlay);
15125 
15126  mouse_bounds.x = ctx->input.mouse.pos.x - cursor->offset.x;
15127  mouse_bounds.y = ctx->input.mouse.pos.y - cursor->offset.y;
15128  mouse_bounds.w = cursor->size.x;
15129  mouse_bounds.h = cursor->size.y;
15130 
15131  nk_draw_image(&ctx->overlay, mouse_bounds, &cursor->img, nk_white);
15132  nk_finish_buffer(ctx, &ctx->overlay);
15133  }
15134  /* build one big draw command list out of all window buffers */
15135  it = ctx->begin;
15136  buffer = (nk_byte*)ctx->memory.memory.ptr;
15137  while (it != 0) {
15138  struct nk_window *next = it->next;
15139  if (it->buffer.last == it->buffer.begin || (it->flags & NK_WINDOW_HIDDEN)||
15140  it->seq != ctx->seq)
15141  goto cont;
15142 
15143  cmd = nk_ptr_add(struct nk_command, buffer, it->buffer.last);
15144  while (next && ((next->buffer.last == next->buffer.begin) ||
15145  (next->flags & NK_WINDOW_HIDDEN) || next->seq != ctx->seq))
15146  next = next->next; /* skip empty command buffers */
15147 
15148  if (next) cmd->next = next->buffer.begin;
15149  cont: it = next;
15150  }
15151  /* append all popup draw commands into lists */
15152  it = ctx->begin;
15153  while (it != 0) {
15154  struct nk_window *next = it->next;
15155  struct nk_popup_buffer *buf;
15156  if (!it->popup.buf.active)
15157  goto skip;
15158 
15159  buf = &it->popup.buf;
15160  cmd->next = buf->begin;
15161  cmd = nk_ptr_add(struct nk_command, buffer, buf->last);
15162  buf->active = nk_false;
15163  skip: it = next;
15164  }
15165  if (cmd) {
15166  /* append overlay commands */
15167  if (ctx->overlay.end != ctx->overlay.begin)
15168  cmd->next = ctx->overlay.begin;
15169  else cmd->next = ctx->memory.allocated;
15170  }
15171 }
15172 NK_API const struct nk_command*
15173 nk__begin(struct nk_context *ctx)
15174 {
15175  struct nk_window *iter;
15176  nk_byte *buffer;
15177  NK_ASSERT(ctx);
15178  if (!ctx) return 0;
15179  if (!ctx->count) return 0;
15180 
15181  buffer = (nk_byte*)ctx->memory.memory.ptr;
15182  if (!ctx->build) {
15183  nk_build(ctx);
15184  ctx->build = nk_true;
15185  }
15186  iter = ctx->begin;
15187  while (iter && ((iter->buffer.begin == iter->buffer.end) ||
15188  (iter->flags & NK_WINDOW_HIDDEN) || iter->seq != ctx->seq))
15189  iter = iter->next;
15190  if (!iter) return 0;
15191  return nk_ptr_add_const(struct nk_command, buffer, iter->buffer.begin);
15192 }
15193 
15194 NK_API const struct nk_command*
15195 nk__next(struct nk_context *ctx, const struct nk_command *cmd)
15196 {
15197  nk_byte *buffer;
15198  const struct nk_command *next;
15199  NK_ASSERT(ctx);
15200  if (!ctx || !cmd || !ctx->count) return 0;
15201  if (cmd->next >= ctx->memory.allocated) return 0;
15202  buffer = (nk_byte*)ctx->memory.memory.ptr;
15203  next = nk_ptr_add_const(struct nk_command, buffer, cmd->next);
15204  return next;
15205 }
15206 
15207 
15208 
15209 
15210 
15211 
15212 /* ===============================================================
15213  *
15214  * POOL
15215  *
15216  * ===============================================================*/
15217 NK_LIB void
15218 nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc,
15219  unsigned int capacity)
15220 {
15221  nk_zero(pool, sizeof(*pool));
15222  pool->alloc = *alloc;
15223  pool->capacity = capacity;
15224  pool->type = NK_BUFFER_DYNAMIC;
15225  pool->pages = 0;
15226 }
15227 NK_LIB void
15228 nk_pool_free(struct nk_pool *pool)
15229 {
15230  struct nk_page *iter = pool->pages;
15231  if (!pool) return;
15232  if (pool->type == NK_BUFFER_FIXED) return;
15233  while (iter) {
15234  struct nk_page *next = iter->next;
15235  pool->alloc.free(pool->alloc.userdata, iter);
15236  iter = next;
15237  }
15238 }
15239 NK_LIB void
15240 nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size)
15241 {
15242  nk_zero(pool, sizeof(*pool));
15243  NK_ASSERT(size >= sizeof(struct nk_page));
15244  if (size < sizeof(struct nk_page)) return;
15245  pool->capacity = (unsigned)(size - sizeof(struct nk_page)) / sizeof(struct nk_page_element);
15246  pool->pages = (struct nk_page*)memory;
15247  pool->type = NK_BUFFER_FIXED;
15248  pool->size = size;
15249 }
15250 NK_LIB struct nk_page_element*
15251 nk_pool_alloc(struct nk_pool *pool)
15252 {
15253  if (!pool->pages || pool->pages->size >= pool->capacity) {
15254  /* allocate new page */
15255  struct nk_page *page;
15256  if (pool->type == NK_BUFFER_FIXED) {
15257  NK_ASSERT(pool->pages);
15258  if (!pool->pages) return 0;
15259  NK_ASSERT(pool->pages->size < pool->capacity);
15260  return 0;
15261  } else {
15262  nk_size size = sizeof(struct nk_page);
15263  size += NK_POOL_DEFAULT_CAPACITY * sizeof(union nk_page_data);
15264  page = (struct nk_page*)pool->alloc.alloc(pool->alloc.userdata,0, size);
15265  page->next = pool->pages;
15266  pool->pages = page;
15267  page->size = 0;
15268  }
15269  } return &pool->pages->win[pool->pages->size++];
15270 }
15271 
15272 
15273 
15274 
15275 
15276 /* ===============================================================
15277  *
15278  * PAGE ELEMENT
15279  *
15280  * ===============================================================*/
15281 NK_LIB struct nk_page_element*
15282 nk_create_page_element(struct nk_context *ctx)
15283 {
15284  struct nk_page_element *elem;
15285  if (ctx->freelist) {
15286  /* unlink page element from free list */
15287  elem = ctx->freelist;
15288  ctx->freelist = elem->next;
15289  } else if (ctx->use_pool) {
15290  /* allocate page element from memory pool */
15291  elem = nk_pool_alloc(&ctx->pool);
15292  NK_ASSERT(elem);
15293  if (!elem) return 0;
15294  } else {
15295  /* allocate new page element from back of fixed size memory buffer */
15296  NK_STORAGE const nk_size size = sizeof(struct nk_page_element);
15297  NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_page_element);
15298  elem = (struct nk_page_element*)nk_buffer_alloc(&ctx->memory, NK_BUFFER_BACK, size, align);
15299  NK_ASSERT(elem);
15300  if (!elem) return 0;
15301  }
15302  nk_zero_struct(*elem);
15303  elem->next = 0;
15304  elem->prev = 0;
15305  return elem;
15306 }
15307 NK_LIB void
15308 nk_link_page_element_into_freelist(struct nk_context *ctx,
15309  struct nk_page_element *elem)
15310 {
15311  /* link table into freelist */
15312  if (!ctx->freelist) {
15313  ctx->freelist = elem;
15314  } else {
15315  elem->next = ctx->freelist;
15316  ctx->freelist = elem;
15317  }
15318 }
15319 NK_LIB void
15320 nk_free_page_element(struct nk_context *ctx, struct nk_page_element *elem)
15321 {
15322  /* we have a pool so just add to free list */
15323  if (ctx->use_pool) {
15324  nk_link_page_element_into_freelist(ctx, elem);
15325  return;
15326  }
15327  /* if possible remove last element from back of fixed memory buffer */
15328  {void *elem_end = (void*)(elem + 1);
15329  void *buffer_end = (nk_byte*)ctx->memory.memory.ptr + ctx->memory.size;
15330  if (elem_end == buffer_end)
15331  ctx->memory.size -= sizeof(struct nk_page_element);
15332  else nk_link_page_element_into_freelist(ctx, elem);}
15333 }
15334 
15335 
15336 
15337 
15338 
15339 /* ===============================================================
15340  *
15341  * TABLE
15342  *
15343  * ===============================================================*/
15344 NK_LIB struct nk_table*
15345 nk_create_table(struct nk_context *ctx)
15346 {
15347  struct nk_page_element *elem;
15348  elem = nk_create_page_element(ctx);
15349  if (!elem) return 0;
15350  nk_zero_struct(*elem);
15351  return &elem->data.tbl;
15352 }
15353 NK_LIB void
15354 nk_free_table(struct nk_context *ctx, struct nk_table *tbl)
15355 {
15356  union nk_page_data *pd = NK_CONTAINER_OF(tbl, union nk_page_data, tbl);
15357  struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
15358  nk_free_page_element(ctx, pe);
15359 }
15360 NK_LIB void
15361 nk_push_table(struct nk_window *win, struct nk_table *tbl)
15362 {
15363  if (!win->tables) {
15364  win->tables = tbl;
15365  tbl->next = 0;
15366  tbl->prev = 0;
15367  tbl->size = 0;
15368  win->table_count = 1;
15369  return;
15370  }
15371  win->tables->prev = tbl;
15372  tbl->next = win->tables;
15373  tbl->prev = 0;
15374  tbl->size = 0;
15375  win->tables = tbl;
15376  win->table_count++;
15377 }
15378 NK_LIB void
15379 nk_remove_table(struct nk_window *win, struct nk_table *tbl)
15380 {
15381  if (win->tables == tbl)
15382  win->tables = tbl->next;
15383  if (tbl->next)
15384  tbl->next->prev = tbl->prev;
15385  if (tbl->prev)
15386  tbl->prev->next = tbl->next;
15387  tbl->next = 0;
15388  tbl->prev = 0;
15389 }
15390 NK_LIB nk_uint*
15391 nk_add_value(struct nk_context *ctx, struct nk_window *win,
15392  nk_hash name, nk_uint value)
15393 {
15394  NK_ASSERT(ctx);
15395  NK_ASSERT(win);
15396  if (!win || !ctx) return 0;
15397  if (!win->tables || win->tables->size >= NK_VALUE_PAGE_CAPACITY) {
15398  struct nk_table *tbl = nk_create_table(ctx);
15399  NK_ASSERT(tbl);
15400  if (!tbl) return 0;
15401  nk_push_table(win, tbl);
15402  }
15403  win->tables->seq = win->seq;
15404  win->tables->keys[win->tables->size] = name;
15405  win->tables->values[win->tables->size] = value;
15406  return &win->tables->values[win->tables->size++];
15407 }
15408 NK_LIB nk_uint*
15409 nk_find_value(struct nk_window *win, nk_hash name)
15410 {
15411  struct nk_table *iter = win->tables;
15412  while (iter) {
15413  unsigned int i = 0;
15414  unsigned int size = iter->size;
15415  for (i = 0; i < size; ++i) {
15416  if (iter->keys[i] == name) {
15417  iter->seq = win->seq;
15418  return &iter->values[i];
15419  }
15420  } size = NK_VALUE_PAGE_CAPACITY;
15421  iter = iter->next;
15422  }
15423  return 0;
15424 }
15425 
15426 
15427 
15428 
15429 
15430 /* ===============================================================
15431  *
15432  * PANEL
15433  *
15434  * ===============================================================*/
15435 NK_LIB void*
15436 nk_create_panel(struct nk_context *ctx)
15437 {
15438  struct nk_page_element *elem;
15439  elem = nk_create_page_element(ctx);
15440  if (!elem) return 0;
15441  nk_zero_struct(*elem);
15442  return &elem->data.pan;
15443 }
15444 NK_LIB void
15445 nk_free_panel(struct nk_context *ctx, struct nk_panel *pan)
15446 {
15447  union nk_page_data *pd = NK_CONTAINER_OF(pan, union nk_page_data, pan);
15448  struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
15449  nk_free_page_element(ctx, pe);
15450 }
15451 NK_LIB int
15452 nk_panel_has_header(nk_flags flags, const char *title)
15453 {
15454  int active = 0;
15455  active = (flags & (NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE));
15456  active = active || (flags & NK_WINDOW_TITLE);
15457  active = active && !(flags & NK_WINDOW_HIDDEN) && title;
15458  return active;
15459 }
15460 NK_LIB struct nk_vec2
15461 nk_panel_get_padding(const struct nk_style *style, enum nk_panel_type type)
15462 {
15463  switch (type) {
15464  default:
15465  case NK_PANEL_WINDOW: return style->window.padding;
15466  case NK_PANEL_GROUP: return style->window.group_padding;
15467  case NK_PANEL_POPUP: return style->window.popup_padding;
15468  case NK_PANEL_CONTEXTUAL: return style->window.contextual_padding;
15469  case NK_PANEL_COMBO: return style->window.combo_padding;
15470  case NK_PANEL_MENU: return style->window.menu_padding;
15471  case NK_PANEL_TOOLTIP: return style->window.menu_padding;}
15472 }
15473 NK_LIB float
15474 nk_panel_get_border(const struct nk_style *style, nk_flags flags,
15475  enum nk_panel_type type)
15476 {
15477  if (flags & NK_WINDOW_BORDER) {
15478  switch (type) {
15479  default:
15480  case NK_PANEL_WINDOW: return style->window.border;
15481  case NK_PANEL_GROUP: return style->window.group_border;
15482  case NK_PANEL_POPUP: return style->window.popup_border;
15483  case NK_PANEL_CONTEXTUAL: return style->window.contextual_border;
15484  case NK_PANEL_COMBO: return style->window.combo_border;
15485  case NK_PANEL_MENU: return style->window.menu_border;
15486  case NK_PANEL_TOOLTIP: return style->window.menu_border;
15487  }} else return 0;
15488 }
15489 NK_LIB struct nk_color
15490 nk_panel_get_border_color(const struct nk_style *style, enum nk_panel_type type)
15491 {
15492  switch (type) {
15493  default:
15494  case NK_PANEL_WINDOW: return style->window.border_color;
15495  case NK_PANEL_GROUP: return style->window.group_border_color;
15496  case NK_PANEL_POPUP: return style->window.popup_border_color;
15497  case NK_PANEL_CONTEXTUAL: return style->window.contextual_border_color;
15498  case NK_PANEL_COMBO: return style->window.combo_border_color;
15499  case NK_PANEL_MENU: return style->window.menu_border_color;
15500  case NK_PANEL_TOOLTIP: return style->window.menu_border_color;}
15501 }
15502 NK_LIB int
15503 nk_panel_is_sub(enum nk_panel_type type)
15504 {
15505  return (type & NK_PANEL_SET_SUB)?1:0;
15506 }
15507 NK_LIB int
15508 nk_panel_is_nonblock(enum nk_panel_type type)
15509 {
15510  return (type & NK_PANEL_SET_NONBLOCK)?1:0;
15511 }
15512 NK_LIB int
15513 nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type panel_type)
15514 {
15515  struct nk_input *in;
15516  struct nk_window *win;
15517  struct nk_panel *layout;
15518  struct nk_command_buffer *out;
15519  const struct nk_style *style;
15520  const struct nk_user_font *font;
15521 
15522  struct nk_vec2 scrollbar_size;
15523  struct nk_vec2 panel_padding;
15524 
15525  NK_ASSERT(ctx);
15526  NK_ASSERT(ctx->current);
15527  NK_ASSERT(ctx->current->layout);
15528  if (!ctx || !ctx->current || !ctx->current->layout) return 0;
15529  nk_zero(ctx->current->layout, sizeof(*ctx->current->layout));
15530  if ((ctx->current->flags & NK_WINDOW_HIDDEN) || (ctx->current->flags & NK_WINDOW_CLOSED)) {
15531  nk_zero(ctx->current->layout, sizeof(struct nk_panel));
15532  ctx->current->layout->type = panel_type;
15533  return 0;
15534  }
15535  /* pull state into local stack */
15536  style = &ctx->style;
15537  font = style->font;
15538  win = ctx->current;
15539  layout = win->layout;
15540  out = &win->buffer;
15541  in = (win->flags & NK_WINDOW_NO_INPUT) ? 0: &ctx->input;
15542 #ifdef NK_INCLUDE_COMMAND_USERDATA
15543  win->buffer.userdata = ctx->userdata;
15544 #endif
15545  /* pull style configuration into local stack */
15546  scrollbar_size = style->window.scrollbar_size;
15547  panel_padding = nk_panel_get_padding(style, panel_type);
15548 
15549  /* window movement */
15550  if ((win->flags & NK_WINDOW_MOVABLE) && !(win->flags & NK_WINDOW_ROM)) {
15551  int left_mouse_down;
15552  int left_mouse_clicked;
15553  int left_mouse_click_in_cursor;
15554 
15555  /* calculate draggable window space */
15556  struct nk_rect header;
15557  header.x = win->bounds.x;
15558  header.y = win->bounds.y;
15559  header.w = win->bounds.w;
15560  if (nk_panel_has_header(win->flags, title)) {
15561  header.h = font->height + 2.0f * style->window.header.padding.y;
15562  header.h += 2.0f * style->window.header.label_padding.y;
15563  } else header.h = panel_padding.y;
15564 
15565  /* window movement by dragging */
15566  left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
15567  left_mouse_clicked = (int)in->mouse.buttons[NK_BUTTON_LEFT].clicked;
15568  left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
15569  NK_BUTTON_LEFT, header, nk_true);
15570  if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) {
15571  win->bounds.x = win->bounds.x + in->mouse.delta.x;
15572  win->bounds.y = win->bounds.y + in->mouse.delta.y;
15576  }
15577  }
15578 
15579  /* setup panel */
15580  layout->type = panel_type;
15581  layout->flags = win->flags;
15582  layout->bounds = win->bounds;
15583  layout->bounds.x += panel_padding.x;
15584  layout->bounds.w -= 2*panel_padding.x;
15585  if (win->flags & NK_WINDOW_BORDER) {
15586  layout->border = nk_panel_get_border(style, win->flags, panel_type);
15587  layout->bounds = nk_shrink_rect(layout->bounds, layout->border);
15588  } else layout->border = 0;
15589  layout->at_y = layout->bounds.y;
15590  layout->at_x = layout->bounds.x;
15591  layout->max_x = 0;
15592  layout->header_height = 0;
15593  layout->footer_height = 0;
15595  layout->row.index = 0;
15596  layout->row.columns = 0;
15597  layout->row.ratio = 0;
15598  layout->row.item_width = 0;
15599  layout->row.tree_depth = 0;
15600  layout->row.height = panel_padding.y;
15601  layout->has_scrolling = nk_true;
15602  if (!(win->flags & NK_WINDOW_NO_SCROLLBAR))
15603  layout->bounds.w -= scrollbar_size.x;
15604  if (!nk_panel_is_nonblock(panel_type)) {
15605  layout->footer_height = 0;
15606  if (!(win->flags & NK_WINDOW_NO_SCROLLBAR) || win->flags & NK_WINDOW_SCALABLE)
15607  layout->footer_height = scrollbar_size.y;
15608  layout->bounds.h -= layout->footer_height;
15609  }
15610 
15611  /* panel header */
15612  if (nk_panel_has_header(win->flags, title))
15613  {
15614  struct nk_text text;
15615  struct nk_rect header;
15616  const struct nk_style_item *background = 0;
15617 
15618  /* calculate header bounds */
15619  header.x = win->bounds.x;
15620  header.y = win->bounds.y;
15621  header.w = win->bounds.w;
15622  header.h = font->height + 2.0f * style->window.header.padding.y;
15623  header.h += (2.0f * style->window.header.label_padding.y);
15624 
15625  /* shrink panel by header */
15626  layout->header_height = header.h;
15627  layout->bounds.y += header.h;
15628  layout->bounds.h -= header.h;
15629  layout->at_y += header.h;
15630 
15631  /* select correct header background and text color */
15632  if (ctx->active == win) {
15633  background = &style->window.header.active;
15634  text.text = style->window.header.label_active;
15635  } else if (nk_input_is_mouse_hovering_rect(&ctx->input, header)) {
15636  background = &style->window.header.hover;
15637  text.text = style->window.header.label_hover;
15638  } else {
15639  background = &style->window.header.normal;
15640  text.text = style->window.header.label_normal;
15641  }
15642 
15643  /* draw header background */
15644  header.h += 1.0f;
15645  if (background->type == NK_STYLE_ITEM_IMAGE) {
15646  text.background = nk_rgba(0,0,0,0);
15647  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
15648  } else {
15649  text.background = background->data.color;
15650  nk_fill_rect(out, header, 0, background->data.color);
15651  }
15652 
15653  /* window close button */
15654  {struct nk_rect button;
15655  button.y = header.y + style->window.header.padding.y;
15656  button.h = header.h - 2 * style->window.header.padding.y;
15657  button.w = button.h;
15658  if (win->flags & NK_WINDOW_CLOSABLE) {
15659  nk_flags ws = 0;
15660  if (style->window.header.align == NK_HEADER_RIGHT) {
15661  button.x = (header.w + header.x) - (button.w + style->window.header.padding.x);
15662  header.w -= button.w + style->window.header.spacing.x + style->window.header.padding.x;
15663  } else {
15664  button.x = header.x + style->window.header.padding.x;
15665  header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
15666  }
15667 
15668  if (nk_do_button_symbol(&ws, &win->buffer, button,
15670  &style->window.header.close_button, in, style->font) && !(win->flags & NK_WINDOW_ROM))
15671  {
15672  layout->flags |= NK_WINDOW_HIDDEN;
15673  layout->flags &= (nk_flags)~NK_WINDOW_MINIMIZED;
15674  }
15675  }
15676 
15677  /* window minimize button */
15678  if (win->flags & NK_WINDOW_MINIMIZABLE) {
15679  nk_flags ws = 0;
15680  if (style->window.header.align == NK_HEADER_RIGHT) {
15681  button.x = (header.w + header.x) - button.w;
15682  if (!(win->flags & NK_WINDOW_CLOSABLE)) {
15683  button.x -= style->window.header.padding.x;
15684  header.w -= style->window.header.padding.x;
15685  }
15686  header.w -= button.w + style->window.header.spacing.x;
15687  } else {
15688  button.x = header.x;
15689  header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
15690  }
15691  if (nk_do_button_symbol(&ws, &win->buffer, button, (layout->flags & NK_WINDOW_MINIMIZED)?
15693  NK_BUTTON_DEFAULT, &style->window.header.minimize_button, in, style->font) && !(win->flags & NK_WINDOW_ROM))
15694  layout->flags = (layout->flags & NK_WINDOW_MINIMIZED) ?
15695  layout->flags & (nk_flags)~NK_WINDOW_MINIMIZED:
15696  layout->flags | NK_WINDOW_MINIMIZED;
15697  }}
15698 
15699  {/* window header title */
15700  int text_len = nk_strlen(title);
15701  struct nk_rect label = {0,0,0,0};
15702  float t = font->width(font->userdata, font->height, title, text_len);
15703  text.padding = nk_vec2(0,0);
15704 
15705  label.x = header.x + style->window.header.padding.x;
15706  label.x += style->window.header.label_padding.x;
15707  label.y = header.y + style->window.header.label_padding.y;
15708  label.h = font->height + 2 * style->window.header.label_padding.y;
15709  label.w = t + 2 * style->window.header.spacing.x;
15710  label.w = NK_CLAMP(0, label.w, header.x + header.w - label.x);
15711  nk_widget_text(out, label,(const char*)title, text_len, &text, NK_TEXT_LEFT, font);}
15712  }
15713 
15714  /* draw window background */
15715  if (!(layout->flags & NK_WINDOW_MINIMIZED) && !(layout->flags & NK_WINDOW_DYNAMIC)) {
15716  struct nk_rect body;
15717  body.x = win->bounds.x;
15718  body.w = win->bounds.w;
15719  body.y = (win->bounds.y + layout->header_height);
15720  body.h = (win->bounds.h - layout->header_height);
15722  nk_draw_image(out, body, &style->window.fixed_background.data.image, nk_white);
15723  else nk_fill_rect(out, body, 0, style->window.fixed_background.data.color);
15724  }
15725 
15726  /* set clipping rectangle */
15727  {struct nk_rect clip;
15728  layout->clip = layout->bounds;
15729  nk_unify(&clip, &win->buffer.clip, layout->clip.x, layout->clip.y,
15730  layout->clip.x + layout->clip.w, layout->clip.y + layout->clip.h);
15731  nk_push_scissor(out, clip);
15732  layout->clip = clip;}
15733  return !(layout->flags & NK_WINDOW_HIDDEN) && !(layout->flags & NK_WINDOW_MINIMIZED);
15734 }
15735 NK_LIB void
15736 nk_panel_end(struct nk_context *ctx)
15737 {
15738  struct nk_input *in;
15739  struct nk_window *window;
15740  struct nk_panel *layout;
15741  const struct nk_style *style;
15742  struct nk_command_buffer *out;
15743 
15744  struct nk_vec2 scrollbar_size;
15745  struct nk_vec2 panel_padding;
15746 
15747  NK_ASSERT(ctx);
15748  NK_ASSERT(ctx->current);
15749  NK_ASSERT(ctx->current->layout);
15750  if (!ctx || !ctx->current || !ctx->current->layout)
15751  return;
15752 
15753  window = ctx->current;
15754  layout = window->layout;
15755  style = &ctx->style;
15756  out = &window->buffer;
15757  in = (layout->flags & NK_WINDOW_ROM || layout->flags & NK_WINDOW_NO_INPUT) ? 0 :&ctx->input;
15758  if (!nk_panel_is_sub(layout->type))
15759  nk_push_scissor(out, nk_null_rect);
15760 
15761  /* cache configuration data */
15762  scrollbar_size = style->window.scrollbar_size;
15763  panel_padding = nk_panel_get_padding(style, layout->type);
15764 
15765  /* update the current cursor Y-position to point over the last added widget */
15766  layout->at_y += layout->row.height;
15767 
15768  /* dynamic panels */
15769  if (layout->flags & NK_WINDOW_DYNAMIC && !(layout->flags & NK_WINDOW_MINIMIZED))
15770  {
15771  /* update panel height to fit dynamic growth */
15772  struct nk_rect empty_space;
15773  if (layout->at_y < (layout->bounds.y + layout->bounds.h))
15774  layout->bounds.h = layout->at_y - layout->bounds.y;
15775 
15776  /* fill top empty space */
15777  empty_space.x = window->bounds.x;
15778  empty_space.y = layout->bounds.y;
15779  empty_space.h = panel_padding.y;
15780  empty_space.w = window->bounds.w;
15781  nk_fill_rect(out, empty_space, 0, style->window.background);
15782 
15783  /* fill left empty space */
15784  empty_space.x = window->bounds.x;
15785  empty_space.y = layout->bounds.y;
15786  empty_space.w = panel_padding.x + layout->border;
15787  empty_space.h = layout->bounds.h;
15788  nk_fill_rect(out, empty_space, 0, style->window.background);
15789 
15790  /* fill right empty space */
15791  empty_space.x = layout->bounds.x + layout->bounds.w - layout->border;
15792  empty_space.y = layout->bounds.y;
15793  empty_space.w = panel_padding.x + layout->border;
15794  empty_space.h = layout->bounds.h;
15795  if (*layout->offset_y == 0 && !(layout->flags & NK_WINDOW_NO_SCROLLBAR))
15796  empty_space.w += scrollbar_size.x;
15797  nk_fill_rect(out, empty_space, 0, style->window.background);
15798 
15799  /* fill bottom empty space */
15800  if (*layout->offset_x != 0 && !(layout->flags & NK_WINDOW_NO_SCROLLBAR)) {
15801  empty_space.x = window->bounds.x;
15802  empty_space.y = layout->bounds.y + layout->bounds.h;
15803  empty_space.w = window->bounds.w;
15804  empty_space.h = scrollbar_size.y;
15805  nk_fill_rect(out, empty_space, 0, style->window.background);
15806  }
15807  }
15808 
15809  /* scrollbars */
15810  if (!(layout->flags & NK_WINDOW_NO_SCROLLBAR) &&
15811  !(layout->flags & NK_WINDOW_MINIMIZED) &&
15813  {
15814  struct nk_rect scroll;
15815  int scroll_has_scrolling;
15816  float scroll_target;
15817  float scroll_offset;
15818  float scroll_step;
15819  float scroll_inc;
15820 
15821  /* mouse wheel scrolling */
15822  if (nk_panel_is_sub(layout->type))
15823  {
15824  /* sub-window mouse wheel scrolling */
15825  struct nk_window *root_window = window;
15826  struct nk_panel *root_panel = window->layout;
15827  while (root_panel->parent)
15828  root_panel = root_panel->parent;
15829  while (root_window->parent)
15830  root_window = root_window->parent;
15831 
15832  /* only allow scrolling if parent window is active */
15833  scroll_has_scrolling = 0;
15834  if ((root_window == ctx->active) && layout->has_scrolling) {
15835  /* and panel is being hovered and inside clip rect*/
15836  if (nk_input_is_mouse_hovering_rect(in, layout->bounds) &&
15837  NK_INTERSECT(layout->bounds.x, layout->bounds.y, layout->bounds.w, layout->bounds.h,
15838  root_panel->clip.x, root_panel->clip.y, root_panel->clip.w, root_panel->clip.h))
15839  {
15840  /* deactivate all parent scrolling */
15841  root_panel = window->layout;
15842  while (root_panel->parent) {
15843  root_panel->has_scrolling = nk_false;
15844  root_panel = root_panel->parent;
15845  }
15846  root_panel->has_scrolling = nk_false;
15847  scroll_has_scrolling = nk_true;
15848  }
15849  }
15850  } else if (!nk_panel_is_sub(layout->type)) {
15851  /* window mouse wheel scrolling */
15852  scroll_has_scrolling = (window == ctx->active) && layout->has_scrolling;
15853  if (in && (in->mouse.scroll_delta.y > 0 || in->mouse.scroll_delta.x > 0) && scroll_has_scrolling)
15854  window->scrolled = nk_true;
15855  else window->scrolled = nk_false;
15856  } else scroll_has_scrolling = nk_false;
15857 
15858  {
15859  /* vertical scrollbar */
15860  nk_flags state = 0;
15861  scroll.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
15862  scroll.y = layout->bounds.y;
15863  scroll.w = scrollbar_size.x;
15864  scroll.h = layout->bounds.h;
15865 
15866  scroll_offset = (float)*layout->offset_y;
15867  scroll_step = scroll.h * 0.10f;
15868  scroll_inc = scroll.h * 0.01f;
15869  scroll_target = (float)(int)(layout->at_y - scroll.y);
15870  scroll_offset = nk_do_scrollbarv(&state, out, scroll, scroll_has_scrolling,
15871  scroll_offset, scroll_target, scroll_step, scroll_inc,
15872  &ctx->style.scrollv, in, style->font);
15873  *layout->offset_y = (nk_uint)scroll_offset;
15874  if (in && scroll_has_scrolling)
15875  in->mouse.scroll_delta.y = 0;
15876  }
15877  {
15878  /* horizontal scrollbar */
15879  nk_flags state = 0;
15880  scroll.x = layout->bounds.x;
15881  scroll.y = layout->bounds.y + layout->bounds.h;
15882  scroll.w = layout->bounds.w;
15883  scroll.h = scrollbar_size.y;
15884 
15885  scroll_offset = (float)*layout->offset_x;
15886  scroll_target = (float)(int)(layout->max_x - scroll.x);
15887  scroll_step = layout->max_x * 0.05f;
15888  scroll_inc = layout->max_x * 0.005f;
15889  scroll_offset = nk_do_scrollbarh(&state, out, scroll, scroll_has_scrolling,
15890  scroll_offset, scroll_target, scroll_step, scroll_inc,
15891  &ctx->style.scrollh, in, style->font);
15892  *layout->offset_x = (nk_uint)scroll_offset;
15893  }
15894  }
15895 
15896  /* hide scroll if no user input */
15897  if (window->flags & NK_WINDOW_SCROLL_AUTO_HIDE) {
15898  int has_input = ctx->input.mouse.delta.x != 0 || ctx->input.mouse.delta.y != 0 || ctx->input.mouse.scroll_delta.y != 0;
15899  int is_window_hovered = nk_window_is_hovered(ctx);
15900  int any_item_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
15901  if ((!has_input && is_window_hovered) || (!is_window_hovered && !any_item_active))
15903  else window->scrollbar_hiding_timer = 0;
15904  } else window->scrollbar_hiding_timer = 0;
15905 
15906  /* window border */
15907  if (layout->flags & NK_WINDOW_BORDER)
15908  {
15909  struct nk_color border_color = nk_panel_get_border_color(style, layout->type);
15910  const float padding_y = (layout->flags & NK_WINDOW_MINIMIZED)
15911  ? (style->window.border + window->bounds.y + layout->header_height)
15912  : ((layout->flags & NK_WINDOW_DYNAMIC)
15913  ? (layout->bounds.y + layout->bounds.h + layout->footer_height)
15914  : (window->bounds.y + window->bounds.h));
15915  struct nk_rect b = window->bounds;
15916  b.h = padding_y - window->bounds.y;
15917  nk_stroke_rect(out, b, 0, layout->border, border_color);
15918  }
15919 
15920  /* scaler */
15921  if ((layout->flags & NK_WINDOW_SCALABLE) && in && !(layout->flags & NK_WINDOW_MINIMIZED))
15922  {
15923  /* calculate scaler bounds */
15924  struct nk_rect scaler;
15925  scaler.w = scrollbar_size.x;
15926  scaler.h = scrollbar_size.y;
15927  scaler.y = layout->bounds.y + layout->bounds.h;
15928  if (layout->flags & NK_WINDOW_SCALE_LEFT)
15929  scaler.x = layout->bounds.x - panel_padding.x * 0.5f;
15930  else scaler.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
15931  if (layout->flags & NK_WINDOW_NO_SCROLLBAR)
15932  scaler.x -= scaler.w;
15933 
15934  /* draw scaler */
15935  {const struct nk_style_item *item = &style->window.scaler;
15936  if (item->type == NK_STYLE_ITEM_IMAGE)
15937  nk_draw_image(out, scaler, &item->data.image, nk_white);
15938  else {
15939  if (layout->flags & NK_WINDOW_SCALE_LEFT) {
15940  nk_fill_triangle(out, scaler.x, scaler.y, scaler.x,
15941  scaler.y + scaler.h, scaler.x + scaler.w,
15942  scaler.y + scaler.h, item->data.color);
15943  } else {
15944  nk_fill_triangle(out, scaler.x + scaler.w, scaler.y, scaler.x + scaler.w,
15945  scaler.y + scaler.h, scaler.x, scaler.y + scaler.h, item->data.color);
15946  }
15947  }}
15948 
15949  /* do window scaling */
15950  if (!(window->flags & NK_WINDOW_ROM)) {
15951  struct nk_vec2 window_size = style->window.min_size;
15952  int left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
15953  int left_mouse_click_in_scaler = nk_input_has_mouse_click_down_in_rect(in,
15954  NK_BUTTON_LEFT, scaler, nk_true);
15955 
15956  if (left_mouse_down && left_mouse_click_in_scaler) {
15957  float delta_x = in->mouse.delta.x;
15958  if (layout->flags & NK_WINDOW_SCALE_LEFT) {
15959  delta_x = -delta_x;
15960  window->bounds.x += in->mouse.delta.x;
15961  }
15962  /* dragging in x-direction */
15963  if (window->bounds.w + delta_x >= window_size.x) {
15964  if ((delta_x < 0) || (delta_x > 0 && in->mouse.pos.x >= scaler.x)) {
15965  window->bounds.w = window->bounds.w + delta_x;
15966  scaler.x += in->mouse.delta.x;
15967  }
15968  }
15969  /* dragging in y-direction (only possible if static window) */
15970  if (!(layout->flags & NK_WINDOW_DYNAMIC)) {
15971  if (window_size.y < window->bounds.h + in->mouse.delta.y) {
15972  if ((in->mouse.delta.y < 0) || (in->mouse.delta.y > 0 && in->mouse.pos.y >= scaler.y)) {
15973  window->bounds.h = window->bounds.h + in->mouse.delta.y;
15974  scaler.y += in->mouse.delta.y;
15975  }
15976  }
15977  }
15979  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = scaler.x + scaler.w/2.0f;
15980  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = scaler.y + scaler.h/2.0f;
15981  }
15982  }
15983  }
15984  if (!nk_panel_is_sub(layout->type)) {
15985  /* window is hidden so clear command buffer */
15986  if (layout->flags & NK_WINDOW_HIDDEN)
15987  nk_command_buffer_reset(&window->buffer);
15988  /* window is visible and not tab */
15989  else nk_finish(ctx, window);
15990  }
15991 
15992  /* NK_WINDOW_REMOVE_ROM flag was set so remove NK_WINDOW_ROM */
15993  if (layout->flags & NK_WINDOW_REMOVE_ROM) {
15994  layout->flags &= ~(nk_flags)NK_WINDOW_ROM;
15995  layout->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM;
15996  }
15997  window->flags = layout->flags;
15998 
15999  /* property garbage collector */
16000  if (window->property.active && window->property.old != window->property.seq &&
16001  window->property.active == window->property.prev) {
16002  nk_zero(&window->property, sizeof(window->property));
16003  } else {
16004  window->property.old = window->property.seq;
16005  window->property.prev = window->property.active;
16006  window->property.seq = 0;
16007  }
16008  /* edit garbage collector */
16009  if (window->edit.active && window->edit.old != window->edit.seq &&
16010  window->edit.active == window->edit.prev) {
16011  nk_zero(&window->edit, sizeof(window->edit));
16012  } else {
16013  window->edit.old = window->edit.seq;
16014  window->edit.prev = window->edit.active;
16015  window->edit.seq = 0;
16016  }
16017  /* contextual garbage collector */
16018  if (window->popup.active_con && window->popup.con_old != window->popup.con_count) {
16019  window->popup.con_count = 0;
16020  window->popup.con_old = 0;
16021  window->popup.active_con = 0;
16022  } else {
16023  window->popup.con_old = window->popup.con_count;
16024  window->popup.con_count = 0;
16025  }
16026  window->popup.combo_count = 0;
16027  /* helper to make sure you have a 'nk_tree_push' for every 'nk_tree_pop' */
16028  NK_ASSERT(!layout->row.tree_depth);
16029 }
16030 
16031 
16032 
16033 
16034 
16035 /* ===============================================================
16036  *
16037  * WINDOW
16038  *
16039  * ===============================================================*/
16040 NK_LIB void*
16041 nk_create_window(struct nk_context *ctx)
16042 {
16043  struct nk_page_element *elem;
16044  elem = nk_create_page_element(ctx);
16045  if (!elem) return 0;
16046  elem->data.win.seq = ctx->seq;
16047  return &elem->data.win;
16048 }
16049 NK_LIB void
16050 nk_free_window(struct nk_context *ctx, struct nk_window *win)
16051 {
16052  /* unlink windows from list */
16053  struct nk_table *it = win->tables;
16054  if (win->popup.win) {
16055  nk_free_window(ctx, win->popup.win);
16056  win->popup.win = 0;
16057  }
16058  win->next = 0;
16059  win->prev = 0;
16060 
16061  while (it) {
16062  /*free window state tables */
16063  struct nk_table *n = it->next;
16064  nk_remove_table(win, it);
16065  nk_free_table(ctx, it);
16066  if (it == win->tables)
16067  win->tables = n;
16068  it = n;
16069  }
16070 
16071  /* link windows into freelist */
16072  {union nk_page_data *pd = NK_CONTAINER_OF(win, union nk_page_data, win);
16073  struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
16074  nk_free_page_element(ctx, pe);}
16075 }
16076 NK_LIB struct nk_window*
16077 nk_find_window(struct nk_context *ctx, nk_hash hash, const char *name)
16078 {
16079  struct nk_window *iter;
16080  iter = ctx->begin;
16081  while (iter) {
16082  NK_ASSERT(iter != iter->next);
16083  if (iter->name == hash) {
16084  int max_len = nk_strlen(iter->name_string);
16085  if (!nk_stricmpn(iter->name_string, name, max_len))
16086  return iter;
16087  }
16088  iter = iter->next;
16089  }
16090  return 0;
16091 }
16092 NK_LIB void
16093 nk_insert_window(struct nk_context *ctx, struct nk_window *win,
16094  enum nk_window_insert_location loc)
16095 {
16096  const struct nk_window *iter;
16097  NK_ASSERT(ctx);
16098  NK_ASSERT(win);
16099  if (!win || !ctx) return;
16100 
16101  iter = ctx->begin;
16102  while (iter) {
16103  NK_ASSERT(iter != iter->next);
16104  NK_ASSERT(iter != win);
16105  if (iter == win) return;
16106  iter = iter->next;
16107  }
16108 
16109  if (!ctx->begin) {
16110  win->next = 0;
16111  win->prev = 0;
16112  ctx->begin = win;
16113  ctx->end = win;
16114  ctx->count = 1;
16115  return;
16116  }
16117  if (loc == NK_INSERT_BACK) {
16118  struct nk_window *end;
16119  end = ctx->end;
16120  end->flags |= NK_WINDOW_ROM;
16121  end->next = win;
16122  win->prev = ctx->end;
16123  win->next = 0;
16124  ctx->end = win;
16125  ctx->active = ctx->end;
16126  ctx->end->flags &= ~(nk_flags)NK_WINDOW_ROM;
16127  } else {
16128  /*ctx->end->flags |= NK_WINDOW_ROM;*/
16129  ctx->begin->prev = win;
16130  win->next = ctx->begin;
16131  win->prev = 0;
16132  ctx->begin = win;
16133  ctx->begin->flags &= ~(nk_flags)NK_WINDOW_ROM;
16134  }
16135  ctx->count++;
16136 }
16137 NK_LIB void
16138 nk_remove_window(struct nk_context *ctx, struct nk_window *win)
16139 {
16140  if (win == ctx->begin || win == ctx->end) {
16141  if (win == ctx->begin) {
16142  ctx->begin = win->next;
16143  if (win->next)
16144  win->next->prev = 0;
16145  }
16146  if (win == ctx->end) {
16147  ctx->end = win->prev;
16148  if (win->prev)
16149  win->prev->next = 0;
16150  }
16151  } else {
16152  if (win->next)
16153  win->next->prev = win->prev;
16154  if (win->prev)
16155  win->prev->next = win->next;
16156  }
16157  if (win == ctx->active || !ctx->active) {
16158  ctx->active = ctx->end;
16159  if (ctx->end)
16160  ctx->end->flags &= ~(nk_flags)NK_WINDOW_ROM;
16161  }
16162  win->next = 0;
16163  win->prev = 0;
16164  ctx->count--;
16165 }
16166 NK_API int
16167 nk_begin(struct nk_context *ctx, const char *title,
16168  struct nk_rect bounds, nk_flags flags)
16169 {
16170  return nk_begin_titled(ctx, title, title, bounds, flags);
16171 }
16172 NK_API int
16173 nk_begin_titled(struct nk_context *ctx, const char *name, const char *title,
16174  struct nk_rect bounds, nk_flags flags)
16175 {
16176  struct nk_window *win;
16177  struct nk_style *style;
16178  nk_hash title_hash;
16179  int title_len;
16180  int ret = 0;
16181 
16182  NK_ASSERT(ctx);
16183  NK_ASSERT(name);
16184  NK_ASSERT(title);
16185  NK_ASSERT(ctx->style.font && ctx->style.font->width && "if this triggers you forgot to add a font");
16186  NK_ASSERT(!ctx->current && "if this triggers you missed a `nk_end` call");
16187  if (!ctx || ctx->current || !title || !name)
16188  return 0;
16189 
16190  /* find or create window */
16191  style = &ctx->style;
16192  title_len = (int)nk_strlen(name);
16193  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16194  win = nk_find_window(ctx, title_hash, name);
16195  if (!win) {
16196  /* create new window */
16197  nk_size name_length = (nk_size)nk_strlen(name);
16198  win = (struct nk_window*)nk_create_window(ctx);
16199  NK_ASSERT(win);
16200  if (!win) return 0;
16201 
16202  if (flags & NK_WINDOW_BACKGROUND)
16203  nk_insert_window(ctx, win, NK_INSERT_FRONT);
16204  else nk_insert_window(ctx, win, NK_INSERT_BACK);
16205  nk_command_buffer_init(&win->buffer, &ctx->memory, NK_CLIPPING_ON);
16206 
16207  win->flags = flags;
16208  win->bounds = bounds;
16209  win->name = title_hash;
16210  name_length = NK_MIN(name_length, NK_WINDOW_MAX_NAME-1);
16211  NK_MEMCPY(win->name_string, name, name_length);
16212  win->name_string[name_length] = 0;
16213  win->popup.win = 0;
16214  if (!ctx->active)
16215  ctx->active = win;
16216  } else {
16217  /* update window */
16218  win->flags &= ~(nk_flags)(NK_WINDOW_PRIVATE-1);
16219  win->flags |= flags;
16220  if (!(win->flags & (NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE)))
16221  win->bounds = bounds;
16222  /* If this assert triggers you either:
16223  *
16224  * I.) Have more than one window with the same name or
16225  * II.) You forgot to actually draw the window.
16226  * More specific you did not call `nk_clear` (nk_clear will be
16227  * automatically called for you if you are using one of the
16228  * provided demo backends). */
16229  NK_ASSERT(win->seq != ctx->seq);
16230  win->seq = ctx->seq;
16231  if (!ctx->active && !(win->flags & NK_WINDOW_HIDDEN)) {
16232  ctx->active = win;
16233  ctx->end = win;
16234  }
16235  }
16236  if (win->flags & NK_WINDOW_HIDDEN) {
16237  ctx->current = win;
16238  win->layout = 0;
16239  return 0;
16240  } else nk_start(ctx, win);
16241 
16242  /* window overlapping */
16243  if (!(win->flags & NK_WINDOW_HIDDEN) && !(win->flags & NK_WINDOW_NO_INPUT))
16244  {
16245  int inpanel, ishovered;
16246  struct nk_window *iter = win;
16247  float h = ctx->style.font->height + 2.0f * style->window.header.padding.y +
16248  (2.0f * style->window.header.label_padding.y);
16249  struct nk_rect win_bounds = (!(win->flags & NK_WINDOW_MINIMIZED))?
16250  win->bounds: nk_rect(win->bounds.x, win->bounds.y, win->bounds.w, h);
16251 
16252  /* activate window if hovered and no other window is overlapping this window */
16253  inpanel = nk_input_has_mouse_click_down_in_rect(&ctx->input, NK_BUTTON_LEFT, win_bounds, nk_true);
16254  inpanel = inpanel && ctx->input.mouse.buttons[NK_BUTTON_LEFT].clicked;
16255  ishovered = nk_input_is_mouse_hovering_rect(&ctx->input, win_bounds);
16256  if ((win != ctx->active) && ishovered && !ctx->input.mouse.buttons[NK_BUTTON_LEFT].down) {
16257  iter = win->next;
16258  while (iter) {
16259  struct nk_rect iter_bounds = (!(iter->flags & NK_WINDOW_MINIMIZED))?
16260  iter->bounds: nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
16261  if (NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
16262  iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
16263  (!(iter->flags & NK_WINDOW_HIDDEN)))
16264  break;
16265 
16266  if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) &&
16267  NK_INTERSECT(win->bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
16268  iter->popup.win->bounds.x, iter->popup.win->bounds.y,
16269  iter->popup.win->bounds.w, iter->popup.win->bounds.h))
16270  break;
16271  iter = iter->next;
16272  }
16273  }
16274 
16275  /* activate window if clicked */
16276  if (iter && inpanel && (win != ctx->end)) {
16277  iter = win->next;
16278  while (iter) {
16279  /* try to find a panel with higher priority in the same position */
16280  struct nk_rect iter_bounds = (!(iter->flags & NK_WINDOW_MINIMIZED))?
16281  iter->bounds: nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
16282  if (NK_INBOX(ctx->input.mouse.pos.x, ctx->input.mouse.pos.y,
16283  iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
16284  !(iter->flags & NK_WINDOW_HIDDEN))
16285  break;
16286  if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) &&
16287  NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
16288  iter->popup.win->bounds.x, iter->popup.win->bounds.y,
16289  iter->popup.win->bounds.w, iter->popup.win->bounds.h))
16290  break;
16291  iter = iter->next;
16292  }
16293  }
16294  if (iter && !(win->flags & NK_WINDOW_ROM) && (win->flags & NK_WINDOW_BACKGROUND)) {
16295  win->flags |= (nk_flags)NK_WINDOW_ROM;
16296  iter->flags &= ~(nk_flags)NK_WINDOW_ROM;
16297  ctx->active = iter;
16298  if (!(iter->flags & NK_WINDOW_BACKGROUND)) {
16299  /* current window is active in that position so transfer to top
16300  * at the highest priority in stack */
16301  nk_remove_window(ctx, iter);
16302  nk_insert_window(ctx, iter, NK_INSERT_BACK);
16303  }
16304  } else {
16305  if (!iter && ctx->end != win) {
16306  if (!(win->flags & NK_WINDOW_BACKGROUND)) {
16307  /* current window is active in that position so transfer to top
16308  * at the highest priority in stack */
16309  nk_remove_window(ctx, win);
16310  nk_insert_window(ctx, win, NK_INSERT_BACK);
16311  }
16312  win->flags &= ~(nk_flags)NK_WINDOW_ROM;
16313  ctx->active = win;
16314  }
16315  if (ctx->end != win && !(win->flags & NK_WINDOW_BACKGROUND))
16316  win->flags |= NK_WINDOW_ROM;
16317  }
16318  }
16319  win->layout = (struct nk_panel*)nk_create_panel(ctx);
16320  ctx->current = win;
16321  ret = nk_panel_begin(ctx, title, NK_PANEL_WINDOW);
16322  win->layout->offset_x = &win->scrollbar.x;
16323  win->layout->offset_y = &win->scrollbar.y;
16324  return ret;
16325 }
16326 NK_API void
16327 nk_end(struct nk_context *ctx)
16328 {
16329  struct nk_panel *layout;
16330  NK_ASSERT(ctx);
16331  NK_ASSERT(ctx->current && "if this triggers you forgot to call `nk_begin`");
16332  if (!ctx || !ctx->current)
16333  return;
16334 
16335  layout = ctx->current->layout;
16336  if (!layout || (layout->type == NK_PANEL_WINDOW && (ctx->current->flags & NK_WINDOW_HIDDEN))) {
16337  ctx->current = 0;
16338  return;
16339  }
16340  nk_panel_end(ctx);
16341  nk_free_panel(ctx, ctx->current->layout);
16342  ctx->current = 0;
16343 }
16344 NK_API struct nk_rect
16345 nk_window_get_bounds(const struct nk_context *ctx)
16346 {
16347  NK_ASSERT(ctx);
16348  NK_ASSERT(ctx->current);
16349  if (!ctx || !ctx->current) return nk_rect(0,0,0,0);
16350  return ctx->current->bounds;
16351 }
16352 NK_API struct nk_vec2
16353 nk_window_get_position(const struct nk_context *ctx)
16354 {
16355  NK_ASSERT(ctx);
16356  NK_ASSERT(ctx->current);
16357  if (!ctx || !ctx->current) return nk_vec2(0,0);
16358  return nk_vec2(ctx->current->bounds.x, ctx->current->bounds.y);
16359 }
16360 NK_API struct nk_vec2
16361 nk_window_get_size(const struct nk_context *ctx)
16362 {
16363  NK_ASSERT(ctx);
16364  NK_ASSERT(ctx->current);
16365  if (!ctx || !ctx->current) return nk_vec2(0,0);
16366  return nk_vec2(ctx->current->bounds.w, ctx->current->bounds.h);
16367 }
16368 NK_API float
16369 nk_window_get_width(const struct nk_context *ctx)
16370 {
16371  NK_ASSERT(ctx);
16372  NK_ASSERT(ctx->current);
16373  if (!ctx || !ctx->current) return 0;
16374  return ctx->current->bounds.w;
16375 }
16376 NK_API float
16377 nk_window_get_height(const struct nk_context *ctx)
16378 {
16379  NK_ASSERT(ctx);
16380  NK_ASSERT(ctx->current);
16381  if (!ctx || !ctx->current) return 0;
16382  return ctx->current->bounds.h;
16383 }
16384 NK_API struct nk_rect
16385 nk_window_get_content_region(struct nk_context *ctx)
16386 {
16387  NK_ASSERT(ctx);
16388  NK_ASSERT(ctx->current);
16389  if (!ctx || !ctx->current) return nk_rect(0,0,0,0);
16390  return ctx->current->layout->clip;
16391 }
16392 NK_API struct nk_vec2
16393 nk_window_get_content_region_min(struct nk_context *ctx)
16394 {
16395  NK_ASSERT(ctx);
16396  NK_ASSERT(ctx->current);
16397  NK_ASSERT(ctx->current->layout);
16398  if (!ctx || !ctx->current) return nk_vec2(0,0);
16399  return nk_vec2(ctx->current->layout->clip.x, ctx->current->layout->clip.y);
16400 }
16401 NK_API struct nk_vec2
16402 nk_window_get_content_region_max(struct nk_context *ctx)
16403 {
16404  NK_ASSERT(ctx);
16405  NK_ASSERT(ctx->current);
16406  NK_ASSERT(ctx->current->layout);
16407  if (!ctx || !ctx->current) return nk_vec2(0,0);
16408  return nk_vec2(ctx->current->layout->clip.x + ctx->current->layout->clip.w,
16409  ctx->current->layout->clip.y + ctx->current->layout->clip.h);
16410 }
16411 NK_API struct nk_vec2
16412 nk_window_get_content_region_size(struct nk_context *ctx)
16413 {
16414  NK_ASSERT(ctx);
16415  NK_ASSERT(ctx->current);
16416  NK_ASSERT(ctx->current->layout);
16417  if (!ctx || !ctx->current) return nk_vec2(0,0);
16418  return nk_vec2(ctx->current->layout->clip.w, ctx->current->layout->clip.h);
16419 }
16420 NK_API struct nk_command_buffer*
16421 nk_window_get_canvas(struct nk_context *ctx)
16422 {
16423  NK_ASSERT(ctx);
16424  NK_ASSERT(ctx->current);
16425  NK_ASSERT(ctx->current->layout);
16426  if (!ctx || !ctx->current) return 0;
16427  return &ctx->current->buffer;
16428 }
16429 NK_API struct nk_panel*
16430 nk_window_get_panel(struct nk_context *ctx)
16431 {
16432  NK_ASSERT(ctx);
16433  NK_ASSERT(ctx->current);
16434  if (!ctx || !ctx->current) return 0;
16435  return ctx->current->layout;
16436 }
16437 NK_API int
16438 nk_window_has_focus(const struct nk_context *ctx)
16439 {
16440  NK_ASSERT(ctx);
16441  NK_ASSERT(ctx->current);
16442  NK_ASSERT(ctx->current->layout);
16443  if (!ctx || !ctx->current) return 0;
16444  return ctx->current == ctx->active;
16445 }
16446 NK_API int
16447 nk_window_is_hovered(struct nk_context *ctx)
16448 {
16449  NK_ASSERT(ctx);
16450  NK_ASSERT(ctx->current);
16451  if (!ctx || !ctx->current) return 0;
16452  if(ctx->current->flags & NK_WINDOW_HIDDEN)
16453  return 0;
16454  return nk_input_is_mouse_hovering_rect(&ctx->input, ctx->current->bounds);
16455 }
16456 NK_API int
16457 nk_window_is_any_hovered(struct nk_context *ctx)
16458 {
16459  struct nk_window *iter;
16460  NK_ASSERT(ctx);
16461  if (!ctx) return 0;
16462  iter = ctx->begin;
16463  while (iter) {
16464  /* check if window is being hovered */
16465  if(!(iter->flags & NK_WINDOW_HIDDEN)) {
16466  /* check if window popup is being hovered */
16467  if (iter->popup.active && iter->popup.win && nk_input_is_mouse_hovering_rect(&ctx->input, iter->popup.win->bounds))
16468  return 1;
16469 
16470  if (iter->flags & NK_WINDOW_MINIMIZED) {
16471  struct nk_rect header = iter->bounds;
16472  header.h = ctx->style.font->height + 2 * ctx->style.window.header.padding.y;
16473  if (nk_input_is_mouse_hovering_rect(&ctx->input, header))
16474  return 1;
16475  } else if (nk_input_is_mouse_hovering_rect(&ctx->input, iter->bounds)) {
16476  return 1;
16477  }
16478  }
16479  iter = iter->next;
16480  }
16481  return 0;
16482 }
16483 NK_API int
16484 nk_item_is_any_active(struct nk_context *ctx)
16485 {
16486  int any_hovered = nk_window_is_any_hovered(ctx);
16487  int any_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
16488  return any_hovered || any_active;
16489 }
16490 NK_API int
16491 nk_window_is_collapsed(struct nk_context *ctx, const char *name)
16492 {
16493  int title_len;
16494  nk_hash title_hash;
16495  struct nk_window *win;
16496  NK_ASSERT(ctx);
16497  if (!ctx) return 0;
16498 
16499  title_len = (int)nk_strlen(name);
16500  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16501  win = nk_find_window(ctx, title_hash, name);
16502  if (!win) return 0;
16503  return win->flags & NK_WINDOW_MINIMIZED;
16504 }
16505 NK_API int
16506 nk_window_is_closed(struct nk_context *ctx, const char *name)
16507 {
16508  int title_len;
16509  nk_hash title_hash;
16510  struct nk_window *win;
16511  NK_ASSERT(ctx);
16512  if (!ctx) return 1;
16513 
16514  title_len = (int)nk_strlen(name);
16515  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16516  win = nk_find_window(ctx, title_hash, name);
16517  if (!win) return 1;
16518  return (win->flags & NK_WINDOW_CLOSED);
16519 }
16520 NK_API int
16521 nk_window_is_hidden(struct nk_context *ctx, const char *name)
16522 {
16523  int title_len;
16524  nk_hash title_hash;
16525  struct nk_window *win;
16526  NK_ASSERT(ctx);
16527  if (!ctx) return 1;
16528 
16529  title_len = (int)nk_strlen(name);
16530  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16531  win = nk_find_window(ctx, title_hash, name);
16532  if (!win) return 1;
16533  return (win->flags & NK_WINDOW_HIDDEN);
16534 }
16535 NK_API int
16536 nk_window_is_active(struct nk_context *ctx, const char *name)
16537 {
16538  int title_len;
16539  nk_hash title_hash;
16540  struct nk_window *win;
16541  NK_ASSERT(ctx);
16542  if (!ctx) return 0;
16543 
16544  title_len = (int)nk_strlen(name);
16545  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16546  win = nk_find_window(ctx, title_hash, name);
16547  if (!win) return 0;
16548  return win == ctx->active;
16549 }
16550 NK_API struct nk_window*
16551 nk_window_find(struct nk_context *ctx, const char *name)
16552 {
16553  int title_len;
16554  nk_hash title_hash;
16555  title_len = (int)nk_strlen(name);
16556  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16557  return nk_find_window(ctx, title_hash, name);
16558 }
16559 NK_API void
16560 nk_window_close(struct nk_context *ctx, const char *name)
16561 {
16562  struct nk_window *win;
16563  NK_ASSERT(ctx);
16564  if (!ctx) return;
16565  win = nk_window_find(ctx, name);
16566  if (!win) return;
16567  NK_ASSERT(ctx->current != win && "You cannot close a currently active window");
16568  if (ctx->current == win) return;
16569  win->flags |= NK_WINDOW_HIDDEN;
16570  win->flags |= NK_WINDOW_CLOSED;
16571 }
16572 NK_API void
16573 nk_window_set_bounds(struct nk_context *ctx,
16574  const char *name, struct nk_rect bounds)
16575 {
16576  struct nk_window *win;
16577  NK_ASSERT(ctx);
16578  if (!ctx) return;
16579  win = nk_window_find(ctx, name);
16580  if (!win) return;
16581  NK_ASSERT(ctx->current != win && "You cannot update a currently in procecss window");
16582  win->bounds = bounds;
16583 }
16584 NK_API void
16585 nk_window_set_position(struct nk_context *ctx,
16586  const char *name, struct nk_vec2 pos)
16587 {
16588  struct nk_window *win = nk_window_find(ctx, name);
16589  if (!win) return;
16590  win->bounds.x = pos.x;
16591  win->bounds.y = pos.y;
16592 }
16593 NK_API void
16594 nk_window_set_size(struct nk_context *ctx,
16595  const char *name, struct nk_vec2 size)
16596 {
16597  struct nk_window *win = nk_window_find(ctx, name);
16598  if (!win) return;
16599  win->bounds.w = size.x;
16600  win->bounds.h = size.y;
16601 }
16602 NK_API void
16603 nk_window_collapse(struct nk_context *ctx, const char *name,
16604  enum nk_collapse_states c)
16605 {
16606  int title_len;
16607  nk_hash title_hash;
16608  struct nk_window *win;
16609  NK_ASSERT(ctx);
16610  if (!ctx) return;
16611 
16612  title_len = (int)nk_strlen(name);
16613  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16614  win = nk_find_window(ctx, title_hash, name);
16615  if (!win) return;
16616  if (c == NK_MINIMIZED)
16617  win->flags |= NK_WINDOW_MINIMIZED;
16618  else win->flags &= ~(nk_flags)NK_WINDOW_MINIMIZED;
16619 }
16620 NK_API void
16621 nk_window_collapse_if(struct nk_context *ctx, const char *name,
16622  enum nk_collapse_states c, int cond)
16623 {
16624  NK_ASSERT(ctx);
16625  if (!ctx || !cond) return;
16626  nk_window_collapse(ctx, name, c);
16627 }
16628 NK_API void
16629 nk_window_show(struct nk_context *ctx, const char *name, enum nk_show_states s)
16630 {
16631  int title_len;
16632  nk_hash title_hash;
16633  struct nk_window *win;
16634  NK_ASSERT(ctx);
16635  if (!ctx) return;
16636 
16637  title_len = (int)nk_strlen(name);
16638  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16639  win = nk_find_window(ctx, title_hash, name);
16640  if (!win) return;
16641  if (s == NK_HIDDEN) {
16642  win->flags |= NK_WINDOW_HIDDEN;
16643  } else win->flags &= ~(nk_flags)NK_WINDOW_HIDDEN;
16644 }
16645 NK_API void
16646 nk_window_show_if(struct nk_context *ctx, const char *name,
16647  enum nk_show_states s, int cond)
16648 {
16649  NK_ASSERT(ctx);
16650  if (!ctx || !cond) return;
16651  nk_window_show(ctx, name, s);
16652 }
16653 
16654 NK_API void
16655 nk_window_set_focus(struct nk_context *ctx, const char *name)
16656 {
16657  int title_len;
16658  nk_hash title_hash;
16659  struct nk_window *win;
16660  NK_ASSERT(ctx);
16661  if (!ctx) return;
16662 
16663  title_len = (int)nk_strlen(name);
16664  title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
16665  win = nk_find_window(ctx, title_hash, name);
16666  if (win && ctx->end != win) {
16667  nk_remove_window(ctx, win);
16668  nk_insert_window(ctx, win, NK_INSERT_BACK);
16669  }
16670  ctx->active = win;
16671 }
16672 
16673 
16674 
16675 
16676 
16677 /* ===============================================================
16678  *
16679  * POPUP
16680  *
16681  * ===============================================================*/
16682 NK_API int
16683 nk_popup_begin(struct nk_context *ctx, enum nk_popup_type type,
16684  const char *title, nk_flags flags, struct nk_rect rect)
16685 {
16686  struct nk_window *popup;
16687  struct nk_window *win;
16688  struct nk_panel *panel;
16689 
16690  int title_len;
16691  nk_hash title_hash;
16692  nk_size allocated;
16693 
16694  NK_ASSERT(ctx);
16695  NK_ASSERT(title);
16696  NK_ASSERT(ctx->current);
16697  NK_ASSERT(ctx->current->layout);
16698  if (!ctx || !ctx->current || !ctx->current->layout)
16699  return 0;
16700 
16701  win = ctx->current;
16702  panel = win->layout;
16703  NK_ASSERT(!(panel->type & NK_PANEL_SET_POPUP) && "popups are not allowed to have popups");
16704  (void)panel;
16705  title_len = (int)nk_strlen(title);
16706  title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_POPUP);
16707 
16708  popup = win->popup.win;
16709  if (!popup) {
16710  popup = (struct nk_window*)nk_create_window(ctx);
16711  popup->parent = win;
16712  win->popup.win = popup;
16713  win->popup.active = 0;
16714  win->popup.type = NK_PANEL_POPUP;
16715  }
16716 
16717  /* make sure we have correct popup */
16718  if (win->popup.name != title_hash) {
16719  if (!win->popup.active) {
16720  nk_zero(popup, sizeof(*popup));
16721  win->popup.name = title_hash;
16722  win->popup.active = 1;
16723  win->popup.type = NK_PANEL_POPUP;
16724  } else return 0;
16725  }
16726 
16727  /* popup position is local to window */
16728  ctx->current = popup;
16729  rect.x += win->layout->clip.x;
16730  rect.y += win->layout->clip.y;
16731 
16732  /* setup popup data */
16733  popup->parent = win;
16734  popup->bounds = rect;
16735  popup->seq = ctx->seq;
16736  popup->layout = (struct nk_panel*)nk_create_panel(ctx);
16737  popup->flags = flags;
16738  popup->flags |= NK_WINDOW_BORDER;
16739  if (type == NK_POPUP_DYNAMIC)
16740  popup->flags |= NK_WINDOW_DYNAMIC;
16741 
16742  popup->buffer = win->buffer;
16743  nk_start_popup(ctx, win);
16744  allocated = ctx->memory.allocated;
16745  nk_push_scissor(&popup->buffer, nk_null_rect);
16746 
16747  if (nk_panel_begin(ctx, title, NK_PANEL_POPUP)) {
16748  /* popup is running therefore invalidate parent panels */
16749  struct nk_panel *root;
16750  root = win->layout;
16751  while (root) {
16752  root->flags |= NK_WINDOW_ROM;
16753  root->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM;
16754  root = root->parent;
16755  }
16756  win->popup.active = 1;
16757  popup->layout->offset_x = &popup->scrollbar.x;
16758  popup->layout->offset_y = &popup->scrollbar.y;
16759  popup->layout->parent = win->layout;
16760  return 1;
16761  } else {
16762  /* popup was closed/is invalid so cleanup */
16763  struct nk_panel *root;
16764  root = win->layout;
16765  while (root) {
16766  root->flags |= NK_WINDOW_REMOVE_ROM;
16767  root = root->parent;
16768  }
16769  win->popup.buf.active = 0;
16770  win->popup.active = 0;
16771  ctx->memory.allocated = allocated;
16772  ctx->current = win;
16773  nk_free_panel(ctx, popup->layout);
16774  popup->layout = 0;
16775  return 0;
16776  }
16777 }
16778 NK_LIB int
16779 nk_nonblock_begin(struct nk_context *ctx,
16780  nk_flags flags, struct nk_rect body, struct nk_rect header,
16781  enum nk_panel_type panel_type)
16782 {
16783  struct nk_window *popup;
16784  struct nk_window *win;
16785  struct nk_panel *panel;
16786  int is_active = nk_true;
16787 
16788  NK_ASSERT(ctx);
16789  NK_ASSERT(ctx->current);
16790  NK_ASSERT(ctx->current->layout);
16791  if (!ctx || !ctx->current || !ctx->current->layout)
16792  return 0;
16793 
16794  /* popups cannot have popups */
16795  win = ctx->current;
16796  panel = win->layout;
16797  NK_ASSERT(!(panel->type & NK_PANEL_SET_POPUP));
16798  (void)panel;
16799  popup = win->popup.win;
16800  if (!popup) {
16801  /* create window for nonblocking popup */
16802  popup = (struct nk_window*)nk_create_window(ctx);
16803  popup->parent = win;
16804  win->popup.win = popup;
16805  win->popup.type = panel_type;
16806  nk_command_buffer_init(&popup->buffer, &ctx->memory, NK_CLIPPING_ON);
16807  } else {
16808  /* close the popup if user pressed outside or in the header */
16809  int pressed, in_body, in_header;
16811  in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
16812  in_header = nk_input_is_mouse_hovering_rect(&ctx->input, header);
16813  if (pressed && (!in_body || in_header))
16814  is_active = nk_false;
16815  }
16816  win->popup.header = header;
16817 
16818  if (!is_active) {
16819  /* remove read only mode from all parent panels */
16820  struct nk_panel *root = win->layout;
16821  while (root) {
16822  root->flags |= NK_WINDOW_REMOVE_ROM;
16823  root = root->parent;
16824  }
16825  return is_active;
16826  }
16827  popup->bounds = body;
16828  popup->parent = win;
16829  popup->layout = (struct nk_panel*)nk_create_panel(ctx);
16830  popup->flags = flags;
16831  popup->flags |= NK_WINDOW_BORDER;
16832  popup->flags |= NK_WINDOW_DYNAMIC;
16833  popup->seq = ctx->seq;
16834  win->popup.active = 1;
16835  NK_ASSERT(popup->layout);
16836 
16837  nk_start_popup(ctx, win);
16838  popup->buffer = win->buffer;
16839  nk_push_scissor(&popup->buffer, nk_null_rect);
16840  ctx->current = popup;
16841 
16842  nk_panel_begin(ctx, 0, panel_type);
16843  win->buffer = popup->buffer;
16844  popup->layout->parent = win->layout;
16845  popup->layout->offset_x = &popup->scrollbar.x;
16846  popup->layout->offset_y = &popup->scrollbar.y;
16847 
16848  /* set read only mode to all parent panels */
16849  {struct nk_panel *root;
16850  root = win->layout;
16851  while (root) {
16852  root->flags |= NK_WINDOW_ROM;
16853  root = root->parent;
16854  }}
16855  return is_active;
16856 }
16857 NK_API void
16858 nk_popup_close(struct nk_context *ctx)
16859 {
16860  struct nk_window *popup;
16861  NK_ASSERT(ctx);
16862  if (!ctx || !ctx->current) return;
16863 
16864  popup = ctx->current;
16865  NK_ASSERT(popup->parent);
16866  NK_ASSERT(popup->layout->type & NK_PANEL_SET_POPUP);
16867  popup->flags |= NK_WINDOW_HIDDEN;
16868 }
16869 NK_API void
16870 nk_popup_end(struct nk_context *ctx)
16871 {
16872  struct nk_window *win;
16873  struct nk_window *popup;
16874 
16875  NK_ASSERT(ctx);
16876  NK_ASSERT(ctx->current);
16877  NK_ASSERT(ctx->current->layout);
16878  if (!ctx || !ctx->current || !ctx->current->layout)
16879  return;
16880 
16881  popup = ctx->current;
16882  if (!popup->parent) return;
16883  win = popup->parent;
16884  if (popup->flags & NK_WINDOW_HIDDEN) {
16885  struct nk_panel *root;
16886  root = win->layout;
16887  while (root) {
16888  root->flags |= NK_WINDOW_REMOVE_ROM;
16889  root = root->parent;
16890  }
16891  win->popup.active = 0;
16892  }
16893  nk_push_scissor(&popup->buffer, nk_null_rect);
16894  nk_end(ctx);
16895 
16896  win->buffer = popup->buffer;
16897  nk_finish_popup(ctx, win);
16898  ctx->current = win;
16899  nk_push_scissor(&win->buffer, win->layout->clip);
16900 }
16901 
16902 
16903 
16904 
16905 
16906 /* ==============================================================
16907  *
16908  * CONTEXTUAL
16909  *
16910  * ===============================================================*/
16911 NK_API int
16912 nk_contextual_begin(struct nk_context *ctx, nk_flags flags, struct nk_vec2 size,
16913  struct nk_rect trigger_bounds)
16914 {
16915  struct nk_window *win;
16916  struct nk_window *popup;
16917  struct nk_rect body;
16918 
16919  NK_STORAGE const struct nk_rect null_rect = {-1,-1,0,0};
16920  int is_clicked = 0;
16921  int is_open = 0;
16922  int ret = 0;
16923 
16924  NK_ASSERT(ctx);
16925  NK_ASSERT(ctx->current);
16926  NK_ASSERT(ctx->current->layout);
16927  if (!ctx || !ctx->current || !ctx->current->layout)
16928  return 0;
16929 
16930  win = ctx->current;
16931  ++win->popup.con_count;
16932  if (ctx->current != ctx->active)
16933  return 0;
16934 
16935  /* check if currently active contextual is active */
16936  popup = win->popup.win;
16937  is_open = (popup && win->popup.type == NK_PANEL_CONTEXTUAL);
16938  is_clicked = nk_input_mouse_clicked(&ctx->input, NK_BUTTON_RIGHT, trigger_bounds);
16939  if (win->popup.active_con && win->popup.con_count != win->popup.active_con)
16940  return 0;
16941  if (!is_open && win->popup.active_con)
16942  win->popup.active_con = 0;
16943  if ((!is_open && !is_clicked))
16944  return 0;
16945 
16946  /* calculate contextual position on click */
16947  win->popup.active_con = win->popup.con_count;
16948  if (is_clicked) {
16949  body.x = ctx->input.mouse.pos.x;
16950  body.y = ctx->input.mouse.pos.y;
16951  } else {
16952  body.x = popup->bounds.x;
16953  body.y = popup->bounds.y;
16954  }
16955  body.w = size.x;
16956  body.h = size.y;
16957 
16958  /* start nonblocking contextual popup */
16959  ret = nk_nonblock_begin(ctx, flags|NK_WINDOW_NO_SCROLLBAR, body,
16960  null_rect, NK_PANEL_CONTEXTUAL);
16961  if (ret) win->popup.type = NK_PANEL_CONTEXTUAL;
16962  else {
16963  win->popup.active_con = 0;
16964  win->popup.type = NK_PANEL_NONE;
16965  if (win->popup.win)
16966  win->popup.win->flags = 0;
16967  }
16968  return ret;
16969 }
16970 NK_API int
16971 nk_contextual_item_text(struct nk_context *ctx, const char *text, int len,
16972  nk_flags alignment)
16973 {
16974  struct nk_window *win;
16975  const struct nk_input *in;
16976  const struct nk_style *style;
16977 
16978  struct nk_rect bounds;
16980 
16981  NK_ASSERT(ctx);
16982  NK_ASSERT(ctx->current);
16983  NK_ASSERT(ctx->current->layout);
16984  if (!ctx || !ctx->current || !ctx->current->layout)
16985  return 0;
16986 
16987  win = ctx->current;
16988  style = &ctx->style;
16989  state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
16990  if (!state) return nk_false;
16991 
16992  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
16993  if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
16994  text, len, alignment, NK_BUTTON_DEFAULT, &style->contextual_button, in, style->font)) {
16995  nk_contextual_close(ctx);
16996  return nk_true;
16997  }
16998  return nk_false;
16999 }
17000 NK_API int
17001 nk_contextual_item_label(struct nk_context *ctx, const char *label, nk_flags align)
17002 {
17003  return nk_contextual_item_text(ctx, label, nk_strlen(label), align);
17004 }
17005 NK_API int
17006 nk_contextual_item_image_text(struct nk_context *ctx, struct nk_image img,
17007  const char *text, int len, nk_flags align)
17008 {
17009  struct nk_window *win;
17010  const struct nk_input *in;
17011  const struct nk_style *style;
17012 
17013  struct nk_rect bounds;
17015 
17016  NK_ASSERT(ctx);
17017  NK_ASSERT(ctx->current);
17018  NK_ASSERT(ctx->current->layout);
17019  if (!ctx || !ctx->current || !ctx->current->layout)
17020  return 0;
17021 
17022  win = ctx->current;
17023  style = &ctx->style;
17024  state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
17025  if (!state) return nk_false;
17026 
17027  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17028  if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, bounds,
17029  img, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)){
17030  nk_contextual_close(ctx);
17031  return nk_true;
17032  }
17033  return nk_false;
17034 }
17035 NK_API int
17036 nk_contextual_item_image_label(struct nk_context *ctx, struct nk_image img,
17037  const char *label, nk_flags align)
17038 {
17039  return nk_contextual_item_image_text(ctx, img, label, nk_strlen(label), align);
17040 }
17041 NK_API int
17042 nk_contextual_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type symbol,
17043  const char *text, int len, nk_flags align)
17044 {
17045  struct nk_window *win;
17046  const struct nk_input *in;
17047  const struct nk_style *style;
17048 
17049  struct nk_rect bounds;
17051 
17052  NK_ASSERT(ctx);
17053  NK_ASSERT(ctx->current);
17054  NK_ASSERT(ctx->current->layout);
17055  if (!ctx || !ctx->current || !ctx->current->layout)
17056  return 0;
17057 
17058  win = ctx->current;
17059  style = &ctx->style;
17060  state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
17061  if (!state) return nk_false;
17062 
17063  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17064  if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
17065  symbol, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)) {
17066  nk_contextual_close(ctx);
17067  return nk_true;
17068  }
17069  return nk_false;
17070 }
17071 NK_API int
17072 nk_contextual_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type symbol,
17073  const char *text, nk_flags align)
17074 {
17075  return nk_contextual_item_symbol_text(ctx, symbol, text, nk_strlen(text), align);
17076 }
17077 NK_API void
17078 nk_contextual_close(struct nk_context *ctx)
17079 {
17080  NK_ASSERT(ctx);
17081  NK_ASSERT(ctx->current);
17082  NK_ASSERT(ctx->current->layout);
17083  if (!ctx || !ctx->current || !ctx->current->layout) return;
17084  nk_popup_close(ctx);
17085 }
17086 NK_API void
17087 nk_contextual_end(struct nk_context *ctx)
17088 {
17089  struct nk_window *popup;
17090  struct nk_panel *panel;
17091  NK_ASSERT(ctx);
17092  NK_ASSERT(ctx->current);
17093  if (!ctx || !ctx->current) return;
17094 
17095  popup = ctx->current;
17096  panel = popup->layout;
17097  NK_ASSERT(popup->parent);
17098  NK_ASSERT(panel->type & NK_PANEL_SET_POPUP);
17099  if (panel->flags & NK_WINDOW_DYNAMIC) {
17100  /* Close behavior
17101  This is a bit of a hack solution since we do not know before we end our popup
17102  how big it will be. We therefore do not directly know when a
17103  click outside the non-blocking popup must close it at that direct frame.
17104  Instead it will be closed in the next frame.*/
17105  struct nk_rect body = {0,0,0,0};
17106  if (panel->at_y < (panel->bounds.y + panel->bounds.h)) {
17107  struct nk_vec2 padding = nk_panel_get_padding(&ctx->style, panel->type);
17108  body = panel->bounds;
17109  body.y = (panel->at_y + panel->footer_height + panel->border + padding.y + panel->row.height);
17110  body.h = (panel->bounds.y + panel->bounds.h) - body.y;
17111  }
17112  {int pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT);
17113  int in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
17114  if (pressed && in_body)
17115  popup->flags |= NK_WINDOW_HIDDEN;
17116  }
17117  }
17118  if (popup->flags & NK_WINDOW_HIDDEN)
17119  popup->seq = 0;
17120  nk_popup_end(ctx);
17121  return;
17122 }
17123 
17124 
17125 
17126 
17127 
17128 /* ===============================================================
17129  *
17130  * MENU
17131  *
17132  * ===============================================================*/
17133 NK_API void
17134 nk_menubar_begin(struct nk_context *ctx)
17135 {
17136  struct nk_panel *layout;
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;
17142 
17143  layout = ctx->current->layout;
17144  NK_ASSERT(layout->at_y == layout->bounds.y);
17145  /* if this assert triggers you allocated space between nk_begin and nk_menubar_begin.
17146  If you want a menubar the first nuklear function after `nk_begin` has to be a
17147  `nk_menubar_begin` call. Inside the menubar you then have to allocate space for
17148  widgets (also supports multiple rows).
17149  Example:
17150  if (nk_begin(...)) {
17151  nk_menubar_begin(...);
17152  nk_layout_xxxx(...);
17153  nk_button(...);
17154  nk_layout_xxxx(...);
17155  nk_button(...);
17156  nk_menubar_end(...);
17157  }
17158  nk_end(...);
17159  */
17160  if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED)
17161  return;
17162 
17163  layout->menu.x = layout->at_x;
17164  layout->menu.y = layout->at_y + layout->row.height;
17165  layout->menu.w = layout->bounds.w;
17166  layout->menu.offset.x = *layout->offset_x;
17167  layout->menu.offset.y = *layout->offset_y;
17168  *layout->offset_y = 0;
17169 }
17170 NK_API void
17171 nk_menubar_end(struct nk_context *ctx)
17172 {
17173  struct nk_window *win;
17174  struct nk_panel *layout;
17175  struct nk_command_buffer *out;
17176 
17177  NK_ASSERT(ctx);
17178  NK_ASSERT(ctx->current);
17179  NK_ASSERT(ctx->current->layout);
17180  if (!ctx || !ctx->current || !ctx->current->layout)
17181  return;
17182 
17183  win = ctx->current;
17184  out = &win->buffer;
17185  layout = win->layout;
17186  if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED)
17187  return;
17188 
17189  layout->menu.h = layout->at_y - layout->menu.y;
17190  layout->bounds.y += layout->menu.h + ctx->style.window.spacing.y + layout->row.height;
17191  layout->bounds.h -= layout->menu.h + ctx->style.window.spacing.y + layout->row.height;
17192 
17193  *layout->offset_x = layout->menu.offset.x;
17194  *layout->offset_y = layout->menu.offset.y;
17195  layout->at_y = layout->bounds.y - layout->row.height;
17196 
17197  layout->clip.y = layout->bounds.y;
17198  layout->clip.h = layout->bounds.h;
17199  nk_push_scissor(out, layout->clip);
17200 }
17201 NK_INTERN int
17202 nk_menu_begin(struct nk_context *ctx, struct nk_window *win,
17203  const char *id, int is_clicked, struct nk_rect header, struct nk_vec2 size)
17204 {
17205  int is_open = 0;
17206  int is_active = 0;
17207  struct nk_rect body;
17208  struct nk_window *popup;
17209  nk_hash hash = nk_murmur_hash(id, (int)nk_strlen(id), NK_PANEL_MENU);
17210 
17211  NK_ASSERT(ctx);
17212  NK_ASSERT(ctx->current);
17213  NK_ASSERT(ctx->current->layout);
17214  if (!ctx || !ctx->current || !ctx->current->layout)
17215  return 0;
17216 
17217  body.x = header.x;
17218  body.w = size.x;
17219  body.y = header.y + header.h;
17220  body.h = size.y;
17221 
17222  popup = win->popup.win;
17223  is_open = popup ? nk_true : nk_false;
17224  is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_MENU);
17225  if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
17226  (!is_open && !is_active && !is_clicked)) return 0;
17227  if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR, body, header, NK_PANEL_MENU))
17228  return 0;
17229 
17230  win->popup.type = NK_PANEL_MENU;
17231  win->popup.name = hash;
17232  return 1;
17233 }
17234 NK_API int
17235 nk_menu_begin_text(struct nk_context *ctx, const char *title, int len,
17236  nk_flags align, struct nk_vec2 size)
17237 {
17238  struct nk_window *win;
17239  const struct nk_input *in;
17240  struct nk_rect header;
17241  int is_clicked = nk_false;
17242  nk_flags state;
17243 
17244  NK_ASSERT(ctx);
17245  NK_ASSERT(ctx->current);
17246  NK_ASSERT(ctx->current->layout);
17247  if (!ctx || !ctx->current || !ctx->current->layout)
17248  return 0;
17249 
17250  win = ctx->current;
17251  state = nk_widget(&header, ctx);
17252  if (!state) return 0;
17253  in = (state == NK_WIDGET_ROM || win->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17254  if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, header,
17255  title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
17256  is_clicked = nk_true;
17257  return nk_menu_begin(ctx, win, title, is_clicked, header, size);
17258 }
17259 NK_API int nk_menu_begin_label(struct nk_context *ctx,
17260  const char *text, nk_flags align, struct nk_vec2 size)
17261 {
17262  return nk_menu_begin_text(ctx, text, nk_strlen(text), align, size);
17263 }
17264 NK_API int
17265 nk_menu_begin_image(struct nk_context *ctx, const char *id, struct nk_image img,
17266  struct nk_vec2 size)
17267 {
17268  struct nk_window *win;
17269  struct nk_rect header;
17270  const struct nk_input *in;
17271  int is_clicked = nk_false;
17272  nk_flags state;
17273 
17274  NK_ASSERT(ctx);
17275  NK_ASSERT(ctx->current);
17276  NK_ASSERT(ctx->current->layout);
17277  if (!ctx || !ctx->current || !ctx->current->layout)
17278  return 0;
17279 
17280  win = ctx->current;
17281  state = nk_widget(&header, ctx);
17282  if (!state) return 0;
17283  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17284  if (nk_do_button_image(&ctx->last_widget_state, &win->buffer, header,
17285  img, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in))
17286  is_clicked = nk_true;
17287  return nk_menu_begin(ctx, win, id, is_clicked, header, size);
17288 }
17289 NK_API int
17290 nk_menu_begin_symbol(struct nk_context *ctx, const char *id,
17291  enum nk_symbol_type sym, struct nk_vec2 size)
17292 {
17293  struct nk_window *win;
17294  const struct nk_input *in;
17295  struct nk_rect header;
17296  int is_clicked = nk_false;
17297  nk_flags state;
17298 
17299  NK_ASSERT(ctx);
17300  NK_ASSERT(ctx->current);
17301  NK_ASSERT(ctx->current->layout);
17302  if (!ctx || !ctx->current || !ctx->current->layout)
17303  return 0;
17304 
17305  win = ctx->current;
17306  state = nk_widget(&header, ctx);
17307  if (!state) return 0;
17308  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17309  if (nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, header,
17310  sym, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
17311  is_clicked = nk_true;
17312  return nk_menu_begin(ctx, win, id, is_clicked, header, size);
17313 }
17314 NK_API int
17315 nk_menu_begin_image_text(struct nk_context *ctx, const char *title, int len,
17316  nk_flags align, struct nk_image img, struct nk_vec2 size)
17317 {
17318  struct nk_window *win;
17319  struct nk_rect header;
17320  const struct nk_input *in;
17321  int is_clicked = nk_false;
17322  nk_flags state;
17323 
17324  NK_ASSERT(ctx);
17325  NK_ASSERT(ctx->current);
17326  NK_ASSERT(ctx->current->layout);
17327  if (!ctx || !ctx->current || !ctx->current->layout)
17328  return 0;
17329 
17330  win = ctx->current;
17331  state = nk_widget(&header, ctx);
17332  if (!state) return 0;
17333  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17334  if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
17335  header, img, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
17336  ctx->style.font, in))
17337  is_clicked = nk_true;
17338  return nk_menu_begin(ctx, win, title, is_clicked, header, size);
17339 }
17340 NK_API int
17341 nk_menu_begin_image_label(struct nk_context *ctx,
17342  const char *title, nk_flags align, struct nk_image img, struct nk_vec2 size)
17343 {
17344  return nk_menu_begin_image_text(ctx, title, nk_strlen(title), align, img, size);
17345 }
17346 NK_API int
17347 nk_menu_begin_symbol_text(struct nk_context *ctx, const char *title, int len,
17348  nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size)
17349 {
17350  struct nk_window *win;
17351  struct nk_rect header;
17352  const struct nk_input *in;
17353  int is_clicked = nk_false;
17354  nk_flags state;
17355 
17356  NK_ASSERT(ctx);
17357  NK_ASSERT(ctx->current);
17358  NK_ASSERT(ctx->current->layout);
17359  if (!ctx || !ctx->current || !ctx->current->layout)
17360  return 0;
17361 
17362  win = ctx->current;
17363  state = nk_widget(&header, ctx);
17364  if (!state) return 0;
17365 
17366  in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
17367  if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer,
17368  header, sym, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
17369  ctx->style.font, in)) is_clicked = nk_true;
17370  return nk_menu_begin(ctx, win, title, is_clicked, header, size);
17371 }
17372 NK_API int
17373 nk_menu_begin_symbol_label(struct nk_context *ctx,
17374  const char *title, nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size )
17375 {
17376  return nk_menu_begin_symbol_text(ctx, title, nk_strlen(title), align,sym,size);
17377 }
17378 NK_API int
17379 nk_menu_item_text(struct nk_context *ctx, const char *title, int len, nk_flags align)
17380 {
17381  return nk_contextual_item_text(ctx, title, len, align);
17382 }
17383 NK_API int
17384 nk_menu_item_label(struct nk_context *ctx, const char *label, nk_flags align)
17385 {
17386  return nk_contextual_item_label(ctx, label, align);
17387 }
17388 NK_API int
17389 nk_menu_item_image_label(struct nk_context *ctx, struct nk_image img,
17390  const char *label, nk_flags align)
17391 {
17392  return nk_contextual_item_image_label(ctx, img, label, align);
17393 }
17394 NK_API int
17395 nk_menu_item_image_text(struct nk_context *ctx, struct nk_image img,
17396  const char *text, int len, nk_flags align)
17397 {
17398  return nk_contextual_item_image_text(ctx, img, text, len, align);
17399 }
17400 NK_API int nk_menu_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym,
17401  const char *text, int len, nk_flags align)
17402 {
17403  return nk_contextual_item_symbol_text(ctx, sym, text, len, align);
17404 }
17405 NK_API int nk_menu_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym,
17406  const char *label, nk_flags align)
17407 {
17408  return nk_contextual_item_symbol_label(ctx, sym, label, align);
17409 }
17410 NK_API void nk_menu_close(struct nk_context *ctx)
17411 {
17412  nk_contextual_close(ctx);
17413 }
17414 NK_API void
17415 nk_menu_end(struct nk_context *ctx)
17416 {
17417  nk_contextual_end(ctx);
17418 }
17419 
17420 
17421 
17422 
17423 
17424 /* ===============================================================
17425  *
17426  * LAYOUT
17427  *
17428  * ===============================================================*/
17429 NK_API void
17430 nk_layout_set_min_row_height(struct nk_context *ctx, float height)
17431 {
17432  struct nk_window *win;
17433  struct nk_panel *layout;
17434 
17435  NK_ASSERT(ctx);
17436  NK_ASSERT(ctx->current);
17437  NK_ASSERT(ctx->current->layout);
17438  if (!ctx || !ctx->current || !ctx->current->layout)
17439  return;
17440 
17441  win = ctx->current;
17442  layout = win->layout;
17443  layout->row.min_height = height;
17444 }
17445 NK_API void
17446 nk_layout_reset_min_row_height(struct nk_context *ctx)
17447 {
17448  struct nk_window *win;
17449  struct nk_panel *layout;
17450 
17451  NK_ASSERT(ctx);
17452  NK_ASSERT(ctx->current);
17453  NK_ASSERT(ctx->current->layout);
17454  if (!ctx || !ctx->current || !ctx->current->layout)
17455  return;
17456 
17457  win = ctx->current;
17458  layout = win->layout;
17459  layout->row.min_height = ctx->style.font->height;
17460  layout->row.min_height += ctx->style.text.padding.y*2;
17461  layout->row.min_height += ctx->style.window.min_row_height_padding*2;
17462 }
17463 NK_LIB float
17464 nk_layout_row_calculate_usable_space(const struct nk_style *style, enum nk_panel_type type,
17465  float total_space, int columns)
17466 {
17467  float panel_padding;
17468  float panel_spacing;
17469  float panel_space;
17470 
17471  struct nk_vec2 spacing;
17472  struct nk_vec2 padding;
17473 
17474  spacing = style->window.spacing;
17475  padding = nk_panel_get_padding(style, type);
17476 
17477  /* calculate the usable panel space */
17478  panel_padding = 2 * padding.x;
17479  panel_spacing = (float)NK_MAX(columns - 1, 0) * spacing.x;
17480  panel_space = total_space - panel_padding - panel_spacing;
17481  return panel_space;
17482 }
17483 NK_LIB void
17484 nk_panel_layout(const struct nk_context *ctx, struct nk_window *win,
17485  float height, int cols)
17486 {
17487  struct nk_panel *layout;
17488  const struct nk_style *style;
17489  struct nk_command_buffer *out;
17490 
17491  struct nk_vec2 item_spacing;
17492  struct nk_color color;
17493 
17494  NK_ASSERT(ctx);
17495  NK_ASSERT(ctx->current);
17496  NK_ASSERT(ctx->current->layout);
17497  if (!ctx || !ctx->current || !ctx->current->layout)
17498  return;
17499 
17500  /* prefetch some configuration data */
17501  layout = win->layout;
17502  style = &ctx->style;
17503  out = &win->buffer;
17504  color = style->window.background;
17505  item_spacing = style->window.spacing;
17506 
17507  /* if one of these triggers you forgot to add an `if` condition around either
17508  a window, group, popup, combobox or contextual menu `begin` and `end` block.
17509  Example:
17510  if (nk_begin(...) {...} nk_end(...); or
17511  if (nk_group_begin(...) { nk_group_end(...);} */
17512  NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED));
17513  NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN));
17514  NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED));
17515 
17516  /* update the current row and set the current row layout */
17517  layout->row.index = 0;
17518  layout->at_y += layout->row.height;
17519  layout->row.columns = cols;
17520  if (height == 0.0f)
17521  layout->row.height = NK_MAX(height, layout->row.min_height) + item_spacing.y;
17522  else layout->row.height = height + item_spacing.y;
17523 
17524  layout->row.item_offset = 0;
17525  if (layout->flags & NK_WINDOW_DYNAMIC) {
17526  /* draw background for dynamic panels */
17527  struct nk_rect background;
17528  background.x = win->bounds.x;
17529  background.w = win->bounds.w;
17530  background.y = layout->at_y - 1.0f;
17531  background.h = layout->row.height + 1.0f;
17532  nk_fill_rect(out, background, 0, color);
17533  }
17534 }
17535 NK_LIB void
17536 nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt,
17537  float height, int cols, int width)
17538 {
17539  /* update the current row and set the current row layout */
17540  struct nk_window *win;
17541  NK_ASSERT(ctx);
17542  NK_ASSERT(ctx->current);
17543  NK_ASSERT(ctx->current->layout);
17544  if (!ctx || !ctx->current || !ctx->current->layout)
17545  return;
17546 
17547  win = ctx->current;
17548  nk_panel_layout(ctx, win, height, cols);
17549  if (fmt == NK_DYNAMIC)
17551  else win->layout->row.type = NK_LAYOUT_STATIC_FIXED;
17552 
17553  win->layout->row.ratio = 0;
17554  win->layout->row.filled = 0;
17555  win->layout->row.item_offset = 0;
17556  win->layout->row.item_width = (float)width;
17557 }
17558 NK_API float
17559 nk_layout_ratio_from_pixel(struct nk_context *ctx, float pixel_width)
17560 {
17561  struct nk_window *win;
17562  NK_ASSERT(ctx);
17563  NK_ASSERT(pixel_width);
17564  if (!ctx || !ctx->current || !ctx->current->layout) return 0;
17565  win = ctx->current;
17566  return NK_CLAMP(0.0f, pixel_width/win->bounds.x, 1.0f);
17567 }
17568 NK_API void
17569 nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols)
17570 {
17571  nk_row_layout(ctx, NK_DYNAMIC, height, cols, 0);
17572 }
17573 NK_API void
17574 nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols)
17575 {
17576  nk_row_layout(ctx, NK_STATIC, height, cols, item_width);
17577 }
17578 NK_API void
17579 nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt,
17580  float row_height, int cols)
17581 {
17582  struct nk_window *win;
17583  struct nk_panel *layout;
17584 
17585  NK_ASSERT(ctx);
17586  NK_ASSERT(ctx->current);
17587  NK_ASSERT(ctx->current->layout);
17588  if (!ctx || !ctx->current || !ctx->current->layout)
17589  return;
17590 
17591  win = ctx->current;
17592  layout = win->layout;
17593  nk_panel_layout(ctx, win, row_height, cols);
17594  if (fmt == NK_DYNAMIC)
17595  layout->row.type = NK_LAYOUT_DYNAMIC_ROW;
17596  else layout->row.type = NK_LAYOUT_STATIC_ROW;
17597 
17598  layout->row.ratio = 0;
17599  layout->row.filled = 0;
17600  layout->row.item_width = 0;
17601  layout->row.item_offset = 0;
17602  layout->row.columns = cols;
17603 }
17604 NK_API void
17605 nk_layout_row_push(struct nk_context *ctx, float ratio_or_width)
17606 {
17607  struct nk_window *win;
17608  struct nk_panel *layout;
17609 
17610  NK_ASSERT(ctx);
17611  NK_ASSERT(ctx->current);
17612  NK_ASSERT(ctx->current->layout);
17613  if (!ctx || !ctx->current || !ctx->current->layout)
17614  return;
17615 
17616  win = ctx->current;
17617  layout = win->layout;
17618  NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
17619  if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
17620  return;
17621 
17622  if (layout->row.type == NK_LAYOUT_DYNAMIC_ROW) {
17623  float ratio = ratio_or_width;
17624  if ((ratio + layout->row.filled) > 1.0f) return;
17625  if (ratio > 0.0f)
17626  layout->row.item_width = NK_SATURATE(ratio);
17627  else layout->row.item_width = 1.0f - layout->row.filled;
17628  } else layout->row.item_width = ratio_or_width;
17629 }
17630 NK_API void
17631 nk_layout_row_end(struct nk_context *ctx)
17632 {
17633  struct nk_window *win;
17634  struct nk_panel *layout;
17635 
17636  NK_ASSERT(ctx);
17637  NK_ASSERT(ctx->current);
17638  NK_ASSERT(ctx->current->layout);
17639  if (!ctx || !ctx->current || !ctx->current->layout)
17640  return;
17641 
17642  win = ctx->current;
17643  layout = win->layout;
17644  NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
17645  if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
17646  return;
17647  layout->row.item_width = 0;
17648  layout->row.item_offset = 0;
17649 }
17650 NK_API void
17651 nk_layout_row(struct nk_context *ctx, enum nk_layout_format fmt,
17652  float height, int cols, const float *ratio)
17653 {
17654  int i;
17655  int n_undef = 0;
17656  struct nk_window *win;
17657  struct nk_panel *layout;
17658 
17659  NK_ASSERT(ctx);
17660  NK_ASSERT(ctx->current);
17661  NK_ASSERT(ctx->current->layout);
17662  if (!ctx || !ctx->current || !ctx->current->layout)
17663  return;
17664 
17665  win = ctx->current;
17666  layout = win->layout;
17667  nk_panel_layout(ctx, win, height, cols);
17668  if (fmt == NK_DYNAMIC) {
17669  /* calculate width of undefined widget ratios */
17670  float r = 0;
17671  layout->row.ratio = ratio;
17672  for (i = 0; i < cols; ++i) {
17673  if (ratio[i] < 0.0f)
17674  n_undef++;
17675  else r += ratio[i];
17676  }
17677  r = NK_SATURATE(1.0f - r);
17678  layout->row.type = NK_LAYOUT_DYNAMIC;
17679  layout->row.item_width = (r > 0 && n_undef > 0) ? (r / (float)n_undef):0;
17680  } else {
17681  layout->row.ratio = ratio;
17682  layout->row.type = NK_LAYOUT_STATIC;
17683  layout->row.item_width = 0;
17684  layout->row.item_offset = 0;
17685  }
17686  layout->row.item_offset = 0;
17687  layout->row.filled = 0;
17688 }
17689 NK_API void
17690 nk_layout_row_template_begin(struct nk_context *ctx, float height)
17691 {
17692  struct nk_window *win;
17693  struct nk_panel *layout;
17694 
17695  NK_ASSERT(ctx);
17696  NK_ASSERT(ctx->current);
17697  NK_ASSERT(ctx->current->layout);
17698  if (!ctx || !ctx->current || !ctx->current->layout)
17699  return;
17700 
17701  win = ctx->current;
17702  layout = win->layout;
17703  nk_panel_layout(ctx, win, height, 1);
17704  layout->row.type = NK_LAYOUT_TEMPLATE;
17705  layout->row.columns = 0;
17706  layout->row.ratio = 0;
17707  layout->row.item_width = 0;
17708  layout->row.item_height = 0;
17709  layout->row.item_offset = 0;
17710  layout->row.filled = 0;
17711  layout->row.item.x = 0;
17712  layout->row.item.y = 0;
17713  layout->row.item.w = 0;
17714  layout->row.item.h = 0;
17715 }
17716 NK_API void
17717 nk_layout_row_template_push_dynamic(struct nk_context *ctx)
17718 {
17719  struct nk_window *win;
17720  struct nk_panel *layout;
17721 
17722  NK_ASSERT(ctx);
17723  NK_ASSERT(ctx->current);
17724  NK_ASSERT(ctx->current->layout);
17725  if (!ctx || !ctx->current || !ctx->current->layout)
17726  return;
17727 
17728  win = ctx->current;
17729  layout = win->layout;
17730  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
17731  NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
17732  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
17733  if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
17734  layout->row.templates[layout->row.columns++] = -1.0f;
17735 }
17736 NK_API void
17737 nk_layout_row_template_push_variable(struct nk_context *ctx, float min_width)
17738 {
17739  struct nk_window *win;
17740  struct nk_panel *layout;
17741 
17742  NK_ASSERT(ctx);
17743  NK_ASSERT(ctx->current);
17744  NK_ASSERT(ctx->current->layout);
17745  if (!ctx || !ctx->current || !ctx->current->layout)
17746  return;
17747 
17748  win = ctx->current;
17749  layout = win->layout;
17750  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
17751  NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
17752  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
17753  if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
17754  layout->row.templates[layout->row.columns++] = -min_width;
17755 }
17756 NK_API void
17757 nk_layout_row_template_push_static(struct nk_context *ctx, float width)
17758 {
17759  struct nk_window *win;
17760  struct nk_panel *layout;
17761 
17762  NK_ASSERT(ctx);
17763  NK_ASSERT(ctx->current);
17764  NK_ASSERT(ctx->current->layout);
17765  if (!ctx || !ctx->current || !ctx->current->layout)
17766  return;
17767 
17768  win = ctx->current;
17769  layout = win->layout;
17770  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
17771  NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
17772  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
17773  if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
17774  layout->row.templates[layout->row.columns++] = width;
17775 }
17776 NK_API void
17777 nk_layout_row_template_end(struct nk_context *ctx)
17778 {
17779  struct nk_window *win;
17780  struct nk_panel *layout;
17781 
17782  int i = 0;
17783  int variable_count = 0;
17784  int min_variable_count = 0;
17785  float min_fixed_width = 0.0f;
17786  float total_fixed_width = 0.0f;
17787  float max_variable_width = 0.0f;
17788 
17789  NK_ASSERT(ctx);
17790  NK_ASSERT(ctx->current);
17791  NK_ASSERT(ctx->current->layout);
17792  if (!ctx || !ctx->current || !ctx->current->layout)
17793  return;
17794 
17795  win = ctx->current;
17796  layout = win->layout;
17797  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
17798  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
17799  for (i = 0; i < layout->row.columns; ++i) {
17800  float width = layout->row.templates[i];
17801  if (width >= 0.0f) {
17802  total_fixed_width += width;
17803  min_fixed_width += width;
17804  } else if (width < -1.0f) {
17805  width = -width;
17806  total_fixed_width += width;
17807  max_variable_width = NK_MAX(max_variable_width, width);
17808  variable_count++;
17809  } else {
17810  min_variable_count++;
17811  variable_count++;
17812  }
17813  }
17814  if (variable_count) {
17815  float space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
17816  layout->bounds.w, layout->row.columns);
17817  float var_width = (NK_MAX(space-min_fixed_width,0.0f)) / (float)variable_count;
17818  int enough_space = var_width >= max_variable_width;
17819  if (!enough_space)
17820  var_width = (NK_MAX(space-total_fixed_width,0)) / (float)min_variable_count;
17821  for (i = 0; i < layout->row.columns; ++i) {
17822  float *width = &layout->row.templates[i];
17823  *width = (*width >= 0.0f)? *width: (*width < -1.0f && !enough_space)? -(*width): var_width;
17824  }
17825  }
17826 }
17827 NK_API void
17828 nk_layout_space_begin(struct nk_context *ctx, enum nk_layout_format fmt,
17829  float height, int widget_count)
17830 {
17831  struct nk_window *win;
17832  struct nk_panel *layout;
17833 
17834  NK_ASSERT(ctx);
17835  NK_ASSERT(ctx->current);
17836  NK_ASSERT(ctx->current->layout);
17837  if (!ctx || !ctx->current || !ctx->current->layout)
17838  return;
17839 
17840  win = ctx->current;
17841  layout = win->layout;
17842  nk_panel_layout(ctx, win, height, widget_count);
17843  if (fmt == NK_STATIC)
17844  layout->row.type = NK_LAYOUT_STATIC_FREE;
17845  else layout->row.type = NK_LAYOUT_DYNAMIC_FREE;
17846 
17847  layout->row.ratio = 0;
17848  layout->row.filled = 0;
17849  layout->row.item_width = 0;
17850  layout->row.item_offset = 0;
17851 }
17852 NK_API void
17853 nk_layout_space_end(struct nk_context *ctx)
17854 {
17855  struct nk_window *win;
17856  struct nk_panel *layout;
17857 
17858  NK_ASSERT(ctx);
17859  NK_ASSERT(ctx->current);
17860  NK_ASSERT(ctx->current->layout);
17861  if (!ctx || !ctx->current || !ctx->current->layout)
17862  return;
17863 
17864  win = ctx->current;
17865  layout = win->layout;
17866  layout->row.item_width = 0;
17867  layout->row.item_height = 0;
17868  layout->row.item_offset = 0;
17869  nk_zero(&layout->row.item, sizeof(layout->row.item));
17870 }
17871 NK_API void
17872 nk_layout_space_push(struct nk_context *ctx, struct nk_rect rect)
17873 {
17874  struct nk_window *win;
17875  struct nk_panel *layout;
17876 
17877  NK_ASSERT(ctx);
17878  NK_ASSERT(ctx->current);
17879  NK_ASSERT(ctx->current->layout);
17880  if (!ctx || !ctx->current || !ctx->current->layout)
17881  return;
17882 
17883  win = ctx->current;
17884  layout = win->layout;
17885  layout->row.item = rect;
17886 }
17887 NK_API struct nk_rect
17888 nk_layout_space_bounds(struct nk_context *ctx)
17889 {
17890  struct nk_rect ret;
17891  struct nk_window *win;
17892  struct nk_panel *layout;
17893 
17894  NK_ASSERT(ctx);
17895  NK_ASSERT(ctx->current);
17896  NK_ASSERT(ctx->current->layout);
17897  win = ctx->current;
17898  layout = win->layout;
17899 
17900  ret.x = layout->clip.x;
17901  ret.y = layout->clip.y;
17902  ret.w = layout->clip.w;
17903  ret.h = layout->row.height;
17904  return ret;
17905 }
17906 NK_API struct nk_rect
17907 nk_layout_widget_bounds(struct nk_context *ctx)
17908 {
17909  struct nk_rect ret;
17910  struct nk_window *win;
17911  struct nk_panel *layout;
17912 
17913  NK_ASSERT(ctx);
17914  NK_ASSERT(ctx->current);
17915  NK_ASSERT(ctx->current->layout);
17916  win = ctx->current;
17917  layout = win->layout;
17918 
17919  ret.x = layout->at_x;
17920  ret.y = layout->at_y;
17921  ret.w = layout->bounds.w - NK_MAX(layout->at_x - layout->bounds.x,0);
17922  ret.h = layout->row.height;
17923  return ret;
17924 }
17925 NK_API struct nk_vec2
17926 nk_layout_space_to_screen(struct nk_context *ctx, struct nk_vec2 ret)
17927 {
17928  struct nk_window *win;
17929  struct nk_panel *layout;
17930 
17931  NK_ASSERT(ctx);
17932  NK_ASSERT(ctx->current);
17933  NK_ASSERT(ctx->current->layout);
17934  win = ctx->current;
17935  layout = win->layout;
17936 
17937  ret.x += layout->at_x - (float)*layout->offset_x;
17938  ret.y += layout->at_y - (float)*layout->offset_y;
17939  return ret;
17940 }
17941 NK_API struct nk_vec2
17942 nk_layout_space_to_local(struct nk_context *ctx, struct nk_vec2 ret)
17943 {
17944  struct nk_window *win;
17945  struct nk_panel *layout;
17946 
17947  NK_ASSERT(ctx);
17948  NK_ASSERT(ctx->current);
17949  NK_ASSERT(ctx->current->layout);
17950  win = ctx->current;
17951  layout = win->layout;
17952 
17953  ret.x += -layout->at_x + (float)*layout->offset_x;
17954  ret.y += -layout->at_y + (float)*layout->offset_y;
17955  return ret;
17956 }
17957 NK_API struct nk_rect
17958 nk_layout_space_rect_to_screen(struct nk_context *ctx, struct nk_rect ret)
17959 {
17960  struct nk_window *win;
17961  struct nk_panel *layout;
17962 
17963  NK_ASSERT(ctx);
17964  NK_ASSERT(ctx->current);
17965  NK_ASSERT(ctx->current->layout);
17966  win = ctx->current;
17967  layout = win->layout;
17968 
17969  ret.x += layout->at_x - (float)*layout->offset_x;
17970  ret.y += layout->at_y - (float)*layout->offset_y;
17971  return ret;
17972 }
17973 NK_API struct nk_rect
17974 nk_layout_space_rect_to_local(struct nk_context *ctx, struct nk_rect ret)
17975 {
17976  struct nk_window *win;
17977  struct nk_panel *layout;
17978 
17979  NK_ASSERT(ctx);
17980  NK_ASSERT(ctx->current);
17981  NK_ASSERT(ctx->current->layout);
17982  win = ctx->current;
17983  layout = win->layout;
17984 
17985  ret.x += -layout->at_x + (float)*layout->offset_x;
17986  ret.y += -layout->at_y + (float)*layout->offset_y;
17987  return ret;
17988 }
17989 NK_LIB void
17990 nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win)
17991 {
17992  struct nk_panel *layout = win->layout;
17993  struct nk_vec2 spacing = ctx->style.window.spacing;
17994  const float row_height = layout->row.height - spacing.y;
17995  nk_panel_layout(ctx, win, row_height, layout->row.columns);
17996 }
17997 NK_LIB void
17998 nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx,
17999  struct nk_window *win, int modify)
18000 {
18001  struct nk_panel *layout;
18002  const struct nk_style *style;
18003 
18004  struct nk_vec2 spacing;
18005  struct nk_vec2 padding;
18006 
18007  float item_offset = 0;
18008  float item_width = 0;
18009  float item_spacing = 0;
18010  float panel_space = 0;
18011 
18012  NK_ASSERT(ctx);
18013  NK_ASSERT(ctx->current);
18014  NK_ASSERT(ctx->current->layout);
18015  if (!ctx || !ctx->current || !ctx->current->layout)
18016  return;
18017 
18018  win = ctx->current;
18019  layout = win->layout;
18020  style = &ctx->style;
18021  NK_ASSERT(bounds);
18022 
18023  spacing = style->window.spacing;
18024  padding = nk_panel_get_padding(style, layout->type);
18025  panel_space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
18026  layout->bounds.w, layout->row.columns);
18027 
18028  /* calculate the width of one item inside the current layout space */
18029  switch (layout->row.type) {
18030  case NK_LAYOUT_DYNAMIC_FIXED: {
18031  /* scaling fixed size widgets item width */
18032  item_width = NK_MAX(1.0f,panel_space) / (float)layout->row.columns;
18033  item_offset = (float)layout->row.index * item_width;
18034  item_spacing = (float)layout->row.index * spacing.x;
18035  } break;
18036  case NK_LAYOUT_DYNAMIC_ROW: {
18037  /* scaling single ratio widget width */
18038  item_width = layout->row.item_width * panel_space;
18039  item_offset = layout->row.item_offset;
18040  item_spacing = 0;
18041 
18042  if (modify) {
18043  layout->row.item_offset += item_width + spacing.x;
18044  layout->row.filled += layout->row.item_width;
18045  layout->row.index = 0;
18046  }
18047  } break;
18048  case NK_LAYOUT_DYNAMIC_FREE: {
18049  /* panel width depended free widget placing */
18050  bounds->x = layout->at_x + (layout->bounds.w * layout->row.item.x);
18051  bounds->x -= (float)*layout->offset_x;
18052  bounds->y = layout->at_y + (layout->row.height * layout->row.item.y);
18053  bounds->y -= (float)*layout->offset_y;
18054  bounds->w = layout->bounds.w * layout->row.item.w;
18055  bounds->h = layout->row.height * layout->row.item.h;
18056  return;
18057  }
18058  case NK_LAYOUT_DYNAMIC: {
18059  /* scaling arrays of panel width ratios for every widget */
18060  float ratio;
18061  NK_ASSERT(layout->row.ratio);
18062  ratio = (layout->row.ratio[layout->row.index] < 0) ?
18063  layout->row.item_width : layout->row.ratio[layout->row.index];
18064 
18065  item_spacing = (float)layout->row.index * spacing.x;
18066  item_width = (ratio * panel_space);
18067  item_offset = layout->row.item_offset;
18068 
18069  if (modify) {
18070  layout->row.item_offset += item_width;
18071  layout->row.filled += ratio;
18072  }
18073  } break;
18074  case NK_LAYOUT_STATIC_FIXED: {
18075  /* non-scaling fixed widgets item width */
18076  item_width = layout->row.item_width;
18077  item_offset = (float)layout->row.index * item_width;
18078  item_spacing = (float)layout->row.index * spacing.x;
18079  } break;
18080  case NK_LAYOUT_STATIC_ROW: {
18081  /* scaling single ratio widget width */
18082  item_width = layout->row.item_width;
18083  item_offset = layout->row.item_offset;
18084  item_spacing = (float)layout->row.index * spacing.x;
18085  if (modify) layout->row.item_offset += item_width;
18086  } break;
18087  case NK_LAYOUT_STATIC_FREE: {
18088  /* free widget placing */
18089  bounds->x = layout->at_x + layout->row.item.x;
18090  bounds->w = layout->row.item.w;
18091  if (((bounds->x + bounds->w) > layout->max_x) && modify)
18092  layout->max_x = (bounds->x + bounds->w);
18093  bounds->x -= (float)*layout->offset_x;
18094  bounds->y = layout->at_y + layout->row.item.y;
18095  bounds->y -= (float)*layout->offset_y;
18096  bounds->h = layout->row.item.h;
18097  return;
18098  }
18099  case NK_LAYOUT_STATIC: {
18100  /* non-scaling array of panel pixel width for every widget */
18101  item_spacing = (float)layout->row.index * spacing.x;
18102  item_width = layout->row.ratio[layout->row.index];
18103  item_offset = layout->row.item_offset;
18104  if (modify) layout->row.item_offset += item_width;
18105  } break;
18106  case NK_LAYOUT_TEMPLATE: {
18107  /* stretchy row layout with combined dynamic/static widget width*/
18108  NK_ASSERT(layout->row.index < layout->row.columns);
18109  NK_ASSERT(layout->row.index < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
18110  item_width = layout->row.templates[layout->row.index];
18111  item_offset = layout->row.item_offset;
18112  item_spacing = (float)layout->row.index * spacing.x;
18113  if (modify) layout->row.item_offset += item_width;
18114  } break;
18115  default: NK_ASSERT(0); break;
18116  };
18117 
18118  /* set the bounds of the newly allocated widget */
18119  bounds->w = item_width;
18120  bounds->h = layout->row.height - spacing.y;
18121  bounds->y = layout->at_y - (float)*layout->offset_y;
18122  bounds->x = layout->at_x + item_offset + item_spacing + padding.x;
18123  if (((bounds->x + bounds->w) > layout->max_x) && modify)
18124  layout->max_x = bounds->x + bounds->w;
18125  bounds->x -= (float)*layout->offset_x;
18126 }
18127 NK_LIB void
18128 nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx)
18129 {
18130  struct nk_window *win;
18131  struct nk_panel *layout;
18132 
18133  NK_ASSERT(ctx);
18134  NK_ASSERT(ctx->current);
18135  NK_ASSERT(ctx->current->layout);
18136  if (!ctx || !ctx->current || !ctx->current->layout)
18137  return;
18138 
18139  /* check if the end of the row has been hit and begin new row if so */
18140  win = ctx->current;
18141  layout = win->layout;
18142  if (layout->row.index >= layout->row.columns)
18143  nk_panel_alloc_row(ctx, win);
18144 
18145  /* calculate widget position and size */
18146  nk_layout_widget_space(bounds, ctx, win, nk_true);
18147  layout->row.index++;
18148 }
18149 NK_LIB void
18150 nk_layout_peek(struct nk_rect *bounds, struct nk_context *ctx)
18151 {
18152  float y;
18153  int index;
18154  struct nk_window *win;
18155  struct nk_panel *layout;
18156 
18157  NK_ASSERT(ctx);
18158  NK_ASSERT(ctx->current);
18159  NK_ASSERT(ctx->current->layout);
18160  if (!ctx || !ctx->current || !ctx->current->layout)
18161  return;
18162 
18163  win = ctx->current;
18164  layout = win->layout;
18165  y = layout->at_y;
18166  index = layout->row.index;
18167  if (layout->row.index >= layout->row.columns) {
18168  layout->at_y += layout->row.height;
18169  layout->row.index = 0;
18170  }
18171  nk_layout_widget_space(bounds, ctx, win, nk_false);
18172  if (!layout->row.index) {
18173  bounds->x -= layout->row.item_offset;
18174  }
18175  layout->at_y = y;
18176  layout->row.index = index;
18177 }
18178 
18179 
18180 
18181 
18182 
18183 /* ===============================================================
18184  *
18185  * TREE
18186  *
18187  * ===============================================================*/
18188 NK_INTERN int
18189 nk_tree_state_base(struct nk_context *ctx, enum nk_tree_type type,
18190  struct nk_image *img, const char *title, enum nk_collapse_states *state)
18191 {
18192  struct nk_window *win;
18193  struct nk_panel *layout;
18194  const struct nk_style *style;
18195  struct nk_command_buffer *out;
18196  const struct nk_input *in;
18197  const struct nk_style_button *button;
18198  enum nk_symbol_type symbol;
18199  float row_height;
18200 
18201  struct nk_vec2 item_spacing;
18202  struct nk_rect header = {0,0,0,0};
18203  struct nk_rect sym = {0,0,0,0};
18204  struct nk_text text;
18205 
18206  nk_flags ws = 0;
18207  enum nk_widget_layout_states widget_state;
18208 
18209  NK_ASSERT(ctx);
18210  NK_ASSERT(ctx->current);
18211  NK_ASSERT(ctx->current->layout);
18212  if (!ctx || !ctx->current || !ctx->current->layout)
18213  return 0;
18214 
18215  /* cache some data */
18216  win = ctx->current;
18217  layout = win->layout;
18218  out = &win->buffer;
18219  style = &ctx->style;
18220  item_spacing = style->window.spacing;
18221 
18222  /* calculate header bounds and draw background */
18223  row_height = style->font->height + 2 * style->tab.padding.y;
18224  nk_layout_set_min_row_height(ctx, row_height);
18225  nk_layout_row_dynamic(ctx, row_height, 1);
18227 
18228  widget_state = nk_widget(&header, ctx);
18229  if (type == NK_TREE_TAB) {
18230  const struct nk_style_item *background = &style->tab.background;
18231  if (background->type == NK_STYLE_ITEM_IMAGE) {
18232  nk_draw_image(out, header, &background->data.image, nk_white);
18233  text.background = nk_rgba(0,0,0,0);
18234  } else {
18235  text.background = background->data.color;
18236  nk_fill_rect(out, header, 0, style->tab.border_color);
18237  nk_fill_rect(out, nk_shrink_rect(header, style->tab.border),
18238  style->tab.rounding, background->data.color);
18239  }
18240  } else text.background = style->window.background;
18241 
18242  /* update node state */
18243  in = (!(layout->flags & NK_WINDOW_ROM)) ? &ctx->input: 0;
18244  in = (in && widget_state == NK_WIDGET_VALID) ? &ctx->input : 0;
18245  if (nk_button_behavior(&ws, header, in, NK_BUTTON_DEFAULT))
18246  *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED;
18247 
18248  /* select correct button style */
18249  if (*state == NK_MAXIMIZED) {
18250  symbol = style->tab.sym_maximize;
18251  if (type == NK_TREE_TAB)
18252  button = &style->tab.tab_maximize_button;
18253  else button = &style->tab.node_maximize_button;
18254  } else {
18255  symbol = style->tab.sym_minimize;
18256  if (type == NK_TREE_TAB)
18257  button = &style->tab.tab_minimize_button;
18258  else button = &style->tab.node_minimize_button;
18259  }
18260 
18261  {/* draw triangle button */
18262  sym.w = sym.h = style->font->height;
18263  sym.y = header.y + style->tab.padding.y;
18264  sym.x = header.x + style->tab.padding.x;
18265  nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT,
18266  button, 0, style->font);
18267 
18268  if (img) {
18269  /* draw optional image icon */
18270  sym.x = sym.x + sym.w + 4 * item_spacing.x;
18271  nk_draw_image(&win->buffer, sym, img, nk_white);
18272  sym.w = style->font->height + style->tab.spacing.x;}
18273  }
18274 
18275  {/* draw label */
18276  struct nk_rect label;
18277  header.w = NK_MAX(header.w, sym.w + item_spacing.x);
18278  label.x = sym.x + sym.w + item_spacing.x;
18279  label.y = sym.y;
18280  label.w = header.w - (sym.w + item_spacing.y + style->tab.indent);
18281  label.h = style->font->height;
18282  text.text = style->tab.text;
18283  text.padding = nk_vec2(0,0);
18284  nk_widget_text(out, label, title, nk_strlen(title), &text,
18285  NK_TEXT_LEFT, style->font);}
18286 
18287  /* increase x-axis cursor widget position pointer */
18288  if (*state == NK_MAXIMIZED) {
18289  layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent;
18290  layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent);
18291  layout->bounds.w -= (style->tab.indent + style->window.padding.x);
18292  layout->row.tree_depth++;
18293  return nk_true;
18294  } else return nk_false;
18295 }
18296 NK_INTERN int
18297 nk_tree_base(struct nk_context *ctx, enum nk_tree_type type,
18298  struct nk_image *img, const char *title, enum nk_collapse_states initial_state,
18299  const char *hash, int len, int line)
18300 {
18301  struct nk_window *win = ctx->current;
18302  int title_len = 0;
18303  nk_hash tree_hash = 0;
18304  nk_uint *state = 0;
18305 
18306  /* retrieve tree state from internal widget state tables */
18307  if (!hash) {
18308  title_len = (int)nk_strlen(title);
18309  tree_hash = nk_murmur_hash(title, (int)title_len, (nk_hash)line);
18310  } else tree_hash = nk_murmur_hash(hash, len, (nk_hash)line);
18311  state = nk_find_value(win, tree_hash);
18312  if (!state) {
18313  state = nk_add_value(ctx, win, tree_hash, 0);
18314  *state = initial_state;
18315  }
18316  return nk_tree_state_base(ctx, type, img, title, (enum nk_collapse_states*)state);
18317 }
18318 NK_API int
18319 nk_tree_state_push(struct nk_context *ctx, enum nk_tree_type type,
18320  const char *title, enum nk_collapse_states *state)
18321 {
18322  return nk_tree_state_base(ctx, type, 0, title, state);
18323 }
18324 NK_API int
18325 nk_tree_state_image_push(struct nk_context *ctx, enum nk_tree_type type,
18326  struct nk_image img, const char *title, enum nk_collapse_states *state)
18327 {
18328  return nk_tree_state_base(ctx, type, &img, title, state);
18329 }
18330 NK_API void
18331 nk_tree_state_pop(struct nk_context *ctx)
18332 {
18333  struct nk_window *win = 0;
18334  struct nk_panel *layout = 0;
18335 
18336  NK_ASSERT(ctx);
18337  NK_ASSERT(ctx->current);
18338  NK_ASSERT(ctx->current->layout);
18339  if (!ctx || !ctx->current || !ctx->current->layout)
18340  return;
18341 
18342  win = ctx->current;
18343  layout = win->layout;
18344  layout->at_x -= ctx->style.tab.indent + ctx->style.window.padding.x;
18345  layout->bounds.w += ctx->style.tab.indent + ctx->style.window.padding.x;
18346  NK_ASSERT(layout->row.tree_depth);
18347  layout->row.tree_depth--;
18348 }
18349 NK_API int
18350 nk_tree_push_hashed(struct nk_context *ctx, enum nk_tree_type type,
18351  const char *title, enum nk_collapse_states initial_state,
18352  const char *hash, int len, int line)
18353 {
18354  return nk_tree_base(ctx, type, 0, title, initial_state, hash, len, line);
18355 }
18356 NK_API int
18357 nk_tree_image_push_hashed(struct nk_context *ctx, enum nk_tree_type type,
18358  struct nk_image img, const char *title, enum nk_collapse_states initial_state,
18359  const char *hash, int len,int seed)
18360 {
18361  return nk_tree_base(ctx, type, &img, title, initial_state, hash, len, seed);
18362 }
18363 NK_API void
18364 nk_tree_pop(struct nk_context *ctx)
18365 {
18366  nk_tree_state_pop(ctx);
18367 }
18368 NK_INTERN int
18369 nk_tree_element_image_push_hashed_base(struct nk_context *ctx, enum nk_tree_type type,
18370  struct nk_image *img, const char *title, int title_len,
18371  enum nk_collapse_states *state, int *selected)
18372 {
18373  struct nk_window *win;
18374  struct nk_panel *layout;
18375  const struct nk_style *style;
18376  struct nk_command_buffer *out;
18377  const struct nk_input *in;
18378  const struct nk_style_button *button;
18379  enum nk_symbol_type symbol;
18380  float row_height;
18381  struct nk_vec2 padding;
18382 
18383  int text_len;
18384  float text_width;
18385 
18386  struct nk_vec2 item_spacing;
18387  struct nk_rect header = {0,0,0,0};
18388  struct nk_rect sym = {0,0,0,0};
18389  struct nk_text text;
18390 
18391  nk_flags ws = 0;
18392  enum nk_widget_layout_states widget_state;
18393 
18394  NK_ASSERT(ctx);
18395  NK_ASSERT(ctx->current);
18396  NK_ASSERT(ctx->current->layout);
18397  if (!ctx || !ctx->current || !ctx->current->layout)
18398  return 0;
18399 
18400  /* cache some data */
18401  win = ctx->current;
18402  layout = win->layout;
18403  out = &win->buffer;
18404  style = &ctx->style;
18405  item_spacing = style->window.spacing;
18406  padding = style->selectable.padding;
18407 
18408  /* calculate header bounds and draw background */
18409  row_height = style->font->height + 2 * style->tab.padding.y;
18410  nk_layout_set_min_row_height(ctx, row_height);
18411  nk_layout_row_dynamic(ctx, row_height, 1);
18413 
18414  widget_state = nk_widget(&header, ctx);
18415  if (type == NK_TREE_TAB) {
18416  const struct nk_style_item *background = &style->tab.background;
18417  if (background->type == NK_STYLE_ITEM_IMAGE) {
18418  nk_draw_image(out, header, &background->data.image, nk_white);
18419  text.background = nk_rgba(0,0,0,0);
18420  } else {
18421  text.background = background->data.color;
18422  nk_fill_rect(out, header, 0, style->tab.border_color);
18423  nk_fill_rect(out, nk_shrink_rect(header, style->tab.border),
18424  style->tab.rounding, background->data.color);
18425  }
18426  } else text.background = style->window.background;
18427 
18428  in = (!(layout->flags & NK_WINDOW_ROM)) ? &ctx->input: 0;
18429  in = (in && widget_state == NK_WIDGET_VALID) ? &ctx->input : 0;
18430 
18431  /* select correct button style */
18432  if (*state == NK_MAXIMIZED) {
18433  symbol = style->tab.sym_maximize;
18434  if (type == NK_TREE_TAB)
18435  button = &style->tab.tab_maximize_button;
18436  else button = &style->tab.node_maximize_button;
18437  } else {
18438  symbol = style->tab.sym_minimize;
18439  if (type == NK_TREE_TAB)
18440  button = &style->tab.tab_minimize_button;
18441  else button = &style->tab.node_minimize_button;
18442  }
18443  {/* draw triangle button */
18444  sym.w = sym.h = style->font->height;
18445  sym.y = header.y + style->tab.padding.y;
18446  sym.x = header.x + style->tab.padding.x;
18447  if (nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT, button, in, style->font))
18448  *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED;}
18449 
18450  /* draw label */
18451  {nk_flags dummy = 0;
18452  struct nk_rect label;
18453  /* calculate size of the text and tooltip */
18454  text_len = nk_strlen(title);
18455  text_width = style->font->width(style->font->userdata, style->font->height, title, text_len);
18456  text_width += (4 * padding.x);
18457 
18458  header.w = NK_MAX(header.w, sym.w + item_spacing.x);
18459  label.x = sym.x + sym.w + item_spacing.x;
18460  label.y = sym.y;
18461  label.w = NK_MIN(header.w - (sym.w + item_spacing.y + style->tab.indent), text_width);
18462  label.h = style->font->height;
18463 
18464  if (img) {
18465  nk_do_selectable_image(&dummy, &win->buffer, label, title, title_len, NK_TEXT_LEFT,
18466  selected, img, &style->selectable, in, style->font);
18467  } else nk_do_selectable(&dummy, &win->buffer, label, title, title_len, NK_TEXT_LEFT,
18468  selected, &style->selectable, in, style->font);
18469  }
18470  /* increase x-axis cursor widget position pointer */
18471  if (*state == NK_MAXIMIZED) {
18472  layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent;
18473  layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent);
18474  layout->bounds.w -= (style->tab.indent + style->window.padding.x);
18475  layout->row.tree_depth++;
18476  return nk_true;
18477  } else return nk_false;
18478 }
18479 NK_INTERN int
18480 nk_tree_element_base(struct nk_context *ctx, enum nk_tree_type type,
18481  struct nk_image *img, const char *title, enum nk_collapse_states initial_state,
18482  int *selected, const char *hash, int len, int line)
18483 {
18484  struct nk_window *win = ctx->current;
18485  int title_len = 0;
18486  nk_hash tree_hash = 0;
18487  nk_uint *state = 0;
18488 
18489  /* retrieve tree state from internal widget state tables */
18490  if (!hash) {
18491  title_len = (int)nk_strlen(title);
18492  tree_hash = nk_murmur_hash(title, (int)title_len, (nk_hash)line);
18493  } else tree_hash = nk_murmur_hash(hash, len, (nk_hash)line);
18494  state = nk_find_value(win, tree_hash);
18495  if (!state) {
18496  state = nk_add_value(ctx, win, tree_hash, 0);
18497  *state = initial_state;
18498  } return nk_tree_element_image_push_hashed_base(ctx, type, img, title,
18499  nk_strlen(title), (enum nk_collapse_states*)state, selected);
18500 }
18501 NK_API int
18502 nk_tree_element_push_hashed(struct nk_context *ctx, enum nk_tree_type type,
18503  const char *title, enum nk_collapse_states initial_state,
18504  int *selected, const char *hash, int len, int seed)
18505 {
18506  return nk_tree_element_base(ctx, type, 0, title, initial_state, selected, hash, len, seed);
18507 }
18508 NK_API int
18509 nk_tree_element_image_push_hashed(struct nk_context *ctx, enum nk_tree_type type,
18510  struct nk_image img, const char *title, enum nk_collapse_states initial_state,
18511  int *selected, const char *hash, int len,int seed)
18512 {
18513  return nk_tree_element_base(ctx, type, &img, title, initial_state, selected, hash, len, seed);
18514 }
18515 NK_API void
18516 nk_tree_element_pop(struct nk_context *ctx)
18517 {
18518  nk_tree_state_pop(ctx);
18519 }
18520 
18521 
18522 
18523 
18524 
18525 /* ===============================================================
18526  *
18527  * GROUP
18528  *
18529  * ===============================================================*/
18530 NK_API int
18531 nk_group_scrolled_offset_begin(struct nk_context *ctx,
18532  nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags)
18533 {
18534  struct nk_rect bounds;
18535  struct nk_window panel;
18536  struct nk_window *win;
18537 
18538  win = ctx->current;
18539  nk_panel_alloc_space(&bounds, ctx);
18540  {const struct nk_rect *c = &win->layout->clip;
18541  if (!NK_INTERSECT(c->x, c->y, c->w, c->h, bounds.x, bounds.y, bounds.w, bounds.h) &&
18542  !(flags & NK_WINDOW_MOVABLE)) {
18543  return 0;
18544  }}
18545  if (win->flags & NK_WINDOW_ROM)
18546  flags |= NK_WINDOW_ROM;
18547 
18548  /* initialize a fake window to create the panel from */
18549  nk_zero(&panel, sizeof(panel));
18550  panel.bounds = bounds;
18551  panel.flags = flags;
18552  panel.scrollbar.x = *x_offset;
18553  panel.scrollbar.y = *y_offset;
18554  panel.buffer = win->buffer;
18555  panel.layout = (struct nk_panel*)nk_create_panel(ctx);
18556  ctx->current = &panel;
18557  nk_panel_begin(ctx, (flags & NK_WINDOW_TITLE) ? title: 0, NK_PANEL_GROUP);
18558 
18559  win->buffer = panel.buffer;
18560  win->buffer.clip = panel.layout->clip;
18561  panel.layout->offset_x = x_offset;
18562  panel.layout->offset_y = y_offset;
18563  panel.layout->parent = win->layout;
18564  win->layout = panel.layout;
18565 
18566  ctx->current = win;
18567  if ((panel.layout->flags & NK_WINDOW_CLOSED) ||
18568  (panel.layout->flags & NK_WINDOW_MINIMIZED))
18569  {
18570  nk_flags f = panel.layout->flags;
18571  nk_group_scrolled_end(ctx);
18572  if (f & NK_WINDOW_CLOSED)
18573  return NK_WINDOW_CLOSED;
18574  if (f & NK_WINDOW_MINIMIZED)
18575  return NK_WINDOW_MINIMIZED;
18576  }
18577  return 1;
18578 }
18579 NK_API void
18580 nk_group_scrolled_end(struct nk_context *ctx)
18581 {
18582  struct nk_window *win;
18583  struct nk_panel *parent;
18584  struct nk_panel *g;
18585 
18586  struct nk_rect clip;
18587  struct nk_window pan;
18588  struct nk_vec2 panel_padding;
18589 
18590  NK_ASSERT(ctx);
18591  NK_ASSERT(ctx->current);
18592  if (!ctx || !ctx->current)
18593  return;
18594 
18595  /* make sure nk_group_begin was called correctly */
18596  NK_ASSERT(ctx->current);
18597  win = ctx->current;
18598  NK_ASSERT(win->layout);
18599  g = win->layout;
18600  NK_ASSERT(g->parent);
18601  parent = g->parent;
18602 
18603  /* dummy window */
18604  nk_zero_struct(pan);
18605  panel_padding = nk_panel_get_padding(&ctx->style, NK_PANEL_GROUP);
18606  pan.bounds.y = g->bounds.y - (g->header_height + g->menu.h);
18607  pan.bounds.x = g->bounds.x - panel_padding.x;
18608  pan.bounds.w = g->bounds.w + 2 * panel_padding.x;
18609  pan.bounds.h = g->bounds.h + g->header_height + g->menu.h;
18610  if (g->flags & NK_WINDOW_BORDER) {
18611  pan.bounds.x -= g->border;
18612  pan.bounds.y -= g->border;
18613  pan.bounds.w += 2*g->border;
18614  pan.bounds.h += 2*g->border;
18615  }
18616  if (!(g->flags & NK_WINDOW_NO_SCROLLBAR)) {
18617  pan.bounds.w += ctx->style.window.scrollbar_size.x;
18618  pan.bounds.h += ctx->style.window.scrollbar_size.y;
18619  }
18620  pan.scrollbar.x = *g->offset_x;
18621  pan.scrollbar.y = *g->offset_y;
18622  pan.flags = g->flags;
18623  pan.buffer = win->buffer;
18624  pan.layout = g;
18625  pan.parent = win;
18626  ctx->current = &pan;
18627 
18628  /* make sure group has correct clipping rectangle */
18629  nk_unify(&clip, &parent->clip, pan.bounds.x, pan.bounds.y,
18630  pan.bounds.x + pan.bounds.w, pan.bounds.y + pan.bounds.h + panel_padding.x);
18631  nk_push_scissor(&pan.buffer, clip);
18632  nk_end(ctx);
18633 
18634  win->buffer = pan.buffer;
18635  nk_push_scissor(&win->buffer, parent->clip);
18636  ctx->current = win;
18637  win->layout = parent;
18638  g->bounds = pan.bounds;
18639  return;
18640 }
18641 NK_API int
18642 nk_group_scrolled_begin(struct nk_context *ctx,
18643  struct nk_scroll *scroll, const char *title, nk_flags flags)
18644 {
18645  return nk_group_scrolled_offset_begin(ctx, &scroll->x, &scroll->y, title, flags);
18646 }
18647 NK_API int
18648 nk_group_begin_titled(struct nk_context *ctx, const char *id,
18649  const char *title, nk_flags flags)
18650 {
18651  int id_len;
18652  nk_hash id_hash;
18653  struct nk_window *win;
18654  nk_uint *x_offset;
18655  nk_uint *y_offset;
18656 
18657  NK_ASSERT(ctx);
18658  NK_ASSERT(id);
18659  NK_ASSERT(ctx->current);
18660  NK_ASSERT(ctx->current->layout);
18661  if (!ctx || !ctx->current || !ctx->current->layout || !id)
18662  return 0;
18663 
18664  /* find persistent group scrollbar value */
18665  win = ctx->current;
18666  id_len = (int)nk_strlen(id);
18667  id_hash = nk_murmur_hash(id, (int)id_len, NK_PANEL_GROUP);
18668  x_offset = nk_find_value(win, id_hash);
18669  if (!x_offset) {
18670  x_offset = nk_add_value(ctx, win, id_hash, 0);
18671  y_offset = nk_add_value(ctx, win, id_hash+1, 0);
18672 
18673  NK_ASSERT(x_offset);
18674  NK_ASSERT(y_offset);
18675  if (!x_offset || !y_offset) return 0;
18676  *x_offset = *y_offset = 0;
18677  } else y_offset = nk_find_value(win, id_hash+1);
18678  return nk_group_scrolled_offset_begin(ctx, x_offset, y_offset, title, flags);
18679 }
18680 NK_API int
18681 nk_group_begin(struct nk_context *ctx, const char *title, nk_flags flags)
18682 {
18683  return nk_group_begin_titled(ctx, title, title, flags);
18684 }
18685 NK_API void
18686 nk_group_end(struct nk_context *ctx)
18687 {
18688  nk_group_scrolled_end(ctx);
18689 }
18690 
18691 
18692 
18693 
18694 
18695 /* ===============================================================
18696  *
18697  * LIST VIEW
18698  *
18699  * ===============================================================*/
18700 NK_API int
18701 nk_list_view_begin(struct nk_context *ctx, struct nk_list_view *view,
18702  const char *title, nk_flags flags, int row_height, int row_count)
18703 {
18704  int title_len;
18705  nk_hash title_hash;
18706  nk_uint *x_offset;
18707  nk_uint *y_offset;
18708 
18709  int result;
18710  struct nk_window *win;
18711  struct nk_panel *layout;
18712  const struct nk_style *style;
18713  struct nk_vec2 item_spacing;
18714 
18715  NK_ASSERT(ctx);
18716  NK_ASSERT(view);
18717  NK_ASSERT(title);
18718  if (!ctx || !view || !title) return 0;
18719 
18720  win = ctx->current;
18721  style = &ctx->style;
18722  item_spacing = style->window.spacing;
18723  row_height += NK_MAX(0, (int)item_spacing.y);
18724 
18725  /* find persistent list view scrollbar offset */
18726  title_len = (int)nk_strlen(title);
18727  title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_GROUP);
18728  x_offset = nk_find_value(win, title_hash);
18729  if (!x_offset) {
18730  x_offset = nk_add_value(ctx, win, title_hash, 0);
18731  y_offset = nk_add_value(ctx, win, title_hash+1, 0);
18732 
18733  NK_ASSERT(x_offset);
18734  NK_ASSERT(y_offset);
18735  if (!x_offset || !y_offset) return 0;
18736  *x_offset = *y_offset = 0;
18737  } else y_offset = nk_find_value(win, title_hash+1);
18738  view->scroll_value = *y_offset;
18739  view->scroll_pointer = y_offset;
18740 
18741  *y_offset = 0;
18742  result = nk_group_scrolled_offset_begin(ctx, x_offset, y_offset, title, flags);
18743  win = ctx->current;
18744  layout = win->layout;
18745 
18746  view->total_height = row_height * NK_MAX(row_count,1);
18747  view->begin = (int)NK_MAX(((float)view->scroll_value / (float)row_height), 0.0f);
18748  view->count = (int)NK_MAX(nk_iceilf((layout->clip.h)/(float)row_height),0);
18749  view->count = NK_MIN(view->count, row_count - view->begin);
18750  view->end = view->begin + view->count;
18751  view->ctx = ctx;
18752  return result;
18753 }
18754 NK_API void
18755 nk_list_view_end(struct nk_list_view *view)
18756 {
18757  struct nk_context *ctx;
18758  struct nk_window *win;
18759  struct nk_panel *layout;
18760 
18761  NK_ASSERT(view);
18762  NK_ASSERT(view->ctx);
18763  NK_ASSERT(view->scroll_pointer);
18764  if (!view || !view->ctx) return;
18765 
18766  ctx = view->ctx;
18767  win = ctx->current;
18768  layout = win->layout;
18769  layout->at_y = layout->bounds.y + (float)view->total_height;
18770  *view->scroll_pointer = *view->scroll_pointer + view->scroll_value;
18771  nk_group_end(view->ctx);
18772 }
18773 
18774 
18775 
18776 
18777 
18778 /* ===============================================================
18779  *
18780  * WIDGET
18781  *
18782  * ===============================================================*/
18783 NK_API struct nk_rect
18784 nk_widget_bounds(struct nk_context *ctx)
18785 {
18786  struct nk_rect bounds;
18787  NK_ASSERT(ctx);
18788  NK_ASSERT(ctx->current);
18789  if (!ctx || !ctx->current)
18790  return nk_rect(0,0,0,0);
18791  nk_layout_peek(&bounds, ctx);
18792  return bounds;
18793 }
18794 NK_API struct nk_vec2
18795 nk_widget_position(struct nk_context *ctx)
18796 {
18797  struct nk_rect bounds;
18798  NK_ASSERT(ctx);
18799  NK_ASSERT(ctx->current);
18800  if (!ctx || !ctx->current)
18801  return nk_vec2(0,0);
18802 
18803  nk_layout_peek(&bounds, ctx);
18804  return nk_vec2(bounds.x, bounds.y);
18805 }
18806 NK_API struct nk_vec2
18807 nk_widget_size(struct nk_context *ctx)
18808 {
18809  struct nk_rect bounds;
18810  NK_ASSERT(ctx);
18811  NK_ASSERT(ctx->current);
18812  if (!ctx || !ctx->current)
18813  return nk_vec2(0,0);
18814 
18815  nk_layout_peek(&bounds, ctx);
18816  return nk_vec2(bounds.w, bounds.h);
18817 }
18818 NK_API float
18819 nk_widget_width(struct nk_context *ctx)
18820 {
18821  struct nk_rect bounds;
18822  NK_ASSERT(ctx);
18823  NK_ASSERT(ctx->current);
18824  if (!ctx || !ctx->current)
18825  return 0;
18826 
18827  nk_layout_peek(&bounds, ctx);
18828  return bounds.w;
18829 }
18830 NK_API float
18831 nk_widget_height(struct nk_context *ctx)
18832 {
18833  struct nk_rect bounds;
18834  NK_ASSERT(ctx);
18835  NK_ASSERT(ctx->current);
18836  if (!ctx || !ctx->current)
18837  return 0;
18838 
18839  nk_layout_peek(&bounds, ctx);
18840  return bounds.h;
18841 }
18842 NK_API int
18843 nk_widget_is_hovered(struct nk_context *ctx)
18844 {
18845  struct nk_rect c, v;
18846  struct nk_rect bounds;
18847  NK_ASSERT(ctx);
18848  NK_ASSERT(ctx->current);
18849  if (!ctx || !ctx->current || ctx->active != ctx->current)
18850  return 0;
18851 
18852  c = ctx->current->layout->clip;
18853  c.x = (float)((int)c.x);
18854  c.y = (float)((int)c.y);
18855  c.w = (float)((int)c.w);
18856  c.h = (float)((int)c.h);
18857 
18858  nk_layout_peek(&bounds, ctx);
18859  nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
18860  if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
18861  return 0;
18862  return nk_input_is_mouse_hovering_rect(&ctx->input, bounds);
18863 }
18864 NK_API int
18865 nk_widget_is_mouse_clicked(struct nk_context *ctx, enum nk_buttons btn)
18866 {
18867  struct nk_rect c, v;
18868  struct nk_rect bounds;
18869  NK_ASSERT(ctx);
18870  NK_ASSERT(ctx->current);
18871  if (!ctx || !ctx->current || ctx->active != ctx->current)
18872  return 0;
18873 
18874  c = ctx->current->layout->clip;
18875  c.x = (float)((int)c.x);
18876  c.y = (float)((int)c.y);
18877  c.w = (float)((int)c.w);
18878  c.h = (float)((int)c.h);
18879 
18880  nk_layout_peek(&bounds, ctx);
18881  nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
18882  if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
18883  return 0;
18884  return nk_input_mouse_clicked(&ctx->input, btn, bounds);
18885 }
18886 NK_API int
18887 nk_widget_has_mouse_click_down(struct nk_context *ctx, enum nk_buttons btn, int down)
18888 {
18889  struct nk_rect c, v;
18890  struct nk_rect bounds;
18891  NK_ASSERT(ctx);
18892  NK_ASSERT(ctx->current);
18893  if (!ctx || !ctx->current || ctx->active != ctx->current)
18894  return 0;
18895 
18896  c = ctx->current->layout->clip;
18897  c.x = (float)((int)c.x);
18898  c.y = (float)((int)c.y);
18899  c.w = (float)((int)c.w);
18900  c.h = (float)((int)c.h);
18901 
18902  nk_layout_peek(&bounds, ctx);
18903  nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
18904  if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
18905  return 0;
18906  return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down);
18907 }
18909 nk_widget(struct nk_rect *bounds, const struct nk_context *ctx)
18910 {
18911  struct nk_rect c, v;
18912  struct nk_window *win;
18913  struct nk_panel *layout;
18914  const struct nk_input *in;
18915 
18916  NK_ASSERT(ctx);
18917  NK_ASSERT(ctx->current);
18918  NK_ASSERT(ctx->current->layout);
18919  if (!ctx || !ctx->current || !ctx->current->layout)
18920  return NK_WIDGET_INVALID;
18921 
18922  /* allocate space and check if the widget needs to be updated and drawn */
18923  nk_panel_alloc_space(bounds, ctx);
18924  win = ctx->current;
18925  layout = win->layout;
18926  in = &ctx->input;
18927  c = layout->clip;
18928 
18929  /* if one of these triggers you forgot to add an `if` condition around either
18930  a window, group, popup, combobox or contextual menu `begin` and `end` block.
18931  Example:
18932  if (nk_begin(...) {...} nk_end(...); or
18933  if (nk_group_begin(...) { nk_group_end(...);} */
18934  NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED));
18935  NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN));
18936  NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED));
18937 
18938  /* need to convert to int here to remove floating point errors */
18939  bounds->x = (float)((int)bounds->x);
18940  bounds->y = (float)((int)bounds->y);
18941  bounds->w = (float)((int)bounds->w);
18942  bounds->h = (float)((int)bounds->h);
18943 
18944  c.x = (float)((int)c.x);
18945  c.y = (float)((int)c.y);
18946  c.w = (float)((int)c.w);
18947  c.h = (float)((int)c.h);
18948 
18949  nk_unify(&v, &c, bounds->x, bounds->y, bounds->x + bounds->w, bounds->y + bounds->h);
18950  if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds->x, bounds->y, bounds->w, bounds->h))
18951  return NK_WIDGET_INVALID;
18952  if (!NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, v.x, v.y, v.w, v.h))
18953  return NK_WIDGET_ROM;
18954  return NK_WIDGET_VALID;
18955 }
18957 nk_widget_fitting(struct nk_rect *bounds, struct nk_context *ctx,
18958  struct nk_vec2 item_padding)
18959 {
18960  /* update the bounds to stand without padding */
18961  struct nk_window *win;
18962  struct nk_style *style;
18963  struct nk_panel *layout;
18965  struct nk_vec2 panel_padding;
18966 
18967  NK_ASSERT(ctx);
18968  NK_ASSERT(ctx->current);
18969  NK_ASSERT(ctx->current->layout);
18970  if (!ctx || !ctx->current || !ctx->current->layout)
18971  return NK_WIDGET_INVALID;
18972 
18973  win = ctx->current;
18974  style = &ctx->style;
18975  layout = win->layout;
18976  state = nk_widget(bounds, ctx);
18977 
18978  panel_padding = nk_panel_get_padding(style, layout->type);
18979  if (layout->row.index == 1) {
18980  bounds->w += panel_padding.x;
18981  bounds->x -= panel_padding.x;
18982  } else bounds->x -= item_padding.x;
18983 
18984  if (layout->row.index == layout->row.columns)
18985  bounds->w += panel_padding.x;
18986  else bounds->w += item_padding.x;
18987  return state;
18988 }
18989 NK_API void
18990 nk_spacing(struct nk_context *ctx, int cols)
18991 {
18992  struct nk_window *win;
18993  struct nk_panel *layout;
18994  struct nk_rect none;
18995  int i, index, rows;
18996 
18997  NK_ASSERT(ctx);
18998  NK_ASSERT(ctx->current);
18999  NK_ASSERT(ctx->current->layout);
19000  if (!ctx || !ctx->current || !ctx->current->layout)
19001  return;
19002 
19003  /* spacing over row boundaries */
19004  win = ctx->current;
19005  layout = win->layout;
19006  index = (layout->row.index + cols) % layout->row.columns;
19007  rows = (layout->row.index + cols) / layout->row.columns;
19008  if (rows) {
19009  for (i = 0; i < rows; ++i)
19010  nk_panel_alloc_row(ctx, win);
19011  cols = index;
19012  }
19013  /* non table layout need to allocate space */
19014  if (layout->row.type != NK_LAYOUT_DYNAMIC_FIXED &&
19015  layout->row.type != NK_LAYOUT_STATIC_FIXED) {
19016  for (i = 0; i < cols; ++i)
19017  nk_panel_alloc_space(&none, ctx);
19018  } layout->row.index = index;
19019 }
19020 
19021 
19022 
19023 
19024 
19025 /* ===============================================================
19026  *
19027  * TEXT
19028  *
19029  * ===============================================================*/
19030 NK_LIB void
19031 nk_widget_text(struct nk_command_buffer *o, struct nk_rect b,
19032  const char *string, int len, const struct nk_text *t,
19033  nk_flags a, const struct nk_user_font *f)
19034 {
19035  struct nk_rect label;
19036  float text_width;
19037 
19038  NK_ASSERT(o);
19039  NK_ASSERT(t);
19040  if (!o || !t) return;
19041 
19042  b.h = NK_MAX(b.h, 2 * t->padding.y);
19043  label.x = 0; label.w = 0;
19044  label.y = b.y + t->padding.y;
19045  label.h = NK_MIN(f->height, b.h - 2 * t->padding.y);
19046 
19047  text_width = f->width(f->userdata, f->height, (const char*)string, len);
19048  text_width += (2.0f * t->padding.x);
19049 
19050  /* align in x-axis */
19051  if (a & NK_TEXT_ALIGN_LEFT) {
19052  label.x = b.x + t->padding.x;
19053  label.w = NK_MAX(0, b.w - 2 * t->padding.x);
19054  } else if (a & NK_TEXT_ALIGN_CENTERED) {
19055  label.w = NK_MAX(1, 2 * t->padding.x + (float)text_width);
19056  label.x = (b.x + t->padding.x + ((b.w - 2 * t->padding.x) - label.w) / 2);
19057  label.x = NK_MAX(b.x + t->padding.x, label.x);
19058  label.w = NK_MIN(b.x + b.w, label.x + label.w);
19059  if (label.w >= label.x) label.w -= label.x;
19060  } else if (a & NK_TEXT_ALIGN_RIGHT) {
19061  label.x = NK_MAX(b.x + t->padding.x, (b.x + b.w) - (2 * t->padding.x + (float)text_width));
19062  label.w = (float)text_width + 2 * t->padding.x;
19063  } else return;
19064 
19065  /* align in y-axis */
19066  if (a & NK_TEXT_ALIGN_MIDDLE) {
19067  label.y = b.y + b.h/2.0f - (float)f->height/2.0f;
19068  label.h = NK_MAX(b.h/2.0f, b.h - (b.h/2.0f + f->height/2.0f));
19069  } else if (a & NK_TEXT_ALIGN_BOTTOM) {
19070  label.y = b.y + b.h - f->height;
19071  label.h = f->height;
19072  }
19073  nk_draw_text(o, label, (const char*)string, len, f, t->background, t->text);
19074 }
19075 NK_LIB void
19076 nk_widget_text_wrap(struct nk_command_buffer *o, struct nk_rect b,
19077  const char *string, int len, const struct nk_text *t,
19078  const struct nk_user_font *f)
19079 {
19080  float width;
19081  int glyphs = 0;
19082  int fitting = 0;
19083  int done = 0;
19084  struct nk_rect line;
19085  struct nk_text text;
19086  NK_INTERN nk_rune seperator[] = {' '};
19087 
19088  NK_ASSERT(o);
19089  NK_ASSERT(t);
19090  if (!o || !t) return;
19091 
19092  text.padding = nk_vec2(0,0);
19093  text.background = t->background;
19094  text.text = t->text;
19095 
19096  b.w = NK_MAX(b.w, 2 * t->padding.x);
19097  b.h = NK_MAX(b.h, 2 * t->padding.y);
19098  b.h = b.h - 2 * t->padding.y;
19099 
19100  line.x = b.x + t->padding.x;
19101  line.y = b.y + t->padding.y;
19102  line.w = b.w - 2 * t->padding.x;
19103  line.h = 2 * t->padding.y + f->height;
19104 
19105  fitting = nk_text_clamp(f, string, len, line.w, &glyphs, &width, seperator,NK_LEN(seperator));
19106  while (done < len) {
19107  if (!fitting || line.y + line.h >= (b.y + b.h)) break;
19108  nk_widget_text(o, line, &string[done], fitting, &text, NK_TEXT_LEFT, f);
19109  done += fitting;
19110  line.y += f->height + 2 * t->padding.y;
19111  fitting = nk_text_clamp(f, &string[done], len - done, line.w, &glyphs, &width, seperator,NK_LEN(seperator));
19112  }
19113 }
19114 NK_API void
19115 nk_text_colored(struct nk_context *ctx, const char *str, int len,
19116  nk_flags alignment, struct nk_color color)
19117 {
19118  struct nk_window *win;
19119  const struct nk_style *style;
19120 
19121  struct nk_vec2 item_padding;
19122  struct nk_rect bounds;
19123  struct nk_text text;
19124 
19125  NK_ASSERT(ctx);
19126  NK_ASSERT(ctx->current);
19127  NK_ASSERT(ctx->current->layout);
19128  if (!ctx || !ctx->current || !ctx->current->layout) return;
19129 
19130  win = ctx->current;
19131  style = &ctx->style;
19132  nk_panel_alloc_space(&bounds, ctx);
19133  item_padding = style->text.padding;
19134 
19135  text.padding.x = item_padding.x;
19136  text.padding.y = item_padding.y;
19137  text.background = style->window.background;
19138  text.text = color;
19139  nk_widget_text(&win->buffer, bounds, str, len, &text, alignment, style->font);
19140 }
19141 NK_API void
19142 nk_text_wrap_colored(struct nk_context *ctx, const char *str,
19143  int len, struct nk_color color)
19144 {
19145  struct nk_window *win;
19146  const struct nk_style *style;
19147 
19148  struct nk_vec2 item_padding;
19149  struct nk_rect bounds;
19150  struct nk_text text;
19151 
19152  NK_ASSERT(ctx);
19153  NK_ASSERT(ctx->current);
19154  NK_ASSERT(ctx->current->layout);
19155  if (!ctx || !ctx->current || !ctx->current->layout) return;
19156 
19157  win = ctx->current;
19158  style = &ctx->style;
19159  nk_panel_alloc_space(&bounds, ctx);
19160  item_padding = style->text.padding;
19161 
19162  text.padding.x = item_padding.x;
19163  text.padding.y = item_padding.y;
19164  text.background = style->window.background;
19165  text.text = color;
19166  nk_widget_text_wrap(&win->buffer, bounds, str, len, &text, style->font);
19167 }
19168 #ifdef NK_INCLUDE_STANDARD_VARARGS
19169 NK_API void
19170 nk_labelf_colored(struct nk_context *ctx, nk_flags flags,
19171  struct nk_color color, const char *fmt, ...)
19172 {
19173  va_list args;
19174  va_start(args, fmt);
19175  nk_labelfv_colored(ctx, flags, color, fmt, args);
19176  va_end(args);
19177 }
19178 NK_API void
19179 nk_labelf_colored_wrap(struct nk_context *ctx, struct nk_color color,
19180  const char *fmt, ...)
19181 {
19182  va_list args;
19183  va_start(args, fmt);
19184  nk_labelfv_colored_wrap(ctx, color, fmt, args);
19185  va_end(args);
19186 }
19187 NK_API void
19188 nk_labelf(struct nk_context *ctx, nk_flags flags, const char *fmt, ...)
19189 {
19190  va_list args;
19191  va_start(args, fmt);
19192  nk_labelfv(ctx, flags, fmt, args);
19193  va_end(args);
19194 }
19195 NK_API void
19196 nk_labelf_wrap(struct nk_context *ctx, const char *fmt,...)
19197 {
19198  va_list args;
19199  va_start(args, fmt);
19200  nk_labelfv_wrap(ctx, fmt, args);
19201  va_end(args);
19202 }
19203 NK_API void
19204 nk_labelfv_colored(struct nk_context *ctx, nk_flags flags,
19205  struct nk_color color, const char *fmt, va_list args)
19206 {
19207  char buf[256];
19208  nk_strfmt(buf, NK_LEN(buf), fmt, args);
19209  nk_label_colored(ctx, buf, flags, color);
19210 }
19211 
19212 NK_API void
19213 nk_labelfv_colored_wrap(struct nk_context *ctx, struct nk_color color,
19214  const char *fmt, va_list args)
19215 {
19216  char buf[256];
19217  nk_strfmt(buf, NK_LEN(buf), fmt, args);
19218  nk_label_colored_wrap(ctx, buf, color);
19219 }
19220 
19221 NK_API void
19222 nk_labelfv(struct nk_context *ctx, nk_flags flags, const char *fmt, va_list args)
19223 {
19224  char buf[256];
19225  nk_strfmt(buf, NK_LEN(buf), fmt, args);
19226  nk_label(ctx, buf, flags);
19227 }
19228 
19229 NK_API void
19230 nk_labelfv_wrap(struct nk_context *ctx, const char *fmt, va_list args)
19231 {
19232  char buf[256];
19233  nk_strfmt(buf, NK_LEN(buf), fmt, args);
19234  nk_label_wrap(ctx, buf);
19235 }
19236 
19237 NK_API void
19238 nk_value_bool(struct nk_context *ctx, const char *prefix, int value)
19239 {
19240  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %s", prefix, ((value) ? "true": "false"));
19241 }
19242 NK_API void
19243 nk_value_int(struct nk_context *ctx, const char *prefix, int value)
19244 {
19245  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %d", prefix, value);
19246 }
19247 NK_API void
19248 nk_value_uint(struct nk_context *ctx, const char *prefix, unsigned int value)
19249 {
19250  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %u", prefix, value);
19251 }
19252 NK_API void
19253 nk_value_float(struct nk_context *ctx, const char *prefix, float value)
19254 {
19255  double double_value = (double)value;
19256  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %.3f", prefix, double_value);
19257 }
19258 NK_API void
19259 nk_value_color_byte(struct nk_context *ctx, const char *p, struct nk_color c)
19260 {
19261  nk_labelf(ctx, NK_TEXT_LEFT, "%s: (%d, %d, %d, %d)", p, c.r, c.g, c.b, c.a);
19262 }
19263 NK_API void
19264 nk_value_color_float(struct nk_context *ctx, const char *p, struct nk_color color)
19265 {
19266  double c[4]; nk_color_dv(c, color);
19267  nk_labelf(ctx, NK_TEXT_LEFT, "%s: (%.2f, %.2f, %.2f, %.2f)",
19268  p, c[0], c[1], c[2], c[3]);
19269 }
19270 NK_API void
19271 nk_value_color_hex(struct nk_context *ctx, const char *prefix, struct nk_color color)
19272 {
19273  char hex[16];
19274  nk_color_hex_rgba(hex, color);
19275  nk_labelf(ctx, NK_TEXT_LEFT, "%s: %s", prefix, hex);
19276 }
19277 #endif
19278 NK_API void
19279 nk_text(struct nk_context *ctx, const char *str, int len, nk_flags alignment)
19280 {
19281  NK_ASSERT(ctx);
19282  if (!ctx) return;
19283  nk_text_colored(ctx, str, len, alignment, ctx->style.text.color);
19284 }
19285 NK_API void
19286 nk_text_wrap(struct nk_context *ctx, const char *str, int len)
19287 {
19288  NK_ASSERT(ctx);
19289  if (!ctx) return;
19290  nk_text_wrap_colored(ctx, str, len, ctx->style.text.color);
19291 }
19292 NK_API void
19293 nk_label(struct nk_context *ctx, const char *str, nk_flags alignment)
19294 {
19295  nk_text(ctx, str, nk_strlen(str), alignment);
19296 }
19297 NK_API void
19298 nk_label_colored(struct nk_context *ctx, const char *str, nk_flags align,
19299  struct nk_color color)
19300 {
19301  nk_text_colored(ctx, str, nk_strlen(str), align, color);
19302 }
19303 NK_API void
19304 nk_label_wrap(struct nk_context *ctx, const char *str)
19305 {
19306  nk_text_wrap(ctx, str, nk_strlen(str));
19307 }
19308 NK_API void
19309 nk_label_colored_wrap(struct nk_context *ctx, const char *str, struct nk_color color)
19310 {
19311  nk_text_wrap_colored(ctx, str, nk_strlen(str), color);
19312 }
19313 
19314 
19315 
19316 
19317 
19318 /* ===============================================================
19319  *
19320  * IMAGE
19321  *
19322  * ===============================================================*/
19323 NK_API nk_handle
19324 nk_handle_ptr(void *ptr)
19325 {
19326  nk_handle handle = {0};
19327  handle.ptr = ptr;
19328  return handle;
19329 }
19330 NK_API nk_handle
19331 nk_handle_id(int id)
19332 {
19333  nk_handle handle;
19334  nk_zero_struct(handle);
19335  handle.id = id;
19336  return handle;
19337 }
19338 NK_API struct nk_image
19339 nk_subimage_ptr(void *ptr, unsigned short w, unsigned short h, struct nk_rect r)
19340 {
19341  struct nk_image s;
19342  nk_zero(&s, sizeof(s));
19343  s.handle.ptr = ptr;
19344  s.w = w; s.h = h;
19345  s.region[0] = (unsigned short)r.x;
19346  s.region[1] = (unsigned short)r.y;
19347  s.region[2] = (unsigned short)r.w;
19348  s.region[3] = (unsigned short)r.h;
19349  return s;
19350 }
19351 NK_API struct nk_image
19352 nk_subimage_id(int id, unsigned short w, unsigned short h, struct nk_rect r)
19353 {
19354  struct nk_image s;
19355  nk_zero(&s, sizeof(s));
19356  s.handle.id = id;
19357  s.w = w; s.h = h;
19358  s.region[0] = (unsigned short)r.x;
19359  s.region[1] = (unsigned short)r.y;
19360  s.region[2] = (unsigned short)r.w;
19361  s.region[3] = (unsigned short)r.h;
19362  return s;
19363 }
19364 NK_API struct nk_image
19365 nk_subimage_handle(nk_handle handle, unsigned short w, unsigned short h,
19366  struct nk_rect r)
19367 {
19368  struct nk_image s;
19369  nk_zero(&s, sizeof(s));
19370  s.handle = handle;
19371  s.w = w; s.h = h;
19372  s.region[0] = (unsigned short)r.x;
19373  s.region[1] = (unsigned short)r.y;
19374  s.region[2] = (unsigned short)r.w;
19375  s.region[3] = (unsigned short)r.h;
19376  return s;
19377 }
19378 NK_API struct nk_image
19379 nk_image_handle(nk_handle handle)
19380 {
19381  struct nk_image s;
19382  nk_zero(&s, sizeof(s));
19383  s.handle = handle;
19384  s.w = 0; s.h = 0;
19385  s.region[0] = 0;
19386  s.region[1] = 0;
19387  s.region[2] = 0;
19388  s.region[3] = 0;
19389  return s;
19390 }
19391 NK_API struct nk_image
19392 nk_image_ptr(void *ptr)
19393 {
19394  struct nk_image s;
19395  nk_zero(&s, sizeof(s));
19396  NK_ASSERT(ptr);
19397  s.handle.ptr = ptr;
19398  s.w = 0; s.h = 0;
19399  s.region[0] = 0;
19400  s.region[1] = 0;
19401  s.region[2] = 0;
19402  s.region[3] = 0;
19403  return s;
19404 }
19405 NK_API struct nk_image
19406 nk_image_id(int id)
19407 {
19408  struct nk_image s;
19409  nk_zero(&s, sizeof(s));
19410  s.handle.id = id;
19411  s.w = 0; s.h = 0;
19412  s.region[0] = 0;
19413  s.region[1] = 0;
19414  s.region[2] = 0;
19415  s.region[3] = 0;
19416  return s;
19417 }
19418 NK_API int
19419 nk_image_is_subimage(const struct nk_image* img)
19420 {
19421  NK_ASSERT(img);
19422  return !(img->w == 0 && img->h == 0);
19423 }
19424 NK_API void
19425 nk_image(struct nk_context *ctx, struct nk_image img)
19426 {
19427  struct nk_window *win;
19428  struct nk_rect bounds;
19429 
19430  NK_ASSERT(ctx);
19431  NK_ASSERT(ctx->current);
19432  NK_ASSERT(ctx->current->layout);
19433  if (!ctx || !ctx->current || !ctx->current->layout) return;
19434 
19435  win = ctx->current;
19436  if (!nk_widget(&bounds, ctx)) return;
19437  nk_draw_image(&win->buffer, bounds, &img, nk_white);
19438 }
19439 NK_API void
19440 nk_image_color(struct nk_context *ctx, struct nk_image img, struct nk_color col)
19441 {
19442  struct nk_window *win;
19443  struct nk_rect bounds;
19444 
19445  NK_ASSERT(ctx);
19446  NK_ASSERT(ctx->current);
19447  NK_ASSERT(ctx->current->layout);
19448  if (!ctx || !ctx->current || !ctx->current->layout) return;
19449 
19450  win = ctx->current;
19451  if (!nk_widget(&bounds, ctx)) return;
19452  nk_draw_image(&win->buffer, bounds, &img, col);
19453 }
19454 
19455 
19456 
19457 
19458 
19459 /* ==============================================================
19460  *
19461  * BUTTON
19462  *
19463  * ===============================================================*/
19464 NK_LIB void
19465 nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type,
19466  struct nk_rect content, struct nk_color background, struct nk_color foreground,
19467  float border_width, const struct nk_user_font *font)
19468 {
19469  switch (type) {
19470  case NK_SYMBOL_X:
19471  case NK_SYMBOL_UNDERSCORE:
19472  case NK_SYMBOL_PLUS:
19473  case NK_SYMBOL_MINUS: {
19474  /* single character text symbol */
19475  const char *X = (type == NK_SYMBOL_X) ? "x":
19476  (type == NK_SYMBOL_UNDERSCORE) ? "_":
19477  (type == NK_SYMBOL_PLUS) ? "+": "-";
19478  struct nk_text text;
19479  text.padding = nk_vec2(0,0);
19480  text.background = background;
19481  text.text = foreground;
19482  nk_widget_text(out, content, X, 1, &text, NK_TEXT_CENTERED, font);
19483  } break;
19486  case NK_SYMBOL_RECT_SOLID:
19487  case NK_SYMBOL_RECT_OUTLINE: {
19488  /* simple empty/filled shapes */
19489  if (type == NK_SYMBOL_RECT_SOLID || type == NK_SYMBOL_RECT_OUTLINE) {
19490  nk_fill_rect(out, content, 0, foreground);
19491  if (type == NK_SYMBOL_RECT_OUTLINE)
19492  nk_fill_rect(out, nk_shrink_rect(content, border_width), 0, background);
19493  } else {
19494  nk_fill_circle(out, content, foreground);
19495  if (type == NK_SYMBOL_CIRCLE_OUTLINE)
19496  nk_fill_circle(out, nk_shrink_rect(content, 1), background);
19497  }
19498  } break;
19499  case NK_SYMBOL_TRIANGLE_UP:
19502  case NK_SYMBOL_TRIANGLE_RIGHT: {
19503  enum nk_heading heading;
19504  struct nk_vec2 points[3];
19505  heading = (type == NK_SYMBOL_TRIANGLE_RIGHT) ? NK_RIGHT :
19506  (type == NK_SYMBOL_TRIANGLE_LEFT) ? NK_LEFT:
19507  (type == NK_SYMBOL_TRIANGLE_UP) ? NK_UP: NK_DOWN;
19508  nk_triangle_from_direction(points, content, 0, 0, heading);
19509  nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
19510  points[2].x, points[2].y, foreground);
19511  } break;
19512  default:
19513  case NK_SYMBOL_NONE:
19514  case NK_SYMBOL_MAX: break;
19515  }
19516 }
19517 NK_LIB int
19518 nk_button_behavior(nk_flags *state, struct nk_rect r,
19519  const struct nk_input *i, enum nk_button_behavior behavior)
19520 {
19521  int ret = 0;
19522  nk_widget_state_reset(state);
19523  if (!i) return 0;
19524  if (nk_input_is_mouse_hovering_rect(i, r)) {
19525  *state = NK_WIDGET_STATE_HOVERED;
19527  *state = NK_WIDGET_STATE_ACTIVE;
19529  ret = (behavior != NK_BUTTON_DEFAULT) ?
19531 #ifdef NK_BUTTON_TRIGGER_ON_RELEASE
19533 #else
19535 #endif
19536  }
19537  }
19539  *state |= NK_WIDGET_STATE_ENTERED;
19540  else if (nk_input_is_mouse_prev_hovering_rect(i, r))
19541  *state |= NK_WIDGET_STATE_LEFT;
19542  return ret;
19543 }
19544 NK_LIB const struct nk_style_item*
19545 nk_draw_button(struct nk_command_buffer *out,
19546  const struct nk_rect *bounds, nk_flags state,
19547  const struct nk_style_button *style)
19548 {
19549  const struct nk_style_item *background;
19550  if (state & NK_WIDGET_STATE_HOVER)
19551  background = &style->hover;
19552  else if (state & NK_WIDGET_STATE_ACTIVED)
19553  background = &style->active;
19554  else background = &style->normal;
19555 
19556  if (background->type == NK_STYLE_ITEM_IMAGE) {
19557  nk_draw_image(out, *bounds, &background->data.image, nk_white);
19558  } else {
19559  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
19560  nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
19561  }
19562  return background;
19563 }
19564 NK_LIB int
19565 nk_do_button(nk_flags *state, struct nk_command_buffer *out, struct nk_rect r,
19566  const struct nk_style_button *style, const struct nk_input *in,
19567  enum nk_button_behavior behavior, struct nk_rect *content)
19568 {
19569  struct nk_rect bounds;
19570  NK_ASSERT(style);
19571  NK_ASSERT(state);
19572  NK_ASSERT(out);
19573  if (!out || !style)
19574  return nk_false;
19575 
19576  /* calculate button content space */
19577  content->x = r.x + style->padding.x + style->border + style->rounding;
19578  content->y = r.y + style->padding.y + style->border + style->rounding;
19579  content->w = r.w - (2 * style->padding.x + style->border + style->rounding*2);
19580  content->h = r.h - (2 * style->padding.y + style->border + style->rounding*2);
19581 
19582  /* execute button behavior */
19583  bounds.x = r.x - style->touch_padding.x;
19584  bounds.y = r.y - style->touch_padding.y;
19585  bounds.w = r.w + 2 * style->touch_padding.x;
19586  bounds.h = r.h + 2 * style->touch_padding.y;
19587  return nk_button_behavior(state, bounds, in, behavior);
19588 }
19589 NK_LIB void
19590 nk_draw_button_text(struct nk_command_buffer *out,
19591  const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state,
19592  const struct nk_style_button *style, const char *txt, int len,
19593  nk_flags text_alignment, const struct nk_user_font *font)
19594 {
19595  struct nk_text text;
19596  const struct nk_style_item *background;
19597  background = nk_draw_button(out, bounds, state, style);
19598 
19599  /* select correct colors/images */
19600  if (background->type == NK_STYLE_ITEM_COLOR)
19601  text.background = background->data.color;
19602  else text.background = style->text_background;
19603  if (state & NK_WIDGET_STATE_HOVER)
19604  text.text = style->text_hover;
19605  else if (state & NK_WIDGET_STATE_ACTIVED)
19606  text.text = style->text_active;
19607  else text.text = style->text_normal;
19608 
19609  text.padding = nk_vec2(0,0);
19610  nk_widget_text(out, *content, txt, len, &text, text_alignment, font);
19611 }
19612 NK_LIB int
19613 nk_do_button_text(nk_flags *state,
19614  struct nk_command_buffer *out, struct nk_rect bounds,
19615  const char *string, int len, nk_flags align, enum nk_button_behavior behavior,
19616  const struct nk_style_button *style, const struct nk_input *in,
19617  const struct nk_user_font *font)
19618 {
19619  struct nk_rect content;
19620  int ret = nk_false;
19621 
19622  NK_ASSERT(state);
19623  NK_ASSERT(style);
19624  NK_ASSERT(out);
19625  NK_ASSERT(string);
19626  NK_ASSERT(font);
19627  if (!out || !style || !font || !string)
19628  return nk_false;
19629 
19630  ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19631  if (style->draw_begin) style->draw_begin(out, style->userdata);
19632  nk_draw_button_text(out, &bounds, &content, *state, style, string, len, align, font);
19633  if (style->draw_end) style->draw_end(out, style->userdata);
19634  return ret;
19635 }
19636 NK_LIB void
19637 nk_draw_button_symbol(struct nk_command_buffer *out,
19638  const struct nk_rect *bounds, const struct nk_rect *content,
19639  nk_flags state, const struct nk_style_button *style,
19640  enum nk_symbol_type type, const struct nk_user_font *font)
19641 {
19642  struct nk_color sym, bg;
19643  const struct nk_style_item *background;
19644 
19645  /* select correct colors/images */
19646  background = nk_draw_button(out, bounds, state, style);
19647  if (background->type == NK_STYLE_ITEM_COLOR)
19648  bg = background->data.color;
19649  else bg = style->text_background;
19650 
19651  if (state & NK_WIDGET_STATE_HOVER)
19652  sym = style->text_hover;
19653  else if (state & NK_WIDGET_STATE_ACTIVED)
19654  sym = style->text_active;
19655  else sym = style->text_normal;
19656  nk_draw_symbol(out, type, *content, bg, sym, 1, font);
19657 }
19658 NK_LIB int
19659 nk_do_button_symbol(nk_flags *state,
19660  struct nk_command_buffer *out, struct nk_rect bounds,
19661  enum nk_symbol_type symbol, enum nk_button_behavior behavior,
19662  const struct nk_style_button *style, const struct nk_input *in,
19663  const struct nk_user_font *font)
19664 {
19665  int ret;
19666  struct nk_rect content;
19667 
19668  NK_ASSERT(state);
19669  NK_ASSERT(style);
19670  NK_ASSERT(font);
19671  NK_ASSERT(out);
19672  if (!out || !style || !font || !state)
19673  return nk_false;
19674 
19675  ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19676  if (style->draw_begin) style->draw_begin(out, style->userdata);
19677  nk_draw_button_symbol(out, &bounds, &content, *state, style, symbol, font);
19678  if (style->draw_end) style->draw_end(out, style->userdata);
19679  return ret;
19680 }
19681 NK_LIB void
19682 nk_draw_button_image(struct nk_command_buffer *out,
19683  const struct nk_rect *bounds, const struct nk_rect *content,
19684  nk_flags state, const struct nk_style_button *style, const struct nk_image *img)
19685 {
19686  nk_draw_button(out, bounds, state, style);
19687  nk_draw_image(out, *content, img, nk_white);
19688 }
19689 NK_LIB int
19690 nk_do_button_image(nk_flags *state,
19691  struct nk_command_buffer *out, struct nk_rect bounds,
19692  struct nk_image img, enum nk_button_behavior b,
19693  const struct nk_style_button *style, const struct nk_input *in)
19694 {
19695  int ret;
19696  struct nk_rect content;
19697 
19698  NK_ASSERT(state);
19699  NK_ASSERT(style);
19700  NK_ASSERT(out);
19701  if (!out || !style || !state)
19702  return nk_false;
19703 
19704  ret = nk_do_button(state, out, bounds, style, in, b, &content);
19705  content.x += style->image_padding.x;
19706  content.y += style->image_padding.y;
19707  content.w -= 2 * style->image_padding.x;
19708  content.h -= 2 * style->image_padding.y;
19709 
19710  if (style->draw_begin) style->draw_begin(out, style->userdata);
19711  nk_draw_button_image(out, &bounds, &content, *state, style, &img);
19712  if (style->draw_end) style->draw_end(out, style->userdata);
19713  return ret;
19714 }
19715 NK_LIB void
19716 nk_draw_button_text_symbol(struct nk_command_buffer *out,
19717  const struct nk_rect *bounds, const struct nk_rect *label,
19718  const struct nk_rect *symbol, nk_flags state, const struct nk_style_button *style,
19719  const char *str, int len, enum nk_symbol_type type,
19720  const struct nk_user_font *font)
19721 {
19722  struct nk_color sym;
19723  struct nk_text text;
19724  const struct nk_style_item *background;
19725 
19726  /* select correct background colors/images */
19727  background = nk_draw_button(out, bounds, state, style);
19728  if (background->type == NK_STYLE_ITEM_COLOR)
19729  text.background = background->data.color;
19730  else text.background = style->text_background;
19731 
19732  /* select correct text colors */
19733  if (state & NK_WIDGET_STATE_HOVER) {
19734  sym = style->text_hover;
19735  text.text = style->text_hover;
19736  } else if (state & NK_WIDGET_STATE_ACTIVED) {
19737  sym = style->text_active;
19738  text.text = style->text_active;
19739  } else {
19740  sym = style->text_normal;
19741  text.text = style->text_normal;
19742  }
19743 
19744  text.padding = nk_vec2(0,0);
19745  nk_draw_symbol(out, type, *symbol, style->text_background, sym, 0, font);
19746  nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
19747 }
19748 NK_LIB int
19749 nk_do_button_text_symbol(nk_flags *state,
19750  struct nk_command_buffer *out, struct nk_rect bounds,
19751  enum nk_symbol_type symbol, const char *str, int len, nk_flags align,
19752  enum nk_button_behavior behavior, const struct nk_style_button *style,
19753  const struct nk_user_font *font, const struct nk_input *in)
19754 {
19755  int ret;
19756  struct nk_rect tri = {0,0,0,0};
19757  struct nk_rect content;
19758 
19759  NK_ASSERT(style);
19760  NK_ASSERT(out);
19761  NK_ASSERT(font);
19762  if (!out || !style || !font)
19763  return nk_false;
19764 
19765  ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19766  tri.y = content.y + (content.h/2) - font->height/2;
19767  tri.w = font->height; tri.h = font->height;
19768  if (align & NK_TEXT_ALIGN_LEFT) {
19769  tri.x = (content.x + content.w) - (2 * style->padding.x + tri.w);
19770  tri.x = NK_MAX(tri.x, 0);
19771  } else tri.x = content.x + 2 * style->padding.x;
19772 
19773  /* draw button */
19774  if (style->draw_begin) style->draw_begin(out, style->userdata);
19775  nk_draw_button_text_symbol(out, &bounds, &content, &tri,
19776  *state, style, str, len, symbol, font);
19777  if (style->draw_end) style->draw_end(out, style->userdata);
19778  return ret;
19779 }
19780 NK_LIB void
19781 nk_draw_button_text_image(struct nk_command_buffer *out,
19782  const struct nk_rect *bounds, const struct nk_rect *label,
19783  const struct nk_rect *image, nk_flags state, const struct nk_style_button *style,
19784  const char *str, int len, const struct nk_user_font *font,
19785  const struct nk_image *img)
19786 {
19787  struct nk_text text;
19788  const struct nk_style_item *background;
19789  background = nk_draw_button(out, bounds, state, style);
19790 
19791  /* select correct colors */
19792  if (background->type == NK_STYLE_ITEM_COLOR)
19793  text.background = background->data.color;
19794  else text.background = style->text_background;
19795  if (state & NK_WIDGET_STATE_HOVER)
19796  text.text = style->text_hover;
19797  else if (state & NK_WIDGET_STATE_ACTIVED)
19798  text.text = style->text_active;
19799  else text.text = style->text_normal;
19800 
19801  text.padding = nk_vec2(0,0);
19802  nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
19803  nk_draw_image(out, *image, img, nk_white);
19804 }
19805 NK_LIB int
19806 nk_do_button_text_image(nk_flags *state,
19807  struct nk_command_buffer *out, struct nk_rect bounds,
19808  struct nk_image img, const char* str, int len, nk_flags align,
19809  enum nk_button_behavior behavior, const struct nk_style_button *style,
19810  const struct nk_user_font *font, const struct nk_input *in)
19811 {
19812  int ret;
19813  struct nk_rect icon;
19814  struct nk_rect content;
19815 
19816  NK_ASSERT(style);
19817  NK_ASSERT(state);
19818  NK_ASSERT(font);
19819  NK_ASSERT(out);
19820  if (!out || !font || !style || !str)
19821  return nk_false;
19822 
19823  ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
19824  icon.y = bounds.y + style->padding.y;
19825  icon.w = icon.h = bounds.h - 2 * style->padding.y;
19826  if (align & NK_TEXT_ALIGN_LEFT) {
19827  icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
19828  icon.x = NK_MAX(icon.x, 0);
19829  } else icon.x = bounds.x + 2 * style->padding.x;
19830 
19831  icon.x += style->image_padding.x;
19832  icon.y += style->image_padding.y;
19833  icon.w -= 2 * style->image_padding.x;
19834  icon.h -= 2 * style->image_padding.y;
19835 
19836  if (style->draw_begin) style->draw_begin(out, style->userdata);
19837  nk_draw_button_text_image(out, &bounds, &content, &icon, *state, style, str, len, font, &img);
19838  if (style->draw_end) style->draw_end(out, style->userdata);
19839  return ret;
19840 }
19841 NK_API void
19842 nk_button_set_behavior(struct nk_context *ctx, enum nk_button_behavior behavior)
19843 {
19844  NK_ASSERT(ctx);
19845  if (!ctx) return;
19846  ctx->button_behavior = behavior;
19847 }
19848 NK_API int
19849 nk_button_push_behavior(struct nk_context *ctx, enum nk_button_behavior behavior)
19850 {
19851  struct nk_config_stack_button_behavior *button_stack;
19852  struct nk_config_stack_button_behavior_element *element;
19853 
19854  NK_ASSERT(ctx);
19855  if (!ctx) return 0;
19856 
19857  button_stack = &ctx->stacks.button_behaviors;
19858  NK_ASSERT(button_stack->head < (int)NK_LEN(button_stack->elements));
19859  if (button_stack->head >= (int)NK_LEN(button_stack->elements))
19860  return 0;
19861 
19862  element = &button_stack->elements[button_stack->head++];
19863  element->address = &ctx->button_behavior;
19864  element->old_value = ctx->button_behavior;
19865  ctx->button_behavior = behavior;
19866  return 1;
19867 }
19868 NK_API int
19869 nk_button_pop_behavior(struct nk_context *ctx)
19870 {
19871  struct nk_config_stack_button_behavior *button_stack;
19872  struct nk_config_stack_button_behavior_element *element;
19873 
19874  NK_ASSERT(ctx);
19875  if (!ctx) return 0;
19876 
19877  button_stack = &ctx->stacks.button_behaviors;
19878  NK_ASSERT(button_stack->head > 0);
19879  if (button_stack->head < 1)
19880  return 0;
19881 
19882  element = &button_stack->elements[--button_stack->head];
19883  *element->address = element->old_value;
19884  return 1;
19885 }
19886 NK_API int
19887 nk_button_text_styled(struct nk_context *ctx,
19888  const struct nk_style_button *style, const char *title, int len)
19889 {
19890  struct nk_window *win;
19891  struct nk_panel *layout;
19892  const struct nk_input *in;
19893 
19894  struct nk_rect bounds;
19896 
19897  NK_ASSERT(ctx);
19898  NK_ASSERT(style);
19899  NK_ASSERT(ctx->current);
19900  NK_ASSERT(ctx->current->layout);
19901  if (!style || !ctx || !ctx->current || !ctx->current->layout) return 0;
19902 
19903  win = ctx->current;
19904  layout = win->layout;
19905  state = nk_widget(&bounds, ctx);
19906 
19907  if (!state) return 0;
19908  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
19909  return nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
19910  title, len, style->text_alignment, ctx->button_behavior,
19911  style, in, ctx->style.font);
19912 }
19913 NK_API int
19914 nk_button_text(struct nk_context *ctx, const char *title, int len)
19915 {
19916  NK_ASSERT(ctx);
19917  if (!ctx) return 0;
19918  return nk_button_text_styled(ctx, &ctx->style.button, title, len);
19919 }
19920 NK_API int nk_button_label_styled(struct nk_context *ctx,
19921  const struct nk_style_button *style, const char *title)
19922 {
19923  return nk_button_text_styled(ctx, style, title, nk_strlen(title));
19924 }
19925 NK_API int nk_button_label(struct nk_context *ctx, const char *title)
19926 {
19927  return nk_button_text(ctx, title, nk_strlen(title));
19928 }
19929 NK_API int
19930 nk_button_color(struct nk_context *ctx, struct nk_color color)
19931 {
19932  struct nk_window *win;
19933  struct nk_panel *layout;
19934  const struct nk_input *in;
19935  struct nk_style_button button;
19936 
19937  int ret = 0;
19938  struct nk_rect bounds;
19939  struct nk_rect content;
19941 
19942  NK_ASSERT(ctx);
19943  NK_ASSERT(ctx->current);
19944  NK_ASSERT(ctx->current->layout);
19945  if (!ctx || !ctx->current || !ctx->current->layout)
19946  return 0;
19947 
19948  win = ctx->current;
19949  layout = win->layout;
19950 
19951  state = nk_widget(&bounds, ctx);
19952  if (!state) return 0;
19953  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
19954 
19955  button = ctx->style.button;
19956  button.normal = nk_style_item_color(color);
19957  button.hover = nk_style_item_color(color);
19958  button.active = nk_style_item_color(color);
19959  ret = nk_do_button(&ctx->last_widget_state, &win->buffer, bounds,
19960  &button, in, ctx->button_behavior, &content);
19961  nk_draw_button(&win->buffer, &bounds, ctx->last_widget_state, &button);
19962  return ret;
19963 }
19964 NK_API int
19965 nk_button_symbol_styled(struct nk_context *ctx,
19966  const struct nk_style_button *style, enum nk_symbol_type symbol)
19967 {
19968  struct nk_window *win;
19969  struct nk_panel *layout;
19970  const struct nk_input *in;
19971 
19972  struct nk_rect bounds;
19974 
19975  NK_ASSERT(ctx);
19976  NK_ASSERT(ctx->current);
19977  NK_ASSERT(ctx->current->layout);
19978  if (!ctx || !ctx->current || !ctx->current->layout)
19979  return 0;
19980 
19981  win = ctx->current;
19982  layout = win->layout;
19983  state = nk_widget(&bounds, ctx);
19984  if (!state) return 0;
19985  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
19986  return nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, bounds,
19987  symbol, ctx->button_behavior, style, in, ctx->style.font);
19988 }
19989 NK_API int
19990 nk_button_symbol(struct nk_context *ctx, enum nk_symbol_type symbol)
19991 {
19992  NK_ASSERT(ctx);
19993  if (!ctx) return 0;
19994  return nk_button_symbol_styled(ctx, &ctx->style.button, symbol);
19995 }
19996 NK_API int
19997 nk_button_image_styled(struct nk_context *ctx, const struct nk_style_button *style,
19998  struct nk_image img)
19999 {
20000  struct nk_window *win;
20001  struct nk_panel *layout;
20002  const struct nk_input *in;
20003 
20004  struct nk_rect bounds;
20006 
20007  NK_ASSERT(ctx);
20008  NK_ASSERT(ctx->current);
20009  NK_ASSERT(ctx->current->layout);
20010  if (!ctx || !ctx->current || !ctx->current->layout)
20011  return 0;
20012 
20013  win = ctx->current;
20014  layout = win->layout;
20015 
20016  state = nk_widget(&bounds, ctx);
20017  if (!state) return 0;
20018  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20019  return nk_do_button_image(&ctx->last_widget_state, &win->buffer, bounds,
20020  img, ctx->button_behavior, style, in);
20021 }
20022 NK_API int
20023 nk_button_image(struct nk_context *ctx, struct nk_image img)
20024 {
20025  NK_ASSERT(ctx);
20026  if (!ctx) return 0;
20027  return nk_button_image_styled(ctx, &ctx->style.button, img);
20028 }
20029 NK_API int
20030 nk_button_symbol_text_styled(struct nk_context *ctx,
20031  const struct nk_style_button *style, enum nk_symbol_type symbol,
20032  const char *text, int len, nk_flags align)
20033 {
20034  struct nk_window *win;
20035  struct nk_panel *layout;
20036  const struct nk_input *in;
20037 
20038  struct nk_rect bounds;
20040 
20041  NK_ASSERT(ctx);
20042  NK_ASSERT(ctx->current);
20043  NK_ASSERT(ctx->current->layout);
20044  if (!ctx || !ctx->current || !ctx->current->layout)
20045  return 0;
20046 
20047  win = ctx->current;
20048  layout = win->layout;
20049 
20050  state = nk_widget(&bounds, ctx);
20051  if (!state) return 0;
20052  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20053  return nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
20054  symbol, text, len, align, ctx->button_behavior,
20055  style, ctx->style.font, in);
20056 }
20057 NK_API int
20058 nk_button_symbol_text(struct nk_context *ctx, enum nk_symbol_type symbol,
20059  const char* text, int len, nk_flags align)
20060 {
20061  NK_ASSERT(ctx);
20062  if (!ctx) return 0;
20063  return nk_button_symbol_text_styled(ctx, &ctx->style.button, symbol, text, len, align);
20064 }
20065 NK_API int nk_button_symbol_label(struct nk_context *ctx, enum nk_symbol_type symbol,
20066  const char *label, nk_flags align)
20067 {
20068  return nk_button_symbol_text(ctx, symbol, label, nk_strlen(label), align);
20069 }
20070 NK_API int nk_button_symbol_label_styled(struct nk_context *ctx,
20071  const struct nk_style_button *style, enum nk_symbol_type symbol,
20072  const char *title, nk_flags align)
20073 {
20074  return nk_button_symbol_text_styled(ctx, style, symbol, title, nk_strlen(title), align);
20075 }
20076 NK_API int
20077 nk_button_image_text_styled(struct nk_context *ctx,
20078  const struct nk_style_button *style, struct nk_image img, const char *text,
20079  int len, nk_flags align)
20080 {
20081  struct nk_window *win;
20082  struct nk_panel *layout;
20083  const struct nk_input *in;
20084 
20085  struct nk_rect bounds;
20087 
20088  NK_ASSERT(ctx);
20089  NK_ASSERT(ctx->current);
20090  NK_ASSERT(ctx->current->layout);
20091  if (!ctx || !ctx->current || !ctx->current->layout)
20092  return 0;
20093 
20094  win = ctx->current;
20095  layout = win->layout;
20096 
20097  state = nk_widget(&bounds, ctx);
20098  if (!state) return 0;
20099  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20100  return nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
20101  bounds, img, text, len, align, ctx->button_behavior,
20102  style, ctx->style.font, in);
20103 }
20104 NK_API int
20105 nk_button_image_text(struct nk_context *ctx, struct nk_image img,
20106  const char *text, int len, nk_flags align)
20107 {
20108  return nk_button_image_text_styled(ctx, &ctx->style.button,img, text, len, align);
20109 }
20110 NK_API int nk_button_image_label(struct nk_context *ctx, struct nk_image img,
20111  const char *label, nk_flags align)
20112 {
20113  return nk_button_image_text(ctx, img, label, nk_strlen(label), align);
20114 }
20115 NK_API int nk_button_image_label_styled(struct nk_context *ctx,
20116  const struct nk_style_button *style, struct nk_image img,
20117  const char *label, nk_flags text_alignment)
20118 {
20119  return nk_button_image_text_styled(ctx, style, img, label, nk_strlen(label), text_alignment);
20120 }
20121 
20122 
20123 
20124 
20125 
20126 /* ===============================================================
20127  *
20128  * TOGGLE
20129  *
20130  * ===============================================================*/
20131 NK_LIB int
20132 nk_toggle_behavior(const struct nk_input *in, struct nk_rect select,
20133  nk_flags *state, int active)
20134 {
20135  nk_widget_state_reset(state);
20136  if (nk_button_behavior(state, select, in, NK_BUTTON_DEFAULT)) {
20137  *state = NK_WIDGET_STATE_ACTIVE;
20138  active = !active;
20139  }
20140  if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, select))
20141  *state |= NK_WIDGET_STATE_ENTERED;
20142  else if (nk_input_is_mouse_prev_hovering_rect(in, select))
20143  *state |= NK_WIDGET_STATE_LEFT;
20144  return active;
20145 }
20146 NK_LIB void
20147 nk_draw_checkbox(struct nk_command_buffer *out,
20148  nk_flags state, const struct nk_style_toggle *style, int active,
20149  const struct nk_rect *label, const struct nk_rect *selector,
20150  const struct nk_rect *cursors, const char *string, int len,
20151  const struct nk_user_font *font)
20152 {
20153  const struct nk_style_item *background;
20154  const struct nk_style_item *cursor;
20155  struct nk_text text;
20156 
20157  /* select correct colors/images */
20158  if (state & NK_WIDGET_STATE_HOVER) {
20159  background = &style->hover;
20160  cursor = &style->cursor_hover;
20161  text.text = style->text_hover;
20162  } else if (state & NK_WIDGET_STATE_ACTIVED) {
20163  background = &style->hover;
20164  cursor = &style->cursor_hover;
20165  text.text = style->text_active;
20166  } else {
20167  background = &style->normal;
20168  cursor = &style->cursor_normal;
20169  text.text = style->text_normal;
20170  }
20171 
20172  /* draw background and cursor */
20173  if (background->type == NK_STYLE_ITEM_COLOR) {
20174  nk_fill_rect(out, *selector, 0, style->border_color);
20175  nk_fill_rect(out, nk_shrink_rect(*selector, style->border), 0, background->data.color);
20176  } else nk_draw_image(out, *selector, &background->data.image, nk_white);
20177  if (active) {
20178  if (cursor->type == NK_STYLE_ITEM_IMAGE)
20179  nk_draw_image(out, *cursors, &cursor->data.image, nk_white);
20180  else nk_fill_rect(out, *cursors, 0, cursor->data.color);
20181  }
20182 
20183  text.padding.x = 0;
20184  text.padding.y = 0;
20185  text.background = style->text_background;
20186  nk_widget_text(out, *label, string, len, &text, NK_TEXT_LEFT, font);
20187 }
20188 NK_LIB void
20189 nk_draw_option(struct nk_command_buffer *out,
20190  nk_flags state, const struct nk_style_toggle *style, int active,
20191  const struct nk_rect *label, const struct nk_rect *selector,
20192  const struct nk_rect *cursors, const char *string, int len,
20193  const struct nk_user_font *font)
20194 {
20195  const struct nk_style_item *background;
20196  const struct nk_style_item *cursor;
20197  struct nk_text text;
20198 
20199  /* select correct colors/images */
20200  if (state & NK_WIDGET_STATE_HOVER) {
20201  background = &style->hover;
20202  cursor = &style->cursor_hover;
20203  text.text = style->text_hover;
20204  } else if (state & NK_WIDGET_STATE_ACTIVED) {
20205  background = &style->hover;
20206  cursor = &style->cursor_hover;
20207  text.text = style->text_active;
20208  } else {
20209  background = &style->normal;
20210  cursor = &style->cursor_normal;
20211  text.text = style->text_normal;
20212  }
20213 
20214  /* draw background and cursor */
20215  if (background->type == NK_STYLE_ITEM_COLOR) {
20216  nk_fill_circle(out, *selector, style->border_color);
20217  nk_fill_circle(out, nk_shrink_rect(*selector, style->border), background->data.color);
20218  } else nk_draw_image(out, *selector, &background->data.image, nk_white);
20219  if (active) {
20220  if (cursor->type == NK_STYLE_ITEM_IMAGE)
20221  nk_draw_image(out, *cursors, &cursor->data.image, nk_white);
20222  else nk_fill_circle(out, *cursors, cursor->data.color);
20223  }
20224 
20225  text.padding.x = 0;
20226  text.padding.y = 0;
20227  text.background = style->text_background;
20228  nk_widget_text(out, *label, string, len, &text, NK_TEXT_LEFT, font);
20229 }
20230 NK_LIB int
20231 nk_do_toggle(nk_flags *state,
20232  struct nk_command_buffer *out, struct nk_rect r,
20233  int *active, const char *str, int len, enum nk_toggle_type type,
20234  const struct nk_style_toggle *style, const struct nk_input *in,
20235  const struct nk_user_font *font)
20236 {
20237  int was_active;
20238  struct nk_rect bounds;
20239  struct nk_rect select;
20240  struct nk_rect cursor;
20241  struct nk_rect label;
20242 
20243  NK_ASSERT(style);
20244  NK_ASSERT(out);
20245  NK_ASSERT(font);
20246  if (!out || !style || !font || !active)
20247  return 0;
20248 
20249  r.w = NK_MAX(r.w, font->height + 2 * style->padding.x);
20250  r.h = NK_MAX(r.h, font->height + 2 * style->padding.y);
20251 
20252  /* add additional touch padding for touch screen devices */
20253  bounds.x = r.x - style->touch_padding.x;
20254  bounds.y = r.y - style->touch_padding.y;
20255  bounds.w = r.w + 2 * style->touch_padding.x;
20256  bounds.h = r.h + 2 * style->touch_padding.y;
20257 
20258  /* calculate the selector space */
20259  select.w = font->height;
20260  select.h = select.w;
20261  select.y = r.y + r.h/2.0f - select.h/2.0f;
20262  select.x = r.x;
20263 
20264  /* calculate the bounds of the cursor inside the selector */
20265  cursor.x = select.x + style->padding.x + style->border;
20266  cursor.y = select.y + style->padding.y + style->border;
20267  cursor.w = select.w - (2 * style->padding.x + 2 * style->border);
20268  cursor.h = select.h - (2 * style->padding.y + 2 * style->border);
20269 
20270  /* label behind the selector */
20271  label.x = select.x + select.w + style->spacing;
20272  label.y = select.y;
20273  label.w = NK_MAX(r.x + r.w, label.x) - label.x;
20274  label.h = select.w;
20275 
20276  /* update selector */
20277  was_active = *active;
20278  *active = nk_toggle_behavior(in, bounds, state, *active);
20279 
20280  /* draw selector */
20281  if (style->draw_begin)
20282  style->draw_begin(out, style->userdata);
20283  if (type == NK_TOGGLE_CHECK) {
20284  nk_draw_checkbox(out, *state, style, *active, &label, &select, &cursor, str, len, font);
20285  } else {
20286  nk_draw_option(out, *state, style, *active, &label, &select, &cursor, str, len, font);
20287  }
20288  if (style->draw_end)
20289  style->draw_end(out, style->userdata);
20290  return (was_active != *active);
20291 }
20292 /*----------------------------------------------------------------
20293  *
20294  * CHECKBOX
20295  *
20296  * --------------------------------------------------------------*/
20297 NK_API int
20298 nk_check_text(struct nk_context *ctx, const char *text, int len, int active)
20299 {
20300  struct nk_window *win;
20301  struct nk_panel *layout;
20302  const struct nk_input *in;
20303  const struct nk_style *style;
20304 
20305  struct nk_rect bounds;
20307 
20308  NK_ASSERT(ctx);
20309  NK_ASSERT(ctx->current);
20310  NK_ASSERT(ctx->current->layout);
20311  if (!ctx || !ctx->current || !ctx->current->layout)
20312  return active;
20313 
20314  win = ctx->current;
20315  style = &ctx->style;
20316  layout = win->layout;
20317 
20318  state = nk_widget(&bounds, ctx);
20319  if (!state) return active;
20320  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20321  nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &active,
20322  text, len, NK_TOGGLE_CHECK, &style->checkbox, in, style->font);
20323  return active;
20324 }
20325 NK_API unsigned int
20326 nk_check_flags_text(struct nk_context *ctx, const char *text, int len,
20327  unsigned int flags, unsigned int value)
20328 {
20329  int old_active;
20330  NK_ASSERT(ctx);
20331  NK_ASSERT(text);
20332  if (!ctx || !text) return flags;
20333  old_active = (int)((flags & value) & value);
20334  if (nk_check_text(ctx, text, len, old_active))
20335  flags |= value;
20336  else flags &= ~value;
20337  return flags;
20338 }
20339 NK_API int
20340 nk_checkbox_text(struct nk_context *ctx, const char *text, int len, int *active)
20341 {
20342  int old_val;
20343  NK_ASSERT(ctx);
20344  NK_ASSERT(text);
20345  NK_ASSERT(active);
20346  if (!ctx || !text || !active) return 0;
20347  old_val = *active;
20348  *active = nk_check_text(ctx, text, len, *active);
20349  return old_val != *active;
20350 }
20351 NK_API int
20352 nk_checkbox_flags_text(struct nk_context *ctx, const char *text, int len,
20353  unsigned int *flags, unsigned int value)
20354 {
20355  int active;
20356  NK_ASSERT(ctx);
20357  NK_ASSERT(text);
20358  NK_ASSERT(flags);
20359  if (!ctx || !text || !flags) return 0;
20360 
20361  active = (int)((*flags & value) & value);
20362  if (nk_checkbox_text(ctx, text, len, &active)) {
20363  if (active) *flags |= value;
20364  else *flags &= ~value;
20365  return 1;
20366  }
20367  return 0;
20368 }
20369 NK_API int nk_check_label(struct nk_context *ctx, const char *label, int active)
20370 {
20371  return nk_check_text(ctx, label, nk_strlen(label), active);
20372 }
20373 NK_API unsigned int nk_check_flags_label(struct nk_context *ctx, const char *label,
20374  unsigned int flags, unsigned int value)
20375 {
20376  return nk_check_flags_text(ctx, label, nk_strlen(label), flags, value);
20377 }
20378 NK_API int nk_checkbox_label(struct nk_context *ctx, const char *label, int *active)
20379 {
20380  return nk_checkbox_text(ctx, label, nk_strlen(label), active);
20381 }
20382 NK_API int nk_checkbox_flags_label(struct nk_context *ctx, const char *label,
20383  unsigned int *flags, unsigned int value)
20384 {
20385  return nk_checkbox_flags_text(ctx, label, nk_strlen(label), flags, value);
20386 }
20387 /*----------------------------------------------------------------
20388  *
20389  * OPTION
20390  *
20391  * --------------------------------------------------------------*/
20392 NK_API int
20393 nk_option_text(struct nk_context *ctx, const char *text, int len, int is_active)
20394 {
20395  struct nk_window *win;
20396  struct nk_panel *layout;
20397  const struct nk_input *in;
20398  const struct nk_style *style;
20399 
20400  struct nk_rect bounds;
20402 
20403  NK_ASSERT(ctx);
20404  NK_ASSERT(ctx->current);
20405  NK_ASSERT(ctx->current->layout);
20406  if (!ctx || !ctx->current || !ctx->current->layout)
20407  return is_active;
20408 
20409  win = ctx->current;
20410  style = &ctx->style;
20411  layout = win->layout;
20412 
20413  state = nk_widget(&bounds, ctx);
20414  if (!state) return (int)state;
20415  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20416  nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &is_active,
20417  text, len, NK_TOGGLE_OPTION, &style->option, in, style->font);
20418  return is_active;
20419 }
20420 NK_API int
20421 nk_radio_text(struct nk_context *ctx, const char *text, int len, int *active)
20422 {
20423  int old_value;
20424  NK_ASSERT(ctx);
20425  NK_ASSERT(text);
20426  NK_ASSERT(active);
20427  if (!ctx || !text || !active) return 0;
20428  old_value = *active;
20429  *active = nk_option_text(ctx, text, len, old_value);
20430  return old_value != *active;
20431 }
20432 NK_API int
20433 nk_option_label(struct nk_context *ctx, const char *label, int active)
20434 {
20435  return nk_option_text(ctx, label, nk_strlen(label), active);
20436 }
20437 NK_API int
20438 nk_radio_label(struct nk_context *ctx, const char *label, int *active)
20439 {
20440  return nk_radio_text(ctx, label, nk_strlen(label), active);
20441 }
20442 
20443 
20444 
20445 
20446 
20447 /* ===============================================================
20448  *
20449  * SELECTABLE
20450  *
20451  * ===============================================================*/
20452 NK_LIB void
20453 nk_draw_selectable(struct nk_command_buffer *out,
20454  nk_flags state, const struct nk_style_selectable *style, int active,
20455  const struct nk_rect *bounds,
20456  const struct nk_rect *icon, const struct nk_image *img, enum nk_symbol_type sym,
20457  const char *string, int len, nk_flags align, const struct nk_user_font *font)
20458 {
20459  const struct nk_style_item *background;
20460  struct nk_text text;
20461  text.padding = style->padding;
20462 
20463  /* select correct colors/images */
20464  if (!active) {
20465  if (state & NK_WIDGET_STATE_ACTIVED) {
20466  background = &style->pressed;
20467  text.text = style->text_pressed;
20468  } else if (state & NK_WIDGET_STATE_HOVER) {
20469  background = &style->hover;
20470  text.text = style->text_hover;
20471  } else {
20472  background = &style->normal;
20473  text.text = style->text_normal;
20474  }
20475  } else {
20476  if (state & NK_WIDGET_STATE_ACTIVED) {
20477  background = &style->pressed_active;
20478  text.text = style->text_pressed_active;
20479  } else if (state & NK_WIDGET_STATE_HOVER) {
20480  background = &style->hover_active;
20481  text.text = style->text_hover_active;
20482  } else {
20483  background = &style->normal_active;
20484  text.text = style->text_normal_active;
20485  }
20486  }
20487  /* draw selectable background and text */
20488  if (background->type == NK_STYLE_ITEM_IMAGE) {
20489  nk_draw_image(out, *bounds, &background->data.image, nk_white);
20490  text.background = nk_rgba(0,0,0,0);
20491  } else {
20492  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
20493  text.background = background->data.color;
20494  }
20495  if (icon) {
20496  if (img) nk_draw_image(out, *icon, img, nk_white);
20497  else nk_draw_symbol(out, sym, *icon, text.background, text.text, 1, font);
20498  }
20499  nk_widget_text(out, *bounds, string, len, &text, align, font);
20500 }
20501 NK_LIB int
20502 nk_do_selectable(nk_flags *state, struct nk_command_buffer *out,
20503  struct nk_rect bounds, const char *str, int len, nk_flags align, int *value,
20504  const struct nk_style_selectable *style, const struct nk_input *in,
20505  const struct nk_user_font *font)
20506 {
20507  int old_value;
20508  struct nk_rect touch;
20509 
20510  NK_ASSERT(state);
20511  NK_ASSERT(out);
20512  NK_ASSERT(str);
20513  NK_ASSERT(len);
20514  NK_ASSERT(value);
20515  NK_ASSERT(style);
20516  NK_ASSERT(font);
20517 
20518  if (!state || !out || !str || !len || !value || !style || !font) return 0;
20519  old_value = *value;
20520 
20521  /* remove padding */
20522  touch.x = bounds.x - style->touch_padding.x;
20523  touch.y = bounds.y - style->touch_padding.y;
20524  touch.w = bounds.w + style->touch_padding.x * 2;
20525  touch.h = bounds.h + style->touch_padding.y * 2;
20526 
20527  /* update button */
20528  if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
20529  *value = !(*value);
20530 
20531  /* draw selectable */
20532  if (style->draw_begin) style->draw_begin(out, style->userdata);
20533  nk_draw_selectable(out, *state, style, *value, &bounds, 0,0,NK_SYMBOL_NONE, str, len, align, font);
20534  if (style->draw_end) style->draw_end(out, style->userdata);
20535  return old_value != *value;
20536 }
20537 NK_LIB int
20538 nk_do_selectable_image(nk_flags *state, struct nk_command_buffer *out,
20539  struct nk_rect bounds, const char *str, int len, nk_flags align, int *value,
20540  const struct nk_image *img, const struct nk_style_selectable *style,
20541  const struct nk_input *in, const struct nk_user_font *font)
20542 {
20543  int old_value;
20544  struct nk_rect touch;
20545  struct nk_rect icon;
20546 
20547  NK_ASSERT(state);
20548  NK_ASSERT(out);
20549  NK_ASSERT(str);
20550  NK_ASSERT(len);
20551  NK_ASSERT(value);
20552  NK_ASSERT(style);
20553  NK_ASSERT(font);
20554 
20555  if (!state || !out || !str || !len || !value || !style || !font) return 0;
20556  old_value = *value;
20557 
20558  /* toggle behavior */
20559  touch.x = bounds.x - style->touch_padding.x;
20560  touch.y = bounds.y - style->touch_padding.y;
20561  touch.w = bounds.w + style->touch_padding.x * 2;
20562  touch.h = bounds.h + style->touch_padding.y * 2;
20563  if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
20564  *value = !(*value);
20565 
20566  icon.y = bounds.y + style->padding.y;
20567  icon.w = icon.h = bounds.h - 2 * style->padding.y;
20568  if (align & NK_TEXT_ALIGN_LEFT) {
20569  icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
20570  icon.x = NK_MAX(icon.x, 0);
20571  } else icon.x = bounds.x + 2 * style->padding.x;
20572 
20573  icon.x += style->image_padding.x;
20574  icon.y += style->image_padding.y;
20575  icon.w -= 2 * style->image_padding.x;
20576  icon.h -= 2 * style->image_padding.y;
20577 
20578  /* draw selectable */
20579  if (style->draw_begin) style->draw_begin(out, style->userdata);
20580  nk_draw_selectable(out, *state, style, *value, &bounds, &icon, img, NK_SYMBOL_NONE, str, len, align, font);
20581  if (style->draw_end) style->draw_end(out, style->userdata);
20582  return old_value != *value;
20583 }
20584 NK_LIB int
20585 nk_do_selectable_symbol(nk_flags *state, struct nk_command_buffer *out,
20586  struct nk_rect bounds, const char *str, int len, nk_flags align, int *value,
20587  enum nk_symbol_type sym, const struct nk_style_selectable *style,
20588  const struct nk_input *in, const struct nk_user_font *font)
20589 {
20590  int old_value;
20591  struct nk_rect touch;
20592  struct nk_rect icon;
20593 
20594  NK_ASSERT(state);
20595  NK_ASSERT(out);
20596  NK_ASSERT(str);
20597  NK_ASSERT(len);
20598  NK_ASSERT(value);
20599  NK_ASSERT(style);
20600  NK_ASSERT(font);
20601 
20602  if (!state || !out || !str || !len || !value || !style || !font) return 0;
20603  old_value = *value;
20604 
20605  /* toggle behavior */
20606  touch.x = bounds.x - style->touch_padding.x;
20607  touch.y = bounds.y - style->touch_padding.y;
20608  touch.w = bounds.w + style->touch_padding.x * 2;
20609  touch.h = bounds.h + style->touch_padding.y * 2;
20610  if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
20611  *value = !(*value);
20612 
20613  icon.y = bounds.y + style->padding.y;
20614  icon.w = icon.h = bounds.h - 2 * style->padding.y;
20615  if (align & NK_TEXT_ALIGN_LEFT) {
20616  icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
20617  icon.x = NK_MAX(icon.x, 0);
20618  } else icon.x = bounds.x + 2 * style->padding.x;
20619 
20620  icon.x += style->image_padding.x;
20621  icon.y += style->image_padding.y;
20622  icon.w -= 2 * style->image_padding.x;
20623  icon.h -= 2 * style->image_padding.y;
20624 
20625  /* draw selectable */
20626  if (style->draw_begin) style->draw_begin(out, style->userdata);
20627  nk_draw_selectable(out, *state, style, *value, &bounds, &icon, 0, sym, str, len, align, font);
20628  if (style->draw_end) style->draw_end(out, style->userdata);
20629  return old_value != *value;
20630 }
20631 
20632 NK_API int
20633 nk_selectable_text(struct nk_context *ctx, const char *str, int len,
20634  nk_flags align, int *value)
20635 {
20636  struct nk_window *win;
20637  struct nk_panel *layout;
20638  const struct nk_input *in;
20639  const struct nk_style *style;
20640 
20642  struct nk_rect bounds;
20643 
20644  NK_ASSERT(ctx);
20645  NK_ASSERT(value);
20646  NK_ASSERT(ctx->current);
20647  NK_ASSERT(ctx->current->layout);
20648  if (!ctx || !ctx->current || !ctx->current->layout || !value)
20649  return 0;
20650 
20651  win = ctx->current;
20652  layout = win->layout;
20653  style = &ctx->style;
20654 
20655  state = nk_widget(&bounds, ctx);
20656  if (!state) return 0;
20657  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20658  return nk_do_selectable(&ctx->last_widget_state, &win->buffer, bounds,
20659  str, len, align, value, &style->selectable, in, style->font);
20660 }
20661 NK_API int
20662 nk_selectable_image_text(struct nk_context *ctx, struct nk_image img,
20663  const char *str, int len, nk_flags align, int *value)
20664 {
20665  struct nk_window *win;
20666  struct nk_panel *layout;
20667  const struct nk_input *in;
20668  const struct nk_style *style;
20669 
20671  struct nk_rect bounds;
20672 
20673  NK_ASSERT(ctx);
20674  NK_ASSERT(value);
20675  NK_ASSERT(ctx->current);
20676  NK_ASSERT(ctx->current->layout);
20677  if (!ctx || !ctx->current || !ctx->current->layout || !value)
20678  return 0;
20679 
20680  win = ctx->current;
20681  layout = win->layout;
20682  style = &ctx->style;
20683 
20684  state = nk_widget(&bounds, ctx);
20685  if (!state) return 0;
20686  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20687  return nk_do_selectable_image(&ctx->last_widget_state, &win->buffer, bounds,
20688  str, len, align, value, &img, &style->selectable, in, style->font);
20689 }
20690 NK_API int
20691 nk_selectable_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym,
20692  const char *str, int len, nk_flags align, int *value)
20693 {
20694  struct nk_window *win;
20695  struct nk_panel *layout;
20696  const struct nk_input *in;
20697  const struct nk_style *style;
20698 
20700  struct nk_rect bounds;
20701 
20702  NK_ASSERT(ctx);
20703  NK_ASSERT(value);
20704  NK_ASSERT(ctx->current);
20705  NK_ASSERT(ctx->current->layout);
20706  if (!ctx || !ctx->current || !ctx->current->layout || !value)
20707  return 0;
20708 
20709  win = ctx->current;
20710  layout = win->layout;
20711  style = &ctx->style;
20712 
20713  state = nk_widget(&bounds, ctx);
20714  if (!state) return 0;
20715  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20716  return nk_do_selectable_symbol(&ctx->last_widget_state, &win->buffer, bounds,
20717  str, len, align, value, sym, &style->selectable, in, style->font);
20718 }
20719 NK_API int
20720 nk_selectable_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym,
20721  const char *title, nk_flags align, int *value)
20722 {
20723  return nk_selectable_symbol_text(ctx, sym, title, nk_strlen(title), align, value);
20724 }
20725 NK_API int nk_select_text(struct nk_context *ctx, const char *str, int len,
20726  nk_flags align, int value)
20727 {
20728  nk_selectable_text(ctx, str, len, align, &value);return value;
20729 }
20730 NK_API int nk_selectable_label(struct nk_context *ctx, const char *str, nk_flags align, int *value)
20731 {
20732  return nk_selectable_text(ctx, str, nk_strlen(str), align, value);
20733 }
20734 NK_API int nk_selectable_image_label(struct nk_context *ctx,struct nk_image img,
20735  const char *str, nk_flags align, int *value)
20736 {
20737  return nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, value);
20738 }
20739 NK_API int nk_select_label(struct nk_context *ctx, const char *str, nk_flags align, int value)
20740 {
20741  nk_selectable_text(ctx, str, nk_strlen(str), align, &value);return value;
20742 }
20743 NK_API int nk_select_image_label(struct nk_context *ctx, struct nk_image img,
20744  const char *str, nk_flags align, int value)
20745 {
20746  nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, &value);return value;
20747 }
20748 NK_API int nk_select_image_text(struct nk_context *ctx, struct nk_image img,
20749  const char *str, int len, nk_flags align, int value)
20750 {
20751  nk_selectable_image_text(ctx, img, str, len, align, &value);return value;
20752 }
20753 NK_API int
20754 nk_select_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym,
20755  const char *title, int title_len, nk_flags align, int value)
20756 {
20757  nk_selectable_symbol_text(ctx, sym, title, title_len, align, &value);return value;
20758 }
20759 NK_API int
20760 nk_select_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym,
20761  const char *title, nk_flags align, int value)
20762 {
20763  return nk_select_symbol_text(ctx, sym, title, nk_strlen(title), align, value);
20764 }
20765 
20766 
20767 
20768 
20769 
20770 /* ===============================================================
20771  *
20772  * SLIDER
20773  *
20774  * ===============================================================*/
20775 NK_LIB float
20776 nk_slider_behavior(nk_flags *state, struct nk_rect *logical_cursor,
20777  struct nk_rect *visual_cursor, struct nk_input *in,
20778  struct nk_rect bounds, float slider_min, float slider_max, float slider_value,
20779  float slider_step, float slider_steps)
20780 {
20781  int left_mouse_down;
20782  int left_mouse_click_in_cursor;
20783 
20784  /* check if visual cursor is being dragged */
20785  nk_widget_state_reset(state);
20786  left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
20787  left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
20788  NK_BUTTON_LEFT, *visual_cursor, nk_true);
20789 
20790  if (left_mouse_down && left_mouse_click_in_cursor) {
20791  float ratio = 0;
20792  const float d = in->mouse.pos.x - (visual_cursor->x+visual_cursor->w*0.5f);
20793  const float pxstep = bounds.w / slider_steps;
20794 
20795  /* only update value if the next slider step is reached */
20796  *state = NK_WIDGET_STATE_ACTIVE;
20797  if (NK_ABS(d) >= pxstep) {
20798  const float steps = (float)((int)(NK_ABS(d) / pxstep));
20799  slider_value += (d > 0) ? (slider_step*steps) : -(slider_step*steps);
20800  slider_value = NK_CLAMP(slider_min, slider_value, slider_max);
20801  ratio = (slider_value - slider_min)/slider_step;
20802  logical_cursor->x = bounds.x + (logical_cursor->w * ratio);
20803  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = logical_cursor->x;
20804  }
20805  }
20806 
20807  /* slider widget state */
20808  if (nk_input_is_mouse_hovering_rect(in, bounds))
20809  *state = NK_WIDGET_STATE_HOVERED;
20810  if (*state & NK_WIDGET_STATE_HOVER &&
20812  *state |= NK_WIDGET_STATE_ENTERED;
20813  else if (nk_input_is_mouse_prev_hovering_rect(in, bounds))
20814  *state |= NK_WIDGET_STATE_LEFT;
20815  return slider_value;
20816 }
20817 NK_LIB void
20818 nk_draw_slider(struct nk_command_buffer *out, nk_flags state,
20819  const struct nk_style_slider *style, const struct nk_rect *bounds,
20820  const struct nk_rect *visual_cursor, float min, float value, float max)
20821 {
20822  struct nk_rect fill;
20823  struct nk_rect bar;
20824  const struct nk_style_item *background;
20825 
20826  /* select correct slider images/colors */
20827  struct nk_color bar_color;
20828  const struct nk_style_item *cursor;
20829 
20830  NK_UNUSED(min);
20831  NK_UNUSED(max);
20832  NK_UNUSED(value);
20833 
20834  if (state & NK_WIDGET_STATE_ACTIVED) {
20835  background = &style->active;
20836  bar_color = style->bar_active;
20837  cursor = &style->cursor_active;
20838  } else if (state & NK_WIDGET_STATE_HOVER) {
20839  background = &style->hover;
20840  bar_color = style->bar_hover;
20841  cursor = &style->cursor_hover;
20842  } else {
20843  background = &style->normal;
20844  bar_color = style->bar_normal;
20845  cursor = &style->cursor_normal;
20846  }
20847  /* calculate slider background bar */
20848  bar.x = bounds->x;
20849  bar.y = (visual_cursor->y + visual_cursor->h/2) - bounds->h/12;
20850  bar.w = bounds->w;
20851  bar.h = bounds->h/6;
20852 
20853  /* filled background bar style */
20854  fill.w = (visual_cursor->x + (visual_cursor->w/2.0f)) - bar.x;
20855  fill.x = bar.x;
20856  fill.y = bar.y;
20857  fill.h = bar.h;
20858 
20859  /* draw background */
20860  if (background->type == NK_STYLE_ITEM_IMAGE) {
20861  nk_draw_image(out, *bounds, &background->data.image, nk_white);
20862  } else {
20863  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
20864  nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
20865  }
20866 
20867  /* draw slider bar */
20868  nk_fill_rect(out, bar, style->rounding, bar_color);
20869  nk_fill_rect(out, fill, style->rounding, style->bar_filled);
20870 
20871  /* draw cursor */
20872  if (cursor->type == NK_STYLE_ITEM_IMAGE)
20873  nk_draw_image(out, *visual_cursor, &cursor->data.image, nk_white);
20874  else nk_fill_circle(out, *visual_cursor, cursor->data.color);
20875 }
20876 NK_LIB float
20877 nk_do_slider(nk_flags *state,
20878  struct nk_command_buffer *out, struct nk_rect bounds,
20879  float min, float val, float max, float step,
20880  const struct nk_style_slider *style, struct nk_input *in,
20881  const struct nk_user_font *font)
20882 {
20883  float slider_range;
20884  float slider_min;
20885  float slider_max;
20886  float slider_value;
20887  float slider_steps;
20888  float cursor_offset;
20889 
20890  struct nk_rect visual_cursor;
20891  struct nk_rect logical_cursor;
20892 
20893  NK_ASSERT(style);
20894  NK_ASSERT(out);
20895  if (!out || !style)
20896  return 0;
20897 
20898  /* remove padding from slider bounds */
20899  bounds.x = bounds.x + style->padding.x;
20900  bounds.y = bounds.y + style->padding.y;
20901  bounds.h = NK_MAX(bounds.h, 2*style->padding.y);
20902  bounds.w = NK_MAX(bounds.w, 2*style->padding.x + style->cursor_size.x);
20903  bounds.w -= 2 * style->padding.x;
20904  bounds.h -= 2 * style->padding.y;
20905 
20906  /* optional buttons */
20907  if (style->show_buttons) {
20908  nk_flags ws;
20909  struct nk_rect button;
20910  button.y = bounds.y;
20911  button.w = bounds.h;
20912  button.h = bounds.h;
20913 
20914  /* decrement button */
20915  button.x = bounds.x;
20916  if (nk_do_button_symbol(&ws, out, button, style->dec_symbol, NK_BUTTON_DEFAULT,
20917  &style->dec_button, in, font))
20918  val -= step;
20919 
20920  /* increment button */
20921  button.x = (bounds.x + bounds.w) - button.w;
20922  if (nk_do_button_symbol(&ws, out, button, style->inc_symbol, NK_BUTTON_DEFAULT,
20923  &style->inc_button, in, font))
20924  val += step;
20925 
20926  bounds.x = bounds.x + button.w + style->spacing.x;
20927  bounds.w = bounds.w - (2*button.w + 2*style->spacing.x);
20928  }
20929 
20930  /* remove one cursor size to support visual cursor */
20931  bounds.x += style->cursor_size.x*0.5f;
20932  bounds.w -= style->cursor_size.x;
20933 
20934  /* make sure the provided values are correct */
20935  slider_max = NK_MAX(min, max);
20936  slider_min = NK_MIN(min, max);
20937  slider_value = NK_CLAMP(slider_min, val, slider_max);
20938  slider_range = slider_max - slider_min;
20939  slider_steps = slider_range / step;
20940  cursor_offset = (slider_value - slider_min) / step;
20941 
20942  /* calculate cursor
20943  Basically you have two cursors. One for visual representation and interaction
20944  and one for updating the actual cursor value. */
20945  logical_cursor.h = bounds.h;
20946  logical_cursor.w = bounds.w / slider_steps;
20947  logical_cursor.x = bounds.x + (logical_cursor.w * cursor_offset);
20948  logical_cursor.y = bounds.y;
20949 
20950  visual_cursor.h = style->cursor_size.y;
20951  visual_cursor.w = style->cursor_size.x;
20952  visual_cursor.y = (bounds.y + bounds.h*0.5f) - visual_cursor.h*0.5f;
20953  visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f;
20954 
20955  slider_value = nk_slider_behavior(state, &logical_cursor, &visual_cursor,
20956  in, bounds, slider_min, slider_max, slider_value, step, slider_steps);
20957  visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f;
20958 
20959  /* draw slider */
20960  if (style->draw_begin) style->draw_begin(out, style->userdata);
20961  nk_draw_slider(out, *state, style, &bounds, &visual_cursor, slider_min, slider_value, slider_max);
20962  if (style->draw_end) style->draw_end(out, style->userdata);
20963  return slider_value;
20964 }
20965 NK_API int
20966 nk_slider_float(struct nk_context *ctx, float min_value, float *value, float max_value,
20967  float value_step)
20968 {
20969  struct nk_window *win;
20970  struct nk_panel *layout;
20971  struct nk_input *in;
20972  const struct nk_style *style;
20973 
20974  int ret = 0;
20975  float old_value;
20976  struct nk_rect bounds;
20978 
20979  NK_ASSERT(ctx);
20980  NK_ASSERT(ctx->current);
20981  NK_ASSERT(ctx->current->layout);
20982  NK_ASSERT(value);
20983  if (!ctx || !ctx->current || !ctx->current->layout || !value)
20984  return ret;
20985 
20986  win = ctx->current;
20987  style = &ctx->style;
20988  layout = win->layout;
20989 
20990  state = nk_widget(&bounds, ctx);
20991  if (!state) return ret;
20992  in = (/*state == NK_WIDGET_ROM || */ layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20993 
20994  old_value = *value;
20995  *value = nk_do_slider(&ctx->last_widget_state, &win->buffer, bounds, min_value,
20996  old_value, max_value, value_step, &style->slider, in, style->font);
20997  return (old_value > *value || old_value < *value);
20998 }
20999 NK_API float
21000 nk_slide_float(struct nk_context *ctx, float min, float val, float max, float step)
21001 {
21002  nk_slider_float(ctx, min, &val, max, step); return val;
21003 }
21004 NK_API int
21005 nk_slide_int(struct nk_context *ctx, int min, int val, int max, int step)
21006 {
21007  float value = (float)val;
21008  nk_slider_float(ctx, (float)min, &value, (float)max, (float)step);
21009  return (int)value;
21010 }
21011 NK_API int
21012 nk_slider_int(struct nk_context *ctx, int min, int *val, int max, int step)
21013 {
21014  int ret;
21015  float value = (float)*val;
21016  ret = nk_slider_float(ctx, (float)min, &value, (float)max, (float)step);
21017  *val = (int)value;
21018  return ret;
21019 }
21020 
21021 
21022 
21023 
21024 
21025 /* ===============================================================
21026  *
21027  * PROGRESS
21028  *
21029  * ===============================================================*/
21030 NK_LIB nk_size
21031 nk_progress_behavior(nk_flags *state, struct nk_input *in,
21032  struct nk_rect r, struct nk_rect cursor, nk_size max, nk_size value, int modifiable)
21033 {
21034  int left_mouse_down = 0;
21035  int left_mouse_click_in_cursor = 0;
21036 
21037  nk_widget_state_reset(state);
21038  if (!in || !modifiable) return value;
21039  left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
21040  left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
21041  NK_BUTTON_LEFT, cursor, nk_true);
21043  *state = NK_WIDGET_STATE_HOVERED;
21044 
21045  if (in && left_mouse_down && left_mouse_click_in_cursor) {
21046  if (left_mouse_down && left_mouse_click_in_cursor) {
21047  float ratio = NK_MAX(0, (float)(in->mouse.pos.x - cursor.x)) / (float)cursor.w;
21048  value = (nk_size)NK_CLAMP(0, (float)max * ratio, (float)max);
21049  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor.x + cursor.w/2.0f;
21050  *state |= NK_WIDGET_STATE_ACTIVE;
21051  }
21052  }
21053  /* set progressbar widget state */
21054  if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, r))
21055  *state |= NK_WIDGET_STATE_ENTERED;
21056  else if (nk_input_is_mouse_prev_hovering_rect(in, r))
21057  *state |= NK_WIDGET_STATE_LEFT;
21058  return value;
21059 }
21060 NK_LIB void
21061 nk_draw_progress(struct nk_command_buffer *out, nk_flags state,
21062  const struct nk_style_progress *style, const struct nk_rect *bounds,
21063  const struct nk_rect *scursor, nk_size value, nk_size max)
21064 {
21065  const struct nk_style_item *background;
21066  const struct nk_style_item *cursor;
21067 
21068  NK_UNUSED(max);
21069  NK_UNUSED(value);
21070 
21071  /* select correct colors/images to draw */
21072  if (state & NK_WIDGET_STATE_ACTIVED) {
21073  background = &style->active;
21074  cursor = &style->cursor_active;
21075  } else if (state & NK_WIDGET_STATE_HOVER){
21076  background = &style->hover;
21077  cursor = &style->cursor_hover;
21078  } else {
21079  background = &style->normal;
21080  cursor = &style->cursor_normal;
21081  }
21082 
21083  /* draw background */
21084  if (background->type == NK_STYLE_ITEM_COLOR) {
21085  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
21086  nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
21087  } else nk_draw_image(out, *bounds, &background->data.image, nk_white);
21088 
21089  /* draw cursor */
21090  if (cursor->type == NK_STYLE_ITEM_COLOR) {
21091  nk_fill_rect(out, *scursor, style->rounding, cursor->data.color);
21092  nk_stroke_rect(out, *scursor, style->rounding, style->border, style->border_color);
21093  } else nk_draw_image(out, *scursor, &cursor->data.image, nk_white);
21094 }
21095 NK_LIB nk_size
21096 nk_do_progress(nk_flags *state,
21097  struct nk_command_buffer *out, struct nk_rect bounds,
21098  nk_size value, nk_size max, int modifiable,
21099  const struct nk_style_progress *style, struct nk_input *in)
21100 {
21101  float prog_scale;
21102  nk_size prog_value;
21103  struct nk_rect cursor;
21104 
21105  NK_ASSERT(style);
21106  NK_ASSERT(out);
21107  if (!out || !style) return 0;
21108 
21109  /* calculate progressbar cursor */
21110  cursor.w = NK_MAX(bounds.w, 2 * style->padding.x + 2 * style->border);
21111  cursor.h = NK_MAX(bounds.h, 2 * style->padding.y + 2 * style->border);
21112  cursor = nk_pad_rect(bounds, nk_vec2(style->padding.x + style->border, style->padding.y + style->border));
21113  prog_scale = (float)value / (float)max;
21114 
21115  /* update progressbar */
21116  prog_value = NK_MIN(value, max);
21117  prog_value = nk_progress_behavior(state, in, bounds, cursor,max, prog_value, modifiable);
21118  cursor.w = cursor.w * prog_scale;
21119 
21120  /* draw progressbar */
21121  if (style->draw_begin) style->draw_begin(out, style->userdata);
21122  nk_draw_progress(out, *state, style, &bounds, &cursor, value, max);
21123  if (style->draw_end) style->draw_end(out, style->userdata);
21124  return prog_value;
21125 }
21126 NK_API int
21127 nk_progress(struct nk_context *ctx, nk_size *cur, nk_size max, int is_modifyable)
21128 {
21129  struct nk_window *win;
21130  struct nk_panel *layout;
21131  const struct nk_style *style;
21132  struct nk_input *in;
21133 
21134  struct nk_rect bounds;
21136  nk_size old_value;
21137 
21138  NK_ASSERT(ctx);
21139  NK_ASSERT(cur);
21140  NK_ASSERT(ctx->current);
21141  NK_ASSERT(ctx->current->layout);
21142  if (!ctx || !ctx->current || !ctx->current->layout || !cur)
21143  return 0;
21144 
21145  win = ctx->current;
21146  style = &ctx->style;
21147  layout = win->layout;
21148  state = nk_widget(&bounds, ctx);
21149  if (!state) return 0;
21150 
21151  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
21152  old_value = *cur;
21153  *cur = nk_do_progress(&ctx->last_widget_state, &win->buffer, bounds,
21154  *cur, max, is_modifyable, &style->progress, in);
21155  return (*cur != old_value);
21156 }
21157 NK_API nk_size
21158 nk_prog(struct nk_context *ctx, nk_size cur, nk_size max, int modifyable)
21159 {
21160  nk_progress(ctx, &cur, max, modifyable);
21161  return cur;
21162 }
21163 
21164 
21165 
21166 
21167 
21168 /* ===============================================================
21169  *
21170  * SCROLLBAR
21171  *
21172  * ===============================================================*/
21173 NK_LIB float
21174 nk_scrollbar_behavior(nk_flags *state, struct nk_input *in,
21175  int has_scrolling, const struct nk_rect *scroll,
21176  const struct nk_rect *cursor, const struct nk_rect *empty0,
21177  const struct nk_rect *empty1, float scroll_offset,
21178  float target, float scroll_step, enum nk_orientation o)
21179 {
21180  nk_flags ws = 0;
21181  int left_mouse_down;
21182  int left_mouse_click_in_cursor;
21183  float scroll_delta;
21184 
21185  nk_widget_state_reset(state);
21186  if (!in) return scroll_offset;
21187 
21188  left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
21189  left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
21190  NK_BUTTON_LEFT, *cursor, nk_true);
21191  if (nk_input_is_mouse_hovering_rect(in, *scroll))
21192  *state = NK_WIDGET_STATE_HOVERED;
21193 
21194  scroll_delta = (o == NK_VERTICAL) ? in->mouse.scroll_delta.y: in->mouse.scroll_delta.x;
21195  if (left_mouse_down && left_mouse_click_in_cursor) {
21196  /* update cursor by mouse dragging */
21197  float pixel, delta;
21198  *state = NK_WIDGET_STATE_ACTIVE;
21199  if (o == NK_VERTICAL) {
21200  float cursor_y;
21201  pixel = in->mouse.delta.y;
21202  delta = (pixel / scroll->h) * target;
21203  scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->h);
21204  cursor_y = scroll->y + ((scroll_offset/target) * scroll->h);
21205  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = cursor_y + cursor->h/2.0f;
21206  } else {
21207  float cursor_x;
21208  pixel = in->mouse.delta.x;
21209  delta = (pixel / scroll->w) * target;
21210  scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->w);
21211  cursor_x = scroll->x + ((scroll_offset/target) * scroll->w);
21212  in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor_x + cursor->w/2.0f;
21213  }
21214  } else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_UP) && o == NK_VERTICAL && has_scrolling)||
21215  nk_button_behavior(&ws, *empty0, in, NK_BUTTON_DEFAULT)) {
21216  /* scroll page up by click on empty space or shortcut */
21217  if (o == NK_VERTICAL)
21218  scroll_offset = NK_MAX(0, scroll_offset - scroll->h);
21219  else scroll_offset = NK_MAX(0, scroll_offset - scroll->w);
21220  } else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_DOWN) && o == NK_VERTICAL && has_scrolling) ||
21221  nk_button_behavior(&ws, *empty1, in, NK_BUTTON_DEFAULT)) {
21222  /* scroll page down by click on empty space or shortcut */
21223  if (o == NK_VERTICAL)
21224  scroll_offset = NK_MIN(scroll_offset + scroll->h, target - scroll->h);
21225  else scroll_offset = NK_MIN(scroll_offset + scroll->w, target - scroll->w);
21226  } else if (has_scrolling) {
21227  if ((scroll_delta < 0 || (scroll_delta > 0))) {
21228  /* update cursor by mouse scrolling */
21229  scroll_offset = scroll_offset + scroll_step * (-scroll_delta);
21230  if (o == NK_VERTICAL)
21231  scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->h);
21232  else scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->w);
21233  } else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_START)) {
21234  /* update cursor to the beginning */
21235  if (o == NK_VERTICAL) scroll_offset = 0;
21236  } else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_END)) {
21237  /* update cursor to the end */
21238  if (o == NK_VERTICAL) scroll_offset = target - scroll->h;
21239  }
21240  }
21241  if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *scroll))
21242  *state |= NK_WIDGET_STATE_ENTERED;
21243  else if (nk_input_is_mouse_prev_hovering_rect(in, *scroll))
21244  *state |= NK_WIDGET_STATE_LEFT;
21245  return scroll_offset;
21246 }
21247 NK_LIB void
21248 nk_draw_scrollbar(struct nk_command_buffer *out, nk_flags state,
21249  const struct nk_style_scrollbar *style, const struct nk_rect *bounds,
21250  const struct nk_rect *scroll)
21251 {
21252  const struct nk_style_item *background;
21253  const struct nk_style_item *cursor;
21254 
21255  /* select correct colors/images to draw */
21256  if (state & NK_WIDGET_STATE_ACTIVED) {
21257  background = &style->active;
21258  cursor = &style->cursor_active;
21259  } else if (state & NK_WIDGET_STATE_HOVER) {
21260  background = &style->hover;
21261  cursor = &style->cursor_hover;
21262  } else {
21263  background = &style->normal;
21264  cursor = &style->cursor_normal;
21265  }
21266 
21267  /* draw background */
21268  if (background->type == NK_STYLE_ITEM_COLOR) {
21269  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
21270  nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
21271  } else {
21272  nk_draw_image(out, *bounds, &background->data.image, nk_white);
21273  }
21274 
21275  /* draw cursor */
21276  if (cursor->type == NK_STYLE_ITEM_COLOR) {
21277  nk_fill_rect(out, *scroll, style->rounding_cursor, cursor->data.color);
21278  nk_stroke_rect(out, *scroll, style->rounding_cursor, style->border_cursor, style->cursor_border_color);
21279  } else nk_draw_image(out, *scroll, &cursor->data.image, nk_white);
21280 }
21281 NK_LIB float
21282 nk_do_scrollbarv(nk_flags *state,
21283  struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling,
21284  float offset, float target, float step, float button_pixel_inc,
21285  const struct nk_style_scrollbar *style, struct nk_input *in,
21286  const struct nk_user_font *font)
21287 {
21288  struct nk_rect empty_north;
21289  struct nk_rect empty_south;
21290  struct nk_rect cursor;
21291 
21292  float scroll_step;
21293  float scroll_offset;
21294  float scroll_off;
21295  float scroll_ratio;
21296 
21297  NK_ASSERT(out);
21298  NK_ASSERT(style);
21299  NK_ASSERT(state);
21300  if (!out || !style) return 0;
21301 
21302  scroll.w = NK_MAX(scroll.w, 1);
21303  scroll.h = NK_MAX(scroll.h, 0);
21304  if (target <= scroll.h) return 0;
21305 
21306  /* optional scrollbar buttons */
21307  if (style->show_buttons) {
21308  nk_flags ws;
21309  float scroll_h;
21310  struct nk_rect button;
21311 
21312  button.x = scroll.x;
21313  button.w = scroll.w;
21314  button.h = scroll.w;
21315 
21316  scroll_h = NK_MAX(scroll.h - 2 * button.h,0);
21317  scroll_step = NK_MIN(step, button_pixel_inc);
21318 
21319  /* decrement button */
21320  button.y = scroll.y;
21321  if (nk_do_button_symbol(&ws, out, button, style->dec_symbol,
21322  NK_BUTTON_REPEATER, &style->dec_button, in, font))
21323  offset = offset - scroll_step;
21324 
21325  /* increment button */
21326  button.y = scroll.y + scroll.h - button.h;
21327  if (nk_do_button_symbol(&ws, out, button, style->inc_symbol,
21328  NK_BUTTON_REPEATER, &style->inc_button, in, font))
21329  offset = offset + scroll_step;
21330 
21331  scroll.y = scroll.y + button.h;
21332  scroll.h = scroll_h;
21333  }
21334 
21335  /* calculate scrollbar constants */
21336  scroll_step = NK_MIN(step, scroll.h);
21337  scroll_offset = NK_CLAMP(0, offset, target - scroll.h);
21338  scroll_ratio = scroll.h / target;
21339  scroll_off = scroll_offset / target;
21340 
21341  /* calculate scrollbar cursor bounds */
21342  cursor.h = NK_MAX((scroll_ratio * scroll.h) - (2*style->border + 2*style->padding.y), 0);
21343  cursor.y = scroll.y + (scroll_off * scroll.h) + style->border + style->padding.y;
21344  cursor.w = scroll.w - (2 * style->border + 2 * style->padding.x);
21345  cursor.x = scroll.x + style->border + style->padding.x;
21346 
21347  /* calculate empty space around cursor */
21348  empty_north.x = scroll.x;
21349  empty_north.y = scroll.y;
21350  empty_north.w = scroll.w;
21351  empty_north.h = NK_MAX(cursor.y - scroll.y, 0);
21352 
21353  empty_south.x = scroll.x;
21354  empty_south.y = cursor.y + cursor.h;
21355  empty_south.w = scroll.w;
21356  empty_south.h = NK_MAX((scroll.y + scroll.h) - (cursor.y + cursor.h), 0);
21357 
21358  /* update scrollbar */
21359  scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
21360  &empty_north, &empty_south, scroll_offset, target, scroll_step, NK_VERTICAL);
21361  scroll_off = scroll_offset / target;
21362  cursor.y = scroll.y + (scroll_off * scroll.h) + style->border_cursor + style->padding.y;
21363 
21364  /* draw scrollbar */
21365  if (style->draw_begin) style->draw_begin(out, style->userdata);
21366  nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
21367  if (style->draw_end) style->draw_end(out, style->userdata);
21368  return scroll_offset;
21369 }
21370 NK_LIB float
21371 nk_do_scrollbarh(nk_flags *state,
21372  struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling,
21373  float offset, float target, float step, float button_pixel_inc,
21374  const struct nk_style_scrollbar *style, struct nk_input *in,
21375  const struct nk_user_font *font)
21376 {
21377  struct nk_rect cursor;
21378  struct nk_rect empty_west;
21379  struct nk_rect empty_east;
21380 
21381  float scroll_step;
21382  float scroll_offset;
21383  float scroll_off;
21384  float scroll_ratio;
21385 
21386  NK_ASSERT(out);
21387  NK_ASSERT(style);
21388  if (!out || !style) return 0;
21389 
21390  /* scrollbar background */
21391  scroll.h = NK_MAX(scroll.h, 1);
21392  scroll.w = NK_MAX(scroll.w, 2 * scroll.h);
21393  if (target <= scroll.w) return 0;
21394 
21395  /* optional scrollbar buttons */
21396  if (style->show_buttons) {
21397  nk_flags ws;
21398  float scroll_w;
21399  struct nk_rect button;
21400  button.y = scroll.y;
21401  button.w = scroll.h;
21402  button.h = scroll.h;
21403 
21404  scroll_w = scroll.w - 2 * button.w;
21405  scroll_step = NK_MIN(step, button_pixel_inc);
21406 
21407  /* decrement button */
21408  button.x = scroll.x;
21409  if (nk_do_button_symbol(&ws, out, button, style->dec_symbol,
21410  NK_BUTTON_REPEATER, &style->dec_button, in, font))
21411  offset = offset - scroll_step;
21412 
21413  /* increment button */
21414  button.x = scroll.x + scroll.w - button.w;
21415  if (nk_do_button_symbol(&ws, out, button, style->inc_symbol,
21416  NK_BUTTON_REPEATER, &style->inc_button, in, font))
21417  offset = offset + scroll_step;
21418 
21419  scroll.x = scroll.x + button.w;
21420  scroll.w = scroll_w;
21421  }
21422 
21423  /* calculate scrollbar constants */
21424  scroll_step = NK_MIN(step, scroll.w);
21425  scroll_offset = NK_CLAMP(0, offset, target - scroll.w);
21426  scroll_ratio = scroll.w / target;
21427  scroll_off = scroll_offset / target;
21428 
21429  /* calculate cursor bounds */
21430  cursor.w = (scroll_ratio * scroll.w) - (2*style->border + 2*style->padding.x);
21431  cursor.x = scroll.x + (scroll_off * scroll.w) + style->border + style->padding.x;
21432  cursor.h = scroll.h - (2 * style->border + 2 * style->padding.y);
21433  cursor.y = scroll.y + style->border + style->padding.y;
21434 
21435  /* calculate empty space around cursor */
21436  empty_west.x = scroll.x;
21437  empty_west.y = scroll.y;
21438  empty_west.w = cursor.x - scroll.x;
21439  empty_west.h = scroll.h;
21440 
21441  empty_east.x = cursor.x + cursor.w;
21442  empty_east.y = scroll.y;
21443  empty_east.w = (scroll.x + scroll.w) - (cursor.x + cursor.w);
21444  empty_east.h = scroll.h;
21445 
21446  /* update scrollbar */
21447  scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
21448  &empty_west, &empty_east, scroll_offset, target, scroll_step, NK_HORIZONTAL);
21449  scroll_off = scroll_offset / target;
21450  cursor.x = scroll.x + (scroll_off * scroll.w);
21451 
21452  /* draw scrollbar */
21453  if (style->draw_begin) style->draw_begin(out, style->userdata);
21454  nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
21455  if (style->draw_end) style->draw_end(out, style->userdata);
21456  return scroll_offset;
21457 }
21458 
21459 
21460 
21461 
21462 
21463 /* ===============================================================
21464  *
21465  * TEXT EDITOR
21466  *
21467  * ===============================================================*/
21468 /* stb_textedit.h - v1.8 - public domain - Sean Barrett */
21469 struct nk_text_find {
21470  float x,y; /* position of n'th character */
21471  float height; /* height of line */
21472  int first_char, length; /* first char of row, and length */
21473  int prev_first; /*_ first char of previous row */
21474 };
21475 
21476 struct nk_text_edit_row {
21477  float x0,x1;
21478  /* starting x location, end x location (allows for align=right, etc) */
21479  float baseline_y_delta;
21480  /* position of baseline relative to previous row's baseline*/
21481  float ymin,ymax;
21482  /* height of row above and below baseline */
21483  int num_chars;
21484 };
21485 
21486 /* forward declarations */
21487 NK_INTERN void nk_textedit_makeundo_delete(struct nk_text_edit*, int, int);
21488 NK_INTERN void nk_textedit_makeundo_insert(struct nk_text_edit*, int, int);
21489 NK_INTERN void nk_textedit_makeundo_replace(struct nk_text_edit*, int, int, int);
21490 #define NK_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
21491 
21492 NK_INTERN float
21493 nk_textedit_get_width(const struct nk_text_edit *edit, int line_start, int char_id,
21494  const struct nk_user_font *font)
21495 {
21496  int len = 0;
21497  nk_rune unicode = 0;
21498  const char *str = nk_str_at_const(&edit->string, line_start + char_id, &unicode, &len);
21499  return font->width(font->userdata, font->height, str, len);
21500 }
21501 NK_INTERN void
21502 nk_textedit_layout_row(struct nk_text_edit_row *r, struct nk_text_edit *edit,
21503  int line_start_id, float row_height, const struct nk_user_font *font)
21504 {
21505  int l;
21506  int glyphs = 0;
21507  nk_rune unicode;
21508  const char *remaining;
21509  int len = nk_str_len_char(&edit->string);
21510  const char *end = nk_str_get_const(&edit->string) + len;
21511  const char *text = nk_str_at_const(&edit->string, line_start_id, &unicode, &l);
21512  const struct nk_vec2 size = nk_text_calculate_text_bounds(font,
21513  text, (int)(end - text), row_height, &remaining, 0, &glyphs, NK_STOP_ON_NEW_LINE);
21514 
21515  r->x0 = 0.0f;
21516  r->x1 = size.x;
21517  r->baseline_y_delta = size.y;
21518  r->ymin = 0.0f;
21519  r->ymax = size.y;
21520  r->num_chars = glyphs;
21521 }
21522 NK_INTERN int
21523 nk_textedit_locate_coord(struct nk_text_edit *edit, float x, float y,
21524  const struct nk_user_font *font, float row_height)
21525 {
21526  struct nk_text_edit_row r;
21527  int n = edit->string.len;
21528  float base_y = 0, prev_x;
21529  int i=0, k;
21530 
21531  r.x0 = r.x1 = 0;
21532  r.ymin = r.ymax = 0;
21533  r.num_chars = 0;
21534 
21535  /* search rows to find one that straddles 'y' */
21536  while (i < n) {
21537  nk_textedit_layout_row(&r, edit, i, row_height, font);
21538  if (r.num_chars <= 0)
21539  return n;
21540 
21541  if (i==0 && y < base_y + r.ymin)
21542  return 0;
21543 
21544  if (y < base_y + r.ymax)
21545  break;
21546 
21547  i += r.num_chars;
21548  base_y += r.baseline_y_delta;
21549  }
21550 
21551  /* below all text, return 'after' last character */
21552  if (i >= n)
21553  return n;
21554 
21555  /* check if it's before the beginning of the line */
21556  if (x < r.x0)
21557  return i;
21558 
21559  /* check if it's before the end of the line */
21560  if (x < r.x1) {
21561  /* search characters in row for one that straddles 'x' */
21562  k = i;
21563  prev_x = r.x0;
21564  for (i=0; i < r.num_chars; ++i) {
21565  float w = nk_textedit_get_width(edit, k, i, font);
21566  if (x < prev_x+w) {
21567  if (x < prev_x+w/2)
21568  return k+i;
21569  else return k+i+1;
21570  }
21571  prev_x += w;
21572  }
21573  /* shouldn't happen, but if it does, fall through to end-of-line case */
21574  }
21575 
21576  /* if the last character is a newline, return that.
21577  * otherwise return 'after' the last character */
21578  if (nk_str_rune_at(&edit->string, i+r.num_chars-1) == '\n')
21579  return i+r.num_chars-1;
21580  else return i+r.num_chars;
21581 }
21582 NK_LIB void
21583 nk_textedit_click(struct nk_text_edit *state, float x, float y,
21584  const struct nk_user_font *font, float row_height)
21585 {
21586  /* API click: on mouse down, move the cursor to the clicked location,
21587  * and reset the selection */
21588  state->cursor = nk_textedit_locate_coord(state, x, y, font, row_height);
21589  state->select_start = state->cursor;
21590  state->select_end = state->cursor;
21591  state->has_preferred_x = 0;
21592 }
21593 NK_LIB void
21594 nk_textedit_drag(struct nk_text_edit *state, float x, float y,
21595  const struct nk_user_font *font, float row_height)
21596 {
21597  /* API drag: on mouse drag, move the cursor and selection endpoint
21598  * to the clicked location */
21599  int p = nk_textedit_locate_coord(state, x, y, font, row_height);
21600  if (state->select_start == state->select_end)
21601  state->select_start = state->cursor;
21602  state->cursor = state->select_end = p;
21603 }
21604 NK_INTERN void
21605 nk_textedit_find_charpos(struct nk_text_find *find, struct nk_text_edit *state,
21606  int n, int single_line, const struct nk_user_font *font, float row_height)
21607 {
21608  /* find the x/y location of a character, and remember info about the previous
21609  * row in case we get a move-up event (for page up, we'll have to rescan) */
21610  struct nk_text_edit_row r;
21611  int prev_start = 0;
21612  int z = state->string.len;
21613  int i=0, first;
21614 
21615  nk_zero_struct(r);
21616  if (n == z) {
21617  /* if it's at the end, then find the last line -- simpler than trying to
21618  explicitly handle this case in the regular code */
21619  nk_textedit_layout_row(&r, state, 0, row_height, font);
21620  if (single_line) {
21621  find->first_char = 0;
21622  find->length = z;
21623  } else {
21624  while (i < z) {
21625  prev_start = i;
21626  i += r.num_chars;
21627  nk_textedit_layout_row(&r, state, i, row_height, font);
21628  }
21629 
21630  find->first_char = i;
21631  find->length = r.num_chars;
21632  }
21633  find->x = r.x1;
21634  find->y = r.ymin;
21635  find->height = r.ymax - r.ymin;
21636  find->prev_first = prev_start;
21637  return;
21638  }
21639 
21640  /* search rows to find the one that straddles character n */
21641  find->y = 0;
21642 
21643  for(;;) {
21644  nk_textedit_layout_row(&r, state, i, row_height, font);
21645  if (n < i + r.num_chars) break;
21646  prev_start = i;
21647  i += r.num_chars;
21648  find->y += r.baseline_y_delta;
21649  }
21650 
21651  find->first_char = first = i;
21652  find->length = r.num_chars;
21653  find->height = r.ymax - r.ymin;
21654  find->prev_first = prev_start;
21655 
21656  /* now scan to find xpos */
21657  find->x = r.x0;
21658  for (i=0; first+i < n; ++i)
21659  find->x += nk_textedit_get_width(state, first, i, font);
21660 }
21661 NK_INTERN void
21662 nk_textedit_clamp(struct nk_text_edit *state)
21663 {
21664  /* make the selection/cursor state valid if client altered the string */
21665  int n = state->string.len;
21666  if (NK_TEXT_HAS_SELECTION(state)) {
21667  if (state->select_start > n) state->select_start = n;
21668  if (state->select_end > n) state->select_end = n;
21669  /* if clamping forced them to be equal, move the cursor to match */
21670  if (state->select_start == state->select_end)
21671  state->cursor = state->select_start;
21672  }
21673  if (state->cursor > n) state->cursor = n;
21674 }
21675 NK_API void
21676 nk_textedit_delete(struct nk_text_edit *state, int where, int len)
21677 {
21678  /* delete characters while updating undo */
21679  nk_textedit_makeundo_delete(state, where, len);
21680  nk_str_delete_runes(&state->string, where, len);
21681  state->has_preferred_x = 0;
21682 }
21683 NK_API void
21685 {
21686  /* delete the section */
21687  nk_textedit_clamp(state);
21688  if (NK_TEXT_HAS_SELECTION(state)) {
21689  if (state->select_start < state->select_end) {
21690  nk_textedit_delete(state, state->select_start,
21691  state->select_end - state->select_start);
21692  state->select_end = state->cursor = state->select_start;
21693  } else {
21694  nk_textedit_delete(state, state->select_end,
21695  state->select_start - state->select_end);
21696  state->select_start = state->cursor = state->select_end;
21697  }
21698  state->has_preferred_x = 0;
21699  }
21700 }
21701 NK_INTERN void
21702 nk_textedit_sortselection(struct nk_text_edit *state)
21703 {
21704  /* canonicalize the selection so start <= end */
21705  if (state->select_end < state->select_start) {
21706  int temp = state->select_end;
21707  state->select_end = state->select_start;
21708  state->select_start = temp;
21709  }
21710 }
21711 NK_INTERN void
21712 nk_textedit_move_to_first(struct nk_text_edit *state)
21713 {
21714  /* move cursor to first character of selection */
21715  if (NK_TEXT_HAS_SELECTION(state)) {
21716  nk_textedit_sortselection(state);
21717  state->cursor = state->select_start;
21718  state->select_end = state->select_start;
21719  state->has_preferred_x = 0;
21720  }
21721 }
21722 NK_INTERN void
21723 nk_textedit_move_to_last(struct nk_text_edit *state)
21724 {
21725  /* move cursor to last character of selection */
21726  if (NK_TEXT_HAS_SELECTION(state)) {
21727  nk_textedit_sortselection(state);
21728  nk_textedit_clamp(state);
21729  state->cursor = state->select_end;
21730  state->select_start = state->select_end;
21731  state->has_preferred_x = 0;
21732  }
21733 }
21734 NK_INTERN int
21735 nk_is_word_boundary( struct nk_text_edit *state, int idx)
21736 {
21737  int len;
21738  nk_rune c;
21739  if (idx <= 0) return 1;
21740  if (!nk_str_at_rune(&state->string, idx, &c, &len)) return 1;
21741  return (c == ' ' || c == '\t' ||c == 0x3000 || c == ',' || c == ';' ||
21742  c == '(' || c == ')' || c == '{' || c == '}' || c == '[' || c == ']' ||
21743  c == '|');
21744 }
21745 NK_INTERN int
21746 nk_textedit_move_to_word_previous(struct nk_text_edit *state)
21747 {
21748  int c = state->cursor - 1;
21749  while( c >= 0 && !nk_is_word_boundary(state, c))
21750  --c;
21751 
21752  if( c < 0 )
21753  c = 0;
21754 
21755  return c;
21756 }
21757 NK_INTERN int
21758 nk_textedit_move_to_word_next(struct nk_text_edit *state)
21759 {
21760  const int len = state->string.len;
21761  int c = state->cursor+1;
21762  while( c < len && !nk_is_word_boundary(state, c))
21763  ++c;
21764 
21765  if( c > len )
21766  c = len;
21767 
21768  return c;
21769 }
21770 NK_INTERN void
21771 nk_textedit_prep_selection_at_cursor(struct nk_text_edit *state)
21772 {
21773  /* update selection and cursor to match each other */
21774  if (!NK_TEXT_HAS_SELECTION(state))
21775  state->select_start = state->select_end = state->cursor;
21776  else state->cursor = state->select_end;
21777 }
21778 NK_API int
21779 nk_textedit_cut(struct nk_text_edit *state)
21780 {
21781  /* API cut: delete selection */
21782  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
21783  return 0;
21784  if (NK_TEXT_HAS_SELECTION(state)) {
21785  nk_textedit_delete_selection(state); /* implicitly clamps */
21786  state->has_preferred_x = 0;
21787  return 1;
21788  }
21789  return 0;
21790 }
21791 NK_API int
21792 nk_textedit_paste(struct nk_text_edit *state, char const *ctext, int len)
21793 {
21794  /* API paste: replace existing selection with passed-in text */
21795  int glyphs;
21796  const char *text = (const char *) ctext;
21797  if (state->mode == NK_TEXT_EDIT_MODE_VIEW) return 0;
21798 
21799  /* if there's a selection, the paste should delete it */
21800  nk_textedit_clamp(state);
21802 
21803  /* try to insert the characters */
21804  glyphs = nk_utf_len(ctext, len);
21805  if (nk_str_insert_text_char(&state->string, state->cursor, text, len)) {
21806  nk_textedit_makeundo_insert(state, state->cursor, glyphs);
21807  state->cursor += len;
21808  state->has_preferred_x = 0;
21809  return 1;
21810  }
21811  /* remove the undo since we didn't actually insert the characters */
21812  if (state->undo.undo_point)
21813  --state->undo.undo_point;
21814  return 0;
21815 }
21816 NK_API void
21817 nk_textedit_text(struct nk_text_edit *state, const char *text, int total_len)
21818 {
21819  nk_rune unicode;
21820  int glyph_len;
21821  int text_len = 0;
21822 
21823  NK_ASSERT(state);
21824  NK_ASSERT(text);
21825  if (!text || !total_len || state->mode == NK_TEXT_EDIT_MODE_VIEW) return;
21826 
21827  glyph_len = nk_utf_decode(text, &unicode, total_len);
21828  while ((text_len < total_len) && glyph_len)
21829  {
21830  /* don't insert a backward delete, just process the event */
21831  if (unicode == 127) goto next;
21832  /* can't add newline in single-line mode */
21833  if (unicode == '\n' && state->single_line) goto next;
21834  /* filter incoming text */
21835  if (state->filter && !state->filter(state, unicode)) goto next;
21836 
21837  if (!NK_TEXT_HAS_SELECTION(state) &&
21838  state->cursor < state->string.len)
21839  {
21840  if (state->mode == NK_TEXT_EDIT_MODE_REPLACE) {
21841  nk_textedit_makeundo_replace(state, state->cursor, 1, 1);
21842  nk_str_delete_runes(&state->string, state->cursor, 1);
21843  }
21844  if (nk_str_insert_text_utf8(&state->string, state->cursor,
21845  text+text_len, 1))
21846  {
21847  ++state->cursor;
21848  state->has_preferred_x = 0;
21849  }
21850  } else {
21851  nk_textedit_delete_selection(state); /* implicitly clamps */
21852  if (nk_str_insert_text_utf8(&state->string, state->cursor,
21853  text+text_len, 1))
21854  {
21855  nk_textedit_makeundo_insert(state, state->cursor, 1);
21856  ++state->cursor;
21857  state->has_preferred_x = 0;
21858  }
21859  }
21860  next:
21861  text_len += glyph_len;
21862  glyph_len = nk_utf_decode(text + text_len, &unicode, total_len-text_len);
21863  }
21864 }
21865 NK_LIB void
21866 nk_textedit_key(struct nk_text_edit *state, enum nk_keys key, int shift_mod,
21867  const struct nk_user_font *font, float row_height)
21868 {
21869 retry:
21870  switch (key)
21871  {
21872  case NK_KEY_NONE:
21873  case NK_KEY_CTRL:
21874  case NK_KEY_ENTER:
21875  case NK_KEY_SHIFT:
21876  case NK_KEY_TAB:
21877  case NK_KEY_COPY:
21878  case NK_KEY_CUT:
21879  case NK_KEY_PASTE:
21880  case NK_KEY_MAX:
21881  default: break;
21882  case NK_KEY_TEXT_UNDO:
21883  nk_textedit_undo(state);
21884  state->has_preferred_x = 0;
21885  break;
21886 
21887  case NK_KEY_TEXT_REDO:
21888  nk_textedit_redo(state);
21889  state->has_preferred_x = 0;
21890  break;
21891 
21893  nk_textedit_select_all(state);
21894  state->has_preferred_x = 0;
21895  break;
21896 
21898  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
21899  state->mode = NK_TEXT_EDIT_MODE_INSERT;
21900  break;
21902  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
21904  break;
21906  if (state->mode == NK_TEXT_EDIT_MODE_INSERT ||
21907  state->mode == NK_TEXT_EDIT_MODE_REPLACE)
21908  state->mode = NK_TEXT_EDIT_MODE_VIEW;
21909  break;
21910 
21911  case NK_KEY_LEFT:
21912  if (shift_mod) {
21913  nk_textedit_clamp(state);
21914  nk_textedit_prep_selection_at_cursor(state);
21915  /* move selection left */
21916  if (state->select_end > 0)
21917  --state->select_end;
21918  state->cursor = state->select_end;
21919  state->has_preferred_x = 0;
21920  } else {
21921  /* if currently there's a selection,
21922  * move cursor to start of selection */
21923  if (NK_TEXT_HAS_SELECTION(state))
21924  nk_textedit_move_to_first(state);
21925  else if (state->cursor > 0)
21926  --state->cursor;
21927  state->has_preferred_x = 0;
21928  } break;
21929 
21930  case NK_KEY_RIGHT:
21931  if (shift_mod) {
21932  nk_textedit_prep_selection_at_cursor(state);
21933  /* move selection right */
21934  ++state->select_end;
21935  nk_textedit_clamp(state);
21936  state->cursor = state->select_end;
21937  state->has_preferred_x = 0;
21938  } else {
21939  /* if currently there's a selection,
21940  * move cursor to end of selection */
21941  if (NK_TEXT_HAS_SELECTION(state))
21942  nk_textedit_move_to_last(state);
21943  else ++state->cursor;
21944  nk_textedit_clamp(state);
21945  state->has_preferred_x = 0;
21946  } break;
21947 
21948  case NK_KEY_TEXT_WORD_LEFT:
21949  if (shift_mod) {
21950  if( !NK_TEXT_HAS_SELECTION( state ) )
21951  nk_textedit_prep_selection_at_cursor(state);
21952  state->cursor = nk_textedit_move_to_word_previous(state);
21953  state->select_end = state->cursor;
21954  nk_textedit_clamp(state );
21955  } else {
21956  if (NK_TEXT_HAS_SELECTION(state))
21957  nk_textedit_move_to_first(state);
21958  else {
21959  state->cursor = nk_textedit_move_to_word_previous(state);
21960  nk_textedit_clamp(state );
21961  }
21962  } break;
21963 
21965  if (shift_mod) {
21966  if( !NK_TEXT_HAS_SELECTION( state ) )
21967  nk_textedit_prep_selection_at_cursor(state);
21968  state->cursor = nk_textedit_move_to_word_next(state);
21969  state->select_end = state->cursor;
21970  nk_textedit_clamp(state);
21971  } else {
21972  if (NK_TEXT_HAS_SELECTION(state))
21973  nk_textedit_move_to_last(state);
21974  else {
21975  state->cursor = nk_textedit_move_to_word_next(state);
21976  nk_textedit_clamp(state );
21977  }
21978  } break;
21979 
21980  case NK_KEY_DOWN: {
21981  struct nk_text_find find;
21982  struct nk_text_edit_row row;
21983  int i, sel = shift_mod;
21984 
21985  if (state->single_line) {
21986  /* on windows, up&down in single-line behave like left&right */
21987  key = NK_KEY_RIGHT;
21988  goto retry;
21989  }
21990 
21991  if (sel)
21992  nk_textedit_prep_selection_at_cursor(state);
21993  else if (NK_TEXT_HAS_SELECTION(state))
21994  nk_textedit_move_to_last(state);
21995 
21996  /* compute current position of cursor point */
21997  nk_textedit_clamp(state);
21998  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
21999  font, row_height);
22000 
22001  /* now find character position down a row */
22002  if (find.length)
22003  {
22004  float x;
22005  float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
22006  int start = find.first_char + find.length;
22007 
22008  state->cursor = start;
22009  nk_textedit_layout_row(&row, state, state->cursor, row_height, font);
22010  x = row.x0;
22011 
22012  for (i=0; i < row.num_chars && x < row.x1; ++i) {
22013  float dx = nk_textedit_get_width(state, start, i, font);
22014  x += dx;
22015  if (x > goal_x)
22016  break;
22017  ++state->cursor;
22018  }
22019  nk_textedit_clamp(state);
22020 
22021  state->has_preferred_x = 1;
22022  state->preferred_x = goal_x;
22023  if (sel)
22024  state->select_end = state->cursor;
22025  }
22026  } break;
22027 
22028  case NK_KEY_UP: {
22029  struct nk_text_find find;
22030  struct nk_text_edit_row row;
22031  int i, sel = shift_mod;
22032 
22033  if (state->single_line) {
22034  /* on windows, up&down become left&right */
22035  key = NK_KEY_LEFT;
22036  goto retry;
22037  }
22038 
22039  if (sel)
22040  nk_textedit_prep_selection_at_cursor(state);
22041  else if (NK_TEXT_HAS_SELECTION(state))
22042  nk_textedit_move_to_first(state);
22043 
22044  /* compute current position of cursor point */
22045  nk_textedit_clamp(state);
22046  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22047  font, row_height);
22048 
22049  /* can only go up if there's a previous row */
22050  if (find.prev_first != find.first_char) {
22051  /* now find character position up a row */
22052  float x;
22053  float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
22054 
22055  state->cursor = find.prev_first;
22056  nk_textedit_layout_row(&row, state, state->cursor, row_height, font);
22057  x = row.x0;
22058 
22059  for (i=0; i < row.num_chars && x < row.x1; ++i) {
22060  float dx = nk_textedit_get_width(state, find.prev_first, i, font);
22061  x += dx;
22062  if (x > goal_x)
22063  break;
22064  ++state->cursor;
22065  }
22066  nk_textedit_clamp(state);
22067 
22068  state->has_preferred_x = 1;
22069  state->preferred_x = goal_x;
22070  if (sel) state->select_end = state->cursor;
22071  }
22072  } break;
22073 
22074  case NK_KEY_DEL:
22075  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
22076  break;
22077  if (NK_TEXT_HAS_SELECTION(state))
22079  else {
22080  int n = state->string.len;
22081  if (state->cursor < n)
22082  nk_textedit_delete(state, state->cursor, 1);
22083  }
22084  state->has_preferred_x = 0;
22085  break;
22086 
22087  case NK_KEY_BACKSPACE:
22088  if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
22089  break;
22090  if (NK_TEXT_HAS_SELECTION(state))
22092  else {
22093  nk_textedit_clamp(state);
22094  if (state->cursor > 0) {
22095  nk_textedit_delete(state, state->cursor-1, 1);
22096  --state->cursor;
22097  }
22098  }
22099  state->has_preferred_x = 0;
22100  break;
22101 
22102  case NK_KEY_TEXT_START:
22103  if (shift_mod) {
22104  nk_textedit_prep_selection_at_cursor(state);
22105  state->cursor = state->select_end = 0;
22106  state->has_preferred_x = 0;
22107  } else {
22108  state->cursor = state->select_start = state->select_end = 0;
22109  state->has_preferred_x = 0;
22110  }
22111  break;
22112 
22113  case NK_KEY_TEXT_END:
22114  if (shift_mod) {
22115  nk_textedit_prep_selection_at_cursor(state);
22116  state->cursor = state->select_end = state->string.len;
22117  state->has_preferred_x = 0;
22118  } else {
22119  state->cursor = state->string.len;
22120  state->select_start = state->select_end = 0;
22121  state->has_preferred_x = 0;
22122  }
22123  break;
22124 
22125  case NK_KEY_TEXT_LINE_START: {
22126  if (shift_mod) {
22127  struct nk_text_find find;
22128  nk_textedit_clamp(state);
22129  nk_textedit_prep_selection_at_cursor(state);
22130  if (state->string.len && state->cursor == state->string.len)
22131  --state->cursor;
22132  nk_textedit_find_charpos(&find, state,state->cursor, state->single_line,
22133  font, row_height);
22134  state->cursor = state->select_end = find.first_char;
22135  state->has_preferred_x = 0;
22136  } else {
22137  struct nk_text_find find;
22138  if (state->string.len && state->cursor == state->string.len)
22139  --state->cursor;
22140  nk_textedit_clamp(state);
22141  nk_textedit_move_to_first(state);
22142  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22143  font, row_height);
22144  state->cursor = find.first_char;
22145  state->has_preferred_x = 0;
22146  }
22147  } break;
22148 
22149  case NK_KEY_TEXT_LINE_END: {
22150  if (shift_mod) {
22151  struct nk_text_find find;
22152  nk_textedit_clamp(state);
22153  nk_textedit_prep_selection_at_cursor(state);
22154  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22155  font, row_height);
22156  state->has_preferred_x = 0;
22157  state->cursor = find.first_char + find.length;
22158  if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) == '\n')
22159  --state->cursor;
22160  state->select_end = state->cursor;
22161  } else {
22162  struct nk_text_find find;
22163  nk_textedit_clamp(state);
22164  nk_textedit_move_to_first(state);
22165  nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
22166  font, row_height);
22167 
22168  state->has_preferred_x = 0;
22169  state->cursor = find.first_char + find.length;
22170  if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) == '\n')
22171  --state->cursor;
22172  }} break;
22173  }
22174 }
22175 NK_INTERN void
22176 nk_textedit_flush_redo(struct nk_text_undo_state *state)
22177 {
22180 }
22181 NK_INTERN void
22182 nk_textedit_discard_undo(struct nk_text_undo_state *state)
22183 {
22184  /* discard the oldest entry in the undo list */
22185  if (state->undo_point > 0) {
22186  /* if the 0th undo state has characters, clean those up */
22187  if (state->undo_rec[0].char_storage >= 0) {
22188  int n = state->undo_rec[0].insert_length, i;
22189  /* delete n characters from all other records */
22190  state->undo_char_point = (short)(state->undo_char_point - n);
22191  NK_MEMCPY(state->undo_char, state->undo_char + n,
22192  (nk_size)state->undo_char_point*sizeof(nk_rune));
22193  for (i=0; i < state->undo_point; ++i) {
22194  if (state->undo_rec[i].char_storage >= 0)
22195  state->undo_rec[i].char_storage = (short)
22196  (state->undo_rec[i].char_storage - n);
22197  }
22198  }
22199  --state->undo_point;
22200  NK_MEMCPY(state->undo_rec, state->undo_rec+1,
22201  (nk_size)((nk_size)state->undo_point * sizeof(state->undo_rec[0])));
22202  }
22203 }
22204 NK_INTERN void
22205 nk_textedit_discard_redo(struct nk_text_undo_state *state)
22206 {
22207 /* discard the oldest entry in the redo list--it's bad if this
22208  ever happens, but because undo & redo have to store the actual
22209  characters in different cases, the redo character buffer can
22210  fill up even though the undo buffer didn't */
22211  nk_size num;
22212  int k = NK_TEXTEDIT_UNDOSTATECOUNT-1;
22213  if (state->redo_point <= k) {
22214  /* if the k'th undo state has characters, clean those up */
22215  if (state->undo_rec[k].char_storage >= 0) {
22216  int n = state->undo_rec[k].insert_length, i;
22217  /* delete n characters from all other records */
22218  state->redo_char_point = (short)(state->redo_char_point + n);
22220  NK_MEMCPY(state->undo_char + state->redo_char_point,
22221  state->undo_char + state->redo_char_point-n, num * sizeof(char));
22222  for (i = state->redo_point; i < k; ++i) {
22223  if (state->undo_rec[i].char_storage >= 0) {
22224  state->undo_rec[i].char_storage = (short)
22225  (state->undo_rec[i].char_storage + n);
22226  }
22227  }
22228  }
22229  ++state->redo_point;
22230  num = (nk_size)(NK_TEXTEDIT_UNDOSTATECOUNT - state->redo_point);
22231  if (num) NK_MEMCPY(state->undo_rec + state->redo_point-1,
22232  state->undo_rec + state->redo_point, num * sizeof(state->undo_rec[0]));
22233  }
22234 }
22236 nk_textedit_create_undo_record(struct nk_text_undo_state *state, int numchars)
22237 {
22238  /* any time we create a new undo record, we discard redo*/
22239  nk_textedit_flush_redo(state);
22240 
22241  /* if we have no free records, we have to make room,
22242  * by sliding the existing records down */
22243  if (state->undo_point == NK_TEXTEDIT_UNDOSTATECOUNT)
22244  nk_textedit_discard_undo(state);
22245 
22246  /* if the characters to store won't possibly fit in the buffer,
22247  * we can't undo */
22248  if (numchars > NK_TEXTEDIT_UNDOCHARCOUNT) {
22249  state->undo_point = 0;
22250  state->undo_char_point = 0;
22251  return 0;
22252  }
22253 
22254  /* if we don't have enough free characters in the buffer,
22255  * we have to make room */
22256  while (state->undo_char_point + numchars > NK_TEXTEDIT_UNDOCHARCOUNT)
22257  nk_textedit_discard_undo(state);
22258  return &state->undo_rec[state->undo_point++];
22259 }
22260 NK_INTERN nk_rune*
22261 nk_textedit_createundo(struct nk_text_undo_state *state, int pos,
22262  int insert_len, int delete_len)
22263 {
22264  struct nk_text_undo_record *r = nk_textedit_create_undo_record(state, insert_len);
22265  if (r == 0)
22266  return 0;
22267 
22268  r->where = pos;
22269  r->insert_length = (short) insert_len;
22270  r->delete_length = (short) delete_len;
22271 
22272  if (insert_len == 0) {
22273  r->char_storage = -1;
22274  return 0;
22275  } else {
22276  r->char_storage = state->undo_char_point;
22277  state->undo_char_point = (short)(state->undo_char_point + insert_len);
22278  return &state->undo_char[r->char_storage];
22279  }
22280 }
22281 NK_API void
22282 nk_textedit_undo(struct nk_text_edit *state)
22283 {
22284  struct nk_text_undo_state *s = &state->undo;
22285  struct nk_text_undo_record u, *r;
22286  if (s->undo_point == 0)
22287  return;
22288 
22289  /* we need to do two things: apply the undo record, and create a redo record */
22290  u = s->undo_rec[s->undo_point-1];
22291  r = &s->undo_rec[s->redo_point-1];
22292  r->char_storage = -1;
22293 
22294  r->insert_length = u.delete_length;
22295  r->delete_length = u.insert_length;
22296  r->where = u.where;
22297 
22298  if (u.delete_length)
22299  {
22300  /* if the undo record says to delete characters, then the redo record will
22301  need to re-insert the characters that get deleted, so we need to store
22302  them.
22303  there are three cases:
22304  - there's enough room to store the characters
22305  - characters stored for *redoing* don't leave room for redo
22306  - characters stored for *undoing* don't leave room for redo
22307  if the last is true, we have to bail */
22308  if (s->undo_char_point + u.delete_length >= NK_TEXTEDIT_UNDOCHARCOUNT) {
22309  /* the undo records take up too much character space; there's no space
22310  * to store the redo characters */
22311  r->insert_length = 0;
22312  } else {
22313  int i;
22314  /* there's definitely room to store the characters eventually */
22315  while (s->undo_char_point + u.delete_length > s->redo_char_point) {
22316  /* there's currently not enough room, so discard a redo record */
22317  nk_textedit_discard_redo(s);
22318  /* should never happen: */
22320  return;
22321  }
22322 
22323  r = &s->undo_rec[s->redo_point-1];
22324  r->char_storage = (short)(s->redo_char_point - u.delete_length);
22325  s->redo_char_point = (short)(s->redo_char_point - u.delete_length);
22326 
22327  /* now save the characters */
22328  for (i=0; i < u.delete_length; ++i)
22329  s->undo_char[r->char_storage + i] =
22330  nk_str_rune_at(&state->string, u.where + i);
22331  }
22332  /* now we can carry out the deletion */
22333  nk_str_delete_runes(&state->string, u.where, u.delete_length);
22334  }
22335 
22336  /* check type of recorded action: */
22337  if (u.insert_length) {
22338  /* easy case: was a deletion, so we need to insert n characters */
22339  nk_str_insert_text_runes(&state->string, u.where,
22340  &s->undo_char[u.char_storage], u.insert_length);
22341  s->undo_char_point = (short)(s->undo_char_point - u.insert_length);
22342  }
22343  state->cursor = (short)(u.where + u.insert_length);
22344 
22345  s->undo_point--;
22346  s->redo_point--;
22347 }
22348 NK_API void
22349 nk_textedit_redo(struct nk_text_edit *state)
22350 {
22351  struct nk_text_undo_state *s = &state->undo;
22352  struct nk_text_undo_record *u, r;
22354  return;
22355 
22356  /* we need to do two things: apply the redo record, and create an undo record */
22357  u = &s->undo_rec[s->undo_point];
22358  r = s->undo_rec[s->redo_point];
22359 
22360  /* we KNOW there must be room for the undo record, because the redo record
22361  was derived from an undo record */
22364  u->where = r.where;
22365  u->char_storage = -1;
22366 
22367  if (r.delete_length) {
22368  /* the redo record requires us to delete characters, so the undo record
22369  needs to store the characters */
22370  if (s->undo_char_point + u->insert_length > s->redo_char_point) {
22371  u->insert_length = 0;
22372  u->delete_length = 0;
22373  } else {
22374  int i;
22375  u->char_storage = s->undo_char_point;
22376  s->undo_char_point = (short)(s->undo_char_point + u->insert_length);
22377 
22378  /* now save the characters */
22379  for (i=0; i < u->insert_length; ++i) {
22380  s->undo_char[u->char_storage + i] =
22381  nk_str_rune_at(&state->string, u->where + i);
22382  }
22383  }
22385  }
22386 
22387  if (r.insert_length) {
22388  /* easy case: need to insert n characters */
22391  }
22392  state->cursor = r.where + r.insert_length;
22393 
22394  s->undo_point++;
22395  s->redo_point++;
22396 }
22397 NK_INTERN void
22398 nk_textedit_makeundo_insert(struct nk_text_edit *state, int where, int length)
22399 {
22400  nk_textedit_createundo(&state->undo, where, 0, length);
22401 }
22402 NK_INTERN void
22403 nk_textedit_makeundo_delete(struct nk_text_edit *state, int where, int length)
22404 {
22405  int i;
22406  nk_rune *p = nk_textedit_createundo(&state->undo, where, length, 0);
22407  if (p) {
22408  for (i=0; i < length; ++i)
22409  p[i] = nk_str_rune_at(&state->string, where+i);
22410  }
22411 }
22412 NK_INTERN void
22413 nk_textedit_makeundo_replace(struct nk_text_edit *state, int where,
22414  int old_length, int new_length)
22415 {
22416  int i;
22417  nk_rune *p = nk_textedit_createundo(&state->undo, where, old_length, new_length);
22418  if (p) {
22419  for (i=0; i < old_length; ++i)
22420  p[i] = nk_str_rune_at(&state->string, where+i);
22421  }
22422 }
22423 NK_LIB void
22424 nk_textedit_clear_state(struct nk_text_edit *state, enum nk_text_edit_type type,
22426 {
22427  /* reset the state to default */
22428  state->undo.undo_point = 0;
22429  state->undo.undo_char_point = 0;
22432  state->select_end = state->select_start = 0;
22433  state->cursor = 0;
22434  state->has_preferred_x = 0;
22435  state->preferred_x = 0;
22436  state->cursor_at_end_of_line = 0;
22437  state->initialized = 1;
22438  state->single_line = (unsigned char)(type == NK_TEXT_EDIT_SINGLE_LINE);
22439  state->mode = NK_TEXT_EDIT_MODE_VIEW;
22440  state->filter = filter;
22441  state->scrollbar = nk_vec2(0,0);
22442 }
22443 NK_API void
22444 nk_textedit_init_fixed(struct nk_text_edit *state, void *memory, nk_size size)
22445 {
22446  NK_ASSERT(state);
22447  NK_ASSERT(memory);
22448  if (!state || !memory || !size) return;
22449  NK_MEMSET(state, 0, sizeof(struct nk_text_edit));
22450  nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
22451  nk_str_init_fixed(&state->string, memory, size);
22452 }
22453 NK_API void
22454 nk_textedit_init(struct nk_text_edit *state, struct nk_allocator *alloc, nk_size size)
22455 {
22456  NK_ASSERT(state);
22457  NK_ASSERT(alloc);
22458  if (!state || !alloc) return;
22459  NK_MEMSET(state, 0, sizeof(struct nk_text_edit));
22460  nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
22461  nk_str_init(&state->string, alloc, size);
22462 }
22463 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
22464 NK_API void
22465 nk_textedit_init_default(struct nk_text_edit *state)
22466 {
22467  NK_ASSERT(state);
22468  if (!state) return;
22469  NK_MEMSET(state, 0, sizeof(struct nk_text_edit));
22470  nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
22471  nk_str_init_default(&state->string);
22472 }
22473 #endif
22474 NK_API void
22475 nk_textedit_select_all(struct nk_text_edit *state)
22476 {
22477  NK_ASSERT(state);
22478  state->select_start = 0;
22479  state->select_end = state->string.len;
22480 }
22481 NK_API void
22482 nk_textedit_free(struct nk_text_edit *state)
22483 {
22484  NK_ASSERT(state);
22485  if (!state) return;
22486  nk_str_free(&state->string);
22487 }
22488 
22489 
22490 
22491 
22492 
22493 /* ===============================================================
22494  *
22495  * FILTER
22496  *
22497  * ===============================================================*/
22498 NK_API int
22499 nk_filter_default(const struct nk_text_edit *box, nk_rune unicode)
22500 {
22501  NK_UNUSED(unicode);
22502  NK_UNUSED(box);
22503  return nk_true;
22504 }
22505 NK_API int
22506 nk_filter_ascii(const struct nk_text_edit *box, nk_rune unicode)
22507 {
22508  NK_UNUSED(box);
22509  if (unicode > 128) return nk_false;
22510  else return nk_true;
22511 }
22512 NK_API int
22513 nk_filter_float(const struct nk_text_edit *box, nk_rune unicode)
22514 {
22515  NK_UNUSED(box);
22516  if ((unicode < '0' || unicode > '9') && unicode != '.' && unicode != '-')
22517  return nk_false;
22518  else return nk_true;
22519 }
22520 NK_API int
22521 nk_filter_decimal(const struct nk_text_edit *box, nk_rune unicode)
22522 {
22523  NK_UNUSED(box);
22524  if ((unicode < '0' || unicode > '9') && unicode != '-')
22525  return nk_false;
22526  else return nk_true;
22527 }
22528 NK_API int
22529 nk_filter_hex(const struct nk_text_edit *box, nk_rune unicode)
22530 {
22531  NK_UNUSED(box);
22532  if ((unicode < '0' || unicode > '9') &&
22533  (unicode < 'a' || unicode > 'f') &&
22534  (unicode < 'A' || unicode > 'F'))
22535  return nk_false;
22536  else return nk_true;
22537 }
22538 NK_API int
22539 nk_filter_oct(const struct nk_text_edit *box, nk_rune unicode)
22540 {
22541  NK_UNUSED(box);
22542  if (unicode < '0' || unicode > '7')
22543  return nk_false;
22544  else return nk_true;
22545 }
22546 NK_API int
22547 nk_filter_binary(const struct nk_text_edit *box, nk_rune unicode)
22548 {
22549  NK_UNUSED(box);
22550  if (unicode != '0' && unicode != '1')
22551  return nk_false;
22552  else return nk_true;
22553 }
22554 
22555 /* ===============================================================
22556  *
22557  * EDIT
22558  *
22559  * ===============================================================*/
22560 NK_LIB void
22561 nk_edit_draw_text(struct nk_command_buffer *out,
22562  const struct nk_style_edit *style, float pos_x, float pos_y,
22563  float x_offset, const char *text, int byte_len, float row_height,
22564  const struct nk_user_font *font, struct nk_color background,
22565  struct nk_color foreground, int is_selected)
22566 {
22567  NK_ASSERT(out);
22568  NK_ASSERT(font);
22569  NK_ASSERT(style);
22570  if (!text || !byte_len || !out || !style) return;
22571 
22572  {int glyph_len = 0;
22573  nk_rune unicode = 0;
22574  int text_len = 0;
22575  float line_width = 0;
22576  float glyph_width;
22577  const char *line = text;
22578  float line_offset = 0;
22579  int line_count = 0;
22580 
22581  struct nk_text txt;
22582  txt.padding = nk_vec2(0,0);
22583  txt.background = background;
22584  txt.text = foreground;
22585 
22586  glyph_len = nk_utf_decode(text+text_len, &unicode, byte_len-text_len);
22587  if (!glyph_len) return;
22588  while ((text_len < byte_len) && glyph_len)
22589  {
22590  if (unicode == '\n') {
22591  /* new line separator so draw previous line */
22592  struct nk_rect label;
22593  label.y = pos_y + line_offset;
22594  label.h = row_height;
22595  label.w = line_width;
22596  label.x = pos_x;
22597  if (!line_count)
22598  label.x += x_offset;
22599 
22600  if (is_selected) /* selection needs to draw different background color */
22601  nk_fill_rect(out, label, 0, background);
22602  nk_widget_text(out, label, line, (int)((text + text_len) - line),
22603  &txt, NK_TEXT_CENTERED, font);
22604 
22605  text_len++;
22606  line_count++;
22607  line_width = 0;
22608  line = text + text_len;
22609  line_offset += row_height;
22610  glyph_len = nk_utf_decode(text + text_len, &unicode, (int)(byte_len-text_len));
22611  continue;
22612  }
22613  if (unicode == '\r') {
22614  text_len++;
22615  glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
22616  continue;
22617  }
22618  glyph_width = font->width(font->userdata, font->height, text+text_len, glyph_len);
22619  line_width += (float)glyph_width;
22620  text_len += glyph_len;
22621  glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
22622  continue;
22623  }
22624  if (line_width > 0) {
22625  /* draw last line */
22626  struct nk_rect label;
22627  label.y = pos_y + line_offset;
22628  label.h = row_height;
22629  label.w = line_width;
22630  label.x = pos_x;
22631  if (!line_count)
22632  label.x += x_offset;
22633 
22634  if (is_selected)
22635  nk_fill_rect(out, label, 0, background);
22636  nk_widget_text(out, label, line, (int)((text + text_len) - line),
22637  &txt, NK_TEXT_LEFT, font);
22638  }}
22639 }
22640 NK_LIB nk_flags
22641 nk_do_edit(nk_flags *state, struct nk_command_buffer *out,
22642  struct nk_rect bounds, nk_flags flags, nk_plugin_filter filter,
22643  struct nk_text_edit *edit, const struct nk_style_edit *style,
22644  struct nk_input *in, const struct nk_user_font *font)
22645 {
22646  struct nk_rect area;
22647  nk_flags ret = 0;
22648  float row_height;
22649  char prev_state = 0;
22650  char is_hovered = 0;
22651  char select_all = 0;
22652  char cursor_follow = 0;
22653  struct nk_rect old_clip;
22654  struct nk_rect clip;
22655 
22656  NK_ASSERT(state);
22657  NK_ASSERT(out);
22658  NK_ASSERT(style);
22659  if (!state || !out || !style)
22660  return ret;
22661 
22662  /* visible text area calculation */
22663  area.x = bounds.x + style->padding.x + style->border;
22664  area.y = bounds.y + style->padding.y + style->border;
22665  area.w = bounds.w - (2.0f * style->padding.x + 2 * style->border);
22666  area.h = bounds.h - (2.0f * style->padding.y + 2 * style->border);
22667  if (flags & NK_EDIT_MULTILINE)
22668  area.w = NK_MAX(0, area.w - style->scrollbar_size.x);
22669  row_height = (flags & NK_EDIT_MULTILINE)? font->height + style->row_padding: area.h;
22670 
22671  /* calculate clipping rectangle */
22672  old_clip = out->clip;
22673  nk_unify(&clip, &old_clip, area.x, area.y, area.x + area.w, area.y + area.h);
22674 
22675  /* update edit state */
22676  prev_state = (char)edit->active;
22677  is_hovered = (char)nk_input_is_mouse_hovering_rect(in, bounds);
22679  edit->active = NK_INBOX(in->mouse.pos.x, in->mouse.pos.y,
22680  bounds.x, bounds.y, bounds.w, bounds.h);
22681  }
22682 
22683  /* (de)activate text editor */
22684  if (!prev_state && edit->active) {
22685  const enum nk_text_edit_type type = (flags & NK_EDIT_MULTILINE) ?
22687  nk_textedit_clear_state(edit, type, filter);
22688  if (flags & NK_EDIT_AUTO_SELECT)
22689  select_all = nk_true;
22690  if (flags & NK_EDIT_GOTO_END_ON_ACTIVATE) {
22691  edit->cursor = edit->string.len;
22692  in = 0;
22693  }
22694  } else if (!edit->active) edit->mode = NK_TEXT_EDIT_MODE_VIEW;
22695  if (flags & NK_EDIT_READ_ONLY)
22696  edit->mode = NK_TEXT_EDIT_MODE_VIEW;
22697  else if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
22699 
22700  ret = (edit->active) ? NK_EDIT_ACTIVE: NK_EDIT_INACTIVE;
22701  if (prev_state != edit->active)
22702  ret |= (edit->active) ? NK_EDIT_ACTIVATED: NK_EDIT_DEACTIVATED;
22703 
22704  /* handle user input */
22705  if (edit->active && in)
22706  {
22707  int shift_mod = in->keyboard.keys[NK_KEY_SHIFT].down;
22708  const float mouse_x = (in->mouse.pos.x - area.x) + edit->scrollbar.x;
22709  const float mouse_y = (in->mouse.pos.y - area.y) + edit->scrollbar.y;
22710 
22711  /* mouse click handler */
22712  is_hovered = (char)nk_input_is_mouse_hovering_rect(in, area);
22713  if (select_all) {
22714  nk_textedit_select_all(edit);
22715  } else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
22717  nk_textedit_click(edit, mouse_x, mouse_y, font, row_height);
22718  } else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
22719  (in->mouse.delta.x != 0.0f || in->mouse.delta.y != 0.0f)) {
22720  nk_textedit_drag(edit, mouse_x, mouse_y, font, row_height);
22721  cursor_follow = nk_true;
22722  } else if (is_hovered && in->mouse.buttons[NK_BUTTON_RIGHT].clicked &&
22724  nk_textedit_key(edit, NK_KEY_TEXT_WORD_LEFT, nk_false, font, row_height);
22725  nk_textedit_key(edit, NK_KEY_TEXT_WORD_RIGHT, nk_true, font, row_height);
22726  cursor_follow = nk_true;
22727  }
22728 
22729  {int i; /* keyboard input */
22730  int old_mode = edit->mode;
22731  for (i = 0; i < NK_KEY_MAX; ++i) {
22732  if (i == NK_KEY_ENTER || i == NK_KEY_TAB) continue; /* special case */
22733  if (nk_input_is_key_pressed(in, (enum nk_keys)i)) {
22734  nk_textedit_key(edit, (enum nk_keys)i, shift_mod, font, row_height);
22735  cursor_follow = nk_true;
22736  }
22737  }
22738  if (old_mode != edit->mode) {
22739  in->keyboard.text_len = 0;
22740  }}
22741 
22742  /* text input */
22743  edit->filter = filter;
22744  if (in->keyboard.text_len) {
22746  cursor_follow = nk_true;
22747  in->keyboard.text_len = 0;
22748  }
22749 
22750  /* enter key handler */
22752  cursor_follow = nk_true;
22753  if (flags & NK_EDIT_CTRL_ENTER_NEWLINE && shift_mod)
22754  nk_textedit_text(edit, "\n", 1);
22755  else if (flags & NK_EDIT_SIG_ENTER)
22756  ret |= NK_EDIT_COMMITED;
22757  else nk_textedit_text(edit, "\n", 1);
22758  }
22759 
22760  /* cut & copy handler */
22762  int cut = nk_input_is_key_pressed(in, NK_KEY_CUT);
22763  if ((copy || cut) && (flags & NK_EDIT_CLIPBOARD))
22764  {
22765  int glyph_len;
22766  nk_rune unicode;
22767  const char *text;
22768  int b = edit->select_start;
22769  int e = edit->select_end;
22770 
22771  int begin = NK_MIN(b, e);
22772  int end = NK_MAX(b, e);
22773  text = nk_str_at_const(&edit->string, begin, &unicode, &glyph_len);
22774  if (edit->clip.copy)
22775  edit->clip.copy(edit->clip.userdata, text, end - begin);
22776  if (cut && !(flags & NK_EDIT_READ_ONLY)){
22777  nk_textedit_cut(edit);
22778  cursor_follow = nk_true;
22779  }
22780  }}
22781 
22782  /* paste handler */
22783  {int paste = nk_input_is_key_pressed(in, NK_KEY_PASTE);
22784  if (paste && (flags & NK_EDIT_CLIPBOARD) && edit->clip.paste) {
22785  edit->clip.paste(edit->clip.userdata, edit);
22786  cursor_follow = nk_true;
22787  }}
22788 
22789  /* tab handler */
22790  {int tab = nk_input_is_key_pressed(in, NK_KEY_TAB);
22791  if (tab && (flags & NK_EDIT_ALLOW_TAB)) {
22792  nk_textedit_text(edit, " ", 4);
22793  cursor_follow = nk_true;
22794  }}
22795  }
22796 
22797  /* set widget state */
22798  if (edit->active)
22799  *state = NK_WIDGET_STATE_ACTIVE;
22800  else nk_widget_state_reset(state);
22801 
22802  if (is_hovered)
22803  *state |= NK_WIDGET_STATE_HOVERED;
22804 
22805  /* DRAW EDIT */
22806  {const char *text = nk_str_get_const(&edit->string);
22807  int len = nk_str_len_char(&edit->string);
22808 
22809  {/* select background colors/images */
22810  const struct nk_style_item *background;
22811  if (*state & NK_WIDGET_STATE_ACTIVED)
22812  background = &style->active;
22813  else if (*state & NK_WIDGET_STATE_HOVER)
22814  background = &style->hover;
22815  else background = &style->normal;
22816 
22817  /* draw background frame */
22818  if (background->type == NK_STYLE_ITEM_COLOR) {
22819  nk_stroke_rect(out, bounds, style->rounding, style->border, style->border_color);
22820  nk_fill_rect(out, bounds, style->rounding, background->data.color);
22821  } else nk_draw_image(out, bounds, &background->data.image, nk_white);}
22822 
22823  area.w = NK_MAX(0, area.w - style->cursor_size);
22824  if (edit->active)
22825  {
22826  int total_lines = 1;
22827  struct nk_vec2 text_size = nk_vec2(0,0);
22828 
22829  /* text pointer positions */
22830  const char *cursor_ptr = 0;
22831  const char *select_begin_ptr = 0;
22832  const char *select_end_ptr = 0;
22833 
22834  /* 2D pixel positions */
22835  struct nk_vec2 cursor_pos = nk_vec2(0,0);
22836  struct nk_vec2 selection_offset_start = nk_vec2(0,0);
22837  struct nk_vec2 selection_offset_end = nk_vec2(0,0);
22838 
22839  int selection_begin = NK_MIN(edit->select_start, edit->select_end);
22840  int selection_end = NK_MAX(edit->select_start, edit->select_end);
22841 
22842  /* calculate total line count + total space + cursor/selection position */
22843  float line_width = 0.0f;
22844  if (text && len)
22845  {
22846  /* utf8 encoding */
22847  float glyph_width;
22848  int glyph_len = 0;
22849  nk_rune unicode = 0;
22850  int text_len = 0;
22851  int glyphs = 0;
22852  int row_begin = 0;
22853 
22854  glyph_len = nk_utf_decode(text, &unicode, len);
22855  glyph_width = font->width(font->userdata, font->height, text, glyph_len);
22856  line_width = 0;
22857 
22858  /* iterate all lines */
22859  while ((text_len < len) && glyph_len)
22860  {
22861  /* set cursor 2D position and line */
22862  if (!cursor_ptr && glyphs == edit->cursor)
22863  {
22864  int glyph_offset;
22865  struct nk_vec2 out_offset;
22866  struct nk_vec2 row_size;
22867  const char *remaining;
22868 
22869  /* calculate 2d position */
22870  cursor_pos.y = (float)(total_lines-1) * row_height;
22871  row_size = nk_text_calculate_text_bounds(font, text+row_begin,
22872  text_len-row_begin, row_height, &remaining,
22873  &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
22874  cursor_pos.x = row_size.x;
22875  cursor_ptr = text + text_len;
22876  }
22877 
22878  /* set start selection 2D position and line */
22879  if (!select_begin_ptr && edit->select_start != edit->select_end &&
22880  glyphs == selection_begin)
22881  {
22882  int glyph_offset;
22883  struct nk_vec2 out_offset;
22884  struct nk_vec2 row_size;
22885  const char *remaining;
22886 
22887  /* calculate 2d position */
22888  selection_offset_start.y = (float)(NK_MAX(total_lines-1,0)) * row_height;
22889  row_size = nk_text_calculate_text_bounds(font, text+row_begin,
22890  text_len-row_begin, row_height, &remaining,
22891  &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
22892  selection_offset_start.x = row_size.x;
22893  select_begin_ptr = text + text_len;
22894  }
22895 
22896  /* set end selection 2D position and line */
22897  if (!select_end_ptr && edit->select_start != edit->select_end &&
22898  glyphs == selection_end)
22899  {
22900  int glyph_offset;
22901  struct nk_vec2 out_offset;
22902  struct nk_vec2 row_size;
22903  const char *remaining;
22904 
22905  /* calculate 2d position */
22906  selection_offset_end.y = (float)(total_lines-1) * row_height;
22907  row_size = nk_text_calculate_text_bounds(font, text+row_begin,
22908  text_len-row_begin, row_height, &remaining,
22909  &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
22910  selection_offset_end.x = row_size.x;
22911  select_end_ptr = text + text_len;
22912  }
22913  if (unicode == '\n') {
22914  text_size.x = NK_MAX(text_size.x, line_width);
22915  total_lines++;
22916  line_width = 0;
22917  text_len++;
22918  glyphs++;
22919  row_begin = text_len;
22920  glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
22921  glyph_width = font->width(font->userdata, font->height, text+text_len, glyph_len);
22922  continue;
22923  }
22924 
22925  glyphs++;
22926  text_len += glyph_len;
22927  line_width += (float)glyph_width;
22928 
22929  glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
22930  glyph_width = font->width(font->userdata, font->height,
22931  text+text_len, glyph_len);
22932  continue;
22933  }
22934  text_size.y = (float)total_lines * row_height;
22935 
22936  /* handle case when cursor is at end of text buffer */
22937  if (!cursor_ptr && edit->cursor == edit->string.len) {
22938  cursor_pos.x = line_width;
22939  cursor_pos.y = text_size.y - row_height;
22940  }
22941  }
22942  {
22943  /* scrollbar */
22944  if (cursor_follow)
22945  {
22946  /* update scrollbar to follow cursor */
22947  if (!(flags & NK_EDIT_NO_HORIZONTAL_SCROLL)) {
22948  /* horizontal scroll */
22949  const float scroll_increment = area.w * 0.25f;
22950  if (cursor_pos.x < edit->scrollbar.x)
22951  edit->scrollbar.x = (float)(int)NK_MAX(0.0f, cursor_pos.x - scroll_increment);
22952  if (cursor_pos.x >= edit->scrollbar.x + area.w)
22953  edit->scrollbar.x = (float)(int)NK_MAX(0.0f, edit->scrollbar.x + scroll_increment);
22954  } else edit->scrollbar.x = 0;
22955 
22956  if (flags & NK_EDIT_MULTILINE) {
22957  /* vertical scroll */
22958  if (cursor_pos.y < edit->scrollbar.y)
22959  edit->scrollbar.y = NK_MAX(0.0f, cursor_pos.y - row_height);
22960  if (cursor_pos.y >= edit->scrollbar.y + area.h)
22961  edit->scrollbar.y = edit->scrollbar.y + row_height;
22962  } else edit->scrollbar.y = 0;
22963  }
22964 
22965  /* scrollbar widget */
22966  if (flags & NK_EDIT_MULTILINE)
22967  {
22968  nk_flags ws;
22969  struct nk_rect scroll;
22970  float scroll_target;
22971  float scroll_offset;
22972  float scroll_step;
22973  float scroll_inc;
22974 
22975  scroll = area;
22976  scroll.x = (bounds.x + bounds.w - style->border) - style->scrollbar_size.x;
22977  scroll.w = style->scrollbar_size.x;
22978 
22979  scroll_offset = edit->scrollbar.y;
22980  scroll_step = scroll.h * 0.10f;
22981  scroll_inc = scroll.h * 0.01f;
22982  scroll_target = text_size.y;
22983  edit->scrollbar.y = nk_do_scrollbarv(&ws, out, scroll, 0,
22984  scroll_offset, scroll_target, scroll_step, scroll_inc,
22985  &style->scrollbar, in, font);
22986  }
22987  }
22988 
22989  /* draw text */
22990  {struct nk_color background_color;
22991  struct nk_color text_color;
22992  struct nk_color sel_background_color;
22993  struct nk_color sel_text_color;
22994  struct nk_color cursor_color;
22995  struct nk_color cursor_text_color;
22996  const struct nk_style_item *background;
22997  nk_push_scissor(out, clip);
22998 
22999  /* select correct colors to draw */
23000  if (*state & NK_WIDGET_STATE_ACTIVED) {
23001  background = &style->active;
23002  text_color = style->text_active;
23003  sel_text_color = style->selected_text_hover;
23004  sel_background_color = style->selected_hover;
23005  cursor_color = style->cursor_hover;
23006  cursor_text_color = style->cursor_text_hover;
23007  } else if (*state & NK_WIDGET_STATE_HOVER) {
23008  background = &style->hover;
23009  text_color = style->text_hover;
23010  sel_text_color = style->selected_text_hover;
23011  sel_background_color = style->selected_hover;
23012  cursor_text_color = style->cursor_text_hover;
23013  cursor_color = style->cursor_hover;
23014  } else {
23015  background = &style->normal;
23016  text_color = style->text_normal;
23017  sel_text_color = style->selected_text_normal;
23018  sel_background_color = style->selected_normal;
23019  cursor_color = style->cursor_normal;
23020  cursor_text_color = style->cursor_text_normal;
23021  }
23022  if (background->type == NK_STYLE_ITEM_IMAGE)
23023  background_color = nk_rgba(0,0,0,0);
23024  else background_color = background->data.color;
23025 
23026 
23027  if (edit->select_start == edit->select_end) {
23028  /* no selection so just draw the complete text */
23029  const char *begin = nk_str_get_const(&edit->string);
23030  int l = nk_str_len_char(&edit->string);
23031  nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
23032  area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
23033  background_color, text_color, nk_false);
23034  } else {
23035  /* edit has selection so draw 1-3 text chunks */
23036  if (edit->select_start != edit->select_end && selection_begin > 0){
23037  /* draw unselected text before selection */
23038  const char *begin = nk_str_get_const(&edit->string);
23039  NK_ASSERT(select_begin_ptr);
23040  nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
23041  area.y - edit->scrollbar.y, 0, begin, (int)(select_begin_ptr - begin),
23042  row_height, font, background_color, text_color, nk_false);
23043  }
23044  if (edit->select_start != edit->select_end) {
23045  /* draw selected text */
23046  NK_ASSERT(select_begin_ptr);
23047  if (!select_end_ptr) {
23048  const char *begin = nk_str_get_const(&edit->string);
23049  select_end_ptr = begin + nk_str_len_char(&edit->string);
23050  }
23051  nk_edit_draw_text(out, style,
23052  area.x - edit->scrollbar.x,
23053  area.y + selection_offset_start.y - edit->scrollbar.y,
23054  selection_offset_start.x,
23055  select_begin_ptr, (int)(select_end_ptr - select_begin_ptr),
23056  row_height, font, sel_background_color, sel_text_color, nk_true);
23057  }
23058  if ((edit->select_start != edit->select_end &&
23059  selection_end < edit->string.len))
23060  {
23061  /* draw unselected text after selected text */
23062  const char *begin = select_end_ptr;
23063  const char *end = nk_str_get_const(&edit->string) +
23064  nk_str_len_char(&edit->string);
23065  NK_ASSERT(select_end_ptr);
23066  nk_edit_draw_text(out, style,
23067  area.x - edit->scrollbar.x,
23068  area.y + selection_offset_end.y - edit->scrollbar.y,
23069  selection_offset_end.x,
23070  begin, (int)(end - begin), row_height, font,
23071  background_color, text_color, nk_true);
23072  }
23073  }
23074 
23075  /* cursor */
23076  if (edit->select_start == edit->select_end)
23077  {
23078  if (edit->cursor >= nk_str_len(&edit->string) ||
23079  (cursor_ptr && *cursor_ptr == '\n')) {
23080  /* draw cursor at end of line */
23081  struct nk_rect cursor;
23082  cursor.w = style->cursor_size;
23083  cursor.h = font->height;
23084  cursor.x = area.x + cursor_pos.x - edit->scrollbar.x;
23085  cursor.y = area.y + cursor_pos.y + row_height/2.0f - cursor.h/2.0f;
23086  cursor.y -= edit->scrollbar.y;
23087  nk_fill_rect(out, cursor, 0, cursor_color);
23088  } else {
23089  /* draw cursor inside text */
23090  int glyph_len;
23091  struct nk_rect label;
23092  struct nk_text txt;
23093 
23094  nk_rune unicode;
23095  NK_ASSERT(cursor_ptr);
23096  glyph_len = nk_utf_decode(cursor_ptr, &unicode, 4);
23097 
23098  label.x = area.x + cursor_pos.x - edit->scrollbar.x;
23099  label.y = area.y + cursor_pos.y - edit->scrollbar.y;
23100  label.w = font->width(font->userdata, font->height, cursor_ptr, glyph_len);
23101  label.h = row_height;
23102 
23103  txt.padding = nk_vec2(0,0);
23104  txt.background = cursor_color;;
23105  txt.text = cursor_text_color;
23106  nk_fill_rect(out, label, 0, cursor_color);
23107  nk_widget_text(out, label, cursor_ptr, glyph_len, &txt, NK_TEXT_LEFT, font);
23108  }
23109  }}
23110  } else {
23111  /* not active so just draw text */
23112  int l = nk_str_len_char(&edit->string);
23113  const char *begin = nk_str_get_const(&edit->string);
23114 
23115  const struct nk_style_item *background;
23116  struct nk_color background_color;
23117  struct nk_color text_color;
23118  nk_push_scissor(out, clip);
23119  if (*state & NK_WIDGET_STATE_ACTIVED) {
23120  background = &style->active;
23121  text_color = style->text_active;
23122  } else if (*state & NK_WIDGET_STATE_HOVER) {
23123  background = &style->hover;
23124  text_color = style->text_hover;
23125  } else {
23126  background = &style->normal;
23127  text_color = style->text_normal;
23128  }
23129  if (background->type == NK_STYLE_ITEM_IMAGE)
23130  background_color = nk_rgba(0,0,0,0);
23131  else background_color = background->data.color;
23132  nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
23133  area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
23134  background_color, text_color, nk_false);
23135  }
23136  nk_push_scissor(out, old_clip);}
23137  return ret;
23138 }
23139 NK_API void
23140 nk_edit_focus(struct nk_context *ctx, nk_flags flags)
23141 {
23142  nk_hash hash;
23143  struct nk_window *win;
23144 
23145  NK_ASSERT(ctx);
23146  NK_ASSERT(ctx->current);
23147  if (!ctx || !ctx->current) return;
23148 
23149  win = ctx->current;
23150  hash = win->edit.seq;
23151  win->edit.active = nk_true;
23152  win->edit.name = hash;
23153  if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
23155 }
23156 NK_API void
23157 nk_edit_unfocus(struct nk_context *ctx)
23158 {
23159  struct nk_window *win;
23160  NK_ASSERT(ctx);
23161  NK_ASSERT(ctx->current);
23162  if (!ctx || !ctx->current) return;
23163 
23164  win = ctx->current;
23165  win->edit.active = nk_false;
23166  win->edit.name = 0;
23167 }
23168 NK_API nk_flags
23169 nk_edit_string(struct nk_context *ctx, nk_flags flags,
23170  char *memory, int *len, int max, nk_plugin_filter filter)
23171 {
23172  nk_hash hash;
23173  nk_flags state;
23174  struct nk_text_edit *edit;
23175  struct nk_window *win;
23176 
23177  NK_ASSERT(ctx);
23178  NK_ASSERT(memory);
23179  NK_ASSERT(len);
23180  if (!ctx || !memory || !len)
23181  return 0;
23182 
23183  filter = (!filter) ? nk_filter_default: filter;
23184  win = ctx->current;
23185  hash = win->edit.seq;
23186  edit = &ctx->text_edit;
23187  nk_textedit_clear_state(&ctx->text_edit, (flags & NK_EDIT_MULTILINE)?
23189 
23190  if (win->edit.active && hash == win->edit.name) {
23191  if (flags & NK_EDIT_NO_CURSOR)
23192  edit->cursor = nk_utf_len(memory, *len);
23193  else edit->cursor = win->edit.cursor;
23194  if (!(flags & NK_EDIT_SELECTABLE)) {
23195  edit->select_start = win->edit.cursor;
23196  edit->select_end = win->edit.cursor;
23197  } else {
23198  edit->select_start = win->edit.sel_start;
23199  edit->select_end = win->edit.sel_end;
23200  }
23201  edit->mode = win->edit.mode;
23202  edit->scrollbar.x = (float)win->edit.scrollbar.x;
23203  edit->scrollbar.y = (float)win->edit.scrollbar.y;
23204  edit->active = nk_true;
23205  } else edit->active = nk_false;
23206 
23207  max = NK_MAX(1, max);
23208  *len = NK_MIN(*len, max-1);
23209  nk_str_init_fixed(&edit->string, memory, (nk_size)max);
23210  edit->string.buffer.allocated = (nk_size)*len;
23211  edit->string.len = nk_utf_len(memory, *len);
23212  state = nk_edit_buffer(ctx, flags, edit, filter);
23213  *len = (int)edit->string.buffer.allocated;
23214 
23215  if (edit->active) {
23216  win->edit.cursor = edit->cursor;
23217  win->edit.sel_start = edit->select_start;
23218  win->edit.sel_end = edit->select_end;
23219  win->edit.mode = edit->mode;
23220  win->edit.scrollbar.x = (nk_uint)edit->scrollbar.x;
23221  win->edit.scrollbar.y = (nk_uint)edit->scrollbar.y;
23222  } return state;
23223 }
23224 NK_API nk_flags
23225 nk_edit_buffer(struct nk_context *ctx, nk_flags flags,
23226  struct nk_text_edit *edit, nk_plugin_filter filter)
23227 {
23228  struct nk_window *win;
23229  struct nk_style *style;
23230  struct nk_input *in;
23231 
23233  struct nk_rect bounds;
23234 
23235  nk_flags ret_flags = 0;
23236  unsigned char prev_state;
23237  nk_hash hash;
23238 
23239  /* make sure correct values */
23240  NK_ASSERT(ctx);
23241  NK_ASSERT(edit);
23242  NK_ASSERT(ctx->current);
23243  NK_ASSERT(ctx->current->layout);
23244  if (!ctx || !ctx->current || !ctx->current->layout)
23245  return 0;
23246 
23247  win = ctx->current;
23248  style = &ctx->style;
23249  state = nk_widget(&bounds, ctx);
23250  if (!state) return state;
23251  in = (win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
23252 
23253  /* check if edit is currently hot item */
23254  hash = win->edit.seq++;
23255  if (win->edit.active && hash == win->edit.name) {
23256  if (flags & NK_EDIT_NO_CURSOR)
23257  edit->cursor = edit->string.len;
23258  if (!(flags & NK_EDIT_SELECTABLE)) {
23259  edit->select_start = edit->cursor;
23260  edit->select_end = edit->cursor;
23261  }
23262  if (flags & NK_EDIT_CLIPBOARD)
23263  edit->clip = ctx->clip;
23264  edit->active = (unsigned char)win->edit.active;
23265  } else edit->active = nk_false;
23266  edit->mode = win->edit.mode;
23267 
23268  filter = (!filter) ? nk_filter_default: filter;
23269  prev_state = (unsigned char)edit->active;
23270  in = (flags & NK_EDIT_READ_ONLY) ? 0: in;
23271  ret_flags = nk_do_edit(&ctx->last_widget_state, &win->buffer, bounds, flags,
23272  filter, edit, &style->edit, in, style->font);
23273 
23274  if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
23276  if (edit->active && prev_state != edit->active) {
23277  /* current edit is now hot */
23278  win->edit.active = nk_true;
23279  win->edit.name = hash;
23280  } else if (prev_state && !edit->active) {
23281  /* current edit is now cold */
23282  win->edit.active = nk_false;
23283  } return ret_flags;
23284 }
23285 NK_API nk_flags
23286 nk_edit_string_zero_terminated(struct nk_context *ctx, nk_flags flags,
23287  char *buffer, int max, nk_plugin_filter filter)
23288 {
23289  nk_flags result;
23290  int len = nk_strlen(buffer);
23291  result = nk_edit_string(ctx, flags, buffer, &len, max, filter);
23292  buffer[NK_MIN(NK_MAX(max-1,0), len)] = '\0';
23293  return result;
23294 }
23295 
23296 
23297 
23298 
23299 
23300 /* ===============================================================
23301  *
23302  * PROPERTY
23303  *
23304  * ===============================================================*/
23305 NK_LIB void
23306 nk_drag_behavior(nk_flags *state, const struct nk_input *in,
23307  struct nk_rect drag, struct nk_property_variant *variant,
23308  float inc_per_pixel)
23309 {
23310  int left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
23311  int left_mouse_click_in_cursor = in &&
23313 
23314  nk_widget_state_reset(state);
23315  if (nk_input_is_mouse_hovering_rect(in, drag))
23316  *state = NK_WIDGET_STATE_HOVERED;
23317 
23318  if (left_mouse_down && left_mouse_click_in_cursor) {
23319  float delta, pixels;
23320  pixels = in->mouse.delta.x;
23321  delta = pixels * inc_per_pixel;
23322  switch (variant->kind) {
23323  default: break;
23324  case NK_PROPERTY_INT:
23325  variant->value.i = variant->value.i + (int)delta;
23326  variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
23327  break;
23328  case NK_PROPERTY_FLOAT:
23329  variant->value.f = variant->value.f + (float)delta;
23330  variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
23331  break;
23332  case NK_PROPERTY_DOUBLE:
23333  variant->value.d = variant->value.d + (double)delta;
23334  variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
23335  break;
23336  }
23337  *state = NK_WIDGET_STATE_ACTIVE;
23338  }
23339  if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, drag))
23340  *state |= NK_WIDGET_STATE_ENTERED;
23341  else if (nk_input_is_mouse_prev_hovering_rect(in, drag))
23342  *state |= NK_WIDGET_STATE_LEFT;
23343 }
23344 NK_LIB void
23345 nk_property_behavior(nk_flags *ws, const struct nk_input *in,
23346  struct nk_rect property, struct nk_rect label, struct nk_rect edit,
23347  struct nk_rect empty, int *state, struct nk_property_variant *variant,
23348  float inc_per_pixel)
23349 {
23350  if (in && *state == NK_PROPERTY_DEFAULT) {
23351  if (nk_button_behavior(ws, edit, in, NK_BUTTON_DEFAULT))
23352  *state = NK_PROPERTY_EDIT;
23353  else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, label, nk_true))
23354  *state = NK_PROPERTY_DRAG;
23355  else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, empty, nk_true))
23356  *state = NK_PROPERTY_DRAG;
23357  }
23358  if (*state == NK_PROPERTY_DRAG) {
23359  nk_drag_behavior(ws, in, property, variant, inc_per_pixel);
23360  if (!(*ws & NK_WIDGET_STATE_ACTIVED)) *state = NK_PROPERTY_DEFAULT;
23361  }
23362 }
23363 NK_LIB void
23364 nk_draw_property(struct nk_command_buffer *out, const struct nk_style_property *style,
23365  const struct nk_rect *bounds, const struct nk_rect *label, nk_flags state,
23366  const char *name, int len, const struct nk_user_font *font)
23367 {
23368  struct nk_text text;
23369  const struct nk_style_item *background;
23370 
23371  /* select correct background and text color */
23372  if (state & NK_WIDGET_STATE_ACTIVED) {
23373  background = &style->active;
23374  text.text = style->label_active;
23375  } else if (state & NK_WIDGET_STATE_HOVER) {
23376  background = &style->hover;
23377  text.text = style->label_hover;
23378  } else {
23379  background = &style->normal;
23380  text.text = style->label_normal;
23381  }
23382 
23383  /* draw background */
23384  if (background->type == NK_STYLE_ITEM_IMAGE) {
23385  nk_draw_image(out, *bounds, &background->data.image, nk_white);
23386  text.background = nk_rgba(0,0,0,0);
23387  } else {
23388  text.background = background->data.color;
23389  nk_fill_rect(out, *bounds, style->rounding, background->data.color);
23390  nk_stroke_rect(out, *bounds, style->rounding, style->border, background->data.color);
23391  }
23392 
23393  /* draw label */
23394  text.padding = nk_vec2(0,0);
23395  nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font);
23396 }
23397 NK_LIB void
23398 nk_do_property(nk_flags *ws,
23399  struct nk_command_buffer *out, struct nk_rect property,
23400  const char *name, struct nk_property_variant *variant,
23401  float inc_per_pixel, char *buffer, int *len,
23402  int *state, int *cursor, int *select_begin, int *select_end,
23403  const struct nk_style_property *style,
23404  enum nk_property_filter filter, struct nk_input *in,
23405  const struct nk_user_font *font, struct nk_text_edit *text_edit,
23406  enum nk_button_behavior behavior)
23407 {
23408  const nk_plugin_filter filters[] = {
23411  };
23412  int active, old;
23413  int num_len, name_len;
23414  char string[NK_MAX_NUMBER_BUFFER];
23415  float size;
23416 
23417  char *dst = 0;
23418  int *length;
23419 
23420  struct nk_rect left;
23421  struct nk_rect right;
23422  struct nk_rect label;
23423  struct nk_rect edit;
23424  struct nk_rect empty;
23425 
23426  /* left decrement button */
23427  left.h = font->height/2;
23428  left.w = left.h;
23429  left.x = property.x + style->border + style->padding.x;
23430  left.y = property.y + style->border + property.h/2.0f - left.h/2;
23431 
23432  /* text label */
23433  name_len = nk_strlen(name);
23434  size = font->width(font->userdata, font->height, name, name_len);
23435  label.x = left.x + left.w + style->padding.x;
23436  label.w = (float)size + 2 * style->padding.x;
23437  label.y = property.y + style->border + style->padding.y;
23438  label.h = property.h - (2 * style->border + 2 * style->padding.y);
23439 
23440  /* right increment button */
23441  right.y = left.y;
23442  right.w = left.w;
23443  right.h = left.h;
23444  right.x = property.x + property.w - (right.w + style->padding.x);
23445 
23446  /* edit */
23447  if (*state == NK_PROPERTY_EDIT) {
23448  size = font->width(font->userdata, font->height, buffer, *len);
23449  size += style->edit.cursor_size;
23450  length = len;
23451  dst = buffer;
23452  } else {
23453  switch (variant->kind) {
23454  default: break;
23455  case NK_PROPERTY_INT:
23456  nk_itoa(string, variant->value.i);
23457  num_len = nk_strlen(string);
23458  break;
23459  case NK_PROPERTY_FLOAT:
23460  NK_DTOA(string, (double)variant->value.f);
23461  num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
23462  break;
23463  case NK_PROPERTY_DOUBLE:
23464  NK_DTOA(string, variant->value.d);
23465  num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
23466  break;
23467  }
23468  size = font->width(font->userdata, font->height, string, num_len);
23469  dst = string;
23470  length = &num_len;
23471  }
23472 
23473  edit.w = (float)size + 2 * style->padding.x;
23474  edit.w = NK_MIN(edit.w, right.x - (label.x + label.w));
23475  edit.x = right.x - (edit.w + style->padding.x);
23476  edit.y = property.y + style->border;
23477  edit.h = property.h - (2 * style->border);
23478 
23479  /* empty left space activator */
23480  empty.w = edit.x - (label.x + label.w);
23481  empty.x = label.x + label.w;
23482  empty.y = property.y;
23483  empty.h = property.h;
23484 
23485  /* update property */
23486  old = (*state == NK_PROPERTY_EDIT);
23487  nk_property_behavior(ws, in, property, label, edit, empty, state, variant, inc_per_pixel);
23488 
23489  /* draw property */
23490  if (style->draw_begin) style->draw_begin(out, style->userdata);
23491  nk_draw_property(out, style, &property, &label, *ws, name, name_len, font);
23492  if (style->draw_end) style->draw_end(out, style->userdata);
23493 
23494  /* execute right button */
23495  if (nk_do_button_symbol(ws, out, left, style->sym_left, behavior, &style->dec_button, in, font)) {
23496  switch (variant->kind) {
23497  default: break;
23498  case NK_PROPERTY_INT:
23499  variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i - variant->step.i, variant->max_value.i); break;
23500  case NK_PROPERTY_FLOAT:
23501  variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f - variant->step.f, variant->max_value.f); break;
23502  case NK_PROPERTY_DOUBLE:
23503  variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d - variant->step.d, variant->max_value.d); break;
23504  }
23505  }
23506  /* execute left button */
23507  if (nk_do_button_symbol(ws, out, right, style->sym_right, behavior, &style->inc_button, in, font)) {
23508  switch (variant->kind) {
23509  default: break;
23510  case NK_PROPERTY_INT:
23511  variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i + variant->step.i, variant->max_value.i); break;
23512  case NK_PROPERTY_FLOAT:
23513  variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f + variant->step.f, variant->max_value.f); break;
23514  case NK_PROPERTY_DOUBLE:
23515  variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d + variant->step.d, variant->max_value.d); break;
23516  }
23517  }
23518  if (old != NK_PROPERTY_EDIT && (*state == NK_PROPERTY_EDIT)) {
23519  /* property has been activated so setup buffer */
23520  NK_MEMCPY(buffer, dst, (nk_size)*length);
23521  *cursor = nk_utf_len(buffer, *length);
23522  *len = *length;
23523  length = len;
23524  dst = buffer;
23525  active = 0;
23526  } else active = (*state == NK_PROPERTY_EDIT);
23527 
23528  /* execute and run text edit field */
23529  nk_textedit_clear_state(text_edit, NK_TEXT_EDIT_SINGLE_LINE, filters[filter]);
23530  text_edit->active = (unsigned char)active;
23531  text_edit->string.len = *length;
23532  text_edit->cursor = NK_CLAMP(0, *cursor, *length);
23533  text_edit->select_start = NK_CLAMP(0,*select_begin, *length);
23534  text_edit->select_end = NK_CLAMP(0,*select_end, *length);
23535  text_edit->string.buffer.allocated = (nk_size)*length;
23537  text_edit->string.buffer.memory.ptr = dst;
23538  text_edit->string.buffer.size = NK_MAX_NUMBER_BUFFER;
23539  text_edit->mode = NK_TEXT_EDIT_MODE_INSERT;
23540  nk_do_edit(ws, out, edit, NK_EDIT_FIELD|NK_EDIT_AUTO_SELECT,
23541  filters[filter], text_edit, &style->edit, (*state == NK_PROPERTY_EDIT) ? in: 0, font);
23542 
23543  *length = text_edit->string.len;
23544  *cursor = text_edit->cursor;
23545  *select_begin = text_edit->select_start;
23546  *select_end = text_edit->select_end;
23547  if (text_edit->active && nk_input_is_key_pressed(in, NK_KEY_ENTER))
23548  text_edit->active = nk_false;
23549 
23550  if (active && !text_edit->active) {
23551  /* property is now not active so convert edit text to value*/
23552  *state = NK_PROPERTY_DEFAULT;
23553  buffer[*len] = '\0';
23554  switch (variant->kind) {
23555  default: break;
23556  case NK_PROPERTY_INT:
23557  variant->value.i = nk_strtoi(buffer, 0);
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  nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
23562  variant->value.f = nk_strtof(buffer, 0);
23563  variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
23564  break;
23565  case NK_PROPERTY_DOUBLE:
23566  nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
23567  variant->value.d = nk_strtod(buffer, 0);
23568  variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
23569  break;
23570  }
23571  }
23572 }
23573 NK_LIB struct nk_property_variant
23574 nk_property_variant_int(int value, int min_value, int max_value, int step)
23575 {
23576  struct nk_property_variant result;
23577  result.kind = NK_PROPERTY_INT;
23578  result.value.i = value;
23579  result.min_value.i = min_value;
23580  result.max_value.i = max_value;
23581  result.step.i = step;
23582  return result;
23583 }
23584 NK_LIB struct nk_property_variant
23585 nk_property_variant_float(float value, float min_value, float max_value, float step)
23586 {
23587  struct nk_property_variant result;
23588  result.kind = NK_PROPERTY_FLOAT;
23589  result.value.f = value;
23590  result.min_value.f = min_value;
23591  result.max_value.f = max_value;
23592  result.step.f = step;
23593  return result;
23594 }
23595 NK_LIB struct nk_property_variant
23596 nk_property_variant_double(double value, double min_value, double max_value,
23597  double step)
23598 {
23599  struct nk_property_variant result;
23600  result.kind = NK_PROPERTY_DOUBLE;
23601  result.value.d = value;
23602  result.min_value.d = min_value;
23603  result.max_value.d = max_value;
23604  result.step.d = step;
23605  return result;
23606 }
23607 NK_LIB void
23608 nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant *variant,
23609  float inc_per_pixel, const enum nk_property_filter filter)
23610 {
23611  struct nk_window *win;
23612  struct nk_panel *layout;
23613  struct nk_input *in;
23614  const struct nk_style *style;
23615 
23616  struct nk_rect bounds;
23618 
23619  int *state = 0;
23620  nk_hash hash = 0;
23621  char *buffer = 0;
23622  int *len = 0;
23623  int *cursor = 0;
23624  int *select_begin = 0;
23625  int *select_end = 0;
23626  int old_state;
23627 
23628  char dummy_buffer[NK_MAX_NUMBER_BUFFER];
23629  int dummy_state = NK_PROPERTY_DEFAULT;
23630  int dummy_length = 0;
23631  int dummy_cursor = 0;
23632  int dummy_select_begin = 0;
23633  int dummy_select_end = 0;
23634 
23635  NK_ASSERT(ctx);
23636  NK_ASSERT(ctx->current);
23637  NK_ASSERT(ctx->current->layout);
23638  if (!ctx || !ctx->current || !ctx->current->layout)
23639  return;
23640 
23641  win = ctx->current;
23642  layout = win->layout;
23643  style = &ctx->style;
23644  s = nk_widget(&bounds, ctx);
23645  if (!s) return;
23646 
23647  /* calculate hash from name */
23648  if (name[0] == '#') {
23649  hash = nk_murmur_hash(name, (int)nk_strlen(name), win->property.seq++);
23650  name++; /* special number hash */
23651  } else hash = nk_murmur_hash(name, (int)nk_strlen(name), 42);
23652 
23653  /* check if property is currently hot item */
23654  if (win->property.active && hash == win->property.name) {
23655  buffer = win->property.buffer;
23656  len = &win->property.length;
23657  cursor = &win->property.cursor;
23658  state = &win->property.state;
23659  select_begin = &win->property.select_start;
23660  select_end = &win->property.select_end;
23661  } else {
23662  buffer = dummy_buffer;
23663  len = &dummy_length;
23664  cursor = &dummy_cursor;
23665  state = &dummy_state;
23666  select_begin = &dummy_select_begin;
23667  select_end = &dummy_select_end;
23668  }
23669 
23670  /* execute property widget */
23671  old_state = *state;
23672  ctx->text_edit.clip = ctx->clip;
23673  in = ((s == NK_WIDGET_ROM && !win->property.active) ||
23674  layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
23675  nk_do_property(&ctx->last_widget_state, &win->buffer, bounds, name,
23676  variant, inc_per_pixel, buffer, len, state, cursor, select_begin,
23677  select_end, &style->property, filter, in, style->font, &ctx->text_edit,
23678  ctx->button_behavior);
23679 
23680  if (in && *state != NK_PROPERTY_DEFAULT && !win->property.active) {
23681  /* current property is now hot */
23682  win->property.active = 1;
23683  NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len);
23684  win->property.length = *len;
23685  win->property.cursor = *cursor;
23686  win->property.state = *state;
23687  win->property.name = hash;
23688  win->property.select_start = *select_begin;
23689  win->property.select_end = *select_end;
23690  if (*state == NK_PROPERTY_DRAG) {
23691  ctx->input.mouse.grab = nk_true;
23692  ctx->input.mouse.grabbed = nk_true;
23693  }
23694  }
23695  /* check if previously active property is now inactive */
23696  if (*state == NK_PROPERTY_DEFAULT && old_state != NK_PROPERTY_DEFAULT) {
23697  if (old_state == NK_PROPERTY_DRAG) {
23698  ctx->input.mouse.grab = nk_false;
23699  ctx->input.mouse.grabbed = nk_false;
23700  ctx->input.mouse.ungrab = nk_true;
23701  }
23702  win->property.select_start = 0;
23703  win->property.select_end = 0;
23704  win->property.active = 0;
23705  }
23706 }
23707 NK_API void
23708 nk_property_int(struct nk_context *ctx, const char *name,
23709  int min, int *val, int max, int step, float inc_per_pixel)
23710 {
23711  struct nk_property_variant variant;
23712  NK_ASSERT(ctx);
23713  NK_ASSERT(name);
23714  NK_ASSERT(val);
23715 
23716  if (!ctx || !ctx->current || !name || !val) return;
23717  variant = nk_property_variant_int(*val, min, max, step);
23718  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
23719  *val = variant.value.i;
23720 }
23721 NK_API void
23722 nk_property_float(struct nk_context *ctx, const char *name,
23723  float min, float *val, float max, float step, float inc_per_pixel)
23724 {
23725  struct nk_property_variant variant;
23726  NK_ASSERT(ctx);
23727  NK_ASSERT(name);
23728  NK_ASSERT(val);
23729 
23730  if (!ctx || !ctx->current || !name || !val) return;
23731  variant = nk_property_variant_float(*val, min, max, step);
23732  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
23733  *val = variant.value.f;
23734 }
23735 NK_API void
23736 nk_property_double(struct nk_context *ctx, const char *name,
23737  double min, double *val, double max, double step, float inc_per_pixel)
23738 {
23739  struct nk_property_variant variant;
23740  NK_ASSERT(ctx);
23741  NK_ASSERT(name);
23742  NK_ASSERT(val);
23743 
23744  if (!ctx || !ctx->current || !name || !val) return;
23745  variant = nk_property_variant_double(*val, min, max, step);
23746  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
23747  *val = variant.value.d;
23748 }
23749 NK_API int
23750 nk_propertyi(struct nk_context *ctx, const char *name, int min, int val,
23751  int max, int step, float inc_per_pixel)
23752 {
23753  struct nk_property_variant variant;
23754  NK_ASSERT(ctx);
23755  NK_ASSERT(name);
23756 
23757  if (!ctx || !ctx->current || !name) return val;
23758  variant = nk_property_variant_int(val, min, max, step);
23759  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
23760  val = variant.value.i;
23761  return val;
23762 }
23763 NK_API float
23764 nk_propertyf(struct nk_context *ctx, const char *name, float min,
23765  float val, float max, float step, float inc_per_pixel)
23766 {
23767  struct nk_property_variant variant;
23768  NK_ASSERT(ctx);
23769  NK_ASSERT(name);
23770 
23771  if (!ctx || !ctx->current || !name) return val;
23772  variant = nk_property_variant_float(val, min, max, step);
23773  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
23774  val = variant.value.f;
23775  return val;
23776 }
23777 NK_API double
23778 nk_propertyd(struct nk_context *ctx, const char *name, double min,
23779  double val, double max, double step, float inc_per_pixel)
23780 {
23781  struct nk_property_variant variant;
23782  NK_ASSERT(ctx);
23783  NK_ASSERT(name);
23784 
23785  if (!ctx || !ctx->current || !name) return val;
23786  variant = nk_property_variant_double(val, min, max, step);
23787  nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
23788  val = variant.value.d;
23789  return val;
23790 }
23791 
23792 
23793 
23794 
23795 
23796 /* ==============================================================
23797  *
23798  * CHART
23799  *
23800  * ===============================================================*/
23801 NK_API int
23802 nk_chart_begin_colored(struct nk_context *ctx, enum nk_chart_type type,
23803  struct nk_color color, struct nk_color highlight,
23804  int count, float min_value, float max_value)
23805 {
23806  struct nk_window *win;
23807  struct nk_chart *chart;
23808  const struct nk_style *config;
23809  const struct nk_style_chart *style;
23810 
23811  const struct nk_style_item *background;
23812  struct nk_rect bounds = {0, 0, 0, 0};
23813 
23814  NK_ASSERT(ctx);
23815  NK_ASSERT(ctx->current);
23816  NK_ASSERT(ctx->current->layout);
23817 
23818  if (!ctx || !ctx->current || !ctx->current->layout) return 0;
23819  if (!nk_widget(&bounds, ctx)) {
23820  chart = &ctx->current->layout->chart;
23821  nk_zero(chart, sizeof(*chart));
23822  return 0;
23823  }
23824 
23825  win = ctx->current;
23826  config = &ctx->style;
23827  chart = &win->layout->chart;
23828  style = &config->chart;
23829 
23830  /* setup basic generic chart */
23831  nk_zero(chart, sizeof(*chart));
23832  chart->x = bounds.x + style->padding.x;
23833  chart->y = bounds.y + style->padding.y;
23834  chart->w = bounds.w - 2 * style->padding.x;
23835  chart->h = bounds.h - 2 * style->padding.y;
23836  chart->w = NK_MAX(chart->w, 2 * style->padding.x);
23837  chart->h = NK_MAX(chart->h, 2 * style->padding.y);
23838 
23839  /* add first slot into chart */
23840  {struct nk_chart_slot *slot = &chart->slots[chart->slot++];
23841  slot->type = type;
23842  slot->count = count;
23843  slot->color = color;
23844  slot->highlight = highlight;
23845  slot->min = NK_MIN(min_value, max_value);
23846  slot->max = NK_MAX(min_value, max_value);
23847  slot->range = slot->max - slot->min;}
23848 
23849  /* draw chart background */
23850  background = &style->background;
23851  if (background->type == NK_STYLE_ITEM_IMAGE) {
23852  nk_draw_image(&win->buffer, bounds, &background->data.image, nk_white);
23853  } else {
23854  nk_fill_rect(&win->buffer, bounds, style->rounding, style->border_color);
23855  nk_fill_rect(&win->buffer, nk_shrink_rect(bounds, style->border),
23856  style->rounding, style->background.data.color);
23857  }
23858  return 1;
23859 }
23860 NK_API int
23861 nk_chart_begin(struct nk_context *ctx, const enum nk_chart_type type,
23862  int count, float min_value, float max_value)
23863 {
23864  return nk_chart_begin_colored(ctx, type, ctx->style.chart.color,
23865  ctx->style.chart.selected_color, count, min_value, max_value);
23866 }
23867 NK_API void
23868 nk_chart_add_slot_colored(struct nk_context *ctx, const enum nk_chart_type type,
23869  struct nk_color color, struct nk_color highlight,
23870  int count, float min_value, float max_value)
23871 {
23872  NK_ASSERT(ctx);
23873  NK_ASSERT(ctx->current);
23874  NK_ASSERT(ctx->current->layout);
23875  NK_ASSERT(ctx->current->layout->chart.slot < NK_CHART_MAX_SLOT);
23876  if (!ctx || !ctx->current || !ctx->current->layout) return;
23877  if (ctx->current->layout->chart.slot >= NK_CHART_MAX_SLOT) return;
23878 
23879  /* add another slot into the graph */
23880  {struct nk_chart *chart = &ctx->current->layout->chart;
23881  struct nk_chart_slot *slot = &chart->slots[chart->slot++];
23882  slot->type = type;
23883  slot->count = count;
23884  slot->color = color;
23885  slot->highlight = highlight;
23886  slot->min = NK_MIN(min_value, max_value);
23887  slot->max = NK_MAX(min_value, max_value);
23888  slot->range = slot->max - slot->min;}
23889 }
23890 NK_API void
23891 nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type type,
23892  int count, float min_value, float max_value)
23893 {
23894  nk_chart_add_slot_colored(ctx, type, ctx->style.chart.color,
23895  ctx->style.chart.selected_color, count, min_value, max_value);
23896 }
23897 NK_INTERN nk_flags
23898 nk_chart_push_line(struct nk_context *ctx, struct nk_window *win,
23899  struct nk_chart *g, float value, int slot)
23900 {
23901  struct nk_panel *layout = win->layout;
23902  const struct nk_input *i = &ctx->input;
23903  struct nk_command_buffer *out = &win->buffer;
23904 
23905  nk_flags ret = 0;
23906  struct nk_vec2 cur;
23907  struct nk_rect bounds;
23908  struct nk_color color;
23909  float step;
23910  float range;
23911  float ratio;
23912 
23913  NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
23914  step = g->w / (float)g->slots[slot].count;
23915  range = g->slots[slot].max - g->slots[slot].min;
23916  ratio = (value - g->slots[slot].min) / range;
23917 
23918  if (g->slots[slot].index == 0) {
23919  /* first data point does not have a connection */
23920  g->slots[slot].last.x = g->x;
23921  g->slots[slot].last.y = (g->y + g->h) - ratio * (float)g->h;
23922 
23923  bounds.x = g->slots[slot].last.x - 2;
23924  bounds.y = g->slots[slot].last.y - 2;
23925  bounds.w = bounds.h = 4;
23926 
23927  color = g->slots[slot].color;
23928  if (!(layout->flags & NK_WINDOW_ROM) &&
23929  NK_INBOX(i->mouse.pos.x,i->mouse.pos.y, g->slots[slot].last.x-3, g->slots[slot].last.y-3, 6, 6)){
23930  ret = nk_input_is_mouse_hovering_rect(i, bounds) ? NK_CHART_HOVERING : 0;
23931  ret |= (i->mouse.buttons[NK_BUTTON_LEFT].down &&
23933  color = g->slots[slot].highlight;
23934  }
23935  nk_fill_rect(out, bounds, 0, color);
23936  g->slots[slot].index += 1;
23937  return ret;
23938  }
23939 
23940  /* draw a line between the last data point and the new one */
23941  color = g->slots[slot].color;
23942  cur.x = g->x + (float)(step * (float)g->slots[slot].index);
23943  cur.y = (g->y + g->h) - (ratio * (float)g->h);
23944  nk_stroke_line(out, g->slots[slot].last.x, g->slots[slot].last.y, cur.x, cur.y, 1.0f, color);
23945 
23946  bounds.x = cur.x - 3;
23947  bounds.y = cur.y - 3;
23948  bounds.w = bounds.h = 6;
23949 
23950  /* user selection of current data point */
23951  if (!(layout->flags & NK_WINDOW_ROM)) {
23952  if (nk_input_is_mouse_hovering_rect(i, bounds)) {
23953  ret = NK_CHART_HOVERING;
23954  ret |= (!i->mouse.buttons[NK_BUTTON_LEFT].down &&
23956  color = g->slots[slot].highlight;
23957  }
23958  }
23959  nk_fill_rect(out, nk_rect(cur.x - 2, cur.y - 2, 4, 4), 0, color);
23960 
23961  /* save current data point position */
23962  g->slots[slot].last.x = cur.x;
23963  g->slots[slot].last.y = cur.y;
23964  g->slots[slot].index += 1;
23965  return ret;
23966 }
23967 NK_INTERN nk_flags
23968 nk_chart_push_column(const struct nk_context *ctx, struct nk_window *win,
23969  struct nk_chart *chart, float value, int slot)
23970 {
23971  struct nk_command_buffer *out = &win->buffer;
23972  const struct nk_input *in = &ctx->input;
23973  struct nk_panel *layout = win->layout;
23974 
23975  float ratio;
23976  nk_flags ret = 0;
23977  struct nk_color color;
23978  struct nk_rect item = {0,0,0,0};
23979 
23980  NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
23981  if (chart->slots[slot].index >= chart->slots[slot].count)
23982  return nk_false;
23983  if (chart->slots[slot].count) {
23984  float padding = (float)(chart->slots[slot].count-1);
23985  item.w = (chart->w - padding) / (float)(chart->slots[slot].count);
23986  }
23987 
23988  /* calculate bounds of current bar chart entry */
23989  color = chart->slots[slot].color;;
23990  item.h = chart->h * NK_ABS((value/chart->slots[slot].range));
23991  if (value >= 0) {
23992  ratio = (value + NK_ABS(chart->slots[slot].min)) / NK_ABS(chart->slots[slot].range);
23993  item.y = (chart->y + chart->h) - chart->h * ratio;
23994  } else {
23995  ratio = (value - chart->slots[slot].max) / chart->slots[slot].range;
23996  item.y = chart->y + (chart->h * NK_ABS(ratio)) - item.h;
23997  }
23998  item.x = chart->x + ((float)chart->slots[slot].index * item.w);
23999  item.x = item.x + ((float)chart->slots[slot].index);
24000 
24001  /* user chart bar selection */
24002  if (!(layout->flags & NK_WINDOW_ROM) &&
24003  NK_INBOX(in->mouse.pos.x,in->mouse.pos.y,item.x,item.y,item.w,item.h)) {
24004  ret = NK_CHART_HOVERING;
24005  ret |= (!in->mouse.buttons[NK_BUTTON_LEFT].down &&
24007  color = chart->slots[slot].highlight;
24008  }
24009  nk_fill_rect(out, item, 0, color);
24010  chart->slots[slot].index += 1;
24011  return ret;
24012 }
24013 NK_API nk_flags
24014 nk_chart_push_slot(struct nk_context *ctx, float value, int slot)
24015 {
24016  nk_flags flags;
24017  struct nk_window *win;
24018 
24019  NK_ASSERT(ctx);
24020  NK_ASSERT(ctx->current);
24021  NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
24022  NK_ASSERT(slot < ctx->current->layout->chart.slot);
24023  if (!ctx || !ctx->current || slot >= NK_CHART_MAX_SLOT) return nk_false;
24024  if (slot >= ctx->current->layout->chart.slot) return nk_false;
24025 
24026  win = ctx->current;
24027  if (win->layout->chart.slot < slot) return nk_false;
24028  switch (win->layout->chart.slots[slot].type) {
24029  case NK_CHART_LINES:
24030  flags = nk_chart_push_line(ctx, win, &win->layout->chart, value, slot); break;
24031  case NK_CHART_COLUMN:
24032  flags = nk_chart_push_column(ctx, win, &win->layout->chart, value, slot); break;
24033  default:
24034  case NK_CHART_MAX:
24035  flags = 0;
24036  }
24037  return flags;
24038 }
24039 NK_API nk_flags
24040 nk_chart_push(struct nk_context *ctx, float value)
24041 {
24042  return nk_chart_push_slot(ctx, value, 0);
24043 }
24044 NK_API void
24045 nk_chart_end(struct nk_context *ctx)
24046 {
24047  struct nk_window *win;
24048  struct nk_chart *chart;
24049 
24050  NK_ASSERT(ctx);
24051  NK_ASSERT(ctx->current);
24052  if (!ctx || !ctx->current)
24053  return;
24054 
24055  win = ctx->current;
24056  chart = &win->layout->chart;
24057  NK_MEMSET(chart, 0, sizeof(*chart));
24058  return;
24059 }
24060 NK_API void
24061 nk_plot(struct nk_context *ctx, enum nk_chart_type type, const float *values,
24062  int count, int offset)
24063 {
24064  int i = 0;
24065  float min_value;
24066  float max_value;
24067 
24068  NK_ASSERT(ctx);
24069  NK_ASSERT(values);
24070  if (!ctx || !values || !count) return;
24071 
24072  min_value = values[offset];
24073  max_value = values[offset];
24074  for (i = 0; i < count; ++i) {
24075  min_value = NK_MIN(values[i + offset], min_value);
24076  max_value = NK_MAX(values[i + offset], max_value);
24077  }
24078 
24079  if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
24080  for (i = 0; i < count; ++i)
24081  nk_chart_push(ctx, values[i + offset]);
24082  nk_chart_end(ctx);
24083  }
24084 }
24085 NK_API void
24086 nk_plot_function(struct nk_context *ctx, enum nk_chart_type type, void *userdata,
24087  float(*value_getter)(void* user, int index), int count, int offset)
24088 {
24089  int i = 0;
24090  float min_value;
24091  float max_value;
24092 
24093  NK_ASSERT(ctx);
24094  NK_ASSERT(value_getter);
24095  if (!ctx || !value_getter || !count) return;
24096 
24097  max_value = min_value = value_getter(userdata, offset);
24098  for (i = 0; i < count; ++i) {
24099  float value = value_getter(userdata, i + offset);
24100  min_value = NK_MIN(value, min_value);
24101  max_value = NK_MAX(value, max_value);
24102  }
24103 
24104  if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
24105  for (i = 0; i < count; ++i)
24106  nk_chart_push(ctx, value_getter(userdata, i + offset));
24107  nk_chart_end(ctx);
24108  }
24109 }
24110 
24111 
24112 
24113 
24114 
24115 /* ==============================================================
24116  *
24117  * COLOR PICKER
24118  *
24119  * ===============================================================*/
24120 NK_LIB int
24121 nk_color_picker_behavior(nk_flags *state,
24122  const struct nk_rect *bounds, const struct nk_rect *matrix,
24123  const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar,
24124  struct nk_colorf *color, const struct nk_input *in)
24125 {
24126  float hsva[4];
24127  int value_changed = 0;
24128  int hsv_changed = 0;
24129 
24130  NK_ASSERT(state);
24131  NK_ASSERT(matrix);
24132  NK_ASSERT(hue_bar);
24133  NK_ASSERT(color);
24134 
24135  /* color matrix */
24136  nk_colorf_hsva_fv(hsva, *color);
24137  if (nk_button_behavior(state, *matrix, in, NK_BUTTON_REPEATER)) {
24138  hsva[1] = NK_SATURATE((in->mouse.pos.x - matrix->x) / (matrix->w-1));
24139  hsva[2] = 1.0f - NK_SATURATE((in->mouse.pos.y - matrix->y) / (matrix->h-1));
24140  value_changed = hsv_changed = 1;
24141  }
24142  /* hue bar */
24143  if (nk_button_behavior(state, *hue_bar, in, NK_BUTTON_REPEATER)) {
24144  hsva[0] = NK_SATURATE((in->mouse.pos.y - hue_bar->y) / (hue_bar->h-1));
24145  value_changed = hsv_changed = 1;
24146  }
24147  /* alpha bar */
24148  if (alpha_bar) {
24149  if (nk_button_behavior(state, *alpha_bar, in, NK_BUTTON_REPEATER)) {
24150  hsva[3] = 1.0f - NK_SATURATE((in->mouse.pos.y - alpha_bar->y) / (alpha_bar->h-1));
24151  value_changed = 1;
24152  }
24153  }
24154  nk_widget_state_reset(state);
24155  if (hsv_changed) {
24156  *color = nk_hsva_colorfv(hsva);
24157  *state = NK_WIDGET_STATE_ACTIVE;
24158  }
24159  if (value_changed) {
24160  color->a = hsva[3];
24161  *state = NK_WIDGET_STATE_ACTIVE;
24162  }
24163  /* set color picker widget state */
24164  if (nk_input_is_mouse_hovering_rect(in, *bounds))
24165  *state = NK_WIDGET_STATE_HOVERED;
24166  if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *bounds))
24167  *state |= NK_WIDGET_STATE_ENTERED;
24168  else if (nk_input_is_mouse_prev_hovering_rect(in, *bounds))
24169  *state |= NK_WIDGET_STATE_LEFT;
24170  return value_changed;
24171 }
24172 NK_LIB void
24173 nk_draw_color_picker(struct nk_command_buffer *o, const struct nk_rect *matrix,
24174  const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar,
24175  struct nk_colorf col)
24176 {
24177  NK_STORAGE const struct nk_color black = {0,0,0,255};
24178  NK_STORAGE const struct nk_color white = {255, 255, 255, 255};
24179  NK_STORAGE const struct nk_color black_trans = {0,0,0,0};
24180 
24181  const float crosshair_size = 7.0f;
24182  struct nk_color temp;
24183  float hsva[4];
24184  float line_y;
24185  int i;
24186 
24187  NK_ASSERT(o);
24188  NK_ASSERT(matrix);
24189  NK_ASSERT(hue_bar);
24190 
24191  /* draw hue bar */
24192  nk_colorf_hsva_fv(hsva, col);
24193  for (i = 0; i < 6; ++i) {
24194  NK_GLOBAL const struct nk_color hue_colors[] = {
24195  {255, 0, 0, 255}, {255,255,0,255}, {0,255,0,255}, {0, 255,255,255},
24196  {0,0,255,255}, {255, 0, 255, 255}, {255, 0, 0, 255}
24197  };
24199  nk_rect(hue_bar->x, hue_bar->y + (float)i * (hue_bar->h/6.0f) + 0.5f,
24200  hue_bar->w, (hue_bar->h/6.0f) + 0.5f), hue_colors[i], hue_colors[i],
24201  hue_colors[i+1], hue_colors[i+1]);
24202  }
24203  line_y = (float)(int)(hue_bar->y + hsva[0] * matrix->h + 0.5f);
24204  nk_stroke_line(o, hue_bar->x-1, line_y, hue_bar->x + hue_bar->w + 2,
24205  line_y, 1, nk_rgb(255,255,255));
24206 
24207  /* draw alpha bar */
24208  if (alpha_bar) {
24209  float alpha = NK_SATURATE(col.a);
24210  line_y = (float)(int)(alpha_bar->y + (1.0f - alpha) * matrix->h + 0.5f);
24211 
24212  nk_fill_rect_multi_color(o, *alpha_bar, white, white, black, black);
24213  nk_stroke_line(o, alpha_bar->x-1, line_y, alpha_bar->x + alpha_bar->w + 2,
24214  line_y, 1, nk_rgb(255,255,255));
24215  }
24216 
24217  /* draw color matrix */
24218  temp = nk_hsv_f(hsva[0], 1.0f, 1.0f);
24219  nk_fill_rect_multi_color(o, *matrix, white, temp, temp, white);
24220  nk_fill_rect_multi_color(o, *matrix, black_trans, black_trans, black, black);
24221 
24222  /* draw cross-hair */
24223  {struct nk_vec2 p; float S = hsva[1]; float V = hsva[2];
24224  p.x = (float)(int)(matrix->x + S * matrix->w);
24225  p.y = (float)(int)(matrix->y + (1.0f - V) * matrix->h);
24226  nk_stroke_line(o, p.x - crosshair_size, p.y, p.x-2, p.y, 1.0f, white);
24227  nk_stroke_line(o, p.x + crosshair_size + 1, p.y, p.x+3, p.y, 1.0f, white);
24228  nk_stroke_line(o, p.x, p.y + crosshair_size + 1, p.x, p.y+3, 1.0f, white);
24229  nk_stroke_line(o, p.x, p.y - crosshair_size, p.x, p.y-2, 1.0f, white);}
24230 }
24231 NK_LIB int
24232 nk_do_color_picker(nk_flags *state,
24233  struct nk_command_buffer *out, struct nk_colorf *col,
24234  enum nk_color_format fmt, struct nk_rect bounds,
24235  struct nk_vec2 padding, const struct nk_input *in,
24236  const struct nk_user_font *font)
24237 {
24238  int ret = 0;
24239  struct nk_rect matrix;
24240  struct nk_rect hue_bar;
24241  struct nk_rect alpha_bar;
24242  float bar_w;
24243 
24244  NK_ASSERT(out);
24245  NK_ASSERT(col);
24246  NK_ASSERT(state);
24247  NK_ASSERT(font);
24248  if (!out || !col || !state || !font)
24249  return ret;
24250 
24251  bar_w = font->height;
24252  bounds.x += padding.x;
24253  bounds.y += padding.x;
24254  bounds.w -= 2 * padding.x;
24255  bounds.h -= 2 * padding.y;
24256 
24257  matrix.x = bounds.x;
24258  matrix.y = bounds.y;
24259  matrix.h = bounds.h;
24260  matrix.w = bounds.w - (3 * padding.x + 2 * bar_w);
24261 
24262  hue_bar.w = bar_w;
24263  hue_bar.y = bounds.y;
24264  hue_bar.h = matrix.h;
24265  hue_bar.x = matrix.x + matrix.w + padding.x;
24266 
24267  alpha_bar.x = hue_bar.x + hue_bar.w + padding.x;
24268  alpha_bar.y = bounds.y;
24269  alpha_bar.w = bar_w;
24270  alpha_bar.h = matrix.h;
24271 
24272  ret = nk_color_picker_behavior(state, &bounds, &matrix, &hue_bar,
24273  (fmt == NK_RGBA) ? &alpha_bar:0, col, in);
24274  nk_draw_color_picker(out, &matrix, &hue_bar, (fmt == NK_RGBA) ? &alpha_bar:0, *col);
24275  return ret;
24276 }
24277 NK_API int
24278 nk_color_pick(struct nk_context * ctx, struct nk_colorf *color,
24279  enum nk_color_format fmt)
24280 {
24281  struct nk_window *win;
24282  struct nk_panel *layout;
24283  const struct nk_style *config;
24284  const struct nk_input *in;
24285 
24287  struct nk_rect bounds;
24288 
24289  NK_ASSERT(ctx);
24290  NK_ASSERT(color);
24291  NK_ASSERT(ctx->current);
24292  NK_ASSERT(ctx->current->layout);
24293  if (!ctx || !ctx->current || !ctx->current->layout || !color)
24294  return 0;
24295 
24296  win = ctx->current;
24297  config = &ctx->style;
24298  layout = win->layout;
24299  state = nk_widget(&bounds, ctx);
24300  if (!state) return 0;
24301  in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
24302  return nk_do_color_picker(&ctx->last_widget_state, &win->buffer, color, fmt, bounds,
24303  nk_vec2(0,0), in, config->font);
24304 }
24305 NK_API struct nk_colorf
24306 nk_color_picker(struct nk_context *ctx, struct nk_colorf color,
24307  enum nk_color_format fmt)
24308 {
24309  nk_color_pick(ctx, &color, fmt);
24310  return color;
24311 }
24312 
24313 
24314 
24315 
24316 
24317 /* ==============================================================
24318  *
24319  * COMBO
24320  *
24321  * ===============================================================*/
24322 NK_INTERN int
24323 nk_combo_begin(struct nk_context *ctx, struct nk_window *win,
24324  struct nk_vec2 size, int is_clicked, struct nk_rect header)
24325 {
24326  struct nk_window *popup;
24327  int is_open = 0;
24328  int is_active = 0;
24329  struct nk_rect body;
24330  nk_hash hash;
24331 
24332  NK_ASSERT(ctx);
24333  NK_ASSERT(ctx->current);
24334  NK_ASSERT(ctx->current->layout);
24335  if (!ctx || !ctx->current || !ctx->current->layout)
24336  return 0;
24337 
24338  popup = win->popup.win;
24339  body.x = header.x;
24340  body.w = size.x;
24341  body.y = header.y + header.h-ctx->style.window.combo_border;
24342  body.h = size.y;
24343 
24344  hash = win->popup.combo_count++;
24345  is_open = (popup) ? nk_true:nk_false;
24346  is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_COMBO);
24347  if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
24348  (!is_open && !is_active && !is_clicked)) return 0;
24349  if (!nk_nonblock_begin(ctx, 0, body,
24350  (is_clicked && is_open)?nk_rect(0,0,0,0):header, NK_PANEL_COMBO)) return 0;
24351 
24352  win->popup.type = NK_PANEL_COMBO;
24353  win->popup.name = hash;
24354  return 1;
24355 }
24356 NK_API int
24357 nk_combo_begin_text(struct nk_context *ctx, const char *selected, int len,
24358  struct nk_vec2 size)
24359 {
24360  const struct nk_input *in;
24361  struct nk_window *win;
24362  struct nk_style *style;
24363 
24365  int is_clicked = nk_false;
24366  struct nk_rect header;
24367  const struct nk_style_item *background;
24368  struct nk_text text;
24369 
24370  NK_ASSERT(ctx);
24371  NK_ASSERT(selected);
24372  NK_ASSERT(ctx->current);
24373  NK_ASSERT(ctx->current->layout);
24374  if (!ctx || !ctx->current || !ctx->current->layout || !selected)
24375  return 0;
24376 
24377  win = ctx->current;
24378  style = &ctx->style;
24379  s = nk_widget(&header, ctx);
24380  if (s == NK_WIDGET_INVALID)
24381  return 0;
24382 
24383  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24384  if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
24385  is_clicked = nk_true;
24386 
24387  /* draw combo box header background and border */
24388  if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
24389  background = &style->combo.active;
24390  text.text = style->combo.label_active;
24391  } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
24392  background = &style->combo.hover;
24393  text.text = style->combo.label_hover;
24394  } else {
24395  background = &style->combo.normal;
24396  text.text = style->combo.label_normal;
24397  }
24398  if (background->type == NK_STYLE_ITEM_IMAGE) {
24399  text.background = nk_rgba(0,0,0,0);
24400  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24401  } else {
24402  text.background = background->data.color;
24403  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24404  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24405  }
24406  {
24407  /* print currently selected text item */
24408  struct nk_rect label;
24409  struct nk_rect button;
24410  struct nk_rect content;
24411 
24412  enum nk_symbol_type sym;
24413  if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
24414  sym = style->combo.sym_hover;
24415  else if (is_clicked)
24416  sym = style->combo.sym_active;
24417  else sym = style->combo.sym_normal;
24418 
24419  /* calculate button */
24420  button.w = header.h - 2 * style->combo.button_padding.y;
24421  button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
24422  button.y = header.y + style->combo.button_padding.y;
24423  button.h = button.w;
24424 
24425  content.x = button.x + style->combo.button.padding.x;
24426  content.y = button.y + style->combo.button.padding.y;
24427  content.w = button.w - 2 * style->combo.button.padding.x;
24428  content.h = button.h - 2 * style->combo.button.padding.y;
24429 
24430  /* draw selected label */
24431  text.padding = nk_vec2(0,0);
24432  label.x = header.x + style->combo.content_padding.x;
24433  label.y = header.y + style->combo.content_padding.y;
24434  label.w = button.x - (style->combo.content_padding.x + style->combo.spacing.x) - label.x;;
24435  label.h = header.h - 2 * style->combo.content_padding.y;
24436  nk_widget_text(&win->buffer, label, selected, len, &text,
24437  NK_TEXT_LEFT, ctx->style.font);
24438 
24439  /* draw open/close button */
24440  nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
24441  &ctx->style.combo.button, sym, style->font);
24442  }
24443  return nk_combo_begin(ctx, win, size, is_clicked, header);
24444 }
24445 NK_API int
24446 nk_combo_begin_label(struct nk_context *ctx, const char *selected, struct nk_vec2 size)
24447 {
24448  return nk_combo_begin_text(ctx, selected, nk_strlen(selected), size);
24449 }
24450 NK_API int
24451 nk_combo_begin_color(struct nk_context *ctx, struct nk_color color, struct nk_vec2 size)
24452 {
24453  struct nk_window *win;
24454  struct nk_style *style;
24455  const struct nk_input *in;
24456 
24457  struct nk_rect header;
24458  int is_clicked = nk_false;
24460  const struct nk_style_item *background;
24461 
24462  NK_ASSERT(ctx);
24463  NK_ASSERT(ctx->current);
24464  NK_ASSERT(ctx->current->layout);
24465  if (!ctx || !ctx->current || !ctx->current->layout)
24466  return 0;
24467 
24468  win = ctx->current;
24469  style = &ctx->style;
24470  s = nk_widget(&header, ctx);
24471  if (s == NK_WIDGET_INVALID)
24472  return 0;
24473 
24474  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24475  if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
24476  is_clicked = nk_true;
24477 
24478  /* draw combo box header background and border */
24479  if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED)
24480  background = &style->combo.active;
24481  else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
24482  background = &style->combo.hover;
24483  else background = &style->combo.normal;
24484 
24485  if (background->type == NK_STYLE_ITEM_IMAGE) {
24486  nk_draw_image(&win->buffer, header, &background->data.image,nk_white);
24487  } else {
24488  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24489  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24490  }
24491  {
24492  struct nk_rect content;
24493  struct nk_rect button;
24494  struct nk_rect bounds;
24495 
24496  enum nk_symbol_type sym;
24497  if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
24498  sym = style->combo.sym_hover;
24499  else if (is_clicked)
24500  sym = style->combo.sym_active;
24501  else sym = style->combo.sym_normal;
24502 
24503  /* calculate button */
24504  button.w = header.h - 2 * style->combo.button_padding.y;
24505  button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
24506  button.y = header.y + style->combo.button_padding.y;
24507  button.h = button.w;
24508 
24509  content.x = button.x + style->combo.button.padding.x;
24510  content.y = button.y + style->combo.button.padding.y;
24511  content.w = button.w - 2 * style->combo.button.padding.x;
24512  content.h = button.h - 2 * style->combo.button.padding.y;
24513 
24514  /* draw color */
24515  bounds.h = header.h - 4 * style->combo.content_padding.y;
24516  bounds.y = header.y + 2 * style->combo.content_padding.y;
24517  bounds.x = header.x + 2 * style->combo.content_padding.x;
24518  bounds.w = (button.x - (style->combo.content_padding.x + style->combo.spacing.x)) - bounds.x;
24519  nk_fill_rect(&win->buffer, bounds, 0, color);
24520 
24521  /* draw open/close button */
24522  nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
24523  &ctx->style.combo.button, sym, style->font);
24524  }
24525  return nk_combo_begin(ctx, win, size, is_clicked, header);
24526 }
24527 NK_API int
24528 nk_combo_begin_symbol(struct nk_context *ctx, enum nk_symbol_type symbol, struct nk_vec2 size)
24529 {
24530  struct nk_window *win;
24531  struct nk_style *style;
24532  const struct nk_input *in;
24533 
24534  struct nk_rect header;
24535  int is_clicked = nk_false;
24537  const struct nk_style_item *background;
24538  struct nk_color sym_background;
24539  struct nk_color symbol_color;
24540 
24541  NK_ASSERT(ctx);
24542  NK_ASSERT(ctx->current);
24543  NK_ASSERT(ctx->current->layout);
24544  if (!ctx || !ctx->current || !ctx->current->layout)
24545  return 0;
24546 
24547  win = ctx->current;
24548  style = &ctx->style;
24549  s = nk_widget(&header, ctx);
24550  if (s == NK_WIDGET_INVALID)
24551  return 0;
24552 
24553  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24554  if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
24555  is_clicked = nk_true;
24556 
24557  /* draw combo box header background and border */
24558  if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
24559  background = &style->combo.active;
24560  symbol_color = style->combo.symbol_active;
24561  } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
24562  background = &style->combo.hover;
24563  symbol_color = style->combo.symbol_hover;
24564  } else {
24565  background = &style->combo.normal;
24566  symbol_color = style->combo.symbol_hover;
24567  }
24568 
24569  if (background->type == NK_STYLE_ITEM_IMAGE) {
24570  sym_background = nk_rgba(0,0,0,0);
24571  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24572  } else {
24573  sym_background = background->data.color;
24574  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24575  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24576  }
24577  {
24578  struct nk_rect bounds = {0,0,0,0};
24579  struct nk_rect content;
24580  struct nk_rect button;
24581 
24582  enum nk_symbol_type sym;
24583  if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
24584  sym = style->combo.sym_hover;
24585  else if (is_clicked)
24586  sym = style->combo.sym_active;
24587  else sym = style->combo.sym_normal;
24588 
24589  /* calculate button */
24590  button.w = header.h - 2 * style->combo.button_padding.y;
24591  button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
24592  button.y = header.y + style->combo.button_padding.y;
24593  button.h = button.w;
24594 
24595  content.x = button.x + style->combo.button.padding.x;
24596  content.y = button.y + style->combo.button.padding.y;
24597  content.w = button.w - 2 * style->combo.button.padding.x;
24598  content.h = button.h - 2 * style->combo.button.padding.y;
24599 
24600  /* draw symbol */
24601  bounds.h = header.h - 2 * style->combo.content_padding.y;
24602  bounds.y = header.y + style->combo.content_padding.y;
24603  bounds.x = header.x + style->combo.content_padding.x;
24604  bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
24605  nk_draw_symbol(&win->buffer, symbol, bounds, sym_background, symbol_color,
24606  1.0f, style->font);
24607 
24608  /* draw open/close button */
24609  nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
24610  &ctx->style.combo.button, sym, style->font);
24611  }
24612  return nk_combo_begin(ctx, win, size, is_clicked, header);
24613 }
24614 NK_API int
24615 nk_combo_begin_symbol_text(struct nk_context *ctx, const char *selected, int len,
24616  enum nk_symbol_type symbol, struct nk_vec2 size)
24617 {
24618  struct nk_window *win;
24619  struct nk_style *style;
24620  struct nk_input *in;
24621 
24622  struct nk_rect header;
24623  int is_clicked = nk_false;
24625  const struct nk_style_item *background;
24626  struct nk_color symbol_color;
24627  struct nk_text text;
24628 
24629  NK_ASSERT(ctx);
24630  NK_ASSERT(ctx->current);
24631  NK_ASSERT(ctx->current->layout);
24632  if (!ctx || !ctx->current || !ctx->current->layout)
24633  return 0;
24634 
24635  win = ctx->current;
24636  style = &ctx->style;
24637  s = nk_widget(&header, ctx);
24638  if (!s) return 0;
24639 
24640  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24641  if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
24642  is_clicked = nk_true;
24643 
24644  /* draw combo box header background and border */
24645  if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
24646  background = &style->combo.active;
24647  symbol_color = style->combo.symbol_active;
24648  text.text = style->combo.label_active;
24649  } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
24650  background = &style->combo.hover;
24651  symbol_color = style->combo.symbol_hover;
24652  text.text = style->combo.label_hover;
24653  } else {
24654  background = &style->combo.normal;
24655  symbol_color = style->combo.symbol_normal;
24656  text.text = style->combo.label_normal;
24657  }
24658  if (background->type == NK_STYLE_ITEM_IMAGE) {
24659  text.background = nk_rgba(0,0,0,0);
24660  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24661  } else {
24662  text.background = background->data.color;
24663  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24664  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24665  }
24666  {
24667  struct nk_rect content;
24668  struct nk_rect button;
24669  struct nk_rect label;
24670  struct nk_rect image;
24671 
24672  enum nk_symbol_type sym;
24673  if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
24674  sym = style->combo.sym_hover;
24675  else if (is_clicked)
24676  sym = style->combo.sym_active;
24677  else sym = style->combo.sym_normal;
24678 
24679  /* calculate button */
24680  button.w = header.h - 2 * style->combo.button_padding.y;
24681  button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
24682  button.y = header.y + style->combo.button_padding.y;
24683  button.h = button.w;
24684 
24685  content.x = button.x + style->combo.button.padding.x;
24686  content.y = button.y + style->combo.button.padding.y;
24687  content.w = button.w - 2 * style->combo.button.padding.x;
24688  content.h = button.h - 2 * style->combo.button.padding.y;
24689  nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
24690  &ctx->style.combo.button, sym, style->font);
24691 
24692  /* draw symbol */
24693  image.x = header.x + style->combo.content_padding.x;
24694  image.y = header.y + style->combo.content_padding.y;
24695  image.h = header.h - 2 * style->combo.content_padding.y;
24696  image.w = image.h;
24697  nk_draw_symbol(&win->buffer, symbol, image, text.background, symbol_color,
24698  1.0f, style->font);
24699 
24700  /* draw label */
24701  text.padding = nk_vec2(0,0);
24702  label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
24703  label.y = header.y + style->combo.content_padding.y;
24704  label.w = (button.x - style->combo.content_padding.x) - label.x;
24705  label.h = header.h - 2 * style->combo.content_padding.y;
24706  nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
24707  }
24708  return nk_combo_begin(ctx, win, size, is_clicked, header);
24709 }
24710 NK_API int
24711 nk_combo_begin_image(struct nk_context *ctx, struct nk_image img, struct nk_vec2 size)
24712 {
24713  struct nk_window *win;
24714  struct nk_style *style;
24715  const struct nk_input *in;
24716 
24717  struct nk_rect header;
24718  int is_clicked = nk_false;
24720  const struct nk_style_item *background;
24721 
24722  NK_ASSERT(ctx);
24723  NK_ASSERT(ctx->current);
24724  NK_ASSERT(ctx->current->layout);
24725  if (!ctx || !ctx->current || !ctx->current->layout)
24726  return 0;
24727 
24728  win = ctx->current;
24729  style = &ctx->style;
24730  s = nk_widget(&header, ctx);
24731  if (s == NK_WIDGET_INVALID)
24732  return 0;
24733 
24734  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24735  if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
24736  is_clicked = nk_true;
24737 
24738  /* draw combo box header background and border */
24739  if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED)
24740  background = &style->combo.active;
24741  else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
24742  background = &style->combo.hover;
24743  else background = &style->combo.normal;
24744 
24745  if (background->type == NK_STYLE_ITEM_IMAGE) {
24746  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24747  } else {
24748  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24749  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24750  }
24751  {
24752  struct nk_rect bounds = {0,0,0,0};
24753  struct nk_rect content;
24754  struct nk_rect button;
24755 
24756  enum nk_symbol_type sym;
24757  if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
24758  sym = style->combo.sym_hover;
24759  else if (is_clicked)
24760  sym = style->combo.sym_active;
24761  else sym = style->combo.sym_normal;
24762 
24763  /* calculate button */
24764  button.w = header.h - 2 * style->combo.button_padding.y;
24765  button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
24766  button.y = header.y + style->combo.button_padding.y;
24767  button.h = button.w;
24768 
24769  content.x = button.x + style->combo.button.padding.x;
24770  content.y = button.y + style->combo.button.padding.y;
24771  content.w = button.w - 2 * style->combo.button.padding.x;
24772  content.h = button.h - 2 * style->combo.button.padding.y;
24773 
24774  /* draw image */
24775  bounds.h = header.h - 2 * style->combo.content_padding.y;
24776  bounds.y = header.y + style->combo.content_padding.y;
24777  bounds.x = header.x + style->combo.content_padding.x;
24778  bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
24779  nk_draw_image(&win->buffer, bounds, &img, nk_white);
24780 
24781  /* draw open/close button */
24782  nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
24783  &ctx->style.combo.button, sym, style->font);
24784  }
24785  return nk_combo_begin(ctx, win, size, is_clicked, header);
24786 }
24787 NK_API int
24788 nk_combo_begin_image_text(struct nk_context *ctx, const char *selected, int len,
24789  struct nk_image img, struct nk_vec2 size)
24790 {
24791  struct nk_window *win;
24792  struct nk_style *style;
24793  struct nk_input *in;
24794 
24795  struct nk_rect header;
24796  int is_clicked = nk_false;
24798  const struct nk_style_item *background;
24799  struct nk_text text;
24800 
24801  NK_ASSERT(ctx);
24802  NK_ASSERT(ctx->current);
24803  NK_ASSERT(ctx->current->layout);
24804  if (!ctx || !ctx->current || !ctx->current->layout)
24805  return 0;
24806 
24807  win = ctx->current;
24808  style = &ctx->style;
24809  s = nk_widget(&header, ctx);
24810  if (!s) return 0;
24811 
24812  in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
24813  if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
24814  is_clicked = nk_true;
24815 
24816  /* draw combo box header background and border */
24817  if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
24818  background = &style->combo.active;
24819  text.text = style->combo.label_active;
24820  } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
24821  background = &style->combo.hover;
24822  text.text = style->combo.label_hover;
24823  } else {
24824  background = &style->combo.normal;
24825  text.text = style->combo.label_normal;
24826  }
24827  if (background->type == NK_STYLE_ITEM_IMAGE) {
24828  text.background = nk_rgba(0,0,0,0);
24829  nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
24830  } else {
24831  text.background = background->data.color;
24832  nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
24833  nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
24834  }
24835  {
24836  struct nk_rect content;
24837  struct nk_rect button;
24838  struct nk_rect label;
24839  struct nk_rect image;
24840 
24841  enum nk_symbol_type sym;
24842  if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
24843  sym = style->combo.sym_hover;
24844  else if (is_clicked)
24845  sym = style->combo.sym_active;
24846  else sym = style->combo.sym_normal;
24847 
24848  /* calculate button */
24849  button.w = header.h - 2 * style->combo.button_padding.y;
24850  button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
24851  button.y = header.y + style->combo.button_padding.y;
24852  button.h = button.w;
24853 
24854  content.x = button.x + style->combo.button.padding.x;
24855  content.y = button.y + style->combo.button.padding.y;
24856  content.w = button.w - 2 * style->combo.button.padding.x;
24857  content.h = button.h - 2 * style->combo.button.padding.y;
24858  nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
24859  &ctx->style.combo.button, sym, style->font);
24860 
24861  /* draw image */
24862  image.x = header.x + style->combo.content_padding.x;
24863  image.y = header.y + style->combo.content_padding.y;
24864  image.h = header.h - 2 * style->combo.content_padding.y;
24865  image.w = image.h;
24866  nk_draw_image(&win->buffer, image, &img, nk_white);
24867 
24868  /* draw label */
24869  text.padding = nk_vec2(0,0);
24870  label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
24871  label.y = header.y + style->combo.content_padding.y;
24872  label.w = (button.x - style->combo.content_padding.x) - label.x;
24873  label.h = header.h - 2 * style->combo.content_padding.y;
24874  nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
24875  }
24876  return nk_combo_begin(ctx, win, size, is_clicked, header);
24877 }
24878 NK_API int
24879 nk_combo_begin_symbol_label(struct nk_context *ctx,
24880  const char *selected, enum nk_symbol_type type, struct nk_vec2 size)
24881 {
24882  return nk_combo_begin_symbol_text(ctx, selected, nk_strlen(selected), type, size);
24883 }
24884 NK_API int
24885 nk_combo_begin_image_label(struct nk_context *ctx,
24886  const char *selected, struct nk_image img, struct nk_vec2 size)
24887 {
24888  return nk_combo_begin_image_text(ctx, selected, nk_strlen(selected), img, size);
24889 }
24890 NK_API int
24891 nk_combo_item_text(struct nk_context *ctx, const char *text, int len,nk_flags align)
24892 {
24893  return nk_contextual_item_text(ctx, text, len, align);
24894 }
24895 NK_API int
24896 nk_combo_item_label(struct nk_context *ctx, const char *label, nk_flags align)
24897 {
24898  return nk_contextual_item_label(ctx, label, align);
24899 }
24900 NK_API int
24901 nk_combo_item_image_text(struct nk_context *ctx, struct nk_image img, const char *text,
24902  int len, nk_flags alignment)
24903 {
24904  return nk_contextual_item_image_text(ctx, img, text, len, alignment);
24905 }
24906 NK_API int
24907 nk_combo_item_image_label(struct nk_context *ctx, struct nk_image img,
24908  const char *text, nk_flags alignment)
24909 {
24910  return nk_contextual_item_image_label(ctx, img, text, alignment);
24911 }
24912 NK_API int
24913 nk_combo_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym,
24914  const char *text, int len, nk_flags alignment)
24915 {
24916  return nk_contextual_item_symbol_text(ctx, sym, text, len, alignment);
24917 }
24918 NK_API int
24919 nk_combo_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym,
24920  const char *label, nk_flags alignment)
24921 {
24922  return nk_contextual_item_symbol_label(ctx, sym, label, alignment);
24923 }
24924 NK_API void nk_combo_end(struct nk_context *ctx)
24925 {
24926  nk_contextual_end(ctx);
24927 }
24928 NK_API void nk_combo_close(struct nk_context *ctx)
24929 {
24930  nk_contextual_close(ctx);
24931 }
24932 NK_API int
24933 nk_combo(struct nk_context *ctx, const char **items, int count,
24934  int selected, int item_height, struct nk_vec2 size)
24935 {
24936  int i = 0;
24937  int max_height;
24938  struct nk_vec2 item_spacing;
24939  struct nk_vec2 window_padding;
24940 
24941  NK_ASSERT(ctx);
24942  NK_ASSERT(items);
24943  NK_ASSERT(ctx->current);
24944  if (!ctx || !items ||!count)
24945  return selected;
24946 
24947  item_spacing = ctx->style.window.spacing;
24948  window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
24949  max_height = count * item_height + count * (int)item_spacing.y;
24950  max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
24951  size.y = NK_MIN(size.y, (float)max_height);
24952  if (nk_combo_begin_label(ctx, items[selected], size)) {
24953  nk_layout_row_dynamic(ctx, (float)item_height, 1);
24954  for (i = 0; i < count; ++i) {
24955  if (nk_combo_item_label(ctx, items[i], NK_TEXT_LEFT))
24956  selected = i;
24957  }
24958  nk_combo_end(ctx);
24959  }
24960  return selected;
24961 }
24962 NK_API int
24963 nk_combo_separator(struct nk_context *ctx, const char *items_separated_by_separator,
24964  int separator, int selected, int count, int item_height, struct nk_vec2 size)
24965 {
24966  int i;
24967  int max_height;
24968  struct nk_vec2 item_spacing;
24969  struct nk_vec2 window_padding;
24970  const char *current_item;
24971  const char *iter;
24972  int length = 0;
24973 
24974  NK_ASSERT(ctx);
24975  NK_ASSERT(items_separated_by_separator);
24976  if (!ctx || !items_separated_by_separator)
24977  return selected;
24978 
24979  /* calculate popup window */
24980  item_spacing = ctx->style.window.spacing;
24981  window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
24982  max_height = count * item_height + count * (int)item_spacing.y;
24983  max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
24984  size.y = NK_MIN(size.y, (float)max_height);
24985 
24986  /* find selected item */
24987  current_item = items_separated_by_separator;
24988  for (i = 0; i < count; ++i) {
24989  iter = current_item;
24990  while (*iter && *iter != separator) iter++;
24991  length = (int)(iter - current_item);
24992  if (i == selected) break;
24993  current_item = iter + 1;
24994  }
24995 
24996  if (nk_combo_begin_text(ctx, current_item, length, size)) {
24997  current_item = items_separated_by_separator;
24998  nk_layout_row_dynamic(ctx, (float)item_height, 1);
24999  for (i = 0; i < count; ++i) {
25000  iter = current_item;
25001  while (*iter && *iter != separator) iter++;
25002  length = (int)(iter - current_item);
25003  if (nk_combo_item_text(ctx, current_item, length, NK_TEXT_LEFT))
25004  selected = i;
25005  current_item = current_item + length + 1;
25006  }
25007  nk_combo_end(ctx);
25008  }
25009  return selected;
25010 }
25011 NK_API int
25012 nk_combo_string(struct nk_context *ctx, const char *items_separated_by_zeros,
25013  int selected, int count, int item_height, struct nk_vec2 size)
25014 {
25015  return nk_combo_separator(ctx, items_separated_by_zeros, '\0', selected, count, item_height, size);
25016 }
25017 NK_API int
25018 nk_combo_callback(struct nk_context *ctx, void(*item_getter)(void*, int, const char**),
25019  void *userdata, int selected, int count, int item_height, struct nk_vec2 size)
25020 {
25021  int i;
25022  int max_height;
25023  struct nk_vec2 item_spacing;
25024  struct nk_vec2 window_padding;
25025  const char *item;
25026 
25027  NK_ASSERT(ctx);
25028  NK_ASSERT(item_getter);
25029  if (!ctx || !item_getter)
25030  return selected;
25031 
25032  /* calculate popup window */
25033  item_spacing = ctx->style.window.spacing;
25034  window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
25035  max_height = count * item_height + count * (int)item_spacing.y;
25036  max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
25037  size.y = NK_MIN(size.y, (float)max_height);
25038 
25039  item_getter(userdata, selected, &item);
25040  if (nk_combo_begin_label(ctx, item, size)) {
25041  nk_layout_row_dynamic(ctx, (float)item_height, 1);
25042  for (i = 0; i < count; ++i) {
25043  item_getter(userdata, i, &item);
25044  if (nk_combo_item_label(ctx, item, NK_TEXT_LEFT))
25045  selected = i;
25046  }
25047  nk_combo_end(ctx);
25048  } return selected;
25049 }
25050 NK_API void
25051 nk_combobox(struct nk_context *ctx, const char **items, int count,
25052  int *selected, int item_height, struct nk_vec2 size)
25053 {
25054  *selected = nk_combo(ctx, items, count, *selected, item_height, size);
25055 }
25056 NK_API void
25057 nk_combobox_string(struct nk_context *ctx, const char *items_separated_by_zeros,
25058  int *selected, int count, int item_height, struct nk_vec2 size)
25059 {
25060  *selected = nk_combo_string(ctx, items_separated_by_zeros, *selected, count, item_height, size);
25061 }
25062 NK_API void
25063 nk_combobox_separator(struct nk_context *ctx, const char *items_separated_by_separator,
25064  int separator,int *selected, int count, int item_height, struct nk_vec2 size)
25065 {
25066  *selected = nk_combo_separator(ctx, items_separated_by_separator, separator,
25067  *selected, count, item_height, size);
25068 }
25069 NK_API void
25070 nk_combobox_callback(struct nk_context *ctx,
25071  void(*item_getter)(void* data, int id, const char **out_text),
25072  void *userdata, int *selected, int count, int item_height, struct nk_vec2 size)
25073 {
25074  *selected = nk_combo_callback(ctx, item_getter, userdata, *selected, count, item_height, size);
25075 }
25076 
25077 
25078 
25079 
25080 
25081 /* ===============================================================
25082  *
25083  * TOOLTIP
25084  *
25085  * ===============================================================*/
25086 NK_API int
25087 nk_tooltip_begin(struct nk_context *ctx, float width)
25088 {
25089  int x,y,w,h;
25090  struct nk_window *win;
25091  const struct nk_input *in;
25092  struct nk_rect bounds;
25093  int ret;
25094 
25095  NK_ASSERT(ctx);
25096  NK_ASSERT(ctx->current);
25097  NK_ASSERT(ctx->current->layout);
25098  if (!ctx || !ctx->current || !ctx->current->layout)
25099  return 0;
25100 
25101  /* make sure that no nonblocking popup is currently active */
25102  win = ctx->current;
25103  in = &ctx->input;
25104  if (win->popup.win && (win->popup.type & NK_PANEL_SET_NONBLOCK))
25105  return 0;
25106 
25107  w = nk_iceilf(width);
25108  h = nk_iceilf(nk_null_rect.h);
25109  x = nk_ifloorf(in->mouse.pos.x + 1) - (int)win->layout->clip.x;
25110  y = nk_ifloorf(in->mouse.pos.y + 1) - (int)win->layout->clip.y;
25111 
25112  bounds.x = (float)x;
25113  bounds.y = (float)y;
25114  bounds.w = (float)w;
25115  bounds.h = (float)h;
25116 
25117  ret = nk_popup_begin(ctx, NK_POPUP_DYNAMIC,
25118  "__##Tooltip##__", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER, bounds);
25119  if (ret) win->layout->flags &= ~(nk_flags)NK_WINDOW_ROM;
25120  win->popup.type = NK_PANEL_TOOLTIP;
25122  return ret;
25123 }
25124 
25125 NK_API void
25126 nk_tooltip_end(struct nk_context *ctx)
25127 {
25128  NK_ASSERT(ctx);
25129  NK_ASSERT(ctx->current);
25130  if (!ctx || !ctx->current) return;
25131  ctx->current->seq--;
25132  nk_popup_close(ctx);
25133  nk_popup_end(ctx);
25134 }
25135 NK_API void
25136 nk_tooltip(struct nk_context *ctx, const char *text)
25137 {
25138  const struct nk_style *style;
25139  struct nk_vec2 padding;
25140 
25141  int text_len;
25142  float text_width;
25143  float text_height;
25144 
25145  NK_ASSERT(ctx);
25146  NK_ASSERT(ctx->current);
25147  NK_ASSERT(ctx->current->layout);
25148  NK_ASSERT(text);
25149  if (!ctx || !ctx->current || !ctx->current->layout || !text)
25150  return;
25151 
25152  /* fetch configuration data */
25153  style = &ctx->style;
25154  padding = style->window.padding;
25155 
25156  /* calculate size of the text and tooltip */
25157  text_len = nk_strlen(text);
25158  text_width = style->font->width(style->font->userdata,
25159  style->font->height, text, text_len);
25160  text_width += (4 * padding.x);
25161  text_height = (style->font->height + 2 * padding.y);
25162 
25163  /* execute tooltip and fill with text */
25164  if (nk_tooltip_begin(ctx, (float)text_width)) {
25165  nk_layout_row_dynamic(ctx, (float)text_height, 1);
25166  nk_text(ctx, text, text_len, NK_TEXT_LEFT);
25167  nk_tooltip_end(ctx);
25168  }
25169 }
25170 #ifdef NK_INCLUDE_STANDARD_VARARGS
25171 NK_API void
25172 nk_tooltipf(struct nk_context *ctx, const char *fmt, ...)
25173 {
25174  va_list args;
25175  va_start(args, fmt);
25176  nk_tooltipfv(ctx, fmt, args);
25177  va_end(args);
25178 }
25179 NK_API void
25180 nk_tooltipfv(struct nk_context *ctx, const char *fmt, va_list args)
25181 {
25182  char buf[256];
25183  nk_strfmt(buf, NK_LEN(buf), fmt, args);
25184  nk_tooltip(ctx, buf);
25185 }
25186 #endif
25187 
25188 
25189 
25190 #endif /* NK_IMPLEMENTATION */
25191 
25192 /*
25235 
25513 
25538 */
25539 
unsigned short r
Definition: nuklear.h:4425
struct nk_vec2 padding
Definition: nuklear.h:4990
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4998
NK_API struct nk_color nk_rgb_iv(const int *rgb)
NK_API int nk_menu_item_text(struct nk_context *, const char *, int, nk_flags align)
struct nk_style_item hover
Definition: nuklear.h:4940
nk_chart_event
Definition: nuklear.h:474
struct nk_vec2 padding
Definition: nuklear.h:4896
float preferred_x
Definition: nuklear.h:4222
struct nk_style_item hover_active
Definition: nuklear.h:4812
NK_API int nk_window_has_focus(const struct nk_context *)
NK_API int nk_menu_item_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment)
struct nk_style_button dec_button
Definition: nuklear.h:4994
NK_API struct nk_rect nk_rectv(const float *xywh)
nk_handle userdata
Definition: nuklear.h:4899
#define NK_CONFIG_STACK(type, size)
Definition: nuklear.h:5415
struct nk_style_item cursor_hover
Definition: nuklear.h:4783
NK_API int nk_input_mouse_clicked(const struct nk_input *, enum nk_buttons, struct nk_rect)
struct nk_pool pool
Definition: nuklear.h:5522
struct nk_style_item active
Definition: nuklear.h:4843
NK_API int nk_select_text(struct nk_context *, const char *, int, nk_flags align, int value)
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)
unsigned int scrolled
Definition: nuklear.h:5346
NK_API struct nk_color nk_rgba_bv(const nk_byte *rgba)
float menu_border
Definition: nuklear.h:5114
NK_API int nk_contextual_item_image_text(struct nk_context *, struct nk_image, const char *, int len, nk_flags alignment)
NK_API void nk_textedit_select_all(struct nk_text_edit *)
struct nk_style_button close_button
Definition: nuklear.h:5079
nk_convert_result
Definition: nuklear.h:1135
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_API int nk_contextual_begin(struct nk_context *, nk_flags, struct nk_vec2, struct nk_rect trigger_bounds)
struct nk_vec2 last
Definition: nuklear.h:5196
struct nk_color label_normal
Definition: nuklear.h:5086
struct nk_color text_hover
Definition: nuklear.h:4817
static const ImVec4 white
Definition: model-views.h:45
struct nk_style_item cursor_normal
Definition: nuklear.h:4782
NK_API void nk_color_hex_rgb(char *output, struct nk_color)
float rounding_cursor
Definition: nuklear.h:4921
float border
Definition: nuklear.h:5256
NK_API struct nk_rect nk_get_null_rect(void)
nk_buffer_allocation_type
Definition: nuklear.h:4032
NK_API int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags)
struct nk_color color
Definition: nuklear.h:4427
#define NK_STORAGE
Definition: nuklear.h:271
nk_handle userdata
Definition: nuklear.h:4873
nk_widget_states
Definition: nuklear.h:2974
GLuint GLuint end
float tooltip_border
Definition: nuklear.h:5116
float max_x
Definition: nuklear.h:5253
#define NK_INT32
Definition: nuklear.h:354
GLboolean GLboolean GLboolean b
NK_API int nk_contextual_item_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment)
NK_API int nk_filter_default(const struct nk_text_edit *, nk_rune unicode)
GLboolean GLboolean g
unsigned int page_count
Definition: nuklear.h:5483
nk_size allocated
Definition: nuklear.h:4055
NK_API void nk_stroke_circle(struct nk_command_buffer *, struct nk_rect, float line_thickness, struct nk_color)
NK_API struct nk_vec2 nk_vec2i(int x, int y)
struct nk_vec2 contextual_padding
Definition: nuklear.h:5129
GLint y
nk_panel_flags
Definition: nuklear.h:1440
NK_API int nk_utf_decode(const char *, nk_rune *, int)
struct nk_style_button menu_button
Definition: nuklear.h:5144
NK_API struct nk_color nk_rgba_u32(nk_uint)
nk_size needed
Definition: nuklear.h:4057
float(* nk_text_width_f)(nk_handle, float h, const char *, int len)
Definition: nuklear.h:3822
NK_API int nk_filter_hex(const struct nk_text_edit *, nk_rune unicode)
NK_API int nk_menu_item_image_text(struct nk_context *, struct nk_image, const char *, int len, nk_flags alignment)
float bar_height
Definition: nuklear.h:4860
unsigned short w
Definition: nuklear.h:4367
NK_API void nk_buffer_init(struct nk_buffer *, const struct nk_allocator *, nk_size size)
NK_API int nk_button_color(struct nk_context *, struct nk_color)
unsigned short h
Definition: nuklear.h:4409
NK_API int nk_select_image_text(struct nk_context *, struct nk_image, const char *, int, nk_flags align, int value)
NK_API struct nk_window * nk_window_find(struct nk_context *ctx, const char *name)
NK_API void nk_str_remove_chars(struct nk_str *, int len)
NK_API int nk_widget_is_hovered(struct nk_context *)
#define NK_FLAGS_STACK_SIZE
Definition: nuklear.h:5403
NK_API void nk_layout_row_end(struct nk_context *)
NK_API void nk_fill_circle(struct nk_command_buffer *, struct nk_rect, struct nk_color)
struct nk_vec2 padding
Definition: nuklear.h:4744
struct nk_color label_active
Definition: nuklear.h:5088
#define nk_zero_struct(s)
Definition: nuklear.h:5558
struct nk_image img
Definition: nuklear.h:464
boost_foreach_argument_dependent_lookup_hack tag
Definition: foreach_fwd.hpp:31
struct nk_color text_normal
Definition: nuklear.h:4756
nk_handle handle
Definition: nuklear.h:463
GLenum GLenum GLsizei void * row
unsigned int seq
Definition: nuklear.h:5306
enum nk_symbol_type sym_left
Definition: nuklear.h:4984
struct nk_config_stack_button_behavior button_behaviors
Definition: nuklear.h:5445
nk_flags text_alignment
Definition: nuklear.h:4759
struct nk_rect clip
Definition: nuklear.h:5258
typedef void(APIENTRY *GLDEBUGPROC)(GLenum source
nk_modify
Definition: nuklear.h:469
struct nk_color selected_text_hover
Definition: nuklear.h:4960
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_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_API void nk_colorf_hsva_fv(float *hsva, struct nk_colorf in)
GLuint const GLchar * name
short h
Definition: nuklear.h:460
NK_API void nk_str_init_fixed(struct nk_str *, void *memory, nk_size size)
struct nk_color col
Definition: nuklear.h:4458
NK_API int nk_popup_begin(struct nk_context *, enum nk_popup_type, const char *, nk_flags, struct nk_rect bounds)
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_API void nk_layout_row_template_push_variable(struct nk_context *, float min_width)
struct nk_vec2 touch_padding
Definition: nuklear.h:4794
nk_style_header_align
Definition: nuklear.h:5068
NK_API int nk_button_text_styled(struct nk_context *, const struct nk_style_button *, const char *title, int len)
struct nk_row_layout row
Definition: nuklear.h:5260
unsigned short line_thickness
Definition: nuklear.h:4448
struct nk_style_button node_maximize_button
Definition: nuklear.h:5055
unsigned int seq
Definition: nuklear.h:5455
NK_API void nk_layout_row_template_push_static(struct nk_context *, float width)
NK_API void nk_color_hsv_iv(int *hsv_out, struct nk_color)
struct nk_vec2 tooltip_padding
Definition: nuklear.h:5131
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_API int nk_combo_item_text(struct nk_context *, const char *, int, nk_flags alignment)
NK_API nk_flags nk_edit_string_zero_terminated(struct nk_context *, nk_flags, char *buffer, int max, nk_plugin_filter)
struct nk_window * current
Definition: nuklear.h:5526
NK_API void nk_text(struct nk_context *, const char *, int, nk_flags)
nk_flags flags
Definition: nuklear.h:5334
struct nk_color color
Definition: nuklear.h:4395
nk_uint values[NK_VALUE_PAGE_CAPACITY]
Definition: nuklear.h:5458
float border
Definition: nuklear.h:5010
NK_API int nk_select_label(struct nk_context *, const char *, nk_flags align, int value)
float h
Definition: nuklear.h:5202
NK_API int nk_menu_item_label(struct nk_context *, const char *, nk_flags alignment)
struct nk_color color
Definition: nuklear.h:4342
float cursor_size
Definition: nuklear.h:4965
GLdouble GLdouble GLdouble top
NK_API struct nk_rect nk_layout_widget_bounds(struct nk_context *)
struct nk_vec2i c
Definition: nuklear.h:4386
GLint i1
struct nk_color selected_text_normal
Definition: nuklear.h:4959
float w
Definition: nuklear.h:5202
NK_API int nk_button_symbol_styled(struct nk_context *, const struct nk_style_button *, enum nk_symbol_type)
float item_height
Definition: nuklear.h:5226
struct nk_color color
Definition: nuklear.h:4351
struct nk_chart_slot slots[NK_CHART_MAX_SLOT]
Definition: nuklear.h:5203
struct nk_color text_normal_active
Definition: nuklear.h:4821
char nk_glyph[NK_UTF_SIZE]
Definition: nuklear.h:461
GLdouble s
nk_plugin_free free
Definition: nuklear.h:489
NK_POINTER_TYPE nk_ptr
Definition: nuklear.h:404
NK_API struct nk_rect nk_layout_space_rect_to_local(struct nk_context *, struct nk_rect)
nk_handle texture
Definition: nuklear.h:1143
NK_API struct nk_color nk_hsv(int h, int s, int v)
struct nk_chart chart
Definition: nuklear.h:5261
struct nk_color tooltip_border_color
Definition: nuklear.h:5108
struct nk_vec2 image_padding
Definition: nuklear.h:4831
nk_flags text_alignment
Definition: nuklear.h:4825
struct nk_vec2 cursor_size
Definition: nuklear.h:4863
struct nk_color group_border_color
Definition: nuklear.h:5107
struct nk_style_item scaler
Definition: nuklear.h:5109
#define NK_ABS(a)
Definition: nuklear.h:5542
nk_buttons
Definition: nuklear.h:768
NK_API void nk_edit_focus(struct nk_context *, nk_flags flags)
GLuint GLenum matrix
Definition: glext.h:11553
unsigned short point_count
Definition: nuklear.h:4434
#define NK_MAX_FLOAT_PRECISION
Definition: nuklear.h:5537
#define NK_MAX_NUMBER_BUFFER
Definition: nuklear.h:237
unsigned char ungrab
Definition: nuklear.h:4538
nk_edit_types
Definition: nuklear.h:3358
NK_API struct nk_color nk_hsv_fv(const float *hsv)
NK_API struct nk_style_item nk_style_item_image(struct nk_image img)
nk_anti_aliasing
Definition: nuklear.h:1134
GLfloat GLfloat p
Definition: glext.h:12687
NK_API int nk_widget_is_mouse_clicked(struct nk_context *, enum nk_buttons)
struct nk_color bar_hover
Definition: nuklear.h:4848
struct nk_style_progress progress
Definition: nuklear.h:5149
const GLfloat * m
Definition: glext.h:6814
NK_API void nk_window_collapse(struct nk_context *, const char *name, enum nk_collapse_states state)
short y
Definition: nuklear.h:460
Definition: lz4.c:398
NK_API void nk_button_set_behavior(struct nk_context *, enum nk_button_behavior)
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition: glext.h:9721
nk_handle userdata
Definition: nuklear.h:4174
NK_API void nk_group_end(struct nk_context *)
NK_API int nk_input_is_key_pressed(const struct nk_input *, enum nk_keys)
unsigned short point_count
Definition: nuklear.h:4441
struct nk_style_item normal
Definition: nuklear.h:4806
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:10806
#define NK_FLAG(x)
Definition: nuklear.h:274
unsigned short w
Definition: nuklear.h:4359
GLboolean invert
static GLFWwindow * window
Definition: joysticks.c:55
unsigned short line_thickness
Definition: nuklear.h:4339
unsigned short h
Definition: nuklear.h:4456
#define NK_UTF_INVALID
Definition: nuklear.h:5536
struct nk_color top
Definition: nuklear.h:4376
struct nk_property_state property
Definition: nuklear.h:5343
GLdouble GLdouble GLdouble y2
NK_API void nk_layout_space_end(struct nk_context *)
#define NK_GLOBAL
Definition: nuklear.h:272
struct nk_style_item active
Definition: nuklear.h:4941
struct nk_style_item cursor_hover
Definition: nuklear.h:4854
nk_flags flags
Definition: nuklear.h:5249
struct nk_color border_color
Definition: nuklear.h:5102
struct nk_color text_pressed
Definition: nuklear.h:4818
NK_API void nk_layout_row_template_push_dynamic(struct nk_context *)
unsigned short w
Definition: nuklear.h:4456
struct nk_style_item normal
Definition: nuklear.h:4749
struct nk_page_element * freelist
Definition: nuklear.h:5527
GLuint64 GLenum void * handle
Definition: glext.h:7785
struct nk_vec2i c
Definition: nuklear.h:4394
struct nk_style_selectable selectable
Definition: nuklear.h:5147
GLuint color
NK_API int nk_str_insert_str_runes(struct nk_str *, int pos, const nk_rune *)
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4874
GLsizei const GLint * box
Definition: glext.h:8982
enum nk_symbol_type sym_minimize
Definition: nuklear.h:5057
struct nk_style_button inc_button
Definition: nuklear.h:4867
nk_handle userdata
Definition: nuklear.h:4799
#define NK_ALIGNOF(t)
Definition: nuklear.h:5601
struct nk_style_window window
Definition: nuklear.h:5157
float height
Definition: nuklear.h:5221
unsigned char grab
Definition: nuklear.h:4536
enum nk_symbol_type dec_symbol
Definition: nuklear.h:4929
GLsizei const GLchar *const * path
Definition: glext.h:4276
int select_start
Definition: nuklear.h:4213
struct nk_vec2i ctrl[2]
Definition: nuklear.h:4350
float group_border
Definition: nuklear.h:5115
NK_API void nk_stroke_triangle(struct nk_command_buffer *, float, float, float, float, float, float, float line_thichness, struct nk_color)
NK_SIZE_TYPE nk_size
Definition: nuklear.h:403
unsigned short w
Definition: nuklear.h:4334
unsigned short line_thickness
Definition: nuklear.h:4383
struct nk_color border_color
Definition: nuklear.h:4942
struct nk_color text_normal
Definition: nuklear.h:4816
nk_panel_row_layout_type
Definition: nuklear.h:5206
struct nk_style_button contextual_button
Definition: nuklear.h:5143
GLfloat value
NK_API void nk_label_wrap(struct nk_context *, const char *)
NK_API struct nk_color nk_hsv_bv(const nk_byte *hsv)
struct nk_style_item hover
Definition: nuklear.h:4750
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
Definition: glext.h:9721
NK_API int nk_strmatch_fuzzy_text(const char *txt, int txt_len, const char *pattern, int *out_score)
NK_API void nk_window_set_focus(struct nk_context *, const char *name)
NK_API void nk_str_delete_runes(struct nk_str *, int pos, int len)
struct nk_vec2 padding
Definition: nuklear.h:4922
#define NK_POINTER_TYPE
Definition: nuklear.h:391
unsigned int seq
Definition: nuklear.h:5325
NK_API struct nk_color nk_hsva_bv(const nk_byte *hsva)
NK_API int nk_utf_encode(nk_rune, char *, int)
NK_API void nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color)
nk_byte r
Definition: nuklear.h:455
float a[2]
Definition: nuklear.h:4418
NK_API int nk_str_append_text_char(struct nk_str *, const char *, int)
struct nk_color border_color
Definition: nuklear.h:5020
NK_API struct nk_colorf nk_hsva_colorfv(float *c)
float rounding
Definition: nuklear.h:4763
struct nk_memory memory
Definition: nuklear.h:4051
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_API void nk_list_view_end(struct nk_list_view *)
struct nk_color color
Definition: nuklear.h:4447
float header_height
Definition: nuklear.h:5255
unsigned con_old
Definition: nuklear.h:5299
NK_API struct nk_vec2 nk_layout_space_to_local(struct nk_context *, struct nk_vec2)
struct nk_image img
Definition: nuklear.h:4457
nk_size begin
Definition: nuklear.h:5235
NK_API char * nk_str_at_rune(struct nk_str *, int pos, nk_rune *unicode, int *len)
struct nk_mouse_button buttons[NK_BUTTON_MAX]
Definition: nuklear.h:4531
struct nk_vec2 clicked_pos
Definition: nuklear.h:4528
unsigned char has_preferred_x
Definition: nuklear.h:4218
NK_API struct nk_rect nk_layout_space_rect_to_screen(struct nk_context *, struct nk_rect)
struct nk_window * parent
Definition: nuklear.h:5354
union nk_style_item_data data
Definition: nuklear.h:4739
NK_API nk_uint nk_color_u32(struct nk_color)
NK_API struct nk_vec2 nk_widget_position(struct nk_context *)
struct nk_color background
Definition: nuklear.h:5100
NK_API int nk_button_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment)
NK_API int nk_filter_ascii(const struct nk_text_edit *, nk_rune unicode)
struct nk_color bottom
Definition: nuklear.h:4377
nk_popup_type
Definition: nuklear.h:476
NK_API int nk_contextual_item_text(struct nk_context *, const char *, int, nk_flags align)
struct nk_page_element * next
Definition: nuklear.h:5470
nk_uint nk_flags
Definition: nuklear.h:407
float at_x
Definition: nuklear.h:5253
NK_API int nk_str_insert_text_char(struct nk_str *, int pos, const char *, int)
struct nk_window * active
Definition: nuklear.h:5525
struct nk_color highlight
Definition: nuklear.h:5193
struct nk_color color
Definition: nuklear.h:5007
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition: glext.h:9721
float rounding
Definition: nuklear.h:5062
float at_y
Definition: nuklear.h:5253
struct nk_style_text text
Definition: nuklear.h:5141
struct nk_vec2i b
Definition: nuklear.h:4393
struct nk_color text_pressed_active
Definition: nuklear.h:4823
nk_handle userdata
Definition: nuklear.h:4834
struct nk_color label_normal
Definition: nuklear.h:5023
struct nk_color combo_border_color
Definition: nuklear.h:5104
NK_API void nk_textedit_text(struct nk_text_edit *, const char *, int total_len)
NK_API void nk_str_delete_chars(struct nk_str *, int pos, int len)
struct nk_popup_buffer buf
Definition: nuklear.h:5295
struct nk_color color
Definition: nuklear.h:4734
nk_hash name
Definition: nuklear.h:5296
struct nk_allocator alloc
Definition: nuklear.h:5481
NK_API int nk_str_append_text_runes(struct nk_str *, const nk_rune *, int)
#define NK_INT8
Definition: nuklear.h:339
nk_command_custom_callback callback
Definition: nuklear.h:4468
NK_API void nk_color_f(float *r, float *g, float *b, float *a, struct nk_color)
def progress(args)
Definition: log.py:43
NK_INT8 nk_char
Definition: nuklear.h:396
NK_API void nk_color_hsv_bv(nk_byte *hsv_out, struct nk_color)
struct nk_table * tables
Definition: nuklear.h:5348
GLenum GLenum dst
Definition: glext.h:1751
struct nk_vec2 scrollbar_size
Definition: nuklear.h:5122
NK_API int nk_strtoi(const char *str, const char **endptr)
struct nk_vec2 prev
Definition: nuklear.h:4533
enum nk_symbol_type sym_normal
Definition: nuklear.h:5034
struct nk_table * next
Definition: nuklear.h:5459
struct nk_style_item cursor_hover
Definition: nuklear.h:4887
struct nk_key keys[NK_KEY_MAX]
Definition: nuklear.h:4546
NK_API struct nk_style_item nk_style_item_hide(void)
NK_API int nk_combo_item_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment)
unsigned short line_thickness
Definition: nuklear.h:4433
NK_API void nk_label(struct nk_context *, const char *, nk_flags align)
nk_byte g
Definition: nuklear.h:455
NK_API int nk_style_set_cursor(struct nk_context *, enum nk_style_cursor)
struct nk_color text_hover
Definition: nuklear.h:4757
NK_API const struct nk_command * nk__next(struct nk_context *, const struct nk_command *)
nk_tree_type
Definition: nuklear.h:478
NK_API int nk_stricmp(const char *s1, const char *s2)
NK_API int nk_str_insert_at_rune(struct nk_str *, int pos, const char *, int)
NK_API void nk_plot(struct nk_context *, enum nk_chart_type, const float *values, int count, int offset)
unsigned curve_segment_count
Definition: nuklear.h:1152
nk_panel_type
Definition: nuklear.h:5174
GLdouble GLdouble GLdouble w
float delta_time_seconds
Definition: nuklear.h:5500
NK_API void nk_contextual_end(struct nk_context *)
GLsizei const GLchar *const * string
NK_API int nk_combo_item_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags alignment)
std_msgs::Header * header(M &m)
returns Header<M>::pointer(m);
struct nk_command_buffer overlay
Definition: nuklear.h:5517
d
Definition: rmse.py:171
NK_API int nk_progress(struct nk_context *, nk_size *cur, nk_size max, int modifyable)
nk_size needed
Definition: nuklear.h:4023
void checkbox(const char *id, T *val, S T::*f, bool &to_set)
struct nk_style_item normal
Definition: nuklear.h:5017
struct nk_vec2i begin
Definition: nuklear.h:4340
struct nk_buffer buffer
Definition: nuklear.h:4091
struct nk_vec2i a
Definition: nuklear.h:4384
struct nk_style_item active
Definition: nuklear.h:4882
struct nk_style_edit edit
Definition: nuklear.h:5151
NK_API int nk_window_is_any_hovered(struct nk_context *)
GLfloat v0
NK_API struct nk_vec2 nk_vec2iv(const int *xy)
unsigned short h
Definition: nuklear.h:4334
unsigned char cursor_at_end_of_line
Definition: nuklear.h:4216
NK_API int nk_combo_begin_text(struct nk_context *, const char *selected, int, struct nk_vec2 size)
#define NK_BUTTON_BEHAVIOR_STACK_SIZE
Definition: nuklear.h:5383
struct nk_style_button dec_button
Definition: nuklear.h:4868
NK_API void nk_input_glyph(struct nk_context *, const nk_glyph)
struct nk_style_item pressed_active
Definition: nuklear.h:4813
GLenum src
Definition: glext.h:1751
void(* nk_plugin_paste)(nk_handle, struct nk_text_edit *)
Definition: nuklear.h:483
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:1960
GLdouble GLdouble z
nk_button_behavior
Definition: nuklear.h:468
GLuint GLuint GLfloat weight
Definition: glext.h:10534
NK_API struct nk_vec2 nk_layout_space_to_screen(struct nk_context *, struct nk_vec2)
struct nk_vec2 label_padding
Definition: nuklear.h:5093
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4933
NK_API int nk_style_pop_float(struct nk_context *)
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4875
NK_API struct nk_rect nk_layout_space_bounds(struct nk_context *)
float min_row_height_padding
Definition: nuklear.h:5118
struct nk_table * prev
Definition: nuklear.h:5459
GLdouble n
Definition: glext.h:1966
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)
normal
Definition: rmse.py:164
NK_API int nk_init_custom(struct nk_context *, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font *)
struct nk_vec2i points[1]
Definition: nuklear.h:4435
struct nk_style_tab tab
Definition: nuklear.h:5155
void(* draw_begin)(struct nk_command_buffer *, nk_handle userdata)
Definition: nuklear.h:4770
struct nk_color border_color
Definition: nuklear.h:4779
NK_API int nk_select_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags align, int value)
NK_API enum nk_widget_layout_states nk_widget_fitting(struct nk_rect *, struct nk_context *, struct nk_vec2)
e
Definition: rmse.py:177
NK_API double nk_strtod(const char *str, const char **endptr)
struct nk_window win
Definition: nuklear.h:5465
NK_API void nk_window_close(struct nk_context *ctx, const char *name)
int(* nk_plugin_filter)(const struct nk_text_edit *, nk_rune unicode)
Definition: nuklear.h:482
struct nk_clipboard clip
Definition: nuklear.h:4207
nk_style_cursor
Definition: nuklear.h:3518
point
Definition: rmse.py:166
struct nk_window * begin
Definition: nuklear.h:5523
GLenum GLfloat * buffer
NK_API void nk_style_default(struct nk_context *)
NK_API void nk_input_scroll(struct nk_context *, struct nk_vec2 val)
NK_API int nk_input_has_mouse_click_down_in_rect(const struct nk_input *, enum nk_buttons, struct nk_rect, int down)
#define NK_FLOAT_STACK_SIZE
Definition: nuklear.h:5395
struct nk_style_item cursor_hover
Definition: nuklear.h:4913
float y
Definition: nuklear.h:5202
NK_API void nk_free(struct nk_context *)
struct nk_color text_normal
Definition: nuklear.h:4952
unsigned short point_count
Definition: nuklear.h:4449
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
NK_API char * nk_str_at_char(struct nk_str *, int pos)
GLuint num
Definition: glext.h:5648
direction
Definition: rs-align.cpp:25
The texture class.
Definition: example.hpp:402
NK_API int nk_button_label_styled(struct nk_context *, const struct nk_style_button *, const char *title)
NK_API struct nk_color nk_rgb(int r, int g, int b)
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)
enum nk_symbol_type sym_active
Definition: nuklear.h:5036
NK_API void nk_layout_space_push(struct nk_context *, struct nk_rect bounds)
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)
unsigned int has_scrolling
Definition: nuklear.h:5257
int len
Definition: nuklear.h:4092
unsigned int type
Definition: nuklear.h:4020
NK_API void nk_tree_state_pop(struct nk_context *)
NK_API int nk_combo_begin_label(struct nk_context *, const char *selected, struct nk_vec2 size)
NK_API int nk_stricmpn(const char *s1, const char *s2, int n)
#define NK_UINT32
Definition: nuklear.h:361
GLenum GLuint id
unsigned int table_count
Definition: nuklear.h:5349
GLenum GLenum GLsizei void * image
NK_API int nk_style_push_flags(struct nk_context *, nk_flags *, nk_flags)
struct nk_style_item active
Definition: nuklear.h:5019
NK_API void nk_window_collapse_if(struct nk_context *, const char *name, enum nk_collapse_states, int cond)
struct nk_vec2 button_padding
Definition: nuklear.h:5042
float contextual_border
Definition: nuklear.h:5113
char text[NK_INPUT_MAX]
Definition: nuklear.h:4547
NK_API void nk_layout_reset_min_row_height(struct nk_context *)
nk_uint y
Definition: nuklear.h:465
GLuint index
NK_API struct nk_colorf nk_color_cf(struct nk_color)
unsigned char active
Definition: nuklear.h:4220
float templates[NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS]
Definition: nuklear.h:5231
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_API struct nk_vec2 nk_window_get_position(const struct nk_context *ctx)
NK_API void nk_color_fv(float *rgba_out, struct nk_color)
NK_API int nk_input_is_mouse_prev_hovering_rect(const struct nk_input *, struct nk_rect)
GLdouble t
nk_keys
Definition: nuklear.h:733
unsigned arc_segment_count
Definition: nuklear.h:1151
GLboolean GLboolean GLboolean GLboolean a
#define NK_INT16
Definition: nuklear.h:345
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4801
NK_API void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols)
GLenum GLuint GLenum GLsizei const GLchar * buf
nk_style_item_type
Definition: nuklear.h:4727
const struct nk_cursor * cursor_active
Definition: nuklear.h:5137
GLenum GLsizei len
Definition: glext.h:3285
unsigned circle_segment_count
Definition: nuklear.h:1150
GLuint GLfloat * val
GLuint64 key
Definition: glext.h:8966
enum nk_symbol_type dec_symbol
Definition: nuklear.h:4870
#define NK_LIB
Definition: nuklear.h:264
struct nk_color label_hover
Definition: nuklear.h:5087
enum nk_symbol_type maximize_symbol
Definition: nuklear.h:5083
struct nk_vec2i b
Definition: nuklear.h:4385
def info(name, value, persistent=False)
Definition: test.py:301
struct nk_style_button button
Definition: nuklear.h:5142
struct nk_style_scrollbar scrollh
Definition: nuklear.h:5153
NK_API int nk_input_is_mouse_click_in_rect(const struct nk_input *, enum nk_buttons, struct nk_rect)
GLenum const void GLbitfield GLsizei numGlyphs
Definition: glext.h:10530
NK_API void nk_group_scrolled_end(struct nk_context *)
nk_handle userdata
Definition: nuklear.h:4932
unsigned active_con
Definition: nuklear.h:5300
const float * ratio
Definition: nuklear.h:5224
NK_API int nk_contextual_item_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags alignment)
unsigned char single_line
Definition: nuklear.h:4219
struct nk_color foreground
Definition: nuklear.h:4475
struct nk_vec2 padding
Definition: nuklear.h:5125
struct nk_table tbl
Definition: nuklear.h:5463
struct nk_panel * parent
Definition: nuklear.h:5263
NK_API void nk_layout_set_min_row_height(struct nk_context *, float height)
struct nk_style_item normal
Definition: nuklear.h:4973
struct nk_vec2 scrollbar
Definition: nuklear.h:4210
not_this_one begin(...)
NK_API struct nk_vec2 nk_vec2(float x, float y)
unsigned char padding1
Definition: nuklear.h:4221
NK_API void nk_menubar_end(struct nk_context *)
struct nk_vec2 scrollbar_size
Definition: nuklear.h:4966
struct nk_color border_color
Definition: nuklear.h:4752
NK_API void nk_buffer_mark(struct nk_buffer *, enum nk_buffer_allocation_type type)
#define NK_WINDOW_MAX_NAME
Definition: nuklear.h:5270
nk_uint * offset_x
Definition: nuklear.h:5251
struct nk_config_stack_user_font fonts
Definition: nuklear.h:5444
union nk_page_data data
Definition: nuklear.h:5469
GLdouble f
NK_API int nk_combo_begin_symbol(struct nk_context *, enum nk_symbol_type, struct nk_vec2 size)
NK_API void nk_image(struct nk_context *, struct nk_image)
float footer_height
Definition: nuklear.h:5254
#define NK_VECTOR_STACK_SIZE
Definition: nuklear.h:5399
NK_API void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols)
NK_API int nk_strlen(const char *str)
struct nk_style_item normal
Definition: nuklear.h:4939
float height
Definition: nuklear.h:3843
unsigned short rounding
Definition: nuklear.h:4365
NK_API void nk_tree_element_pop(struct nk_context *)
GLfloat cursor_y
Definition: boing.c:98
struct nk_page * next
Definition: nuklear.h:5476
NK_API float nk_strtof(const char *str, const char **endptr)
NK_UINT32 nk_uint
Definition: nuklear.h:402
float3 colors[]
Definition: rs-pcl.cpp:44
struct nk_vec2 spacing
Definition: nuklear.h:5043
#define NK_SIZE_TYPE
Definition: nuklear.h:376
struct nk_color bar_active
Definition: nuklear.h:4849
struct nk_color cursor_text_normal
Definition: nuklear.h:4948
NK_API struct nk_color nk_rgb_fv(const float *rgb)
NK_API int nk_color_pick(struct nk_context *, struct nk_colorf *, enum nk_color_format)
NK_API int nk_window_is_collapsed(struct nk_context *ctx, const char *name)
int tree_depth
Definition: nuklear.h:5230
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)
float b
Definition: nuklear.h:456
enum nk_allocation_type type
Definition: nuklear.h:5482
GLfloat GLfloat GLfloat alpha
unsigned int seq
Definition: nuklear.h:5331
struct nk_buffer memory
Definition: nuklear.h:5495
nk_text_align
Definition: nuklear.h:3000
NK_API struct nk_color nk_hsva_iv(const int *hsva)
NK_API void nk_combobox(struct nk_context *, const char **items, int count, int *selected, int item_height, struct nk_vec2 size)
struct nk_scroll scrollbar
Definition: nuklear.h:5312
NK_API void nk_buffer_reset(struct nk_buffer *, enum nk_buffer_allocation_type type)
NK_API int nk_str_insert_text_runes(struct nk_str *, int pos, const nk_rune *, int)
enum nk_symbol_type sym_maximize
Definition: nuklear.h:5058
void(* nk_command_custom_callback)(void *canvas, short x, short y, unsigned short w, unsigned short h, nk_handle callback_data)
Definition: nuklear.h:4461
NK_API void nk_textedit_delete_selection(struct nk_text_edit *)
struct nk_window * end
Definition: nuklear.h:5524
struct nk_rect item
Definition: nuklear.h:5229
NK_API void nk_color_hsva_bv(nk_byte *hsva_out, struct nk_color)
Definition: getopt.h:41
float item_offset
Definition: nuklear.h:5227
struct nk_color text
Definition: nuklear.h:5050
NK_API struct nk_color nk_rgba(int r, int g, int b, int a)
GLsizeiptr size
NK_API void * nk_buffer_memory(struct nk_buffer *)
nk_text_edit_type
Definition: nuklear.h:4195
NK_API void nk_textedit_init_fixed(struct nk_text_edit *, void *memory, nk_size size)
NK_API int nk_init_fixed(struct nk_context *, void *memory, nk_size size, const struct nk_user_font *)
unsigned short h
Definition: nuklear.h:4367
#define NK_SATURATE(x)
Definition: nuklear.h:5540
struct nk_style_slider slider
Definition: nuklear.h:5148
struct nk_color label_active
Definition: nuklear.h:4981
NK_API void nk_stroke_curve(struct nk_command_buffer *, float, float, float, float, float, float, float, float, float line_thickness, struct nk_color)
float popup_border
Definition: nuklear.h:5117
NK_API int nk_button_image(struct nk_context *, struct nk_image img)
NK_API struct nk_image nk_subimage_handle(nk_handle, unsigned short w, unsigned short h, struct nk_rect sub_region)
nk_hash name
Definition: nuklear.h:5305
float border
Definition: nuklear.h:5039
nk_size parent
Definition: nuklear.h:5236
NK_API int nk_combo(struct nk_context *, const char **items, int count, int selected, int item_height, struct nk_vec2 size)
nk_byte a
Definition: nuklear.h:455
NK_API struct nk_color nk_rgba_f(float r, float g, float b, float a)
NK_API void nk_str_clear(struct nk_str *)
float rounding
Definition: nuklear.h:5011
#define NK_TEXTEDIT_UNDOCHARCOUNT
Definition: nuklear.h:4169
NK_API const void * nk_buffer_memory_const(const struct nk_buffer *)
#define nk_ptr_add_const(t, p, i)
Definition: nuklear.h:5557
const GLubyte * c
Definition: glext.h:12690
NK_API void nk_buffer_init_fixed(struct nk_buffer *, void *memory, nk_size size)
float x
Definition: nuklear.h:459
NK_API void nk_layout_row_template_begin(struct nk_context *, float row_height)
NK_API void nk_popup_close(struct nk_context *)
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)
GLdouble GLdouble r
enum nk_symbol_type inc_symbol
Definition: nuklear.h:4928
nk_uint nk_rune
Definition: nuklear.h:408
struct nk_color text_active
Definition: nuklear.h:4758
struct nk_page_element * freelist
Definition: nuklear.h:5485
struct nk_window * next
Definition: nuklear.h:5352
struct nk_vec2 combo_padding
Definition: nuklear.h:5128
NK_API int nk_str_append_text_utf8(struct nk_str *, const char *, int)
struct nk_color text_hover
Definition: nuklear.h:4787
NK_API void nk_text_colored(struct nk_context *, const char *, int, nk_flags, struct nk_color)
GLenum GLint GLint * precision
Definition: glext.h:1883
nk_panel_set
Definition: nuklear.h:5184
unsigned short w
Definition: nuklear.h:4477
float x
Definition: nuklear.h:5202
struct nk_image image
Definition: nuklear.h:4733
float cursor_rounding
Definition: nuklear.h:4895
NK_API int nk_checkbox_flags_text(struct nk_context *, const char *, int, unsigned int *flags, unsigned int value)
NK_API int nk_button_image_styled(struct nk_context *, const struct nk_style_button *, struct nk_image img)
unsigned short line_thickness
Definition: nuklear.h:4347
int total_height
Definition: nuklear.h:2957
NK_API struct nk_rect nk_rect(float x, float y, float w, float h)
struct nk_vec2 touch_padding
Definition: nuklear.h:4766
nk_orientation
Definition: nuklear.h:470
GLbyte ty
Definition: glext.h:6694
NK_API void nk_style_show_cursor(struct nk_context *)
GLdouble x
struct nk_window * prev
Definition: nuklear.h:5353
struct nk_vec2 min_size
Definition: nuklear.h:5123
struct nk_color color
Definition: nuklear.h:4410
struct nk_style_item normal
Definition: nuklear.h:5074
struct nk_vec2 padding
Definition: nuklear.h:5092
nk_widget_layout_states
Definition: nuklear.h:2969
struct nk_style_scrollbar scrollv
Definition: nuklear.h:5154
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_API struct nk_colorf nk_color_picker(struct nk_context *, struct nk_colorf, enum nk_color_format)
NK_API int nk_style_push_font(struct nk_context *, const struct nk_user_font *)
enum nk_anti_aliasing line_AA
Definition: nuklear.h:1148
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)
struct nk_style_item active
Definition: nuklear.h:4751
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_collapse_states
Definition: nuklear.h:471
NK_API const char * nk_utf_at(const char *buffer, int length, int index, nk_rune *unicode, int *len)
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_API void nk_style_hide_cursor(struct nk_context *)
NK_API int nk_menu_begin_image_text(struct nk_context *, const char *, int, nk_flags align, struct nk_image, struct nk_vec2 size)
struct nk_color border_color
Definition: nuklear.h:4844
struct nk_color color
Definition: nuklear.h:4368
NK_API void nk_str_remove_runes(struct nk_str *str, int len)
struct nk_vec2 spacing
Definition: nuklear.h:5121
float item_width
Definition: nuklear.h:5225
GLdouble GLdouble x2
#define NK_ALIGN_PTR(x, mask)
Definition: nuklear.h:5578
struct nk_color color
Definition: nuklear.h:4387
int cursor_visible
Definition: nuklear.h:5139
NK_API int nk_widget_has_mouse_click_down(struct nk_context *, enum nk_buttons, int down)
#define NK_CLAMP(i, v, x)
Definition: nuklear.h:301
struct nk_style_combo combo
Definition: nuklear.h:5156
struct nk_style_property property
Definition: nuklear.h:5150
unsigned short region[4]
Definition: nuklear.h:463
NK_API void nk_input_begin(struct nk_context *)
struct nk_window * win
Definition: nuklear.h:5293
struct nk_color contextual_border_color
Definition: nuklear.h:5105
NK_API int nk_option_text(struct nk_context *, const char *, int, int active)
void * ptr
Definition: nuklear.h:462
struct nk_menu_state menu
Definition: nuklear.h:5259
NK_API void nk_stroke_rect(struct nk_command_buffer *, struct nk_rect, float rounding, float line_thickness, struct nk_color)
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_API void nk_push_scissor(struct nk_command_buffer *, struct nk_rect)
NK_API const struct nk_command * nk__begin(struct nk_context *)
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4800
float min_height
Definition: nuklear.h:5222
NK_API nk_flags nk_chart_push_slot(struct nk_context *, float, int)
nk_edit_flags
Definition: nuklear.h:3343
#define NK_INBOX(px, py, x, y, w, h)
Definition: nuklear.h:5544
#define nk_vec2_sub(a, b)
Definition: nuklear.h:5551
GLint GLsizei GLsizei height
NK_API int nk_str_append_str_char(struct nk_str *, const char *)
float indent
Definition: nuklear.h:5063
static const textual_icon edit
Definition: model-views.h:221
struct nk_color selected_color
Definition: nuklear.h:5006
unsigned char initialized
Definition: nuklear.h:4217
NK_API int nk_input_is_key_down(const struct nk_input *, enum nk_keys)
NK_API int nk_window_is_hovered(struct nk_context *)
GLsizei GLenum GLsizei GLsizei GLuint memory
Definition: glext.h:7730
NK_API double nk_propertyd(struct nk_context *, const char *name, double min, double val, double max, double step, float inc_per_pixel)
#define NK_PI
Definition: nuklear.h:5535
struct nk_cursor * cursor_last
Definition: nuklear.h:5138
GLint GLint GLsizei GLint GLenum format
NK_API int nk_filter_decimal(const struct nk_text_edit *, nk_rune unicode)
NK_API int nk_filter_binary(const struct nk_text_edit *, nk_rune unicode)
NK_API int nk_init(struct nk_context *, struct nk_allocator *, const struct nk_user_font *)
NK_API int nk_radio_label(struct nk_context *, const char *, int *active)
struct nk_vec2 spacing
Definition: nuklear.h:5094
NK_API void nk_contextual_close(struct nk_context *)
NK_API int nk_input_has_mouse_click_in_rect(const struct nk_input *, enum nk_buttons, struct nk_rect)
NK_API void nk_textedit_init(struct nk_text_edit *, struct nk_allocator *, nk_size size)
const struct nk_cursor * cursors[NK_CURSOR_COUNT]
Definition: nuklear.h:5136
struct nk_vec2 spacing
Definition: nuklear.h:4862
const struct nk_draw_vertex_layout_element * vertex_layout
Definition: nuklear.h:1154
struct nk_style_chart chart
Definition: nuklear.h:5152
#define NK_UTF_SIZE
Definition: nuklear.h:232
struct nk_vec2 popup_padding
Definition: nuklear.h:5127
NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols)
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_API const char * nk_str_get_const(const struct nk_str *)
NK_API int nk_textedit_cut(struct nk_text_edit *)
NK_API void nk_property_double(struct nk_context *, const char *name, double min, double *val, double max, double step, float inc_per_pixel)
struct nk_color cursor_text_hover
Definition: nuklear.h:4949
GLenum target
Definition: glext.h:1565
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_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_API void nk_color_hsva_i(int *h, int *s, int *v, int *a, struct nk_color)
float rounding
Definition: nuklear.h:4859
NK_API void nk_stroke_polyline(struct nk_command_buffer *, float *points, int point_count, float line_thickness, struct nk_color col)
NK_API void nk_text_wrap_colored(struct nk_context *, const char *, int, struct nk_color)
NK_API enum nk_widget_layout_states nk_widget(struct nk_rect *, const struct nk_context *)
nk_edit_events
Definition: nuklear.h:3364
NK_API struct nk_vec2 nk_rect_pos(struct nk_rect)
GLbitfield flags
struct nk_text_undo_state undo
Definition: nuklear.h:4223
NK_API int nk_input_is_mouse_released(const struct nk_input *, enum nk_buttons)
NK_API void nk_property_int(struct nk_context *, const char *name, int min, int *val, int max, int step, float inc_per_pixel)
struct nk_style_button button
Definition: nuklear.h:5033
#define NK_SCROLLBAR_HIDING_TIMEOUT
Definition: nuklear.h:240
enum nk_symbol_type sym_right
Definition: nuklear.h:4985
def find(dir, mask)
Definition: file.py:25
NK_API struct nk_colorf nk_hsva_colorf(float h, float s, float v, float a)
NK_API void nk_color_hex_rgba(char *output, struct nk_color)
#define NK_MIN(a, b)
Definition: nuklear.h:299
struct nk_vec2 group_padding
Definition: nuklear.h:5126
nk_handle userdata
Definition: nuklear.h:487
NK_API void nk_style_load_cursor(struct nk_context *, enum nk_style_cursor, const struct nk_cursor *)
unsigned int size
Definition: nuklear.h:5475
double ay[GRIDW][GRIDH]
Definition: wave.c:111
NK_API int nk_select_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags align, int value)
NK_API int nk_input_is_mouse_pressed(const struct nk_input *, enum nk_buttons)
struct nk_style_item cursor_normal
Definition: nuklear.h:4853
#define NK_VALUE_PAGE_CAPACITY
Definition: nuklear.h:5451
NK_API void nk_push_custom(struct nk_command_buffer *, struct nk_rect, nk_command_custom_callback, nk_handle usr)
enum nk_style_header_align align
Definition: nuklear.h:5091
NK_API int nk_str_len_char(struct nk_str *)
unsigned int clicked
Definition: nuklear.h:4543
NK_API int nk_input_any_mouse_click_in_rect(const struct nk_input *, struct nk_rect)
void * ptr
Definition: nuklear.h:4043
NK_API const char * nk_style_get_color_by_name(enum nk_style_colors)
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_size vertex_alignment
Definition: nuklear.h:1156
NK_API void nk_tooltip_end(struct nk_context *)
GLuint GLfloat x0
Definition: glext.h:9721
struct nk_color border_color
Definition: nuklear.h:5005
struct nk_style_item cursor_normal
Definition: nuklear.h:4886
GLuint start
unsigned short h
Definition: nuklear.h:4402
static int done
short w
Definition: nuklear.h:460
NK_API void nk_spacing(struct nk_context *, int cols)
GLint j
GLdouble GLdouble GLint stride
struct nk_color text_background
Definition: nuklear.h:4755
float y
Definition: nuklear.h:457
NK_API struct nk_color nk_rgba_hex(const char *rgb)
struct nk_vec2i points[1]
Definition: nuklear.h:4442
struct nk_vec2 padding
Definition: nuklear.h:5064
struct nk_style_item active
Definition: nuklear.h:4975
NK_API int nk_button_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags text_alignment)
#define NK_STATIC_ASSERT(exp)
Definition: nuklear.h:288
GLint left
Definition: glext.h:1963
static std::string custom
Definition: hid-types.h:25
NK_API struct nk_image nk_subimage_ptr(void *, unsigned short w, unsigned short h, struct nk_rect sub_region)
NK_API void nk_text_wrap(struct nk_context *, const char *, int)
NK_API struct nk_image nk_image_handle(nk_handle)
NK_API struct nk_image nk_image_ptr(void *)
GLint first
NK_API float nk_window_get_width(const struct nk_context *)
NK_API int nk_image_is_subimage(const struct nk_image *img)
struct nk_context * ctx
Definition: nuklear.h:2958
unsigned char mode
Definition: nuklear.h:4215
struct nk_style_item hover
Definition: nuklear.h:4842
unsigned short h
Definition: nuklear.h:4477
NK_API void nk_draw_image(struct nk_command_buffer *, struct nk_rect, const struct nk_image *, struct nk_color)
struct nk_color text_hover_active
Definition: nuklear.h:4822
NK_API int nk_selectable_label(struct nk_context *, const char *, nk_flags align, int *value)
struct nk_style_button tab_minimize_button
Definition: nuklear.h:5054
struct nk_vec2 padding
Definition: nuklear.h:4967
NK_API struct nk_color nk_hsva(int h, int s, int v, int a)
struct nk_vec2 spacing
Definition: nuklear.h:5065
#define NK_STYLE_ITEM_STACK_SIZE
Definition: nuklear.h:5391
NK_API int nk_str_insert_text_utf8(struct nk_str *, int pos, const char *, int)
NK_API void nk_tooltip(struct nk_context *, const char *)
struct nk_color text_active
Definition: nuklear.h:4788
#define NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
Definition: nuklear.h:5168
nk_plugin_alloc alloc
Definition: nuklear.h:488
NK_API void nk_combo_close(struct nk_context *)
struct nk_color text_hover
Definition: nuklear.h:4953
NK_API int nk_radio_text(struct nk_context *, const char *, int, int *active)
GLint void * img
NK_API void nk_buffer_clear(struct nk_buffer *)
nk_uint scroll_value
Definition: nuklear.h:2960
short undo_char_point
Definition: nuklear.h:4191
enum nk_symbol_type sym_hover
Definition: nuklear.h:5035
enum nk_symbol_type close_symbol
Definition: nuklear.h:5081
int id
Definition: nuklear.h:462
void *(* nk_plugin_alloc)(nk_handle, void *old, nk_size)
Definition: nuklear.h:480
NK_API struct nk_vec2 nk_window_get_size(const struct nk_context *)
nk_uint * offset_y
Definition: nuklear.h:5252
struct nk_color label_hover
Definition: nuklear.h:4980
nk_size end
Definition: nuklear.h:5238
int select_end
Definition: nuklear.h:4214
NK_API const char * nk_str_at_char_const(const struct nk_str *, int pos)
struct nk_configuration_stacks stacks
Definition: nuklear.h:5499
struct nk_style_item cursor_active
Definition: nuklear.h:4914
GLint GLint GLsizei GLint GLenum GLenum const void * pixels
NK_API nk_handle nk_handle_id(int)
NK_API int nk_combo_item_image_label(struct nk_context *, struct nk_image, const char *, nk_flags alignment)
NK_UINT8 nk_uchar
Definition: nuklear.h:397
NK_API struct nk_color nk_rgb_f(float r, float g, float b)
enum nk_allocation_type type
Definition: nuklear.h:4049
float r
Definition: nuklear.h:456
nk_window_flags
Definition: nuklear.h:5274
nk_chart_type
Definition: nuklear.h:473
float x
Definition: nuklear.h:457
struct nk_color symbol_hover
Definition: nuklear.h:5029
struct nk_mouse mouse
Definition: nuklear.h:4553
enum nk_chart_type type
Definition: nuklear.h:5191
struct nk_rect bounds
Definition: nuklear.h:5250
NK_API int nk_contextual_item_label(struct nk_context *, const char *, nk_flags align)
#define NK_CONFIGURATION_STACK_TYPE(prefix, name, type)
Definition: nuklear.h:5410
struct nk_color border_color
Definition: nuklear.h:4909
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)
float rounding
Definition: nuklear.h:4964
nk_size size
Definition: nuklear.h:5487
struct nk_vec2 padding
Definition: nuklear.h:4829
NK_API void nk_stroke_polygon(struct nk_command_buffer *, float *, int point_count, float line_thickness, struct nk_color)
unsigned combo_count
Definition: nuklear.h:5298
NK_API void nk_popup_end(struct nk_context *)
unsigned int size
Definition: nuklear.h:5456
int build
Definition: nuklear.h:5520
struct nk_page * pages
Definition: nuklear.h:5484
NK_API void nk_input_motion(struct nk_context *, int x, int y)
NK_API int nk_textedit_paste(struct nk_text_edit *, char const *, int len)
NK_API int nk_utf_len(const char *, int byte_len)
float g
Definition: nuklear.h:456
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_size vertex_size
Definition: nuklear.h:1155
unsigned short w
Definition: nuklear.h:4402
NK_API struct nk_color nk_hsva_fv(const float *hsva)
nk_size cap
Definition: nuklear.h:5488
static const ImVec4 black
Definition: model-views.h:43
enum nk_symbol_type inc_symbol
Definition: nuklear.h:4869
NK_API void nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color)
struct nk_keyboard keyboard
Definition: nuklear.h:4552
unsigned short rounding
Definition: nuklear.h:4356
#define NK_UINT16
Definition: nuklear.h:348
unsigned short w
Definition: nuklear.h:463
unsigned short w
Definition: nuklear.h:4409
#define NK_TEXTEDIT_UNDOSTATECOUNT
Definition: nuklear.h:4165
float dot(float3 const &a, float3 const &b)
Definition: test-pose.cpp:74
NK_API void nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type, int count, float min_value, float max_value)
struct nk_style_scrollbar scrollbar
Definition: nuklear.h:4943
struct nk_color bar_normal
Definition: nuklear.h:4847
nk_flags last_widget_state
Definition: nuklear.h:5497
#define nk_foreach(c, ctx)
Definition: nuklear.h:1202
struct nk_color color
Definition: nuklear.h:5192
struct nk_style_item normal_active
Definition: nuklear.h:4811
NK_API float nk_window_get_height(const struct nk_context *)
NK_API float nk_widget_height(struct nk_context *)
NK_API int nk_menu_item_image_label(struct nk_context *, struct nk_image, const char *, nk_flags alignment)
NK_API int nk_slide_int(struct nk_context *, int min, int val, int max, int step)
NK_API int nk_filter_oct(const struct nk_text_edit *, nk_rune unicode)
float filled
Definition: nuklear.h:5228
#define NK_LEN(a)
Definition: nuklear.h:5541
NK_API struct nk_rect nk_recta(struct nk_vec2 pos, struct nk_vec2 size)
NK_API int nk_slider_float(struct nk_context *, float min, float *val, float max, float step)
NK_API int nk_window_is_hidden(struct nk_context *, const char *)
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)
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
Definition: glext.h:12384
struct nk_command_buffer buffer
Definition: nuklear.h:5338
#define NK_INTERN
Definition: nuklear.h:270
NK_API int nk_slider_int(struct nk_context *, int min, int *val, int max, int step)
nk_size allocated
Definition: nuklear.h:4022
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4934
struct nk_vec2i end
Definition: nuklear.h:4341
NK_API int nk_contextual_item_image_label(struct nk_context *, struct nk_image, const char *, nk_flags alignment)
unsigned con_count
Definition: nuklear.h:5299
NK_API void nk_input_button(struct nk_context *, enum nk_buttons, int x, int y, int down)
NK_API int nk_item_is_any_active(struct nk_context *)
NK_API void nk_label_colored_wrap(struct nk_context *, const char *, struct nk_color)
struct nk_style_toggle checkbox
Definition: nuklear.h:5146
NK_API void nk_input_key(struct nk_context *, enum nk_keys, int down)
void(* nk_plugin_free)(nk_handle, void *old)
Definition: nuklear.h:481
NK_API struct nk_style_item nk_style_item_color(struct nk_color)
NK_API void nk_fill_rect(struct nk_command_buffer *, struct nk_rect, float rounding, struct nk_color)
GLenum GLenum GLsizei void * table
NK_API int nk_button_push_behavior(struct nk_context *, enum nk_button_behavior)
#define nk_ptr_add(t, p, i)
Definition: nuklear.h:5556
NK_API float nk_slide_float(struct nk_context *, float min, float val, float max, float step)
NK_API void nk_color_hsva_fv(float *hsva_out, struct nk_color)
GLsizei const GLfloat * values
NK_API void nk_fill_polygon(struct nk_command_buffer *, float *, int point_count, struct nk_color)
NK_API int nk_selectable_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags align, int *value)
nk_size size
Definition: nuklear.h:4043
GLdouble GLdouble GLint GLint GLdouble v1
NK_API float nk_widget_width(struct nk_context *)
struct nk_color border_color
Definition: nuklear.h:4883
#define nk_vec2_add(a, b)
Definition: nuklear.h:5552
NK_API int nk_input_is_mouse_hovering_rect(const struct nk_input *, struct nk_rect)
double ax[GRIDW][GRIDH]
Definition: wave.c:111
float cursor_border
Definition: nuklear.h:4894
NK_API int nk_chart_begin(struct nk_context *, enum nk_chart_type, int num, float min, float max)
void next(auto_any_t cur, type2type< T, C > *)
Definition: foreach.hpp:757
NK_API int nk_style_pop_vec2(struct nk_context *)
NK_API nk_size nk_buffer_total(struct nk_buffer *)
nk_size size
Definition: nuklear.h:4021
NK_API nk_handle nk_handle_ptr(void *)
unsigned short h
Definition: nuklear.h:4466
unsigned int clicked
Definition: nuklear.h:4527
struct nk_style_item cursor_active
Definition: nuklear.h:4855
Definition: example.hpp:70
NK_API void nk_window_show(struct nk_context *, const char *name, enum nk_show_states)
struct nk_style style
Definition: nuklear.h:5494
NK_API void nk_tree_pop(struct nk_context *)
float range
Definition: nuklear.h:5194
const struct nk_user_font * font
Definition: nuklear.h:4473
NK_API void nk_textedit_undo(struct nk_text_edit *)
NK_API unsigned nk_check_flags_text(struct nk_context *, const char *, int, unsigned int flags, unsigned int value)
unsigned int count
Definition: nuklear.h:5528
GLenum array
Definition: glext.h:7022
GLuint GLfloat GLfloat GLfloat x1
Definition: glext.h:9721
struct nk_popup_state popup
Definition: nuklear.h:5344
NK_API float nk_layout_ratio_from_pixel(struct nk_context *, float pixel_width)
struct nk_vec2 padding
Definition: nuklear.h:4764
NK_API nk_flags nk_edit_buffer(struct nk_context *, nk_flags, struct nk_text_edit *, nk_plugin_filter)
float y
Definition: nuklear.h:459
short x
Definition: nuklear.h:458
struct nk_color right
Definition: nuklear.h:4378
NK_API int nk_style_pop_style_item(struct nk_context *)
std::pair< T, T > in_range(T begin, T end)
Definition: foreach.hpp:112
nk_handle userdata
Definition: nuklear.h:3841
struct nk_style_item hover
Definition: nuklear.h:4907
nk_plugin_filter filter
Definition: nuklear.h:4209
struct nk_style_item normal
Definition: nuklear.h:4906
NK_API int nk_checkbox_flags_label(struct nk_context *, const char *, unsigned int *flags, unsigned int value)
struct nk_color symbol_active
Definition: nuklear.h:5030
nk_rune undo_char[NK_TEXTEDIT_UNDOCHARCOUNT]
Definition: nuklear.h:4188
float scrollbar_hiding_timer
Definition: nuklear.h:5340
GLdouble GLdouble GLdouble q
NK_API struct nk_color nk_rgb_cf(struct nk_colorf c)
NK_API int nk_str_append_str_utf8(struct nk_str *, const char *)
nk_text_alignment
Definition: nuklear.h:3008
#define NK_API
Definition: nuklear.h:259
struct nk_rect bounds
Definition: nuklear.h:5336
unsigned short w
Definition: nuklear.h:4466
NK_API int nk_window_is_active(struct nk_context *, const char *)
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4835
unsigned short line_thickness
Definition: nuklear.h:4401
struct nk_style_window_header header
Definition: nuklear.h:5098
int mx
Definition: rmse.py:54
float global_alpha
Definition: nuklear.h:1147
struct nk_color color
Definition: nuklear.h:4360
unsigned capacity
Definition: nuklear.h:5486
NK_API int nk_style_push_color(struct nk_context *, struct nk_color *, struct nk_color)
struct nk_vec2 padding
Definition: nuklear.h:5012
NK_API void nk_style_load_all_cursors(struct nk_context *, struct nk_cursor *)
NK_API void nk_window_set_position(struct nk_context *, const char *name, struct nk_vec2 pos)
struct nk_vec2 touch_padding
Definition: nuklear.h:4830
struct nk_color color
Definition: nuklear.h:4432
struct nk_style_item fixed_background
Definition: nuklear.h:5099
static const struct @18 vertices[3]
nk_byte b
Definition: nuklear.h:455
NK_API int nk_input_has_mouse_click(const struct nk_input *, enum nk_buttons)
NK_API int nk_combo_begin_color(struct nk_context *, struct nk_color color, struct nk_vec2 size)
NK_API void nk_str_free(struct nk_str *)
NK_API int nk_option_label(struct nk_context *, const char *, int active)
nk_size last
Definition: nuklear.h:5237
nk_allocation_type
Definition: nuklear.h:4027
struct nk_vec2i a
Definition: nuklear.h:4392
GLenum query
nk_plugin_paste paste
Definition: nuklear.h:4175
NK_API int nk_combo_begin_image_label(struct nk_context *, const char *selected, struct nk_image, struct nk_vec2 size)
struct nk_color cursor_border_color
Definition: nuklear.h:4915
nk_size next
Definition: nuklear.h:4325
struct nk_color color
Definition: nuklear.h:4440
GLdouble right
struct nk_style_item background
Definition: nuklear.h:5048
static auto it
NK_API void nk_image_color(struct nk_context *, struct nk_image, struct nk_color)
NK_API void nk_textedit_free(struct nk_text_edit *)
struct nk_scroll scrollbar
Definition: nuklear.h:5337
GLenum GLenum GLenum input
Definition: glext.h:10805
NK_API void nk_color_hsva_iv(int *hsva_out, struct nk_color)
struct nk_buffer * base
Definition: nuklear.h:4489
void(* nk_plugin_copy)(nk_handle, const char *, int len)
Definition: nuklear.h:484
const GLchar * marker
Definition: glext.h:6789
NK_API struct nk_command_buffer * nk_window_get_canvas(struct nk_context *)
GLuint in
Definition: glext.h:8859
NK_API int nk_checkbox_text(struct nk_context *, const char *, int, int *active)
GLenum type
nk_uint nk_hash
Definition: nuklear.h:406
NK_API int nk_str_len(struct nk_str *)
nk_command_type
Definition: nuklear.h:4300
NK_API nk_flags nk_edit_string(struct nk_context *, nk_flags, char *buffer, int *len, int max, nk_plugin_filter)
NK_API void nk_edit_unfocus(struct nk_context *)
unsigned int old
Definition: nuklear.h:5307
nk_size calls
Definition: nuklear.h:4024
struct nk_vec2 pos
Definition: nuklear.h:4532
struct nk_style_item hover
Definition: nuklear.h:4974
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:3823
NK_API int nk_combo_item_image_text(struct nk_context *, struct nk_image, const char *, int, nk_flags alignment)
NK_API int nk_combo_begin_symbol_text(struct nk_context *, const char *selected, int, enum nk_symbol_type, struct nk_vec2 size)
int min(int a, int b)
Definition: lz4s.c:73
#define NK_INPUT_MAX
Definition: nuklear.h:234
GLuint GLsizei const GLchar * 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_API void nk_buffer_free(struct nk_buffer *)
struct nk_style_item hover
Definition: nuklear.h:5075
NK_API struct nk_color nk_hsv_f(float h, float s, float v)
nk_hash name
Definition: nuklear.h:5332
void(* draw_end)(struct nk_command_buffer *, nk_handle userdata)
Definition: nuklear.h:4771
struct nk_style_item cursor_active
Definition: nuklear.h:4888
static double xpos
Definition: splitview.c:33
struct nk_color color
Definition: nuklear.h:4403
struct nk_style_item normal
Definition: nuklear.h:4841
NK_API int nk_button_symbol(struct nk_context *, enum nk_symbol_type)
NK_API int nk_checkbox_label(struct nk_context *, const char *, int *active)
int use_pool
Definition: nuklear.h:5521
enum nk_symbol_type minimize_symbol
Definition: nuklear.h:5082
struct nk_vec2 scroll_delta
Definition: nuklear.h:4535
enum nk_panel_type type
Definition: nuklear.h:5294
NK_API int nk_window_is_closed(struct nk_context *, const char *)
struct nk_vec2 padding
Definition: nuklear.h:4793
NK_API int nk_selectable_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags align, int *value)
NK_API int nk_group_begin(struct nk_context *, const char *title, nk_flags)
struct nk_rect header
Definition: nuklear.h:5301
GLint GLsizei count
NK_API void nk_buffer_info(struct nk_memory_status *, struct nk_buffer *)
std::pair< int, int > pixel
Definition: rs-measure.cpp:18
NK_API const char * nk_str_at_const(const struct nk_str *, int pos, nk_rune *unicode, int *len)
struct nk_color symbol_normal
Definition: nuklear.h:5028
struct nk_vec2 delta
Definition: nuklear.h:4534
#define NK_COLOR_STACK_SIZE
Definition: nuklear.h:5407
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4999
float row_padding
Definition: nuklear.h:4968
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)
struct nk_style_item normal
Definition: nuklear.h:4776
enum nk_panel_row_layout_type type
Definition: nuklear.h:5219
NK_API void nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color)
#define NK_BETWEEN(x, a, b)
Definition: nuklear.h:5543
NK_API struct nk_rect nk_window_get_bounds(const struct nk_context *ctx)
NK_API void nk_clear(struct nk_context *)
struct nk_color cursor_border_color
Definition: nuklear.h:4889
float w
Definition: nuklear.h:459
NK_API void nk_menu_end(struct nk_context *)
#define NK_CONTAINER_OF(ptr, type, member)
Definition: nuklear.h:5584
NK_API void nk_colorf_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_colorf in)
GLuint GLfloat GLfloat y0
Definition: glext.h:9721
struct nk_style_item hover
Definition: nuklear.h:4807
NK_API int nk_selectable_image_text(struct nk_context *, struct nk_image, const char *, int, nk_flags align, int *value)
struct nk_style_button minimize_button
Definition: nuklear.h:5080
struct nk_style_item cursor_normal
Definition: nuklear.h:4912
NK_API nk_flags nk_chart_push(struct nk_context *, float)
NK_API unsigned nk_check_flags_label(struct nk_context *, const char *, unsigned int flags, unsigned int value)
NK_API int nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags)
NK_API float nk_propertyf(struct nk_context *, const char *name, float min, float val, float max, float step, float inc_per_pixel)
NK_API int nk_input_is_key_released(const struct nk_input *, enum nk_keys)
struct nk_color cursor_hover
Definition: nuklear.h:4947
struct nk_style_item hover
Definition: nuklear.h:4881
void(* draw_begin)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4900
enum nk_command_type type
Definition: nuklear.h:4324
float rounding
Definition: nuklear.h:5040
struct nk_style_button inc_button
Definition: nuklear.h:4926
struct nk_color text_active
Definition: nuklear.h:4954
NK_API struct nk_rect nk_widget_bounds(struct nk_context *)
GLuint GLuint64EXT address
Definition: glext.h:11417
float border
Definition: nuklear.h:5061
GLbyte by
Definition: glext.h:6704
NK_API void nk_window_show_if(struct nk_context *, const char *name, enum nk_show_states, int cond)
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_color_format
Definition: nuklear.h:475
float combo_border
Definition: nuklear.h:5112
struct nk_color cursor_normal
Definition: nuklear.h:4946
nk_hash keys[NK_VALUE_PAGE_CAPACITY]
Definition: nuklear.h:5457
NK_API struct nk_color nk_hsv_iv(const int *hsv)
NK_API int nk_menu_begin_image(struct nk_context *, const char *, struct nk_image, struct nk_vec2 size)
struct nk_color popup_border_color
Definition: nuklear.h:5103
NK_API int nk_menu_begin_image_label(struct nk_context *, const char *, nk_flags align, struct nk_image, struct nk_vec2 size)
NK_API int nk_str_insert_at_char(struct nk_str *, int pos, const char *, int)
float rs2_vector::* pos
NK_API int nk_selectable_text(struct nk_context *, const char *, int, nk_flags align, int *value)
NK_UINT16 nk_ushort
Definition: nuklear.h:400
GLuint segments
Definition: glext.h:9587
unsigned int old
Definition: nuklear.h:5326
NK_API void nk_window_set_bounds(struct nk_context *, const char *name, struct nk_rect bounds)
nk_size size
Definition: nuklear.h:4061
enum nk_panel_type type
Definition: nuklear.h:5248
NK_API int nk_input_is_mouse_down(const struct nk_input *, enum nk_buttons)
NK_API nk_size nk_prog(struct nk_context *, nk_size cur, nk_size max, int modifyable)
NK_API int nk_filter_float(const struct nk_text_edit *, nk_rune unicode)
struct nk_vec2i begin
Definition: nuklear.h:4348
nk_handle callback_data
Definition: nuklear.h:4467
NK_API void nk_input_end(struct nk_context *)
NK_API int nk_button_pop_behavior(struct nk_context *)
float h
Definition: nuklear.h:459
struct nk_color selected_normal
Definition: nuklear.h:4957
NK_API void nk_layout_row(struct nk_context *, enum nk_layout_format, float height, int cols, const float *ratio)
NK_API void nk_layout_row_template_end(struct nk_context *)
struct nk_style_button dec_button
Definition: nuklear.h:4927
float rounding
Definition: nuklear.h:5120
NK_API struct nk_color nk_hsva_f(float h, float s, float v, float a)
GLsizei range
struct nk_style_edit edit
Definition: nuklear.h:4992
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)
struct nk_style_toggle option
Definition: nuklear.h:5145
struct nk_panel pan
Definition: nuklear.h:5464
NK_API int nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score)
struct nk_buffer_marker marker[NK_BUFFER_MAX]
Definition: nuklear.h:4045
NK_API int nk_combo_begin_image_text(struct nk_context *, const char *selected, int, struct nk_image, struct nk_vec2 size)
char string[1]
Definition: nuklear.h:4480
nk_plugin_copy copy
Definition: nuklear.h:4176
struct nk_vec2 size offset
Definition: nuklear.h:464
struct nk_style_item normal
Definition: nuklear.h:4880
NK_API int nk_selectable_image_label(struct nk_context *, struct nk_image, const char *, nk_flags align, int *value)
struct nk_style_button node_minimize_button
Definition: nuklear.h:5056
nk_handle userdata
Definition: nuklear.h:4769
unsigned short line_thickness
Definition: nuklear.h:4417
NK_API int nk_check_text(struct nk_context *, const char *, int, int active)
GLuint texture
struct nk_text_edit text_edit
Definition: nuklear.h:5515
NK_API int nk_style_push_style_item(struct nk_context *, struct nk_style_item *, struct nk_style_item)
int i
NK_API void nk_textedit_delete(struct nk_text_edit *, int where, int len)
int slot
Definition: nuklear.h:5201
GLdouble u1
GLenum GLuint GLenum GLsizei length
NK_API nk_hash nk_murmur_hash(const void *key, int len, nk_hash seed)
struct nk_style_item active
Definition: nuklear.h:4778
char name_string[NK_WINDOW_MAX_NAME]
Definition: nuklear.h:5333
GLuint res
Definition: glext.h:8856
struct nk_page_element * prev
Definition: nuklear.h:5471
short x
Definition: nuklear.h:460
enum nk_anti_aliasing shape_AA
Definition: nuklear.h:1149
struct nk_rect clip
Definition: nuklear.h:4490
struct nk_panel * layout
Definition: nuklear.h:5339
std::array< float, 3 > color
Definition: model-views.h:449
GLfloat cursor_x
Definition: boing.c:97
NK_API int nk_group_scrolled_begin(struct nk_context *, struct nk_scroll *off, const char *title, nk_flags)
NK_API void nk_style_set_font(struct nk_context *, const struct nk_user_font *)
struct nk_color left
Definition: nuklear.h:4375
struct nk_str string
Definition: nuklear.h:4208
nk_handle userdata
Definition: nuklear.h:4997
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition: glext.h:9721
short redo_char_point
Definition: nuklear.h:4192
struct nk_clipboard clip
Definition: nuklear.h:5496
NK_API void nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color)
struct nk_vec2 content_padding
Definition: nuklear.h:5041
GLushort pattern
unsigned short line_thickness
Definition: nuklear.h:4357
enum nk_style_item_type type
Definition: nuklear.h:4738
list X
Definition: rmse.py:131
NK_API void nk_label_colored(struct nk_context *, const char *, nk_flags align, struct nk_color)
struct nk_style_item active
Definition: nuklear.h:5076
struct nk_color text_normal
Definition: nuklear.h:4786
struct nk_color label_hover
Definition: nuklear.h:5024
NK_API int nk_check_label(struct nk_context *, const char *, int active)
nk_layout_format
Definition: nuklear.h:477
struct nk_color bar_filled
Definition: nuklear.h:4850
NK_API struct nk_color nk_rgba_cf(struct nk_colorf c)
GLuint64 GLenum GLint fd
Definition: glext.h:7768
short y
Definition: nuklear.h:458
NK_API void nk_end(struct nk_context *ctx)
root
Definition: repo.py:7
NK_API int nk_menu_begin_symbol(struct nk_context *, const char *, enum nk_symbol_type, struct nk_vec2 size)
NK_API int nk_strfilter(const char *text, const char *regexp)
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_text_width_f width
Definition: nuklear.h:3845
char buffer[NK_MAX_NUMBER_BUFFER]
Definition: nuklear.h:5319
NK_API char * nk_str_get(struct nk_str *)
NK_UINT8 nk_byte
Definition: nuklear.h:398
#define NK_CHART_MAX_SLOT
Definition: nuklear.h:5171
GLuint * ids
unsigned char advance
struct nk_text_undo_record undo_rec[NK_TEXTEDIT_UNDOSTATECOUNT]
Definition: nuklear.h:4187
unsigned short h
Definition: nuklear.h:4359
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4901
NK_API int nk_str_append_str_runes(struct nk_str *, const nk_rune *)
NK_API struct nk_color nk_rgba_fv(const float *rgba)
nk_uint x
Definition: nuklear.h:465
struct nk_style_button tab_maximize_button
Definition: nuklear.h:5053
#define NK_UNUSED(x)
Definition: nuklear.h:5539
int down
Definition: nuklear.h:4542
NK_INT16 nk_short
Definition: nuklear.h:399
NK_API struct nk_vec2 nk_window_get_content_region_size(struct nk_context *)
NK_API struct nk_vec2 nk_window_get_content_region_max(struct nk_context *)
GLboolean * data
NK_API struct nk_rect nk_window_get_content_region(struct nk_context *)
NK_API int nk_select_image_label(struct nk_context *, struct nk_image, const char *, nk_flags align, int value)
float grow_factor
Definition: nuklear.h:4053
struct nk_vec2 uv
Definition: nuklear.h:1144
nk_uint * scroll_pointer
Definition: nuklear.h:2959
NK_API void nk_layout_space_begin(struct nk_context *, enum nk_layout_format, float height, int widget_count)
unsigned int seq
Definition: nuklear.h:5529
nk_text_edit_mode
Definition: nuklear.h:4200
NK_API int nk_group_begin_titled(struct nk_context *, const char *name, const char *title, nk_flags)
struct nk_edit_state edit
Definition: nuklear.h:5345
struct nk_color label_active
Definition: nuklear.h:5025
NK_API void nk_style_from_table(struct nk_context *, const struct nk_color *)
#define NK_UINT8
Definition: nuklear.h:342
struct nk_input input
Definition: nuklear.h:5493
NK_API int nk_button_label(struct nk_context *, const char *title)
#define NK_MAX(a, b)
Definition: nuklear.h:300
const struct nk_user_font * font
Definition: nuklear.h:5135
enum nk_button_behavior button_behavior
Definition: nuklear.h:5498
NK_API int nk_button_text(struct nk_context *, const char *title, int len)
GLint GLint i2
NK_API void nk_menubar_begin(struct nk_context *)
NK_API int nk_style_push_float(struct nk_context *, float *, float)
#define NK_PTR_TO_UINT(x)
Definition: nuklear.h:5569
#define NK_FONT_STACK_SIZE
Definition: nuklear.h:5387
NK_API int nk_combo_item_label(struct nk_context *, const char *, nk_flags alignment)
NK_API int nk_button_image_label(struct nk_context *, struct nk_image img, const char *, nk_flags text_alignment)
NK_API int nk_button_image_text(struct nk_context *, struct nk_image img, const char *, int, nk_flags alignment)
GLuint64EXT * result
Definition: glext.h:10921
NK_API void nk_color_hsv_fv(float *hsv_out, struct nk_color)
NK_API int nk_str_insert_str_char(struct nk_str *, int pos, const char *)
struct nk_vec2i points[1]
Definition: nuklear.h:4450
struct nk_vec2 padding
Definition: nuklear.h:4861
NK_API int nk_menu_begin_label(struct nk_context *, const char *, nk_flags align, struct nk_vec2 size)
unsigned char grabbed
Definition: nuklear.h:4537
NK_API void nk_color_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_color)
unsigned char mode
Definition: nuklear.h:5313
GLdouble v
NK_API int nk_style_pop_flags(struct nk_context *)
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_API struct nk_color nk_rgb_hex(const char *rgb)
struct nk_style_item hover
Definition: nuklear.h:5018
nk_symbol_type
Definition: nuklear.h:491
NK_API struct nk_color nk_rgb_bv(const nk_byte *rgb)
NK_API int nk_str_insert_str_utf8(struct nk_str *, int pos, const char *)
struct nk_allocator pool
Definition: nuklear.h:4047
NK_API struct nk_image nk_subimage_id(int, unsigned short w, unsigned short h, struct nk_rect sub_region)
struct nk_color text_background
Definition: nuklear.h:4789
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)
struct nk_vec2 image_padding
Definition: nuklear.h:4765
NK_API nk_rune nk_str_rune_at(const struct nk_str *, int pos)
struct nk_scroll offset
Definition: nuklear.h:5244
NK_API int nk_style_pop_font(struct nk_context *)
struct nk_style_item hover
Definition: nuklear.h:4777
nk_command_clipping
Definition: nuklear.h:4483
GLdouble y1
unsigned short r
Definition: nuklear.h:4416
int text_len
Definition: nuklear.h:4548
NK_INT32 nk_int
Definition: nuklear.h:401
NK_API int nk_tree_state_push(struct nk_context *, enum nk_tree_type, const char *title, enum nk_collapse_states *state)
float border
Definition: nuklear.h:4963
NK_API void nk_window_set_size(struct nk_context *, const char *name, struct nk_vec2)
NK_API void nk_input_unicode(struct nk_context *, nk_rune)
NK_API void nk_textedit_redo(struct nk_text_edit *)
NK_API void nk_menu_close(struct nk_context *)
NK_API struct nk_vec2 nk_rect_size(struct nk_rect)
struct nk_style_item background
Definition: nuklear.h:5004
Definition: parser.hpp:150
NK_API void nk_str_init(struct nk_str *, const struct nk_allocator *, nk_size size)
NK_API struct nk_image nk_image_id(int)
struct nk_color color
Definition: nuklear.h:4419
NK_API int nk_combo_begin_image(struct nk_context *, struct nk_image img, struct nk_vec2 size)
#define nk_vec2_len_sqr(a)
Definition: nuklear.h:5553
struct nk_style_button inc_button
Definition: nuklear.h:4993
struct nk_style_item active
Definition: nuklear.h:4908
NK_API void nk_color_d(double *r, double *g, double *b, double *a, struct nk_color)
GLint GLsizei width
NK_API void nk_combo_end(struct nk_context *)
NK_API int nk_propertyi(struct nk_context *, const char *name, int min, int val, int max, int step, float inc_per_pixel)
GLdouble GLdouble GLint GLint const GLdouble * points
nk_size calls
Definition: nuklear.h:4059
void(* draw_end)(struct nk_command_buffer *, nk_handle)
Definition: nuklear.h:4836
NK_API void nk_input_char(struct nk_context *, char)
void copy(void *dst, void const *src, size_t size)
Definition: types.cpp:836
NK_API void nk_color_dv(double *rgba_out, struct nk_color)
struct nk_page_element win[1]
Definition: nuklear.h:5477
#define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1)
Definition: nuklear.h:5546
NK_API struct nk_vec2 nk_vec2v(const float *xy)
NK_API int nk_tooltip_begin(struct nk_context *, float width)
NK_API struct nk_rect nk_recti(int x, int y, int w, int h)
NK_API struct nk_panel * nk_window_get_panel(struct nk_context *)
struct nk_vec2 menu_padding
Definition: nuklear.h:5130
GLintptr offset
struct nk_color label_normal
Definition: nuklear.h:4979
static double ypos
Definition: splitview.c:33
nk_size offset
Definition: nuklear.h:4040
nk_show_states
Definition: nuklear.h:472
struct nk_color color
Definition: nuklear.h:4743
struct nk_style_item pressed
Definition: nuklear.h:4808
NK_API int nk_style_pop_color(struct nk_context *)
NK_API struct nk_color nk_rgba_iv(const int *rgba)
unsigned char single_line
Definition: nuklear.h:5314
struct nk_color selected_hover
Definition: nuklear.h:4958
NK_API void nk_chart_end(struct nk_context *)
float a
Definition: nuklear.h:456
struct nk_command_buffer * buffer
Definition: nuklear.h:5262
struct nk_color menu_border_color
Definition: nuklear.h:5106
NK_API int nk_menu_item_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags alignment)
Definition: nuklear.h:467
NK_API int nk_combo_begin_symbol_label(struct nk_context *, const char *selected, enum nk_symbol_type, struct nk_vec2 size)
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
Definition: glext.h:12384
#define NK_ALIGN_PTR_BACK(x, mask)
Definition: nuklear.h:5580
NK_API int nk_style_push_vec2(struct nk_context *, struct nk_vec2 *, struct nk_vec2)
nk_heading
Definition: nuklear.h:467
#define nk_vec2_muls(a, t)
Definition: nuklear.h:5554
nk_style_colors
Definition: nuklear.h:3487
NK_API struct nk_vec2 nk_window_get_content_region_min(struct nk_context *)
NK_API int nk_menu_begin_text(struct nk_context *, const char *title, int title_len, nk_flags align, struct nk_vec2 size)
struct nk_color background
Definition: nuklear.h:4474
struct nk_vec2i end
Definition: nuklear.h:4349
GLdouble GLdouble bottom
nk_handle userdata
Definition: nuklear.h:4492
unsigned short h
Definition: nuklear.h:463
NK_API struct nk_rect nk_rectiv(const int *xywh)
struct nk_color border_color
Definition: nuklear.h:5049
NK_API struct nk_vec2 nk_widget_size(struct nk_context *)
NK_API void nk_layout_row_push(struct nk_context *, float value)
nk_flags text_alignment
Definition: nuklear.h:4790


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:38