├── .editorconfig
├── .gitignore
├── .gitmodules
├── CMakeLists.txt
├── LICENSE
├── README.md
├── examples
├── CMakeLists.txt
├── LICENSE
├── minshell.html
├── raylib-nuklear-demo.c
├── raylib-nuklear-example.c
├── raylib-nuklear-example.png
├── raylib-nuklear-font-default.c
├── raylib-nuklear-font.c
├── raylib-nuklear-texture.c
└── resources
│ ├── anonymous_pro_bold.ttf
│ └── test-image.png
├── include
├── CMakeLists.txt
├── nuklear.h
├── raylib-nuklear-font.h
└── raylib-nuklear.h
└── test
├── CMakeLists.txt
├── raylib-assert.h
├── raylib-nuklear-test.c
└── resources
├── anonymous_pro_bold.ttf
└── test-image.png
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | charset = utf-8
6 | end_of_line = lf
7 | indent_size = 4
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | .vscode
3 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "vendor/nuklear"]
2 | path = vendor/nuklear
3 | url = https://github.com/Immediate-Mode-UI/Nuklear.git
4 | ignore = dirty
5 | branch = master
6 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.11)
2 | project(raylib_nuklear
3 | DESCRIPTION "raylib_nuklear: Nuklear immediate mode GUI for raylib."
4 | HOMEPAGE_URL "https://github.com/robloach/raylib-nuklear"
5 | VERSION 5.5.0
6 | LANGUAGES C
7 | )
8 |
9 | # raylib-nuklear
10 | add_subdirectory(include)
11 |
12 | # Options
13 | if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
14 | set(RAYLIB_NUKLEAR_IS_MAIN TRUE)
15 | else()
16 | set(RAYLIB_NUKLEAR_IS_MAIN FALSE)
17 | endif()
18 | option(RAYLIB_NUKLEAR_BUILD_EXAMPLES "Examples" ${RAYLIB_NUKLEAR_IS_MAIN})
19 |
20 | # Examples
21 | if (RAYLIB_NUKLEAR_BUILD_EXAMPLES)
22 | add_subdirectory(examples)
23 |
24 | # Testing
25 | include(CTest)
26 | enable_testing()
27 | if (BUILD_TESTING)
28 | # set(CTEST_CUSTOM_TESTS_IGNORE
29 | # pkg-config--static
30 | # )
31 | # Always print verbose output when tests fail if run using `make test`.
32 | list(APPEND CMAKE_CTEST_ARGUMENTS "--output-on-failure")
33 | add_subdirectory(test)
34 | endif()
35 | endif()
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2020 Rob Loach (@RobLoach)
2 |
3 | This software is provided "as-is", without any express or implied warranty. In no event
4 | will the authors be held liable for any damages arising from the use of this software.
5 |
6 | Permission is granted to anyone to use this software for any purpose, including commercial
7 | applications, and to alter it and redistribute it freely, subject to the following restrictions:
8 |
9 | 1. The origin of this software must not be misrepresented; you must not claim that you
10 | wrote the original software. If you use this software in a product, an acknowledgment
11 | in the product documentation would be appreciated but is not required.
12 |
13 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented
14 | as being the original software.
15 |
16 | 3. This notice may not be removed or altered from any source distribution.
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # raylib-nuklear
2 |
3 | Use the [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) immediate mode cross-platform GUI library in [raylib](https://www.raylib.com/).
4 |
5 | [](examples)
6 |
7 | ## Usage
8 |
9 | 1. Since this is a header-only library, you must first define `RAYLIB_NUKLEAR_IMPLEMENTATION` in one of your `.c` files...
10 | ``` c
11 | #define RAYLIB_NUKLEAR_IMPLEMENTATION
12 | ```
13 | 2. Include the [`raylib-nuklear.h`](include/raylib-nuklear.h) file...
14 | ``` c
15 | #include "path/to/raylib-nuklear.h"
16 | ```
17 | 3. Use `InitNuklear(fontSize)` or `InitNuklearEx(font, fontSize)` to create the nuklear context...
18 | ``` c
19 | struct nk_context *ctx = InitNuklear(10);
20 | ```
21 | 4. Build your Nuklear GUI through the standard [Nuklear API](https://github.com/Immediate-Mode-UI/Nuklear/wiki/Window)
22 | 5. Update the input for the GUI using `UpdateNuklear(ctx)`
23 | 6. Render the context using `DrawNuklear(ctx)`
24 | 7. Destroy the nuklear context with `UnloadNuklear(ctx)`
25 |
26 | ## Example
27 |
28 | ``` c
29 | #define RAYLIB_NUKLEAR_IMPLEMENTATION
30 | #include "raylib-nuklear.h"
31 |
32 | int main() {
33 | InitWindow(640, 480, "raylib-nuklear example");
34 |
35 | // Create the Nuklear Context
36 | int fontSize = 10;
37 | struct nk_context *ctx = InitNuklear(fontSize);
38 |
39 | while (!WindowShouldClose()) {
40 | // Update the Nuklear context, along with input
41 | UpdateNuklear(ctx);
42 |
43 | // Nuklear GUI Code
44 | // https://github.com/Immediate-Mode-UI/Nuklear/wiki/Window
45 | if (nk_begin(ctx, "Nuklear", nk_rect(100, 100, 220, 220),
46 | NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) {
47 | nk_layout_row_static(ctx, 50, 150, 1);
48 | if (nk_button_label(ctx, "Button")) {
49 | // Button was clicked!
50 | }
51 | }
52 | nk_end(ctx);
53 |
54 | // Render
55 | BeginDrawing();
56 | ClearBackground(RAYWHITE);
57 |
58 | // Render the Nuklear GUI
59 | DrawNuklear(ctx);
60 |
61 | EndDrawing();
62 | }
63 |
64 | // De-initialize the Nuklear GUI
65 | UnloadNuklear(ctx);
66 |
67 | CloseWindow();
68 | return 0;
69 | }
70 | ```
71 |
72 | ## API
73 |
74 | ``` c
75 | struct nk_context* InitNuklear(int fontSize); // Initialize the Nuklear GUI context using raylib's font
76 | struct nk_context* InitNuklearEx(Font font, float fontSize); // Initialize the Nuklear GUI context, with a custom font
77 | Font LoadFontFromNuklear(int fontSize); // Loads the default Nuklear font
78 | void UpdateNuklear(struct nk_context * ctx); // Update the input state and internal components for Nuklear
79 | void UpdateNuklearEx(struct nk_context * ctx, float deltaTime); // Update the input state and internal components for Nuklear, with a custom frame time
80 | void DrawNuklear(struct nk_context * ctx); // Render the Nuklear GUI on the screen
81 | void UnloadNuklear(struct nk_context * ctx); // Deinitialize the Nuklear context
82 | struct nk_color ColorToNuklear(Color color); // Convert a raylib Color to a Nuklear color object
83 | struct nk_colorf ColorToNuklearF(Color color); // Convert a raylib Color to a Nuklear floating color
84 | struct Color ColorFromNuklear(struct nk_color color); // Convert a Nuklear color to a raylib Color
85 | struct Color ColorFromNuklearF(struct nk_colorf color); // Convert a Nuklear floating color to a raylib Color
86 | struct Rectangle RectangleFromNuklear(struct nk_context * ctx, struct nk_rect rect); // Convert a Nuklear rectangle to a raylib Rectangle
87 | struct nk_rect RectangleToNuklear(struct nk_context * ctx, Rectangle rect); // Convert a raylib Rectangle to a Nuklear Rectangle
88 | struct nk_image TextureToNuklear(Texture tex); // Convert a raylib Texture to A Nuklear image
89 | struct Texture TextureFromNuklear(struct nk_image img); // Convert a Nuklear image to a raylib Texture
90 | struct nk_image LoadNuklearImage(const char* path); // Load a Nuklear image
91 | void UnloadNuklearImage(struct nk_image img); // Unload a Nuklear image. And free its data
92 | void CleanupNuklearImage(struct nk_image img); // Frees the data stored by the Nuklear image
93 | void SetNuklearScaling(struct nk_context * ctx, float scaling); // Sets the scaling for the given Nuklear context
94 | float GetNuklearScaling(struct nk_context * ctx); // Retrieves the scaling of the given Nuklear context
95 | ```
96 |
97 | See the [Nuklear API documenation](https://immediate-mode-ui.github.io/Nuklear/doc/nuklear.html) for more how to use Nuklear.
98 |
99 | ## Comparision
100 |
101 | There are a few other graphical user interface solutions out there for use with raylib. [raygui](https://github.com/raysan5/raygui), [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear), and [ImGui](https://github.com/ocornut/imgui) with [rlImGui](https://github.com/raylib-extras/rlImGui), are popular choices. It's best to choose the GUI that fits your needs best. Generally, if you're unsure which GUI to use with raylib, use [raygui](https://github.com/raysan5/raygui).
102 |
103 | | | [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) | [raygui](https://github.com/raysan5/raygui) | [rlImGui](https://github.com/raylib-extras/rlImGui) |
104 | | ----- |:-------:|:------:|:-----:|
105 | | Only C | :white_check_mark: | :white_check_mark: | C++ |
106 | | Minimal Dependencies | :white_check_mark: | :white_check_mark: | :x: |
107 | | Automatic Layouts | :white_check_mark: | :x: | :white_check_mark: |
108 | | Advanced Controls | :white_check_mark: | :x: | :white_check_mark: |
109 | | Documentation | :white_check_mark: | :x: | :white_check_mark: |
110 | | Industry Standard | :x: | :x: | :white_check_mark: |
111 | | Easy to Use | :x: | :white_check_mark: | :x: |
112 |
113 | ## Development
114 |
115 | While this project uses CMake, CMake is not required in order to use *raylib-nuklear*.
116 |
117 | ```
118 | git submodule update --init
119 | mkdir build
120 | cd build
121 | cmake ..
122 | make
123 | ./example/raylib-nuklear-example
124 | make test
125 | ```
126 |
127 | ## License
128 |
129 | *raylib-nuklear* is licensed under an unmodified zlib/libpng license, which is an OSI-certified, BSD-like license that allows static linking with closed source software. Check [LICENSE](LICENSE) for further details.
130 |
--------------------------------------------------------------------------------
/examples/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # raylib
2 | find_package(raylib QUIET)
3 | if (NOT raylib_FOUND)
4 | include(FetchContent)
5 | FetchContent_Declare(
6 | raylib
7 | GIT_REPOSITORY https://github.com/raysan5/raylib.git
8 | GIT_TAG 5.5
9 | GIT_SHALLOW 1
10 | )
11 | FetchContent_GetProperties(raylib)
12 | if (NOT raylib_POPULATED) # Have we downloaded raylib yet?
13 | set(FETCHCONTENT_QUIET NO)
14 | FetchContent_Populate(raylib)
15 | set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
16 | set(BUILD_GAMES OFF CACHE BOOL "" FORCE)
17 | add_subdirectory(${raylib_SOURCE_DIR} ${raylib_BINARY_DIR})
18 | endif()
19 | endif()
20 |
21 | # raylib-nuklear-example
22 | add_executable(raylib-nuklear-example
23 | raylib-nuklear-example.c
24 | )
25 | target_link_libraries(raylib-nuklear-example PUBLIC
26 | raylib
27 | raylib_nuklear
28 | )
29 |
30 | # raylib-nuklear-demo
31 | add_executable(raylib-nuklear-demo
32 | raylib-nuklear-demo.c
33 | )
34 | target_link_libraries(raylib-nuklear-demo PUBLIC
35 | raylib
36 | raylib_nuklear
37 | )
38 |
39 | # raylib-nuklear-font
40 | add_executable(raylib-nuklear-font
41 | raylib-nuklear-font.c
42 | )
43 | target_link_libraries(raylib-nuklear-font PUBLIC
44 | raylib
45 | raylib_nuklear
46 | )
47 |
48 | # raylib-nuklear-font
49 | add_executable(raylib-nuklear-font-default
50 | raylib-nuklear-font-default.c
51 | )
52 | target_link_libraries(raylib-nuklear-font-default PUBLIC
53 | raylib
54 | raylib_nuklear
55 | )
56 |
57 | # raylib-nuklear-texture
58 | add_executable(raylib-nuklear-texture
59 | raylib-nuklear-texture.c
60 | )
61 | target_link_libraries(raylib-nuklear-texture PUBLIC
62 | raylib
63 | raylib_nuklear
64 | )
65 |
66 | # Target C99
67 | set_property(TARGET raylib-nuklear-example PROPERTY C_STANDARD 99)
68 | set_property(TARGET raylib-nuklear-demo PROPERTY C_STANDARD 99)
69 | set_property(TARGET raylib-nuklear-font PROPERTY C_STANDARD 99)
70 | set_property(TARGET raylib-nuklear-texture PROPERTY C_STANDARD 99)
71 |
72 | # Enable warnings
73 | if(MSVC)
74 | target_compile_options(raylib-nuklear-example PRIVATE /W4 /WX)
75 | target_compile_options(raylib-nuklear-demo PRIVATE /W4 /WX)
76 | target_compile_options(raylib-nuklear-font PRIVATE /W4 /WX)
77 | target_compile_options(raylib-nuklear-texture PRIVATE /W4 /WX)
78 | else()
79 | target_compile_options(raylib-nuklear-example PRIVATE -Wall -Wextra -Wpedantic -Werror)
80 | target_compile_options(raylib-nuklear-demo PRIVATE -Wall -Wextra -Wpedantic -Werror)
81 | target_compile_options(raylib-nuklear-font PRIVATE -Wall -Wextra -Wpedantic -Werror)
82 | target_compile_options(raylib-nuklear-texture PRIVATE -Wall -Wextra -Wpedantic -Werror)
83 | endif()
84 |
85 | # Resources
86 | configure_file(resources/anonymous_pro_bold.ttf resources/anonymous_pro_bold.ttf COPYONLY)
87 | configure_file(resources/test-image.png resources/test-image.png COPYONLY)
88 |
89 | # Web Configurations
90 | #if (${PLATFORM} STREQUAL "Web")
91 | if (EMSCRIPTEN)
92 | # Tell Emscripten to build an example.html file.
93 | set_target_properties(raylib-nuklear-demo PROPERTIES SUFFIX ".html")
94 | set_target_properties(raylib-nuklear-demo PROPERTIES OUTPUT_NAME "index")
95 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --shell-file ${CMAKE_CURRENT_SOURCE_DIR}/minshell.html")
96 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_GLFW=3")
97 | add_definitions(-DPLATFORM=Web)
98 | add_definitions(-DCMAKE_BUILD_TYPE=Release)
99 | endif()
100 |
--------------------------------------------------------------------------------
/examples/LICENSE:
--------------------------------------------------------------------------------
1 | Fonts used in examples are provided under a free and permissive license.
2 | Check individual licenses for details:
3 |
4 | - [Anonymous Pro] by Mark Simonson - https://fonts.google.com/specimen/Anonymous+Pro
5 |
--------------------------------------------------------------------------------
/examples/minshell.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | raylib-nuklear: Demo
7 |
8 |
9 |
10 |
28 |
29 |
30 |
31 |
32 |
33 |
47 | {{{ SCRIPT }}}
48 |
49 |
50 |
--------------------------------------------------------------------------------
/examples/raylib-nuklear-demo.c:
--------------------------------------------------------------------------------
1 | /* nuklear - 1.32.0 - public domain */
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include "raylib.h"
14 |
15 | #if defined(PLATFORM_WEB)
16 | #include
17 | #endif
18 |
19 | //#define NK_INCLUDE_FIXED_TYPES
20 | //#define NK_INCLUDE_STANDARD_IO
21 | #define NK_INCLUDE_STANDARD_VARARGS
22 | //#define NK_INCLUDE_DEFAULT_ALLOCATOR
23 | //#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
24 | //#define NK_INCLUDE_FONT_BAKING
25 | //#define NK_INCLUDE_DEFAULT_FONT
26 | #define RAYLIB_NUKLEAR_IMPLEMENTATION
27 | #define RAYLIB_NUKLEAR_INCLUDE_DEFAULT_FONT
28 | #include "raylib-nuklear.h"
29 |
30 | #define WINDOW_WIDTH 1200
31 | #define WINDOW_HEIGHT 800
32 |
33 | /* ===============================================================
34 | *
35 | * EXAMPLE
36 | *
37 | * ===============================================================*/
38 | /* This are some code examples to provide a small overview of what can be
39 | * done with this library. To try out an example uncomment the defines */
40 | #define INCLUDE_ALL
41 | /*#define INCLUDE_STYLE */
42 | /*#define INCLUDE_CALCULATOR */
43 | /*#define INCLUDE_CANVAS */
44 | /*#define INCLUDE_OVERVIEW */
45 | /*#define INCLUDE_NODE_EDITOR */
46 |
47 | #ifdef INCLUDE_ALL
48 | //#define INCLUDE_STYLE
49 | #define INCLUDE_CALCULATOR
50 | #define INCLUDE_CANVAS
51 | #define INCLUDE_OVERVIEW
52 | //#define INCLUDE_NODE_EDITOR
53 | #endif
54 |
55 | #ifdef INCLUDE_STYLE
56 | #include "../vendor/nuklear/demo/style.c"
57 | #endif
58 | #ifdef INCLUDE_CALCULATOR
59 | #include "../vendor/nuklear/demo/common/calculator.c"
60 | #endif
61 | #ifdef INCLUDE_CANVAS
62 | #include "../vendor/nuklear/demo/common/canvas.c"
63 | #endif
64 | #ifdef INCLUDE_OVERVIEW
65 | #include "../vendor/nuklear/demo/common/overview.c"
66 | #endif
67 | #ifdef INCLUDE_NODE_EDITOR
68 | #include "../vendor/nuklear/demo/common/node_editor.c"
69 | #endif
70 |
71 | //----------------------------------------------------------------------------------
72 | // Global Variables Definition
73 | //----------------------------------------------------------------------------------
74 | struct nk_context *ctx;
75 | struct nk_colorf bg;
76 |
77 | //----------------------------------------------------------------------------------
78 | // Module Functions Declaration
79 | //----------------------------------------------------------------------------------
80 | void UpdateDrawFrame(void); // Update and Draw one frame
81 |
82 | //----------------------------------------------------------------------------------
83 | // Main Entry Point
84 | //----------------------------------------------------------------------------------
85 | int main(void) {
86 | // Initialization
87 | //--------------------------------------------------------------------------------------
88 | InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "[raylib-nuklear] demo");
89 | SetTargetFPS(60);
90 |
91 | /* GUI */
92 | const int fontSize = 13;
93 | Font font = LoadFontFromNuklear(fontSize);
94 | ctx = InitNuklearEx(font, fontSize);
95 | bg.r = 0.10f, bg.g = 0.18f, bg.b = 0.24f, bg.a = 1.0f;
96 |
97 | /* style.c */
98 | #ifdef INCLUDE_STYLE
99 | /*set_style(ctx, THEME_WHITE);*/
100 | /*set_style(ctx, THEME_RED);*/
101 | /*set_style(ctx, THEME_BLUE);*/
102 | /*set_style(ctx, THEME_DARK);*/
103 | #endif
104 |
105 | //--------------------------------------------------------------------------------------
106 |
107 | // Main game loop
108 | #if defined(PLATFORM_WEB)
109 | emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
110 | #else
111 | while (!WindowShouldClose()) // Detect window close button or ESC key
112 | {
113 | UpdateDrawFrame();
114 | }
115 | #endif
116 | //--------------------------------------------------------------------------------------
117 |
118 | // De-Initialization
119 | //--------------------------------------------------------------------------------------
120 | UnloadNuklear(ctx); // Unload the Nuklear GUI
121 | CloseWindow();
122 | //--------------------------------------------------------------------------------------
123 |
124 | return 0;
125 | }
126 |
127 |
128 | void UpdateDrawFrame(void) {
129 | /* Input */
130 | UpdateNuklear(ctx);
131 |
132 | /* GUI */
133 | if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250),
134 | NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
135 | NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
136 | {
137 | enum {EASY, HARD};
138 | static int op = EASY;
139 | static int property = 20;
140 |
141 | nk_layout_row_static(ctx, 30, 80, 1);
142 | if (nk_button_label(ctx, "button"))
143 | TraceLog(LOG_INFO, "button pressed!");
144 | nk_layout_row_dynamic(ctx, 30, 2);
145 | if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
146 | if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;
147 | nk_layout_row_dynamic(ctx, 22, 1);
148 | nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
149 |
150 | nk_layout_row_dynamic(ctx, 20, 1);
151 | nk_label(ctx, "background:", NK_TEXT_LEFT);
152 | nk_layout_row_dynamic(ctx, 25, 1);
153 | if (nk_combo_begin_color(ctx, nk_rgb_cf(bg), nk_vec2(nk_widget_width(ctx),400))) {
154 | nk_layout_row_dynamic(ctx, 120, 1);
155 | bg = nk_color_picker(ctx, bg, NK_RGBA);
156 | nk_layout_row_dynamic(ctx, 25, 1);
157 | bg.r = nk_propertyf(ctx, "#R:", 0, bg.r, 1.0f, 0.01f,0.005f);
158 | bg.g = nk_propertyf(ctx, "#G:", 0, bg.g, 1.0f, 0.01f,0.005f);
159 | bg.b = nk_propertyf(ctx, "#B:", 0, bg.b, 1.0f, 0.01f,0.005f);
160 | bg.a = nk_propertyf(ctx, "#A:", 0, bg.a, 1.0f, 0.01f,0.005f);
161 | nk_combo_end(ctx);
162 | }
163 | }
164 | nk_end(ctx);
165 |
166 | /* -------------- EXAMPLES ---------------- */
167 | #ifdef INCLUDE_CALCULATOR
168 | calculator(ctx);
169 | #endif
170 | #ifdef INCLUDE_CANVAS
171 | canvas(ctx);
172 | #endif
173 | #ifdef INCLUDE_OVERVIEW
174 | overview(ctx);
175 | #endif
176 | #ifdef INCLUDE_NODE_EDITOR
177 | node_editor(ctx);
178 | #endif
179 | /* ----------------------------------------- */
180 |
181 | /* Draw */
182 | BeginDrawing();
183 | {
184 | ClearBackground(ColorFromNuklearF(bg));
185 | DrawNuklear(ctx);
186 | }
187 | EndDrawing();
188 | }
189 |
--------------------------------------------------------------------------------
/examples/raylib-nuklear-example.c:
--------------------------------------------------------------------------------
1 | /**********************************************************************************************
2 | *
3 | * raylib-nuklear-example - Example of using Nuklear with Raylib.
4 | *
5 | * LICENSE: zlib/libpng
6 | *
7 | * nuklear_raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
8 | * BSD-like license that allows static linking with closed source software:
9 | *
10 | * Copyright (c) 2020 Rob Loach (@RobLoach)
11 | *
12 | * This software is provided "as-is", without any express or implied warranty. In no event
13 | * will the authors be held liable for any damages arising from the use of this software.
14 | *
15 | * Permission is granted to anyone to use this software for any purpose, including commercial
16 | * applications, and to alter it and redistribute it freely, subject to the following restrictions:
17 | *
18 | * 1. The origin of this software must not be misrepresented; you must not claim that you
19 | * wrote the original software. If you use this software in a product, an acknowledgment
20 | * in the product documentation would be appreciated but is not required.
21 | *
22 | * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
23 | * as being the original software.
24 | *
25 | * 3. This notice may not be removed or altered from any source distribution.
26 | *
27 | **********************************************************************************************/
28 |
29 | #include "raylib.h"
30 |
31 | #define RAYLIB_NUKLEAR_IMPLEMENTATION
32 | #include "raylib-nuklear.h"
33 |
34 | int main(void)
35 | {
36 | // Initialization
37 | //--------------------------------------------------------------------------------------
38 | const int screenWidth = 700;
39 | const int screenHeight = 394;
40 | InitWindow(screenWidth, screenHeight, "[raylib-nuklear] example");
41 |
42 | SetTargetFPS(60); // Set our game to run at 60 frames-per-second
43 | //--------------------------------------------------------------------------------------
44 |
45 | /* GUI */
46 | struct nk_colorf bg = ColorToNuklearF(SKYBLUE);
47 | struct nk_context *ctx = InitNuklear(0);
48 |
49 | // Main game loop
50 | while (!WindowShouldClose()) // Detect window close button or ESC key
51 | {
52 | // Update
53 | UpdateNuklear(ctx);
54 |
55 | // GUI
56 | if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250),
57 | NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
58 | NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
59 | {
60 | enum {EASY, HARD};
61 | static int op = EASY;
62 | static int property = 20;
63 | nk_layout_row_static(ctx, 30, 80, 1);
64 | if (nk_button_label(ctx, "button"))
65 | TraceLog(LOG_INFO, "button pressed");
66 |
67 | nk_layout_row_dynamic(ctx, 30, 2);
68 | if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
69 | if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;
70 |
71 | nk_layout_row_dynamic(ctx, 25, 1);
72 | nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
73 |
74 | nk_layout_row_dynamic(ctx, 20, 1);
75 | nk_label(ctx, "background:", NK_TEXT_LEFT);
76 | nk_layout_row_dynamic(ctx, 25, 1);
77 | if (nk_combo_begin_color(ctx, nk_rgb_cf(bg), nk_vec2(nk_widget_width(ctx),400))) {
78 | nk_layout_row_dynamic(ctx, 120, 1);
79 | bg = nk_color_picker(ctx, bg, NK_RGBA);
80 | nk_layout_row_dynamic(ctx, 25, 1);
81 | bg.r = nk_propertyf(ctx, "#R:", 0, bg.r, 1.0f, 0.01f,0.005f);
82 | bg.g = nk_propertyf(ctx, "#G:", 0, bg.g, 1.0f, 0.01f,0.005f);
83 | bg.b = nk_propertyf(ctx, "#B:", 0, bg.b, 1.0f, 0.01f,0.005f);
84 | bg.a = nk_propertyf(ctx, "#A:", 0, bg.a, 1.0f, 0.01f,0.005f);
85 | nk_combo_end(ctx);
86 | }
87 | }
88 |
89 | nk_end(ctx);
90 |
91 | // Draw
92 | //----------------------------------------------------------------------------------
93 | BeginDrawing();
94 |
95 | ClearBackground(ColorFromNuklearF(bg));
96 |
97 | DrawNuklear(ctx);
98 |
99 | EndDrawing();
100 | //----------------------------------------------------------------------------------
101 | }
102 |
103 | // De-Initialization
104 | //--------------------------------------------------------------------------------------
105 | UnloadNuklear(ctx); // Unload the Nuklear GUI
106 | CloseWindow();
107 | //--------------------------------------------------------------------------------------
108 |
109 | return 0;
110 | }
111 |
--------------------------------------------------------------------------------
/examples/raylib-nuklear-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobLoach/raylib-nuklear/d2bd2b7b3cef4831c0a57ee1b0e11a76a9fe1c19/examples/raylib-nuklear-example.png
--------------------------------------------------------------------------------
/examples/raylib-nuklear-font-default.c:
--------------------------------------------------------------------------------
1 | /**********************************************************************************************
2 | *
3 | * raylib-nuklear-font - Example of using Nuklear with a custom Raylib font.
4 | *
5 | * LICENSE: zlib/libpng
6 | *
7 | * raylib-nuklear is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
8 | * BSD-like license that allows static linking with closed source software:
9 | *
10 | * Copyright (c) 2020 Rob Loach (@RobLoach)
11 | *
12 | * This software is provided "as-is", without any express or implied warranty. In no event
13 | * will the authors be held liable for any damages arising from the use of this software.
14 | *
15 | * Permission is granted to anyone to use this software for any purpose, including commercial
16 | * applications, and to alter it and redistribute it freely, subject to the following restrictions:
17 | *
18 | * 1. The origin of this software must not be misrepresented; you must not claim that you
19 | * wrote the original software. If you use this software in a product, an acknowledgment
20 | * in the product documentation would be appreciated but is not required.
21 | *
22 | * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
23 | * as being the original software.
24 | *
25 | * 3. This notice may not be removed or altered from any source distribution.
26 | *
27 | **********************************************************************************************/
28 |
29 | #include "raylib.h"
30 |
31 | #define RAYLIB_NUKLEAR_IMPLEMENTATION
32 | #define RAYLIB_NUKLEAR_INCLUDE_DEFAULT_FONT
33 | #include "raylib-nuklear.h"
34 |
35 | int main(void)
36 | {
37 | // Initialization
38 | //--------------------------------------------------------------------------------------
39 | const int screenWidth = 800;
40 | const int screenHeight = 450;
41 | const int fontSize = 14;
42 |
43 | InitWindow(screenWidth, screenHeight, "[raylib-nuklear] font example");
44 | Font font = LoadFontFromNuklear(0);
45 |
46 | SetTargetFPS(60); // Set our game to run at 60 frames-per-second
47 | //--------------------------------------------------------------------------------------
48 |
49 | /* GUI */
50 | struct nk_colorf bg = ColorToNuklearF(SKYBLUE);
51 | struct nk_context *ctx = InitNuklearEx(font, 0);
52 |
53 | // Main game loop
54 | while (!WindowShouldClose()) // Detect window close button or ESC key
55 | {
56 | // Update
57 | UpdateNuklear(ctx);
58 |
59 | // GUI
60 | if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250),
61 | NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
62 | NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
63 | {
64 | enum {EASY, HARD};
65 | static int op = EASY;
66 | static int property = 20;
67 | nk_layout_row_static(ctx, 30, 80, 1);
68 | if (nk_button_label(ctx, "button"))
69 | TraceLog(LOG_INFO, "button pressed");
70 |
71 | nk_layout_row_dynamic(ctx, 30, 2);
72 | if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
73 | if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;
74 |
75 | nk_layout_row_dynamic(ctx, 25, 1);
76 | nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
77 |
78 | nk_layout_row_dynamic(ctx, 20, 1);
79 | nk_label(ctx, "background:", NK_TEXT_LEFT);
80 | nk_layout_row_dynamic(ctx, 25, 1);
81 | if (nk_combo_begin_color(ctx, nk_rgb_cf(bg), nk_vec2(nk_widget_width(ctx),400))) {
82 | nk_layout_row_dynamic(ctx, 120, 1);
83 | bg = nk_color_picker(ctx, bg, NK_RGBA);
84 | nk_layout_row_dynamic(ctx, 25, 1);
85 | bg.r = nk_propertyf(ctx, "#R:", 0, bg.r, 1.0f, 0.01f,0.005f);
86 | bg.g = nk_propertyf(ctx, "#G:", 0, bg.g, 1.0f, 0.01f,0.005f);
87 | bg.b = nk_propertyf(ctx, "#B:", 0, bg.b, 1.0f, 0.01f,0.005f);
88 | bg.a = nk_propertyf(ctx, "#A:", 0, bg.a, 1.0f, 0.01f,0.005f);
89 | nk_combo_end(ctx);
90 | }
91 | }
92 |
93 | nk_end(ctx);
94 |
95 | // Draw
96 | //----------------------------------------------------------------------------------
97 | BeginDrawing();
98 |
99 | ClearBackground(ColorFromNuklearF(bg));
100 |
101 | DrawNuklear(ctx);
102 |
103 | EndDrawing();
104 | //----------------------------------------------------------------------------------
105 | }
106 |
107 | // De-Initialization
108 | //--------------------------------------------------------------------------------------
109 | UnloadNuklear(ctx); // Unload the Nuklear GUI
110 | UnloadFont(font);
111 | CloseWindow();
112 | //--------------------------------------------------------------------------------------
113 |
114 | return 0;
115 | }
116 |
--------------------------------------------------------------------------------
/examples/raylib-nuklear-font.c:
--------------------------------------------------------------------------------
1 | /**********************************************************************************************
2 | *
3 | * raylib-nuklear-font - Example of using Nuklear with a custom Raylib font.
4 | *
5 | * LICENSE: zlib/libpng
6 | *
7 | * raylib-nuklear is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
8 | * BSD-like license that allows static linking with closed source software:
9 | *
10 | * Copyright (c) 2020 Rob Loach (@RobLoach)
11 | *
12 | * This software is provided "as-is", without any express or implied warranty. In no event
13 | * will the authors be held liable for any damages arising from the use of this software.
14 | *
15 | * Permission is granted to anyone to use this software for any purpose, including commercial
16 | * applications, and to alter it and redistribute it freely, subject to the following restrictions:
17 | *
18 | * 1. The origin of this software must not be misrepresented; you must not claim that you
19 | * wrote the original software. If you use this software in a product, an acknowledgment
20 | * in the product documentation would be appreciated but is not required.
21 | *
22 | * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
23 | * as being the original software.
24 | *
25 | * 3. This notice may not be removed or altered from any source distribution.
26 | *
27 | **********************************************************************************************/
28 |
29 | #include "raylib.h"
30 |
31 | #define RAYLIB_NUKLEAR_IMPLEMENTATION
32 | #include "raylib-nuklear.h"
33 |
34 | int main(void)
35 | {
36 | // Initialization
37 | //--------------------------------------------------------------------------------------
38 | const int screenWidth = 800;
39 | const int screenHeight = 450;
40 | const int fontSize = 18;
41 |
42 | InitWindow(screenWidth, screenHeight, "[raylib-nuklear] font example");
43 | Font font = LoadFontEx("resources/anonymous_pro_bold.ttf", fontSize, NULL, 0);
44 |
45 | SetTargetFPS(60); // Set our game to run at 60 frames-per-second
46 | //--------------------------------------------------------------------------------------
47 |
48 | /* GUI */
49 | struct nk_colorf bg = ColorToNuklearF(SKYBLUE);
50 | struct nk_context *ctx = InitNuklearEx(font, fontSize);
51 |
52 | // Main game loop
53 | while (!WindowShouldClose()) // Detect window close button or ESC key
54 | {
55 | // Update
56 | UpdateNuklear(ctx);
57 |
58 | // GUI
59 | if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250),
60 | NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
61 | NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
62 | {
63 | enum {EASY, HARD};
64 | static int op = EASY;
65 | static int property = 20;
66 | nk_layout_row_static(ctx, 30, 80, 1);
67 | if (nk_button_label(ctx, "button"))
68 | TraceLog(LOG_INFO, "button pressed");
69 |
70 | nk_layout_row_dynamic(ctx, 30, 2);
71 | if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
72 | if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;
73 |
74 | nk_layout_row_dynamic(ctx, 25, 1);
75 | nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
76 |
77 | nk_layout_row_dynamic(ctx, 20, 1);
78 | nk_label(ctx, "background:", NK_TEXT_LEFT);
79 | nk_layout_row_dynamic(ctx, 25, 1);
80 | if (nk_combo_begin_color(ctx, nk_rgb_cf(bg), nk_vec2(nk_widget_width(ctx),400))) {
81 | nk_layout_row_dynamic(ctx, 120, 1);
82 | bg = nk_color_picker(ctx, bg, NK_RGBA);
83 | nk_layout_row_dynamic(ctx, 25, 1);
84 | bg.r = nk_propertyf(ctx, "#R:", 0, bg.r, 1.0f, 0.01f,0.005f);
85 | bg.g = nk_propertyf(ctx, "#G:", 0, bg.g, 1.0f, 0.01f,0.005f);
86 | bg.b = nk_propertyf(ctx, "#B:", 0, bg.b, 1.0f, 0.01f,0.005f);
87 | bg.a = nk_propertyf(ctx, "#A:", 0, bg.a, 1.0f, 0.01f,0.005f);
88 | nk_combo_end(ctx);
89 | }
90 | }
91 |
92 | nk_end(ctx);
93 |
94 | // Draw
95 | //----------------------------------------------------------------------------------
96 | BeginDrawing();
97 |
98 | ClearBackground(ColorFromNuklearF(bg));
99 |
100 | DrawNuklear(ctx);
101 |
102 | EndDrawing();
103 | //----------------------------------------------------------------------------------
104 | }
105 |
106 | // De-Initialization
107 | //--------------------------------------------------------------------------------------
108 | UnloadNuklear(ctx); // Unload the Nuklear GUI
109 | UnloadFont(font);
110 | CloseWindow();
111 | //--------------------------------------------------------------------------------------
112 |
113 | return 0;
114 | }
115 |
--------------------------------------------------------------------------------
/examples/raylib-nuklear-texture.c:
--------------------------------------------------------------------------------
1 | /* ===============================================================
2 | *
3 | * EXAMPLE
4 | *
5 | * ===============================================================*/
6 | /*
7 | This example shows how to use the image API from raylib nuklear.
8 | And then display it.
9 | */
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #define RAYLIB_NUKLEAR_IMPLEMENTATION
16 | #include "raylib-nuklear.h"
17 |
18 | int main(void)
19 | {
20 | InitWindow(1280, 720, "[raylib-nuklear] - Texture/Image");
21 |
22 | // Initialize the context
23 | struct nk_context* ctx = InitNuklear(20);
24 |
25 | // Scale up the Nuklear GUI
26 | SetNuklearScaling(ctx, 1.2f);
27 |
28 | // Load the nk_image
29 | struct nk_image img = LoadNuklearImage("resources/test-image.png");
30 |
31 | while (!WindowShouldClose())
32 | {
33 | // Input
34 | UpdateNuklear(ctx);
35 |
36 | // The window called "Image example" is opend
37 | if(nk_begin(ctx, "Image example", nk_rect(300, 100, img.w, img.h + 50), NK_WINDOW_MINIMIZABLE|NK_WINDOW_BORDER|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE))
38 | {
39 | // Setup the layout
40 | nk_layout_row_static(ctx, img.h, img.w, 1);
41 |
42 | // Draw the image
43 | nk_image(ctx, img);
44 | }
45 | nk_end(ctx);
46 |
47 | // Draw the GUI
48 | BeginDrawing();
49 | ClearBackground(RAYWHITE);
50 | DrawNuklear(ctx);
51 | EndDrawing();
52 | }
53 |
54 | // Unload the Nuklear image
55 | UnloadNuklearImage(img);
56 |
57 | CloseWindow();
58 | return 0;
59 | }
60 |
--------------------------------------------------------------------------------
/examples/resources/anonymous_pro_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobLoach/raylib-nuklear/d2bd2b7b3cef4831c0a57ee1b0e11a76a9fe1c19/examples/resources/anonymous_pro_bold.ttf
--------------------------------------------------------------------------------
/examples/resources/test-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobLoach/raylib-nuklear/d2bd2b7b3cef4831c0a57ee1b0e11a76a9fe1c19/examples/resources/test-image.png
--------------------------------------------------------------------------------
/include/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # raylib_nuklear
2 | add_library(raylib_nuklear INTERFACE)
3 | target_include_directories(raylib_nuklear INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
4 | install(FILES
5 | raylib-nuklear.h
6 | raylib-nuklear-font.h
7 | nuklear.h
8 | DESTINATION include
9 | )
10 |
--------------------------------------------------------------------------------
/include/raylib-nuklear.h:
--------------------------------------------------------------------------------
1 | /**********************************************************************************************
2 | *
3 | * raylib-nuklear v5.5.0 - Nuklear GUI for Raylib.
4 | *
5 | * FEATURES:
6 | * - Use the Nuklear immediate-mode graphical user interface in raylib.
7 | *
8 | * DEPENDENCIES:
9 | * - raylib 5.5+ https://www.raylib.com/
10 | * - Nuklear https://github.com/Immediate-Mode-UI/Nuklear
11 | *
12 | * LICENSE: zlib/libpng
13 | *
14 | * raylib-nuklear is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
15 | * BSD-like license that allows static linking with closed source software:
16 | *
17 | * Copyright (c) 2020 Rob Loach (@RobLoach)
18 | *
19 | * This software is provided "as-is", without any express or implied warranty. In no event
20 | * will the authors be held liable for any damages arising from the use of this software.
21 | *
22 | * Permission is granted to anyone to use this software for any purpose, including commercial
23 | * applications, and to alter it and redistribute it freely, subject to the following restrictions:
24 | *
25 | * 1. The origin of this software must not be misrepresented; you must not claim that you
26 | * wrote the original software. If you use this software in a product, an acknowledgment
27 | * in the product documentation would be appreciated but is not required.
28 | *
29 | * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
30 | * as being the original software.
31 | *
32 | * 3. This notice may not be removed or altered from any source distribution.
33 | *
34 | **********************************************************************************************/
35 |
36 | #ifndef RAYLIB_NUKLEAR_H
37 | #define RAYLIB_NUKLEAR_H
38 |
39 | #include "raylib.h"
40 |
41 | // Nuklear defines
42 | #define NK_INCLUDE_FIXED_TYPES
43 | #define NK_INCLUDE_STANDARD_VARARGS
44 | #define NK_INCLUDE_STANDARD_BOOL
45 | #define NK_INCLUDE_COMMAND_USERDATA
46 | #define NK_KEYSTATE_BASED_INPUT
47 |
48 | #ifndef NK_ASSERT
49 | #ifdef NDEBUG
50 | #define NK_ASSERT(condition) ((void)0)
51 | #else
52 | #define NK_ASSERT(condition) do { if (!(condition)) { TraceLog(LOG_ERROR, "NUKLEAR: Failed assert \"%s\" (%s:%i)", #condition, "nuklear.h", __LINE__); }} while (0)
53 | #endif // NDEBUG
54 | #endif // NK_ASSERT
55 |
56 | #include "nuklear.h"
57 |
58 | #ifdef __cplusplus
59 | extern "C" {
60 | #endif
61 |
62 | NK_API struct nk_context* InitNuklear(int fontSize); // Initialize the Nuklear GUI context using raylib's font
63 | NK_API struct nk_context* InitNuklearEx(Font font, float fontSize); // Initialize the Nuklear GUI context, with a custom font
64 | NK_API Font LoadFontFromNuklear(int fontSize); // Loads the default Nuklear font
65 | NK_API void UpdateNuklear(struct nk_context * ctx); // Update the input state and internal components for Nuklear
66 | NK_API void UpdateNuklearEx(struct nk_context * ctx, float deltaTime); // Update the input state and internal components for Nuklear, with a custom frame time
67 | NK_API void DrawNuklear(struct nk_context * ctx); // Render the Nuklear GUI on the screen
68 | NK_API void UnloadNuklear(struct nk_context * ctx); // Deinitialize the Nuklear context
69 | NK_API struct nk_color ColorToNuklear(Color color); // Convert a raylib Color to a Nuklear color object
70 | NK_API struct nk_colorf ColorToNuklearF(Color color); // Convert a raylib Color to a Nuklear floating color
71 | NK_API struct Color ColorFromNuklear(struct nk_color color); // Convert a Nuklear color to a raylib Color
72 | NK_API struct Color ColorFromNuklearF(struct nk_colorf color); // Convert a Nuklear floating color to a raylib Color
73 | NK_API struct Rectangle RectangleFromNuklear(struct nk_context * ctx, struct nk_rect rect); // Convert a Nuklear rectangle to a raylib Rectangle
74 | NK_API struct nk_rect RectangleToNuklear(struct nk_context * ctx, Rectangle rect); // Convert a raylib Rectangle to a Nuklear Rectangle
75 | NK_API struct nk_image TextureToNuklear(Texture tex); // Convert a raylib Texture to A Nuklear image
76 | NK_API struct Texture TextureFromNuklear(struct nk_image img); // Convert a Nuklear image to a raylib Texture
77 | NK_API struct nk_image LoadNuklearImage(const char* path); // Load a Nuklear image
78 | NK_API void UnloadNuklearImage(struct nk_image img); // Unload a Nuklear image. And free its data
79 | NK_API void CleanupNuklearImage(struct nk_image img); // Frees the data stored by the Nuklear image
80 | NK_API void SetNuklearScaling(struct nk_context * ctx, float scaling); // Sets the scaling for the given Nuklear context
81 | NK_API float GetNuklearScaling(struct nk_context * ctx); // Retrieves the scaling of the given Nuklear context
82 |
83 | // Internal Nuklear functions
84 | NK_API float nk_raylib_font_get_text_width(nk_handle handle, float height, const char *text, int len);
85 | NK_API float nk_raylib_font_get_text_width_user_font(nk_handle handle, float height, const char *text, int len);
86 | NK_API void nk_raylib_clipboard_paste(nk_handle usr, struct nk_text_edit *edit);
87 | NK_API void nk_raylib_clipboard_copy(nk_handle usr, const char *text, int len);
88 | NK_API void* nk_raylib_malloc(nk_handle unused, void *old, nk_size size);
89 | NK_API void nk_raylib_mfree(nk_handle unused, void *ptr);
90 | NK_API struct nk_context* InitNuklearContext(struct nk_user_font* userFont);
91 | NK_API void nk_raylib_input_keyboard(struct nk_context * ctx);
92 | NK_API void nk_raylib_input_mouse(struct nk_context * ctx);
93 |
94 | #ifdef __cplusplus
95 | }
96 | #endif
97 |
98 | #endif // RAYLIB_NUKLEAR_H
99 |
100 | #ifdef RAYLIB_NUKLEAR_IMPLEMENTATION
101 | #ifndef RAYLIB_NUKLEAR_IMPLEMENTATION_ONCE
102 | #define RAYLIB_NUKLEAR_IMPLEMENTATION_ONCE
103 |
104 | #include // NULL
105 | #include // cosf, sinf, sqrtf
106 |
107 | // Math
108 | #ifndef NK_COS
109 | #define NK_COS cosf
110 | #endif // NK_COS
111 | #ifndef NK_SIN
112 | #define NK_SIN sinf
113 | #endif // NK_SIN
114 | #ifndef NK_INV_SQRT
115 | #define NK_INV_SQRT(value) (1.0f / sqrtf(value))
116 | #endif // NK_INV_SQRT
117 |
118 | #define NK_IMPLEMENTATION
119 | #include "nuklear.h"
120 |
121 | #ifdef __cplusplus
122 | extern "C" {
123 | #endif
124 |
125 | #ifndef RAYLIB_NUKLEAR_DEFAULT_FONTSIZE
126 | /**
127 | * The default font size that is used when a font size is not provided.
128 | */
129 | #define RAYLIB_NUKLEAR_DEFAULT_FONTSIZE 13
130 | #endif // RAYLIB_NUKLEAR_DEFAULT_FONTSIZE
131 |
132 | /*
133 | * Spacing is determined by the font size multiplied by RAYLIB_NUKLEAR_FONT_SPACING_RATIO.
134 | */
135 | #ifndef RAYLIB_NUKLEAR_FONT_SPACING_RATIO
136 | #define RAYLIB_NUKLEAR_FONT_SPACING_RATIO 0.01f
137 | #endif // RAYLIB_NUKLEAR_FONT_SPACING_RATIO
138 |
139 | #ifndef RAYLIB_NUKLEAR_DEFAULT_ARC_SEGMENTS
140 | /**
141 | * The amount of segments used when drawing an arc.
142 | *
143 | * @see NK_COMMAND_ARC_FILLED
144 | */
145 | #define RAYLIB_NUKLEAR_DEFAULT_ARC_SEGMENTS 20
146 | #endif // RAYLIB_NUKLEAR_DEFAULT_ARC_SEGMENTS
147 |
148 | #ifdef RAYLIB_NUKLEAR_INCLUDE_DEFAULT_FONT
149 | #include "raylib-nuklear-font.h"
150 | #endif
151 |
152 | /**
153 | * The user data that's leverages internally through Nuklear.
154 | */
155 | typedef struct NuklearUserData {
156 | float scaling; // The scaling of the Nuklear user interface.
157 | } NuklearUserData;
158 |
159 | /**
160 | * Nuklear callback; Get the width of the given text.
161 | *
162 | * @internal
163 | */
164 | NK_API float
165 | nk_raylib_font_get_text_width(nk_handle handle, float height, const char *text, int len)
166 | {
167 | NK_UNUSED(handle);
168 |
169 | if (len > 0) {
170 | // Grab the text with the cropped length so that it only measures the desired string length.
171 | const char* subtext = TextSubtext(text, 0, len);
172 |
173 | // Spacing is determined by the font size multiplied by RAYLIB_NUKLEAR_FONT_SPACING_RATIO.
174 | // Raylib only counts the spacing between characters, but Nuklear expects one spacing to be
175 | // counter for every character in the string:
176 | return (float)MeasureText(subtext, (int)height) + height * RAYLIB_NUKLEAR_FONT_SPACING_RATIO;
177 | }
178 |
179 | return 0;
180 | }
181 |
182 | /**
183 | * Nuklear callback; Get the width of the given text (userFont version)
184 | *
185 | * @internal
186 | */
187 | NK_API float
188 | nk_raylib_font_get_text_width_user_font(nk_handle handle, float height, const char *text, int len)
189 | {
190 | if (len > 0) {
191 | // Grab the text with the cropped length so that it only measures the desired string length.
192 | const char* subtext = TextSubtext(text, 0, len);
193 |
194 | // Spacing is determined by the font size multiplied by RAYLIB_NUKLEAR_FONT_SPACING_RATIO.
195 | // Raylib only counts the spacing between characters, but Nuklear expects one spacing to be
196 | // counter for every character in the string:
197 | return MeasureTextEx(*(Font*)handle.ptr, subtext, height, height * RAYLIB_NUKLEAR_FONT_SPACING_RATIO).x + height * RAYLIB_NUKLEAR_FONT_SPACING_RATIO;
198 | }
199 |
200 | return 0;
201 | }
202 |
203 | /**
204 | * Nuklear callback; Paste the current clipboard.
205 | *
206 | * @internal
207 | */
208 | NK_API void
209 | nk_raylib_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
210 | {
211 | const char *text = GetClipboardText();
212 | NK_UNUSED(usr);
213 | if (text != NULL) {
214 | nk_textedit_paste(edit, text, (int)TextLength(text));
215 | }
216 | }
217 |
218 | /**
219 | * Nuklear callback; Copy the given text.
220 | *
221 | * @internal
222 | */
223 | NK_API void
224 | nk_raylib_clipboard_copy(nk_handle usr, const char *text, int len)
225 | {
226 | NK_UNUSED(usr);
227 | char* trimmedText = (char*)MemAlloc((unsigned int)(sizeof(char) * (size_t)(len + 1)));
228 | if(!trimmedText)
229 | return;
230 | nk_memcopy(trimmedText, text, (nk_size)len);
231 | trimmedText[len] = 0;
232 | SetClipboardText(trimmedText);
233 | MemFree(trimmedText);
234 | }
235 |
236 | /**
237 | * Nuklear callback; Allocate memory for Nuklear.
238 | *
239 | * @internal
240 | */
241 | NK_API void*
242 | nk_raylib_malloc(nk_handle unused, void *old, nk_size size)
243 | {
244 | NK_UNUSED(unused);
245 | NK_UNUSED(old);
246 | return MemAlloc((unsigned int)size);
247 | }
248 |
249 | /**
250 | * Nuklear callback; Free memory for Nuklear.
251 | */
252 | NK_API void
253 | nk_raylib_mfree(nk_handle unused, void *ptr)
254 | {
255 | NK_UNUSED(unused);
256 | MemFree(ptr);
257 | }
258 |
259 | /**
260 | * Initialize the Nuklear context for use with Raylib, with the given Nuklear user font.
261 | *
262 | * @param userFont The Nuklear user font to initialize the Nuklear context with.
263 | *
264 | * @internal
265 | */
266 | NK_API struct nk_context*
267 | InitNuklearContext(struct nk_user_font* userFont)
268 | {
269 | struct nk_context* ctx = (struct nk_context*)MemAlloc(sizeof(struct nk_context));
270 | if (ctx == NULL) {
271 | TraceLog(LOG_ERROR, "NUKLEAR: Failed to initialize nuklear memory");
272 | return NULL;
273 | }
274 |
275 | struct NuklearUserData* userData = (struct NuklearUserData*)MemAlloc(sizeof(struct NuklearUserData));
276 | if (userData == NULL) {
277 | TraceLog(LOG_ERROR, "NUKLEAR: Failed to initialize nuklear user data");
278 | MemFree(ctx);
279 | return NULL;
280 | }
281 |
282 | // Allocator
283 | struct nk_allocator alloc;
284 | alloc.userdata = nk_handle_ptr(0);
285 | alloc.alloc = nk_raylib_malloc;
286 | alloc.free = nk_raylib_mfree;
287 |
288 | // Initialize the context.
289 | if (!nk_init(ctx, &alloc, userFont)) {
290 | TraceLog(LOG_ERROR, "NUKLEAR: Failed to initialize nuklear");
291 | MemFree(ctx);
292 | MemFree(userData);
293 | return NULL;
294 | }
295 |
296 | // Clipboard
297 | ctx->clip.copy = nk_raylib_clipboard_copy;
298 | ctx->clip.paste = nk_raylib_clipboard_paste;
299 | ctx->clip.userdata = nk_handle_ptr(0);
300 |
301 | // Set the internal user data.
302 | userData->scaling = 1.0f;
303 | nk_handle userDataHandle;
304 | userDataHandle.id = 1;
305 | userDataHandle.ptr = (void*)userData;
306 | nk_set_user_data(ctx, userDataHandle);
307 |
308 | TraceLog(LOG_INFO, "NUKLEAR: Initialized GUI");
309 |
310 | return ctx;
311 | }
312 |
313 | /**
314 | * Initialize the Nuklear context for use with Raylib.
315 | *
316 | * @param fontSize The size of the font to use for GUI text. Use 0 to use the default font size of 10.
317 | *
318 | * @return The nuklear context, or NULL on error.
319 | */
320 | NK_API struct nk_context*
321 | InitNuklear(int fontSize)
322 | {
323 | // User font.
324 | struct nk_user_font* userFont = (struct nk_user_font*)MemAlloc(sizeof(struct nk_user_font));
325 |
326 | // Use the default font size if desired.
327 | if (fontSize <= 0) {
328 | fontSize = RAYLIB_NUKLEAR_DEFAULT_FONTSIZE;
329 | }
330 |
331 | userFont->height = (float)fontSize;
332 | userFont->width = nk_raylib_font_get_text_width;
333 | userFont->userdata = nk_handle_ptr(0);
334 |
335 | // Nuklear context.
336 | return InitNuklearContext(userFont);
337 | }
338 |
339 | /**
340 | * Initialize the Nuklear context for use with Raylib, with a supplied custom font.
341 | *
342 | * @param font The custom raylib font to use with Nuklear.
343 | * @param fontSize The desired size of the font. Use 0 to set the default size of 10.
344 | *
345 | * @return The nuklear context, or NULL on error.
346 | */
347 | NK_API struct nk_context*
348 | InitNuklearEx(Font font, float fontSize)
349 | {
350 | // Copy the font to a new raylib font pointer.
351 | struct Font* newFont = (struct Font*)MemAlloc(sizeof(struct Font));
352 |
353 | // Use the default font size if desired.
354 | if (fontSize <= 0.0f) {
355 | fontSize = (float)RAYLIB_NUKLEAR_DEFAULT_FONTSIZE;
356 | }
357 | newFont->baseSize = font.baseSize;
358 | newFont->glyphCount = font.glyphCount;
359 | newFont->glyphPadding = font.glyphPadding;
360 | newFont->glyphs = font.glyphs;
361 | newFont->recs = font.recs;
362 | newFont->texture = font.texture;
363 |
364 | // Create the nuklear user font.
365 | struct nk_user_font* userFont = (struct nk_user_font*)MemAlloc(sizeof(struct nk_user_font));
366 | userFont->userdata = nk_handle_ptr(newFont);
367 | userFont->height = fontSize;
368 | userFont->width = nk_raylib_font_get_text_width_user_font;
369 |
370 | // Nuklear context.
371 | return InitNuklearContext(userFont);
372 | }
373 |
374 | /**
375 | * Load the default Nuklear font. Requires `RAYLIB_NUKLEAR_INCLUDE_DEFAULT_FONT` to be defined.
376 | *
377 | * @param size The size of the font to load (optional). Provide 0 if you'd like to use the default size from Nuklear.
378 | *
379 | * @return The loaded font, or an empty font on error.
380 | *
381 | * @code
382 | * #define RAYLIB_NUKLEAR_INCLUDE_DEFAULT_FONT
383 | * #include "raylib-nuklear.h"
384 | * Font font = LoadFontFromNuklear(0);
385 | * @endcode
386 | */
387 | NK_API Font LoadFontFromNuklear(int size) {
388 | #ifndef RAYLIB_NUKLEAR_INCLUDE_DEFAULT_FONT
389 | (void)size;
390 | TraceLog(LOG_ERROR, "NUKLEAR: RAYLIB_NUKLEAR_INCLUDE_DEFAULT_FONT must be defined to use LoadFontFromNuklear()");
391 | return CLITERAL(Font) {0};
392 | #else
393 | if (size <= 0) {
394 | size = RAYLIB_NUKLEAR_DEFAULT_FONTSIZE;
395 | }
396 |
397 | #ifndef RAYLIB_NUKLEAR_DEFAULT_FONT_GLYPHS
398 | /**
399 | * The amount of glyphs to load for the default font.
400 | */
401 | #define RAYLIB_NUKLEAR_DEFAULT_FONT_GLYPHS 95
402 | #endif
403 |
404 | return LoadFontFromMemory(".ttf", RAYLIB_NUKLEAR_DEFAULT_FONT_NAME, RAYLIB_NUKLEAR_DEFAULT_FONT_SIZE, size, NULL, RAYLIB_NUKLEAR_DEFAULT_FONT_GLYPHS);
405 | #endif
406 | }
407 |
408 | /**
409 | * Convert the given Nuklear color to a raylib color.
410 | */
411 | NK_API Color
412 | ColorFromNuklear(struct nk_color color)
413 | {
414 | Color rc;
415 | rc.a = color.a;
416 | rc.r = color.r;
417 | rc.g = color.g;
418 | rc.b = color.b;
419 | return rc;
420 | }
421 |
422 | /**
423 | * Convert the given raylib color to a Nuklear color.
424 | */
425 | NK_API struct nk_color
426 | ColorToNuklear(Color color)
427 | {
428 | struct nk_color rc;
429 | rc.a = color.a;
430 | rc.r = color.r;
431 | rc.g = color.g;
432 | rc.b = color.b;
433 | return rc;
434 | }
435 |
436 | /**
437 | * Convert the given Nuklear float color to a raylib color.
438 | */
439 | NK_API Color
440 | ColorFromNuklearF(struct nk_colorf color)
441 | {
442 | return ColorFromNuklear(nk_rgba_cf(color));
443 | }
444 |
445 | /**
446 | * Convert the given raylib color to a raylib float color.
447 | */
448 | NK_API struct nk_colorf
449 | ColorToNuklearF(Color color)
450 | {
451 | return nk_color_cf(ColorToNuklear(color));
452 | }
453 |
454 | /**
455 | * Draw the given Nuklear context in raylib.
456 | *
457 | * @param ctx The nuklear context.
458 | */
459 | NK_API void
460 | DrawNuklear(struct nk_context * ctx)
461 | {
462 | // Protect against drawing when there's nothing to draw.
463 | if (ctx == NULL) {
464 | return;
465 | }
466 |
467 | const struct nk_command *cmd;
468 | const float scale = GetNuklearScaling(ctx);
469 |
470 | nk_foreach(cmd, ctx) {
471 | switch (cmd->type) {
472 | case NK_COMMAND_NOP: {
473 | break;
474 | }
475 |
476 | case NK_COMMAND_SCISSOR: {
477 | // TODO(RobLoach): Verify if NK_COMMAND_SCISSOR works.
478 | const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd;
479 | BeginScissorMode((int)(s->x * scale), (int)(s->y * scale), (int)(s->w * scale), (int)(s->h * scale));
480 | } break;
481 |
482 | case NK_COMMAND_LINE: {
483 | const struct nk_command_line *l = (const struct nk_command_line *)cmd;
484 | Color color = ColorFromNuklear(l->color);
485 | Vector2 startPos = CLITERAL(Vector2) {(float)l->begin.x * scale, (float)l->begin.y * scale};
486 | Vector2 endPos = CLITERAL(Vector2) {(float)l->end.x * scale, (float)l->end.y * scale};
487 | DrawLineEx(startPos, endPos, l->line_thickness * scale, color);
488 | } break;
489 |
490 | case NK_COMMAND_CURVE: {
491 | const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
492 | Color color = ColorFromNuklear(q->color);
493 | Vector2 begin = CLITERAL(Vector2) {(float)q->begin.x * scale, (float)q->begin.y * scale};
494 | Vector2 controlPoint1 = CLITERAL(Vector2) {(float)q->ctrl[0].x * scale, (float)q->ctrl[0].y * scale};
495 | Vector2 controlPoint2 = CLITERAL(Vector2) {(float)q->ctrl[1].x * scale, (float)q->ctrl[1].y * scale};
496 | Vector2 end = CLITERAL(Vector2) {(float)q->end.x * scale, (float)q->end.y * scale};
497 | DrawSplineSegmentBezierCubic(begin, controlPoint1, controlPoint2, end, (float)q->line_thickness * scale, color);
498 | } break;
499 |
500 | case NK_COMMAND_RECT: {
501 | const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
502 | Color color = ColorFromNuklear(r->color);
503 | Rectangle rect = CLITERAL(Rectangle) {(float)r->x * scale, (float)r->y * scale, (float)r->w * scale, (float)r->h * scale};
504 | float roundness = (rect.width > rect.height) ?
505 | ((2 * r->rounding * scale)/rect.height) : ((2 * r->rounding * scale)/rect.width);
506 | roundness = NK_CLAMP(0.0f, roundness, 1.0f);
507 | if (roundness > 0.0f) {
508 | // DrawRectangleRoundedLines doesn't work in the same way as DrawRectangleLinesEx and it draws
509 | // the outline outside the region defined by the rectangle. To compensate for that, shrink
510 | // the rectangle by the thickness plus 1 (due to inconsistencies from DrawRectangleRoundedLines):
511 | rect.x += ((float) r->line_thickness) * scale + 1.0f;
512 | rect.y += ((float) r->line_thickness) * scale + 1.0f;
513 | rect.width = NK_MAX(rect.width - (2 * ((float) r->line_thickness) * scale + 1.0f), 0.0f);
514 | rect.height = NK_MAX(rect.height - (2 * ((float) r->line_thickness) * scale + 1.0f), 0.0f);
515 | #if RAYLIB_VERSION_MAJOR >= 5 && RAYLIB_VERSION_MINOR == 0
516 | DrawRectangleRoundedLines(rect, roundness, RAYLIB_NUKLEAR_DEFAULT_ARC_SEGMENTS, (float)r->line_thickness * scale, color);
517 | #else
518 | DrawRectangleRoundedLinesEx(rect, roundness, RAYLIB_NUKLEAR_DEFAULT_ARC_SEGMENTS, (float)r->line_thickness * scale, color);
519 | #endif
520 | }
521 | else {
522 | DrawRectangleLinesEx(rect, r->line_thickness * scale, color);
523 | }
524 | } break;
525 |
526 | case NK_COMMAND_RECT_FILLED: {
527 | const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd;
528 | Color color = ColorFromNuklear(r->color);
529 | Rectangle rect = CLITERAL(Rectangle) {(float)r->x * scale, (float)r->y * scale, (float)r->w * scale, (float)r->h * scale};
530 | float roundness = (rect.width > rect.height) ?
531 | ((2 * r->rounding * scale)/rect.height) : ((2 * r->rounding * scale)/rect.width);
532 | roundness = NK_CLAMP(0.0f, roundness, 1.0f);
533 | if (roundness > 0.0f) {
534 | DrawRectangleRounded(rect, roundness, RAYLIB_NUKLEAR_DEFAULT_ARC_SEGMENTS, color);
535 | }
536 | else {
537 | DrawRectangleRec(rect, color);
538 | }
539 | } break;
540 |
541 | case NK_COMMAND_RECT_MULTI_COLOR: {
542 | const struct nk_command_rect_multi_color* rectangle = (const struct nk_command_rect_multi_color *)cmd;
543 | Rectangle position = {(float)rectangle->x * scale, (float)rectangle->y * scale, (float)rectangle->w * scale, (float)rectangle->h * scale};
544 | Color left = ColorFromNuklear(rectangle->left);
545 | Color top = ColorFromNuklear(rectangle->top);
546 | Color bottom = ColorFromNuklear(rectangle->bottom);
547 | Color right = ColorFromNuklear(rectangle->right);
548 | DrawRectangleGradientEx(position, left, bottom, right, top);
549 | } break;
550 |
551 | case NK_COMMAND_CIRCLE: {
552 | const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
553 | Color color = ColorFromNuklear(c->color);
554 | for (unsigned short i = 0; i < c->line_thickness; i++) {
555 | DrawEllipseLines((int)(c->x * scale + c->w * scale / 2.0f), (int)(c->y * scale + c->h * scale / 2.0f), c->w * scale / 2.0f - (float)i / 2.0f, c->h * scale / 2.0f - (float)i / 2.0f, color);
556 | }
557 | } break;
558 |
559 | case NK_COMMAND_CIRCLE_FILLED: {
560 | const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
561 | Color color = ColorFromNuklear(c->color);
562 | DrawEllipse((int)(c->x * scale + c->w * scale / 2.0f), (int)(c->y * scale + c->h * scale / 2.0f), (int)(c->w * scale / 2), (int)(c->h * scale / 2), color);
563 | } break;
564 |
565 | case NK_COMMAND_ARC: {
566 | const struct nk_command_arc *a = (const struct nk_command_arc*)cmd;
567 | Color color = ColorFromNuklear(a->color);
568 | Vector2 center = CLITERAL(Vector2) {(float)a->cx, (float)a->cy};
569 | DrawRingLines(center, 0, a->r * scale, a->a[0] * RAD2DEG, a->a[1] * RAD2DEG, RAYLIB_NUKLEAR_DEFAULT_ARC_SEGMENTS, color);
570 | } break;
571 |
572 | case NK_COMMAND_ARC_FILLED: {
573 | const struct nk_command_arc_filled *a = (const struct nk_command_arc_filled*)cmd;
574 | Color color = ColorFromNuklear(a->color);
575 | Vector2 center = CLITERAL(Vector2) {(float)a->cx * scale, (float)a->cy * scale};
576 | DrawRing(center, 0, a->r * scale, a->a[0] * RAD2DEG, a->a[1] * RAD2DEG, RAYLIB_NUKLEAR_DEFAULT_ARC_SEGMENTS, color);
577 | } break;
578 |
579 | case NK_COMMAND_TRIANGLE: {
580 | const struct nk_command_triangle *t = (const struct nk_command_triangle*)cmd;
581 | Color color = ColorFromNuklear(t->color);
582 | Vector2 point1 = CLITERAL(Vector2) {(float)t->b.x * scale, (float)t->b.y * scale};
583 | Vector2 point2 = CLITERAL(Vector2) {(float)t->a.x * scale, (float)t->a.y * scale};
584 | Vector2 point3 = CLITERAL(Vector2) {(float)t->c.x * scale, (float)t->c.y * scale};
585 |
586 | // DrawLineEx(point1, point2, t->line_thickness * scale, color);
587 | // DrawLineEx(point2, point3, t->line_thickness * scale, color);
588 | // DrawLineEx(point3, point1, t->line_thickness * scale, color);
589 | // TODO: Add line thickness to DrawTriangleLines(), maybe via a DrawTriangleLinesEx()?
590 | DrawTriangleLines(point1, point2, point3, color);
591 | } break;
592 |
593 | case NK_COMMAND_TRIANGLE_FILLED: {
594 | const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled*)cmd;
595 | Color color = ColorFromNuklear(t->color);
596 | Vector2 point1 = CLITERAL(Vector2) {(float)t->b.x * scale, (float)t->b.y * scale};
597 | Vector2 point2 = CLITERAL(Vector2) {(float)t->a.x * scale, (float)t->a.y * scale};
598 | Vector2 point3 = CLITERAL(Vector2) {(float)t->c.x * scale, (float)t->c.y * scale};
599 | DrawTriangle(point1, point2, point3, color);
600 | } break;
601 |
602 | case NK_COMMAND_POLYGON: {
603 | const struct nk_command_polygon *p = (const struct nk_command_polygon*)cmd;
604 | Color color = ColorFromNuklear(p->color);
605 | struct Vector2* points = (struct Vector2*)MemAlloc((unsigned int)((size_t)(p->point_count + 1) * sizeof(Vector2)));
606 | unsigned short i;
607 | for (i = 0; i < p->point_count; i++) {
608 | points[i].x = p->points[i].x * scale;
609 | points[i].y = p->points[i].y * scale;
610 | }
611 | points[p->point_count] = points[0];
612 | DrawLineStrip(points, p->point_count + 1, color);
613 | MemFree(points);
614 | } break;
615 |
616 | case NK_COMMAND_POLYGON_FILLED: {
617 | // TODO: Implement NK_COMMAND_POLYGON_FILLED
618 | const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled*)cmd;
619 | Color color = ColorFromNuklear(p->color);
620 | struct Vector2* points = (struct Vector2*)MemAlloc((unsigned int)((size_t)(p->point_count + 1) * sizeof(Vector2)));
621 | for (unsigned short i = 0; i < p->point_count; i++) {
622 | points[i].x = p->points[i].x * scale;
623 | points[i].y = p->points[i].y * scale;
624 | }
625 | points[p->point_count] = points[0];
626 | DrawLineStrip(points, p->point_count + 1, color);
627 | MemFree(points);
628 | } break;
629 |
630 | case NK_COMMAND_POLYLINE: {
631 | const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
632 | Color color = ColorFromNuklear(p->color);
633 | for (unsigned short i = 0; i < p->point_count - 1; i++) {
634 | Vector2 start = {(float)p->points[i].x * scale, (float)p->points[i].y * scale};
635 | Vector2 end = {(float)p->points[i + 1].x * scale, (float)p->points[i + 1].y * scale};
636 | DrawLineEx(start, end, p->line_thickness * scale, color);
637 | }
638 | } break;
639 |
640 | case NK_COMMAND_TEXT: {
641 | const struct nk_command_text *text = (const struct nk_command_text*)cmd;
642 | Color color = ColorFromNuklear(text->foreground);
643 | float fontSize = text->font->height * scale;
644 | Font* font = (Font*)text->font->userdata.ptr;
645 | if (font != NULL) {
646 | Vector2 position = {(float)text->x * scale, (float)text->y * scale};
647 | DrawTextEx(*font, (const char*)text->string, position, fontSize, fontSize * RAYLIB_NUKLEAR_FONT_SPACING_RATIO, color);
648 | }
649 | else {
650 | DrawText((const char*)text->string, (int)(text->x * scale), (int)(text->y * scale), (int)fontSize, color);
651 | }
652 | } break;
653 |
654 | case NK_COMMAND_IMAGE: {
655 | const struct nk_command_image *i = (const struct nk_command_image *)cmd;
656 | Texture texture = *(Texture*)i->img.handle.ptr;
657 | Rectangle source = CLITERAL(Rectangle) {(float)i->img.region[0], (float)i->img.region[1], (float)i->img.region[2], (float)i->img.region[3]};
658 | Rectangle dest = CLITERAL(Rectangle) {(float)i->x * scale, (float)i->y * scale, (float)i->w * scale, (float)i->h * scale};
659 | Vector2 origin = CLITERAL(Vector2) {0, 0};
660 | Color tint = ColorFromNuklear(i->col);
661 | DrawTexturePro(texture, source, dest, origin, 0, tint);
662 | } break;
663 |
664 | case NK_COMMAND_CUSTOM: {
665 | TraceLog(LOG_WARNING, "NUKLEAR: Unverified custom callback implementation NK_COMMAND_CUSTOM");
666 | const struct nk_command_custom *custom = (const struct nk_command_custom *)cmd;
667 | custom->callback(NULL, (short)(custom->x * scale), (short)(custom->y * scale), (unsigned short)(custom->w * scale), (unsigned short)(custom->h * scale), custom->callback_data);
668 | } break;
669 |
670 | default: {
671 | TraceLog(LOG_WARNING, "NUKLEAR: Missing implementation %i", cmd->type);
672 | } break;
673 | }
674 | }
675 |
676 | nk_clear(ctx);
677 | }
678 |
679 | struct nk_raylib_input_keyboard_check {
680 | int key;
681 | int input_key;
682 | bool modifier;
683 | };
684 |
685 | /**
686 | * Update the Nuklear context for the keyboard input from raylib.
687 | *
688 | * @param ctx The nuklear context.
689 | *
690 | * @internal
691 | */
692 | NK_API void
693 | nk_raylib_input_keyboard(struct nk_context * ctx)
694 | {
695 | bool control = IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL);
696 | bool command = IsKeyDown(KEY_LEFT_SUPER);
697 | bool shift = IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT);
698 | #define NK_RAYLIB_INPUT_KEYBOARD_CHECK_NUM 16
699 | struct nk_raylib_input_keyboard_check checks[NK_RAYLIB_INPUT_KEYBOARD_CHECK_NUM] = {
700 | (struct nk_raylib_input_keyboard_check) {KEY_DELETE, NK_KEY_DEL, true},
701 | (struct nk_raylib_input_keyboard_check) {KEY_ENTER, NK_KEY_ENTER, true},
702 | (struct nk_raylib_input_keyboard_check) {KEY_BACKSPACE, NK_KEY_BACKSPACE, true},
703 | (struct nk_raylib_input_keyboard_check) {KEY_C, NK_KEY_COPY, (control || command)},
704 | (struct nk_raylib_input_keyboard_check) {KEY_V, NK_KEY_PASTE, (control || command)},
705 | (struct nk_raylib_input_keyboard_check) {KEY_B, NK_KEY_TEXT_LINE_START, (control || command)},
706 | (struct nk_raylib_input_keyboard_check) {KEY_E, NK_KEY_TEXT_LINE_END, (control || command)},
707 | (struct nk_raylib_input_keyboard_check) {KEY_Z, NK_KEY_TEXT_UNDO, (control || command)},
708 | (struct nk_raylib_input_keyboard_check) {KEY_R, NK_KEY_TEXT_REDO, (control || command)},
709 | (struct nk_raylib_input_keyboard_check) {KEY_A, NK_KEY_TEXT_SELECT_ALL, (control || command)},
710 | (struct nk_raylib_input_keyboard_check) {KEY_LEFT, NK_KEY_TEXT_WORD_LEFT, (control || command)},
711 | (struct nk_raylib_input_keyboard_check) {KEY_RIGHT, NK_KEY_TEXT_WORD_RIGHT, (control || command)},
712 | (struct nk_raylib_input_keyboard_check) {KEY_RIGHT, NK_KEY_RIGHT, true},
713 | (struct nk_raylib_input_keyboard_check) {KEY_LEFT, NK_KEY_LEFT, true},
714 | (struct nk_raylib_input_keyboard_check) {KEY_UP, NK_KEY_UP, true},
715 | (struct nk_raylib_input_keyboard_check) {KEY_DOWN, NK_KEY_DOWN, true}
716 | };
717 | bool checked = false;
718 | for (int i = 0; i < NK_RAYLIB_INPUT_KEYBOARD_CHECK_NUM; i++) {
719 | struct nk_raylib_input_keyboard_check check = checks[i];
720 | if (IsKeyDown(check.key) && check.modifier) {
721 | nk_input_key(ctx, (enum nk_keys)check.input_key, true);
722 | checked = true;
723 | } else {
724 | nk_input_key(ctx, (enum nk_keys)check.input_key, false);
725 | }
726 | }
727 | #undef NK_RAYLIB_INPUT_KEYBOARD_CHECK_NUM
728 |
729 | nk_input_key(ctx, NK_KEY_SHIFT, shift);
730 |
731 | if (checked) {
732 | return;
733 | }
734 |
735 | nk_input_key(ctx, NK_KEY_LEFT, IsKeyDown(KEY_LEFT));
736 | nk_input_key(ctx, NK_KEY_RIGHT, IsKeyDown(KEY_RIGHT));
737 | nk_input_key(ctx, NK_KEY_UP, IsKeyDown(KEY_UP));
738 | nk_input_key(ctx, NK_KEY_DOWN, IsKeyDown(KEY_DOWN));
739 | nk_input_key(ctx, NK_KEY_TEXT_START, IsKeyDown(KEY_HOME));
740 | nk_input_key(ctx, NK_KEY_TEXT_END, IsKeyDown(KEY_END));
741 | nk_input_key(ctx, NK_KEY_SCROLL_START, IsKeyDown(KEY_HOME) && control);
742 | nk_input_key(ctx, NK_KEY_SCROLL_END, IsKeyDown(KEY_END) && control);
743 | nk_input_key(ctx, NK_KEY_SCROLL_DOWN, IsKeyDown(KEY_PAGE_DOWN));
744 | nk_input_key(ctx, NK_KEY_SCROLL_UP, IsKeyDown(KEY_PAGE_UP));
745 |
746 | // Functions
747 | if (IsKeyPressed(KEY_TAB)) nk_input_unicode(ctx, 9);
748 |
749 | // Unicode
750 | int code;
751 | while ((code = GetCharPressed()) != 0)
752 | nk_input_unicode(ctx, (nk_rune)code);
753 | }
754 |
755 | /**
756 | * Update the Nuklear context for the mouse input from raylib.
757 | *
758 | * @param ctx The nuklear context.
759 | *
760 | * @internal
761 | */
762 | NK_API void
763 | nk_raylib_input_mouse(struct nk_context * ctx)
764 | {
765 | const float scale = GetNuklearScaling(ctx);
766 | const int mouseX = (int)((float)GetMouseX() / scale);
767 | const int mouseY = (int)((float)GetMouseY() / scale);
768 |
769 | nk_input_motion(ctx, mouseX, mouseY);
770 | nk_input_button(ctx, NK_BUTTON_LEFT, mouseX, mouseY, IsMouseButtonDown(MOUSE_LEFT_BUTTON));
771 | nk_input_button(ctx, NK_BUTTON_RIGHT, mouseX, mouseY, IsMouseButtonDown(MOUSE_RIGHT_BUTTON));
772 | nk_input_button(ctx, NK_BUTTON_MIDDLE, mouseX, mouseY, IsMouseButtonDown(MOUSE_MIDDLE_BUTTON));
773 |
774 | // Mouse Wheel
775 | float mouseWheel = GetMouseWheelMove();
776 | if (mouseWheel != 0.0f) {
777 | struct nk_vec2 mouseWheelMove;
778 | mouseWheelMove.x = 0.0f;
779 | mouseWheelMove.y = mouseWheel;
780 | nk_input_scroll(ctx, mouseWheelMove);
781 | }
782 | }
783 |
784 | /**
785 | * Update the Nuklear context for raylib's state.
786 | *
787 | * @param ctx The nuklear context to act upon.
788 | */
789 | NK_API void
790 | UpdateNuklear(struct nk_context * ctx)
791 | {
792 | UpdateNuklearEx(ctx, GetFrameTime());
793 | }
794 |
795 | /**
796 | * Update the Nuklear context for raylib's state.
797 | *
798 | * @param ctx The nuklear context to act upon.
799 | * @param deltaTime Time in seconds since last frame.
800 | */
801 | NK_API void
802 | UpdateNuklearEx(struct nk_context * ctx, float deltaTime)
803 | {
804 | // Update the time that has changed since last frame.
805 | ctx->delta_time_seconds = deltaTime;
806 |
807 | // Update the input state.
808 | nk_input_begin(ctx);
809 | {
810 | nk_raylib_input_mouse(ctx);
811 | nk_raylib_input_keyboard(ctx);
812 | }
813 | nk_input_end(ctx);
814 | }
815 |
816 | /**
817 | * Unload the given Nuklear context, along with all internal raylib textures.
818 | *
819 | * @param ctx The nuklear context.
820 | */
821 | NK_API void
822 | UnloadNuklear(struct nk_context * ctx)
823 | {
824 | struct nk_user_font* userFont;
825 |
826 | // Skip unloading if it's not set.
827 | if (ctx == NULL) {
828 | return;
829 | }
830 |
831 | // Unload the font.
832 | userFont = (struct nk_user_font*)ctx->style.font;
833 | if (userFont != NULL) {
834 | // Clear the raylib Font object.
835 | void* fontPtr = userFont->userdata.ptr;
836 | if (fontPtr != NULL) {
837 | MemFree(fontPtr);
838 | }
839 |
840 | // Clear the user font.
841 | MemFree(userFont);
842 | ctx->style.font = NULL;
843 | }
844 |
845 | // Unload the custom user data.
846 | if (ctx->userdata.ptr != NULL) {
847 | MemFree(ctx->userdata.ptr);
848 | }
849 |
850 | // Unload the nuklear context.
851 | nk_free(ctx);
852 | MemFree(ctx);
853 | TraceLog(LOG_INFO, "NUKLEAR: Unloaded GUI");
854 | }
855 |
856 | /**
857 | * Convert the given Nuklear rectangle to a raylib Rectangle.
858 | */
859 | NK_API struct
860 | Rectangle RectangleFromNuklear(struct nk_context* ctx, struct nk_rect rect)
861 | {
862 | float scaling = GetNuklearScaling(ctx);
863 | Rectangle output;
864 | output.x = rect.x * scaling;
865 | output.y = rect.y * scaling;
866 | output.width = rect.w * scaling;
867 | output.height = rect.h * scaling;
868 | return output;
869 | }
870 |
871 | /**
872 | * Convert the given raylib Rectangle to a Nuklear rectangle.
873 | */
874 | NK_API struct
875 | nk_rect RectangleToNuklear(struct nk_context* ctx, Rectangle rect)
876 | {
877 | float scaling = GetNuklearScaling(ctx);
878 | return nk_rect(rect.x / scaling, rect.y / scaling, rect.width / scaling, rect.height / scaling);
879 | }
880 |
881 | /**
882 | * Convert the given raylib texture to a Nuklear image
883 | */
884 | NK_API struct nk_image
885 | TextureToNuklear(Texture tex)
886 | {
887 | // Declare the img to store data and allocate memory
888 | // For the texture
889 | struct nk_image img;
890 | struct Texture* stored_tex = (struct Texture*)MemAlloc(sizeof(Texture));
891 |
892 | // Copy the data from the texture given into the new texture
893 | stored_tex->id = tex.id;
894 | stored_tex->width = tex.width;
895 | stored_tex->height = tex.height;
896 | stored_tex->mipmaps = tex.mipmaps;
897 | stored_tex->format = tex.format;
898 |
899 | // Initialize the nk_image struct
900 | img.handle.ptr = stored_tex;
901 | img.w = (nk_ushort)stored_tex->width;
902 | img.h = (nk_ushort)stored_tex->height;
903 |
904 | // Set the region so we can sub-select the image later.
905 | img.region[0] = (nk_ushort)0;
906 | img.region[1] = (nk_ushort)0;
907 | img.region[2] = img.w;
908 | img.region[3] = img.h;
909 |
910 | return img;
911 | }
912 |
913 | /**
914 | * Convert the given Nuklear image to a raylib Texture
915 | */
916 | NK_API struct Texture
917 | TextureFromNuklear(struct nk_image img)
918 | {
919 | // Declare texture for storage
920 | // And get back the stored texture
921 | Texture tex;
922 | Texture* stored_tex = (Texture*)img.handle.ptr;
923 |
924 | // Copy the data from the stored texture to the texture
925 | tex.id = stored_tex->id;
926 | tex.width = stored_tex->width;
927 | tex.height = stored_tex->height;
928 | tex.mipmaps = stored_tex->mipmaps;
929 | tex.format = stored_tex->format;
930 |
931 | return tex;
932 | }
933 |
934 | /**
935 | * Load a Nuklear image directly
936 | *
937 | * @param path The path to the image
938 | */
939 | NK_API struct nk_image
940 | LoadNuklearImage(const char* path)
941 | {
942 | return TextureToNuklear(LoadTexture(path));
943 | }
944 |
945 | /**
946 | * Unload a loaded Nuklear image
947 | *
948 | * @param img The Nuklear image to unload
949 | */
950 | NK_API void
951 | UnloadNuklearImage(struct nk_image img)
952 | {
953 | Texture tex = TextureFromNuklear(img);
954 | UnloadTexture(tex);
955 | CleanupNuklearImage(img);
956 | }
957 |
958 | /**
959 | * Cleans up memory used by a Nuklear image
960 | * Does not unload the image.
961 | *
962 | * @param img The Nuklear image to cleanup
963 | */
964 | NK_API void
965 | CleanupNuklearImage(struct nk_image img)
966 | {
967 | MemFree(img.handle.ptr);
968 | }
969 |
970 | /**
971 | * Sets the scaling of the given Nuklear context.
972 | *
973 | * @param ctx The nuklear context.
974 | * @param scaling How much scale to apply to the graphical user interface.
975 | */
976 | NK_API void
977 | SetNuklearScaling(struct nk_context * ctx, float scaling)
978 | {
979 | if (ctx == NULL) {
980 | return;
981 | }
982 |
983 | if (scaling <= 0.0f) {
984 | TraceLog(LOG_WARNING, "NUKLEAR: Cannot set scaling to be less than 0");
985 | return;
986 | }
987 |
988 | struct NuklearUserData* userData = (struct NuklearUserData*)ctx->userdata.ptr;
989 | if (userData != NULL) {
990 | userData->scaling = scaling;
991 | }
992 | }
993 |
994 | /**
995 | * Retrieves the scale value of the given Nuklear context.
996 | *
997 | * @return The scale value that had been set for the Nuklear context. 1.0f is the default scale value.
998 | */
999 | NK_API float
1000 | GetNuklearScaling(struct nk_context * ctx)
1001 | {
1002 | if (ctx == NULL) {
1003 | return 1.0f;
1004 | }
1005 |
1006 | struct NuklearUserData* userData = (struct NuklearUserData*)ctx->userdata.ptr;
1007 | if (userData != NULL) {
1008 | return userData->scaling;
1009 | }
1010 |
1011 | return 1.0f;
1012 | }
1013 |
1014 | #ifdef __cplusplus
1015 | }
1016 | #endif
1017 |
1018 | #endif // RAYLIB_NUKLEAR_IMPLEMENTATION_ONCE
1019 | #endif // RAYLIB_NUKLEAR_IMPLEMENTATION
1020 |
--------------------------------------------------------------------------------
/test/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # raylib-nuklear-test
2 | add_executable(raylib-nuklear-test raylib-nuklear-test.c)
3 | target_compile_options(raylib-nuklear-test PRIVATE -Wall -Wextra -Wconversion -Wsign-conversion)
4 | target_link_libraries(raylib-nuklear-test PUBLIC
5 | raylib
6 | raylib_nuklear
7 | )
8 |
9 | # Copy the resources
10 | file(GLOB resources resources/*)
11 | set(test_resources)
12 | list(APPEND test_resources ${resources})
13 | file(COPY ${test_resources} DESTINATION "resources/")
14 |
15 | # Set up the test
16 | list(APPEND CMAKE_CTEST_ARGUMENTS "--output-on-failure")
17 | add_test(NAME raylib-nuklear-test COMMAND raylib-nuklear-test)
18 |
--------------------------------------------------------------------------------
/test/raylib-assert.h:
--------------------------------------------------------------------------------
1 | /**********************************************************************************************
2 | *
3 | * raylib-assert - Assertion library for raylib.
4 | * https://github.com/robloach/raylib-assert
5 | *
6 | * Version: v3.0.0
7 | *
8 | * Copyright 2023 Rob Loach (@RobLoach)
9 | *
10 | * DEPENDENCIES:
11 | * raylib 5.5+ https://www.raylib.com
12 | *
13 | * LICENSE: zlib/libpng
14 | *
15 | * raylib-assert is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
16 | * BSD-like license that allows static linking with closed source software:
17 | *
18 | * This software is provided "as-is", without any express or implied warranty. In no event
19 | * will the authors be held liable for any damages arising from the use of this software.
20 | *
21 | * Permission is granted to anyone to use this software for any purpose, including commercial
22 | * applications, and to alter it and redistribute it freely, subject to the following restrictions:
23 | *
24 | * 1. The origin of this software must not be misrepresented; you must not claim that you
25 | * wrote the original software. If you use this software in a product, an acknowledgment
26 | * in the product documentation would be appreciated but is not required.
27 | *
28 | * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
29 | * as being the original software.
30 | *
31 | * 3. This notice may not be removed or altered from any source distribution.
32 | *
33 | **********************************************************************************************/
34 |
35 | #ifndef RAYLIB_ASSERT_H
36 | #define RAYLIB_ASSERT_H
37 |
38 | #ifdef __cplusplus
39 | extern "C" {
40 | #endif
41 |
42 | // How to report failed assertions
43 | #ifndef RAYLIB_ASSERT_LOG
44 | /**
45 | * The Trace Log Level used to report to TraceLog() on failed assertions. Defaults to LOG_FATAL.
46 | *
47 | * @example
48 | * #define RAYLIB_ASSERT_LOG LOG_WARNING
49 | *
50 | * @see TraceLogLevel
51 | */
52 | #define RAYLIB_ASSERT_LOG LOG_FATAL
53 | #endif
54 |
55 | // Define NDEBUG or RAYLIB_ASSERT_NDEBUG to skip assertions
56 | #ifdef NDEBUG
57 | #ifndef RAYLIB_ASSERT_NDEBUG
58 | #define RAYLIB_ASSERT_NDEBUG
59 | #endif
60 | #endif
61 |
62 | #ifndef RAYLIB_ASSERT_TRACELOG
63 | /**
64 | * The TraceLog() function to use.
65 | *
66 | * @see TraceLog()
67 | */
68 | #define RAYLIB_ASSERT_TRACELOG TraceLog
69 | #endif
70 |
71 | #ifndef RAYLIB_ASSERT_TEXTFORMAT
72 | /**
73 | * The TextFormat() function to use when formating text.
74 | *
75 | * @see TextFormat()
76 | */
77 | #define RAYLIB_ASSERT_TEXTFORMAT TextFormat
78 | #endif
79 |
80 | // Variadic Arguments
81 | #define RAYLIB_ASSERT_CAT( A, B ) A ## B
82 | #define RAYLIB_ASSERT_SELECT( NAME, NUM ) RAYLIB_ASSERT_CAT( NAME ## _, NUM )
83 | #define RAYLIB_ASSERT_GET_COUNT( _1, _2, _3, _4, _5, _6, _7, RAYLIB_ASSERT_COUNT, ... ) RAYLIB_ASSERT_COUNT
84 | #define RAYLIB_ASSERT_VA_SIZE( ... ) RAYLIB_ASSERT_GET_COUNT( __VA_ARGS__, 7, 6, 5, 4, 3, 2, 1 )
85 | #define RAYLIB_ASSERT_VA_SELECT( NAME, ... ) RAYLIB_ASSERT_SELECT( NAME, RAYLIB_ASSERT_VA_SIZE(__VA_ARGS__) )(__VA_ARGS__)
86 |
87 | /**
88 | * Assert whether the given condition is true.
89 | *
90 | * @param condition The condition that is expected to be true.
91 | * @param message (Optional) The message to provide on failed assertions.
92 | * @param p1 (Optional) The first parameter in the message.
93 | * @param p2 (Optional) The second parameter in the message.
94 | * @param p3 (Optional) The third parameter in the message.
95 | * @param p4 (Optional) The fourth parameter in the message.
96 | * @param p5 (Optional) The fifth parameter in the message.
97 | */
98 | #define Assert(...) RAYLIB_ASSERT_VA_SELECT(Assert, __VA_ARGS__)
99 |
100 | /**
101 | * Assert whether the two given parameters are equal.
102 | *
103 | * @param actual The actual value.
104 | * @param expected The expected value.
105 | * @param message (Optional) The message to provide on failed assertions.
106 | * @param p1 (Optional) The first parameter in the message.
107 | * @param p2 (Optional) The second parameter in the message.
108 | * @param p3 (Optional) The third parameter in the message.
109 | * @param p4 (Optional) The fourth parameter in the message.
110 | */
111 | #define AssertEqual(...) RAYLIB_ASSERT_VA_SELECT(AssertEqual, __VA_ARGS__)
112 |
113 | /**
114 | * Assert whether the given condition is false.
115 | *
116 | * @param condition The condition that is expected to be false.
117 | * @param message (Optional) The message to provide on failed assertions.
118 | * @param p1 (Optional) The first parameter in the message.
119 | * @param p2 (Optional) The second parameter in the message.
120 | * @param p3 (Optional) The third parameter in the message.
121 | * @param p4 (Optional) The fourth parameter in the message.
122 | * @param p5 (Optional) The fifth parameter in the message.
123 | */
124 | #define AssertNot(...) RAYLIB_ASSERT_VA_SELECT(AssertNot, __VA_ARGS__)
125 |
126 | /**
127 | * Assert whether the two given parameters are not equal.
128 | *
129 | * @param actual The actual value.
130 | * @param notexpected The expected value that shouldn't equal the actual value.
131 | * @param message (Optional) The message to provide on failed assertions.
132 | * @param p1 (Optional) The first parameter in the message.
133 | * @param p2 (Optional) The second parameter in the message.
134 | * @param p3 (Optional) The third parameter in the message.
135 | * @param p4 (Optional) The fourth parameter in the message.
136 | */
137 | #define AssertNotEqual(...) RAYLIB_ASSERT_VA_SELECT(AssertNotEqual, __VA_ARGS__)
138 |
139 | /**
140 | * Sets a failed assertion, with the given message.
141 | *
142 | * @param message (Optional) The message to provide for the failed assertion.
143 | * @param p1 (Optional) The first parameter in the message.
144 | * @param p2 (Optional) The second parameter in the message.
145 | * @param p3 (Optional) The third parameter in the message.
146 | * @param p4 (Optional) The fourth parameter in the message.
147 | * @param p5 (Optional) The fifth parameter in the message.
148 | * @param p6 (Optional) The sixth parameter in the message.
149 | */
150 | #define AssertFail(...) RAYLIB_ASSERT_VA_SELECT(AssertFail, __VA_ARGS__)
151 |
152 | /**
153 | * Assert whether an image is loaded.
154 | *
155 | * @param image The image to check for valid data.
156 | * @param message (Optional) The message to provide on failed assertions.
157 | * @param p1 (Optional) The first parameter in the message.
158 | * @param p2 (Optional) The second parameter in the message.
159 | * @param p3 (Optional) The third parameter in the message.
160 | * @param p4 (Optional) The fourth parameter in the message.
161 | * @param p5 (Optional) The fifth parameter in the message.
162 | */
163 | #define AssertImage(...) RAYLIB_ASSERT_VA_SELECT(AssertImage, __VA_ARGS__)
164 |
165 | /**
166 | * Assert whether two images are the same.
167 | *
168 | * @param image1 The first image to check is equal to the second.
169 | * @param image2 The second image to check is equal to the first.
170 | * @param message (Optional) The message to provide on failed assertions.
171 | * @param p1 (Optional) The first parameter in the message.
172 | * @param p2 (Optional) The second parameter in the message.
173 | * @param p3 (Optional) The third parameter in the message.
174 | * @param p4 (Optional) The fourth parameter in the message.
175 | */
176 | #define AssertImageSame(...) RAYLIB_ASSERT_VA_SELECT(AssertImageSame, __VA_ARGS__)
177 |
178 | /**
179 | * Assert whether two colors are the same.
180 | *
181 | * @param color1 The first color to check.
182 | * @param color2 The second color to check.
183 | * @param message (Optional) The message to provide on failed assertions.
184 | * @param p1 (Optional) The first parameter in the message.
185 | * @param p2 (Optional) The second parameter in the message.
186 | * @param p3 (Optional) The third parameter in the message.
187 | * @param p4 (Optional) The fourth parameter in the message.
188 | */
189 | #define AssertColorSame(...) RAYLIB_ASSERT_VA_SELECT(AssertColorSame, __VA_ARGS__)
190 |
191 | /**
192 | * Assert whether two Vector2s are the same.
193 | *
194 | * @param vector1 The first Vector2 to check.
195 | * @param vector2 The second Vector2 to check.
196 | * @param message (Optional) The message to provide on failed assertions.
197 | * @param p1 (Optional) The first parameter in the message.
198 | * @param p2 (Optional) The second parameter in the message.
199 | * @param p3 (Optional) The third parameter in the message.
200 | * @param p4 (Optional) The fourth parameter in the message.
201 | */
202 | #define AssertVector2Same(...) RAYLIB_ASSERT_VA_SELECT(AssertVector2Same, __VA_ARGS__)
203 |
204 | /**
205 | * Assert whether two Vector3s are the same.
206 | *
207 | * @param vector1 The first Vector3 to check.
208 | * @param vector2 The second Vector3 to check.
209 | * @param message (Optional) The message to provide on failed assertions.
210 | * @param p1 (Optional) The first parameter in the message.
211 | * @param p2 (Optional) The second parameter in the message.
212 | * @param p3 (Optional) The third parameter in the message.
213 | * @param p4 (Optional) The fourth parameter in the message.
214 | */
215 | #define AssertVector3Same(...) RAYLIB_ASSERT_VA_SELECT(AssertVector3Same, __VA_ARGS__)
216 |
217 | // Assert()
218 | #ifdef RAYLIB_ASSERT_NDEBUG
219 | #define Assert_0()
220 | #define Assert_1(condition)
221 | #define Assert_2(condition, message)
222 | #define Assert_3(condition, message, p1)
223 | #define Assert_4(condition, message, p1, p2)
224 | #define Assert_5(condition, message, p1, p2, p3)
225 | #define Assert_6(condition, message, p1, p2, p3, p4)
226 | #define Assert_7(condition, message, p1, p2, p3, p4, p5)
227 | #else
228 | #define Assert_0() AssertFail_1("No condition provided for Assert()")
229 | #define Assert_1(condition) Assert_2(condition, #condition)
230 | #define Assert_2(condition, message) do { if (!((bool)(condition))) { RAYLIB_ASSERT_TRACELOG(RAYLIB_ASSERT_LOG, "ASSERT: %s (%s:%i)", message, __FILE__, __LINE__); } } while(0)
231 | #define Assert_3(condition, message, p1) Assert_2(condition, RAYLIB_ASSERT_TEXTFORMAT(message, p1))
232 | #define Assert_4(condition, message, p1, p2) Assert_2(condition, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2))
233 | #define Assert_5(condition, message, p1, p2, p3) Assert_2(condition, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3))
234 | #define Assert_6(condition, message, p1, p2, p3, p4) Assert_2(condition, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3, p4))
235 | #define Assert_7(condition, message, p1, p2, p3, p4, p5) Assert_2(condition, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3, p4, p5))
236 | #endif
237 |
238 | // AssertEqual()
239 | #define AssertEqual_0() AssertFail_1("No condition provided for AssertEqual()")
240 | #define AssertEqual_1(condition) Assert_2(condition, #condition)
241 | #define AssertEqual_2(actual, expected) Assert_4((actual) == (expected), "AssertEqual(%s, %s) - Provided arguments are not equal", #actual, #expected)
242 | #define AssertEqual_3(actual, expected, message) Assert_2((actual) == (expected), message)
243 | #define AssertEqual_4(actual, expected, message, p1) Assert_3((actual) == (expected), message, p1)
244 | #define AssertEqual_5(actual, expected, message, p1, p2) Assert_4((actual) == (expected), message, p1, p2)
245 | #define AssertEqual_6(actual, expected, message, p1, p2, p3) Assert_5((actual) == (expected), message, p1, p2, p3)
246 | #define AssertEqual_7(actual, expected, message, p1, p2, p3, p4) Assert_6((actual) == (expected), message, p1, p2, p3, p4)
247 |
248 | // AssertNotEqual()
249 | #define AssertNotEqual_0() AssertFail_1("No condition provided for AssertNotEqual()")
250 | #define AssertNotEqual_1(condition) AssertNot_2(condition, #condition)
251 | #define AssertNotEqual_2(actual, expected) Assert_4((actual) != (expected), "AssertNotEqual(%s, %s) - Provided arguments are equal", #actual, #expected)
252 | #define AssertNotEqual_3(actual, expected, message) Assert_2((actual) != (expected), message)
253 | #define AssertNotEqual_4(actual, expected, message, p1) Assert_3((actual) != (expected), message, p1)
254 | #define AssertNotEqual_5(actual, expected, message, p1, p2) Assert_4((actual) != (expected), message, p1, p2)
255 | #define AssertNotEqual_6(actual, expected, message, p1, p2, p3) Assert_5((actual) != (expected), message, p1, p2, p3)
256 | #define AssertNotEqual_7(actual, expected, message, p1, p2, p3, p4) Assert_6((actual) != (expected), message, p1, p2, p3, p4)
257 |
258 | // AssertNot()
259 | #define AssertNot_0() AssertFail_1("No condition provided for AssertNot()")
260 | #define AssertNot_1(condition) Assert_2(!(bool)(condition), #condition)
261 | #define AssertNot_2(condition, message) Assert_2(!(bool)(condition), message)
262 | #define AssertNot_3(condition, message, p1) Assert_3(!(bool)(condition), message, p1)
263 | #define AssertNot_4(condition, message, p1, p2) Assert_4(!(bool)(condition), message, p1, p2)
264 | #define AssertNot_5(condition, message, p1, p2, p3) Assert_5(!(bool)(condition), message, p1, p2, p3)
265 | #define AssertNot_6(condition, message, p1, p2, p3, p4) Assert_6(!(bool)(condition), message, p1, p2, p3, p4)
266 | #define AssertNot_7(condition, message, p1, p2, p3, p4, p5) Assert_7(!(bool)(condition), message, p1, p2, p3, p4, p5)
267 |
268 | // AssertFail()
269 | #ifdef RAYLIB_ASSERT_NDEBUG
270 | #define AssertFail_0()
271 | #define AssertFail_1(message)
272 | #define AssertFail_2(message, p1)
273 | #define AssertFail_3(message, p1, p2)
274 | #define AssertFail_4(message, p1, p2, p3)
275 | #define AssertFail_5(message, p1, p2, p3, p4)
276 | #define AssertFail_6(message, p1, p2, p3, p4, p5)
277 | #define AssertFail_7(message, p1, p2, p3, p4, p5, p6)
278 | #else
279 | #define AssertFail_0() RAYLIB_ASSERT_TRACELOG(RAYLIB_ASSERT_LOG, "ASSERT: AssertFail() (%s:%i)", __FILE__, __LINE__)
280 | #define AssertFail_1(message) RAYLIB_ASSERT_TRACELOG(RAYLIB_ASSERT_LOG, "ASSERT: %s (%s:%i)", message, __FILE__, __LINE__)
281 | #define AssertFail_2(message, p1) AssertFail_1(RAYLIB_ASSERT_TEXTFORMAT(message, p1))
282 | #define AssertFail_3(message, p1, p2) AssertFail_1(RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2))
283 | #define AssertFail_4(message, p1, p2, p3) AssertFail_1(RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3))
284 | #define AssertFail_5(message, p1, p2, p3, p4) AssertFail_1(RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3, p4))
285 | #define AssertFail_6(message, p1, p2, p3, p4, p5) AssertFail_1(RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3, p4, p5))
286 | #define AssertFail_7(message, p1, p2, p3, p4, p5, p6) AssertFail_1(RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3, p4, p5, p6))
287 | #endif
288 |
289 | // AssertImage()
290 | #define AssertImage_0() AssertFail_1("No image provided for AssertImage()")
291 | #define AssertImage_1(image) Assert_3(IsImageValid(image), "AssertImage(%s) - Image not loaded", #image)
292 | #define AssertImage_2(image, message) Assert_2(IsImageValid(image), message)
293 | #define AssertImage_3(image, message, p1) Assert_3(IsImageValid(image), message, p1)
294 | #define AssertImage_4(image, message, p1, p2) Assert_4(IsImageValid(image), message, p1, p2)
295 | #define AssertImage_5(image, message, p1, p2, p3) Assert_5(IsImageValid(image), message, p1, p2, p3)
296 | #define AssertImage_6(image, message, p1, p2, p3, p4) Assert_6(IsImageValid(image), message, p1, p2, p3, p4)
297 |
298 | // AssertTexture()
299 | #define AssertTexture_0() AssertFail_1("No texture provided for AssertTexture()")
300 | #define AssertTexture_1(texture) Assert_3(IsTextureValid(texture), "AssertTexture(%s) - Texture not loaded", #texture)
301 | #define AssertTexture_2(texture, message) Assert_2(IsTextureValid(texture), message)
302 | #define AssertTexture_3(texture, message, p1) Assert_3(IsTextureValid(texture), message, p1)
303 | #define AssertTexture_4(texture, message, p1, p2) Assert_4(IsTextureValid(texture), message, p1, p2)
304 | #define AssertTexture_5(texture, message, p1, p2, p3) Assert_5(IsTextureValid(texture), message, p1, p2, p3)
305 | #define AssertTexture_6(texture, message, p1, p2, p3, p4) Assert_6(IsTextureValid(texture), message, p1, p2, p3, p4)
306 |
307 | // AssertImageSame()
308 | #ifdef RAYLIB_ASSERT_NDEBUG
309 | #define AssertImageSame_0()
310 | #define AssertImageSame_1(image)
311 | #define AssertImageSame_2(image1, image2)
312 | #define AssertImageSame_3(image1, image2, message)
313 | #define AssertImageSame_4(image1, image2, message, p1)
314 | #define AssertImageSame_5(image1, image2, message, p1, p2)
315 | #define AssertImageSame_6(image1, image2, message, p1, p2, p3)
316 | #define AssertImageSame_7(image1, image2, message, p1, p2, p3, p4)
317 | #else
318 | #define AssertImageSame_0() AssertFail_1("AssertImageSame(): No images provided to AssertImageSame(), expected 2")
319 | #define AssertImageSame_1(image) AssertFail_1("Only one image provided for AssertImageSame()")
320 | #define AssertImageSame_2(image1, image2) AssertImageSame_5(image1, image2, "AssertImageSame(%s, %s) - Images do not match", #image1, #image2)
321 | #define AssertImageSame_3(image1, image2, message) do { \
322 | if (image1.width != image2.width || image1.height != image2.height || image1.format != image2.format) { \
323 | AssertFail_1(message); \
324 | break; \
325 | } \
326 | Color* colors1 = LoadImageColors(image1); \
327 | Color* colors2 = LoadImageColors(image2); \
328 | bool failure = false; \
329 | for (int i = 0; i < image1.width * image1.height; i++) { \
330 | Color color1 = colors1[i]; \
331 | Color color2 = colors2[i]; \
332 | if (color1.r != color2.r || color1.g != color2.g || color1.b != color2.b || color1.a != color2.a) { \
333 | failure = true; \
334 | break; \
335 | } \
336 | } \
337 | UnloadImageColors(colors1); \
338 | UnloadImageColors(colors2); \
339 | if (failure) { \
340 | AssertFail_1(message); \
341 | } \
342 | } while(0)
343 | #define AssertImageSame_4(image1, image2, message, p1) AssertImageSame_3(image1, image2, RAYLIB_ASSERT_TEXTFORMAT(message, p1))
344 | #define AssertImageSame_5(image1, image2, message, p1, p2) AssertImageSame_3(image1, image2, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2))
345 | #define AssertImageSame_6(image1, image2, message, p1, p2, p3) AssertImageSame_3(image1, image2, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3))
346 | #define AssertImageSame_7(image1, image2, message, p1, p2, p3, p4) AssertImageSame_3(image1, image2, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3, p4))
347 | #endif
348 |
349 | // AssertColorSame()
350 | #ifdef RAYLIB_ASSERT_NDEBUG
351 | #define AssertColorSame_0()
352 | #define AssertColorSame_1(color)
353 | #define AssertColorSame_2(color1, color2)
354 | #define AssertColorSame_3(color1, color2, message)
355 | #define AssertColorSame_4(color1, color2, message, p1)
356 | #define AssertColorSame_5(color1, color2, message, p1, p2)
357 | #define AssertColorSame_6(color1, color2, message, p1, p2, p3)
358 | #define AssertColorSame_7(color1, color2, message, p1, p2, p3, p4)
359 | #else
360 | #define AssertColorSame_0() AssertFail_1("Colors not provided to AssertColorSame()")
361 | #define AssertColorSame_1(color) AssertFail_1("Expected two colors for AssertColorSame()")
362 | #define AssertColorSame_2(color1, color2) AssertColorSame_5(color1, color2, "AssertColorSame(%s, %s) - Colors do not match", #color1, #color2)
363 | #define AssertColorSame_3(color1, color2, message) do { \
364 | if (color1.r != color2.r || color1.g != color2.g || color1.b != color2.b || color1.a != color2.a) { \
365 | AssertFail_1(message); \
366 | }\
367 | } while (0)
368 | #define AssertColorSame_4(color1, color2, message, p1) AssertColorSame_3(color1, color2, RAYLIB_ASSERT_TEXTFORMAT(message, p1))
369 | #define AssertColorSame_5(color1, color2, message, p1, p2) AssertColorSame_3(color1, color2, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2))
370 | #define AssertColorSame_6(color1, color2, message, p1, p2, p3) AssertColorSame_3(color1, color2, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3))
371 | #define AssertColorSame_7(color1, color2, message, p1, p2, p3, p4) AssertColorSame_3(color1, color2, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3, p4))
372 | #endif
373 |
374 | // AssertVector2Same()
375 | #ifdef RAYLIB_ASSERT_NDEBUG
376 | #define AssertVector2Same_0()
377 | #define AssertVector2Same_1(vector)
378 | #define AssertVector2Same_2(vector1, vector2)
379 | #define AssertVector2Same_3(vector1, vector2, message)
380 | #define AssertVector2Same_4(vector1, vector2, message, p1)
381 | #define AssertVector2Same_5(vector1, vector2, message, p1, p2)
382 | #define AssertVector2Same_6(vector1, vector2, message, p1, p2, p3)
383 | #define AssertVector2Same_7(vector1, vector2, message, p1, p2, p3, p4)
384 | #else
385 | #define AssertVector2Same_0() AssertFail_1("Vectors not provided to AssertVector2Same()")
386 | #define AssertVector2Same_1(vector) AssertFail_1("Expected two vectors for AssertVector2Same()")
387 | #define AssertVector2Same_2(vector1, vector2) AssertVector2Same_5(vector1, vector2, "AssertVector2Same(%s, %s) - vectors do not match", #vector1, #vector2)
388 | #define AssertVector2Same_3(vector1, vector2, message) do { \
389 | if (vector1.x != vector2.x || vector1.y != vector2.y) { \
390 | AssertFail_1(message); \
391 | }\
392 | } while (0)
393 | #define AssertVector2Same_4(vector1, vector2, message, p1) AssertVector2Same_3(vector1, vector2, RAYLIB_ASSERT_TEXTFORMAT(message, p1))
394 | #define AssertVector2Same_5(vector1, vector2, message, p1, p2) AssertVector2Same_3(vector1, vector2, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2))
395 | #define AssertVector2Same_6(vector1, vector2, message, p1, p2, p3) AssertVector2Same_3(vector1, vector2, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3))
396 | #define AssertVector2Same_7(vector1, vector2, message, p1, p2, p3, p4) AssertVector2Same_3(vector1, vector2, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3, p4))
397 | #endif
398 |
399 | // AssertVector3Same()
400 | #ifdef RAYLIB_ASSERT_NDEBUG
401 | #define AssertVector3Same_0()
402 | #define AssertVector3Same_1(vector)
403 | #define AssertVector3Same_2(vector1, vector2)
404 | #define AssertVector3Same_3(vector1, vector2, message)
405 | #define AssertVector3Same_4(vector1, vector2, message, p1)
406 | #define AssertVector3Same_5(vector1, vector2, message, p1, p2)
407 | #define AssertVector3Same_6(vector1, vector2, message, p1, p2, p3)
408 | #define AssertVector3Same_7(vector1, vector2, message, p1, p2, p3, p4)
409 | #else
410 | #define AssertVector3Same_0() AssertFail_1("Vectors not provided to AssertVector2Same()")
411 | #define AssertVector3Same_1(vector) AssertFail_1("Expected two vectors for AssertVector2Same()")
412 | #define AssertVector3Same_2(vector1, vector2) AssertVector3Same_5(vector1, vector2, "AssertVector2Same(%s, %s) - vectors do not match", #vector1, #vector2)
413 | #define AssertVector3Same_3(vector1, vector2, message) do { \
414 | if (vector1.x != vector2.x || vector1.y != vector2.y || vector1.z != vector2.z) { \
415 | AssertFail_1(message); \
416 | }\
417 | } while (0)
418 | #define AssertVector3Same_4(vector1, vector2, message, p1) AssertVector3Same_3(vector1, vector2, RAYLIB_ASSERT_TEXTFORMAT(message, p1))
419 | #define AssertVector3Same_5(vector1, vector2, message, p1, p2) AssertVector3Same_3(vector1, vector2, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2))
420 | #define AssertVector3Same_6(vector1, vector2, message, p1, p2, p3) AssertVector3Same_3(vector1, vector2, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3))
421 | #define AssertVector3Same_7(vector1, vector2, message, p1, p2, p3, p4) AssertVector3Same_3(vector1, vector2, RAYLIB_ASSERT_TEXTFORMAT(message, p1, p2, p3, p4))
422 | #endif
423 |
424 | #ifdef __cplusplus
425 | }
426 | #endif
427 |
428 | #endif // RAYLIB_ASSERT_H
429 |
--------------------------------------------------------------------------------
/test/raylib-nuklear-test.c:
--------------------------------------------------------------------------------
1 | #include "raylib.h"
2 |
3 | #define RAYLIB_NUKLEAR_IMPLEMENTATION
4 | #include "raylib-nuklear.h"
5 |
6 | #include "raylib-assert.h"
7 |
8 | int main(int argc, char *argv[]) {
9 | // Initialization
10 | SetTraceLogLevel(LOG_ALL);
11 | TraceLog(LOG_INFO, "================================");
12 | TraceLog(LOG_INFO, "raylib-nuklear-test");
13 | TraceLog(LOG_INFO, "================================");
14 |
15 | InitWindow(640, 480, "raylib-nuklear-tests");
16 | Assert(IsWindowReady());
17 |
18 | // Make sure we're running in the correct directory.
19 | Assert(argc > 0);
20 | const char* dir = GetDirectoryPath(argv[0]);
21 | Assert(ChangeDirectory(dir));
22 |
23 | // InitNuklear()
24 | struct nk_context *ctx = InitNuklear(10);
25 | Assert(ctx);
26 |
27 | // Image
28 | struct nk_image image = LoadNuklearImage("resources/test-image.png");
29 | Assert(image.handle.ptr);
30 | Texture texture = TextureFromNuklear(image);
31 | Assert(texture.width > 0);
32 |
33 | // UpdateNuklear()
34 | UpdateNuklear(ctx);
35 |
36 | // UpdateNuklearEx()
37 | UpdateNuklearEx(ctx, 1.0f / 60.0f);
38 |
39 | // Nuklear GUI Code
40 | // https://github.com/Immediate-Mode-UI/Nuklear/wiki/Window
41 | if (nk_begin(ctx, "Nuklear", nk_rect(50, 50, 400, 400),
42 | NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) {
43 | nk_button_label(ctx, "Button");
44 | nk_layout_row_static(ctx, 256, 256, 1);
45 | nk_image(ctx, image);
46 | }
47 | nk_end(ctx);
48 |
49 | // Render
50 | BeginDrawing();
51 | ClearBackground(RAYWHITE);
52 |
53 | // DrawNuklear()
54 | DrawNuklear(ctx);
55 | EndDrawing();
56 |
57 | // Save a screenshot for debugging.
58 | TakeScreenshot("raylib-nuklear-test.png");
59 |
60 | // UnloadNuklearImage()
61 | UnloadNuklearImage(image);
62 |
63 | // UnloadNuklear()
64 | UnloadNuklear(ctx);
65 |
66 | // InitNuklearEx()
67 | {
68 | Font font = LoadFont("resources/anonymous_pro_bold.ttf");
69 | ctx = InitNuklearEx(font, 25.0f);
70 | Assert(ctx);
71 | UnloadNuklear(ctx);
72 | UnloadFont(font);
73 | }
74 |
75 | // RectangleFromNuklear()
76 | {
77 | ctx = NULL;
78 | struct nk_rect rect = nk_rect(10, 20, 30, 40);
79 | Rectangle rectangle = RectangleFromNuklear(ctx, rect);
80 | AssertEqual(rect.x, rectangle.x);
81 | AssertEqual(rect.y, rectangle.y);
82 | AssertEqual(rect.w, rectangle.width);
83 | AssertEqual(rect.h, rectangle.height);
84 | }
85 |
86 | // RectangleFromNuklear(), RectangleToNuklear(), with scaling
87 | {
88 | struct nk_rect rect = nk_rect(10, 20, 30, 40);
89 | ctx = InitNuklear(10);
90 | SetNuklearScaling(ctx, 2.0f);
91 | float scaling = GetNuklearScaling(ctx);
92 | AssertEqual(scaling, 2.0f, "Scaling was incorrectly set.");
93 | Rectangle rectangle = RectangleFromNuklear(ctx, rect);
94 | AssertEqual(rect.x, rectangle.x / 2);
95 | AssertEqual(rect.y, rectangle.y / 2);
96 | AssertEqual(rect.w, rectangle.width / 2);
97 | AssertEqual(rect.h, rectangle.height / 2);
98 |
99 | rectangle = (Rectangle){20, 40, 60, 80};
100 | rect = RectangleToNuklear(ctx, rectangle);
101 | AssertEqual(rect.x, rectangle.x / 2);
102 | AssertEqual(rect.y, rectangle.y / 2);
103 | AssertEqual(rect.w, rectangle.width / 2);
104 | AssertEqual(rect.h, rectangle.height / 2);
105 |
106 | UnloadNuklear(ctx);
107 | }
108 |
109 | CloseWindow();
110 | TraceLog(LOG_INFO, "================================");
111 | TraceLog(LOG_INFO, "raylib-nuklear tests succesful");
112 | TraceLog(LOG_INFO, "================================");
113 |
114 | return 0;
115 | }
116 |
--------------------------------------------------------------------------------
/test/resources/anonymous_pro_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobLoach/raylib-nuklear/d2bd2b7b3cef4831c0a57ee1b0e11a76a9fe1c19/test/resources/anonymous_pro_bold.ttf
--------------------------------------------------------------------------------
/test/resources/test-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobLoach/raylib-nuklear/d2bd2b7b3cef4831c0a57ee1b0e11a76a9fe1c19/test/resources/test-image.png
--------------------------------------------------------------------------------