File indexing completed on 2024-04-28 04:52:23
0001 /* 0002 SPDX-FileCopyrightText: 2010 Simon Andreas Eugster <simon.eu@gmail.com> 0003 This file is part of kdenlive. See www.kdenlive.org. 0004 0005 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 */ 0007 0008 #include "waveform.h" 0009 #include "waveformgenerator.h" 0010 // For reading out the project resolution 0011 #include "core.h" 0012 #include "profiles/profilemodel.hpp" 0013 0014 #include "klocalizedstring.h" 0015 #include <KConfigGroup> 0016 #include <KSharedConfig> 0017 #include <QActionGroup> 0018 #include <QElapsedTimer> 0019 #include <QPainter> 0020 #include <QPoint> 0021 0022 const QSize Waveform::m_textWidth(35, 0); 0023 const int Waveform::m_paddingBottom(20); 0024 0025 Waveform::Waveform(QWidget *parent) 0026 : AbstractGfxScopeWidget(true, parent) 0027 0028 { 0029 m_ui = new Ui::Waveform_UI(); 0030 m_ui->setupUi(this); 0031 0032 m_ui->paintMode->addItem(i18n("Yellow"), QVariant(WaveformGenerator::PaintMode_Yellow)); 0033 m_ui->paintMode->addItem(i18n("White"), QVariant(WaveformGenerator::PaintMode_White)); 0034 m_ui->paintMode->addItem(i18n("Green"), QVariant(WaveformGenerator::PaintMode_Green)); 0035 0036 m_aRec601 = new QAction(i18n("Rec. 601"), this); 0037 m_aRec601->setCheckable(true); 0038 m_aRec709 = new QAction(i18n("Rec. 709"), this); 0039 m_aRec709->setCheckable(true); 0040 m_agRec = new QActionGroup(this); 0041 m_agRec->addAction(m_aRec601); 0042 m_agRec->addAction(m_aRec709); 0043 m_menu->addSeparator()->setText(i18n("Luma mode")); 0044 m_menu->addAction(m_aRec601); 0045 m_menu->addAction(m_aRec709); 0046 0047 connect(m_ui->paintMode, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &Waveform::forceUpdateScope); 0048 connect(this, &Waveform::signalMousePositionChanged, this, &Waveform::forceUpdateHUD); 0049 connect(m_aRec601, &QAction::toggled, this, &Waveform::forceUpdateScope); 0050 connect(m_aRec709, &QAction::toggled, this, &Waveform::forceUpdateScope); 0051 0052 init(); 0053 m_waveformGenerator = new WaveformGenerator(); 0054 } 0055 0056 Waveform::~Waveform() 0057 { 0058 writeConfig(); 0059 0060 delete m_waveformGenerator; 0061 delete m_aRec601; 0062 delete m_aRec709; 0063 delete m_agRec; 0064 delete m_ui; 0065 } 0066 0067 void Waveform::readConfig() 0068 { 0069 AbstractGfxScopeWidget::readConfig(); 0070 0071 KSharedConfigPtr config = KSharedConfig::openConfig(); 0072 KConfigGroup scopeConfig(config, configName()); 0073 m_ui->paintMode->setCurrentIndex(scopeConfig.readEntry("paintmode", 0)); 0074 m_aRec601->setChecked(scopeConfig.readEntry("rec601", false)); 0075 m_aRec709->setChecked(!m_aRec601->isChecked()); 0076 } 0077 0078 void Waveform::writeConfig() 0079 { 0080 KSharedConfigPtr config = KSharedConfig::openConfig(); 0081 KConfigGroup scopeConfig(config, configName()); 0082 scopeConfig.writeEntry("paintmode", m_ui->paintMode->currentIndex()); 0083 scopeConfig.writeEntry("rec601", m_aRec601->isChecked()); 0084 scopeConfig.sync(); 0085 } 0086 0087 QRect Waveform::scopeRect() 0088 { 0089 // Distance from top/left/right 0090 int border = 6; 0091 QPoint topleft(border, m_ui->verticalSpacer->geometry().y() + border); 0092 0093 return QRect(topleft, this->size() - QSize(border + topleft.x(), border + topleft.y())); 0094 } 0095 0096 ///// Implemented methods ///// 0097 0098 QString Waveform::widgetName() const 0099 { 0100 return QStringLiteral("Waveform"); 0101 } 0102 bool Waveform::isHUDDependingOnInput() const 0103 { 0104 return false; 0105 } 0106 bool Waveform::isScopeDependingOnInput() const 0107 { 0108 return true; 0109 } 0110 bool Waveform::isBackgroundDependingOnInput() const 0111 { 0112 return false; 0113 } 0114 0115 QImage Waveform::renderHUD(uint) 0116 { 0117 QImage hud(m_scopeRect.size(), QImage::Format_ARGB32); 0118 hud.fill(qRgba(0, 0, 0, 0)); 0119 0120 QPainter davinci; 0121 bool ok = davinci.begin(&hud); 0122 if (!ok) { 0123 qDebug() << "Could not initialise QPainter for Waveform HUD."; 0124 return hud; 0125 } 0126 davinci.setPen(penLight); 0127 0128 // qCDebug(KDENLIVE_LOG) << values.value("width"); 0129 0130 const int rightX = scopeRect().width() - m_textWidth.width() + 3; 0131 const int x = m_mousePos.x() - scopeRect().x(); 0132 const int y = m_mousePos.y() - scopeRect().y(); 0133 0134 if (scopeRect().height() > 0 && m_mouseWithinWidget) { 0135 int val = 255 - (255 * y) / scopeRect().height(); 0136 0137 if (val >= 0 && val <= 255) { 0138 // Draw a horizontal line through the current mouse position 0139 // and show the value of the waveform there 0140 davinci.drawLine(0, y, scopeRect().size().width() - m_textWidth.width(), y); 0141 0142 // Make the value stick to the line unless it is at the top/bottom of the scope 0143 int valY = y + 5; 0144 const int top = 30; 0145 const int bottom = 20; 0146 if (valY < top) { 0147 valY = top; 0148 } else if (valY > scopeRect().height() - bottom) { 0149 valY = scopeRect().height() - bottom; 0150 } 0151 davinci.drawText(rightX, valY, QVariant(val).toString()); 0152 } 0153 0154 if (scopeRect().width() > 0) { 0155 // Draw a vertical line and the x position of the source clip 0156 const int profileWidth = pCore->getCurrentProfile()->width(); 0157 0158 const int clipX = (x * (profileWidth - 1)) / (scopeRect().width() - m_textWidth.width() - 1); 0159 0160 if (clipX >= 0 && clipX <= profileWidth) { 0161 int valX = x - 15; 0162 if (valX < 0) { 0163 valX = 0; 0164 } 0165 if (valX > scopeRect().width() - 55 - m_textWidth.width()) { 0166 valX = scopeRect().width() - 55 - m_textWidth.width(); 0167 } 0168 0169 davinci.drawLine(x, y, x, scopeRect().height() - m_paddingBottom); 0170 davinci.drawText(valX, scopeRect().height() - 5, QVariant(clipX).toString() + QStringLiteral(" px")); 0171 } 0172 } 0173 } 0174 davinci.drawText(rightX, scopeRect().height() - m_paddingBottom, QStringLiteral("0")); 0175 davinci.drawText(rightX, 10, QStringLiteral("255")); 0176 0177 Q_EMIT signalHUDRenderingFinished(0, 1); 0178 return hud; 0179 } 0180 0181 QImage Waveform::renderGfxScope(uint accelFactor, const QImage &qimage) 0182 { 0183 QElapsedTimer timer; 0184 timer.start(); 0185 0186 const int paintmode = m_ui->paintMode->itemData(m_ui->paintMode->currentIndex()).toInt(); 0187 ITURec rec = m_aRec601->isChecked() ? ITURec::Rec_601 : ITURec::Rec_709; 0188 QImage wave = m_waveformGenerator->calculateWaveform(scopeRect().size() - m_textWidth - QSize(0, m_paddingBottom), qimage, 0189 WaveformGenerator::PaintMode(paintmode), true, rec, accelFactor); 0190 0191 Q_EMIT signalScopeRenderingFinished(uint(timer.elapsed()), 1); 0192 return wave; 0193 } 0194 0195 QImage Waveform::renderBackground(uint) 0196 { 0197 Q_EMIT signalBackgroundRenderingFinished(0, 1); 0198 return QImage(); 0199 }