@@ -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,13 +49,18 @@ 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
6059std::string MacroConditionMidi::GetShortDesc () const
6160{
62- return _device.Name ();
61+ return _condition == MacroConditionMidi::Condition::MIDI_MESSAGE
62+ ? _device.Name ()
63+ : " " ;
6364}
6465
6566void MacroConditionMidi::SetDevice (const MidiDevice &dev)
@@ -68,9 +69,64 @@ void MacroConditionMidi::SetDevice(const MidiDevice &dev)
6869 _messageBuffer = dev.RegisterForMidiMessages ();
6970}
7071
72+ void MacroConditionMidi::SetCondition (Condition condition)
73+ {
74+ _condition = condition;
75+ if (_condition == Condition::MIDI_MESSAGE) {
76+ _messageBuffer = _device.RegisterForMidiMessages ();
77+ }
78+ SetupTempVars ();
79+ }
80+
81+ bool MacroConditionMidi::CheckMessage ()
82+ {
83+ if (!_messageBuffer) {
84+ return false ;
85+ }
86+
87+ const bool macroWasPausedSinceLastCheck =
88+ MacroWasPausedSince (GetMacro (), _lastCheck);
89+ _lastCheck = std::chrono::high_resolution_clock::now ();
90+ if (macroWasPausedSinceLastCheck) {
91+ _messageBuffer->Clear ();
92+ return false ;
93+ }
94+
95+ while (!_messageBuffer->Empty ()) {
96+ auto message = _messageBuffer->ConsumeMessage ();
97+ if (!message) {
98+ continue ;
99+ }
100+ if (message->Matches (_message)) {
101+ SetVariableValues (*message);
102+ return true ;
103+ }
104+ }
105+
106+ return false ;
107+ }
108+
109+ bool MacroConditionMidi::CheckConnectedDevcieNames ()
110+ {
111+ auto deviceNames = GetDeviceNames ();
112+ if (!_regex.Enabled ()) {
113+ return std::find (deviceNames.begin (), deviceNames.end (),
114+ std::string (_deviceName)) != deviceNames.end ();
115+ }
116+ for (const auto &deviceName : deviceNames) {
117+ if (_regex.Matches (deviceName, _deviceName)) {
118+ return true ;
119+ }
120+ }
121+ return false ;
122+ }
123+
71124void MacroConditionMidi::SetupTempVars ()
72125{
73126 MacroCondition::SetupTempVars ();
127+ if (_condition == Condition::MIDI_CONNECTED_DEVICE_NAMES) {
128+ return ;
129+ }
74130 AddTempvar (" type" ,
75131 obs_module_text (" AdvSceneSwitcher.tempVar.midi.type" ));
76132 AddTempvar (" channel" ,
@@ -98,16 +154,45 @@ void MacroConditionMidi::SetVariableValues(const MidiMessage &m)
98154 SetTempVarValue (" value2" , std::to_string (m.Value ()));
99155}
100156
157+ static void populateConditionSelection (QComboBox *list)
158+ {
159+ for (const auto &[_, name] : conditionTypes) {
160+ list->addItem (obs_module_text (name.c_str ()));
161+ }
162+ }
163+
101164MacroConditionMidiEdit::MacroConditionMidiEdit (
102165 QWidget *parent, std::shared_ptr<MacroConditionMidi> entryData)
103166 : QWidget(parent),
167+ _conditions (new QComboBox()),
104168 _devices(new MidiDeviceSelection(this , MidiDeviceType::INPUT)),
105169 _message(new MidiMessageSelection(this )),
106170 _resetMidiDevices(new QPushButton(
107171 obs_module_text (" AdvSceneSwitcher.midi.resetDevices" ))),
108172 _listen(new QPushButton(
109- obs_module_text (" AdvSceneSwitcher.midi.startListen" )))
173+ obs_module_text (" AdvSceneSwitcher.midi.startListen" ))),
174+ _deviceNames(new QComboBox()),
175+ _regex(new RegexConfigWidget()),
176+ _deviceListInfo(new QLabel()),
177+ _listenLayout(new QHBoxLayout()),
178+ _entryLayout(new QHBoxLayout())
110179{
180+ _deviceNames->addItems (GetDeviceNamesAsQStringList ());
181+ _deviceNames->setEditable (true );
182+
183+ QString path = GetThemeTypeName () == " Light"
184+ ? " :/res/images/help.svg"
185+ : " :/res/images/help_light.svg" ;
186+ QIcon icon (path);
187+ QPixmap pixmap = icon.pixmap (QSize (16 , 16 ));
188+ _deviceListInfo->setPixmap (pixmap);
189+ _deviceListInfo->setToolTip (obs_module_text (
190+ " AdvSceneSwitcher.condition.midi.condition.deviceName.info" ));
191+
192+ populateConditionSelection (_conditions);
193+
194+ QWidget::connect (_conditions, SIGNAL (currentIndexChanged (int )), this ,
195+ SLOT (ConditionChanged (int )));
111196 QWidget::connect (_devices,
112197 SIGNAL (DeviceSelectionChanged (const MidiDevice &)),
113198 this ,
@@ -121,19 +206,21 @@ MacroConditionMidiEdit::MacroConditionMidiEdit(
121206 SLOT (ToggleListen ()));
122207 QWidget::connect (&_listenTimer, SIGNAL (timeout ()), this ,
123208 SLOT (SetMessageSelectionToLastReceived ()));
209+ QWidget::connect (_deviceNames,
210+ SIGNAL (currentTextChanged (const QString &)), this ,
211+ SLOT (DeviceNameChanged (const QString &)));
212+ QWidget::connect (_regex,
213+ SIGNAL (RegexConfigChanged (const RegexConfig &)), this ,
214+ SLOT (RegexChanged (const RegexConfig &)));
124215
125- auto entryLayout = new QHBoxLayout;
126- PlaceWidgets (obs_module_text (" AdvSceneSwitcher.condition.midi.entry" ),
127- entryLayout, {{" {{device}}" , _devices}});
128- auto listenLayout = new QHBoxLayout;
129216 PlaceWidgets (
130217 obs_module_text (" AdvSceneSwitcher.condition.midi.entry.listen" ),
131- listenLayout , {{" {{listenButton}}" , _listen}});
218+ _listenLayout , {{" {{listenButton}}" , _listen}});
132219
133220 auto mainLayout = new QVBoxLayout;
134- mainLayout->addLayout (entryLayout );
221+ mainLayout->addLayout (_entryLayout );
135222 mainLayout->addWidget (_message);
136- mainLayout->addLayout (listenLayout );
223+ mainLayout->addLayout (_listenLayout );
137224 mainLayout->addWidget (_resetMidiDevices);
138225 setLayout (mainLayout);
139226
@@ -155,11 +242,14 @@ void MacroConditionMidiEdit::UpdateEntryData()
155242 return ;
156243 }
157244
245+ _conditions->setCurrentIndex (
246+ static_cast <int >(_entryData->GetCondition ()));
158247 _message->SetMessage (_entryData->_message );
159248 _devices->SetDevice (_entryData->GetDevice ());
160-
161- adjustSize ();
162- updateGeometry ();
249+ _deviceNames->setCurrentText (QString::fromStdString (
250+ _entryData->_deviceName .UnresolvedValue ()));
251+ _regex->SetRegexConfig (_entryData->_regex );
252+ SetWidgetVisibility ();
163253}
164254
165255void MacroConditionMidiEdit::DeviceSelectionChanged (const MidiDevice &device)
@@ -211,6 +301,46 @@ void MacroConditionMidiEdit::EnableListening(bool enable)
211301 }
212302}
213303
304+ void MacroConditionMidiEdit::SetWidgetVisibility ()
305+ {
306+ _entryLayout->removeWidget (_conditions);
307+ _entryLayout->removeWidget (_devices);
308+ _entryLayout->removeWidget (_deviceNames);
309+ _entryLayout->removeWidget (_regex);
310+
311+ ClearLayout (_entryLayout);
312+
313+ std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
314+ {" {{conditions}}" , _conditions},
315+ {" {{device}}" , _devices},
316+ {" {{deviceNames}}" , _deviceNames},
317+ {" {{regex}}" , _regex},
318+ {" {{deviceListInfo}}" , _deviceListInfo},
319+ };
320+
321+ const bool isMessageCheck = _entryData->GetCondition () ==
322+ MacroConditionMidi::Condition::MIDI_MESSAGE;
323+
324+ auto layoutString =
325+ isMessageCheck
326+ ? " AdvSceneSwitcher.condition.midi.entry.message"
327+ : " AdvSceneSwitcher.condition.midi.entry.deviceName" ;
328+
329+ PlaceWidgets (obs_module_text (layoutString), _entryLayout,
330+ widgetPlaceholders);
331+
332+ SetLayoutVisible (_listenLayout, isMessageCheck);
333+ _devices->setVisible (isMessageCheck);
334+ _message->setVisible (isMessageCheck);
335+ _resetMidiDevices->setVisible (isMessageCheck);
336+ _deviceNames->setVisible (!isMessageCheck);
337+ _regex->setVisible (!isMessageCheck);
338+ _deviceListInfo->setVisible (!isMessageCheck);
339+
340+ adjustSize ();
341+ updateGeometry ();
342+ }
343+
214344void MacroConditionMidiEdit::ToggleListen ()
215345{
216346 if (!_entryData) {
@@ -249,4 +379,41 @@ void MacroConditionMidiEdit::SetMessageSelectionToLastReceived()
249379 _entryData->_message = *message;
250380}
251381
382+ void MacroConditionMidiEdit::ConditionChanged (int value)
383+ {
384+ if (_loading || !_entryData) {
385+ return ;
386+ }
387+
388+ auto lock = LockContext ();
389+ _entryData->SetCondition (
390+ static_cast <MacroConditionMidi::Condition>(value));
391+ SetWidgetVisibility ();
392+ emit HeaderInfoChanged (
393+ QString::fromStdString (_entryData->GetShortDesc ()));
394+ }
395+
396+ void MacroConditionMidiEdit::DeviceNameChanged (const QString &deviceName)
397+ {
398+ if (_loading || !_entryData) {
399+ return ;
400+ }
401+
402+ auto lock = LockContext ();
403+ _entryData->_deviceName = deviceName.toStdString ();
404+ }
405+
406+ void MacroConditionMidiEdit::RegexChanged (const RegexConfig &conf)
407+ {
408+ if (_loading || !_entryData) {
409+ return ;
410+ }
411+
412+ auto lock = LockContext ();
413+ _entryData->_regex = conf;
414+
415+ adjustSize ();
416+ updateGeometry ();
417+ }
418+
252419} // namespace advss
0 commit comments