* 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>
#endif
#include <kglobal.h>
#include <kwindowsystem.h>
#include <KDebug>
#include <KGlobal>
#include <KWindowSystem>
#include <plasma/theme.h>
#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("<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());
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("<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
// tooltip widget that tells KWin to render the preview in this area. This depends

View File

@ -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;

View File

@ -55,9 +55,14 @@ class Widget::Private
std::numeric_limits<qreal>::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();

View File

@ -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