1 #pragma once
2
3 #include <QList>
4 #include <QMutex>
5
6 #include "control/controlproxy.h"
7 #include "engine/controls/enginecontrol.h"
8 #include "preferences/colorpalettesettings.h"
9 #include "preferences/usersettings.h"
10 #include "track/cue.h"
11 #include "track/track_decl.h"
12
13 #define NUM_HOT_CUES 37
14
15 class ControlObject;
16 class ControlPushButton;
17 class ControlIndicator;
18
19 enum class CueMode {
20 Mixxx,
21 Pioneer,
22 Denon,
23 Numark,
24 MixxxNoBlinking,
25 CueAndPlay
26 };
27
28 enum class SeekOnLoadMode {
29 MainCue = 0, // Use main cue point
30 Beginning = 1, // Use 0:00.000
31 FirstSound = 2, // Skip leading silence
32 IntroStart = 3, // Use intro start cue point
33 };
34
seekOnLoadModeFromDouble(double value)35 inline SeekOnLoadMode seekOnLoadModeFromDouble(double value) {
36 return static_cast<SeekOnLoadMode>(int(value));
37 }
38
39 class HotcueControl : public QObject {
40 Q_OBJECT
41 public:
42 HotcueControl(const QString& group, int hotcueIndex);
43 ~HotcueControl() override;
44
getHotcueIndex()45 int getHotcueIndex() const {
46 return m_hotcueIndex;
47 }
48
getCue()49 CuePointer getCue() const {
50 return m_pCue;
51 }
52 double getPosition() const;
53 void setCue(const CuePointer& pCue);
54 void resetCue();
55 void setPosition(double position);
56 void setColor(mixxx::RgbColor::optional_t newColor);
57 mixxx::RgbColor::optional_t getColor() const;
58
59 // Used for caching the preview state of this hotcue control.
isPreviewing()60 bool isPreviewing() const {
61 return m_bPreviewing;
62 }
setPreviewing(bool bPreviewing)63 void setPreviewing(bool bPreviewing) {
64 m_bPreviewing = bPreviewing;
65 }
getPreviewingPosition()66 double getPreviewingPosition() const {
67 return m_previewingPosition;
68 }
setPreviewingPosition(double position)69 void setPreviewingPosition(double position) {
70 m_previewingPosition = position;
71 }
72
73 private slots:
74 void slotHotcueSet(double v);
75 void slotHotcueGoto(double v);
76 void slotHotcueGotoAndPlay(double v);
77 void slotHotcueGotoAndStop(double v);
78 void slotHotcueActivate(double v);
79 void slotHotcueActivatePreview(double v);
80 void slotHotcueClear(double v);
81 void slotHotcuePositionChanged(double newPosition);
82 void slotHotcueColorChangeRequest(double newColor);
83 void slotHotcueColorChanged(double newColor);
84
85 signals:
86 void hotcueSet(HotcueControl* pHotcue, double v);
87 void hotcueGoto(HotcueControl* pHotcue, double v);
88 void hotcueGotoAndPlay(HotcueControl* pHotcue, double v);
89 void hotcueGotoAndStop(HotcueControl* pHotcue, double v);
90 void hotcueActivate(HotcueControl* pHotcue, double v);
91 void hotcueActivatePreview(HotcueControl* pHotcue, double v);
92 void hotcueClear(HotcueControl* pHotcue, double v);
93 void hotcuePositionChanged(HotcueControl* pHotcue, double newPosition);
94 void hotcueColorChanged(HotcueControl* pHotcue, double newColor);
95 void hotcuePlay(double v);
96
97 private:
98 ConfigKey keyForControl(const QString& name);
99
100 const QString m_group;
101 const int m_hotcueIndex;
102 CuePointer m_pCue;
103
104 // Hotcue state controls
105 std::unique_ptr<ControlObject> m_hotcuePosition;
106 std::unique_ptr<ControlObject> m_hotcueEnabled;
107 std::unique_ptr<ControlObject> m_hotcueColor;
108 // Hotcue button controls
109 std::unique_ptr<ControlPushButton> m_hotcueSet;
110 std::unique_ptr<ControlPushButton> m_hotcueGoto;
111 std::unique_ptr<ControlPushButton> m_hotcueGotoAndPlay;
112 std::unique_ptr<ControlPushButton> m_hotcueGotoAndStop;
113 std::unique_ptr<ControlPushButton> m_hotcueActivate;
114 std::unique_ptr<ControlPushButton> m_hotcueActivatePreview;
115 std::unique_ptr<ControlPushButton> m_hotcueClear;
116
117 bool m_bPreviewing;
118 double m_previewingPosition;
119 };
120
121 class CueControl : public EngineControl {
122 Q_OBJECT
123 public:
124 CueControl(const QString& group,
125 UserSettingsPointer pConfig);
126 ~CueControl() override;
127
128 void hintReader(HintVector* pHintList) override;
129 bool updateIndicatorsAndModifyPlay(bool newPlay, bool oldPlay, bool playPossible);
130 void updateIndicators();
131 bool isTrackAtIntroCue();
132 void resetIndicators();
133 bool isPlayingByPlayButton();
134 bool getPlayFlashingAtPause();
135 SeekOnLoadMode getSeekOnLoadPreference();
136 void trackLoaded(TrackPointer pNewTrack) override;
137 void trackBeatsUpdated(mixxx::BeatsPointer pBeats) override;
138
139 private slots:
140 void quantizeChanged(double v);
141
142 void cueUpdated();
143 void trackAnalyzed();
144 void trackCuesUpdated();
145 void hotcueSet(HotcueControl* pControl, double v);
146 void hotcueGoto(HotcueControl* pControl, double v);
147 void hotcueGotoAndPlay(HotcueControl* pControl, double v);
148 void hotcueGotoAndStop(HotcueControl* pControl, double v);
149 void hotcueActivate(HotcueControl* pControl, double v);
150 void hotcueActivatePreview(HotcueControl* pControl, double v);
151 void hotcueClear(HotcueControl* pControl, double v);
152 void hotcuePositionChanged(HotcueControl* pControl, double newPosition);
153
154 void hotcueFocusColorNext(double v);
155 void hotcueFocusColorPrev(double v);
156
157 void cueSet(double v);
158 void cueClear(double v);
159 void cueGoto(double v);
160 void cueGotoAndPlay(double v);
161 void cueGotoAndStop(double v);
162 void cuePreview(double v);
163 void cueCDJ(double v);
164 void cueDenon(double v);
165 void cuePlay(double v);
166 void cueDefault(double v);
167 void pause(double v);
168 void playStutter(double v);
169
170 void introStartSet(double v);
171 void introStartClear(double v);
172 void introStartActivate(double v);
173 void introEndSet(double v);
174 void introEndClear(double v);
175 void introEndActivate(double v);
176 void outroStartSet(double v);
177 void outroStartClear(double v);
178 void outroStartActivate(double v);
179 void outroEndSet(double v);
180 void outroEndClear(double v);
181 void outroEndActivate(double v);
182
183 private:
184 enum class TrackAt {
185 Cue,
186 End,
187 ElseWhere
188 };
189
190 // These methods are not thread safe, only call them when the lock is held.
191 void createControls();
192 void attachCue(const CuePointer& pCue, HotcueControl* pControl);
193 void detachCue(HotcueControl* pControl);
194 void loadCuesFromTrack();
195 double quantizeCuePoint(double position);
196 double getQuantizedCurrentPosition();
197 TrackAt getTrackAt() const;
198 void seekOnLoad(double seekOnLoadPosition);
199 void setHotcueFocusIndex(int hotcueIndex);
200 int getHotcueFocusIndex() const;
201
202 UserSettingsPointer m_pConfig;
203 ColorPaletteSettings m_colorPaletteSettings;
204 bool m_bPreviewing;
205 ControlObject* m_pPlay;
206 ControlObject* m_pStopButton;
207 int m_iCurrentlyPreviewingHotcues;
208 ControlObject* m_pQuantizeEnabled;
209 ControlObject* m_pClosestBeat;
210 bool m_bypassCueSetByPlay;
211 ControlValueAtomic<double> m_usedSeekOnLoadPosition;
212
213 const int m_iNumHotCues;
214 QList<HotcueControl*> m_hotcueControls;
215
216 ControlObject* m_pTrackSamples;
217 ControlObject* m_pCuePoint;
218 ControlObject* m_pCueMode;
219 ControlPushButton* m_pCueSet;
220 ControlPushButton* m_pCueClear;
221 ControlPushButton* m_pCueCDJ;
222 ControlPushButton* m_pCueDefault;
223 ControlPushButton* m_pPlayStutter;
224 ControlIndicator* m_pCueIndicator;
225 ControlIndicator* m_pPlayIndicator;
226 ControlObject* m_pPlayLatched;
227 ControlPushButton* m_pCueGoto;
228 ControlPushButton* m_pCueGotoAndPlay;
229 ControlPushButton* m_pCuePlay;
230 ControlPushButton* m_pCueGotoAndStop;
231 ControlPushButton* m_pCuePreview;
232
233 ControlObject* m_pIntroStartPosition;
234 ControlObject* m_pIntroStartEnabled;
235 ControlPushButton* m_pIntroStartSet;
236 ControlPushButton* m_pIntroStartClear;
237 ControlPushButton* m_pIntroStartActivate;
238
239 ControlObject* m_pIntroEndPosition;
240 ControlObject* m_pIntroEndEnabled;
241 ControlPushButton* m_pIntroEndSet;
242 ControlPushButton* m_pIntroEndClear;
243 ControlPushButton* m_pIntroEndActivate;
244
245 ControlObject* m_pOutroStartPosition;
246 ControlObject* m_pOutroStartEnabled;
247 ControlPushButton* m_pOutroStartSet;
248 ControlPushButton* m_pOutroStartClear;
249 ControlPushButton* m_pOutroStartActivate;
250
251 ControlObject* m_pOutroEndPosition;
252 ControlObject* m_pOutroEndEnabled;
253 ControlPushButton* m_pOutroEndSet;
254 ControlPushButton* m_pOutroEndClear;
255 ControlPushButton* m_pOutroEndActivate;
256
257 ControlProxy* m_pVinylControlEnabled;
258 ControlProxy* m_pVinylControlMode;
259
260 ControlObject* m_pHotcueFocus;
261 ControlObject* m_pHotcueFocusColorNext;
262 ControlObject* m_pHotcueFocusColorPrev;
263
264 TrackPointer m_pLoadedTrack; // is written from an engine worker thread
265
266 // Tells us which controls map to which hotcue
267 QMap<QObject*, int> m_controlMap;
268
269 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
270 QRecursiveMutex m_mutex;
271 #else
272 QMutex m_mutex;
273 #endif
274 };
275