forked from mixxxdj/mixxx
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlegacycontrollermapping.h
More file actions
382 lines (324 loc) · 11.5 KB
/
Copy pathlegacycontrollermapping.h
File metadata and controls
382 lines (324 loc) · 11.5 KB
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
#pragma once
#include <util/assert.h>
#include <QDir>
#include <QFileInfo>
#include <QHash>
#include <QImage>
#include <QList>
#include <QString>
#include <bit>
#include <chrono>
#include <memory>
#ifdef MIXXX_USE_QML
#include <bit>
#endif
#include "controllers/legacycontrollersettings.h"
#include "controllers/legacycontrollersettingslayout.h"
#include "defs_urls.h"
#include "preferences/usersettings.h"
#include "qml/mixxxcontroller.h"
#include "util/assert.h"
/// This class represents a controller mapping, containing the data elements that
/// make it up.
class LegacyControllerMapping {
public:
LegacyControllerMapping()
: m_bDirty(false),
m_deviceDirection(DeviceDirection::Bidirectionnal) {
}
LegacyControllerMapping(const LegacyControllerMapping& other)
: m_productMatches(other.m_productMatches),
m_bDirty(other.m_bDirty),
m_deviceId(other.m_deviceId),
m_filePath(other.m_filePath),
m_name(other.m_name),
m_author(other.m_author),
m_description(other.m_description),
m_forumlink(other.m_forumlink),
m_manualPage(other.m_manualPage),
m_wikilink(other.m_wikilink),
m_schemaVersion(other.m_schemaVersion),
m_mixxxVersion(other.m_mixxxVersion),
m_settings(other.m_settings),
m_settingsLayout(other.m_settingsLayout.get() != nullptr
? other.m_settingsLayout->clone()
: nullptr),
#ifdef MIXXX_USE_QML
m_modules(other.m_modules),
m_screens(other.m_screens),
#endif
m_scripts(other.m_scripts),
m_deviceDirection(other.m_deviceDirection) {
}
virtual ~LegacyControllerMapping() = default;
virtual std::shared_ptr<LegacyControllerMapping> clone() const = 0;
struct ScriptFileInfo {
enum class Type {
Javascript,
#ifdef MIXXX_USE_QML
Qml,
#endif
};
QString name; // Name of the script file to add.
QString identifier; // The script's function prefix with Javascript OR
// the screen identifier this QML should be run for
// (or empty string).
QFileInfo file; // A FileInfo object pointing to the script file.
Type type; // A ScriptFileInfo::Type the specify script file type.
bool builtin; // If this is true, the script won't be written to the XML.
};
// TODO (xxx): this is a temporary solution to address devices that don't
// support and need bidirectional communication and lead to
// polling/performance issues. The proper solution would involve refactoring
// the bulk integration to perform a better endpoint capability discovery
// and let Mixxx decide communication direction depending of the hardware
// capabilities
enum class DeviceDirection : uint8_t {
Outgoing = 0x1,
Incoming = 0x2,
Bidirectionnal = 0x3
};
Q_DECLARE_FLAGS(DeviceDirections, DeviceDirection)
#ifdef MIXXX_USE_QML
struct QMLModuleInfo {
QMLModuleInfo(const QFileInfo& aDirinfo,
bool isBuiltin)
: dirinfo(aDirinfo),
builtin(isBuiltin) {
}
QFileInfo dirinfo;
bool builtin;
};
struct ScreenInfo {
// Defining a custom enum here as std::endian contains `native` which is
// confusing and will have unpredictable behaviour depending of the
// platform.
enum class ColorEndian {
Big = static_cast<int>(std::endian::big),
Little = static_cast<int>(std::endian::little),
};
QString identifier; // The screen identifier.
QSize size; // The size of the screen.
uint target_fps; // The maximum FPS to render.
uint msaa; // The MSAA value to use for render.
std::chrono::milliseconds
splash_off; // The rendering grace time given when the screen is
// requested to shutdown.
QImage::Format pixelFormat; // The pixel encoding format.
ColorEndian endian; // The pixel endian format.
bool reversedColor; // Whether or not the RGB is swapped BGR.
bool rawData; // Whether or not the screen is allowed to receive bare
// data, not transformed.
};
#endif
/// Adds a script file to the list of controller scripts for this mapping.
/// @param info The script info to add.
virtual void addScriptFile(ScriptFileInfo info) {
m_scripts.append(std::move(info));
setDirty(true);
}
/// Adds a setting option to the list of setting option for this mapping.
/// The option added must be a valid option.
/// @param option The option to add
/// @return whether or not the setting was added successfully.
bool addSetting(std::shared_ptr<AbstractLegacyControllerSetting> option) {
VERIFY_OR_DEBUG_ASSERT(option->valid()) {
return false;
}
for (const auto& setting : std::as_const(m_settings)) {
if (*setting == *option) {
qWarning() << "Mapping setting duplication detected for "
"setting with name"
<< option->variableName()
<< ". Keeping the first occurrence.";
return false;
}
}
m_settings.append(option);
return true;
}
/// @brief Set a setting layout as they should be perceived when edited in
/// the preference dialog.
/// @param layout The layout root element
void setSettingLayout(std::unique_ptr<LegacyControllerSettingsLayoutElement>&& layout) {
VERIFY_OR_DEBUG_ASSERT(layout.get()) {
return;
}
m_settingsLayout = std::move(layout);
}
const QList<ScriptFileInfo>& getScriptFiles() const {
return m_scripts;
}
const QList<std::shared_ptr<AbstractLegacyControllerSetting>>& getSettings() const {
return m_settings;
}
bool hasDirtySettings() const {
for (const auto& setting : m_settings) {
if (setting->isDirty()) {
return true;
}
}
return false;
}
LegacyControllerSettingsLayoutElement* getSettingsLayout() {
return m_settingsLayout.get();
}
void setDeviceDirection(DeviceDirections aDeviceDirection) {
m_deviceDirection = aDeviceDirection;
}
DeviceDirections getDeviceDirection() const {
return m_deviceDirection;
}
#ifdef MIXXX_USE_QML
/// Adds a custom QML module file to the list of controller modules for this mapping.
/// @param dirInfo A FileInfo of the directory or QML module
/// @param builtin If this is true, the script won't be written to the XML
virtual void addModule(const QFileInfo& dirInfo,
bool builtin = false) {
m_modules.append(QMLModuleInfo(
dirInfo,
builtin));
setDirty(true);
}
const QList<QMLModuleInfo>& getModules() const {
return m_modules;
}
/// @brief Adds a screen info where QML will be rendered.
/// @param identifier The screen identifier
/// @param size the size of the screen
/// @param targetFps the maximum FPS to render
/// @param msaa the MSAA value to use for render
/// @param splashoff the rendering grace time given when the screen is requested to shutdown
/// @param pixelFormat the pixel encoding format
/// @param endian the pixel endian format
/// @param reversedColor whether or not the RGB is swapped BGR
/// @param rawData whether or not the screen is allowed to reserve bare data, not transformed
virtual void addScreenInfo(ScreenInfo info) {
m_screens.append(std::move(info));
setDirty(true);
}
const QList<ScreenInfo>& getInfoScreens() const {
return m_screens;
}
#endif
void setDirty(bool bDirty) {
m_bDirty = bDirty;
}
bool isDirty() const {
return m_bDirty;
}
void setDeviceId(const QString& id) {
m_deviceId = id;
setDirty(true);
}
QString deviceId() const {
return m_deviceId;
}
void setFilePath(const QString& filePath) {
m_filePath = filePath;
setDirty(true);
}
QString filePath() const {
return m_filePath;
}
QDir dirPath() const {
return QFileInfo(filePath()).absoluteDir();
}
void setName(const QString& name) {
m_name = name;
setDirty(true);
}
QString name() const {
return m_name;
}
void setAuthor(const QString& author) {
m_author = author;
setDirty(true);
}
inline QString author() const {
return m_author;
}
inline void setDescription(const QString& description) {
m_description = description;
setDirty(true);
}
inline QString description() const {
return m_description;
}
inline void setForumLink(const QString& forumlink) {
m_forumlink = forumlink;
setDirty(true);
}
inline QString forumlink() const {
return m_forumlink;
}
void setManualPage(const QString& manualPage) {
m_manualPage = manualPage;
setDirty(true);
}
QString manualPage() const {
return m_manualPage;
}
QString manualLink() const {
QString page = manualPage();
if (page.isEmpty()) {
return {};
}
return MIXXX_MANUAL_CONTROLLERMANUAL_PREFIX + page + MIXXX_MANUAL_CONTROLLERMANUAL_SUFFIX;
}
inline void setWikiLink(const QString& wikilink) {
m_wikilink = wikilink;
setDirty(true);
}
inline QString wikilink() const {
return m_wikilink;
}
inline void setSchemaVersion(const QString& schemaVersion) {
m_schemaVersion = schemaVersion;
setDirty(true);
}
inline QString schemaVersion() const {
return m_schemaVersion;
}
inline void setMixxxVersion(const QString& mixxxVersion) {
m_mixxxVersion = mixxxVersion;
setDirty(true);
}
inline QString mixxxVersion() const {
return m_mixxxVersion;
}
inline void addProductMatch(const QHash<QString, QString>& match) {
m_productMatches.append(match);
setDirty(true);
}
virtual bool saveMapping(const QString& filename) const = 0;
virtual bool isMappable() const = 0;
void loadSettings(UserSettingsPointer pConfig,
const QString& controllerName) const;
void saveSettings(UserSettingsPointer pConfig,
const QString& controllerName) const;
void resetSettings();
// Optional list of controller device match details
QList<QHash<QString, QString>> m_productMatches;
private:
bool m_bDirty;
QString m_deviceId;
QString m_filePath;
QString m_name;
QString m_author;
QString m_description;
QString m_forumlink;
QString m_manualPage;
QString m_wikilink;
QString m_schemaVersion;
QString m_mixxxVersion;
QList<std::shared_ptr<AbstractLegacyControllerSetting>> m_settings;
std::unique_ptr<LegacyControllerSettingsLayoutElement> m_settingsLayout;
#ifdef MIXXX_USE_QML
QList<QMLModuleInfo> m_modules;
QList<ScreenInfo> m_screens;
QList<mixxx::qml::MixxxController> m_mixxxControllers;
#endif
QList<ScriptFileInfo> m_scripts;
DeviceDirections m_deviceDirection;
};