From ec919723020afa52069d03a9510f1ad8e01c7916 Mon Sep 17 00:00:00 2001 From: manongjohn Date: Jun 30 2019 14:47:11 +0000 Subject: Merged in OT master with conflicts resolved --- diff --git a/toonz/sources/common/tfx/tmacrofx.cpp b/toonz/sources/common/tfx/tmacrofx.cpp index c643533..2759545 100644 --- a/toonz/sources/common/tfx/tmacrofx.cpp +++ b/toonz/sources/common/tfx/tmacrofx.cpp @@ -492,6 +492,9 @@ void TMacroFx::loadData(TIStream &is) { m_fxs.push_back(fx); } } + // collecting params just after loading nodes since they may need on + // loading "super" tag in case it is linked with another macro fx + collectParams(this); } else if (tagName == "ports") { int i = 0; while (is.matchTag(tagName)) { @@ -533,7 +536,6 @@ void TMacroFx::loadData(TIStream &is) { throw TException("unexpected tag " + tagName); is.closeChild(); } - collectParams(this); } //-------------------------------------------------- diff --git a/toonz/sources/common/tiio/tiio_jpg_exif.cpp b/toonz/sources/common/tiio/tiio_jpg_exif.cpp index c7613dd..36774b8 100644 --- a/toonz/sources/common/tiio/tiio_jpg_exif.cpp +++ b/toonz/sources/common/tiio/tiio_jpg_exif.cpp @@ -135,7 +135,7 @@ const int TAG_IMAGE_UNIQUE_ID = 0xA420; typedef struct { unsigned short Tag; - char *Desc; + const char *Desc; } TagTable_t; const TagTable_t TagTable[] = { @@ -253,7 +253,7 @@ const int TAG_TABLE_SIZE = (sizeof(TagTable) / sizeof(TagTable_t)); const int TRUE = 1; const int FALSE = 0; -} +} // namespace //-------------------------------------------------------------------------- // Convert a 16 bit unsigned value from file's native byte order @@ -633,7 +633,7 @@ void JpgExifReader::ProcessExifDir(unsigned char *DirStart, break; case FMT_UNDEFINED: - // Undefined is typically an ascii string. + // Undefined is typically an ascii string. case FMT_STRING: // String arrays printed without function call (different from int @@ -683,7 +683,7 @@ void JpgExifReader::ProcessExifDir(unsigned char *DirStart, case TAG_DATETIME_ORIGINAL: // If we get a DATETIME_ORIGINAL, we use that one. strncpy(ImageInfo.DateTime, (char *)ValuePtr, 19); - // Fallthru... + // Fallthru... case TAG_DATETIME_DIGITIZED: case TAG_DATETIME: @@ -737,7 +737,7 @@ void JpgExifReader::ProcessExifDir(unsigned char *DirStart, // Copy the comment { - int msiz = ExifLength - (ValuePtr - OffsetBase); + int msiz = ExifLength - (ValuePtr - OffsetBase); if (msiz > ByteCount) msiz = ByteCount; if (msiz > MAX_COMMENT_SIZE - 1) msiz = MAX_COMMENT_SIZE - 1; if (msiz > 5 && memcmp(ValuePtr, "ASCII", 5) == 0) { diff --git a/toonz/sources/common/tvrender/tglregions.cpp b/toonz/sources/common/tvrender/tglregions.cpp index 8ae9139..86a4073 100644 --- a/toonz/sources/common/tvrender/tglregions.cpp +++ b/toonz/sources/common/tvrender/tglregions.cpp @@ -135,7 +135,7 @@ void drawControlPoints(const TVectorRenderData &rd, TStroke *stroke, //----------------------------------------------------------------------------- -void drawArrows(TStroke *stroke, bool onlyFirstPoint) { +static void drawArrows(TStroke *stroke, bool onlyFirstPoint) { double length = stroke->getLength(0.0, 1.0); int points = length / 20; if (points < 2) points += 1; @@ -179,7 +179,8 @@ void drawArrows(TStroke *stroke, bool onlyFirstPoint) { //----------------------------------------------------------------------------- // Used for Guided Drawing -void drawFirstControlPoint(const TVectorRenderData &rd, TStroke *stroke) { +static void drawFirstControlPoint(const TVectorRenderData &rd, + TStroke *stroke) { TPointD p = stroke->getPoint(0.0); double length = stroke->getLength(0.0, 1.0); int msecs = QTime::currentTime().msec(); @@ -276,8 +277,8 @@ void tglDraw(const TVectorRenderData &rd, TRegion *r, bool pushAttribs) { } else { visible = false; for (j = 0; j < colorCount && !visible; j++) { - TPixel32 color = style->getColorParamValue(j); - if (rd.m_cf) color = (*(rd.m_cf))(color); + TPixel32 color = style->getColorParamValue(j); + if (rd.m_cf) color = (*(rd.m_cf))(color); if (color.m != 0) visible = true; } } @@ -434,7 +435,7 @@ bool isOThick(const TStroke *s) { if (s->getControlPoint(i).thick != 0) return false; return true; } -} +} // namespace void tglDraw(const TVectorRenderData &rd, const TStroke *s, bool pushAttribs) { assert(s); @@ -554,8 +555,8 @@ static void tglDoDraw(const TVectorRenderData &rd, TRegion *r) { else { visible = false; for (int j = 0; j < colorCount && !visible; j++) { - TPixel32 color = style->getColorParamValue(j); - if (rd.m_cf) color = (*(rd.m_cf))(color); + TPixel32 color = style->getColorParamValue(j); + if (rd.m_cf) color = (*(rd.m_cf))(color); if (color.m != 0) visible = true; } } @@ -584,8 +585,8 @@ static bool tglDoDraw(const TVectorRenderData &rd, const TStroke *s) { else { visible = false; for (int j = 0; j < style->getColorParamCount() && !visible; j++) { - TPixel32 color = style->getColorParamValue(j); - if (rd.m_cf) color = (*(rd.m_cf))(color); + TPixel32 color = style->getColorParamValue(j); + if (rd.m_cf) color = (*(rd.m_cf))(color); if (color.m != 0) visible = true; } } @@ -676,7 +677,7 @@ rdRegions.m_alphaChannel = rdRegions.m_antiAliasing = false;*/ } } } -} +} // namespace //------------------------------------------------------------------------------------ diff --git a/toonz/sources/common/twain/ttwain_stateX.c b/toonz/sources/common/twain/ttwain_stateX.c index 8295d7a..75c820d 100644 --- a/toonz/sources/common/twain/ttwain_stateX.c +++ b/toonz/sources/common/twain/ttwain_stateX.c @@ -4,6 +4,8 @@ extern "C" { #endif +#include "ttwain_statePD.h" + int TTWAIN_LoadSourceManagerPD(void) { return 0; } int TTWAIN_UnloadSourceManagerPD(void) { return 1; } diff --git a/toonz/sources/include/tools/tooloptions.h b/toonz/sources/include/tools/tooloptions.h index 428c5fb..d1ee09a 100644 --- a/toonz/sources/include/tools/tooloptions.h +++ b/toonz/sources/include/tools/tooloptions.h @@ -476,6 +476,21 @@ protected slots: //============================================================================= // +// FullColorFillToolOptionsBox +// +//============================================================================= + +class FullColorFillToolOptionsBox final : public ToolOptionsBox { + Q_OBJECT + +public: + FullColorFillToolOptionsBox(QWidget *parent, TTool *tool, + TPaletteHandle *pltHandle, + ToolHandle *toolHandle); +}; + +//============================================================================= +// // FillToolOptionsBox // //============================================================================= diff --git a/toonz/sources/include/toonz/fill.h b/toonz/sources/include/toonz/fill.h index 5a4eece..2d62faf 100644 --- a/toonz/sources/include/toonz/fill.h +++ b/toonz/sources/include/toonz/fill.h @@ -81,6 +81,9 @@ void DVAPI rectFillInk(const TRasterCM32P &ras, const TRect &r, int color); void DVAPI fillautoInks(TRasterCM32P &r, TRect &rect, const TRasterCM32P &rbefore, TPalette *plt); +void DVAPI fullColorFill(const TRaster32P &ras, const FillParameters ¶ms, + TTileSaverFullColor *saver = 0); + //============================================================================= //! The class AreaFiller allows to fill a raster area, delimited by rect or //! spline. diff --git a/toonz/sources/include/toonz/ttileset.h b/toonz/sources/include/toonz/ttileset.h index e5dfac9..c2cefcd 100644 --- a/toonz/sources/include/toonz/ttileset.h +++ b/toonz/sources/include/toonz/ttileset.h @@ -146,6 +146,7 @@ public: void add(const TRasterP &ras, TRect rect) override; const Tile *getTile(int index) const; + Tile *editTile(int index) const; TTileSetFullColor *clone() const override; }; diff --git a/toonz/sources/include/toonzqt/fxschematicnode.h b/toonz/sources/include/toonzqt/fxschematicnode.h index f0d7a7a..1538523 100644 --- a/toonz/sources/include/toonzqt/fxschematicnode.h +++ b/toonz/sources/include/toonzqt/fxschematicnode.h @@ -365,6 +365,7 @@ public: protected: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *me) override; + void mousePressEvent(QGraphicsSceneMouseEvent *me) override; }; //***************************************************** @@ -384,6 +385,7 @@ public: protected: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *me) override; + void mousePressEvent(QGraphicsSceneMouseEvent *me) override; }; //***************************************************** @@ -408,6 +410,7 @@ public: protected: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *me) override; + void mousePressEvent(QGraphicsSceneMouseEvent *me) override; protected slots: @@ -441,6 +444,7 @@ public: protected: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *me) override; + void mousePressEvent(QGraphicsSceneMouseEvent *me) override; protected slots: @@ -479,6 +483,7 @@ public: protected: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *me) override; + void mousePressEvent(QGraphicsSceneMouseEvent *me) override; private: void renameObject(const TStageObjectId &id, std::string name); @@ -517,6 +522,7 @@ public: protected: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *me) override; + void mousePressEvent(QGraphicsSceneMouseEvent *me) override; protected slots: @@ -575,6 +581,7 @@ public: protected: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *me) override; + void mousePressEvent(QGraphicsSceneMouseEvent *me) override; QPointF computePos() const; protected slots: diff --git a/toonz/sources/include/toonzqt/fxsettings.h b/toonz/sources/include/toonzqt/fxsettings.h index 64386c0..5fa0619 100644 --- a/toonz/sources/include/toonzqt/fxsettings.h +++ b/toonz/sources/include/toonzqt/fxsettings.h @@ -190,6 +190,7 @@ class DVAPI ParamViewer final : public QFrame { Q_OBJECT TFxP m_fx; + TFxP m_actualFx; QStackedWidget *m_tablePageSet; QMap m_tableFxIndex; @@ -253,6 +254,7 @@ class DVAPI FxSettings final : public QSplitter { bool m_isCameraModeView; int m_container_height; + int m_container_width; public: FxSettings(QWidget *parent, const TPixel32 &checkCol1, diff --git a/toonz/sources/tnztools/CMakeLists.txt b/toonz/sources/tnztools/CMakeLists.txt index bfef22e..62ae7a2 100644 --- a/toonz/sources/tnztools/CMakeLists.txt +++ b/toonz/sources/tnztools/CMakeLists.txt @@ -3,6 +3,7 @@ set(MOC_HEADERS edittoolgadgets.h filltool.h fullcolorbrushtool.h + fullcolorfilltool.h plastictool.h skeletonsubtools.h tooloptionscontrols.h @@ -58,6 +59,7 @@ set(SOURCES filltool.cpp fullcolorbrushtool.cpp fullcolorerasertool.cpp + fullcolorfilltool.cpp geometrictool.cpp hooktool.cpp hookselection.cpp diff --git a/toonz/sources/tnztools/fullcolorbrushtool.cpp b/toonz/sources/tnztools/fullcolorbrushtool.cpp index fde2213..1f421a5 100644 --- a/toonz/sources/tnztools/fullcolorbrushtool.cpp +++ b/toonz/sources/tnztools/fullcolorbrushtool.cpp @@ -143,6 +143,9 @@ FullColorBrushTool::FullColorBrushTool(std::string name) m_prop.bind(m_preset); m_preset.setId("BrushPreset"); + m_modifierEraser.setId("RasterEraser"); + m_modifierLockAlpha.setId("LockAlpha"); + m_pressure.setId("PressureSensitivity"); m_brushTimer.start(); } diff --git a/toonz/sources/tnztools/fullcolorfilltool.cpp b/toonz/sources/tnztools/fullcolorfilltool.cpp new file mode 100644 index 0000000..5c53980 --- /dev/null +++ b/toonz/sources/tnztools/fullcolorfilltool.cpp @@ -0,0 +1,223 @@ +#include "fullcolorfilltool.h" + +#include "toonz/stage2.h" +#include "tools/cursors.h" +#include "toonz/txshlevelhandle.h" +#include "toonz/trasterimageutils.h" +#include "toonz/ttileset.h" +#include "toonz/ttilesaver.h" +#include "toonz/levelproperties.h" +#include "toonz/preferences.h" +#include "toonz/txsheethandle.h" + +#include "tools/toolhandle.h" +#include "tools/toolutils.h" + +#include "tenv.h" +#include "tpalette.h" +#include "tsystem.h" + +using namespace ToolUtils; + +TEnv::IntVar FullColorMinFillDepth("InknpaintFullColorMinFillDepth", 4); +TEnv::IntVar FullColorMaxFillDepth("InknpaintFullColorMaxFillDepth", 12); + +namespace { + +//============================================================================= +// FullColorFillUndo +//----------------------------------------------------------------------------- + +class FullColorFillUndo final : public TFullColorRasterUndo { + FillParameters m_params; + bool m_saveboxOnly; + +public: + FullColorFillUndo(TTileSetFullColor *tileSet, const FillParameters ¶ms, + TXshSimpleLevel *sl, const TFrameId &fid, bool saveboxOnly) + : TFullColorRasterUndo(tileSet, sl, fid, false, false, 0) + , m_params(params) + , m_saveboxOnly(saveboxOnly) {} + + void redo() const override { + TRasterImageP image = getImage(); + if (!image) return; + TRaster32P r; + if (m_saveboxOnly) { + TRectD temp = image->getBBox(); + TRect ttemp = convert(temp); + r = image->getRaster()->extract(ttemp); + } else + r = image->getRaster(); + + fullColorFill(r, m_params); + + TTool::Application *app = TTool::getApplication(); + if (app) { + app->getCurrentXsheet()->notifyXsheetChanged(); + notifyImageChanged(); + } + } + + int getSize() const override { + return sizeof(*this) + TFullColorRasterUndo::getSize(); + } + + QString getToolName() override { + return QString("Fill Tool : %1") + .arg(QString::fromStdWString(m_params.m_fillType)); + } + int getHistoryType() override { return HistoryType::FillTool; } +}; + +//============================================================================= +// doFill +//----------------------------------------------------------------------------- + +void doFill(const TImageP &img, const TPointD &pos, FillParameters ¶ms, + bool isShiftFill, TXshSimpleLevel *sl, const TFrameId &fid) { + TTool::Application *app = TTool::getApplication(); + if (!app || !sl) return; + + if (TRasterImageP ri = TRasterImageP(img)) { + TPoint offs(0, 0); + TRaster32P ras = ri->getRaster(); + // only accept 32bpp images for now + if (!ras.getPointer() || ras->isEmpty()) return; + + ras->lock(); + + TTileSetFullColor *tileSet = new TTileSetFullColor(ras->getSize()); + TTileSaverFullColor tileSaver(ras, tileSet); + TDimension imageSize = ras->getSize(); + TPointD p(imageSize.lx % 2 ? 0.0 : 0.5, imageSize.ly % 2 ? 0.0 : 0.5); + + /*-- params.m_p = convert(pos-p)�ł́A�}�C�i�X���W�ł��ꂪ������ --*/ + TPointD tmp_p = pos - p; + params.m_p = TPoint((int)floor(tmp_p.x + 0.5), (int)floor(tmp_p.y + 0.5)); + + params.m_p += ras->getCenter(); + params.m_p -= offs; + params.m_shiftFill = isShiftFill; + + TRect rasRect(ras->getSize()); + if (!rasRect.contains(params.m_p)) { + ras->unlock(); + return; + } + + fullColorFill(ras, params, &tileSaver); + + if (tileSaver.getTileSet()->getTileCount() != 0) { + static int count = 0; + TSystem::outputDebug("RASTERFILL" + std::to_string(count++) + "\n"); + if (offs != TPoint()) + for (int i = 0; i < tileSet->getTileCount(); i++) { + TTileSet::Tile *t = tileSet->editTile(i); + t->m_rasterBounds = t->m_rasterBounds + offs; + } + TUndoManager::manager()->add( + new FullColorFillUndo(tileSet, params, sl, fid, + Preferences::instance()->getFillOnlySavebox())); + } + + sl->getProperties()->setDirtyFlag(true); + + ras->unlock(); + } + + TTool *t = app->getCurrentTool()->getTool(); + if (t) t->notifyImageChanged(); +} +}; + +//============================================================================= +// FullColorFillTool +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- + +FullColorFillTool::FullColorFillTool() + : TTool("T_Fill"), m_fillDepth("Fill Depth", 0, 15, 4, 12) { + bind(TTool::RasterImage); + m_prop.bind(m_fillDepth); +} + +void FullColorFillTool::updateTranslation() { + m_fillDepth.setQStringName(tr("Fill Depth")); +} + +FillParameters FullColorFillTool::getFillParameters() const { + FillParameters params; + int styleId = TTool::getApplication()->getCurrentLevelStyleIndex(); + params.m_styleId = styleId; + params.m_minFillDepth = (int)m_fillDepth.getValue().first; + params.m_maxFillDepth = (int)m_fillDepth.getValue().second; + + if (m_level) params.m_palette = m_level->getPalette(); + return params; +} + +void FullColorFillTool::leftButtonDown(const TPointD &pos, + const TMouseEvent &e) { + m_clickPoint = pos; + TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel(); + m_level = xl ? xl->getSimpleLevel() : 0; + FillParameters params = getFillParameters(); + doFill(getImage(true), pos, params, e.isShiftPressed(), m_level.getPointer(), + getCurrentFid()); + invalidate(); +} + +void FullColorFillTool::leftButtonDrag(const TPointD &pos, + const TMouseEvent &e) { + FillParameters params = getFillParameters(); + if (m_clickPoint == pos) return; + if (!m_level || !params.m_palette) return; + TImageP img = getImage(true); + TPixel32 fillColor = + params.m_palette->getStyle(params.m_styleId)->getMainColor(); + if (TRasterImageP ri = img) { + TRaster32P ras = ri->getRaster(); + if (!ras) return; + TPointD center = ras->getCenterD(); + TPoint ipos = convert(pos + center); + if (!ras->getBounds().contains(ipos)) return; + TPixel32 pix = ras->pixels(ipos.y)[ipos.x]; + if (pix == fillColor) { + invalidate(); + return; + } + } else + return; + doFill(img, pos, params, e.isShiftPressed(), m_level.getPointer(), + getCurrentFid()); + invalidate(); +} + +bool FullColorFillTool::onPropertyChanged(std::string propertyName) { + // Fill Depth + if (propertyName == m_fillDepth.getName()) { + FullColorMinFillDepth = (int)m_fillDepth.getValue().first; + FullColorMaxFillDepth = (int)m_fillDepth.getValue().second; + } + return true; +} + +void FullColorFillTool::onActivate() { + static bool firstTime = true; + if (firstTime) { + m_fillDepth.setValue(TDoublePairProperty::Value(FullColorMinFillDepth, + FullColorMaxFillDepth)); + firstTime = false; + } +} + +int FullColorFillTool::getCursorId() const { + int ret = ToolCursor::FillCursor; + if (ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg) + ret = ret | ToolCursor::Ex_Negate; + return ret; +} + +FullColorFillTool FullColorRasterFillTool; \ No newline at end of file diff --git a/toonz/sources/tnztools/fullcolorfilltool.h b/toonz/sources/tnztools/fullcolorfilltool.h new file mode 100644 index 0000000..1dd979c --- /dev/null +++ b/toonz/sources/tnztools/fullcolorfilltool.h @@ -0,0 +1,45 @@ +#pragma once + +#ifndef FULLCOLORFILLTOOL_H +#define FULLCOLORFILLTOOL_H + +// TnzCore includes +#include "tproperty.h" + +// TnzTools includes +#include "tools/tool.h" +#include "toonz/fill.h" +#include "toonz/txshsimplelevel.h" + +#include +#include + +class FullColorFillTool final : public QObject, public TTool { + Q_DECLARE_TR_FUNCTIONS(FullColorFillTool) + + TXshSimpleLevelP m_level; + TDoublePairProperty m_fillDepth; + TPropertyGroup m_prop; + TPointD m_clickPoint; + +public: + FullColorFillTool(); + + ToolType getToolType() const override { return TTool::LevelWriteTool; } + + void updateTranslation() override; + + TPropertyGroup *getProperties(int targetType) override { return &m_prop; } + + FillParameters getFillParameters() const; + + void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override; + void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override; + + bool onPropertyChanged(std::string propertyName) override; + + void onActivate() override; + int getCursorId() const override; +}; + +#endif // FULLCOLORFILLTOOL_H \ No newline at end of file diff --git a/toonz/sources/tnztools/tooloptions.cpp b/toonz/sources/tnztools/tooloptions.cpp index 272b18e..871c9f0 100644 --- a/toonz/sources/tnztools/tooloptions.cpp +++ b/toonz/sources/tnztools/tooloptions.cpp @@ -125,7 +125,8 @@ ToolOptionsBox::ToolOptionsBox(QWidget *parent, bool isScrollable) ToolOptionsBox::~ToolOptionsBox() { std::for_each(m_controls.begin(), m_controls.end(), std::default_delete()); - std::for_each(m_labels.begin(), m_labels.end(), std::default_delete()); + std::for_each(m_labels.begin(), m_labels.end(), + std::default_delete()); } //----------------------------------------------------------------------------- @@ -218,6 +219,17 @@ void ToolOptionControlBuilder::visit(TDoubleProperty *p) { control->addAction(a); QObject::connect(a, SIGNAL(triggered()), control, SLOT(decrease())); } + if (p->getName() == "ModifierSize") { + QAction *a; + a = cm->getAction("A_IncreaseMaxBrushThickness"); + control->addAction(a); + QObject::connect(a, SIGNAL(triggered()), control, + SLOT(increaseFractional())); + a = cm->getAction("A_DecreaseMaxBrushThickness"); + control->addAction(a); + QObject::connect(a, SIGNAL(triggered()), control, + SLOT(decreaseFractional())); + } if (p->getName() == "Hardness:") { QAction *a; a = cm->getAction("A_IncreaseBrushHardness"); @@ -1635,6 +1647,25 @@ void PaintbrushToolOptionsBox::onColorModeChanged(int index) { //============================================================================= // +// FullColorFillToolOptionsBox +// +//============================================================================= + +FullColorFillToolOptionsBox::FullColorFillToolOptionsBox( + QWidget *parent, TTool *tool, TPaletteHandle *pltHandle, + ToolHandle *toolHandle) + : ToolOptionsBox(parent) { + TPropertyGroup *props = tool->getProperties(0); + assert(props->getPropertyCount() > 0); + + ToolOptionControlBuilder builder(this, tool, pltHandle, toolHandle); + if (tool && tool->getProperties(0)) tool->getProperties(0)->accept(builder); + + m_layout->addStretch(0); +} + +//============================================================================= +// // FillToolOptionsBox // //============================================================================= @@ -2796,9 +2827,13 @@ void ToolOptions::onToolSwitched() { panel = new TypeToolOptionsBox(0, tool, currPalette, currTool); else if (tool->getName() == T_PaintBrush) panel = new PaintbrushToolOptionsBox(0, tool, currPalette, currTool); - else if (tool->getName() == T_Fill) - panel = new FillToolOptionsBox(0, tool, currPalette, currTool); - else if (tool->getName() == T_Eraser) + else if (tool->getName() == T_Fill) { + if (tool->getTargetType() & TTool::RasterImage) + panel = + new FullColorFillToolOptionsBox(0, tool, currPalette, currTool); + else + panel = new FillToolOptionsBox(0, tool, currPalette, currTool); + } else if (tool->getName() == T_Eraser) panel = new EraserToolOptionsBox(0, tool, currPalette, currTool); else if (tool->getName() == T_Tape) panel = new TapeToolOptionsBox(0, tool, currPalette, currTool); diff --git a/toonz/sources/tnztools/tooloptionscontrols.cpp b/toonz/sources/tnztools/tooloptionscontrols.cpp index bee24dc..24f64bb 100644 --- a/toonz/sources/tnztools/tooloptionscontrols.cpp +++ b/toonz/sources/tnztools/tooloptionscontrols.cpp @@ -192,7 +192,7 @@ void ToolOptionSlider::onValueChanged(bool isDragging) { //----------------------------------------------------------------------------- -void ToolOptionSlider::increase() { +void ToolOptionSlider::increase(double step) { if (m_toolHandle && m_toolHandle->getTool() != m_tool) return; // active only if the belonging combo-viewer is visible if (!isInVisibleViewer(this)) return; @@ -201,7 +201,7 @@ void ToolOptionSlider::increase() { double minValue, maxValue; getRange(minValue, maxValue); - value += 1; + value += step; if (value > maxValue) value = maxValue; setValue(value); @@ -213,7 +213,11 @@ void ToolOptionSlider::increase() { //----------------------------------------------------------------------------- -void ToolOptionSlider::decrease() { +void ToolOptionSlider::increaseFractional() { increase(0.06); } + +//----------------------------------------------------------------------------- + +void ToolOptionSlider::decrease(double step) { if (m_toolHandle && m_toolHandle->getTool() != m_tool) return; // active only if the belonging combo-viewer is visible if (!isInVisibleViewer(this)) return; @@ -222,7 +226,7 @@ void ToolOptionSlider::decrease() { double minValue, maxValue; getRange(minValue, maxValue); - value -= 1; + value -= step; if (value < minValue) value = minValue; setValue(value); @@ -232,6 +236,10 @@ void ToolOptionSlider::decrease() { repaint(); } +//----------------------------------------------------------------------------- + +void ToolOptionSlider::decreaseFractional() { decrease(0.06); } + //============================================================================= ToolOptionPairSlider::ToolOptionPairSlider(TTool *tool, diff --git a/toonz/sources/tnztools/tooloptionscontrols.h b/toonz/sources/tnztools/tooloptionscontrols.h index 6af4bbc..6698552 100644 --- a/toonz/sources/tnztools/tooloptionscontrols.h +++ b/toonz/sources/tnztools/tooloptionscontrols.h @@ -119,8 +119,10 @@ public: protected slots: void onValueChanged(bool isDragging); - void increase(); - void decrease(); + void increase(double step = 1.0); + void decrease(double step = 1.0); + void increaseFractional(); + void decreaseFractional(); }; //----------------------------------------------------------------------------- diff --git a/toonz/sources/toonz/filmstripcommand.cpp b/toonz/sources/toonz/filmstripcommand.cpp index 1dfc524..da4bc84 100644 --- a/toonz/sources/toonz/filmstripcommand.cpp +++ b/toonz/sources/toonz/filmstripcommand.cpp @@ -70,9 +70,8 @@ void doUpdateXSheet(TXshSimpleLevel *sl, std::vector oldFids, cells[i].m_level->getType() == CHILD_XSHLEVEL) { TXshChildLevel *level = cells[i].m_level->getChildLevel(); // make sure we haven't already checked the level - if (level && - std::find(childLevels.begin(), childLevels.end(), level) == - childLevels.end()) { + if (level && std::find(childLevels.begin(), childLevels.end(), + level) == childLevels.end()) { childLevels.push_back(level); TXsheet *subXsh = level->getXsheet(); doUpdateXSheet(sl, oldFids, newFids, subXsh, childLevels); @@ -101,8 +100,8 @@ void doUpdateXSheet(TXshSimpleLevel *sl, std::vector oldFids, //----------------------------------------------------------------------------- -void updateXSheet(TXshSimpleLevel *sl, std::vector oldFids, - std::vector newFids) { +static void updateXSheet(TXshSimpleLevel *sl, std::vector oldFids, + std::vector newFids) { std::vector childLevels; TXsheet *xsh = TApp::instance()->getCurrentScene()->getScene()->getTopXsheet(); @@ -145,7 +144,7 @@ void makeSpaceForFids(TXshSimpleLevel *sl, if (Preferences::instance()->isSyncLevelRenumberWithXsheetEnabled()) updateXSheet(sl, oldFids, fids); sl->renumber(fids); - sl->setDirtyFlag(true); + sl->setDirtyFlag(true); } } @@ -250,10 +249,10 @@ bool pasteAreasWithoutUndo(const QMimeData *data, TXshSimpleLevel *sl, affine *= sc; int i; TRectD boxD; - if (rects.size() > 0) boxD = rects[0]; + if (rects.size() > 0) boxD = rects[0]; if (strokes.size() > 0) boxD = strokes[0].getBBox(); for (i = 0; i < rects.size(); i++) boxD += rects[i]; - for (i = 0; i < strokes.size(); i++) boxD += strokes[i].getBBox(); + for (i = 0; i < strokes.size(); i++) boxD += strokes[i].getBBox(); boxD = affine * boxD; TRect box = ToonzImageUtils::convertWorldToRaster(boxD, ti); TPoint pos = box.getP00(); @@ -309,10 +308,10 @@ bool pasteAreasWithoutUndo(const QMimeData *data, TXshSimpleLevel *sl, affine *= sc; int i; TRectD boxD; - if (rects.size() > 0) boxD = rects[0]; + if (rects.size() > 0) boxD = rects[0]; if (strokes.size() > 0) boxD = strokes[0].getBBox(); for (i = 0; i < rects.size(); i++) boxD += rects[i]; - for (i = 0; i < strokes.size(); i++) boxD += strokes[i].getBBox(); + for (i = 0; i < strokes.size(); i++) boxD += strokes[i].getBBox(); boxD = affine * boxD; TRect box = TRasterImageUtils::convertWorldToRaster(boxD, ri); TPoint pos = box.getP00(); @@ -604,13 +603,13 @@ public: int i; TRectD boxD; - if (rects.size() > 0) boxD = rects[0]; + if (rects.size() > 0) boxD = rects[0]; if (strokes.size() > 0) boxD = strokes[0].getBBox(); for (i = 0; i < rects.size(); i++) boxD += rects[i]; - for (i = 0; i < strokes.size(); i++) boxD += strokes[i].getBBox(); - boxD = affine * boxD; - TRect box = ToonzImageUtils::convertWorldToRaster(boxD, ti); - TPoint pos = box.getP00(); + for (i = 0; i < strokes.size(); i++) boxD += strokes[i].getBBox(); + boxD = affine * boxD; + TRect box = ToonzImageUtils::convertWorldToRaster(boxD, ti); + TPoint pos = box.getP00(); TRasterCM32P app = ras; TRop::over(ti->getRaster(), app, pos, affine); ToolUtils::updateSaveBox(m_level, *it); @@ -639,13 +638,13 @@ public: affine *= sc; int i; TRectD boxD; - if (rects.size() > 0) boxD = rects[0]; + if (rects.size() > 0) boxD = rects[0]; if (strokes.size() > 0) boxD = strokes[0].getBBox(); for (i = 0; i < rects.size(); i++) boxD += rects[i]; - for (i = 0; i < strokes.size(); i++) boxD += strokes[i].getBBox(); - boxD = affine * boxD; - TRect box = TRasterImageUtils::convertWorldToRaster(boxD, ri); - TPoint pos = box.getP00(); + for (i = 0; i < strokes.size(); i++) boxD += strokes[i].getBBox(); + boxD = affine * boxD; + TRect box = TRasterImageUtils::convertWorldToRaster(boxD, ri); + TPoint pos = box.getP00(); TRasterCM32P app = ras; if (app) TRop::over(ri->getRaster(), app, ri->getPalette(), pos, affine); @@ -985,7 +984,7 @@ public: updateXSheet(m_sl.getPointer(), newFrames, m_oldLevelFrameId); } m_sl->renumber(m_oldLevelFrameId); - m_sl->setDirtyFlag(true); + m_sl->setDirtyFlag(true); TApp::instance() ->getPaletteController() ->getCurrentLevelPalette() @@ -1309,8 +1308,8 @@ public: m_level->renumber(fids); TSelection *selection = TSelection::getCurrent(); if (selection) selection->selectNone(); - m_level->setDirtyFlag(true); - TApp::instance()->getCurrentLevel()->notifyLevelChange(); + m_level->setDirtyFlag(true); + TApp::instance()->getCurrentLevel()->notifyLevelChange(); } void undo() const override { std::vector fids; @@ -1725,7 +1724,7 @@ public: // TImageCache::instance()->add("UndoInsertEmptyFrames"+QString::number((UINT)this), // img); TImageCache::instance()->add( - "UndoInsertEmptyFrames" + QString::number((uintptr_t) this), img); + "UndoInsertEmptyFrames" + QString::number((uintptr_t)this), img); } } m_updateXSheet = @@ -1735,7 +1734,7 @@ public: ~UndoInsertEmptyFrames() { // TImageCache::instance()->remove("UndoInsertEmptyFrames"+QString::number((UINT)this)); TImageCache::instance()->remove("UndoInsertEmptyFrames" + - QString::number((uintptr_t) this)); + QString::number((uintptr_t)this)); } void undo() const override { @@ -1747,7 +1746,7 @@ public: updateXSheet(m_level.getPointer(), newFrames, m_oldFrames); } m_level->renumber(m_oldFrames); - m_level->setDirtyFlag(true); + m_level->setDirtyFlag(true); TApp::instance()->getCurrentLevel()->notifyLevelChange(); } @@ -1762,7 +1761,7 @@ public: // (TToonzImageP)TImageCache::instance()->get("UndoInsertEmptyFrames"+QString::number((UINT)this), // true); TToonzImageP image = (TToonzImageP)TImageCache::instance()->get( - "UndoInsertEmptyFrames" + QString::number((uintptr_t) this), true); + "UndoInsertEmptyFrames" + QString::number((uintptr_t)this), true); if (!image) return; for (it = m_frames.begin(); it != m_frames.end(); ++it) m_level->setFrame(*it, image); @@ -2039,7 +2038,7 @@ public: m_level->renumber(m_oldFrames); TSelection *selection = TSelection::getCurrent(); if (selection) selection->selectNone(); - m_level->setDirtyFlag(true); + m_level->setDirtyFlag(true); TApp::instance()->getCurrentLevel()->notifyLevelChange(); } void redo() const override { @@ -2205,7 +2204,7 @@ public: updateXSheet(m_level.getPointer(), newFrames, m_oldFrames); } m_level->renumber(m_oldFrames); - m_level->setDirtyFlag(true); + m_level->setDirtyFlag(true); TApp::instance()->getCurrentLevel()->notifyLevelChange(); } void redo() const override { diff --git a/toonz/sources/toonz/fxparameditorpopup.cpp b/toonz/sources/toonz/fxparameditorpopup.cpp index ef0385e..0ff3a2b 100644 --- a/toonz/sources/toonz/fxparameditorpopup.cpp +++ b/toonz/sources/toonz/fxparameditorpopup.cpp @@ -59,6 +59,7 @@ FxParamEditorPopup::FxParamEditorPopup() } //============================================================================= - +/* OpenPopupCommandHandler openFxParamEditorPopup( MI_FxParamEditor); +*/ \ No newline at end of file diff --git a/toonz/sources/toonz/iocommand.cpp b/toonz/sources/toonz/iocommand.cpp index f524220..d66fb58 100644 --- a/toonz/sources/toonz/iocommand.cpp +++ b/toonz/sources/toonz/iocommand.cpp @@ -190,7 +190,7 @@ public: // TFilePath process(ToonzScene *scene, ToonzScene *srcScene, TFilePath srcPath) override { - TFilePath actualSrcPath = srcPath; + TFilePath actualSrcPath = srcPath; if (srcScene) actualSrcPath = srcScene->decodeFilePath(srcPath); if (!isImportEnabled()) { @@ -1350,7 +1350,7 @@ bool IoCmd::saveScene(const TFilePath &path, int flags) { TApp *app = TApp::instance(); assert(!path.isEmpty()); - TFilePath scenePath = path; + TFilePath scenePath = path; if (scenePath.getType() == "") scenePath = scenePath.withType("tnz"); if (scenePath.getType() != "tnz") { error( @@ -1389,7 +1389,7 @@ bool IoCmd::saveScene(const TFilePath &path, int flags) { TFilePath newFullPath = scene->decodeFilePath(scenePath); QApplication::setOverrideCursor(Qt::WaitCursor); - TXsheet *xsheet = 0; + TXsheet *xsheet = 0; if (saveSubxsheet) xsheet = TApp::instance()->getCurrentXsheet()->getXsheet(); if (app->getCurrentScene()->getDirtyFlag()) scene->getContentHistory(true)->modifiedNow(); @@ -1468,8 +1468,8 @@ bool IoCmd::saveScene() { ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene(); if (scene->isUntitled()) { static SaveSceneAsPopup *popup = 0; - if (!popup) popup = new SaveSceneAsPopup(); - int ret = popup->exec(); + if (!popup) popup = new SaveSceneAsPopup(); + int ret = popup->exec(); if (ret == QDialog::Accepted) { TApp::instance()->getCurrentScene()->setDirtyFlag(false); return true; @@ -1733,8 +1733,8 @@ bool IoCmd::loadScene(const TFilePath &path, bool updateRecentFile, if (checkSaveOldScene) if (!saveSceneIfNeeded(QApplication::tr("Load Scene"))) return false; assert(!path.isEmpty()); - TFilePath scenePath = path; - bool importScene = false; + TFilePath scenePath = path; + bool importScene = false; if (scenePath.getType() == "") scenePath = scenePath.withType("tnz"); if (scenePath.getType() != "tnz") { QString msg; @@ -1828,9 +1828,8 @@ bool IoCmd::loadScene(const TFilePath &path, bool updateRecentFile, // import if needed TProjectManager *pm = TProjectManager::instance(); TProjectP currentProject = pm->getCurrentProject(); - if (!scene->getProject() || - scene->getProject()->getProjectPath() != - currentProject->getProjectPath()) { + if (!scene->getProject() || scene->getProject()->getProjectPath() != + currentProject->getProjectPath()) { ResourceImportDialog resourceLoader; // resourceLoader.setImportEnabled(true); ResourceImporter importer(scene, currentProject.getPointer(), @@ -2106,10 +2105,10 @@ static int loadPSDResource(IoCmd::LoadResourceArguments &args, int &row1 = args.row1; int &col1 = args.col1; - int count = 0; - TApp *app = TApp::instance(); - ToonzScene *scene = app->getCurrentScene()->getScene(); - TXsheet *xsh = scene->getXsheet(); + int count = 0; + TApp *app = TApp::instance(); + ToonzScene *scene = app->getCurrentScene()->getScene(); + TXsheet *xsh = scene->getXsheet(); if (row0 == -1) row0 = app->getCurrentFrame()->getFrameIndex(); if (col0 == -1) col0 = app->getCurrentColumn()->getColumnIndex(); @@ -2494,8 +2493,8 @@ bool IoCmd::exposeLevel(TXshSimpleLevel *sl, int row, int col, if (!insert && !overWrite) insertEmptyColumn = beforeCellsInsert( xsh, row, col, fids.size(), TXshColumn::toColumnType(sl->getType())); - ExposeType type = eNone; - if (insert) type = eShiftCells; + ExposeType type = eNone; + if (insert) type = eShiftCells; if (overWrite) type = eOverWrite; ExposeLevelUndo *undo = new ExposeLevelUndo(sl, row, col, frameCount, insertEmptyColumn, type); @@ -2592,24 +2591,32 @@ bool IoCmd::takeCareSceneFolderItemsOnSaveSceneAs(ToonzScene *scene, QList sceneFolderLevels; levelSet->listLevels(levels); QString str; + int count = 0; for (int i = 0; i < levels.size(); i++) { TXshLevel *level = levels.at(i); if (!level->getPath().isEmpty() && TFilePath("$scenefolder").isAncestorOf(level->getPath())) { sceneFolderLevels.append(level); - str.append(" " + QString::fromStdWString(level->getName()) + " (" + - level->getPath().getQString() + ")\n"); + if (count < 10) { + str.append(" " + QString::fromStdWString(level->getName()) + " (" + + level->getPath().getQString() + ")\n"); + } + count++; } } + // list maximum 10 levels + if (count > 10) + str.append(QObject::tr(" + %1 more level(s) \n").arg(count - 10)); // in case there is no items with $scenefolder if (sceneFolderLevels.isEmpty()) return true; str = QObject::tr( "The following level(s) use path with $scenefolder alias.\n\n") + - str + QObject::tr( - "\nThey will not be opened properly when you load the " - "scene next time.\nWhat do you want to do?"); + str + + QObject::tr( + "\nThey will not be opened properly when you load the " + "scene next time.\nWhat do you want to do?"); int ret = DVGui::MsgBox( str, QObject::tr("Copy the levels to correspondent paths"), diff --git a/toonz/sources/toonz/mainwindow.cpp b/toonz/sources/toonz/mainwindow.cpp index 73a3525..3061ae7 100644 --- a/toonz/sources/toonz/mainwindow.cpp +++ b/toonz/sources/toonz/mainwindow.cpp @@ -2161,6 +2161,10 @@ void MainWindow::defineActions() { createToolOptionsAction("A_ToolOption_JoinVectors", tr("Join Vectors"), ""); createToolOptionsAction("A_ToolOption_ShowOnlyActiveSkeleton", tr("Show Only Active Skeleton"), ""); + createToolOptionsAction("A_ToolOption_RasterEraser", + tr("Brush Tool - Eraser (Raster option)"), ""); + createToolOptionsAction("A_ToolOption_LockAlpha", + tr("Brush Tool - Lock Alpha"), ""); // Option Menu createToolOptionsAction("A_ToolOption_BrushPreset", tr("Brush Preset"), ""); diff --git a/toonz/sources/toonz/sceneviewer.cpp b/toonz/sources/toonz/sceneviewer.cpp index 6082220..008cf7b 100644 --- a/toonz/sources/toonz/sceneviewer.cpp +++ b/toonz/sources/toonz/sceneviewer.cpp @@ -2056,8 +2056,18 @@ void SceneViewer::zoom(const TPointD ¢er, double factor) { //----------------------------------------------------------------------------- void SceneViewer::flipX() { - m_viewAff[0] = m_viewAff[0] * TScale(-1, 1); - m_viewAff[1] = m_viewAff[1] * TScale(-1, 1); + double flipAngle0 = (m_rotationAngle[0] * -1) * 2; + double flipAngle1 = (m_rotationAngle[1] * -1) * 2; + m_rotationAngle[0] += flipAngle0; + m_rotationAngle[1] += flipAngle1; + if (m_isFlippedX != m_isFlippedY) { + flipAngle0 = -flipAngle0; + flipAngle1 = -flipAngle1; + } + m_viewAff[0] = m_viewAff[0] * TRotation(flipAngle0) * TScale(-1, 1); + m_viewAff[1] = m_viewAff[1] * TRotation(flipAngle1) * TScale(-1, 1); + m_viewAff[0].a13 *= -1; + m_viewAff[1].a13 *= -1; m_isFlippedX = !m_isFlippedX; invalidateAll(); emit onZoomChanged(); @@ -2066,8 +2076,18 @@ void SceneViewer::flipX() { //----------------------------------------------------------------------------- void SceneViewer::flipY() { - m_viewAff[0] = m_viewAff[0] * TScale(1, -1); - m_viewAff[1] = m_viewAff[1] * TScale(1, -1); + double flipAngle0 = (m_rotationAngle[0] * -1) * 2; + double flipAngle1 = (m_rotationAngle[1] * -1) * 2; + m_rotationAngle[0] += flipAngle0; + m_rotationAngle[1] += flipAngle1; + if (m_isFlippedX != m_isFlippedY) { + flipAngle0 = -flipAngle0; + flipAngle1 = -flipAngle1; + } + m_viewAff[0] = m_viewAff[0] * TRotation(flipAngle0) * TScale(1, -1); + m_viewAff[1] = m_viewAff[1] * TRotation(flipAngle1) * TScale(1, -1); + m_viewAff[0].a23 *= -1; + m_viewAff[1].a23 *= -1; m_isFlippedY = !m_isFlippedY; invalidateAll(); emit onZoomChanged(); diff --git a/toonz/sources/toonz/startuppopup.cpp b/toonz/sources/toonz/startuppopup.cpp index fcc6408..e49fb68 100644 --- a/toonz/sources/toonz/startuppopup.cpp +++ b/toonz/sources/toonz/startuppopup.cpp @@ -95,9 +95,9 @@ StartupPopup::StartupPopup() : Dialog(TApp::instance()->getMainWindow(), true, true, "StartupPopup") { setWindowTitle(tr("OpenToonz Startup")); - m_projectBox = new QGroupBox(tr("Choose Project"), this); + m_projectBox = new QGroupBox(tr("Current Project"), this); m_sceneBox = new QGroupBox(tr("Create a New Scene"), this); - m_recentBox = new QGroupBox(tr("Open Scene [Project]"), this); + m_recentBox = new QGroupBox(tr("Recent Scenes [Project]"), this); m_projectBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_nameFld = new LineEdit(this); m_pathFld = new FileField(this); @@ -168,6 +168,7 @@ StartupPopup::StartupPopup() m_sceneBox->setMinimumWidth(480); m_projectBox->setMinimumWidth(480); m_buttonFrame->setFixedHeight(34); + //--- layout m_topLayout->setMargin(0); m_topLayout->setSpacing(0); @@ -240,14 +241,15 @@ StartupPopup::StartupPopup() newSceneLay->addWidget(createButton, 7, 1, 1, 3, Qt::AlignLeft); } m_sceneBox->setLayout(newSceneLay); - guiLay->addWidget(m_sceneBox, 2, 0, 4, 1, Qt::AlignLeft); + guiLay->addWidget(m_sceneBox, 2, 0, 4, 1, Qt::AlignTop); m_recentSceneLay->setMargin(5); m_recentSceneLay->setSpacing(2); { // Recent Scene List m_recentBox->setLayout(m_recentSceneLay); - guiLay->addWidget(m_recentBox, 1, 1, 4, 1, Qt::AlignTop); + guiLay->addWidget(m_recentBox, 1, 1, 4, 1, + Qt::AlignTop | Qt::AlignHCenter); guiLay->addWidget(loadOtherSceneButton, 5, 1, 1, 1, Qt::AlignRight); } m_topLayout->addLayout(guiLay, 0); @@ -867,7 +869,15 @@ void StartupPopup::onRecentSceneClicked(int index) { DVGui::warning(msg); refreshRecentScenes(); } else { - IoCmd::loadScene(TFilePath(path.toStdWString()), false); + if (RecentFiles::instance()->getFileProject(index) != "-") { + QString projectName = RecentFiles::instance()->getFileProject(index); + int projectIndex = m_projectsCB->findText(projectName); + if (projectIndex >= 0) { + TFilePath projectFp = m_projectPaths[projectIndex]; + TProjectManager::instance()->setCurrentProjectPath(projectFp); + } + } + IoCmd::loadScene(TFilePath(path.toStdWString()), false, true); QString origProjectName = RecentFiles::instance()->getFileProject(index); QString projectName = QString::fromStdString(TApp::instance() ->getCurrentScene() diff --git a/toonz/sources/toonz/tasksviewer.cpp b/toonz/sources/toonz/tasksviewer.cpp index e9abdf6..f76bbd8 100644 --- a/toonz/sources/toonz/tasksviewer.cpp +++ b/toonz/sources/toonz/tasksviewer.cpp @@ -324,7 +324,7 @@ void TaskSheet::update(TFarmTask *task) { m_commandLine->setText(task->getCommandLine()); m_server->setText(task->m_server); m_submittedBy->setText(task->m_user); - m_submittedOn->setText(task->m_submissionDate.toString()); + m_submittedOn->setText(task->m_callerMachineName); m_priority->setText(QString::number(task->m_priority)); m_submitDate->setText(task->m_submissionDate.toString()); m_startDate->setText(task->m_startDate.toString()); diff --git a/toonz/sources/toonz/tpanels.cpp b/toonz/sources/toonz/tpanels.cpp index 0f77011..4e5a6c1 100644 --- a/toonz/sources/toonz/tpanels.cpp +++ b/toonz/sources/toonz/tpanels.cpp @@ -53,6 +53,7 @@ #include "toonzqt/tselectionhandle.h" #include "toonzqt/tmessageviewer.h" #include "toonzqt/scriptconsole.h" +#include "toonzqt/fxsettings.h" // TnzLib includes #include "toonz/palettecontroller.h" @@ -1358,3 +1359,52 @@ public: OpenFloatingPanel openHistoryPanelCommand(MI_OpenHistoryPanel, "HistoryPanel", QObject::tr("History")); //============================================================================= + +//============================================================================= +// FxSettings +//----------------------------------------------------------------------------- + +FxSettingsPanel::FxSettingsPanel(QWidget *parent) : TPanel(parent) { + TApp *app = TApp::instance(); + TSceneHandle *hScene = app->getCurrentScene(); + TPixel32 col1, col2; + Preferences::instance()->getChessboardColors(col1, col2); + + m_fxSettings = new FxSettings(this, col1, col2); + m_fxSettings->setSceneHandle(hScene); + m_fxSettings->setFxHandle(app->getCurrentFx()); + m_fxSettings->setFrameHandle(app->getCurrentFrame()); + m_fxSettings->setXsheetHandle(app->getCurrentXsheet()); + m_fxSettings->setLevelHandle(app->getCurrentLevel()); + m_fxSettings->setObjectHandle(app->getCurrentObject()); + + m_fxSettings->setCurrentFx(); + + setWidget(m_fxSettings); +} + +//============================================================================= +// FxSettingsFactory +//----------------------------------------------------------------------------- + +class FxSettingsFactory final : public TPanelFactory { +public: + FxSettingsFactory() : TPanelFactory("FxSettings") {} + + TPanel *createPanel(QWidget *parent) override { + FxSettingsPanel *panel = new FxSettingsPanel(parent); + panel->move(qApp->desktop()->screenGeometry(panel).center()); + panel->setObjectName(getPanelType()); + panel->setWindowTitle(QObject::tr("Fx Settings")); + panel->setMinimumSize(390, 85); + panel->allowMultipleInstances(false); + return panel; + } + + void initialize(TPanel *panel) override { assert(0); } + +} FxSettingsFactory; + +//============================================================================= +OpenFloatingPanel openFxSettingsCommand(MI_FxParamEditor, "FxSettings", + QObject::tr("Fx Settings")); diff --git a/toonz/sources/toonz/tpanels.h b/toonz/sources/toonz/tpanels.h index 2a0498a..904902b 100644 --- a/toonz/sources/toonz/tpanels.h +++ b/toonz/sources/toonz/tpanels.h @@ -25,6 +25,8 @@ class FunctionViewer; class FlipBook; class ToolOptions; class ComboViewerPanel; +class FxSettings; + //========================================================= // PaletteViewerPanel //--------------------------------------------------------- @@ -267,4 +269,17 @@ protected: void widgetClearFocusOnLeave() override; }; +//========================================================= +// FxSettingsPanel +//--------------------------------------------------------- + +class FxSettingsPanel final : public TPanel { + Q_OBJECT + + FxSettings *m_fxSettings; + +public: + FxSettingsPanel(QWidget *parent); +}; + #endif diff --git a/toonz/sources/toonzfarm/tfarm/tfarmtask.cpp b/toonz/sources/toonzfarm/tfarm/tfarmtask.cpp index f4c79a8..66ffc5f 100644 --- a/toonz/sources/toonzfarm/tfarm/tfarmtask.cpp +++ b/toonz/sources/toonzfarm/tfarm/tfarmtask.cpp @@ -19,7 +19,7 @@ // MACOSX includes #ifdef _WIN32 #include -#elif MACOSX +#elif defined(MACOSX) #include "tversion.h" using namespace TVER; #include // gethostbyname @@ -361,12 +361,12 @@ void TFarmTask::saveData(TOStream &os) { //------------------------------------------------------------------------------ namespace { -QString getExeName(bool isComposer) { +static QString getExeName(bool isComposer) { QString name = isComposer ? "tcomposer" : "tcleanup"; #ifdef _WIN32 return name + ".exe "; -#elif MACOSX +#elif defined(MACOSX) TVER::ToonzVersion tver; return "\"./" + QString::fromStdString(tver.getAppName()) + "_" + QString::fromStdString(tver.getAppVersionString()) + @@ -380,7 +380,7 @@ QString getExeName(bool isComposer) { QString toString(int value, int w, char c = ' ') { QString s = QString::number(value); - while (s.size() < w) s= c + s; + while (s.size() < w) s = c + s; return s; } @@ -642,7 +642,7 @@ TFarmTaskGroup::TFarmTaskGroup(const QString &id, const QString &name, threadsIndex, maxTileSizeIndex, Overwrite_Off, false) , m_imp(new Imp()) { int subCount = 0; - if (chunksize > 0) subCount= tceil((to - from + 1) / (double)chunksize); + if (chunksize > 0) subCount = tceil((to - from + 1) / (double)chunksize); int ra = from; if (subCount > 1) { diff --git a/toonz/sources/toonzfarm/tfarmserver/tfarmserver.cpp b/toonz/sources/toonzfarm/tfarmserver/tfarmserver.cpp index b9281ec..be839a3 100644 --- a/toonz/sources/toonzfarm/tfarmserver/tfarmserver.cpp +++ b/toonz/sources/toonzfarm/tfarmserver/tfarmserver.cpp @@ -378,12 +378,12 @@ private: }; //------------------------------------------------------------------- -QString getExeName(bool isComposer) { +static QString getExeName(bool isComposer) { QString name = isComposer ? "tcomposer" : "tcleanup"; #ifdef _WIN32 return name + ".exe "; -#elif MACOSX +#elif defined(MACOSX) TVER::ToonzVersion tver; return "\"./" + QString::fromStdString(tver.getAppName()) + "_" + QString::fromStdString(tver.getAppVersionString()) + @@ -433,7 +433,7 @@ void Task::run() { m_log->info(logMsg); -// =========== + // =========== #ifdef _WIN32 if (m_cmdline.contains("runcasm")) service.mountDisks(); @@ -994,8 +994,8 @@ void FarmServerService::onStop() { } catch (TException & /*e*/) { } -// i dischi vengono montati al primo task di tipo "runcasm" -// e smontati allo stop del servizio + // i dischi vengono montati al primo task di tipo "runcasm" + // e smontati allo stop del servizio #ifdef _WIN32 unmountDisks(); diff --git a/toonz/sources/toonzlib/cellpositionratio.cpp b/toonz/sources/toonzlib/cellpositionratio.cpp index 1b95b03..f3286ec 100644 --- a/toonz/sources/toonzlib/cellpositionratio.cpp +++ b/toonz/sources/toonzlib/cellpositionratio.cpp @@ -4,7 +4,7 @@ #include // Euclid's algorithm -int greatestCommonDivisor(int a, int b) { +static int greatestCommonDivisor(int a, int b) { a = std::abs(a); b = std::abs(b); int c = std::max(a, b); @@ -18,12 +18,14 @@ int greatestCommonDivisor(int a, int b) { return c; } +#if 0 /* UNUSED */ int leastCommonMultiple(int a, int b) { return a * b / greatestCommonDivisor(a, b); } +#endif void Ratio::normalize() { - int gcd = greatestCommonDivisor(m_num, m_denom); + int gcd = greatestCommonDivisor(m_num, m_denom); if (m_denom < 0) gcd = -gcd; m_num /= gcd; m_denom /= gcd; diff --git a/toonz/sources/toonzlib/fill.cpp b/toonz/sources/toonzlib/fill.cpp index 902a853..7072667 100644 --- a/toonz/sources/toonzlib/fill.cpp +++ b/toonz/sources/toonzlib/fill.cpp @@ -170,7 +170,7 @@ void fillRow(const TRasterCM32P &r, const TPoint &p, int &xa, int &xb, //----------------------------------------------------------------------------- void findSegment(const TRaster32P &r, const TPoint &p, int &xa, int &xb, - const TPixel32 &color) { + const TPixel32 &color, const int fillDepth = 254) { int matte, oldmatte; TPixel32 *pix, *pix0, *limit, *tmp_limit; @@ -185,7 +185,7 @@ void findSegment(const TRaster32P &r, const TPoint &p, int &xa, int &xb, for (; pix <= limit; pix++) { if (*pix == color) break; matte = pix->m; - if (matte < oldmatte || matte == 255) break; + if (matte < oldmatte || matte > fillDepth) break; oldmatte = matte; } if (matte == 0) { @@ -206,7 +206,7 @@ void findSegment(const TRaster32P &r, const TPoint &p, int &xa, int &xb, for (; pix >= limit; pix--) { if (*pix == color) break; matte = pix->m; - if (matte < oldmatte || matte == 255) break; + if (matte < oldmatte || matte > fillDepth) break; oldmatte = matte; } if (matte == 0) { @@ -221,6 +221,77 @@ void findSegment(const TRaster32P &r, const TPoint &p, int &xa, int &xb, } //----------------------------------------------------------------------------- +// Used when the clicked pixel is solid or semi-transparent. +// Check if the fill is stemmed at the target pixel. +// Note that RGB values are used for checking the difference, not Alpha value. + +bool doesStemFill(const TPixel32 &clickColor, const TPixel32 *targetPix, + const int fillDepth2) { + // stop if the target pixel is transparent + if (targetPix->m == 0) return true; + // check difference of RGB values is larger than fillDepth + int dr = (int)clickColor.r - (int)targetPix->r; + int dg = (int)clickColor.g - (int)targetPix->g; + int db = (int)clickColor.b - (int)targetPix->b; + return (dr * dr + dg * dg + db * db) > + fillDepth2; // condition for "stem" the fill +} + +//----------------------------------------------------------------------------- + +void fullColorFindSegment(const TRaster32P &r, const TPoint &p, int &xa, + int &xb, const TPixel32 &color, + const TPixel32 &clickedPosColor, + const int fillDepth) { + if (clickedPosColor.m == 0) { + findSegment(r, p, xa, xb, color, fillDepth); + return; + } + + TPixel32 *pix, *pix0, *limit; + // check to the right + TPixel32 *line = r->pixels(p.y); + + pix0 = line + p.x; // seed pixel + pix = pix0; + limit = line + r->getBounds().x1; // right end + + TPixel32 oldPix = *pix; + + int fillDepth2 = fillDepth * fillDepth; + + for (; pix <= limit; pix++) { + // break if the target pixel is with the same as filling color + if (*pix == color) break; + // continue if the target pixel is the same as the previous one + if (*pix == oldPix) continue; + + if (doesStemFill(clickedPosColor, pix, fillDepth2)) break; + + // store pixel color in case if the next pixel is with the same color + oldPix = *pix; + } + xb = p.x + pix - pix0 - 1; + + // check to the left + pix = pix0; // seed pixel + limit = line + r->getBounds().x0; // left end + oldPix = *pix; + for (; pix >= limit; pix--) { + // break if the target pixel is with the same as filling color + if (*pix == color) break; + // continue if the target pixel is the same as the previous one + if (*pix == oldPix) continue; + + if (doesStemFill(clickedPosColor, pix, fillDepth2)) break; + + // store pixel color in case if the next pixel is with the same color + oldPix = *pix; + } + xa = p.x + pix - pix0 + 1; +} + +//----------------------------------------------------------------------------- class FillSeed { public: @@ -272,6 +343,23 @@ void insertSegment(std::vector> &segments, } //----------------------------------------------------------------------------- + +bool floodCheck(const TPixel32 &clickColor, const TPixel32 *targetPix, + const TPixel32 *oldPix, const int fillDepth) { + auto fullColorThreshMatte = [](int matte, int fillDepth) -> int { + return (matte <= fillDepth) ? matte : 255; + }; + + if (clickColor.m == 0) { + int oldMatte = fullColorThreshMatte(oldPix->m, fillDepth); + int matte = fullColorThreshMatte(targetPix->m, fillDepth); + return matte >= oldMatte && matte != 255; + } + int fillDepth2 = fillDepth * fillDepth; + return !doesStemFill(clickColor, targetPix, fillDepth2); +} + +//----------------------------------------------------------------------------- } // namespace //----------------------------------------------------------------------------- /*-- 戻り値はsaveBoxが更新されたかどうか --*/ @@ -588,3 +676,129 @@ void inkFill(const TRasterCM32P &r, const TPoint &pin, int ink, int searchRay, } r->unlock(); } + +//----------------------------------------------------------------------------- + +void fullColorFill(const TRaster32P &ras, const FillParameters ¶ms, + TTileSaverFullColor *saver) { + int oldy, xa, xb, xc, xd, dy, oldxd, oldxc; + TPixel32 *pix, *limit, *pix0, *oldpix; + int x = params.m_p.x, y = params.m_p.y; + + TRect bbbox = ras->getBounds(); + if (!bbbox.contains(params.m_p)) return; + + TPixel32 clickedPosColor = *(ras->pixels(y) + x); + + TPaletteP plt = params.m_palette; + TPixel32 color = plt->getStyle(params.m_styleId)->getMainColor(); + + if (clickedPosColor == color) return; + + int fillDepth = + params.m_shiftFill ? params.m_maxFillDepth : params.m_minFillDepth; + + assert(fillDepth >= 0 && fillDepth < 16); + TPointD m_firstPoint, m_clickPoint; + + // convert fillDepth range from [0 - 15] to [0 - 255] + fillDepth = (fillDepth << 4) | fillDepth; + + std::stack seeds; + std::map>> segments; + + fullColorFindSegment(ras, params.m_p, xa, xb, color, clickedPosColor, + fillDepth); + + segments[y].push_back(std::pair(xa, xb)); + seeds.push(FillSeed(xa, xb, y, 1)); + seeds.push(FillSeed(xa, xb, y, -1)); + + while (!seeds.empty()) { + FillSeed fs = seeds.top(); + seeds.pop(); + + xa = fs.m_xa; + xb = fs.m_xb; + oldy = fs.m_y; + dy = fs.m_dy; + y = oldy + dy; + // continue if the fill runs over image bounding + if (y > bbbox.y1 || y < bbbox.y0) continue; + // left end of the pixels to be filled + pix = pix0 = ras->pixels(y) + xa; + // right end of the pixels to be filled + limit = ras->pixels(y) + xb; + // left end of the fill seed pixels + oldpix = ras->pixels(oldy) + xa; + + x = xa; + oldxd = (std::numeric_limits::min)(); + oldxc = (std::numeric_limits::max)(); + + // check pixels to right + while (pix <= limit) { + bool test = false; + // check if the target is already in the range to be filled + if (segments.find(y) != segments.end()) + test = isPixelInSegment(segments[y], x); + + if (*pix != color && !test && + floodCheck(clickedPosColor, pix, oldpix, fillDepth)) { + // compute horizontal range to be filled + fullColorFindSegment(ras, TPoint(x, y), xc, xd, color, clickedPosColor, + fillDepth); + // insert segment to be filled + insertSegment(segments[y], std::pair(xc, xd)); + // create new fillSeed to invert direction, if needed + if (xc < xa) seeds.push(FillSeed(xc, xa - 1, y, -dy)); + if (xd > xb) seeds.push(FillSeed(xb + 1, xd, y, -dy)); + if (oldxd >= xc - 1) + oldxd = xd; + else { + if (oldxd >= 0) seeds.push(FillSeed(oldxc, oldxd, y, dy)); + oldxc = xc; + oldxd = xd; + } + // jump to the next pixel to the right end of the range + pix += xd - x + 1; + oldpix += xd - x + 1; + x += xd - x + 1; + } else { + pix++; + oldpix++, x++; + } + } + // insert filled range as new fill seed + if (oldxd > 0) seeds.push(FillSeed(oldxc, oldxd, y, dy)); + } + + // pixels are actually filled here + TPixel32 premultiColor = premultiply(color); + + std::map>>::iterator it; + for (it = segments.begin(); it != segments.end(); it++) { + TPixel32 *line = ras->pixels(it->first); + TPixel32 *refLine = 0; + std::vector> segmentVector = it->second; + for (int i = 0; i < (int)segmentVector.size(); i++) { + std::pair segment = segmentVector[i]; + if (segment.second >= segment.first) { + pix = line + segment.first; + if (saver) { + saver->save( + TRect(segment.first, it->first, segment.second, it->first)); + } + int n; + for (n = 0; n < segment.second - segment.first + 1; n++, pix++) { + if (clickedPosColor.m == 0) + *pix = pix->m == 0 ? color : overPix(color, *pix); + else if (color.m == 0 || color.m == 255) // used for erasing area + *pix = color; + else + *pix = overPix(*pix, premultiColor); + } + } + } + } +} diff --git a/toonz/sources/toonzlib/stylemanager.cpp b/toonz/sources/toonzlib/stylemanager.cpp index 35781c3..6bb014e 100644 --- a/toonz/sources/toonzlib/stylemanager.cpp +++ b/toonz/sources/toonzlib/stylemanager.cpp @@ -8,10 +8,16 @@ #include "tropcm.h" #include "tvectorrenderdata.h" #include "tsystem.h" +#include "tvectorgl.h" // Qt includes #include #include +#include +#include +#include +#include +#include #include "toonz/stylemanager.h" @@ -50,6 +56,7 @@ class CustomStyleManager::StyleLoaderTask final : public TThread::Runnable { CustomStyleManager *m_manager; TFilePath m_fp; PatternData m_data; + std::shared_ptr m_offScreenSurface; public: StyleLoaderTask(CustomStyleManager *manager, const TFilePath &fp); @@ -66,6 +73,12 @@ CustomStyleManager::StyleLoaderTask::StyleLoaderTask( : m_manager(manager), m_fp(fp) { connect(this, SIGNAL(finished(TThread::RunnableP)), this, SLOT(onFinished(TThread::RunnableP))); + + if (QThread::currentThread() == qGuiApp->thread()) { + m_offScreenSurface.reset(new QOffscreenSurface()); + m_offScreenSurface->setFormat(QSurfaceFormat::defaultFormat()); + m_offScreenSurface->create(); + } } //----------------------------------------------------------------------------- @@ -90,16 +103,39 @@ void CustomStyleManager::StyleLoaderTask::run() { TRasterImageP rimg = img; TRaster32P ras; + + QImage *image = nullptr; + if (vimg) { assert(level->getPalette()); TPalette *vPalette = level->getPalette(); assert(vPalette); vimg->setPalette(vPalette); - TOfflineGL *glContext = 0; - glContext = TOfflineGL::getStock(chipSize); + QOpenGLContext *glContext = new QOpenGLContext(); + if (QOpenGLContext::currentContext()) + glContext->setShareContext(QOpenGLContext::currentContext()); + glContext->setFormat(QSurfaceFormat::defaultFormat()); + glContext->create(); + glContext->makeCurrent(m_offScreenSurface.get()); + // attaching stencil buffer here as some styles use it + QOpenGLFramebufferObject fb( + chipSize.lx, chipSize.ly, + QOpenGLFramebufferObject::CombinedDepthStencil); + + fb.bind(); + // Draw + glViewport(0, 0, chipSize.lx, chipSize.ly); + glClearColor(1.0, 1.0, 1.0, 1.0); // clear with white color + glClear(GL_COLOR_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, chipSize.lx, 0, chipSize.ly); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); - glContext->clear(TPixel32::White); TRectD bbox = img->getBBox(); double scx = 0.8 * chipSize.lx / bbox.getLx(); double scy = 0.8 * chipSize.ly / bbox.getLy(); @@ -112,11 +148,14 @@ void CustomStyleManager::StyleLoaderTask::run() { TTranslation(-0.5 * (bbox.x0 + bbox.x1), -0.5 * (bbox.y0 + bbox.y1)); TVectorRenderData rd(aff, chipSize, vPalette, 0, true); - glContext->draw(img, rd); + tglDraw(rd, vimg.getPointer()); + + image = new QImage(fb.toImage().scaled(QSize(chipSize.lx, chipSize.ly), + Qt::IgnoreAspectRatio, + Qt::SmoothTransformation)); + fb.release(); + glContext->deleteLater(); - // No need to clone! The received raster already is a copy of the - // context's buffer - ras = glContext->getRaster(); //->clone(); } else if (rimg) { TDimension size = rimg->getRaster()->getSize(); if (size == chipSize) @@ -131,12 +170,11 @@ void CustomStyleManager::StyleLoaderTask::run() { TRop::addBackground(rout, TPixel::White); ras = rout; } + image = new QImage(chipSize.lx, chipSize.ly, QImage::Format_RGB32); + convertRaster32ToImage(ras, image); } else assert(!"unsupported type for custom styles!"); - QImage *image = new QImage(chipSize.lx, chipSize.ly, QImage::Format_RGB32); - convertRaster32ToImage(ras, image); - m_data.m_patternName = m_fp.getName(); m_data.m_isVector = (m_fp.getType() == "pli" || m_fp.getType() == "svg"); m_data.m_image = image; diff --git a/toonz/sources/toonzlib/ttileset.cpp b/toonz/sources/toonzlib/ttileset.cpp index c12288d..fa5e135 100644 --- a/toonz/sources/toonzlib/ttileset.cpp +++ b/toonz/sources/toonzlib/ttileset.cpp @@ -197,6 +197,16 @@ const TTileSetFullColor::Tile *TTileSetFullColor::getTile(int index) const { //------------------------------------------------------------------------------------------ +TTileSetFullColor::Tile *TTileSetFullColor::editTile(int index) const { + assert(0 <= index && index < getTileCount()); + TTileSetFullColor::Tile *tile = + dynamic_cast(m_tiles[index]); + assert(tile); + return tile; +} + +//------------------------------------------------------------------------------------------ + TTileSetFullColor *TTileSetFullColor::clone() const { TTileSetFullColor *tileSet = new TTileSetFullColor(m_srcImageSize); Tiles::const_iterator it = m_tiles.begin(); diff --git a/toonz/sources/toonzqt/fxschematicnode.cpp b/toonz/sources/toonzqt/fxschematicnode.cpp index 8651375..5affb29 100644 --- a/toonz/sources/toonzqt/fxschematicnode.cpp +++ b/toonz/sources/toonzqt/fxschematicnode.cpp @@ -46,6 +46,8 @@ // TnzCore includes #include "tconst.h" +#include "../toonz/menubarcommandids.h" + // Qt includes #include #include @@ -690,7 +692,7 @@ void FxPainter::contextMenuEvent(QGraphicsSceneContextMenuEvent *cme) { QMenu *addMenu = fxScene->getAddFxMenu(); QAction *fxEditorPopup = - CommandManager::instance()->getAction("MI_FxParamEditor"); + CommandManager::instance()->getAction(MI_FxParamEditor); QAction *copy = CommandManager::instance()->getAction("MI_Copy"); QAction *cut = CommandManager::instance()->getAction("MI_Cut"); QAction *group = CommandManager::instance()->getAction("MI_Group"); @@ -1579,7 +1581,7 @@ void FxSchematicPort::contextMenuEvent(QGraphicsSceneContextMenuEvent *cme) { SLOT(onConnectToXSheet())); QAction *fxEditorPopup = - CommandManager::instance()->getAction("MI_FxParamEditor"); + CommandManager::instance()->getAction(MI_FxParamEditor); menu.addMenu(fxScene->getAddFxMenu()); menu.addAction(fxEditorPopup); @@ -2238,6 +2240,15 @@ void FxSchematicOutputNode::mouseDoubleClickEvent( outputSettingsPopup->trigger(); } +void FxSchematicOutputNode::mousePressEvent(QGraphicsSceneMouseEvent *me) { + FxSchematicNode::mousePressEvent(me); + + QAction *fxEditorPopup = + CommandManager::instance()->getAction(MI_FxParamEditor); + // this signal cause the update the contents of the FxSettings + if (fxEditorPopup->isVisible()) emit fxNodeDoubleClicked(); +} + //***************************************************** // // FxSchematicXSheetNode @@ -2306,6 +2317,15 @@ void FxSchematicXSheetNode::mouseDoubleClickEvent( sceneSettingsPopup->trigger(); } +void FxSchematicXSheetNode::mousePressEvent(QGraphicsSceneMouseEvent *me) { + FxSchematicNode::mousePressEvent(me); + + QAction *fxEditorPopup = + CommandManager::instance()->getAction(MI_FxParamEditor); + // this signal cause the update the contents of the FxSettings + if (fxEditorPopup->isVisible()) emit fxNodeDoubleClicked(); +} + //***************************************************** // // FxSchematicNormalFxNode @@ -2620,9 +2640,9 @@ void FxSchematicNormalFxNode::mouseDoubleClickEvent( m_nameItem->setFocus(); setFlag(QGraphicsItem::ItemIsSelectable, false); } else { - QAction *fxEitorPopup = - CommandManager::instance()->getAction("MI_FxParamEditor"); - fxEitorPopup->trigger(); + QAction *fxEditorPopup = + CommandManager::instance()->getAction(MI_FxParamEditor); + fxEditorPopup->trigger(); // this signal cause the update the contents of the FxSettings emit fxNodeDoubleClicked(); } @@ -2630,6 +2650,17 @@ void FxSchematicNormalFxNode::mouseDoubleClickEvent( //----------------------------------------------------- +void FxSchematicNormalFxNode::mousePressEvent(QGraphicsSceneMouseEvent *me) { + FxSchematicNode::mousePressEvent(me); + + QAction *fxEditorPopup = + CommandManager::instance()->getAction(MI_FxParamEditor); + // this signal cause the update the contents of the FxSettings + if (fxEditorPopup->isVisible()) emit fxNodeDoubleClicked(); +} + +//----------------------------------------------------- + void FxSchematicNormalFxNode::resize(bool maximized) {} //***************************************************** @@ -2856,7 +2887,7 @@ void FxSchematicZeraryNode::mouseDoubleClickEvent( setFlag(QGraphicsItem::ItemIsSelectable, false); } else { QAction *fxEditorPopup = - CommandManager::instance()->getAction("MI_FxParamEditor"); + CommandManager::instance()->getAction(MI_FxParamEditor); fxEditorPopup->trigger(); // this signal cause the update the contents of the FxSettings @@ -2866,6 +2897,17 @@ void FxSchematicZeraryNode::mouseDoubleClickEvent( //----------------------------------------------------- +void FxSchematicZeraryNode::mousePressEvent(QGraphicsSceneMouseEvent *me) { + FxSchematicNode::mousePressEvent(me); + + QAction *fxEditorPopup = + CommandManager::instance()->getAction(MI_FxParamEditor); + // this signal cause the update the contents of the FxSettings + if (fxEditorPopup->isVisible()) emit fxNodeDoubleClicked(); +} + +//----------------------------------------------------- + void FxSchematicZeraryNode::onNameChanged() { m_nameItem->hide(); m_name = m_nameItem->toPlainText(); @@ -3164,11 +3206,28 @@ void FxSchematicColumnNode::mouseDoubleClickEvent( m_nameItem->show(); m_nameItem->setFocus(); setFlag(QGraphicsItem::ItemIsSelectable, false); + } else { + QAction *fxEditorPopup = + CommandManager::instance()->getAction(MI_FxParamEditor); + fxEditorPopup->trigger(); + // this signal cause the update the contents of the FxSettings + emit fxNodeDoubleClicked(); } } //----------------------------------------------------- +void FxSchematicColumnNode::mousePressEvent(QGraphicsSceneMouseEvent *me) { + FxSchematicNode::mousePressEvent(me); + + QAction *fxEditorPopup = + CommandManager::instance()->getAction(MI_FxParamEditor); + // this signal cause the update the contents of the FxSettings + if (fxEditorPopup->isVisible()) emit fxNodeDoubleClicked(); +} + +//----------------------------------------------------- + void FxSchematicColumnNode::renameObject(const TStageObjectId &id, std::string name) { FxSchematicScene *fxScene = dynamic_cast(scene()); @@ -3335,14 +3394,25 @@ void FxSchematicPaletteNode::mouseDoubleClickEvent( m_nameItem->setFocus(); setFlag(QGraphicsItem::ItemIsSelectable, false); } else { - QAction *fxEitorPopup = - CommandManager::instance()->getAction("MI_FxParamEditor"); - fxEitorPopup->trigger(); + QAction *fxEditorPopup = + CommandManager::instance()->getAction(MI_FxParamEditor); + fxEditorPopup->trigger(); } } //----------------------------------------------------- +void FxSchematicPaletteNode::mousePressEvent(QGraphicsSceneMouseEvent *me) { + FxSchematicNode::mousePressEvent(me); + + QAction *fxEditorPopup = + CommandManager::instance()->getAction(MI_FxParamEditor); + // this signal cause the update the contents of the FxSettings + if (fxEditorPopup->isVisible()) emit fxNodeDoubleClicked(); +} + +//----------------------------------------------------- + void FxSchematicPaletteNode::renameObject(const TStageObjectId &id, std::string name) { FxSchematicScene *fxScene = dynamic_cast(scene()); @@ -3494,6 +3564,15 @@ void FxGroupNode::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *me) { } } +void FxGroupNode::mousePressEvent(QGraphicsSceneMouseEvent *me) { + FxSchematicNode::mousePressEvent(me); + + QAction *fxEditorPopup = + CommandManager::instance()->getAction(MI_FxParamEditor); + // this signal cause the update the contents of the FxSettings + if (fxEditorPopup->isVisible()) emit fxNodeDoubleClicked(); +} + //----------------------------------------------------- QPointF FxGroupNode::computePos() const { diff --git a/toonz/sources/toonzqt/fxschematicscene.cpp b/toonz/sources/toonzqt/fxschematicscene.cpp index e16c8ab..dfb2b01 100644 --- a/toonz/sources/toonzqt/fxschematicscene.cpp +++ b/toonz/sources/toonzqt/fxschematicscene.cpp @@ -578,6 +578,8 @@ FxSchematicNode *FxSchematicScene::addGroupedFxSchematicNode( SLOT(onSwitchCurrentFx(TFx *))); connect(node, SIGNAL(currentColumnChanged(int)), this, SLOT(onCurrentColumnChanged(int))); + connect(node, SIGNAL(fxNodeDoubleClicked()), this, + SLOT(onFxNodeDoubleClicked())); m_groupedTable[groupId] = node; return node; } diff --git a/toonz/sources/toonzqt/fxsettings.cpp b/toonz/sources/toonzqt/fxsettings.cpp index 20f35ab..2c2da56 100644 --- a/toonz/sources/toonzqt/fxsettings.cpp +++ b/toonz/sources/toonzqt/fxsettings.cpp @@ -16,6 +16,7 @@ #include "pluginhost.h" #include "tenv.h" #include "tsystem.h" +#include "docklayout.h" #include "toonz/tcamera.h" #include "toonz/toonzfolders.h" @@ -38,7 +39,6 @@ #include #include #include -#include #include #include @@ -1016,9 +1016,12 @@ void ParamViewer::setFx(const TFxP ¤tFx, const TFxP &actualFx, int frame, if (m_fx != currentFx) { getCurrentPageSet()->setFx(currentFx, actualFx, frame); - QSize pageViewerPreferedSize = - getCurrentPageSet()->getPreferedSize() + QSize(2, 20); - emit preferedSizeChanged(pageViewerPreferedSize); + if (m_actualFx != actualFx) { + m_actualFx = actualFx; + QSize pageViewerPreferedSize = + getCurrentPageSet()->getPreferedSize() + QSize(2, 50); + emit preferedSizeChanged(pageViewerPreferedSize); + } } } @@ -1086,7 +1089,8 @@ FxSettings::FxSettings(QWidget *parent, const TPixel32 &checkCol1, , m_checkCol1(checkCol1) , m_checkCol2(checkCol2) , m_isCameraModeView(false) - , m_container_height(177) { + , m_container_height(184) + , m_container_width(390) { // param viewer m_paramViewer = new ParamViewer(this); // swatch @@ -1306,7 +1310,7 @@ void FxSettings::setCurrentFrame() { //----------------------------------------------------------------------------- void FxSettings::changeTitleBar(TFx *fx) { - QDialog *popup = dynamic_cast(parentWidget()); + DockWidget *popup = dynamic_cast(parentWidget()); if (!popup) return; QString titleText(tr("Fx Settings")); @@ -1512,12 +1516,19 @@ void FxSettings::onViewModeChanged(QAction *triggeredAct) { void FxSettings::onPreferedSizeChanged(QSize pvBestSize) { QSize popupBestSize = pvBestSize; + + // Set minimum size, just in case + popupBestSize.setHeight(std::max(popupBestSize.height(), 85)); + popupBestSize.setWidth(std::max(popupBestSize.width(), 390)); + if (m_toolBar->isVisible()) { - popupBestSize += QSize(0, m_viewer->height() + m_toolBar->height()); + popupBestSize += QSize(0, m_viewer->height() + m_toolBar->height() + 4); + popupBestSize.setWidth( + std::max(popupBestSize.width(), m_viewer->width() + 13)); } - QDialog *popup = dynamic_cast(parentWidget()); - if (popup) { + DockWidget *popup = dynamic_cast(parentWidget()); + if (popup && popup->isFloating()) { QRect geom = popup->geometry(); geom.setSize(popupBestSize); popup->setGeometry(geom); @@ -1530,19 +1541,24 @@ void FxSettings::onPreferedSizeChanged(QSize pvBestSize) { void FxSettings::onShowSwatchButtonToggled(bool on) { QWidget *bottomContainer = widget(1); - if (!on) + if (!on) { m_container_height = bottomContainer->height() + handleWidth() /* ハンドル幅 */; - + m_container_width = m_viewer->width() + 13; + } bottomContainer->setVisible(on); - QDialog *popup = dynamic_cast(parentWidget()); - if (popup) { + DockWidget *popup = dynamic_cast(parentWidget()); + if (popup && popup->isFloating()) { QRect geom = popup->geometry(); int height_change = (on) ? m_container_height : -m_container_height; + int width_change = 0; + + if (on && m_container_width > geom.width()) + width_change = m_container_width - geom.width(); - geom.setSize(geom.size() + QSize(0, height_change)); + geom.setSize(geom.size() + QSize(width_change, height_change)); popup->setGeometry(geom); popup->update(); } diff --git a/toonz/sources/toonzqt/styleeditor.cpp b/toonz/sources/toonzqt/styleeditor.cpp index fa4df3f..00c0944 100644 --- a/toonz/sources/toonzqt/styleeditor.cpp +++ b/toonz/sources/toonzqt/styleeditor.cpp @@ -1880,7 +1880,8 @@ else return false; void drawChip(QPainter &p, QRect rect, int index) override { assert(0 <= index && index < getChipCount()); CustomStyleManager::PatternData pattern = styleManager()->getPattern(index); - p.drawImage(rect, *pattern.m_image); + if (pattern.m_image && !pattern.m_image->isNull()) + p.drawImage(rect, *pattern.m_image); } void onSelect(int index) override; };