diff --git a/libs/libkis/PaletteView.cpp b/libs/libkis/PaletteView.cpp index bb29ffffb7..471c0fbeb7 100644 --- a/libs/libkis/PaletteView.cpp +++ b/libs/libkis/PaletteView.cpp @@ -1,84 +1,84 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include struct PaletteView::Private { KisPaletteModel *model = 0; KisPaletteView *widget = 0; bool allowPaletteModification = true; }; PaletteView::PaletteView(QWidget *parent) : QWidget(parent), d(new Private) { d->widget = new KisPaletteView(this); d->model = new KisPaletteModel(); d->widget->setPaletteModel(d->model); this->setLayout(new QVBoxLayout()); this->layout()->addWidget(d->widget); //forward signals. connect(d->widget, SIGNAL(entrySelected(KisSwatch)), this, SIGNAL(entrySelectedForeGround(KisSwatch))); connect(d->widget, SIGNAL(entrySelectedBackGround(KisSwatch)), this, SIGNAL(entrySelectedBackGround(KisSwatch))); } PaletteView::~PaletteView() { delete d->model; } void PaletteView::setPalette(Palette *palette) { - d->model->setColorSet(palette->colorSet()); + d->model->setPalette(palette->colorSet()); d->widget->setPaletteModel(d->model); } bool PaletteView::addEntryWithDialog(ManagedColor *color) { if (d->model->colorSet()) { return d->widget->addEntryWithDialog(color->color()); } return false; } bool PaletteView::addGroupWithDialog() { if (d->model->colorSet()) { d->widget->addGroupWithDialog(); return false; } return false; } bool PaletteView::removeSelectedEntryWithDialog() { if (d->model->colorSet()) { return d->widget->removeEntryWithDialog(d->widget->currentIndex()); } return false; } void PaletteView::trySelectClosestColor(ManagedColor *color) { d->widget->selectClosestColor(color->color()); } diff --git a/libs/widgets/KisDlgInternalColorSelector.cpp b/libs/widgets/KisDlgInternalColorSelector.cpp index f54ed68b69..c6b9fea272 100644 --- a/libs/widgets/KisDlgInternalColorSelector.cpp +++ b/libs/widgets/KisDlgInternalColorSelector.cpp @@ -1,347 +1,344 @@ /* * Copyright (C) Wolthera van Hovell tot Westerflier , (C) 2016 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include "KoColorSpaceRegistry.h" #include #include #include #include #include #include #include "kis_signal_compressor.h" #include "KoColorDisplayRendererInterface.h" #include "kis_spinbox_color_selector.h" #include "KisDlgInternalColorSelector.h" #include "ui_WdgDlgInternalColorSelector.h" #include "kis_config_notifier.h" #include "kis_color_input.h" #include "kis_icon_utils.h" #include "squeezedcombobox.h" std::function KisDlgInternalColorSelector::s_screenColorPickerFactory = 0; struct KisDlgInternalColorSelector::Private { bool allowUpdates = true; KoColor currentColor; KoColor previousColor; KoColor sRGB = KoColor(KoColorSpaceRegistry::instance()->rgb8()); const KoColorSpace *currentColorSpace; bool lockUsedCS = false; bool chooseAlpha = false; KisSignalCompressor *compressColorChanges; const KoColorDisplayRendererInterface *displayRenderer; KisHexColorInput *hexColorInput = 0; KisPaletteModel *paletteModel = 0; KisPaletteListWidget *paletteChooser = 0; KisScreenColorPickerBase *screenColorPicker = 0; }; KisDlgInternalColorSelector::KisDlgInternalColorSelector(QWidget *parent, KoColor color, Config config, const QString &caption, const KoColorDisplayRendererInterface *displayRenderer) : QDialog(parent) , m_d(new Private) { setModal(config.modal); setFocusPolicy(Qt::ClickFocus); m_ui = new Ui_WdgDlgInternalColorSelector(); m_ui->setupUi(this); setWindowTitle(caption); m_d->currentColor = color; m_d->currentColorSpace = m_d->currentColor.colorSpace(); m_d->displayRenderer = displayRenderer; m_ui->spinboxselector->slotSetColor(color); connect(m_ui->spinboxselector, SIGNAL(sigNewColor(KoColor)), this, SLOT(slotColorUpdated(KoColor))); m_ui->visualSelector->slotSetColor(color); m_ui->visualSelector->setDisplayRenderer(displayRenderer); m_ui->visualSelector->setConfig(false, config.modal); if (config.visualColorSelector) { connect(m_ui->visualSelector, SIGNAL(sigNewColor(KoColor)), this, SLOT(slotColorUpdated(KoColor))); connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), m_ui->visualSelector, SLOT(configurationChanged())); } else { m_ui->visualSelector->hide(); } m_d->paletteChooser = new KisPaletteListWidget(this); m_d->paletteModel = new KisPaletteModel(this); m_ui->bnPaletteChooser->setIcon(KisIconUtils::loadIcon("hi16-palette_library")); m_ui->paletteBox->setPaletteModel(m_d->paletteModel); m_ui->paletteBox->setDisplayRenderer(displayRenderer); - m_ui->cmbNameList->setPaletteModel(m_d->paletteModel); + m_ui->cmbNameList->setCompanionView(m_ui->paletteBox); connect(m_d->paletteChooser, SIGNAL(sigPaletteSelected(KoColorSet*)), this, SLOT(slotChangePalette(KoColorSet*))); connect(m_ui->cmbNameList, SIGNAL(sigColorSelected(KoColor)), SLOT(slotColorUpdated(KoColor))); - connect(m_ui->paletteBox, SIGNAL(sigIndexSelected(QModelIndex)), - m_ui->cmbNameList, SLOT(slotSwatchSelected(QModelIndex))); - // For some bizare reason, the modal dialog doesn't like having the colorset set, so let's not. if (config.paletteBox) { //TODO: Add disable signal as well. Might be not necessary...? KConfigGroup cfg(KSharedConfig::openConfig()->group("")); QString paletteName = cfg.readEntry("internal_selector_active_color_set", QString()); KoResourceServer* rServer = KoResourceServerProvider::instance()->paletteServer(); KoColorSet *savedPal = rServer->resourceByName(paletteName); if (savedPal) { this->slotChangePalette(savedPal); } else { if (rServer->resources().count()) { savedPal = rServer->resources().first(); if (savedPal) { this->slotChangePalette(savedPal); } } } connect(m_ui->paletteBox, SIGNAL(sigColorSelected(KoColor)), this, SLOT(slotColorUpdated(KoColor))); m_ui->bnPaletteChooser->setPopupWidget(m_d->paletteChooser); } else { m_ui->paletteBox->setEnabled(false); m_ui->cmbNameList->setEnabled(false); m_ui->bnPaletteChooser->setEnabled(false); } if (config.prevNextButtons) { m_ui->currentColor->setColor(m_d->currentColor); m_ui->currentColor->setDisplayRenderer(displayRenderer); m_ui->previousColor->setColor(m_d->currentColor); m_ui->previousColor->setDisplayRenderer(displayRenderer); connect(m_ui->previousColor, SIGNAL(triggered(KoColorPatch*)), SLOT(slotSetColorFromPatch(KoColorPatch*))); } else { m_ui->currentColor->hide(); m_ui->previousColor->hide(); } if (config.hexInput) { m_d->sRGB.fromKoColor(m_d->currentColor); m_d->hexColorInput = new KisHexColorInput(this, &m_d->sRGB); m_d->hexColorInput->update(); connect(m_d->hexColorInput, SIGNAL(updated()), SLOT(slotSetColorFromHex())); m_ui->rightPane->addWidget(m_d->hexColorInput); m_d->hexColorInput->setToolTip(i18n("This is a hexcode input, for webcolors. It can only get colors in the sRGB space.")); } // screen color picker is in kritaui, so a dependency inversion is used to get it m_ui->screenColorPickerWidget->setLayout(new QHBoxLayout(m_ui->screenColorPickerWidget)); if (s_screenColorPickerFactory) { m_d->screenColorPicker = s_screenColorPickerFactory(m_ui->screenColorPickerWidget); m_ui->screenColorPickerWidget->layout()->addWidget(m_d->screenColorPicker); if (config.screenColorPicker) { connect(m_d->screenColorPicker, SIGNAL(sigNewColorPicked(KoColor)),this, SLOT(slotColorUpdated(KoColor))); } else { m_d->screenColorPicker->hide(); } } connect(this, SIGNAL(signalForegroundColorChosen(KoColor)), this, SLOT(slotLockSelector())); m_d->compressColorChanges = new KisSignalCompressor(100 /* ms */, KisSignalCompressor::POSTPONE, this); connect(m_d->compressColorChanges, SIGNAL(timeout()), this, SLOT(endUpdateWithNewColor())); connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(this, SIGNAL(finished(int)), SLOT(slotFinishUp())); } KisDlgInternalColorSelector::~KisDlgInternalColorSelector() { delete m_ui; } void KisDlgInternalColorSelector::slotColorUpdated(KoColor newColor) { //if the update did not come from this selector... if (m_d->allowUpdates || QObject::sender() == this->parent()) { if (m_d->lockUsedCS){ newColor.convertTo(m_d->currentColorSpace); m_d->currentColor = newColor; } else { m_d->currentColor = newColor; } updateAllElements(QObject::sender()); } } void KisDlgInternalColorSelector::slotSetColorFromPatch(KoColorPatch *patch) { slotColorUpdated(patch->color()); } void KisDlgInternalColorSelector::colorSpaceChanged(const KoColorSpace *cs) { if (cs == m_d->currentColorSpace) { return; } m_d->currentColorSpace = KoColorSpaceRegistry::instance()->colorSpace(cs->colorModelId().id(), cs->colorDepthId().id(), cs->profile()); m_ui->spinboxselector->slotSetColorSpace(m_d->currentColorSpace); m_ui->visualSelector->slotsetColorSpace(m_d->currentColorSpace); } void KisDlgInternalColorSelector::lockUsedColorSpace(const KoColorSpace *cs) { colorSpaceChanged(cs); m_d->lockUsedCS = true; } void KisDlgInternalColorSelector::setDisplayRenderer(const KoColorDisplayRendererInterface *displayRenderer) { if (displayRenderer) { m_d->displayRenderer = displayRenderer; m_ui->visualSelector->setDisplayRenderer(displayRenderer); m_ui->currentColor->setDisplayRenderer(displayRenderer); m_ui->previousColor->setDisplayRenderer(displayRenderer); // m_ui->paletteBox->setDisplayRenderer(displayRenderer); } else { m_d->displayRenderer = KoDumbColorDisplayRenderer::instance(); } } KoColor KisDlgInternalColorSelector::getModalColorDialog(const KoColor color, QWidget* parent, QString caption) { Config config = Config(); KisDlgInternalColorSelector dialog(parent, color, config, caption); dialog.setPreviousColor(color); dialog.exec(); return dialog.getCurrentColor(); } KoColor KisDlgInternalColorSelector::getCurrentColor() { return m_d->currentColor; } void KisDlgInternalColorSelector::chooseAlpha(bool chooseAlpha) { m_d->chooseAlpha = chooseAlpha; } void KisDlgInternalColorSelector::slotConfigurationChanged() { //m_d->canvas->displayColorConverter()-> //slotColorSpaceChanged(m_d->canvas->image()->colorSpace()); } void KisDlgInternalColorSelector::slotLockSelector() { m_d->allowUpdates = false; } void KisDlgInternalColorSelector::setPreviousColor(KoColor c) { m_d->previousColor = c; } void KisDlgInternalColorSelector::reject() { slotColorUpdated(m_d->previousColor); QDialog::reject(); } void KisDlgInternalColorSelector::updateAllElements(QObject *source) { //update everything!!! if (source != m_ui->spinboxselector) { m_ui->spinboxselector->slotSetColor(m_d->currentColor); } if (source != m_ui->visualSelector) { m_ui->visualSelector->slotSetColor(m_d->currentColor); } if (source != m_d->hexColorInput) { m_d->sRGB.fromKoColor(m_d->currentColor); m_d->hexColorInput->update(); } if (source != m_ui->paletteBox) { m_ui->paletteBox->selectClosestColor(m_d->currentColor); } m_ui->previousColor->setColor(m_d->previousColor); m_ui->currentColor->setColor(m_d->currentColor); if (source != this->parent()) { emit(signalForegroundColorChosen(m_d->currentColor)); m_d->compressColorChanges->start(); } if (m_d->screenColorPicker) { m_d->screenColorPicker->updateIcons(); } } void KisDlgInternalColorSelector::endUpdateWithNewColor() { m_d->allowUpdates = true; } void KisDlgInternalColorSelector::focusInEvent(QFocusEvent *) { //setPreviousColor(); } void KisDlgInternalColorSelector::slotFinishUp() { setPreviousColor(m_d->currentColor); KConfigGroup cfg(KSharedConfig::openConfig()->group("")); if (m_d->paletteModel) { if (m_d->paletteModel->colorSet()) { cfg.writeEntry("internal_selector_active_color_set", m_d->paletteModel->colorSet()->name()); } } } void KisDlgInternalColorSelector::slotSetColorFromHex() { slotColorUpdated(m_d->sRGB); } void KisDlgInternalColorSelector::slotChangePalette(KoColorSet *set) { if (!set) { return; } - m_d->paletteModel->setColorSet(set); + m_d->paletteModel->setPalette(set); } void KisDlgInternalColorSelector::showEvent(QShowEvent *event) { updateAllElements(0); QDialog::showEvent(event); } diff --git a/libs/widgets/KisPaletteComboBox.cpp b/libs/widgets/KisPaletteComboBox.cpp index ff0381929a..f3c03a3477 100644 --- a/libs/widgets/KisPaletteComboBox.cpp +++ b/libs/widgets/KisPaletteComboBox.cpp @@ -1,114 +1,158 @@ +/* + * Copyright (c) 2018 Michael Zhou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + // Qt #include #include #include // STL #include +#include "kis_palette_view.h" #include "KisPaletteComboBox.h" KisPaletteComboBox::KisPaletteComboBox(QWidget *parent) : QComboBox(parent) , m_completer(new QCompleter(QComboBox::model(), this)) , m_model(Q_NULLPTR) { m_completer->setCompletionMode(QCompleter::PopupCompletion); m_completer->setCaseSensitivity(Qt::CaseInsensitive); m_completer->setFilterMode(Qt::MatchContains); setCompleter(m_completer.data()); - connect(this, SIGNAL(currentIndexChanged(int)), SLOT(slotIndexSelected(int))); + connect(this, SIGNAL(currentIndexChanged(int)), SLOT(slotIndexUpdated(int))); } KisPaletteComboBox::~KisPaletteComboBox() { } void KisPaletteComboBox::setPaletteModel(const KisPaletteModel *paletteModel) { if (!m_model.isNull()) { m_model->disconnect(this); } m_model = paletteModel; if (m_model.isNull()) { return; } slotPaletteChanged(); - connect(m_model, SIGNAL(modelReset()), + connect(m_model, SIGNAL(sigPaletteChanged()), SLOT(slotPaletteChanged())); - connect(m_model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex&, const QVector &)), + connect(m_model, SIGNAL(sigPaletteModified()), SLOT(slotPaletteChanged())); } +void KisPaletteComboBox::setCompanionView(KisPaletteView *view) +{ + if (!m_view.isNull()) { + m_view->disconnect(this); + disconnect(m_view.data()); + } + m_view = view; + setPaletteModel(view->paletteModel()); + connect(view, SIGNAL(sigIndexSelected(QModelIndex)), + SLOT(slotSwatchSelected(QModelIndex))); + connect(this, SIGNAL(sigColorSelected(KoColor)), + view, SLOT(slotFGColorChanged(KoColor))); +} + void KisPaletteComboBox::slotPaletteChanged() { if (QPointer(m_model->colorSet()).isNull()) { return; } - blockSignals(true); // avoid changing fg color clear(); m_groupMapMap.clear(); m_idxSwatchMap.clear(); for (const QString &groupName : m_model->colorSet()->getGroupNames()) { QVector infoList; PosIdxMapType posIdxMap; const KisSwatchGroup *group = m_model->colorSet()->getGroup(groupName); for (const SwatchInfoType &info : group->infoList()) { infoList.append(info); } std::sort(infoList.begin(), infoList.end(), swatchInfoLess); for (const SwatchInfoType &info : infoList) { const KisSwatch &swatch = info.swatch; QString name = swatch.name(); if (!swatch.id().isEmpty()){ name = swatch.id() + " - " + swatch.name(); } addItem(QIcon(createColorSquare(swatch)), name); posIdxMap[SwatchPosType(info.column, info.row)] = count() - 1; m_idxSwatchMap.push_back(swatch); } m_groupMapMap[group->name()] = posIdxMap; } - setCurrentIndex(0); + if (!m_view.isNull()) { + setCurrentIndex(0); + } + QModelIndex idx = m_view->currentIndex(); + if (!idx.isValid()) { return; } + if (!qvariant_cast(idx.data(KisPaletteModel::IsGroupNameRole))) { return; } + if (!qvariant_cast(idx.data(KisPaletteModel::CheckSlotRole))) { return; } + + QString groupName = qvariant_cast(idx.data(KisPaletteModel::GroupNameRole)); + int rowInGroup = qvariant_cast(idx.data(KisPaletteModel::RowInGroupRole)); + + blockSignals(true); // this is a passive selection; this shouldn't make others change + setCurrentIndex(m_groupMapMap[groupName][SwatchPosType(idx.column(), rowInGroup)]); blockSignals(false); } bool KisPaletteComboBox::swatchInfoLess(const SwatchInfoType &first, const SwatchInfoType &second) { return first.swatch.name() < second.swatch.name(); } QPixmap KisPaletteComboBox::createColorSquare(const KisSwatch &swatch) const { QPixmap colorSquare(32, 32); if (swatch.spotColor()) { QImage img = QImage(32, 32, QImage::Format_ARGB32); QPainter circlePainter; img.fill(Qt::transparent); circlePainter.begin(&img); QBrush brush = QBrush(Qt::SolidPattern); brush.setColor(swatch.color().toQColor()); circlePainter.setBrush(brush); QPen pen = circlePainter.pen(); pen.setColor(Qt::transparent); pen.setWidth(0); circlePainter.setPen(pen); circlePainter.drawEllipse(0, 0, 32, 32); circlePainter.end(); colorSquare = QPixmap::fromImage(img); } else { colorSquare.fill(swatch.color().toQColor()); } return colorSquare; } void KisPaletteComboBox::slotSwatchSelected(const QModelIndex &index) { QString gName = qvariant_cast(index.data(KisPaletteModel::GroupNameRole)); int rowInGroup = qvariant_cast(index.data(KisPaletteModel::RowInGroupRole)); setCurrentIndex(m_groupMapMap[gName][SwatchPosType(index.column(), rowInGroup)]); } -void KisPaletteComboBox::slotIndexSelected(int idx) +void KisPaletteComboBox::slotIndexUpdated(int idx) { if (idx >= 0 && idx < m_idxSwatchMap.size()) { emit sigColorSelected(m_idxSwatchMap[idx].color()); } } diff --git a/libs/widgets/KisPaletteComboBox.h b/libs/widgets/KisPaletteComboBox.h index 7bfa1942a5..fbcf12e0cf 100644 --- a/libs/widgets/KisPaletteComboBox.h +++ b/libs/widgets/KisPaletteComboBox.h @@ -1,53 +1,77 @@ -#ifndef KISPALETTECOLORNAMELIST_H -#define KISPALETTECOLORNAMELIST_H +/* + * Copyright (c) 2018 Michael Zhou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KISPALETTECOMBOBOX_H +#define KISPALETTECOMBOBOX_H #include "kritawidgets_export.h" #include #include #include #include #include #include #include #include class KisPaletteView; +/** + * @brief The KisPaletteComboBox class + * A combobox used with KisPaletteView + * + */ class KRITAWIDGETS_EXPORT KisPaletteComboBox : public QComboBox { Q_OBJECT private /* typedef */: typedef KisSwatchGroup::SwatchInfo SwatchInfoType; typedef QPair SwatchPosType; // first is column #, second is row # typedef QHash PosIdxMapType; public: explicit KisPaletteComboBox(QWidget *parent = Q_NULLPTR); ~KisPaletteComboBox(); Q_SIGNALS: void sigColorSelected(const KoColor &); public /* methods */: - void setPaletteModel(const KisPaletteModel *); void setCompanionView(KisPaletteView *); private Q_SLOTS: + void setPaletteModel(const KisPaletteModel *); void slotPaletteChanged(); void slotSwatchSelected(const QModelIndex &index); - void slotIndexSelected(int); + void slotIndexUpdated(int); private /* methods */: QPixmap createColorSquare(const KisSwatch &swatch) const; static bool swatchInfoLess(const SwatchInfoType &, const SwatchInfoType &); private /* member variables */: QScopedPointer m_completer; QPointer m_model; + QPointer m_view; QHash m_groupMapMap; QVector m_idxSwatchMap; }; -#endif // KISPALETTECOLORNAMELIST_H +#endif // KISPALETTECOMBOBOX_H diff --git a/libs/widgets/KisPaletteModel.cpp b/libs/widgets/KisPaletteModel.cpp index 00c714619f..dc0227b009 100644 --- a/libs/widgets/KisPaletteModel.cpp +++ b/libs/widgets/KisPaletteModel.cpp @@ -1,484 +1,483 @@ /* * Copyright (c) 2013 Sven Langkamp * Copyright (c) 2018 Michael Zhou * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "KisPaletteModel.h" #include #include #include #include #include #include #include #include #include KisPaletteModel::KisPaletteModel(QObject* parent) : QAbstractTableModel(parent) , m_colorSet(0) , m_displayRenderer(KoDumbColorDisplayRenderer::instance()) { - connect(this, SIGNAL(sigPaletteModifed()), SLOT(slotPaletteModified())); + connect(this, SIGNAL(sigPaletteModified()), SLOT(slotPaletteModified())); } KisPaletteModel::~KisPaletteModel() { } QVariant KisPaletteModel::data(const QModelIndex& index, int role) const { bool groupNameRow = m_groupNameRows.contains(index.row()); if (role == IsGroupNameRole) { return groupNameRow; } if (groupNameRow) { return dataForGroupNameRow(index, role); } else { return dataForSwatch(index, role); } } int KisPaletteModel::rowCount(const QModelIndex& /*parent*/) const { if (!m_colorSet) return 0; return m_colorSet->rowCount() // count of color rows + m_groupNameRows.size() // rows for names - 1; // global doesn't have a name } int KisPaletteModel::columnCount(const QModelIndex& /*parent*/) const { if (m_colorSet && m_colorSet->columnCount() > 0) { return m_colorSet->columnCount(); } if (!m_colorSet) { return 0; } return 16; } Qt::ItemFlags KisPaletteModel::flags(const QModelIndex& index) const { if (index.isValid()) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; } return Qt::ItemIsDropEnabled; } QModelIndex KisPaletteModel::index(int row, int column, const QModelIndex& parent) const { Q_UNUSED(parent); Q_ASSERT(m_colorSet); int groupNameRow = groupNameRowForRow(row); KisSwatchGroup *group = m_colorSet->getGroup(m_groupNameRows[groupNameRow]); Q_ASSERT(group); return createIndex(row, column, group); } -void KisPaletteModel::setColorSet(KoColorSet* colorSet) +void KisPaletteModel::setPalette(KoColorSet* palette) { beginResetModel(); m_groupNameRows.clear(); - m_colorSet = colorSet; - if (colorSet) { + m_colorSet = palette; + if (palette) { int row = -1; for (const QString &groupName : m_colorSet->getGroupNames()) { m_groupNameRows[row] = groupName; row += m_colorSet->getGroup(groupName)->rowCount(); row += 1; // row for group name } } endResetModel(); - emit sigPaletteChanged(); } KoColorSet* KisPaletteModel::colorSet() const { return m_colorSet; } int KisPaletteModel::rowNumberInGroup(int rowInModel) const { if (m_groupNameRows.contains(rowInModel)) { return -1; } for (auto it = m_groupNameRows.keys().rbegin(); it != m_groupNameRows.keys().rend(); it++) { if (*it < rowInModel) { return rowInModel - *it - 1; } } return rowInModel; } bool KisPaletteModel::addEntry(const KisSwatch &entry, const QString &groupName) { beginResetModel(); m_colorSet->add(entry, groupName); endResetModel(); if (m_colorSet->isGlobal()) { m_colorSet->save(); } - emit sigPaletteModifed(); + emit sigPaletteModified(); return true; } bool KisPaletteModel::removeEntry(const QModelIndex &index, bool keepColors) { if (!qvariant_cast(data(index, IsGroupNameRole))) { static_cast(index.internalPointer())->removeEntry(index.column(), rowNumberInGroup(index.row())); emit dataChanged(index, index); } else { int groupNameRow = groupNameRowForRow(index.row()); QString groupName = m_groupNameRows[groupNameRow]; removeGroup(groupName, keepColors); } - emit sigPaletteModifed(); + emit sigPaletteModified(); return true; } void KisPaletteModel::removeGroup(const QString &groupName, bool keepColors) { beginResetModel(); m_colorSet->removeGroup(groupName, keepColors); m_groupNameRows.clear(); int row = -1; for (const QString &groupName : m_colorSet->getGroupNames()) { m_groupNameRows[row] = groupName; row += m_colorSet->getGroup(groupName)->rowCount(); row += 1; // row for group name } endResetModel(); } bool KisPaletteModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { Q_UNUSED(row); Q_UNUSED(column); if (!data->hasFormat("krita/x-colorsetentry") && !data->hasFormat("krita/x-colorsetgroup")) { return false; } if (action == Qt::IgnoreAction) { return false; } if (data->hasFormat("krita/x-colorsetgroup")) { // dragging group not supported for now /* QByteArray encodedData = data->data("krita/x-colorsetgroup"); QDataStream stream(&encodedData, QIODevice::ReadOnly); while (!stream.atEnd()) { QString groupName; stream >> groupName; QModelIndex index = this->index(endRow, 0); if (index.isValid()) { QStringList entryList = qvariant_cast(index.data(RetrieveEntryRole)); QString groupDroppedOn = QString(); if (!entryList.isEmpty()) { groupDroppedOn = entryList.at(0); } int groupIndex = colorSet()->getGroupNames().indexOf(groupName); beginMoveRows( QModelIndex(), groupIndex, groupIndex, QModelIndex(), endRow); m_colorSet->moveGroup(groupName, groupDroppedOn); m_colorSet->save(); endMoveRows(); ++endRow; } */ return true; } QModelIndex finalIdx = parent; if (!finalIdx.isValid()) { return false; } if (qvariant_cast(finalIdx.data(KisPaletteModel::IsGroupNameRole))) { return true; } QByteArray encodedData = data->data("krita/x-colorsetentry"); QDataStream stream(&encodedData, QIODevice::ReadOnly); while (!stream.atEnd()) { KisSwatch entry; QString name, id; bool spotColor; QString oldGroupName; int oriRow; int oriColumn; QString colorXml; stream >> name >> id >> spotColor >> oriRow >> oriColumn >> oldGroupName >> colorXml; entry.setName(name); entry.setId(id); entry.setSpotColor(spotColor); QDomDocument doc; doc.setContent(colorXml); QDomElement e = doc.documentElement(); QDomElement c = e.firstChildElement(); if (!c.isNull()) { QString colorDepthId = c.attribute("bitdepth", Integer8BitsColorDepthID.id()); entry.setColor(KoColor::fromXML(c, colorDepthId)); } if (action == Qt::MoveAction){ KisSwatchGroup *g = m_colorSet->getGroup(oldGroupName); if (g) { if (qvariant_cast(finalIdx.data(KisPaletteModel::CheckSlotRole))) { g->setEntry(getEntry(finalIdx), oriColumn, oriRow); } else { g->removeEntry(oriColumn, oriRow); } } setEntry(entry, finalIdx); - emit sigPaletteModifed(); + emit sigPaletteModified(); if (m_colorSet->isGlobal()) { m_colorSet->save(); } } } return true; } QMimeData *KisPaletteModel::mimeData(const QModelIndexList &indexes) const { QMimeData *mimeData = new QMimeData(); QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); QModelIndex index = indexes.last(); if (index.isValid() && qvariant_cast(index.data(CheckSlotRole))) { QString mimeTypeName = "krita/x-colorsetentry"; if (qvariant_cast(index.data(IsGroupNameRole))==false) { KisSwatch entry = getEntry(index); QDomDocument doc; QDomElement root = doc.createElement("Color"); root.setAttribute("bitdepth", entry.color().colorSpace()->colorDepthId().id()); doc.appendChild(root); entry.color().toXML(doc, root); stream << entry.name() << entry.id() << entry.spotColor() << rowNumberInGroup(index.row()) << index.column() << qvariant_cast(index.data(GroupNameRole)) << doc.toString(); } else { mimeTypeName = "krita/x-colorsetgroup"; QStringList entryList = qvariant_cast(index.data(RetrieveEntryRole)); QString groupName = QString(); if (!entryList.isEmpty()) { groupName = entryList.at(0); } stream << groupName; } mimeData->setData(mimeTypeName, encodedData); } return mimeData; } QStringList KisPaletteModel::mimeTypes() const { return QStringList() << "krita/x-colorsetentry" << "krita/x-colorsetgroup"; } Qt::DropActions KisPaletteModel::supportedDropActions() const { return Qt::MoveAction; } void KisPaletteModel::setEntry(const KisSwatch &entry, const QModelIndex &index) { KisSwatchGroup *group = static_cast(index.internalPointer()); Q_ASSERT(group); group->setEntry(entry, index.column(), rowNumberInGroup(index.row())); - emit sigPaletteModifed(); + emit sigPaletteModified(); emit dataChanged(index, index); if (m_colorSet->isGlobal()) { m_colorSet->save(); } } bool KisPaletteModel::renameGroup(const QString &groupName, const QString &newName) { beginResetModel(); bool success = m_colorSet->changeGroupName(groupName, newName); for (auto it = m_groupNameRows.begin(); it != m_groupNameRows.end(); it++) { if (it.value() == groupName) { m_groupNameRows[it.key()] = newName; break; } } endResetModel(); - emit sigPaletteModifed(); + emit sigPaletteModified(); return success; } void KisPaletteModel::addGroup(const KisSwatchGroup &group) { beginInsertRows(QModelIndex(), rowCount(), rowCount() + group.rowCount()); m_colorSet->addGroup(group.name()); *m_colorSet->getGroup(group.name()) = group; endInsertColumns(); - emit sigPaletteModifed(); + emit sigPaletteModified(); } void KisPaletteModel::setRowNumber(const QString &groupName, int rowCount) { beginResetModel(); KisSwatchGroup *g = m_colorSet->getGroup(groupName); if (g) { g->setRowCount(rowCount); } endResetModel(); } QVariant KisPaletteModel::dataForGroupNameRow(const QModelIndex &idx, int role) const { KisSwatchGroup *group = static_cast(idx.internalPointer()); Q_ASSERT(group); QString groupName = group->name(); switch (role) { case Qt::ToolTipRole: case Qt::DisplayRole: { return groupName; } case GroupNameRole: { return groupName; } case CheckSlotRole: { return true; } case RowInGroupRole: { return -1; } default: { return QVariant(); } } } QVariant KisPaletteModel::dataForSwatch(const QModelIndex &idx, int role) const { KisSwatchGroup *group = static_cast(idx.internalPointer()); Q_ASSERT(group); int rowInGroup = rowNumberInGroup(idx.row()); bool entryPresent = group->checkEntry(idx.column(), rowInGroup); KisSwatch entry; if (entryPresent) { entry = group->getEntry(idx.column(), rowInGroup); } switch (role) { case Qt::ToolTipRole: case Qt::DisplayRole: { return entryPresent ? entry.name() : i18n("Empty slot"); } case Qt::BackgroundRole: { QColor color(0, 0, 0, 0); if (entryPresent) { color = m_displayRenderer->toQColor(entry.color()); } return QBrush(color); } case GroupNameRole: { return group->name(); } case CheckSlotRole: { return entryPresent; } case RowInGroupRole: { return rowInGroup; } default: { return QVariant(); } } } void KisPaletteModel::setDisplayRenderer(const KoColorDisplayRendererInterface *displayRenderer) { if (displayRenderer) { if (m_displayRenderer) { disconnect(m_displayRenderer, 0, this, 0); } m_displayRenderer = displayRenderer; connect(m_displayRenderer, SIGNAL(displayConfigurationChanged()), SLOT(slotDisplayConfigurationChanged())); } else { m_displayRenderer = KoDumbColorDisplayRenderer::instance(); } } void KisPaletteModel::slotDisplayConfigurationChanged() { beginResetModel(); endResetModel(); } void KisPaletteModel::slotPaletteModified() { m_colorSet->setPaletteType(KoColorSet::KPL); } QModelIndex KisPaletteModel::indexForClosest(const KoColor &compare) { KisSwatchGroup::SwatchInfo info = colorSet()->getClosestColorInfo(compare); return createIndex(indexRowForInfo(info), info.column, colorSet()->getGroup(info.group)); } int KisPaletteModel::indexRowForInfo(const KisSwatchGroup::SwatchInfo &info) { for (auto it = m_groupNameRows.begin(); it != m_groupNameRows.end(); it++) { if (it.value() == info.group) { return it.key() + info.row + 1; } } return info.row; } KisSwatch KisPaletteModel::getEntry(const QModelIndex &index) const { KisSwatchGroup *group = static_cast(index.internalPointer()); if (!group || !group->checkEntry(index.column(), rowNumberInGroup(index.row()))) { return KisSwatch(); } return group->getEntry(index.column(), rowNumberInGroup(index.row())); } int KisPaletteModel::groupNameRowForRow(int rowInModel) const { return rowInModel - rowNumberInGroup(rowInModel) - 1; } diff --git a/libs/widgets/KisPaletteModel.h b/libs/widgets/KisPaletteModel.h index 20b40ab183..244041f179 100644 --- a/libs/widgets/KisPaletteModel.h +++ b/libs/widgets/KisPaletteModel.h @@ -1,169 +1,177 @@ /* * Copyright (c) 2013 Sven Langkamp * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KIS_PALETTEMODEL_H #define KIS_PALETTEMODEL_H #include #include #include #include #include "kritawidgets_export.h" #include #include class KoColorSet; class KisPaletteView; /** * @brief The KisPaletteModel class * This, together with KisPaletteView and KisPaletteDelegate forms a mvc way to access kocolorsets. * A display renderer is given to this model to convert KoColor to QColor when * colors are requested */ class KRITAWIDGETS_EXPORT KisPaletteModel : public QAbstractTableModel { Q_OBJECT public: explicit KisPaletteModel(QObject* parent = Q_NULLPTR); ~KisPaletteModel() override; enum AdditionalRoles { IsGroupNameRole = Qt::UserRole + 1, RetrieveEntryRole, CheckSlotRole, GroupNameRole, RowInGroupRole }; public /* overriden methods */: // QAbstractTableModel QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex& parent = QModelIndex()) const override; /** * @brief index * @param row * @param column * @param parent * @return the index of for the data at row, column * if the data is a color entry, the internal pointer points to the group * the entry belongs to, and the row and column are row number and column * number inside the group. * if the data is a group, the row number and group number is Q_INFINIFY, * and the internal pointer also points to the group */ QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; Qt::ItemFlags flags(const QModelIndex& index) const override; /** * @brief dropMimeData * This is an overridden function that handles dropped mimedata. * right now only colorsetentries and colorsetgroups are handled. * @return */ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; /** * @brief mimeData * gives the mimedata for a kocolorsetentry or a kocolorsetgroup. * @param indexes * @return the mimedata for the given indices */ QMimeData *mimeData(const QModelIndexList &indexes) const override; QStringList mimeTypes() const override; Qt::DropActions supportedDropActions() const override; /** * @brief setData * setData is not used as KoColor is not a QVariant * use setEntry, addEntry and removeEntry instead */ // TODO Used QVariant::setValue and QVariant.value to implement this // bool setData(const QModelIndex &index, const QVariant &value, int role) override; Q_SIGNALS: - void sigPaletteModifed(); + /** + * @brief sigPaletteModified + * emitted when palette associated with the model is modified + */ + void sigPaletteModified(); + /** + * @brief sigPaletteChanged + * emitted when the palette associated with the model is made another one + */ void sigPaletteChanged(); public /* methods */: /** * @brief addEntry * proper function to handle adding entries. * @return whether successful. */ bool addEntry(const KisSwatch &entry, const QString &groupName = KoColorSet::GLOBAL_GROUP_NAME); void setEntry(const KisSwatch &entry, const QModelIndex &index); /** * @brief removeEntry * proper function to remove the colorsetentry at the given index. * The consolidtes both removeentry and removegroup. * @param keepColors: This bool determines whether, when deleting a group, * the colors should be added to the default group. This is usually desirable, * so hence the default is true. * @return if successful */ bool removeEntry(const QModelIndex &index, bool keepColors=true); void removeGroup(const QString &groupName, bool keepColors); bool renameGroup(const QString &groupName, const QString &newName); void addGroup(const KisSwatchGroup &group); void setRowNumber(const QString &groupName, int rowCount); KisSwatch getEntry(const QModelIndex &index) const; - void setColorSet(KoColorSet* colorSet); + void setPalette(KoColorSet* colorSet); KoColorSet* colorSet() const; QModelIndex indexForClosest(const KoColor &compare); int indexRowForInfo(const KisSwatchGroup::SwatchInfo &info); public Q_SLOTS: private Q_SLOTS: void slotDisplayConfigurationChanged(); void slotPaletteModified(); private /* methods */: QVariant dataForGroupNameRow(const QModelIndex &idx, int role) const; QVariant dataForSwatch(const QModelIndex &idx, int role) const; int rowNumberInGroup(int rowInModel) const; int groupNameRowForRow(int rowInModel) const; /** * Installs a display renderer object for a palette that will * convert the KoColor to the displayable QColor. Default is the * dumb renderer. */ void setDisplayRenderer(const KoColorDisplayRendererInterface *displayRenderer); private /* member variables */: QPointer m_colorSet; QPointer m_displayRenderer; QMap m_groupNameRows; friend class KisPaletteView; }; #endif diff --git a/libs/widgets/KoColorSetWidget.cpp b/libs/widgets/KoColorSetWidget.cpp index d0d0030eec..1ad682e304 100644 --- a/libs/widgets/KoColorSetWidget.cpp +++ b/libs/widgets/KoColorSetWidget.cpp @@ -1,223 +1,217 @@ /* This file is part of the KDE project Copyright (c) 2007, 2012 C. Boemann Copyright (c) 2007-2008 Fredy Yanardi This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KoColorSetWidget.h" #include "KoColorSetWidget_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void KoColorSetWidget::KoColorSetWidgetPrivate::addRecent(const KoColor &color) { if(numRecents < 6) { recentPatches[numRecents] = new KoColorPatch(thePublic); recentPatches[numRecents]->setFrameShape(QFrame::StyledPanel); recentPatches[numRecents]->setDisplayRenderer(displayRenderer); recentsLayout->insertWidget(numRecents + 1, recentPatches[numRecents]); connect(recentPatches[numRecents], SIGNAL(triggered(KoColorPatch *)), thePublic, SLOT(slotPatchTriggered(KoColorPatch *))); numRecents++; } // shift colors to the right for (int i = numRecents- 1; i >0; i--) { recentPatches[i]->setColor(recentPatches[i-1]->color()); } //Finally set the recent color recentPatches[0]->setColor(color); } void KoColorSetWidget::KoColorSetWidgetPrivate::activateRecent(int i) { KoColor color = recentPatches[i]->color(); while (i >0) { recentPatches[i]->setColor(recentPatches[i-1]->color()); i--; } recentPatches[0]->setColor(color); } KoColorSetWidget::KoColorSetWidget(QWidget *parent) : QFrame(parent) , d(new KoColorSetWidgetPrivate()) { d->thePublic = this; d->numRecents = 0; d->recentsLayout = new QHBoxLayout; d->recentsLayout->setMargin(0); d->recentsLayout->addWidget(new QLabel(i18n("Recent:"))); d->recentsLayout->addStretch(1); KoColor color(KoColorSpaceRegistry::instance()->rgb8()); color.fromQColor(QColor(128,0,0)); d->addRecent(color); d->paletteView = new KisPaletteView(this); KisPaletteModel *paletteModel = new KisPaletteModel(d->paletteView); d->paletteView->setPaletteModel(paletteModel); d->paletteView->setDisplayRenderer(d->displayRenderer); d->paletteChooser = new KisPaletteListWidget(this); d->paletteChooserButton = new KisPopupButton(this); d->paletteChooserButton->setPopupWidget(d->paletteChooser); d->paletteChooserButton->setIcon(KisIconUtils::loadIcon("hi16-palette_library")); d->paletteChooserButton->setToolTip(i18n("Choose palette")); d->colorNameCmb = new KisPaletteComboBox(this); - d->colorNameCmb->setEditable(true); - d->colorNameCmb->setInsertPolicy(QComboBox::NoInsert); - d->colorNameCmb->setPaletteModel(paletteModel); + d->colorNameCmb->setCompanionView(d->paletteView); d->bottomLayout = new QHBoxLayout; d->bottomLayout->addWidget(d->paletteChooserButton); d->bottomLayout->addWidget(d->colorNameCmb); d->bottomLayout->setStretch(0, 0); // minimize chooser button d->bottomLayout->setStretch(1, 1); // maximize color name cmb d->mainLayout = new QVBoxLayout(this); d->mainLayout->setMargin(4); d->mainLayout->setSpacing(2); d->mainLayout->addLayout(d->recentsLayout); d->mainLayout->addWidget(d->paletteView); d->mainLayout->addLayout(d->bottomLayout); setLayout(d->mainLayout); connect(d->paletteChooser, SIGNAL(sigPaletteSelected(KoColorSet*)), SLOT(slotPaletteChoosen(KoColorSet*))); connect(d->paletteView, SIGNAL(sigColorSelected(KoColor)), SLOT(slotColorSelectedByPalette(KoColor))); - connect(d->paletteView, SIGNAL(sigIndexSelected(QModelIndex)), - d->colorNameCmb, SLOT(slotSwatchSelected(QModelIndex))); connect(d->colorNameCmb, SIGNAL(sigColorSelected(KoColor)), SLOT(slotNameListSelection(KoColor))); - connect(this, SIGNAL(colorChanged(KoColor,bool)), - d->paletteView, SLOT(slotFGColorChanged(KoColor))); d->rServer = KoResourceServerProvider::instance()->paletteServer(); QPointer defaultColorSet = d->rServer->resourceByName("Default"); if (!defaultColorSet && d->rServer->resources().count() > 0) { defaultColorSet = d->rServer->resources().first(); } setColorSet(defaultColorSet); } KoColorSetWidget::~KoColorSetWidget() { delete d; } void KoColorSetWidget::setColorSet(QPointer colorSet) { if (!colorSet) return; if (colorSet == d->colorSet) return; - d->paletteView->paletteModel()->setColorSet(colorSet.data()); + d->paletteView->paletteModel()->setPalette(colorSet.data()); d->colorSet = colorSet; } KoColorSet* KoColorSetWidget::colorSet() { return d->colorSet; } void KoColorSetWidget::setDisplayRenderer(const KoColorDisplayRendererInterface *displayRenderer) { if (displayRenderer) { d->displayRenderer = displayRenderer; for (int i=0; i<6; i++) { if (d->recentPatches[i]) { d->recentPatches[i]->setDisplayRenderer(displayRenderer); } } } } void KoColorSetWidget::resizeEvent(QResizeEvent *event) { emit widgetSizeChanged(event->size()); QFrame::resizeEvent(event); } void KoColorSetWidget::slotColorSelectedByPalette(const KoColor &color) { emit colorChanged(color, true); d->addRecent(color); } void KoColorSetWidget::slotPatchTriggered(KoColorPatch *patch) { emit colorChanged(patch->color(), true); int i; for (i = 0; i < d->numRecents; i++) { if(patch == d->recentPatches[i]) { d->activateRecent(i); break; } } if (i == d->numRecents) { // we didn't find it above d->addRecent(patch->color()); } } void KoColorSetWidget::slotPaletteChoosen(KoColorSet *colorSet) { d->colorSet = colorSet; - d->paletteView->paletteModel()->setColorSet(colorSet); + d->paletteView->paletteModel()->setPalette(colorSet); } void KoColorSetWidget::slotNameListSelection(const KoColor &color) { emit colorChanged(color, true); } //have to include this because of Q_PRIVATE_SLOT #include "moc_KoColorSetWidget.cpp" diff --git a/plugins/dockers/palettedocker/palettedocker_dock.cpp b/plugins/dockers/palettedocker/palettedocker_dock.cpp index 2cecce5015..0984f10f18 100644 --- a/plugins/dockers/palettedocker/palettedocker_dock.cpp +++ b/plugins/dockers/palettedocker/palettedocker_dock.cpp @@ -1,362 +1,360 @@ /* * Copyright (c) 2013 Sven Langkamp * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "palettedocker_dock.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ui_wdgpalettedock.h" PaletteDockerDock::PaletteDockerDock( ) : QDockWidget(i18n("Palette")) , m_ui(new Ui_WdgPaletteDock()) , m_model(new KisPaletteModel(this)) , m_paletteChooser(new KisPaletteListWidget(this)) , m_view(Q_NULLPTR) , m_resourceProvider(Q_NULLPTR) , m_rServer(KoResourceServerProvider::instance()->paletteServer()) , m_rAdapter(new KoResourceServerAdapter(KoResourceServerProvider::instance()->paletteServer())) , m_activeDocument(Q_NULLPTR) , m_paletteEditor(new KisPaletteEditor) , m_actAdd(new QAction(KisIconUtils::loadIcon("list-add"), i18n("Add foreground color"))) , m_actRemove(new QAction(KisIconUtils::loadIcon("edit-delete"), i18n("Delete color"))) , m_actModify(new QAction(KisIconUtils::loadIcon("edit-rename"), i18n("Modify this spot"))) , m_actEditPalette(new QAction(KisIconUtils::loadIcon("groupLayer"), i18n("Edit this palette"))) { QWidget *mainWidget = new QWidget(this); setWidget(mainWidget); m_ui->setupUi(mainWidget); m_ui->bnAdd->setDefaultAction(m_actAdd.data()); m_ui->bnRemove->setDefaultAction(m_actRemove.data()); m_ui->bnRename->setDefaultAction(m_actModify.data()); m_ui->bnEditPalette->setDefaultAction(m_actEditPalette.data()); // to make sure their icons have the same size m_ui->bnRemove->setIconSize(QSize(16, 16)); m_ui->bnRename->setIconSize(QSize(16, 16)); m_ui->bnAdd->setIconSize(QSize(16, 16)); m_ui->bnEditPalette->setIconSize(QSize(16, 16)); m_ui->paletteView->setPaletteModel(m_model); m_ui->paletteView->setAllowModification(true); - m_ui->cmbNameList->setPaletteModel(m_model); + m_ui->cmbNameList->setCompanionView(m_ui->paletteView); m_paletteEditor->setPaletteModel(m_model); connect(m_actAdd.data(), SIGNAL(triggered()), SLOT(slotAddColor())); connect(m_actRemove.data(), SIGNAL(triggered()), SLOT(slotRemoveColor())); connect(m_actModify.data(), SIGNAL(triggered()), SLOT(slotEditEntry())); connect(m_actEditPalette.data(), SIGNAL(triggered()), SLOT(slotEditPalette())); connect(m_ui->paletteView, SIGNAL(sigIndexSelected(QModelIndex)), SLOT(slotPaletteIndexSelected(QModelIndex))); connect(m_ui->paletteView, SIGNAL(doubleClicked(QModelIndex)), SLOT(slotPaletteIndexDoubleClicked(QModelIndex))); - connect(m_ui->paletteView, SIGNAL(sigIndexSelected(QModelIndex)), - m_ui->cmbNameList, SLOT(slotSwatchSelected(QModelIndex))); - connect(m_ui->cmbNameList, SIGNAL(sigColorSelected(KoColor)), - SLOT(slotNameListSelection(KoColor))); + // connect(m_ui->cmbNameList, SIGNAL(sigColorSelected(KoColor)), + // SLOT(slotNameListSelection(KoColor))); m_viewContextMenu.addAction(m_actRemove.data()); m_viewContextMenu.addAction(m_actModify.data()); m_paletteChooser->setAllowModification(true); connect(m_paletteChooser, SIGNAL(sigPaletteSelected(KoColorSet*)), SLOT(slotSetColorSet(KoColorSet*))); connect(m_paletteChooser, SIGNAL(sigAddPalette()), SLOT(slotAddPalette())); connect(m_paletteChooser, SIGNAL(sigImportPalette()), SLOT(slotImportPalette())); connect(m_paletteChooser, SIGNAL(sigRemovePalette(KoColorSet*)), SLOT(slotRemovePalette(KoColorSet*))); connect(m_paletteChooser, SIGNAL(sigExportPalette(KoColorSet*)), SLOT(slotExportPalette(KoColorSet*))); m_ui->bnColorSets->setIcon(KisIconUtils::loadIcon("hi16-palette_library")); m_ui->bnColorSets->setToolTip(i18n("Choose palette")); m_ui->bnColorSets->setPopupWidget(m_paletteChooser); KisConfig cfg(true); QString defaultPaletteName = cfg.defaultPalette(); KoColorSet* defaultPalette = m_rServer->resourceByName(defaultPaletteName); if (defaultPalette) { slotSetColorSet(defaultPalette); } else { m_ui->bnAdd->setEnabled(false); m_ui->bnRename->setEnabled(false); m_ui->bnRemove->setEnabled(false); m_ui->bnEditPalette->setEnabled(false); m_ui->paletteView->setAllowModification(false); } } PaletteDockerDock::~PaletteDockerDock() { } void PaletteDockerDock::setViewManager(KisViewManager* kisview) { m_view = kisview; m_resourceProvider = kisview->resourceProvider(); connect(m_resourceProvider, SIGNAL(sigSavingWorkspace(KisWorkspaceResource*)), SLOT(saveToWorkspace(KisWorkspaceResource*))); connect(m_resourceProvider, SIGNAL(sigLoadingWorkspace(KisWorkspaceResource*)), SLOT(loadFromWorkspace(KisWorkspaceResource*))); connect(m_resourceProvider, SIGNAL(sigFGColorChanged(KoColor)), m_ui->paletteView, SLOT(slotFGColorChanged(KoColor))); kisview->nodeManager()->disconnect(m_model); } void PaletteDockerDock::slotAddPalette() { m_paletteEditor->addPalette(); } void PaletteDockerDock::slotRemovePalette(KoColorSet *cs) { m_paletteEditor->removePalette(cs); } void PaletteDockerDock::slotImportPalette() { m_paletteEditor->importPalette(); } void PaletteDockerDock::slotExportPalette(KoColorSet *palette) { KoFileDialog dialog(this, KoFileDialog::SaveFile, "Save Palette"); dialog.setDefaultDir(palette->filename()); dialog.setMimeTypeFilters(QStringList() << "krita/x-colorset"); QString newPath; bool isStandAlone = palette->isGlobal(); QString oriPath = palette->filename(); if ((newPath = dialog.filename()).isEmpty()) { return; } palette->setFilename(newPath); palette->setIsGlobal(true); palette->save(); palette->setFilename(oriPath); palette->setIsGlobal(isStandAlone); } void PaletteDockerDock::setCanvas(KoCanvasBase *canvas) { setEnabled(canvas != Q_NULLPTR); if (canvas) { KisCanvas2 *cv = qobject_cast(canvas); m_ui->paletteView->setDisplayRenderer(cv->displayColorConverter()->displayRendererInterface()); } if (m_activeDocument) { for (KoColorSet * &cs : m_activeDocument->paletteList()) { KoColorSet *tmpAddr = cs; cs = new KoColorSet(*cs); m_rAdapter->removeResource(tmpAddr); } } if (m_view && m_view->document()) { m_activeDocument = m_view->document(); m_paletteEditor->setView(m_view); for (KoColorSet *cs : m_activeDocument->paletteList()) { m_rAdapter->addResource(cs); } } if (!m_currentColorSet) { slotSetColorSet(Q_NULLPTR); } } void PaletteDockerDock::unsetCanvas() { setEnabled(false); m_ui->paletteView->setDisplayRenderer(Q_NULLPTR); m_paletteEditor->setView(Q_NULLPTR); for (KoResource *r : m_rServer->resources()) { KoColorSet *g = static_cast(r); if (!g->isGlobal()) { m_rAdapter->removeResource(r); } } if (!m_currentColorSet) { slotSetColorSet(Q_NULLPTR); } } void PaletteDockerDock::slotSetColorSet(KoColorSet* colorSet) { if (colorSet && colorSet->isEditable()) { m_ui->bnAdd->setEnabled(true); m_ui->bnRename->setEnabled(true); m_ui->bnRemove->setEnabled(true); m_ui->bnEditPalette->setEnabled(true); m_ui->paletteView->setAllowModification(true); } else { m_ui->bnAdd->setEnabled(false); m_ui->bnRename->setEnabled(false); m_ui->bnRemove->setEnabled(false); m_ui->bnEditPalette->setEnabled(false); m_ui->paletteView->setAllowModification(false); } m_currentColorSet = colorSet; - m_model->setColorSet(colorSet); + m_model->setPalette(colorSet); if (colorSet) { KisConfig cfg(true); cfg.setDefaultPalette(colorSet->name()); m_ui->bnColorSets->setText(colorSet->name()); } else { m_ui->bnColorSets->setText(""); } } void PaletteDockerDock::slotEditPalette() { KisDlgPaletteEditor dlg; if (!m_currentColorSet) { return; } dlg.setPaletteModel(m_model); dlg.setView(m_view); if (dlg.exec() != QDialog::Accepted){ return; } slotSetColorSet(m_currentColorSet); // update GUI } void PaletteDockerDock::slotAddColor() { if (m_currentColorSet->isEditable()) { if (m_resourceProvider) { m_paletteEditor->addEntry(m_resourceProvider->fgColor()); } } } void PaletteDockerDock::slotRemoveColor() { if (m_currentColorSet->isEditable()) { QModelIndex index = m_ui->paletteView->currentIndex(); if (!index.isValid()) { return; } m_paletteEditor->removeEntry(index); m_ui->bnRemove->setEnabled(false); } } void PaletteDockerDock::setFGColorByPalette(const KisSwatch &entry) { if (m_resourceProvider) { m_resourceProvider->setFGColor(entry.color()); } } void PaletteDockerDock::saveToWorkspace(KisWorkspaceResource* workspace) { if (!m_currentColorSet.isNull()) { workspace->setProperty("palette", m_currentColorSet->name()); } } void PaletteDockerDock::loadFromWorkspace(KisWorkspaceResource* workspace) { if (workspace->hasProperty("palette")) { KoResourceServer* rServer = KoResourceServerProvider::instance()->paletteServer(); KoColorSet* colorSet = rServer->resourceByName(workspace->getString("palette")); if (colorSet) { slotSetColorSet(colorSet); } } } void PaletteDockerDock::slotPaletteIndexSelected(const QModelIndex &index) { bool slotEmpty = !(qvariant_cast(index.data(KisPaletteModel::CheckSlotRole))); if (slotEmpty) { if (!m_currentColorSet->isEditable()) { return; } setEntryByForeground(index); } else { m_ui->bnRemove->setEnabled(true); KisSwatch entry = m_model->getEntry(index); setFGColorByPalette(entry); } } void PaletteDockerDock::slotPaletteIndexDoubleClicked(const QModelIndex &index) { m_paletteEditor->modifyEntry(index); } void PaletteDockerDock::setEntryByForeground(const QModelIndex &index) { m_paletteEditor->setEntry(m_resourceProvider->fgColor(), index); if (m_currentColorSet->isEditable()) { m_ui->bnRemove->setEnabled(true); } } void PaletteDockerDock::slotEditEntry() { if (m_currentColorSet->isEditable()) { QModelIndex index = m_ui->paletteView->currentIndex(); if (!index.isValid()) { return; } m_paletteEditor->modifyEntry(index); } } void PaletteDockerDock::slotNameListSelection(const KoColor &color) { m_resourceProvider->setFGColor(color); } diff --git a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.cpp b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.cpp index a28a4d1d6f..2f8e602c67 100644 --- a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.cpp +++ b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.cpp @@ -1,377 +1,377 @@ /* * Copyright (c) 2016 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_tool_lazy_brush_options_widget.h" #include "ui_kis_tool_lazy_brush_options_widget.h" #include #include "KisPaletteModel.h" #include "kis_config.h" #include #include "kis_canvas_resource_provider.h" #include "kis_signal_auto_connection.h" #include "lazybrush/kis_colorize_mask.h" #include "kis_image.h" #include "kis_signals_blocker.h" #include "kis_signal_compressor.h" #include "kis_layer_properties_icons.h" struct KisToolLazyBrushOptionsWidget::Private { Private() : baseNodeChangedCompressor(500, KisSignalCompressor::FIRST_ACTIVE) { } Ui_KisToolLazyBrushOptionsWidget *ui; KisPaletteModel *colorModel; KisCanvasResourceProvider *provider; KisSignalAutoConnectionsStore providerSignals; KisSignalAutoConnectionsStore maskSignals; KisColorizeMaskSP activeMask; KoColorSet colorSet; int transparentColorIndex; KisSignalCompressor baseNodeChangedCompressor; }; KisToolLazyBrushOptionsWidget::KisToolLazyBrushOptionsWidget(KisCanvasResourceProvider *provider, QWidget *parent) : QWidget(parent), m_d(new Private) { m_d->ui = new Ui_KisToolLazyBrushOptionsWidget(); m_d->ui->setupUi(this); m_d->colorModel = new KisPaletteModel(this); m_d->ui->colorView->setPaletteModel(m_d->colorModel); m_d->ui->colorView->setAllowModification(false); //people proly shouldn't be able to edit the colorentries themselves. m_d->ui->colorView->setCrossedKeyword("transparent"); connect(m_d->ui->chkUseEdgeDetection, SIGNAL(toggled(bool)), SLOT(slotUseEdgeDetectionChanged(bool))); connect(m_d->ui->intEdgeDetectionSize, SIGNAL(valueChanged(int)), SLOT(slotEdgeDetectionSizeChanged(int))); connect(m_d->ui->intRadius, SIGNAL(valueChanged(int)), SLOT(slotRadiusChanged(int))); connect(m_d->ui->intCleanUp, SIGNAL(valueChanged(int)), SLOT(slotCleanUpChanged(int))); connect(m_d->ui->chkLimitToDevice, SIGNAL(toggled(bool)), SLOT(slotLimitToDeviceChanged(bool))); m_d->ui->intEdgeDetectionSize->setRange(0, 100); m_d->ui->intEdgeDetectionSize->setExponentRatio(2.0); m_d->ui->intEdgeDetectionSize->setSuffix(i18n(" px")); m_d->ui->intEdgeDetectionSize->setPrefix(i18n("Edge detection: ")); m_d->ui->intEdgeDetectionSize->setToolTip( i18nc("@info:tooltip", "Activate for images with vast solid areas. " "Set the value to the width of the thinnest " "lines on the image")); m_d->ui->intRadius->setRange(0, 1000); m_d->ui->intRadius->setExponentRatio(3.0); m_d->ui->intRadius->setSuffix(i18n(" px")); m_d->ui->intRadius->setPrefix(i18n("Gap close hint: ")); m_d->ui->intRadius->setToolTip( i18nc("@info:tooltip", "The mask will try to close non-closed contours " "if the gap is smaller than \"Gap close hint\" value")); m_d->ui->intCleanUp->setRange(0, 100); m_d->ui->intCleanUp->setSuffix(i18n(" %")); m_d->ui->intCleanUp->setPrefix(i18n("Clean up: ")); m_d->ui->intCleanUp->setToolTip( i18nc("@info:tooltip", "The mask will try to remove parts of the key strokes " "that are placed outside the closed contours. 0% - no effect, 100% - max effect")); connect(m_d->ui->colorView, SIGNAL(sigIndexSelected(QModelIndex)), this, SLOT(entrySelected(QModelIndex))); connect(m_d->ui->btnTransparent, SIGNAL(toggled(bool)), this, SLOT(slotMakeTransparent(bool))); connect(m_d->ui->btnRemove, SIGNAL(clicked()), this, SLOT(slotRemove())); connect(m_d->ui->chkAutoUpdates, SIGNAL(toggled(bool)), m_d->ui->btnUpdate, SLOT(setDisabled(bool))); connect(m_d->ui->btnUpdate, SIGNAL(clicked()), this, SLOT(slotUpdate())); connect(m_d->ui->chkAutoUpdates, SIGNAL(toggled(bool)), this, SLOT(slotSetAutoUpdates(bool))); connect(m_d->ui->chkShowKeyStrokes, SIGNAL(toggled(bool)), this, SLOT(slotSetShowKeyStrokes(bool))); connect(m_d->ui->chkShowOutput, SIGNAL(toggled(bool)), this, SLOT(slotSetShowOutput(bool))); connect(&m_d->baseNodeChangedCompressor, SIGNAL(timeout()), this, SLOT(slotUpdateNodeProperties())); m_d->provider = provider; const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8(); m_d->colorSet.setIsGlobal(false); m_d->colorSet.setIsEditable(true); - m_d->colorModel->setColorSet(&m_d->colorSet); + m_d->colorModel->setPalette(&m_d->colorSet); m_d->colorModel->addEntry(KisSwatch(KoColor(Qt::red, cs), "color1")); m_d->colorModel->addEntry(KisSwatch(KoColor(Qt::green, cs), "color2")); m_d->colorModel->addEntry(KisSwatch(KoColor(Qt::blue, cs), "color3")); } KisToolLazyBrushOptionsWidget::~KisToolLazyBrushOptionsWidget() { } void KisToolLazyBrushOptionsWidget::showEvent(QShowEvent *event) { QWidget::showEvent(event); m_d->providerSignals.addConnection( m_d->provider, SIGNAL(sigNodeChanged(KisNodeSP)), this, SLOT(slotCurrentNodeChanged(KisNodeSP))); m_d->providerSignals.addConnection( m_d->provider, SIGNAL(sigFGColorChanged(const KoColor&)), this, SLOT(slotCurrentFgColorChanged(const KoColor&))); slotCurrentNodeChanged(m_d->provider->currentNode()); slotCurrentFgColorChanged(m_d->provider->fgColor()); } void KisToolLazyBrushOptionsWidget::hideEvent(QHideEvent *event) { QWidget::hideEvent(event); m_d->providerSignals.clear(); } void KisToolLazyBrushOptionsWidget::entrySelected(QModelIndex index) { if (!index.isValid()) return; if (!qvariant_cast(index.data(KisPaletteModel::CheckSlotRole))) return; KisSwatch entry = m_d->colorModel->getEntry(index); m_d->provider->setFGColor(entry.color()); int idxInList = m_d->activeMask->keyStrokesColors().colors.indexOf(entry.color()); if (idxInList != -1) { const bool transparentChecked = idxInList == m_d->transparentColorIndex; KisSignalsBlocker b(m_d->ui->btnTransparent); m_d->ui->btnTransparent->setChecked(transparentChecked); } } void KisToolLazyBrushOptionsWidget::slotCurrentFgColorChanged(const KoColor &color) { bool found = false; QModelIndex candidateIdx = m_d->colorModel->indexForClosest(color); if (m_d->colorModel->getEntry(candidateIdx).color() == color) { found = true; } m_d->ui->btnRemove->setEnabled(found); m_d->ui->btnTransparent->setEnabled(found); if (!found) { KisSignalsBlocker b(m_d->ui->btnTransparent); m_d->ui->btnTransparent->setChecked(false); } QModelIndex newIndex = found ? candidateIdx : QModelIndex(); if (!found) { m_d->ui->colorView->selectionModel()->clear(); } if (newIndex.isValid() && newIndex != m_d->ui->colorView->currentIndex()) { m_d->ui->colorView->setCurrentIndex(newIndex); m_d->ui->colorView->update(newIndex); } } void KisToolLazyBrushOptionsWidget::slotColorLabelsChanged() { m_d->colorSet.clear(); m_d->transparentColorIndex = -1; if (m_d->activeMask) { KisColorizeMask::KeyStrokeColors colors = m_d->activeMask->keyStrokesColors(); m_d->transparentColorIndex = colors.transparentIndex; for (int i = 0; i < colors.colors.size(); i++) { const QString name = i == m_d->transparentColorIndex ? "transparent" : ""; m_d->colorModel->addEntry(KisSwatch(colors.colors[i], name)); } } slotCurrentFgColorChanged(m_d->provider->fgColor()); } void KisToolLazyBrushOptionsWidget::slotUpdateNodeProperties() { KisSignalsBlocker b1(m_d->ui->chkAutoUpdates, m_d->ui->btnUpdate, m_d->ui->chkShowKeyStrokes, m_d->ui->chkShowOutput); KisSignalsBlocker b2(m_d->ui->chkUseEdgeDetection, m_d->ui->intEdgeDetectionSize, m_d->ui->intRadius, m_d->ui->intCleanUp, m_d->ui->chkLimitToDevice); // not implemented yet! //m_d->ui->chkAutoUpdates->setEnabled(m_d->activeMask); m_d->ui->chkAutoUpdates->setEnabled(false); m_d->ui->chkAutoUpdates->setVisible(false); bool value = false; value = m_d->activeMask && KisLayerPropertiesIcons::nodeProperty(m_d->activeMask, KisLayerPropertiesIcons::colorizeNeedsUpdate, true).toBool(); m_d->ui->btnUpdate->setEnabled(m_d->activeMask && !m_d->ui->chkAutoUpdates->isChecked() && value); value = m_d->activeMask && KisLayerPropertiesIcons::nodeProperty(m_d->activeMask, KisLayerPropertiesIcons::colorizeEditKeyStrokes, true).toBool(); m_d->ui->chkShowKeyStrokes->setEnabled(m_d->activeMask); m_d->ui->chkShowKeyStrokes->setChecked(value); value = m_d->activeMask && KisLayerPropertiesIcons::nodeProperty(m_d->activeMask, KisLayerPropertiesIcons::colorizeShowColoring, true).toBool(); m_d->ui->chkShowOutput->setEnabled(m_d->activeMask); m_d->ui->chkShowOutput->setChecked(value); m_d->ui->chkUseEdgeDetection->setEnabled(m_d->activeMask); m_d->ui->chkUseEdgeDetection->setChecked(m_d->activeMask && m_d->activeMask->useEdgeDetection()); m_d->ui->intEdgeDetectionSize->setEnabled(m_d->activeMask && m_d->ui->chkUseEdgeDetection->isChecked()); m_d->ui->intEdgeDetectionSize->setValue(m_d->activeMask ? m_d->activeMask->edgeDetectionSize() : 4.0); m_d->ui->intRadius->setEnabled(m_d->activeMask); m_d->ui->intRadius->setValue(2 * (m_d->activeMask ? m_d->activeMask->fuzzyRadius() : 15)); m_d->ui->intCleanUp->setEnabled(m_d->activeMask); m_d->ui->intCleanUp->setValue(100 * (m_d->activeMask ? m_d->activeMask->cleanUpAmount() : 0.7)); m_d->ui->chkLimitToDevice->setEnabled(m_d->activeMask); m_d->ui->chkLimitToDevice->setChecked(m_d->activeMask && m_d->activeMask->limitToDeviceBounds()); } void KisToolLazyBrushOptionsWidget::slotCurrentNodeChanged(KisNodeSP node) { m_d->maskSignals.clear(); KisColorizeMask *mask = dynamic_cast(node.data()); m_d->activeMask = mask; if (m_d->activeMask) { m_d->maskSignals.addConnection( m_d->activeMask, SIGNAL(sigKeyStrokesListChanged()), this, SLOT(slotColorLabelsChanged())); m_d->maskSignals.addConnection( m_d->provider->currentImage(), SIGNAL(sigNodeChanged(KisNodeSP)), this, SLOT(slotUpdateNodeProperties())); } slotColorLabelsChanged(); slotUpdateNodeProperties(); m_d->ui->colorView->setEnabled(m_d->activeMask); } void KisToolLazyBrushOptionsWidget::slotMakeTransparent(bool value) { KIS_ASSERT_RECOVER_RETURN(m_d->activeMask); QModelIndex index = m_d->ui->colorView->currentIndex(); KisSwatch activeSwatch = m_d->colorModel->getEntry(index); if (!index.isValid()) return; int activeIndex = -1; KisColorizeMask::KeyStrokeColors colors; int i = 0; for (const QString &groupName : m_d->colorSet.getGroupNames()) { KisSwatchGroup *group = m_d->colorSet.getGroup(groupName); for (const KisSwatchGroup::SwatchInfo &info : group->infoList()) { colors.colors << info.swatch.color(); if (activeSwatch == info.swatch) { activeIndex = i; } i++; } } colors.transparentIndex = value ? activeIndex : -1; m_d->activeMask->setKeyStrokesColors(colors); } void KisToolLazyBrushOptionsWidget::slotRemove() { KIS_ASSERT_RECOVER_RETURN(m_d->activeMask); QModelIndex index = m_d->ui->colorView->currentIndex(); if (!index.isValid()) return; const KoColor color = m_d->colorModel->getEntry(index).color(); m_d->activeMask->removeKeyStroke(color); } void KisToolLazyBrushOptionsWidget::slotUpdate() { KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->activeMask); KisLayerPropertiesIcons::setNodeProperty(m_d->activeMask, KisLayerPropertiesIcons::colorizeNeedsUpdate, false, m_d->provider->currentImage()); } void KisToolLazyBrushOptionsWidget::slotSetAutoUpdates(bool value) { // not implemented yet! ENTER_FUNCTION() << ppVar(value); } void KisToolLazyBrushOptionsWidget::slotSetShowKeyStrokes(bool value) { KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->activeMask); KisLayerPropertiesIcons::setNodeProperty(m_d->activeMask, KisLayerPropertiesIcons::colorizeEditKeyStrokes, value, m_d->provider->currentImage()); } void KisToolLazyBrushOptionsWidget::slotSetShowOutput(bool value) { KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->activeMask); KisLayerPropertiesIcons::setNodeProperty(m_d->activeMask, KisLayerPropertiesIcons::colorizeShowColoring, value, m_d->provider->currentImage()); } void KisToolLazyBrushOptionsWidget::slotUseEdgeDetectionChanged(bool value) { KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->activeMask); m_d->activeMask->setUseEdgeDetection(value); m_d->ui->intEdgeDetectionSize->setEnabled(value); } void KisToolLazyBrushOptionsWidget::slotEdgeDetectionSizeChanged(int value) { KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->activeMask); m_d->activeMask->setEdgeDetectionSize(value); } void KisToolLazyBrushOptionsWidget::slotRadiusChanged(int value) { KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->activeMask); m_d->activeMask->setFuzzyRadius(0.5 * value); } void KisToolLazyBrushOptionsWidget::slotCleanUpChanged(int value) { KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->activeMask); m_d->activeMask->setCleanUpAmount(qreal(value) / 100.0); } void KisToolLazyBrushOptionsWidget::slotLimitToDeviceChanged(bool value) { KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->activeMask); m_d->activeMask->setLimitToDeviceBounds(value); }