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_ZOOM 0
32 #include <kpToolZoom.h>
40 #include <kpDocument.h>
41 #include <kpPixmapFX.h>
42 #include <kpSetOverrideCursorSaver.h>
43 #include <kpTempImage.h>
44 #include <kpToolEnvironment.h>
45 #include <kpViewManager.h>
48 struct DrawZoomRectPackage
53 static void DrawZoomRect (kpImage
*destImage
,
54 const QPoint
&topLeft
,
57 DrawZoomRectPackage
*pack
= static_cast <DrawZoomRectPackage
*> (userData
);
59 kpPixmapFX::drawNOTRect (destImage
,
60 topLeft
.x (), topLeft
.y (), pack
->normalizedRect
.width (), pack
->normalizedRect
.height (),
61 kpColor::Yellow
/*1st hint color if "Raster NOT" not supported*/,
62 kpColor::Green
/*2nd hint color if "Raster NOT" not supported*/);
66 struct kpToolZoomPrivate
68 bool dragHasBegun
, dragCompleted
;
69 DrawZoomRectPackage drawPackage
;
72 kpToolZoom::kpToolZoom (kpToolEnvironment
*environ
, QWidget
*parent
)
73 : kpTool (i18n ("Zoom"), i18n ("Zooms in and out of the image"),
75 environ
, parent
, "tool_zoom"),
76 d (new kpToolZoomPrivate ())
80 kpToolZoom::~kpToolZoom ()
86 // public virtual [base kpTool]
87 QString
kpToolZoom::iconName () const
89 // Standard KDE action icon.
90 return QString ("zoom-original");
94 // public virtual [base kpTool]
95 bool kpToolZoom::returnToPreviousToolAfterEndDraw () const
97 // If the user clicks to zoom in or out, s/he generally wants to click
98 // some more to get the exact zoom level wanted.
100 // However, if they drag out a rectangle to zoom into a particular area,
101 // they probably don't need to do any further zooming so we can return
102 // them to their previous tool.
104 // Note that if they cancel a drag (cancelShape()), we do _not_ return
105 // them to their previous tool, unlike the Color Picker. This is because
106 // cancelling a drag generally means that the user got the top-left of
107 // the drag wrong and wants to try a different top-left. In contrast,
108 // with the Color Picket, if you've made a mistake while pressing the
109 // mouse, you can just keep holding down the mouse and drag to the intended
110 // color -- a cancel with a Color Picker really means "I've decided not
111 // to pick another color after all", not "I got the start of the drag wrong"
112 // because you can correct that drag.
113 return d
->dragCompleted
;
118 QString
kpToolZoom::haventBegunDrawUserMessage () const
120 return i18n ("Click to zoom in/out or left drag to zoom into a specific area.");
124 // public virtual [base kpTool]
125 void kpToolZoom::begin ()
127 viewManager ()->setCursor (Qt::CrossCursor
);
129 setUserMessage (haventBegunDrawUserMessage ());
132 // public virtual [base kpTool]
133 void kpToolZoom::end ()
135 viewManager ()->unsetCursor ();
139 // public virtual [base kpTool]
140 void kpToolZoom::globalDraw ()
142 #if DEBUG_KP_TOOL_ZOOM
145 environ ()->fitToPage ();
149 // public virtual [base kpTool]
150 void kpToolZoom::beginDraw ()
152 d
->dragHasBegun
= false;
153 d
->dragCompleted
= false;
155 setUserMessage (cancelUserMessage ());
158 // public virtual [base kpTool]
159 void kpToolZoom::draw (const QPoint
&thisPoint
, const QPoint
&, const QRect
&normalizedRect
)
161 #if DEBUG_KP_TOOL_ZOOM
162 kDebug () << "kpToomZoom::draw() currentPoint=" << currentPoint ()
163 << " lastPoint=" << lastPoint ()
167 // TODO: Need accidental drag detection from selection tool (when dragging
168 // out new selection)
170 if (!d
->dragHasBegun
)
172 if (thisPoint
== startPoint ())
175 // Left mouse drags select an area to zoom into.
176 // However, it wouldn't make sense to select an area to "zoom out of"
177 // (using the right mouse button). Therefore, make RMB drags do the
178 // same as RMB clicks i.e. a simple zoom out, with no "area" to worry
180 if (mouseButton () == 1/*RMB*/)
183 d
->dragHasBegun
= true;
187 d
->drawPackage
.normalizedRect
= normalizedRect
;
189 kpTempImage
newTempImage (false/*always display*/,
190 normalizedRect
.topLeft (),
191 &::DrawZoomRect
, &d
->drawPackage
,
192 normalizedRect
.width (), normalizedRect
.height ());
194 viewManager ()->setFastUpdates ();
196 viewManager ()->setTempImage (newTempImage
);
198 viewManager ()->restoreFastUpdates ();
201 // public virtual [base kpTool]
202 void kpToolZoom::cancelShape ()
204 viewManager ()->invalidateTempImage ();
206 // LOREFACTOR: A lot of tools use this - push up to kpTool?
207 setUserMessage (i18n ("Let go of all the mouse buttons."));
210 // public virtual [base kpTool]
211 void kpToolZoom::releasedAllButtons ()
213 setUserMessage (haventBegunDrawUserMessage ());
216 // public virtual [base kpTool]
217 void kpToolZoom::endDraw (const QPoint
&, const QRect
&normalizedRect
)
219 #if DEBUG_KP_TOOL_ZOOM
220 kDebug () << "kpToolZoom::endDraw(rect=" << normalizedRect
<< ")"
221 << " dragHasBegun=" << d
->dragHasBegun
<< endl
;
224 // TODO: This cursor doesn't stay on for long enough because zooming uses
225 // event loop tricks.
226 kpSetOverrideCursorSaver
cursorSaver (Qt::WaitCursor
);
228 viewManager ()->invalidateTempImage ();
231 if (!d
->dragHasBegun
)
233 if (mouseButton () == 0/*LMB*/)
234 environ ()->zoomIn (true/*center under cursor*/);
236 environ ()->zoomOut (false/*don't center under cursor - as is
237 confusing behaviour when zooming
243 environ ()->zoomToRect (
245 false/*don't account for grips*/,
246 true/*care about width*/, true/*care about height*/);
248 d
->dragCompleted
= true;
253 #include <kpToolZoom.moc>