]> git.sesse.net Git - kdenlive/blob - src/scopes/colorscopes/waveform.cpp
Preparing for scope manager (merge from Granjow's work in refactoring)
[kdenlive] / src / scopes / colorscopes / waveform.cpp
1 /***************************************************************************
2  *   Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com)      *
3  *   This file is part of kdenlive. See www.kdenlive.org.                  *
4  *                                                                         *
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  ***************************************************************************/
10
11 #include <QMenu>
12 #include <QMouseEvent>
13 #include <QPainter>
14 #include <QPoint>
15
16 // For reading out the project resolution
17 #include "kdenlivesettings.h"
18 #include "profilesdialog.h"
19
20 #include "renderer.h"
21 #include "waveform.h"
22 #include "colorcorrection/waveformgenerator.h"
23
24
25 const QSize Waveform::m_textWidth(35,0);
26 const int Waveform::m_paddingBottom(20);
27
28 Waveform::Waveform(MonitorManager *manager, QWidget *parent) :
29     AbstractGfxScopeWidget(manager, true, parent)
30   ,ui(NULL)
31 {
32     ui = new Ui::Waveform_UI();
33     ui->setupUi(this);
34
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));
38
39
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);
50
51
52     bool b = true;
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()));
57     Q_ASSERT(b);
58
59     init();
60     m_waveformGenerator = new WaveformGenerator();
61 }
62
63 Waveform::~Waveform()
64 {
65     writeConfig();
66
67     delete m_waveformGenerator;
68     delete m_aRec601;
69     delete m_aRec709;
70     delete m_agRec;
71     delete ui;
72 }
73
74 void Waveform::readConfig()
75 {
76     AbstractGfxScopeWidget::readConfig();
77
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());
83 }
84
85 void Waveform::writeConfig()
86 {
87     KSharedConfigPtr config = KGlobal::config();
88     KConfigGroup scopeConfig(config, configName());
89     scopeConfig.writeEntry("paintmode", ui->paintMode->currentIndex());
90     scopeConfig.writeEntry("rec601", m_aRec601->isChecked());
91     scopeConfig.sync();
92 }
93
94
95 QRect Waveform::scopeRect()
96 {
97     // Distance from top/left/right
98     int offset = 6;
99     QPoint topleft(offset, ui->verticalSpacer->geometry().y()+offset);
100
101     return QRect(topleft, this->size() - QSize(offset+topleft.x(), offset+topleft.y()));
102 }
103
104
105 ///// Implemented methods /////
106
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; }
111
112 QImage Waveform::renderHUD(uint)
113 {
114     QImage hud(m_scopeRect.size(), QImage::Format_ARGB32);
115     hud.fill(qRgba(0,0,0,0));
116
117     QPainter davinci(&hud);
118     davinci.setPen(penLight);
119
120     QMap< QString, QString > values = ProfilesDialog::getSettingsFromFile(KdenliveSettings::current_profile());
121 //    qDebug() << values.value("width");
122
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();
126
127     if (scopeRect().height() > 0 && m_mouseWithinWidget) {
128         const int top = 30;
129         const int bottom = 20;
130         int val = 255*(1-(float)y/scopeRect().height());
131
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);
136
137             // Make the value stick to the line unless it is at the top/bottom of the scope
138             int valY = y+5;
139             if (valY < top) {
140                 valY = top;
141             } else if (valY > scopeRect().height()-bottom) {
142                 valY = scopeRect().height()-bottom;
143             }
144             davinci.drawText(rightX, valY, QVariant(val).toString());
145         }
146
147         if (scopeRect().width() > 0) {
148             // Draw a vertical line and the x position of the source clip
149             bool ok;
150             const int profileWidth = values.value("width").toInt(&ok);
151
152             if (ok) {
153                 const int clipX = (float)x/(scopeRect().width()-m_textWidth.width()-1)*(profileWidth-1);
154
155                 if (clipX >= 0 && clipX <= profileWidth) {
156                     int valX = x-15;
157                     if (valX < 0) { valX = 0; }
158                     if (valX > scopeRect().width()-55-m_textWidth.width()) { valX = scopeRect().width()-55-m_textWidth.width(); }
159
160                     davinci.drawLine(x, y, x, scopeRect().height()-m_paddingBottom);
161                     davinci.drawText(valX, scopeRect().height()-5, QVariant(clipX).toString() + " px");
162                 }
163             }
164         }
165
166     }
167     davinci.drawText(rightX, scopeRect().height()-m_paddingBottom, "0");
168     davinci.drawText(rightX, 10, "255");
169
170     emit signalHUDRenderingFinished(0, 1);
171     return hud;
172 }
173
174 QImage Waveform::renderGfxScope(uint accelFactor, const QImage qimage)
175 {
176     QTime start = QTime::currentTime();
177     start.start();
178
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);
183
184     emit signalScopeRenderingFinished(start.elapsed(), 1);
185     return wave;
186 }
187
188 QImage Waveform::renderBackground(uint)
189 {
190     emit signalBackgroundRenderingFinished(0, 1);
191     return QImage();
192 }