diff --git a/stuff/config/colornames.txt b/stuff/config/colornames.txt new file mode 100644 index 00000000..fefe1631 --- /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 + \ No newline at end of file diff --git a/toonz/sources/include/toonzqt/colorfield.h b/toonz/sources/include/toonzqt/colorfield.h index 4e449024..9148f265 100644 --- a/toonz/sources/include/toonzqt/colorfield.h +++ b/toonz/sources/include/toonzqt/colorfield.h @@ -36,6 +36,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 c6b4fa2a..c602a68e 100644 --- a/toonz/sources/include/toonzqt/styleeditor.h +++ b/toonz/sources/include/toonzqt/styleeditor.h @@ -83,13 +83,29 @@ class HexLineEdit : public QLineEdit { Q_OBJECT public: - HexLineEdit(const QString &contents, QWidget *parent) - : QLineEdit(contents, parent) {} + 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 focusInEvent(QFocusEvent *event) override; + 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; // ... }; //============================================================================= @@ -257,13 +273,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); @@ -278,6 +294,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(); @@ -287,6 +306,8 @@ protected: private: ColorChannel m_channel; ColorModel m_color; + static int s_chandle_size; + static int s_chandle_tall; }; //============================================================================= @@ -795,7 +816,6 @@ class DVAPI StyleEditor final : public QWidget, public SaveLoadQSettings { TPaletteHandle *m_paletteHandle; TPaletteHandle *m_cleanupPaletteHandle; HexLineEdit *m_hexLineEdit; - QWidgetAction *m_hexAction; QWidget *m_parent; TXshLevelHandle *m_levelHandle; //!< for clearing the level cache when the color changed @@ -833,6 +853,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. @@ -975,7 +996,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 @@ -1001,6 +1023,7 @@ protected slots: void onParamStyleChanged(bool isDragging); void onHexChanged(); + void onHexEdited(const QString &text); void onHideMenu(); void onPageChanged(int index); diff --git a/toonz/sources/toonz/preferencespopup.cpp b/toonz/sources/toonz/preferencespopup.cpp index 9eb8394b..3c69a8fb 100644 --- a/toonz/sources/toonz/preferencespopup.cpp +++ b/toonz/sources/toonz/preferencespopup.cpp @@ -693,6 +693,12 @@ void PreferencesPopup::onUseThemeViewerColorsChanged() { //----------------------------------------------------------------------------- +void PreferencesPopup::onChessboardChanged() { + CommonChessboard::instance()->update(); +} + +//----------------------------------------------------------------------------- + void PreferencesPopup::onSVNEnabledChanged() { if (m_pref->getBoolValue(SVNEnabled)) { if (!VersionControl::instance()->testSetup()) @@ -2012,6 +2018,10 @@ QWidget* PreferencesPopup::createColorsPage() { &PreferencesPopup::notifySceneChanged); m_onEditedFuncMap.insert(chessboardColor2, &PreferencesPopup::notifySceneChanged); + m_onEditedFuncMap.insert(chessboardColor1, + &PreferencesPopup::onChessboardChanged); + m_onEditedFuncMap.insert(chessboardColor2, + &PreferencesPopup::onChessboardChanged); m_onEditedFuncMap.insert(useThemeViewerColors, &PreferencesPopup::onUseThemeViewerColorsChanged); diff --git a/toonz/sources/toonz/preferencespopup.h b/toonz/sources/toonz/preferencespopup.h index 6deaad77..2ffbf725 100644 --- a/toonz/sources/toonz/preferencespopup.h +++ b/toonz/sources/toonz/preferencespopup.h @@ -161,6 +161,7 @@ private: void onOnionColorChanged(); // Colors void onTranspCheckDataChanged(); + void onChessboardChanged(); void onUseThemeViewerColorsChanged(); // Version Control void onSVNEnabledChanged(); 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 00000000..4ade75c2 --- /dev/null +++ b/toonz/sources/toonzqt/Resources/h_chandle_arrow.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file 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 00000000..ff5cf1fe --- /dev/null +++ b/toonz/sources/toonzqt/Resources/v_chandle_arrow.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/toonz/sources/toonzqt/colorfield.cpp b/toonz/sources/toonzqt/colorfield.cpp index e91c489b..96575ff5 100644 --- a/toonz/sources/toonzqt/colorfield.cpp +++ b/toonz/sources/toonzqt/colorfield.cpp @@ -47,6 +47,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(180, 180, 180) , m_chessColor2(239, 239, 239) + , 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 ecbb0386..2ebbff3f 100644 --- a/toonz/sources/toonzqt/styleeditor.cpp +++ b/toonz/sources/toonzqt/styleeditor.cpp @@ -41,6 +41,7 @@ #include "tvectorrenderdata.h" #include "tsimplecolorstyles.h" #include "tvectorbrushstyle.h" +#include "tenv.h" // Qt includes #include @@ -70,6 +71,212 @@ using namespace StyleEditorGUI; using namespace DVGui; +//***************************************************************************** +// 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 //***************************************************************************** @@ -153,12 +360,6 @@ TPixel32 hex2Color(QString hex) { if (hasAlpha) color.m = values.at(3).toInt(&dummy, 16); return color; } -void HexLineEdit::focusInEvent(QFocusEvent *event) { - // QLineEdit::focusInEvent(event); - selectAll(); -} - -void HexLineEdit::showEvent(QShowEvent *event) { selectAll(); } namespace { @@ -572,25 +773,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: @@ -1077,8 +1266,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); @@ -1088,6 +1281,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"); @@ -1118,21 +1318,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 + (handleSize / 2), y + 1, w - handleSize, h, - checkboard); + p.drawTiledPixmap(x, y, w, h, DVGui::CommonChessboard::instance()->getPixmap()); } if (!bgPixmap.isNull()) { - p.drawTiledPixmap(x + (handleSize / 2), y + 1, w - handleSize, h, bgPixmap); - p.setPen(Qt::black); - p.drawRect(x + (handleSize / 2), y + 1, x + w - handleSize, y + h); + p.drawTiledPixmap(x, y, w, h, bgPixmap); } /*! @@ -1140,59 +1344,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_chandle_up.svg"); - static QPixmap hHandleDownPm(":Resources/h_chandle_down.svg"); - static QPixmap hHandleCenterPm(":Resources/h_chandle_center.svg"); - 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(); - span = grooveRect.height(); - } else { - int handleSize = QPixmap(":Resources/h_chandle_center.svg").width(); - pos = event->pos().x(); - span = grooveRect.width(); - } - int value = QStyle::sliderValueFromPosition(minimum(), maximum(), pos, span, - upsideDown); - setValue(value); - } - QSlider::mousePressEvent(event); + chandleMouse(event->pos().x(), event->pos().y()); } //----------------------------------------------------------------------------- @@ -1201,6 +1366,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 //***************************************************************************** @@ -1534,7 +1719,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) { @@ -1588,7 +1773,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(); } @@ -1599,7 +1784,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(); } @@ -4125,28 +4310,25 @@ 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(false); m_alphaAction->setChecked(true); m_rgbAction->setChecked(false); + m_hexAction->setChecked(false); menu->addAction(m_wheelAction); menu->addAction(m_alphaAction); menu->addAction(m_hsvAction); menu->addAction(m_rgbAction); - - m_hexAction = new QWidgetAction(this); - m_hexLineEdit = new HexLineEdit("", this); - m_hexLineEdit->setObjectName("HexLineEdit"); - m_hexAction->setDefaultWidget(m_hexLineEdit); - m_hexAction->setText(" "); menu->addAction(m_hexAction); + QFontMetrics fm(QApplication::font()); - m_hexLineEdit->setFixedWidth(75); m_plainColorPage->m_hsvFrame->setVisible(false); m_plainColorPage->m_rgbFrame->setVisible(false); @@ -4223,6 +4405,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, @@ -4263,8 +4449,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, 30); - m_newColor = new DVGui::StyleSample(this, 32, 32); + m_oldColor = new DVGui::StyleSample(this, 42, 24); + m_newColor = new DVGui::StyleSample(this, 42, 24); m_applyButton = new QPushButton(tr("Apply")); m_fillColorWidget = new QFrame(this); @@ -4283,9 +4469,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->setFixedWidth(32); + 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_fillColorWidget->setFixedHeight(32); m_fillColorWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); @@ -4303,11 +4498,14 @@ 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, 0); hLayout->addWidget(m_fillColorWidget, 0); + hLayout->addSpacing(2); + hLayout->addWidget(m_hexLineEdit); m_oldColor->hide(); } mainLayout->addLayout(hLayout); @@ -4328,9 +4526,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; @@ -4526,6 +4725,7 @@ void StyleEditor::showEvent(QShowEvent *) { m_plainColorPage->m_alphaFrame->setVisible(m_alphaAction->isChecked()); m_plainColorPage->m_hsvFrame->setVisible(m_hsvAction->isChecked()); m_plainColorPage->m_rgbFrame->setVisible(m_rgbAction->isChecked()); + m_hexLineEdit->setVisible(m_hexAction->isChecked()); updateOrientationButton(); assert(ret); } @@ -4807,7 +5007,7 @@ 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()); int tag = m_editedStyle->getTagId(); if (tag == 4 || tag == 2000 || tag == 2800 || getStyleIndex() == 0) { m_fillColorWidget->hide(); @@ -4828,7 +5028,9 @@ void StyleEditor::onStyleChanged(bool isDragging) { m_fillColorWidget->setStyleSheet(styleSheet.arg(myColor)); } 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()); } //----------------------------------------------------------------------- @@ -4917,7 +5119,7 @@ void StyleEditor::onColorChanged(const ColorModel &color, bool isDragging) { delete style; } - m_newColor->setStyle(*m_editedStyle); + m_newColor->setStyle(*m_editedStyle, getColorParam()); int tag = m_editedStyle->getTagId(); if (tag == 4 || tag == 2000 || tag == 2800 || getStyleIndex() == 0) { m_fillColorWidget->hide(); @@ -4937,6 +5139,7 @@ void StyleEditor::onColorChanged(const ColorModel &color, bool isDragging) { m_fillColorWidget->setStyleSheet(styleSheet.arg(myColor)); } m_colorParameterSelector->setStyle(*m_editedStyle); + m_hexLineEdit->setStyle(*m_editedStyle, getColorParam()); if (m_autoButton->isChecked()) { copyEditedStyleToPalette(isDragging); @@ -4958,6 +5161,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); @@ -4997,13 +5201,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) { if (index == 1) @@ -5081,8 +5291,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()); int tag = currentStyle->getTagId(); if (tag == 4 || tag == 2000 || tag == 2800 || getStyleIndex() == 0) { @@ -5166,7 +5377,7 @@ void StyleEditor::selectStyle(const TColorStyle &newStyle) { } // Update editor widgets - m_newColor->setStyle(*m_editedStyle); + m_newColor->setStyle(*m_editedStyle, getColorParam()); int tag = m_editedStyle->getTagId(); if (tag == 4 || tag == 2000 || tag == 2800 || getStyleIndex() == 0) { m_fillColorWidget->hide(); @@ -5188,6 +5399,7 @@ void StyleEditor::selectStyle(const TColorStyle &newStyle) { m_plainColorPage->setColor(*m_editedStyle, getColorParam()); m_colorParameterSelector->setStyle(*m_editedStyle); m_settingsPage->setStyle(m_editedStyle); + m_hexLineEdit->setStyle(*m_editedStyle, getColorParam()); } //----------------------------------------------------------------------------- @@ -5212,7 +5424,8 @@ void StyleEditor::addToPalette(const TColorStyle &newStyle) { palette->setDirtyFlag(true); // Update editor widgets - m_newColor->setStyle(*m_editedStyle); + m_newColor->setStyle(*m_editedStyle, getColorParam()); + m_oldColor->setStyle(*m_editedStyle, getColorParam()); int tag = m_editedStyle->getTagId(); if (tag == 4 || tag == 2000 || tag == 2800 || getStyleIndex() == 0) { m_fillColorWidget->hide(); @@ -5234,6 +5447,7 @@ void StyleEditor::addToPalette(const TColorStyle &newStyle) { m_plainColorPage->setColor(*m_editedStyle, getColorParam()); m_colorParameterSelector->setStyle(*m_editedStyle); m_settingsPage->setStyle(m_editedStyle); + m_hexLineEdit->setStyle(*m_editedStyle, getColorParam()); } //----------------------------------------------------------------------------- @@ -5250,8 +5464,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()); } int tag = m_editedStyle->getTagId(); if (tag == 4 || tag == 2000 || tag == 2800 || getStyleIndex() == 0) { @@ -5286,7 +5504,7 @@ 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()); int tag = m_editedStyle->getTagId(); if (tag == 4 || tag == 2000 || tag == 2800 || getStyleIndex() == 0) { @@ -5306,6 +5524,18 @@ void StyleEditor::onParamStyleChanged(bool isDragging) { QString styleSheet = "QFrame {background-color: rgb(%1);}"; m_fillColorWidget->setStyleSheet(styleSheet.arg(myColor)); } + 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(); + } } //----------------------------------------------------------------------------- @@ -5350,18 +5580,6 @@ void StyleEditor::onPageChanged(int index) { onUpdateFavorites(); update(); } -//----------------------------------------------------------------------------- - -void StyleEditor::onHexChanged() { - m_hsvAction->parentWidget()->clearFocus(); - QString hex = m_hexLineEdit->text(); - if (isHex(hex)) { - TPixel32 color = hex2Color(hex); - ColorModel cm; - cm.setTPixel(color); - onColorChanged(cm, false); - } -} //----------------------------------------------------------------------------- QStringList StyleEditor::savePageStates(StylePageType pageType) const { @@ -5456,6 +5674,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()); settings.setValue("texturePageStates", @@ -5490,6 +5709,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)) diff --git a/toonz/sources/toonzqt/toonzqt.qrc b/toonz/sources/toonzqt/toonzqt.qrc index 6bc78c10..ee9e0812 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/h_chandle_down.svg Resources/h_chandle_center.svg Resources/h_chandle_top.svg