diff --git a/stuff/config/colornames.txt b/stuff/config/colornames.txt
new file mode 100644
index 0000000..f139a27
--- /dev/null
+++ b/stuff/config/colornames.txt
@@ -0,0 +1,164 @@
+
+
+
+ #FF0000
+ #00FF00
+ #0000FF
+
+ #FFFFFF00
+ #FFFFFF00
+ #00000000
+ #000000
+ #FF0000
+ #00FF00
+ #0000FF
+
+ #F0F8FF
+ #FAEBD7
+ #00FFFF
+ #7FFFD4
+ #F0FFFF
+ #F5F5DC
+ #FFE4C4
+ #000000
+ #FFEBCD
+ #0000FF
+ #8A2BE2
+ #A52A2A
+ #DEB887
+ #5F9EA0
+ #7FFF00
+ #D2691E
+ #FF7F50
+ #6495ED
+ #FFF8DC
+ #DC143C
+ #00FFFF
+ #00008B
+ #008B8B
+ #B8860B
+ #A9A9A9
+ #A9A9A9
+ #006400
+ #BDB76B
+ #8B008B
+ #556B2F
+ #FF8C00
+ #9932CC
+ #8B0000
+ #E9967A
+ #8FBC8F
+ #483D8B
+ #2F4F4F
+ #2F4F4F
+ #00CED1
+ #9400D3
+ #FF1493
+ #00BFFF
+ #696969
+ #696969
+ #1E90FF
+ #B22222
+ #FFFAF0
+ #228B22
+ #FF00FF
+ #DCDCDC
+ #F8F8FF
+ #FFD700
+ #DAA520
+ #808080
+ #808080
+ #008000
+ #ADFF2F
+ #F0FFF0
+ #FF69B4
+ #CD5C5C
+ #4B0082
+ #FFFFF0
+ #F0E68C
+ #E6E6FA
+ #FFF0F5
+ #7CFC00
+ #FFFACD
+ #ADD8E6
+ #F08080
+ #E0FFFF
+ #FAFAD2
+ #D3D3D3
+ #D3D3D3
+ #90EE90
+ #FFB6C1
+ #FFA07A
+ #20B2AA
+ #87CEFA
+ #778899
+ #778899
+ #B0C4DE
+ #FFFFE0
+ #00FF00
+ #32CD32
+ #FAF0E6
+ #FF00FF
+ #800000
+ #66CDAA
+ #0000CD
+ #BA55D3
+ #9370DB
+ #3CB371
+ #7B68EE
+ #00FA9A
+ #48D1CC
+ #C71585
+ #191970
+ #F5FFFA
+ #FFE4E1
+ #FFE4B5
+ #FFDEAD
+ #000080
+ #FDF5E6
+ #808000
+ #6B8E23
+ #FFA500
+ #FF4500
+ #DA70D6
+ #EEE8AA
+ #98FB98
+ #AFEEEE
+ #DB7093
+ #FFEFD5
+ #FFDAB9
+ #CD853F
+ #FFC0CB
+ #DDA0DD
+ #B0E0E6
+ #800080
+ #663399
+ #FF0000
+ #BC8F8F
+ #4169E1
+ #8B4513
+ #FA8072
+ #F4A460
+ #2E8B57
+ #FFF5EE
+ #A0522D
+ #C0C0C0
+ #87CEEB
+ #6A5ACD
+ #708090
+ #708090
+ #FFFAFA
+ #00FF7F
+ #4682B4
+ #D2B48C
+ #008080
+ #D8BFD8
+ #FF6347
+ #40E0D0
+ #EE82EE
+ #F5DEB3
+ #FFFFFF
+ #F5F5F5
+ #FFFF00
+ #9ACD32
+
diff --git a/toonz/sources/common/tvrender/tcolorstyles.cpp b/toonz/sources/common/tvrender/tcolorstyles.cpp
index 98d0da4..9a8cfee 100644
--- a/toonz/sources/common/tvrender/tcolorstyles.cpp
+++ b/toonz/sources/common/tvrender/tcolorstyles.cpp
@@ -292,13 +292,12 @@ void TColorStyle::makeIcon(const TDimension &d) {
bbox = bbox.enlarge(TDimensionD(-10, -10));
checkErrorsByGL;
- double scx = 0.9 * d.lx / bbox.getLx();
- double scy = 0.9 * d.ly / bbox.getLy();
- double sc = std::min(scx, scy);
- double dx = (d.lx - bbox.getLx() * sc) * 0.5;
- double dy = (d.ly - bbox.getLy() * sc) * 0.5;
- TAffine aff =
- TScale(scx, scy) * TTranslation(-bbox.getP00() + TPointD(dx, dy));
+ double scx = 0.9 * d.lx / bbox.getLx();
+ double scy = 0.9 * d.ly / bbox.getLy();
+ double sc = std::min(scx, scy);
+ double dx = (d.lx - bbox.getLx() * sc) * 0.5;
+ double dy = (d.ly - bbox.getLy() * sc) * 0.5;
+ TAffine aff = TScale(sc) * TTranslation(-bbox.getP00() + TPointD(dx, dy));
checkErrorsByGL;
if (isRegionStyle() && !isStrokeStyle()) aff = aff * TTranslation(-10, -10);
@@ -388,7 +387,7 @@ class ColorStyleList { // singleton
public:
static ColorStyleList *instance() {
static ColorStyleList *_instance = 0;
- if (!_instance) _instance = new ColorStyleList();
+ if (!_instance) _instance = new ColorStyleList();
return _instance;
}
diff --git a/toonz/sources/include/toonzqt/colorfield.h b/toonz/sources/include/toonzqt/colorfield.h
index 4e44902..9148f26 100644
--- a/toonz/sources/include/toonzqt/colorfield.h
+++ b/toonz/sources/include/toonzqt/colorfield.h
@@ -37,6 +37,25 @@ class TPaletteHandle;
namespace DVGui {
//=============================================================================
+// CommonChessboard singleton
+//-----------------------------------------------------------------------------
+
+class DVAPI CommonChessboard final : public QObject {
+ Q_OBJECT
+ TRaster32P m_bgRas;
+ QPixmap m_bgPix;
+ void setChessboardColors(const TPixel32 &col1, const TPixel32 &col2);
+
+public:
+ CommonChessboard();
+
+ const QPixmap &getPixmap() { return m_bgPix; }
+ void update();
+
+ static CommonChessboard *instance();
+};
+
+//=============================================================================
// StyleSample
//-----------------------------------------------------------------------------
@@ -49,6 +68,10 @@ class DVAPI StyleSample final : public QWidget {
bool m_drawEnable;
TPixel m_chessColor1;
TPixel m_chessColor2;
+ bool m_cloneStyle;
+ bool m_sysChessboard;
+ bool m_stretch;
+ QColor m_currentColor;
bool m_isEditing;
@@ -58,7 +81,7 @@ public:
void enableClick(bool on) { m_clickEnabled = on; }
- void setStyle(TColorStyle &style);
+ void setStyle(TColorStyle &style, int colorParameterIndex);
TColorStyle *getStyle() const;
void setColor(const TPixel32 &color);
@@ -73,13 +96,16 @@ public:
void setEnable(bool drawEnable) { m_drawEnable = drawEnable; }
bool isEnable() const { return m_drawEnable; }
+ void setCloneStyle(bool enable) { m_cloneStyle = enable; }
+ void setSystemChessboard(bool enable) { m_sysChessboard = enable; }
+
protected:
void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *) override;
void mouseDoubleClickEvent(QMouseEvent *event) override;
signals:
- void clicked(const TColorStyle &style);
+ void clicked();
};
//=============================================================================
diff --git a/toonz/sources/include/toonzqt/styleeditor.h b/toonz/sources/include/toonzqt/styleeditor.h
index e4e93c6..346a738 100644
--- a/toonz/sources/include/toonzqt/styleeditor.h
+++ b/toonz/sources/include/toonzqt/styleeditor.h
@@ -74,6 +74,35 @@ class LutCalibrator;
//=============================================
+class HexLineEdit : public QLineEdit {
+ Q_OBJECT
+
+public:
+ HexLineEdit(const QString &contents, QWidget *parent);
+ ~HexLineEdit() {}
+
+ bool loadDefaultColorNames(bool reload);
+ bool hasUserColorNames();
+ bool loadUserColorNames(bool reload);
+ void setStyle(TColorStyle &style, int index);
+ void updateColor();
+ void setColor(TPixel color);
+ TPixel getColor() { return m_color; }
+ bool fromText(QString text);
+ bool fromHex(QString text);
+
+protected:
+ void loadColorTableXML(QMap &table, const TFilePath &fp);
+ void mousePressEvent(QMouseEvent *event) override;
+ void focusOutEvent(QFocusEvent *event) override;
+ void showEvent(QShowEvent *event) override;
+
+ bool m_editing;
+ TPixel m_color;
+ static QMap s_defcolornames; // make it shared
+ static QMap s_usercolornames; // ...
+};
+
//=============================================================================
namespace StyleEditorGUI {
//=============================================================================
@@ -238,14 +267,15 @@ signals:
//=============================================================================
/*! \brief The ColorSlider is used to set a color channel.
- Inherits \b QSlider.
+ Inherits \b QAbstractSlider.
This object show a bar which colors differ from minimum to
maximum channel color
value.
*/
-class DVAPI ColorSlider final : public QSlider {
+class DVAPI ColorSlider final : public QAbstractSlider {
Q_OBJECT
+
public:
ColorSlider(Qt::Orientation orientation, QWidget *parent = 0);
@@ -259,6 +289,9 @@ protected:
void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+
+ void chandleMouse(int x, int y);
// QIcon getFirstArrowIcon();
// QIcon getLastArrowIcon();
@@ -268,6 +301,11 @@ protected:
private:
ColorChannel m_channel;
ColorModel m_color;
+ static int s_chandle_size;
+ static int s_chandle_tall;
+
+public:
+ static int s_slider_appearance;
};
//=============================================================================
@@ -614,6 +652,7 @@ class DVAPI StyleEditor final : public QWidget, public SaveLoadQSettings {
PaletteController *m_paletteController;
TPaletteHandle *m_paletteHandle;
TPaletteHandle *m_cleanupPaletteHandle;
+ HexLineEdit *m_hexLineEdit;
QWidget *m_parent;
TXshLevelHandle
*m_levelHandle; //!< for clearing the level cache when the color changed
@@ -652,6 +691,8 @@ class DVAPI StyleEditor final : public QWidget, public SaveLoadQSettings {
QAction *m_hsvAction;
QAction *m_alphaAction;
QAction *m_rgbAction;
+ QAction *m_hexAction;
+ QActionGroup *m_sliderAppearanceAG;
TColorStyleP
m_oldStyle; //!< A copy of current style \a before the last change.
@@ -727,7 +768,8 @@ protected slots:
void onStyleSwitched();
void onStyleChanged(bool isDragging);
void onCleanupStyleChanged(bool isDragging);
- void onOldStyleClicked(const TColorStyle &);
+ void onOldStyleClicked();
+ void onNewStyleClicked();
void updateOrientationButton();
void checkPaletteLock();
// called (e.g.) by PaletteController when an other StyleEditor change the
@@ -752,10 +794,15 @@ protected slots:
void onParamStyleChanged(bool isDragging);
+ void onHexChanged();
+
void onSpecialButtonToggled(bool on);
void onCustomButtonToggled(bool on);
void onVectorBrushButtonToggled(bool on);
+ void onSliderAppearanceSelected(QAction *);
+ void onPopupMenuAboutToShow();
+
private:
QFrame *createBottomWidget();
QFrame *createVectorPage();
diff --git a/toonz/sources/toonz/preferencespopup.cpp b/toonz/sources/toonz/preferencespopup.cpp
index dda75ac..a655dc4 100644
--- a/toonz/sources/toonz/preferencespopup.cpp
+++ b/toonz/sources/toonz/preferencespopup.cpp
@@ -706,6 +706,12 @@ void PreferencesPopup::onTranspCheckDataChanged() { invalidateIcons(); }
//-----------------------------------------------------------------------------
+void PreferencesPopup::onChessboardChanged() {
+ CommonChessboard::instance()->update();
+}
+
+//-----------------------------------------------------------------------------
+
void PreferencesPopup::onSVNEnabledChanged() {
if (m_pref->getBoolValue(SVNEnabled)) {
if (!VersionControl::instance()->testSetup())
@@ -1173,7 +1179,8 @@ QString PreferencesPopup::getUIString(PreferencesItemId id) {
{ffmpegPath, tr("FFmpeg Path:")},
{ffmpegTimeout, tr("FFmpeg Timeout:")},
{fastRenderPath, tr("Fast Render Path:")},
- {ffmpegMultiThread, tr("Allow Multi-Thread in FFMPEG Rendering (UNSTABLE)")},
+ {ffmpegMultiThread,
+ tr("Allow Multi-Thread in FFMPEG Rendering (UNSTABLE)")},
// Drawing
{scanLevelType, tr("Scan File Format:")},
@@ -2043,6 +2050,10 @@ QWidget* PreferencesPopup::createColorsPage() {
&PreferencesPopup::notifySceneChanged);
m_onEditedFuncMap.insert(chessboardColor2,
&PreferencesPopup::notifySceneChanged);
+ m_onEditedFuncMap.insert(chessboardColor1,
+ &PreferencesPopup::onChessboardChanged);
+ m_onEditedFuncMap.insert(chessboardColor2,
+ &PreferencesPopup::onChessboardChanged);
return widget;
}
diff --git a/toonz/sources/toonz/preferencespopup.h b/toonz/sources/toonz/preferencespopup.h
index df95d9b..06d986c 100644
--- a/toonz/sources/toonz/preferencespopup.h
+++ b/toonz/sources/toonz/preferencespopup.h
@@ -147,6 +147,7 @@ private:
void onOnionColorChanged();
// Colors
void onTranspCheckDataChanged();
+ void onChessboardChanged();
// Version Control
void onSVNEnabledChanged();
// Commonly used
diff --git a/toonz/sources/toonzlib/mypaintbrushstyle.cpp b/toonz/sources/toonzlib/mypaintbrushstyle.cpp
index eecc712..a23a084 100644
--- a/toonz/sources/toonzlib/mypaintbrushstyle.cpp
+++ b/toonz/sources/toonzlib/mypaintbrushstyle.cpp
@@ -149,8 +149,8 @@ static std::string mybToVersion3(std::string origStr) {
outStr += " \"inputs\": {\n";
while (pipe != line.length()) {
if (startPos > 0) outStr += ",\n";
- startPos = pipe + 1;
- pipe = line.find("|", startPos);
+ startPos = pipe + 1;
+ pipe = line.find("|", startPos);
if (pipe == std::string::npos) pipe = line.length();
settingInfo = line.substr(startPos, pipe - startPos);
int firstCharPos = settingInfo.find_first_not_of(" ");
@@ -161,7 +161,7 @@ static std::string mybToVersion3(std::string origStr) {
baseValue = settingInfo.substr(firstCharPos, pipe - startPos);
int comma = baseValue.find(", ");
if (comma == std::string::npos) comma = baseValue.length();
- std::string value = baseValue.substr(0, comma);
+ std::string value = baseValue.substr(0, comma);
std::replace(value.begin(), value.end(), '(', '[');
std::replace(value.begin(), value.end(), ')', ']');
std::replace(value.begin(), value.end(), ' ', ',');
@@ -250,28 +250,43 @@ void TMyPaintBrushStyle::resetBaseValues() {
void TMyPaintBrushStyle::makeIcon(const TDimension &d) {
TFilePath path =
m_fullpath.getParentDir() + (m_fullpath.getWideName() + L"_prev.png");
+ TPointD offset(0, 0);
if (!m_preview) {
m_icon = TRaster32P(d);
m_icon->fill(TPixel32::Red);
} else if (m_preview->getSize() == d) {
m_icon = m_preview;
} else {
- m_icon = TRaster32P(d);
- double sx = (double)d.lx / (double)m_preview->getLx();
- double sy = (double)d.ly / (double)m_preview->getLy();
- TRop::resample(m_icon, m_preview, TScale(sx, sy));
+ m_icon = TRaster32P(d);
+ if (d.lx != d.ly) {
+ TPixel32 col = getMainColor();
+ if (col.m == 255)
+ m_icon->fill(col);
+ else {
+ TRaster32P fg(d);
+ fg->fill(premultiply(col));
+ TRop::checkBoard(m_icon, TPixel32::Black, TPixel32::White,
+ TDimensionD(6, 6), TPointD());
+ TRop::over(m_icon, fg);
+ }
+ }
+ double sx = (double)d.lx / (double)m_preview->getLx();
+ double sy = (double)d.ly / (double)m_preview->getLy();
+ double scale = std::min(sx, sy);
+ TRop::quickPut(m_icon, m_preview, TScale(scale));
}
// paint color marker
if (d.lx > 0 && d.ly > 0) {
- int size = std::min(1 + std::min(d.lx, d.ly) * 2 / 3,
+ int size = std::min(1 + std::min(d.lx, d.ly) * 2 / 3,
1 + std::max(d.lx, d.ly) / 2);
TPixel32 color = getMainColor();
+ color.m = 255; // show full opac color
for (int y = 0; y < size; ++y) {
- TPixel32 *p = m_icon->pixels(d.ly - y - 1);
- TPixel32 *endp = p + size - y - 1;
+ TPixel32 *p = m_icon->pixels(d.ly - y - 1);
+ TPixel32 *endp = p + size - y - 1;
for (; p != endp; ++p) *p = color;
- *p = blend(*p, color, 0.5);
+ *p = blend(*p, color, 0.5);
}
}
}
diff --git a/toonz/sources/toonzqt/Resources/h_chandle_arrow.svg b/toonz/sources/toonzqt/Resources/h_chandle_arrow.svg
new file mode 100644
index 0000000..34c1405
--- /dev/null
+++ b/toonz/sources/toonzqt/Resources/h_chandle_arrow.svg
@@ -0,0 +1,10 @@
+
+
+
diff --git a/toonz/sources/toonzqt/Resources/v_chandle_arrow.svg b/toonz/sources/toonzqt/Resources/v_chandle_arrow.svg
new file mode 100644
index 0000000..1863d86
--- /dev/null
+++ b/toonz/sources/toonzqt/Resources/v_chandle_arrow.svg
@@ -0,0 +1,10 @@
+
+
+
diff --git a/toonz/sources/toonzqt/colorfield.cpp b/toonz/sources/toonzqt/colorfield.cpp
index 52bc928..dfb4f53 100644
--- a/toonz/sources/toonzqt/colorfield.cpp
+++ b/toonz/sources/toonzqt/colorfield.cpp
@@ -48,6 +48,31 @@ QPixmap getIconPm(const QColor &color) {
} // namespace
//=============================================================================
+
+CommonChessboard *CommonChessboard::instance() {
+ static CommonChessboard _instance;
+ return &_instance;
+}
+
+CommonChessboard::CommonChessboard() : m_bgRas(40.0, 40.0) { update(); }
+
+void CommonChessboard::setChessboardColors(const TPixel32 &col1,
+ const TPixel32 &col2) {
+ TRop::checkBoard(m_bgRas, col1, col2,
+ TDimensionD(m_bgRas->getLx() / 8, m_bgRas->getLy() / 8),
+ TPointD(0, 0));
+ QImage img(m_bgRas->getRawData(), m_bgRas->getLx(), m_bgRas->getLy(),
+ QImage::Format_ARGB32);
+ m_bgPix = QPixmap::fromImage(img);
+}
+
+void CommonChessboard::update() {
+ TPixel32 col1, col2;
+ Preferences::instance()->getChessboardColors(col1, col2);
+ setChessboardColors(col1, col2);
+}
+
+//=============================================================================
/*! \class DVGui::StyleSample
\brief The StyleSample class provides to view a square color.
@@ -82,6 +107,8 @@ StyleSample::StyleSample(QWidget *parent, int sizeX, int sizeY)
, m_clickEnabled(false)
, m_chessColor1(0, 0, 0)
, m_chessColor2(255, 255, 255)
+ , m_sysChessboard(false)
+ , m_stretch(true)
, m_isEditing(false) {
setMinimumSize(sizeX, sizeY);
setColor(TPixel32::Transparent);
@@ -106,17 +133,39 @@ TColorStyle *StyleSample::getStyle() const { return m_style; }
/*! Update current square colore and, if click event is enable set current
StyleSample \b TColorStyle style to \b style.
*/
-void StyleSample::setStyle(TColorStyle &style) {
+void StyleSample::setStyle(TColorStyle &style, int colorParameterIndex) {
+ // Store current color
+ TPixel32 color = style.getColorParamValue(colorParameterIndex);
+ m_currentColor = QColor(color.r, color.g, color.b, color.m);
+ if (LutManager::instance()->isValid())
+ LutManager::instance()->convert(m_currentColor);
+
/*-- TSolidColorStyleの場合のみ、単色塗りつぶし --*/
- if (style.getTagId() == 3)
+ if (style.getTagId() == 3) {
setColor(style.getMainColor());
- else {
- TRaster32P icon =
- style.getIcon(qsize2Dimension(m_samplePixmap.rect().size()));
+ m_stretch = true;
+ } else {
+ TDimension iconDim(width(), height());
+
+ // obtain square icon for the TMyPaintBrushStyle
+ // so that the checkerboard color will become consistent with solido style
+ // when the main color is semi-transparent.
+ if (style.getTagId() == 4001) {
+ int d = std::min(width(), height());
+ iconDim = TDimension(d, d);
+ }
+
+ TRaster32P icon = style.getIcon(iconDim);
+ // TRaster32P icon =
+ // style.getIcon(qsize2Dimension(m_samplePixmap.rect().size()));
m_samplePixmap = rasterToQImage(icon, false); // modified in 6.2
+ m_stretch = false;
update();
}
- if (m_clickEnabled) m_style = style.clone();
+ if (m_cloneStyle) {
+ if (m_style) delete m_style; // avoid memory leak
+ m_style = style.clone();
+ }
}
//-----------------------------------------------------------------------------
@@ -149,10 +198,24 @@ void StyleSample::setChessboardColors(const TPixel32 &col1,
void StyleSample::paintEvent(QPaintEvent *event) {
if (!isEnable()) return;
QPainter painter(this);
- QImage img(m_bgRas->getRawData(), m_bgRas->getLx(), m_bgRas->getLy(),
- QImage::Format_ARGB32);
- painter.drawImage(0, 0, img.scaled(size()));
- painter.drawImage(0, 0, m_samplePixmap.scaled(size()));
+ if (m_sysChessboard) {
+ painter.drawTiledPixmap(rect(),
+ DVGui::CommonChessboard::instance()->getPixmap());
+ } else {
+ QImage img(m_bgRas->getRawData(), m_bgRas->getLx(), m_bgRas->getLy(),
+ QImage::Format_ARGB32);
+ painter.drawImage(0, 0, img.scaled(size()));
+ }
+ if (m_stretch) {
+ painter.drawImage(0, 0, m_samplePixmap.scaled(size()));
+ } else {
+ // put the icon on the left
+ int x = 0;
+ // int x = (width() - m_samplePixmap.width()) / 2;
+ int y = (height() - m_samplePixmap.height()) / 2;
+ painter.fillRect(rect(), m_currentColor);
+ painter.drawImage(x, y, m_samplePixmap);
+ }
if (m_isEditing) {
// QRect rect(0,0,m_bgRas->getLx(),m_bgRas->getLy());
painter.setPen(Qt::white);
@@ -168,8 +231,8 @@ void StyleSample::paintEvent(QPaintEvent *event) {
clicked(const TColorStyle &style).
*/
void StyleSample::mousePressEvent(QMouseEvent *event) {
- if (m_style && m_clickEnabled)
- emit clicked(*m_style);
+ if (m_clickEnabled)
+ emit clicked();
else
event->ignore();
}
@@ -771,7 +834,7 @@ CleanupColorField::CleanupColorField(QWidget *parent,
}
}
- m_colorSample->setStyle(*cleanupStyle);
+ m_colorSample->setStyle(*cleanupStyle, 0);
//---- layout
@@ -828,7 +891,7 @@ CleanupColorField::CleanupColorField(QWidget *parent,
void CleanupColorField::updateColor() {
if (m_cleanupStyle->canUpdate()) {
m_cleanupStyle->invalidateIcon();
- m_colorSample->setStyle(*m_cleanupStyle);
+ m_colorSample->setStyle(*m_cleanupStyle, 0);
m_brightnessChannel->setChannel(m_cleanupStyle->getBrightness());
if (m_cleanupStyle->isContrastEnabled())
@@ -860,7 +923,7 @@ void CleanupColorField::setColor(const TPixel32 &color) {
m_cleanupStyle->setMainColor(color);
m_cleanupStyle->invalidateIcon();
- m_colorSample->setStyle(*m_cleanupStyle);
+ m_colorSample->setStyle(*m_cleanupStyle, 0);
m_ph->notifyColorStyleChanged(false);
}
@@ -877,7 +940,7 @@ void CleanupColorField::setOutputColor(const TPixel32 &color) {
m_cleanupStyle->setColorParamValue(1, color);
m_cleanupStyle->invalidateIcon();
- m_colorSample->setStyle(*m_cleanupStyle);
+ m_colorSample->setStyle(*m_cleanupStyle, 0);
m_ph->notifyColorStyleChanged();
}
@@ -891,7 +954,7 @@ void CleanupColorField::setStyle(TColorStyle *style) {
m_cleanupStyle->setMainColor(style->getMainColor());
m_cleanupStyle->setColorParamValue(1, style->getColorParamValue(1));
m_cleanupStyle->invalidateIcon();
- m_colorSample->setStyle(*m_cleanupStyle);
+ m_colorSample->setStyle(*m_cleanupStyle, 0);
m_ph->notifyColorStyleChanged();
}
diff --git a/toonz/sources/toonzqt/styleeditor.cpp b/toonz/sources/toonzqt/styleeditor.cpp
index 78334a9..9953396 100644
--- a/toonz/sources/toonzqt/styleeditor.cpp
+++ b/toonz/sources/toonzqt/styleeditor.cpp
@@ -37,6 +37,7 @@
#include "tvectorrenderdata.h"
#include "tsimplecolorstyles.h"
#include "tvectorbrushstyle.h"
+#include "tenv.h"
// Qt includes
#include
@@ -58,9 +59,224 @@
#include
#include
+namespace {
+enum ColorSliderAppearance {
+ RelativeColoredTriangleHandle,
+ AbsoluteColoredLineHandle
+};
+}
+TEnv::IntVar StyleEditorColorSliderAppearance(
+ "StyleEditorColorSliderAppearance", RelativeColoredTriangleHandle);
+
using namespace StyleEditorGUI;
//*****************************************************************************
+// Hex line editor
+//*****************************************************************************
+
+#define COLORNAMES_FILE "colornames.txt"
+
+QMap HexLineEdit::s_defcolornames;
+QMap HexLineEdit::s_usercolornames;
+
+HexLineEdit::HexLineEdit(const QString &contents, QWidget *parent)
+ : QLineEdit(contents, parent), m_editing(false), m_color(0, 0, 0) {}
+
+bool HexLineEdit::loadDefaultColorNames(bool reload) {
+ TFilePath defCTFp = TEnv::getConfigDir() + COLORNAMES_FILE;
+
+ // Load default color names
+ try {
+ if (reload || s_defcolornames.size() == 0) {
+ s_defcolornames.clear();
+ loadColorTableXML(s_defcolornames, defCTFp);
+ }
+ } catch (...) {
+ return false;
+ }
+ return true;
+}
+
+bool HexLineEdit::hasUserColorNames() {
+ TFilePath userCTFp = ToonzFolder::getMyModuleDir() + COLORNAMES_FILE;
+ return TFileStatus(userCTFp).doesExist();
+}
+
+bool HexLineEdit::loadUserColorNames(bool reload) {
+ TFilePath userCTFp = ToonzFolder::getMyModuleDir() + COLORNAMES_FILE;
+
+ // Load user color names (if exists...)
+ if (TFileStatus(userCTFp).doesExist()) {
+ try {
+ if (reload || s_usercolornames.size() == 0) {
+ s_usercolornames.clear();
+ loadColorTableXML(s_usercolornames, userCTFp);
+ }
+ } catch (...) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void HexLineEdit::updateColor() {
+ if (m_color.m == 255) {
+ // Opaque, omit alpha
+ setText(QString("#%1%2%3")
+ .arg(m_color.r, 2, 16, QLatin1Char('0'))
+ .arg(m_color.g, 2, 16, QLatin1Char('0'))
+ .arg(m_color.b, 2, 16, QLatin1Char('0'))
+ .toUpper());
+ } else {
+ setText(QString("#%1%2%3%4")
+ .arg(m_color.r, 2, 16, QLatin1Char('0'))
+ .arg(m_color.g, 2, 16, QLatin1Char('0'))
+ .arg(m_color.b, 2, 16, QLatin1Char('0'))
+ .arg(m_color.m, 2, 16, QLatin1Char('0'))
+ .toUpper());
+ }
+}
+
+void HexLineEdit::setColor(TPixel color) {
+ if (m_color != color) {
+ m_color = color;
+ if (isVisible()) updateColor();
+ }
+}
+
+bool HexLineEdit::fromText(QString text) {
+ static QRegExp space("\\s");
+ text.remove(space);
+ if (text.size() == 0) return false;
+ if (text[0] == "#") return fromHex(text);
+ text = text.toLower(); // table names are lowercase
+
+ // Find color from tables, user takes priority
+ QMap::const_iterator it;
+ it = s_usercolornames.constFind(text);
+ if (it == s_usercolornames.constEnd()) {
+ it = s_defcolornames.constFind(text);
+ if (it == s_defcolornames.constEnd()) return false;
+ }
+
+ QString hexText = it.value();
+ return fromHex(hexText);
+}
+
+// Whitespaces can break this implementation, thankfully
+// '.fromText' already took care of it.
+bool HexLineEdit::fromHex(QString text) {
+ if (text.size() == 0) return false;
+ if (text[0] != "#") return false;
+ text.remove(0, 1);
+ bool ok;
+ uint parsedValue = text.toUInt(&ok, 16);
+ if (!ok) return false;
+
+ switch (text.length()) {
+ case 8: // #RRGGBBAA
+ m_color.r = parsedValue >> 24;
+ m_color.g = parsedValue >> 16;
+ m_color.b = parsedValue >> 8;
+ m_color.m = parsedValue;
+ break;
+ case 6: // #RRGGBB
+ m_color.r = parsedValue >> 16;
+ m_color.g = parsedValue >> 8;
+ m_color.b = parsedValue;
+ m_color.m = 255;
+ break;
+ case 4: // #RGBA
+ m_color.r = (parsedValue >> 12) & 15;
+ m_color.r |= m_color.r << 4;
+ m_color.g = (parsedValue >> 8) & 15;
+ m_color.g |= m_color.g << 4;
+ m_color.b = (parsedValue >> 4) & 15;
+ m_color.b |= m_color.b << 4;
+ m_color.m = parsedValue & 15;
+ m_color.m |= m_color.m << 4;
+ break;
+ case 3: // #RGB
+ m_color.r = (parsedValue >> 8) & 15;
+ m_color.r |= m_color.r << 4;
+ m_color.g = (parsedValue >> 4) & 15;
+ m_color.g |= m_color.g << 4;
+ m_color.b = parsedValue & 15;
+ m_color.b |= m_color.b << 4;
+ m_color.m = 255;
+ break;
+ case 2: // #VV (non-standard)
+ m_color.r = parsedValue;
+ m_color.g = m_color.r;
+ m_color.b = m_color.r;
+ m_color.m = 255;
+ break;
+ case 1: // #V (non-standard)
+ m_color.r = parsedValue & 15;
+ m_color.r |= m_color.r << 4;
+ m_color.g = m_color.r;
+ m_color.b = m_color.r;
+ m_color.m = 255;
+ break;
+ default:
+ return false;
+ }
+ updateColor();
+ return true;
+}
+
+void HexLineEdit::loadColorTableXML(QMap &table,
+ const TFilePath &fp) {
+ if (!TFileStatus(fp).doesExist()) throw TException("File not found");
+
+ TIStream is(fp);
+ if (!is) throw TException("Can't read color names");
+
+ std::string tagName;
+ if (!is.matchTag(tagName) || tagName != "colors")
+ throw TException("Not a color names file");
+
+ while (!is.matchEndTag()) {
+ if (!is.matchTag(tagName)) throw TException("Expected tag");
+ if (tagName == "color") {
+ QString name, hex;
+ name = QString::fromStdString(is.getTagAttribute("name"));
+ std::string hexs;
+ is >> hexs;
+ hex = QString::fromStdString(hexs);
+ if (name.size() != 0 && hex.size() != 0)
+ table.insert(name.toLower(), hex);
+ if (!is.matchEndTag()) throw TException("Expected end tag");
+ } else
+ throw TException("unexpected tag /" + tagName + "/");
+ }
+}
+
+void HexLineEdit::setStyle(TColorStyle &style, int index) {
+ setColor(style.getColorParamValue(index));
+}
+
+void HexLineEdit::mousePressEvent(QMouseEvent *event) {
+ QLineEdit::mousePressEvent(event);
+ // Make Ctrl key disable select all so the user can click a specific character
+ // after a focus-in, this likely will fall into a hidden feature thought.
+ bool ctrlDown = event->modifiers() & Qt::ControlModifier;
+ if (!m_editing && !ctrlDown) selectAll();
+ m_editing = true;
+}
+
+void HexLineEdit::focusOutEvent(QFocusEvent *event) {
+ QLineEdit::focusOutEvent(event);
+ deselect();
+ m_editing = false;
+}
+
+void HexLineEdit::showEvent(QShowEvent *event) {
+ QLineEdit::showEvent(event);
+ updateColor();
+}
+
+//*****************************************************************************
// UndoPaletteChange definition
//*****************************************************************************
@@ -474,24 +690,26 @@ QPixmap makeLinearShading(const ShadeMaker &shadeMaker, int size,
QPixmap makeLinearShading(const ColorModel &color, ColorChannel channel,
int size, bool isVertical) {
+ bool relative =
+ ColorSlider::s_slider_appearance == RelativeColoredTriangleHandle;
switch (channel) {
case eRed:
- if (isVertical)
+ if (isVertical || relative)
return makeLinearShading(RedShadeMaker(color), size, isVertical);
else
return QPixmap(":Resources/grad_r.png").scaled(size, 1);
case eGreen:
- if (isVertical)
+ if (isVertical || relative)
return makeLinearShading(GreenShadeMaker(color), size, isVertical);
else
return QPixmap(":Resources/grad_g.png").scaled(size, 1);
case eBlue:
- if (isVertical)
+ if (isVertical || relative)
return makeLinearShading(BlueShadeMaker(color), size, isVertical);
else
return QPixmap(":Resources/grad_b.png").scaled(size, 1);
case eAlpha:
- if (isVertical)
+ if (isVertical || relative)
return makeLinearShading(AlphaShadeMaker(color), size, isVertical);
else
return QPixmap(":Resources/grad_m.png").scaled(size, 1);
@@ -579,6 +797,13 @@ HexagonalColorWheel::~HexagonalColorWheel() {
void HexagonalColorWheel::updateColorCalibration() {
if (Preferences::instance()->isColorCalibrationEnabled()) {
+ // prevent to initialize LutCalibrator before this instance is initialized
+ // or OT may crash due to missing OpenGL context
+ if (m_firstInitialized) {
+ cueCalibrationUpdate();
+ return;
+ }
+
makeCurrent();
if (!m_lutCalibrator)
m_lutCalibrator = new LutCalibrator();
@@ -981,8 +1206,13 @@ void SquaredColorWheel::setChannel(int channel) {
// ColorSlider implementation
//*****************************************************************************
+// Adquire size later...
+int ColorSlider::s_chandle_size = -1;
+int ColorSlider::s_chandle_tall = -1;
+int ColorSlider::s_slider_appearance = -1;
+
ColorSlider::ColorSlider(Qt::Orientation orientation, QWidget *parent)
- : QSlider(orientation, parent), m_channel(eRed), m_color() {
+ : QAbstractSlider(parent), m_channel(eRed), m_color() {
setFocusPolicy(Qt::NoFocus);
setOrientation(orientation);
@@ -992,6 +1222,14 @@ ColorSlider::ColorSlider(Qt::Orientation orientation, QWidget *parent)
setMinimumHeight(7);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ // Get color handle size once
+ if (s_chandle_size == -1) {
+ QImage chandle = QImage(":Resources/h_chandle_arrow.svg");
+ s_chandle_size = chandle.width();
+ s_chandle_tall = chandle.height();
+ s_slider_appearance = StyleEditorColorSliderAppearance;
+ }
+
// Attenzione: necessario per poter individuare l'oggetto nel file di
// definizione dello stile
setObjectName("colorSlider");
@@ -1020,19 +1258,34 @@ void ColorSlider::paintEvent(QPaintEvent *event) {
int h = height();
bool isVertical = orientation() == Qt::Vertical;
+ bool isLineHandle =
+ ColorSlider::s_slider_appearance == AbsoluteColoredLineHandle;
- if (!isVertical) h -= 5;
+ if (isVertical) {
+ y += s_chandle_size / 2;
+ h -= s_chandle_size;
+ w -= 3;
+ } else {
+ x += s_chandle_size / 2;
+ w -= s_chandle_size;
+ h -= 3;
+ if (isLineHandle) {
+ y += 1;
+ h -= 2;
+ }
+ }
+ if (w < 2 || h < 2) return;
QPixmap bgPixmap =
makeLinearShading(m_color, m_channel, isVertical ? h : w, isVertical);
if (m_channel == eAlpha) {
- static QPixmap checkboard(":Resources/backg.png");
- p.drawTiledPixmap(x, y + 1, w, h, checkboard);
+ p.drawTiledPixmap(x, y, w, h,
+ DVGui::CommonChessboard::instance()->getPixmap());
}
if (!bgPixmap.isNull()) {
- p.drawTiledPixmap(x, y + 1, w, h, bgPixmap);
+ p.drawTiledPixmap(x, y, w, h, bgPixmap);
}
/*!
@@ -1040,59 +1293,34 @@ void ColorSlider::paintEvent(QPaintEvent *event) {
In this case we draw "manually" the slider handle at correct position
*/
if (isVertical) {
- int pos = QStyle::sliderPositionFromValue(minimum(), maximum(), value(),
- h - 9, true);
- static QPixmap vHandlePixmap(":Resources/v_chandle.png");
- p.drawPixmap(0, pos, vHandlePixmap);
+ static QPixmap vHandlePixmap =
+ svgToPixmap(":Resources/v_chandle_arrow.svg");
+ int pos = QStyle::sliderPositionFromValue(0, maximum(), value(), h, true);
+ p.drawPixmap(width() - s_chandle_tall, pos, vHandlePixmap);
} else {
- static QPixmap hHandleUpPm(":Resources/h_chandleUp.png");
- static QPixmap hHandleDownPm(":Resources/h_chandleDown.png");
- static QPixmap hHandleCenterPm(":Resources/h_chandleCenter.png");
- int pos = QStyle::sliderPositionFromValue(
- 0, maximum(), value(), width() - hHandleCenterPm.width(), false);
- p.drawPixmap(pos, 0, hHandleUpPm);
- p.drawPixmap(pos, height() - hHandleDownPm.height(), hHandleDownPm);
- p.drawPixmap(pos, hHandleUpPm.height(), hHandleCenterPm.width(),
- height() - hHandleUpPm.height() - hHandleDownPm.height(),
- hHandleCenterPm);
+ int pos = QStyle::sliderPositionFromValue(0, maximum(), value(), w, false);
+ if (isLineHandle) {
+ static QPixmap hHandleUpPm(":Resources/h_chandleUp.png");
+ static QPixmap hHandleDownPm(":Resources/h_chandleDown.png");
+ static QPixmap hHandleCenterPm(":Resources/h_chandleCenter.png");
+ int linePos = pos + (s_chandle_size - hHandleCenterPm.width()) / 2;
+ p.drawPixmap(linePos, 0, hHandleUpPm);
+ p.drawPixmap(linePos, height() - hHandleDownPm.height(), hHandleDownPm);
+ p.drawPixmap(linePos, hHandleUpPm.height(), hHandleCenterPm.width(),
+ height() - hHandleUpPm.height() - hHandleDownPm.height(),
+ hHandleCenterPm);
+ } else {
+ static QPixmap hHandlePixmap =
+ svgToPixmap(":Resources/h_chandle_arrow.svg");
+ p.drawPixmap(pos, height() - s_chandle_tall, hHandlePixmap);
+ }
}
};
//-----------------------------------------------------------------------------
void ColorSlider::mousePressEvent(QMouseEvent *event) {
- // vogliamo che facendo click sullo slider, lontano dall'handle
- // l'handle salti subito nella posizione giusta invece di far partire
- // l'autorepeat.
- //
- // cfr. qslider.cpp:429: sembra che questo comportamento si possa ottenere
- // anche con SH_Slider_AbsoluteSetButtons. Ma non capisco come si possa fare
- // per definire quest hint
- QStyleOptionSlider opt;
- initStyleOption(&opt);
- const QRect handleRect = style()->subControlRect(
- QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
- if (!handleRect.contains(event->pos())) {
- const QPoint handleCenter = handleRect.center();
- const QRect grooveRect = style()->subControlRect(
- QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this);
- int pos, span;
- bool upsideDown = false;
- if (opt.orientation == Qt::Vertical) {
- upsideDown = true;
- int handleSize = handleRect.height();
- pos = event->pos().y() - handleSize / 2;
- span = grooveRect.height() - handleSize;
- } else {
- int handleSize = QPixmap(":Resources/h_chandleCenter.png").width();
- pos = event->pos().x() - handleSize / 2;
- span = grooveRect.width() - handleSize;
- }
- int value = QStyle::sliderValueFromPosition(minimum(), maximum(), pos, span,
- upsideDown);
- setValue(value);
- }
- QSlider::mousePressEvent(event);
+ chandleMouse(event->pos().x(), event->pos().y());
}
//-----------------------------------------------------------------------------
@@ -1101,6 +1329,26 @@ void ColorSlider::mouseReleaseEvent(QMouseEvent *event) {
emit sliderReleased();
}
+//-----------------------------------------------------------------------------
+
+void ColorSlider::mouseMoveEvent(QMouseEvent *event) {
+ chandleMouse(event->pos().x(), event->pos().y());
+}
+
+//-----------------------------------------------------------------------------
+
+void ColorSlider::chandleMouse(int mouse_x, int mouse_y) {
+ if (orientation() == Qt::Vertical) {
+ int pos = mouse_y - s_chandle_size / 2;
+ int span = height() - s_chandle_size;
+ setValue(QStyle::sliderValueFromPosition(0, maximum(), pos, span, true));
+ } else {
+ int pos = mouse_x - s_chandle_size / 2;
+ int span = width() - s_chandle_size;
+ setValue(QStyle::sliderValueFromPosition(0, maximum(), pos, span, false));
+ }
+}
+
//*****************************************************************************
// ArrowButton implementation
//*****************************************************************************
@@ -1425,7 +1673,7 @@ StyleEditorPage::StyleEditorPage(QWidget *parent) : QFrame(parent) {
ColorParameterSelector::ColorParameterSelector(QWidget *parent)
: QWidget(parent)
- , m_index(-1)
+ , m_index(0)
, m_chipSize(21, 21)
, m_chipOrigin(0, 1)
, m_chipDelta(21, 0) {
@@ -1463,6 +1711,7 @@ void ColorParameterSelector::setStyle(const TColorStyle &style) {
clear();
return;
}
+ show();
if (m_colors.size() != count) {
m_index = 0;
m_colors.resize(count);
@@ -1479,8 +1728,12 @@ void ColorParameterSelector::setStyle(const TColorStyle &style) {
void ColorParameterSelector::clear() {
if (m_colors.size() != 0) m_colors.clear();
- m_index = -1;
- update();
+ m_index = 0;
+ if (isVisible()) {
+ hide();
+ update();
+ qApp->processEvents();
+ }
}
//-----------------------------------------------------------------------------
@@ -1490,7 +1743,7 @@ void ColorParameterSelector::mousePressEvent(QMouseEvent *event) {
int index = pos.x() / m_chipDelta.x();
QRect chipRect(index * m_chipDelta, m_chipSize);
if (chipRect.contains(pos)) {
- m_index = index;
+ if (index < m_colors.size()) m_index = index;
emit colorParamChanged();
update();
}
@@ -2391,7 +2644,7 @@ void SpecialStyleChooserPage::loadItems() {
tagId == 2000 || // imagepattern
tagId == 2800 || // imagepattern
tagId == 2001 || // cleanup
- tagId == 2002 || // ??
+ tagId == 2002 || // black cleanup
tagId == 3000 || // vector brush
tagId == 4001 // mypaint brush
)
@@ -3002,50 +3255,6 @@ StyleEditor::StyleEditor(PaletteController *paletteController, QWidget *parent)
m_styleChooser->setFocusPolicy(Qt::NoFocus);
QFrame *bottomWidget = createBottomWidget();
-
- m_toolBar = new QToolBar(this);
- m_toolBar->setMovable(false);
- m_toolBar->setMaximumHeight(22);
- m_toolBar->addWidget(m_colorParameterSelector);
-
- QMenu *menu = new QMenu();
- m_wheelAction = new QAction(tr("Wheel"), this);
- m_hsvAction = new QAction(tr("HSV"), this);
- m_alphaAction = new QAction(tr("Alpha"), this);
- m_rgbAction = new QAction(tr("RGB"), this);
-
- m_wheelAction->setCheckable(true);
- m_hsvAction->setCheckable(true);
- m_alphaAction->setCheckable(true);
- m_rgbAction->setCheckable(true);
- m_wheelAction->setChecked(true);
- m_hsvAction->setChecked(true);
- m_alphaAction->setChecked(true);
- m_rgbAction->setChecked(true);
- menu->addAction(m_wheelAction);
- menu->addAction(m_hsvAction);
- menu->addAction(m_alphaAction);
- menu->addAction(m_rgbAction);
-
- QToolButton *toolButton = new QToolButton(this);
- toolButton->setIcon(createQIcon("menu"));
- toolButton->setFixedSize(22, 22);
- toolButton->setMenu(menu);
- toolButton->setPopupMode(QToolButton::InstantPopup);
- toolButton->setToolTip(tr("Show or hide parts of the Color Page."));
- QToolBar *displayToolbar = new QToolBar(this);
- m_toggleOrientationAction =
- displayToolbar->addAction(createQIcon("orientation_h"), "");
- m_toggleOrientationAction->setToolTip(
- tr("Toggle orientation of the Color Page."));
- QWidget *toggleOrientationButton =
- displayToolbar->widgetForAction(m_toggleOrientationAction);
- toggleOrientationButton->setFixedSize(22, 22);
- toggleOrientationButton->setFocusPolicy(Qt::NoFocus);
- displayToolbar->addWidget(toolButton);
- displayToolbar->setMaximumHeight(22);
- displayToolbar->setIconSize(QSize(16, 16));
-
/* ------- layout ------- */
QGridLayout *mainLayout = new QGridLayout;
mainLayout->setMargin(0);
@@ -3063,8 +3272,8 @@ StyleEditor::StyleEditor(PaletteController *paletteController, QWidget *parent)
mainLayout->addWidget(m_tabBarContainer, 0, 0, 1, 2);
mainLayout->addWidget(m_styleChooser, 1, 0, 1, 2);
mainLayout->addWidget(bottomWidget, 2, 0, 1, 2);
- mainLayout->addWidget(m_toolBar, 3, 0);
- mainLayout->addWidget(displayToolbar, 3, 1);
+ // mainLayout->addWidget(m_toolBar, 3, 0);
+ // mainLayout->addWidget(displayToolbar, 3, 1);
}
mainLayout->setColumnStretch(0, 1);
mainLayout->setRowStretch(1, 1);
@@ -3097,19 +3306,6 @@ StyleEditor::StyleEditor(PaletteController *paletteController, QWidget *parent)
ret = ret && connect(m_plainColorPage,
SIGNAL(colorChanged(const ColorModel &, bool)), this,
SLOT(onColorChanged(const ColorModel &, bool)));
-
- ret = ret && connect(m_wheelAction, SIGNAL(toggled(bool)),
- m_plainColorPage->m_wheelFrame, SLOT(setVisible(bool)));
- ret = ret && connect(m_hsvAction, SIGNAL(toggled(bool)),
- m_plainColorPage->m_hsvFrame, SLOT(setVisible(bool)));
- ret = ret && connect(m_alphaAction, SIGNAL(toggled(bool)),
- m_plainColorPage->m_alphaFrame, SLOT(setVisible(bool)));
- ret = ret && connect(m_rgbAction, SIGNAL(toggled(bool)),
- m_plainColorPage->m_rgbFrame, SLOT(setVisible(bool)));
- ret = ret && connect(m_toggleOrientationAction, SIGNAL(triggered()),
- m_plainColorPage, SLOT(toggleOrientation()));
- ret = ret && connect(m_toggleOrientationAction, SIGNAL(triggered()), this,
- SLOT(updateOrientationButton()));
assert(ret);
/* ------- initial conditions ------- */
enable(false, false, false);
@@ -3135,13 +3331,14 @@ void StyleEditor::setPaletteHandle(TPaletteHandle* paletteHandle)
QFrame *StyleEditor::createBottomWidget() {
QFrame *bottomWidget = new QFrame(this);
m_autoButton = new QPushButton(tr("Auto"));
- m_oldColor = new DVGui::StyleSample(this, 42, 20);
- m_newColor = new DVGui::StyleSample(this, 42, 20);
+ m_oldColor = new DVGui::StyleSample(this, 42, 24);
+ m_newColor = new DVGui::StyleSample(this, 42, 24);
m_applyButton = new QPushButton(tr("Apply"));
bottomWidget->setFrameStyle(QFrame::StyledPanel);
bottomWidget->setObjectName("bottomWidget");
bottomWidget->setContentsMargins(0, 0, 0, 0);
+ bottomWidget->setMinimumHeight(60);
m_applyButton->setToolTip(tr("Apply changes to current style"));
m_applyButton->setDisabled(m_paletteController->isColorAutoApplyEnabled());
m_applyButton->setFocusPolicy(Qt::NoFocus);
@@ -3154,31 +3351,120 @@ QFrame *StyleEditor::createBottomWidget() {
m_oldColor->setToolTip(tr("Return To Previous Style"));
m_oldColor->enableClick(true);
m_oldColor->setEnable(false);
+ m_oldColor->setSystemChessboard(true);
+ m_oldColor->setCloneStyle(true);
m_newColor->setToolTip(tr("Current Style"));
+ m_newColor->enableClick(true);
m_newColor->setEnable(false);
+ m_newColor->setSystemChessboard(true);
+
+ m_hexLineEdit = new HexLineEdit("", this);
+ m_hexLineEdit->setObjectName("HexLineEdit");
+ m_hexLineEdit->setFixedWidth(75);
+ m_hexLineEdit->loadDefaultColorNames(false);
+ m_hexLineEdit->loadUserColorNames(false);
+
+ m_toolBar = new QToolBar(this);
+ m_toolBar->setMovable(false);
+ m_toolBar->setMaximumHeight(22);
+ QMenu *menu = new QMenu();
+ m_wheelAction = new QAction(tr("Wheel"), this);
+ m_hsvAction = new QAction(tr("HSV"), this);
+ m_alphaAction = new QAction(tr("Alpha"), this);
+ m_rgbAction = new QAction(tr("RGB"), this);
+ m_hexAction = new QAction(tr("Hex"), this);
+
+ m_wheelAction->setCheckable(true);
+ m_hsvAction->setCheckable(true);
+ m_alphaAction->setCheckable(true);
+ m_rgbAction->setCheckable(true);
+ m_hexAction->setCheckable(true);
+ m_wheelAction->setChecked(true);
+ m_hsvAction->setChecked(true);
+ m_alphaAction->setChecked(true);
+ m_rgbAction->setChecked(true);
+ m_hexAction->setChecked(false);
+ menu->addAction(m_wheelAction);
+ menu->addAction(m_hsvAction);
+ menu->addAction(m_alphaAction);
+ menu->addAction(m_rgbAction);
+ menu->addAction(m_hexAction);
+
+ m_sliderAppearanceAG = new QActionGroup(this);
+ QAction *relColorAct =
+ new QAction(tr("Relative colored + Triangle handle"), this);
+ QAction *absColorAct =
+ new QAction(tr("Absolute colored + Line handle"), this);
+ relColorAct->setData(RelativeColoredTriangleHandle);
+ absColorAct->setData(AbsoluteColoredLineHandle);
+ relColorAct->setCheckable(true);
+ absColorAct->setCheckable(true);
+ if (StyleEditorColorSliderAppearance == RelativeColoredTriangleHandle)
+ relColorAct->setChecked(true);
+ else
+ absColorAct->setChecked(true);
+ m_sliderAppearanceAG->addAction(relColorAct);
+ m_sliderAppearanceAG->addAction(absColorAct);
+ m_sliderAppearanceAG->setExclusive(true);
+ menu->addSeparator();
+ QMenu *appearanceSubMenu = menu->addMenu(tr("Slider Appearance"));
+ appearanceSubMenu->addAction(relColorAct);
+ appearanceSubMenu->addAction(absColorAct);
+ QToolButton *toolButton = new QToolButton(this);
+ toolButton->setIcon(createQIcon("menu"));
+ toolButton->setFixedSize(22, 22);
+ toolButton->setMenu(menu);
+ toolButton->setPopupMode(QToolButton::InstantPopup);
+ toolButton->setToolTip(tr("Show or hide parts of the Color Page."));
+ // QToolBar* displayToolbar = new QToolBar(this);
+ m_toggleOrientationAction =
+ m_toolBar->addAction(createQIcon("orientation_h"), "");
+ m_toggleOrientationAction->setToolTip(
+ tr("Toggle orientation of the Color Page."));
+ QWidget *toggleOrientationButton =
+ m_toolBar->widgetForAction(m_toggleOrientationAction);
+ toggleOrientationButton->setFixedSize(22, 22);
+ toggleOrientationButton->setFocusPolicy(Qt::NoFocus);
+ m_toolBar->addWidget(toolButton);
+ m_toolBar->setMaximumHeight(22);
+ m_toolBar->setIconSize(QSize(16, 16));
/* ------ layout ------ */
- QVBoxLayout *mainLayout = new QVBoxLayout;
+ QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->setMargin(2);
- mainLayout->setSpacing(1);
+ mainLayout->setSpacing(0);
{
- QHBoxLayout *hLayout = new QHBoxLayout;
- hLayout->setMargin(0);
- hLayout->setSpacing(0);
+ mainLayout->addWidget(m_autoButton);
+ mainLayout->addSpacing(4);
+ mainLayout->addWidget(m_applyButton);
+ mainLayout->addSpacing(4);
+
+ QVBoxLayout *colorLay = new QVBoxLayout();
+ colorLay->setMargin(0);
+ colorLay->setSpacing(2);
{
- hLayout->addWidget(m_autoButton);
- hLayout->addWidget(m_applyButton);
- hLayout->addSpacing(2);
- hLayout->addWidget(m_newColor, 1);
- hLayout->addWidget(m_oldColor, 1);
+ QHBoxLayout *chipLay = new QHBoxLayout();
+ chipLay->setMargin(0);
+ chipLay->setSpacing(0);
+ {
+ chipLay->addWidget(m_newColor, 1);
+ chipLay->addWidget(m_oldColor, 1);
+ }
+ colorLay->addLayout(chipLay, 1);
+
+ colorLay->addWidget(m_colorParameterSelector, 0);
}
- mainLayout->addLayout(hLayout);
+ mainLayout->addLayout(colorLay, 1);
+ mainLayout->addSpacing(4);
- // QHBoxLayout *buttonsLayout = new QHBoxLayout;
- // buttonsLayout->setMargin(0);
- // buttonsLayout->setSpacing(5);
- //{ buttonsLayout->addWidget(m_applyButton); }
- // mainLayout->addLayout(buttonsLayout);
+ QVBoxLayout *hexLay = new QVBoxLayout();
+ hexLay->setMargin(0);
+ hexLay->setSpacing(2);
+ {
+ hexLay->addWidget(m_hexLineEdit);
+ hexLay->addWidget(m_toolBar, 0, Qt::AlignBottom | Qt::AlignRight);
+ }
+ mainLayout->addLayout(hexLay, 0);
}
bottomWidget->setLayout(mainLayout);
@@ -3188,8 +3474,30 @@ QFrame *StyleEditor::createBottomWidget() {
SLOT(applyButtonClicked()));
ret = ret && connect(m_autoButton, SIGNAL(toggled(bool)), this,
SLOT(autoCheckChanged(bool)));
- ret = ret && connect(m_oldColor, SIGNAL(clicked(const TColorStyle &)), this,
- SLOT(onOldStyleClicked(const TColorStyle &)));
+ ret = ret &&
+ connect(m_oldColor, SIGNAL(clicked()), this, SLOT(onOldStyleClicked()));
+ ret = ret &&
+ connect(m_newColor, SIGNAL(clicked()), this, SLOT(onNewStyleClicked()));
+ ret = ret && connect(m_wheelAction, SIGNAL(toggled(bool)),
+ m_plainColorPage->m_wheelFrame, SLOT(setVisible(bool)));
+ ret = ret && connect(m_hsvAction, SIGNAL(toggled(bool)),
+ m_plainColorPage->m_hsvFrame, SLOT(setVisible(bool)));
+ ret = ret && connect(m_alphaAction, SIGNAL(toggled(bool)),
+ m_plainColorPage->m_alphaFrame, SLOT(setVisible(bool)));
+ ret = ret && connect(m_rgbAction, SIGNAL(toggled(bool)),
+ m_plainColorPage->m_rgbFrame, SLOT(setVisible(bool)));
+ ret = ret && connect(m_hexAction, SIGNAL(toggled(bool)), m_hexLineEdit,
+ SLOT(setVisible(bool)));
+ ret = ret && connect(m_hexLineEdit, SIGNAL(editingFinished()), this,
+ SLOT(onHexChanged()));
+ ret = ret && connect(m_toggleOrientationAction, SIGNAL(triggered()),
+ m_plainColorPage, SLOT(toggleOrientation()));
+ ret = ret && connect(m_toggleOrientationAction, SIGNAL(triggered()), this,
+ SLOT(updateOrientationButton()));
+ ret = ret && connect(m_sliderAppearanceAG, SIGNAL(triggered(QAction *)), this,
+ SLOT(onSliderAppearanceSelected(QAction *)));
+ ret = ret && connect(menu, SIGNAL(aboutToShow()), this,
+ SLOT(onPopupMenuAboutToShow()));
assert(ret);
return bottomWidget;
@@ -3308,6 +3616,7 @@ void StyleEditor::showEvent(QShowEvent *) {
m_plainColorPage->m_hsvFrame->setVisible(m_hsvAction->isChecked());
m_plainColorPage->m_alphaFrame->setVisible(m_alphaAction->isChecked());
m_plainColorPage->m_rgbFrame->setVisible(m_rgbAction->isChecked());
+ m_hexLineEdit->setVisible(m_hexAction->isChecked());
updateOrientationButton();
assert(ret);
}
@@ -3404,9 +3713,11 @@ void StyleEditor::onStyleChanged(bool isDragging) {
m_plainColorPage->setColor(*m_editedStyle, getColorParam());
m_colorParameterSelector->setStyle(*m_editedStyle);
m_settingsPage->setStyle(m_editedStyle);
- m_newColor->setStyle(*m_editedStyle);
+ m_newColor->setStyle(*m_editedStyle, getColorParam());
m_oldColor->setStyle(
- *m_oldStyle); // This line is needed for proper undo behavior
+ *m_oldStyle,
+ getColorParam()); // This line is needed for proper undo behavior
+ m_hexLineEdit->setStyle(*m_editedStyle, getColorParam());
}
//-----------------------------------------------------------------------
@@ -3501,8 +3812,9 @@ void StyleEditor::onColorChanged(const ColorModel &color, bool isDragging) {
delete style;
}
- m_newColor->setStyle(*m_editedStyle);
+ m_newColor->setStyle(*m_editedStyle, getColorParam());
m_colorParameterSelector->setStyle(*m_editedStyle);
+ m_hexLineEdit->setStyle(*m_editedStyle, getColorParam());
// Auto Button should be disabled with locked palette
if (m_autoButton->isEnabled() && m_autoButton->isChecked()) {
copyEditedStyleToPalette(isDragging);
@@ -3524,6 +3836,7 @@ void StyleEditor::enable(bool enabled, bool enabledOnlyFirstTab,
m_applyButton->setDisabled(!enabled || m_autoButton->isChecked());
m_oldColor->setEnable(enabled);
m_newColor->setEnable(enabled);
+ m_hexLineEdit->setEnabled(enabled);
if (enabled == false) {
m_oldColor->setColor(TPixel32::Transparent);
m_newColor->setColor(TPixel32::Transparent);
@@ -3558,13 +3871,17 @@ void StyleEditor::checkPaletteLock() {
//-----------------------------------------------------------------------------
-void StyleEditor::onOldStyleClicked(const TColorStyle &) {
+void StyleEditor::onOldStyleClicked() {
if (!m_enabled) return;
selectStyle(*(m_oldColor->getStyle()));
}
//-----------------------------------------------------------------------------
+void StyleEditor::onNewStyleClicked() { applyButtonClicked(); }
+
+//-----------------------------------------------------------------------------
+
void StyleEditor::setPage(int index) {
if (!m_enabledFirstAndLastTab) {
m_styleChooser->setCurrentIndex(index);
@@ -3636,8 +3953,9 @@ bool StyleEditor::setStyle(TColorStyle *currentStyle) {
if (currentStyle) {
m_colorParameterSelector->setStyle(*currentStyle);
m_plainColorPage->setColor(*currentStyle, getColorParam());
- m_oldColor->setStyle(*currentStyle);
- m_newColor->setStyle(*currentStyle);
+ m_oldColor->setStyle(*currentStyle, getColorParam());
+ m_newColor->setStyle(*currentStyle, getColorParam());
+ m_hexLineEdit->setStyle(*m_editedStyle, getColorParam());
setOldStyleToStyle(currentStyle);
}
@@ -3702,10 +4020,11 @@ void StyleEditor::selectStyle(const TColorStyle &newStyle) {
}
// Update editor widgets
- m_newColor->setStyle(*m_editedStyle);
- m_plainColorPage->setColor(*m_editedStyle, getColorParam());
m_colorParameterSelector->setStyle(*m_editedStyle);
+ m_newColor->setStyle(*m_editedStyle, getColorParam());
+ m_plainColorPage->setColor(*m_editedStyle, getColorParam());
m_settingsPage->setStyle(m_editedStyle);
+ m_hexLineEdit->setStyle(*m_editedStyle, getColorParam());
}
//-----------------------------------------------------------------------------
@@ -3717,13 +4036,19 @@ void StyleEditor::onColorParamChanged() {
int styleIndex = getStyleIndex();
if (styleIndex < 0 || palette->getStyleCount() <= styleIndex) return;
+ if (*m_oldStyle != *m_editedStyle) applyButtonClicked();
+
m_paletteHandle->setStyleParamIndex(getColorParam());
if (TColorStyle *currentStyle = palette->getStyle(styleIndex)) {
setEditedStyleToStyle(currentStyle);
+ m_colorParameterSelector->setStyle(*m_editedStyle);
+ m_newColor->setStyle(*m_editedStyle, getColorParam());
+ m_oldColor->setStyle(*m_editedStyle, getColorParam());
m_plainColorPage->setColor(*m_editedStyle, getColorParam());
m_settingsPage->setStyle(m_editedStyle);
+ m_hexLineEdit->setStyle(*m_editedStyle, getColorParam());
}
}
@@ -3738,8 +4063,20 @@ void StyleEditor::onParamStyleChanged(bool isDragging) {
if (m_autoButton->isChecked()) copyEditedStyleToPalette(isDragging);
- m_editedStyle->invalidateIcon(); // Refresh the new color icon
- m_newColor->setStyle(*m_editedStyle); //
+ m_editedStyle->invalidateIcon(); // Refresh the new color icon
+ m_newColor->setStyle(*m_editedStyle, getColorParam());
+ m_hexLineEdit->setStyle(*m_editedStyle, getColorParam());
+}
+
+//-----------------------------------------------------------------------------
+
+void StyleEditor::onHexChanged() {
+ if (m_hexLineEdit->fromText(m_hexLineEdit->text())) {
+ ColorModel cm;
+ cm.setTPixel(m_hexLineEdit->getColor());
+ onColorChanged(cm, false);
+ m_hexLineEdit->selectAll();
+ }
}
//-----------------------------------------------------------------------------
@@ -3775,6 +4112,7 @@ void StyleEditor::save(QSettings &settings) const {
if (m_hsvAction->isChecked()) visibleParts |= 0x02;
if (m_alphaAction->isChecked()) visibleParts |= 0x04;
if (m_rgbAction->isChecked()) visibleParts |= 0x08;
+ if (m_hexAction->isChecked()) visibleParts |= 0x10;
settings.setValue("visibleParts", visibleParts);
settings.setValue("splitterState", m_plainColorPage->getSplitterState());
}
@@ -3804,6 +4142,10 @@ void StyleEditor::load(QSettings &settings) {
m_rgbAction->setChecked(true);
else
m_rgbAction->setChecked(false);
+ if (visiblePartsInt & 0x10)
+ m_hexAction->setChecked(true);
+ else
+ m_hexAction->setChecked(false);
}
QVariant splitterState = settings.value("splitterState");
if (splitterState.canConvert(QVariant::ByteArray))
@@ -3814,4 +4156,28 @@ void StyleEditor::load(QSettings &settings) {
void StyleEditor::updateColorCalibration() {
m_plainColorPage->updateColorCalibration();
+}
+
+//-----------------------------------------------------------------------------
+
+void StyleEditor::onSliderAppearanceSelected(QAction *action) {
+ bool ok = true;
+ int appearanceId = action->data().toInt(&ok);
+ if (!ok) return;
+ if (appearanceId == StyleEditorColorSliderAppearance) return;
+ StyleEditorColorSliderAppearance = appearanceId;
+ ColorSlider::s_slider_appearance = appearanceId;
+ m_plainColorPage->update();
+}
+
+//-----------------------------------------------------------------------------
+
+void StyleEditor::onPopupMenuAboutToShow() {
+ // sync radio button state to the current user env settings
+ for (auto action : m_sliderAppearanceAG->actions()) {
+ bool ok = true;
+ int appearanceId = action->data().toInt(&ok);
+ if (ok && appearanceId == StyleEditorColorSliderAppearance)
+ action->setChecked(true);
+ }
}
\ No newline at end of file
diff --git a/toonz/sources/toonzqt/toonzqt.qrc b/toonz/sources/toonzqt/toonzqt.qrc
index a2a8845..66ab744 100644
--- a/toonz/sources/toonzqt/toonzqt.qrc
+++ b/toonz/sources/toonzqt/toonzqt.qrc
@@ -29,6 +29,8 @@
Resources/h_chandleDown.png
Resources/h_chandleCenter.png
Resources/h_chandleUp.png
+ Resources/h_chandle_arrow.svg
+ Resources/v_chandle_arrow.svg
Resources/schematic_palette.png
Resources/schematic_tablenode.png
Resources/port_red.svg