diff --git a/libs/ui/kis_autogradient.cc b/libs/ui/kis_autogradient.cc index e6ceaac593..fd3d4139d3 100644 --- a/libs/ui/kis_autogradient.cc +++ b/libs/ui/kis_autogradient.cc @@ -1,342 +1,358 @@ /* * Copyright (c) 2004 Cyrille Berger * 2004 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 "kis_autogradient.h" #include #include #include #include #include #include #include "kis_debug.h" #include "KisGradientSliderWidget.h" /****************************** KisAutogradient ******************************/ KisAutogradientEditor::KisAutogradientEditor(KoSegmentGradientSP gradient, QWidget *parent, const char* name, const QString& caption, KoColor fgColor, KoColor bgColor) : QWidget(parent) , m_autogradientResource(gradient) , m_fgColor(fgColor) , m_bgColor(bgColor) { setObjectName(name); setupUi(this); setWindowTitle(caption); gradientSlider->setGradientResource(m_autogradientResource); nameedit->setText(gradient->name()); KoGradientSegment* segment = gradientSlider->selectedSegment(); if (segment) { slotSelectedSegment(segment); } connect(nameedit, SIGNAL(editingFinished()), this, SLOT(slotChangedName())); connect(gradientSlider, SIGNAL(sigSelectedSegment(KoGradientSegment*)), SLOT(slotSelectedSegment(KoGradientSegment*))); connect(gradientSlider, SIGNAL(sigChangedSegment(KoGradientSegment*)), SLOT(slotChangedSegment(KoGradientSegment*))); connect(comboBoxColorInterpolationType, SIGNAL(activated(int)), SLOT(slotChangedColorInterpolation(int))); connect(comboBoxInterpolationType, SIGNAL(activated(int)), SLOT(slotChangedInterpolation(int))); connect(leftColorButton, SIGNAL(changed(KoColor)), SLOT(slotChangedLeftColor(KoColor))); connect(rightColorButton, SIGNAL(changed(KoColor)), SLOT(slotChangedRightColor(KoColor))); connect(intNumInputLeftOpacity, SIGNAL(valueChanged(int)), SLOT(slotChangedLeftOpacity(int))); connect(intNumInputRightOpacity, SIGNAL(valueChanged(int)), SLOT(slotChangedRightOpacity(int))); connect(leftBtnGroup, SIGNAL(buttonToggled(QAbstractButton*, bool)), this, SLOT(slotChangedLeftType(QAbstractButton*, bool))); connect(rightBtnGroup, SIGNAL(buttonToggled(QAbstractButton*, bool)), this, SLOT(slotChangedRightType(QAbstractButton*, bool))); connect(leftForegroundTransparent, SIGNAL(toggled(bool)), this, SLOT(slotChangedLeftTypeTransparent(bool))); connect(leftBackgroundTransparent, SIGNAL(toggled(bool)), this, SLOT(slotChangedLeftTypeTransparent(bool))); connect(rightForegroundTransparent, SIGNAL(toggled(bool)), this, SLOT(slotChangedRightTypeTransparent(bool))); connect(rightBackgroundTransparent, SIGNAL(toggled(bool)), this, SLOT(slotChangedRightTypeTransparent(bool))); } void KisAutogradientEditor::activate() { paramChanged(); } +void KisAutogradientEditor::disableTransparentCheckboxes() { + leftForegroundTransparent->setEnabled(false); + leftBackgroundTransparent->setEnabled(false); + rightForegroundTransparent->setEnabled(false); + rightBackgroundTransparent->setEnabled(false); +} + void KisAutogradientEditor::slotSelectedSegment(KoGradientSegment* segment) { leftColorButton->setColor(segment->startColor()); rightColorButton->setColor(segment->endColor()); comboBoxColorInterpolationType->setCurrentIndex(segment->colorInterpolation()); comboBoxInterpolationType->setCurrentIndex(segment->interpolation()); int leftOpacity = segment->startColor().opacityF(); intNumInputLeftOpacity->setValue(leftOpacity * 100); intNumInputLeftOpacity->setSuffix(i18n(" %")); int rightOpacity = segment->endColor().opacityF(); intNumInputRightOpacity->setValue(rightOpacity * 100); intNumInputRightOpacity->setSuffix(i18n(" %")); KoGradientSegmentEndpointType leftType = segment->startType(); KoGradientSegmentEndpointType rightType = segment->endType(); + disableTransparentCheckboxes(); //disable all of them, then enable the correct ones switch (leftType) { case COLOR_ENDPOINT: leftColorRadioButton->setChecked(true); break; case FOREGROUND_TRANSPARENT_ENDPOINT: leftForegroundTransparent->setChecked(true); case FOREGROUND_ENDPOINT: + leftForegroundTransparent->setEnabled(true); leftForegroundRadioButton->setChecked(true); break; case BACKGROUND_TRANSPARENT_ENDPOINT: leftBackgroundTransparent->setChecked(true); case BACKGROUND_ENDPOINT: + leftBackgroundTransparent->setEnabled(true); leftBackgroundRadioButton->setChecked(true); break; } switch (rightType) { case COLOR_ENDPOINT: rightColorRadioButton->setChecked(true); break; case FOREGROUND_TRANSPARENT_ENDPOINT: rightForegroundTransparent->setChecked(true); case FOREGROUND_ENDPOINT: + rightForegroundTransparent->setEnabled(true); rightForegroundRadioButton->setChecked(true); break; case BACKGROUND_TRANSPARENT_ENDPOINT: rightBackgroundTransparent->setChecked(true); case BACKGROUND_ENDPOINT: + rightBackgroundTransparent->setEnabled(true); rightBackgroundRadioButton->setChecked(true); break; } paramChanged(); } void KisAutogradientEditor::slotChangedSegment(KoGradientSegment*) { paramChanged(); } void KisAutogradientEditor::slotChangedInterpolation(int type) { KoGradientSegment* segment = gradientSlider->selectedSegment(); if (segment) segment->setInterpolation(type); gradientSlider->update(); paramChanged(); } void KisAutogradientEditor::slotChangedColorInterpolation(int type) { KoGradientSegment* segment = gradientSlider->selectedSegment(); if (segment) segment->setColorInterpolation(type); gradientSlider->update(); paramChanged(); } void KisAutogradientEditor::slotChangedLeftColor(const KoColor& color) { KoGradientSegment* segment = gradientSlider->selectedSegment(); if (segment) { KoColor c(color, segment->startColor().colorSpace()); c.setOpacity(segment->startColor().opacityU8()); segment->setStartColor(c); } gradientSlider->update(); paramChanged(); } void KisAutogradientEditor::slotChangedRightColor(const KoColor& color) { KoGradientSegment* segment = gradientSlider->selectedSegment(); if (segment) { KoColor c(color, segment->endColor().colorSpace()); c.setOpacity(segment->endColor().opacityU8()); segment->setEndColor(c); } gradientSlider->repaint(); paramChanged(); } void KisAutogradientEditor::slotChangedLeftOpacity(int value) { KoGradientSegment* segment = gradientSlider->selectedSegment(); if (segment) { KoColor c(segment->startColor(), segment->startColor().colorSpace()); c.setOpacity(qreal(value) / qreal(100.0)); segment->setStartColor(c); } gradientSlider->repaint(); paramChanged(); } void KisAutogradientEditor::slotChangedRightOpacity(int value) { KoGradientSegment* segment = gradientSlider->selectedSegment(); if (segment) { KoColor c(segment->endColor(), segment->endColor().colorSpace()); c.setOpacity(quint8((value *OPACITY_OPAQUE_U8) / 100)); segment->setEndColor(c); } gradientSlider->repaint(); paramChanged(); } void KisAutogradientEditor::slotChangedLeftType(QAbstractButton* button, bool checked) { if (!checked) { //Radio buttons, so we only care about the one that was checked, not the one unchecked return; } KoGradientSegmentEndpointType type; KoColor color; const KoColorSpace* colorSpace = m_autogradientResource->colorSpace(); if (button == leftForegroundRadioButton) { color = KoColor(m_fgColor, colorSpace); leftForegroundTransparent->setEnabled(true); + leftBackgroundTransparent->setEnabled(false); if (leftForegroundTransparent->isChecked()) { type = FOREGROUND_TRANSPARENT_ENDPOINT; } else { type = FOREGROUND_ENDPOINT; } } else if (button == leftBackgroundRadioButton) { color = KoColor(m_bgColor, colorSpace); leftBackgroundTransparent->setEnabled(true); + leftForegroundTransparent->setEnabled(false); if (leftBackgroundTransparent->isChecked()) { type = BACKGROUND_TRANSPARENT_ENDPOINT; } else { type = BACKGROUND_ENDPOINT; } } else { type = COLOR_ENDPOINT; leftForegroundTransparent->setEnabled(false); leftBackgroundTransparent->setEnabled(false); color = KoColor(leftColorButton->color(), colorSpace); } KoGradientSegment* segment = gradientSlider->selectedSegment(); if (segment) { segment->setStartType(type); } slotChangedLeftColor(color); } void KisAutogradientEditor::slotChangedRightType(QAbstractButton* button, bool checked) { if (!checked) { //Radio buttons, so we only care about the one that was checked, not the one unchecked return; } KoGradientSegmentEndpointType type; KoColor color; const KoColorSpace* colorSpace = m_autogradientResource->colorSpace(); if (button == rightForegroundRadioButton) { color = KoColor(m_fgColor, colorSpace); rightForegroundTransparent->setEnabled(true); + rightBackgroundTransparent->setEnabled(false); if (rightForegroundTransparent->isChecked()) { type = FOREGROUND_TRANSPARENT_ENDPOINT; } else { type = FOREGROUND_ENDPOINT; } } else if (button == rightBackgroundRadioButton) { color = KoColor(m_bgColor, colorSpace); rightBackgroundTransparent->setEnabled(true); + rightForegroundTransparent->setEnabled(false); if (rightBackgroundTransparent->isChecked()) { type = BACKGROUND_TRANSPARENT_ENDPOINT; } else { type = BACKGROUND_ENDPOINT; } } else { type = COLOR_ENDPOINT; rightForegroundTransparent->setEnabled(false); rightBackgroundTransparent->setEnabled(false); color = KoColor(rightColorButton->color(), colorSpace); } KoGradientSegment* segment = gradientSlider->selectedSegment(); if (segment) { segment->setEndType(type); } slotChangedRightColor(color); } void KisAutogradientEditor::slotChangedLeftTypeTransparent(bool checked) { if (leftColorRadioButton->isChecked()) { //shouldn't be able to check/uncheck in this state, but just in case return; } KoGradientSegmentEndpointType type; if (leftForegroundRadioButton->isChecked()) { if (checked) { type = FOREGROUND_TRANSPARENT_ENDPOINT; } else { type = FOREGROUND_ENDPOINT; } } else { if (checked) { type = FOREGROUND_TRANSPARENT_ENDPOINT; } else { type = FOREGROUND_ENDPOINT; } } KoGradientSegment* segment = gradientSlider->selectedSegment(); if (segment) { segment->setStartType(type); slotChangedLeftColor(segment->startColor()); } } void KisAutogradientEditor::slotChangedRightTypeTransparent(bool checked) { if (rightColorRadioButton->isChecked()) { //shouldn't be able to check/uncheck in this state, but just in case return; } KoGradientSegmentEndpointType type; if (rightForegroundRadioButton->isChecked()) { if (checked) { type = FOREGROUND_TRANSPARENT_ENDPOINT; } else { type = FOREGROUND_ENDPOINT; } } else { if (checked) { type = FOREGROUND_TRANSPARENT_ENDPOINT; } else { type = FOREGROUND_ENDPOINT; } } KoGradientSegment* segment = gradientSlider->selectedSegment(); if (segment) { segment->setEndType(type); slotChangedRightColor(segment->endColor()); } } void KisAutogradientEditor::slotChangedName() { m_autogradientResource->setName(nameedit->text()); } void KisAutogradientEditor::paramChanged() { m_autogradientResource->updatePreview(); } diff --git a/libs/ui/kis_autogradient.h b/libs/ui/kis_autogradient.h index ff3eb7b04b..c0e00c3c32 100644 --- a/libs/ui/kis_autogradient.h +++ b/libs/ui/kis_autogradient.h @@ -1,59 +1,62 @@ /* * Copyright (c) 2004 Cyrille Berger * 2004 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_AUTOGRADIENT_H_ #define _KIS_AUTOGRADIENT_H_ #include "ui_wdgautogradient.h" class KoGradientSegment; #include class KisAutogradientEditor : public QWidget, public Ui::KisWdgAutogradient { Q_OBJECT public: KisAutogradientEditor(KoSegmentGradientSP gradient, QWidget *parent, const char* name, const QString& caption, KoColor fgColor, KoColor bgColor); void activate(); +private: + void disableTransparentCheckboxes(); + private: KoSegmentGradientSP m_autogradientResource; KoColor m_fgColor; KoColor m_bgColor; private Q_SLOTS: void slotSelectedSegment(KoGradientSegment* segment); void slotChangedSegment(KoGradientSegment* segment); void slotChangedInterpolation(int type); void slotChangedColorInterpolation(int type); void slotChangedLeftColor(const KoColor& color); void slotChangedRightColor(const KoColor& color); void slotChangedLeftOpacity(int value); void slotChangedRightOpacity(int value); void slotChangedLeftType(QAbstractButton* button, bool checked); void slotChangedRightType(QAbstractButton* button, bool checked); void slotChangedLeftTypeTransparent(bool checked); void slotChangedRightTypeTransparent(bool checked); void slotChangedName(); void paramChanged(); }; #endif diff --git a/libs/ui/kis_stopgradient_editor.cpp b/libs/ui/kis_stopgradient_editor.cpp index ca0bd8713b..d5c41425d3 100644 --- a/libs/ui/kis_stopgradient_editor.cpp +++ b/libs/ui/kis_stopgradient_editor.cpp @@ -1,312 +1,318 @@ /* * Copyright (c) 2004 Cyrille Berger * 2016 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 "kis_stopgradient_editor.h" #include #include #include #include #include #include #include #include "kis_debug.h" #include /****************************** KisStopGradientEditor ******************************/ KisStopGradientEditor::KisStopGradientEditor(QWidget *parent) : QWidget(parent), m_gradient(0), m_fgColor(KoColor()), m_bgColor(KoColor()) { setupUi(this); connect(gradientSlider, SIGNAL(sigSelectedStop(int)), this, SLOT(stopChanged(int))); connect(nameedit, SIGNAL(editingFinished()), this, SLOT(nameChanged())); connect(colorButton, SIGNAL(changed(KoColor)), SLOT(colorChanged(KoColor))); connect(colorRadioButton, SIGNAL(toggled(bool)), this, SLOT(stopTypeChanged())); connect(foregroundRadioButton, SIGNAL(toggled(bool)), this, SLOT(stopTypeChanged())); connect(backgroundRadioButton, SIGNAL(toggled(bool)), this, SLOT(stopTypeChanged())); opacitySlider->setPrefix(i18n("Opacity: ")); opacitySlider->setRange(0.0, 1.0, 2); connect(opacitySlider, SIGNAL(valueChanged(qreal)), this, SLOT(opacityChanged(qreal))); buttonReverse->setIcon(KisIconUtils::loadIcon("transform_icons_mirror_x")); buttonReverse->setToolTip(i18n("Flip Gradient")); KisIconUtils::updateIcon(buttonReverse); connect(buttonReverse, SIGNAL(pressed()), SLOT(reverse())); buttonReverseSecond->setIcon(KisIconUtils::loadIcon("transform_icons_mirror_x")); buttonReverseSecond->setToolTip(i18n("Flip Gradient")); KisIconUtils::updateIcon(buttonReverseSecond); connect(buttonReverseSecond, SIGNAL(clicked()), SLOT(reverse())); this->setContextMenuPolicy(Qt::CustomContextMenu); connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showContextMenu(const QPoint &))); setCompactMode(false); setGradient(0); stopChanged(-1); } KisStopGradientEditor::KisStopGradientEditor(KoStopGradientSP gradient, QWidget *parent, const char* name, const QString& caption, const KoColor &fgColor, const KoColor &bgColor) : KisStopGradientEditor(parent) { m_fgColor = fgColor; m_bgColor = bgColor; setObjectName(name); setWindowTitle(caption); setGradient(gradient); } void KisStopGradientEditor::setCompactMode(bool value) { lblName->setVisible(!value); buttonReverse->setVisible(!value); nameedit->setVisible(!value); buttonReverseSecond->setVisible(value); } void KisStopGradientEditor::setGradient(KoStopGradientSP gradient) { m_gradient = gradient; setEnabled(m_gradient); if (m_gradient) { gradientSlider->setGradientResource(m_gradient); nameedit->setText(gradient->name()); stopChanged(gradientSlider->selectedStop()); } emit sigGradientChanged(); } void KisStopGradientEditor::notifyGlobalColorChanged(const KoColor &color) { if (colorButton->isEnabled() && color != colorButton->color()) { colorButton->setColor(color); } } boost::optional KisStopGradientEditor::currentActiveStopColor() const { if (!colorButton->isEnabled()) return boost::none; return colorButton->color(); } void KisStopGradientEditor::stopChanged(int stop) { if (!m_gradient) return; const bool hasStopSelected = stop >= 0; opacitySlider->setEnabled(hasStopSelected); colorButton->setEnabled(hasStopSelected); stopLabel->setEnabled(hasStopSelected); foregroundRadioButton->setEnabled(hasStopSelected); backgroundRadioButton->setEnabled(hasStopSelected); colorRadioButton->setEnabled(hasStopSelected); if (hasStopSelected) { KoColor color; KoGradientStopType type = m_gradient->stops()[stop].type; if (type == FOREGROUNDSTOP) { foregroundRadioButton->setChecked(true); + opacitySlider->setEnabled(false); color = m_fgColor; } else if (type == BACKGROUNDSTOP) { backgroundRadioButton->setChecked(true); + opacitySlider->setEnabled(false); color = m_bgColor; } else { colorRadioButton->setChecked(true); + opacitySlider->setEnabled(true); color = m_gradient->stops()[stop].color; } opacitySlider->setValue(color.opacityF()); color.setOpacity(1.0); colorButton->setColor(color); } emit sigGradientChanged(); } void KisStopGradientEditor::stopTypeChanged() { QList stops = m_gradient->stops(); int currentStop = gradientSlider->selectedStop(); double t = stops[currentStop].position; KoColor color = stops[currentStop].color; KoGradientStopType type; if (foregroundRadioButton->isChecked()) { type = FOREGROUNDSTOP; color = KoColor(m_fgColor, color.colorSpace()); + opacitySlider->setEnabled(false); } else if (backgroundRadioButton->isChecked()) { type = BACKGROUNDSTOP; color = KoColor(m_bgColor, color.colorSpace()); + opacitySlider->setEnabled(false); } else { type = COLORSTOP; + opacitySlider->setEnabled(true); } stops.removeAt(currentStop); stops.insert(currentStop, KoGradientStop(t, color, type)); m_gradient->setStops(stops); gradientSlider->update(); //setSelectedStopType(type); emit sigGradientChanged(); } void KisStopGradientEditor::colorChanged(const KoColor& color) { if (!m_gradient) return; QList stops = m_gradient->stops(); int currentStop = gradientSlider->selectedStop(); double t = stops[currentStop].position; KoColor c(color, stops[currentStop].color.colorSpace()); c.setOpacity(stops[currentStop].color.opacityU8()); KoGradientStopType type = stops[currentStop].type; stops.removeAt(currentStop); stops.insert(currentStop, KoGradientStop(t, c, type)); m_gradient->setStops(stops); gradientSlider->update(); emit sigGradientChanged(); } void KisStopGradientEditor::opacityChanged(qreal value) { if (!m_gradient) return; QList stops = m_gradient->stops(); int currentStop = gradientSlider->selectedStop(); double t = stops[currentStop].position; KoColor c = stops[currentStop].color; c.setOpacity(value); KoGradientStopType type = stops[currentStop].type; stops.removeAt(currentStop); stops.insert(currentStop, KoGradientStop(t, c, type)); m_gradient->setStops(stops); gradientSlider->update(); emit sigGradientChanged(); } void KisStopGradientEditor::nameChanged() { if (!m_gradient) return; m_gradient->setName(nameedit->text()); emit sigGradientChanged(); } void KisStopGradientEditor::reverse() { if (!m_gradient) return; QList stops = m_gradient->stops(); QList reversedStops; for(const KoGradientStop& stop : stops) { reversedStops.push_front(KoGradientStop(1 - stop.position, stop.color, stop.type)); } m_gradient->setStops(reversedStops); gradientSlider->setSelectedStop(stops.size() - 1 - gradientSlider->selectedStop()); emit sigGradientChanged(); } void KisStopGradientEditor::sortByValue( SortFlags flags = SORT_ASCENDING ) { if (!m_gradient) return; bool ascending = (flags & SORT_ASCENDING) > 0; bool evenDistribution = (flags & EVEN_DISTRIBUTION) > 0; QList stops = m_gradient->stops(); const int stopCount = stops.size(); QList sortedStops; std::sort(stops.begin(), stops.end(), KoGradientStopValueSort()); int stopIndex = 0; for (const KoGradientStop& stop : stops) { const float value = evenDistribution ? (float)stopIndex / (float)(stopCount - 1) : stop.color.toQColor().valueF(); const float position = ascending ? value : 1.f - value; if (ascending) { sortedStops.push_back(KoGradientStop(position, stop.color, stop.type)); } else { sortedStops.push_front(KoGradientStop(position, stop.color, stop.type)); } stopIndex++; } m_gradient->setStops(sortedStops); gradientSlider->setSelectedStop(stopCount - 1); gradientSlider->update(); emit sigGradientChanged(); } void KisStopGradientEditor::showContextMenu(const QPoint &origin) { QMenu contextMenu(i18n("Options"), this); QAction reverseValues(i18n("Reverse Values"), this); connect(&reverseValues, &QAction::triggered, this, &KisStopGradientEditor::reverse); QAction sortAscendingValues(i18n("Sort by Value"), this); connect(&sortAscendingValues, &QAction::triggered, this, [this]{ this->sortByValue(SORT_ASCENDING); } ); QAction sortAscendingDistributed(i18n("Sort by Value (Even Distribution)"), this); connect(&sortAscendingDistributed, &QAction::triggered, this, [this]{ this->sortByValue(SORT_ASCENDING | EVEN_DISTRIBUTION);} ); contextMenu.addAction(&reverseValues); contextMenu.addSeparator(); contextMenu.addAction(&sortAscendingValues); contextMenu.addAction(&sortAscendingDistributed); contextMenu.exec(mapToGlobal(origin)); }