diff --git a/krita/data/gamutmasks/Atmosphere_With_Accent.kgm b/krita/data/gamutmasks/Atmosphere_With_Accent.kgm
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@
+
+
+
diff --git a/krita/pics/svg/dark_gamut-mask-on.svg b/krita/pics/svg/dark_gamut-mask-on.svg
new file mode 100644
--- /dev/null
+++ b/krita/pics/svg/dark_gamut-mask-on.svg
@@ -0,0 +1,1535 @@
+
+
+
+
diff --git a/krita/pics/svg/light_gamut-mask-off.svg b/krita/pics/svg/light_gamut-mask-off.svg
new file mode 100644
--- /dev/null
+++ b/krita/pics/svg/light_gamut-mask-off.svg
@@ -0,0 +1,1563 @@
+
+
+
+
diff --git a/krita/pics/svg/light_gamut-mask-on.svg b/krita/pics/svg/light_gamut-mask-on.svg
new file mode 100644
--- /dev/null
+++ b/krita/pics/svg/light_gamut-mask-on.svg
@@ -0,0 +1,1535 @@
+
+
+
+
diff --git a/krita/pics/svg/svg-icons.qrc b/krita/pics/svg/svg-icons.qrc
--- a/krita/pics/svg/svg-icons.qrc
+++ b/krita/pics/svg/svg-icons.qrc
@@ -147,5 +147,9 @@
dark_wheel-sectors.svg
dark_infinity.svg
light_infinity.svg
+ dark_gamut-mask-on.svg
+ dark_gamut-mask-off.svg
+ light_gamut-mask-off.svg
+ light_gamut-mask-on.svg
diff --git a/libs/flake/KisGamutMaskViewConverter.h b/libs/flake/KisGamutMaskViewConverter.h
--- a/libs/flake/KisGamutMaskViewConverter.h
+++ b/libs/flake/KisGamutMaskViewConverter.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (c) 2018 Anna Medonosova
+ *
+ * This library 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; version 2.1 of the License.
+ *
+ * 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 Lesser 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.
+ */
+
#ifndef KISGAMUTMASKVIEWCONVERTER_H
#define KISGAMUTMASKVIEWCONVERTER_H
@@ -11,7 +28,7 @@
class QRectF;
/**
- * @brief view convertor for gamut mask calculations and painting; 0,0 in the center
+ * @brief view convertor for gamut mask calculations and painting
*/
class KRITAFLAKE_EXPORT KisGamutMaskViewConverter : public KoViewConverter
{
diff --git a/libs/flake/KisGamutMaskViewConverter.cpp b/libs/flake/KisGamutMaskViewConverter.cpp
--- a/libs/flake/KisGamutMaskViewConverter.cpp
+++ b/libs/flake/KisGamutMaskViewConverter.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (c) 2018 Anna Medonosova
+ *
+ * This library 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; version 2.1 of the License.
+ *
+ * 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 Lesser 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 "KisGamutMaskViewConverter.h"
#include
diff --git a/libs/flake/resources/KoGamutMask.h b/libs/flake/resources/KoGamutMask.h
--- a/libs/flake/resources/KoGamutMask.h
+++ b/libs/flake/resources/KoGamutMask.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (c) 2018 Anna Medonosova
+ *
+ * This library 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; version 2.1 of the License.
+ *
+ * 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 Lesser 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.
+ */
+
#ifndef KOGAMUTMASK_H
#define KOGAMUTMASK_H
@@ -24,6 +41,7 @@
bool coordIsClear(const QPointF& coord, const KoViewConverter& viewConverter) const;
QPainterPath outline();
void paint(QPainter &painter, const KoViewConverter& viewConverter);
+ void paintStroke(QPainter &painter, const KoViewConverter& viewConverter);
KoShape* koShape();
private:
@@ -40,19 +58,8 @@
Q_OBJECT
public:
- /**
- * @brief load a gamut mask from given file
- * @param filename
- */
KoGamutMask(const QString &filename);
-
- /**
- * @brief create KoGamutMask from polygons
- * @param polygons
- */
KoGamutMask();
-
- // TODO: copy constructor, for duplicating masks
KoGamutMask(KoGamutMask *rhs);
bool coordIsClear(const QPointF& coord, KoViewConverter& viewConverter, bool preview);
@@ -63,6 +70,7 @@
bool saveToDevice(QIODevice* dev) const override;
void paint(QPainter &painter, KoViewConverter& viewConverter, bool preview);
+ void paintStroke(QPainter &painter, KoViewConverter& viewConverter, bool preview);
QString title();
void setTitle(QString title);
@@ -74,13 +82,14 @@
void setMaskShapes(QList shapes);
void setPreviewMaskShapes(QList shapes);
- void setMaskShapesToVector(QList shapes, QVector& targetVector);
QList koShapes() const;
- // switch back to loaded shapes when ending mask preview
void clearPreview();
+
private:
+ void setMaskShapesToVector(QList shapes, QVector& targetVector);
+
struct Private;
Private* const d;
};
diff --git a/libs/flake/resources/KoGamutMask.cpp b/libs/flake/resources/KoGamutMask.cpp
--- a/libs/flake/resources/KoGamutMask.cpp
+++ b/libs/flake/resources/KoGamutMask.cpp
@@ -1,4 +1,21 @@
-#include "KoGamutMask.h"
+/*
+ * Copyright (c) 2018 Anna Medonosova
+ *
+ * This library 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; version 2.1 of the License.
+ *
+ * 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 Lesser 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 "KoGamutMask.h"
#include
@@ -54,28 +71,37 @@
painter.restore();
}
+void KoGamutMaskShape::paintStroke(QPainter &painter, const KoViewConverter &viewConverter)
+{
+ painter.save();
+ painter.setTransform(m_maskShape->absoluteTransformation(&viewConverter) * painter.transform());
+ m_maskShape->paintStroke(painter, viewConverter, m_shapePaintingContext);
+ painter.restore();
+
+}
struct Q_DECL_HIDDEN KoGamutMask::Private {
QString name;
QString title;
QString description;
QByteArray data;
QVector maskShapes;
QVector previewShapes;
- QSizeF maskSize; // at 100DPI
+ QSizeF maskSize;
};
KoGamutMask::KoGamutMask(const QString& filename)
: KoResource(filename)
, d(new Private())
{
-
+ d->maskSize = QSizeF(144.0,144.0);
}
KoGamutMask::KoGamutMask()
: KoResource(QString())
, d(new Private())
{
+ d->maskSize = QSizeF(144.0,144.0);
}
KoGamutMask::KoGamutMask(KoGamutMask* rhs)
@@ -89,9 +115,8 @@
d->maskSize = rhs->d->maskSize;
QList newShapes;
- for(KoGamutMaskShape* sh: d->maskShapes) {
- KoShape* shape = sh->koShape();
- newShapes.append(shape);
+ for(KoShape* sh: rhs->koShapes()) {
+ newShapes.append(sh->cloneShape());
}
setMaskShapes(newShapes);
@@ -134,6 +159,21 @@
}
}
+void KoGamutMask::paintStroke(QPainter &painter, KoViewConverter &viewConverter, bool preview)
+{
+ QVector* shapeVector;
+
+ if (preview && !d->previewShapes.isEmpty()) {
+ shapeVector = &d->previewShapes;
+ } else {
+ shapeVector = &d->maskShapes;
+ }
+
+ for(KoGamutMaskShape* shape: *shapeVector) {
+ shape->paintStroke(painter, viewConverter);
+ }
+}
+
bool KoGamutMask::load()
{
QFile file(filename());
@@ -143,7 +183,6 @@
return false;
}
bool res = loadFromDevice(&file);
- setValid(res);
file.close();
return res;
}
@@ -154,7 +193,8 @@
d->data = dev->readAll();
- Q_ASSERT(d->data.size() != 0);
+ // TODO: test
+ KIS_ASSERT_RECOVER_RETURN_VALUE(d->data.size() != 0, false);
if (filename().isNull()) {
warnFlake << "Cannot load gamut mask" << name() << "there is no filename set";
@@ -190,7 +230,7 @@
KoXmlDocument xmlDocument;
QString errorMsg;
int errorLine = 0;
- int errorColumn;
+ int errorColumn = 0;
bool ok = xmlDocument.setContent(ba, false, &errorMsg, &errorLine, &errorColumn);
if (!ok) {
@@ -233,6 +273,8 @@
buf.close();
+ setValid(true);
+
return true;
}
@@ -327,7 +369,6 @@
return d->maskSize;
}
-// TODO: rethink preview
void KoGamutMask::setPreviewMaskShapes(QList shapes)
{
setMaskShapesToVector(shapes, d->previewShapes);
diff --git a/libs/ui/KisResourceBundle.h b/libs/ui/KisResourceBundle.h
--- a/libs/ui/KisResourceBundle.h
+++ b/libs/ui/KisResourceBundle.h
@@ -152,6 +152,7 @@
QList m_palettesMd5Installed;
QList m_workspacesMd5Installed;
QList m_presetsMd5Installed;
+ QList m_gamutMasksMd5Installed;
QString m_bundleVersion;
};
diff --git a/libs/ui/KisResourceBundle.cpp b/libs/ui/KisResourceBundle.cpp
--- a/libs/ui/KisResourceBundle.cpp
+++ b/libs/ui/KisResourceBundle.cpp
@@ -383,6 +383,21 @@
}
}
}
+ else if (resType == "ko_gamutmasks") {
+ KoResourceServer* gamutMaskServer = KoResourceServerProvider::instance()->gamutMaskServer();
+ Q_FOREACH (const KisResourceBundleManifest::ResourceReference &ref, m_manifest.files(resType)) {
+ KoResource *res = gamutMaskServer->resourceByMD5(ref.md5sum);
+ if (!res) res = gamutMaskServer->resourceByFilename(QFileInfo(ref.resourcePath).fileName());
+ if (!saveResourceToStore(res, store.data(), "gamutmasks")) {
+ if (res) {
+ warnKrita << "Could not save resource" << resType << res->name();
+ }
+ else {
+ warnKrita << "could not find resource for" << QFileInfo(ref.resourcePath).fileName();
+ }
+ }
+ }
+ }
}
if (!m_thumbnail.isNull()) {
@@ -700,6 +715,51 @@
}
}
+ else if (resType == "gamutmasks") {
+ KoResourceServer* gamutMaskServer = KoResourceServerProvider::instance()->gamutMaskServer();
+ Q_FOREACH (const KisResourceBundleManifest::ResourceReference &ref, m_manifest.files(resType)) {
+
+ if (resourceStore->isOpen()) resourceStore->close();
+
+ dbgResources << "\tInstalling" << ref.resourcePath;
+ KoGamutMask *res = gamutMaskServer->createResource(QString("bundle://%1:%2").arg(filename()).arg(ref.resourcePath));
+
+ if (!res) {
+ warnKrita << "Could not create resource for" << ref.resourcePath;
+ continue;
+ }
+ if (!resourceStore->open(ref.resourcePath)) {
+ warnKrita << "Failed to open" << ref.resourcePath << "from bundle" << filename();
+ continue;
+ }
+ if (!res->loadFromDevice(resourceStore->device())) {
+ warnKrita << "Failed to load" << ref.resourcePath << "from bundle" << filename();
+ continue;
+ }
+ dbgResources << "\t\tresource:" << res->name();
+
+ //find the resource on the server
+ KoGamutMask *res2 = gamutMaskServer->resourceByName(res->name());
+ if (!res2) {//if it doesn't exist...
+ gamutMaskServer->addResource(res, false);//add it!
+
+ if (!m_gamutMasksMd5Installed.contains(res->md5())) {
+ m_gamutMasksMd5Installed.append(res->md5());
+ }
+ if (ref.md5sum!=res->md5()) {
+ md5Mismatch.append(res->name());
+ }
+
+ Q_FOREACH (const QString &tag, ref.tagList) {
+ gamutMaskServer->addTag(res, tag);
+ }
+ //gamutMaskServer->addTag(res, name());
+ }
+ else {
+ //warnKrita << "Didn't install" << res->name()<<"It already exists on the server";
+ }
+ }
+ }
}
m_installed = true;
if(!md5Mismatch.isEmpty()){
@@ -777,13 +837,23 @@
}
}
+ KoResourceServer* gamutMaskServer = KoResourceServerProvider::instance()->gamutMaskServer();
+ //Q_FOREACH (const KisResourceBundleManifest::ResourceReference &ref, m_manifest.files("gamutmasks")) {
+ Q_FOREACH (const QByteArray md5, m_gamutMasksMd5Installed) {
+ KoGamutMask *res = gamutMaskServer->resourceByMD5(md5);
+ if (res) {
+ gamutMaskServer->removeResourceFromServer(res);
+ }
+ }
+
Q_FOREACH(const QString &tag, tags) {
paintoppresetServer->tagCategoryRemoved(tag);
workspaceServer->tagCategoryRemoved(tag);
paletteServer->tagCategoryRemoved(tag);
brushServer->tagCategoryRemoved(tag);
patternServer->tagCategoryRemoved(tag);
gradientServer->tagCategoryRemoved(tag);
+ gamutMaskServer->tagCategoryRemoved(tag);
}
@@ -863,6 +933,11 @@
KisPaintOpPresetSP res = paintoppresetServer->resourceByMD5(ref.md5sum);
if (res) ret << res.data();
}
+ else if (resType == "gamutmasks") {
+ KoResourceServer* gamutMaskServer = KoResourceServerProvider::instance()->gamutMaskServer();
+ KoResource *res = gamutMaskServer->resourceByMD5(ref.md5sum);
+ if (res) ret << res;
+ }
}
return ret;
}
diff --git a/libs/ui/KisResourceBundleManifest.cpp b/libs/ui/KisResourceBundleManifest.cpp
--- a/libs/ui/KisResourceBundleManifest.cpp
+++ b/libs/ui/KisResourceBundleManifest.cpp
@@ -47,7 +47,7 @@
}
QString manifestTypeToResourceType(const QString &type) {
- if (type == "patterns" || type == "gradients" || type == "palettes") {
+ if (type == "patterns" || type == "gradients" || type == "palettes" || type == "gamutmasks") {
return "ko_" + type;
}
else {
diff --git a/libs/ui/dialogs/kis_dlg_blacklist_cleanup.cpp b/libs/ui/dialogs/kis_dlg_blacklist_cleanup.cpp
--- a/libs/ui/dialogs/kis_dlg_blacklist_cleanup.cpp
+++ b/libs/ui/dialogs/kis_dlg_blacklist_cleanup.cpp
@@ -62,5 +62,8 @@
if (cbRemovePattern->isChecked()) {
KoResourceServerProvider::instance()->patternServer()->removeBlackListedFiles();
}
+ if (cbRemoveGamutMasks->isChecked()) {
+ KoResourceServerProvider::instance()->gamutMaskServer()->removeBlackListedFiles();
+ }
}
diff --git a/libs/ui/forms/wdgdlgblacklistcleanup.ui b/libs/ui/forms/wdgdlgblacklistcleanup.ui
--- a/libs/ui/forms/wdgdlgblacklistcleanup.ui
+++ b/libs/ui/forms/wdgdlgblacklistcleanup.ui
@@ -117,6 +117,16 @@
+ -
+
+
+ Gamut Masks
+
+
+ true
+
+
+
diff --git a/plugins/dockers/artisticcolorselector/CMakeLists.txt b/plugins/dockers/artisticcolorselector/CMakeLists.txt
--- a/plugins/dockers/artisticcolorselector/CMakeLists.txt
+++ b/plugins/dockers/artisticcolorselector/CMakeLists.txt
@@ -12,5 +12,5 @@
)
add_library(kritaartisticcolorselector MODULE ${kritaartisticcolorselector_SOURCES})
-target_link_libraries(kritaartisticcolorselector kritalibkis kritaui)
+target_link_libraries(kritaartisticcolorselector kritaui)
install(TARGETS kritaartisticcolorselector DESTINATION ${KRITA_PLUGIN_INSTALL_DIR})
diff --git a/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.h b/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.h
--- a/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.h
+++ b/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.h
@@ -28,7 +28,6 @@
#include
#include
#include
-//#include
#include
#include
@@ -55,18 +54,14 @@
void setCanvas(KoCanvasBase *canvas) override;
void unsetCanvas() override;
-//Q_SIGNALS:
-// void sigGamutMaskChanged();
-
private Q_SLOTS:
void slotCanvasResourceChanged(int key, const QVariant& value);
void slotFgColorChanged(const KisColor& color);
void slotBgColorChanged(const KisColor& color);
void slotColorSpaceSelected(int type);
+ void slotSetGamma(qreal gamma);
void slotPreferenceChanged();
- void slotResetRingPositions();
void slotResetDefaultSettings();
- void slotLightModeChanged(bool setToAbsolute);
void slotGamutMaskToggle(bool value);
void slotGamutMaskActivatePreview(bool value);
void slotGamutMaskSet(KoGamutMask* mask);
@@ -81,9 +76,10 @@
WheelPreferencesPopupUI* m_wheelPrefsUI;
KoGamutMask* m_selectedMask;
- QPixmap m_infinityPixmap;
+ QIcon m_iconMaskOff;
+ QIcon m_iconMaskOn;
- void updateWheelInfoStrip();
+ QPixmap m_infinityPixmap;
};
diff --git a/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.cpp b/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.cpp
--- a/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.cpp
+++ b/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.cpp
@@ -91,26 +91,19 @@
QPixmap valueScaleStepsPixmap = KisIconUtils::loadIcon("wheel-light").pixmap(16,16);
QIcon infinityIcon = KisIconUtils::loadIcon("infinity");
m_infinityPixmap = infinityIcon.pixmap(16,16);
+ m_iconMaskOff = KisIconUtils::loadIcon("gamut-mask-off");
+ m_iconMaskOn = KisIconUtils::loadIcon("gamut-mask-on");
m_selectorUI->colorSelector->loadSettings();
+ m_selectorUI->bnWheelPrefs->setIcon(KisIconUtils::loadIcon("wheel-sectors"));
m_selectorUI->bnWheelPrefs->setPopupWidget(m_wheelPrefsUI);
- // TODO: make it into separate window
m_selectorUI->bnDockerPrefs->setPopupWidget(m_preferencesUI);
m_selectorUI->bnDockerPrefs->setIcon(KisIconUtils::loadIcon("configure"));
m_selectorUI->bnToggleMask->setChecked(false);
- m_selectorUI->bnToggleMask->setIcon(KisIconUtils::loadIcon("novisible"));
- m_selectorUI->labelMaskToolbar->setPixmap(KisIconUtils::loadIcon("media-playback-stop").pixmap(16,16));
-
- m_selectorUI->labelHueStepsIcon->setPixmap(hueStepsPixmap);
- m_selectorUI->labelSaturationStepsIcon->setPixmap(saturationStepsPixmap);
- m_selectorUI->labelValueScaleStepsIcon->setPixmap(valueScaleStepsPixmap);
-
- m_selectorUI->labelHueSteps->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
- m_selectorUI->labelSaturationSteps->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
- m_selectorUI->labelValueScaleSteps->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
+ m_selectorUI->bnToggleMask->setIcon(m_iconMaskOff);
//preferences
m_hsxButtons->addButton(m_preferencesUI->bnHsy, KisColor::HSY);
@@ -167,28 +160,34 @@
m_preferencesUI->showColorBlip->setChecked(m_selectorUI->colorSelector->getShowColorBlip());
m_preferencesUI->showBgColor->setChecked(m_selectorUI->colorSelector->getShowBgColor());
m_preferencesUI->showValueScaleNumbers->setChecked(m_selectorUI->colorSelector->getShowValueScaleNumbers());
- m_preferencesUI->bnAbsLight->setChecked(m_selectorUI->colorSelector->islightRelative());
m_preferencesUI->enforceGamutMask->setChecked(m_selectorUI->colorSelector->enforceGamutMask());
m_preferencesUI->permissiveGamutMask->setChecked(!m_selectorUI->colorSelector->enforceGamutMask());
m_preferencesUI->showMaskPreview->setChecked(m_selectorUI->colorSelector->maskPreviewActive());
+ m_preferencesUI->valueScaleGamma->setValue(m_selectorUI->colorSelector->gamma());
+
switch(m_selectorUI->colorSelector->getColorSpace())
{
case KisColor::HSV: { m_preferencesUI->bnHsv->setChecked(true); } break;
case KisColor::HSI: { m_preferencesUI->bnHsi->setChecked(true); } break;
case KisColor::HSL: { m_preferencesUI->bnHsl->setChecked(true); } break;
case KisColor::HSY: { m_preferencesUI->bnHsy->setChecked(true); } break;
}
+ if (m_selectorUI->colorSelector->getColorSpace() == KisColor::HSY) {
+ m_preferencesUI->valueScaleGammaBox->show();
+ } else {
+ m_preferencesUI->valueScaleGammaBox->hide();
+ }
+
connect(m_wheelPrefsUI->numValueScaleSteps , SIGNAL(valueChanged(int)) , SLOT(slotPreferenceChanged()));
connect(m_wheelPrefsUI->numHueSteps , SIGNAL(valueChanged(int)) , SLOT(slotPreferenceChanged()));
connect(m_wheelPrefsUI->numSaturationSteps , SIGNAL(valueChanged(int)) , SLOT(slotPreferenceChanged()));
connect(m_wheelPrefsUI->bnInverseSat , SIGNAL(clicked(bool)) , SLOT(slotPreferenceChanged()));
connect(m_wheelPrefsUI->bnInfHueSteps , SIGNAL(clicked(bool)) , SLOT(slotPreferenceChanged()));
connect(m_wheelPrefsUI->bnInfValueScaleSteps, SIGNAL(clicked(bool)) , SLOT(slotPreferenceChanged()));
connect(m_wheelPrefsUI->bnDefault , SIGNAL(clicked(bool)) , SLOT(slotResetDefaultSettings()));
- connect(m_wheelPrefsUI->bnResetPosition , SIGNAL(clicked(bool)) , SLOT(slotResetRingPositions()));
connect(m_preferencesUI->defaultHueSteps , SIGNAL(valueChanged(int)) , SLOT(slotPreferenceChanged()));
connect(m_preferencesUI->defaultSaturationSteps, SIGNAL(valueChanged(int)) , SLOT(slotPreferenceChanged()));
@@ -200,8 +199,8 @@
connect(m_preferencesUI->showBgColor , SIGNAL(toggled(bool)) , SLOT(slotPreferenceChanged()));
connect(m_preferencesUI->showValueScaleNumbers, SIGNAL(toggled(bool)) , SLOT(slotPreferenceChanged()));
connect(m_preferencesUI->enforceGamutMask , SIGNAL(toggled(bool)) , SLOT(slotPreferenceChanged()));
- connect(m_preferencesUI->bnAbsLight , SIGNAL(toggled(bool)) , SLOT(slotLightModeChanged(bool)));
connect(m_preferencesUI->showMaskPreview , SIGNAL(toggled(bool)), SLOT(slotGamutMaskActivatePreview(bool)));
+ connect(m_preferencesUI->valueScaleGamma , SIGNAL(valueChanged(qreal)), SLOT(slotSetGamma(qreal)));
connect(m_selectorUI->colorSelector , SIGNAL(sigFgColorChanged(const KisColor&)) , SLOT(slotFgColorChanged(const KisColor&)));
connect(m_selectorUI->colorSelector , SIGNAL(sigBgColorChanged(const KisColor&)) , SLOT(slotBgColorChanged(const KisColor&)));
@@ -211,8 +210,6 @@
connect(m_hsxButtons , SIGNAL(buttonClicked(int)) , SLOT(slotColorSpaceSelected(int)));
- updateWheelInfoStrip();
-
setWidget(m_selectorUI);
}
@@ -267,12 +264,23 @@
void ArtisticColorSelectorDock::slotColorSpaceSelected(int type)
{
- m_selectorUI->colorSelector->setColorSpace(static_cast(type));
+ m_selectorUI->colorSelector->setColorSpace(static_cast(type), m_preferencesUI->valueScaleGamma->value());
+
+ if (m_selectorUI->colorSelector->getColorSpace() == KisColor::HSY) {
+ m_preferencesUI->valueScaleGammaBox->show();
+ } else {
+ m_preferencesUI->valueScaleGammaBox->hide();
+ }
+}
+
+void ArtisticColorSelectorDock::slotSetGamma(qreal gamma)
+{
+ m_selectorUI->colorSelector->setGamma(gamma);
}
void ArtisticColorSelectorDock::slotPreferenceChanged()
{
- int hueSteps;
+ int hueSteps = DEFAULT_HUE_STEPS;
if (m_wheelPrefsUI->bnInfHueSteps->isChecked()) {
m_wheelPrefsUI->numHueSteps->setEnabled(false);
hueSteps = 1;
@@ -332,12 +340,6 @@
m_selectorUI->colorSelector->setInverseSaturation(false);
}
- updateWheelInfoStrip();
-}
-
-void ArtisticColorSelectorDock::slotResetRingPositions()
-{
- m_selectorUI->colorSelector->resetRings();
}
void ArtisticColorSelectorDock::slotResetDefaultSettings()
@@ -376,32 +378,6 @@
m_wheelPrefsUI->numValueScaleSteps->setEnabled(true);
m_wheelPrefsUI->bnInfValueScaleSteps->setChecked(false);
}
-
- updateWheelInfoStrip();
-}
-
-void ArtisticColorSelectorDock::slotLightModeChanged(bool setToAbsolute)
-{
- m_selectorUI->colorSelector->setLight(m_selectorUI->colorSelector->getLight(), setToAbsolute);
-}
-
-void ArtisticColorSelectorDock::updateWheelInfoStrip()
-{
- int hueSteps = m_selectorUI->colorSelector->getNumPieces();
- if (hueSteps == 1) {
- m_selectorUI->labelHueSteps->setPixmap(m_infinityPixmap);
- } else {
- m_selectorUI->labelHueSteps->setNum(hueSteps);
- }
-
- m_selectorUI->labelSaturationSteps->setNum(m_wheelPrefsUI->numSaturationSteps->value());
-
- int valueScaleSteps = m_selectorUI->colorSelector->getNumLightPieces();
- if (valueScaleSteps == 1) {
- m_selectorUI->labelValueScaleSteps->setPixmap(m_infinityPixmap);
- } else {
- m_selectorUI->labelValueScaleSteps->setNum(valueScaleSteps);
- }
}
void ArtisticColorSelectorDock::slotGamutMaskActivatePreview(bool value)
@@ -427,9 +403,9 @@
if (b == true) {
m_selectorUI->colorSelector->setGamutMask(m_selectedMask);
- m_selectorUI->bnToggleMask->setIcon(KisIconUtils::loadIcon("visible"));
+ m_selectorUI->bnToggleMask->setIcon(m_iconMaskOn);
} else {
- m_selectorUI->bnToggleMask->setIcon(KisIconUtils::loadIcon("novisible"));
+ m_selectorUI->bnToggleMask->setIcon(m_iconMaskOff);
}
m_selectorUI->colorSelector->setGamutMaskOn(b);
@@ -460,6 +436,10 @@
void ArtisticColorSelectorDock::slotGamutMaskSet(KoGamutMask *mask)
{
+ if (!mask) {
+ return;
+ }
+
m_selectedMask = mask;
if (m_selectedMask) {
diff --git a/plugins/dockers/artisticcolorselector/forms/wdgARCSSettings.ui b/plugins/dockers/artisticcolorselector/forms/wdgARCSSettings.ui
--- a/plugins/dockers/artisticcolorselector/forms/wdgARCSSettings.ui
+++ b/plugins/dockers/artisticcolorselector/forms/wdgARCSSettings.ui
@@ -7,7 +7,7 @@
0
0
358
- 520
+ 472
@@ -34,7 +34,7 @@
-
- Show lightness numbers on the value scale
+ Show numbered value scale
@@ -95,10 +95,51 @@
-
-
-
- Use HSV saturation component
+
+
+ QFrame::NoFrame
+
+
-
+
+
+ Value Scale Gamma
+
+
+
+ -
+
+
+ 1
+
+
+ 0.100000000000000
+
+
+ 50.000000000000000
+
+
+ 0.100000000000000
+
+
+ 1.000000000000000
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
diff --git a/plugins/dockers/artisticcolorselector/forms/wdgArtisticColorSelector.ui b/plugins/dockers/artisticcolorselector/forms/wdgArtisticColorSelector.ui
--- a/plugins/dockers/artisticcolorselector/forms/wdgArtisticColorSelector.ui
+++ b/plugins/dockers/artisticcolorselector/forms/wdgArtisticColorSelector.ui
@@ -6,103 +6,55 @@
0
0
- 360
- 279
+ 334
+ 284
100
100
-
+
-
-
-
-
-
- 1
- 0
-
-
-
- V
-
-
-
- -
-
-
-
- 2
- 0
-
-
-
- QFrame::StyledPanel
+
+
+ Toggle gamut mask
- 0
-
-
-
- -
-
-
-
- 1
- 0
-
+
-
- H
+
+ true
-
-
+
-
- 2
+
+ 0
0
-
- QFrame::StyledPanel
-
- 0
-
-
-
- -
-
-
-
- 1
- 0
-
+ Select a mask in "Gamut Masks" docker
-
- S
+
+ true
-
-
-
-
- 2
- 0
-
+
+
+ QFrame::Sunken
-
- QFrame::StyledPanel
-
-
- 0
+
+ Qt::Vertical
@@ -116,12 +68,15 @@
- 20
+ 16777215
16777215
+
+ Color wheel preferences
+
- Text-align:left
+
@@ -131,19 +86,6 @@
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
- -
-
-
-
-
-
- M
-
-
-
- -
-
-
-
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Select a mask in "Gamut Masks" docker
-
-
- true
-
-
-
-
-
diff --git a/plugins/dockers/artisticcolorselector/forms/wdgWheelPreferencesPopup.ui b/plugins/dockers/artisticcolorselector/forms/wdgWheelPreferencesPopup.ui
--- a/plugins/dockers/artisticcolorselector/forms/wdgWheelPreferencesPopup.ui
+++ b/plugins/dockers/artisticcolorselector/forms/wdgWheelPreferencesPopup.ui
@@ -132,17 +132,7 @@
-
- Reset Steps
-
-
- false
-
-
-
- -
-
-
- Reset Rings
+ Reset to default
false
diff --git a/plugins/dockers/artisticcolorselector/kis_arcs_constants.h b/plugins/dockers/artisticcolorselector/kis_arcs_constants.h
--- a/plugins/dockers/artisticcolorselector/kis_arcs_constants.h
+++ b/plugins/dockers/artisticcolorselector/kis_arcs_constants.h
@@ -1,7 +1,25 @@
+/*
+ * Copyright (c) 2018 Anna Medonosova
+ *
+ * This library 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; version 2.1 of the License.
+ *
+ * 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 Lesser 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.
+ */
+
#ifndef KIS_ARCS_CONSTANTS_H
#define KIS_ARCS_CONSTANTS_H
#include
+#include
static const int MIN_NUM_HUE_PIECES = 1;
static const int MIN_NUM_UI_HUE_PIECES = 2;
@@ -16,6 +34,16 @@
static const int DEFAULT_SATURATION_STEPS = 7;
static const int DEFAULT_VALUE_SCALE_STEPS = 11;
-static const QString UTF_INF_CHAR = "\u221E";
+// color scheme for the selector
+static const QColor COLOR_MIDDLE_GRAY = QColor(128,128,128,255);
+static const QColor COLOR_DARK = QColor(20,20,20,255);
+static const QColor COLOR_LIGHT = QColor(232,232,232,255);
+static const QColor COLOR_ACCENT = QColor(255,60,60,255);
+
+static const QColor COLOR_MASK_FILL = COLOR_MIDDLE_GRAY;
+static const QColor COLOR_MASK_OUTLINE = COLOR_LIGHT;
+static const QColor COLOR_MASK_CLEAR = COLOR_LIGHT;
+static const QColor COLOR_SELECTED = COLOR_ACCENT;
+static const QColor COLOR_NORMAL_OUTLINE = COLOR_MIDDLE_GRAY;
#endif // KIS_ARCS_CONSTANTS_H
diff --git a/plugins/dockers/artisticcolorselector/kis_color.h b/plugins/dockers/artisticcolorselector/kis_color.h
--- a/plugins/dockers/artisticcolorselector/kis_color.h
+++ b/plugins/dockers/artisticcolorselector/kis_color.h
@@ -62,36 +62,26 @@
inline float getB() const { return core()->rgb(2); }
inline float getH() const { return core()->hsx(0); }
inline float getS() const { return core()->hsx(1); }
- inline float getX() const { return core()->hsx(2); }
+ inline float getX(float gamma=1.0f) const { return pow(core()->hsx(2), 1/gamma); }
inline float getA() const { return core()->hsx(3); }
inline void setR(float v) { setRGB(v, core()->rgb(1), core()->rgb(2), core()->hsx(3)); }
inline void setG(float v) { setRGB(core()->rgb(0), v, core()->rgb(2), core()->hsx(3)); }
inline void setB(float v) { setRGB(core()->rgb(0), core()->rgb(1), v, core()->hsx(3)); }
inline void setH(float v) { setHSX(v, core()->hsx(1), core()->hsx(2), core()->hsx(3)); }
inline void setS(float v) { setHSX(core()->hsx(0), v, core()->hsx(2), core()->hsx(3)); }
- inline void setX(float v) { setHSX(core()->hsx(0), core()->hsx(1), v, core()->hsx(3)); }
+ inline void setX(float v, float gamma=1.0f) {
+ setHSX(core()->hsx(0), core()->hsx(1), v, core()->hsx(3), gamma);
+ }
inline void setA(float v) { core()->hsx(3) = qBound(0.0f, v, 1.0f); }
inline QColor getQColor() const { return QColor(getR()*255, getG()*255, getB()*255, getA()*255); }
- inline const VecHSXA& getHSX () const { return core()->hsx; }
- inline const VecRGB& getRGB () const { return core()->rgb; }
inline void setRGB(float r, float g, float b, float a=1.0f) { core()->setRGB(r, g, b, a); }
- inline void setHSX(float h, float s, float x, float a=1.0f) { core()->setHSX(h, s, x, a); }
-
- inline void setRGB(const VecRGB& rgb) {
- core()->rgb = rgb;
- core()->updateHSX();
- }
-
- inline void setHSX(const VecHSXA& hsx) {
- core()->hsx = hsx;
- core()->updateRGB();
+ inline void setHSX(float h, float s, float x, float a=1.0f, float gamma=1.0f) {
+ core()->setHSX(h, s, pow(x, gamma), a);
}
-
- void setRGBfromHue(float hue, float alpha=1.0f);
-
+
KisColor& operator = (const KisColor& color);
friend KisColor operator - (const KisColor& a, const KisColor& b) {
@@ -116,7 +106,6 @@
KisColor result;
result.core()->hsx = a.core()->hsx * b;
result.core()->updateRGB();
-// result.setH(a.getH());
return result;
}
diff --git a/plugins/dockers/artisticcolorselector/kis_color.cpp b/plugins/dockers/artisticcolorselector/kis_color.cpp
--- a/plugins/dockers/artisticcolorselector/kis_color.cpp
+++ b/plugins/dockers/artisticcolorselector/kis_color.cpp
@@ -76,7 +76,7 @@
KisColor::KisColor(Type type)
{
- initRGB(type, 0.0f, 0.0f, 0.0f, 0.0f);
+ initRGB(type, 0.0f, 0.0f, 0.0f, 1.0f);
}
KisColor::KisColor(float hue, float a, Type type)
@@ -160,15 +160,6 @@
core()->setHSX(h, s, x, a);
}
-void KisColor::setRGBfromHue(float hue, float alpha)
-{
- float r = 0;
- float g = 0;
- float b = 0;
- ::getRGB(r, g, b, hue);
- core()->setRGB(r, g, b, alpha);
-}
-
KisColor& KisColor::operator=(const KisColor& color)
{
initHSX(color.getType(), color.getH(), color.getS(), color.getX(), color.getA());
diff --git a/plugins/dockers/artisticcolorselector/kis_color_selector.h b/plugins/dockers/artisticcolorselector/kis_color_selector.h
--- a/plugins/dockers/artisticcolorselector/kis_color_selector.h
+++ b/plugins/dockers/artisticcolorselector/kis_color_selector.h
@@ -43,20 +43,12 @@
struct ColorRing
{
- ColorRing(): angle(0) { }
+ ColorRing()
+ : saturation(0)
+ , outerRadius(0)
+ , innerRadius(0)
+ { }
- Radian getPieceAngle() const { return RAD_360 / float(pieced.size()); }
- Radian getShift () const { return angle % getPieceAngle(); }
- Radian getMovedAngel() const { return angle - tmpAngle; }
-
- void setTemporaries(const KisColor& color) {
- tmpAngle = angle;
- tmpColor = color;
- }
-
- KisColor tmpColor;
- Radian tmpAngle;
- Radian angle;
float saturation;
float outerRadius;
float innerRadius;
@@ -66,14 +58,16 @@
public:
KisColorSelector(QWidget* parent, KisColor::Type type=KisColor::HSL);
- void setColorSpace(KisColor::Type type);
+ void setColorSpace(KisColor::Type type, float valueScaleGamma);
void setNumPieces(int num);
void setNumLightPieces(int num) __attribute__((optimize(0)));
void setNumRings(int num);
- void resetRings();
- void resetSelectedRing();
- void resetLight();
- void setLight(float light=0.0f, bool relative=true);
+
+ void setLight(float light=0.0f);
+
+ float gamma() const { return m_gamma; }
+ void setGamma(float gamma);
+
void setInverseSaturation(bool inverse);
void selectColor(const KisColor& color);
void setFgColor(const KisColor& fgColor);
@@ -103,9 +97,7 @@
qint32 getNumRings () const { return m_colorRings.size(); }
qint32 getNumPieces () const { return m_numPieces; }
qint32 getNumLightPieces () const { return m_numLightPieces; }
- qreal getLight () const { return m_light; }
bool isSaturationInverted() const { return m_inverseSaturation; }
- bool islightRelative () const { return m_relativeLight; }
quint32 getDefaultHueSteps () const { return m_defaultHueSteps; }
quint32 getDefaultSaturationSteps () const { return m_defaultSaturationSteps; }
@@ -135,27 +127,26 @@
void recalculateRings(quint8 numRings, quint8 numPieces);
void createRing(ColorRing& wheel, quint8 numPieces, qreal innerRadius, qreal outerRadius);
- void drawRing(QPainter& painter, int ringIndex, ColorRing& wheel, const QRect& rect);
+ void drawRing(QPainter& painter, ColorRing& wheel, const QRect& rect);
void drawOutline(QPainter& painter, const QRect& rect);
void drawBlip(QPainter& painter, const QRect& rect);
void drawLightStrip(QPainter& painter, const QRect& rect);
void drawGamutMaskShape(QPainter& painter, const QRect& rect);
- qint8 getHueIndex(Radian hue, Radian shift=0.0f) const;
+ qint8 getHueIndex(Radian hue) const;
qreal getHue(int hueIdx, Radian shift=0.0f) const;
qint8 getLightIndex(const QPointF& pt) const;
qint8 getLightIndex(qreal light) const;
- qreal getLight(qreal light, qreal hue, bool relative) const;
qreal getLight(const QPointF& pt) const;
qint8 getSaturationIndex(const QPointF& pt) const;
qint8 getSaturationIndex(qreal saturation) const;
qreal getSaturation(int saturationIdx) const;
-// QPointF mapCoord(const QPointF& pt, const QRectF& rect) const;
-
QPointF mapCoordToView(const QPointF& pt, const QRectF& viewRect) const;
QPointF mapCoordToUnit(const QPointF& pt, const QRectF& viewRect) const;
QPointF mapColorToUnit(const KisColor& color, bool invertSaturation = true) const;
+ Radian mapCoordToAngle(qreal x, qreal y) const;
+ QPointF mapHueToAngle(float hue) const;
public:
// This is a private interface for signal compressor, don't use it.
@@ -167,8 +158,7 @@
quint8 m_numPieces;
quint8 m_numLightPieces;
bool m_inverseSaturation;
- bool m_relativeLight;
- float m_light;
+ float m_gamma;
qint8 m_selectedRing;
qint8 m_selectedPiece;
qint8 m_selectedLightPiece;
@@ -180,13 +170,10 @@
QRect m_renderArea;
QRect m_lightStripArea;
bool m_mouseMoved;
- Acs::ColorRole m_selectedColorRole;
QPointF m_clickPos;
qint8 m_clickedRing;
QVector m_colorRings;
Qt::MouseButtons m_pressedButtons;
- const QColor m_grayColor;
- const QColor m_gamutMaskColor;
// docker settings
quint8 m_defaultHueSteps;
diff --git a/plugins/dockers/artisticcolorselector/kis_color_selector.cpp b/plugins/dockers/artisticcolorselector/kis_color_selector.cpp
--- a/plugins/dockers/artisticcolorselector/kis_color_selector.cpp
+++ b/plugins/dockers/artisticcolorselector/kis_color_selector.cpp
@@ -36,36 +36,40 @@
#include "kis_color_selector.h"
+//#define DEBUG_ARC_SELECTOR
+
KisColorSelector::KisColorSelector(QWidget* parent, KisColor::Type type)
: QWidget(parent)
, m_colorSpace(type)
, m_inverseSaturation(false)
- , m_relativeLight(true)
- , m_light(0.5f)
- , m_selectedColorRole(Acs::Foreground)
+ , m_gamma(1.0f)
, m_clickedRing(-1)
, m_gamutMaskOn(false)
- , m_widgetUpdatesSelf(false)
- , m_grayColor(QColor(128,128,128,255))
- , m_gamutMaskColor(QColor(128,128,128,255))
, m_currentGamutMask(nullptr)
, m_maskPreviewActive(true)
-{
+ , m_widgetUpdatesSelf(false)
+{
m_viewConverter = new KisGamutMaskViewConverter();
- recalculateRings(9, 12);
- recalculateAreas(9);
+ recalculateRings(DEFAULT_SATURATION_STEPS, DEFAULT_HUE_STEPS);
+ recalculateAreas(DEFAULT_VALUE_SCALE_STEPS);
selectColor(KisColor(Qt::red, KisColor::HSY));
using namespace std::placeholders; // For _1 placeholder
auto function = std::bind(&KisColorSelector::slotUpdateColorAndPreview, this, _1);
m_updateColorCompressor.reset(new ColorCompressorType(20 /* ms */, function));
}
-void KisColorSelector::setColorSpace(KisColor::Type type)
+void KisColorSelector::setColorSpace(KisColor::Type type, float valueScaleGamma)
{
m_colorSpace = type;
+ setGamma(valueScaleGamma);
m_selectedColor = KisColor(m_selectedColor, m_colorSpace);
+
+#ifdef DEBUG_ARC_SELECTOR
+ dbgPlugins << "KisColorSelector::setColorSpace: set to:" << m_colorSpace;
+#endif
+
update();
}
@@ -76,7 +80,7 @@
recalculateAreas(quint8(num));
if (m_selectedLightPiece >= 0)
- m_selectedLightPiece = getLightIndex(m_selectedColor.getX());
+ m_selectedLightPiece = getLightIndex(m_selectedColor.getX(m_gamma));
update();
}
@@ -110,74 +114,63 @@
m_selectedColor = KisColor(color, m_colorSpace);
m_selectedPiece = getHueIndex(m_selectedColor.getH() * PI2);
m_selectedRing = getSaturationIndex(m_selectedColor.getS());
- m_selectedLightPiece = getLightIndex(m_selectedColor.getX());
+ m_selectedLightPiece = getLightIndex(m_selectedColor.getX(m_gamma));
update();
}
void KisColorSelector::setFgColor(const KisColor& fgColor)
{
if (!m_widgetUpdatesSelf) {
m_fgColor = KisColor(fgColor, m_colorSpace);
+ m_selectedColor = KisColor(fgColor, m_colorSpace);
+
+#ifdef DEBUG_ARC_SELECTOR
dbgPlugins << "KisColorSelector::setFgColor: m_fgColor set to:"
<< "H:" << m_fgColor.getH()
<< "S:" << m_fgColor.getS()
- << "X:" << m_fgColor.getX();
+ << "X:" << m_fgColor.getX(m_gamma);
- m_selectedColor = KisColor(fgColor, m_colorSpace);
dbgPlugins << "KisColorSelector::setFgColor: m_selectedColor set to:"
<< "H:" << m_selectedColor.getH()
<< "S:" << m_selectedColor.getS()
- << "X:" << m_selectedColor.getX();
+ << "X:" << m_selectedColor.getX(m_gamma);
+#endif
update();
- } else {
- dbgPlugins << "KisColorSelector::setFgColor: m_widgetUpdatesSelf == true, not updating color";
}
}
void KisColorSelector::setBgColor(const KisColor& bgColor)
{
if (!m_widgetUpdatesSelf) {
m_bgColor = KisColor(bgColor, m_colorSpace);
+#ifdef DEBUG_ARC_SELECTOR
dbgPlugins << "KisColorSelector::setBgColor: m_bgColor set to:"
<< "H:" << m_bgColor.getH()
<< "S:" << m_bgColor.getS()
- << "X:" << m_bgColor.getX();
+ << "X:" << m_bgColor.getX(m_gamma);
+#endif
update();
- } else {
- dbgPlugins << "KisColorSelector::setBgColor: m_widgetUpdatesSelf == true, not updating color";
}
}
-void KisColorSelector::resetRings()
+void KisColorSelector::setLight(float light)
{
- for(int i=0; i= 0) {
- m_colorRings[m_selectedRing].angle = 0.0f;
- update();
+void KisColorSelector::setGamma(float gamma) {
+ if (m_colorSpace == KisColor::HSY) {
+ m_gamma = gamma;
+ } else {
+ m_gamma = 1.0f;
}
-}
-void KisColorSelector::setLight(float light, bool relative)
-{
- m_light = qBound(0.0f, light, 1.0f);
+#ifdef DEBUG_ARC_SELECTOR
+ dbgPlugins << "KisColorSelector::setGamma: set to:" << m_gamma;
+#endif
- m_selectedColor.setX(getLight(m_light, m_selectedColor.getH(), relative));
- m_relativeLight = relative;
- m_selectedLightPiece = getLightIndex(m_selectedColor.getX());
update();
}
@@ -226,7 +219,6 @@
void KisColorSelector::setGamutMaskOn(bool gamutMaskOn)
{
- // do not allow the mask on, if it is a nullptr
if (m_currentGamutMask) {
m_gamutMaskOn = gamutMaskOn;
update();
@@ -261,17 +253,39 @@
QPointF KisColorSelector::mapColorToUnit(const KisColor& color, bool invertSaturation) const
{
- qreal angle = color.getH() * 2.0 * M_PI;
-
qreal radius;
if (invertSaturation && m_inverseSaturation) {
radius = 1.0 - color.getS();
} else {
radius = color.getS();
}
- qreal x = std::cos(angle)*radius;
- qreal y = std::sin(-angle)*radius;
+ QPointF hueCoord = mapHueToAngle(color.getH());
+ qreal x = hueCoord.x()*radius;
+ qreal y = hueCoord.y()*radius;
+
+ return QPointF(x,y);
+}
+
+KisColorSelector::Radian KisColorSelector::mapCoordToAngle(qreal x, qreal y) const
+{
+ float angle = std::atan2(-y, -x);
+
+#ifdef DEBUG_ARC_SELECTOR
+ dbgPlugins << "KisColorSelector::mapCoordToAngle: "
+ << "X:" << x
+ << "Y:" << y
+ << "angle:" << angle;
+#endif
+
+ return angle;
+}
+
+QPointF KisColorSelector::mapHueToAngle(float hue) const
+{
+ float angle = hue * 2.0 * M_PI - M_PI;
+ float x = std::cos(angle);
+ float y = std::sin(angle);
return QPointF(x,y);
}
@@ -295,18 +309,6 @@
return qint8(qRound(light * (getNumLightPieces()-1)));
}
-qreal KisColorSelector::getLight(qreal light, qreal hue, bool relative) const
-{
- if (relative) {
- KisColor color(hue, 1.0f, m_colorSpace);
- qreal cl = color.getX();
- light = (light * 2.0f) - 1.0f;
- return (light < 0.0f) ? (cl + cl*light) : (cl + (1.0f-cl)*light);
- }
-
- return light;
-}
-
qreal KisColorSelector::getLight(const QPointF& pt) const
{
qint8 clickedLightPiece = getLightIndex(pt);
@@ -321,9 +323,8 @@
return qreal(0);
}
-qint8 KisColorSelector::getHueIndex(Radian hue, Radian shift) const
+qint8 KisColorSelector::getHueIndex(Radian hue) const
{
- hue -= shift;
qreal partSize = 1.0 / qreal(getNumPieces());
return qint8(qRound(hue.scaled(0.0f, 1.0f) / partSize) % getNumPieces());
}
@@ -362,7 +363,11 @@
void KisColorSelector::recalculateAreas(quint8 numLightPieces)
{
- const qreal LIGHT_STRIP_RATIO = 0.075;
+
+ qreal LIGHT_STRIP_RATIO = 0.075;
+ if (m_showValueScaleNumbers) {
+ LIGHT_STRIP_RATIO = 0.25;
+ }
int width = QWidget::width();
int height = QWidget::height();
@@ -451,11 +456,12 @@
void KisColorSelector::requestUpdateColorAndPreview(const KisColor &color, Acs::ColorRole role)
{
+#ifdef DEBUG_ARC_SELECTOR
dbgPlugins << "KisColorSelector::requestUpdateColorAndPreview: requesting update to: "
<< "H:" << color.getH()
<< "S:" << color.getS()
- << "X:" << color.getX();
-
+ << "X:" << color.getX(m_gamma);
+#endif
m_updateColorCompressor->start(qMakePair(color, role));
}
@@ -466,52 +472,52 @@
if (selectAsFgColor) { m_fgColor = color.first; }
else { m_bgColor = color.first; }
- m_selectedColor = color.first;
- m_selectedColorRole = color.second;
+ m_selectedColor = color.first;
+#ifdef DEBUG_ARC_SELECTOR
dbgPlugins << "KisColorSelector::slotUpdateColorAndPreview: m_selectedColor set to:"
<< "H:" << m_selectedColor.getH()
<< "S:" << m_selectedColor.getS()
- << "X:" << m_selectedColor.getX()
- << "role:" << m_selectedColorRole;
-
+ << "X:" << m_selectedColor.getX(m_gamma);
+#endif
if (selectAsFgColor) { emit sigFgColorChanged(m_selectedColor); }
else { emit sigBgColorChanged(m_selectedColor); }
}
-void KisColorSelector::drawRing(QPainter& painter, int ringIndex, KisColorSelector::ColorRing& ring, const QRect& rect)
+void KisColorSelector::drawRing(QPainter& painter, KisColorSelector::ColorRing& ring, const QRect& rect)
{
painter.save();
painter.setRenderHint(QPainter::Antialiasing, true);
painter.resetTransform();
painter.translate(rect.width()/2, rect.height()/2);
if (ring.pieced.size() > 1) {
- painter.rotate(-ring.getShift().degrees());
+ QTransform mirror;
+ mirror.rotate(180, Qt::YAxis);
+ painter.setTransform(mirror, true);
painter.scale(rect.width()/2, rect.height()/2);
-// painter.setPen(Qt::NoPen);
- QPen normalPen = QPen(QBrush(m_grayColor), 0.005);
- QPen clearMaskPen = QPen(QBrush(Qt::white), 0.005);
+ QPen normalPen = QPen(QBrush(COLOR_NORMAL_OUTLINE), 0.005);
+ QPen clearMaskPen = QPen(QBrush(COLOR_MASK_CLEAR), 0.005);
QBrush brush(Qt::SolidPattern);
for(int i=0; i= 1.0f) ? (hue - 1.0f) : hue;
hue = (hue < 0.0f) ? (hue + 1.0f) : hue;
KisColor color(hue, 1.0f, m_colorSpace);
color.setS(ring.saturation);
- color.setX(getLight(m_light, hue, m_relativeLight));
+ color.setX(m_selectedColor.getX(m_gamma), m_gamma);
if(m_gamutMaskOn && m_enforceGamutMask && colorIsClear(color)) {
painter.setPen(clearMaskPen);
} else {
painter.setPen(normalPen);
}
if ((m_enforceGamutMask) && (!colorIsClear(color))) {
- brush.setColor(m_gamutMaskColor);
+ brush.setColor(COLOR_MASK_FILL);
} else {
brush.setColor(color.getQColor());
}
@@ -522,29 +528,28 @@
}
else {
KisColor colors[7] = {
- KisColor(Qt::red , m_colorSpace),
- KisColor(Qt::yellow , m_colorSpace),
- KisColor(Qt::green , m_colorSpace),
KisColor(Qt::cyan , m_colorSpace),
- KisColor(Qt::blue , m_colorSpace),
+ KisColor(Qt::green , m_colorSpace),
+ KisColor(Qt::yellow , m_colorSpace),
+ KisColor(Qt::red , m_colorSpace),
KisColor(Qt::magenta, m_colorSpace),
- KisColor(Qt::red , m_colorSpace)
+ KisColor(Qt::blue , m_colorSpace),
+ KisColor(Qt::cyan , m_colorSpace)
};
QConicalGradient gradient(0, 0, 0);
for(int i=0; i<=6; ++i) {
qreal hue = float(i) / 6.0f;
colors[i].setS(ring.saturation);
- colors[i].setX(getLight(m_light, hue, m_relativeLight));
+ colors[i].setX(m_selectedColor.getX(m_gamma), m_gamma);
gradient.setColorAt(hue, colors[i].getQColor());
}
painter.scale(rect.width()/2, rect.height()/2);
painter.fillPath(ring.pieced[0], QBrush(gradient));
}
-// painter.resetTransform();
painter.restore();
}
@@ -555,26 +560,18 @@
painter.translate(rect.x() + rect.width()/2, rect.y() + rect.height()/2);
painter.scale(rect.width()/2, rect.height()/2);
- QPen normalPen = QPen(QBrush(m_grayColor), 0.005);
- QPen selectedPen = QPen(QBrush(Qt::red), 0.01);
+ QPen normalPen = QPen(QBrush(COLOR_NORMAL_OUTLINE), 0.005);
+ QPen selectedPen = QPen(QBrush(COLOR_SELECTED), 0.01);
painter.setPen(normalPen);
if (getNumPieces() > 1) {
-// for(int i=0; i= 0 && m_selectedPiece >= 0) {
painter.resetTransform();
painter.translate(rect.x() + rect.width()/2, rect.y() + rect.height()/2);
- painter.rotate(-m_colorRings[m_selectedRing].getShift().degrees());
+ QTransform mirror;
+ mirror.rotate(180, Qt::YAxis);
+ painter.setTransform(mirror, true);
painter.scale(rect.width()/2, rect.height()/2);
painter.setPen(selectedPen);
@@ -595,86 +592,124 @@
painter.drawEllipse(QRectF(-iRad, -iRad, iRad*2.0, iRad*2.0));
painter.drawEllipse(QRectF(-oRad, -oRad, oRad*2.0, oRad*2.0));
- float c = std::cos(-m_selectedColor.getH() * PI2);
- float s = std::sin(-m_selectedColor.getH() * PI2);
- painter.drawLine(QPointF(c*iRad, s*iRad), QPointF(c*oRad, s*oRad));
+ QPointF lineCoords = mapHueToAngle(m_selectedColor.getH());
+ painter.drawLine(QPointF(lineCoords.x()*iRad, lineCoords.y()*iRad), QPointF(lineCoords.x()*oRad, lineCoords.y()*oRad));
}
}
}
void KisColorSelector::drawLightStrip(QPainter& painter, const QRect& rect)
{
- bool isVertical = true;
qreal penSize = qreal(qMin(QWidget::width(), QWidget::height())) / 200.0;
- KisColor color(m_fgColor);
+ KisColor valueScaleColor(m_selectedColor);
+ KisColor grayScaleColor(Qt::gray, m_colorSpace);
+ int rectSize = rect.height();
painter.resetTransform();
+ painter.save();
+ painter.setRenderHint(QPainter::Antialiasing, true);
- if (getNumLightPieces() > 1) {
- painter.setRenderHint(QPainter::Antialiasing, true);
- painter.setPen(QPen(QBrush(Qt::red), penSize));
+ QTransform matrix;
+ matrix.translate(rect.x(), rect.y());
+ matrix.scale(rect.width(), rect.height());
- QTransform matrix;
- matrix.translate(rect.x(), rect.y());
- matrix.scale(rect.width(), rect.height());
+ qreal rectColorLeftX;
+ qreal rectColorWidth;
+ if (m_showValueScaleNumbers) {
+ rectColorLeftX = 0.6;
+ rectColorWidth = 0.4;
+ } else {
+ rectColorLeftX = 0.0;
+ rectColorWidth = 1.0;
+ }
+
+ if (getNumLightPieces() > 1) {
for(int i=0; i coord X:" << fgColorPos.x() << " Y:" << fgColorPos.y();
+#endif
-
- painter.setPen(QPen(QBrush(Qt::white), 0.01));
+ painter.setPen(QPen(QBrush(COLOR_LIGHT), 0.01));
painter.drawEllipse(fgColorPos, 0.05, 0.05);
- painter.setPen(QPen(QBrush(Qt::black), 0.01));
+ painter.setPen(QPen(QBrush(COLOR_DARK), 0.01));
painter.setBrush(m_fgColor.getQColor());
painter.drawEllipse(fgColorPos, 0.04, 0.04);
}
@@ -709,16 +745,18 @@
painter.scale(rect.width()/2, rect.height()/2);
painter.setPen(Qt::NoPen);
- painter.setBrush(m_gamutMaskColor);
+ painter.setBrush(COLOR_MASK_FILL);
painter.drawEllipse(QPointF(0,0), 1.0, 1.0);
painter.resetTransform();
-// painter.setCompositionMode(QPainter::CompositionMode_Xor);
- painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
m_currentGamutMask->paint(painter, *m_viewConverter, m_maskPreviewActive);
+ painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+ m_currentGamutMask->paintStroke(painter, *m_viewConverter, m_maskPreviewActive);
+
painter.restore();
}
@@ -762,11 +800,10 @@
wdgPainter.restore();
for(int i=0; ilocalPos(), m_renderArea);
m_mouseMoved = false;
m_pressedButtons = event->buttons();
m_clickedRing = getSaturationIndex(m_clickPos);
+ Acs::ColorRole colorRole = Acs::buttonsToRole(Qt::NoButton, m_pressedButtons);
qint8 clickedLightPiece = getLightIndex(event->localPos());
if (clickedLightPiece >= 0) {
- setLight(getLight(event->localPos()), m_relativeLight);
+ setLight(getLight(event->localPos()));
m_selectedLightPiece = clickedLightPiece;
- requestUpdateColorAndPreview(m_selectedColor, Acs::buttonsToRole(Qt::NoButton, m_pressedButtons));
+ requestUpdateColorAndPreview(m_selectedColor, colorRole);
m_mouseMoved = true;
}
else if (m_clickedRing >= 0) {
- if (getNumPieces() > 1) {
- for(int i=0; ilocalPos(), m_renderArea);
qint8 clickedLightPiece = getLightIndex(event->localPos());
+ Acs::ColorRole colorRole = Acs::buttonsToRole(Qt::NoButton, m_pressedButtons);
if (clickedLightPiece >= 0) {
- setLight(getLight(event->localPos()), m_relativeLight);
+ setLight(getLight(event->localPos()));
m_selectedLightPiece = clickedLightPiece;
- requestUpdateColorAndPreview(m_selectedColor, m_selectedColorRole);
+ requestUpdateColorAndPreview(m_selectedColor, colorRole);
}
if (m_clickedRing < 0)
return;
- if (getNumPieces() > 1) {
- float angle = std::atan2(dragPos.x(), dragPos.y()) - std::atan2(m_clickPos.x(), m_clickPos.y());
- float dist = std::sqrt(dragPos.x()*dragPos.x() + dragPos.y()*dragPos.y()) * 0.80f;
- float threshold = 5.0f * (1.0f-(dist*dist));
-
- if (qAbs(angle * TO_DEG) >= threshold || m_mouseMoved) {
- bool selectedRingMoved = true;
-
- if (m_pressedButtons & Qt::RightButton) {
- selectedRingMoved = m_clickedRing == m_selectedRing;
- m_colorRings[m_clickedRing].angle = m_colorRings[m_clickedRing].tmpAngle + angle;
- }
- else for(int i=0; i= 0) {
- Radian angle = std::atan2(m_clickPos.x(), m_clickPos.y()) - RAD_90;
- KisColor color;
+ Radian angle = mapCoordToAngle(m_clickPos.x(), m_clickPos.y());
+ KisColor color(m_colorSpace);
- qint8 hueIndex = getHueIndex(angle, m_colorRings[m_clickedRing].getShift());
+ qint8 hueIndex = getHueIndex(angle);
if (getNumPieces() > 1) {
- color.setH(getHue(hueIndex, m_colorRings[m_clickedRing].getShift()));
+ color.setH(getHue(hueIndex));
} else {
color.setH(angle.scaled(0.0f, 1.0f));
}
color.setS(getSaturation(m_clickedRing));
- color.setX(getLight(m_light, color.getH(), m_relativeLight));
+ color.setX(m_selectedColor.getX(m_gamma), m_gamma);
if ((!m_enforceGamutMask) || colorIsClear(color)) {
- m_selectedColor.setHSX(color.getH(), color.getS(), color.getX());
+ m_selectedColor.setHSX(color.getH(), color.getS(), color.getX(m_gamma), color.getA(), m_gamma);
m_selectedPiece = hueIndex;
m_selectedRing = m_clickedRing;
- requestUpdateColorAndPreview(m_selectedColor, Acs::buttonsToRole(Qt::NoButton, m_pressedButtons));
+ requestUpdateColorAndPreview(m_selectedColor, colorRole);
}
}
else if (m_mouseMoved)
- requestUpdateColorAndPreview(m_selectedColor, m_selectedColorRole);
+ requestUpdateColorAndPreview(m_selectedColor, colorRole);
m_clickedRing = -1;
m_widgetUpdatesSelf = false;
+#ifdef DEBUG_ARC_SELECTOR
dbgPlugins << "KisColorSelector::ReleasePressEvent: m_widgetUpdatesSelf = false";
+#endif
update();
}
@@ -934,7 +958,9 @@
void KisColorSelector::leaveEvent(QEvent* /*e*/)
{
m_widgetUpdatesSelf = false;
+#ifdef DEBUG_ARC_SELECTOR
dbgPlugins << "KisColorSelector::leaveEvent: m_widgetUpdatesSelf = false";
+#endif
}
void KisColorSelector::saveSettings()
@@ -946,67 +972,60 @@
cfg.writeEntry("ArtColorSel.LightPieces", qint32(m_numLightPieces));
cfg.writeEntry("ArtColorSel.InversedSaturation", m_inverseSaturation);
- cfg.writeEntry("ArtColorSel.RelativeLight" , m_relativeLight);
- cfg.writeEntry("ArtColorSel.Light" , m_light);
+ cfg.writeEntry("ArtColorSel.Light" , m_selectedColor.getX(m_gamma));
cfg.writeEntry("ArtColorSel.SelColorH", m_selectedColor.getH());
cfg.writeEntry("ArtColorSel.SelColorS", m_selectedColor.getS());
- cfg.writeEntry("ArtColorSel.SelColorX", m_selectedColor.getX());
+ cfg.writeEntry("ArtColorSel.SelColorX", m_selectedColor.getX(m_gamma));
cfg.writeEntry("ArtColorSel.SelColorA", m_selectedColor.getA());
cfg.writeEntry("ArtColorSel.defaultHueSteps", quint32(m_defaultHueSteps));
cfg.writeEntry("ArtColorSel.defaultSaturationSteps", quint32(m_defaultSaturationSteps));
cfg.writeEntry("ArtColorSel.defaultValueScaleSteps", quint32(m_defaultValueScaleSteps));
cfg.writeEntry("ArtColorSel.showBgColor", m_showBgColor);
cfg.writeEntry("ArtColorSel.showColorBlip", m_showColorBlip);
- cfg.writeEntry("ArtColorSel.showValueScaleNumber", m_showValueScaleNumbers);
+ cfg.writeEntry("ArtColorSel.showValueScale", m_showValueScaleNumbers);
cfg.writeEntry("ArtColorSel.enforceGamutMask", m_enforceGamutMask);
cfg.writeEntry("ArtColorSel.maskPreviewActive", m_maskPreviewActive);
-
- QList angles;
-
- for(int i=0; i("ArtColorSel.ColorSpace" , KisColor::HSY)));
m_defaultHueSteps = cfg.readEntry("ArtColorSel.defaultHueSteps", DEFAULT_HUE_STEPS);
m_defaultSaturationSteps = cfg.readEntry("ArtColorSel.defaultSaturationSteps", DEFAULT_SATURATION_STEPS);
m_defaultValueScaleSteps = cfg.readEntry("ArtColorSel.defaultValueScaleSteps", DEFAULT_VALUE_SCALE_STEPS);
setNumLightPieces(cfg.readEntry("ArtColorSel.LightPieces", DEFAULT_VALUE_SCALE_STEPS));
+ KisColor::Type colorSpace = KisColor::Type(cfg.readEntry("ArtColorSel.ColorSpace" , KisColor::HSY));
+ float valueScaleGamma = cfg.readEntry("ArtColorSel.valueScaleGamma", 2.2f);
+ if (colorSpace == KisColor::HSY) {
+ setGamma(valueScaleGamma);
+
+ }
+
+ setColorSpace(colorSpace, valueScaleGamma);
+
m_selectedColor.setH(cfg.readEntry("ArtColorSel.SelColorH", 0.0f));
m_selectedColor.setS(cfg.readEntry("ArtColorSel.SelColorS", 0.0f));
- m_selectedColor.setX(cfg.readEntry("ArtColorSel.SelColorX", 0.0f));
+ m_selectedColor.setX(cfg.readEntry("ArtColorSel.SelColorX", 0.0f), m_gamma);
m_selectedColor.setA(1.0f);
setInverseSaturation(cfg.readEntry("ArtColorSel.InversedSaturation", false));
- setLight(cfg.readEntry("ArtColorSel.Light", 0.5f), cfg.readEntry("ArtColorSel.RelativeLight", true));
+ setLight(cfg.readEntry("ArtColorSel.Light", 0.5f));
- setNumRings(cfg.readEntry("ArtColorSel.NumRings" , DEFAULT_SATURATION_STEPS));
+ setNumRings(cfg.readEntry("ArtColorSel.NumRings", DEFAULT_SATURATION_STEPS));
setNumPieces(cfg.readEntry("ArtColorSel.RingPieces", DEFAULT_HUE_STEPS));
- QList angles = cfg.readList("ArtColorSel.RingAngles");
-
- for (int i = 0; i < m_colorRings.size(); ++i) {
- if (i < angles.size() && i < m_colorRings.size()) {
- m_colorRings[i].angle = angles[i];
- }
- }
-
m_showBgColor = cfg.readEntry("ArtColorSel.showBgColor", true);
m_showColorBlip = cfg.readEntry("ArtColorSel.showColorBlip", true);
- m_showValueScaleNumbers = cfg.readEntry("ArtColorSel.showValueScaleNumber", false);
- m_enforceGamutMask = cfg.readEntry("ArtColorSel.enforceGamutMask", true);
+ m_showValueScaleNumbers = cfg.readEntry("ArtColorSel.showValueScale", false);
+ m_enforceGamutMask = cfg.readEntry("ArtColorSel.enforceGamutMask", false);
m_maskPreviewActive = cfg.readEntry("ArtColorSel.maskPreviewActive", true);
@@ -1046,6 +1065,7 @@
void KisColorSelector::setShowValueScaleNumbers(bool value)
{
m_showValueScaleNumbers = value;
+ recalculateAreas(quint8(getNumLightPieces()));
update();
}
diff --git a/plugins/dockers/gamutmask/KisGamutMaskChooser.h b/plugins/dockers/gamutmask/KisGamutMaskChooser.h
--- a/plugins/dockers/gamutmask/KisGamutMaskChooser.h
+++ b/plugins/dockers/gamutmask/KisGamutMaskChooser.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (c) 2018 Anna Medonosova
+ *
+ * This library 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; version 2.1 of the License.
+ *
+ * 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 Lesser 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.
+ */
+
#ifndef KISGAMUTMASKCHOOSER_H
#define KISGAMUTMASKCHOOSER_H
@@ -14,6 +31,8 @@
explicit KisGamutMaskChooser(QWidget *parent = nullptr);
~KisGamutMaskChooser() override;
+ void setCurrentResource(KoResource* resource);
+
Q_SIGNALS:
void sigGamutMaskSelected(KoGamutMask* mask);
diff --git a/plugins/dockers/gamutmask/KisGamutMaskChooser.cpp b/plugins/dockers/gamutmask/KisGamutMaskChooser.cpp
--- a/plugins/dockers/gamutmask/KisGamutMaskChooser.cpp
+++ b/plugins/dockers/gamutmask/KisGamutMaskChooser.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (c) 2018 Anna Medonosova
+ *
+ * This library 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; version 2.1 of the License.
+ *
+ * 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 Lesser 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 "KisGamutMaskChooser.h"
#include
@@ -64,6 +81,8 @@
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins(0,0,0,0);
+ // TODO: menu for view mode change
+
layout->addWidget(m_itemChooser);
setLayout(layout);
@@ -75,6 +94,11 @@
}
+void KisGamutMaskChooser::setCurrentResource(KoResource *resource)
+{
+ m_itemChooser->setCurrentResource(resource);
+}
+
void KisGamutMaskChooser::resourceSelected(KoResource* resource)
{
emit sigGamutMaskSelected(static_cast(resource));
diff --git a/plugins/dockers/gamutmask/forms/wdgGamutMaskChooser.ui b/plugins/dockers/gamutmask/forms/wdgGamutMaskChooser.ui
--- a/plugins/dockers/gamutmask/forms/wdgGamutMaskChooser.ui
+++ b/plugins/dockers/gamutmask/forms/wdgGamutMaskChooser.ui
@@ -6,8 +6,8 @@
0
0
- 358
- 336
+ 363
+ 322
@@ -22,51 +22,81 @@
-
-
-
-
-
-
-
- 0
- 0
-
-
-
- Select a mask
-
-
-
- -
-
-
- Apply To Selector
-
-
-
-
-
-
- -
-
-
- Edit
-
-
-
-
-
-
- -
-
-
- Delete
-
-
-
-
-
-
-
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Plain
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Create new mask
+
+
+
+
+
+
+ -
+
+
+ Edit selected mask
+
+
+
+
+
+
+ -
+
+
+ Duplicate selected mask
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Delete selected mask
+
+
+
+
+
+
+
+
-
@@ -184,16 +214,6 @@
- -
-
-
- Save As New
-
-
-
-
-
-
diff --git a/plugins/dockers/gamutmask/gamutmask_dock.h b/plugins/dockers/gamutmask/gamutmask_dock.h
--- a/plugins/dockers/gamutmask/gamutmask_dock.h
+++ b/plugins/dockers/gamutmask/gamutmask_dock.h
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
#include
#include
@@ -35,7 +36,6 @@
#include
class KisCanvasResourceProvider;
-class KisColor;
class QButtonGroup;
class QMenu;
@@ -55,7 +55,7 @@
public: // KoResourceServerObserver
void unsetResourceServer() override;
- void resourceAdded(KoGamutMask* resource) override {}
+ void resourceAdded(KoGamutMask* /*resource*/) override {};
void removingResource(KoGamutMask* resource) override;
void resourceChanged(KoGamutMask* resource) override;
void syncTaggedResourceView() override {}
@@ -74,29 +74,42 @@
void slotGamutMaskCancelEdit();
void slotGamutMaskSelected(KoGamutMask* mask);
void slotGamutMaskPreview();
- void slotGamutMaskSaveNew();
+ void slotGamutMaskCreateNew();
+ void slotGamutMaskDuplicate();
void slotGamutMaskDelete();
- void slotGamutMaskSet();
void slotDocumentRemoved(QString filename);
+ void slotViewChanged();
+ void slotDocumentSaved();
private:
- KisCanvasResourceProvider* m_resourceProvider;
-
void closeMaskDocument();
void openMaskEditor();
void cancelMaskEdit();
- void saveSelectedMaskResource();
- void finalizeMaskSave();
+ void selectMask(KoGamutMask* mask, bool notifyItemChooser = true);
+ bool saveSelectedMaskResource();
+ void deleteMask();
+ int getUserFeedback(QString message
+ , QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No
+ , QMessageBox::StandardButton defaultButton = QMessageBox::Yes);
+
+ int saveOrCancel(QMessageBox::StandardButton defaultAction = QMessageBox::Save);
- bool m_selfClosingMaskFile;
+ KoGamutMask* createMaskResource(KoGamutMask* sourceMask, QString newTitle);
- KoGamutMask *addDuplicateResource(QString newTitle);
QPair resolveMaskTitle(QString suggestedTitle);
QList getShapesFromLayer();
KisShapeLayerSP getShapeLayer();
+ KisCanvasResourceProvider* m_resourceProvider;
+
+ bool m_selfClosingTemplate;
+ bool m_externalTemplateClose;
+ bool m_creatingNewMask;
+ bool m_templatePrevSaved;
+ bool m_selfSelectingMask;
+
GamutMaskChooserUI* m_dockerUI;
KoResourceItemChooser* m_maskChooser;
diff --git a/plugins/dockers/gamutmask/gamutmask_dock.cpp b/plugins/dockers/gamutmask/gamutmask_dock.cpp
--- a/plugins/dockers/gamutmask/gamutmask_dock.cpp
+++ b/plugins/dockers/gamutmask/gamutmask_dock.cpp
@@ -46,6 +46,10 @@
#include "gamutmask_dock.h"
#include
#include
+#include
+#include
+
+#include
#include "ui_wdgGamutMaskChooser.h"
@@ -62,23 +66,28 @@
GamutMaskDock::GamutMaskDock()
: QDockWidget(i18n("Gamut Masks"))
, m_resourceProvider(0)
+ , m_selfClosingTemplate(false)
+ , m_externalTemplateClose(false)
+ , m_creatingNewMask(false)
+ , m_templatePrevSaved(false)
+ , m_selfSelectingMask(false)
+ , m_selectedMask(nullptr)
, m_maskDocument(nullptr)
, m_view(nullptr)
- , m_selectedMask(nullptr)
{
m_dockerUI = new GamutMaskChooserUI();
m_dockerUI->bnMaskEditor->setIcon(KisIconUtils::loadIcon("dirty-preset"));
- m_dockerUI->bnMaskSet->setIcon(KisIconUtils::loadIcon("dialog-ok"));
m_dockerUI->bnMaskDelete->setIcon(KisIconUtils::loadIcon("deletelayer"));
- m_dockerUI->maskPropertiesBox->setVisible(false);
+ m_dockerUI->bnMaskNew->setIcon(KisIconUtils::loadIcon("list-add"));
+ m_dockerUI->bnMaskDuplicate->setIcon(KisIconUtils::loadIcon("duplicatelayer"));
- m_dockerUI->bnSaveMaskNew->setIcon(KisIconUtils::loadIcon("list-add"));
+ m_dockerUI->maskPropertiesBox->setVisible(false);
m_dockerUI->bnSaveMask->setIcon(KisIconUtils::loadIcon("document-save"));
m_dockerUI->bnCancelMaskEdit->setIcon(KisIconUtils::loadIcon("dialog-cancel"));
m_dockerUI->bnPreviewMask->setIcon(KisIconUtils::loadIcon("visible"));
- QRegularExpression maskTitleRegex("^[-_\\sA-Za-z0-9]+$");
+ QRegularExpression maskTitleRegex("^[-_\\(\\)\\sA-Za-z0-9]+$");
QRegularExpressionValidator* m_maskTitleValidator = new QRegularExpressionValidator(maskTitleRegex, this);
m_dockerUI->maskTitleEdit->setValidator(m_maskTitleValidator);
@@ -92,9 +101,9 @@
connect(m_dockerUI->bnMaskEditor , SIGNAL(clicked()) , SLOT(slotGamutMaskEdit()));
connect(m_dockerUI->maskChooser, SIGNAL(sigGamutMaskSelected(KoGamutMask*)), SLOT(slotGamutMaskSelected(KoGamutMask*)));
- connect(m_dockerUI->bnSaveMaskNew , SIGNAL(clicked()) , SLOT(slotGamutMaskSaveNew()));
- connect(m_dockerUI->bnMaskSet , SIGNAL(clicked()) , SLOT(slotGamutMaskSet()));
+ connect(m_dockerUI->bnMaskNew , SIGNAL(clicked()) , SLOT(slotGamutMaskCreateNew()));
connect(m_dockerUI->bnMaskDelete , SIGNAL(clicked()) , SLOT(slotGamutMaskDelete()));
+ connect(m_dockerUI->bnMaskDuplicate , SIGNAL(clicked()) , SLOT(slotGamutMaskDuplicate()));
setWidget(m_dockerUI);
}
@@ -109,7 +118,7 @@
{
m_resourceProvider = kisview->resourceProvider();
- m_selectedMask = m_resourceProvider->currentGamutMask();
+ selectMask(m_resourceProvider->currentGamutMask());
connect(this, SIGNAL(sigGamutMaskSet(KoGamutMask*)), m_resourceProvider, SLOT(slotGamutMaskActivated(KoGamutMask*)));
connect(this, SIGNAL(sigGamutMaskChanged(KoGamutMask*)), m_resourceProvider, SLOT(slotGamutMaskActivated(KoGamutMask*)));
@@ -128,93 +137,207 @@
void GamutMaskDock::openMaskEditor()
{
- m_dockerUI->maskPropertiesBox->setVisible(true);
-
- //shouldnt be nullptr here
if (!m_selectedMask) {
return;
}
+ m_dockerUI->maskPropertiesBox->setVisible(true);
+ m_dockerUI->maskPropertiesBox->setEnabled(true);
+ m_dockerUI->editControlsBox->setEnabled(false);
+ m_dockerUI->editControlsBox->setVisible(false);
+
m_dockerUI->maskTitleEdit->setText(m_selectedMask->title());
m_dockerUI->maskDescriptionEdit->setPlainText(m_selectedMask->description());
// open gamut mask template in the application
QString maskTemplateFile = KoResourcePaths::findResource("data", "gamutmasks/GamutMaskTemplate.kra");
- dbgPlugins << "GamutMaskDock::slotGamutMaskEdit: maskTemplateFile"
- << maskTemplateFile;
- // open template document
m_maskDocument = KisPart::instance()->createDocument();
KisPart::instance()->addDocument(m_maskDocument);
m_maskDocument->openUrl(QUrl::fromLocalFile(maskTemplateFile), KisDocument::DontAddToRecent);
- m_maskDocument->resetURL();
+
+ // template document needs a proper autogenerated filename,
+ // to avoid collision with other documents,
+ // otherwise bugs happen when slotDocumentRemoved is called
+ // (e.g. user closes another view, the template stays open, but the edit operation is canceled)
+ m_maskDocument->setInfiniteAutoSaveInterval();
+ QString maskPath = QString("%1%2%3_%4.kra")
+ .arg(QDir::tempPath())
+ .arg(QDir::separator())
+ .arg("GamutMaskTemplate")
+ .arg(std::time(nullptr));
+ m_maskDocument->setUrl(QUrl::fromLocalFile(maskPath));
+ m_maskDocument->setLocalFilePath(maskPath);
KisShapeLayerSP shapeLayer = getShapeLayer();
// pass only copies of shapes to the layer,
// so the originals don't disappear from the mask later
for (KoShape *shape: m_selectedMask->koShapes()) {
- shapeLayer->addShape(shape->cloneShape());
+ KoShape* newShape = shape->cloneShape();
+ newShape->setStroke(KoShapeStrokeModelSP());
+ newShape->setBackground(QSharedPointer(new KoColorBackground(QColor(255,255,255))));
+ shapeLayer->addShape(newShape);
}
m_maskDocument->setPreActivatedNode(shapeLayer);
// set document as active
KisMainWindow* mainWindow = KisPart::instance()->currentMainwindow();
- Q_ASSERT(mainWindow);
+ KIS_ASSERT(mainWindow);
m_view = mainWindow->addViewAndNotifyLoadingCompleted(m_maskDocument);
- Q_ASSERT(m_view);
+ KIS_ASSERT(m_view);
for(KisView *view: KisPart::instance()->views()) {
if (view->document() == m_maskDocument) {
view->activateWindow();
break;
}
}
+
+ connect(m_view->viewManager(), SIGNAL(viewChanged()), this, SLOT(slotViewChanged()));
+ connect(m_maskDocument, SIGNAL(completed()), this, SLOT(slotDocumentSaved()));
}
void GamutMaskDock::cancelMaskEdit()
{
+ if (m_creatingNewMask) {
+ deleteMask();
+ }
+
if (m_selectedMask) {
m_selectedMask->clearPreview();
- m_dockerUI->maskPropertiesBox->setVisible(false);
-
if (m_resourceProvider->currentGamutMask() == m_selectedMask) {
emit sigGamutMaskChanged(m_selectedMask);
}
}
+
+ closeMaskDocument();
}
-void GamutMaskDock::saveSelectedMaskResource()
+void GamutMaskDock::selectMask(KoGamutMask *mask, bool notifyItemChooser)
{
+ if (!mask) {
+ return;
+ }
+
+ m_selectedMask = mask;
+
+ if (notifyItemChooser) {
+ m_selfSelectingMask = true;
+ m_dockerUI->maskChooser->setCurrentResource(m_selectedMask);
+ m_selfSelectingMask = false;
+ }
+
+ emit sigGamutMaskSet(m_selectedMask);
+}
+
+bool GamutMaskDock::saveSelectedMaskResource()
+{
+ if (!m_selectedMask || !m_maskDocument) {
+ return false;
+ }
+
+ bool maskSaved = false;
+
if (m_selectedMask) {
- m_selectedMask->setDescription(m_dockerUI->maskDescriptionEdit->toPlainText());
+ QList shapes = getShapesFromLayer();
- m_selectedMask->setMaskShapes(getShapesFromLayer());
+ if (shapes.count() > 0) {
+ m_selectedMask->setMaskShapes(shapes);
- m_selectedMask->setImage(
- m_maskDocument->image()->convertToQImage(m_maskDocument->image()->bounds()
- , m_maskDocument->image()->profile()
- )
- );
+ m_selectedMask->setImage(
+ m_maskDocument->image()->convertToQImage(m_maskDocument->image()->bounds()
+ , m_maskDocument->image()->profile()
+ )
+ );
- m_selectedMask->clearPreview();
- m_selectedMask->save();
+ m_selectedMask->setDescription(m_dockerUI->maskDescriptionEdit->toPlainText());
+
+ m_selectedMask->clearPreview();
+ m_selectedMask->save();
+ maskSaved = true;
+ } else {
+ getUserFeedback(i18n("Saving of gamut mask '%1' was aborted.
"
+ "The mask template is invalid.
"
+ "Please check that:"
+ "
"
+ "- your template contains a vector layer named 'maskShapesLayer'
"
+ "- there are one or more vector shapes on the 'maskShapesLayer'
"
+ "
"
+ , m_selectedMask->title()),
+ QMessageBox::Ok, QMessageBox::Ok);
+ }
}
+
+ return maskSaved;
}
-void GamutMaskDock::finalizeMaskSave()
+void GamutMaskDock::deleteMask()
{
- closeMaskDocument();
- m_dockerUI->maskPropertiesBox->setVisible(false);
+ KoResourceServer* rServer = KoResourceServerProvider::instance()->gamutMaskServer();
+ rServer->removeResourceAndBlacklist(m_selectedMask);
+ m_selectedMask = nullptr;
}
-KoGamutMask* GamutMaskDock::addDuplicateResource(QString newTitle)
+int GamutMaskDock::getUserFeedback(QString message, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
{
- // construct a copy
- KoGamutMask* newMask = new KoGamutMask(m_selectedMask);
+ int res = QMessageBox::warning(this,
+ i18nc("@title:window", "Krita"),
+ message,
+ buttons, defaultButton);
+
+ return res;
+}
+
+int GamutMaskDock::saveOrCancel(QMessageBox::StandardButton defaultAction)
+{
+ int response = 0;
+
+ if (m_maskDocument->isModified()) {
+ response = getUserFeedback(i18n("Gamut mask '%1' has been modified.
Do you want to save it?
"
+ , m_selectedMask->title()),
+ QMessageBox::Cancel | QMessageBox::Close | QMessageBox::Save, defaultAction);
+
+ } else if (m_templatePrevSaved && defaultAction != QMessageBox::Close) {
+ response = QMessageBox::Save;
+
+ } else if (!m_templatePrevSaved) {
+ response = QMessageBox::Close;
+
+ } else {
+ response = defaultAction;
+ }
+
+ switch (response) {
+ case QMessageBox::Save : {
+ slotGamutMaskSave();
+ break;
+ }
+ case QMessageBox::Close : {
+ cancelMaskEdit();
+ break;
+ }
+ }
+
+ return response;
+}
+
+KoGamutMask *GamutMaskDock::createMaskResource(KoGamutMask* sourceMask, QString newTitle)
+{
+ m_creatingNewMask = true;
+
+ KoGamutMask* newMask = nullptr;
+ if (sourceMask) {
+ newMask = new KoGamutMask(sourceMask);
+ newMask->setImage(sourceMask->image());
+ } else {
+ newMask = new KoGamutMask();
+ QString defaultPreviewPath = KoResourcePaths::findResource("data", "gamutmasks/empty_mask_preview.png");
+ newMask->setImage(QImage(defaultPreviewPath, "PNG"));
+ }
QPair maskFile = resolveMaskTitle(newTitle);
QString maskTitle = maskFile.first;
@@ -226,64 +349,68 @@
newMask->setValid(true);
KoResourceServer* rServer = KoResourceServerProvider::instance()->gamutMaskServer();
+ rServer->removeFromBlacklist(newMask);
rServer->addResource(newMask, false);
-
-
return newMask;
}
QPair GamutMaskDock::resolveMaskTitle(QString suggestedTitle)
{
KoResourceServer* rServer = KoResourceServerProvider::instance()->gamutMaskServer();
QString saveLocation = rServer->saveLocation();
-
QString processedTitle = suggestedTitle.trimmed();
- QString newFilename = saveLocation + processedTitle.replace(QRegularExpression("\\s+"), "_") + ".kgm";
-
- QFileInfo fileInfo(newFilename);
- QStringList resourceBlacklist = rServer->blackListedFiles();
-
- int i = 1;
- int lastIndex = 0;
- while (fileInfo.exists()) {
- if (resourceBlacklist.contains(fileInfo.filePath())) {
- // allow to overwrite blacklisted masks
- break;
- } else {
- fileInfo.setFile(saveLocation + processedTitle + QString("%1").arg(i) + ".kgm");
- lastIndex = i;
- i++;
- }
+ QString resourceName = processedTitle;
+ while (rServer->resourceByName(resourceName)) {
+ resourceName = resourceName + QString(" (Copy)");
}
- QString maskTitle = (lastIndex > 0) ? (processedTitle + QString("%1").arg(lastIndex)) : processedTitle;
+ QString maskTitle = resourceName;
+ QString maskFile = maskTitle + ".kgm";
+ QString path = saveLocation + maskFile.replace(QRegularExpression("\\s+"), "_");
+ QFileInfo fileInfo(path);
return QPair(maskTitle, fileInfo);
}
void GamutMaskDock::closeMaskDocument()
{
- if (m_maskDocument) {
- // HACK: set the document to not modified to bypass confirmation dialog
- // the close is already confirmed
- m_maskDocument->setModified(false);
+ if (!m_externalTemplateClose) {
+ if (m_maskDocument) {
+ // set the document to not modified to bypass confirmation dialog
+ // the close is already confirmed
+ m_maskDocument->setModified(false);
+
+ m_maskDocument->closeUrl();
+ m_view->closeView();
+ m_view->deleteLater();
+
+ // set a flag that we are doing it ourselves, so the docker does not react to
+ // removing signal from KisPart
+ m_selfClosingTemplate = true;
+ KisPart::instance()->removeView(m_view);
+ KisPart::instance()->removeDocument(m_maskDocument);
+ m_selfClosingTemplate = false;
+ }
+ }
- m_maskDocument->closeUrl();
- m_view->closeView();
- m_view->deleteLater();
+ m_dockerUI->maskPropertiesBox->setVisible(false);
+ m_dockerUI->editControlsBox->setVisible(true);
+ m_dockerUI->editControlsBox->setEnabled(true);
- // HACK: set a flag that we are doing it ourselves, so the docker does not react to
- // removing signal from KisPart
- m_selfClosingMaskFile = true;
- KisPart::instance()->removeView(m_view);
- KisPart::instance()->removeDocument(m_maskDocument);
- m_selfClosingMaskFile = false;
+ disconnect(m_view->viewManager(), SIGNAL(viewChanged()), this, SLOT(slotViewChanged()));
+ disconnect(m_maskDocument, SIGNAL(completed()), this, SLOT(slotDocumentSaved()));
- m_maskDocument = nullptr;
- m_view = nullptr;
+ // the template file is meant as temporary, if the user saved it, delete now
+ if (QFile::exists(m_maskDocument->localFilePath())) {
+ QFile::remove(m_maskDocument->localFilePath());
}
+
+ m_maskDocument = nullptr;
+ m_view = nullptr;
+ m_creatingNewMask = false;
+ m_templatePrevSaved = false;
}
QList GamutMaskDock::getShapesFromLayer()
@@ -293,9 +420,15 @@
// create a deep copy of the shapes to save in the mask,
// otherwise they vanish when the template closes
QList newShapes;
- for (KoShape* sh: shapeLayer->shapes()) {
- KoShape* newShape = sh->cloneShape();
- newShapes.append(newShape);
+
+ if (shapeLayer) {
+ for (KoShape* sh: shapeLayer->shapes()) {
+ KoShape* newShape = sh->cloneShape();
+ KoShapeStrokeSP border(new KoShapeStroke(0.5f, Qt::white));
+ newShape->setStroke(border);
+ newShape->setBackground(QSharedPointer(new KoColorBackground(QColor(255,255,255,0))));
+ newShapes.append(newShape);
+ }
}
return newShapes;
@@ -309,29 +442,25 @@
void GamutMaskDock::slotGamutMaskSave()
{
+ if (!m_selectedMask || !m_maskDocument) {
+ return;
+ }
+
QString newTitle = m_dockerUI->maskTitleEdit->text();
- // was this mask previously set to selectors?
- bool setToSelectors = (m_resourceProvider->currentGamutMask() == m_selectedMask);
if (m_selectedMask->title() != newTitle) {
// title has changed, rename
- if (!m_selectedMask) {
- return;
- }
-
- // construct a copy
- KoGamutMask* newMask = addDuplicateResource(newTitle);
+ KoGamutMask* newMask = createMaskResource(m_selectedMask, newTitle);
// delete old mask and select new
- slotGamutMaskDelete();
- m_selectedMask = newMask;
+ deleteMask();
+ selectMask(newMask);
}
- saveSelectedMaskResource();
- finalizeMaskSave();
-
- if (setToSelectors) {
+ bool maskSaved = saveSelectedMaskResource();
+ if (maskSaved) {
emit sigGamutMaskSet(m_selectedMask);
+ closeMaskDocument();
}
}
@@ -341,32 +470,7 @@
return;
}
- bool cancelApproved = false;
- if (m_maskDocument->isModified()) {
- int res = QMessageBox::warning(this,
- i18nc("@title:window", "Krita"),
- i18n("Gamut mask '%1' has been modified.
Discard changes?
"
- , m_selectedMask->title()),
- QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
-
- switch (res) {
- case QMessageBox::Yes : {
- cancelApproved = true;
- break;
- }
- case QMessageBox::No : {
- cancelApproved = false;
- break;
- }
- }
- } else {
- cancelApproved = true;
- }
-
- if (cancelApproved) {
- cancelMaskEdit();
- closeMaskDocument();
- }
+ saveOrCancel(QMessageBox::Close);
}
void GamutMaskDock::slotGamutMaskPreview()
@@ -381,12 +485,15 @@
void GamutMaskDock::slotGamutMaskSelected(KoGamutMask *mask)
{
- m_selectedMask = mask;
+ if (!m_selfSelectingMask) {
+ if (m_maskDocument) {
+ int res = saveOrCancel();
+ if (res == QMessageBox::Cancel) {
+ return;
+ }
+ }
- if (m_selectedMask) {
- m_dockerUI->labelMaskName->setText(m_selectedMask->title());
- } else {
- m_dockerUI->labelMaskName->setText(i18n("Select a mask"));
+ selectMask(mask, false);
}
}
@@ -413,77 +520,84 @@
if (resource == m_resourceProvider->currentGamutMask()) {
emit sigGamutMaskUnset();
m_selectedMask = nullptr;
- m_dockerUI->labelMaskName->setText(i18n("Select a mask"));
}
}
void GamutMaskDock::resourceChanged(KoGamutMask *resource)
{
// if currently set mask has been changed, notify selectors
- // TODO: is m_resourceProvider->currentGamutMask() == m_selectedMask?
if (resource == m_resourceProvider->currentGamutMask()) {
- m_selectedMask = resource;
- emit sigGamutMaskChanged(resource);
+ selectMask(resource);
}
}
-void GamutMaskDock::slotGamutMaskSaveNew()
+void GamutMaskDock::slotGamutMaskCreateNew()
+{
+ KoGamutMask* newMask = createMaskResource(nullptr, "new mask");
+ selectMask(newMask);
+ openMaskEditor();
+}
+
+void GamutMaskDock::slotGamutMaskDuplicate()
{
if (!m_selectedMask) {
return;
}
- KoGamutMask* newMask = addDuplicateResource(m_dockerUI->maskTitleEdit->text());
- m_selectedMask = newMask;
-
- saveSelectedMaskResource();
- finalizeMaskSave();
+ KoGamutMask* newMask = createMaskResource(m_selectedMask, m_selectedMask->title());
+ selectMask(newMask);
+ openMaskEditor();
}
void GamutMaskDock::slotGamutMaskDelete()
{
if (!m_selectedMask) {
return;
}
- int res = QMessageBox::warning(this,
- i18nc("@title:window", "Krita"),
- i18n("Are you sure you want to delete mask '%1'?"
- , m_selectedMask->title()),
- QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+ int res = getUserFeedback(i18n("Are you sure you want to delete mask '%1'?"
+ , m_selectedMask->title()));
- // delete only if user confirms
if (res == QMessageBox::Yes) {
- KoResourceServer* rServer = KoResourceServerProvider::instance()->gamutMaskServer();
- // TODO: other resources do it this way, but the files stay on disk
- rServer->removeResourceAndBlacklist(m_selectedMask);
-
- m_selectedMask = nullptr;
- m_dockerUI->labelMaskName->setText(i18n("Select a mask"));
+ deleteMask();
}
}
-void GamutMaskDock::slotGamutMaskSet()
-{
- if (!m_selectedMask) {
- return;
- }
-
- emit sigGamutMaskSet(m_selectedMask);
-}
-
void GamutMaskDock::slotDocumentRemoved(QString filename)
{
if (!m_maskDocument) {
return;
}
- // HACK: we do not want to run this if it is we who close the file
- if (!m_selfClosingMaskFile) {
+ m_externalTemplateClose = true;
+
+ // we do not want to run this if it is we who close the file
+ if (!m_selfClosingTemplate) {
// KisPart called, that a document will be removed
// if it's ours, cancel the mask edit operation
if (m_maskDocument->url().toLocalFile() == filename) {
- cancelMaskEdit();
+ m_maskDocument->waitForSavingToComplete();
+ saveOrCancel();
}
}
+
+ m_externalTemplateClose = false;
+}
+
+void GamutMaskDock::slotViewChanged()
+{
+ if (!m_maskDocument || !m_view) {
+ return;
+ }
+
+ if (m_view->viewManager()->document() == m_maskDocument) {
+ m_dockerUI->maskPropertiesBox->setEnabled(true);
+ } else {
+ m_dockerUI->maskPropertiesBox->setEnabled(false);
+ }
+}
+
+void GamutMaskDock::slotDocumentSaved()
+{
+ m_templatePrevSaved = true;
}
diff --git a/plugins/extensions/resourcemanager/dlg_bundle_manager.cpp b/plugins/extensions/resourcemanager/dlg_bundle_manager.cpp
--- a/plugins/extensions/resourcemanager/dlg_bundle_manager.cpp
+++ b/plugins/extensions/resourcemanager/dlg_bundle_manager.cpp
@@ -295,6 +295,10 @@
else if (resType == "paintoppresets") {
toplevel->setText(0, i18n("Brush Presets"));
}
+ else if (resType == "gamutmasks") {
+ toplevel->setText(0, i18n("Gamut Masks"));
+ }
+
m_ui->listBundleContents->addTopLevelItem(toplevel);
diff --git a/plugins/extensions/resourcemanager/dlg_create_bundle.h b/plugins/extensions/resourcemanager/dlg_create_bundle.h
--- a/plugins/extensions/resourcemanager/dlg_create_bundle.h
+++ b/plugins/extensions/resourcemanager/dlg_create_bundle.h
@@ -51,6 +51,7 @@
QStringList selectedPatterns() const { return m_selectedPatterns; }
QStringList selectedPalettes() const { return m_selectedPalettes; }
QStringList selectedWorkspaces() const { return m_selectedWorkspaces; }
+ QStringList selectedGamutMasks() const { return m_selectedGamutMasks; }
private Q_SLOTS:
@@ -72,6 +73,7 @@
QStringList m_selectedPatterns;
QStringList m_selectedPalettes;
QStringList m_selectedWorkspaces;
+ QStringList m_selectedGamutMasks;
QString m_previewImage;
diff --git a/plugins/extensions/resourcemanager/dlg_create_bundle.cpp b/plugins/extensions/resourcemanager/dlg_create_bundle.cpp
--- a/plugins/extensions/resourcemanager/dlg_create_bundle.cpp
+++ b/plugins/extensions/resourcemanager/dlg_create_bundle.cpp
@@ -126,6 +126,13 @@
}
}
}
+ else if (resType == "gamutmasks") {
+ Q_FOREACH (const KoResource *res, bundle->resources(resType)) {
+ if (res) {
+ m_selectedGamutMasks << res->shortFilename();
+ }
+ }
+ }
}
}
else {
@@ -150,6 +157,7 @@
m_ui->cmbResourceTypes->addItem(i18n("Brushes"), QString("brushes"));
m_ui->cmbResourceTypes->addItem(i18n("Brush Presets"), QString("presets"));
m_ui->cmbResourceTypes->addItem(i18n("Gradients"), QString("gradients"));
+ m_ui->cmbResourceTypes->addItem(i18n("Gamut Masks"), QString("gamutmasks"));
m_ui->cmbResourceTypes->addItem(i18n("Patterns"), QString("patterns"));
m_ui->cmbResourceTypes->addItem(i18n("Palettes"), QString("palettes"));
m_ui->cmbResourceTypes->addItem(i18n("Workspaces"), QString("workspaces"));
@@ -277,6 +285,9 @@
else if (resourceType == "workspaces") {
m_selectedWorkspaces.append(item->data(Qt::UserRole).toString());
}
+ else if (resourceType == "gamutmasks") {
+ m_selectedGamutMasks.append(item->data(Qt::UserRole).toString());
+ }
}
m_ui->tableAvailable->setCurrentRow(row);
@@ -308,6 +319,9 @@
else if (resourceType == "workspaces") {
m_selectedWorkspaces.removeAll(item->data(Qt::UserRole).toString());
}
+ else if (resourceType == "gamutmasks") {
+ m_selectedGamutMasks.removeAll(item->data(Qt::UserRole).toString());
+ }
}
m_ui->tableSelected->setCurrentRow(row);
@@ -420,6 +434,21 @@
}
}
}
+ else if (resourceType == "gamutmasks") {
+ KoResourceServer* server = KoResourceServerProvider::instance()->gamutMaskServer();
+ Q_FOREACH (KoResource *res, server->resources()) {
+ QListWidgetItem *item = new QListWidgetItem(imageToIcon(res->image()), res->name());
+ item->setData(Qt::UserRole, res->shortFilename());
+
+ if (m_selectedGamutMasks.contains(res->shortFilename())) {
+ m_ui->tableSelected->addItem(item);
+ }
+ else {
+ m_ui->tableAvailable->addItem(item);
+ }
+ }
+ }
+
}
void DlgCreateBundle::getPreviewImage()
diff --git a/plugins/extensions/resourcemanager/resourcemanager.cpp b/plugins/extensions/resourcemanager/resourcemanager.cpp
--- a/plugins/extensions/resourcemanager/resourcemanager.cpp
+++ b/plugins/extensions/resourcemanager/resourcemanager.cpp
@@ -63,15 +63,16 @@
patternServer = KoResourceServerProvider::instance()->patternServer();
paletteServer = KoResourceServerProvider::instance()->paletteServer();
workspaceServer = KisResourceServerProvider::instance()->workspaceServer();
+ gamutMaskServer = KoResourceServerProvider::instance()->gamutMaskServer();
}
KisBrushResourceServer* brushServer;
KisPaintOpPresetResourceServer * paintopServer;
KoResourceServer* gradientServer;
KoResourceServer *patternServer;
KoResourceServer* paletteServer;
KoResourceServer* workspaceServer;
-
+ KoResourceServer* gamutMaskServer;
};
K_PLUGIN_FACTORY_WITH_JSON(ResourceManagerFactory, "kritaresourcemanager.json", registerPlugin();)
@@ -196,6 +197,12 @@
newBundle->addResource("kis_workspaces", res->filename(), d->workspaceServer->assignedTagsList(res), res->md5());
}
+ res = dlgCreateBundle.selectedGamutMasks();
+ Q_FOREACH (const QString &r, res) {
+ KoResource *res = d->gamutMaskServer->resourceByFilename(r);
+ newBundle->addResource("ko_gamutmasks", res->filename(), d->gamutMaskServer->assignedTagsList(res), res->md5());
+ }
+
newBundle->addMeta("fileName", bundlePath);
newBundle->addMeta("created", QDate::currentDate().toString("dd/MM/yyyy"));