From 9ba8a02a118a99cd319865b5638df44533982b7e Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Sat, 26 Mar 2022 17:01:38 +0100 Subject: [PATCH] Add hotkey to move current macro segment selection up / down --- data/locale/en-US.ini | 2 + src/headers/advanced-scene-switcher.hpp | 9 ++ src/headers/switcher-data-structs.hpp | 2 + src/hotkey.cpp | 93 ++++++++++-------- src/macro-action-edit.cpp | 2 + src/macro-condition-edit.cpp | 2 + src/macro-tab.cpp | 121 +++++++++++++++++++++++- 7 files changed, 192 insertions(+), 39 deletions(-) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index c49b378a..a1bd6bd4 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -708,6 +708,8 @@ AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey="Toggle Start/Stop for the AdvSceneSwitcher.hotkey.macro.pause="Pause macro %1" AdvSceneSwitcher.hotkey.macro.unpause="Unpause macro %1" AdvSceneSwitcher.hotkey.macro.togglePause="Toggle pause of macro %1" +AdvSceneSwitcher.hotkey.upMacroSegmentHotkey="Move macro segment selection up" +AdvSceneSwitcher.hotkey.downMacroSegmentHotkey="Move macro segment selection down" AdvSceneSwitcher.hotkey.removeMacroSegmentHotkey="Remove selected macro segment" AdvSceneSwitcher.askBackup="Detected a new version of the Advanced Scene Switcher.\nShould a backup of the old settings be created?" diff --git a/src/headers/advanced-scene-switcher.hpp b/src/headers/advanced-scene-switcher.hpp index 2fdcd9ab..0696fead 100644 --- a/src/headers/advanced-scene-switcher.hpp +++ b/src/headers/advanced-scene-switcher.hpp @@ -133,6 +133,8 @@ public slots: void on_actionRemove_clicked(); void on_actionUp_clicked(); void on_actionDown_clicked(); + void UpMacroSegementHotkey(); + void DownMacroSegementHotkey(); void DeleteMacroSegementHotkey(); void ShowMacroContextMenu(const QPoint &); void ShowMacroActionsContextMenu(const QPoint &); @@ -298,9 +300,16 @@ public slots: void on_close_clicked(); private: + bool MacroTabIsInFocus(); + MacroSegmentList *conditionsList = nullptr; MacroSegmentList *actionsList = nullptr; + enum class MacroSection { + CONDITIONS, + ACTIONS, + }; + MacroSection lastInteracted = MacroSection::CONDITIONS; int currentConditionIdx = -1; int currentActionIdx = -1; }; diff --git a/src/headers/switcher-data-structs.hpp b/src/headers/switcher-data-structs.hpp index 7033417b..307e3578 100644 --- a/src/headers/switcher-data-structs.hpp +++ b/src/headers/switcher-data-structs.hpp @@ -219,6 +219,8 @@ struct SwitcherData { obs_hotkey_id startHotkey = OBS_INVALID_HOTKEY_ID; obs_hotkey_id stopHotkey = OBS_INVALID_HOTKEY_ID; obs_hotkey_id toggleHotkey = OBS_INVALID_HOTKEY_ID; + obs_hotkey_id upMacroSegment = OBS_INVALID_HOTKEY_ID; + obs_hotkey_id downMacroSegment = OBS_INVALID_HOTKEY_ID; obs_hotkey_id removeMacroSegment = OBS_INVALID_HOTKEY_ID; bool saveWindowGeo = false; diff --git a/src/hotkey.cpp b/src/hotkey.cpp index d77c29f8..989232a4 100644 --- a/src/hotkey.cpp +++ b/src/hotkey.cpp @@ -34,6 +34,28 @@ void startStopToggleHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, } } +void upMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, + bool pressed) +{ + if (pressed && switcher->settingsWindowOpened && + AdvSceneSwitcher::window) { + QMetaObject::invokeMethod(AdvSceneSwitcher::window, + "UpMacroSegementHotkey", + Qt::QueuedConnection); + } +} + +void downMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, + bool pressed) +{ + if (pressed && switcher->settingsWindowOpened && + AdvSceneSwitcher::window) { + QMetaObject::invokeMethod(AdvSceneSwitcher::window, + "DownMacroSegementHotkey", + Qt::QueuedConnection); + } +} + void removeMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed) { @@ -60,6 +82,15 @@ void registerHotkeys() obs_module_text( "AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey"), startStopToggleHotkeyFunc, NULL); + switcher->upMacroSegment = obs_hotkey_register_frontend( + "upMacroSegmentSwitcherHotkey", + obs_module_text("AdvSceneSwitcher.hotkey.upMacroSegmentHotkey"), + upMacroSegmentHotkeyFunc, NULL); + switcher->downMacroSegment = obs_hotkey_register_frontend( + "downMacroSegmentSwitcherHotkey", + obs_module_text( + "AdvSceneSwitcher.hotkey.downMacroSegmentHotkey"), + downMacroSegmentHotkeyFunc, NULL); switcher->removeMacroSegment = obs_hotkey_register_frontend( "removeMacroSegmentSwitcherHotkey", obs_module_text( @@ -69,26 +100,28 @@ void registerHotkeys() switcher->hotkeysRegistered = true; } +void saveHotkey(obs_data_t *obj, obs_hotkey_id id, const char *name) +{ + obs_data_array_t *a = obs_hotkey_save(id); + obs_data_set_array(obj, name, a); + obs_data_array_release(a); +} + void SwitcherData::saveHotkeys(obs_data_t *obj) { - obs_data_array_t *startHotkeyArrray = obs_hotkey_save(startHotkey); - obs_data_set_array(obj, "startHotkey", startHotkeyArrray); - obs_data_array_release(startHotkeyArrray); + saveHotkey(obj, startHotkey, "startHotkey"); + saveHotkey(obj, stopHotkey, "stopHotkey"); + saveHotkey(obj, toggleHotkey, "toggleHotkey"); + saveHotkey(obj, upMacroSegment, "upMacroSegmentHotkey"); + saveHotkey(obj, downMacroSegment, "downMacroSegmentHotkey"); + saveHotkey(obj, removeMacroSegment, "removeMacroSegmentHotkey"); +} - obs_data_array_t *stopHotkeyArrray = obs_hotkey_save(stopHotkey); - - obs_data_set_array(obj, "stopHotkey", stopHotkeyArrray); - obs_data_array_release(stopHotkeyArrray); - - obs_data_array_t *toggleHotkeyArrray = obs_hotkey_save(toggleHotkey); - obs_data_set_array(obj, "toggleHotkey", toggleHotkeyArrray); - obs_data_array_release(toggleHotkeyArrray); - - obs_data_array_t *removeSegmentArrray = - obs_hotkey_save(removeMacroSegment); - obs_data_set_array(obj, "removeMacroSegmentHotkey", - removeSegmentArrray); - obs_data_array_release(removeSegmentArrray); +void loadHotkey(obs_data_t *obj, obs_hotkey_id id, const char *name) +{ + obs_data_array_t *a = obs_data_get_array(obj, name); + obs_hotkey_load(id, a); + obs_data_array_release(a); } void SwitcherData::loadHotkeys(obs_data_t *obj) @@ -96,24 +129,10 @@ void SwitcherData::loadHotkeys(obs_data_t *obj) if (!hotkeysRegistered) { registerHotkeys(); } - - obs_data_array_t *startHotkeyArrray = - obs_data_get_array(obj, "startHotkey"); - obs_hotkey_load(startHotkey, startHotkeyArrray); - obs_data_array_release(startHotkeyArrray); - - obs_data_array_t *stopHotkeyArrray = - obs_data_get_array(obj, "stopHotkey"); - obs_hotkey_load(stopHotkey, stopHotkeyArrray); - obs_data_array_release(stopHotkeyArrray); - - obs_data_array_t *toggleHotkeyArrray = - obs_data_get_array(obj, "toggleHotkey"); - obs_hotkey_load(toggleHotkey, toggleHotkeyArrray); - obs_data_array_release(toggleHotkeyArrray); - - obs_data_array_t *removeSegmentArrray = - obs_data_get_array(obj, "removeMacroSegmentHotkey"); - obs_hotkey_load(removeMacroSegment, removeSegmentArrray); - obs_data_array_release(removeSegmentArrray); + loadHotkey(obj, startHotkey, "startHotkey"); + loadHotkey(obj, stopHotkey, "stopHotkey"); + loadHotkey(obj, toggleHotkey, "toggleHotkey"); + loadHotkey(obj, upMacroSegment, "upMacroSegmentHotkey"); + loadHotkey(obj, downMacroSegment, "downMacroSegmentHotkey"); + loadHotkey(obj, removeMacroSegment, "removeMacroSegmentHotkey"); } diff --git a/src/macro-action-edit.cpp b/src/macro-action-edit.cpp index 921beb87..514cd9f1 100644 --- a/src/macro-action-edit.cpp +++ b/src/macro-action-edit.cpp @@ -221,6 +221,7 @@ void AdvSceneSwitcher::RemoveMacroAction(int idx) SetActionData(*macro); } MacroActionSelectionChanged(-1); + lastInteracted = MacroSection::ACTIONS; } void AdvSceneSwitcher::on_actionRemove_clicked() @@ -323,6 +324,7 @@ void AdvSceneSwitcher::MacroActionSelectionChanged(int idx) currentActionIdx = -1; } else { currentActionIdx = idx; + lastInteracted = MacroSection::ACTIONS; } currentConditionIdx = -1; HighlightControls(); diff --git a/src/macro-condition-edit.cpp b/src/macro-condition-edit.cpp index 2c179b38..fa202fc5 100644 --- a/src/macro-condition-edit.cpp +++ b/src/macro-condition-edit.cpp @@ -361,6 +361,7 @@ void AdvSceneSwitcher::RemoveMacroCondition(int idx) SetConditionData(*macro); } MacroConditionSelectionChanged(-1); + lastInteracted = MacroSection::CONDITIONS; } void AdvSceneSwitcher::on_conditionRemove_clicked() @@ -474,6 +475,7 @@ void AdvSceneSwitcher::MacroConditionSelectionChanged(int idx) currentConditionIdx = -1; } else { currentConditionIdx = idx; + lastInteracted = MacroSection::CONDITIONS; } currentActionIdx = -1; HighlightControls(); diff --git a/src/macro-tab.cpp b/src/macro-tab.cpp index ab488870..57d0fe71 100644 --- a/src/macro-tab.cpp +++ b/src/macro-tab.cpp @@ -601,10 +601,127 @@ void AdvSceneSwitcher::MinimizeConditions() ui->macroSplitter->setSizes(sizes); } +bool AdvSceneSwitcher::MacroTabIsInFocus() +{ + return isActiveWindow() && isAncestorOf(focusWidget()) && + (ui->tabWidget->currentWidget()->objectName() == "macroTab"); +} + +void AdvSceneSwitcher::UpMacroSegementHotkey() +{ + if (!MacroTabIsInFocus()) { + return; + } + + auto macro = getSelectedMacro(); + if (!macro) { + return; + } + size_t actionSize = macro->Actions().size(); + size_t conditionSize = macro->Conditions().size(); + + if (currentActionIdx == -1 && currentConditionIdx == -1) { + if (lastInteracted == MacroSection::CONDITIONS) { + if (conditionSize == 0) { + MacroActionSelectionChanged(0); + } else { + MacroConditionSelectionChanged(0); + } + } else { + if (actionSize == 0) { + MacroConditionSelectionChanged(0); + } else { + MacroActionSelectionChanged(0); + } + } + return; + } + + if (currentActionIdx > 0) { + MacroActionSelectionChanged(currentActionIdx - 1); + return; + } + if (currentConditionIdx > 0) { + MacroConditionSelectionChanged(currentConditionIdx - 1); + return; + } + if (currentActionIdx == 0) { + if (conditionSize == 0) { + MacroActionSelectionChanged(actionSize - 1); + } else { + MacroConditionSelectionChanged(conditionSize - 1); + } + return; + } + if (currentConditionIdx == 0) { + if (actionSize == 0) { + MacroConditionSelectionChanged(conditionSize - 1); + } else { + MacroActionSelectionChanged(actionSize - 1); + } + return; + } +} + +void AdvSceneSwitcher::DownMacroSegementHotkey() +{ + if (!MacroTabIsInFocus()) { + return; + } + + auto macro = getSelectedMacro(); + if (!macro) { + return; + } + size_t actionSize = macro->Actions().size(); + size_t conditionSize = macro->Conditions().size(); + + if (currentActionIdx == -1 && currentConditionIdx == -1) { + if (lastInteracted == MacroSection::CONDITIONS) { + if (conditionSize == 0) { + MacroActionSelectionChanged(0); + } else { + MacroConditionSelectionChanged(0); + } + } else { + if (actionSize == 0) { + MacroConditionSelectionChanged(0); + } else { + MacroActionSelectionChanged(0); + } + } + return; + } + + if (currentActionIdx < actionSize - 1) { + MacroActionSelectionChanged(currentActionIdx + 1); + return; + } + if (currentConditionIdx < conditionSize - 1) { + MacroConditionSelectionChanged(currentConditionIdx + 1); + return; + } + if (currentActionIdx == actionSize - 1) { + if (conditionSize == 0) { + MacroActionSelectionChanged(0); + } else { + MacroConditionSelectionChanged(0); + } + return; + } + if (currentConditionIdx == conditionSize - 1) { + if (actionSize == 0) { + MacroConditionSelectionChanged(0); + } else { + MacroActionSelectionChanged(0); + } + return; + } +} + void AdvSceneSwitcher::DeleteMacroSegementHotkey() { - if (!isActiveWindow() || !isAncestorOf(focusWidget()) || - !(ui->tabWidget->currentWidget()->objectName() == "macroTab")) { + if (!MacroTabIsInFocus()) { return; }