Merge pull request #875 from manongjohn/implicit_hold_fixes_2
Implicit hold fixes 2
This commit is contained in:
commit
d4ab9b4c7a
26 changed files with 399 additions and 258 deletions
|
@ -348,11 +348,13 @@ Return true if cell in \b row is empty.
|
|||
*/
|
||||
bool isCellEmpty(int row) const override;
|
||||
|
||||
bool isCellImplicit(int row) const;
|
||||
|
||||
/*!
|
||||
Return cell in \b row.
|
||||
\sa getCells and setCell()
|
||||
*/
|
||||
virtual const TXshCell &getCell(int row) const;
|
||||
virtual const TXshCell &getCell(int row, bool implicitLookup = true) const;
|
||||
/*!
|
||||
Set cell in \b row to \b TXshCell \b cell.
|
||||
\sa setCells() and getCell(); return false if cannot set cells.
|
||||
|
|
|
@ -192,9 +192,10 @@ public:
|
|||
an empty cell.
|
||||
\sa setCell(), getCells(), setCells()
|
||||
*/
|
||||
const TXshCell &getCell(int row, int col) const;
|
||||
const TXshCell &getCell(int row, int col, bool implicitLookup = true) const;
|
||||
|
||||
const TXshCell &getCell(const CellPosition &pos) const;
|
||||
const TXshCell &getCell(const CellPosition &pos,
|
||||
bool implicitLookup = true) const;
|
||||
|
||||
bool isImplicitCell(int row, int col) const;
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ public:
|
|||
/*! Return min row not empty.*/
|
||||
int getFirstRow() const override;
|
||||
|
||||
const TXshCell &getCell(int row) const override;
|
||||
const TXshCell &getCell(int row, bool implicitLookup = false) const override;
|
||||
TXshCell getSoundCell(int row);
|
||||
void getCells(int row, int rowCount, TXshCell cells[]) override;
|
||||
|
||||
|
|
|
@ -1347,9 +1347,11 @@ bool RasterSelection::isEditable() {
|
|||
// 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 false;
|
||||
TXshCell cell = xsh->getCell(rowIndex, parentId.getIndex());
|
||||
TXshSimpleLevel *parentSl = cell.getSimpleLevel();
|
||||
if (!cell.getFrameId().isStopFrame() && parentSl &&
|
||||
parentSl->getType() == MESH_XSHLEVEL)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -786,9 +786,11 @@ bool StrokeSelection::isEditable() {
|
|||
// 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 false;
|
||||
TXshCell cell = xsh->getCell(rowIndex, parentId.getIndex());
|
||||
TXshSimpleLevel *parentSl = cell.getSimpleLevel();
|
||||
if (!cell.getFrameId().isStopFrame() && parentSl &&
|
||||
parentSl->getType() == MESH_XSHLEVEL)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -385,8 +385,8 @@ TImage *TTool::touchImage() {
|
|||
// measure the hold length (starting from the current row) : r0-r1
|
||||
int r0 = row, r1 = row;
|
||||
if (isAutoStretchEnabled)
|
||||
while (xsh->getCell(r1 + 1, col) == cell &&
|
||||
!xsh->isImplicitCell(r1 + 1, col))
|
||||
while (!cell.getFrameId().isStopFrame() &&
|
||||
xsh->getCell(r1 + 1, col, false) == cell)
|
||||
r1++;
|
||||
// find the proper frameid (possibly addisng suffix, in order to avoid a
|
||||
// fid already used)
|
||||
|
@ -465,6 +465,8 @@ TImage *TTool::touchImage() {
|
|||
while (a >= r0 && xsh->getCell(a, col).isEmpty()) a--;
|
||||
while (b <= r1 && xsh->getCell(b, col).isEmpty()) b++;
|
||||
|
||||
if (a >= r0 && xsh->getCell(a, col).getFrameId().isStopFrame()) a = r0 - 1;
|
||||
|
||||
// find the level we must attach to
|
||||
if (a >= r0) {
|
||||
// there is a not-empty cell before the current one
|
||||
|
|
|
@ -153,9 +153,8 @@ AutoInputCellNumberUndo::AutoInputCellNumberUndo(int increment, int interval,
|
|||
TXsheetP xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
for (int c = 0; c < m_columnIndices.size(); ++c) {
|
||||
for (int r = m_r0; r <= rowUpTo; ++r) {
|
||||
const TXshCell &cell = xsh->getCell(r, m_columnIndices.at(c));
|
||||
m_beforeCells[k++] =
|
||||
xsh->isImplicitCell(r, m_columnIndices.at(c)) ? TXshCell() : cell;
|
||||
const TXshCell &cell = xsh->getCell(r, m_columnIndices.at(c), false);
|
||||
m_beforeCells[k++] = cell;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -165,9 +164,8 @@ AutoInputCellNumberUndo::AutoInputCellNumberUndo(int increment, int interval,
|
|||
int k = 0;
|
||||
TXsheetP xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
for (int c = 0; c < m_columnIndices.size(); ++c) {
|
||||
const TXshCell &cell = xsh->getCell(m_r0, m_columnIndices.at(c));
|
||||
m_beforeCells[k++] =
|
||||
xsh->isImplicitCell(m_r0, m_columnIndices.at(c)) ? TXshCell() : cell;
|
||||
const TXshCell &cell = xsh->getCell(m_r0, m_columnIndices.at(c), false);
|
||||
m_beforeCells[k++] = cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2897,8 +2897,7 @@ void TCellSelection::stopFrameHold(int row, int col, bool multiple) {
|
|||
return;
|
||||
}
|
||||
|
||||
TXshCell cell;
|
||||
if (!xsh->isImplicitCell(row, col)) cell = xsh->getCell(row, col);
|
||||
TXshCell cell = xsh->getCell(row, col, false);
|
||||
|
||||
StopFrameHoldUndo *undo = new StopFrameHoldUndo(lvl, row, col, cell);
|
||||
TUndoManager::manager()->add(undo);
|
||||
|
|
|
@ -213,10 +213,14 @@ void IncrementUndo::undo() const {
|
|||
xsh->removeCells(r.x0, r.y0, size);
|
||||
else {
|
||||
xsh->insertCells(r.x0, r.y0, size);
|
||||
for (int j = 0; j < size; ++j)
|
||||
for (int j = 0; j < size; ++j) {
|
||||
if (j > 0 && Preferences::instance()->isImplicitHoldEnabled())
|
||||
xsh->setCell(r.x0 + j, r.y0, TXshCell(0, TFrameId::EMPTY_FRAME));
|
||||
else
|
||||
xsh->setCell(r.x0 + j, r.y0, m_undoCells[i].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
|
||||
TApp::instance()->getCurrentScene()->setDirtyFlag(true);
|
||||
|
@ -391,8 +395,8 @@ StepUndo::StepUndo(int r0, int c0, int r1, int c1, int step)
|
|||
int k = 0;
|
||||
for (int r = r0; r <= r1; ++r)
|
||||
for (int c = c0; c <= c1; ++c) {
|
||||
const TXshCell &cell = xsh->getCell(r, c);
|
||||
m_cells[k++] = xsh->isImplicitCell(r, c) ? TXshCell() : cell;
|
||||
const TXshCell &cell = xsh->getCell(r, c, false);
|
||||
m_cells[k++] = cell;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -495,8 +499,8 @@ EachUndo::EachUndo(int r0, int c0, int r1, int c1, int each)
|
|||
TXsheetP xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
for (int r = r0; r <= r1; ++r)
|
||||
for (int c = c0; c <= c1; ++c) {
|
||||
const TXshCell &cell = xsh->getCell(r, c);
|
||||
m_cells[k++] = xsh->isImplicitCell(r, c) ? TXshCell() : cell;
|
||||
const TXshCell &cell = xsh->getCell(r, c, false);
|
||||
m_cells[k++] = cell;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -611,9 +615,8 @@ ReframeUndo::ReframeUndo(int r0, int r1, std::vector<int> columnIndeces,
|
|||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
for (int r = r0; r <= (r1 + 1); r++)
|
||||
for (int c = 0; c < (int)m_columnIndeces.size(); c++) {
|
||||
const TXshCell &cell = xsh->getCell(r, m_columnIndeces[c]);
|
||||
m_cells[k++] =
|
||||
xsh->isImplicitCell(r, m_columnIndeces[c]) ? TXshCell() : cell;
|
||||
const TXshCell &cell = xsh->getCell(r, m_columnIndeces[c], false);
|
||||
m_cells[k++] = cell;
|
||||
}
|
||||
|
||||
m_newRows.clear();
|
||||
|
@ -847,7 +850,7 @@ ResetStepUndo::ResetStepUndo(int r0, int c0, int r1, int c1)
|
|||
TXsheetP xsh = app->getCurrentXsheet()->getXsheet();
|
||||
for (int r = r0; r <= r1; ++r) {
|
||||
const TXshCell &cell = xsh->getCell(r, c);
|
||||
m_cells[k++] = xsh->isImplicitCell(r, c) ? TXshCell() : cell;
|
||||
m_cells[k++] = xsh->getCell(r, c, false);
|
||||
|
||||
if (prevCell != cell) {
|
||||
prevCell = cell;
|
||||
|
@ -947,7 +950,7 @@ IncreaseStepUndo::IncreaseStepUndo(int r0, int c0, int r1, int c1)
|
|||
TXsheetP xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
for (int r = r0; r <= r1; ++r) {
|
||||
const TXshCell &cell = xsh->getCell(r, c);
|
||||
m_cells[k++] = xsh->isImplicitCell(r, c) ? TXshCell() : cell;
|
||||
m_cells[k++] = xsh->getCell(r, c, false);
|
||||
|
||||
if (prevCell != cell) {
|
||||
prevCell = cell;
|
||||
|
@ -1062,11 +1065,11 @@ DecreaseStepUndo::DecreaseStepUndo(int r0, int c0, int r1, int c1)
|
|||
m_removedCells[c] = 0;
|
||||
|
||||
bool removed = false;
|
||||
m_cells[k++] = xsh->isImplicitCell(r0, c) ? TXshCell() : prevCell;
|
||||
m_cells[k++] = xsh->getCell(r0, c, false);
|
||||
|
||||
for (int r = r0 + 1; r <= r1; ++r) {
|
||||
const TXshCell &cell = xsh->getCell(r, c);
|
||||
m_cells[k++] = xsh->isImplicitCell(r, c) ? TXshCell() : cell;
|
||||
m_cells[k++] = xsh->getCell(r, c, false);
|
||||
|
||||
if (prevCell == cell) {
|
||||
if (!removed) {
|
||||
|
@ -1610,16 +1613,9 @@ void CloneLevelUndo::insertCells() const {
|
|||
// Now, re-traverse the selected range, and add corresponding cells
|
||||
// in the destination range
|
||||
for (int c = m_range.m_c0; c <= m_range.m_c1; ++c) {
|
||||
TXshCell prevCell;
|
||||
TXshLevelP lastLevel = 0;
|
||||
for (int r = m_range.m_r0; r <= m_range.m_r1; ++r) {
|
||||
TXshCell srcCell = xsh->getCell(r, c);
|
||||
if (useImplicitHold) {
|
||||
if (r > m_range.m_r0 &&
|
||||
(prevCell == srcCell || xsh->isImplicitCell(r, c)))
|
||||
srcCell = TXshCell();
|
||||
prevCell = srcCell;
|
||||
}
|
||||
TXshCell srcCell = xsh->getCell(r, c, false);
|
||||
if (TXshSimpleLevel *srcSl = srcCell.getSimpleLevel()) {
|
||||
std::map<TXshSimpleLevel *, TXshLevelP>::iterator lt =
|
||||
m_insertedLevels.find(srcSl);
|
||||
|
|
|
@ -322,8 +322,7 @@ bool beforeCellsInsert(TXsheet *xsh, int row, int &col, int rowCount,
|
|||
int i = 0;
|
||||
TXshColumn *column = xsh->getColumn(col);
|
||||
|
||||
for (i = 0; i < rowCount && (xsh->getCell(row + i, col).isEmpty() ||
|
||||
xsh->isImplicitCell(row + i, col));
|
||||
for (i = 0; i < rowCount && (xsh->getCell(row + i, col, false).isEmpty());
|
||||
i++) {
|
||||
}
|
||||
int type = (column && !column->isEmpty()) ? column->getColumnType()
|
||||
|
@ -510,8 +509,7 @@ public:
|
|||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
for (c = m_col0; c <= m_col1; c++)
|
||||
for (r = m_row0; r <= m_row1; r++) {
|
||||
TXshCell cell;
|
||||
if (!xsh->isImplicitCell(r, c)) cell = xsh->getCell(r, c);
|
||||
TXshCell cell = xsh->getCell(r, c, false);
|
||||
TXshSimpleLevel *oldLevel = cell.getSimpleLevel();
|
||||
TFrameId fid = cell.getFrameId();
|
||||
QPair<int, int> cellId(r, c);
|
||||
|
|
|
@ -2018,6 +2018,10 @@ void MainWindow::defineActions() {
|
|||
createMenuXsheetAction(MI_RemoveGlobalKeyframe,
|
||||
QT_TR_NOOP("Remove Multiple Keys"), "",
|
||||
"remove_multiple_keys");
|
||||
createMenuXsheetAction(MI_SetGlobalStopframe,
|
||||
QT_TR_NOOP("Set Multiple Stop Frames"), "");
|
||||
createMenuXsheetAction(MI_RemoveGlobalStopframe,
|
||||
QT_TR_NOOP("Remove Multiple Stop Frames"), "");
|
||||
createMenuXsheetAction(MI_RemoveEmptyColumns,
|
||||
QT_TR_NOOP("Remove Empty Columns"), "",
|
||||
"remove_empty_columns");
|
||||
|
|
|
@ -429,6 +429,8 @@ void TopBar::loadMenubar() {
|
|||
addMenuItem(sceneMenu, MI_RemoveSceneFrame);
|
||||
addMenuItem(sceneMenu, MI_InsertGlobalKeyframe);
|
||||
addMenuItem(sceneMenu, MI_RemoveGlobalKeyframe);
|
||||
addMenuItem(sceneMenu, MI_SetGlobalStopframe);
|
||||
addMenuItem(sceneMenu, MI_RemoveGlobalStopframe);
|
||||
sceneMenu->addSeparator();
|
||||
addMenuItem(sceneMenu, MI_LipSyncPopup);
|
||||
sceneMenu->addSeparator();
|
||||
|
|
|
@ -137,6 +137,8 @@
|
|||
|
||||
#define MI_InsertGlobalKeyframe "MI_InsertGlobalKeyframe"
|
||||
#define MI_RemoveGlobalKeyframe "MI_RemoveGlobalKeyframe"
|
||||
#define MI_SetGlobalStopframe "MI_SetGlobalStopframe"
|
||||
#define MI_RemoveGlobalStopframe "MI_RemoveGlobalStopframe"
|
||||
#define MI_DrawingSubForward "MI_DrawingSubForward"
|
||||
#define MI_DrawingSubBackward "MI_DrawingSubBackward"
|
||||
#define MI_DrawingSubGroupForward "MI_DrawingSubGroupForward"
|
||||
|
|
|
@ -1617,15 +1617,16 @@ bool changeFrameSkippingHolds(QKeyEvent *e) {
|
|||
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
||||
TXshCell cell = xsh->getCell(row, col);
|
||||
if (e->key() == Qt::Key_Down) {
|
||||
if (cell.isEmpty()) {
|
||||
int r0, r1;
|
||||
if (xsh->getCellRange(col, r0, r1)) {
|
||||
bool range = xsh->getCellRange(col, r0, r1);
|
||||
if (cell.isEmpty()) {
|
||||
if (range) {
|
||||
while (row <= r1 && xsh->getCell(row, col).isEmpty()) row++;
|
||||
if (xsh->getCell(row, col).isEmpty()) return false;
|
||||
} else
|
||||
return false;
|
||||
} else {
|
||||
while (xsh->getCell(row, col) == cell) row++;
|
||||
while (row <= r1 && xsh->getCell(row, col) == cell) row++;
|
||||
}
|
||||
} else {
|
||||
// Key_Up
|
||||
|
|
|
@ -68,8 +68,8 @@ public:
|
|||
TXsheetP xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
for (int c = c0; c <= c1; c++)
|
||||
for (int r = r0; r <= r1; r++) {
|
||||
const TXshCell &cell = xsh->getCell(r, c);
|
||||
m_cells[k++] = xsh->isImplicitCell(r, c) ? TXshCell() : cell;
|
||||
const TXshCell &cell = xsh->getCell(r, c, false);
|
||||
m_cells[k++] = cell;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -248,9 +248,7 @@ bool CellsMover::canMoveCells(const TPoint &pos) {
|
|||
int count = 0;
|
||||
for (int i = 0; i < m_colCount; i++) {
|
||||
for (int j = 0; j < m_rowCount; j++) {
|
||||
if (!xsh->getCell(r + j, c + i).isEmpty() &&
|
||||
!xsh->isImplicitCell(r + j, c + i))
|
||||
return false;
|
||||
if (!xsh->getCell(r + j, c + i, false).isEmpty()) return false;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2272,7 +2272,8 @@ void CellArea::drawLevelCell(QPainter &p, int row, int col, bool isReference,
|
|||
if (showLevelName &&
|
||||
(!sameLevel || (row > 0 && xsh->isImplicitCell(row - 1, col)) ||
|
||||
(isAfterMarkers && !isSimpleView &&
|
||||
Preferences::instance()->isLevelNameOnEachMarkerEnabled()))) {
|
||||
Preferences::instance()->isLevelNameOnEachMarkerEnabled()) ||
|
||||
prevCell.getFrameId().isStopFrame())) {
|
||||
std::wstring levelName = cell.m_level->getName();
|
||||
QString text = QString::fromStdWString(levelName);
|
||||
QFontMetrics fm(font);
|
||||
|
@ -2989,7 +2990,7 @@ void CellArea::drawPaletteCell(QPainter &p, int row, int col,
|
|||
text, font, nameRect.width() - fm.width(numberStr) - 2, QString("~"));
|
||||
#endif
|
||||
|
||||
if (!sameLevel || isAfterMarkers)
|
||||
if (!sameLevel || isAfterMarkers || prevCell.getFrameId().isStopFrame())
|
||||
p.drawText(nameRect, Qt::AlignLeft | Qt::AlignBottom, elidaName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "toonz/tfxhandle.h"
|
||||
#include "toonz/scenefx.h"
|
||||
#include "toonz/preferences.h"
|
||||
#include "toonz/txshlevelcolumn.h"
|
||||
|
||||
// TnzQt includes
|
||||
#include "toonzqt/tselectionhandle.h"
|
||||
|
@ -335,8 +336,8 @@ public:
|
|||
|
||||
for (int c = 0; c != colsCount; ++c) {
|
||||
// Store cell
|
||||
const TXshCell &cell = xsh->getCell(m_frame, c);
|
||||
m_cells[c] = xsh->isImplicitCell(m_frame, c) ? TXshCell() : cell;
|
||||
const TXshCell &cell = xsh->getCell(m_frame, c, false);
|
||||
m_cells[c] = cell;
|
||||
|
||||
// Store stage object keyframes
|
||||
TStageObject *obj = xsh->getStageObject(TStageObjectId::ColumnId(c));
|
||||
|
@ -636,6 +637,265 @@ public:
|
|||
}
|
||||
} removeGlobalKeyframeCommand;
|
||||
|
||||
//*****************************************************************************
|
||||
// SetGlobalStopframe command
|
||||
//*****************************************************************************
|
||||
|
||||
class SetGlobalStopframeUndo final : public TUndo {
|
||||
std::vector<std::pair<int, TXshCell>> m_oldCells;
|
||||
std::vector<int> m_columns;
|
||||
int m_frame;
|
||||
|
||||
public:
|
||||
SetGlobalStopframeUndo(int frame, const std::vector<int> &columns);
|
||||
~SetGlobalStopframeUndo() {}
|
||||
|
||||
void undo() const override {
|
||||
if (m_frame < 0 || !m_oldCells.size()) return;
|
||||
|
||||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
|
||||
for (int i = 0; i < m_oldCells.size(); i++) {
|
||||
std::pair<int, TXshCell> cellData = m_oldCells[i];
|
||||
TXshColumn *xshColumn = xsh->getColumn(cellData.first);
|
||||
if (!xshColumn) continue;
|
||||
|
||||
TXshCellColumn *cellColumn = xshColumn->getCellColumn();
|
||||
if (!cellColumn) continue;
|
||||
|
||||
std::vector<TXshCell> cells;
|
||||
cells.push_back(cellData.second);
|
||||
cellColumn->setCells(m_frame, 1, &cells[0]);
|
||||
}
|
||||
|
||||
TApp::instance()->getCurrentScene()->setDirtyFlag(true);
|
||||
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
|
||||
}
|
||||
|
||||
void redo() const override;
|
||||
|
||||
int getSize() const override { return m_oldCells.size(); }
|
||||
|
||||
QString getHistoryString() override {
|
||||
return QObject::tr("Set Multiple Stop Frames at Frame %1")
|
||||
.arg(QString::number(m_frame + 1));
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SetGlobalStopframeUndo::SetGlobalStopframeUndo(int frame,
|
||||
const std::vector<int> &columns)
|
||||
: m_frame(frame), m_columns(columns) {
|
||||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
|
||||
m_oldCells.clear();
|
||||
|
||||
for (int c : m_columns) {
|
||||
if (c < 0) continue;
|
||||
|
||||
TXshColumn *xshColumn = xsh->getColumn(c);
|
||||
if (!xshColumn || xshColumn->getSoundColumn() ||
|
||||
xshColumn->getSoundTextColumn() || xshColumn->isLocked() ||
|
||||
xshColumn->isEmpty())
|
||||
continue;
|
||||
|
||||
TXshCellColumn *cellColumn = xshColumn->getCellColumn();
|
||||
if (!cellColumn || cellColumn->isEmpty()) continue;
|
||||
|
||||
TXshCell cell = cellColumn->getCell(m_frame, false);
|
||||
if (!cell.isEmpty()) continue;
|
||||
|
||||
m_oldCells.push_back(std::make_pair(c, cell));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SetGlobalStopframeUndo::redo() const {
|
||||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
|
||||
for (int c : m_columns) {
|
||||
if (c < 0) continue;
|
||||
|
||||
TXshColumn *xshColumn = xsh->getColumn(c);
|
||||
if (!xshColumn || xshColumn->getSoundColumn() ||
|
||||
xshColumn->getSoundTextColumn() || xshColumn->isLocked() ||
|
||||
xshColumn->isEmpty())
|
||||
continue;
|
||||
|
||||
TXshCellColumn *cellColumn = xshColumn->getCellColumn();
|
||||
if (!cellColumn || cellColumn->isEmpty()) continue;
|
||||
|
||||
TXshCell cell = cellColumn->getCell(m_frame);
|
||||
if (!cell.isEmpty() && !cellColumn->isCellImplicit(m_frame)) continue;
|
||||
|
||||
if (cell.isEmpty()) { // Might have hit a stop frame
|
||||
for (int r = m_frame - 1; r >= 0; r--) {
|
||||
cell = cellColumn->getCell(r, false);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
if (cell.isEmpty()) continue;
|
||||
}
|
||||
cellColumn->setCell(
|
||||
m_frame, TXshCell(cell.m_level.getPointer(), TFrameId::STOP_FRAME));
|
||||
}
|
||||
|
||||
TApp::instance()->getCurrentScene()->setDirtyFlag(true);
|
||||
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void setGlobalStopframe(int frame) {
|
||||
std::vector<int> columns;
|
||||
::getColumns(columns);
|
||||
|
||||
if (columns.empty()) return;
|
||||
|
||||
TUndo *undo = new SetGlobalStopframeUndo(frame, columns);
|
||||
TUndoManager::manager()->add(undo);
|
||||
|
||||
undo->redo();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
class SetGlobalStopframeCommand final : public MenuItemHandler {
|
||||
public:
|
||||
SetGlobalStopframeCommand() : MenuItemHandler(MI_SetGlobalStopframe) {}
|
||||
void execute() override {
|
||||
int frame = TApp::instance()->getCurrentFrame()->getFrame();
|
||||
XshCmd::setGlobalStopframe(frame);
|
||||
}
|
||||
} setGlobalStopframeCommand;
|
||||
|
||||
//*****************************************************************************
|
||||
// RemoveGlobalStopframe command
|
||||
//*****************************************************************************
|
||||
|
||||
class RemoveGlobalStopframeUndo final : public TUndo {
|
||||
std::vector<std::pair<int, TXshCell>> m_oldCells;
|
||||
std::vector<int> m_columns;
|
||||
int m_frame;
|
||||
|
||||
public:
|
||||
RemoveGlobalStopframeUndo(int frame, const std::vector<int> &columns);
|
||||
~RemoveGlobalStopframeUndo() {}
|
||||
|
||||
void undo() const override {
|
||||
if (m_frame < 0 || !m_oldCells.size()) return;
|
||||
|
||||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
|
||||
for (int i = 0; i < m_oldCells.size(); i++) {
|
||||
std::pair<int, TXshCell> cellData = m_oldCells[i];
|
||||
TXshColumn *xshColumn = xsh->getColumn(cellData.first);
|
||||
if (!xshColumn) continue;
|
||||
|
||||
TXshCellColumn *cellColumn = xshColumn->getCellColumn();
|
||||
if (!cellColumn) continue;
|
||||
|
||||
std::vector<TXshCell> cells;
|
||||
cells.push_back(cellData.second);
|
||||
cellColumn->setCells(m_frame, 1, &cells[0]);
|
||||
}
|
||||
|
||||
TApp::instance()->getCurrentScene()->setDirtyFlag(true);
|
||||
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
|
||||
}
|
||||
|
||||
void redo() const override;
|
||||
|
||||
int getSize() const override { return m_oldCells.size(); }
|
||||
|
||||
QString getHistoryString() override {
|
||||
return QObject::tr("Remove Multiple Stop Frames at Frame %1")
|
||||
.arg(QString::number(m_frame + 1));
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
RemoveGlobalStopframeUndo::RemoveGlobalStopframeUndo(
|
||||
int frame, const std::vector<int> &columns)
|
||||
: m_frame(frame), m_columns(columns) {
|
||||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
|
||||
m_oldCells.clear();
|
||||
|
||||
for (int c : m_columns) {
|
||||
if (c < 0) continue;
|
||||
|
||||
TXshColumn *xshColumn = xsh->getColumn(c);
|
||||
if (!xshColumn || xshColumn->getSoundColumn() ||
|
||||
xshColumn->getSoundTextColumn() || xshColumn->isLocked() ||
|
||||
xshColumn->isEmpty())
|
||||
continue;
|
||||
|
||||
TXshCellColumn *cellColumn = xshColumn->getCellColumn();
|
||||
if (!cellColumn || cellColumn->isEmpty()) continue;
|
||||
|
||||
TXshCell cell = cellColumn->getCell(m_frame, false);
|
||||
if (!cell.getFrameId().isStopFrame()) continue;
|
||||
|
||||
m_oldCells.push_back(std::make_pair(c, cell));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void RemoveGlobalStopframeUndo::redo() const {
|
||||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
|
||||
for (int c : m_columns) {
|
||||
if (c < 0) continue;
|
||||
|
||||
TXshColumn *xshColumn = xsh->getColumn(c);
|
||||
if (!xshColumn || xshColumn->getSoundColumn() ||
|
||||
xshColumn->getSoundTextColumn() || xshColumn->isLocked() ||
|
||||
xshColumn->isEmpty())
|
||||
continue;
|
||||
|
||||
TXshCellColumn *cellColumn = xshColumn->getCellColumn();
|
||||
if (!cellColumn || cellColumn->isEmpty()) continue;
|
||||
|
||||
TXshCell cell = cellColumn->getCell(m_frame, false);
|
||||
if (!cell.getFrameId().isStopFrame()) continue;
|
||||
|
||||
cellColumn->clearCells(m_frame, 1);
|
||||
}
|
||||
|
||||
TApp::instance()->getCurrentScene()->setDirtyFlag(true);
|
||||
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void removeGlobalStopframe(int frame) {
|
||||
std::vector<int> columns;
|
||||
::getColumns(columns);
|
||||
|
||||
if (columns.empty()) return;
|
||||
|
||||
TUndo *undo = new RemoveGlobalStopframeUndo(frame, columns);
|
||||
TUndoManager::manager()->add(undo);
|
||||
|
||||
undo->redo();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
class RemoveGlobalStopframeCommand final : public MenuItemHandler {
|
||||
public:
|
||||
RemoveGlobalStopframeCommand() : MenuItemHandler(MI_RemoveGlobalStopframe) {}
|
||||
void execute() override {
|
||||
int frame = TApp::instance()->getCurrentFrame()->getFrame();
|
||||
XshCmd::removeGlobalStopframe(frame);
|
||||
}
|
||||
} RemoveGlobalStopframeCommand;
|
||||
|
||||
//============================================================
|
||||
// Drawing Substitution
|
||||
//============================================================
|
||||
|
@ -662,10 +922,8 @@ public:
|
|||
tempCol = c;
|
||||
while (r <= m_range.m_r1 + 1) {
|
||||
tempRow = r;
|
||||
if (xsh->getCell(tempRow, tempCol).isEmpty() ||
|
||||
xsh->isImplicitCell(tempRow, tempCol)) {
|
||||
if (xsh->getCell(tempRow, tempCol, false).isEmpty())
|
||||
emptyCells.push_back(std::make_pair(tempRow, tempCol));
|
||||
}
|
||||
r++;
|
||||
}
|
||||
r = m_range.m_r0;
|
||||
|
|
|
@ -2063,8 +2063,7 @@ protected:
|
|||
getViewer()->orientation()->isVerticalTimeline());
|
||||
for (c = col; c < rect.getLx() + col; c++) {
|
||||
for (r = row; r < rect.getLy() + row; r++)
|
||||
if (!xsh->getCell(r, c).isEmpty() && !xsh->isImplicitCell(r, c))
|
||||
return false;
|
||||
if (!xsh->getCell(r, c, false).isEmpty()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1255,6 +1255,8 @@ void RowArea::contextMenuEvent(QContextMenuEvent *event) {
|
|||
menu->addAction(cmdManager->getAction(MI_RemoveSceneFrame));
|
||||
menu->addAction(cmdManager->getAction(MI_InsertGlobalKeyframe));
|
||||
menu->addAction(cmdManager->getAction(MI_RemoveGlobalKeyframe));
|
||||
menu->addAction(cmdManager->getAction(MI_SetGlobalStopframe));
|
||||
menu->addAction(cmdManager->getAction(MI_RemoveGlobalStopframe));
|
||||
menu->addAction(cmdManager->getAction(MI_DrawingSubForward));
|
||||
menu->addAction(cmdManager->getAction(MI_DrawingSubBackward));
|
||||
menu->addSeparator();
|
||||
|
|
|
@ -196,15 +196,6 @@ bool PlasticDeformerFx::buildTextureDataSl(double frame, TRenderSettings &info,
|
|||
TXshLevelColumn *texColumn = lcfx->getColumn();
|
||||
|
||||
TXshCell texCell = texColumn->getCell(row);
|
||||
if (texCell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
texColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, (int)frame); r >= r0; r--) {
|
||||
texCell = texColumn->getCell(r);
|
||||
if (texCell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TXshSimpleLevel *texSl = texCell.getSimpleLevel();
|
||||
const TFrameId &texFid = texCell.getFrameId();
|
||||
|
|
|
@ -111,15 +111,6 @@ public:
|
|||
if (!m_cellColumn) return m_frame;
|
||||
TXshCell cell = m_cellColumn->getCell(tfloor(frame));
|
||||
assert(!cell.isEmpty());
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
m_cellColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, frame); r >= r0; r--) {
|
||||
cell = m_cellColumn->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cell.m_frameId.getNumber() - 1;
|
||||
}
|
||||
|
||||
|
@ -813,15 +804,6 @@ PlacedFx FxBuilder::makePF(TLevelColumnFx *lcfx) {
|
|||
// Retrieve the corresponding xsheet cell to build up
|
||||
/*-- 現在のフレームのセルを取得 --*/
|
||||
TXshCell cell = lcfx->getColumn()->getCell(tfloor(m_frame));
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
lcfx->getColumn()->getRange(r0, r1);
|
||||
for (int r = std::min(r1, tfloor(m_frame)); r >= r0; r--) {
|
||||
cell = lcfx->getColumn()->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int levelFrame = cell.m_frameId.getNumber() - 1;
|
||||
|
||||
/*-- ParticlesFxに繋がっておらず、空セルの場合は 中身無しを返す --*/
|
||||
|
@ -964,15 +946,6 @@ PlacedFx FxBuilder::makePF(TPaletteColumnFx *pcfx) {
|
|||
if (!pcfx->getColumn()->isPreviewVisible()) return PlacedFx();
|
||||
|
||||
TXshCell cell = pcfx->getColumn()->getCell(tfloor(m_frame));
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
pcfx->getColumn()->getRange(r0, r1);
|
||||
for (int r = std::min(r1, tfloor(m_frame)); r >= r0; r--) {
|
||||
cell = pcfx->getColumn()->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell.isEmpty() || cell.getFrameId().isStopFrame()) return PlacedFx();
|
||||
|
||||
|
@ -1002,15 +975,6 @@ PlacedFx FxBuilder::makePF(TZeraryColumnFx *zcfx) {
|
|||
return PlacedFx();
|
||||
|
||||
TXshCell cell = zcfx->getColumn()->getCell(tfloor(m_frame));
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
zcfx->getColumn()->getRange(r0, r1);
|
||||
for (int r = std::min(r1, tfloor(m_frame)); r >= r0; r--) {
|
||||
cell = zcfx->getColumn()->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Build
|
||||
PlacedFx pf;
|
||||
|
|
|
@ -821,15 +821,6 @@ bool TLevelColumnFx::canHandle(const TRenderSettings &info, double frame) {
|
|||
|
||||
int row = m_levelColumn->getFirstRow();
|
||||
TXshCell cell = m_levelColumn->getCell(row);
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
m_levelColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, row); r >= r0; r--) {
|
||||
cell = m_levelColumn->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cell.isEmpty()) return true;
|
||||
|
||||
TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
|
||||
|
@ -847,15 +838,6 @@ TAffine TLevelColumnFx::handledAffine(const TRenderSettings &info,
|
|||
|
||||
int row = m_levelColumn->getFirstRow();
|
||||
TXshCell cell = m_levelColumn->getCell(row);
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
m_levelColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, row); r >= r0; r--) {
|
||||
cell = m_levelColumn->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cell.isEmpty()) return TAffine();
|
||||
|
||||
TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
|
||||
|
@ -893,16 +875,6 @@ TFilePath TLevelColumnFx::getPalettePath(int frame) const {
|
|||
if (!m_levelColumn) return TFilePath();
|
||||
|
||||
TXshCell cell = m_levelColumn->getCell(frame);
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
m_levelColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, frame); r >= r0; r--) {
|
||||
cell = m_levelColumn->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell.isEmpty()) return TFilePath();
|
||||
|
||||
TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
|
||||
|
@ -924,15 +896,6 @@ TPalette *TLevelColumnFx::getPalette(int frame) const {
|
|||
if (!m_levelColumn) return 0;
|
||||
|
||||
TXshCell cell = m_levelColumn->getCell(frame);
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
m_levelColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, frame); r >= r0; r--) {
|
||||
cell = m_levelColumn->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cell.isEmpty()) return 0;
|
||||
|
||||
TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
|
||||
|
@ -960,15 +923,6 @@ void TLevelColumnFx::doDryCompute(TRectD &rect, double frame,
|
|||
|
||||
int row = (int)frame;
|
||||
TXshCell cell = m_levelColumn->getCell(row);
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
m_levelColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, row); r >= r0; r--) {
|
||||
cell = m_levelColumn->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cell.isEmpty()) return;
|
||||
|
||||
TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
|
||||
|
@ -1019,15 +973,6 @@ void TLevelColumnFx::doCompute(TTile &tile, double frame,
|
|||
// Ensure that a corresponding cell and level exists
|
||||
int row = (int)frame;
|
||||
TXshCell cell = m_levelColumn->getCell(row);
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
m_levelColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, row); r >= r0; r--) {
|
||||
cell = m_levelColumn->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cell.isEmpty()) return;
|
||||
|
||||
TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
|
||||
|
@ -1446,15 +1391,6 @@ bool TLevelColumnFx::doGetBBox(double frame, TRectD &bBox,
|
|||
|
||||
int row = (int)frame;
|
||||
TXshCell cell = m_levelColumn->getCell(row);
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
m_levelColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, row); r >= r0; r--) {
|
||||
cell = m_levelColumn->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cell.isEmpty()) return false;
|
||||
|
||||
TXshLevelP xshl = cell.m_level;
|
||||
|
@ -1487,15 +1423,6 @@ bool TLevelColumnFx::doGetBBox(double frame, TRectD &bBox,
|
|||
dpi = imageInfo.m_dpix / Stage::inch;
|
||||
} else {
|
||||
TXshCell cell = m_levelColumn->getCell(row);
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
m_levelColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, row); r >= r0; r--) {
|
||||
cell = m_levelColumn->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TImageP img = cell.getImage(false);
|
||||
if (!img) return false;
|
||||
bBox = img->getBBox();
|
||||
|
@ -1532,6 +1459,12 @@ TFxTimeRegion TLevelColumnFx::getTimeRegion() const {
|
|||
int first = m_levelColumn->getFirstRow();
|
||||
int last = m_levelColumn->getRowCount();
|
||||
|
||||
// For implicit hold, if the last frame is not a stop frame, it's held
|
||||
// indefinitely
|
||||
if (Preferences::instance()->isImplicitHoldEnabled() &&
|
||||
!m_levelColumn->getCell(last - 1).getFrameId().isStopFrame())
|
||||
return TFxTimeRegion(0, (std::numeric_limits<double>::max)());
|
||||
|
||||
return TFxTimeRegion(first, last);
|
||||
}
|
||||
|
||||
|
@ -1565,15 +1498,6 @@ std::string TLevelColumnFx::getAlias(double frame,
|
|||
if (!m_levelColumn) return std::string();
|
||||
|
||||
TXshCell cell = m_levelColumn->getCell((int)frame);
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
m_levelColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, (int)frame); r >= r0; r--) {
|
||||
cell = m_levelColumn->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cell.isEmpty()) return std::string();
|
||||
|
||||
TFilePath fp;
|
||||
|
@ -1635,15 +1559,6 @@ TAffine TLevelColumnFx::getDpiAff(int frame) {
|
|||
if (!m_levelColumn) return TAffine();
|
||||
|
||||
TXshCell cell = m_levelColumn->getCell(frame);
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
m_levelColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, frame); r >= r0; r--) {
|
||||
cell = m_levelColumn->getCell(r);
|
||||
if (cell.isEmpty()) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cell.isEmpty()) return TAffine();
|
||||
|
||||
TXshSimpleLevel *sl = cell.m_level->getSimpleLevel();
|
||||
|
|
|
@ -84,11 +84,34 @@ int TXshCellColumn::getFirstRow() const { return m_first; }
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const TXshCell &TXshCellColumn::getCell(int row) const {
|
||||
const TXshCell &TXshCellColumn::getCell(int row, bool implicitLookup) const {
|
||||
static TXshCell emptyCell;
|
||||
if (row < 0 || row < m_first || row >= m_first + (int)m_cells.size())
|
||||
return emptyCell;
|
||||
return m_cells[row - m_first];
|
||||
|
||||
if (row < 0 || row < m_first || !m_cells.size()) return emptyCell;
|
||||
|
||||
bool implicitEnabled = Preferences::instance()->isImplicitHoldEnabled() &&
|
||||
implicitLookup &&
|
||||
getColumnType() != ColumnType::eSoundTextType &&
|
||||
getColumnType() != ColumnType::eSoundType;
|
||||
|
||||
int r = row - m_first;
|
||||
|
||||
if (r >= m_cells.size()) {
|
||||
if (!implicitEnabled) return emptyCell;
|
||||
r = m_cells.size() - 1;
|
||||
if (m_cells[r].getFrameId().isStopFrame()) return emptyCell;
|
||||
}
|
||||
|
||||
if (m_cells[r].isEmpty() && implicitEnabled) {
|
||||
for (; r >= 0; r--) {
|
||||
if (m_cells[r].isEmpty()) continue;
|
||||
if (m_cells[r].getFrameId().isStopFrame()) return emptyCell;
|
||||
break;
|
||||
}
|
||||
if (r < 0) return emptyCell;
|
||||
}
|
||||
|
||||
return m_cells[r];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -99,6 +122,21 @@ bool TXshCellColumn::isCellEmpty(int row) const {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool TXshCellColumn::isCellImplicit(int row) const {
|
||||
if (!Preferences::instance()->isImplicitHoldEnabled() ||
|
||||
getColumnType() == ColumnType::eSoundType ||
|
||||
getColumnType() == ColumnType::eSoundTextType || row < 0 ||
|
||||
row < m_first || getCell(row).isEmpty())
|
||||
return false;
|
||||
|
||||
// If we got here, the cell is technically not empty
|
||||
// If it is truely empty in the array, then it is implicit
|
||||
int r = row - m_first;
|
||||
return r >= m_cells.size() || m_cells[r].isEmpty();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//--- debug only
|
||||
void TXshCellColumn::checkColumn() const {
|
||||
assert(m_first >= 0);
|
||||
|
@ -422,10 +460,11 @@ bool TXshCellColumn::getLevelRange(int row, int &r0, int &r1) const {
|
|||
r0 = r1 = row;
|
||||
TXshCell cell = getCell(row);
|
||||
if (cell.isEmpty()) return false;
|
||||
while (r0 > 0 &&
|
||||
while (r0 > 0 && !isCellImplicit(r0 - 1) &&
|
||||
getCell(r0 - 1).m_level.getPointer() == cell.m_level.getPointer())
|
||||
r0--;
|
||||
while (getCell(r1 + 1).m_level.getPointer() == cell.m_level.getPointer())
|
||||
while (!isCellImplicit(r1 + 1) &&
|
||||
getCell(r1 + 1).m_level.getPointer() == cell.m_level.getPointer())
|
||||
r1++;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -230,11 +230,12 @@ int TXsheet::getFrameCount() const { return m_imp->m_frameCount; }
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const TXshCell &TXsheet::getCell(int row, int col) const {
|
||||
return getCell(CellPosition(row, col));
|
||||
const TXshCell &TXsheet::getCell(int row, int col, bool implicitLookup) const {
|
||||
return getCell(CellPosition(row, col), implicitLookup);
|
||||
}
|
||||
|
||||
const TXshCell &TXsheet::getCell(const CellPosition &pos) const {
|
||||
const TXshCell &TXsheet::getCell(const CellPosition &pos,
|
||||
bool implicitLookup) const {
|
||||
static const TXshCell emptyCell;
|
||||
|
||||
TXshColumnP column = m_imp->m_columnSet.getColumn(pos.layer());
|
||||
|
@ -242,22 +243,7 @@ const TXshCell &TXsheet::getCell(const CellPosition &pos) const {
|
|||
TXshCellColumn *xshColumn = column->getCellColumn();
|
||||
if (!xshColumn) return emptyCell;
|
||||
int frame = pos.frame();
|
||||
TXshCell cell = xshColumn->getCell(frame);
|
||||
if (cell.isEmpty() && Preferences::instance()->isImplicitHoldEnabled()) {
|
||||
int r0, r1;
|
||||
xshColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, pos.frame()); r >= r0; r--) {
|
||||
TXshCell tempCell = xshColumn->getCell(r);
|
||||
if (tempCell.isEmpty()) continue;
|
||||
if (tempCell.getSoundLevel() || tempCell.getSoundTextLevel())
|
||||
return emptyCell;
|
||||
if (tempCell.getFrameId().isStopFrame() && cell.isEmpty())
|
||||
return emptyCell;
|
||||
frame = r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return xshColumn->getCell(frame);
|
||||
return xshColumn->getCell(frame, implicitLookup);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -274,17 +260,8 @@ bool TXsheet::isImplicitCell(const CellPosition &pos) const {
|
|||
if (!column) return false;
|
||||
TXshCellColumn *xshColumn = column->getCellColumn();
|
||||
if (!xshColumn) return false;
|
||||
TXshCell tempCell = xshColumn->getCell(pos.frame());
|
||||
if (!tempCell.isEmpty()) return false;
|
||||
|
||||
int r0, r1;
|
||||
xshColumn->getRange(r0, r1);
|
||||
for (int r = std::min(r1, pos.frame()); r >= r0; r--) {
|
||||
tempCell = xshColumn->getCell(r);
|
||||
if (tempCell.getFrameId().isStopFrame()) return false;
|
||||
if (!tempCell.isEmpty()) return true;
|
||||
}
|
||||
return false;
|
||||
return xshColumn->isCellImplicit(pos.frame());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -294,7 +271,7 @@ bool TXsheet::setCell(int row, int col, const TXshCell &cell) {
|
|||
|
||||
bool wasColumnEmpty = isColumnEmpty(col);
|
||||
TXshCellColumn *cellColumn;
|
||||
if (!cell.isEmpty() && !isImplicitCell(row, col)) {
|
||||
if (!cell.isEmpty()) {
|
||||
TXshLevel *level = cell.m_level.getPointer();
|
||||
assert(level);
|
||||
|
||||
|
@ -678,12 +655,8 @@ void TXsheet::reverseCells(int r0, int c0, int r1, int c1) {
|
|||
for (int j = c0; j <= c1; j++) {
|
||||
int i1, i2;
|
||||
for (i1 = r0, i2 = r1; i1 < i2; i1++, i2--) {
|
||||
TXshCell app1;
|
||||
if (!isImplicitCell(CellPosition(i1, j)))
|
||||
app1 = getCell(CellPosition(i1, j));
|
||||
TXshCell app2;
|
||||
if (!isImplicitCell(CellPosition(i2, j)))
|
||||
app2 = getCell(CellPosition(i2, j));
|
||||
TXshCell app1 = getCell(CellPosition(i1, j), false);
|
||||
TXshCell app2 = getCell(CellPosition(i2, j), false);
|
||||
setCell(i1, j, app2);
|
||||
setCell(i2, j, app1);
|
||||
}
|
||||
|
@ -700,9 +673,7 @@ void TXsheet::swingCells(int r0, int c0, int r1, int c1) {
|
|||
|
||||
for (int j = c0; j <= c1; j++) {
|
||||
for (int i1 = r0Mod, i2 = r1 - 1; i2 >= r0; i1++, i2--) {
|
||||
TXshCell cell;
|
||||
if (!isImplicitCell(CellPosition(i2, j)))
|
||||
cell = getCell(CellPosition(i2, j));
|
||||
TXshCell cell = getCell(CellPosition(i2, j), false);
|
||||
setCell(i1, j, cell);
|
||||
}
|
||||
}
|
||||
|
@ -734,7 +705,7 @@ bool TXsheet::incrementCells(int r0, int c0, int r1, int c1,
|
|||
int frame1 = getCell(CellPosition(i, j)).getFrameId().getNumber();
|
||||
if (frame1 == TFrameId::EMPTY_FRAME || frame1 == TFrameId::STOP_FRAME)
|
||||
break;
|
||||
while (!getCell(CellPosition(i + 1, j)).isEmpty() &&
|
||||
while ((i + 1 <= r1) && !getCell(CellPosition(i + 1, j)).isEmpty() &&
|
||||
!getCell(CellPosition(i + 1, j)).getFrameId().isStopFrame() &&
|
||||
getCell(CellPosition(i + 1, j)).getFrameId().getNumber() ==
|
||||
getCell(CellPosition(i, j)).getFrameId().getNumber())
|
||||
|
@ -754,9 +725,7 @@ bool TXsheet::incrementCells(int r0, int c0, int r1, int c1,
|
|||
forUndo.push_back(std::pair<TRect, TXshCell>(
|
||||
TRect(i + 1, j, i + 1 + numCells - 1, j), cell));
|
||||
for (int k = 1; k <= numCells; k++) {
|
||||
TXshCell cell;
|
||||
if (!isImplicitCell(CellPosition(i + k, j)))
|
||||
cell = getCell(CellPosition(i, j));
|
||||
TXshCell cell = getCell(CellPosition(i, j), false);
|
||||
setCell(i + k, j, cell);
|
||||
}
|
||||
i += numCells;
|
||||
|
@ -765,9 +734,7 @@ bool TXsheet::incrementCells(int r0, int c0, int r1, int c1,
|
|||
{
|
||||
int numCells = count - frame2 + frame1;
|
||||
i = i - numCells;
|
||||
TXshCell cell;
|
||||
if (!isImplicitCell(CellPosition(i + 1, j)))
|
||||
cell = getCell(CellPosition(i + 1, j));
|
||||
TXshCell cell = getCell(CellPosition(i + 1, j), false);
|
||||
forUndo.push_back(std::pair<TRect, TXshCell>(
|
||||
TRect(i + 1, j, i + 1 + numCells - 1, j), cell));
|
||||
removeCells(i + 1, j, numCells);
|
||||
|
@ -788,9 +755,7 @@ void TXsheet::duplicateCells(int r0, int c0, int r1, int c1, int upTo) {
|
|||
insertCells(r1 + 1, j, upTo - (r1 + 1) + 1);
|
||||
for (int i = r1 + 1; i <= upTo; i++) {
|
||||
int row = r0 + ((i - (r1 + 1)) % chunk);
|
||||
TXshCell cell;
|
||||
if (!isImplicitCell(CellPosition(row, j)))
|
||||
cell = getCell(CellPosition(row, j));
|
||||
TXshCell cell = getCell(CellPosition(row, j), false);
|
||||
setCell(i, j, cell);
|
||||
}
|
||||
}
|
||||
|
@ -809,8 +774,8 @@ void TXsheet::stepCells(int r0, int c0, int r1, int c1, int type) {
|
|||
int k = 0;
|
||||
for (int r = r0; r <= r1; r++)
|
||||
for (int c = c0; c <= c1; c++) {
|
||||
const TXshCell &cell = getCell(CellPosition(r, c));
|
||||
cells[k++] = isImplicitCell(CellPosition(r, c)) ? TXshCell() : cell;
|
||||
const TXshCell &cell = getCell(CellPosition(r, c), false);
|
||||
cells[k++] = cell;
|
||||
}
|
||||
|
||||
int nrows = nr * (type - 1);
|
||||
|
@ -919,8 +884,8 @@ void TXsheet::eachCells(int r0, int c0, int r1, int c1, int type) {
|
|||
j += type) // in cells copio il contenuto delle celle che mi interessano
|
||||
{
|
||||
for (k = c0; k <= c1; k++, i++) {
|
||||
const TXshCell &cell = getCell(CellPosition(j, k));
|
||||
cells[i] = isImplicitCell(j, k) ? TXshCell() : cell;
|
||||
const TXshCell &cell = getCell(CellPosition(j, k), false);
|
||||
cells[i] = cell;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -316,7 +316,7 @@ int TXshSoundColumn::getFirstRow() const {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const TXshCell &TXshSoundColumn::getCell(int row) const {
|
||||
const TXshCell &TXshSoundColumn::getCell(int row, bool implicitLookup) const {
|
||||
static TXshCell emptyCell;
|
||||
|
||||
ColumnLevel *l = getColumnLevelByFrame(row);
|
||||
|
|
Loading…
Reference in a new issue