void CControlBase::CContNode::PopulateChildren() { CDasherNode *pNewNode; const unsigned int iNChildren( m_pTemplate->successors.size() ); unsigned int iLbnd(0), iIdx(0); for (vector<NodeTemplate *>::iterator it = m_pTemplate->successors.begin(); it!=m_pTemplate->successors.end(); it++) { const unsigned int iHbnd((++iIdx*CDasherModel::NORMALIZATION)/iNChildren); if( *it == NULL ) { // Escape back to alphabet pNewNode = m_pMgr->m_pNCManager->GetAlphabetManager()->GetRoot(this, false, offset()+1); } else { pNewNode = new CContNode(offset(), m_pMgr->getColour(*it, this), *it, m_pMgr); } pNewNode->Reparent(this, iLbnd, iHbnd); iLbnd=iHbnd; DASHER_ASSERT(GetChildren().back()==pNewNode); } }
void CDasherModel::SetControlOffset(int iOffset) { // This is a hack, making many dubious assumptions which happen to // work right now. CDasherNode *pNode = Get_node_under_crosshair(); pNode->SetControlOffset(iOffset); }
void CDasherModel::HandleOutput(Dasher::VECTOR_SYMBOL_PROB* pAdded, int* pNumDeleted) { CDasherNode *pNewNode = Get_node_under_crosshair(); DASHER_ASSERT(pNewNode != NULL); // std::cout << "HandleOutput: " << m_pLastOutput << " => " << pNewNode << std::endl; CDasherNode *pLastSeen = pNewNode; while (pLastSeen && !pLastSeen->GetFlag(NF_SEEN)) pLastSeen = pLastSeen->Parent(); while (m_pLastOutput != pLastSeen) { m_pLastOutput->Undo(); m_pLastOutput->Leave(); //Should we? I think so, but the old code didn't...? m_pLastOutput->SetFlag(NF_SEEN, false); // TODO: Is this the right place to trap output? if(pNumDeleted != NULL) (*pNumDeleted) += m_pLastOutput->m_iNumSymbols; m_pLastOutput = m_pLastOutput->Parent(); if (m_pLastOutput) m_pLastOutput->Enter(); } if(!pNewNode->GetFlag(NF_SEEN)) { RecursiveOutput(pNewNode, pAdded); } }
void CControlBase::CContNode::PopulateChildren() { CDasherNode *pNewNode; const unsigned int iNChildren( m_pTemplate->successors.size() ); unsigned int iLbnd(0), iIdx(0); int newOffset = m_pTemplate->calculateNewOffset(this, offset()); for (auto child : m_pTemplate->successors) { const unsigned int iHbnd((++iIdx*CDasherModel::NORMALIZATION)/iNChildren); if( child == NULL ) { // Escape back to alphabet pNewNode = m_pMgr->m_pNCManager->GetAlphabetManager()->GetRoot(this, false, newOffset + 1); } else { pNewNode = new CContNode(newOffset, m_pMgr->getColour(child, this), child, m_pMgr); } pNewNode->Reparent(this, iLbnd, iHbnd); iLbnd=iHbnd; DASHER_ASSERT(GetChildren().back()==pNewNode); } }
void CNodeCreationManager::AddExtras(CDasherNode *pParent) { //control mode: DASHER_ASSERT(pParent->GetChildren().back()->Hbnd() == m_iAlphNorm); if (m_pControlManager) { //ACL leave offset as is - like its groupnode parent, but unlike its alphnode siblings, //the control node does not enter a symbol.... CDasherNode *ctl = m_pControlManager->GetRoot(pParent, pParent->offset()); ctl->Reparent(pParent, pParent->GetChildren().back()->Hbnd(), CDasherModel::NORMALIZATION); } }
CDasherNode *const CDasherNode::Get_node_under(int iNormalization, myint miY1, myint miY2, myint miMousex, myint miMousey) { myint miRange = miY2 - miY1; ChildMap::const_iterator i; for(i = GetChildren().begin(); i != GetChildren().end(); i++) { CDasherNode *pChild = *i; myint miNewy1 = miY1 + (miRange * pChild->m_iLbnd) / iNormalization; myint miNewy2 = miY1 + (miRange * pChild->m_iHbnd) / iNormalization; if(miMousey < miNewy2 && miMousey > miNewy1 && miMousex < miNewy2 - miNewy1) return pChild->Get_node_under(iNormalization, miNewy1, miNewy2, miMousex, miMousey); } return this; }
void CDasherInterfaceBase::SetOffset(int iOffset, bool bForce) { if (iOffset == m_pDasherModel->GetOffset() && !bForce) return; CDasherNode *pNode = m_pNCManager->GetAlphabetManager()->GetRoot(NULL, iOffset!=0, iOffset); if (GetGameModule()) pNode->SetFlag(NF_GAME, true); m_pDasherModel->SetNode(pNode); //ACL TODO note that CTL_MOVE, etc., do not come here (that would probably // rebuild the model / violently repaint the screen every time!). But we // still want to notifyOffset all text actions, so the "New" suboption sees // all the editing the user's done... for (set<TextAction *>::iterator it = m_vTextActions.begin(); it!=m_vTextActions.end(); it++) { (*it)->NotifyOffset(iOffset); } ScheduleRedraw(); }
void CDasherModel::Reparent_root(int lower, int upper) { DASHER_ASSERT(m_Root != NULL); // Change the root node to the parent of the existing node. We need // to recalculate the coordinates for the "new" root as the user may // have moved around within the current root CDasherNode *pNewRoot; if(oldroots.size() == 0) { pNewRoot = m_Root->RebuildParent(); } else { pNewRoot = oldroots.back(); oldroots.pop_back(); } // Return if there's no existing parent and no way of recreating one if(pNewRoot == NULL) return; pNewRoot->SetFlag(NF_COMMITTED, false); CDasherNode *pCurrent = m_Root; // Need to iterate through group pseudo-nodes while(pCurrent != pNewRoot) { lower = pCurrent->Lbnd(); upper = pCurrent->Hbnd(); pCurrent = pCurrent->Parent(); myint iWidth = upper - lower; myint iRootWidth = m_Rootmax - m_Rootmin; // Fail and undo root creation if the new root is bigger than allowed by normalisation if(((myint((GetLongParameter(LP_NORMALIZATION) - upper)) / static_cast<double>(iWidth)) > (m_Rootmax_max - m_Rootmax)/static_cast<double>(iRootWidth)) || ((myint(lower) / static_cast<double>(iWidth)) > (m_Rootmin - m_Rootmin_min) / static_cast<double>(iRootWidth))) { pNewRoot->OrphanChild(m_Root); delete pNewRoot; return; } //Update the root coordinates to reflect the new root m_Root = pNewRoot; m_Rootmax = m_Rootmax + (myint((GetLongParameter(LP_NORMALIZATION) - upper)) * iRootWidth / iWidth); m_Rootmin = m_Rootmin - (myint(lower) * iRootWidth / iWidth); for(std::deque<SGotoItem>::iterator it(m_deGotoQueue.begin()); it != m_deGotoQueue.end(); ++it) { iRootWidth = it->iN2 - it->iN1; it->iN2 = it->iN2 + (myint((GetLongParameter(LP_NORMALIZATION) - upper)) * iRootWidth / iWidth); it->iN1 = it->iN1 - (myint(lower) * iRootWidth / iWidth); } } }
bool CDasherModel::CheckForNewRoot(CDasherView *pView) { DASHER_ASSERT(m_Root != NULL); // TODO: pView is redundant here #ifdef DEBUG CDasherNode *pOldNode = Get_node_under_crosshair(); #endif CDasherNode *root(m_Root); if(!(m_Root->GetFlag(NF_SUPER))) { Reparent_root(root->Lbnd(), root->Hbnd()); return(m_Root != root); } CDasherNode *pNewRoot = NULL; for (CDasherNode::ChildMap::const_iterator it = m_Root->GetChildren().begin(); it != m_Root->GetChildren().end(); it++) { if ((*it)->GetFlag(NF_SUPER)) { //at most one child should have NF_SUPER set... DASHER_ASSERT(pNewRoot == NULL); pNewRoot = *it; #ifndef DEBUG break; #endif } } ////GAME MODE TEMP - only change the root if it is on the game path///////// if (pNewRoot && (!m_bGameMode || pNewRoot->GetFlag(NF_GAME))) { m_Root->DeleteNephews(pNewRoot); RecursiveMakeRoot(pNewRoot); } DASHER_ASSERT(Get_node_under_crosshair() == pOldNode); return false; }