mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-22 18:04:59 -05:00
The "core" macro conditions and actions have been extracted out to the "base" plugin. The library now mostly contains functionality which is required across all plugins and (e.g. definitions for macro segments). The goal is to reduce the complexity and cross-dependencies and group the source files in a better way. This should relsove the "library limit of 65535 objects exceeded" build issue occuring in some Windows build environments.
922 lines
25 KiB
C++
922 lines
25 KiB
C++
#include "macro-action-hotkey.hpp"
|
|
#include "platform-funcs.hpp"
|
|
#include "utility.hpp"
|
|
|
|
#include <thread>
|
|
#include <obs-interaction.h>
|
|
|
|
namespace advss {
|
|
|
|
const std::string MacroActionHotkey::id = "hotkey";
|
|
|
|
bool MacroActionHotkey::_registered = MacroActionFactory::Register(
|
|
MacroActionHotkey::id,
|
|
{MacroActionHotkey::Create, MacroActionHotkeyEdit::Create,
|
|
"AdvSceneSwitcher.action.hotkey"});
|
|
|
|
const static std::map<MacroActionHotkey::Action, std::string> actionTypes = {
|
|
{MacroActionHotkey::Action::OBS_HOTKEY,
|
|
"AdvSceneSwitcher.action.hotkey.type.obs"},
|
|
{MacroActionHotkey::Action::CUSTOM,
|
|
"AdvSceneSwitcher.action.hotkey.type.custom"},
|
|
};
|
|
|
|
const static std::map<obs_hotkey_registerer_type, std::string> hotkeyTypes = {
|
|
{OBS_HOTKEY_REGISTERER_FRONTEND,
|
|
"AdvSceneSwitcher.action.hotkey.type.obs.type.frontend"},
|
|
{OBS_HOTKEY_REGISTERER_SOURCE,
|
|
"AdvSceneSwitcher.action.hotkey.type.obs.type.soruce"},
|
|
{OBS_HOTKEY_REGISTERER_OUTPUT,
|
|
"AdvSceneSwitcher.action.hotkey.type.obs.type.output"},
|
|
{OBS_HOTKEY_REGISTERER_ENCODER,
|
|
"AdvSceneSwitcher.action.hotkey.type.obs.type.encoder"},
|
|
{OBS_HOTKEY_REGISTERER_SERVICE,
|
|
"AdvSceneSwitcher.action.hotkey.type.obs.type.service"},
|
|
};
|
|
|
|
static std::unordered_map<HotkeyType, long> keyTable = {
|
|
// Chars
|
|
{HotkeyType::Key_A, OBS_KEY_A},
|
|
{HotkeyType::Key_B, OBS_KEY_B},
|
|
{HotkeyType::Key_C, OBS_KEY_C},
|
|
{HotkeyType::Key_D, OBS_KEY_D},
|
|
{HotkeyType::Key_E, OBS_KEY_E},
|
|
{HotkeyType::Key_F, OBS_KEY_F},
|
|
{HotkeyType::Key_G, OBS_KEY_G},
|
|
{HotkeyType::Key_H, OBS_KEY_H},
|
|
{HotkeyType::Key_I, OBS_KEY_I},
|
|
{HotkeyType::Key_J, OBS_KEY_J},
|
|
{HotkeyType::Key_K, OBS_KEY_K},
|
|
{HotkeyType::Key_L, OBS_KEY_L},
|
|
{HotkeyType::Key_M, OBS_KEY_M},
|
|
{HotkeyType::Key_N, OBS_KEY_N},
|
|
{HotkeyType::Key_O, OBS_KEY_O},
|
|
{HotkeyType::Key_P, OBS_KEY_P},
|
|
{HotkeyType::Key_Q, OBS_KEY_Q},
|
|
{HotkeyType::Key_R, OBS_KEY_R},
|
|
{HotkeyType::Key_S, OBS_KEY_S},
|
|
{HotkeyType::Key_T, OBS_KEY_T},
|
|
{HotkeyType::Key_U, OBS_KEY_U},
|
|
{HotkeyType::Key_V, OBS_KEY_V},
|
|
{HotkeyType::Key_W, OBS_KEY_W},
|
|
{HotkeyType::Key_X, OBS_KEY_X},
|
|
{HotkeyType::Key_Y, OBS_KEY_Y},
|
|
{HotkeyType::Key_Z, OBS_KEY_Z},
|
|
|
|
// Numbers
|
|
{HotkeyType::Key_0, OBS_KEY_0},
|
|
{HotkeyType::Key_1, OBS_KEY_1},
|
|
{HotkeyType::Key_2, OBS_KEY_2},
|
|
{HotkeyType::Key_3, OBS_KEY_3},
|
|
{HotkeyType::Key_4, OBS_KEY_4},
|
|
{HotkeyType::Key_5, OBS_KEY_5},
|
|
{HotkeyType::Key_6, OBS_KEY_6},
|
|
{HotkeyType::Key_7, OBS_KEY_7},
|
|
{HotkeyType::Key_8, OBS_KEY_8},
|
|
{HotkeyType::Key_9, OBS_KEY_9},
|
|
|
|
{HotkeyType::Key_F1, OBS_KEY_F1},
|
|
{HotkeyType::Key_F2, OBS_KEY_F2},
|
|
{HotkeyType::Key_F3, OBS_KEY_F3},
|
|
{HotkeyType::Key_F4, OBS_KEY_F4},
|
|
{HotkeyType::Key_F5, OBS_KEY_F5},
|
|
{HotkeyType::Key_F6, OBS_KEY_F6},
|
|
{HotkeyType::Key_F7, OBS_KEY_F7},
|
|
{HotkeyType::Key_F8, OBS_KEY_F8},
|
|
{HotkeyType::Key_F9, OBS_KEY_F9},
|
|
{HotkeyType::Key_F10, OBS_KEY_F10},
|
|
{HotkeyType::Key_F11, OBS_KEY_F11},
|
|
{HotkeyType::Key_F12, OBS_KEY_F12},
|
|
{HotkeyType::Key_F13, OBS_KEY_F13},
|
|
{HotkeyType::Key_F14, OBS_KEY_F14},
|
|
{HotkeyType::Key_F15, OBS_KEY_F15},
|
|
{HotkeyType::Key_F16, OBS_KEY_F16},
|
|
{HotkeyType::Key_F17, OBS_KEY_F17},
|
|
{HotkeyType::Key_F18, OBS_KEY_F18},
|
|
{HotkeyType::Key_F19, OBS_KEY_F19},
|
|
{HotkeyType::Key_F20, OBS_KEY_F20},
|
|
{HotkeyType::Key_F21, OBS_KEY_F21},
|
|
{HotkeyType::Key_F22, OBS_KEY_F22},
|
|
{HotkeyType::Key_F23, OBS_KEY_F23},
|
|
{HotkeyType::Key_F24, OBS_KEY_F24},
|
|
|
|
{HotkeyType::Key_Escape, OBS_KEY_ESCAPE},
|
|
{HotkeyType::Key_Space, OBS_KEY_SPACE},
|
|
{HotkeyType::Key_Return, OBS_KEY_RETURN},
|
|
{HotkeyType::Key_Backspace, OBS_KEY_BACKSPACE},
|
|
{HotkeyType::Key_Tab, OBS_KEY_TAB},
|
|
|
|
{HotkeyType::Key_Shift_L, OBS_KEY_SHIFT},
|
|
{HotkeyType::Key_Shift_R, OBS_KEY_SHIFT},
|
|
{HotkeyType::Key_Control_L, OBS_KEY_CONTROL},
|
|
{HotkeyType::Key_Control_R, OBS_KEY_CONTROL},
|
|
{HotkeyType::Key_Alt_L, OBS_KEY_ALT},
|
|
{HotkeyType::Key_Alt_R, OBS_KEY_ALT},
|
|
{HotkeyType::Key_Win_L, OBS_KEY_META},
|
|
{HotkeyType::Key_Win_R, OBS_KEY_META},
|
|
{HotkeyType::Key_Apps, OBS_KEY_APPLICATIONLEFT},
|
|
|
|
{HotkeyType::Key_CapsLock, OBS_KEY_CAPSLOCK},
|
|
{HotkeyType::Key_NumLock, OBS_KEY_NUMLOCK},
|
|
{HotkeyType::Key_ScrollLock, OBS_KEY_SCROLLLOCK},
|
|
|
|
{HotkeyType::Key_PrintScreen, OBS_KEY_PRINT},
|
|
{HotkeyType::Key_Pause, OBS_KEY_PAUSE},
|
|
|
|
{HotkeyType::Key_Insert, OBS_KEY_INSERT},
|
|
{HotkeyType::Key_Delete, OBS_KEY_DELETE},
|
|
{HotkeyType::Key_PageUP, OBS_KEY_PAGEUP},
|
|
{HotkeyType::Key_PageDown, OBS_KEY_PAGEDOWN},
|
|
{HotkeyType::Key_Home, OBS_KEY_HOME},
|
|
{HotkeyType::Key_End, OBS_KEY_END},
|
|
|
|
{HotkeyType::Key_Left, OBS_KEY_LEFT},
|
|
{HotkeyType::Key_Up, OBS_KEY_UP},
|
|
{HotkeyType::Key_Right, OBS_KEY_RIGHT},
|
|
{HotkeyType::Key_Down, OBS_KEY_DOWN},
|
|
|
|
{HotkeyType::Key_Numpad0, OBS_KEY_NUM0},
|
|
{HotkeyType::Key_Numpad1, OBS_KEY_NUM1},
|
|
{HotkeyType::Key_Numpad2, OBS_KEY_NUM2},
|
|
{HotkeyType::Key_Numpad3, OBS_KEY_NUM3},
|
|
{HotkeyType::Key_Numpad4, OBS_KEY_NUM4},
|
|
{HotkeyType::Key_Numpad5, OBS_KEY_NUM5},
|
|
{HotkeyType::Key_Numpad6, OBS_KEY_NUM6},
|
|
{HotkeyType::Key_Numpad7, OBS_KEY_NUM7},
|
|
{HotkeyType::Key_Numpad8, OBS_KEY_NUM8},
|
|
{HotkeyType::Key_Numpad9, OBS_KEY_NUM9},
|
|
|
|
{HotkeyType::Key_NumpadAdd, OBS_KEY_NUMPLUS},
|
|
{HotkeyType::Key_NumpadSubtract, OBS_KEY_NUMMINUS},
|
|
{HotkeyType::Key_NumpadMultiply, OBS_KEY_NUMASTERISK},
|
|
{HotkeyType::Key_NumpadDivide, OBS_KEY_NUMSLASH},
|
|
{HotkeyType::Key_NumpadDecimal, OBS_KEY_NUMPERIOD},
|
|
//{HotkeyType::Key_NumpadEnter, ???},
|
|
};
|
|
|
|
static obs_key_combination
|
|
keysToOBSKeycombo(const std::vector<HotkeyType> &keys)
|
|
{
|
|
obs_key_combination combo{};
|
|
auto it = keyTable.find(keys.back());
|
|
if (it != keyTable.end()) {
|
|
combo.key = (obs_key_t)it->second;
|
|
}
|
|
if (keys.size() == 1) {
|
|
return combo;
|
|
}
|
|
|
|
for (uint32_t i = 0; i < keys.size() - 1; i++) {
|
|
switch (keys[i]) {
|
|
case HotkeyType::Key_Shift_L:
|
|
combo.modifiers |= INTERACT_SHIFT_KEY;
|
|
break;
|
|
case HotkeyType::Key_Shift_R:
|
|
combo.modifiers |= INTERACT_SHIFT_KEY;
|
|
break;
|
|
case HotkeyType::Key_Control_L:
|
|
combo.modifiers |= INTERACT_CONTROL_KEY;
|
|
break;
|
|
case HotkeyType::Key_Control_R:
|
|
combo.modifiers |= INTERACT_CONTROL_KEY;
|
|
break;
|
|
case HotkeyType::Key_Alt_L:
|
|
combo.modifiers |= INTERACT_ALT_KEY;
|
|
break;
|
|
case HotkeyType::Key_Alt_R:
|
|
combo.modifiers |= INTERACT_ALT_KEY;
|
|
break;
|
|
case HotkeyType::Key_Win_L:
|
|
combo.modifiers |= INTERACT_COMMAND_KEY;
|
|
break;
|
|
case HotkeyType::Key_Win_R:
|
|
combo.modifiers |= INTERACT_COMMAND_KEY;
|
|
break;
|
|
case HotkeyType::Key_CapsLock:
|
|
combo.modifiers |= INTERACT_CAPS_KEY;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return combo;
|
|
}
|
|
|
|
static void InjectKeys(const std::vector<HotkeyType> &keys, int duration)
|
|
{
|
|
auto combo = keysToOBSKeycombo(keys);
|
|
if (obs_key_combination_is_empty(combo)) {
|
|
return;
|
|
}
|
|
// I am not sure why this is necessary
|
|
obs_hotkey_inject_event(combo, false);
|
|
|
|
obs_hotkey_inject_event(combo, true);
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(duration));
|
|
obs_hotkey_inject_event(combo, false);
|
|
}
|
|
|
|
static void addNamePrefix(std::string &name, obs_hotkey_t *hotkey)
|
|
{
|
|
const auto type = obs_hotkey_get_registerer_type(hotkey);
|
|
std::string prefix;
|
|
if (type == OBS_HOTKEY_REGISTERER_SOURCE) {
|
|
auto source = reinterpret_cast<obs_weak_source_t *>(
|
|
obs_hotkey_get_registerer(hotkey));
|
|
prefix = "[" + GetWeakSourceName(source) + "] ";
|
|
} else if (type == OBS_HOTKEY_REGISTERER_OUTPUT) {
|
|
auto weakOutput = reinterpret_cast<obs_weak_output_t *>(
|
|
obs_hotkey_get_registerer(hotkey));
|
|
std::string name;
|
|
auto output = obs_weak_output_get_output(weakOutput);
|
|
if (output) {
|
|
name = obs_output_get_name(output);
|
|
obs_output_release(output);
|
|
}
|
|
prefix = "[" + name + "] ";
|
|
} else if (type == OBS_HOTKEY_REGISTERER_ENCODER) {
|
|
auto weakEncoder = reinterpret_cast<obs_weak_encoder_t *>(
|
|
obs_hotkey_get_registerer(hotkey));
|
|
std::string name;
|
|
auto encoder = obs_weak_encoder_get_encoder(weakEncoder);
|
|
if (encoder) {
|
|
name = obs_encoder_get_name(encoder);
|
|
obs_encoder_release(encoder);
|
|
}
|
|
prefix = "[" + name + "] ";
|
|
} else if (type == OBS_HOTKEY_REGISTERER_SERVICE) {
|
|
auto weakService = reinterpret_cast<obs_weak_service_t *>(
|
|
obs_hotkey_get_registerer(hotkey));
|
|
std::string name;
|
|
auto service = obs_weak_service_get_service(weakService);
|
|
if (service) {
|
|
name = obs_service_get_name(service);
|
|
obs_service_release(service);
|
|
}
|
|
prefix = "[" + name + "] ";
|
|
}
|
|
name = prefix + name;
|
|
}
|
|
|
|
static obs_hotkey_id getHotkeyIdByName(const std::string &name)
|
|
{
|
|
struct Parameters {
|
|
std::string name;
|
|
obs_hotkey_id id = OBS_INVALID_HOTKEY_ID;
|
|
} params;
|
|
|
|
auto func = [](void *param, obs_hotkey_id id, obs_hotkey_t *hotkey) {
|
|
auto params = static_cast<Parameters *>(param);
|
|
std::string name = obs_hotkey_get_name(hotkey);
|
|
addNamePrefix(name, hotkey);
|
|
if (name == params->name) {
|
|
params->id = id;
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
params.name = name;
|
|
obs_enum_hotkeys(func, ¶ms);
|
|
return params.id;
|
|
}
|
|
|
|
void MacroActionHotkey::SendOBSHotkey()
|
|
{
|
|
auto id = getHotkeyIdByName(_hotkeyName);
|
|
if (id == OBS_INVALID_HOTKEY_ID) {
|
|
blog(LOG_WARNING,
|
|
"failed to get hotkey id for \"%s\" - key will not be pressed",
|
|
_hotkeyName.c_str());
|
|
return;
|
|
}
|
|
obs_queue_task(
|
|
OBS_TASK_UI,
|
|
[](void *param) {
|
|
auto id = (size_t *)param;
|
|
obs_hotkey_trigger_routed_callback(*id, false);
|
|
obs_hotkey_trigger_routed_callback(*id, true);
|
|
obs_hotkey_trigger_routed_callback(*id, false);
|
|
},
|
|
&id, true);
|
|
}
|
|
|
|
void MacroActionHotkey::SendCustomHotkey()
|
|
{
|
|
std::vector<HotkeyType> keys;
|
|
if (_leftShift) {
|
|
keys.push_back(HotkeyType::Key_Shift_L);
|
|
}
|
|
if (_rightShift) {
|
|
keys.push_back(HotkeyType::Key_Shift_R);
|
|
}
|
|
if (_leftCtrl) {
|
|
keys.push_back(HotkeyType::Key_Control_L);
|
|
}
|
|
if (_rightCtrl) {
|
|
keys.push_back(HotkeyType::Key_Control_R);
|
|
}
|
|
if (_leftAlt) {
|
|
keys.push_back(HotkeyType::Key_Alt_L);
|
|
}
|
|
if (_rightAlt) {
|
|
keys.push_back(HotkeyType::Key_Alt_R);
|
|
}
|
|
if (_leftMeta) {
|
|
keys.push_back(HotkeyType::Key_Win_L);
|
|
}
|
|
if (_rightMeta) {
|
|
keys.push_back(HotkeyType::Key_Win_R);
|
|
}
|
|
if (_key != HotkeyType::Key_NoKey) {
|
|
keys.push_back(_key);
|
|
}
|
|
|
|
if (!keys.empty()) {
|
|
int dur = _duration.Milliseconds();
|
|
if (_onlySendToObs || !CanSimulateKeyPresses()) {
|
|
std::thread t([keys, dur]() { InjectKeys(keys, dur); });
|
|
t.detach();
|
|
} else {
|
|
std::thread t([keys, dur]() { PressKeys(keys, dur); });
|
|
t.detach();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool MacroActionHotkey::PerformAction()
|
|
{
|
|
switch (_action) {
|
|
case advss::MacroActionHotkey::Action::OBS_HOTKEY:
|
|
SendOBSHotkey();
|
|
break;
|
|
case advss::MacroActionHotkey::Action::CUSTOM:
|
|
SendCustomHotkey();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void MacroActionHotkey::LogAction() const
|
|
{
|
|
vblog(LOG_INFO, "sent hotkey type %d", static_cast<int>(_action));
|
|
}
|
|
|
|
bool MacroActionHotkey::Save(obs_data_t *obj) const
|
|
{
|
|
MacroAction::Save(obj);
|
|
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
|
obs_data_set_int(obj, "hotkeyType", _hotkeyType);
|
|
obs_data_set_string(obj, "hotkeyName", _hotkeyName.c_str());
|
|
obs_data_set_int(obj, "key", static_cast<int>(_key));
|
|
obs_data_set_bool(obj, "left_shift", _leftShift);
|
|
obs_data_set_bool(obj, "right_shift", _rightShift);
|
|
obs_data_set_bool(obj, "left_ctrl", _leftCtrl);
|
|
obs_data_set_bool(obj, "right_ctrl", _rightCtrl);
|
|
obs_data_set_bool(obj, "left_alt", _leftAlt);
|
|
obs_data_set_bool(obj, "right_alt", _rightAlt);
|
|
obs_data_set_bool(obj, "left_meta", _leftMeta);
|
|
obs_data_set_bool(obj, "right_meta", _rightMeta);
|
|
_duration.Save(obj);
|
|
obs_data_set_bool(obj, "onlyOBS", _onlySendToObs);
|
|
obs_data_set_int(obj, "version", 2);
|
|
return true;
|
|
}
|
|
|
|
bool MacroActionHotkey::Load(obs_data_t *obj)
|
|
{
|
|
MacroAction::Load(obj);
|
|
int version = obs_data_get_int(obj, "version");
|
|
if (version != 2) {
|
|
_action = Action::CUSTOM;
|
|
} else {
|
|
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
|
}
|
|
_hotkeyType = static_cast<obs_hotkey_registerer_type>(
|
|
obs_data_get_int(obj, "hotkeyType"));
|
|
_hotkeyName = obs_data_get_string(obj, "hotkeyName");
|
|
_key = static_cast<HotkeyType>(obs_data_get_int(obj, "key"));
|
|
_leftShift = obs_data_get_bool(obj, "left_shift");
|
|
_rightShift = obs_data_get_bool(obj, "right_shift");
|
|
_leftCtrl = obs_data_get_bool(obj, "left_ctrl");
|
|
_rightCtrl = obs_data_get_bool(obj, "right_ctrl");
|
|
_leftAlt = obs_data_get_bool(obj, "left_alt");
|
|
_rightAlt = obs_data_get_bool(obj, "right_alt");
|
|
_leftMeta = obs_data_get_bool(obj, "left_meta");
|
|
_rightMeta = obs_data_get_bool(obj, "right_meta");
|
|
if (version == 0) {
|
|
_duration = obs_data_get_int(obj, "duration") / 1000.0;
|
|
} else {
|
|
_duration.Load(obj);
|
|
}
|
|
_onlySendToObs = obs_data_get_bool(obj, "onlyOBS");
|
|
return true;
|
|
}
|
|
|
|
static inline void populateKeySelection(QComboBox *list)
|
|
{
|
|
list->addItem("No key");
|
|
list->addItem("A");
|
|
list->addItem("B");
|
|
list->addItem("C");
|
|
list->addItem("D");
|
|
list->addItem("E");
|
|
list->addItem("F");
|
|
list->addItem("G");
|
|
list->addItem("H");
|
|
list->addItem("I");
|
|
list->addItem("J");
|
|
list->addItem("K");
|
|
list->addItem("L");
|
|
list->addItem("M");
|
|
list->addItem("N");
|
|
list->addItem("O");
|
|
list->addItem("P");
|
|
list->addItem("Q");
|
|
list->addItem("R");
|
|
list->addItem("S");
|
|
list->addItem("T");
|
|
list->addItem("U");
|
|
list->addItem("V");
|
|
list->addItem("W");
|
|
list->addItem("X");
|
|
list->addItem("Y");
|
|
list->addItem("Z");
|
|
list->addItem("0");
|
|
list->addItem("1");
|
|
list->addItem("2");
|
|
list->addItem("3");
|
|
list->addItem("4");
|
|
list->addItem("5");
|
|
list->addItem("6");
|
|
list->addItem("7");
|
|
list->addItem("8");
|
|
list->addItem("9");
|
|
list->addItem("F1");
|
|
list->addItem("F2");
|
|
list->addItem("F3");
|
|
list->addItem("F4");
|
|
list->addItem("F5");
|
|
list->addItem("F6");
|
|
list->addItem("F7");
|
|
list->addItem("F8");
|
|
list->addItem("F9");
|
|
list->addItem("F10");
|
|
list->addItem("F11");
|
|
list->addItem("F12");
|
|
list->addItem("F13");
|
|
list->addItem("F14");
|
|
list->addItem("F15");
|
|
list->addItem("F16");
|
|
list->addItem("F17");
|
|
list->addItem("F18");
|
|
list->addItem("F19");
|
|
list->addItem("F20");
|
|
list->addItem("F21");
|
|
list->addItem("F22");
|
|
list->addItem("F23");
|
|
list->addItem("F24");
|
|
list->addItem("Escape");
|
|
list->addItem("Space");
|
|
list->addItem("Return");
|
|
list->addItem("Backspace");
|
|
list->addItem("Tab");
|
|
list->addItem("Shift_L");
|
|
list->addItem("Shift_R");
|
|
list->addItem("Control_L");
|
|
list->addItem("Control_R");
|
|
list->addItem("Alt_L");
|
|
list->addItem("Alt_R");
|
|
list->addItem("Win_L");
|
|
list->addItem("Win_R");
|
|
list->addItem("Apps");
|
|
list->addItem("CapsLock");
|
|
list->addItem("NumLock");
|
|
list->addItem("ScrollLock");
|
|
list->addItem("PrintScreen");
|
|
list->addItem("Pause");
|
|
list->addItem("Insert");
|
|
list->addItem("Delete");
|
|
list->addItem("PageUP");
|
|
list->addItem("PageDown");
|
|
list->addItem("Home");
|
|
list->addItem("End");
|
|
list->addItem("Left");
|
|
list->addItem("Right");
|
|
list->addItem("Up");
|
|
list->addItem("Down");
|
|
list->addItem("Numpad0");
|
|
list->addItem("Numpad1");
|
|
list->addItem("Numpad2");
|
|
list->addItem("Numpad3");
|
|
list->addItem("Numpad4");
|
|
list->addItem("Numpad5");
|
|
list->addItem("Numpad6");
|
|
list->addItem("Numpad7");
|
|
list->addItem("Numpad8");
|
|
list->addItem("Numpad9");
|
|
list->addItem("NumpadAdd");
|
|
list->addItem("NumpadSubtract");
|
|
list->addItem("NumpadMultiply");
|
|
list->addItem("NumpadDivide");
|
|
list->addItem("NumpadDecimal");
|
|
list->addItem("NumpadEnter");
|
|
}
|
|
|
|
static void populateActionSelection(QComboBox *list)
|
|
{
|
|
for (const auto &[_, value] : actionTypes) {
|
|
list->addItem(obs_module_text(value.c_str()));
|
|
}
|
|
}
|
|
static void populateHotkeyTypeSelection(QComboBox *list)
|
|
{
|
|
for (const auto &[_, value] : hotkeyTypes) {
|
|
list->addItem(obs_module_text(value.c_str()));
|
|
}
|
|
}
|
|
|
|
static void addNamePrefix(QString &name, obs_hotkey_t *hotkey)
|
|
{
|
|
auto temp = name.toStdString();
|
|
addNamePrefix(temp, hotkey);
|
|
name = QString::fromStdString(temp);
|
|
}
|
|
|
|
static void populateHotkeyNames(QComboBox *list,
|
|
obs_hotkey_registerer_type type)
|
|
{
|
|
struct Parameters {
|
|
QStringList names;
|
|
QStringList descriptions;
|
|
obs_hotkey_registerer_type type;
|
|
} params;
|
|
|
|
auto func = [](void *param, obs_hotkey_id, obs_hotkey_t *hotkey) {
|
|
auto params = static_cast<Parameters *>(param);
|
|
if (obs_hotkey_get_registerer_type(hotkey) == params->type) {
|
|
QString description(obs_hotkey_get_description(hotkey));
|
|
addNamePrefix(description, hotkey);
|
|
params->descriptions.append(description);
|
|
QString name(obs_hotkey_get_name(hotkey));
|
|
addNamePrefix(name, hotkey);
|
|
params->names.append(name);
|
|
}
|
|
return true;
|
|
};
|
|
|
|
params.type = type;
|
|
obs_enum_hotkeys(func, ¶ms);
|
|
|
|
list->clear();
|
|
for (int i = 0; i < params.names.size(); i++) {
|
|
list->addItem(params.descriptions.at(i), params.names.at(i));
|
|
}
|
|
AddSelectionEntry(list,
|
|
obs_module_text("AdvSceneSwitcher.selectHotkey"));
|
|
}
|
|
|
|
MacroActionHotkeyEdit::MacroActionHotkeyEdit(
|
|
QWidget *parent, std::shared_ptr<MacroActionHotkey> entryData)
|
|
: QWidget(parent),
|
|
_actionType(new QComboBox()),
|
|
_hotkeyType(new QComboBox()),
|
|
_obsHotkeys(new QComboBox()),
|
|
_keys(new QComboBox()),
|
|
_leftShift(new QCheckBox(
|
|
obs_module_text("AdvSceneSwitcher.action.hotkey.leftShift"))),
|
|
_rightShift(new QCheckBox(obs_module_text(
|
|
"AdvSceneSwitcher.action.hotkey.rightShift"))),
|
|
_leftCtrl(new QCheckBox(
|
|
obs_module_text("AdvSceneSwitcher.action.hotkey.leftCtrl"))),
|
|
_rightCtrl(new QCheckBox(
|
|
obs_module_text("AdvSceneSwitcher.action.hotkey.rightCtrl"))),
|
|
_leftAlt(new QCheckBox(
|
|
obs_module_text("AdvSceneSwitcher.action.hotkey.leftAlt"))),
|
|
_rightAlt(new QCheckBox(
|
|
obs_module_text("AdvSceneSwitcher.action.hotkey.rightAlt"))),
|
|
_leftMeta(new QCheckBox(
|
|
obs_module_text("AdvSceneSwitcher.action.hotkey.leftMeta"))),
|
|
_rightMeta(new QCheckBox(
|
|
obs_module_text("AdvSceneSwitcher.action.hotkey.rightMeta"))),
|
|
_duration(new DurationSelection(this, false)),
|
|
_onlySendToOBS(new QCheckBox(
|
|
obs_module_text("AdvSceneSwitcher.action.hotkey.onlyOBS"))),
|
|
_noKeyPressSimulationWarning(new QLabel(
|
|
obs_module_text("AdvSceneSwitcher.action.hotkey.disabled"))),
|
|
_entryLayout(new QHBoxLayout()),
|
|
_keyConfigLayout(new QHBoxLayout())
|
|
{
|
|
populateKeySelection(_keys);
|
|
populateActionSelection(_actionType);
|
|
populateHotkeyTypeSelection(_hotkeyType);
|
|
|
|
QWidget::connect(_actionType, SIGNAL(currentIndexChanged(int)), this,
|
|
SLOT(ActionChanged(int)));
|
|
QWidget::connect(_hotkeyType, SIGNAL(currentIndexChanged(int)), this,
|
|
SLOT(HotkeyTypeChanged(int)));
|
|
QWidget::connect(_obsHotkeys, SIGNAL(currentIndexChanged(int)), this,
|
|
SLOT(OBSHotkeyChanged(int)));
|
|
QWidget::connect(_keys, SIGNAL(currentIndexChanged(int)), this,
|
|
SLOT(KeyChanged(int)));
|
|
QWidget::connect(_leftShift, SIGNAL(stateChanged(int)), this,
|
|
SLOT(LShiftChanged(int)));
|
|
QWidget::connect(_rightShift, SIGNAL(stateChanged(int)), this,
|
|
SLOT(RShiftChanged(int)));
|
|
QWidget::connect(_leftCtrl, SIGNAL(stateChanged(int)), this,
|
|
SLOT(LCtrlChanged(int)));
|
|
QWidget::connect(_rightCtrl, SIGNAL(stateChanged(int)), this,
|
|
SLOT(RCtrlChanged(int)));
|
|
QWidget::connect(_leftAlt, SIGNAL(stateChanged(int)), this,
|
|
SLOT(LAltChanged(int)));
|
|
QWidget::connect(_rightAlt, SIGNAL(stateChanged(int)), this,
|
|
SLOT(RAltChanged(int)));
|
|
QWidget::connect(_leftMeta, SIGNAL(stateChanged(int)), this,
|
|
SLOT(LMetaChanged(int)));
|
|
QWidget::connect(_rightMeta, SIGNAL(stateChanged(int)), this,
|
|
SLOT(RMetaChanged(int)));
|
|
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
|
this, SLOT(DurationChanged(const Duration &)));
|
|
QWidget::connect(_onlySendToOBS, SIGNAL(stateChanged(int)), this,
|
|
SLOT(OnlySendToOBSChanged(int)));
|
|
|
|
_entryLayout->setContentsMargins(0, 0, 0, 0);
|
|
_keyConfigLayout->setContentsMargins(0, 0, 0, 0);
|
|
_keyConfigLayout->addWidget(_leftShift);
|
|
_keyConfigLayout->addWidget(_rightShift);
|
|
_keyConfigLayout->addWidget(_leftCtrl);
|
|
_keyConfigLayout->addWidget(_rightCtrl);
|
|
_keyConfigLayout->addWidget(_leftAlt);
|
|
_keyConfigLayout->addWidget(_rightAlt);
|
|
_keyConfigLayout->addWidget(_leftMeta);
|
|
_keyConfigLayout->addWidget(_rightMeta);
|
|
_keyConfigLayout->addStretch();
|
|
|
|
auto mainLayout = new QVBoxLayout;
|
|
mainLayout->addLayout(_entryLayout);
|
|
mainLayout->addLayout(_keyConfigLayout);
|
|
mainLayout->addWidget(_onlySendToOBS);
|
|
mainLayout->addWidget(_noKeyPressSimulationWarning);
|
|
setLayout(mainLayout);
|
|
|
|
_onlySendToOBS->setEnabled(CanSimulateKeyPresses());
|
|
|
|
_entryData = entryData;
|
|
UpdateEntryData();
|
|
_loading = false;
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::RepopulateOBSHotkeySelection()
|
|
{
|
|
populateHotkeyNames(_obsHotkeys, _entryData->_hotkeyType);
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::SetWidgetVisibility()
|
|
{
|
|
_entryLayout->removeWidget(_actionType);
|
|
_entryLayout->removeWidget(_hotkeyType);
|
|
_entryLayout->removeWidget(_obsHotkeys);
|
|
_entryLayout->removeWidget(_keys);
|
|
_entryLayout->removeWidget(_duration);
|
|
ClearLayout(_entryLayout);
|
|
PlaceWidgets(
|
|
obs_module_text(
|
|
_entryData->_action ==
|
|
MacroActionHotkey::Action::OBS_HOTKEY
|
|
? "AdvSceneSwitcher.action.hotkey.entry.obs"
|
|
: "AdvSceneSwitcher.action.hotkey.entry.custom"),
|
|
_entryLayout,
|
|
{
|
|
{"{{actionType}}", _actionType},
|
|
{"{{hotkeyType}}", _hotkeyType},
|
|
{"{{obsHotkeys}}", _obsHotkeys},
|
|
{"{{keys}}", _keys},
|
|
{"{{duration}}", _duration},
|
|
});
|
|
|
|
_noKeyPressSimulationWarning->setVisible(!_entryData->_onlySendToObs &&
|
|
!CanSimulateKeyPresses());
|
|
SetLayoutVisible(_keyConfigLayout,
|
|
_entryData->_action ==
|
|
MacroActionHotkey::Action::CUSTOM);
|
|
_duration->setVisible(_entryData->_action ==
|
|
MacroActionHotkey::Action::CUSTOM);
|
|
_keys->setVisible(_entryData->_action ==
|
|
MacroActionHotkey::Action::CUSTOM);
|
|
_onlySendToOBS->setVisible(_entryData->_action ==
|
|
MacroActionHotkey::Action::CUSTOM);
|
|
_hotkeyType->setVisible(_entryData->_action ==
|
|
MacroActionHotkey::Action::OBS_HOTKEY);
|
|
_obsHotkeys->setVisible(_entryData->_action ==
|
|
MacroActionHotkey::Action::OBS_HOTKEY);
|
|
adjustSize();
|
|
updateGeometry();
|
|
}
|
|
|
|
static QString getHotkeyDescriptionByName(const std::string &name)
|
|
{
|
|
struct Parameters {
|
|
std::string name;
|
|
QString description = "";
|
|
} params;
|
|
|
|
auto func = [](void *param, obs_hotkey_id, obs_hotkey_t *hotkey) {
|
|
auto params = static_cast<Parameters *>(param);
|
|
std::string name = obs_hotkey_get_name(hotkey);
|
|
addNamePrefix(name, hotkey);
|
|
if (name == params->name) {
|
|
params->description =
|
|
obs_hotkey_get_description(hotkey);
|
|
addNamePrefix(params->description, hotkey);
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
params.name = name;
|
|
obs_enum_hotkeys(func, ¶ms);
|
|
return params.description;
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::UpdateEntryData()
|
|
{
|
|
if (!_entryData) {
|
|
return;
|
|
}
|
|
|
|
_actionType->setCurrentIndex(static_cast<int>(_entryData->_action));
|
|
_hotkeyType->setCurrentIndex(static_cast<int>(_entryData->_hotkeyType));
|
|
RepopulateOBSHotkeySelection();
|
|
_obsHotkeys->setCurrentText(
|
|
getHotkeyDescriptionByName(_entryData->_hotkeyName));
|
|
_keys->setCurrentIndex(static_cast<int>(_entryData->_key));
|
|
_leftShift->setChecked(_entryData->_leftShift);
|
|
_rightShift->setChecked(_entryData->_rightShift);
|
|
_leftCtrl->setChecked(_entryData->_leftCtrl);
|
|
_rightCtrl->setChecked(_entryData->_rightCtrl);
|
|
_leftAlt->setChecked(_entryData->_leftAlt);
|
|
_rightAlt->setChecked(_entryData->_rightAlt);
|
|
_leftMeta->setChecked(_entryData->_leftMeta);
|
|
_rightMeta->setChecked(_entryData->_rightMeta);
|
|
_duration->SetDuration(_entryData->_duration);
|
|
_onlySendToOBS->setChecked(_entryData->_onlySendToObs ||
|
|
!CanSimulateKeyPresses());
|
|
SetWidgetVisibility();
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::LShiftChanged(int state)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
_entryData->_leftShift = state;
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::RShiftChanged(int state)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
_entryData->_rightShift = state;
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::LCtrlChanged(int state)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
_entryData->_leftCtrl = state;
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::RCtrlChanged(int state)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
_entryData->_rightCtrl = state;
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::LAltChanged(int state)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
_entryData->_leftAlt = state;
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::RAltChanged(int state)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
_entryData->_rightAlt = state;
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::LMetaChanged(int state)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
_entryData->_leftMeta = state;
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::RMetaChanged(int state)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
_entryData->_rightMeta = state;
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::DurationChanged(const Duration &dur)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
_entryData->_duration = dur;
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::OnlySendToOBSChanged(int state)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
_entryData->_onlySendToObs = state;
|
|
SetWidgetVisibility();
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::KeyChanged(int key)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
_entryData->_key = static_cast<HotkeyType>(key);
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::ActionChanged(int value)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
_entryData->_action = static_cast<MacroActionHotkey::Action>(value);
|
|
SetWidgetVisibility();
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::HotkeyTypeChanged(int value)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
{
|
|
auto lock = LockContext();
|
|
_entryData->_hotkeyType =
|
|
static_cast<obs_hotkey_registerer_type>(value);
|
|
}
|
|
RepopulateOBSHotkeySelection();
|
|
}
|
|
|
|
void MacroActionHotkeyEdit::OBSHotkeyChanged(int idx)
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
auto lock = LockContext();
|
|
if (idx == -1) {
|
|
_entryData->_hotkeyName = "";
|
|
return;
|
|
}
|
|
_entryData->_hotkeyName =
|
|
_obsHotkeys->itemData(idx).toString().toStdString();
|
|
}
|
|
|
|
} // namespace advss
|