Beispiel #1
0
bool LevelMoverTool::canMoveColumns(const TPoint &pos) {
  TXsheet *xsh = getViewer()->getXsheet();
  if (pos.x < 0) return false;
  if (pos.x != m_lastPos.x) {
    int count = 0;
    // controlla il tipo
    for (int i = 0; i < m_range.lx; i++) {
      int srcIndex          = m_lastPos.x + i;
      int dstIndex          = pos.x + i;
      TXshColumn *srcColumn = xsh->getColumn(srcIndex);
      if (srcColumn && srcColumn->isLocked()) continue;
      TXshColumn *dstColumn          = xsh->getColumn(dstIndex);
      TXshColumn::ColumnType srcType = TXshColumn::eLevelType;
      if (srcColumn) srcType         = srcColumn->getColumnType();
      if (srcType == TXshColumn::eZeraryFxType) return false;
      /*
qDebug() << "check: " << srcIndex << ":" <<
(srcColumn ? QString::number(srcType) : "empty") <<
" => " << dstIndex << ":" <<
(dstColumn ? QString::number(dstColumn->getColumnType()) : "empty");
*/

      if (dstColumn && !dstColumn->isEmpty() &&
          dstColumn->getColumnType() != srcType) {
        return false;
      }
      if (!dstColumn || dstColumn->isLocked() == false) {
        count++;
      }
    }
    if (count == 0) return false;
  }
  return true;
}
void TKeyframeSelection::unselectLockedColumn() {
  TApp *app = TApp::instance();
  assert(app);
  TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
  std::set<Position> positions;
  std::set<Position>::iterator it;
  for (it = m_positions.begin(); it != m_positions.end(); ++it) {
    int col = it->second;
    if (col >= 0 && xsh->getColumn(col) && xsh->getColumn(col)->isLocked())
      continue;
    positions.insert(*it);
  }
  m_positions.swap(positions);
}
 void enableColumns(ToonzScene *scene, QList<bool> &oldStatus) {
   if (m_columnList.empty()) return;
   QList<bool> newStatus;
   TXsheet *xsh = scene->getXsheet();
   for (int i = 0; i < xsh->getColumnCount(); i++) {
     oldStatus.append(xsh->getColumn(i)->isPreviewVisible());
     newStatus.append(false);
   }
   for (int i : m_columnList) {
     if (0 <= i && i < xsh->getColumnCount()) newStatus[i] = true;
   }
   for (int i = 0; i < newStatus.length(); i++) {
     xsh->getColumn(i)->setPreviewVisible(newStatus[i]);
   }
 }
Beispiel #4
0
bool CellsMover::canMoveCells(const TPoint &pos) {
  TXsheet *xsh = getXsheet();
  if (pos.x < 0) return false;
  if (pos.x != m_startPos.x) {
    int count = 0;
    // controlla il tipo
    int i = 0;
    while (i < m_rowCount * m_colCount) {
      TXshColumn::ColumnType srcType = getColumnTypeFromCell(i);
      int dstIndex                   = pos.x + i;
      TXshColumn *dstColumn          = xsh->getColumn(dstIndex);
      if (srcType == TXshColumn::eZeraryFxType) return false;
      if (dstColumn && !dstColumn->isEmpty() &&
          dstColumn->getColumnType() != srcType)
        return false;
      if (!dstColumn || dstColumn->isLocked() == false) count++;
      i += m_rowCount;
    }
    if (count == 0) return false;
  }
  if ((m_qualifiers & CellsMover::eInsertCells) ||
      (m_qualifiers & CellsMover::eOverwriteCells))
    return true;
  int count = 0;
  for (int i = 0; i < m_colCount; i++) {
    for (int j = 0; j < m_rowCount; j++) {
      if (!xsh->getCell(pos.y + j, pos.x + i).isEmpty()) return false;
      count++;
    }
  }
  if (count == 0) return false;
  return true;
}
Beispiel #5
0
void LayerHeaderPanel::mouseReleaseEvent(QMouseEvent *event) {
  TApp *app    = TApp::instance();
  TXsheet *xsh = m_viewer->getXsheet();
  int col, totcols = xsh->getColumnCount();
  bool sound_changed = false;

  if (m_doOnRelease != 0 && totcols > 0) {
    for (col = 0; col < totcols; col++) {
      if (!xsh->isColumnEmpty(col)) {
        TXshColumn *column = xsh->getColumn(col);

        if (m_doOnRelease == ToggleAllPreviewVisible) {
          column->setPreviewVisible(!column->isPreviewVisible());
        } else if (m_doOnRelease == ToggleAllTransparency) {
          column->setCamstandVisible(!column->isCamstandVisible());
          if (column->getSoundColumn()) sound_changed = true;
        } else if (m_doOnRelease == ToggleAllLock) {
          column->lock(!column->isLocked());
        }
      }
    }

    if (sound_changed) {
      app->getCurrentXsheet()->notifyXsheetSoundChanged();
    }

    app->getCurrentScene()->notifySceneChanged();
    app->getCurrentXsheet()->notifyXsheetChanged();
  }
  m_viewer->updateColumnArea();
  update();
  m_doOnRelease = 0;
}
Beispiel #6
0
void ColumnCmd::resequence(int index) {
  if (!canResequence(index)) return;
  TXsheet *xsh       = TApp::instance()->getCurrentXsheet()->getXsheet();
  TXshColumn *column = xsh->getColumn(index);
  assert(column);
  TXshLevelColumn *lcolumn = column->getLevelColumn();
  assert(lcolumn);
  int r0 = 0, r1 = -1;
  lcolumn->getRange(r0, r1);
  assert(r0 <= r1);
  TXshCell cell = lcolumn->getCell(r0);
  assert(!cell.isEmpty());
  TXshChildLevel *xl = cell.m_level->getChildLevel();
  assert(xl);
  TXsheet *childXsh              = xl->getXsheet();
  int frameCount                 = childXsh->getFrameCount();
  if (frameCount < 1) frameCount = 1;

  TUndoManager::manager()->add(new ResequenceUndo(index, frameCount));

  lcolumn->clearCells(r0, r1 - r0 + 1);
  for (int i = 0; i < frameCount; i++) {
    cell.m_frameId = TFrameId(i + 1);
    lcolumn->setCell(r0 + i, cell);
  }

  xsh->updateFrameCount();

  TApp::instance()->getCurrentScene()->setDirtyFlag(true);
  TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}
Beispiel #7
0
void RowArea::mousePressEvent(QMouseEvent *event)
{
	m_viewer->setQtModifiers(event->modifiers());
	if (event->button() == Qt::LeftButton) {
		bool playRangeModifierisClicked = false;

		TApp *app = TApp::instance();
		TXsheet *xsh = app->getCurrentScene()->getScene()->getXsheet();
		TPoint pos(event->pos().x(), event->pos().y());

		int row = m_viewer->yToRow(pos.y);

		QRect visibleRect = visibleRegion().boundingRect();
		int playR0, playR1, step;
		XsheetGUI::getPlayRange(playR0, playR1, step);

		bool playRangeEnabled = playR0 <= playR1;
		if (!playRangeEnabled) {
			TXsheet *xsh = m_viewer->getXsheet();
			playR1 = xsh->getFrameCount() - 1;
			playR0 = 0;
		}

		if (playR1 == -1) { //getFrameCount = 0 i.e. xsheet is empty
			setDragTool(XsheetGUI::DragTool::makeCurrentFrameModifierTool(m_viewer));
		} else if (m_xa <= pos.x && pos.x <= m_xa + 10 && (row == playR0 || row == playR1)) {
			if (!playRangeEnabled)
				XsheetGUI::setPlayRange(playR0, playR1, step);
			setDragTool(XsheetGUI::DragTool::makePlayRangeModifierTool(m_viewer));
			playRangeModifierisClicked = true;
		} else
			setDragTool(XsheetGUI::DragTool::makeCurrentFrameModifierTool(m_viewer));

		//when shift+click the row area, select a single row region in the cell area
		if (!playRangeModifierisClicked && 0 != (event->modifiers() & Qt::ShiftModifier)) {
			int filledCol;
			for (filledCol = xsh->getColumnCount() - 1; filledCol >= 0; filledCol--) {
				TXshColumn *currentColumn = xsh->getColumn(filledCol);
				if (!currentColumn)
					continue;
				if (!currentColumn->isEmpty())
					break;
			}

			m_viewer->getCellSelection()->selectNone();
			m_viewer->getCellSelection()->selectCells(row, 0, row, tmax(0, filledCol));
			m_viewer->updateCellRowAree();
		}

		m_viewer->dragToolClick(event);
		event->accept();
	} // left-click
	// pan by middle-drag
	else if (event->button() == Qt::MidButton) {
		m_pos = event->pos();
		m_isPanning = true;
	}
}
Beispiel #8
0
void CellsMover::getCells(std::vector<TXshCell> &cells, int r, int c) const {
  for (int i = 0; i < (int)cells.size(); i++) cells[i] = TXshCell();
  TXsheet *xsh                                         = getXsheet();
  for (int i = 0; i < m_colCount; i++) {
    TXshColumn *column = xsh->getColumn(c + i);
    if (column && column->isLocked()) continue;
    xsh->getCells(r, c + i, m_rowCount, &cells[m_rowCount * i]);
  }
}
Beispiel #9
0
// isTotallyEmptyColumn == column empty, no fx
bool LevelMoverTool::isTotallyEmptyColumn(int col) const {
  if (col < 0) return false;
  TXsheet *xsh       = getViewer()->getXsheet();
  TXshColumn *column = xsh->getColumn(col);
  if (!column) return true;
  if (!column->isEmpty()) return false;
  if (column->getFx()->getOutputConnectionCount() != 0) return false;
  // bisogna controllare lo stage object
  return true;
}
Beispiel #10
0
//
// xsheet <- cells
//
void CellsMover::setCells(const std::vector<TXshCell> &cells, int r,
                          int c) const {
  TXsheet *xsh = getXsheet();
  for (int i = 0; i < m_colCount; i++) {
    TXshColumn *column = xsh->getColumn(c + i);
    if (column)  // skip if columns is locked or doesn't support cells operation
      if (column->getCellColumn() == 0 || column->isLocked()) continue;
    xsh->setCells(r, c + i, m_rowCount, &cells[m_rowCount * i]);
  }
}
Beispiel #11
0
TStageObject *ViewerKeyframeNavigator::getStageObject() const {
  if (!m_xsheetHandle || !m_objectHandle) return 0;

  TStageObjectId objectId = m_objectHandle->getObjectId();
  TXsheet *xsh            = m_xsheetHandle->getXsheet();
  // Se e' una colonna sound non posso settare chiavi
  if (objectId.isColumn()) {
    TXshColumn *column = xsh->getColumn(objectId.getIndex());
    if (column && column->getSoundColumn()) return 0;
  }
  return xsh->getStageObject(objectId);
}
Beispiel #12
0
static bool canMergeColumns(int column, int mColumn, bool forMatchlines) {
  TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();

  if (xsh->getColumn(column)->isLocked()) return false;

  int start, end;
  xsh->getCellRange(column, start, end);

  if (start > end) return false;
  std::vector<TXshCell> cell(end - start + 1);
  std::vector<TXshCell> mCell(end - start + 1);

  xsh->getCells(start, column, cell.size(), &(cell[0]));
  xsh->getCells(start, mColumn, cell.size(), &(mCell[0]));

  TXshSimpleLevel *level = 0, *mLevel = 0;
  TXshLevelP xl;

  for (int i = 0; i < (int)cell.size(); i++) {
    if (cell[i].isEmpty() || mCell[i].isEmpty()) continue;
    if (!level) {
      level = cell[i].getSimpleLevel();
      xl    = cell[i].m_level;
    }

    else if (level != cell[i].getSimpleLevel())
      return false;

    if (!mLevel)
      mLevel = mCell[i].getSimpleLevel();
    else if (mLevel != mCell[i].getSimpleLevel())
      return false;

    if (!mLevel || !level ||  // potrebbero non essere dei simplelevel
        (forMatchlines && (level->getType() != TZP_XSHLEVEL ||
                           mLevel->getType() != TZP_XSHLEVEL)))
      return false;
    else if (!forMatchlines) {
      if (level->getType() != mLevel->getType()) return false;
      if (level->getType() != PLI_XSHLEVEL && level->getType() != OVL_XSHLEVEL)
        return false;
      // Check level type write support. Based on TTool::updateEnabled()
      if (level->getType() == OVL_XSHLEVEL &&
          (level->getPath().getType() == "psd" ||     // PSD files.
           level->is16BitChannelLevel() ||            // 16bpc images.
           level->getProperties()->getBpp() == 1)) {  // Black & White images.
        return false;
      }
    }
  }
  return true;
}
Beispiel #13
0
bool SkeletonTool::doesApply() const
{
	TTool::Application *app = TTool::getApplication();
	TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
	assert(xsh);
	TStageObjectId objId = app->getCurrentObject()->getObjectId();
	if (objId.isColumn()) {
		TXshColumn *column = xsh->getColumn(objId.getIndex());
		if (column && column->getSoundColumn())
			return false;
	}
	return true;
}
Beispiel #14
0
//
// xsheet <- m_cells; insert cells if qualifiers contain eInsertCells
//
void CellsMover::moveCells(const TPoint &pos) const {
  int r        = pos.y;
  int c        = pos.x;
  TXsheet *xsh = getXsheet();
  if (m_qualifiers & eInsertCells) {
    for (int i = 0; i < m_colCount; i++) {
      TXshColumn *column = xsh->getColumn(c + i);
      if (column) {
        if (column->getCellColumn() == 0 || column->isLocked()) continue;
        xsh->insertCells(r, c + i, m_rowCount);
      }
    }
  }
  setCells(m_cells, r, c);
}
Beispiel #15
0
void SchematicViewer::updateScenes() {
  TStageObjectId id = m_stageScene->getCurrentObject();
  if (id.isColumn()) {
    m_stageScene->update();
    TXsheet *xsh = m_stageScene->getXsheetHandle()->getXsheet();
    if (!xsh) return;
    TXshColumn *column = xsh->getColumn(id.getIndex());
    if (!column) {
      m_fxScene->getFxHandle()->setFx(0, false);
      return;
    }
    TFx *fx = column->getFx();
    m_fxScene->getFxHandle()->setFx(fx, false);
    m_fxScene->update();
  }
}
Beispiel #16
0
void CellsMover::restoreColumns(int c) const {
  std::set<int> ii;
  for (int i   = 0; i < m_colCount; i++) ii.insert(c + i);
  TXsheet *xsh = getXsheet();
  for (int i = 0; i < m_colCount; i++) xsh->removeColumn(c);
  std::list<int> restoredSplineIds;
  m_columnsData->restoreObjects(
      ii, restoredSplineIds, xsh,
      StageObjectsData::eDoClone | StageObjectsData::eResetFxDagPositions);
  for (int i = 0; i < m_colCount; i++) {
    TXshColumn *column = xsh->getColumn(c + i);
    if (!column) continue;
    TXshCellColumn *cellColumn = column->getCellColumn();
    if (!cellColumn) continue;
    int r0 = 0, r1 = -1;
    cellColumn->getRange(r0, r1);
    if (r0 <= r1) cellColumn->clearCells(r0, r1 - r0 + 1);
  }
}
void FxSelection::visitFx(TFx *fx, QList<TFx *> &visitedFxs) {
  if (visitedFxs.contains(fx)) return;
  TZeraryColumnFx *zfx = dynamic_cast<TZeraryColumnFx *>(fx);
  if (zfx) fx          = zfx->getZeraryFx();
  if (!canGroup(fx)) return;
  visitedFxs.append(fx);
  int i;
  for (i = 0; i < fx->getInputPortCount(); i++) {
    TFx *inputFx              = fx->getInputPort(i)->getFx();
    TZeraryColumnFx *onputZFx = dynamic_cast<TZeraryColumnFx *>(inputFx);
    if (onputZFx) inputFx     = onputZFx->getZeraryFx();
    if (!inputFx) continue;
    bool canBeGrouped = !inputFx->getAttributes()->isGrouped() ||
                        (inputFx->getAttributes()->getEditingGroupId() ==
                         fx->getAttributes()->getEditingGroupId());
    if (!visitedFxs.contains(inputFx) && isSelected(inputFx) && canBeGrouped)
      visitFx(inputFx, visitedFxs);
  }
  if (zfx) fx = zfx;
  if (fx->isZerary() && !zfx) {
    TXsheet *xsh    = m_xshHandle->getXsheet();
    int columnCount = xsh->getColumnCount();
    int j;
    for (j = 0; j < columnCount; j++) {
      TZeraryColumnFx *zerary =
          dynamic_cast<TZeraryColumnFx *>(xsh->getColumn(j)->getFx());
      if (zerary && zerary->getZeraryFx() == fx) {
        fx = zerary;
        break;
      }
    }
  }
  for (i = 0; i < fx->getOutputConnectionCount(); i++) {
    TFx *outputFx = fx->getOutputConnection(i)->getOwnerFx();
    if (!outputFx) continue;
    bool canBeGrouped = !outputFx->getAttributes()->isGrouped() ||
                        (outputFx->getAttributes()->getEditingGroupId() ==
                         fx->getAttributes()->getEditingGroupId());
    if (!visitedFxs.contains(outputFx) && isSelected(outputFx) && canBeGrouped)
      visitFx(outputFx, visitedFxs);
  }
}
Beispiel #18
0
bool ColumnCmd::canResequence(int index) {
  TXsheet *xsh       = TApp::instance()->getCurrentXsheet()->getXsheet();
  TXshColumn *column = xsh->getColumn(index);
  if (!column) return false;
  TXshLevelColumn *lcolumn = column->getLevelColumn();
  if (!lcolumn) return false;
  int r0 = 0, r1 = -1;
  if (lcolumn->getRange(r0, r1) == 0) return false;
  assert(r0 <= r1);
  TXshCell cell = lcolumn->getCell(r0);
  assert(!cell.isEmpty());
  TXshLevel *xl = cell.m_level->getChildLevel();
  if (!xl) return false;
  for (int r = r0 + 1; r <= r1; r++) {
    cell = lcolumn->getCell(r);
    if (cell.isEmpty()) continue;
    if (cell.m_level.getPointer() != xl) return false;
  }
  return true;
}
Beispiel #19
0
    }

    players.push_back(player);
  } else if (TXshChildLevel *cl = xl->getChildLevel()) {
    int childRow         = cell.m_frameId.getNumber() - 1;
    TXsheet *childXsheet = cl->getXsheet();
    TStageObjectId childCameraId =
        childXsheet->getStageObjectTree()->getCurrentCameraId();
    TStageObject *childCamera = childXsheet->getStageObject(childCameraId);
    TAffine childCameraAff    = childCamera->getPlacement(childRow);
    double childCameraZ       = childCamera->getZ(childRow);

    std::vector<UCHAR> originalOpacity(childXsheet->getColumnCount());

    for (int c = 0; c < childXsheet->getColumnCount(); c++) {
      originalOpacity[c] = childXsheet->getColumn(c)->getOpacity();
      childXsheet->getColumn(c)->setOpacity(column->getOpacity());
    }

    SubXSheet subXSheet;
    subXSheet.m_camera = ZPlacement(childCameraAff, childCameraZ);
    subXSheet.m_z      = columnZ;

    TAffine childCameraZaff =
        childCameraAff *
        TScale((1000 + childCameraZ) / 1000);  // TODO: put in some lib
    TAffine invChildCameraZaff = childCameraZaff.inv();

    subXSheet.m_aff  = columnAff * invChildCameraZaff;
    subXSheet.m_zaff = columnZaff * invChildCameraZaff;
Beispiel #20
0
bool TTool::isColumnLocked(int columnIndex) const {
  if (columnIndex < 0) return false;
  TXsheet *xsh       = getXsheet();
  TXshColumn *column = xsh->getColumn(columnIndex);
  return column->isLocked();
}
Beispiel #21
0
  void execute() override {
    TColumnSelection *selection = dynamic_cast<TColumnSelection *>(
        TApp::instance()->getCurrentSelection()->getSelection());
    TXsheet *xsh       = TApp::instance()->getCurrentXsheet()->getXsheet();
    int cc             = TApp::instance()->getCurrentColumn()->getColumnIndex();
    bool sound_changed = false;
    TTool *tool        = TApp::instance()->getCurrentTool()->getTool();
    TTool::Viewer *viewer = tool ? tool->getViewer() : nullptr;
    bool viewer_changed   = false;

    for (int i = 0; i < xsh->getColumnCount(); i++) {
      /*- 空のカラムの場合は飛ばす -*/
      if (xsh->isColumnEmpty(i)) continue;
      /*- カラムが取得できなかったら飛ばす -*/
      TXshColumn *column = xsh->getColumn(i);
      if (!column) continue;
      /*- ターゲットが選択カラムのモードで、選択されていなかった場合は飛ばす -*/
      bool isSelected = selection && selection->isColumnSelected(i);
      if (m_target == TARGET_SELECTED && !isSelected) continue;

      /*-
       * ターゲットが「カレントカラムより右側」のモードで、iがカレントカラムより左の場合は飛ばす
       * -*/
      if (m_target == TARGET_UPPER && i < cc) continue;

      bool negate = m_target == TARGET_CURRENT && cc != i ||
                    m_target == TARGET_OTHER && cc == i ||
                    m_target == TARGET_UPPER && cc == i;

      int cmd = m_cmd;

      if (cmd & (CMD_LOCK | CMD_UNLOCK | CMD_TOGGLE_LOCK)) {
        if (cmd & CMD_LOCK)
          column->lock(!negate);
        else if (cmd & CMD_UNLOCK)
          column->lock(negate);
        else
          column->lock(!column->isLocked());
        viewer_changed = true;
      }
      if (cmd &
          (CMD_ENABLE_PREVIEW | CMD_DISABLE_PREVIEW | CMD_TOGGLE_PREVIEW)) {
        if (cmd & CMD_ENABLE_PREVIEW)
          column->setPreviewVisible(!negate);
        else if (cmd & CMD_DISABLE_PREVIEW)
          column->setPreviewVisible(negate);
        else
          column->setPreviewVisible(!column->isPreviewVisible());
      }
      if (cmd &
          (CMD_ENABLE_CAMSTAND | CMD_DISABLE_CAMSTAND | CMD_TOGGLE_CAMSTAND)) {
        if (cmd & CMD_ENABLE_CAMSTAND)
          column->setCamstandVisible(!negate);
        else if (cmd & CMD_DISABLE_CAMSTAND)
          column->setCamstandVisible(negate);
        else
          column->setCamstandVisible(!column->isCamstandVisible());
        if (column->getSoundColumn()) sound_changed = true;
        viewer_changed                              = true;
      }
      /*TAB
if(cmd & (CMD_ENABLE_PREVIEW|CMD_DISABLE_PREVIEW|CMD_TOGGLE_PREVIEW))
{ //In Tab preview e cameraStand vanno settati entrambi
if(cmd&CMD_ENABLE_PREVIEW)
{
column->setPreviewVisible(!negate);
column->setCamstandVisible(!negate);
}
else if(cmd&CMD_DISABLE_PREVIEW)
{
column->setPreviewVisible(negate);
column->setCamstandVisible(negate);
}
else
{
column->setPreviewVisible(!column->isPreviewVisible());
column->setCamstandVisible(!column->isCamstandVisible());
}
}
      */
    }
    if (sound_changed)
      TApp::instance()->getCurrentXsheet()->notifyXsheetSoundChanged();
    TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
    TApp::instance()->getCurrentScene()->setDirtyFlag(true);
    if (viewer && viewer_changed) viewer->invalidateToolStatus();
  }
Beispiel #22
0
void ColumnCmd::cloneChild(int index) {
  if (!canResequence(index)) return;

  /*-- カラムを取得 --*/
  TXsheet *xsh       = TApp::instance()->getCurrentXsheet()->getXsheet();
  TXshColumn *column = xsh->getColumn(index);
  assert(column);

  // get the subxsheet to clone (childLevel, childXsh)
  /*-- SubXsheetレベルを取得 --*/
  TXshLevelColumn *lcolumn = column->getLevelColumn();
  assert(lcolumn);
  int r0 = 0, r1 = -1;
  lcolumn->getRange(r0, r1);
  assert(r0 <= r1);
  /*-- SubXsheetの一番頭のセル --*/
  TXshCell cell = lcolumn->getCell(r0);
  assert(!cell.isEmpty());
  /*- cell内に格納されているLevelを取得 -*/
  TXshChildLevel *childLevel = cell.m_level->getChildLevel();
  assert(childLevel);
  /*- SubXsheetのXsheetを取得 -*/
  TXsheet *childXsh = childLevel->getXsheet();

  // insert a new empty column
  /*- 隣に空きColumnをInsertしてCloneに備える -*/
  int newColumnIndex = index + 1;
  xsh->insertColumn(newColumnIndex);

  // create a subxsheet (newChildLevel, newChildXsh)
  ToonzScene *scene      = TApp::instance()->getCurrentScene()->getScene();
  ChildStack *childStack = scene->getChildStack();
  TXshChildLevel *newChildLevel = childStack->createChild(0, newColumnIndex);
  TXsheet *newChildXsh          = newChildLevel->getXsheet();

  // copy columns.
  std::set<int> indices;
  for (int i = 0; i < childXsh->getColumnCount(); i++) indices.insert(i);
  StageObjectsData *data = new StageObjectsData();
  data->storeColumns(indices, childXsh, 0);
  data->storeColumnFxs(indices, childXsh, 0);
  std::list<int> restoredSplineIds;
  data->restoreObjects(indices, restoredSplineIds, newChildXsh,
                       StageObjectsData::eDoClone);
  delete data;

  cloneNotColumnLinkedFxsAndOutputsFx(childXsh, newChildXsh);
  cloneXsheetTStageObjectTree(childXsh, newChildXsh);
  /*--以下は、Clone SubXsheet
  するときに、SubXsheet内にある子SubXsheetをクローンする関数
  クローンされた中にある子SubXsheetは、同じもので良いので、スキップする --*/
  // cloneSubXsheets(newChildXsh);

  /*-- XSheetノードのFxSchematicでのDagNodePosを再現
  FxやColumnノードの位置の再現は上のsetColumnで行っている
--*/
  newChildXsh->getFxDag()->getXsheetFx()->getAttributes()->setDagNodePos(
      childXsh->getFxDag()->getXsheetFx()->getAttributes()->getDagNodePos());

  newChildXsh->updateFrameCount();

  /*-- TXshChildLevel作成時にsetCellした1つ目のセルを消去 --*/
  xsh->removeCells(0, newColumnIndex);
  /*-- CloneしたColumnのセル番号順を再現 --*/
  for (int r = r0; r <= r1; r++) {
    TXshCell cell = lcolumn->getCell(r);
    if (cell.isEmpty()) continue;

    cell.m_level = newChildLevel;
    xsh->setCell(r, newColumnIndex, cell);
  }

  TStageObjectId currentObjectId =
      TApp::instance()->getCurrentObject()->getObjectId();
  xsh->getStageObject(TStageObjectId::ColumnId(newColumnIndex))
      ->setParent(xsh->getStageObjectParent(currentObjectId));

  xsh->updateFrameCount();
  TUndoManager::manager()->add(
      new CloneChildUndo(newChildLevel, newColumnIndex));

  // notify changes
  TApp::instance()->getCurrentScene()->setDirtyFlag(true);
  TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}
Beispiel #23
0
void SkeletonTool::drawHooks()
{
	// camera stand reference system
	//glColor3d(0,0,1);
	//tglDrawRect(3,3,97,97);

	//glColor3d(0,1,1);
	//tglDrawRect(0,100,Stage::inch,110);

	QTime time;
	time.start();

	m_magicLinks.clear();
	computeMagicLinks();

	TTool::Application *app = TTool::getApplication();
	TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
	int row = app->getCurrentFrame()->getFrame();
	int col = app->getCurrentColumn()->getColumnIndex();
	TPointD dpiScale = getViewer()->getDpiScale();

	// glColor3d(1,0,1);
	// tglDrawRect(-100*dpiScale.x, -100*dpiScale.y, 0,0);

	// I should not show hooks of columns already connected with the current one
	// ("linking" to those hooks would create evil loops in the hierarchy)
	std::set<int> connectedColumns;
	getConnectedColumns(connectedColumns, xsh, col);

	std::vector<HookData> currentColumnHooks;
	std::vector<HookData> otherColumnsHooks;

	// fill currentColumnHooks
	// detect otherColumn (i.e. the active column during a click&drag operator
	int otherColumn = -1;
	if (m_parentProbeEnabled) {
		// qDebug("  parent probe enabled");
		// currentColumnHooks <- current column & current handle
		int hookId = 0;
		std::string handle = xsh->getStageObject(TStageObjectId::ColumnId(col))->getHandle();
		if (handle.find("H") == 0) {
			int j = 1;
			while (j < (int)handle.size() && '0' <= handle[j] && handle[j] <= '9') {
				hookId = hookId * 10 + (int)handle[j] - '0';
				j++;
			}
		}

		currentColumnHooks.push_back(HookData(xsh, col, hookId, m_parentProbe));

		// otherColumn = "picked" column not connected
		TPoint parentProbePos = getViewer()->worldToPos(m_parentProbe);
		std::vector<int> indexes;
		getViewer()->posToColumnIndexes(parentProbePos, indexes, getPixelSize() * 10, false);
		for (int i = (int)indexes.size() - 1; i >= 0; i--) {
			if (connectedColumns.count(indexes[i]) == 0) {
				otherColumn = indexes[i];
				break;
			}
		}
		// if the mouse is not on a stroke, I'm using the "old" m_otherColumn, if any.
		// (this is needed because of the hooks put inside of unfilled regions)
		if (otherColumn < 0 && m_otherColumn >= 0) {
			if (m_otherColumnBBox.contains(m_otherColumnBBoxAff.inv() * m_parentProbe))
				otherColumn = m_otherColumn;
			else
				m_otherColumn = -1;
		}
	} else {
		// parent probe not enabled: get all hooks of current column. other column = -1
		getHooks(currentColumnHooks, xsh, row, col, TPointD(1, 1)); // dpiScale);
	}

	// other columns hooks <- all hooks of all unlinked columns
	for (int i = 0; i < xsh->getColumnCount(); i++)
		if (xsh->getColumn(i)->isCamstandVisible())
			if (connectedColumns.count(i) == 0)
				getHooks(otherColumnsHooks, xsh, row, i, TPointD(1, 1)); // dpiScale);

	/*
  qDebug("  time=%dms", time.elapsed());
  qDebug("  %d hooks (current column)", currentColumnHooks.size());
  for(int i=0;i<(int)currentColumnHooks.size();i++)
    qDebug("    %d,%d",currentColumnHooks[i].m_columnIndex,currentColumnHooks[i].m_hookId);
  qDebug("  %d hooks (other columns)", otherColumnsHooks.size());
  for(int i=0;i<(int)otherColumnsHooks.size();i++)
    qDebug("    %d,%d",otherColumnsHooks[i].m_columnIndex,otherColumnsHooks[i].m_hookId);
*/

	std::vector<TRectD> balloons;

	// draw current column hooks
	for (int i = 0; i < (int)currentColumnHooks.size(); i++) {
		const HookData &hook = currentColumnHooks[i];
		if (hook.m_name == "")
			continue; // should not happen
		int code = TD_Hook + hook.m_hookId;
		TPointD pos = hook.m_pos;
		ToolUtils::drawHook(pos, ToolUtils::OtherLevelHook);
		glPushName(code);
		TPixel32 color(200, 220, 205, 200);
		if (hook.m_isPivot)
			color = TPixel32(200, 200, 10, 200);
		else if (code == m_device)
			color = TPixel32(185, 255, 255);
		ToolUtils::drawBalloon(pos, hook.m_name, color, TPoint(20, 20), isPicking(), &balloons);
		glPopName();
	}

	if (m_parentProbeEnabled) {
		for (int i = 0; i < (int)otherColumnsHooks.size(); i++)
			ToolUtils::drawHook(otherColumnsHooks[i].m_pos, ToolUtils::OtherLevelHook);
	}

	// search for magic links
	double minDist2 = 0;
	double snapRadius2 = 100 * getPixelSize() * getPixelSize();
	double snapRadius2bis = 100;

	if (!m_parentProbeEnabled) {
		// "static" magic links: no parent probe
		for (int i = 0; i < (int)currentColumnHooks.size(); i++) {
			for (int j = 0; j < (int)otherColumnsHooks.size(); j++) {
				double dist2 = norm2(currentColumnHooks[i].m_pos - otherColumnsHooks[j].m_pos);
				if (currentColumnHooks[i].m_hookId == 0 || otherColumnsHooks[j].m_hookId == 0)
					continue;
				if (dist2 < snapRadius2bis) {
					m_magicLinks.push_back(MagicLink(currentColumnHooks[i], otherColumnsHooks[j], dist2));

					qDebug("  magic link_a %d (%d,%d) %d (%d,%d); dist=%f",
						   i,
						   currentColumnHooks[i].m_columnIndex,
						   currentColumnHooks[i].m_hookId,
						   j,
						   otherColumnsHooks[j].m_columnIndex,
						   otherColumnsHooks[j].m_hookId,
						   dist2);
				}
			}
		}
	}

	if (m_parentProbeEnabled) {
		// search for the closest hook of the picked column
		int i = -1, j = -1;
		double minDist2 = snapRadius2;
		for (i = 0; i < (int)otherColumnsHooks.size(); i++) {
			double dist2 = tdistance2(otherColumnsHooks[i].m_pos, m_parentProbe);
			if (dist2 < minDist2) {
				j = i;
				minDist2 = dist2;
				otherColumn = otherColumnsHooks[i].m_columnIndex;
			}
		}
	}

	if (m_parentProbeEnabled && otherColumn >= 0) //  && m_magicLinks.empty()
	{
		// "dynamic" magic links: probing and picking a column

		// show image bounding box
		m_otherColumn = otherColumn;
		getImageBoundingBox(m_otherColumnBBox, m_otherColumnBBoxAff, row, otherColumn);
		if (!m_otherColumnBBox.isEmpty()) {
			glPushMatrix();
			tglMultMatrix(m_otherColumnBBoxAff);
			ToolUtils::drawRect(m_otherColumnBBox, TPixel32(188, 202, 191), 0xF0F0);
			//tglDrawRect(img->getBBox());
			glPopMatrix();
		}

		/*
    TXshCell cell = xsh->getCell(row, otherColumn);
    //TAffine aff = xsh->getPlacement(TStageObjectId::ColumnId(otherColumn),row);
    //m_otherColumnAff = aff;
    TImageP img = cell.getImage(false);
    if(img)
    {
      getImageBoundingBox(m_otherColumnBBox, m_otherColumnBBoxAff, row, otherColumn);
      //glColor3d(188.0/255.0, 202.0/255.0, 191.0/255.0);
      glPushMatrix();
      tglMultMatrix(aff * imageDpiAff);
      ToolUtils::drawRect(img->getBBox(), TPixel32(188,202,191), 0xF0F0);
      //tglDrawRect(img->getBBox());
      glPopMatrix();
    }
*/
		// search for the closest hook of the picked column
		int i = -1, j = -1;
		double minDist2 = snapRadius2;
		for (i = 0; i < (int)otherColumnsHooks.size(); i++)
			if (otherColumnsHooks[i].m_columnIndex == otherColumn) {
				double dist2 = tdistance2(otherColumnsHooks[i].m_pos, m_parentProbe);
				if (j < 0)
					j = i;
				else if (dist2 < minDist2 || otherColumnsHooks[i].m_hookId == 0) {
					j = i;
					minDist2 = dist2;
				}
			}
		// visualize a balloon for the closest hook
		if (0 <= j && j < (int)otherColumnsHooks.size()) {
			// I want to get a specific color when overlaying the label on white
			int alfa = 100, ialfa = 255 - alfa;
			TPixel32 color(255 * (188 - ialfa) / alfa, 255 * (202 - ialfa) / alfa, 255 * (191 - ialfa) / alfa, alfa);
			ToolUtils::drawBalloon(
				otherColumnsHooks[j].m_pos,
				otherColumnsHooks[j].m_name, // getHandle(),
				color,
				TPoint(20, 20),
				false,
				&balloons);

			HookData baseHook = currentColumnHooks[0];
			baseHook.m_pos = otherColumnsHooks[j].m_pos;

			// this is also a magic link
			m_magicLinks.push_back(MagicLink(baseHook, otherColumnsHooks[j], 10000));
		}
	}

	// visualize all the magic links

	for (int i = 0; i < (int)m_magicLinks.size(); i++) {
		const MagicLink &magicLink = m_magicLinks[i];
		const HookData &h1 = magicLink.m_h1;
		std::string name;
		name = (m_parentProbeEnabled ? "Linking " : "Link ") + removeTrailingH(magicLink.m_h0.getHandle()) +
			   " to Col " + std::to_string(h1.m_columnIndex + 1) + "/" + removeTrailingH(h1.getHandle());

		int code = TD_MagicLink + i;
		glPushName(code);
		TPixel32 color(100, 255, 100, 100);
		if (code == m_device)
			color = TPixel32(185, 255, 255);
		ToolUtils::drawBalloon(magicLink.m_h0.m_pos, name, color, TPoint(20, -20), isPicking(), &balloons);
		glPopName();
	}
}
Beispiel #24
0
QString TTool::updateEnabled() {
  // Disable every tool during playback
  if (m_application->getCurrentFrame()->isPlaying())
    return (enable(false), QString());

  // Release Generic tools at once
  int toolType   = getToolType();
  int targetType = getTargetType();

  if (toolType == TTool::GenericTool) return (enable(true), QString());

  // Retrieve vars and view modes
  TXsheet *xsh = m_application->getCurrentXsheet()->getXsheet();

  int rowIndex       = m_application->getCurrentFrame()->getFrame();
  int columnIndex    = m_application->getCurrentColumn()->getColumnIndex();
  TXshColumn *column = (columnIndex >= 0) ? xsh->getColumn(columnIndex) : 0;

  TXshLevel *xl       = m_application->getCurrentLevel()->getLevel();
  TXshSimpleLevel *sl = xl ? xl->getSimpleLevel() : 0;
  int levelType       = sl ? sl->getType() : NO_XSHLEVEL;

  TStageObject *obj =
      xsh->getStageObject(TStageObjectId::ColumnId(columnIndex));
  bool spline = m_application->getCurrentObject()->isSpline();

  bool filmstrip = m_application->getCurrentFrame()->isEditingLevel();

  /*-- MultiLayerStylePickerONのときは、現状に関わらず使用可能 --*/
  if (m_name == T_StylePicker &&
      Preferences::instance()->isMultiLayerStylePickerEnabled())
    return (enable(true), QString());

  // Check against unplaced columns (not in filmstrip mode)
  if (column && !filmstrip) {
    if (column->isLocked())
      return (enable(false), QObject::tr("The current column is locked."));

    else if (!column->isCamstandVisible())
      return (enable(false), QObject::tr("The current column is hidden."));

    else if (column->getSoundColumn())
      return (enable(false),
              QObject::tr("It is not possible to edit the audio column."));

    else if (column->getSoundTextColumn())
      return (
          enable(false),
          QObject::tr(
              "Note columns can only be edited in the xsheet or timeline."));

    if (toolType == TTool::ColumnTool) {
      // Check column target
      if (column->getLevelColumn() && !(targetType & LevelColumns))
        return (
            enable(false),
            QObject::tr("The current tool cannot be used on a Level column."));

      if (column->getMeshColumn() && !(targetType & MeshColumns))
        return (
            enable(false),
            QObject::tr("The current tool cannot be used on a Mesh column."));
    }
  }

  // Check column tools
  if (toolType == TTool::ColumnTool) {
    if (filmstrip)
      return (
          enable(false),
          QObject::tr("The current tool cannot be used in Level Strip mode."));

    if ((!column || column->isEmpty()) && !(targetType & TTool::EmptyTarget))
      return (enable(false), QString());
  }

  // Check LevelRead & LevelWrite tools
  if (toolType & TTool::LevelTool) {
    // Check against splines
    if (spline) {
      return (targetType & Splines)
                 ? (enable(true), QString())
                 : (enable(false), QObject::tr("The current tool cannot be "
                                               "used to edit a motion path."));
    }

    // Check against empty levels
    if (!xl)
      return (targetType & EmptyTarget) ? (enable(true), QString())
                                        : (enable(false), QString());

    // Check against simple-level-edness
    if (!sl)
      return (enable(false),
              QObject::tr("The current level is not editable."));  // Does it
                                                                   // happen at
                                                                   // all btw?

    // Check against level types
    {
      if ((levelType == PLI_XSHLEVEL) && !(targetType & VectorImage))
        return (
            enable(false),
            QObject::tr("The current tool cannot be used on a Vector Level."));

      if ((levelType == TZP_XSHLEVEL) && !(targetType & ToonzImage))
        return (
            enable(false),
            QObject::tr("The current tool cannot be used on a Toonz Level."));

      if ((levelType == OVL_XSHLEVEL) && !(targetType & RasterImage))
        return (
            enable(false),
            QObject::tr("The current tool cannot be used on a Raster Level."));

      if ((levelType == MESH_XSHLEVEL) && !(targetType & MeshImage))
        return (
            enable(false),
            QObject::tr("The current tool cannot be used on a Mesh Level."));
    }

    // Check against impossibly traceable movements on the column
    if ((levelType & LEVELCOLUMN_XSHLEVEL) && !filmstrip) {
      // Test for Mesh-deformed levels
      const TStageObjectId &parentId = obj->getParent();
      if (parentId.isColumn() && obj->getParentHandle()[0] != 'H') {
        TXshSimpleLevel *parentSl =
            xsh->getCell(rowIndex, parentId.getIndex()).getSimpleLevel();
        if (parentSl && parentSl->getType() == MESH_XSHLEVEL)
          return (
              enable(false),
              QObject::tr(
                  "The current tool cannot be used on a mesh-deformed level"));
      }
    }

    // Check TTool::ImageType tools
    if (toolType == TTool::LevelWriteTool) {
      // Check level against read-only status
      if (sl->isReadOnly()) {
        const std::set<TFrameId> &editableFrames = sl->getEditableRange();
        TFrameId currentFid                      = getCurrentFid();

        if (editableFrames.find(currentFid) == editableFrames.end())
          return (
              enable(false),
              QObject::tr(
                  "The current frame is locked: any editing is forbidden."));
      }

      // Check level type write support
      if (sl->getPath().getType() ==
              "psd" ||  // We don't have the API to write psd files
          sl->is16BitChannelLevel() ||  // Inherited by previous implementation.
                                        // Could be fixed?
          sl->getProperties()->getBpp() ==
              1)  // Black & White images. Again, could be fixed?

        return (enable(false),
                QObject::tr("The current level is not editable."));
    }
  }

  return (enable(true), QString());
}
bool LevelCreatePopup::apply() {
  TApp *app = TApp::instance();
  int row   = app->getCurrentFrame()->getFrame();
  int col   = app->getCurrentColumn()->getColumnIndex();
  int i, j;

  ToonzScene *scene = app->getCurrentScene()->getScene();
  TXsheet *xsh      = scene->getXsheet();

  bool validColumn = true;
  if (xsh->getColumn(col))
    validColumn =
        xsh->getColumn(col)->getColumnType() == TXshColumn::eLevelType;

  int from   = (int)m_fromFld->getValue();
  int to     = (int)m_toFld->getValue();
  int inc    = (int)m_incFld->getValue();
  int step   = (int)m_stepFld->getValue();
  double w   = m_widthFld->getValue();
  double h   = m_heightFld->getValue();
  double dpi = m_dpiFld->getValue();
  int xres   = std::max(tround(w * dpi), 1);
  int yres   = std::max(tround(h * dpi), 1);
  int lType  = getLevelType();

  std::wstring levelName = m_nameFld->text().toStdWString();
  // tolgo i blanks prima e dopo

  i = levelName.find_first_not_of(L' ');
  if (i == (int)std::wstring::npos)
    levelName = L"";
  else {
    int j = levelName.find_last_not_of(L' ');
    assert(j != (int)std::wstring::npos);
    levelName = levelName.substr(i, j - i + 1);
  }
  if (levelName.empty()) {
    error(tr("No level name specified: please choose a valid level name"));
    return false;
  }

  if (from > to) {
    error(tr("Invalid frame range"));
    return false;
  }
  if (inc <= 0) {
    error(tr("Invalid increment value"));
    return false;
  }
  if (step <= 0) {
    error(tr("Invalid step value"));
    return false;
  }

  int numFrames = step * (((to - from) / inc) + 1);

  if (scene->getLevelSet()->getLevel(levelName)) {
    error(
        tr("The level name specified is already used: please choose a "
           "different level name"));
    m_nameFld->selectAll();
    return false;
  }

  TFilePath parentDir(m_pathFld->getPath().toStdWString());
  TFilePath fp =
      scene->getDefaultLevelPath(lType, levelName).withParentDir(parentDir);

  TFilePath actualFp = scene->decodeFilePath(fp);
  if (TSystem::doesExistFileOrLevel(actualFp)) {
    error(
        tr("The level name specified is already used: please choose a "
           "different level name"));
    m_nameFld->selectAll();
    return false;
  }
  parentDir = scene->decodeFilePath(parentDir);
  if (!TFileStatus(parentDir).doesExist()) {
    QString question;
    /*question = "Folder " +toQString(parentDir) +
                                                     " doesn't exist.\nDo you
       want to create it?";*/
    question = tr("Folder %1 doesn't exist.\nDo you want to create it?")
                   .arg(toQString(parentDir));
    int ret = DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No"));
    if (ret == 0 || ret == 2) return false;
    try {
      TSystem::mkDir(parentDir);
      DvDirModel::instance()->refreshFolder(parentDir.getParentDir());
    } catch (...) {
      error(tr("Unable to create") + toQString(parentDir));
      return false;
    }
  }

  TXshLevel *level =
      scene->createNewLevel(lType, levelName, TDimension(), 0, fp);
  TXshSimpleLevel *sl = dynamic_cast<TXshSimpleLevel *>(level);
  assert(sl);
  sl->setPath(fp, true);
  if (lType == TZP_XSHLEVEL || lType == OVL_XSHLEVEL) {
    sl->getProperties()->setDpiPolicy(LevelProperties::DP_ImageDpi);
    sl->getProperties()->setDpi(dpi);
    sl->getProperties()->setImageDpi(TPointD(dpi, dpi));
    sl->getProperties()->setImageRes(TDimension(xres, yres));
  }

  /*-- これからLevelを配置しようとしているセルが空いているかどうかのチェック
   * --*/
  bool areColumnsShifted = false;
  TXshCell cell          = xsh->getCell(row, col);
  bool isInRange         = true;
  for (i = row; i < row + numFrames; i++) {
    if (!cell.isEmpty()) {
      isInRange = false;
      break;
    }
    cell = xsh->getCell(i, col);
  }
  if (!validColumn) {
    isInRange = false;
  }

  /*-- 別のLevelに占有されていた場合、Columnを1つ右に移動 --*/
  if (!isInRange) {
    col += 1;
    TApp::instance()->getCurrentColumn()->setColumnIndex(col);
    areColumnsShifted = true;
    xsh->insertColumn(col);
  }

  CreateLevelUndo *undo =
      new CreateLevelUndo(row, col, numFrames, step, areColumnsShifted);
  TUndoManager::manager()->add(undo);

  for (i = from; i <= to; i += inc) {
    TFrameId fid(i);
    TXshCell cell(sl, fid);
    if (lType == PLI_XSHLEVEL)
      sl->setFrame(fid, new TVectorImage());
    else if (lType == TZP_XSHLEVEL) {
      TRasterCM32P raster(xres, yres);
      raster->fill(TPixelCM32());
      TToonzImageP ti(raster, TRect());
      ti->setDpi(dpi, dpi);
      sl->setFrame(fid, ti);
      ti->setSavebox(TRect(0, 0, xres - 1, yres - 1));
    } else if (lType == OVL_XSHLEVEL) {
      TRaster32P raster(xres, yres);
      raster->clear();
      TRasterImageP ri(raster);
      ri->setDpi(dpi, dpi);
      sl->setFrame(fid, ri);
    }
    for (j = 0; j < step; j++) xsh->setCell(row++, col, cell);
  }

  if (lType == TZP_XSHLEVEL || lType == OVL_XSHLEVEL) {
    sl->save(fp);
    DvDirModel::instance()->refreshFolder(fp.getParentDir());
  }

  undo->onAdd(sl);

  app->getCurrentScene()->notifySceneChanged();
  app->getCurrentScene()->notifyCastChange();
  app->getCurrentXsheet()->notifyXsheetChanged();

  // Cambia l'immagine corrente ma non cambiano ne' il frame ne' la colonna
  // corrente
  // (entrambi notificano il cambiamento dell'immagine al tool).
  // devo verfificare che sia settato il tool giusto.
  app->getCurrentTool()->onImageChanged(
      (TImage::Type)app->getCurrentImageType());
  return true;
}
Beispiel #26
0
void mergeColumns(int column, int mColumn, bool isRedo)
{
	MergeColumnsSessionId++;
	TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
	int start, end;
	xsh->getCellRange(column, start, end);

	if (start > end)
		return;
	vector<TXshCell> cell(end - start + 1);
	vector<TXshCell> mCell(end - start + 1);

	xsh->getCells(start, column, cell.size(), &(cell[0]));

	xsh->getCells(start, mColumn, cell.size(), &(mCell[0]));

	TXshColumn *col = xsh->getColumn(column);
	TXshColumn *mcol = xsh->getColumn(mColumn);

	vector<MatchlinePair> matchingLevels;

	std::set<TFrameId> alreadyDoneSet;

	TXshSimpleLevel *level = 0, *mLevel = 0;
	TXshLevelP xl;
	bool areRasters = false;

	std::map<TFrameId, QString> images;

	for (int i = 0; i < (int)cell.size(); i++) {
		if (cell[i].isEmpty() || mCell[i].isEmpty())
			continue;
		if (!level) {
			level = cell[i].getSimpleLevel();
			xl = cell[i].m_level;
		}

		else if (level != cell[i].getSimpleLevel()) {
			MsgBox(WARNING, QObject::tr("It is not possible to perform a merging involving more than one level per column."));
			return;
		}

		if (!mLevel)
			mLevel = mCell[i].getSimpleLevel();
		else if (mLevel != mCell[i].getSimpleLevel()) {
			MsgBox(WARNING, QObject::tr("It is not possible to perform a merging involving more than one level per column."));
			return;
		}
		TImageP img = cell[i].getImage(true);
		TImageP match = mCell[i].getImage(false);
		TFrameId fid = cell[i].m_frameId;
		TFrameId mFid = mCell[i].m_frameId;

		if (!img || !match)
			continue;

		if (alreadyDoneSet.find(fid) == alreadyDoneSet.end()) {
			TRasterImageP timg = (TRasterImageP)img;
			TRasterImageP tmatch = (TRasterImageP)match;
			TVectorImageP vimg = (TVectorImageP)img;
			TVectorImageP vmatch = (TVectorImageP)match;

			if (timg) {
				if (!tmatch) {
					MsgBox(WARNING, QObject::tr("Only raster levels can be merged to a raster level."));
					return;
				}
				areRasters = true;
			} else if (vimg) {
				if (!vmatch) {
					MsgBox(WARNING, QObject::tr("Only vector levels can be merged to a vector level."));
					return;
				}
			} else {
				MsgBox(WARNING, QObject::tr("It is possible to merge only Toonz vector levels or standard raster levels."));
				return;
			}

			QString id = "MergeColumnsUndo" + QString::number(MergeColumnsSessionId) + "-" + QString::number(fid.getNumber());
			TImageCache::instance()->add(id, (timg) ? timg->cloneImage() : vimg->cloneImage());
			images[fid] = id;
			TAffine imgAff, matchAff;
			getColumnPlacement(imgAff, xsh, start + i, column, false);
			getColumnPlacement(matchAff, xsh, start + i, mColumn, false);
			TAffine dpiAff = getDpiAffine(level, fid);
			TAffine mdpiAff = getDpiAffine(mLevel, mFid);
			matchingLevels.push_back(MatchlinePair(cell[i], imgAff * dpiAff, mCell[i], matchAff * mdpiAff));
			alreadyDoneSet.insert(fid);
		}
	}

	if (matchingLevels.empty()) {
		MsgBox(WARNING, QObject::tr("It is possible to merge only Toonz vector levels or standard raster levels."));
		return;
	}

	ToonzScene *sc = TApp::instance()->getCurrentScene()->getScene();
	TXshSimpleLevel *simpleLevel = sc->getLevelSet()->getLevel(column)->getSimpleLevel();

	if (!isRedo)
		TUndoManager::manager()->add(new MergeColumnsUndo(xl, MergeColumnsSessionId,
														  column, level, images,
														  mColumn, level->getPalette()));

	if (areRasters) {
		mergeRasterColumns(matchingLevels);
		for (int i = 0; i < (int)cell.size(); i++) //the saveboxes must be updated
		{
			if (cell[i].isEmpty() || mCell[i].isEmpty())
				continue;

			if (!cell[i].getImage(false) || !mCell[i].getImage(false))
				continue;

			ToolUtils::updateSaveBox(cell[i].getSimpleLevel(), cell[i].m_frameId);
		}
	} else
		mergeVectorColumns(matchingLevels);

	TXshLevel *sl = TApp::instance()->getCurrentScene()->getScene()->getLevelSet()->getLevel(column);
	vector<TFrameId> fidsss;
	sl->getFids(fidsss);
	invalidateIcons(sl, fidsss);
	sl->setDirtyFlag(true);
	level->setDirtyFlag(true);
	TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}
void SceneViewerContextMenu::addLevelCommands(std::vector<int> &indices) {
  addSeparator();
  TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
  TStageObjectId currentId =
      TApp::instance()->getCurrentObject()->getObjectId();

  /*- Xsheet内の、空でないColumnを登録 -*/
  std::vector<TXshColumn *> columns;
  for (int i = 0; i < (int)indices.size(); i++) {
    if (xsh->isColumnEmpty(indices[i])) continue;
    TXshColumn *column = xsh->getColumn(indices[i]);
    if (column) {
      columns.push_back(column);
    }
  }

  if (!columns.empty()) {
    // show/hide
    if (columns.size() > 1) {
      QMenu *subMenu = addMenu("Show / Hide");
      for (int i = 0; i < (int)columns.size(); i++)
        addShowHideCommand(subMenu, columns[i]);
    } else
      addShowHideCommand(this, columns[0]);
    addSeparator();
  }

  // selection
  /*
    if(selectableColumns.size()==1)
    {
      addSelectCommand(this,
    TStageObjectId::ColumnId(selectableColumns[0]->getIndex()));
    }
    else
    */

  /*-- Scene内の全Objectを選択可能にする --*/
  TStageObjectId id;
  QMenu *cameraMenu = addMenu(tr("Select Camera"));
  QMenu *pegbarMenu = addMenu(tr("Select Pegbar"));
  QMenu *columnMenu = addMenu(tr("Select Column"));

  bool flag = false;

  for (int i = 0; i < xsh->getStageObjectTree()->getStageObjectCount(); i++) {
    id = xsh->getStageObjectTree()->getStageObject(i)->getId();
    if (id.isColumn()) {
      int columnIndex = id.getIndex();
      if (xsh->isColumnEmpty(columnIndex))
        continue;
      else {
        addSelectCommand(columnMenu, id);
        flag = true;
      }
    } else if (id.isTable())
      addSelectCommand(this, id);
    else if (id.isCamera())
      addSelectCommand(cameraMenu, id);
    else if (id.isPegbar())
      addSelectCommand(pegbarMenu, id);
  }

  /*- カラムがひとつも無かったらDisable -*/
  if (!flag) columnMenu->setEnabled(false);
}
Beispiel #28
0
void LevelMoverTool::onCellChange(int row, int col) {
  TXsheet *xsh = getViewer()->getXsheet();

  TPoint pos           = TPoint(col, row) + m_grabOffset;
  if (pos.y < 0) pos.y = 0;
  if (pos.x < 0) return;
  if (pos == m_aimedPos) return;

  m_aimedPos   = pos;
  TPoint delta = m_aimedPos - m_lastPos;

  m_validPos = canMoveColumns(pos);
  if (!m_validPos) return;

  CellsMover *cellsMover = m_undo->getCellsMover();
  if (m_moved) cellsMover->undoMoveCells();
  m_validPos = canMove(pos);

  if (m_validPos) {
    //----------------------
    if (delta.x != 0 && (m_qualifiers & CellsMover::eMoveColumns)) {
      // spostamento di colonne
      int colCount = m_range.lx;

      bool emptySrc = true;
      for (int i = 0; i < colCount; i++) {
        TXshColumn *column = xsh->getColumn(m_lastPos.x + i);
        if (column && !column->isEmpty()) {
          emptySrc = false;
          break;
        }
      }

      bool lockedDst = false;
      bool emptyDst  = true;
      for (int i = 0; i < colCount; i++) {
        if (!isTotallyEmptyColumn(pos.x + i)) emptyDst = false;
        TXshColumn *column                          = xsh->getColumn(pos.x + i);
        if (column && column->isLocked()) lockedDst = true;
      }

      if (emptySrc) {
        if (m_lastPos.x == m_startPos.x)
          m_undo->getCellsMover()->m_uffa |=
              1;  // first column(s) has/have been cleared
        cellsMover->emptyColumns(m_lastPos.x);
      }

      if (emptyDst && !lockedDst) {
        if (pos.x == m_startPos.x)
          m_undo->getCellsMover()->m_uffa &=
              ~1;  // first column(s) has/have been restored
        else
          m_undo->getCellsMover()->m_uffa |=
              2;  // columns data have been copied on the current position
        cellsMover->restoreColumns(pos.x);
      } else {
        m_undo->getCellsMover()->m_uffa &=
            ~2;  // no columns data have been copied on the current position
      }
    }

    //----------------------

    m_lastPos = pos;
    cellsMover->setPos(pos.y, pos.x);
    cellsMover->saveCells();
    cellsMover->moveCells();
    m_moved = true;
  } else {
    cellsMover->moveCells();
  }

  xsh->updateFrameCount();
  TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
  if (cellsMover->getColumnTypeFromCell(0) == TXshColumn::eSoundType)
    TApp::instance()->getCurrentXsheet()->notifyXsheetSoundChanged();
  TRect selection(m_aimedPos, m_range);
  getViewer()->getCellSelection()->selectCells(selection.y0, selection.x0,
                                               selection.y1, selection.x1);
}
 void restoreColumns(ToonzScene *scene, const QList<bool> &oldStatus) {
   TXsheet *xsh = scene->getXsheet();
   for (int i = 0; i < oldStatus.length(); i++) {
     xsh->getColumn(i)->setPreviewVisible(oldStatus[i]);
   }
 }
Beispiel #30
0
void mergeCmapped(int column, int mColumn, const QString &fullpath, bool isRedo)
{
	static int MergeCmappedSessionId = 0;
	MergeCmappedSessionId++;

	TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
	int start, end;
	int mStart, mEnd;
	xsh->getCellRange(column, start, end);
	xsh->getCellRange(mColumn, mStart, mEnd);

	if (start > end)
		return;
	vector<TXshCell> cell(max(end, mEnd) - min(start, mStart) + 1);
	vector<TXshCell> mCell(cell.size());

	xsh->getCells(min(start, mStart), column, cell.size(), &(cell[0]));

	if (mColumn != -1)
		xsh->getCells(min(start, mStart), mColumn, cell.size(), &(mCell[0]));

	TXshColumn *col = xsh->getColumn(column);
	TXshColumn *mcol = xsh->getColumn(mColumn);

	vector<MergeCmappedPair> matchingLevels;

	std::map<MergedPair, TFrameId> computedMergedMap;

	TXshSimpleLevel *level = 0, *mLevel = 0;
	TXshLevel *xl;

	std::map<TFrameId, QString> images;
	double dpix = 0, dpiy = 0;
	for (int i = 0; i < (int)cell.size(); i++) {
		if (!cell[i].isEmpty() && dpix == 0)
			((TToonzImageP)(cell[i].getImage(false)))->getDpi(dpix, dpiy);

		if (!level) {
			level = cell[i].getSimpleLevel();
			xl = cell[i].m_level.getPointer();
		}
		if (!mLevel)
			mLevel = mCell[i].getSimpleLevel();
	}

	if (!level || !mLevel)
		return;

	TFilePath fp(fullpath.toStdString());

	TXshLevel *txl = level->getScene()->createNewLevel(level->getType(), fp.getWideName(), level->getResolution());
	TXshSimpleLevel *newLevel = txl->getSimpleLevel();
	newLevel->setPalette(level->getPalette());
	newLevel->clonePropertiesFrom(level);
	newLevel->setPath(fp);

	TApp::instance()->getCurrentScene()->notifySceneChanged();
	TApp::instance()->getCurrentScene()->notifyCastChange();
	TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();

	int count = 0;
	for (int i = 0; i < (int)cell.size(); i++) {
		if (cell[i].isEmpty() && mCell[i].isEmpty())
			continue;

		TAffine imgAff, matchAff;

		getColumnPlacement(imgAff, xsh, min(start, mStart) + i, column, false);
		getColumnPlacement(matchAff, xsh, min(start, mStart) + i, mColumn, false);

		//std::map<TFrameId, TFrameId>::iterator it;
		MergedPair mp(cell[i].isEmpty() ? TFrameId() : cell[i].getFrameId(),
					  mCell[i].isEmpty() ? TFrameId() : mCell[i].getFrameId(),
					  imgAff.inv() * matchAff);

		std::map<MergedPair, TFrameId>::iterator computedMergedIt = computedMergedMap.find(mp);

		if (computedMergedIt != computedMergedMap.end()) {
			TXshCell newCell(newLevel, computedMergedIt->second);
			xsh->setCell(i, column, newCell);
			cell[i] = newCell;
			continue;
		}

		TFrameId newFid(++count); //level->getLastFid().getNumber()+1);
		TDimension dim = level->getResolution();
		TToonzImageP newImage;
		if (cell[i].isEmpty()) {
			newImage = TToonzImageP(TRasterCM32P(dim), TRect(0, 0, dim.lx - 1, dim.ly - 1));
			newImage->setDpi(dpix, dpiy);
		} else
			newImage = (TToonzImageP)(cell[i].getImage(false)->cloneImage());

		newImage->setPalette(level->getPalette());

		newLevel->setFrame(newFid, newImage);
		TXshCell newCell(newLevel, newFid);
		xsh->setCell(i, column, newCell);
		computedMergedMap[mp] = newCell.getFrameId();

		cell[i] = newCell;

		TImageP img = cell[i].getImage(true);
		TImageP match = mCell[i].getImage(true);
		TFrameId fid = cell[i].m_frameId;
		TFrameId mFid = mCell[i].m_frameId;

		if (!img || !match)
			continue;

		TToonzImageP timg = (TToonzImageP)img;
		TToonzImageP tmatch = (TToonzImageP)match;

		QString id = "MergeCmappedUndo" + QString::number(MergeCmappedSessionId) + "-" + QString::number(fid.getNumber());
		TImageCache::instance()->add(id, timg->clone());
		images[fid] = id;

		TAffine dpiAff = getDpiAffine(level, fid);
		TAffine mdpiAff = getDpiAffine(mLevel, mFid);
		matchingLevels.push_back(MergeCmappedPair(cell[i], imgAff * dpiAff, mCell[i], matchAff * mdpiAff));
	}

	if (!isRedo) {
		TPalette *plt = level->getPalette();

		TPaletteHandle *pltHandle = new TPaletteHandle();
		pltHandle->setPalette(plt);
		int styleCount = plt->getStyleCount();

		TUndoManager::manager()->add(new MergeCmappedUndo(txl, MergeCmappedSessionId,
														  column,
														  level, images,
														  mColumn,
														  plt));
	}

	removeLevel(xl);
	QApplication::setOverrideCursor(Qt::WaitCursor);
	mergeCmapped(matchingLevels);
	QApplication::restoreOverrideCursor();

	for (int i = 0; i < (int)cell.size(); i++) //the saveboxes must be updated
	{
		if (cell[i].isEmpty() || mCell[i].isEmpty())
			continue;

		if (!cell[i].getImage(false) || !mCell[i].getImage(false))
			continue;

		TXshSimpleLevel *sl = cell[i].getSimpleLevel();
		const TFrameId &fid = cell[i].m_frameId;

		ToolUtils::updateSaveBox(sl, fid);
		IconGenerator::instance()->invalidate(sl, fid);
		sl->setDirtyFlag(true);
	}

	newLevel->setDirtyFlag(true);
	TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}