fix desktop toolbox dragging once and for all; i should have implemented dragging like this in the first place. also fixes misplacement of the toolbox on the bottom or right edge of the screen. there's some room for optimization here as cornerSize, fullHeight and fullWidth do a -lot- of manip on the background svg that really is only needed once per drag. in practice, it's not so bad and i'd like to keep the diff as small as possible (it's already huge) so i can backport it without feeling tooo guilty ;)

BUG:201672

svn path=/trunk/KDE/kdelibs/; revision=1003346
This commit is contained in:
Aaron J. Seigo 2009-07-28 03:19:33 +00:00
parent 4dd1cc887b
commit 68d9558843
4 changed files with 84 additions and 84 deletions

View File

@ -215,13 +215,13 @@ DesktopToolBox::DesktopToolBox(Containment *parent)
setZValue(10000000);
setIsMovable(true);
assignColors();
updateTheming();
connect(Plasma::Animator::self(), SIGNAL(movementFinished(QGraphicsItem*)),
this, SLOT(toolMoved(QGraphicsItem*)));
connect(this, SIGNAL(toggled()), this, SLOT(toggle()));
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
this, SLOT(assignColors()));
this, SLOT(updateTheming()));
}
DesktopToolBox::~DesktopToolBox()
@ -229,27 +229,47 @@ DesktopToolBox::~DesktopToolBox()
delete d;
}
QRectF DesktopToolBox::boundingRect() const
QSize DesktopToolBox::cornerSize() const
{
int extraSpace = size();
//keep space for the label and a character more
if (!d->containment->activity().isNull()) {
extraSpace = Plasma::Theme::defaultTheme()->fontMetrics().width(d->containment->activity()+"x");
}
//get all borders
d->background->setEnabledBorders(FrameSvg::AllBorders);
qreal left, top, right, bottom;
d->background->getMargins(left, top, right, bottom);
d->adjustBackgroundBorders();
return QRectF(0, 0, size()+left+right+extraSpace, size()+top+bottom+extraSpace);
return QSize(size() + left, size() + bottom);
}
QRectF DesktopToolBox::apparentBoundingRect() const
QSize DesktopToolBox::fullWidth() const
{
d->background->setEnabledBorders(FrameSvg::AllBorders);
qreal left, top, right, bottom;
d->background->getMargins(left, top, right, bottom);
d->adjustBackgroundBorders();
int extraSpace = 0;
if (!d->containment->activity().isNull()) {
extraSpace = Plasma::Theme::defaultTheme()->fontMetrics().width(d->containment->activity()+"x");
}
return QSize(size() + left + right + extraSpace, size() + bottom);
}
QSize DesktopToolBox::fullHeight() const
{
d->background->setEnabledBorders(FrameSvg::AllBorders);
qreal left, top, right, bottom;
d->background->getMargins(left, top, right, bottom);
d->adjustBackgroundBorders();
int extraSpace = 0;
if (!d->containment->activity().isNull()) {
extraSpace = Plasma::Theme::defaultTheme()->fontMetrics().width(d->containment->activity()+"x");
}
return QSize(size() + left, size() + top + bottom + extraSpace);
}
QRectF DesktopToolBox::boundingRect() const
{
int extraSpace = size();
@ -275,37 +295,10 @@ QRectF DesktopToolBox::apparentBoundingRect() const
rect = QRectF(0, 0, size()+extraSpace+left+right, size()+top+bottom);
}
switch (corner()) {
case TopLeft:
//the rect is ok
break;
case TopRight:
rect.moveTopRight(boundingRect().topRight());
break;
case BottomLeft:
rect.moveBottomLeft(boundingRect().bottomLeft());
break;
case BottomRight:
rect.moveBottomRight(boundingRect().bottomRight());
break;
case Left:
rect.moveLeft(boundingRect().left());
break;
case Right:
rect.moveRight(boundingRect().right());
break;
case Top:
//the rect is ok
break;
case Bottom:
default:
rect.moveBottom(boundingRect().bottom());
}
return rect;
}
void DesktopToolBox::assignColors()
void DesktopToolBox::updateTheming()
{
d->bgColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor);
d->fgColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
@ -333,7 +326,7 @@ void DesktopToolBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *op
QPoint iconPos;
QRect backgroundRect;
const QRectF rect = apparentBoundingRect();
const QRectF rect = boundingRect();
const QSize icons = iconSize();
QString cornerElement;
@ -463,7 +456,7 @@ void DesktopToolBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *op
QPainterPath DesktopToolBox::shape() const
{
const QRectF rect = apparentBoundingRect();
const QRectF rect = boundingRect();
const int w = rect.width();
const int h = rect.height();

View File

@ -51,8 +51,11 @@ public:
void showToolBox();
void hideToolBox();
QSize cornerSize() const;
QSize fullWidth() const;
QSize fullHeight() const;
protected:
QRectF apparentBoundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
@ -60,7 +63,7 @@ protected:
protected slots:
void animateHighlight(qreal progress);
void toolMoved(QGraphicsItem*);
void assignColors();
void updateTheming();
void toolTriggered(bool);
/**
* show/hide the toolbox

View File

@ -211,6 +211,21 @@ void ToolBox::mousePressEvent(QGraphicsSceneMouseEvent *event)
d->dragStartRelative = mapToParent(event->pos()).toPoint() - pos().toPoint();
}
QSize ToolBox::cornerSize() const
{
return boundingRect().size().toSize();
}
QSize ToolBox::fullWidth() const
{
return boundingRect().size().toSize();
}
QSize ToolBox::fullHeight() const
{
return boundingRect().size().toSize();
}
void ToolBox::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (!d->movable || (!d->dragging && boundingRect().contains(event->pos())) || isToolbar()) {
@ -221,8 +236,12 @@ void ToolBox::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
d->userMoved = true;
const QPoint newPos = mapToParent(event->pos()).toPoint();
const QPoint curPos = pos().toPoint();
const int h = abs((int)boundingRect().height());
const int w = abs((int)boundingRect().width());
const QSize cSize = cornerSize();
const QSize fHeight = fullHeight();
const QSize fWidth = fullWidth();
const int h = fHeight.height();
const int w = fWidth.width();
const int areaWidth = parentWidget()->size().width();
const int areaHeight = parentWidget()->size().height();
@ -244,18 +263,15 @@ void ToolBox::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
distanceToLeft < distanceToBottom ) {
x = 0;
y = (newPos.y() - d->dragStartRelative.y());
}
else if (distanceToRight < distanceToTop && distanceToRight < distanceToLeft &&
} else if (distanceToRight < distanceToTop && distanceToRight < distanceToLeft &&
distanceToRight < distanceToBottom) {
x = areaWidth - w;
y = (newPos.y() - d->dragStartRelative.y());
}
else if (distanceToTop < distanceToLeft && distanceToTop < distanceToRight &&
} else if (distanceToTop < distanceToLeft && distanceToTop < distanceToRight &&
distanceToTop < distanceToBottom ) {
y = 0;
x = (newPos.x() - d->dragStartRelative.x());
}
else if (distanceToBottom < distanceToLeft && distanceToBottom < distanceToRight &&
} else if (distanceToBottom < distanceToLeft && distanceToBottom < distanceToRight &&
distanceToBottom < distanceToTop) {
y = areaHeight - h;
x = (newPos.x() - d->dragStartRelative.x());
@ -267,29 +283,6 @@ void ToolBox::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
y = areaHeight/2 - d->dragStartRelative.y();
}
//kDebug() << "distances from borders" << (newPos - d->dragStartRelative) << distanceToLeft << distanceToRight << distanceToTop << distanceToBottom << "=>" << x << y;
/*
if (y == 0 || y + h >= areaHeight) {
x = curPos.x() + (newPos.x() - d->dragStart.x());
if (x < 0) {
x = 0;
} else if (x + w > areaWidth) {
x = areaWidth - w;
}
}
//kDebug() << x << w << areaWidth;
if (x == 0 || x + w >= areaWidth) {
//kDebug() << "moving along the y axis" << curPos << newPos << d->dragStart;
y = curPos.y() + (newPos.y() - d->dragStart.y());
if (y < 0) {
y = 0;
} else if (y + h > areaHeight) {
y = areaHeight - h;
}
}
*/
x = qBound(0, x, areaWidth - w);
y = qBound(0, y, areaHeight - h);
@ -297,24 +290,30 @@ void ToolBox::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
if (x == 0) {
if (y == 0) {
newCorner = TopLeft;
} else if (y + h >= areaHeight) {
} else if (areaHeight - cSize.height() < newPos.y()) {
y = areaHeight - cSize.height();
newCorner = BottomLeft;
} else {
newCorner = Left;
}
} else if (y == 0) {
if (x + w >= areaWidth) {
if (areaWidth - cSize.width() < newPos.x()) {
x = areaWidth - cSize.width();
newCorner = TopRight;
} else {
newCorner = Top;
}
} else if (x + w >= areaWidth) {
if (y + h >= areaHeight) {
if (areaHeight - cSize.height() < newPos.y()) {
y = areaHeight - cSize.height();
x = areaWidth - cSize.width();
newCorner = BottomRight;
} else {
x = areaWidth - fHeight.width();
newCorner = Right;
}
} else {
y = areaHeight - fWidth.height();
newCorner = Bottom;
}

View File

@ -90,6 +90,10 @@ public:
void load(const KConfigGroup &containmentGroup = KConfigGroup());
void reposition();
virtual QSize fullWidth() const;
virtual QSize fullHeight() const;
virtual QSize cornerSize() const;
virtual void showToolBox() = 0;
virtual void hideToolBox() = 0;
public Q_SLOTS:
@ -112,6 +116,7 @@ protected Q_SLOTS:
private:
ToolBoxPrivate *d;
};
} // Plasma namespace