diff --git a/krita/data/gamutmasks/Atmosphere_With_Accent.kgm b/krita/data/gamutmasks/Atmosphere_With_Accent.kgm index 8bea9a5673..aa14412dbb 100644 Binary files a/krita/data/gamutmasks/Atmosphere_With_Accent.kgm and b/krita/data/gamutmasks/Atmosphere_With_Accent.kgm differ diff --git a/libs/flake/KisGamutMaskViewConverter.cpp b/libs/flake/KisGamutMaskViewConverter.cpp index e5c22e8b74..2135f61c2e 100644 --- a/libs/flake/KisGamutMaskViewConverter.cpp +++ b/libs/flake/KisGamutMaskViewConverter.cpp @@ -1,169 +1,174 @@ /* * 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 #include #include #include //#define DEBUG_GAMUT_MASK_CONVERTER KisGamutMaskViewConverter::KisGamutMaskViewConverter() : m_viewSize(1.0) , m_maskSize(QSizeF(1,1)) , m_maskResolution(1) { computeAndSetZoom(); } KisGamutMaskViewConverter::~KisGamutMaskViewConverter() { } +QSize KisGamutMaskViewConverter::viewSize() const +{ + return QSize(m_viewSize, m_viewSize); +} + QPointF KisGamutMaskViewConverter::documentToView(const QPointF &documentPoint) const { return QPointF(documentToViewX(documentPoint.x()), documentToViewY(documentPoint.y())); } QPointF KisGamutMaskViewConverter::viewToDocument(const QPointF &viewPoint) const { return QPointF(viewToDocumentX(viewPoint.x()), viewToDocumentY(viewPoint.y())); } QRectF KisGamutMaskViewConverter::documentToView(const QRectF &documentRect) const { return QRectF(documentToView(documentRect.topLeft()), documentToView(documentRect.size())); } QRectF KisGamutMaskViewConverter::viewToDocument(const QRectF &viewRect) const { return QRectF(viewToDocument(viewRect.topLeft()), viewToDocument(viewRect.size())); } QSizeF KisGamutMaskViewConverter::documentToView(const QSizeF &documentSize) const { return QSizeF(documentToViewX(documentSize.width()), documentToViewY(documentSize.height())); } QSizeF KisGamutMaskViewConverter::viewToDocument(const QSizeF &viewSize) const { return QSizeF(viewToDocumentX(viewSize.width()), viewToDocumentY(viewSize.height())); } qreal KisGamutMaskViewConverter::documentToViewX(qreal documentX) const { qreal translated = documentX * m_zoomLevel; #ifdef DEBUG_GAMUT_MASK_CONVERTER debugFlake << "KisGamutMaskViewConverter::DocumentToViewX: " << "documentX: " << documentX << " -> translated: " << translated; #endif return translated; } qreal KisGamutMaskViewConverter::documentToViewY(qreal documentY) const { qreal translated = documentY * m_zoomLevel; #ifdef DEBUG_GAMUT_MASK_CONVERTER debugFlake << "KisGamutMaskViewConverter::DocumentToViewY: " << "documentY: " << documentY << " -> translated: " << translated; #endif return translated; } qreal KisGamutMaskViewConverter::viewToDocumentX(qreal viewX) const { qreal translated = viewX / m_zoomLevel; #ifdef DEBUG_GAMUT_MASK_CONVERTER debugFlake << "KisGamutMaskViewConverter::viewToDocumentX: " << "viewX: " << viewX << " -> translated: " << translated; #endif return translated; } qreal KisGamutMaskViewConverter::viewToDocumentY(qreal viewY) const { qreal translated = viewY / m_zoomLevel; #ifdef DEBUG_GAMUT_MASK_CONVERTER debugFlake << "KisGamutMaskViewConverter::viewToDocumentY: " << "viewY: " << viewY << " -> translated: " << translated; #endif return translated; } void KisGamutMaskViewConverter::setZoom(qreal zoom) { if (qFuzzyCompare(zoom, qreal(0.0)) || qFuzzyCompare(zoom, qreal(1.0))) { zoom = 1; } #ifdef DEBUG_GAMUT_MASK_CONVERTER debugFlake << "KisGamutMaskViewConverter::setZoom: setting to " << zoom; #endif m_zoomLevel = zoom; } void KisGamutMaskViewConverter::zoom(qreal *zoomX, qreal *zoomY) const { *zoomX = m_zoomLevel; *zoomY = m_zoomLevel; } void KisGamutMaskViewConverter::setViewSize(QSize viewSize) { m_viewSize = viewSize.width(); computeAndSetZoom(); } void KisGamutMaskViewConverter::setMaskSize(QSizeF maskSize) { m_maskSize = maskSize; m_maskResolution = maskSize.width(); computeAndSetZoom(); } void KisGamutMaskViewConverter::computeAndSetZoom() { qreal zoom = m_viewSize / m_maskResolution; #ifdef DEBUG_GAMUT_MASK_CONVERTER debugFlake << "KisGamutMaskViewConverter::computeAndSetZoom: " << "m_viewSize: " << m_viewSize << " m_maskSize: " << m_maskResolution; #endif setZoom(zoom); } diff --git a/libs/flake/KisGamutMaskViewConverter.h b/libs/flake/KisGamutMaskViewConverter.h index 447a785cc5..73073efae8 100644 --- a/libs/flake/KisGamutMaskViewConverter.h +++ b/libs/flake/KisGamutMaskViewConverter.h @@ -1,68 +1,70 @@ /* * 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 #include "kritaflake_export.h" #include #include #include class QPointF; class QRectF; /** * @brief view convertor for gamut mask calculations and painting */ class KRITAFLAKE_EXPORT KisGamutMaskViewConverter : public KoViewConverter { public: KisGamutMaskViewConverter(); ~KisGamutMaskViewConverter(); + QSize viewSize() const; void setViewSize(QSize viewSize); + void setMaskSize(QSizeF maskSize); QPointF documentToView(const QPointF &documentPoint) const override; QPointF viewToDocument(const QPointF &viewPoint) const override; QRectF documentToView(const QRectF &documentRect) const override; QRectF viewToDocument(const QRectF &viewRect) const override; QSizeF documentToView(const QSizeF& documentSize) const override; QSizeF viewToDocument(const QSizeF& viewSize) const override; qreal documentToViewX(qreal documentX) const override; qreal documentToViewY(qreal documentY) const override; qreal viewToDocumentX(qreal viewX) const override; qreal viewToDocumentY(qreal viewY) const override; void setZoom(qreal zoom) override; void zoom(qreal *zoomX, qreal *zoomY) const override; private: void computeAndSetZoom(); qreal m_zoomLevel; // 1.0 is 100% int m_viewSize; QSizeF m_maskSize; qreal m_maskResolution; }; #endif // KISGAMUTMASKVIEWCONVERTER_H diff --git a/libs/flake/resources/KoGamutMask.cpp b/libs/flake/resources/KoGamutMask.cpp index 80fd9de3f6..dfd09193c4 100644 --- a/libs/flake/resources/KoGamutMask.cpp +++ b/libs/flake/resources/KoGamutMask.cpp @@ -1,391 +1,427 @@ /* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include KoGamutMaskShape::KoGamutMaskShape(KoShape* shape) : m_maskShape(shape) , m_shapePaintingContext(KoShapePaintingContext()) { } KoGamutMaskShape::KoGamutMaskShape() {}; KoGamutMaskShape::~KoGamutMaskShape() {}; KoShape* KoGamutMaskShape::koShape() { return m_maskShape; } -bool KoGamutMaskShape::coordIsClear(const QPointF& coord, const KoViewConverter& viewConverter) const +bool KoGamutMaskShape::coordIsClear(const QPointF& coord, const KoViewConverter& viewConverter, int maskRotation) const { - QPointF translatedPoint = viewConverter.viewToDocument(coord); + // apply mask rotation to coord + const KisGamutMaskViewConverter& converter = dynamic_cast(viewConverter); + QPointF centerPoint(converter.viewSize().width()*0.5, converter.viewSize().height()*0.5); + + QTransform rotationTransform; + rotationTransform.translate(centerPoint.x(), centerPoint.y()); + rotationTransform.rotate(-maskRotation); + rotationTransform.translate(-centerPoint.x(), -centerPoint.y()); + + QPointF rotatedCoord = rotationTransform.map(coord); + QPointF translatedPoint = viewConverter.viewToDocument(rotatedCoord); bool isClear = m_maskShape->hitTest(translatedPoint); return isClear; } -void KoGamutMaskShape::paint(QPainter &painter, const KoViewConverter& viewConverter) +void KoGamutMaskShape::paint(QPainter &painter, const KoViewConverter& viewConverter, int maskRotation) { painter.save(); + + // apply mask rotation before drawing + QPointF centerPoint(painter.viewport().width()*0.5, painter.viewport().height()*0.5); + painter.translate(centerPoint); + painter.rotate(maskRotation); + painter.translate(-centerPoint); painter.setTransform(m_maskShape->absoluteTransformation(&viewConverter) * painter.transform()); m_maskShape->paint(painter, viewConverter, m_shapePaintingContext); painter.restore(); } -void KoGamutMaskShape::paintStroke(QPainter &painter, const KoViewConverter &viewConverter) +void KoGamutMaskShape::paintStroke(QPainter &painter, const KoViewConverter &viewConverter, int maskRotation) { painter.save(); + + // apply mask rotation before drawing + QPointF centerPoint(painter.viewport().width()*0.5, painter.viewport().height()*0.5); + painter.translate(centerPoint); + painter.rotate(maskRotation); + painter.translate(-centerPoint); + 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; + int rotation; }; KoGamutMask::KoGamutMask(const QString& filename) : KoResource(filename) , d(new Private()) { d->maskSize = QSizeF(144.0,144.0); + setRotation(0); } KoGamutMask::KoGamutMask() : KoResource(QString()) , d(new Private()) { d->maskSize = QSizeF(144.0,144.0); + setRotation(0); } KoGamutMask::KoGamutMask(KoGamutMask* rhs) : QObject(0) , KoResource(QString()) , d(new Private()) { setFilename(rhs->filename()); setTitle(rhs->title()); setDescription(rhs->description()); d->maskSize = rhs->d->maskSize; QList newShapes; for(KoShape* sh: rhs->koShapes()) { newShapes.append(sh->cloneShape()); } setMaskShapes(newShapes); setValid(true); } bool KoGamutMask::coordIsClear(const QPointF& coord, KoViewConverter &viewConverter, bool preview) { QVector* shapeVector; if (preview && !d->previewShapes.isEmpty()) { shapeVector = &d->previewShapes; } else { shapeVector = &d->maskShapes; } for(KoGamutMaskShape* shape: *shapeVector) { - if (shape->coordIsClear(coord, viewConverter) == true) { + if (shape->coordIsClear(coord, viewConverter, rotation()) == true) { return true; } } return false; } void KoGamutMask::paint(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->paint(painter, viewConverter); + shape->paint(painter, viewConverter, rotation()); } } 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); + shape->paintStroke(painter, viewConverter, rotation()); } } bool KoGamutMask::load() { QFile file(filename()); if (file.size() == 0) return false; if (!file.open(QIODevice::ReadOnly)) { warnFlake << "Can't open file " << filename(); return false; } bool res = loadFromDevice(&file); file.close(); return res; } bool KoGamutMask::loadFromDevice(QIODevice *dev) { if (!dev->isOpen()) dev->open(QIODevice::ReadOnly); d->data = dev->readAll(); // 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"; return false; } if (d->data.isNull()) { QFile file(filename()); if (file.size() == 0) { warnFlake << "Cannot load gamut mask" << name() << "there is no data available"; return false; } file.open(QIODevice::ReadOnly); d->data = file.readAll(); file.close(); } QBuffer buf(&d->data); buf.open(QBuffer::ReadOnly); KoStore* store(KoStore::createStore(&buf, KoStore::Read, "application/x-krita-gamutmask", KoStore::Zip)); if (!store || store->bad()) return false; bool storeOpened = store->open("gamutmask.svg"); if (!storeOpened) { return false; } QByteArray data; data.resize(store->size()); QByteArray ba = store->read(store->size()); store->close(); KoXmlDocument xmlDocument; QString errorMsg; int errorLine = 0; int errorColumn = 0; bool ok = xmlDocument.setContent(ba, false, &errorMsg, &errorLine, &errorColumn); if (!ok) { errorFlake << "Parsing error in " << filename() << "! Aborting!" << endl << " In line: " << errorLine << ", column: " << errorColumn << endl << " Error message: " << errorMsg << endl; errorFlake << "Parsing error in the main document at line" << errorLine << ", column" << errorColumn << endl << "Error message: " << errorMsg; return false; } KoDocumentResourceManager manager; SvgParser parser(&manager); parser.setResolution(QRectF(0,0,100,100), 72); // initialize with default values QSizeF fragmentSize; QList shapes = parser.parseSvg(xmlDocument.documentElement(), &fragmentSize); d->maskSize = fragmentSize; d->title = parser.documentTitle(); setName(d->title); d->description = parser.documentDescription(); setMaskShapes(shapes); if (store->open("preview.png")) { KoStoreDevice previewDev(store); previewDev.open(QIODevice::ReadOnly); QImage preview = QImage(); preview.load(&previewDev, "PNG"); setImage(preview); (void)store->close(); } buf.close(); setValid(true); return true; } void KoGamutMask::setMaskShapes(QList shapes) { setMaskShapesToVector(shapes, d->maskShapes); } bool KoGamutMask::save() { QFile file(filename()); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { return false; } saveToDevice(&file); file.close(); return true; } QList KoGamutMask::koShapes() const { QList shapes; for(KoGamutMaskShape* maskShape: d->maskShapes) { shapes.append(maskShape->koShape()); } return shapes; } bool KoGamutMask::saveToDevice(QIODevice *dev) const { KoStore* store(KoStore::createStore(dev, KoStore::Write, "application/x-krita-gamutmask", KoStore::Zip)); if (!store || store->bad()) return false; QList shapes = koShapes(); std::sort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex); if (!store->open("gamutmask.svg")) { return false; } KoStoreDevice storeDev(store); storeDev.open(QIODevice::WriteOnly); SvgWriter writer(shapes); writer.setDocumentTitle(d->title); writer.setDocumentDescription(d->description); writer.save(storeDev, d->maskSize); if (!store->close()) { return false; } if (!store->open("preview.png")) { return false; } KoStoreDevice previewDev(store); previewDev.open(QIODevice::WriteOnly); image().save(&previewDev, "PNG"); if (!store->close()) { return false; } return store->finalize(); } QString KoGamutMask::title() { return d->title; } void KoGamutMask::setTitle(QString title) { d->title = title; setName(title); } QString KoGamutMask::description() { return d->description; } void KoGamutMask::setDescription(QString description) { d->description = description; } +int KoGamutMask::rotation() +{ + return d->rotation; +} + +void KoGamutMask::setRotation(int rotation) +{ + d->rotation = rotation; +} + QSizeF KoGamutMask::maskSize() { return d->maskSize; } void KoGamutMask::setPreviewMaskShapes(QList shapes) { setMaskShapesToVector(shapes, d->previewShapes); } void KoGamutMask::setMaskShapesToVector(QList shapes, QVector &targetVector) { targetVector.clear(); for(KoShape* sh: shapes) { KoGamutMaskShape* maskShape = new KoGamutMaskShape(sh); targetVector.append(maskShape); } } // clean up when ending mask preview void KoGamutMask::clearPreview() { d->previewShapes.clear(); } diff --git a/libs/flake/resources/KoGamutMask.h b/libs/flake/resources/KoGamutMask.h index e55af16541..87ae77d708 100644 --- a/libs/flake/resources/KoGamutMask.h +++ b/libs/flake/resources/KoGamutMask.h @@ -1,97 +1,100 @@ /* * 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 #include #include #include #include #include #include #include #include #include class KoViewConverter; class KoGamutMaskShape { public: KoGamutMaskShape(KoShape* shape); KoGamutMaskShape(); ~KoGamutMaskShape(); - bool coordIsClear(const QPointF& coord, const KoViewConverter& viewConverter) const; + bool coordIsClear(const QPointF& coord, const KoViewConverter& viewConverter, int maskRotation) const; QPainterPath outline(); - void paint(QPainter &painter, const KoViewConverter& viewConverter); - void paintStroke(QPainter &painter, const KoViewConverter& viewConverter); + void paint(QPainter &painter, const KoViewConverter& viewConverter, int maskRotation); + void paintStroke(QPainter &painter, const KoViewConverter& viewConverter, int maskRotation); KoShape* koShape(); private: KoShape* m_maskShape; KoShapePaintingContext m_shapePaintingContext; }; /** * @brief The resource type for gamut masks used by the artistic color selector */ class KRITAFLAKE_EXPORT KoGamutMask : public QObject, public KoResource { Q_OBJECT public: KoGamutMask(const QString &filename); KoGamutMask(); KoGamutMask(KoGamutMask *rhs); bool coordIsClear(const QPointF& coord, KoViewConverter& viewConverter, bool preview); bool load() override __attribute__((optimize(0))); bool loadFromDevice(QIODevice *dev) override; bool save() override; 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); QString description(); void setDescription(QString description); + int rotation(); + void setRotation(int rotation); + QSizeF maskSize(); void setMaskShapes(QList shapes); void setPreviewMaskShapes(QList shapes); QList koShapes() const; void clearPreview(); private: void setMaskShapesToVector(QList shapes, QVector& targetVector); struct Private; Private* const d; }; #endif // KOGAMUTMASK_H diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt index e5359e84fe..db8bbb2306 100644 --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -1,584 +1,586 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/qtlockedfile ${EXIV2_INCLUDE_DIR} ) include_directories(SYSTEM ${EIGEN3_INCLUDE_DIR} ${OCIO_INCLUDE_DIR} ) add_subdirectory( tests ) if (APPLE) find_library(FOUNDATION_LIBRARY Foundation) find_library(APPKIT_LIBRARY AppKit) endif () set(kritaui_LIB_SRCS canvas/kis_canvas_widget_base.cpp canvas/kis_canvas2.cpp canvas/kis_canvas_updates_compressor.cpp canvas/kis_canvas_controller.cpp canvas/kis_paintop_transformation_connector.cpp canvas/kis_display_color_converter.cpp canvas/kis_display_filter.cpp canvas/kis_exposure_gamma_correction_interface.cpp canvas/kis_tool_proxy.cpp canvas/kis_canvas_decoration.cc canvas/kis_coordinates_converter.cpp canvas/kis_grid_manager.cpp canvas/kis_grid_decoration.cpp canvas/kis_grid_config.cpp canvas/kis_prescaled_projection.cpp canvas/kis_qpainter_canvas.cpp canvas/kis_projection_backend.cpp canvas/kis_update_info.cpp canvas/kis_image_patch.cpp canvas/kis_image_pyramid.cpp canvas/kis_infinity_manager.cpp canvas/kis_change_guides_command.cpp canvas/kis_guides_decoration.cpp canvas/kis_guides_manager.cpp canvas/kis_guides_config.cpp canvas/kis_snap_config.cpp canvas/kis_snap_line_strategy.cpp canvas/KisSnapPointStrategy.cpp dialogs/kis_about_application.cpp dialogs/kis_dlg_adj_layer_props.cc dialogs/kis_dlg_adjustment_layer.cc dialogs/kis_dlg_filter.cpp dialogs/kis_dlg_generator_layer.cpp dialogs/kis_dlg_file_layer.cpp dialogs/kis_dlg_filter.cpp dialogs/kis_dlg_stroke_selection_properties.cpp dialogs/kis_dlg_image_properties.cc dialogs/kis_dlg_layer_properties.cc dialogs/kis_dlg_preferences.cc dialogs/slider_and_spin_box_sync.cpp dialogs/kis_dlg_blacklist_cleanup.cpp dialogs/kis_dlg_layer_style.cpp dialogs/kis_dlg_png_import.cpp dialogs/kis_dlg_import_image_sequence.cpp dialogs/kis_delayed_save_dialog.cpp dialogs/KisSessionManagerDialog.cpp dialogs/KisNewWindowLayoutDialog.cpp flake/kis_node_dummies_graph.cpp flake/kis_dummies_facade_base.cpp flake/kis_dummies_facade.cpp flake/kis_node_shapes_graph.cpp flake/kis_node_shape.cpp flake/kis_shape_controller.cpp flake/kis_shape_layer.cc flake/kis_shape_layer_canvas.cpp flake/kis_shape_selection.cpp flake/kis_shape_selection_canvas.cpp flake/kis_shape_selection_model.cpp flake/kis_take_all_shapes_command.cpp brushhud/kis_uniform_paintop_property_widget.cpp brushhud/kis_brush_hud.cpp brushhud/kis_round_hud_button.cpp brushhud/kis_dlg_brush_hud_config.cpp brushhud/kis_brush_hud_properties_list.cpp brushhud/kis_brush_hud_properties_config.cpp kis_aspect_ratio_locker.cpp kis_autogradient.cc kis_bookmarked_configurations_editor.cc kis_bookmarked_configurations_model.cc kis_bookmarked_filter_configurations_model.cc KisPaintopPropertiesBase.cpp kis_canvas_resource_provider.cpp kis_derived_resources.cpp kis_categories_mapper.cpp kis_categorized_list_model.cpp kis_categorized_item_delegate.cpp kis_clipboard.cc kis_config.cc kis_control_frame.cpp kis_composite_ops_model.cc kis_paint_ops_model.cpp kis_cursor.cc kis_cursor_cache.cpp kis_custom_pattern.cc kis_file_layer.cpp kis_change_file_layer_command.h kis_safe_document_loader.cpp kis_splash_screen.cpp kis_filter_manager.cc kis_filters_model.cc kis_histogram_view.cc KisImageBarrierLockerWithFeedback.cpp kis_image_manager.cc kis_image_view_converter.cpp kis_import_catcher.cc kis_layer_manager.cc kis_mask_manager.cc kis_mimedata.cpp kis_node_commands_adapter.cpp kis_node_manager.cpp kis_node_juggler_compressed.cpp kis_node_selection_adapter.cpp kis_node_insertion_adapter.cpp KisNodeDisplayModeAdapter.cpp kis_node_model.cpp kis_node_filter_proxy_model.cpp kis_model_index_converter_base.cpp kis_model_index_converter.cpp kis_model_index_converter_show_all.cpp kis_painting_assistant.cc kis_painting_assistants_decoration.cpp KisDecorationsManager.cpp kis_paintop_box.cc kis_paintop_option.cpp kis_paintop_options_model.cpp kis_paintop_settings_widget.cpp kis_popup_palette.cpp kis_png_converter.cpp kis_preference_set_registry.cpp KisResourceServerProvider.cpp KisResourceBundleServerProvider.cpp KisSelectedShapesProxy.cpp kis_selection_decoration.cc kis_selection_manager.cc KisSelectionActionsAdapter.cpp kis_statusbar.cc kis_zoom_manager.cc kis_favorite_resource_manager.cpp kis_workspace_resource.cpp kis_action.cpp kis_action_manager.cpp KisActionPlugin.cpp kis_canvas_controls_manager.cpp kis_tooltip_manager.cpp kis_multinode_property.cpp kis_stopgradient_editor.cpp KisWelcomePageWidget.cpp kisexiv2/kis_exif_io.cpp kisexiv2/kis_exiv2.cpp kisexiv2/kis_iptc_io.cpp kisexiv2/kis_xmp_io.cpp opengl/kis_opengl.cpp opengl/kis_opengl_canvas2.cpp opengl/kis_opengl_canvas_debugger.cpp opengl/kis_opengl_image_textures.cpp opengl/kis_texture_tile.cpp opengl/kis_opengl_shader_loader.cpp opengl/kis_texture_tile_info_pool.cpp opengl/KisOpenGLUpdateInfoBuilder.cpp kis_fps_decoration.cpp tool/KisToolChangesTracker.cpp tool/KisToolChangesTrackerData.cpp tool/kis_selection_tool_helper.cpp tool/kis_selection_tool_config_widget_helper.cpp tool/kis_rectangle_constraint_widget.cpp tool/kis_shape_tool_helper.cpp tool/kis_tool.cc tool/kis_delegated_tool_policies.cpp tool/kis_tool_freehand.cc tool/kis_speed_smoother.cpp tool/kis_painting_information_builder.cpp tool/kis_stabilized_events_sampler.cpp tool/kis_tool_freehand_helper.cpp tool/kis_tool_multihand_helper.cpp tool/kis_figure_painting_tool_helper.cpp tool/kis_tool_paint.cc tool/kis_tool_shape.cc tool/kis_tool_ellipse_base.cpp tool/kis_tool_rectangle_base.cpp tool/kis_tool_polyline_base.cpp tool/kis_tool_utils.cpp tool/kis_resources_snapshot.cpp tool/kis_smoothing_options.cpp tool/KisStabilizerDelayedPaintHelper.cpp tool/KisStrokeSpeedMonitor.cpp tool/strokes/freehand_stroke.cpp tool/strokes/KisStrokeEfficiencyMeasurer.cpp tool/strokes/kis_painter_based_stroke_strategy.cpp tool/strokes/kis_filter_stroke_strategy.cpp tool/strokes/kis_color_picker_stroke_strategy.cpp tool/strokes/KisFreehandStrokeInfo.cpp tool/strokes/KisMaskedFreehandStrokePainter.cpp tool/strokes/KisMaskingBrushRenderer.cpp tool/strokes/KisMaskingBrushCompositeOpFactory.cpp tool/strokes/move_stroke_strategy.cpp widgets/kis_cmb_composite.cc widgets/kis_cmb_contour.cpp widgets/kis_cmb_gradient.cpp widgets/kis_paintop_list_widget.cpp widgets/kis_cmb_idlist.cc widgets/kis_color_space_selector.cc widgets/kis_advanced_color_space_selector.cc widgets/kis_cie_tongue_widget.cpp widgets/kis_tone_curve_widget.cpp widgets/kis_curve_widget.cpp widgets/kis_custom_image_widget.cc widgets/kis_image_from_clipboard_widget.cpp widgets/kis_double_widget.cc widgets/kis_filter_selector_widget.cc widgets/kis_gradient_chooser.cc widgets/kis_iconwidget.cc widgets/kis_mask_widgets.cpp widgets/kis_meta_data_merge_strategy_chooser_widget.cc widgets/kis_multi_bool_filter_widget.cc widgets/kis_multi_double_filter_widget.cc widgets/kis_multi_integer_filter_widget.cc widgets/kis_multipliers_double_slider_spinbox.cpp widgets/kis_paintop_presets_popup.cpp widgets/kis_tool_options_popup.cpp widgets/kis_paintop_presets_chooser_popup.cpp widgets/kis_paintop_presets_save.cpp widgets/kis_paintop_preset_icon_library.cpp widgets/kis_pattern_chooser.cc widgets/kis_preset_chooser.cpp widgets/kis_progress_widget.cpp widgets/kis_selection_options.cc widgets/kis_scratch_pad.cpp widgets/kis_scratch_pad_event_filter.cpp widgets/kis_preset_selector_strip.cpp widgets/kis_slider_spin_box.cpp widgets/KisSelectionPropertySlider.cpp widgets/kis_size_group.cpp widgets/kis_size_group_p.cpp widgets/kis_wdg_generator.cpp widgets/kis_workspace_chooser.cpp widgets/kis_categorized_list_view.cpp widgets/kis_widget_chooser.cpp widgets/kis_tool_button.cpp widgets/kis_floating_message.cpp widgets/kis_lod_availability_widget.cpp widgets/kis_color_label_selector_widget.cpp widgets/kis_color_filter_combo.cpp widgets/kis_elided_label.cpp widgets/kis_stopgradient_slider_widget.cpp widgets/kis_preset_live_preview_view.cpp widgets/KisScreenColorPicker.cpp widgets/KoDualColorButton.cpp widgets/KoStrokeConfigWidget.cpp widgets/KoFillConfigWidget.cpp widgets/KisNewsWidget.cpp + widgets/KisGamutMaskToolbar.cpp utils/kis_document_aware_spin_box_unit_manager.cpp input/kis_input_manager.cpp input/kis_input_manager_p.cpp input/kis_extended_modifiers_mapper.cpp input/kis_abstract_input_action.cpp input/kis_tool_invocation_action.cpp input/kis_pan_action.cpp input/kis_alternate_invocation_action.cpp input/kis_rotate_canvas_action.cpp input/kis_zoom_action.cpp input/kis_change_frame_action.cpp input/kis_gamma_exposure_action.cpp input/kis_show_palette_action.cpp input/kis_change_primary_setting_action.cpp input/kis_abstract_shortcut.cpp input/kis_native_gesture_shortcut.cpp input/kis_single_action_shortcut.cpp input/kis_stroke_shortcut.cpp input/kis_shortcut_matcher.cpp input/kis_select_layer_action.cpp input/KisQtWidgetsTweaker.cpp input/KisInputActionGroup.cpp operations/kis_operation.cpp operations/kis_operation_configuration.cpp operations/kis_operation_registry.cpp operations/kis_operation_ui_factory.cpp operations/kis_operation_ui_widget.cpp operations/kis_filter_selection_operation.cpp actions/kis_selection_action_factories.cpp actions/KisPasteActionFactory.cpp input/kis_touch_shortcut.cpp kis_document_undo_store.cpp kis_gui_context_command.cpp kis_gui_context_command_p.cpp input/kis_tablet_debugger.cpp input/kis_input_profile_manager.cpp input/kis_input_profile.cpp input/kis_shortcut_configuration.cpp input/config/kis_input_configuration_page.cpp input/config/kis_edit_profiles_dialog.cpp input/config/kis_input_profile_model.cpp input/config/kis_input_configuration_page_item.cpp input/config/kis_action_shortcuts_model.cpp input/config/kis_input_type_delegate.cpp input/config/kis_input_mode_delegate.cpp input/config/kis_input_button.cpp input/config/kis_input_editor_delegate.cpp input/config/kis_mouse_input_editor.cpp input/config/kis_wheel_input_editor.cpp input/config/kis_key_input_editor.cpp processing/fill_processing_visitor.cpp kis_asl_layer_style_serializer.cpp kis_psd_layer_style_resource.cpp canvas/kis_mirror_axis.cpp kis_abstract_perspective_grid.cpp KisApplication.cpp KisAutoSaveRecoveryDialog.cpp KisDetailsPane.cpp KisDocument.cpp KisCloneDocumentStroke.cpp KisNodeDelegate.cpp kis_node_view_visibility_delegate.cpp KisNodeToolTip.cpp KisNodeView.cpp kis_node_view_color_scheme.cpp KisImportExportFilter.cpp KisFilterEntry.cpp KisImportExportManager.cpp KisImportExportUtils.cpp kis_async_action_feedback.cpp KisMainWindow.cpp KisOpenPane.cpp KisPart.cpp KisPrintJob.cpp KisTemplate.cpp KisTemplateCreateDia.cpp KisTemplateGroup.cpp KisTemplates.cpp KisTemplatesPane.cpp KisTemplateTree.cpp KisUndoActionsUpdateManager.cpp KisView.cpp thememanager.cpp kis_mainwindow_observer.cpp KisViewManager.cpp kis_mirror_manager.cpp qtlockedfile/qtlockedfile.cpp qtsingleapplication/qtlocalpeer.cpp qtsingleapplication/qtsingleapplication.cpp KisResourceBundle.cpp KisResourceBundleManifest.cpp kis_md5_generator.cpp KisApplicationArguments.cpp KisNetworkAccessManager.cpp KisMultiFeedRSSModel.cpp KisRemoteFileFetcher.cpp KisSaveGroupVisitor.cpp KisWindowLayoutResource.cpp KisWindowLayoutManager.cpp KisSessionResource.cpp KisReferenceImagesDecoration.cpp KisReferenceImage.cpp flake/KisReferenceImagesLayer.cpp flake/KisReferenceImagesLayer.h ) if(WIN32) set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} input/kis_tablet_event.cpp input/wintab/kis_tablet_support_win.cpp input/wintab/kis_screen_size_choice_dialog.cpp qtlockedfile/qtlockedfile_win.cpp input/wintab/kis_tablet_support_win8.cpp opengl/kis_opengl_win.cpp ) endif() set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} kis_animation_frame_cache.cpp kis_animation_cache_populator.cpp KisAsyncAnimationRendererBase.cpp KisAsyncAnimationCacheRenderer.cpp KisAsyncAnimationFramesSavingRenderer.cpp dialogs/KisAsyncAnimationRenderDialogBase.cpp dialogs/KisAsyncAnimationCacheRenderDialog.cpp dialogs/KisAsyncAnimationFramesSaveDialog.cpp canvas/kis_animation_player.cpp kis_animation_importer.cpp KisSyncedAudioPlayback.cpp KisFrameDataSerializer.cpp KisFrameCacheStore.cpp KisFrameCacheSwapper.cpp KisAbstractFrameCacheSwapper.cpp KisInMemoryFrameCacheSwapper.cpp input/wintab/drawpile_tablettester/tablettester.cpp input/wintab/drawpile_tablettester/tablettest.cpp ) if(UNIX) set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} input/kis_tablet_event.cpp input/wintab/kis_tablet_support.cpp qtlockedfile/qtlockedfile_unix.cpp ) if(NOT APPLE) set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} input/wintab/qxcbconnection_xi2.cpp input/wintab/qxcbconnection.cpp input/wintab/kis_xi2_event_filter.cpp ) endif() endif() if(APPLE) set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} osx.mm ) endif() ki18n_wrap_ui(kritaui_LIB_SRCS widgets/KoFillConfigWidget.ui widgets/KoStrokeConfigWidget.ui forms/wdgdlgpngimport.ui forms/wdgfullscreensettings.ui forms/wdgautogradient.ui forms/wdggeneralsettings.ui forms/wdgperformancesettings.ui forms/wdggenerators.ui forms/wdgbookmarkedconfigurationseditor.ui forms/wdgapplyprofile.ui forms/wdgcustompattern.ui forms/wdglayerproperties.ui forms/wdgcolorsettings.ui forms/wdgtabletsettings.ui forms/wdgcolorspaceselector.ui forms/wdgcolorspaceselectoradvanced.ui forms/wdgdisplaysettings.ui forms/kis_previewwidgetbase.ui forms/kis_matrix_widget.ui forms/wdgselectionoptions.ui forms/wdggeometryoptions.ui forms/wdgnewimage.ui forms/wdgimageproperties.ui forms/wdgmaskfromselection.ui forms/wdgmasksource.ui forms/wdgfilterdialog.ui forms/wdgmetadatamergestrategychooser.ui forms/wdgpaintoppresets.ui forms/wdgpaintopsettings.ui forms/wdgdlggeneratorlayer.ui forms/wdgdlgfilelayer.ui forms/wdgfilterselector.ui forms/wdgfilternodecreation.ui forms/wdgmultipliersdoublesliderspinbox.ui forms/wdgnodequerypatheditor.ui forms/wdgpresetselectorstrip.ui forms/wdgsavebrushpreset.ui forms/wdgpreseticonlibrary.ui forms/wdgdlgblacklistcleanup.ui forms/wdgrectangleconstraints.ui forms/wdgimportimagesequence.ui forms/wdgstrokeselectionproperties.ui forms/KisDetailsPaneBase.ui forms/KisOpenPaneBase.ui forms/wdgstopgradienteditor.ui forms/wdgsessionmanager.ui forms/wdgnewwindowlayout.ui forms/KisWelcomePage.ui forms/KisNewsPage.ui + forms/wdgGamutMaskToolbar.ui brushhud/kis_dlg_brush_hud_config.ui dialogs/kis_delayed_save_dialog.ui input/config/kis_input_configuration_page.ui input/config/kis_edit_profiles_dialog.ui input/config/kis_input_configuration_page_item.ui input/config/kis_mouse_input_editor.ui input/config/kis_wheel_input_editor.ui input/config/kis_key_input_editor.ui layerstyles/wdgBevelAndEmboss.ui layerstyles/wdgblendingoptions.ui layerstyles/WdgColorOverlay.ui layerstyles/wdgContour.ui layerstyles/wdgdropshadow.ui layerstyles/WdgGradientOverlay.ui layerstyles/wdgInnerGlow.ui layerstyles/wdglayerstyles.ui layerstyles/WdgPatternOverlay.ui layerstyles/WdgSatin.ui layerstyles/WdgStroke.ui layerstyles/wdgstylesselector.ui layerstyles/wdgTexture.ui wdgsplash.ui input/wintab/kis_screen_size_choice_dialog.ui input/wintab/drawpile_tablettester/tablettest.ui ) QT5_WRAP_CPP(kritaui_HEADERS_MOC KisNodePropertyAction_p.h) add_library(kritaui SHARED ${kritaui_HEADERS_MOC} ${kritaui_LIB_SRCS} ) generate_export_header(kritaui BASE_NAME kritaui) target_link_libraries(kritaui KF5::CoreAddons KF5::Completion KF5::I18n KF5::ItemViews Qt5::Network kritaimpex kritacolor kritaimage kritalibbrush kritawidgets kritawidgetutils ${PNG_LIBRARIES} ${EXIV2_LIBRARIES} ) if (HAVE_QT_MULTIMEDIA) target_link_libraries(kritaui Qt5::Multimedia) endif() if (HAVE_KIO) target_link_libraries(kritaui KF5::KIOCore) endif() if (NOT WIN32 AND NOT APPLE) target_link_libraries(kritaui ${X11_X11_LIB} ${X11_Xinput_LIB} ${XCB_LIBRARIES}) endif() if(APPLE) target_link_libraries(kritaui ${FOUNDATION_LIBRARY}) target_link_libraries(kritaui ${APPKIT_LIBRARY}) endif () target_link_libraries(kritaui ${OPENEXR_LIBRARIES}) # Add VSync disable workaround if(NOT WIN32 AND NOT APPLE) target_link_libraries(kritaui ${CMAKE_DL_LIBS} Qt5::X11Extras) endif() if(X11_FOUND) target_link_libraries(kritaui Qt5::X11Extras ${X11_LIBRARIES}) endif() target_include_directories(kritaui PUBLIC $ $ $ $ $ $ $ ) set_target_properties(kritaui PROPERTIES VERSION ${GENERIC_KRITA_LIB_VERSION} SOVERSION ${GENERIC_KRITA_LIB_SOVERSION} ) install(TARGETS kritaui ${INSTALL_TARGETS_DEFAULT_ARGS}) if (APPLE) install(FILES osx.stylesheet DESTINATION ${DATA_INSTALL_DIR}/krita) endif () diff --git a/libs/ui/forms/wdgGamutMaskToolbar.ui b/libs/ui/forms/wdgGamutMaskToolbar.ui new file mode 100644 index 0000000000..f5c9239252 --- /dev/null +++ b/libs/ui/forms/wdgGamutMaskToolbar.ui @@ -0,0 +1,104 @@ + + + wdgGamutMaskToolbar + + + + 0 + 0 + 378 + 57 + + + + + 0 + 0 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 20 + + + + Toggle gamut mask + + + + + + true + + + + + + + + 0 + 0 + + + + Select a mask in "Gamut Masks" docker + + + true + + + + + + + + 0 + 0 + + + + + 0 + 20 + + + + + + + + + KisSliderSpinBox + QWidget +
kis_slider_spin_box.h
+ 1 +
+
+ + +
diff --git a/libs/ui/widgets/KisGamutMaskToolbar.cpp b/libs/ui/widgets/KisGamutMaskToolbar.cpp new file mode 100644 index 0000000000..88201939b3 --- /dev/null +++ b/libs/ui/widgets/KisGamutMaskToolbar.cpp @@ -0,0 +1,115 @@ +/* + * 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 +#include "KisGamutMaskToolbar.h" +#include +#include + +KisGamutMaskToolbar::KisGamutMaskToolbar(QWidget* parent) : QWidget(parent) + , m_selectedMask(nullptr) +{ + m_ui = new Ui_wdgGamutMaskToolbar(); + m_ui->setupUi(this); + + m_iconMaskOff = KisIconUtils::loadIcon("gamut-mask-off"); + m_iconMaskOn = KisIconUtils::loadIcon("gamut-mask-on"); + + m_textNoMask = i18n("Select a mask in \"Gamut Masks\" docker"); + m_textMaskDisabled = i18n("Mask is disabled"); + + m_ui->bnToggleMask->setChecked(false); + m_ui->bnToggleMask->setIcon(m_iconMaskOff); + + m_ui->rotationSlider->setRange(0, 360); + m_ui->rotationSlider->setPrefix(i18n("Rotation: ")); + m_ui->rotationSlider->setSuffix("°"); + m_ui->rotationSlider->setFastSliderStep(30); // TODO: test for usability + m_ui->rotationSlider->hide(); + + // gamut mask connections + connect(m_ui->bnToggleMask, SIGNAL(toggled(bool)), SLOT(slotGamutMaskToggle(bool))); + connect(m_ui->rotationSlider, SIGNAL(valueChanged(int)), SLOT(slotGamutMaskRotate(int))); +} + +void KisGamutMaskToolbar::connectMaskSignals(KisCanvasResourceProvider* resourceProvider) +{ + connect(resourceProvider, SIGNAL(sigGamutMaskChanged(KoGamutMask*)), + this, SLOT(slotGamutMaskSet(KoGamutMask*))); + + connect(resourceProvider, SIGNAL(sigGamutMaskUnset()), + this, SLOT(slotGamutMaskUnset())); + + connect(this, SIGNAL(sigGamutMaskChanged(KoGamutMask*)), + resourceProvider, SLOT(slotGamutMaskActivated(KoGamutMask*))); +} + +void KisGamutMaskToolbar::slotGamutMaskSet(KoGamutMask *mask) +{ + if (!mask) { + return; + } + + m_selectedMask = mask; + + if (m_selectedMask) { + slotGamutMaskToggle(true); + } else { + slotGamutMaskToggle(false); + } +} + +void KisGamutMaskToolbar::slotGamutMaskUnset() +{ + m_ui->rotationSlider->hide(); + m_ui->labelMaskName->show(); + m_ui->labelMaskName->setText(m_textNoMask); +} + +void KisGamutMaskToolbar::slotGamutMaskToggle(bool state) +{ + bool b = (!m_selectedMask) ? false : state; + + m_ui->bnToggleMask->setChecked(b); + + if (b == true) { + m_ui->bnToggleMask->setIcon(m_iconMaskOn); + m_ui->labelMaskName->hide(); + m_ui->rotationSlider->show(); + + m_ui->rotationSlider->blockSignals(true); + m_ui->rotationSlider->setValue(m_selectedMask->rotation()); + m_ui->rotationSlider->blockSignals(false); + } else { + m_ui->bnToggleMask->setIcon(m_iconMaskOff); + m_ui->rotationSlider->hide(); + m_ui->labelMaskName->show(); + m_ui->labelMaskName->setText(m_textMaskDisabled); + } + + emit sigGamutMaskToggle(state); +} + +void KisGamutMaskToolbar::slotGamutMaskRotate(int angle) +{ + if (!m_selectedMask) { + return; + } + + m_selectedMask->setRotation(angle); + emit sigGamutMaskChanged(m_selectedMask); +} diff --git a/libs/ui/widgets/KisGamutMaskToolbar.h b/libs/ui/widgets/KisGamutMaskToolbar.h new file mode 100644 index 0000000000..45386705b2 --- /dev/null +++ b/libs/ui/widgets/KisGamutMaskToolbar.h @@ -0,0 +1,61 @@ +/* + * 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 KISGAMUTMASKTOOLBAR_H +#define KISGAMUTMASKTOOLBAR_H + +#include +#include + +#include +#include "kritaui_export.h" + +#include "ui_wdgGamutMaskToolbar.h" + +class KisCanvasResourceProvider; + +class KRITAUI_EXPORT KisGamutMaskToolbar : public QWidget +{ + Q_OBJECT +public: + KisGamutMaskToolbar(QWidget* parent = nullptr); + void connectMaskSignals(KisCanvasResourceProvider* resourceProvider); + +Q_SIGNALS: + void sigGamutMaskToggle(bool state); + void sigGamutMaskChanged(KoGamutMask*); + +public Q_SLOTS: + void slotGamutMaskSet(KoGamutMask* mask); + void slotGamutMaskUnset(); + +private Q_SLOTS: + void slotGamutMaskToggle(bool state); + void slotGamutMaskRotate(int angle); + +private: + Ui_wdgGamutMaskToolbar* m_ui; + KoGamutMask* m_selectedMask; + + QIcon m_iconMaskOff; + QIcon m_iconMaskOn; + + QString m_textNoMask; + QString m_textMaskDisabled; +}; + +#endif // KISGAMUTMASKTOOLBAR_H diff --git a/plugins/dockers/advancedcolorselector/kis_color_selector.cpp b/plugins/dockers/advancedcolorselector/kis_color_selector.cpp index 17b3703199..0a01117fb7 100644 --- a/plugins/dockers/advancedcolorselector/kis_color_selector.cpp +++ b/plugins/dockers/advancedcolorselector/kis_color_selector.cpp @@ -1,366 +1,395 @@ /* * Copyright (c) 2010 Adam Celarek * * 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 "kis_color_selector.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_color_selector_ring.h" #include "kis_color_selector_triangle.h" #include "kis_color_selector_simple.h" #include "kis_color_selector_wheel.h" #include "kis_color_selector_container.h" #include "kis_canvas2.h" #include "kis_signal_compressor.h" #include "KisViewManager.h" KisColorSelector::KisColorSelector(KisColorSelectorConfiguration conf, QWidget* parent) : KisColorSelectorBase(parent), m_ring(0), m_triangle(0), m_slider(0), m_square(0), m_wheel(0), m_mainComponent(0), m_subComponent(0), m_grabbingComponent(0), m_blipDisplay(true) { init(); updateSettings(); setConfiguration(conf); } KisColorSelector::KisColorSelector(QWidget* parent) : KisColorSelectorBase(parent), m_ring(0), m_triangle(0), m_slider(0), m_square(0), m_wheel(0), m_button(0), m_mainComponent(0), m_subComponent(0), m_grabbingComponent(0), m_blipDisplay(true) { init(); updateSettings(); } KisColorSelectorBase* KisColorSelector::createPopup() const { KisColorSelectorBase* popup = new KisColorSelector(0); popup->setColor(m_lastRealColor); return popup; } void KisColorSelector::setConfiguration(KisColorSelectorConfiguration conf) { m_configuration = conf; if(m_mainComponent!=0) { Q_ASSERT(m_subComponent!=0); m_mainComponent->setGeometry(0, 0, 0, 0); m_subComponent->setGeometry(0, 0, 0, 0); m_mainComponent->disconnect(); m_subComponent->disconnect(); } switch (m_configuration.mainType) { case KisColorSelectorConfiguration::Square: m_mainComponent=m_square; break; case KisColorSelectorConfiguration::Wheel: m_mainComponent=m_wheel; break; case KisColorSelectorConfiguration::Triangle: m_mainComponent=m_triangle; break; default: Q_ASSERT(false); } switch (m_configuration.subType) { case KisColorSelectorConfiguration::Ring: m_subComponent=m_ring; break; case KisColorSelectorConfiguration::Slider: m_subComponent=m_slider; break; default: Q_ASSERT(false); } connect(m_mainComponent, SIGNAL(paramChanged(qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal)), m_subComponent, SLOT(setParam(qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal)), Qt::UniqueConnection); connect(m_subComponent, SIGNAL(paramChanged(qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal)), m_mainComponent, SLOT(setParam(qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal)), Qt::UniqueConnection); connect(m_mainComponent, SIGNAL(update()), m_signalCompressor, SLOT(start()), Qt::UniqueConnection); connect(m_subComponent, SIGNAL(update()), m_signalCompressor, SLOT(start()), Qt::UniqueConnection); m_mainComponent->setConfiguration(m_configuration.mainTypeParameter, m_configuration.mainType); m_subComponent->setConfiguration(m_configuration.subTypeParameter, m_configuration.subType); QResizeEvent event(QSize(width(), height()), QSize()); resizeEvent(&event); } KisColorSelectorConfiguration KisColorSelector::configuration() const { return m_configuration; } void KisColorSelector::updateSettings() { KisColorSelectorBase::updateSettings(); KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector"); + setConfiguration(KisColorSelectorConfiguration::fromString(cfg.readEntry("colorSelectorConfiguration", KisColorSelectorConfiguration().toString()))); } +void KisColorSelector::slotGamutMaskSet(KoGamutMask *gamutMask) +{ + m_mainComponent->setGamutMask(gamutMask); + m_subComponent->setGamutMask(gamutMask); + + slotGamutMaskToggle(true); +} + +void KisColorSelector::slotGamutMaskUnset() +{ + m_mainComponent->unsetGamutMask(); + m_subComponent->unsetGamutMask(); + + slotGamutMaskToggle(false); +} + +void KisColorSelector::slotGamutMaskPreviewUpdate() +{ + m_mainComponent->updateGamutMaskPreview(); + m_subComponent->updateGamutMaskPreview(); +} + +void KisColorSelector::slotGamutMaskToggle(bool state) +{ + m_mainComponent->toggleGamutMask(state); + m_subComponent->toggleGamutMask(state); +} + void KisColorSelector::updateIcons() { if (m_button) { m_button->setIcon(KisIconUtils::loadIcon("configure")); } } void KisColorSelector::hasAtLeastOneDocument(bool value) { m_hasAtLeastOneDocumentOpen = value; } void KisColorSelector::reset() { KisColorSelectorBase::reset(); if (m_mainComponent) { m_mainComponent->setDirty(); } if (m_subComponent) { m_subComponent->setDirty(); } } void KisColorSelector::paintEvent(QPaintEvent* e) { Q_UNUSED(e); QPainter p(this); p.fillRect(0,0,width(), height(), QColor(128,128,128)); p.setRenderHint(QPainter::Antialiasing); // this variable name isn't entirely accurate to what always happens. see definition in header file to understand it better if (!m_hasAtLeastOneDocumentOpen) { p.setOpacity(0.2); } m_mainComponent->paintEvent(&p); m_subComponent->paintEvent(&p); p.setOpacity(1.0); } inline int iconSize(qreal width, qreal height) { qreal radius = qMin(width, height)/2.; qreal xm = width/2.; qreal ym = height/2.; if(xm>=2*ym || ym>=2*xm) return qBound(5., radius, 32.); qreal a=-2; qreal b=2.*(xm+ym); qreal c=radius*radius-xm*xm-ym*ym; return qBound(5., ((-b+sqrt(b*b-4*a*c))/(2*a)), 32.); } void KisColorSelector::resizeEvent(QResizeEvent* e) { if (m_configuration.subType == KisColorSelectorConfiguration::Ring) { m_ring->setGeometry(0,0,width(), height()); if (displaySettingsButton()) { int size = iconSize(width(), height()); m_button->setGeometry(0, 0, size, size); } if (m_configuration.mainType == KisColorSelectorConfiguration::Triangle) { m_triangle->setGeometry(width()/2-m_ring->innerRadius(), height()/2-m_ring->innerRadius(), m_ring->innerRadius()*2, m_ring->innerRadius()*2); } else { int size = m_ring->innerRadius()*2/sqrt(2.); m_square->setGeometry(width()/2-size/2, height()/2-size/2, size, size); } } else { // type wheel and square if (m_configuration.mainType == KisColorSelectorConfiguration::Wheel) { if(displaySettingsButton()) { int size = iconSize(width(), height()*0.9); m_button->setGeometry(0, height()*0.1, size, size); } m_mainComponent->setGeometry(0, height()*0.1, width(), height()*0.9); m_subComponent->setGeometry( 0, 0, width(), height()*0.1); } else { int buttonSize = 0; if(displaySettingsButton()) { buttonSize = qBound(20, int(0.1*height()), 32); m_button->setGeometry(0, 0, buttonSize, buttonSize); } if(height()>width()) { int selectorHeight=height()-buttonSize; m_mainComponent->setGeometry(0, buttonSize+selectorHeight*0.1, width(), selectorHeight*0.9); m_subComponent->setGeometry( 0, buttonSize, width(), selectorHeight*0.1); } else { int selectorWidth=width()-buttonSize; m_mainComponent->setGeometry(buttonSize, height()*0.1, selectorWidth, height()*0.9); m_subComponent->setGeometry( buttonSize, 0, selectorWidth, height()*0.1); } } } // reset the correct color after resizing the widget setColor(m_lastRealColor); KisColorSelectorBase::resizeEvent(e); } void KisColorSelector::mousePressEvent(QMouseEvent* e) { e->setAccepted(false); KisColorSelectorBase::mousePressEvent(e); if(!e->isAccepted()) { if(m_mainComponent->wantsGrab(e->x(), e->y())) m_grabbingComponent=m_mainComponent; else if(m_subComponent->wantsGrab(e->x(), e->y())) m_grabbingComponent=m_subComponent; mouseEvent(e); updatePreviousColorPreview(); e->accept(); } } void KisColorSelector::mouseMoveEvent(QMouseEvent* e) { KisColorSelectorBase::mouseMoveEvent(e); mouseEvent(e); e->accept(); } void KisColorSelector::mouseReleaseEvent(QMouseEvent* e) { e->setAccepted(false); KisColorSelectorBase::mousePressEvent(e); if(!e->isAccepted() && !(m_lastRealColor == m_currentRealColor)) { m_lastRealColor = m_currentRealColor; m_lastColorRole = Acs::buttonToRole(e->button()); updateColor(m_lastRealColor, m_lastColorRole, false); updateBaseColorPreview(m_currentRealColor); e->accept(); } m_grabbingComponent=0; } bool KisColorSelector::displaySettingsButton() { return dynamic_cast(parent()); } void KisColorSelector::setColor(const KoColor &color) { m_mainComponent->setColor(color); m_subComponent->setColor(color); m_lastRealColor = color; m_signalCompressor->start(); } void KisColorSelector::mouseEvent(QMouseEvent *e) { if (m_grabbingComponent && (e->buttons() & Qt::LeftButton || e->buttons() & Qt::RightButton)) { m_grabbingComponent->mouseEvent(e->x(), e->y()); KoColor color = m_mainComponent->currentColor(); Acs::ColorRole role = Acs::buttonsToRole(e->button(), e->buttons()); m_currentRealColor = color; requestUpdateColorAndPreview(color, role); } } void KisColorSelector::init() { setAcceptDrops(true); m_lastColorRole = Acs::Foreground; m_ring = new KisColorSelectorRing(this); m_triangle = new KisColorSelectorTriangle(this); m_slider = new KisColorSelectorSimple(this); m_square = new KisColorSelectorSimple(this); m_wheel = new KisColorSelectorWheel(this); if(displaySettingsButton()) { m_button = new QPushButton(this); m_button->setIcon(KisIconUtils::loadIcon("configure")); m_button->setFlat(true); connect(m_button, SIGNAL(clicked()), SIGNAL(settingsButtonClicked())); } // a tablet can send many more signals, than a mouse // this causes many repaints, if updating after every signal. m_signalCompressor = new KisSignalCompressor(20, KisSignalCompressor::FIRST_INACTIVE, this); connect(m_signalCompressor, SIGNAL(timeout()), SLOT(update())); setMinimumSize(40, 40); } diff --git a/plugins/dockers/advancedcolorselector/kis_color_selector.h b/plugins/dockers/advancedcolorselector/kis_color_selector.h index 362a01bc98..c71661019d 100644 --- a/plugins/dockers/advancedcolorselector/kis_color_selector.h +++ b/plugins/dockers/advancedcolorselector/kis_color_selector.h @@ -1,101 +1,104 @@ /* * Copyright (c) 2010 Adam Celarek * * 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_COLOR_SELECTOR_H #define KIS_COLOR_SELECTOR_H #include "kis_color_selector_base.h" #include class KisColorSelectorRing; class KisColorSelectorComponent; class KisColorSelectorSimple; class KisColorSelectorWheel; class QPushButton; class KisSignalCompressor; class KisColorSelector : public KisColorSelectorBase { Q_OBJECT public: KisColorSelector(KisColorSelectorConfiguration conf, QWidget* parent = 0); KisColorSelector(QWidget* parent=0); KisColorSelectorBase* createPopup() const override; void setConfiguration(KisColorSelectorConfiguration conf); KisColorSelectorConfiguration configuration() const; void setColor(const KoColor &color) override; /// update icons when a theme update happens void updateIcons(); void hasAtLeastOneDocument(bool value); public Q_SLOTS: void reset() override; void updateSettings() override; - + void slotGamutMaskSet(KoGamutMask* gamutMask); + void slotGamutMaskUnset(); + void slotGamutMaskPreviewUpdate(); + void slotGamutMaskToggle(bool state); Q_SIGNALS: void settingsButtonClicked(); protected: void paintEvent(QPaintEvent*) override; void resizeEvent(QResizeEvent*) override; void mousePressEvent(QMouseEvent*) override; void mouseMoveEvent(QMouseEvent*) override; void mouseReleaseEvent(QMouseEvent*) override; bool displaySettingsButton(); private: void mouseEvent(QMouseEvent* e); void init(); KisColorSelectorRing* m_ring; KisColorSelectorComponent* m_triangle; KisColorSelectorSimple* m_slider; KisColorSelectorSimple* m_square; KisColorSelectorWheel* m_wheel; QPushButton* m_button; KisColorSelectorComponent* m_mainComponent; KisColorSelectorComponent* m_subComponent; KisColorSelectorComponent* m_grabbingComponent; KisSignalCompressor *m_signalCompressor; KisColorSelectorConfiguration m_configuration; KoColor m_lastRealColor; KoColor m_currentRealColor; bool m_blipDisplay; Acs::ColorRole m_lastColorRole; /// if Krita starts with a reference to this componenet that is attached to a canvas, it will call setCanvas() /// that check will be what ultimately decides whether this component will look enabled or disabled /// This color selector is sometimes not attached to the canvas, so we shouldn't disable it in that situation /// One instane of that is when you select the color wheel type from the settings. bool m_hasAtLeastOneDocumentOpen = true; public: void setDisplayBlip(bool disp) {m_blipDisplay = disp;} bool displayBlip() const {return m_blipDisplay;} }; #endif // KIS_COLSELNG_COLOR_SELECTOR_H diff --git a/plugins/dockers/advancedcolorselector/kis_color_selector_base.cpp b/plugins/dockers/advancedcolorselector/kis_color_selector_base.cpp index c6e9233f89..55bb587097 100644 --- a/plugins/dockers/advancedcolorselector/kis_color_selector_base.cpp +++ b/plugins/dockers/advancedcolorselector/kis_color_selector_base.cpp @@ -1,536 +1,537 @@ /* * Copyright (c) 2010 Adam Celarek * * 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 */ #include "kis_color_selector_base.h" #include #include #include #include #include #include #include #include #include #include #include "KoColorSpace.h" #include "KoColorSpaceRegistry.h" #include "kis_canvas2.h" #include "kis_canvas_resource_provider.h" #include "kis_node.h" #include "KisViewManager.h" #include #include "kis_image.h" #include "kis_display_color_converter.h" +#include class KisColorPreviewPopup : public QWidget { public: KisColorPreviewPopup(KisColorSelectorBase* parent) : QWidget(), m_parent(parent) { setWindowFlags(Qt::ToolTip); setQColor(QColor(0,0,0)); setMouseTracking(true); m_baseColor = QColor(0,0,0,0); m_previousColor = QColor(0,0,0,0); m_lastUsedColor = QColor(0,0,0,0); } void show() { updatePosition(); QWidget::show(); } void updatePosition() { QPoint parentPos = m_parent->mapToGlobal(QPoint(0,0)); QRect availRect = QApplication::desktop()->availableGeometry(this); QPoint targetPos; if ( parentPos.x() - 100 > availRect.x() ) { targetPos = QPoint(parentPos.x() - 100, parentPos.y()); } else if ( parentPos.x() + m_parent->width() + 100 < availRect.right()) { targetPos = m_parent->mapToGlobal(QPoint(m_parent->width(), 0)); } else if ( parentPos.y() - 100 > availRect.y() ) { targetPos = QPoint(parentPos.x(), parentPos.y() - 100); } else { targetPos = QPoint(parentPos.x(), parentPos.y() + m_parent->height()); } setGeometry(targetPos.x(), targetPos.y(), 100, 150); setAttribute(Qt::WA_TranslucentBackground); } void setQColor(const QColor& color) { m_color = color; update(); } void setPreviousColor() { m_previousColor = m_baseColor; } void setBaseColor(const QColor& color) { m_baseColor = color; update(); } void setLastUsedColor(const QColor& color) { m_lastUsedColor = color; update(); } protected: void paintEvent(QPaintEvent *e) override { Q_UNUSED(e); QPainter p(this); p.fillRect(0, 0, width(), width(), m_color); p.fillRect(50, width(), width(), height(), m_previousColor); p.fillRect(0, width(), 50, height(), m_lastUsedColor); } private: KisColorSelectorBase* m_parent; QColor m_color; QColor m_baseColor; QColor m_previousColor; QColor m_lastUsedColor; }; KisColorSelectorBase::KisColorSelectorBase(QWidget *parent) : QWidget(parent), m_canvas(0), m_popup(0), m_parent(0), m_colorUpdateAllowed(true), m_colorUpdateSelf(false), m_hideTimer(new QTimer(this)), m_popupOnMouseOver(false), m_popupOnMouseClick(true), m_colorSpace(0), m_isPopup(false), m_hideOnMouseClick(false), m_colorPreviewPopup(new KisColorPreviewPopup(this)) { m_hideTimer->setInterval(0); m_hideTimer->setSingleShot(true); connect(m_hideTimer, SIGNAL(timeout()), this, SLOT(hidePopup())); using namespace std::placeholders; // For _1 placeholder auto function = std::bind(&KisColorSelectorBase::slotUpdateColorAndPreview, this, _1); m_updateColorCompressor.reset(new ColorCompressorType(20 /* ms */, function)); } KisColorSelectorBase::~KisColorSelectorBase() { delete m_popup; delete m_colorPreviewPopup; } void KisColorSelectorBase::setPopupBehaviour(bool onMouseOver, bool onMouseClick) { m_popupOnMouseClick = onMouseClick; m_popupOnMouseOver = onMouseOver; if(onMouseClick) { m_popupOnMouseOver = false; } if(m_popupOnMouseOver) { setMouseTracking(true); } } void KisColorSelectorBase::setColorSpace(const KoColorSpace *colorSpace) { m_colorSpace = colorSpace; } void KisColorSelectorBase::setCanvas(KisCanvas2 *canvas) { if (m_canvas) { m_canvas->disconnectCanvasObserver(this); } m_canvas = canvas; if (m_canvas) { connect(m_canvas->resourceManager(), SIGNAL(canvasResourceChanged(int,QVariant)), SLOT(canvasResourceChanged(int,QVariant)), Qt::UniqueConnection); connect(m_canvas->displayColorConverter(), SIGNAL(displayConfigurationChanged()), SLOT(reset())); connect(canvas->imageView()->resourceProvider(), SIGNAL(sigFGColorUsed(KoColor)), this, SLOT(updateLastUsedColorPreview(KoColor)), Qt::UniqueConnection); if (m_canvas->viewManager() && m_canvas->viewManager()->resourceProvider()) { setColor(Acs::currentColor(m_canvas->viewManager()->resourceProvider(), Acs::Foreground)); } } if (m_popup) { m_popup->setCanvas(canvas); } reset(); } void KisColorSelectorBase::unsetCanvas() { if (m_popup) { m_popup->unsetCanvas(); } m_canvas = 0; } void KisColorSelectorBase::mousePressEvent(QMouseEvent* event) { event->accept(); //this boolean here is to check if the colour selector is updating the resource, so it won't update itself when the resource is updated// if (m_colorUpdateSelf==false) {m_colorUpdateSelf=true;} if(!m_isPopup && m_popupOnMouseClick && event->button() == Qt::MidButton) { lazyCreatePopup(); int x = event->globalX(); int y = event->globalY(); int popupsize = m_popup->width(); x-=popupsize/2; y-=popupsize/2; QRect availRect = QApplication::desktop()->availableGeometry(this); if(xwidth()>availRect.x()+availRect.width()) x = availRect.x()+availRect.width()-m_popup->width(); if(y+m_popup->height()>availRect.y()+availRect.height()) y = availRect.y()+availRect.height()-m_popup->height(); m_popup->move(x, y); m_popup->setHidingTime(200); showPopup(DontMove); } else if (m_isPopup && event->button() == Qt::MidButton) { hide(); } else { showColorPreview(); event->ignore(); } } void KisColorSelectorBase::mouseReleaseEvent(QMouseEvent *e) { Q_UNUSED(e); if (e->button() == Qt::MidButton) { e->accept(); } else if (m_isPopup && m_hideOnMouseClick==true && !m_hideTimer->isActive()) { showColorPreview(); hide(); } } void KisColorSelectorBase::enterEvent(QEvent *e) { Q_UNUSED(e); if (m_popup && m_popup->isVisible()) { m_popup->m_hideTimer->stop(); } if (m_isPopup && m_hideTimer->isActive()) { m_hideTimer->stop(); } // do not show the popup when boxed in // the configuration dialog (m_canvas == 0) if (m_canvas && !m_isPopup && m_popupOnMouseOver && (!m_popup || m_popup->isHidden())) { lazyCreatePopup(); QRect availRect = QApplication::desktop()->availableGeometry(this); QRect forbiddenRect = QRect(parentWidget()->mapToGlobal(QPoint(0,0)), QSize(parentWidget()->width(), parentWidget()->height())); int x,y; if(forbiddenRect.y()+forbiddenRect.height()/2 > availRect.height()/2) { //popup above forbiddenRect y = forbiddenRect.y()-m_popup->height(); } else { //popup below forbiddenRect y = forbiddenRect.y()+forbiddenRect.height(); } if(forbiddenRect.x()+forbiddenRect.width()/2 < availRect.width()/2) { //left edge of popup justified with left edge of popup x = forbiddenRect.x(); } else { //the other way round x = forbiddenRect.x()+forbiddenRect.width()-m_popup->width(); } m_popup->move(x, y); m_popup->setHidingTime(200); showPopup(DontMove); } } void KisColorSelectorBase::leaveEvent(QEvent *e) { Q_UNUSED(e); if (m_colorPreviewPopup->isVisible()) { m_colorUpdateSelf=false; //this is for allowing advanced selector to listen to outside colour-change events. m_colorPreviewPopup->hide(); } if (m_popup && m_popup->isVisible()) { m_popup->m_hideTimer->start(); } if (m_isPopup && !m_hideTimer->isActive()) { m_hideTimer->start(); } } void KisColorSelectorBase::keyPressEvent(QKeyEvent *) { if (m_isPopup) { hidePopup(); } } void KisColorSelectorBase::dragEnterEvent(QDragEnterEvent *e) { if(e->mimeData()->hasColor()) e->acceptProposedAction(); if(e->mimeData()->hasText() && QColor(e->mimeData()->text()).isValid()) e->acceptProposedAction(); } void KisColorSelectorBase::dropEvent(QDropEvent *e) { QColor color; if(e->mimeData()->hasColor()) { color = qvariant_cast(e->mimeData()->colorData()); } else if(e->mimeData()->hasText()) { color.setNamedColor(e->mimeData()->text()); if(!color.isValid()) return; } KoColor kocolor(color , KoColorSpaceRegistry::instance()->rgb8()); updateColor(kocolor, Acs::Foreground, true); } void KisColorSelectorBase::updateColor(const KoColor &color, Acs::ColorRole role, bool needsExplicitColorReset) { commitColor(color, role); if (needsExplicitColorReset) { setColor(color); } } void KisColorSelectorBase::requestUpdateColorAndPreview(const KoColor &color, Acs::ColorRole role) { m_updateColorCompressor->start(qMakePair(color, role)); } void KisColorSelectorBase::slotUpdateColorAndPreview(QPair color) { updateColorPreview(color.first); updateColor(color.first, color.second, false); } void KisColorSelectorBase::setColor(const KoColor& color) { Q_UNUSED(color); } void KisColorSelectorBase::setHidingTime(int time) { KIS_ASSERT_RECOVER_NOOP(m_isPopup); m_hideTimer->setInterval(time); } void KisColorSelectorBase::lazyCreatePopup() { if (!m_popup) { m_popup = createPopup(); Q_ASSERT(m_popup); m_popup->setWindowFlags(Qt::FramelessWindowHint|Qt::SubWindow|Qt::X11BypassWindowManagerHint); m_popup->m_parent = this; m_popup->m_isPopup=true; } m_popup->setCanvas(m_canvas); m_popup->updateSettings(); } void KisColorSelectorBase::showPopup(Move move) { // This slot may be called by some action, // so we need to be able to handle it lazyCreatePopup(); QPoint cursorPos = QCursor::pos(); if (move == MoveToMousePosition) { m_popup->move(cursorPos.x()-m_popup->width()/2, cursorPos.y()-m_popup->height()/2); QRect rc = m_popup->geometry(); if (rc.x() < 0) rc.setX(0); if (rc.y() < 0) rc.setY(0); m_popup->setGeometry(rc); } m_popup->show(); m_popup->m_colorPreviewPopup->show(); } void KisColorSelectorBase::hidePopup() { KIS_ASSERT_RECOVER_RETURN(m_isPopup); m_colorPreviewPopup->hide(); hide(); } void KisColorSelectorBase::commitColor(const KoColor& color, Acs::ColorRole role) { if (!m_canvas) return; m_colorUpdateAllowed=false; if (role == Acs::Foreground) m_canvas->resourceManager()->setForegroundColor(color); else m_canvas->resourceManager()->setBackgroundColor(color); m_colorUpdateAllowed=true; } void KisColorSelectorBase::showColorPreview() { if(m_colorPreviewPopup->isHidden()) { m_colorPreviewPopup->show(); } } void KisColorSelectorBase::updateColorPreview(const KoColor &color) { m_colorPreviewPopup->setQColor(converter()->toQColor(color)); } void KisColorSelectorBase::canvasResourceChanged(int key, const QVariant &v) { if (key == KoCanvasResourceManager::ForegroundColor || key == KoCanvasResourceManager::BackgroundColor) { KoColor realColor(v.value()); updateColorPreview(realColor); if (m_colorUpdateAllowed && !m_colorUpdateSelf) { setColor(realColor); } } } const KoColorSpace* KisColorSelectorBase::colorSpace() const { return converter()->paintingColorSpace(); } void KisColorSelectorBase::updateSettings() { if(m_popup) { m_popup->updateSettings(); } KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector"); int zoomSelectorOptions = (int) cfg.readEntry("zoomSelectorOptions", 0) ; if (zoomSelectorOptions == 0) { setPopupBehaviour(false, true); // middle mouse button click will open zoom selector } else if (zoomSelectorOptions == 1) { setPopupBehaviour(true, false); // move over will open the zoom selector } else { setPopupBehaviour(false, false); // do not show zoom selector } if(m_isPopup) { m_hideOnMouseClick = cfg.readEntry("hidePopupOnClickCheck", false); const int zoomSize = cfg.readEntry("zoomSize", 280); resize(zoomSize, zoomSize); } reset(); } void KisColorSelectorBase::reset() { update(); } void KisColorSelectorBase::updateBaseColorPreview(const KoColor &color) { m_colorPreviewPopup->setBaseColor(converter()->toQColor(color)); } void KisColorSelectorBase::updatePreviousColorPreview() { m_colorPreviewPopup->setPreviousColor(); } void KisColorSelectorBase::updateLastUsedColorPreview(const KoColor &color) { m_colorPreviewPopup->setLastUsedColor(converter()->toQColor(color)); } KisDisplayColorConverter* KisColorSelectorBase::converter() const { return m_canvas ? m_canvas->displayColorConverter() : KisDisplayColorConverter::dumbConverterInstance(); } void KisColorSelectorBase::mouseMoveEvent(QMouseEvent *event) { event->accept(); } diff --git a/plugins/dockers/advancedcolorselector/kis_color_selector_base.h b/plugins/dockers/advancedcolorselector/kis_color_selector_base.h index 3a70663ef8..ad4676b08c 100644 --- a/plugins/dockers/advancedcolorselector/kis_color_selector_base.h +++ b/plugins/dockers/advancedcolorselector/kis_color_selector_base.h @@ -1,129 +1,130 @@ /* * Copyright (c) 2010 Adam Celarek * * 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 */ #ifndef KIS_COLOR_SELECTOR_BASE_H #define KIS_COLOR_SELECTOR_BASE_H #include #include #include #include #include "kis_acs_types.h" #include "kis_signal_compressor_with_param.h" class KoColor; class QTimer; class KoColorSpace; class KisCanvas2; class KisColorPreviewPopup; class KisDisplayColorConverter; +class KoGamutMask; /// Base class for all color selectors, that should support color management and zooming. class KisColorSelectorBase : public QWidget { Q_OBJECT public: enum Move {MoveToMousePosition, DontMove}; explicit KisColorSelectorBase(QWidget *parent = 0); ~KisColorSelectorBase() override; void setPopupBehaviour(bool onMouseOver, bool onMouseClick); void setColorSpace(const KoColorSpace* colorSpace); virtual void setCanvas(KisCanvas2* canvas); virtual void unsetCanvas(); const KoColorSpace* colorSpace() const; KisDisplayColorConverter* converter() const; public: void updateColor(const KoColor &color, Acs::ColorRole role, bool needsExplicitColorReset); void updateColorPreview(const KoColor &color); void showColorPreview(); void updateBaseColorPreview(const KoColor &color); void updatePreviousColorPreview(); virtual void setColor(const KoColor& color); public Q_SLOTS: /** * Flushes caches and redraws the selectors */ virtual void reset(); virtual void updateSettings(); virtual void showPopup(Move move=MoveToMousePosition); public: void enterEvent(QEvent *e) override; void leaveEvent(QEvent *e) override; void mousePressEvent(QMouseEvent *) override; void mouseReleaseEvent(QMouseEvent *) override; protected: void keyPressEvent(QKeyEvent *) override; virtual KisColorSelectorBase* createPopup() const = 0; void dragEnterEvent(QDragEnterEvent *) override; void dropEvent(QDropEvent *) override; void setHidingTime(int time); bool isPopup() const { return m_isPopup; } void mouseMoveEvent(QMouseEvent *event) override; void requestUpdateColorAndPreview(const KoColor &color, Acs::ColorRole role); private: void commitColor(const KoColor& koColor, Acs::ColorRole role); protected Q_SLOTS: void hidePopup(); /// if you overwrite this, keep in mind, that you should set the colour only, if m_colorUpdateAllowed is true virtual void canvasResourceChanged(int key, const QVariant& v); void updateLastUsedColorPreview(const KoColor &color); public: // This is a private interface for signal compressor, don't use it. // Use requestUpdateColorAndPreview() instead void slotUpdateColorAndPreview(QPair color); private: void lazyCreatePopup(); protected: QPointer m_canvas; KisColorSelectorBase* m_popup; QWidget* m_parent; bool m_colorUpdateAllowed; bool m_colorUpdateSelf; private: QTimer* m_hideTimer; bool m_popupOnMouseOver; bool m_popupOnMouseClick; mutable const KoColorSpace* m_colorSpace; bool m_isPopup; //this instance is a popup bool m_hideOnMouseClick; KisColorPreviewPopup* m_colorPreviewPopup; typedef KisSignalCompressorWithParam> ColorCompressorType; QScopedPointer m_updateColorCompressor; }; #endif diff --git a/plugins/dockers/advancedcolorselector/kis_color_selector_component.cpp b/plugins/dockers/advancedcolorselector/kis_color_selector_component.cpp index 17d2aa7141..bdca98a0f0 100644 --- a/plugins/dockers/advancedcolorselector/kis_color_selector_component.cpp +++ b/plugins/dockers/advancedcolorselector/kis_color_selector_component.cpp @@ -1,210 +1,240 @@ /* * Copyright (c) 2010 Adam Celarek * * 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 */ #include "kis_color_selector_component.h" #include "kis_color_selector_base.h" #include "KoColorSpace.h" #include #include +#include KisColorSelectorComponent::KisColorSelectorComponent(KisColorSelector* parent) : QObject(parent), m_hue(0), m_hsvSaturation(1), m_value(1), m_hslSaturation(1), m_lightness(0.5), m_hsiSaturation(1), m_intensity(0.333), m_hsySaturation(1), m_luma(0.299), m_parent(parent), - m_width(0), - m_height(0), + m_gamutMaskOn(false), + m_currentGamutMask(nullptr), + m_maskPreviewActive(true), + m_lastX(0), + m_lastY(0), m_x(0), m_y(0), + m_width(0), + m_height(0), m_dirty(true), - m_lastColorSpace(0), - m_lastX(0), - m_lastY(0) + m_lastColorSpace(0) { Q_ASSERT(parent); } void KisColorSelectorComponent::setGeometry(int x, int y, int width, int height) { m_x=x; m_y=y; m_width=width; m_height=height; m_dirty=true; } void KisColorSelectorComponent::paintEvent(QPainter* painter) { painter->save(); painter->translate(m_x, m_y); paint(painter); painter->restore(); m_dirty=false; m_lastColorSpace=colorSpace(); } void KisColorSelectorComponent::mouseEvent(int x, int y) { int newX=qBound(0, (x-m_x), width()); int newY=qBound(0, (y-m_y), height()); selectColor(newX, newY); m_lastX=newX; m_lastY=newY; } const KoColorSpace* KisColorSelectorComponent::colorSpace() const { const KoColorSpace* cs = m_parent->colorSpace(); Q_ASSERT(cs); return cs; } void KisColorSelectorComponent::setDirty() { m_dirty = true; } +void KisColorSelectorComponent::setGamutMask(KoGamutMask *gamutMask) +{ + m_currentGamutMask = gamutMask; + m_gamutMaskOn = true; +} + +void KisColorSelectorComponent::unsetGamutMask() +{ + m_gamutMaskOn = false; + m_currentGamutMask = nullptr; +} + +void KisColorSelectorComponent::updateGamutMaskPreview() +{ + setDirty(); + update(); +} + +void KisColorSelectorComponent::toggleGamutMask(bool state) +{ + m_gamutMaskOn = state; + setDirty(); + update(); +} + + bool KisColorSelectorComponent::isDirty() const { return m_dirty || m_lastColorSpace!=colorSpace(); } bool KisColorSelectorComponent::containsPointInComponentCoords(int x, int y) const { if(x>=0 && y>=0 && x<=width() && y<=height()) return true; else return false; } KoColor KisColorSelectorComponent::currentColor() { return selectColor(m_lastX, m_lastY); } void KisColorSelectorComponent::setParam(qreal hue, qreal hsvSaturation, qreal value, qreal hslSaturation, qreal lightness, qreal hsiSaturation, qreal intensity, qreal hsySaturation, qreal luma) { if(qFuzzyCompare(m_hue, hue) && qFuzzyCompare(m_hsvSaturation, hsvSaturation) && qFuzzyCompare(m_value, value) && qFuzzyCompare(m_hslSaturation, hslSaturation) && qFuzzyCompare(m_lightness, lightness) && qFuzzyCompare(m_hsiSaturation, hsiSaturation) && qFuzzyCompare(m_intensity, intensity) && qFuzzyCompare(m_hsySaturation, hsySaturation) && qFuzzyCompare(m_luma, luma)) return; if(hue>=0. && hue<=1.) m_hue=hue; if(hsvSaturation>=0. && hsvSaturation<=1.) { m_hsvSaturation=hsvSaturation; m_hslSaturation=-1; m_hsiSaturation=-1; m_hsySaturation=-1; } if(value>=0. && value<=1.) { m_value=value; m_intensity=-1; m_luma=-1; m_lightness=-1; } if(hslSaturation>=0. && hslSaturation<=1.) { m_hslSaturation=hslSaturation; m_hsvSaturation=-1; m_hsiSaturation=-1; m_hsySaturation=-1; } if(lightness>=0. && lightness<=1.) { m_lightness=lightness; m_value=-1; m_luma=-1; m_intensity=-1; } if(hsiSaturation>=0. && hsiSaturation<=1.) { m_hsiSaturation=hsiSaturation; m_hsvSaturation=-1; m_hslSaturation=-1; m_hsySaturation=-1; } if(intensity>=0. && intensity<=1.) { m_intensity=intensity; m_value=-1; m_luma=-1; m_lightness=-1; } if(hsySaturation>=0. && hsySaturation<=1.) { m_hsySaturation=hsySaturation; m_hsvSaturation=-1; m_hsiSaturation=-1; m_hslSaturation=-1; } if(luma>=0. && luma<=1.) { m_intensity=-1; m_value=-1; m_luma=luma; m_lightness=-1; } m_dirty=true; emit update(); } int KisColorSelectorComponent::width() const { return m_width; } int KisColorSelectorComponent::height() const { return m_height; } void KisColorSelectorComponent::setConfiguration(Parameter param, Type type) { m_parameter = param; m_type = type; } void KisColorSelectorComponent::setLastMousePosition(int x, int y) { // prevent movement due to rounding errors if (abs((int)m_lastX - x) > 1 || abs((int)m_lastY - y) > 1) { m_lastX = x; m_lastY = y; } } diff --git a/plugins/dockers/advancedcolorselector/kis_color_selector_component.h b/plugins/dockers/advancedcolorselector/kis_color_selector_component.h index eaaeeda3c4..6e3c67a710 100644 --- a/plugins/dockers/advancedcolorselector/kis_color_selector_component.h +++ b/plugins/dockers/advancedcolorselector/kis_color_selector_component.h @@ -1,114 +1,125 @@ /* * Copyright (c) 2010 Adam Celarek * * 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 */ #ifndef KIS_COLOR_SELECTOR_COMPONENT_H #define KIS_COLOR_SELECTOR_COMPONENT_H #include #include + +#include + #include "kis_color_selector.h" class KoColorSpace; class QPainter; class KisColorSelectorComponent : public QObject { Q_OBJECT public: typedef KisColorSelectorConfiguration::Parameters Parameter; typedef KisColorSelectorConfiguration::Type Type; explicit KisColorSelectorComponent(KisColorSelector* parent); void setGeometry(int x, int y, int width, int height); void paintEvent(QPainter*); /// saves the mouse position, so that a blip can be created. - void mouseEvent(int x, int y); + virtual void mouseEvent(int x, int y); /// return the color, that was selected by calling mouseEvent KoColor currentColor(); int width() const; int height() const; /// setConfiguration can be ignored (for instance ring and triangle, as they can have only one config) void setConfiguration(Parameter param, Type type); /// set the color, blibs etc virtual void setColor(const KoColor& color) = 0; /// force subsequent redraw of the component void setDirty(); /// returns true, if this component wants to grab the mouse (normally true, if containsPoint returns true) bool wantsGrab(int x, int y) {return containsPointInComponentCoords(x-m_x, y-m_y);} + void setGamutMask(KoGamutMask* gamutMask); + void unsetGamutMask(); + void updateGamutMaskPreview(); + void toggleGamutMask(bool state); + public Q_SLOTS: /// set hue, saturation, value or/and lightness /// unused parameters should be set to -1 void setParam(qreal hue, qreal hsvSaturation, qreal value, qreal hslSaturation, qreal lightness, qreal hsiSaturation, qreal intensity, qreal hsySaturation, qreal luma); Q_SIGNALS: /// request for repaint, for instance, if the hue changes. void update(); /// -1, if unaffected void paramChanged(qreal hue, qreal hsvSaturation, qreal value, qreal hslSaturation, qreal lightness, qreal hsiSaturation, qreal intensity, qreal hsySaturation, qreal luma); protected: const KoColorSpace* colorSpace() const; /// returns true, if ether the colour space, the size or the parameters have changed since the last paint event bool isDirty() const; /// this method must be overloaded to return the colour at position x/y and draw a marker on that position virtual KoColor selectColor(int x, int y) = 0; /// paint component using given painter /// the component should respect width() and height() (eg. scale to width and height), but doesn't /// have to care about x/y coordinates (top left corner) virtual void paint(QPainter*) = 0; /// a subclass can implement this method, the default returns true if the coordinates are in the component rect /// values for the subclasses are provided in component coordinates, eg (0,0) is top left of component virtual bool containsPointInComponentCoords(int x, int y) const; // Workaround for Bug 287001 void setLastMousePosition(int x, int y); qreal m_hue; qreal m_hsvSaturation; qreal m_value; qreal m_hslSaturation; qreal m_lightness; qreal m_hsiSaturation; qreal m_intensity; qreal m_hsySaturation; qreal m_luma; Parameter m_parameter; Type m_type; KisColorSelector* m_parent; + bool m_gamutMaskOn; + KoGamutMask* m_currentGamutMask; + bool m_maskPreviewActive; + qreal m_lastX; + qreal m_lastY; + int m_x; + int m_y; private: int m_width; int m_height; - int m_x; - int m_y; bool m_dirty; const KoColorSpace* m_lastColorSpace; - qreal m_lastX; - qreal m_lastY; }; #endif // KIS_COLOR_SELECTOR_COMPONENT_H diff --git a/plugins/dockers/advancedcolorselector/kis_color_selector_container.cpp b/plugins/dockers/advancedcolorselector/kis_color_selector_container.cpp index 0c31aac403..6a4fc834d7 100644 --- a/plugins/dockers/advancedcolorselector/kis_color_selector_container.cpp +++ b/plugins/dockers/advancedcolorselector/kis_color_selector_container.cpp @@ -1,216 +1,244 @@ /* * Copyright (c) 2010 Adam Celarek * * 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 */ #include "kis_color_selector_container.h" #include "kis_color_selector.h" #include "kis_my_paint_shade_selector.h" #include "kis_minimal_shade_selector.h" #include #include #include #include #include #include #include #include #include +#include #include "KisViewManager.h" #include "kis_canvas2.h" #include "kis_canvas_resource_provider.h" #include "kis_node_manager.h" #include "kis_node.h" #include "kis_paint_device.h" #include "kis_action_registry.h" KisColorSelectorContainer::KisColorSelectorContainer(QWidget *parent) : QWidget(parent), m_colorSelector(new KisColorSelector(this)), m_myPaintShadeSelector(new KisMyPaintShadeSelector(this)), m_minimalShadeSelector(new KisMinimalShadeSelector(this)), m_shadeSelector(m_myPaintShadeSelector), + m_gamutMaskToolbar(new KisGamutMaskToolbar(this)), m_canvas(0) { m_widgetLayout = new QBoxLayout(QBoxLayout::TopToBottom, this); m_widgetLayout->setSpacing(0); m_widgetLayout->setMargin(0); + m_gamutMaskToolbar->setContentsMargins(0, 0, 0, 5); + m_gamutMaskToolbar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + m_colorSelector->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_myPaintShadeSelector->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_minimalShadeSelector->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + m_widgetLayout->addWidget(m_gamutMaskToolbar); m_widgetLayout->addWidget(m_colorSelector); m_widgetLayout->addWidget(m_myPaintShadeSelector); m_widgetLayout->addWidget(m_minimalShadeSelector); + m_gamutMaskToolbar->hide(); m_myPaintShadeSelector->hide(); m_minimalShadeSelector->hide(); connect(m_colorSelector,SIGNAL(settingsButtonClicked()), SIGNAL(openSettings())); connect(this, SIGNAL(settingsChanged()), m_colorSelector, SLOT(updateSettings())); connect(this, SIGNAL(settingsChanged()), m_myPaintShadeSelector, SLOT(updateSettings())); connect(this, SIGNAL(settingsChanged()), this, SLOT(updateSettings())); connect(this, SIGNAL(settingsChanged()), m_minimalShadeSelector, SLOT(updateSettings())); m_colorSelAction = KisActionRegistry::instance()->makeQAction("show_color_selector", this); connect(m_colorSelAction, SIGNAL(triggered()), m_colorSelector, SLOT(showPopup()), Qt::UniqueConnection); m_mypaintAction = KisActionRegistry::instance()->makeQAction("show_mypaint_shade_selector", this); connect(m_mypaintAction, SIGNAL(triggered()), m_myPaintShadeSelector, SLOT(showPopup()), Qt::UniqueConnection); m_minimalAction = KisActionRegistry::instance()->makeQAction("show_minimal_shade_selector", this); connect(m_minimalAction, SIGNAL(triggered()), m_minimalShadeSelector, SLOT(showPopup()), Qt::UniqueConnection); - - } void KisColorSelectorContainer::unsetCanvas() { m_colorSelector->hasAtLeastOneDocument(doesAtleastOneDocumentExist()); m_colorSelector->unsetCanvas(); m_myPaintShadeSelector->unsetCanvas(); m_minimalShadeSelector->unsetCanvas(); m_canvas = 0; } bool KisColorSelectorContainer::doesAtleastOneDocumentExist() { if (m_canvas && m_canvas->viewManager() && m_canvas->viewManager()->document() ) { if (m_canvas->viewManager()->document()->image()->height() == 0) { return false; } else { return true; } } else { return false; } } void KisColorSelectorContainer::slotUpdateIcons() { m_colorSelector->updateIcons(); } void KisColorSelectorContainer::setCanvas(KisCanvas2* canvas) { if (m_canvas) { m_canvas->disconnectCanvasObserver(this); m_canvas->viewManager()->nodeManager()->disconnect(this); KActionCollection *ac = m_canvas->viewManager()->actionCollection(); ac->takeAction(ac->action("show_color_selector")); ac->takeAction(ac->action("show_mypaint_shade_selector")); ac->takeAction(ac->action("show_minimal_shade_selector")); } m_canvas = canvas; m_colorSelector->setCanvas(canvas); m_myPaintShadeSelector->setCanvas(canvas); m_minimalShadeSelector->setCanvas(canvas); m_colorSelector->hasAtLeastOneDocument(doesAtleastOneDocumentExist()); if (m_canvas && m_canvas->viewManager()) { if (m_canvas->viewManager()->nodeManager()) { connect(m_canvas->viewManager()->nodeManager(), SIGNAL(sigLayerActivated(KisLayerSP)), SLOT(reactOnLayerChange()), Qt::UniqueConnection); } + connect(m_canvas->viewManager()->resourceProvider(), SIGNAL(sigGamutMaskChanged(KoGamutMask*)), + m_colorSelector, SLOT(slotGamutMaskSet(KoGamutMask*))); + + connect(m_canvas->viewManager()->resourceProvider(), SIGNAL(sigGamutMaskUnset()), + m_colorSelector, SLOT(slotGamutMaskUnset())); + + connect(m_canvas->viewManager()->resourceProvider(), SIGNAL(sigGamutMaskPreviewUpdate()), + m_colorSelector, SLOT(slotGamutMaskPreviewUpdate())); + + m_gamutMaskToolbar->connectMaskSignals(m_canvas->viewManager()->resourceProvider()); + + // gamut mask connections + connect(m_gamutMaskToolbar, SIGNAL(sigGamutMaskToggle(bool)), m_colorSelector, SLOT(slotGamutMaskToggle(bool))); + KActionCollection* actionCollection = canvas->viewManager()->actionCollection(); actionCollection->addAction("show_color_selector", m_colorSelAction); actionCollection->addAction("show_mypaint_shade_selector", m_mypaintAction); actionCollection->addAction("show_minimal_shade_selector", m_minimalAction); } - } void KisColorSelectorContainer::updateSettings() { KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector"); m_onDockerResizeSetting = (int)cfg.readEntry("onDockerResize", 0); QString type = cfg.readEntry("shadeSelectorType", "Minimal"); QWidget* newShadeSelector; if(type=="MyPaint") newShadeSelector = m_myPaintShadeSelector; else if (type=="Minimal") newShadeSelector = m_minimalShadeSelector; else newShadeSelector = 0; if(m_shadeSelector!=newShadeSelector && m_shadeSelector!=0) { m_shadeSelector->hide(); } m_shadeSelector=newShadeSelector; if(m_shadeSelector!=0) m_shadeSelector->show(); + + if (m_colorSelector->configuration().mainType == KisColorSelectorConfiguration::Wheel) { + m_gamutMaskToolbar->show(); + } else { + m_gamutMaskToolbar->hide(); + } + } void KisColorSelectorContainer::reactOnLayerChange() { if (m_canvas) { KisNodeSP node = m_canvas->viewManager()->resourceProvider()->currentNode(); if (node) { KisPaintDeviceSP device = node->paintDevice(); if (device) { m_colorSelAction->setEnabled(true); m_mypaintAction->setEnabled(true); m_minimalAction->setEnabled(true); } else { // m_colorSelAction->setEnabled(false); // m_mypaintAction->setEnabled(false); // m_minimalAction->setEnabled(false); } } } } void KisColorSelectorContainer::resizeEvent(QResizeEvent * e) { if(m_shadeSelector!=0) { int minimumHeightForBothWidgets = m_colorSelector->minimumHeight()+m_shadeSelector->minimumHeight()+30; //+30 for the buttons (temporarily) if(height()hide(); } else { m_shadeSelector->show(); } // m_onDockerResizeSetting==0 is allow horizontal layout if(height() < width() && m_onDockerResizeSetting==0 && m_shadeSelector!=m_minimalShadeSelector) { m_widgetLayout->setDirection(QBoxLayout::LeftToRight); } else { m_widgetLayout->setDirection(QBoxLayout::TopToBottom); } } QWidget::resizeEvent(e); } diff --git a/plugins/dockers/advancedcolorselector/kis_color_selector_container.h b/plugins/dockers/advancedcolorselector/kis_color_selector_container.h index 985e4ae412..fc98414e32 100644 --- a/plugins/dockers/advancedcolorselector/kis_color_selector_container.h +++ b/plugins/dockers/advancedcolorselector/kis_color_selector_container.h @@ -1,73 +1,75 @@ /* * Copyright (c) 2010 Adam Celarek * * 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 */ #ifndef KIS_COLOR_SELECTOR_CONTAINER_H #define KIS_COLOR_SELECTOR_CONTAINER_H #include #include #include class KisColorSelector; class KisMyPaintShadeSelector; class KisMinimalShadeSelector; class QBoxLayout; class QAction; +class KisGamutMaskToolbar; class KisColorSelectorContainer : public QWidget { Q_OBJECT public: explicit KisColorSelectorContainer(QWidget *parent = 0); void setCanvas(KisCanvas2* canvas); void unsetCanvas(); bool doesAtleastOneDocumentExist(); enum ShadeSelectorType{MyPaintSelector, MinimalSelector, NoSelector}; public Q_SLOTS: void slotUpdateIcons(); Q_SIGNALS: void openSettings(); void settingsChanged(); protected Q_SLOTS: void updateSettings(); void reactOnLayerChange(); protected: void resizeEvent(QResizeEvent *) override; private: KisColorSelector* m_colorSelector; KisMyPaintShadeSelector* m_myPaintShadeSelector; KisMinimalShadeSelector* m_minimalShadeSelector; QWidget* m_shadeSelector; + KisGamutMaskToolbar* m_gamutMaskToolbar; int m_onDockerResizeSetting; QBoxLayout* m_widgetLayout; QAction * m_colorSelAction; QAction * m_mypaintAction; QAction * m_minimalAction; QPointer m_canvas; }; #endif // KIS_COLOR_SELECTOR_CONTAINER_H diff --git a/plugins/dockers/advancedcolorselector/kis_color_selector_wheel.cpp b/plugins/dockers/advancedcolorselector/kis_color_selector_wheel.cpp index c9d3d4f43f..1cc38c6fc8 100644 --- a/plugins/dockers/advancedcolorselector/kis_color_selector_wheel.cpp +++ b/plugins/dockers/advancedcolorselector/kis_color_selector_wheel.cpp @@ -1,269 +1,341 @@ /* * Copyright (c) 2010 Adam Celarek * * 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 */ #include "kis_color_selector_wheel.h" #include #include #include #include #include #include #include +#include + #include "kis_display_color_converter.h" #include "kis_acs_pixel_cache_renderer.h" KisColorSelectorWheel::KisColorSelectorWheel(KisColorSelector *parent) : KisColorSelectorComponent(parent), - m_lastClickPos(-1,-1) + m_lastClickPos(-1,-1), + m_renderAreaSize(1,1), + m_renderAreaOffsetX(0.0), + m_renderAreaOffsetY(0.0), + m_toRenderArea(QTransform()) { + m_viewConverter = new KisGamutMaskViewConverter(); } KoColor KisColorSelectorWheel::selectColor(int x, int y) { int xWheel = x-width()/2; int yWheel = y-height()/2; qreal radius = sqrt((double)xWheel*xWheel+yWheel*yWheel); radius/=qMin(width(), height()); if(radius>0.5) radius=0.5; radius*=2.; qreal angle = std::atan2((qreal)yWheel, (qreal)xWheel); angle+=M_PI; angle/=2*M_PI; switch (m_parameter) { case KisColorSelectorConfiguration::hsvSH: emit paramChanged(angle, radius, -1, -1, -1, -1, -1, -1, -1); break; case KisColorSelectorConfiguration::hslSH: emit paramChanged(angle, -1, -1, radius, -1, -1, -1, -1, -1); break; case KisColorSelectorConfiguration::hsiSH: emit paramChanged(angle, -1, -1, -1, -1, radius, -1, -1, -1); break; case KisColorSelectorConfiguration::hsySH: emit paramChanged(angle, -1, -1, -1, -1, -1, -1, radius, -1); break; case KisColorSelectorConfiguration::VH: emit paramChanged(angle, -1, radius, -1, -1, -1, -1, -1, -1); break; case KisColorSelectorConfiguration::LH: emit paramChanged(angle, -1, -1, -1, radius, -1, -1, -1, -1); break; case KisColorSelectorConfiguration::IH: emit paramChanged(angle, -1, -1, -1, -1, -1, radius, -1, -1); break; case KisColorSelectorConfiguration::YH: emit paramChanged(angle, -1, -1, -1, -1, -1, -1, -1, radius); break; default: Q_ASSERT(false); break; } emit update(); angle *= 2. * M_PI; angle -= M_PI; radius*=0.5; m_lastClickPos.setX(cos(angle)*radius+0.5); m_lastClickPos.setY(sin(angle)*radius+0.5); return colorAt(x, y, true); } void KisColorSelectorWheel::setColor(const KoColor &color) { qreal hsvH, hsvS, hsvV; qreal hslH, hslS, hslL; qreal hsiH, hsiS, hsiI; qreal hsyH, hsyS, hsyY; KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector"); R = cfg.readEntry("lumaR", 0.2126); G = cfg.readEntry("lumaG", 0.7152); B = cfg.readEntry("lumaB", 0.0722); Gamma = cfg.readEntry("gamma", 2.2); m_parent->converter()->getHsvF(color, &hsvH, &hsvS, &hsvV); m_parent->converter()->getHslF(color, &hslH, &hslS, &hslL); m_parent->converter()->getHsiF(color, &hsiH, &hsiS, &hsiI); m_parent->converter()->getHsyF(color, &hsyH, &hsyS, &hsyY, R, G, B, Gamma); //workaround, for some reason the HSI and HSY algorithms are fine, but they don't seem to update the selectors properly. hsiH=hslH; hsyH=hslH; qreal angle = 0.0, radius = 0.0; angle = hsvH; angle *= 2. * M_PI; angle -= M_PI; switch (m_parameter) { case KisColorSelectorConfiguration::LH: emit paramChanged(hslH, -1, -1, -1, hslL, -1, -1, -1, -1); radius = hslL; break; case KisColorSelectorConfiguration::VH: emit paramChanged(hsvH, -1, hsvV, -1, -1, -1, -1, -1, -1); radius = hsvV; break; case KisColorSelectorConfiguration::IH: emit paramChanged(hslH, -1, -1, -1, -1, -1, hsiI, -1, -1); radius = hsiI; break; case KisColorSelectorConfiguration::YH: emit paramChanged(hsvH, -1, -1, -1, -1, -1, -1, -1, hsyY); radius = hsyY; break; case KisColorSelectorConfiguration::hsvSH: emit paramChanged(hsvH, hsvS, -1, -1, -1, -1, -1, -1, -1); radius = hsvS; break; case KisColorSelectorConfiguration::hslSH: emit paramChanged(hslH, -1, -1, hslS, -1, -1, -1, -1, -1); radius = hslS; break; case KisColorSelectorConfiguration::hsiSH: emit paramChanged(hsiH, -1, -1, -1, -1, hsiS, -1, -1, -1); radius = hsiS; break; case KisColorSelectorConfiguration::hsySH: emit paramChanged(hsyH, -1, -1, -1, -1, -1, -1, hsyS, -1); radius = hsyS; break; default: Q_ASSERT(false); break; } radius *= 0.5; m_lastClickPos.setX(cos(angle)*radius+0.5); m_lastClickPos.setY(sin(angle)*radius+0.5); //workaround for bug 279500 if(m_lastClickPos!=QPoint(-1,-1) && m_parent->displayBlip()) { QPoint pos = (m_lastClickPos*qMin(width(), height())).toPoint(); if(width() < height()) { pos.setY(pos.y()+height()/2-width()/2); } else { pos.setX(pos.x()+width()/2-height()/2); } setLastMousePosition(pos.x(), pos.y()); } } void KisColorSelectorWheel::paint(QPainter* painter) { if(isDirty()) { KisPaintDeviceSP realPixelCache; Acs::PixelCacheRenderer::render(this, m_parent->converter(), QRect(0, 0, width(), height()), realPixelCache, m_pixelCache, m_pixelCacheOffset); //antialiasing for wheel QPainter tmpPainter(&m_pixelCache); tmpPainter.setRenderHint(QPainter::Antialiasing); tmpPainter.setPen(QPen(QColor(0,0,0,0), 2.5)); tmpPainter.setCompositionMode(QPainter::CompositionMode_Clear); int size=qMin(width(), height()); + m_renderAreaSize = QSize(size,size); + m_renderAreaOffsetX = ((qreal)width()-(qreal)m_renderAreaSize.width())*0.5; + m_renderAreaOffsetY = ((qreal)height()-(qreal)m_renderAreaSize.height())*0.5; + m_toRenderArea.reset(); + m_toRenderArea.translate(-m_renderAreaOffsetX,-m_renderAreaOffsetY); + + m_viewConverter->setViewSize(m_renderAreaSize); + if (m_currentGamutMask) { + m_viewConverter->setMaskSize(m_currentGamutMask->maskSize()); + } + QPoint ellipseCenter(width() / 2 - size / 2, height() / 2 - size / 2); ellipseCenter -= m_pixelCacheOffset; tmpPainter.drawEllipse(ellipseCenter.x(), ellipseCenter.y(), size, size); } painter->drawImage(m_pixelCacheOffset.x(),m_pixelCacheOffset.y(), m_pixelCache); + // draw gamut mask + if (m_gamutMaskOn && m_currentGamutMask) { + QImage maskBuffer = QImage(m_renderAreaSize.width(), m_renderAreaSize.height(), QImage::Format_ARGB32_Premultiplied); + maskBuffer.fill(0); + QPainter maskPainter(&maskBuffer); + + QRect rect = QRect(0, 0, m_renderAreaSize.width(), m_renderAreaSize.height()); + maskPainter.setRenderHint(QPainter::Antialiasing, true); + + maskPainter.resetTransform(); + maskPainter.translate(rect.width()/2, rect.height()/2); + maskPainter.scale(rect.width()/2, rect.height()/2); + + maskPainter.setPen(QPen(QBrush(Qt::white), 0.002)); + maskPainter.setBrush(QColor(128,128,128,255)); // middle gray + + maskPainter.drawEllipse(QPointF(0,0), 1.0, 1.0); + + maskPainter.resetTransform(); + + maskPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); + m_currentGamutMask->paint(maskPainter, *m_viewConverter, m_maskPreviewActive); + + maskPainter.setCompositionMode(QPainter::CompositionMode_SourceOver); + m_currentGamutMask->paintStroke(maskPainter, *m_viewConverter, m_maskPreviewActive); + + painter->drawImage(m_renderAreaOffsetX, m_renderAreaOffsetY, maskBuffer); + } + // draw blips if(m_lastClickPos!=QPoint(-1,-1) && m_parent->displayBlip()) { QPoint pos = (m_lastClickPos*qMin(width(), height())).toPoint(); if(width()setPen(QColor(0,0,0)); painter->drawEllipse(pos, 5, 5); painter->setPen(QColor(255,255,255)); painter->drawEllipse(pos, 4, 4); } } +void KisColorSelectorWheel::mouseEvent(int x, int y) +{ + int newX=qBound(0, (x-m_x), width()); + int newY=qBound(0, (y-m_y), height()); + + if (coordIsClear(newX,newY)) { + selectColor(newX, newY); + m_lastX=newX; + m_lastY=newY; + } +} + KoColor KisColorSelectorWheel::colorAt(int x, int y, bool forceValid) { KoColor color(Qt::transparent, m_parent->colorSpace()); Q_ASSERT(x>=0 && x<=width()); Q_ASSERT(y>=0 && y<=height()); const qreal xRel = x - 0.5 * width(); const qreal yRel = y - 0.5 * height(); const qreal minDimension = qMin(width(), height()); qreal radius = sqrt(xRel*xRel+yRel*yRel); if (radius > 0.5 * minDimension) { if (!forceValid) { return color; } else { radius = 0.5 * minDimension; } } radius /= 0.5 * minDimension; qreal angle = std::atan2(yRel, xRel); angle += M_PI; angle /= 2 * M_PI; switch(m_parameter) { case KisColorSelectorConfiguration::hsvSH: color = m_parent->converter()->fromHsvF(angle, radius, m_value); break; case KisColorSelectorConfiguration::hslSH: color = m_parent->converter()->fromHslF(angle, radius, m_lightness); break; case KisColorSelectorConfiguration::hsiSH: color = m_parent->converter()->fromHsiF(angle, radius, m_intensity); break; case KisColorSelectorConfiguration::hsySH: color = m_parent->converter()->fromHsyF(angle, radius, m_luma, R, G, B, Gamma); break; case KisColorSelectorConfiguration::VH: color = m_parent->converter()->fromHsvF(angle, m_hsvSaturation, radius); break; case KisColorSelectorConfiguration::LH: color = m_parent->converter()->fromHslF(angle, m_hslSaturation, radius); break; case KisColorSelectorConfiguration::IH: color = m_parent->converter()->fromHsiF(angle, m_hsiSaturation, radius); break; case KisColorSelectorConfiguration::YH: color = m_parent->converter()->fromHsyF(angle, m_hsySaturation, radius, R, G, B, Gamma); break; default: Q_ASSERT(false); return color; } return color; } + +bool KisColorSelectorWheel::coordIsClear(int x, int y) +{ + bool retval = false; + if (m_gamutMaskOn && m_currentGamutMask) { + bool isClear = m_currentGamutMask->coordIsClear(m_toRenderArea.map(QPointF(x,y)), *m_viewConverter, m_maskPreviewActive); + retval = (isClear) ? true : false; + } else { + retval = true; + } + + return retval; +} diff --git a/plugins/dockers/advancedcolorselector/kis_color_selector_wheel.h b/plugins/dockers/advancedcolorselector/kis_color_selector_wheel.h index 9eff86aa09..b5bff11de7 100644 --- a/plugins/dockers/advancedcolorselector/kis_color_selector_wheel.h +++ b/plugins/dockers/advancedcolorselector/kis_color_selector_wheel.h @@ -1,58 +1,69 @@ /* * Copyright (c) 2010 Adam Celarek * * 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 */ #ifndef KIS_COLOR_SELECTOR_WHEEL_H #define KIS_COLOR_SELECTOR_WHEEL_H typedef unsigned int QRgb; #include #include +#include + +#include #include "KoColor.h" #include "kis_color_selector_component.h" namespace Acs { class PixelCacheRenderer; } class KisColorSelectorWheel : public KisColorSelectorComponent { Q_OBJECT public: explicit KisColorSelectorWheel(KisColorSelector *parent); void setColor(const KoColor &color) override; protected: KoColor selectColor(int x, int y) override; void paint(QPainter*) override; + void mouseEvent(int x, int y) override; private: friend class Acs::PixelCacheRenderer; KoColor colorAt(int x, int y, bool forceValid = false); private: + bool coordIsClear(int x, int y); QPointF m_lastClickPos; QImage m_pixelCache; QPoint m_pixelCacheOffset; qreal R; qreal G; qreal B; qreal Gamma; + + QSize m_renderAreaSize; + qreal m_renderAreaOffsetX; + qreal m_renderAreaOffsetY; + QTransform m_toRenderArea; + KisGamutMaskViewConverter* m_viewConverter; }; #endif // KIS_COLOR_SELECTOR_WHEEL_H diff --git a/plugins/dockers/advancedcolorselector/wdg_color_selector_settings.ui b/plugins/dockers/advancedcolorselector/wdg_color_selector_settings.ui index 2eff486a4d..2397ed6b47 100644 --- a/plugins/dockers/advancedcolorselector/wdg_color_selector_settings.ui +++ b/plugins/dockers/advancedcolorselector/wdg_color_selector_settings.ui @@ -1,1557 +1,1557 @@ KisColorSelectorSettings 0 0 - 612 - 973 + 721 + 1108 0 0 Color Selector Settings Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 6 20 Docker: 0 0 0 30 0 0 0 280 0 Color Selector 0 0 Qt::Vertical QSizePolicy::MinimumExpanding 20 5 6 12 6 6 0 0 Qt::LeftToRight Color &Model Type: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter colorSelectorConfiguration 0 0 0 0 Type Description goes here Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 0 Luma Coefficients 0 0 6 0 0 Red': Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 50 0 4 0 0 Green': 0 0 Blue': 0 0 50 0 4 0 0 50 0 4 <html><head/><body><p>This sets the gamma value that the linearised HSY Luminosity is crunched with. 1 makes the selector fully linear, 2.2 is a practical default value.</p></body></html> 1 -3.000000000000000 3.000000000000000 0.100000000000000 2.200000000000000 Gamma: 0 0 Color Selector Uses Different Color Space than Ima&ge true false 0 0 Qt::Vertical QSizePolicy::MinimumExpanding 20 5 Behavior 0 0 Qt::LeftToRight When Docker Resizes: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Show Zoom Selector UI: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Zoom Selector Size: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 px 100 1000 10 260 true 0 0 Hide Popup on click. Qt::Vertical QSizePolicy::MinimumExpanding 20 - 228 + 40 Shade Selector Type: Color model: Qt::Horizontal 20 20 0 0 0 Update Selector When: Right clicking on shade selector Left clicking on shade selector this doesn't include a color change by the shade selector Foreground color changes false this doesn't include a color change by the shade selector Background color change true 0 0 Minimal Shade Selector 0 0 Display: &Gradient Colo&r Patches 0 0 Qt::Horizontal 59 20 Line Count: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 10 3 Line Height: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter px 8 99 16 Patches Per Line: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Vertical QSizePolicy::MinimumExpanding 20 10 true 0 0 Color History 0 0 Show Color Histor&y true Patch Options Height: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter px 16 Width: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter px 16 Max Patches: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 30 Qt::Horizontal 40 20 Layout 0 &Vertical true Colu&mns: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter lastUsedColorsNumCols 1 20 2 Hori&zontal &Rows: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter lastUsedColorsNumRows 1 20 3 Allow scrolling true Qt::Vertical QSizePolicy::MinimumExpanding 20 5 Colors from Image true Show Colors from the ima&ge true Patch Options Height: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter px 16 Width: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter px 16 Max Patches: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 30 Qt::Horizontal 40 20 Layout 6 0 &Vertical Colu&mns: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter commonColorsNumCols 1 20 2 Hori&zontal true &Rows: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter commonColorsNumRows 1 20 3 this can be slow on big images Update after every stroke Allow scrolling Qt::Vertical QSizePolicy::MinimumExpanding 20 10 HSV Sliders to Show Hue Saturation Value HSL Sliders to Show Hue Saturation Lightness HSI Sliders to Show Hue Saturation Intensity HSY' Sliders to Show Hue Saturation Luma Lightness, Saturation and Hue hotkey steps Lightness: steps Qt::Horizontal 40 20 Saturation: steps Qt::Horizontal 40 20 Hue: steps YUV Redder/Greener/Bluer/Yellower hotkey steps Redder/Greener: steps Qt::Horizontal 40 20 Bluer/Yellower: steps Qt::Vertical 20 10 + + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
KisColorSpaceSelector QWidget
widgets/kis_color_space_selector.h
1
KisIntParseSpinBox QSpinBox
kis_int_parse_spin_box.h
KisColorSelectorComboBox QComboBox
kis_color_selector_combo_box.h
KisShadeSelectorLinesSettings QComboBox
kis_shade_selector_lines_settings.h
- - KisDoubleParseSpinBox - QDoubleSpinBox -
kis_double_parse_spin_box.h
-
minimalShadeSelectorAsColorPatches toggled(bool) minimalShadeSelectorPatchesPerLine setEnabled(bool) 194 393 520 463
diff --git a/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.cpp b/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.cpp index de889fc2b4..981795c164 100644 --- a/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.cpp +++ b/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.cpp @@ -1,512 +1,459 @@ /* * Copyright (c) 2009 Cyrille Berger * * 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 #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 "artisticcolorselector_dock.h" #include #include +#include +#include #include "ui_wdgArtisticColorSelector.h" #include "ui_wdgARCSSettings.h" #include "ui_wdgWheelPreferencesPopup.h" class KisMainWindow; struct ArtisticColorSelectorUI: public QWidget, public Ui_wdgArtisticColorSelector { ArtisticColorSelectorUI() { setupUi(this); } }; struct ARCSSettingsUI: public QWidget, public Ui_wdgARCSSettings { ARCSSettingsUI() { setupUi(this); } }; struct WheelPreferencesPopupUI: public QWidget, public Ui_wdgWheelPreferencesPopup { WheelPreferencesPopupUI() { setupUi(this); } }; ArtisticColorSelectorDock::ArtisticColorSelectorDock() : QDockWidget(i18n("Artistic Color Selector")) , m_canvas(nullptr) , m_resourceProvider(0) , m_selectedMask(nullptr) { setEnabled(false); m_hsxButtons = new QButtonGroup(); m_preferencesUI = new ARCSSettingsUI(); m_wheelPrefsUI = new WheelPreferencesPopupUI(); m_selectorUI = new ArtisticColorSelectorUI(); QPixmap hueStepsPixmap = KisIconUtils::loadIcon("wheel-sectors").pixmap(16,16); QPixmap saturationStepsPixmap = KisIconUtils::loadIcon("wheel-rings").pixmap(16,16); 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); m_selectorUI->bnDockerPrefs->setPopupWidget(m_preferencesUI); m_selectorUI->bnDockerPrefs->setIcon(KisIconUtils::loadIcon("configure")); - m_selectorUI->bnToggleMask->setChecked(false); - m_selectorUI->bnToggleMask->setIcon(m_iconMaskOff); - //preferences m_hsxButtons->addButton(m_preferencesUI->bnHsy, KisColor::HSY); m_hsxButtons->addButton(m_preferencesUI->bnHsi, KisColor::HSI); m_hsxButtons->addButton(m_preferencesUI->bnHsl, KisColor::HSL); m_hsxButtons->addButton(m_preferencesUI->bnHsv, KisColor::HSV); m_wheelPrefsUI->bnInverseSat->setChecked(m_selectorUI->colorSelector->isSaturationInverted()); m_wheelPrefsUI->labelHueSteps->setPixmap(hueStepsPixmap); m_wheelPrefsUI->labelSaturationSteps->setPixmap(saturationStepsPixmap); m_wheelPrefsUI->labelValueScaleSteps->setPixmap(valueScaleStepsPixmap); m_wheelPrefsUI->numHueSteps->setRange(MIN_NUM_UI_HUE_PIECES, MAX_NUM_HUE_PIECES); m_wheelPrefsUI->numSaturationSteps->setRange(MIN_NUM_SATURATION_RINGS, MAX_NUM_SATURATION_RINGS); m_wheelPrefsUI->numValueScaleSteps->setRange(MIN_NUM_UI_LIGHT_PIECES, MAX_NUM_LIGHT_PIECES); m_wheelPrefsUI->bnInfHueSteps->setIcon(infinityIcon); m_wheelPrefsUI->bnInfValueScaleSteps->setIcon(infinityIcon); m_wheelPrefsUI->bnInfHueSteps->setToolTip(i18n("Continuous Mode")); m_wheelPrefsUI->bnInfValueScaleSteps->setToolTip(i18n("Continuous Mode")); int selectorHueSteps = m_selectorUI->colorSelector->getNumPieces(); if (selectorHueSteps == 1) { m_wheelPrefsUI->bnInfHueSteps->setChecked(true); } else { m_wheelPrefsUI->bnInfHueSteps->setChecked(false); } m_wheelPrefsUI->numHueSteps->setValue(selectorHueSteps); m_wheelPrefsUI->numSaturationSteps->setValue(m_selectorUI->colorSelector->getNumRings()); int selectorValueScaleSteps = m_selectorUI->colorSelector->getNumLightPieces(); if (selectorValueScaleSteps == 1) { m_wheelPrefsUI->bnInfValueScaleSteps->setChecked(true); } else { m_wheelPrefsUI->bnInfValueScaleSteps->setChecked(false); } m_wheelPrefsUI->numValueScaleSteps->setValue(m_selectorUI->colorSelector->getNumLightPieces()); m_preferencesUI->bnDefInfHueSteps->setIcon(infinityIcon); m_preferencesUI->bnDefInfValueScaleSteps->setIcon(infinityIcon); m_preferencesUI->labelDefHueSteps->setPixmap(hueStepsPixmap); m_preferencesUI->labelDefSaturationSteps->setPixmap(saturationStepsPixmap); m_preferencesUI->labelDefValueScaleSteps->setPixmap(valueScaleStepsPixmap); m_preferencesUI->defaultHueSteps->setRange(MIN_NUM_HUE_PIECES, MAX_NUM_HUE_PIECES); m_preferencesUI->defaultSaturationSteps->setRange(MIN_NUM_SATURATION_RINGS, MAX_NUM_SATURATION_RINGS); m_preferencesUI->defaultValueScaleSteps->setRange(MIN_NUM_LIGHT_PIECES, MAX_NUM_LIGHT_PIECES); m_preferencesUI->defaultHueSteps->setValue(m_selectorUI->colorSelector->getDefaultHueSteps()); m_preferencesUI->defaultSaturationSteps->setValue(m_selectorUI->colorSelector->getDefaultSaturationSteps()); m_preferencesUI->defaultValueScaleSteps->setValue(m_selectorUI->colorSelector->getDefaultValueScaleSteps()); - 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->enforceGamutMask->setChecked(m_selectorUI->colorSelector->enforceGamutMask()); m_preferencesUI->permissiveGamutMask->setChecked(!m_selectorUI->colorSelector->enforceGamutMask()); - m_preferencesUI->showMaskPreview->setChecked(m_selectorUI->colorSelector->maskPreviewActive()); m_preferencesUI->spLumaR->setValue(m_selectorUI->colorSelector->lumaR()); m_preferencesUI->spLumaG->setValue(m_selectorUI->colorSelector->lumaG()); m_preferencesUI->spLumaB->setValue(m_selectorUI->colorSelector->lumaB()); m_preferencesUI->spLumaGamma->setValue(m_selectorUI->colorSelector->lumaGamma()); 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->lumaCoefficientBox->show(); } else { m_preferencesUI->lumaCoefficientBox->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_preferencesUI->defaultHueSteps , SIGNAL(valueChanged(int)) , SLOT(slotPreferenceChanged())); connect(m_preferencesUI->defaultSaturationSteps, SIGNAL(valueChanged(int)) , SLOT(slotPreferenceChanged())); connect(m_preferencesUI->defaultValueScaleSteps, SIGNAL(valueChanged(int)) , SLOT(slotPreferenceChanged())); connect(m_preferencesUI->bnDefInfHueSteps , SIGNAL(clicked(bool)) , SLOT(slotPreferenceChanged())); connect(m_preferencesUI->bnDefInfValueScaleSteps, SIGNAL(clicked(bool)) , SLOT(slotPreferenceChanged())); - connect(m_preferencesUI->showColorBlip , SIGNAL(toggled(bool)) , SLOT(slotPreferenceChanged())); 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->showMaskPreview , SIGNAL(toggled(bool)), SLOT(slotGamutMaskActivatePreview(bool))); connect(m_preferencesUI->spLumaR , SIGNAL(valueChanged(qreal)), SLOT(slotColorSpaceSelected())); connect(m_preferencesUI->spLumaG , SIGNAL(valueChanged(qreal)), SLOT(slotColorSpaceSelected())); connect(m_preferencesUI->spLumaB , SIGNAL(valueChanged(qreal)), SLOT(slotColorSpaceSelected())); connect(m_preferencesUI->spLumaGamma , SIGNAL(valueChanged(qreal)), SLOT(slotColorSpaceSelected())); connect(m_selectorUI->colorSelector , SIGNAL(sigFgColorChanged(KisColor)) , SLOT(slotFgColorChanged(KisColor))); connect(m_selectorUI->colorSelector , SIGNAL(sigBgColorChanged(KisColor)) , SLOT(slotBgColorChanged(KisColor))); // gamut mask connections - connect(m_selectorUI->bnToggleMask , SIGNAL(toggled(bool)) , SLOT(slotGamutMaskToggle(bool))); + connect(m_selectorUI->gamutMaskToolbar, SIGNAL(sigGamutMaskToggle(bool)), SLOT(slotGamutMaskToggle(bool))); connect(m_hsxButtons , SIGNAL(buttonClicked(int)) , SLOT(slotColorSpaceSelected())); setWidget(m_selectorUI); } ArtisticColorSelectorDock::~ArtisticColorSelectorDock() { m_selectorUI->colorSelector->saveSettings(); delete m_hsxButtons; } void ArtisticColorSelectorDock::setViewManager(KisViewManager* kisview) { m_resourceProvider = kisview->resourceProvider(); m_selectorUI->colorSelector->setFgColor(m_resourceProvider->resourceManager()->foregroundColor()); m_selectorUI->colorSelector->setBgColor(m_resourceProvider->resourceManager()->backgroundColor()); connect(m_resourceProvider, SIGNAL(sigGamutMaskChanged(KoGamutMask*)), this, SLOT(slotGamutMaskSet(KoGamutMask*))); connect(m_resourceProvider, SIGNAL(sigGamutMaskUnset()), this, SLOT(slotGamutMaskUnset())); - if (m_selectorUI->colorSelector->maskPreviewActive()) { - connect(m_resourceProvider, SIGNAL(sigGamutMaskPreviewUpdate()), - this, SLOT(slotGamutMaskPreviewUpdate())); - } + connect(m_resourceProvider, SIGNAL(sigGamutMaskPreviewUpdate()), + this, SLOT(slotGamutMaskPreviewUpdate())); + + m_selectorUI->gamutMaskToolbar->connectMaskSignals(m_resourceProvider); } void ArtisticColorSelectorDock::slotCanvasResourceChanged(int key, const QVariant& value) { if(key == KoCanvasResourceManager::ForegroundColor) m_selectorUI->colorSelector->setFgColor(value.value()); if(key == KoCanvasResourceManager::BackgroundColor) m_selectorUI->colorSelector->setBgColor(value.value()); } void ArtisticColorSelectorDock::slotFgColorChanged(const KisColor& color) { m_resourceProvider->resourceManager()->setForegroundColor( KoColor(color.toKoColor(), m_resourceProvider->resourceManager()->foregroundColor().colorSpace()) ); } void ArtisticColorSelectorDock::slotBgColorChanged(const KisColor& color) { m_resourceProvider->resourceManager()->setBackgroundColor( KoColor(color.toKoColor(), m_resourceProvider->resourceManager()->backgroundColor().colorSpace()) ); } void ArtisticColorSelectorDock::slotColorSpaceSelected() { KisColor::Type type = static_cast( m_hsxButtons->id(m_hsxButtons->checkedButton())); m_selectorUI->colorSelector->setColorSpace(type); if (type == KisColor::HSY) { m_preferencesUI->lumaCoefficientBox->show(); } else { m_preferencesUI->lumaCoefficientBox->hide(); } m_selectorUI->colorSelector->setLumaCoefficients( m_preferencesUI->spLumaR->value(), m_preferencesUI->spLumaG->value(), m_preferencesUI->spLumaB->value(), m_preferencesUI->spLumaGamma->value() ); } void ArtisticColorSelectorDock::slotPreferenceChanged() { int hueSteps = DEFAULT_HUE_STEPS; if (m_wheelPrefsUI->bnInfHueSteps->isChecked()) { m_wheelPrefsUI->numHueSteps->setEnabled(false); hueSteps = 1; } else { m_wheelPrefsUI->numHueSteps->setEnabled(true); hueSteps = m_wheelPrefsUI->numHueSteps->value(); } m_selectorUI->colorSelector->setNumPieces(hueSteps); m_selectorUI->colorSelector->setNumRings(m_wheelPrefsUI->numSaturationSteps->value()); int valueScaleSteps; if (m_wheelPrefsUI->bnInfValueScaleSteps->isChecked()) { m_wheelPrefsUI->numValueScaleSteps->setEnabled(false); valueScaleSteps = 1; } else { valueScaleSteps = m_wheelPrefsUI->numValueScaleSteps->value(); m_wheelPrefsUI->numValueScaleSteps->setEnabled(true); } m_selectorUI->colorSelector->setNumLightPieces(valueScaleSteps); int defHueSteps; if (m_preferencesUI->bnDefInfHueSteps->isChecked()) { m_preferencesUI->defaultHueSteps->setEnabled(false); defHueSteps = 1; } else { m_preferencesUI->defaultHueSteps->setEnabled(true); defHueSteps = m_preferencesUI->defaultHueSteps->value(); } m_selectorUI->colorSelector->setDefaultHueSteps(defHueSteps); m_selectorUI->colorSelector->setDefaultSaturationSteps(m_preferencesUI->defaultSaturationSteps->value()); int defValueScaleSteps; if (m_preferencesUI->bnDefInfValueScaleSteps->isChecked()) { m_preferencesUI->defaultValueScaleSteps->setEnabled(false); defValueScaleSteps = 1; } else { m_preferencesUI->defaultValueScaleSteps->setEnabled(true); defValueScaleSteps = m_preferencesUI->defaultValueScaleSteps->value(); } m_selectorUI->colorSelector->setDefaultValueScaleSteps(defValueScaleSteps); - m_selectorUI->colorSelector->setShowColorBlip(m_preferencesUI->showColorBlip->isChecked()); m_selectorUI->colorSelector->setShowBgColor(m_preferencesUI->showBgColor->isChecked()); m_selectorUI->colorSelector->setShowValueScaleNumbers(m_preferencesUI->showValueScaleNumbers->isChecked()); m_selectorUI->colorSelector->setEnforceGamutMask(m_preferencesUI->enforceGamutMask->isChecked()); - // the selector wheel forbids saturation inversion in some cases, - // reflecting that in the ui - if (m_selectorUI->colorSelector->saturationIsInvertible()) { - m_wheelPrefsUI->bnInverseSat->setEnabled(true); - m_selectorUI->colorSelector->setInverseSaturation(m_wheelPrefsUI->bnInverseSat->isChecked()); - } else { - m_wheelPrefsUI->bnInverseSat->setEnabled(false); - m_wheelPrefsUI->bnInverseSat->setChecked(false); - m_selectorUI->colorSelector->setInverseSaturation(false); - } + m_selectorUI->colorSelector->setInverseSaturation(m_wheelPrefsUI->bnInverseSat->isChecked()); } void ArtisticColorSelectorDock::slotResetDefaultSettings() { quint32 hueSteps = m_selectorUI->colorSelector->getDefaultHueSteps(); quint32 saturationSteps = m_selectorUI->colorSelector->getDefaultSaturationSteps(); quint32 valueScaleSteps = m_selectorUI->colorSelector->getDefaultValueScaleSteps(); m_selectorUI->colorSelector->setNumRings(saturationSteps); m_wheelPrefsUI->numSaturationSteps->blockSignals(true); m_wheelPrefsUI->numSaturationSteps->setValue(saturationSteps); m_wheelPrefsUI->numSaturationSteps->blockSignals(false); m_selectorUI->colorSelector->setNumPieces(hueSteps); m_wheelPrefsUI->numHueSteps->blockSignals(true); m_wheelPrefsUI->numHueSteps->setValue(hueSteps); m_wheelPrefsUI->numHueSteps->blockSignals(false); if (hueSteps == 1) { m_wheelPrefsUI->numHueSteps->setEnabled(false); m_wheelPrefsUI->bnInfHueSteps->setChecked(true); } else { m_wheelPrefsUI->numHueSteps->setEnabled(true); m_wheelPrefsUI->bnInfHueSteps->setChecked(false); } m_selectorUI->colorSelector->setNumLightPieces(valueScaleSteps); m_wheelPrefsUI->numValueScaleSteps->blockSignals(true); m_wheelPrefsUI->numValueScaleSteps->setValue(valueScaleSteps); m_wheelPrefsUI->numValueScaleSteps->blockSignals(false); if (valueScaleSteps == 1) { m_wheelPrefsUI->numValueScaleSteps->setEnabled(false); m_wheelPrefsUI->bnInfValueScaleSteps->setChecked(true); } else { m_wheelPrefsUI->numValueScaleSteps->setEnabled(true); m_wheelPrefsUI->bnInfValueScaleSteps->setChecked(false); } } -void ArtisticColorSelectorDock::slotGamutMaskActivatePreview(bool value) -{ - m_selectorUI->colorSelector->setMaskPreviewActive(value); - - if (value) { - connect(m_resourceProvider, SIGNAL(sigGamutMaskPreviewUpdate()), - this, SLOT(slotGamutMaskPreviewUpdate())); - } else { - disconnect(m_resourceProvider, SIGNAL(sigGamutMaskPreviewUpdate()), - this, SLOT(slotGamutMaskPreviewUpdate())); - } - - m_selectorUI->colorSelector->update(); -} - void ArtisticColorSelectorDock::slotGamutMaskToggle(bool checked) { bool b = (!m_selectedMask) ? false : checked; - m_selectorUI->bnToggleMask->setChecked(b); - if (b == true) { m_selectorUI->colorSelector->setGamutMask(m_selectedMask); - m_selectorUI->bnToggleMask->setIcon(m_iconMaskOn); - } else { - m_selectorUI->bnToggleMask->setIcon(m_iconMaskOff); } m_selectorUI->colorSelector->setGamutMaskOn(b); - - // TODO: HACK - // the selector wheel forbids saturation inversion in some cases, - // reflecting that in the ui - if (m_selectorUI->colorSelector->saturationIsInvertible()) { - m_wheelPrefsUI->bnInverseSat->setEnabled(true); - m_selectorUI->colorSelector->setInverseSaturation(m_wheelPrefsUI->bnInverseSat->isChecked()); - } else { - m_wheelPrefsUI->bnInverseSat->setEnabled(false); - m_wheelPrefsUI->bnInverseSat->setChecked(false); - m_selectorUI->colorSelector->setInverseSaturation(false); - } - } void ArtisticColorSelectorDock::setCanvas(KoCanvasBase *canvas) { if (!canvas) { return; } m_canvas = dynamic_cast(canvas); if (m_canvas) { m_canvas->disconnectCanvasObserver(this); } if (m_canvas) { connect(m_canvas->resourceManager(), SIGNAL(canvasResourceChanged(int,QVariant)), SLOT(slotCanvasResourceChanged(int,QVariant))); connect(m_canvas->displayColorConverter(), SIGNAL(displayConfigurationChanged()), SLOT(slotSelectorSettingsChanged())); m_selectorUI->colorSelector->setColorConverter(m_canvas->displayColorConverter()); setEnabled(true); } } void ArtisticColorSelectorDock::unsetCanvas() { setEnabled(false); m_canvas = nullptr; m_selectorUI->colorSelector->setColorConverter(KisDisplayColorConverter::dumbConverterInstance()); } void ArtisticColorSelectorDock::slotGamutMaskSet(KoGamutMask *mask) { if (!mask) { return; } m_selectedMask = mask; if (m_selectedMask) { m_selectorUI->colorSelector->setGamutMask(m_selectedMask); - m_selectorUI->labelMaskName->setText(m_selectedMask->title()); slotGamutMaskToggle(true); } else { slotGamutMaskToggle(false); - m_selectorUI->labelMaskName->setText(i18n("Select a mask in \"Gamut Masks\" docker")); } } void ArtisticColorSelectorDock::slotGamutMaskUnset() { if (!m_selectedMask) { return; } m_selectedMask = nullptr; slotGamutMaskToggle(false); - m_selectorUI->labelMaskName->setText(i18n("Select a mask in \"Gamut Masks\" docker")); m_selectorUI->colorSelector->setGamutMask(m_selectedMask); } void ArtisticColorSelectorDock::slotGamutMaskPreviewUpdate() { m_selectorUI->colorSelector->update(); } void ArtisticColorSelectorDock::slotSelectorSettingsChanged() { m_selectorUI->colorSelector->update(); } diff --git a/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.h b/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.h index 9b82125554..23112382c8 100644 --- a/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.h +++ b/plugins/dockers/artisticcolorselector/artisticcolorselector_dock.h @@ -1,87 +1,86 @@ /* * Copyright (c) 2009 Cyrille Berger * * 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 H_ARTISTIC_COLOR_SELECTOR_DOCK_H #define H_ARTISTIC_COLOR_SELECTOR_DOCK_H #include #include #include #include #include #include #include #include #include #include #include #include class KisCanvasResourceProvider; class KisColor; class QButtonGroup; class QMenu; struct ArtisticColorSelectorUI; struct ARCSSettingsUI; struct WheelPreferencesPopupUI; class ArtisticColorSelectorDock: public QDockWidget, public KisMainwindowObserver { Q_OBJECT public: ArtisticColorSelectorDock(); ~ArtisticColorSelectorDock() override; QString observerName() override { return "ArtisticColorSelectorDock"; } void setViewManager(KisViewManager* kisview) override; void setCanvas(KoCanvasBase* canvas) override; void unsetCanvas() override; private Q_SLOTS: void slotCanvasResourceChanged(int key, const QVariant& value); void slotFgColorChanged(const KisColor& color); void slotBgColorChanged(const KisColor& color); void slotColorSpaceSelected(); void slotPreferenceChanged(); void slotResetDefaultSettings(); void slotGamutMaskToggle(bool value); - void slotGamutMaskActivatePreview(bool value); void slotGamutMaskSet(KoGamutMask* mask); void slotGamutMaskUnset(); void slotGamutMaskPreviewUpdate(); void slotSelectorSettingsChanged(); private: KisCanvas2* m_canvas; KisCanvasResourceProvider* m_resourceProvider; QButtonGroup* m_hsxButtons; ArtisticColorSelectorUI* m_selectorUI; ARCSSettingsUI* m_preferencesUI; WheelPreferencesPopupUI* m_wheelPrefsUI; KoGamutMask* m_selectedMask; QIcon m_iconMaskOff; QIcon m_iconMaskOn; QPixmap m_infinityPixmap; }; #endif // H_ARTISTIC_COLOR_SELECTOR_DOCK_H diff --git a/plugins/dockers/artisticcolorselector/forms/wdgARCSSettings.ui b/plugins/dockers/artisticcolorselector/forms/wdgARCSSettings.ui index 9ecbd7d0b5..cd9224f089 100644 --- a/plugins/dockers/artisticcolorselector/forms/wdgARCSSettings.ui +++ b/plugins/dockers/artisticcolorselector/forms/wdgARCSSettings.ui @@ -1,417 +1,400 @@ wdgARCSSettings 0 0 446 - 769 + 633 Selector Appearance - - - - Show color blip - - - Show background color indicator Show numbered value scale Color Space HS&Y true true HS&V true HSL true HSI true 0 0 Luma Coefficients 0 0 6 0 0 50 0 4 0 0 Green': 0 0 Blue': 0 0 50 0 4 0 0 50 0 4 <html><head/><body><p>This sets the gamma value that the linearised HSY Luminosity is crunched with. 1 makes the selector fully linear, 2.2 is a practical default value.</p></body></html> 1 -3.000000000000000 3.000000000000000 0.100000000000000 2.200000000000000 Gamma: 0 0 Red': Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Gamut Mask Behavior Enforce gamut &mask &Just show the shapes - - - - Show preview while editing a mask - - - false - - - Default Selector Steps Settings 0 0 0 0 Hue Steps 0 0 Saturation Rings true 0 0 0 0 Value Scale Steps 0 0 true - - KisDoubleParseSpinBox - QDoubleSpinBox -
kis_double_parse_spin_box.h
-
KisSliderSpinBox QWidget
kis_slider_spin_box.h
1
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
diff --git a/plugins/dockers/artisticcolorselector/forms/wdgArtisticColorSelector.ui b/plugins/dockers/artisticcolorselector/forms/wdgArtisticColorSelector.ui index a030c0203f..280c7ad346 100644 --- a/plugins/dockers/artisticcolorselector/forms/wdgArtisticColorSelector.ui +++ b/plugins/dockers/artisticcolorselector/forms/wdgArtisticColorSelector.ui @@ -1,143 +1,136 @@ wdgArtisticColorSelector 0 0 334 284 100 100 - - - Toggle gamut mask - - - - - - true - - - - - + 0 0 - - Select a mask in "Gamut Masks" docker - - - true - QFrame::Sunken Qt::Vertical 0 0 + + + 0 + 0 + + 16777215 16777215 Color wheel preferences false 0 0 - 30 + 0 0 Docker settings false 0 1 KisPopupButton QPushButton
kis_popup_button.h
KisColorSelector QWidget
kis_color_selector.h
1
+ + KisGamutMaskToolbar + QWidget +
KisGamutMaskToolbar.h
+ 1 +
diff --git a/plugins/dockers/artisticcolorselector/kis_arcs_constants.h b/plugins/dockers/artisticcolorselector/kis_arcs_constants.h index 74837691f8..4a40cbbfb4 100644 --- a/plugins/dockers/artisticcolorselector/kis_arcs_constants.h +++ b/plugins/dockers/artisticcolorselector/kis_arcs_constants.h @@ -1,54 +1,54 @@ /* * 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; static const int MAX_NUM_HUE_PIECES = 48; static const int MIN_NUM_LIGHT_PIECES = 1; static const int MIN_NUM_UI_LIGHT_PIECES = 2; static const int MAX_NUM_LIGHT_PIECES = 30; static const int MIN_NUM_SATURATION_RINGS = 1; static const int MAX_NUM_SATURATION_RINGS = 20; static const int DEFAULT_HUE_STEPS = 12; static const int DEFAULT_SATURATION_STEPS = 7; static const int DEFAULT_VALUE_SCALE_STEPS = 11; static const qreal DEFAULT_LUMA_R = 0.2126; static const qreal DEFAULT_LUMA_G = 0.7152; static const qreal DEFAULT_LUMA_B = 0.0722; static const qreal DEFAULT_LUMA_GAMMA = 2.2; // 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_DARK = QColor(50,50,50,255); +static const QColor COLOR_LIGHT = QColor(200,200,200,255); +static const QColor COLOR_SELECTED_DARK = QColor(30,30,30,255); +static const QColor COLOR_SELECTED_LIGHT = QColor(220,220,220,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_selector.cpp b/plugins/dockers/artisticcolorselector/kis_color_selector.cpp index 88ba6f9bcc..6c03e24f0a 100644 --- a/plugins/dockers/artisticcolorselector/kis_color_selector.cpp +++ b/plugins/dockers/artisticcolorselector/kis_color_selector.cpp @@ -1,1104 +1,1094 @@ /* Copyright (C) 2011 Silvio Heinrich 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 #include #include #include #include #include #include #include #include "kis_color_selector.h" //#define DEBUG_ARC_SELECTOR KisColorSelector::KisColorSelector(QWidget* parent, KisColor::Type type) : QWidget(parent) , m_colorConverter(KisDisplayColorConverter::dumbConverterInstance()) , m_colorSpace(type) , m_inverseSaturation(false) , m_selectedColor(m_colorConverter) , m_fgColor(m_colorConverter) , m_bgColor(m_colorConverter) , m_clickedRing(-1) , m_gamutMaskOn(false) , m_currentGamutMask(nullptr) , m_maskPreviewActive(true) , m_widgetUpdatesSelf(false) { m_viewConverter = new KisGamutMaskViewConverter(); setLumaCoefficients(DEFAULT_LUMA_R, DEFAULT_LUMA_G, DEFAULT_LUMA_B,DEFAULT_LUMA_GAMMA); recalculateRings(DEFAULT_SATURATION_STEPS, DEFAULT_HUE_STEPS); recalculateAreas(DEFAULT_VALUE_SCALE_STEPS); selectColor(KisColor(Qt::red, m_colorConverter, KisColor::HSY, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma)); 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) { m_colorSpace = type; m_selectedColor = KisColor(m_selectedColor, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma); #ifdef DEBUG_ARC_SELECTOR dbgPlugins << "KisColorSelector::setColorSpace: set to:" << m_colorSpace; #endif update(); } void KisColorSelector::setColorConverter(KisDisplayColorConverter *colorConverter) { m_colorConverter = colorConverter; update(); } void KisColorSelector::setNumLightPieces(int num) { num = qBound(MIN_NUM_LIGHT_PIECES, num, MAX_NUM_LIGHT_PIECES); recalculateAreas(quint8(num)); if (m_selectedLightPiece >= 0) m_selectedLightPiece = getLightIndex(m_selectedColor.getX()); update(); } void KisColorSelector::setNumPieces(int num) { num = qBound(MIN_NUM_HUE_PIECES, num, MAX_NUM_HUE_PIECES); recalculateRings(quint8(getNumRings()), quint8(num)); if (m_selectedPiece >= 0) m_selectedPiece = getHueIndex(m_selectedColor.getH() * PI2); update(); } void KisColorSelector::setNumRings(int num) { num = qBound(MIN_NUM_SATURATION_RINGS, num, MAX_NUM_SATURATION_RINGS); recalculateRings(quint8(num), quint8(getNumPieces())); if (m_selectedRing >= 0) m_selectedRing = getSaturationIndex(m_selectedColor.getS()); update(); } void KisColorSelector::selectColor(const KisColor& color) { m_selectedColor = KisColor(color, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma); m_selectedPiece = getHueIndex(m_selectedColor.getH() * PI2); m_selectedRing = getSaturationIndex(m_selectedColor.getS()); m_selectedLightPiece = getLightIndex(m_selectedColor.getX()); update(); } void KisColorSelector::setFgColor(const KoColor& fgColor) { if (!m_widgetUpdatesSelf) { m_fgColor = KisColor(fgColor, m_colorConverter, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma); m_selectedColor = KisColor(fgColor, m_colorConverter, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma); #ifdef DEBUG_ARC_SELECTOR dbgPlugins << "KisColorSelector::setFgColor: m_fgColor set to:" << "H:" << m_fgColor.getH() << "S:" << m_fgColor.getS() << "X:" << m_fgColor.getX(); dbgPlugins << "KisColorSelector::setFgColor: m_selectedColor set to:" << "H:" << m_selectedColor.getH() << "S:" << m_selectedColor.getS() << "X:" << m_selectedColor.getX(); #endif update(); } } void KisColorSelector::setBgColor(const KoColor& bgColor) { if (!m_widgetUpdatesSelf) { m_bgColor = KisColor(bgColor, m_colorConverter, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma); #ifdef DEBUG_ARC_SELECTOR dbgPlugins << "KisColorSelector::setBgColor: m_bgColor set to:" << "H:" << m_bgColor.getH() << "S:" << m_bgColor.getS() << "X:" << m_bgColor.getX(); #endif update(); } } void KisColorSelector::setLight(qreal light) { m_selectedColor.setX(qBound(0.0, light, 1.0)); m_selectedLightPiece = getLightIndex(m_selectedColor.getX()); update(); } void KisColorSelector::setLumaCoefficients(qreal lR, qreal lG, qreal lB, qreal lGamma) { m_lumaR = lR; m_lumaG = lG; m_lumaB = lB; if (m_colorSpace == KisColor::HSY) { m_lumaGamma = lGamma; } else { m_lumaGamma = 1.0; } m_selectedColor = KisColor(m_selectedColor, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma); #ifdef DEBUG_ARC_SELECTOR dbgPlugins << "KisColorSelector::setLumaCoefficients: " << m_lumaR << " " << m_lumaG << " " << m_lumaB << " " << m_lumaGamma; #endif update(); } void KisColorSelector::setInverseSaturation(bool inverse) { if (m_inverseSaturation != inverse) { m_selectedRing = (getNumRings()-1) - m_selectedRing; m_inverseSaturation = inverse; recalculateRings(quint8(getNumRings()), quint8(getNumPieces())); update(); } } void KisColorSelector::setGamutMask(KoGamutMask* gamutMask) { if (!gamutMask) { return; } m_currentGamutMask = gamutMask; m_viewConverter->setViewSize(m_renderAreaSize); m_viewConverter->setMaskSize(m_currentGamutMask->maskSize()); update(); } KoGamutMask* KisColorSelector::gamutMask() { return m_currentGamutMask; } -bool KisColorSelector::maskPreviewActive() -{ - return m_maskPreviewActive; -} - -void KisColorSelector::setMaskPreviewActive(bool value) -{ - m_maskPreviewActive = value; -} - bool KisColorSelector::gamutMaskOn() { return m_gamutMaskOn; } void KisColorSelector::setGamutMaskOn(bool gamutMaskOn) { if (m_currentGamutMask) { m_gamutMaskOn = gamutMaskOn; update(); } } void KisColorSelector::setEnforceGamutMask(bool enforce) { m_enforceGamutMask = enforce; update(); } QPointF KisColorSelector::mapCoordToView(const QPointF& pt, const QRectF& viewRect) const { qreal w = viewRect.width() / 2.0; qreal h = viewRect.height() / 2.0; qreal x = pt.x() + 1.0; qreal y = (pt.y()) + 1.0; return QPointF(x*w, y*h); } QPointF KisColorSelector::mapCoordToUnit(const QPointF& pt, const QRectF& viewRect) const { qreal w = viewRect.width() / 2.0; qreal h = viewRect.height() / 2.0; qreal x = pt.x() - (viewRect.x() + w); qreal y = pt.y() - (viewRect.y() + h); return QPointF(x/w, y/h); } QPointF KisColorSelector::mapColorToUnit(const KisColor& color, bool invertSaturation) const { qreal radius; if (invertSaturation && m_inverseSaturation) { radius = 1.0 - color.getS(); } else { radius = color.getS(); } 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 { qreal angle = std::atan2(-y, -x); #ifdef DEBUG_ARC_SELECTOR dbgPlugins << "KisColorSelector::mapCoordToAngle: " << "X:" << x << "Y:" << y << "angle:" << angle; #endif return angle; } QPointF KisColorSelector::mapHueToAngle(qreal hue) const { qreal angle = hue * 2.0 * M_PI - M_PI; qreal x = std::cos(angle); qreal y = std::sin(angle); return QPointF(x,y); } qint8 KisColorSelector::getLightIndex(const QPointF& pt) const { if (m_lightStripArea.contains(pt.toPoint(), true)) { qreal t = (pt.x() - m_lightStripArea.x()) / qreal(m_lightStripArea.width()); t = (pt.y() - m_lightStripArea.y()) / qreal(m_lightStripArea.height()); return qint8(t * getNumLightPieces()); } return -1; } qint8 KisColorSelector::getLightIndex(qreal light) const { light = qreal(1) - qBound(qreal(0), light, qreal(1)); return qint8(qRound(light * (getNumLightPieces()-1))); } qreal KisColorSelector::getLight(const QPointF& pt) const { qint8 clickedLightPiece = getLightIndex(pt); if (clickedLightPiece >= 0) { if (getNumLightPieces() > 1) { return 1.0 - (qreal(clickedLightPiece) / qreal(getNumLightPieces()-1)); } return 1.0 - (qreal(pt.y()) / qreal(m_lightStripArea.height())); } return qreal(0); } qint8 KisColorSelector::getHueIndex(Radian hue) const { qreal partSize = 1.0 / qreal(getNumPieces()); return qint8(qRound(hue.scaled(0.0, 1.0) / partSize) % getNumPieces()); } qreal KisColorSelector::getHue(int hueIdx, Radian shift) const { Radian hue = (qreal(hueIdx) / qreal(getNumPieces())) * PI2; hue += shift; return hue.scaled(0.0, 1.0); } qint8 KisColorSelector::getSaturationIndex(qreal saturation) const { saturation = qBound(qreal(0), saturation, qreal(1)); saturation = m_inverseSaturation ? (qreal(1) - saturation) : saturation; return qint8(saturation * qreal(getNumRings() - 1)); } qint8 KisColorSelector::getSaturationIndex(const QPointF& pt) const { qreal length = std::sqrt(pt.x()*pt.x() + pt.y()*pt.y()); for(int i=0; i= m_colorRings[i].innerRadius && length < m_colorRings[i].outerRadius) return qint8(i); } return -1; } qreal KisColorSelector::getSaturation(int saturationIdx) const { qreal sat = qreal(saturationIdx) / qreal(getNumRings()-1); return m_inverseSaturation ? (1.0 - sat) : sat; } void KisColorSelector::recalculateAreas(quint8 numLightPieces) { qreal LIGHT_STRIP_RATIO = 0.075; if (m_showValueScaleNumbers) { LIGHT_STRIP_RATIO = 0.25; } int width = QWidget::width(); int height = QWidget::height(); int size = qMin(width, height); int stripThick = int(size * LIGHT_STRIP_RATIO); width -= stripThick; size = qMin(width, height); int x = (width - size) / 2; int y = (height - size) / 2; m_renderAreaSize = QSize(size,size); m_viewConverter->setViewSize(m_renderAreaSize); m_renderArea = QRect(x+stripThick, y, size, size); m_lightStripArea = QRect(0, 0, stripThick, QWidget::height()); m_renderBuffer = QImage(size, size, QImage::Format_ARGB32_Premultiplied); m_maskBuffer = QImage(size, size, QImage::Format_ARGB32_Premultiplied); m_numLightPieces = numLightPieces; } void KisColorSelector::recalculateRings(quint8 numRings, quint8 numPieces) { m_colorRings.resize(numRings); m_numPieces = numPieces; for(int i=0; i(numPieces, 1); ring.innerRadius = innerRadius; ring.outerRadius = outerRadius; ring.pieced.resize(numParts); qreal partSize = 360.0 / qreal(numParts); QRectF outerRect(-outerRadius, -outerRadius, outerRadius*2.0, outerRadius*2.0); QRectF innerRect(-innerRadius, -innerRadius, innerRadius*2.0, innerRadius*2.0); for(int i=0; icoordIsClear(colorCoord, *m_viewConverter, m_maskPreviewActive); if (isClear) { return true; } else { return false; } } else { return true; } return false; } 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(); #endif m_updateColorCompressor->start(qMakePair(color, role)); } void KisColorSelector::slotUpdateColorAndPreview(QPair color) { const bool selectAsFgColor = color.second == Acs::Foreground; if (selectAsFgColor) { m_fgColor = color.first; } else { m_bgColor = color.first; } 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(); #endif if (selectAsFgColor) { emit sigFgColorChanged(m_selectedColor); } else { emit sigBgColorChanged(m_selectedColor); } } 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) { QTransform mirror; mirror.rotate(180, Qt::YAxis); painter.setTransform(mirror, true); painter.scale(rect.width()/2, rect.height()/2); 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.0) ? (hue - 1.0) : hue; hue = (hue < 0.0) ? (hue + 1.0) : hue; KisColor color(hue, m_colorConverter, m_colorSpace); color.setS(ring.saturation); color.setX(m_selectedColor.getX()); if(m_gamutMaskOn && m_enforceGamutMask && colorIsClear(color)) { painter.setPen(clearMaskPen); } else { painter.setPen(normalPen); } if ((m_enforceGamutMask) && (!colorIsClear(color))) { brush.setColor(COLOR_MASK_FILL); } else { brush.setColor(color.toQColor()); } painter.setBrush(brush); painter.drawPath(ring.pieced[i]); } } else { KisColor colors[7] = { KisColor(Qt::cyan , m_colorConverter, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma), KisColor(Qt::green , m_colorConverter, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma), KisColor(Qt::yellow , m_colorConverter, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma), KisColor(Qt::red , m_colorConverter, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma), KisColor(Qt::magenta, m_colorConverter, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma), KisColor(Qt::blue , m_colorConverter, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma), KisColor(Qt::cyan , m_colorConverter, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma) }; QConicalGradient gradient(0, 0, 0); for(int i=0; i<=6; ++i) { qreal hue = qreal(i) / 6.0; colors[i].setS(ring.saturation); colors[i].setX(m_selectedColor.getX()); gradient.setColorAt(hue, colors[i].toQColor()); } painter.scale(rect.width()/2, rect.height()/2); painter.fillPath(ring.pieced[0], QBrush(gradient)); } painter.restore(); } void KisColorSelector::drawOutline(QPainter& painter, const QRect& rect) { painter.setRenderHint(QPainter::Antialiasing, true); painter.resetTransform(); painter.translate(rect.x() + rect.width()/2, rect.y() + rect.height()/2); painter.scale(rect.width()/2, rect.height()/2); QPen normalPen = QPen(QBrush(COLOR_NORMAL_OUTLINE), 0.005); - QPen selectedPen = QPen(QBrush(COLOR_LIGHT), 0.01); + QPen selectedPen; painter.setPen(normalPen); if (getNumPieces() > 1) { if (m_selectedRing >= 0 && m_selectedPiece >= 0) { painter.resetTransform(); painter.translate(rect.x() + rect.width()/2, rect.y() + rect.height()/2); QTransform mirror; mirror.rotate(180, Qt::YAxis); painter.setTransform(mirror, true); painter.scale(rect.width()/2, rect.height()/2); + if (m_selectedColor.getX() < 0.55) { + selectedPen = QPen(QBrush(COLOR_SELECTED_LIGHT), 0.007); + } else { + selectedPen = QPen(QBrush(COLOR_SELECTED_DARK), 0.007); + } + painter.setPen(selectedPen); painter.drawPath(m_colorRings[m_selectedRing].pieced[m_selectedPiece]); } } else { for(int i=0; i= 0) { qreal iRad = m_colorRings[m_selectedRing].innerRadius; qreal oRad = m_colorRings[m_selectedRing].outerRadius; + if (m_selectedColor.getX() < 0.55) { + selectedPen = QPen(QBrush(COLOR_SELECTED_LIGHT), 0.005); + } else { + selectedPen = QPen(QBrush(COLOR_SELECTED_DARK), 0.005); + } + painter.setPen(selectedPen); painter.drawEllipse(QRectF(-iRad, -iRad, iRad*2.0, iRad*2.0)); painter.drawEllipse(QRectF(-oRad, -oRad, oRad*2.0, oRad*2.0)); 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) { qreal penSize = qreal(qMin(QWidget::width(), QWidget::height())) / 200.0; + qreal penSizeSmall = penSize / 1.2; + QPen selectedPen; + KisColor valueScaleColor(m_selectedColor, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma); KisColor grayScaleColor(Qt::gray, m_colorConverter, m_colorSpace, m_lumaR, m_lumaG, m_lumaB, m_lumaGamma); int rectSize = rect.height(); painter.resetTransform(); painter.save(); painter.setRenderHint(QPainter::Antialiasing, true); 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 rect.width()*rectColorLeftX) { + font.setPointSize(font.pointSize() - 1); + painter.setFont(font); + fm = painter.fontMetrics(); + } for(int i=0; i coord X:" << fgColorPos.x() << " Y:" << fgColorPos.y(); #endif - painter.setPen(QPen(QBrush(COLOR_DARK), 0.01)); + painter.setPen(QPen(QBrush(COLOR_SELECTED_DARK), 0.01)); painter.drawEllipse(fgColorPos, 0.05, 0.05); - painter.setPen(QPen(QBrush(COLOR_LIGHT), 0.01)); + painter.setPen(QPen(QBrush(COLOR_SELECTED_LIGHT), 0.01)); painter.setBrush(m_fgColor.toQColor()); painter.drawEllipse(fgColorPos, 0.04, 0.04); } void KisColorSelector::drawGamutMaskShape(QPainter &painter, const QRect &rect) { painter.save(); painter.setRenderHint(QPainter::Antialiasing, true); painter.resetTransform(); painter.translate(rect.width()/2, rect.height()/2); painter.scale(rect.width()/2, rect.height()/2); painter.setPen(Qt::NoPen); painter.setBrush(COLOR_MASK_FILL); painter.drawEllipse(QPointF(0,0), 1.0, 1.0); painter.resetTransform(); 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(); } void KisColorSelector::paintEvent(QPaintEvent* /*event*/) { // 0 red -> (1,0,0) // 1 yellow -> (1,1,0) // 2 green -> (0,1,0) // 3 cyan -> (0,1,1) // 4 blue -> (0,0,1) // 5 maenta -> (1,0,1) // 6 red -> (1,0,0) m_renderBuffer.fill(0); QPainter imgPainter(&m_renderBuffer); QPainter wdgPainter(this); // draw the fg and bg color previews // QPainter settings must be saved and restored afterwards, otherwise the wheel drawing is totally broken wdgPainter.save(); wdgPainter.setRenderHint(QPainter::Antialiasing, true); QRect fgRect(0, 0, QWidget::width(), QWidget::height()); wdgPainter.fillRect(fgRect, m_fgColor.toQColor()); int bgSide = qMin(QWidget::width()*0.15,QWidget::height()*0.15); if (m_showBgColor) { QPointF bgPolyPoints[3] = { QPointF(QWidget::width(), QWidget::height()), QPointF(QWidget::width()-bgSide, QWidget::height()), QPointF(QWidget::width(), QWidget::height()-bgSide) }; wdgPainter.setBrush(m_bgColor.toQColor()); wdgPainter.setPen(m_bgColor.toQColor()); wdgPainter.drawPolygon(bgPolyPoints, 3); } 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_selectedLightPiece = clickedLightPiece; requestUpdateColorAndPreview(m_selectedColor, colorRole); m_mouseMoved = true; } else if (m_clickedRing >= 0) { if (getNumPieces() == 1) { Radian angle = mapCoordToAngle(m_clickPos.x(), m_clickPos.y()); KisColor color(m_colorConverter, m_colorSpace); color.setHSX(angle.scaled(0.0, 1.0) , getSaturation(m_clickedRing) , m_selectedColor.getX() ); #ifdef DEBUG_ARC_SELECTOR dbgPlugins << "KisColorSelector::mousePressEvent: picked color: " << "H:" << color.getH() << "S:" << color.getS() << "X:" << color.getX(); #endif if ((!m_enforceGamutMask) || colorIsClear(color)) { m_selectedColor.setHSX(color.getH(), color.getS(), color.getX()); requestUpdateColorAndPreview(m_selectedColor, colorRole); m_selectedRing = m_clickedRing; m_mouseMoved = true; update(); } } } } void KisColorSelector::mouseMoveEvent(QMouseEvent* event) { QPointF dragPos = mapCoordToUnit(event->localPos(), m_renderArea); qint8 clickedLightPiece = getLightIndex(event->localPos()); Acs::ColorRole colorRole = Acs::buttonsToRole(Qt::NoButton, m_pressedButtons); if (clickedLightPiece >= 0) { setLight(getLight(event->localPos())); m_selectedLightPiece = clickedLightPiece; requestUpdateColorAndPreview(m_selectedColor, colorRole); } if (m_clickedRing < 0) return; if (getNumPieces() == 1) { Radian angle = mapCoordToAngle(dragPos.x(), dragPos.y()); KisColor color(m_colorConverter, m_colorSpace); color.setHSX(angle.scaled(0.0, 1.0) , getSaturation(m_clickedRing) , m_selectedColor.getX() ); if ((!m_enforceGamutMask) || colorIsClear(color)) { m_selectedColor.setHSX(color.getH(), color.getS(), color.getX()); requestUpdateColorAndPreview(m_selectedColor, colorRole); } } update(); } void KisColorSelector::mouseReleaseEvent(QMouseEvent* /*event*/) { Acs::ColorRole colorRole = Acs::buttonsToRole(Qt::NoButton, m_pressedButtons); if (!m_mouseMoved && m_clickedRing >= 0) { Radian angle = mapCoordToAngle(m_clickPos.x(), m_clickPos.y()); KisColor color(m_colorConverter, m_colorSpace); qint8 hueIndex = getHueIndex(angle); if (getNumPieces() > 1) { color.setH(getHue(hueIndex)); } else { color.setH(angle.scaled(0.0, 1.0)); } color.setS(getSaturation(m_clickedRing)); color.setX(m_selectedColor.getX()); if ((!m_enforceGamutMask) || colorIsClear(color)) { m_selectedColor.setHSX(color.getH(), color.getS(), color.getX()); m_selectedPiece = hueIndex; m_selectedRing = m_clickedRing; requestUpdateColorAndPreview(m_selectedColor, colorRole); } } else if (m_mouseMoved) requestUpdateColorAndPreview(m_selectedColor, colorRole); m_clickedRing = -1; m_widgetUpdatesSelf = false; #ifdef DEBUG_ARC_SELECTOR dbgPlugins << "KisColorSelector::ReleasePressEvent: m_widgetUpdatesSelf = false"; #endif update(); } void KisColorSelector::resizeEvent(QResizeEvent* /*event*/) { recalculateAreas(quint8(getNumLightPieces())); } void KisColorSelector::leaveEvent(QEvent* /*e*/) { m_widgetUpdatesSelf = false; #ifdef DEBUG_ARC_SELECTOR dbgPlugins << "KisColorSelector::leaveEvent: m_widgetUpdatesSelf = false"; #endif } void KisColorSelector::saveSettings() { KisConfig cfg(false); cfg.writeEntry("ArtColorSel.ColorSpace" , qint32(m_colorSpace)); cfg.writeEntry("ArtColorSel.lumaR", qreal(m_lumaR)); cfg.writeEntry("ArtColorSel.lumaG", qreal(m_lumaG)); cfg.writeEntry("ArtColorSel.lumaB", qreal(m_lumaB)); cfg.writeEntry("ArtColorSel.lumaGamma", qreal(m_lumaGamma)); cfg.writeEntry("ArtColorSel.NumRings" , m_colorRings.size()); cfg.writeEntry("ArtColorSel.RingPieces" , qint32(m_numPieces)); cfg.writeEntry("ArtColorSel.LightPieces", qint32(m_numLightPieces)); cfg.writeEntry("ArtColorSel.InversedSaturation", m_inverseSaturation); cfg.writeEntry("ArtColorSel.Light" , m_selectedColor.getX()); cfg.writeEntry("ArtColorSel.SelColorH", m_selectedColor.getH()); cfg.writeEntry("ArtColorSel.SelColorS", m_selectedColor.getS()); cfg.writeEntry("ArtColorSel.SelColorX", m_selectedColor.getX()); 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.showValueScale", m_showValueScaleNumbers); cfg.writeEntry("ArtColorSel.enforceGamutMask", m_enforceGamutMask); - - cfg.writeEntry("ArtColorSel.maskPreviewActive", m_maskPreviewActive); } void KisColorSelector::loadSettings() { KisConfig cfg(true); 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)); setColorSpace(colorSpace); setLumaCoefficients(cfg.readEntry("ArtColorSel.lumaR", DEFAULT_LUMA_R), cfg.readEntry("ArtColorSel.lumaG", DEFAULT_LUMA_G), cfg.readEntry("ArtColorSel.lumaB", DEFAULT_LUMA_B), cfg.readEntry("ArtColorSel.lumaGamma", DEFAULT_LUMA_GAMMA)); m_selectedColor.setH(cfg.readEntry("ArtColorSel.SelColorH", 0.0)); m_selectedColor.setS(cfg.readEntry("ArtColorSel.SelColorS", 0.0)); m_selectedColor.setX(cfg.readEntry("ArtColorSel.SelColorX", 0.0)); setInverseSaturation(cfg.readEntry("ArtColorSel.InversedSaturation", false)); setLight(cfg.readEntry("ArtColorSel.Light", 0.5f)); setNumRings(cfg.readEntry("ArtColorSel.NumRings", DEFAULT_SATURATION_STEPS)); setNumPieces(cfg.readEntry("ArtColorSel.RingPieces", DEFAULT_HUE_STEPS)); m_showBgColor = cfg.readEntry("ArtColorSel.showBgColor", true); - m_showColorBlip = cfg.readEntry("ArtColorSel.showColorBlip", true); m_showValueScaleNumbers = cfg.readEntry("ArtColorSel.showValueScale", false); m_enforceGamutMask = cfg.readEntry("ArtColorSel.enforceGamutMask", false); - m_maskPreviewActive = cfg.readEntry("ArtColorSel.maskPreviewActive", true); - selectColor(m_selectedColor); update(); } void KisColorSelector::setDefaultHueSteps(int num) { num = qBound(MIN_NUM_HUE_PIECES, num, MAX_NUM_HUE_PIECES); m_defaultHueSteps = num; } void KisColorSelector::setDefaultSaturationSteps(int num) { num = qBound(MIN_NUM_SATURATION_RINGS, num, MAX_NUM_SATURATION_RINGS); m_defaultSaturationSteps = num; } void KisColorSelector::setDefaultValueScaleSteps(int num) { num = qBound(MIN_NUM_LIGHT_PIECES, num, MAX_NUM_LIGHT_PIECES); m_defaultValueScaleSteps = num; } -void KisColorSelector::setShowColorBlip(bool value) { - m_showColorBlip = value; - update(); -} - void KisColorSelector::setShowBgColor(bool value) { m_showBgColor = value; update(); } void KisColorSelector::setShowValueScaleNumbers(bool value) { m_showValueScaleNumbers = value; recalculateAreas(quint8(getNumLightPieces())); update(); } bool KisColorSelector::saturationIsInvertible() { if (!m_gamutMaskOn) return true; bool b = (m_enforceGamutMask && getNumPieces() == 1) ? false : true; return b; } diff --git a/plugins/dockers/artisticcolorselector/kis_color_selector.h b/plugins/dockers/artisticcolorselector/kis_color_selector.h index 49aa887d55..80bf402aef 100644 --- a/plugins/dockers/artisticcolorselector/kis_color_selector.h +++ b/plugins/dockers/artisticcolorselector/kis_color_selector.h @@ -1,208 +1,202 @@ /* Copyright (C) 2011 Silvio Heinrich 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 H_KIS_COLOR_SELECTOR_H #define H_KIS_COLOR_SELECTOR_H #include #include #include #include #include "kis_color.h" #include "kis_radian.h" #include "kis_acs_types.h" #include "kis_signal_compressor_with_param.h" #include #include class QPainter; class KisDisplayColorConverter; class KisColorSelector: public QWidget { Q_OBJECT typedef KisRadian Radian; struct ColorRing { ColorRing() : saturation(0) , outerRadius(0) , innerRadius(0) { } qreal saturation; qreal outerRadius; qreal innerRadius; QVector pieced; }; public: KisColorSelector(QWidget* parent, KisColor::Type type=KisColor::HSL); void setColorSpace(KisColor::Type type); void setColorConverter(KisDisplayColorConverter* colorConverter); void setNumPieces(int num); void setNumLightPieces(int num) __attribute__((optimize(0))); void setNumRings(int num); void setLight(qreal light=0.0f); void setLumaCoefficients(qreal lR, qreal lG, qreal lB, qreal lGamma); inline qreal lumaR() const { return m_lumaR; } inline qreal lumaG() const { return m_lumaG; } inline qreal lumaB() const { return m_lumaB; } inline qreal lumaGamma() const { return m_lumaGamma; } void setInverseSaturation(bool inverse); void selectColor(const KisColor& color); void setFgColor(const KoColor& fgColor); void setBgColor(const KoColor& bgColor); void setDefaultHueSteps(int num); void setDefaultSaturationSteps(int num); void setDefaultValueScaleSteps(int num); - void setShowColorBlip(bool value); void setShowBgColor(bool value); void setShowValueScaleNumbers(bool value); void setGamutMask(KoGamutMask* gamutMask); bool gamutMaskOn(); void setGamutMaskOn(bool gamutMaskOn); void setEnforceGamutMask(bool enforce); KoGamutMask* gamutMask(); - bool maskPreviewActive(); - void setMaskPreviewActive(bool value); - bool saturationIsInvertible(); void saveSettings(); void loadSettings(); KisColor::Type getColorSpace () const { return m_colorSpace; } qint32 getNumRings () const { return m_colorRings.size(); } qint32 getNumPieces () const { return m_numPieces; } qint32 getNumLightPieces () const { return m_numLightPieces; } bool isSaturationInverted() const { return m_inverseSaturation; } quint32 getDefaultHueSteps () const { return m_defaultHueSteps; } quint32 getDefaultSaturationSteps () const { return m_defaultSaturationSteps; } quint32 getDefaultValueScaleSteps () const { return m_defaultValueScaleSteps; } - bool getShowColorBlip () const { return m_showColorBlip; } bool getShowBgColor () const { return m_showBgColor; } bool getShowValueScaleNumbers () const { return m_showValueScaleNumbers; } bool enforceGamutMask () const { return m_enforceGamutMask; } Q_SIGNALS: void sigFgColorChanged(const KisColor& color); void sigBgColorChanged(const KisColor& color); private: void mousePressEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; void resizeEvent(QResizeEvent* event) override; void paintEvent(QPaintEvent* event) override; void leaveEvent(QEvent* e) override; bool colorIsClear(const KisColor &color); bool colorIsClear(const QPointF &colorPoint); void requestUpdateColorAndPreview(const KisColor &color, Acs::ColorRole role); void recalculateAreas(quint8 numLightPieces); void recalculateRings(quint8 numRings, quint8 numPieces); void createRing(ColorRing& wheel, quint8 numPieces, qreal innerRadius, qreal outerRadius); 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) const; qreal getHue(int hueIdx, Radian shift=0.0f) const; qint8 getLightIndex(const QPointF& pt) const; qint8 getLightIndex(qreal light) const; qreal getLight(const QPointF& pt) const; qint8 getSaturationIndex(const QPointF& pt) const; qint8 getSaturationIndex(qreal saturation) const; qreal getSaturation(int saturationIdx) 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(qreal hue) const; public: // This is a private interface for signal compressor, don't use it. // Use requestUpdateColorAndPreview() instead void slotUpdateColorAndPreview(QPair color); private: KisDisplayColorConverter* m_colorConverter; KisColor::Type m_colorSpace; quint8 m_numPieces; quint8 m_numLightPieces; bool m_inverseSaturation; qint8 m_selectedRing; qint8 m_selectedPiece; qint8 m_selectedLightPiece; KisColor m_selectedColor; KisColor m_fgColor; KisColor m_bgColor; QImage m_renderBuffer; QImage m_maskBuffer; QRect m_renderArea; QRect m_lightStripArea; bool m_mouseMoved; QPointF m_clickPos; qint8 m_clickedRing; QVector m_colorRings; Qt::MouseButtons m_pressedButtons; // docker settings quint8 m_defaultHueSteps; quint8 m_defaultSaturationSteps; quint8 m_defaultValueScaleSteps; - bool m_showColorBlip; bool m_showValueScaleNumbers; bool m_showBgColor; bool m_gamutMaskOn; KoGamutMask* m_currentGamutMask; bool m_enforceGamutMask; QSize m_renderAreaSize; bool m_maskPreviewActive; KisGamutMaskViewConverter* m_viewConverter; bool m_widgetUpdatesSelf; qreal m_lumaR; qreal m_lumaG; qreal m_lumaB; qreal m_lumaGamma; typedef KisSignalCompressorWithParam> ColorCompressorType; QScopedPointer m_updateColorCompressor; }; #endif // H_KIS_COLOR_SELECTOR_H