diff --git a/toonz/sources/include/tools/tool.h b/toonz/sources/include/tools/tool.h index 9402091..8ce93ed 100644 --- a/toonz/sources/include/tools/tool.h +++ b/toonz/sources/include/tools/tool.h @@ -446,8 +446,8 @@ return true if the method execution can have changed the current tool int getFrame(); //!< Returns the actual frame in use. int getColumnIndex(); //!< Returns the actual column index. - TStageObjectId - getObjectId(); //!< Returns a pointer to the actual stage object. + TStageObjectId getObjectId() + const; //!< Returns a pointer to the actual stage object. void notifyImageChanged(); //!< Notifies changes on the actual image; used to //! update @@ -503,7 +503,7 @@ transformation. QString updateEnabled(); //!< Sets the tool's \a enability and returns a //! reason in case the tool was disabled. - QString updateEnabled(int rowIndex, int columnIndex); + virtual QString updateEnabled(int rowIndex, int columnIndex); bool isColumnLocked(int columnIndex) const; diff --git a/toonz/sources/tnztools/edittool.cpp b/toonz/sources/tnztools/edittool.cpp index 3471fdf..e4b3a17 100644 --- a/toonz/sources/tnztools/edittool.cpp +++ b/toonz/sources/tnztools/edittool.cpp @@ -613,6 +613,15 @@ public: } }; +bool hasVisibleChildColumn(const TStageObject *obj, const TXsheet *xsh) { + if (!obj->getId().isColumn()) return false; // just in case + if (xsh->getColumn(obj->getId().getIndex())->isCamstandVisible()) return true; + for (const auto child : obj->getChildren()) { + if (hasVisibleChildColumn(child, xsh)) return true; + } + return false; +} + //============================================================================= } // namespace //----------------------------------------------------------------------------- @@ -699,6 +708,7 @@ public: bool doesApply() const; // ritorna vero se posso deformare l'oggetto corrente void saveOldValues(); + bool transformEnabled() const; const TStroke *getSpline() const; @@ -738,6 +748,8 @@ public: } void drawText(const TPointD &p, double unit, std::string text); + + QString updateEnabled(int rowIndex, int columnIndex) override; }; //----------------------------------------------------------------------------- @@ -890,6 +902,16 @@ bool EditTool::doesApply() const { //----------------------------------------------------------------------------- +bool EditTool::transformEnabled() const { + // check if the column transformation is enabled + TXsheet *xsh = getXsheet(); + TStageObjectId objId(getObjectId()); + TStageObject *pegbar = xsh->getStageObject(objId); + return (!objId.isColumn() || hasVisibleChildColumn(pegbar, xsh)); +} + +//----------------------------------------------------------------------------- + const TStroke *EditTool::getSpline() const { TTool::Application *app = TTool::getApplication(); TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); @@ -971,7 +993,7 @@ void EditTool::leftButtonDown(const TPointD &ppos, const TMouseEvent &e) { m_dragTool = m_fxGadgetController->createDragTool(m_highlightedDevice); } - if (!m_dragTool) { + if (!m_dragTool && transformEnabled()) { switch (m_what) { case Center: m_dragTool = new DragCenterTool(m_lockCenterX.getValue(), @@ -1389,6 +1411,12 @@ void EditTool::draw() { /*-- Show nothing on Level Editing mode --*/ if (TTool::getApplication()->getCurrentFrame()->isEditingLevel()) return; + + // if the column and its children are all hidden, only draw fx gadgets + if (!transformEnabled()) { + m_fxGadgetController->draw(isPicking()); + return; + } const TPixel32 normalColor(250, 127, 240); const TPixel32 highlightedColor(150, 255, 140); @@ -1396,10 +1424,11 @@ void EditTool::draw() { TXsheet *xsh = getXsheet(); /*-- Obtain ID of the current editing stage object --*/ TStageObjectId objId = getObjectId(); - int frame = getFrame(); - TAffine parentAff = xsh->getParentPlacement(objId, frame); - TAffine aff = xsh->getPlacement(objId, frame); - TPointD center = Stage::inch * xsh->getCenter(objId, frame); + + int frame = getFrame(); + TAffine parentAff = xsh->getParentPlacement(objId, frame); + TAffine aff = xsh->getPlacement(objId, frame); + TPointD center = Stage::inch * xsh->getCenter(objId, frame); /*-- Enable Z translation on 3D view --*/ if (getViewer()->is3DView()) { @@ -1676,7 +1705,7 @@ int EditTool::getCursorId() const { // cursor for controling the fx gadget if (m_highlightedDevice >= 1000) ret = ToolCursor::FxGadgetCursor; - else { + else if (transformEnabled()) { // switch cursors depending on the active axis std::wstring activeAxis = m_activeAxis.getValue(); if (activeAxis == L"Position") { @@ -1724,12 +1753,66 @@ int EditTool::getCursorId() const { ret = ToolCursor::MoveCursor; } else ret = ToolCursor::StrokeSelectCursor; - } + } else + return ToolCursor::DisableCursor; // precise control with pressing Alt key if (m_isAltPressed) ret = ret | ToolCursor::Ex_Precise; return ret; } +//----------------------------------------------------------------------------- +// overriding TTool::updateEnabled() +QString EditTool::updateEnabled(int rowIndex, int columnIndex) { + // toolType = TTool::ColumnTool + // targetType = TTool::AllTargets; + + // Disable every tool during playback + if (m_application->getCurrentFrame()->isPlaying()) + return (enable(false), QString()); + + // Disable in Level Strip + if (m_application->getCurrentFrame()->isEditingLevel()) + return ( + enable(false), + QObject::tr("The current tool cannot be used in Level Strip mode.")); + + // if an object other than column is selected, then enable the tool + // regardless of the current column state + TStageObjectId objId = m_application->getCurrentObject()->getObjectId(); + if (!objId.isColumn()) return (enable(true), QString()); + + // Retrieve vars and view modes + TXsheet *xsh = m_application->getCurrentXsheet()->getXsheet(); + // if a column object is selected, switch the inspected column to it + TXshColumn *column = xsh->getColumn(objId.getIndex()); + + // disable if the column is empty + if (!column || column->isEmpty()) return (enable(false), QString()); + + 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.")); + + // Enable to control Fx gadgets even on the locked or hidden columns + if (m_fxGadgetController && m_fxGadgetController->hasGadget()) + return (enable(true), QString()); + + // Check against unplaced columns + if (column->isLocked()) + return (enable(false), QObject::tr("The current column is locked.")); + + // check if the current column and all of its child columns are hidden + if (!hasVisibleChildColumn(xsh->getStageObject(objId), xsh)) + return (enable(false), QObject::tr("The current column is hidden.")); + + return (enable(true), QString()); +} + //============================================================================= EditTool arrowTool; diff --git a/toonz/sources/tnztools/tool.cpp b/toonz/sources/tnztools/tool.cpp index 4032da2..d7e1905 100644 --- a/toonz/sources/tnztools/tool.cpp +++ b/toonz/sources/tnztools/tool.cpp @@ -581,7 +581,7 @@ int TTool::getColumnIndex() { //----------------------------------------------------------------------------- -TStageObjectId TTool::getObjectId() { +TStageObjectId TTool::getObjectId() const { if (!m_application) return TStageObjectId(); return m_application->getCurrentObject()->getObjectId(); } @@ -825,6 +825,7 @@ QString TTool::updateEnabled() { return updateEnabled(rowIndex, columnIndex); } +// See the overridden function EditTool::updateEnabled() for the Animate Tool QString TTool::updateEnabled(int rowIndex, int columnIndex) { // Disable every tool during playback if (m_application->getCurrentFrame()->isPlaying()) @@ -905,17 +906,6 @@ QString TTool::updateEnabled(int rowIndex, int columnIndex) { (m_name == T_Type || m_name == T_Geometric || m_name == T_Brush)) return (enable(false), QString()); - // In case of Animate Tool - if (m_name == T_Edit && !filmstrip) { - // if an object other than column is selected, then enable the tool - // regardless of the current column state - if (!m_application->getCurrentObject()->getObjectId().isColumn()) - return (enable(true), QString()); - // if a column object is selected, switch the inspected column to it - column = xsh->getColumn( - m_application->getCurrentObject()->getObjectId().getIndex()); - } - bool isZeraryCol = column ? (column->getZeraryFxColumn() ? true : false) : false; bool isPaletteCol = @@ -1091,17 +1081,17 @@ void TTool::Viewer::getGuidedFrameIdx(int *backIdx, int *frontIdx) { for (int i = 0; i < mosCount; i++) { int cmos = osMask.getMos(i); if (cmos == 0) continue; // skip current - if (cmos < 0 && (!mosBack || cmos > mosBack)) mosBack = cmos; + if (cmos < 0 && (!mosBack || cmos > mosBack)) mosBack = cmos; if (cmos > 0 && (!mosFront || cmos < mosFront)) mosFront = cmos; } - if (mosBack) *backIdx = mosBack + cidx; + if (mosBack) *backIdx = mosBack + cidx; if (mosFront) *frontIdx = mosFront + cidx; // Get closest fixed onionskin for (int i = 0; i < fosCount; i++) { int cfos = osMask.getFos(i); if (cfos == cidx) continue; // skip current - if (cfos < cidx && (fosBack == -1 || cfos > fosBack)) fosBack = cfos; + if (cfos < cidx && (fosBack == -1 || cfos > fosBack)) fosBack = cfos; if (cfos > cidx && (fosFront == -1 || cfos < fosFront)) fosFront = cfos; } @@ -1119,17 +1109,17 @@ void TTool::Viewer::getGuidedFrameIdx(int *backIdx, int *frontIdx) { for (int i = 0; i < mosCount; i++) { int cmos = osMask.getMos(i); if (cmos == 0) continue; // skip current - if (cmos < 0 && (!mosBack || cmos < mosBack)) mosBack = cmos; + if (cmos < 0 && (!mosBack || cmos < mosBack)) mosBack = cmos; if (cmos > 0 && (!mosFront || cmos > mosFront)) mosFront = cmos; } - if (mosBack) *backIdx = mosBack + cidx; + if (mosBack) *backIdx = mosBack + cidx; if (mosFront) *frontIdx = mosFront + cidx; // Get fixed onionskin for (int i = 0; i < fosCount; i++) { int cfos = osMask.getFos(i); if (cfos == cidx) continue; // skip current - if (cfos < cidx && (fosBack == -1 || cfos < fosBack)) fosBack = cfos; + if (cfos < cidx && (fosBack == -1 || cfos < fosBack)) fosBack = cfos; if (cfos > cidx && (fosFront == -1 || cfos > fosFront)) fosFront = cfos; } @@ -1174,7 +1164,7 @@ void TTool::Viewer::doPickGuideStroke(const TPointD &pos) { TXsheet *xsh = getApplication()->getCurrentXsheet()->getXsheet(); int col = getApplication()->getCurrentColumn()->getColumnIndex(); if (xsh && col >= 0) { - TXshCell cell = xsh->getCell(os, col); + TXshCell cell = xsh->getCell(os, col); if (!cell.isEmpty()) fid = cell.getFrameId(); } } else @@ -1257,9 +1247,9 @@ void TTool::tweenSelectedGuideStrokes() { TXsheet *xsh = m_application->getCurrentXsheet()->getXsheet(); int col = m_application->getCurrentColumn()->getColumnIndex(); if (xsh && col >= 0) { - TXshCell cell = xsh->getCell(backIdx, col); + TXshCell cell = xsh->getCell(backIdx, col); if (!cell.isEmpty()) bFid = cell.getFrameId(); - cell = xsh->getCell(frontIdx, col); + cell = xsh->getCell(frontIdx, col); if (!cell.isEmpty()) fFid = cell.getFrameId(); } } else { @@ -1347,7 +1337,7 @@ void TTool::tweenGuideStrokeToSelected() { TXsheet *xsh = m_application->getCurrentXsheet()->getXsheet(); int col = m_application->getCurrentColumn()->getColumnIndex(); if (xsh && col >= 0) { - TXshCell cell = xsh->getCell(backIdx, col); + TXshCell cell = xsh->getCell(backIdx, col); if (!cell.isEmpty()) bFid = cell.getFrameId(); } } else @@ -1361,7 +1351,7 @@ void TTool::tweenGuideStrokeToSelected() { TXsheet *xsh = m_application->getCurrentXsheet()->getXsheet(); int col = m_application->getCurrentColumn()->getColumnIndex(); if (xsh && col >= 0) { - TXshCell cell = xsh->getCell(frontIdx, col); + TXshCell cell = xsh->getCell(frontIdx, col); if (!cell.isEmpty()) fFid = cell.getFrameId(); } } else @@ -1455,7 +1445,7 @@ void TTool::flipGuideStrokeDirection(int mode) { TXsheet *xsh = getApplication()->getCurrentXsheet()->getXsheet(); int col = getApplication()->getCurrentColumn()->getColumnIndex(); if (xsh && col >= 0) { - TXshCell cell = xsh->getCell(os, col); + TXshCell cell = xsh->getCell(os, col); if (!cell.isEmpty()) fid = cell.getFrameId(); } } else