[HN Gopher] Raygui - A simple and easy-to-use immediate-mode GUI...
___________________________________________________________________
Raygui - A simple and easy-to-use immediate-mode GUI library
Author : maydemir
Score : 144 points
Date : 2022-03-26 16:00 UTC (6 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| synergy20 wrote:
| I have seen quite often 'immediate mode gui' on HN and elsewhere
| these days,I rarely do GUI myself, where are these im-gui's use
| cases? gaming only? or some embedded boards with limited
| resources can benefit to draw some pixels on a small LCD for a
| simple GUI(even that people are more likely use some light-weight
| x11 like libraries instead of im-gui library)?
|
| Other than game-development why is im-gui better than those
| normal widget kits we are relatively more familiar with: gtk,
| qt,etc)? or im-gui is specifically for gaming coding?
| throwaway684936 wrote:
| Immediate mode GUIs can be used for almost anything that
| retained mode GUI toolkits (GTK, Qt) can be used for. It
| removes a lot of the overhead and boilerplate to speed up
| development.
| flohofwoe wrote:
| It's (more or less) just a different approach to describe a UI
| through code which does away with objects, event handlers or
| data binding. Very convenient for purely code driven UI
| development.
| quotemstr wrote:
| Many people at a certain point in their careers become
| infatuated with the idea of making a "small", "simple", and
| "opinionated" component free from legacy "BS". They have the
| skill to implement the core of that component but lack the
| wisdom and humility to understand that the "BS" complexity
| exists for good reasons, that their "small" component is
| subject to those reasons, and that they haven't actually found
| a fundamentally better approach that avoids the "BS", but
| merely skipped the hard parts of software engineering.
|
| You just have to let people go through this phase. You should
| nod, smile, and compliment them on the economy of their vision.
| This phase hones skills people need for more serious endeavors.
| Butt God help you if you actually use one of these "small"
| systems in production!
| throwaway684936 wrote:
| Immediate mode is generally used for quick and dirty
| developer tools. It's rarely used for user-facing UI. You're
| free to waste your time carefully architecting an MVC
| application any time you want a few text boxes and sliders to
| fiddle with something. Microsoft, Google, Nvidia, Valve, Id,
| Blizzard, Ubisoft will continue to use immediate mode where
| they deem it useful, in spite of your advice.
| Adverblessly wrote:
| IMO The main benefit of immediate mode GUI is that (unlike
| "normal widget kits"), the data required to "drive" the widgets
| is not actually owned by the widgets themselves, making widgets
| controlled directly by the "program's" data. You make some sort
| of change to the program's data and it is immediately reflected
| on the screen. This is as opposed to the "normal widget kits"
| where you need some "glue" to reflect those changes for example
| maybe you need to let the widget know its contents were updated
| and it needs to redraw or redo its layout.
|
| This makes it easier to create certain types of UIs where the
| main interaction is to modify some data structure directly,
| which is how many simple tools behave.
| schaefer wrote:
| Immediate mode guis let you structure your code differently
| than traditional libraries. (gtk, etc.)
|
| It's can be such a fast and light way to work. Get this thing
| done. And move on to the next thing.
|
| To me it's just a valuable addition to our toolbox and our
| quest to use the right tool for the right job.
| frankzander wrote:
| The used font is really cruel ... I hope it's interchangeable
| crispyalmond wrote:
| It does support changing the font
| a-priori wrote:
| Before you start picking up a library like this, keep in mind
| that no immediate-mode GUI library I'm aware of (including this
| one from what I can see in the source code) has support for
| assistive technologies such as screen readers.
|
| To them the whole UI is one big black box, so your program is
| completely useless to anyone with a wide range of disabilities.
| milansuk wrote:
| Do operation systems have APIs, so the program can send them
| what is on the screen? I mean just description like: There is
| the button with title "Push me" in the rectangle(50, 50, 100,
| 70), etc.
|
| Or are there any "screen reader" libraries?
| jcelerier wrote:
| Yes, OSes have APIs. Another commenter talked about the Mac
| one, Linux has AT-SPI and Windows has MSAA (historic) and
| UIA. If I'm not mistaken, they generally are about
| representing the UI as a tree of items as this is what the
| accessibility hardware expects / works best with.
| pjmlp wrote:
| Yes they do, at least Apple, Google and Microsoft ones.
|
| On GNU/Linux, I think the only thing that exists in the Gtk+
| features that were originally sponsored by Sun.
| malkia wrote:
| Even systems like Qt, where things are drawn using non-native
| widgets support that (I was long proponent of wxWidgets,
| because I thought assistive tech is only support only if you
| use native widgets. The idea of API where you explain what
| you are showing, and how to interact with it never came to my
| mind, but with ARIA - like any browser that's the way to go).
|
| Not only that, but I thhink assistive tech should allow you
| do to easier GUI testing too, but haven't digged into that
| idea yet (probably folks already are)
| fatih-erikli wrote:
| There's a10n standards defined by w3c,
| https://www.w3.org/TR/using-aria/.
| a-priori wrote:
| Yes. I don't know about Windows but I know that for OSX you
| need to implement the NSAccessibility protocol in AppKit.
| This gives you a way to describe the hierarchy of the UI and
| to notify the system of important changes.
| [deleted]
| eliasnaur wrote:
| The immediate mode Gio (gioui.org) toolkit has support for
| accessibility (on Android for now), IME and, recently, RTL text
| layout.
|
| Disclaimer: I'm the author.
| mwcampbell wrote:
| I can also report some modest progress on my own work on
| accessibility of immediate-mode GUIs. I have a branch of the
| Rust egui library [1] that has basic accessibility on Windows
| using my AccessKit project [2]. I do have a long way to go to
| make this fully usable and ready to submit upstream,
| especially when taking non-Windows platforms into account.
|
| [1]: https://github.com/mwcampbell/egui/tree/accesskit
|
| [2]: https://github.com/AccessKit/accesskit
| a-priori wrote:
| That's great, thanks for the letting me know!
| nikki93 wrote:
| I've been using an immediate mode api that generates html
| elements in web, so that you do get the things that html
| offers. I basically have a thin wrapper around
| http://google.github.io/incremental-dom/ (I'm using it from
| wasm) -- calling it per frame has actually been reasonable
| perf-wise.
| [deleted]
| nanochad wrote:
| AbuAssar wrote:
| Does anyone care to explain what immediate mode means?
| delian66 wrote:
| See
| https://en.wikipedia.org/wiki/Immediate_mode_(computer_graph...
| , and https://en.wikipedia.org/wiki/Immediate_mode_GUI .
|
| TLDR: instead of declaring your GUI objects/components ahead of
| time, and letting a framework render the prepared scene graph
| (while calling you back when there are user triggered state
| changes), you just draw the GUI objects yourself in your main
| loop, just like you draw all your other objects (backgrounds,
| sprites, models etc).
| modeless wrote:
| Immediate mode is a style of API where important state is kept
| in user code instead of being retained inside the API
| implementation. For example, an immediate mode GUI checkbox
| implementation does not store a boolean value determining
| whether the checkbox is checked. Instead, user code passes that
| information as a function parameter whenever the UI needs to be
| drawn. Even the fact that a checkbox exists on screen is not
| stored in the GUI library. The checkbox is simply drawn when
| user code requests it each frame.
|
| Couterintuitively this is often less complicated than the
| traditional "retained mode" style of GUI libraries because
| there is no duplication of state. That means no setup or
| teardown of widget object trees, no syncing of state between
| GUI objects and application code, no hooking up or removing
| event handlers, no "data binding", etc. The structure and
| function of your UI is naturally expressed in the code of the
| functions that draw it, instead of in ephemeral and opaque
| object trees that only exist in RAM after they're constructed
| at runtime. You retain control over the event loop and you
| define the order in which everything happens rather than
| receiving callbacks in some uncertain order from someone else's
| event dispatching code.
|
| Crucially, "immediate mode" is a statement about the
| _interface_ of the library, not the internals. Common
| objections of the form "immediate mode GUIs can't support X"
| or "immediate mode GUIs are inefficient because Y" are
| generally false and based on a misconception that immediate
| mode GUIs are forbidden from retaining any internal state at
| all. It is perfectly normal for an immediate mode library to
| retain various types of internal state for efficiency or other
| reasons, and this is fine as long as the state stored in user
| code remains the source of truth. This can even go as far as
| internally constructing a whole retained widget tree and
| maintaining it via React-like tree diffing.
| theonething wrote:
| sounds like html over the wire in the web world. State only
| resides on the backend. I think it's a good direction.
| lolinder wrote:
| Jetpack Compose on Android has an API exactly like you
| describe, but I've never heard it described as an immediate-
| mode GUI. Is it one, or is there something else that makes a
| GUI toolkit immediate-mode?
| modeless wrote:
| Jetpack Compose is very interesting, but I don't think it's
| exactly what I described. It explicitly retains a lot of
| state including a widget tree and event handlers. Although
| the state is opaque because there is no DOM-like API to
| inspect it, the user is still required to reason about the
| retained state and know exactly when and which parts should
| be invalidated. It provides a lot of "convenience" features
| for the user to annotate and wrap state which is expected
| to change so that invalidation can happen semi-
| automatically. But that results in a lot of rules you must
| follow which can't be automatically checked or enforced,
| which ends up being rather complex I think:
| https://developer.android.com/jetpack/compose/state and
| https://developer.android.com/jetpack/compose/side-effects
|
| Here's a checkbox in Jetpack Compose with the required
| state annotation and event handling stuff, which if
| forgotten or done incorrectly will make the checkbox
| silently malfunction: val checkedState =
| remember { mutableStateOf(true) } Checkbox(
| checked = checkedState.value, onCheckedChange =
| { checkedState.value = it } )
|
| And here's a checkbox in Dear Imgui which just uses a plain
| bool and no event handlers (also note that this includes a
| clickable text label which would require additional event
| handlers with Compose): static bool foo =
| true; // could be any bool in the application, nothing
| special about this one ImGui::Checkbox("Foo
| enabled", &foo)
|
| Here's a great example of how the retained state in Jetpack
| Compose can confuse people:
| https://stackoverflow.com/questions/70040541/jetpack-
| compose...
| panzerboiler wrote:
| The best explanation is probably the one by Casey Muratori
| (https://caseymuratori.com/blog_0001). He devised the technique
| and conied the term in 2002.
| ahefner wrote:
| Can't imagine he was the first person to use this technique.
| I'd assume any game written from the point where it was
| reasonable to continually redraw the screen instead of using
| incremental repainting would've used such a technique,
| because it's simply the easiest way to implement random ad-
| hoc GUIs if you don't have a widget toolkit underneath you
| (and possibly even if you do).
| [deleted]
| chrisdalke wrote:
| Related, check out raylib, the rendering/game engine made by the
| same author!
|
| I've used Raylib and raygui on a few RPi based projects and
| recommend it. It's a really simple, intuitive way to get an
| OpenGL-based UI running. Good alternative to web-based UIs
| because it has similar simplicity but runs on devices with lower
| specs. I built this pinball machine with raylib:
| https://youtu.be/iiBn7FVzlcc
| deckarep wrote:
| Brilliant project and execution. I love the idea of bringing
| the tactile experience together with a digital gaming
| experience.
| wly_cdgr wrote:
| Ray is amazing. He's been at it since around 2014. Super
| friendly, super responsive dude
| matthewfcarlson wrote:
| This is fantastic, it's a shame this doesn't have more views.
| If it's okay, I submitted it to the hackaday.com tip line.
| chrisdalke wrote:
| Thanks! A little more detail at
| https://www.chrisdalke.com/projects/mini-pinball-machine/,
| and the Raylib-based code is on GitHub:
| https://github.com/chrisdalke/mini-pinball-machine
| infogulch wrote:
| There has been a recent explosion of immediate-mode GUIs
| recently, but I'm skeptical that an immediate-mode solution can
| cover our GUI needs now and into the future.
|
| High refresh rate screens are a reality so you only have 3-6ms to
| render each frame, as well as high resolution screens at 4k-8k.
| That's _a lot_ of pixels to push with a CPU on every frame. As
| another comment points out we also need accessibility. I would
| generalize this need as "GUIs need to be _reinterpretable_ ",
| this need is not limited to those with disabilities and such a
| capability can be useful to anyone that wants to customize,
| automate, and integrate their digital tools.
|
| Are immediate-mode GUIs up to the task? What is driving their
| authors to pursue this design? Why aren't they choosing a
| declarative design?
| _trackno5 wrote:
| I don't get your point here. What's the problem with high
| refresh rates? Games deal with it no problem, and they do way
| more complicated stuff than a UI with a bunch of buttons and
| text.
|
| > Are immediate-mode GUIs up to the task?
|
| Yes, there's no reason why imgui's can't do any of that.
|
| > What is driving their authors to pursue this design?
|
| To name a few: Ridiculous bloat and complicated development
| with things like Qt. No real GUI framework provided by
| Microsoft apart of their 4-5 half-abandoned offerings.
|
| Also imgui is way simpler to wrap your head around. It's just
| straight up function calls with no complicated abstractions.
|
| > Why aren't they choosing a declarative design?
|
| Why should it be declarative though? imgui code looks fairly
| declarative when you read it and it's easy to understand what
| UI events cause changes
| throwaway684936 wrote:
| >What is driving their authors to pursue this design?
|
| The fact that it requires an order of magnitude less code to do
| functionally the same thing as traditional toolkits.
|
| >Why aren't they choosing a declarative design?
|
| Because they aren't trying to build a native, standalone
| desktop application. Declarative design makes little sense for
| quick and dirty developer tools that just need to directly view
| and modify simple data structures.
| hexomancer wrote:
| All these pixels have to be pushed every frame even with
| classic GUI. The only difference is that it is usually done by
| the operating system.
| infogulch wrote:
| The advantage of a declarative design is that it can be
| accelerated by the GPU which has a much better scaling
| computational architecture to serve this need.
| _trackno5 wrote:
| Can you give more details on how this GPU acceleration
| works?
| dymk wrote:
| Both declarative and imperative UI frameworks benefit just
| fine from GPU acceleration, that's orthogonal to the
| underlying drawing mechanism
| flohofwoe wrote:
| "Immediate mode" just describes the programming model (e.g.
| how the UI is described with code and how the code reacts
| to user input), it doesn't tell anything about how
| rendering happens (or really anything that happens under
| the hood).
| mortehu wrote:
| It does imply to some degree that the entire geometry of
| the UI isn't stored in GPU memory. It's possible to store
| an entire UI, with text and all, in GPU memory and render
| it with a single call (e.g. glDrawElements).
| flohofwoe wrote:
| ...and those GPU buffers need to be rebuilt as soon as
| anything in the UI changes. An immediate mode UI could
| just as well track state changes and only rebuild GPU
| buffers if needed.
|
| Most just don't this (and instead use dynamic buffers
| which are updated with new data each frame) because the
| state diffing would complicate the implementation and is
| usually "not worth it", but they still implement batching
| within a single frame and reduce the amount of draw calls
| as much as possible (for instance in Dear ImGui, there's
| usually one draw call per scroll/clip region so you get
| away with a handful or at most a few dozen draw calls
| even for complex UIs).
| [deleted]
| throwaway684936 wrote:
| Dear-imgui, the most popular and mature immediate mode GUI
| library, renders with OpenGL/Vulkan/DirectX.
| eliasnaur wrote:
| With intelligent frame pacing you can sacrifice, say, a frame
| of input latency to sustain high frame rates. See https://raphl
| inus.github.io/ui/graphics/gpu/2021/10/22/swapc....
|
| > Are immediate-mode GUIs up to the task? What is driving their
| authors to pursue this design? Why aren't they choosing a
| declarative design
|
| Immediate mode UIs make managing state much easier, and avoids
| callbacks for event processing. That alone is worth it in my
| opinion.
| welklkjlerg wrote:
| pmorici wrote:
| Can this be used with the Linux frame buffer device on embedded
| systems without a window manager?
| 999900000999 wrote:
| Would it be possible to define the GUI with XML, Unity just added
| this officially and it makes life much better.
|
| Then you do something like
| rootGUI.Query("elementID").RegisterCallback( e => otherFunc(e));
| dividuum wrote:
| The joy of immediate mode guis is that you don't have to
| register callbacks or manually modify (for example) the
| visibility of elements in response to some action. Instead you
| do: if checkbox(&show_debug, "Show debugging
| features") { if button("Run some test") {
| test()
| pjmlp wrote:
| Joy for ones, pain for others, I don't miss coding GUIs like
| MS-DOS MODE X or Linux's SVGAlib.
| 999900000999 wrote:
| But then if you need to change some non interactive parts of
| the UI, your digging though source code instead of modifying
| XML.
|
| Defining the UI via code becomes cumbersome, stuff like
| adding attributes, etc
| rstat1 wrote:
| Changing attributes of UI elements defined in code vs some
| XML format is in my mind the same level of effort.
|
| button.SetBackground(<color>)
|
| or
|
| <button backgroundColor="<color>" />
|
| I see no difference there.
|
| EDIT: Ok the main difference I guess would be having to
| switch files (and thus context) which could be annoying.
| Plus there's also the non-zero performance impact from
| having to parse an XML format.
| 999900000999 wrote:
| What if you have stacked elements, or elements within
| elements.
|
| <Box> <Button> <Icon/> </Button> </Box>
|
| In code it's something weird like
|
| Box(button( Icon() )))
| dragonwriter wrote:
| How is: Box( Button(
| Icon(...) ) )
|
| Weirder than: <Box> <Button>
| <Icon ... /> </Button> </Box>
| 999900000999 wrote:
| Now attach some callbacks.
|
| With XML I'm attaching my callbacks via code while
| defining the UI elsewhere.
|
| With pure code, I have to attach the callbacks directly
| to the object.
|
| Theirs a reason you don't just use JavaScript to define
| React components
| dragonwriter wrote:
| > Now attach some callbacks.
|
| Not that any of this is relevant to immediate mode GUI,
| but the actual attachment of callbacks can be done
| identically in code no matter how the base UI design is
| done if you want it separately, but if you do it in code
| (whether with normal syntax or a funky transform like
| JSX) you can also have the option of direct attachment.
|
| > With pure code, I have to attach the callbacks directly
| to the object.
|
| No, you don't, but you can, and as it turns out, that's
| kind of popular.
|
| > Theirs a reason you don't just use JavaScript to define
| React components
|
| You can, in fact, but even when you use JSX, there is a
| reason you don't use actual (HT/X)ML code, but instead a
| language that compiles to, and let's you freely mix in,
| JavaScript.
| 999900000999 wrote:
| Let's say you have a really complex UI.
|
| Would you really define your UI in code over XML or HTML
| setr wrote:
| Yes.
|
| The more complex and more dynamic the UI, the worse the
| separation gets. The worst of it being when you're
| writing code to generate your XML/HTML, and probably
| introducing a third "templating" language to continue the
| pretense that HTML/XML is not just standard data
| structures defined in a different syntax.
|
| The purpose of XML/HTML is to make your GUI specification
| independent of the programming language itself, and
| independent of any particular library ( _anyone_ can spit
| out an HTML <button>... it's quite difficult for C++ to
| construct a Java Button class).
|
| And there's some notion that it's easier for "non-
| programmers" to edit, without being bogged down
| programming language details (its "easier" to learn HTML
| than Java... and as programmers we eat the cost by now
| having to learn both)
| dividuum wrote:
| You're in the wrong thread. :-)
|
| The main benefit of most immediate mode guis I've seen is
| that it's trivial to expose internal values to a ui in
| one line of code. No callbacks, no looking for the right
| place in any XML file or similar. Instead you add these
| lines when you need them and they show up in a ui:
| checkbox(&godmode, "Activate Godmode")
| slider(&enemy_aggro, "Enemy aggression", 0, 100)
| rstat1 wrote:
| Its entirely dependent on how w/e library your using
| implements that pattern. For the code I just recently
| wrote that does a similar thing, its literally just:
|
| button.SetIcon(<icon-path-or-font-glyph>)
|
| box.add(button)
|
| Doesn't really seem all that weird to me.
| elcritch wrote:
| I prefer the best of both worlds. I've been making a YAML
| like widget syntax in code using an immediate mode GUI
| written in Nim. It let's me write things like:
| Horizontal: box 10.WPerc, 100, 8.Em, 2.Em
| Button: text: fmt"Clicked4: {self.count:4d}"
| setup: size 8.Em, 2.Em onClick:
| self.count.inc()
|
| https://github.com/elcritch/fidget/blob/devel/tests/basic
| wid...
| conradludgate wrote:
| Wait until you find out about HTML and the document object in
| Javascript
| jensus wrote:
| The evolution of HTML and CSS clearly shows that HTML isn't
| suited to describe a interface without massive hints to a
| rendering engine to manipulate it
| conradludgate wrote:
| You say that, but I have a really hard time making any
| native UI toolkit look how I want it to
| formerly_proven wrote:
| This is almost by definition incompatible with the immediate
| mode paradigm and UXML is for UI Toolkit, which is retained-
| mode.
| weakfish wrote:
| Looks like metal gear solid. Nice.
| b20000 wrote:
| very cool. there are already immediate mode libs with a focus on
| tools. what i'm more interested in is really great gui libs that
| make architecting multimedia or audio applications easy without
| requiring me to learn and use game engines. ideally on top of
| opengl(es) and linux (arm) support. i am thinking about
| applications where you want cooler UI effects and UX than what we
| are all used to, like what you sometimes see in games. i just
| don't want to do all the drawing myself and don't want to use
| game engines. stuff like qt is too heavyweight and too much
| traditional UI focused. most UI frameworks also have little
| support built in for advanced producer/consumer or
| multithreading/work load balancing scenarios and expect you to
| roll all that stuff yourself over and over.
| Pulcinella wrote:
| Cocoa and CoreAnimation on the Mac allow you to apply arbitrary
| CoreImage filters to UI elements (not just images) and you can
| even write your own filters using the Metal shading language
| (though that's basically doing a lot of the drawing yourself).
|
| Unfortunately this doesn't work on iOS (probably for power
| consumption reasons). Apple does have some filters for things
| like Gaussian blurs, but they are a private API.
| Flankk wrote:
| JUCE is the best option. Shopify came out with React Native
| Skia, which allows you to draw whatever you need. You can also
| use Skia directly but it's only a drawing library. I wanted to
| use something like IMGUI but it's hard to theme and not
| designed for consumer products. This raygui looks cool but it's
| bitmap fonts which is no good for i18n.
|
| Edit: Looks like it uses real fonts it just includes a crappy
| one. I'll have to take a closer look at this.
| teawrecks wrote:
| Immediate mode GUIs are usually pretty inefficient. I wouldn't
| use it as a permanent solution in a product. More like a quick
| way to add controls to avoid having to close the app and edit a
| config file, or recompile with different params.
|
| Usually you want app GUIs with a style that matches the rest of
| the apps. Though mobile kinda changed that. I don't know of a
| performant UI framework for building non traditional desktop
| apps.
| hexomancer wrote:
| Does it support RTL languages?
|
| My main problem with DearImgui is lack of RTL language support. I
| think one of the biggest factors which deter people from using
| immediate mode GUI is lack of support for many languages.
| artemonster wrote:
| What languages?
| poisonborz wrote:
| https://en.wikipedia.org/wiki/Right-to-left_script
| hn_version_0023 wrote:
| I believe they're referring to languages that read "Right To
| Left"
| artemonster wrote:
| Thanks!
| eliasnaur wrote:
| FWIW, Gio (gioui.org) recently added support for RTL languages
| and complex scripts. So there's no fundamental reason immediate
| mode UIs can't have the nice features you're used to from
| retained mode UIs.
___________________________________________________________________
(page generated 2022-03-26 23:00 UTC)