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-condition.hpp
lib/macro/macro-dock.cpp lib/macro/macro-dock.cpp
lib/macro/macro-dock.hpp 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.cpp
lib/macro/macro-export-import-dialog.hpp lib/macro/macro-export-import-dialog.hpp
lib/macro/macro-helpers.cpp lib/macro/macro-helpers.cpp
@@ -217,6 +219,8 @@ target_sources(
lib/utils/priority-helper.hpp lib/utils/priority-helper.hpp
lib/utils/regex-config.cpp lib/utils/regex-config.cpp
lib/utils/regex-config.hpp 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.cpp
lib/utils/resizing-text-edit.hpp lib/utils/resizing-text-edit.hpp
lib/utils/resource-table.cpp lib/utils/resource-table.cpp

View File

@@ -150,9 +150,9 @@ AdvSceneSwitcher.macroTab.title="Macro"
AdvSceneSwitcher.macroTab.macros="Macros" 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.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.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.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.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, 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.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="Edit macro"
AdvSceneSwitcher.macroTab.edit.logic="Logic type:" AdvSceneSwitcher.macroTab.edit.logic="Logic type:"
AdvSceneSwitcher.macroTab.edit.condition="Condition type:" AdvSceneSwitcher.macroTab.edit.condition="Condition type:"
@@ -177,6 +177,8 @@ AdvSceneSwitcher.macroTab.contextMenuAdd="Add"
AdvSceneSwitcher.macroTab.copy="Duplicate Macro" AdvSceneSwitcher.macroTab.copy="Duplicate Macro"
AdvSceneSwitcher.macroTab.group="Group Selected Macros" AdvSceneSwitcher.macroTab.group="Group Selected Macros"
AdvSceneSwitcher.macroTab.ungroup="Ungroup Selected Groups" AdvSceneSwitcher.macroTab.ungroup="Ungroup Selected Groups"
AdvSceneSwitcher.macroTab.expandAllGroups="Expand all Groups"
AdvSceneSwitcher.macroTab.collapseAllGroups="Collapse all Groups"
AdvSceneSwitcher.macroTab.rename="Rename" AdvSceneSwitcher.macroTab.rename="Rename"
AdvSceneSwitcher.macroTab.remove="Remove" AdvSceneSwitcher.macroTab.remove="Remove"
AdvSceneSwitcher.macroTab.export="Export" AdvSceneSwitcher.macroTab.export="Export"
@@ -516,6 +518,7 @@ AdvSceneSwitcher.condition.source.sizeCompare.equal="Equals"
AdvSceneSwitcher.condition.source.sizeCompare.more="Bigger than" AdvSceneSwitcher.condition.source.sizeCompare.more="Bigger than"
AdvSceneSwitcher.condition.source.refresh="Refresh" 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.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.sceneVisibilityHint="Scene specific visibility can be checked using the \"Scene item visibility\" condition"
AdvSceneSwitcher.condition.source.getSettings="Get current settings" AdvSceneSwitcher.condition.source.getSettings="Get current settings"
AdvSceneSwitcher.condition.source.entry.line1="{{sources}}{{conditions}}{{settingSelection}}{{refresh}}{{sizeCompareMethods}}{{size}}" 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.type.individualSettingChanged="Settings value changed"
AdvSceneSwitcher.condition.filter.refresh="Refresh" 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.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.getSettings="Get current settings"
AdvSceneSwitcher.condition.filter.entry.line1="On{{sources}}{{filters}}{{conditions}}{{settingSelection}}{{refresh}}" AdvSceneSwitcher.condition.filter.entry.line1="On{{sources}}{{filters}}{{conditions}}{{settingSelection}}{{refresh}}"
AdvSceneSwitcher.condition.filter.entry.line2="{{settings}}" 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="Audio"
AdvSceneSwitcher.action.audio.type.mute="Mute" AdvSceneSwitcher.action.audio.type.mute="Mute"
AdvSceneSwitcher.action.audio.type.unmute="Unmute" 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.sourceVolume="Set source volume"
AdvSceneSwitcher.action.audio.type.masterVolume="Set master volume" AdvSceneSwitcher.action.audio.type.masterVolume="Set master volume"
AdvSceneSwitcher.action.audio.type.syncOffset="Set sync offset" 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.disableAction="Disable action"
AdvSceneSwitcher.action.macro.type.enableAction="Enable action" AdvSceneSwitcher.action.macro.type.enableAction="Enable action"
AdvSceneSwitcher.action.macro.type.toggleAction="Toggle 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="{{actions}}{{actionTypes}}of{{macros}}"
AdvSceneSwitcher.action.macro.entry.run.condition="{{conditionBehaviors}}of{{conditionMacros}}" AdvSceneSwitcher.action.macro.entry.run.condition="{{conditionBehaviors}}of{{conditionMacros}}"
AdvSceneSwitcher.action.macro.entry.other="{{actions}}{{actionIndex}}{{macros}}" 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> </item>
</layout> </layout>
</widget> </widget>
<widget class="QGroupBox" name="macroEdit"> <widget class="QGroupBox" name="macroEditGroup">
<property name="title"> <property name="title">
<string>AdvSceneSwitcher.macroTab.edit</string> <string>AdvSceneSwitcher.macroTab.edit</string>
</property> </property>
@@ -896,339 +896,7 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QSplitter" name="macroActionConditionSplitter"> <widget class="advss::MacroEdit" name="macroEdit" native="true"/>
<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> </item>
</layout> </layout>
</widget> </widget>
@@ -4440,12 +4108,6 @@
<extends>QListView</extends> <extends>QListView</extends>
<header>macro-tree.hpp</header> <header>macro-tree.hpp</header>
</customwidget> </customwidget>
<customwidget>
<class>advss::MacroSegmentList</class>
<extends>QScrollArea</extends>
<header>macro-segment-list.hpp</header>
<container>1</container>
</customwidget>
<customwidget> <customwidget>
<class>advss::MacroRunButton</class> <class>advss::MacroRunButton</class>
<extends>QPushButton</extends> <extends>QPushButton</extends>
@@ -4456,6 +4118,12 @@
<extends>QWidget</extends> <extends>QWidget</extends>
<header>duration-control.hpp</header> <header>duration-control.hpp</header>
</customwidget> </customwidget>
<customwidget>
<class>advss::MacroEdit</class>
<extends>QWidget</extends>
<header>macro-edit.hpp</header>
<container>1</container>
</customwidget>
</customwidgets> </customwidgets>
<tabstops> <tabstops>
<tabstop>tabWidget</tabstop> <tabstop>tabWidget</tabstop>
@@ -4492,28 +4160,7 @@
<tabstop>runMacroInParallel</tabstop> <tabstop>runMacroInParallel</tabstop>
<tabstop>runMacroOnChange</tabstop> <tabstop>runMacroOnChange</tabstop>
<tabstop>macroSettings</tabstop> <tabstop>macroSettings</tabstop>
<tabstop>conditionsList</tabstop> <tabstop>macroEdit</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>sceneGroups</tabstop> <tabstop>sceneGroups</tabstop>
<tabstop>sceneGroupAdd</tabstop> <tabstop>sceneGroupAdd</tabstop>
<tabstop>sceneGroupRemove</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) bool AdvSceneSwitcher::eventFilter(QObject *obj, QEvent *event)
{ {
auto eventType = event->type(); auto eventType = event->type();
if (obj == ui->macroElseActions && eventType == QEvent::Resize) { if (eventType == QEvent::KeyPress) {
QResizeEvent *resizeEvent = static_cast<QResizeEvent *>(event);
if (resizeEvent->size().height() == 0) {
SetElseActionsStateToHidden();
return QDialog::eventFilter(obj, event);
}
SetElseActionsStateToVisible();
} else if (eventType == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
auto pressedKey = keyEvent->key(); auto pressedKey = keyEvent->key();
@@ -608,7 +599,7 @@ static void handleSceneCollectionChanging()
AdvSceneSwitcher::window->close(); AdvSceneSwitcher::window->close();
} }
if (!switcher->stop) { if (!switcher->stop) {
switcher->sceneColletionStop = true; switcher->sceneCollectionStop = true;
switcher->Stop(); switcher->Stop();
} }
} }
@@ -744,6 +735,21 @@ void AdvSceneSwitcher::HighlightMacroSettingsButton(bool enable)
highlight = HighlightWidget(ui->macroSettings, Qt::green); 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) void HighlightMacroSettingsButton(bool enable)
{ {
auto window = GetSettingsWindow(); auto window = GetSettingsWindow();

View File

@@ -79,6 +79,7 @@ public slots:
/* --- Begin of macro tab section --- */ /* --- Begin of macro tab section --- */
public: public:
void SetupMacroTab(); void SetupMacroTab();
bool MacroTabIsInFocus();
bool AddNewMacro(std::shared_ptr<Macro> &res, std::string &name, bool AddNewMacro(std::shared_ptr<Macro> &res, std::string &name,
std::string format = ""); std::string format = "");
void RemoveMacro(std::shared_ptr<Macro> &); void RemoveMacro(std::shared_ptr<Macro> &);
@@ -86,7 +87,6 @@ public:
void RenameMacro(std::shared_ptr<Macro> &, const QString &name); void RenameMacro(std::shared_ptr<Macro> &, const QString &name);
std::shared_ptr<Macro> GetSelectedMacro() const; std::shared_ptr<Macro> GetSelectedMacro() const;
std::vector<std::shared_ptr<Macro>> GetSelectedMacros() const; std::vector<std::shared_ptr<Macro>> GetSelectedMacros() const;
void SetEditMacro(Macro &m);
void SetMacroEditAreaDisabled(bool) const; void SetMacroEditAreaDisabled(bool) const;
void HighlightAction(int idx, QColor color = QColor(Qt::green)) const; void HighlightAction(int idx, QColor color = QColor(Qt::green)) const;
void HighlightElseAction(int idx, void HighlightElseAction(int idx,
@@ -111,82 +111,14 @@ public slots:
void on_macroName_editingFinished(); void on_macroName_editingFinished();
void on_runMacroInParallel_stateChanged(int value) const; void on_runMacroInParallel_stateChanged(int value) const;
void on_runMacroOnChange_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 MacroSelectionChanged();
void UpMacroSegementHotkey();
void DownMacroSegementHotkey();
void DeleteMacroSegementHotkey();
void ShowMacroContextMenu(const QPoint &); void ShowMacroContextMenu(const QPoint &);
void ShowMacroActionsContextMenu(const QPoint &);
void ShowMacroElseActionsContextMenu(const QPoint &);
void ShowMacroConditionsContextMenu(const QPoint &);
void CopyMacro(); void CopyMacro();
void RenameSelectedMacro(); void RenameSelectedMacro();
void ExportMacros() const; void ExportMacros() const;
void ImportMacros(); 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 HighlightOnChange() const;
void on_macroSettings_clicked(); void on_macroSettings_clicked();
void CopyMacroSegment();
void PasteMacroSegment();
signals: signals:
void MacroAdded(const QString &name); void MacroAdded(const QString &name);
@@ -201,16 +133,7 @@ signals:
void ConnectionRemoved(const QString &); void ConnectionRemoved(const QString &);
private: private:
enum class MacroSection { CONDITIONS, ACTIONS, ELSE_ACTIONS };
void SetupMacroSegmentSelection(MacroSection type, int idx);
bool ResolveMacroImportNameConflict(std::shared_ptr<Macro> &); 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 --- */ /* --- End of macro tab section --- */

View File

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

View File

@@ -158,473 +158,4 @@ std::shared_ptr<MacroSegment> MacroActionEdit::Data() const
return *_entryData; 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 } // namespace advss

View File

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

View File

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

View File

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

View File

@@ -275,289 +275,4 @@ std::shared_ptr<MacroSegment> MacroConditionEdit::Data() const
return *_entryData; 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 } // 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), : ListEditor(parent, reorder),
_allowDuplicates(allowDuplicates) _allowDuplicates(allowDuplicates)
{ {
QWidget::connect(window(), QWidget::connect(GetSettingsWindow(),
SIGNAL(MacroRenamed(const QString &, const QString &)), SIGNAL(MacroRenamed(const QString &, const QString &)),
this, this,
SLOT(MacroRename(const QString &, const QString &))); 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 &))); SLOT(MacroRemove(const QString &)));
UpdateListSize(); UpdateListSize();
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -478,7 +478,14 @@ bool MacroSettingsDialog::AskForSettings(QWidget *parent,
macro->SetSkipExecOnStart(dialog._currentSkipOnStartup->isChecked()); macro->SetSkipExecOnStart(dialog._currentSkipOnStartup->isChecked());
macro->SetStopActionsIfNotDone( macro->SetStopActionsIfNotDone(
dialog._currentStopActionsIfNotDone->isChecked()); 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( macro->SetDockHasRunButton(
dialog._currentMacroDockAddRunButton->isChecked()); dialog._currentMacroDockAddRunButton->isChecked());
macro->SetDockHasPauseButton( 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); 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) void MacroTreeModel::Remove(std::shared_ptr<Macro> item)
{ {
auto lock = LockContext(); auto lock = LockContext();
@@ -789,6 +803,13 @@ void MacroTree::Add(std::shared_ptr<Macro> item,
assert(GetModel()->IsInValidState()); 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 std::shared_ptr<Macro> MacroTree::GetCurrentMacro() const
{ {
return GetModel()->GetCurrentMacro(); return GetModel()->GetCurrentMacro();
@@ -1160,6 +1181,28 @@ bool MacroTree::SelectionEmpty() const
return selectedIndexes().empty(); 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, void MacroTree::MoveItemBefore(const std::shared_ptr<Macro> &item,
const std::shared_ptr<Macro> &after) const const std::shared_ptr<Macro> &after) const
{ {
@@ -1260,6 +1303,26 @@ void MacroTree::UngroupSelectedGroups()
assert(GetModel()->IsInValidState()); 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 &, void MacroTree::SelectionChangedHelper(const QItemSelection &,
const QItemSelection &) const QItemSelection &)
{ {

View File

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

View File

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

View File

@@ -101,7 +101,7 @@ public:
bool firstBoot = true; bool firstBoot = true;
bool transitionActive = false; bool transitionActive = false;
bool sceneColletionStop = false; bool sceneCollectionStop = false;
bool obsIsShuttingDown = false; bool obsIsShuttingDown = false;
bool firstInterval = true; bool firstInterval = true;
bool firstIntervalAfterStop = 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))); SLOT(SelectionChanged(int)));
// Scene groups // Scene groups
QWidget::connect(window(), SIGNAL(SceneGroupAdded(const QString &)), QWidget::connect(GetSettingsWindow(),
this, SLOT(ItemAdd(const QString &))); SIGNAL(SceneGroupAdded(const QString &)), this,
QWidget::connect(window(), SIGNAL(SceneGroupRemoved(const QString &)), SLOT(ItemAdd(const QString &)));
this, SLOT(ItemRemove(const QString &))); QWidget::connect(GetSettingsWindow(),
SIGNAL(SceneGroupRemoved(const QString &)), this,
SLOT(ItemRemove(const QString &)));
QWidget::connect( QWidget::connect(
window(), GetSettingsWindow(),
SIGNAL(SceneGroupRenamed(const QString &, const QString &)), SIGNAL(SceneGroupRenamed(const QString &, const QString &)),
this, SLOT(ItemRename(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) void Section::Collapse(bool collapse)
{ {
if (_contentHeight != _content->sizeHint().height()) {
_contentHeight = _content->sizeHint().height();
}
SetupAnimations();
_toggleButton->setChecked(collapse); _toggleButton->setChecked(collapse);
_toggleButton->setArrowType(collapse ? Qt::ArrowType::RightArrow _toggleButton->setArrowType(collapse ? Qt::ArrowType::RightArrow
: Qt::ArrowType::DownArrow); : Qt::ArrowType::DownArrow);
@@ -72,7 +77,7 @@ void Section::SetContent(QWidget *w, bool collapsed)
delete _contentArea; delete _contentArea;
// Setup contentArea // Setup contentArea
_contentArea = new QScrollArea(this); _contentArea = new QWidget(this);
_contentArea->setObjectName("macroSegmentContent"); _contentArea->setObjectName("macroSegmentContent");
_contentArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); _contentArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
_contentArea->setStyleSheet( _contentArea->setStyleSheet(
@@ -93,12 +98,11 @@ void Section::SetContent(QWidget *w, bool collapsed)
SetupAnimations(); SetupAnimations();
setMinimumHeight(_headerHeight);
if (collapsed) { if (collapsed) {
this->setMinimumHeight(_headerHeight);
_contentArea->setMaximumHeight(0); _contentArea->setMaximumHeight(0);
} else { } else {
this->setMinimumHeight(_headerHeight + _contentHeight); _contentArea->setMaximumHeight(QWIDGETSIZE_MAX);
_contentArea->setMaximumHeight(_contentHeight);
} }
const QSignalBlocker b(_toggleButton); const QSignalBlocker b(_toggleButton);
_toggleButton->setChecked(collapsed); _toggleButton->setChecked(collapsed);
@@ -120,23 +124,6 @@ void Section::SetCollapsed(bool collapsed)
Collapse(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() void Section::SetupAnimations()
{ {
if (_toggleAnimation) { if (_toggleAnimation) {
@@ -160,7 +147,7 @@ void Section::SetupAnimations()
SectionAnimation->setEndValue(_headerHeight + _contentHeight); SectionAnimation->setEndValue(_headerHeight + _contentHeight);
} }
QPropertyAnimation *contentAnimation = auto contentAnimation =
static_cast<QPropertyAnimation *>(_toggleAnimation->animationAt( static_cast<QPropertyAnimation *>(_toggleAnimation->animationAt(
_toggleAnimation->animationCount() - 1)); _toggleAnimation->animationCount() - 1));
contentAnimation->setDuration(_animationDuration); contentAnimation->setDuration(_animationDuration);
@@ -185,6 +172,14 @@ void Section::CleanUpPreviousContent()
void Section::AnimationFinish() void Section::AnimationFinish()
{ {
_transitioning = false; _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(); emit AnimationFinished();
} }

View File

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

View File

@@ -2,7 +2,10 @@
#include "export-symbol-helper.hpp" #include "export-symbol-helper.hpp"
#include <obs-data.h> #include <obs-data.h>
#include <QList> #include <QList>
#include <QSplitter>
#include <string> #include <string>
namespace advss { 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, void LoadSplitterPos(QList<int> &sizes, obs_data_t *obj,
const std::string &name); 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 } // namespace advss

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -133,20 +133,6 @@ static void addSettingsHelper(obs_property_t *property,
} while (obs_property_next(&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> static std::optional<std::string>
getDataJsonWithDefaults(const OBSWeakSource &ws) getDataJsonWithDefaults(const OBSWeakSource &ws)
{ {
@@ -495,11 +481,25 @@ void SourceSettingSelection::SelectionIdxChanged(int idx)
emit SelectionChanged(setting); 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) void SourceSettingSelection::Populate(const OBSWeakSource &source)
{ {
_settings->clear(); _settings->clear();
OBSSourceAutoRelease s = obs_weak_source_get_source(source); OBSSourceAutoRelease s = obs_weak_source_get_source(source);
auto settings = GetSoruceSettings(s); const auto settings = getSourceSettings(s);
for (const auto &setting : settings) { for (const auto &setting : settings) {
QVariant variant; QVariant variant;
variant.setValue(setting); variant.setValue(setting);

View File

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

View File

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

View File

@@ -1,13 +1,17 @@
#pragma once #pragma once
#include <obs.hpp>
#include <string>
#include <regex-config.hpp> #include <regex-config.hpp>
#include <obs.hpp>
#include <optional>
#include <string>
namespace advss { 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); 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 std::string &settings,
const RegexConfig &regex); const RegexConfig &regex);

View File

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