Compare commits

...

16 Commits

Author SHA1 Message Date
WarmUpTill
bf7fe71ae3 Fix system tray warning not being translated
Some checks failed
debian-build / build (push) Has been cancelled
Check locale / ubuntu64 (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2025-07-17 17:49:44 +02:00
炭酸コーラ
12a6b26d9a Updated Japanese translation to the latest version 2025-07-17 17:45:44 +02:00
WarmUpTill
373e74c080 Switch to different port for aquiring Twitch tokens
Some checks are pending
debian-build / build (push) Waiting to run
Push to master / Check Formatting 🔍 (push) Waiting to run
Push to master / Build Project 🧱 (push) Waiting to run
Push to master / Create Release 🛫 (push) Blocked by required conditions
2025-07-16 21:15:36 +02:00
WarmUpTill
f3e7eaf212 Rework to support frequently resizing widgets
Some checks failed
debian-build / build (push) Waiting to run
Push to master / Check Formatting 🔍 (push) Waiting to run
Push to master / Build Project 🧱 (push) Waiting to run
Push to master / Create Release 🛫 (push) Blocked by required conditions
Check locale / ubuntu64 (push) Has been cancelled
2025-07-13 18:17:46 +02:00
WarmUpTill
b036736547 Refactor MacroSegmentList rework to support nested macros 2025-07-13 18:17:46 +02:00
WarmUpTill
817de13e9d Add nested macro support 2025-07-13 18:17:46 +02:00
WarmUpTill
0b774c171d Cleanup
* Use GetSettingsWindow() instead of window() to avoid connecting to the
  wrong widget
* Fix typos
2025-07-13 18:17:46 +02:00
WarmUpTill
be8f7bd70f Add ResizableWidget
When manual resizing is enabled, the vertical widget size can be changed
by dragging the widget in the lower right corner.
2025-07-13 18:17:46 +02:00
WarmUpTill
5f963b5b7d Refactor macro edit area into separate class
This will enable support for nested macros
2025-07-13 18:17:46 +02:00
WarmUpTill
c6155c9fea Add default settings support 2025-07-13 18:17:46 +02:00
WarmUpTill
be809dbfab Fix macro dock being being destroyed when opening macro settings
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2025-07-09 15:22:04 +02:00
WarmUpTill
7478c149b3 Add option to toggle mute state of audio source
Some checks failed
debian-build / build (push) Waiting to run
Push to master / Check Formatting 🔍 (push) Waiting to run
Push to master / Build Project 🧱 (push) Waiting to run
Push to master / Create Release 🛫 (push) Blocked by required conditions
Check locale / ubuntu64 (push) Has been cancelled
2025-07-08 17:51:21 +02:00
WarmUpTill
f4eaa9785d Fix crash on macro load 2025-07-08 17:49:33 +02:00
WarmUpTill
49c0de3f1b Add context menu option to expand / collapse all macro groups 2025-07-08 17:49:33 +02:00
WarmUpTill
101ef4e973 Fix crash when adding new macro to group 2025-07-08 17:49:33 +02:00
WarmUpTill
82568b23e8 Fix crash when initially setting up tab ordering
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
The tabOrder vector was initialized with the size of tabNames.
Then new tabs were registered with AddSetupTabCallback() causing
tabNames to grow but tabOrder to remain the same.

Usually this is not a problem as LoadTabOrder() will be called which
ensures that their sizes are in sync.

However, when using a fresh OBS install or one with a corrupted scene
configuration file, the on_save() callbacks are called before any
loading callbacks.
With the sizes of tabNames and tabOrder not being in sync this would
lead to a crash.

Fixed by adding a tabWidgetOrderValid() check within SaveTabOrder()
before iterating over both vectors.
The tabWidgetOrderValid() was expanded to check the sizes of both
vectors.
Additionally the tabOrder initialization was moved from global static
initialization to function local static initialization to ensure that
potential preceeding calls to AddSetupTabCallback() will be taken into
account when setting up the tabOrder vector.
2025-07-06 10:19:20 +02:00
69 changed files with 3865 additions and 2746 deletions

View File

@@ -123,6 +123,8 @@ target_sources(
lib/macro/macro-condition.hpp
lib/macro/macro-dock.cpp
lib/macro/macro-dock.hpp
lib/macro/macro-edit.cpp
lib/macro/macro-edit.hpp
lib/macro/macro-export-import-dialog.cpp
lib/macro/macro-export-import-dialog.hpp
lib/macro/macro-helpers.cpp
@@ -217,6 +219,8 @@ target_sources(
lib/utils/priority-helper.hpp
lib/utils/regex-config.cpp
lib/utils/regex-config.hpp
lib/utils/resizable-widget.cpp
lib/utils/resizable-widget.hpp
lib/utils/resizing-text-edit.cpp
lib/utils/resizing-text-edit.hpp
lib/utils/resource-table.cpp

View File

@@ -150,9 +150,9 @@ AdvSceneSwitcher.macroTab.title="Macro"
AdvSceneSwitcher.macroTab.macros="Macros"
AdvSceneSwitcher.macroTab.priorityWarning="Note: It is recommended to configure macros to be the highest priority functionality.\nThis setting can be changed on the General tab."
AdvSceneSwitcher.macroTab.help="Macros allow you to execute a string of actions depending on multiple conditions.\n\nClick on the highlighted plus symbol to add a new Macro."
AdvSceneSwitcher.macroTab.editConditionHelp="This section allows you to define Macro conditions.\n\nSelect an existing or add a new Macro on the left.\nThen click the plus button below to add a new condition."
AdvSceneSwitcher.macroTab.editActionHelp="This section allows you to define Macro actions.\n\nSelect an existing or add a new Macro on the left.\nThen click the plus button below to add a new action."
AdvSceneSwitcher.macroTab.editElseActionHelp="This section allows you to define Macro actions, which are executed if the conditions are *not* met.\n\nSelect an existing or add a new Macro on the left.\nThen click the plus button below to add a new action."
AdvSceneSwitcher.macroTab.editConditionHelp="This section allows you to define macro conditions.\n\nSelect an existing or add a new macro on the left.\nThen click the plus button below to add a new condition."
AdvSceneSwitcher.macroTab.editActionHelp="This section allows you to define macro actions.\nThe actions in this section will be performed when the conditions are met.\n\nSelect an existing or add a new macro on the left.\nThen click the plus button below to add a new action."
AdvSceneSwitcher.macroTab.editElseActionHelp="This section allows you to define macro actions.\nThe actions in this section will be performed when the conditions are *not* met.\n\nSelect an existing or add a new macro on the left.\nThen click the plus button below to add a new action."
AdvSceneSwitcher.macroTab.edit="Edit macro"
AdvSceneSwitcher.macroTab.edit.logic="Logic type:"
AdvSceneSwitcher.macroTab.edit.condition="Condition type:"
@@ -177,6 +177,8 @@ AdvSceneSwitcher.macroTab.contextMenuAdd="Add"
AdvSceneSwitcher.macroTab.copy="Duplicate Macro"
AdvSceneSwitcher.macroTab.group="Group Selected Macros"
AdvSceneSwitcher.macroTab.ungroup="Ungroup Selected Groups"
AdvSceneSwitcher.macroTab.expandAllGroups="Expand all Groups"
AdvSceneSwitcher.macroTab.collapseAllGroups="Collapse all Groups"
AdvSceneSwitcher.macroTab.rename="Rename"
AdvSceneSwitcher.macroTab.remove="Remove"
AdvSceneSwitcher.macroTab.export="Export"
@@ -516,6 +518,7 @@ AdvSceneSwitcher.condition.source.sizeCompare.equal="Equals"
AdvSceneSwitcher.condition.source.sizeCompare.more="Bigger than"
AdvSceneSwitcher.condition.source.refresh="Refresh"
AdvSceneSwitcher.condition.source.refresh.tooltip="Repopulate the source settings selection with the settings of the source which's name matches the variable value."
AdvSceneSwitcher.condition.source.includeDefaults="Include default settings values"
AdvSceneSwitcher.condition.source.sceneVisibilityHint="Scene specific visibility can be checked using the \"Scene item visibility\" condition"
AdvSceneSwitcher.condition.source.getSettings="Get current settings"
AdvSceneSwitcher.condition.source.entry.line1="{{sources}}{{conditions}}{{settingSelection}}{{refresh}}{{sizeCompareMethods}}{{size}}"
@@ -535,6 +538,7 @@ AdvSceneSwitcher.condition.filter.type.individualSettingListSelectionMatches="Se
AdvSceneSwitcher.condition.filter.type.individualSettingChanged="Settings value changed"
AdvSceneSwitcher.condition.filter.refresh="Refresh"
AdvSceneSwitcher.condition.filter.refresh.tooltip="Repopulate the filter settings selection with the settings of the filter which's name matches the variable value."
AdvSceneSwitcher.condition.filter.includeDefaults="Include default settings values"
AdvSceneSwitcher.condition.filter.getSettings="Get current settings"
AdvSceneSwitcher.condition.filter.entry.line1="On{{sources}}{{filters}}{{conditions}}{{settingSelection}}{{refresh}}"
AdvSceneSwitcher.condition.filter.entry.line2="{{settings}}"
@@ -824,6 +828,7 @@ AdvSceneSwitcher.action.wait.entry.random="Wait for{{waitType}}duration from{{du
AdvSceneSwitcher.action.audio="Audio"
AdvSceneSwitcher.action.audio.type.mute="Mute"
AdvSceneSwitcher.action.audio.type.unmute="Unmute"
AdvSceneSwitcher.action.audio.type.toggleMute="Toggle mute"
AdvSceneSwitcher.action.audio.type.sourceVolume="Set source volume"
AdvSceneSwitcher.action.audio.type.masterVolume="Set master volume"
AdvSceneSwitcher.action.audio.type.syncOffset="Set sync offset"
@@ -959,6 +964,10 @@ AdvSceneSwitcher.action.macro.type.stop="Stop actions"
AdvSceneSwitcher.action.macro.type.disableAction="Disable action"
AdvSceneSwitcher.action.macro.type.enableAction="Enable action"
AdvSceneSwitcher.action.macro.type.toggleAction="Toggle action"
AdvSceneSwitcher.action.macro.type.nestedMacro="Nested macro"
AdvSceneSwitcher.action.macro.type.nestedMacro.conditionHelp="This section allows you to define macro conditions.\n\nClick the plus button below to add a new condition."
AdvSceneSwitcher.action.macro.type.nestedMacro.actionHelp="This section allows you to define macro actions.\nThe actions in this section will be performed when the conditions are met.\n\nClick the plus button below to add a new action."
AdvSceneSwitcher.action.macro.type.nestedMacro.elseActionHelp="This section allows you to define macro actions.\nThe actions in this section will be performed when the conditions are *not* met.\n\nClick the plus button below to add a new action."
AdvSceneSwitcher.action.macro.entry.run="{{actions}}{{actionTypes}}of{{macros}}"
AdvSceneSwitcher.action.macro.entry.run.condition="{{conditionBehaviors}}of{{conditionMacros}}"
AdvSceneSwitcher.action.macro.entry.other="{{actions}}{{actionIndex}}{{macros}}"

File diff suppressed because it is too large Load Diff

View File

@@ -790,7 +790,7 @@
</item>
</layout>
</widget>
<widget class="QGroupBox" name="macroEdit">
<widget class="QGroupBox" name="macroEditGroup">
<property name="title">
<string>AdvSceneSwitcher.macroTab.edit</string>
</property>
@@ -896,339 +896,7 @@
</layout>
</item>
<item>
<widget class="QSplitter" name="macroActionConditionSplitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QWidget" name="macroConditions" native="true">
<layout class="QVBoxLayout" name="macroConditionsLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="advss::MacroSegmentList" name="conditionsList">
<property name="minimumSize">
<size>
<width>0</width>
<height>1</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="conditionControlsLayout">
<property name="leftMargin">
<number>9</number>
</property>
<item>
<widget class="QToolButton" name="conditionAdd">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.conditionAddButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">addIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-plus</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="conditionRemove">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.conditionRemoveButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">removeIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-trash</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="conditionTop">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.conditionTopButton</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="conditionUp">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.conditionUpButton</string>
</property>
<property name="text">
<string/>
</property>
<property name="themeID" stdset="0">
<string notr="true">upArrowIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-up</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="conditionDown">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.conditionDownButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">downArrowIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-down</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="conditionBottom">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.conditionBottomButton</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QSplitter" name="macroElseActionSplitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QWidget" name="macroActions" native="true">
<layout class="QVBoxLayout" name="macroActionsLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="advss::MacroSegmentList" name="actionsList">
<property name="minimumSize">
<size>
<width>0</width>
<height>1</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="actionControlsLayout">
<property name="leftMargin">
<number>9</number>
</property>
<item>
<widget class="QToolButton" name="actionAdd">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.actionAddButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">addIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-plus</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="actionRemove">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.actionRemoveButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">removeIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-trash</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="actionTop">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.actionTopButton</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="actionUp">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.actionUpButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">upArrowIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-up</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="actionDown">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.actionDownButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">downArrowIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-down</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="actionBottom">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.actionBottomButton</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_14">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="toggleElseActions">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.toggleShowElseSection</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="macroElseActions" native="true">
<layout class="QVBoxLayout" name="macroElseActionsLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="advss::MacroSegmentList" name="elseActionsList">
<property name="minimumSize">
<size>
<width>0</width>
<height>1</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="elseActionControlsLayout">
<property name="leftMargin">
<number>9</number>
</property>
<item>
<widget class="QToolButton" name="elseActionAdd">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionAddButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">addIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-plus</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="elseActionRemove">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionRemoveButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">removeIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-trash</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="elseActionTop">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionTopButton</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="elseActionUp">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionUpButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">upArrowIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-up</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="elseActionDown">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionDownButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">downArrowIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-down</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="elseActionBottom">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionBottomButton</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</widget>
<widget class="advss::MacroEdit" name="macroEdit" native="true"/>
</item>
</layout>
</widget>
@@ -4440,12 +4108,6 @@
<extends>QListView</extends>
<header>macro-tree.hpp</header>
</customwidget>
<customwidget>
<class>advss::MacroSegmentList</class>
<extends>QScrollArea</extends>
<header>macro-segment-list.hpp</header>
<container>1</container>
</customwidget>
<customwidget>
<class>advss::MacroRunButton</class>
<extends>QPushButton</extends>
@@ -4456,6 +4118,12 @@
<extends>QWidget</extends>
<header>duration-control.hpp</header>
</customwidget>
<customwidget>
<class>advss::MacroEdit</class>
<extends>QWidget</extends>
<header>macro-edit.hpp</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>tabWidget</tabstop>
@@ -4492,28 +4160,7 @@
<tabstop>runMacroInParallel</tabstop>
<tabstop>runMacroOnChange</tabstop>
<tabstop>macroSettings</tabstop>
<tabstop>conditionsList</tabstop>
<tabstop>conditionAdd</tabstop>
<tabstop>conditionRemove</tabstop>
<tabstop>conditionTop</tabstop>
<tabstop>conditionUp</tabstop>
<tabstop>conditionDown</tabstop>
<tabstop>conditionBottom</tabstop>
<tabstop>actionsList</tabstop>
<tabstop>actionAdd</tabstop>
<tabstop>actionRemove</tabstop>
<tabstop>actionTop</tabstop>
<tabstop>actionUp</tabstop>
<tabstop>actionDown</tabstop>
<tabstop>actionBottom</tabstop>
<tabstop>toggleElseActions</tabstop>
<tabstop>elseActionsList</tabstop>
<tabstop>elseActionAdd</tabstop>
<tabstop>elseActionRemove</tabstop>
<tabstop>elseActionTop</tabstop>
<tabstop>elseActionUp</tabstop>
<tabstop>elseActionDown</tabstop>
<tabstop>elseActionBottom</tabstop>
<tabstop>macroEdit</tabstop>
<tabstop>sceneGroups</tabstop>
<tabstop>sceneGroupAdd</tabstop>
<tabstop>sceneGroupRemove</tabstop>

388
forms/macro-edit.ui Normal file
View File

@@ -0,0 +1,388 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MacroEdit</class>
<widget class="QWidget" name="MacroEdit">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QSplitter" name="macroActionConditionSplitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QWidget" name="macroConditions" native="true">
<layout class="QVBoxLayout" name="macroConditionsLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="advss::MacroSegmentList" name="conditionsList">
<property name="minimumSize">
<size>
<width>0</width>
<height>1</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="conditionControlsLayout">
<property name="leftMargin">
<number>9</number>
</property>
<item>
<widget class="QToolButton" name="conditionAdd">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.conditionAddButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">addIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-plus</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="conditionRemove">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.conditionRemoveButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">removeIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-trash</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="conditionTop">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.conditionTopButton</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="conditionUp">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.conditionUpButton</string>
</property>
<property name="text">
<string/>
</property>
<property name="themeID" stdset="0">
<string notr="true">upArrowIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-up</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="conditionDown">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.conditionDownButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">downArrowIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-down</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="conditionBottom">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.conditionBottomButton</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QSplitter" name="macroElseActionSplitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QWidget" name="macroActions" native="true">
<layout class="QVBoxLayout" name="macroActionsLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="advss::MacroSegmentList" name="actionsList">
<property name="minimumSize">
<size>
<width>0</width>
<height>1</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="actionControlsLayout">
<property name="leftMargin">
<number>9</number>
</property>
<item>
<widget class="QToolButton" name="actionAdd">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.actionAddButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">addIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-plus</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="actionRemove">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.actionRemoveButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">removeIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-trash</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="actionTop">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.actionTopButton</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="actionUp">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.actionUpButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">upArrowIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-up</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="actionDown">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.actionDownButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">downArrowIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-down</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="actionBottom">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.actionBottomButton</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_14">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="toggleElseActions">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.toggleShowElseSection</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="macroElseActions" native="true">
<layout class="QVBoxLayout" name="macroElseActionsLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="advss::MacroSegmentList" name="elseActionsList">
<property name="minimumSize">
<size>
<width>0</width>
<height>1</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="elseActionControlsLayout">
<property name="leftMargin">
<number>9</number>
</property>
<item>
<widget class="QToolButton" name="elseActionAdd">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionAddButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">addIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-plus</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="elseActionRemove">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionRemoveButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">removeIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-trash</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="elseActionTop">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionTopButton</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="elseActionUp">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionUpButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">upArrowIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-up</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="elseActionDown">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionDownButton</string>
</property>
<property name="themeID" stdset="0">
<string notr="true">downArrowIconSmall</string>
</property>
<property name="class" stdset="0">
<string notr="true">icon-down</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="elseActionBottom">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionBottomButton</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>advss::MacroSegmentList</class>
<extends>QScrollArea</extends>
<header>macro-segment-list.hpp</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>conditionsList</tabstop>
<tabstop>conditionAdd</tabstop>
<tabstop>conditionRemove</tabstop>
<tabstop>conditionTop</tabstop>
<tabstop>conditionUp</tabstop>
<tabstop>conditionDown</tabstop>
<tabstop>conditionBottom</tabstop>
<tabstop>actionsList</tabstop>
<tabstop>actionAdd</tabstop>
<tabstop>actionRemove</tabstop>
<tabstop>actionTop</tabstop>
<tabstop>actionUp</tabstop>
<tabstop>actionDown</tabstop>
<tabstop>actionBottom</tabstop>
<tabstop>toggleElseActions</tabstop>
<tabstop>elseActionsList</tabstop>
<tabstop>elseActionAdd</tabstop>
<tabstop>elseActionRemove</tabstop>
<tabstop>elseActionTop</tabstop>
<tabstop>elseActionUp</tabstop>
<tabstop>elseActionDown</tabstop>
<tabstop>elseActionBottom</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -146,16 +146,7 @@ void AdvSceneSwitcher::LoadUI()
bool AdvSceneSwitcher::eventFilter(QObject *obj, QEvent *event)
{
auto eventType = event->type();
if (obj == ui->macroElseActions && eventType == QEvent::Resize) {
QResizeEvent *resizeEvent = static_cast<QResizeEvent *>(event);
if (resizeEvent->size().height() == 0) {
SetElseActionsStateToHidden();
return QDialog::eventFilter(obj, event);
}
SetElseActionsStateToVisible();
} else if (eventType == QEvent::KeyPress) {
if (eventType == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
auto pressedKey = keyEvent->key();
@@ -608,7 +599,7 @@ static void handleSceneCollectionChanging()
AdvSceneSwitcher::window->close();
}
if (!switcher->stop) {
switcher->sceneColletionStop = true;
switcher->sceneCollectionStop = true;
switcher->Stop();
}
}
@@ -744,6 +735,21 @@ void AdvSceneSwitcher::HighlightMacroSettingsButton(bool enable)
highlight = HighlightWidget(ui->macroSettings, Qt::green);
}
void AdvSceneSwitcher::HighlightAction(int idx, QColor color) const
{
ui->macroEdit->HighlightAction(idx, color);
}
void AdvSceneSwitcher::HighlightElseAction(int idx, QColor color) const
{
ui->macroEdit->HighlightElseAction(idx, color);
}
void AdvSceneSwitcher::HighlightCondition(int idx, QColor color) const
{
ui->macroEdit->HighlightCondition(idx, color);
}
void HighlightMacroSettingsButton(bool enable)
{
auto window = GetSettingsWindow();

View File

@@ -79,6 +79,7 @@ public slots:
/* --- Begin of macro tab section --- */
public:
void SetupMacroTab();
bool MacroTabIsInFocus();
bool AddNewMacro(std::shared_ptr<Macro> &res, std::string &name,
std::string format = "");
void RemoveMacro(std::shared_ptr<Macro> &);
@@ -86,7 +87,6 @@ public:
void RenameMacro(std::shared_ptr<Macro> &, const QString &name);
std::shared_ptr<Macro> GetSelectedMacro() const;
std::vector<std::shared_ptr<Macro>> GetSelectedMacros() const;
void SetEditMacro(Macro &m);
void SetMacroEditAreaDisabled(bool) const;
void HighlightAction(int idx, QColor color = QColor(Qt::green)) const;
void HighlightElseAction(int idx,
@@ -111,82 +111,14 @@ public slots:
void on_macroName_editingFinished();
void on_runMacroInParallel_stateChanged(int value) const;
void on_runMacroOnChange_stateChanged(int value) const;
void on_conditionAdd_clicked();
void on_conditionRemove_clicked();
void on_conditionTop_clicked();
void on_conditionUp_clicked();
void on_conditionDown_clicked();
void on_conditionBottom_clicked();
void on_actionAdd_clicked();
void on_actionRemove_clicked();
void on_actionTop_clicked();
void on_actionUp_clicked();
void on_actionDown_clicked();
void on_actionBottom_clicked();
void on_toggleElseActions_clicked() const;
void on_elseActionAdd_clicked();
void on_elseActionRemove_clicked();
void on_elseActionTop_clicked();
void on_elseActionUp_clicked();
void on_elseActionDown_clicked();
void on_elseActionBottom_clicked();
void MacroSelectionAboutToChange() const;
void MacroSelectionChanged();
void UpMacroSegementHotkey();
void DownMacroSegementHotkey();
void DeleteMacroSegementHotkey();
void ShowMacroContextMenu(const QPoint &);
void ShowMacroActionsContextMenu(const QPoint &);
void ShowMacroElseActionsContextMenu(const QPoint &);
void ShowMacroConditionsContextMenu(const QPoint &);
void CopyMacro();
void RenameSelectedMacro();
void ExportMacros() const;
void ImportMacros();
void ExpandAllActions() const;
void ExpandAllElseActions() const;
void ExpandAllConditions() const;
void CollapseAllActions() const;
void CollapseAllElseActions() const;
void CollapseAllConditions() const;
void MinimizeActions() const;
void MaximizeActions() const;
void MinimizeElseActions() const;
void MaximizeElseActions() const;
void MinimizeConditions() const;
void MaximizeConditions() const;
void SetElseActionsStateToHidden() const;
void SetElseActionsStateToVisible() const;
void MacroActionSelectionChanged(int idx);
void MacroActionReorder(int to, int target);
void AddMacroAction(Macro *macro, int idx, const std::string &id,
obs_data_t *data);
void AddMacroAction(int idx);
void RemoveMacroAction(int idx);
void MoveMacroActionUp(int idx);
void MoveMacroActionDown(int idx);
void MacroElseActionSelectionChanged(int idx);
void MacroElseActionReorder(int to, int target);
void AddMacroElseAction(Macro *macro, int idx, const std::string &id,
obs_data_t *data);
void AddMacroElseAction(int idx);
void RemoveMacroElseAction(int idx);
void SwapElseActions(Macro *m, int pos1, int pos2);
void MoveMacroElseActionUp(int idx);
void MoveMacroElseActionDown(int idx);
void MacroConditionSelectionChanged(int idx);
void MacroConditionReorder(int to, int target);
void AddMacroCondition(int idx);
void AddMacroCondition(Macro *macro, int idx, const std::string &id,
obs_data_t *data, Logic::Type logic);
void RemoveMacroCondition(int idx);
void MoveMacroConditionUp(int idx);
void MoveMacroConditionDown(int idx);
void HighlightControls() const;
void HighlightOnChange() const;
void on_macroSettings_clicked();
void CopyMacroSegment();
void PasteMacroSegment();
signals:
void MacroAdded(const QString &name);
@@ -201,16 +133,7 @@ signals:
void ConnectionRemoved(const QString &);
private:
enum class MacroSection { CONDITIONS, ACTIONS, ELSE_ACTIONS };
void SetupMacroSegmentSelection(MacroSection type, int idx);
bool ResolveMacroImportNameConflict(std::shared_ptr<Macro> &);
bool MacroTabIsInFocus();
MacroSection lastInteracted = MacroSection::CONDITIONS;
int currentConditionIdx = -1;
int currentActionIdx = -1;
int currentElseActionIdx = -1;
/* --- End of macro tab section --- */

View File

@@ -163,7 +163,7 @@ void AdvSceneSwitcher::closeEvent(QCloseEvent *)
switcher->windowSize = this->size();
switcher->macroListMacroEditSplitterPosition =
ui->macroListMacroEditSplitter->sizes();
MacroSelectionAboutToChange(); // Trigger saving of splitter states
ui->macroEdit->SetMacro(nullptr); // Trigger saving of splitter states
obs_frontend_save();
}
@@ -535,8 +535,8 @@ void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
cooldown.Save(obj, "cooldown");
obs_data_set_bool(obj, "enableCooldown", enableCooldown);
obs_data_set_bool(obj, "active", sceneColletionStop ? true : !stop);
sceneColletionStop = false;
obs_data_set_bool(obj, "active", sceneCollectionStop ? true : !stop);
sceneCollectionStop = false;
obs_data_set_int(obj, "startup_behavior",
static_cast<int>(startupBehavior));

View File

@@ -158,473 +158,4 @@ std::shared_ptr<MacroSegment> MacroActionEdit::Data() const
return *_entryData;
}
void AdvSceneSwitcher::AddMacroAction(Macro *macro, int idx,
const std::string &id, obs_data_t *data)
{
if (idx < 0 || idx > (int)macro->Actions().size()) {
assert(false);
return;
}
{
auto lock = LockContext();
macro->Actions().emplace(macro->Actions().begin() + idx,
MacroActionFactory::Create(id, macro));
if (data) {
macro->Actions().at(idx)->Load(data);
}
macro->Actions().at(idx)->PostLoad();
RunPostLoadSteps();
macro->UpdateActionIndices();
ui->actionsList->Insert(
idx,
new MacroActionEdit(this, &macro->Actions()[idx], id));
SetActionData(*macro);
}
HighlightAction(idx);
ui->actionsList->SetHelpMsgVisible(false);
emit(MacroSegmentOrderChanged());
}
void AdvSceneSwitcher::AddMacroAction(int idx)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (idx < 0 || idx > (int)macro->Actions().size()) {
assert(false);
return;
}
std::string id;
if (idx - 1 >= 0) {
id = macro->Actions().at(idx - 1)->GetId();
} else {
id = MacroAction::GetDefaultID();
}
OBSDataAutoRelease data;
if (idx - 1 >= 0) {
data = obs_data_create();
macro->Actions().at(idx - 1)->Save(data);
}
AddMacroAction(macro.get(), idx, id, data);
}
void AdvSceneSwitcher::on_actionAdd_clicked()
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (currentActionIdx == -1) {
AddMacroAction((int)macro->Actions().size());
} else {
AddMacroAction(currentActionIdx + 1);
}
if (currentActionIdx != -1) {
MacroActionSelectionChanged(currentActionIdx + 1);
}
}
void AdvSceneSwitcher::RemoveMacroAction(int idx)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (idx < 0 || idx >= (int)macro->Actions().size()) {
return;
}
{
auto lock = LockContext();
ui->actionsList->Remove(idx);
macro->Actions().erase(macro->Actions().begin() + idx);
SetMacroAbortWait(true);
GetMacroWaitCV().notify_all();
macro->UpdateActionIndices();
SetActionData(*macro);
}
MacroActionSelectionChanged(-1);
lastInteracted = MacroSection::ACTIONS;
emit(MacroSegmentOrderChanged());
}
void AdvSceneSwitcher::on_actionRemove_clicked()
{
if (currentActionIdx == -1) {
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
RemoveMacroAction((int)macro->Actions().size() - 1);
} else {
RemoveMacroAction(currentActionIdx);
}
MacroActionSelectionChanged(-1);
}
void AdvSceneSwitcher::on_actionTop_clicked()
{
if (currentActionIdx == -1) {
return;
}
MacroActionReorder(0, currentActionIdx);
MacroActionSelectionChanged(0);
}
void AdvSceneSwitcher::on_actionUp_clicked()
{
if (currentActionIdx == -1 || currentActionIdx == 0) {
return;
}
MoveMacroActionUp(currentActionIdx);
MacroActionSelectionChanged(currentActionIdx - 1);
}
void AdvSceneSwitcher::on_actionDown_clicked()
{
if (currentActionIdx == -1 ||
currentActionIdx == ui->actionsList->ContentLayout()->count() - 1) {
return;
}
MoveMacroActionDown(currentActionIdx);
MacroActionSelectionChanged(currentActionIdx + 1);
}
void AdvSceneSwitcher::on_actionBottom_clicked()
{
if (currentActionIdx == -1) {
return;
}
const int newIdx = ui->actionsList->ContentLayout()->count() - 1;
MacroActionReorder(newIdx, currentActionIdx);
MacroActionSelectionChanged(newIdx);
}
void AdvSceneSwitcher::on_elseActionAdd_clicked()
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (currentElseActionIdx == -1) {
AddMacroElseAction((int)macro->ElseActions().size());
} else {
AddMacroElseAction(currentElseActionIdx + 1);
}
if (currentElseActionIdx != -1) {
MacroElseActionSelectionChanged(currentElseActionIdx + 1);
}
}
void AdvSceneSwitcher::on_elseActionRemove_clicked()
{
if (currentElseActionIdx == -1) {
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
RemoveMacroElseAction((int)macro->ElseActions().size() - 1);
} else {
RemoveMacroElseAction(currentElseActionIdx);
}
MacroElseActionSelectionChanged(-1);
}
void AdvSceneSwitcher::on_elseActionTop_clicked()
{
if (currentElseActionIdx == -1) {
return;
}
MacroElseActionReorder(0, currentElseActionIdx);
MacroElseActionSelectionChanged(0);
}
void AdvSceneSwitcher::on_elseActionUp_clicked()
{
if (currentElseActionIdx == -1 || currentElseActionIdx == 0) {
return;
}
MoveMacroElseActionUp(currentElseActionIdx);
MacroElseActionSelectionChanged(currentElseActionIdx - 1);
}
void AdvSceneSwitcher::on_elseActionDown_clicked()
{
if (currentElseActionIdx == -1 ||
currentElseActionIdx ==
ui->elseActionsList->ContentLayout()->count() - 1) {
return;
}
MoveMacroElseActionDown(currentElseActionIdx);
MacroElseActionSelectionChanged(currentElseActionIdx + 1);
}
void AdvSceneSwitcher::on_elseActionBottom_clicked()
{
if (currentElseActionIdx == -1) {
return;
}
const int newIdx = ui->elseActionsList->ContentLayout()->count() - 1;
MacroElseActionReorder(newIdx, currentElseActionIdx);
MacroElseActionSelectionChanged(newIdx);
}
void AdvSceneSwitcher::SwapActions(Macro *m, int pos1, int pos2)
{
if (pos1 == pos2) {
return;
}
if (pos1 > pos2) {
std::swap(pos1, pos2);
}
auto lock = LockContext();
iter_swap(m->Actions().begin() + pos1, m->Actions().begin() + pos2);
m->UpdateActionIndices();
auto widget1 = static_cast<MacroActionEdit *>(
ui->actionsList->ContentLayout()->takeAt(pos1)->widget());
auto widget2 = static_cast<MacroActionEdit *>(
ui->actionsList->ContentLayout()->takeAt(pos2 - 1)->widget());
ui->actionsList->Insert(pos1, widget2);
ui->actionsList->Insert(pos2, widget1);
SetActionData(*m);
emit(MacroSegmentOrderChanged());
}
void AdvSceneSwitcher::MoveMacroActionUp(int idx)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (idx < 1 || idx >= (int)macro->Actions().size()) {
return;
}
SwapActions(macro.get(), idx, idx - 1);
HighlightAction(idx - 1);
}
void AdvSceneSwitcher::MoveMacroActionDown(int idx)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (idx < 0 || idx >= (int)macro->Actions().size() - 1) {
return;
}
SwapActions(macro.get(), idx, idx + 1);
HighlightAction(idx + 1);
}
void AdvSceneSwitcher::MacroElseActionSelectionChanged(int idx)
{
SetupMacroSegmentSelection(MacroSection::ELSE_ACTIONS, idx);
}
void AdvSceneSwitcher::MacroElseActionReorder(int to, int from)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (to == from || from < 0 || from > (int)macro->ElseActions().size() ||
to < 0 || to > (int)macro->ElseActions().size()) {
return;
}
{
auto lock = LockContext();
auto action = macro->ElseActions().at(from);
macro->ElseActions().erase(macro->ElseActions().begin() + from);
macro->ElseActions().insert(macro->ElseActions().begin() + to,
action);
macro->UpdateElseActionIndices();
ui->elseActionsList->ContentLayout()->insertItem(
to, ui->elseActionsList->ContentLayout()->takeAt(from));
SetElseActionData(*macro);
}
HighlightElseAction(to);
emit(MacroSegmentOrderChanged());
}
void AdvSceneSwitcher::AddMacroElseAction(Macro *macro, int idx,
const std::string &id,
obs_data_t *data)
{
if (idx < 0 || idx > (int)macro->ElseActions().size()) {
assert(false);
return;
}
{
auto lock = LockContext();
macro->ElseActions().emplace(macro->ElseActions().begin() + idx,
MacroActionFactory::Create(id,
macro));
if (data) {
macro->ElseActions().at(idx)->Load(data);
}
macro->ElseActions().at(idx)->PostLoad();
RunPostLoadSteps();
macro->UpdateElseActionIndices();
ui->elseActionsList->Insert(
idx, new MacroActionEdit(
this, &macro->ElseActions()[idx], id));
SetElseActionData(*macro);
}
HighlightElseAction(idx);
ui->elseActionsList->SetHelpMsgVisible(false);
emit(MacroSegmentOrderChanged());
}
void AdvSceneSwitcher::AddMacroElseAction(int idx)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (idx < 0 || idx > (int)macro->ElseActions().size()) {
assert(false);
return;
}
std::string id;
if (idx - 1 >= 0) {
id = macro->ElseActions().at(idx - 1)->GetId();
} else {
id = MacroAction::GetDefaultID();
}
OBSDataAutoRelease data;
if (idx - 1 >= 0) {
data = obs_data_create();
macro->ElseActions().at(idx - 1)->Save(data);
}
AddMacroElseAction(macro.get(), idx, id, data);
}
void AdvSceneSwitcher::RemoveMacroElseAction(int idx)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (idx < 0 || idx >= (int)macro->ElseActions().size()) {
return;
}
{
auto lock = LockContext();
ui->elseActionsList->Remove(idx);
macro->ElseActions().erase(macro->ElseActions().begin() + idx);
SetMacroAbortWait(true);
GetMacroWaitCV().notify_all();
macro->UpdateElseActionIndices();
SetElseActionData(*macro);
}
MacroElseActionSelectionChanged(-1);
lastInteracted = MacroSection::ELSE_ACTIONS;
emit(MacroSegmentOrderChanged());
}
void AdvSceneSwitcher::SwapElseActions(Macro *m, int pos1, int pos2)
{
if (pos1 == pos2) {
return;
}
if (pos1 > pos2) {
std::swap(pos1, pos2);
}
auto lock = LockContext();
iter_swap(m->ElseActions().begin() + pos1,
m->ElseActions().begin() + pos2);
m->UpdateElseActionIndices();
auto widget1 = static_cast<MacroActionEdit *>(
ui->elseActionsList->ContentLayout()->takeAt(pos1)->widget());
auto widget2 = static_cast<MacroActionEdit *>(
ui->elseActionsList->ContentLayout()
->takeAt(pos2 - 1)
->widget());
ui->elseActionsList->Insert(pos1, widget2);
ui->elseActionsList->Insert(pos2, widget1);
SetElseActionData(*m);
emit(MacroSegmentOrderChanged());
}
void AdvSceneSwitcher::MoveMacroElseActionUp(int idx)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (idx < 1 || idx >= (int)macro->ElseActions().size()) {
return;
}
SwapElseActions(macro.get(), idx, idx - 1);
HighlightElseAction(idx - 1);
}
void AdvSceneSwitcher::MoveMacroElseActionDown(int idx)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (idx < 0 || idx >= (int)macro->ElseActions().size() - 1) {
return;
}
SwapElseActions(macro.get(), idx, idx + 1);
HighlightElseAction(idx + 1);
}
void AdvSceneSwitcher::MacroActionSelectionChanged(int idx)
{
SetupMacroSegmentSelection(MacroSection::ACTIONS, idx);
}
void AdvSceneSwitcher::MacroActionReorder(int to, int from)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (to == from || from < 0 || from > (int)macro->Actions().size() ||
to < 0 || to > (int)macro->Actions().size()) {
return;
}
{
auto lock = LockContext();
auto action = macro->Actions().at(from);
macro->Actions().erase(macro->Actions().begin() + from);
macro->Actions().insert(macro->Actions().begin() + to, action);
macro->UpdateActionIndices();
ui->actionsList->ContentLayout()->insertItem(
to, ui->actionsList->ContentLayout()->takeAt(from));
SetActionData(*macro);
}
HighlightAction(to);
emit(MacroSegmentOrderChanged());
}
} // namespace advss

View File

@@ -14,6 +14,11 @@ bool MacroActionMacro::_registered = MacroActionFactory::Register(
bool MacroActionMacro::PerformAction()
{
if (_action == Action::NESTED_MACRO) {
const bool conditionsMatched = _nestedMacro->CheckConditions();
return _nestedMacro->PerformActions(conditionsMatched);
}
auto macro = _macro.GetMacro();
if (!macro) {
return true;
@@ -32,7 +37,7 @@ bool MacroActionMacro::PerformAction()
case Action::RESET_COUNTER:
macro->ResetRunCount();
break;
case Action::RUN:
case Action::RUN_ACTIONS:
RunActions(macro.get());
break;
case Action::STOP:
@@ -80,7 +85,7 @@ void MacroActionMacro::LogAction() const
ablog(LOG_INFO, "reset counter for \"%s\"",
macro->Name().c_str());
break;
case Action::RUN:
case Action::RUN_ACTIONS:
ablog(LOG_INFO, "run nested macro \"%s\"",
macro->Name().c_str());
break;
@@ -99,6 +104,9 @@ void MacroActionMacro::LogAction() const
ablog(LOG_INFO, "toggled action %d of macro \"%s\"",
_actionIndex.GetValue(), macro->Name().c_str());
break;
case Action::NESTED_MACRO:
ablog(LOG_INFO, "run nested macro");
break;
default:
break;
}
@@ -111,6 +119,10 @@ bool MacroActionMacro::Save(obs_data_t *obj) const
_actionIndex.Save(obj, "actionIndex");
obs_data_set_int(obj, "action", static_cast<int>(_action));
_runOptions.Save(obj);
OBSDataAutoRelease nestedMacroData = obs_data_create();
_nestedMacro->Save(nestedMacroData);
obs_data_set_obj(obj, "nestedMacro", nestedMacroData);
obs_data_set_int(obj, "customWidgetHeight", _customWidgetHeight);
return true;
}
@@ -122,6 +134,16 @@ bool MacroActionMacro::Load(obs_data_t *obj)
_action = static_cast<MacroActionMacro::Action>(
obs_data_get_int(obj, "action"));
_runOptions.Load(obj);
if (obs_data_has_user_value(obj, "nestedMacro")) {
OBSDataAutoRelease nestedMacroData =
obs_data_get_obj(obj, "nestedMacro");
_nestedMacro->Load(nestedMacroData);
_nestedMacro->PostLoad();
}
_customWidgetHeight = obs_data_get_int(obj, "customWidgetHeight");
return true;
}
@@ -204,7 +226,9 @@ static void populateActionSelection(QComboBox *list)
"AdvSceneSwitcher.action.macro.type.togglePause"},
{MacroActionMacro::Action::RESET_COUNTER,
"AdvSceneSwitcher.action.macro.type.resetCounter"},
{MacroActionMacro::Action::RUN,
{MacroActionMacro::Action::NESTED_MACRO,
"AdvSceneSwitcher.action.macro.type.nestedMacro"},
{MacroActionMacro::Action::RUN_ACTIONS,
"AdvSceneSwitcher.action.macro.type.run"},
{MacroActionMacro::Action::STOP,
"AdvSceneSwitcher.action.macro.type.stop"},
@@ -242,7 +266,7 @@ static void populateActionTypeSelection(QComboBox *list)
MacroActionMacroEdit::MacroActionMacroEdit(
QWidget *parent, std::shared_ptr<MacroActionMacro> entryData)
: QWidget(parent),
: ResizableWidget(parent),
_macros(new MacroSelection(parent)),
_actionIndex(new MacroSegmentSelection(
this, MacroSegmentSelection::Type::ACTION)),
@@ -261,7 +285,13 @@ MacroActionMacroEdit::MacroActionMacroEdit(
_entryLayout(new QHBoxLayout()),
_conditionLayout(new QHBoxLayout()),
_reevaluateConditionStateLayout(new QHBoxLayout()),
_setInputsLayout(new QHBoxLayout())
_setInputsLayout(new QHBoxLayout()),
_nestedMacro(new MacroEdit(
this,
QStringList()
<< "AdvSceneSwitcher.action.macro.type.nestedMacro.conditionHelp"
<< "AdvSceneSwitcher.action.macro.type.nestedMacro.actionHelp"
<< "AdvSceneSwitcher.action.macro.type.nestedMacro.elseActionHelp"))
{
populateActionSelection(_actions);
populateConditionBehaviorSelection(_conditionBehaviors);
@@ -310,6 +340,7 @@ MacroActionMacroEdit::MacroActionMacroEdit(
layout->addLayout(_setInputsLayout);
layout->addWidget(_inputs);
layout->addWidget(_skipWhenPaused);
layout->addWidget(_nestedMacro);
setLayout(layout);
_entryData = entryData;
UpdateEntryData();
@@ -321,6 +352,12 @@ void HighlightMacroSettingsButton(bool enable);
MacroActionMacroEdit::~MacroActionMacroEdit()
{
HighlightMacroSettingsButton(false);
if (!_entryData) {
return;
}
_entryData->_customWidgetHeight = GetCustomHeight();
_nestedMacro->SetMacro({}); // Save splitter states
}
void MacroActionMacroEdit::UpdateEntryData()
@@ -343,9 +380,20 @@ void MacroActionMacroEdit::UpdateEntryData()
_skipWhenPaused->setChecked(_entryData->_runOptions.skipWhenPaused);
_setInputs->setChecked(_entryData->_runOptions.setInputs);
SetupMacroInput(_entryData->_macro.GetMacro().get());
const auto &macro = _entryData->_nestedMacro;
_nestedMacro->SetMacro(macro);
SetWidgetVisibility();
}
QWidget *MacroActionMacroEdit::Create(QWidget *parent,
std::shared_ptr<MacroAction> action)
{
return new MacroActionMacroEdit(
parent, std::dynamic_pointer_cast<MacroActionMacro>(action));
}
void MacroActionMacroEdit::MacroChanged(const QString &text)
{
GUARD_LOADING_AND_LOCK();
@@ -444,7 +492,8 @@ void MacroActionMacroEdit::SetWidgetVisibility()
PlaceWidgets(
obs_module_text(
_entryData->_action == MacroActionMacro::Action::RUN
_entryData->_action ==
MacroActionMacro::Action::RUN_ACTIONS
? "AdvSceneSwitcher.action.macro.entry.run"
: "AdvSceneSwitcher.action.macro.entry.other"),
_entryLayout, placeholders);
@@ -460,7 +509,7 @@ void MacroActionMacroEdit::SetWidgetVisibility()
_conditionLayout, placeholders);
}
if (_entryData->_action == MacroActionMacro::Action::RUN ||
if (_entryData->_action == MacroActionMacro::Action::RUN_ACTIONS ||
_entryData->_action == MacroActionMacro::Action::STOP) {
_macros->HideSelectedMacro();
} else {
@@ -476,27 +525,43 @@ void MacroActionMacroEdit::SetWidgetVisibility()
_actionIndex->setVisible(isModifyingActionState);
SetLayoutVisible(_conditionLayout,
_entryData->_action == MacroActionMacro::Action::RUN);
_entryData->_action ==
MacroActionMacro::Action::RUN_ACTIONS);
const bool needsAdditionalConditionWidgets =
_entryData->_action == MacroActionMacro::Action::RUN &&
_entryData->_action == MacroActionMacro::Action::RUN_ACTIONS &&
_entryData->_runOptions.logic !=
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS;
_conditionMacros->setVisible(needsAdditionalConditionWidgets);
SetLayoutVisible(_reevaluateConditionStateLayout,
needsAdditionalConditionWidgets);
SetLayoutVisible(_setInputsLayout,
_entryData->_action == MacroActionMacro::Action::RUN);
_entryData->_action ==
MacroActionMacro::Action::RUN_ACTIONS);
_inputs->setVisible(_entryData->_action ==
MacroActionMacro::Action::RUN &&
MacroActionMacro::Action::RUN_ACTIONS &&
_entryData->_runOptions.setInputs);
HighlightMacroSettingsButton(_entryData->_action ==
MacroActionMacro::Action::RUN &&
_entryData->_runOptions.setInputs &&
!_inputs->HasInputsToSet());
HighlightMacroSettingsButton(
_entryData->_action == MacroActionMacro::Action::RUN_ACTIONS &&
_entryData->_runOptions.setInputs &&
!_inputs->HasInputsToSet());
_actionTypes->setVisible(_entryData->_action ==
MacroActionMacro::Action::RUN);
MacroActionMacro::Action::RUN_ACTIONS);
_skipWhenPaused->setVisible(_entryData->_action ==
MacroActionMacro::Action::RUN);
MacroActionMacro::Action::RUN_ACTIONS);
_nestedMacro->setVisible(_entryData->_action ==
MacroActionMacro::Action::NESTED_MACRO);
_macros->setVisible(_entryData->_action !=
MacroActionMacro::Action::NESTED_MACRO);
SetResizingEnabled(_entryData->_action ==
MacroActionMacro::Action::NESTED_MACRO);
if (_nestedMacro->IsEmpty()) {
_nestedMacro->ShowAllMacroSections();
// TODO: find a better solution than setting a fixed height
_entryData->_customWidgetHeight = 600;
}
SetCustomHeight(_entryData->_customWidgetHeight);
adjustSize();
updateGeometry();

View File

@@ -1,8 +1,11 @@
#pragma once
#include "macro-action-edit.hpp"
#include "macro.hpp"
#include "macro-edit.hpp"
#include "macro-input.hpp"
#include "macro-selection.hpp"
#include "macro-segment-selection.hpp"
#include "resizable-widget.hpp"
#include <QCheckBox>
#include <QHBoxLayout>
@@ -44,16 +47,19 @@ public:
PAUSE,
UNPAUSE,
RESET_COUNTER,
RUN,
RUN_ACTIONS,
STOP,
DISABLE_ACTION,
ENABLE_ACTION,
TOGGLE_ACTION,
TOGGLE_PAUSE,
NESTED_MACRO,
};
Action _action = Action::RUN;
Action _action = Action::NESTED_MACRO;
IntVariable _actionIndex = 1;
RunOptions _runOptions = {};
std::shared_ptr<Macro> _nestedMacro = std::make_shared<Macro>();
int _customWidgetHeight = 0;
private:
void RunActions(Macro *actionMacro) const;
@@ -62,7 +68,7 @@ private:
static const std::string id;
};
class MacroActionMacroEdit final : public QWidget {
class MacroActionMacroEdit final : public ResizableWidget {
Q_OBJECT
public:
@@ -71,13 +77,7 @@ public:
std::shared_ptr<MacroActionMacro> entryData = nullptr);
~MacroActionMacroEdit();
void UpdateEntryData();
static QWidget *Create(QWidget *parent,
std::shared_ptr<MacroAction> action)
{
return new MacroActionMacroEdit(
parent,
std::dynamic_pointer_cast<MacroActionMacro>(action));
}
static QWidget *Create(QWidget *, std::shared_ptr<MacroAction>);
private slots:
void MacroChanged(const QString &text);
@@ -112,6 +112,7 @@ private:
QHBoxLayout *_conditionLayout;
QHBoxLayout *_reevaluateConditionStateLayout;
QHBoxLayout *_setInputsLayout;
MacroEdit *_nestedMacro;
std::shared_ptr<MacroActionMacro> _entryData;
bool _loading = true;

View File

@@ -884,7 +884,8 @@ MacroActionVariableEdit::MacroActionVariableEdit(
QWidget::connect(_segmentIdx,
SIGNAL(SelectionChanged(const IntVariable &)), this,
SLOT(SegmentIndexChanged(const IntVariable &)));
QWidget::connect(window(), SIGNAL(MacroSegmentOrderChanged()), this,
QWidget::connect(GetSettingsWindow(),
SIGNAL(MacroSegmentOrderChanged()), this,
SLOT(MacroSegmentOrderChanged()));
QWidget::connect(
_subStringStart,

View File

@@ -275,289 +275,4 @@ std::shared_ptr<MacroSegment> MacroConditionEdit::Data() const
return *_entryData;
}
void AdvSceneSwitcher::AddMacroCondition(int idx)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (idx < 0 || idx > (int)macro->Conditions().size()) {
assert(false);
return;
}
std::string id;
Logic::Type logic;
if (idx >= 1) {
id = macro->Conditions().at(idx - 1)->GetId();
if (idx == 1) {
logic = Logic::Type::OR;
} else {
logic = macro->Conditions().at(idx - 1)->GetLogicType();
}
} else {
id = MacroCondition::GetDefaultID();
logic = Logic::Type::ROOT_NONE;
}
OBSDataAutoRelease data;
if (idx - 1 >= 0) {
data = obs_data_create();
macro->Conditions().at(idx - 1)->Save(data);
}
AddMacroCondition(macro.get(), idx, id, data.Get(), logic);
}
void AdvSceneSwitcher::AddMacroCondition(Macro *macro, int idx,
const std::string &id,
obs_data_t *data, Logic::Type logic)
{
if (idx < 0 || idx > (int)macro->Conditions().size()) {
assert(false);
return;
}
{
auto lock = LockContext();
auto cond = macro->Conditions().emplace(
macro->Conditions().begin() + idx,
MacroConditionFactory::Create(id, macro));
if (data) {
macro->Conditions().at(idx)->Load(data);
}
macro->Conditions().at(idx)->PostLoad();
RunPostLoadSteps();
(*cond)->SetLogicType(logic);
macro->UpdateConditionIndices();
ui->conditionsList->Insert(
idx,
new MacroConditionEdit(this, &macro->Conditions()[idx],
id, idx == 0));
SetConditionData(*macro);
}
HighlightCondition(idx);
ui->conditionsList->SetHelpMsgVisible(false);
emit(MacroSegmentOrderChanged());
}
void AdvSceneSwitcher::on_conditionAdd_clicked()
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (currentConditionIdx == -1) {
AddMacroCondition((int)macro->Conditions().size());
} else {
AddMacroCondition(currentConditionIdx + 1);
}
if (currentConditionIdx != -1) {
MacroConditionSelectionChanged(currentConditionIdx + 1);
}
}
void AdvSceneSwitcher::RemoveMacroCondition(int idx)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (idx < 0 || idx >= (int)macro->Conditions().size()) {
return;
}
{
auto lock = LockContext();
ui->conditionsList->Remove(idx);
macro->Conditions().erase(macro->Conditions().begin() + idx);
macro->UpdateConditionIndices();
if (idx == 0 && macro->Conditions().size() > 0) {
auto newRoot = macro->Conditions().at(0);
newRoot->SetLogicType(Logic::Type::ROOT_NONE);
static_cast<MacroConditionEdit *>(
ui->conditionsList->WidgetAt(0))
->SetRootNode(true);
}
SetConditionData(*macro);
}
MacroConditionSelectionChanged(-1);
lastInteracted = MacroSection::CONDITIONS;
emit(MacroSegmentOrderChanged());
}
void AdvSceneSwitcher::on_conditionRemove_clicked()
{
if (currentConditionIdx == -1) {
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
RemoveMacroCondition((int)macro->Conditions().size() - 1);
} else {
RemoveMacroCondition(currentConditionIdx);
}
MacroConditionSelectionChanged(-1);
}
void AdvSceneSwitcher::on_conditionTop_clicked()
{
if (currentConditionIdx == -1) {
return;
}
MacroConditionReorder(0, currentConditionIdx);
MacroConditionSelectionChanged(0);
}
void AdvSceneSwitcher::on_conditionUp_clicked()
{
if (currentConditionIdx == -1 || currentConditionIdx == 0) {
return;
}
MoveMacroConditionUp(currentConditionIdx);
MacroConditionSelectionChanged(currentConditionIdx - 1);
}
void AdvSceneSwitcher::on_conditionDown_clicked()
{
if (currentConditionIdx == -1 ||
currentConditionIdx ==
ui->conditionsList->ContentLayout()->count() - 1) {
return;
}
MoveMacroConditionDown(currentConditionIdx);
MacroConditionSelectionChanged(currentConditionIdx + 1);
}
void AdvSceneSwitcher::on_conditionBottom_clicked()
{
if (currentConditionIdx == -1) {
return;
}
const int newIdx = ui->conditionsList->ContentLayout()->count() - 1;
MacroConditionReorder(newIdx, currentConditionIdx);
MacroConditionSelectionChanged(newIdx);
}
void AdvSceneSwitcher::SwapConditions(Macro *m, int pos1, int pos2)
{
if (pos1 == pos2) {
return;
}
if (pos1 > pos2) {
std::swap(pos1, pos2);
}
bool root = pos1 == 0;
auto lock = LockContext();
iter_swap(m->Conditions().begin() + pos1,
m->Conditions().begin() + pos2);
m->UpdateConditionIndices();
auto c1 = m->Conditions().begin() + pos1;
auto c2 = m->Conditions().begin() + pos2;
if (root) {
auto logic1 = (*c1)->GetLogicType();
auto logic2 = (*c2)->GetLogicType();
(*c1)->SetLogicType(logic2);
(*c2)->SetLogicType(logic1);
}
auto widget1 = static_cast<MacroConditionEdit *>(
ui->conditionsList->ContentLayout()->takeAt(pos1)->widget());
auto widget2 = static_cast<MacroConditionEdit *>(
ui->conditionsList->ContentLayout()->takeAt(pos2 - 1)->widget());
ui->conditionsList->Insert(pos1, widget2);
ui->conditionsList->Insert(pos2, widget1);
SetConditionData(*m);
widget2->SetRootNode(root);
widget1->SetRootNode(false);
emit(MacroSegmentOrderChanged());
}
void AdvSceneSwitcher::MoveMacroConditionUp(int idx)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (idx < 1 || idx >= (int)macro->Conditions().size()) {
return;
}
SwapConditions(macro.get(), idx, idx - 1);
HighlightCondition(idx - 1);
}
void AdvSceneSwitcher::MoveMacroConditionDown(int idx)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (idx < 0 || idx >= (int)macro->Conditions().size() - 1) {
return;
}
SwapConditions(macro.get(), idx, idx + 1);
HighlightCondition(idx + 1);
}
void AdvSceneSwitcher::MacroConditionSelectionChanged(int idx)
{
SetupMacroSegmentSelection(MacroSection::CONDITIONS, idx);
}
void AdvSceneSwitcher::MacroConditionReorder(int to, int from)
{
auto macro = GetSelectedMacro();
if (!macro) {
return;
}
if (to == from || from < 0 || from > (int)macro->Conditions().size() ||
to < 0 || to > (int)macro->Conditions().size()) {
return;
}
{
auto lock = LockContext();
auto condition = macro->Conditions().at(from);
if (to == 0) {
condition->SetLogicType(Logic::Type::ROOT_NONE);
static_cast<MacroConditionEdit *>(
ui->conditionsList->WidgetAt(from))
->SetRootNode(true);
macro->Conditions().at(0)->SetLogicType(
Logic::Type::AND);
static_cast<MacroConditionEdit *>(
ui->conditionsList->WidgetAt(0))
->SetRootNode(false);
}
if (from == 0) {
condition->SetLogicType(Logic::Type::AND);
static_cast<MacroConditionEdit *>(
ui->conditionsList->WidgetAt(from))
->SetRootNode(false);
macro->Conditions().at(1)->SetLogicType(
Logic::Type::ROOT_NONE);
static_cast<MacroConditionEdit *>(
ui->conditionsList->WidgetAt(1))
->SetRootNode(true);
}
macro->Conditions().erase(macro->Conditions().begin() + from);
macro->Conditions().insert(macro->Conditions().begin() + to,
condition);
macro->UpdateConditionIndices();
ui->conditionsList->ContentLayout()->insertItem(
to, ui->conditionsList->ContentLayout()->takeAt(from));
SetConditionData(*macro);
}
HighlightCondition(to);
emit(MacroSegmentOrderChanged());
}
} // namespace advss

1824
lib/macro/macro-edit.cpp Normal file

File diff suppressed because it is too large Load Diff

144
lib/macro/macro-edit.hpp Normal file
View File

@@ -0,0 +1,144 @@
#pragma once
#include "condition-logic.hpp"
#include <ui_macro-edit.h>
namespace advss {
class Macro;
class MacroSegment;
/*******************************************************************************
* Advanced Scene Switcher window
*******************************************************************************/
class MacroEdit : public QWidget {
Q_OBJECT
public:
MacroEdit(QWidget *parent, QStringList helpMsg = {});
void SetMacro(const std::shared_ptr<Macro> &);
void ClearSegmentWidgetCacheFor(Macro *) const;
void SetControlsDisabled(bool disable) const;
void HighlightAction(int idx, QColor color = QColor(Qt::green)) const;
void HighlightElseAction(int idx,
QColor color = QColor(Qt::green)) const;
void HighlightCondition(int idx,
QColor color = QColor(Qt::green)) const;
void ResetConditionHighlights();
void ResetActionHighlights();
void SetActionData(Macro &m) const;
void SetElseActionData(Macro &m) const;
void SetConditionData(Macro &m) const;
void SwapActions(Macro *m, int pos1, int pos2);
void SwapElseActions(Macro *m, int pos1, int pos2);
void SwapConditions(Macro *m, int pos1, int pos2);
void CopyMacroSegment();
void PasteMacroSegment();
bool IsEmpty() const;
void ShowAllMacroSections();
private slots:
void on_conditionAdd_clicked();
void on_conditionRemove_clicked();
void on_conditionTop_clicked();
void on_conditionUp_clicked();
void on_conditionDown_clicked();
void on_conditionBottom_clicked();
void on_actionAdd_clicked();
void on_actionRemove_clicked();
void on_actionTop_clicked();
void on_actionUp_clicked();
void on_actionDown_clicked();
void on_actionBottom_clicked();
void on_toggleElseActions_clicked() const;
void on_elseActionAdd_clicked();
void on_elseActionRemove_clicked();
void on_elseActionTop_clicked();
void on_elseActionUp_clicked();
void on_elseActionDown_clicked();
void on_elseActionBottom_clicked();
void UpMacroSegmentHotkey();
void DownMacroSegmentHotkey();
void DeleteMacroSegmentHotkey();
void ShowMacroActionsContextMenu(const QPoint &);
void ShowMacroElseActionsContextMenu(const QPoint &);
void ShowMacroConditionsContextMenu(const QPoint &);
void ExpandAllActions() const;
void ExpandAllElseActions() const;
void ExpandAllConditions() const;
void CollapseAllActions() const;
void CollapseAllElseActions() const;
void CollapseAllConditions() const;
void MinimizeActions() const;
void MaximizeActions() const;
void MinimizeElseActions() const;
void MaximizeElseActions() const;
void MinimizeConditions() const;
void MaximizeConditions() const;
void SetElseActionsStateToHidden() const;
void SetElseActionsStateToVisible() const;
void MacroActionSelectionChanged(int idx);
void MacroActionReorder(int to, int target);
void AddMacroAction(Macro *macro, int idx, const std::string &id,
obs_data_t *data);
void AddMacroAction(int idx);
void RemoveMacroAction(int idx);
void MoveMacroActionUp(int idx);
void MoveMacroActionDown(int idx);
void MacroElseActionSelectionChanged(int idx);
void MacroElseActionReorder(int to, int target);
void AddMacroElseAction(Macro *macro, int idx, const std::string &id,
obs_data_t *data);
void AddMacroElseAction(int idx);
void RemoveMacroElseAction(int idx);
void MoveMacroElseActionUp(int idx);
void MoveMacroElseActionDown(int idx);
void MacroConditionSelectionChanged(int idx);
void MacroConditionReorder(int to, int target);
void AddMacroCondition(int idx);
void AddMacroCondition(Macro *macro, int idx, const std::string &id,
obs_data_t *data, Logic::Type logic);
void RemoveMacroCondition(int idx);
void MoveMacroConditionUp(int idx);
void MoveMacroConditionDown(int idx);
void HighlightControls() const;
signals:
void MacroAdded(const QString &name);
void MacroRemoved(const QString &name);
void MacroRenamed(const QString &oldName, const QString &newName);
void MacroSegmentOrderChanged();
void SegmentTempVarsChanged(MacroSegment *);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
enum class MacroSection { CONDITIONS, ACTIONS, ELSE_ACTIONS };
void PopulateMacroActions(Macro &m, uint32_t afterIdx = 0);
void PopulateMacroElseActions(Macro &m, uint32_t afterIdx = 0);
void PopulateMacroConditions(Macro &m, uint32_t afterIdx = 0);
void SetupMacroSegmentSelection(MacroSection type, int idx);
void
SetupContextMenu(const QPoint &pos,
const std::function<void(MacroEdit *, int)> &remove,
const std::function<void(MacroEdit *)> &expand,
const std::function<void(MacroEdit *)> &collapse,
const std::function<void(MacroEdit *)> &maximize,
const std::function<void(MacroEdit *)> &minimize,
MacroSegmentList *list);
void RunSegmentHighlightChecks();
bool ElseSectionIsVisible() const;
MacroSection lastInteracted = MacroSection::CONDITIONS;
int currentConditionIdx = -1;
int currentActionIdx = -1;
int currentElseActionIdx = -1;
std::shared_ptr<Macro> _currentMacro;
std::unique_ptr<Ui_MacroEdit> ui;
};
} // namespace advss

View File

@@ -10,11 +10,12 @@ MacroList::MacroList(QWidget *parent, bool allowDuplicates, bool reorder)
: ListEditor(parent, reorder),
_allowDuplicates(allowDuplicates)
{
QWidget::connect(window(),
QWidget::connect(GetSettingsWindow(),
SIGNAL(MacroRenamed(const QString &, const QString &)),
this,
SLOT(MacroRename(const QString &, const QString &)));
QWidget::connect(window(), SIGNAL(MacroRemoved(const QString &)), this,
QWidget::connect(GetSettingsWindow(),
SIGNAL(MacroRemoved(const QString &)), this,
SLOT(MacroRemove(const QString &)));
UpdateListSize();
}

View File

@@ -11,10 +11,14 @@ namespace advss {
MacroRunButton::MacroRunButton(QWidget *parent) : QPushButton(parent)
{
installEventFilter(this);
auto parentWindow = window();
if (parentWindow) {
parentWindow->installEventFilter(this);
}
// GetSettingsWindow() might still return null while this constructor is called
QTimer::singleShot(0, this, [this]() {
auto parentWindow = GetSettingsWindow();
if (parentWindow) {
parentWindow->installEventFilter(this);
}
});
setToolTip(obs_module_text("AdvSceneSwitcher.macroTab.run.tooltip"));

View File

@@ -13,7 +13,7 @@ struct MacroSegmentCopyInfo {
};
static MacroSegmentCopyInfo copyInfo;
void AdvSceneSwitcher::CopyMacroSegment()
void MacroEdit::CopyMacroSegment()
{
copyInfo.segment.reset();
copyInfo.type = MacroSegmentCopyInfo::Type::NONE;
@@ -23,7 +23,7 @@ void AdvSceneSwitcher::CopyMacroSegment()
return;
}
auto macro = GetSelectedMacro();
auto macro = _currentMacro;
if (!macro) {
return;
}
@@ -43,13 +43,13 @@ void AdvSceneSwitcher::CopyMacroSegment()
}
}
void AdvSceneSwitcher::PasteMacroSegment()
void MacroEdit::PasteMacroSegment()
{
if (copyInfo.type == MacroSegmentCopyInfo::Type::NONE) {
return;
}
auto macro = GetSelectedMacro();
auto macro = _currentMacro;
if (!macro || !copyInfo.segment) {
return;
}
@@ -113,14 +113,14 @@ void SetCopySegmentTargetActionType(bool setToElseAction)
}
}
void SetupSegmentCopyPasteShortcutHandlers(AdvSceneSwitcher *window)
void SetupSegmentCopyPasteShortcutHandlers(MacroEdit *edit)
{
auto copyShortcut = new QShortcut(QKeySequence("Ctrl+C"), window);
QWidget::connect(copyShortcut, &QShortcut::activated, window,
&AdvSceneSwitcher::CopyMacroSegment);
auto pasteShortcut = new QShortcut(QKeySequence("Ctrl+V"), window);
QWidget::connect(pasteShortcut, &QShortcut::activated, window,
&AdvSceneSwitcher::PasteMacroSegment);
auto copyShortcut = new QShortcut(QKeySequence("Ctrl+C"), edit);
QWidget::connect(copyShortcut, &QShortcut::activated, edit,
&MacroEdit::CopyMacroSegment);
auto pasteShortcut = new QShortcut(QKeySequence("Ctrl+V"), edit);
QWidget::connect(pasteShortcut, &QShortcut::activated, edit,
&MacroEdit::PasteMacroSegment);
}
} // namespace advss

View File

@@ -1,10 +1,10 @@
namespace advss {
class AdvSceneSwitcher;
class MacroEdit;
bool MacroSegmentIsInClipboard();
bool MacroActionIsInClipboard();
void SetCopySegmentTargetActionType(bool setToElseAction);
void SetupSegmentCopyPasteShortcutHandlers(AdvSceneSwitcher *window);
void SetupSegmentCopyPasteShortcutHandlers(MacroEdit *edit);
} // namespace advss

View File

@@ -17,27 +17,39 @@ bool MacroSegmentList::_useCache = true;
MacroSegmentList::MacroSegmentList(QWidget *parent)
: QScrollArea(parent),
_stackedWidget(new QStackedWidget(this)),
_layout(new QVBoxLayout),
_contentLayout(new QVBoxLayout),
_helpMsg(new QLabel)
_helpMsg(new QLabel(this))
{
_helpMsg->setWordWrap(true);
_helpMsg->setAlignment(Qt::AlignCenter);
auto helpWidget = new QWidget(this);
auto helpLayout = new QVBoxLayout(helpWidget);
helpLayout->addWidget(_helpMsg);
helpLayout->setAlignment(Qt::AlignCenter);
auto contentWidget = new QWidget(this);
contentWidget->setLayout(_contentLayout);
_contentLayout->setSpacing(0);
auto helperLayout = new QGridLayout();
helperLayout->addWidget(_helpMsg, 0, 0,
Qt::AlignHCenter | Qt::AlignVCenter);
helperLayout->addLayout(_contentLayout, 0, 0);
helperLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
_layout->addLayout(helperLayout, 10);
_layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding,
QSizePolicy::Expanding));
auto wrapper = new QWidget;
wrapper->setLayout(_layout);
setWidget(wrapper);
auto contentWrapper = new QWidget(this);
auto wrapperLayout = new QVBoxLayout(contentWrapper);
wrapperLayout->setContentsMargins(0, 0, 0, 0);
wrapperLayout->addWidget(contentWidget);
// Move macro segments to the top of the list
wrapperLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding,
QSizePolicy::Expanding));
_stackedWidget->addWidget(helpWidget);
_stackedWidget->addWidget(contentWrapper);
setWidget(_stackedWidget);
setWidgetResizable(true);
setAcceptDrops(true);
SetHelpMsgVisible(true);
connect(verticalScrollBar(), &QScrollBar::valueChanged, this,
[this]() { SetupVisibleMacroSegmentWidgets(); });
}
@@ -107,9 +119,11 @@ void MacroSegmentList::SetHelpMsg(const QString &msg) const
_helpMsg->setText(msg);
}
void MacroSegmentList::SetHelpMsgVisible(bool visible) const
void MacroSegmentList::SetHelpMsgVisible(bool visible)
{
_helpMsg->setVisible(visible);
_stackedWidget->setCurrentIndex(visible ? 0 : 1);
adjustSize();
updateGeometry();
}
void MacroSegmentList::Insert(int idx, QWidget *widget)
@@ -117,23 +131,33 @@ void MacroSegmentList::Insert(int idx, QWidget *widget)
widget->installEventFilter(this);
_contentLayout->insertWidget(idx, widget);
SetupVisibleMacroSegmentWidgets();
SetHelpMsgVisible(false);
adjustSize();
updateGeometry();
}
void MacroSegmentList::Add(QWidget *widget)
{
widget->installEventFilter(this);
_contentLayout->addWidget(widget);
SetupVisibleMacroSegmentWidgets();
Insert(_contentLayout->count(), widget);
}
void MacroSegmentList::Remove(int idx) const
void MacroSegmentList::Remove(int idx)
{
DeleteLayoutItemWidget(_contentLayout->takeAt(idx));
adjustSize();
updateGeometry();
if (IsEmpty()) {
SetHelpMsgVisible(true);
}
}
void MacroSegmentList::Clear(int idx) const
void MacroSegmentList::Clear(int idx)
{
ClearLayout(_contentLayout, idx);
adjustSize();
updateGeometry();
SetHelpMsgVisible(true);
}
void MacroSegmentList::SetCachingEnabled(bool enable)
@@ -178,6 +202,8 @@ bool MacroSegmentList::PopulateWidgetsFromCache(const Macro *macro)
widget->show();
}
adjustSize();
updateGeometry();
return true;
}
@@ -411,6 +437,24 @@ void MacroSegmentList::SetVisibilityCheckEnable(bool enable)
}
}
bool MacroSegmentList::IsEmpty() const
{
return _contentLayout->count() == 0;
}
QSize MacroSegmentList::minimumSizeHint() const
{
return _stackedWidget->currentWidget()->minimumSizeHint();
}
QSize MacroSegmentList::sizeHint() const
{
const auto contentSize = _stackedWidget->currentWidget()->sizeHint();
const auto hint =
QSize(width(), contentSize.height() + 2 * frameWidth());
return hint;
}
void MacroSegmentList::SetupVisibleMacroSegmentWidgets()
{
if (!_checkVisibility) {
@@ -428,6 +472,7 @@ void MacroSegmentList::SetupVisibleMacroSegmentWidgets()
segment->SetupWidgets();
}
updateGeometry();
}
int MacroSegmentList::GetSegmentIndexFromPos(const QPoint &pos) const

View File

@@ -1,12 +1,14 @@
#pragma once
#include "macro-segment.hpp"
#include <QWidget>
#include <QScrollArea>
#include <QVBoxLayout>
#include <QLabel>
#include <thread>
#include <QLabel>
#include <QScrollArea>
#include <QStackedWidget>
#include <QVBoxLayout>
#include <QWidget>
namespace advss {
class Macro;
@@ -17,51 +19,63 @@ class MacroSegmentList : public QScrollArea {
public:
MacroSegmentList(QWidget *parent = nullptr);
~MacroSegmentList();
void SetHelpMsg(const QString &msg) const;
void SetHelpMsgVisible(bool visible) const;
void SetHelpMsgVisible(bool visible);
MacroSegmentEdit *WidgetAt(int idx) const;
MacroSegmentEdit *WidgetAt(const QPoint &) const;
int IndexAt(const QPoint &) const;
void Insert(int idx, QWidget *widget);
void Add(QWidget *widget);
void Remove(int idx) const;
void Clear(int idx = 0) const; // Clear all elements >= idx
void Remove(int idx);
void Clear(int idx = 0); // Clear all elements >= idx
bool IsEmpty() const;
static void SetCachingEnabled(bool enable);
void CacheCurrentWidgetsFor(const Macro *);
bool PopulateWidgetsFromCache(const Macro *);
void ClearWidgetsFromCacheFor(const Macro *);
void SetVisibilityCheckEnable(bool enable);
void Highlight(int idx, QColor color = QColor(Qt::green));
void SetCollapsed(bool) const;
void SetSelection(int idx) const;
QVBoxLayout *ContentLayout() const { return _contentLayout; }
void SetVisibilityCheckEnable(bool enable);
QSize minimumSizeHint() const override;
QSize sizeHint() const override;
signals:
void SelectionChanged(int idx);
void Reorder(int source, int target);
protected:
bool eventFilter(QObject *object, QEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
void resizeEvent(QResizeEvent *event);
bool eventFilter(QObject *object, QEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void dragLeaveEvent(QDragLeaveEvent *event) override;
void dragEnterEvent(QDragEnterEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
void dropEvent(QDropEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
private:
void SetupVisibleMacroSegmentWidgets();
void ClearWidgetCache();
int GetSegmentIndexFromPos(const QPoint &) const;
bool IsInListArea(const QPoint &) const;
QRect GetContentItemRectWithPadding(int idx) const;
int GetDragIndex(const QPoint &) const;
int GetDropIndex(const QPoint &) const;
void CheckScroll() const;
void CheckDropLine(const QPoint &);
bool IsInListArea(const QPoint &) const;
QRect GetContentItemRectWithPadding(int idx) const;
void HideLastDropLine();
void ClearWidgetCache();
int _dragPosition = -1;
int _dropLineIdx = -1;
@@ -69,6 +83,7 @@ private:
std::thread _autoScrollThread;
std::atomic_bool _autoScroll{false};
QStackedWidget *_stackedWidget;
QVBoxLayout *_layout;
QVBoxLayout *_contentLayout;
QLabel *_helpMsg;

View File

@@ -31,7 +31,8 @@ MacroSegmentSelection::MacroSegmentSelection(QWidget *parent, Type type,
_index,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this, SLOT(IndexChanged(const NumberVariable<int> &)));
QWidget::connect(window(), SIGNAL(MacroSegmentOrderChanged()), this,
QWidget::connect(GetSettingsWindow(),
SIGNAL(MacroSegmentOrderChanged()), this,
SLOT(MacroSegmentOrderChanged()));
auto layout = new QHBoxLayout;

View File

@@ -257,20 +257,25 @@ MacroSegmentEdit::MacroSegmentEdit(QWidget *parent)
QWidget::connect(_section, &Section::Collapsed, this,
&MacroSegmentEdit::Collapsed);
// Macro signals
QWidget::connect(parent, SIGNAL(MacroAdded(const QString &)), this,
QWidget::connect(GetSettingsWindow(),
SIGNAL(MacroAdded(const QString &)), this,
SIGNAL(MacroAdded(const QString &)));
QWidget::connect(parent, SIGNAL(MacroRemoved(const QString &)), this,
QWidget::connect(GetSettingsWindow(),
SIGNAL(MacroRemoved(const QString &)), this,
SIGNAL(MacroRemoved(const QString &)));
QWidget::connect(
parent, SIGNAL(MacroRenamed(const QString &, const QString &)),
this, SIGNAL(MacroRenamed(const QString &, const QString &)));
GetSettingsWindow(),
SIGNAL(MacroRenamed(const QString &, const QString &)), this,
SIGNAL(MacroRenamed(const QString &, const QString &)));
// Scene group signals
QWidget::connect(parent, SIGNAL(SceneGroupAdded(const QString &)), this,
QWidget::connect(GetSettingsWindow(),
SIGNAL(SceneGroupAdded(const QString &)), this,
SIGNAL(SceneGroupAdded(const QString &)));
QWidget::connect(parent, SIGNAL(SceneGroupRemoved(const QString &)),
this, SIGNAL(SceneGroupRemoved(const QString &)));
QWidget::connect(GetSettingsWindow(),
SIGNAL(SceneGroupRemoved(const QString &)), this,
SIGNAL(SceneGroupRemoved(const QString &)));
QWidget::connect(
parent,
GetSettingsWindow(),
SIGNAL(SceneGroupRenamed(const QString &, const QString)), this,
SIGNAL(SceneGroupRenamed(const QString &, const QString)));

View File

@@ -49,7 +49,7 @@ void MacroSelection::SetCurrentMacro(const MacroRef &macro)
void MacroSelection::HideSelectedMacro()
{
auto ssWindow = static_cast<AdvSceneSwitcher *>(window());
auto ssWindow = static_cast<AdvSceneSwitcher *>(GetSettingsWindow());
if (!ssWindow) {
return;
}

View File

@@ -478,7 +478,14 @@ bool MacroSettingsDialog::AskForSettings(QWidget *parent,
macro->SetSkipExecOnStart(dialog._currentSkipOnStartup->isChecked());
macro->SetStopActionsIfNotDone(
dialog._currentStopActionsIfNotDone->isChecked());
macro->EnableDock(dialog._currentMacroRegisterDock->isChecked());
// Only apply "on change" to avoid recreation of the dock widget
const bool enableDock = dialog._currentMacroRegisterDock->isChecked();
if (macro->DockEnabled() != enableDock) {
macro->EnableDock(
dialog._currentMacroRegisterDock->isChecked());
}
macro->SetDockHasRunButton(
dialog._currentMacroDockAddRunButton->isChecked());
macro->SetDockHasPauseButton(

File diff suppressed because it is too large Load Diff

View File

@@ -414,6 +414,20 @@ void MacroTreeModel::Add(std::shared_ptr<Macro> item)
QItemSelectionModel::Select);
}
void MacroTreeModel::MoveToBeginningOfGroup(std::shared_ptr<Macro> item,
std::shared_ptr<Macro> group)
{
auto it = std::find(_macros.begin(), _macros.end(), item);
assert(it != _macros.end());
std::shared_ptr<Macro> tmp = *it;
_macros.erase(it);
it = std::find(_macros.begin(), _macros.end(), group);
assert(it != _macros.end());
_macros.insert(std::next(it), tmp);
Reset(_macros);
}
void MacroTreeModel::Remove(std::shared_ptr<Macro> item)
{
auto lock = LockContext();
@@ -789,6 +803,13 @@ void MacroTree::Add(std::shared_ptr<Macro> item,
assert(GetModel()->IsInValidState());
}
void MacroTree::AddToGroup(std::shared_ptr<Macro> item,
std::shared_ptr<Macro> group) const
{
GetModel()->Add(item);
GetModel()->MoveToBeginningOfGroup(item, group);
}
std::shared_ptr<Macro> MacroTree::GetCurrentMacro() const
{
return GetModel()->GetCurrentMacro();
@@ -1160,6 +1181,28 @@ bool MacroTree::SelectionEmpty() const
return selectedIndexes().empty();
}
bool MacroTree::GroupsExist() const
{
for (const auto &macro : GetMacros()) {
if (macro->IsGroup()) {
return true;
}
}
return false;
}
void MacroTree::ExpandGroup(std::shared_ptr<Macro> item) const
{
auto *mtm = GetModel();
mtm->ExpandGroup(item);
}
void MacroTree::CollapseGroup(std::shared_ptr<Macro> item) const
{
auto *mtm = GetModel();
mtm->CollapseGroup(item);
}
void MacroTree::MoveItemBefore(const std::shared_ptr<Macro> &item,
const std::shared_ptr<Macro> &after) const
{
@@ -1260,6 +1303,26 @@ void MacroTree::UngroupSelectedGroups()
assert(GetModel()->IsInValidState());
}
void MacroTree::ExpandAll()
{
for (const auto &macro : GetMacros()) {
if (!macro->IsGroup()) {
continue;
}
ExpandGroup(macro);
}
}
void MacroTree::CollapseAll()
{
for (const auto &macro : GetMacros()) {
if (!macro->IsGroup()) {
continue;
}
CollapseGroup(macro);
}
}
void MacroTree::SelectionChangedHelper(const QItemSelection &,
const QItemSelection &)
{

View File

@@ -91,6 +91,8 @@ private:
void MoveItemAfter(const std::shared_ptr<Macro> &item,
const std::shared_ptr<Macro> &after);
void Add(std::shared_ptr<Macro> item);
void MoveToBeginningOfGroup(std::shared_ptr<Macro> item,
std::shared_ptr<Macro>);
void Remove(std::shared_ptr<Macro> item);
std::shared_ptr<Macro> Neighbor(const std::shared_ptr<Macro> &m,
bool above) const;
@@ -126,6 +128,8 @@ public:
void Reset(std::deque<std::shared_ptr<Macro>> &, bool highlight);
void Add(std::shared_ptr<Macro> item,
std::shared_ptr<Macro> after = {}) const;
void AddToGroup(std::shared_ptr<Macro> item,
std::shared_ptr<Macro> group) const;
void Remove(std::shared_ptr<Macro> item) const;
void Up(std::shared_ptr<Macro> item) const;
void Down(std::shared_ptr<Macro> item) const;
@@ -135,10 +139,15 @@ public:
bool GroupedItemsSelected() const;
bool SingleItemSelected() const;
bool SelectionEmpty() const;
bool GroupsExist() const;
void ExpandGroup(std::shared_ptr<Macro> item) const;
void CollapseGroup(std::shared_ptr<Macro> item) const;
public slots:
void GroupSelectedItems();
void UngroupSelectedGroups();
void ExpandAll();
void CollapseAll();
void SelectionChangedHelper(const QItemSelection &,
const QItemSelection &);

View File

@@ -984,7 +984,7 @@ bool Macro::Load(obs_data_t *obj)
auto newEntry = MacroActionFactory::Create(id, this);
if (newEntry) {
_elseActions.emplace_back(newEntry);
auto action = _actions.back().get();
auto action = _elseActions.back().get();
action->WithLock([action, &arrayObj]() {
action->Load(arrayObj);
});

View File

@@ -101,7 +101,7 @@ public:
bool firstBoot = true;
bool transitionActive = false;
bool sceneColletionStop = false;
bool sceneCollectionStop = false;
bool obsIsShuttingDown = false;
bool firstInterval = true;
bool firstIntervalAfterStop = true;

View File

@@ -0,0 +1,106 @@
#include "resizable-widget.hpp"
namespace advss {
ResizableWidget::ResizableWidget(QWidget *parent) : QWidget(parent) {}
void ResizableWidget::SetResizingEnabled(bool enable)
{
setMouseTracking(enable);
_customHeight = enable ? sizeHint().height() : 0;
auto pol = sizePolicy();
pol.setVerticalPolicy(enable ? QSizePolicy::Fixed
: QSizePolicy::Preferred);
_resizingEnabled = enable;
}
void ResizableWidget::mousePressEvent(QMouseEvent *event)
{
if (!_resizingEnabled) {
QWidget::mousePressEvent(event);
return;
}
if (IsInResizeArea(event->pos())) {
_resizing = true;
_lastMousePos = event->globalPosition().toPoint();
event->accept();
} else {
QWidget::mousePressEvent(event);
}
}
void ResizableWidget::mouseMoveEvent(QMouseEvent *event)
{
if (!_resizingEnabled) {
QWidget::mouseMoveEvent(event);
return;
}
if (_resizing) {
const int dy = event->globalPosition().toPoint().y() -
_lastMousePos.y();
const int baseHeight = _customHeight == 0 ? height()
: _customHeight;
const int newHeight = baseHeight + dy;
_customHeight =
std::clamp(newHeight, minimumHeight(), maximumHeight());
updateGeometry();
_lastMousePos = event->globalPosition().toPoint();
event->accept();
} else {
setCursor(IsInResizeArea(event->pos()) ? Qt::SizeVerCursor
: Qt::ArrowCursor);
QWidget::mouseMoveEvent(event);
}
}
void ResizableWidget::mouseReleaseEvent(QMouseEvent *event)
{
if (_resizing) {
event->accept();
_resizing = false;
} else {
QWidget::mouseReleaseEvent(event);
}
}
void ResizableWidget::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
if (!_resizingEnabled) {
return;
}
// Draw a triangle in bottom-right as resize indicator
QPainter painter(this);
QPolygon triangle;
triangle << QPoint(width() - 1, height() - _gripSize)
<< QPoint(width() - _gripSize, height() - 1)
<< QPoint(width() - 1, height() - 1);
painter.setBrush(Qt::gray);
painter.drawPolygon(triangle);
}
QSize ResizableWidget::sizeHint() const
{
if (!_resizingEnabled) {
return QWidget::sizeHint();
}
if (_customHeight == 0) {
return QWidget::sizeHint();
}
return QSize(width(), _customHeight);
}
bool ResizableWidget::IsInResizeArea(const QPoint &pos) const
{
return QRect(width() - _gripSize, height() - _gripSize, _gripSize,
_gripSize)
.contains(pos);
}
} // namespace advss

View File

@@ -0,0 +1,34 @@
#pragma once
#include <QMouseEvent>
#include <QPainter>
#include <QWidget>
namespace advss {
class ResizableWidget : public QWidget {
Q_OBJECT
public:
ResizableWidget(QWidget *parent = nullptr);
protected:
void SetResizingEnabled(bool enable);
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *event) override;
QSize sizeHint() const override;
int GetCustomHeight() const { return _customHeight; }
void SetCustomHeight(int value) { _customHeight = value; }
private:
bool IsInResizeArea(const QPoint &pos) const;
bool _resizingEnabled = false;
bool _resizing = false;
QPoint _lastMousePos;
int _customHeight = 0;
const int _gripSize = 15;
};
} // namespace advss

View File

@@ -314,12 +314,14 @@ SceneSelectionWidget::SceneSelectionWidget(QWidget *parent, bool variables,
SLOT(SelectionChanged(int)));
// Scene groups
QWidget::connect(window(), SIGNAL(SceneGroupAdded(const QString &)),
this, SLOT(ItemAdd(const QString &)));
QWidget::connect(window(), SIGNAL(SceneGroupRemoved(const QString &)),
this, SLOT(ItemRemove(const QString &)));
QWidget::connect(GetSettingsWindow(),
SIGNAL(SceneGroupAdded(const QString &)), this,
SLOT(ItemAdd(const QString &)));
QWidget::connect(GetSettingsWindow(),
SIGNAL(SceneGroupRemoved(const QString &)), this,
SLOT(ItemRemove(const QString &)));
QWidget::connect(
window(),
GetSettingsWindow(),
SIGNAL(SceneGroupRenamed(const QString &, const QString &)),
this, SLOT(ItemRename(const QString &, const QString &)));

View File

@@ -44,6 +44,11 @@ Section::Section(const int animationDuration, QWidget *parent)
void Section::Collapse(bool collapse)
{
if (_contentHeight != _content->sizeHint().height()) {
_contentHeight = _content->sizeHint().height();
}
SetupAnimations();
_toggleButton->setChecked(collapse);
_toggleButton->setArrowType(collapse ? Qt::ArrowType::RightArrow
: Qt::ArrowType::DownArrow);
@@ -72,7 +77,7 @@ void Section::SetContent(QWidget *w, bool collapsed)
delete _contentArea;
// Setup contentArea
_contentArea = new QScrollArea(this);
_contentArea = new QWidget(this);
_contentArea->setObjectName("macroSegmentContent");
_contentArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
_contentArea->setStyleSheet(
@@ -93,12 +98,11 @@ void Section::SetContent(QWidget *w, bool collapsed)
SetupAnimations();
setMinimumHeight(_headerHeight);
if (collapsed) {
this->setMinimumHeight(_headerHeight);
_contentArea->setMaximumHeight(0);
} else {
this->setMinimumHeight(_headerHeight + _contentHeight);
_contentArea->setMaximumHeight(_contentHeight);
_contentArea->setMaximumHeight(QWIDGETSIZE_MAX);
}
const QSignalBlocker b(_toggleButton);
_toggleButton->setChecked(collapsed);
@@ -120,23 +124,6 @@ void Section::SetCollapsed(bool collapsed)
Collapse(collapsed);
}
bool Section::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::Resize && !_transitioning && !_collapsed) {
if (_contentHeight != _content->sizeHint().height()) {
_contentHeight = _content->sizeHint().height();
setMaximumHeight(_headerHeight + _contentHeight);
setMinimumHeight(_headerHeight + _contentHeight);
_contentArea->setMaximumHeight(_contentHeight);
// Note: Calling this too frequently inside this event
// filter will cause a segfault for some reason
SetupAnimations();
}
setMinimumWidth(_content->sizeHint().width());
}
return QObject::eventFilter(obj, event);
}
void Section::SetupAnimations()
{
if (_toggleAnimation) {
@@ -160,7 +147,7 @@ void Section::SetupAnimations()
SectionAnimation->setEndValue(_headerHeight + _contentHeight);
}
QPropertyAnimation *contentAnimation =
auto contentAnimation =
static_cast<QPropertyAnimation *>(_toggleAnimation->animationAt(
_toggleAnimation->animationCount() - 1));
contentAnimation->setDuration(_animationDuration);
@@ -185,6 +172,14 @@ void Section::CleanUpPreviousContent()
void Section::AnimationFinish()
{
_transitioning = false;
// Allow resizing if we are not currently transitioning or collapsed
if (!_collapsed) {
setMinimumHeight(0);
setMaximumHeight(QWIDGETSIZE_MAX);
_contentArea->setMaximumHeight(QWIDGETSIZE_MAX);
}
emit AnimationFinished();
}

View File

@@ -3,7 +3,6 @@
#include <QFrame>
#include <QGridLayout>
#include <QParallelAnimationGroup>
#include <QScrollArea>
#include <QToolButton>
#include <QWidget>
@@ -21,9 +20,6 @@ public:
void AddHeaderWidget(QWidget *);
void SetCollapsed(bool);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private slots:
void AnimationFinish();
void Collapse(bool collapse);
@@ -41,7 +37,7 @@ private:
QFrame *_headerLine;
QParallelAnimationGroup *_toggleAnimation = nullptr;
QParallelAnimationGroup *_contentAnimation = nullptr;
QScrollArea *_contentArea = nullptr;
QWidget *_contentArea = nullptr;
QWidget *_content = nullptr;
int _animationDuration;
std::atomic_bool _transitioning = {false};

View File

@@ -30,4 +30,36 @@ void LoadSplitterPos(QList<int> &sizes, obs_data_t *obj,
obs_data_array_release(array);
}
void CenterSplitterPosition(QSplitter *splitter)
{
SetSplitterPositionByFraction(splitter, 0.5);
}
void SetSplitterPositionByFraction(QSplitter *splitter, double fraction)
{
int value1 = (double)QWIDGETSIZE_MAX * fraction;
int value2 = (double)QWIDGETSIZE_MAX * (1.0 - fraction);
splitter->setSizes(QList<int>() << value1 << value2);
}
void MaximizeFirstSplitterEntry(QSplitter *splitter)
{
QList<int> newSizes;
newSizes << QWIDGETSIZE_MAX;
for (int i = 0; i < splitter->sizes().size() - 1; i++) {
newSizes << 0;
}
splitter->setSizes(newSizes);
}
void ReduceSizeOfSplitterIdx(QSplitter *splitter, int idx)
{
auto sizes = splitter->sizes();
int sum = sizes[0] + sizes[1];
int reducedSize = sum / 10;
sizes[idx] = reducedSize;
sizes[(idx + 1) % 2] = sum - reducedSize;
splitter->setSizes(sizes);
}
} // namespace advss

View File

@@ -2,7 +2,10 @@
#include "export-symbol-helper.hpp"
#include <obs-data.h>
#include <QList>
#include <QSplitter>
#include <string>
namespace advss {
@@ -12,4 +15,9 @@ void SaveSplitterPos(const QList<int> &sizes, obs_data_t *obj,
void LoadSplitterPos(QList<int> &sizes, obs_data_t *obj,
const std::string &name);
void CenterSplitterPosition(QSplitter *splitter);
void SetSplitterPositionByFraction(QSplitter *splitter, double fraction);
void MaximizeFirstSplitterEntry(QSplitter *splitter);
void ReduceSizeOfSplitterIdx(QSplitter *splitter, int idx);
} // namespace advss

View File

@@ -17,7 +17,11 @@ static std::vector<std::string> tabNames = {
"videoTab", "sceneGroupTab", "transitionsTab", "pauseTab",
};
static std::vector<int> tabOrder = std::vector<int>(tabNames.size());
static std::vector<int> &getTabOrderVector()
{
static std::vector<int> tabOrder = std::vector<int>(tabNames.size());
return tabOrder;
}
namespace {
struct TabCallbacks {
@@ -65,19 +69,14 @@ void ResetLastOpenedTab()
lastOpenedTab = -1;
}
void SaveTabOrder(obs_data_t *obj)
{
OBSDataArrayAutoRelease tabWidgetOrder = obs_data_array_create();
for (size_t i = 0; i < tabNames.size(); i++) {
OBSDataAutoRelease entry = obs_data_create();
obs_data_set_int(entry, tabNames[i].c_str(), tabOrder[i]);
obs_data_array_push_back(tabWidgetOrder, entry);
}
obs_data_set_array(obj, "tabWidgetOrder", tabWidgetOrder);
}
static bool tabWidgetOrderValid()
{
auto &tabOrder = getTabOrderVector();
if (tabNames.size() != tabOrder.size()) {
return false;
}
auto tmp = std::vector<int>(tabNames.size());
std::iota(tmp.begin(), tmp.end(), 0);
@@ -92,10 +91,29 @@ static bool tabWidgetOrderValid()
static void resetTabWidgetOrder()
{
auto &tabOrder = getTabOrderVector();
tabOrder = std::vector<int>(tabNames.size());
std::iota(tabOrder.begin(), tabOrder.end(), 0);
}
void SaveTabOrder(obs_data_t *obj)
{
auto &tabOrder = getTabOrderVector();
// Can happen when corrupting settings files
if (!tabWidgetOrderValid()) {
resetTabWidgetOrder();
}
OBSDataArrayAutoRelease tabWidgetOrder = obs_data_array_create();
for (size_t i = 0; i < tabNames.size(); i++) {
OBSDataAutoRelease entry = obs_data_create();
obs_data_set_int(entry, tabNames[i].c_str(), tabOrder[i]);
obs_data_array_push_back(tabWidgetOrder, entry);
}
obs_data_set_array(obj, "tabWidgetOrder", tabWidgetOrder);
}
void LoadTabOrder(obs_data_t *obj)
{
OBSDataArrayAutoRelease defaultTabWidgetOrder = obs_data_array_create();
@@ -107,6 +125,7 @@ void LoadTabOrder(obs_data_t *obj)
obs_data_set_default_array(obj, "tabWidgetOrder",
defaultTabWidgetOrder);
auto &tabOrder = getTabOrderVector();
tabOrder.clear();
OBSDataArrayAutoRelease tabWidgetOrder =
obs_data_get_array(obj, "tabWidgetOrder");
@@ -144,6 +163,8 @@ void SetTabOrder(QTabWidget *tabWidget)
resetTabWidgetOrder();
}
auto &tabOrder = getTabOrderVector();
auto bar = tabWidget->tabBar();
for (int i = 0; i < bar->count(); ++i) {
int curPos = findTabIndex(tabWidget, tabOrder[i]);
@@ -153,9 +174,10 @@ void SetTabOrder(QTabWidget *tabWidget)
}
}
QWidget::connect(bar, &QTabBar::tabMoved, [](int from, int to) {
std::swap(tabOrder[from], tabOrder[to]);
});
QWidget::connect(bar, &QTabBar::tabMoved,
[&tabOrder](int from, int to) {
std::swap(tabOrder[from], tabOrder[to]);
});
}
void SetCurrentTab(QTabWidget *tabWidget)

View File

@@ -18,5 +18,6 @@ void SetCurrentTab(QTabWidget *tabWidget);
void SetupOtherTabs(QTabWidget *tabWidget);
void SaveTabOrder(obs_data_t *obj);
void LoadTabOrder(obs_data_t *obj);
bool MacroTabIsInFocus();
} // namespace advss

View File

@@ -272,9 +272,10 @@ TempVariableSelection::TempVariableSelection(QWidget *parent)
SLOT(SelectionIdxChanged(int)));
QWidget::connect(_selection, SIGNAL(highlighted(int)), this,
SLOT(HighlightChanged(int)));
QWidget::connect(window(), SIGNAL(MacroSegmentOrderChanged()), this,
QWidget::connect(GetSettingsWindow(),
SIGNAL(MacroSegmentOrderChanged()), this,
SLOT(MacroSegmentsChanged()));
QWidget::connect(window(),
QWidget::connect(GetSettingsWindow(),
SIGNAL(SegmentTempVarsChanged(MacroSegment *)), this,
SLOT(SegmentTempVarsChanged(MacroSegment *)));
@@ -334,7 +335,8 @@ void TempVariableSelection::HighlightChanged(int idx)
void TempVariableSelection::PopulateSelection()
{
auto advssWindow = qobject_cast<AdvSceneSwitcher *>(window());
auto advssWindow =
qobject_cast<AdvSceneSwitcher *>(GetSettingsWindow());
if (!advssWindow) {
return;
}
@@ -367,7 +369,8 @@ void TempVariableSelection::PopulateSelection()
void TempVariableSelection::HighlightSelection(const TempVariableRef &var)
{
auto advssWindow = qobject_cast<AdvSceneSwitcher *>(window());
auto advssWindow =
qobject_cast<AdvSceneSwitcher *>(GetSettingsWindow());
if (!advssWindow) {
return;
}
@@ -394,7 +397,8 @@ QString TempVariableSelection::SetupInfoLabel()
{
auto currentSelection = _selection->itemData(_selection->currentIndex())
.value<TempVariableRef>();
auto advssWindow = qobject_cast<AdvSceneSwitcher *>(window());
auto advssWindow =
qobject_cast<AdvSceneSwitcher *>(GetSettingsWindow());
if (!advssWindow) {
_info->setToolTip("");
_info->hide();

View File

@@ -16,25 +16,28 @@ bool MacroActionAudio::_registered = MacroActionFactory::Register(
{MacroActionAudio::Create, MacroActionAudioEdit::Create,
"AdvSceneSwitcher.action.audio"});
static const std::map<MacroActionAudio::Action, std::string> actionTypes = {
{MacroActionAudio::Action::MUTE,
"AdvSceneSwitcher.action.audio.type.mute"},
{MacroActionAudio::Action::UNMUTE,
"AdvSceneSwitcher.action.audio.type.unmute"},
{MacroActionAudio::Action::SOURCE_VOLUME,
"AdvSceneSwitcher.action.audio.type.sourceVolume"},
{MacroActionAudio::Action::MASTER_VOLUME,
"AdvSceneSwitcher.action.audio.type.masterVolume"},
{MacroActionAudio::Action::SYNC_OFFSET,
"AdvSceneSwitcher.action.audio.type.syncOffset"},
{MacroActionAudio::Action::MONITOR,
"AdvSceneSwitcher.action.audio.type.monitor"},
{MacroActionAudio::Action::BALANCE,
"AdvSceneSwitcher.action.audio.type.balance"},
{MacroActionAudio::Action::ENABLE_ON_TRACK,
"AdvSceneSwitcher.action.audio.type.enableOnTrack"},
{MacroActionAudio::Action::DISABLE_ON_TRACK,
"AdvSceneSwitcher.action.audio.type.disableOnTrack"},
static const std::vector<std::pair<MacroActionAudio::Action, std::string>>
actionTypes = {
{MacroActionAudio::Action::MUTE,
"AdvSceneSwitcher.action.audio.type.mute"},
{MacroActionAudio::Action::UNMUTE,
"AdvSceneSwitcher.action.audio.type.unmute"},
{MacroActionAudio::Action::TOGGLE_MUTE,
"AdvSceneSwitcher.action.audio.type.toggleMute"},
{MacroActionAudio::Action::SOURCE_VOLUME,
"AdvSceneSwitcher.action.audio.type.sourceVolume"},
{MacroActionAudio::Action::MASTER_VOLUME,
"AdvSceneSwitcher.action.audio.type.masterVolume"},
{MacroActionAudio::Action::SYNC_OFFSET,
"AdvSceneSwitcher.action.audio.type.syncOffset"},
{MacroActionAudio::Action::MONITOR,
"AdvSceneSwitcher.action.audio.type.monitor"},
{MacroActionAudio::Action::BALANCE,
"AdvSceneSwitcher.action.audio.type.balance"},
{MacroActionAudio::Action::ENABLE_ON_TRACK,
"AdvSceneSwitcher.action.audio.type.enableOnTrack"},
{MacroActionAudio::Action::DISABLE_ON_TRACK,
"AdvSceneSwitcher.action.audio.type.disableOnTrack"},
};
static const std::map<MacroActionAudio::FadeType, std::string> fadeTypes = {
@@ -255,6 +258,9 @@ bool MacroActionAudio::PerformAction()
case Action::UNMUTE:
obs_source_set_muted(s, false);
break;
case Action::TOGGLE_MUTE:
obs_source_set_muted(s, !obs_source_muted(s));
break;
case Action::SOURCE_VOLUME:
case Action::MASTER_VOLUME:
if (_fade) {
@@ -287,7 +293,10 @@ bool MacroActionAudio::PerformAction()
void MacroActionAudio::LogAction() const
{
auto it = actionTypes.find(_action);
auto it = std::find_if(
actionTypes.begin(), actionTypes.end(),
[this](const std::pair<MacroActionAudio::Action, std::string>
&item) { return item.first == _action; });
if (it != actionTypes.end()) {
auto &[_, action] = *it;
ablog(LOG_INFO,
@@ -632,8 +641,7 @@ void MacroActionAudioEdit::SetWidgetVisibility()
if (_entryData->_action != MacroActionAudio::Action::MASTER_VOLUME &&
obs_get_version() >= MAKE_SEMANTIC_VERSION(29, 0, 0)) {
_actions->removeItem(_actions->findText(obs_module_text(
actionTypes.at(MacroActionAudio::Action::MASTER_VOLUME)
.c_str())));
"AdvSceneSwitcher.action.audio.type.masterVolume")));
}
updateGeometry();

View File

@@ -34,6 +34,7 @@ public:
BALANCE,
ENABLE_ON_TRACK,
DISABLE_ON_TRACK,
TOGGLE_MUTE,
};
enum class FadeType {

View File

@@ -396,9 +396,10 @@ void MacroActionFilterEdit::GetSettingsClicked()
case MacroActionFilter::SettingsInputMethod::JSON_STRING: {
const auto filters =
_entryData->_filter.GetFilters(_entryData->_source);
const auto settings = GetSourceSettings(
filters.empty() ? nullptr : filters.at(0), true);
_settingsString->setPlainText(
FormatJsonString(GetSourceSettings(
filters.empty() ? nullptr : filters.at(0))));
FormatJsonString(settings ? *settings : ""));
break;
}
}

View File

@@ -242,9 +242,9 @@ MacroActionProjectorEdit::MacroActionProjectorEdit(
_actions(new QComboBox()),
_types(new QComboBox()),
_windowTypes(new QComboBox()),
_scenes(new SceneSelectionWidget(window(), true, false, true, true,
_scenes(new SceneSelectionWidget(this, true, false, true, true,
true)),
_sources(new SourceSelectionWidget(window(), getSourcesList, true)),
_sources(new SourceSelectionWidget(this, getSourcesList, true)),
_monitors(new MonitorSelectionWidget(this)),
_projectorWindowName(new VariableLineEdit(this)),
_regex(new RegexConfigWidget(this)),

View File

@@ -1,6 +1,7 @@
#include "macro-action-random.hpp"
#include "layout-helpers.hpp"
#include "macro-helpers.hpp"
#include "ui-helpers.hpp"
#include <cstdlib>
@@ -105,7 +106,8 @@ MacroActionRandomEdit::MacroActionRandomEdit(
QWidget::connect(_list, SIGNAL(Removed(int)), this, SLOT(Remove(int)));
QWidget::connect(_list, SIGNAL(Replaced(int, const std::string &)),
this, SLOT(Replace(int, const std::string &)));
QWidget::connect(window(), SIGNAL(MacroRemoved(const QString &)), this,
QWidget::connect(GetSettingsWindow(),
SIGNAL(MacroRemoved(const QString &)), this,
SLOT(MacroRemove(const QString &)));
QWidget::connect(_allowRepeat, SIGNAL(stateChanged(int)), this,
SLOT(AllowRepeatChanged(int)));

View File

@@ -112,7 +112,7 @@ void MacroActionSceneLock::ResolveVariablesToFixedValues()
MacroActionSceneLockEdit::MacroActionSceneLockEdit(
QWidget *parent, std::shared_ptr<MacroActionSceneLock> entryData)
: QWidget(parent),
_scenes(new SceneSelectionWidget(window(), true, false, true, true)),
_scenes(new SceneSelectionWidget(this, true, false, true, true)),
_sources(new SceneItemSelectionWidget(parent)),
_actions(new QComboBox())
{

View File

@@ -224,7 +224,7 @@ static inline void populateTypeSelection(QComboBox *list)
MacroActionSwitchSceneEdit::MacroActionSwitchSceneEdit(
QWidget *parent, std::shared_ptr<MacroActionSwitchScene> entryData)
: QWidget(parent),
_scenes(new SceneSelectionWidget(window(), true, true, true)),
_scenes(new SceneSelectionWidget(this, true, true, true)),
_transitions(new TransitionSelectionWidget(this)),
_duration(new DurationSelection(parent, false)),
_blockUntilTransitionDone(new QCheckBox(obs_module_text(

View File

@@ -399,7 +399,7 @@ static inline void populateActionSelection(QComboBox *list)
MacroActionSceneTransformEdit::MacroActionSceneTransformEdit(
QWidget *parent, std::shared_ptr<MacroActionSceneTransform> entryData)
: QWidget(parent),
_scenes(new SceneSelectionWidget(window(), true, false, false, true)),
_scenes(new SceneSelectionWidget(this, true, false, false, true)),
_sources(new SceneItemSelectionWidget(parent)),
_action(new QComboBox()),
_rotation(new VariableDoubleSpinBox()),

View File

@@ -127,7 +127,7 @@ static inline void populateActionSelection(QComboBox *list)
MacroActionSceneVisibilityEdit::MacroActionSceneVisibilityEdit(
QWidget *parent, std::shared_ptr<MacroActionSceneVisibility> entryData)
: QWidget(parent),
_scenes(new SceneSelectionWidget(window(), true, false, true, true)),
_scenes(new SceneSelectionWidget(this, true, false, true, true)),
_sources(new SceneItemSelectionWidget(parent)),
_actions(new QComboBox())
{

View File

@@ -212,7 +212,7 @@ MacroActionSequenceEdit::MacroActionSequenceEdit(
SLOT(ContinueFromClicked()));
QWidget::connect(_restart, SIGNAL(stateChanged(int)), this,
SLOT(RestartChanged(int)));
QWidget::connect(window(), SIGNAL(MacroRemoved(const QString &)), this,
QWidget::connect(this, SIGNAL(MacroRemoved(const QString &)), this,
SLOT(MacroRemove(const QString &)));
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionChanged(int)));

View File

@@ -461,8 +461,10 @@ void MacroActionSourceEdit::GetSettingsClicked()
case MacroActionSource::SettingsInputMethod::INDIVIDUAL_TEMPVAR:
break;
case MacroActionSource::SettingsInputMethod::JSON_STRING:
_settingsString->setPlainText(FormatJsonString(
GetSourceSettings(_entryData->_source.GetSource())));
const auto settings = GetSourceSettings(
_entryData->_source.GetSource(), true);
_settingsString->setPlainText(
FormatJsonString(settings ? *settings : ""));
break;
}
}

View File

@@ -9,7 +9,7 @@ const std::string MacroActionSudioMode::id = "studio_mode";
bool MacroActionSudioMode::_registered = MacroActionFactory::Register(
MacroActionSudioMode::id,
{MacroActionSudioMode::Create, MacroActionSudioModeEdit::Create,
{MacroActionSudioMode::Create, MacroActionStudioModeEdit::Create,
"AdvSceneSwitcher.action.studioMode"});
const static std::map<MacroActionSudioMode::Action, std::string> actionTypes = {
@@ -124,11 +124,11 @@ static inline void populateActionSelection(QComboBox *list)
}
}
MacroActionSudioModeEdit::MacroActionSudioModeEdit(
MacroActionStudioModeEdit::MacroActionStudioModeEdit(
QWidget *parent, std::shared_ptr<MacroActionSudioMode> entryData)
: QWidget(parent),
_actions(new QComboBox()),
_scenes(new SceneSelectionWidget(window(), true, true, true, true))
_scenes(new SceneSelectionWidget(this, true, true, true, true))
{
populateActionSelection(_actions);
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
@@ -151,7 +151,7 @@ MacroActionSudioModeEdit::MacroActionSudioModeEdit(
_loading = false;
}
void MacroActionSudioModeEdit::UpdateEntryData()
void MacroActionStudioModeEdit::UpdateEntryData()
{
if (!_entryData) {
return;
@@ -162,7 +162,7 @@ void MacroActionSudioModeEdit::UpdateEntryData()
SetWidgetVisibility();
}
void MacroActionSudioModeEdit::SceneChanged(const SceneSelection &s)
void MacroActionStudioModeEdit::SceneChanged(const SceneSelection &s)
{
GUARD_LOADING_AND_LOCK();
_entryData->_scene = s;
@@ -170,7 +170,7 @@ void MacroActionSudioModeEdit::SceneChanged(const SceneSelection &s)
QString::fromStdString(_entryData->GetShortDesc()));
}
void MacroActionSudioModeEdit::SetWidgetVisibility()
void MacroActionStudioModeEdit::SetWidgetVisibility()
{
_scenes->setVisible(_entryData->_action ==
MacroActionSudioMode::Action::SET_SCENE);
@@ -181,7 +181,7 @@ void MacroActionSudioModeEdit::SetWidgetVisibility()
}
}
void MacroActionSudioModeEdit::ActionChanged(int index)
void MacroActionStudioModeEdit::ActionChanged(int index)
{
GUARD_LOADING_AND_LOCK();
_entryData->_action = static_cast<MacroActionSudioMode::Action>(

View File

@@ -32,18 +32,18 @@ private:
static const std::string id;
};
class MacroActionSudioModeEdit : public QWidget {
class MacroActionStudioModeEdit : public QWidget {
Q_OBJECT
public:
MacroActionSudioModeEdit(
MacroActionStudioModeEdit(
QWidget *parent,
std::shared_ptr<MacroActionSudioMode> entryData = nullptr);
void UpdateEntryData();
static QWidget *Create(QWidget *parent,
std::shared_ptr<MacroAction> action)
{
return new MacroActionSudioModeEdit(
return new MacroActionStudioModeEdit(
parent, std::dynamic_pointer_cast<MacroActionSudioMode>(
action));
}

View File

@@ -76,8 +76,8 @@ MacroActionSystrayEdit::MacroActionSystrayEdit(
_message(new VariableLineEdit(this)),
_title(new VariableLineEdit(this)),
_iconPath(new FileSelection()),
_trayDisableWarning(
new QLabel("AdvSceneSwitcher.action.systray.disabled"))
_trayDisableWarning(new QLabel(
obs_module_text("AdvSceneSwitcher.action.systray.disabled")))
{
_iconPath->setToolTip(
obs_module_text("AdvSceneSwitcher.action.systray.iconHint"));

View File

@@ -52,18 +52,28 @@ bool MacroConditionFilter::CheckConditionHelper(const OBSWeakSource &filter)
ret = !obs_source_enabled(filterSource);
break;
case Condition::SETTINGS_MATCH: {
ret = CompareSourceSettings(filter, _settings, _regex);
const auto settings = GetSourceSettings(filter);
SetVariableValue(settings);
SetTempVarValue("settings", settings);
const auto settings =
GetSourceSettings(filter, _includeDefaults);
if (!settings) {
break;
}
ret = CompareSourceSettings(*settings, _settings, _regex);
SetVariableValue(*settings);
SetTempVarValue("settings", *settings);
break;
}
case Condition::SETTINGS_CHANGED: {
const auto settings = GetSourceSettings(filter);
ret = !_currentSettings.empty() && settings != _currentSettings;
const auto settings =
GetSourceSettings(filter, _includeDefaults);
ret = _currentSettings.has_value() &&
settings != _currentSettings;
_currentSettings = settings;
SetVariableValue(settings);
SetTempVarValue("settings", settings);
if (!settings) {
break;
}
SetVariableValue(*settings);
SetTempVarValue("settings", *settings);
break;
}
case Condition::INDIVIDUAL_SETTING_MATCH: {
@@ -134,6 +144,7 @@ bool MacroConditionFilter::Save(obs_data_t *obj) const
_settings.Save(obj, "settings");
_regex.Save(obj);
_setting.Save(obj);
obs_data_set_bool(obj, "includeDefaults", _includeDefaults);
return true;
}
@@ -152,6 +163,7 @@ bool MacroConditionFilter::Load(obs_data_t *obj)
obs_data_get_bool(obj, "regex"));
}
_setting.Load(obj);
_includeDefaults = obs_data_get_bool(obj, "includeDefaults");
return true;
}
@@ -221,8 +233,12 @@ MacroConditionFilterEdit::MacroConditionFilterEdit(
_settings(new VariableTextEdit(this)),
_regex(new RegexConfigWidget(parent)),
_settingSelection(new SourceSettingSelection()),
_refreshSettingSelection(new QPushButton(
obs_module_text("AdvSceneSwitcher.condition.filter.refresh")))
_refreshSettingSelection(new QPushButton(obs_module_text(
"AdvSceneSwitcher.condition.filter.refresh"))),
_includeDefaults(new QCheckBox(
obs_module_text(
"AdvSceneSwitcher.condition.filter.includeDefaults"),
this))
{
populateConditionSelection(_conditions);
@@ -249,6 +265,8 @@ MacroConditionFilterEdit::MacroConditionFilterEdit(
SLOT(SettingSelectionChanged(const SourceSetting &)));
QWidget::connect(_refreshSettingSelection, SIGNAL(clicked()), this,
SLOT(RefreshVariableSourceSelectionValue()));
QWidget::connect(_includeDefaults, SIGNAL(stateChanged(int)), this,
SLOT(IncludeDefaultsChanged(int)));
const std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{sources}}", _sources},
@@ -280,6 +298,7 @@ MacroConditionFilterEdit::MacroConditionFilterEdit(
mainLayout->addLayout(line1Layout);
mainLayout->addLayout(line2Layout);
mainLayout->addLayout(line3Layout);
mainLayout->addWidget(_includeDefaults);
setLayout(mainLayout);
_entryData = entryData;
@@ -332,7 +351,11 @@ void MacroConditionFilterEdit::GetSettingsClicked()
QString value;
if (_entryData->GetCondition() ==
MacroConditionFilter::Condition::SETTINGS_MATCH) {
value = FormatJsonString(GetSourceSettings(filters.at(0)));
const auto settings = GetSourceSettings(
filters.at(0), _entryData->_includeDefaults);
if (settings) {
value = FormatJsonString(*settings);
}
} else if (_entryData->GetCondition() ==
MacroConditionFilter::Condition::
INDIVIDUAL_SETTING_LIST_ENTRY_MATCH) {
@@ -387,6 +410,12 @@ void MacroConditionFilterEdit::RefreshVariableSourceSelectionValue()
_settingSelection->SetSource(filters.empty() ? nullptr : filters.at(0));
}
void MacroConditionFilterEdit::IncludeDefaultsChanged(int state)
{
GUARD_LOADING_AND_LOCK();
_entryData->_includeDefaults = state;
}
static QString GetIndividualListEntryName()
{
static const auto matchesInput =
@@ -440,6 +469,10 @@ void MacroConditionFilterEdit::SetWidgetVisibility()
SetRowVisibleByValue(_conditions, GetIndividualListEntryName(),
_entryData->_setting.IsList());
_includeDefaults->setVisible(
_entryData->GetCondition() ==
MacroConditionFilter::Condition::SETTINGS_MATCH);
adjustSize();
updateGeometry();
}
@@ -461,6 +494,7 @@ void MacroConditionFilterEdit::UpdateEntryData()
_settingSelection->SetSelection(filters.empty() ? nullptr
: filters.at(0),
_entryData->_setting);
_includeDefaults->setChecked(_entryData->_includeDefaults);
SetWidgetVisibility();
adjustSize();

View File

@@ -42,13 +42,14 @@ public:
StringVariable _settings = "";
RegexConfig _regex;
SourceSetting _setting;
bool _includeDefaults = false;
private:
void SetupTempVars();
bool CheckConditionHelper(const OBSWeakSource &);
Condition _condition = Condition::ENABLED;
std::string _currentSettings;
std::optional<std::string> _currentSettings;
std::string _currentSettingsValue;
static bool _registered;
@@ -80,6 +81,7 @@ private slots:
void RegexChanged(const RegexConfig &);
void SettingSelectionChanged(const SourceSetting &);
void RefreshVariableSourceSelectionValue();
void IncludeDefaultsChanged(int);
signals:
void HeaderInfoChanged(const QString &);
@@ -94,6 +96,7 @@ private:
RegexConfigWidget *_regex;
SourceSettingSelection *_settingSelection;
QPushButton *_refreshSettingSelection;
QCheckBox *_includeDefaults;
std::shared_ptr<MacroConditionFilter> _entryData;
bool _loading = true;

View File

@@ -622,8 +622,7 @@ MacroConditionMediaEdit::MacroConditionMediaEdit(
: QWidget(parent),
_sourceTypes(new QComboBox()),
_checkTypes(new QComboBox()),
_scenes(new SceneSelectionWidget(window(), true, true, true, true,
true)),
_scenes(new SceneSelectionWidget(this, true, true, true, true, true)),
_sources(new SourceSelectionWidget(this, getMediaSourcesList, true)),
_states(new QComboBox()),
_timeRestrictions(new QComboBox()),

View File

@@ -197,7 +197,7 @@ static inline void populateConditionSelection(QComboBox *list)
MacroConditionSceneOrderEdit::MacroConditionSceneOrderEdit(
QWidget *parent, std::shared_ptr<MacroConditionSceneOrder> entryData)
: QWidget(parent),
_scenes(new SceneSelectionWidget(window(), true, false, false, true)),
_scenes(new SceneSelectionWidget(this, true, false, false, true)),
_conditions(new QComboBox()),
_sources(new SceneItemSelectionWidget(parent)),
_sources2(new SceneItemSelectionWidget(parent)),

View File

@@ -333,7 +333,7 @@ MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit(
QWidget *parent,
std::shared_ptr<MacroConditionSceneTransform> entryData)
: QWidget(parent),
_scenes(new SceneSelectionWidget(window(), true, false, false, true)),
_scenes(new SceneSelectionWidget(this, true, false, false, true)),
_sources(new SceneItemSelectionWidget(
parent, true, SceneItemSelectionWidget::Placeholder::ANY)),
_settingsType(new QComboBox()),

View File

@@ -134,7 +134,7 @@ MacroConditionSceneVisibilityEdit::MacroConditionSceneVisibilityEdit(
std::shared_ptr<MacroConditionSceneVisibility> entryData)
: QWidget(parent)
{
_scenes = new SceneSelectionWidget(window(), true, false, true, true);
_scenes = new SceneSelectionWidget(this, true, false, true, true);
_sources = new SceneItemSelectionWidget(parent);
_conditions = new QComboBox();

View File

@@ -264,8 +264,7 @@ static inline void populateTypeSelection(QComboBox *list)
MacroConditionSceneEdit::MacroConditionSceneEdit(
QWidget *parent, std::shared_ptr<MacroConditionScene> entryData)
: QWidget(parent),
_scenes(new SceneSelectionWidget(window(), true, false, false,
false)),
_scenes(new SceneSelectionWidget(this, true, false, false, false)),
_sceneType(new QComboBox()),
_pattern(new QLineEdit()),
_useTransitionTargetScene(new QCheckBox(obs_module_text(

View File

@@ -82,19 +82,28 @@ bool MacroConditionSource::CheckCondition()
ret = obs_source_showing(s);
break;
case Condition::ALL_SETTINGS_MATCH: {
ret = CompareSourceSettings(_source.GetSource(), _settings,
_regex);
const auto settings = GetSourceSettings(_source.GetSource());
SetVariableValue(settings);
SetTempVarValue("settings", settings);
const auto settings = GetSourceSettings(_source.GetSource(),
_includeDefaults);
if (!settings) {
break;
}
ret = CompareSourceSettings(*settings, _settings, _regex);
SetVariableValue(*settings);
SetTempVarValue("settings", *settings);
break;
}
case Condition::SETTINGS_CHANGED: {
const auto settings = GetSourceSettings(_source.GetSource());
ret = !_currentSettings.empty() && settings != _currentSettings;
const auto settings = GetSourceSettings(_source.GetSource(),
_includeDefaults);
ret = _currentSettings.has_value() &&
settings != _currentSettings;
_currentSettings = settings;
SetVariableValue(settings);
SetTempVarValue("settings", settings);
if (!settings) {
break;
}
SetVariableValue(*settings);
SetTempVarValue("settings", *settings);
break;
}
case Condition::INDIVIDUAL_SETTING_MATCH: {
@@ -135,13 +144,13 @@ bool MacroConditionSource::CheckCondition()
}
case Condition::HEIGHT: {
const auto height = obs_source_get_height(s);
ret = compareSourceSize(_comparision, height, _size);
ret = compareSourceSize(_comparison, height, _size);
SetTempVarValue("height", std::to_string(height));
break;
}
case Condition::WIDTH: {
const auto width = obs_source_get_width(s);
ret = compareSourceSize(_comparision, width, _size);
ret = compareSourceSize(_comparison, width, _size);
SetTempVarValue("width", std::to_string(width));
break;
}
@@ -165,8 +174,9 @@ bool MacroConditionSource::Save(obs_data_t *obj) const
_regex.Save(obj);
_setting.Save(obj);
_size.Save(obj, "size");
obs_data_set_int(obj, "sizeComparisionMethod",
static_cast<int>(_comparision));
obs_data_set_int(obj, "sizeComparisonMethod",
static_cast<int>(_comparison));
obs_data_set_bool(obj, "includeDefaults", _includeDefaults);
return true;
}
@@ -185,8 +195,11 @@ bool MacroConditionSource::Load(obs_data_t *obj)
}
_setting.Load(obj);
_size.Load(obj, "size");
_comparision = static_cast<SizeComparision>(
obs_data_get_int(obj, "sizeComparisionMethod"));
_comparison = static_cast<SizeComparision>(obs_data_get_int(
obj, obs_data_has_user_value(obj, "sizeComparisionMethod")
? "sizeComparisionMethod"
: "sizeComparisonMethod"));
_includeDefaults = obs_data_get_bool(obj, "includeDefaults");
return true;
}
@@ -268,7 +281,11 @@ MacroConditionSourceEdit::MacroConditionSourceEdit(
_refreshSettingSelection(new QPushButton(obs_module_text(
"AdvSceneSwitcher.condition.source.refresh"))),
_size(new VariableSpinBox(this)),
_sizeCompareMethods(new QComboBox())
_sizeCompareMethods(new QComboBox()),
_includeDefaults(new QCheckBox(
obs_module_text(
"AdvSceneSwitcher.condition.source.includeDefaults"),
this))
{
populateSelection(_conditions, sourceConditionTypes);
populateSelection(_sizeCompareMethods, compareMethods);
@@ -300,6 +317,8 @@ MacroConditionSourceEdit::MacroConditionSourceEdit(
this, SLOT(SizeChanged(const NumberVariable<int> &)));
QWidget::connect(_sizeCompareMethods, SIGNAL(currentIndexChanged(int)),
this, SLOT(CompareMethodChanged(int)));
QWidget::connect(_includeDefaults, SIGNAL(stateChanged(int)), this,
SLOT(IncludeDefaultsChanged(int)));
auto line1Layout = new QHBoxLayout;
line1Layout->setContentsMargins(0, 0, 0, 0);
@@ -328,6 +347,7 @@ MacroConditionSourceEdit::MacroConditionSourceEdit(
mainLayout->addLayout(line1Layout);
mainLayout->addLayout(line2Layout);
mainLayout->addLayout(line3Layout);
mainLayout->addWidget(_includeDefaults);
setLayout(mainLayout);
_entryData = entryData;
@@ -364,8 +384,12 @@ void MacroConditionSourceEdit::GetSettingsClicked()
QString value;
if (_entryData->GetCondition() ==
MacroConditionSource::Condition::ALL_SETTINGS_MATCH) {
value = FormatJsonString(
GetSourceSettings(_entryData->_source.GetSource()));
const auto settings =
GetSourceSettings(_entryData->_source.GetSource(),
_entryData->_includeDefaults);
if (settings) {
value = FormatJsonString(*settings);
}
} else if (_entryData->GetCondition() ==
MacroConditionSource::Condition::
INDIVIDUAL_SETTING_LIST_ENTRY_MATCH) {
@@ -427,10 +451,16 @@ void MacroConditionSourceEdit::SizeChanged(const NumberVariable<int> &value)
void MacroConditionSourceEdit::CompareMethodChanged(int index)
{
GUARD_LOADING_AND_LOCK();
_entryData->_comparision =
_entryData->_comparison =
static_cast<MacroConditionSource::SizeComparision>(index);
}
void MacroConditionSourceEdit::IncludeDefaultsChanged(int state)
{
GUARD_LOADING_AND_LOCK();
_entryData->_includeDefaults = state;
}
static QString GetIndividualListEntryName()
{
static const auto matchesInput =
@@ -500,6 +530,10 @@ void MacroConditionSourceEdit::SetWidgetVisibility()
SetRowVisibleByValue(_conditions, GetIndividualListEntryName(),
_entryData->_setting.IsList());
_includeDefaults->setVisible(
_entryData->GetCondition() ==
MacroConditionSource::Condition::ALL_SETTINGS_MATCH);
adjustSize();
updateGeometry();
}
@@ -519,7 +553,8 @@ void MacroConditionSourceEdit::UpdateEntryData()
_entryData->_setting);
_size->SetValue(_entryData->_size);
_sizeCompareMethods->setCurrentIndex(
static_cast<int>(_entryData->_comparision));
static_cast<int>(_entryData->_comparison));
_includeDefaults->setChecked(_entryData->_includeDefaults);
SetWidgetVisibility();
}

View File

@@ -45,13 +45,14 @@ public:
SourceSetting _setting;
RegexConfig _regex;
IntVariable _size;
SizeComparision _comparision = SizeComparision::EQUAL;
SizeComparision _comparison = SizeComparision::EQUAL;
bool _includeDefaults = false;
private:
void SetupTempVars();
Condition _condition = Condition::ACTIVE;
std::string _currentSettings;
std::optional<std::string> _currentSettings;
std::string _currentSettingsValue;
static bool _registered;
@@ -84,6 +85,7 @@ private slots:
void RefreshVariableSourceSelectionValue();
void SizeChanged(const NumberVariable<int> &value);
void CompareMethodChanged(int);
void IncludeDefaultsChanged(int);
signals:
void HeaderInfoChanged(const QString &);
@@ -97,6 +99,7 @@ protected:
QPushButton *_refreshSettingSelection;
VariableSpinBox *_size;
QComboBox *_sizeCompareMethods;
QCheckBox *_includeDefaults;
std::shared_ptr<MacroConditionSource> _entryData;

View File

@@ -90,7 +90,7 @@ MacroConditionStudioModeEdit::MacroConditionStudioModeEdit(
: QWidget(parent)
{
_condition = new QComboBox();
_scenes = new SceneSelectionWidget(window(), true, false, true, true);
_scenes = new SceneSelectionWidget(this, true, false, true, true);
populateConditionSelection(_condition);

View File

@@ -133,20 +133,6 @@ static void addSettingsHelper(obs_property_t *property,
} while (obs_property_next(&property));
}
std::vector<SourceSetting> GetSoruceSettings(obs_source_t *source)
{
properties_t properties(obs_source_properties(source),
obs_properties_destroy);
if (!properties) {
return {};
}
std::vector<SourceSetting> settings;
auto it = obs_properties_first(properties.get());
addSettingsHelper(it, settings);
return settings;
}
static std::optional<std::string>
getDataJsonWithDefaults(const OBSWeakSource &ws)
{
@@ -495,11 +481,25 @@ void SourceSettingSelection::SelectionIdxChanged(int idx)
emit SelectionChanged(setting);
}
static std::vector<SourceSetting> getSourceSettings(obs_source_t *source)
{
properties_t properties(obs_source_properties(source),
obs_properties_destroy);
if (!properties) {
return {};
}
std::vector<SourceSetting> settings;
auto it = obs_properties_first(properties.get());
addSettingsHelper(it, settings);
return settings;
}
void SourceSettingSelection::Populate(const OBSWeakSource &source)
{
_settings->clear();
OBSSourceAutoRelease s = obs_weak_source_get_source(source);
auto settings = GetSoruceSettings(s);
const auto settings = getSourceSettings(s);
for (const auto &setting : settings) {
QVariant variant;
variant.setValue(setting);

View File

@@ -32,7 +32,6 @@ private:
friend class SourceSettingSelection;
};
std::vector<SourceSetting> GetSoruceSettings(obs_source_t *source);
std::optional<std::string> GetSourceSettingValue(const OBSWeakSource &source,
const SourceSetting &setting);
std::optional<std::string>

View File

@@ -4,23 +4,30 @@
namespace advss {
std::string GetSourceSettings(OBSWeakSource ws)
std::optional<std::string> GetSourceSettings(OBSWeakSource ws,
bool includeDefaults)
{
if (!ws) {
return "";
return {};
}
std::string settings;
auto s = obs_weak_source_get_source(ws);
obs_data_t *data = obs_source_get_settings(s);
OBSSourceAutoRelease source = obs_weak_source_get_source(ws);
OBSDataAutoRelease dataWithoutDefaults =
obs_source_get_settings(source);
if (!dataWithoutDefaults) {
return {};
}
OBSDataAutoRelease dataWithDefaults =
obs_data_get_defaults(dataWithoutDefaults);
obs_data_apply(dataWithDefaults, dataWithoutDefaults);
auto &data = includeDefaults ? dataWithDefaults : dataWithoutDefaults;
auto json = obs_data_get_json(data);
if (json) {
settings = json;
if (!json) {
return {};
}
obs_data_release(data);
obs_source_release(s);
return settings;
return json;
}
void SetSourceSettings(obs_source_t *s, const std::string &settings)
@@ -39,12 +46,11 @@ void SetSourceSettings(obs_source_t *s, const std::string &settings)
obs_data_release(data);
}
bool CompareSourceSettings(const OBSWeakSource &source,
bool CompareSourceSettings(const std::string &sourceSettings,
const std::string &settings,
const RegexConfig &regex)
{
std::string currentSettings = GetSourceSettings(source);
return MatchJson(currentSettings, settings, regex);
return MatchJson(sourceSettings, settings, regex);
}
} // namespace advss

View File

@@ -1,13 +1,17 @@
#pragma once
#include <obs.hpp>
#include <string>
#include <regex-config.hpp>
#include <obs.hpp>
#include <optional>
#include <string>
namespace advss {
std::string GetSourceSettings(OBSWeakSource ws);
std::optional<std::string> GetSourceSettings(OBSWeakSource ws,
bool includeDefaults);
void SetSourceSettings(obs_source_t *s, const std::string &settings);
bool CompareSourceSettings(const OBSWeakSource &source,
bool CompareSourceSettings(const std::string &sourceSettings,
const std::string &settings,
const RegexConfig &regex);

View File

@@ -13,7 +13,7 @@
namespace advss {
static const int tokenGrabberPort = 8080;
static const int tokenGrabberPort = 42171;
static std::deque<std::shared_ptr<Item>> twitchTokens;