Nana: A modern C++ GUI library
nanapro.org
nanapro.org
Looks like XML but it is definitely not (the </> construct for example).
If the purpose is to provide inline styling then I would use something richtext alike:
"Hello, [B S16 C#00F]Nana C++ Library[bsc]"
But split on HTML (semantic, structure) and CSS (styling) is anyway better for many reasons.
When you need to show the same UI on different devices (desktop, mobile, OSes) and media (screen, high-dpi-screen, printer) you will come up to the need of separate style definition entity almost immediately.
Like this: "Hello, <bold blue size=16>Nana C++ Library</>" Should be just this "Hello, <em>Nana C++ Library</em>" and styles for the emphasis that can be different for each platform.
Even for the same OS and user session you will need different style systems if you want to support dark and light theming for example.
Yet having UI nailed down to pixels grids (<bold size=16>) is a path nowhere.
The benefits to developers are more "trade-offs", but I think it generally is a better raw framework to work in without significant IDE-assistance to do development.
Again, I like the argument. I just feel there is more taking about it, than benefits from it. Empirically, it just falls flat.
Benevolent systems cater to the least powerful user, not the median user, and I think it's good to support benevolent systems wherever possible, because businesses are naturally biased against benevolence.
Not clear what exactly.
> with just minimal styling and/or multiple versions.
If an application has simple UI that can use predefined and quite limited set of system UI elements then you probably don't need to style anything. But this is not the case of the library we are discussing.
What I meant is that most of us don't have the same content that needs to be styled differently across different devices. Majority of the time, things are easier. As you mention, use the predefined UI elements and call it a day. It is sadly hilarious how much better that would be for most applications.
For things that do have content that wants custom styling, think games and such, you are almost certainly either inventing your own abstraction language and porting that to different targets, or just creating a new implementation for each target. Yes, some folks have tried to make uber languages where you "write once, run everywhere." Those are almost always subpar compared to "write once for everywhere you care about running."
I'll say that I do agree with the argument on its merits. However, I disagree with the argument on evidence. Statistically, the style/content divide has really just increased the complexity of the code I deal with.
Not necessarily. As always with software design, there’re tradeoffs involved.
Separate styles work when the stuff you’re styling is content to consume, not rich GUI to edit/produce. For rich GUI that works well on every platform you need different structure, not just different styles.
Separate styles work when the devices are not too different. If they are very different, like PC and smartwatch, you probably need different structure even for readonly content.
There’re frameworks/design patterns, like MVVM for XAML, MVC for iOS and old-school web, where you can replace complete views while reusing the rest of the app.
Why do you need such "modern C++ GUI library" then?
Check my Sciter Notes. Screenshots of the application for each platform are on its frontpage: https://notes.sciter.com/
This application uses the same UI definitions on any platform (https://github.com/c-smile/sciter-sdk/tree/master/notes/res) and the same C++ code.
Very nice library! But you only support PCs. You have same structure, and same UX (mouse+keyboard, relatively large screen) on all of them, you only need to adjust for DPI scaling, and for window resize.
About hardcoded pixel sizes, sometimes they’re OK. Apple did that in iOS, worked well for them. When they released iPhone 4, they just doubled the DPI. And when they released iPad, they made developers replace complete views and it made sense because it was much different UX.
I’m not saying that library is good. Apple has separate UI markup language, and they have decent UI designer in XCode for that. The feature is IMO required for a modern GUI framework and it’s missing in Nana.
Also, GPU-based rendering is nice to have nowadays, see MS XAML or Google Flutter.
I once needed to create rich GUI for embedded Linux app on top of essentially raw hardware, drm, kms, gles. I’ve compiled C shared library exposing some wrappers around NanoVG API https://github.com/memononen/nanovg then implemented touchscreen input, controls, styles and animations in C# using .NET core. Worked well for my requirements.
btn.events().click([&fm]{
fm.close();
});
will do a dynamic allocation, and create an indirection, since std::function does type erasure (so you get a vtable, etc...).
Qt may look less modern, but the cost of doing a `connect` there is far smaller especially if you connect to a member function.- binary size increase (e.g look at that : https://gcc.godbolt.org/z/xre7cp)
- more symbols (I guess you never hit the per-object file symbol limit on windows, even with /BIGOBJ - when you do the only thing left is despair).
- most callbacks will have to copy a kind of `this` pointer so the size of your objects increase and they stop fitting into cache lines
- when you have "normal" inheritance, the vtable of your parent object is generally already in your cache, while here there will be one vtable per-object (and no, the vtables aren't optimized to be part of the object itself so you still get that indirection even with SBO). so goodbye memory coherency. I've been working on my own callback implementation with an inlined vtable which allowed me to grasp sometimes more than 30% perf improvement vs std::function, in callback-heavy code : https://github.com/jcelerier/smallfunction/blob/master/small...
Unless the profiler marks that code as reason to worry about, I wouldn't spend one second thinking about it.
(The callback approach is OOP I would say. And as always, OOP prevents us from seeing the better way to structure processing).
(Yes I can DDG the answer, but the Nana home page should make that unnecessary.)
Modernity can be added on top using a thin layer, if and when needed.
gives me a bad feeling.
However, in 35 years of programming I have not coded any kind of GUI, so my judgment might be off.
Junior programmers pick on whitespace formatting and variable names because that's the only kind of criticism their skill level allows.
In a sound design, objects more usually get their attributes at construction time, and keep them until they are destroyed. When something needs to change, from outside the object, it is usually better to make another object.
Of course an object can still have mutable state, altered by member functions that do actual, useful work, but they have no use for setters and getters -- they have direct access to the member data that needs to change.
The key here is that the public member functions should be doing useful work for you. Just mutating primitive state is noise. If the object doesn't abstract anything, it isn't earning it keep.
Another indicator of bad design is public virtual functions.
I'm all for learning and debating, but this comes off awfully patronizing.
> In a sound design, objects more usually get their attributes at construction time, and keep them until they are destroyed.
Immutable objects are nice and I always try to use them when I can, but arguing that everything should be immutable or you have a design problem... that's exaggerated.
> When something needs to change, from outside the object, it is usually better to make another object.
As with everything, there's a trade-off with any solution. Allocating and copying data isn't cheap. And the fact that you just pick one way of doing things and discard anything else as "bad design" doesn't inspire confidence.
> The key here is that the public member functions should be doing useful work for you.
No, the "key" is that you are abstracting access to data. Your setter may do validation or transformation on the data. You may only offer const access to data. You may even do a defensive copy of the data. You may set breakpoints or log access to the data.
> If the object doesn't abstract anything, it isn't earning it keep.
Not all objects need to represent functionality. Some represent data. And mutating data is fundamentally what every program does. Just because you have an aversion to mutating data outside your object and you are willing to pay the price for immutable structures, doesn't mean everyone else is following a "classic anti-pattern".
> Another indicator of bad design is public virtual functions.
I really don't see the wisdom behind this one.
Consider the humble popup button: a native one can support mouse input, or arrow keys, or keyboard shortcuts, or type selection, or accessible interfaces. Take it a step further and support scripting.
But if your popup button is a div with an onClick, it won't support any of these. Even if you go the extra mile and reimplement all of them, the user won't even think to try it, because it's a "styled" snowflake. So the web sinks.
HTML is way easier because it does a hell of a lot less.
HTML/CSS win for a reason. ;P
HTML/CSS/JS win because at this point there's both a mountain of features that you'd need to match in a native framework, it's cross-platform with rendering engine(s) that are mostly platform agnostic, and it's _actually documented_ unlike things like AppKit.
Someone learning HTML/CSS/JS can google their issue and find a solution or guide or what-have-you with relative ease. It's nowhere the near the same for any other framework.
For example, implement a table with more than a few hundred rows. UI toolkits don't even blink while HTML just falls over.
This was true 10 years ago. Now frameworks like React are at or beyond the sophistication of anything native. Practically every other UI technology implements their interfaces in an XML-esque syntax that is far less expressive and flexible than HTML, which end up locking you in to a small constrained ecosystem. CSS has evolved as well, and with GPU acceleration out of the box and things like grid and flexbox all of the older issues are gone.
Where is Blend for HTML/CSS?
React might be sofisticated, but having the performance of native GUIs, or the eco-system of companies selling UI components, is surely something that it will never have.
- no GPU accelerated rendering
- no accessibility
That's not very modern, sorry, that's very 90s. Regardless of how the programming interface looks.
No C++ malarkey for me!!