• Skip to content
  • Skip to link menu
KDE 4.2 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         document->clear();
00068         data.registerResources(document);
00069         document->setHtml("<p><b>" + data.mainText() + "</b><br>" + data.subText() + "</p>");
00070         document->adjustSize();
00071         update();
00072     }
00073 
00074     QSize minimumSizeHint() const
00075     {
00076         return document->size().toSize();
00077     }
00078 
00079     QSize maximumSizeHint() const
00080     {
00081         return minimumSizeHint();
00082     }
00083 
00084     void paintEvent(QPaintEvent *event)
00085     {
00086         QPainter p(this);
00087         document->drawContents(&p, event->rect());
00088     }
00089 
00090 private:
00091     QTextDocument *document;
00092 };
00093 
00094 class ToolTipPrivate
00095 {
00096     public:
00097         ToolTipPrivate()
00098         : text(0),
00099           imageLabel(0),
00100           preview(0),
00101           source(0),
00102           timeline(0),
00103           direction(Plasma::Up),
00104           autohide(true)
00105     { }
00106 
00107     TipTextWidget *text;
00108     QLabel *imageLabel;
00109     WindowPreview *preview;
00110     FrameSvg *background;
00111     QPointer<QObject> source;
00112     QTimeLine *timeline;
00113     QPoint to;
00114     QPoint from;
00115     Plasma::Direction direction;
00116     bool autohide;
00117 };
00118 
00119 void ToolTip::showEvent(QShowEvent *e)
00120 {
00121     checkSize();
00122     QWidget::showEvent(e);
00123     d->preview->setInfo();
00124 }
00125 
00126 void ToolTip::hideEvent(QHideEvent *e)
00127 {
00128     QWidget::hideEvent(e);
00129     if (d->source) {
00130         QMetaObject::invokeMethod(d->source, "toolTipHidden");
00131     }
00132 }
00133 
00134 void ToolTip::mouseReleaseEvent(QMouseEvent *event)
00135 {
00136     if (rect().contains(event->pos())) {
00137         hide();
00138     }
00139 }
00140 
00141 ToolTip::ToolTip(QWidget *parent)
00142     : QWidget(parent),
00143       d(new ToolTipPrivate())
00144 {
00145     setWindowFlags(Qt::ToolTip);
00146     QGridLayout *l = new QGridLayout;
00147     d->preview = new WindowPreview(this);
00148     d->text = new TipTextWidget(this);
00149     d->imageLabel = new QLabel(this);
00150     d->imageLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
00151 
00152     d->background = new FrameSvg(this);
00153     d->background->setImagePath("widgets/tooltip");
00154     d->background->setEnabledBorders(FrameSvg::AllBorders);
00155     updateTheme();
00156     connect(d->background, SIGNAL(repaintNeeded()), this, SLOT(updateTheme()));
00157 
00158     l->addWidget(d->preview, 0, 0, 1, 2);
00159     l->addWidget(d->imageLabel, 1, 0);
00160     l->addWidget(d->text, 1, 1);
00161     setLayout(l);
00162 }
00163 
00164 ToolTip::~ToolTip()
00165 {
00166     delete d;
00167 }
00168 
00169 void ToolTip::checkSize()
00170 {
00171     //FIXME: layout bugs even on qlayouts? oh, please, no.
00172     d->text->setMinimumSize(0, 0);
00173     d->text->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
00174     d->text->setMinimumSize(d->text->minimumSizeHint());
00175     d->text->setMaximumSize(d->text->maximumSizeHint());
00176 
00177     QSize previous = size();
00178     adjustSize();
00179     QSize current = size();
00180 
00181     if (previous != current) {
00182         /*
00183 #ifdef Q_WS_X11
00184         NETRootInfo i(QX11Info::display(), 0);
00185         int flags = NET::BottomLeft;
00186         i.moveResizeWindowRequest(winId(), flags,
00187                                   x(), y() + (current.height() - hint.height()),
00188                                   hint.width(), hint.height());
00189 #else
00190         move(x(), y() + (current.height() - hint.height()));
00191         resize(hint);
00192 #endif
00193     */
00194 
00195         //offsets to stop tooltips from jumping when they resize
00196         int deltaX = 0;
00197         int deltaY = 0;
00198         if (d->direction == Plasma::Up) {
00199         /*
00200         kDebug() << "resizing from" << current << "to" << hint
00201                  << "and moving from" << pos() << "to"
00202                  << x() << y() + (current.height() - hint.height())
00203                  << current.height() - hint.height();
00204                  */
00205             deltaY = previous.height() - current.height();
00206         } else if (d->direction == Plasma::Left) {
00207         /*
00208         kDebug() << "vertical resizing from" << current << "to" << hint
00209                  << "and moving from" << pos() << "to"
00210                  << x() + (current.width() - hint.width()) << y()
00211                  << current.width() - hint.width(); */
00212             deltaX = previous.width() - current.width();
00213         }
00214 
00215         // resize then move if we're getting smaller, vice versa when getting bigger
00216         // this prevents overlap with the item in the smaller case, and a repaint of
00217         // the tipped item when getting bigger
00218 
00219         move(x() + deltaX, y() + deltaY);
00220     }
00221 }
00222 
00223 void ToolTip::setContent(QObject *tipper, const ToolTipContent &data)
00224 {
00225     //reset our size
00226     d->text->setContent(data);
00227     d->imageLabel->setPixmap(data.image());
00228     d->preview->setWindowId(data.windowToPreview());
00229     d->autohide = data.autohide();
00230     d->source = tipper;
00231 
00232     if (isVisible()) {
00233         d->preview->setInfo();
00234         //kDebug() << "about to check size";
00235         checkSize();
00236     }
00237 }
00238 
00239 void ToolTip::prepareShowing()
00240 {
00241     if (d->preview->windowId() != 0) {
00242         // show/hide the preview area
00243         d->preview->show();
00244     } else {
00245         d->preview->hide();
00246     }
00247 
00248     layout()->activate();
00249     d->preview->setInfo();
00250     //kDebug() << "about to check size";
00251     checkSize();
00252 }
00253 
00254 void ToolTip::moveTo(const QPoint &to)
00255 {
00256     if (!isVisible() ||
00257         !(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
00258         move(to);
00259         return;
00260     }
00261 
00262     d->from = QPoint();
00263     d->to = to;
00264 
00265     if (!d->timeline) {
00266         d->timeline = new QTimeLine(250, this);
00267         d->timeline->setFrameRange(0, 10);
00268         d->timeline->setCurveShape(QTimeLine::EaseInCurve);
00269         connect(d->timeline, SIGNAL(valueChanged(qreal)), this, SLOT(animateMove(qreal)));
00270     }
00271 
00272     d->timeline->stop();
00273     d->timeline->start();
00274 }
00275 
00276 void ToolTip::animateMove(qreal progress)
00277 {
00278     if (d->from.isNull()) {
00279         d->from = pos();
00280     }
00281 
00282     if (qFuzzyCompare(progress, qreal(1.0))) {
00283         move(d->to);
00284         return;
00285     }
00286 
00287     move(d->from.x() + ((d->to.x() - d->from.x()) * progress),
00288          d->from.y() + ((d->to.y() - d->from.y()) * progress));
00289 }
00290 
00291 void ToolTip::resizeEvent(QResizeEvent *e)
00292 {
00293     QWidget::resizeEvent(e);
00294     d->background->resizeFrame(size());
00295     setMask(d->background->mask());
00296     d->preview->setInfo();
00297 }
00298 
00299 void ToolTip::paintEvent(QPaintEvent *e)
00300 {
00301     QPainter painter(this);
00302     painter.setRenderHint(QPainter::Antialiasing);
00303     painter.setClipRect(e->rect());
00304     painter.setCompositionMode(QPainter::CompositionMode_Source);
00305     painter.fillRect(rect(), Qt::transparent);
00306 
00307     d->background->paintFrame(&painter);
00308 }
00309 
00310 bool ToolTip::autohide() const
00311 {
00312     return d->autohide;
00313 }
00314 
00315 void ToolTip::setDirection(Plasma::Direction direction)
00316 {
00317     d->direction = direction;
00318 }
00319 
00320 void ToolTip::updateTheme()
00321 {
00322     const int topHeight = d->background->marginSize(Plasma::TopMargin);
00323     const int leftWidth = d->background->marginSize(Plasma::LeftMargin);
00324     const int rightWidth = d->background->marginSize(Plasma::RightMargin);
00325     const int bottomHeight = d->background->marginSize(Plasma::BottomMargin);
00326     setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight);
00327 
00328     // Make the tooltip use Plasma's colorscheme
00329     QColor textColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
00330     QPalette plasmaPalette = QPalette();
00331     plasmaPalette.setColor(QPalette::Window,
00332                            Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor));
00333     plasmaPalette.setColor(QPalette::WindowText, textColor);
00334     setAutoFillBackground(true);
00335     setPalette(plasmaPalette);
00336     d->text->setStyleSheet(QString("p { color: %1; }").arg(textColor.name()));
00337     update();
00338 }
00339 
00340 } // namespace Plasma
00341 
00342 #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
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
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