1 /***************************************************************************
2 * Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com) *
3 * This file is part of kdenlive. See www.kdenlive.org. *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 ***************************************************************************/
12 #include <QMouseEvent>
16 // For reading out the project resolution
17 #include "kdenlivesettings.h"
18 #include "profilesdialog.h"
22 #include "waveformgenerator.h"
25 const QSize Waveform::m_textWidth(35,0);
26 const int Waveform::m_paddingBottom(20);
28 Waveform::Waveform(MonitorManager *manager, QWidget *parent) :
29 AbstractGfxScopeWidget(manager, true, parent)
32 ui = new Ui::Waveform_UI();
35 ui->paintMode->addItem(i18n("Yellow"), QVariant(WaveformGenerator::PaintMode_Yellow));
36 ui->paintMode->addItem(i18n("White"), QVariant(WaveformGenerator::PaintMode_White));
37 ui->paintMode->addItem(i18n("Green"), QVariant(WaveformGenerator::PaintMode_Green));
40 m_aRec601 = new QAction(i18n("Rec. 601"), this);
41 m_aRec601->setCheckable(true);
42 m_aRec709 = new QAction(i18n("Rec. 709"), this);
43 m_aRec709->setCheckable(true);
44 m_agRec = new QActionGroup(this);
45 m_agRec->addAction(m_aRec601);
46 m_agRec->addAction(m_aRec709);
47 m_menu->addSeparator()->setText(i18n("Luma mode"));
48 m_menu->addAction(m_aRec601);
49 m_menu->addAction(m_aRec709);
53 b &= connect(ui->paintMode, SIGNAL(currentIndexChanged(int)), this, SLOT(forceUpdateScope()));
54 b &= connect(this, SIGNAL(signalMousePositionChanged()), this, SLOT(forceUpdateHUD()));
55 b &= connect(m_aRec601, SIGNAL(toggled(bool)), this, SLOT(forceUpdateScope()));
56 b &= connect(m_aRec709, SIGNAL(toggled(bool)), this, SLOT(forceUpdateScope()));
60 m_waveformGenerator = new WaveformGenerator();
67 delete m_waveformGenerator;
74 void Waveform::readConfig()
76 AbstractGfxScopeWidget::readConfig();
78 KSharedConfigPtr config = KGlobal::config();
79 KConfigGroup scopeConfig(config, configName());
80 ui->paintMode->setCurrentIndex(scopeConfig.readEntry("paintmode", 0));
81 m_aRec601->setChecked(scopeConfig.readEntry("rec601", false));
82 m_aRec709->setChecked(!m_aRec601->isChecked());
85 void Waveform::writeConfig()
87 KSharedConfigPtr config = KGlobal::config();
88 KConfigGroup scopeConfig(config, configName());
89 scopeConfig.writeEntry("paintmode", ui->paintMode->currentIndex());
90 scopeConfig.writeEntry("rec601", m_aRec601->isChecked());
95 QRect Waveform::scopeRect()
97 // Distance from top/left/right
99 QPoint topleft(offset, ui->verticalSpacer->geometry().y()+offset);
101 return QRect(topleft, this->size() - QSize(offset+topleft.x(), offset+topleft.y()));
105 ///// Implemented methods /////
107 QString Waveform::widgetName() const { return QString("Waveform"); }
108 bool Waveform::isHUDDependingOnInput() const { return false; }
109 bool Waveform::isScopeDependingOnInput() const { return true; }
110 bool Waveform::isBackgroundDependingOnInput() const { return false; }
112 QImage Waveform::renderHUD(uint)
114 QImage hud(m_scopeRect.size(), QImage::Format_ARGB32);
115 hud.fill(qRgba(0,0,0,0));
117 QPainter davinci(&hud);
118 davinci.setPen(penLight);
120 QMap< QString, QString > values = ProfilesDialog::getSettingsFromFile(KdenliveSettings::current_profile());
121 // qDebug() << values.value("width");
123 const int rightX = scopeRect().width()-m_textWidth.width()+3;
124 const int x = m_mousePos.x() - scopeRect().x();
125 const int y = m_mousePos.y() - scopeRect().y();
127 if (scopeRect().height() > 0 && m_mouseWithinWidget) {
129 const int bottom = 20;
130 int val = 255*(1-(float)y/scopeRect().height());
132 if (val >= 0 && val <= 255) {
133 // Draw a horizontal line through the current mouse position
134 // and show the value of the waveform there
135 davinci.drawLine(0, y, scopeRect().size().width()-m_textWidth.width(), y);
137 // Make the value stick to the line unless it is at the top/bottom of the scope
141 } else if (valY > scopeRect().height()-bottom) {
142 valY = scopeRect().height()-bottom;
144 davinci.drawText(rightX, valY, QVariant(val).toString());
147 if (scopeRect().width() > 0) {
148 // Draw a vertical line and the x position of the source clip
150 const int profileWidth = values.value("width").toInt(&ok);
153 const int clipX = (float)x/(scopeRect().width()-m_textWidth.width()-1)*(profileWidth-1);
155 if (clipX >= 0 && clipX <= profileWidth) {
157 if (valX < 0) { valX = 0; }
158 if (valX > scopeRect().width()-55-m_textWidth.width()) { valX = scopeRect().width()-55-m_textWidth.width(); }
160 davinci.drawLine(x, y, x, scopeRect().height()-m_paddingBottom);
161 davinci.drawText(valX, scopeRect().height()-5, QVariant(clipX).toString() + " px");
167 davinci.drawText(rightX, scopeRect().height()-m_paddingBottom, "0");
168 davinci.drawText(rightX, 10, "255");
170 emit signalHUDRenderingFinished(0, 1);
174 QImage Waveform::renderGfxScope(uint accelFactor, const QImage qimage)
176 QTime start = QTime::currentTime();
179 int paintmode = ui->paintMode->itemData(ui->paintMode->currentIndex()).toInt();
180 WaveformGenerator::Rec rec = m_aRec601->isChecked() ? WaveformGenerator::Rec_601 : WaveformGenerator::Rec_709;
181 QImage wave = m_waveformGenerator->calculateWaveform(scopeRect().size() - m_textWidth - QSize(0,m_paddingBottom), qimage,
182 (WaveformGenerator::PaintMode) paintmode, true, rec, accelFactor);
184 emit signalScopeRenderingFinished(start.elapsed(), 1);
188 QImage Waveform::renderBackground(uint)
190 emit signalBackgroundRenderingFinished(0, 1);