diff --git a/containment.cpp b/containment.cpp index 04e676c49..eee6bdbe5 100644 --- a/containment.cpp +++ b/containment.cpp @@ -1375,24 +1375,56 @@ void ContainmentPrivate::positionToolBox() //The placement assumes that the geometry width/height is no more than the screen if (type == Containment::PanelContainment) { if (q->formFactor() == Vertical) { - toolBox->setOrientation(Qt::Vertical); + toolBox->setCorner(ToolBox::Bottom); toolBox->setPos(q->geometry().width()/2 - toolBox->boundingRect().width()/2, q->geometry().height()); //defaulting to Horizontal right now } else { - toolBox->setOrientation(Qt::Horizontal); if (QApplication::layoutDirection() == Qt::RightToLeft) { toolBox->setPos(q->geometry().left(), q->geometry().height()/2 - toolBox->boundingRect().height()/2); + toolBox->setCorner(ToolBox::Left); } else { toolBox->setPos(q->geometry().width(), q->geometry().height()/2 - toolBox->boundingRect().height()/2); + toolBox->setCorner(ToolBox::Right); } } } else { QDesktopWidget *desktop = QApplication::desktop(); - QRectF r = desktop->availableGeometry(screen); + QRectF avail = desktop->availableGeometry(screen); + QRectF screenGeom = desktop->screenGeometry(screen); + if (q->view() && !q->view()->transform().isScaling()) { - toolBox->setPos(r.topRight()); + + if (QApplication::layoutDirection() == Qt::RightToLeft) { + if (avail.top() > screenGeom.top()) { + toolBox->setPos(avail.topLeft() - QPoint(0, toolBox->size())); + toolBox->setCorner(ToolBox::Left); + } else if (avail.left() > screenGeom.left()) { + toolBox->setPos(avail.topLeft() - QPoint(toolBox->size(), 0)); + toolBox->setCorner(ToolBox::Top); + } else { + toolBox->setPos(avail.topLeft()); + toolBox->setCorner(ToolBox::TopLeft); + } + } else { + if (avail.top() > screenGeom.top()) { + toolBox->setPos(avail.topRight() - QPoint(0, toolBox->size())); + toolBox->setCorner(ToolBox::Right); + } else if (avail.right() < screenGeom.right()) { + toolBox->setPos(QPoint(avail.right() - toolBox->boundingRect().width(), avail.top())); + toolBox->setCorner(ToolBox::Top); + } else { + toolBox->setPos(avail.topRight()); + toolBox->setCorner(ToolBox::TopRight); + } + } } else { - toolBox->setPos(q->mapFromScene(QPointF(q->geometry().topRight()))); + if (QApplication::layoutDirection() == Qt::RightToLeft) { + toolBox->setPos(q->mapFromScene(QPointF(q->geometry().topLeft()))); + toolBox->setCorner(ToolBox::TopLeft); + } else { + toolBox->setPos(q->mapFromScene(QPointF(q->geometry().topRight()))); + toolBox->setCorner(ToolBox::TopRight); + } } } } @@ -1462,10 +1494,12 @@ void ContainmentPrivate::containmentConstraintsEvent(Plasma::Constraints constra if (constraints & Plasma::FormFactorConstraint) { if (toolBox) { if (q->formFactor() == Vertical) { - toolBox->setOrientation(Qt::Vertical); + toolBox->setCorner(ToolBox::Bottom); //defaults to horizontal + } else if (QApplication::layoutDirection() == Qt::RightToLeft) { + toolBox->setCorner(ToolBox::Left); } else { - toolBox->setOrientation(Qt::Horizontal); + toolBox->setCorner(ToolBox::Right); } } diff --git a/private/desktoptoolbox.cpp b/private/desktoptoolbox.cpp index 3af8d79f0..d1286c2d6 100644 --- a/private/desktoptoolbox.cpp +++ b/private/desktoptoolbox.cpp @@ -96,6 +96,7 @@ public: int animHighlightId; qreal animCircleFrame; qreal animHighlightFrame; + QRect shapeRect; bool hovering : 1; }; @@ -119,7 +120,31 @@ DesktopToolBox::~DesktopToolBox() QRectF DesktopToolBox::boundingRect() const { - return QRectF(0, 0, -size()*2, size()*2); + Corner c = corner(); + qreal width; + qreal height; + + if (c == Left || c == Right) { + height = size()*4; + } else { + height = size()*2; + } + + if (c == Bottom || c == BottomRight || c == BottomLeft) { + height = -height; + } + + if (c == Top || c == Bottom) { + width = size()*4; + } else { + width = size()*2; + } + + if (c == Right || c == TopRight || c == BottomRight) { + width = -width; + } + + return QRectF(0, 0, width, height); } void DesktopToolBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) @@ -139,8 +164,47 @@ void DesktopToolBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *op color2.setAlpha(64); QPainterPath p = shape(); - QRadialGradient gradient(boundingRect().topLeft(), size() + d->animCircleFrame); - gradient.setFocalPoint(boundingRect().topLeft()); + + QPoint iconPos; + QPointF gradientCenter; + switch (corner()) { + case TopRight: + iconPos = QPoint((int)boundingRect().left() - iconSize().width() + 2, 2); + gradientCenter = boundingRect().topLeft(); + break; + case Top: + iconPos = QPoint(boundingRect().center().x() - iconSize().width() / 2, 2); + gradientCenter = QPoint(boundingRect().center().x(), boundingRect().y()); + break; + case TopLeft: + iconPos = QPoint(2, 2); + gradientCenter = boundingRect().topLeft(); + break; + case Left: + iconPos = QPoint(2, boundingRect().center().y() - iconSize().height() / 2); + gradientCenter = QPointF(boundingRect().left(), boundingRect().center().y()); + break; + case Right: + iconPos = QPoint((int)boundingRect().left() - iconSize().width() + 2, boundingRect().center().y() - iconSize().height() / 2); + gradientCenter = QPointF(boundingRect().left(), boundingRect().center().y()); + break; + case BottomLeft: + iconPos = QPoint(2, boundingRect().top() - iconSize().height() - 2); + gradientCenter = boundingRect().topLeft(); + break; + case Bottom: + iconPos = QPoint(boundingRect().center().x() - iconSize().width() / 2, boundingRect().top() - iconSize().height() - 2); + gradientCenter = QPointF(boundingRect().center().x(), boundingRect().top()); + break; + case BottomRight: + default: + iconPos = QPoint((int)boundingRect().left() - iconSize().width() - 2, (int)boundingRect().top() - iconSize().height() - 2); + gradientCenter = boundingRect().topLeft(); + break; + } + + QRadialGradient gradient(gradientCenter, size() + d->animCircleFrame); + gradient.setFocalPoint(gradientCenter); gradient.setColorAt(0, color1); gradient.setColorAt(.87, color1); gradient.setColorAt(.97, color2); @@ -155,14 +219,15 @@ void DesktopToolBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *op const qreal progress = d->animHighlightFrame; + if (progress <= 0.9) { - d->icon.paint(painter, QRect(QPoint((int)boundingRect().left() - iconSize().width() + 2, 2), iconSize()), Qt::AlignCenter, QIcon::Disabled, QIcon::Off); + d->icon.paint(painter, QRect(iconPos, iconSize()), Qt::AlignCenter, QIcon::Disabled, QIcon::Off); } if (progress > 0.1) { painter->save(); painter->setOpacity(progress); - d->icon.paint(painter, QRect(QPoint((int)boundingRect().left() - iconSize().width() + 2, 2), iconSize())); + d->icon.paint(painter, QRect(iconPos, iconSize())); painter->restore(); } @@ -173,7 +238,34 @@ QPainterPath DesktopToolBox::shape() const { QPainterPath path; int toolSize = size() + (int)d->animCircleFrame; - path.arcTo(QRectF(boundingRect().left() - toolSize, boundingRect().top() - toolSize, toolSize*2, toolSize*2), 180, 90); + + switch (corner()) { + case TopRight: + path.arcTo(QRectF(boundingRect().left() - toolSize, boundingRect().top() - toolSize, toolSize*2, toolSize*2), 180, 90); + break; + case Top: + path.arcTo(QRectF(boundingRect().center().x() - toolSize, boundingRect().top() - toolSize, toolSize*2, toolSize*2), 180, 180); + break; + case TopLeft: + path.arcTo(QRectF(boundingRect().left() - toolSize, boundingRect().top() - toolSize, toolSize*2, toolSize*2), 270, 90); + break; + case Left: + path.arcTo(QRectF(boundingRect().left() - toolSize, boundingRect().center().y() - toolSize, toolSize*2, toolSize*2), 270, 180); + break; + case Right: + path.arcTo(QRectF(boundingRect().left() - toolSize, boundingRect().center().y() - toolSize, toolSize*2, toolSize*2), 90, 180); + break; + case BottomLeft: + path.arcTo(QRectF(boundingRect().left() - toolSize, boundingRect().top() - toolSize, toolSize*2, toolSize*2), 0, 90); + break; + case Bottom: + path.arcTo(QRectF(boundingRect().center().x() - toolSize, boundingRect().top() - toolSize, toolSize*2, toolSize*2), 0, 180); + break; + case BottomRight: + default: + path.arcTo(QRectF(boundingRect().left() - toolSize, boundingRect().top() - toolSize, toolSize*2, toolSize*2), 90, 90); + break; + } return path; } @@ -210,8 +302,43 @@ void DesktopToolBox::showToolBox() // put tools 5px from icon edge const int iconWidth = 32; - int x = (int)boundingRect().left() - maxwidth - iconWidth - 5; - int y = (int)boundingRect().top() + 5; + int x; + int y; + switch (corner()) { + case TopRight: + x = (int)boundingRect().left() - maxwidth - iconWidth - 5; + y = (int)boundingRect().top() + 5; + break; + case Top: + x = (int)boundingRect().center().x() - iconWidth; + y = (int)boundingRect().top() + iconWidth + 5; + break; + case TopLeft: + x = (int)boundingRect().left() + iconWidth + 5; + y = (int)boundingRect().top() + 5; + break; + case Left: + x = (int)boundingRect().left() + iconWidth + 5; + y = (int)boundingRect().center().y() - iconWidth; + break; + case Right: + x = (int)boundingRect().left() - maxwidth - iconWidth - 5; + y = (int)boundingRect().center().y() - iconWidth; + break; + case BottomLeft: + x = (int)boundingRect().left() + iconWidth + 5; + y = (int)boundingRect().bottom() - 5; + break; + case Bottom: + x = (int)boundingRect().center().x() - iconWidth; + y = (int)boundingRect().bottom() - iconWidth - 5; + break; + case BottomRight: + default: + x = (int)boundingRect().left() - maxwidth - iconWidth - 5; + y = (int)boundingRect().bottom() - iconWidth - 5; + break; + } Plasma::Animator* animdriver = Plasma::Animator::self(); foreach (QGraphicsItem* tool, QGraphicsItem::children()) { if (tool == d->toolBacker) { @@ -221,7 +348,7 @@ void DesktopToolBox::showToolBox() if (!tool->isEnabled()) { if (tool->isVisible()) { const int height = static_cast(tool->boundingRect().height()); - animdriver->moveItem(tool, Plasma::Animator::SlideOutMovement, QPoint(size() * 2, -height)); + animdriver->moveItem(tool, Plasma::Animator::SlideOutMovement, toolPosition(height)); } continue; } @@ -274,8 +401,6 @@ void DesktopToolBox::hideToolBox() return; } - int x = size() * 2; - int y = 0; Plasma::Animator* animdriver = Plasma::Animator::self(); foreach (QGraphicsItem* tool, QGraphicsItem::children()) { if (tool == d->toolBacker) { @@ -283,7 +408,7 @@ void DesktopToolBox::hideToolBox() } const int height = static_cast(tool->boundingRect().height()); - animdriver->moveItem(tool, Plasma::Animator::SlideOutMovement, QPoint(x, y-height)); + animdriver->moveItem(tool, Plasma::Animator::SlideOutMovement, toolPosition(height)); } if (d->animCircleId) { diff --git a/private/paneltoolbox.cpp b/private/paneltoolbox.cpp index 3d35aa5dc..8b38165f7 100644 --- a/private/paneltoolbox.cpp +++ b/private/paneltoolbox.cpp @@ -117,11 +117,11 @@ PanelToolBox::~PanelToolBox() QRectF PanelToolBox::boundingRect() const { - if (orientation() == Qt::Vertical) { + if (corner() == ToolBox::Bottom) { return QRectF(0, 0, size()*2, -size()); - //horizontal - } else if (QApplication::layoutDirection() == Qt::RightToLeft) { + } else if (corner() == ToolBox::Left) { return QRectF(0, 0, size(), size()*2); + //Only Left,Right and Bottom supported, default to Right } else { return QRectF(0, 0, -size(), size()*2); } @@ -135,7 +135,7 @@ void PanelToolBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti const qreal progress = d->animFrame / size(); QPoint gradientCenter; - if (orientation() == Qt::Vertical) { + if (corner() == ToolBox::Bottom) { gradientCenter = QPoint(boundingRect().center().x(), boundingRect().top()); } else { gradientCenter = QPoint(boundingRect().left(), boundingRect().center().y()); @@ -171,10 +171,11 @@ void PanelToolBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti QRect iconRect; - if (orientation() == Qt::Vertical) { + if (corner() == ToolBox::Bottom) { iconRect = QRect(QPoint(gradientCenter.x() - iconSize().width()/2, (int)boundingRect().top() - iconSize().height() - 2), iconSize()); - } else if (QApplication::layoutDirection() == Qt::RightToLeft) { + } else if (corner() == ToolBox::Left) { iconRect = QRect(QPoint(2, gradientCenter.y() - iconSize().height()/2), iconSize()); + //Only Left,Right and Bottom supported, default to Right } else { iconRect = QRect(QPoint((int)boundingRect().left() - iconSize().width() + 1, gradientCenter.y() - iconSize().height()/2), iconSize()); } @@ -197,10 +198,11 @@ QPainterPath PanelToolBox::shape() const QPainterPath path; int toolSize = size();// + (int)d->animFrame; - if (orientation() == Qt::Vertical) { + if (corner() == ToolBox::Bottom) { path.arcTo(QRectF(boundingRect().center().x() - toolSize, boundingRect().top() - toolSize, toolSize*2, toolSize*2), 0, 180); - } else if (QApplication::layoutDirection() == Qt::RightToLeft) { + } else if (corner() == ToolBox::Left) { path.arcTo(QRectF(boundingRect().left() - toolSize, boundingRect().center().y() - toolSize, toolSize*2, toolSize*2), 90, -180); + //Only Left,Right and Bottom supported, default to Right } else { path.arcTo(QRectF(boundingRect().left() - toolSize, boundingRect().center().y() - toolSize, toolSize*2, toolSize*2), 90, 180); } diff --git a/private/toolbox.cpp b/private/toolbox.cpp index e5fcfd500..e0e98df69 100644 --- a/private/toolbox.cpp +++ b/private/toolbox.cpp @@ -43,14 +43,14 @@ public: iconSize(32, 32), hidden(false), showing(false), - orientation(Qt::Horizontal) + corner(ToolBox::TopRight) {} int size; QSize iconSize; bool hidden; bool showing; - Qt::Orientation orientation; + ToolBox::Corner corner; }; ToolBox::ToolBox(QGraphicsItem *parent) @@ -65,6 +65,29 @@ ToolBox::~ToolBox() delete d; } +QPoint ToolBox::toolPosition(int toolHeight) +{ + switch (d->corner) { + case TopRight: + return QPoint( d->size*2, -toolHeight); + case Top: + return QPoint( (int)boundingRect().center().x() - d->iconSize.width(), -toolHeight); + case TopLeft: + return QPoint( -d->size*2, -toolHeight); + case Left: + return QPoint( -d->size*2, (int)boundingRect().center().y() - d->iconSize.height()); + case Right: + return QPoint( d->size*2, (int)boundingRect().center().y() - d->iconSize.height()); + case BottomLeft: + return QPoint( -d->size*2,toolHeight); + case Bottom: + return QPoint( (int)boundingRect().center().x() - d->iconSize.width(), toolHeight); + case BottomRight: + default: + return QPoint( d->size*2, toolHeight); + } +} + void ToolBox::addTool(QAction *action) { if (!action) { @@ -80,7 +103,7 @@ void ToolBox::addTool(QAction *action) tool->hide(); const int height = static_cast(tool->boundingRect().height()); - tool->setPos(QPoint( d->size*2,-height)); + tool->setPos(toolPosition(height)); tool->setZValue(zValue() + 1); //make enabled/disabled tools appear/disappear instantly @@ -138,14 +161,14 @@ void ToolBox::setShowing(const bool show) d->showing = show; } -Qt::Orientation ToolBox::orientation() const +void ToolBox::setCorner(const Corner corner) { - return d->orientation; + d->corner = corner; } -void ToolBox::setOrientation( Qt::Orientation orient ) +ToolBox::Corner ToolBox::corner() const { - d->orientation = orient; + return d->corner; } void ToolBox::mousePressEvent(QGraphicsSceneMouseEvent *event) diff --git a/private/toolbox_p.h b/private/toolbox_p.h index 5576e5743..8bf44f962 100644 --- a/private/toolbox_p.h +++ b/private/toolbox_p.h @@ -40,6 +40,19 @@ class ToolBox : public QObject, public QGraphicsItem Q_OBJECT public: + /** + * These flags represents what borders should be drawn + */ + enum Corner { Top = 0, + TopRight, + TopLeft, + Left, + Right, + Bottom, + BottomRight, + BottomLeft + }; + explicit ToolBox(QGraphicsItem *parent = 0); ~ToolBox(); @@ -58,8 +71,8 @@ public: void setIconSize(const QSize newSize); bool showing() const; void setShowing(const bool show); - Qt::Orientation orientation() const; - void setOrientation(Qt::Orientation orient); + void setCorner(Corner corner); + Corner corner() const; virtual void showToolBox() = 0; virtual void hideToolBox() = 0; @@ -72,6 +85,7 @@ Q_SIGNALS: void toggled(); protected: + QPoint toolPosition(int toolHeight); void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);