KTextEditor

katetextanimation.cpp
1 /*
2  SPDX-FileCopyrightText: 2013-2018 Dominik Haumann <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "katetextanimation.h"
8 
9 #include "katerenderer.h"
10 #include "kateviewinternal.h"
11 
12 #include <ktexteditor/document.h>
13 
14 #include <QPainter>
15 #include <QPointF>
16 #include <QRect>
17 #include <QSizeF>
18 #include <QTimeLine>
19 
20 KateTextAnimation::KateTextAnimation(const KTextEditor::Range &range, KTextEditor::Attribute::Ptr attribute, KateViewInternal *view)
21  : QObject(view)
22  , m_range(range)
23  , m_attribute(std::move(attribute))
24  , m_doc(view->view()->doc())
25  , m_view(view)
26  , m_timeLine(new QTimeLine(250, this))
27  , m_value(0.0)
28 {
29  m_text = view->view()->doc()->text(range);
30 
31  connect(m_timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(nextFrame(qreal)));
32  connect(m_timeLine, SIGNAL(finished()), this, SLOT(deleteLater()));
33 
34  m_timeLine->setEasingCurve(QEasingCurve::SineCurve);
35  m_timeLine->start();
36 
38 }
39 
40 KateTextAnimation::~KateTextAnimation()
41 {
42  // if still running, we need to update the view a last time to avoid artifacts
43  if (m_timeLine->state() == QTimeLine::Running) {
44  m_timeLine->stop();
45  nextFrame(0.0);
46  }
47 }
48 
49 QRectF KateTextAnimation::rectForText()
50 {
51  const QFontMetricsF fm = m_view->view()->renderer()->currentFontMetrics();
52  const int lineHeight = m_view->view()->renderer()->lineHeight();
53  QPoint pixelPos = m_view->cursorToCoordinate(m_range.start(), /*bool realCursor*/ true, /*bool includeBorder*/ false);
54 
55  if (pixelPos.x() == -1 || pixelPos.y() == -1) {
56  return QRectF();
57  } else {
58  QRectF rect(pixelPos.x(), pixelPos.y(), fm.boundingRect(m_view->view()->doc()->text(m_range)).width(), lineHeight);
59  const QPointF center = rect.center();
60  const qreal factor = 1.0 + 0.5 * m_value;
61  rect.setWidth(rect.width() * factor);
62  rect.setHeight(rect.height() * factor);
63  rect.moveCenter(center);
64  return rect;
65  }
66 }
67 
68 void KateTextAnimation::draw(QPainter &painter)
69 {
70  // could happen in corner cases: timeLine emitted finished(), but this object
71  // is not yet deleted. Therefore, draw() might be called in paintEvent().
72  if (m_timeLine->state() == QTimeLine::NotRunning) {
73  return;
74  }
75 
76  // get current rect and fill background
77  QRectF rect = rectForText();
78  painter.fillRect(rect, m_attribute->background());
79 
80  // scale font with animation
81  QFont f = m_view->view()->renderer()->currentFont();
82  f.setBold(m_attribute->fontBold());
83  f.setPointSizeF(f.pointSizeF() * (1.0 + 0.5 * m_value));
84  painter.setFont(f);
85 
86  painter.setPen(m_attribute->foreground().color());
87  // finally draw contents on the view
88  painter.drawText(rect, m_text);
89 }
90 
91 void KateTextAnimation::nextFrame(qreal value)
92 {
93  // cache previous rect for update
94  const QRectF prevRect = rectForText();
95 
96  m_value = value;
97 
98  // next rect is used to draw the text
99  const QRectF nextRect = rectForText();
100 
101  // due to rounding errors, increase the rect 1px to avoid artifacts
102  const QRect updateRect = nextRect.united(prevRect).adjusted(-1, -1, 1, 1).toRect();
103 
104  // request repaint
105  m_view->update(updateRect);
106 }
QTextStream & center(QTextStream &s)
QRect toRect() const const
void fillRect(const QRectF &rectangle, const QBrush &brush)
qreal pointSizeF() const const
int x() const const
int y() const const
void setBold(bool enable)
void setFont(const QFont &font)
void setPen(const QColor &color)
QRectF boundingRect(const QString &text) const const
QTextStream & center(QTextStream &stream)
void drawText(const QPointF &position, const QString &text)
void deleteLater()
QRectF united(const QRectF &rectangle) const const
An object representing a section of text, from one Cursor to another.
void setPointSizeF(qreal pointSize)
void stop()
QRectF adjusted(qreal dx1, qreal dy1, qreal dx2, qreal dy2) const const
KIOCORE_EXPORT CopyJob * move(const QUrl &src, const QUrl &dest, JobFlags flags=DefaultFlags)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void destroyed(QObject *obj)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Jan 23 2021 03:31:34 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.