[dasher: 59/217] Completely customized control box - all commands are parsed from control.xml
- From: Patrick Welche <pwelche src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dasher: 59/217] Completely customized control box - all commands are parsed from control.xml
- Date: Sat, 27 Feb 2016 12:05:17 +0000 (UTC)
commit 67b6544e9af8426c8b92c63ccc05d6cdb3d9c394
Author: ipomoena <amajorek google com>
Date: Tue Oct 13 18:19:42 2015 -0700
Completely customized control box - all commands are parsed from control.xml
Data/control/control.dtd | 18 ++-
Src/DasherCore/ControlManager.cpp | 242 ++++++++++++++++++++-----------------
Src/DasherCore/ControlManager.h | 32 +----
3 files changed, 150 insertions(+), 142 deletions(-)
---
diff --git a/Data/control/control.dtd b/Data/control/control.dtd
index 28a5b79..5d9c428 100644
--- a/Data/control/control.dtd
+++ b/Data/control/control.dtd
@@ -1,7 +1,7 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="utf-8"?>
<!ELEMENT nodes (node*)>
-<!ELEMENT node ((node|move|delete|ref|root|alph)*)>
+<!ELEMENT node ((node|move|delete|copy|speak|pause|stop|ref|root|alph)*)>
<!--by specifying the name attribute as type ID rather than CDATA, the XML
validator checks that all IDs are distinct:-->
<!ATTLIST node name ID #IMPLIED>
@@ -10,11 +10,21 @@
<!ELEMENT move EMPTY>
<!ATTLIST move forward (yes|no) #REQUIRED>
-<!ATTLIST move dist (char|word|line|file) #REQUIRED>
+<!ATTLIST move dist (char|word|line|sentence|paragraph|file) #REQUIRED>
<!ELEMENT delete EMPTY>
<!ATTLIST delete forward (yes|no) #REQUIRED>
-<!ATTLIST delete dist (char|word|line|file) #REQUIRED>
+<!ATTLIST delete dist (char|word|line|sentence|paragraph|file) #REQUIRED>
+
+<!ELEMENT copy EMPTY>
+<!ATTLIST copy dist (all|new|repeat|sentence|paragraph) #REQUIRED>
+
+<!ELEMENT speak EMPTY>
+<!ATTLIST speak what (cancel|all|new|repeat|sentence|paragraph) #REQUIRED>
+
+<!ELEMENT pause EMPTY>
+
+<!ELEMENT stop EMPTY>
<!ELEMENT ref EMPTY>
<!--by specifying the name attribute as type IDREF rather than CDATA, the XML
diff --git a/Src/DasherCore/ControlManager.cpp b/Src/DasherCore/ControlManager.cpp
index c7342e6..855ad79 100644
--- a/Src/DasherCore/ControlManager.cpp
+++ b/Src/DasherCore/ControlManager.cpp
@@ -236,30 +236,129 @@ void CControlParser::XmlEndHandler(const XML_Char *szName) {
}
}
+class Dasher::SpeechHeader : public CDasherInterfaceBase::TextAction{
+public:
+ SpeechHeader(CDasherInterfaceBase *pIntf) : TextAction(pIntf) {}
+ void operator()(const std::string &strText) {
+ m_pIntf->Speak(strText, false);
+ }
+};
+
+class Dasher::CopyHeader : public CDasherInterfaceBase::TextAction{
+public:
+ CopyHeader(CDasherInterfaceBase *pIntf) : TextAction(pIntf) {}
+ void operator()(const std::string &strText) {
+ m_pIntf->CopyToClipboard(strText);
+ }
+};
+
+class Pause : public CControlBase::Action{
+public:
+ void happen(CControlBase::CContNode *pNode) {
+ pNode->mgr()->GetDasherInterface()->GetActiveInputMethod()->pause();
+ }
+};
+
+class SpeakCancel : public CControlBase::Action {
+public:
+ void happen(CControlBase::CContNode *pNode) {
+ pNode->mgr()->GetDasherInterface()->Speak("", true);
+ }
+};
+
+template <typename T> class MethodAction : public CControlBase::Action {
+public:
+ ///A "Method" is pointer to a function "void X()", that is a member of a T...
+ typedef void (T::*Method)();
+ MethodAction(T *pRecv, Method f) : m_pRecv(pRecv), m_f(f) {
+ }
+ virtual void happen(CControlBase::CContNode *pNode) {
+ //invoke pointer-to-member-function m_f on object *m_pRecv!
+ (m_pRecv->*m_f)();
+ }
+private:
+ T *m_pRecv;
+ Method m_f;
+};
+
+class Delete : public CControlBase::Action {
+ const bool m_bForwards;
+ const CControlManager::EditDistance m_dist;
+public:
+ Delete(bool bForwards, CControlManager::EditDistance dist) : m_bForwards(bForwards), m_dist(dist) {
+ }
+ virtual void happen(CControlBase::CContNode *pNode) {
+ pNode->mgr()->GetDasherInterface()->ctrlDelete(m_bForwards, m_dist);
+ }
+};
+
+class Move : public CControlBase::Action {
+ const bool m_bForwards;
+ const CControlManager::EditDistance m_dist;
+public:
+ Move(bool bForwards, CControlManager::EditDistance dist) : m_bForwards(bForwards), m_dist(dist) {
+ }
+ virtual void happen(CControlBase::CContNode *pNode) {
+ pNode->mgr()->GetDasherInterface()->ctrlMove(m_bForwards, m_dist);
+ }
+};
+
+
CControlManager::CControlManager(CSettingsUser *pCreateFrom, CNodeCreationManager *pNCManager,
CDasherInterfaceBase *pInterface)
: CControlParser(pInterface), CControlBase(pCreateFrom, pInterface, pNCManager),
CSettingsObserver(pCreateFrom), m_pSpeech(NULL), m_pCopy(NULL) {
//TODO, used to be able to change label+colour of root/pause/stop from controllabels.xml
// (or, get the root node title "control" from the alphabet!)
+ m_pSpeech = new SpeechHeader(pInterface);
+ m_pCopy = new CopyHeader(pInterface);
SetRootTemplate(new NodeTemplate("",8)); //default NodeTemplate does nothing
GetRootTemplate()->successors.push_back(NULL);
- m_pPause = new Pause("Pause",241);
- m_pPause->successors.push_back(NULL);
- m_pPause->successors.push_back(GetRootTemplate());
- m_pStop = new MethodTemplate<CDasherInterfaceBase>(_("Done"), 242, pInterface,
&CDasherInterfaceBase::Done);
- m_pStop->successors.push_back(NULL);
- m_pStop->successors.push_back(GetRootTemplate());
+ // Key in actions map is name plus arguments in alphabetical order.
+ m_actions["stop"] = new MethodAction<CDasherInterfaceBase>(pInterface, &CDasherInterfaceBase::Done);
+ m_actions["pause"] = new Pause();
+
+ m_actions["speak what=cancel"] = new SpeakCancel();
+ m_actions["speak what=all"] = new MethodAction<SpeechHeader>(m_pSpeech, &SpeechHeader::executeOnAll);
+ m_actions["speak what=new"] = new MethodAction<SpeechHeader>(m_pSpeech, &SpeechHeader::executeOnNew);
+ m_actions["speak what=repeat"] = new MethodAction<SpeechHeader>(m_pSpeech, &SpeechHeader::executeLast);
+
+ m_actions["copy what=all"] = new MethodAction<CopyHeader>(m_pCopy, &CopyHeader::executeOnAll);
+ m_actions["copy what=new"] = new MethodAction<CopyHeader>(m_pCopy, &CopyHeader::executeOnNew);
+ m_actions["copy what=repeat"] = new MethodAction<CopyHeader>(m_pCopy, &CopyHeader::executeLast);
+
+ m_actions["move dist=char forward=yes"] = new Move(true, EDIT_CHAR);
+ m_actions["move dist=word forward=yes"] = new Move(true, EDIT_WORD);
+ m_actions["move dist=line forward=yes"] = new Move(true, EDIT_LINE);
+ m_actions["move dist=sentence forward=yes"] = new Move(true, EDIT_SENTENCE);
+ m_actions["move dist=paragraph forward=yes"] = new Move(true, EDIT_PARAGRAPH);
+ m_actions["move dist=file forward=yes"] = new Move(true, EDIT_FILE);
+
+ m_actions["move dist=char forward=no"] = new Move(true, EDIT_CHAR);
+ m_actions["move dist=word forward=no"] = new Move(true, EDIT_WORD);
+ m_actions["move dist=line forward=no"] = new Move(true, EDIT_LINE);
+ m_actions["move dist=sentence forward=no"] = new Move(true, EDIT_SENTENCE);
+ m_actions["move dist=paragraph forward=no"] = new Move(true, EDIT_PARAGRAPH);
+ m_actions["move dist=file forward=no"] = new Move(true, EDIT_FILE);
+
+ m_actions["delete dist=char forward=yes"] = new Delete(true, EDIT_CHAR);
+ m_actions["delete dist=word forward=yes"] = new Delete(true, EDIT_WORD);
+ m_actions["delete dist=line forward=yes"] = new Delete(true, EDIT_LINE);
+ m_actions["delete dist=sentence forward=yes"] = new Delete(true, EDIT_SENTENCE);
+ m_actions["delete dist=paragraph forward=yes"] = new Delete(true, EDIT_PARAGRAPH);
+ m_actions["delete dist=file forward=yes"] = new Delete(true, EDIT_FILE);
+
+ m_actions["delete dist=char forward=no"] = new Delete(true, EDIT_CHAR);
+ m_actions["delete dist=word forward=no"] = new Delete(true, EDIT_WORD);
+ m_actions["delete dist=line forward=no"] = new Delete(true, EDIT_LINE);
+ m_actions["delete dist=sentence forward=no"] = new Delete(true, EDIT_SENTENCE);
+ m_actions["delete dist=paragraph forward=no"] = new Delete(true, EDIT_PARAGRAPH);
+ m_actions["delete dist=file forward=no"] = new Delete(true, EDIT_FILE);
m_pInterface->ScanFiles(this, "control.xml"); //just look for the one
updateActions();
}
-CControlBase::Pause::Pause(const string &strLabel, int iColour) : NodeTemplate(strLabel,iColour) {
-}
-void CControlBase::Pause::happen(CContNode *pNode) {
- pNode->mgr()->m_pInterface->GetActiveInputMethod()->pause();
-}
CControlBase::NodeTemplate *CControlManager::parseOther(const XML_Char *name, const XML_Char **atts) {
if (strcmp(name,"root")==0) return GetRootTemplate();
@@ -267,117 +366,30 @@ CControlBase::NodeTemplate *CControlManager::parseOther(const XML_Char *name, co
}
CControlBase::Action *CControlManager::parseAction(const XML_Char *name, const XML_Char **atts) {
- if (strcmp(name,"delete")==0 || strcmp(name,"move")==0) {
- bool bForwards=true; //pick some defaults...
- EditDistance dist=EDIT_WORD; // (?!)
- while (*atts) {
- if (strcmp(*atts,"forward")==0)
- bForwards=(strcmp(*(atts+1),"yes")==0 || strcmp(*(atts+1),"true")==0 || strcmp(*(atts+1),"on")==0);
- else if (strcmp(*atts,"dist")==0) {
- if (strcmp(*(atts+1),"char")==0)
- dist=EDIT_CHAR;
- else if (strcmp(*(atts+1),"word")==0)
- dist=EDIT_WORD;
- else if (strcmp(*(atts+1),"line")==0)
- dist = EDIT_LINE;
- else if (strcmp(*(atts + 1), "sentence") == 0)
- dist = EDIT_SENTENCE;
- else if (strcmp(*(atts + 1), "paragraph") == 0)
- dist = EDIT_PARAGRAPH;
- else if (strcmp(*(atts + 1), "file") == 0)
- dist = EDIT_FILE;
- }
- atts+=2;
- }
- class DirDist {
- protected:
- const bool m_bForwards;
- const EditDistance m_dist;
- public:
- DirDist(bool bForwards,EditDistance dist) : m_bForwards(bForwards), m_dist(dist) {
- }
- };
-
- if (name[0]=='d') {
- class Delete : private DirDist, public Action {
- public:
- Delete(bool bForwards,EditDistance dist) : DirDist(bForwards,dist) {
- }
- void happen(CContNode *pNode) {
- static_cast<CControlManager*>(pNode->mgr())->m_pInterface->ctrlDelete(m_bForwards,m_dist);
- }
- };
- return new Delete(bForwards,dist);
- } else {
- class Move : private DirDist, public Action {
- public:
- Move(bool bForwards,EditDistance dist) : DirDist(bForwards, dist) {}
- void happen(CContNode *pNode) {
- static_cast<CControlManager*>(pNode->mgr())->m_pInterface->ctrlMove(m_bForwards,m_dist);
- };
- };
- return new Move(bForwards, dist);
+ map<string, string> arguments;
+ while (*atts) {
+ arguments[*atts] = *(atts + 1);
+ atts += 2;
+ }
+ stringstream key;
+ // Key in actions map is name plus arguments in alphabetical order.
+ key << name;
+ if (!arguments.empty()) {
+ for each (auto arg in arguments) {
+ key << " " << arg.first << "=" << arg.second;
}
}
+ if (auto action = m_actions[key.str()])
+ return action;
+
return CControlParser::parseAction(name, atts);
}
CControlManager::~CControlManager() {
}
-class TextActionHeader : public CDasherInterfaceBase::TextAction, public CControlBase::NodeTemplate {
-public:
- TextActionHeader(CDasherInterfaceBase *pIntf, const string &strHdr, NodeTemplate *pRoot) :
TextAction(pIntf), NodeTemplate(strHdr,-1),
- m_all("All", -1, this, &CDasherInterfaceBase::TextAction::executeOnAll),
- m_new("New", -1, this, &CDasherInterfaceBase::TextAction::executeOnNew),
- m_again("Repeat", -1, this, &CDasherInterfaceBase::TextAction::executeLast) {
- successors.push_back(&m_all); m_all.successors.push_back(NULL); m_all.successors.push_back(pRoot);
- successors.push_back(&m_new); m_new.successors.push_back(NULL); m_new.successors.push_back(pRoot);
- successors.push_back(&m_again); m_again.successors.push_back(NULL); m_again.successors.push_back(pRoot);
- }
-private:
- CControlBase::MethodTemplate<CDasherInterfaceBase::TextAction> m_all, m_new, m_again;
-};
-
-class CancelSpeech : public CControlBase::NodeTemplate {
-public:
- CancelSpeech(CDasherInterfaceBase *pIntf, const std::string &strLabel, int iColour)
- : NodeTemplate(strLabel, iColour), m_pIntf(pIntf){}
-
- void happen(CControlBase::CContNode *pNode) {
- m_pIntf->Speak("", true);
- }
- CDasherInterfaceBase *m_pIntf;
-};
-
-class SpeechHeader : public TextActionHeader {
-public:
- SpeechHeader(CDasherInterfaceBase *pIntf, NodeTemplate *pRoot)
- : TextActionHeader(pIntf, "Speak", pRoot), m_stop(pIntf,"Cancel",242){
- successors.push_back(&m_stop); m_stop.successors.push_back(NULL); m_stop.successors.push_back(pRoot);
- }
- void operator()(const std::string &strText) {
- m_pIntf->Speak(strText, false);
- }
-private:
- CancelSpeech m_stop;
-};
-
-class CopyHeader : public TextActionHeader {
-public:
- CopyHeader(CDasherInterfaceBase *pIntf, NodeTemplate *pRoot) : TextActionHeader(pIntf, "Copy", pRoot) {
- }
- void operator()(const std::string &strText) {
- m_pIntf->CopyToClipboard(strText);
- }
-};
-
void CControlManager::HandleEvent(int iParameter) {
switch (iParameter) {
- case BP_CONTROL_MODE_HAS_HALT:
- case BP_CONTROL_MODE_HAS_EDIT:
- case BP_CONTROL_MODE_HAS_SPEECH:
- case BP_CONTROL_MODE_HAS_COPY:
case BP_COPY_ALL_ON_STOP:
case BP_SPEAK_ALL_ON_STOP:
case SP_INPUT_FILTER:
@@ -386,6 +398,10 @@ void CControlManager::HandleEvent(int iParameter) {
}
void CControlManager::updateActions() {
+ // decide if removal of pause and stop are worth the trouble
+ // reimplement if yes
+ // imo with control.xml it isn't.
+ /*
vector<NodeTemplate *> &vRootSuccessors(GetRootTemplate()->successors);
vector<NodeTemplate *> vOldRootSuccessors;
vOldRootSuccessors.swap(vRootSuccessors);
@@ -428,7 +444,7 @@ void CControlManager::updateActions() {
//copy anything else (custom) that might have been added...
while (it != vOldRootSuccessors.end()) vRootSuccessors.push_back(*it++);
-
+ */
if (CDasherScreen *pScreen = m_pScreen) {
//hack to make ChangeScreen do something
m_pScreen = NULL; //i.e. make it think the screen has changed
diff --git a/Src/DasherCore/ControlManager.h b/Src/DasherCore/ControlManager.h
index d83e54d..88c92d9 100644
--- a/Src/DasherCore/ControlManager.h
+++ b/Src/DasherCore/ControlManager.h
@@ -46,6 +46,8 @@ class CNodeCreationManager;
namespace Dasher {
class CDasherInterfaceBase;
+ class SpeechHeader;
+ class CopyHeader;
/// \ingroup Model
/// @{
@@ -94,27 +96,6 @@ namespace Dasher {
CDasherScreen::Label *m_pLabel;
};
- class Pause : public NodeTemplate {
- public:
- Pause(const std::string &strLabel, int iColour);
- void happen(CContNode *pNode);
- };
-
- template <typename T> class MethodTemplate : public NodeTemplate {
- public:
- ///A "Method" is pointer to a function "void X()", that is a member of a T...
- typedef void (T::*Method)();
- MethodTemplate(const std::string &strLabel, int color, T *pRecv, Method f) :
NodeTemplate(strLabel,color),m_pRecv(pRecv),m_f(f) {
- }
- virtual void happen(CContNode *pNode) {
- //invoke pointer-to-member-function m_f on object *m_pRecv!
- (m_pRecv->*m_f)();
- }
- private:
- T *m_pRecv;
- Method m_f;
- };
-
NodeTemplate *GetRootTemplate();
CControlBase(CSettingsUser *pCreateFrom, CDasherInterfaceBase *pInterface, CNodeCreationManager
*pNCManager);
@@ -127,7 +108,7 @@ namespace Dasher {
///
virtual CDasherNode *GetRoot(CDasherNode *pContext, int iOffset);
-
+ CDasherInterfaceBase* GetDasherInterface() { return m_pInterface; }
protected:
///Sets the root - should be called by subclass constructor to make
/// superclass ready for use.
@@ -220,9 +201,10 @@ namespace Dasher {
Action *parseAction(const XML_Char *name, const XML_Char **atts);
private:
- NodeTemplate *m_pPause, *m_pStop;
- ///group headers, with three children each (all/new/repeat)
- NodeTemplate *m_pSpeech, *m_pCopy;
+ map<string, CControlBase::Action*> m_actions;
+ ///group of state full actions (all/new/repeat/...)
+ SpeechHeader *m_pSpeech;
+ CopyHeader *m_pCopy;
};
/// @}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]