Summary: | Resizing ellipses from edge grab-boxes not working correctly | ||
---|---|---|---|
Product: | [Applications] kst | Reporter: | Andrew Walker <arwalker> |
Component: | general | Assignee: | Duncan Hanson <duncan.hanson> |
Status: | RESOLVED FIXED | ||
Severity: | normal | ||
Priority: | NOR | ||
Version: | 1.x | ||
Target Milestone: | --- | ||
Platform: | unspecified | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: |
Description
Andrew Walker
2007-04-03 20:29:48 UTC
Duncan, could you check this fix in to the 1.5 branch before the 1.4 release so we can backport if necessary. SVN commit 659768 by dhanson: CCBUG:143804 most straightforward solution-- non-centered resizing of ellipses when edges are dragged. M +5 -12 kstviewellipse.cpp --- branches/work/kst/1.5/kst/src/libkstapp/kstviewellipse.cpp #659767:659768 @@ -95,22 +95,15 @@ } } - const QRect g(geometry()); - int bw(_borderWidth * p.lineWidthAdjustmentFactor()); - if (bw > g.width()/2) { - bw = g.width()/2; - } - if (bw > g.height()/2) { - bw = g.height()/2; - } + const int bw(_borderWidth * p.lineWidthAdjustmentFactor()); QPen pen(bw > 0 ? _borderColor : _foregroundColor, bw); p.setPen(pen); if (_transparentFill) { - p.setBrush(Qt::NoBrush); + p.setBrush(Qt::NoBrush); } else { p.setBrush(_foregroundColor); } - + const QRect g(geometry()); p.drawEllipse(g.x() + bw/2, g.y() + bw/2, g.width() - bw, g.height() - bw); p.restore(); } @@ -185,8 +178,8 @@ signed int KstViewEllipse::directionFor(const QPoint& pos) { signed int direction = KstViewObject::directionFor(pos); - if (direction != 0) { - // not moving, so in any resize direction, we want it centred + if (!(((direction & (UP|DOWN)) == 0) || ((direction & (LEFT|RIGHT)) == 0))) { + // not an edge. direction |= CENTEREDRESIZE; } return direction; There is one remaining problems with this fix: resizing from a corner leaves the center fixed, resizing from an edge does not. This behaviour should be made consistent to avoid confusing the user. We could do that... my own thought is that it would be nicest to just have ellipses resize in the same way as rectangles (boxes?) We could have ellipses `resize from center' when you drag their edges, but I think that will give you exactly the same functionality as resizing from a corner. I can't see anyone getting confused by the way that things are now. For both drag types, there are separate visual cues to tip you off to what is happening. So-- I don't think that anything should be done. Duncan. On 30 Apr 2007 23:26:52 -0000, Andrew Walker <arwalker@sumusltd.com> wrote: [bugs.kde.org quoted mail] The existing functionality shouldn't be changed because of a bug report without at least some discussion first. 'Resize from center' for an ellipse from the edges (the pre-existing functionality if there had been no bug) would behave differently than from the corners as the former would change only the width or height, while the latter would change both width and height. SVN commit 660202 by arwalker: BUG:143804 fix problem with resizing of ellipses while maintaining intended functionality M +72 -32 kstgfxmousehandlerutils.cpp M +2 -0 kstgfxmousehandlerutils.h M +23 -4 ksttoplevelview.cpp M +1 -1 ksttoplevelview.h M +2 -2 kstviewellipse.cpp --- branches/work/kst/1.5/kst/src/libkstapp/kstgfxmousehandlerutils.cpp #660201:660202 @@ -92,12 +92,12 @@ newHalfHeight = kMin(newHalfHeight,bounds.bottom() - anchorPoint.y()); QSize newSize(originalRect.size()); - newSize.scale(2*newHalfWidth,2*newHalfHeight,QSize::ScaleMin); + newSize.scale(2*newHalfWidth, 2*newHalfHeight, QSize::ScaleMin); newRect.setSize(newSize); newRect.moveCenter(anchorPoint); } else { - newRect = QRect(0,0,2*newHalfWidth,2*newHalfHeight); + newRect = QRect(0, 0, 2*newHalfWidth, 2*newHalfHeight); newRect.moveCenter(anchorPoint); newRect = newRect.intersect(bounds); } @@ -110,51 +110,91 @@ QRect newSize(originalSize); if (movePoint.y() == anchorPoint.y()) { - int newWidth = pos.x() - anchorPoint.x(); //defined differently than in QRect. + int newWidth = pos.x() - anchorPoint.x(); //defined differently than in QRect. - if (maintainAspect) { - double newHalfHeight = originalSize.height() * (abs(newWidth) + 1) / originalSize.width() / 2.0; //defined with the QRect convention (height = bot - top + 1) + if (maintainAspect) { + double newHalfHeight = originalSize.height() * (abs(newWidth) + 1) / originalSize.width() / 2.0; //defined with the QRect convention (height = bot - top + 1) - newHalfHeight = kMin(double(movePoint.y() - bounds.top()) + 1, newHalfHeight); // ensure we are still within the bounds. - newHalfHeight = kMin(double(bounds.bottom() - movePoint.y()) + 1, newHalfHeight); + newHalfHeight = kMin(double(movePoint.y() - bounds.top()) + 1, newHalfHeight); // ensure we are still within the bounds. + newHalfHeight = kMin(double(bounds.bottom() - movePoint.y()) + 1, newHalfHeight); - if (newWidth == 0) { // anything better to be done? - newWidth = 1; - } + if (newWidth == 0) { // anything better to be done? + newWidth = 1; + } - newWidth = (int(originalSize.width() * (newHalfHeight * 2.0) / originalSize.height()) - 1)*newWidth/abs(newWidth); // consistency of width w/ the newly calculated height. + newWidth = (int(originalSize.width() * (newHalfHeight * 2.0) / originalSize.height()) - 1)*newWidth/abs(newWidth); // consistency of width w/ the newly calculated height. - newSize.setTop(anchorPoint.y() + int(newHalfHeight - 0.5)); - newSize.setBottom(anchorPoint.y() - int(newHalfHeight - 0.5)); + newSize.setTop(anchorPoint.y() + int(newHalfHeight - 0.5)); + newSize.setBottom(anchorPoint.y() - int(newHalfHeight - 0.5)); + } + + newSize.setLeft(anchorPoint.x()); + newSize.setRight(anchorPoint.x() + newWidth); // +1 for the way widths are defined in QRect. + } else if (movePoint.x() == anchorPoint.x()) { + // mimic the case for (movePoint.y() == anchorPoint.y()). comments are there. + int newHeight = pos.y() - anchorPoint.y(); + + if (maintainAspect) { + double newHalfWidth = originalSize.width() * (abs(newHeight) + 1) / originalSize.height() / 2.0; + + newHalfWidth = kMin(double(movePoint.x() - bounds.left() + 1), newHalfWidth); + newHalfWidth = kMin(double(bounds.right() - movePoint.x() + 1), newHalfWidth); + + if (newHeight == 0) { + newHeight = 1; } - newSize.setLeft(anchorPoint.x()); - newSize.setRight(anchorPoint.x() + newWidth); // +1 for the way widths are defined in QRect. + newHeight = (int(originalSize.height() * newHalfWidth * 2.0 / originalSize.width()) - 1)*newHeight/abs(newHeight); + newSize.setLeft(anchorPoint.x() + int(newHalfWidth - 0.5)); + newSize.setRight(anchorPoint.x() - int(newHalfWidth - 0.5)); + } - } else if (movePoint.x() == anchorPoint.x()) { - // mimic the case for (movePoint.y() == anchorPoint.y()). comments are there. - int newHeight = pos.y() - anchorPoint.y(); + newSize.setTop(anchorPoint.y()); + newSize.setBottom(anchorPoint.y() + newHeight); + } - if (maintainAspect) { - double newHalfWidth = originalSize.width() * (abs(newHeight) + 1) / originalSize.height() / 2.0; + return newSize.normalize(); +} - newHalfWidth = kMin(double(movePoint.x() - bounds.left() + 1), newHalfWidth); - newHalfWidth = kMin(double(bounds.right() - movePoint.x() + 1), newHalfWidth); - if (newHeight == 0) { - newHeight = 1; - } +QRect KstGfxMouseHandlerUtils::resizeRectFromEdgeCentered(const QRect& originalRect, const QPoint& anchorPoint, const QPoint& movePoint, const QPoint& pos, const QRect& bounds, bool maintainAspect) { + QRect newRect; + bool vertical; + int newHalfWidth = abs((pos - anchorPoint).x()); + int newHalfHeight = abs((pos - anchorPoint).y()); - newHeight = (int(originalSize.height() * newHalfWidth * 2.0 / originalSize.width()) - 1)*newHeight/abs(newHeight); - newSize.setLeft(anchorPoint.x() + int(newHalfWidth - .5)); - newSize.setRight(anchorPoint.x() - int(newHalfWidth - .5)); - } + if (movePoint.x() == anchorPoint.x()) { + vertical = true; + } else { + vertical = false; + } - newSize.setTop(anchorPoint.y()); - newSize.setBottom(anchorPoint.y() + newHeight); + if (maintainAspect) { + QSize newSize(originalRect.size()); + + if (vertical) { + newHalfHeight = kMin(newHalfHeight, anchorPoint.y() - bounds.top()); + newHalfHeight = kMin(newHalfHeight, bounds.bottom() - anchorPoint.y()); + newSize.scale(originalRect.width(), 2*newHalfHeight, QSize::ScaleMin); + } else { + newHalfWidth = kMin(newHalfWidth, anchorPoint.x() - bounds.left()); + newHalfWidth = kMin(newHalfWidth, bounds.right() - anchorPoint.x()); + newSize.scale(2*newHalfWidth, originalRect.height(), QSize::ScaleMin); } - return newSize.normalize(); + newRect.setSize(newSize); + newRect.moveCenter(anchorPoint); + } else { + if (vertical) { + newRect = QRect(0, 0, originalRect.width(), 2*newHalfHeight); + } else { + newRect = QRect(0, 0, 2*newHalfWidth, originalRect.height()); + } + newRect.moveCenter(anchorPoint); + newRect = newRect.intersect(bounds); + } + + return newRect; } --- branches/work/kst/1.5/kst/src/libkstapp/kstgfxmousehandlerutils.h #660201:660202 @@ -30,6 +30,8 @@ QRect resizeRectFromCornerCentered(const QRect& originalRect, const QPoint& pos, const QRect& bounds, bool maintainAspect); // resizes a rect from an edge, keeping anchorPoint fixed. movePoint = center of edge being dragged. anchorPoint = center of opposite edge. anchorPoint and movePoint must be inside bounds already. QRect resizeRectFromEdge(const QRect& originalSize, const QPoint& anchorPoint, const QPoint& movePoint, const QPoint& pos, const QRect &bounds, bool maintainAspect); + // resizes a rect from an edge, keeping anchorPoint fixed. movePoint = center of edge being dragged. anchorPoint = center of opposite edge. anchorPoint and movePoint must be inside bounds already. + QRect resizeRectFromEdgeCentered(const QRect& originalRect, const QPoint& anchorPoint, const QPoint& movePoint, const QPoint& pos, const QRect& bounds, bool maintainAspect); // returns a new rectangle. mouseOrigin must be inside bounds already. QRect newRect(const QPoint& pos, const QPoint& mouseOrigin, const QRect& bounds, bool squareAspect); // returns a new rectangle, mouseOrigin must be inside bounds already. --- branches/work/kst/1.5/kst/src/libkstapp/ksttoplevelview.cpp #660201:660202 @@ -433,13 +433,14 @@ if ( ((direction & (UP|DOWN)) == 0) || ((direction & (LEFT|RIGHT)) == 0) ) { //resizing from edge. return KstGfxMouseHandlerUtils::resizeRectFromEdge(originalSize, anchor_pt, move_pt, npos, bounds, maintainAspect); } else { //resizing from corner. - return KstGfxMouseHandlerUtils::resizeRectFromCorner(anchor_pt, move_pt, npos, bounds,maintainAspect); + return KstGfxMouseHandlerUtils::resizeRectFromCorner(anchor_pt, move_pt, npos, bounds, maintainAspect); } } -QRect KstTopLevelView::newSizeCentered(const QRect& oldSize, const QRect& bounds, const QPoint& pos, bool maintainAspect) { +QRect KstTopLevelView::newSizeCentered(const QRect& originalSize, const QRect& bounds, int direction, const QPoint& pos, bool maintainAspect) { + QPoint anchor_pt, move_pt; QPoint npos = pos; npos.setX(kMax(npos.x(), bounds.left())); @@ -447,7 +448,25 @@ npos.setY(kMin(npos.y(), bounds.bottom())); npos.setY(kMax(npos.y(), bounds.top())); - return KstGfxMouseHandlerUtils::resizeRectFromCornerCentered(oldSize, npos, bounds, maintainAspect); + anchor_pt = move_pt = originalSize.center(); + + if ((direction & UP) != 0) { + move_pt.setY(originalSize.top()); + } else if ((direction & DOWN) != 0) { + move_pt.setY(originalSize.bottom()); + } + + if ((direction & LEFT) != 0) { + move_pt.setX(originalSize.left()); + } else if ((direction & RIGHT) != 0) { + move_pt.setX(originalSize.right()); + } + + if ( ((direction & (UP|DOWN)) == 0) || ((direction & (LEFT|RIGHT)) == 0) ) { //resizing from edge. + return KstGfxMouseHandlerUtils::resizeRectFromEdgeCentered(originalSize, anchor_pt, move_pt, npos, bounds, maintainAspect); + } else { //resizing from corner. + return KstGfxMouseHandlerUtils::resizeRectFromCornerCentered(originalSize, npos, bounds, maintainAspect); + } } @@ -836,7 +855,7 @@ //centered resize means that the center of the object stays constant const QRect old(_prevBand); - _prevBand = newSizeCentered(_pressTarget->geometry(), _pressTarget->_parent->geometry(), pos, maintainAspect); + _prevBand = newSizeCentered(_pressTarget->geometry(), _pressTarget->_parent->geometry(), _pressDirection, pos, maintainAspect); if (_prevBand != old) { KstPainter p; --- branches/work/kst/1.5/kst/src/libkstapp/ksttoplevelview.h #660201:660202 @@ -126,7 +126,7 @@ bool popupMenu(KPopupMenu *menu, const QPoint& pos); void correctPosition(KstViewObjectPtr pObject, QPoint point); QRect newSize(const QRect& originalSize, const QRect& bounds, int direction, const QPoint& pos, bool maintainAspect = false); - QRect newSizeCentered(const QRect& oldSize, const QRect& bounds, const QPoint& pos, bool maintainAspect); + QRect newSizeCentered(const QRect& oldSize, const QRect& bounds, int direction, const QPoint& pos, bool maintainAspect); QRect correctWidthForRatio(const QRect& oldRect, double ratio, int direction); QRect correctHeightForRatio(const QRect& oldRect, double ratio, int direction, int origRight, int origLeft); void moveSnapToBorders(int *xMin, int *yMin, const KstViewObjectPtr &obj, const QRect &r) const; --- branches/work/kst/1.5/kst/src/libkstapp/kstviewellipse.cpp #660201:660202 @@ -185,8 +185,8 @@ signed int KstViewEllipse::directionFor(const QPoint& pos) { signed int direction = KstViewObject::directionFor(pos); - if (!(((direction & (UP|DOWN)) == 0) || ((direction & (LEFT|RIGHT)) == 0))) { - // not an edge + + if (direction != 0) { direction |= CENTEREDRESIZE; } return direction; |