mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-08-29 04:36:21 -05:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3ff6f34fc | ||
|
|
ed75a221fe | ||
|
|
7b48cb2b8d | ||
|
|
9d4c8ab475 | ||
|
|
3d61ea7d25 | ||
|
|
99c8a46296 | ||
|
|
7e1d20031c | ||
|
|
0e4b000fb1 | ||
|
|
fc2451ae08 | ||
|
|
be44577967 | ||
|
|
3480ff238e | ||
|
|
ee68427036 | ||
|
|
37c32dd1ed | ||
|
|
c05a92d417 | ||
|
|
d72a0c0d38 | ||
|
|
235b31fccc | ||
|
|
286f781f4d | ||
|
|
b7516cac5b | ||
|
|
45967a090f | ||
|
|
687fb4623e | ||
|
|
4157ae4ed2 | ||
|
|
5e1469b0d8 | ||
|
|
b3bde6c59f | ||
|
|
032f5e2fe9 | ||
|
|
91c053dfd8 | ||
|
|
1f1ef4ca03 | ||
|
|
7cc44b4470 | ||
|
|
54356d9410 | ||
|
|
defbdf8b7a | ||
|
|
a01af6cfc3 | ||
|
|
4d9c7f1054 | ||
|
|
ced36e2b5b | ||
|
|
d2749f29b0 | ||
|
|
b78c8bc1de |
@@ -120,10 +120,10 @@ target_sources(
|
||||
lib/macro/macro-export-import-dialog.hpp
|
||||
lib/macro/macro-helpers.cpp
|
||||
lib/macro/macro-helpers.hpp
|
||||
lib/macro/macro-input.cpp
|
||||
lib/macro/macro-input.hpp
|
||||
lib/macro/macro-list.cpp
|
||||
lib/macro/macro-list.hpp
|
||||
lib/macro/macro-properties.cpp
|
||||
lib/macro/macro-properties.hpp
|
||||
lib/macro/macro-ref.cpp
|
||||
lib/macro/macro-ref.hpp
|
||||
lib/macro/macro-run-button.cpp
|
||||
@@ -138,6 +138,8 @@ target_sources(
|
||||
lib/macro/macro-segment.hpp
|
||||
lib/macro/macro-selection.cpp
|
||||
lib/macro/macro-selection.hpp
|
||||
lib/macro/macro-settings.cpp
|
||||
lib/macro/macro-settings.hpp
|
||||
lib/macro/macro-tab.cpp
|
||||
lib/macro/macro-tree.cpp
|
||||
lib/macro/macro-tree.hpp
|
||||
@@ -166,10 +168,14 @@ target_sources(
|
||||
lib/utils/file-selection.hpp
|
||||
lib/utils/filter-combo-box.cpp
|
||||
lib/utils/filter-combo-box.hpp
|
||||
lib/utils/help-icon.hpp
|
||||
lib/utils/help-icon.cpp
|
||||
lib/utils/item-selection-helpers.cpp
|
||||
lib/utils/item-selection-helpers.hpp
|
||||
lib/utils/layout-helpers.cpp
|
||||
lib/utils/layout-helpers.hpp
|
||||
lib/utils/list-editor.cpp
|
||||
lib/utils/list-editor.hpp
|
||||
lib/utils/log-helper.cpp
|
||||
lib/utils/log-helper.hpp
|
||||
lib/utils/math-helpers.cpp
|
||||
@@ -221,6 +227,8 @@ target_sources(
|
||||
lib/utils/splitter-helpers.hpp
|
||||
lib/utils/status-control.cpp
|
||||
lib/utils/status-control.hpp
|
||||
lib/utils/string-list.cpp
|
||||
lib/utils/string-list.hpp
|
||||
lib/utils/switch-button.cpp
|
||||
lib/utils/switch-button.hpp
|
||||
lib/utils/sync-helpers.cpp
|
||||
@@ -337,6 +345,9 @@ if(OS_WINDOWS)
|
||||
if(MSVC)
|
||||
target_compile_options(${LIB_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267
|
||||
/bigobj)
|
||||
|
||||
# Workaround for MSVC incompatibility in CI environment
|
||||
add_compile_definitions(${target_name} _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR)
|
||||
endif()
|
||||
target_sources(${LIB_NAME} PRIVATE lib/win/advanced-scene-switcher-win.cpp)
|
||||
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
|
||||
|
||||
@@ -99,8 +99,8 @@ AdvSceneSwitcher.actionQueueTab.isRunning.header="Is running"
|
||||
AdvSceneSwitcher.actionQueueTab.runOnStartup.header="Run on startup"
|
||||
AdvSceneSwitcher.actionQueueTab.yes="Yes"
|
||||
AdvSceneSwitcher.actionQueueTab.no="No"
|
||||
AdvSceneSwitcher.actionQueueTab.removeSingleConnectionPopup.text="Are you sure you want to remove \"%1\"?"
|
||||
AdvSceneSwitcher.actionQueueTab.removeMultipleConnectionsPopup.text="Are you sure you want to remove %1 action queues?"
|
||||
AdvSceneSwitcher.actionQueueTab.removeSingleQueuePopup.text="Are you sure you want to remove \"%1\"?"
|
||||
AdvSceneSwitcher.actionQueueTab.removeMultipleQueuesPopup.text="Are you sure you want to remove %1 action queues?"
|
||||
|
||||
; Websocket Connections Tab
|
||||
AdvSceneSwitcher.websocketConnectionTab.title="Websocket Connections"
|
||||
@@ -182,6 +182,10 @@ AdvSceneSwitcher.macroTab.segment.paste="Paste"
|
||||
AdvSceneSwitcher.macroTab.highlightSettings="Visual settings"
|
||||
AdvSceneSwitcher.macroTab.hotkeySettings="Hotkey settings"
|
||||
AdvSceneSwitcher.macroTab.generalSettings="General settings"
|
||||
AdvSceneSwitcher.macroTab.inputSettings="Input settings"
|
||||
AdvSceneSwitcher.macroTab.inputSettings.description="This section will allow you to specify variables, which will be treated as input parameters for the selected macro.\nWhen executing the macro using the \"Macro\" action type, you will have the option to set the values for those variables."
|
||||
AdvSceneSwitcher.macroTab.inputSettings.invalid="<Invalid selection>"
|
||||
AdvSceneSwitcher.macroTab.inputSettings.noInputs="No inputs are defined for the selected macro!\nOpen the settings of the macro to define inputs.\nThe settings button is highlighted above."
|
||||
AdvSceneSwitcher.macroTab.dockSettings="Dock settings"
|
||||
AdvSceneSwitcher.macroTab.highlightExecutedMacros="Highlight recently executed macros"
|
||||
AdvSceneSwitcher.macroTab.highlightTrueConditions="Highlight conditions of currently selected macro that evaluated to true recently"
|
||||
@@ -226,7 +230,7 @@ AdvSceneSwitcher.macroTab.tooltip.elseActionTopButton="Move selected action to t
|
||||
AdvSceneSwitcher.macroTab.tooltip.elseActionUpButton="Move selected action up in the else section"
|
||||
AdvSceneSwitcher.macroTab.tooltip.elseActionDownButton="Move selected action down in the else section"
|
||||
AdvSceneSwitcher.macroTab.tooltip.elseActionBottomButton="Move selected action to the bottom in the else section"
|
||||
AdvSceneSwitcher.macroTab.tooltip.openMacroPropertiesButton="Open macro properties"
|
||||
AdvSceneSwitcher.macroTab.tooltip.openMacroSettingsButton="Open macro settings"
|
||||
|
||||
AdvSceneSwitcher.macroDock.pause="Pause"
|
||||
AdvSceneSwitcher.macroDock.unpause="Unpause"
|
||||
@@ -453,11 +457,16 @@ AdvSceneSwitcher.condition.source.type.settingsMatch="Settings match"
|
||||
AdvSceneSwitcher.condition.source.type.settingsChanged="Settings changed"
|
||||
AdvSceneSwitcher.condition.source.type.individualSettingMatches="Setting value matches"
|
||||
AdvSceneSwitcher.condition.source.type.individualSettingChanged="Setting value changed"
|
||||
AdvSceneSwitcher.condition.source.type.width="Width"
|
||||
AdvSceneSwitcher.condition.source.type.height="Height"
|
||||
AdvSceneSwitcher.condition.source.sizeCompare.less="Smaller than"
|
||||
AdvSceneSwitcher.condition.source.sizeCompare.equal="Equals"
|
||||
AdvSceneSwitcher.condition.source.sizeCompare.more="Bigger than"
|
||||
AdvSceneSwitcher.condition.source.refresh="Refresh"
|
||||
AdvSceneSwitcher.condition.source.refreshTooltip="Repopulate the source settings selection with the settings of the source which's name matches the variable value."
|
||||
AdvSceneSwitcher.condition.source.sceneVisibilityHint="Scene specific visibility can be checked using the \"Scene item visibility\" condition"
|
||||
AdvSceneSwitcher.condition.source.getSettings="Get current settings"
|
||||
AdvSceneSwitcher.condition.source.entry.line1="{{sources}}{{conditions}}{{settingSelection}}{{refresh}}"
|
||||
AdvSceneSwitcher.condition.source.entry.line1="{{sources}}{{conditions}}{{settingSelection}}{{refresh}}{{sizeCompareMethods}}{{size}}"
|
||||
AdvSceneSwitcher.condition.source.entry.line2="{{settings}}"
|
||||
AdvSceneSwitcher.condition.source.entry.line3="{{regex}}{{getSettings}}"
|
||||
AdvSceneSwitcher.condition.virtualCamera="Virtual camera"
|
||||
@@ -683,6 +692,17 @@ AdvSceneSwitcher.condition.clipboard.condition.isImage="Clipboard contains an im
|
||||
AdvSceneSwitcher.condition.clipboard.condition.isURL="Clipboard contains an URL"
|
||||
AdvSceneSwitcher.condition.clipboard.condition.matches="Clipboard content matches"
|
||||
AdvSceneSwitcher.condition.clipboard.condition.entry="{{conditions}}{{regex}}{{urlInfo}}"
|
||||
AdvSceneSwitcher.condition.folder="Folder watch"
|
||||
AdvSceneSwitcher.condition.folder.tooltip="This condition type will allow you to monitor the contents of a folder.\nNote that the monitoring will *not* recursively scan for changes in sub directories within directories of the selected folder!\nNote that if there are several changes during a short period of time, some of the changes might not emit this signal.\nHowever, the last change in the sequence of changes always will."
|
||||
AdvSceneSwitcher.condition.folder.condition.any="Any change happened"
|
||||
AdvSceneSwitcher.condition.folder.condition.fileAdd="A file was added"
|
||||
AdvSceneSwitcher.condition.folder.condition.fileChange="A file was modified"
|
||||
AdvSceneSwitcher.condition.folder.condition.fileRemove="A file was removed"
|
||||
AdvSceneSwitcher.condition.folder.condition.folderAdd="A directory was added"
|
||||
AdvSceneSwitcher.condition.folder.condition.folderRemove="A directory was removed"
|
||||
AdvSceneSwitcher.condition.folder.entry="{{conditions}}in{{folder}}{{tooltip}}"
|
||||
AdvSceneSwitcher.condition.folder.enableFilter="Only evaluate to true, if the changed path matches a patern"
|
||||
AdvSceneSwitcher.condition.folder.entry.filter="{{filter}}{{regex}}"
|
||||
|
||||
; Macro Actions
|
||||
AdvSceneSwitcher.action.scene="Switch scene"
|
||||
@@ -818,9 +838,13 @@ AdvSceneSwitcher.action.macro.type.run="Run macro"
|
||||
AdvSceneSwitcher.action.macro.type.run.conditions.ignore="Do not consider condition state"
|
||||
AdvSceneSwitcher.action.macro.type.run.conditions.true="Only if conditions evaluate to true"
|
||||
AdvSceneSwitcher.action.macro.type.run.conditions.false="Only if conditions evaluate to false"
|
||||
AdvSceneSwitcher.action.macro.type.run.updateConditionMatchState="Reevaluate the condition state before executing this action"
|
||||
AdvSceneSwitcher.action.macro.type.run.updateConditionMatchState.help="The plugin operates in phases:\n * The phase evaluating the macro conditions\n * The phase running macro actions\nMacros executed before this particular action might have side effects on the condition state of macros.\nCheck this option if you want those side effects to be taken into account when evaluating the condition state."
|
||||
AdvSceneSwitcher.action.macro.type.run.actionType.regular="actions"
|
||||
AdvSceneSwitcher.action.macro.type.run.actionType.else="else-actions"
|
||||
AdvSceneSwitcher.action.macro.type.run.skipWhenPaused="Skip execution when macro is paused"
|
||||
AdvSceneSwitcher.action.macro.type.run.setInputs="Set inputs"
|
||||
AdvSceneSwitcher.action.macro.type.run.setInputs.description="Input variables can be defined in the macro settings.\nDefining input variables will allow you to modify the values of variables before an action is executed."
|
||||
AdvSceneSwitcher.action.macro.type.stop="Stop actions"
|
||||
AdvSceneSwitcher.action.macro.type.disableAction="Disable action"
|
||||
AdvSceneSwitcher.action.macro.type.enableAction="Enable action"
|
||||
@@ -972,9 +996,11 @@ AdvSceneSwitcher.action.variable.type.sceneItemCount="Set to scene item count of
|
||||
AdvSceneSwitcher.action.variable.type.stringLength="Set to length of string"
|
||||
AdvSceneSwitcher.action.variable.type.extractJson="Extract json field with name"
|
||||
AdvSceneSwitcher.action.variable.type.setToTempvar="Set to macro property"
|
||||
AdvSceneSwitcher.action.variable.type.setToTempvar.help="This action type will allow you to extract values out of segments of the current macro and assign those values to the selected variable.\nFor example, you can get the current scene name from a scene condition and assign this name to a variable."
|
||||
AdvSceneSwitcher.action.variable.type.sceneItemName="Set to scene item name at index"
|
||||
AdvSceneSwitcher.action.variable.type.padValue="Pad current value"
|
||||
AdvSceneSwitcher.action.variable.type.truncateValue="Truncate current value"
|
||||
AdvSceneSwitcher.action.variable.type.swapValues="Swap variable values"
|
||||
AdvSceneSwitcher.action.variable.truncateOrPadDirection.left="Left"
|
||||
AdvSceneSwitcher.action.variable.truncateOrPadDirection.right="Right"
|
||||
AdvSceneSwitcher.action.variable.askForValuePromptDefault="Assign value to variable \"%1\":"
|
||||
@@ -988,7 +1014,7 @@ AdvSceneSwitcher.action.variable.invalidSelection="Invalid selection!"
|
||||
AdvSceneSwitcher.action.variable.actionNoVariableSupport="Getting variable values from %1 actions is not supported!"
|
||||
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Getting variable values from %1 conditions is not supported!"
|
||||
AdvSceneSwitcher.action.variable.currentSegmentValue="Current value:"
|
||||
AdvSceneSwitcher.action.variable.entry.other="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}{{envVariableName}}{{scenes}}{{tempVars}}{{sceneItemIndex}}{{direction}}{{stringLength}}{{paddingCharSelection}}"
|
||||
AdvSceneSwitcher.action.variable.entry.other="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}{{envVariableName}}{{scenes}}{{tempVars}}{{tempVarsHelp}}{{sceneItemIndex}}{{direction}}{{stringLength}}{{paddingCharSelection}}"
|
||||
AdvSceneSwitcher.action.variable.entry.pad="{{actions}}of{{variables}}to length{{stringLength}}by adding{{paddingCharSelection}}to the{{direction}}"
|
||||
AdvSceneSwitcher.action.variable.entry.truncate="{{actions}}of{{variables}}to length{{stringLength}}by removing characters from the{{direction}}"
|
||||
AdvSceneSwitcher.action.variable.entry.substringIndex="Substring start:{{subStringStart}}Substring size:{{subStringSize}}"
|
||||
@@ -1054,6 +1080,8 @@ AdvSceneSwitcher.action.queue.entry.add="{{actions}}actions of macro{{macros}}to
|
||||
AdvSceneSwitcher.action.queue.entry.other="{{actions}}queue{{queues}}"
|
||||
AdvSceneSwitcher.action.window="Window"
|
||||
AdvSceneSwitcher.action.window.type.setFocusWindow="Focus window"
|
||||
AdvSceneSwitcher.action.window.type.setFocusWindow.limitation="The focus action can only be performed under certain circumstances"
|
||||
AdvSceneSwitcher.action.window.type.setFocusWindow.limitation.details="At least one of the following conditions must be true:\n OBS is the foreground process.\n There is currently no foreground window, and thus no foreground process.\n OBS received the last input event."
|
||||
AdvSceneSwitcher.action.window.type.maximizeWindow="Maximize window"
|
||||
AdvSceneSwitcher.action.window.type.minimizeWindow="Minimize window"
|
||||
AdvSceneSwitcher.action.window.type.closeWindow="Close window"
|
||||
@@ -1103,6 +1131,7 @@ AdvSceneSwitcher.variable.save="Save / load behavior"
|
||||
AdvSceneSwitcher.variable.save.dontSave="Don't save variable value"
|
||||
AdvSceneSwitcher.variable.save.save="Save variable value"
|
||||
AdvSceneSwitcher.variable.save.default="Set to value"
|
||||
AdvSceneSwitcher.variable.selectionDialog="Select variable:"
|
||||
|
||||
AdvSceneSwitcher.tooltip.availableVariables="Variables are supported, use ${VarName} to retrieve the value of VarName"
|
||||
|
||||
@@ -1732,6 +1761,20 @@ AdvSceneSwitcher.tempVar.clipboard.text.description="The text contained in the c
|
||||
AdvSceneSwitcher.tempVar.file.content="File content"
|
||||
AdvSceneSwitcher.tempVar.file.date="File modification date"
|
||||
|
||||
AdvSceneSwitcher.tempVar.folder.newFiles="New files"
|
||||
AdvSceneSwitcher.tempVar.folder.changedFiles="Changed files"
|
||||
AdvSceneSwitcher.tempVar.folder.removedFiles="Removed files"
|
||||
AdvSceneSwitcher.tempVar.folder.newDirs="New directories"
|
||||
AdvSceneSwitcher.tempVar.folder.removedDirs="Removed directories"
|
||||
|
||||
AdvSceneSwitcher.tempVar.source.width="Source width"
|
||||
AdvSceneSwitcher.tempVar.source.height="Source height"
|
||||
AdvSceneSwitcher.tempVar.source.setting="Setting value"
|
||||
AdvSceneSwitcher.tempVar.source.settings="Settings string"
|
||||
|
||||
AdvSceneSwitcher.tempVar.filter.setting="Setting value"
|
||||
AdvSceneSwitcher.tempVar.filter.settings="Settings string"
|
||||
|
||||
AdvSceneSwitcher.selectScene="--select scene--"
|
||||
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
||||
AdvSceneSwitcher.selectCurrentScene="Current Scene"
|
||||
|
||||
2
deps/opencv
vendored
2
deps/opencv
vendored
Submodule deps/opencv updated: b0dc474160...71d3237a09
@@ -960,7 +960,7 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="macroProperties">
|
||||
<widget class="QPushButton" name="macroSettings">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
@@ -968,7 +968,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>AdvSceneSwitcher.macroTab.tooltip.openMacroPropertiesButton</string>
|
||||
<string>AdvSceneSwitcher.macroTab.tooltip.openMacroSettingsButton</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -5033,7 +5033,7 @@
|
||||
<tabstop>runMacro</tabstop>
|
||||
<tabstop>runMacroInParallel</tabstop>
|
||||
<tabstop>runMacroOnChange</tabstop>
|
||||
<tabstop>macroProperties</tabstop>
|
||||
<tabstop>macroSettings</tabstop>
|
||||
<tabstop>conditionsList</tabstop>
|
||||
<tabstop>conditionAdd</tabstop>
|
||||
<tabstop>conditionRemove</tabstop>
|
||||
|
||||
@@ -750,6 +750,36 @@ QWidget *GetSettingsWindow()
|
||||
return SettingsWindowIsOpened() ? AdvSceneSwitcher::window : nullptr;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::HighligthMacroSettingsButton(bool enable)
|
||||
{
|
||||
static QObject *highlight = nullptr;
|
||||
if ((highlight && enable) || (!highlight && !enable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (highlight && !enable) {
|
||||
highlight->deleteLater();
|
||||
highlight = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HighlightUIElementsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
highlight = HighlightWidget(ui->macroSettings, Qt::green);
|
||||
}
|
||||
|
||||
void HighligthMacroSettingsButton(bool enable)
|
||||
{
|
||||
auto window = GetSettingsWindow();
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
static_cast<AdvSceneSwitcher *>(window)->HighligthMacroSettingsButton(
|
||||
enable);
|
||||
}
|
||||
|
||||
void SetupActionQueues();
|
||||
|
||||
extern "C" EXPORT void InitSceneSwitcher(obs_module_t *module,
|
||||
|
||||
@@ -96,6 +96,7 @@ public:
|
||||
void SetConditionData(Macro &m);
|
||||
void SwapActions(Macro *m, int pos1, int pos2);
|
||||
void SwapConditions(Macro *m, int pos1, int pos2);
|
||||
void HighligthMacroSettingsButton(bool enable = true);
|
||||
|
||||
public slots:
|
||||
void on_macroAdd_clicked();
|
||||
@@ -178,7 +179,7 @@ public slots:
|
||||
void MoveMacroConditionDown(int idx);
|
||||
void HighlightControls();
|
||||
void HighlightOnChange();
|
||||
void on_macroProperties_clicked();
|
||||
void on_macroSettings_clicked();
|
||||
void CopyMacroSegment();
|
||||
void PasteMacroSegment();
|
||||
|
||||
@@ -410,5 +411,6 @@ public slots:
|
||||
|
||||
void OpenSettingsWindow();
|
||||
QWidget *GetSettingsWindow();
|
||||
void HighligthMacroSettingsButton(bool enable);
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -431,7 +431,7 @@ void SwitcherData::LoadSettings(obs_data_t *obj)
|
||||
}
|
||||
|
||||
LoadMacros(obj);
|
||||
LoadGlobalMacroProperties(obj);
|
||||
LoadGlobalMacroSettings(obj);
|
||||
loadWindowTitleSwitches(obj);
|
||||
loadScreenRegionSwitches(obj);
|
||||
loadPauseSwitches(obj);
|
||||
@@ -466,7 +466,7 @@ void SwitcherData::SaveSettings(obs_data_t *obj)
|
||||
|
||||
saveSceneGroups(obj);
|
||||
SaveMacros(obj);
|
||||
SaveGlobalMacroProperties(obj);
|
||||
SaveGlobalMacroSettings(obj);
|
||||
SaveVariables(obj);
|
||||
saveWindowTitleSwitches(obj);
|
||||
saveScreenRegionSwitches(obj);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
SceneGroupEditWidget *typeEdit = nullptr;
|
||||
|
||||
std::deque<SceneGroup> &GetSceneGroups()
|
||||
@@ -170,7 +170,8 @@ void AdvSceneSwitcher::on_sceneGroupAdd_clicked()
|
||||
item->setData(Qt::UserRole, text);
|
||||
ui->sceneGroups->setCurrentItem(item);
|
||||
|
||||
ui->sceneGroupAdd->disconnect(addPulse);
|
||||
addPulse->deleteLater();
|
||||
addPulse = nullptr;
|
||||
ui->sceneGroupHelp->setVisible(false);
|
||||
|
||||
emit SceneGroupAdded(QString::fromStdString(name));
|
||||
@@ -512,8 +513,8 @@ void AdvSceneSwitcher::SetupSceneGroupTab()
|
||||
|
||||
if (switcher->sceneGroups.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse = PulseWidget(ui->sceneGroupAdd,
|
||||
QColor(Qt::green));
|
||||
addPulse = HighlightWidget(ui->sceneGroupAdd,
|
||||
QColor(Qt::green));
|
||||
}
|
||||
ui->sceneGroupHelp->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace advss {
|
||||
|
||||
bool SceneTrigger::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
|
||||
void AdvSceneSwitcher::on_triggerAdd_clicked()
|
||||
{
|
||||
@@ -22,7 +22,7 @@ void AdvSceneSwitcher::on_triggerAdd_clicked()
|
||||
listAddClicked(ui->sceneTriggers,
|
||||
new SceneTriggerWidget(this,
|
||||
&switcher->sceneTriggers.back()),
|
||||
ui->triggerAdd, &addPulse);
|
||||
ui->triggerAdd, addPulse);
|
||||
|
||||
ui->triggerHelp->setVisible(false);
|
||||
}
|
||||
@@ -370,8 +370,8 @@ void AdvSceneSwitcher::SetupTriggerTab()
|
||||
|
||||
if (switcher->sceneTriggers.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse =
|
||||
PulseWidget(ui->triggerAdd, QColor(Qt::green));
|
||||
addPulse = HighlightWidget(ui->triggerAdd,
|
||||
QColor(Qt::green));
|
||||
}
|
||||
ui->triggerHelp->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace advss {
|
||||
|
||||
bool AudioSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
|
||||
void AdvSceneSwitcher::on_audioAdd_clicked()
|
||||
{
|
||||
@@ -22,7 +22,7 @@ void AdvSceneSwitcher::on_audioAdd_clicked()
|
||||
AudioSwitchWidget *sw =
|
||||
new AudioSwitchWidget(this, &switcher->audioSwitches.back());
|
||||
|
||||
listAddClicked(ui->audioSwitches, sw, ui->audioAdd, &addPulse);
|
||||
listAddClicked(ui->audioSwitches, sw, ui->audioAdd, addPulse);
|
||||
|
||||
ui->audioHelp->setVisible(false);
|
||||
}
|
||||
@@ -232,7 +232,8 @@ void AdvSceneSwitcher::SetupAudioTab()
|
||||
|
||||
if (switcher->audioSwitches.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse = PulseWidget(ui->audioAdd, QColor(Qt::green));
|
||||
addPulse = HighlightWidget(ui->audioAdd,
|
||||
QColor(Qt::green));
|
||||
}
|
||||
ui->audioHelp->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace advss {
|
||||
|
||||
bool ExecutableSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
|
||||
void AdvSceneSwitcher::on_executableAdd_clicked()
|
||||
{
|
||||
@@ -19,7 +19,7 @@ void AdvSceneSwitcher::on_executableAdd_clicked()
|
||||
listAddClicked(ui->executables,
|
||||
new ExecutableSwitchWidget(
|
||||
this, &switcher->executableSwitches.back()),
|
||||
ui->executableAdd, &addPulse);
|
||||
ui->executableAdd, addPulse);
|
||||
|
||||
ui->exeHelp->setVisible(false);
|
||||
}
|
||||
@@ -177,8 +177,8 @@ void AdvSceneSwitcher::SetupExecutableTab()
|
||||
|
||||
if (switcher->executableSwitches.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse = PulseWidget(ui->executableAdd,
|
||||
QColor(Qt::green));
|
||||
addPulse = HighlightWidget(ui->executableAdd,
|
||||
QColor(Qt::green));
|
||||
}
|
||||
ui->exeHelp->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
namespace advss {
|
||||
|
||||
bool FileSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
static std::hash<std::string> strHash;
|
||||
|
||||
void AdvSceneSwitcher::on_browseButton_clicked()
|
||||
@@ -291,7 +291,7 @@ void AdvSceneSwitcher::on_fileAdd_clicked()
|
||||
listAddClicked(ui->fileSwitches,
|
||||
new FileSwitchWidget(this,
|
||||
&switcher->fileSwitches.back()),
|
||||
ui->fileAdd, &addPulse);
|
||||
ui->fileAdd, addPulse);
|
||||
|
||||
ui->fileHelp->setVisible(false);
|
||||
}
|
||||
@@ -441,7 +441,8 @@ void AdvSceneSwitcher::SetupFileTab()
|
||||
|
||||
if (switcher->fileSwitches.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse = PulseWidget(ui->fileAdd, QColor(Qt::green));
|
||||
addPulse =
|
||||
HighlightWidget(ui->fileAdd, QColor(Qt::green));
|
||||
}
|
||||
ui->fileHelp->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace advss {
|
||||
|
||||
bool MediaSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
|
||||
constexpr auto media_played_to_end_idx = 8;
|
||||
constexpr auto media_any_idx = 9;
|
||||
@@ -22,7 +22,7 @@ void AdvSceneSwitcher::on_mediaAdd_clicked()
|
||||
listAddClicked(ui->mediaSwitches,
|
||||
new MediaSwitchWidget(this,
|
||||
&switcher->mediaSwitches.back()),
|
||||
ui->mediaAdd, &addPulse);
|
||||
ui->mediaAdd, addPulse);
|
||||
|
||||
ui->mediaHelp->setVisible(false);
|
||||
}
|
||||
@@ -252,7 +252,8 @@ void AdvSceneSwitcher::SetupMediaTab()
|
||||
|
||||
if (switcher->mediaSwitches.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse = PulseWidget(ui->mediaAdd, QColor(Qt::green));
|
||||
addPulse = HighlightWidget(ui->mediaAdd,
|
||||
QColor(Qt::green));
|
||||
}
|
||||
ui->mediaHelp->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
|
||||
void AdvSceneSwitcher::on_pauseAdd_clicked()
|
||||
{
|
||||
@@ -20,7 +20,7 @@ void AdvSceneSwitcher::on_pauseAdd_clicked()
|
||||
listAddClicked(ui->pauseEntries,
|
||||
new PauseEntryWidget(this,
|
||||
&switcher->pauseEntries.back()),
|
||||
ui->pauseAdd, &addPulse);
|
||||
ui->pauseAdd, addPulse);
|
||||
|
||||
ui->pauseHelp->setVisible(false);
|
||||
}
|
||||
@@ -264,7 +264,8 @@ void AdvSceneSwitcher::SetupPauseTab()
|
||||
|
||||
if (switcher->pauseEntries.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse = PulseWidget(ui->pauseAdd, QColor(Qt::green));
|
||||
addPulse = HighlightWidget(ui->pauseAdd,
|
||||
QColor(Qt::green));
|
||||
}
|
||||
ui->pauseHelp->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace advss {
|
||||
|
||||
bool RandomSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
|
||||
void AdvSceneSwitcher::on_randomAdd_clicked()
|
||||
{
|
||||
@@ -19,7 +19,7 @@ void AdvSceneSwitcher::on_randomAdd_clicked()
|
||||
listAddClicked(ui->randomSwitches,
|
||||
new RandomSwitchWidget(this,
|
||||
&switcher->randomSwitches.back()),
|
||||
ui->randomAdd, &addPulse);
|
||||
ui->randomAdd, addPulse);
|
||||
|
||||
ui->randomHelp->setVisible(false);
|
||||
}
|
||||
@@ -131,8 +131,8 @@ void AdvSceneSwitcher::SetupRandomTab()
|
||||
|
||||
if (switcher->randomSwitches.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse =
|
||||
PulseWidget(ui->randomAdd, QColor(Qt::green));
|
||||
addPulse = HighlightWidget(ui->randomAdd,
|
||||
QColor(Qt::green));
|
||||
}
|
||||
ui->randomHelp->setVisible(true);
|
||||
} else {
|
||||
@@ -147,8 +147,8 @@ void AdvSceneSwitcher::SetupRandomTab()
|
||||
}");
|
||||
if (switcher->switchIfNotMatching != NoMatchBehavior::RANDOM_SWITCH) {
|
||||
if (!switcher->disableHints) {
|
||||
PulseWidget(ui->randomDisabledWarning, QColor(Qt::red),
|
||||
QColor(0, 0, 0, 0));
|
||||
HighlightWidget(ui->randomDisabledWarning,
|
||||
QColor(Qt::red), QColor(0, 0, 0, 0));
|
||||
}
|
||||
} else {
|
||||
ui->randomDisabledWarning->setVisible(false);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
namespace advss {
|
||||
|
||||
bool ScreenRegionSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
|
||||
void AdvSceneSwitcher::ClearFrames(QListWidget *list)
|
||||
{
|
||||
@@ -79,7 +79,7 @@ void AdvSceneSwitcher::on_screenRegionAdd_clicked()
|
||||
listAddClicked(ui->screenRegionSwitches,
|
||||
new ScreenRegionWidget(
|
||||
this, &switcher->screenRegionSwitches.back()),
|
||||
ui->screenRegionAdd, &addPulse);
|
||||
ui->screenRegionAdd, addPulse);
|
||||
|
||||
ui->regionHelp->setVisible(false);
|
||||
}
|
||||
@@ -248,8 +248,8 @@ void AdvSceneSwitcher::SetupRegionTab()
|
||||
|
||||
if (switcher->screenRegionSwitches.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse = PulseWidget(ui->screenRegionAdd,
|
||||
QColor(Qt::green));
|
||||
addPulse = HighlightWidget(ui->screenRegionAdd,
|
||||
QColor(Qt::green));
|
||||
}
|
||||
ui->regionHelp->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace advss {
|
||||
constexpr auto max_extend_text_size = 150;
|
||||
|
||||
bool SceneSequenceSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
|
||||
void AdvSceneSwitcher::on_sceneSequenceAdd_clicked()
|
||||
{
|
||||
@@ -26,7 +26,7 @@ void AdvSceneSwitcher::on_sceneSequenceAdd_clicked()
|
||||
listAddClicked(ui->sceneSequenceSwitches,
|
||||
new SequenceWidget(
|
||||
this, &switcher->sceneSequenceSwitches.back()),
|
||||
ui->sceneSequenceAdd, &addPulse);
|
||||
ui->sceneSequenceAdd, addPulse);
|
||||
|
||||
ui->sequenceHelp->setVisible(false);
|
||||
}
|
||||
@@ -299,8 +299,8 @@ void AdvSceneSwitcher::SetupSequenceTab()
|
||||
|
||||
if (switcher->sceneSequenceSwitches.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse = PulseWidget(ui->sceneSequenceAdd,
|
||||
QColor(Qt::green));
|
||||
addPulse = HighlightWidget(ui->sceneSequenceAdd,
|
||||
QColor(Qt::green));
|
||||
}
|
||||
ui->sequenceHelp->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
namespace advss {
|
||||
|
||||
bool TimeSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
|
||||
void AdvSceneSwitcher::on_timeAdd_clicked()
|
||||
{
|
||||
@@ -17,7 +17,7 @@ void AdvSceneSwitcher::on_timeAdd_clicked()
|
||||
listAddClicked(ui->timeSwitches,
|
||||
new TimeSwitchWidget(this,
|
||||
&switcher->timeSwitches.back()),
|
||||
ui->timeAdd, &addPulse);
|
||||
ui->timeAdd, addPulse);
|
||||
|
||||
ui->timeHelp->setVisible(false);
|
||||
}
|
||||
@@ -197,7 +197,8 @@ void AdvSceneSwitcher::SetupTimeTab()
|
||||
|
||||
if (switcher->timeSwitches.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse = PulseWidget(ui->timeAdd, QColor(Qt::green));
|
||||
addPulse =
|
||||
HighlightWidget(ui->timeAdd, QColor(Qt::green));
|
||||
}
|
||||
ui->timeHelp->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace advss {
|
||||
|
||||
bool VideoSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
|
||||
void AdvSceneSwitcher::on_videoAdd_clicked()
|
||||
{
|
||||
@@ -24,7 +24,7 @@ void AdvSceneSwitcher::on_videoAdd_clicked()
|
||||
VideoSwitchWidget *sw =
|
||||
new VideoSwitchWidget(this, &switcher->videoSwitches.back());
|
||||
|
||||
listAddClicked(ui->videoSwitches, sw, ui->videoAdd, &addPulse);
|
||||
listAddClicked(ui->videoSwitches, sw, ui->videoAdd, addPulse);
|
||||
|
||||
ui->videoHelp->setVisible(false);
|
||||
}
|
||||
@@ -202,7 +202,8 @@ void AdvSceneSwitcher::SetupVideoTab()
|
||||
|
||||
if (switcher->videoSwitches.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse = PulseWidget(ui->videoAdd, QColor(Qt::green));
|
||||
addPulse = HighlightWidget(ui->videoAdd,
|
||||
QColor(Qt::green));
|
||||
}
|
||||
ui->videoHelp->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
namespace advss {
|
||||
|
||||
bool WindowSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
|
||||
void AdvSceneSwitcher::on_windowAdd_clicked()
|
||||
{
|
||||
@@ -21,7 +21,7 @@ void AdvSceneSwitcher::on_windowAdd_clicked()
|
||||
listAddClicked(ui->windowSwitches,
|
||||
new WindowSwitchWidget(this,
|
||||
&switcher->windowSwitches.back()),
|
||||
ui->windowAdd, &addPulse);
|
||||
ui->windowAdd, addPulse);
|
||||
|
||||
ui->windowHelp->setVisible(false);
|
||||
}
|
||||
@@ -335,8 +335,8 @@ void AdvSceneSwitcher::SetupTitleTab()
|
||||
|
||||
if (switcher->windowSwitches.size() == 0) {
|
||||
if (!switcher->disableHints) {
|
||||
addPulse =
|
||||
PulseWidget(ui->windowAdd, QColor(Qt::green));
|
||||
addPulse = HighlightWidget(ui->windowAdd,
|
||||
QColor(Qt::green));
|
||||
}
|
||||
ui->windowHelp->setVisible(true);
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "macro-helpers.hpp"
|
||||
#include "macro-properties.hpp"
|
||||
#include "macro-settings.hpp"
|
||||
#include "macro.hpp"
|
||||
#include "plugin-state-helpers.hpp"
|
||||
#include "section.hpp"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "macro-action-macro.hpp"
|
||||
#include "help-icon.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "macro.hpp"
|
||||
|
||||
@@ -168,6 +169,15 @@ void MacroActionMacro::ResolveVariablesToFixedValues()
|
||||
_actionIndex.ResolveVariables();
|
||||
}
|
||||
|
||||
static void runActionsHelper(Macro *macro, bool runElseActions, bool setInputs,
|
||||
const StringList &inputs)
|
||||
{
|
||||
if (setInputs) {
|
||||
macro->GetInputVariables().SetValues(inputs);
|
||||
}
|
||||
macro->PerformActions(!runElseActions, false, true);
|
||||
}
|
||||
|
||||
void MacroActionMacro::RunActions(Macro *actionMacro) const
|
||||
{
|
||||
if (_runOptions.skipWhenPaused && actionMacro->Paused()) {
|
||||
@@ -175,8 +185,8 @@ void MacroActionMacro::RunActions(Macro *actionMacro) const
|
||||
}
|
||||
|
||||
if (_runOptions.logic == RunOptions::Logic::IGNORE_CONDITIONS) {
|
||||
actionMacro->PerformActions(!_runOptions.runElseActions, false,
|
||||
true);
|
||||
runActionsHelper(actionMacro, _runOptions.runElseActions,
|
||||
_runOptions.setInputs, _runOptions.inputs);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -185,12 +195,16 @@ void MacroActionMacro::RunActions(Macro *actionMacro) const
|
||||
return;
|
||||
}
|
||||
|
||||
if (_runOptions.reevaluateConditionState) {
|
||||
conditionMacro->CeckMatch(true);
|
||||
}
|
||||
|
||||
if ((_runOptions.logic == RunOptions::Logic::CONDITIONS &&
|
||||
conditionMacro->Matched()) ||
|
||||
(_runOptions.logic == RunOptions::Logic::INVERT_CONDITIONS &&
|
||||
!conditionMacro->Matched())) {
|
||||
actionMacro->PerformActions(!_runOptions.runElseActions, false,
|
||||
true);
|
||||
runActionsHelper(actionMacro, _runOptions.runElseActions,
|
||||
_runOptions.setInputs, _runOptions.inputs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,11 +242,19 @@ MacroActionMacroEdit::MacroActionMacroEdit(
|
||||
_actions(new QComboBox()),
|
||||
_conditionMacros(new MacroSelection(parent)),
|
||||
_conditionBehaviors(new QComboBox()),
|
||||
_reevaluateConditionState(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.macro.type.run."
|
||||
"updateConditionMatchState"))),
|
||||
_actionTypes(new QComboBox()),
|
||||
_skipWhenPaused(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.action.macro.type.run.skipWhenPaused"))),
|
||||
_setInputs(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.action.macro.type.run.setInputs"))),
|
||||
_inputs(new MacroInputEdit()),
|
||||
_entryLayout(new QHBoxLayout()),
|
||||
_conditionLayout(new QHBoxLayout())
|
||||
_conditionLayout(new QHBoxLayout()),
|
||||
_reevaluateConditionStateLayout(new QHBoxLayout()),
|
||||
_setInputsLayout(new QHBoxLayout())
|
||||
{
|
||||
populateActionSelection(_actions);
|
||||
populateConditionBehaviorSelection(_conditionBehaviors);
|
||||
@@ -256,10 +278,30 @@ MacroActionMacroEdit::MacroActionMacroEdit(
|
||||
SLOT(ActionTypeChanged(int)));
|
||||
QWidget::connect(_skipWhenPaused, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(SkipWhenPausedChanged(int)));
|
||||
QWidget::connect(_setInputs, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(SetInputsChanged(int)));
|
||||
QWidget::connect(_inputs,
|
||||
SIGNAL(MacroInputValuesChanged(const StringList &)),
|
||||
this, SLOT(InputsChanged(const StringList &)));
|
||||
QWidget::connect(_reevaluateConditionState, SIGNAL(stateChanged(int)),
|
||||
this, SLOT(ReevaluateConditionStateChanged(int)));
|
||||
|
||||
_setInputsLayout->addWidget(_setInputs);
|
||||
_setInputsLayout->addWidget(new HelpIcon(obs_module_text(
|
||||
"AdvSceneSwitcher.action.macro.type.run.setInputs.description")));
|
||||
_setInputsLayout->addStretch();
|
||||
|
||||
_reevaluateConditionStateLayout->addWidget(_reevaluateConditionState);
|
||||
_reevaluateConditionStateLayout->addWidget(new HelpIcon(obs_module_text(
|
||||
"AdvSceneSwitcher.action.macro.type.run.updateConditionMatchState.help")));
|
||||
_reevaluateConditionStateLayout->addStretch();
|
||||
|
||||
auto layout = new QVBoxLayout();
|
||||
layout->addLayout(_entryLayout);
|
||||
layout->addLayout(_conditionLayout);
|
||||
layout->addLayout(_reevaluateConditionStateLayout);
|
||||
layout->addLayout(_setInputsLayout);
|
||||
layout->addWidget(_inputs);
|
||||
layout->addWidget(_skipWhenPaused);
|
||||
setLayout(layout);
|
||||
_entryData = entryData;
|
||||
@@ -267,6 +309,13 @@ MacroActionMacroEdit::MacroActionMacroEdit(
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void HighligthMacroSettingsButton(bool enable);
|
||||
|
||||
MacroActionMacroEdit::~MacroActionMacroEdit()
|
||||
{
|
||||
HighligthMacroSettingsButton(false);
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::UpdateEntryData()
|
||||
{
|
||||
if (!_entryData) {
|
||||
@@ -279,88 +328,89 @@ void MacroActionMacroEdit::UpdateEntryData()
|
||||
_conditionMacros->SetCurrentMacro(_entryData->_runOptions.macro);
|
||||
_conditionBehaviors->setCurrentIndex(
|
||||
static_cast<int>(_entryData->_runOptions.logic));
|
||||
_reevaluateConditionState->setChecked(
|
||||
_entryData->_runOptions.reevaluateConditionState);
|
||||
_actionTypes->setCurrentIndex(
|
||||
_entryData->_runOptions.runElseActions ? 1 : 0);
|
||||
_skipWhenPaused->setChecked(_entryData->_runOptions.skipWhenPaused);
|
||||
_setInputs->setChecked(_entryData->_runOptions.setInputs);
|
||||
SetupMacroInput(_entryData->_macro.GetMacro().get());
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::MacroChanged(const QString &text)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_macro = text;
|
||||
_actionIndex->SetMacro(_entryData->_macro.GetMacro());
|
||||
const auto ¯o = _entryData->_macro.GetMacro();
|
||||
_actionIndex->SetMacro(macro);
|
||||
SetupMacroInput(macro.get());
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::ActionChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_action = static_cast<MacroActionMacro::Action>(value);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::ActionIndexChanged(const IntVariable &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_actionIndex = value;
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::ConditionMacroChanged(const QString &text)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_runOptions.macro = text;
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::ConditionBehaviorChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_runOptions.logic =
|
||||
static_cast<MacroActionMacro::RunOptions::Logic>(value);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::ReevaluateConditionStateChanged(int value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_runOptions.reevaluateConditionState = value;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::ActionTypeChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_runOptions.runElseActions = value;
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::SkipWhenPausedChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_runOptions.skipWhenPaused = value;
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::SetInputsChanged(int value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_runOptions.setInputs = value;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::InputsChanged(const StringList &inputs)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_runOptions.inputs = inputs;
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::SetWidgetVisibility()
|
||||
{
|
||||
_entryLayout->removeWidget(_actions);
|
||||
@@ -418,10 +468,22 @@ void MacroActionMacroEdit::SetWidgetVisibility()
|
||||
|
||||
SetLayoutVisible(_conditionLayout,
|
||||
_entryData->_action == MacroActionMacro::Action::RUN);
|
||||
_conditionMacros->setVisible(
|
||||
const bool needsAdditionalConditionWidgets =
|
||||
_entryData->_action == MacroActionMacro::Action::RUN &&
|
||||
_entryData->_runOptions.logic !=
|
||||
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS);
|
||||
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS;
|
||||
_conditionMacros->setVisible(needsAdditionalConditionWidgets);
|
||||
SetLayoutVisible(_reevaluateConditionStateLayout,
|
||||
needsAdditionalConditionWidgets);
|
||||
SetLayoutVisible(_setInputsLayout,
|
||||
_entryData->_action == MacroActionMacro::Action::RUN);
|
||||
_inputs->setVisible(_entryData->_action ==
|
||||
MacroActionMacro::Action::RUN &&
|
||||
_entryData->_runOptions.setInputs);
|
||||
HighligthMacroSettingsButton(_entryData->_action ==
|
||||
MacroActionMacro::Action::RUN &&
|
||||
_entryData->_runOptions.setInputs &&
|
||||
!_inputs->HasInputsToSet());
|
||||
_actionTypes->setVisible(_entryData->_action ==
|
||||
MacroActionMacro::Action::RUN);
|
||||
_skipWhenPaused->setVisible(_entryData->_action ==
|
||||
@@ -431,12 +493,27 @@ void MacroActionMacroEdit::SetWidgetVisibility()
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::SetupMacroInput(Macro *macro) const
|
||||
{
|
||||
if (macro) {
|
||||
_inputs->SetInputVariablesAndValues(
|
||||
macro->GetInputVariables(),
|
||||
_entryData->_runOptions.inputs);
|
||||
} else {
|
||||
_inputs->SetInputVariablesAndValues({}, {});
|
||||
}
|
||||
}
|
||||
|
||||
void MacroActionMacro::RunOptions::Save(obs_data_t *obj) const
|
||||
{
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
obs_data_set_int(data, "logic", static_cast<int>(logic));
|
||||
obs_data_set_bool(data, "reevaluateConditionState",
|
||||
reevaluateConditionState);
|
||||
obs_data_set_bool(data, "runElseActions", runElseActions);
|
||||
obs_data_set_bool(data, "skipWhenPaused", skipWhenPaused);
|
||||
obs_data_set_bool(data, "setInputs", setInputs);
|
||||
inputs.Save(data, "inputs");
|
||||
macro.Save(data);
|
||||
obs_data_set_obj(obj, "runOptions", data);
|
||||
}
|
||||
@@ -448,8 +525,12 @@ void MacroActionMacro::RunOptions::Load(obs_data_t *obj)
|
||||
}
|
||||
OBSDataAutoRelease data = obs_data_get_obj(obj, "runOptions");
|
||||
logic = static_cast<Logic>(obs_data_get_int(data, "logic"));
|
||||
reevaluateConditionState =
|
||||
obs_data_get_bool(data, "reevaluateConditionState");
|
||||
runElseActions = obs_data_get_bool(data, "runElseActions");
|
||||
skipWhenPaused = obs_data_get_bool(data, "skipWhenPaused");
|
||||
setInputs = obs_data_get_bool(data, "setInputs");
|
||||
inputs.Load(data, "inputs");
|
||||
macro.Load(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "macro-input.hpp"
|
||||
#include "macro-selection.hpp"
|
||||
#include "macro-segment-selection.hpp"
|
||||
|
||||
@@ -8,7 +9,7 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
class MacroActionMacro : public MacroRefAction {
|
||||
class MacroActionMacro final : public MacroRefAction {
|
||||
public:
|
||||
MacroActionMacro(Macro *m) : MacroAction(m), MacroRefAction(m) {}
|
||||
bool PerformAction();
|
||||
@@ -31,8 +32,11 @@ public:
|
||||
INVERT_CONDITIONS,
|
||||
};
|
||||
Logic logic;
|
||||
bool reevaluateConditionState = false;
|
||||
bool runElseActions = false;
|
||||
bool skipWhenPaused = true;
|
||||
bool setInputs = false;
|
||||
StringList inputs;
|
||||
MacroRef macro;
|
||||
};
|
||||
|
||||
@@ -46,7 +50,7 @@ public:
|
||||
ENABLE_ACTION,
|
||||
TOGGLE_ACTION,
|
||||
};
|
||||
Action _action = Action::PAUSE;
|
||||
Action _action = Action::RUN;
|
||||
IntVariable _actionIndex = 1;
|
||||
RunOptions _runOptions = {};
|
||||
|
||||
@@ -57,13 +61,14 @@ private:
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
class MacroActionMacroEdit : public QWidget {
|
||||
class MacroActionMacroEdit final : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroActionMacroEdit(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<MacroActionMacro> entryData = nullptr);
|
||||
~MacroActionMacroEdit();
|
||||
void UpdateEntryData();
|
||||
static QWidget *Create(QWidget *parent,
|
||||
std::shared_ptr<MacroAction> action)
|
||||
@@ -79,24 +84,33 @@ private slots:
|
||||
void ActionIndexChanged(const IntVariable &value);
|
||||
void ConditionMacroChanged(const QString &text);
|
||||
void ConditionBehaviorChanged(int value);
|
||||
void ReevaluateConditionStateChanged(int value);
|
||||
void ActionTypeChanged(int value);
|
||||
void SkipWhenPausedChanged(int value);
|
||||
void SetInputsChanged(int value);
|
||||
void InputsChanged(const StringList &);
|
||||
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
private:
|
||||
void SetWidgetVisibility();
|
||||
void SetupMacroInput(Macro *) const;
|
||||
|
||||
MacroSelection *_macros;
|
||||
MacroSegmentSelection *_actionIndex;
|
||||
QComboBox *_actions;
|
||||
MacroSelection *_conditionMacros;
|
||||
QComboBox *_conditionBehaviors;
|
||||
QCheckBox *_reevaluateConditionState;
|
||||
QComboBox *_actionTypes;
|
||||
QCheckBox *_skipWhenPaused;
|
||||
QCheckBox *_setInputs;
|
||||
MacroInputEdit *_inputs;
|
||||
QHBoxLayout *_entryLayout;
|
||||
QHBoxLayout *_conditionLayout;
|
||||
QHBoxLayout *_reevaluateConditionStateLayout;
|
||||
QHBoxLayout *_setInputsLayout;
|
||||
|
||||
std::shared_ptr<MacroActionMacro> _entryData;
|
||||
bool _loading = true;
|
||||
|
||||
@@ -58,6 +58,8 @@ const static std::map<MacroActionVariable::Type, std::string> actionTypes = {
|
||||
"AdvSceneSwitcher.action.variable.type.padValue"},
|
||||
{MacroActionVariable::Type::TRUNCATE,
|
||||
"AdvSceneSwitcher.action.variable.type.truncateValue"},
|
||||
{MacroActionVariable::Type::SWAP_VALUES,
|
||||
"AdvSceneSwitcher.action.variable.type.swapValues"},
|
||||
};
|
||||
|
||||
static void apppend(Variable &var, const std::string &value)
|
||||
@@ -392,6 +394,17 @@ bool MacroActionVariable::PerformAction()
|
||||
var->SetValue(
|
||||
truncate(var->Value(), _direction, _stringLength));
|
||||
return true;
|
||||
case Type::SWAP_VALUES: {
|
||||
auto var2 = _variable2.lock();
|
||||
if (!var2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto tempValue = var->Value();
|
||||
var->SetValue(var2->Value());
|
||||
var2->SetValue(tempValue);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -630,6 +643,8 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
||||
_scenes(new SceneSelectionWidget(this, true, false, true, true,
|
||||
true)),
|
||||
_tempVars(new TempVariableSelection(this)),
|
||||
_tempVarsHelp(new HelpIcon(obs_module_text(
|
||||
"AdvSceneSwitcher.action.variable.type.setToTempvar.help"))),
|
||||
_sceneItemIndex(new VariableSpinBox()),
|
||||
_direction(new QComboBox()),
|
||||
_stringLength(new VariableSpinBox()),
|
||||
@@ -742,6 +757,7 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
||||
{"{{envVariableName}}", _envVariable},
|
||||
{"{{scenes}}", _scenes},
|
||||
{"{{tempVars}}", _tempVars},
|
||||
{"{{tempVarsHelp}}", _tempVarsHelp},
|
||||
{"{{sceneItemIndex}}", _sceneItemIndex},
|
||||
{"{{direction}}", _direction},
|
||||
{"{{stringLength}}", _stringLength},
|
||||
@@ -1202,6 +1218,7 @@ void MacroActionVariableEdit::SelectionChanged(const TempVariableRef &var)
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_tempVar = var;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionVariableEdit::SceneItemIndexChanged(
|
||||
@@ -1268,6 +1285,7 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
||||
{"{{envVariableName}}", _envVariable},
|
||||
{"{{scenes}}", _scenes},
|
||||
{"{{tempVars}}", _tempVars},
|
||||
{"{{tempVarsHelp}}", _tempVarsHelp},
|
||||
{"{{sceneItemIndex}}", _sceneItemIndex},
|
||||
{"{{direction}}", _direction},
|
||||
{"{{stringLength}}", _stringLength},
|
||||
@@ -1304,8 +1322,9 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
||||
AddStretchIfNecessary(_entryLayout);
|
||||
}
|
||||
|
||||
_variables2->setVisible(_entryData->_type ==
|
||||
MacroActionVariable::Type::APPEND_VAR);
|
||||
_variables2->setVisible(
|
||||
_entryData->_type == MacroActionVariable::Type::APPEND_VAR ||
|
||||
_entryData->_type == MacroActionVariable::Type::SWAP_VALUES);
|
||||
_strValue->setVisible(
|
||||
_entryData->_type ==
|
||||
MacroActionVariable::Type::SET_FIXED_VALUE ||
|
||||
@@ -1381,6 +1400,10 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
||||
MacroActionVariable::Type::SCENE_ITEM_NAME);
|
||||
_tempVars->setVisible(_entryData->_type ==
|
||||
MacroActionVariable::Type::SET_TO_TEMPVAR);
|
||||
_tempVarsHelp->setVisible(
|
||||
_entryData->_type ==
|
||||
MacroActionVariable::Type::SET_TO_TEMPVAR &&
|
||||
!_entryData->_tempVar.HasValidID());
|
||||
_sceneItemIndex->setVisible(_entryData->_type ==
|
||||
MacroActionVariable::Type::SCENE_ITEM_NAME);
|
||||
_direction->setVisible(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "help-icon.hpp"
|
||||
#include "macro-segment-selection.hpp"
|
||||
#include "regex-config.hpp"
|
||||
#include "resizing-text-edit.hpp"
|
||||
@@ -48,6 +49,7 @@ public:
|
||||
SCENE_ITEM_NAME,
|
||||
PAD,
|
||||
TRUNCATE,
|
||||
SWAP_VALUES,
|
||||
};
|
||||
|
||||
Type _type = Type::SET_FIXED_VALUE;
|
||||
@@ -185,6 +187,7 @@ private:
|
||||
VariableLineEdit *_envVariable;
|
||||
SceneSelectionWidget *_scenes;
|
||||
TempVariableSelection *_tempVars;
|
||||
HelpIcon *_tempVarsHelp;
|
||||
VariableSpinBox *_sceneItemIndex;
|
||||
QComboBox *_direction;
|
||||
VariableSpinBox *_stringLength;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "macro-properties.hpp"
|
||||
#include "macro-settings.hpp"
|
||||
#include "macro.hpp"
|
||||
#include "path-helpers.hpp"
|
||||
#include "plugin-state-helpers.hpp"
|
||||
|
||||
@@ -167,7 +167,7 @@ void MacroDock::Highlight()
|
||||
}
|
||||
if (_lastHighlightCheckTime.time_since_epoch().count() != 0 &&
|
||||
macro->WasExecutedSince(_lastHighlightCheckTime)) {
|
||||
PulseWidget(this, Qt::green, QColor(0, 0, 0, 0), true);
|
||||
HighlightWidget(this, Qt::green, QColor(0, 0, 0, 0), true);
|
||||
}
|
||||
_lastHighlightCheckTime = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
247
lib/macro/macro-input.cpp
Normal file
247
lib/macro/macro-input.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
#include "macro-input.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "log-helper.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "variable-line-edit.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <obs.hpp>
|
||||
|
||||
namespace advss {
|
||||
|
||||
void MacroInputVariables::Save(obs_data_t *obj) const
|
||||
{
|
||||
OBSDataArrayAutoRelease array = obs_data_array_create();
|
||||
for (auto &var : _inputVariables) {
|
||||
OBSDataAutoRelease arrayObj = obs_data_create();
|
||||
auto variable = var.lock();
|
||||
if (variable) {
|
||||
obs_data_set_string(arrayObj, "variableName",
|
||||
variable->Name().c_str());
|
||||
} else {
|
||||
obs_data_set_bool(arrayObj, "invalidVariable", true);
|
||||
}
|
||||
obs_data_array_push_back(array, arrayObj);
|
||||
}
|
||||
obs_data_set_array(obj, "inputVariables", array);
|
||||
}
|
||||
|
||||
void MacroInputVariables::Load(obs_data_t *obj)
|
||||
{
|
||||
OBSDataArrayAutoRelease array =
|
||||
obs_data_get_array(obj, "inputVariables");
|
||||
const size_t count = obs_data_array_count(array);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
OBSDataAutoRelease arrayObj = obs_data_array_item(array, i);
|
||||
const bool isInvalid =
|
||||
obs_data_get_bool(arrayObj, "invalidVariable");
|
||||
if (isInvalid) {
|
||||
_inputVariables.emplace_back();
|
||||
} else {
|
||||
const auto name =
|
||||
obs_data_get_string(arrayObj, "variableName");
|
||||
_inputVariables.emplace_back(
|
||||
GetWeakVariableByName(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MacroInputVariables::SetValues(const StringList &values)
|
||||
{
|
||||
if (_inputVariables.size() != (size_t)values.size()) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
blog(LOG_WARNING,
|
||||
"%s - sizes do not match (variables: %ld, values %d)",
|
||||
__func__, _inputVariables.size(), values.size());
|
||||
#else
|
||||
blog(LOG_WARNING,
|
||||
"%s - sizes do not match (variables: %ld, values %lld)",
|
||||
__func__, _inputVariables.size(), values.size());
|
||||
#endif
|
||||
}
|
||||
|
||||
for (size_t index = 0;
|
||||
index < _inputVariables.size() && index < (size_t)values.size();
|
||||
index++) {
|
||||
auto variable = _inputVariables.at(index).lock();
|
||||
if (!variable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
variable->SetValue(values.at(index));
|
||||
}
|
||||
}
|
||||
|
||||
MacroInputSelection::MacroInputSelection(QWidget *parent) : ListEditor(parent)
|
||||
{
|
||||
_list->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
}
|
||||
|
||||
void MacroInputSelection::SetInputs(const MacroInputVariables &inputs)
|
||||
{
|
||||
_currentSelection = inputs;
|
||||
for (const auto &var : inputs._inputVariables) {
|
||||
auto variable = var.lock();
|
||||
const auto name =
|
||||
variable
|
||||
? QString::fromStdString(variable->Name())
|
||||
: obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.inputSettings.invalid");
|
||||
|
||||
QVariant v = QVariant::fromValue(name);
|
||||
auto item = new QListWidgetItem(name, _list);
|
||||
item->setData(Qt::UserRole, name);
|
||||
}
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
void MacroInputSelection::Add()
|
||||
{
|
||||
std::string varName;
|
||||
bool accepted = VariableSelectionDialog::AskForVariable(this, varName);
|
||||
|
||||
if (!accepted || varName.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_currentSelection._inputVariables.emplace_back(
|
||||
GetWeakVariableByName(varName));
|
||||
|
||||
QVariant v = QVariant::fromValue(QString::fromStdString(varName));
|
||||
auto item = new QListWidgetItem(QString::fromStdString(varName), _list);
|
||||
item->setData(Qt::UserRole, QString::fromStdString(varName));
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
void MacroInputSelection::Remove()
|
||||
{
|
||||
auto item = _list->currentItem();
|
||||
int idx = _list->currentRow();
|
||||
if (!item || idx == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
_currentSelection._inputVariables.erase(
|
||||
std::next(_currentSelection._inputVariables.begin(), idx));
|
||||
|
||||
delete item;
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
void MacroInputSelection::Up()
|
||||
{
|
||||
int idx = _list->currentRow();
|
||||
if (idx < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
_list->insertItem(idx - 1, _list->takeItem(idx));
|
||||
_list->setCurrentRow(idx - 1);
|
||||
|
||||
std::iter_swap(
|
||||
std::next(_currentSelection._inputVariables.begin(), idx),
|
||||
std::next(_currentSelection._inputVariables.begin(), idx - 1));
|
||||
}
|
||||
|
||||
void MacroInputSelection::Down()
|
||||
{
|
||||
int idx = _list->currentRow();
|
||||
if (idx < 0 || idx >= _list->count()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_list->insertItem(idx + 1, _list->takeItem(idx));
|
||||
_list->setCurrentRow(idx + 1);
|
||||
|
||||
std::iter_swap(
|
||||
std::next(_currentSelection._inputVariables.begin(), idx + 1),
|
||||
std::next(_currentSelection._inputVariables.begin(), idx));
|
||||
}
|
||||
|
||||
void MacroInputSelection::Clicked(QListWidgetItem *item)
|
||||
{
|
||||
std::string varName;
|
||||
bool accepted = VariableSelectionDialog::AskForVariable(this, varName);
|
||||
|
||||
if (!accepted || varName.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
item->setText(QString::fromStdString(varName));
|
||||
int idx = _list->currentRow();
|
||||
|
||||
_currentSelection._inputVariables.at(idx) =
|
||||
GetWeakVariableByName(varName);
|
||||
}
|
||||
|
||||
MacroInputEdit::MacroInputEdit(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
_layout(new QGridLayout())
|
||||
{
|
||||
setLayout(_layout);
|
||||
}
|
||||
|
||||
void MacroInputEdit::SetInputVariablesAndValues(
|
||||
const MacroInputVariables &inputs, const StringList &values)
|
||||
{
|
||||
_variables = inputs;
|
||||
_values = values;
|
||||
if ((size_t)_values.size() < _variables._inputVariables.size()) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
for (int i = 0;
|
||||
_variables._inputVariables.size() - (size_t)_values.size();
|
||||
i++) {
|
||||
_values.push_back({});
|
||||
}
|
||||
#else
|
||||
_values.resize(_variables._inputVariables.size());
|
||||
#endif
|
||||
}
|
||||
SetupWidgets();
|
||||
}
|
||||
|
||||
bool MacroInputEdit::HasInputsToSet() const
|
||||
{
|
||||
return !_variables._inputVariables.empty();
|
||||
}
|
||||
|
||||
void HighligthMacroSettingsButton(bool enable);
|
||||
|
||||
void MacroInputEdit::SetupWidgets()
|
||||
{
|
||||
ClearLayout(_layout);
|
||||
|
||||
auto &vars = _variables._inputVariables;
|
||||
if (vars.empty()) {
|
||||
_layout->addWidget(new QLabel(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.inputSettings.noInputs")));
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t index = 0; index < vars.size(); index++) {
|
||||
auto variable = vars.at(index).lock();
|
||||
QLabel *label = new QLabel(
|
||||
variable
|
||||
? QString::fromStdString(variable->Name())
|
||||
: obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.inputSettings.invalid"));
|
||||
_layout->addWidget(label, index, 0);
|
||||
auto valueEdit = new VariableLineEdit(this);
|
||||
valueEdit->setEnabled(!!variable);
|
||||
valueEdit->setText(_values.at(index));
|
||||
connect(valueEdit, &VariableLineEdit::editingFinished,
|
||||
[this, valueEdit, index]() {
|
||||
_values[index] =
|
||||
valueEdit->text().toStdString();
|
||||
emit MacroInputValuesChanged(_values);
|
||||
});
|
||||
_layout->addWidget(valueEdit, index, 1);
|
||||
}
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
63
lib/macro/macro-input.hpp
Normal file
63
lib/macro/macro-input.hpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
#include "list-editor.hpp"
|
||||
#include "string-list.hpp"
|
||||
#include "variable.hpp"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class MacroInputVariables {
|
||||
public:
|
||||
void Save(obs_data_t *obj) const;
|
||||
void Load(obs_data_t *obj);
|
||||
void SetValues(const StringList &values);
|
||||
|
||||
private:
|
||||
std::vector<std::weak_ptr<Variable>> _inputVariables;
|
||||
friend class MacroInputSelection;
|
||||
friend class MacroInputEdit;
|
||||
};
|
||||
|
||||
class MacroInputSelection final : public ListEditor {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroInputSelection(QWidget *parent = nullptr);
|
||||
void SetInputs(const MacroInputVariables &inputs);
|
||||
MacroInputVariables GetInputs() const { return _currentSelection; }
|
||||
|
||||
private slots:
|
||||
void Add();
|
||||
void Remove();
|
||||
void Up();
|
||||
void Down();
|
||||
void Clicked(QListWidgetItem *);
|
||||
|
||||
private:
|
||||
MacroInputVariables _currentSelection;
|
||||
};
|
||||
|
||||
class MacroInputEdit final : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroInputEdit(QWidget *parent = nullptr);
|
||||
void SetInputVariablesAndValues(const MacroInputVariables &inputs,
|
||||
const StringList &values);
|
||||
bool HasInputsToSet() const;
|
||||
|
||||
signals:
|
||||
void MacroInputValuesChanged(const StringList &);
|
||||
|
||||
private:
|
||||
void SetupWidgets();
|
||||
|
||||
MacroInputVariables _variables;
|
||||
StringList _values;
|
||||
QGridLayout *_layout;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
@@ -7,68 +7,16 @@
|
||||
namespace advss {
|
||||
|
||||
MacroList::MacroList(QWidget *parent, bool allowDuplicates, bool reorder)
|
||||
: QWidget(parent),
|
||||
_list(new QListWidget()),
|
||||
_add(new QPushButton()),
|
||||
_remove(new QPushButton()),
|
||||
_up(new QPushButton()),
|
||||
_down(new QPushButton()),
|
||||
_controlsLayout(new QHBoxLayout()),
|
||||
_allowDuplicates(allowDuplicates),
|
||||
_reorder(reorder)
|
||||
: ListEditor(parent, reorder),
|
||||
_allowDuplicates(allowDuplicates)
|
||||
{
|
||||
_add->setMaximumWidth(22);
|
||||
_add->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("addIconSmall")));
|
||||
_add->setFlat(true);
|
||||
_remove->setMaximumWidth(22);
|
||||
_remove->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("removeIconSmall")));
|
||||
_remove->setFlat(true);
|
||||
_up->setMaximumWidth(22);
|
||||
_up->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("upArrowIconSmall")));
|
||||
_up->setFlat(true);
|
||||
_down->setMaximumWidth(22);
|
||||
_down->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("downArrowIconSmall")));
|
||||
_down->setFlat(true);
|
||||
|
||||
QWidget::connect(_add, SIGNAL(clicked()), this, SLOT(Add()));
|
||||
QWidget::connect(_remove, SIGNAL(clicked()), this, SLOT(Remove()));
|
||||
QWidget::connect(_up, SIGNAL(clicked()), this, SLOT(Up()));
|
||||
QWidget::connect(_down, SIGNAL(clicked()), this, SLOT(Down()));
|
||||
QWidget::connect(_list, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
|
||||
this, SLOT(MacroItemClicked(QListWidgetItem *)));
|
||||
QWidget::connect(window(),
|
||||
SIGNAL(MacroRenamed(const QString &, const QString &)),
|
||||
this,
|
||||
SLOT(MacroRename(const QString &, const QString &)));
|
||||
QWidget::connect(window(), SIGNAL(MacroRemoved(const QString &)), this,
|
||||
SLOT(MacroRemove(const QString &)));
|
||||
|
||||
_controlsLayout->addWidget(_add);
|
||||
_controlsLayout->addWidget(_remove);
|
||||
if (reorder) {
|
||||
QFrame *line = new QFrame();
|
||||
line->setFrameShape(QFrame::VLine);
|
||||
line->setFrameShadow(QFrame::Sunken);
|
||||
_controlsLayout->addWidget(line);
|
||||
}
|
||||
_controlsLayout->addWidget(_up);
|
||||
_controlsLayout->addWidget(_down);
|
||||
_controlsLayout->addStretch();
|
||||
|
||||
auto mainLayout = new QVBoxLayout;
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->addWidget(_list);
|
||||
mainLayout->addLayout(_controlsLayout);
|
||||
setLayout(mainLayout);
|
||||
|
||||
_up->setVisible(reorder);
|
||||
_down->setVisible(reorder);
|
||||
|
||||
SetMacroListSize();
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
void MacroList::SetContent(const std::vector<MacroRef> ¯os)
|
||||
@@ -89,7 +37,7 @@ void MacroList::SetContent(const std::vector<MacroRef> ¯os)
|
||||
new QListWidgetItem(listEntryName, _list);
|
||||
item->setData(Qt::UserRole, listEntryName);
|
||||
}
|
||||
SetMacroListSize();
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
void MacroList::AddControl(QWidget *widget)
|
||||
@@ -122,7 +70,7 @@ void MacroList::MacroRemove(const QString &name)
|
||||
delete _list->item(idx);
|
||||
idx = FindEntry(name.toStdString());
|
||||
}
|
||||
SetMacroListSize();
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
void MacroList::Add()
|
||||
@@ -142,7 +90,7 @@ void MacroList::Add()
|
||||
auto item =
|
||||
new QListWidgetItem(QString::fromStdString(macroName), _list);
|
||||
item->setData(Qt::UserRole, QString::fromStdString(macroName));
|
||||
SetMacroListSize();
|
||||
UpdateListSize();
|
||||
emit Added(macroName);
|
||||
}
|
||||
|
||||
@@ -154,7 +102,7 @@ void MacroList::Remove()
|
||||
return;
|
||||
}
|
||||
delete item;
|
||||
SetMacroListSize();
|
||||
UpdateListSize();
|
||||
emit Removed(idx);
|
||||
}
|
||||
|
||||
@@ -178,7 +126,7 @@ void MacroList::Down()
|
||||
}
|
||||
}
|
||||
|
||||
void MacroList::MacroItemClicked(QListWidgetItem *item)
|
||||
void MacroList::Clicked(QListWidgetItem *item)
|
||||
{
|
||||
std::string macroName;
|
||||
bool accepted = MacroSelectionDialog::AskForMacro(this, macroName);
|
||||
@@ -216,10 +164,4 @@ int MacroList::FindEntry(const std::string ¯o)
|
||||
return idx;
|
||||
}
|
||||
|
||||
void MacroList::SetMacroListSize()
|
||||
{
|
||||
SetHeightToContentHeight(_list);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
#pragma once
|
||||
#include "list-editor.hpp"
|
||||
#include "macro-ref.hpp"
|
||||
|
||||
#include <QListWidget>
|
||||
#include <QPushButton>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class ADVSS_EXPORT MacroList : public QWidget {
|
||||
class ADVSS_EXPORT MacroList final : public ListEditor {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MacroList(QWidget *parent, bool allowDuplicates, bool reorder);
|
||||
@@ -22,7 +19,7 @@ private slots:
|
||||
void Remove();
|
||||
void Up();
|
||||
void Down();
|
||||
void MacroItemClicked(QListWidgetItem *);
|
||||
void Clicked(QListWidgetItem *);
|
||||
|
||||
signals:
|
||||
void Added(const std::string &);
|
||||
@@ -33,16 +30,8 @@ signals:
|
||||
|
||||
private:
|
||||
int FindEntry(const std::string ¯o);
|
||||
void SetMacroListSize();
|
||||
|
||||
QListWidget *_list;
|
||||
QPushButton *_add;
|
||||
QPushButton *_remove;
|
||||
QPushButton *_up;
|
||||
QPushButton *_down;
|
||||
QHBoxLayout *_controlsLayout;
|
||||
const bool _allowDuplicates;
|
||||
const bool _reorder;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -130,7 +130,7 @@ void MacroSegmentList::Highlight(int idx, QColor color)
|
||||
if (!widget) {
|
||||
return;
|
||||
}
|
||||
PulseWidget(widget, color, QColor(0, 0, 0, 0), true);
|
||||
HighlightWidget(widget, color, QColor(0, 0, 0, 0), true);
|
||||
}
|
||||
|
||||
void MacroSegmentList::SetCollapsed(bool collapse)
|
||||
|
||||
@@ -175,7 +175,7 @@ void MacroSegmentSelection::MarkSelectedSegment()
|
||||
index - 1, QColor(Qt::lightGray));
|
||||
}
|
||||
|
||||
PulseWidget(this, QColor(Qt::lightGray), QColor(0, 0, 0, 0), true);
|
||||
HighlightWidget(this, QColor(Qt::lightGray), QColor(0, 0, 0, 0), true);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "macro-properties.hpp"
|
||||
#include "macro-settings.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "macro.hpp"
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
static MacroProperties macroProperties;
|
||||
static GlobalMacroSettings macroSettings;
|
||||
|
||||
void MacroProperties::Save(obs_data_t *obj) const
|
||||
void GlobalMacroSettings::Save(obs_data_t *obj) const
|
||||
{
|
||||
auto data = obs_data_create();
|
||||
obs_data_set_bool(data, "highlightExecuted", _highlightExecuted);
|
||||
@@ -20,13 +20,16 @@ void MacroProperties::Save(obs_data_t *obj) const
|
||||
obs_data_set_bool(data, "highlightActions", _highlightActions);
|
||||
obs_data_set_bool(data, "newMacroRegisterHotkey",
|
||||
_newMacroRegisterHotkeys);
|
||||
obs_data_set_obj(obj, "macroProperties", data);
|
||||
obs_data_set_obj(obj, "macroSettings", data);
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
||||
void MacroProperties::Load(obs_data_t *obj)
|
||||
void GlobalMacroSettings::Load(obs_data_t *obj)
|
||||
{
|
||||
auto data = obs_data_get_obj(obj, "macroProperties");
|
||||
auto data = obs_data_get_obj(
|
||||
obj, obs_data_has_user_value(obj, "macroProperties")
|
||||
? "macroProperties"
|
||||
: "macroSettings");
|
||||
obs_data_set_default_bool(data, "highlightExecuted", true);
|
||||
obs_data_set_default_bool(data, "highlightConditions", true);
|
||||
obs_data_set_default_bool(data, "highlightActions", true);
|
||||
@@ -38,9 +41,9 @@ void MacroProperties::Load(obs_data_t *obj)
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
||||
MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
||||
const MacroProperties &prop,
|
||||
Macro *macro)
|
||||
MacroSettingsDialog::MacroSettingsDialog(QWidget *parent,
|
||||
const GlobalMacroSettings &settings,
|
||||
Macro *macro)
|
||||
: QDialog(parent),
|
||||
_executed(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.highlightExecutedMacros"))),
|
||||
@@ -56,6 +59,7 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
||||
"AdvSceneSwitcher.macroTab.currentSkipExecutionOnStartup"))),
|
||||
_currentStopActionsIfNotDone(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.currentStopActionsIfNotDone"))),
|
||||
_currentInputs(new MacroInputSelection()),
|
||||
_currentMacroRegisterDock(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.currentRegisterDock"))),
|
||||
_currentMacroDockAddRunButton(new QCheckBox(obs_module_text(
|
||||
@@ -101,6 +105,16 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
||||
generalLayout->addWidget(_currentStopActionsIfNotDone);
|
||||
generalOptions->setLayout(generalLayout);
|
||||
|
||||
auto inputOptions = new QGroupBox(
|
||||
obs_module_text("AdvSceneSwitcher.macroTab.inputSettings"));
|
||||
auto description = new QLabel(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.inputSettings.description"));
|
||||
description->setWordWrap(true);
|
||||
auto inputLayout = new QVBoxLayout();
|
||||
inputLayout->addWidget(description);
|
||||
inputLayout->addWidget(_currentInputs);
|
||||
inputOptions->setLayout(inputLayout);
|
||||
|
||||
int row = 0;
|
||||
_dockLayout->addWidget(_currentMacroRegisterDock, row, 1, 1, 2);
|
||||
row++;
|
||||
@@ -157,13 +171,13 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
||||
connect(buttonbox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
|
||||
connect(_currentMacroRegisterDock, &QCheckBox::stateChanged, this,
|
||||
&MacroPropertiesDialog::DockEnableChanged);
|
||||
&MacroSettingsDialog::DockEnableChanged);
|
||||
connect(_currentMacroDockAddRunButton, &QCheckBox::stateChanged, this,
|
||||
&MacroPropertiesDialog::RunButtonEnableChanged);
|
||||
&MacroSettingsDialog::RunButtonEnableChanged);
|
||||
connect(_currentMacroDockAddPauseButton, &QCheckBox::stateChanged, this,
|
||||
&MacroPropertiesDialog::PauseButtonEnableChanged);
|
||||
&MacroSettingsDialog::PauseButtonEnableChanged);
|
||||
connect(_currentMacroDockAddStatusLabel, &QCheckBox::stateChanged, this,
|
||||
&MacroPropertiesDialog::StatusLabelEnableChanged);
|
||||
&MacroSettingsDialog::StatusLabelEnableChanged);
|
||||
|
||||
auto scrollArea = new QScrollArea(this);
|
||||
scrollArea->setWidgetResizable(true);
|
||||
@@ -174,6 +188,7 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
||||
layout->addWidget(highlightOptions);
|
||||
layout->addWidget(hotkeyOptions);
|
||||
layout->addWidget(generalOptions);
|
||||
layout->addWidget(inputOptions);
|
||||
layout->addWidget(_dockOptions);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
scrollArea->setWidget(contentWidget);
|
||||
@@ -183,14 +198,15 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
||||
dialogLayout->addWidget(buttonbox);
|
||||
setLayout(dialogLayout);
|
||||
|
||||
_executed->setChecked(prop._highlightExecuted);
|
||||
_conditions->setChecked(prop._highlightConditions);
|
||||
_actions->setChecked(prop._highlightActions);
|
||||
_newMacroRegisterHotkeys->setChecked(prop._newMacroRegisterHotkeys);
|
||||
_executed->setChecked(settings._highlightExecuted);
|
||||
_conditions->setChecked(settings._highlightConditions);
|
||||
_actions->setChecked(settings._highlightActions);
|
||||
_newMacroRegisterHotkeys->setChecked(settings._newMacroRegisterHotkeys);
|
||||
|
||||
if (!macro || macro->IsGroup()) {
|
||||
hotkeyOptions->hide();
|
||||
generalOptions->hide();
|
||||
inputOptions->hide();
|
||||
_dockOptions->hide();
|
||||
return;
|
||||
}
|
||||
@@ -198,6 +214,7 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
||||
_currentMacroRegisterHotkeys->setChecked(macro->PauseHotkeysEnabled());
|
||||
_currentSkipOnStartup->setChecked(macro->SkipExecOnStart());
|
||||
_currentStopActionsIfNotDone->setChecked(macro->StopActionsIfNotDone());
|
||||
_currentInputs->SetInputs(macro->GetInputVariables());
|
||||
const bool dockEnabled = macro->DockEnabled();
|
||||
_currentMacroRegisterDock->setChecked(dockEnabled);
|
||||
_currentMacroDockAddRunButton->setChecked(macro->DockHasRunButton());
|
||||
@@ -245,7 +262,7 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
||||
20);
|
||||
}
|
||||
|
||||
void MacroPropertiesDialog::DockEnableChanged(int enabled)
|
||||
void MacroSettingsDialog::DockEnableChanged(int enabled)
|
||||
{
|
||||
_currentMacroDockAddRunButton->setVisible(enabled);
|
||||
_currentMacroDockAddPauseButton->setVisible(enabled);
|
||||
@@ -270,37 +287,37 @@ void MacroPropertiesDialog::DockEnableChanged(int enabled)
|
||||
Resize();
|
||||
}
|
||||
|
||||
void MacroPropertiesDialog::RunButtonEnableChanged(int enabled)
|
||||
void MacroSettingsDialog::RunButtonEnableChanged(int enabled)
|
||||
{
|
||||
SetGridLayoutRowVisible(_dockLayout, _runButtonTextRow, enabled);
|
||||
Resize();
|
||||
}
|
||||
|
||||
void MacroPropertiesDialog::PauseButtonEnableChanged(int enabled)
|
||||
void MacroSettingsDialog::PauseButtonEnableChanged(int enabled)
|
||||
{
|
||||
SetGridLayoutRowVisible(_dockLayout, _pauseButtonTextRow, enabled);
|
||||
SetGridLayoutRowVisible(_dockLayout, _unpauseButtonTextRow, enabled);
|
||||
Resize();
|
||||
}
|
||||
|
||||
void MacroPropertiesDialog::StatusLabelEnableChanged(int enabled)
|
||||
void MacroSettingsDialog::StatusLabelEnableChanged(int enabled)
|
||||
{
|
||||
SetGridLayoutRowVisible(_dockLayout, _conditionsTrueTextRow, enabled);
|
||||
SetGridLayoutRowVisible(_dockLayout, _conditionsFalseTextRow, enabled);
|
||||
Resize();
|
||||
}
|
||||
|
||||
void MacroPropertiesDialog::Resize()
|
||||
void MacroSettingsDialog::Resize()
|
||||
{
|
||||
_dockOptions->adjustSize();
|
||||
_dockOptions->updateGeometry();
|
||||
}
|
||||
|
||||
bool MacroPropertiesDialog::AskForSettings(QWidget *parent,
|
||||
MacroProperties &userInput,
|
||||
Macro *macro)
|
||||
bool MacroSettingsDialog::AskForSettings(QWidget *parent,
|
||||
GlobalMacroSettings &userInput,
|
||||
Macro *macro)
|
||||
{
|
||||
MacroPropertiesDialog dialog(parent, userInput, macro);
|
||||
MacroSettingsDialog dialog(parent, userInput, macro);
|
||||
dialog.setWindowTitle(obs_module_text("AdvSceneSwitcher.windowTitle"));
|
||||
if (dialog.exec() != DialogCode::Accepted) {
|
||||
return false;
|
||||
@@ -337,23 +354,23 @@ bool MacroPropertiesDialog::AskForSettings(QWidget *parent,
|
||||
dialog._conditionsTrueStatusText->text().toStdString());
|
||||
macro->SetConditionsFalseStatusText(
|
||||
dialog._conditionsFalseStatusText->text().toStdString());
|
||||
|
||||
macro->SetInputVariables(dialog._currentInputs->GetInputs());
|
||||
return true;
|
||||
}
|
||||
|
||||
MacroProperties &GetGlobalMacroProperties()
|
||||
GlobalMacroSettings &GetGlobalMacroSettings()
|
||||
{
|
||||
return macroProperties;
|
||||
return macroSettings;
|
||||
}
|
||||
|
||||
void SaveGlobalMacroProperties(obs_data_t *obj)
|
||||
void SaveGlobalMacroSettings(obs_data_t *obj)
|
||||
{
|
||||
macroProperties.Save(obj);
|
||||
macroSettings.Save(obj);
|
||||
}
|
||||
|
||||
void LoadGlobalMacroProperties(obs_data_t *obj)
|
||||
void LoadGlobalMacroSettings(obs_data_t *obj)
|
||||
{
|
||||
macroProperties.Load(obj);
|
||||
macroSettings.Load(obj);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "variable-line-edit.hpp"
|
||||
#include "macro-input.hpp"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
@@ -13,7 +14,7 @@ namespace advss {
|
||||
|
||||
class Macro;
|
||||
|
||||
class MacroProperties {
|
||||
class GlobalMacroSettings {
|
||||
public:
|
||||
void Save(obs_data_t *obj) const;
|
||||
void Load(obs_data_t *obj);
|
||||
@@ -25,13 +26,14 @@ public:
|
||||
};
|
||||
|
||||
// Dialog for configuring global and individual macro specific settings
|
||||
class MacroPropertiesDialog : public QDialog {
|
||||
class MacroSettingsDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroPropertiesDialog(QWidget *parent, const MacroProperties &,
|
||||
Macro *macro);
|
||||
static bool AskForSettings(QWidget *parent, MacroProperties &userInput,
|
||||
MacroSettingsDialog(QWidget *parent, const GlobalMacroSettings &,
|
||||
Macro *macro);
|
||||
static bool AskForSettings(QWidget *parent,
|
||||
GlobalMacroSettings &userInput,
|
||||
Macro *macro);
|
||||
private slots:
|
||||
void DockEnableChanged(int);
|
||||
@@ -50,6 +52,7 @@ private:
|
||||
QCheckBox *_currentMacroRegisterHotkeys;
|
||||
QCheckBox *_currentSkipOnStartup;
|
||||
QCheckBox *_currentStopActionsIfNotDone;
|
||||
MacroInputSelection *_currentInputs;
|
||||
QCheckBox *_currentMacroRegisterDock;
|
||||
QCheckBox *_currentMacroDockAddRunButton;
|
||||
QCheckBox *_currentMacroDockAddPauseButton;
|
||||
@@ -70,8 +73,8 @@ private:
|
||||
int _conditionsFalseTextRow = -1;
|
||||
};
|
||||
|
||||
MacroProperties &GetGlobalMacroProperties();
|
||||
void SaveGlobalMacroProperties(obs_data_t *obj);
|
||||
void LoadGlobalMacroProperties(obs_data_t *obj);
|
||||
GlobalMacroSettings &GetGlobalMacroSettings();
|
||||
void SaveGlobalMacroSettings(obs_data_t *obj);
|
||||
void LoadGlobalMacroSettings(obs_data_t *obj);
|
||||
|
||||
} // namespace advss
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "macro-export-import-dialog.hpp"
|
||||
#include "macro-properties.hpp"
|
||||
#include "macro-settings.hpp"
|
||||
#include "macro-segment-copy-paste.hpp"
|
||||
#include "macro-tree.hpp"
|
||||
#include "macro.hpp"
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
static QMetaObject::Connection addPulse;
|
||||
static QObject *addPulse = nullptr;
|
||||
static QTimer onChangeHighlightTimer;
|
||||
|
||||
static bool macroNameExists(const std::string &name)
|
||||
@@ -86,7 +86,7 @@ bool AdvSceneSwitcher::AddNewMacro(std::shared_ptr<Macro> &res,
|
||||
}
|
||||
|
||||
res = std::make_shared<Macro>(
|
||||
name, GetGlobalMacroProperties()._newMacroRegisterHotkeys);
|
||||
name, GetGlobalMacroSettings()._newMacroRegisterHotkeys);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -99,7 +99,8 @@ void AdvSceneSwitcher::on_macroAdd_clicked()
|
||||
}
|
||||
|
||||
ui->macros->Add(newMacro);
|
||||
ui->macroAdd->disconnect(addPulse);
|
||||
addPulse->deleteLater();
|
||||
addPulse = nullptr;
|
||||
emit MacroAdded(QString::fromStdString(name));
|
||||
}
|
||||
|
||||
@@ -462,7 +463,7 @@ void AdvSceneSwitcher::ImportMacros()
|
||||
RunPostLoadSteps();
|
||||
|
||||
ui->macros->Reset(GetMacros(),
|
||||
GetGlobalMacroProperties()._highlightExecuted);
|
||||
GetGlobalMacroSettings()._highlightExecuted);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_macroName_editingFinished()
|
||||
@@ -742,8 +743,8 @@ void AdvSceneSwitcher::MacroSelectionChanged()
|
||||
|
||||
void AdvSceneSwitcher::HighlightOnChange()
|
||||
{
|
||||
if (!GetGlobalMacroProperties()._highlightActions &&
|
||||
!GetGlobalMacroProperties()._highlightExecuted) {
|
||||
if (!GetGlobalMacroSettings()._highlightActions &&
|
||||
!GetGlobalMacroSettings()._highlightExecuted) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -753,20 +754,20 @@ void AdvSceneSwitcher::HighlightOnChange()
|
||||
}
|
||||
|
||||
if (macro->OnChangePreventedActionsRecently()) {
|
||||
PulseWidget(ui->runMacroOnChange, Qt::yellow, Qt::transparent,
|
||||
true);
|
||||
HighlightWidget(ui->runMacroOnChange, Qt::yellow,
|
||||
Qt::transparent, true);
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_macroProperties_clicked()
|
||||
void AdvSceneSwitcher::on_macroSettings_clicked()
|
||||
{
|
||||
MacroProperties prop = GetGlobalMacroProperties();
|
||||
bool accepted = MacroPropertiesDialog::AskForSettings(
|
||||
GlobalMacroSettings prop = GetGlobalMacroSettings();
|
||||
bool accepted = MacroSettingsDialog::AskForSettings(
|
||||
this, prop, GetSelectedMacro().get());
|
||||
if (!accepted) {
|
||||
return;
|
||||
}
|
||||
GetGlobalMacroProperties() = prop;
|
||||
GetGlobalMacroSettings() = prop;
|
||||
emit HighlightMacrosChanged(prop._highlightExecuted);
|
||||
}
|
||||
|
||||
@@ -816,11 +817,11 @@ static void runSegmentHighligtChecks(AdvSceneSwitcher *ss)
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &properties = GetGlobalMacroProperties();
|
||||
if (properties._highlightConditions) {
|
||||
const auto &settings = GetGlobalMacroSettings();
|
||||
if (settings._highlightConditions) {
|
||||
runSegmentHighligtChecksHelper(ss->ui->conditionsList);
|
||||
}
|
||||
if (properties._highlightActions) {
|
||||
if (settings._highlightActions) {
|
||||
runSegmentHighligtChecksHelper(ss->ui->actionsList);
|
||||
runSegmentHighligtChecksHelper(ss->ui->elseActionsList);
|
||||
}
|
||||
@@ -832,10 +833,10 @@ void AdvSceneSwitcher::SetupMacroTab()
|
||||
ui->macros->installEventFilter(this);
|
||||
|
||||
if (GetMacros().size() == 0 && !switcher->disableHints) {
|
||||
addPulse = PulseWidget(ui->macroAdd, QColor(Qt::green));
|
||||
addPulse = HighlightWidget(ui->macroAdd, QColor(Qt::green));
|
||||
}
|
||||
ui->macros->Reset(GetMacros(),
|
||||
GetGlobalMacroProperties()._highlightExecuted);
|
||||
GetGlobalMacroSettings()._highlightExecuted);
|
||||
connect(ui->macros, SIGNAL(MacroSelectionAboutToChange()), this,
|
||||
SLOT(MacroSelectionAboutToChange()));
|
||||
connect(ui->macros, SIGNAL(MacroSelectionChanged()), this,
|
||||
@@ -1106,7 +1107,8 @@ void AdvSceneSwitcher::CopyMacro()
|
||||
Macro::PrepareMoveToGroup(macro->Parent(), newMacro);
|
||||
|
||||
ui->macros->Add(newMacro, macro);
|
||||
ui->macroAdd->disconnect(addPulse);
|
||||
addPulse->deleteLater();
|
||||
addPulse = nullptr;
|
||||
emit MacroAdded(QString::fromStdString(name));
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ void MacroTreeItem::HighlightIfExecuted()
|
||||
|
||||
if (_lastHighlightCheckTime.time_since_epoch().count() != 0 &&
|
||||
_macro->WasExecutedSince(_lastHighlightCheckTime)) {
|
||||
PulseWidget(this, Qt::green, QColor(0, 0, 0, 0), true);
|
||||
HighlightWidget(this, Qt::green, QColor(0, 0, 0, 0), true);
|
||||
}
|
||||
_lastHighlightCheckTime = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ void Macro::PrepareMoveToGroup(std::shared_ptr<Macro> group,
|
||||
}
|
||||
}
|
||||
|
||||
bool Macro::CeckMatch()
|
||||
bool Macro::CeckMatch(bool ignorePause)
|
||||
{
|
||||
if (_isGroup) {
|
||||
return false;
|
||||
@@ -109,7 +109,7 @@ bool Macro::CeckMatch()
|
||||
|
||||
_matched = false;
|
||||
for (auto &c : _conditions) {
|
||||
if (_paused) {
|
||||
if (_paused && !ignorePause) {
|
||||
vblog(LOG_INFO, "Macro %s is paused", _name.c_str());
|
||||
return false;
|
||||
}
|
||||
@@ -185,6 +185,7 @@ bool Macro::CeckMatch()
|
||||
if (!_conditionSateChanged && _performActionsOnChange) {
|
||||
_onPreventedActionExecution = true;
|
||||
}
|
||||
|
||||
_lastMatched = _matched;
|
||||
_lastCheckTime = std::chrono::high_resolution_clock::now();
|
||||
return _matched;
|
||||
@@ -348,6 +349,11 @@ void Macro::SetMatchOnChange(bool onChange)
|
||||
_performActionsOnChange = onChange;
|
||||
}
|
||||
|
||||
void Macro::SetStopActionsIfNotDone(bool stopActionsIfNotDone)
|
||||
{
|
||||
_stopActionsIfNotDone = stopActionsIfNotDone;
|
||||
}
|
||||
|
||||
void Macro::SetPaused(bool pause)
|
||||
{
|
||||
if (_paused && !pause) {
|
||||
@@ -382,6 +388,16 @@ void Macro::Stop()
|
||||
}
|
||||
}
|
||||
|
||||
MacroInputVariables Macro::GetInputVariables() const
|
||||
{
|
||||
return _inputVariables;
|
||||
}
|
||||
|
||||
void Macro::SetInputVariables(const MacroInputVariables &inputVariables)
|
||||
{
|
||||
_inputVariables = inputVariables;
|
||||
}
|
||||
|
||||
std::vector<TempVariable> Macro::GetTempVars(MacroSegment *filter) const
|
||||
{
|
||||
std::vector<TempVariable> res;
|
||||
@@ -610,6 +626,8 @@ bool Macro::Save(obs_data_t *obj) const
|
||||
}
|
||||
obs_data_set_array(obj, "elseActions", elseActions);
|
||||
|
||||
_inputVariables.Save(obj);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -748,6 +766,8 @@ bool Macro::Load(obs_data_t *obj)
|
||||
}
|
||||
UpdateElseActionIndices();
|
||||
|
||||
_inputVariables.Load(obj);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "macro-action.hpp"
|
||||
#include "macro-condition.hpp"
|
||||
#include "macro-helpers.hpp"
|
||||
#include "macro-input.hpp"
|
||||
#include "macro-ref.hpp"
|
||||
#include "variable-string.hpp"
|
||||
#include "temp-variable.hpp"
|
||||
@@ -25,35 +26,44 @@ public:
|
||||
Macro(const std::string &name = "", const bool addHotkey = false);
|
||||
virtual ~Macro();
|
||||
|
||||
bool CeckMatch();
|
||||
bool PerformActions(bool match, bool forceParallel = false,
|
||||
bool ignorePause = false);
|
||||
bool Matched() const { return _matched; }
|
||||
bool ShouldRunActions() const;
|
||||
int64_t MsSinceLastCheck() const;
|
||||
std::string Name() const { return _name; }
|
||||
void SetName(const std::string &name);
|
||||
void SetRunInParallel(bool parallel) { _runInParallel = parallel; }
|
||||
bool RunInParallel() const { return _runInParallel; }
|
||||
|
||||
bool CeckMatch(bool ignorePause = false);
|
||||
bool Matched() const { return _matched; }
|
||||
int64_t MsSinceLastCheck() const;
|
||||
bool ShouldRunActions() const;
|
||||
bool PerformActions(bool match, bool forceParallel = false,
|
||||
bool ignorePause = false);
|
||||
|
||||
void SetPaused(bool pause = true);
|
||||
bool Paused() const { return _paused; }
|
||||
bool WasPausedSince(
|
||||
const std::chrono::high_resolution_clock::time_point &) const;
|
||||
|
||||
void Stop();
|
||||
bool GetStop() const { return _stop; }
|
||||
void ResetTimers();
|
||||
|
||||
void SetMatchOnChange(bool onChange);
|
||||
bool MatchOnChange() const { return _performActionsOnChange; }
|
||||
|
||||
void SetSkipExecOnStart(bool skip) { _skipExecOnStart = skip; }
|
||||
bool SkipExecOnStart() const { return _skipExecOnStart; }
|
||||
void SetStopActionsIfNotDone(bool stopActionsIfNotDone)
|
||||
{
|
||||
_stopActionsIfNotDone = stopActionsIfNotDone;
|
||||
}
|
||||
|
||||
void SetStopActionsIfNotDone(bool stopActionsIfNotDone);
|
||||
bool StopActionsIfNotDone() const { return _stopActionsIfNotDone; }
|
||||
|
||||
int RunCount() const { return _runCount; };
|
||||
void ResetRunCount() { _runCount = 0; };
|
||||
void ResetTimers();
|
||||
|
||||
void AddHelperThread(std::thread &&);
|
||||
bool GetStop() const { return _stop; }
|
||||
void Stop();
|
||||
void SetRunInParallel(bool parallel) { _runInParallel = parallel; }
|
||||
bool RunInParallel() const { return _runInParallel; }
|
||||
|
||||
// Input variables
|
||||
MacroInputVariables GetInputVariables() const;
|
||||
void SetInputVariables(const MacroInputVariables &);
|
||||
|
||||
// Temporary variable helpers
|
||||
std::vector<TempVariable> GetTempVars(MacroSegment *filter) const;
|
||||
@@ -98,19 +108,21 @@ public:
|
||||
bool SwitchesScene() const;
|
||||
|
||||
// UI helpers
|
||||
const QList<int> &GetActionConditionSplitterPosition() const;
|
||||
void SetActionConditionSplitterPosition(const QList<int>);
|
||||
const QList<int> &GetElseActionSplitterPosition() const;
|
||||
const QList<int> &GetActionConditionSplitterPosition() const;
|
||||
void SetElseActionSplitterPosition(const QList<int>);
|
||||
const QList<int> &GetElseActionSplitterPosition() const;
|
||||
bool HasValidSplitterPositions() const;
|
||||
bool WasExecutedSince(
|
||||
const std::chrono::high_resolution_clock::time_point &) const;
|
||||
bool OnChangePreventedActionsRecently();
|
||||
void ResetUIHelpers();
|
||||
|
||||
// Hotkeys
|
||||
void EnablePauseHotkeys(bool);
|
||||
bool PauseHotkeysEnabled() const;
|
||||
|
||||
// Docks
|
||||
void EnableDock(bool);
|
||||
bool DockEnabled() const { return _registerDock; }
|
||||
void SetDockHasRunButton(bool value);
|
||||
@@ -182,6 +194,8 @@ private:
|
||||
obs_hotkey_id _unpauseHotkey = OBS_INVALID_HOTKEY_ID;
|
||||
obs_hotkey_id _togglePauseHotkey = OBS_INVALID_HOTKEY_ID;
|
||||
|
||||
MacroInputVariables _inputVariables;
|
||||
|
||||
// UI helpers
|
||||
bool _onPreventedActionExecution = false;
|
||||
|
||||
|
||||
@@ -11,19 +11,16 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
static bool registerTab();
|
||||
static void setupTab(QTabWidget *);
|
||||
static bool registerTabDone = registerTab();
|
||||
|
||||
static ActionQueueTable *tabWidget = nullptr;
|
||||
|
||||
static bool registerTab()
|
||||
void RegisterActionQueueTab()
|
||||
{
|
||||
AddPluginInitStep([]() {
|
||||
AddSetupTabCallback("actionQueueTab", ActionQueueTable::Create,
|
||||
setupTab);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
static void setTabVisible(QTabWidget *tabWidget, bool visible)
|
||||
@@ -70,11 +67,11 @@ static QStringList getCellLabels(ActionQueue *queue, bool addName = true)
|
||||
<< QString::fromStdString(obs_module_text(
|
||||
queue->IsRunning()
|
||||
? "AdvSceneSwitcher.actionQueueTab.yes"
|
||||
: "AdvSceneSwitcher.actionQueueTab.yes"))
|
||||
: "AdvSceneSwitcher.actionQueueTab.no"))
|
||||
<< QString::fromStdString(obs_module_text(
|
||||
queue->RunsOnStartup()
|
||||
? "AdvSceneSwitcher.actionQueueTab.yes"
|
||||
: "AdvSceneSwitcher.actionQueueTab.yes"));
|
||||
: "AdvSceneSwitcher.actionQueueTab.no"));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -223,14 +220,15 @@ static void setupTab(QTabWidget *tab)
|
||||
}
|
||||
|
||||
QWidget::connect(ActionQueueSignalManager::Instance(),
|
||||
&ActionQueueSignalManager::Rename,
|
||||
&ActionQueueSignalManager::Rename, tab,
|
||||
[](const QString &oldName, const QString &newName) {
|
||||
RenameItemTableRow(tabWidget->Table(), oldName,
|
||||
newName);
|
||||
});
|
||||
QWidget::connect(
|
||||
ActionQueueSignalManager::Instance(),
|
||||
&ActionQueueSignalManager::Add, [tab](const QString &name) {
|
||||
&ActionQueueSignalManager::Add, tab,
|
||||
[tab](const QString &name) {
|
||||
AddItemTableRow(
|
||||
tabWidget->Table(),
|
||||
getCellLabels(GetWeakActionQueueByQString(name)
|
||||
@@ -241,7 +239,7 @@ static void setupTab(QTabWidget *tab)
|
||||
setTabVisible(tab, true);
|
||||
});
|
||||
QWidget::connect(ActionQueueSignalManager::Instance(),
|
||||
&ActionQueueSignalManager::Remove,
|
||||
&ActionQueueSignalManager::Remove, tab,
|
||||
[](const QString &name) {
|
||||
RemoveItemTableRow(tabWidget->Table(), name);
|
||||
if (tabWidget->Table()->rowCount() == 0) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "action-queue.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "plugin-state-helpers.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
@@ -11,6 +12,8 @@ std::deque<std::shared_ptr<Item>> &GetActionQueues()
|
||||
return queues;
|
||||
}
|
||||
|
||||
void RegisterActionQueueTab();
|
||||
|
||||
void SetupActionQueues()
|
||||
{
|
||||
static bool done = false;
|
||||
@@ -19,6 +22,7 @@ void SetupActionQueues()
|
||||
}
|
||||
AddSaveStep(SaveActionQueues);
|
||||
AddLoadStep(LoadActionQueues);
|
||||
RegisterActionQueueTab();
|
||||
done = true;
|
||||
}
|
||||
|
||||
@@ -376,11 +380,24 @@ static bool queueWithNameExists(const std::string &name)
|
||||
return !GetWeakActionQueueByName(name).expired();
|
||||
}
|
||||
|
||||
static void signalImportedQueues(void *varsPtr)
|
||||
{
|
||||
auto queues = std::unique_ptr<std::vector<std::shared_ptr<Item>>>(
|
||||
static_cast<std::vector<std::shared_ptr<Item>> *>(varsPtr));
|
||||
for (const auto &queue : *queues) {
|
||||
ActionQueueSignalManager::Instance()->Add(
|
||||
QString::fromStdString(queue->Name()));
|
||||
}
|
||||
}
|
||||
|
||||
void ImportQueues(obs_data_t *data)
|
||||
{
|
||||
OBSDataArrayAutoRelease array =
|
||||
obs_data_get_array(data, "actionQueues");
|
||||
size_t count = obs_data_array_count(array);
|
||||
|
||||
auto importedQueues = new std::vector<std::shared_ptr<Item>>;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
OBSDataAutoRelease arrayElement = obs_data_array_item(array, i);
|
||||
auto queue = ActionQueue::Create();
|
||||
@@ -389,7 +406,10 @@ void ImportQueues(obs_data_t *data)
|
||||
continue;
|
||||
}
|
||||
queues.emplace_back(queue);
|
||||
importedQueues->emplace_back(queue);
|
||||
}
|
||||
|
||||
QeueUITask(signalImportedQueues, importedQueues);
|
||||
}
|
||||
|
||||
std::weak_ptr<ActionQueue> GetWeakActionQueueByName(const std::string &name)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "switch-video.hpp"
|
||||
#include "switch-network.hpp"
|
||||
|
||||
#include "macro-properties.hpp"
|
||||
#include "macro-settings.hpp"
|
||||
#include "duration-control.hpp"
|
||||
#include "priority-helper.hpp"
|
||||
#include "plugin-state-helpers.hpp"
|
||||
|
||||
19
lib/utils/help-icon.cpp
Normal file
19
lib/utils/help-icon.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "help-icon.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
HelpIcon::HelpIcon(const QString &tooltip, QWidget *parent) : QLabel(parent)
|
||||
{
|
||||
auto path = GetThemeTypeName() == "Light"
|
||||
? ":/res/images/help.svg"
|
||||
: ":/res/images/help_light.svg";
|
||||
QIcon icon(path);
|
||||
QPixmap pixmap = icon.pixmap(QSize(16, 16));
|
||||
setPixmap(pixmap);
|
||||
if (!tooltip.isEmpty()) {
|
||||
setToolTip(tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
15
lib/utils/help-icon.hpp
Normal file
15
lib/utils/help-icon.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "export-symbol-helper.hpp"
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class ADVSS_EXPORT HelpIcon : public QLabel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HelpIcon(const QString &tooltip = "", QWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
@@ -81,6 +81,7 @@ public:
|
||||
"AdvSceneSwitcher.item.nameNotAvailable",
|
||||
std::string_view configureTooltip = "", QWidget *parent = 0);
|
||||
virtual ~ItemSelection() = default;
|
||||
Item *GetCurrentItem();
|
||||
void SetItem(const std::string &);
|
||||
void ShowRenameContextMenu(bool value);
|
||||
|
||||
@@ -99,8 +100,6 @@ signals:
|
||||
void ItemRenamed(const QString &oldName, const QString &name);
|
||||
|
||||
private:
|
||||
Item *GetCurrentItem();
|
||||
|
||||
FilterComboBox *_selection;
|
||||
QPushButton *_modify;
|
||||
CreateItemFunc _create;
|
||||
|
||||
77
lib/utils/list-editor.cpp
Normal file
77
lib/utils/list-editor.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "list-editor.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
ListEditor::ListEditor(QWidget *parent, bool reorder)
|
||||
: QWidget(parent),
|
||||
_list(new QListWidget()),
|
||||
_add(new QPushButton()),
|
||||
_remove(new QPushButton()),
|
||||
_up(new QPushButton()),
|
||||
_down(new QPushButton()),
|
||||
_controlsLayout(new QHBoxLayout()),
|
||||
_mainLayout(new QVBoxLayout())
|
||||
{
|
||||
_add->setMaximumWidth(22);
|
||||
_add->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("addIconSmall")));
|
||||
_add->setFlat(true);
|
||||
_remove->setMaximumWidth(22);
|
||||
_remove->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("removeIconSmall")));
|
||||
_remove->setFlat(true);
|
||||
_up->setMaximumWidth(22);
|
||||
_up->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("upArrowIconSmall")));
|
||||
_up->setFlat(true);
|
||||
_down->setMaximumWidth(22);
|
||||
_down->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("downArrowIconSmall")));
|
||||
_down->setFlat(true);
|
||||
|
||||
QWidget::connect(_add, SIGNAL(clicked()), this, SLOT(Add()));
|
||||
QWidget::connect(_remove, SIGNAL(clicked()), this, SLOT(Remove()));
|
||||
QWidget::connect(_up, SIGNAL(clicked()), this, SLOT(Up()));
|
||||
QWidget::connect(_down, SIGNAL(clicked()), this, SLOT(Down()));
|
||||
QWidget::connect(_list, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
|
||||
this, SLOT(Clicked(QListWidgetItem *)));
|
||||
|
||||
_controlsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
_controlsLayout->addWidget(_add);
|
||||
_controlsLayout->addWidget(_remove);
|
||||
if (reorder) {
|
||||
auto line = new QFrame();
|
||||
line->setFrameShape(QFrame::VLine);
|
||||
line->setFrameShadow(QFrame::Sunken);
|
||||
_controlsLayout->addWidget(line);
|
||||
_controlsLayout->addWidget(_up);
|
||||
_controlsLayout->addWidget(_down);
|
||||
}
|
||||
_controlsLayout->addStretch();
|
||||
|
||||
_mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
_mainLayout->addWidget(_list);
|
||||
_mainLayout->addLayout(_controlsLayout);
|
||||
setLayout(_mainLayout);
|
||||
}
|
||||
|
||||
void ListEditor::showEvent(QShowEvent *e)
|
||||
{
|
||||
QWidget::showEvent(e);
|
||||
// This is necessary as the list viewport might not be updated yet while
|
||||
// the list was hidden.
|
||||
// Thus, previous calls to UpdateListSize() might not have resized the
|
||||
// widget correctly, for example due to not regarding the horizontal
|
||||
// scrollbar yet.
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
void ListEditor::UpdateListSize()
|
||||
{
|
||||
SetHeightToContentHeight(_list);
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
38
lib/utils/list-editor.hpp
Normal file
38
lib/utils/list-editor.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include "export-symbol-helper.hpp"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QListWidget>
|
||||
#include <QLayout>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class ADVSS_EXPORT ListEditor : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ListEditor(QWidget *parent = nullptr, bool reorder = true);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *);
|
||||
|
||||
private slots:
|
||||
virtual void Add() = 0;
|
||||
virtual void Remove() = 0;
|
||||
virtual void Up(){};
|
||||
virtual void Down(){};
|
||||
virtual void Clicked(QListWidgetItem *) {}
|
||||
|
||||
protected:
|
||||
void UpdateListSize();
|
||||
|
||||
QListWidget *_list;
|
||||
QPushButton *_add;
|
||||
QPushButton *_remove;
|
||||
QPushButton *_up;
|
||||
QPushButton *_down;
|
||||
QHBoxLayout *_controlsLayout;
|
||||
QVBoxLayout *_mainLayout;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
@@ -81,9 +81,13 @@ void ResourceTable::SetHelpVisible(bool visible) const
|
||||
|
||||
void ResourceTable::HighlightAddButton(bool enable)
|
||||
{
|
||||
_add->disconnect(_highlightConnection);
|
||||
if (_highlightConnection) {
|
||||
_highlightConnection->deleteLater();
|
||||
_highlightConnection = nullptr;
|
||||
}
|
||||
|
||||
if (enable && HighlightUIElementsEnabled()) {
|
||||
_highlightConnection = PulseWidget(_add, QColor(Qt::green));
|
||||
_highlightConnection = HighlightWidget(_add, QColor(Qt::green));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ private:
|
||||
QPushButton *_remove;
|
||||
QLabel *_help;
|
||||
|
||||
QMetaObject::Connection _highlightConnection;
|
||||
QObject *_highlightConnection = nullptr;
|
||||
};
|
||||
|
||||
EXPORT void AddItemTableRow(QTableWidget *table, const QStringList &cells);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <obs-frontend-api.h>
|
||||
#include <QAction>
|
||||
#include <QMainWindow>
|
||||
#include <QPalette>
|
||||
#include <QToolBar>
|
||||
|
||||
namespace advss {
|
||||
@@ -15,6 +16,50 @@ namespace advss {
|
||||
void OpenSettingsWindow();
|
||||
StatusDock *dock = nullptr;
|
||||
|
||||
static QString colorToString(const QColor &color)
|
||||
{
|
||||
return QString("rgba(") + QString::number(color.red()) + "," +
|
||||
QString::number(color.green()) + "," +
|
||||
QString::number(color.blue()) + "," +
|
||||
QString::number(color.alpha()) + ")";
|
||||
}
|
||||
|
||||
static QString getDefaultBackgroundColorString()
|
||||
{
|
||||
static QString defaultColorString;
|
||||
static bool cacheReady = false;
|
||||
|
||||
if (cacheReady) {
|
||||
return defaultColorString;
|
||||
}
|
||||
|
||||
QWidget tempWidget;
|
||||
const auto defaultColor =
|
||||
tempWidget.palette().brush(QPalette::Window).color();
|
||||
defaultColorString = colorToString(defaultColor);
|
||||
|
||||
cacheReady = true;
|
||||
return defaultColorString;
|
||||
}
|
||||
|
||||
static QString getDefaultTextColorString()
|
||||
{
|
||||
static QString defaultColorString;
|
||||
static bool cacheReady = false;
|
||||
|
||||
if (cacheReady) {
|
||||
return defaultColorString;
|
||||
}
|
||||
|
||||
QLabel tempWidget;
|
||||
const auto defaultColor =
|
||||
tempWidget.palette().brush(QPalette::Text).color();
|
||||
defaultColorString = colorToString(defaultColor);
|
||||
|
||||
cacheReady = true;
|
||||
return defaultColorString;
|
||||
}
|
||||
|
||||
StatusControl::StatusControl(QWidget *parent, bool noLayout)
|
||||
: QWidget(parent),
|
||||
_button(new QPushButton("-", this)),
|
||||
@@ -28,30 +73,22 @@ StatusControl::StatusControl(QWidget *parent, bool noLayout)
|
||||
_statusPrefix->setWordWrap(true);
|
||||
_statusPrefix->setSizePolicy(QSizePolicy::Expanding,
|
||||
QSizePolicy::Expanding);
|
||||
_status->setStyleSheet("QLabel{ \
|
||||
border-style: outset; \
|
||||
border-width: 2px; \
|
||||
border-radius: 7px; \
|
||||
border-color: rgb(0,0,0,0) \
|
||||
}");
|
||||
_status->setSizePolicy(QSizePolicy::Maximum,
|
||||
QSizePolicy::MinimumExpanding);
|
||||
|
||||
QWidget::connect(_button, SIGNAL(clicked()), this,
|
||||
SLOT(ButtonClicked()));
|
||||
|
||||
if (!noLayout) {
|
||||
QHBoxLayout *statusLayout = new QHBoxLayout();
|
||||
statusLayout->addWidget(_statusPrefix);
|
||||
statusLayout->addStretch();
|
||||
statusLayout->addWidget(_status);
|
||||
statusLayout->setStretch(0, 10);
|
||||
_buttonLayout->setContentsMargins(0, 0, 0, 0);
|
||||
_buttonLayout->addWidget(_button);
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
layout->addLayout(statusLayout);
|
||||
_statusPrefix->setAlignment(Qt::AlignCenter);
|
||||
_status->setAlignment(Qt::AlignCenter);
|
||||
layout->addWidget(_statusPrefix);
|
||||
layout->addWidget(_status);
|
||||
layout->addLayout(_buttonLayout);
|
||||
setLayout(layout);
|
||||
} else {
|
||||
_status->setSizePolicy(QSizePolicy::Maximum,
|
||||
QSizePolicy::MinimumExpanding);
|
||||
}
|
||||
|
||||
if (PluginIsRunning()) {
|
||||
@@ -94,7 +131,8 @@ void StatusControl::SetStarted()
|
||||
_button->setText(
|
||||
obs_module_text("AdvSceneSwitcher.generalTab.status.stop"));
|
||||
_status->setText(obs_module_text("AdvSceneSwitcher.status.active"));
|
||||
_status->disconnect(_pulse);
|
||||
_pulse->deleteLater();
|
||||
SetStatusStyleSheet(false);
|
||||
_setToStopped = false;
|
||||
}
|
||||
|
||||
@@ -103,13 +141,31 @@ void StatusControl::SetStopped()
|
||||
_button->setText(
|
||||
obs_module_text("AdvSceneSwitcher.generalTab.status.start"));
|
||||
_status->setText(obs_module_text("AdvSceneSwitcher.status.inactive"));
|
||||
SetStatusStyleSheet(true);
|
||||
if (HighlightUIElementsEnabled()) {
|
||||
_pulse = PulseWidget(_status, QColor(Qt::red),
|
||||
QColor(0, 0, 0, 0));
|
||||
_pulse = HighlightWidget(_status, QColor(Qt::red),
|
||||
QColor(0, 0, 0, 0));
|
||||
}
|
||||
_setToStopped = true;
|
||||
}
|
||||
|
||||
void StatusControl::SetStatusStyleSheet(bool stopped) const
|
||||
{
|
||||
auto style = QString("QLabel{ "
|
||||
"background-color: ");
|
||||
if (stopped) {
|
||||
style += getDefaultBackgroundColorString() + "; ";
|
||||
} else {
|
||||
style += "transparent; ";
|
||||
}
|
||||
style += "border-style: outset; "
|
||||
"border-width: 2px; "
|
||||
"border-radius: 7px; "
|
||||
"border-color: " +
|
||||
getDefaultTextColorString() + "; }";
|
||||
_status->setStyleSheet(style);
|
||||
}
|
||||
|
||||
StatusDock::StatusDock(QWidget *parent) : OBSDock(parent)
|
||||
{
|
||||
setWindowTitle(obs_module_text("AdvSceneSwitcher.windowTitle"));
|
||||
|
||||
@@ -26,13 +26,14 @@ private slots:
|
||||
private:
|
||||
void SetStopped();
|
||||
void SetStarted();
|
||||
void SetStatusStyleSheet(bool stopped) const;
|
||||
|
||||
QPushButton *_button;
|
||||
QHBoxLayout *_buttonLayout;
|
||||
QLabel *_status;
|
||||
QLabel *_statusPrefix;
|
||||
QTimer _timer;
|
||||
QMetaObject::Connection _pulse;
|
||||
QObject *_pulse = nullptr;
|
||||
|
||||
bool _setToStopped = true;
|
||||
};
|
||||
|
||||
@@ -49,60 +49,12 @@ void StringList::ResolveVariables()
|
||||
StringListEdit::StringListEdit(QWidget *parent, const QString &addString,
|
||||
const QString &addStringDescription,
|
||||
int maxStringSize, bool allowEmtpy)
|
||||
: QWidget(parent),
|
||||
_list(new QListWidget()),
|
||||
_add(new QPushButton()),
|
||||
_remove(new QPushButton()),
|
||||
_up(new QPushButton()),
|
||||
_down(new QPushButton()),
|
||||
: ListEditor(parent),
|
||||
_addString(addString),
|
||||
_addStringDescription(addStringDescription),
|
||||
_maxStringSize(maxStringSize),
|
||||
_allowEmpty(allowEmtpy)
|
||||
{
|
||||
_add->setMaximumWidth(22);
|
||||
_add->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("addIconSmall")));
|
||||
_add->setFlat(true);
|
||||
_remove->setMaximumWidth(22);
|
||||
_remove->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("removeIconSmall")));
|
||||
_remove->setFlat(true);
|
||||
_up->setMaximumWidth(22);
|
||||
_up->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("upArrowIconSmall")));
|
||||
_up->setFlat(true);
|
||||
_down->setMaximumWidth(22);
|
||||
_down->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("downArrowIconSmall")));
|
||||
_down->setFlat(true);
|
||||
|
||||
QWidget::connect(_add, SIGNAL(clicked()), this, SLOT(Add()));
|
||||
QWidget::connect(_remove, SIGNAL(clicked()), this, SLOT(Remove()));
|
||||
QWidget::connect(_up, SIGNAL(clicked()), this, SLOT(Up()));
|
||||
QWidget::connect(_down, SIGNAL(clicked()), this, SLOT(Down()));
|
||||
QWidget::connect(_list, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
|
||||
this, SLOT(Clicked(QListWidgetItem *)));
|
||||
|
||||
auto controlLayout = new QHBoxLayout;
|
||||
controlLayout->setContentsMargins(0, 0, 0, 0);
|
||||
controlLayout->addWidget(_add);
|
||||
controlLayout->addWidget(_remove);
|
||||
QFrame *line = new QFrame();
|
||||
line->setFrameShape(QFrame::VLine);
|
||||
line->setFrameShadow(QFrame::Sunken);
|
||||
controlLayout->addWidget(line);
|
||||
controlLayout->addWidget(_up);
|
||||
controlLayout->addWidget(_down);
|
||||
controlLayout->addStretch();
|
||||
|
||||
auto mainLayout = new QVBoxLayout;
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->addWidget(_list);
|
||||
mainLayout->addLayout(controlLayout);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
}
|
||||
|
||||
void StringListEdit::SetStringList(const StringList &list)
|
||||
@@ -115,7 +67,7 @@ void StringListEdit::SetStringList(const StringList &list)
|
||||
_list);
|
||||
item->setData(Qt::UserRole, string);
|
||||
}
|
||||
SetListSize();
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
void StringListEdit::SetMaxStringSize(int size)
|
||||
@@ -123,17 +75,6 @@ void StringListEdit::SetMaxStringSize(int size)
|
||||
_maxStringSize = size;
|
||||
}
|
||||
|
||||
void StringListEdit::showEvent(QShowEvent *e)
|
||||
{
|
||||
QWidget::showEvent(e);
|
||||
// This is necessary as the list viewport might not be updated yet
|
||||
// while the list was hidden.
|
||||
// Thus, previous calls to SetListSize() might not have resized the
|
||||
// widget correctly, for example due to not regarding the horizontal
|
||||
// scrollbar yet.
|
||||
SetListSize();
|
||||
}
|
||||
|
||||
void StringListEdit::Add()
|
||||
{
|
||||
std::string name;
|
||||
@@ -153,7 +94,7 @@ void StringListEdit::Add()
|
||||
_stringList << string;
|
||||
|
||||
// Delay resizing to make sure the list viewport was already updated
|
||||
QTimer::singleShot(0, this, [this]() { SetListSize(); });
|
||||
QTimer::singleShot(0, this, [this]() { UpdateListSize(); });
|
||||
|
||||
StringListChanged(_stringList);
|
||||
}
|
||||
@@ -173,7 +114,7 @@ void StringListEdit::Remove()
|
||||
delete item;
|
||||
|
||||
// Delay resizing to make sure the list viewport was already updated
|
||||
QTimer::singleShot(0, this, [this]() { SetListSize(); });
|
||||
QTimer::singleShot(0, this, [this]() { UpdateListSize(); });
|
||||
|
||||
StringListChanged(_stringList);
|
||||
}
|
||||
@@ -222,16 +163,9 @@ void StringListEdit::Clicked(QListWidgetItem *item)
|
||||
_stringList[idx] = string;
|
||||
|
||||
// Delay resizing to make sure the list viewport was already updated
|
||||
QTimer::singleShot(0, this, [this]() { SetListSize(); });
|
||||
QTimer::singleShot(0, this, [this]() { UpdateListSize(); });
|
||||
|
||||
StringListChanged(_stringList);
|
||||
}
|
||||
|
||||
void StringListEdit::SetListSize()
|
||||
{
|
||||
SetHeightToContentHeight(_list);
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
@@ -1,27 +1,25 @@
|
||||
#pragma once
|
||||
#include "variable-string.hpp"
|
||||
#include "export-symbol-helper.hpp"
|
||||
#include "list-editor.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "variable-string.hpp"
|
||||
|
||||
#include <obs-data.h>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QListWidget>
|
||||
#include <QStringList>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class StringList : public QList<StringVariable> {
|
||||
public:
|
||||
bool Save(obs_data_t *obj, const char *name,
|
||||
const char *elementName = "string") const;
|
||||
bool Load(obs_data_t *obj, const char *name,
|
||||
const char *elementName = "string");
|
||||
void ResolveVariables();
|
||||
EXPORT bool Save(obs_data_t *obj, const char *name,
|
||||
const char *elementName = "string") const;
|
||||
EXPORT bool Load(obs_data_t *obj, const char *name,
|
||||
const char *elementName = "string");
|
||||
EXPORT void ResolveVariables();
|
||||
|
||||
friend class StringListEdit;
|
||||
};
|
||||
|
||||
class StringListEdit : public QWidget {
|
||||
class ADVSS_EXPORT StringListEdit final : public ListEditor {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@@ -31,9 +29,6 @@ public:
|
||||
void SetStringList(const StringList &);
|
||||
void SetMaxStringSize(int);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *);
|
||||
|
||||
private slots:
|
||||
void Add();
|
||||
void Remove();
|
||||
@@ -44,16 +39,8 @@ signals:
|
||||
void StringListChanged(const StringList &);
|
||||
|
||||
private:
|
||||
void SetListSize();
|
||||
|
||||
StringList _stringList;
|
||||
|
||||
QListWidget *_list;
|
||||
QPushButton *_add;
|
||||
QPushButton *_remove;
|
||||
QPushButton *_up;
|
||||
QPushButton *_down;
|
||||
|
||||
QString _addString;
|
||||
QString _addStringDescription;
|
||||
int _maxStringSize = 170;
|
||||
@@ -5,8 +5,15 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
EXPORT std::mutex *GetMutex();
|
||||
EXPORT std::lock_guard<std::mutex> LockContext();
|
||||
EXPORT std::unique_lock<std::mutex> *GetLoopLock();
|
||||
// Helper used in macro segment edit widgets
|
||||
#define GUARD_LOADING_AND_LOCK() \
|
||||
if (_loading || !_entryData) { \
|
||||
return; \
|
||||
} \
|
||||
auto lock = LockContext();
|
||||
|
||||
[[nodiscard]] EXPORT std::mutex *GetMutex();
|
||||
[[nodiscard]] EXPORT std::lock_guard<std::mutex> LockContext();
|
||||
[[nodiscard]] EXPORT std::unique_lock<std::mutex> *GetLoopLock();
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -161,7 +161,7 @@ void SetTabOrder(QTabWidget *tabWidget)
|
||||
|
||||
void SetCurrentTab(QTabWidget *tabWidget)
|
||||
{
|
||||
if (lastOpenedTab >= 0) {
|
||||
if (lastOpenedTab >= 0 && tabWidget->isTabVisible(lastOpenedTab)) {
|
||||
tabWidget->setCurrentIndex(lastOpenedTab);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
EXPORT void Load(obs_data_t *, Macro *, const char *name = "tempVar");
|
||||
EXPORT std::optional<const TempVariable> GetTempVariable(Macro *) const;
|
||||
EXPORT bool operator==(const TempVariableRef &other) const;
|
||||
bool HasValidID() const { return !_id.empty(); }
|
||||
|
||||
private:
|
||||
enum class SegmentType { NONE, CONDITION, ACTION, ELSEACTION };
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
QMetaObject::Connection PulseWidget(QWidget *widget, QColor startColor,
|
||||
QColor endColor, bool once)
|
||||
QObject *HighlightWidget(QWidget *widget, QColor startColor, QColor endColor,
|
||||
bool once)
|
||||
{
|
||||
QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect(widget);
|
||||
widget->setGraphicsEffect(effect);
|
||||
@@ -24,33 +24,22 @@ QMetaObject::Connection PulseWidget(QWidget *widget, QColor startColor,
|
||||
animation->setEndValue(endColor);
|
||||
animation->setDuration(1000);
|
||||
|
||||
QMetaObject::Connection con;
|
||||
// Clean up the effect when the animation is deleted
|
||||
QWidget::connect(animation, &QPropertyAnimation::destroyed, [widget]() {
|
||||
if (widget) {
|
||||
widget->setGraphicsEffect(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
if (once) {
|
||||
auto widgetPtr = widget;
|
||||
con = QWidget::connect(
|
||||
animation, &QPropertyAnimation::finished,
|
||||
[widgetPtr]() {
|
||||
if (widgetPtr) {
|
||||
widgetPtr->setGraphicsEffect(nullptr);
|
||||
}
|
||||
});
|
||||
animation->start(QPropertyAnimation::DeleteWhenStopped);
|
||||
} else {
|
||||
auto widgetPtr = widget;
|
||||
con = QWidget::connect(
|
||||
animation, &QPropertyAnimation::finished,
|
||||
[animation, widgetPtr]() {
|
||||
QTimer *timer = new QTimer(widgetPtr);
|
||||
QWidget::connect(timer, &QTimer::timeout,
|
||||
[animation] {
|
||||
animation->start();
|
||||
});
|
||||
timer->setSingleShot(true);
|
||||
timer->start(1000);
|
||||
});
|
||||
animation->start();
|
||||
return animation;
|
||||
}
|
||||
return con;
|
||||
|
||||
QWidget::connect(animation, &QPropertyAnimation::finished,
|
||||
[animation]() { animation->start(); });
|
||||
animation->start();
|
||||
return animation;
|
||||
}
|
||||
|
||||
static int getHorizontalScrollBarHeight(QListWidget *list)
|
||||
@@ -166,4 +155,9 @@ std::string GetThemeTypeName()
|
||||
#endif
|
||||
}
|
||||
|
||||
void QeueUITask(void (*task)(void *param), void *param)
|
||||
{
|
||||
obs_queue_task(OBS_TASK_UI, task, param, false);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
EXPORT QMetaObject::Connection PulseWidget(QWidget *widget, QColor startColor,
|
||||
QColor endColor = QColor(0, 0, 0, 0),
|
||||
bool once = false);
|
||||
// Returns QObject* to QPropertyAnimation object
|
||||
// Delete it to stop the animation
|
||||
EXPORT QObject *HighlightWidget(QWidget *widget, QColor startColor,
|
||||
QColor endColor = QColor(0, 0, 0, 0),
|
||||
bool once = false);
|
||||
|
||||
EXPORT void SetHeightToContentHeight(QListWidget *list);
|
||||
EXPORT void SetButtonIcon(QPushButton *button, const char *path);
|
||||
@@ -29,4 +31,6 @@ EXPORT void DisplayTrayMessage(const QString &title, const QString &msg,
|
||||
|
||||
EXPORT std::string GetThemeTypeName();
|
||||
|
||||
void QeueUITask(void (*task)(void *param), void *param);
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -76,15 +76,15 @@ std::string ToString(double value)
|
||||
}
|
||||
|
||||
void listAddClicked(QListWidget *list, QWidget *newWidget,
|
||||
QPushButton *addButton,
|
||||
QMetaObject::Connection *addHighlight)
|
||||
QPushButton *addButton, QObject *addHighlight)
|
||||
{
|
||||
if (!list || !newWidget) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (addButton && addHighlight) {
|
||||
addButton->disconnect(*addHighlight);
|
||||
if (addHighlight) {
|
||||
addHighlight->deleteLater();
|
||||
addHighlight = nullptr;
|
||||
}
|
||||
|
||||
QListWidgetItem *item;
|
||||
|
||||
@@ -24,7 +24,7 @@ std::string ToString(double value);
|
||||
|
||||
void listAddClicked(QListWidget *list, QWidget *newWidget,
|
||||
QPushButton *addButton = nullptr,
|
||||
QMetaObject::Connection *addHighlight = nullptr);
|
||||
QObject *addHighlight = nullptr);
|
||||
bool listMoveUp(QListWidget *list);
|
||||
bool listMoveDown(QListWidget *list);
|
||||
|
||||
|
||||
@@ -154,6 +154,15 @@ static void updateVariableStatus(QTableWidget *table)
|
||||
|
||||
UpdateItemTableRow(table, row,
|
||||
getCellLabels(variable.get(), false));
|
||||
|
||||
// Special tooltip handling for the "last used" cell
|
||||
const auto lastUsedItem = table->item(row, 4);
|
||||
if (!lastUsedItem) {
|
||||
continue;
|
||||
}
|
||||
const auto lastUsedTooltip =
|
||||
formatLastChangedTooltip(variable.get());
|
||||
lastUsedItem->setToolTip(lastUsedTooltip);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,14 +273,14 @@ static void setupTab(QTabWidget *tab)
|
||||
}
|
||||
|
||||
QWidget::connect(VariableSignalManager::Instance(),
|
||||
&VariableSignalManager::Rename,
|
||||
&VariableSignalManager::Rename, tab,
|
||||
[](const QString &oldName, const QString &newName) {
|
||||
RenameItemTableRow(tabWidget->Table(), oldName,
|
||||
newName);
|
||||
});
|
||||
QWidget::connect(
|
||||
VariableSignalManager::Instance(), &VariableSignalManager::Add,
|
||||
[tab](const QString &name) {
|
||||
tab, [tab](const QString &name) {
|
||||
AddItemTableRow(
|
||||
tabWidget->Table(),
|
||||
getCellLabels(GetVariableByQString(name)));
|
||||
@@ -280,7 +289,7 @@ static void setupTab(QTabWidget *tab)
|
||||
setTabVisible(tab, true);
|
||||
});
|
||||
QWidget::connect(VariableSignalManager::Instance(),
|
||||
&VariableSignalManager::Remove,
|
||||
&VariableSignalManager::Remove, tab,
|
||||
[](const QString &name) {
|
||||
RemoveItemTableRow(tabWidget->Table(), name);
|
||||
if (tabWidget->Table()->rowCount() == 0) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "variable.hpp"
|
||||
#include "math-helpers.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <QGridLayout>
|
||||
@@ -267,6 +268,53 @@ void VariableSelection::SetVariable(const std::weak_ptr<Variable> &variable_)
|
||||
}
|
||||
}
|
||||
|
||||
VariableSelectionDialog::VariableSelectionDialog(QWidget *parent)
|
||||
: QDialog(parent),
|
||||
_variableSelection(new VariableSelection(this))
|
||||
{
|
||||
setModal(true);
|
||||
setWindowModality(Qt::WindowModality::ApplicationModal);
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
setMinimumWidth(350);
|
||||
setMinimumHeight(70);
|
||||
|
||||
auto buttonbox = new QDialogButtonBox(QDialogButtonBox::Ok |
|
||||
QDialogButtonBox::Cancel);
|
||||
|
||||
buttonbox->setCenterButtons(true);
|
||||
connect(buttonbox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttonbox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
|
||||
auto selectionLayout = new QHBoxLayout();
|
||||
selectionLayout->addWidget(new QLabel(
|
||||
obs_module_text("AdvSceneSwitcher.variable.selectionDialog")));
|
||||
selectionLayout->addWidget(_variableSelection);
|
||||
selectionLayout->addStretch();
|
||||
auto layout = new QVBoxLayout();
|
||||
layout->addLayout(selectionLayout);
|
||||
layout->addWidget(buttonbox);
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
QWidget *GetSettingsWindow();
|
||||
|
||||
bool VariableSelectionDialog::AskForVariable(QWidget *parent,
|
||||
std::string &varName)
|
||||
{
|
||||
VariableSelectionDialog dialog(GetSettingsWindow());
|
||||
dialog.setWindowTitle(obs_module_text("AdvSceneSwitcher.windowTitle"));
|
||||
|
||||
if (dialog.exec() != DialogCode::Accepted) {
|
||||
return false;
|
||||
}
|
||||
auto item = dialog._variableSelection->GetCurrentItem();
|
||||
if (!item) {
|
||||
return false;
|
||||
}
|
||||
varName = item->Name();
|
||||
return true;
|
||||
}
|
||||
|
||||
VariableSignalManager::VariableSignalManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
}
|
||||
@@ -375,11 +423,23 @@ void LoadVariables(obs_data_t *obj)
|
||||
obs_data_array_release(variablesArray);
|
||||
}
|
||||
|
||||
static void signalImportedVariables(void *varsPtr)
|
||||
{
|
||||
auto vars = std::unique_ptr<std::vector<std::shared_ptr<Item>>>(
|
||||
static_cast<std::vector<std::shared_ptr<Item>> *>(varsPtr));
|
||||
for (const auto &var : *vars) {
|
||||
VariableSignalManager::Instance()->Add(
|
||||
QString::fromStdString(var->Name()));
|
||||
}
|
||||
}
|
||||
|
||||
void ImportVariables(obs_data_t *data)
|
||||
{
|
||||
obs_data_array_t *array = obs_data_get_array(data, "variables");
|
||||
size_t count = obs_data_array_count(array);
|
||||
|
||||
auto importedVars = new std::vector<std::shared_ptr<Item>>;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *arrayElement = obs_data_array_item(array, i);
|
||||
auto var = Variable::Create();
|
||||
@@ -391,9 +451,12 @@ void ImportVariables(obs_data_t *data)
|
||||
}
|
||||
|
||||
GetVariables().emplace_back(var);
|
||||
importedVars->emplace_back(var);
|
||||
}
|
||||
|
||||
obs_data_array_release(array);
|
||||
|
||||
QeueUITask(signalImportedVariables, importedVars);
|
||||
}
|
||||
|
||||
std::chrono::high_resolution_clock::time_point GetLastVariableChangeTime()
|
||||
|
||||
@@ -82,6 +82,17 @@ public:
|
||||
void SetVariable(const std::weak_ptr<Variable> &);
|
||||
};
|
||||
|
||||
class VariableSelectionDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
VariableSelectionDialog(QWidget *parent);
|
||||
static bool AskForVariable(QWidget *parent, std::string &variableName);
|
||||
|
||||
private:
|
||||
VariableSelection *_variableSelection;
|
||||
};
|
||||
|
||||
class ADVSS_EXPORT VariableSignalManager : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
@@ -87,6 +87,8 @@ target_sources(
|
||||
macro-condition-file.hpp
|
||||
macro-condition-filter.cpp
|
||||
macro-condition-filter.hpp
|
||||
macro-condition-folder.cpp
|
||||
macro-condition-folder.hpp
|
||||
macro-condition-hotkey.cpp
|
||||
macro-condition-hotkey.hpp
|
||||
macro-condition-idle.cpp
|
||||
@@ -166,8 +168,6 @@ target_sources(
|
||||
utils/source-settings-helpers.hpp
|
||||
utils/source-setting.cpp
|
||||
utils/source-setting.hpp
|
||||
utils/string-list.cpp
|
||||
utils/string-list.hpp
|
||||
utils/striped-frame.cpp
|
||||
utils/striped-frame.hpp
|
||||
utils/text-helpers.cpp
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "macro-action-run.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
#include <QProcess>
|
||||
#include <QDesktopServices>
|
||||
@@ -130,16 +129,10 @@ MacroActionRunEdit::MacroActionRunEdit(
|
||||
_waitLayout(new QHBoxLayout()),
|
||||
_wait(new QCheckBox()),
|
||||
_timeout(new DurationSelection(this, true, 0.1)),
|
||||
_waitHelp(new QLabel())
|
||||
_waitHelp(new HelpIcon(obs_module_text(
|
||||
"AdvSceneSwitcher.action.run.wait.help.tooltip")))
|
||||
{
|
||||
QString helpIconPath = GetThemeTypeName() == "Light"
|
||||
? ":/res/images/help.svg"
|
||||
: ":/res/images/help_light.svg";
|
||||
QIcon helpIcon(helpIconPath);
|
||||
_waitHelp->setPixmap(helpIcon.pixmap(QSize(16, 16)));
|
||||
_waitHelp->hide();
|
||||
_waitHelp->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.action.run.wait.help.tooltip"));
|
||||
|
||||
QWidget::connect(_procConfig,
|
||||
SIGNAL(ConfigChanged(const ProcessConfig &)), this,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "help-icon.hpp"
|
||||
#include "process-config.hpp"
|
||||
#include "duration-control.hpp"
|
||||
|
||||
@@ -60,7 +61,7 @@ private:
|
||||
QHBoxLayout *_waitLayout;
|
||||
QCheckBox *_wait;
|
||||
DurationSelection *_timeout;
|
||||
QLabel *_waitHelp;
|
||||
HelpIcon *_waitHelp;
|
||||
|
||||
std::shared_ptr<MacroActionRun> _entryData;
|
||||
bool _loading = true;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "macro-action-window.hpp"
|
||||
#include "help-icon.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "platform-funcs.hpp"
|
||||
#include "selection-helpers.hpp"
|
||||
@@ -163,7 +164,8 @@ MacroActionWindowEdit::MacroActionWindowEdit(
|
||||
: QWidget(parent),
|
||||
_actions(new QComboBox()),
|
||||
_windows(new QComboBox()),
|
||||
_regex(new RegexConfigWidget(this))
|
||||
_regex(new RegexConfigWidget(this)),
|
||||
_infoLayout(new QHBoxLayout())
|
||||
{
|
||||
populateActionSelection(_actions);
|
||||
|
||||
@@ -171,6 +173,15 @@ MacroActionWindowEdit::MacroActionWindowEdit(
|
||||
_windows->setMaxVisibleItems(20);
|
||||
PopulateWindowSelection(_windows);
|
||||
|
||||
auto focusLimitation = new QLabel(obs_module_text(
|
||||
"AdvSceneSwitcher.action.window.type.setFocusWindow.limitation"));
|
||||
_infoLayout->addWidget(focusLimitation);
|
||||
|
||||
auto focusLimitationDetails = new HelpIcon(obs_module_text(
|
||||
"AdvSceneSwitcher.action.window.type.setFocusWindow.limitation.details"));
|
||||
_infoLayout->addWidget(focusLimitationDetails);
|
||||
_infoLayout->addStretch();
|
||||
|
||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
QWidget::connect(_windows, SIGNAL(currentTextChanged(const QString &)),
|
||||
@@ -179,12 +190,15 @@ MacroActionWindowEdit::MacroActionWindowEdit(
|
||||
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
|
||||
SLOT(RegexChanged(const RegexConfig &)));
|
||||
|
||||
auto layout = new QHBoxLayout;
|
||||
auto entryLayout = new QHBoxLayout;
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.window.entry"),
|
||||
layout,
|
||||
entryLayout,
|
||||
{{"{{actions}}", _actions},
|
||||
{"{{windows}}", _windows},
|
||||
{"{{regex}}", _regex}});
|
||||
auto layout = new QVBoxLayout();
|
||||
layout->addLayout(entryLayout);
|
||||
layout->addLayout(_infoLayout);
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
@@ -200,8 +214,7 @@ void MacroActionWindowEdit::UpdateEntryData()
|
||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||
_windows->setCurrentText(QString::fromStdString(_entryData->_window));
|
||||
_regex->SetRegexConfig(_entryData->_regex);
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionWindowEdit::WindowChanged(const QString &text)
|
||||
@@ -228,6 +241,15 @@ void MacroActionWindowEdit::RegexChanged(const RegexConfig ®ex)
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionWindowEdit::SetWidgetVisibility()
|
||||
{
|
||||
SetLayoutVisible(_infoLayout,
|
||||
_entryData->_action ==
|
||||
MacroActionWindow::Action::SET_FOCUS_WINDOW);
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionWindowEdit::ActionChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
@@ -236,6 +258,7 @@ void MacroActionWindowEdit::ActionChanged(int value)
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_action = static_cast<MacroActionWindow::Action>(value);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -59,9 +59,12 @@ signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
private:
|
||||
void SetWidgetVisibility();
|
||||
|
||||
QComboBox *_actions;
|
||||
QComboBox *_windows;
|
||||
RegexConfigWidget *_regex;
|
||||
QHBoxLayout *_infoLayout;
|
||||
|
||||
std::shared_ptr<MacroActionWindow> _entryData;
|
||||
bool _loading = true;
|
||||
|
||||
@@ -61,26 +61,48 @@ MacroConditionAudio::~MacroConditionAudio()
|
||||
obs_volmeter_destroy(_volmeter);
|
||||
}
|
||||
|
||||
float MacroConditionAudio::GetVolumePeak()
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
using namespace std::chrono;
|
||||
static constexpr std::chrono::milliseconds timeout = 250ms;
|
||||
|
||||
// OBS might rarely not update _peak quickly enough when very low
|
||||
// intervals are configured on the General tab.
|
||||
// In that case _peak might be set to negative infinity still, which
|
||||
// will result in unexpected behavior, so we use the previously valid
|
||||
// peak value instead.
|
||||
//
|
||||
// If no volume update was received within a timeout window, however, it
|
||||
// is assumed, that the source no longer produces any audio output and
|
||||
// thus a peak volume value of negative infinity is used.
|
||||
|
||||
float peak;
|
||||
|
||||
std::lock_guard<std::mutex> lock(_peakMutex);
|
||||
auto msPassedSinceLastUpdate = duration_cast<milliseconds>(
|
||||
high_resolution_clock::now() - _lastPeakUpdate);
|
||||
if (_lastPeakUpdate.time_since_epoch().count() != 0 &&
|
||||
msPassedSinceLastUpdate > timeout) {
|
||||
peak = -std::numeric_limits<float>::infinity();
|
||||
} else {
|
||||
peak = _peakUpdated ? _peak : _previousPeak;
|
||||
}
|
||||
|
||||
_previousPeak = peak;
|
||||
_peak = -std::numeric_limits<float>::infinity();
|
||||
_peakUpdated = false;
|
||||
|
||||
return peak;
|
||||
}
|
||||
|
||||
bool MacroConditionAudio::CheckOutputCondition()
|
||||
{
|
||||
bool ret = false;
|
||||
OBSSourceAutoRelease source =
|
||||
obs_weak_source_get_source(_audioSource.GetSource());
|
||||
|
||||
// OBS might very rarely not update _peak quickly enough when very low
|
||||
// intervals are configured on the General tab.
|
||||
// In that case _peak might be set to negative infinity still, which
|
||||
// will result in unexpected behavior, so we use the previously valid
|
||||
// peak value instead.
|
||||
float peak;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_peakMutex);
|
||||
peak = _peakUpdated ? _peak : _previousPeak;
|
||||
_previousPeak = peak;
|
||||
_peak = -std::numeric_limits<float>::infinity();
|
||||
_peakUpdated = false;
|
||||
}
|
||||
|
||||
float peak = GetVolumePeak();
|
||||
double curVolume = _useDb ? peak : DecibelToPercent(peak) * 100;
|
||||
|
||||
switch (_outputCondition) {
|
||||
@@ -349,6 +371,7 @@ void MacroConditionAudio::SetVolumeLevel(void *data, const float *,
|
||||
}
|
||||
}
|
||||
c->_peakUpdated = true;
|
||||
c->_lastPeakUpdate = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
void MacroConditionAudio::ResetVolmeter()
|
||||
|
||||
@@ -71,12 +71,14 @@ private:
|
||||
bool CheckMonitor();
|
||||
bool CheckBalance();
|
||||
void SetupTempVars();
|
||||
float GetVolumePeak();
|
||||
|
||||
Type _checkType = Type::OUTPUT_VOLUME;
|
||||
std::mutex _peakMutex;
|
||||
float _peak = -std::numeric_limits<float>::infinity();
|
||||
float _previousPeak = -std::numeric_limits<float>::infinity();
|
||||
bool _peakUpdated = false;
|
||||
std::chrono::high_resolution_clock::time_point _lastPeakUpdate = {};
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "macro-condition-clipboard.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
@@ -197,19 +196,11 @@ MacroConditionClipboardEdit::MacroConditionClipboardEdit(
|
||||
_conditions(new QComboBox(this)),
|
||||
_text(new VariableTextEdit(this)),
|
||||
_regex(new RegexConfigWidget(parent)),
|
||||
_urlInfo(new QLabel())
|
||||
_urlInfo(new HelpIcon(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.clipboard.urlTooltip")))
|
||||
{
|
||||
populateCompareModeselection(_conditions);
|
||||
|
||||
QString path = GetThemeTypeName() == "Light"
|
||||
? ":/res/images/help.svg"
|
||||
: ":/res/images/help_light.svg";
|
||||
QIcon icon(path);
|
||||
QPixmap pixmap = icon.pixmap(QSize(16, 16));
|
||||
_urlInfo->setPixmap(pixmap);
|
||||
_urlInfo->hide();
|
||||
_urlInfo->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.clipboard.urlTooltip"));
|
||||
|
||||
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ConditionChanged(int)));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "filter-combo-box.hpp"
|
||||
#include "help-icon.hpp"
|
||||
#include "message-buffer.hpp"
|
||||
#include "message-dispatcher.hpp"
|
||||
#include "regex-config.hpp"
|
||||
@@ -83,7 +84,7 @@ private:
|
||||
QComboBox *_conditions;
|
||||
VariableTextEdit *_text;
|
||||
RegexConfigWidget *_regex;
|
||||
QLabel *_urlInfo;
|
||||
HelpIcon *_urlInfo;
|
||||
|
||||
std::shared_ptr<MacroConditionClipboard> _entryData;
|
||||
bool _loading = true;
|
||||
|
||||
@@ -47,17 +47,19 @@ bool MacroConditionFilter::CheckConditionHelper(const OBSWeakSource &filter)
|
||||
case Condition::DISABLED:
|
||||
ret = !obs_source_enabled(filterSource);
|
||||
break;
|
||||
case Condition::SETTINGS_MATCH:
|
||||
case Condition::SETTINGS_MATCH: {
|
||||
ret = CompareSourceSettings(filter, _settings, _regex);
|
||||
if (IsReferencedInVars()) {
|
||||
SetVariableValue(GetSourceSettings(filter));
|
||||
}
|
||||
const auto settings = GetSourceSettings(filter);
|
||||
SetVariableValue(settings);
|
||||
SetTempVarValue("settings", settings);
|
||||
break;
|
||||
}
|
||||
case Condition::SETTINGS_CHANGED: {
|
||||
std::string settings = GetSourceSettings(filter);
|
||||
const auto settings = GetSourceSettings(filter);
|
||||
ret = !_currentSettings.empty() && settings != _currentSettings;
|
||||
_currentSettings = settings;
|
||||
SetVariableValue(settings);
|
||||
SetTempVarValue("settings", settings);
|
||||
break;
|
||||
}
|
||||
case Condition::INDIVIDUAL_SETTING_MATCH: {
|
||||
@@ -68,6 +70,7 @@ bool MacroConditionFilter::CheckConditionHelper(const OBSWeakSource &filter)
|
||||
ret = _regex.Enabled() ? _regex.Matches(*value, _settings)
|
||||
: value == std::string(_settings);
|
||||
SetVariableValue(*value);
|
||||
SetTempVarValue("setting", *value);
|
||||
break;
|
||||
}
|
||||
case Condition::INDIVIDUAL_SETTING_CHANGED: {
|
||||
@@ -78,6 +81,7 @@ bool MacroConditionFilter::CheckConditionHelper(const OBSWeakSource &filter)
|
||||
ret = _currentSettingsValue != value;
|
||||
_currentSettingsValue = *value;
|
||||
SetVariableValue(*value);
|
||||
SetTempVarValue("setting", *value);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -122,7 +126,8 @@ bool MacroConditionFilter::Load(obs_data_t *obj)
|
||||
MacroCondition::Load(obj);
|
||||
_source.Load(obj);
|
||||
_filter.Load(obj, _source, "filter");
|
||||
_condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
|
||||
SetCondition(
|
||||
static_cast<Condition>(obs_data_get_int(obj, "condition")));
|
||||
_settings.Load(obj, "settings");
|
||||
_regex.Load(obj);
|
||||
// TOOD: remove in future version
|
||||
@@ -142,6 +147,37 @@ std::string MacroConditionFilter::GetShortDesc() const
|
||||
return "";
|
||||
}
|
||||
|
||||
void MacroConditionFilter::SetCondition(Condition cond)
|
||||
{
|
||||
_condition = cond;
|
||||
SetupTempVars();
|
||||
}
|
||||
|
||||
void MacroConditionFilter::SetupTempVars()
|
||||
{
|
||||
MacroCondition::SetupTempVars();
|
||||
switch (_condition) {
|
||||
case Condition::ENABLED:
|
||||
break;
|
||||
case Condition::DISABLED:
|
||||
break;
|
||||
case Condition::SETTINGS_MATCH:
|
||||
case Condition::SETTINGS_CHANGED:
|
||||
AddTempvar("settings",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.filter.settings"));
|
||||
break;
|
||||
case Condition::INDIVIDUAL_SETTING_MATCH:
|
||||
case Condition::INDIVIDUAL_SETTING_CHANGED:
|
||||
AddTempvar("setting",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.filter.setting"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void populateConditionSelection(QComboBox *list)
|
||||
{
|
||||
for (const auto &[_, name] : filterConditionTypes) {
|
||||
@@ -263,8 +299,8 @@ void MacroConditionFilterEdit::ConditionChanged(int index)
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_condition =
|
||||
static_cast<MacroConditionFilter::Condition>(index);
|
||||
_entryData->SetCondition(
|
||||
static_cast<MacroConditionFilter::Condition>(index));
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
@@ -283,7 +319,7 @@ void MacroConditionFilterEdit::GetSettingsClicked()
|
||||
}
|
||||
|
||||
QString value;
|
||||
if (_entryData->_condition ==
|
||||
if (_entryData->GetCondition() ==
|
||||
MacroConditionFilter::Condition::SETTINGS_MATCH) {
|
||||
value = FormatJsonString(GetSourceSettings(filters.at(0)));
|
||||
} else {
|
||||
@@ -346,21 +382,22 @@ void MacroConditionFilterEdit::RefreshVariableSourceSelectionValue()
|
||||
void MacroConditionFilterEdit::SetWidgetVisibility()
|
||||
{
|
||||
const bool showSettingsControls =
|
||||
_entryData->_condition ==
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionFilter::Condition::SETTINGS_MATCH ||
|
||||
_entryData->_condition ==
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionFilter::Condition::INDIVIDUAL_SETTING_MATCH;
|
||||
_settings->setVisible(showSettingsControls);
|
||||
_getSettings->setVisible(showSettingsControls);
|
||||
_regex->setVisible(showSettingsControls);
|
||||
_settingSelection->setVisible(
|
||||
_entryData->_condition == MacroConditionFilter::Condition::
|
||||
INDIVIDUAL_SETTING_MATCH ||
|
||||
_entryData->_condition == MacroConditionFilter::Condition::
|
||||
INDIVIDUAL_SETTING_CHANGED);
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionFilter::Condition::INDIVIDUAL_SETTING_MATCH ||
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionFilter::Condition::
|
||||
INDIVIDUAL_SETTING_CHANGED);
|
||||
_refreshSettingSelection->setVisible(
|
||||
_entryData->_condition == MacroConditionFilter::Condition::
|
||||
INDIVIDUAL_SETTING_MATCH &&
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionFilter::Condition::INDIVIDUAL_SETTING_MATCH &&
|
||||
(_entryData->_source.GetType() ==
|
||||
SourceSelection::Type::VARIABLE ||
|
||||
_entryData->_filter.GetType() ==
|
||||
@@ -377,7 +414,8 @@ void MacroConditionFilterEdit::UpdateEntryData()
|
||||
|
||||
_sources->SetSource(_entryData->_source);
|
||||
_filters->SetFilter(_entryData->_source, _entryData->_filter);
|
||||
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||
_conditions->setCurrentIndex(
|
||||
static_cast<int>(_entryData->GetCondition()));
|
||||
_settings->setPlainText(_entryData->_settings);
|
||||
_regex->SetRegexConfig(_entryData->_regex);
|
||||
const auto filters =
|
||||
|
||||
@@ -33,17 +33,20 @@ public:
|
||||
INDIVIDUAL_SETTING_MATCH,
|
||||
INDIVIDUAL_SETTING_CHANGED,
|
||||
};
|
||||
void SetCondition(Condition);
|
||||
Condition GetCondition() const { return _condition; }
|
||||
|
||||
SourceSelection _source;
|
||||
FilterSelection _filter;
|
||||
Condition _condition = Condition::ENABLED;
|
||||
StringVariable _settings = "";
|
||||
RegexConfig _regex;
|
||||
SourceSetting _setting;
|
||||
|
||||
private:
|
||||
void SetupTempVars();
|
||||
bool CheckConditionHelper(const OBSWeakSource &);
|
||||
|
||||
Condition _condition = Condition::ENABLED;
|
||||
std::string _currentSettings;
|
||||
std::string _currentSettingsValue;
|
||||
|
||||
|
||||
407
plugins/base/macro-condition-folder.cpp
Normal file
407
plugins/base/macro-condition-folder.cpp
Normal file
@@ -0,0 +1,407 @@
|
||||
#include "macro-condition-folder.hpp"
|
||||
#include "help-icon.hpp"
|
||||
#include "macro-helpers.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace advss {
|
||||
|
||||
const std::string MacroConditionFolder::id = "folder";
|
||||
|
||||
bool MacroConditionFolder::_registered = MacroConditionFactory::Register(
|
||||
MacroConditionFolder::id,
|
||||
{MacroConditionFolder::Create, MacroConditionFolderEdit::Create,
|
||||
"AdvSceneSwitcher.condition.folder"});
|
||||
|
||||
static const std::map<MacroConditionFolder::Condition, std::string> conditions =
|
||||
{
|
||||
{MacroConditionFolder::Condition::ANY,
|
||||
"AdvSceneSwitcher.condition.folder.condition.any"},
|
||||
{MacroConditionFolder::Condition::FILE_ADD,
|
||||
"AdvSceneSwitcher.condition.folder.condition.fileAdd"},
|
||||
{MacroConditionFolder::Condition::FILE_CHANGE,
|
||||
"AdvSceneSwitcher.condition.folder.condition.fileChange"},
|
||||
{MacroConditionFolder::Condition::FILE_REMOVE,
|
||||
"AdvSceneSwitcher.condition.folder.condition.fileRemove"},
|
||||
{MacroConditionFolder::Condition::FOLDER_ADD,
|
||||
"AdvSceneSwitcher.condition.folder.condition.folderAdd"},
|
||||
{MacroConditionFolder::Condition::FOLDER_REMOVE,
|
||||
"AdvSceneSwitcher.condition.folder.condition.folderRemove"},
|
||||
};
|
||||
|
||||
MacroConditionFolder::MacroConditionFolder(Macro *m) : MacroCondition(m, true)
|
||||
{
|
||||
}
|
||||
|
||||
bool MacroConditionFolder::CheckCondition()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
bool ret = _matched;
|
||||
if (_lastWatchedValue != _folder.UnresolvedValue()) {
|
||||
SetupWatcher();
|
||||
}
|
||||
|
||||
SetTempVarValues();
|
||||
|
||||
_newFiles.clear();
|
||||
_changedFiles.clear();
|
||||
_removedFiles.clear();
|
||||
_newDirs.clear();
|
||||
_removedDirs.clear();
|
||||
_matched = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool MacroConditionFolder::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
_folder.Save(obj, "file");
|
||||
obs_data_set_bool(obj, "enableFilter", _enableFilter);
|
||||
_regex.Save(obj);
|
||||
_filter.Save(obj, "filter");
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroConditionFolder::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_folder.Load(obj, "file");
|
||||
_enableFilter = obs_data_get_bool(obj, "enableFilter");
|
||||
_regex.Load(obj);
|
||||
_regex.SetEnabled(true); // Already controlled via _enableFilter
|
||||
_filter.Load(obj, "filter");
|
||||
_condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
|
||||
SetupWatcher();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string MacroConditionFolder::GetShortDesc() const
|
||||
{
|
||||
return _folder.UnresolvedValue();
|
||||
}
|
||||
|
||||
void MacroConditionFolder::SetFolder(const std::string &folder)
|
||||
{
|
||||
_folder = folder;
|
||||
SetupWatcher();
|
||||
}
|
||||
|
||||
static QSet<QString> getFilesInDir(const QString &path)
|
||||
{
|
||||
QSet<QString> result;
|
||||
for (const auto &file : QDir(path).entryList(QDir::Files)) {
|
||||
result << file;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static QSet<QString> getDirsInDir(const QString &path)
|
||||
{
|
||||
QSet<QString> result;
|
||||
for (const auto &dir : QDir(path).entryList(QDir::AllDirs)) {
|
||||
result << dir;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void reduceSetToPatternMatch(QSet<QString> &set,
|
||||
const RegexConfig ®ex,
|
||||
const std::string &pattern)
|
||||
{
|
||||
QSet<QString> copy = set;
|
||||
for (const auto &value : copy) {
|
||||
if (!regex.Matches(value.toStdString(), pattern)) {
|
||||
set.remove(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MacroConditionFolder::DirectoryChanged(const QString &path)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
if (MacroIsPaused(GetMacro())) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto currentFiles = getFilesInDir(path);
|
||||
auto currentDirs = getDirsInDir(path);
|
||||
|
||||
if (currentFiles.count() > _currentFiles.count()) {
|
||||
_newFiles += currentFiles - _currentFiles;
|
||||
} else {
|
||||
_removedFiles += _currentFiles - currentFiles;
|
||||
}
|
||||
|
||||
if (currentDirs.count() > _currentDirs.count()) {
|
||||
_newDirs += currentDirs - _currentDirs;
|
||||
} else {
|
||||
_removedDirs += _currentDirs - currentDirs;
|
||||
}
|
||||
|
||||
if (_enableFilter) {
|
||||
reduceSetToPatternMatch(_newFiles, _regex, _filter);
|
||||
reduceSetToPatternMatch(_removedFiles, _regex, _filter);
|
||||
reduceSetToPatternMatch(_newDirs, _regex, _filter);
|
||||
reduceSetToPatternMatch(_removedDirs, _regex, _filter);
|
||||
}
|
||||
|
||||
switch (_condition) {
|
||||
case Condition::ANY:
|
||||
_matched = _matched || _newFiles.count() > 0 ||
|
||||
_removedFiles.count() > 0 || _newDirs.count() > 0 ||
|
||||
_removedDirs.count() > 0;
|
||||
break;
|
||||
case Condition::FILE_ADD:
|
||||
_matched = _newFiles.count() > 0;
|
||||
break;
|
||||
case Condition::FILE_REMOVE:
|
||||
_matched = _removedFiles.count() > 0;
|
||||
break;
|
||||
case Condition::FOLDER_ADD:
|
||||
_matched = _newDirs.count() > 0;
|
||||
break;
|
||||
case Condition::FOLDER_REMOVE:
|
||||
_matched = _removedDirs.count() > 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (const auto &newFile : _newFiles) {
|
||||
_watcher->addPath(path + "/" + newFile);
|
||||
}
|
||||
|
||||
_currentFiles = currentFiles;
|
||||
_currentDirs = currentDirs;
|
||||
}
|
||||
|
||||
void MacroConditionFolder::FileChanged(const QString &path)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
QFileInfo fileInfo(path);
|
||||
if (!fileInfo.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto fileName = fileInfo.fileName();
|
||||
if (_enableFilter && !_regex.Matches(fileName.toStdString(), _filter)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_changedFiles << fileName;
|
||||
if (_condition == Condition::FILE_CHANGE ||
|
||||
_condition == Condition::ANY) {
|
||||
_matched = true;
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList getFileWatcherList(const QSet<QString> &files,
|
||||
const QString &dirName)
|
||||
{
|
||||
QStringList list;
|
||||
for (const auto &value : files) {
|
||||
list << (dirName + "/" + value);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void MacroConditionFolder::SetupWatcher()
|
||||
{
|
||||
_watcher = std::make_unique<QFileSystemWatcher>();
|
||||
const auto path = QString::fromStdString(_folder);
|
||||
_currentFiles = getFilesInDir(path);
|
||||
_currentDirs = getDirsInDir(path);
|
||||
_lastWatchedValue = _folder.UnresolvedValue();
|
||||
connect(_watcher.get(), SIGNAL(directoryChanged(const QString &)), this,
|
||||
SLOT(DirectoryChanged(const QString &)));
|
||||
connect(_watcher.get(), SIGNAL(fileChanged(const QString &)), this,
|
||||
SLOT(FileChanged(const QString &)));
|
||||
_watcher.get()->addPaths(getFileWatcherList(_currentFiles, path));
|
||||
_watcher->addPath(path);
|
||||
}
|
||||
|
||||
void MacroConditionFolder::SetTempVarValues()
|
||||
{
|
||||
auto setVarHelper = [this](const QSet<QString> &set,
|
||||
const std::string &id) {
|
||||
std::string result;
|
||||
for (const auto &value : set) {
|
||||
result += value.toStdString() + "\n";
|
||||
}
|
||||
if (result.size() > 0) {
|
||||
result.pop_back();
|
||||
}
|
||||
SetTempVarValue(id, result);
|
||||
};
|
||||
|
||||
setVarHelper(_newFiles, "newFiles");
|
||||
setVarHelper(_changedFiles, "changedFiles");
|
||||
setVarHelper(_removedFiles, "removedFiles");
|
||||
setVarHelper(_newDirs, "newDirs");
|
||||
setVarHelper(_removedDirs, "removedDirs");
|
||||
}
|
||||
|
||||
void MacroConditionFolder::SetupTempVars()
|
||||
{
|
||||
MacroCondition::SetupTempVars();
|
||||
AddTempvar("newFiles",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.folder.newFiles"));
|
||||
AddTempvar("changedFiles",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.folder.changedFiles"));
|
||||
AddTempvar("removedFiles",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.folder.removedFiles"));
|
||||
AddTempvar("newDirs",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.folder.newDirs"));
|
||||
AddTempvar(
|
||||
"removedDirs",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.folder.removedDirs"));
|
||||
}
|
||||
|
||||
static void populateConditions(QComboBox *list)
|
||||
{
|
||||
for (const auto &[value, name] : conditions) {
|
||||
list->addItem(obs_module_text(name.c_str()),
|
||||
static_cast<int>(value));
|
||||
}
|
||||
}
|
||||
|
||||
MacroConditionFolderEdit::MacroConditionFolderEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionFolder> entryData)
|
||||
: QWidget(parent),
|
||||
_conditions(new QComboBox()),
|
||||
_folder(new FileSelection(FileSelection::Type::FOLDER)),
|
||||
_enableFilter(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.folder.enableFilter"))),
|
||||
_filterLayout(new QHBoxLayout()),
|
||||
_regex(new RegexConfigWidget(this, false)),
|
||||
_filter(new VariableLineEdit(this))
|
||||
{
|
||||
populateConditions(_conditions);
|
||||
|
||||
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ConditionChanged(int)));
|
||||
QWidget::connect(_folder, SIGNAL(PathChanged(const QString &)), this,
|
||||
SLOT(PathChanged(const QString &)));
|
||||
QWidget::connect(_enableFilter, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(EnableFilterChanged(int)));
|
||||
QWidget::connect(_regex,
|
||||
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
|
||||
SLOT(RegexChanged(const RegexConfig &)));
|
||||
QWidget::connect(_filter, SIGNAL(editingFinished()), this,
|
||||
SLOT(FilterChanged()));
|
||||
|
||||
auto tooltipLabel = new HelpIcon(
|
||||
obs_module_text("AdvSceneSwitcher.condition.folder.tooltip"));
|
||||
|
||||
const std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{conditions}}", _conditions}, {"{{folder}}", _folder},
|
||||
{"{{tooltip}}", tooltipLabel}, {"{{regex}}", _regex},
|
||||
{"{{filter}}", _filter},
|
||||
};
|
||||
|
||||
auto entryLayout = new QHBoxLayout();
|
||||
entryLayout->setContentsMargins(0, 0, 0, 0);
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.condition.folder.entry"),
|
||||
entryLayout, widgetPlaceholders, false);
|
||||
_filterLayout->setContentsMargins(0, 0, 0, 0);
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.folder.entry.filter"),
|
||||
_filterLayout, widgetPlaceholders, false);
|
||||
|
||||
auto layout = new QVBoxLayout();
|
||||
layout->addLayout(entryLayout);
|
||||
layout->addWidget(_enableFilter);
|
||||
layout->addLayout(_filterLayout);
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroConditionFolderEdit::UpdateEntryData()
|
||||
{
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
_conditions->setCurrentIndex(_conditions->findData(
|
||||
static_cast<int>(_entryData->_condition)));
|
||||
_folder->SetPath(_entryData->GetFolder());
|
||||
_enableFilter->setChecked(_entryData->_enableFilter);
|
||||
_regex->SetRegexConfig(_entryData->_regex);
|
||||
_filter->setText(_entryData->_filter);
|
||||
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionFolderEdit::ConditionChanged(int index)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_condition = static_cast<MacroConditionFolder::Condition>(
|
||||
_conditions->itemData(index).toInt());
|
||||
}
|
||||
|
||||
void MacroConditionFolderEdit::PathChanged(const QString &text)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->SetFolder(text.toStdString());
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
|
||||
void MacroConditionFolderEdit::RegexChanged(const RegexConfig ®ex)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_regex = regex;
|
||||
_entryData->_regex.SetEnabled(true);
|
||||
}
|
||||
|
||||
void MacroConditionFolderEdit::FilterChanged()
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_filter = _filter->text().toStdString();
|
||||
}
|
||||
|
||||
void MacroConditionFolderEdit::EnableFilterChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_enableFilter = value;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionFolderEdit::SetWidgetVisibility()
|
||||
{
|
||||
SetLayoutVisible(_filterLayout, _entryData->_enableFilter);
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
109
plugins/base/macro-condition-folder.hpp
Normal file
109
plugins/base/macro-condition-folder.hpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#pragma once
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "file-selection.hpp"
|
||||
#include "regex-config.hpp"
|
||||
#include "variable-line-edit.hpp"
|
||||
|
||||
#include <QFileSystemWatcher>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class MacroConditionFolder : public QObject, public MacroCondition {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroConditionFolder(Macro *m);
|
||||
bool CheckCondition();
|
||||
bool Save(obs_data_t *obj) const;
|
||||
bool Load(obs_data_t *obj);
|
||||
std::string GetShortDesc() const;
|
||||
std::string GetId() const { return id; };
|
||||
static std::shared_ptr<MacroCondition> Create(Macro *m)
|
||||
{
|
||||
return std::make_shared<MacroConditionFolder>(m);
|
||||
}
|
||||
void SetFolder(const std::string &);
|
||||
StringVariable GetFolder() const { return _folder; }
|
||||
|
||||
enum class Condition {
|
||||
ANY,
|
||||
FILE_ADD,
|
||||
FILE_CHANGE,
|
||||
FILE_REMOVE,
|
||||
FOLDER_ADD,
|
||||
FOLDER_REMOVE,
|
||||
};
|
||||
|
||||
Condition _condition = Condition::ANY;
|
||||
bool _enableFilter = false;
|
||||
RegexConfig _regex = RegexConfig(true);
|
||||
StringVariable _filter = ".*";
|
||||
|
||||
private slots:
|
||||
void DirectoryChanged(const QString &);
|
||||
void FileChanged(const QString &);
|
||||
|
||||
private:
|
||||
void SetupWatcher();
|
||||
void SetTempVarValues();
|
||||
void SetupTempVars();
|
||||
|
||||
StringVariable _folder = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||
|
||||
std::unique_ptr<QFileSystemWatcher> _watcher;
|
||||
std::string _lastWatchedValue = "";
|
||||
|
||||
std::mutex _mutex;
|
||||
bool _matched = false;
|
||||
QSet<QString> _newFiles;
|
||||
QSet<QString> _changedFiles;
|
||||
QSet<QString> _removedFiles;
|
||||
QSet<QString> _newDirs;
|
||||
QSet<QString> _removedDirs;
|
||||
QSet<QString> _currentFiles;
|
||||
QSet<QString> _currentDirs;
|
||||
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
class MacroConditionFolderEdit : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroConditionFolderEdit(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<MacroConditionFolder> cond = nullptr);
|
||||
void UpdateEntryData();
|
||||
static QWidget *Create(QWidget *parent,
|
||||
std::shared_ptr<MacroCondition> cond)
|
||||
{
|
||||
return new MacroConditionFolderEdit(
|
||||
parent,
|
||||
std::dynamic_pointer_cast<MacroConditionFolder>(cond));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void ConditionChanged(int index);
|
||||
void PathChanged(const QString &text);
|
||||
void EnableFilterChanged(int value);
|
||||
void RegexChanged(const RegexConfig &);
|
||||
void FilterChanged();
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
private:
|
||||
void SetWidgetVisibility();
|
||||
|
||||
QComboBox *_conditions;
|
||||
FileSelection *_folder;
|
||||
QCheckBox *_enableFilter;
|
||||
QHBoxLayout *_filterLayout;
|
||||
RegexConfigWidget *_regex;
|
||||
VariableLineEdit *_filter;
|
||||
|
||||
std::shared_ptr<MacroConditionFolder> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
@@ -14,8 +14,8 @@ bool MacroConditionSource::_registered = MacroConditionFactory::Register(
|
||||
{MacroConditionSource::Create, MacroConditionSourceEdit::Create,
|
||||
"AdvSceneSwitcher.condition.source"});
|
||||
|
||||
const static std::map<MacroConditionSource::Condition, std::string>
|
||||
sourceCnditionTypes = {
|
||||
static const std::map<MacroConditionSource::Condition, std::string>
|
||||
sourceConditionTypes = {
|
||||
{MacroConditionSource::Condition::ACTIVE,
|
||||
"AdvSceneSwitcher.condition.source.type.active"},
|
||||
{MacroConditionSource::Condition::SHOWING,
|
||||
@@ -28,8 +28,38 @@ const static std::map<MacroConditionSource::Condition, std::string>
|
||||
"AdvSceneSwitcher.condition.source.type.individualSettingMatches"},
|
||||
{MacroConditionSource::Condition::INDIVIDUAL_SETTING_CHANGED,
|
||||
"AdvSceneSwitcher.condition.source.type.individualSettingChanged"},
|
||||
{MacroConditionSource::Condition::HEIGHT,
|
||||
"AdvSceneSwitcher.condition.source.type.height"},
|
||||
{MacroConditionSource::Condition::WIDTH,
|
||||
"AdvSceneSwitcher.condition.source.type.width"},
|
||||
};
|
||||
|
||||
static const std::map<MacroConditionSource::SizeComparision, std::string>
|
||||
compareMethods = {
|
||||
{MacroConditionSource::SizeComparision::LESS,
|
||||
"AdvSceneSwitcher.condition.source.sizeCompare.less"},
|
||||
{MacroConditionSource::SizeComparision::EQUAL,
|
||||
"AdvSceneSwitcher.condition.source.sizeCompare.equal"},
|
||||
{MacroConditionSource::SizeComparision::MORE,
|
||||
"AdvSceneSwitcher.condition.source.sizeCompare.more"},
|
||||
};
|
||||
|
||||
static bool compareSourceSize(MacroConditionSource::SizeComparision method,
|
||||
int sourceValue, int compareValue)
|
||||
{
|
||||
switch (method) {
|
||||
case MacroConditionSource::SizeComparision::LESS:
|
||||
return sourceValue < compareValue;
|
||||
case MacroConditionSource::SizeComparision::EQUAL:
|
||||
return sourceValue == compareValue;
|
||||
case MacroConditionSource::SizeComparision::MORE:
|
||||
return sourceValue > compareValue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MacroConditionSource::CheckCondition()
|
||||
{
|
||||
if (!_source.GetSource()) {
|
||||
@@ -47,23 +77,24 @@ bool MacroConditionSource::CheckCondition()
|
||||
case Condition::SHOWING:
|
||||
ret = obs_source_showing(s);
|
||||
break;
|
||||
case Condition::ALL_SETTINGS_MATCH:
|
||||
case Condition::ALL_SETTINGS_MATCH: {
|
||||
ret = CompareSourceSettings(_source.GetSource(), _settings,
|
||||
_regex);
|
||||
if (IsReferencedInVars()) {
|
||||
SetVariableValue(
|
||||
GetSourceSettings(_source.GetSource()));
|
||||
}
|
||||
const auto settings = GetSourceSettings(_source.GetSource());
|
||||
SetVariableValue(settings);
|
||||
SetTempVarValue("settings", settings);
|
||||
break;
|
||||
}
|
||||
case Condition::SETTINGS_CHANGED: {
|
||||
std::string settings = GetSourceSettings(_source.GetSource());
|
||||
const auto settings = GetSourceSettings(_source.GetSource());
|
||||
ret = !_currentSettings.empty() && settings != _currentSettings;
|
||||
_currentSettings = settings;
|
||||
SetVariableValue(settings);
|
||||
SetTempVarValue("settings", settings);
|
||||
break;
|
||||
}
|
||||
case Condition::INDIVIDUAL_SETTING_MATCH: {
|
||||
auto value =
|
||||
const auto value =
|
||||
GetSourceSettingValue(_source.GetSource(), _setting);
|
||||
if (!value) {
|
||||
return false;
|
||||
@@ -71,10 +102,11 @@ bool MacroConditionSource::CheckCondition()
|
||||
ret = _regex.Enabled() ? _regex.Matches(*value, _settings)
|
||||
: value == std::string(_settings);
|
||||
SetVariableValue(*value);
|
||||
SetTempVarValue("setting", *value);
|
||||
break;
|
||||
}
|
||||
case Condition::INDIVIDUAL_SETTING_CHANGED: {
|
||||
auto value =
|
||||
const auto value =
|
||||
GetSourceSettingValue(_source.GetSource(), _setting);
|
||||
if (!value) {
|
||||
return false;
|
||||
@@ -82,6 +114,19 @@ bool MacroConditionSource::CheckCondition()
|
||||
ret = _currentSettingsValue != *value;
|
||||
_currentSettingsValue = *value;
|
||||
SetVariableValue(*value);
|
||||
SetTempVarValue("setting", *value);
|
||||
break;
|
||||
}
|
||||
case Condition::HEIGHT: {
|
||||
const auto height = obs_source_get_height(s);
|
||||
ret = compareSourceSize(_comparision, height, _size);
|
||||
SetTempVarValue("height", std::to_string(height));
|
||||
break;
|
||||
}
|
||||
case Condition::WIDTH: {
|
||||
const auto width = obs_source_get_width(s);
|
||||
ret = compareSourceSize(_comparision, width, _size);
|
||||
SetTempVarValue("width", std::to_string(width));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -103,6 +148,9 @@ bool MacroConditionSource::Save(obs_data_t *obj) const
|
||||
_settings.Save(obj, "settings");
|
||||
_regex.Save(obj);
|
||||
_setting.Save(obj);
|
||||
_size.Save(obj, "size");
|
||||
obs_data_set_int(obj, "sizeComparisionMethod",
|
||||
static_cast<int>(_comparision));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -110,7 +158,8 @@ bool MacroConditionSource::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_source.Load(obj);
|
||||
_condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
|
||||
SetCondition(
|
||||
static_cast<Condition>(obs_data_get_int(obj, "condition")));
|
||||
_settings.Load(obj, "settings");
|
||||
_regex.Load(obj);
|
||||
// TOOD: remove in future version
|
||||
@@ -119,6 +168,9 @@ bool MacroConditionSource::Load(obs_data_t *obj)
|
||||
obs_data_get_bool(obj, "regex"));
|
||||
}
|
||||
_setting.Load(obj);
|
||||
_size.Load(obj, "size");
|
||||
_comparision = static_cast<SizeComparision>(
|
||||
obs_data_get_int(obj, "sizeComparisionMethod"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -127,9 +179,52 @@ std::string MacroConditionSource::GetShortDesc() const
|
||||
return _source.ToString();
|
||||
}
|
||||
|
||||
static inline void populateConditionSelection(QComboBox *list)
|
||||
void MacroConditionSource::SetCondition(Condition cond)
|
||||
{
|
||||
for (const auto &[_, name] : sourceCnditionTypes) {
|
||||
_condition = cond;
|
||||
SetupTempVars();
|
||||
}
|
||||
|
||||
void MacroConditionSource::SetupTempVars()
|
||||
{
|
||||
MacroCondition::SetupTempVars();
|
||||
switch (_condition) {
|
||||
case Condition::ACTIVE:
|
||||
break;
|
||||
case Condition::SHOWING:
|
||||
break;
|
||||
case Condition::ALL_SETTINGS_MATCH:
|
||||
case Condition::SETTINGS_CHANGED:
|
||||
AddTempvar("settings",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.source.settings"));
|
||||
break;
|
||||
case Condition::INDIVIDUAL_SETTING_MATCH:
|
||||
case Condition::INDIVIDUAL_SETTING_CHANGED:
|
||||
AddTempvar("setting",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.source.setting"));
|
||||
break;
|
||||
case Condition::HEIGHT:
|
||||
AddTempvar("height",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.source.height"));
|
||||
break;
|
||||
case Condition::WIDTH:
|
||||
AddTempvar("width",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.source.width"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline void populateSelection(QComboBox *list,
|
||||
const std::map<T, std::string> &map)
|
||||
{
|
||||
for (const auto &[_, name] : map) {
|
||||
list->addItem(obs_module_text(name.c_str()));
|
||||
}
|
||||
}
|
||||
@@ -144,10 +239,13 @@ MacroConditionSourceEdit::MacroConditionSourceEdit(
|
||||
_settings(new VariableTextEdit(this)),
|
||||
_regex(new RegexConfigWidget(parent)),
|
||||
_settingSelection(new SourceSettingSelection()),
|
||||
_refreshSettingSelection(new QPushButton(
|
||||
obs_module_text("AdvSceneSwitcher.condition.source.refresh")))
|
||||
_refreshSettingSelection(new QPushButton(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.source.refresh"))),
|
||||
_size(new VariableSpinBox(this)),
|
||||
_sizeCompareMethods(new QComboBox())
|
||||
{
|
||||
populateConditionSelection(_conditions);
|
||||
populateSelection(_conditions, sourceConditionTypes);
|
||||
populateSelection(_sizeCompareMethods, compareMethods);
|
||||
auto sources = GetSourceNames();
|
||||
sources.sort();
|
||||
auto scenes = GetSceneNames();
|
||||
@@ -155,6 +253,7 @@ MacroConditionSourceEdit::MacroConditionSourceEdit(
|
||||
_sources->SetSourceNameList(sources + scenes);
|
||||
_refreshSettingSelection->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.source.refreshTooltip"));
|
||||
_size->setMaximum(999999);
|
||||
|
||||
QWidget::connect(_sources,
|
||||
SIGNAL(SourceChanged(const SourceSelection &)), this,
|
||||
@@ -173,31 +272,36 @@ MacroConditionSourceEdit::MacroConditionSourceEdit(
|
||||
SLOT(SettingSelectionChanged(const SourceSetting &)));
|
||||
QWidget::connect(_refreshSettingSelection, SIGNAL(clicked()), this,
|
||||
SLOT(RefreshVariableSourceSelectionValue()));
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{sources}}", _sources},
|
||||
{"{{conditions}}", _conditions},
|
||||
{"{{settings}}", _settings},
|
||||
{"{{getSettings}}", _getSettings},
|
||||
{"{{regex}}", _regex},
|
||||
{"{{settingSelection}}", _settingSelection},
|
||||
{"{{refresh}}", _refreshSettingSelection}};
|
||||
QWidget::connect(
|
||||
_size,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(SizeChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(_sizeCompareMethods, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(CompareMethodChanged(int)));
|
||||
|
||||
auto line1Layout = new QHBoxLayout;
|
||||
line1Layout->setContentsMargins(0, 0, 0, 0);
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.source.entry.line1"),
|
||||
line1Layout, widgetPlaceholders);
|
||||
line1Layout,
|
||||
{{"{{sources}}", _sources},
|
||||
{"{{conditions}}", _conditions},
|
||||
{"{{settingSelection}}", _settingSelection},
|
||||
{"{{refresh}}", _refreshSettingSelection},
|
||||
{"{{size}}", _size},
|
||||
{"{{sizeCompareMethods}}", _sizeCompareMethods}});
|
||||
auto line2Layout = new QHBoxLayout;
|
||||
line2Layout->setContentsMargins(0, 0, 0, 0);
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.source.entry.line2"),
|
||||
line2Layout, widgetPlaceholders, false);
|
||||
line2Layout, {{"{{settings}}", _settings}}, false);
|
||||
auto line3Layout = new QHBoxLayout;
|
||||
line3Layout->setContentsMargins(0, 0, 0, 0);
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.source.entry.line3"),
|
||||
line3Layout, widgetPlaceholders);
|
||||
line3Layout,
|
||||
{{"{{getSettings}}", _getSettings}, {"{{regex}}", _regex}},
|
||||
true);
|
||||
auto mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(line1Layout);
|
||||
mainLayout->addLayout(line2Layout);
|
||||
@@ -232,8 +336,8 @@ void MacroConditionSourceEdit::ConditionChanged(int index)
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_condition =
|
||||
static_cast<MacroConditionSource::Condition>(index);
|
||||
_entryData->SetCondition(
|
||||
static_cast<MacroConditionSource::Condition>(index));
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
@@ -244,7 +348,7 @@ void MacroConditionSourceEdit::GetSettingsClicked()
|
||||
}
|
||||
|
||||
QString value;
|
||||
if (_entryData->_condition ==
|
||||
if (_entryData->GetCondition() ==
|
||||
MacroConditionSource::Condition::ALL_SETTINGS_MATCH) {
|
||||
value = FormatJsonString(
|
||||
GetSourceSettings(_entryData->_source.GetSource()));
|
||||
@@ -303,37 +407,67 @@ void MacroConditionSourceEdit::RefreshVariableSourceSelectionValue()
|
||||
_settingSelection->SetSource(_entryData->_source.GetSource());
|
||||
}
|
||||
|
||||
void MacroConditionSourceEdit::SizeChanged(const NumberVariable<int> &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_size = value;
|
||||
}
|
||||
|
||||
void MacroConditionSourceEdit::CompareMethodChanged(int index)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_comparision =
|
||||
static_cast<MacroConditionSource::SizeComparision>(index);
|
||||
}
|
||||
|
||||
void MacroConditionSourceEdit::SetWidgetVisibility()
|
||||
{
|
||||
const bool settingsMatch =
|
||||
_entryData->_condition ==
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionSource::Condition::ALL_SETTINGS_MATCH ||
|
||||
_entryData->_condition ==
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionSource::Condition::INDIVIDUAL_SETTING_MATCH;
|
||||
_settings->setVisible(settingsMatch);
|
||||
_getSettings->setVisible(settingsMatch);
|
||||
_regex->setVisible(settingsMatch);
|
||||
_settingSelection->setVisible(
|
||||
_entryData->_condition == MacroConditionSource::Condition::
|
||||
INDIVIDUAL_SETTING_MATCH ||
|
||||
_entryData->_condition == MacroConditionSource::Condition::
|
||||
INDIVIDUAL_SETTING_CHANGED);
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionSource::Condition::INDIVIDUAL_SETTING_MATCH ||
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionSource::Condition::
|
||||
INDIVIDUAL_SETTING_CHANGED);
|
||||
|
||||
setToolTip(
|
||||
(_entryData->_condition ==
|
||||
(_entryData->GetCondition() ==
|
||||
MacroConditionSource::Condition::ACTIVE ||
|
||||
_entryData->_condition ==
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionSource::Condition::SHOWING)
|
||||
? obs_module_text(
|
||||
"AdvSceneSwitcher.condition.source.sceneVisibilityHint")
|
||||
: "");
|
||||
|
||||
_refreshSettingSelection->setVisible(
|
||||
_entryData->_condition == MacroConditionSource::Condition::
|
||||
INDIVIDUAL_SETTING_MATCH &&
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionSource::Condition::INDIVIDUAL_SETTING_MATCH &&
|
||||
_entryData->_source.GetType() ==
|
||||
SourceSelection::Type::VARIABLE);
|
||||
|
||||
const bool isSizeCheck =
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionSource::Condition::WIDTH ||
|
||||
_entryData->GetCondition() ==
|
||||
MacroConditionSource::Condition::HEIGHT;
|
||||
_size->setVisible(isSizeCheck);
|
||||
_sizeCompareMethods->setVisible(isSizeCheck);
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
@@ -345,11 +479,15 @@ void MacroConditionSourceEdit::UpdateEntryData()
|
||||
}
|
||||
|
||||
_sources->SetSource(_entryData->_source);
|
||||
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||
_conditions->setCurrentIndex(
|
||||
static_cast<int>(_entryData->GetCondition()));
|
||||
_settings->setPlainText(_entryData->_settings);
|
||||
_regex->SetRegexConfig(_entryData->_regex);
|
||||
_settingSelection->SetSource(_entryData->_source.GetSource());
|
||||
_settingSelection->SetSetting(_entryData->_setting);
|
||||
_size->SetValue(_entryData->_size);
|
||||
_sizeCompareMethods->setCurrentIndex(
|
||||
static_cast<int>(_entryData->_comparision));
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,15 +31,25 @@ public:
|
||||
SETTINGS_CHANGED,
|
||||
INDIVIDUAL_SETTING_MATCH,
|
||||
INDIVIDUAL_SETTING_CHANGED,
|
||||
HEIGHT,
|
||||
WIDTH,
|
||||
};
|
||||
void SetCondition(Condition);
|
||||
Condition GetCondition() const { return _condition; }
|
||||
|
||||
enum class SizeComparision { LESS, EQUAL, MORE };
|
||||
|
||||
SourceSelection _source;
|
||||
Condition _condition = Condition::ACTIVE;
|
||||
StringVariable _settings = "";
|
||||
SourceSetting _setting;
|
||||
RegexConfig _regex;
|
||||
IntVariable _size;
|
||||
SizeComparision _comparision = SizeComparision::EQUAL;
|
||||
|
||||
private:
|
||||
void SetupTempVars();
|
||||
|
||||
Condition _condition = Condition::ACTIVE;
|
||||
std::string _currentSettings;
|
||||
std::string _currentSettingsValue;
|
||||
|
||||
@@ -71,6 +81,8 @@ private slots:
|
||||
void RegexChanged(const RegexConfig &);
|
||||
void SettingSelectionChanged(const SourceSetting &);
|
||||
void RefreshVariableSourceSelectionValue();
|
||||
void SizeChanged(const NumberVariable<int> &value);
|
||||
void CompareMethodChanged(int);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
@@ -82,6 +94,8 @@ protected:
|
||||
RegexConfigWidget *_regex;
|
||||
SourceSettingSelection *_settingSelection;
|
||||
QPushButton *_refreshSettingSelection;
|
||||
VariableSpinBox *_size;
|
||||
QComboBox *_sizeCompareMethods;
|
||||
|
||||
std::shared_ptr<MacroConditionSource> _entryData;
|
||||
|
||||
|
||||
@@ -529,68 +529,26 @@ void OSCMessageElementEdit::TypeChanged(int idx)
|
||||
}
|
||||
|
||||
OSCMessageEdit::OSCMessageEdit(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
_address(new VariableLineEdit(this)),
|
||||
_elements(new QListWidget()),
|
||||
_add(new QPushButton()),
|
||||
_remove(new QPushButton()),
|
||||
_up(new QPushButton()),
|
||||
_down(new QPushButton())
|
||||
: ListEditor(parent),
|
||||
_address(new VariableLineEdit(this))
|
||||
{
|
||||
_elements->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
_elements->setAutoScroll(false);
|
||||
|
||||
_add->setMaximumWidth(22);
|
||||
_add->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("addIconSmall")));
|
||||
_add->setFlat(true);
|
||||
_remove->setMaximumWidth(22);
|
||||
_remove->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("removeIconSmall")));
|
||||
_remove->setFlat(true);
|
||||
_up->setMaximumWidth(22);
|
||||
_up->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("upArrowIconSmall")));
|
||||
_up->setFlat(true);
|
||||
_down->setMaximumWidth(22);
|
||||
_down->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("downArrowIconSmall")));
|
||||
_down->setFlat(true);
|
||||
_list->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
_list->setAutoScroll(false);
|
||||
|
||||
QWidget::connect(_address, SIGNAL(editingFinished()), this,
|
||||
SLOT(AddressChanged()));
|
||||
QWidget::connect(_add, SIGNAL(clicked()), this, SLOT(Add()));
|
||||
QWidget::connect(_remove, SIGNAL(clicked()), this, SLOT(Remove()));
|
||||
QWidget::connect(_up, SIGNAL(clicked()), this, SLOT(Up()));
|
||||
QWidget::connect(_down, SIGNAL(clicked()), this, SLOT(Down()));
|
||||
|
||||
auto controlsLayout = new QHBoxLayout();
|
||||
controlsLayout->addWidget(_add);
|
||||
controlsLayout->addWidget(_remove);
|
||||
QFrame *line = new QFrame();
|
||||
line->setFrameShape(QFrame::VLine);
|
||||
line->setFrameShadow(QFrame::Sunken);
|
||||
controlsLayout->addWidget(line);
|
||||
controlsLayout->addWidget(_up);
|
||||
controlsLayout->addWidget(_down);
|
||||
controlsLayout->addStretch();
|
||||
|
||||
auto layout = new QVBoxLayout;
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(_address);
|
||||
layout->addWidget(_elements);
|
||||
layout->addLayout(controlsLayout);
|
||||
setLayout(layout);
|
||||
_mainLayout->insertWidget(0, _address);
|
||||
}
|
||||
|
||||
void OSCMessageEdit::InsertElement(const OSCMessageElement &element)
|
||||
{
|
||||
auto item = new QListWidgetItem(_elements);
|
||||
_elements->addItem(item);
|
||||
auto item = new QListWidgetItem(_list);
|
||||
_list->addItem(item);
|
||||
auto elementEdit = new OSCMessageElementEdit(this);
|
||||
elementEdit->SetMessageElement(element);
|
||||
item->setSizeHint(elementEdit->minimumSizeHint());
|
||||
_elements->setItemWidget(item, elementEdit);
|
||||
_list->setItemWidget(item, elementEdit);
|
||||
QWidget::connect(elementEdit,
|
||||
SIGNAL(ElementValueChanged(const OSCMessageElement &)),
|
||||
this,
|
||||
@@ -607,7 +565,7 @@ void OSCMessageEdit::SetMessage(const OSCMessage &message)
|
||||
InsertElement(element);
|
||||
}
|
||||
_currentSelection = message;
|
||||
SetWidgetSize();
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
void OSCMessageEdit::AddressChanged()
|
||||
@@ -621,13 +579,13 @@ void OSCMessageEdit::Add()
|
||||
OSCMessageElement element;
|
||||
InsertElement(element);
|
||||
emit MessageChanged(_currentSelection);
|
||||
SetWidgetSize();
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
void OSCMessageEdit::Remove()
|
||||
{
|
||||
auto item = _elements->currentItem();
|
||||
int idx = _elements->currentRow();
|
||||
auto item = _list->currentItem();
|
||||
int idx = _list->currentRow();
|
||||
if (!item || idx == -1) {
|
||||
return;
|
||||
}
|
||||
@@ -635,7 +593,7 @@ void OSCMessageEdit::Remove()
|
||||
_currentSelection._elements.erase(_currentSelection._elements.begin() +
|
||||
idx);
|
||||
emit MessageChanged(_currentSelection);
|
||||
SetWidgetSize();
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
static bool moveUp(QListWidget *list)
|
||||
@@ -658,8 +616,8 @@ static bool moveUp(QListWidget *list)
|
||||
|
||||
void OSCMessageEdit::Up()
|
||||
{
|
||||
int idx = _elements->currentRow();
|
||||
if (!moveUp(_elements)) {
|
||||
int idx = _list->currentRow();
|
||||
if (!moveUp(_list)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -667,7 +625,7 @@ void OSCMessageEdit::Up()
|
||||
_currentSelection._elements.begin() + idx - 1);
|
||||
|
||||
emit MessageChanged(_currentSelection);
|
||||
SetWidgetSize();
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
static bool moveDown(QListWidget *list)
|
||||
@@ -690,8 +648,8 @@ static bool moveDown(QListWidget *list)
|
||||
|
||||
void OSCMessageEdit::Down()
|
||||
{
|
||||
int idx = _elements->currentRow();
|
||||
if (!moveDown(_elements)) {
|
||||
int idx = _list->currentRow();
|
||||
if (!moveDown(_list)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -699,7 +657,7 @@ void OSCMessageEdit::Down()
|
||||
_currentSelection._elements.begin() + idx + 1);
|
||||
|
||||
emit MessageChanged(_currentSelection);
|
||||
SetWidgetSize();
|
||||
UpdateListSize();
|
||||
}
|
||||
|
||||
static QListWidgetItem *getItemFromWidget(QListWidget *list, QWidget *widget)
|
||||
@@ -727,7 +685,7 @@ int OSCMessageEdit::GetIndexOfSignal()
|
||||
if (!widget) {
|
||||
return -1;
|
||||
}
|
||||
return _elements->row(getItemFromWidget(_elements, widget));
|
||||
return _list->row(getItemFromWidget(_list, widget));
|
||||
}
|
||||
|
||||
void OSCMessageEdit::ElementFocussed()
|
||||
@@ -736,7 +694,7 @@ void OSCMessageEdit::ElementFocussed()
|
||||
if (idx == -1) {
|
||||
return;
|
||||
}
|
||||
_elements->setCurrentRow(idx);
|
||||
_list->setCurrentRow(idx);
|
||||
}
|
||||
|
||||
void OSCMessageEdit::ElementValueChanged(const OSCMessageElement &element)
|
||||
@@ -747,15 +705,8 @@ void OSCMessageEdit::ElementValueChanged(const OSCMessageElement &element)
|
||||
}
|
||||
|
||||
_currentSelection._elements.at(idx) = element;
|
||||
_elements->setCurrentRow(idx);
|
||||
_list->setCurrentRow(idx);
|
||||
emit MessageChanged(_currentSelection);
|
||||
}
|
||||
|
||||
void OSCMessageEdit::SetWidgetSize()
|
||||
{
|
||||
SetHeightToContentHeight(_elements);
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "list-editor.hpp"
|
||||
#include "variable-string.hpp"
|
||||
#include "variable-number.hpp"
|
||||
#include "variable-line-edit.hpp"
|
||||
@@ -6,7 +7,6 @@
|
||||
|
||||
#include <variant>
|
||||
#include <unordered_map>
|
||||
#include <QListWidget>
|
||||
|
||||
namespace advss {
|
||||
|
||||
@@ -137,7 +137,7 @@ private:
|
||||
VariableLineEdit *_binaryText;
|
||||
};
|
||||
|
||||
class OSCMessageEdit : public QWidget {
|
||||
class OSCMessageEdit final : public ListEditor {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OSCMessageEdit(QWidget *);
|
||||
@@ -157,15 +157,9 @@ signals:
|
||||
|
||||
private:
|
||||
void InsertElement(const OSCMessageElement &);
|
||||
void SetWidgetSize();
|
||||
int GetIndexOfSignal();
|
||||
|
||||
VariableLineEdit *_address;
|
||||
QListWidget *_elements;
|
||||
QPushButton *_add;
|
||||
QPushButton *_remove;
|
||||
QPushButton *_up;
|
||||
QPushButton *_down;
|
||||
|
||||
OSCMessage _currentSelection;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "source-setting.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "math-helpers.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
@@ -233,14 +232,8 @@ SourceSettingSelection::SourceSettingSelection(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
_settings(new FilterComboBox(
|
||||
this, obs_module_text("AdvSceneSwitcher.setting.select"))),
|
||||
_tooltip(new QLabel())
|
||||
_tooltip(new HelpIcon())
|
||||
{
|
||||
QString path = GetThemeTypeName() == "Light"
|
||||
? ":/res/images/help.svg"
|
||||
: ":/res/images/help_light.svg";
|
||||
QIcon icon(path);
|
||||
QPixmap pixmap = icon.pixmap(QSize(16, 16));
|
||||
_tooltip->setPixmap(pixmap);
|
||||
_tooltip->hide();
|
||||
|
||||
_settings->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "filter-combo-box.hpp"
|
||||
#include "help-icon.hpp"
|
||||
|
||||
#include <obs.hpp>
|
||||
#include <optional>
|
||||
@@ -52,7 +53,7 @@ private:
|
||||
void Populate(const OBSWeakSource &);
|
||||
|
||||
FilterComboBox *_settings;
|
||||
QLabel *_tooltip;
|
||||
HelpIcon *_tooltip;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -207,14 +207,14 @@ static void setupTab(QTabWidget *tab)
|
||||
}
|
||||
|
||||
QWidget::connect(ConnectionSelectionSignalManager::Instance(),
|
||||
&ConnectionSelectionSignalManager::Rename,
|
||||
&ConnectionSelectionSignalManager::Rename, tab,
|
||||
[](const QString &oldName, const QString &newName) {
|
||||
RenameItemTableRow(tabWidget->Table(), oldName,
|
||||
newName);
|
||||
});
|
||||
QWidget::connect(
|
||||
ConnectionSelectionSignalManager::Instance(),
|
||||
&ConnectionSelectionSignalManager::Add,
|
||||
&ConnectionSelectionSignalManager::Add, tab,
|
||||
[tab](const QString &name) {
|
||||
AddItemTableRow(
|
||||
tabWidget->Table(),
|
||||
@@ -224,7 +224,7 @@ static void setupTab(QTabWidget *tab)
|
||||
setTabVisible(tab, true);
|
||||
});
|
||||
QWidget::connect(ConnectionSelectionSignalManager::Instance(),
|
||||
&ConnectionSelectionSignalManager::Remove,
|
||||
&ConnectionSelectionSignalManager::Remove, tab,
|
||||
[](const QString &name) {
|
||||
RemoveItemTableRow(tabWidget->Table(), name);
|
||||
if (tabWidget->Table()->rowCount() == 0) {
|
||||
|
||||
@@ -529,7 +529,8 @@ TwitchTokenSettingsDialog::TwitchTokenSettingsDialog(
|
||||
HideToken();
|
||||
|
||||
if (_name->text().isEmpty()) {
|
||||
PulseWidget(_requestToken, Qt::green, QColor(0, 0, 0, 0), true);
|
||||
HighlightWidget(_requestToken, Qt::green, QColor(0, 0, 0, 0),
|
||||
true);
|
||||
}
|
||||
|
||||
_currentToken = settings;
|
||||
@@ -573,7 +574,8 @@ void TwitchTokenSettingsDialog::HideToken()
|
||||
void TwitchTokenSettingsDialog::TokenOptionChanged(int)
|
||||
{
|
||||
if (!_name->text().isEmpty()) {
|
||||
PulseWidget(_requestToken, Qt::green, QColor(0, 0, 0, 0), true);
|
||||
HighlightWidget(_requestToken, Qt::green, QColor(0, 0, 0, 0),
|
||||
true);
|
||||
}
|
||||
_name->setText("");
|
||||
SetTokenInfoVisible(false);
|
||||
|
||||
@@ -196,7 +196,7 @@ static void setupTab(QTabWidget *tab)
|
||||
|
||||
QWidget::connect(
|
||||
TwitchConnectionSignalManager::Instance(),
|
||||
&TwitchConnectionSignalManager::Add,
|
||||
&TwitchConnectionSignalManager::Add, tab,
|
||||
[tab](const QString &name) {
|
||||
AddItemTableRow(
|
||||
tabWidget->Table(),
|
||||
@@ -208,7 +208,7 @@ static void setupTab(QTabWidget *tab)
|
||||
setTabVisible(tab, true);
|
||||
});
|
||||
QWidget::connect(TwitchConnectionSignalManager::Instance(),
|
||||
&TwitchConnectionSignalManager::Remove,
|
||||
&TwitchConnectionSignalManager::Remove, tab,
|
||||
[](const QString &name) {
|
||||
RemoveItemTableRow(tabWidget->Table(), name);
|
||||
if (tabWidget->Table()->rowCount() == 0) {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
class QObejct;
|
||||
|
||||
namespace advss {
|
||||
|
||||
QMetaObject::Connection PulseWidget(QWidget *widget, QColor startColor,
|
||||
QColor endColor, bool once)
|
||||
QObject *HighlightWidget(QWidget *widget, QColor startColor, QColor endColor,
|
||||
bool once)
|
||||
{
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SetHeightToContentHeight(QListWidget *list) {}
|
||||
@@ -33,4 +35,11 @@ std::string GetThemeTypeName()
|
||||
return "Dark";
|
||||
}
|
||||
|
||||
void QeueUITask(void (*task)(void *param), void *) {}
|
||||
|
||||
QWidget *GetSettingsWindow()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
Reference in New Issue
Block a user