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"
21 #include "colorcorrection/waveformgenerator.h"
24 const QSize Waveform::m_textWidth(35,0);
25 const int Waveform::m_paddingBottom(20);
27 Waveform::Waveform(QWidget *parent) :
28 AbstractGfxScopeWidget(true, parent)
31 ui = new Ui::Waveform_UI();
34 ui->paintMode->addItem(i18n("Yellow"), QVariant(WaveformGenerator::PaintMode_Yellow));
35 ui->paintMode->addItem(i18n("White"), QVariant(WaveformGenerator::PaintMode_White));
36 ui->paintMode->addItem(i18n("Green"), QVariant(WaveformGenerator::PaintMode_Green));
39 m_aRec601 = new QAction(i18n("Rec. 601"), this);
40 m_aRec601->setCheckable(true);
41 m_aRec709 = new QAction(i18n("Rec. 709"), this);
42 m_aRec709->setCheckable(true);
43 m_agRec = new QActionGroup(this);
44 m_agRec->addAction(m_aRec601);
45 m_agRec->addAction(m_aRec709);
46 m_menu->addSeparator()->setText(i18n("Luma mode"));
47 m_menu->addAction(m_aRec601);
48 m_menu->addAction(m_aRec709);
52 b &= connect(ui->paintMode, SIGNAL(currentIndexChanged(int)), this, SLOT(forceUpdateScope()));
53 b &= connect(this, SIGNAL(signalMousePositionChanged()), this, SLOT(forceUpdateHUD()));
54 b &= connect(m_aRec601, SIGNAL(toggled(bool)), this, SLOT(forceUpdateScope()));
55 b &= connect(m_aRec709, SIGNAL(toggled(bool)), this, SLOT(forceUpdateScope()));
59 m_waveformGenerator = new WaveformGenerator();
66 delete m_waveformGenerator;
73 void Waveform::readConfig()
75 AbstractGfxScopeWidget::readConfig();
77 KSharedConfigPtr config = KGlobal::config();
78 KConfigGroup scopeConfig(config, configName());
79 ui->paintMode->setCurrentIndex(scopeConfig.readEntry("paintmode", 0));
80 m_aRec601->setChecked(scopeConfig.readEntry("rec601", false));
81 m_aRec709->setChecked(!m_aRec601->isChecked());
84 void Waveform::writeConfig()
86 KSharedConfigPtr config = KGlobal::config();
87 KConfigGroup scopeConfig(config, configName());
88 scopeConfig.writeEntry("paintmode", ui->paintMode->currentIndex());
89 scopeConfig.writeEntry("rec601", m_aRec601->isChecked());
94 QRect Waveform::scopeRect()
96 // Distance from top/left/right
98 QPoint topleft(offset, ui->verticalSpacer->geometry().y()+offset);
100 return QRect(topleft, this->size() - QSize(offset+topleft.x(), offset+topleft.y()));
104 ///// Implemented methods /////
106 QString Waveform::widgetName() const { return QString("Waveform"); }
107 bool Waveform::isHUDDependingOnInput() const { return false; }
108 bool Waveform::isScopeDependingOnInput() const { return true; }
109 bool Waveform::isBackgroundDependingOnInput() const { return false; }
111 QImage Waveform::renderHUD(uint)
113 QImage hud(m_scopeRect.size(), QImage::Format_ARGB32);
114 hud.fill(qRgba(0,0,0,0));
116 QPainter davinci(&hud);
117 davinci.setPen(penLight);
119 QMap< QString, QString > values = ProfilesDialog::getSettingsFromFile(KdenliveSettings::current_profile());
120 // qDebug() << values.value("width");
122 const int rightX = scopeRect().width()-m_textWidth.width()+3;
123 const int x = m_mousePos.x() - scopeRect().x();
124 const int y = m_mousePos.y() - scopeRect().y();
126 if (scopeRect().height() > 0 && m_mouseWithinWidget) {
128 const int bottom = 20;
129 int val = 255*(1-(float)y/scopeRect().height());
131 if (val >= 0 && val <= 255) {
132 // Draw a horizontal line through the current mouse position
133 // and show the value of the waveform there
134 davinci.drawLine(0, y, scopeRect().size().width()-m_textWidth.width(), y);
136 // Make the value stick to the line unless it is at the top/bottom of the scope
140 } else if (valY > scopeRect().height()-bottom) {
141 valY = scopeRect().height()-bottom;
143 davinci.drawText(rightX, valY, QVariant(val).toString());
146 if (scopeRect().width() > 0) {
147 // Draw a vertical line and the x position of the source clip
149 const int profileWidth = values.value("width").toInt(&ok);
152 const int clipX = (float)x/(scopeRect().width()-m_textWidth.width()-1)*(profileWidth-1);
154 if (clipX >= 0 && clipX <= profileWidth) {
156 if (valX < 0) { valX = 0; }
157 if (valX > scopeRect().width()-55-m_textWidth.width()) { valX = scopeRect().width()-55-m_textWidth.width(); }
159 davinci.drawLine(x, y, x, scopeRect().height()-m_paddingBottom);
160 davinci.drawText(valX, scopeRect().height()-5, QVariant(clipX).toString() + " px");
166 davinci.drawText(rightX, scopeRect().height()-m_paddingBottom, "0");
167 davinci.drawText(rightX, 10, "255");
169 emit signalHUDRenderingFinished(0, 1);
173 QImage Waveform::renderGfxScope(uint accelFactor, const QImage qimage)
175 QTime start = QTime::currentTime();
178 int paintmode = ui->paintMode->itemData(ui->paintMode->currentIndex()).toInt();
179 WaveformGenerator::Rec rec = m_aRec601->isChecked() ? WaveformGenerator::Rec_601 : WaveformGenerator::Rec_709;
180 QImage wave = m_waveformGenerator->calculateWaveform(scopeRect().size() - m_textWidth - QSize(0,m_paddingBottom), qimage,
181 (WaveformGenerator::PaintMode) paintmode, true, rec, accelFactor);
183 emit signalScopeRenderingFinished(start.elapsed(), 1);
187 QImage Waveform::renderBackground(uint)
189 emit signalBackgroundRenderingFinished(0, 1);