diff --git a/widgets/tooltip.cpp b/widgets/tooltip.cpp index 900f1b3da..51dc208c2 100644 --- a/widgets/tooltip.cpp +++ b/widgets/tooltip.cpp @@ -30,8 +30,9 @@ #include #endif -#include -#include +#include +#include +#include #include #ifdef Q_WS_X11 @@ -53,6 +54,7 @@ class ToolTip::Private , windowToPreview(0) , currentWidget(0) , isShown(false) + , delayedHide(false) , showTimer(0) , hideTimer(0) { } @@ -63,6 +65,7 @@ class ToolTip::Private WId windowToPreview; Plasma::Widget *currentWidget; bool isShown; + bool delayedHide; QTimer *showTimer; QTimer *hideTimer; }; @@ -79,38 +82,34 @@ ToolTip *ToolTip::self() return &privateInstance->self; } -void ToolTip::show(const QPoint &location, Plasma::Widget *widget) +void ToolTip::show(Plasma::Widget *widget) { + d->hideTimer->stop(); + d->delayedHide = false; d->currentWidget = widget; - setData(widget->toolTip()); - - // Make the tooltip use Plasma's colorscheme - QPalette plasmaPalette = QPalette(); - plasmaPalette.setColor(QPalette::Window, Plasma::Theme::self()->backgroundColor()); - plasmaPalette.setColor(QPalette::WindowText, Plasma::Theme::self()->textColor()); - setAutoFillBackground(true); - setPalette(plasmaPalette); - - move(location.x(), location.y()); + d->showTimer->stop(); if (d->isShown) { - // Don't delay if the tooltip is already shown(i.e. moving from one task to another) - // Qt doesn't seem to like visible tooltips moving though, so hide it and then - // immediately show it again - setVisible(false); - // small delay to prevent unecessary showing when the mouse is moving quickly across items // which can be too much for less powerful CPUs to keep up with - d->showTimer->start(150); + d->showTimer->start(200); } else { d->showTimer->start(500); } } +void ToolTip::delayedHide() +{ + d->showTimer->stop(); // stop the timer to show the tooltip + d->delayedHide = true; + d->hideTimer->start(250); +} + void ToolTip::hide() { d->currentWidget = 0; d->showTimer->stop(); //Mouse out, stop the timer to show the tooltip + d->delayedHide = false; setVisible(false); d->hideTimer->start(250); //250 ms delay before we are officially "gone" to allow for the time to move between widgets } @@ -121,13 +120,19 @@ Plasma::Widget *ToolTip::currentWidget() const } //PRIVATE FUNCTIONS -void ToolTip::slotShowToolTip() +void ToolTip::showToolTip() { + if (!d->currentWidget || !d->currentWidget->toolTip()) { + return; + } + QGraphicsView *v = d->currentWidget->view(); if (v && v->mouseGrabber()) { return; } + setData(*d->currentWidget->toolTip()); + if( d->windowToPreview != 0 ) { // show/hide the preview area d->preview->show(); @@ -138,12 +143,18 @@ void ToolTip::slotShowToolTip() d->isShown = true; //ToolTip is visible setVisible(true); + resize(sizeHint()); + move(d->currentWidget->popupPosition(size())); } -void ToolTip::slotResetTimer() +void ToolTip::resetShownState() { - if (!isVisible()) { //One might have moused out and back in again + if (!isVisible() || //One might have moused out and back in again + d->delayedHide) { + d->delayedHide = false; d->isShown = false; + d->currentWidget = 0; + setVisible(false); } } @@ -182,20 +193,11 @@ ToolTip::ToolTip() d->hideTimer = new QTimer(this); d->hideTimer->setSingleShot(true); - connect(d->showTimer, SIGNAL(timeout()), SLOT(slotShowToolTip())); - connect(d->hideTimer, SIGNAL(timeout()), SLOT(slotResetTimer())); -} + connect(d->showTimer, SIGNAL(timeout()), SLOT(showToolTip())); + connect(d->hideTimer, SIGNAL(timeout()), SLOT(resetShownState())); -void ToolTip::setData(const Plasma::ToolTipData &data) -{ - //reset our size - d->label->setText("" + data.mainText + "
" + - data.subText + "
"); - d->imageLabel->setPixmap(data.image); - d->windowToPreview = data.windowToPreview; - d->preview->setWindowId( d->windowToPreview ); - - resize(sizeHint()); + connect(Plasma::Theme::self(), SIGNAL(changed()), this, SLOT(resetPalette())); + resetPalette(); } ToolTip::~ToolTip() @@ -203,6 +205,32 @@ ToolTip::~ToolTip() delete d; } +void ToolTip::setData(const Plasma::ToolTipData &data) +{ + //reset our size + d->label->setText("" + data.mainText + "
" + data.subText + "
"); + d->imageLabel->setPixmap(data.image); + d->windowToPreview = data.windowToPreview; + d->preview->setWindowId( d->windowToPreview ); + + if (isVisible()) { + resize(sizeHint()); + + if (d->currentWidget) { + move(d->currentWidget->popupPosition(size())); + } + } +} + +void ToolTip::resetPalette() +{ + // Make the tooltip use Plasma's colorscheme + QPalette plasmaPalette = QPalette(); + plasmaPalette.setColor(QPalette::Window, Plasma::Theme::self()->backgroundColor()); + plasmaPalette.setColor(QPalette::WindowText, Plasma::Theme::self()->textColor()); + setAutoFillBackground(true); + setPalette(plasmaPalette); +} // A widget which reserves area for window preview and sets hints on the toplevel // tooltip widget that tells KWin to render the preview in this area. This depends diff --git a/widgets/tooltip_p.h b/widgets/tooltip_p.h index 626c43dd1..98b371d04 100644 --- a/widgets/tooltip_p.h +++ b/widgets/tooltip_p.h @@ -44,7 +44,8 @@ public: ~ToolTip(); static ToolTip *self(); - void show(const QPoint &location, Plasma::Widget *widget); + void show(Plasma::Widget *widget); + void delayedHide(); void hide(); Plasma::Widget *currentWidget() const; @@ -57,11 +58,12 @@ protected: void paintEvent(QPaintEvent *); private Q_SLOTS: - void slotResetTimer(); - void slotShowToolTip(); + void resetShownState(); + void showToolTip(); private: void setData(const Plasma::ToolTipData &data); + void resetPalette(); class Private; Private *const d; diff --git a/widgets/widget.cpp b/widgets/widget.cpp index 33d5f3cd5..1027e0eca 100644 --- a/widgets/widget.cpp +++ b/widgets/widget.cpp @@ -55,9 +55,14 @@ class Widget::Private std::numeric_limits::infinity()), opacity(1.0), cachePaintMode(Widget::NoCacheMode), - wasMovable(false) + wasMovable(false), + toolTip(0) { } - ~Private() { } + + ~Private() + { + delete toolTip; + } QSizeF size; QSizeF minimumSize; @@ -77,7 +82,7 @@ class Widget::Private bool wasMovable; bool shouldPaint(QPainter *painter, const QTransform &transform); - ToolTipData toolTip; + ToolTipData *toolTip; }; QGraphicsItem* Widget::graphicsItem() @@ -504,16 +509,28 @@ NOTE: put this back if we end up needing to control when things paint due to, e. } } -ToolTipData Widget::toolTip() const +const ToolTipData* Widget::toolTip() const { return d->toolTip; } void Widget::setToolTip(const ToolTipData &tip) { - d->toolTip = tip; + if (tip.image.isNull() && + tip.subText.isEmpty() && + tip.mainText.isEmpty()) { + delete d->toolTip; + d->toolTip = 0; + } + + if (!d->toolTip) { + d->toolTip = new ToolTipData; + } + + *d->toolTip = tip; + if (ToolTip::self()->currentWidget() == this) { - ToolTip::self()->show(popupPosition(ToolTip::self()->sizeHint()), this); + ToolTip::self()->show(this); } } @@ -620,9 +637,7 @@ bool Widget::sceneEvent(QEvent *event) case QEvent::GraphicsSceneHoverEnter: { // Check that there is a tooltip to show - if (d->toolTip.image.isNull() && - d->toolTip.subText.isEmpty() && - d->toolTip.mainText.isEmpty()) { + if (!d->toolTip) { break; } @@ -631,15 +646,16 @@ bool Widget::sceneEvent(QEvent *event) // initialized, in which case view() will return 0. QGraphicsView *parentView = view(); if (parentView) { - ToolTip *tip = ToolTip::self(); - tip->adjustSize(); - tip->show(popupPosition(tip->size()), this); + ToolTip::self()->show(this); } break; } case QEvent::GraphicsSceneHoverLeave: + ToolTip::self()->delayedHide(); + break; + case QEvent::GraphicsSceneMousePress: case QEvent::GraphicsSceneWheel: ToolTip::self()->hide(); diff --git a/widgets/widget.h b/widgets/widget.h index e137c9ca9..efbd69404 100644 --- a/widgets/widget.h +++ b/widgets/widget.h @@ -276,7 +276,7 @@ public: * The Data from the tooltip * @returns A ToolTip::Data object with current information */ - ToolTipData toolTip() const; + const ToolTipData* toolTip() const; /** * Setter for data shown in tooltip