[dasher: 170/217] Core changes for letting users select different control box layouts.



commit 27376976a8a04916e6150f66a0b37a4d79b5e8d0
Author: Ada Majorek <amajorek google com>
Date:   Wed Jan 13 10:14:20 2016 -0800

    Core changes for letting users select different control box layouts.

 Src/DasherCore/ControlManager.cpp      |   55 +++++++++++++++++++++++++-------
 Src/DasherCore/ControlManager.h        |   18 +++++++++--
 Src/DasherCore/DasherInterfaceBase.cpp |   15 +++++++--
 Src/DasherCore/DasherInterfaceBase.h   |    1 +
 Src/DasherCore/NodeCreationManager.cpp |   16 ++++++---
 Src/DasherCore/NodeCreationManager.h   |    8 +++--
 6 files changed, 86 insertions(+), 27 deletions(-)
---
diff --git a/Src/DasherCore/ControlManager.cpp b/Src/DasherCore/ControlManager.cpp
index 93ee234..42a5099 100644
--- a/Src/DasherCore/ControlManager.cpp
+++ b/Src/DasherCore/ControlManager.cpp
@@ -180,13 +180,13 @@ bool CControlParser::ParseFile(const string &strFileName, bool bUser) {
   namedNodes.clear();
   unresolvedRefs.clear();
   nodeStack.clear();
-  
+
   if (!AbstractXMLParser::ParseFile(strFileName, bUser)) return false;
   //resolve any forward references to nodes declared later
-  for (vector<pair<CControlBase::NodeTemplate**,string> >::iterator it=unresolvedRefs.begin(); 
it!=unresolvedRefs.end(); it++) {
-    map<string,CControlBase::NodeTemplate*>::iterator target = namedNodes.find(it->second);
+  for (auto ref : unresolvedRefs) {
+    auto target = namedNodes.find(ref.second);
     if (target != namedNodes.end())
-      *(it->first) = target->second;
+      *(ref.first) = target->second;
   }
   //somehow, need to clear out any refs that weren't resolved...???
   return true;
@@ -417,16 +417,8 @@ CControlManager::CControlManager(CSettingsUser *pCreateFrom, CNodeCreationManage
   m_actions["delete dist=paragraph forward=no"] = new Delete(false, EDIT_PARAGRAPH);
   m_actions["delete dist=page forward=no"] = new Delete(false, EDIT_PAGE);
   m_actions["delete dist=all forward=no"] = new Delete(false, EDIT_FILE);
-  auto id = GetStringParameter(SP_CONTROL_BOX_ID);
-  string fileName = "control.xml";
-  if (!id.empty())
-    fileName = "control." + id + ".xml";
-  m_pInterface->ScanFiles(this, fileName);
-
-  updateActions();
 }
 
-
 CControlBase::NodeTemplate *CControlManager::parseOther(const XML_Char *name, const XML_Char **atts) {
   if (strcmp(name,"root")==0) return GetRootTemplate();
   return CControlParser::parseOther(name, atts);
@@ -488,3 +480,42 @@ void CControlManager::updateActions() {
     ChangeScreen(pScreen);
   }
 }
+
+CControlBoxIO::CControlBoxIO(CMessageDisplay *pMsgs) : AbstractXMLParser(pMsgs) {
+}
+CControlManager* CControlBoxIO::CreateControlManager(
+  const std::string& id, CSettingsUser *pCreateFrom, CNodeCreationManager *pNCManager, 
+  CDasherInterfaceBase *pInterface) const {
+  auto mgr = new CControlManager(pCreateFrom, pNCManager, pInterface);
+  auto it = m_controlFiles.find(id);
+  if (it != m_controlFiles.end())
+    mgr->ParseFile(it->second, true);
+  mgr->updateActions();
+  return mgr;
+}
+
+void CControlBoxIO::GetControlBoxes(std::vector < std::string > *pList) const {
+  for (auto id_filename : m_controlFiles)
+    pList->push_back(id_filename.first);
+}
+
+bool CControlBoxIO::ParseFile(const std::string &strFilename, bool bUser) {
+  m_filename = strFilename;
+  return AbstractXMLParser::ParseFile(strFilename, bUser);
+}
+
+void CControlBoxIO::XmlStartHandler(const XML_Char *name, const XML_Char **atts) {
+  if (strcmp(name, "nodes") == 0) {
+    string id;
+    while (*atts != 0) {
+      if (strcmp(*atts, "name") == 0) {
+        id = *(atts + 1);
+      }
+      atts += 2;
+    }
+    if (!isUser() && m_controlFiles.count(id))
+      return; // Ignore system files if that name already taken
+
+    m_controlFiles[id] = m_filename;
+  }
+}
diff --git a/Src/DasherCore/ControlManager.h b/Src/DasherCore/ControlManager.h
index d12f368..8288cfd 100644
--- a/Src/DasherCore/ControlManager.h
+++ b/Src/DasherCore/ControlManager.h
@@ -137,7 +137,6 @@ namespace Dasher {
   class CControlParser : public AbstractXMLParser {
   public:
     CControlParser(CMessageDisplay *pMsgs);
-  protected:
     ///Loads all node definitions from the specified filename. Note that
     /// system files will not be loaded if user files are (and user files will
     /// clear out any nodes from system ones). However, multiple system or multiple
@@ -147,7 +146,7 @@ namespace Dasher {
     /// \param bUser true if from user-specific location (takes priority over system)
     /// \return true if the file was opened successfully; false if not.
     bool ParseFile(const std::string &strFilename, bool bUser);
-    
+  protected:
     /// \return all node definitions that have been loaded by this CControlParser.
     const vector<CControlBase::NodeTemplate*> &parsedNodes();
     ///Subclasses may override to parse other nodes (besides "node", "ref" and "alph").
@@ -206,11 +205,24 @@ namespace Dasher {
 
   private:
     map<string, CControlBase::Action*> m_actions;
-    ///group of state full actions (all/new/repeat/...)
+    ///group of statefull actions (all/new/repeat/...)
     SpeechHeader *m_pSpeech;
     CopyHeader *m_pCopy;
   };
   /// @}
+
+  class CControlBoxIO : public AbstractXMLParser {
+  public:
+    CControlBoxIO(CMessageDisplay *pMsgs);
+    void GetControlBoxes(std::vector < std::string > *pList) const;
+    CControlManager* CreateControlManager(const std::string& id, CSettingsUser *pCreateFrom, 
CNodeCreationManager *pNCManager, CDasherInterfaceBase *pInterface) const;
+    bool ParseFile(const std::string &strFilename, bool bUser) override;
+    void XmlStartHandler(const XML_Char *name, const XML_Char **atts) override;
+    void XmlEndHandler(const XML_Char *szName) override {};
+  private:
+    std::map<std::string, std::string> m_controlFiles;
+    std::string m_filename;
+  };
 }
 
 
diff --git a/Src/DasherCore/DasherInterfaceBase.cpp b/Src/DasherCore/DasherInterfaceBase.cpp
index 0ad4041..e76d50a 100644
--- a/Src/DasherCore/DasherInterfaceBase.cpp
+++ b/Src/DasherCore/DasherInterfaceBase.cpp
@@ -93,6 +93,7 @@ CDasherInterfaceBase::CDasherInterfaceBase(CSettingsStore *pSettingsStore, CFile
   m_pInputFilter = NULL;
   m_AlphIO = NULL;
   m_ColourIO = NULL;
+  m_ControlBoxIO = NULL;
   m_pUserLog = NULL;
   m_pNCManager = NULL;
   m_defaultPolicy = NULL;
@@ -124,6 +125,9 @@ void CDasherInterfaceBase::Realize(unsigned long ulTime) {
   m_ColourIO = new CColourIO(this);
   ScanFiles(m_ColourIO, "colour*.xml");
 
+  m_ControlBoxIO = new CControlBoxIO(this);
+  ScanFiles(m_ControlBoxIO, "control*.xml");
+
   ChangeColours();
 
   ChangeView();
@@ -170,6 +174,7 @@ CDasherInterfaceBase::~CDasherInterfaceBase() {
   //WriteTrainFileFull();???
   delete m_pDasherModel;        // The order of some of these deletions matters
   delete m_pDasherView;
+  delete m_ControlBoxIO;
   delete m_ColourIO;
   delete m_AlphIO;
   delete m_pNCManager;
@@ -288,7 +293,7 @@ void CDasherInterfaceBase::EnterGameMode(CGameModule *pGameModule) {
   if (CWordGeneratorBase *pWords = m_pNCManager->GetAlphabetManager()->GetGameWords()) {
     if (!pGameModule) pGameModule=CreateGameModule();
     m_pGameModule=pGameModule;
-    m_pNCManager->updateControl();
+    //m_pNCManager->updateControl();
     m_pGameModule->SetWordGenerator(m_pNCManager->GetAlphabet(), pWords);
   } else {
     ///TRANSLATORS: %s is the name of the alphabet; the string "GameTextFile"
@@ -304,7 +309,7 @@ void CDasherInterfaceBase::LeaveGameMode() {
   CGameModule *pMod = m_pGameModule;
   m_pGameModule=NULL; //point at which we officially exit game mode
   delete pMod;
-  m_pNCManager->updateControl();
+  //m_pNCManager->updateControl();
   SetBuffer(0);
 }
 
@@ -380,7 +385,7 @@ void CDasherInterfaceBase::CreateNCManager() {
   CNodeCreationManager *pOldMgr = m_pNCManager;
 
   //now create the new manager...
-  m_pNCManager = new CNodeCreationManager(this, this, m_AlphIO);
+  m_pNCManager = new CNodeCreationManager(this, this, m_AlphIO, m_ControlBoxIO);
   if (GetBoolParameter(BP_PALETTE_CHANGE))
     SetStringParameter(SP_COLOUR_ID, m_pNCManager->GetAlphabet()->GetPalette());
 
@@ -793,6 +798,10 @@ void CDasherInterfaceBase::GetPermittedValues(int iParameter, std::vector<std::s
     DASHER_ASSERT(m_ColourIO != NULL);
     m_ColourIO->GetColours(&vList);
     break;
+  case SP_CONTROL_BOX_ID:
+    DASHER_ASSERT(m_ControlBoxIO != NULL);
+    m_ControlBoxIO->GetControlBoxes(&vList);
+    break;
   case SP_INPUT_FILTER:
     m_oModuleManager.ListModules(1, vList);
     break;
diff --git a/Src/DasherCore/DasherInterfaceBase.h b/Src/DasherCore/DasherInterfaceBase.h
index da9b438..4f90441 100644
--- a/Src/DasherCore/DasherInterfaceBase.h
+++ b/Src/DasherCore/DasherInterfaceBase.h
@@ -559,6 +559,7 @@ protected:
   CModuleManager m_oModuleManager;
   CAlphIO *m_AlphIO;
   CColourIO *m_ColourIO;
+  CControlBoxIO *m_ControlBoxIO;
   CNodeCreationManager *m_pNCManager;
   CUserLogBase *m_pUserLog;
 
diff --git a/Src/DasherCore/NodeCreationManager.cpp b/Src/DasherCore/NodeCreationManager.cpp
index 42b5899..9a86739 100644
--- a/Src/DasherCore/NodeCreationManager.cpp
+++ b/Src/DasherCore/NodeCreationManager.cpp
@@ -46,9 +46,12 @@ private:
   string m_strDisplay;
 };
 
-CNodeCreationManager::CNodeCreationManager(CSettingsUser *pCreateFrom,
-                                           Dasher::CDasherInterfaceBase *pInterface,
-                                           const Dasher::CAlphIO *pAlphIO) : 
CSettingsUserObserver(pCreateFrom),
+CNodeCreationManager::CNodeCreationManager(
+  CSettingsUser *pCreateFrom,
+  Dasher::CDasherInterfaceBase *pInterface,
+  const Dasher::CAlphIO *pAlphIO,
+  const Dasher::CControlBoxIO *pControlBoxIO
+  ) : CSettingsUserObserver(pCreateFrom),
   m_pInterface(pInterface), m_pControlManager(NULL), m_pScreen(NULL) {
 
   const Dasher::CAlphInfo *pAlphInfo(pAlphIO->GetInfo(GetStringParameter(SP_ALPHABET_ID)));
@@ -109,7 +112,7 @@ CNodeCreationManager::CNodeCreationManager(CSettingsUser *pCreateFrom,
 #endif
 
   HandleEvent(LP_ORIENTATION);
-  updateControl();
+  CreateControlBox(pControlBoxIO);
 }
 
 CNodeCreationManager::~CNodeCreationManager() {
@@ -126,12 +129,13 @@ void CNodeCreationManager::ChangeScreen(CDasherScreen *pScreen) {
   if (m_pControlManager) m_pControlManager->ChangeScreen(pScreen);
 }
 
-void CNodeCreationManager::updateControl() {
+void CNodeCreationManager::CreateControlBox(const CControlBoxIO* pControlIO) {
   delete m_pControlManager;
   unsigned long iControlSpace;
   //don't allow a control manager during Game Mode 
   if (GetBoolParameter(BP_CONTROL_MODE) && !m_pInterface->GetGameModule()) {
-    m_pControlManager = new CControlManager(this, this, m_pInterface);
+    auto id = GetStringParameter(SP_CONTROL_BOX_ID);
+    m_pControlManager = pControlIO->CreateControlManager(id, this, this, m_pInterface);
     if (m_pScreen) m_pControlManager->ChangeScreen(m_pScreen);
     iControlSpace = CDasherModel::NORMALIZATION / 20;
   } else {
diff --git a/Src/DasherCore/NodeCreationManager.h b/Src/DasherCore/NodeCreationManager.h
index 5973c74..26d8878 100644
--- a/Src/DasherCore/NodeCreationManager.h
+++ b/Src/DasherCore/NodeCreationManager.h
@@ -19,6 +19,7 @@ namespace Dasher {
   class CDasherInterfaceBase;
   class CControlManager;
   class CDasherScreen;
+  class CControlBoxIO;
 }
 //TODO why is CNodeCreationManager _not_ in namespace Dasher?!?!
 /// \ingroup Model
@@ -27,15 +28,16 @@ class CNodeCreationManager : public Dasher::CSettingsUserObserver {
  public:
   CNodeCreationManager(Dasher::CSettingsUser *pCreateFrom,
                        Dasher::CDasherInterfaceBase *pInterface,
-                       const Dasher::CAlphIO *pAlphIO);
+                       const Dasher::CAlphIO *pAlphIO,
+                       const Dasher::CControlBoxIO *pControlBoxIO);
   ~CNodeCreationManager();
   
   ///Tells us the screen on which all created node labels must be rendered
   void ChangeScreen(Dasher::CDasherScreen *pScreen);
   
-  ///Create/destroy Control Manager, as appropriate (according to
+  ///Create/ or not Control Manager, as appropriate (according to
   /// BP_CONTROL_MODE and game mode status)
-  void updateControl();
+  void CreateControlBox(const Dasher::CControlBoxIO* pControlIO);
 
   void HandleEvent(int iParameter) {}
   ///


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]