mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-22 01:44:49 -05:00
252 lines
6.6 KiB
C++
252 lines
6.6 KiB
C++
#include "hotkey.hpp"
|
|
#include "advanced-scene-switcher.hpp"
|
|
#include <obs-module.h>
|
|
#include <fstream>
|
|
#include <regex>
|
|
|
|
std::vector<std::weak_ptr<Hotkey>> Hotkey::_registeredHotkeys = {};
|
|
uint32_t Hotkey::_hotkeyCounter = 1;
|
|
|
|
std::shared_ptr<Hotkey> Hotkey::GetHotkey(const std::string &description,
|
|
bool ignoreExistingHotkeys)
|
|
{
|
|
// Clean up expired hotkeys
|
|
auto it = _registeredHotkeys.begin();
|
|
while (it != _registeredHotkeys.end()) {
|
|
if (it->expired()) {
|
|
it = _registeredHotkeys.erase(it);
|
|
} else {
|
|
it++;
|
|
}
|
|
}
|
|
|
|
// Check for existing hotkey with same description
|
|
for (const auto &h : _registeredHotkeys) {
|
|
auto hotkey = h.lock();
|
|
if (!hotkey) {
|
|
continue;
|
|
}
|
|
if (hotkey->_description == description) {
|
|
hotkey->_ignoreExistingHotkeys = ignoreExistingHotkeys;
|
|
return hotkey;
|
|
}
|
|
}
|
|
|
|
// Create new hotkey
|
|
auto hotkey = std::make_shared<Hotkey>(description);
|
|
_registeredHotkeys.emplace_back(hotkey);
|
|
hotkey->_ignoreExistingHotkeys = ignoreExistingHotkeys;
|
|
return hotkey;
|
|
}
|
|
|
|
Hotkey::Hotkey(const std::string &description) : _description(description)
|
|
{
|
|
std::string name =
|
|
"macro_condition_hotkey_" + std::to_string(_hotkeyCounter);
|
|
_hotkeyID = obs_hotkey_register_frontend(
|
|
name.c_str(), _description.c_str(), Callback, this);
|
|
_hotkeyCounter++;
|
|
}
|
|
|
|
bool Hotkey::Save(obs_data_t *obj) const
|
|
{
|
|
obs_data_set_string(obj, "desc", _description.c_str());
|
|
obs_data_array_t *hotkeyData = obs_hotkey_save(_hotkeyID);
|
|
obs_data_set_array(obj, "keyBind", hotkeyData);
|
|
obs_data_array_release(hotkeyData);
|
|
return true;
|
|
}
|
|
|
|
bool Hotkey::Load(obs_data_t *obj)
|
|
{
|
|
auto description = obs_data_get_string(obj, "desc");
|
|
if (!DescriptionAvailable(description)) {
|
|
return false;
|
|
}
|
|
_description = description;
|
|
obs_data_array_t *hotkeyData = obs_data_get_array(obj, "keyBind");
|
|
obs_hotkey_load(_hotkeyID, hotkeyData);
|
|
obs_data_array_release(hotkeyData);
|
|
obs_hotkey_set_description(_hotkeyID, _description.c_str());
|
|
_ignoreExistingHotkeys = false;
|
|
return true;
|
|
}
|
|
|
|
Hotkey::~Hotkey()
|
|
{
|
|
obs_hotkey_unregister(_hotkeyID);
|
|
}
|
|
|
|
bool Hotkey::UpdateDescription(const std::string &descritpion)
|
|
{
|
|
if (!DescriptionAvailable(descritpion)) {
|
|
return false;
|
|
}
|
|
_description = descritpion;
|
|
obs_hotkey_set_description(_hotkeyID, descritpion.c_str());
|
|
return true;
|
|
}
|
|
|
|
bool Hotkey::DescriptionAvailable(const std::string &descritpion)
|
|
{
|
|
for (const auto &hotkey : _registeredHotkeys) {
|
|
auto h = hotkey.lock();
|
|
if (!h) {
|
|
continue;
|
|
}
|
|
if (!h->_ignoreExistingHotkeys &&
|
|
h->_description == descritpion) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void Hotkey::Callback(void *data, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
|
{
|
|
auto hotkey = static_cast<Hotkey *>(data);
|
|
if (pressed) {
|
|
hotkey->_lastPressed =
|
|
std::chrono::high_resolution_clock::now();
|
|
}
|
|
hotkey->_pressed = pressed;
|
|
}
|
|
|
|
void Hotkey::ClearAllHotkeys()
|
|
{
|
|
_registeredHotkeys.clear();
|
|
}
|
|
|
|
void startHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
|
{
|
|
if (pressed) {
|
|
if (!(switcher->th && switcher->th->isRunning())) {
|
|
switcher->Start();
|
|
}
|
|
}
|
|
}
|
|
|
|
void stopHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
|
{
|
|
if (pressed) {
|
|
if (switcher->th && switcher->th->isRunning()) {
|
|
switcher->Stop();
|
|
}
|
|
}
|
|
}
|
|
|
|
void startStopToggleHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
|
bool pressed)
|
|
{
|
|
if (pressed) {
|
|
if (switcher->th && switcher->th->isRunning()) {
|
|
switcher->Stop();
|
|
} else {
|
|
switcher->Start();
|
|
}
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
if (pressed && switcher->settingsWindowOpened &&
|
|
AdvSceneSwitcher::window) {
|
|
QMetaObject::invokeMethod(AdvSceneSwitcher::window,
|
|
"DeleteMacroSegementHotkey",
|
|
Qt::QueuedConnection);
|
|
}
|
|
}
|
|
|
|
void registerHotkeys()
|
|
{
|
|
switcher->startHotkey = obs_hotkey_register_frontend(
|
|
"startSwitcherHotkey",
|
|
obs_module_text("AdvSceneSwitcher.hotkey.startSwitcherHotkey"),
|
|
startHotkeyFunc, NULL);
|
|
switcher->stopHotkey = obs_hotkey_register_frontend(
|
|
"stopSwitcherHotkey",
|
|
obs_module_text("AdvSceneSwitcher.hotkey.stopSwitcherHotkey"),
|
|
stopHotkeyFunc, NULL);
|
|
switcher->toggleHotkey = obs_hotkey_register_frontend(
|
|
"startStopToggleSwitcherHotkey",
|
|
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(
|
|
"AdvSceneSwitcher.hotkey.removeMacroSegmentHotkey"),
|
|
removeMacroSegmentHotkeyFunc, NULL);
|
|
|
|
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)
|
|
{
|
|
saveHotkey(obj, startHotkey, "startHotkey");
|
|
saveHotkey(obj, stopHotkey, "stopHotkey");
|
|
saveHotkey(obj, toggleHotkey, "toggleHotkey");
|
|
saveHotkey(obj, upMacroSegment, "upMacroSegmentHotkey");
|
|
saveHotkey(obj, downMacroSegment, "downMacroSegmentHotkey");
|
|
saveHotkey(obj, removeMacroSegment, "removeMacroSegmentHotkey");
|
|
}
|
|
|
|
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)
|
|
{
|
|
if (!hotkeysRegistered) {
|
|
registerHotkeys();
|
|
}
|
|
loadHotkey(obj, startHotkey, "startHotkey");
|
|
loadHotkey(obj, stopHotkey, "stopHotkey");
|
|
loadHotkey(obj, toggleHotkey, "toggleHotkey");
|
|
loadHotkey(obj, upMacroSegment, "upMacroSegmentHotkey");
|
|
loadHotkey(obj, downMacroSegment, "downMacroSegmentHotkey");
|
|
loadHotkey(obj, removeMacroSegment, "removeMacroSegmentHotkey");
|
|
}
|