Add Create Blank Drawing command

This commit is contained in:
manongjohn 2019-12-01 21:33:38 -05:00
parent d98db10fae
commit 0ec114857b
11 changed files with 258 additions and 79 deletions

View file

@ -212,6 +212,7 @@
</menu>
<separator/>
<command>MI_Autorenumber</command>
<command>MI_CreateBlankDrawing</command>
<command>MI_Duplicate</command>
<command>MI_MergeFrames</command>
<command>MI_CloneLevel</command>

View file

@ -110,6 +110,7 @@ MI_ConvertToToonzRaster=
MI_ConvertToVectors=
MI_ConvertVectorToVector=
MI_Copy=Ctrl+C
MI_CreateBlankDrawing=Alt+D
MI_CursorOutline=
MI_Cut=Ctrl+X
MI_DeactivateAllColumns=

View file

@ -110,6 +110,7 @@ MI_ConvertToToonzRaster=
MI_ConvertToVectors=
MI_ConvertVectorToVector=
MI_Copy=Ctrl+C
MI_CreateBlankDrawing=F7
MI_CursorOutline=
MI_Cut=Ctrl+X
MI_DeactivateAllColumns=

View file

@ -110,6 +110,7 @@ MI_ConvertToToonzRaster=
MI_ConvertToVectors=
MI_ConvertVectorToVector=
MI_Copy=Ctrl+C
MI_CreateBlankDrawing=Alt+Shift+R
MI_CursorOutline=
MI_Cut=Ctrl+X
MI_DeactivateAllColumns=

View file

@ -110,6 +110,7 @@ MI_ConvertToToonzRaster=
MI_ConvertToVectors=
MI_ConvertVectorToVector=
MI_Copy=Ctrl+C
MI_CreateBlankDrawing=
MI_CursorOutline=
MI_Cut=Ctrl+X
MI_DeactivateAllColumns=

View file

@ -17,6 +17,7 @@
// TnzTools includes
#include "tools/toolutils.h"
#include "tools/toolhandle.h"
#include "tools/toolcommandids.h"
// TnzQt includes
#include "toonzqt/strokesdata.h"
@ -1217,6 +1218,42 @@ public:
//-----------------------------------------------------------------------------
class CreateBlankDrawingUndo final : public ToolUtils::TToolUndo {
int row;
int col;
public:
CreateBlankDrawingUndo(TXshSimpleLevel *level, const TFrameId &frameId,
bool levelCreated, const TPaletteP &oldPalette)
: TToolUndo(level, frameId, true, levelCreated, oldPalette) {}
~CreateBlankDrawingUndo() {}
void undo() const override {
removeLevelAndFrameIfNeeded();
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
notifyImageChanged();
}
void redo() const override {
insertLevelAndFrameIfNeeded();
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
notifyImageChanged();
}
int getSize() const override { return sizeof(*this); }
QString getHistoryString() override {
return QObject::tr("Create Blank Drawing");
}
int getHistoryType() override { return HistoryType::Xsheet; }
//-----------------------------------------------------------------------------
};
//-----------------------------------------------------------------------------
class FillEmptyCellUndo final : public TUndo {
TCellSelection *m_selection;
TXshCell m_cell;
@ -1397,6 +1434,8 @@ void TCellSelection::enableCommands() {
&TCellSelection::reframeWithEmptyInbetweens);
enableCommand(this, MI_PasteNumbers, &TCellSelection::overwritePasteNumbers);
enableCommand(this, MI_CreateBlankDrawing,
&TCellSelection::createBlankDrawings);
enableCommand(this, MI_Duplicate, &TCellSelection::duplicateFrame);
}
//-----------------------------------------------------------------------------
@ -1439,6 +1478,7 @@ bool TCellSelection::isEnabledCommand(
MI_PasteNumbers,
MI_ConvertToToonzRaster,
MI_ConvertVectorToVector,
MI_CreateBlankDrawing,
MI_FillEmptyCell};
return commands.contains(commandId);
}
@ -1919,6 +1959,110 @@ void TCellSelection::pasteKeyframesInto() {
//-----------------------------------------------------------------------------
void TCellSelection::createBlankDrawing(int row, int col, bool multiple) {
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
if (col < 0) {
if (!multiple)
DVGui::warning(
QObject::tr("Unable to create a blank drawing on the camera column"));
return;
}
TXshColumn *column = xsh->getColumn(col);
if (column && column->isLocked()) {
if (!multiple) DVGui::warning(QObject::tr("The current column is locked"));
return;
}
TApp::instance()->getCurrentColumn()->setColumnIndex(col);
TApp::instance()->getCurrentFrame()->setCurrentFrame(row + 1);
TXshLevel *level = TApp::instance()->getCurrentLevel()->getLevel();
if (!level && Preferences::instance()->isAutoCreateEnabled() &&
Preferences::instance()->isAnimationSheetEnabled()) {
int r0, r1;
xsh->getCellRange(col, r0, r1);
for (int r = std::min(r1, row); r > r0; r--) {
TXshCell cell = xsh->getCell(r, col);
if (cell.isEmpty()) continue;
level = cell.m_level.getPointer();
if (!level) continue;
break;
}
}
if (level) {
int levelType = level->getType();
if (levelType == ZERARYFX_XSHLEVEL || levelType == PLT_XSHLEVEL ||
levelType == SND_XSHLEVEL || levelType == SND_TXT_XSHLEVEL ||
levelType == MESH_XSHLEVEL) {
if (!multiple)
DVGui::warning(
QObject::tr("Cannot create a blank drawing on the current column"));
return;
} else if (level->getSimpleLevel() &&
level->getSimpleLevel()->isReadOnly()) {
if (!multiple)
DVGui::warning(QObject::tr("The current level is not editable"));
return;
}
}
ToolHandle *toolHandle = TApp::instance()->getCurrentTool();
// If autocreate disabled, let's turn it on temporarily
bool isAutoCreateEnabled = Preferences::instance()->isAutoCreateEnabled();
if (!isAutoCreateEnabled) Preferences::instance()->setAutocreationType(1);
TImage *img = toolHandle->getTool()->touchImage();
TXshCell cell = xsh->getCell(row, col);
TXshSimpleLevel *sl = cell.getSimpleLevel();
if (!img || !sl) {
if (!isAutoCreateEnabled) Preferences::instance()->setAutocreationType(0);
if (!multiple)
DVGui::warning(QObject::tr(
"Unable to create a blank drawing on the current column"));
return;
}
TPalette *palette = sl->getPalette();
TFrameId frame = cell.getFrameId();
CreateBlankDrawingUndo *undo = new CreateBlankDrawingUndo(
sl, frame, toolHandle->getTool()->m_isLevelCreated, palette);
TUndoManager::manager()->add(undo);
// Reset back to what these were
if (!isAutoCreateEnabled) Preferences::instance()->setAutocreationType(0);
}
//-----------------------------------------------------------------------------
void TCellSelection::createBlankDrawings() {
int col = TApp::instance()->getCurrentColumn()->getColumnIndex();
int row = TApp::instance()->getCurrentFrame()->getFrameIndex();
int r0, c0, r1, c1;
getSelectedCells(r0, c0, r1, c1);
bool multiple = (r1 - r0 > 1) || (c1 - c0 > 1);
TUndoManager::manager()->beginBlock();
for (int c = c0; c <= c1; c++) {
for (int r = r0; r <= r1; r++) {
createBlankDrawing(r, c, multiple);
}
}
TUndoManager::manager()->endBlock();
TApp::instance()->getCurrentColumn()->setColumnIndex(col);
TApp::instance()->getCurrentFrame()->setCurrentFrame(row + 1);
}
//-----------------------------------------------------------------------------
void TCellSelection::duplicateFrame() {
if (!Preferences::instance()->isSyncLevelRenumberWithXsheetEnabled()) {
DVGui::warning(

View file

@ -117,6 +117,8 @@ public:
static bool isEnabledCommand(std::string commandId);
void createBlankDrawing(int row, int col, bool inRange);
void createBlankDrawings();
void fillEmptyCell();
};

View file

@ -1802,6 +1802,8 @@ void MainWindow::defineActions() {
QAction *timeStretchAction =
createMenuCellsAction(MI_TimeStretch, tr("&Time Stretch..."), "");
timeStretchAction->setIcon(QIcon(":Resources/timestretch.svg"));
createMenuCellsAction(MI_CreateBlankDrawing, tr("&Create Blank Drawing"),
"Alt+D");
createMenuCellsAction(MI_Duplicate, tr("&Duplicate Drawing "), "D");
createMenuCellsAction(MI_Autorenumber, tr("&Autorenumber"), "");
createMenuCellsAction(MI_CloneLevel, tr("&Clone"), "");

View file

@ -1315,6 +1315,7 @@ QMenuBar *StackedMenuBar::createFullMenuBar() {
}
cellsMenu->addSeparator();
addMenuItem(cellsMenu, MI_Autorenumber);
addMenuItem(cellsMenu, MI_CreateBlankDrawing);
addMenuItem(cellsMenu, MI_Duplicate);
addMenuItem(cellsMenu, MI_MergeFrames);
addMenuItem(cellsMenu, MI_CloneLevel);

View file

@ -147,6 +147,7 @@
#define MI_PasteNew "MI_PasteNew"
#define MI_Autorenumber "MI_Autorenumber"
#define MI_CreateBlankDrawing "MI_CreateBlankDrawing"
#define MI_FillEmptyCell "MI_FillEmptyCell"
#define MI_MergeFrames "MI_MergeFrames"

View file

@ -318,36 +318,46 @@ bool isGlobalKeyFrameWithSameTypeDiffFromLinear(TStageObject *stageObject,
TDoubleKeyframe::Type type =
stageObject->getParam(TStageObject::T_Angle)->getKeyframeAt(frame).m_type;
if (type == TDoubleKeyframe::Linear) return false;
if (type != stageObject->getParam(TStageObject::T_X)
->getKeyframeAt(frame)
.m_type ||
type != stageObject->getParam(TStageObject::T_Y)
->getKeyframeAt(frame)
.m_type ||
type != stageObject->getParam(TStageObject::T_Z)
->getKeyframeAt(frame)
.m_type ||
type != stageObject->getParam(TStageObject::T_SO)
->getKeyframeAt(frame)
.m_type ||
type != stageObject->getParam(TStageObject::T_ScaleX)
->getKeyframeAt(frame)
.m_type ||
type != stageObject->getParam(TStageObject::T_ScaleY)
->getKeyframeAt(frame)
.m_type ||
type != stageObject->getParam(TStageObject::T_Scale)
->getKeyframeAt(frame)
.m_type ||
type != stageObject->getParam(TStageObject::T_Path)
->getKeyframeAt(frame)
.m_type ||
type != stageObject->getParam(TStageObject::T_ShearX)
->getKeyframeAt(frame)
.m_type ||
type != stageObject->getParam(TStageObject::T_ShearY)
->getKeyframeAt(frame)
.m_type)
if (type !=
stageObject->getParam(TStageObject::T_X)
->getKeyframeAt(frame)
.m_type ||
type !=
stageObject->getParam(TStageObject::T_Y)
->getKeyframeAt(frame)
.m_type ||
type !=
stageObject->getParam(TStageObject::T_Z)
->getKeyframeAt(frame)
.m_type ||
type !=
stageObject->getParam(TStageObject::T_SO)
->getKeyframeAt(frame)
.m_type ||
type !=
stageObject->getParam(TStageObject::T_ScaleX)
->getKeyframeAt(frame)
.m_type ||
type !=
stageObject->getParam(TStageObject::T_ScaleY)
->getKeyframeAt(frame)
.m_type ||
type !=
stageObject->getParam(TStageObject::T_Scale)
->getKeyframeAt(frame)
.m_type ||
type !=
stageObject->getParam(TStageObject::T_Path)
->getKeyframeAt(frame)
.m_type ||
type !=
stageObject->getParam(TStageObject::T_ShearX)
->getKeyframeAt(frame)
.m_type ||
type !=
stageObject->getParam(TStageObject::T_ShearY)
->getKeyframeAt(frame)
.m_type)
return false;
return true;
}
@ -370,36 +380,46 @@ bool isGlobalKeyFrameWithSamePrevTypeDiffFromLinear(TStageObject *stageObject,
->getKeyframeAt(frame)
.m_prevType;
if (type == TDoubleKeyframe::Linear) return false;
if (type != stageObject->getParam(TStageObject::T_X)
->getKeyframeAt(frame)
.m_prevType ||
type != stageObject->getParam(TStageObject::T_Y)
->getKeyframeAt(frame)
.m_prevType ||
type != stageObject->getParam(TStageObject::T_Z)
->getKeyframeAt(frame)
.m_prevType ||
type != stageObject->getParam(TStageObject::T_SO)
->getKeyframeAt(frame)
.m_prevType ||
type != stageObject->getParam(TStageObject::T_ScaleX)
->getKeyframeAt(frame)
.m_prevType ||
type != stageObject->getParam(TStageObject::T_ScaleY)
->getKeyframeAt(frame)
.m_prevType ||
type != stageObject->getParam(TStageObject::T_Scale)
->getKeyframeAt(frame)
.m_prevType ||
type != stageObject->getParam(TStageObject::T_Path)
->getKeyframeAt(frame)
.m_prevType ||
type != stageObject->getParam(TStageObject::T_ShearX)
->getKeyframeAt(frame)
.m_prevType ||
type != stageObject->getParam(TStageObject::T_ShearY)
->getKeyframeAt(frame)
.m_prevType)
if (type !=
stageObject->getParam(TStageObject::T_X)
->getKeyframeAt(frame)
.m_prevType ||
type !=
stageObject->getParam(TStageObject::T_Y)
->getKeyframeAt(frame)
.m_prevType ||
type !=
stageObject->getParam(TStageObject::T_Z)
->getKeyframeAt(frame)
.m_prevType ||
type !=
stageObject->getParam(TStageObject::T_SO)
->getKeyframeAt(frame)
.m_prevType ||
type !=
stageObject->getParam(TStageObject::T_ScaleX)
->getKeyframeAt(frame)
.m_prevType ||
type !=
stageObject->getParam(TStageObject::T_ScaleY)
->getKeyframeAt(frame)
.m_prevType ||
type !=
stageObject->getParam(TStageObject::T_Scale)
->getKeyframeAt(frame)
.m_prevType ||
type !=
stageObject->getParam(TStageObject::T_Path)
->getKeyframeAt(frame)
.m_prevType ||
type !=
stageObject->getParam(TStageObject::T_ShearX)
->getKeyframeAt(frame)
.m_prevType ||
type !=
stageObject->getParam(TStageObject::T_ShearY)
->getKeyframeAt(frame)
.m_prevType)
return false;
return true;
}
@ -758,7 +778,7 @@ void RenameCellField::renameCell() {
fid = TFrameId(fidRe.cap(1).toInt(),
fidRe.cap(2) == "" ? 0 : fidRe.cap(2).toLatin1()[0]);
#else
fid = TFrameId(fidRe.cap(1).toInt(),
fid = TFrameId(fidRe.cap(1).toInt(),
fidRe.cap(2) == "" ? 0 : fidRe.cap(2).toAscii()[0]);
#endif
FilmstripCmd::renumberDrawing(sl, cell.m_frameId, fid);
@ -1805,10 +1825,10 @@ void CellArea::drawLevelCell(QPainter &p, int row, int col, bool isReference) {
nameRect.adjust(0, 0, -frameAdj, 0);
// draw text in red if the file does not exist
bool isRed = false;
TXshSimpleLevel *sl = cell.getSimpleLevel();
bool isRed = false;
TXshSimpleLevel *sl = cell.getSimpleLevel();
if (sl && !sl->isFid(cell.m_frameId)) isRed = true;
TXshChildLevel *cl = cell.getChildLevel();
TXshChildLevel *cl = cell.getChildLevel();
if (cl && cell.getFrameId().getNumber() - 1 >= cl->getFrameCount())
isRed = true;
QColor penColor =
@ -1908,9 +1928,8 @@ void CellArea::drawSoundTextCell(QPainter &p, int row, int col) {
bool isSelected = cellSelection->isCellSelected(row, col) ||
columnSelection->isColumnSelected(col);
if (row > 0)
prevCell = xsh->getCell(row - 1, col); // cell in previous frame
// nothing to draw
if (row > 0) prevCell = xsh->getCell(row - 1, col); // cell in previous frame
// nothing to draw
bool sameLevel = prevCell.m_level.getPointer() == cell.m_level.getPointer();
@ -2016,7 +2035,7 @@ void CellArea::drawSoundTextCell(QPainter &p, int row, int col) {
#ifdef _WIN32
fontName = "Arial";
#else
fontName = "Helvetica";
fontName = "Helvetica";
#endif
}
static QFont font(fontName, -1, QFont::Normal);
@ -2048,7 +2067,7 @@ void CellArea::drawSoundTextCell(QPainter &p, int row, int col) {
#if QT_VERSION >= 0x050500
QString elidaName = elideText(text, metric, nameRect.width(), "~");
#else
QString elidaName = elideText(text, font, nameRect.width(), "~");
QString elidaName = elideText(text, font, nameRect.width(), "~");
#endif
if (!sameLevel || prevCell.m_frameId != cell.m_frameId)
@ -2069,7 +2088,7 @@ void CellArea::drawPaletteCell(QPainter &p, int row, int col,
bool isSelected = cellSelection->isCellSelected(row, col);
if (row > 0) prevCell = xsh->getCell(row - 1, col);
TXshCell nextCell = xsh->getCell(row + 1, col);
TXshCell nextCell = xsh->getCell(row + 1, col);
bool sameLevel = prevCell.m_level.getPointer() == cell.m_level.getPointer();
@ -2080,8 +2099,8 @@ void CellArea::drawPaletteCell(QPainter &p, int row, int col,
bool isAfterMarkers =
distance > 0 && ((row - offset) % distance) == 0 && row != 0;
bool isRed = false;
TXshPaletteLevel *pl = cell.getPaletteLevel();
bool isRed = false;
TXshPaletteLevel *pl = cell.getPaletteLevel();
if (pl && !pl->getPalette()) isRed = true;
QPoint xy = m_viewer->positionToXY(CellPosition(row, col));
@ -2213,7 +2232,7 @@ void CellArea::drawPaletteCell(QPainter &p, int row, int col,
#ifdef _WIN32
fontName = "Arial";
#else
fontName = "Helvetica";
fontName = "Helvetica";
#endif
}
static QFont font(fontName, -1, QFont::Normal);
@ -2772,9 +2791,10 @@ void CellArea::mousePressEvent(QMouseEvent *event) {
setDragTool(XsheetGUI::DragTool::makeLevelMoverTool(m_viewer));
} else {
m_viewer->getKeyframeSelection()->selectNone();
if (isSoundColumn && o->rect(PredefinedRect::PREVIEW_TRACK)
.adjusted(0, 0, -frameAdj, 0)
.contains(mouseInCell))
if (isSoundColumn &&
o->rect(PredefinedRect::PREVIEW_TRACK)
.adjusted(0, 0, -frameAdj, 0)
.contains(mouseInCell))
setDragTool(XsheetGUI::DragTool::makeSoundScrubTool(
m_viewer, column->getSoundColumn()));
else if (isSoundColumn &&
@ -2909,9 +2929,10 @@ void CellArea::mouseMoveEvent(QMouseEvent *event) {
: QString::fromStdWString(levelName) + QString(" ") +
QString::fromStdString(frameNumber));
}
} else if (isSoundColumn && o->rect(PredefinedRect::PREVIEW_TRACK)
.adjusted(0, 0, -frameAdj, 0)
.contains(mouseInCell))
} else if (isSoundColumn &&
o->rect(PredefinedRect::PREVIEW_TRACK)
.adjusted(0, 0, -frameAdj, 0)
.contains(mouseInCell))
m_tooltip = tr("Click and drag to play");
else if (m_levelExtenderRect.contains(pos))
m_tooltip = tr("Click and drag to repeat selected cells");
@ -3292,6 +3313,7 @@ void CellArea::createCellMenu(QMenu &menu, bool isCellSelected, TXshCell cell) {
menu.addAction(cmdManager->getAction(MI_Clear));
menu.addAction(cmdManager->getAction(MI_Insert));
menu.addAction(cmdManager->getAction(MI_CreateBlankDrawing));
menu.addAction(cmdManager->getAction(MI_Duplicate));
menu.addSeparator();
@ -3330,6 +3352,8 @@ void CellArea::createCellMenu(QMenu &menu, bool isCellSelected, TXshCell cell) {
TApp::instance()->getCurrentLevel()->getLevel()->getChildLevel()))
menu.addAction(cmdManager->getAction(MI_LipSyncPopup));
} else {
menu.addAction(cmdManager->getAction(MI_CreateBlankDrawing));
menu.addSeparator();
menu.addAction(cmdManager->getAction(MI_FillEmptyCell));
if (cameraCellsSelected) {
menu.addSeparator();