Merge pull request #891 from justburner/HexEditor

Hex color names editor
This commit is contained in:
manongjohn 2022-02-16 17:38:12 -05:00 committed by GitHub
commit 4075bb5d39
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 1298 additions and 241 deletions

View file

@ -12,6 +12,10 @@
<color name="1">#FF0000</color>
<color name="2">#00FF00</color>
<color name="3">#0000FF</color>
<color name="4">#00FFFF</color>
<color name="5">#FF00FF</color>
<color name="6">#FFFF00</color>
<color name="7">#FFFFFF</color>
<!-- HTML Color Names -->
<color name="AliceBlue">#F0F8FF</color>
<color name="AntiqueWhite">#FAEBD7</color>

View file

@ -44,11 +44,10 @@ class DVAPI CommonChessboard final : public QObject {
Q_OBJECT
TRaster32P m_bgRas;
QPixmap m_bgPix;
CommonChessboard();
void setChessboardColors(const TPixel32 &col1, const TPixel32 &col2);
public:
CommonChessboard();
const QPixmap &getPixmap() { return m_bgPix; }
void update();

View file

@ -0,0 +1,315 @@
#pragma once
#ifndef HEXCOLORNAMES_H
#define HEXCOLORNAMES_H
// TnzCore includes
#include "tcommon.h"
#include "tfilepath.h"
#include "tpixel.h"
#include "tpalette.h"
#include "tenv.h"
// TnzQt includes
#include "toonzqt/dvdialog.h"
#include "toonzqt/colorfield.h"
// Qt includes
#include <QString>
#include <QPushButton>
#include <QCheckBox>
#include <QLineEdit>
#include <QCompleter>
#include <QMap>
#include <QTreeWidget>
#include <QStyledItemDelegate>
#undef DVAPI
#undef DVVAR
#ifdef TOONZQT_EXPORTS
#define DVAPI DV_EXPORT_API
#define DVVAR DV_EXPORT_VAR
#else
#define DVAPI DV_IMPORT_API
#define DVVAR DV_IMPORT_VAR
#endif
namespace DVGui {
//-----------------------------------------------------------------------------
//! Manage all Hex and named colors conversions.
class HexColorNames final : public QObject {
Q_OBJECT
HexColorNames();
static QMap<QString, QString> s_maincolornames;
static QMap<QString, QString> s_usercolornames;
static QMap<QString, QString> s_tempcolornames;
static void loadColorTableXML(QMap<QString, QString> &table,
const TFilePath &fp);
static void saveColorTableXML(QMap<QString, QString> &table,
const TFilePath &fp);
static bool parseHexInternal(QString text, TPixel &outPixel);
public:
//! iterator for accessing user entries
class iterator {
QMap<QString, QString>::iterator m_it;
bool m_mutable;
public:
inline iterator() : m_it(nullptr), m_mutable(false) {}
inline iterator(iterator *it)
: m_it(it->m_it), m_mutable(it->m_mutable) {}
inline iterator(QMap<QString, QString>::iterator it, bool isMutable)
: m_it(it), m_mutable(isMutable) {}
inline const QString &name() const { return m_it.key(); }
inline const QString &value() const { return m_it.value(); }
inline void setValue(const QString &value) { if (m_mutable) m_it.value() = value; }
inline bool operator==(const iterator &o) const { return m_it == o.m_it; }
inline bool operator!=(const iterator &o) const { return m_it != o.m_it; }
inline iterator &operator++() {
++m_it;
return *this;
}
inline iterator &operator--() {
--m_it;
return *this;
}
inline iterator operator++(int) {
iterator r = *this;
m_it++;
return r;
}
inline iterator operator--(int) {
iterator r = *this;
m_it--;
return r;
}
};
//! Load entries from main colornames.txt file
static bool loadMainFile(bool reload);
//! Load entries from user colornames.txt file
static bool loadUserFile(bool reload);
//! Load temporary entries from custom file
static bool loadTempFile(const TFilePath& fp);
//! Verify if there's personal colornames.txt file
static bool hasUserFile();
//! Save entries to user colornames.txt file
static bool saveUserFile();
//! Load temporary entries from custom file
static bool saveTempFile(const TFilePath &fp);
//! Clear all user entries
static void clearUserEntries();
//! Clear all user entries
static void clearTempEntries();
//! Set single user entry
static void setUserEntry(const QString &name, const QString &hex);
//! Set single user entry
static void setTempEntry(const QString &name, const QString &hex);
//! Get first main entry
static inline iterator beginMain() {
return iterator(s_maincolornames.begin(), false);
}
//! Get last main entry
static inline iterator endMain() {
return iterator(s_maincolornames.end(), false);
}
//! Get first user entry
static inline iterator beginUser() {
return iterator(s_usercolornames.begin(), true);
}
//! Get last user entry
static inline iterator endUser() {
return iterator(s_usercolornames.end(), true);
}
//! Get first user entry
static inline iterator beginTemp() {
return iterator(s_tempcolornames.begin(), true);
}
//! Get last user entry
static inline iterator endTemp() {
return iterator(s_tempcolornames.end(), true);
}
//! Parse raw text into RGBA color
static bool parseText(QString text, TPixel &outPixel);
//! Parse hex format into RGBA color
static bool parseHex(QString text, TPixel &outPixel);
//! Generate hex format from RGBA color
static QString generateHex(TPixel pixel);
//! To access singleton for signaling
static HexColorNames *instance();
//! Emit that user entries were changed
inline void emitChanged() { emit colorsChanged(); }
inline void emitAutoComplete(bool enable) { emit autoCompleteChanged(enable); }
signals:
void autoCompleteChanged(bool);
void colorsChanged();
};
//-----------------------------------------------------------------------------
//! Hex line-edit widget
class DVAPI HexLineEdit : public QLineEdit {
Q_OBJECT
public:
HexLineEdit(const QString &contents, QWidget *parent);
~HexLineEdit() {}
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 mousePressEvent(QMouseEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;
void showEvent(QShowEvent *event) override;
QCompleter *getCompleter();
bool m_editing;
TPixel m_color;
QCompleter *m_completer;
protected slots:
void onAutoCompleteChanged(bool);
void onColorsChanged();
};
//-----------------------------------------------------------------------------
//! Editing delegate for editor
class HexColorNamesEditingDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
HexColorNamesEditingDelegate(QObject *parent = nullptr)
: QStyledItemDelegate(parent) {
connect(this,
SIGNAL(closeEditor(QWidget *,
QAbstractItemDelegate::EndEditHint)),
this,
SLOT(onCloseEditor(QWidget *, QAbstractItemDelegate::EndEditHint)));
}
virtual QWidget *createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const {
QWidget *widget = QStyledItemDelegate::createEditor(parent, option, index);
emit editingStarted(index);
return widget;
}
virtual void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const {
QStyledItemDelegate::setModelData(editor, model, index);
emit editingFinished(index);
}
signals:
void editingStarted(const QModelIndex &) const;
void editingFinished(const QModelIndex &) const;
void editingClosed() const;
private slots:
inline void onCloseEditor(QWidget *editor,
QAbstractItemDelegate::EndEditHint hint = NoHint) {
emit editingClosed();
}
};
//-----------------------------------------------------------------------------
//! Dialog: Hex color names editor
class HexColorNamesEditor final : public DVGui::Dialog {
Q_OBJECT
HexColorNamesEditingDelegate *m_userEditingDelegate;
QTreeWidget *m_userTreeWidget;
QTreeWidget *m_mainTreeWidget;
QCheckBox *m_autoCompleteCb;
QPushButton *m_addColorButton;
QPushButton *m_delColorButton;
QPushButton *m_unsColorButton;
QPushButton *m_importButton;
QPushButton *m_exportButton;
HexLineEdit *m_hexLineEdit;
ColorField *m_colorField;
bool m_autoComplete;
bool m_newEntry;
int m_selectedColn;
QTreeWidgetItem *m_selectedItem;
QString m_selectedName, m_selectedHex;
QTreeWidgetItem *addEntry(QTreeWidget *tree, const QString &name,
const QString &hex, bool editable);
bool updateUserHexEntry(QTreeWidgetItem *treeItem, const TPixel32 &color);
bool nameValid(const QString& name);
bool nameExists(const QString &name, QTreeWidgetItem *self);
void deselectItem(bool treeFocus);
void deleteCurrentItem(bool deselect);
void populateMainList(bool reload);
void populateUserList(bool reload);
void showEvent(QShowEvent *e) override;
void keyPressEvent(QKeyEvent *event) override;
void focusInEvent(QFocusEvent *e) override;
void focusOutEvent(QFocusEvent *e) override;
bool eventFilter(QObject *obj, QEvent *e) override;
private slots:
void onCurrentItemChanged(QTreeWidgetItem *current,
QTreeWidgetItem *previous);
void onEditingStarted(const QModelIndex &);
void onEditingFinished(const QModelIndex &);
void onEditingClosed();
void onItemStarted(QTreeWidgetItem *item, int column);
void onItemFinished(QTreeWidgetItem *item, int column);
void onColorFieldChanged(const TPixel32 &color, bool isDragging);
void onHexChanged();
void onAddColor();
void onDelColor();
void onDeselect();
void onImport();
void onExport();
void onOK();
void onApply();
public:
HexColorNamesEditor(QWidget *parent);
};
//-----------------------------------------------------------------------------
} // namespace DVGui
//-----------------------------------------------------------------------------
#endif // HEXCOLORNAMES_H

View file

@ -24,6 +24,7 @@
#include "toonzqt/tabbar.h"
#include "toonzqt/glwidget_for_highdpi.h"
#include "toonzqt/dvdialog.h"
#include "toonzqt/hexcolornames.h"
// Qt includes
#include <QWidget>
@ -79,35 +80,6 @@ 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<QString, QString> &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<QString, QString> s_defcolornames; // make it shared
static QMap<QString, QString> s_usercolornames; // ...
};
//=============================================================================
namespace StyleEditorGUI {
//=============================================================================
@ -817,7 +789,8 @@ class DVAPI StyleEditor final : public QWidget, public SaveLoadQSettings {
PaletteController *m_paletteController;
TPaletteHandle *m_paletteHandle;
TPaletteHandle *m_cleanupPaletteHandle;
HexLineEdit *m_hexLineEdit;
DVGui::HexLineEdit *m_hexLineEdit;
DVGui::HexColorNamesEditor *m_hexColorNamesEditor;
QWidget *m_parent;
TXshLevelHandle
*m_levelHandle; //!< for clearing the level cache when the color changed
@ -856,6 +829,7 @@ class DVAPI StyleEditor final : public QWidget, public SaveLoadQSettings {
QAction *m_alphaAction;
QAction *m_rgbAction;
QAction *m_hexAction;
QAction *m_hexEditorAction;
TColorStyleP
m_oldStyle; //!< A copy of current style \a before the last change.
@ -1025,6 +999,7 @@ protected slots:
void onParamStyleChanged(bool isDragging);
void onHexChanged();
void onHexEditor();
void onHexEdited(const QString &text);
void onHideMenu();

View file

@ -33,6 +33,7 @@ set(MOC_HEADERS
../include/toonzqt/fxselection.h
../include/toonzqt/fxsettings.h
../include/toonzqt/gutil.h
../include/toonzqt/hexcolornames.h
../include/toonzqt/histogram.h
../include/toonzqt/icongenerator.h
../include/toonzqt/imageutils.h
@ -122,6 +123,7 @@ set(SOURCES
fxhistogramrender.cpp
fxsettings.cpp
gutil.cpp
hexcolornames.cpp
histogram.cpp
icongenerator.cpp
imageutils.cpp

View file

@ -0,0 +1,955 @@
#include "toonzqt/hexcolornames.h"
// TnzLib includes
#include "toonz/toonzfolders.h"
// TnzCore includes
#include "tconvert.h"
#include "tfiletype.h"
#include "tsystem.h"
#include "tcolorstyles.h"
#include "tpalette.h"
#include "tpixel.h"
#include "tvectorimage.h"
#include "trasterimage.h"
#include "tlevel_io.h"
// Qt includes
#include <QCoreApplication>
#include <QPainter>
#include <QMouseEvent>
#include <QLabel>
#include <QToolTip>
#include <QTabWidget>
#include <QCheckBox>
#include <QFileDialog>
#include <QMessageBox>
using namespace DVGui;
//-----------------------------------------------------------------------------
#define COLORNAMES_FILE "colornames.txt"
QMap<QString, QString> HexColorNames::s_maincolornames;
QMap<QString, QString> HexColorNames::s_usercolornames;
QMap<QString, QString> HexColorNames::s_tempcolornames;
HexColorNames *HexColorNames::instance() {
static HexColorNames _instance;
return &_instance;
}
HexColorNames::HexColorNames() {}
void HexColorNames::loadColorTableXML(QMap<QString, QString> &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 HexColorNames::saveColorTableXML(QMap<QString, QString> &table,
const TFilePath &fp) {
TOStream os(fp);
if (!os) throw TException("Can't write color names");
os.openChild("colors");
QMap<QString, QString>::const_iterator it;
std::map<std::string, std::string> attrs;
for (it = table.cbegin(); it != table.cend(); ++it) {
std::string nameStd = it.key().toStdString();
attrs.clear();
attrs.insert({"name", nameStd});
os.openChild("color", attrs);
os << it.value();
os.closeChild();
}
os.closeChild();
}
//-----------------------------------------------------------------------------
bool HexColorNames::parseHexInternal(QString text, TPixel &outPixel) {
bool ok;
uint parsedValue = text.toUInt(&ok, 16);
if (!ok) return false;
switch (text.length()) {
case 8: // #RRGGBBAA
outPixel.r = parsedValue >> 24;
outPixel.g = parsedValue >> 16;
outPixel.b = parsedValue >> 8;
outPixel.m = parsedValue;
break;
case 6: // #RRGGBB
outPixel.r = parsedValue >> 16;
outPixel.g = parsedValue >> 8;
outPixel.b = parsedValue;
outPixel.m = 255;
break;
case 4: // #RGBA
outPixel.r = (parsedValue >> 12) & 15;
outPixel.r |= outPixel.r << 4;
outPixel.g = (parsedValue >> 8) & 15;
outPixel.g |= outPixel.g << 4;
outPixel.b = (parsedValue >> 4) & 15;
outPixel.b |= outPixel.b << 4;
outPixel.m = parsedValue & 15;
outPixel.m |= outPixel.m << 4;
break;
case 3: // #RGB
outPixel.r = (parsedValue >> 8) & 15;
outPixel.r |= outPixel.r << 4;
outPixel.g = (parsedValue >> 4) & 15;
outPixel.g |= outPixel.g << 4;
outPixel.b = parsedValue & 15;
outPixel.b |= outPixel.b << 4;
outPixel.m = 255;
break;
case 2: // #VV (non-standard)
outPixel.r = parsedValue;
outPixel.g = outPixel.r;
outPixel.b = outPixel.r;
outPixel.m = 255;
break;
case 1: // #V (non-standard)
outPixel.r = parsedValue & 15;
outPixel.r |= outPixel.r << 4;
outPixel.g = outPixel.r;
outPixel.b = outPixel.r;
outPixel.m = 255;
break;
default:
return false;
}
return true;
}
//-----------------------------------------------------------------------------
bool HexColorNames::loadMainFile(bool reload) {
TFilePath mainCTFp = TEnv::getConfigDir() + COLORNAMES_FILE;
// Load main color names
try {
if (reload || s_maincolornames.size() == 0) {
s_maincolornames.clear();
loadColorTableXML(s_maincolornames, mainCTFp);
}
} catch (...) {
return false;
}
return true;
}
//-----------------------------------------------------------------------------
bool HexColorNames::hasUserFile() {
TFilePath userCTFp = ToonzFolder::getMyModuleDir() + COLORNAMES_FILE;
return TFileStatus(userCTFp).doesExist();
}
//-----------------------------------------------------------------------------
bool HexColorNames::loadUserFile(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;
}
//-----------------------------------------------------------------------------
bool HexColorNames::loadTempFile(const TFilePath &fp) {
if (TFileStatus(fp).doesExist()) {
try {
s_tempcolornames.clear();
loadColorTableXML(s_tempcolornames, fp);
} catch (...) {
return false;
}
}
return true;
}
//-----------------------------------------------------------------------------
bool HexColorNames::saveUserFile() {
TFilePath userCTFp = ToonzFolder::getMyModuleDir() + COLORNAMES_FILE;
try {
saveColorTableXML(s_usercolornames, userCTFp);
} catch (...) {
return false;
}
return true;
}
//-----------------------------------------------------------------------------
bool HexColorNames::saveTempFile(const TFilePath &fp) {
try {
saveColorTableXML(s_tempcolornames, fp);
} catch (...) {
return false;
}
return true;
}
//-----------------------------------------------------------------------------
void HexColorNames::clearUserEntries() { s_usercolornames.clear(); }
void HexColorNames::clearTempEntries() { s_tempcolornames.clear(); }
//-----------------------------------------------------------------------------
void HexColorNames::setUserEntry(const QString &name, const QString &hex) {
s_usercolornames.insert(name, hex);
}
//-----------------------------------------------------------------------------
void HexColorNames::setTempEntry(const QString &name, const QString &hex) {
s_tempcolornames.insert(name, hex);
}
//-----------------------------------------------------------------------------
bool HexColorNames::parseText(QString text, TPixel &outPixel) {
static QRegExp space("\\s");
text.remove(space);
if (text.size() == 0) return false;
if (text[0] == "#") {
text.remove(0, 1);
return parseHexInternal(text, outPixel);
}
text = text.toLower(); // table names are lowercase
// Find color from tables, user takes priority
QMap<QString, QString>::const_iterator it;
it = s_usercolornames.constFind(text);
if (it == s_usercolornames.constEnd()) {
it = s_maincolornames.constFind(text);
if (it == s_maincolornames.constEnd()) return false;
}
QString hexText = it.value();
hexText.remove(space);
if (hexText[0] == "#") {
hexText.remove(0, 1);
return parseHexInternal(hexText, outPixel);
}
return false;
}
//-----------------------------------------------------------------------------
bool HexColorNames::parseHex(QString text, TPixel &outPixel) {
static QRegExp space("\\s");
text.remove(space);
if (text.size() == 0) return false;
if (text[0] == "#") {
text.remove(0, 1);
}
return parseHexInternal(text, outPixel);
}
//-----------------------------------------------------------------------------
QString HexColorNames::generateHex(TPixel pixel) {
if (pixel.m == 255) {
// Opaque, omit alpha
return QString("#%1%2%3")
.arg(pixel.r, 2, 16, QLatin1Char('0'))
.arg(pixel.g, 2, 16, QLatin1Char('0'))
.arg(pixel.b, 2, 16, QLatin1Char('0'))
.toUpper();
} else {
return QString("#%1%2%3%4")
.arg(pixel.r, 2, 16, QLatin1Char('0'))
.arg(pixel.g, 2, 16, QLatin1Char('0'))
.arg(pixel.b, 2, 16, QLatin1Char('0'))
.arg(pixel.m, 2, 16, QLatin1Char('0'))
.toUpper();
}
}
//-----------------------------------------------------------------------------
//*****************************************************************************
// Hex line widget
//*****************************************************************************
TEnv::IntVar HexLineEditAutoComplete("HexLineEditAutoComplete", 1);
HexLineEdit::HexLineEdit(const QString &contents, QWidget *parent)
: QLineEdit(contents, parent)
, m_editing(false)
, m_color(0, 0, 0)
, m_completer(nullptr) {
HexColorNames::loadMainFile(false);
HexColorNames::loadUserFile(false);
if (HexLineEditAutoComplete != 0) onAutoCompleteChanged(true);
bool ret = true;
ret = ret &&
connect(HexColorNames::instance(), SIGNAL(autoCompleteChanged(bool)),
this, SLOT(onAutoCompleteChanged(bool)));
ret = ret && connect(HexColorNames::instance(), SIGNAL(colorsChanged()), this,
SLOT(onColorsChanged()));
assert(ret);
}
//-----------------------------------------------------------------------------
void HexLineEdit::updateColor() {
setText(HexColorNames::generateHex(m_color));
}
//-----------------------------------------------------------------------------
void HexLineEdit::setStyle(TColorStyle &style, int index) {
setColor(style.getColorParamValue(index));
}
//-----------------------------------------------------------------------------
void HexLineEdit::setColor(TPixel color) {
if (m_color != color) {
m_color = color;
if (isVisible()) updateColor();
}
}
//-----------------------------------------------------------------------------
bool HexLineEdit::fromText(QString text) {
bool res = HexColorNames::parseText(text, m_color);
if (res) updateColor();
return res;
}
//-----------------------------------------------------------------------------
bool HexLineEdit::fromHex(QString text) {
bool res = HexColorNames::parseHex(text, m_color);
if (res) updateColor();
return res;
}
//-----------------------------------------------------------------------------
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();
}
//-----------------------------------------------------------------------------
QCompleter *HexLineEdit::getCompleter() {
QStringList autolist;
// Build words list from all color names tables
HexColorNames::iterator it;
for (it = HexColorNames::beginMain(); it != HexColorNames::endMain(); ++it) {
autolist.append(it.name());
}
for (it = HexColorNames::beginUser(); it != HexColorNames::endUser(); ++it) {
autolist.append(it.name());
}
QCompleter *completer = new QCompleter(autolist);
completer->setCaseSensitivity(Qt::CaseInsensitive);
return completer;
}
//-----------------------------------------------------------------------------
void HexLineEdit::onAutoCompleteChanged(bool enable) {
if (m_completer) {
m_completer->deleteLater();
setCompleter(nullptr);
m_completer = nullptr;
}
if (enable) {
m_completer = getCompleter();
setCompleter(m_completer);
}
}
void HexLineEdit::onColorsChanged() { onAutoCompleteChanged(true); }
//-----------------------------------------------------------------------------
//*****************************************************************************
// Hex color names editor
//*****************************************************************************
HexColorNamesEditor::HexColorNamesEditor(QWidget *parent)
: DVGui::Dialog(parent, true, false, "HexColorNamesEditor")
, m_selectedItem(nullptr)
, m_newEntry(false) {
setWindowTitle(tr("Hex Color Names Editor"));
setModal(false); // user may want to access main style editor and palettes
QPushButton *okButton = new QPushButton(tr("OK"), this);
QPushButton *applyButton = new QPushButton(tr("Apply"), this);
QPushButton *closeButton = new QPushButton(tr("Close"), this);
m_unsColorButton = new QPushButton(tr("Unselect"));
m_addColorButton = new QPushButton(tr("Add Color"));
m_delColorButton = new QPushButton(tr("Delete Color"));
m_hexLineEdit = new HexLineEdit("", this);
m_hexLineEdit->setObjectName("HexLineEdit");
m_hexLineEdit->setFixedWidth(75);
// Main default color names
QGridLayout *mainLay = new QGridLayout();
QWidget *mainTab = new QWidget();
mainTab->setLayout(mainLay);
m_mainTreeWidget = new QTreeWidget();
m_mainTreeWidget->setRootIsDecorated(false);
m_mainTreeWidget->setColumnCount(2);
m_mainTreeWidget->setColumnWidth(0, 175);
m_mainTreeWidget->setColumnWidth(1, 50);
m_mainTreeWidget->setHeaderLabels(QStringList() << "Name"
<< "Hex value");
mainLay->addWidget(m_mainTreeWidget, 0, 0);
// User defined color names
QGridLayout *userLay = new QGridLayout();
QWidget *userTab = new QWidget();
userTab->setLayout(userLay);
m_userTreeWidget = new QTreeWidget();
m_userTreeWidget->setRootIsDecorated(false);
m_userTreeWidget->setColumnCount(2);
m_userTreeWidget->setColumnWidth(0, 175);
m_userTreeWidget->setColumnWidth(1, 50);
m_userTreeWidget->setHeaderLabels(QStringList() << "Name"
<< "Hex value");
m_colorField = new ColorField(this, true);
userLay->addWidget(m_userTreeWidget, 0, 0, 1, 4);
userLay->addWidget(m_unsColorButton, 1, 0);
userLay->addWidget(m_addColorButton, 1, 1);
userLay->addWidget(m_delColorButton, 1, 2);
userLay->addWidget(m_hexLineEdit, 1, 3);
userLay->addWidget(m_colorField, 2, 0, 1, 4);
// Set delegate
m_userEditingDelegate = new HexColorNamesEditingDelegate(m_userTreeWidget);
m_mainTreeWidget->setItemDelegate(m_userEditingDelegate);
m_userTreeWidget->setItemDelegate(m_userEditingDelegate);
populateMainList(false);
// Tabs
QTabWidget *tab = new QTabWidget();
tab->addTab(userTab, tr("User Defined Colors"));
tab->addTab(mainTab, tr("Default Main Colors"));
tab->setObjectName("hexTabWidget");
// Bottom widgets
QHBoxLayout *bottomLay = new QHBoxLayout();
m_autoCompleteCb = new QCheckBox(tr("Enable Auto-Complete"));
m_autoCompleteCb->setChecked(HexLineEditAutoComplete != 0);
m_autoCompleteCb->setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Preferred);
m_importButton = new QPushButton(tr("Import"));
m_exportButton = new QPushButton(tr("Export"));
bottomLay->setMargin(8);
bottomLay->setSpacing(5);
bottomLay->addWidget(m_autoCompleteCb);
bottomLay->addWidget(m_importButton);
bottomLay->addWidget(m_exportButton);
m_topLayout->setContentsMargins(0, 0, 0, 0);
m_topLayout->addWidget(tab);
m_topLayout->addLayout(bottomLay);
addButtonBarWidget(okButton, applyButton, closeButton);
bool ret = true;
ret = ret && connect(m_userEditingDelegate,
SIGNAL(editingStarted(const QModelIndex &)), this,
SLOT(onEditingStarted(const QModelIndex &)));
ret = ret && connect(m_userEditingDelegate,
SIGNAL(editingFinished(const QModelIndex &)), this,
SLOT(onEditingFinished(const QModelIndex &)));
ret = ret && connect(m_userEditingDelegate, SIGNAL(editingClosed()), this,
SLOT(onEditingClosed()));
ret =
ret &&
connect(m_userTreeWidget,
SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
this,
SLOT(onCurrentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
ret =
ret && connect(m_colorField, SIGNAL(colorChanged(const TPixel32 &, bool)),
this, SLOT(onColorFieldChanged(const TPixel32 &, bool)));
ret = ret && connect(m_hexLineEdit, SIGNAL(editingFinished()), this,
SLOT(onHexChanged()));
ret = ret &&
connect(m_unsColorButton, SIGNAL(pressed()), this, SLOT(onDeselect()));
ret = ret &&
connect(m_addColorButton, SIGNAL(pressed()), this, SLOT(onAddColor()));
ret = ret &&
connect(m_delColorButton, SIGNAL(pressed()), this, SLOT(onDelColor()));
ret =
ret && connect(m_importButton, SIGNAL(pressed()), this, SLOT(onImport()));
ret =
ret && connect(m_exportButton, SIGNAL(pressed()), this, SLOT(onExport()));
ret = ret && connect(okButton, SIGNAL(pressed()), this, SLOT(onOK()));
ret = ret && connect(applyButton, SIGNAL(pressed()), this, SLOT(onApply()));
ret = ret && connect(closeButton, SIGNAL(pressed()), this, SLOT(close()));
assert(ret);
}
//-----------------------------------------------------------------------------
QTreeWidgetItem *HexColorNamesEditor::addEntry(QTreeWidget *tree,
const QString &name,
const QString &hex,
bool editable) {
TPixel pixel = TPixel(0, 0, 0);
HexColorNames::parseHex(hex, pixel);
QPixmap pixm(16, 16);
pixm.fill(QColor(pixel.r, pixel.g, pixel.b, pixel.m));
QTreeWidgetItem *treeItem = new QTreeWidgetItem(tree);
treeItem->setText(0, name);
treeItem->setIcon(1, QIcon(pixm));
treeItem->setText(1, hex);
if (!editable)
treeItem->setFlags(treeItem->flags() & ~Qt::ItemIsSelectable);
else
treeItem->setFlags(treeItem->flags() | Qt::ItemIsEditable);
return treeItem;
}
//-----------------------------------------------------------------------------
bool HexColorNamesEditor::updateUserHexEntry(QTreeWidgetItem *treeItem,
const TPixel32 &color) {
if (treeItem) {
QPixmap pixm(16, 16);
pixm.fill(QColor(color.r, color.g, color.b, color.m));
treeItem->setIcon(1, QIcon(pixm));
treeItem->setText(1, HexColorNames::generateHex(color));
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool HexColorNamesEditor::nameValid(const QString& name) {
if (name.isEmpty()) return false;
return name.count(QRegExp("[\\\\#<>\"']")) == 0;
}
//-----------------------------------------------------------------------------
bool HexColorNamesEditor::nameExists(const QString &name,
QTreeWidgetItem *self) {
for (int i = 0; i < m_userTreeWidget->topLevelItemCount(); ++i) {
QTreeWidgetItem *item = m_userTreeWidget->topLevelItem(i);
if (item == self) continue;
if (name.compare(item->text(0), Qt::CaseInsensitive) == 0) return true;
}
return false;
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::deselectItem(bool treeFocus) {
if (m_newEntry) return;
m_userTreeWidget->setCurrentItem(nullptr);
if (treeFocus) m_userTreeWidget->setFocus();
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::deleteCurrentItem(bool deselect) {
if (m_newEntry) return;
QTreeWidgetItem *treeItem = m_userTreeWidget->currentItem();
if (treeItem) delete treeItem;
m_selectedItem = nullptr;
if (deselect) m_userTreeWidget->setCurrentItem(nullptr);
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::populateMainList(bool reload) {
HexColorNames::loadMainFile(reload);
HexColorNames::iterator it;
m_mainTreeWidget->clear();
for (it = HexColorNames::beginMain(); it != HexColorNames::endMain(); ++it) {
addEntry(m_mainTreeWidget, it.name(), it.value(), false);
}
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::populateUserList(bool reload) {
HexColorNames::loadUserFile(reload);
HexColorNames::iterator it;
m_userTreeWidget->clear();
for (it = HexColorNames::beginUser(); it != HexColorNames::endUser(); ++it) {
if (!nameExists(it.name(), nullptr))
addEntry(m_userTreeWidget, it.name(), it.value(), true);
}
m_userTreeWidget->sortItems(0, Qt::SortOrder::AscendingOrder);
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::showEvent(QShowEvent *e) {
populateUserList(false);
deselectItem(false);
m_delColorButton->setEnabled(false);
m_unsColorButton->setEnabled(false);
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::keyPressEvent(QKeyEvent *event) {
// Blocking dialog default actions is actually desirable
// for example when user press Esc or Enter twice while
// editing it might close the dialog by accident.
if (!m_userTreeWidget->hasFocus()) return;
switch (event->key()) {
case Qt::Key_F5:
populateMainList(true);
populateUserList(true);
m_mainTreeWidget->update();
m_userTreeWidget->update();
break;
case Qt::Key_Escape:
deselectItem(true);
break;
case Qt::Key_Delete:
deleteCurrentItem(false);
break;
case Qt::Key_Insert:
onAddColor();
break;
}
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::focusInEvent(QFocusEvent *e) {
QWidget::focusInEvent(e);
qApp->installEventFilter(this);
}
//--------------------------------------------------------
void HexColorNamesEditor::focusOutEvent(QFocusEvent *e) {
QWidget::focusOutEvent(e);
qApp->removeEventFilter(this);
}
//-----------------------------------------------------------------------------
bool HexColorNamesEditor::eventFilter(QObject *obj, QEvent *e) {
if (e->type() == QEvent::Shortcut ||
e->type() == QEvent::ShortcutOverride) {
e->accept();
return true;
}
return false;
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::onCurrentItemChanged(QTreeWidgetItem *current,
QTreeWidgetItem *previous) {
m_selectedItem = current;
m_delColorButton->setEnabled(current);
m_unsColorButton->setEnabled(current);
if (!current) return;
m_selectedName = current->text(0);
m_selectedHex = current->text(1);
m_selectedColn = 0;
// Modify color field
TPixel pixel(0, 0, 0);
if (HexColorNames::parseHex(m_selectedHex, pixel)) {
m_colorField->setColor(pixel);
m_hexLineEdit->setColor(pixel);
}
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::onEditingStarted(const QModelIndex &modelIndex) {
QTreeWidgetItem *item = (QTreeWidgetItem *)modelIndex.internalPointer();
int column = modelIndex.column();
onItemStarted(item, column);
}
void HexColorNamesEditor::onEditingFinished(const QModelIndex &modelIndex) {
QTreeWidgetItem *item = (QTreeWidgetItem *)modelIndex.internalPointer();
int column = modelIndex.column();
onItemFinished(item, column);
}
void HexColorNamesEditor::onEditingClosed() {
onItemFinished(m_selectedItem, m_selectedColn);
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::onItemStarted(QTreeWidgetItem *item, int column) {
m_selectedName = item->text(0);
m_selectedHex = item->text(1);
m_selectedColn = 0;
m_selectedItem = item;
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::onItemFinished(QTreeWidgetItem *item, int column) {
if (!m_selectedItem || !item) return;
m_delColorButton->setEnabled(true);
m_unsColorButton->setEnabled(true);
try {
if (m_selectedItem == item) {
QString text = item->text(column);
if (column == 0) {
// Edit Name
static QRegExp space("\\s");
text.remove(space);
text = text.toLower();
if (text.isEmpty()) throw "";
if (!nameValid(text))
throw "Color name is not valid.\nFollowing characters can't be used: \\ # < > \" '";
if (nameExists(text, item)) throw "Color name already exists.\nPlease use another name.";
item->setText(0, text);
m_userTreeWidget->sortItems(0, Qt::SortOrder::AscendingOrder);
} else {
// Edit Hex
TPixel pixel;
if (HexColorNames::parseHex(text, pixel)) {
m_colorField->setColor(pixel);
m_hexLineEdit->setColor(pixel);
updateUserHexEntry(item, pixel);
} else {
item->setText(1, m_selectedHex);
}
}
}
} catch (const char *reason) {
m_selectedItem = nullptr;
if (m_selectedName.isEmpty()) {
delete item;
} else {
item->setText(0, m_selectedName);
}
if (strlen(reason)) DVGui::warning(tr(reason));
} catch (...) {
m_selectedItem = nullptr;
delete item;
}
m_newEntry = false;
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::onColorFieldChanged(const TPixel32 &color,
bool isDragging) {
QTreeWidgetItem *treeItem = m_userTreeWidget->currentItem();
if (updateUserHexEntry(treeItem, color)) {
m_userTreeWidget->setCurrentItem(treeItem);
}
m_hexLineEdit->setColor(color);
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::onHexChanged() {
QTreeWidgetItem *treeItem = m_userTreeWidget->currentItem();
if (m_hexLineEdit->fromText(m_hexLineEdit->text())) {
TPixel pixel = m_hexLineEdit->getColor();
updateUserHexEntry(treeItem, pixel);
m_colorField->setColor(pixel);
}
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::onAddColor() {
if (m_newEntry) return;
TPixel pixel = m_colorField->getColor();
QString hex = HexColorNames::generateHex(pixel);
QTreeWidgetItem *treeItem = addEntry(m_userTreeWidget, "", hex, true);
m_userTreeWidget->setCurrentItem(treeItem);
onItemStarted(treeItem, 0);
m_newEntry = true;
m_userTreeWidget->editItem(treeItem, 0);
m_delColorButton->setEnabled(false);
m_unsColorButton->setEnabled(false);
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::onDelColor() {
if (m_newEntry) return;
deleteCurrentItem(true);
m_userTreeWidget->setFocus();
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::onDeselect() { deselectItem(false); }
//-----------------------------------------------------------------------------
void HexColorNamesEditor::onImport() {
QString fileName = QFileDialog::getOpenFileName(
this, tr("Open Color Names"), QString(),
tr("Text or XML (*.txt *.xml);;Text files (*.txt);;XML files (*.xml)"));
if (fileName.isEmpty()) return;
QMessageBox::StandardButton ret = QMessageBox::question(
this, tr("Hex Color Names Import"), tr("Do you want to merge with existing entries?"),
QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No |
QMessageBox::Cancel));
if (ret == QMessageBox::Cancel) return;
if (!HexColorNames::loadTempFile(TFilePath(fileName))) {
DVGui::warning(tr("Error importing color names XML"));
}
HexColorNames::iterator it;
if (ret == QMessageBox::No) m_userTreeWidget->clear();
for (it = HexColorNames::beginTemp(); it != HexColorNames::endTemp(); ++it) {
if (!nameExists(it.name(), nullptr))
addEntry(m_userTreeWidget, it.name(), it.value(), true);
}
HexColorNames::clearTempEntries();
m_userTreeWidget->sortItems(0, Qt::SortOrder::AscendingOrder);
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::onExport() {
QString fileName = QFileDialog::getSaveFileName(
this, tr("Save Color Names"), QString(),
tr("XML files (*.xml);;Text files (*.txt)"));
if (fileName.isEmpty()) return;
HexColorNames::clearTempEntries();
for (int i = 0; i < m_userTreeWidget->topLevelItemCount(); ++i) {
QTreeWidgetItem *item = m_userTreeWidget->topLevelItem(i);
HexColorNames::setTempEntry(item->text(0), item->text(1));
}
if (!HexColorNames::saveTempFile(TFilePath(fileName))) {
DVGui::warning(tr("Error exporting color names XML"));
}
}
//-----------------------------------------------------------------------------
void HexColorNamesEditor::onOK() {
onApply();
close();
};
void HexColorNamesEditor::onApply() {
HexColorNames::clearUserEntries();
for (int i = 0; i < m_userTreeWidget->topLevelItemCount(); ++i) {
QTreeWidgetItem *item = m_userTreeWidget->topLevelItem(i);
HexColorNames::setUserEntry(item->text(0), item->text(1));
}
HexColorNames::saveUserFile();
HexColorNames::instance()->emitChanged();
bool oldAutoCompState = (HexLineEditAutoComplete != 0);
bool newAutoCompState = m_autoCompleteCb->isChecked();
if (oldAutoCompState != newAutoCompState) {
HexLineEditAutoComplete = newAutoCompState ? 1 : 0;
HexColorNames::instance()->emitAutoComplete(newAutoCompState);
}
};
//-----------------------------------------------------------------------------

View file

@ -41,7 +41,6 @@
#include "tvectorrenderdata.h"
#include "tsimplecolorstyles.h"
#include "tvectorbrushstyle.h"
#include "tenv.h"
// Qt includes
#include <QHBoxLayout>
@ -71,212 +70,6 @@
using namespace StyleEditorGUI;
using namespace DVGui;
//*****************************************************************************
// Hex line editor
//*****************************************************************************
#define COLORNAMES_FILE "colornames.txt"
QMap<QString, QString> HexLineEdit::s_defcolornames;
QMap<QString, QString> 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<QString, QString>::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<QString, QString> &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
//*****************************************************************************
@ -4238,6 +4031,7 @@ StyleEditor::StyleEditor(PaletteController *paletteController, QWidget *parent)
, m_enabledFirstAndLastTab(false)
, m_oldStyle(0)
, m_parent(parent)
, m_hexColorNamesEditor(0)
, m_editedStyle(0) {
// TOGLIERE
TFilePath libraryPath = ToonzFolder::getLibraryFolder();
@ -4411,8 +4205,6 @@ QFrame *StyleEditor::createBottomWidget() {
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);
@ -4447,6 +4239,10 @@ QFrame *StyleEditor::createBottomWidget() {
m_plainColorPage->m_hsvFrame->setVisible(false);
m_plainColorPage->m_rgbFrame->setVisible(false);
menu->addSeparator();
m_hexEditorAction = new QAction(tr("Hex Color Names..."), this);
menu->addAction(m_hexEditorAction);
QToolButton *toolButton = new QToolButton(this);
toolButton->setIcon(createQIcon("menu"));
toolButton->setFixedSize(22, 22);
@ -4546,6 +4342,8 @@ QFrame *StyleEditor::createBottomWidget() {
SLOT(setVisible(bool)));
ret = ret && connect(m_hexLineEdit, SIGNAL(editingFinished()), this,
SLOT(onHexChanged()));
ret = ret && connect(m_hexEditorAction, SIGNAL(triggered()), this,
SLOT(onHexEditor()));
ret = ret && connect(m_toggleOrientationAction, SIGNAL(triggered()),
m_plainColorPage, SLOT(toggleOrientation()));
ret = ret && connect(m_toggleOrientationAction, SIGNAL(triggered()), this,
@ -5568,6 +5366,15 @@ void StyleEditor::onHexChanged() {
//-----------------------------------------------------------------------------
void StyleEditor::onHexEditor() {
if (!m_hexColorNamesEditor) {
m_hexColorNamesEditor = new DVGui::HexColorNamesEditor(this);
}
m_hexColorNamesEditor->show();
}
//-----------------------------------------------------------------------------
void StyleEditor::onHexEdited(const QString &text) {
m_hsvAction->setDisabled(true);
m_alphaAction->setDisabled(true);