File indexing completed on 2024-05-12 16:02:11

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2012 C. Boemann <cbo@boemann.dk>
0003  * SPDX-FileCopyrightText: 2008 Jan Hambrecht <jaham@gmx.net>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "KoShadowConfigWidget.h"
0009 #include "ui_KoShadowConfigWidget.h"
0010 
0011 #include <KoIcon.h>
0012 #include <KoUnit.h>
0013 #include <KoColorPopupAction.h>
0014 #include <KoCanvasBase.h>
0015 #include <KoCanvasResourceProvider.h>
0016 #include <KoSelection.h>
0017 #include <KoShapeShadow.h>
0018 #include <KoShapeShadowCommand.h>
0019 #include <KoSelectedShapesProxy.h>
0020 
0021 #include <klocalizedstring.h>
0022 
0023 #include <QCheckBox>
0024 
0025 #include <math.h>
0026 
0027 class Q_DECL_HIDDEN KoShadowConfigWidget::Private
0028 {
0029 public:
0030     Private()
0031     {
0032     }
0033     Ui_KoShadowConfigWidget widget;
0034     KoColorPopupAction *actionShadowColor {nullptr};
0035     KoCanvasBase *canvas {nullptr};
0036 };
0037 
0038 KoShadowConfigWidget::KoShadowConfigWidget(QWidget *parent)
0039     : QWidget(parent)
0040     , d(new Private())
0041 {
0042     d->widget.setupUi(this);
0043     d->widget.shadowOffset->setValue(8.0);
0044     d->widget.shadowBlur->setValue(8.0);
0045     d->widget.shadowBlur->setMinimum(0.0);
0046     d->widget.shadowAngle->setValue(315.0);
0047     d->widget.shadowAngle->setMinimum(0.0);
0048     d->widget.shadowAngle->setMaximum(360.0);
0049     d->widget.shadowVisible->setChecked(false);
0050     visibilityChanged();
0051 
0052     d->actionShadowColor = new KoColorPopupAction(this);
0053     d->actionShadowColor->setCurrentColor(QColor(0, 0, 0, 192)); // some reasonable default for shadow
0054     d->actionShadowColor->setIcon(koIcon("format-stroke-color"));
0055     d->actionShadowColor->setToolTip(i18n("Change the color of the shadow"));
0056     d->widget.shadowColor->setDefaultAction(d->actionShadowColor);
0057 
0058     connect(d->widget.shadowVisible, SIGNAL(toggled(bool)), this, SLOT(applyChanges()));
0059     connect(d->widget.shadowVisible, SIGNAL(toggled(bool)), this, SLOT(visibilityChanged()));
0060     connect(d->actionShadowColor, SIGNAL(colorChanged(KoColor)), this, SLOT(applyChanges()));
0061     connect(d->widget.shadowAngle, SIGNAL(valueChanged(int)), this, SLOT(applyChanges()));
0062     connect(d->widget.shadowOffset, SIGNAL(valueChangedPt(qreal)), this, SLOT(applyChanges()));
0063     connect(d->widget.shadowBlur, SIGNAL(valueChangedPt(qreal)), this, SLOT(applyChanges()));
0064 }
0065 
0066 KoShadowConfigWidget::~KoShadowConfigWidget()
0067 {
0068     delete d;
0069 }
0070 
0071 void KoShadowConfigWidget::setShadowColor(const QColor &color)
0072 {
0073     d->widget.shadowColor->blockSignals(true);
0074     d->actionShadowColor->blockSignals(true);
0075 
0076     d->actionShadowColor->setCurrentColor( color );
0077 
0078     d->actionShadowColor->blockSignals(false);
0079     d->widget.shadowColor->blockSignals(false);
0080 }
0081 
0082 QColor KoShadowConfigWidget::shadowColor() const
0083 {
0084     return d->actionShadowColor->currentColor();
0085 }
0086 
0087 void KoShadowConfigWidget::setShadowOffset(const QPointF &offset)
0088 {
0089     qreal length = sqrt(offset.x()*offset.x() + offset.y()*offset.y());
0090     qreal angle = atan2(-offset.y(), offset.x());
0091     if (angle < 0.0) {
0092         angle += 2*M_PI;
0093     }
0094 
0095     d->widget.shadowAngle->blockSignals(true);
0096     d->widget.shadowAngle->setValue(-90 - angle * 180.0 / M_PI);
0097     d->widget.shadowAngle->blockSignals(false);
0098 
0099     d->widget.shadowOffset->blockSignals(true);
0100     d->widget.shadowOffset->changeValue(length);
0101     d->widget.shadowOffset->blockSignals(false);
0102 }
0103 
0104 QPointF KoShadowConfigWidget::shadowOffset() const
0105 {
0106     QPointF offset(d->widget.shadowOffset->value(), 0);
0107     QTransform m;
0108     m.rotate(d->widget.shadowAngle->value() + 90);
0109     return m.map(offset);
0110 }
0111 
0112 void KoShadowConfigWidget::setShadowBlur(const qreal &blur)
0113 {
0114     d->widget.shadowBlur->blockSignals(true);
0115     d->widget.shadowBlur->changeValue(blur);
0116     d->widget.shadowBlur->blockSignals(false);
0117 }
0118 
0119 qreal KoShadowConfigWidget::shadowBlur() const
0120 {
0121     return d->widget.shadowBlur->value();
0122 }
0123 
0124 void KoShadowConfigWidget::setShadowVisible(bool visible)
0125 {
0126     d->widget.shadowVisible->blockSignals(true);
0127     d->widget.shadowVisible->setChecked(visible);
0128     d->widget.shadowVisible->blockSignals(false);
0129     visibilityChanged();
0130 }
0131 
0132 bool KoShadowConfigWidget::shadowVisible() const
0133 {
0134     return d->widget.shadowVisible->isChecked();
0135 }
0136 
0137 void KoShadowConfigWidget::visibilityChanged()
0138 {
0139     d->widget.shadowAngle->setEnabled( d->widget.shadowVisible->isChecked() );
0140     d->widget.shadowBlur->setEnabled( d->widget.shadowVisible->isChecked() );
0141     d->widget.shadowColor->setEnabled( d->widget.shadowVisible->isChecked() );
0142     d->widget.shadowOffset->setEnabled( d->widget.shadowVisible->isChecked() );
0143 }
0144 
0145 void KoShadowConfigWidget::applyChanges()
0146 {
0147     if (d->canvas) {
0148         KoSelection *selection = d->canvas->selectedShapesProxy()->selection();
0149         KoShape * shape = selection->firstSelectedShape();
0150         if (! shape) {
0151             return;
0152         }
0153 
0154         KoShapeShadow *newShadow = new KoShapeShadow();
0155         newShadow->setVisible(shadowVisible());
0156         newShadow->setColor(shadowColor());
0157         newShadow->setOffset(shadowOffset());
0158         newShadow->setBlur(shadowBlur());
0159         d->canvas->addCommand(new KoShapeShadowCommand(selection->selectedShapes(), newShadow));
0160     }
0161 }
0162 
0163 void KoShadowConfigWidget::selectionChanged()
0164 {
0165     if (! d->canvas) {
0166         return;
0167     }
0168 
0169     KoSelection *selection = d->canvas->selectedShapesProxy()->selection();
0170     KoShape * shape = selection->firstSelectedShape();
0171 
0172     setEnabled(shape != 0);
0173 
0174     if (! shape) {
0175         setShadowVisible(false);
0176         return;
0177     }
0178 
0179     KoShapeShadow * shadow = shape->shadow();
0180     if (! shadow) {
0181         setShadowVisible(false);
0182         return;
0183     }
0184 
0185     setShadowVisible(shadow->isVisible());
0186     setShadowOffset(shadow->offset());
0187     setShadowColor(shadow->color());
0188     setShadowBlur(shadow->blur());
0189 }
0190 
0191 void KoShadowConfigWidget::setCanvas(KoCanvasBase *canvas)
0192 {
0193     d->canvas = canvas;
0194     connect(canvas->selectedShapesProxy(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
0195     connect(canvas->selectedShapesProxy(), SIGNAL(selectionContentChanged()), this, SLOT(selectionChanged()));
0196 
0197     setUnit(canvas->unit());
0198 
0199     connect( d->canvas->resourceManager(), SIGNAL(canvasResourceChanged(int,QVariant)),
0200              this, SLOT(resourceChanged(int,QVariant)) );
0201 }
0202 
0203 void KoShadowConfigWidget::setUnitManagers(KisSpinBoxUnitManager* managerBlur, KisSpinBoxUnitManager *managerOffset)
0204 {
0205     d->widget.shadowOffset->blockSignals(true);
0206     d->widget.shadowBlur->blockSignals(true);
0207     d->widget.shadowOffset->setUnitManager(managerOffset);
0208     d->widget.shadowBlur->setUnitManager(managerBlur);
0209     d->widget.shadowOffset->blockSignals(false);
0210     d->widget.shadowBlur->blockSignals(false);
0211 }
0212 
0213 void KoShadowConfigWidget::setUnit(const KoUnit &unit)
0214 {
0215     d->widget.shadowOffset->blockSignals(true);
0216     d->widget.shadowBlur->blockSignals(true);
0217     d->widget.shadowOffset->setUnit(unit);
0218     d->widget.shadowBlur->setUnit(unit);
0219     d->widget.shadowOffset->blockSignals(false);
0220     d->widget.shadowBlur->blockSignals(false);
0221 }
0222 
0223 void KoShadowConfigWidget::resourceChanged( int key, const QVariant & res )
0224 {
0225     if( key == KoCanvasResource::Unit ) {
0226         setUnit(res.value<KoUnit>());
0227     }
0228 }