# \[ANN\] CImGui.jl - A Wrapper for Bloat-free Immediate Mode Graphical User interface(Dear ImGui)

**URL:** <https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268>\
**Category:** Package Announcements\
**Created:** [February 27, 2019, 4:22pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268 "2019-02-27T16:22:39Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [February 27, 2019, 4:22pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/1 "2019-02-27T16:22:39Z")

</div>

[CImGui.jl](https://github.com/Gnimuc/CImGui.jl) is a wrapper for [cimgui](https://github.com/cimgui/cimgui): a thin c-api wrapper programmatically generated for the excellent C++ immediate mode gui [Dear ImGui](https://github.com/ocornut/imgui). Dear ImGui is mainly for creating content creation tools and visualization / debug tools. Let me quote from ImGui’s README directly:

> Dear ImGui allows you create elaborate tools as well as very short-lived ones. On the extreme side of short-liveness: using the Edit&Continue (hot code reload) feature of modern compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! Dear ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, an entire game making editor/framework, etc.

CImGui.jl aims to provide the same user experience as the original ImGui C++ API and I’ve ported almost all of the built-in demos of ImGui to Julia:

![37%20PM](https://global.discourse-cdn.com/julialang/original/3X/b/1/b10eb02194822a3dae568b3f55fec0533f6916f4.gif)  
 ![37%20PM%202](https://global.discourse-cdn.com/julialang/original/3X/c/d/cd4230b266ea4e2308b7bd86724c8802d789715b.gif)  
 ![37%20PM%203](https://global.discourse-cdn.com/julialang/original/3X/b/c/bcba9f72cbecc15d274d0cf56d45a4e50ceceaa3.gif)  
 ![37%20PM%204](https://global.discourse-cdn.com/julialang/original/3X/3/3/3312c8f3d493e3d83de1b15b4919d38ae7bd905d.gif)

This package is still somwhat in its BETA phase. Any feedback would be highly appreciated!

Cheers!

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [February 27, 2019, 4:57pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/2 "2019-02-27T16:57:02Z")

</div>

This is great. Your demo loaded in 1 second the first time.

Would it be possible to integrate this with Observables?

---

<div class="post-metadata">

**Author:** ![musm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/musm/32/3675_2.png) [@musm](https://discourse.julialang.org/u/musm)\
**Post date:** [February 27, 2019, 5:09pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/3 "2019-02-27T17:09:37Z")

</div>

How does this compare to Nuklear.jl. I.e. relative advantages, disadvantages, etc?

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [February 27, 2019, 8:16pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/4 "2019-02-27T20:16:13Z")

</div>

he should know, he made that library too 😄

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [February 28, 2019, 12:10am UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/5 "2019-02-28T00:10:58Z")

</div>

That’s probably due to JIT overhead, those examples are not precompiled.

I didn’t know Observables.jl before, it looks like we could build a more easy to use high-level GUI interfaces with it.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [February 28, 2019, 12:37am UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/6 "2019-02-28T00:37:12Z")

</div>

I meant that is amazingly fast! To load an interface from cold start of Julia just after the package install 🙂 GUIs normally take forever in Julia.

Observables do make it pretty easy to connect things together. Makie and Interact.jl use them, Gtk has GtkReactive which uses the older Signals based framework.

Another benefit of using Obserables is that apps could abstract the interface for all the common widgets, and say swap ImGui for a web interface when required without too much work.

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [February 28, 2019, 1:34am UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/7 "2019-02-28T01:34:18Z")

</div>

Both nuklear and Dear ImGui are inmmediate mode GUIs. Both their design and APIs are quite the same. One distinctive feature of nuklear is its customizability(via these [flags](https://rawgit.com/vurtun/nuklear/master/doc/nuklear.html#nuklear/usage/flags)), but these implementation details are usually agnostic to end users and many wrappers like Nuklear.jl only use a fixed configuration, so this advantage is totally lost.

On the other hand, Dear ImGui is under active and sustainable maintenance. There are some cool features like [docking and multi-viewport](https://github.com/ocornut/imgui#roadmap) will be coming in this year. For now, CImGui.jl has a thin wrapper which is as close as the original C++ API, so CImGui.jl’s interfaces are simpler than Nuklear.jl’s C89 API.

---

<div class="post-metadata">

**Author:** ![purplishrock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/purplishrock/32/13451_2.png) [@purplishrock](https://discourse.julialang.org/u/purplishrock)\
**Post date:** [February 28, 2019, 6:35am UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/8 "2019-02-28T06:35:30Z")

</div>

that looks awesome. i’ve been wanting a simple gui tool to be able to put simple drawings in a window and give it basic controls like zoom, pan , etc…

this looks perfect for that!

i’m shocked that i’ve never heard of dear imgui before.

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [February 28, 2019, 8:05am UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/9 "2019-02-28T08:05:20Z")

</div>

That’s probably because Dear ImGui is not for creating UIs for the average end-user. As explained in the Dear ImGui’s [FAQs](https://github.com/ocornut/imgui/blob/f02705fbaa22cad03f0b033d901f8b232dfb1ce5/imgui.cpp#L569-L653), it’s a renderer-agnostic GUI lib and does not provide any 2D/3D rendering utilities by default. People need to build their own 2D texture renderer for drawing images. Although this can be done in a couple of lines using quite a few knowledge in 3D graphics, the learning curve may look steep for those who don’t have any relevant background. Maybe I should add a default 2D image renderer to CImGui.jl. I’m still looking for a way to integrate ImGui with other 2D plotting tools in the Julia ecosystem, so stay tuned. 🙂

My personal use case is to build simple GUI tools for 3D computer vision tasks like [IntelRealSense-viewer](https://github.com/IntelRealSense/librealsense/tree/d39b5139ce62efffddee4cd11a87e8927ecdfa0c/tools/realsense-viewer) or [open3d](http://www.open3d.org/). I feel like Dear ImGui is the perfect tool for this kinda use case. The learning curve of its API is really flat.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [February 28, 2019, 12:14pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/10 "2019-02-28T12:14:14Z")

</div>

Hi @Gnimuc, thanks for this one more contribution to the GUI packages, it looks really impressive. But, like in the Nuklear.jl case, I still have the problem with the font size that it’s too small in HD screens. In the Nuklear case you added the possibility to increase the font size. That kind of worked but it requires that each user sets the fonts to adjust to his/her case. Isn’t there a more general solution to this problem?

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [February 28, 2019, 12:24pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/11 "2019-02-28T12:24:10Z")

</div>

Really nice! The demo loads very fast and has so many features! I concur with the suggestion of using Observables for the logic (it has worked quite well for Interact and Makie as far as I understand).

I’m playing with the idea of trying to unify “widget syntax” across GUI packages based on a lightweight [Widgets.jl](https://github.com/piever/Widgets.jl) package ([here](https://juliagizmos.github.io/Interact.jl/latest/custom_widgets/) are some docs). The idea is that a Widget has some components, optionally an output and a layout function that defines how it’s rendered. The idea is that the GUI package needs to define a backend and overload methods for the backend for the various widgets (slider, textbox, spinbox, dropdown, etc…) and then the same syntax (including fancier things like [@manipulate](https://juliagizmos.github.io/Interact.jl/latest/custom_widgets/#A-simpler-approach:-the-manipulate-macro-1)) would work on various backends. [Here](https://github.com/JuliaPlots/AbstractPlotting.jl/pull/88) is an attempt of doing that for AbstractPlotting/Makie.

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [February 28, 2019, 12:34pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/12 "2019-02-28T12:34:25Z")

</div>

This is actually another reason why I prefer Dear ImGui. There is a StyleEditor shipped along with the library. You could uncomment the following code to pre-load different fonts:

> <https://github.com/Gnimuc/CImGui.jl/blob/f03c9eb73571db1433e4c74114375ccdcefa2be9/demo/demo.jl#L50-L58>

and let users to config their favorite style:

> <https://github.com/Gnimuc/CImGui.jl/blob/f03c9eb73571db1433e4c74114375ccdcefa2be9/examples/demo_window.jl#L195-L199>

![08%20PM](https://global.discourse-cdn.com/julialang/original/3X/e/c/ecddde0d5a88a2e1a933e6ae316d17cb8675cd36.gif)

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [February 28, 2019, 12:43pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/13 "2019-02-28T12:43:53Z")

</div>

X-ref:

> <https://github.com/ocornut/imgui/issues/707>
>
> I have decided to include a few better color themes in the default packaging, pe…rhaps as soon as next release (1.50).
> 
> The reasoning is that I want to do it to reduce the like-hood of people actually messing up too much with styling themselves. In small part because this is taking people time, and in big part because custom themes are easier to break and create a situation where I am more cautious to change the styling system. So I'm hoping to provide a better baseline with named themes that people are happy with, that we maintain and actually not encourage people to do too much skinning until ImGui is actually ready for it.
> 
> 1.A.
> I would like to improve the existing default theme. Most probably, the main button colors needs to be changed, they are the worst looking now. A slight amount of tweaks to the current default theme would be a good freshening move. If you are in a creative mood please try to have a look at tweaking the default theme :)
> 
> 1.B.
> I would like to add new themes. Please submit yours with suitable screenshots here! I was thinking probably at least a black-ish theme, a white-ish theme. Probably one or two more. While discussing we need to be considerate that slightly transparent windows are useful to many users who are overlaying windows over their game/contents. While this isn't a deal-breaker, it is nice if a theme both work with fully opaque background colors and will slightly transparent colors. You may also submit shots of other software for ideas/references, tho I am hoping to get straight to the point and getting actual settings integrated.
> 
> 2.
> I also would like, if possible, to find a practical way to showcase font changes without adding new building/compatibility issues to the examples/ applications. In particular, depending on the toolset/build system used, the starting directory may be variable and make it a little more work to use external files such as the one exhibited in extra\_fonts/. That's solvable.
> 
> Related topics
> \#438 simplified design
> \#184 new design / colors (not doing right now).

and the [roadmap](https://github.com/ocornut/imgui#roadmap) says:

> Make the examples look better, improve styles, improve font support, make the examples hi-DPI aware.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [February 28, 2019, 2:22pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/14 "2019-02-28T14:22:54Z")

</div>

Yes, much better. Now the widget sizes adapt for larger fonts, which was not the case for Nuklear (I think). And very good news from the roadmap.

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [March 1, 2019, 7:02am UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/15 "2019-03-01T07:02:02Z")

</div>

hi @piever, I have no experience of Interact.jl-based GUI before, so please correct me if I’m wrong. After reading the docs, I feel like the underlying design between ImGui and Interact are quite different.

ImGui is immediate mode UI that doesn’t hold any hidden states, which means it manipulates the value and does “drawing” stuff (emits vertices, textures, drawing cmds, etc to drawing data buffer/window stack) simultaneously. For example, what this line of [code](https://github.com/Gnimuc/CImGui.jl/blob/ec585f97fc86ee957a9bd8deada0ae1642a85ead/examples/demo_widgets.jl#L126-L131) `CImGui.ColorEdit3("color", col1)` does is “drawing” the slider widget and immediately set `col1` to current color/value selected by users. Unlike retained mode UI, all of the widgets get updated every frame regardless of whether the states changed or not(the idea is to update widgets and the states every frame instead of storing hidden states and calculating which widget should be re-rendering). As a result, widgets in ImGui do not return outputs, so current unify widget syntax may not fit.

Considering the following example:

```julia
import Colors
using Plots

function mycolorpicker()
    r = slider(0:255, label = "red")
    g = slider(0:255, label = "green")
    b = slider(0:255, label = "blue")
    output = Interact.@map Colors.RGB(&r/255, &g/255, &b/255)
    plt = Interact.@map plot(sin, color = &output)
    wdg = Widget(["r" => r, "g" => g, "b" => b], output = output)
    @layout! wdg hbox(plt, vbox(:r, :g, :b)) ## custom layout: by default things are stacked vertically
end

```

In ImGui, one might write:

```julia
# this is a fake Julia code snippet, but you may already get the idea.
let
r, g, b = 0, 0, 0 # ImGui won't handle states for us, we need to find a way to store them ourselves.
function mycolorpicker()
    # Interact.@map magic should happen here, but is it still necessary?
    slider(&r, 0, 255, label = "red")
    slider(&g, 0, 255, label = "green")
    slider(&b, 0, 255, label = "blue")
    # emit textures immediately to drawing buffer
    plot(sin, color = Colors.RGB(r/255, g/255, b/255))
    SameLine()/NoSameLine() # layouts are not a part of widgets in ImGui
end
end

```

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [March 5, 2019, 5:45pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/16 "2019-03-05T17:45:28Z")

</div>

My intuition is that the `Widget` struct would be a wrapper for the CImGui widgets. For example, in case of a slider, one would create something where the output is an `Observable` corresponding to the value of the slider and the “layout” (i.e. the thing that is actually rendered would be the CImGui slider), so something like:

```julia
function Widgets.slider(::CImGuiBackend, range; label = label)
  imslider = slider(range)
  imoutput = # observable corresponding to slider output
  Widget{:slider}(output = imoutput, layout = _ -> hbox(imslider, label))
end

```

The tricky bit is to have an observable that carries the value of the slider (which was already mentioned above as "supporting the `Observables` framework). The easiest is probably to initialize the observable to the same value as the slider and at every frame if the slider is changed, update the observable.

---

<div class="post-metadata">

**Author:** ![jpsamaroo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jpsamaroo/32/46804_2.png) [@jpsamaroo](https://discourse.julialang.org/u/jpsamaroo)\
**Post date:** [March 5, 2019, 9:28pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/17 "2019-03-05T21:28:50Z")

</div>

Just want to say that going from an `] add CImGui CSyntax`, to being able to run `julia demo.jl` and have everything work extremely well (and look beautiful and minimalistic to boot) is just absolutely amazing. Thanks for putting this wrapper together @Gnimuc! I look forward to using this for all sorts of stuff. 🙂

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [March 5, 2019, 10:18pm UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/18 "2019-03-05T22:18:35Z")

</div>

Unfortunately I’ve noticed an important downside of `Dear ImGui` (not specifically the Julia wrapper). When we launch the demo window for instances the GPU activity raises above 35%, even if we don’t touch any window. This is quite bad for the durability of battery charges on laptops.

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [March 6, 2019, 4:38am UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/19 "2019-03-06T04:38:39Z")

</div>

> [@piever](#):
>
> The easiest is probably to initialize the observable to the same value as the slider and at every frame if the slider is changed, update the observable.

not quite fits ImGui’s design, but it’s good for `Widget` API consistency, so makes sense to me. 🙂

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [March 6, 2019, 4:50am UTC](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268/20 "2019-03-06T04:50:31Z")

</div>

That’s probably due to the implementation of OpenGL backend is not very efficient. It queries a lot OpenGL global states in the rendering loop:

> <https://github.com/Gnimuc/CImGui.jl/blob/0c5d72d5066b54d37f50e08ae3f93dc7985103db/src/backend/OpenGL/impl.jl#L40-L59>

This implementation is copied from `Dear ImGui` which maybe a trade-off bwteen correctness and performance.

[Next page](https://discourse.julialang.org/t/ann-cimgui-jl-a-wrapper-for-bloat-free-immediate-mode-graphical-user-interface-dear-imgui/21268.md?page=2)
