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); } } }
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(); }