5 ms·
Has anyone made a serious attempt at a intermediate-mode frontend to desktop GUI toolkits (as opposed to single-application ones that are rendered by some gener
by msoloviev 6y ago
Has anyone made a serious attempt at a intermediate-mode frontend to desktop GUI toolkits (as opposed to single-application ones that are rendered by some general-purpose accelerated graphics library)? I've experimented a little bit in the past (https://github.com/blackhole89/instagui/blob/master/main.cpp https://github.com/blackhole89/instagui/blob/master/main.cpp, whose implementation is based on something pretty close to my understanding of Elm's "virtual DOM" diffing; don't mind the kooky custom macro system), but wound up bumping into a lot of nasty little problems that made hacking on it not a lot of fun.
- adinisom 6y agoYou might be interested in Mike Dunlavey's Differential Execution demo: https://sourceforge.net/projects/dyndlgdemo/files/ https://sourceforge.net/projects/dyndlgdemo/files/ https://github.com/MikeDunlavey/AucUI https://github.com/MikeDunlavey/AucUI He explains it a bit more here: https://stackoverflow.com/questions/371898/how-does-differential-execution-work https://stackoverflow.com/questions/371898/how-does-differen...
- msoloviev 6y agoOh, yeah, the Stack Overflow post especially seems to talk about very similar problems to what I have been grappling with. Thanks for the pointer! The code is pretty opaque to me, though; it's been well over a decade since I've last had any interaction with the WINAPI programming style, Hungarian notation and all. I wonder why he arrives at the conclusion that he needs a full-fledged DSL for what he is doing. I remember that at the time I was working on this, the impression I had was that a lot of my problems would go away if only there were some unique way to identify every distinct invocation of a function (so I could use data along the lines of "you are currently in the 3rd call of Button() in something.cpp"). __FILE__ and __LINE__ get close but don't disambiguate between multiple calls on the same line (and anyhow would need to be baked into the invocations with macro hackery).
- psykotic 6y agoEvery immediate-mode UI deals with the id namespace issue. What they usually have in common is a hierarchical id namespace where you have an id stack and a child id is derived from the parent id via hashing, child_id = hash(parent_id, widget_type, subid). [1] The subid can be derived from widget arguments that are likely to be unique and stable from frame to frame, e.g. a text edit box's buffer pointer. But there always needs to be a way to provide an explicit subid since the implicit method doesn't always cut it. Alternatively, as long as the default subid is stable you can always make it unique by wrapping the widget (and other nearby related widgets) with an explicit pair of push_id/pop_id calls. You can see an example here: https://github.com/ocornut/imgui/blob/master/imgui_demo.cpp#L1701 https://github.com/ocornut/imgui/blob/master/imgui_demo.cpp#.... The defaults work most of the time but this is definitely an aspect of immediate-mode UIs that can't just be treated as a hidden implementation detail. [1] The prevailing use of hashing is a consequence of the popular immediate-mode UI libraries being focused on minimal state per widget. If you already plan to maintain significant state for every widget (as you would need in an immediate-mode interface to win32 controls) you would just do hierarchical interning with sequential id assignment (i.e. the first time a new subid is used with a given parent, it is assigned a sequential global id and put in a table so the association can be memoized across frames) and then hash collisions won't cause id collisions.
- msoloviev 6y agoYeah, I essentially copied imgui's ID stack approach for my experiments too. (I've been using imgui for some other projects to great success.) It still seems like a hack; I'm quite surprised that no programming language (I'm aware of) makes it possible to uniquely identify callsites like that. Maybe it hints at a more general blind spot/free real estate in PL design :) (On the off chance you're curious, I just pushed some previously unpushed updates to that experiment I had sitting around, so now it has labels and text entry too. I guess the real test of the architecture would still be making an alternative "rendering backend" based on win32 widgets or something.)
- psykotic 6y ago
- jkcxn 6y agoNot a serious attempt but I prototyped a single header library for macos and will attempt to make it work on windows too example: https://pbs.twimg.com/media/EuQ-6vzXUAca_Ph?format=jpg&name=large https://pbs.twimg.com/media/EuQ-6vzXUAca_Ph?format=jpg&name=... (ignore the fact the UI goes from bottom to top, that will be fixed) A cross platform gui library needs to have consistent layout across all platforms so it has uses basic flexbox layout algorithm instead of the native macos constraint system, I think this turns out better anyway because flexbox is a lot simpler in my mind. It decouples the layout algorithm from the UI code so you don't need to rerun your whole UI whenever the window changes size. It uses pure c++ native calls instead of objective-c which is kind of crazy but the library user never needs to interact with it