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