From 7fcdf77fdc3c796fbc16c17aad7e5b3f78db88cd Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Thu, 27 Jun 2024 14:14:46 -0400 Subject: [PATCH] Add triangle outline symbols --- demo/common/overview.c | 4 +++ demo/sdl_renderer/main.c | 2 +- nuklear.h | 74 +++++++++++++++++++++++++--------------- src/nuklear.h | 60 +++++++++++++++++--------------- src/nuklear_button.c | 14 ++++++++ 5 files changed, 97 insertions(+), 57 deletions(-) diff --git a/demo/common/overview.c b/demo/common/overview.c index c6aaf4e2a..dfc6fcbfc 100644 --- a/demo/common/overview.c +++ b/demo/common/overview.c @@ -205,9 +205,13 @@ overview(struct nk_context *ctx) nk_button_symbol(ctx, NK_SYMBOL_RECT_SOLID); nk_button_symbol(ctx, NK_SYMBOL_RECT_OUTLINE); nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_UP); + nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_UP_OUTLINE); nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_DOWN); + nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_DOWN_OUTLINE); nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_LEFT); + nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_LEFT_OUTLINE); nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_RIGHT); + nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE); nk_layout_row_static(ctx, 30, 100, 2); nk_button_symbol_label(ctx, NK_SYMBOL_TRIANGLE_LEFT, "prev", NK_TEXT_RIGHT); diff --git a/demo/sdl_renderer/main.c b/demo/sdl_renderer/main.c index 851374baa..fb9e04ec2 100644 --- a/demo/sdl_renderer/main.c +++ b/demo/sdl_renderer/main.c @@ -39,7 +39,7 @@ /*#define INCLUDE_CANVAS */ /*#define INCLUDE_OVERVIEW */ /*#define INCLUDE_NODE_EDITOR */ - +#define INCLUDE_ALL #ifdef INCLUDE_ALL #define INCLUDE_STYLE #define INCLUDE_CALCULATOR diff --git a/nuklear.h b/nuklear.h index 6c5060276..f0dbb6dd6 100644 --- a/nuklear.h +++ b/nuklear.h @@ -524,6 +524,10 @@ enum nk_symbol_type { NK_SYMBOL_TRIANGLE_RIGHT, NK_SYMBOL_PLUS, NK_SYMBOL_MINUS, + NK_SYMBOL_TRIANGLE_UP_OUTLINE, + NK_SYMBOL_TRIANGLE_DOWN_OUTLINE, + NK_SYMBOL_TRIANGLE_LEFT_OUTLINE, + NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE, NK_SYMBOL_MAX }; /* ============================================================================= @@ -3849,7 +3853,7 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune /// Finally the most complex API wise is using nuklear's font baking API. // /// #### Using your own implementation without vertex buffer output -/// +/// /// So first up the easiest way to do font handling is by just providing a /// `nk_user_font` struct which only requires the height in pixel of the used /// font and a callback to calculate the width of a string. This way of handling @@ -3872,12 +3876,12 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune /// font.userdata.ptr = &your_font_class_or_struct; /// font.height = your_font_height; /// font.width = your_text_width_calculation; -/// +/// /// struct nk_context ctx; /// nk_init_default(&ctx, &font); /// ``` /// #### Using your own implementation with vertex buffer output -/// +/// /// While the first approach works fine if you don't want to use the optional /// vertex buffer output it is not enough if you do. To get font handling working /// for these cases you have to provide two additional parameters inside the @@ -3906,44 +3910,44 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune /// glyph.offset.x = ...; /// glyph.offset.y = ...; /// } -/// +/// /// struct nk_user_font font; /// font.userdata.ptr = &your_font_class_or_struct; /// font.height = your_font_height; /// font.width = your_text_width_calculation; /// font.query = query_your_font_glyph; /// font.texture.id = your_font_texture; -/// +/// /// struct nk_context ctx; /// nk_init_default(&ctx, &font); /// ``` /// /// #### Nuklear font baker -/// +/// /// The final approach if you do not have a font handling functionality or don't /// want to use it in this library is by using the optional font baker. /// The font baker APIs can be used to create a font plus font atlas texture /// and can be used with or without the vertex buffer output. -/// +/// /// It still uses the `nk_user_font` struct and the two different approaches /// previously stated still work. The font baker is not located inside /// `nk_context` like all other systems since it can be understood as more of /// an extension to nuklear and does not really depend on any `nk_context` state. -/// +/// /// Font baker need to be initialized first by one of the nk_font_atlas_init_xxx /// functions. If you don't care about memory just call the default version /// `nk_font_atlas_init_default` which will allocate all memory from the standard library. /// If you want to control memory allocation but you don't care if the allocated /// memory is temporary and therefore can be freed directly after the baking process /// is over or permanent you can call `nk_font_atlas_init`. -/// +/// /// After successfully initializing the font baker you can add Truetype(.ttf) fonts from /// different sources like memory or from file by calling one of the `nk_font_atlas_add_xxx`. /// functions. Adding font will permanently store each font, font config and ttf memory block(!) /// inside the font atlas and allows to reuse the font atlas. If you don't want to reuse /// the font baker by for example adding additional fonts you can call /// `nk_font_atlas_cleanup` after the baking process is over (after calling nk_font_atlas_end). -/// +/// /// As soon as you added all fonts you wanted you can now start the baking process /// for every selected glyph to image by calling `nk_font_atlas_bake`. /// The baking process returns image memory, width and height which can be used to @@ -3954,12 +3958,12 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune /// to your font texture or object and optionally fills a `struct nk_draw_null_texture` /// which can be used for the optional vertex output. If you don't want it just /// set the argument to `NULL`. -/// +/// /// At this point you are done and if you don't want to reuse the font atlas you /// can call `nk_font_atlas_cleanup` to free all truetype blobs and configuration /// memory. Finally if you don't use the font atlas and any of it's fonts anymore /// you need to call `nk_font_atlas_clear` to free all memory still being used. -/// +/// /// ```c /// struct nk_font_atlas atlas; /// nk_font_atlas_init_default(&atlas); @@ -3968,11 +3972,11 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune /// nk_font *font2 = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font2.ttf", 16, 0); /// const void* img = nk_font_atlas_bake(&atlas, &img_width, &img_height, NK_FONT_ATLAS_RGBA32); /// nk_font_atlas_end(&atlas, nk_handle_id(texture), 0); -/// +/// /// struct nk_context ctx; /// nk_init_default(&ctx, &font->handle); /// while (1) { -/// +/// /// } /// nk_font_atlas_clear(&atlas); /// ``` @@ -4167,7 +4171,7 @@ NK_API void nk_font_atlas_clear(struct nk_font_atlas*); /// not as much control is needed. /// In general all memory inside this library can be provided from the user in /// three different ways. -/// +/// /// The first way and the one providing most control is by just passing a fixed /// size memory block. In this case all control lies in the hand of the user /// since he can exactly control where the memory comes from and how much memory @@ -4176,13 +4180,13 @@ NK_API void nk_font_atlas_clear(struct nk_font_atlas*); /// you have to take over the resizing. While being a fixed sized buffer sounds /// quite limiting, it is very effective in this library since the actual memory /// consumption is quite stable and has a fixed upper bound for a lot of cases. -/// +/// /// If you don't want to think about how much memory the library should allocate /// at all time or have a very dynamic UI with unpredictable memory consumption /// habits but still want control over memory allocation you can use the dynamic /// allocator based API. The allocator consists of two callbacks for allocating /// and freeing memory and optional userdata so you can plugin your own allocator. -/// +/// /// The final and easiest way can be used by defining /// NK_INCLUDE_DEFAULT_ALLOCATOR which uses the standard library memory /// allocation functions malloc and free and takes over complete control over @@ -4437,34 +4441,34 @@ NK_API void nk_textedit_redo(struct nk_text_edit*); /// started. It is probably important to note that the command buffer is the main /// drawing API and the optional vertex buffer API only takes this format and /// converts it into a hardware accessible format. -/// +/// /// To use the command queue to draw your own widgets you can access the /// command buffer of each window by calling `nk_window_get_canvas` after /// previously having called `nk_begin`: -/// +/// /// ```c /// void draw_red_rectangle_widget(struct nk_context *ctx) /// { /// struct nk_command_buffer *canvas; /// struct nk_input *input = &ctx->input; /// canvas = nk_window_get_canvas(ctx); -/// +/// /// struct nk_rect space; /// enum nk_widget_layout_states state; /// state = nk_widget(&space, ctx); /// if (!state) return; -/// +/// /// if (state != NK_WIDGET_ROM) /// update_your_widget_by_user_input(...); /// nk_fill_rect(canvas, space, 0, nk_rgb(255,0,0)); /// } -/// +/// /// if (nk_begin(...)) { /// nk_layout_row_dynamic(ctx, 25, 1); /// draw_red_rectangle_widget(ctx); /// } /// nk_end(..) -/// +/// /// ``` /// Important to know if you want to create your own widgets is the `nk_widget` /// call. It allocates space on the panel reserved for this widget to be used, @@ -4765,7 +4769,7 @@ NK_API nk_bool nk_input_is_key_down(const struct nk_input*, enum nk_keys); /// library since converting the default library draw command output is done by /// just calling `nk_convert` but I decided to still make this library accessible /// since it can be useful. -/// +/// /// The draw list is based on a path buffering and polygon and polyline /// rendering API which allows a lot of ways to draw 2D content to screen. /// In fact it is probably more powerful than needed but allows even more crazy @@ -5581,19 +5585,19 @@ struct nk_window { /// red button you can temporarily push the old button color onto a stack /// draw the button with a red color and then you just pop the old color /// back from the stack: -/// +/// /// nk_style_push_style_item(ctx, &ctx->style.button.normal, nk_style_item_color(nk_rgb(255,0,0))); /// nk_style_push_style_item(ctx, &ctx->style.button.hover, nk_style_item_color(nk_rgb(255,0,0))); /// nk_style_push_style_item(ctx, &ctx->style.button.active, nk_style_item_color(nk_rgb(255,0,0))); /// nk_style_push_vec2(ctx, &cx->style.button.padding, nk_vec2(2,2)); -/// +/// /// nk_button(...); -/// +/// /// nk_style_pop_style_item(ctx); /// nk_style_pop_style_item(ctx); /// nk_style_pop_style_item(ctx); /// nk_style_pop_vec2(ctx); -/// +/// /// Nuklear has a stack for style_items, float properties, vector properties, /// flags, colors, fonts and for button_behavior. Each has it's own fixed size stack /// which can be changed at compile time. @@ -24032,6 +24036,7 @@ nk_nine_slice_is_sub9slice(const struct nk_nine_slice* slice) * BUTTON * * ===============================================================*/ +#include NK_LIB void nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type, struct nk_rect content, struct nk_color background, struct nk_color foreground, @@ -24080,6 +24085,19 @@ nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type, nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y, foreground); } break; + case NK_SYMBOL_TRIANGLE_UP_OUTLINE: + case NK_SYMBOL_TRIANGLE_DOWN_OUTLINE: + case NK_SYMBOL_TRIANGLE_LEFT_OUTLINE: + case NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE: { + enum nk_heading heading; + struct nk_vec2 points[3]; + heading = (type == NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE) ? NK_RIGHT : + (type == NK_SYMBOL_TRIANGLE_LEFT_OUTLINE) ? NK_LEFT: + (type == NK_SYMBOL_TRIANGLE_UP_OUTLINE) ? NK_UP: NK_DOWN; + nk_triangle_from_direction(points, content, 0, 0, heading); + nk_stroke_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y, + points[2].x, points[2].y, border_width, foreground); + } break; default: case NK_SYMBOL_NONE: case NK_SYMBOL_MAX: break; diff --git a/src/nuklear.h b/src/nuklear.h index 034b9d167..43afb1de1 100644 --- a/src/nuklear.h +++ b/src/nuklear.h @@ -302,6 +302,10 @@ enum nk_symbol_type { NK_SYMBOL_TRIANGLE_RIGHT, NK_SYMBOL_PLUS, NK_SYMBOL_MINUS, + NK_SYMBOL_TRIANGLE_UP_OUTLINE, + NK_SYMBOL_TRIANGLE_DOWN_OUTLINE, + NK_SYMBOL_TRIANGLE_LEFT_OUTLINE, + NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE, NK_SYMBOL_MAX }; /* ============================================================================= @@ -3627,7 +3631,7 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune /// Finally the most complex API wise is using nuklear's font baking API. // /// #### Using your own implementation without vertex buffer output -/// +/// /// So first up the easiest way to do font handling is by just providing a /// `nk_user_font` struct which only requires the height in pixel of the used /// font and a callback to calculate the width of a string. This way of handling @@ -3650,12 +3654,12 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune /// font.userdata.ptr = &your_font_class_or_struct; /// font.height = your_font_height; /// font.width = your_text_width_calculation; -/// +/// /// struct nk_context ctx; /// nk_init_default(&ctx, &font); /// ``` /// #### Using your own implementation with vertex buffer output -/// +/// /// While the first approach works fine if you don't want to use the optional /// vertex buffer output it is not enough if you do. To get font handling working /// for these cases you have to provide two additional parameters inside the @@ -3684,44 +3688,44 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune /// glyph.offset.x = ...; /// glyph.offset.y = ...; /// } -/// +/// /// struct nk_user_font font; /// font.userdata.ptr = &your_font_class_or_struct; /// font.height = your_font_height; /// font.width = your_text_width_calculation; /// font.query = query_your_font_glyph; /// font.texture.id = your_font_texture; -/// +/// /// struct nk_context ctx; /// nk_init_default(&ctx, &font); /// ``` /// /// #### Nuklear font baker -/// +/// /// The final approach if you do not have a font handling functionality or don't /// want to use it in this library is by using the optional font baker. /// The font baker APIs can be used to create a font plus font atlas texture /// and can be used with or without the vertex buffer output. -/// +/// /// It still uses the `nk_user_font` struct and the two different approaches /// previously stated still work. The font baker is not located inside /// `nk_context` like all other systems since it can be understood as more of /// an extension to nuklear and does not really depend on any `nk_context` state. -/// +/// /// Font baker need to be initialized first by one of the nk_font_atlas_init_xxx /// functions. If you don't care about memory just call the default version /// `nk_font_atlas_init_default` which will allocate all memory from the standard library. /// If you want to control memory allocation but you don't care if the allocated /// memory is temporary and therefore can be freed directly after the baking process /// is over or permanent you can call `nk_font_atlas_init`. -/// +/// /// After successfully initializing the font baker you can add Truetype(.ttf) fonts from /// different sources like memory or from file by calling one of the `nk_font_atlas_add_xxx`. /// functions. Adding font will permanently store each font, font config and ttf memory block(!) /// inside the font atlas and allows to reuse the font atlas. If you don't want to reuse /// the font baker by for example adding additional fonts you can call /// `nk_font_atlas_cleanup` after the baking process is over (after calling nk_font_atlas_end). -/// +/// /// As soon as you added all fonts you wanted you can now start the baking process /// for every selected glyph to image by calling `nk_font_atlas_bake`. /// The baking process returns image memory, width and height which can be used to @@ -3732,12 +3736,12 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune /// to your font texture or object and optionally fills a `struct nk_draw_null_texture` /// which can be used for the optional vertex output. If you don't want it just /// set the argument to `NULL`. -/// +/// /// At this point you are done and if you don't want to reuse the font atlas you /// can call `nk_font_atlas_cleanup` to free all truetype blobs and configuration /// memory. Finally if you don't use the font atlas and any of it's fonts anymore /// you need to call `nk_font_atlas_clear` to free all memory still being used. -/// +/// /// ```c /// struct nk_font_atlas atlas; /// nk_font_atlas_init_default(&atlas); @@ -3746,11 +3750,11 @@ NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune /// nk_font *font2 = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font2.ttf", 16, 0); /// const void* img = nk_font_atlas_bake(&atlas, &img_width, &img_height, NK_FONT_ATLAS_RGBA32); /// nk_font_atlas_end(&atlas, nk_handle_id(texture), 0); -/// +/// /// struct nk_context ctx; /// nk_init_default(&ctx, &font->handle); /// while (1) { -/// +/// /// } /// nk_font_atlas_clear(&atlas); /// ``` @@ -3945,7 +3949,7 @@ NK_API void nk_font_atlas_clear(struct nk_font_atlas*); /// not as much control is needed. /// In general all memory inside this library can be provided from the user in /// three different ways. -/// +/// /// The first way and the one providing most control is by just passing a fixed /// size memory block. In this case all control lies in the hand of the user /// since he can exactly control where the memory comes from and how much memory @@ -3954,13 +3958,13 @@ NK_API void nk_font_atlas_clear(struct nk_font_atlas*); /// you have to take over the resizing. While being a fixed sized buffer sounds /// quite limiting, it is very effective in this library since the actual memory /// consumption is quite stable and has a fixed upper bound for a lot of cases. -/// +/// /// If you don't want to think about how much memory the library should allocate /// at all time or have a very dynamic UI with unpredictable memory consumption /// habits but still want control over memory allocation you can use the dynamic /// allocator based API. The allocator consists of two callbacks for allocating /// and freeing memory and optional userdata so you can plugin your own allocator. -/// +/// /// The final and easiest way can be used by defining /// NK_INCLUDE_DEFAULT_ALLOCATOR which uses the standard library memory /// allocation functions malloc and free and takes over complete control over @@ -4215,34 +4219,34 @@ NK_API void nk_textedit_redo(struct nk_text_edit*); /// started. It is probably important to note that the command buffer is the main /// drawing API and the optional vertex buffer API only takes this format and /// converts it into a hardware accessible format. -/// +/// /// To use the command queue to draw your own widgets you can access the /// command buffer of each window by calling `nk_window_get_canvas` after /// previously having called `nk_begin`: -/// +/// /// ```c /// void draw_red_rectangle_widget(struct nk_context *ctx) /// { /// struct nk_command_buffer *canvas; /// struct nk_input *input = &ctx->input; /// canvas = nk_window_get_canvas(ctx); -/// +/// /// struct nk_rect space; /// enum nk_widget_layout_states state; /// state = nk_widget(&space, ctx); /// if (!state) return; -/// +/// /// if (state != NK_WIDGET_ROM) /// update_your_widget_by_user_input(...); /// nk_fill_rect(canvas, space, 0, nk_rgb(255,0,0)); /// } -/// +/// /// if (nk_begin(...)) { /// nk_layout_row_dynamic(ctx, 25, 1); /// draw_red_rectangle_widget(ctx); /// } /// nk_end(..) -/// +/// /// ``` /// Important to know if you want to create your own widgets is the `nk_widget` /// call. It allocates space on the panel reserved for this widget to be used, @@ -4543,7 +4547,7 @@ NK_API nk_bool nk_input_is_key_down(const struct nk_input*, enum nk_keys); /// library since converting the default library draw command output is done by /// just calling `nk_convert` but I decided to still make this library accessible /// since it can be useful. -/// +/// /// The draw list is based on a path buffering and polygon and polyline /// rendering API which allows a lot of ways to draw 2D content to screen. /// In fact it is probably more powerful than needed but allows even more crazy @@ -5359,19 +5363,19 @@ struct nk_window { /// red button you can temporarily push the old button color onto a stack /// draw the button with a red color and then you just pop the old color /// back from the stack: -/// +/// /// nk_style_push_style_item(ctx, &ctx->style.button.normal, nk_style_item_color(nk_rgb(255,0,0))); /// nk_style_push_style_item(ctx, &ctx->style.button.hover, nk_style_item_color(nk_rgb(255,0,0))); /// nk_style_push_style_item(ctx, &ctx->style.button.active, nk_style_item_color(nk_rgb(255,0,0))); /// nk_style_push_vec2(ctx, &cx->style.button.padding, nk_vec2(2,2)); -/// +/// /// nk_button(...); -/// +/// /// nk_style_pop_style_item(ctx); /// nk_style_pop_style_item(ctx); /// nk_style_pop_style_item(ctx); /// nk_style_pop_vec2(ctx); -/// +/// /// Nuklear has a stack for style_items, float properties, vector properties, /// flags, colors, fonts and for button_behavior. Each has it's own fixed size stack /// which can be changed at compile time. diff --git a/src/nuklear_button.c b/src/nuklear_button.c index 655692c42..3752c4a77 100644 --- a/src/nuklear_button.c +++ b/src/nuklear_button.c @@ -6,6 +6,7 @@ * BUTTON * * ===============================================================*/ +#include NK_LIB void nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type, struct nk_rect content, struct nk_color background, struct nk_color foreground, @@ -54,6 +55,19 @@ nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type, nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y, foreground); } break; + case NK_SYMBOL_TRIANGLE_UP_OUTLINE: + case NK_SYMBOL_TRIANGLE_DOWN_OUTLINE: + case NK_SYMBOL_TRIANGLE_LEFT_OUTLINE: + case NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE: { + enum nk_heading heading; + struct nk_vec2 points[3]; + heading = (type == NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE) ? NK_RIGHT : + (type == NK_SYMBOL_TRIANGLE_LEFT_OUTLINE) ? NK_LEFT: + (type == NK_SYMBOL_TRIANGLE_UP_OUTLINE) ? NK_UP: NK_DOWN; + nk_triangle_from_direction(points, content, 0, 0, heading); + nk_stroke_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y, + points[2].x, points[2].y, border_width, foreground); + } break; default: case NK_SYMBOL_NONE: case NK_SYMBOL_MAX: break;