I'm designing/writing a small UI toolkit (for self-betterment purposes, what else?) and I am unsure what kind of API would be better in the following senses:
- lowest WTF? level.
- most flexible.
- most succinct, yet descriptive
- best fit with Standard C++.
Some elements that are important:
- The
window
class represents well, a window, and can be shown, hidden, minimized, maximized, full screen maximized, and closed. - I have a
proxy_property
class which can be assigned arbitrary get and set functions that can e.g. reflect a current value that ought to be fetched or set through some external API call. - I also have a
property
class that can be connected to (i.e. observed), and when it is assigned a new/different value, will signal this new value to its observers.
I am unsure what the best way to handle the window state:
- Private member variable, only accessible through
hide()
,isVisible()
etc. member functions, Qt style. - read-only property (will need some extra implementation as I don't currently have this worked out) that is backed by
hide()
,show()
, etc. getters and updated accordingly. - A
proxy_property
that can be assigned a new state, resulting in a call tohide()
,show()
, etc. or a combination thereof when assigned a new value.
At first glance, I'd prefer number 3 for reason 3, but in light of the other conditions I'm unsure how well this design will hold up. Suffice to say I haven't seen my number 3 used anywhere, and I'm afraid to lean too much on my proxy_property
concept as it might incur more overhead than it's worth (on the other hand, this is UI code we're talking about, so overhead will be there nonetheless).
For clarity:
enum class window_state { windowed, hidden, minimized, maximized, fullscreen_maximized };
class window
{
public:
proxy_property<window_state> state;
//....
};
So one can do
some_window.state = window_state::minimized;
To actually do something more traditionally done by e.g.
some_window.minimize();
The end result would be functionally identical of course. It's just the API that is completely different.
I think you should be careful to distinguish between the properties you can set (e.g., say,
visibility
from the properties you can observe (e.g.isVisible
), because in many cases the observable properties depend on more than just the setting.A control, for example
isVisible
if it hasvisibility == true
AND it's containerisVisible
.There is no reason to make a control's
visibility
setting observable, and it fact it would probably lead to mistakes.For this reason, I would prefer setters and getters for
visibility
, and a listenable property forisVisible
.