• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

Plasma

tooltip.cpp

Go to the documentation of this file.
00001 /*
00002  *   Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
00003  *   Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com>
00004  *
00005  *   This program is free software; you can redistribute it and/or modify
00006  *   it under the terms of the GNU Library General Public License as
00007  *   published by the Free Software Foundation; either version 2, or
00008  *   (at your option) any later version.
00009  *
00010  *   This program is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details
00014  *
00015  *   You should have received a copy of the GNU Library General Public
00016  *   License along with this program; if not, write to the
00017  *   Free Software Foundation, Inc.,
00018  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019  */
00020 
00021 #include "tooltip_p.h"
00022 #include "windowpreview_p.h"
00023 
00024 #include <QBitmap>
00025 #include <QGridLayout>
00026 #include <QLabel>
00027 #include <QMouseEvent>
00028 #include <QPainter>
00029 #include <QPalette>
00030 #include <QTextDocument>
00031 #include <QTimeLine>
00032 #ifdef Q_WS_X11
00033 #include <QX11Info>
00034 #include <netwm.h>
00035 #endif
00036 
00037 #include <kdebug.h>
00038 #include <kglobal.h>
00039 #include <kglobalsettings.h>
00040 
00041 #include <plasma/plasma.h>
00042 #include <plasma/theme.h>
00043 #include <plasma/framesvg.h>
00044 
00045 namespace Plasma {
00046 
00047 class TipTextWidget : public QWidget
00048 {
00049 public:
00050     TipTextWidget(QWidget *parent)
00051         : QWidget(parent),
00052           document(new QTextDocument(this))
00053     {
00054         //d->text->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
00055 //        QTextOption op;
00056 //        op.setWrapMode(QTextOption::WordWrap);
00057 //        document->setDefaultTextOption(op);
00058     }
00059 
00060     void setStyleSheet(const QString &css)
00061     {
00062         document->setDefaultStyleSheet(css);
00063     }
00064 
00065     void setContent(const ToolTipContent &data)
00066     {
00067         QString html;
00068         if (!data.mainText().isEmpty()) {
00069             html.append("<b>" + data.mainText() + "</b>");
00070 
00071             if (!data.subText().isEmpty()) {
00072                 html.append("<br>");
00073             }
00074         }
00075         html.append(data.subText());
00076 
00077         document->clear();
00078         data.registerResources(document);
00079         document->setHtml("<p>" + html + "</p>");
00080         document->adjustSize();
00081         update();
00082     }
00083 
00084     QSize minimumSizeHint() const
00085     {
00086         return document->size().toSize();
00087     }
00088 
00089     QSize maximumSizeHint() const
00090     {
00091         return minimumSizeHint();
00092     }
00093 
00094     void paintEvent(QPaintEvent *event)
00095     {
00096         QPainter p(this);
00097         document->drawContents(&p, event->rect());
00098     }
00099 
00100 private:
00101     QTextDocument *document;
00102 };
00103 
00104 class ToolTipPrivate
00105 {
00106     public:
00107         ToolTipPrivate()
00108         : text(0),
00109           imageLabel(0),
00110           preview(0),
00111           source(0),
00112           timeline(0),
00113           direction(Plasma::Up),
00114           autohide(true)
00115     { }
00116 
00117     TipTextWidget *text;
00118     QLabel *imageLabel;
00119     WindowPreview *preview;
00120     FrameSvg *background;
00121     QPointer<QObject> source;
00122     QTimeLine *timeline;
00123     QPoint to;
00124     QPoint from;
00125     Plasma::Direction direction;
00126     bool autohide;
00127 };
00128 
00129 void ToolTip::showEvent(QShowEvent *e)
00130 {
00131     checkSize();
00132     QWidget::showEvent(e);
00133     d->preview->setInfo();
00134 }
00135 
00136 void ToolTip::hideEvent(QHideEvent *e)
00137 {
00138     QWidget::hideEvent(e);
00139     if (d->source) {
00140         QMetaObject::invokeMethod(d->source, "toolTipHidden");
00141     }
00142 }
00143 
00144 void ToolTip::mouseReleaseEvent(QMouseEvent *event)
00145 {
00146     if (rect().contains(event->pos())) {
00147         hide();
00148     }
00149 }
00150 
00151 ToolTip::ToolTip(QWidget *parent)
00152     : QWidget(parent),
00153       d(new ToolTipPrivate())
00154 {
00155     setAttribute(Qt::WA_TranslucentBackground);
00156     setWindowFlags(Qt::ToolTip);
00157     QGridLayout *l = new QGridLayout;
00158     d->preview = new WindowPreview(this);
00159     d->text = new TipTextWidget(this);
00160     d->imageLabel = new QLabel(this);
00161     d->imageLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
00162 
00163     d->background = new FrameSvg(this);
00164     d->background->setImagePath("widgets/tooltip");
00165     d->background->setEnabledBorders(FrameSvg::AllBorders);
00166     updateTheme();
00167     connect(d->background, SIGNAL(repaintNeeded()), this, SLOT(updateTheme()));
00168 
00169     l->addWidget(d->preview, 0, 0, 1, 2);
00170     l->addWidget(d->imageLabel, 1, 0);
00171     l->addWidget(d->text, 1, 1);
00172     setLayout(l);
00173 }
00174 
00175 ToolTip::~ToolTip()
00176 {
00177     delete d;
00178 }
00179 
00180 void ToolTip::checkSize()
00181 {
00182     //FIXME: layout bugs even on qlayouts? oh, please, no.
00183     d->text->setMinimumSize(0, 0);
00184     d->text->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
00185     d->text->setMinimumSize(d->text->minimumSizeHint());
00186     d->text->setMaximumSize(d->text->maximumSizeHint());
00187 
00188     adjustSize();
00189 }
00190 
00191 void ToolTip::adjustPosition(const QSize &previous, const QSize &current)
00192 {
00193     if (previous != current) {
00194         //offsets to stop tooltips from jumping when they resize
00195         int deltaX = 0;
00196         int deltaY = 0;
00197         if (d->direction == Plasma::Up) {
00198         /*
00199         kDebug() << "resizing from" << current << "to" << hint
00200                  << "and moving from" << pos() << "to"
00201                  << x() << y() + (current.height() - hint.height())
00202                  << current.height() - hint.height();
00203                  */
00204             deltaY = previous.height() - current.height();
00205         } else if (d->direction == Plasma::Left) {
00206         /*
00207         kDebug() << "vertical resizing from" << current << "to" << hint
00208                  << "and moving from" << pos() << "to"
00209                  << x() + (current.width() - hint.width()) << y()
00210                  << current.width() - hint.width(); */
00211             deltaX = previous.width() - current.width();
00212         }
00213 
00214         // resize then move if we're getting smaller, vice versa when getting bigger
00215         // this prevents overlap with the item in the smaller case, and a repaint of
00216         // the tipped item when getting bigger
00217 
00218         move(x() + deltaX, y() + deltaY);
00219     }
00220 }
00221 
00222 void ToolTip::setContent(QObject *tipper, const ToolTipContent &data)
00223 {
00224     //reset our size
00225     d->text->setContent(data);
00226     d->imageLabel->setPixmap(data.image());
00227     if (data.windowsToPreview().size() > 1) {
00228         d->preview->setWindowIds(data.windowsToPreview());
00229     } else {
00230         QList<WId>ids;
00231         ids.append(data.windowToPreview());
00232         d->preview->setWindowIds(ids);
00233     }
00234 
00235     d->autohide = data.autohide();
00236     d->source = tipper;
00237 
00238     if (isVisible()) {
00239         d->preview->setInfo();
00240         //kDebug() << "about to check size";
00241         checkSize();
00242     }
00243 }
00244 
00245 void ToolTip::prepareShowing()
00246 {
00247     if (!d->preview->isEmpty()) {
00248         // show/hide the preview area
00249         d->preview->show();
00250     } else {
00251         d->preview->hide();
00252     }
00253 
00254     layout()->activate();
00255     d->preview->setInfo();
00256     //kDebug() << "about to check size";
00257     checkSize();
00258 }
00259 
00260 void ToolTip::moveTo(const QPoint &to)
00261 {
00262     if (!isVisible() ||
00263         !(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
00264         move(to);
00265         return;
00266     }
00267 
00268     d->from = QPoint();
00269     d->to = to;
00270 
00271     if (!d->timeline) {
00272         d->timeline = new QTimeLine(250, this);
00273         d->timeline->setFrameRange(0, 10);
00274         d->timeline->setCurveShape(QTimeLine::EaseInCurve);
00275         connect(d->timeline, SIGNAL(valueChanged(qreal)), this, SLOT(animateMove(qreal)));
00276     }
00277 
00278     d->timeline->stop();
00279     d->timeline->start();
00280 }
00281 
00282 void ToolTip::animateMove(qreal progress)
00283 {
00284     if (d->from.isNull()) {
00285         d->from = pos();
00286     }
00287 
00288     if (qFuzzyCompare(progress, qreal(1.0))) {
00289         move(d->to);
00290         return;
00291     }
00292 
00293     move(d->from.x() + ((d->to.x() - d->from.x()) * progress),
00294          d->from.y() + ((d->to.y() - d->from.y()) * progress));
00295 }
00296 
00297 void ToolTip::resizeEvent(QResizeEvent *e)
00298 {
00299     QWidget::resizeEvent(e);
00300     d->background->resizeFrame(size());
00301     setMask(d->background->mask());
00302     d->preview->setInfo();
00303 
00304     if (isVisible()) {
00305         adjustPosition(e->oldSize(), e->size());
00306     }
00307 }
00308 
00309 void ToolTip::paintEvent(QPaintEvent *e)
00310 {
00311     QPainter painter(this);
00312     painter.setRenderHint(QPainter::Antialiasing);
00313     painter.setClipRect(e->rect());
00314     painter.setCompositionMode(QPainter::CompositionMode_Source);
00315     painter.fillRect(rect(), Qt::transparent);
00316 
00317     d->background->paintFrame(&painter);
00318 }
00319 
00320 bool ToolTip::autohide() const
00321 {
00322     return d->autohide;
00323 }
00324 
00325 void ToolTip::setDirection(Plasma::Direction direction)
00326 {
00327     d->direction = direction;
00328 }
00329 
00330 void ToolTip::updateTheme()
00331 {
00332     const int topHeight = d->background->marginSize(Plasma::TopMargin);
00333     const int leftWidth = d->background->marginSize(Plasma::LeftMargin);
00334     const int rightWidth = d->background->marginSize(Plasma::RightMargin);
00335     const int bottomHeight = d->background->marginSize(Plasma::BottomMargin);
00336     setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight);
00337 
00338     // Make the tooltip use Plasma's colorscheme
00339     QColor textColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
00340     QPalette plasmaPalette = QPalette();
00341     plasmaPalette.setColor(QPalette::Window,
00342                            Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor));
00343     plasmaPalette.setColor(QPalette::WindowText, textColor);
00344     setAutoFillBackground(true);
00345     setPalette(plasmaPalette);
00346     d->text->setStyleSheet(QString("p { color: %1; }").arg(textColor.name()));
00347     update();
00348 }
00349 
00350 } // namespace Plasma
00351 
00352 #include "tooltip_p.moc"

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal