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 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
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
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 int deltaX = 0;
00197 int deltaY = 0;
00198 if (d->direction == Plasma::Up) {
00199
00200
00201
00202
00203
00204
00205 deltaY = previous.height() - current.height();
00206 } else if (d->direction == Plasma::Left) {
00207
00208
00209
00210
00211
00212 deltaX = previous.width() - current.width();
00213 }
00214
00215
00216
00217
00218
00219 move(x() + deltaX, y() + deltaY);
00220 }
00221 }
00222
00223 void ToolTip::setContent(QObject *tipper, const ToolTipContent &data)
00224 {
00225
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
00235 checkSize();
00236 }
00237 }
00238
00239 void ToolTip::prepareShowing()
00240 {
00241 if (d->preview->windowId() != 0) {
00242
00243 d->preview->show();
00244 } else {
00245 d->preview->hide();
00246 }
00247
00248 layout()->activate();
00249 d->preview->setInfo();
00250
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
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 }
00341
00342 #include "tooltip_p.moc"