~keithsalisbury/mixxx/mixxx

« back to all changes in this revision

Viewing changes to mixxx/src/waveform/waveformwidgetfactory.cpp

  • Committer: Keith Salisbury
  • Date: 2012-05-06 13:44:20 UTC
  • mfrom: (2994.1.100 mixxx-trunk)
  • Revision ID: keithsalisbury@gmail.com-20120506134420-8k1dqq10aqmx0ecq
merge with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include "waveform/waveformwidgetfactory.h"
2
 
#include "waveform/widgets/waveformwidgetabstract.h"
3
 
 
4
 
#include "widget/wwaveformviewer.h"
5
 
 
6
 
//WaveformWidgets
7
 
#include "waveform/widgets/emptywaveformwidget.h"
8
 
#include "waveform/widgets/softwarewaveformwidget.h"
9
 
#include "waveform/widgets/glwaveformwidget.h"
10
 
#include "waveform/widgets/glslwaveformwidget.h"
11
 
#include "waveform/widgets/glsimplewaveformwidget.h"
12
 
 
13
 
#include "defs.h"
14
 
 
 
1
#include <QStringList>
 
2
#include <QTime>
15
3
#include <QTimer>
16
4
#include <QWidget>
17
 
#include <QTime>
18
 
#include <QStringList>
19
 
 
 
5
#include <QtDebug>
20
6
#include <QtOpenGL/QGLFormat>
21
7
#include <QtOpenGL/QGLShaderProgram>
22
8
 
23
 
 
24
 
#include <QDebug>
 
9
#include "waveform/waveformwidgetfactory.h"
 
10
 
 
11
#include "controlpotmeter.h"
 
12
#include "defs.h"
 
13
#include "waveform/widgets/emptywaveformwidget.h"
 
14
#include "waveform/widgets/glsimplewaveformwidget.h"
 
15
#include "waveform/widgets/glslwaveformwidget.h"
 
16
#include "waveform/widgets/glwaveformwidget.h"
 
17
#include "waveform/widgets/softwarewaveformwidget.h"
 
18
#include "waveform/widgets/waveformwidgetabstract.h"
 
19
#include "widget/wwaveformviewer.h"
 
20
 
 
21
///////////////////////////////////////////
 
22
 
 
23
WaveformWidgetAbstractHandle::WaveformWidgetAbstractHandle()
 
24
        : m_active(true),
 
25
          m_type(WaveformWidgetType::Count_WaveformwidgetType) {
 
26
}
 
27
 
 
28
///////////////////////////////////////////
 
29
 
 
30
WaveformWidgetHolder::WaveformWidgetHolder(WaveformWidgetAbstract* waveformWidget,
 
31
                                           WWaveformViewer* waveformViewer,
 
32
                                           const QDomNode& visualNodeCache)
 
33
        : m_waveformWidget(waveformWidget),
 
34
          m_waveformViewer(waveformViewer),
 
35
          m_visualNodeCache(visualNodeCache.cloneNode()) {
 
36
}
 
37
 
 
38
///////////////////////////////////////////
25
39
 
26
40
WaveformWidgetFactory::WaveformWidgetFactory() {
27
41
    m_time = new QTime();
28
42
    m_config = 0;
 
43
    m_skipRender = false;
29
44
    setFrameRate(33);
30
45
    m_defaultZoom = 1;
31
46
    m_zoomSync = false;
 
47
    m_visualGain[All] = 1.5;
 
48
    m_visualGain[Low] = 1.0;
 
49
    m_visualGain[Mid] = 1.0;
 
50
    m_visualGain[High] = 1.0;
32
51
 
33
52
    m_lastFrameTime = 0;
34
53
    m_actualFrameRate = 0;
77
96
            minorVersion = 1;
78
97
        }
79
98
 
80
 
        if( majorVersion != 0 && minorVersion != 0)
 
99
        if (majorVersion != 0) {
81
100
            m_openGLVersion = QString::number(majorVersion) + "." +
82
101
                    QString::number(minorVersion);
 
102
        }
83
103
        m_openGLAvailable = true;
84
104
        {
85
105
            QGLWidget glWidget;
89
109
        }
90
110
    }
91
111
 
92
 
    //default selection
93
 
    if (m_openGLAvailable) {
94
 
        if (m_openGLShaderAvailable) {
95
 
            //TODO: (vrince) enable when ready
96
 
            //m_type = WaveformWidgetType::GLSLWaveform;
97
 
            m_type = WaveformWidgetType::GLWaveform;
98
 
        } else {
99
 
            m_type = WaveformWidgetType::GLWaveform;
100
 
        }
101
 
    } else {
102
 
        m_type = WaveformWidgetType::SoftwareWaveform;
103
 
    }
104
 
 
105
112
    evaluateWidgets();
106
113
    start();
107
114
}
112
119
 
113
120
bool WaveformWidgetFactory::setConfig(ConfigObject<ConfigValue> *config){
114
121
    m_config = config;
115
 
    if( !m_config)
 
122
    if (!m_config)
116
123
        return false;
117
124
 
118
 
    QString framRate = m_config->getValueString(ConfigKey("[Waveform]","FrameRate"));
119
 
    if( !framRate.isEmpty()) {
120
 
        int frameRate = framRate.toInt();
 
125
    bool ok = false;
 
126
 
 
127
    int frameRate = m_config->getValueString(ConfigKey("[Waveform]","FrameRate")).toInt(&ok);
 
128
    if (ok) {
121
129
        setFrameRate(frameRate);
122
130
    } else {
123
131
        m_config->set(ConfigKey("[Waveform]","FrameRate"), ConfigValue(m_frameRate));
124
132
    }
125
133
 
126
 
    QString defaultZoom = m_config->getValueString(ConfigKey("[Waveform]","DefaultZoom"));
127
 
    if( !defaultZoom.isEmpty()) {
128
 
        int zoom = defaultZoom.toInt();
129
 
        setDefaultZoom(zoom);
 
134
    int defaultZoom = m_config->getValueString(ConfigKey("[Waveform]","DefaultZoom")).toInt(&ok);
 
135
    if (ok) {
 
136
        setDefaultZoom(defaultZoom);
130
137
    } else{
131
138
        m_config->set(ConfigKey("[Waveform]","DefaultZoom"), ConfigValue(m_defaultZoom));
132
139
    }
133
140
 
134
 
    QString zoomSync = m_config->getValueString(ConfigKey("[Waveform]","ZoomSynchronization"));
135
 
    if( !zoomSync.isEmpty()) {
136
 
        bool sync = zoomSync.toInt();
137
 
        setZoomSync(sync);
 
141
 
 
142
    int zoomSync = m_config->getValueString(ConfigKey("[Waveform]","ZoomSynchronization")).toInt(&ok);
 
143
    if (ok) {
 
144
        setZoomSync(static_cast<bool>(zoomSync));
138
145
    } else {
139
146
        m_config->set(ConfigKey("[Waveform]","ZoomSynchronization"), ConfigValue(m_zoomSync));
140
147
    }
141
148
 
 
149
    WaveformWidgetType::Type type = static_cast<WaveformWidgetType::Type>(
 
150
        m_config->getValueString(ConfigKey("[Waveform]","WaveformType")).toInt(&ok));
 
151
    if (!ok || !setWidgetType(type)) {
 
152
        setWidgetType(autoChooseWidgetType());
 
153
    }
 
154
 
 
155
    for (int i = 0; i < FilterCount; i++) {
 
156
        double visualGain = m_config->getValueString(
 
157
            ConfigKey("[Waveform]","VisualGain_" + QString::number(i))).toDouble(&ok);
 
158
 
 
159
        if (ok) {
 
160
            setVisualGain(FilterIndex(i), visualGain);
 
161
        } else {
 
162
            m_config->set(ConfigKey("[Waveform]","VisualGain_" + QString::number(i)),
 
163
                          QString::number(m_visualGain[i]));
 
164
        }
 
165
    }
 
166
 
142
167
    return true;
143
168
}
144
169
 
145
170
void WaveformWidgetFactory::start() {
146
 
    qDebug() << "WaveformWidgetFactory::start";
 
171
    //qDebug() << "WaveformWidgetFactory::start";
147
172
    killTimer(m_mainTimerId);
148
173
    m_mainTimerId = startTimer(1000.0/double(m_frameRate));
149
174
}
150
175
 
151
176
void WaveformWidgetFactory::stop() {
152
177
    killTimer(m_mainTimerId);
153
 
    m_mainTimerId = 0;
 
178
    m_mainTimerId = -1;
154
179
}
155
180
 
156
181
void WaveformWidgetFactory::timerEvent(QTimerEvent *timerEvent) {
157
 
    if( timerEvent->timerId() == m_mainTimerId)
 
182
    if (timerEvent->timerId() == m_mainTimerId) {
158
183
        refresh();
 
184
    }
159
185
}
160
186
 
161
187
void WaveformWidgetFactory::destroyWidgets() {
162
 
    for (int i = 0; i < m_waveformWidgets.size(); i++)
163
 
        delete m_waveformWidgets[i];
164
 
    m_waveformWidgets.clear();
 
188
    for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++) {
 
189
        WaveformWidgetAbstract* pWidget = m_waveformWidgetHolders[i].m_waveformWidget;;
 
190
        m_waveformWidgetHolders[i].m_waveformWidget = NULL;
 
191
        delete pWidget;
 
192
    }
 
193
    m_waveformWidgetHolders.clear();
165
194
}
166
195
 
167
196
void WaveformWidgetFactory::addTimerListener(QWidget* pWidget) {
170
199
            pWidget, SLOT(update()));
171
200
}
172
201
 
173
 
bool WaveformWidgetFactory::setWaveformWidget(WWaveformViewer* viewer) {
174
 
    int index = -1;
175
 
    if (viewer->getWaveformWidget()) {
176
 
        //it already have a WaveformeWidget
177
 
        index = m_waveformWidgets.indexOf(viewer->getWaveformWidget());
178
 
        if (index == -1) {
179
 
            qDebug() << "WaveformWidgetFactory::setWaveformWidget - "\
180
 
                        "viewer already have a waveform widget but it's not found by the factory !";
181
 
        }
 
202
bool WaveformWidgetFactory::setWaveformWidget(WWaveformViewer* viewer, const QDomElement& node) {
 
203
    int index = findIndexOf(viewer);
 
204
    if (index != -1) {
 
205
        qDebug() << "WaveformWidgetFactory::setWaveformWidget - "\
 
206
                    "viewer already have a waveform widget but it's not found by the factory !";
182
207
        delete viewer->getWaveformWidget();
183
208
    }
184
209
 
186
211
    WaveformWidgetAbstract* waveformWidget = createWaveformWidget(m_type, viewer);
187
212
    waveformWidget->castToQWidget();
188
213
    viewer->setWaveformWidget(waveformWidget);
189
 
    viewer->setup();
190
 
 
191
 
    m_waveformWidgets.append(waveformWidget);
192
 
    index = m_waveformWidgets.size()-1;
 
214
    viewer->setup(node);
 
215
 
 
216
    // create new holder
 
217
    if (index == -1) {
 
218
        m_waveformWidgetHolders.push_back(WaveformWidgetHolder(waveformWidget, viewer, node));
 
219
        index = m_waveformWidgetHolders.size()-1;
 
220
    } else { //update holder
 
221
        m_waveformWidgetHolders[index] = WaveformWidgetHolder(waveformWidget, viewer, node);
 
222
    }
 
223
 
 
224
    viewer->setZoom(m_defaultZoom);
193
225
 
194
226
    qDebug() << "WaveformWidgetFactory::setWaveformWidget - waveform widget added in factory index" << index;
195
227
 
197
229
}
198
230
 
199
231
void WaveformWidgetFactory::setFrameRate(int frameRate) {
200
 
    m_frameRate = math_min(60, math_max( 10, frameRate));
201
 
    if( m_config)
 
232
    m_frameRate = math_min(60, math_max(10, frameRate));
 
233
    if (m_config) {
202
234
        m_config->set(ConfigKey("[Waveform]","FrameRate"), ConfigValue(m_frameRate));
203
 
}
204
 
 
205
 
bool WaveformWidgetFactory::setWidgetType(int handleIndex) {
 
235
    }
 
236
}
 
237
 
 
238
bool WaveformWidgetFactory::setWidgetType(WaveformWidgetType::Type type) {
 
239
    if (type == m_type)
 
240
        return true;
 
241
 
 
242
    // check if type is acceptable
 
243
    for (unsigned int i = 0; i < m_waveformWidgetHandles.size(); i++) {
 
244
        WaveformWidgetAbstractHandle& handle = m_waveformWidgetHandles[i];
 
245
        if (handle.m_type == type) {
 
246
            // type is acceptable
 
247
            m_type = type;
 
248
            if (m_config) {
 
249
                m_config->set(ConfigKey("[Waveform]","WaveformType"), ConfigValue((int)m_type));
 
250
            }
 
251
            return true;
 
252
        }
 
253
    }
 
254
 
 
255
    // fallback
 
256
    m_type = WaveformWidgetType::EmptyWaveform;
 
257
    if (m_config) {
 
258
        m_config->set(ConfigKey("[Waveform]","WaveformType"), ConfigValue((int)m_type));
 
259
    }
 
260
    return false;
 
261
}
 
262
 
 
263
bool WaveformWidgetFactory::setWidgetTypeFromHandle(int handleIndex) {
206
264
    if (handleIndex < 0 && handleIndex > m_waveformWidgetHandles.size()) {
207
 
        qDebug() << "WaveformWidgetFactory::setWidgetType - invalid handle";
 
265
        qDebug() << "WaveformWidgetFactory::setWidgetType - invalid handle --> use of 'EmptyWaveform'";
 
266
        // fallback empty type
 
267
        setWidgetType(WaveformWidgetType::EmptyWaveform);
208
268
        return false;
209
269
    }
210
270
 
211
271
    WaveformWidgetAbstractHandle& handle = m_waveformWidgetHandles[handleIndex];
212
272
    if (handle.m_type == m_type) {
213
273
        qDebug() << "WaveformWidgetFactory::setWidgetType - type already in use";
214
 
        return false;
215
 
    }
216
 
 
217
 
    //change the type
218
 
    m_type = handle.m_type;
219
 
 
220
 
    /*
221
 
      vRince
222
 
      I can't just recreate waveform widgets (even if its nicer !!)
223
 
      Waveform widget creation works but it the complete setup (color etc ...) from the skin
224
 
      need to be re-run ! I tried to implement some int the skin loader be it became "spagetti"
225
 
      code :( ... So for the moment a mixxx restart will do ...
226
 
 
227
 
    //retrieve existing viewers
228
 
    QVector<WWaveformViewer*> viewers;
229
 
    for( int i = 0; i < m_waveformWidgets.size(); i++)
230
 
    {
231
 
        if( !m_waveformWidgets[i]->isValid())
232
 
        {
233
 
            //should never happend the casting must be check into the setWaveformWidget
234
 
            //method to ensre we never store mis-formed widget in the factory !!
235
 
            continue;
236
 
        }
237
 
 
238
 
        //it should be safe since only the factory can build WaveformWidget and we know
239
 
        //we give them a WWaveformViewer as a parent
240
 
        WWaveformViewer* viewer = static_cast<WWaveformViewer*>(m_waveformWidgets[i]->getWidget()->parent());
241
 
        viewers.push_back(viewer);
242
 
    }
243
 
 
244
 
    //re-create them with the current type
245
 
    for( int i = 0; i < viewers.size(); i++)
246
 
        setWaveformWidget(viewers[i]);
247
 
    */
248
 
 
 
274
        return true;
 
275
    }
 
276
 
 
277
    // change the type
 
278
    setWidgetType(handle.m_type);
 
279
 
 
280
    m_skipRender = true;
 
281
    qDebug() << "recreate start";
 
282
 
 
283
    //re-create/setup all waveform widgets
 
284
    for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++) {
 
285
        WaveformWidgetHolder& holder = m_waveformWidgetHolders[i];
 
286
        WaveformWidgetAbstract* previousWidget = holder.m_waveformWidget;
 
287
        TrackPointer pTrack = previousWidget->getTrackInfo();
 
288
        previousWidget->hold();
 
289
        delete previousWidget;
 
290
        WWaveformViewer* viewer = holder.m_waveformViewer;
 
291
        WaveformWidgetAbstract* widget = createWaveformWidget(m_type, holder.m_waveformViewer);
 
292
        holder.m_waveformWidget = widget;
 
293
        widget->castToQWidget();
 
294
        widget->hold();
 
295
        viewer->setWaveformWidget(widget);
 
296
        viewer->setup(holder.m_visualNodeCache);
 
297
        // resize() doesn't seem to get called on the widget. I think Qt skips
 
298
        // it since the size didn't change.
 
299
        //viewer->resize(viewer->size());
 
300
        widget->resize(viewer->width(), viewer->height());
 
301
        widget->setTrack(pTrack);
 
302
    }
 
303
 
 
304
    m_skipRender = false;
 
305
    qDebug() << "recreate done";
249
306
    return true;
250
307
}
251
308
 
252
 
void WaveformWidgetFactory::setDefaultZoom(int zoom){
253
 
    m_defaultZoom = math_max(1,math_min(4,zoom));
254
 
    if( m_config)
 
309
void WaveformWidgetFactory::setDefaultZoom(int zoom) {
 
310
    m_defaultZoom = math_max(WaveformWidgetRenderer::s_waveformMinZoom,
 
311
                             math_min(zoom, WaveformWidgetRenderer::s_waveformMaxZoom));
 
312
    if (m_config) {
255
313
        m_config->set(ConfigKey("[Waveform]","DefaultZoom"), ConfigValue(m_defaultZoom));
 
314
    }
256
315
 
257
 
    for (int i = 0; i < m_waveformWidgets.size(); i++)
258
 
        m_waveformWidgets[i]->setZoom(m_defaultZoom);
 
316
    for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++) {
 
317
        m_waveformWidgetHolders[i].m_waveformViewer->setZoom(m_defaultZoom);
 
318
    }
259
319
}
260
320
 
261
321
void WaveformWidgetFactory::setZoomSync(bool sync) {
262
322
    m_zoomSync = sync;
263
 
    if( m_config)
 
323
    if (m_config) {
264
324
        m_config->set(ConfigKey("[Waveform]","ZoomSynchronization"), ConfigValue(m_zoomSync));
 
325
    }
265
326
 
266
 
    if( m_waveformWidgets.isEmpty())
 
327
    if (m_waveformWidgetHolders.size() == 0) {
267
328
        return;
268
 
 
269
 
    int refZoom = m_waveformWidgets[0]->getZoomFactor();
270
 
    for (int i = 1; i < m_waveformWidgets.size(); i++)
271
 
        m_waveformWidgets[i]->setZoom(refZoom);
272
 
}
273
 
 
274
 
void WaveformWidgetFactory::onZoomChange( WaveformWidgetAbstract* widget) {
275
 
    if( isZoomSync()) {
276
 
        int refZoom = widget->getZoomFactor();
277
 
        for (int i = 0; i < m_waveformWidgets.size(); i++)
278
 
            if( m_waveformWidgets[i] != widget)
279
 
                m_waveformWidgets[i]->setZoom(refZoom);
 
329
    }
 
330
 
 
331
    int refZoom = m_waveformWidgetHolders[0].m_waveformWidget->getZoomFactor();
 
332
    for (unsigned int i = 1; i < m_waveformWidgetHolders.size(); i++) {
 
333
        m_waveformWidgetHolders[i].m_waveformViewer->setZoom(refZoom);
 
334
    }
 
335
}
 
336
 
 
337
void WaveformWidgetFactory::setVisualGain(FilterIndex index, double gain) {
 
338
    m_visualGain[index] = gain;
 
339
    if (m_config)
 
340
        m_config->set(ConfigKey("[Waveform]","VisualGain_" + QString::number(index)), QString::number(m_visualGain[index]));
 
341
}
 
342
 
 
343
double WaveformWidgetFactory::getVisualGain(FilterIndex index) const {
 
344
    return m_visualGain[index];
 
345
}
 
346
 
 
347
void WaveformWidgetFactory::notifyZoomChange(WWaveformViewer* viewer) {
 
348
    if (isZoomSync()) {
 
349
        //qDebug() << "WaveformWidgetFactory::notifyZoomChange";
 
350
        int refZoom = viewer->getWaveformWidget()->getZoomFactor();
 
351
        for (int i = 0; i < m_waveformWidgetHolders.size(); i++) {
 
352
            if (m_waveformWidgetHolders[i].m_waveformViewer != viewer) {
 
353
                m_waveformWidgetHolders[i].m_waveformViewer->setZoom(refZoom);
 
354
            }
 
355
        }
280
356
    }
281
357
}
282
358
 
283
359
void WaveformWidgetFactory::refresh() {
284
 
    for (int i = 0; i < m_waveformWidgets.size(); i++)
285
 
        m_waveformWidgets[i]->preRender();
286
 
 
287
 
    for (int i = 0; i < m_waveformWidgets.size(); i++)
288
 
        m_waveformWidgets[i]->render();
 
360
    if (m_skipRender)
 
361
       return;
 
362
 
 
363
    for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++)
 
364
        m_waveformWidgetHolders[i].m_waveformWidget->preRender();
 
365
 
 
366
    for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++)
 
367
        m_waveformWidgetHolders[i].m_waveformWidget->render();
 
368
 
 
369
    for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++)
 
370
        m_waveformWidgetHolders[i].m_waveformWidget->postRender();
289
371
 
290
372
    // Notify all other waveform-like widgets (e.g. WSpinny's) that they should
291
373
    // update.
297
379
    m_actualFrameRate = 1000.0/(double)(m_lastFrameTime);
298
380
}
299
381
 
 
382
WaveformWidgetType::Type WaveformWidgetFactory::autoChooseWidgetType() const {
 
383
    //default selection
 
384
    if (m_openGLAvailable) {
 
385
        if (m_openGLShaderAvailable) {
 
386
            //TODO: (vrince) enable when ready
 
387
            //return = WaveformWidgetType::GLSLWaveform;
 
388
            return WaveformWidgetType::GLWaveform;
 
389
        } else {
 
390
            return WaveformWidgetType::GLWaveform;
 
391
        }
 
392
    }
 
393
    return WaveformWidgetType::SoftwareWaveform;
 
394
}
 
395
 
300
396
void WaveformWidgetFactory::evaluateWidgets() {
301
397
    m_waveformWidgetHandles.clear();
302
398
    for (int type = 0; type < WaveformWidgetType::Count_WaveformwidgetType; type++) {
313
409
        if (widget) {
314
410
            QString widgetName = widget->getWaveformWidgetName();
315
411
            if (widget->useOpenGLShaders()) {
316
 
                widgetName += " " + WaveformWidgetAbstract::s_openGlShaderFlag;
 
412
                widgetName += " " + tr("(GLSL)");
317
413
            } else if (widget->useOpenGl()) {
318
 
                widgetName += " " + WaveformWidgetAbstract::s_openGlFlag;
 
414
                widgetName += " " + tr("(GL)");
319
415
            }
320
416
 
321
417
            // add new handle for each available widget type
352
448
    return 0;
353
449
}
354
450
 
 
451
int WaveformWidgetFactory::findIndexOf(WWaveformViewer* viewer) const {
 
452
    for (int i = 0; i < m_waveformWidgetHolders.size(); i++)
 
453
        if (m_waveformWidgetHolders[i].m_waveformViewer == viewer)
 
454
            return i;
 
455
    return -1;
 
456
}