summaryrefslogtreecommitdiffstats
path: root/src/waveform/waveformwidgetfactory.h
blob: 6fc991b7173a5c63294950c507564a752580250f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#pragma once

#include <QObject>
#include <QVector>
#include <vector>

#include "preferences/usersettings.h"
#include "skin/skincontext.h"
#include "util/performancetimer.h"
#include "util/singleton.h"
#include "waveform/waveform.h"
#include "waveform/widgets/waveformwidgettype.h"

class WWaveformViewer;
class WaveformWidgetAbstract;
class VSyncThread;
class GuiTick;
class VisualsManager;

class WaveformWidgetAbstractHandle {
  public:
    WaveformWidgetAbstractHandle();

    WaveformWidgetType::Type getType() const { return m_type;}
    QString getDisplayName() const { return m_displayString;}

  private:
    WaveformWidgetType::Type m_type;
    QString m_displayString;

    friend class WaveformWidgetFactory;
};

class WaveformWidgetHolder {
  public:
    WaveformWidgetHolder();
    WaveformWidgetHolder(WaveformWidgetHolder&&) = default;
    WaveformWidgetHolder& operator=(WaveformWidgetHolder&&) = default;
  private:
    WaveformWidgetHolder(
            WaveformWidgetAbstract* waveformWidget,
            WWaveformViewer* waveformViewer,
            const QDomNode& skinNode,
            const SkinContext& parentContext);

    WaveformWidgetAbstract* m_waveformWidget;
    WWaveformViewer* m_waveformViewer;
    QDomNode m_skinNodeCache;
    SkinContext m_skinContextCache;

    friend class WaveformWidgetFactory;
};

//########################################

class WaveformWidgetFactory : public QObject, public Singleton<WaveformWidgetFactory> {
    Q_OBJECT
  public:
    //TODO merge this enum with the waveform analyzer one
    enum FilterIndex { All = 0, Low = 1, Mid = 2, High = 3, FilterCount = 4};

    bool setConfig(UserSettingsPointer config);

    /// Creates the waveform widget using the type set with setWidgetType
    /// and binds it to the viewer.
    /// Deletes older widget and resets positions to config defaults.
    bool setWaveformWidget(
            WWaveformViewer* viewer,
            const QDomElement &node,
            const SkinContext& parentContext);

    void setFrameRate(int frameRate);
    int getFrameRate() const { return m_frameRate;}
//    bool getVSync() const { return m_vSyncType;}
    void setEndOfTrackWarningTime(int endTime);
    int getEndOfTrackWarningTime() const { return m_endOfTrackWarningTime;}

    bool isOpenGlAvailable() const { return m_openGlAvailable;}
    bool isOpenGlesAvailable() const { return m_openGlesAvailable;}
    QString getOpenGLVersion() const { return m_openGLVersion;}

    bool isOpenGlShaderAvailable() const { return m_openGLShaderAvailable;}

    /// Sets the widget type and saves it to configuration.
    /// Returns false and sets EmtpyWaveform if type is invalid
    bool setWidgetType(WaveformWidgetType::Type type);
    /// Changes the widget type to that loaded from config and recreates them.
    /// Used as a workaround on Windows due to a problem with GL and QT 5.14.2
    bool setWidgetTypeFromConfig();
    /// Changes the widget type and recreates them. Used from the preferences
    /// dialog.
    bool setWidgetTypeFromHandle(int handleIndex, bool force = false);
    WaveformWidgetType::Type getType() const { return m_type;}

  protected:
    bool setWidgetType(
            WaveformWidgetType::Type type,
            WaveformWidgetType::Type* pCurrentType);

  public:
    void setDefaultZoom(double zoom);
    double getDefaultZoom() const { return m_defaultZoom;}

    void setZoomSync(bool sync);
    int isZoomSync() const { return m_zoomSync;}

    void setDisplayBeatGridAlpha(int alpha);
    int getBeatGridAlpha() const { return m_beatGridAlpha; }

    void setVisualGain(FilterIndex index, double gain);
    double getVisualGain(FilterIndex index) const;

    void setOverviewNormalized(bool normalize);
    int isOverviewNormalized() const { return m_overviewNormalized;}

    const QVector<WaveformWidgetAbstractHandle> getAvailableTypes() const { return m_waveformWidgetHandles;}
    void getAvailableVSyncTypes(QList<QPair<int, QString > >* list);
    void destroyWidgets();

    void addTimerListener(QWidget* pWidget);

    void startVSync(GuiTick* pGuiTick, VisualsManager* pVisualsManager);
    void setVSyncType(int vsType);
    int getVSyncType();

    void setPlayMarkerPosition(double position);
    double getPlayMarkerPosition() const { return m_playMarkerPosition; }

    void notifyZoomChange(WWaveformViewer *viewer);

    WaveformWidgetType::Type autoChooseWidgetType() const;

  signals:
    void waveformUpdateTick();
    void waveformMeasured(float frameRate, int droppedFrames);
    void renderSpinnies(VSyncThread*);
    void swapSpinnies();

  public slots:
    void slotSkinLoaded();

  protected:
    WaveformWidgetFactory();
    virtual ~WaveformWidgetFactory();

    friend class Singleton<WaveformWidgetFactory>;

  private slots:
    void render();
    void swap();

  private:
    void evaluateWidgets();
    WaveformWidgetAbstract* createWaveformWidget(WaveformWidgetType::Type type, WWaveformViewer* viewer);
    int findIndexOf(WWaveformViewer* viewer) const;

    WaveformWidgetType::Type findTypeFromHandleIndex(int index);
    int findHandleIndexFromType(WaveformWidgetType::Type type);

    //All type of available widgets

    QVector<WaveformWidgetAbstractHandle> m_waveformWidgetHandles;

    //Currently in use widgets/visual/node
    std::vector<WaveformWidgetHolder> m_waveformWidgetHolders;

    WaveformWidgetType::Type m_type;
    WaveformWidgetType::Type m_configType;

    UserSettingsPointer m_config;

    bool m_skipRender;
    int m_frameRate;
    int m_endOfTrackWarningTime;
    double m_defaultZoom;
    bool m_zoomSync;
    double m_visualGain[FilterCount];
    bool m_overviewNormalized;

    bool m_openGlAvailable;
    bool m_openGlesAvailable;
    QString m_openGLVersion;
    bool m_openGLShaderAvailable;
    int m_beatGridAlpha;

    VSyncThread* m_vsyncThread;
    GuiTick* m_pGuiTick;  // not owned
    VisualsManager* m_pVisualsManager;  // not owned

    //Debug
    PerformanceTimer m_time;
    float m_frameCnt;
    double m_actualFrameRate;
    int m_vSyncType;
    double m_playMarkerPosition;
};