Instead of everyone overriding save_to() and set_property() and doing
a pretty asymmetric job of implementing the various properties, let's
add a bit of structure here.
Object properties are now represented by a Core::Property. Properties
are registered with a getter and setter (optional) in constructors.
I've added some convenience macros for creating and registering
properties, but this does still feel a bit bulky. We'll have to
iterate on this and see where it goes.
GUI::TabWidget has long has a TabPosition::Bottom option, but we still
rendered the tab buttons the same as TabPosition::Top.
This patch implements a custom look for bottom-side tabs. I've done my
best to match the look of the top-side ones, but there might be some
improvements we can make here. :^)
In TabWidgets with the "uniform tabs" mode on, we will now scale tabs
between a minimum and maximum size, distributing the available space.
Partially addresses #1971.
This patch adds the following convenience helper:
auto tab_widget = GUI::TabWidget::construct();
auto my_widget = tab_widget->add_tab<GUI::Widget>("My tab", ...);
The above is equivalent to:
auto tab_widget = GUI::TabWidget::construct();
auto my_widget = GUI::Widget::construct(...);
tab_widget->add_widget("My tab", my_widget);