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 }