-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
It allows to set the focus window and close windows. Only supported on Windows for now.
- Loading branch information
1 parent
3a1c353
commit bf218e9
Showing
5 changed files
with
336 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
#include "macro-action-window.hpp" | ||
#include "layout-helpers.hpp" | ||
#include "platform-funcs.hpp" | ||
#include "selection-helpers.hpp" | ||
|
||
namespace advss { | ||
|
||
const std::string MacroActionWindow::id = "window"; | ||
|
||
#ifdef _WIN32 | ||
bool MacroActionWindow::_registered = MacroActionFactory::Register( | ||
MacroActionWindow::id, | ||
{MacroActionWindow::Create, MacroActionWindowEdit::Create, | ||
"AdvSceneSwitcher.action.window"}); | ||
#else | ||
bool MacroActionWindow::_registered = false; | ||
#endif // _WIN32 | ||
|
||
const static std::map<MacroActionWindow::Action, std::string> actionTypes = { | ||
{MacroActionWindow::Action::SET_FOCUS_WINDOW, | ||
"AdvSceneSwitcher.action.window.type.setFocusWindow"}, | ||
{MacroActionWindow::Action::MAXIMIZE_WINDOW, | ||
"AdvSceneSwitcher.action.window.type.maximizeWindow"}, | ||
{MacroActionWindow::Action::MINIMIZE_WINDOW, | ||
"AdvSceneSwitcher.action.window.type.minimizeWindow"}, | ||
{MacroActionWindow::Action::CLOSE_WINDOW, | ||
"AdvSceneSwitcher.action.window.type.closeWindow"}, | ||
}; | ||
|
||
#ifdef _WIN32 | ||
void SetFocusWindow(const std::string &); | ||
void MaximizeWindow(const std::string &); | ||
void MinimizeWindow(const std::string &); | ||
void CloseWindow(const std::string &); | ||
#else | ||
void SetFocusWindow(const std::string &) {} | ||
void MaximizeWindow(const std::string &) {} | ||
void MinimizeWindow(const std::string &) {} | ||
void CloseWindow(const std::string &) {} | ||
#endif // _WIN32 | ||
|
||
std::optional<std::string> MacroActionWindow::GetMatchingWindow() const | ||
{ | ||
std::vector<std::string> windowList; | ||
GetWindowList(windowList); | ||
|
||
if (!_regex.Enabled()) { | ||
if (std::find(windowList.begin(), windowList.end(), | ||
std::string(_window)) == windowList.end()) { | ||
return {}; | ||
} | ||
return _window; | ||
} | ||
|
||
for (const auto &window : windowList) { | ||
if (_regex.Matches(window, _window)) { | ||
return window; | ||
} | ||
} | ||
|
||
return {}; | ||
} | ||
|
||
bool MacroActionWindow::PerformAction() | ||
{ | ||
auto window = GetMatchingWindow(); | ||
if (!window) { | ||
return true; | ||
} | ||
|
||
switch (_action) { | ||
case Action::SET_FOCUS_WINDOW: | ||
SetFocusWindow(*window); | ||
break; | ||
case Action::MAXIMIZE_WINDOW: | ||
MaximizeWindow(*window); | ||
break; | ||
case Action::MINIMIZE_WINDOW:; | ||
MinimizeWindow(*window); | ||
break; | ||
case Action::CLOSE_WINDOW: | ||
CloseWindow(*window); | ||
break; | ||
default: | ||
break; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
void MacroActionWindow::LogAction() const | ||
{ | ||
auto window = GetMatchingWindow(); | ||
switch (_action) { | ||
case Action::CLOSE_WINDOW: | ||
blog(LOG_INFO, "close window \"%s\"", | ||
window ? window->c_str() : "nothing matched"); | ||
break; | ||
case Action::SET_FOCUS_WINDOW: | ||
blog(LOG_INFO, "set focus window \"%s\"", | ||
window ? window->c_str() : "nothing matched"); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
bool MacroActionWindow::Save(obs_data_t *obj) const | ||
{ | ||
MacroAction::Save(obj); | ||
obs_data_set_int(obj, "action", static_cast<int>(_action)); | ||
_window.Save(obj, "window"); | ||
_regex.Save(obj, "regex"); | ||
return true; | ||
} | ||
|
||
bool MacroActionWindow::Load(obs_data_t *obj) | ||
{ | ||
MacroAction::Load(obj); | ||
_action = static_cast<Action>(obs_data_get_int(obj, "action")); | ||
_window.Load(obj, "window"); | ||
_regex.Load(obj, "regex"); | ||
return true; | ||
} | ||
|
||
std::string MacroActionWindow::GetShortDesc() const | ||
{ | ||
return _window; | ||
} | ||
|
||
static inline void populateActionSelection(QComboBox *list) | ||
{ | ||
for (const auto &[_, name] : actionTypes) { | ||
list->addItem(obs_module_text(name.c_str())); | ||
} | ||
} | ||
|
||
MacroActionWindowEdit::MacroActionWindowEdit( | ||
QWidget *parent, std::shared_ptr<MacroActionWindow> entryData) | ||
: QWidget(parent), | ||
_actions(new QComboBox()), | ||
_windows(new QComboBox()), | ||
_regex(new RegexConfigWidget(this)) | ||
{ | ||
populateActionSelection(_actions); | ||
|
||
_windows->setEditable(true); | ||
_windows->setMaxVisibleItems(20); | ||
PopulateWindowSelection(_windows); | ||
|
||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this, | ||
SLOT(ActionChanged(int))); | ||
QWidget::connect(_windows, SIGNAL(currentTextChanged(const QString &)), | ||
this, SLOT(WindowChanged(const QString &))); | ||
QWidget::connect(_regex, | ||
SIGNAL(RegexConfigChanged(const RegexConfig &)), this, | ||
SLOT(RegexChanged(const RegexConfig &))); | ||
|
||
auto layout = new QHBoxLayout; | ||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.window.entry"), | ||
layout, | ||
{{"{{actions}}", _actions}, | ||
{"{{windows}}", _windows}, | ||
{"{{regex}}", _regex}}); | ||
setLayout(layout); | ||
|
||
_entryData = entryData; | ||
UpdateEntryData(); | ||
_loading = false; | ||
} | ||
|
||
void MacroActionWindowEdit::UpdateEntryData() | ||
{ | ||
if (!_entryData) { | ||
return; | ||
} | ||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action)); | ||
_windows->setCurrentText(QString::fromStdString(_entryData->_window)); | ||
_regex->SetRegexConfig(_entryData->_regex); | ||
adjustSize(); | ||
updateGeometry(); | ||
} | ||
|
||
void MacroActionWindowEdit::WindowChanged(const QString &text) | ||
{ | ||
if (_loading || !_entryData) { | ||
return; | ||
} | ||
|
||
auto lock = LockContext(); | ||
_entryData->_window = text.toStdString(); | ||
emit HeaderInfoChanged( | ||
QString::fromStdString(_entryData->GetShortDesc())); | ||
} | ||
|
||
void MacroActionWindowEdit::RegexChanged(const RegexConfig ®ex) | ||
{ | ||
if (_loading || !_entryData) { | ||
return; | ||
} | ||
|
||
auto lock = LockContext(); | ||
_entryData->_regex = regex; | ||
adjustSize(); | ||
updateGeometry(); | ||
} | ||
|
||
void MacroActionWindowEdit::ActionChanged(int value) | ||
{ | ||
if (_loading || !_entryData) { | ||
return; | ||
} | ||
|
||
auto lock = LockContext(); | ||
_entryData->_action = static_cast<MacroActionWindow::Action>(value); | ||
} | ||
|
||
} // namespace advss |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#pragma once | ||
#include "macro-action-edit.hpp" | ||
#include "regex-config.hpp" | ||
#include "variable-string.hpp" | ||
|
||
namespace advss { | ||
|
||
class MacroActionWindow : public MacroAction { | ||
public: | ||
MacroActionWindow(Macro *m) : MacroAction(m) {} | ||
bool PerformAction(); | ||
void LogAction() const; | ||
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<MacroAction> Create(Macro *m) | ||
{ | ||
return std::make_shared<MacroActionWindow>(m); | ||
} | ||
|
||
enum class Action { | ||
SET_FOCUS_WINDOW, | ||
MAXIMIZE_WINDOW, | ||
MINIMIZE_WINDOW, | ||
CLOSE_WINDOW, | ||
}; | ||
Action _action = Action::SET_FOCUS_WINDOW; | ||
StringVariable _window; | ||
RegexConfig _regex; | ||
|
||
private: | ||
std::optional<std::string> GetMatchingWindow() const; | ||
|
||
static bool _registered; | ||
static const std::string id; | ||
}; | ||
|
||
class MacroActionWindowEdit : public QWidget { | ||
Q_OBJECT | ||
|
||
public: | ||
MacroActionWindowEdit( | ||
QWidget *parent, | ||
std::shared_ptr<MacroActionWindow> entryData = nullptr); | ||
void UpdateEntryData(); | ||
static QWidget *Create(QWidget *parent, | ||
std::shared_ptr<MacroAction> action) | ||
{ | ||
return new MacroActionWindowEdit( | ||
parent, | ||
std::dynamic_pointer_cast<MacroActionWindow>(action)); | ||
} | ||
|
||
private slots: | ||
void ActionChanged(int value); | ||
void WindowChanged(const QString &text); | ||
void RegexChanged(const RegexConfig &); | ||
signals: | ||
void HeaderInfoChanged(const QString &); | ||
|
||
private: | ||
QComboBox *_actions; | ||
QComboBox *_windows; | ||
RegexConfigWidget *_regex; | ||
|
||
std::shared_ptr<MacroActionWindow> _entryData; | ||
bool _loading = true; | ||
}; | ||
|
||
} // namespace advss |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters