diff --git a/libs/widgets/KoResourcePopupAction.cpp b/libs/widgets/KoResourcePopupAction.cpp index 182eb7739b..8b692d3d66 100644 --- a/libs/widgets/KoResourcePopupAction.cpp +++ b/libs/widgets/KoResourcePopupAction.cpp @@ -1,210 +1,215 @@ /* 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 "KoResourceItemView.h" #include "KoResourceModel.h" #include "KoResourceItemDelegate.h" #include #include "KoCheckerBoardPainter.h" #include "KoShapeBackground.h" #include #include #include #include #include #include #include #include #include #include #include #include #include class KoResourcePopupAction::Private { public: QMenu *menu = 0; KoResourceModel *model = 0; KoResourceItemView *resourceList = 0; QSharedPointer background; KoImageCollection *imageCollection = 0; KoCheckerBoardPainter checkerPainter {4}; }; KoResourcePopupAction::KoResourcePopupAction(QSharedPointerresourceAdapter, 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 KoResourceItemView(widget); d->model = new KoResourceModel(resourceAdapter, widget); d->resourceList->setModel(d->model); d->resourceList->setItemDelegate(new KoResourceItemDelegate(widget)); KoResourceModel * resourceModel = qobject_cast(d->resourceList->model()); if (resourceModel) { resourceModel->setColumnCount(1); } KoResource *resource = 0; QList resources = resourceAdapter->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(KoResource *resource) { QModelIndex index = d->model->indexFromResource(resource); if (index.isValid()) { d->resourceList->setCurrentIndex(index); indexChanged(index); } } KoResource* KoResourcePopupAction::currentResource() const { QModelIndex index = d->resourceList->currentIndex(); if (!index.isValid()) return 0; return static_cast(index.internalPointer()); } +void KoResourcePopupAction::keepAspectRatio(bool keepRatio) +{ + d->resourceList->keepAspectRatio(keepRatio); +} + void KoResourcePopupAction::indexChanged(const QModelIndex &modelIndex) { if (! modelIndex.isValid()) { return; } d->menu->hide(); KoResource *resource = static_cast(modelIndex.internalPointer()); if(resource) { KoAbstractGradient *gradient = dynamic_cast(resource); KoPattern *pattern = dynamic_cast(resource); 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) { 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 ce64f1ad17..91fc3e612e 100644 --- a/libs/widgets/KoResourcePopupAction.h +++ b/libs/widgets/KoResourcePopupAction.h @@ -1,74 +1,76 @@ /* 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 "kritawidgets_export.h" class KoShapeBackground; class KoAbstractResourceServerAdapter; class QModelIndex; class KoResource; 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 resourceAdapter pointer to the gradient or pattern * @param parent The parent for this action. */ - explicit KoResourcePopupAction(QSharedPointergradientResourceAdapter, QObject *parent = 0); + explicit KoResourcePopupAction(QSharedPointerresourceAdapter, QObject *parent = 0); /** * Destructor */ ~KoResourcePopupAction() override; QSharedPointer currentBackground() const; void setCurrentBackground(QSharedPointer background); void setCurrentResource(KoResource *resource); KoResource *currentResource() const; + void keepAspectRatio(bool keepRatio); + 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 70274986c1..f60812793f 100644 --- a/plugins/filters/gradientmap/gradientmap.cpp +++ b/plugins/filters/gradientmap/gradientmap.cpp @@ -1,135 +1,137 @@ /* * 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_page->btnGradientChooser); + m_gradientPopUp->keepAspectRatio(false); + m_activeGradient = KoStopGradient::fromQGradient(dynamic_cast(gradientResourceAdapter->resources().first())->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())); QObject::connect(m_page->colorModeComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &KisConfigWidget::sigConfigurationItemChanged); QObject::connect(m_page->ditherWidget, &KisDitherWidget::sigConfigurationItemChanged, this, &KisConfigWidget::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()); } cfg->setProperty("colorMode", m_page->colorModeComboBox->currentIndex()); m_page->ditherWidget->configuration(*cfg, "dither/"); 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()); } m_page->gradientEditor->setGradient(m_activeGradient); } m_page->colorModeComboBox->setCurrentIndex(config->getInt("colorMode")); m_page->ditherWidget->setConfiguration(*config, "dither/"); } 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"