
Nana: A modern C++ GUI library - geezerjay
http://nanapro.org/
======
c-smile
This: "Hello, <bold blue size=16>Nana C++ Library</>" looks a bit strange.

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.

~~~
oaiey
They also lost me at that moment. I can understand high level representation
like qml and xaml... but mixing them like that into plain c++ and also with
this XML/sgml/HTML thingy ... Smells wrong.

~~~
qPCR4vir
What is bad with mixing them like that into plain c++? Why may be better to
have external tools?

------
jcelerier
The "modernness" in Nana comes at a heavy cost : callbacks are based on
std::function, which means that adding a callback - e.g. as in their front
page :

    
    
        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.

~~~
antoinevg
Oh ffs, have you actually calculated this "cost" on a CPU made after 1985?

~~~
jcelerier
There's a lot of costs which all sum up:

\- binary size increase (e.g look at that :
[https://gcc.godbolt.org/z/xre7cp](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...](https://github.com/jcelerier/smallfunction/blob/master/smallfun/include/smallfun.hpp#L29)

------
dreamcompiler
What problem does this solve that Qt doesn't solve?

(Yes I can DDG the answer, but the Nana home page should make that
unnecessary.)

~~~
jacobush
More liberal license I noticed. (Boost vs QTs LGPL + commercial)

~~~
pjmlp
Aka not willing to pay upstream development costs.

------
nzjrs
A modern GUI library without screenshots on the homepage...

~~~
hellofunk
There is one screenshot on the front page, and I must admit, it does not
_look_ modern.

~~~
eps
More importantly, it doesn't look _native_ ... to anything really, which is
the main (and hard) problem for any portable GUI library.

Modernity can be added on top using a thin layer, if and when needed.

~~~
lake99
It looks like a native Breeze themed KDE application. If I did not know I was
on the Nana website, I would have assumed it's all Breeze.

------
ncmncm
> lab.format(true)

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.

~~~
int_19h
This looks like a common C++ pattern of having a pair of overloaded methods as
property accessors - foo() to get the value of foo for this object, and foo(x)
to set it.

~~~
ncmncm
Yes, that's the bad feeling all right. Classic anti-pattern.

~~~
otabdeveloper2
Disagreement about how to name methods is not an 'anti-pattern'. It's a
literal non-issue that affects nothing at all whatsoever.

Junior programmers pick on whitespace formatting and variable names because
that's the only kind of criticism their skill level allows.

~~~
ncmncm
This is not about naming or formatting. This is about the prevalence of what
are commonly called "setters and getters", that are a fairly reliable
indicator of poorly thought-out design. You can learn something here, if you
pay attention.

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.

~~~
rootlocus
> You can learn something here, if you pay attention.

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.

------
aphextron
Every nontrivial GUI framework eventually converges on a poor reimplentation
of HTML/CSS. If you need a complex modern interface, just use Electron or the
like.

~~~
ridiculous_fish
No, HTML and CSS are document markup languages. They are actually quite bad at
UIs.

For example, implement a table with more than a few hundred rows. UI toolkits
don't even blink while HTML just falls over.

~~~
aphextron
>No, HTML and CSS are document markup languages. They are actually quite bad
at UIs.

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.

~~~
pjmlp
Nah, HTML and CSS have lots to learn from iOS and Android layouts, QML and
XAML.

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.

------
floatboth
\- no Wayland support

\- no GPU accelerated rendering

\- no accessibility

That's not very modern, sorry, that's very 90s. Regardless of how the
programming interface looks.

~~~
viraptor
Not saying these aren't important, but you can implement these features once
you've got a nice API working. You can't easily retrofit a nice API into an
existing project with lots of features. So maybe they chose the right way.

~~~
smitty1e
[https://en.wikipedia.org/wiki/John_Gall_(author)#Gall's_law](https://en.wikipedia.org/wiki/John_Gall_\(author\)#Gall's_law)

------
jscholes
Correct me if I'm wrong, but these widgets are custom-drawn, making the
"modern" world completely inaccessible to and unusable by the majority of
disabled users.

~~~
snarfy
Don't blame the GUI, blame the screen reader. It's the screen readers that are
stuck in the 70's. We have software that can do facial recognition and run on
an raspberry pi but for some reason screen readers still need some ascii text
buffer to send to the equivalent of a speak&spell.

~~~
jscholes
The screen reader I'm using includes modern accurate OCR. I'm very interested
in this, though. How do you suggest a screen reader should recognise the often
subtle differences between control types and states across every application
and framework when custom controls are so common?

~~~
taeric
To add to your point, why require such sophistication if it can be avoided? I
mean, we could all send bitmaps back and forth to communicate. We could
literally just take pictures of hand written notes. Encoded email seems much
saner.

------
vfclists
Does it support interop with plain C, eg C99?

No C++ malarkey for me!!

