Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ float GetNuklearScaling(struct nk_context * ctx); // Retrieves the sc

See the [Nuklear API documenation](https://immediate-mode-ui.github.io/Nuklear/doc/nuklear.html) for more how to use Nuklear.

> [!WARNING]
> *raylib-nuklear* stores its own state (scaling, insert mode, double-click tracking) in the context's user data. Calling `nk_set_user_data()` replaces it, which disables scaling, insert mode and double-click detection. Save `ctx->userdata` beforehand and restore it before `UnloadNuklear()`.

## Configuration

The following macros can be defined before including `raylib-nuklear.h` to tune behavior:
Expand Down
40 changes: 29 additions & 11 deletions include/raylib-nuklear.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,10 +468,19 @@ NK_API Font LoadFontFromNuklear(int size) {
// Decode base85 -> compressed binary -> raw TTF
int compressed_size = (((int)nk_strlen(nk_proggy_clean_ttf_compressed_data_base85) + 4) / 5) * 4;
unsigned char *compressed_data = (unsigned char*)MemAlloc((unsigned int)compressed_size);
if (compressed_data == NULL) {
TraceLog(LOG_ERROR, "NUKLEAR: Failed to allocate the default font data");
return CLITERAL(Font) {0};
}
nk_decode_85(compressed_data, (const unsigned char*)nk_proggy_clean_ttf_compressed_data_base85);

unsigned int ttf_size = nk_decompress_length(compressed_data);
unsigned char *ttf_data = (unsigned char*)MemAlloc(ttf_size);
if (ttf_data == NULL) {
TraceLog(LOG_ERROR, "NUKLEAR: Failed to allocate the default font data");
MemFree(compressed_data);
return CLITERAL(Font) {0};
}
nk_decompress(ttf_data, compressed_data, (unsigned int)compressed_size);
MemFree(compressed_data);

Expand Down Expand Up @@ -962,9 +971,11 @@ nk_raylib_input_keyboard(struct nk_context * ctx)
nk_input_key(ctx, NK_KEY_TAB, IsKeyDown(KEY_TAB));

NuklearUserData* userData = (NuklearUserData*)ctx->userdata.ptr;
if (IsKeyPressed(KEY_INSERT)) userData->insert_mode = !userData->insert_mode;
nk_input_key(ctx, NK_KEY_TEXT_INSERT_MODE, userData->insert_mode);
nk_input_key(ctx, NK_KEY_TEXT_REPLACE_MODE, !userData->insert_mode);
if (userData != NULL) {
if (IsKeyPressed(KEY_INSERT)) userData->insert_mode = !userData->insert_mode;
nk_input_key(ctx, NK_KEY_TEXT_INSERT_MODE, userData->insert_mode);
nk_input_key(ctx, NK_KEY_TEXT_REPLACE_MODE, !userData->insert_mode);
}

int code;
while ((code = GetCharPressed()) != 0) {
Expand Down Expand Up @@ -1010,15 +1021,17 @@ nk_raylib_input_mouse(struct nk_context * ctx)
// Double Click
{
NuklearUserData* userData = (NuklearUserData*)ctx->userdata.ptr;
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) {
double now = GetTime();
userData->double_clicking = now - userData->last_left_press <= RAYLIB_NUKLEAR_DOUBLE_CLICK_THRESHOLD;
userData->last_left_press = now;
}
else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) {
userData->double_clicking = false;
if (userData != NULL) {
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) {
double now = GetTime();
userData->double_clicking = now - userData->last_left_press <= RAYLIB_NUKLEAR_DOUBLE_CLICK_THRESHOLD;
userData->last_left_press = now;
}
else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) {
userData->double_clicking = false;
}
nk_input_button(ctx, NK_BUTTON_DOUBLE, mouseX, mouseY, userData->double_clicking);
}
nk_input_button(ctx, NK_BUTTON_DOUBLE, mouseX, mouseY, userData->double_clicking);
}

// Mouse Wheel
Expand Down Expand Up @@ -1049,6 +1062,11 @@ UpdateNuklear(struct nk_context * ctx)
NK_API void
UpdateNuklearEx(struct nk_context * ctx, float deltaTime)
{
// Skip updating if it's not set.
if (ctx == NULL) {
return;
}

// Update the time that has changed since last frame.
ctx->delta_time_seconds = deltaTime;

Expand Down
32 changes: 32 additions & 0 deletions test/raylib-nuklear-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,38 @@ int main(int argc, char *argv[]) {
UnloadNuklear(ctx);
}

// A NULL context must not crash any of the public entry points.
{
UpdateNuklear(NULL);
UpdateNuklearEx(NULL, 1.0f / 60.0f);
DrawNuklear(NULL);
SetNuklearScaling(NULL, 2.0f);
AssertEqual(GetNuklearScaling(NULL), 1.0f);
UnloadNuklear(NULL);
}

// Replacing the context user data with nk_set_user_data() must not crash.
{
ctx = InitNuklear(10);
Assert(ctx);

nk_handle original = ctx->userdata;
nk_set_user_data(ctx, nk_handle_ptr(NULL));

UpdateNuklear(ctx);
UpdateNuklearEx(ctx, 1.0f / 60.0f);
AssertEqual(GetNuklearScaling(ctx), 1.0f);

BeginDrawing();
ClearBackground(RAYWHITE);
DrawNuklear(ctx);
EndDrawing();

// Restore the internal user data so that it's still freed on unload.
nk_set_user_data(ctx, original);
UnloadNuklear(ctx);
}

// RAYLIB_NUKLEAR_VERSION macros
Assert(RAYLIB_NUKLEAR_VERSION_MAJOR >= 1);
Assert(RAYLIB_NUKLEAR_VERSION_MINOR >= 0);
Expand Down
Loading