Handle touch input in Allegro v5
mastermouse-move events.repository·master·Indexed 11 days ago
https://github.com/immediate-mode-ui/nuklearA minimal-state, immediate-mode graphical user interface toolkit written in ANSI C. Designed as a modular, embeddable library, Nuklear focuses on UI logic and requires the host application to handle rendering and input. It supports various backends including GLFW, SDL, SFML, Vulkan, and OpenGL ES, and can be integrated as a single-header library using the NK_IMPLEMENTATION macro.
mouse-move events.On mobile devices, the soft keyboard may cover widgets located near the bottom of the screen.
A recommended pattern to handle this is:
Nuklear is an immediate-mode UI toolkit that does not handle rendering or OS windowing/input directly. Instead, it follows a three-step loop every frame:
nk_input_begin(&ctx) and nk_input_end(&ctx).nk_begin, nk_button_label, nk_slider_float).nk_foreach and pass those commands to your specific rendering backend (e.g., OpenGL, Vulkan, Direct3D). Finally, call nk_clear(&ctx) to reset the command list for the next frame./* 1. Setup (once) */
struct nk_context ctx;
// ... initialize ctx with nk_init_fixed ...
while (running) {
/* 2. Input (every frame) */
nk_input_begin(&ctx);
// ... mirror input ...
nk_input_end(&ctx);
/* 3. Build UI (every frame) */
if (nk_begin(&ctx, "Window", nk_rect(50, 50, 220, 220), NK_WINDOW_BORDER)) {
if (nk_button_label(&ctx, "Click Me")) { /* handle click */ }
}
nk_end(&ctx);
/* 4. Draw (every frame) */
const struct nk_command *cmd;
nk_foreach(cmd, &ctx) {
// ... dispatch cmd->type to your renderer ...
}
nk_clear(&ctx);
}The nuklear.h header file is generated by the File Packer utility. To build the header, execute the appropriate script for your operating system from the repository root:
./paq.shpaq.bat# Linux/Mac
./paq.sh
# Windows
paq.batNuklear uses an immediate-mode paradigm where UI elements are declared and handled within a window block. The typical lifecycle involves:
nk_init_fixed.nk_begin.nk_layout_row_* functions.nk_button_label, nk_slider_float) which return true if an interaction occurred.nk_end.Layouts determine how widgets are positioned:
nk_layout_row_static: Uses fixed pixel dimensions for widgets.nk_layout_row_dynamic: Uses a ratio of the window width for widgets.nk_layout_row_begin/push/end: Allows for complex, custom-sized widget rows.// init gui state
enum {EASY, HARD};
static int op = EASY;
static float value = 0.6f;
static int i = 20;
struct nk_context ctx;
// Initialize context
nk_init_fixed(&ctx, calloc(1, MAX_MEMORY), MAX_MEMORY, &font);
// Start a window
if (nk_begin(&ctx, "Show", nk_rect(50, 50, 220, 220),
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) {
// 1. Fixed widget pixel width
nk_layout_row_static(&ctx, 30, 80, 1);
if (nk_button_label(&ctx, "button")) {
// event handling
}
// 2. Fixed widget window ratio width
nk_layout_row_dynamic(&ctx, 30, 2);
if (nk_option_label(&ctx, "easy", op == EASY)) op = EASY;
if (nk_option_label(&ctx, "hard", op == HARD)) op = HARD;
// 3. Custom widget pixel width using row push
nk_layout_row_begin(&ctx, NK_STATIC, 30, 2);
{
nk_layout_row_push(&ctx, 50);
nk_label(&ctx, "Volume:", NK_TEXT_LEFT);
nk_layout_row_push(&ctx, 110);
nk_slider_float(&ctx, 0, &value, 1.0f, 0.1f);
}
nk_layout_row_end(&ctx);
}
k_end(&ctx);To compile the demo, you must modify the SFML_DIR variable in the provided Makefile. Set SFML_DIR to the absolute path of your SFML installation root (the directory containing the lib and include folders).
Linux Requirements:
You must install the udev development files on your system to successfully build the demo on Linux.
# Example Makefile modification
SFML_DIR = /path/to/your/sfml_installation_rootThe demo supports accelerated OpenGL ES2 output on Raspberry Pi. However, because the default SDL2 in Raspbian repositories often lacks the rpi video driver, you may need to compile SDL2 yourself (ideally with the --disable-video-x11 configure option) or manually set the video driver environment variable.
To build the demo specifically for Raspberry Pi, use:
make rpiIf you have already compiled SDL2, you can attempt to run the application by exporting the driver variable first:
export SDL_VIDEODRIVER=rpiThe Nuklear SDL Vulkan integration operates by rendering the UI to independent render targets (overlay images). The application is responsible for managing these targets, ensuring they are correctly sized and resized.
Key Requirements:
nk_sdl_resize whenever the overlay images are resized.Integration Workflow:
nk_sdl_init providing your window, device, physical device, graphics queue indices, overlay image views, swap chain length, and format.nk_sdl_render to render to the specific image_index. This returns an nk_semaphore.overlay_image to produce the final swap chain image./* Setup */
struct nk_context *ctx = nk_sdl_init(
demo.win,
demo.device,
demo.physical_device,
demo.indices.graphics,
demo.overlay_image_views,
demo.swap_chain_images_len,
demo.swap_chain_image_format,
0, // flags
MAX_VERTEX_BUFFER,
MAX_ELEMENT_BUFFER
);
/* In the draw loop */
k_semaphore semaphore =
nk_sdl_render(demo.graphics_queue, image_index,
demo.image_available, NK_ANTI_ALIASING_ON);
if (!render(&demo, &bg, nk_semaphore, image_index)) {
fprintf(stderr, "render failed\n");
return false;
}Nuklear is a single-header library that can be used in two modes:
nuklear.h in your headers. This mode does not contain the actual implementation.NK_IMPLEMENTATION macro in exactly one .c or .cpp file before including the header.CRITICAL: Every time you include nuklear.h, you must define the exact same optional configuration flags. Failure to do so can lead to compiler errors or stack corruption.
#define NK_IMPLEMENTATION
#include "nuklear.h"To create a single-header release for the SDL Vulkan backend, run make within the demo/sdl_vulkan/src directory. This process compiles the necessary SPIR-V shaders and inlines them into a single file named nuklear_sdl_vulkan.h.
Once generated, copy nuklear_sdl_vulkan.h to the parent directory to complete the release process.
Prerequisites: You must have the following tools installed on your system:
xxdglslc (Vulkan shader compiler)awk# Navigate to the source directory
cd demo/sdl_vulkan/src
# Execute make to generate the header
make
# Copy the result to the parent directory
cp nuklear_sdl_vulkan.h ..You can compile this demo into a WebGL version using Emscripten. This version is designed to run without the overhead of compatibility modes.
make webTo support soft keyboards on iOS, you must create a UIView subclass that implements the UIKeyInput interface. Because the Allegro keyboard driver does not listen for iOS events, you must use a custom event emitter to pass keyboard events to the backend using: (void)setCustomKeyboardEventSource:(ALLEGRO_EVENT_SOURCE *)ev_src.
To detect when Nuklear requires the keyboard to open or close, check the flags returned by nk_edit_string against NK_EDIT_ACTIVATED and NK_EDIT_DEACTIVATED.
k_flags ed_flags = nk_edit_string(ctx, NK_EDIT_FIELD, field_buffer, &field_len, 64, nk_filter_default);
if (ed_flags & NK_EDIT_ACTIVATED)
open_ios_soft_keyboard();
if (ed_flags & NK_EDIT_DEACTIVATED)
close_ios_soft_keyboard();