* set the palette on theme changes only

* don't grab the data until actually shown
* show the right size and position when we are showing the tip
* allow the tooltip to figure out it's size with the help of the widget (it knows when to do this, the widget only knows how)
* don't show the tip on every item's mouse over, respect the small timeout
* only create a ToolTipData struct for those items that actually use it (memory savings as well as makes the check for showing the tip a lot simpler)


svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=771314
This commit is contained in:
Aaron J. Seigo 2008-02-05 18:26:17 +00:00
parent 9560513680
commit 9aa26c5e35
4 changed files with 97 additions and 51 deletions

View File

@ -30,8 +30,9 @@
#include <QX11Info> #include <QX11Info>
#endif #endif
#include <kglobal.h> #include <KDebug>
#include <kwindowsystem.h> #include <KGlobal>
#include <KWindowSystem>
#include <plasma/theme.h> #include <plasma/theme.h>
#ifdef Q_WS_X11 #ifdef Q_WS_X11
@ -53,6 +54,7 @@ class ToolTip::Private
, windowToPreview(0) , windowToPreview(0)
, currentWidget(0) , currentWidget(0)
, isShown(false) , isShown(false)
, delayedHide(false)
, showTimer(0) , showTimer(0)
, hideTimer(0) , hideTimer(0)
{ } { }
@ -63,6 +65,7 @@ class ToolTip::Private
WId windowToPreview; WId windowToPreview;
Plasma::Widget *currentWidget; Plasma::Widget *currentWidget;
bool isShown; bool isShown;
bool delayedHide;
QTimer *showTimer; QTimer *showTimer;
QTimer *hideTimer; QTimer *hideTimer;
}; };
@ -79,38 +82,34 @@ ToolTip *ToolTip::self()
return &privateInstance->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; d->currentWidget = widget;
setData(widget->toolTip()); d->showTimer->stop();
// 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());
if (d->isShown) { 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 // 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 // which can be too much for less powerful CPUs to keep up with
d->showTimer->start(150); d->showTimer->start(200);
} else { } else {
d->showTimer->start(500); 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() void ToolTip::hide()
{ {
d->currentWidget = 0; d->currentWidget = 0;
d->showTimer->stop(); //Mouse out, stop the timer to show the tooltip d->showTimer->stop(); //Mouse out, stop the timer to show the tooltip
d->delayedHide = false;
setVisible(false); setVisible(false);
d->hideTimer->start(250); //250 ms delay before we are officially "gone" to allow for the time to move between widgets 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 //PRIVATE FUNCTIONS
void ToolTip::slotShowToolTip() void ToolTip::showToolTip()
{ {
if (!d->currentWidget || !d->currentWidget->toolTip()) {
return;
}
QGraphicsView *v = d->currentWidget->view(); QGraphicsView *v = d->currentWidget->view();
if (v && v->mouseGrabber()) { if (v && v->mouseGrabber()) {
return; return;
} }
setData(*d->currentWidget->toolTip());
if( d->windowToPreview != 0 ) { if( d->windowToPreview != 0 ) {
// show/hide the preview area // show/hide the preview area
d->preview->show(); d->preview->show();
@ -138,12 +143,18 @@ void ToolTip::slotShowToolTip()
d->isShown = true; //ToolTip is visible d->isShown = true; //ToolTip is visible
setVisible(true); 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->isShown = false;
d->currentWidget = 0;
setVisible(false);
} }
} }
@ -182,20 +193,11 @@ ToolTip::ToolTip()
d->hideTimer = new QTimer(this); d->hideTimer = new QTimer(this);
d->hideTimer->setSingleShot(true); d->hideTimer->setSingleShot(true);
connect(d->showTimer, SIGNAL(timeout()), SLOT(slotShowToolTip())); connect(d->showTimer, SIGNAL(timeout()), SLOT(showToolTip()));
connect(d->hideTimer, SIGNAL(timeout()), SLOT(slotResetTimer())); connect(d->hideTimer, SIGNAL(timeout()), SLOT(resetShownState()));
}
void ToolTip::setData(const Plasma::ToolTipData &data) connect(Plasma::Theme::self(), SIGNAL(changed()), this, SLOT(resetPalette()));
{ resetPalette();
//reset our size
d->label->setText("<qt><b>" + data.mainText + "</b><br>" +
data.subText + "</qt>");
d->imageLabel->setPixmap(data.image);
d->windowToPreview = data.windowToPreview;
d->preview->setWindowId( d->windowToPreview );
resize(sizeHint());
} }
ToolTip::~ToolTip() ToolTip::~ToolTip()
@ -203,6 +205,32 @@ ToolTip::~ToolTip()
delete d; delete d;
} }
void ToolTip::setData(const Plasma::ToolTipData &data)
{
//reset our size
d->label->setText("<qt><b>" + data.mainText + "</b><br>" + data.subText + "</qt>");
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 // 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 // tooltip widget that tells KWin to render the preview in this area. This depends

View File

@ -44,7 +44,8 @@ public:
~ToolTip(); ~ToolTip();
static ToolTip *self(); static ToolTip *self();
void show(const QPoint &location, Plasma::Widget *widget); void show(Plasma::Widget *widget);
void delayedHide();
void hide(); void hide();
Plasma::Widget *currentWidget() const; Plasma::Widget *currentWidget() const;
@ -57,11 +58,12 @@ protected:
void paintEvent(QPaintEvent *); void paintEvent(QPaintEvent *);
private Q_SLOTS: private Q_SLOTS:
void slotResetTimer(); void resetShownState();
void slotShowToolTip(); void showToolTip();
private: private:
void setData(const Plasma::ToolTipData &data); void setData(const Plasma::ToolTipData &data);
void resetPalette();
class Private; class Private;
Private *const d; Private *const d;

View File

@ -55,9 +55,14 @@ class Widget::Private
std::numeric_limits<qreal>::infinity()), std::numeric_limits<qreal>::infinity()),
opacity(1.0), opacity(1.0),
cachePaintMode(Widget::NoCacheMode), cachePaintMode(Widget::NoCacheMode),
wasMovable(false) wasMovable(false),
toolTip(0)
{ } { }
~Private() { }
~Private()
{
delete toolTip;
}
QSizeF size; QSizeF size;
QSizeF minimumSize; QSizeF minimumSize;
@ -77,7 +82,7 @@ class Widget::Private
bool wasMovable; bool wasMovable;
bool shouldPaint(QPainter *painter, const QTransform &transform); bool shouldPaint(QPainter *painter, const QTransform &transform);
ToolTipData toolTip; ToolTipData *toolTip;
}; };
QGraphicsItem* Widget::graphicsItem() 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; return d->toolTip;
} }
void Widget::setToolTip(const ToolTipData &tip) 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) { 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: case QEvent::GraphicsSceneHoverEnter:
{ {
// Check that there is a tooltip to show // Check that there is a tooltip to show
if (d->toolTip.image.isNull() && if (!d->toolTip) {
d->toolTip.subText.isEmpty() &&
d->toolTip.mainText.isEmpty()) {
break; break;
} }
@ -631,15 +646,16 @@ bool Widget::sceneEvent(QEvent *event)
// initialized, in which case view() will return 0. // initialized, in which case view() will return 0.
QGraphicsView *parentView = view(); QGraphicsView *parentView = view();
if (parentView) { if (parentView) {
ToolTip *tip = ToolTip::self(); ToolTip::self()->show(this);
tip->adjustSize();
tip->show(popupPosition(tip->size()), this);
} }
break; break;
} }
case QEvent::GraphicsSceneHoverLeave: case QEvent::GraphicsSceneHoverLeave:
ToolTip::self()->delayedHide();
break;
case QEvent::GraphicsSceneMousePress: case QEvent::GraphicsSceneMousePress:
case QEvent::GraphicsSceneWheel: case QEvent::GraphicsSceneWheel:
ToolTip::self()->hide(); ToolTip::self()->hide();

View File

@ -276,7 +276,7 @@ public:
* The Data from the tooltip * The Data from the tooltip
* @returns A ToolTip::Data object with current information * @returns A ToolTip::Data object with current information
*/ */
ToolTipData toolTip() const; const ToolTipData* toolTip() const;
/** /**
* Setter for data shown in tooltip * Setter for data shown in tooltip