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_SELECTION 0
32
#include <kpAbstractSelectionTool.h>
33
#include <kpAbstractSelectionToolPrivate.h>
35
#include <qapplication.h>
48
#include <kpAbstractImageSelection.h>
49
#include <kpAbstractSelection.h>
50
#include <kpCommandHistory.h>
52
#include <kpDocument.h>
53
#include <kpMacroCommand.h>
54
#include <kpToolSelectionCreateCommand.h>
55
#include <kpToolSelectionDestroyCommand.h>
56
#include <kpToolSelectionEnvironment.h>
57
#include <kpToolSelectionMoveCommand.h>
58
#include <kpToolSelectionResizeScaleCommand.h>
59
#include <kpToolImageSelectionTransparencyCommand.h>
60
#include <kpToolToolBar.h>
61
#include <kpToolWidgetOpaqueOrTransparent.h>
63
#include <kpViewManager.h>
67
int kpAbstractSelectionTool::onSelectionResizeHandle () const
69
kpView *v = viewManager ()->viewUnderCursor ();
73
return v->mouseOnSelectionResizeHandle (currentViewPoint ());
76
//---------------------------------------------------------------------
79
void kpAbstractSelectionTool::initResizeScale ()
81
d->currentResizeScaleCommand = 0;
87
void kpAbstractSelectionTool::uninitResizeScale ()
89
// (state must be after construction, or after some time after endResizeScale())
90
Q_ASSERT (!d->currentResizeScaleCommand);
97
void kpAbstractSelectionTool::beginResizeScale ()
99
// (state must be after construction, or after some time after endResizeScale())
100
Q_ASSERT (!d->currentResizeScaleCommand);
102
// d->resizeScaleType
106
void kpAbstractSelectionTool::endResizeScale ()
108
// (should have been killed by cancelResizeScale() or endResizeScale())
109
Q_ASSERT (!d->currentResizeScaleCommand);
111
// d->resizeScaleType
114
//---------------------------------------------------------------------
117
void kpAbstractSelectionTool::setCursorResizeScale ()
119
#if DEBUG_KP_TOOL_SELECTION && 0
120
kDebug () << "\tonSelectionResizeHandle="
121
<< onSelectionResizeHandle () << endl;
123
Qt::CursorShape shape = Qt::ArrowCursor;
125
switch (onSelectionResizeHandle ())
127
case (kpView::Top | kpView::Left):
128
case (kpView::Bottom | kpView::Right):
129
shape = Qt::SizeFDiagCursor;
132
case (kpView::Bottom | kpView::Left):
133
case (kpView::Top | kpView::Right):
134
shape = Qt::SizeBDiagCursor;
139
shape = Qt::SizeVerCursor;
144
shape = Qt::SizeHorCursor;
148
viewManager ()->setCursor (shape);
151
//---------------------------------------------------------------------
154
void kpAbstractSelectionTool::setSelectionBorderForBeginDrawResizeScale ()
156
viewManager ()->setQueueUpdates ();
158
viewManager ()->setSelectionBorderVisible (true);
159
viewManager ()->setSelectionBorderFinished (true);
161
viewManager ()->restoreQueueUpdates ();
164
//---------------------------------------------------------------------
167
void kpAbstractSelectionTool::beginDrawResizeScale ()
169
d->resizeScaleType = onSelectionResizeHandle ();
171
/*virtual*/setSelectionBorderForBeginDrawResizeScale ();
173
setUserMessage (cancelUserMessage ());
176
//---------------------------------------------------------------------
180
void kpAbstractSelectionTool::drawResizeScaleTryKeepAspect (
181
int newWidth, int newHeight,
182
bool horizontalGripDragged, bool verticalGripDragged,
183
const kpAbstractSelection &originalSelection,
184
int *newWidthOut, int *newHeightOut)
186
const int oldWidth = originalSelection.width (),
187
oldHeight = originalSelection.height ();
189
// Width changed more than height? At equality, favor width.
190
// Fix width, change height.
192
// We use <horizontalGripDragged> and <verticalGripDragged> to prevent
193
// e.g. the situation where we've dragged such that newWidth < oldWidth but
194
// we're not dragging a vertical grip. We certainly don't want this
195
// code to modify the width - we want to fix the width and change the
197
if ((horizontalGripDragged ? double (newWidth) / oldWidth : 0) >=
198
(verticalGripDragged ? double (newHeight) / oldHeight : 0))
200
*newHeightOut = newWidth * oldHeight / oldWidth;
201
*newHeightOut = qMax (originalSelection.minimumHeight (), *newHeightOut);
203
// Height changed more than width?
204
// Fix height, change width.
207
*newWidthOut = newHeight * oldWidth / oldHeight;
208
*newWidthOut = qMax (originalSelection.minimumWidth (), *newWidthOut);
212
//---------------------------------------------------------------------
215
void kpAbstractSelectionTool::drawResizeScaleCalculateNewSelectionPosSize (
216
const kpAbstractSelection &originalSelection,
217
int *newX, int *newY,
218
int *newWidth, int *newHeight)
221
// Determine new width.
224
// Dragging left or right grip?
225
// If left, positive X drags decrease width.
226
// If right, positive X drags increase width.
228
if (d->resizeScaleType & kpView::Left)
230
else if (d->resizeScaleType & kpView::Right)
233
// Calcluate new width.
234
*newWidth = originalSelection.width () +
235
userXSign * (currentPoint ().x () - startPoint ().x ());
237
// Don't allow new width to be less than that kind of selection type's
239
*newWidth = qMax (originalSelection.minimumWidth (), *newWidth);
243
// Determine new height.
246
// Dragging top or bottom grip?
247
// If top, positive Y drags decrease height.
248
// If bottom, positive Y drags increase height.
250
if (d->resizeScaleType & kpView::Top)
252
else if (d->resizeScaleType & kpView::Bottom)
255
// Calcluate new height.
256
*newHeight = originalSelection.height () +
257
userYSign * (currentPoint ().y () - startPoint ().y ());
259
// Don't allow new height to be less than that kind of selection type's
261
*newHeight = qMax (originalSelection.minimumHeight (), *newHeight);
264
// Keep aspect ratio?
267
drawResizeScaleTryKeepAspect (*newWidth, *newHeight,
268
(userXSign != 0)/*X or XY grip dragged*/,
269
(userYSign != 0)/*Y or XY grip dragged*/,
271
newWidth/*ptr*/, newHeight/*ptr*/);
275
*newX = originalSelection.x ();
276
*newY = originalSelection.y ();
280
// Adjust x/y to new width/height for left/top resizes.
283
if (d->resizeScaleType & kpView::Left)
285
*newX -= (*newWidth - originalSelection.width ());
288
if (d->resizeScaleType & kpView::Top)
290
*newY -= (*newHeight - originalSelection.height ());
293
#if DEBUG_KP_TOOL_SELECTION && 1
294
kDebug () << "\t\tnewX=" << *newX
296
<< " newWidth=" << *newWidth
297
<< " newHeight=" << *newHeight
302
//---------------------------------------------------------------------
305
void kpAbstractSelectionTool::drawResizeScale (
306
const QPoint &thisPoint,
307
const QRect &/*normalizedRect*/)
309
#if DEBUG_KP_TOOL_SELECTION && 1
310
kDebug () << "\tresize/scale";
313
kpAbstractSelection *sel = document ()->selection ();
315
if (!d->dragAccepted && thisPoint == startPoint ())
317
#if DEBUG_KP_TOOL_SELECTION && 1
318
kDebug () << "\t\tnop";
321
setUserShapePoints (QPoint (sel->width (), sel->height ()));
326
giveContentIfNeeded ();
329
if (!d->currentResizeScaleCommand)
331
d->currentResizeScaleCommand
332
= new kpToolSelectionResizeScaleCommand (environ ()->commandEnvironment ());
336
const kpAbstractSelection *originalSelection =
337
d->currentResizeScaleCommand->originalSelection ();
340
// There is nothing illegal about position (-1,-1) but why not.
341
int newX = -1, newY = -1,
342
newWidth = 0, newHeight = 0;
344
// This should change all of the above values.
345
drawResizeScaleCalculateNewSelectionPosSize (
348
&newWidth, &newHeight);
351
viewManager ()->setFastUpdates ();
353
d->currentResizeScaleCommand->resizeAndMoveTo (
356
true/*smooth scale delayed*/);
358
viewManager ()->restoreFastUpdates ();
360
setUserShapePoints (QPoint (originalSelection->width (),
361
originalSelection->height ()),
364
false/*don't set size*/);
365
setUserShapeSize (newWidth - originalSelection->width (),
366
newHeight - originalSelection->height ());
369
d->dragAccepted = true;
372
//---------------------------------------------------------------------
376
void kpAbstractSelectionTool::cancelResizeScale ()
378
#if DEBUG_KP_TOOL_SELECTION
379
kDebug () << "\twas resize/scale sel - kill";
383
if (!d->currentResizeScaleCommand)
386
#if DEBUG_KP_TOOL_SELECTION
387
kDebug () << "\t\tundo currentResizeScaleCommand";
389
d->currentResizeScaleCommand->finalize (); // (unneeded but let's be safe)
390
d->currentResizeScaleCommand->unexecute ();
391
delete d->currentResizeScaleCommand;
392
d->currentResizeScaleCommand = 0;
395
//---------------------------------------------------------------------
398
void kpAbstractSelectionTool::endDrawResizeScale ()
401
if (!d->currentResizeScaleCommand)
404
d->currentResizeScaleCommand->finalize ();
406
addNeedingContentCommand (d->currentResizeScaleCommand);
407
d->currentResizeScaleCommand = 0;
410
//---------------------------------------------------------------------
413
QVariant kpAbstractSelectionTool::operationResizeScale (Operation op,
414
const QVariant &data1, const QVariant &data2)
422
case HaventBegunDrawUserMessage:
423
return /*virtual*/haventBegunDrawUserMessageResizeScale ();
426
setCursorResizeScale ();
430
beginDrawResizeScale ();
434
drawResizeScale (currentPoint (), normalizedRect ());
438
cancelResizeScale ();
442
endDrawResizeScale ();
446
Q_ASSERT (!"Unhandled operation");
454
//---------------------------------------------------------------------