Warning, /multimedia/kdenlive/src/assets/view/widgets/curves/abstractcurvewidget.ipp is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2016 Nicolas Carion 0003 * SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 0006 #include <QKeyEvent> 0007 #include <QMouseEvent> 0008 #include <QResizeEvent> 0009 #include <QFontInfo> 0010 0011 template <typename Curve_t> 0012 AbstractCurveWidget<Curve_t>::AbstractCurveWidget(QWidget *parent) 0013 : __dummy_AbstractCurveWidget(parent) 0014 , m_pixmapCache(nullptr) 0015 0016 { 0017 setMouseTracking(true); 0018 setAutoFillBackground(false); 0019 setAttribute(Qt::WA_OpaquePaintEvent); 0020 setMinimumSize(150, QFontInfo(font()).pixelSize() * 12); 0021 QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); 0022 sp.setHeightForWidth(true); // force widget to have a height dependent on width; 0023 setSizePolicy(sp); 0024 setFocusPolicy(Qt::StrongFocus); 0025 } 0026 0027 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::paintBackground(QPainter *p) 0028 { 0029 /* 0030 * Zoom 0031 */ 0032 m_wWidth = width() - 1; 0033 m_wHeight = height() - 1; 0034 int offsetX = int(1 / 8. * m_zoomLevel * m_wWidth); 0035 int offsetY = int(1 / 8. * m_zoomLevel * m_wHeight); 0036 m_wWidth -= 2 * offsetX; 0037 m_wHeight -= 2 * offsetY; 0038 0039 p->translate(offsetX, offsetY); 0040 0041 /* 0042 * Background 0043 */ 0044 p->fillRect(rect().translated(-offsetX, -offsetY), palette().window()); 0045 if (!m_pixmap.isNull()) { 0046 if (m_pixmapIsDirty || !m_pixmapCache) { 0047 m_pixmapCache = std::make_shared<QPixmap>(m_wWidth + 1, m_wHeight + 1); 0048 QPainter cachePainter(m_pixmapCache.get()); 0049 0050 cachePainter.scale(1.0 * (m_wWidth + 1) / m_pixmap.width(), 1.0 * (m_wHeight + 1) / m_pixmap.height()); 0051 cachePainter.drawPixmap(0, 0, m_pixmap); 0052 m_pixmapIsDirty = false; 0053 } 0054 p->drawPixmap(0, 0, *m_pixmapCache); 0055 } 0056 0057 // select color of the grid, depending on whether we have a palette or not 0058 if (!m_pixmap.isNull()) { 0059 p->setPen(QPen(palette().mid().color(), 1, Qt::SolidLine)); 0060 } else { 0061 int h, s, l, a; 0062 auto bg = palette().color(QPalette::Window); 0063 bg.getHsl(&h, &s, &l, &a); 0064 l = (l > 128) ? l - 30 : l + 30; 0065 bg.setHsl(h, s, l, a); 0066 p->setPen(QPen(bg, 1, Qt::SolidLine)); 0067 } 0068 0069 /* 0070 * Borders 0071 */ 0072 p->drawRect(0, 0, m_wWidth, m_wHeight); 0073 0074 /* 0075 * Grid 0076 */ 0077 if (m_gridLines != 0) { 0078 double stepH = m_wWidth / double(m_gridLines + 1); 0079 double stepV = m_wHeight / double(m_gridLines + 1); 0080 for (int i = 1; i <= m_gridLines; ++i) { 0081 p->drawLine(QLineF(i * stepH, 0, i * stepH, m_wHeight)); 0082 p->drawLine(QLineF(0, i * stepV, m_wWidth, i * stepV)); 0083 } 0084 } 0085 0086 p->setRenderHint(QPainter::Antialiasing); 0087 0088 /* 0089 * Standard line 0090 */ 0091 p->drawLine(QLineF(0, m_wHeight, m_wWidth, 0)); 0092 } 0093 0094 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::setMaxPoints(int max) 0095 { 0096 Q_ASSERT(max >= 2); 0097 m_maxPoints = max; 0098 } 0099 0100 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::setPixmap(const QPixmap &pix) 0101 { 0102 m_pixmap = pix; 0103 m_pixmapIsDirty = true; 0104 update(); 0105 } 0106 0107 template <typename Curve_t> int AbstractCurveWidget<Curve_t>::gridLines() const 0108 { 0109 return m_gridLines; 0110 } 0111 0112 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::setGridLines(int lines) 0113 { 0114 m_gridLines = qBound(0, lines, 8); 0115 update(); 0116 } 0117 0118 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::slotZoomIn() 0119 { 0120 m_zoomLevel = qMax(m_zoomLevel - 1, 0); 0121 m_pixmapIsDirty = true; 0122 update(); 0123 } 0124 0125 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::slotZoomOut() 0126 { 0127 m_zoomLevel = qMin(m_zoomLevel + 1, 3); 0128 m_pixmapIsDirty = true; 0129 update(); 0130 } 0131 0132 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::setFromString(const QString &str) 0133 { 0134 m_curve.fromString(str); 0135 m_currentPointIndex = -1; 0136 Q_EMIT currentPoint(Point_t(), true); 0137 update(); 0138 } 0139 0140 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::reset() 0141 { 0142 setFromString(Curve_t().toString()); 0143 m_currentPointIndex = -1; 0144 Q_EMIT currentPoint(Point_t(), true); 0145 Q_EMIT modified(); 0146 update(); 0147 } 0148 0149 template <typename Curve_t> QString AbstractCurveWidget<Curve_t>::toString() 0150 { 0151 return m_curve.toString(); 0152 } 0153 0154 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::updateCurrentPoint(const Point_t &p, bool final) 0155 { 0156 if (m_currentPointIndex >= 0) { 0157 m_curve.setPoint(m_currentPointIndex, p); 0158 // during validation the point might have changed 0159 Q_EMIT currentPoint(m_curve.getPoint(m_currentPointIndex), isCurrentPointExtremal()); 0160 if (final) { 0161 Q_EMIT modified(); 0162 } 0163 update(); 0164 } 0165 } 0166 0167 template <typename Curve_t> typename AbstractCurveWidget<Curve_t>::Point_t AbstractCurveWidget<Curve_t>::getCurrentPoint() 0168 { 0169 if (m_currentPointIndex >= 0) { 0170 return m_curve.getPoint(m_currentPointIndex); 0171 } else { 0172 return Point_t(); 0173 } 0174 } 0175 0176 template <typename Curve_t> bool AbstractCurveWidget<Curve_t>::isCurrentPointExtremal() 0177 { 0178 return m_currentPointIndex == 0 || m_currentPointIndex == m_curve.points().size() - 1; 0179 } 0180 0181 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::slotDeleteCurrentPoint() 0182 { 0183 if (m_currentPointIndex > 0 && m_currentPointIndex < m_curve.points().size() - 1) { 0184 m_curve.removePoint(m_currentPointIndex); 0185 m_currentPointIndex--; 0186 Q_EMIT currentPoint(m_curve.getPoint(m_currentPointIndex), isCurrentPointExtremal()); 0187 update(); 0188 Q_EMIT modified(); 0189 setCursor(Qt::ArrowCursor); 0190 m_state = State_t::NORMAL; 0191 } 0192 } 0193 0194 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::resizeEvent(QResizeEvent *e) 0195 { 0196 m_pixmapIsDirty = true; 0197 QWidget::resizeEvent(e); 0198 } 0199 0200 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::leaveEvent(QEvent *event) 0201 { 0202 QWidget::leaveEvent(event); 0203 } 0204 0205 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::mouseReleaseEvent(QMouseEvent *event) 0206 { 0207 if (event->button() != Qt::LeftButton) { 0208 return; 0209 } 0210 0211 setCursor(Qt::ArrowCursor); 0212 m_state = State_t::NORMAL; 0213 0214 Q_EMIT modified(); 0215 } 0216 0217 template <typename Curve_t> void AbstractCurveWidget<Curve_t>::keyPressEvent(QKeyEvent *e) 0218 { 0219 if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace) { 0220 slotDeleteCurrentPoint(); 0221 } else { 0222 QWidget::keyPressEvent(e); 0223 } 0224 } 0225 0226 template <typename Curve_t> int AbstractCurveWidget<Curve_t>::heightForWidth(int w) const 0227 { 0228 return w; 0229 }