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/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..b661dd2 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,13 +267,13 @@ 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 +288,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 +300,8 @@ protected:
private:
ColorChannel m_channel;
ColorModel m_color;
+ static int s_chandle_size;
+ static int s_chandle_tall;
};
//=============================================================================
@@ -614,6 +648,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 +687,7 @@ class DVAPI StyleEditor final : public QWidget, public SaveLoadQSettings {
QAction *m_hsvAction;
QAction *m_alphaAction;
QAction *m_rgbAction;
+ QAction *m_hexAction;
TColorStyleP
m_oldStyle; //!< A copy of current style \a before the last change.
@@ -727,7 +763,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,6 +789,8 @@ protected slots:
void onParamStyleChanged(bool isDragging);
+ void onHexChanged();
+
void onSpecialButtonToggled(bool on);
void onCustomButtonToggled(bool on);
void onVectorBrushButtonToggled(bool on);
diff --git a/toonz/sources/toonz/preferencespopup.cpp b/toonz/sources/toonz/preferencespopup.cpp
index dda75ac..872aa69 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())
@@ -2043,6 +2049,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/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..c1aaf1f 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,26 @@ 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);
+
/*-- TSolidColorStyleの場合のみ、単色塗りつぶし --*/
- if (style.getTagId() == 3)
+ if (style.getTagId() == 3) {
setColor(style.getMainColor());
- else {
+ m_stretch = true;
+ } else {
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 +185,22 @@ 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 {
+ 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 +216,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 +819,7 @@ CleanupColorField::CleanupColorField(QWidget *parent,
}
}
- m_colorSample->setStyle(*cleanupStyle);
+ m_colorSample->setStyle(*cleanupStyle, 0);
//---- layout
@@ -828,7 +876,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 +908,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 +925,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 +939,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..3f00653 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
@@ -61,6 +62,212 @@
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
//*****************************************************************************
@@ -476,25 +683,13 @@ QPixmap makeLinearShading(const ColorModel &color, ColorChannel channel,
int size, bool isVertical) {
switch (channel) {
case eRed:
- if (isVertical)
- return makeLinearShading(RedShadeMaker(color), size, isVertical);
- else
- return QPixmap(":Resources/grad_r.png").scaled(size, 1);
+ return makeLinearShading(RedShadeMaker(color), size, isVertical);
case eGreen:
- if (isVertical)
- return makeLinearShading(GreenShadeMaker(color), size, isVertical);
- else
- return QPixmap(":Resources/grad_g.png").scaled(size, 1);
+ return makeLinearShading(GreenShadeMaker(color), size, isVertical);
case eBlue:
- if (isVertical)
- return makeLinearShading(BlueShadeMaker(color), size, isVertical);
- else
- return QPixmap(":Resources/grad_b.png").scaled(size, 1);
+ return makeLinearShading(BlueShadeMaker(color), size, isVertical);
case eAlpha:
- if (isVertical)
- return makeLinearShading(AlphaShadeMaker(color), size, isVertical);
- else
- return QPixmap(":Resources/grad_m.png").scaled(size, 1);
+ return makeLinearShading(AlphaShadeMaker(color), size, isVertical);
case eHue:
return makeLinearShading(HueShadeMaker(color), size, isVertical);
case eSaturation:
@@ -981,8 +1176,12 @@ void SquaredColorWheel::setChannel(int channel) {
// ColorSlider implementation
//*****************************************************************************
+// Adquire size later...
+int ColorSlider::s_chandle_size = -1;
+int ColorSlider::s_chandle_tall = -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 +1191,13 @@ 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();
+ }
+
// Attenzione: necessario per poter individuare l'oggetto nel file di
// definizione dello stile
setObjectName("colorSlider");
@@ -1021,18 +1227,25 @@ void ColorSlider::paintEvent(QPaintEvent *event) {
bool isVertical = orientation() == Qt::Vertical;
- 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;
+ }
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 +1253,20 @@ 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);
+ static QPixmap hHandlePixmap = svgToPixmap(":Resources/h_chandle_arrow.svg");
+ int pos = QStyle::sliderPositionFromValue(0, maximum(), value(), w, false);
+ 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 +1275,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 +1619,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) {
@@ -1479,7 +1673,7 @@ void ColorParameterSelector::setStyle(const TColorStyle &style) {
void ColorParameterSelector::clear() {
if (m_colors.size() != 0) m_colors.clear();
- m_index = -1;
+ m_index = 0;
update();
}
@@ -1490,7 +1684,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 +2585,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
)
@@ -3013,19 +3207,23 @@ StyleEditor::StyleEditor(PaletteController *paletteController, QWidget *parent)
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);
QToolButton *toolButton = new QToolButton(this);
toolButton->setIcon(createQIcon("menu"));
@@ -3106,6 +3304,10 @@ StyleEditor::StyleEditor(PaletteController *paletteController, QWidget *parent)
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,
@@ -3135,8 +3337,8 @@ 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);
@@ -3154,8 +3356,18 @@ 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);
/* ------ layout ------ */
QVBoxLayout *mainLayout = new QVBoxLayout;
@@ -3167,10 +3379,13 @@ QFrame *StyleEditor::createBottomWidget() {
hLayout->setSpacing(0);
{
hLayout->addWidget(m_autoButton);
+ hLayout->addSpacing(2);
hLayout->addWidget(m_applyButton);
hLayout->addSpacing(2);
hLayout->addWidget(m_newColor, 1);
hLayout->addWidget(m_oldColor, 1);
+ hLayout->addSpacing(2);
+ hLayout->addWidget(m_hexLineEdit);
}
mainLayout->addLayout(hLayout);
@@ -3188,8 +3403,10 @@ 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()));
assert(ret);
return bottomWidget;
@@ -3308,6 +3525,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 +3622,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 +3721,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 +3745,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 +3780,19 @@ 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 +3864,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 +3931,11 @@ void StyleEditor::selectStyle(const TColorStyle &newStyle) {
}
// Update editor widgets
- m_newColor->setStyle(*m_editedStyle);
+ m_newColor->setStyle(*m_editedStyle, getColorParam());
m_plainColorPage->setColor(*m_editedStyle, getColorParam());
m_colorParameterSelector->setStyle(*m_editedStyle);
m_settingsPage->setStyle(m_editedStyle);
+ m_hexLineEdit->setStyle(*m_editedStyle, getColorParam());
}
//-----------------------------------------------------------------------------
@@ -3722,8 +3952,12 @@ void StyleEditor::onColorParamChanged() {
if (TColorStyle *currentStyle = palette->getStyle(styleIndex)) {
setEditedStyleToStyle(currentStyle);
+ m_newColor->setStyle(*m_editedStyle, getColorParam());
+ m_oldColor->setStyle(*m_editedStyle, getColorParam());
m_plainColorPage->setColor(*m_editedStyle, getColorParam());
+ m_colorParameterSelector->setStyle(*m_editedStyle);
m_settingsPage->setStyle(m_editedStyle);
+ m_hexLineEdit->setStyle(*m_editedStyle, getColorParam());
}
}
@@ -3739,7 +3973,19 @@ 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_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 +4021,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 +4051,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 +4065,4 @@ void StyleEditor::load(QSettings &settings) {
void StyleEditor::updateColorCalibration() {
m_plainColorPage->updateColorCalibration();
-}
\ No newline at end of file
+}
diff --git a/toonz/sources/toonzqt/toonzqt.qrc b/toonz/sources/toonzqt/toonzqt.qrc
index a2a8845..20066b8 100644
--- a/toonz/sources/toonzqt/toonzqt.qrc
+++ b/toonz/sources/toonzqt/toonzqt.qrc
@@ -26,9 +26,8 @@
Resources/grad_g.png
Resources/grad_b.png
Resources/grad_m.png
- 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