As the title says, I want to practice coding a GUI framework, probably in C++.
I read about a retained and an immediate modes, have a rough understanding how event loop works, and overall my goal is to practice architecture and optimization (especially cache-friendliness), and less so graphics and typography rendering, though I understand it's unavoidable to implement a rendering pipeline (I plan to start off with AGG or Skia graphics libraries).
The dummy app itself will be less about forms but more about data representation, e.g. an audio editor or a node-based system, where data should be updated and visualized in real time, and everything should feel responsive.
Could you please give some research directions? Maybe case studies, best practices, some interesting software, maybe to read more in detail about related architectures, etc.? Or maybe personal stories? I'm struggling to find related info which would not be focused on some framework, etc.
https://www.cs.cmu.edu/~bam/uicourse/05631fall2021/
The second is Dan Olsen's book Developing User Interfaces, which has all of the details of how GUIs work, from graphics to interactor trees to events to dispatching. For some reason, it's absurdly expensive on Amazon right now.
Both Dan Olsen and Brad Myers were early pioneers in GUIs and GUI tools, so you'd be learning from the masters.
I love Dear Imgui: https://github.com/ocornut/imgui
It is the simplest thing in the world. If you are starting and are going to do 3D graphics anyway you don't need state(you just redraw the screen 60 times per second).
Anything else is extremely sophisticated. I also loved Qt, but the policies got a little cumbersome, and went native.
The big problem is that with state there is a lot of complexity involved that is dependent on a platform, and once you pick one it is hard to change.
The big advantage of 3d graphics and dear imgui or any other open source software is that it works anywhere and you are not as dependent on a single company.
Good UI frameworks are composable, and progressively expose their API users (developers) to their constituent parts, which can include systems such as drawing/rendering, animation, compositing, event handling, text editing, view hierarchy, navigation, accessibility, and so forth. As you build more complex applications with a UI framework, you naturally find yourself customizing default behaviors or implementing new controls or functionality on top of the existing capabilities. You start to see how the framework itself is built just by using it.
Once you reach expert level with a UI framework, you will have a conceptual understanding of how high level features of the framework are implemented in terms of the lower level functionality. As an expert, you will feel confident that you could implement a new type of control, or reimplement existing functionality such that your version is a perfect peer to the built-in functionality from the library author on all important axes (developer API, performance, user experience, etc). In some cases this might be a lot of work, but at least you should know generally how to go about it if you had to.
See if you can get to expert level with at least 2 different styles of UI frameworks. At that point, you will be capable of building your own.
The following design patterns are widely used with graphical user interfaces: observer-design pattern; model-view-controller; model-view-presentation; two-way-data binding; property binding; command design pattern; and composite design patterns for representing a collection of objects as single object.
For understanding event loop it may be much easier to implement a Xterm or VT100 keyboard-driven terminal user interface TUI since this does not requiring dealing with too many backends.
I don't have any suggestions for how to build such a framework, but I would encourage you to play around with a few existing frameworks to see how they are designed, what you like about them, and what ideas to avoid.
For just one example, see the difference between managing the event loop entirely by hand with Win32[1] and using "signals and slots" in Qt[2]. There is a lot more to UI frameworks than this, and they vary on many more aspects.
- [1] https://docs.microsoft.com/en-us/windows/win32/winmsg/using-...
Other than that, I do recommend the immediate mode GUI approach if you're writing everything yourself, as it's the lowest overall system complexity of all the approaches. It has a number of drawbacks, and things don't abstract/compose as easily as a standard object-oriented retained, or a newer React/SwiftUI approach, but exposing the raw parts has its upsides.
There is a start of a native Rust GUI which you could contribute to: https://github.com/linebender/druid
Would you be interested in a 'no restrictions, informal' collaboration?
I have little to no experience writing GUIs, but your "dummy apps" sound to me like the sorts of things I could populate the 'guts' of, to make useful.
For instance, I work a lot with audio signal processing, have considerable experience in that area, and am "half-assedly" (low priority side project) writing tools that would benefit from a GUI.
My email is on my profile.
Here's my fork of Fidget: https://github.com/elcritch/fidget
I've uploaded a few youtube samples: https://www.youtube.com/playlist?list=PLfEcHAJujZRlloKeDj6iK...
Based on what you're asking about you might be interested in following an example where I tied in Nim's async system into Fidget: https://github.com/elcritch/fidget/blob/devel/tests/progress...
I thought about writing a cross platform GUI toolkit, that would start from being a cross platform accessibility library.
GUI frameworks are like cryptography: you never want to roll your own. You will spend endless time implementing all the widgets a typical UI framework has, tweaking it until it feels kinda right, and even then they won't feel totally right until you've done extensive user testing and acted on the resultant feedback. Hundreds or thousands of hours of work for something that won't be as good as Windows, macOS, or Qt.
And I haven't even gotten started on internationalization or accessibility! Ohohohoho, boy.
There's a reason why the best (only good, really) UI framework is proprietary to a large, multi-trillion-dollar company.
In conclusion, just use your OS's native framework or one of the half-decent ones for Linux if you're working on Linux.
My personal experience is that starting developing in opengl always ends up wasting hours getting the right libs installed to get potentially full 3d GPU acceleration - which might be beyond the point if you want to draw stuff.
Casey muratorri is spot on in saying that not having a single, simple, unniversal and basic API to "open a window and draw pixels" is what we lost the most during the 90s.
Anyway, try to bypass the not-interesting-to-you parts, and have fun !
xlib is quite a pleasure to use though, and it probably doesn't qualify as a "framework" that you don't want to use.
If you see yourself doing something 3+ times, automate it early!