From 026049a13c2cfbb634dad9342cd1d62c55ba412b Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 31 Aug 2018 23:42:55 +0200 Subject: [PATCH] UiElement: likewise integrate the Revealer functor (#1162) --- src/gui/ctrl/notification-hub.hpp | 7 +----- src/gui/model/controller.hpp | 12 ---------- src/gui/model/tangible.cpp | 37 ++++++++++++++++++++++-------- src/gui/model/tangible.hpp | 21 +++++++++++++---- src/gui/model/widget.hpp | 12 ---------- tests/gui/test/mock-elm.hpp | 9 ++------ wiki/renderengine.html | 4 ++-- wiki/thinkPad.ichthyo.mm | 38 +++++++++++++++---------------- 8 files changed, 69 insertions(+), 71 deletions(-) diff --git a/src/gui/ctrl/notification-hub.hpp b/src/gui/ctrl/notification-hub.hpp index 3c75f17f9..638e6bc90 100644 --- a/src/gui/ctrl/notification-hub.hpp +++ b/src/gui/ctrl/notification-hub.hpp @@ -117,12 +117,6 @@ namespace ctrl { return true; } - virtual void - doRevealYourself() override - { - getWidget().revealYourself(); // implies also expand - } - virtual bool doMsg (string text) override { @@ -179,6 +173,7 @@ namespace ctrl { getWidget().expand (yes); } ); + installRevealer([&](){ getWidget().revealYourself(); }); // implementation implies also expand } ~NotificationHub() { }; diff --git a/src/gui/model/controller.hpp b/src/gui/model/controller.hpp index f44df49d0..802c47d44 100644 --- a/src/gui/model/controller.hpp +++ b/src/gui/model/controller.hpp @@ -70,18 +70,6 @@ namespace model { UNIMPLEMENTED ("Controller reset"); } - virtual void - doReveal (ID child) override - { - UNIMPLEMENTED ("Controller doReveal"); - } - - virtual void - doRevealYourself() override - { - UNIMPLEMENTED ("Controller doRevealYourself"); - } - virtual bool doMsg (string text) override { diff --git a/src/gui/model/tangible.cpp b/src/gui/model/tangible.cpp index 581912e7a..dc6e95d39 100644 --- a/src/gui/model/tangible.cpp +++ b/src/gui/model/tangible.cpp @@ -189,22 +189,41 @@ namespace model { /** - * @todo 12/2015 not clear yet what needs to be done - * @remarks the intention is to request the given child - * to be brought into sight. We need to set up some kind - * of children registration, but better not do this in - * a completely generic fashion, for danger of overengineering. - * Moreover, it is not clear yet, who will issue this request - * and at which element the initial request can/will be targeted. + * Cause the element to be brought into sight. + * This is a generic Slot to connect UI signals against; + * the same action can also be triggered by sending a **mark** + * message over the UI-Bus with the symbol "`revealYourself`". + * @note this is an optional feature and requires the actual widget or controller + * either to override the ::doRevealYourself() extension point, or to + * [install a suitable closure](\ref installRevealer()). Typically this + * is not in itself a persistent state change; however, it might incur + * expanding some widgets, which is recorded as persistent UI state. + * @remarks the intention is to make a specific element visible, e.g. to reveal + * the effect of some operation, or to mark a serious error condition. + * Implementing this is by no means trivial, since it involves the + * possibly recursive collaboration with enclosing container widgets, + * and maybe even to scroll to a given canvas position. */ void - Tangible::slotReveal(ID child) + Tangible::slotReveal() { - this->doReveal(child); this->doRevealYourself(); } + /** + * generic default implementation of the "reveal" functionality. + * Based on the #reveal_ functor, which needs to be [configured](\ref installRevealer()) + * explicitly to enable this functionality. + */ + void + Tangible::doRevealYourself() + { + if (reveal_.canReveal()) + reveal_(); + } + + /** * Perform a command or action, once the execution context has been established. diff --git a/src/gui/model/tangible.hpp b/src/gui/model/tangible.hpp index 137e9ea3e..170d14e62 100644 --- a/src/gui/model/tangible.hpp +++ b/src/gui/model/tangible.hpp @@ -202,8 +202,7 @@ namespace model { void slotExpand(); void slotCollapse(); - - void slotReveal(ID child); + void slotReveal(); void markFlash(); void markMsg (string message); @@ -211,14 +210,14 @@ namespace model { void mark(GenNode const&); void installExpander (Expander::ProbeFun, Expander::ChangeFun); + void installRevealer (Revealer::RevealeItFun); protected: virtual bool doReset() =0; virtual bool doClearMsg() =0; virtual bool doClearErr() =0; virtual bool doExpand (bool yes); - virtual void doReveal (ID child) =0; - virtual void doRevealYourself () =0; + virtual void doRevealYourself(); virtual bool doMsg (string) =0; virtual bool doErr (string) =0; @@ -269,6 +268,20 @@ namespace model { { expand_ = Expander{move (detectCurrExpansionState), move (howto_expand_collapse)}; } + + + /** + * Configure the (optional) functionality to bring the UI-Element into sight. + * @param how_to_uncover_the_element a lambda or function to actually cause the necessary actions. + * @note unless this setup function is invoked, the "`revealYourself`" functionality remains disabled. + * Typically this setup will be done by an owning parent container, binding to some internals + * and also recursively invoking the "`revealYourself`" action on the container. + */ + inline void + Tangible::installRevealer (Revealer::RevealeItFun how_to_uncover_the_element) + { + reveal_ = Revealer{move (how_to_uncover_the_element)}; + } diff --git a/src/gui/model/widget.hpp b/src/gui/model/widget.hpp index d5b303725..2abfa875e 100644 --- a/src/gui/model/widget.hpp +++ b/src/gui/model/widget.hpp @@ -67,18 +67,6 @@ namespace model { UNIMPLEMENTED ("Widget reset"); } - virtual void - doReveal (ID child) override - { - UNIMPLEMENTED ("Widget doReveal"); - } - - virtual void - doRevealYourself() override - { - UNIMPLEMENTED ("Widget doRevealYourself"); - } - virtual bool doMsg (string text) override { diff --git a/tests/gui/test/mock-elm.hpp b/tests/gui/test/mock-elm.hpp index b0cec0865..132fe7ddc 100644 --- a/tests/gui/test/mock-elm.hpp +++ b/tests/gui/test/mock-elm.hpp @@ -145,16 +145,11 @@ namespace test{ return Tangible::doExpand (yes); } - virtual void - doReveal (ID child) override - { - UNIMPLEMENTED ("mock doReveal"); - } - virtual void doRevealYourself() override { - UNIMPLEMENTED ("mock doRevealYourself"); + log_.call(this->identify(), "revealYourself"); + Tangible::doRevealYourself(); // NOTE: without specific configuration this is NOP } virtual bool diff --git a/wiki/renderengine.html b/wiki/renderengine.html index af92192b7..9a14cf2a4 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -3241,7 +3241,7 @@ More specifically, the integration is based on ''messaging''. To start with, the ---- In a preliminary attempt to establish an integration between the GUI and the lower layers, in 1/2009 we created an PlayerDummy, which "pulls" dummy frames from the (not yet existing) engine and displays them within an XV viewer widget. This highlighted the problems we're about to encounter and made us think about the more radically decoupled approach we followed thereafter... -
+
Building a layered architecture is a challenge, since the lower layer //really// needs to be self-contained, while prepared for usage by the higher layer.
 A major fraction of all desktop applications is written in a way where operational logic is built around the invocation from UI events -- what should be a shell turns into a backbone. One possible way to escape from this common anti pattern is to introduce a mediating entity, to translate between two partially incompatible demands and concerns: Sure, the "tangible stuff" is what matters, but you can not build any significant piece of technology if all you want is to "serve" the user.
 
@@ -3275,7 +3275,7 @@ Several UI elements offer the ability to be collapsed into a minimal representat
 
 !!!revealing an element
 The UI-Element protocol also includes the ability to //reveal an element// -- which means actively to bring this element into sight, in case it is hidden, collapsed or obscured by scrolling away.
-{{red{As of 8/2018 this is just an idea}}}, and many details still need to be considered. Yet at least one point is clear: implementing such a feature requires the help of the container widget actually holding the element to be revealed. It might even happen that also the collaboration of the container holding aforementioned immediate parent container is necessary -- indicating a recursive implementation scheme.
+{{red{As of 8/2018 this is just an idea}}}, and many details still need to be considered. Yet at least one point is clear: implementing such a feature requires the help of the container widget actually holding the element to be revealed. It might even happen that also the collaboration of the container holding aforementioned immediate parent container is necessary -- indicating a recursive implementation scheme. The default implementation is based on a similar scheme as the expand/collapse functionality: here we embed a {{{Revealer}}} functor, which then needs to be outfitted with a lambda binding into the internals of the parent container to effect the necessary presentation changes.
 
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 8ae6c0337..6ffe5f950 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -2009,22 +2009,19 @@ - + - - - - - + + + + + - - + + - - - - - + + @@ -2033,18 +2030,21 @@ - - - - + + + + - - + + + + +