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 ***************************************************************************/
15 // For reading out the project resolution
16 #include "kdenlivesettings.h"
17 #include "profilesdialog.h"
20 #include "colorcorrection/waveformgenerator.h"
23 const QSize Waveform::m_textWidth(35,0);
24 const int Waveform::m_paddingBottom(20);
26 Waveform::Waveform(QWidget *parent) :
27 AbstractGfxScopeWidget(true, parent)
30 ui = new Ui::Waveform_UI();
33 ui->paintMode->addItem(i18n("Yellow"), QVariant(WaveformGenerator::PaintMode_Yellow));
34 ui->paintMode->addItem(i18n("White"), QVariant(WaveformGenerator::PaintMode_White));
35 ui->paintMode->addItem(i18n("Green"), QVariant(WaveformGenerator::PaintMode_Green));
38 m_aRec601 = new QAction(i18n("Rec. 601"), this);
39 m_aRec601->setCheckable(true);
40 m_aRec709 = new QAction(i18n("Rec. 709"), this);
41 m_aRec709->setCheckable(true);
42 m_agRec = new QActionGroup(this);
43 m_agRec->addAction(m_aRec601);
44 m_agRec->addAction(m_aRec709);
45 m_menu->addSeparator()->setText(i18n("Luma mode"));
46 m_menu->addAction(m_aRec601);
47 m_menu->addAction(m_aRec709);
51 b &= connect(ui->paintMode, SIGNAL(currentIndexChanged(int)), this, SLOT(forceUpdateScope()));
52 b &= connect(this, SIGNAL(signalMousePositionChanged()), this, SLOT(forceUpdateHUD()));
53 b &= connect(m_aRec601, SIGNAL(toggled(bool)), this, SLOT(forceUpdateScope()));
54 b &= connect(m_aRec709, SIGNAL(toggled(bool)), this, SLOT(forceUpdateScope()));
58 m_waveformGenerator = new WaveformGenerator();
65 delete m_waveformGenerator;
72 void Waveform::readConfig()
74 AbstractGfxScopeWidget::readConfig();
76 KSharedConfigPtr config = KGlobal::config();
77 KConfigGroup scopeConfig(config, configName());
78 ui->paintMode->setCurrentIndex(scopeConfig.readEntry("paintmode", 0));
79 m_aRec601->setChecked(scopeConfig.readEntry("rec601", false));
80 m_aRec709->setChecked(!m_aRec601->isChecked());
83 void Waveform::writeConfig()
85 KSharedConfigPtr config = KGlobal::config();
86 KConfigGroup scopeConfig(config, configName());
87 scopeConfig.writeEntry("paintmode", ui->paintMode->currentIndex());
88 scopeConfig.writeEntry("rec601", m_aRec601->isChecked());
93 QRect Waveform::scopeRect()
95 // Distance from top/left/right
97 QPoint topleft(offset, ui->verticalSpacer->geometry().y()+offset);
99 return QRect(topleft, this->size() - QSize(offset+topleft.x(), offset+topleft.y()));
103 ///// Implemented methods /////
105 QString Waveform::widgetName() const { return QString("Waveform"); }
106 bool Waveform::isHUDDependingOnInput() const { return false; }
107 bool Waveform::isScopeDependingOnInput() const { return true; }
108 bool Waveform::isBackgroundDependingOnInput() const { return false; }
110 QImage Waveform::renderHUD(uint)
112 QImage hud(m_scopeRect.size(), QImage::Format_ARGB32);
113 hud.fill(qRgba(0,0,0,0));
115 QPainter davinci(&hud);
116 davinci.setPen(penLight);
118 QMap< QString, QString > values = ProfilesDialog::getSettingsFromFile(KdenliveSettings::current_profile());
119 // qDebug() << values.value("width");
121 const int rightX = scopeRect().width()-m_textWidth.width()+3;
122 const int x = m_mousePos.x() - scopeRect().x();
123 const int y = m_mousePos.y() - scopeRect().y();
125 if (scopeRect().height() > 0 && m_mouseWithinWidget) {
127 const int bottom = 20;
128 int val = 255*(1-(float)y/scopeRect().height());
130 if (val >= 0 && val <= 255) {
131 // Draw a horizontal line through the current mouse position
132 // and show the value of the waveform there
133 davinci.drawLine(0, y, scopeRect().size().width()-m_textWidth.width(), y);
135 // Make the value stick to the line unless it is at the top/bottom of the scope
139 } else if (valY > scopeRect().height()-bottom) {
140 valY = scopeRect().height()-bottom;
142 davinci.drawText(rightX, valY, QVariant(val).toString());
145 if (scopeRect().width() > 0) {
146 // Draw a vertical line and the x position of the source clip
148 const int profileWidth = values.value("width").toInt(&ok);
151 const int clipX = (float)x/(scopeRect().width()-m_textWidth.width()-1)*(profileWidth-1);
153 if (clipX >= 0 && clipX <= profileWidth) {
155 if (valX < 0) { valX = 0; }
156 if (valX > scopeRect().width()-55-m_textWidth.width()) { valX = scopeRect().width()-55-m_textWidth.width(); }
158 davinci.drawLine(x, y, x, scopeRect().height()-m_paddingBottom);
159 davinci.drawText(valX, scopeRect().height()-5, QVariant(clipX).toString() + " px");
165 davinci.drawText(rightX, scopeRect().height()-m_paddingBottom, "0");
166 davinci.drawText(rightX, 10, "255");
168 emit signalHUDRenderingFinished(0, 1);
172 QImage Waveform::renderGfxScope(uint accelFactor, const QImage &qimage)
174 QTime start = QTime::currentTime();
177 const int paintmode = ui->paintMode->itemData(ui->paintMode->currentIndex()).toInt();
178 WaveformGenerator::Rec rec = m_aRec601->isChecked() ? WaveformGenerator::Rec_601 : WaveformGenerator::Rec_709;
179 QImage wave = m_waveformGenerator->calculateWaveform(scopeRect().size() - m_textWidth - QSize(0,m_paddingBottom), qimage,
180 (WaveformGenerator::PaintMode) paintmode, true, rec, accelFactor);
182 emit signalScopeRenderingFinished(start.elapsed(), 1);
186 QImage Waveform::renderBackground(uint)
188 emit signalBackgroundRenderingFinished(0, 1);
192 #include "waveform.moc"