Lumiera
0.pre.03
»edit your freedom«
|
Go to the source code of this file.
Abstraction: a tangible element of the User Interface.
This is a generic foundation for any elements of more than local relevance within the Lumiera UI.
Any such element is connected to the UI-Bus.
Simple user interfaces can be built by wiring up the actions right within the code processing the trigger of actions. This leads to core functionality littered and tangled with presentation code. The next step towards a more sane architecture would be to code a forwarding call into every UI action, invoking some core facade in turn. This approach works, but is repetitive and thus lures the lazy programmer into taking shortcuts. Since we can foresee the Lumiera UI to become quite challenging in itself, we prefer to introduce a mediating backbone, impersonating the role of the Model and the Controler in the MVC-Pattern in common UI architecture.
The MVC-Pattern as such is fine, and probably the best we know for construction of user interfaces. But it doesn't scale well towards the integration into a larger and more structured system. There is a tension between the Controller in the UI and other parts of an application, which as well need to be in control. And, even more important, there is a tension between the demands of UI elements for support by a model, and the demands to be placed on a core domain model of a large scale application. This tension is resolved by enacting these roles while transforming the requests and demands into Messages.
This way, we separate between immediate local control of UI state and the more global, generic concerns of interaction control and command binding. The immediately tangible "mechanics" of the UI shall be implemented in a conventional way, right within the concrete widget (or controller) code. But, since any widget concerned with more than local behaviour will inherit from Tangible, the embedded UI-Bus terminal Tangible::uiBus_
can be used for interaction with core services.
The generic interface element based on Tangible covers a set of behaviour common to all elements of the interface. This behaviour is targeted towards the integration with the core application. Beyond that, there are still several concerns regarding presentation, like a common styling. These are addressed the conventional way, through a common StyleManager. The following discussion focuses on the aspects of integration with the core.
For one reason or another, any element in the UI can appear and go away. This lifecycle behaviour corresponds to attachment and deregistration at the UI-Bus
In regular, operative state, an interface element may initiate actions, which translate into commands at the session interface. To complicate matters, there might be higher-level, cooperative gestures implemented within the interface, leading to actions being formed similar to sentences of spoken language, with the help of a focus concept – anyway, this means, in the end, there is a subject and a predicate. These need to be bound in order to form an action. And some interface element takes on or relates to the role of the underlying, the subject, the tangible element.
And then there are manipulations that alter presentation state: Scrolling, canvas dragging, expanding and collapsing, moving by focus or manipulation of a similar presentation control. These manipulations in itself do not constitute an action. But there typically is some widget or controller, which is responsible for the touched presentation state. If this entity judges the state change to be relevant and persistent, it may send a state mark into the UI-Bus – expecting this marked state to be remembered. In turn this means the bus terminal might feed a state mark back into the tangible element, expecting this state to be restored.
A special case of state marking is the presentation of transient feedback. Such feedback is pushed from "somewhere" towards given elements, which react through an implementation dependent visual state change (flushing, colour change, marker icon). If such state marking is to be persistent, the interface element has in turn to send a specific state mark. An example would be a permanent error flag with an explanatory text showed in mouse over.
And finally, there are the essential updates – any changes in the model for real. These are sent as notifications just to some relevant top level element, expecting this element to request a diff and to mutate contents into shape recursively.
Beside these basic interactions, the generic element also exposes some common signal slots
sigc::trackable
for automated disconnection see sigc-track for an explanation.Definition in file tangible.hpp.
#include "lib/error.hpp"
#include "lib/nocopy.hpp"
#include "stage/ctrl/bus-term.hpp"
#include "stage/model/expander-revealer.hpp"
#include "lib/diff/diff-mutable.hpp"
#include "lib/idi/entry-id.hpp"
#include "lib/symbol.hpp"
#include <sigc++/trackable.h>
#include <utility>
#include <string>
Classes | |
class | Tangible |
Interface common to all UI elements of relevance for the Lumiera application. More... | |
Functions | |
template<typename... ARGS> | |
lib::diff::GenNode | commandMessage (Symbol cmdID, ARGS &&... args) |
convenience shortcut to build a message suitable for command invocation More... | |
Namespaces | |
stage | |
Lumiera GTK UI implementation root. | |
stage::model | |
The Lumiera GTK-GUI uses a thin proxy layer data model on top of the actual "high-level-model", which lives in the Steam-Layer below. | |