Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/childstack.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshchildlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshleveltypes.h"
Toshihiro Shimizu 890ddd
#include "toonz/scenefx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
//! The Node class is a container of element necessary to define a sub-xsheet.
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
   The class contain a pointer to \b TXsheet \b m_xsheet, two integer to
Shinya Kitaoka 120a6e
   identify column
Shinya Kitaoka 120a6e
   \b m_col and row \b m_row, a \b TXshChildLevelP \b m_cl and a bool \b
Shinya Kitaoka 120a6e
   m_justCreated.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class ChildStack::Node {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TXsheet *m_xsheet;
Shinya Kitaoka 120a6e
  int m_row, m_col;
Shinya Kitaoka 120a6e
  std::map<int, int=""> m_rowTable;</int,>
Shinya Kitaoka 120a6e
  TXshChildLevelP m_cl;
Shinya Kitaoka 120a6e
  bool m_justCreated;
Shinya Kitaoka 120a6e
  Node()
Shinya Kitaoka 120a6e
      : m_xsheet(0), m_row(0), m_col(0), m_rowTable(), m_justCreated(false) {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// ChildStack
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ChildStack::ChildStack(ToonzScene *scene)
Jeremy Bullock 0ff1b6
    : m_scene(scene), m_xsheet(new TXsheet()) {
Shinya Kitaoka 120a6e
  m_xsheet->setScene(m_scene);
Shinya Kitaoka 120a6e
  m_xsheet->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ChildStack::~ChildStack() {
Shinya Kitaoka 120a6e
  m_xsheet->release();
Shinya Kitaoka 120a6e
  clearPointerContainer(m_stack);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ChildStack::clear() {
Shinya Kitaoka 120a6e
  m_xsheet->clearAll();
Shinya Kitaoka 120a6e
  m_xsheet->setScene(m_scene);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  clearPointerContainer(m_stack);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ChildStack::openChild(int row, int col) {
Shinya Kitaoka 120a6e
  TXshChildLevel *childLevel = 0;
Shinya Kitaoka 120a6e
  TXshCell cell              = m_xsheet->getCell(row, col);
Shinya Kitaoka 120a6e
  if (!cell.m_level) {
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    childLevel = cell.m_level->getChildLevel();
Shinya Kitaoka 120a6e
  if (!childLevel) return false;
Shinya Kitaoka 120a6e
  TXsheet *childXsheet = childLevel->getXsheet();
Shinya Kitaoka 120a6e
  Node *node           = new Node();
Shinya Kitaoka 120a6e
  node->m_row          = row;
Shinya Kitaoka 120a6e
  node->m_col          = col;
Shinya Kitaoka 120a6e
  node->m_xsheet       = m_xsheet;
Shinya Kitaoka 120a6e
  node->m_cl           = childLevel;
Shinya Kitaoka 120a6e
  node->m_justCreated  = !cell.m_level;
Shinya Kitaoka 120a6e
  int r0 = 0, r1 = -1;
Shinya Kitaoka 120a6e
  m_xsheet->getCellRange(col, r0, r1);
Shinya Kitaoka 120a6e
  for (int r = r0; r <= r1; r++) {
Shinya Kitaoka 120a6e
    TXshCell cell = m_xsheet->getCell(r, col);
Shinya Kitaoka 120a6e
    if (cell.m_level.getPointer() == childLevel) {
Shinya Kitaoka 120a6e
      int d = cell.m_frameId.getNumber() - 1;
Shinya Kitaoka 120a6e
      std::map<int, int="">::iterator it = node->m_rowTable.find(d);</int,>
Shinya Kitaoka 120a6e
      if (it == node->m_rowTable.end()) node->m_rowTable[d] = r;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_stack.push_back(node);
Shinya Kitaoka 120a6e
  m_xsheet = childXsheet;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ChildStack::closeChild(int &row, int &col) {
Shinya Kitaoka 120a6e
  if (m_stack.empty()) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXsheet *childXsh = m_xsheet;
Shinya Kitaoka 120a6e
  childXsh
Shinya Kitaoka 120a6e
      ->updateFrameCount();  // non dovrebbe essere necessario, ma non si sa mai
Shinya Kitaoka 120a6e
  int childFrameCount = childXsh->getFrameCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Node *node = m_stack.back();
Shinya Kitaoka 120a6e
  m_stack.pop_back();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXsheet *parentXsh = node->m_xsheet;
Shinya Kitaoka 120a6e
  TXshChildLevelP cl = node->m_cl;
Shinya Kitaoka 120a6e
  row                = node->m_row;
Shinya Kitaoka 120a6e
  col                = node->m_col;
Shinya Kitaoka 120a6e
  bool justCreated   = node->m_justCreated;
Shinya Kitaoka 120a6e
  delete node;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_xsheet = parentXsh;
Shinya Kitaoka 120a6e
  m_xsheet->updateFrameCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // if(cl) cl->invalidateIcon();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXsheet *xsh = m_xsheet;
Shinya Kitaoka 120a6e
  if (justCreated) {
Shinya Kitaoka 120a6e
    assert(xsh->getCell(row, col).m_level.getPointer() == cl.getPointer());
Shinya Kitaoka 120a6e
    if (childFrameCount > 1) {
Shinya Kitaoka 120a6e
      xsh->insertCells(row + 1, col, childFrameCount - 1);
Shinya Kitaoka 120a6e
      for (int i = 1; i < childFrameCount; i++)
Shinya Kitaoka 120a6e
        xsh->setCell(row + i, col, TXshCell(cl.getPointer(), TFrameId(1 + i)));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXshChildLevel *ChildStack::createChild(int row, int col) {
Shinya Kitaoka 120a6e
  TXshLevel *xl = m_scene->createNewLevel(CHILD_XSHLEVEL);
Shinya Kitaoka 120a6e
  m_xsheet->setCell(row, col, TXshCell(xl, TFrameId(1)));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TXshCell cell = m_xsheet->getCell(row, col);
Shinya Kitaoka 120a6e
  return cell.m_level->getChildLevel();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int ChildStack::getAncestorCount() const { return m_stack.size(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXsheet *ChildStack::getTopXsheet() const {
Shinya Kitaoka 120a6e
  return m_stack.empty() ? m_xsheet : m_stack.front()->m_xsheet;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::pair<txsheet *,="" int=""> ChildStack::getAncestor(int row) const {</txsheet>
Shinya Kitaoka 120a6e
  TXsheet *xsh = m_xsheet;
Shinya Kitaoka 120a6e
  int i        = m_stack.size() - 1;
Shinya Kitaoka 120a6e
  while (i >= 0) {
Shinya Kitaoka 120a6e
    std::map<int, int="">::const_iterator it = m_stack[i]->m_rowTable.find(row);</int,>
Shinya Kitaoka 120a6e
    if (it == m_stack[i]->m_rowTable.end()) break;
Shinya Kitaoka 120a6e
    row = it->second;
Shinya Kitaoka 120a6e
    xsh = m_stack[i]->m_xsheet;
Shinya Kitaoka 120a6e
    i--;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return std::make_pair(xsh, row);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ChildStack::getAncestorAffine(TAffine &aff, int row) const {
Shinya Kitaoka 120a6e
  aff   = TAffine();
Shinya Kitaoka 120a6e
  int i = m_stack.size() - 1;
Shinya Kitaoka 120a6e
  while (i >= 0) {
Shinya Kitaoka 120a6e
    std::map<int, int="">::const_iterator it = m_stack[i]->m_rowTable.find(row);</int,>
Shinya Kitaoka 120a6e
    if (it == m_stack[i]->m_rowTable.end()) break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    row        = it->second;
Shinya Kitaoka 120a6e
    Node *node = m_stack[i];
Shinya Kitaoka 120a6e
    TAffine aff2;
Shinya Kitaoka 120a6e
    if (!getColumnPlacement(aff2, node->m_xsheet, row, node->m_col, false))
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    aff = aff2 * aff;
Shinya Kitaoka 120a6e
    i--;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}