Plasma
tooltip.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00055
00056
00057
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
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 ¤t)
00192 {
00193 if (previous != current) {
00194
00195 int deltaX = 0;
00196 int deltaY = 0;
00197 if (d->direction == Plasma::Up) {
00198
00199
00200
00201
00202
00203
00204 deltaY = previous.height() - current.height();
00205 } else if (d->direction == Plasma::Left) {
00206
00207
00208
00209
00210
00211 deltaX = previous.width() - current.width();
00212 }
00213
00214
00215
00216
00217
00218 move(x() + deltaX, y() + deltaY);
00219 }
00220 }
00221
00222 void ToolTip::setContent(QObject *tipper, const ToolTipContent &data)
00223 {
00224
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
00241 checkSize();
00242 }
00243 }
00244
00245 void ToolTip::prepareShowing()
00246 {
00247 if (!d->preview->isEmpty()) {
00248
00249 d->preview->show();
00250 } else {
00251 d->preview->hide();
00252 }
00253
00254 layout()->activate();
00255 d->preview->setInfo();
00256
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
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 }
00351
00352 #include "tooltip_p.moc"