@@ -12,39 +12,35 @@ bool MacroConditionMidi::_registered = MacroConditionFactory::Register(
12
12
{MacroConditionMidi::Create, MacroConditionMidiEdit::Create,
13
13
" AdvSceneSwitcher.condition.midi" });
14
14
15
+ static const std::map<MacroConditionMidi::Condition, std::string>
16
+ conditionTypes = {
17
+ {MacroConditionMidi::Condition::MIDI_MESSAGE,
18
+ " AdvSceneSwitcher.condition.midi.condition.message" },
19
+ {MacroConditionMidi::Condition::MIDI_CONNECTED_DEVICE_NAMES,
20
+ " AdvSceneSwitcher.condition.midi.condition.deviceName" },
21
+ };
22
+
15
23
bool MacroConditionMidi::CheckCondition ()
16
24
{
17
- if (!_messageBuffer) {
18
- return false ;
19
- }
20
-
21
- const bool macroWasPausedSinceLastCheck =
22
- MacroWasPausedSince (GetMacro (), _lastCheck);
23
- _lastCheck = std::chrono::high_resolution_clock::now ();
24
- if (macroWasPausedSinceLastCheck) {
25
- _messageBuffer->Clear ();
26
- return false ;
25
+ switch (_condition) {
26
+ case Condition::MIDI_MESSAGE:
27
+ return CheckMessage ();
28
+ case Condition::MIDI_CONNECTED_DEVICE_NAMES:
29
+ return CheckConnectedDevcieNames ();
30
+ default :
31
+ break ;
27
32
}
28
-
29
- while (!_messageBuffer->Empty ()) {
30
- auto message = _messageBuffer->ConsumeMessage ();
31
- if (!message) {
32
- continue ;
33
- }
34
- if (message->Matches (_message)) {
35
- SetVariableValues (*message);
36
- return true ;
37
- }
38
- }
39
-
40
33
return false ;
41
34
}
42
35
43
36
bool MacroConditionMidi::Save (obs_data_t *obj) const
44
37
{
45
38
MacroCondition::Save (obj);
39
+ obs_data_set_int (obj, " condition" , static_cast <int >(_condition));
46
40
_message.Save (obj);
47
41
_device.Save (obj);
42
+ _deviceName.Save (obj, " deviceName" );
43
+ _regex.Save (obj);
48
44
return true ;
49
45
}
50
46
@@ -53,7 +49,10 @@ bool MacroConditionMidi::Load(obs_data_t *obj)
53
49
MacroCondition::Load (obj);
54
50
_message.Load (obj);
55
51
_device.Load (obj);
56
- _messageBuffer = _device.RegisterForMidiMessages ();
52
+ _deviceName.Load (obj, " deviceName" );
53
+ _regex.Load (obj);
54
+ SetCondition (
55
+ static_cast <Condition>(obs_data_get_int (obj, " condition" )));
57
56
return true ;
58
57
}
59
58
@@ -68,9 +67,64 @@ void MacroConditionMidi::SetDevice(const MidiDevice &dev)
68
67
_messageBuffer = dev.RegisterForMidiMessages ();
69
68
}
70
69
70
+ void MacroConditionMidi::SetCondition (Condition condition)
71
+ {
72
+ _condition = condition;
73
+ if (_condition == Condition::MIDI_MESSAGE) {
74
+ _messageBuffer = _device.RegisterForMidiMessages ();
75
+ }
76
+ SetupTempVars ();
77
+ }
78
+
79
+ bool MacroConditionMidi::CheckMessage ()
80
+ {
81
+ if (!_messageBuffer) {
82
+ return false ;
83
+ }
84
+
85
+ const bool macroWasPausedSinceLastCheck =
86
+ MacroWasPausedSince (GetMacro (), _lastCheck);
87
+ _lastCheck = std::chrono::high_resolution_clock::now ();
88
+ if (macroWasPausedSinceLastCheck) {
89
+ _messageBuffer->Clear ();
90
+ return false ;
91
+ }
92
+
93
+ while (!_messageBuffer->Empty ()) {
94
+ auto message = _messageBuffer->ConsumeMessage ();
95
+ if (!message) {
96
+ continue ;
97
+ }
98
+ if (message->Matches (_message)) {
99
+ SetVariableValues (*message);
100
+ return true ;
101
+ }
102
+ }
103
+
104
+ return false ;
105
+ }
106
+
107
+ bool MacroConditionMidi::CheckConnectedDevcieNames ()
108
+ {
109
+ auto deviceNames = GetDeviceNames ();
110
+ if (!_regex.Enabled ()) {
111
+ return std::find (deviceNames.begin (), deviceNames.end (),
112
+ std::string (_deviceName)) != deviceNames.end ();
113
+ }
114
+ for (const auto &deviceName : deviceNames) {
115
+ if (_regex.Matches (deviceName, _deviceName)) {
116
+ return true ;
117
+ }
118
+ }
119
+ return false ;
120
+ }
121
+
71
122
void MacroConditionMidi::SetupTempVars ()
72
123
{
73
124
MacroCondition::SetupTempVars ();
125
+ if (_condition == Condition::MIDI_CONNECTED_DEVICE_NAMES) {
126
+ return ;
127
+ }
74
128
AddTempvar (" type" ,
75
129
obs_module_text (" AdvSceneSwitcher.tempVar.midi.type" ));
76
130
AddTempvar (" channel" ,
@@ -98,16 +152,35 @@ void MacroConditionMidi::SetVariableValues(const MidiMessage &m)
98
152
SetTempVarValue (" value2" , std::to_string (m.Value ()));
99
153
}
100
154
155
+ static void populateConditionSelection (QComboBox *list)
156
+ {
157
+ for (const auto &[_, name] : conditionTypes) {
158
+ list->addItem (obs_module_text (name.c_str ()));
159
+ }
160
+ }
161
+
101
162
MacroConditionMidiEdit::MacroConditionMidiEdit (
102
163
QWidget *parent, std::shared_ptr<MacroConditionMidi> entryData)
103
164
: QWidget(parent),
165
+ _conditions (new QComboBox()),
104
166
_devices(new MidiDeviceSelection(this , MidiDeviceType::INPUT)),
105
167
_message(new MidiMessageSelection(this )),
106
168
_resetMidiDevices(new QPushButton(
107
169
obs_module_text (" AdvSceneSwitcher.midi.resetDevices" ))),
108
170
_listen(new QPushButton(
109
- obs_module_text (" AdvSceneSwitcher.midi.startListen" )))
171
+ obs_module_text (" AdvSceneSwitcher.midi.startListen" ))),
172
+ _deviceNames(new QComboBox()),
173
+ _regex(new RegexConfigWidget()),
174
+ _listenLayout(new QHBoxLayout()),
175
+ _entryLayout(new QHBoxLayout())
110
176
{
177
+ _deviceNames->addItems (GetDeviceNamesAsQStringList ());
178
+ _deviceNames->setEditable (true );
179
+
180
+ populateConditionSelection (_conditions);
181
+
182
+ QWidget::connect (_conditions, SIGNAL (currentIndexChanged (int )), this ,
183
+ SLOT (ConditionChanged (int )));
111
184
QWidget::connect (_devices,
112
185
SIGNAL (DeviceSelectionChanged (const MidiDevice &)),
113
186
this ,
@@ -121,19 +194,17 @@ MacroConditionMidiEdit::MacroConditionMidiEdit(
121
194
SLOT (ToggleListen ()));
122
195
QWidget::connect (&_listenTimer, SIGNAL (timeout ()), this ,
123
196
SLOT (SetMessageSelectionToLastReceived ()));
124
-
125
- auto entryLayout = new QHBoxLayout;
126
- PlaceWidgets (obs_module_text (" AdvSceneSwitcher.condition.midi.entry" ),
127
- entryLayout, {{" {{device}}" , _devices}});
128
- auto listenLayout = new QHBoxLayout;
129
- PlaceWidgets (
130
- obs_module_text (" AdvSceneSwitcher.condition.midi.entry.listen" ),
131
- listenLayout, {{" {{listenButton}}" , _listen}});
197
+ QWidget::connect (_deviceNames,
198
+ SIGNAL (currentTextChanged (const QString &)), this ,
199
+ SLOT (DeviceNameChanged (const QString &)));
200
+ QWidget::connect (_regex,
201
+ SIGNAL (RegexConfigChanged (const RegexConfig &)), this ,
202
+ SLOT (RegexChanged (const RegexConfig &)));
132
203
133
204
auto mainLayout = new QVBoxLayout;
134
- mainLayout->addLayout (entryLayout );
205
+ mainLayout->addLayout (_entryLayout );
135
206
mainLayout->addWidget (_message);
136
- mainLayout->addLayout (listenLayout );
207
+ mainLayout->addLayout (_listenLayout );
137
208
mainLayout->addWidget (_resetMidiDevices);
138
209
setLayout (mainLayout);
139
210
@@ -155,11 +226,14 @@ void MacroConditionMidiEdit::UpdateEntryData()
155
226
return ;
156
227
}
157
228
229
+ _conditions->setCurrentIndex (
230
+ static_cast <int >(_entryData->GetCondition ()));
158
231
_message->SetMessage (_entryData->_message );
159
232
_devices->SetDevice (_entryData->GetDevice ());
160
-
161
- adjustSize ();
162
- updateGeometry ();
233
+ _deviceNames->setCurrentText (QString::fromStdString (
234
+ _entryData->_deviceName .UnresolvedValue ()));
235
+ _regex->SetRegexConfig (_entryData->_regex );
236
+ SetWidgetVisibility ();
163
237
}
164
238
165
239
void MacroConditionMidiEdit::DeviceSelectionChanged (const MidiDevice &device)
@@ -211,6 +285,44 @@ void MacroConditionMidiEdit::EnableListening(bool enable)
211
285
}
212
286
}
213
287
288
+ void MacroConditionMidiEdit::SetWidgetVisibility ()
289
+ {
290
+ _entryLayout->removeWidget (_conditions);
291
+ _entryLayout->removeWidget (_devices);
292
+ _entryLayout->removeWidget (_deviceNames);
293
+ _entryLayout->removeWidget (_regex);
294
+
295
+ ClearLayout (_entryLayout);
296
+
297
+ std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
298
+ {" {{conditions}}" , _conditions},
299
+ {" {{device}}" , _devices},
300
+ {" {{deviceNames}}" , _deviceNames},
301
+ {" {{regex}}" , _regex},
302
+ };
303
+
304
+ const bool isMessageCheck = _entryData->GetCondition () ==
305
+ MacroConditionMidi::Condition::MIDI_MESSAGE;
306
+
307
+ auto layoutString =
308
+ isMessageCheck
309
+ ? " AdvSceneSwitcher.condition.midi.entry.message"
310
+ : " AdvSceneSwitcher.condition.midi.entry.deviceName" ;
311
+
312
+ PlaceWidgets (obs_module_text (layoutString), _entryLayout,
313
+ widgetPlaceholders);
314
+
315
+ SetLayoutVisible (_listenLayout, isMessageCheck);
316
+ _devices->setVisible (isMessageCheck);
317
+ _message->setVisible (isMessageCheck);
318
+ _resetMidiDevices->setVisible (isMessageCheck);
319
+ _deviceNames->setVisible (!isMessageCheck);
320
+ _regex->setVisible (!isMessageCheck);
321
+
322
+ adjustSize ();
323
+ updateGeometry ();
324
+ }
325
+
214
326
void MacroConditionMidiEdit::ToggleListen ()
215
327
{
216
328
if (!_entryData) {
@@ -249,4 +361,39 @@ void MacroConditionMidiEdit::SetMessageSelectionToLastReceived()
249
361
_entryData->_message = *message;
250
362
}
251
363
364
+ void MacroConditionMidiEdit::ConditionChanged (int value)
365
+ {
366
+ if (_loading || !_entryData) {
367
+ return ;
368
+ }
369
+
370
+ auto lock = LockContext ();
371
+ _entryData->SetCondition (
372
+ static_cast <MacroConditionMidi::Condition>(value));
373
+ SetWidgetVisibility ();
374
+ }
375
+
376
+ void MacroConditionMidiEdit::DeviceNameChanged (const QString &deviceName)
377
+ {
378
+ if (_loading || !_entryData) {
379
+ return ;
380
+ }
381
+
382
+ auto lock = LockContext ();
383
+ _entryData->_deviceName = deviceName.toStdString ();
384
+ }
385
+
386
+ void MacroConditionMidiEdit::RegexChanged (const RegexConfig &conf)
387
+ {
388
+ if (_loading || !_entryData) {
389
+ return ;
390
+ }
391
+
392
+ auto lock = LockContext ();
393
+ _entryData->_regex = conf;
394
+
395
+ adjustSize ();
396
+ updateGeometry ();
397
+ }
398
+
252
399
} // namespace advss
0 commit comments