nuklear 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  /*
2
- Nuklear - 1.37.0 - public domain
3
- no warrenty implied; use at your own risk.
2
+ Nuklear - 2.00.7 - public domain
3
+ no warranty implied; use at your own risk.
4
4
  authored from 2015-2017 by Micha Mettke
5
5
 
6
6
  ABOUT:
@@ -17,7 +17,7 @@ VALUES:
17
17
  - Graphical user interface toolkit
18
18
  - Single header library
19
19
  - Written in C89 (a.k.a. ANSI C or ISO C90)
20
- - Small codebase (~17kLOC)
20
+ - Small codebase (~18kLOC)
21
21
  - Focus on portability, efficiency and simplicity
22
22
  - No dependencies (not even the standard library if not wanted)
23
23
  - Fully skinnable and customizable
@@ -47,7 +47,7 @@ USAGE:
47
47
  or even worse stack corruptions.
48
48
 
49
49
  FEATURES:
50
- - Absolutely no platform dependend code
50
+ - Absolutely no platform dependent code
51
51
  - Memory management control ranging from/to
52
52
  - Ease of use by allocating everything from standard library
53
53
  - Control every byte of memory inside the library
@@ -128,7 +128,7 @@ OPTIONAL DEFINES:
128
128
  <!> If used needs to be defined for implementation and header <!>
129
129
 
130
130
  NK_BUTTON_TRIGGER_ON_RELEASE
131
- Different platforms require button clicks occuring either on buttons being
131
+ Different platforms require button clicks occurring either on buttons being
132
132
  pressed (up to down) or released (down to up).
133
133
  By default this library will react on buttons being pressed, but if you
134
134
  define this it will only trigger if a button is released.
@@ -516,7 +516,7 @@ enum nk_symbol_type {
516
516
  * To use a context it first has to be initialized which can be achieved by calling
517
517
  * one of either `nk_init_default`, `nk_init_fixed`, `nk_init`, `nk_init_custom`.
518
518
  * Each takes in a font handle and a specific way of handling memory. Memory control
519
- * hereby ranges from standard library to just specifing a fixed sized block of memory
519
+ * hereby ranges from standard library to just specifying a fixed sized block of memory
520
520
  * which nuklear has to manage itself from.
521
521
  *
522
522
  * struct nk_context ctx;
@@ -529,7 +529,7 @@ enum nk_symbol_type {
529
529
  *
530
530
  * Reference
531
531
  * -------------------
532
- * nk_init_default - Initializes context with standard library memory alloction (malloc,free)
532
+ * nk_init_default - Initializes context with standard library memory allocation (malloc,free)
533
533
  * nk_init_fixed - Initializes context from single fixed size memory block
534
534
  * nk_init - Initializes context with memory allocator callbacks for alloc and free
535
535
  * nk_init_custom - Initializes context from two buffers. One for draw commands the other for window/panel/table allocations
@@ -549,10 +549,10 @@ enum nk_symbol_type {
549
549
  NK_API int nk_init_default(struct nk_context*, const struct nk_user_font*);
550
550
  #endif
551
551
  /* nk_init_fixed - Initializes a `nk_context` struct from a single fixed size memory block
552
- * Should be used if you want complete control over nuklears memory management.
552
+ * Should be used if you want complete control over nuklear's memory management.
553
553
  * Especially recommended for system with little memory or systems with virtual memory.
554
554
  * For the later case you can just allocate for example 16MB of virtual memory
555
- * and only the required amount of memory will actually be commited.
555
+ * and only the required amount of memory will actually be committed.
556
556
  * IMPORTANT: make sure the passed memory block is aligned correctly for `nk_draw_commands`
557
557
  * Parameters:
558
558
  * @ctx must point to an either stack or heap allocated `nk_context` struct
@@ -700,37 +700,36 @@ enum nk_buttons {
700
700
  NK_BUTTON_MAX
701
701
  };
702
702
  /* nk_input_begin - Begins the input mirroring process by resetting text, scroll
703
- * mouse previous mouse position and movement as well as key state transistions,
703
+ * mouse previous mouse position and movement as well as key state transitions,
704
704
  * Parameters:
705
705
  * @ctx must point to an previously initialized `nk_context` struct */
706
706
  NK_API void nk_input_begin(struct nk_context*);
707
- /* nk_input_motion - Mirros current mouse position to nuklear
707
+ /* nk_input_motion - Mirrors current mouse position to nuklear
708
708
  * Parameters:
709
709
  * @ctx must point to an previously initialized `nk_context` struct
710
- * @x must constain an integer describing the current mouse cursor x-position
711
- * @y must constain an integer describing the current mouse cursor y-position */
710
+ * @x must contain an integer describing the current mouse cursor x-position
711
+ * @y must contain an integer describing the current mouse cursor y-position */
712
712
  NK_API void nk_input_motion(struct nk_context*, int x, int y);
713
- /* nk_input_key - Mirros state of a specific key to nuklear
713
+ /* nk_input_key - Mirrors state of a specific key to nuklear
714
714
  * Parameters:
715
715
  * @ctx must point to an previously initialized `nk_context` struct
716
716
  * @key must be any value specified in enum `nk_keys` that needs to be mirrored
717
717
  * @down must be 0 for key is up and 1 for key is down */
718
718
  NK_API void nk_input_key(struct nk_context*, enum nk_keys, int down);
719
- /* nk_input_button - Mirros the state of a specific mouse button to nuklear
719
+ /* nk_input_button - Mirrors the state of a specific mouse button to nuklear
720
720
  * Parameters:
721
721
  * @ctx must point to an previously initialized `nk_context` struct
722
722
  * @nk_buttons must be any value specified in enum `nk_buttons` that needs to be mirrored
723
- * @x must constain an integer describing mouse cursor x-position on click up/down
724
- * @y must constain an integer describing mouse cursor y-position on click up/down
723
+ * @x must contain an integer describing mouse cursor x-position on click up/down
724
+ * @y must contain an integer describing mouse cursor y-position on click up/down
725
725
  * @down must be 0 for key is up and 1 for key is down */
726
726
  NK_API void nk_input_button(struct nk_context*, enum nk_buttons, int x, int y, int down);
727
- /* nk_input_char - Copies a single ASCII character into an internal text buffer
728
- * This is basically a helper function to quickly push ASCII characters into
729
- * nuklear. Note that you can only push up to NK_INPUT_MAX bytes into
730
- * struct `nk_input` between `nk_input_begin` and `nk_input_end`.
727
+ /* nk_input_scroll - Copies the last mouse scroll value to nuklear. Is generally
728
+ * a scroll value. So does not have to come from mouse and could also originate
729
+ * from touch for example.
731
730
  * Parameters:
732
731
  * @ctx must point to an previously initialized `nk_context` struct
733
- * @c must be a single ASCII character preferable one that can be printed */
732
+ * @val vector with both X- as well as Y-scroll value */
734
733
  NK_API void nk_input_scroll(struct nk_context*, struct nk_vec2 val);
735
734
  /* nk_input_char - Copies a single ASCII character into an internal text buffer
736
735
  * This is basically a helper function to quickly push ASCII characters into
@@ -746,7 +745,7 @@ NK_API void nk_input_char(struct nk_context*, char);
746
745
  * struct `nk_input` between `nk_input_begin` and `nk_input_end`.
747
746
  * Parameters:
748
747
  * @ctx must point to an previously initialized `nk_context` struct
749
- * @glyph UTF-32 uncode codepoint */
748
+ * @glyph UTF-32 unicode codepoint */
750
749
  NK_API void nk_input_glyph(struct nk_context*, const nk_glyph);
751
750
  /* nk_input_unicode - Converts a unicode rune into UTF-8 and copies the result
752
751
  * into an internal text buffer.
@@ -754,7 +753,7 @@ NK_API void nk_input_glyph(struct nk_context*, const nk_glyph);
754
753
  * struct `nk_input` between `nk_input_begin` and `nk_input_end`.
755
754
  * Parameters:
756
755
  * @ctx must point to an previously initialized `nk_context` struct
757
- * @glyph UTF-32 uncode codepoint */
756
+ * @glyph UTF-32 unicode codepoint */
758
757
  NK_API void nk_input_unicode(struct nk_context*, nk_rune);
759
758
  /* nk_input_end - End the input mirroring process by resetting mouse grabbing
760
759
  * state to ensure the mouse cursor is not grabbed indefinitely.
@@ -872,7 +871,7 @@ NK_API void nk_input_end(struct nk_context*);
872
871
  * nk_free(&ctx);
873
872
  *
874
873
  * The second probably more applicable trick is to only draw if anything changed.
875
- * It is not really useful for applications with continous draw loop but
874
+ * It is not really useful for applications with continuous draw loop but
876
875
  * quite useful for desktop applications. To actually get nuklear to only
877
876
  * draw on changes you first have to define `NK_ZERO_COMMAND_MEMORY` and
878
877
  * allocate a memory buffer that will store each unique drawing output.
@@ -920,7 +919,7 @@ NK_API void nk_input_end(struct nk_context*);
920
919
  * hardware directly. Therefore it is possible to just define
921
920
  * `NK_INCLUDE_VERTEX_BUFFER_OUTPUT` which includes optional vertex output.
922
921
  * To access the vertex output you first have to convert all draw commands into
923
- * vertexes by calling `nk_convert` which takes in your prefered vertex format.
922
+ * vertexes by calling `nk_convert` which takes in your preferred vertex format.
924
923
  * After successfully converting all draw commands just iterate over and execute all
925
924
  * vertex draw commands:
926
925
  *
@@ -959,9 +958,9 @@ NK_API void nk_input_end(struct nk_context*);
959
958
  * -------------------
960
959
  * nk__begin - Returns the first draw command in the context draw command list to be drawn
961
960
  * nk__next - Increments the draw command iterator to the next command inside the context draw command list
962
- * nk_foreach - Iteratates over each draw command inside the context draw command list
961
+ * nk_foreach - Iterates over each draw command inside the context draw command list
963
962
  *
964
- * nk_convert - Converts from the abstract draw commands list into a hardware accessable vertex format
963
+ * nk_convert - Converts from the abstract draw commands list into a hardware accessible vertex format
965
964
  * nk__draw_begin - Returns the first vertex command in the context vertex draw list to be executed
966
965
  * nk__draw_next - Increments the vertex command iterator to the next command inside the context vertex command list
967
966
  * nk__draw_end - Returns the end of the vertex draw list
@@ -989,7 +988,7 @@ struct nk_convert_config {
989
988
  struct nk_draw_null_texture null; /* handle to texture with a white pixel for shape drawing */
990
989
  const struct nk_draw_vertex_layout_element *vertex_layout; /* describes the vertex output format and packing */
991
990
  nk_size vertex_size; /* sizeof one vertex for vertex packing */
992
- nk_size vertex_alignment; /* vertex alignment: Can be optained by NK_ALIGNOF */
991
+ nk_size vertex_alignment; /* vertex alignment: Can be obtained by NK_ALIGNOF */
993
992
  };
994
993
  /* nk__begin - Returns a draw command list iterator to iterate all draw
995
994
  * commands accumulated over one frame.
@@ -1012,14 +1011,14 @@ NK_API const struct nk_command* nk__next(struct nk_context*, const struct nk_com
1012
1011
  #define nk_foreach(c, ctx) for((c) = nk__begin(ctx); (c) != 0; (c) = nk__next(ctx,c))
1013
1012
  #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
1014
1013
  /* nk_convert - converts all internal draw command into vertex draw commands and fills
1015
- * three buffers with vertexes, vertex draw commands and vertex indicies. The vertex format
1016
- * as well as some other configuration values have to be configurated by filling out a
1014
+ * three buffers with vertexes, vertex draw commands and vertex indices. The vertex format
1015
+ * as well as some other configuration values have to be configured by filling out a
1017
1016
  * `nk_convert_config` struct.
1018
1017
  * Parameters:
1019
1018
  * @ctx must point to an previously initialized `nk_context` struct at the end of a frame
1020
1019
  * @cmds must point to a previously initialized buffer to hold converted vertex draw commands
1021
- * @vertices must point to a previously initialized buffer to hold all produced verticies
1022
- * @elements must point to a previously initialized buffer to hold all procudes vertex indicies
1020
+ * @vertices must point to a previously initialized buffer to hold all produced vertices
1021
+ * @elements must point to a previously initialized buffer to hold all produced vertex indices
1023
1022
  * @config must point to a filled out `nk_config` struct to configure the conversion process
1024
1023
  * Returns:
1025
1024
  * returns NK_CONVERT_SUCCESS on success and a enum nk_convert_result error values if not */
@@ -1038,7 +1037,7 @@ NK_API const struct nk_draw_command* nk__draw_begin(const struct nk_context*, co
1038
1037
  * Return values:
1039
1038
  * vertex draw command pointer pointing to the end of the last vertex draw command inside the vertex draw command buffer */
1040
1039
  NK_API const struct nk_draw_command* nk__draw_end(const struct nk_context*, const struct nk_buffer*);
1041
- /* nk__draw_next - Increments the the vertex draw command buffer iterator
1040
+ /* nk__draw_next - Increments the vertex draw command buffer iterator
1042
1041
  * Parameters:
1043
1042
  * @cmd must point to an previously either by `nk__draw_begin` or `nk__draw_next` returned vertex draw command
1044
1043
  * @buf must point to an previously by `nk_convert` filled out vertex draw command buffer
@@ -1070,7 +1069,7 @@ NK_API const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*
1070
1069
  * order. The topmost window thereby is the currently active window.
1071
1070
  *
1072
1071
  * To change window position inside the stack occurs either automatically by
1073
- * user input by being clicked on or programatically by calling `nk_window_focus`.
1072
+ * user input by being clicked on or programmatically by calling `nk_window_focus`.
1074
1073
  * Windows by default are visible unless explicitly being defined with flag
1075
1074
  * `NK_WINDOW_HIDDEN`, the user clicked the close button on windows with flag
1076
1075
  * `NK_WINDOW_CLOSABLE` or if a window was explicitly hidden by calling
@@ -1082,9 +1081,9 @@ NK_API const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*
1082
1081
  * functions to start window declarations and `nk_end` at the end. Furthermore it
1083
1082
  * is recommended to check the return value of `nk_begin_xxx` and only process
1084
1083
  * widgets inside the window if the value is not 0. Either way you have to call
1085
- * `nk_end` at the end of window declarations. Furthmore do not attempt to
1084
+ * `nk_end` at the end of window declarations. Furthermore, do not attempt to
1086
1085
  * nest `nk_begin_xxx` calls which will hopefully result in an assert or if not
1087
- * in a segmation fault.
1086
+ * in a segmentation fault.
1088
1087
  *
1089
1088
  * if (nk_begin_xxx(...) {
1090
1089
  * [... widgets ...]
@@ -1094,7 +1093,7 @@ NK_API const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*
1094
1093
  * In the grand concept window and widget declarations need to occur after input
1095
1094
  * handling and before drawing to screen. Not doing so can result in higher
1096
1095
  * latency or at worst invalid behavior. Furthermore make sure that `nk_clear`
1097
- * is called at the end of the frame. While nuklears default platform backends
1096
+ * is called at the end of the frame. While nuklear's default platform backends
1098
1097
  * already call `nk_clear` for you if you write your own backend not calling
1099
1098
  * `nk_clear` can cause asserts or even worse undefined behavior.
1100
1099
  *
@@ -1135,7 +1134,7 @@ NK_API const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*
1135
1134
  * Reference
1136
1135
  * -------------------
1137
1136
  * nk_begin - starts a new window; needs to be called every frame for every window (unless hidden) or otherwise the window gets removed
1138
- * nk_begin_titled - extended window start with seperated title and identifier to allow multiple windows with same name but not title
1137
+ * nk_begin_titled - extended window start with separated title and identifier to allow multiple windows with same name but not title
1139
1138
  * nk_end - needs to be called at the end of the window building process to process scaling, scrollbars and general cleanup
1140
1139
  *
1141
1140
  * nk_window_find - finds and returns the window with give name
@@ -1144,7 +1143,7 @@ NK_API const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*
1144
1143
  * nk_window_get_size - returns the size with width and height of the currently processed window
1145
1144
  * nk_window_get_width - returns the width of the currently processed window
1146
1145
  * nk_window_get_height - returns the height of the currently processed window
1147
- * nk_window_get_panel - returns the underlying panel which contains all processing state of the currnet window
1146
+ * nk_window_get_panel - returns the underlying panel which contains all processing state of the current window
1148
1147
  * nk_window_get_content_region - returns the position and size of the currently visible and non-clipped space inside the currently processed window
1149
1148
  * nk_window_get_content_region_min - returns the upper rectangle position of the currently visible and non-clipped space inside the currently processed window
1150
1149
  * nk_window_get_content_region_max - returns the upper rectangle position of the currently visible and non-clipped space inside the currently processed window
@@ -1157,7 +1156,7 @@ NK_API const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*
1157
1156
  * nk_window_is_hidden - returns if the currently processed window was hidden
1158
1157
  * nk_window_is_active - same as nk_window_has_focus for some reason
1159
1158
  * nk_window_is_hovered - returns if the currently processed window is currently being hovered by mouse
1160
- * nk_window_is_any_hovered - return if any wndow currently hovered
1159
+ * nk_window_is_any_hovered - return if any window currently hovered
1161
1160
  * nk_item_is_any_active - returns if any window or widgets is currently hovered or active
1162
1161
  *
1163
1162
  * nk_window_set_bounds - updates position and size of the currently processed window
@@ -1187,16 +1186,16 @@ enum nk_panel_flags {
1187
1186
  /* nk_begin - starts a new window; needs to be called every frame for every window (unless hidden) or otherwise the window gets removed
1188
1187
  * Parameters:
1189
1188
  * @ctx must point to an previously initialized `nk_context` struct
1190
- * @title window title and identifier. Needs to be persitent over frames to identify the window
1189
+ * @title window title and identifier. Needs to be persistent over frames to identify the window
1191
1190
  * @bounds initial position and window size. However if you do not define `NK_WINDOW_SCALABLE` or `NK_WINDOW_MOVABLE` you can set window position and size every frame
1192
1191
  * @flags window flags defined in `enum nk_panel_flags` with a number of different window behaviors
1193
1192
  * Return values:
1194
1193
  * returns 1 if the window can be filled up with widgets from this point until `nk_end or 0 otherwise for example if minimized `*/
1195
1194
  NK_API int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags);
1196
- /* nk_begin_titled - extended window start with seperated title and identifier to allow multiple windows with same name but not title
1195
+ /* nk_begin_titled - extended window start with separated title and identifier to allow multiple windows with same name but not title
1197
1196
  * Parameters:
1198
1197
  * @ctx must point to an previously initialized `nk_context` struct
1199
- * @name window identifier. Needs to be persitent over frames to identify the window
1198
+ * @name window identifier. Needs to be persistent over frames to identify the window
1200
1199
  * @title window title displayed inside header if flag `NK_WINDOW_TITLE` or either `NK_WINDOW_CLOSABLE` or `NK_WINDOW_MINIMIZED` was set
1201
1200
  * @bounds initial position and window size. However if you do not define `NK_WINDOW_SCALABLE` or `NK_WINDOW_MOVABLE` you can set window position and size every frame
1202
1201
  * @flags window flags defined in `enum nk_panel_flags` with a number of different window behaviors
@@ -1213,7 +1212,7 @@ NK_API void nk_end(struct nk_context *ctx);
1213
1212
  * @ctx must point to an previously initialized `nk_context` struct
1214
1213
  * @name window identifier
1215
1214
  * Return values:
1216
- * returns a `nk_window` struct pointing to the idified window or 0 if no window with given name was found */
1215
+ * returns a `nk_window` struct pointing to the identified window or 0 if no window with given name was found */
1217
1216
  NK_API struct nk_window *nk_window_find(struct nk_context *ctx, const char *name);
1218
1217
  /* nk_window_get_bounds - returns a rectangle with screen position and size of the currently processed window.
1219
1218
  * IMPORTANT: only call this function between calls `nk_begin_xxx` and `nk_end`
@@ -1250,7 +1249,7 @@ NK_API float nk_window_get_width(const struct nk_context*);
1250
1249
  * Return values:
1251
1250
  * returns the window height */
1252
1251
  NK_API float nk_window_get_height(const struct nk_context*);
1253
- /* nk_window_get_panel - returns the underlying panel which contains all processing state of the currnet window.
1252
+ /* nk_window_get_panel - returns the underlying panel which contains all processing state of the current window.
1254
1253
  * IMPORTANT: only call this function between calls `nk_begin_xxx` and `nk_end`
1255
1254
  * Parameters:
1256
1255
  * @ctx must point to an previously initialized `nk_context` struct
@@ -1352,20 +1351,23 @@ NK_API int nk_item_is_any_active(struct nk_context*);
1352
1351
  * IMPORTANT: only call this function between calls `nk_begin_xxx` and `nk_end`
1353
1352
  * Parameters:
1354
1353
  * @ctx must point to an previously initialized `nk_context` struct
1354
+ * @name of the window to modify both position and size
1355
1355
  * @bounds points to a `nk_rect` struct with the new position and size of currently active window */
1356
- NK_API void nk_window_set_bounds(struct nk_context*, struct nk_rect bounds);
1356
+ NK_API void nk_window_set_bounds(struct nk_context*, const char *name, struct nk_rect bounds);
1357
1357
  /* nk_window_set_position - updates position of the currently processed window
1358
1358
  * IMPORTANT: only call this function between calls `nk_begin_xxx` and `nk_end`
1359
1359
  * Parameters:
1360
1360
  * @ctx must point to an previously initialized `nk_context` struct
1361
+ * @name of the window to modify position of
1361
1362
  * @pos points to a `nk_vec2` struct with the new position of currently active window */
1362
- NK_API void nk_window_set_position(struct nk_context*, struct nk_vec2 pos);
1363
+ NK_API void nk_window_set_position(struct nk_context*, const char *name, struct nk_vec2 pos);
1363
1364
  /* nk_window_set_size - updates size of the currently processed window
1364
1365
  * IMPORTANT: only call this function between calls `nk_begin_xxx` and `nk_end`
1365
1366
  * Parameters:
1366
1367
  * @ctx must point to an previously initialized `nk_context` struct
1367
- * @bounds points to a `nk_vec2` struct with the new size of currently active window */
1368
- NK_API void nk_window_set_size(struct nk_context*, struct nk_vec2);
1368
+ * @name of the window to modify size of
1369
+ * @size points to a `nk_vec2` struct with the new size of currently active window */
1370
+ NK_API void nk_window_set_size(struct nk_context*, const char *name, struct nk_vec2);
1369
1371
  /* nk_window_set_focus - sets the window with given name as active
1370
1372
  * Parameters:
1371
1373
  * @ctx must point to an previously initialized `nk_context` struct
@@ -1386,7 +1388,7 @@ NK_API void nk_window_collapse(struct nk_context*, const char *name, enum nk_col
1386
1388
  * @ctx must point to an previously initialized `nk_context` struct
1387
1389
  * @name of the window to be either collapse or maximize
1388
1390
  * @state the window should be put into
1389
- * @condition that has to be true to actually commit the collsage state change */
1391
+ * @condition that has to be true to actually commit the collapse state change */
1390
1392
  NK_API void nk_window_collapse_if(struct nk_context*, const char *name, enum nk_collapse_states, int cond);
1391
1393
  /* nk_window_show - updates visibility state of a window with given name
1392
1394
  * Parameters:
@@ -1410,30 +1412,39 @@ NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show
1410
1412
  * While in this particular implementation there are five different APIs for layouting
1411
1413
  * each with different trade offs between control and ease of use.
1412
1414
  *
1413
- * All layouting methodes in this library are based around the concept of a row.
1415
+ * All layouting methods in this library are based around the concept of a row.
1414
1416
  * A row has a height the window content grows by and a number of columns and each
1415
1417
  * layouting method specifies how each widget is placed inside the row.
1416
1418
  * After a row has been allocated by calling a layouting functions and then
1417
1419
  * filled with widgets will advance an internal pointer over the allocated row.
1418
1420
  *
1419
- * To acually define a layout you just call the appropriate layouting function
1420
- * and each subsequnetial widget call will place the widget as specified. Important
1421
+ * To actually define a layout you just call the appropriate layouting function
1422
+ * and each subsequent widget call will place the widget as specified. Important
1421
1423
  * here is that if you define more widgets then columns defined inside the layout
1422
1424
  * functions it will allocate the next row without you having to make another layouting
1423
1425
  * call.
1424
1426
  *
1425
1427
  * Biggest limitation with using all these APIs outside the `nk_layout_space_xxx` API
1426
1428
  * is that you have to define the row height for each. However the row height
1427
- * often depends on the height of the font. So I would recommend writing
1428
- * a higher level layouting functions that just calls each function with default font height
1429
- * plus some spacing between rows. The reason why this library does't support this
1430
- * behavior by default is to grant more control.
1429
+ * often depends on the height of the font.
1430
+ *
1431
+ * To fix that internally nuklear uses a minimum row height that is set to the
1432
+ * height plus padding of currently active font and overwrites the row height
1433
+ * value if zero.
1434
+ *
1435
+ * If you manually want to change the minimum row height then
1436
+ * use nk_layout_set_min_row_height, and use nk_layout_reset_min_row_height to
1437
+ * reset it back to be derived from font height.
1438
+ *
1439
+ * Also if you change the font in nuklear it will automatically change the minimum
1440
+ * row height for you and. This means if you change the font but still want
1441
+ * a minimum row height smaller than the font you have to repush your value.
1431
1442
  *
1432
1443
  * For actually more advanced UI I would even recommend using the `nk_layout_space_xxx`
1433
1444
  * layouting method in combination with a cassowary constraint solver (there are
1434
1445
  * some versions on github with permissive license model) to take over all control over widget
1435
1446
  * layouting yourself. However for quick and dirty layouting using all the other layouting
1436
- * functions, especially if you don't change the font height, should be fine.
1447
+ * functions should be fine.
1437
1448
  *
1438
1449
  * Usage
1439
1450
  * -------------------
@@ -1458,6 +1469,11 @@ NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show
1458
1469
  * // second row with same parameter as defined above
1459
1470
  * nk_widget(...);
1460
1471
  * nk_widget(...);
1472
+ *
1473
+ * // third row uses 0 for height which will use auto layouting
1474
+ * nk_layout_row_dynamic(&ctx, 0, 2);
1475
+ * nk_widget(...);
1476
+ * nk_widget(...);
1461
1477
  * }
1462
1478
  * nk_end(...);
1463
1479
  *
@@ -1475,13 +1491,18 @@ NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show
1475
1491
  * // second row with same parameter as defined above
1476
1492
  * nk_widget(...);
1477
1493
  * nk_widget(...);
1494
+ *
1495
+ * // third row uses 0 for height which will use auto layouting
1496
+ * nk_layout_row_static(&ctx, 0, 80, 2);
1497
+ * nk_widget(...);
1498
+ * nk_widget(...);
1478
1499
  * }
1479
1500
  * nk_end(...);
1480
1501
  *
1481
1502
  * 3.) nk_layout_row_xxx
1482
1503
  * A little bit more advanced layouting API are functions `nk_layout_row_begin`,
1483
1504
  * `nk_layout_row_push` and `nk_layout_row_end`. They allow to directly
1484
- * specify each column pixel or window ratio in a row. It support either
1505
+ * specify each column pixel or window ratio in a row. It supports either
1485
1506
  * directly setting per column pixel width or widget window ratio but not
1486
1507
  * both. Furthermore it is a immediate mode API so each value is directly
1487
1508
  * pushed before calling a widget. Therefore the layout is not automatically
@@ -1503,11 +1524,19 @@ NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show
1503
1524
  * nk_layout_row_push(ctx, 0.75f);
1504
1525
  * nk_widget(...);
1505
1526
  * nk_layout_row_end(ctx);
1527
+ *
1528
+ * // third row with auto generated height: composed of two widgets with window ratio 0.25 and 0.75
1529
+ * nk_layout_row_begin(ctx, NK_DYNAMIC, 0, 2);
1530
+ * nk_layout_row_push(ctx, 0.25f);
1531
+ * nk_widget(...);
1532
+ * nk_layout_row_push(ctx, 0.75f);
1533
+ * nk_widget(...);
1534
+ * nk_layout_row_end(ctx);
1506
1535
  * }
1507
1536
  * nk_end(...);
1508
1537
  *
1509
1538
  * 4.) nk_layout_row
1510
- * The retain mode counterpart to API nk_layout_row_xxx is the single nk_layout_row
1539
+ * The array counterpart to API nk_layout_row_xxx is the single nk_layout_row
1511
1540
  * functions. Instead of pushing either pixel or window ratio for every widget
1512
1541
  * it allows to define it by array. The trade of for less control is that
1513
1542
  * `nk_layout_row` is automatically repeating. Otherwise the behavior is the
@@ -1529,6 +1558,14 @@ NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show
1529
1558
  * nk_widget(...);
1530
1559
  * nk_widget(...);
1531
1560
  * nk_widget(...);
1561
+ *
1562
+ * // two rows with auto generated height composed of two widgets with window ratio 0.25 and 0.75
1563
+ * const float ratio[] = {0.25, 0.75};
1564
+ * nk_layout_row(ctx, NK_DYNAMIC, 30, 2, ratio);
1565
+ * nk_widget(...);
1566
+ * nk_widget(...);
1567
+ * nk_widget(...);
1568
+ * nk_widget(...);
1532
1569
  * }
1533
1570
  * nk_end(...);
1534
1571
  *
@@ -1541,8 +1578,8 @@ NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show
1541
1578
  * one is the static widget size specifier with fixed widget pixel width. They do
1542
1579
  * not grow if the row grows and will always stay the same. The second size
1543
1580
  * specifier is nk_layout_row_template_push_variable which defines a
1544
- * minumum widget size but it also can grow if more space is available not taken
1545
- * by other widgets. Finally there are dynamic widgets which are completly flexible
1581
+ * minimum widget size but it also can grow if more space is available not taken
1582
+ * by other widgets. Finally there are dynamic widgets which are completely flexible
1546
1583
  * and unlike variable widgets can even shrink to zero if not enough space
1547
1584
  * is provided.
1548
1585
  *
@@ -1554,9 +1591,14 @@ NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show
1554
1591
  * nk_layout_row_template_push_static(ctx, 80);
1555
1592
  * nk_layout_row_template_end(ctx);
1556
1593
  *
1557
- * nk_widget(...); // dynamic widget completly can go to zero
1594
+ * nk_widget(...); // dynamic widget can go to zero if not enough space
1558
1595
  * nk_widget(...); // variable widget with min 80 pixel but can grow bigger if enough space
1559
1596
  * nk_widget(...); // static widget with fixed 80 pixel width
1597
+ *
1598
+ * // second row same layout
1599
+ * nk_widget(...);
1600
+ * nk_widget(...);
1601
+ * nk_widget(...);
1560
1602
  * }
1561
1603
  * nk_end(...);
1562
1604
  *
@@ -1564,9 +1606,9 @@ NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show
1564
1606
  * Finally the most flexible API directly allows you to place widgets inside the
1565
1607
  * window. The space layout API is an immediate mode API which does not support
1566
1608
  * row auto repeat and directly sets position and size of a widget. Position
1567
- * and size hereby can be either specified as ratio of alloated space or
1609
+ * and size hereby can be either specified as ratio of allocated space or
1568
1610
  * allocated space local position and pixel size. Since this API is quite
1569
- * powerfull there are a number of utility functions to get the available space
1611
+ * powerful there are a number of utility functions to get the available space
1570
1612
  * and convert between local allocated space and screen space.
1571
1613
  *
1572
1614
  * if (nk_begin_xxx(...) {
@@ -1589,36 +1631,62 @@ NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show
1589
1631
  *
1590
1632
  * Reference
1591
1633
  * -------------------
1592
- * nk_layout_row_dynamic - current layout is divided into n same sized gowing columns
1593
- * nk_layout_row_static - current layout is divided into n same fixed sized columns
1594
- * nk_layout_row_begin - starts a new row with given height and number of columns
1595
- * nk_layout_row_push - pushes another column with given size or window ratio
1596
- * nk_layout_row_end - finished previously started row
1597
- * nk_layout_row - specifies row columns in array as either window ratio or size
1598
- *
1599
- * nk_layout_row_template_begin
1600
- * nk_layout_row_template_push_dynamic
1601
- * nk_layout_row_template_push_variable
1602
- * nk_layout_row_template_push_static
1603
- * nk_layout_row_template_end
1604
- *
1605
- * nk_layout_space_begin
1606
- * nk_layout_space_push
1607
- * nk_layout_space_end
1608
- *
1609
- * nk_layout_space_bounds
1610
- * nk_layout_space_to_screen
1611
- * nk_layout_space_to_local
1612
- * nk_layout_space_rect_to_screen
1613
- * nk_layout_space_rect_to_local
1614
- * nk_layout_ratio_from_pixel
1634
+ * nk_layout_set_min_row_height - set the currently used minimum row height to a specified value
1635
+ * nk_layout_reset_min_row_height - resets the currently used minimum row height to font height
1636
+ *
1637
+ * nk_layout_widget_bounds - calculates current width a static layout row can fit inside a window
1638
+ * nk_layout_ratio_from_pixel - utility functions to calculate window ratio from pixel size
1639
+ *
1640
+ * nk_layout_row_dynamic - current layout is divided into n same sized growing columns
1641
+ * nk_layout_row_static - current layout is divided into n same fixed sized columns
1642
+ * nk_layout_row_begin - starts a new row with given height and number of columns
1643
+ * nk_layout_row_push - pushes another column with given size or window ratio
1644
+ * nk_layout_row_end - finished previously started row
1645
+ * nk_layout_row - specifies row columns in array as either window ratio or size
1646
+ *
1647
+ * nk_layout_row_template_begin - begins the row template declaration
1648
+ * nk_layout_row_template_push_dynamic - adds a dynamic column that dynamically grows and can go to zero if not enough space
1649
+ * nk_layout_row_template_push_variable - adds a variable column that dynamically grows but does not shrink below specified pixel width
1650
+ * nk_layout_row_template_push_static - adds a static column that does not grow and will always have the same size
1651
+ * nk_layout_row_template_end - marks the end of the row template
1652
+ *
1653
+ * nk_layout_space_begin - begins a new layouting space that allows to specify each widgets position and size
1654
+ * nk_layout_space_push - pushes position and size of the next widget in own coordinate space either as pixel or ratio
1655
+ * nk_layout_space_end - marks the end of the layouting space
1656
+ *
1657
+ * nk_layout_space_bounds - callable after nk_layout_space_begin and returns total space allocated
1658
+ * nk_layout_space_to_screen - converts vector from nk_layout_space coordinate space into screen space
1659
+ * nk_layout_space_to_local - converts vector from screen space into nk_layout_space coordinates
1660
+ * nk_layout_space_rect_to_screen - converts rectangle from nk_layout_space coordinate space into screen space
1661
+ * nk_layout_space_rect_to_local - converts rectangle from screen space into nk_layout_space coordinates
1615
1662
  */
1663
+ /* nk_layout_set_min_row_height - sets the currently used minimum row height.
1664
+ * IMPORTANT: The passed height needs to include both your preferred row height
1665
+ * as well as padding. No internal padding is added.
1666
+ * Parameters:
1667
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
1668
+ * @height new minimum row height to be used for auto generating the row height */
1669
+ NK_API void nk_layout_set_min_row_height(struct nk_context*, float height);
1670
+ /* nk_layout_reset_min_row_height - Reset the currently used minimum row height
1671
+ * back to font height + text padding + additional padding (style_window.min_row_height_padding)
1672
+ * Parameters:
1673
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` */
1674
+ NK_API void nk_layout_reset_min_row_height(struct nk_context*);
1675
+ /* nk_layout_widget_bounds - returns the width of the next row allocate by one of the layouting functions
1676
+ * Parameters:
1677
+ * @ctx must point to an previously initialized `nk_context` */
1678
+ NK_API struct nk_rect nk_layout_widget_bounds(struct nk_context*);
1679
+ /* nk_layout_ratio_from_pixel - utility functions to calculate window ratio from pixel size
1680
+ * Parameters:
1681
+ * @ctx must point to an previously initialized `nk_context`
1682
+ * @pixel_width to convert to window ratio */
1683
+ NK_API float nk_layout_ratio_from_pixel(struct nk_context*, float pixel_width);
1616
1684
  /* nk_layout_row_dynamic - Sets current row layout to share horizontal space
1617
1685
  * between @cols number of widgets evenly. Once called all subsequent widget
1618
1686
  * calls greater than @cols will allocate a new row with same layout.
1619
1687
  * Parameters:
1620
1688
  * @ctx must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
1621
- * @height holds row height to allocate from panel for widget height
1689
+ * @row_height holds height of each widget in row or zero for auto layouting
1622
1690
  * @cols number of widget inside row */
1623
1691
  NK_API void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols);
1624
1692
  /* nk_layout_row_static - Sets current row layout to fill @cols number of widgets
@@ -1634,7 +1702,7 @@ NK_API void nk_layout_row_static(struct nk_context *ctx, float height, int item_
1634
1702
  * Parameters:
1635
1703
  * @ctx must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
1636
1704
  * @fmt either `NK_DYNAMIC` for window ratio or `NK_STATIC` for fixed size columns
1637
- * @row_height holds width of each widget in row
1705
+ * @row_height holds height of each widget in row or zero for auto layouting
1638
1706
  * @cols number of widget inside row */
1639
1707
  NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols);
1640
1708
  /* nk_layout_row_push - Specifies either window ratio or width of a single column
@@ -1642,26 +1710,80 @@ NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fm
1642
1710
  * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_row_begin`
1643
1711
  * @value either a window ratio or fixed width depending on @fmt in previous `nk_layout_row_begin` call */
1644
1712
  NK_API void nk_layout_row_push(struct nk_context*, float value);
1713
+ /* nk_layout_row_end - finished previously started row
1714
+ * Parameters:
1715
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_row_begin` */
1645
1716
  NK_API void nk_layout_row_end(struct nk_context*);
1717
+ /* nk_layout_row - specifies row columns in array as either window ratio or size
1718
+ * Parameters:
1719
+ * @ctx must point to an previously initialized `nk_context`
1720
+ * @fmt either `NK_DYNAMIC` for window ratio or `NK_STATIC` for fixed size columns
1721
+ * @row_height holds height of each widget in row or zero for auto layouting
1722
+ * @cols number of widget inside row */
1646
1723
  NK_API void nk_layout_row(struct nk_context*, enum nk_layout_format, float height, int cols, const float *ratio);
1647
-
1648
- NK_API void nk_layout_row_template_begin(struct nk_context*, float height);
1724
+ /* nk_layout_row_template_begin - Begins the row template declaration
1725
+ * Parameters:
1726
+ * @ctx must point to an previously initialized `nk_context` struct
1727
+ * @row_height holds height of each widget in row or zero for auto layouting */
1728
+ NK_API void nk_layout_row_template_begin(struct nk_context*, float row_height);
1729
+ /* nk_layout_row_template_push_dynamic - adds a dynamic column that dynamically grows and can go to zero if not enough space
1730
+ * Parameters:
1731
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_row_template_begin` */
1649
1732
  NK_API void nk_layout_row_template_push_dynamic(struct nk_context*);
1733
+ /* nk_layout_row_template_push_variable - adds a variable column that dynamically grows but does not shrink below specified pixel width
1734
+ * Parameters:
1735
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_row_template_begin`
1736
+ * @min_width holds the minimum pixel width the next column must be */
1650
1737
  NK_API void nk_layout_row_template_push_variable(struct nk_context*, float min_width);
1738
+ /* nk_layout_row_template_push_static - adds a static column that does not grow and will always have the same size
1739
+ * Parameters:
1740
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_row_template_begin`
1741
+ * @width holds the absolute pixel width value the next column must be */
1651
1742
  NK_API void nk_layout_row_template_push_static(struct nk_context*, float width);
1743
+ /* nk_layout_row_template_end - marks the end of the row template
1744
+ * Parameters:
1745
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_row_template_begin` */
1652
1746
  NK_API void nk_layout_row_template_end(struct nk_context*);
1653
-
1747
+ /* nk_layout_space_begin - begins a new layouting space that allows to specify each widgets position and size.
1748
+ * Parameters:
1749
+ * @ctx must point to an previously initialized `nk_context` struct
1750
+ * @fmt either `NK_DYNAMIC` for window ratio or `NK_STATIC` for fixed size columns
1751
+ * @row_height holds height of each widget in row or zero for auto layouting
1752
+ * @widget_count number of widgets inside row */
1654
1753
  NK_API void nk_layout_space_begin(struct nk_context*, enum nk_layout_format, float height, int widget_count);
1754
+ /* nk_layout_space_push - pushes position and size of the next widget in own coordinate space either as pixel or ratio
1755
+ * Parameters:
1756
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
1757
+ * @bounds position and size in laoyut space local coordinates */
1655
1758
  NK_API void nk_layout_space_push(struct nk_context*, struct nk_rect);
1759
+ /* nk_layout_space_end - marks the end of the layout space
1760
+ * Parameters:
1761
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin` */
1656
1762
  NK_API void nk_layout_space_end(struct nk_context*);
1657
-
1658
- NK_API struct nk_rect nk_layout_widget_bounds(struct nk_context*);
1763
+ /* nk_layout_space_bounds - returns total space allocated for `nk_layout_space`
1764
+ * Parameters:
1765
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin` */
1659
1766
  NK_API struct nk_rect nk_layout_space_bounds(struct nk_context*);
1767
+ /* nk_layout_space_to_screen - converts vector from nk_layout_space coordinate space into screen space
1768
+ * Parameters:
1769
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
1770
+ * @vec position to convert from layout space into screen coordinate space */
1660
1771
  NK_API struct nk_vec2 nk_layout_space_to_screen(struct nk_context*, struct nk_vec2);
1772
+ /* nk_layout_space_to_screen - converts vector from layout space into screen space
1773
+ * Parameters:
1774
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
1775
+ * @vec position to convert from screen space into layout coordinate space */
1661
1776
  NK_API struct nk_vec2 nk_layout_space_to_local(struct nk_context*, struct nk_vec2);
1777
+ /* nk_layout_space_rect_to_screen - converts rectangle from screen space into layout space
1778
+ * Parameters:
1779
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
1780
+ * @bounds rectangle to convert from layout space into screen space */
1662
1781
  NK_API struct nk_rect nk_layout_space_rect_to_screen(struct nk_context*, struct nk_rect);
1782
+ /* nk_layout_space_rect_to_local - converts rectangle from layout space into screen space
1783
+ * Parameters:
1784
+ * @ctx must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
1785
+ * @bounds rectangle to convert from screen space into layout space */
1663
1786
  NK_API struct nk_rect nk_layout_space_rect_to_local(struct nk_context*, struct nk_rect);
1664
- NK_API float nk_layout_ratio_from_pixel(struct nk_context*, float pixel_width);
1665
1787
  /* =============================================================================
1666
1788
  *
1667
1789
  * GROUP
@@ -1984,6 +2106,9 @@ NK_API void nk_contextual_end(struct nk_context*);
1984
2106
  *
1985
2107
  * ============================================================================= */
1986
2108
  NK_API void nk_tooltip(struct nk_context*, const char*);
2109
+ #ifdef NK_INCLUDE_STANDARD_VARARGS
2110
+ NK_API void nk_tooltipf(struct nk_context*, const char*, ...);
2111
+ #endif
1987
2112
  NK_API int nk_tooltip_begin(struct nk_context*, float width);
1988
2113
  NK_API void nk_tooltip_end(struct nk_context*);
1989
2114
  /* =============================================================================
@@ -2201,7 +2326,7 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune
2201
2326
  different ways to use the font atlas. The first two will use your font
2202
2327
  handling scheme and only requires essential data to run nuklear. The next
2203
2328
  slightly more advanced features is font handling with vertex buffer output.
2204
- Finally the most complex API wise is using nuklears font baking API.
2329
+ Finally the most complex API wise is using nuklear's font baking API.
2205
2330
 
2206
2331
  1.) Using your own implementation without vertex buffer output
2207
2332
  --------------------------------------------------------------
@@ -2274,7 +2399,7 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune
2274
2399
  ------------------------------------
2275
2400
  The final approach if you do not have a font handling functionality or don't
2276
2401
  want to use it in this library is by using the optional font baker.
2277
- The font baker API's can be used to create a font plus font atlas texture
2402
+ The font baker APIs can be used to create a font plus font atlas texture
2278
2403
  and can be used with or without the vertex buffer output.
2279
2404
 
2280
2405
  It still uses the `nk_user_font` struct and the two different approaches
@@ -2289,7 +2414,7 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune
2289
2414
  memory is temporary and therefore can be freed directly after the baking process
2290
2415
  is over or permanent you can call `nk_font_atlas_init`.
2291
2416
 
2292
- After successfull intializing the font baker you can add Truetype(.ttf) fonts from
2417
+ After successfully initializing the font baker you can add Truetype(.ttf) fonts from
2293
2418
  different sources like memory or from file by calling one of the `nk_font_atlas_add_xxx`.
2294
2419
  functions. Adding font will permanently store each font, font config and ttf memory block(!)
2295
2420
  inside the font atlas and allows to reuse the font atlas. If you don't want to reuse
@@ -2297,7 +2422,7 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune
2297
2422
  `nk_font_atlas_cleanup` after the baking process is over (after calling nk_font_atlas_end).
2298
2423
 
2299
2424
  As soon as you added all fonts you wanted you can now start the baking process
2300
- for every selected glyphes to image by calling `nk_font_atlas_bake`.
2425
+ for every selected glyph to image by calling `nk_font_atlas_bake`.
2301
2426
  The baking process returns image memory, width and height which can be used to
2302
2427
  either create your own image object or upload it to any graphics library.
2303
2428
  No matter which case you finally have to call `nk_font_atlas_end` which
@@ -2331,7 +2456,7 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune
2331
2456
  I would suggest reading some of my examples `example/` to get a grip on how
2332
2457
  to use the font atlas. There are a number of details I left out. For example
2333
2458
  how to merge fonts, configure a font with `nk_font_config` to use other languages,
2334
- use another texture coodinate format and a lot more:
2459
+ use another texture coordinate format and a lot more:
2335
2460
 
2336
2461
  struct nk_font_config cfg = nk_font_config(font_pixel_height);
2337
2462
  cfg.merge_mode = nk_false or nk_true;
@@ -2346,7 +2471,7 @@ typedef void(*nk_query_font_glyph_f)(nk_handle handle, float font_height,
2346
2471
  struct nk_user_font_glyph *glyph,
2347
2472
  nk_rune codepoint, nk_rune next_codepoint);
2348
2473
 
2349
- #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
2474
+ #if defined(NK_INCLUDE_VERTEX_BUFFER_OUTPUT) || defined(NK_INCLUDE_SOFTWARE_FONT)
2350
2475
  struct nk_user_font_glyph {
2351
2476
  struct nk_vec2 uv[2];
2352
2477
  /* texture coordinates */
@@ -2380,6 +2505,7 @@ enum nk_font_coord_type {
2380
2505
  NK_COORD_PIXEL /* texture coordinates inside font glyphs are in absolute pixel */
2381
2506
  };
2382
2507
 
2508
+ struct nk_font;
2383
2509
  struct nk_baked_font {
2384
2510
  float height;
2385
2511
  /* height of the font */
@@ -2425,6 +2551,8 @@ struct nk_font_config {
2425
2551
  /* font to setup in the baking process: NOTE: not needed for font atlas */
2426
2552
  nk_rune fallback_glyph;
2427
2553
  /* fallback glyph to use if a given rune is not found */
2554
+ struct nk_font_config *n;
2555
+ struct nk_font_config *p;
2428
2556
  };
2429
2557
 
2430
2558
  struct nk_font_glyph {
@@ -2666,7 +2794,7 @@ NK_API int nk_str_len_char(struct nk_str*);
2666
2794
  * First of is the most basic way of just providing a simple char array with
2667
2795
  * string length. This method is probably the easiest way of handling simple
2668
2796
  * user text input. Main upside is complete control over memory while the biggest
2669
- * downside in comparsion with the other two approaches is missing undo/redo.
2797
+ * downside in comparison with the other two approaches is missing undo/redo.
2670
2798
  *
2671
2799
  * For UIs that require undo/redo the second way was created. It is based on
2672
2800
  * a fixed size nk_text_edit struct, which has an internal undo/redo stack.
@@ -2813,8 +2941,8 @@ NK_API void nk_textedit_redo(struct nk_text_edit*);
2813
2941
  but also returns the state of the widget space. If your widget is not seen and does
2814
2942
  not have to be updated it is '0' and you can just return. If it only has
2815
2943
  to be drawn the state will be `NK_WIDGET_ROM` otherwise you can do both
2816
- update and draw your widget. The reason for seperating is to only draw and
2817
- update what is actually neccessary which is crucial for performance.
2944
+ update and draw your widget. The reason for separating is to only draw and
2945
+ update what is actually necessary which is crucial for performance.
2818
2946
  */
2819
2947
  enum nk_command_type {
2820
2948
  NK_COMMAND_NOP,
@@ -3186,6 +3314,9 @@ struct nk_draw_list {
3186
3314
  unsigned int path_count;
3187
3315
  unsigned int path_offset;
3188
3316
 
3317
+ enum nk_anti_aliasing line_AA;
3318
+ enum nk_anti_aliasing shape_AA;
3319
+
3189
3320
  #ifdef NK_INCLUDE_COMMAND_USERDATA
3190
3321
  nk_handle userdata;
3191
3322
  #endif
@@ -3193,7 +3324,7 @@ struct nk_draw_list {
3193
3324
 
3194
3325
  /* draw list */
3195
3326
  NK_API void nk_draw_list_init(struct nk_draw_list*);
3196
- 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);
3327
+ 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);
3197
3328
  NK_API void nk_draw_list_clear(struct nk_draw_list*);
3198
3329
 
3199
3330
  /* drawing */
@@ -3633,6 +3764,7 @@ struct nk_style_window {
3633
3764
  float group_border;
3634
3765
  float tooltip_border;
3635
3766
  float popup_border;
3767
+ float min_row_height_padding;
3636
3768
 
3637
3769
  float rounding;
3638
3770
  struct nk_vec2 spacing;
@@ -3735,6 +3867,7 @@ struct nk_row_layout {
3735
3867
  enum nk_panel_row_layout_type type;
3736
3868
  int index;
3737
3869
  float height;
3870
+ float min_height;
3738
3871
  int columns;
3739
3872
  const float *ratio;
3740
3873
  float item_width;
@@ -3861,8 +3994,7 @@ struct nk_window {
3861
3994
  unsigned int scrolled;
3862
3995
 
3863
3996
  struct nk_table *tables;
3864
- unsigned short table_count;
3865
- unsigned short table_size;
3997
+ unsigned int table_count;
3866
3998
 
3867
3999
  /* window list hooks */
3868
4000
  struct nk_window *next;
@@ -3965,10 +4097,11 @@ struct nk_configuration_stacks {
3965
4097
  * CONTEXT
3966
4098
  * =============================================================*/
3967
4099
  #define NK_VALUE_PAGE_CAPACITY \
3968
- ((NK_MAX(sizeof(struct nk_window),sizeof(struct nk_panel)) / sizeof(nk_uint)) / 2)
4100
+ (((NK_MAX(sizeof(struct nk_window),sizeof(struct nk_panel)) / sizeof(nk_uint))) / 2)
3969
4101
 
3970
4102
  struct nk_table {
3971
4103
  unsigned int seq;
4104
+ unsigned int size;
3972
4105
  nk_hash keys[NK_VALUE_PAGE_CAPACITY];
3973
4106
  nk_uint values[NK_VALUE_PAGE_CAPACITY];
3974
4107
  struct nk_table *next, *prev;
@@ -4109,14 +4242,14 @@ template<typename T, int size_diff> struct nk_helper{enum {value = size_diff};};
4109
4242
  template<typename T> struct nk_helper<T,0>{enum {value = nk_alignof<T>::value};};
4110
4243
  template<typename T> struct nk_alignof{struct Big {T x; char c;}; enum {
4111
4244
  diff = sizeof(Big) - sizeof(T), value = nk_helper<Big, diff>::value};};
4112
- #define NK_ALIGNOF(t) (nk_alignof<t>::value);
4245
+ #define NK_ALIGNOF(t) (nk_alignof<t>::value)
4113
4246
  #elif defined(_MSC_VER)
4114
4247
  #define NK_ALIGNOF(t) (__alignof(t))
4115
4248
  #else
4116
4249
  #define NK_ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0)
4117
4250
  #endif
4118
4251
 
4119
- #endif /* NK_H_ */
4252
+ #endif /* NK_NUKLEAR_H_ */
4120
4253
  /*
4121
4254
  * ==============================================================
4122
4255
  *
@@ -4246,7 +4379,7 @@ NK_GLOBAL const struct nk_color nk_yellow = {255,255,0,255};
4246
4379
  ----
4247
4380
  For square root nuklear uses the famous fast inverse square root:
4248
4381
  https://en.wikipedia.org/wiki/Fast_inverse_square_root with
4249
- slightly tweaked magic constant. While on todays hardware it is
4382
+ slightly tweaked magic constant. While on today's hardware it is
4250
4383
  probably not faster it is still fast and accurate enough for
4251
4384
  nuklear's use cases. IMPORTANT: this requires float format IEEE 754
4252
4385
 
@@ -4257,7 +4390,7 @@ NK_GLOBAL const struct nk_color nk_yellow = {255,255,0,255};
4257
4390
  approximate exactly that range is that nuklear only needs sine and
4258
4391
  cosine to generate circles which only requires that exact range.
4259
4392
  In addition I used Remez instead of Taylor for additional precision:
4260
- www.lolengine.net/blog/2011/12/21/better-function-approximatations.
4393
+ www.lolengine.net/blog/2011/12/21/better-function-approximations.
4261
4394
 
4262
4395
  The tool I used to generate constants for both sine and cosine
4263
4396
  (it can actually approximate a lot more functions) can be
@@ -4764,7 +4897,7 @@ nk_strmatch_fuzzy_text(const char *str, int str_len,
4764
4897
  const char *pattern, int *out_score)
4765
4898
  {
4766
4899
  /* Returns true if each character in pattern is found sequentially within str
4767
- * if found then outScore is also set. Score value has no intrinsic meaning.
4900
+ * if found then out_score is also set. Score value has no intrinsic meaning.
4768
4901
  * Range varies with pattern. Can only compare scores with same search pattern. */
4769
4902
 
4770
4903
  /* ------- scores --------- */
@@ -4942,7 +5075,7 @@ nk_iceilf(float x)
4942
5075
  {
4943
5076
  if (x >= 0) {
4944
5077
  int i = (int)x;
4945
- return i;
5078
+ return (x > i) ? i+1: i;
4946
5079
  } else {
4947
5080
  int t = (int)x;
4948
5081
  float r = x - (float)t;
@@ -5513,7 +5646,7 @@ nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc)
5513
5646
  fclose(fd);
5514
5647
  return 0;
5515
5648
  }
5516
- *siz = (nk_size)fread(buf, *siz, 1, fd);
5649
+ *siz = (nk_size)fread(buf, 1,*siz, fd);
5517
5650
  fclose(fd);
5518
5651
  return buf;
5519
5652
  }
@@ -7216,7 +7349,7 @@ nk_stroke_line(struct nk_command_buffer *b, float x0, float y0,
7216
7349
  {
7217
7350
  struct nk_command_line *cmd;
7218
7351
  NK_ASSERT(b);
7219
- if (!b) return;
7352
+ if (!b || line_thickness <= 0) return;
7220
7353
  cmd = (struct nk_command_line*)
7221
7354
  nk_command_buffer_push(b, NK_COMMAND_LINE, sizeof(*cmd));
7222
7355
  if (!cmd) return;
@@ -7235,7 +7368,7 @@ nk_stroke_curve(struct nk_command_buffer *b, float ax, float ay,
7235
7368
  {
7236
7369
  struct nk_command_curve *cmd;
7237
7370
  NK_ASSERT(b);
7238
- if (!b || col.a == 0) return;
7371
+ if (!b || col.a == 0 || line_thickness <= 0) return;
7239
7372
 
7240
7373
  cmd = (struct nk_command_curve*)
7241
7374
  nk_command_buffer_push(b, NK_COMMAND_CURVE, sizeof(*cmd));
@@ -7258,13 +7391,12 @@ nk_stroke_rect(struct nk_command_buffer *b, struct nk_rect rect,
7258
7391
  {
7259
7392
  struct nk_command_rect *cmd;
7260
7393
  NK_ASSERT(b);
7261
- if (!b || c.a == 0 || rect.w == 0 || rect.h == 0) return;
7394
+ if (!b || c.a == 0 || rect.w == 0 || rect.h == 0 || line_thickness <= 0) return;
7262
7395
  if (b->use_clipping) {
7263
7396
  const struct nk_rect *clip = &b->clip;
7264
7397
  if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
7265
7398
  clip->x, clip->y, clip->w, clip->h)) return;
7266
7399
  }
7267
-
7268
7400
  cmd = (struct nk_command_rect*)
7269
7401
  nk_command_buffer_push(b, NK_COMMAND_RECT, sizeof(*cmd));
7270
7402
  if (!cmd) return;
@@ -7333,7 +7465,7 @@ nk_stroke_circle(struct nk_command_buffer *b, struct nk_rect r,
7333
7465
  float line_thickness, struct nk_color c)
7334
7466
  {
7335
7467
  struct nk_command_circle *cmd;
7336
- if (!b || r.w == 0 || r.h == 0) return;
7468
+ if (!b || r.w == 0 || r.h == 0 || line_thickness <= 0) return;
7337
7469
  if (b->use_clipping) {
7338
7470
  const struct nk_rect *clip = &b->clip;
7339
7471
  if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
@@ -7378,7 +7510,7 @@ nk_stroke_arc(struct nk_command_buffer *b, float cx, float cy, float radius,
7378
7510
  float a_min, float a_max, float line_thickness, struct nk_color c)
7379
7511
  {
7380
7512
  struct nk_command_arc *cmd;
7381
- if (!b || c.a == 0) return;
7513
+ if (!b || c.a == 0 || line_thickness <= 0) return;
7382
7514
  cmd = (struct nk_command_arc*)
7383
7515
  nk_command_buffer_push(b, NK_COMMAND_ARC, sizeof(*cmd));
7384
7516
  if (!cmd) return;
@@ -7415,7 +7547,7 @@ nk_stroke_triangle(struct nk_command_buffer *b, float x0, float y0, float x1,
7415
7547
  {
7416
7548
  struct nk_command_triangle *cmd;
7417
7549
  NK_ASSERT(b);
7418
- if (!b || c.a == 0) return;
7550
+ if (!b || c.a == 0 || line_thickness <= 0) return;
7419
7551
  if (b->use_clipping) {
7420
7552
  const struct nk_rect *clip = &b->clip;
7421
7553
  if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
@@ -7474,7 +7606,7 @@ nk_stroke_polygon(struct nk_command_buffer *b, float *points, int point_count,
7474
7606
  struct nk_command_polygon *cmd;
7475
7607
 
7476
7608
  NK_ASSERT(b);
7477
- if (!b || col.a == 0) return;
7609
+ if (!b || col.a == 0 || line_thickness <= 0) return;
7478
7610
  size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
7479
7611
  cmd = (struct nk_command_polygon*) nk_command_buffer_push(b, NK_COMMAND_POLYGON, size);
7480
7612
  if (!cmd) return;
@@ -7518,7 +7650,7 @@ nk_stroke_polyline(struct nk_command_buffer *b, float *points, int point_count,
7518
7650
  struct nk_command_polyline *cmd;
7519
7651
 
7520
7652
  NK_ASSERT(b);
7521
- if (!b || col.a == 0) return;
7653
+ if (!b || col.a == 0 || line_thickness <= 0) return;
7522
7654
  size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
7523
7655
  cmd = (struct nk_command_polyline*) nk_command_buffer_push(b, NK_COMMAND_POLYLINE, size);
7524
7656
  if (!cmd) return;
@@ -7643,7 +7775,8 @@ nk_draw_list_init(struct nk_draw_list *list)
7643
7775
 
7644
7776
  NK_API void
7645
7777
  nk_draw_list_setup(struct nk_draw_list *canvas, const struct nk_convert_config *config,
7646
- struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements)
7778
+ struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements,
7779
+ enum nk_anti_aliasing line_aa, enum nk_anti_aliasing shape_aa)
7647
7780
  {
7648
7781
  NK_ASSERT(canvas);
7649
7782
  NK_ASSERT(config);
@@ -7657,6 +7790,8 @@ nk_draw_list_setup(struct nk_draw_list *canvas, const struct nk_convert_config *
7657
7790
  canvas->config = *config;
7658
7791
  canvas->elements = elements;
7659
7792
  canvas->vertices = vertices;
7793
+ canvas->line_AA = line_aa;
7794
+ canvas->shape_AA = shape_aa;
7660
7795
  canvas->clip_rect = nk_null_rect;
7661
7796
  }
7662
7797
 
@@ -7836,10 +7971,16 @@ nk_draw_list_push_image(struct nk_draw_list *list, nk_handle texture)
7836
7971
  nk_draw_list_push_command(list, nk_null_rect, texture);
7837
7972
  } else {
7838
7973
  struct nk_draw_command *prev = nk_draw_list_command_last(list);
7839
- if (prev->elem_count == 0)
7974
+ if (prev->elem_count == 0) {
7840
7975
  prev->texture = texture;
7841
- else if (prev->texture.id != texture.id)
7842
- nk_draw_list_push_command(list, prev->clip_rect, texture);
7976
+ #ifdef NK_INCLUDE_COMMAND_USERDATA
7977
+ prev->userdata = list->userdata;
7978
+ #endif
7979
+ } else if (prev->texture.id != texture.id
7980
+ #ifdef NK_INCLUDE_COMMAND_USERDATA
7981
+ || prev->userdata.id != list->userdata.id
7982
+ #endif
7983
+ ) nk_draw_list_push_command(list, prev->clip_rect, texture);
7843
7984
  }
7844
7985
  }
7845
7986
 
@@ -8459,12 +8600,42 @@ nk_draw_list_path_arc_to(struct nk_draw_list *list, struct nk_vec2 center,
8459
8600
  NK_ASSERT(list);
8460
8601
  if (!list) return;
8461
8602
  if (radius == 0.0f) return;
8462
- for (i = 0; i <= segments; ++i) {
8463
- const float a = a_min + ((float)i / ((float)segments) * (a_max - a_min));
8464
- const float x = center.x + (float)NK_COS(a) * radius;
8465
- const float y = center.y + (float)NK_SIN(a) * radius;
8603
+
8604
+ /* This algorithm for arc drawing relies on these two trigonometric identities[1]:
8605
+ sin(a + b) = sin(a) * cos(b) + cos(a) * sin(b)
8606
+ cos(a + b) = cos(a) * cos(b) - sin(a) * sin(b)
8607
+
8608
+ Two coordinates (x, y) of a point on a circle centered on
8609
+ the origin can be written in polar form as:
8610
+ x = r * cos(a)
8611
+ y = r * sin(a)
8612
+ where r is the radius of the circle,
8613
+ a is the angle between (x, y) and the origin.
8614
+
8615
+ This allows us to rotate the coordinates around the
8616
+ origin by an angle b using the following transformation:
8617
+ x' = r * cos(a + b) = x * cos(b) - y * sin(b)
8618
+ y' = r * sin(a + b) = y * cos(b) + x * sin(b)
8619
+
8620
+ [1] https://en.wikipedia.org/wiki/List_of_trigonometric_identities#Angle_sum_and_difference_identities
8621
+ */
8622
+ {const float d_angle = (a_max - a_min) / (float)segments;
8623
+ const float sin_d = (float)NK_SIN(d_angle);
8624
+ const float cos_d = (float)NK_COS(d_angle);
8625
+
8626
+ float cx = (float)NK_COS(a_min) * radius;
8627
+ float cy = (float)NK_SIN(a_min) * radius;
8628
+ for(i = 0; i <= segments; ++i) {
8629
+ float new_cx, new_cy;
8630
+ const float x = center.x + cx;
8631
+ const float y = center.y + cy;
8466
8632
  nk_draw_list_path_line_to(list, nk_vec2(x, y));
8467
- }
8633
+
8634
+ new_cx = cx * cos_d - cy * sin_d;
8635
+ new_cy = cy * cos_d + cx * sin_d;
8636
+ cx = new_cx;
8637
+ cy = new_cy;
8638
+ }}
8468
8639
  }
8469
8640
 
8470
8641
  NK_API void
@@ -8549,8 +8720,13 @@ nk_draw_list_stroke_line(struct nk_draw_list *list, struct nk_vec2 a,
8549
8720
  {
8550
8721
  NK_ASSERT(list);
8551
8722
  if (!list || !col.a) return;
8552
- nk_draw_list_path_line_to(list, nk_vec2_add(a, nk_vec2(0.5f, 0.5f)));
8553
- nk_draw_list_path_line_to(list, nk_vec2_add(b, nk_vec2(0.5f, 0.5f)));
8723
+ if (list->line_AA == NK_ANTI_ALIASING_ON) {
8724
+ nk_draw_list_path_line_to(list, a);
8725
+ nk_draw_list_path_line_to(list, b);
8726
+ } else {
8727
+ nk_draw_list_path_line_to(list, nk_vec2_sub(a,nk_vec2(0.5f,0.5f)));
8728
+ nk_draw_list_path_line_to(list, nk_vec2_sub(b,nk_vec2(0.5f,0.5f)));
8729
+ }
8554
8730
  nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
8555
8731
  }
8556
8732
 
@@ -8560,9 +8736,14 @@ nk_draw_list_fill_rect(struct nk_draw_list *list, struct nk_rect rect,
8560
8736
  {
8561
8737
  NK_ASSERT(list);
8562
8738
  if (!list || !col.a) return;
8563
- nk_draw_list_path_rect_to(list, nk_vec2(rect.x + 0.5f, rect.y + 0.5f),
8564
- nk_vec2(rect.x + rect.w + 0.5f, rect.y + rect.h + 0.5f), rounding);
8565
- nk_draw_list_path_fill(list, col);
8739
+
8740
+ if (list->line_AA == NK_ANTI_ALIASING_ON) {
8741
+ nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y),
8742
+ nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
8743
+ } else {
8744
+ nk_draw_list_path_rect_to(list, nk_vec2(rect.x-0.5f, rect.y-0.5f),
8745
+ nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
8746
+ } nk_draw_list_path_fill(list, col);
8566
8747
  }
8567
8748
 
8568
8749
  NK_API void
@@ -8571,9 +8752,13 @@ nk_draw_list_stroke_rect(struct nk_draw_list *list, struct nk_rect rect,
8571
8752
  {
8572
8753
  NK_ASSERT(list);
8573
8754
  if (!list || !col.a) return;
8574
- nk_draw_list_path_rect_to(list, nk_vec2(rect.x + 0.5f, rect.y + 0.5f),
8575
- nk_vec2(rect.x + rect.w + 0.5f, rect.y + rect.h + 0.5f), rounding);
8576
- nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
8755
+ if (list->line_AA == NK_ANTI_ALIASING_ON) {
8756
+ nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y),
8757
+ nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
8758
+ } else {
8759
+ nk_draw_list_path_rect_to(list, nk_vec2(rect.x-0.5f, rect.y-0.5f),
8760
+ nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
8761
+ } nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
8577
8762
  }
8578
8763
 
8579
8764
  NK_API void
@@ -8799,7 +8984,8 @@ nk_convert(struct nk_context *ctx, struct nk_buffer *cmds,
8799
8984
  if (!ctx || !cmds || !vertices || !elements || !config || !config->vertex_layout)
8800
8985
  return NK_CONVERT_INVALID_PARAM;
8801
8986
 
8802
- nk_draw_list_setup(&ctx->draw_list, config, cmds, vertices, elements);
8987
+ nk_draw_list_setup(&ctx->draw_list, config, cmds, vertices, elements,
8988
+ config->line_AA, config->shape_AA);
8803
8989
  nk_foreach(cmd, ctx)
8804
8990
  {
8805
8991
  #ifdef NK_INCLUDE_COMMAND_USERDATA
@@ -11128,7 +11314,7 @@ nk_font_baker_memory(nk_size *temp, int *glyph_count,
11128
11314
  {
11129
11315
  int range_count = 0;
11130
11316
  int total_range_count = 0;
11131
- struct nk_font_config *iter;
11317
+ struct nk_font_config *iter, *i;
11132
11318
 
11133
11319
  NK_ASSERT(config_list);
11134
11320
  NK_ASSERT(glyph_count);
@@ -11137,16 +11323,15 @@ nk_font_baker_memory(nk_size *temp, int *glyph_count,
11137
11323
  *glyph_count = 0;
11138
11324
  return;
11139
11325
  }
11140
-
11141
11326
  *glyph_count = 0;
11142
- if (!config_list->range)
11143
- config_list->range = nk_font_default_glyph_ranges();
11144
11327
  for (iter = config_list; iter; iter = iter->next) {
11145
- range_count = nk_range_count(iter->range);
11146
- total_range_count += range_count;
11147
- *glyph_count += nk_range_glyph_count(iter->range, range_count);
11328
+ i = iter;
11329
+ do {if (!i->range) iter->range = nk_font_default_glyph_ranges();
11330
+ range_count = nk_range_count(i->range);
11331
+ total_range_count += range_count;
11332
+ *glyph_count += nk_range_glyph_count(i->range, range_count);
11333
+ } while ((i = i->n) != iter);
11148
11334
  }
11149
-
11150
11335
  *temp = (nk_size)*glyph_count * sizeof(struct nk_rp_rect);
11151
11336
  *temp += (nk_size)total_range_count * sizeof(struct nk_tt_pack_range);
11152
11337
  *temp += (nk_size)*glyph_count * sizeof(struct nk_tt_packedchar);
@@ -11178,7 +11363,7 @@ nk_font_bake_pack(struct nk_font_baker *baker,
11178
11363
  struct nk_allocator *alloc)
11179
11364
  {
11180
11365
  NK_STORAGE const nk_size max_height = 1024 * 32;
11181
- const struct nk_font_config *config_iter;
11366
+ const struct nk_font_config *config_iter, *it;
11182
11367
  int total_glyph_count = 0;
11183
11368
  int total_range_count = 0;
11184
11369
  int range_count = 0;
@@ -11193,18 +11378,19 @@ nk_font_bake_pack(struct nk_font_baker *baker,
11193
11378
 
11194
11379
  if (!image_memory || !width || !height || !config_list || !count) return nk_false;
11195
11380
  for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
11196
- range_count = nk_range_count(config_iter->range);
11197
- total_range_count += range_count;
11198
- total_glyph_count += nk_range_glyph_count(config_iter->range, range_count);
11381
+ it = config_iter;
11382
+ do {range_count = nk_range_count(it->range);
11383
+ total_range_count += range_count;
11384
+ total_glyph_count += nk_range_glyph_count(it->range, range_count);
11385
+ } while ((it = it->n) != config_iter);
11199
11386
  }
11200
-
11201
11387
  /* setup font baker from temporary memory */
11202
11388
  for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
11203
- const struct nk_font_config *cfg = config_iter;
11204
- if (!nk_tt_InitFont(&baker->build[i++].info, (const unsigned char*)cfg->ttf_blob, 0))
11389
+ it = config_iter;
11390
+ do {if (!nk_tt_InitFont(&baker->build[i++].info, (const unsigned char*)it->ttf_blob, 0))
11205
11391
  return nk_false;
11392
+ } while ((it = it->n) != config_iter);
11206
11393
  }
11207
-
11208
11394
  *height = 0;
11209
11395
  *width = (total_glyph_count > 1000) ? 1024 : 512;
11210
11396
  nk_tt_PackBegin(&baker->spc, 0, (int)*width, (int)max_height, 0, 1, alloc);
@@ -11233,47 +11419,48 @@ nk_font_bake_pack(struct nk_font_baker *baker,
11233
11419
 
11234
11420
  /* first font pass: pack all glyphs */
11235
11421
  for (input_i = 0, config_iter = config_list; input_i < count && config_iter;
11236
- input_i++, config_iter = config_iter->next)
11237
- {
11238
- int n = 0;
11239
- int glyph_count;
11240
- const nk_rune *in_range;
11241
- const struct nk_font_config *cfg = config_iter;
11242
- struct nk_font_bake_data *tmp = &baker->build[input_i];
11243
-
11244
- /* count glyphs + ranges in current font */
11245
- glyph_count = 0; range_count = 0;
11246
- for (in_range = cfg->range; in_range[0] && in_range[1]; in_range += 2) {
11247
- glyph_count += (int)(in_range[1] - in_range[0]) + 1;
11248
- range_count++;
11249
- }
11422
+ config_iter = config_iter->next) {
11423
+ it = config_iter;
11424
+ do {int n = 0;
11425
+ int glyph_count;
11426
+ const nk_rune *in_range;
11427
+ const struct nk_font_config *cfg = it;
11428
+ struct nk_font_bake_data *tmp = &baker->build[input_i++];
11429
+
11430
+ /* count glyphs + ranges in current font */
11431
+ glyph_count = 0; range_count = 0;
11432
+ for (in_range = cfg->range; in_range[0] && in_range[1]; in_range += 2) {
11433
+ glyph_count += (int)(in_range[1] - in_range[0]) + 1;
11434
+ range_count++;
11435
+ }
11250
11436
 
11251
- /* setup ranges */
11252
- tmp->ranges = baker->ranges + range_n;
11253
- tmp->range_count = (nk_rune)range_count;
11254
- range_n += range_count;
11255
- for (i = 0; i < range_count; ++i) {
11256
- in_range = &cfg->range[i * 2];
11257
- tmp->ranges[i].font_size = cfg->size;
11258
- tmp->ranges[i].first_unicode_codepoint_in_range = (int)in_range[0];
11259
- tmp->ranges[i].num_chars = (int)(in_range[1]- in_range[0]) + 1;
11260
- tmp->ranges[i].chardata_for_range = baker->packed_chars + char_n;
11261
- char_n += tmp->ranges[i].num_chars;
11262
- }
11437
+ /* setup ranges */
11438
+ tmp->ranges = baker->ranges + range_n;
11439
+ tmp->range_count = (nk_rune)range_count;
11440
+ range_n += range_count;
11441
+ for (i = 0; i < range_count; ++i) {
11442
+ in_range = &cfg->range[i * 2];
11443
+ tmp->ranges[i].font_size = cfg->size;
11444
+ tmp->ranges[i].first_unicode_codepoint_in_range = (int)in_range[0];
11445
+ tmp->ranges[i].num_chars = (int)(in_range[1]- in_range[0]) + 1;
11446
+ tmp->ranges[i].chardata_for_range = baker->packed_chars + char_n;
11447
+ char_n += tmp->ranges[i].num_chars;
11448
+ }
11263
11449
 
11264
- /* pack */
11265
- tmp->rects = baker->rects + rect_n;
11266
- rect_n += glyph_count;
11267
- nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
11268
- n = nk_tt_PackFontRangesGatherRects(&baker->spc, &tmp->info,
11269
- tmp->ranges, (int)tmp->range_count, tmp->rects);
11270
- nk_rp_pack_rects((struct nk_rp_context*)baker->spc.pack_info, tmp->rects, (int)n);
11271
-
11272
- /* texture height */
11273
- for (i = 0; i < n; ++i) {
11274
- if (tmp->rects[i].was_packed)
11275
- *height = NK_MAX(*height, tmp->rects[i].y + tmp->rects[i].h);
11276
- }
11450
+ /* pack */
11451
+ tmp->rects = baker->rects + rect_n;
11452
+ rect_n += glyph_count;
11453
+ nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
11454
+ n = nk_tt_PackFontRangesGatherRects(&baker->spc, &tmp->info,
11455
+ tmp->ranges, (int)tmp->range_count, tmp->rects);
11456
+ nk_rp_pack_rects((struct nk_rp_context*)baker->spc.pack_info, tmp->rects, (int)n);
11457
+
11458
+ /* texture height */
11459
+ for (i = 0; i < n; ++i) {
11460
+ if (tmp->rects[i].was_packed)
11461
+ *height = NK_MAX(*height, tmp->rects[i].y + tmp->rects[i].h);
11462
+ }
11463
+ } while ((it = it->n) != config_iter);
11277
11464
  }
11278
11465
  NK_ASSERT(rect_n == total_glyph_count);
11279
11466
  NK_ASSERT(char_n == total_glyph_count);
@@ -11292,6 +11479,7 @@ nk_font_bake(struct nk_font_baker *baker, void *image_memory, int width, int hei
11292
11479
  int input_i = 0;
11293
11480
  nk_rune glyph_n = 0;
11294
11481
  const struct nk_font_config *config_iter;
11482
+ const struct nk_font_config *it;
11295
11483
 
11296
11484
  NK_ASSERT(image_memory);
11297
11485
  NK_ASSERT(width);
@@ -11309,88 +11497,88 @@ nk_font_bake(struct nk_font_baker *baker, void *image_memory, int width, int hei
11309
11497
  baker->spc.pixels = (unsigned char*)image_memory;
11310
11498
  baker->spc.height = (int)height;
11311
11499
  for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
11312
- ++input_i, config_iter = config_iter->next)
11313
- {
11314
- const struct nk_font_config *cfg = config_iter;
11315
- struct nk_font_bake_data *tmp = &baker->build[input_i];
11316
- nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
11317
- nk_tt_PackFontRangesRenderIntoRects(&baker->spc, &tmp->info, tmp->ranges,
11318
- (int)tmp->range_count, tmp->rects, &baker->alloc);
11319
- }
11320
- nk_tt_PackEnd(&baker->spc, &baker->alloc);
11500
+ config_iter = config_iter->next) {
11501
+ it = config_iter;
11502
+ do {const struct nk_font_config *cfg = it;
11503
+ struct nk_font_bake_data *tmp = &baker->build[input_i++];
11504
+ nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
11505
+ nk_tt_PackFontRangesRenderIntoRects(&baker->spc, &tmp->info, tmp->ranges,
11506
+ (int)tmp->range_count, tmp->rects, &baker->alloc);
11507
+ } while ((it = it->n) != config_iter);
11508
+ } nk_tt_PackEnd(&baker->spc, &baker->alloc);
11321
11509
 
11322
11510
  /* third pass: setup font and glyphs */
11323
11511
  for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
11324
- ++input_i, config_iter = config_iter->next)
11325
- {
11326
- nk_size i = 0;
11327
- int char_idx = 0;
11328
- nk_rune glyph_count = 0;
11329
- const struct nk_font_config *cfg = config_iter;
11330
- struct nk_font_bake_data *tmp = &baker->build[input_i];
11331
- struct nk_baked_font *dst_font = cfg->font;
11332
-
11333
- float font_scale = nk_tt_ScaleForPixelHeight(&tmp->info, cfg->size);
11334
- int unscaled_ascent, unscaled_descent, unscaled_line_gap;
11335
- nk_tt_GetFontVMetrics(&tmp->info, &unscaled_ascent, &unscaled_descent,
11336
- &unscaled_line_gap);
11337
-
11338
- /* fill baked font */
11339
- if (!cfg->merge_mode) {
11340
- dst_font->ranges = cfg->range;
11341
- dst_font->height = cfg->size;
11342
- dst_font->ascent = ((float)unscaled_ascent * font_scale);
11343
- dst_font->descent = ((float)unscaled_descent * font_scale);
11344
- dst_font->glyph_offset = glyph_n;
11345
- }
11512
+ config_iter = config_iter->next) {
11513
+ it = config_iter;
11514
+ do {nk_size i = 0;
11515
+ int char_idx = 0;
11516
+ nk_rune glyph_count = 0;
11517
+ const struct nk_font_config *cfg = it;
11518
+ struct nk_font_bake_data *tmp = &baker->build[input_i++];
11519
+ struct nk_baked_font *dst_font = cfg->font;
11520
+
11521
+ float font_scale = nk_tt_ScaleForPixelHeight(&tmp->info, cfg->size);
11522
+ int unscaled_ascent, unscaled_descent, unscaled_line_gap;
11523
+ nk_tt_GetFontVMetrics(&tmp->info, &unscaled_ascent, &unscaled_descent,
11524
+ &unscaled_line_gap);
11525
+
11526
+ /* fill baked font */
11527
+ if (!cfg->merge_mode) {
11528
+ dst_font->ranges = cfg->range;
11529
+ dst_font->height = cfg->size;
11530
+ dst_font->ascent = ((float)unscaled_ascent * font_scale);
11531
+ dst_font->descent = ((float)unscaled_descent * font_scale);
11532
+ dst_font->glyph_offset = glyph_n;
11533
+ }
11346
11534
 
11347
- /* fill own baked font glyph array */
11348
- for (i = 0; i < tmp->range_count; ++i)
11349
- {
11350
- struct nk_tt_pack_range *range = &tmp->ranges[i];
11351
- for (char_idx = 0; char_idx < range->num_chars; char_idx++)
11352
- {
11353
- nk_rune codepoint = 0;
11354
- float dummy_x = 0, dummy_y = 0;
11355
- struct nk_tt_aligned_quad q;
11356
- struct nk_font_glyph *glyph;
11357
-
11358
- /* query glyph bounds from stb_truetype */
11359
- const struct nk_tt_packedchar *pc = &range->chardata_for_range[char_idx];
11360
- if (!pc->x0 && !pc->x1 && !pc->y0 && !pc->y1) continue;
11361
- codepoint = (nk_rune)(range->first_unicode_codepoint_in_range + char_idx);
11362
- nk_tt_GetPackedQuad(range->chardata_for_range, (int)width,
11363
- (int)height, char_idx, &dummy_x, &dummy_y, &q, 0);
11364
-
11365
- /* fill own glyph type with data */
11366
- glyph = &glyphs[dst_font->glyph_offset + (unsigned int)glyph_count];
11367
- glyph->codepoint = codepoint;
11368
- glyph->x0 = q.x0; glyph->y0 = q.y0;
11369
- glyph->x1 = q.x1; glyph->y1 = q.y1;
11370
- glyph->y0 += (dst_font->ascent + 0.5f);
11371
- glyph->y1 += (dst_font->ascent + 0.5f);
11372
- glyph->w = glyph->x1 - glyph->x0 + 0.5f;
11373
- glyph->h = glyph->y1 - glyph->y0;
11374
-
11375
- if (cfg->coord_type == NK_COORD_PIXEL) {
11376
- glyph->u0 = q.s0 * (float)width;
11377
- glyph->v0 = q.t0 * (float)height;
11378
- glyph->u1 = q.s1 * (float)width;
11379
- glyph->v1 = q.t1 * (float)height;
11380
- } else {
11381
- glyph->u0 = q.s0;
11382
- glyph->v0 = q.t0;
11383
- glyph->u1 = q.s1;
11384
- glyph->v1 = q.t1;
11535
+ /* fill own baked font glyph array */
11536
+ for (i = 0; i < tmp->range_count; ++i) {
11537
+ struct nk_tt_pack_range *range = &tmp->ranges[i];
11538
+ for (char_idx = 0; char_idx < range->num_chars; char_idx++)
11539
+ {
11540
+ nk_rune codepoint = 0;
11541
+ float dummy_x = 0, dummy_y = 0;
11542
+ struct nk_tt_aligned_quad q;
11543
+ struct nk_font_glyph *glyph;
11544
+
11545
+ /* query glyph bounds from stb_truetype */
11546
+ const struct nk_tt_packedchar *pc = &range->chardata_for_range[char_idx];
11547
+ if (!pc->x0 && !pc->x1 && !pc->y0 && !pc->y1) continue;
11548
+ codepoint = (nk_rune)(range->first_unicode_codepoint_in_range + char_idx);
11549
+ nk_tt_GetPackedQuad(range->chardata_for_range, (int)width,
11550
+ (int)height, char_idx, &dummy_x, &dummy_y, &q, 0);
11551
+
11552
+ /* fill own glyph type with data */
11553
+ glyph = &glyphs[dst_font->glyph_offset + dst_font->glyph_count + (unsigned int)glyph_count];
11554
+ glyph->codepoint = codepoint;
11555
+ glyph->x0 = q.x0; glyph->y0 = q.y0;
11556
+ glyph->x1 = q.x1; glyph->y1 = q.y1;
11557
+ glyph->y0 += (dst_font->ascent + 0.5f);
11558
+ glyph->y1 += (dst_font->ascent + 0.5f);
11559
+ glyph->w = glyph->x1 - glyph->x0 + 0.5f;
11560
+ glyph->h = glyph->y1 - glyph->y0;
11561
+
11562
+ if (cfg->coord_type == NK_COORD_PIXEL) {
11563
+ glyph->u0 = q.s0 * (float)width;
11564
+ glyph->v0 = q.t0 * (float)height;
11565
+ glyph->u1 = q.s1 * (float)width;
11566
+ glyph->v1 = q.t1 * (float)height;
11567
+ } else {
11568
+ glyph->u0 = q.s0;
11569
+ glyph->v0 = q.t0;
11570
+ glyph->u1 = q.s1;
11571
+ glyph->v1 = q.t1;
11572
+ }
11573
+ glyph->xadvance = (pc->xadvance + cfg->spacing.x);
11574
+ if (cfg->pixel_snap)
11575
+ glyph->xadvance = (float)(int)(glyph->xadvance + 0.5f);
11576
+ glyph_count++;
11385
11577
  }
11386
- glyph->xadvance = (pc->xadvance + cfg->spacing.x);
11387
- if (cfg->pixel_snap)
11388
- glyph->xadvance = (float)(int)(glyph->xadvance + 0.5f);
11389
- glyph_count++;
11390
11578
  }
11391
- }
11392
- dst_font->glyph_count = glyph_count;
11393
- glyph_n += dst_font->glyph_count;
11579
+ dst_font->glyph_count += glyph_count;
11580
+ glyph_n += glyph_count;
11581
+ } while ((it = it->n) != config_iter);
11394
11582
  }
11395
11583
  }
11396
11584
 
@@ -11517,6 +11705,7 @@ nk_font_find_glyph(struct nk_font *font, nk_rune unicode)
11517
11705
  int count;
11518
11706
  int total_glyphs = 0;
11519
11707
  const struct nk_font_glyph *glyph = 0;
11708
+ const struct nk_font_config *iter = 0;
11520
11709
 
11521
11710
  NK_ASSERT(font);
11522
11711
  NK_ASSERT(font->glyphs);
@@ -11524,15 +11713,17 @@ nk_font_find_glyph(struct nk_font *font, nk_rune unicode)
11524
11713
  if (!font || !font->glyphs) return 0;
11525
11714
 
11526
11715
  glyph = font->fallback;
11527
- count = nk_range_count(font->info.ranges);
11528
- for (i = 0; i < count; ++i) {
11529
- nk_rune f = font->info.ranges[(i*2)+0];
11530
- nk_rune t = font->info.ranges[(i*2)+1];
11531
- int diff = (int)((t - f) + 1);
11532
- if (unicode >= f && unicode <= t)
11533
- return &font->glyphs[((nk_rune)total_glyphs + (unicode - f))];
11534
- total_glyphs += diff;
11535
- }
11716
+ iter = font->config;
11717
+ do {count = nk_range_count(iter->range);
11718
+ for (i = 0; i < count; ++i) {
11719
+ nk_rune f = iter->range[(i*2)+0];
11720
+ nk_rune t = iter->range[(i*2)+1];
11721
+ int diff = (int)((t - f) + 1);
11722
+ if (unicode >= f && unicode <= t)
11723
+ return &font->glyphs[((nk_rune)total_glyphs + (unicode - f))];
11724
+ total_glyphs += diff;
11725
+ }
11726
+ } while ((iter = iter->n) != font->config);
11536
11727
  return glyph;
11537
11728
  }
11538
11729
 
@@ -11884,6 +12075,7 @@ nk_font_config(float pixel_height)
11884
12075
  cfg.merge_mode = 0;
11885
12076
  cfg.fallback_glyph = '?';
11886
12077
  cfg.font = 0;
12078
+ cfg.n = 0;
11887
12079
  return cfg;
11888
12080
  }
11889
12081
 
@@ -11967,43 +12159,57 @@ nk_font_atlas_add(struct nk_font_atlas *atlas, const struct nk_font_config *conf
11967
12159
  !atlas->temporary.alloc || !atlas->temporary.free)
11968
12160
  return 0;
11969
12161
 
11970
- /* allocate and insert font config into list */
12162
+ /* allocate font config */
11971
12163
  cfg = (struct nk_font_config*)
11972
12164
  atlas->permanent.alloc(atlas->permanent.userdata,0, sizeof(struct nk_font_config));
11973
12165
  NK_MEMCPY(cfg, config, sizeof(*config));
11974
- if (!atlas->config) {
11975
- atlas->config = cfg;
11976
- cfg->next = 0;
11977
- } else {
11978
- cfg->next = atlas->config;
11979
- atlas->config = cfg;
11980
- }
12166
+ cfg->n = cfg;
12167
+ cfg->p = cfg;
11981
12168
 
11982
- /* allocate new font */
11983
12169
  if (!config->merge_mode) {
12170
+ /* insert font config into list */
12171
+ if (!atlas->config) {
12172
+ atlas->config = cfg;
12173
+ cfg->next = 0;
12174
+ } else {
12175
+ struct nk_font_config *i = atlas->config;
12176
+ while (i->next) i = i->next;
12177
+ i->next = cfg;
12178
+ cfg->next = 0;
12179
+ }
12180
+ /* allocate new font */
11984
12181
  font = (struct nk_font*)
11985
12182
  atlas->permanent.alloc(atlas->permanent.userdata,0, sizeof(struct nk_font));
11986
12183
  NK_ASSERT(font);
12184
+ nk_zero(font, sizeof(*font));
11987
12185
  if (!font) return 0;
11988
12186
  font->config = cfg;
11989
- } else {
11990
- NK_ASSERT(atlas->font_num);
11991
- font = atlas->fonts;
11992
- font->config = cfg;
11993
- }
11994
12187
 
11995
- /* insert font into list */
11996
- if (!config->merge_mode) {
12188
+ /* insert font into list */
11997
12189
  if (!atlas->fonts) {
11998
12190
  atlas->fonts = font;
11999
12191
  font->next = 0;
12000
12192
  } else {
12001
- font->next = atlas->fonts;
12002
- atlas->fonts = font;
12193
+ struct nk_font *i = atlas->fonts;
12194
+ while (i->next) i = i->next;
12195
+ i->next = font;
12196
+ font->next = 0;
12003
12197
  }
12004
12198
  cfg->font = &font->info;
12005
- }
12199
+ } else {
12200
+ /* extend previously added font */
12201
+ struct nk_font *f = 0;
12202
+ struct nk_font_config *c = 0;
12203
+ NK_ASSERT(atlas->font_num);
12204
+ f = atlas->fonts;
12205
+ c = f->config;
12206
+ cfg->font = &f->info;
12006
12207
 
12208
+ cfg->n = c;
12209
+ cfg->p = c->p;
12210
+ c->p->n = cfg;
12211
+ c->p = cfg;
12212
+ }
12007
12213
  /* create own copy of .TTF font blob */
12008
12214
  if (!config->ttf_data_owned_by_atlas) {
12009
12215
  cfg->ttf_blob = atlas->permanent.alloc(atlas->permanent.userdata,0, cfg->ttf_size);
@@ -12322,16 +12528,18 @@ nk_font_atlas_cleanup(struct nk_font_atlas *atlas)
12322
12528
  NK_ASSERT(atlas->temporary.free);
12323
12529
  NK_ASSERT(atlas->permanent.alloc);
12324
12530
  NK_ASSERT(atlas->permanent.free);
12325
-
12326
12531
  if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return;
12327
12532
  if (atlas->config) {
12328
- struct nk_font_config *iter, *next;
12329
- for (iter = atlas->config; iter; iter = next) {
12330
- next = iter->next;
12533
+ struct nk_font_config *iter;
12534
+ for (iter = atlas->config; iter; iter = iter->next) {
12535
+ struct nk_font_config *i;
12536
+ for (i = iter->n; i != iter; i = i->n) {
12537
+ atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
12538
+ i->ttf_blob = 0;
12539
+ }
12331
12540
  atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
12332
- atlas->permanent.free(atlas->permanent.userdata, iter);
12541
+ iter->ttf_blob = 0;
12333
12542
  }
12334
- atlas->config = 0;
12335
12543
  }
12336
12544
  }
12337
12545
 
@@ -12345,7 +12553,23 @@ nk_font_atlas_clear(struct nk_font_atlas *atlas)
12345
12553
  NK_ASSERT(atlas->permanent.free);
12346
12554
  if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return;
12347
12555
 
12348
- nk_font_atlas_cleanup(atlas);
12556
+ if (atlas->config) {
12557
+ struct nk_font_config *iter, *next;
12558
+ for (iter = atlas->config; iter; iter = next) {
12559
+ struct nk_font_config *i, *n;
12560
+ for (i = iter->n; i != iter; i = n) {
12561
+ n = i->n;
12562
+ if (i->ttf_blob)
12563
+ atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
12564
+ atlas->permanent.free(atlas->permanent.userdata, i);
12565
+ }
12566
+ next = iter->next;
12567
+ if (i->ttf_blob)
12568
+ atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
12569
+ atlas->permanent.free(atlas->permanent.userdata, iter);
12570
+ }
12571
+ atlas->config = 0;
12572
+ }
12349
12573
  if (atlas->fonts) {
12350
12574
  struct nk_font *iter, *next;
12351
12575
  for (iter = atlas->fonts; iter; iter = next) {
@@ -14528,8 +14752,7 @@ nk_slider_behavior(nk_flags *state, struct nk_rect *logical_cursor,
14528
14752
  left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
14529
14753
  NK_BUTTON_LEFT, *visual_cursor, nk_true);
14530
14754
 
14531
- if (left_mouse_down && left_mouse_click_in_cursor)
14532
- {
14755
+ if (left_mouse_down && left_mouse_click_in_cursor) {
14533
14756
  float ratio = 0;
14534
14757
  const float d = in->mouse.pos.x - (visual_cursor->x+visual_cursor->w*0.5f);
14535
14758
  const float pxstep = bounds.w / slider_steps;
@@ -14714,30 +14937,37 @@ nk_do_slider(nk_flags *state,
14714
14937
  *
14715
14938
  * ===============================================================*/
14716
14939
  NK_INTERN nk_size
14717
- nk_progress_behavior(nk_flags *state, const struct nk_input *in,
14718
- struct nk_rect r, nk_size max, nk_size value, int modifiable)
14940
+ nk_progress_behavior(nk_flags *state, struct nk_input *in,
14941
+ struct nk_rect r, struct nk_rect cursor, nk_size max, nk_size value, int modifiable)
14719
14942
  {
14943
+ int left_mouse_down = 0;
14944
+ int left_mouse_click_in_cursor = 0;
14945
+
14720
14946
  nk_widget_state_reset(state);
14721
- if (in && modifiable && nk_input_is_mouse_hovering_rect(in, r)) {
14947
+ if (!in) return value;
14948
+ left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
14949
+ left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
14950
+ NK_BUTTON_LEFT, cursor, nk_true);
14951
+ if (nk_input_is_mouse_hovering_rect(in, r))
14952
+ *state = NK_WIDGET_STATE_HOVERED;
14953
+
14954
+ if (in && left_mouse_down && left_mouse_click_in_cursor) {
14722
14955
  int left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
14723
14956
  int left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
14724
14957
  NK_BUTTON_LEFT, r, nk_true);
14725
14958
 
14726
14959
  if (left_mouse_down && left_mouse_click_in_cursor) {
14727
- float ratio = NK_MAX(0, (float)(in->mouse.pos.x - r.x)) / (float)r.w;
14728
- value = (nk_size)NK_MAX(0,((float)max * ratio));
14729
- *state = NK_WIDGET_STATE_ACTIVE;
14730
- } else *state = NK_WIDGET_STATE_HOVERED;
14960
+ float ratio = NK_MAX(0, (float)(in->mouse.pos.x - cursor.x)) / (float)cursor.w;
14961
+ value = (nk_size)NK_CLAMP(0, (float)max * ratio, max);
14962
+ in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor.x + cursor.w/2.0f;
14963
+ *state |= NK_WIDGET_STATE_ACTIVE;
14964
+ }
14731
14965
  }
14732
-
14733
14966
  /* set progressbar widget state */
14734
14967
  if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, r))
14735
14968
  *state |= NK_WIDGET_STATE_ENTERED;
14736
14969
  else if (nk_input_is_mouse_prev_hovering_rect(in, r))
14737
14970
  *state |= NK_WIDGET_STATE_LEFT;
14738
-
14739
- if (!max) return value;
14740
- value = NK_MIN(value, max);
14741
14971
  return value;
14742
14972
  }
14743
14973
 
@@ -14771,7 +15001,7 @@ nk_draw_progress(struct nk_command_buffer *out, nk_flags state,
14771
15001
  } else nk_draw_image(out, *bounds, &background->data.image, nk_white);
14772
15002
 
14773
15003
  /* draw cursor */
14774
- if (background->type == NK_STYLE_ITEM_COLOR) {
15004
+ if (cursor->type == NK_STYLE_ITEM_COLOR) {
14775
15005
  nk_fill_rect(out, *scursor, style->rounding, cursor->data.color);
14776
15006
  nk_stroke_rect(out, *scursor, style->rounding, style->border, style->border_color);
14777
15007
  } else nk_draw_image(out, *scursor, &cursor->data.image, nk_white);
@@ -14781,7 +15011,7 @@ NK_INTERN nk_size
14781
15011
  nk_do_progress(nk_flags *state,
14782
15012
  struct nk_command_buffer *out, struct nk_rect bounds,
14783
15013
  nk_size value, nk_size max, int modifiable,
14784
- const struct nk_style_progress *style, const struct nk_input *in)
15014
+ const struct nk_style_progress *style, struct nk_input *in)
14785
15015
  {
14786
15016
  float prog_scale;
14787
15017
  nk_size prog_value;
@@ -14796,11 +15026,11 @@ nk_do_progress(nk_flags *state,
14796
15026
  cursor.h = NK_MAX(bounds.h, 2 * style->padding.y + 2 * style->border);
14797
15027
  cursor = nk_pad_rect(bounds, nk_vec2(style->padding.x + style->border, style->padding.y + style->border));
14798
15028
  prog_scale = (float)value / (float)max;
14799
- cursor.w = (bounds.w - 2) * prog_scale;
14800
15029
 
14801
15030
  /* update progressbar */
14802
15031
  prog_value = NK_MIN(value, max);
14803
- prog_value = nk_progress_behavior(state, in, bounds, max, prog_value, modifiable);
15032
+ prog_value = nk_progress_behavior(state, in, bounds, cursor,max, prog_value, modifiable);
15033
+ cursor.w = cursor.w * prog_scale;
14804
15034
 
14805
15035
  /* draw progressbar */
14806
15036
  if (style->draw_begin) style->draw_begin(out, style->userdata);
@@ -15202,7 +15432,7 @@ nk_edit_draw_text(struct nk_command_buffer *out,
15202
15432
  while ((text_len < byte_len) && glyph_len)
15203
15433
  {
15204
15434
  if (unicode == '\n') {
15205
- /* new line sepeator so draw previous line */
15435
+ /* new line separator so draw previous line */
15206
15436
  struct nk_rect label;
15207
15437
  label.y = pos_y + line_offset;
15208
15438
  label.h = row_height;
@@ -15300,8 +15530,6 @@ nk_do_edit(nk_flags *state, struct nk_command_buffer *out,
15300
15530
  const enum nk_text_edit_type type = (flags & NK_EDIT_MULTILINE) ?
15301
15531
  NK_TEXT_EDIT_MULTI_LINE: NK_TEXT_EDIT_SINGLE_LINE;
15302
15532
  nk_textedit_clear_state(edit, type, filter);
15303
- if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
15304
- edit->mode = NK_TEXT_EDIT_MODE_INSERT;
15305
15533
  if (flags & NK_EDIT_AUTO_SELECT)
15306
15534
  select_all = nk_true;
15307
15535
  if (flags & NK_EDIT_GOTO_END_ON_ACTIVATE) {
@@ -15311,6 +15539,8 @@ nk_do_edit(nk_flags *state, struct nk_command_buffer *out,
15311
15539
  } else if (!edit->active) edit->mode = NK_TEXT_EDIT_MODE_VIEW;
15312
15540
  if (flags & NK_EDIT_READ_ONLY)
15313
15541
  edit->mode = NK_TEXT_EDIT_MODE_VIEW;
15542
+ else if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
15543
+ edit->mode = NK_TEXT_EDIT_MODE_INSERT;
15314
15544
 
15315
15545
  ret = (edit->active) ? NK_EDIT_ACTIVE: NK_EDIT_INACTIVE;
15316
15546
  if (prev_state != edit->active)
@@ -15942,11 +16172,11 @@ nk_do_property(nk_flags *ws,
15942
16172
  num_len = nk_strlen(string);
15943
16173
  break;
15944
16174
  case NK_PROPERTY_FLOAT:
15945
- nk_dtoa(string, (double)variant->value.f);
16175
+ NK_DTOA(string, (double)variant->value.f);
15946
16176
  num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
15947
16177
  break;
15948
16178
  case NK_PROPERTY_DOUBLE:
15949
- nk_dtoa(string, variant->value.d);
16179
+ NK_DTOA(string, variant->value.d);
15950
16180
  num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
15951
16181
  break;
15952
16182
  }
@@ -16822,6 +17052,7 @@ nk_style_from_table(struct nk_context *ctx, const struct nk_color *table)
16822
17052
  win->tooltip_border = 1.0f;
16823
17053
  win->popup_border = 1.0f;
16824
17054
  win->border = 2.0f;
17055
+ win->min_row_height_padding = 8;
16825
17056
 
16826
17057
  win->padding = nk_vec2(4,4);
16827
17058
  win->group_padding = nk_vec2(4,4);
@@ -16837,10 +17068,13 @@ nk_style_set_font(struct nk_context *ctx, const struct nk_user_font *font)
16837
17068
  {
16838
17069
  struct nk_style *style;
16839
17070
  NK_ASSERT(ctx);
17071
+
16840
17072
  if (!ctx) return;
16841
17073
  style = &ctx->style;
16842
17074
  style->font = font;
16843
17075
  ctx->stacks.fonts.head = 0;
17076
+ if (ctx->current)
17077
+ nk_layout_reset_min_row_height(ctx);
16844
17078
  }
16845
17079
 
16846
17080
  NK_API int
@@ -17189,25 +17423,27 @@ nk_clear(struct nk_context *ctx)
17189
17423
  /* garbage collector */
17190
17424
  iter = ctx->begin;
17191
17425
  while (iter) {
17192
- /* make sure minimized windows do not get removed */
17426
+ /* make sure valid minimized windows do not get removed */
17193
17427
  if ((iter->flags & NK_WINDOW_MINIMIZED) &&
17194
- !(iter->flags & NK_WINDOW_CLOSED)) {
17428
+ !(iter->flags & NK_WINDOW_CLOSED) &&
17429
+ iter->seq == ctx->seq) {
17195
17430
  iter = iter->next;
17196
17431
  continue;
17197
17432
  }
17198
-
17199
17433
  /* remove hotness from hidden or closed windows*/
17200
17434
  if (((iter->flags & NK_WINDOW_HIDDEN) ||
17201
17435
  (iter->flags & NK_WINDOW_CLOSED)) &&
17202
- iter == ctx->active)
17203
- ctx->active = iter->next;
17204
-
17436
+ iter == ctx->active) {
17437
+ ctx->active = iter->prev;
17438
+ ctx->end = iter->prev;
17439
+ if (ctx->active)
17440
+ ctx->active->flags &= ~(unsigned)NK_WINDOW_ROM;
17441
+ }
17205
17442
  /* free unused popup windows */
17206
17443
  if (iter->popup.win && iter->popup.win->seq != ctx->seq) {
17207
17444
  nk_free_window(ctx, iter->popup.win);
17208
17445
  iter->popup.win = 0;
17209
17446
  }
17210
-
17211
17447
  /* remove unused window state tables */
17212
17448
  {struct nk_table *n, *it = iter->tables;
17213
17449
  while (it) {
@@ -17218,10 +17454,8 @@ nk_clear(struct nk_context *ctx)
17218
17454
  nk_free_table(ctx, it);
17219
17455
  if (it == iter->tables)
17220
17456
  iter->tables = n;
17221
- }
17222
- it = n;
17457
+ } it = n;
17223
17458
  }}
17224
-
17225
17459
  /* window itself is not used anymore so free */
17226
17460
  if (iter->seq != ctx->seq || iter->flags & NK_WINDOW_CLOSED) {
17227
17461
  next = iter->next;
@@ -17319,7 +17553,7 @@ nk_finish(struct nk_context *ctx, struct nk_window *win)
17319
17553
  NK_INTERN void
17320
17554
  nk_build(struct nk_context *ctx)
17321
17555
  {
17322
- struct nk_window *iter = 0;
17556
+ struct nk_window *it = 0;
17323
17557
  struct nk_command *cmd = 0;
17324
17558
  nk_byte *buffer = 0;
17325
17559
 
@@ -17341,37 +17575,38 @@ nk_build(struct nk_context *ctx)
17341
17575
  nk_finish_buffer(ctx, &ctx->overlay);
17342
17576
  }
17343
17577
  /* build one big draw command list out of all window buffers */
17344
- iter = ctx->begin;
17578
+ it = ctx->begin;
17345
17579
  buffer = (nk_byte*)ctx->memory.memory.ptr;
17346
- while (iter != 0) {
17347
- struct nk_window *next = iter->next;
17348
- if (iter->buffer.last == iter->buffer.begin || (iter->flags & NK_WINDOW_HIDDEN))
17580
+ while (it != 0) {
17581
+ struct nk_window *next = it->next;
17582
+ if (it->buffer.last == it->buffer.begin || (it->flags & NK_WINDOW_HIDDEN)||
17583
+ it->seq != ctx->seq)
17349
17584
  goto cont;
17350
17585
 
17351
- cmd = nk_ptr_add(struct nk_command, buffer, iter->buffer.last);
17586
+ cmd = nk_ptr_add(struct nk_command, buffer, it->buffer.last);
17352
17587
  while (next && ((next->buffer.last == next->buffer.begin) ||
17353
17588
  (next->flags & NK_WINDOW_HIDDEN)))
17354
17589
  next = next->next; /* skip empty command buffers */
17355
17590
 
17356
17591
  if (next) cmd->next = next->buffer.begin;
17357
- cont: iter = next;
17592
+ cont: it = next;
17358
17593
  }
17359
17594
  /* append all popup draw commands into lists */
17360
- iter = ctx->begin;
17361
- while (iter != 0) {
17362
- struct nk_window *next = iter->next;
17595
+ it = ctx->begin;
17596
+ while (it != 0) {
17597
+ struct nk_window *next = it->next;
17363
17598
  struct nk_popup_buffer *buf;
17364
- if (!iter->popup.buf.active)
17599
+ if (!it->popup.buf.active)
17365
17600
  goto skip;
17366
17601
 
17367
- buf = &iter->popup.buf;
17602
+ buf = &it->popup.buf;
17368
17603
  cmd->next = buf->begin;
17369
17604
  cmd = nk_ptr_add(struct nk_command, buffer, buf->last);
17370
17605
  buf->active = nk_false;
17371
- skip: iter = next;
17606
+ skip: it = next;
17372
17607
  }
17373
- /* append overlay commands */
17374
17608
  if (cmd) {
17609
+ /* append overlay commands */
17375
17610
  if (ctx->overlay.end != ctx->overlay.begin)
17376
17611
  cmd->next = ctx->overlay.begin;
17377
17612
  else cmd->next = ctx->memory.allocated;
@@ -17392,9 +17627,9 @@ nk__begin(struct nk_context *ctx)
17392
17627
  nk_build(ctx);
17393
17628
  ctx->build = nk_true;
17394
17629
  }
17395
-
17396
17630
  iter = ctx->begin;
17397
- while (iter && ((iter->buffer.begin == iter->buffer.end) || (iter->flags & NK_WINDOW_HIDDEN)))
17631
+ while (iter && ((iter->buffer.begin == iter->buffer.end) ||
17632
+ (iter->flags & NK_WINDOW_HIDDEN) || iter->seq != ctx->seq))
17398
17633
  iter = iter->next;
17399
17634
  if (!iter) return 0;
17400
17635
  return nk_ptr_add_const(struct nk_command, buffer, iter->buffer.begin);
@@ -17567,6 +17802,7 @@ nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type pan
17567
17802
  layout->max_x = 0;
17568
17803
  layout->header_height = 0;
17569
17804
  layout->footer_height = 0;
17805
+ nk_layout_reset_min_row_height(ctx);
17570
17806
  layout->row.index = 0;
17571
17807
  layout->row.columns = 0;
17572
17808
  layout->row.ratio = 0;
@@ -18134,16 +18370,16 @@ nk_push_table(struct nk_window *win, struct nk_table *tbl)
18134
18370
  win->tables = tbl;
18135
18371
  tbl->next = 0;
18136
18372
  tbl->prev = 0;
18373
+ tbl->size = 0;
18137
18374
  win->table_count = 1;
18138
- win->table_size = 0;
18139
18375
  return;
18140
18376
  }
18141
18377
  win->tables->prev = tbl;
18142
18378
  tbl->next = win->tables;
18143
18379
  tbl->prev = 0;
18380
+ tbl->size = 0;
18144
18381
  win->tables = tbl;
18145
18382
  win->table_count++;
18146
- win->table_size = 0;
18147
18383
  }
18148
18384
 
18149
18385
  NK_INTERN void
@@ -18166,32 +18402,31 @@ nk_add_value(struct nk_context *ctx, struct nk_window *win,
18166
18402
  NK_ASSERT(ctx);
18167
18403
  NK_ASSERT(win);
18168
18404
  if (!win || !ctx) return 0;
18169
- if (!win->tables || win->table_size >= NK_VALUE_PAGE_CAPACITY) {
18405
+ if (!win->tables || win->tables->size >= NK_VALUE_PAGE_CAPACITY) {
18170
18406
  struct nk_table *tbl = nk_create_table(ctx);
18171
18407
  NK_ASSERT(tbl);
18172
18408
  if (!tbl) return 0;
18173
18409
  nk_push_table(win, tbl);
18174
18410
  }
18175
18411
  win->tables->seq = win->seq;
18176
- win->tables->keys[win->table_size] = name;
18177
- win->tables->values[win->table_size] = value;
18178
- return &win->tables->values[win->table_size++];
18412
+ win->tables->keys[win->tables->size] = name;
18413
+ win->tables->values[win->tables->size] = value;
18414
+ return &win->tables->values[win->tables->size++];
18179
18415
  }
18180
18416
 
18181
18417
  NK_INTERN nk_uint*
18182
18418
  nk_find_value(struct nk_window *win, nk_hash name)
18183
18419
  {
18184
- nk_ushort size = win->table_size;
18185
18420
  struct nk_table *iter = win->tables;
18186
18421
  while (iter) {
18187
- nk_ushort i = 0;
18422
+ unsigned int i = 0;
18423
+ unsigned int size = iter->size;
18188
18424
  for (i = 0; i < size; ++i) {
18189
18425
  if (iter->keys[i] == name) {
18190
18426
  iter->seq = win->seq;
18191
18427
  return &iter->values[i];
18192
18428
  }
18193
- }
18194
- size = NK_VALUE_PAGE_CAPACITY;
18429
+ } size = NK_VALUE_PAGE_CAPACITY;
18195
18430
  iter = iter->next;
18196
18431
  }
18197
18432
  return 0;
@@ -18297,7 +18532,7 @@ nk_insert_window(struct nk_context *ctx, struct nk_window *win,
18297
18532
  ctx->active = ctx->end;
18298
18533
  ctx->end->flags &= ~(nk_flags)NK_WINDOW_ROM;
18299
18534
  } else {
18300
- ctx->end->flags |= NK_WINDOW_ROM;
18535
+ /*ctx->end->flags |= NK_WINDOW_ROM;*/
18301
18536
  ctx->begin->prev = win;
18302
18537
  win->next = ctx->begin;
18303
18538
  win->prev = 0;
@@ -18403,27 +18638,28 @@ nk_begin_titled(struct nk_context *ctx, const char *name, const char *title,
18403
18638
  * provided demo backends). */
18404
18639
  NK_ASSERT(win->seq != ctx->seq);
18405
18640
  win->seq = ctx->seq;
18406
- if (!ctx->active && !(win->flags & NK_WINDOW_HIDDEN))
18641
+ if (!ctx->active && !(win->flags & NK_WINDOW_HIDDEN)) {
18407
18642
  ctx->active = win;
18643
+ ctx->end = win;
18644
+ }
18408
18645
  }
18409
18646
  if (win->flags & NK_WINDOW_HIDDEN) {
18410
18647
  ctx->current = win;
18411
18648
  win->layout = 0;
18412
18649
  return 0;
18413
- }
18650
+ } else nk_start(ctx, win);
18414
18651
 
18415
18652
  /* window overlapping */
18416
18653
  if (!(win->flags & NK_WINDOW_HIDDEN) && !(win->flags & NK_WINDOW_NO_INPUT))
18417
18654
  {
18418
18655
  int inpanel, ishovered;
18419
- const struct nk_window *iter = win;
18656
+ struct nk_window *iter = win;
18420
18657
  float h = ctx->style.font->height + 2.0f * style->window.header.padding.y +
18421
18658
  (2.0f * style->window.header.label_padding.y);
18422
18659
  struct nk_rect win_bounds = (!(win->flags & NK_WINDOW_MINIMIZED))?
18423
18660
  win->bounds: nk_rect(win->bounds.x, win->bounds.y, win->bounds.w, h);
18424
18661
 
18425
18662
  /* activate window if hovered and no other window is overlapping this window */
18426
- nk_start(ctx, win);
18427
18663
  inpanel = nk_input_has_mouse_click_down_in_rect(&ctx->input, NK_BUTTON_LEFT, win_bounds, nk_true);
18428
18664
  inpanel = inpanel && ctx->input.mouse.buttons[NK_BUTTON_LEFT].clicked;
18429
18665
  ishovered = nk_input_is_mouse_hovering_rect(&ctx->input, win_bounds);
@@ -18434,7 +18670,7 @@ nk_begin_titled(struct nk_context *ctx, const char *name, const char *title,
18434
18670
  iter->bounds: nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
18435
18671
  if (NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
18436
18672
  iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
18437
- (!(iter->flags & NK_WINDOW_HIDDEN) || !(iter->flags & NK_WINDOW_BACKGROUND)))
18673
+ (!(iter->flags & NK_WINDOW_HIDDEN)))
18438
18674
  break;
18439
18675
 
18440
18676
  if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) &&
@@ -18447,7 +18683,7 @@ nk_begin_titled(struct nk_context *ctx, const char *name, const char *title,
18447
18683
  }
18448
18684
 
18449
18685
  /* activate window if clicked */
18450
- if (iter && inpanel && (win != ctx->end) && !(iter->flags & NK_WINDOW_BACKGROUND)) {
18686
+ if (iter && inpanel && (win != ctx->end)) {
18451
18687
  iter = win->next;
18452
18688
  while (iter) {
18453
18689
  /* try to find a panel with higher priority in the same position */
@@ -18465,21 +18701,31 @@ nk_begin_titled(struct nk_context *ctx, const char *name, const char *title,
18465
18701
  iter = iter->next;
18466
18702
  }
18467
18703
  }
18468
-
18469
- if (!iter && ctx->end != win) {
18470
- if (!(win->flags & NK_WINDOW_BACKGROUND)) {
18704
+ if (iter && !(win->flags & NK_WINDOW_ROM) && (win->flags & NK_WINDOW_BACKGROUND)) {
18705
+ win->flags |= (nk_flags)NK_WINDOW_ROM;
18706
+ iter->flags &= ~(nk_flags)NK_WINDOW_ROM;
18707
+ ctx->active = iter;
18708
+ if (!(iter->flags & NK_WINDOW_BACKGROUND)) {
18471
18709
  /* current window is active in that position so transfer to top
18472
18710
  * at the highest priority in stack */
18473
- nk_remove_window(ctx, win);
18474
- nk_insert_window(ctx, win, NK_INSERT_BACK);
18711
+ nk_remove_window(ctx, iter);
18712
+ nk_insert_window(ctx, iter, NK_INSERT_BACK);
18475
18713
  }
18476
- win->flags &= ~(nk_flags)NK_WINDOW_ROM;
18477
- ctx->active = win;
18714
+ } else {
18715
+ if (!iter && ctx->end != win) {
18716
+ if (!(win->flags & NK_WINDOW_BACKGROUND)) {
18717
+ /* current window is active in that position so transfer to top
18718
+ * at the highest priority in stack */
18719
+ nk_remove_window(ctx, win);
18720
+ nk_insert_window(ctx, win, NK_INSERT_BACK);
18721
+ }
18722
+ win->flags &= ~(nk_flags)NK_WINDOW_ROM;
18723
+ ctx->active = win;
18724
+ }
18725
+ if (ctx->end != win && !(win->flags & NK_WINDOW_BACKGROUND))
18726
+ win->flags |= NK_WINDOW_ROM;
18478
18727
  }
18479
- if (ctx->end != win && !(win->flags & NK_WINDOW_BACKGROUND))
18480
- win->flags |= NK_WINDOW_ROM;
18481
18728
  }
18482
-
18483
18729
  win->layout = (struct nk_panel*)nk_create_panel(ctx);
18484
18730
  ctx->current = win;
18485
18731
  ret = nk_panel_begin(ctx, title, NK_PANEL_WINDOW);
@@ -18627,6 +18873,8 @@ nk_window_is_hovered(struct nk_context *ctx)
18627
18873
  NK_ASSERT(ctx);
18628
18874
  NK_ASSERT(ctx->current);
18629
18875
  if (!ctx || !ctx->current) return 0;
18876
+ if(ctx->current->flags & NK_WINDOW_HIDDEN)
18877
+ return 0;
18630
18878
  return nk_input_is_mouse_hovering_rect(&ctx->input, ctx->current->bounds);
18631
18879
  }
18632
18880
 
@@ -18639,17 +18887,20 @@ nk_window_is_any_hovered(struct nk_context *ctx)
18639
18887
  iter = ctx->begin;
18640
18888
  while (iter) {
18641
18889
  /* check if window is being hovered */
18642
- if (iter->flags & NK_WINDOW_MINIMIZED) {
18643
- struct nk_rect header = iter->bounds;
18644
- header.h = ctx->style.font->height + 2 * ctx->style.window.header.padding.y;
18645
- if (nk_input_is_mouse_hovering_rect(&ctx->input, header))
18890
+ if(!(iter->flags & NK_WINDOW_HIDDEN)) {
18891
+ /* check if window popup is being hovered */
18892
+ if (iter->popup.active && iter->popup.win && nk_input_is_mouse_hovering_rect(&ctx->input, iter->popup.win->bounds))
18646
18893
  return 1;
18647
- } else if (nk_input_is_mouse_hovering_rect(&ctx->input, iter->bounds)) {
18648
- return 1;
18894
+
18895
+ if (iter->flags & NK_WINDOW_MINIMIZED) {
18896
+ struct nk_rect header = iter->bounds;
18897
+ header.h = ctx->style.font->height + 2 * ctx->style.window.header.padding.y;
18898
+ if (nk_input_is_mouse_hovering_rect(&ctx->input, header))
18899
+ return 1;
18900
+ } else if (nk_input_is_mouse_hovering_rect(&ctx->input, iter->bounds)) {
18901
+ return 1;
18902
+ }
18649
18903
  }
18650
- /* check if window popup is being hovered */
18651
- if (iter->popup.active && iter->popup.win && nk_input_is_mouse_hovering_rect(&ctx->input, iter->popup.win->bounds))
18652
- return 1;
18653
18904
  iter = iter->next;
18654
18905
  }
18655
18906
  return 0;
@@ -18752,29 +19003,36 @@ nk_window_close(struct nk_context *ctx, const char *name)
18752
19003
  }
18753
19004
 
18754
19005
  NK_API void
18755
- nk_window_set_bounds(struct nk_context *ctx, struct nk_rect bounds)
19006
+ nk_window_set_bounds(struct nk_context *ctx,
19007
+ const char *name, struct nk_rect bounds)
18756
19008
  {
18757
- NK_ASSERT(ctx); NK_ASSERT(ctx->current);
18758
- if (!ctx || !ctx->current) return;
18759
- ctx->current->bounds = bounds;
19009
+ struct nk_window *win;
19010
+ NK_ASSERT(ctx);
19011
+ if (!ctx) return;
19012
+ win = nk_window_find(ctx, name);
19013
+ if (!win) return;
19014
+ NK_ASSERT(ctx->current != win && "You cannot update a currently in procecss window");
19015
+ win->bounds = bounds;
18760
19016
  }
18761
19017
 
18762
19018
  NK_API void
18763
- nk_window_set_position(struct nk_context *ctx, struct nk_vec2 pos)
19019
+ nk_window_set_position(struct nk_context *ctx,
19020
+ const char *name, struct nk_vec2 pos)
18764
19021
  {
18765
- NK_ASSERT(ctx); NK_ASSERT(ctx->current);
18766
- if (!ctx || !ctx->current) return;
18767
- ctx->current->bounds.x = pos.x;
18768
- ctx->current->bounds.y = pos.y;
19022
+ struct nk_window *win = nk_window_find(ctx, name);
19023
+ if (!win) return;
19024
+ win->bounds.x = pos.x;
19025
+ win->bounds.y = pos.y;
18769
19026
  }
18770
19027
 
18771
19028
  NK_API void
18772
- nk_window_set_size(struct nk_context *ctx, struct nk_vec2 size)
19029
+ nk_window_set_size(struct nk_context *ctx,
19030
+ const char *name, struct nk_vec2 size)
18773
19031
  {
18774
- NK_ASSERT(ctx); NK_ASSERT(ctx->current);
18775
- if (!ctx || !ctx->current) return;
18776
- ctx->current->bounds.w = size.x;
18777
- ctx->current->bounds.h = size.y;
19032
+ struct nk_window *win = nk_window_find(ctx, name);
19033
+ if (!win) return;
19034
+ win->bounds.w = size.x;
19035
+ win->bounds.h = size.y;
18778
19036
  }
18779
19037
 
18780
19038
  NK_API void
@@ -18930,6 +19188,42 @@ nk_menubar_end(struct nk_context *ctx)
18930
19188
  * LAYOUT
18931
19189
  *
18932
19190
  * --------------------------------------------------------------*/
19191
+ NK_API void
19192
+ nk_layout_set_min_row_height(struct nk_context *ctx, float height)
19193
+ {
19194
+ struct nk_window *win;
19195
+ struct nk_panel *layout;
19196
+
19197
+ NK_ASSERT(ctx);
19198
+ NK_ASSERT(ctx->current);
19199
+ NK_ASSERT(ctx->current->layout);
19200
+ if (!ctx || !ctx->current || !ctx->current->layout)
19201
+ return;
19202
+
19203
+ win = ctx->current;
19204
+ layout = win->layout;
19205
+ layout->row.min_height = height;
19206
+ }
19207
+
19208
+ NK_API void
19209
+ nk_layout_reset_min_row_height(struct nk_context *ctx)
19210
+ {
19211
+ struct nk_window *win;
19212
+ struct nk_panel *layout;
19213
+
19214
+ NK_ASSERT(ctx);
19215
+ NK_ASSERT(ctx->current);
19216
+ NK_ASSERT(ctx->current->layout);
19217
+ if (!ctx || !ctx->current || !ctx->current->layout)
19218
+ return;
19219
+
19220
+ win = ctx->current;
19221
+ layout = win->layout;
19222
+ layout->row.min_height = ctx->style.font->height;
19223
+ layout->row.min_height += ctx->style.text.padding.y*2;
19224
+ layout->row.min_height += ctx->style.window.min_row_height_padding*2;
19225
+ }
19226
+
18933
19227
  NK_INTERN float
18934
19228
  nk_layout_row_calculate_usable_space(const struct nk_style *style, enum nk_panel_type type,
18935
19229
  float total_space, int columns)
@@ -18988,7 +19282,10 @@ nk_panel_layout(const struct nk_context *ctx, struct nk_window *win,
18988
19282
  layout->row.index = 0;
18989
19283
  layout->at_y += layout->row.height;
18990
19284
  layout->row.columns = cols;
18991
- layout->row.height = height + item_spacing.y;
19285
+ if (height == 0.0f)
19286
+ layout->row.height = NK_MAX(height, layout->row.min_height) + item_spacing.y;
19287
+ else layout->row.height = height + item_spacing.y;
19288
+
18992
19289
  layout->row.item_offset = 0;
18993
19290
  if (layout->flags & NK_WINDOW_DYNAMIC) {
18994
19291
  /* draw background for dynamic panels */
@@ -19403,7 +19700,7 @@ nk_layout_widget_bounds(struct nk_context *ctx)
19403
19700
  layout = win->layout;
19404
19701
 
19405
19702
  ret.x = layout->at_x;
19406
- ret.y = layout->clip.y;
19703
+ ret.y = layout->at_y;
19407
19704
  ret.w = layout->bounds.w - NK_MAX(layout->at_x - layout->bounds.x,0);
19408
19705
  ret.h = layout->row.height;
19409
19706
  return ret;
@@ -19663,6 +19960,9 @@ nk_layout_peek(struct nk_rect *bounds, struct nk_context *ctx)
19663
19960
  layout->row.index = 0;
19664
19961
  }
19665
19962
  nk_layout_widget_space(bounds, ctx, win, nk_false);
19963
+ if (!layout->row.index) {
19964
+ bounds->x -= layout->row.item_offset;
19965
+ }
19666
19966
  layout->at_y = y;
19667
19967
  layout->row.index = index;
19668
19968
  }
@@ -19678,6 +19978,7 @@ nk_tree_state_base(struct nk_context *ctx, enum nk_tree_type type,
19678
19978
  const struct nk_input *in;
19679
19979
  const struct nk_style_button *button;
19680
19980
  enum nk_symbol_type symbol;
19981
+ float row_height;
19681
19982
 
19682
19983
  struct nk_vec2 item_spacing;
19683
19984
  struct nk_rect header = {0,0,0,0};
@@ -19701,7 +20002,11 @@ nk_tree_state_base(struct nk_context *ctx, enum nk_tree_type type,
19701
20002
  item_spacing = style->window.spacing;
19702
20003
 
19703
20004
  /* calculate header bounds and draw background */
19704
- nk_layout_row_dynamic(ctx, style->font->height + 2 * style->tab.padding.y, 1);
20005
+ row_height = style->font->height + 2 * style->tab.padding.y;
20006
+ nk_layout_set_min_row_height(ctx, row_height);
20007
+ nk_layout_row_dynamic(ctx, row_height, 1);
20008
+ nk_layout_reset_min_row_height(ctx);
20009
+
19705
20010
  widget_state = nk_widget(&header, ctx);
19706
20011
  if (type == NK_TREE_TAB) {
19707
20012
  const struct nk_style_item *background = &style->tab.background;
@@ -19912,49 +20217,70 @@ nk_widget_height(struct nk_context *ctx)
19912
20217
  NK_API int
19913
20218
  nk_widget_is_hovered(struct nk_context *ctx)
19914
20219
  {
19915
- int ret;
20220
+ struct nk_rect c, v;
19916
20221
  struct nk_rect bounds;
19917
20222
  NK_ASSERT(ctx);
19918
20223
  NK_ASSERT(ctx->current);
19919
- if (!ctx || !ctx->current)
20224
+ if (!ctx || !ctx->current || ctx->active != ctx->current)
19920
20225
  return 0;
19921
20226
 
20227
+ c = ctx->current->layout->clip;
20228
+ c.x = (float)((int)c.x);
20229
+ c.y = (float)((int)c.y);
20230
+ c.w = (float)((int)c.w);
20231
+ c.h = (float)((int)c.h);
20232
+
19922
20233
  nk_layout_peek(&bounds, ctx);
19923
- ret = (ctx->active == ctx->current);
19924
- ret = ret && nk_input_is_mouse_hovering_rect(&ctx->input, bounds);
19925
- return ret;
20234
+ nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
20235
+ if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
20236
+ return 0;
20237
+ return nk_input_is_mouse_hovering_rect(&ctx->input, bounds);
19926
20238
  }
19927
20239
 
19928
20240
  NK_API int
19929
20241
  nk_widget_is_mouse_clicked(struct nk_context *ctx, enum nk_buttons btn)
19930
20242
  {
19931
- int ret;
20243
+ struct nk_rect c, v;
19932
20244
  struct nk_rect bounds;
19933
20245
  NK_ASSERT(ctx);
19934
20246
  NK_ASSERT(ctx->current);
19935
- if (!ctx || !ctx->current)
20247
+ if (!ctx || !ctx->current || ctx->active != ctx->current)
19936
20248
  return 0;
19937
20249
 
20250
+ c = ctx->current->layout->clip;
20251
+ c.x = (float)((int)c.x);
20252
+ c.y = (float)((int)c.y);
20253
+ c.w = (float)((int)c.w);
20254
+ c.h = (float)((int)c.h);
20255
+
19938
20256
  nk_layout_peek(&bounds, ctx);
19939
- ret = (ctx->active == ctx->current);
19940
- ret = ret && nk_input_mouse_clicked(&ctx->input, btn, bounds);
19941
- return ret;
20257
+ nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
20258
+ if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
20259
+ return 0;
20260
+ return nk_input_mouse_clicked(&ctx->input, btn, bounds);
19942
20261
  }
19943
20262
 
19944
20263
  NK_API int
19945
20264
  nk_widget_has_mouse_click_down(struct nk_context *ctx, enum nk_buttons btn, int down)
19946
20265
  {
19947
- int ret;
20266
+ struct nk_rect c, v;
19948
20267
  struct nk_rect bounds;
19949
20268
  NK_ASSERT(ctx);
19950
20269
  NK_ASSERT(ctx->current);
19951
- if (!ctx || !ctx->current)
20270
+ if (!ctx || !ctx->current || ctx->active != ctx->current)
19952
20271
  return 0;
19953
20272
 
20273
+ c = ctx->current->layout->clip;
20274
+ c.x = (float)((int)c.x);
20275
+ c.y = (float)((int)c.y);
20276
+ c.w = (float)((int)c.w);
20277
+ c.h = (float)((int)c.h);
20278
+
19954
20279
  nk_layout_peek(&bounds, ctx);
19955
- ret = (ctx->active == ctx->current);
19956
- ret = ret && nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down);
19957
- return ret;
20280
+ nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
20281
+ if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
20282
+ return 0;
20283
+ return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down);
19958
20284
  }
19959
20285
 
19960
20286
  NK_API enum nk_widget_layout_states
@@ -20879,7 +21205,7 @@ nk_progress(struct nk_context *ctx, nk_size *cur, nk_size max, int is_modifyable
20879
21205
  struct nk_window *win;
20880
21206
  struct nk_panel *layout;
20881
21207
  const struct nk_style *style;
20882
- const struct nk_input *in;
21208
+ struct nk_input *in;
20883
21209
 
20884
21210
  struct nk_rect bounds;
20885
21211
  enum nk_widget_layout_states state;
@@ -20996,10 +21322,9 @@ nk_edit_string(struct nk_context *ctx, nk_flags flags,
20996
21322
  win->edit.sel_start = edit->select_start;
20997
21323
  win->edit.sel_end = edit->select_end;
20998
21324
  win->edit.mode = edit->mode;
20999
- win->edit.scrollbar.x = (nk_ushort)edit->scrollbar.x;
21000
- win->edit.scrollbar.y = (nk_ushort)edit->scrollbar.y;
21001
- }
21002
- return state;
21325
+ win->edit.scrollbar.x = (nk_uint)edit->scrollbar.x;
21326
+ win->edit.scrollbar.y = (nk_uint)edit->scrollbar.y;
21327
+ } return state;
21003
21328
  }
21004
21329
 
21005
21330
  NK_API nk_flags
@@ -21042,7 +21367,9 @@ nk_edit_buffer(struct nk_context *ctx, nk_flags flags,
21042
21367
  }
21043
21368
  if (flags & NK_EDIT_CLIPBOARD)
21044
21369
  edit->clip = ctx->clip;
21045
- }
21370
+ edit->active = (unsigned char)win->edit.active;
21371
+ } else edit->active = nk_false;
21372
+ edit->mode = win->edit.mode;
21046
21373
 
21047
21374
  filter = (!filter) ? nk_filter_default: filter;
21048
21375
  prev_state = (unsigned char)edit->active;
@@ -21059,8 +21386,7 @@ nk_edit_buffer(struct nk_context *ctx, nk_flags flags,
21059
21386
  } else if (prev_state && !edit->active) {
21060
21387
  /* current edit is now cold */
21061
21388
  win->edit.active = nk_false;
21062
- }
21063
- return ret_flags;
21389
+ } return ret_flags;
21064
21390
  }
21065
21391
 
21066
21392
  NK_API nk_flags
@@ -21632,10 +21958,12 @@ nk_plot(struct nk_context *ctx, enum nk_chart_type type, const float *values,
21632
21958
  min_value = NK_MIN(values[i + offset], min_value);
21633
21959
  max_value = NK_MAX(values[i + offset], max_value);
21634
21960
  }
21635
- nk_chart_begin(ctx, type, count, min_value, max_value);
21636
- for (i = 0; i < count; ++i)
21637
- nk_chart_push(ctx, values[i + offset]);
21638
- nk_chart_end(ctx);
21961
+
21962
+ if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
21963
+ for (i = 0; i < count; ++i)
21964
+ nk_chart_push(ctx, values[i + offset]);
21965
+ nk_chart_end(ctx);
21966
+ }
21639
21967
  }
21640
21968
 
21641
21969
  NK_API void
@@ -21656,10 +21984,12 @@ nk_plot_function(struct nk_context *ctx, enum nk_chart_type type, void *userdata
21656
21984
  min_value = NK_MIN(value, min_value);
21657
21985
  max_value = NK_MAX(value, max_value);
21658
21986
  }
21659
- nk_chart_begin(ctx, type, count, min_value, max_value);
21660
- for (i = 0; i < count; ++i)
21661
- nk_chart_push(ctx, value_getter(userdata, i + offset));
21662
- nk_chart_end(ctx);
21987
+
21988
+ if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
21989
+ for (i = 0; i < count; ++i)
21990
+ nk_chart_push(ctx, value_getter(userdata, i + offset));
21991
+ nk_chart_end(ctx);
21992
+ }
21663
21993
  }
21664
21994
 
21665
21995
  /* -------------------------------------------------------------
@@ -22149,10 +22479,10 @@ nk_tooltip_begin(struct nk_context *ctx, float width)
22149
22479
  if (win->popup.win && (win->popup.type & NK_PANEL_SET_NONBLOCK))
22150
22480
  return 0;
22151
22481
 
22152
- bounds.w = width;
22153
- bounds.h = nk_null_rect.h;
22154
- bounds.x = (in->mouse.pos.x + 1) - win->layout->clip.x;
22155
- bounds.y = (in->mouse.pos.y + 1) - win->layout->clip.y;
22482
+ bounds.w = nk_iceilf(width);
22483
+ bounds.h = nk_iceilf(nk_null_rect.h);
22484
+ bounds.x = nk_ifloorf(in->mouse.pos.x + 1) - win->layout->clip.x;
22485
+ bounds.y = nk_ifloorf(in->mouse.pos.y + 1) - win->layout->clip.y;
22156
22486
 
22157
22487
  ret = nk_popup_begin(ctx, NK_POPUP_DYNAMIC,
22158
22488
  "__##Tooltip##__", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER, bounds);
@@ -22208,6 +22538,19 @@ nk_tooltip(struct nk_context *ctx, const char *text)
22208
22538
  nk_tooltip_end(ctx);
22209
22539
  }
22210
22540
  }
22541
+ #ifdef NK_INCLUDE_STANDARD_VARARGS
22542
+ NK_API void
22543
+ nk_tooltipf(struct nk_context *ctx, const char *fmt, ...)
22544
+ {
22545
+ char buf[256];
22546
+ va_list args;
22547
+ va_start(args, fmt);
22548
+ nk_strfmt(buf, NK_LEN(buf), fmt, args);
22549
+ va_end(args);
22550
+ nk_tooltip(ctx, buf);
22551
+ }
22552
+ #endif
22553
+
22211
22554
  /* -------------------------------------------------------------
22212
22555
  *
22213
22556
  * CONTEXTUAL
@@ -23375,4 +23718,4 @@ NK_API void
23375
23718
  nk_menu_end(struct nk_context *ctx)
23376
23719
  {nk_contextual_end(ctx);}
23377
23720
 
23378
- #endif
23721
+ #endif /* NK_IMPLEMENTATION */