CMakeLists wrapper around imgui

Related tags

GUI imguiwrap
Overview

ImGui Wrappings

This is a trifold wrapper for the Dear ImGui library.

  1. Ease integration with CMake,
  2. Provide an RAII mechanism for ImGui scopes,
  3. Provide some minor ImGui helpers,

The RAII mechanisms are written to provide a zero-cost abstraction so that using them will produce the same machine code (or better) as hand-writing your Begin/End calls.

godbolt example

main branch win/lin/mac build

Integration with your CMakeLists-based project:

The imgui library is exposed as a target: imguiwrap. You can then either manually vendor or git-submodule imguiwrap into a subdirectory and including imgui in your project is then as simple as:

    add_subdirectory(imguiwrap)
    target_link_libraries(
        YOUR_TARGET

        PUBLIC

        imguiwrap
    )

Alternatively, you can use FetchContent or CPM.

RAII ImGui scopes:

ImGui is essentially a sort of bare-bones virtual machine where you push directives and parameters onto a stack for execution by the vm. Each directive starts with a push (Begin) of some form and is completed with a corresponding Pop (End).

While this isn't particularly difficult, it's a high cognitive load when the surrounding code is C++.

ImGuiWrap uses zero-cost conceptual classes to provide an RAII approach to ImGui. The constructors call the relevant Begin() function, allow you to execute your dependent code, and then conditionally invoke the appropriate End() function.

You can do this in a completely conventional way:

    dear::MainMenuBar bar("Main Menu");
    if (bar) {
        dear::Menu file("File");
        if (file) {
            ...
        }
    }

but the classes also implement an operator&& which accepts a callable so that you can use them anonymously and in an increasingly modern compositional style:

    dear::MainMenuBar("Main Menu")  &&  [](){
        dear::Menu("File")  &&  [](){
            ...
        };
    };

(This form might, for instance, look familiar to boost/ut users)

And yes, it knows that ImGui::Begin() must always have a matching ImGui::End while ImGui::BeginMainMenuBar only needs ImGui::EndMainMenuBar if the begin returned true.

Note

  • You may sometimes need to use capturing lambdas, e.g. [&] {},
  • If you have access to C++23 you can abbreviate your lambdas from [] () {...} to [] { ... },
  • You can also use the name of a function:
    void main_menu() noexcept {
        dear::Menu("File") && [](){
        };
    }

    dear::MainMenuBar("Main Menu") && main_menu;

Minor helpers:

dear::ItemTooltip

Provides a scoped wrapper that will only execute your callable if the previous item is hovered.

    dear::Text("[help]");
    dear::ItemTooltip(/*flags*/) && []() { dear::Text("Help is not available"); }

dear::EditTableFlags and EditWindowFlags

These two functions let you edit window or table flags in real time, to help you find the right flags for your own layouts.

static ImGuiWindowFlags mywindow_flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysVerticalScrollbar;
static bool mywindow_visible  = false;
static bool mywindow_editable = false;

void debug_menu()
{
    dear::Menu("Debug") && []() {
        // Only enable this option if mywindow is being shown.
        dear::MenuItem("Edit MyWindow flags", NULL, &mywindow_editable, mywindow_visible));
    };
}

void show_my_window()
{
    debug_menu();
    dear::Begin("My Window", &mywindow_visible, mywindow_flags) && []() {
        dear::Text("Hello!");
    };
}

dear::Text specialiations

dear::Text (and TextUnformatted) specializes for std::string and std::string_view, which can be disabled by defining DEAR_NO_STRING and DEAR_NO_STRINGVIEW accordingly.

It also allows you to avoid the vsnprintf overhead of ImGui::Text by taking variadic parameters:

    ImGui::Text("hello, %s!", "world");  // goes through vsnprintf equiv
    dear::Text("hello, %s!", "world");   // uses perfect-forwarding

dear::MenuItem specializations

dear::MenuItem can take a std::string as its first argument instead of a const char*.

dear::Zero

Because life is too short to be writing ImVec2(0, 0) all over the place...

DEFER

If crazy RAII operator&& is too much for you, imguiwrap.helpers.h provides a simpler DEFER macro too:

    DEFER(ImGui::End(););
    if (ImGui:Begin("my window")) {
        if (ImGui::BeginChild("child")) {
            DEFER(ImGui::EndChild(););
        }
    }

Questions

Why "&&"?

To emphasize that the callable will only be invoked if the element is being rendered.

The approach was inspired by Boost μt's style of writing unit tests:

	"life"_test = [](){
		int i = 43;
		expect(42_i == i);
	};

and I seriously considered

	"File"_Menu = [](){
		"Open"_MenuItem = onOpen;
		...
	};

but the model breaks down for no- and multi-argument cases and I wanted something consistent.

Ultimately while I was reading a mock-up line, I found myself saying "then" so it was either &&, >> or <<. Connotations imbued by iostreams into both of the latter made >> feel very akward while << was less akward but less obviously conditional.

	MainMenuBar() << [](){ Menu(get_filename(argv[0])); };
	// vs
	MainMenuBar() && [](){ Menu(get_filename(argv[0])); };

The short-circuit, when the menu bar is not being displayed, is far more obvious in the second form.

How do the RAII types work?

Each type is a concrete instantiation of a CRTP template (so they shouldn't blow up your compilation time). This template, ScopeWrapper, hosts a boolean used to determine if End() needs calling, which can be overwridden with a template parameter.

These are leveraged in such a way that the compilers can easily recognize that the bool is unused and eliminate it.

In the following piece of code:

    dear::MenuBar("File") && []() {
    };

we are (1) constructing a temporary and passing a (3) lambda to an operator method on it (2) before the object destructs (4).

    dear::MenuBar("File")
    ^^^^^^^^^-1-^^^^^^^^^
                          && 
                         ^-2-^
                               [](){ }
                               ^^-3-^^
                                       ;
                                     ^-4-^

To expand this out:

if (temp.ok_) { ImGui::EndMenuBar(); } ">
    {
        dear::MenuBar temp("File");    // temp.ok_ = ImGui::BeginMenuBar("File");

        auto noop_lambda = [] () {};

        temp.operator&&(noop_lambda);  // if (temp.ok_) noop_lambda();

    } // invokes temp.~MenuBar();      -> if (temp.ok_) { ImGui::EndMenuBar(); }

Docker build

There is a Dockerfile and docker-build.sh provided which I use to test the Linux build.

> docker pull kfsone/imguibuild
or
> docker build --tag kfsone/imguibuild
> docker run --rm -it -v ${pwd}:/src kfsone/imguibuild
> docker-build/example/dear_example
Issues
  • Building on a system with 'glew' installed results in link errors

    Building on a system with 'glew' installed results in link errors

    Let to its own devices, imgui will attempt to detect the opengl loader:

    https://github.com/ocornut/imgui/blob/d9b606672ae145457d12dacdc82b82c6ce9ebd79/backends/imgui_impl_opengl3.h#L67-L86

    and if 'glew' is present, it will find it before finding glfw.

    Solution: Set IMGUI_IMPL_OPENGL_LOADER_GL3W ahead of time.

    opened by kfsone 2
  • Solves #6 - Ensure backend definition is set

    Solves #6 - Ensure backend definition is set

    If the backend is unspecified, imgui will do a simple linear check to see which glewalike to use, starting with glew. This is fine in a simple container with the minimum required installs, but if your system has glew it will make the wrong selection.

    So this change introduces a CMakeLists.txt parameter to make users aware that there is a choice to be had, but then hardcodes it to a simple default.

    opened by kfsone 0
  • Missing support for cmake

    Missing support for cmake

    I am having problems with integrating this library into my project. If cmake is 100% supported, it should work seamless with my gitache project; but it doesn't.

    Now gitache isn't relevant here; that does just the standard things expected for cmake; I am just mentioning it to make clear that this is a well established, automated, standard process; which doesn't work with imguiwrap ;).

    The problems I run into are:

    Could not find a package configuration file provided by "imguiwrap" with
     any of the following names:
    
       imguiwrapConfig.cmake
       imguiwrap-config.cmake
    

    And the fact that nothing got "installed".

    When listing the files in the install prefix of a gitache project, I expect to see something like:

    >ls /opt/gitache/libcwd_r/49222d132e2085669a45e519a8165087bfbe40eb818eb0743f5f7caf4a89a683/
    DONE  include/  lib/  share/
    

    with installed headers in include, the libraries in lib etc. (Most notably, 'lib' contains (apart from the library itself):

    lib/cmake/libcwd_r/libcwd_rConfigVersion.cmake
    lib/cmake/libcwd_r/libcwd_rConfig.cmake
    lib/cmake/libcwd_r/libcwd_rTargets.cmake
    lib/cmake/libcwd_r/libcwd_rTargets-release.cmake
    lib/pkgconfig/libcwd_r.pc
    

    For imguiwrap I end up with:

    >ls /opt/gitache/imguiwrap/0d4482cb3cc895fda9ade4fa0a5452f208bcc226fd07e7c60f0c10c52816f54d
    DONE
    

    a completely empty directory.

    Obviously this doesn't allow my project to find anything - no headers and no library.

    opened by CarloWood 0
Owner
Oliver Smith
Oliver Smith
This is a thin c-api wrapper programmatically generated for the excellent C++ immediate mode gui Dear ImGui.

cimgui This is a thin c-api wrapper programmatically generated for the excellent C++ immediate mode gui Dear ImGui. All imgui.h functions are programm

Victor Bombi 22 Jul 5, 2021
Simple ImGui external base. Uses ImGui DX9.

ImGui External Base ??️ What is this? ⚡ Hello all! I used to use noteffex's loader base for all my external ImGui projects. I got bored of using this

Alfie 11 Jun 29, 2022
imgui-filebrowser is a header-only file browser implementation for dear-imgui. C++ 17 is required.

imgui-filebrowser imgui-filebrowser is a header-only file browser implementation for dear-imgui. C++ 17 is required. Getting Started imfilebrowser.h s

Z Guan 382 Aug 1, 2022
An addon of imgui for supporting docks in the imgui's window

An addon of imgui for support dock in the window

BB 197 Aug 3, 2022
Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies

Dear ImGui (This library is available under a free and permissive license, but needs financial support to sustain its continued improvements. In addit

omar 40.3k Aug 5, 2022
Advanced 2D Plotting for Dear ImGui

ImPlot ImPlot is an immediate mode, GPU accelerated plotting library for Dear ImGui. It aims to provide a first-class API that ImGui fans will love. I

Evan Pezent 2.5k Aug 8, 2022
super duper simple gui for C, wrapping imgui and stb

super duper simle gui for C, wrapping imgui and stb You can use it as a static library with cmake. See the example directory for a complete example. E

Rasmus 11 May 19, 2022
Real-time GUI layout creator/editor for Dear ImGui

ImStudio Real-time GUI layout creator/editor for Dear ImGui Inspired by Code-Building/ImGuiBuilder Features Drag edit Property edit Covers most of the

null 229 Aug 3, 2022
KeyAuth login form made with ImGui.

KeyAuth-ImGui-Example KeyAuth ImGui Example Download Repository Download the DirectX SDK

Lolys 18 Jul 11, 2022
An integrated information center created with dear ImGui using modern C++ design / coding style.

ImGui info-center Introduction An integrated notification and information center created with dear ImGui. Interfaces and variables are designed under

Feej 6 Jul 20, 2022
ImGuiBase - A very good & simple external ImGui base

ImGuiBase Join CProject to learn about ImGui! https://discord.gg/dnkdDuUtQu Check out our website: https://cproject.xyz Check out the youtube tutorial

null 17 Jul 17, 2022
Addon widgets for GUI library Dear ImGui.

ImGui-Addons Addon widgets for GUI library Dear ImGui. File Dialog A simple cross-platform file dialog that uses dirent interface for reading director

null 252 Aug 8, 2022
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 Jun 22, 2022
This is a software renderer for Dear ImGui. I built it not out of a specific need, but because it was fun

Dear ImGui software renderer This is a software renderer for Dear ImGui. I built it not out of a specific need, but because it was fun. The goal was t

Emil Ernerfeldt 199 Jul 2, 2022
glw_imgui - C++ IMGUI implementation

glw_imgui - C++ IMGUI implementation Immediate Mode UI C++ implementation. IMGUI is a code-driven, simple and bloat-free GUI system, widely used in mo

null 51 Feb 8, 2022
Unity OnGUI(IMGUI) extensions for Rapid prototyping/development

RapidGUI Unity IMGUI extensions for Rapid prototyping/development. Installation Install via OpenUPM The package is available on the openupm registry.

null 242 Jul 27, 2022
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 796 Jul 28, 2022
Window and GUI system based on Dear ImGui from OCornut

ImWindow Window and GUI system based on ImGui from OCornut. Include docking/floating window, multi window and multi render support. Platform Actually

Thibault Hennequin 687 Aug 2, 2022
Nice things to use along dear imgui

Mini hexadecimal editor! Right-click for option menu. Features: Keyboard controls. Read-only mode. Optional Ascii display. Optional HexII display. Goto address. Highlight range/function. Read/Write handlers.

omar 624 Aug 7, 2022