3 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #define DEBUG_KP_TOOL_RECTANGULAR_BASE 0
32 #include <kpToolRectangularBase.h>
45 #include <kpCommandHistory.h>
47 #include <kpDocument.h>
48 #include <kpPainter.h>
49 #include <kpPixmapFX.h>
50 #include <kpTempImage.h>
51 #include <kpToolEnvironment.h>
52 #include <kpToolRectangularCommand.h>
53 #include <kpToolToolBar.h>
54 #include <kpToolWidgetFillStyle.h>
55 #include <kpToolWidgetLineWidth.h>
57 #include <kpViewManager.h>
60 struct kpToolRectangularBasePrivate
62 kpToolRectangularBase::DrawShapeFunc drawShapeFunc
;
64 kpToolWidgetLineWidth
*toolWidgetLineWidth
;
65 kpToolWidgetFillStyle
*toolWidgetFillStyle
;
67 QRect toolRectangleRect
;
71 kpToolRectangularBase::kpToolRectangularBase (
73 const QString
&description
,
74 DrawShapeFunc drawShapeFunc
,
76 kpToolEnvironment
*environ
, QObject
*parent
,
79 : kpTool (text
, description
, key
, environ
, parent
, name
),
80 d (new kpToolRectangularBasePrivate ())
82 d
->drawShapeFunc
= drawShapeFunc
;
84 d
->toolWidgetLineWidth
= 0, d
->toolWidgetFillStyle
= 0;
88 kpToolRectangularBase::~kpToolRectangularBase ()
94 // private slot virtual
95 void kpToolRectangularBase::slotLineWidthChanged ()
101 // private slot virtual
102 void kpToolRectangularBase::slotFillStyleChanged ()
110 QString
kpToolRectangularBase::haventBegunDrawUserMessage () const
112 return i18n ("Drag to draw.");
116 void kpToolRectangularBase::begin ()
118 #if DEBUG_KP_TOOL_RECTANGULAR_BASE
119 kDebug () << "kpToolRectangularBase::begin ()";
122 kpToolToolBar
*tb
= toolToolBar ();
125 #if DEBUG_KP_TOOL_RECTANGULAR_BASE
126 kDebug () << "\ttoolToolBar=" << tb
;
129 d
->toolWidgetLineWidth
= tb
->toolWidgetLineWidth ();
130 connect (d
->toolWidgetLineWidth
,
131 SIGNAL (lineWidthChanged (int)),
133 SLOT (slotLineWidthChanged ()));
134 d
->toolWidgetLineWidth
->show ();
136 d
->toolWidgetFillStyle
= tb
->toolWidgetFillStyle ();
137 connect (d
->toolWidgetFillStyle
,
138 SIGNAL (fillStyleChanged (kpToolWidgetFillStyle::FillStyle
)),
140 SLOT (slotFillStyleChanged ()));
141 d
->toolWidgetFillStyle
->show ();
143 viewManager ()->setCursor (QCursor (Qt::CrossCursor
));
145 setUserMessage (haventBegunDrawUserMessage ());
149 void kpToolRectangularBase::end ()
151 #if DEBUG_KP_TOOL_RECTANGULAR_BASE
152 kDebug () << "kpToolRectangularBase::end ()";
155 if (d
->toolWidgetLineWidth
)
157 disconnect (d
->toolWidgetLineWidth
,
158 SIGNAL (lineWidthChanged (int)),
160 SLOT (slotLineWidthChanged ()));
161 d
->toolWidgetLineWidth
= 0;
164 if (d
->toolWidgetFillStyle
)
166 disconnect (d
->toolWidgetFillStyle
,
167 SIGNAL (fillStyleChanged (kpToolWidgetFillStyle::FillStyle
)),
169 SLOT (slotFillStyleChanged ()));
170 d
->toolWidgetFillStyle
= 0;
173 viewManager ()->unsetCursor ();
176 void kpToolRectangularBase::applyModifiers ()
178 QRect rect
= normalizedRect ();
180 #if DEBUG_KP_TOOL_RECTANGULAR_BASE
181 kDebug () << "kpToolRectangularBase::applyModifiers(" << rect
182 << ") shift=" << shiftPressed ()
183 << " ctrl=" << controlPressed ()
187 // user wants to startPoint () == center
188 if (controlPressed ())
190 int xdiff
= qAbs (startPoint ().x () - currentPoint ().x ());
191 int ydiff
= qAbs (startPoint ().y () - currentPoint ().y ());
192 rect
= QRect (startPoint ().x () - xdiff
, startPoint ().y () - ydiff
,
193 xdiff
* 2 + 1, ydiff
* 2 + 1);
196 // user wants major axis == minor axis:
197 // rectangle --> square
198 // rounded rectangle --> rounded square
199 // ellipse --> circle
202 if (!controlPressed ())
204 if (rect
.width () < rect
.height ())
206 if (startPoint ().y () == rect
.y ())
207 rect
.setHeight (rect
.width ());
209 rect
.setY (rect
.bottom () - rect
.width () + 1);
213 if (startPoint ().x () == rect
.x ())
214 rect
.setWidth (rect
.height ());
216 rect
.setX (rect
.right () - rect
.height () + 1);
219 // have to maintain the center
222 if (rect
.width () < rect
.height ())
224 QPoint center
= rect
.center ();
225 rect
.setHeight (rect
.width ());
226 rect
.moveCenter (center
);
230 QPoint center
= rect
.center ();
231 rect
.setWidth (rect
.height ());
232 rect
.moveCenter (center
);
237 d
->toolRectangleRect
= rect
;
240 void kpToolRectangularBase::beginDraw ()
242 setUserMessage (cancelUserMessage ());
247 kpColor
kpToolRectangularBase::drawingForegroundColor () const
249 return color (mouseButton ());
253 kpColor
kpToolRectangularBase::drawingBackgroundColor () const
255 const kpColor foregroundColor
= color (mouseButton ());
256 const kpColor backgroundColor
= color (1 - mouseButton ());
258 return d
->toolWidgetFillStyle
->drawingBackgroundColor (
259 foregroundColor
, backgroundColor
);
263 void kpToolRectangularBase::updateShape ()
265 kpImage image
= document ()->getImageAt (d
->toolRectangleRect
);
267 // Invoke shape drawing function passed in ctor.
268 (*d
->drawShapeFunc
) (&image
,
269 0, 0, d
->toolRectangleRect
.width (), d
->toolRectangleRect
.height (),
270 drawingForegroundColor (), d
->toolWidgetLineWidth
->lineWidth (),
271 drawingBackgroundColor ());
273 kpTempImage
newTempImage (false/*always display*/,
274 kpTempImage::SetImage
/*render mode*/,
275 d
->toolRectangleRect
.topLeft (),
278 viewManager ()->setFastUpdates ();
280 viewManager ()->setTempImage (newTempImage
);
282 viewManager ()->restoreFastUpdates ();
286 void kpToolRectangularBase::draw (const QPoint
&, const QPoint
&, const QRect
&)
294 // Recover the start and end points from the transformed & normalized d->toolRectangleRect
296 // S. or S or SC or S == C
298 if (currentPoint ().x () >= startPoint ().x () &&
299 currentPoint ().y () >= startPoint ().y ())
301 setUserShapePoints (d
->toolRectangleRect
.topLeft (),
302 d
->toolRectangleRect
.bottomRight ());
306 else if (currentPoint ().x () >= startPoint ().x () &&
307 currentPoint ().y () < startPoint ().y ())
309 setUserShapePoints (d
->toolRectangleRect
.bottomLeft (),
310 d
->toolRectangleRect
.topRight ());
314 else if (currentPoint ().x () < startPoint ().x () &&
315 currentPoint ().y () >= startPoint ().y ())
317 setUserShapePoints (d
->toolRectangleRect
.topRight (),
318 d
->toolRectangleRect
.bottomLeft ());
324 setUserShapePoints (d
->toolRectangleRect
.bottomRight (),
325 d
->toolRectangleRect
.topLeft ());
329 void kpToolRectangularBase::cancelShape ()
331 viewManager ()->invalidateTempImage ();
333 setUserMessage (i18n ("Let go of all the mouse buttons."));
336 void kpToolRectangularBase::releasedAllButtons ()
338 setUserMessage (haventBegunDrawUserMessage ());
341 void kpToolRectangularBase::endDraw (const QPoint
&, const QRect
&)
346 // Later: So why can't we use kpViewManager::setQueueUpdates()? Check SVN
347 // log to see if this method was not available at the time of the
348 // TODO, hence justifying the TODO.
349 // Later2: kpToolPolygonalBase, and perhaps, other shapes will have the
351 viewManager ()->invalidateTempImage ();
353 environ ()->commandHistory ()->addCommand (
354 new kpToolRectangularCommand (
356 d
->drawShapeFunc
, d
->toolRectangleRect
,
357 drawingForegroundColor (), d
->toolWidgetLineWidth
->lineWidth (),
358 drawingBackgroundColor (),
359 environ ()->commandEnvironment ()));
361 setUserMessage (haventBegunDrawUserMessage ());
365 #include <kpToolRectangularBase.moc>