예제 #1
0
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);
    }
  }
}
예제 #2
0
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();
}