@@ -12,39 +12,35 @@ bool MacroConditionMidi::_registered = MacroConditionFactory::Register(
1212 {MacroConditionMidi::Create, MacroConditionMidiEdit::Create,
1313 " AdvSceneSwitcher.condition.midi" });
1414
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+
1523bool MacroConditionMidi::CheckCondition ()
1624{
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 ;
2732 }
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-
4033 return false ;
4134}
4235
4336bool MacroConditionMidi::Save (obs_data_t *obj) const
4437{
4538 MacroCondition::Save (obj);
39+ obs_data_set_int (obj, " condition" , static_cast <int >(_condition));
4640 _message.Save (obj);
4741 _device.Save (obj);
42+ _deviceName.Save (obj, " deviceName" );
43+ _regex.Save (obj);
4844 return true ;
4945}
5046
@@ -53,7 +49,10 @@ bool MacroConditionMidi::Load(obs_data_t *obj)
5349 MacroCondition::Load (obj);
5450 _message.Load (obj);
5551 _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" )));
5756 return true ;
5857}
5958
@@ -68,9 +67,64 @@ void MacroConditionMidi::SetDevice(const MidiDevice &dev)
6867 _messageBuffer = dev.RegisterForMidiMessages ();
6968}
7069
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+
71122void MacroConditionMidi::SetupTempVars ()
72123{
73124 MacroCondition::SetupTempVars ();
125+ if (_condition == Condition::MIDI_CONNECTED_DEVICE_NAMES) {
126+ return ;
127+ }
74128 AddTempvar (" type" ,
75129 obs_module_text (" AdvSceneSwitcher.tempVar.midi.type" ));
76130 AddTempvar (" channel" ,
@@ -98,16 +152,35 @@ void MacroConditionMidi::SetVariableValues(const MidiMessage &m)
98152 SetTempVarValue (" value2" , std::to_string (m.Value ()));
99153}
100154
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+
101162MacroConditionMidiEdit::MacroConditionMidiEdit (
102163 QWidget *parent, std::shared_ptr<MacroConditionMidi> entryData)
103164 : QWidget(parent),
165+ _conditions (new QComboBox()),
104166 _devices(new MidiDeviceSelection(this , MidiDeviceType::INPUT)),
105167 _message(new MidiMessageSelection(this )),
106168 _resetMidiDevices(new QPushButton(
107169 obs_module_text (" AdvSceneSwitcher.midi.resetDevices" ))),
108170 _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())
110176{
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 )));
111184 QWidget::connect (_devices,
112185 SIGNAL (DeviceSelectionChanged (const MidiDevice &)),
113186 this ,
@@ -121,19 +194,17 @@ MacroConditionMidiEdit::MacroConditionMidiEdit(
121194 SLOT (ToggleListen ()));
122195 QWidget::connect (&_listenTimer, SIGNAL (timeout ()), this ,
123196 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 &)));
132203
133204 auto mainLayout = new QVBoxLayout;
134- mainLayout->addLayout (entryLayout );
205+ mainLayout->addLayout (_entryLayout );
135206 mainLayout->addWidget (_message);
136- mainLayout->addLayout (listenLayout );
207+ mainLayout->addLayout (_listenLayout );
137208 mainLayout->addWidget (_resetMidiDevices);
138209 setLayout (mainLayout);
139210
@@ -155,11 +226,14 @@ void MacroConditionMidiEdit::UpdateEntryData()
155226 return ;
156227 }
157228
229+ _conditions->setCurrentIndex (
230+ static_cast <int >(_entryData->GetCondition ()));
158231 _message->SetMessage (_entryData->_message );
159232 _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 ();
163237}
164238
165239void MacroConditionMidiEdit::DeviceSelectionChanged (const MidiDevice &device)
@@ -211,6 +285,44 @@ void MacroConditionMidiEdit::EnableListening(bool enable)
211285 }
212286}
213287
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+
214326void MacroConditionMidiEdit::ToggleListen ()
215327{
216328 if (!_entryData) {
@@ -249,4 +361,39 @@ void MacroConditionMidiEdit::SetMessageSelectionToLastReceived()
249361 _entryData->_message = *message;
250362}
251363
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+
252399} // namespace advss
0 commit comments