diff --git a/libs/image/kis_layer_properties_icons.cpp b/libs/image/kis_layer_properties_icons.cpp index 583cee6f6f..7cd6c4d1a2 100644 --- a/libs/image/kis_layer_properties_icons.cpp +++ b/libs/image/kis_layer_properties_icons.cpp @@ -1,105 +1,139 @@ /* * Copyright (c) 2015 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_layer_properties_icons.h" #include #include Q_GLOBAL_STATIC(KisLayerPropertiesIcons, s_instance) #include +#include +#include +#include "kis_image.h" const KoID KisLayerPropertiesIcons::locked("locked", ki18n("Locked")); const KoID KisLayerPropertiesIcons::visible("visible", ki18n("Visible")); const KoID KisLayerPropertiesIcons::layerStyle("layer-style", ki18n("Layer Style")); const KoID KisLayerPropertiesIcons::inheritAlpha("inherit-alpha", ki18n("Inherit Alpha")); const KoID KisLayerPropertiesIcons::alphaLocked("alpha-locked", ki18n("Alpha Locked")); const KoID KisLayerPropertiesIcons::onionSkins("onion-skins", ki18n("Onion Skins")); const KoID KisLayerPropertiesIcons::passThrough("pass-through", ki18n("Pass Through")); const KoID KisLayerPropertiesIcons::selectionActive("selection-active", ki18n("Active")); const KoID KisLayerPropertiesIcons::colorLabelIndex("color-label", ki18n("Color Label")); const KoID KisLayerPropertiesIcons::colorizeNeedsUpdate("colorize-needs-update", ki18n("Update Result")); const KoID KisLayerPropertiesIcons::colorizeShowKeyStrokes("colorize-show-key-strokes", ki18n("Show Key Strokes")); const KoID KisLayerPropertiesIcons::colorizeShowColoring("colorize-show-coloring", ki18n("Show Coloring")); struct IconsPair { IconsPair() {} IconsPair(const QIcon &_on, const QIcon &_off) : on(_on), off(_off) {} QIcon on; QIcon off; const QIcon& getIcon(bool state) { return state ? on : off; } }; struct KisLayerPropertiesIcons::Private { QMap icons; }; KisLayerPropertiesIcons::KisLayerPropertiesIcons() : m_d(new Private) { updateIcons(); } KisLayerPropertiesIcons::~KisLayerPropertiesIcons() { } KisLayerPropertiesIcons *KisLayerPropertiesIcons::instance() { return s_instance; } void KisLayerPropertiesIcons::updateIcons() { m_d->icons.clear(); m_d->icons.insert(locked.id(), IconsPair(KisIconUtils::loadIcon("layer-locked"), KisIconUtils::loadIcon("layer-unlocked"))); m_d->icons.insert(visible.id(), IconsPair(KisIconUtils::loadIcon("visible"), KisIconUtils::loadIcon("novisible"))); m_d->icons.insert(layerStyle.id(), IconsPair(KisIconUtils::loadIcon("layer-style-enabled"), KisIconUtils::loadIcon("layer-style-disabled"))); m_d->icons.insert(inheritAlpha.id(), IconsPair(KisIconUtils::loadIcon("transparency-disabled"), KisIconUtils::loadIcon("transparency-enabled"))); m_d->icons.insert(alphaLocked.id(), IconsPair(KisIconUtils::loadIcon("transparency-locked"), KisIconUtils::loadIcon("transparency-unlocked"))); m_d->icons.insert(onionSkins.id(), IconsPair(KisIconUtils::loadIcon("onionOn"), KisIconUtils::loadIcon("onionOff"))); m_d->icons.insert(passThrough.id(), IconsPair(KisIconUtils::loadIcon("passthrough-enabled"), KisIconUtils::loadIcon("passthrough-disabled"))); m_d->icons.insert(selectionActive.id(), IconsPair(KisIconUtils::loadIcon("local_selection_active"), KisIconUtils::loadIcon("local_selection_inactive"))); m_d->icons.insert(colorizeNeedsUpdate.id(), IconsPair(KisIconUtils::loadIcon("updateColorize"), KisIconUtils::loadIcon("updateColorize"))); m_d->icons.insert(colorizeShowKeyStrokes.id(), IconsPair(KisIconUtils::loadIcon("showMarks"), KisIconUtils::loadIcon("showMarksOff"))); m_d->icons.insert(colorizeShowColoring.id(), IconsPair(KisIconUtils::loadIcon("showColoring"), KisIconUtils::loadIcon("showColoringOff"))); } KisBaseNode::Property KisLayerPropertiesIcons::getProperty(const KoID &id, bool state) { const IconsPair &pair = instance()->m_d->icons[id.id()]; return KisBaseNode::Property(id, pair.on, pair.off, state); } KisBaseNode::Property KisLayerPropertiesIcons::getProperty(const KoID &id, bool state, bool isInStasis, bool stateInStasis) { const IconsPair &pair = instance()->m_d->icons[id.id()]; return KisBaseNode::Property(id, pair.on, pair.off, state, isInStasis, stateInStasis); } + +void KisLayerPropertiesIcons::setNodeProperty(KisNodeSP node, const KoID &id, const QVariant &value, KisImageSP image) +{ + KisBaseNode::PropertyList props = node->sectionModelProperties(); + + KisBaseNode::PropertyList::iterator it = props.begin(); + KisBaseNode::PropertyList::iterator end = props.end(); + for (; it != end; ++it) { + if (it->id == id.id()) { + it->state = value; + break; + } + } + + KisNodePropertyListCommand::setNodePropertiesNoUndo(node, image, props); +} + +QVariant KisLayerPropertiesIcons::nodeProperty(KisNodeSP node, const KoID &id, const QVariant &defaultValue) +{ + KisBaseNode::PropertyList props = node->sectionModelProperties(); + + KisBaseNode::PropertyList::const_iterator it = props.constBegin(); + KisBaseNode::PropertyList::const_iterator end = props.constEnd(); + for (; it != end; ++it) { + if (it->id == id.id()) { + return it->state; + } + } + + return defaultValue; +} diff --git a/libs/image/kis_layer_properties_icons.h b/libs/image/kis_layer_properties_icons.h index 39fc63c54a..1c8adfab68 100644 --- a/libs/image/kis_layer_properties_icons.h +++ b/libs/image/kis_layer_properties_icons.h @@ -1,61 +1,71 @@ /* * Copyright (c) 2015 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __KIS_LAYER_PROPERTIES_ICONS_H #define __KIS_LAYER_PROPERTIES_ICONS_H #include #include #include #include "kritaimage_export.h" class KRITAIMAGE_EXPORT KisLayerPropertiesIcons { public: KisLayerPropertiesIcons(); ~KisLayerPropertiesIcons(); static const KoID locked; static const KoID visible; static const KoID layerStyle; static const KoID inheritAlpha; static const KoID alphaLocked; static const KoID onionSkins; static const KoID passThrough; static const KoID selectionActive; static const KoID colorLabelIndex; static const KoID colorizeNeedsUpdate; static const KoID colorizeShowKeyStrokes; static const KoID colorizeShowColoring; static KisLayerPropertiesIcons* instance(); static KisBaseNode::Property getProperty(const KoID &id, bool state); static KisBaseNode::Property getProperty(const KoID &id, bool state, bool isInStasis, bool stateInStasis); + /** + * Sets the specified property of the node and updates it + */ + static void setNodeProperty(KisNodeSP node, const KoID &id, const QVariant &value, KisImageSP image); + + /** + * Gets the specified property of the node + */ + static QVariant nodeProperty(KisNodeSP node, const KoID &id, const QVariant &defaultValue); + private: void updateIcons(); private: struct Private; const QScopedPointer m_d; }; #endif /* __KIS_LAYER_PROPERTIES_ICONS_H */ diff --git a/libs/image/kis_types.h b/libs/image/kis_types.h index 243fc63e3d..5412f2e156 100644 --- a/libs/image/kis_types.h +++ b/libs/image/kis_types.h @@ -1,265 +1,269 @@ /* * Copyright (c) 2002 Patrick Julien * * 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 KISTYPES_H_ #define KISTYPES_H_ #include #include #include #include "kritaimage_export.h" template class KisWeakSharedPtr; template class KisSharedPtr; template class QSharedPointer; template class QWeakPointer; template uint qHash(KisSharedPtr ptr) { return qHash(ptr.data()); } template uint qHash(KisWeakSharedPtr ptr) { return qHash(ptr.data()); } /** * Define lots of shared pointer versions of Krita classes. * Shared pointer classes have the advantage of near automatic * memory management (but beware of circular references) * and the disadvantage that inheritiance relations are no longer * recognizable */ class KisImage; typedef KisSharedPtr KisImageSP; typedef KisWeakSharedPtr KisImageWSP; class KisPaintDevice; typedef KisSharedPtr KisPaintDeviceSP; typedef KisWeakSharedPtr KisPaintDeviceWSP; typedef QVector vKisPaintDeviceSP; typedef vKisPaintDeviceSP::iterator vKisPaintDeviceSP_it; class KisFixedPaintDevice; typedef KisSharedPtr KisFixedPaintDeviceSP; class KisMask; typedef KisSharedPtr KisMaskSP; typedef KisWeakSharedPtr KisMaskWSP; class KisNode; typedef KisSharedPtr KisNodeSP; typedef KisWeakSharedPtr KisNodeWSP; typedef QVector vKisNodeSP; typedef vKisNodeSP::iterator vKisNodeSP_it; typedef vKisNodeSP::const_iterator vKisNodeSP_cit; class KisBaseNode; typedef KisSharedPtr KisBaseNodeSP; typedef KisWeakSharedPtr KisBaseNodeWSP; class KisEffectMask; typedef KisSharedPtr KisEffectMaskSP; typedef KisWeakSharedPtr KisEffectMaskWSP; class KisFilterMask; typedef KisSharedPtr KisFilterMaskSP; typedef KisWeakSharedPtr KisFilterMaskWSP; class KisTransformMask; typedef KisSharedPtr KisTransformMaskSP; typedef KisWeakSharedPtr KisTransformMaskWSP; class KisTransformMaskParamsInterface; typedef QSharedPointer KisTransformMaskParamsInterfaceSP; typedef QWeakPointer KisTransformMaskParamsInterfaceWSP; class KisTransparencyMask; typedef KisSharedPtr KisTransparencyMaskSP; typedef KisWeakSharedPtr KisTransparencyMaskWSP; +class KisColorizeMask; +typedef KisSharedPtr KisColorizeMaskSP; +typedef KisWeakSharedPtr KisColorizeMaskWSP; + class KisLayer; typedef KisSharedPtr KisLayerSP; typedef KisWeakSharedPtr KisLayerWSP; class KisShapeLayer; typedef KisSharedPtr KisShapeLayerSP; class KisPaintLayer; typedef KisSharedPtr KisPaintLayerSP; class KisAdjustmentLayer; typedef KisSharedPtr KisAdjustmentLayerSP; class KisGeneratorLayer; typedef KisSharedPtr KisGeneratorLayerSP; class KisCloneLayer; typedef KisSharedPtr KisCloneLayerSP; typedef KisWeakSharedPtr KisCloneLayerWSP; class KisGroupLayer; typedef KisSharedPtr KisGroupLayerSP; typedef KisWeakSharedPtr KisGroupLayerWSP; class KisSelection; typedef KisSharedPtr KisSelectionSP; typedef KisWeakSharedPtr KisSelectionWSP; class KisSelectionComponent; typedef KisSharedPtr KisSelectionComponentSP; class KisBackground; typedef KisSharedPtr KisBackgroundSP; class KisSelectionMask; typedef KisSharedPtr KisSelectionMaskSP; class KisPixelSelection; typedef KisSharedPtr KisPixelSelectionSP; class KisHistogram; typedef KisSharedPtr KisHistogramSP; typedef QVector vKisSegments; class KisFilter; typedef KisSharedPtr KisFilterSP; class KisLayerStyleFilter; typedef KisSharedPtr KisLayerStyleFilterSP; class KisGenerator; typedef KisSharedPtr KisGeneratorSP; class KisConvolutionKernel; typedef KisSharedPtr KisConvolutionKernelSP; class KisAnnotation; typedef KisSharedPtr KisAnnotationSP; typedef QVector vKisAnnotationSP; typedef vKisAnnotationSP::iterator vKisAnnotationSP_it; typedef vKisAnnotationSP::const_iterator vKisAnnotationSP_cit; class KisAnimationFrameCache; typedef KisSharedPtr KisAnimationFrameCacheSP; typedef KisWeakSharedPtr KisAnimationFrameCacheWSP; class KisPaintingAssistant; typedef QSharedPointer KisPaintingAssistantSP; typedef QWeakPointer KisPaintingAssistantWSP; // Repeat iterators class KisHLineIterator2; template class KisRepeatHLineIteratorPixelBase; typedef KisRepeatHLineIteratorPixelBase< KisHLineIterator2 > KisRepeatHLineConstIteratorNG; typedef KisSharedPtr KisRepeatHLineConstIteratorSP; class KisVLineIterator2; template class KisRepeatVLineIteratorPixelBase; typedef KisRepeatVLineIteratorPixelBase< KisVLineIterator2 > KisRepeatVLineConstIteratorNG; typedef KisSharedPtr KisRepeatVLineConstIteratorSP; // NG Iterators class KisHLineIteratorNG; typedef KisSharedPtr KisHLineIteratorSP; class KisHLineConstIteratorNG; typedef KisSharedPtr KisHLineConstIteratorSP; class KisVLineIteratorNG; typedef KisSharedPtr KisVLineIteratorSP; class KisVLineConstIteratorNG; typedef KisSharedPtr KisVLineConstIteratorSP; class KisRandomConstAccessorNG; typedef KisSharedPtr KisRandomConstAccessorSP; class KisRandomAccessorNG; typedef KisSharedPtr KisRandomAccessorSP; class KisRandomSubAccessor; typedef KisSharedPtr KisRandomSubAccessorSP; // Things typedef QVector vQPointF; class KisPaintOpPreset; typedef KisSharedPtr KisPaintOpPresetSP; typedef KisWeakSharedPtr KisPaintOpPresetWSP; class KisPaintOpSettings; typedef KisSharedPtr KisPaintOpSettingsSP; class KisPaintOp; typedef KisSharedPtr KisPaintOpSP; class KoID; typedef QList KoIDList; class KoUpdater; template class QPointer; typedef QPointer KoUpdaterPtr; class KisProcessingVisitor; typedef KisSharedPtr KisProcessingVisitorSP; class KUndo2Command; typedef QSharedPointer KUndo2CommandSP; typedef QList KisNodeList; typedef QSharedPointer KisNodeListSP; typedef QList KisPaintDeviceList; class KisStroke; typedef QSharedPointer KisStrokeSP; typedef QWeakPointer KisStrokeWSP; typedef KisStrokeWSP KisStrokeId; class KisFilterConfiguration; typedef QSharedPointer KisSafeFilterConfigurationSP; class KisProjectionUpdatesFilter; typedef QSharedPointer KisProjectionUpdatesFilterSP; class KisAbstractProjectionPlane; typedef QSharedPointer KisAbstractProjectionPlaneSP; typedef QWeakPointer KisAbstractProjectionPlaneWSP; class KisProjectionLeaf; typedef QSharedPointer KisProjectionLeafSP; typedef QWeakPointer KisProjectionLeafWSP; class KisKeyframe; typedef QSharedPointer KisKeyframeSP; typedef QWeakPointer KisKeyframeWSP; #include #include #include #endif // KISTYPES_H_ diff --git a/libs/image/lazybrush/kis_colorize_mask.cpp b/libs/image/lazybrush/kis_colorize_mask.cpp index 602d6ca6f4..41c3247668 100644 --- a/libs/image/lazybrush/kis_colorize_mask.cpp +++ b/libs/image/lazybrush/kis_colorize_mask.cpp @@ -1,564 +1,661 @@ /* * Copyright (c) 2016 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_colorize_mask.h" #include #include #include "kis_pixel_selection.h" #include "kis_icon_utils.h" #include "kis_node_visitor.h" #include "kis_processing_visitor.h" #include "kis_painter.h" #include "kis_fill_painter.h" #include "kis_lazy_fill_tools.h" #include "kis_cached_paint_device.h" #include "kis_paint_device_debug_utils.h" #include "kis_layer_properties_icons.h" #include "kis_signal_compressor.h" #include "kis_colorize_job.h" #include "kis_multiway_cut.h" #include "kis_image.h" #include "kis_layer.h" #include "kis_macro_based_undo_store.h" #include "kis_post_execution_undo_adapter.h" #include "kis_command_utils.h" +#include "kis_processing_applicator.h" using namespace KisLazyFillTools; struct KisColorizeMask::Private { Private() : needAddCurrentKeyStroke(false), showKeyStrokes(true), showColoring(true), needsUpdate(true), updateCompressor(1000, KisSignalCompressor::POSTPONE) { } Private(const Private &rhs) : needAddCurrentKeyStroke(rhs.needAddCurrentKeyStroke), showKeyStrokes(rhs.showKeyStrokes), showColoring(rhs.showColoring), cachedSelection(), needsUpdate(false), updateCompressor(1000, KisSignalCompressor::POSTPONE) { } QList keyStrokes; KisPaintDeviceSP coloringProjection; KisPaintDeviceSP fakePaintDevice; KisPaintDeviceSP filteredSource; KoColor currentColor; KisPaintDeviceSP currentKeyStrokeDevice; bool needAddCurrentKeyStroke; bool showKeyStrokes; bool showColoring; KisCachedSelection cachedSelection; KisCachedSelection cachedConversionSelection; bool needsUpdate; KisSignalCompressor updateCompressor; }; KisColorizeMask::KisColorizeMask() : m_d(new Private) { // TODO: correct initialization of the layer's color space m_d->fakePaintDevice = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8()); connect(&m_d->updateCompressor, SIGNAL(timeout()), SLOT(slotUpdateRegenerateFilling())); m_d->updateCompressor.moveToThread(qApp->thread()); } KisColorizeMask::~KisColorizeMask() { } KisColorizeMask::KisColorizeMask(const KisColorizeMask& rhs) : KisEffectMask(rhs), m_d(new Private(*rhs.m_d)) { connect(&m_d->updateCompressor, SIGNAL(timeout()), SLOT(slotUpdateRegenerateFilling())); m_d->updateCompressor.moveToThread(qApp->thread()); } bool KisColorizeMask::needsUpdate() const { return m_d->needsUpdate; } void KisColorizeMask::setNeedsUpdate(bool value) { if (value != m_d->needsUpdate) { m_d->needsUpdate = value; baseNodeChangedCallback(); if (!value) { m_d->updateCompressor.start(); } } } void KisColorizeMask::slotUpdateRegenerateFilling() { KisPaintDeviceSP src = parent()->original(); KIS_ASSERT_RECOVER_RETURN(src); if (!m_d->coloringProjection) { m_d->coloringProjection = new KisPaintDevice(src->colorSpace()); m_d->filteredSource = new KisPaintDevice(src->colorSpace()); } else { // TODO: sync colorspaces m_d->coloringProjection->clear(); m_d->filteredSource->clear(); } KisLayerSP parentLayer = dynamic_cast(parent().data()); if (!parentLayer) return; KisImageSP image = parentLayer->image(); if (image) { KisColorizeJob *job = new KisColorizeJob(src, m_d->coloringProjection, m_d->filteredSource, image->bounds()); Q_FOREACH (const KeyStroke &stroke, m_d->keyStrokes) { - job->addKeyStroke(stroke.dev, stroke.color); + const KoColor color = + !stroke.isTransparent ? + stroke.color : + KoColor(Qt::transparent, stroke.color.colorSpace()); + + job->addKeyStroke(stroke.dev, color); } connect(job, SIGNAL(sigFinished()), SLOT(slotRegenerationFinished())); image->addSpontaneousJob(job); } } void KisColorizeMask::slotRegenerationFinished() { setNeedsUpdate(true); setDirty(); } KisBaseNode::PropertyList KisColorizeMask::sectionModelProperties() const { KisBaseNode::PropertyList l = KisMask::sectionModelProperties(); l << KisLayerPropertiesIcons::getProperty(KisLayerPropertiesIcons::colorizeNeedsUpdate, needsUpdate()); l << KisLayerPropertiesIcons::getProperty(KisLayerPropertiesIcons::colorizeShowKeyStrokes, showKeyStrokes()); l << KisLayerPropertiesIcons::getProperty(KisLayerPropertiesIcons::colorizeShowColoring, showColoring()); return l; } void KisColorizeMask::setSectionModelProperties(const KisBaseNode::PropertyList &properties) { KisMask::setSectionModelProperties(properties); Q_FOREACH (const KisBaseNode::Property &property, properties) { if (property.id == KisLayerPropertiesIcons::colorizeNeedsUpdate.id()) { if (m_d->needsUpdate != property.state.toBool()) { setNeedsUpdate(property.state.toBool()); } } if (property.id == KisLayerPropertiesIcons::colorizeShowKeyStrokes.id()) { if (m_d->showKeyStrokes != property.state.toBool()) { setShowKeyStrokes(property.state.toBool()); } } if (property.id == KisLayerPropertiesIcons::colorizeShowColoring.id()) { if (m_d->showColoring != property.state.toBool()) { setShowColoring(property.state.toBool()); } } } } KisPaintDeviceSP KisColorizeMask::paintDevice() const { return m_d->showKeyStrokes ? m_d->fakePaintDevice : 0; } QIcon KisColorizeMask::icon() const { return KisIconUtils::loadIcon("filterMask"); } bool KisColorizeMask::accept(KisNodeVisitor &v) { return v.visit(this); } void KisColorizeMask::accept(KisProcessingVisitor &visitor, KisUndoAdapter *undoAdapter) { return visitor.visit(this, undoAdapter); } QRect KisColorizeMask::decorateRect(KisPaintDeviceSP &src, KisPaintDeviceSP &dst, const QRect &rect, PositionToFilthy maskPos) const { Q_UNUSED(maskPos); KIS_ASSERT(dst != src); // Draw the filling and the original layer { KisPainter gc(dst); if (m_d->showKeyStrokes) { gc.setOpacity(128); } if (m_d->showColoring && m_d->coloringProjection) { gc.bitBlt(rect.topLeft(), m_d->coloringProjection, rect); } if (m_d->showKeyStrokes && m_d->filteredSource && !m_d->filteredSource->extent().isEmpty()) { // TODO: the filtered source should be converted back into alpha! gc.setOpacity(128); gc.bitBlt(rect.topLeft(), m_d->filteredSource, rect); } else { gc.setOpacity(255); gc.bitBlt(rect.topLeft(), src, rect); } } // Draw the key strokes if (m_d->showKeyStrokes) { lockTemporaryTarget(); KisSelectionSP selection = m_d->cachedSelection.getSelection(); KisSelectionSP conversionSelection = m_d->cachedConversionSelection.getSelection(); KisPixelSelectionSP tempSelection = conversionSelection->pixelSelection(); KisPaintDeviceSP temporaryTarget = this->temporaryTarget(); const bool isTemporaryTargetErasing = temporaryCompositeOp() == COMPOSITE_ERASE; const QRect temporaryExtent = temporaryTarget ? temporaryTarget->extent() : QRect(); KisFillPainter gc(dst); QList extendedStrokes = m_d->keyStrokes; if (m_d->currentKeyStrokeDevice && m_d->needAddCurrentKeyStroke && !isTemporaryTargetErasing) { extendedStrokes << KeyStroke(m_d->currentKeyStrokeDevice, m_d->currentColor); } Q_FOREACH (const KeyStroke &stroke, extendedStrokes) { selection->pixelSelection()->makeCloneFromRough(stroke.dev, rect); gc.setSelection(selection); if (stroke.color == m_d->currentColor || (isTemporaryTargetErasing && temporaryExtent.intersects(selection->pixelSelection()->selectedRect()))) { if (temporaryTarget) { tempSelection->copyAlphaFrom(temporaryTarget, rect); KisPainter selectionPainter(selection->pixelSelection()); setupTemporaryPainter(&selectionPainter); selectionPainter.bitBlt(rect.topLeft(), tempSelection, rect); } } gc.fillSelection(rect, stroke.color); } m_d->cachedSelection.putSelection(selection); m_d->cachedSelection.putSelection(conversionSelection); unlockTemporaryTarget(); } return rect; } QRect KisColorizeMask::extent() const { QRect rc; // TODO: take care about the filtered device, which can be painted // semi-transparent sometimes if (m_d->showColoring && m_d->coloringProjection) { rc |= m_d->coloringProjection->extent(); } if (m_d->showKeyStrokes) { Q_FOREACH (const KeyStroke &stroke, m_d->keyStrokes) { rc |= stroke.dev->extent(); } lockTemporaryTarget(); KisPaintDeviceSP temporaryTarget = this->temporaryTarget(); if (temporaryTarget) { rc |= temporaryTarget->extent(); } unlockTemporaryTarget(); } return rc; } QRect KisColorizeMask::exactBounds() const { QRect rc; if (m_d->showColoring && m_d->coloringProjection) { rc |= m_d->coloringProjection->exactBounds(); } if (m_d->showKeyStrokes) { Q_FOREACH (const KeyStroke &stroke, m_d->keyStrokes) { rc |= stroke.dev->exactBounds(); } lockTemporaryTarget(); KisPaintDeviceSP temporaryTarget = this->temporaryTarget(); if (temporaryTarget) { rc |= temporaryTarget->exactBounds(); } unlockTemporaryTarget(); } return rc; } KisImageSP KisColorizeMask::fetchImage() const { KisLayerSP parentLayer = dynamic_cast(parent().data()); if (!parentLayer) return 0; return parentLayer->image(); } void KisColorizeMask::setImage(KisImageWSP image) { auto it = m_d->keyStrokes.begin(); for(; it != m_d->keyStrokes.end(); ++it) { it->dev->setDefaultBounds(new KisDefaultBounds(image)); } } void KisColorizeMask::setCurrentColor(const KoColor &color) { lockTemporaryTargetForWrite(); setNeedsUpdate(true); QList::const_iterator it = std::find_if(m_d->keyStrokes.constBegin(), m_d->keyStrokes.constEnd(), [color] (const KeyStroke &s) { return s.color == color; }); KisPaintDeviceSP activeDevice; bool newKeyStroke = false; if (it == m_d->keyStrokes.constEnd()) { activeDevice = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha8()); activeDevice->setParentNode(this); activeDevice->setDefaultBounds(new KisDefaultBounds(fetchImage())); newKeyStroke = true; } else { activeDevice = it->dev; } m_d->currentColor = color; m_d->currentKeyStrokeDevice = activeDevice; m_d->needAddCurrentKeyStroke = newKeyStroke; m_d->fakePaintDevice->convertTo(colorSpace()); unlockTemporaryTarget(); } struct KeyStrokeAddRemoveCommand : public KisCommandUtils::FlipFlopCommand { - KeyStrokeAddRemoveCommand(bool add, int index, KeyStroke stroke, QList *list, KisNodeSP node) + KeyStrokeAddRemoveCommand(bool add, int index, KeyStroke stroke, QList *list, KisColorizeMaskSP node) : FlipFlopCommand(!add), m_index(index), m_stroke(stroke), m_list(list), m_node(node) {} void init() { m_list->insert(m_index, m_stroke); + emit m_node->sigKeyStrokesListChanged(); } void end() { KIS_ASSERT_RECOVER_RETURN((*m_list)[m_index] == m_stroke); m_list->removeAt(m_index); + emit m_node->sigKeyStrokesListChanged(); } private: int m_index; KeyStroke m_stroke; QList *m_list; - // just a pointer to keep the node from deleting - KisNodeSP m_node; + KisColorizeMaskSP m_node; }; void KisColorizeMask::mergeToLayer(KisNodeSP layer, KisPostExecutionUndoAdapter *undoAdapter, const KUndo2MagicString &transactionText,int timedID) { Q_UNUSED(layer); KisPaintDeviceSP temporaryTarget = this->temporaryTarget(); const bool isTemporaryTargetErasing = temporaryCompositeOp() == COMPOSITE_ERASE; const QRect temporaryExtent = temporaryTarget ? temporaryTarget->extent() : QRect(); KisSavedMacroCommand *macro = undoAdapter->createMacro(transactionText); KisMacroBasedUndoStore store(macro); KisPostExecutionUndoAdapter fakeUndoAdapter(&store, undoAdapter->strokesFacade()); /** * Add a new key stroke plane */ if (m_d->needAddCurrentKeyStroke && !isTemporaryTargetErasing) { KeyStroke key(m_d->currentKeyStrokeDevice, m_d->currentColor); KUndo2Command *cmd = new KeyStrokeAddRemoveCommand( - true, m_d->keyStrokes.size(), key, &m_d->keyStrokes, layer); + true, m_d->keyStrokes.size(), key, &m_d->keyStrokes, this); cmd->redo(); fakeUndoAdapter.addCommand(toQShared(cmd)); } /** * When erasing, the brush affects all the key strokes, not only * the current one. */ if (!isTemporaryTargetErasing) { mergeToLayerImpl(m_d->currentKeyStrokeDevice, &fakeUndoAdapter, transactionText, timedID, false); } else { Q_FOREACH (const KeyStroke &stroke, m_d->keyStrokes) { if (temporaryExtent.intersects(stroke.dev->extent())) { mergeToLayerImpl(stroke.dev, &fakeUndoAdapter, transactionText, timedID, false); } } } mergeToLayerImpl(m_d->fakePaintDevice, &fakeUndoAdapter, transactionText, timedID, false); m_d->currentKeyStrokeDevice = 0; m_d->currentColor = KoColor(); releaseResources(); /** * Try removing the key strokes that has been completely erased */ if (isTemporaryTargetErasing) { lockTemporaryTargetForWrite(); - int index = 0; - auto it = m_d->keyStrokes.begin(); - while (it != m_d->keyStrokes.end()) { - if (it->dev->exactBounds().isEmpty()) { - fakeUndoAdapter.addCommand( - toQShared( - new KeyStrokeAddRemoveCommand( - false, index, *it, &m_d->keyStrokes, layer))); - it = m_d->keyStrokes.erase(it); + for (int index = 0; index < m_d->keyStrokes.size(); /*noop*/) { + const KeyStroke &stroke = m_d->keyStrokes[index]; + + if (stroke.dev->exactBounds().isEmpty()) { + KUndo2Command *cmd = + new KeyStrokeAddRemoveCommand( + false, index, stroke, &m_d->keyStrokes, this); + + cmd->redo(); + fakeUndoAdapter.addCommand(toQShared(cmd)); + } else { - ++it; - ++index; + index++; } } unlockTemporaryTarget(); } undoAdapter->addMacro(macro); } void KisColorizeMask::writeMergeData(KisPainter *painter, KisPaintDeviceSP src) { const KoColorSpace *alpha8 = KoColorSpaceRegistry::instance()->alpha8(); const bool nonAlphaDst = !(*painter->device()->colorSpace() == *alpha8); if (nonAlphaDst) { Q_FOREACH (const QRect &rc, src->region().rects()) { painter->bitBlt(rc.topLeft(), src, rc); } } else { KisSelectionSP conversionSelection = m_d->cachedConversionSelection.getSelection(); KisPixelSelectionSP tempSelection = conversionSelection->pixelSelection(); Q_FOREACH (const QRect &rc, src->region().rects()) { tempSelection->copyAlphaFrom(src, rc); painter->bitBlt(rc.topLeft(), tempSelection, rc); } m_d->cachedSelection.putSelection(conversionSelection); } } bool KisColorizeMask::showColoring() const { return m_d->showColoring; } void KisColorizeMask::setShowColoring(bool value) { QRect savedExtent; if (m_d->showColoring && !value) { savedExtent = extent(); } m_d->showColoring = value; if (!savedExtent.isEmpty()) { setDirty(savedExtent); } } bool KisColorizeMask::showKeyStrokes() const { return m_d->showKeyStrokes; } void KisColorizeMask::setShowKeyStrokes(bool value) { QRect savedExtent; if (m_d->showKeyStrokes && !value) { savedExtent = extent(); } m_d->showKeyStrokes = value; if (!savedExtent.isEmpty()) { setDirty(savedExtent); } } +KisColorizeMask::KeyStrokeColors KisColorizeMask::keyStrokesColors() const +{ + KeyStrokeColors colors; + + // TODO: thread safety! + for (int i = 0; i < m_d->keyStrokes.size(); i++) { + colors.colors << m_d->keyStrokes[i].color; + + if (m_d->keyStrokes[i].isTransparent) { + colors.transparentIndex = i; + } + } + + return colors; +} + +struct SetKeyStrokeColorsCommand : public KUndo2Command { + SetKeyStrokeColorsCommand(const QList newList, QList *list, KisColorizeMaskSP node) + : m_newList(newList), + m_oldList(*list), + m_list(list), + m_node(node) {} + + void redo() { + *m_list = m_newList; + + emit m_node->sigKeyStrokesListChanged(); + m_node->setDirty(); + } + + void undo() { + *m_list = m_oldList; + + emit m_node->sigKeyStrokesListChanged(); + m_node->setDirty(); + } + +private: + QList m_newList; + QList m_oldList; + QList *m_list; + KisColorizeMaskSP m_node; +}; + +void KisColorizeMask::setKeyStrokesColors(KeyStrokeColors colors) +{ + KIS_ASSERT_RECOVER_RETURN(colors.colors.size() == m_d->keyStrokes.size()); + + QList newList = m_d->keyStrokes; + + for (int i = 0; i < newList.size(); i++) { + newList[i].color = colors.colors[i]; + newList[i].isTransparent = colors.transparentIndex == i; + } + + KisProcessingApplicator applicator(fetchImage(), this, + KisProcessingApplicator::NONE, + KisImageSignalVector(), + kundo2_i18n("Change Key Stroke Color")); + applicator.applyCommand( + new SetKeyStrokeColorsCommand( + newList, &m_d->keyStrokes, this)); + + applicator.end(); +} + +void KisColorizeMask::removeKeyStroke(const KoColor &color) +{ + QList::iterator it = + std::find_if(m_d->keyStrokes.begin(), + m_d->keyStrokes.end(), + [color] (const KeyStroke &s) { + return s.color == color; + }); + + KIS_SAFE_ASSERT_RECOVER_RETURN(it != m_d->keyStrokes.end()); + + const int index = it - m_d->keyStrokes.begin(); + + KisProcessingApplicator applicator(fetchImage(), this, + KisProcessingApplicator::NONE, + KisImageSignalVector(), + kundo2_i18n("Remove Key Stroke")); + applicator.applyCommand( + new KeyStrokeAddRemoveCommand( + false, index, *it, &m_d->keyStrokes, this)); + + applicator.end(); +} diff --git a/libs/image/lazybrush/kis_colorize_mask.h b/libs/image/lazybrush/kis_colorize_mask.h index e672563cf3..4cf8c2f451 100644 --- a/libs/image/lazybrush/kis_colorize_mask.h +++ b/libs/image/lazybrush/kis_colorize_mask.h @@ -1,89 +1,105 @@ /* * Copyright (c) 2016 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __KIS_COLORIZE_MASK_H #define __KIS_COLORIZE_MASK_H #include #include "kis_types.h" #include "kis_effect_mask.h" #include "kritaimage_export.h" class KoColor; class KRITAIMAGE_EXPORT KisColorizeMask : public KisEffectMask { Q_OBJECT +public: + struct KeyStrokeColors { + QVector colors; + int transparentIndex; + }; + public: KisColorizeMask(); ~KisColorizeMask(); KisColorizeMask(const KisColorizeMask& rhs); KisPaintDeviceSP paintDevice() const; KisNodeSP clone() const { return KisNodeSP(new KisColorizeMask(*this)); } QIcon icon() const; void setImage(KisImageWSP image); bool accept(KisNodeVisitor &v); void accept(KisProcessingVisitor &visitor, KisUndoAdapter *undoAdapter); QRect decorateRect(KisPaintDeviceSP &src, KisPaintDeviceSP &dst, const QRect & rc, PositionToFilthy maskPos) const; void setCurrentColor(const KoColor &color); void mergeToLayer(KisNodeSP layer, KisPostExecutionUndoAdapter *undoAdapter, const KUndo2MagicString &transactionText,int timedID); void writeMergeData(KisPainter *painter, KisPaintDeviceSP src); QRect exactBounds() const; QRect extent() const; + void setSectionModelProperties(const KisBaseNode::PropertyList &properties); + KisBaseNode::PropertyList sectionModelProperties() const; + + KeyStrokeColors keyStrokesColors() const; + void setKeyStrokesColors(KeyStrokeColors colors); + + void removeKeyStroke(const KoColor &color); + +private Q_SLOTS: + void slotUpdateRegenerateFilling(); + void slotRegenerationFinished(); + +Q_SIGNALS: + void sigKeyStrokesListChanged(); + +private: + // NOTE: please access this methods using model properties only! + bool needsUpdate() const; void setNeedsUpdate(bool value); bool showColoring() const; void setShowColoring(bool value); bool showKeyStrokes() const; void setShowKeyStrokes(bool value); - void setSectionModelProperties(const KisBaseNode::PropertyList &properties); - KisBaseNode::PropertyList sectionModelProperties() const; - - -private Q_SLOTS: - void slotUpdateRegenerateFilling(); - void slotRegenerationFinished(); - private: KisImageSP fetchImage() const; private: struct Private; const QScopedPointer m_d; }; #endif /* __KIS_COLORIZE_MASK_H */ diff --git a/libs/image/lazybrush/kis_lazy_fill_tools.cpp b/libs/image/lazybrush/kis_lazy_fill_tools.cpp index 9007132e1f..7d0425a451 100644 --- a/libs/image/lazybrush/kis_lazy_fill_tools.cpp +++ b/libs/image/lazybrush/kis_lazy_fill_tools.cpp @@ -1,171 +1,175 @@ /* * Copyright (c) 2016 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_lazy_fill_tools.h" #include #include #include #include #include #include #include #include #include #include "lazybrush/kis_lazy_fill_graph.h" #include "lazybrush/kis_lazy_fill_capacity_map.h" #include "kis_sequential_iterator.h" #include #include "krita_utils.h" namespace KisLazyFillTools { void normalizeAndInvertAlpha8Device(KisPaintDeviceSP dev, const QRect &rect) { quint8 maxPixel = std::numeric_limits::min(); quint8 minPixel = std::numeric_limits::max(); KritaUtils::applyToAlpha8Device(dev, rect, [&minPixel, &maxPixel](quint8 pixel) { if (pixel > maxPixel) { maxPixel = pixel; } if (pixel < minPixel) { minPixel = pixel; } }); const qreal scale = 255.0 / (maxPixel - minPixel); KritaUtils::filterAlpha8Device(dev, rect, [minPixel, scale](quint8 pixel) { return pow2(255 - quint8((pixel - minPixel) * scale)) / 255; }); } void cutOneWay(const KoColor &color, KisPaintDeviceSP src, KisPaintDeviceSP colorScribble, KisPaintDeviceSP backgroundScribble, KisPaintDeviceSP resultDevice, KisPaintDeviceSP maskDevice, const QRect &boundingRect) { using namespace boost; KIS_ASSERT_RECOVER_RETURN(src->pixelSize() == 1); KIS_ASSERT_RECOVER_RETURN(colorScribble->pixelSize() == 1); KIS_ASSERT_RECOVER_RETURN(backgroundScribble->pixelSize() == 1); KIS_ASSERT_RECOVER_RETURN(maskDevice->pixelSize() == 1); KIS_ASSERT_RECOVER_RETURN(*resultDevice->colorSpace() == *color.colorSpace()); KisLazyFillCapacityMap capacityMap(src, colorScribble, backgroundScribble, maskDevice, boundingRect); KisLazyFillGraph &graph = capacityMap.graph(); std::vector groups(num_vertices(graph)); std::vector residual_capacity(num_edges(graph), 0); std::vector::vertices_size_type> distance_vec(num_vertices(graph), 0); std::vector::edge_descriptor> predecessor_vec(num_vertices(graph)); auto vertexIndexMap = get(boost::vertex_index, graph); typedef KisLazyFillGraph::vertex_descriptor Vertex; Vertex s(Vertex::LABEL_A); Vertex t(Vertex::LABEL_B); float maxFlow = boykov_kolmogorov_max_flow(graph, capacityMap, make_iterator_property_map(&residual_capacity[0], get(boost::edge_index, graph)), get(boost::edge_reverse, graph), make_iterator_property_map(&predecessor_vec[0], vertexIndexMap), make_iterator_property_map(&groups[0], vertexIndexMap), make_iterator_property_map(&distance_vec[0], vertexIndexMap), vertexIndexMap, s, t); Q_UNUSED(maxFlow); KisSequentialIterator dstIt(resultDevice, graph.rect()); KisSequentialIterator mskIt(maskDevice, graph.rect()); const int pixelSize = resultDevice->pixelSize(); do { KisLazyFillGraph::vertex_descriptor v(dstIt.x(), dstIt.y()); long vertex_idx = get(boost::vertex_index, graph, v); default_color_type label = groups[vertex_idx]; if (label == black_color) { memcpy(dstIt.rawData(), color.data(), pixelSize); *mskIt.rawData() = 10 + (int(label) << 4); } } while (dstIt.nextPixel() && mskIt.nextPixel()); } QVector splitIntoConnectedComponents(KisPaintDeviceSP dev, const QRect &boundingRect) { QVector points; const KoColorSpace *cs = dev->colorSpace(); const QRect rect = dev->exactBounds() & boundingRect; if (rect.isEmpty()) return points; /** * Please note that since we modify the device inside * clearNonZeroComponent() call, we must use a *writable* * iterator, for not ending up with a lazy copied old version of a * device. */ KisSequentialIterator dstIt(dev, rect); do { if (cs->opacityU8(dstIt.rawData()) > 0) { const QPoint pt(dstIt.x(), dstIt.y()); points << pt; KisScanlineFill fill(dev, pt, rect); fill.clearNonZeroComponent(); } } while (dstIt.nextPixel()); return points; } KeyStroke::KeyStroke() + : isTransparent(false) { } -KeyStroke::KeyStroke(KisPaintDeviceSP _dev, const KoColor &_color) - : dev(_dev), color(_color) +KeyStroke::KeyStroke(KisPaintDeviceSP _dev, const KoColor &_color, bool _isTransparent) + : dev(_dev), color(_color), isTransparent(_isTransparent) { } bool operator==(const KeyStroke& t1, const KeyStroke&t2) { - return t1.dev == t2.dev && t1.color == t2.color; + return + t1.dev == t2.dev && + t1.color == t2.color && + t1.isTransparent == t2.isTransparent; } } diff --git a/libs/image/lazybrush/kis_lazy_fill_tools.h b/libs/image/lazybrush/kis_lazy_fill_tools.h index 976291268c..895a88d87d 100644 --- a/libs/image/lazybrush/kis_lazy_fill_tools.h +++ b/libs/image/lazybrush/kis_lazy_fill_tools.h @@ -1,80 +1,81 @@ /* * Copyright (c) 2016 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __KIS_LAZY_FILL_TOOLS_H #define __KIS_LAZY_FILL_TOOLS_H #include "kis_types.h" #include "kritaimage_export.h" #include #include class KoColor; namespace KisLazyFillTools { KRITAIMAGE_EXPORT void normalizeAndInvertAlpha8Device(KisPaintDeviceSP dev, const QRect &rect); /** * Uses Boykov-Kolmogorov Max-Flow/Min-Cut algorithm to split the * device \src into two parts. The first part is defined by \p * colorScribble and the second part --- by \p * backgroundScribble. In the result of the split the area defined * by \p colorScribble in \p resultDevice is filled with \p * color. Also the same area in \p maskDevice is filled with a * non-null scribble index. * * \p maskDevice is used for limiting the area used for filling * the color. */ KRITAIMAGE_EXPORT void cutOneWay(const KoColor &color, KisPaintDeviceSP src, KisPaintDeviceSP colorScribble, KisPaintDeviceSP backgroundScribble, KisPaintDeviceSP resultDevice, KisPaintDeviceSP maskDevice, const QRect &boundingRect); /** * Returns one pixel from each connected component of \p src. * * WARNING: \p src is used as a temporary device, so it will be * cleared(!) after the execution of the algorithm */ KRITAIMAGE_EXPORT QVector splitIntoConnectedComponents(KisPaintDeviceSP src, const QRect &boundingRect); struct KRITAIMAGE_EXPORT KeyStroke : public boost::equality_comparable { KeyStroke(); - KeyStroke(KisPaintDeviceSP _dev, const KoColor &_color); + KeyStroke(KisPaintDeviceSP _dev, const KoColor &_color, bool isTransparent = false); friend bool operator==(const KeyStroke& t1, const KeyStroke&t2); KisPaintDeviceSP dev; KoColor color; + bool isTransparent; }; }; #endif /* __KIS_LAZY_FILL_TOOLS_H */ diff --git a/libs/pigment/resources/KoColorSet.cpp b/libs/pigment/resources/KoColorSet.cpp index d4747e3bc5..4377d0be66 100644 --- a/libs/pigment/resources/KoColorSet.cpp +++ b/libs/pigment/resources/KoColorSet.cpp @@ -1,526 +1,531 @@ /* This file is part of the KDE project Copyright (c) 2005 Boudewijn Rempt 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; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include // qFromLittleEndian #include #include #include #include #include #include #include #include #include #include #include #include "KoColor.h" #include "KoColorSpaceRegistry.h" #include "KoColorModelStandardIds.h" KoColorSet::PaletteType detectFormat(const QString &fileName, const QByteArray &ba) { QFileInfo fi(fileName); // .pal if (ba.startsWith("RIFF") && ba.indexOf("PAL data", 8)) { return KoColorSet::RIFF_PAL; } // .gpl else if (ba.startsWith("GIMP Palette")) { return KoColorSet::GPL; } // .pal else if (ba.startsWith("JASC-PAL")) { return KoColorSet::PSP_PAL; } else if (fi.suffix().toLower() == "aco") { return KoColorSet::ACO; } else if (fi.suffix().toLower() == "act") { return KoColorSet::ACT; } return KoColorSet::UNKNOWN; } KoColorSet::KoColorSet(const QString& filename) : KoResource(filename) { // Implemented in KoResource class m_columns = 0; // Set the default value that the GIMP uses... } KoColorSet::KoColorSet() : KoResource("") { m_columns = 0; // Set the default value that the GIMP uses... } /// Create an copied palette KoColorSet::KoColorSet(const KoColorSet& rhs) : QObject(0) , KoResource("") { setFilename(rhs.filename()); m_ownData = false; m_name = rhs.m_name; m_comment = rhs.m_comment; m_columns = rhs.m_columns; m_colors = rhs.m_colors; setValid(true); } KoColorSet::~KoColorSet() { } bool KoColorSet::load() { QFile file(filename()); if (file.size() == 0) return false; if (!file.open(QIODevice::ReadOnly)) { warnPigment << "Can't open file " << filename(); return false; } bool res = loadFromDevice(&file); file.close(); return res; } bool KoColorSet::loadFromDevice(QIODevice *dev) { if (!dev->isOpen()) dev->open(QIODevice::ReadOnly); m_data = dev->readAll(); Q_ASSERT(m_data.size() != 0); return init(); } bool KoColorSet::save() { QFile file(filename()); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { return false; } saveToDevice(&file); file.close(); return true; } qint32 KoColorSet::nColors() { return m_colors.count(); } bool KoColorSet::saveToDevice(QIODevice *dev) const { QTextStream stream(dev); stream << "GIMP Palette\nName: " << name() << "\nColumns: " << m_columns << "\n#\n"; for (int i = 0; i < m_colors.size(); i++) { const KoColorSetEntry& entry = m_colors.at(i); QColor c = entry.color.toQColor(); stream << c.red() << " " << c.green() << " " << c.blue() << "\t"; if (entry.name.isEmpty()) stream << "Untitled\n"; else stream << entry.name << "\n"; } KoResource::saveToDevice(dev); return true; } bool KoColorSet::init() { m_colors.clear(); // just in case this is a reload (eg by KoEditColorSetDialog), if (filename().isNull()) { warnPigment << "Cannot load palette" << name() << "there is no filename set"; return false; } if (m_data.isNull()) { QFile file(filename()); if (file.size() == 0) { warnPigment << "Cannot load palette" << name() << "there is no data available"; return false; } file.open(QIODevice::ReadOnly); m_data = file.readAll(); file.close(); } bool res = false; PaletteType paletteType = detectFormat(filename(), m_data); switch(paletteType) { case GPL: res = loadGpl(); break; case ACT: res = loadAct(); break; case RIFF_PAL: res = loadRiff(); break; case PSP_PAL: res = loadPsp(); break; case ACO: res = loadAco(); break; default: res = false; } setValid(res); if (m_columns == 0) { m_columns = 10; } QImage img(m_columns * 4, (m_colors.size() / m_columns) * 4, QImage::Format_ARGB32); QPainter gc(&img); gc.fillRect(img.rect(), Qt::darkGray); int counter = 0; for(int i = 0; i < m_columns; ++i) { for (int j = 0; j < (m_colors.size() / m_columns); ++j) { if (counter < m_colors.size()) { QColor c = m_colors.at(counter).color.toQColor(); gc.fillRect(i * 4, j * 4, 4, 4, c); counter++; } else { break; } } } setImage(img); // save some memory m_data.clear(); return res; } void KoColorSet::add(const KoColorSetEntry & c) { m_colors.push_back(c); } void KoColorSet::remove(const KoColorSetEntry & c) { for (auto it = m_colors.begin(); it != m_colors.end(); /*noop*/) { if ((*it) == c) { it = m_colors.erase(it); return; } ++it; } } void KoColorSet::removeAt(quint32 index) { m_colors.remove(index); } +void KoColorSet::clear() +{ + m_colors.clear(); +} + KoColorSetEntry KoColorSet::getColor(quint32 index) { return m_colors[index]; } void KoColorSet::setColumnCount(int columns) { m_columns = columns; } int KoColorSet::columnCount() { return m_columns; } QString KoColorSet::defaultFileExtension() const { return QString(".gpl"); } bool KoColorSet::loadGpl() { QString s = QString::fromUtf8(m_data.data(), m_data.count()); if (s.isEmpty() || s.isNull() || s.length() < 50) { warnPigment << "Illegal Gimp palette file: " << filename(); return false; } quint32 index = 0; QStringList lines = s.split('\n', QString::SkipEmptyParts); if (lines.size() < 3) { return false; } QString columns; qint32 r, g, b; KoColorSetEntry e; // Read name if (!lines[0].startsWith("GIMP") || !lines[1].startsWith("Name: ")) { warnPigment << "Illegal Gimp palette file: " << filename(); return false; } setName(i18n(lines[1].mid(strlen("Name: ")).trimmed().toLatin1())); index = 2; // Read columns if (lines[index].startsWith("Columns: ")) { columns = lines[index].mid(strlen("Columns: ")).trimmed(); m_columns = columns.toInt(); index = 3; } for (qint32 i = index; i < lines.size(); i++) { if (lines[i].startsWith('#')) { m_comment += lines[i].mid(1).trimmed() + ' '; } else if (!lines[i].isEmpty()) { QStringList a = lines[i].replace('\t', ' ').split(' ', QString::SkipEmptyParts); if (a.count() < 3) { break; } r = a[0].toInt(); a.pop_front(); g = a[0].toInt(); a.pop_front(); b = a[0].toInt(); a.pop_front(); r = qBound(0, r, 255); g = qBound(0, g, 255); b = qBound(0, b, 255); e.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); e.color.fromQColor(QColor(r, g, b)); QString name = a.join(" "); e.name = name.isEmpty() ? i18n("Untitled") : name; add(e); } } return true; } bool KoColorSet::loadAct() { QFileInfo info(filename()); setName(info.baseName()); KoColorSetEntry e; for (int i = 0; i < m_data.size(); i += 3) { quint8 r = m_data[i]; quint8 g = m_data[i+1]; quint8 b = m_data[i+2]; e.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); e.color.fromQColor(QColor(r, g, b)); add(e); } return true; } struct RiffHeader { quint32 riff; quint32 size; quint32 signature; quint32 data; quint32 datasize; quint16 version; quint16 colorcount; }; bool KoColorSet::loadRiff() { // http://worms2d.info/Palette_file QFileInfo info(filename()); setName(info.baseName()); KoColorSetEntry e; RiffHeader header; memcpy(&header, m_data.constData(), sizeof(RiffHeader)); header.colorcount = qFromBigEndian(header.colorcount); for (int i = sizeof(RiffHeader); (i < (int)(sizeof(RiffHeader) + header.colorcount) && i < m_data.size()); i += 4) { quint8 r = m_data[i]; quint8 g = m_data[i+1]; quint8 b = m_data[i+2]; e.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); e.color.fromQColor(QColor(r, g, b)); add(e); } return true; } bool KoColorSet::loadPsp() { QFileInfo info(filename()); setName(info.baseName()); KoColorSetEntry e; qint32 r, g, b; QString s = QString::fromUtf8(m_data.data(), m_data.count()); QStringList l = s.split('\n', QString::SkipEmptyParts); if (l.size() < 4) return false; if (l[0] != "JASC-PAL") return false; if (l[1] != "0100") return false; int entries = l[2].toInt(); for (int i = 0; i < entries; ++i) { QStringList a = l[i + 3].replace('\t', ' ').split(' ', QString::SkipEmptyParts); if (a.count() != 3) { continue; } r = a[0].toInt(); a.pop_front(); g = a[0].toInt(); a.pop_front(); b = a[0].toInt(); a.pop_front(); r = qBound(0, r, 255); g = qBound(0, g, 255); b = qBound(0, b, 255); e.color = KoColor(KoColorSpaceRegistry::instance()->rgb8()); e.color.fromQColor(QColor(r, g, b)); QString name = a.join(" "); e.name = name.isEmpty() ? i18n("Untitled") : name; add(e); } return true; } quint16 readShort(QIODevice *io) { quint16 val; quint64 read = io->read((char*)&val, 2); if (read != 2) return false; return qFromBigEndian(val); } bool KoColorSet::loadAco() { QFileInfo info(filename()); setName(info.baseName()); QBuffer buf(&m_data); buf.open(QBuffer::ReadOnly); quint16 version = readShort(&buf); quint16 numColors = readShort(&buf); KoColorSetEntry e; const quint16 quint16_MAX = 65535; for (int i = 0; i < numColors && !buf.atEnd(); ++i) { quint16 colorSpace = readShort(&buf); quint16 ch1 = readShort(&buf); quint16 ch2 = readShort(&buf); quint16 ch3 = readShort(&buf); quint16 ch4 = readShort(&buf); bool skip = false; if (colorSpace == 0) { // RGB e.color = KoColor(KoColorSpaceRegistry::instance()->rgb16()); reinterpret_cast(e.color.data())[0] = ch3; reinterpret_cast(e.color.data())[1] = ch2; reinterpret_cast(e.color.data())[2] = ch1; e.color.setOpacity(OPACITY_OPAQUE_U8); } else if (colorSpace == 1) { // HSB e.color = KoColor(KoColorSpaceRegistry::instance()->rgb16()); QColor c; c.setHsvF(ch1 / 65536.0, ch2 / 65536.0, ch3 / 65536.0); e.color.fromQColor(c); e.color.setOpacity(OPACITY_OPAQUE_U8); } else if (colorSpace == 2) { // CMYK e.color = KoColor(KoColorSpaceRegistry::instance()->colorSpace(CMYKAColorModelID.id(), Integer16BitsColorDepthID.id(), "")); reinterpret_cast(e.color.data())[0] = quint16_MAX - ch1; reinterpret_cast(e.color.data())[1] = quint16_MAX - ch2; reinterpret_cast(e.color.data())[2] = quint16_MAX - ch3; reinterpret_cast(e.color.data())[3] = quint16_MAX - ch4; e.color.setOpacity(OPACITY_OPAQUE_U8); } else if (colorSpace == 7) { // LAB e.color = KoColor(KoColorSpaceRegistry::instance()->lab16()); reinterpret_cast(e.color.data())[0] = ch3; reinterpret_cast(e.color.data())[1] = ch2; reinterpret_cast(e.color.data())[2] = ch1; e.color.setOpacity(OPACITY_OPAQUE_U8); } else if (colorSpace == 8) { // GRAY e.color = KoColor(KoColorSpaceRegistry::instance()->colorSpace(GrayAColorModelID.id(), Integer16BitsColorDepthID.id(), "")); reinterpret_cast(e.color.data())[0] = ch1 * (quint16_MAX / 10000); e.color.setOpacity(OPACITY_OPAQUE_U8); } else { warnPigment << "Unsupported colorspace in palette" << filename() << "(" << colorSpace << ")"; skip = true; } if (version == 2) { quint16 v2 = readShort(&buf); if (v2 != 2) { warnPigment << "Version 2 block is not version 2" << filename() << "(" << v2 << ")"; return false; } quint16 size = readShort(&buf); QByteArray ba = buf.read(size); if (ba.size() != size) { warnPigment << "Version 2 name block is the wrong size" << filename(); return false; } e.name = QString::fromUtf8(ba.constData(), ba.size()); } if (!skip) { add(e); } } return true; } diff --git a/libs/pigment/resources/KoColorSet.h b/libs/pigment/resources/KoColorSet.h index a87d10442e..0414ed9a25 100644 --- a/libs/pigment/resources/KoColorSet.h +++ b/libs/pigment/resources/KoColorSet.h @@ -1,108 +1,113 @@ /* This file is part of the KDE project Copyright (c) 2005 Boudewijn Rempt 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; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef KOCOLORSET #define KOCOLORSET #include #include #include #include #include "KoColor.h" struct KoColorSetEntry { + KoColorSetEntry() {} + KoColorSetEntry(const KoColor &_color, const QString &_name) + : color(_color), name(_name) {} + KoColor color; QString name; bool operator==(const KoColorSetEntry& rhs) const { return color == rhs.color && name == rhs.name; } }; /** * Open Gimp, Photoshop or RIFF palette files. This is a straight port * from the Gimp. */ class KRITAPIGMENT_EXPORT KoColorSet : public QObject, public KoResource { Q_OBJECT public: enum PaletteType { UNKNOWN = 0, GPL, // GIMP RIFF_PAL, // RIFF ACT, // Photoshop binary PSP_PAL, // PaintShop Pro ACO // Photoshop Swatches }; /** * Load a color set from a file. This can be a Gimp * palette, a RIFF palette or a Photoshop palette. */ explicit KoColorSet(const QString &filename); /// Create an empty color set KoColorSet(); /// Explicit copy constructor (KoResource copy constructor is private) KoColorSet(const KoColorSet& rhs); virtual ~KoColorSet(); virtual bool load(); virtual bool loadFromDevice(QIODevice *dev); virtual bool save(); virtual bool saveToDevice(QIODevice* dev) const; virtual QString defaultFileExtension() const; void setColumnCount(int columns); int columnCount(); public: void add(const KoColorSetEntry &); void remove(const KoColorSetEntry &); void removeAt(quint32 index); KoColorSetEntry getColor(quint32 index); qint32 nColors(); + void clear(); private: bool init(); bool loadGpl(); bool loadAct(); bool loadRiff(); bool loadPsp(); bool loadAco(); QByteArray m_data; bool m_ownData; QString m_name; QString m_comment; qint32 m_columns; QVector m_colors; }; #endif // KOCOLORSET diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt index 21dfc97bf0..3324e824ef 100644 --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -1,532 +1,534 @@ # Disable -Wswitch because of the extra definitions we here: # kis_input_manager.cpp: In member function ‘virtual bool KisInputManager::eventFilter(QObject*, QEvent*)’: # warning: case value ‘1001’ not in enumerated type ‘QEvent::Type’ [-Wswitch] # warning: case value ‘1002’ not in enumerated type ‘QEvent::Type’ [-Wswitch] if (CMAKE_COMPILER_IS_GNUCXX) add_definitions(${KDE4_ENABLE_EXCEPTIONS} -Wno-switch) endif () include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/qtlockedfile ${EXIV2_INCLUDE_DIR} ) include_directories(SYSTEM ${EIGEN3_INCLUDE_DIR} ${OCIO_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ) add_subdirectory( tests ) if (APPLE) find_library(FOUNDATION_LIBRARY Foundation) 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 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_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 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 kis_aspect_ratio_locker.cpp kis_autogradient.cc kis_bookmarked_configurations_editor.cc kis_bookmarked_configurations_model.cc kis_bookmarked_filter_configurations_model.cc 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_config_notifier.cpp 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_safe_document_loader.cpp kis_splash_screen.cpp kis_filter_manager.cc kis_filters_model.cc kis_histogram_view.cc 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 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 kis_painting_assistants_manager.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 kis_resource_server_provider.cpp kis_selection_decoration.cc kis_selection_manager.cc kis_statusbar.cc kis_zoom_manager.cc kis_favorite_resource_manager.cpp kis_workspace_resource.cpp kis_action.cpp kis_action_manager.cpp kis_view_plugin.cpp kis_canvas_controls_manager.cpp kis_tooltip_manager.cpp kis_multinode_property.cpp kis_async_action_feedback.cpp kisexiv2/kis_exif_io.cpp kisexiv2/kis_exiv2.cpp kisexiv2/kis_iptc_io.cpp kisexiv2/kis_xmp_io.cpp kra/kis_kra_utils.cpp kra/kis_kra_load_visitor.cpp kra/kis_kra_loader.cpp kra/kis_kra_save_visitor.cpp kra/kis_kra_saver.cpp kra/kis_kra_savexml_visitor.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 kis_fps_decoration.cpp ora/kis_open_raster_stack_load_visitor.cpp ora/kis_open_raster_stack_save_visitor.cpp ora/ora_load_context.cc ora/ora_save_context.cc recorder/kis_node_query_path_editor.cc recorder/kis_recorded_action_creator.cc recorder/kis_recorded_action_creator_factory.cc recorder/kis_recorded_action_creator_factory_registry.cc recorder/kis_recorded_action_editor_factory.cc recorder/kis_recorded_action_editor_factory_registry.cc recorder/kis_recorded_filter_action_editor.cc recorder/kis_recorded_filter_action_creator.cpp recorder/kis_recorded_paint_action_editor.cc 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_recording_adapter.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/strokes/freehand_stroke.cpp tool/strokes/kis_painter_based_stroke_strategy.cpp tool/strokes/kis_filter_stroke_strategy.cpp tool/strokes/kis_color_picker_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_gradient_slider_widget.cc widgets/kis_gradient_slider.cpp 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_pattern_chooser.cc widgets/kis_popup_button.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/kis_size_group.cpp widgets/kis_size_group_p.cpp widgets/kis_wdg_generator.cpp widgets/kis_workspace_chooser.cpp widgets/squeezedcombobox.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 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_single_action_shortcut.cpp input/kis_stroke_shortcut.cpp input/kis_shortcut_matcher.cpp input/kis_select_layer_action.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 input/kis_touch_shortcut.cpp kis_document_undo_store.cpp kis_transaction_based_command.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 KisNodeDelegate.cpp kis_node_view_visibility_delegate.cpp KisNodeToolTip.cpp KisNodeView.cpp kis_node_view_color_scheme.cpp KisFilterChain.cpp KisFilterChainLink.cpp KisFilterChainLinkList.cpp KisImportExportFilter.cpp KisFilterEdge.cpp KisFilterEntry.cpp KisFilterGraph.cpp KisImportExportManager.cpp KisFilterVertex.cpp KisMainWindow.cpp KisOpenPane.cpp KisPart.cpp KisPrintJob.cpp KisTemplate.cpp KisTemplateCreateDia.cpp KisTemplateGroup.cpp KisTemplates.cpp KisTemplatesPane.cpp KisTemplateTree.cpp KisUndoStackAction.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 KisPaletteModel.cpp + kis_palette_delegate.cpp + kis_palette_view.cpp KisColorsetChooser.cpp KisSaveGroupVisitor.cpp ) if(WIN32) if (NOT Qt5Gui_PRIVATE_INCLUDE_DIRS) message(FATAL_ERROR "Qt5Gui Private header are missing!") endif() 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 ) include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) endif() set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} kis_animation_frame_cache.cpp kis_animation_cache_populator.cpp canvas/kis_animation_player.cpp kis_animation_exporter.cpp kis_animation_importer.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/kis_tablet_support_x11.cpp input/wintab/qxcbconnection_xi2.cpp input/wintab/qxcbconnection.cpp input/wintab/kis_xi2_event_filter.cpp ) endif() endif() if(WIN32) #ki18n_wrap_ui( # input/wintab/kis_screen_size_choice_dialog.ui #) endif() ki18n_wrap_ui(kritaui_LIB_SRCS forms/wdgdlgpngimport.ui forms/wdgfullscreensettings.ui forms/wdgautogradient.ui forms/wdggeneralsettings.ui forms/wdgperformancesettings.ui forms/wdggenerators.ui forms/wdgcustompalette.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/wdgpaintactioneditor.ui forms/wdgmultipliersdoublesliderspinbox.ui forms/wdgnodequerypatheditor.ui forms/wdgpresetselectorstrip.ui forms/wdgdlgblacklistcleanup.ui forms/wdgrectangleconstraints.ui forms/wdgimportimagesequence.ui forms/KisDetailsPaneBase.ui forms/KisOpenPaneBase.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 ) 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 kritacolor kritaimage kritalibbrush kritawidgets kritawidgetutils ${PNG_LIBRARIES} ${EXIV2_LIBRARIES} ) 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}) 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_link_libraries(kritaui LINK_INTERFACE_LIBRARIES kritaimage kritalibbrush kritapigment KF5::Completion KF5::I18n ${GL_INTERFACE_LIBRARIES}) 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/KisPaletteModel.cpp b/libs/ui/KisPaletteModel.cpp index cb882bca79..d910b79435 100644 --- a/libs/ui/KisPaletteModel.cpp +++ b/libs/ui/KisPaletteModel.cpp @@ -1,117 +1,133 @@ /* * Copyright (c) 2013 Sven Langkamp * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "KisPaletteModel.h" #include #include #include #include #include #include KisPaletteModel::KisPaletteModel(QObject* parent) : QAbstractTableModel(parent), m_colorSet(0), m_displayRenderer(KoDumbColorDisplayRenderer::instance()) { } KisPaletteModel::~KisPaletteModel() { } void KisPaletteModel::setDisplayRenderer(KoColorDisplayRendererInterface *displayRenderer) { if (displayRenderer) { if (m_displayRenderer) { disconnect(m_displayRenderer, 0, this, 0); } m_displayRenderer = displayRenderer; connect(m_displayRenderer, SIGNAL(displayConfigurationChanged()), SLOT(slotDisplayConfigurationChanged())); } else { m_displayRenderer = KoDumbColorDisplayRenderer::instance(); } } void KisPaletteModel::slotDisplayConfigurationChanged() { reset(); } QVariant KisPaletteModel::data(const QModelIndex& index, int role) const { if (m_colorSet) { int i = index.row()*columnCount()+index.column(); if (i < m_colorSet->nColors()) { switch (role) { - case Qt::BackgroundRole: { - QColor color = m_displayRenderer->toQColor(m_colorSet->getColor(i).color); - return QBrush(color); - } - break; + case Qt::DisplayRole: { + return m_colorSet->getColor(i).name; + } + case Qt::BackgroundRole: { + QColor color = m_displayRenderer->toQColor(m_colorSet->getColor(i).color); + return QBrush(color); + } } } } return QVariant(); } int KisPaletteModel::rowCount(const QModelIndex& /*parent*/) const { if (!m_colorSet) { return 0; } if (m_colorSet->columnCount() > 0) { return m_colorSet->nColors()/m_colorSet->columnCount() + 1; - } + } return m_colorSet->nColors()/15 + 1; } int KisPaletteModel::columnCount(const QModelIndex& /*parent*/) const { if (m_colorSet && m_colorSet->columnCount() > 0) { return m_colorSet->columnCount(); } return 15; } Qt::ItemFlags KisPaletteModel::flags(const QModelIndex& /*index*/) const { Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; return flags; } QModelIndex KisPaletteModel::index(int row, int column, const QModelIndex& parent) const { int index = row*columnCount()+column; if (m_colorSet && index < m_colorSet->nColors()) { return QAbstractTableModel::index(row, column, parent); } return QModelIndex(); } - void KisPaletteModel::setColorSet(KoColorSet* colorSet) { m_colorSet = colorSet; reset(); } +KoColorSet* KisPaletteModel::colorSet() const +{ + return m_colorSet; +} + +QModelIndex KisPaletteModel::indexFromId(int i) const +{ + const int width = columnCount(); + return width > 0 ? index(i / width, i & width) : QModelIndex(); +} + +int KisPaletteModel::idFromIndex(const QModelIndex &index) const +{ + return index.isValid() ? index.row() * columnCount() + index.column() : -1; +} diff --git a/libs/ui/KisPaletteModel.h b/libs/ui/KisPaletteModel.h index bfb4201b09..413f0b54ee 100644 --- a/libs/ui/KisPaletteModel.h +++ b/libs/ui/KisPaletteModel.h @@ -1,61 +1,65 @@ /* * Copyright (c) 2013 Sven Langkamp * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KIS_PALETTEMODEL_H #define KIS_PALETTEMODEL_H #include #include #include "kritaui_export.h" class KoColorSet; class KoColorDisplayRendererInterface; class KRITAUI_EXPORT KisPaletteModel : public QAbstractTableModel { Q_OBJECT public: KisPaletteModel(QObject* parent = 0); virtual ~KisPaletteModel(); virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; void setColorSet(KoColorSet* colorSet); + KoColorSet* colorSet() const; /** * Installs a display renderer object for a palette that will * convert the KoColor to the displayable QColor. Default is the * dumb renderer. */ void setDisplayRenderer(KoColorDisplayRendererInterface *displayRenderer); + QModelIndex indexFromId(int i) const; + int idFromIndex(const QModelIndex &index) const; + private Q_SLOTS: void slotDisplayConfigurationChanged(); private: KoColorSet* m_colorSet; KoColorDisplayRendererInterface *m_displayRenderer; }; #endif diff --git a/libs/ui/kis_palette_delegate.cpp b/libs/ui/kis_palette_delegate.cpp new file mode 100644 index 0000000000..f6034287b5 --- /dev/null +++ b/libs/ui/kis_palette_delegate.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2016 Dmitry Kazakov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_palette_delegate.h" + +#include +#include + +#include +#include "kis_debug.h" + + +KisPaletteDelegate::KisPaletteDelegate(QObject *parent) + : QAbstractItemDelegate(parent) +{ +} + +KisPaletteDelegate::~KisPaletteDelegate() +{ +} + +void KisPaletteDelegate::setCrossedKeyword(const QString &value) +{ + m_crossedKeyword = value; +} + +void KisPaletteDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const +{ + painter->save(); + + if (! index.isValid()) + return; + + const bool isSelected = option.state & QStyle::State_Selected; + const int minSize = qMin(option.rect.width(), option.rect.height()); + const int maxWidth = qBound(2, minSize / 6, 4); + const int width = isSelected ? maxWidth : 1; + + if (isSelected) { + painter->fillRect(option.rect, option.palette.highlight()); + } + + QRect paintRect = kisGrowRect(option.rect, -width); + QBrush brush = qVariantValue(index.data(Qt::BackgroundRole)); + painter->fillRect(paintRect, brush); + painter->restore(); + + QString name = qVariantValue(index.data(Qt::DisplayRole)); + if (!m_crossedKeyword.isNull() && name.toLower().contains(m_crossedKeyword)) { + QRect crossRect = kisGrowRect(option.rect, -maxWidth); + + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(QPen(Qt::white, 2.5)); + painter->drawLine(crossRect.topLeft(), crossRect.bottomRight()); + painter->setPen(QPen(Qt::red, 1.0)); + painter->drawLine(crossRect.topLeft(), crossRect.bottomRight()); + painter->restore(); + } +} + +QSize KisPaletteDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex &) const +{ + return option.decorationSize; +} diff --git a/libs/ui/kis_palette_delegate.h b/libs/ui/kis_palette_delegate.h new file mode 100644 index 0000000000..e3ca71f8e5 --- /dev/null +++ b/libs/ui/kis_palette_delegate.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016 Dmitry Kazakov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __KIS_PALETTE_DELEGATE_H +#define __KIS_PALETTE_DELEGATE_H + +#include + +#include "kritaui_export.h" + + +class KRITAUI_EXPORT KisPaletteDelegate : public QAbstractItemDelegate +{ +public: + KisPaletteDelegate(QObject * parent = 0); + ~KisPaletteDelegate(); + + void setCrossedKeyword(const QString &value); + + void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const; + QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex &) const; + +private: + QString m_crossedKeyword; +}; + +#endif /* __KIS_PALETTE_DELEGATE_H */ diff --git a/libs/ui/kis_palette_view.cpp b/libs/ui/kis_palette_view.cpp new file mode 100644 index 0000000000..44bfb108c0 --- /dev/null +++ b/libs/ui/kis_palette_view.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016 Dmitry Kazakov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_palette_view.h" + +#include +#include + +#include "kis_palette_delegate.h" +#include "KisPaletteModel.h" +#include "kis_config.h" + + +struct KisPaletteView::Private +{ + KisPaletteModel *model = 0; +}; + + +KisPaletteView::KisPaletteView(QWidget *parent) + : KoTableView(parent), + m_d(new Private) +{ + setShowGrid(false); + horizontalHeader()->setVisible(false); + verticalHeader()->setVisible(false); + setItemDelegate(new KisPaletteDelegate()); + + KisConfig cfg; + QPalette pal(palette()); + pal.setColor(QPalette::Base, cfg.getMDIBackgroundColor()); + setAutoFillBackground(true); + setPalette(pal); + + int defaultSectionSize = cfg.paletteDockerPaletteViewSectionSize(); + horizontalHeader()->setDefaultSectionSize(defaultSectionSize); + verticalHeader()->setDefaultSectionSize(defaultSectionSize); +} + +KisPaletteView::~KisPaletteView() +{ +} + +void KisPaletteView::setCrossedKeyword(const QString &value) +{ + KisPaletteDelegate *delegate = + dynamic_cast(itemDelegate()); + KIS_ASSERT_RECOVER_RETURN(delegate); + + delegate->setCrossedKeyword(value); +} + +void KisPaletteView::setPaletteModel(KisPaletteModel *model) +{ + m_d->model = model; + setModel(model); +} + +KisPaletteModel* KisPaletteView::paletteModel() const +{ + return m_d->model; +} + + +void KisPaletteView::wheelEvent(QWheelEvent *event) +{ + if (event->modifiers() & Qt::ControlModifier) { + int numDegrees = event->delta() / 8; + int numSteps = numDegrees / 7; + int curSize = horizontalHeader()->sectionSize(0); + int setSize = numSteps + curSize; + + if ( setSize >= 12 ) { + horizontalHeader()->setDefaultSectionSize(setSize); + verticalHeader()->setDefaultSectionSize(setSize); + KisConfig cfg; + cfg.setPaletteDockerPaletteViewSectionSize(setSize); + } + + event->accept(); + } else { + KoTableView::wheelEvent(event); + } +} diff --git a/libs/ui/kis_palette_view.h b/libs/ui/kis_palette_view.h new file mode 100644 index 0000000000..6dae7b3d11 --- /dev/null +++ b/libs/ui/kis_palette_view.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016 Dmitry Kazakov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __KIS_PALETTE_VIEW_H +#define __KIS_PALETTE_VIEW_H + +#include +#include + +#include "kritaui_export.h" + +class KisPaletteModel; +class QWheelEvent; + + +class KRITAUI_EXPORT KisPaletteView : public KoTableView +{ +public: + KisPaletteView(QWidget *parent = 0); + ~KisPaletteView(); + + void setPaletteModel(KisPaletteModel *model); + KisPaletteModel* paletteModel() const; + + void setCrossedKeyword(const QString &value); + +protected: + void wheelEvent(QWheelEvent *event); + +private: + struct Private; + const QScopedPointer m_d; +}; + +#endif /* __KIS_PALETTE_VIEW_H */ diff --git a/plugins/dockers/palettedocker/palettedocker_dock.cpp b/plugins/dockers/palettedocker/palettedocker_dock.cpp index a4363560b8..7c9b057f74 100644 --- a/plugins/dockers/palettedocker/palettedocker_dock.cpp +++ b/plugins/dockers/palettedocker/palettedocker_dock.cpp @@ -1,334 +1,255 @@ /* * Copyright (c) 2013 Sven Langkamp * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "palettedocker_dock.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "KisPaletteModel.h" #include "KisColorsetChooser.h" #include "ui_wdgpalettedock.h" - -/// The resource item delegate for rendering the resource preview -class PaletteDelegate : public QAbstractItemDelegate -{ -public: - PaletteDelegate(QObject * parent = 0) : QAbstractItemDelegate(parent), m_showText(false) {} - virtual ~PaletteDelegate() {} - /// reimplemented - virtual void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const; - /// reimplemented - QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex &) const { - return option.decorationSize; - } - - void setShowText(bool showText) { - m_showText = showText; - } - -private: - bool m_showText; -}; - -void PaletteDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const -{ - painter->save(); - - if (! index.isValid()) - return; - - if (option.state & QStyle::State_Selected) { - painter->setPen(QPen(option.palette.highlightedText(), 2.0)); - painter->fillRect(option.rect, option.palette.highlight()); - } else { - painter->setPen(QPen(option.palette.text(), 2.0)); - - } - QRect paintRect = option.rect.adjusted(1, 1, -1, -1); - QBrush brush = qVariantValue(index.data(Qt::BackgroundRole)); - painter->fillRect(paintRect, brush); - painter->restore(); -} - -bool PaletteDockerDock::eventFilter(QObject* object, QEvent* event) -{ - if (object == m_wdgPaletteDock->paletteView->viewport() && event->type() == QEvent::Wheel) { - QWheelEvent* qwheel = dynamic_cast(event); - if (qwheel->modifiers() & Qt::ControlModifier) { - - int numDegrees = qwheel->delta() / 8; - int numSteps = numDegrees / 7; - int curSize = m_wdgPaletteDock->paletteView->horizontalHeader()->sectionSize(0); - int setSize = numSteps + curSize; - - if ( setSize >= 12 ) { - m_wdgPaletteDock->paletteView->horizontalHeader()->setDefaultSectionSize(setSize); - m_wdgPaletteDock->paletteView->verticalHeader()->setDefaultSectionSize(setSize); - KisConfig cfg; - cfg.setPaletteDockerPaletteViewSectionSize(setSize); - } - return true; - } else { - return false; - } - } else { - return QWidget::eventFilter(object, event); - } -} +#include "kis_palette_delegate.h" +#include "kis_palette_view.h" PaletteDockerDock::PaletteDockerDock( ) : QDockWidget(i18n("Palette")) , m_wdgPaletteDock(new Ui_WdgPaletteDock()) , m_currentColorSet(0) , m_resourceProvider(0) , m_canvas(0) { QWidget* mainWidget = new QWidget(this); setWidget(mainWidget); m_wdgPaletteDock->setupUi(mainWidget); m_wdgPaletteDock->bnAdd->setIcon(KisIconUtils::loadIcon("list-add")); m_wdgPaletteDock->bnAdd->setIconSize(QSize(16, 16)); m_wdgPaletteDock->bnAddDialog->setIcon(KisIconUtils::loadIcon("document-new")); m_wdgPaletteDock->bnAddDialog->setIconSize(QSize(16, 16)); m_wdgPaletteDock->bnRemove->setIcon(KisIconUtils::loadIcon("edit-delete")); m_wdgPaletteDock->bnRemove->setIconSize(QSize(16, 16)); m_wdgPaletteDock->bnAdd->setEnabled(false); m_wdgPaletteDock->bnRemove->setEnabled(false); connect(m_wdgPaletteDock->bnAdd, SIGNAL(clicked(bool)), this, SLOT(addColorForeground())); connect(m_wdgPaletteDock->bnAddDialog, SIGNAL(clicked(bool)), this, SLOT(addColor())); connect(m_wdgPaletteDock->bnRemove, SIGNAL(clicked(bool)), this, SLOT(removeColor())); m_model = new KisPaletteModel(this); - m_wdgPaletteDock->paletteView->setModel(m_model); - m_wdgPaletteDock->paletteView->setShowGrid(false); - m_wdgPaletteDock->paletteView->horizontalHeader()->setVisible(false); - m_wdgPaletteDock->paletteView->verticalHeader()->setVisible(false); - m_wdgPaletteDock->paletteView->setItemDelegate(new PaletteDelegate()); - - KisConfig cfg; + m_wdgPaletteDock->paletteView->setPaletteModel(m_model); - QPalette pal(palette()); - pal.setColor(QPalette::Base, cfg.getMDIBackgroundColor()); - m_wdgPaletteDock->paletteView->setAutoFillBackground(true); - m_wdgPaletteDock->paletteView->setPalette(pal); connect(m_wdgPaletteDock->paletteView, SIGNAL(clicked(QModelIndex)), this, SLOT(entrySelected(QModelIndex))); - m_wdgPaletteDock->paletteView->viewport()->installEventFilter(this); KoResourceServer* rServer = KoResourceServerProvider::instance()->paletteServer(false); m_serverAdapter = QSharedPointer(new KoResourceServerAdapter(rServer)); m_serverAdapter->connectToResourceServer(); rServer->addObserver(this); m_colorSetChooser = new KisColorsetChooser(this); connect(m_colorSetChooser, SIGNAL(paletteSelected(KoColorSet*)), this, SLOT(setColorSet(KoColorSet*))); m_wdgPaletteDock->bnColorSets->setIcon(KisIconUtils::loadIcon("hi16-palette_library")); m_wdgPaletteDock->bnColorSets->setToolTip(i18n("Choose palette")); m_wdgPaletteDock->bnColorSets->setPopupWidget(m_colorSetChooser); - int defaultSectionSize = cfg.paletteDockerPaletteViewSectionSize(); - m_wdgPaletteDock->paletteView->horizontalHeader()->setDefaultSectionSize(defaultSectionSize); - m_wdgPaletteDock->paletteView->verticalHeader()->setDefaultSectionSize(defaultSectionSize); - + KisConfig cfg; QString defaultPalette = cfg.defaultPalette(); KoColorSet* defaultColorSet = rServer->resourceByName(defaultPalette); if (defaultColorSet) { setColorSet(defaultColorSet); } } PaletteDockerDock::~PaletteDockerDock() { KoResourceServer* rServer = KoResourceServerProvider::instance()->paletteServer(); rServer->removeObserver(this); if (m_currentColorSet) { KisConfig cfg; cfg.setDefaultPalette(m_currentColorSet->name()); } delete m_wdgPaletteDock->paletteView->itemDelegate(); delete m_wdgPaletteDock; } void PaletteDockerDock::setMainWindow(KisViewManager* kisview) { m_resourceProvider = kisview->resourceProvider(); connect(m_resourceProvider, SIGNAL(sigSavingWorkspace(KisWorkspaceResource*)), SLOT(saveToWorkspace(KisWorkspaceResource*))); connect(m_resourceProvider, SIGNAL(sigLoadingWorkspace(KisWorkspaceResource*)), SLOT(loadFromWorkspace(KisWorkspaceResource*))); kisview->nodeManager()->disconnect(m_model); } void PaletteDockerDock::setCanvas(KoCanvasBase *canvas) { setEnabled(canvas != 0); if (canvas) { KisCanvas2 *cv = dynamic_cast(canvas); m_model->setDisplayRenderer(cv->displayColorConverter()->displayRendererInterface()); } m_canvas = static_cast(canvas); } void PaletteDockerDock::unsetCanvas() { setEnabled(false); m_model->setDisplayRenderer(0); m_canvas = 0; } void PaletteDockerDock::unsetResourceServer() { KoResourceServer* rServer = KoResourceServerProvider::instance()->paletteServer(); rServer->removeObserver(this); } void PaletteDockerDock::removingResource(KoColorSet *resource) { if (resource == m_currentColorSet) { setColorSet(0); } } void PaletteDockerDock::resourceChanged(KoColorSet *resource) { setColorSet(resource); } void PaletteDockerDock::setColorSet(KoColorSet* colorSet) { m_model->setColorSet(colorSet); if (colorSet && colorSet->removable()) { m_wdgPaletteDock->bnAdd->setEnabled(true); m_wdgPaletteDock->bnRemove->setEnabled(false); } else { m_wdgPaletteDock->bnAdd->setEnabled(false); m_wdgPaletteDock->bnRemove->setEnabled(false); } m_currentColorSet = colorSet; } void PaletteDockerDock::addColorForeground() { if (m_resourceProvider) { KoColorSetEntry newEntry; newEntry.color = m_resourceProvider->fgColor(); m_currentColorSet->add(newEntry); m_currentColorSet->save(); setColorSet(m_currentColorSet); // update model } } void PaletteDockerDock::addColor() { if (m_currentColorSet && m_resourceProvider) { const KoColorDisplayRendererInterface *displayRenderer = m_canvas->displayColorConverter()->displayRendererInterface(); KoColor currentFgColor = m_canvas->resourceManager()->foregroundColor(); QColor color = QColorDialog::getColor(displayRenderer->toQColor(currentFgColor)); if (color.isValid()) { KoColorSetEntry newEntry; newEntry.color = displayRenderer->approximateFromRenderedQColor(color); m_currentColorSet->add(newEntry); m_currentColorSet->save(); setColorSet(m_currentColorSet); // update model } } } void PaletteDockerDock::removeColor() { QModelIndex index = m_wdgPaletteDock->paletteView->currentIndex(); if (!index.isValid()) { return; } int i = index.row()*m_model->columnCount()+index.column(); m_currentColorSet->removeAt(i); m_currentColorSet->save(); setColorSet(m_currentColorSet); // update model } void PaletteDockerDock::entrySelected(QModelIndex index) { if (!index.isValid()) { return; } int i = index.row()*m_model->columnCount()+index.column(); if (i < m_currentColorSet->nColors()) { KoColorSetEntry entry = m_currentColorSet->getColor(i); if (m_resourceProvider) { m_resourceProvider->setFGColor(entry.color); } if (m_currentColorSet->removable()) { m_wdgPaletteDock->bnRemove->setEnabled(true); } } } void PaletteDockerDock::saveToWorkspace(KisWorkspaceResource* workspace) { if (m_currentColorSet) { workspace->setProperty("palette", m_currentColorSet->name()); } } void PaletteDockerDock::loadFromWorkspace(KisWorkspaceResource* workspace) { if (workspace->hasProperty("palette")) { KoResourceServer* rServer = KoResourceServerProvider::instance()->paletteServer(); KoColorSet* colorSet = rServer->resourceByName(workspace->getString("palette")); if (colorSet) { setColorSet(colorSet); } } } diff --git a/plugins/dockers/palettedocker/palettedocker_dock.h b/plugins/dockers/palettedocker/palettedocker_dock.h index f69c1dc9f4..77b129a817 100644 --- a/plugins/dockers/palettedocker/palettedocker_dock.h +++ b/plugins/dockers/palettedocker/palettedocker_dock.h @@ -1,84 +1,82 @@ /* * Copyright (c) 2013 Sven Langkamp * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PALETTEDOCKER_DOCK_H #define PALETTEDOCKER_DOCK_H #include #include #include #include #include #include #include class KisViewManager; class KisCanvasResourceProvider; class KisCanvas2; class KisWorkspaceResource; class KisColorsetChooser; class KisPaletteModel; class Ui_WdgPaletteDock; class PaletteDockerDock : public QDockWidget, public KisMainwindowObserver, public KoResourceServerObserver { Q_OBJECT public: PaletteDockerDock(); virtual ~PaletteDockerDock(); QString observerName() { return "PaletteDockerDock"; } virtual void setMainWindow(KisViewManager* kisview); virtual void setCanvas(KoCanvasBase *canvas); virtual void unsetCanvas(); public: // KoResourceServerObserver virtual void unsetResourceServer(); virtual void resourceAdded(KoColorSet *) {} virtual void removingResource(KoColorSet *resource); virtual void resourceChanged(KoColorSet *resource); virtual void syncTaggedResourceView() {} virtual void syncTagAddition(const QString&) {} virtual void syncTagRemoval(const QString&) {} private Q_SLOTS: void addColorForeground(); void addColor(); void removeColor(); void entrySelected(QModelIndex index); void setColorSet(KoColorSet* colorSet); void saveToWorkspace(KisWorkspaceResource* workspace); void loadFromWorkspace(KisWorkspaceResource* workspace); - virtual bool eventFilter(QObject*, QEvent*); - private: Ui_WdgPaletteDock* m_wdgPaletteDock; KisPaletteModel *m_model; QSharedPointer m_serverAdapter; KoColorSet *m_currentColorSet; KisColorsetChooser *m_colorSetChooser; KisCanvasResourceProvider *m_resourceProvider; KisCanvas2 *m_canvas; }; #endif diff --git a/plugins/dockers/palettedocker/wdgpalettedock.ui b/plugins/dockers/palettedocker/wdgpalettedock.ui index 0154b44a81..8c98abe7f3 100644 --- a/plugins/dockers/palettedocker/wdgpalettedock.ui +++ b/plugins/dockers/palettedocker/wdgpalettedock.ui @@ -1,130 +1,139 @@ WdgPaletteDock 0 0 256 219 1 - + + 0 + + + 0 + + + 0 + + 0 - + 0 16 Qt::Horizontal 40 20 Delete color ... 22 22 false Add foreground color ... 22 22 false Add color ... 22 22 false KisPopupButton QPushButton
kis_popup_button.h
- KoTableView + KisPaletteView QTableView -
KoTableView.h
+
kis_palette_view.h
bnRemove
diff --git a/plugins/tools/tool_lazybrush/CMakeLists.txt b/plugins/tools/tool_lazybrush/CMakeLists.txt index bbd2cb4665..ce982da51f 100644 --- a/plugins/tools/tool_lazybrush/CMakeLists.txt +++ b/plugins/tools/tool_lazybrush/CMakeLists.txt @@ -1,25 +1,26 @@ #include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) set(kritatoollazybrush_SOURCES tool_lazybrush.cpp kis_tool_lazy_brush.cpp + kis_tool_lazy_brush_options_widget.cpp ) -#ki18n_wrap_ui(kritatoollazybrush_SOURCES wdgcolorpicker.ui wdgmovetool.ui) +ki18n_wrap_ui(kritatoollazybrush_SOURCES kis_tool_lazy_brush_options_widget.ui) qt5_add_resources(kritatoollazybrush_SOURCES tool_lazybrush.qrc ) add_library(kritatoollazybrush MODULE ${kritatoollazybrush_SOURCES}) generate_export_header(kritatoollazybrush BASE_NAME kritatoollazybrush) target_link_libraries(kritatoollazybrush kritaui) #target_link_libraries(kritatoollazybrush ${Boost_SYSTEM_LIBRARY}) install(TARGETS kritatoollazybrush DESTINATION ${KRITA_PLUGIN_INSTALL_DIR}) ########### install files ############### # install( FILES # KisToolPencil.action # DESTINATION ${DATA_INSTALL_DIR}/krita/actions) diff --git a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush.cpp b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush.cpp index 561ddf0fe4..21f2355c72 100644 --- a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush.cpp +++ b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush.cpp @@ -1,75 +1,82 @@ /* * Copyright (c) 2016 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_tool_lazy_brush.h" #include #include #include #include #include #include +#include +#include "kis_canvas2.h" #include "kis_cursor.h" #include "kis_config.h" #include "kundo2magicstring.h" +#include "kis_tool_lazy_brush_options_widget.h" + + KisToolLazyBrush::KisToolLazyBrush(KoCanvasBase * canvas) : KisToolFreehand(canvas, KisCursor::load("tool_freehand_cursor.png", 5, 5), kundo2_i18n("Colorize Mask Key Stroke")) { setObjectName("tool_lazybrush"); } KisToolLazyBrush::~KisToolLazyBrush() { } void KisToolLazyBrush::activate(ToolActivation activation, const QSet &shapes) { KisToolFreehand::activate(activation, shapes); } void KisToolLazyBrush::deactivate() { KisToolFreehand::deactivate(); } void KisToolLazyBrush::resetCursorStyle() { KisToolFreehand::resetCursorStyle(); } QWidget * KisToolLazyBrush::createOptionWidget() { - QWidget *optionsWidget = KisToolFreehand::createOptionWidget(); + KisCanvas2 * kiscanvas = dynamic_cast(canvas()); + + QWidget *optionsWidget = new KisToolLazyBrushOptionsWidget(kiscanvas->viewManager()->resourceProvider(), 0); optionsWidget->setObjectName(toolId() + "option widget"); // // See https://bugs.kde.org/show_bug.cgi?id=316896 // QWidget *specialSpacer = new QWidget(optionsWidget); // specialSpacer->setObjectName("SpecialSpacer"); // specialSpacer->setFixedSize(0, 0); // optionsWidget->layout()->addWidget(specialSpacer); return optionsWidget; } diff --git a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush.h b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush.h index ed89b5ade1..5335964b5a 100644 --- a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush.h +++ b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush.h @@ -1,84 +1,85 @@ /* * Copyright (c) 2016 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KIS_TOOL_LAZY_BRUSH_H_ #define KIS_TOOL_LAZY_BRUSH_H_ #include "kis_tool_freehand.h" #include "KoToolFactoryBase.h" #include #include #include #include #include #include class KActionCollection; class KoCanvasBase; class KisToolLazyBrush : public KisToolFreehand { + Q_OBJECT public: KisToolLazyBrush(KoCanvasBase * canvas); virtual ~KisToolLazyBrush(); QWidget * createOptionWidget(); protected Q_SLOTS: - virtual void resetCursorStyle(); + void resetCursorStyle(); public Q_SLOTS: virtual void activate(ToolActivation toolActivation, const QSet &shapes); void deactivate(); Q_SIGNALS: private: }; class KisToolLazyBrushFactory : public KoToolFactoryBase { public: KisToolLazyBrushFactory() : KoToolFactoryBase("KritaShape/KisToolLazyBrush") { setToolTip(i18n("Colorize Mask Editing Tool")); // Temporarily setToolType(TOOL_TYPE_SHAPE); setIconName(koIconNameCStr("krita_tool_lazy_brush_stub")); setShortcut(QKeySequence(Qt::Key_Shift + Qt::Key_B)); setPriority(0); setActivationShapeId(KRITA_TOOL_ACTIVATION_ID); } virtual ~KisToolLazyBrushFactory() {} virtual KoToolBase * createTool(KoCanvasBase *canvas) { return new KisToolLazyBrush(canvas); } }; #endif // KIS_TOOL_LAZY_BRUSH_H_ diff --git a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.cpp b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.cpp new file mode 100644 index 0000000000..815e775af1 --- /dev/null +++ b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.cpp @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2016 Dmitry Kazakov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_tool_lazy_brush_options_widget.h" + +#include "ui_kis_tool_lazy_brush_options_widget.h" + +#include +#include "KisPaletteModel.h" + +#include "kis_config.h" +#include +#include "kis_canvas_resource_provider.h" +#include "kis_signal_auto_connection.h" +#include "lazybrush/kis_colorize_mask.h" +#include "kis_image.h" +#include "kis_signals_blocker.h" +#include "kis_signal_compressor.h" +#include "kis_layer_properties_icons.h" + + +struct KisToolLazyBrushOptionsWidget::Private +{ + Private() + : transparentColorIndex(-1), + baseNodeChangedCompressor(500, KisSignalCompressor::FIRST_ACTIVE) + { + } + + Ui_KisToolLazyBrushOptionsWidget *ui; + KisPaletteModel *colorModel; + KisCanvasResourceProvider *provider; + + KisSignalAutoConnectionsStore providerSignals; + KisSignalAutoConnectionsStore maskSignals; + KisColorizeMaskSP activeMask; + + KoColorSet colorSet; + int transparentColorIndex = -1; + + KisSignalCompressor baseNodeChangedCompressor; +}; + +KisToolLazyBrushOptionsWidget::KisToolLazyBrushOptionsWidget(KisCanvasResourceProvider *provider, QWidget *parent) + : QWidget(parent), + m_d(new Private) +{ + m_d->ui = new Ui_KisToolLazyBrushOptionsWidget(); + m_d->ui->setupUi(this); + + m_d->colorModel = new KisPaletteModel(this); + m_d->ui->colorView->setPaletteModel(m_d->colorModel); + m_d->ui->colorView->setCrossedKeyword("transparent"); + + connect(m_d->ui->colorView, SIGNAL(clicked(QModelIndex)), this, SLOT(entrySelected(QModelIndex))); + connect(m_d->ui->btnTransparent, SIGNAL(toggled(bool)), this, SLOT(slotMakeTransparent(bool))); + connect(m_d->ui->btnRemove, SIGNAL(clicked()), this, SLOT(slotRemove())); + + connect(m_d->ui->chkAutoUpdates, SIGNAL(toggled(bool)), m_d->ui->btnUpdate, SLOT(setDisabled(bool))); + + connect(m_d->ui->btnUpdate, SIGNAL(clicked()), this, SLOT(slotUpdate())); + connect(m_d->ui->chkAutoUpdates, SIGNAL(toggled(bool)), this, SLOT(slotSetAutoUpdates(bool))); + connect(m_d->ui->chkShowKeyStrokes, SIGNAL(toggled(bool)), this, SLOT(slotSetShowKeyStrokes(bool))); + connect(m_d->ui->chkShowOutput, SIGNAL(toggled(bool)), this, SLOT(slotSetShowOutput(bool))); + + connect(&m_d->baseNodeChangedCompressor, SIGNAL(timeout()), this, SLOT(slotUpdateNodeProperties())); + + + m_d->provider = provider; + + const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8(); + + m_d->colorSet.add(KoColorSetEntry(KoColor(Qt::red, cs), "color1")); + m_d->colorSet.add(KoColorSetEntry(KoColor(Qt::green, cs), "color2")); + m_d->colorSet.add(KoColorSetEntry(KoColor(Qt::blue, cs), "color3")); + + m_d->colorModel->setColorSet(&m_d->colorSet); +} + +KisToolLazyBrushOptionsWidget::~KisToolLazyBrushOptionsWidget() +{ +} + +void KisToolLazyBrushOptionsWidget::showEvent(QShowEvent *event) +{ + QWidget::showEvent(event); + + m_d->providerSignals.addConnection( + m_d->provider, SIGNAL(sigNodeChanged(KisNodeSP)), + this, SLOT(slotCurrentNodeChanged(KisNodeSP))); + + m_d->providerSignals.addConnection( + m_d->provider, SIGNAL(sigFGColorChanged(const KoColor&)), + this, SLOT(slotCurrentFgColorChanged(const KoColor&))); + + slotCurrentNodeChanged(m_d->provider->currentNode()); + slotCurrentFgColorChanged(m_d->provider->fgColor()); +} + +void KisToolLazyBrushOptionsWidget::hideEvent(QHideEvent *event) +{ + QWidget::hideEvent(event); + + m_d->providerSignals.clear(); +} + +void KisToolLazyBrushOptionsWidget::entrySelected(QModelIndex index) +{ + if (!index.isValid()) return; + + const int i = m_d->colorModel->idFromIndex(index); + + if (i >= 0 && i < m_d->colorSet.nColors()) { + KoColorSetEntry entry = m_d->colorSet.getColor(i); + m_d->provider->setFGColor(entry.color); + } + + const bool transparentChecked = i >= 0 && i == m_d->transparentColorIndex; + KisSignalsBlocker b(m_d->ui->btnTransparent); + m_d->ui->btnTransparent->setChecked(transparentChecked); +} + +void KisToolLazyBrushOptionsWidget::slotCurrentFgColorChanged(const KoColor &color) +{ + int selectedIndex = -1; + + for (int i = 0; i < m_d->colorSet.nColors(); i++) { + KoColorSetEntry entry = m_d->colorSet.getColor(i); + if (entry.color == color) { + selectedIndex = i; + break; + } + } + + m_d->ui->btnRemove->setEnabled(selectedIndex >= 0); + m_d->ui->btnTransparent->setEnabled(selectedIndex >= 0); + + if (selectedIndex < 0) { + m_d->ui->btnTransparent->setChecked(false); + } + + QModelIndex newIndex = m_d->colorModel->indexFromId(selectedIndex); + + if (newIndex != m_d->ui->colorView->currentIndex()) { + m_d->ui->colorView->setCurrentIndex(newIndex); + } +} + +void KisToolLazyBrushOptionsWidget::slotColorLabelsChanged() +{ + m_d->colorSet.clear(); + m_d->transparentColorIndex = -1; + + if (m_d->activeMask) { + KisColorizeMask::KeyStrokeColors colors = m_d->activeMask->keyStrokesColors(); + m_d->transparentColorIndex = colors.transparentIndex; + + for (int i = 0; i < colors.colors.size(); i++) { + const QString name = i == m_d->transparentColorIndex ? "transparent" : ""; + m_d->colorSet.add(KoColorSetEntry(colors.colors[i], name)); + } + } + + m_d->colorModel->setColorSet(&m_d->colorSet); + slotCurrentFgColorChanged(m_d->provider->fgColor()); +} + +void KisToolLazyBrushOptionsWidget::slotUpdateNodeProperties() +{ + KisSignalsBlocker b(m_d->ui->chkAutoUpdates, + m_d->ui->btnUpdate, + m_d->ui->chkShowKeyStrokes, + m_d->ui->chkShowOutput); + + // not implemented yet! + //m_d->ui->chkAutoUpdates->setEnabled(m_d->activeMask); + m_d->ui->chkAutoUpdates->setEnabled(false); + + bool value = false; + + value = m_d->activeMask && !KisLayerPropertiesIcons::nodeProperty(m_d->activeMask, KisLayerPropertiesIcons::colorizeNeedsUpdate, true).toBool(); + m_d->ui->btnUpdate->setEnabled(m_d->activeMask && !m_d->ui->chkAutoUpdates->isChecked()); + m_d->ui->btnUpdate->setChecked(value); + + value = m_d->activeMask && KisLayerPropertiesIcons::nodeProperty(m_d->activeMask, KisLayerPropertiesIcons::colorizeShowKeyStrokes, true).toBool(); + m_d->ui->chkShowKeyStrokes->setEnabled(m_d->activeMask); + m_d->ui->chkShowKeyStrokes->setChecked(value); + + value = m_d->activeMask && KisLayerPropertiesIcons::nodeProperty(m_d->activeMask, KisLayerPropertiesIcons::colorizeShowColoring, true).toBool(); + m_d->ui->chkShowOutput->setEnabled(m_d->activeMask); + m_d->ui->chkShowOutput->setChecked(value); +} + +void KisToolLazyBrushOptionsWidget::slotCurrentNodeChanged(KisNodeSP node) +{ + m_d->maskSignals.clear(); + + KisColorizeMask *mask = dynamic_cast(node.data()); + m_d->activeMask = mask; + + if (m_d->activeMask) { + m_d->maskSignals.addConnection( + m_d->activeMask, SIGNAL(sigKeyStrokesListChanged()), + this, SLOT(slotColorLabelsChanged())); + + m_d->maskSignals.addConnection( + m_d->provider->currentImage(), SIGNAL(sigNodeChanged(KisNodeSP)), + this, SLOT(slotUpdateNodeProperties())); + } + + slotColorLabelsChanged(); + slotUpdateNodeProperties(); + m_d->ui->colorView->setEnabled(m_d->activeMask); +} + +void KisToolLazyBrushOptionsWidget::slotMakeTransparent(bool value) +{ + KIS_ASSERT_RECOVER_RETURN(m_d->activeMask); + + QModelIndex index = m_d->ui->colorView->currentIndex(); + if (!index.isValid()) return; + + const int activeIndex = m_d->colorModel->idFromIndex(index); + KIS_ASSERT_RECOVER_RETURN(activeIndex >= 0); + + KisColorizeMask::KeyStrokeColors colors; + + for (int i = 0; i < m_d->colorSet.nColors(); i++) { + colors.colors << m_d->colorSet.getColor(i).color; + } + + colors.transparentIndex = value ? activeIndex : -1; + + m_d->activeMask->setKeyStrokesColors(colors); +} + +void KisToolLazyBrushOptionsWidget::slotRemove() +{ + KIS_ASSERT_RECOVER_RETURN(m_d->activeMask); + + QModelIndex index = m_d->ui->colorView->currentIndex(); + if (!index.isValid()) return; + + const int activeIndex = m_d->colorModel->idFromIndex(index); + KIS_ASSERT_RECOVER_RETURN(activeIndex >= 0); + + + const KoColor color = m_d->colorSet.getColor(activeIndex).color; + m_d->activeMask->removeKeyStroke(color); +} + +void KisToolLazyBrushOptionsWidget::slotUpdate() +{ + KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->activeMask); + KisLayerPropertiesIcons::setNodeProperty(m_d->activeMask, KisLayerPropertiesIcons::colorizeNeedsUpdate, false, m_d->provider->currentImage()); +} + +void KisToolLazyBrushOptionsWidget::slotSetAutoUpdates(bool value) +{ + ENTER_FUNCTION() << ppVar(value); +} + +void KisToolLazyBrushOptionsWidget::slotSetShowKeyStrokes(bool value) +{ + KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->activeMask); + KisLayerPropertiesIcons::setNodeProperty(m_d->activeMask, KisLayerPropertiesIcons::colorizeShowKeyStrokes, value, m_d->provider->currentImage()); +} + +void KisToolLazyBrushOptionsWidget::slotSetShowOutput(bool value) +{ + KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->activeMask); + KisLayerPropertiesIcons::setNodeProperty(m_d->activeMask, KisLayerPropertiesIcons::colorizeShowColoring, value, m_d->provider->currentImage()); +} + diff --git a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.h b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.h new file mode 100644 index 0000000000..4ef1f96c35 --- /dev/null +++ b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016 Dmitry Kazakov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __KIS_TOOL_LAZY_BRUSH_OPTIONS_WIDGET_H +#define __KIS_TOOL_LAZY_BRUSH_OPTIONS_WIDGET_H + +#include +#include +#include + +#include "kis_types.h" + +class KisCanvasResourceProvider; +class KoColor; + + +class KisToolLazyBrushOptionsWidget : public QWidget +{ + Q_OBJECT +public: + KisToolLazyBrushOptionsWidget(KisCanvasResourceProvider *provider, QWidget *parent); + ~KisToolLazyBrushOptionsWidget(); + +private Q_SLOTS: + void entrySelected(QModelIndex index); + void slotCurrentFgColorChanged(const KoColor &color); + void slotCurrentNodeChanged(KisNodeSP node); + void slotColorLabelsChanged(); + + void slotMakeTransparent(bool value); + void slotRemove(); + + void slotUpdate(); + void slotSetAutoUpdates(bool value); + void slotSetShowKeyStrokes(bool value); + void slotSetShowOutput(bool value); + + void slotUpdateNodeProperties(); + +protected: + void showEvent(QShowEvent *event); + void hideEvent(QHideEvent *event); + +private: + struct Private; + const QScopedPointer m_d; +}; + +#endif /* __KIS_TOOL_LAZY_BRUSH_OPTIONS_WIDGET_H */ diff --git a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.ui b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.ui new file mode 100644 index 0000000000..6d83b21a7e --- /dev/null +++ b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.ui @@ -0,0 +1,143 @@ + + + KisToolLazyBrushOptionsWidget + + + + 0 + 0 + 233 + 264 + + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + Auto updates + + + + + + + Update + + + true + + + + + + + + + Show key strokes + + + + + + + Show output + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 10 + + + + + + + + Key Strokes + + + true + + + + 0 + + + 0 + + + 0 + + + + + + 0 + 16 + + + + + + + + + + Transparent + + + true + + + + + + + Remove + + + + + + + + + + + + + KisPaletteView + QTableView +
kis_palette_view.h
+
+
+ + +