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