From 9894542bf9ecb89afcd8d434e17b6d59a0149156 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 8 Oct 2018 05:00:06 +0200 Subject: [PATCH] Introduce predefined constants for magic IDs in UI communication ...these magical strings are already spreading dangerously throughout the code base PS: also fixup for c6b8811af03 (broken whitespace in test definition) --- src/common/guifacade.cpp | 15 +--- src/common/ui-protocol.cpp | 62 ++++++++++++++++ src/gui/ctrl/notification-hub.hpp | 2 +- src/gui/ctrl/state-recorder.hpp | 11 +-- src/gui/dialog/test-control.hpp | 13 ++-- src/gui/model/expander-revealer.hpp | 2 +- src/gui/model/tangible.cpp | 51 ++++++------- src/gui/model/tangible.hpp | 6 +- src/gui/notification-service.cpp | 7 +- src/gui/timeline/clip-presenter.cpp | 7 +- src/gui/timeline/marker-widget.cpp | 5 +- src/gui/timeline/timeline-controller.cpp | 5 +- src/gui/timeline/track-presenter.cpp | 7 +- src/include/ui-protocol.hpp | 93 ++++++++++++++++++++++++ src/lib/diff/diff-language.hpp | 6 +- src/proc/cmd/meta-cmd.cpp | 6 +- tests/15library.tests | 4 +- tests/gui/abstract-tangible-test.cpp | 18 ++--- tests/gui/bus-term-test.cpp | 23 +++--- tests/gui/test/mock-elm.hpp | 13 ++-- 20 files changed, 258 insertions(+), 98 deletions(-) create mode 100644 src/common/ui-protocol.cpp create mode 100644 src/include/ui-protocol.hpp diff --git a/src/common/guifacade.cpp b/src/common/guifacade.cpp index 25779272a..212c431a1 100644 --- a/src/common/guifacade.cpp +++ b/src/common/guifacade.cpp @@ -150,7 +150,7 @@ namespace gui { ERROR_LOG_AND_IGNORE (guifacade, "trigger shutdown of the GUI"); } - bool + bool checkRunningState () noexcept override { return bool(facade); @@ -210,15 +210,6 @@ namespace gui { { return bool(facade); } - - - + + } // namespace gui - -/* -// Local Variables: -// mode: C++ -// c-file-style: "gnu" -// indent-tabs-mode: nil -// End: -*/ diff --git a/src/common/ui-protocol.cpp b/src/common/ui-protocol.cpp new file mode 100644 index 000000000..4dfc4b13a --- /dev/null +++ b/src/common/ui-protocol.cpp @@ -0,0 +1,62 @@ +/* + UiProtocol - magic keys used for communication with the Lumiera UI + + Copyright (C) Lumiera.org + 2018, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +/** @file ui-protocol.cpp + ** Storage for key constants and basic definitions used for interfacing with the GUI. + */ + +//#include "gui/gtk-base.hpp" /////////////////////TODO necessary? +#include "include/ui-protocol.hpp" + + +namespace gui { + + const Symbol META_kind{"kind"}; + + const Symbol TYPE_Fork{"Fork"}; + const Symbol TYPE_Clip{"Clip"}; + const Symbol TYPE_Marker{"Marker"}; + const Symbol TYPE_Channel{"Channel"}; + const Symbol TYPE_Effect{"Effect"}; + + const Symbol ATTR_name{"name"}; + const Symbol ATTR_fork{"fork"}; + + + /* ======== UI-Element protocol ======== */ + + const Symbol MARK_reset{"reset"}; + const Symbol MARK_clearErr{"clearErr"}; + const Symbol MARK_clearMsg{"clearMsg"}; + const Symbol MARK_expand{"expand"}; + const Symbol MARK_reveal{"reveal"}; + const Symbol MARK_Flash{"Flash"}; + const Symbol MARK_Error{"Error"}; + const Symbol MARK_Warning{"Warning"}; + const Symbol MARK_Message{"Message"}; + + /** */ + + + +}// namespace gui diff --git a/src/gui/ctrl/notification-hub.hpp b/src/gui/ctrl/notification-hub.hpp index 225bdc6da..84b897ff1 100644 --- a/src/gui/ctrl/notification-hub.hpp +++ b/src/gui/ctrl/notification-hub.hpp @@ -147,7 +147,7 @@ namespace ctrl { virtual void doMark (GenNode const& stateMark) override { - if (stateMark.idi.getSym() == "Warning") + if (stateMark.idi.getSym() == MARK_Warning) getWidget().addWarn (stateMark.data.get()); else // forward to default handler diff --git a/src/gui/ctrl/state-recorder.hpp b/src/gui/ctrl/state-recorder.hpp index edf89dd44..b3b4ee8fc 100644 --- a/src/gui/ctrl/state-recorder.hpp +++ b/src/gui/ctrl/state-recorder.hpp @@ -59,6 +59,7 @@ #include "gui/ctrl/bus-term.hpp" #include "gui/ctrl/state-manager.hpp" #include "gui/ctrl/state-map-grouping-storage.hpp" +#include "include/ui-protocol.hpp" #include @@ -174,14 +175,14 @@ namespace ctrl { void recordState (ID uiElm, StateMark stateMark) { - if ("reset" == stateMark.idi.getSym()) + if (MARK_reset == stateMark.idi.getSym()) storage_.clearState (uiElm); else - if ("clearErr" == stateMark.idi.getSym()) - storage_.clearProperty (uiElm, "Error"); + if (MARK_clearErr == stateMark.idi.getSym()) + storage_.clearProperty (uiElm, string{MARK_Error}); else - if ("clearMsg" == stateMark.idi.getSym()) - storage_.clearProperty (uiElm, "Message"); + if (MARK_clearMsg == stateMark.idi.getSym()) + storage_.clearProperty (uiElm, string{MARK_Message}); else storage_.record (uiElm, stateMark); } diff --git a/src/gui/dialog/test-control.hpp b/src/gui/dialog/test-control.hpp index 8d8b04e77..039c00ad3 100644 --- a/src/gui/dialog/test-control.hpp +++ b/src/gui/dialog/test-control.hpp @@ -44,6 +44,7 @@ #include "gui/ctrl/bus-term.hpp" #include "gui/model/tangible.hpp" #include "proc/cmd.hpp" +#include "include/ui-protocol.hpp" #include "include/gui-notification-facade.h" #include "lib/scoped-ptrvect.hpp" #include "lib/diff/gen-node.hpp" @@ -225,12 +226,12 @@ namespace dialog { trig_4_.set_tooltip_markup (_("trigger Proc-command, which in turn\n" "sends an state mark message, using\n" "the message action-ID from the combobox")); - actionID_.append ("Flash"); - actionID_.append ("revealYourself"); - actionID_.append ("clearErr"); - actionID_.append ("clearMsg"); - actionID_.append ("expand"); - actionID_.append ("reset"); + actionID_.append (cuString{MARK_Flash}); + actionID_.append (cuString{MARK_reveal}); + actionID_.append (cuString{MARK_clearErr}); + actionID_.append (cuString{MARK_clearMsg}); + actionID_.append (cuString{MARK_expand}); + actionID_.append (cuString{MARK_reset}); actionID_.set_active(1); actionID_.set_tooltip_markup("select the specific action-ID\n" "when sending a mark message.\n" diff --git a/src/gui/model/expander-revealer.hpp b/src/gui/model/expander-revealer.hpp index 41c5db905..6bbe689dc 100644 --- a/src/gui/model/expander-revealer.hpp +++ b/src/gui/model/expander-revealer.hpp @@ -36,7 +36,7 @@ ** ** The base class of all [tangible UI elements](\ref Tangible) provides a default implementation ** for these generic interaction mechanisms: It offers slots to connect UI signals against, and - ** it understands the \em `mark` messages `"expand"` and `"revealYourself"`. These are implemented + ** it understands the \em `mark` messages `"expand"` and `"reveal"`. These are implemented ** by delegating to the \ref Expander and \ref Revealer functors respectively. Moreover, this ** default implementation automatically detects a resulting state change and emits an appropriate ** \em `note` message on the UI-Bus, so to make those state changes persistent. However, in order diff --git a/src/gui/model/tangible.cpp b/src/gui/model/tangible.cpp index e81daf3dd..0070bc029 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 "include/ui-protocol.hpp" #include "lib/diff/gen-node.hpp" @@ -60,7 +61,7 @@ namespace model { Tangible::reset() { if (this->doReset()) - uiBus_.note (GenNode{"reset", true}); + uiBus_.note (GenNode{string{MARK_reset}, true}); } @@ -82,7 +83,7 @@ namespace model { Tangible::clearErr() { if (this->doClearErr()) - uiBus_.note (GenNode{"clearErr", true}); + uiBus_.note (GenNode{string{MARK_clearErr}, true}); } @@ -93,7 +94,7 @@ namespace model { Tangible::clearMsg() { if (this->doClearMsg()) - uiBus_.note (GenNode{"clearMsg", true}); + uiBus_.note (GenNode{string{MARK_clearMsg}, true}); } @@ -125,7 +126,7 @@ namespace model { Tangible::markMsg (string message) { if (this->doMsg (message)) - uiBus_.note (GenNode{"Message", message}); + uiBus_.note (GenNode{string{MARK_Message}, message}); } @@ -136,7 +137,7 @@ namespace model { Tangible::markErr (string error) { if (this->doErr (error)) - uiBus_.note (GenNode("Error", error)); + uiBus_.note (GenNode{string{MARK_Error}, error}); } @@ -156,7 +157,7 @@ namespace model { Tangible::slotExpand() { if (this->doExpand(true)) - uiBus_.note (GenNode("expand", true)); + uiBus_.note (GenNode{string{MARK_expand}, true}); } @@ -168,7 +169,7 @@ namespace model { Tangible::slotCollapse() { if (this->doExpand(false)) - uiBus_.note (GenNode("expand", false)); + uiBus_.note (GenNode{string{MARK_expand}, false}); } @@ -192,9 +193,9 @@ namespace model { * 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`". + * message over the UI-Bus with the symbol "`reveal`". * @note this is an optional feature and requires the actual widget or controller - * either to override the ::doRevealYourself() extension point, or to + * either to override the ::doReveal() 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. @@ -207,7 +208,7 @@ namespace model { void Tangible::slotReveal() { - this->doRevealYourself(); + this->doReveal(); } @@ -217,7 +218,7 @@ namespace model { * explicitly to enable this functionality. */ void - Tangible::doRevealYourself() + Tangible::doReveal() { if (reveal_.canReveal()) reveal_(); @@ -245,13 +246,13 @@ namespace model { void Tangible::mark (GenNode const& stateMark) { - if (stateMark.idi.getSym() == "Flash") + if (stateMark.idi.getSym() == MARK_Flash) this->doFlash(); else - if (stateMark.idi.getSym() == "Error") + if (stateMark.idi.getSym() == MARK_Error) this->markErr (stateMark.data.get()); else - if (stateMark.idi.getSym() == "Message") + if (stateMark.idi.getSym() == MARK_Message) this->markMsg (stateMark.data.get()); else this->doMark(stateMark); @@ -267,10 +268,10 @@ namespace model { * 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. + * - *reveal* 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. @@ -280,23 +281,23 @@ namespace model { void Tangible::doMark (GenNode const& stateMark) { - if (stateMark.idi.getSym() == "expand") + if (stateMark.idi.getSym() == MARK_expand) { if (this->doExpand (stateMark.data.get())) - uiBus_.note (GenNode("expand", true)); // possibly reentrant (yet harmless) + uiBus_.note (GenNode(string{MARK_expand}, true)); // possibly reentrant (yet harmless) } else - if (stateMark.idi.getSym() == "reset") + if (stateMark.idi.getSym() == MARK_reset) this->reset(); else - if (stateMark.idi.getSym() == "clearMsg") + if (stateMark.idi.getSym() == MARK_clearMsg) this->clearMsg(); else - if (stateMark.idi.getSym() == "clearErr") + if (stateMark.idi.getSym() == MARK_clearErr) this->clearErr(); else - if (stateMark.idi.getSym() == "revealYourself") - this->doRevealYourself(); + if (stateMark.idi.getSym() == MARK_reveal) + this->doReveal(); } diff --git a/src/gui/model/tangible.hpp b/src/gui/model/tangible.hpp index 55f8d73ae..c20601116 100644 --- a/src/gui/model/tangible.hpp +++ b/src/gui/model/tangible.hpp @@ -217,7 +217,7 @@ namespace model { virtual bool doClearMsg() =0; virtual bool doClearErr() =0; virtual bool doExpand (bool yes); - virtual void doRevealYourself(); + virtual void doReveal (); virtual bool doMsg (string) =0; virtual bool doErr (string) =0; @@ -287,9 +287,9 @@ namespace model { /** * 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. + * @note unless this setup function is invoked, the "`reveal`" 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. + * and also recursively invoking the "`reveal`" action on the container. */ inline void Tangible::installRevealer (Revealer::RevealeItFun how_to_uncover_the_element) diff --git a/src/gui/notification-service.cpp b/src/gui/notification-service.cpp index 529a60449..41cff9361 100644 --- a/src/gui/notification-service.cpp +++ b/src/gui/notification-service.cpp @@ -56,6 +56,7 @@ #include "gui/ctrl/ui-dispatcher.hpp" #include "gui/notification-service.hpp" #include "gui/interact/wizard.hpp" +#include "include/ui-protocol.hpp" #include "lib/diff/mutation-message.hpp" #include "lib/diff/gen-node.hpp" @@ -113,7 +114,7 @@ namespace gui { markNote (errorLogID, text); break; case NOTE_WARN: - mark (errorLogID, GenNode{"Warning", text}); + mark (errorLogID, GenNode{string{MARK_Warning}, text}); break; default: throw lumiera::error::Logic (_Fmt{"UI Notification with invalid severity %d encountered. " @@ -124,14 +125,14 @@ namespace gui { void NotificationService::markError (ID uiElement, string const& text) { - dispatchMsg (uiElement, GenNode{"Error", text}); + dispatchMsg (uiElement, GenNode{string{MARK_Error}, text}); } void NotificationService::markNote (ID uiElement, string const& text) { - dispatchMsg (uiElement, GenNode{"Message", text}); + dispatchMsg (uiElement, GenNode{string{MARK_Message}, text}); } diff --git a/src/gui/timeline/clip-presenter.cpp b/src/gui/timeline/clip-presenter.cpp index 098fd7a8b..411e10c5d 100644 --- a/src/gui/timeline/clip-presenter.cpp +++ b/src/gui/timeline/clip-presenter.cpp @@ -31,6 +31,7 @@ #include "gui/gtk-base.hpp" +#include "include/ui-protocol.hpp" #include "gui/timeline/clip-presenter.hpp" #include "gui/timeline/marker-widget.hpp" @@ -94,7 +95,7 @@ namespace timeline { .attach (collection(markers_) .isApplicableIf ([&](GenNode const& spec) -> bool { // »Selector« : require object-like sub scope with type-field "Marker" - return "Marker" == spec.data.recordType(); + return TYPE_Marker == spec.data.recordType(); }) .matchElement ([&](GenNode const& spec, PMarker const& elm) -> bool { @@ -113,7 +114,7 @@ namespace timeline { .attach (collection(effects_) .isApplicableIf ([&](GenNode const& spec) -> bool { // »Selector« : require object-like sub scope with type-field "Effect" - return "Effect" == spec.data.recordType(); + return TYPE_Effect == spec.data.recordType(); }) .matchElement ([&](GenNode const& spec, PEffect const& elm) -> bool { @@ -132,7 +133,7 @@ namespace timeline { .attach (collection(channels_) .isApplicableIf ([&](GenNode const& spec) -> bool { // »Selector« : require object-like sub scope with type-field "Channel" - return "Channel" == spec.data.recordType(); + return TYPE_Channel == spec.data.recordType(); }) .matchElement ([&](GenNode const& spec, PChannel const& elm) -> bool { diff --git a/src/gui/timeline/marker-widget.cpp b/src/gui/timeline/marker-widget.cpp index 0208ea27b..530a30c02 100644 --- a/src/gui/timeline/marker-widget.cpp +++ b/src/gui/timeline/marker-widget.cpp @@ -31,6 +31,7 @@ #include "gui/gtk-base.hpp" +#include "include/ui-protocol.hpp" #include "gui/timeline/marker-widget.hpp" //#include "gui/ui-bus.hpp" @@ -82,11 +83,11 @@ namespace timeline { { buffer.create ( TreeMutator::build() - .change("name", [&](string val) + .change(ATTR_name, [&](string val) { name_ = val; }) - .change("kind", [&](string val) + .change(META_kind, [&](string val) { if (val == "LOOP") kind_ = LOOP; else kind_ = MARK; diff --git a/src/gui/timeline/timeline-controller.cpp b/src/gui/timeline/timeline-controller.cpp index 985b556e5..fa85ba73f 100644 --- a/src/gui/timeline/timeline-controller.cpp +++ b/src/gui/timeline/timeline-controller.cpp @@ -39,6 +39,7 @@ #include "gui/gtk-base.hpp" +#include "include/ui-protocol.hpp" #include "gui/timeline/timeline-controller.hpp" #include "gui/timeline/track-presenter.hpp" #include "gui/timeline/marker-widget.hpp" @@ -155,12 +156,12 @@ namespace timeline { target->buildMutator (buff); // - delegate to child to build nested TreeMutator return true; })) - .mutateAttrib("fork", [&](TreeMutator::Handle buff) + .mutateAttrib(ATTR_fork, [&](TreeMutator::Handle buff) { // »Attribute Mutator« : how enter an object field as nested scope REQUIRE (fork_); fork_->buildMutator(buff); }) - .change("name", [&](string val) + .change(ATTR_name, [&](string val) { // »Attribute Setter« : how assign a new value to some object field name_ = val; })); diff --git a/src/gui/timeline/track-presenter.cpp b/src/gui/timeline/track-presenter.cpp index bce8ed079..ea541c650 100644 --- a/src/gui/timeline/track-presenter.cpp +++ b/src/gui/timeline/track-presenter.cpp @@ -31,6 +31,7 @@ #include "gui/gtk-base.hpp" +#include "include/ui-protocol.hpp" #include "gui/timeline/track-presenter.hpp" #include "gui/timeline/clip-presenter.hpp" #include "gui/timeline/marker-widget.hpp" @@ -104,7 +105,7 @@ namespace timeline { .attach (collection(markers_) .isApplicableIf ([&](GenNode const& spec) -> bool { // »Selector« : require object-like sub scope with type-field "Marker" - return "Marker" == spec.data.recordType(); + return TYPE_Marker == spec.data.recordType(); }) .matchElement ([&](GenNode const& spec, PMarker const& elm) -> bool { @@ -123,7 +124,7 @@ namespace timeline { .attach (collection(clips_) .isApplicableIf ([&](GenNode const& spec) -> bool { // »Selector« : require object-like sub scope with type-field "Clip" - return "Clip" == spec.data.recordType(); + return TYPE_Clip == spec.data.recordType(); }) .matchElement ([&](GenNode const& spec, PClip const& elm) -> bool { @@ -142,7 +143,7 @@ namespace timeline { .attach (collection(subFork_) .isApplicableIf ([&](GenNode const& spec) -> bool { // »Selector« : require object-like sub scope with type-field "Fork" - return "Fork" == spec.data.recordType(); + return TYPE_Fork == spec.data.recordType(); }) .matchElement ([&](GenNode const& spec, PFork const& elm) -> bool { diff --git a/src/include/ui-protocol.hpp b/src/include/ui-protocol.hpp new file mode 100644 index 000000000..999e95c27 --- /dev/null +++ b/src/include/ui-protocol.hpp @@ -0,0 +1,93 @@ +/* + UI-PROTOCOL.h - magic keys used for communication with the Lumiera UI + + Copyright (C) Lumiera.org + 2018, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/** @file ui-protocol.hpp + ** Hard wired key constants and basic definitions for communication with the GUI. + ** The Lumiera UI is connected to the application core via message oriented interfaces, + ** running an asynchronous communication protocol. + ** - the [UI-Bus](\ref ui-bus.hpp) allows for some specific kinds of messages to be + ** sent either "upstream" (towards the CoreService) or "downstream" to individual + ** [UI-Elements](\ref gui::model::Tangible) known by ID. + ** - these ["tangible interface elements"](\ref tangible.hpp) themselves define a + ** basic set of actions and "state mark" messages, known as the "element protocol" + ** - and changes to the structure of tangible elements exposed through the UI are + ** conducted by pushing up [»diff messages«](\ref mutation-message.hpp) into the + ** UI via UI-Bus. These messages need to comply to an underlying structural + ** model of elements to be edited within the session and exposed for GUI + ** manipulation. This is referred to as "Session Model Scheme" + ** + ** These protocols are basically _implementation defined_ conventions and not + ** rigorously formalised. To a large extent, they are guided by the types and + ** corresponding API interfaces. However, since the lumiera session allows for + ** quite flexible structures, these protocols are kept open for local extensions. + ** At various levels, magic ID-Values are used to initiate specific interactions. + ** This header supplies the hard wired key constants and IDs thereby employed. + ** + ** @see common/ui-protocol.cpp (translation unit backing those constants) + */ + + +#ifndef GUI_INTERFACE_UI_PROTOCOL_H +#define GUI_INTERFACE_UI_PROTOCOL_H + + +#include "lib/symbol.hpp" + + +namespace Glib { +//class ustring; /////////////////////////////TODO needed? +} +namespace gui { + +//using lib::Literal; + using lib::Symbol; +//using cuString = const Glib::ustring; + + + extern const Symbol META_kind; + + extern const Symbol TYPE_Fork; + extern const Symbol TYPE_Clip; + extern const Symbol TYPE_Marker; + extern const Symbol TYPE_Channel; + extern const Symbol TYPE_Effect; + + extern const Symbol ATTR_name; + extern const Symbol ATTR_fork; + + + /* ======== UI-Element protocol ======== */ + + extern const Symbol MARK_reset; + extern const Symbol MARK_clearErr; + extern const Symbol MARK_clearMsg; + extern const Symbol MARK_expand; + extern const Symbol MARK_reveal; + extern const Symbol MARK_Flash; + extern const Symbol MARK_Error; + extern const Symbol MARK_Warning; + extern const Symbol MARK_Message; + + +}// namespace gui +#endif /*GUI_INTERFACE_UI_PROTOCOL_H*/ diff --git a/src/lib/diff/diff-language.hpp b/src/lib/diff/diff-language.hpp index f4683c2a5..c7fe57ceb 100644 --- a/src/lib/diff/diff-language.hpp +++ b/src/lib/diff/diff-language.hpp @@ -33,7 +33,8 @@ ** Such an architecture allows for tight cooperation between strictly separated ** components, without the need of a fixed, predefined and shared data structure. ** - ** \par Basic Assumptions + ** # Basic Assumptions + ** ** While the \em linearisation folds knowledge about the underlying data structure ** down into the actual diff, we deliberately assume that the data to be diffed is ** \em structured data. Moreover, we'll assume implicitly that this data is \em typed, @@ -44,7 +45,8 @@ ** send the actual content data this way, or to serve as redundancy to verify ** proper application of the changes at the diff receiver downstream. ** - ** \par Solution Pattern + ** # Solution Pattern + ** ** The representation of this linearised diff language relies on a specialised form ** of the visitor pattern: We assume the vocabulary of the diff language to be ** relatively fixed, while the actual effect when consuming the stream of diff tokens diff --git a/src/proc/cmd/meta-cmd.cpp b/src/proc/cmd/meta-cmd.cpp index 5eeb7fcbd..030a5ebfa 100644 --- a/src/proc/cmd/meta-cmd.cpp +++ b/src/proc/cmd/meta-cmd.cpp @@ -38,6 +38,7 @@ #include "proc/cmd.hpp" #include "proc/control/command-def.hpp" //#include "proc/mobject/session.hpp" +#include "include/ui-protocol.hpp" //////////////////////////////////////////////////////////////TICKET #1140 : verify if this include is required #include "include/gui-notification-facade.h" #include "gui/interact/wizard.hpp" //////////////////////////////////////////////////////////////TICKET #1140 : include needed temporarily #include "lib/diff/gen-node.hpp" @@ -54,6 +55,7 @@ using gui::NOTE_INFO; using gui::NOTE_WARN; using gui::NOTE_ERROR; using gui::NotifyLevel; +using gui::MARK_expand; using gui::GuiNotification; using lib::diff::GenNode; //using util::cStr; @@ -214,8 +216,8 @@ COMMAND_DEFINITION (test_meta_markAction) { ID errorLogID = gui::interact::Wizard::getErrorLogID(); GuiNotification::facade().mark (errorLogID - ,actionID=="expand"? GenNode{actionID, isYes(message)} - : GenNode{actionID, message}); + ,actionID==MARK_expand? GenNode{actionID, isYes(message)} + : GenNode{actionID, message}); }) .captureUndo ([](string actionID, string message) -> string { diff --git a/tests/15library.tests b/tests/15library.tests index a9779dc4c..c2a94f0cb 100644 --- a/tests/15library.tests +++ b/tests/15library.tests @@ -705,8 +705,8 @@ TEST "util: sanitised identifier" UtilSanitizedIdentifier_test < 'Word' out-lit: 'a Sentence' --> 'a_Sentence' out-lit: 'trailing Withespace -out-lit: ' --> 'trailing_Withespace' -out-lit: 'with a lot +out-lit: ' --> 'trailing_Withespace' +out-lit: 'with a lot out-lit: of Whitespace' --> 'with_a_lot_of_Whitespace' out-lit: 'with"much (punctuation)[]!' --> 'withmuch_(punctuation)' out-lit: '§&Ω%€ leading garbage' --> 'leading_garbage' diff --git a/tests/gui/abstract-tangible-test.cpp b/tests/gui/abstract-tangible-test.cpp index 9382b4c9d..c9ffc776a 100644 --- a/tests/gui/abstract-tangible-test.cpp +++ b/tests/gui/abstract-tangible-test.cpp @@ -470,7 +470,7 @@ namespace test { } - /** @test configure a handler for the (optional) "revealYourself" functionality. + /** @test configure a handler for the (optional) "reveal yourself" functionality. * We install a lambda to supply the actual implementation action, which can then * either be triggered by a signal/slot invocation, or by sending a "state mark". */ @@ -494,7 +494,7 @@ namespace test { bool revealed = false; mock.installRevealer([&]() - { // NOTE: our mock "implementation" of the revealYourself functionality + { // NOTE: our mock "implementation" of the »reveal yourself« functionality mock.slotExpand(); // explicitly prompts the element to expand itself, revealed = true; // and then via closure sets a flag we can verify. }); @@ -504,7 +504,7 @@ namespace test { CHECK (true == revealed); CHECK (mock.isExpanded()); CHECK (mock.verifyEvent("create","target") - .beforeCall("revealYourself") + .beforeCall("reveal") .beforeCall("expand").arg(true) .beforeEvent("expanded")); @@ -515,28 +515,28 @@ namespace test { // second test: the same can be achieved via UI-Bus message... revealed = false; - auto stateMark = GenNode{"revealYourself", 47}; // (payload argument irrelevant) + auto stateMark = GenNode{"reveal", 47}; // (payload argument irrelevant) auto& uiBus = gui::test::Nexus::testUI(); - CHECK (nexusLog.ensureNot("revealYourself")); + CHECK (nexusLog.ensureNot("reveal")); uiBus.mark (targetID, stateMark); // send the state mark message to reveal the element CHECK (true == revealed); - CHECK (mock.verifyMark("revealYourself", 47) + CHECK (mock.verifyMark("reveal", 47) .afterEvent("expanded") - .beforeCall("revealYourself") + .beforeCall("reveal") .beforeCall("expand").arg(true)); CHECK (nexusLog.verifyCall("mark").arg(targetID, stateMark) .after("handling state-mark") - .before("revealYourself") + .before("reveal") .beforeEvent("delivered mark")); // Note the fine point: the target element /was/ already expanded // and thus there is no second "expanded" event, nor is there a // second state mark emitted into the UI-Bus... CHECK (mock.ensureNot("expanded") - .afterCall("revealYourself") + .afterCall("reveal") .afterEvent("expanded")); CHECK (nexusLog.ensureNot("note") .afterCall("mark").arg(targetID, stateMark) diff --git a/tests/gui/bus-term-test.cpp b/tests/gui/bus-term-test.cpp index 1b5b91e28..931f20711 100644 --- a/tests/gui/bus-term-test.cpp +++ b/tests/gui/bus-term-test.cpp @@ -30,6 +30,7 @@ #include "lib/sync.hpp" #include "lib/sync-classlock.hpp" #include "backend/thread-wrapper.hpp" +#include "include/ui-protocol.hpp" #include "gui/ctrl/bus-term.hpp" #include "gui/ctrl/state-manager.hpp" #include "proc/control/command.hpp" @@ -190,8 +191,8 @@ namespace test { CHECK (nexusLog.verifyCall("note").on("TestNexus").arg(elmID, "GenNode-ID(\"expand\")-DataCap|«bool»|true")); // send a state mark down to the mock element - gui::test::Nexus::testUI().mark (elmID, GenNode("Flash", 23)); - CHECK (nexusLog.verifyCall("mark").on("TestNexus").arg(elmID, "Flash") + gui::test::Nexus::testUI().mark (elmID, GenNode(string{MARK_Flash}, 23)); + CHECK (nexusLog.verifyCall("mark").on("TestNexus").arg(elmID, MARK_Flash) .beforeEvent("TestNexus", "mark to bID-zeitgeist")); CHECK (elmLog.verifyCall("doFlash").on("zeitgeist")); @@ -202,9 +203,9 @@ namespace test { CHECK (nexusLog.verifyCall("routeDetach").on("TestNexus").arg(elmID) .beforeEvent("TestNexus", "removed route to bID-zeitgeist")); - gui::test::Nexus::testUI().mark (elmID, GenNode("Flash", 88)); + gui::test::Nexus::testUI().mark (elmID, GenNode({MARK_Flash}, 88)); CHECK (nexusLog.verify("removed route to bID-zeitgeist") - .beforeCall("mark").on("TestNexus").arg(elmID, "Flash") + .beforeCall("mark").on("TestNexus").arg(elmID, MARK_Flash) .beforeEvent("warn","discarding mark to unknown bID-zeitgeist")); CHECK (elmLog.ensureNot("Flash") .afterEvent("destroy","zeitgeist")); @@ -367,8 +368,8 @@ namespace test { CHECK (not mockB.isTouched()); CHECK (not mockC.isTouched()); - uiBus.mark (alpha, GenNode{"Message", "Centauri"}); - uiBus.mark (bravo, GenNode{"Flash", true}); + uiBus.mark (alpha, GenNode{"Message", "Centauri"}); + uiBus.mark (bravo, GenNode{"Flash", true}); uiBus.mark (charly, GenNode{"Message", "Delta"}); uiBus.mark (charly, GenNode{"Error", "Echo"}); @@ -497,8 +498,8 @@ namespace test { auto& stateManager = gui::test::Nexus::getMockStateManager(); CHECK (stateManager.currentState(alpha, "expand") == GenNode("expand", false )); CHECK (stateManager.currentState(bravo, "expand") == GenNode("expand", true )); - CHECK (stateManager.currentState(charly, "expand") == Ref::NO); - CHECK (stateManager.currentState(charly, "Error") == GenNode("Error", "Echo")); // sticky error state was recorded + CHECK (stateManager.currentState(charly,"expand") == Ref::NO); + CHECK (stateManager.currentState(charly, "Error") == GenNode("Error", "Echo")); // sticky error state was recorded // reset error state(s) uiBus.markAll (GenNode{"clearErr", true}); @@ -509,9 +510,9 @@ namespace test { CHECK (stateManager.currentState(alpha, "expand") == GenNode("expand", false )); CHECK (stateManager.currentState(bravo, "expand") == GenNode("expand", true )); - CHECK (stateManager.currentState(charly, "expand") == Ref::NO); - CHECK (stateManager.currentState(charly, "Error") == Ref::NO); // sticky error state was cleared, - // because charly sent a clearErr state mark notification back + CHECK (stateManager.currentState(charly,"expand") == Ref::NO); + CHECK (stateManager.currentState(charly, "Error") == Ref::NO); // sticky error state was cleared, + // because charly sent a clearErr state mark notification back // send global sweeping reset uiBus.markAll (GenNode{"reset", true}); diff --git a/tests/gui/test/mock-elm.hpp b/tests/gui/test/mock-elm.hpp index 82baec4b2..09cf2e996 100644 --- a/tests/gui/test/mock-elm.hpp +++ b/tests/gui/test/mock-elm.hpp @@ -61,6 +61,7 @@ #include "lib/error.hpp" +#include "include/ui-protocol.hpp" #include "lib/test/event-log.hpp" #include "gui/model/tangible.hpp" #include "lib/diff/record.hpp" @@ -126,7 +127,7 @@ namespace test{ virtual bool doReset() override { - log_.call(this->identify(), "reset"); + log_.call(this->identify(), string{MARK_reset}); if (virgin_) return false; // there was nothing to reset @@ -134,22 +135,22 @@ namespace test{ message_ = ""; expanded_ = false; virgin_ = true; - log_.event("reset"); + log_.event(string{MARK_reset}); return true; // we did indeed reset something } // and thus a state mark should be captured virtual bool doExpand (bool yes) override { - log_.call(this->identify(), "expand", yes); + log_.call(this->identify(), string{MARK_expand}, yes); return Tangible::doExpand (yes); } virtual void - doRevealYourself() override + doReveal() override { - log_.call(this->identify(), "revealYourself"); - Tangible::doRevealYourself(); // NOTE: without specific configuration this is NOP + log_.call(this->identify(), string{MARK_reveal}); + Tangible::doReveal(); // NOTE: without specific configuration this is NOP } virtual bool