implement state reset handlers / mock handlers
This commit is contained in:
parent
afeedfc288
commit
18b6a388a0
6 changed files with 210 additions and 71 deletions
|
|
@ -64,57 +64,67 @@ namespace model {
|
|||
virtual bool
|
||||
doReset() override
|
||||
{
|
||||
UNIMPLEMENTED ("reset");
|
||||
UNIMPLEMENTED ("Controller reset");
|
||||
}
|
||||
|
||||
virtual bool
|
||||
doExpand (bool yes) override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doExpand");
|
||||
UNIMPLEMENTED ("Controller doExpand");
|
||||
}
|
||||
|
||||
virtual void
|
||||
doReveal (ID child) override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doReveal");
|
||||
UNIMPLEMENTED ("Controller doReveal");
|
||||
}
|
||||
|
||||
virtual void
|
||||
doRevealYourself() override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doRevealYourself");
|
||||
UNIMPLEMENTED ("Controller doRevealYourself");
|
||||
}
|
||||
|
||||
virtual void
|
||||
virtual bool
|
||||
doMsg (string text) override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doMsg");
|
||||
UNIMPLEMENTED ("Controller doMsg");
|
||||
}
|
||||
|
||||
virtual void
|
||||
virtual bool
|
||||
doClearMsg () override
|
||||
{
|
||||
UNIMPLEMENTED ("Controller doClearMsg");
|
||||
}
|
||||
|
||||
virtual bool
|
||||
doErr (string text) override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doErr");
|
||||
UNIMPLEMENTED ("Controller doErr");
|
||||
}
|
||||
|
||||
virtual bool
|
||||
doClearErr () override
|
||||
{
|
||||
UNIMPLEMENTED ("Controller doClearErr");
|
||||
}
|
||||
|
||||
virtual void
|
||||
doFlash() override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doFlash");
|
||||
UNIMPLEMENTED ("Controller doFlash");
|
||||
}
|
||||
|
||||
virtual void
|
||||
doMark (GenNode const& mark) override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doMark");
|
||||
UNIMPLEMENTED ("Controller doMark");
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
using Tangible::Tangible;
|
||||
|
||||
protected:
|
||||
string maybe () const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -48,41 +48,96 @@ namespace model {
|
|||
/** invoke the generic reset hook
|
||||
* @note the actual subclass has to override the doReset() hook
|
||||
* to perform the actual clean-up work.
|
||||
* @note in case an actual reset happened, the implementation should
|
||||
* return `true` from this `doReset()` hook. As a consequence,
|
||||
* a new "reset" state mark is emitted, which causes the
|
||||
* PresentationStateManager to discard any state
|
||||
* previously recorded for this element.
|
||||
* @remarks the intention is that, after invoking reset(), the
|
||||
* interface element or controller is in pristine (presentation) state
|
||||
*/
|
||||
void
|
||||
Tangible::reset()
|
||||
{
|
||||
this->doReset();
|
||||
uiBus_.note (GenNode("reset", true));
|
||||
if (this->doReset())
|
||||
uiBus_.note (GenNode{"reset", true});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepare a command or action for actual invocation, once the execution context
|
||||
* has been established. The action is not executed right away, but it is now ready
|
||||
* and bound to the concrete arguments supplied with the [record](\ref lib::diff::Rec).
|
||||
* @param prototype handle to a command instantiation, to be readied for invocation
|
||||
* @param arguments suitable tuple of values, to be used to outfit the prototype
|
||||
/** invoke the hook to clear error markers
|
||||
* @note the actual subclass has to override the doClearErr() hook...
|
||||
* @note and similar to the reset() call, also the implementation should
|
||||
* return `true` in case any actual (sticky) error state has been cleared.
|
||||
* Again, this causes emitting of a "resetErr" state mark, which will
|
||||
* purge any sticky error state remembered within the state manager.
|
||||
* @remarks usually, most error markers are _not sticky_, that is, they will
|
||||
* be forgotten when the session ends. In this case, the implementation
|
||||
* doesn't need to care for anything special. Only in those cases, where
|
||||
* actually an error state has to be preserved, the implementation should
|
||||
* - emit an "Error" state mark, with the sticky error state in payload
|
||||
* - be prepared to recognise when this sticky error state is fed back
|
||||
* - actually signal the sticky state has to be purged when it is cleared.
|
||||
*/
|
||||
void
|
||||
Tangible::prepareCommand (Cmd const& prototype, Rec&& arguments)
|
||||
{
|
||||
uiBus_.act (prototype.bind (std::forward<Rec>(arguments)));
|
||||
}
|
||||
Tangible::clearErr()
|
||||
{
|
||||
if (this->doClearErr())
|
||||
uiBus_.note (GenNode{"clearErr", true});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Actually trigger execution of an action or command.
|
||||
* @param preparedAction handle pointing to a command definition,
|
||||
* which needs to be outfitted with arguments and ready for invocation.
|
||||
/** invoke the hook to clear notification messages
|
||||
* @remarks everything is symmetrical to reset() and clearErr() here...
|
||||
*/
|
||||
void
|
||||
Tangible::issueCommand (Cmd const& preparedAction)
|
||||
{
|
||||
uiBus_.act (preparedAction.bang());
|
||||
}
|
||||
Tangible::clearMsg()
|
||||
{
|
||||
if (this->doClearMsg())
|
||||
uiBus_.note (GenNode{"clearMsg", true});
|
||||
}
|
||||
|
||||
|
||||
/** highlight the element visually to catch the user's attention
|
||||
* @remarks this is meant as a short transient visual change,
|
||||
* just to indicate something of relevance happened here.
|
||||
*/
|
||||
void
|
||||
Tangible::markFlash()
|
||||
{
|
||||
this->doFlash();
|
||||
}
|
||||
|
||||
|
||||
/** push a notification (or warning) message to the element.
|
||||
* @param message notification text
|
||||
* @note the actual interface response need to be coded
|
||||
* in the concrete subclass within doMsg().
|
||||
* @remarks the intention is for this message to be somehow
|
||||
* visible at this element, e.g. as mouse over.
|
||||
* When this notification is meant to be "sticky" / permanent,
|
||||
* then the mentioned doMsg() implementation function should
|
||||
* return true; in this case we'll emit a "state mark notification",
|
||||
* which will be recorded by the PresentationStateManager, under
|
||||
* the property name "`Message`" for this UI-Element.
|
||||
* This mechanism allows to persist such UI states.
|
||||
*/
|
||||
void
|
||||
Tangible::markMsg (string message)
|
||||
{
|
||||
if (this->doMsg (message))
|
||||
uiBus_.note (GenNode{"Message", message});
|
||||
}
|
||||
|
||||
|
||||
/** push an error state tag to the element
|
||||
* @remarks everything detailed at markMsg applies here too.
|
||||
*/
|
||||
void
|
||||
Tangible::markErr (string error)
|
||||
{
|
||||
if (this->doErr (error))
|
||||
uiBus_.note (GenNode("Error", error));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -131,6 +186,51 @@ namespace model {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Prepare a command or action for actual invocation, once the execution context
|
||||
* has been established. The action is not executed right away, but it is now ready
|
||||
* and bound to the concrete arguments supplied with the [record](\ref lib::diff::Rec).
|
||||
* @param prototype handle to a command instantiation, to be readied for invocation
|
||||
* @param arguments suitable tuple of values, to be used to outfit the prototype
|
||||
*/
|
||||
void
|
||||
Tangible::prepareCommand (Cmd const& prototype, Rec&& arguments)
|
||||
{
|
||||
uiBus_.act (prototype.bind (std::forward<Rec>(arguments)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Actually trigger execution of an action or command.
|
||||
* @param preparedAction handle pointing to a command definition,
|
||||
* which needs to be outfitted with arguments and ready for invocation.
|
||||
*/
|
||||
void
|
||||
Tangible::issueCommand (Cmd const& preparedAction)
|
||||
{
|
||||
uiBus_.act (preparedAction.bang());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** generic handler for all incoming "state mark" messages */
|
||||
void
|
||||
Tangible::mark (GenNode const& stateMark)
|
||||
{
|
||||
if (stateMark.idi.getSym() == "Flash")
|
||||
this->doFlash();
|
||||
else
|
||||
if (stateMark.idi.getSym() == "Error")
|
||||
this->markErr (stateMark.data.get<string>());
|
||||
else
|
||||
if (stateMark.idi.getSym() == "Message")
|
||||
this->markMsg (stateMark.data.get<string>());
|
||||
else
|
||||
this->doMark(stateMark);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* default implementation and catch-all handler for receiving »state mark« messages.
|
||||
* Such messages serve either to cause a presentation state effect specific to this
|
||||
|
|
@ -157,7 +257,13 @@ namespace model {
|
|||
this->doExpand (stateMark.data.get<bool>());
|
||||
else
|
||||
if (stateMark.idi.getSym() == "reset")
|
||||
this->doReset();
|
||||
this->reset();
|
||||
else
|
||||
if (stateMark.idi.getSym() == "clearMsg")
|
||||
this->clearMsg();
|
||||
else
|
||||
if (stateMark.idi.getSym() == "clearErr")
|
||||
this->clearErr();
|
||||
else
|
||||
if (stateMark.idi.getSym() == "revealYourself")
|
||||
this->doRevealYourself();
|
||||
|
|
|
|||
|
|
@ -174,6 +174,8 @@ namespace model {
|
|||
operator ID() const { return uiBus_.getID();}
|
||||
|
||||
void reset();
|
||||
void clearMsg();
|
||||
void clearErr();
|
||||
|
||||
template<typename...ARGS>
|
||||
void prepareCommand (Cmd const& prototype, ARGS&&...);
|
||||
|
|
@ -185,19 +187,21 @@ namespace model {
|
|||
|
||||
void slotReveal(ID child);
|
||||
|
||||
void markMsg (string m) { this->doMsg(m); }
|
||||
void markErr (string e) { this->doErr(e); }
|
||||
void markFlash() { this->doFlash();}
|
||||
void markFlash();
|
||||
void markMsg (string message);
|
||||
void markErr (string error);
|
||||
void mark(GenNode const&);
|
||||
|
||||
protected:
|
||||
virtual bool doReset() =0;
|
||||
virtual bool doClearMsg() =0;
|
||||
virtual bool doClearErr() =0;
|
||||
virtual bool doExpand (bool yes) =0;
|
||||
virtual void doReveal (ID child) =0;
|
||||
virtual void doRevealYourself () =0;
|
||||
|
||||
virtual void doMsg (string) =0;
|
||||
virtual void doErr (string) =0;
|
||||
virtual bool doMsg (string) =0;
|
||||
virtual bool doErr (string) =0;
|
||||
virtual void doFlash() =0;
|
||||
virtual void doMark(GenNode const&) =0;
|
||||
private:
|
||||
|
|
@ -219,23 +223,6 @@ namespace model {
|
|||
|
||||
|
||||
|
||||
/** generic handler for all incoming "state mark" messages */
|
||||
inline void
|
||||
Tangible::mark (GenNode const& stateMark)
|
||||
{
|
||||
if (stateMark.idi.getSym() == "Flash")
|
||||
this->doFlash();
|
||||
else
|
||||
if (stateMark.idi.getSym() == "Error")
|
||||
this->doErr (stateMark.data.get<string>());
|
||||
else
|
||||
if (stateMark.idi.getSym() == "Message")
|
||||
this->doMsg (stateMark.data.get<string>());
|
||||
else
|
||||
this->doMark(stateMark);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace gui::model
|
||||
#endif /*GUI_MODEL_TANGIBLE_H*/
|
||||
|
|
|
|||
|
|
@ -64,57 +64,67 @@ namespace model {
|
|||
virtual bool
|
||||
doReset() override
|
||||
{
|
||||
UNIMPLEMENTED ("reset");
|
||||
UNIMPLEMENTED ("Widget reset");
|
||||
}
|
||||
|
||||
virtual bool
|
||||
doExpand (bool yes) override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doExpand");
|
||||
UNIMPLEMENTED ("Widget doExpand");
|
||||
}
|
||||
|
||||
virtual void
|
||||
doReveal (ID child) override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doReveal");
|
||||
UNIMPLEMENTED ("Widget doReveal");
|
||||
}
|
||||
|
||||
virtual void
|
||||
doRevealYourself() override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doRevealYourself");
|
||||
UNIMPLEMENTED ("Widget doRevealYourself");
|
||||
}
|
||||
|
||||
virtual void
|
||||
virtual bool
|
||||
doMsg (string text) override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doMsg");
|
||||
UNIMPLEMENTED ("Widget doMsg");
|
||||
}
|
||||
|
||||
virtual void
|
||||
virtual bool
|
||||
doClearMsg () override
|
||||
{
|
||||
UNIMPLEMENTED ("Widget doClearMsg");
|
||||
}
|
||||
|
||||
virtual bool
|
||||
doErr (string text) override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doErr");
|
||||
UNIMPLEMENTED ("Widget doErr");
|
||||
}
|
||||
|
||||
virtual bool
|
||||
doClearErr () override
|
||||
{
|
||||
UNIMPLEMENTED ("Widget doClearErr");
|
||||
}
|
||||
|
||||
virtual void
|
||||
doFlash() override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doFlash");
|
||||
UNIMPLEMENTED ("Widget doFlash");
|
||||
}
|
||||
|
||||
virtual void
|
||||
doMark (GenNode const& mark) override
|
||||
{
|
||||
UNIMPLEMENTED ("mock doMark");
|
||||
UNIMPLEMENTED ("Widget doMark");
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
using Tangible::Tangible;
|
||||
|
||||
protected:
|
||||
string maybe () const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -444,7 +444,7 @@ namespace test {
|
|||
CHECK ("Centauri" == mockA.getMessage());
|
||||
|
||||
// reset all notification messages
|
||||
uiBus.markAll (GenNode{"resetMsg", true});
|
||||
uiBus.markAll (GenNode{"clearMsg", true});
|
||||
CHECK (mockB.isExpanded());
|
||||
CHECK (mockC.isError());
|
||||
CHECK (isnil (mockA.getMessage()));
|
||||
|
|
@ -455,7 +455,7 @@ namespace test {
|
|||
mockA.slotCollapse();
|
||||
|
||||
// reset error state(s)
|
||||
uiBus.markAll (GenNode{"resetErr", true});
|
||||
uiBus.markAll (GenNode{"clearErr", true});
|
||||
CHECK (not mockB.isExpanded());
|
||||
CHECK (mockB.isExpanded());
|
||||
CHECK ("miss" == mockB.getMessage());
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ namespace test{
|
|||
UNIMPLEMENTED ("mock doRevealYourself");
|
||||
}
|
||||
|
||||
virtual void
|
||||
virtual bool
|
||||
doMsg (string text) override
|
||||
{
|
||||
log_.call (this->identify(), "doMsg", text);
|
||||
|
|
@ -162,9 +162,22 @@ namespace test{
|
|||
message_ = text;
|
||||
virgin_ = false;
|
||||
log_.note ("type=mark", "ID=Message", text);
|
||||
|
||||
return false; // messages not sticky for this mock implementation
|
||||
}
|
||||
|
||||
virtual void
|
||||
virtual bool
|
||||
doClearMsg () override
|
||||
{
|
||||
log_.call (this->identify(), "doClearMsg");
|
||||
if (isnil (message_))
|
||||
return false;
|
||||
|
||||
message_ = "";
|
||||
log_.note ("type=mark", "ID=Message", "Message notification cleared");
|
||||
}
|
||||
|
||||
virtual bool
|
||||
doErr (string text) override
|
||||
{
|
||||
log_.call (this->identify(), "doErr", text);
|
||||
|
|
@ -172,6 +185,19 @@ namespace test{
|
|||
error_ = text;
|
||||
virgin_ = false;
|
||||
log_.note ("type=mark", "ID=Error", text);
|
||||
|
||||
return true; // error states are sticky for this mock implementation
|
||||
}
|
||||
|
||||
virtual bool
|
||||
doClearErr () override
|
||||
{
|
||||
log_.call (this->identify(), "doClearErr");
|
||||
if (not isError())
|
||||
return false;
|
||||
|
||||
error_ = "";
|
||||
log_.note ("type=mark", "ID=Error", "Error state cleared");
|
||||
}
|
||||
|
||||
virtual void
|
||||
|
|
|
|||
Loading…
Reference in a new issue