* register widgets when data is set on them if they aren't already registered

* allocate ToolTip objects only as needed
* invoke tool tip show/hide slots on the associated widget to allow for dynamic tooltip data

svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=833526
This commit is contained in:
Aaron J. Seigo 2008-07-16 23:27:34 +00:00
parent 24d494fd5a
commit c1fb3655cd
4 changed files with 149 additions and 82 deletions

View File

@ -49,11 +49,12 @@ namespace Plasma {
class ToolTipPrivate class ToolTipPrivate
{ {
public: public:
ToolTipPrivate() ToolTipPrivate(QObject *s)
: label(0) : label(0)
, imageLabel(0) , imageLabel(0)
, preview(0) , preview(0)
, windowToPreview(0) , windowToPreview(0)
, source(s)
{ } { }
QLabel *label; QLabel *label;
@ -61,7 +62,7 @@ class ToolTipPrivate
WindowPreview *preview; WindowPreview *preview;
WId windowToPreview; WId windowToPreview;
PanelSvg *background; PanelSvg *background;
QObject *source;
}; };
void ToolTip::showEvent(QShowEvent *e) void ToolTip::showEvent(QShowEvent *e)
@ -70,6 +71,14 @@ void ToolTip::showEvent(QShowEvent *e)
d->preview->setInfo(); d->preview->setInfo();
} }
void ToolTip::hideEvent(QHideEvent *e)
{
QWidget::hideEvent(e);
if (d->source) {
QMetaObject::invokeMethod(d->source, SLOT(toolTipHidden()));
}
}
void ToolTip::mouseReleaseEvent(QMouseEvent* event) void ToolTip::mouseReleaseEvent(QMouseEvent* event)
{ {
if (rect().contains(event->pos())) { if (rect().contains(event->pos())) {
@ -77,10 +86,14 @@ void ToolTip::mouseReleaseEvent(QMouseEvent* event)
} }
} }
ToolTip::ToolTip() ToolTip::ToolTip(QObject *source)
: QWidget(0) : QWidget(0)
, d( new ToolTipPrivate ) , d(new ToolTipPrivate(source))
{ {
if (source) {
connect(source, SIGNAL(destroyed(QObject*)), this, SLOT(sourceDestroyed()));
}
setWindowFlags(Qt::ToolTip); setWindowFlags(Qt::ToolTip);
QGridLayout *l = new QGridLayout; QGridLayout *l = new QGridLayout;
d->preview = new WindowPreview; d->preview = new WindowPreview;
@ -97,7 +110,6 @@ ToolTip::ToolTip()
l->addWidget(d->imageLabel, 1, 0); l->addWidget(d->imageLabel, 1, 0);
l->addWidget(d->label, 1, 1); l->addWidget(d->label, 1, 1);
setLayout(l); setLayout(l);
} }
ToolTip::~ToolTip() ToolTip::~ToolTip()
@ -120,14 +132,18 @@ void ToolTip::setContent(const ToolTipManager::ToolTipContent &data)
void ToolTip::prepareShowing() void ToolTip::prepareShowing()
{ {
if( d->windowToPreview != 0 ) { if (d->source) {
QMetaObject::invokeMethod(d->source, SLOT(toolTipAboutToShow()));
}
if (d->windowToPreview != 0) {
// show/hide the preview area // show/hide the preview area
d->preview->show(); d->preview->show();
} else { } else {
d->preview->hide(); d->preview->hide();
} }
layout()->activate();
layout()->activate();
resize(sizeHint()); resize(sizeHint());
if (isVisible()) { if (isVisible()) {
@ -156,6 +172,11 @@ void ToolTip::paintEvent(QPaintEvent *e)
d->background->paintPanel(&painter, rect()); d->background->paintPanel(&painter, rect());
} }
void ToolTip::sourceDestroyed()
{
d->source = 0;
}
void ToolTip::updateTheme() void ToolTip::updateTheme()
{ {
d->background->setImagePath("widgets/tooltip"); d->background->setImagePath("widgets/tooltip");

View File

@ -38,7 +38,7 @@ class ToolTip : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
ToolTip(); ToolTip(QObject *source);
~ToolTip(); ~ToolTip();
void updateTheme(); void updateTheme();
void setContent(const ToolTipManager::ToolTipContent &data); void setContent(const ToolTipManager::ToolTipContent &data);
@ -46,11 +46,15 @@ public:
protected: protected:
void showEvent(QShowEvent *); void showEvent(QShowEvent *);
void hideEvent(QHideEvent *);
void mouseReleaseEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *);
void resizeEvent(QResizeEvent *); void resizeEvent(QResizeEvent *);
void paintEvent(QPaintEvent *); void paintEvent(QPaintEvent *);
private Q_SLOTS:
void sourceDestroyed();
private: private:
ToolTipPrivate *const d; ToolTipPrivate *const d;
}; };

View File

@ -1,22 +1,23 @@
/************************************************************************** /***************************************************************************
* Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com> * * Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com> *
* Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com> * * Copyright 2008 by Aaron Seigo <aseigo@kde.org> *
* * * Copyright 2008 by Alexis Ménard <darktears31@gmail.com> *
* This program is free software; you can redistribute it and/or modify * * *
* it under the terms of the GNU General Public License as published by * * This program is free software; you can redistribute it and/or modify *
* the Free Software Foundation; either version 2 of the License, or * * it under the terms of the GNU General Public License as published by *
* (at your option) any later version. * * the Free Software Foundation; either version 2 of the License, or *
* * * (at your option) any later version. *
* This program is distributed in the hope that it will be useful, * * *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * This program is distributed in the hope that it will be useful, *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* GNU General Public License for more details. * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* * * GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License * * *
* along with this program; if not, write to the * * You should have received a copy of the GNU General Public License *
* Free Software Foundation, Inc., * * along with this program; if not, write to the *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * Free Software Foundation, Inc., *
***************************************************************************/ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "tooltipmanager.h" #include "tooltipmanager.h"
//Qt //Qt
@ -90,6 +91,16 @@ ToolTipManager *ToolTipManager::self()
return &privateInstance->self; return &privateInstance->self;
} }
ToolTipManager::ToolTipContent::ToolTipContent()
: windowToPreview(0)
{
}
bool ToolTipManager::ToolTipContent::isEmpty() const
{
return mainText.isEmpty() && subText.isEmpty() && image.isNull() && windowToPreview == 0;
}
ToolTipManager::ToolTipManager(QObject* parent) ToolTipManager::ToolTipManager(QObject* parent)
: QObject(parent), : QObject(parent),
d(new ToolTipManagerPrivate) d(new ToolTipManagerPrivate)
@ -113,7 +124,7 @@ ToolTipManager::~ToolTipManager()
void ToolTipManager::showToolTip(QGraphicsWidget *widget) void ToolTipManager::showToolTip(QGraphicsWidget *widget)
{ {
ToolTip * tooltip = d->tooltips.value(widget); ToolTip *tooltip = d->tooltips.value(widget);
if (tooltip) { if (tooltip) {
if (d->currentWidget) { if (d->currentWidget) {
hideToolTip(d->currentWidget); hideToolTip(d->currentWidget);
@ -134,11 +145,10 @@ void ToolTipManager::showToolTip(QGraphicsWidget *widget)
bool ToolTipManager::isWidgetToolTipDisplayed(QGraphicsWidget *widget) bool ToolTipManager::isWidgetToolTipDisplayed(QGraphicsWidget *widget)
{ {
ToolTip * tooltip = d->tooltips.value(widget); ToolTip *tooltip = d->tooltips.value(widget);
if (tooltip) { if (tooltip) {
return tooltip->isVisible(); return tooltip->isVisible();
} } else {
else {
return false; return false;
} }
} }
@ -152,23 +162,23 @@ void ToolTipManager::delayedHideToolTip()
void ToolTipManager::hideToolTip(QGraphicsWidget *widget) void ToolTipManager::hideToolTip(QGraphicsWidget *widget)
{ {
ToolTip * tooltip = d->tooltips.value(widget); ToolTip *tooltip = d->tooltips.value(widget);
if (tooltip) { if (tooltip) {
d->showTimer->stop(); // stop the timer to show the tooltip d->showTimer->stop(); // stop the timer to show the tooltip
d->delayedHide = false; d->delayedHide = false;
d->currentWidget = 0; d->currentWidget = 0;
tooltip->hide(); tooltip->hide();
} }
} }
void ToolTipManager::registerWidget(QGraphicsWidget *widget) void ToolTipManager::registerWidget(QGraphicsWidget *widget)
{ {
if (!d->tooltips.contains(widget)) { if (!d->tooltips.contains(widget)) {
//the tooltip is not registered we add it in our map of tooltips //the tooltip is not registered we add it in our map of tooltips
d->tooltips.insert(widget,new ToolTip()); d->tooltips.insert(widget, 0);
widget->installEventFilter(this); widget->installEventFilter(this);
//connect to object destruction //connect to object destruction
connect(widget,SIGNAL(destroyed(QObject *)),this,SLOT(onWidgetDestroyed(QObject *))); connect(widget, SIGNAL(destroyed(QObject *)),this,SLOT(onWidgetDestroyed(QObject *)));
} }
} }
@ -178,19 +188,30 @@ void ToolTipManager::unregisterWidget(QGraphicsWidget *widget)
return; return;
} }
widget->removeEventFilter(this); widget->removeEventFilter(this);
ToolTip * tooltip = d->tooltips.take(widget); ToolTip *tooltip = d->tooltips.take(widget);
if (tooltip) { if (tooltip) {
delete tooltip; delete tooltip;
} }
} }
void ToolTipManager::setWidgetToolTipContent(QGraphicsWidget *widget,const ToolTipContent &data) void ToolTipManager::setToolTipContent(QGraphicsWidget *widget, const ToolTipContent &data)
{ {
if (!d->tooltips.contains(widget)) { if (!d->tooltips.contains(widget)) {
registerWidget(widget);
}
ToolTip *tooltip = d->tooltips.value(widget);
if (data.isEmpty()) {
delete tooltip;
d->tooltips.insert(widget, 0);
return; return;
} }
ToolTip * tooltip = d->tooltips.value(widget); if (!tooltip) {
d->tooltips.insert(widget, new ToolTip(widget));
}
tooltip->setContent(data); tooltip->setContent(data);
tooltip->updateTheme(); tooltip->updateTheme();
} }
@ -234,10 +255,12 @@ void ToolTipManagerPrivate::onWidgetDestroyed(QObject *object)
while (iterator.hasNext()) { while (iterator.hasNext()) {
iterator.next(); iterator.next();
if (iterator.key() == w) { if (iterator.key() == w) {
ToolTip * tooltip = iterator.value(); ToolTip *tooltip = iterator.value();
tooltips.remove(iterator.key()); tooltips.remove(iterator.key());
tooltip->hide(); if (tooltip) {
delete tooltip; tooltip->hide();
delete tooltip;
}
} }
} }
} }
@ -262,7 +285,7 @@ void ToolTipManagerPrivate::showToolTip()
return; return;
} }
ToolTip * tooltip = tooltips.value(currentWidget); ToolTip *tooltip = tooltips.value(currentWidget);
if (tooltip) { if (tooltip) {
tooltip->prepareShowing(); tooltip->prepareShowing();
tooltip->move(ToolTipManager::popupPosition(currentWidget,tooltip->size())); tooltip->move(ToolTipManager::popupPosition(currentWidget,tooltip->size()));
@ -295,7 +318,10 @@ bool ToolTipManager::eventFilter(QObject *watched, QEvent *event)
// created the widget can receive a hover event before it is fully // created the widget can receive a hover event before it is fully
// initialized, in which case view() will return 0. // initialized, in which case view() will return 0.
const Applet * applet = ToolTipManager::getItemItsApplet(widget); const Applet * applet = ToolTipManager::getItemItsApplet(widget);
if (!applet) break; if (!applet) {
break;
}
QGraphicsView *parentView = applet->view(); QGraphicsView *parentView = applet->view();
if (parentView) { if (parentView) {
showToolTip(widget); showToolTip(widget);

View File

@ -1,22 +1,23 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2007 by Alexis Ménard <darktears31@gmail.com> * * Copyright 2008 by Alexis Ménard <darktears31@gmail.com> *
* Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com> * * Copyright 2008 by Aaron Seigo <aseigo@kde.org> *
* * * Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com> *
* This program is free software; you can redistribute it and/or modify * * *
* it under the terms of the GNU General Public License as published by * * This program is free software; you can redistribute it and/or modify *
* the Free Software Foundation; either version 2 of the License, or * * it under the terms of the GNU General Public License as published by *
* (at your option) any later version. * * the Free Software Foundation; either version 2 of the License, or *
* * * (at your option) any later version. *
* This program is distributed in the hope that it will be useful, * * *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * This program is distributed in the hope that it will be useful, *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* GNU General Public License for more details. * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* * * GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License * * *
* along with this program; if not, write to the * * You should have received a copy of the GNU General Public License *
* Free Software Foundation, Inc., * * along with this program; if not, write to the *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * * Free Software Foundation, Inc., *
***************************************************************************/ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef PLASMA_TOOLTIP_MANAGER_H #ifndef PLASMA_TOOLTIP_MANAGER_H
#define PLASMA_TOOLTIP_MANAGER_H #define PLASMA_TOOLTIP_MANAGER_H
@ -46,8 +47,19 @@ namespace Plasma
/** /**
* @short The class to manage tooltips on QGraphicsWidget in Plasma * @short The class to manage tooltips on QGraphicsWidget in Plasma
* *
* Manage tooltips on QGraphicsWidget. First you have to register your widget by calling registerWidget on the ToolTipManager singleton. After this you have to set the content of the tooltip by calling setWidgetToolTipContent using the struct ToolTipContent. The tooltip manager unregister automatically the widget when it is destroyed but if you want to do it manually call unregisterWidget. If you use plasma's applets show/hide of tooltip is automatically manage but if you use custom QGraphicsWidget, please call showToolTip on you hoverEnterEvent or hideToolTip on you hoverLeaveEvent. * Manage tooltips on QGraphicsWidget. First you have to register your widget by calling
* registerWidget on the ToolTipManager singleton. After this you have to set the content of
* the tooltip by calling setToolTipContent using the struct ToolTipContent. Calling
* setToolTipContent on a widget that is not registered will cause it to be registered.
*
* The tooltip manager unregister automatically the widget when it is destroyed but if
* you want to do it manually call unregisterWidget.
*
* When a tooltip for a widget is about to be shown, the widget's toolTipAboutToShow slot will be
* invoked if it exists. Similarly, when a tooltip is hidden, the widget's toolTipHidden() slow
* will be invoked if it exists. This allows widgets to provide on-demand tooltip data.
*/ */
class PLASMA_EXPORT ToolTipManager : public QObject class PLASMA_EXPORT ToolTipManager : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -58,11 +70,13 @@ namespace Plasma
*/ */
struct ToolTipContent struct ToolTipContent
{ {
ToolTipContent() : windowToPreview( 0 ) {} ToolTipContent();
QString mainText; /**Important information, e.g. the title*/ bool isEmpty() const;
QString subText; /** Elaborates on the Main Text */
QPixmap image; /** Icon to show */ QString mainText; /**Important information, e.g. the title*/
WId windowToPreview; /** Id of a window if you want to show a preview */ QString subText; /** Elaborates on the Main Text */
QPixmap image; /** Icon to show */
WId windowToPreview; /** Id of a window if you want to show a preview */
}; };
/** /**
@ -120,11 +134,13 @@ namespace Plasma
void unregisterWidget(QGraphicsWidget *widget); void unregisterWidget(QGraphicsWidget *widget);
/** /**
* Function to set the content of a tooltip on a desired widget * Function to set the content of a tooltip on a desired widget.
* @param widget the desired widget *
* @param data the content of the tooltip * @param widget the desired widget
*/ * @param data the content of the tooltip. If an empty ToolTipContent is passed in,
void setWidgetToolTipContent(QGraphicsWidget *widget,const ToolTipContent &data); * the tooltip content will be reset.
*/
void setToolTipContent(QGraphicsWidget *widget, const ToolTipContent &data);
/** /**
* Function to know if widget has a tooltip registered in the tooltip manager * Function to know if widget has a tooltip registered in the tooltip manager