[dasher] Remove SDisplayInfo substruct of CDasherNode; hide m_iOffset & set in c'tor



commit 6db5cf3e61d31f88077602f9189f1e2023ef18c8
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Tue May 4 19:52:45 2010 +0100

    Remove SDisplayInfo substruct of CDasherNode; hide m_iOffset & set in c'tor
    
    Replacing with boolean bShove() & fields for display text + colour (-1=invis)

 Src/DasherCore/AlphabetManager.cpp   |   87 ++++++++++++----------------------
 Src/DasherCore/AlphabetManager.h     |   16 ++++--
 Src/DasherCore/ControlManager.cpp    |   53 +++++----------------
 Src/DasherCore/ControlManager.h      |    6 ++-
 Src/DasherCore/ConversionHelper.cpp  |   20 ++-----
 Src/DasherCore/ConversionHelper.h    |    4 +-
 Src/DasherCore/ConversionManager.cpp |   19 +++-----
 Src/DasherCore/ConversionManager.h   |    4 +-
 Src/DasherCore/DasherModel.cpp       |    2 +-
 Src/DasherCore/DasherModel.h         |    2 +-
 Src/DasherCore/DasherNode.cpp        |   20 +++-----
 Src/DasherCore/DasherNode.h          |   36 +++++++-------
 Src/DasherCore/DasherViewSquare.cpp  |   24 +++++-----
 Src/DasherCore/MandarinAlphMgr.cpp   |   56 ++++++++++------------
 Src/DasherCore/MandarinAlphMgr.h     |   11 +++--
 15 files changed, 146 insertions(+), 214 deletions(-)
---
diff --git a/Src/DasherCore/AlphabetManager.cpp b/Src/DasherCore/AlphabetManager.cpp
index b11f1e6..a39c35d 100644
--- a/Src/DasherCore/AlphabetManager.cpp
+++ b/Src/DasherCore/AlphabetManager.cpp
@@ -53,24 +53,31 @@ CAlphabetManager::CAlphabetManager(CDasherInterfaceBase *pInterface, CNodeCreati
 
 }
 
-CAlphabetManager::CAlphNode::CAlphNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDisplayInfo, CAlphabetManager *pMgr)
-: CDasherNode(pParent, iLbnd, iHbnd, pDisplayInfo), m_pProbInfo(NULL), m_pMgr(pMgr) {
+CAlphabetManager::CAlphNode::CAlphNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const string &strDisplayText, CAlphabetManager *pMgr)
+: CDasherNode(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText), m_pProbInfo(NULL), m_pMgr(pMgr) {
 };
 
-CAlphabetManager::CSymbolNode::CSymbolNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDisplayInfo, CAlphabetManager *pMgr, symbol _iSymbol)
-: CAlphNode(pParent, iLbnd, iHbnd, pDisplayInfo, pMgr), iSymbol(_iSymbol) {
+CAlphabetManager::CSymbolNode::CSymbolNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CAlphabetManager *pMgr, symbol _iSymbol)
+: CAlphNode(pParent, iOffset, iLbnd, iHbnd, pMgr->m_pNCManager->GetAlphabet()->GetColour(_iSymbol, iOffset%2), pMgr->m_pNCManager->GetAlphabet()->GetDisplayText(_iSymbol), pMgr), iSymbol(_iSymbol) {
 };
 
-CAlphabetManager::CGroupNode::CGroupNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDisplayInfo, CAlphabetManager *pMgr, SGroupInfo *pGroup)
-: CAlphNode(pParent, iLbnd, iHbnd, pDisplayInfo, pMgr), m_pGroup(pGroup) {
+CAlphabetManager::CSymbolNode::CSymbolNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const string &strDisplayText, CAlphabetManager *pMgr, symbol _iSymbol)
+: CAlphNode(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText, pMgr), iSymbol(_iSymbol) {
 };
 
-CAlphabetManager::CSymbolNode *CAlphabetManager::makeSymbol(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDisplayInfo, symbol iSymbol) {
-  return new CSymbolNode(pParent, iLbnd, iHbnd, pDisplayInfo, this, iSymbol);
+CAlphabetManager::CGroupNode::CGroupNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CAlphabetManager *pMgr, SGroupInfo *pGroup)
+: CAlphNode(pParent, iOffset, iLbnd, iHbnd,
+            pGroup ? (pGroup->bVisible ? pGroup->iColour : pParent->getColour())
+                   : pMgr->m_pNCManager->GetAlphabet()->GetColour(0, iOffset%2),
+            pGroup ? pGroup->strLabel : "", pMgr), m_pGroup(pGroup) {
+};
+
+CAlphabetManager::CSymbolNode *CAlphabetManager::makeSymbol(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, symbol iSymbol) {
+  return new CSymbolNode(pParent, iOffset, iLbnd, iHbnd, this, iSymbol);
 }
 
-CAlphabetManager::CGroupNode *CAlphabetManager::makeGroup(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDisplayInfo, SGroupInfo *pGroup) {
-  return new CGroupNode(pParent, iLbnd, iHbnd, pDisplayInfo, this, pGroup);
+CAlphabetManager::CGroupNode *CAlphabetManager::makeGroup(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, SGroupInfo *pGroup) {
+  return new CGroupNode(pParent, iOffset, iLbnd, iHbnd, this, pGroup);
 }
 
 CAlphabetManager::CAlphNode *CAlphabetManager::GetRoot(CDasherNode *pParent, unsigned int iLower, unsigned int iUpper, bool bEnteredLast, int iOffset) {
@@ -89,10 +96,6 @@ CAlphabetManager::CAlphNode *CAlphabetManager::GetRoot(CDasherNode *pParent, uns
       : m_pInterface->GetContext(iStart, iNewOffset+1 - iStart);
     m_pNCManager->GetAlphabet()->GetSymbols(vContextSymbols, strContext);
   }
-
-  CDasherNode::SDisplayInfo *pDisplayInfo = new CDasherNode::SDisplayInfo;
-  pDisplayInfo->bShove = true;
-  pDisplayInfo->bVisible = true;  
   
   CAlphNode *pNewNode;
   CLanguageModel::Context iContext = m_pLanguageModel->CreateEmptyContext();
@@ -121,14 +124,10 @@ CAlphabetManager::CAlphNode *CAlphabetManager::GetRoot(CDasherNode *pParent, uns
   }
   
   if(!bEnteredLast) {
-    pDisplayInfo->strDisplayText = ""; //equivalent to do m_pNCManager->GetAlphabet()->GetDisplayText(0)
-    pDisplayInfo->iColour = m_pNCManager->GetAlphabet()->GetColour(0, iNewOffset%2);
-    pNewNode = makeGroup(pParent, iLower, iUpper, pDisplayInfo, NULL);
+    pNewNode = makeGroup(pParent, iNewOffset, iLower, iUpper,  NULL);
   } else {
     const symbol iSymbol(vContextSymbols[vContextSymbols.size() - 1]);
-    pDisplayInfo->strDisplayText = m_pNCManager->GetAlphabet()->GetDisplayText(iSymbol);
-    pDisplayInfo->iColour = m_pNCManager->GetAlphabet()->GetColour(iSymbol, iNewOffset%2);
-    pNewNode = makeSymbol(pParent, iLower, iUpper, pDisplayInfo, iSymbol);
+    pNewNode = makeSymbol(pParent, iNewOffset, iLower, iUpper, iSymbol);
     //if the new node is not child of an existing node, then it
     // represents a symbol that's already happened - so we're either
     // going backwards (rebuildParent) or creating a new root after a language change
@@ -136,8 +135,6 @@ CAlphabetManager::CAlphNode *CAlphabetManager::GetRoot(CDasherNode *pParent, uns
     pNewNode->SetFlag(NF_SEEN, true);
   }
 
-  pNewNode->m_iOffset = iNewOffset;
-
   pNewNode->iContext = iContext;
   return pNewNode;
 }
@@ -196,7 +193,7 @@ std::vector<unsigned int> *CAlphabetManager::CAlphNode::GetProbInfo() {
 
 std::vector<unsigned int> *CAlphabetManager::CGroupNode::GetProbInfo() {
   if (m_pGroup && Parent() && Parent()->mgr() == mgr()) {
-    DASHER_ASSERT(Parent()->m_iOffset == m_iOffset);
+    DASHER_ASSERT(Parent()->offset() == offset());
     return (static_cast<CAlphNode *>(Parent()))->GetProbInfo();
   }
   //nope, no usable parent. compute here...
@@ -212,17 +209,12 @@ int CAlphabetManager::CGroupNode::ExpectedNumChildren() {
 }
 
 CAlphabetManager::CGroupNode *CAlphabetManager::CreateGroupNode(CAlphNode *pParent, SGroupInfo *pInfo, unsigned int iLbnd, unsigned int iHbnd) {
-  // TODO: More sensible structure in group data to map directly to this
-  CDasherNode::SDisplayInfo *pDisplayInfo = new CDasherNode::SDisplayInfo;
-  pDisplayInfo->iColour = (pInfo->bVisible ? pInfo->iColour : pParent->GetDisplayInfo()->iColour);
-  pDisplayInfo->bShove = true;
-  pDisplayInfo->bVisible = pInfo->bVisible;
-  pDisplayInfo->strDisplayText = pInfo->strLabel;
-
-  CGroupNode *pNewNode = makeGroup(pParent, iLbnd, iHbnd, pDisplayInfo, pInfo);
 
   // When creating a group node...
-  pNewNode->m_iOffset = pParent->m_iOffset; // ...the offset is the same as the parent...
+  // ...the offset is the same as the parent...
+  CGroupNode *pNewNode = makeGroup(pParent, pParent->offset(), iLbnd, iHbnd, pInfo);
+
+  //...as is the context!
   pNewNode->iContext = m_pLanguageModel->CloneContext(pParent->iContext);
 
   return pNewNode;
@@ -233,7 +225,7 @@ CAlphabetManager::CGroupNode *CAlphabetManager::CGroupNode::RebuildGroup(CAlphNo
     SetRange(iLbnd, iHbnd);
     SetParent(pParent);
     //offset doesn't increase for groups...
-    DASHER_ASSERT (m_iOffset == pParent->m_iOffset);
+    DASHER_ASSERT (offset() == pParent->offset());
     return this;
   }
   CGroupNode *pRet=m_pMgr->CreateGroupNode(pParent, pInfo, iLbnd, iHbnd);
@@ -270,7 +262,7 @@ CDasherNode *CAlphabetManager::CreateSymbolNode(CAlphNode *pParent, symbol iSymb
   // TODO: Need to fix fact that this is created even when control mode is switched off
   if(iSymbol == m_pNCManager->GetAlphabet()->GetControlSymbol()) {
       //ACL setting offset as one more than parent for consistency with "proper" symbol nodes...
-      pNewNode = m_pNCManager->GetCtrlRoot(pParent, iLbnd, iHbnd, pParent->m_iOffset+1); 
+      pNewNode = m_pNCManager->GetCtrlRoot(pParent, iLbnd, iHbnd, pParent->offset()+1); 
 
 #ifdef _WIN32_WCE
       //no control manager - but (TODO!) we still try to create (0-size!) control node...
@@ -285,22 +277,13 @@ CDasherNode *CAlphabetManager::CreateSymbolNode(CAlphNode *pParent, symbol iSymb
       //  else if(iSymbol == m_pNCManager->GetSpaceSymbol()) {
 
       //ACL setting m_iOffset+1 for consistency with "proper" symbol nodes...
-      pNewNode = m_pNCManager->GetConvRoot(pParent, iLbnd, iHbnd, pParent->m_iOffset+1);
+      pNewNode = m_pNCManager->GetConvRoot(pParent, iLbnd, iHbnd, pParent->offset()+1);
     }
     else {
-      //compute phase directly from offset
-      int iColour = m_pNCManager->GetAlphabet()->GetColour(iSymbol, (pParent->m_iOffset+1)%2);
-
       // TODO: Exceptions / error handling in general
 
-      CDasherNode::SDisplayInfo *pDisplayInfo = new CDasherNode::SDisplayInfo;
-      pDisplayInfo->iColour = iColour;
-      pDisplayInfo->bShove = true;
-      pDisplayInfo->bVisible = true;
-      pDisplayInfo->strDisplayText = m_pNCManager->GetAlphabet()->GetDisplayText(iSymbol);
-
       CAlphNode *pAlphNode;
-      pNewNode = pAlphNode = makeSymbol(pParent, iLbnd, iHbnd, pDisplayInfo,iSymbol);
+      pNewNode = pAlphNode = makeSymbol(pParent, pParent->offset()+1, iLbnd, iHbnd, iSymbol);
 
       //     std::stringstream ssLabel;
 
@@ -308,8 +291,6 @@ CDasherNode *CAlphabetManager::CreateSymbolNode(CAlphNode *pParent, symbol iSymb
 
       //    pDisplayInfo->strDisplayText = ssLabel.str();
 
-      pNewNode->m_iOffset = pParent->m_iOffset + 1;
-
       pAlphNode->iContext = CreateSymbolContext(pParent, iSymbol);
   }
 
@@ -320,7 +301,7 @@ CDasherNode *CAlphabetManager::CSymbolNode::RebuildSymbol(CAlphNode *pParent, sy
   if(iSymbol == this->iSymbol) {
     SetRange(iLbnd, iHbnd);
     SetParent(pParent);
-    DASHER_ASSERT(m_iOffset == pParent->m_iOffset + 1);
+    DASHER_ASSERT(offset() == pParent->offset() + 1);
     return this;
   }
   return m_pMgr->CreateSymbolNode(pParent, iSymbol, iLbnd, iHbnd);
@@ -391,14 +372,8 @@ void CAlphabetManager::IterateChildGroups(CAlphNode *pParent, SGroupInfo *pParen
     //created a new node - symbol or (group which will have >1 child).
     DASHER_ASSERT(pParent->GetChildren().back()==pNewChild);
     //now adjust the node we've actually created, to take account of any elided group(s)...
-    // ick: cast away const-ness...TODO!
-    CDasherNode::SDisplayInfo *pChildInfo = (CDasherNode::SDisplayInfo *)pNewChild->GetDisplayInfo();
-    if (iOverrideColour!=-1 && !pChildInfo->bVisible) {
-      pChildInfo->bVisible = true;
-      pChildInfo->iColour = iOverrideColour;
-    }
-    //if we've reused the existing node, make sure we don't adjust the display text twice...
-    if (pNewChild != buildAround) pChildInfo->strDisplayText = groupPrefix + pChildInfo->strDisplayText;    
+    // tho not if we've reused the existing node, assume that's been adjusted already
+    if (pNewChild && pNewChild!=buildAround) pNewChild->PrependElidedGroup(iOverrideColour, groupPrefix);
   }
 
   pParent->SetFlag(NF_ALLCHILDREN, true);
diff --git a/Src/DasherCore/AlphabetManager.h b/Src/DasherCore/AlphabetManager.h
index dc65355..6b98c6b 100644
--- a/Src/DasherCore/AlphabetManager.h
+++ b/Src/DasherCore/AlphabetManager.h
@@ -51,7 +51,7 @@ namespace Dasher {
     class CAlphNode : public CDasherNode {
     public:
       virtual CAlphabetManager *mgr() {return m_pMgr;}
-      CAlphNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, CAlphabetManager *pMgr);
+      CAlphNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const std::string &strDisplayText, CAlphabetManager *pMgr);
       CLanguageModel::Context iContext;
       ///
       /// Delete any storage alocated for this node
@@ -71,8 +71,9 @@ namespace Dasher {
     };
     class CSymbolNode : public CAlphNode {
     public:
-      CSymbolNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, CAlphabetManager *pMgr, symbol iSymbol);
-      
+      ///Standard constructor, gets colour+label by looking up symbol in current alphabet (& computing phase from offset)
+      CSymbolNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CAlphabetManager *pMgr, symbol iSymbol);
+
       ///
       /// Provide children for the supplied node
       ///
@@ -92,11 +93,14 @@ namespace Dasher {
       virtual CGroupNode *RebuildGroup(CAlphNode *pParent, SGroupInfo *pInfo, unsigned int iLbnd, unsigned int iHbnd);
     private:
       virtual const std::string &outputText();
+    protected:
+      ///Compatibility constructor, so that subclasses can specify their own colour & label
+      CSymbolNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const std::string &strDisplayText, CAlphabetManager *pMgr, symbol _iSymbol);
     };
 
     class CGroupNode : public CAlphNode {
     public:
-      CGroupNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, CAlphabetManager *pMgr, SGroupInfo *pGroup);
+      CGroupNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CAlphabetManager *pMgr, SGroupInfo *pGroup);
       
       ///
       /// Provide children for the supplied node
@@ -124,8 +128,8 @@ namespace Dasher {
     ///
     /// Factory method for CAlphNode construction, so subclasses can override.
     ///
-    virtual CSymbolNode *makeSymbol(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, symbol iSymbol);
-    virtual CGroupNode *makeGroup(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, SGroupInfo *pGroup);
+    virtual CSymbolNode *makeSymbol(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, symbol iSymbol);
+    virtual CGroupNode *makeGroup(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, SGroupInfo *pGroup);
     
     virtual CDasherNode *CreateSymbolNode(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd);
     virtual CLanguageModel::Context CreateSymbolContext(CAlphNode *pParent, symbol iSymbol);
diff --git a/Src/DasherCore/ControlManager.cpp b/Src/DasherCore/ControlManager.cpp
index ee64dbc..5589384 100644
--- a/Src/DasherCore/ControlManager.cpp
+++ b/Src/DasherCore/ControlManager.cpp
@@ -269,27 +269,17 @@ void CControlManager::DisconnectNode(int iChild, int iParent) {
 
 CDasherNode *CControlManager::GetRoot(CDasherNode *pParent, unsigned int iLower, unsigned int iUpper, int iOffset) {
 
-  // TODO: Tie this structure to info contained in control map
-  CDasherNode::SDisplayInfo *pDisplayInfo = new CDasherNode::SDisplayInfo;
-  pDisplayInfo->iColour = m_mapControlMap[0]->iColour;
-  pDisplayInfo->bShove = false;
-  pDisplayInfo->bVisible = true;
-  pDisplayInfo->strDisplayText = m_mapControlMap[0]->strLabel;
-  
-  CContNode *pNewNode = new CContNode(pParent, iLower, iUpper, pDisplayInfo, this);
+  CContNode *pNewNode = new CContNode(pParent, iOffset, iLower, iUpper, m_mapControlMap[0], this);
  
   // FIXME - handle context properly
 
   //  pNewNode->SetContext(m_pLanguageModel->CreateEmptyContext());
 
-  pNewNode->pControlItem = m_mapControlMap[0];
-  pNewNode->m_iOffset = iOffset;
-
   return pNewNode;
 }
 
-CControlManager::CContNode::CContNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDisplayInfo, CControlManager *pMgr)
-: CDasherNode(pParent, iLbnd, iHbnd, pDisplayInfo), m_pMgr(pMgr) {
+CControlManager::CContNode::CContNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const SControlItem *pControlItem, CControlManager *pMgr)
+: CDasherNode(pParent, iOffset, iLbnd, iHbnd, (pControlItem->iColour != -1) ? pControlItem->iColour : (pParent->ChildCount()%99)+11, pControlItem->strLabel), m_pControlItem(pControlItem), m_pMgr(pMgr) {
 }
 
 
@@ -297,16 +287,13 @@ void CControlManager::CContNode::PopulateChildren() {
   
   CDasherNode *pNewNode;
 
-   int iNChildren( pControlItem->vChildren.size() );
-
-   int iIdx(0);
-
-   for(std::vector<SControlItem *>::iterator it(pControlItem->vChildren.begin()); it != pControlItem->vChildren.end(); ++it) {
+   const unsigned int iNChildren( m_pControlItem->vChildren.size() );
+   const unsigned int iNorm(m_pMgr->m_pNCManager->GetLongParameter(LP_NORMALIZATION));
+   unsigned int iLbnd(0), iIdx(0);
 
-     // FIXME - could do this better
+   for(std::vector<SControlItem *>::const_iterator it(m_pControlItem->vChildren.begin()); it != m_pControlItem->vChildren.end(); ++it) {
 
-     unsigned int iLbnd( iIdx*(m_pMgr->m_pNCManager->GetLongParameter(LP_NORMALIZATION)/iNChildren)); 
-     unsigned int iHbnd( (iIdx+1)*(m_pMgr->m_pNCManager->GetLongParameter(LP_NORMALIZATION)/iNChildren)); 
+     const unsigned int iHbnd((++iIdx*iNorm)/iNChildren); 
 
      if( *it == NULL ) {
        // Escape back to alphabet
@@ -315,35 +302,19 @@ void CControlManager::CContNode::PopulateChildren() {
      }
      else {
 
-       int iColour((*it)->iColour);
-
-       if( iColour == -1 ) {
-	 iColour = (iIdx%99)+11;
-       }
-
-       CDasherNode::SDisplayInfo *pDisplayInfo = new CDasherNode::SDisplayInfo;
-       pDisplayInfo->iColour = iColour;
-       pDisplayInfo->bShove = false;
-       pDisplayInfo->bVisible = true;
-       pDisplayInfo->strDisplayText = (*it)->strLabel;
-       
-       CContNode *pContNode;
-       pNewNode = pContNode = new CContNode(this, iLbnd, iHbnd, pDisplayInfo, m_pMgr);
-
-       pContNode->pControlItem = *it;
+       pNewNode = new CContNode(this, m_iOffset, iLbnd, iHbnd, *it, m_pMgr);
 
-       pNewNode->m_iOffset = m_iOffset;
      }
+     iLbnd=iHbnd;
      DASHER_ASSERT(GetChildren().back()==pNewNode);
-     ++iIdx;
    }
 }
 int CControlManager::CContNode::ExpectedNumChildren() {
-  return pControlItem->vChildren.size();
+  return m_pControlItem->vChildren.size();
 }
 void CControlManager::CContNode::Output(Dasher::VECTOR_SYMBOL_PROB* pAdded, int iNormalization ) {
 
-  CControlEvent oEvent(pControlItem->iID);
+  CControlEvent oEvent(m_pControlItem->iID);
   // TODO: Need to reimplement this
   //  m_pNCManager->m_bContextSensitive=false;
   m_pMgr->m_pNCManager->InsertEvent(&oEvent);
diff --git a/Src/DasherCore/ControlManager.h b/Src/DasherCore/ControlManager.h
index dc01666..9593e0e 100644
--- a/Src/DasherCore/ControlManager.h
+++ b/Src/DasherCore/ControlManager.h
@@ -90,7 +90,9 @@ namespace Dasher {
     class CContNode : public CDasherNode {
     public:
       CControlManager *mgr() {return m_pMgr;}
-      CContNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDisplayInfo, CControlManager *pMgr);
+      CContNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const SControlItem *pControlItem, CControlManager *pMgr);
+      
+      bool bShove() {return false;}
     ///
     /// Provide children for the supplied node
     ///
@@ -104,7 +106,7 @@ namespace Dasher {
     virtual void Leave();
 
     void SetControlOffset(int iOffset);
-      SControlItem *pControlItem;
+      const SControlItem *m_pControlItem;
     private:
       CControlManager *m_pMgr;
     };
diff --git a/Src/DasherCore/ConversionHelper.cpp b/Src/DasherCore/ConversionHelper.cpp
index 7ec9f2e..2dc38ea 100644
--- a/Src/DasherCore/ConversionHelper.cpp
+++ b/Src/DasherCore/ConversionHelper.cpp
@@ -38,6 +38,7 @@
 //Need to reconcile (a small project)
 
 using namespace Dasher;
+using namespace std;
 
 CConversionHelper::CConversionHelper(CNodeCreationManager *pNCManager, CAlphabet *pAlphabet, CLanguageModel *pLanguageModel) :
   CConversionManager(pNCManager, pAlphabet), m_pLanguageModel(pLanguageModel) {
@@ -118,17 +119,9 @@ void CConversionHelper::CConvHNode::PopulateChildren() {
       // TODO: Parameters here are placeholders - need to figure out
       // what's right
 
-
-      CDasherNode::SDisplayInfo *pDisplayInfo = new CDasherNode::SDisplayInfo;
-      pDisplayInfo->iColour = mgr()->AssignColour(parentClr, pCurrentSCEChild, iIdx);
-      pDisplayInfo->bShove = true;
-      pDisplayInfo->bVisible = true;
-
       //  std::cout << "#" << pCurrentSCEChild->pszConversion << "#" << std::endl;
 
-      pDisplayInfo->strDisplayText = pCurrentSCEChild->pszConversion;
-
-      CConvNode *pNewNode = mgr()->makeNode(this, iLbnd, iHbnd, pDisplayInfo);
+      CConvNode *pNewNode = mgr()->makeNode(this, m_iOffset+1, iLbnd, iHbnd, mgr()->AssignColour(parentClr, pCurrentSCEChild, iIdx), string(pCurrentSCEChild->pszConversion));
 
       // TODO: Reimplement ----
 
@@ -139,7 +132,6 @@ void CConversionHelper::CConvHNode::PopulateChildren() {
       pNewNode->bisRoot = false;
       pNewNode->pSCENode = pCurrentSCEChild;
       pNewNode->pLanguageModel = pLanguageModel;
-      pNewNode->m_iOffset = m_iOffset + 1;
 
       if(pLanguageModel) {
         CLanguageModel::Context iContext;
@@ -198,13 +190,13 @@ void CConversionHelper::BuildTree(CConvHNode *pRoot) {
   pRoot->pSCENode = pStartTemp;
 }
 
-CConversionHelper::CConvHNode::CConvHNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, CConversionHelper *pMgr)
-: CConvNode(pParent, iLbnd, iHbnd, pDispInfo, pMgr) {
+CConversionHelper::CConvHNode::CConvHNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const string &strDisplayText, CConversionHelper *pMgr)
+: CConvNode(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText, pMgr) {
 }
 
 
-CConversionHelper::CConvHNode *CConversionHelper::makeNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo) {
-  return new CConvHNode(pParent, iLbnd, iHbnd, pDispInfo, this);
+CConversionHelper::CConvHNode *CConversionHelper::makeNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const string &strDisplayText) {
+  return new CConvHNode(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText, this);
 }
 
 void CConversionHelper::CConvHNode::SetFlag(int iFlag, bool bValue) {
diff --git a/Src/DasherCore/ConversionHelper.h b/Src/DasherCore/ConversionHelper.h
index ec7efc5..76080b8 100644
--- a/Src/DasherCore/ConversionHelper.h
+++ b/Src/DasherCore/ConversionHelper.h
@@ -113,7 +113,7 @@ namespace Dasher{
 	protected:
     class CConvHNode : public CConvNode {
     public:
-      CConvHNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, CConversionHelper *pMgr);
+      CConvHNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const std::string &strDisplayText, CConversionHelper *pMgr);
       ///
       /// Provide children for the supplied node
       ///
@@ -123,7 +123,7 @@ namespace Dasher{
     protected:
       inline CConversionHelper *mgr() {return static_cast<CConversionHelper *>(m_pMgr);}
     };
-	  virtual CConvHNode *makeNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo);
+	  virtual CConvHNode *makeNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const std::string &strDisplayText);
     /// 
     /// Build the conversion tree (lattice) for the given string -
     /// evaluated late to prevent unnecessary conversions when the
diff --git a/Src/DasherCore/ConversionManager.cpp b/Src/DasherCore/ConversionManager.cpp
index 183a5ec..66729fc 100644
--- a/Src/DasherCore/ConversionManager.cpp
+++ b/Src/DasherCore/ConversionManager.cpp
@@ -38,6 +38,7 @@
 //Need to reconcile (a small project)
 
 using namespace Dasher;
+using namespace std;
 
 CConversionManager::CConversionManager(CNodeCreationManager *pNCManager, CAlphabet *pAlphabet) {
 
@@ -55,21 +56,16 @@ CConversionManager::CConversionManager(CNodeCreationManager *pNCManager, CAlphab
   */
 }
 
-CConversionManager::CConvNode *CConversionManager::makeNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo) {
-  return new CConvNode(pParent, iLbnd, iHbnd, pDispInfo, this);
+CConversionManager::CConvNode *CConversionManager::makeNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const string &strDisplayText) {
+  return new CConvNode(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText, this);
 }
 
 CConversionManager::CConvNode *CConversionManager::GetRoot(CDasherNode *pParent, unsigned int iLower, unsigned int iUpper, int iOffset) {
 
   // TODO: Parameters here are placeholders - need to figure out what's right
 
-  CDasherNode::SDisplayInfo *pDisplayInfo = new CDasherNode::SDisplayInfo;
-  pDisplayInfo->iColour = 9; // TODO: Hard coded value
-  pDisplayInfo->bShove = true;
-  pDisplayInfo->bVisible = true;
-  pDisplayInfo->strDisplayText = ""; // TODO: Hard coded value, needs i18n
-
-  CConvNode *pNewNode = makeNode(pParent, iLower, iUpper, pDisplayInfo);
+  //TODO: hard-coded colour, and hard-coded displaytext... (ACL: read from Alphabet -> startConversionSymbol ?)
+  CConvNode *pNewNode = makeNode(pParent, iOffset, iLower, iUpper, 9, "");
 
   // FIXME - handle context properly
   // TODO: Reimplemnt -----
@@ -78,7 +74,6 @@ CConversionManager::CConvNode *CConversionManager::GetRoot(CDasherNode *pParent,
 
 
   pNewNode->bisRoot = true;
-  pNewNode->m_iOffset = iOffset;
 
   pNewNode->pLanguageModel = NULL;
 
@@ -87,8 +82,8 @@ CConversionManager::CConvNode *CConversionManager::GetRoot(CDasherNode *pParent,
   return pNewNode;
 }
 
-CConversionManager::CConvNode::CConvNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, CConversionManager *pMgr)
- : CDasherNode(pParent, iLbnd, iHbnd, pDispInfo), m_pMgr(pMgr) {
+CConversionManager::CConvNode::CConvNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const string &strDisplayText, CConversionManager *pMgr)
+ : CDasherNode(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText), m_pMgr(pMgr) {
   pMgr->m_iRefCount++;
 }
 
diff --git a/Src/DasherCore/ConversionManager.h b/Src/DasherCore/ConversionManager.h
index 146304b..ff2c1ed 100644
--- a/Src/DasherCore/ConversionManager.h
+++ b/Src/DasherCore/ConversionManager.h
@@ -82,7 +82,7 @@ namespace Dasher {
     class CConvNode : public CDasherNode {
     public:
       CConversionManager *mgr() {return m_pMgr;}
-      CConvNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, CConversionManager *pMgr);
+      CConvNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const std::string &strDisplayText, CConversionManager *pMgr);
     ///
     /// Provide children for the supplied node
     ///
@@ -130,7 +130,7 @@ namespace Dasher {
     virtual CConvNode *GetRoot(CDasherNode *pParent, unsigned int iLower, unsigned int iUpper, int iOffset);
   protected:    
     
-  virtual CConvNode *makeNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo);
+    virtual CConvNode *makeNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const std::string &strDisplayText);
 
 	  
 	CNodeCreationManager *m_pNCManager;
diff --git a/Src/DasherCore/DasherModel.cpp b/Src/DasherCore/DasherModel.cpp
index 5430cb8..536ea35 100644
--- a/Src/DasherCore/DasherModel.cpp
+++ b/Src/DasherCore/DasherModel.cpp
@@ -595,7 +595,7 @@ void CDasherModel::ExpandNode(CDasherNode *pNode) {
   GameMode::CDasherGameMode* pTeacher = GameMode::CDasherGameMode::GetTeacher();
   if(m_bGameMode && pNode->GetFlag(NF_GAME) && pTeacher )
   {
-    std::string strTargetUtf8Char(pTeacher->GetSymbolAtOffset(pNode->m_iOffset + 1));
+    std::string strTargetUtf8Char(pTeacher->GetSymbolAtOffset(pNode->offset() + 1));
       
     // Check if this is the last node in the sentence...
     if(strTargetUtf8Char == "GameEnd")
diff --git a/Src/DasherCore/DasherModel.h b/Src/DasherCore/DasherModel.h
index b2fda97..82482f3 100644
--- a/Src/DasherCore/DasherModel.h
+++ b/Src/DasherCore/DasherModel.h
@@ -192,7 +192,7 @@ class Dasher::CDasherModel:public Dasher::CFrameRate, private NoClones
   ///
 
   int GetOffset() {
-    return m_pLastOutput->m_iOffset+1;
+    return m_pLastOutput->offset()+1;
   };
 
   /// Create the children of a Dasher node
diff --git a/Src/DasherCore/DasherNode.cpp b/Src/DasherCore/DasherNode.cpp
index ab5ed2f..0fb1ab6 100644
--- a/Src/DasherCore/DasherNode.cpp
+++ b/Src/DasherCore/DasherNode.cpp
@@ -42,20 +42,15 @@ static int iNumNodes = 0;
 int Dasher::currentNumNodeObjects() {return iNumNodes;}
 
 //TODO this used to be inline - should we make it so again?
-CDasherNode::CDasherNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, SDisplayInfo *pDisplayInfo) {
-  // TODO: Check that these are disabled for debug builds, and that we're not shipping such a build
+CDasherNode::CDasherNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const string &strDisplayText)
+: m_pParent(pParent), m_iOffset(iOffset), m_iLbnd(iLbnd), m_iHbnd(iHbnd), m_iColour(iColour), m_strDisplayText(strDisplayText) {
   DASHER_ASSERT(iHbnd >= iLbnd);
-  DASHER_ASSERT(pDisplayInfo != NULL);
 	
-  m_pParent = pParent;  
   if (pParent) {
     DASHER_ASSERT(!pParent->GetFlag(NF_ALLCHILDREN));
     pParent->Children().push_back(this);
   }
 
-  m_iLbnd = iLbnd;
-  m_iHbnd = iHbnd;
-  m_pDisplayInfo = pDisplayInfo;
   onlyChildRendered = NULL;
 	
   // Default flags (make a definition somewhere, pass flags to constructor?)
@@ -74,10 +69,14 @@ CDasherNode::~CDasherNode() {
 
   //  std::cout << "done." << std::endl;
 
-  delete m_pDisplayInfo;
   iNumNodes--;
 }
 
+void CDasherNode::PrependElidedGroup(int iGroupColour, string &strGroupLabel) {
+  if (m_iColour==-1) m_iColour = iGroupColour;
+  m_strDisplayText = strGroupLabel + m_strDisplayText;
+}
+
 
 void CDasherNode::Trace() const {
   /* TODO sort out
@@ -158,11 +157,6 @@ void CDasherNode::DeleteNephews(CDasherNode *pChild) {
 // TODO: Need to allow for subnodes
 // TODO: Incorporate into above routine
 void CDasherNode::Delete_children() {
-//    CAlphabetManager::SAlphabetData *pParentUserData(static_cast<CAlphabetManager::SAlphabetData *>(m_pUserData));
-
-//    if((GetDisplayInfo()->strDisplayText)[0] == 'e')
-//      std::cout << "ed: " << this << " " << pParentUserData->iContext << " " << pParentUserData->iOffset << std::endl;
-
 //  std::cout << "Start: " << this << std::endl;
 
   ChildMap::iterator i;
diff --git a/Src/DasherCore/DasherNode.h b/Src/DasherCore/DasherNode.h
index 8aebecb..720369b 100644
--- a/Src/DasherCore/DasherNode.h
+++ b/Src/DasherCore/DasherNode.h
@@ -62,12 +62,14 @@ class Dasher::CDasherNode:private NoClones {
  public:
 
   /// Display attributes of this node, used for rendering.
-  struct SDisplayInfo {
-    int iColour;
-    bool bShove;
-    bool bVisible;
-    std::string strDisplayText;
-  };
+  /// Colour: -1 for invisible
+  inline int getColour() {return m_iColour;}
+  inline std::string &getDisplayText() {return m_strDisplayText;}
+  ///Whether labels on child nodes should be displaced to the right of this node's label.
+  /// (Default implementation returns true, subclasses should override if appropriate)
+  virtual bool bShove() {return true;}
+  
+  inline int offset() {return m_iOffset;}
   CDasherNode *onlyChildRendered; //cache that only one child was rendered (as it filled the screen)
 
   /// Container type for storing children. Note that it's worth
@@ -81,17 +83,19 @@ class Dasher::CDasherNode:private NoClones {
   /// @param iHbnd Upper bound of node within parent
   /// @param pDisplayInfo Struct containing information on how to display the node
   ///
-  CDasherNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, SDisplayInfo *pDisplayInfo);
+  CDasherNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const std::string &strDisplayText);
 
   /// @brief Destructor
   ///
   virtual ~CDasherNode();
 
+  /// Adjusts the colour & label of this node to look as it would if it 
+  /// were the sole child of another node with the specified colour and label
+  /// (without actually making the other/group node)
+  void PrependElidedGroup(int iGroupColour, std::string &strGroupLabel);
+  
   void Trace() const;           // diagnostic
 
-  /// Return display information for this node
-  inline const SDisplayInfo *GetDisplayInfo() const;
-
   /// @name Routines for manipulating node status
   /// @{
 
@@ -263,13 +267,10 @@ class Dasher::CDasherNode:private NoClones {
   }
 
   /// @}
-  int m_iOffset;
 
  private:
   inline ChildMap &Children();
 
-  SDisplayInfo *m_pDisplayInfo;
-
   unsigned int m_iLbnd;
   unsigned int m_iHbnd;   // the cumulative lower and upper bound prob relative to parent
 
@@ -280,6 +281,11 @@ class Dasher::CDasherNode:private NoClones {
 
   // Binary flags representing the state of the node
   int m_iFlags;
+  
+ protected:
+  int m_iColour;
+  int m_iOffset;
+  std::string m_strDisplayText;
 };
 /// @}
 
@@ -295,10 +301,6 @@ namespace Dasher {
 
 namespace Dasher {
 
-inline const CDasherNode::SDisplayInfo *CDasherNode::GetDisplayInfo() const {
-  return m_pDisplayInfo;
-}
-
 inline unsigned int CDasherNode::Lbnd() const {
   return m_iLbnd;
 }
diff --git a/Src/DasherCore/DasherViewSquare.cpp b/Src/DasherCore/DasherViewSquare.cpp
index 966ad52..f0ec7ad 100644
--- a/Src/DasherCore/DasherViewSquare.cpp
+++ b/Src/DasherCore/DasherViewSquare.cpp
@@ -366,17 +366,17 @@ void CDasherViewSquare::RecursiveRender(CDasherNode *pRender, myint y1, myint y2
 
   DasherDrawRectangle(std::min(parent_width,iDasherMaxX), std::max(y1,iDasherMinY), std::min(y2-y1,iDasherMaxX), std::min(y2,iDasherMaxY), parent_color, -1, Nodes1, 0);
   
-  const std::string &sDisplayText(pRender->GetDisplayInfo()->strDisplayText);
+  const std::string &sDisplayText(pRender->getDisplayText());
   if( sDisplayText.size() > 0 )
   {  
-    DasherDrawText(y2-y1, y1, y2-y1, y2, sDisplayText, mostleft, pRender->GetDisplayInfo()->bShove);
+    DasherDrawText(y2-y1, y1, y2-y1, y2, sDisplayText, mostleft, pRender->bShove());
   }
 	
   pRender->SetFlag(NF_SUPER, !IsSpaceAroundNode(y1,y2));
 
   // If there are no children then we still need to render the parent
   if(pRender->ChildCount() == 0) {
-    DasherDrawRectangle(std::min(y2-y1,iDasherMaxX), std::min(y2,iDasherMaxY),0, std::max(y1,iDasherMinY), pRender->GetDisplayInfo()->iColour, -1, Nodes1, 0);
+    DasherDrawRectangle(std::min(y2-y1,iDasherMaxX), std::min(y2,iDasherMaxY),0, std::max(y1,iDasherMinY), pRender->getColour(), -1, Nodes1, 0);
 	  //also allow it to be expanded, it's big enough.
 	  policy.pushNode(pRender, y1, y2, true, dMaxCost);
 	  return;
@@ -398,7 +398,7 @@ void CDasherViewSquare::RecursiveRender(CDasherNode *pRender, myint y1, myint y2
   int id=-1;
   //  int lower=-1,upper=-1;
   myint temp_parentwidth=y2-y1;
-  int temp_parentcolor = pRender->GetDisplayInfo()->iColour;
+  int temp_parentcolor = pRender->getColour();
 
   const myint Range(y2 - y1);
   
@@ -448,8 +448,8 @@ void CDasherViewSquare::RecursiveRender(CDasherNode *pRender, myint y1, myint y2
 			//std::cout << "Fill in: " << lasty << " " << newy1 << std::endl;
 		  
 			RenderNodePartFast(temp_parentcolor, lasty, newy1, mostleft, 
-					 pRender->GetDisplayInfo()->strDisplayText, 
-					 pRender->GetDisplayInfo()->bShove,
+					 pRender->getDisplayText(),
+					 pRender->bShove(),
 					 temp_parentwidth);
           }
 		
@@ -463,17 +463,17 @@ void CDasherViewSquare::RecursiveRender(CDasherNode *pRender, myint y1, myint y2
 		// Theres a chance that we haven't yet filled the entire parent, so finish things off if necessary.
 		if(lasty<y2) {
 		  RenderNodePartFast(temp_parentcolor, lasty, y2, mostleft, 
-				 pRender->GetDisplayInfo()->strDisplayText, 
-				 pRender->GetDisplayInfo()->bShove,
+				 pRender->getDisplayText(),
+				 pRender->bShove(),
 				 temp_parentwidth);
 		}
   }  
     // Draw the outline
-    if(pRender->GetDisplayInfo()->bVisible) {
-      RenderNodeOutlineFast(pRender->GetDisplayInfo()->iColour, 
+    if(pRender->getColour() != -1) {//-1 = invisible
+      RenderNodeOutlineFast(pRender->getColour(),
 			    y1, y2, mostleft, 
-			    pRender->GetDisplayInfo()->strDisplayText, 
-			    pRender->GetDisplayInfo()->bShove);
+			    pRender->getDisplayText(), 
+			    pRender->bShove());
     }
     //  }
 }
diff --git a/Src/DasherCore/MandarinAlphMgr.cpp b/Src/DasherCore/MandarinAlphMgr.cpp
index 5ca8f92..93b3926 100644
--- a/Src/DasherCore/MandarinAlphMgr.cpp
+++ b/Src/DasherCore/MandarinAlphMgr.cpp
@@ -71,17 +71,10 @@ CDasherNode *CMandarinAlphMgr::CreateSymbolNode(CAlphNode *pParent, symbol iSymb
 	   * return pNewNode;
      */
 
-    //from ConversionManager:
-    CDasherNode::SDisplayInfo *pInfo = new CDasherNode::SDisplayInfo;
-    pInfo->bVisible = true;
-    pInfo->bShove = true;
-    pInfo->strDisplayText = "";
-    pInfo->iColour = 9;
-    //CTrieNode parallels old PinyinConversionHelper's SetConvSymbol:
-    CConvRoot *pNewNode = new CConvRoot(pParent, iLbnd, iHbnd, pInfo, this, m_pParser->GetTrieNode(m_pNCManager->GetAlphabet()->GetDisplayText(iSymbol)));
 
-    //keep same offset, as we still haven't entered/selected a definite symbol
-    pNewNode->m_iOffset = pParent->m_iOffset;
+    //CTrieNode parallels old PinyinConversionHelper's SetConvSymbol; we keep
+    // the same offset as we've still not entered/selected a symbol (leaf)
+    CConvRoot *pNewNode = new CConvRoot(pParent, pParent->offset(), iLbnd, iHbnd, this, m_pParser->GetTrieNode(m_pNCManager->GetAlphabet()->GetDisplayText(iSymbol)));
 
     //from ConversionHelper:
     //pNewNode->m_pLanguageModel = m_pLanguageModel;
@@ -92,9 +85,9 @@ CDasherNode *CMandarinAlphMgr::CreateSymbolNode(CAlphNode *pParent, symbol iSymb
   return CAlphabetManager::CreateSymbolNode(pParent, iSymbol, iLbnd, iHbnd);
 }
 
-CMandarinAlphMgr::CConvRoot::CConvRoot(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, SDisplayInfo *pDisplayInfo, CMandarinAlphMgr *pMgr, CTrieNode *pTrie)
-: CDasherNode(pParent, iLbnd, iHbnd, pDisplayInfo), m_pMgr(pMgr), m_pTrie(pTrie) {
-  
+CMandarinAlphMgr::CConvRoot::CConvRoot(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CMandarinAlphMgr *pMgr, CTrieNode *pTrie)
+: CDasherNode(pParent, iOffset, iLbnd, iHbnd, 9, ""), m_pMgr(pMgr), m_pTrie(pTrie) {
+  //colour + label from ConversionManager.
 }
 
 int CMandarinAlphMgr::CConvRoot::ExpectedNumChildren() {
@@ -139,19 +132,11 @@ void CMandarinAlphMgr::CConvRoot::PopulateChildren() {
     // TODO: Parameters here are placeholders - need to figure out
     // what's right    
     
-    CDasherNode::SDisplayInfo *pDisplayInfo = new CDasherNode::SDisplayInfo;
-    pDisplayInfo->iColour = (m_vChInfo.size()==1) ? GetDisplayInfo()->iColour : m_pMgr->AssignColour(parentClr, iIdx);
-    pDisplayInfo->bShove = true;
-    pDisplayInfo->bVisible = true;
+    int iColour(m_vChInfo.size()==1 ? getColour() : m_pMgr->AssignColour(parentClr, iIdx));
     
     //  std::cout << "#" << pCurrentSCEChild->pszConversion << "#" << std::endl;
     
-    //The chinese characters are in the _text_ (not label - that's e.g. "liang4")
-    // of the alphabet (& the pszConversion from PinyinParser was converted to symbol
-    // by CAlphabet::GetSymbols, which does string->symbol by _text_; we're reversing that)
-    pDisplayInfo->strDisplayText = m_pMgr->m_pCHAlphabet->GetText(it->first);
-    
-    CMandNode *pNewNode = new CMandSym(this, iLbnd, iHbnd, pDisplayInfo, m_pMgr, it->first);
+    CMandNode *pNewNode = new CMandSym(this, m_iOffset+1, iLbnd, iHbnd, iColour, m_pMgr, it->first);
     
     // TODO: Reimplement ----
     
@@ -159,8 +144,6 @@ void CMandarinAlphMgr::CConvRoot::PopulateChildren() {
     //      pNewNode->SetContext(m_pLanguageModel->CreateEmptyContext());
     // -----
     
-    pNewNode->m_iOffset = m_iOffset + 1;
-    
     pNewNode->iContext = m_pMgr->m_pLanguageModel->CloneContext(this->iContext);
       
     m_pMgr->m_pLanguageModel->EnterSymbol(iContext, it->first); // TODO: Don't use symbols?      
@@ -283,12 +266,18 @@ CLanguageModel::Context CMandarinAlphMgr::CreateSymbolContext(CAlphNode *pParent
 	return m_pLanguageModel->CloneContext(pParent->iContext);
 }
 
-CMandarinAlphMgr::CMandNode::CMandNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, CMandarinAlphMgr *pMgr, symbol iSymbol)
-: CSymbolNode(pParent, iLbnd, iHbnd, pDispInfo, pMgr, iSymbol) {
+CMandarinAlphMgr::CMandNode::CMandNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CMandarinAlphMgr *pMgr, symbol iSymbol)
+: CSymbolNode(pParent, iOffset, iLbnd, iHbnd, pMgr, iSymbol) {
+}
+
+CMandarinAlphMgr::CMandNode::CMandNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const string &strDisplayText, CMandarinAlphMgr *pMgr, symbol iSymbol)
+: CSymbolNode(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText, pMgr, iSymbol) {
 }
 
-CMandarinAlphMgr::CMandNode *CMandarinAlphMgr::makeSymbol(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, symbol iSymbol) {
-  return new CMandNode(pParent, iLbnd, iHbnd, pDispInfo, this, iSymbol);
+CMandarinAlphMgr::CMandNode *CMandarinAlphMgr::makeSymbol(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, symbol iSymbol) {
+  // Override standard symbol factory method, called by superclass, to make CMandNodes
+  //  - important only to disable learn-as-you-write...
+  return new CMandNode(pParent, iOffset, iLbnd, iHbnd, this, iSymbol);
 }
 
 void CMandarinAlphMgr::CMandNode::SetFlag(int iFlag, bool bValue) {
@@ -299,8 +288,13 @@ void CMandarinAlphMgr::CMandNode::SetFlag(int iFlag, bool bValue) {
       CAlphNode::SetFlag(iFlag, bValue);
 }
 
-CMandarinAlphMgr::CMandSym::CMandSym(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, CMandarinAlphMgr *pMgr, symbol iSymbol)
-: CMandNode(pParent, iLbnd, iHbnd, pDispInfo, pMgr, iSymbol) {
+// For converted chinese symbols, we construct instead CMandSyms...
+CMandarinAlphMgr::CMandSym::CMandSym(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, CMandarinAlphMgr *pMgr, symbol iSymbol)
+: CMandNode(pParent, iOffset, iLbnd, iHbnd, iColour, pMgr->m_pCHAlphabet->GetText(iSymbol), pMgr, iSymbol) {
+  //Note we passed a custom label into superclass constructor:
+  // the chinese characters are in the _text_ (not label - that's e.g. "liang4")
+  // of the alphabet (& the pszConversion from PinyinParser was converted to symbol
+  // by CAlphabet::GetSymbols, which does string->symbol by _text_; we're reversing that)
 }
 
 const std::string &CMandarinAlphMgr::CMandSym::outputText() {
diff --git a/Src/DasherCore/MandarinAlphMgr.h b/Src/DasherCore/MandarinAlphMgr.h
index b0abadb..e09e54b 100644
--- a/Src/DasherCore/MandarinAlphMgr.h
+++ b/Src/DasherCore/MandarinAlphMgr.h
@@ -55,20 +55,23 @@ namespace Dasher {
     class CMandNode : public CSymbolNode {
     public:
       CMandarinAlphMgr *mgr() {return static_cast<CMandarinAlphMgr *>(CSymbolNode::mgr());}
-      CMandNode(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, CMandarinAlphMgr *pMgr, symbol iSymbol);
+      CMandNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CMandarinAlphMgr *pMgr, symbol iSymbol);
       virtual void SetFlag(int iFlag, bool bValue);
       virtual CDasherNode *RebuildParent() {return 0;}
+    protected:
+      /// Constructor for subclasses (CMandSym!) to specify own colour & label
+      CMandNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const std::string &strDisplayText, CMandarinAlphMgr *pMgr, symbol iSymbol);
     };
     class CMandSym : public CMandNode {
     public:
-      CMandSym(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, CMandarinAlphMgr *pMgr, symbol iSymbol);
+      CMandSym(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, CMandarinAlphMgr *pMgr, symbol iSymbol);
     private:
       virtual const std::string &outputText();
     };
     class CConvRoot : public CDasherNode {
     public:
       CMandarinAlphMgr *mgr() {return m_pMgr;}
-      CConvRoot(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, CMandarinAlphMgr *pMgr, CTrieNode *pTrie);
+      CConvRoot(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CMandarinAlphMgr *pMgr, CTrieNode *pTrie);
       void PopulateChildren();
       int ExpectedNumChildren();
       int iContext;
@@ -79,7 +82,7 @@ namespace Dasher {
       CMandarinAlphMgr *m_pMgr;
       CTrieNode *m_pTrie;
     };
-    CMandNode *makeSymbol(CDasherNode *pParent, unsigned int iLbnd, unsigned int iHbnd, CDasherNode::SDisplayInfo *pDispInfo, symbol iSymbol);
+    CMandNode *makeSymbol(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, symbol iSymbol);
     virtual CDasherNode *CreateSymbolNode(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd);
     virtual CLanguageModel::Context CreateSymbolContext(CAlphNode *pParent, symbol iSymbol);
 



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