A single-header ANSI C immediate mode cross-platform GUI library

Overview

Nuklear

This is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed as a simple embeddable user interface for application and does not have any dependencies, a default render backend or OS window/input handling but instead provides a highly modular, library-based approach, with simple input state for input and draw commands describing primitive shapes as output. So instead of providing a layered library that tries to abstract over a number of platform and render backends, it focuses only on the actual UI.

Features

  • Immediate-mode graphical user interface toolkit
  • Single-header library
  • Written in C89 (ANSI C)
  • Small codebase (~18kLOC)
  • Focus on portability, efficiency and simplicity
  • No dependencies (not even the standard library if not wanted)
  • Fully skinnable and customizable
  • Low memory footprint with total control of memory usage if needed / wanted
  • UTF-8 support
  • No global or hidden state
  • Customizable library modules (you can compile and use only what you need)
  • Optional font baker and vertex buffer output
  • Documentation

Building

This library is self-contained in one single header file and can be used either in header-only mode or in implementation mode. The header-only mode is used by default when included and allows including this header in other headers and does not contain the actual implementation.

The implementation mode requires defining the preprocessor macro NK_IMPLEMENTATION in one .c/.cpp file before #includeing this file, e.g.:

#define NK_IMPLEMENTATION
#include "nuklear.h"

IMPORTANT: Every time you include "nuklear.h" you have to define the same optional flags. This is very important; not doing it either leads to compiler errors, or even worse, stack corruptions.

Gallery

screenshot screen screen2 node skinning gamepad

Example

/* init gui state */
struct nk_context ctx;
nk_init_fixed(&ctx, calloc(1, MAX_MEMORY), MAX_MEMORY, &font);

enum {EASY, HARD};
static int op = EASY;
static float value = 0.6f;
static int i =  20;

if (nk_begin(&ctx, "Show", nk_rect(50, 50, 220, 220),
    NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) {
    /* fixed widget pixel width */
    nk_layout_row_static(&ctx, 30, 80, 1);
    if (nk_button_label(&ctx, "button")) {
        /* event handling */
    }

    /* 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;

    /* custom widget pixel width */
    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);
}
nk_end(&ctx);

example

Bindings

There are a number of nuklear bindings for different languges created by other authors. I cannot attest for their quality since I am not necessarily proficient in any of these languages. Furthermore there are no guarantee that all bindings will always be kept up to date:

Credits

Developed by Micha Mettke and every direct or indirect contributor to the GitHub.

Embeds stb_texedit, stb_truetype and stb_rectpack by Sean Barrett (public domain) Embeds ProggyClean.ttf font by Tristan Grimmer (MIT license).

Big thank you to Omar Cornut (ocornut@github) for his imgui library and giving me the inspiration for this library, Casey Muratori for handmade hero and his original immediate-mode graphical user interface idea and Sean Barrett for his amazing single-header libraries which restored my faith in libraries and brought me to create some of my own. Finally Apoorva Joshi for his single-header file packer.

License

------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Micha Mettke
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------

Reviewers guide

When reviewing pull request there are common things a reviewer should keep in mind.

Reviewing changes to src/* and nuklear.h:

  • Ensure C89 compatibility.
  • The code should work for several backends to an acceptable degree.
  • Check no other parts of nuklear.h are related to the PR and thus nothing is missing.
  • Recommend simple optimizations.
    • Pass small structs by value instead of by pointer.
    • Use local buffers over heap allocation when possible.
  • Check that the coding style is consistent with code around it.
    • Variable/function name casing.
    • Indentation.
    • Curly bracket ({}) placement.
  • Ensure that the contributer have bumped the appropriate version in package.json and added their changes to the CHANGELOG.
  • Have at least one other person review the changes before merging.

Reviewing changes to demo/*, example/* and other files in the repo:

  • Focus on getting working code merged.
    • We want to make it easy for people to get started with Nuklear, and any demo and example improvements helps in this regard.
  • Use of newer C features, or even other languages is not discouraged.
    • If another language is used, ensure that the build process is easy to figure out.
  • Messy or less efficient code can be merged so long as these outliers are pointed out and easy to find.
  • Version shouldn't be bumped for these changes.
  • Changes that improves code to be more inline with nuklear.h are ofc always welcome.
Comments
  • Added support for 9-slice/9-patch image for various widgets

    Added support for 9-slice/9-patch image for various widgets

    I have added support for 9-slice (also called 9-patch) images for most of the widgets, at least where it made sense. The following widgets now support nk_style_item_9slice for skinning:

    • button
    • chart
    • combo
    • edit
    • panel (inc. window) (header + fixed_background only)
    • progress
    • property
    • scrollbar
    • selectable
    • slider (background only)
    • tree

    9-slice images can be assigned to styles in much the same way as regular images:

    nk_9slice slc = nk_sub9slice_ptr(tex, tex_width, tex_height,
        nk_rect(rgn_x, rgn_y, rgn_w, rgn_h));
    ctx->style.button.normal = nk_style_item_9slice(slc,
        left_edge, top_edge, right_edge, bottom_edge));
    /* Edges are measured from the edge of the image, so bottom_edge = 2
       would mean that bottom_edge was 2 pixels from the bottom of the image */
    

    Please review this PR and let me know if there are any problems. closes #68

    opened by Michael-Kelley 26
  • first attempt at updating stb_truetype and stb_rect_pack

    first attempt at updating stb_truetype and stb_rect_pack

    In response to the issue I reported, I forked the repo and pushed my changes to a branch.

    The code does compile and it seems to run 'ok' on Linux, but it crashes on macOS because apparently the allocator stuff in the baker percolates around.

    I don't understand all the ramifications so I'm asking for someone who knows the code to please assist.

    help wanted 
    opened by ronaaron 19
  • `multiple definition` issue when including hpp header files

    `multiple definition` issue when including hpp header files

    Hello

    I am writing a GUI rendering class which uses nuklear as the GUI backend. My header file contains various nuklear structs (struct nk_context *ctx etc), and it has a setup like this:

    #ifndef NUKLEAR_GUI_HPP 
    #define NUKLEAR_GUI_HPP //header include guard
    
    #define NK_INCLUDE_FIXED_TYPES
    #define NK_INCLUDE_STANDARD_IO
    #define NK_INCLUDE_STANDARD_VARARGS
    #define NK_INCLUDE_DEFAULT_ALLOCATOR
    #define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
    #define NK_INCLUDE_FONT_BAKING
    #define NK_INCLUDE_DEFAULT_FONT
    #define NK_IMPLEMENTATION
    #define NK_GLFW_GL3_IMPLEMENTATION
    #define NK_KEYSTATE_BASED_INPUT
    #define INCLUDE_STYLE
    #define WINDOW_WIDTH 1200
    #define WINDOW_HEIGHT 800
    
    #define MAX_VERTEX_BUFFER 512 * 1024
    #define MAX_ELEMENT_BUFFER 128 * 1024
    
    #include <GL/glew.h>
    #include <GLFW/glfw3.h>
    
    #include "nuklear.h"
    #include "nuklear_glfw_gl3.h"
    #include "style.c"
    
    //NUKLEAR CLASS
    class NuklearGui{
    public:
      struct nk_glfw glfw = {0};
      int* width;
      int* height;
      struct nk_context *ctx;
      struct nk_colorf bg;
      struct nk_command_buffer *canvas;
      NuklearGui();
    }
    
    
    #endif // NUKLEAR_GUI_HPP
    

    However, upon compiling, I get a huge backlog of multiple definition errors, like this:

    multiple definition of `nk_glfw3_font_stash_end(nk_glfw*)'; CMakeFiles/binary.dir/src/Application.cpp.o:Application.cpp:(.text+0x4b5e0):
    

    I don't understand why this is happening, as I've already included my own header guards. Any ideas what i could be doing wrong?

    opened by frutas-fruit 16
  • Memory leak?

    Memory leak?

    Memory usage, keeps rising up in chunks of atleast ~20MB on Windows 7, on Windows 10 doesn't seem to be an issue...

    I thought this might've been an issue with nuklear_glfw_gl3.h, but it happens also with nuklear_glfw_gl2.h, so I know that it's most-likely an issue with nuklear.h itself.

    The program starts at 10MB memory usage, then climbs all the way up to ~151MB!

    opened by saidm00 16
  • Backend: SDL2 SDL_Renderer

    Backend: SDL2 SDL_Renderer

    Provide an example to build Nuklear using SDL2 / SDL_RenderGeometry (using this PR https://github.com/libsdl-org/SDL/pull/4195)

    Which makes Nuklear using the platform backend available (opengl, opengles2, Direct3D11, Metal, or software rendering).

    Backend 
    opened by 1bsyl 14
  • NK_UINT_DRAW_INDEX not working for D3D11 implementation

    NK_UINT_DRAW_INDEX not working for D3D11 implementation

    If I draw a tonne of things at once, I reach the limit of the maximum number of indices or vertexes of the default ushort size. However, I read that defining NK_UINT_DRAW_INDEX will increase this limit to a uint which should be way more than enough for what I need it for.

    However, if I have this define added, even when barely drawing anything for e.g. just using the nuklear demo, this happens (defined)-

    Click to expand

    image

    when it should look normal like this (not defined)-

    Click to expand

    image

    Does anyone know how to properly fix this in the D3D11 implementation, or perhaps what I am doing wrong?

    The demo used is from here- https://github.com/Immediate-Mode-UI/Nuklear/tree/master/demo/d3d11

    Thank you.

    opened by Hecklezz 14
  • how do i compile one of the demo examples?

    how do i compile one of the demo examples?

    I know my english is worse and my question is newbie, but, try to understand and help anyway.

    I recently started learning programming starting with c as my first and i also wanted to learn c alongside with GUI programming in c by using nuklear, but the problem is i can't figure out how to compile demo/glfw_opengl3/main.c on 64-bit windows. I'm using vscode with C/C++ extension + mingw-64 installed with mingw-64 installer. As for glew and glfw 64-bit i copied their files to these folders:

    Project
        main.c
        Makefile
        Nuklear_glfw_gl3.h
    
      MinGW-64
          +- mingw32     
                +- i686-w64-mingw32
                          +- include
                            |  +- GLFW
                            |    |  glfw3.h
                            |    |  glfw3native.h
                            |  +- GL (for glew)
                            |       eglew.h
                            |       glew.h
                            |       glxew.h
                            |       wglew.h
                            |
                          +- lib (for glfw+glew)
                               libglfw3.a
                               libglfw3dll.a
                               glfw3.dll ( to system32)
                               glew32.lib
                               glew32s.lib
                               glew32.dll ( to system32)
    

    tried with gcc -o main.exe main.c -lglfw3 -lopengl32 -lglew32 -lkernel32 -luser32 -lgdi32 And throws a long list of undefined reference to errors starting with _imp____glewCreateProgram

    i tried make -f makefile it creates empty bin and-p folders and complains 20200410_212954

    I really don't even know what i'm doing, but, if you help me to get the window, i will keep playing with it.

    I know, but, i'm not starting with python/javascript first and i'm not going to wait till i learn c and get used to programming world. i want to do this.

    opened by dhuux 14
  • Strict c++17 now compiles

    Strict c++17 now compiles

    Fixes issue https://github.com/Immediate-Mode-UI/Nuklear/issues/11

    Now detecting if memcpy and memset are actually needed. And same goes for the vertex check (they check correctly now).

    Paq.sh now automatically outputs to nuklear.h.

    opened by Nielsbishere 14
  • Hell o world

    Hell o world

    I see that you failed to provide an hello world example, and I can see why. In the sample on the readme you omitted the font hell that you must do. I hope its temporary. The default font and size should be automatic, and there should be an optional function like setdefaultfont( path, size ) and setdefaultfont( name, size ).

    opened by jackghg 12
  • Cant compile under C++ 20

    Cant compile under C++ 20

    Hello i have a problem with compilation in my C++ 20 project. When i try to compile it it gives me this error: image

    It looks like that it need C DirectX API so i tried to do this but no luck image Any ideas how to fix it?

    opened by M0n7y5 11
  • Fix high-DPI scaling in sdl_renderer

    Fix high-DPI scaling in sdl_renderer

    This commit resolves two issues with high-DPI display rendering:

    1. The coordinates were not scaled properly, resulting in tiny output and misalignment of actual cursor position with apparent position; this is fixed by calling SDL_SetRenderScale with appropriate scaling factors determined by comparing the window size to the renderer's output size
    2. The fonts were not oversampled, resulting in excessively blurry text; this is fixed by setting oversample_h and oversample_v on the font_config according to the scaling factors
    opened by kbolino 10
  • Add

    Add "glazier" half-backend

    I wonder if Nuklear could interface with Glazier (yeah, Rust) or similar to lower the barrier for both newcomers as well as seniors who must currently choose backend and then handle these os-specific things on their own.

    opened by dumblob 0
  • Fix incorrect glyph index in nk_font_bake

    Fix incorrect glyph index in nk_font_bake

    In stbtt_PackFontRangesGatherRects, it skips packing when glyphs are missing. Resulting in incorrect glyphs when nk_font_bake reading these ranges rects data. Referring to the way IMGUI handles it, we skip the rect data check.

    ref #399

    load font: image

    before: image

    after: image

    opened by dulingzhi 3
  • Trying to understand how to work with text input boxes

    Trying to understand how to work with text input boxes

    Hello!

    While trying to find and understand the information on how to work with text input boxes, I met two issues:

    1. Lack of examples: I could only find one example in demo/common/calculator.c, for double type. As I am definitely not brilliant with C, I couldn't figure out how to make it work with strings, and there is not much info on how to handle it.
    2. Lack of documentation: There are no examples on https://immediate-mode-ui.github.io/Nuklear/doc/index.html, and there is only one example on Wiki which is quite too broad in my opinion(though I couldn't exactly understand it due to how it's written)

    I love this lib, and I would also love to see some better docs on it. Thanks!

    opened by fluentpwn 2
  • Converting examples/demos to CMake

    Converting examples/demos to CMake

    Would you be open to converting all Makefiles / batch files to CMake? This would allow easier cross-platform testing / building.

    Additionally, when you would agree on using CMake, how do you feel about using vcpkg for package management? This integrates with CMake, and can be used in Windows, Linux and Mac. The recommended way is to use vcpkg as submodule, but this can also be done as manual checkout.

    See example runners for how build definitions could look like.

    opened by learn-more 0
  • Add MSVC CI

    Add MSVC CI

    Both a 'default' build, and with the define INCLUDE_ALL set will be built. I did not know how to unroll the individual build steps (without making it a huge matrix, where each build will do a new checkout), so all build steps are copy-pasted manually.

    opened by learn-more 1
  • Touch to Scroll

    Touch to Scroll

    I would like to have touch to scroll working, for usage on touch screens. You know, how you can effortlessly just scroll up and down on a webpage with a phone. So for a flawless experience, with an enlarged scrollbar being used for scrolling though. As a workaround it is trivial to remap to fingers moving to -> nk_input_scroll() But it just isn't the same as proper one finger touch to scroll.

    The logic needed for this is rather simple I imagine. The logic for this is "If mouse is not hovering over something that can be interacted with, then click + drag distance affects ctx.input.scroll_delta". However, whilst there are a bunch of functions to test whether the mouse is over an intractable rectangle, I don't know how to test for the opposite. There is a nk_window_is_any_hovered() but no nk_window_is_any_clickable_thingy_hovered().

    Anyone have an idea how to test for "Is the current mouse click over something that can be interacted with?"

    opened by FrostKiwi 0
Owner
Immediate Mode UIs, Nuklear, etc.
We review all PRs before merging. We require backwards compatibility of nuklear.h (unlike of backends/demos/examples), but we also like major version bumps.
Immediate Mode UIs, Nuklear, etc.
The bindings to the Nuklear 2D immediate GUI library.

nuklear-rust The bindings to the Nuklear 2D immediate GUI library. Currently beta. Drawing backends: gfx-pre-ll for GFX 3D drawing engine (examples: O

Serhii Plyhun 332 Dec 27, 2022
Simple and portable (but not inflexible) GUI library in C that uses the native GUI technologies of each platform it supports.

libui: a portable GUI library for C This README is being written. Status It has come to my attention that I have not been particularly clear about how

Pietro Gagliardi 10.4k Dec 31, 2022
A cross-platform GUI library for Rust, inspired by Elm

Iced A cross-platform GUI library for Rust focused on simplicity and type-safety. Inspired by Elm. Features Simple, easy-to-use, batteries-included AP

Héctor Ramón 17.5k Jan 2, 2023
A cross-platform GUI library for Rust focused on simplicity and type-safety

A cross-platform GUI library for Rust, inspired by Elm

Héctor Ramón 17.5k Jan 8, 2023
A cross-platform GUI library for Rust, inspired by Elm

Iced A cross-platform GUI library for Rust focused on simplicity and type-safety. Inspired by Elm. Features Simple, easy-to-use, batteries-included AP

null 17.5k Dec 28, 2022
A simple, cross-platform GUI automation module for Rust.

AutoPilot AutoPilot is a Rust port of the Python C extension AutoPy, a simple, cross-platform GUI automation library for Python. For more information,

null 271 Dec 27, 2022
Truly cross platform, truly native. multiple backend GUI for rust

WIP: Sauron-native a rust UI library that conquers all platforms ranging from desktop to mobile devices. An attempt to create a truly native, truly cr

Jovansonlee Cesar 627 Jan 5, 2023
Cross-platform GUI toolkit written in Rust

Tuix is a cross-platform GUI toolkit written in Rust. The driving principle behind tuix is to be a self-contained, small-as-possible, but still fast,

George Atkinson 166 Dec 13, 2022
A cross-platform GUI toolkit in Rust

NXUI - Native X UI A cross-platform GUI toolkit in Rust NXUI is a GUI toolkit that calls OS native APIs as much as possible to achieve fast operation.

らて 11 Jun 3, 2022
A lightweight cross-platform system-monitoring fltk gui application based on sysinfo

Sysinfo-gui A lightweight cross-platform system-monitoring fltk gui application based on sysinfo. The UI design is inspired by stacer. The svg icons a

Mohammed Alyousef 22 Dec 31, 2022
rsautogui aims to be a cross-platform GUI automation rust crate.

rsautogui rsautogui aims to be a cross-platform GUI automation rust crate. It lets you control the mouse and keyboard to automate interactions with ot

null 5 Sep 18, 2022
Cross-platform native Rust menu library

A cross-platform Rust library for managing the native operating system menus.

Mads Marquart 16 Jan 6, 2023
Rust bindings to the minimalist, native, cross-platform UI toolkit `libui`

Improved User Interface A cross-platform UI toolkit for Rust based on libui iui: ui-sys: iui is a simple (about 4 kLOC of Rust), small (about 800kb, i

Rust Native UI Group 865 Dec 27, 2022
A Rust binding of the wxWidgets cross platform toolkit.

wxRust master: / mac(0.10): This is a Rust binding for the wxWidgets cross platform toolkit. API wxRust API documentation How it works The wxRust libr

KENZ 129 Jan 4, 2023
A cross-platform Mod Manager for RimWorld intended to work with macOS, linux and Windows

TODOs are available here. Discussions, PRs and Issues are open for anyone who is willing to contribute. rrm Inspired by Spoons rmm. This is a cross-pl

Alejandro Osornio 7 Sep 5, 2022
An easy-to-use, 2D GUI library written entirely in Rust.

Conrod An easy-to-use, 2D GUI library written entirely in Rust. Guide What is Conrod? A Brief Summary Screenshots and Videos Feature Overview Availabl

PistonDevelopers 3.3k Jan 1, 2023
Rust bindings for the FLTK GUI library.

fltk-rs Rust bindings for the FLTK Graphical User Interface library. The FLTK crate is a crossplatform lightweight gui library which can be statically

Mohammed Alyousef 1.1k Jan 9, 2023
Idiomatic, GTK+-based, GUI library, inspired by Elm, written in Rust

Relm Asynchronous, GTK+-based, GUI library, inspired by Elm, written in Rust. This library is in beta stage: it has not been thoroughly tested and its

null 2.2k Dec 31, 2022
Clear Coat is a Rust wrapper for the IUP GUI library.

Clear Coat Clear Coat is a Rust wrapper for the IUP GUI library. IUP uses native controls and has Windows and GTK backends. A macOS backend has been o

Jordan Miner 18 Feb 13, 2021