diff --git a/libs/ui/widgets/KoFillConfigWidget.cpp b/libs/ui/widgets/KoFillConfigWidget.cpp index 20f25c8e1e..5ff0b0d82e 100644 --- a/libs/ui/widgets/KoFillConfigWidget.cpp +++ b/libs/ui/widgets/KoFillConfigWidget.cpp @@ -1,851 +1,849 @@ /* This file is part of the KDE project * Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) * Copyright (C) 2012 Jean-Nicolas Artaud * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KoFillConfigWidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "KoResourceServerProvider.h" #include "KoResourceServerAdapter.h" #include "KoResourceSelector.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "KoZoomHandler.h" #include "KoColorPopupButton.h" #include "ui_KoFillConfigWidget.h" #include #include #include #include #include "kis_canvas_resource_provider.h" #include #include #include #include "kis_global.h" #include "kis_debug.h" static const char* const buttonnone[]={ "16 16 3 1", "# c #000000", "e c #ff0000", "- c #ffffff", "################", "#--------------#", "#-e----------e-#", "#--e--------e--#", "#---e------e---#", "#----e----e----#", "#-----e--e-----#", "#------ee------#", "#------ee------#", "#-----e--e-----#", "#----e----e----#", "#---e------e---#", "#--e--------e--#", "#-e----------e-#", "#--------------#", "################"}; static const char* const buttonsolid[]={ "16 16 2 1", "# c #000000", ". c #969696", "################", "#..............#", "#..............#", "#..............#", "#..............#", "#..............#", "#..............#", "#..............#", "#..............#", "#..............#", "#..............#", "#..............#", "#..............#", "#..............#", "#..............#", "################"}; // FIXME: Smoother gradient button. static const char* const buttongradient[]={ "16 16 15 1", "# c #000000", "n c #101010", "m c #202020", "l c #303030", "k c #404040", "j c #505050", "i c #606060", "h c #707070", "g c #808080", "f c #909090", "e c #a0a0a0", "d c #b0b0b0", "c c #c0c0c0", "b c #d0d0d0", "a c #e0e0e0", "################", "#abcdefghijklmn#", "#abcdefghijklmn#", "#abcdefghijklmn#", "#abcdefghijklmn#", "#abcdefghijklmn#", "#abcdefghijklmn#", "#abcdefghijklmn#", "#abcdefghijklmn#", "#abcdefghijklmn#", "#abcdefghijklmn#", "#abcdefghijklmn#", "#abcdefghijklmn#", "#abcdefghijklmn#", "#abcdefghijklmn#", "################"}; static const char* const buttonpattern[]={ "16 16 4 1", ". c #0a0a0a", "# c #333333", "a c #a0a0a0", "b c #ffffffff", "################", "#aaaaabbbbaaaaa#", "#aaaaabbbbaaaaa#", "#aaaaabbbbaaaaa#", "#aaaaabbbbaaaaa#", "#aaaaabbbbaaaaa#", "#bbbbbaaaabbbbb#", "#bbbbbaaaabbbbb#", "#bbbbbaaaabbbbb#", "#bbbbbaaaabbbbb#", "#aaaaabbbbaaaaa#", "#aaaaabbbbaaaaa#", "#aaaaabbbbaaaaa#", "#aaaaabbbbaaaaa#", "#aaaaabbbbaaaaa#", "################"}; class Q_DECL_HIDDEN KoFillConfigWidget::Private { public: Private(KoFlake::FillVariant _fillVariant) : canvas(0), colorChangedCompressor(100, KisSignalCompressor::FIRST_ACTIVE), gradientChangedCompressor(100, KisSignalCompressor::FIRST_ACTIVE), fillVariant(_fillVariant), noSelectionTrackingMode(false) { } KoColorPopupAction *colorAction; KoResourcePopupAction *gradientAction; KoResourcePopupAction *patternAction; QButtonGroup *group; KoCanvasBase *canvas; KisSignalCompressor colorChangedCompressor; KisAcyclicSignalConnector shapeChangedAcyclicConnector; KisAcyclicSignalConnector resourceManagerAcyclicConnector; KoFillConfigWidget::StyleButton selectedFillIndex; KoStopGradientSP activeGradient; KisSignalCompressor gradientChangedCompressor; KoFlake::FillVariant fillVariant; bool noSelectionTrackingMode; Ui_KoFillConfigWidget *ui; std::vector deactivationLocks; }; KoFillConfigWidget::KoFillConfigWidget(KoCanvasBase *canvas, KoFlake::FillVariant fillVariant, bool trackShapeSelection, QWidget *parent) : QWidget(parent) , d(new Private(fillVariant)) { d->canvas = canvas; if (trackShapeSelection) { d->shapeChangedAcyclicConnector.connectBackwardVoid( d->canvas->selectedShapesProxy(), SIGNAL(selectionChanged()), this, SLOT(shapeChanged())); d->shapeChangedAcyclicConnector.connectBackwardVoid( d->canvas->selectedShapesProxy(), SIGNAL(selectionContentChanged()), this, SLOT(shapeChanged())); } d->resourceManagerAcyclicConnector.connectBackwardResourcePair( d->canvas->resourceManager(), SIGNAL(canvasResourceChanged(int,QVariant)), this, SLOT(slotCanvasResourceChanged(int,QVariant))); d->resourceManagerAcyclicConnector.connectForwardVoid( this, SIGNAL(sigInternalRequestColorToResourceManager()), this, SLOT(slotProposeCurrentColorToResourceManager())); // configure GUI d->ui = new Ui_KoFillConfigWidget(); d->ui->setupUi(this); d->group = new QButtonGroup(this); d->group->setExclusive(true); d->ui->btnNoFill->setIcon(QPixmap((const char **) buttonnone)); d->group->addButton(d->ui->btnNoFill, None); d->ui->btnSolidFill->setIcon(QPixmap((const char **) buttonsolid)); d->group->addButton(d->ui->btnSolidFill, Solid); d->ui->btnGradientFill->setIcon(QPixmap((const char **) buttongradient)); d->group->addButton(d->ui->btnGradientFill, Gradient); d->ui->btnPatternFill->setIcon(QPixmap((const char **) buttonpattern)); d->group->addButton(d->ui->btnPatternFill, Pattern); d->colorAction = new KoColorPopupAction(d->ui->btnChooseSolidColor); d->colorAction->setToolTip(i18n("Change the filling color")); d->colorAction->setCurrentColor(Qt::white); d->ui->btnChooseSolidColor->setDefaultAction(d->colorAction); d->ui->btnChooseSolidColor->setPopupMode(QToolButton::InstantPopup); d->ui->btnSolidColorPick->setIcon(KisIconUtils::loadIcon("krita_tool_color_picker")); // TODO: for now the color picking button is disabled! d->ui->btnSolidColorPick->setEnabled(false); d->ui->btnSolidColorPick->setVisible(false); connect(d->colorAction, SIGNAL(colorChanged(KoColor)), &d->colorChangedCompressor, SLOT(start())); connect(&d->colorChangedCompressor, SIGNAL(timeout()), SLOT(colorChanged())); connect(d->ui->btnChooseSolidColor, SIGNAL(iconSizeChanged()), d->colorAction, SLOT(updateIcon())); connect(d->group, SIGNAL(buttonClicked(int)), SLOT(styleButtonPressed(int))); connect(d->group, SIGNAL(buttonClicked(int)), SLOT(slotUpdateFillTitle())); slotUpdateFillTitle(); styleButtonPressed(d->group->checkedId()); // Gradient selector d->ui->wdgGradientEditor->setCompactMode(true); connect(d->ui->wdgGradientEditor, SIGNAL(sigGradientChanged()), &d->gradientChangedCompressor, SLOT(start())); connect(&d->gradientChangedCompressor, SIGNAL(timeout()), SLOT(activeGradientChanged())); KoResourceServerProvider *serverProvider = KoResourceServerProvider::instance(); QSharedPointer gradientResourceAdapter( new KoResourceServerAdapter(serverProvider->gradientServer())); - d->gradientAction = new KoResourcePopupAction(gradientResourceAdapter, - d->ui->btnChoosePredefinedGradient); + d->gradientAction = new KoResourcePopupAction(ResourceType::Gradients, d->ui->btnChoosePredefinedGradient); d->gradientAction->setToolTip(i18n("Change filling gradient")); d->ui->btnChoosePredefinedGradient->setDefaultAction(d->gradientAction); d->ui->btnChoosePredefinedGradient->setPopupMode(QToolButton::InstantPopup); connect(d->gradientAction, SIGNAL(resourceSelected(QSharedPointer)), SLOT(gradientResourceChanged())); connect(d->ui->btnChoosePredefinedGradient, SIGNAL(iconSizeChanged()), d->gradientAction, SLOT(updateIcon())); d->ui->btnSaveGradient->setIcon(KisIconUtils::loadIcon("document-save")); connect(d->ui->btnSaveGradient, SIGNAL(clicked()), SLOT(slotSavePredefinedGradientClicked())); connect(d->ui->cmbGradientRepeat, SIGNAL(currentIndexChanged(int)), SLOT(slotGradientRepeatChanged())); connect(d->ui->cmbGradientType, SIGNAL(currentIndexChanged(int)), SLOT(slotGradientTypeChanged())); deactivate(); -#if 0 - +/* // Pattern selector QSharedPointerpatternResourceAdapter(new KoResourceServerAdapter(serverProvider->patternServer())); - d->patternAction = new KoResourcePopupAction(patternResourceAdapter, d->colorButton); + d->patternAction = new KoResourcePopupAction(ResourceType::Patterns, d->colorButton); d->patternAction->setToolTip(i18n("Change the filling pattern")); connect(d->patternAction, SIGNAL(resourceSelected(QSharedPointer)), this, SLOT(patternChanged(QSharedPointer))); connect(d->colorButton, SIGNAL(iconSizeChanged()), d->patternAction, SLOT(updateIcon())); +*/ -#endif } KoFillConfigWidget::~KoFillConfigWidget() { delete d; } void KoFillConfigWidget::activate() { KIS_SAFE_ASSERT_RECOVER_RETURN(!d->deactivationLocks.empty()); d->deactivationLocks.clear(); if (!d->noSelectionTrackingMode) { shapeChanged(); } else { loadCurrentFillFromResourceServer(); } updateWidgetComponentVisbility(); } void KoFillConfigWidget::deactivate() { KIS_SAFE_ASSERT_RECOVER_RETURN(d->deactivationLocks.empty()); d->deactivationLocks.push_back(KisAcyclicSignalConnector::Blocker(d->shapeChangedAcyclicConnector)); d->deactivationLocks.push_back(KisAcyclicSignalConnector::Blocker(d->resourceManagerAcyclicConnector)); } void KoFillConfigWidget::forceUpdateOnSelectionChanged() { shapeChanged(); } void KoFillConfigWidget::setNoSelectionTrackingMode(bool value) { d->noSelectionTrackingMode = value; if (!d->noSelectionTrackingMode) { shapeChanged(); } } void KoFillConfigWidget::slotUpdateFillTitle() { QString text = d->group->checkedButton() ? d->group->checkedButton()->text() : QString(); text.replace('&', QString()); d->ui->lblFillTitle->setText(text); } void KoFillConfigWidget::slotCanvasResourceChanged(int key, const QVariant &value) { if ((key == KoCanvasResourceProvider::ForegroundColor && d->fillVariant == KoFlake::Fill) || (key == KoCanvasResourceProvider::BackgroundColor && d->fillVariant == KoFlake::StrokeFill && !d->noSelectionTrackingMode) || (key == KoCanvasResourceProvider::ForegroundColor && d->noSelectionTrackingMode)) { KoColor color = value.value(); const int checkedId = d->group->checkedId(); if ((checkedId < 0 || checkedId == None || checkedId == Solid) && !(checkedId == Solid && d->colorAction->currentKoColor() == color)) { d->group->button(Solid)->setChecked(true); d->selectedFillIndex = Solid; d->colorAction->setCurrentColor(color); d->colorChangedCompressor.start(); } else if (checkedId == Gradient && key == KoCanvasResourceProvider::ForegroundColor) { d->ui->wdgGradientEditor->notifyGlobalColorChanged(color); } } else if (key == KisCanvasResourceProvider::CurrentGradient) { KoResourceSP gradient = value.value(); const int checkedId = d->group->checkedId(); if (gradient && (checkedId < 0 || checkedId == None || checkedId == Gradient)) { d->group->button(Gradient)->setChecked(true); d->gradientAction->setCurrentResource(gradient); } } } QList KoFillConfigWidget::currentShapes() { return d->canvas->selectedShapesProxy()->selection()->selectedEditableShapes(); } int KoFillConfigWidget::selectedFillIndex() { return d->selectedFillIndex; } void KoFillConfigWidget::styleButtonPressed(int buttonId) { switch (buttonId) { case KoFillConfigWidget::None: noColorSelected(); break; case KoFillConfigWidget::Solid: colorChanged(); break; case KoFillConfigWidget::Gradient: if (d->activeGradient) { activeGradientChanged(); } else { gradientResourceChanged(); } break; case KoFillConfigWidget::Pattern: // Only select mode in the widget, don't set actual pattern :/ //d->colorButton->setDefaultAction(d->patternAction); //patternChanged(d->patternAction->currentBackground()); break; } if (buttonId >= None && buttonId <= Pattern) { d->selectedFillIndex = static_cast(buttonId); updateWidgetComponentVisbility(); } } KoShapeStrokeSP KoFillConfigWidget::createShapeStroke() { KoShapeStrokeSP stroke(new KoShapeStroke()); KIS_ASSERT_RECOVER_RETURN_VALUE(d->fillVariant == KoFlake::StrokeFill, stroke); switch (d->group->checkedId()) { case KoFillConfigWidget::None: stroke->setColor(Qt::transparent); break; case KoFillConfigWidget::Solid: stroke->setColor(d->colorAction->currentColor()); break; case KoFillConfigWidget::Gradient: { QScopedPointer g(d->activeGradient->toQGradient()); QBrush newBrush = *g; stroke->setLineBrush(newBrush); stroke->setColor(Qt::transparent); break; } case KoFillConfigWidget::Pattern: break; } return stroke; } void KoFillConfigWidget::noColorSelected() { KisAcyclicSignalConnector::Blocker b(d->shapeChangedAcyclicConnector); QList selectedShapes = currentShapes(); if (selectedShapes.isEmpty()) { emit sigFillChanged(); return; } KoShapeFillWrapper wrapper(selectedShapes, d->fillVariant); KUndo2Command *command = wrapper.setColor(QColor()); if (command) { d->canvas->addCommand(command); } emit sigFillChanged(); } void KoFillConfigWidget::colorChanged() { KisAcyclicSignalConnector::Blocker b(d->shapeChangedAcyclicConnector); QList selectedShapes = currentShapes(); if (selectedShapes.isEmpty()) { emit sigInternalRequestColorToResourceManager(); emit sigFillChanged(); return; } KoShapeFillWrapper wrapper(selectedShapes, d->fillVariant); KUndo2Command *command = wrapper.setColor(d->colorAction->currentColor()); if (command) { d->canvas->addCommand(command); } emit sigInternalRequestColorToResourceManager(); emit sigFillChanged(); } void KoFillConfigWidget::slotProposeCurrentColorToResourceManager() { const int checkedId = d->group->checkedId(); bool hasColor = false; KoColor color; KoCanvasResourceProvider::CanvasResource colorSlot = KoCanvasResourceProvider::ForegroundColor; if (checkedId == Solid) { if (d->fillVariant == KoFlake::StrokeFill) { colorSlot = KoCanvasResourceProvider::BackgroundColor; } color = d->colorAction->currentKoColor(); hasColor = true; } else if (checkedId == Gradient) { if (boost::optional gradientColor = d->ui->wdgGradientEditor->currentActiveStopColor()) { color = *gradientColor; hasColor = true; } } if (hasColor) { /** * Don't let opacity leak to our resource manager system * * NOTE: theoretically, we could guarantee it on a level of the * resource manager itself, */ color.setOpacity(OPACITY_OPAQUE_U8); d->canvas->resourceManager()->setResource(colorSlot, QVariant::fromValue(color)); } } template QString findFirstAvailableResourceName(const QString &baseName, ResourceServer *server) { if (!server->resourceByName(baseName)) return baseName; int counter = 1; QString result; while ((result = QString("%1%2").arg(baseName).arg(counter)), server->resourceByName(result)) { counter++; } return result; } void KoFillConfigWidget::slotSavePredefinedGradientClicked() { KoResourceServerProvider *serverProvider = KoResourceServerProvider::instance(); auto server = serverProvider->gradientServer(); const QString defaultGradientNamePrefix = i18nc("default prefix for the saved gradient", "gradient"); QString name = d->activeGradient->name().isEmpty() ? defaultGradientNamePrefix : d->activeGradient->name(); name = findFirstAvailableResourceName(name, server); name = QInputDialog::getText(this, i18nc("@title:window", "Save Gradient"), i18n("Enter gradient name:"), QLineEdit::Normal, name); // TODO: currently we do not allow the user to // create two resources with the same name! // Please add some feedback for it! name = findFirstAvailableResourceName(name, server); d->activeGradient->setName(name); const QString saveLocation = server->saveLocation(); d->activeGradient->setFilename(saveLocation + d->activeGradient->name() + d->activeGradient->defaultFileExtension()); KoAbstractGradientSP newGradient = d->activeGradient->clone(); server->addResource(newGradient); d->gradientAction->setCurrentResource(newGradient); } void KoFillConfigWidget::activeGradientChanged() { setNewGradientBackgroundToShape(); updateGradientSaveButtonAvailability(); emit sigInternalRequestColorToResourceManager(); } void KoFillConfigWidget::gradientResourceChanged() { QSharedPointer bg = qSharedPointerDynamicCast( d->gradientAction->currentBackground()); uploadNewGradientBackground(bg->gradient()); setNewGradientBackgroundToShape(); updateGradientSaveButtonAvailability(); } void KoFillConfigWidget::slotGradientTypeChanged() { QGradient::Type type = d->ui->cmbGradientType->currentIndex() == 0 ? QGradient::LinearGradient : QGradient::RadialGradient; d->activeGradient->setType(type); activeGradientChanged(); } void KoFillConfigWidget::slotGradientRepeatChanged() { QGradient::Spread spread = QGradient::Spread(d->ui->cmbGradientRepeat->currentIndex()); d->activeGradient->setSpread(spread); activeGradientChanged(); } void KoFillConfigWidget::uploadNewGradientBackground(const QGradient *gradient) { KisSignalsBlocker b1(d->ui->wdgGradientEditor, d->ui->cmbGradientType, d->ui->cmbGradientRepeat); d->ui->wdgGradientEditor->setGradient(0); d->activeGradient = KoStopGradient::fromQGradient(gradient); d->ui->wdgGradientEditor->setGradient(d->activeGradient); d->ui->cmbGradientType->setCurrentIndex(d->activeGradient->type() != QGradient::LinearGradient); d->ui->cmbGradientRepeat->setCurrentIndex(int(d->activeGradient->spread())); } void KoFillConfigWidget::setNewGradientBackgroundToShape() { QList selectedShapes = currentShapes(); if (selectedShapes.isEmpty()) { emit sigFillChanged(); return; } KisAcyclicSignalConnector::Blocker b(d->shapeChangedAcyclicConnector); KoShapeFillWrapper wrapper(selectedShapes, d->fillVariant); QScopedPointer srcQGradient(d->activeGradient->toQGradient()); KUndo2Command *command = wrapper.applyGradientStopsOnly(srcQGradient.data()); if (command) { d->canvas->addCommand(command); } emit sigFillChanged(); } void KoFillConfigWidget::updateGradientSaveButtonAvailability() { bool savingEnabled = false; QScopedPointer currentGradient(d->activeGradient->toQGradient()); QSharedPointer bg = d->gradientAction->currentBackground(); if (bg) { QSharedPointer resourceBackground = qSharedPointerDynamicCast(bg); savingEnabled = resourceBackground->gradient()->stops() != currentGradient->stops(); savingEnabled |= resourceBackground->gradient()->type() != currentGradient->type(); savingEnabled |= resourceBackground->gradient()->spread() != currentGradient->spread(); } d->ui->btnSaveGradient->setEnabled(savingEnabled); } void KoFillConfigWidget::patternChanged(QSharedPointer background) { Q_UNUSED(background); #if 0 QSharedPointer patternBackground = qSharedPointerDynamicCast(background); if (! patternBackground) { return; } QList selectedShapes = currentShapes(); if (selectedShapes.isEmpty()) { return; } KoImageCollection *imageCollection = d->canvas->shapeController()->resourceManager()->imageCollection(); if (imageCollection) { QSharedPointer fill(new KoPatternBackground(imageCollection)); fill->setPattern(patternBackground->pattern()); d->canvas->addCommand(new KoShapeBackgroundCommand(selectedShapes, fill)); } #endif } void KoFillConfigWidget::loadCurrentFillFromResourceServer() { { KoColor color = d->canvas->resourceManager()->backgroundColor(); slotCanvasResourceChanged(KoCanvasResourceProvider::BackgroundColor, QVariant::fromValue(color)); } { KoColor color = d->canvas->resourceManager()->foregroundColor(); slotCanvasResourceChanged(KoCanvasResourceProvider::ForegroundColor, QVariant::fromValue(color)); } Q_FOREACH (QAbstractButton *button, d->group->buttons()) { button->setEnabled(true); } emit sigFillChanged(); } void KoFillConfigWidget::shapeChanged() { if (d->noSelectionTrackingMode) return; QList shapes = currentShapes(); if (shapes.isEmpty() || (shapes.size() > 1 && KoShapeFillWrapper(shapes, d->fillVariant).isMixedFill())) { Q_FOREACH (QAbstractButton *button, d->group->buttons()) { button->setEnabled(!shapes.isEmpty()); } d->group->button(None)->setChecked(true); d->selectedFillIndex = None; } else { Q_FOREACH (QAbstractButton *button, d->group->buttons()) { button->setEnabled(true); } KoShape *shape = shapes.first(); updateWidget(shape); } } bool KoFillConfigWidget::checkNewFillModeIsSame(const KoShapeFillWrapper &w) const { bool retval = false; switch (w.type()) { case KoFlake::None: retval = d->selectedFillIndex == None; break; case KoFlake::Solid: retval = d->selectedFillIndex == Solid && w.color() == d->colorAction->currentColor(); break; case KoFlake::Gradient: { KoStopGradientSP newGradient(KoStopGradient::fromQGradient(w.gradient())); retval = d->selectedFillIndex == Gradient && *newGradient == *d->activeGradient; break; } case KoFlake::Pattern: // TODO: not implemented retval = d->selectedFillIndex == Pattern && false; break; } return retval; } void KoFillConfigWidget::updateWidget(KoShape *shape) { KIS_SAFE_ASSERT_RECOVER_RETURN(shape); StyleButton newActiveButton = None; KoShapeFillWrapper wrapper(shape, d->fillVariant); if (checkNewFillModeIsSame(wrapper)) return; switch (wrapper.type()) { case KoFlake::None: break; case KoFlake::Solid: { QColor color = wrapper.color(); if (color.alpha() > 0) { newActiveButton = KoFillConfigWidget::Solid; d->colorAction->setCurrentColor(wrapper.color()); } break; } case KoFlake::Gradient: newActiveButton = KoFillConfigWidget::Gradient; uploadNewGradientBackground(wrapper.gradient()); updateGradientSaveButtonAvailability(); break; case KoFlake::Pattern: newActiveButton = KoFillConfigWidget::Pattern; break; } d->group->button(newActiveButton)->setChecked(true); d->selectedFillIndex = newActiveButton; updateWidgetComponentVisbility(); } void KoFillConfigWidget::updateWidgetComponentVisbility() { // The UI is showing/hiding things like this because the 'stacked widget' isn't very flexible // and makes it difficult to put anything underneath it without a lot empty space // hide everything first d->ui->wdgGradientEditor->setVisible(false); d->ui->btnChoosePredefinedGradient->setVisible(false); d->ui->btnChooseSolidColor->setVisible(false); d->ui->typeLabel->setVisible(false); d->ui->repeatLabel->setVisible(false); d->ui->cmbGradientRepeat->setVisible(false); d->ui->cmbGradientType->setVisible(false); d->ui->btnSolidColorPick->setVisible(false); d->ui->btnSaveGradient->setVisible(false); d->ui->gradientTypeLine->setVisible(false); d->ui->soldStrokeColorLabel->setVisible(false); d->ui->presetLabel->setVisible(false); switch (d->selectedFillIndex) { case KoFillConfigWidget::None: break; case KoFillConfigWidget::Solid: d->ui->btnChooseSolidColor->setVisible(true); d->ui->btnSolidColorPick->setVisible(true); d->ui->soldStrokeColorLabel->setVisible(true); break; case KoFillConfigWidget::Gradient: d->ui->wdgGradientEditor->setVisible(true); d->ui->btnChoosePredefinedGradient->setVisible(true); d->ui->typeLabel->setVisible(true); d->ui->repeatLabel->setVisible(true); d->ui->cmbGradientRepeat->setVisible(true); d->ui->cmbGradientType->setVisible(true); d->ui->btnSaveGradient->setVisible(true); d->ui->gradientTypeLine->setVisible(true); d->ui->presetLabel->setVisible(true); break; case KoFillConfigWidget::Pattern: break; } } diff --git a/libs/widgets/KoResourcePopupAction.cpp b/libs/widgets/KoResourcePopupAction.cpp index 2f8d91ce71..4226f41324 100644 --- a/libs/widgets/KoResourcePopupAction.cpp +++ b/libs/widgets/KoResourcePopupAction.cpp @@ -1,210 +1,210 @@ /* This file is part of the KDE project * Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) * Copyright (C) 2012 Jean-Nicolas Artaud * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KoResourcePopupAction.h" -#include "KoResourceServerAdapter.h" -#include "KisResourceItemView.h" -#include "KoLegacyResourceModel.h" -#include "KisResourceItemDelegate.h" +#include +#include +#include +#include +#include #include -#include "KoCheckerBoardPainter.h" -#include "KoShapeBackground.h" + +#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include class KoResourcePopupAction::Private { public: QMenu *menu = 0; - KoLegacyResourceModel *model = 0; + KisResourceModel *model = 0; KisResourceItemView *resourceList = 0; QSharedPointer background; KoImageCollection *imageCollection = 0; KoCheckerBoardPainter checkerPainter {4}; }; -KoResourcePopupAction::KoResourcePopupAction(QSharedPointerresourceAdapter, QObject *parent) - : QAction(parent) +KoResourcePopupAction::KoResourcePopupAction(const QString &resourceType, QObject *parent) + : QAction(parent) , d(new Private()) { - Q_ASSERT(resourceAdapter); - d->menu = new QMenu(); QWidget *widget = new QWidget(); QWidgetAction *wdgAction = new QWidgetAction(this); d->resourceList = new KisResourceItemView(widget); - d->model = new KoLegacyResourceModel(resourceAdapter, widget); + d->model = KisResourceModelProvider::instance()->resourceModel(resourceType); d->resourceList->setModel(d->model); d->resourceList->setItemDelegate(new KisResourceItemDelegate(widget)); - KoLegacyResourceModel * resourceModel = qobject_cast(d->resourceList->model()); - if (resourceModel) { - resourceModel->setColumnCount(1); - } + +/* All of this seems to be happening just to set the listview on the first row? KoResourceSP resource = 0; - QList resources = resourceAdapter->resources(); + QList resources = resourceType->resources(); if (resources.count() > 0) { resource = resources.at(0); d->resourceList->setCurrentIndex(d->model->indexFromResource(resource)); indexChanged(d->resourceList->currentIndex()); } - +*/ QHBoxLayout *layout = new QHBoxLayout(widget); layout->addWidget(d->resourceList); widget->setLayout(layout); wdgAction->setDefaultWidget(widget); d->menu->addAction(wdgAction); setMenu(d->menu); new QHBoxLayout(d->menu); d->menu->layout()->addWidget(widget); d->menu->layout()->setMargin(0); connect(d->resourceList, SIGNAL(clicked(QModelIndex)), this, SLOT(indexChanged(QModelIndex))); updateIcon(); } KoResourcePopupAction::~KoResourcePopupAction() { /* Removing the actions here make them be deleted together with their default widget. * This happens only if the actions are QWidgetAction, and we know they are since * the only ones added are in KoResourcePopupAction constructor. */ int i = 0; while(d->menu->actions().size() > 0) { d->menu->removeAction(d->menu->actions()[i]); ++i; } delete d->menu; delete d->imageCollection; delete d; } QSharedPointer KoResourcePopupAction::currentBackground() const { return d->background; } void KoResourcePopupAction::setCurrentBackground(QSharedPointer background) { d->background = background; updateIcon(); } void KoResourcePopupAction::setCurrentResource(KoResourceSP resource) { QModelIndex index = d->model->indexFromResource(resource); if (index.isValid()) { d->resourceList->setCurrentIndex(index); indexChanged(index); } } KoResourceSP KoResourcePopupAction::currentResource() const { QModelIndex index = d->resourceList->currentIndex(); if (!index.isValid()) return 0; return QSharedPointer(static_cast(index.internalPointer())); } void KoResourcePopupAction::indexChanged(const QModelIndex &modelIndex) { if (! modelIndex.isValid()) { return; } d->menu->hide(); - KoResourceSP resource = QSharedPointer(static_cast(modelIndex.internalPointer())); - if(resource) { + KoResourceSP resource = d->model->resourceForIndex(modelIndex); + + if (resource) { KoAbstractGradientSP gradient = resource.dynamicCast(); KoPatternSP pattern = resource.dynamicCast(); if (gradient) { QGradient *qg = gradient->toQGradient(); qg->setCoordinateMode(QGradient::ObjectBoundingMode); d->background = QSharedPointer(new KoGradientBackground(qg)); } else if (pattern) { KoImageCollection *collection = new KoImageCollection(); d->background = QSharedPointer(new KoPatternBackground(collection)); qSharedPointerDynamicCast(d->background)->setPattern(pattern->pattern()); } emit resourceSelected(d->background); updateIcon(); } } void KoResourcePopupAction::updateIcon() { QSize iconSize; QToolButton *toolButton = dynamic_cast(parentWidget()); if (toolButton) { iconSize = QSize(toolButton->iconSize()); } else { iconSize = QSize(16, 16); } // This must be a QImage, as drawing to a QPixmap outside the // UI thread will cause sporadic crashes. QImage pm = QImage(iconSize, QImage::Format_ARGB32_Premultiplied); pm.fill(Qt::transparent); QPainter p(&pm); QSharedPointer gradientBackground = qSharedPointerDynamicCast(d->background); QSharedPointer patternBackground = qSharedPointerDynamicCast(d->background); if (gradientBackground) { QRect innerRect(0, 0, iconSize.width(), iconSize.height()); QLinearGradient paintGradient; paintGradient.setStops(gradientBackground->gradient()->stops()); paintGradient.setStart(innerRect.topLeft()); paintGradient.setFinalStop(innerRect.topRight()); d->checkerPainter.paint(p, innerRect); p.fillRect(innerRect, QBrush(paintGradient)); - } else if (patternBackground) { + } + else if (patternBackground) { d->checkerPainter.paint(p, QRect(QPoint(),iconSize)); p.fillRect(0, 0, iconSize.width(), iconSize.height(), patternBackground->pattern()); } p.end(); setIcon(QIcon(QPixmap::fromImage(pm))); } diff --git a/libs/widgets/KoResourcePopupAction.h b/libs/widgets/KoResourcePopupAction.h index f778d02de7..6e1997549e 100644 --- a/libs/widgets/KoResourcePopupAction.h +++ b/libs/widgets/KoResourcePopupAction.h @@ -1,75 +1,75 @@ /* This file is part of the KDE project * Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) * Copyright (C) 2012 Jean-Nicolas Artaud * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KORESOURCEPOPUPACTION_H #define KORESOURCEPOPUPACTION_H #include #include #include class KoShapeBackground; class KoAbstractResourceServerAdapter; class QModelIndex; #include "kritawidgets_export.h" class KRITAWIDGETS_EXPORT KoResourcePopupAction : public QAction { Q_OBJECT public: /** * Constructs a KoResourcePopupAction (gradient or pattern) with the specified parent. * * @param gradientResourceAdapter pointer to the gradient or pattern * @param parent The parent for this action. */ - explicit KoResourcePopupAction(QSharedPointergradientResourceAdapter, QObject *parent = 0); + explicit KoResourcePopupAction(const QString &resourceType, QObject *parent = 0); /** * Destructor */ ~KoResourcePopupAction() override; QSharedPointer currentBackground() const; void setCurrentBackground(QSharedPointer background); void setCurrentResource(KoResourceSP resource); KoResourceSP currentResource() const; Q_SIGNALS: /// Emitted when a resource was selected void resourceSelected(QSharedPointer background); public Q_SLOTS: void updateIcon(); private Q_SLOTS: void indexChanged(const QModelIndex &modelIndex); private: class Private; Private * const d; }; #endif /* KORESOURCEPOPUPACTION_H */ diff --git a/plugins/filters/gradientmap/gradientmap.cpp b/plugins/filters/gradientmap/gradientmap.cpp index d9c4de40c9..aa6c66923d 100644 --- a/plugins/filters/gradientmap/gradientmap.cpp +++ b/plugins/filters/gradientmap/gradientmap.cpp @@ -1,125 +1,124 @@ /* * This file is part of the KDE project * * Copyright (c) 2016 Spencer Brown * 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 "QObject" #include "gradientmap.h" #include #include #include "krita_filter_gradient_map.h" #include "KoResourceServerProvider.h" #include "kis_config_widget.h" #include #include #include #include K_PLUGIN_FACTORY_WITH_JSON(KritaGradientMapFactory, "kritagradientmap.json", registerPlugin();) KritaGradientMapConfigWidget::KritaGradientMapConfigWidget(QWidget *parent, KisPaintDeviceSP dev, Qt::WindowFlags f) : KisConfigWidget(parent, f) { Q_UNUSED(dev) m_page = new WdgGradientMap(this); QHBoxLayout *l = new QHBoxLayout(this); Q_CHECK_PTR(l); l->addWidget(m_page); l->setContentsMargins(0, 0, 0, 0); KoResourceServerProvider *serverProvider = KoResourceServerProvider::instance(); QSharedPointer gradientResourceAdapter( new KoResourceServerAdapter(serverProvider->gradientServer())); m_gradientChangedCompressor = new KisSignalCompressor(100, KisSignalCompressor::FIRST_ACTIVE); - m_gradientPopUp = new KoResourcePopupAction(gradientResourceAdapter, - m_page->btnGradientChooser); + m_gradientPopUp = new KoResourcePopupAction(ResourceType::Gradients, m_page->btnGradientChooser); m_activeGradient = KoStopGradient::fromQGradient(gradientResourceAdapter->resources().first().dynamicCast()->toQGradient()); m_page->gradientEditor->setGradient(m_activeGradient); m_page->gradientEditor->setCompactMode(true); m_page->gradientEditor->setEnabled(true); m_page->btnGradientChooser->setDefaultAction(m_gradientPopUp); m_page->btnGradientChooser->setPopupMode(QToolButton::InstantPopup); connect(m_gradientPopUp, SIGNAL(resourceSelected(QSharedPointer)), this, SLOT(setAbstractGradientToEditor())); connect(m_page->gradientEditor, SIGNAL(sigGradientChanged()), m_gradientChangedCompressor, SLOT(start())); connect(m_gradientChangedCompressor, SIGNAL(timeout()), this, SIGNAL(sigConfigurationItemChanged())); } KritaGradientMapConfigWidget::~KritaGradientMapConfigWidget() { delete m_page; } void KritaGradientMapConfigWidget::setAbstractGradientToEditor() { QSharedPointer bg = qSharedPointerDynamicCast( m_gradientPopUp->currentBackground()); m_activeGradient = KoStopGradient::fromQGradient(bg->gradient()); m_page->gradientEditor->setGradient(m_activeGradient); } KisPropertiesConfigurationSP KritaGradientMapConfigWidget::configuration() const { KisFilterConfigurationSP cfg = new KisFilterConfiguration("gradientmap", 2); if (m_activeGradient) { QDomDocument doc; QDomElement elt = doc.createElement("gradient"); m_activeGradient->toXML(doc, elt); doc.appendChild(elt); cfg->setProperty("gradientXML", doc.toString()); } return cfg; } //----------------------------- void KritaGradientMapConfigWidget::setConfiguration(const KisPropertiesConfigurationSP config) { Q_ASSERT(config); QDomDocument doc; if (config->hasProperty("gradientXML")) { doc.setContent(config->getString("gradientXML", "")); KoStopGradient gradient = KoStopGradient::fromXML(doc.firstChildElement()); if (gradient.stops().size()>0) { m_activeGradient->setStops(gradient.stops()); } } } void KritaGradientMapConfigWidget::setView(KisViewManager *view) { Q_UNUSED(view) } //------------------------------ KritaGradientMap::KritaGradientMap(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(KisFilterSP(new KritaFilterGradientMap())); } KritaGradientMap::~KritaGradientMap() { } //----------------------------- #include "gradientmap.moc"