KTextEditor

katetextanimation.cpp
1 /* SPDX-License-Identifier: LGPL-2.0-or-later
2 
3  Copyright (C) 2013-2018 Dominik Haumann <[email protected]>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 #include "katetextanimation.h"
22 
23 #include "katerenderer.h"
24 #include "kateviewinternal.h"
25 
26 #include <ktexteditor/document.h>
27 
28 #include <QPainter>
29 #include <QPointF>
30 #include <QRect>
31 #include <QSizeF>
32 #include <QTimeLine>
33 
34 KateTextAnimation::KateTextAnimation(const KTextEditor::Range &range, KTextEditor::Attribute::Ptr attribute, KateViewInternal *view)
35  : QObject(view)
36  , m_range(range)
37  , m_attribute(std::move(attribute))
38  , m_doc(view->view()->doc())
39  , m_view(view)
40  , m_timeLine(new QTimeLine(250, this))
41  , m_value(0.0)
42 {
43  m_text = view->view()->doc()->text(range);
44 
45  connect(m_timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(nextFrame(qreal)));
46  connect(m_timeLine, SIGNAL(finished()), this, SLOT(deleteLater()));
47 
48  m_timeLine->setCurveShape(QTimeLine::SineCurve);
49  m_timeLine->start();
50 
52 }
53 
54 KateTextAnimation::~KateTextAnimation()
55 {
56  // if still running, we need to update the view a last time to avoid artifacts
57  if (m_timeLine->state() == QTimeLine::Running) {
58  m_timeLine->stop();
59  nextFrame(0.0);
60  }
61 }
62 
63 QRectF KateTextAnimation::rectForText()
64 {
65  const QFontMetricsF fm = m_view->view()->renderer()->currentFontMetrics();
66  const int lineHeight = m_view->view()->renderer()->lineHeight();
67  QPoint pixelPos = m_view->cursorToCoordinate(m_range.start(), /*bool realCursor*/ true, /*bool includeBorder*/ false);
68 
69  if (pixelPos.x() == -1 || pixelPos.y() == -1) {
70  return QRectF();
71  } else {
72  QRectF rect(pixelPos.x(), pixelPos.y(), fm.boundingRect(m_view->view()->doc()->text(m_range)).width(), lineHeight);
73  const QPointF center = rect.center();
74  const qreal factor = 1.0 + 0.5 * m_value;
75  rect.setWidth(rect.width() * factor);
76  rect.setHeight(rect.height() * factor);
77  rect.moveCenter(center);
78  return rect;
79  }
80 }
81 
82 void KateTextAnimation::draw(QPainter &painter)
83 {
84  // could happen in corner cases: timeLine emitted finished(), but this object
85  // is not yet deleted. Therefore, draw() might be called in paintEvent().
86  if (m_timeLine->state() == QTimeLine::NotRunning) {
87  return;
88  }
89 
90  // get current rect and fill background
91  QRectF rect = rectForText();
92  painter.fillRect(rect, m_attribute->background());
93 
94  // scale font with animation
95  QFont f = m_view->view()->renderer()->currentFont();
96  f.setBold(m_attribute->fontBold());
97  f.setPointSizeF(f.pointSizeF() * (1.0 + 0.5 * m_value));
98  painter.setFont(f);
99 
100  painter.setPen(m_attribute->foreground().color());
101  // finally draw contents on the view
102  painter.drawText(rect, m_text);
103 }
104 
105 void KateTextAnimation::nextFrame(qreal value)
106 {
107  // cache previous rect for update
108  const QRectF prevRect = rectForText();
109 
110  m_value = value;
111 
112  // next rect is used to draw the text
113  const QRectF nextRect = rectForText();
114 
115  // due to rounding errors, increase the rect 1px to avoid artifacts
116  const QRect updateRect = nextRect.united(prevRect).adjusted(-1, -1, 1, 1).toRect();
117 
118  // request repaint
119  m_view->update(updateRect);
120 }
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-2020 The KDE developers.
Generated on Mon Aug 10 2020 23:01:33 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.