@@ -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 ;
27- }
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- }
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 ;
3832 }
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,45 @@ 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+ _deviceListInfo(new QLabel()),
175+ _listenLayout(new QHBoxLayout()),
176+ _entryLayout(new QHBoxLayout())
110177{
178+ _deviceNames->addItems (GetDeviceNamesAsQStringList ());
179+ _deviceNames->setEditable (true );
180+
181+ QString path = GetThemeTypeName () == " Light"
182+ ? " :/res/images/help.svg"
183+ : " :/res/images/help_light.svg" ;
184+ QIcon icon (path);
185+ QPixmap pixmap = icon.pixmap (QSize (16 , 16 ));
186+ _deviceListInfo->setPixmap (pixmap);
187+ _deviceListInfo->setToolTip (obs_module_text (
188+ " AdvSceneSwitcher.condition.midi.condition.deviceName.info" ));
189+
190+ populateConditionSelection (_conditions);
191+
192+ QWidget::connect (_conditions, SIGNAL (currentIndexChanged (int )), this ,
193+ SLOT (ConditionChanged (int )));
111194 QWidget::connect (_devices,
112195 SIGNAL (DeviceSelectionChanged (const MidiDevice &)),
113196 this ,
@@ -121,19 +204,21 @@ MacroConditionMidiEdit::MacroConditionMidiEdit(
121204 SLOT (ToggleListen ()));
122205 QWidget::connect (&_listenTimer, SIGNAL (timeout ()), this ,
123206 SLOT (SetMessageSelectionToLastReceived ()));
207+ QWidget::connect (_deviceNames,
208+ SIGNAL (currentTextChanged (const QString &)), this ,
209+ SLOT (DeviceNameChanged (const QString &)));
210+ QWidget::connect (_regex,
211+ SIGNAL (RegexConfigChanged (const RegexConfig &)), this ,
212+ SLOT (RegexChanged (const RegexConfig &)));
124213
125- auto entryLayout = new QHBoxLayout;
126- PlaceWidgets (obs_module_text (" AdvSceneSwitcher.condition.midi.entry" ),
127- entryLayout, {{" {{device}}" , _devices}});
128- auto listenLayout = new QHBoxLayout;
129214 PlaceWidgets (
130215 obs_module_text (" AdvSceneSwitcher.condition.midi.entry.listen" ),
131- listenLayout , {{" {{listenButton}}" , _listen}});
216+ _listenLayout , {{" {{listenButton}}" , _listen}});
132217
133218 auto mainLayout = new QVBoxLayout;
134- mainLayout->addLayout (entryLayout );
219+ mainLayout->addLayout (_entryLayout );
135220 mainLayout->addWidget (_message);
136- mainLayout->addLayout (listenLayout );
221+ mainLayout->addLayout (_listenLayout );
137222 mainLayout->addWidget (_resetMidiDevices);
138223 setLayout (mainLayout);
139224
@@ -155,11 +240,14 @@ void MacroConditionMidiEdit::UpdateEntryData()
155240 return ;
156241 }
157242
243+ _conditions->setCurrentIndex (
244+ static_cast <int >(_entryData->GetCondition ()));
158245 _message->SetMessage (_entryData->_message );
159246 _devices->SetDevice (_entryData->GetDevice ());
160-
161- adjustSize ();
162- updateGeometry ();
247+ _deviceNames->setCurrentText (QString::fromStdString (
248+ _entryData->_deviceName .UnresolvedValue ()));
249+ _regex->SetRegexConfig (_entryData->_regex );
250+ SetWidgetVisibility ();
163251}
164252
165253void MacroConditionMidiEdit::DeviceSelectionChanged (const MidiDevice &device)
@@ -211,6 +299,46 @@ void MacroConditionMidiEdit::EnableListening(bool enable)
211299 }
212300}
213301
302+ void MacroConditionMidiEdit::SetWidgetVisibility ()
303+ {
304+ _entryLayout->removeWidget (_conditions);
305+ _entryLayout->removeWidget (_devices);
306+ _entryLayout->removeWidget (_deviceNames);
307+ _entryLayout->removeWidget (_regex);
308+
309+ ClearLayout (_entryLayout);
310+
311+ std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
312+ {" {{conditions}}" , _conditions},
313+ {" {{device}}" , _devices},
314+ {" {{deviceNames}}" , _deviceNames},
315+ {" {{regex}}" , _regex},
316+ {" {{deviceListInfo}}" , _deviceListInfo},
317+ };
318+
319+ const bool isMessageCheck = _entryData->GetCondition () ==
320+ MacroConditionMidi::Condition::MIDI_MESSAGE ;
321+
322+ auto layoutString =
323+ isMessageCheck
324+ ? " AdvSceneSwitcher.condition.midi.entry.message"
325+ : " AdvSceneSwitcher.condition.midi.entry.deviceName" ;
326+
327+ PlaceWidgets (obs_module_text (layoutString), _entryLayout,
328+ widgetPlaceholders);
329+
330+ SetLayoutVisible (_listenLayout, isMessageCheck);
331+ _devices->setVisible (isMessageCheck);
332+ _message->setVisible (isMessageCheck);
333+ _resetMidiDevices->setVisible (isMessageCheck);
334+ _deviceNames->setVisible (!isMessageCheck);
335+ _regex->setVisible (!isMessageCheck);
336+ _deviceListInfo->setVisible (!isMessageCheck);
337+
338+ adjustSize ();
339+ updateGeometry ();
340+ }
341+
214342void MacroConditionMidiEdit::ToggleListen ()
215343{
216344 if (!_entryData) {
@@ -249,4 +377,39 @@ void MacroConditionMidiEdit::SetMessageSelectionToLastReceived()
249377 _entryData->_message = *message;
250378}
251379
380+ void MacroConditionMidiEdit::ConditionChanged (int value)
381+ {
382+ if (_loading || !_entryData) {
383+ return ;
384+ }
385+
386+ auto lock = LockContext ();
387+ _entryData->SetCondition (
388+ static_cast <MacroConditionMidi::Condition>(value));
389+ SetWidgetVisibility ();
390+ }
391+
392+ void MacroConditionMidiEdit::DeviceNameChanged (const QString &deviceName)
393+ {
394+ if (_loading || !_entryData) {
395+ return ;
396+ }
397+
398+ auto lock = LockContext ();
399+ _entryData->_deviceName = deviceName.toStdString ();
400+ }
401+
402+ void MacroConditionMidiEdit::RegexChanged (const RegexConfig &conf)
403+ {
404+ if (_loading || !_entryData) {
405+ return ;
406+ }
407+
408+ auto lock = LockContext ();
409+ _entryData->_regex = conf;
410+
411+ adjustSize ();
412+ updateGeometry ();
413+ }
414+
252415} // namespace advss
0 commit comments