00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "paneltoolbox_p.h"
00022
00023 #include <QGraphicsSceneHoverEvent>
00024 #include <QPainter>
00025 #include <QRadialGradient>
00026 #include <QApplication>
00027
00028 #include <plasma/theme.h>
00029 #include <KColorScheme>
00030
00031 #include <KDebug>
00032
00033 #include <plasma/applet.h>
00034
00035 namespace Plasma
00036 {
00037
00038 class EmptyGraphicsItem : public QGraphicsItem
00039 {
00040 public:
00041 EmptyGraphicsItem(QGraphicsItem *parent)
00042 : QGraphicsItem(parent)
00043 {
00044 setAcceptsHoverEvents(true);
00045 }
00046
00047 QRectF boundingRect() const
00048 {
00049 return QRectF(QPointF(0, 0), m_rect.size());
00050 }
00051
00052 QRectF rect() const
00053 {
00054 return m_rect;
00055 }
00056
00057 void setRect(const QRectF &rect)
00058 {
00059
00060 prepareGeometryChange();
00061 m_rect = rect;
00062 setPos(rect.topLeft());
00063 }
00064
00065 void paint(QPainter * p, const QStyleOptionGraphicsItem*, QWidget*)
00066 {
00067 Q_UNUSED(p)
00068
00069
00070 }
00071
00072 private:
00073 QRectF m_rect;
00074 };
00075
00076
00077 static const int ToolName = 7001;
00078
00079 class PanelToolBoxPrivate
00080 {
00081 public:
00082 PanelToolBoxPrivate()
00083 : icon("plasma"),
00084 toolBacker(0),
00085 animId(0),
00086 animFrame(0),
00087 toggled(false)
00088 {}
00089
00090 KIcon icon;
00091 EmptyGraphicsItem *toolBacker;
00092 QTime stopwatch;
00093 int animId;
00094 qreal animFrame;
00095 bool toggled;
00096 };
00097
00098 PanelToolBox::PanelToolBox(QGraphicsItem *parent)
00099 : ToolBox(parent),
00100 d(new PanelToolBoxPrivate)
00101 {
00102 connect(Plasma::Animator::self(), SIGNAL(movementFinished(QGraphicsItem*)), this, SLOT(toolMoved(QGraphicsItem*)));
00103 connect(this, SIGNAL(toggled()), this, SLOT(toggle()));
00104
00105 setZValue(10000000);
00106 setFlag(ItemClipsToShape, true);
00107 setFlag(ItemClipsChildrenToShape, false);
00108
00109
00110 setFlag(ItemIgnoresTransformations, false);
00111 }
00112
00113 PanelToolBox::~PanelToolBox()
00114 {
00115 delete d;
00116 }
00117
00118 QRectF PanelToolBox::boundingRect() const
00119 {
00120 if (orientation() == Qt::Vertical) {
00121 return QRectF(0, 0, size()*2, -size());
00122
00123 } else if (QApplication::layoutDirection() == Qt::RightToLeft) {
00124 return QRectF(0, 0, size(), size()*2);
00125 } else {
00126 return QRectF(0, 0, -size(), size()*2);
00127 }
00128 }
00129
00130 void PanelToolBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
00131 {
00132 Q_UNUSED(option)
00133 Q_UNUSED(widget)
00134
00135 const qreal progress = d->animFrame / size();
00136
00137 QPoint gradientCenter;
00138 if (orientation() == Qt::Vertical) {
00139 gradientCenter = QPoint(boundingRect().center().x(), boundingRect().top());
00140 } else {
00141 gradientCenter = QPoint(boundingRect().left(), boundingRect().center().y());
00142 }
00143
00144 {
00145 painter->translate(boundingRect().topLeft());
00146
00147 KColorScheme colors(QPalette::Active, KColorScheme::Window,
00148 Plasma::Theme::defaultTheme()->colorScheme());
00149 QColor color1 = colors.background().color();
00150 color1.setAlpha(64.0);
00151
00152 QColor color2 = colors.foreground().color();
00153 color2.setAlpha(64.0);
00154
00155 QRadialGradient gradient(gradientCenter, size() - 2);
00156 gradient.setFocalPoint(gradientCenter);
00157 gradient.setColorAt(0, color1);
00158 gradient.setColorAt(.85, color1);
00159 gradient.setColorAt(.95, color2);
00160 color2.setAlpha(0);
00161 gradient.setColorAt(1, color2);
00162
00163 painter->save();
00164 painter->setPen(Qt::NoPen);
00165 painter->setRenderHint(QPainter::Antialiasing, true);
00166 painter->setBrush(gradient);
00167 QPainterPath p = shape();
00168 painter->drawPath(p);
00169 painter->restore();
00170 }
00171
00172 QRect iconRect;
00173
00174 if (orientation() == Qt::Vertical) {
00175 iconRect = QRect(QPoint(gradientCenter.x() - iconSize().width()/2, (int)boundingRect().top() - iconSize().height() - 2), iconSize());
00176 } else if (QApplication::layoutDirection() == Qt::RightToLeft) {
00177 iconRect = QRect(QPoint(2, gradientCenter.y() - iconSize().height()/2), iconSize());
00178 } else {
00179 iconRect = QRect(QPoint((int)boundingRect().left() - iconSize().width() + 1, gradientCenter.y() - iconSize().height()/2), iconSize());
00180 }
00181
00182 if (progress <= 0.9) {
00183 d->icon.paint(painter, iconRect, Qt::AlignCenter, QIcon::Disabled, QIcon::Off);
00184 }
00185
00186 if (progress > 0.1) {
00187 painter->save();
00188 painter->setOpacity(progress);
00189 d->icon.paint(painter, iconRect);
00190 painter->restore();
00191 }
00192
00193 }
00194
00195 QPainterPath PanelToolBox::shape() const
00196 {
00197 QPainterPath path;
00198 int toolSize = size();
00199
00200 if (orientation() == Qt::Vertical) {
00201 path.arcTo(QRectF(boundingRect().center().x() - toolSize, boundingRect().top() - toolSize, toolSize*2, toolSize*2), 0, 180);
00202 } else if (QApplication::layoutDirection() == Qt::RightToLeft) {
00203 path.arcTo(QRectF(boundingRect().left() - toolSize, boundingRect().center().y() - toolSize, toolSize*2, toolSize*2), 90, -180);
00204 } else {
00205 path.arcTo(QRectF(boundingRect().left() - toolSize, boundingRect().center().y() - toolSize, toolSize*2, toolSize*2), 90, 180);
00206 }
00207
00208 return path;
00209 }
00210
00211 void PanelToolBox::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
00212 {
00213 if (showing() || d->stopwatch.elapsed() < 100) {
00214 QGraphicsItem::hoverEnterEvent(event);
00215 return;
00216 }
00217
00218 showToolBox();
00219 QGraphicsItem::hoverEnterEvent(event);
00220 }
00221
00222 void PanelToolBox::showToolBox()
00223 {
00224 if (showing()) {
00225 return;
00226 }
00227
00228 int maxwidth = 0;
00229 foreach (QGraphicsItem* tool, QGraphicsItem::children()) {
00230 if (!tool->isEnabled()) {
00231 continue;
00232 }
00233 maxwidth = qMax(static_cast<int>(tool->boundingRect().width()), maxwidth);
00234 }
00235
00236
00237 const int iconWidth = 32;
00238 int x = size()*2 - maxwidth - iconWidth - 5;
00239 int y = 5;
00240 Plasma::Animator* animdriver = Plasma::Animator::self();
00241 foreach (QGraphicsItem* tool, QGraphicsItem::children()) {
00242 if (tool == d->toolBacker) {
00243 continue;
00244 }
00245
00246 if (!tool->isEnabled()) {
00247 if (tool->isVisible()) {
00248 const int height = static_cast<int>(tool->boundingRect().height());
00249 animdriver->moveItem(tool, Plasma::Animator::SlideOutMovement, QPoint(size() * 2, -height));
00250 }
00251 continue;
00252 }
00253
00254
00255 tool->show();
00256 animdriver->moveItem(tool, Plasma::Animator::SlideInMovement, QPoint(x, y));
00257
00258 y += static_cast<int>(tool->boundingRect().height()) + 5;
00259 }
00260
00261 if (!d->toolBacker) {
00262 d->toolBacker = new EmptyGraphicsItem(this);
00263 }
00264 d->toolBacker->setRect(QRectF(QPointF(x, 0), QSizeF(maxwidth, y - 10)));
00265 d->toolBacker->show();
00266
00267 if (d->animId) {
00268 animdriver->stopCustomAnimation(d->animId);
00269 }
00270
00271 setShowing(true);
00272
00273
00274 d->animId = animdriver->customAnimation(10, 240, Plasma::Animator::EaseInCurve, this, "animate");
00275 d->stopwatch.restart();
00276 }
00277
00278 void PanelToolBox::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
00279 {
00280
00281 if ((d->toolBacker && d->toolBacker->rect().contains(event->scenePos().toPoint())) ||
00282 d->stopwatch.elapsed() < 100 || d->toggled) {
00283 QGraphicsItem::hoverLeaveEvent(event);
00284 return;
00285 }
00286
00287 hideToolBox();
00288 QGraphicsItem::hoverLeaveEvent(event);
00289 }
00290
00291 void PanelToolBox::hideToolBox()
00292 {
00293 if (!showing()) {
00294 return;
00295 }
00296
00297 d->toggled = false;
00298 int x = size() * 2;
00299 int y = 0;
00300 Plasma::Animator* animdriver = Plasma::Animator::self();
00301 foreach (QGraphicsItem* tool, QGraphicsItem::children()) {
00302 if (tool == d->toolBacker) {
00303 continue;
00304 }
00305
00306 const int height = static_cast<int>(tool->boundingRect().height());
00307 animdriver->moveItem(tool, Plasma::Animator::SlideOutMovement, QPoint(x, y-height));
00308 }
00309
00310 if (d->animId) {
00311 animdriver->stopCustomAnimation(d->animId);
00312 }
00313
00314 setShowing(false);
00315 d->animId = animdriver->customAnimation(10, 240, Plasma::Animator::EaseOutCurve, this, "animate");
00316
00317 if (d->toolBacker) {
00318 d->toolBacker->hide();
00319 }
00320
00321 d->stopwatch.restart();
00322 }
00323
00324 void PanelToolBox::animate(qreal progress)
00325 {
00326 if (showing()) {
00327 d->animFrame = size() * progress;
00328 } else {
00329 d->animFrame = size() * (1.0 - progress);
00330 }
00331
00332
00333
00334 if (progress >= 1) {
00335 d->animId = 0;
00336 }
00337
00338 update();
00339 }
00340
00341 void PanelToolBox::toolMoved(QGraphicsItem *item)
00342 {
00343
00344 if (!showing() &&
00345 QGraphicsItem::children().indexOf(static_cast<Plasma::Applet*>(item)) != -1) {
00346 item->hide();
00347 }
00348 }
00349
00350 void PanelToolBox::toggle()
00351 {
00352 d->toggled = !d->toggled;
00353 if (showing() && !d->toggled) {
00354 hideToolBox();
00355 }
00356 }
00357
00358 }
00359
00360 #include "paneltoolbox_p.moc"
00361