A barebones single-header GUI library for Win32 and X11.

Related tags

GUI luigi
Overview

luigi

A barebones single-header GUI library for Win32 and X11.

Screenshot showing an example interface with buttons, split panes, tab panes, sliders, gauges, labels, scrollbars, tables and code views.

Building example

Windows

Update luigi_example.c to #define UI_WINDOWS at the top of the file, and then run the following command in a Visual Studio command prompt:

cl /O2 luigi_example.c user32.lib gdi32.lib

Linux

Update luigi_example.c to #define UI_LINUX at the top of the file, and then run the following command in Bash:

gcc -O2 luigi_example.c -lX11 -lm -o luigi

If you want to use FreeType for font rendering, pass the additional arguments to gcc:

-lfreetype -D UI_FREETYPE -I  -D UI_FONT_PATH= -D UI_FONT_SIZE=

Projects made with luigi

Designer, https://gitlab.com/nakst/essence/-/blob/master/util/designer.c Screenshot of Designer, showing a list of layers, sequences, keyframes, properties, preview settings, and a preview of a push button being edited.

GDB frontend, https://github.com/nakst/gf/ Screenshot of the debugger's interface, showing the source view, breakpoints list, call stack and command prompt.

Documentation

Introduction

As with other single-header libraries, to use it in your project define UI_IMPLEMENTATION in exactly one translation unit where you include the header. Furthermore, everytime you include the header, you must either define UI_WINDOWS or UI_LINUX to specify the target platform.

To initialise the library, call UIInitialise. You can then create a window using UIWindowCreate and populate it using the UI...Create functions. Once you're ready, call UIMessageLoop, and input messages will start being processed.

Windows are built up of elements, which are allocated and initialised by UI...Create functions. These functions all return a pointer to the allocated element. At the start of every element is a common header of type UIElement, contained in the field e. When you create an element, you must specify its parent element and its flags. Each element determines the position of its children, and every element is clipped to its parent (i.e. it cannot draw outside the bounds of the parent).

The library uses a message-based system to allow elements to respond to events and requests. The enumeration UIMessage specifies all the different messages that can be sent to an element using the UIElementMessage function. A message is passed with two parameters, an integer di and a pointer dp, and the element receiving the message must return an integer in response. If the meaning of the return value is not specified, or the element does not handle the message, it should return 0. After ensuring the element has not been marked for deletion, UIElementMessage will first try sending the message to the messageUser function pointer in the UIElement header. If this returns 0, then the message will also be sent to the messageClass function pointer. The UI...Create functions will set the messageClass function pointer, and the user may optionally set the messageUser to also receive messages sent to the element.

For example, the messageClass function set by UIButtonCreate will handle drawing the button when it receives the UI_MSG_PAINT message. The user will likely want to set messageUser so that they can receive the UI_MSG_CLICKED message, which indicates that the button has been clicked.

UIRectangle

This contains 4 integers, l, r, t and b which represent the left, right, top and bottom edges of a rectangle. Usually, the coordinates are in pixels relative to the top-left corner of the relevant window.

UIElement

The common header for all elements.

struct UIElement {
	uint64_t flags; 

	struct UIElement *parent;
	struct UIElement *next;
	struct UIElement *children;
	struct UIWindow *window;

	UIRectangle bounds, clip, repaint;
	
	void *cp; 

	int (*messageClass)(struct UIElement *element, UIMessage message, int di, void *dp);
	int (*messageUser)(struct UIElement *element, UIMessage message, int di, void *dp);
};

flags contains a bitset of flags for the element. The first 32-bits are specific to each type of element. The upper 32-bits are common to all elements. Bits 32-47 are intended to specifying options, and bits 48-63 are for storing the element's state.

The following flags are available:

  • UI_ELEMENT_V_FILL is a hint to the parent element that this element should take up all available vertical space.
  • UI_ELEMENT_H_FILL is a hint to the parent element that this element should take up all available horizontal space.
  • UI_ELEMENT_REPAINT marks the element for repainting. Do not set directly; see UIElementRepaint.
  • UI_ELEMENT_DESTROY marks the element to be destroyed. Do not set directly; see UIElementDestroy.
  • UI_ELEMENT_HIDE marks the element as hidden. It will not receive input events, be drawn, or take up space in the parent's layout.

parent contains a pointer to the element's parent. next contains a pointer to the element's sibling. children contains a pointer to the element's first child (children are linked by the next pointer). window contains a pointer to the window that contains the element.

bounds contains the element's bounds, expressed in pixels relative to the top-left corner of the containing window. Do not set directly; see UIElementMove. clip contains the element's clip region, expressed in pixels relative to the top-left corner of the containing window. Do not set directly; see UIElementMove. repaint contains the element's repaint region, expressed in pixels relative to the top-left corner of the containing window. Do not set directly; see UIElementRepaint.

cp is a context pointer available for the user.

messageClass and messageUser contain function pointers to the element's message handlers. messageClass is set when the element is first created, and has lower priority than messageUser when receiving messages. messageUser can be optionally set by the user of the element to inspect and handle its messages. If messageUser returns a non-zero value, then messageClass will not receive the message. If messageUser is NULL, then messageClass will always receive the message. Do not call these directly; see UIElementMessage.

Functions

// General.
void UIInitialise();
int UIMessageLoop();
uint64_t UIAnimateClock(); // In ms.

// Creating elements.
UIElement     *UIElementCreate(size_t bytes, UIElement *parent, uint32_t flags, int (*messageClass)(UIElement *, UIMessage, int, void *), const char *cClassName);
UIButton      *UIButtonCreate(UIElement *parent, uint32_t flags, const char *label, ptrdiff_t labelBytes);
UICode        *UICodeCreate(UIElement *parent, uint32_t flags);
UIColorPicker *UIColorPickerCreate(UIElement *parent, uint32_t flags);
UIGauge       *UIGaugeCreate(UIElement *parent, uint32_t flags);
UILabel       *UILabelCreate(UIElement *parent, uint32_t flags, const char *label, ptrdiff_t labelBytes);
UIMDIChild    *UIMDIChildCreate(UIElement *parent, uint32_t flags, UIRectangle initialBounds, const char *title, ptrdiff_t titleBytes);
UIMDIClient   *UIMDIClientCreate(UIElement *parent, uint32_t flags);
UIMenu        *UIMenuCreate(UIElement *parent, uint32_t flags);
UIPanel       *UIPanelCreate(UIElement *parent, uint32_t flags);
UIScrollBar   *UIScrollBarCreate(UIElement *parent, uint32_t flags);
UISlider      *UISliderCreate(UIElement *parent, uint32_t flags);
UISpacer      *UISpacerCreate(UIElement *parent, uint32_t flags, int width, int height);
UISplitPane   *UISplitPaneCreate(UIElement *parent, uint32_t flags, float weight);
UITabPane     *UITabPaneCreate(UIElement *parent, uint32_t flags, const char *tabs /* separate with \t, terminate with \0 */);
UITable       *UITableCreate(UIElement *parent, uint32_t flags, const char *columns /* separate with \t, terminate with \0 */);
UITextbox     *UITextboxCreate(UIElement *parent, uint32_t flags);
UIWindow      *UIWindowCreate(UIWindow *owner, uint32_t flags, const char *cTitle, int width, int height);

// General elements.
bool        UIElementAnimate(UIElement *element, bool stop);
void        UIElementDestroy(UIElement *element);
void        UIElementDestroyDescendents(UIElement *element);
UIElement  *UIElementFindByPoint(UIElement *element, int x, int y);
void        UIElementFocus(UIElement *element);
UIRectangle UIElementScreenBounds(UIElement *element); // Returns bounds of element in same coordinate system as used by UIWindowCreate.
void        UIElementRefresh(UIElement *element);
void        UIElementRepaint(UIElement *element, UIRectangle *region);
void        UIElementMove(UIElement *element, UIRectangle bounds, bool alwaysLayout);
int         UIElementMessage(UIElement *element, UIMessage message, int di, void *dp);
UIElement  *UIParentPush(UIElement *element);
UIElement  *UIParentPop();

// Specific elements.
void UICodeFocusLine(UICode *code, int index); // Line numbers are 1-indexed!!
int  UICodeHitTest(UICode *code, int x, int y); // Returns line number; negates if in margin. Returns 0 if not on a line.
void UICodeInsertContent(UICode *code, const char *content, ptrdiff_t byteCount, bool replace);
void UILabelSetContent(UILabel *code, const char *content, ptrdiff_t byteCount);
void UIMenuAddItem(UIMenu *menu, uint32_t flags, const char *label, ptrdiff_t labelBytes, void (*invoke)(void *cp), void *cp);
void UIMenuShow(UIMenu *menu);
int  UITableHitTest(UITable *table, int x, int y); // Returns item index. Returns -1 if not on an item.
bool UITableEnsureVisible(UITable *table, int index); // Returns false if the item was already visible.
void UITableResizeColumns(UITable *table);
void UITextboxReplace(UITextbox *textbox, const char *text, ptrdiff_t bytes, bool sendChangedMessage);
void UITextboxClear(UITextbox *textbox, bool sendChangedMessage);
void UITextboxMoveCaret(UITextbox *textbox, bool backward, bool word);
void UIWindowRegisterShortcut(UIWindow *window, UIShortcut shortcut);
void UIWindowPostMessage(UIWindow *window, UIMessage message, void *dp); // Thread-safe.

// Graphics.
void UIDrawBlock(UIPainter *painter, UIRectangle rectangle, uint32_t color);
void UIDrawInvert(UIPainter *painter, UIRectangle rectangle);
void UIDrawGlyph(UIPainter *painter, int x, int y, int c, uint32_t color);
void UIDrawRectangle(UIPainter *painter, UIRectangle r, uint32_t mainColor, uint32_t borderColor, UIRectangle borderSize);
void UIDrawBorder(UIPainter *painter, UIRectangle r, uint32_t borderColor, UIRectangle borderSize);
void UIDrawString(UIPainter *painter, UIRectangle r, const char *string, ptrdiff_t bytes, uint32_t color, int align, UIStringSelection *selection);
int  UIMeasureStringWidth(const char *string, ptrdiff_t bytes);
int  UIMeasureStringHeight();

// Helpers.
bool        UIColorToHSV(uint32_t rgb, float *hue, float *saturation, float *value);
void        UIColorToRGB(float hue, float saturation, float value, uint32_t *rgb);
UIRectangle UIRectangleIntersection(UIRectangle a, UIRectangle b);
UIRectangle UIRectangleBounding(UIRectangle a, UIRectangle b);
UIRectangle UIRectangleAdd(UIRectangle a, UIRectangle b);
UIRectangle UIRectangleTranslate(UIRectangle a, UIRectangle b);
bool        UIRectangleEquals(UIRectangle a, UIRectangle b);
bool        UIRectangleContains(UIRectangle a, int x, int y);
char       *UIStringCopy(const char *in, ptrdiff_t inBytes);

Messages

// General events.
UI_MSG_PAINT, // dp = pointer to UIPainter
UI_MSG_DESTROY,
UI_MSG_UPDATE, // di = UI_UPDATE_... constant
UI_MSG_ANIMATE,

// Layouting.
UI_MSG_LAYOUT,
UI_MSG_GET_WIDTH, // di = height (if known); return width
UI_MSG_GET_HEIGHT, // di = width (if known); return height

// Scrollbars.
UI_MSG_SCROLLED, // sent to parent of the scrollbar

// Mouse input.
UI_MSG_CLICKED,
UI_MSG_LEFT_DOWN,
UI_MSG_LEFT_UP,
UI_MSG_MIDDLE_DOWN,
UI_MSG_MIDDLE_UP,
UI_MSG_RIGHT_DOWN,
UI_MSG_RIGHT_UP,
UI_MSG_MOUSE_MOVE,
UI_MSG_MOUSE_DRAG,
UI_MSG_MOUSE_WHEEL, // di = delta; return 1 if handled

// Cursors.
UI_MSG_FIND_BY_POINT, // dp = pointer to UIFindByPoint; return 1 if handled
UI_MSG_GET_CURSOR, // return cursor code
UI_MSG_PRESSED_DESCENDENT, // dp = pointer to child that is/contains pressed element

// Keyboard input.
UI_MSG_KEY_TYPED, // dp = pointer to UIKeyTyped; return 1 if handled

// Element-specific.
UI_MSG_VALUE_CHANGED, // sent to notify that the element's value has changed
UI_MSG_TABLE_GET_ITEM, // dp = pointer to UITableGetItem; return string length
UI_MSG_CODE_GET_MARGIN_COLOR, // di = line index (starts at 1); return color
UI_MSG_CODE_GET_LINE_HINT, // dp = pointer to UITableGetItem (line in index field); return string length
UI_MSG_WINDOW_CLOSE, // return 1 to prevent default (process exit for UIWindow; close for UIMDIChild)
Comments
  • ARM support

    ARM support

    Hi,

    first off, congrats for the effort put into this single header lib. I am honestly amazed at some of the tricks i see in here. Getting to the point, the library works flawlessly on my x86-64 machine, but i noticed it segfaults on ARM (32 bit) . Note : i replaced some of the x86 specific SIMD instructions with standard functions in order to compile for arm and i recompiled and tested them on x86 and i confirm they still work the same. I have also statically compiled a binary to run some tests using qemu on my workstation, getting the same segfault.

    Anyways, do you plan on supporting the ARM arch? I know theres a lot of low level stuff going on in the header, so the fact that im running this on 32 bit is causing it to segfault, and im honestly at a loss.

    Sorry for bothering

    opened by drank40 14
  • Subtle layout issue

    Subtle layout issue

    In _UIPanelLayout ,

    int width = ((child->flags & UI_ELEMENT_H_FILL) || expand) ? hSpace : UIElementMessage(child, UI_MSG_GET_WIDTH, 0, 0);
    

    should be replaced with

    int width = ((child->flags & UI_ELEMENT_H_FILL) || expand) ? hSpace : UIElementMessage(child, MSG_GET_WIDTH, (child->flags & ELEMENT_V_FILL) ? perFill : 0, 0);
    

    since the height is known in the case where V_FILL is set.

    Similar in the horizontal branch.

    opened by nakst 2
  • Windows codepath problems

    Windows codepath problems

    Compiling with

    cl -Od -Z7 -nologo -TC ./luigi_example.c -link User32.lib Gdi32.lib Shell32.lib
    

    Results in

    luigi.h(3678): error C2143: syntax error: missing ')' before '*'
    luigi.h(3678): error C2059: syntax error: ')'
    luigi.h(3678): error C2100: illegal indirection
    luigi.h(3678): error C2143: syntax error: missing ')' before ';'
    

    The line it's complaining about is

    void (*callback)(UIElement *) = va_arg(arguments, void (*)(UIElement *));
    

    MSVC doesn't seem to understand a function pointer type without a typedef. I tried changing compiler flags - removing -TC adding -std:c11, -std:c17. It didn't help.

    Beyond that, the other problem is that

    _UIInitialiseCommon();
    

    runs before

    ui.heap = GetProcessHeap();
    

    But there is a font allocation in _UIInitialiseCommon which just crashes since it tries to access ui.heap

    opened by khvorov45 2
  • FreeType for font rendering (linux)

    FreeType for font rendering (linux)

    gcc -O2 luigi_example.c -lX11 -lm -lfreetype -DUI_FREETYPE `pkg-config --cflags freetype2` -DUI_FONT_PATH=./luculent.ttf -DUI_FONT_SIZE=24
    

    The command compiles fine, but the font is the same as without the freetype flags.

    Its possible to change the font size of the default X11 (no freetype) font ? Thanks and cool project.

    opened by rncar 2
  • Luigi2 - gauge and slider improvements [closed / re-opened]

    Luigi2 - gauge and slider improvements [closed / re-opened]

    • Updated UIGauge and UISlider elements to support:
      • UI_GAUGE_VERTICAL and UI_SLIDER_VERTICAL creation/layout options
      • UIGaugeSetPosition() and UISliderSetPosition()
    • New 'luigi2_example.c'
      • This file is a copy of 'luigi_example.c' with updates to compile on luigi2
      • Added a demonstration of the Gauge and Slider updates

    Tested on Windows and X11/NetBSD.

    opened by ChrisDownUnder 1
  • luigi_example.c out of date (doesn't compile)

    luigi_example.c out of date (doesn't compile)

    On linux, command

    gcc luigi_example.c -lX11 -lm -o luigi
    

    Produces

    luigi_example.c: In function ‘ThemeEditorTableMessage’:
    luigi_example.c:59:64: error: ‘UITheme’ {aka ‘struct UITheme’} has no member named ‘colors’
       59 |    return snprintf(m->buffer, m->bufferBytes, "#%.6x", ui.theme.colors[m->index]);
          |                                                                ^
    luigi_example.c:63:24: error: ‘UITheme’ {aka ‘struct UITheme’} has no member named ‘colors’
       63 |   UIColorToHSV(ui.theme.colors[themeEditorSelectedColor],
          |                        ^
    luigi_example.c: In function ‘ThemeEditorColorPickerMessage’:
    luigi_example.c:75:13: error: ‘UITheme’ {aka ‘struct UITheme’} has no member named ‘colors’
       75 |    &ui.theme.colors[themeEditorSelectedColor]);
          |             ^
    

    Seems like it's expecting colors array in UITheme? I fixed it like this just to run it

    typedef union UITheme {
    	struct {
    		uint32_t panel1, panel2, selected, border;
    		uint32_t text, textDisabled, textSelected;
    		uint32_t buttonNormal, buttonHovered, buttonPressed, buttonDisabled;
    		uint32_t textboxNormal, textboxFocused;
    		uint32_t codeFocused, codeBackground, codeDefault, codeComment, codeString, codeNumber, codeOperator, codePreprocessor;
    	};
    	uint32_t colors[20];
    } UITheme;
    

    Which works but is there some other intended way to access those colors as an array? Also, themeItems appears to be out of date. Replacing it with

    const char *themeItems[] = {
    	"panel1", 
    	"panel2",
    	"selected",
    	"border",
    	"text", 
    	"textDisabled", 
    	"textSelected", 
    	"buttonNormal", 
    	"buttonHovered", 
    	"buttonPressed", 
    	"buttonDisabled",
    	"textboxNormal", 
    	"textboxFocused", 
    	"codeFocused", 
    	"codeBackground", 
    	"codeDefault", 
    	"codeComment", 
    	"codeString", 
    	"codeNumber", 
    	"codeOperator", 
    	"codePreprocessor",
    };
    

    Appears to make the example work as intended.

    opened by khvorov45 1
  • Luigi2 - gauge and slider improvements

    Luigi2 - gauge and slider improvements

    • Updated UIGauge and UISlider elements to support:

      • UI_GAUGE_VERTICAL and UI_SLIDER_VERTICAL creation/layout options
      • UIGaugeSetPosition() and UISliderSetPosition()
    • New 'luigi2_example.c'

      • This file is a copy of 'luigi_example.c' with updates to compile on luigi2
      • Added a demonstration of the Gauge and Slider updates

    Tested on Windows 10 and X11/NetBSD.

    opened by ChrisDownUnder 0
  • luigi2 - Gauge and Slider (vertical layout and SetPosition)

    luigi2 - Gauge and Slider (vertical layout and SetPosition)

    Hi nakst

    I've made some enhancements to Gauge and Slider elements in my personal fork. Would you be interested in merging these changes?

    • Support for vertical layout of Gauge and Slider elements
    • New UISliderSetPosition procedure, and update to the existing UIGaugeSetPosition
    • New 'luigi2_example.c' file (a copy of the original luigi example with updates to build on luigi2 and demonstrate these new features)

    (See my 'luigi vs luigi2' issue for further discussion on the new example file.)

    I tried to keep the approach in line with your existing code. If you would implement these features in a different manner, I would be interested to know how, so that I can keep further updates I make in line with your approach.

    If you are happy to merge these changes (pull request Luigi2 - gauge and slider improvements), you're welcome to create the initial luigi2_example.c file in your own repository before merging my changes, if you would like to keep an accurate version history (i.e., so it registers that you wrote the original file and I only contributed the few lines of changed code).

    Regards, OzChris / ChrisDownUnder

    opened by ChrisDownUnder 0
  • Clipboard support/fixes on Windows

    Clipboard support/fixes on Windows

    This change has two components:

    luigi2 (beta)

    • Fixed clipboard support on the Windows platform.

    There were errors compiling on Windows due to use of a variable that that doesn't exist (window->window should have been window->hwnd). Some other minor code changes included for consistency with procedure definition and other platforms.

    NOTE: I updated the UIClipboard procedures to use the existing 'hwnd' within the UIWindow struct. On the Linux and Essence code paths the equivalent variable is called 'window'. You could update the variable name from 'hwnd' to 'window' throughout the UI_WINDOWS code path to match the other platforms, however as this is a bigger change I took the simpler approach here. I would be happy to rename the variable throughout and test that it still works if you would prefer.

    luigi

    • Back-ported the fixed clipboard support from this update to luigi2 into luigi.

    I'm not sure if you plan on maintaining luigi and luigi2 as separate files going forward, but this would be useful for anyone using the luigi header while luigi2 is in beta.

    opened by ChrisDownUnder 0
  • Implement clipboard for linux

    Implement clipboard for linux

    Added stubs for windows as well. Got incremental transfers working so you can paste large (>256k) strings if that's ever needed. These incremental transfers don't seem to be necessary for copying large strings to other programs (maybe it's a legacy thing?), so I just send what we've got.

    There is an invisible window associated with the clipboard. That's how linux programs seem to do it generally. Allows largely bypassing the X server when copying stuff within the program's windows (check if the invisible window owns the clipboard and use your own buffer rather than doing the usual request-response thing).

    opened by khvorov45 0
  • UITable scrollbar behaviour

    UITable scrollbar behaviour

    Hi nakst

    Currently when you use a UITable, the vertical scrollbar extends into the table header background area.

    The screenshot showing your Config Editor demonstrates this scrollbar behaviour, as does the luigi/luigi2 example.

    For your consideration, a two-line patch which:

    • changes the scrollbar bounds.t so it fits within the table draw area
    • moves the table bounds.r update to after UIDrawControl is called for the table header background (UI_DRAW_CONTROL_TABLE_BACKGROUND), so this call paints across the full width

    See pull request #15

    Regards, OzChris / ChrisDownUnder

    opened by ChrisDownUnder 2
  • Updated UITable scrollbar behaviour

    Updated UITable scrollbar behaviour

    Update so that within a UITable the vertical scrollbar no longer extends into the table header area.

    • changes the scrollbar bounds.t so it fits within the table draw area
    • moves the table bounds.r update to after UIDrawControl is called for the table header background (UI_DRAW_CONTROL_TABLE_BACKGROUND), so this call paints across the full width
    opened by ChrisDownUnder 0
  • luigi vs luigi2

    luigi vs luigi2

    Hi nakst

    With luigi2 being the actively developed version of this library, I was wondering:

    • are you planning to remove the luigi header and examples to focus only on luigi2, or
    • are you planning to have them co-exist for some time going forward?

    The reason I ask is to do with incompatibilities (or just new APIs) between luigi2 and luigi + it's examples.

    The current luigi examples do not compile with luigi2 for two main reasons that I can see:

    1. the ColorPicker element isn't present in luigi2
    2. the change from UI_PANEL_GRAY/WHITE to UI_PANEL_COLOR_1/2.

    Proposal

    If you are planning to keep luigi and luigi2 coexisting, could I suggest adding a 'luigi2_example.c' file to the repository to compile against luigi2? This would also allow further updates to the example to showcase luigi2 improvements without breaking the luigi example.

    If you are keeping both versions of the library, see my Luigi1 - backport luigi2 fixes pull request with a few small quality of life improvements in case anyone uses the luigi1 header and examples -- for your consideration.

    Note: See my other raised issue/pull request, which includes proposed luigi2 element updates along with an updated version of 'luigi2_example.c' demonstrating those features.

    Regards, OzChris / ChrisDownUnder

    opened by ChrisDownUnder 0
  • Luigi1 - backport luigi2 fixes

    Luigi1 - backport luigi2 fixes

    Quality of life improvements for luigi1:

    • Some fixes/improvements back-ported from luigi2:
      • UI_MEMMOVE on all platforms
      • UIClock update on Linux
      • improved version of UI_RECT_VALID
      • UITextboxToCString()
    • Compiler pre-processor error message advising development has moved to luigi2
    • Example updated so moving the slider now updates the gauge

    Note: the compiler pre-processor #error message will cause the automated builds to fail, remove the line to build, see the message for details as to why I thought it may be worth including.

    Tested on Windows 10 and X11/NetBSD.

    opened by ChrisDownUnder 0
Owner
Nakst
You can usually catch me on the Handmade Network Discord: https://discord.gg/GAWhBpc
Nakst
FLTK - Fast Light Tool Kit - a cross-platform C++ GUI toolkit for UNIX(r)/Linux(r) (X11)

FLTK - Fast Light Tool Kit - a cross-platform C++ GUI toolkit for UNIX(r)/Linux(r) (X11)

The FLTK Team 1.1k Dec 25, 2022
A single-header ANSI C immediate mode cross-platform GUI library

Nuklear This is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed a

Immediate Mode UIs, Nuklear, etc. 6.7k Dec 24, 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 Jan 2, 2023
This is a collection of widgets and utilities for the immediate mode GUI (imgui) that I am developing for the critic2 GUI

ImGui Goodies This is a collection of widgets and utilities for the immediate mode GUI (imgui) that I am developing for the critic2 GUI. Currently, th

null 95 Nov 19, 2022
A lightweight modern C++11 library for Win32 API, using lambdas to handle Windows messages.

WinLamb A lightweight modern C++11 library for Win32 API, using lambdas to handle Windows messages. Overview Setup Example Classes summary License 1.

Rodrigo 239 Dec 28, 2022
Modern Window Sitter for X11 based Desktop Environments

Modern Window Sitter for X11 based Desktop Environments (Coming to Wayland, Windows and Mac soon-ish). But using with a terminal emulator is recommended.

Antony Jr 40 Nov 30, 2022
x11 window manager

viru - Yet Another WM

zbj 15 Dec 6, 2021
Lets try out a few ways to easily create a modern Win32 UI app

UI-Experiments Lets try out a few ways to easily create a modern Win32 UI app This is a VS2019 solution with a handful of single projects, each one tr

Tammo 'kb' Hinrichs 21 Dec 6, 2021
✔️The smallest header-only GUI library(4 KLOC) for all platforms

Welcome to GUI-lite The smallest header-only GUI library (4 KLOC) for all platforms. 中文 Lightweight ✂️ Small: 4,000+ lines of C++ code, zero dependenc

null 6.6k Jan 8, 2023
A permissively licensed markdown single-header library for Dear ImGui.

Support development of imgui_markdown through GitHub Sponsors or Patreon imgui_markdown Markdown For Dear ImGui A permissively licensed markdown singl

Juliette Foucaut 853 Jan 8, 2023
Minimalistic C++/Python GUI library for OpenGL, GLES2/3, Metal, and WebAssembly/WebGL

NanoGUI NanoGUI is a minimalistic cross-platform widget library for OpenGL 3+, GLES 2/3, and Metal. It supports automatic layout generation, stateful

Mitsuba Physically Based Renderer 1.2k Dec 28, 2022
raygui is a simple and easy-to-use immediate-mode-gui library.

raygui is a simple and easy-to-use immediate-mode-gui library.

Ray 2k Dec 30, 2022
Examples, tutorials and applications for the LVGL embedded GUI library

Examples, tutorials and applications for the LVGL embedded GUI library

LVGL 441 Nov 11, 2022
HastyBadger is a branch of the excellent widget and GUI library Turbo Badger.

Branch Notice - HastyBadger Hasty is not Turbo. HastyBadger is a branch of the excellent widget and GUI library Turbo Badger. Notabe additions are c++

Michael Tesch 38 Nov 17, 2022
FlatUI is a immediate mode C++ GUI library for games and graphical applications.

FlatUI is a immediate mode C++ GUI library for games and graphical applications. Go to our landing page to browse our documentation.

Google 610 Dec 23, 2022
Elements C++ GUI library

Elements C++ GUI library Introduction Elements is a lightweight, fine-grained, resolution independent, modular GUI library. Elements is designed with

Cycfi Research 2.5k Dec 30, 2022
A library for creating native cross-platform GUI apps

Yue A library for creating native cross-platform GUI apps. Getting started Documentations FAQ Development Examples Sample apps (with screenshots) Muba

Yue 2.8k Jan 7, 2023
Minimalistic GUI library for OpenGL

NanoGUI NanoGUI is a minimalistic cross-platform widget library for OpenGL 3.x or higher. It supports automatic layout generation, stateful C++11 lamb

Wenzel Jakob 4.2k Jan 1, 2023
Cross-platform GUI library

Harbour Nuklear backend This backend provides support for Nuklear. It works on on all supported platforms with an OpenGL backend, including iOS and An

Rafał Jopek 2 Jan 19, 2022