Merged in OT master with conflicts resolved

This commit is contained in:
manongjohn 2019-06-30 10:47:11 -04:00
commit ec91972302
35 changed files with 955 additions and 136 deletions

View file

@ -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);
}
//--------------------------------------------------

View file

@ -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) {

View file

@ -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
//------------------------------------------------------------------------------------

View file

@ -4,6 +4,8 @@
extern "C" {
#endif
#include "ttwain_statePD.h"
int TTWAIN_LoadSourceManagerPD(void) { return 0; }
int TTWAIN_UnloadSourceManagerPD(void) { return 1; }

View file

@ -474,6 +474,21 @@ protected slots:
void onColorModeChanged(int);
};
//=============================================================================
//
// FullColorFillToolOptionsBox
//
//=============================================================================
class FullColorFillToolOptionsBox final : public ToolOptionsBox {
Q_OBJECT
public:
FullColorFillToolOptionsBox(QWidget *parent, TTool *tool,
TPaletteHandle *pltHandle,
ToolHandle *toolHandle);
};
//=============================================================================
//
// FillToolOptionsBox

View file

@ -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 &params,
TTileSaverFullColor *saver = 0);
//=============================================================================
//! The class AreaFiller allows to fill a raster area, delimited by rect or
//! spline.

View file

@ -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;
};

View file

@ -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:

View file

@ -190,6 +190,7 @@ class DVAPI ParamViewer final : public QFrame {
Q_OBJECT
TFxP m_fx;
TFxP m_actualFx;
QStackedWidget *m_tablePageSet;
QMap<std::string, int> 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,

View file

@ -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

View file

@ -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();
}

View file

@ -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 &params,
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 &params,
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)では、マイナス座標でずれが生じる --*/
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;

View file

@ -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 <QCoreApplication>
#include <QObject>
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

View file

@ -125,7 +125,8 @@ ToolOptionsBox::ToolOptionsBox(QWidget *parent, bool isScrollable)
ToolOptionsBox::~ToolOptionsBox() {
std::for_each(m_controls.begin(), m_controls.end(),
std::default_delete<ToolOptionControl>());
std::for_each(m_labels.begin(), m_labels.end(), std::default_delete<QLabel>());
std::for_each(m_labels.begin(), m_labels.end(),
std::default_delete<QLabel>());
}
//-----------------------------------------------------------------------------
@ -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");
@ -1633,6 +1645,25 @@ void PaintbrushToolOptionsBox::onColorModeChanged(int index) {
m_selectiveMode->setEnabled(enabled);
}
//=============================================================================
//
// 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);

View file

@ -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,

View file

@ -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();
};
//-----------------------------------------------------------------------------

View file

@ -70,9 +70,8 @@ void doUpdateXSheet(TXshSimpleLevel *sl, std::vector<TFrameId> 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<TFrameId> oldFids,
//-----------------------------------------------------------------------------
void updateXSheet(TXshSimpleLevel *sl, std::vector<TFrameId> oldFids,
std::vector<TFrameId> newFids) {
static void updateXSheet(TXshSimpleLevel *sl, std::vector<TFrameId> oldFids,
std::vector<TFrameId> newFids) {
std::vector<TXshChildLevel *> 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<TFrameId> 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 {

View file

@ -59,6 +59,7 @@ FxParamEditorPopup::FxParamEditorPopup()
}
//=============================================================================
/*
OpenPopupCommandHandler<FxParamEditorPopup> openFxParamEditorPopup(
MI_FxParamEditor);
*/

View file

@ -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<TXshLevel *> 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"),

View file

@ -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"), "");

View file

@ -2056,8 +2056,18 @@ void SceneViewer::zoom(const TPointD &center, 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();

View file

@ -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()

View file

@ -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());

View file

@ -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"));

View file

@ -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

View file

@ -19,7 +19,7 @@
// MACOSX includes
#ifdef _WIN32
#include <winsock.h>
#elif MACOSX
#elif defined(MACOSX)
#include "tversion.h"
using namespace TVER;
#include <netdb.h> // 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) {

View file

@ -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();

View file

@ -4,7 +4,7 @@
#include <algorithm>
// 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;

View file

@ -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) {
@ -220,6 +220,77 @@ void findSegment(const TRaster32P &r, const TPoint &p, int &xa, int &xb,
xa = p.x + pix - pix0 + 1;
}
//-----------------------------------------------------------------------------
// 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 {
@ -271,6 +342,23 @@ void insertSegment(std::vector<std::pair<int, int>> &segments,
segments.push_back(segment);
}
//-----------------------------------------------------------------------------
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
//-----------------------------------------------------------------------------
@ -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 &params,
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<FillSeed> seeds;
std::map<int, std::vector<std::pair<int, int>>> segments;
fullColorFindSegment(ras, params.m_p, xa, xb, color, clickedPosColor,
fillDepth);
segments[y].push_back(std::pair<int, int>(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<int>::min)();
oldxc = (std::numeric_limits<int>::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<int, int>(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<int, std::vector<std::pair<int, int>>>::iterator it;
for (it = segments.begin(); it != segments.end(); it++) {
TPixel32 *line = ras->pixels(it->first);
TPixel32 *refLine = 0;
std::vector<std::pair<int, int>> segmentVector = it->second;
for (int i = 0; i < (int)segmentVector.size(); i++) {
std::pair<int, int> 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);
}
}
}
}
}

View file

@ -8,10 +8,16 @@
#include "tropcm.h"
#include "tvectorrenderdata.h"
#include "tsystem.h"
#include "tvectorgl.h"
// Qt includes
#include <QDir>
#include <QImage>
#include <QOffscreenSurface>
#include <QThread>
#include <QGuiApplication>
#include <QOpenGLContext>
#include <QOpenGLFramebufferObject>
#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<QOffscreenSurface> 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;

View file

@ -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<TTileSetFullColor::Tile *>(m_tiles[index]);
assert(tile);
return tile;
}
//------------------------------------------------------------------------------------------
TTileSetFullColor *TTileSetFullColor::clone() const {
TTileSetFullColor *tileSet = new TTileSetFullColor(m_srcImageSize);
Tiles::const_iterator it = m_tiles.begin();

View file

@ -46,6 +46,8 @@
// TnzCore includes
#include "tconst.h"
#include "../toonz/menubarcommandids.h"
// Qt includes
#include <QAction>
#include <QApplication>
@ -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<FxSchematicScene *>(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<FxSchematicScene *>(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 {

View file

@ -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;
}

View file

@ -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 <QMap>
#include <QPainter>
#include <QCheckBox>
#include <QDialog>
#include <QPushButton>
#include <QDesktopServices>
@ -1016,9 +1016,12 @@ void ParamViewer::setFx(const TFxP &currentFx, 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<QDialog *>(parentWidget());
DockWidget *popup = dynamic_cast<DockWidget *>(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<QDialog *>(parentWidget());
if (popup) {
DockWidget *popup = dynamic_cast<DockWidget *>(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<QDialog *>(parentWidget());
if (popup) {
DockWidget *popup = dynamic_cast<DockWidget *>(parentWidget());
if (popup && popup->isFloating()) {
QRect geom = popup->geometry();
int height_change = (on) ? m_container_height : -m_container_height;
int width_change = 0;
geom.setSize(geom.size() + QSize(0, height_change));
if (on && m_container_width > geom.width())
width_change = m_container_width - geom.width();
geom.setSize(geom.size() + QSize(width_change, height_change));
popup->setGeometry(geom);
popup->update();
}

View file

@ -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;
};