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