From 26d0f50e47307bb161cdde5f1adfb5ff72022c81 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 12 Feb 2016 01:31:51 +0100 Subject: [PATCH] state mark handling within the base element: unit test PASS ...and I made the decision *not* to consider any kind of generic properties for now. YAGNI. UI coding is notorious spaghetti code. No point in fighting that, it is just the way it is, because somewhere you're bound to get concrete, hands-on. --- src/gui/model/tangible.cpp | 34 ++++++++++++++++ tests/gui/abstract-tangible-test.cpp | 45 +++++++++++++++++--- tests/gui/test/mock-elm.hpp | 3 ++ wiki/thinkPad.ichthyo.mm | 61 ++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 5 deletions(-) diff --git a/src/gui/model/tangible.cpp b/src/gui/model/tangible.cpp index 9e792cc30..9a8099841 100644 --- a/src/gui/model/tangible.cpp +++ b/src/gui/model/tangible.cpp @@ -33,6 +33,7 @@ #include "gui/model/tangible.hpp" #include "gui/model/widget.hpp" #include "gui/model/controller.hpp" +#include "lib/diff/gen-node.hpp" namespace gui { @@ -129,5 +130,38 @@ namespace model { } + /** + * default implementation and catch-all handler for receiving »state mark« messages. + * Such messages serve either to cause a presentation state effect specific to this + * element, or they are used to re-play a former state change to restore some + * specific UI state captured within a past working session. Events handled here: + * - *expand* with a `bool` argument calls the `doExpand(bool)` virtual function. + * It is up to the concrete element to give this a tangible meaning, e.g. a track + * might switch to detail view and a clip might reveal attached effects. + * - *reset* restores the element to the hard wired default, by invoking `doReset()` + * - *revealYourself* prompts the element to take the necessary actions to bring + * itself into view. There is no requirement for an element to even implement + * this call, but those which do typically know some kind of _"parent object"_ + * to forward this request, by invoking `doReveal(myID)` on this parent. + * For instance, a clip might ask the enclosing track, which in turn might + * call the enclosing timeline display for help, resulting in a scroll action + * to bring the clip into sight. + * @note this is a default implementation for a virtual function declared _abstract_ + * with the intention for derived classes to tail-call this default handler. + */ + void + Tangible::doMark (GenNode const& stateMark) + { + if (stateMark.idi.getSym() == "expand") + this->doExpand (stateMark.data.get()); + else + if (stateMark.idi.getSym() == "reset") + this->doReset(); + else + if (stateMark.idi.getSym() == "revealYourself") + this->doRevealYourself(); + } + + }} // namespace gui::model diff --git a/tests/gui/abstract-tangible-test.cpp b/tests/gui/abstract-tangible-test.cpp index 957957862..33c07c94b 100644 --- a/tests/gui/abstract-tangible-test.cpp +++ b/tests/gui/abstract-tangible-test.cpp @@ -441,7 +441,43 @@ namespace test { .beforeCall("note").arg(targetID, GenNode{"expand", false}) .before("handling state-mark")); - ////////////////////////////////////////////////////////////TODO: WIP + + + // Second part: replay of a state mark via UI-Bus.... + auto stateMark = GenNode{"expand", true}; + auto& uiBus = gui::test::Nexus::testUI(); + + CHECK (not mock.isExpanded()); + CHECK (mock.ensureNot("mark")); + + uiBus.mark (targetID, stateMark); + + CHECK (nexusLog.verifyCall("mark").arg(targetID, stateMark) + .before("delivered mark to "+string(targetID)).arg(stateMark)); + + CHECK (mock.verifyMark("expand", "true") + .beforeCall("expand").arg(true) + .beforeEvent("expanded")); + CHECK (mock.isExpanded()); + CHECK (mock.isTouched()); + + // the default handler defined in model::Tangible + // already supports some rather generic state changes, + // like e.g. a reset to the element's default state. + // Note that the actual implementation doReset() + // is a virtual function, here implemented in MockElm. + uiBus.mark (targetID, GenNode{"reset", true}); + // note: payload is irrelevant for "reset" mark + + // and we're back to pristine state... + CHECK (not mock.isTouched()); + CHECK (not mock.isExpanded()); + CHECK (mock.verifyMark("reset", "true") + .afterEvent("expanded") + .beforeCall("reset") + .beforeEvent("reset")); + + cout << "____Event-Log_________________\n" << util::join(mock.getLog(), "\n") << "\n───╼━━━━━━━━━╾────────────────"<identify(), "doMark", mark); cout << this->identify() << " <-- state-mark = "<< mark < + + + + + + + + + + + + + + + + + + + + + + +

+ ich wollte explizit kein generisch-introspektives UI, +

+

+ weil das die Tendenz hat, sich zu einem Framework auszuwachsen. +

+

+ Für die UI-Programmierung muß man Spaghetticode akzeptieren. +

+ + +
+
+ + + + + + +
+
@@ -280,6 +323,24 @@ + + + + + + + + + +

+ support ist optional +

+ + +
+
+ +