shift and trace improvement (#2240)
This commit is contained in:
parent
e5a0a35b95
commit
1d5937a1fe
25 changed files with 559 additions and 192 deletions
|
@ -607,7 +607,8 @@ public:
|
||||||
//! onionskins)
|
//! onionskins)
|
||||||
//! (window coordinate, pixels, bottom-left origin)
|
//! (window coordinate, pixels, bottom-left origin)
|
||||||
virtual int posToRow(const TPointD &p, double distance,
|
virtual int posToRow(const TPointD &p, double distance,
|
||||||
bool includeInvisible = true) const = 0;
|
bool includeInvisible = true,
|
||||||
|
bool currentColumnOnly = false) const = 0;
|
||||||
|
|
||||||
//! return pos in pixel, bottom-left origin
|
//! return pos in pixel, bottom-left origin
|
||||||
virtual TPointD worldToPos(const TPointD &worldPos) const = 0;
|
virtual TPointD worldToPos(const TPointD &worldPos) const = 0;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <QToolBar>
|
#include <QToolBar>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QRadioButton>
|
||||||
|
|
||||||
// STD includes
|
// STD includes
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -678,15 +679,25 @@ protected slots:
|
||||||
|
|
||||||
class ShiftTraceToolOptionBox final : public ToolOptionsBox {
|
class ShiftTraceToolOptionBox final : public ToolOptionsBox {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
QPushButton *m_resetPrevGhostBtn;
|
QFrame *m_prevFrame, *m_afterFrame;
|
||||||
QPushButton *m_resetAfterGhostBtn;
|
QRadioButton *m_prevRadioBtn, *m_afterRadioBtn;
|
||||||
|
QPushButton *m_resetPrevGhostBtn, *m_resetAfterGhostBtn;
|
||||||
|
TTool *m_tool;
|
||||||
void resetGhost(int index);
|
void resetGhost(int index);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void showEvent(QShowEvent *);
|
||||||
|
void hideEvent(QShowEvent *);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ShiftTraceToolOptionBox(QWidget *parent = 0);
|
ShiftTraceToolOptionBox(QWidget *parent = 0, TTool *tool = 0);
|
||||||
|
void updateStatus() override;
|
||||||
protected slots:
|
protected slots:
|
||||||
void onResetPrevGhostBtnPressed();
|
void onResetPrevGhostBtnPressed();
|
||||||
void onResetAfterGhostBtnPressed();
|
void onResetAfterGhostBtnPressed();
|
||||||
|
void onPrevRadioBtnClicked();
|
||||||
|
void onAfterRadioBtnClicked();
|
||||||
|
void updateColors();
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
@ -507,6 +507,11 @@ public:
|
||||||
}
|
}
|
||||||
bool getOnionSkinDuringPlayback() { return m_onionSkinDuringPlayback; }
|
bool getOnionSkinDuringPlayback() { return m_onionSkinDuringPlayback; }
|
||||||
void setOnionSkinDuringPlayback(bool on);
|
void setOnionSkinDuringPlayback(bool on);
|
||||||
|
|
||||||
|
void useOnionColorsForShiftAndTraceGhosts(bool on);
|
||||||
|
bool areOnionColorsUsedForShiftAndTraceGhosts() const {
|
||||||
|
return m_useOnionColorsForShiftAndTraceGhosts;
|
||||||
|
}
|
||||||
// Transparency Check tab
|
// Transparency Check tab
|
||||||
|
|
||||||
void setTranspCheckData(const TPixel &bg, const TPixel &ink,
|
void setTranspCheckData(const TPixel &bg, const TPixel &ink,
|
||||||
|
@ -711,7 +716,8 @@ private:
|
||||||
|
|
||||||
TPixel32 m_currentColumnColor;
|
TPixel32 m_currentColumnColor;
|
||||||
|
|
||||||
bool m_enableWinInk = false;
|
bool m_enableWinInk = false;
|
||||||
|
bool m_useOnionColorsForShiftAndTraceGhosts = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Preferences();
|
Preferences();
|
||||||
|
|
|
@ -107,6 +107,8 @@ public:
|
||||||
static double m_firstBackOnionSkin;
|
static double m_firstBackOnionSkin;
|
||||||
static double m_lastBackVisibleSkin;
|
static double m_lastBackVisibleSkin;
|
||||||
|
|
||||||
|
static bool m_isShiftAndTraceEnabled;
|
||||||
|
|
||||||
TPixel32 m_filterColor;
|
TPixel32 m_filterColor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -289,6 +289,8 @@ class DVAPI Picker final : public Visitor {
|
||||||
TAffine m_viewAff;
|
TAffine m_viewAff;
|
||||||
double m_minDist2;
|
double m_minDist2;
|
||||||
|
|
||||||
|
int m_currentColumnIndex = -1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Picker(const TAffine &viewAff, const TPointD &p,
|
Picker(const TAffine &viewAff, const TPointD &p,
|
||||||
const ImagePainter::VisualSettings &vs);
|
const ImagePainter::VisualSettings &vs);
|
||||||
|
@ -304,6 +306,8 @@ public:
|
||||||
int getColumnIndex() const;
|
int getColumnIndex() const;
|
||||||
void getColumnIndexes(std::vector<int> &indexes) const;
|
void getColumnIndexes(std::vector<int> &indexes) const;
|
||||||
int getRow() const;
|
int getRow() const;
|
||||||
|
|
||||||
|
void setCurrentColumnIndex(int index) { m_currentColumnIndex = index; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
|
@ -36,6 +36,7 @@ set(HEADERS ${MOC_HEADERS}
|
||||||
../include/tools/toolutils.h
|
../include/tools/toolutils.h
|
||||||
../include/tools/RGBpicker.h
|
../include/tools/RGBpicker.h
|
||||||
mypainttoonzbrush.h
|
mypainttoonzbrush.h
|
||||||
|
shifttracetool.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
|
@ -96,6 +97,7 @@ set(SOURCES
|
||||||
fingertool.cpp
|
fingertool.cpp
|
||||||
rulertool.cpp
|
rulertool.cpp
|
||||||
mypainttoonzbrush.cpp
|
mypainttoonzbrush.cpp
|
||||||
|
shifttracetool.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(RESOURCES tnztools.qrc)
|
set(RESOURCES tnztools.qrc)
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "toonz/onionskinmask.h"
|
#include "toonz/onionskinmask.h"
|
||||||
#include "toonz/tonionskinmaskhandle.h"
|
#include "toonz/tonionskinmaskhandle.h"
|
||||||
#include "tools/cursors.h"
|
#include "tools/cursors.h"
|
||||||
#include "tools/tool.h"
|
|
||||||
#include "timage.h"
|
#include "timage.h"
|
||||||
#include "trasterimage.h"
|
#include "trasterimage.h"
|
||||||
#include "ttoonzimage.h"
|
#include "ttoonzimage.h"
|
||||||
|
@ -15,10 +14,10 @@
|
||||||
#include "toonz/tframehandle.h"
|
#include "toonz/tframehandle.h"
|
||||||
#include "toonz/tcolumnhandle.h"
|
#include "toonz/tcolumnhandle.h"
|
||||||
#include "toonz/txshlevelhandle.h"
|
#include "toonz/txshlevelhandle.h"
|
||||||
|
#include "tools/toolhandle.h"
|
||||||
#include "toonz/txshsimplelevel.h"
|
#include "toonz/txshsimplelevel.h"
|
||||||
#include "toonz/dpiscale.h"
|
#include "toonz/dpiscale.h"
|
||||||
#include "toonz/stage.h"
|
#include "toonz/stage.h"
|
||||||
#include "tapp.h"
|
|
||||||
#include "tpixel.h"
|
#include "tpixel.h"
|
||||||
#include "toonzqt/menubarcommand.h"
|
#include "toonzqt/menubarcommand.h"
|
||||||
|
|
||||||
|
@ -51,97 +50,6 @@ static bool circumCenter(TPointD &out, const TPointD &a, const TPointD &b,
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
class ShiftTraceTool final : public TTool {
|
|
||||||
public:
|
|
||||||
enum CurveStatus {
|
|
||||||
NoCurve,
|
|
||||||
TwoPointsCurve, // just during the first click&drag
|
|
||||||
ThreePointsCurve
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GadgetId {
|
|
||||||
NoGadget,
|
|
||||||
NoGadget_InBox,
|
|
||||||
CurveP0Gadget,
|
|
||||||
CurveP1Gadget,
|
|
||||||
CurvePmGadget,
|
|
||||||
MoveCenterGadget,
|
|
||||||
RotateGadget,
|
|
||||||
TranslateGadget,
|
|
||||||
ScaleGadget
|
|
||||||
};
|
|
||||||
inline bool isCurveGadget(GadgetId id) const {
|
|
||||||
return CurveP0Gadget <= id && id <= CurvePmGadget;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
TPointD m_oldPos, m_startPos;
|
|
||||||
int m_ghostIndex;
|
|
||||||
TPointD m_p0, m_p1, m_p2;
|
|
||||||
|
|
||||||
CurveStatus m_curveStatus;
|
|
||||||
GadgetId m_gadget;
|
|
||||||
GadgetId m_highlightedGadget;
|
|
||||||
|
|
||||||
TRectD m_box;
|
|
||||||
TAffine m_dpiAff;
|
|
||||||
int m_row[2];
|
|
||||||
TAffine m_aff[2];
|
|
||||||
TPointD m_center[2];
|
|
||||||
|
|
||||||
TAffine m_oldAff;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ShiftTraceTool();
|
|
||||||
|
|
||||||
ToolType getToolType() const override { return GenericTool; }
|
|
||||||
|
|
||||||
void clearData();
|
|
||||||
void updateData();
|
|
||||||
void updateBox();
|
|
||||||
void updateCurveAffs();
|
|
||||||
void updateGhost();
|
|
||||||
|
|
||||||
void reset() override {
|
|
||||||
int ghostIndex = m_ghostIndex;
|
|
||||||
onActivate();
|
|
||||||
invalidate();
|
|
||||||
m_ghostIndex = ghostIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouseMove(const TPointD &, const TMouseEvent &e) override;
|
|
||||||
void leftButtonDown(const TPointD &, const TMouseEvent &) override;
|
|
||||||
void leftButtonDrag(const TPointD &, const TMouseEvent &) override;
|
|
||||||
void leftButtonUp(const TPointD &, const TMouseEvent &) override;
|
|
||||||
void draw() override;
|
|
||||||
|
|
||||||
TAffine getGhostAff();
|
|
||||||
GadgetId getGadget(const TPointD &);
|
|
||||||
void drawDot(const TPointD ¢er, double r,
|
|
||||||
const TPixel32 &color = TPixel32::White);
|
|
||||||
void drawControlRect();
|
|
||||||
void drawCurve();
|
|
||||||
|
|
||||||
void onActivate() override {
|
|
||||||
m_ghostIndex = 0;
|
|
||||||
m_curveStatus = NoCurve;
|
|
||||||
clearData();
|
|
||||||
OnionSkinMask osm =
|
|
||||||
TApp::instance()->getCurrentOnionSkin()->getOnionSkinMask();
|
|
||||||
m_aff[0] = osm.getShiftTraceGhostAff(0);
|
|
||||||
m_aff[1] = osm.getShiftTraceGhostAff(1);
|
|
||||||
m_center[0] = osm.getShiftTraceGhostCenter(0);
|
|
||||||
m_center[1] = osm.getShiftTraceGhostCenter(1);
|
|
||||||
}
|
|
||||||
void onDeactivate() override {
|
|
||||||
QAction *action = CommandManager::instance()->getAction("MI_EditShift");
|
|
||||||
action->setChecked(false);
|
|
||||||
}
|
|
||||||
bool isEventAcceptable(QEvent *e) override;
|
|
||||||
|
|
||||||
int getCursorId() const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
ShiftTraceTool::ShiftTraceTool()
|
ShiftTraceTool::ShiftTraceTool()
|
||||||
: TTool("T_ShiftTrace")
|
: TTool("T_ShiftTrace")
|
||||||
, m_ghostIndex(0)
|
, m_ghostIndex(0)
|
||||||
|
@ -170,7 +78,7 @@ void ShiftTraceTool::updateBox() {
|
||||||
|
|
||||||
TImageP img;
|
TImageP img;
|
||||||
|
|
||||||
TApp *app = TApp::instance();
|
TApplication *app = TTool::getApplication();
|
||||||
if (app->getCurrentFrame()->isEditingScene()) {
|
if (app->getCurrentFrame()->isEditingScene()) {
|
||||||
int col = app->getCurrentColumn()->getColumnIndex();
|
int col = app->getCurrentColumn()->getColumnIndex();
|
||||||
int row = m_row[m_ghostIndex];
|
int row = m_row[m_ghostIndex];
|
||||||
|
@ -214,10 +122,9 @@ void ShiftTraceTool::updateData() {
|
||||||
m_box = TRectD();
|
m_box = TRectD();
|
||||||
for (int i = 0; i < 2; i++) m_row[i] = -1;
|
for (int i = 0; i < 2; i++) m_row[i] = -1;
|
||||||
m_dpiAff = TAffine();
|
m_dpiAff = TAffine();
|
||||||
TApp *app = TApp::instance();
|
TApplication *app = TTool::getApplication();
|
||||||
|
|
||||||
OnionSkinMask osm =
|
OnionSkinMask osm = app->getCurrentOnionSkin()->getOnionSkinMask();
|
||||||
TApp::instance()->getCurrentOnionSkin()->getOnionSkinMask();
|
|
||||||
int previousOffset = osm.getShiftTraceGhostFrameOffset(0);
|
int previousOffset = osm.getShiftTraceGhostFrameOffset(0);
|
||||||
int forwardOffset = osm.getShiftTraceGhostFrameOffset(1);
|
int forwardOffset = osm.getShiftTraceGhostFrameOffset(1);
|
||||||
// we must find the prev (m_row[0]) and next (m_row[1]) reference images
|
// we must find the prev (m_row[0]) and next (m_row[1]) reference images
|
||||||
|
@ -284,12 +191,23 @@ void ShiftTraceTool::updateCurveAffs() {
|
||||||
|
|
||||||
void ShiftTraceTool::updateGhost() {
|
void ShiftTraceTool::updateGhost() {
|
||||||
OnionSkinMask osm =
|
OnionSkinMask osm =
|
||||||
TApp::instance()->getCurrentOnionSkin()->getOnionSkinMask();
|
TTool::getApplication()->getCurrentOnionSkin()->getOnionSkinMask();
|
||||||
osm.setShiftTraceGhostAff(0, m_aff[0]);
|
osm.setShiftTraceGhostAff(0, m_aff[0]);
|
||||||
osm.setShiftTraceGhostAff(1, m_aff[1]);
|
osm.setShiftTraceGhostAff(1, m_aff[1]);
|
||||||
osm.setShiftTraceGhostCenter(0, m_center[0]);
|
osm.setShiftTraceGhostCenter(0, m_center[0]);
|
||||||
osm.setShiftTraceGhostCenter(1, m_center[1]);
|
osm.setShiftTraceGhostCenter(1, m_center[1]);
|
||||||
TApp::instance()->getCurrentOnionSkin()->setOnionSkinMask(osm);
|
TTool::getApplication()->getCurrentOnionSkin()->setOnionSkinMask(osm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShiftTraceTool::reset() {
|
||||||
|
int ghostIndex = m_ghostIndex;
|
||||||
|
onActivate();
|
||||||
|
invalidate();
|
||||||
|
m_ghostIndex = ghostIndex;
|
||||||
|
|
||||||
|
TTool::getApplication()
|
||||||
|
->getCurrentTool()
|
||||||
|
->notifyToolChanged(); // Refreshes toolbar values
|
||||||
}
|
}
|
||||||
|
|
||||||
TAffine ShiftTraceTool::getGhostAff() {
|
TAffine ShiftTraceTool::getGhostAff() {
|
||||||
|
@ -417,6 +335,23 @@ void ShiftTraceTool::drawCurve() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShiftTraceTool::onActivate() {
|
||||||
|
m_ghostIndex = 0;
|
||||||
|
m_curveStatus = NoCurve;
|
||||||
|
clearData();
|
||||||
|
OnionSkinMask osm =
|
||||||
|
TTool::getApplication()->getCurrentOnionSkin()->getOnionSkinMask();
|
||||||
|
m_aff[0] = osm.getShiftTraceGhostAff(0);
|
||||||
|
m_aff[1] = osm.getShiftTraceGhostAff(1);
|
||||||
|
m_center[0] = osm.getShiftTraceGhostCenter(0);
|
||||||
|
m_center[1] = osm.getShiftTraceGhostCenter(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShiftTraceTool::onDeactivate() {
|
||||||
|
QAction *action = CommandManager::instance()->getAction("MI_EditShift");
|
||||||
|
action->setChecked(false);
|
||||||
|
}
|
||||||
|
|
||||||
ShiftTraceTool::GadgetId ShiftTraceTool::getGadget(const TPointD &p) {
|
ShiftTraceTool::GadgetId ShiftTraceTool::getGadget(const TPointD &p) {
|
||||||
std::vector<std::pair<TPointD, GadgetId>> gadgets;
|
std::vector<std::pair<TPointD, GadgetId>> gadgets;
|
||||||
gadgets.push_back(std::make_pair(m_p0, CurveP0Gadget));
|
gadgets.push_back(std::make_pair(m_p0, CurveP0Gadget));
|
||||||
|
@ -505,6 +440,8 @@ void ShiftTraceTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
|
||||||
m_gadget = m_highlightedGadget;
|
m_gadget = m_highlightedGadget;
|
||||||
m_oldPos = m_startPos = pos;
|
m_oldPos = m_startPos = pos;
|
||||||
|
|
||||||
|
bool notify = false;
|
||||||
|
|
||||||
if (m_gadget == NoGadget || m_gadget == NoGadget_InBox) {
|
if (m_gadget == NoGadget || m_gadget == NoGadget_InBox) {
|
||||||
if (!e.isCtrlPressed()) {
|
if (!e.isCtrlPressed()) {
|
||||||
if (m_gadget == NoGadget_InBox)
|
if (m_gadget == NoGadget_InBox)
|
||||||
|
@ -513,13 +450,13 @@ void ShiftTraceTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
|
||||||
m_gadget = RotateGadget;
|
m_gadget = RotateGadget;
|
||||||
// m_curveStatus = NoCurve;
|
// m_curveStatus = NoCurve;
|
||||||
}
|
}
|
||||||
int row = getViewer()->posToRow(e.m_pos, 5 * getPixelSize(), false);
|
int row = getViewer()->posToRow(e.m_pos, 5 * getPixelSize(), false, true);
|
||||||
if (row >= 0) {
|
if (row >= 0) {
|
||||||
int index = -1;
|
int index = -1;
|
||||||
TApp *app = TApp::instance();
|
TApplication *app = TTool::getApplication();
|
||||||
if (app->getCurrentFrame()->isEditingScene()) {
|
if (app->getCurrentFrame()->isEditingScene()) {
|
||||||
int currentRow = getFrame();
|
int currentRow = getFrame();
|
||||||
if (m_row[0] >= 0 && row <= currentRow)
|
if (m_row[0] >= 0 && row < currentRow)
|
||||||
index = 0;
|
index = 0;
|
||||||
else if (m_row[1] >= 0 && row > currentRow)
|
else if (m_row[1] >= 0 && row > currentRow)
|
||||||
index = 1;
|
index = 1;
|
||||||
|
@ -535,12 +472,19 @@ void ShiftTraceTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
|
||||||
updateBox();
|
updateBox();
|
||||||
m_gadget = TranslateGadget;
|
m_gadget = TranslateGadget;
|
||||||
m_highlightedGadget = TranslateGadget;
|
m_highlightedGadget = TranslateGadget;
|
||||||
|
notify = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_oldAff = m_aff[m_ghostIndex];
|
m_oldAff = m_aff[m_ghostIndex];
|
||||||
invalidate();
|
invalidate();
|
||||||
|
|
||||||
|
if (notify) {
|
||||||
|
TTool::getApplication()
|
||||||
|
->getCurrentTool()
|
||||||
|
->notifyToolChanged(); // Refreshes toolbar values
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShiftTraceTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
|
void ShiftTraceTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
|
||||||
|
@ -613,6 +557,10 @@ void ShiftTraceTool::leftButtonUp(const TPointD &pos, const TMouseEvent &) {
|
||||||
}
|
}
|
||||||
m_gadget = NoGadget;
|
m_gadget = NoGadget;
|
||||||
invalidate();
|
invalidate();
|
||||||
|
|
||||||
|
TTool::getApplication()
|
||||||
|
->getCurrentTool()
|
||||||
|
->notifyToolChanged(); // Refreshes toolbar values
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShiftTraceTool::draw() {
|
void ShiftTraceTool::draw() {
|
||||||
|
@ -639,4 +587,17 @@ bool ShiftTraceTool::isEventAcceptable(QEvent *e) {
|
||||||
return (Qt::Key_F1 <= key && key <= Qt::Key_F3);
|
return (Qt::Key_F1 <= key && key <= Qt::Key_F3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShiftTraceTool::onLeave() {
|
||||||
|
OnionSkinMask osm =
|
||||||
|
TTool::getApplication()->getCurrentOnionSkin()->getOnionSkinMask();
|
||||||
|
osm.clearGhostFlipKey();
|
||||||
|
TTool::getApplication()->getCurrentOnionSkin()->setOnionSkinMask(osm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShiftTraceTool::setCurrentGhostIndex(int index) {
|
||||||
|
m_ghostIndex = index;
|
||||||
|
updateBox();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
ShiftTraceTool shiftTraceTool;
|
ShiftTraceTool shiftTraceTool;
|
82
toonz/sources/tnztools/shifttracetool.h
Normal file
82
toonz/sources/tnztools/shifttracetool.h
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tools/tool.h"
|
||||||
|
|
||||||
|
class ShiftTraceTool final : public TTool {
|
||||||
|
public:
|
||||||
|
enum CurveStatus {
|
||||||
|
NoCurve,
|
||||||
|
TwoPointsCurve, // just during the first click&drag
|
||||||
|
ThreePointsCurve
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GadgetId {
|
||||||
|
NoGadget,
|
||||||
|
NoGadget_InBox,
|
||||||
|
CurveP0Gadget,
|
||||||
|
CurveP1Gadget,
|
||||||
|
CurvePmGadget,
|
||||||
|
MoveCenterGadget,
|
||||||
|
RotateGadget,
|
||||||
|
TranslateGadget,
|
||||||
|
ScaleGadget
|
||||||
|
};
|
||||||
|
inline bool isCurveGadget(GadgetId id) const {
|
||||||
|
return CurveP0Gadget <= id && id <= CurvePmGadget;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TPointD m_oldPos, m_startPos;
|
||||||
|
int m_ghostIndex;
|
||||||
|
TPointD m_p0, m_p1, m_p2;
|
||||||
|
|
||||||
|
CurveStatus m_curveStatus;
|
||||||
|
GadgetId m_gadget;
|
||||||
|
GadgetId m_highlightedGadget;
|
||||||
|
|
||||||
|
TRectD m_box;
|
||||||
|
TAffine m_dpiAff;
|
||||||
|
int m_row[2];
|
||||||
|
TAffine m_aff[2];
|
||||||
|
TPointD m_center[2];
|
||||||
|
|
||||||
|
TAffine m_oldAff;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ShiftTraceTool();
|
||||||
|
|
||||||
|
ToolType getToolType() const override { return GenericTool; }
|
||||||
|
|
||||||
|
void clearData();
|
||||||
|
void updateData();
|
||||||
|
void updateBox();
|
||||||
|
void updateCurveAffs();
|
||||||
|
void updateGhost();
|
||||||
|
|
||||||
|
void reset() override;
|
||||||
|
|
||||||
|
void mouseMove(const TPointD &, const TMouseEvent &e) override;
|
||||||
|
void leftButtonDown(const TPointD &, const TMouseEvent &) override;
|
||||||
|
void leftButtonDrag(const TPointD &, const TMouseEvent &) override;
|
||||||
|
void leftButtonUp(const TPointD &, const TMouseEvent &) override;
|
||||||
|
void draw() override;
|
||||||
|
|
||||||
|
TAffine getGhostAff();
|
||||||
|
GadgetId getGadget(const TPointD &);
|
||||||
|
void drawDot(const TPointD ¢er, double r,
|
||||||
|
const TPixel32 &color = TPixel32::White);
|
||||||
|
void drawControlRect();
|
||||||
|
void drawCurve();
|
||||||
|
|
||||||
|
void onActivate() override;
|
||||||
|
void onDeactivate() override;
|
||||||
|
|
||||||
|
void onLeave() override;
|
||||||
|
|
||||||
|
bool isEventAcceptable(QEvent *e) override;
|
||||||
|
|
||||||
|
int getCursorId() const override;
|
||||||
|
|
||||||
|
int getCurrentGhostIndex() { return m_ghostIndex; }
|
||||||
|
void setCurrentGhostIndex(int index);
|
||||||
|
};
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
//#include "rgbpickertool.h"
|
//#include "rgbpickertool.h"
|
||||||
#include "rulertool.h"
|
#include "rulertool.h"
|
||||||
|
#include "shifttracetool.h"
|
||||||
|
|
||||||
// TnzQt includes
|
// TnzQt includes
|
||||||
#include "toonzqt/dvdialog.h"
|
#include "toonzqt/dvdialog.h"
|
||||||
|
@ -2501,24 +2502,58 @@ void StylePickerToolOptionsBox::updateRealTimePickLabel(const int ink,
|
||||||
// ShiftTraceToolOptionBox
|
// ShiftTraceToolOptionBox
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ShiftTraceToolOptionBox::ShiftTraceToolOptionBox(QWidget *parent)
|
ShiftTraceToolOptionBox::ShiftTraceToolOptionBox(QWidget *parent, TTool *tool)
|
||||||
: ToolOptionsBox(parent) {
|
: ToolOptionsBox(parent), m_tool(tool) {
|
||||||
setFrameStyle(QFrame::StyledPanel);
|
setFrameStyle(QFrame::StyledPanel);
|
||||||
setFixedHeight(26);
|
setFixedHeight(26);
|
||||||
|
|
||||||
m_resetPrevGhostBtn =
|
m_prevFrame = new QFrame(this);
|
||||||
new QPushButton(tr("Reset Shift of Previous Drawing"), this);
|
m_afterFrame = new QFrame(this);
|
||||||
m_resetAfterGhostBtn =
|
|
||||||
new QPushButton(tr("Reset Shift of Forward Drawing"), this);
|
|
||||||
|
|
||||||
|
m_resetPrevGhostBtn = new QPushButton(tr("Reset Previous"), this);
|
||||||
|
m_resetAfterGhostBtn = new QPushButton(tr("Reset Following"), this);
|
||||||
|
|
||||||
|
m_prevRadioBtn = new QRadioButton(tr("Previous Drawing"), this);
|
||||||
|
m_afterRadioBtn = new QRadioButton(tr("Following Drawing"), this);
|
||||||
|
|
||||||
|
m_prevFrame->setFixedSize(10, 21);
|
||||||
|
m_afterFrame->setFixedSize(10, 21);
|
||||||
|
|
||||||
|
m_layout->addWidget(m_prevFrame, 0);
|
||||||
|
m_layout->addWidget(m_prevRadioBtn, 0);
|
||||||
m_layout->addWidget(m_resetPrevGhostBtn, 0);
|
m_layout->addWidget(m_resetPrevGhostBtn, 0);
|
||||||
|
|
||||||
|
m_layout->addWidget(new DVGui::Separator("", this, false));
|
||||||
|
|
||||||
|
m_layout->addWidget(m_afterFrame, 0);
|
||||||
|
m_layout->addWidget(m_afterRadioBtn, 0);
|
||||||
m_layout->addWidget(m_resetAfterGhostBtn, 0);
|
m_layout->addWidget(m_resetAfterGhostBtn, 0);
|
||||||
|
|
||||||
m_layout->addStretch(1);
|
m_layout->addStretch(1);
|
||||||
|
|
||||||
connect(m_resetPrevGhostBtn, SIGNAL(clicked()), this,
|
connect(m_resetPrevGhostBtn, SIGNAL(clicked(bool)), this,
|
||||||
SLOT(onResetPrevGhostBtnPressed()));
|
SLOT(onResetPrevGhostBtnPressed()));
|
||||||
connect(m_resetAfterGhostBtn, SIGNAL(clicked()), this,
|
connect(m_resetAfterGhostBtn, SIGNAL(clicked(bool)), this,
|
||||||
SLOT(onResetAfterGhostBtnPressed()));
|
SLOT(onResetAfterGhostBtnPressed()));
|
||||||
|
connect(m_prevRadioBtn, SIGNAL(clicked(bool)), this,
|
||||||
|
SLOT(onPrevRadioBtnClicked()));
|
||||||
|
connect(m_afterRadioBtn, SIGNAL(clicked(bool)), this,
|
||||||
|
SLOT(onAfterRadioBtnClicked()));
|
||||||
|
|
||||||
|
updateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShiftTraceToolOptionBox::showEvent(QShowEvent *) {
|
||||||
|
TTool::Application *app = TTool::getApplication();
|
||||||
|
connect(app->getCurrentOnionSkin(), SIGNAL(onionSkinMaskChanged()), this,
|
||||||
|
SLOT(updateColors()));
|
||||||
|
updateColors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShiftTraceToolOptionBox::hideEvent(QShowEvent *) {
|
||||||
|
TTool::Application *app = TTool::getApplication();
|
||||||
|
disconnect(app->getCurrentOnionSkin(), SIGNAL(onionSkinMaskChanged()), this,
|
||||||
|
SLOT(updateColors()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShiftTraceToolOptionBox::resetGhost(int index) {
|
void ShiftTraceToolOptionBox::resetGhost(int index) {
|
||||||
|
@ -2530,12 +2565,68 @@ void ShiftTraceToolOptionBox::resetGhost(int index) {
|
||||||
app->getCurrentOnionSkin()->notifyOnionSkinMaskChanged();
|
app->getCurrentOnionSkin()->notifyOnionSkinMaskChanged();
|
||||||
TTool *tool = app->getCurrentTool()->getTool();
|
TTool *tool = app->getCurrentTool()->getTool();
|
||||||
if (tool) tool->reset();
|
if (tool) tool->reset();
|
||||||
|
|
||||||
|
if (index == 0)
|
||||||
|
m_resetPrevGhostBtn->setDisabled(true);
|
||||||
|
else // index == 1
|
||||||
|
m_resetAfterGhostBtn->setDisabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShiftTraceToolOptionBox::onResetPrevGhostBtnPressed() { resetGhost(0); }
|
void ShiftTraceToolOptionBox::onResetPrevGhostBtnPressed() { resetGhost(0); }
|
||||||
|
|
||||||
void ShiftTraceToolOptionBox::onResetAfterGhostBtnPressed() { resetGhost(1); }
|
void ShiftTraceToolOptionBox::onResetAfterGhostBtnPressed() { resetGhost(1); }
|
||||||
|
|
||||||
|
void ShiftTraceToolOptionBox::updateColors() {
|
||||||
|
TPixel front, back;
|
||||||
|
bool ink;
|
||||||
|
Preferences::instance()->getOnionData(front, back, ink);
|
||||||
|
|
||||||
|
m_prevFrame->setStyleSheet(QString("background:rgb(%1,%2,%3,255);")
|
||||||
|
.arg((int)back.r)
|
||||||
|
.arg((int)back.g)
|
||||||
|
.arg((int)back.b));
|
||||||
|
m_afterFrame->setStyleSheet(QString("background:rgb(%1,%2,%3,255);")
|
||||||
|
.arg((int)front.r)
|
||||||
|
.arg((int)front.g)
|
||||||
|
.arg((int)front.b));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShiftTraceToolOptionBox::updateStatus() {
|
||||||
|
TTool::Application *app = TTool::getApplication();
|
||||||
|
OnionSkinMask osm = app->getCurrentOnionSkin()->getOnionSkinMask();
|
||||||
|
if (osm.getShiftTraceGhostAff(0).isIdentity() &&
|
||||||
|
osm.getShiftTraceGhostCenter(0) == TPointD())
|
||||||
|
m_resetPrevGhostBtn->setDisabled(true);
|
||||||
|
else
|
||||||
|
m_resetPrevGhostBtn->setEnabled(true);
|
||||||
|
|
||||||
|
if (osm.getShiftTraceGhostAff(1).isIdentity() &&
|
||||||
|
osm.getShiftTraceGhostCenter(1) == TPointD())
|
||||||
|
m_resetAfterGhostBtn->setDisabled(true);
|
||||||
|
else
|
||||||
|
m_resetAfterGhostBtn->setEnabled(true);
|
||||||
|
|
||||||
|
// Check the ghost index
|
||||||
|
ShiftTraceTool *stTool = (ShiftTraceTool *)m_tool;
|
||||||
|
if (!stTool) return;
|
||||||
|
if (stTool->getCurrentGhostIndex() == 0)
|
||||||
|
m_prevRadioBtn->setChecked(true);
|
||||||
|
else // ghostIndex == 1
|
||||||
|
m_afterRadioBtn->setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShiftTraceToolOptionBox::onPrevRadioBtnClicked() {
|
||||||
|
ShiftTraceTool *stTool = (ShiftTraceTool *)m_tool;
|
||||||
|
if (!stTool) return;
|
||||||
|
stTool->setCurrentGhostIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShiftTraceToolOptionBox::onAfterRadioBtnClicked() {
|
||||||
|
ShiftTraceTool *stTool = (ShiftTraceTool *)m_tool;
|
||||||
|
if (!stTool) return;
|
||||||
|
stTool->setCurrentGhostIndex(1);
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// ToolOptions
|
// ToolOptions
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -2645,7 +2736,7 @@ void ToolOptions::onToolSwitched() {
|
||||||
panel = new StylePickerToolOptionsBox(0, tool, currPalette, currTool,
|
panel = new StylePickerToolOptionsBox(0, tool, currPalette, currTool,
|
||||||
app->getPaletteController());
|
app->getPaletteController());
|
||||||
else if (tool->getName() == "T_ShiftTrace")
|
else if (tool->getName() == "T_ShiftTrace")
|
||||||
panel = new ShiftTraceToolOptionBox(this);
|
panel = new ShiftTraceToolOptionBox(this, tool);
|
||||||
else
|
else
|
||||||
panel = tool->createOptionsBox(); // Only this line should remain out
|
panel = tool->createOptionsBox(); // Only this line should remain out
|
||||||
// of that if/else monstrosity
|
// of that if/else monstrosity
|
||||||
|
|
|
@ -107,7 +107,6 @@ set(MOC_HEADERS
|
||||||
sceneviewerevents.h
|
sceneviewerevents.h
|
||||||
scriptconsolepanel.h
|
scriptconsolepanel.h
|
||||||
selectionutils.h
|
selectionutils.h
|
||||||
shifttracetool.h
|
|
||||||
shortcutpopup.h
|
shortcutpopup.h
|
||||||
soundtrackexport.h
|
soundtrackexport.h
|
||||||
startuppopup.h
|
startuppopup.h
|
||||||
|
@ -255,7 +254,6 @@ set(SOURCES
|
||||||
sceneviewercontextmenu.cpp
|
sceneviewercontextmenu.cpp
|
||||||
scenesettingspopup.cpp
|
scenesettingspopup.cpp
|
||||||
scriptconsolepanel.cpp
|
scriptconsolepanel.cpp
|
||||||
shifttracetool.cpp
|
|
||||||
shortcutpopup.cpp
|
shortcutpopup.cpp
|
||||||
soundtrackexport.cpp
|
soundtrackexport.cpp
|
||||||
startuppopup.cpp
|
startuppopup.cpp
|
||||||
|
|
18
toonz/sources/toonz/Resources/shift_and_trace.svg
Normal file
18
toonz/sources/toonz/Resources/shift_and_trace.svg
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
||||||
|
y="0px" width="24px" height="24px" viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;stroke:#000000;stroke-miterlimit:10;}
|
||||||
|
.st1{fill:none;stroke:#000000;stroke-linecap:round;stroke-miterlimit:10;}
|
||||||
|
.st2{fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;}
|
||||||
|
.st3{fill:none;stroke:#FFFFFF;stroke-linecap:round;stroke-miterlimit:10;}
|
||||||
|
</style>
|
||||||
|
<path class="st0" d="M19.5,9.2c0-4.3-3.4-7.7-7.5-7.7S4.5,4.9,4.5,9.2c0,4.9,4.9,6.3,4.9,10.5c0,2,1.2,2.8,2.6,2.8
|
||||||
|
c1.5,0,2.6-0.8,2.6-2.8C14.6,15.5,19.5,14.1,19.5,9.2z"/>
|
||||||
|
<rect x="10" y="10.5" class="st1" width="4" height="7"/>
|
||||||
|
<g>
|
||||||
|
<line class="st2" x1="8.5" y1="18.5" x2="15.5" y2="18.5"/>
|
||||||
|
<line class="st3" x1="8.5" y1="18.5" x2="15.5" y2="18.5"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1 KiB |
59
toonz/sources/toonz/Resources/shift_and_trace_edit.svg
Normal file
59
toonz/sources/toonz/Resources/shift_and_trace_edit.svg
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
||||||
|
y="0px" width="24px" height="24px" viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;stroke:#000000;stroke-miterlimit:10;}
|
||||||
|
.st1{fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;}
|
||||||
|
.st2{fill:none;stroke:#FFFFFF;stroke-linecap:round;stroke-miterlimit:10;}
|
||||||
|
.st3{fill:none;stroke:#000000;stroke-linecap:round;stroke-miterlimit:10;}
|
||||||
|
.st4{fill:none;stroke:#000000;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st5{fill:#FFFFFF;}
|
||||||
|
.st6{display:none;}
|
||||||
|
.st7{display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st8{display:inline;fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<path class="st0" d="M12.5,7c0-3-2.5-5.5-5.5-5.5S1.5,4,1.5,7c0,3.5,3.6,4.5,3.6,7.5c0,1.5,0.9,2,1.9,2c1.1,0,1.9-0.5,1.9-2
|
||||||
|
C8.9,11.5,12.5,10.5,12.5,7z"/>
|
||||||
|
<g>
|
||||||
|
<line class="st1" x1="4.5" y1="13.5" x2="9.5" y2="13.5"/>
|
||||||
|
<line class="st2" x1="4.5" y1="13.5" x2="9.5" y2="13.5"/>
|
||||||
|
</g>
|
||||||
|
<rect x="5.5" y="7.5" class="st3" width="3" height="5"/>
|
||||||
|
<line class="st1" x1="15.5" y1="10.5" x2="15.5" y2="20.5"/>
|
||||||
|
<line class="st1" x1="10.5" y1="15.5" x2="19.5" y2="15.5"/>
|
||||||
|
<polygon class="st4" points="17.5,20 13.5,20 15.5,22.5 "/>
|
||||||
|
<polygon class="st4" points="19.8,13.5 19.8,17.5 22.3,15.5 "/>
|
||||||
|
<polygon class="st4" points="13.5,11 17.5,11 15.5,8.5 "/>
|
||||||
|
<polygon class="st4" points="11,17.5 11,13.5 8.5,15.5 "/>
|
||||||
|
<polygon class="st5" points="19.8,13.5 19.8,17.5 22.3,15.5 "/>
|
||||||
|
<polygon class="st5" points="13.5,11 17.5,11 15.5,8.5 "/>
|
||||||
|
<polygon class="st5" points="11,17.5 11,13.5 8.5,15.5 "/>
|
||||||
|
<polygon class="st5" points="17.5,20 13.5,20 15.5,22.5 "/>
|
||||||
|
<line class="st2" x1="15.5" y1="10.5" x2="15.5" y2="20.5"/>
|
||||||
|
<line class="st2" x1="10.5" y1="15.5" x2="20.5" y2="15.5"/>
|
||||||
|
<g class="st6">
|
||||||
|
<polygon class="st7" points="13.7,9 16.1,9 15.5,12.6 "/>
|
||||||
|
<polygon class="st8" points="13.7,9 16.1,9 15.5,12.6 "/>
|
||||||
|
</g>
|
||||||
|
<g class="st6">
|
||||||
|
<polygon class="st7" points="17.3,22 14.9,22 15.5,18.5 "/>
|
||||||
|
<polygon class="st8" points="17.3,22 14.9,22 15.5,18.5 "/>
|
||||||
|
</g>
|
||||||
|
<g class="st6">
|
||||||
|
<polygon class="st7" points="20.2,10.7 21.4,12.8 18.1,14 "/>
|
||||||
|
<polygon class="st8" points="20.2,10.7 21.4,12.8 18.1,14 "/>
|
||||||
|
</g>
|
||||||
|
<g class="st6">
|
||||||
|
<polygon class="st7" points="10.8,20.3 9.6,18.2 13,17 "/>
|
||||||
|
<polygon class="st8" points="10.8,20.3 9.6,18.2 13,17 "/>
|
||||||
|
</g>
|
||||||
|
<g class="st6">
|
||||||
|
<polygon class="st7" points="9,13.8 10.2,11.8 13,14 "/>
|
||||||
|
<polygon class="st8" points="9,13.8 10.2,11.8 13,14 "/>
|
||||||
|
</g>
|
||||||
|
<g class="st6">
|
||||||
|
<polygon class="st7" points="22,17.2 20.8,19.3 18.1,17 "/>
|
||||||
|
<polygon class="st8" points="22,17.2 20.8,19.3 18.1,17 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
56
toonz/sources/toonz/Resources/shift_and_trace_reset.svg
Normal file
56
toonz/sources/toonz/Resources/shift_and_trace_reset.svg
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
||||||
|
y="0px" width="24px" height="24px" viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;stroke:#000000;stroke-miterlimit:10;}
|
||||||
|
.st1{fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;}
|
||||||
|
.st2{fill:none;stroke:#FFFFFF;stroke-linecap:round;stroke-miterlimit:10;}
|
||||||
|
.st3{fill:none;stroke:#000000;stroke-linecap:round;stroke-miterlimit:10;}
|
||||||
|
.st4{display:none;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-miterlimit:10;}
|
||||||
|
.st5{display:none;fill:none;stroke:#000000;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st6{display:none;fill:#FFFFFF;}
|
||||||
|
.st7{display:none;fill:none;stroke:#FFFFFF;stroke-linecap:round;stroke-miterlimit:10;}
|
||||||
|
.st8{fill:none;stroke:#000000;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st9{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<path class="st0" d="M12.5,7c0-3-2.5-5.5-5.5-5.5S1.5,4,1.5,7c0,3.5,3.6,4.5,3.6,7.5c0,1.5,0.9,2,1.9,2c1.1,0,1.9-0.5,1.9-2
|
||||||
|
C8.9,11.5,12.5,10.5,12.5,7z"/>
|
||||||
|
<g>
|
||||||
|
<line class="st1" x1="4.5" y1="13.5" x2="9.5" y2="13.5"/>
|
||||||
|
<line class="st2" x1="4.5" y1="13.5" x2="9.5" y2="13.5"/>
|
||||||
|
</g>
|
||||||
|
<rect x="5.5" y="7.5" class="st3" width="3" height="5"/>
|
||||||
|
<line class="st4" x1="13.5" y1="10.5" x2="13.5" y2="18.5"/>
|
||||||
|
<line class="st4" x1="10.5" y1="15.5" x2="16.5" y2="15.5"/>
|
||||||
|
<polygon class="st5" points="16.8,13.5 16.8,17.5 19.3,15.5 "/>
|
||||||
|
<polygon class="st5" points="11.5,11 15.5,11 13.5,8.5 "/>
|
||||||
|
<polygon class="st6" points="16.8,13.5 16.8,17.5 19.3,15.5 "/>
|
||||||
|
<polygon class="st6" points="11.5,11 15.5,11 13.5,8.5 "/>
|
||||||
|
<line class="st7" x1="13.5" y1="10.5" x2="13.5" y2="18.5"/>
|
||||||
|
<line class="st7" x1="10.5" y1="15.5" x2="17.5" y2="15.5"/>
|
||||||
|
<g>
|
||||||
|
<polygon class="st8" points="13.7,9 16.1,9 15.5,12.6 "/>
|
||||||
|
<polygon class="st9" points="13.7,9 16.1,9 15.5,12.6 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polygon class="st8" points="17.3,22 14.9,22 15.5,18.5 "/>
|
||||||
|
<polygon class="st9" points="17.3,22 14.9,22 15.5,18.5 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polygon class="st8" points="20.2,10.7 21.4,12.8 18.1,14 "/>
|
||||||
|
<polygon class="st9" points="20.2,10.7 21.4,12.8 18.1,14 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polygon class="st8" points="10.8,20.3 9.6,18.2 13,17 "/>
|
||||||
|
<polygon class="st9" points="10.8,20.3 9.6,18.2 13,17 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polygon class="st8" points="9,13.8 10.2,11.8 13,14 "/>
|
||||||
|
<polygon class="st9" points="9,13.8 10.2,11.8 13,14 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polygon class="st8" points="22,17.2 20.8,19.3 18.1,17 "/>
|
||||||
|
<polygon class="st9" points="22,17.2 20.8,19.3 18.1,17 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
|
@ -1956,13 +1956,16 @@ void MainWindow::defineActions() {
|
||||||
MenuViewCommandType);
|
MenuViewCommandType);
|
||||||
createToggle(MI_ACheck, tr("&Gap Check"), "", ACheckToggleAction ? 1 : 0,
|
createToggle(MI_ACheck, tr("&Gap Check"), "", ACheckToggleAction ? 1 : 0,
|
||||||
MenuViewCommandType);
|
MenuViewCommandType);
|
||||||
createToggle(MI_ShiftTrace, tr("Shift and Trace"), "", false,
|
QAction* shiftTraceAction = createToggle(MI_ShiftTrace, tr("Shift and Trace"), "", false,
|
||||||
MenuViewCommandType);
|
MenuViewCommandType);
|
||||||
createToggle(MI_EditShift, tr("Edit Shift"), "", false, MenuViewCommandType);
|
shiftTraceAction->setIcon(QIcon(":Resources/shift_and_trace.svg"));
|
||||||
|
shiftTraceAction = createToggle(MI_EditShift, tr("Edit Shift"), "", false, MenuViewCommandType);
|
||||||
|
shiftTraceAction->setIcon(QIcon(":Resources/shift_and_trace_edit.svg"));
|
||||||
createToggle(MI_NoShift, tr("No Shift"), "", false, MenuViewCommandType);
|
createToggle(MI_NoShift, tr("No Shift"), "", false, MenuViewCommandType);
|
||||||
CommandManager::instance()->enable(MI_EditShift, false);
|
CommandManager::instance()->enable(MI_EditShift, false);
|
||||||
CommandManager::instance()->enable(MI_NoShift, false);
|
CommandManager::instance()->enable(MI_NoShift, false);
|
||||||
createAction(MI_ResetShift, tr("Reset Shift"), "", MenuViewCommandType);
|
shiftTraceAction = createAction(MI_ResetShift, tr("Reset Shift"), "", MenuViewCommandType);
|
||||||
|
shiftTraceAction->setIcon(QIcon(":Resources/shift_and_trace_reset.svg"));
|
||||||
|
|
||||||
if (QGLPixelBuffer::hasOpenGLPbuffers())
|
if (QGLPixelBuffer::hasOpenGLPbuffers())
|
||||||
createToggle(MI_RasterizePli, tr("&Visualize Vector As Raster"), "",
|
createToggle(MI_RasterizePli, tr("&Visualize Vector As Raster"), "",
|
||||||
|
|
|
@ -506,6 +506,7 @@ void PreferencesPopup::onOnionDataChanged(const TPixel32 &, bool isDragging) {
|
||||||
|
|
||||||
TApp::instance()->getCurrentScene()->notifySceneChanged();
|
TApp::instance()->getCurrentScene()->notifySceneChanged();
|
||||||
TApp::instance()->getCurrentLevel()->notifyLevelViewChange();
|
TApp::instance()->getCurrentLevel()->notifyLevelViewChange();
|
||||||
|
TApp::instance()->getCurrentOnionSkin()->notifyOnionSkinMaskChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -806,6 +807,12 @@ void PreferencesPopup::onOnionSkinDuringPlaybackChanged(int index) {
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void PreferencesPopup::onOnionColorsForShiftAndTraceChanged(int index) {
|
||||||
|
m_pref->useOnionColorsForShiftAndTraceGhosts(index == Qt::Checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void PreferencesPopup::onGuidedDrawingStyleChanged(int index) {
|
void PreferencesPopup::onGuidedDrawingStyleChanged(int index) {
|
||||||
m_pref->setAnimatedGuidedDrawing(index);
|
m_pref->setAnimatedGuidedDrawing(index);
|
||||||
}
|
}
|
||||||
|
@ -1533,9 +1540,11 @@ PreferencesPopup::PreferencesPopup()
|
||||||
m_onionSkinVisibility = new CheckBox(tr("Onion Skin ON"));
|
m_onionSkinVisibility = new CheckBox(tr("Onion Skin ON"));
|
||||||
m_onionSkinDuringPlayback =
|
m_onionSkinDuringPlayback =
|
||||||
new CheckBox(tr("Show Onion Skin During Playback"));
|
new CheckBox(tr("Show Onion Skin During Playback"));
|
||||||
m_frontOnionColor = new ColorField(this, false, frontColor);
|
m_frontOnionColor = new ColorField(this, false, frontColor);
|
||||||
m_backOnionColor = new ColorField(this, false, backColor);
|
m_backOnionColor = new ColorField(this, false, backColor);
|
||||||
m_inksOnly = new DVGui::CheckBox(tr("Display Lines Only "));
|
m_useOnionColorsForShiftAndTraceCB = new CheckBox(
|
||||||
|
tr("Use Onion Skin Colors for Reference Drawings of Shift and Trace"));
|
||||||
|
m_inksOnly = new DVGui::CheckBox(tr("Display Lines Only "));
|
||||||
m_inksOnly->setChecked(onlyInks);
|
m_inksOnly->setChecked(onlyInks);
|
||||||
|
|
||||||
int thickness = m_pref->getOnionPaperThickness();
|
int thickness = m_pref->getOnionPaperThickness();
|
||||||
|
@ -1898,6 +1907,8 @@ PreferencesPopup::PreferencesPopup()
|
||||||
m_onionSkinDuringPlayback->setChecked(m_pref->getOnionSkinDuringPlayback());
|
m_onionSkinDuringPlayback->setChecked(m_pref->getOnionSkinDuringPlayback());
|
||||||
m_frontOnionColor->setEnabled(m_pref->isOnionSkinEnabled());
|
m_frontOnionColor->setEnabled(m_pref->isOnionSkinEnabled());
|
||||||
m_backOnionColor->setEnabled(m_pref->isOnionSkinEnabled());
|
m_backOnionColor->setEnabled(m_pref->isOnionSkinEnabled());
|
||||||
|
m_useOnionColorsForShiftAndTraceCB->setChecked(
|
||||||
|
m_pref->areOnionColorsUsedForShiftAndTraceGhosts());
|
||||||
m_inksOnly->setEnabled(m_pref->isOnionSkinEnabled());
|
m_inksOnly->setEnabled(m_pref->isOnionSkinEnabled());
|
||||||
QStringList guidedDrawingStyles;
|
QStringList guidedDrawingStyles;
|
||||||
guidedDrawingStyles << tr("Arrow Markers") << tr("Animated Guide");
|
guidedDrawingStyles << tr("Arrow Markers") << tr("Animated Guide");
|
||||||
|
@ -2558,6 +2569,8 @@ PreferencesPopup::PreferencesPopup()
|
||||||
onionLay->addWidget(m_inksOnly, 0, Qt::AlignLeft | Qt::AlignVCenter);
|
onionLay->addWidget(m_inksOnly, 0, Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
onionLay->addWidget(m_onionSkinDuringPlayback, 0,
|
onionLay->addWidget(m_onionSkinDuringPlayback, 0,
|
||||||
Qt::AlignLeft | Qt::AlignVCenter);
|
Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
|
onionLay->addWidget(m_useOnionColorsForShiftAndTraceCB, 0,
|
||||||
|
Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
QGridLayout *guidedDrawingLay = new QGridLayout();
|
QGridLayout *guidedDrawingLay = new QGridLayout();
|
||||||
{
|
{
|
||||||
guidedDrawingLay->addWidget(new QLabel(tr("Vector Guided Style:")), 0,
|
guidedDrawingLay->addWidget(new QLabel(tr("Vector Guided Style:")), 0,
|
||||||
|
@ -2952,6 +2965,9 @@ PreferencesPopup::PreferencesPopup()
|
||||||
SLOT(onOnionSkinVisibilityChanged(int)));
|
SLOT(onOnionSkinVisibilityChanged(int)));
|
||||||
ret = ret && connect(m_onionSkinDuringPlayback, SIGNAL(stateChanged(int)),
|
ret = ret && connect(m_onionSkinDuringPlayback, SIGNAL(stateChanged(int)),
|
||||||
SLOT(onOnionSkinDuringPlaybackChanged(int)));
|
SLOT(onOnionSkinDuringPlaybackChanged(int)));
|
||||||
|
ret = ret &&
|
||||||
|
connect(m_useOnionColorsForShiftAndTraceCB, SIGNAL(stateChanged(int)),
|
||||||
|
SLOT(onOnionColorsForShiftAndTraceChanged(int)));
|
||||||
ret = ret && connect(m_onionPaperThickness, SIGNAL(editingFinished()),
|
ret = ret && connect(m_onionPaperThickness, SIGNAL(editingFinished()),
|
||||||
SLOT(onOnionPaperThicknessChanged()));
|
SLOT(onOnionPaperThicknessChanged()));
|
||||||
ret = ret && connect(m_guidedDrawingStyle, SIGNAL(currentIndexChanged(int)),
|
ret = ret && connect(m_guidedDrawingStyle, SIGNAL(currentIndexChanged(int)),
|
||||||
|
|
|
@ -82,7 +82,8 @@ private:
|
||||||
*m_useHigherDpiOnVectorSimplifyCB, *m_keepFillOnVectorSimplifyCB,
|
*m_useHigherDpiOnVectorSimplifyCB, *m_keepFillOnVectorSimplifyCB,
|
||||||
*m_newLevelToCameraSizeCB, *m_ignoreImageDpiCB,
|
*m_newLevelToCameraSizeCB, *m_ignoreImageDpiCB,
|
||||||
*m_syncLevelRenumberWithXsheet, *m_downArrowInLevelStripCreatesNewFrame,
|
*m_syncLevelRenumberWithXsheet, *m_downArrowInLevelStripCreatesNewFrame,
|
||||||
*m_enableAutoStretch, *m_enableWinInk;
|
*m_enableAutoStretch, *m_enableWinInk,
|
||||||
|
*m_useOnionColorsForShiftAndTraceCB;
|
||||||
|
|
||||||
DVGui::FileField *m_customProjectRootFileField;
|
DVGui::FileField *m_customProjectRootFileField;
|
||||||
|
|
||||||
|
@ -182,6 +183,7 @@ private slots:
|
||||||
void onReplaceAfterSaveLevelAsChanged(int index);
|
void onReplaceAfterSaveLevelAsChanged(int index);
|
||||||
void onOnionSkinVisibilityChanged(int);
|
void onOnionSkinVisibilityChanged(int);
|
||||||
void onOnionSkinDuringPlaybackChanged(int);
|
void onOnionSkinDuringPlaybackChanged(int);
|
||||||
|
void onOnionColorsForShiftAndTraceChanged(int);
|
||||||
void onGuidedDrawingStyleChanged(int);
|
void onGuidedDrawingStyleChanged(int);
|
||||||
void onActualPixelOnSceneModeChanged(int);
|
void onActualPixelOnSceneModeChanged(int);
|
||||||
void onMultiLayerStylePickerChanged(int);
|
void onMultiLayerStylePickerChanged(int);
|
||||||
|
|
|
@ -2376,7 +2376,7 @@ includeInvisible);
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
int SceneViewer::posToRow(const TPointD &p, double distance,
|
int SceneViewer::posToRow(const TPointD &p, double distance,
|
||||||
bool includeInvisible) const {
|
bool includeInvisible, bool currentColumnOnly) const {
|
||||||
int oldRasterizePli = TXshSimpleLevel::m_rasterizePli;
|
int oldRasterizePli = TXshSimpleLevel::m_rasterizePli;
|
||||||
TApp *app = TApp::instance();
|
TApp *app = TApp::instance();
|
||||||
OnionSkinMask osm = app->getCurrentOnionSkin()->getOnionSkinMask();
|
OnionSkinMask osm = app->getCurrentOnionSkin()->getOnionSkinMask();
|
||||||
|
@ -2405,6 +2405,8 @@ int SceneViewer::posToRow(const TPointD &p, double distance,
|
||||||
args.m_osm = &osm;
|
args.m_osm = &osm;
|
||||||
args.m_onlyVisible = includeInvisible;
|
args.m_onlyVisible = includeInvisible;
|
||||||
|
|
||||||
|
if (currentColumnOnly) picker.setCurrentColumnIndex(currentColumnIndex);
|
||||||
|
|
||||||
Stage::visit(picker, args);
|
Stage::visit(picker, args);
|
||||||
}
|
}
|
||||||
TXshSimpleLevel::m_rasterizePli = oldRasterizePli;
|
TXshSimpleLevel::m_rasterizePli = oldRasterizePli;
|
||||||
|
|
|
@ -370,8 +370,8 @@ protected:
|
||||||
//! return the row of the drawings intersecting point \b p (used with onion
|
//! return the row of the drawings intersecting point \b p (used with onion
|
||||||
//! skins)
|
//! skins)
|
||||||
//! (window coordinate, pixels, bottom-left origin)
|
//! (window coordinate, pixels, bottom-left origin)
|
||||||
int posToRow(const TPointD &p, double distance,
|
int posToRow(const TPointD &p, double distance, bool includeInvisible = true,
|
||||||
bool includeInvisible = true) const override;
|
bool currentColumnOnly = false) const override;
|
||||||
|
|
||||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||||
void dropEvent(QDropEvent *event) override;
|
void dropEvent(QDropEvent *event) override;
|
||||||
|
|
|
@ -365,6 +365,11 @@ void SceneViewer::onLeave() {
|
||||||
if (m_freezedStatus != NO_FREEZED) return;
|
if (m_freezedStatus != NO_FREEZED) return;
|
||||||
TTool *tool = TApp::instance()->getCurrentTool()->getTool();
|
TTool *tool = TApp::instance()->getCurrentTool()->getTool();
|
||||||
if (tool && tool->isEnabled()) tool->onLeave();
|
if (tool && tool->isEnabled()) tool->onLeave();
|
||||||
|
|
||||||
|
// force reset the flipping of shift & trace
|
||||||
|
if (CommandManager::instance()->getAction(MI_ShiftTrace)->isChecked())
|
||||||
|
TTool::getTool("T_ShiftTrace", TTool::ToonzImage)->onLeave();
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
#pragma once
|
|
|
@ -465,5 +465,8 @@
|
||||||
<file>Resources/colorchiporder_upleft.svg</file>
|
<file>Resources/colorchiporder_upleft.svg</file>
|
||||||
<file>Resources/timeline2xsheet.svg</file>
|
<file>Resources/timeline2xsheet.svg</file>
|
||||||
<file>Resources/xsheet2timeline.svg</file>
|
<file>Resources/xsheet2timeline.svg</file>
|
||||||
|
<file>Resources/shift_and_trace.svg</file>
|
||||||
|
<file>Resources/shift_and_trace_edit.svg</file>
|
||||||
|
<file>Resources/shift_and_trace_reset.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -344,7 +344,8 @@ Preferences::Preferences()
|
||||||
, m_cursorBrushStyle("Default")
|
, m_cursorBrushStyle("Default")
|
||||||
, m_cursorOutlineEnabled(true)
|
, m_cursorOutlineEnabled(true)
|
||||||
, m_currentColumnColor(TPixel::Black)
|
, m_currentColumnColor(TPixel::Black)
|
||||||
, m_enableWinInk(false) {
|
, m_enableWinInk(false)
|
||||||
|
, m_useOnionColorsForShiftAndTraceGhosts(false) {
|
||||||
TCamera camera;
|
TCamera camera;
|
||||||
m_defLevelType = PLI_XSHLEVEL;
|
m_defLevelType = PLI_XSHLEVEL;
|
||||||
m_defLevelWidth = camera.getSize().lx;
|
m_defLevelWidth = camera.getSize().lx;
|
||||||
|
@ -620,6 +621,8 @@ Preferences::Preferences()
|
||||||
m_moveCurrentFrameByClickCellArea);
|
m_moveCurrentFrameByClickCellArea);
|
||||||
getValue(*m_settings, "onionSkinEnabled", m_onionSkinEnabled);
|
getValue(*m_settings, "onionSkinEnabled", m_onionSkinEnabled);
|
||||||
getValue(*m_settings, "onionSkinDuringPlayback", m_onionSkinDuringPlayback);
|
getValue(*m_settings, "onionSkinDuringPlayback", m_onionSkinDuringPlayback);
|
||||||
|
getValue(*m_settings, "useOnionColorsForShiftAndTraceGhosts",
|
||||||
|
m_useOnionColorsForShiftAndTraceGhosts);
|
||||||
getValue(*m_settings, "multiLayerStylePickerEnabled",
|
getValue(*m_settings, "multiLayerStylePickerEnabled",
|
||||||
m_multiLayerStylePickerEnabled);
|
m_multiLayerStylePickerEnabled);
|
||||||
getValue(*m_settings, "showKeyframesOnXsheetCellArea",
|
getValue(*m_settings, "showKeyframesOnXsheetCellArea",
|
||||||
|
@ -1107,6 +1110,13 @@ void Preferences::setOnionSkinDuringPlayback(bool on) {
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
|
||||||
|
void Preferences::useOnionColorsForShiftAndTraceGhosts(bool on) {
|
||||||
|
m_useOnionColorsForShiftAndTraceGhosts = on;
|
||||||
|
m_settings->setValue("useOnionColorsForShiftAndTraceGhosts", on ? "1" : "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------
|
||||||
|
|
||||||
void Preferences::setShow0ThickLines(bool on) {
|
void Preferences::setShow0ThickLines(bool on) {
|
||||||
m_show0ThickLines = on;
|
m_show0ThickLines = on;
|
||||||
m_settings->setValue(s_show0ThickLines, s_bool[on]);
|
m_settings->setValue(s_show0ThickLines, s_bool[on]);
|
||||||
|
|
|
@ -418,9 +418,6 @@ void StageBuilder::addCell(PlayerSet &players, ToonzScene *scene, TXsheet *xsh,
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (m_shiftTraceGhostId != TRACED)
|
|
||||||
player.m_opacity =
|
|
||||||
UCHAR(255.0 * (1.0 - OnionSkinMask::getOnionSkinFade(1)));
|
|
||||||
int opacity = player.m_opacity;
|
int opacity = player.m_opacity;
|
||||||
player.m_bingoOrder = 10;
|
player.m_bingoOrder = 10;
|
||||||
if (m_onionSkinMask.getShiftTraceStatus() !=
|
if (m_onionSkinMask.getShiftTraceStatus() !=
|
||||||
|
@ -428,13 +425,15 @@ void StageBuilder::addCell(PlayerSet &players, ToonzScene *scene, TXsheet *xsh,
|
||||||
if (m_shiftTraceGhostId == FIRST_GHOST) {
|
if (m_shiftTraceGhostId == FIRST_GHOST) {
|
||||||
player.m_opacity = 30;
|
player.m_opacity = 30;
|
||||||
players.push_back(player);
|
players.push_back(player);
|
||||||
player.m_opacity = opacity;
|
player.m_opacity = opacity;
|
||||||
|
player.m_onionSkinDistance = -1;
|
||||||
player.m_placement =
|
player.m_placement =
|
||||||
m_onionSkinMask.getShiftTraceGhostAff(0) * player.m_placement;
|
m_onionSkinMask.getShiftTraceGhostAff(0) * player.m_placement;
|
||||||
} else if (m_shiftTraceGhostId == SECOND_GHOST) {
|
} else if (m_shiftTraceGhostId == SECOND_GHOST) {
|
||||||
player.m_opacity = 30;
|
player.m_opacity = 30;
|
||||||
players.push_back(player);
|
players.push_back(player);
|
||||||
player.m_opacity = opacity;
|
player.m_opacity = opacity;
|
||||||
|
player.m_onionSkinDistance = 1;
|
||||||
player.m_placement =
|
player.m_placement =
|
||||||
m_onionSkinMask.getShiftTraceGhostAff(1) * player.m_placement;
|
m_onionSkinMask.getShiftTraceGhostAff(1) * player.m_placement;
|
||||||
}
|
}
|
||||||
|
@ -532,32 +531,46 @@ void StageBuilder::addCellWithOnionSkin(PlayerSet &players, ToonzScene *scene,
|
||||||
}
|
}
|
||||||
}; // locals
|
}; // locals
|
||||||
|
|
||||||
if (m_onionSkinMask.isShiftTraceEnabled() && col == m_currentColumnIndex) {
|
if (m_onionSkinMask.isShiftTraceEnabled()) {
|
||||||
TXshCell cell = xsh->getCell(row, col);
|
if (col == m_currentColumnIndex) {
|
||||||
|
TXshCell cell = xsh->getCell(row, col);
|
||||||
|
|
||||||
// First Ghost
|
// First Ghost
|
||||||
int r;
|
int r;
|
||||||
r = row + m_onionSkinMask.getShiftTraceGhostFrameOffset(0);
|
r = row + m_onionSkinMask.getShiftTraceGhostFrameOffset(0);
|
||||||
if (r >= 0 && xsh->getCell(r, col) != cell &&
|
if (r >= 0 && xsh->getCell(r, col) != cell &&
|
||||||
(cell.getSimpleLevel() == 0 ||
|
(cell.getSimpleLevel() == 0 ||
|
||||||
xsh->getCell(r, col).getSimpleLevel() == cell.getSimpleLevel())) {
|
xsh->getCell(r, col).getSimpleLevel() == cell.getSimpleLevel())) {
|
||||||
m_shiftTraceGhostId = FIRST_GHOST;
|
m_shiftTraceGhostId = FIRST_GHOST;
|
||||||
addCell(players, scene, xsh, r, col, level);
|
addCell(players, scene, xsh, r, col, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = row + m_onionSkinMask.getShiftTraceGhostFrameOffset(1);
|
||||||
|
if (r >= 0 && xsh->getCell(r, col) != cell &&
|
||||||
|
(cell.getSimpleLevel() == 0 ||
|
||||||
|
xsh->getCell(r, col).getSimpleLevel() == cell.getSimpleLevel())) {
|
||||||
|
m_shiftTraceGhostId = SECOND_GHOST;
|
||||||
|
addCell(players, scene, xsh, r, col, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw current working frame
|
||||||
|
if (!cell.isEmpty()) {
|
||||||
|
m_shiftTraceGhostId = TRACED;
|
||||||
|
addCell(players, scene, xsh, row, col, level);
|
||||||
|
m_shiftTraceGhostId = NO_GHOST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// flip non-current columns as well
|
||||||
r = row + m_onionSkinMask.getShiftTraceGhostFrameOffset(1);
|
else {
|
||||||
if (r >= 0 && xsh->getCell(r, col) != cell &&
|
int flipKey = m_onionSkinMask.getGhostFlipKey();
|
||||||
(cell.getSimpleLevel() == 0 ||
|
if (flipKey == Qt::Key_F1) {
|
||||||
xsh->getCell(r, col).getSimpleLevel() == cell.getSimpleLevel())) {
|
int r = row + m_onionSkinMask.getShiftTraceGhostFrameOffset(0);
|
||||||
m_shiftTraceGhostId = SECOND_GHOST;
|
addCell(players, scene, xsh, r, col, level);
|
||||||
addCell(players, scene, xsh, r, col, level);
|
} else if (flipKey == Qt::Key_F3) {
|
||||||
}
|
int r = row + m_onionSkinMask.getShiftTraceGhostFrameOffset(1);
|
||||||
|
addCell(players, scene, xsh, r, col, level);
|
||||||
// draw current working frame
|
} else
|
||||||
if (!cell.isEmpty()) {
|
addCell(players, scene, xsh, row, col, level);
|
||||||
m_shiftTraceGhostId = TRACED;
|
|
||||||
addCell(players, scene, xsh, row, col, level);
|
|
||||||
m_shiftTraceGhostId = NO_GHOST;
|
|
||||||
}
|
}
|
||||||
} else if (locals::doStandardOnionSkin(this, xsh, level, col)) {
|
} else if (locals::doStandardOnionSkin(this, xsh, level, col)) {
|
||||||
std::vector<int> rows;
|
std::vector<int> rows;
|
||||||
|
@ -674,17 +687,14 @@ void StageBuilder::addSimpleLevelFrame(PlayerSet &players,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_shiftTraceGhostId != TRACED)
|
|
||||||
player.m_opacity =
|
|
||||||
UCHAR(255.0 * (1.0 - OnionSkinMask::getOnionSkinFade(1)));
|
|
||||||
;
|
|
||||||
int opacity = player.m_opacity;
|
int opacity = player.m_opacity;
|
||||||
player.m_bingoOrder = 10;
|
player.m_bingoOrder = 10;
|
||||||
if (m_onionSkinMask.getShiftTraceStatus() !=
|
if (m_onionSkinMask.getShiftTraceStatus() !=
|
||||||
OnionSkinMask::ENABLED_WITHOUT_GHOST_MOVEMENTS) {
|
OnionSkinMask::ENABLED_WITHOUT_GHOST_MOVEMENTS) {
|
||||||
player.m_opacity = 30;
|
player.m_opacity = 30;
|
||||||
players.push_back(player);
|
players.push_back(player);
|
||||||
player.m_opacity = opacity;
|
player.m_opacity = opacity;
|
||||||
|
player.m_onionSkinDistance = (ghostIndex == 0) ? -1 : 1;
|
||||||
player.m_placement = m_onionSkinMask.getShiftTraceGhostAff(ghostIndex) *
|
player.m_placement = m_onionSkinMask.getShiftTraceGhostAff(ghostIndex) *
|
||||||
player.m_placement;
|
player.m_placement;
|
||||||
}
|
}
|
||||||
|
@ -832,10 +842,11 @@ void Stage::visit(Visitor &visitor, const VisitArgs &args) {
|
||||||
sb.m_onionSkinMask = *osm;
|
sb.m_onionSkinMask = *osm;
|
||||||
sb.m_currentFrameId = args.m_currentFrameId;
|
sb.m_currentFrameId = args.m_currentFrameId;
|
||||||
sb.m_isGuidedDrawingEnabled = args.m_isGuidedDrawingEnabled;
|
sb.m_isGuidedDrawingEnabled = args.m_isGuidedDrawingEnabled;
|
||||||
Player::m_onionSkinFrontSize = 0;
|
Player::m_onionSkinFrontSize = 0;
|
||||||
Player::m_onionSkinBackSize = 0;
|
Player::m_onionSkinBackSize = 0;
|
||||||
Player::m_firstBackOnionSkin = 0;
|
Player::m_firstBackOnionSkin = 0;
|
||||||
Player::m_lastBackVisibleSkin = 0;
|
Player::m_lastBackVisibleSkin = 0;
|
||||||
|
Player::m_isShiftAndTraceEnabled = osm->isShiftTraceEnabled();
|
||||||
sb.addFrame(sb.m_players, scene, xsh, row, 0, args.m_onlyVisible,
|
sb.addFrame(sb.m_players, scene, xsh, row, 0, args.m_onlyVisible,
|
||||||
args.m_checkPreviewVisibility);
|
args.m_checkPreviewVisibility);
|
||||||
|
|
||||||
|
@ -867,14 +878,15 @@ void Stage::visit(Visitor &visitor, TXshSimpleLevel *level, const TFrameId &fid,
|
||||||
const OnionSkinMask &osm, bool isPlaying,
|
const OnionSkinMask &osm, bool isPlaying,
|
||||||
int isGuidedDrawingEnabled) {
|
int isGuidedDrawingEnabled) {
|
||||||
StageBuilder sb;
|
StageBuilder sb;
|
||||||
sb.m_vs = &visitor.m_vs;
|
sb.m_vs = &visitor.m_vs;
|
||||||
sb.m_onionSkinMask = osm;
|
sb.m_onionSkinMask = osm;
|
||||||
sb.m_currentFrameId = fid;
|
sb.m_currentFrameId = fid;
|
||||||
sb.m_isGuidedDrawingEnabled = isGuidedDrawingEnabled;
|
sb.m_isGuidedDrawingEnabled = isGuidedDrawingEnabled;
|
||||||
Player::m_onionSkinFrontSize = 0;
|
Player::m_onionSkinFrontSize = 0;
|
||||||
Player::m_onionSkinBackSize = 0;
|
Player::m_onionSkinBackSize = 0;
|
||||||
Player::m_firstBackOnionSkin = 0;
|
Player::m_firstBackOnionSkin = 0;
|
||||||
Player::m_lastBackVisibleSkin = 0;
|
Player::m_lastBackVisibleSkin = 0;
|
||||||
|
Player::m_isShiftAndTraceEnabled = osm.isShiftTraceEnabled();
|
||||||
sb.addSimpleLevelFrame(sb.m_players, level, fid);
|
sb.addSimpleLevelFrame(sb.m_players, level, fid);
|
||||||
updateOnionSkinSize(sb.m_players);
|
updateOnionSkinSize(sb.m_players);
|
||||||
sb.visit(sb.m_players, visitor, isPlaying);
|
sb.visit(sb.m_players, visitor, isPlaying);
|
||||||
|
|
|
@ -19,10 +19,11 @@ using namespace Stage;
|
||||||
// Stage::Player implementation
|
// Stage::Player implementation
|
||||||
//*****************************************************************************************
|
//*****************************************************************************************
|
||||||
|
|
||||||
double Player::m_onionSkinFrontSize = 0;
|
double Player::m_onionSkinFrontSize = 0;
|
||||||
double Player::m_onionSkinBackSize = 0;
|
double Player::m_onionSkinBackSize = 0;
|
||||||
double Player::m_firstBackOnionSkin = 0;
|
double Player::m_firstBackOnionSkin = 0;
|
||||||
double Player::m_lastBackVisibleSkin = 0;
|
double Player::m_lastBackVisibleSkin = 0;
|
||||||
|
bool Player::m_isShiftAndTraceEnabled = false;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "toonz/txshleveltypes.h"
|
#include "toonz/txshleveltypes.h"
|
||||||
#include "imagebuilders.h"
|
#include "imagebuilders.h"
|
||||||
#include "toonz/tframehandle.h"
|
#include "toonz/tframehandle.h"
|
||||||
|
#include "toonz/preferences.h"
|
||||||
|
|
||||||
// Qt includes
|
// Qt includes
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
|
@ -228,6 +229,12 @@ void Picker::setDistance(double d) { m_minDist2 = d * d; }
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void Picker::onImage(const Stage::Player &player) {
|
void Picker::onImage(const Stage::Player &player) {
|
||||||
|
// if m_currentColumnIndex is other than the default value (-1),
|
||||||
|
// then pick only the current column.
|
||||||
|
if (m_currentColumnIndex != -1 &&
|
||||||
|
m_currentColumnIndex != player.m_ancestorColumnIndex)
|
||||||
|
return;
|
||||||
|
|
||||||
bool picked = false;
|
bool picked = false;
|
||||||
TAffine aff = m_viewAff * player.m_placement;
|
TAffine aff = m_viewAff * player.m_placement;
|
||||||
TPointD point = aff.inv() * m_point;
|
TPointD point = aff.inv() * m_point;
|
||||||
|
@ -815,7 +822,9 @@ void RasterPainter::onVectorImage(TVectorImage *vi,
|
||||||
if (player.m_onionSkinDistance != c_noOnionSkin) {
|
if (player.m_onionSkinDistance != c_noOnionSkin) {
|
||||||
TPixel32 frontOnionColor, backOnionColor;
|
TPixel32 frontOnionColor, backOnionColor;
|
||||||
|
|
||||||
if (player.m_onionSkinDistance != 0) {
|
if (player.m_onionSkinDistance != 0 &&
|
||||||
|
(!player.m_isShiftAndTraceEnabled ||
|
||||||
|
Preferences::instance()->areOnionColorsUsedForShiftAndTraceGhosts())) {
|
||||||
prefs.getOnionData(frontOnionColor, backOnionColor, inksOnly);
|
prefs.getOnionData(frontOnionColor, backOnionColor, inksOnly);
|
||||||
bgColor =
|
bgColor =
|
||||||
(player.m_onionSkinDistance < 0) ? backOnionColor : frontOnionColor;
|
(player.m_onionSkinDistance < 0) ? backOnionColor : frontOnionColor;
|
||||||
|
@ -961,11 +970,17 @@ void RasterPainter::onRasterImage(TRasterImage *ri,
|
||||||
? 0.9
|
? 0.9
|
||||||
: (1.0 - OnionSkinMask::getOnionSkinFade(
|
: (1.0 - OnionSkinMask::getOnionSkinFade(
|
||||||
player.m_onionSkinDistance));
|
player.m_onionSkinDistance));
|
||||||
alpha = tcrop(tround(onionSkiFade * 255.0), 0, 255);
|
alpha = tcrop(tround(onionSkiFade * 255.0), 0, 255);
|
||||||
onionMode = (player.m_onionSkinDistance > 0)
|
if (player.m_isShiftAndTraceEnabled &&
|
||||||
? Node::eOnionSkinFront
|
!Preferences::instance()->areOnionColorsUsedForShiftAndTraceGhosts())
|
||||||
: ((player.m_onionSkinDistance < 0) ? Node::eOnionSkinBack
|
onionMode = Node::eOnionSkinNone;
|
||||||
: Node::eOnionSkinNone);
|
else {
|
||||||
|
onionMode =
|
||||||
|
(player.m_onionSkinDistance > 0)
|
||||||
|
? Node::eOnionSkinFront
|
||||||
|
: ((player.m_onionSkinDistance < 0) ? Node::eOnionSkinBack
|
||||||
|
: Node::eOnionSkinNone);
|
||||||
|
}
|
||||||
} else if (player.m_opacity < 255)
|
} else if (player.m_opacity < 255)
|
||||||
alpha = player.m_opacity;
|
alpha = player.m_opacity;
|
||||||
TXshSimpleLevel *sl = player.m_sl;
|
TXshSimpleLevel *sl = player.m_sl;
|
||||||
|
@ -1018,11 +1033,19 @@ void RasterPainter::onToonzImage(TToonzImage *ti, const Stage::Player &player) {
|
||||||
? 0.9
|
? 0.9
|
||||||
: (1.0 - OnionSkinMask::getOnionSkinFade(
|
: (1.0 - OnionSkinMask::getOnionSkinFade(
|
||||||
player.m_onionSkinDistance));
|
player.m_onionSkinDistance));
|
||||||
alpha = tcrop(tround(onionSkiFade * 255.0), 0, 255);
|
alpha = tcrop(tround(onionSkiFade * 255.0), 0, 255);
|
||||||
onionMode = (player.m_onionSkinDistance > 0)
|
|
||||||
? Node::eOnionSkinFront
|
if (player.m_isShiftAndTraceEnabled &&
|
||||||
: ((player.m_onionSkinDistance < 0) ? Node::eOnionSkinBack
|
!Preferences::instance()->areOnionColorsUsedForShiftAndTraceGhosts())
|
||||||
: Node::eOnionSkinNone);
|
onionMode = Node::eOnionSkinNone;
|
||||||
|
else {
|
||||||
|
onionMode =
|
||||||
|
(player.m_onionSkinDistance > 0)
|
||||||
|
? Node::eOnionSkinFront
|
||||||
|
: ((player.m_onionSkinDistance < 0) ? Node::eOnionSkinBack
|
||||||
|
: Node::eOnionSkinNone);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (player.m_opacity < 255)
|
} else if (player.m_opacity < 255)
|
||||||
alpha = player.m_opacity;
|
alpha = player.m_opacity;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue