From 52b75a02aeeaf2c23f5af32fededf4e5fb24bade Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 6 Dec 2015 00:43:58 +0100 Subject: api, main: implement global shortcuts for controlling tracking Issue: #252 That involves moving stuff around to get rid of circular dependencies. You need to bind keys to shortcuts again this once. --- gui/options-dialog.cpp | 100 +++++++++++++++++++++++--------------------- gui/options-dialog.hpp | 12 +++--- gui/ui.cpp | 50 +++++++++++++++++++--- gui/ui.h | 10 +++++ opentrack/main-settings.hpp | 26 ++++++++++-- opentrack/shortcuts.h | 27 +----------- opentrack/work.hpp | 7 ++-- 7 files changed, 140 insertions(+), 92 deletions(-) diff --git a/gui/options-dialog.cpp b/gui/options-dialog.cpp index 70d5be62..1edf069d 100644 --- a/gui/options-dialog.cpp +++ b/gui/options-dialog.cpp @@ -12,7 +12,7 @@ #include #include -static QString kopts_to_string(const Shortcuts::key_opts& kopts) +static QString kopts_to_string(const key_opts& kopts) { if (static_cast(kopts.guid) != "") { @@ -29,60 +29,65 @@ static QString kopts_to_string(const Shortcuts::key_opts& kopts) return kopts.keycode; } -OptionsDialog::OptionsDialog() +OptionsDialog::OptionsDialog(main_settings& main, std::function register_global_keys) + : main(main), register_global_keys(register_global_keys) { ui.setupUi(this); connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); - tie_setting(s.s_main.tray_enabled, ui.trayp); + tie_setting(main.tray_enabled, ui.trayp); - tie_setting(s.s_main.center_at_startup, ui.center_at_startup); + tie_setting(main.center_at_startup, ui.center_at_startup); - tie_setting(s.s_main.tcomp_p, ui.tcomp_enable); - tie_setting(s.s_main.tcomp_tz, ui.tcomp_rz); - - tie_setting(s.s_main.a_x.zero, ui.pos_tx); - tie_setting(s.s_main.a_y.zero, ui.pos_ty); - tie_setting(s.s_main.a_z.zero, ui.pos_tz); - tie_setting(s.s_main.a_yaw.zero, ui.pos_rx); - tie_setting(s.s_main.a_pitch.zero, ui.pos_ry); - tie_setting(s.s_main.a_roll.zero, ui.pos_rz); - - tie_setting(s.s_main.a_yaw.invert, ui.invert_yaw); - tie_setting(s.s_main.a_pitch.invert, ui.invert_pitch); - tie_setting(s.s_main.a_roll.invert, ui.invert_roll); - tie_setting(s.s_main.a_x.invert, ui.invert_x); - tie_setting(s.s_main.a_y.invert, ui.invert_y); - tie_setting(s.s_main.a_z.invert, ui.invert_z); - - tie_setting(s.s_main.a_yaw.src, ui.src_yaw); - tie_setting(s.s_main.a_pitch.src, ui.src_pitch); - tie_setting(s.s_main.a_roll.src, ui.src_roll); - tie_setting(s.s_main.a_x.src, ui.src_x); - tie_setting(s.s_main.a_y.src, ui.src_y); - tie_setting(s.s_main.a_z.src, ui.src_z); + tie_setting(main.tcomp_p, ui.tcomp_enable); + tie_setting(main.tcomp_tz, ui.tcomp_rz); + + tie_setting(main.a_x.zero, ui.pos_tx); + tie_setting(main.a_y.zero, ui.pos_ty); + tie_setting(main.a_z.zero, ui.pos_tz); + tie_setting(main.a_yaw.zero, ui.pos_rx); + tie_setting(main.a_pitch.zero, ui.pos_ry); + tie_setting(main.a_roll.zero, ui.pos_rz); + + tie_setting(main.a_yaw.invert, ui.invert_yaw); + tie_setting(main.a_pitch.invert, ui.invert_pitch); + tie_setting(main.a_roll.invert, ui.invert_roll); + tie_setting(main.a_x.invert, ui.invert_x); + tie_setting(main.a_y.invert, ui.invert_y); + tie_setting(main.a_z.invert, ui.invert_z); + + tie_setting(main.a_yaw.src, ui.src_yaw); + tie_setting(main.a_pitch.src, ui.src_pitch); + tie_setting(main.a_roll.src, ui.src_roll); + tie_setting(main.a_x.src, ui.src_x); + tie_setting(main.a_y.src, ui.src_y); + tie_setting(main.a_z.src, ui.src_z); - tie_setting(s.s_main.camera_yaw, ui.camera_yaw); - tie_setting(s.s_main.camera_pitch, ui.camera_pitch); - tie_setting(s.s_main.camera_roll, ui.camera_roll); - - tie_setting(s.s_main.center_method, ui.center_method); - - connect(ui.bind_center, &QPushButton::pressed, [&]() -> void { bind_key(s.center, ui.center_text); }); - connect(ui.bind_zero, &QPushButton::pressed, [&]() -> void { bind_key(s.zero, ui.zero_text); }); - connect(ui.bind_toggle, &QPushButton::pressed, [&]() -> void { bind_key(s.toggle, ui.toggle_text); }); - connect(ui.bind_start, &QPushButton::pressed, [&]() -> void { bind_key(s.start_tracking, ui.start_tracking_text); }); - connect(ui.bind_stop, &QPushButton::pressed, [&]() -> void { bind_key(s.stop_tracking, ui.stop_tracking_text); }); - connect(ui.bind_toggle_tracking, &QPushButton::pressed, [&]() -> void { bind_key(s.toggle_tracking, ui.toggle_tracking_text); }); - - ui.center_text->setText(kopts_to_string(s.center)); - ui.toggle_text->setText(kopts_to_string(s.toggle)); - ui.zero_text->setText(kopts_to_string(s.zero)); + tie_setting(main.camera_yaw, ui.camera_yaw); + tie_setting(main.camera_pitch, ui.camera_pitch); + tie_setting(main.camera_roll, ui.camera_roll); + + tie_setting(main.center_method, ui.center_method); + + connect(ui.bind_center, &QPushButton::pressed, [&]() -> void { bind_key(main.key_center, ui.center_text); }); + connect(ui.bind_zero, &QPushButton::pressed, [&]() -> void { bind_key(main.key_zero, ui.zero_text); }); + connect(ui.bind_toggle, &QPushButton::pressed, [&]() -> void { bind_key(main.key_toggle, ui.toggle_text); }); + connect(ui.bind_start, &QPushButton::pressed, [&]() -> void { bind_key(main.key_start_tracking, ui.start_tracking_text); }); + connect(ui.bind_stop, &QPushButton::pressed, [&]() -> void { bind_key(main.key_stop_tracking, ui.stop_tracking_text); }); + connect(ui.bind_toggle_tracking, &QPushButton::pressed, [&]() -> void { bind_key(main.key_toggle_tracking, ui.toggle_tracking_text); }); + + ui.center_text->setText(kopts_to_string(main.key_center)); + ui.toggle_text->setText(kopts_to_string(main.key_toggle)); + ui.zero_text->setText(kopts_to_string(main.key_zero)); + + ui.start_tracking_text->setText(kopts_to_string(main.key_start_tracking)); + ui.stop_tracking_text->setText(kopts_to_string(main.key_stop_tracking)); + ui.toggle_tracking_text->setText(kopts_to_string(main.key_toggle_tracking)); } -void OptionsDialog::bind_key(Shortcuts::key_opts& kopts, QLabel* label) +void OptionsDialog::bind_key(key_opts& kopts, QLabel* label) { kopts.button = -1; kopts.guid = ""; @@ -111,22 +116,21 @@ void OptionsDialog::bind_key(Shortcuts::key_opts& kopts, QLabel* label) } }); d.exec(); + register_global_keys(); label->setText(kopts_to_string(kopts)); delete k; delete l; } void OptionsDialog::doOK() { - s.b->save(); - s.s_main.b->save(); + main.b->save(); ui.game_detector->save(); this->close(); emit reload(); } void OptionsDialog::doCancel() { - s.b->reload(); - s.s_main.b->reload(); + main.b->reload(); ui.game_detector->revert(); close(); } diff --git a/gui/options-dialog.hpp b/gui/options-dialog.hpp index 308b5b0f..72ae3c30 100644 --- a/gui/options-dialog.hpp +++ b/gui/options-dialog.hpp @@ -1,9 +1,10 @@ #pragma once -#include -#include #include "ui_settings.h" #include "opentrack/shortcuts.h" +#include +#include +#include class OptionsDialog: public QWidget { @@ -11,13 +12,14 @@ class OptionsDialog: public QWidget signals: void reload(); public: - OptionsDialog(); + OptionsDialog(main_settings& main, std::function register_global_keys); private: + main_settings& main; + std::function register_global_keys; Ui::UI_Settings ui; - Shortcuts::settings s; void closeEvent(QCloseEvent *) override { doCancel(); } private slots: void doOK(); void doCancel(); - void bind_key(Shortcuts::key_opts &kopts, QLabel* label); + void bind_key(key_opts &kopts, QLabel* label); }; diff --git a/gui/ui.cpp b/gui/ui.cpp index c3e47912..26fcd9ed 100644 --- a/gui/ui.cpp +++ b/gui/ui.cpp @@ -108,10 +108,40 @@ MainWindow::MainWindow() : "Configuration not saved.", "Can't create configuration directory! Expect major malfunction.", QMessageBox::Ok, QMessageBox::NoButton); - + + connect(this, &MainWindow::emit_start_tracker, + this, [&]() -> void { qDebug() << "start tracker"; startTracker(); }, + Qt::QueuedConnection); + + connect(this, &MainWindow::emit_stop_tracker, + this, [&]() -> void { qDebug() << "stop tracker"; stopTracker(); }, + Qt::QueuedConnection); + + connect(this, &MainWindow::emit_toggle_tracker, + this, [&]() -> void { qDebug() << "toggle tracker"; if (work) stopTracker(); else startTracker(); }, + Qt::QueuedConnection); + + register_shortcuts(); + ui.btnStartTracker->setFocus(); } +void MainWindow::register_shortcuts() +{ + using t_shortcut = std::tuple; + + std::vector keys { + t_shortcut(s.key_start_tracking, [&]() -> void { emit_start_tracker(); }), + t_shortcut(s.key_stop_tracking, [&]() -> void { emit_stop_tracker(); }), + t_shortcut(s.key_toggle_tracking, [&]() -> void { emit_toggle_tracker(); }), + }; + + global_shortcuts.reload(keys); + + if (work) + work->reload_shortcuts(); +} + bool MainWindow::get_new_config_name_from_dialog(QString& ret) { new_file_dialog dlg; @@ -261,6 +291,9 @@ void MainWindow::reload_options() } void MainWindow::startTracker() { + if (work) + return; + // tracker dtor needs run first work = nullptr; @@ -306,7 +339,10 @@ void MainWindow::startTracker() { ui.btnStopTracker->setFocus(); } -void MainWindow::stopTracker( ) { +void MainWindow::stopTracker() { + if (!work) + return; + //ui.game_name->setText("Not connected"); pose_update_timer.stop(); @@ -436,7 +472,7 @@ void MainWindow::showFilterSettings() { } template -bool mk_window(mem* place, Args... params) +bool mk_window(mem* place, Args&&... params) { if (*place && (*place)->isVisible()) { @@ -446,7 +482,7 @@ bool mk_window(mem* place, Args... params) } else { - *place = std::make_shared(params...); + *place = std::make_shared(std::forward(params)...); (*place)->setWindowFlags(Qt::Dialog); (*place)->show(); (*place)->raise(); @@ -455,12 +491,14 @@ bool mk_window(mem* place, Args... params) } void MainWindow::show_options_dialog() { - if (mk_window(&options_widget)) + if (mk_window(&options_widget, + s, + [&]() -> void { register_shortcuts(); })) connect(options_widget.get(), SIGNAL(reload()), this, SLOT(reload_options())); } void MainWindow::showCurveConfiguration() { - mk_window(&mapping_widget, pose, s); + mk_window(&mapping_widget, pose, s); } void MainWindow::exit() { diff --git a/gui/ui.h b/gui/ui.h index b4bab271..12ef1f24 100644 --- a/gui/ui.h +++ b/gui/ui.h @@ -17,6 +17,9 @@ #include #include +#include +#include + #include "ui_main.h" #include "opentrack-compat/options.hpp" @@ -35,6 +38,8 @@ using namespace options; class MainWindow : public QMainWindow, private State { Q_OBJECT + + Shortcuts global_shortcuts; Ui::OpentrackUI ui; mem tray; @@ -76,6 +81,7 @@ class MainWindow : public QMainWindow, private State static bool get_new_config_name_from_dialog(QString &ret); void set_profile(const QString& profile); void maybe_save(); + void register_shortcuts(); private slots: void _save(); void save(); @@ -100,6 +106,10 @@ private slots: void startTracker(); void stopTracker(); void reload_options(); +signals: + void emit_start_tracker(); + void emit_stop_tracker(); + void emit_toggle_tracker(); public: MainWindow(); ~MainWindow(); diff --git a/opentrack/main-settings.hpp b/opentrack/main-settings.hpp index b7b086ad..793c52f7 100644 --- a/opentrack/main-settings.hpp +++ b/opentrack/main-settings.hpp @@ -32,7 +32,18 @@ private: } }; -struct main_settings : opts { +struct key_opts { + value keycode, guid; + value button; + + key_opts(pbundle b, const QString& name) : + keycode(b, QString("keycode-%1").arg(name), ""), + guid(b, QString("guid-%1").arg(name), ""), + button(b, QString("button-%1").arg(name), -1) + {} +}; + +struct main_settings : opts { value tracker_dll, filter_dll, protocol_dll; axis_opts a_x, a_y, a_z, a_yaw, a_pitch, a_roll; value tcomp_p, tcomp_tz; @@ -40,6 +51,8 @@ struct main_settings : opts { value camera_yaw, camera_pitch, camera_roll; value center_at_startup; value center_method; + key_opts key_start_tracking, key_stop_tracking, key_toggle_tracking; + key_opts key_center, key_toggle, key_zero; main_settings() : opts("opentrack-ui"), tracker_dll(b, "tracker-dll", ""), @@ -58,6 +71,13 @@ struct main_settings : opts { camera_pitch(b, "camera-pitch", 0), camera_roll(b, "camera-roll", 0), center_at_startup(b, "center-at-startup", true), - center_method(b, "centering-method", true) - {} + center_method(b, "centering-method", true), + key_start_tracking(b, "start-tracking"), + key_stop_tracking(b, "stop-tracking"), + key_toggle_tracking(b, "toggle-tracking"), + key_center(b, "center"), + key_toggle(b, "toggle"), + key_zero(b, "zero") + { + } }; diff --git a/opentrack/shortcuts.h b/opentrack/shortcuts.h index 4dec7c2c..f8343ad8 100644 --- a/opentrack/shortcuts.h +++ b/opentrack/shortcuts.h @@ -46,31 +46,6 @@ public: #ifdef _WIN32 KeybindingWorker::Token key_token; #endif - - struct key_opts { - value keycode, guid; - value button; - - key_opts(pbundle b, const QString& name) : - keycode(b, QString("keycode-%1").arg(name), ""), - guid(b, QString("guid-%1").arg(name), ""), - button(b, QString("button-%1").arg(name), -1) - {} - }; - - struct settings : opts { - key_opts center, toggle, zero, start_tracking, stop_tracking, toggle_tracking; - main_settings s_main; - settings() : - opts("keyboard-shortcuts"), - center(b, "center"), - toggle(b, "toggle"), - zero(b, "zero"), - start_tracking(b, "start-tracking"), - stop_tracking(b, "stop-tracking"), - toggle_tracking(b, "toggle-tracking") - {} - } s; Shortcuts() : #ifdef _WIN32 @@ -78,7 +53,7 @@ public: #endif {} - void reload(const std::vector > &keys); + void reload(const std::vector > &keys); private: void bind_keyboard_shortcut(K &key, const key_opts& k); #ifdef _WIN32 diff --git a/opentrack/work.hpp b/opentrack/work.hpp index a3c0e014..4188b937 100644 --- a/opentrack/work.hpp +++ b/opentrack/work.hpp @@ -28,7 +28,6 @@ struct Work mem sc; WId handle; using fn = std::function; - using key_opts = Shortcuts::key_opts; using tt = std::tuple; std::vector> keys; @@ -38,9 +37,9 @@ struct Work sc(std::make_shared()), handle(handle), keys { - tt(sc->s.center, [&]() -> void { tracker->center(); }), - tt(sc->s.toggle, [&]() -> void { tracker->toggle_enabled(); }), - tt(sc->s.zero, [&]() -> void { tracker->zero(); }), + tt(s.key_center, [&]() -> void { tracker->center(); }), + tt(s.key_toggle, [&]() -> void { tracker->toggle_enabled(); }), + tt(s.key_zero, [&]() -> void { tracker->zero(); }), } { reload_shortcuts(); -- cgit v1.2.3