1 /* This file is part of the KDE project
2 * Copyright (C) 2012 C. Boemann <cbo@boemann.dk>
3 * Copyright (C) 2008 Jan Hambrecht <jaham@gmx.net>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #include "KoShadowConfigWidget.h"
22 #include "ui_KoShadowConfigWidget.h"
23
24 #include <KoIcon.h>
25 #include <KoUnit.h>
26 #include <KoColorPopupAction.h>
27 #include <KoCanvasBase.h>
28 #include <KoCanvasResourceManager.h>
29 #include <KoSelection.h>
30 #include <KoShapeShadow.h>
31 #include <KoShapeShadowCommand.h>
32 #include <KoShapeManager.h>
33
34 #include <klocalizedstring.h>
35
36 #include <QCheckBox>
37
38 #include <math.h>
39
40 class Q_DECL_HIDDEN KoShadowConfigWidget::Private
41 {
42 public:
Private()43 Private()
44 {
45 }
46 Ui_KoShadowConfigWidget widget;
47 KoColorPopupAction *actionShadowColor;
48 KoCanvasBase *canvas;
49 };
50
KoShadowConfigWidget(QWidget * parent)51 KoShadowConfigWidget::KoShadowConfigWidget(QWidget *parent)
52 : QWidget(parent)
53 , d(new Private())
54 {
55 d->widget.setupUi(this);
56 d->widget.shadowOffset->setValue(8.0);
57 d->widget.shadowBlur->setValue(8.0);
58 d->widget.shadowBlur->setMinimum(0.0);
59 d->widget.shadowAngle->setValue(315.0);
60 d->widget.shadowAngle->setMinimum(0.0);
61 d->widget.shadowAngle->setMaximum(360.0);
62 d->widget.shadowVisible->setChecked(false);
63 visibilityChanged();
64
65 d->actionShadowColor = new KoColorPopupAction(this);
66 d->actionShadowColor->setCurrentColor(QColor(0, 0, 0, 192)); // some reasonable default for shadow
67 d->actionShadowColor->setIcon(koIcon("format-stroke-color"));
68 d->actionShadowColor->setToolTip(i18n("Change the color of the shadow"));
69 d->widget.shadowColor->setDefaultAction(d->actionShadowColor);
70
71 connect(d->widget.shadowVisible, SIGNAL(toggled(bool)), this, SLOT(applyChanges()));
72 connect(d->widget.shadowVisible, SIGNAL(toggled(bool)), this, SLOT(visibilityChanged()));
73 connect(d->actionShadowColor, SIGNAL(colorChanged(KoColor)), this, SLOT(applyChanges()));
74 connect(d->widget.shadowAngle, SIGNAL(valueChanged(int)), this, SLOT(applyChanges()));
75 connect(d->widget.shadowOffset, SIGNAL(valueChangedPt(qreal)), this, SLOT(applyChanges()));
76 connect(d->widget.shadowBlur, SIGNAL(valueChangedPt(qreal)), this, SLOT(applyChanges()));
77 }
78
~KoShadowConfigWidget()79 KoShadowConfigWidget::~KoShadowConfigWidget()
80 {
81 delete d;
82 }
83
setShadowColor(const QColor & color)84 void KoShadowConfigWidget::setShadowColor(const QColor &color)
85 {
86 d->widget.shadowColor->blockSignals(true);
87 d->actionShadowColor->blockSignals(true);
88
89 d->actionShadowColor->setCurrentColor( color );
90
91 d->actionShadowColor->blockSignals(false);
92 d->widget.shadowColor->blockSignals(false);
93 }
94
shadowColor() const95 QColor KoShadowConfigWidget::shadowColor() const
96 {
97 return d->actionShadowColor->currentColor();
98 }
99
setShadowOffset(const QPointF & offset)100 void KoShadowConfigWidget::setShadowOffset(const QPointF &offset)
101 {
102 qreal length = sqrt(offset.x()*offset.x() + offset.y()*offset.y());
103 qreal angle = atan2(-offset.y(), offset.x());
104 if (angle < 0.0) {
105 angle += 2*M_PI;
106 }
107
108 d->widget.shadowAngle->blockSignals(true);
109 d->widget.shadowAngle->setValue(-90 - angle * 180.0 / M_PI);
110 d->widget.shadowAngle->blockSignals(false);
111
112 d->widget.shadowOffset->blockSignals(true);
113 d->widget.shadowOffset->changeValue(length);
114 d->widget.shadowOffset->blockSignals(false);
115 }
116
shadowOffset() const117 QPointF KoShadowConfigWidget::shadowOffset() const
118 {
119 QPointF offset(d->widget.shadowOffset->value(), 0);
120 QTransform m;
121 m.rotate(d->widget.shadowAngle->value() + 90);
122 return m.map(offset);
123 }
124
setShadowBlur(const qreal & blur)125 void KoShadowConfigWidget::setShadowBlur(const qreal &blur)
126 {
127 d->widget.shadowBlur->blockSignals(true);
128 d->widget.shadowBlur->changeValue(blur);
129 d->widget.shadowBlur->blockSignals(false);
130 }
131
shadowBlur() const132 qreal KoShadowConfigWidget::shadowBlur() const
133 {
134 return d->widget.shadowBlur->value();
135 }
136
setShadowVisible(bool visible)137 void KoShadowConfigWidget::setShadowVisible(bool visible)
138 {
139 d->widget.shadowVisible->blockSignals(true);
140 d->widget.shadowVisible->setChecked(visible);
141 d->widget.shadowVisible->blockSignals(false);
142 visibilityChanged();
143 }
144
shadowVisible() const145 bool KoShadowConfigWidget::shadowVisible() const
146 {
147 return d->widget.shadowVisible->isChecked();
148 }
149
visibilityChanged()150 void KoShadowConfigWidget::visibilityChanged()
151 {
152 d->widget.shadowAngle->setEnabled( d->widget.shadowVisible->isChecked() );
153 d->widget.shadowBlur->setEnabled( d->widget.shadowVisible->isChecked() );
154 d->widget.shadowColor->setEnabled( d->widget.shadowVisible->isChecked() );
155 d->widget.shadowOffset->setEnabled( d->widget.shadowVisible->isChecked() );
156 }
157
applyChanges()158 void KoShadowConfigWidget::applyChanges()
159 {
160 if (d->canvas) {
161 KoSelection *selection = d->canvas->shapeManager()->selection();
162 KoShape * shape = selection->firstSelectedShape(KoFlake::TopLevelSelection);
163 if (! shape) {
164 return;
165 }
166
167 KoShapeShadow *newShadow = new KoShapeShadow();
168 newShadow->setVisible(shadowVisible());
169 newShadow->setColor(shadowColor());
170 newShadow->setOffset(shadowOffset());
171 newShadow->setBlur(shadowBlur());
172 d->canvas->addCommand(new KoShapeShadowCommand(selection->selectedShapes(KoFlake::TopLevelSelection), newShadow));
173 }
174 }
175
selectionChanged()176 void KoShadowConfigWidget::selectionChanged()
177 {
178 if (! d->canvas) {
179 return;
180 }
181
182 KoSelection *selection = d->canvas->shapeManager()->selection();
183 KoShape * shape = selection->firstSelectedShape(KoFlake::TopLevelSelection);
184
185 setEnabled(shape != nullptr);
186
187 if (! shape) {
188 setShadowVisible(false);
189 return;
190 }
191
192 KoShapeShadow * shadow = shape->shadow();
193 if (! shadow) {
194 setShadowVisible(false);
195 return;
196 }
197
198 setShadowVisible(shadow->isVisible());
199 setShadowOffset(shadow->offset());
200 setShadowColor(shadow->color());
201 setShadowBlur(shadow->blur());
202 }
203
setCanvas(KoCanvasBase * canvas)204 void KoShadowConfigWidget::setCanvas(KoCanvasBase *canvas)
205 {
206 d->canvas = canvas;
207 connect(canvas->shapeManager(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
208 connect(canvas->shapeManager(), SIGNAL(selectionContentChanged()), this, SLOT(selectionChanged()));
209
210 setUnit(canvas->unit());
211
212 connect( d->canvas->resourceManager(), SIGNAL(canvasResourceChanged(int,QVariant)),
213 this, SLOT(resourceChanged(int,QVariant)) );
214 }
215
setUnit(const KoUnit & unit)216 void KoShadowConfigWidget::setUnit(const KoUnit &unit)
217 {
218 d->widget.shadowOffset->blockSignals(true);
219 d->widget.shadowBlur->blockSignals(true);
220 d->widget.shadowOffset->setUnit(unit);
221 d->widget.shadowBlur->setUnit(unit);
222 d->widget.shadowOffset->blockSignals(false);
223 d->widget.shadowBlur->blockSignals(false);
224 }
225
resourceChanged(int key,const QVariant & res)226 void KoShadowConfigWidget::resourceChanged( int key, const QVariant & res )
227 {
228 if( key == KoCanvasResourceManager::Unit ) {
229 setUnit(res.value<KoUnit>());
230 }
231 }
232