From 47d4b25bd0583b1fd65ae885950efd34c9df256b Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 28 Mar 2019 13:40:33 +0100 Subject: cmake: move around variant directories --- cmake/opentrack-variant.cmake | 8 +- opentrack/CMakeLists.txt | 9 + opentrack/lang/nl_NL.ts | 189 ++++ opentrack/lang/ru_RU.ts | 193 ++++ opentrack/lang/stub.ts | 189 ++++ opentrack/lang/zh_CN.ts | 193 ++++ opentrack/main-window.cpp | 920 ++++++++++++++++++ opentrack/main-window.hpp | 145 +++ opentrack/main-window.ui | 1459 ++++++++++++++++++++++++++++ opentrack/main.cpp | 23 + opentrack/new_config.ui | 45 + opentrack/new_file_dialog.cpp | 37 + opentrack/new_file_dialog.h | 25 + opentrack/opentrack.ico | Bin 0 -> 67134 bytes opentrack/resources.rc | 2 + trackmouse/CMakeLists.txt | 9 + trackmouse/images/start.png | Bin 0 -> 1400 bytes trackmouse/images/stop.png | Bin 0 -> 5790 bytes trackmouse/lang/nl_NL.ts | 74 ++ trackmouse/lang/ru_RU.ts | 74 ++ trackmouse/lang/stub.ts | 74 ++ trackmouse/lang/zh_CN.ts | 74 ++ trackmouse/main.cpp | 18 + trackmouse/trackmouse-res.qrc | 6 + trackmouse/trackmouse-settings.cpp | 132 +++ trackmouse/trackmouse.ico | Bin 0 -> 67134 bytes trackmouse/trackmouse.rc | 2 + trackmouse/window.cpp | 388 ++++++++ trackmouse/window.hpp | 94 ++ trackmouse/window.ui | 458 +++++++++ variant/default/CMakeLists.txt | 9 - variant/default/_variant.cmake | 1 + variant/default/lang/nl_NL.ts | 189 ---- variant/default/lang/ru_RU.ts | 193 ---- variant/default/lang/stub.ts | 189 ---- variant/default/lang/zh_CN.ts | 193 ---- variant/default/main-window.cpp | 920 ------------------ variant/default/main-window.hpp | 145 --- variant/default/main-window.ui | 1459 ---------------------------- variant/default/main.cpp | 23 - variant/default/new_config.ui | 45 - variant/default/new_file_dialog.cpp | 37 - variant/default/new_file_dialog.h | 25 - variant/default/opentrack.ico | Bin 67134 -> 0 bytes variant/default/resources.rc | 2 - variant/trackmouse/CMakeLists.txt | 9 - variant/trackmouse/_variant.cmake | 1 + variant/trackmouse/images/start.png | Bin 1400 -> 0 bytes variant/trackmouse/images/stop.png | Bin 5790 -> 0 bytes variant/trackmouse/lang/nl_NL.ts | 74 -- variant/trackmouse/lang/ru_RU.ts | 74 -- variant/trackmouse/lang/stub.ts | 74 -- variant/trackmouse/lang/zh_CN.ts | 74 -- variant/trackmouse/main.cpp | 18 - variant/trackmouse/trackmouse-res.qrc | 6 - variant/trackmouse/trackmouse-settings.cpp | 132 --- variant/trackmouse/trackmouse.ico | Bin 67134 -> 0 bytes variant/trackmouse/trackmouse.rc | 2 - variant/trackmouse/window.cpp | 388 -------- variant/trackmouse/window.hpp | 94 -- variant/trackmouse/window.ui | 458 --------- 61 files changed, 4837 insertions(+), 4837 deletions(-) create mode 100644 opentrack/CMakeLists.txt create mode 100644 opentrack/lang/nl_NL.ts create mode 100644 opentrack/lang/ru_RU.ts create mode 100644 opentrack/lang/stub.ts create mode 100644 opentrack/lang/zh_CN.ts create mode 100644 opentrack/main-window.cpp create mode 100644 opentrack/main-window.hpp create mode 100644 opentrack/main-window.ui create mode 100644 opentrack/main.cpp create mode 100644 opentrack/new_config.ui create mode 100644 opentrack/new_file_dialog.cpp create mode 100644 opentrack/new_file_dialog.h create mode 100644 opentrack/opentrack.ico create mode 100644 opentrack/resources.rc create mode 100644 trackmouse/CMakeLists.txt create mode 100644 trackmouse/images/start.png create mode 100644 trackmouse/images/stop.png create mode 100644 trackmouse/lang/nl_NL.ts create mode 100644 trackmouse/lang/ru_RU.ts create mode 100644 trackmouse/lang/stub.ts create mode 100644 trackmouse/lang/zh_CN.ts create mode 100644 trackmouse/main.cpp create mode 100644 trackmouse/trackmouse-res.qrc create mode 100644 trackmouse/trackmouse-settings.cpp create mode 100644 trackmouse/trackmouse.ico create mode 100644 trackmouse/trackmouse.rc create mode 100644 trackmouse/window.cpp create mode 100644 trackmouse/window.hpp create mode 100644 trackmouse/window.ui delete mode 100644 variant/default/CMakeLists.txt delete mode 100644 variant/default/lang/nl_NL.ts delete mode 100644 variant/default/lang/ru_RU.ts delete mode 100644 variant/default/lang/stub.ts delete mode 100644 variant/default/lang/zh_CN.ts delete mode 100644 variant/default/main-window.cpp delete mode 100644 variant/default/main-window.hpp delete mode 100644 variant/default/main-window.ui delete mode 100644 variant/default/main.cpp delete mode 100644 variant/default/new_config.ui delete mode 100644 variant/default/new_file_dialog.cpp delete mode 100644 variant/default/new_file_dialog.h delete mode 100644 variant/default/opentrack.ico delete mode 100644 variant/default/resources.rc delete mode 100644 variant/trackmouse/CMakeLists.txt delete mode 100644 variant/trackmouse/images/start.png delete mode 100644 variant/trackmouse/images/stop.png delete mode 100644 variant/trackmouse/lang/nl_NL.ts delete mode 100644 variant/trackmouse/lang/ru_RU.ts delete mode 100644 variant/trackmouse/lang/stub.ts delete mode 100644 variant/trackmouse/lang/zh_CN.ts delete mode 100644 variant/trackmouse/main.cpp delete mode 100644 variant/trackmouse/trackmouse-res.qrc delete mode 100644 variant/trackmouse/trackmouse-settings.cpp delete mode 100644 variant/trackmouse/trackmouse.ico delete mode 100644 variant/trackmouse/trackmouse.rc delete mode 100644 variant/trackmouse/window.cpp delete mode 100644 variant/trackmouse/window.hpp delete mode 100644 variant/trackmouse/window.ui diff --git a/cmake/opentrack-variant.cmake b/cmake/opentrack-variant.cmake index 3ea01eaa..2cf39fcd 100644 --- a/cmake/opentrack-variant.cmake +++ b/cmake/opentrack-variant.cmake @@ -7,17 +7,17 @@ function(otr_dist_select_variant) foreach(k ${variants}) get_filename_component(name "${k}" NAME) - if(EXISTS "${k}/_variant.cmake" AND EXISTS "${k}/CMakeLists.txt") + if(EXISTS "${k}/_variant.cmake") list(APPEND variant-list "${name}") else() - message(FATAL_ERROR "Stray item in variant dir '${name}'") + message(FATAL_ERROR "stray variant dir '${name}'") endif() endforeach() set(opentrack_variant "default" CACHE STRING "") set(dir "${CMAKE_SOURCE_DIR}/variant/${opentrack_variant}") - if(NOT EXISTS "${dir}/_variant.cmake" OR NOT EXISTS "${dir}/CMakeLists.txt") + if(NOT EXISTS "${dir}/_variant.cmake") set(opentrack_variant "default" CACHE STRING "" FORCE) set(dir "${CMAKE_SOURCE_DIR}/variant/${opentrack_variant}") endif() @@ -26,6 +26,4 @@ function(otr_dist_select_variant) include("${dir}/_variant.cmake") otr_init_variant() - - add_subdirectory("${dir}") endfunction() diff --git a/opentrack/CMakeLists.txt b/opentrack/CMakeLists.txt new file mode 100644 index 00000000..a8829aa5 --- /dev/null +++ b/opentrack/CMakeLists.txt @@ -0,0 +1,9 @@ +otr_module(executable EXECUTABLE BIN) + +set_target_properties(opentrack-executable PROPERTIES + SUFFIX "${opentrack-binary-suffix}" + OUTPUT_NAME "opentrack" + PREFIX "" +) + +target_link_libraries(${self} opentrack-user-interface opentrack-version) diff --git a/opentrack/lang/nl_NL.ts b/opentrack/lang/nl_NL.ts new file mode 100644 index 00000000..7a465820 --- /dev/null +++ b/opentrack/lang/nl_NL.ts @@ -0,0 +1,189 @@ + + + + + UI_new_config + + Config filename + + + + New file name: + + + + + main_window + + Raw tracker data + + + + Z + + + + Pitch + + + + Y + + + + X + + + + Roll + + + + Yaw + + + + Game data + + + + Profile + + + + Options + + + + Mapping + + + + Tracking + + + + Start + + + + Stop + + + + Input + + + + 🔨 + + + + Output + + + + Filter + + + + Running as root is bad + + + + Do not run as root. Set correct device node permissions. + + + + Running as root is bad, seriously + + + + Do not run as root. I'll keep whining at every startup. + + + + Create new empty config + + + + Create new copied config + + + + Open configuration directory + + + + opentrack + + + + (debug) + + + + Show the Octopus + + + + Hide the Octopus + + + + Tracker settings + + + + Filter settings + + + + Protocol settings + + + + Mappings + + + + Exit + + + + The Octopus is sad + + + + Check permissions for your .ini directory: + +"%1"%2 + +Exiting now. + + + + :: + + + + Be annoyed, comprehensively. + + + + Don't run as root to remove these annoying messages. + + + + + new_file_dialog + + File exists + + + + This file already exists. Pick another name. + + + + diff --git a/opentrack/lang/ru_RU.ts b/opentrack/lang/ru_RU.ts new file mode 100644 index 00000000..684a8212 --- /dev/null +++ b/opentrack/lang/ru_RU.ts @@ -0,0 +1,193 @@ + + + + + UI_new_config + + Config filename + Создание профиля + + + New file name: + Новое имя профиля: + + + + main_window + + Create new empty config + Создать новый пустой профиль + + + Create new copied config + Создать новый профиль на основе текущего + + + Open configuration directory + Открыть каталог с профилями + + + opentrack + + + + (debug) + + + + Show the Octopus + Показать осьминожка + + + Hide the Octopus + Спрятать осьминожка + + + Tracker settings + Настройка источника данных + + + Filter settings + Настройка фильтрации/сглаживания + + + Protocol settings + Настройка выходного интерфейса + + + Mappings + Настройка кривых + + + Options + Настройки + + + Exit + Закрыть + + + The Octopus is sad + Осьминожек опечален + + + Check permissions for your .ini directory: + +"%1"%2 + +Exiting now. + Проверьте права доступа на Вашу .ini папку: + +"%1"%2 + +Закрытие программы. + + + :: + :: + + + Raw tracker data + Исходные данные + + + Z + Z + + + Pitch + Pitch + + + Y + Y + + + X + X + + + Roll + Roll + + + Yaw + Yaw + + + Game data + Игровые данные + + + Profile + Профиль + + + Mapping + Кривые + + + Tracking + Статус работы трекера + + + Start + Запустить + + + Stop + Остановить + + + Input + Источник данных + + + 🔨 + + + + Output + Выходной интерфейс + + + Filter + Фильтрация/сглаживание + + + Running as root is bad + + + + Do not run as root. Set correct device node permissions. + + + + Running as root is bad, seriously + + + + Do not run as root. I'll keep whining at every startup. + + + + Be annoyed, comprehensively. + + + + Don't run as root to remove these annoying messages. + + + + + new_file_dialog + + File exists + Файл создан + + + This file already exists. Pick another name. + Данный файл уже создан. Пожалуйста выберите другое имя. + + + diff --git a/opentrack/lang/stub.ts b/opentrack/lang/stub.ts new file mode 100644 index 00000000..04555dd0 --- /dev/null +++ b/opentrack/lang/stub.ts @@ -0,0 +1,189 @@ + + + + + UI_new_config + + Config filename + + + + New file name: + + + + + main_window + + Raw tracker data + + + + Z + + + + Pitch + + + + Y + + + + X + + + + Roll + + + + Yaw + + + + Game data + + + + Profile + + + + Options + + + + Mapping + + + + Tracking + + + + Start + + + + Stop + + + + Input + + + + 🔨 + + + + Output + + + + Filter + + + + Running as root is bad + + + + Do not run as root. Set correct device node permissions. + + + + Running as root is bad, seriously + + + + Do not run as root. I'll keep whining at every startup. + + + + Create new empty config + + + + Create new copied config + + + + Open configuration directory + + + + opentrack + + + + (debug) + + + + Show the Octopus + + + + Hide the Octopus + + + + Tracker settings + + + + Filter settings + + + + Protocol settings + + + + Mappings + + + + Exit + + + + The Octopus is sad + + + + Check permissions for your .ini directory: + +"%1"%2 + +Exiting now. + + + + :: + + + + Be annoyed, comprehensively. + + + + Don't run as root to remove these annoying messages. + + + + + new_file_dialog + + File exists + + + + This file already exists. Pick another name. + + + + diff --git a/opentrack/lang/zh_CN.ts b/opentrack/lang/zh_CN.ts new file mode 100644 index 00000000..15609d70 --- /dev/null +++ b/opentrack/lang/zh_CN.ts @@ -0,0 +1,193 @@ + + + + + UI_new_config + + Config filename + 配置文件名字: + + + New file name: + 新文件名字: + + + + main_window + + Raw tracker data + 跟踪器原始数据 + + + Z + + + + Pitch + 仰俯 + + + Y + + + + X + + + + Roll + 横滚 + + + Yaw + 偏航 + + + Game data + 游戏得到的数据 + + + Profile + 配置文件 + + + Options + 选项 + + + Mapping + 映射 + + + Tracking + 跟踪 + + + Start + 开始 + + + Stop + 停止 + + + Input + 输入 + + + 🔨 + + + + Output + 输出 + + + Filter + 过滤器 + + + Running as root is bad + 以管理员运行不是什么好主意 + + + Do not run as root. Set correct device node permissions. + 请不要以管理员运行。可以设置何时的设备访问权限来解决。 + + + Running as root is bad, seriously + 再说一遍,以管理员运行不是什么好主意 + + + Do not run as root. I'll keep whining at every startup. + 请不要以管理员运行。这话每次启动我都会强调一遍。 + + + Don't run as root to remove these annoying messages. + 以管理员运行真的非常不好 + + + Be annoyed, comprehensively. + 请不要以管理员运行。烦了吧?赶紧动作起来 + + + Create new empty config + 新建一个空的配置 + + + Create new copied config + 新建一个复制配置 + + + Open configuration directory + 打开配置目录 + + + opentrack + + + + (debug) + (调试) + + + Show the Octopus + 显示八爪鱼 + + + Hide the Octopus + 隐藏八爪鱼 + + + Tracker settings + 跟踪器设置 + + + Filter settings + 过滤器设置 + + + Protocol settings + 协议设置 + + + Mappings + 影射 + + + Exit + 退出 + + + The Octopus is sad + 八爪鱼不开心了 + + + Check permissions for your .ini directory: + +"%1"%2 + +Exiting now. + 检查一下你的 .ini 目录权限: + +"%1"%2 + +退出先. + + + :: + + + + + new_file_dialog + + File exists + 文件已经存在 + + + This file already exists. Pick another name. + 文件重名了,换个其他名字 + + + diff --git a/opentrack/main-window.cpp b/opentrack/main-window.cpp new file mode 100644 index 00000000..b90aa3bd --- /dev/null +++ b/opentrack/main-window.cpp @@ -0,0 +1,920 @@ +/* Copyright (c) 2013-2016, Stanislaw Halik + + * Permission to use, copy, modify, and/or distribute this + * software for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission + * notice appear in all copies. + */ + +#include "main-window.hpp" +#include "logic/pipeline.hpp" +#include "options/options.hpp" +#include "new_file_dialog.h" +#include "migration/migration.hpp" +#include "compat/check-visible.hpp" +#include "compat/sleep.hpp" +#include "compat/macros.hpp" +#include "compat/library-path.hpp" +#include "compat/math.hpp" +#include "compat/sysexits.hpp" + +#include +#include + +#include +#include +#include + +extern "C" const char* const opentrack_version; + +using namespace options::globals; +using namespace options; + +main_window::main_window() : State(OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH) +{ + ui.setupUi(this); + +#if !defined _WIN32 && !defined __APPLE__ + annoy_if_root(); +#endif + + init_profiles(); + init_buttons(); + init_tray_menu(); + init_dylibs(); + init_shortcuts(); + + setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | windowFlags()); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + adjustSize(); + + if (!start_in_tray()) + { + setVisible(true); + show(); + } + else + setVisible(false); + + connect(&pose_update_timer, &QTimer::timeout, + this, &main_window::show_pose, Qt::DirectConnection); + connect(&det_timer, &QTimer::timeout, + this, &main_window::maybe_start_profile_from_executable); + det_timer.start(1000); +} + +void main_window::init_shortcuts() +{ + register_shortcuts(); + + // ctrl+q exits + connect(&kbd_quit, &QShortcut::activated, this, [this]() { main_window::exit(EXIT_SUCCESS); }, Qt::DirectConnection); + kbd_quit.setEnabled(true); +} + +void main_window::init_dylibs() +{ + using dylib_ptr = Modules::dylib_ptr; + using dylib_list = Modules::dylib_list; + + modules.filters().insert(modules.filters().begin(), + std::make_shared("", dylib_type::Filter)); + + for (dylib_ptr& x : modules.trackers()) + ui.iconcomboTrackerSource->addItem(x->icon, x->name, x->module_name); + + for (dylib_ptr& x : modules.protocols()) + ui.iconcomboProtocol->addItem(x->icon, x->name, x->module_name); + + for (dylib_ptr& x : modules.filters()) + ui.iconcomboFilter->addItem(x->icon, x->name, x->module_name); + + connect(ui.iconcomboTrackerSource, &QComboBox::currentTextChanged, + this, [&](const QString&) { pTrackerDialog = nullptr; }); + + connect(ui.iconcomboProtocol, &QComboBox::currentTextChanged, + this, [&](const QString&) { pProtocolDialog = nullptr; }); + + connect(ui.iconcomboFilter, &QComboBox::currentTextChanged, + this, [&](const QString&) { pFilterDialog = nullptr; }); + + connect(&m.tracker_dll, value_::value_changed(), + this, &main_window::save_modules, + Qt::DirectConnection); + + connect(&m.protocol_dll, value_::value_changed(), + this, &main_window::save_modules, + Qt::DirectConnection); + + connect(&m.filter_dll, value_::value_changed(), + this, &main_window::save_modules, + Qt::DirectConnection); + + { + struct list { + dylib_list& libs; + QComboBox* input; + value& place; + }; + + list types[] { + { modules.trackers(), ui.iconcomboTrackerSource, m.tracker_dll }, + { modules.protocols(), ui.iconcomboProtocol, m.protocol_dll }, + { modules.filters(), ui.iconcomboFilter, m.filter_dll }, + }; + + for (list& type : types) + { + list t = type; + tie_setting(t.place, t.input, + [t](const QString& name) { + auto [ptr, idx] = module_by_name(name, t.libs); + return idx; + }, + [t](int, const QVariant& userdata) { + auto [ptr, idx] = module_by_name(userdata.toString(), t.libs); + if (ptr) + return ptr->module_name; + else + return QString(); + }); + } + } +} + +void main_window::init_profiles() +{ + refresh_profile_list(); + // implicitly created by `ini_directory()' + if (ini_directory().isEmpty() || !QDir(ini_directory()).isReadable()) + die_on_profile_not_writable(); + + set_profile(ini_filename()); + + // profile menu + profile_menu.addAction(tr("Create new empty config"), this, &main_window::create_empty_profile); + profile_menu.addAction(tr("Create new copied config"), this, &main_window::create_copied_profile); + profile_menu.addAction(tr("Open configuration directory"), this, &main_window::open_profile_directory); + ui.profile_button->setMenu(&profile_menu); + + connect(&profile_list_timer, &QTimer::timeout, this, &main_window::refresh_profile_list); + profile_list_timer.start(1000 * 5); + + connect(ui.iconcomboProfile, &QComboBox::currentTextChanged, + this, [this](const QString& x) { main_window::set_profile(x); }); +} + +void main_window::init_tray_menu() +{ + tray_menu.clear(); + + QString display_name(opentrack_version); + if (display_name.startsWith("opentrack-")) + display_name = tr("opentrack") + " " + display_name.mid(sizeof("opentrack-") - 1); + if (display_name.endsWith("-DEBUG")) + display_name.replace(display_name.size() - int(sizeof("DEBUG")), display_name.size(), tr(" (debug)")); + + menu_action_header.setEnabled(false); + menu_action_header.setText(display_name); + menu_action_header.setIcon(QIcon(":/images/opentrack.png")); + tray_menu.addAction(&menu_action_header); + + menu_action_show.setIconVisibleInMenu(true); + menu_action_show.setText(isHidden() ? tr("Show the Octopus") : tr("Hide the Octopus")); + menu_action_show.setIcon(QIcon(":/images/opentrack.png")); + QObject::connect(&menu_action_show, &QAction::triggered, this, [&] { toggle_restore_from_tray(QSystemTrayIcon::Trigger); }); + tray_menu.addAction(&menu_action_show); + + tray_menu.addSeparator(); + + menu_action_tracker.setText(tr("Tracker settings")); + menu_action_tracker.setIcon(QIcon(":/images/tools.png")); + QObject::connect(&menu_action_tracker, &QAction::triggered, this, &main_window::show_tracker_settings); + tray_menu.addAction(&menu_action_tracker); + + menu_action_filter.setText(tr("Filter settings")); + menu_action_filter.setIcon(QIcon(":/images/filter-16.png")); + QObject::connect(&menu_action_filter, &QAction::triggered, this, &main_window::show_filter_settings); + tray_menu.addAction(&menu_action_filter); + + menu_action_proto.setText(tr("Protocol settings")); + menu_action_proto.setIcon(QIcon(":/images/settings16.png")); + QObject::connect(&menu_action_proto, &QAction::triggered, this, &main_window::show_proto_settings); + tray_menu.addAction(&menu_action_proto); + + tray_menu.addSeparator(); + + menu_action_mappings.setIcon(QIcon(":/images/curves.png")); + menu_action_mappings.setText(tr("Mappings")); + QObject::connect(&menu_action_mappings, &QAction::triggered, this, &main_window::show_mapping_window); + tray_menu.addAction(&menu_action_mappings); + + menu_action_options.setIcon(QIcon(":/images/tools.png")); + menu_action_options.setText(tr("Options")); + QObject::connect(&menu_action_options, &QAction::triggered, this, &main_window::show_options_dialog); + tray_menu.addAction(&menu_action_options); + + tray_menu.addSeparator(); + + menu_action_exit.setText(tr("Exit")); + QObject::connect(&menu_action_exit, &QAction::triggered, this, &main_window::exit); + tray_menu.addAction(&menu_action_exit); + + connect(&s.tray_enabled, value_::value_changed(), + this, &main_window::ensure_tray); + + ensure_tray(); +} + +void main_window::init_buttons() +{ + update_button_state(false, false); + connect(ui.btnEditCurves, &QPushButton::clicked, this, &main_window::show_mapping_window); + connect(ui.btnShortcuts, &QPushButton::clicked, this, &main_window::show_options_dialog); + connect(ui.btnShowEngineControls, &QPushButton::clicked, this, &main_window::show_tracker_settings); + connect(ui.btnShowServerControls, &QPushButton::clicked, this, &main_window::show_proto_settings); + connect(ui.btnShowFilterControls, &QPushButton::clicked, this, &main_window::show_filter_settings); + connect(ui.btnStartTracker, &QPushButton::clicked, this, &main_window::start_tracker_); + connect(ui.btnStopTracker, &QPushButton::clicked, this, &main_window::stop_tracker_); +} + +void main_window::register_shortcuts() +{ + global_shortcuts.reload({ + { s.key_start_tracking1, [this](bool) { start_tracker(); }, true }, + { s.key_start_tracking2, [this](bool) { start_tracker(); }, true }, + + { s.key_stop_tracking1, [this](bool) { stop_tracker(); }, true }, + { s.key_stop_tracking2, [this](bool) { stop_tracker(); }, true }, + + { s.key_toggle_tracking1, [this](bool) { toggle_tracker(); }, true }, + { s.key_toggle_tracking2, [this](bool) { toggle_tracker(); }, true }, + + { s.key_restart_tracking1, [this](bool) { restart_tracker(); }, true }, + { s.key_restart_tracking2, [this](bool) { restart_tracker(); }, true }, + }); + + if (work) + work->reload_shortcuts(); +} + +void main_window::die_on_profile_not_writable() +{ + stop_tracker_(); + + static const QString pad(16, QChar(' ')); + + QMessageBox::critical(this, + tr("The Octopus is sad"), + tr("Check permissions for your .ini directory:\n\n\"%1\"%2\n\nExiting now.").arg(ini_directory(), pad), + QMessageBox::Close, QMessageBox::NoButton); + + exit(EX_OSFILE); +} + +bool main_window::profile_name_from_dialog(QString& ret) +{ + new_file_dialog dlg; + dlg.exec(); + return dlg.is_ok(ret); +} + +main_window::~main_window() +{ + // stupid ps3 eye has LED issues + if (work && ui.video_frame->layout()) + { + hide(); + stop_tracker_(); + close(); + + constexpr int inc = 25, max = 1000; + + for (int k = 0; k < max; k += inc) + { + QEventLoop ev; + ev.processEvents(); + portable::sleep(inc); + } + } + + exit(); +} + +void main_window::save_modules() +{ + m.b->save(); +} + +void main_window::create_empty_profile() +{ + QString name; + if (profile_name_from_dialog(name)) + { + QFile(ini_combine(name)).open(QFile::ReadWrite); + refresh_profile_list(); + + if (profile_list.contains(name)) + { + QSignalBlocker q(ui.iconcomboProfile); + + set_profile(name, false); + mark_profile_as_not_needing_migration(); + } + } +} + +void main_window::create_copied_profile() +{ + const QString cur = ini_pathname(); + QString name; + if (!cur.isEmpty() && profile_name_from_dialog(name)) + { + const QString new_name = ini_combine(name); + (void) QFile::remove(new_name); + QFile::copy(cur, new_name); + + refresh_profile_list(); + + if (profile_list.contains(name)) + { + QSignalBlocker q(ui.iconcomboProfile); + + set_profile(name, false); + mark_profile_as_not_needing_migration(); + } + } + +} + +void main_window::open_profile_directory() +{ + QDesktopServices::openUrl("file:///" + QDir::toNativeSeparators(ini_directory())); +} + +void main_window::refresh_profile_list() +{ + if (work) + return; + + QStringList list = ini_list(); + QString current = ini_filename(); + + if (list == profile_list) + return; + + if (!list.contains(current)) + current = OPENTRACK_DEFAULT_PROFILE; + + profile_list = list; + + static const QIcon icon(":/images/settings16.png"); + + QSignalBlocker l(ui.iconcomboProfile); + + ui.iconcomboProfile->clear(); + ui.iconcomboProfile->addItems(list); + + for (int i = 0; i < list.size(); i++) + ui.iconcomboProfile->setItemIcon(i, icon); + + ui.iconcomboProfile->setCurrentText(current); +} + + + +void main_window::update_button_state(bool running, bool inertialp) +{ + bool not_running = !running; + ui.iconcomboProfile->setEnabled(not_running); + ui.btnStartTracker->setEnabled(not_running); + ui.btnStopTracker->setEnabled(running); + ui.iconcomboProtocol->setEnabled(not_running); + ui.iconcomboFilter->setEnabled(not_running); + ui.iconcomboTrackerSource->setEnabled(not_running); + ui.profile_button->setEnabled(not_running); + ui.video_frame_label->setVisible(not_running || inertialp); + if(not_running) + { + ui.video_frame_label->setPixmap(QPixmap(":/images/tracking-not-started.png")); + } + else { + ui.video_frame_label->setPixmap(QPixmap(":/images/no-feed.png")); + } +} + +void main_window::start_tracker_() +{ + if (work) + return; + + work = std::make_shared(pose, ev, ui.video_frame, current_tracker(), current_protocol(), current_filter()); + + if (!work->is_ok()) + { + work = nullptr; + return; + } + + { + double p[6] = {0,0,0, 0,0,0}; + show_pose_(p, p); + } + + if (pTrackerDialog) + pTrackerDialog->register_tracker(work->libs.pTracker.get()); + + if (pFilterDialog) + pFilterDialog->register_filter(work->libs.pFilter.get()); + + if (pProtocolDialog) + pProtocolDialog->register_protocol(work->libs.pProtocol.get()); + + pose_update_timer.start(50); + + // NB check valid since SelectedLibraries ctor called + // trackers take care of layout state updates + const bool is_inertial = ui.video_frame->layout() == nullptr; + update_button_state(true, is_inertial); + + ui.btnStopTracker->setFocus(); +} + +void main_window::stop_tracker_() +{ + if (!work) + return; + + force_is_visible(true); + with_tracker_teardown sentinel; + + pose_update_timer.stop(); + ui.pose_display->present(0,0,0, 0,0,0); + + if (pTrackerDialog) + pTrackerDialog->unregister_tracker(); + + if (pProtocolDialog) + pProtocolDialog->unregister_protocol(); + + if (pFilterDialog) + pFilterDialog->unregister_filter(); + + work = nullptr; + + { + double p[6] {}; + show_pose_(p, p); + } + + update_button_state(false, false); + set_title(); + ui.btnStartTracker->setFocus(); +} + +void main_window::show_pose_(const double* mapped, const double* raw) +{ + ui.pose_display->present(mapped[Yaw], mapped[Pitch], -mapped[Roll], + mapped[TX], mapped[TY], mapped[TZ]); + + QLCDNumber* raw_[] = { + ui.raw_x, ui.raw_y, ui.raw_z, + ui.raw_yaw, ui.raw_pitch, ui.raw_roll, + }; + + QLCDNumber* mapped_[] = { + ui.pose_x, ui.pose_y, ui.pose_z, + ui.pose_yaw, ui.pose_pitch, ui.pose_roll, + }; + + for (int k = 0; k < 6; k++) + { + raw_[k]->display(iround(raw[k])); + mapped_[k]->display(iround(mapped[k])); + } + + QString game_title; + if (work && work->libs.pProtocol) + game_title = work->libs.pProtocol->game_name(); + set_title(game_title); +} + +void main_window::set_title(const QString& game_title) +{ + static const QString version{opentrack_version}; + static const QString sep { tr(" :: ") }; + static const QString pat1{ version + sep + "%1" + sep + "%2" }; + static const QString pat2{ version + sep + "%1" }; + + const QString current = ini_filename(); + + if (game_title.isEmpty()) + setWindowTitle(pat2.arg(current)); + else + setWindowTitle(pat1.arg(current, game_title)); +} + +void main_window::show_pose() +{ + set_is_visible(*this); + + if (mapping_widget) + mapping_widget->refresh_tab(); + + if (!check_is_visible()) + return; + + double mapped[6], raw[6]; + + work->pipeline_.raw_and_mapped_pose(mapped, raw); + + show_pose_(mapped, raw); +} + +static void show_window(QWidget& d, bool fresh) +{ + if (fresh) + { + d.setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | d.windowFlags()); + d.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + d.show(); + d.adjustSize(); + d.raise(); + } + else + { + d.show(); + d.raise(); + } +} + +template +static bool mk_window_common(std::unique_ptr& d, F&& fun) +{ + bool fresh = false; + + if (!d) + d = fun(), fresh = !!d; + + if (d) + show_window(*d, fresh); + + return fresh; +} + +template +static bool mk_window(std::unique_ptr& place, Args&&... params) +{ + return mk_window_common(place, [&] { + return std::make_unique(params...); + }); +} + +template +static bool mk_dialog(std::unique_ptr& place, const std::shared_ptr& lib) +{ + using u = std::unique_ptr; + + return mk_window_common(place, [&] { + if (lib && lib->Dialog) + return u{ (t*)lib->Dialog() }; + else + return u{}; + }); +} + +void main_window::show_tracker_settings() +{ + if (mk_dialog(pTrackerDialog, current_tracker()) && work && work->libs.pTracker) + pTrackerDialog->register_tracker(work->libs.pTracker.get()); + if (pTrackerDialog) + QObject::connect(pTrackerDialog.get(), &ITrackerDialog::closing, + this, [this] { pTrackerDialog = nullptr; }); +} + +void main_window::show_proto_settings() +{ + if (mk_dialog(pProtocolDialog, current_protocol()) && work && work->libs.pProtocol) + pProtocolDialog->register_protocol(work->libs.pProtocol.get()); + if (pProtocolDialog) + QObject::connect(pProtocolDialog.get(), &IProtocolDialog::closing, + this, [this] { pProtocolDialog = nullptr; }); +} + +void main_window::show_filter_settings() +{ + if (mk_dialog(pFilterDialog, current_filter()) && work && work->libs.pFilter) + pFilterDialog->register_filter(work->libs.pFilter.get()); + if (pFilterDialog) + QObject::connect(pFilterDialog.get(), &IFilterDialog::closing, + this, [this] { pFilterDialog = nullptr; }); +} + +void main_window::show_options_dialog() +{ + if (mk_window(options_widget, [&](bool flag) { set_keys_enabled(!flag); })) + { + // XXX this should logically connect to a bundle + // also doesn't work when switching profiles with options dialog open + // move shortcuts to a separate bundle and add a migration -sh 20180218 + connect(options_widget.get(), &options_dialog::closing, + this, &main_window::register_shortcuts); + } +} + +void main_window::show_mapping_window() +{ + mk_window(mapping_widget, pose); +} + +void main_window::exit(int status) +{ + // don't use std::call_once here, leads to freeze in Microsoft's CRT + // this function never needs reentrancy anyway + + // this is probably harmless, but better safe than sorry + if (exiting_already) + return; + exiting_already = true; + + qDebug() << "opentrack: exiting"; + + if (tray) + tray->hide(); + tray = nullptr; + + //close(); + QApplication::setQuitOnLastWindowClosed(true); + QApplication::exit(status); +} + +void main_window::set_profile(const QString& new_name_, bool migrate) +{ + QSignalBlocker b(ui.iconcomboProfile); + + QString new_name = new_name_; + + if (!profile_list.contains(new_name)) + { + new_name = OPENTRACK_DEFAULT_PROFILE; + if (!profile_list.contains(new_name)) + migrate = false; + } + + const bool status = new_name != ini_filename(); + + if (status) + set_profile_in_registry(new_name); + + using bundler = options::detail::bundler; + + bundler::reload_no_notify(); + + if (migrate) + // migrations are for config layout changes and other user-visible + // incompatibilities in future versions + run_migrations(); + else + mark_profile_as_not_needing_migration(); + + bundler::notify(); + + set_title(); + + if (status) + ui.iconcomboProfile->setCurrentText(new_name); +} + +void main_window::ensure_tray() +{ + if (!QSystemTrayIcon::isSystemTrayAvailable()) + { + QApplication::setQuitOnLastWindowClosed(true); + return; + } + + if (s.tray_enabled) + { + if (!tray) + { + tray = std::make_unique(this); + tray->setIcon(QIcon(":/images/opentrack.png")); + tray->setContextMenu(&tray_menu); + tray->show(); + + connect(tray.get(), + &QSystemTrayIcon::activated, + this, + &main_window::toggle_restore_from_tray); + } + + QApplication::setQuitOnLastWindowClosed(false); + } + else + { + if (!isVisible()) + { + show(); + setVisible(true); + + raise(); // for OSX + activateWindow(); // for Windows + } + + if (tray) + tray->hide(); + tray = nullptr; + + QApplication::setQuitOnLastWindowClosed(true); + } +} + +void main_window::toggle_restore_from_tray(QSystemTrayIcon::ActivationReason e) +{ + switch (e) + { + // if we enable double click also then it causes + // toggle back to the original state + //case QSystemTrayIcon::DoubleClick: + case QSystemTrayIcon::Trigger: // single click + break; + default: + return; + } + + ensure_tray(); + + const bool is_minimized = isHidden() || !tray_enabled(); + + menu_action_show.setText(!isHidden() ? tr("Show the Octopus") : tr("Hide the Octopus")); + + setVisible(is_minimized); + setHidden(!is_minimized); + + setWindowState(is_minimized ? windowState() & ~Qt::WindowMinimized : Qt::WindowNoState); + + if (is_minimized) + { + raise(); // for OSX + activateWindow(); // for Windows + } + else + { + lower(); + clearFocus(); + } +} + +bool main_window::maybe_hide_to_tray(QEvent* e) +{ + if (e->type() == QEvent::WindowStateChange && + (windowState() & Qt::WindowMinimized) && + tray_enabled()) + { + e->accept(); + ensure_tray(); + hide(); + + return true; + } + + return false; +} + +void main_window::closeEvent(QCloseEvent*) +{ + exit(); +} + +void main_window::maybe_start_profile_from_executable() +{ + if (!work) + { + QString profile; + if (det.profile_to_start(profile) && profile_list.contains(profile)) + { + set_profile(profile); + start_tracker_(); + } + } + else + { + if (det.should_stop()) + stop_tracker_(); + } +} + +void main_window::set_keys_enabled(bool flag) +{ + if (!flag) + { + if (work) + work->sc.reload({}); + global_shortcuts.reload({}); + } + else + register_shortcuts(); +} + +void main_window::changeEvent(QEvent* e) +{ + if (!maybe_hide_to_tray(e)) + e->ignore(); +} + +bool main_window::event(QEvent* event) +{ + using t = QEvent::Type; + + if (work) + { + switch (event->type()) + { + case t::Hide: + case t::WindowActivate: + case t::WindowDeactivate: + case t::WindowStateChange: + case t::FocusIn: + set_is_visible(*this, true); + break; + default: + break; + } + } + return QMainWindow::event(event); +} + +bool main_window::tray_enabled() +{ + return s.tray_enabled && QSystemTrayIcon::isSystemTrayAvailable(); +} + +bool main_window::start_in_tray() +{ + return tray_enabled() && s.tray_start; +} + +void main_window::set_profile_in_registry(const QString &profile) +{ + with_global_settings_object([&](QSettings& s) { + s.setValue(OPENTRACK_PROFILE_FILENAME_KEY, profile); + }); +} + +void main_window::restart_tracker_() +{ + qDebug() << "restart tracker"; + + stop_tracker_(); + start_tracker_(); +} + +void main_window::toggle_tracker_() +{ + qDebug() << "toggle tracker"; + + if (work) + stop_tracker_(); + else + start_tracker_(); +} + +#if !defined _WIN32 +# include +void main_window::annoy_if_root() +{ + if (geteuid() == 0) + { + struct lst { + QString caption; + QString msg; + int sleep_ms; + }; + + const lst list[] = { + { + tr("Running as root is bad"), + tr("Do not run as root. Set correct device node permissions."), + 1000, + }, + { + tr("Running as root is bad, seriously"), + tr("Do not run as root. I'll keep whining at every startup."), + 3000, + }, + { + tr("Be annoyed, comprehensively."), + tr("Don't run as root to remove these annoying messages."), + 0 + } + }; + + for (const auto& x : list) + { + QMessageBox::critical(this, x.caption, x.msg, QMessageBox::Ok); + portable::sleep(x.sleep_ms); + } + } +} +#endif diff --git a/opentrack/main-window.hpp b/opentrack/main-window.hpp new file mode 100644 index 00000000..9ffb7019 --- /dev/null +++ b/opentrack/main-window.hpp @@ -0,0 +1,145 @@ +/* Copyright (c) 2013-2016, Stanislaw Halik + + * Permission to use, copy, modify, and/or distribute this + * software for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission + * notice appear in all copies. + */ + +#pragma once + +#include "api/plugin-support.hpp" +#include "gui/mapping-dialog.hpp" +#include "gui/settings.hpp" +#include "gui/process_detector.h" +#include "logic/main-settings.hpp" +#include "logic/pipeline.hpp" +#include "logic/shortcuts.h" +#include "logic/work.hpp" +#include "logic/state.hpp" +#include "options/options.hpp" +#include "compat/qt-signal.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "ui_main-window.h" + +class main_window final : public QMainWindow, private State +{ + Q_DECLARE_TR_FUNCTIONS(main_window) + + Ui::main_window ui; + + std::unique_ptr tray; + QMenu tray_menu { this }; + + QTimer pose_update_timer { this }; + QTimer det_timer; + QTimer profile_list_timer; + + Shortcuts global_shortcuts; + QShortcut kbd_quit { QKeySequence("Ctrl+Q"), this }; + + std::unique_ptr options_widget; + std::unique_ptr mapping_widget; + + std::unique_ptr pFilterDialog; + std::unique_ptr pProtocolDialog; + std::unique_ptr pTrackerDialog; + + process_detector_worker det; + QMenu profile_menu; + + QList profile_list; + + QAction menu_action_header { &tray_menu }, + menu_action_show { &tray_menu }, + menu_action_exit { &tray_menu }, + menu_action_tracker { &tray_menu }, + menu_action_filter { &tray_menu }, + menu_action_proto { &tray_menu }, + menu_action_options { &tray_menu }, + menu_action_mappings { &tray_menu }; + + bool exiting_already { false }; + + qt_sig::nullary start_tracker { this, &main_window::start_tracker_, Qt::QueuedConnection }; + qt_sig::nullary stop_tracker { this, &main_window::stop_tracker_, Qt::QueuedConnection }; + qt_sig::nullary toggle_tracker { this, &main_window::toggle_tracker_, Qt::QueuedConnection }; + qt_sig::nullary restart_tracker { this, &main_window::restart_tracker_, Qt::QueuedConnection }; + + void init_dylibs(); + void init_tray_menu(); + void init_profiles(); + void init_buttons(); + + void init_shortcuts(); + void register_shortcuts(); + void set_keys_enabled(bool flag); + + void update_button_state(bool running, bool inertialp); + +#if !defined _WIN32 + void annoy_if_root(); +#endif + + void changeEvent(QEvent* e) override; + bool maybe_hide_to_tray(QEvent* e); + void closeEvent(QCloseEvent *event) override; + bool event(QEvent *event) override; + + void show_tracker_settings(); + void show_proto_settings(); + void show_filter_settings(); + + void show_options_dialog(); + void show_mapping_window(); + + void show_pose(); + void show_pose_(const double* mapped, const double* raw); + void set_title(const QString& game_title = QString()); + + void start_tracker_(); + void stop_tracker_(); + void restart_tracker_(); + void toggle_tracker_(); + + void set_profile(const QString& new_name, bool migrate = true); + void set_profile_in_registry(const QString& profile); + void refresh_profile_list(); + void die_on_profile_not_writable(); + void maybe_start_profile_from_executable(); + [[nodiscard]] static bool profile_name_from_dialog(QString& ret); + + void create_empty_profile(); + void create_copied_profile(); + void open_profile_directory(); + + void ensure_tray(); + void toggle_restore_from_tray(QSystemTrayIcon::ActivationReason e); + bool tray_enabled(); + bool start_in_tray(); + + void save_modules(); + + void exit(int status = EXIT_SUCCESS); + +public: + main_window(); + ~main_window() override; +}; diff --git a/opentrack/main-window.ui b/opentrack/main-window.ui new file mode 100644 index 00000000..7aab90e8 --- /dev/null +++ b/opentrack/main-window.ui @@ -0,0 +1,1459 @@ + + + Lovecraftian Octopus + main_window + + + + 0 + 0 + 646 + 517 + + + + + :/images/opentrack.png:/images/opentrack.png + + + #video_feed { border: 0; } + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 6 + + + 6 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 4 + + + + + + 0 + 0 + + + + + 320 + 240 + + + + + 320 + 240 + + + + 0 + + + + + 0 + 0 + 320 + 240 + + + + + 0 + 0 + + + + + 320 + 240 + + + + + 320 + 240 + + + + + + 0 + 0 + 320 + 240 + + + + + 0 + 0 + + + + + 320 + 240 + + + + + 320 + 240 + + + + + Candara + 37 + 50 + false + true + + + + + + + :/images/tracking-not-started.png + + + false + + + Qt::AlignCenter + + + true + + + + + + + + + + 0 + 0 + + + + + 320 + 240 + + + + + 320 + 240 + + + + + + + + + + + + 0 + 0 + + + + QFrame::NoFrame + + + 0 + + + + 6 + + + 5 + + + 0 + + + 0 + + + 6 + + + + + + 0 + 0 + + + + Raw tracker data + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + 0 + 0 + + + + + NoAntialias + false + + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + true + + + 4 + + + QLCDNumber::Outline + + + + + + + true + + + + 0 + 0 + + + + false + + + QFrame::Raised + + + Z + + + + + + + + 0 + 0 + + + + QFrame::Raised + + + Pitch + + + + + + + true + + + + 0 + 0 + + + + + NoAntialias + false + + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + true + + + 4 + + + QLCDNumber::Outline + + + + + + + true + + + + 0 + 0 + + + + false + + + QFrame::Raised + + + Y + + + + + + + + 0 + 0 + + + + QFrame::Raised + + + X + + + + + + + true + + + + 0 + 0 + + + + + NoAntialias + false + + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + true + + + 4 + + + QLCDNumber::Outline + + + + + + + + 0 + 0 + + + + QFrame::Raised + + + Roll + + + + + + + + 0 + 0 + + + + QFrame::Raised + + + Yaw + + + + + + + true + + + + 0 + 0 + + + + + NoAntialias + false + + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + true + + + 4 + + + QLCDNumber::Outline + + + + + + + true + + + + 0 + 0 + + + + + NoAntialias + false + + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + true + + + 4 + + + QLCDNumber::Outline + + + + + + + true + + + + 0 + 0 + + + + + NoAntialias + false + + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + true + + + 4 + + + QLCDNumber::Outline + + + + + + + + + + + 0 + 0 + + + + Game data + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + 0 + 0 + + + + + NoAntialias + false + + + + QFrame::NoFrame + + + true + + + 4 + + + QLCDNumber::Flat + + + + + + + true + + + + 0 + 0 + + + + + NoAntialias + false + + + + QFrame::NoFrame + + + true + + + 4 + + + QLCDNumber::Flat + + + + + + + true + + + + 0 + 0 + + + + + NoAntialias + false + + + + QFrame::NoFrame + + + true + + + 4 + + + QLCDNumber::Flat + + + + + + + + 0 + 0 + + + + QFrame::Raised + + + X + + + + + + + true + + + + 0 + 0 + + + + false + + + QFrame::Raised + + + Y + + + + + + + true + + + + 0 + 0 + + + + + NoAntialias + false + + + + QFrame::NoFrame + + + true + + + 4 + + + QLCDNumber::Flat + + + + + + + + 0 + 0 + + + + QFrame::Raised + + + Pitch + + + + + + + + 0 + 0 + + + + QFrame::Raised + + + Roll + + + + + + + + 0 + 0 + + + + QFrame::Raised + + + Yaw + + + + + + + true + + + + 0 + 0 + + + + false + + + QFrame::Raised + + + Z + + + + + + + true + + + + 0 + 0 + + + + + NoAntialias + false + + + + QFrame::NoFrame + + + true + + + 4 + + + QLCDNumber::Flat + + + + + + + true + + + + 0 + 0 + + + + + NoAntialias + false + + + + QFrame::NoFrame + + + true + + + 4 + + + QLCDNumber::Flat + + + + + + + + + + + + + + 0 + 0 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + + 4 + 0 + + + + 0 + + + + 3 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + 0 + 0 + + + + Qt::StrongFocus + + + Profile + + + QToolButton::InstantPopup + + + Qt::ToolButtonTextBesideIcon + + + true + + + Qt::DownArrow + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + 20 + + + + + + + + + + + 0 + 0 + + + + Options + + + + :/images/tools.png:/images/tools.png + + + + 80 + 24 + + + + + + + + + 0 + 0 + + + + Mapping + + + + :/images/curves.png:/images/curves.png + + + + 80 + 24 + + + + + + + + + 3 + 0 + + + + Tracking + + + true + + + + 8 + + + 0 + + + 6 + + + 0 + + + 6 + + + + + + 0 + 0 + + + + + 75 + true + + + + Start + + + + + + + false + + + + 0 + 0 + + + + + 75 + true + + + + Stop + + + + + + + + + + + + + + 4 + 0 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 2 + + + 3 + + + 2 + + + 3 + + + 8 + + + + + Input + + + + 4 + + + 0 + + + 0 + + + 0 + + + 3 + + + 0 + + + + + + 0 + 0 + + + + Qt::TabFocus + + + + + + + true + + + + 0 + 0 + + + + + DejaVu Sans + PreferAntialias + false + + + + Qt::ClickFocus + + + 🔨 + + + false + + + + + + + + + + Output + + + + 4 + + + 0 + + + 0 + + + 0 + + + 3 + + + 0 + + + + + + 0 + 0 + + + + Qt::TabFocus + + + + + + + true + + + + 0 + 0 + + + + + DejaVu Sans + PreferAntialias + false + + + + Qt::ClickFocus + + + 🔨 + + + false + + + + + + + + + + Filter + + + + 4 + + + 0 + + + 0 + + + 0 + + + 3 + + + 0 + + + + + + 0 + 0 + + + + Qt::TabFocus + + + + + + + true + + + + 0 + 0 + + + + + DejaVu Sans + PreferAntialias + false + + + + Qt::ClickFocus + + + 🔨 + + + false + + + + + + + + + + + + + + + + + + + + + pose_widget + QWidget +
pose-widget/pose-widget.hpp
+
+
+ + btnStartTracker + btnStopTracker + profile_button + iconcomboProfile + btnShortcuts + btnEditCurves + + + + + +
diff --git a/opentrack/main.cpp b/opentrack/main.cpp new file mode 100644 index 00000000..2c1dc607 --- /dev/null +++ b/opentrack/main.cpp @@ -0,0 +1,23 @@ +#include "gui/init.hpp" +#include "main-window.hpp" + +#if defined _WIN32 +# include +#endif + +#ifdef __clang__ +# pragma GCC diagnostic ignored "-Wmain" +#endif + +int main(int argc, char** argv) +{ + return run_application(argc, argv, [] { return std::make_unique(); }); +} + +#if defined _MSC_VER + +int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int /* nCmdShow */) +{ + return main(__argc, __argv); +} +#endif diff --git a/opentrack/new_config.ui b/opentrack/new_config.ui new file mode 100644 index 00000000..a262e725 --- /dev/null +++ b/opentrack/new_config.ui @@ -0,0 +1,45 @@ + + + UI_new_config + + + Qt::ApplicationModal + + + + 0 + 0 + 269 + 67 + + + + Config filename + + + + images/opentrack.pngimages/opentrack.png + + + + + + New file name: + + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + diff --git a/opentrack/new_file_dialog.cpp b/opentrack/new_file_dialog.cpp new file mode 100644 index 00000000..70816c5d --- /dev/null +++ b/opentrack/new_file_dialog.cpp @@ -0,0 +1,37 @@ +#include "new_file_dialog.h" + +new_file_dialog::new_file_dialog(QWidget* parent) : QDialog(parent) +{ + ui.setupUi(this); + connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(ok_clicked())); + connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(cancel_clicked())); + setFixedSize(size()); +} + +bool new_file_dialog::is_ok(QString& name_) +{ + name_ = name; + return ok; +} + +void new_file_dialog::cancel_clicked() { close(); } + +void new_file_dialog::ok_clicked() +{ + QString text = ui.lineEdit->text(); + text = text.replace('/', ""); + text = text.replace('\\', ""); + if (text != "" && !text.endsWith(".ini")) + text += ".ini"; + if (text == "" || text == ".ini" || QFile(options::globals::ini_directory() + "/" + text).exists()) + { + QMessageBox::warning(this, + tr("File exists"), + tr("This file already exists. Pick another name."), + QMessageBox::Ok, QMessageBox::NoButton); + return; + } + ok = true; + close(); + name = text; +} diff --git a/opentrack/new_file_dialog.h b/opentrack/new_file_dialog.h new file mode 100644 index 00000000..7244e524 --- /dev/null +++ b/opentrack/new_file_dialog.h @@ -0,0 +1,25 @@ +#pragma once + +#include "ui_new_config.h" +#include "options/options.hpp" +#include +#include +#include +#include + +class new_file_dialog : public QDialog +{ + Q_OBJECT +public: + new_file_dialog(QWidget* parent = nullptr); + bool is_ok(QString& name_); + +private: + Ui::UI_new_config ui; + bool ok = false; + QString name; + +private slots: + void cancel_clicked(); + void ok_clicked(); +}; diff --git a/opentrack/opentrack.ico b/opentrack/opentrack.ico new file mode 100644 index 00000000..5cac8da1 Binary files /dev/null and b/opentrack/opentrack.ico differ diff --git a/opentrack/resources.rc b/opentrack/resources.rc new file mode 100644 index 00000000..6fd0253b --- /dev/null +++ b/opentrack/resources.rc @@ -0,0 +1,2 @@ +#include +IDI_ICON1 ICON "opentrack.ico" diff --git a/trackmouse/CMakeLists.txt b/trackmouse/CMakeLists.txt new file mode 100644 index 00000000..6240d4b3 --- /dev/null +++ b/trackmouse/CMakeLists.txt @@ -0,0 +1,9 @@ +otr_module(executable EXECUTABLE BIN) + +set_target_properties(opentrack-executable PROPERTIES + SUFFIX "${opentrack-binary-suffix}" + OUTPUT_NAME "trackmouse" + PREFIX "" +) + +target_link_libraries(${self} opentrack-user-interface opentrack-version) diff --git a/trackmouse/images/start.png b/trackmouse/images/start.png new file mode 100644 index 00000000..b8e6f271 Binary files /dev/null and b/trackmouse/images/start.png differ diff --git a/trackmouse/images/stop.png b/trackmouse/images/stop.png new file mode 100644 index 00000000..0ff13bd5 Binary files /dev/null and b/trackmouse/images/stop.png differ diff --git a/trackmouse/lang/nl_NL.ts b/trackmouse/lang/nl_NL.ts new file mode 100644 index 00000000..92f790af --- /dev/null +++ b/trackmouse/lang/nl_NL.ts @@ -0,0 +1,74 @@ + + + + + main_window + + The Octopus is sad + + + + :: + + + + Check permissions for your .ini directory: + +%1"%2 + +Exiting now. + + + + + window + + trackmouse prototype + + + + Keyboard shortcuts + + + + start/stop tracking + + + + Alt+F10 + + + + center + + + + Alt+F11 + + + + Alt+F12 + + + + Sensitivity + + + + 100% + + + + Start + + + + Stop + + + + freeze toggle + + + + diff --git a/trackmouse/lang/ru_RU.ts b/trackmouse/lang/ru_RU.ts new file mode 100644 index 00000000..dd9011c4 --- /dev/null +++ b/trackmouse/lang/ru_RU.ts @@ -0,0 +1,74 @@ + + + + + main_window + + The Octopus is sad + + + + :: + + + + Check permissions for your .ini directory: + +%1"%2 + +Exiting now. + + + + + window + + trackmouse prototype + + + + Keyboard shortcuts + + + + start/stop tracking + + + + Alt+F10 + + + + center + + + + Alt+F11 + + + + Alt+F12 + + + + Sensitivity + + + + 100% + + + + Start + + + + Stop + + + + freeze toggle + + + + diff --git a/trackmouse/lang/stub.ts b/trackmouse/lang/stub.ts new file mode 100644 index 00000000..968e31c5 --- /dev/null +++ b/trackmouse/lang/stub.ts @@ -0,0 +1,74 @@ + + + + + main_window + + The Octopus is sad + + + + :: + + + + Check permissions for your .ini directory: + +%1"%2 + +Exiting now. + + + + + window + + trackmouse prototype + + + + Keyboard shortcuts + + + + start/stop tracking + + + + Alt+F10 + + + + center + + + + Alt+F11 + + + + Alt+F12 + + + + Sensitivity + + + + 100% + + + + Start + + + + Stop + + + + freeze toggle + + + + diff --git a/trackmouse/lang/zh_CN.ts b/trackmouse/lang/zh_CN.ts new file mode 100644 index 00000000..968e31c5 --- /dev/null +++ b/trackmouse/lang/zh_CN.ts @@ -0,0 +1,74 @@ + + + + + main_window + + The Octopus is sad + + + + :: + + + + Check permissions for your .ini directory: + +%1"%2 + +Exiting now. + + + + + window + + trackmouse prototype + + + + Keyboard shortcuts + + + + start/stop tracking + + + + Alt+F10 + + + + center + + + + Alt+F11 + + + + Alt+F12 + + + + Sensitivity + + + + 100% + + + + Start + + + + Stop + + + + freeze toggle + + + + diff --git a/trackmouse/main.cpp b/trackmouse/main.cpp new file mode 100644 index 00000000..2313e1ac --- /dev/null +++ b/trackmouse/main.cpp @@ -0,0 +1,18 @@ +#include "gui/init.hpp" +#include "window.hpp" + +#if defined _WIN32 +# include +#endif + +int main(int argc, char** argv) +{ + return run_application(argc, argv, []() { return new main_window; }); +} + +#if defined _MSC_VER +int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int /* nCmdShow */) +{ + return main(__argc, __argv); +} +#endif diff --git a/trackmouse/trackmouse-res.qrc b/trackmouse/trackmouse-res.qrc new file mode 100644 index 00000000..f351b3f2 --- /dev/null +++ b/trackmouse/trackmouse-res.qrc @@ -0,0 +1,6 @@ + + + images/start.png + images/stop.png + + diff --git a/trackmouse/trackmouse-settings.cpp b/trackmouse/trackmouse-settings.cpp new file mode 100644 index 00000000..45ec36a5 --- /dev/null +++ b/trackmouse/trackmouse-settings.cpp @@ -0,0 +1,132 @@ +#include "logic/main-settings.hpp" +#include "logic/mappings.hpp" + +#include "tracker-pt/pt-settings.hpp" +#include "filter-accela/accela-settings.hpp" +#include "proto-mouse/mouse-settings.hpp" + +#include "options/options.hpp" + +#include + +using namespace options; + +static void force_spline_settings() +{ + main_settings main; + + axis_opts** all_axis_opts = main.all_axis_opts; + Mappings mappings { all_axis_opts }; + + for (unsigned k = 0; k < 6; k++) + { + Map& map = mappings(k); + const QString& prefix = all_axis_opts[k]->prefix(); + + const QString& name1 = map.name; + const QString& name2 = map.alt_name; + + bundle b = make_bundle(prefix); + + spline_detail::settings s1(b, name1, Axis(k)); + spline_detail::settings s2(b, name2, Axis(k)); + + s1.points = QList { { 180, 180 } }; + s2.points = QList { { 180, 180 } }; + + b->save(); + } +} + +static void force_main_settings() +{ + main_settings s; + s.center_at_startup = true; + s.reltrans_mode = reltrans_disabled; + s.neck_enable = false; + + module_settings m; + + m.tracker_dll = "pt"; + m.protocol_dll = "win32-mouse"; + m.filter_dll = "accela"; + + s.b->save(); + s.b_map->save(); +} + +static void force_pt_settings() +{ + pt_settings s("tracker-pt"); + + enum { Clip = 0 }; + + s.active_model_panel = Clip; + // XXX TODO these are Mini Clip Right sizes + s.clip_by = 60; + s.clip_bz = 38.2; + s.clip_ty = 42.2; + s.clip_tz = 12.6; + + s.cam_fps = 60; + s.cam_res_x = 640; + s.cam_res_y = 480; + s.camera_name = "PS3Eye Camera"; + + s.min_point_size = 3.7; + s.max_point_size = 10; + + // XXX TODO auto threshold slider position + s.auto_threshold = true; + s.threshold_slider = slider_value(82., s.threshold_slider->min(), s.threshold_slider->max()); + + s.t_MH_x = 0, s.t_MH_y = 0, s.t_MH_z = 0; + s.blob_color = pt_color_natural; + s.fov = 56; + s.dynamic_pose = false; + + s.b->save(); +} + +static void force_mouse_settings() +{ + + mouse_settings s; + + s.Mouse_X = Yaw + 1; + s.Mouse_Y = Pitch + 1; + + s.b->save(); +} + +static void force_accela_settings() +{ + // XXX TODO +} + +static void force_shortcut_settings() +{ + main_settings s; + s.key_toggle_tracking1.keycode = "Ins"; + s.key_center1.keycode = "PgUp"; + s.key_toggle1.keycode = "PgDown"; + + for (key_opts* k : { &s.key_toggle_tracking1, &s.key_center1, &s.key_toggle_press1 }) + { + k->button = -1; + k->guid = {}; + } + s.b->save(); +} + +void force_trackmouse_settings() +{ + options::globals::with_settings_object([](QSettings&) { + force_main_settings(); + force_spline_settings(); + force_pt_settings(); + force_mouse_settings(); + force_accela_settings(); + force_shortcut_settings(); + }); +} diff --git a/trackmouse/trackmouse.ico b/trackmouse/trackmouse.ico new file mode 100644 index 00000000..5cac8da1 Binary files /dev/null and b/trackmouse/trackmouse.ico differ diff --git a/trackmouse/trackmouse.rc b/trackmouse/trackmouse.rc new file mode 100644 index 00000000..8df1e9b1 --- /dev/null +++ b/trackmouse/trackmouse.rc @@ -0,0 +1,2 @@ +#include +IDI_ICON1 ICON "trackmouse.ico" diff --git a/trackmouse/window.cpp b/trackmouse/window.cpp new file mode 100644 index 00000000..d6c8a8dd --- /dev/null +++ b/trackmouse/window.cpp @@ -0,0 +1,388 @@ +/* Copyright (c) 2013-2018, Stanislaw Halik + + * Permission to use, copy, modify, and/or distribute this + * software for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission + * notice appear in all copies. + */ + +#include "window.hpp" +#include "options/options.hpp" +#include "migration/migration.hpp" +#include "compat/check-visible.hpp" +#include "compat/sleep.hpp" +#include "compat/macros.hpp" +#include "compat/library-path.hpp" +#include "compat/math.hpp" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +extern "C" const char* const opentrack_version; + +using namespace options::globals; +using namespace options; + +#if !defined EXIT_SUCCESS +# define EXIT_SUCCESS 0 +#endif + +#if !defined EXIT_FAILURE +# define EXIT_FAILURE 1 +#endif + +/* FreeBSD sysexits(3) + * + * The input data was incorrect in some way. This + * should only be used for user's data and not system + * files. + */ + +#if !defined EX_OSFILE +# define EX_OSFILE 72 +#endif + +void force_trackmouse_settings(); + +main_window::main_window() : State(OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH) +{ + ui.setupUi(this); + + update_button_state(false, false); + + // ctrl+q exits + connect(&kbd_quit, SIGNAL(activated()), this, SLOT(exit())); + + if (!set_profile()) + { + die_on_config_not_writable(); + exit(EX_OSFILE); + return; + } + + // only tie and connect main screen options after migrations are done + // below is fine, set_profile() is called already + + connect(this, &main_window::start_tracker, + this, [&] { qDebug() << "start tracker"; start_tracker_(); }, + Qt::QueuedConnection); + + connect(this, &main_window::stop_tracker, + this, [&] { qDebug() << "stop tracker"; stop_tracker_(); }, + Qt::QueuedConnection); + + connect(this, &main_window::toggle_tracker, + this, [&] { qDebug() << "toggle tracker"; toggle_tracker_(); }, + Qt::QueuedConnection); + + connect(ui.btnStartTracker, SIGNAL(clicked()), this, SLOT(start_tracker_())); + connect(ui.btnStopTracker, SIGNAL(clicked()), this, SLOT(stop_tracker_())); + + { + tie_setting(mouse.sensitivity_x, ui.sensitivity_slider); + tie_setting(mouse.sensitivity_x, ui.sensitivity_label, + [](double x) { return QString::number(x) + QStringLiteral("%"); }); + // one-way only + tie_setting(mouse.sensitivity_x, this, + [this](double x) { mouse.sensitivity_y = *mouse.sensitivity_x; }); + + // no "ok" button, gotta save on timer + auto save = [this] { + qDebug() << "trackmouse: saving settings"; + mouse.b->save(); + save_settings_timer.stop(); + }; + + auto start_save_timer = [this](double) { + save_settings_timer.start(); + }; + + save_settings_timer.setInterval(save_settings_interval_ms); + save_settings_timer.setSingleShot(true); + + ui.sensitivity_slider->setTracking(false); + connect(&save_settings_timer, &QTimer::timeout, this, save, Qt::DirectConnection); +#if 1 + // this doesn't fire the timer on application load + connect(ui.sensitivity_slider, &QSlider::valueChanged, this, start_save_timer, Qt::DirectConnection); +#else + // but this does so let's not not use it + tie_setting(mouse.sensitivity_x, this, start_save_timer); +#endif + } + + force_trackmouse_settings(); + + register_shortcuts(); + kbd_quit.setEnabled(true); + + setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | windowFlags()); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + adjustSize(); + + setVisible(true); + show(); +} + +void main_window::register_shortcuts() +{ + global_shortcuts.reload({ + { s.key_toggle_tracking1, [this](bool) { main_window::toggle_tracker(); }, true }, + }); + + if (work) + work->reload_shortcuts(); +} + +void main_window::die_on_config_not_writable() +{ + stop_tracker_(); + + static const QString pad(16, QChar(' ')); + + QMessageBox::critical(this, + tr("The Octopus is sad"), + tr("Check permissions for your .ini directory:\n\n%1\"%2\n\n" + "Exiting now." + ).arg(ini_directory(), pad), + QMessageBox::Close, QMessageBox::NoButton); + + exit(EX_OSFILE); +} + +bool main_window::maybe_die_on_config_not_writable(const QString& current) +{ + const bool writable = + with_settings_object([&](QSettings& s) { + return s.isWritable(); + }); + + if (writable) + return false; + + if (!QFile(ini_combine(current)).open(QFile::ReadWrite)) + { + die_on_config_not_writable(); + return true; + } + + return false; +} + +main_window::~main_window() +{ + // stupid ps3 eye has LED issues + if (work) + { + stop_tracker_(); + close(); + + constexpr int inc = 100, max = 2000; + + for (int k = 0; k < max; k += inc) + { + QEventLoop ev; + ev.processEvents(); + portable::sleep(inc); + } + } + + exit(); +} + +void main_window::set_working_directory() +{ + QDir::setCurrent(OPENTRACK_BASE_PATH); +} + +void main_window::save_modules() +{ + m.b->save(); +} + +std::tuple +main_window::module_by_name(const QString& name, Modules::dylib_list& list) +{ + auto it = std::find_if(list.cbegin(), list.cend(), [&name](const dylib_ptr& lib) { + if (!lib) + return name.isEmpty(); + else + return name == lib->module_name; + }); + + if (it == list.cend()) + return { nullptr, -1 }; + else + return { *it, std::distance(list.cbegin(), it) }; +} + +main_window::dylib_ptr main_window::current_tracker() +{ + auto [ptr, idx] = module_by_name(m.tracker_dll, modules.trackers()); + return ptr; +} + +main_window::dylib_ptr main_window::current_protocol() +{ + auto [ptr, idx] = module_by_name(m.protocol_dll, modules.protocols()); + return ptr; +} + +main_window::dylib_ptr main_window::current_filter() +{ + auto [ptr, idx] = module_by_name(m.filter_dll, modules.filters()); + return ptr; +} + +void main_window::update_button_state(bool running, bool inertialp) +{ + bool not_running = !running; +#if 0 + ui.iconcomboProfile->setEnabled(not_running); + ui.btnStartTracker->setEnabled(not_running); + ui.btnStopTracker->setEnabled(running); + ui.iconcomboProtocol->setEnabled(not_running); + ui.iconcomboFilter->setEnabled(not_running); + ui.iconcomboTrackerSource->setEnabled(not_running); + ui.profile_button->setEnabled(not_running); +#endif + ui.video_frame_label->setVisible(not_running || inertialp); + if(not_running) + { + ui.video_frame_label->setPixmap(QPixmap(":/images/tracking-not-started.png")); + } + else { + ui.video_frame_label->setPixmap(QPixmap(":/images/no-feed.png")); + } +} + +void main_window::start_tracker_() +{ + if (work) + return; + + work = std::make_shared(pose, ev, ui.video_frame, current_tracker(), current_protocol(), current_filter()); + + if (!work->is_ok()) + { + work = nullptr; + return; + } + + if (pTrackerDialog) + pTrackerDialog->register_tracker(work->libs.pTracker.get()); + + if (pFilterDialog) + pFilterDialog->register_filter(work->libs.pFilter.get()); + + if (pProtocolDialog) + pProtocolDialog->register_protocol(work->libs.pProtocol.get()); + + // NB check valid since SelectedLibraries ctor called + // trackers take care of layout state updates + const bool is_inertial = ui.video_frame->layout() == nullptr; + update_button_state(true, is_inertial); + + ui.btnStopTracker->setFocus(); +} + +void main_window::stop_tracker_() +{ + if (!work) + return; + + with_tracker_teardown sentinel; + + if (pTrackerDialog) + pTrackerDialog->unregister_tracker(); + + if (pProtocolDialog) + pProtocolDialog->unregister_protocol(); + + if (pFilterDialog) + pFilterDialog->unregister_filter(); + + work = nullptr; + + update_button_state(false, false); + set_title(); + ui.btnStartTracker->setFocus(); +} + +void main_window::set_title(const QString& game_title) +{ + static const QString version{opentrack_version}; + static const QString sep { tr(" :: ") }; + static const QString pat1{ version + sep + "%1" + sep + "%2" }; + static const QString pat2{ version + sep + "%1" }; + + const QString current = ini_filename(); + + if (game_title.isEmpty()) + setWindowTitle(pat2.arg(current)); + else + setWindowTitle(pat1.arg(current, game_title)); +} + +void main_window::exit(int status) +{ + if (exiting_already) + return; + exiting_already = true; + + qDebug() << "trackmouse: saving settings on app exit"; + save_settings_timer.stop(); + mouse.b->save(); + + //close(); + QApplication::setQuitOnLastWindowClosed(true); + QApplication::exit(status); +} + +bool main_window::set_profile() +{ + if (maybe_die_on_config_not_writable(OPENTRACK_DEFAULT_CONFIG)) + return false; + + set_profile_in_registry(); + + options::detail::bundler::refresh_all_bundles(); + + // migrations are for config layout changes and other user-visible + // incompatibilities in future versions + run_migrations(); + + set_title(); + + return true; +} + +void main_window::closeEvent(QCloseEvent*) +{ + exit(); +} + +void main_window::set_profile_in_registry() +{ + with_global_settings_object([&](QSettings& s) { + s.setValue(OPENTRACK_CONFIG_FILENAME_KEY, OPENTRACK_DEFAULT_CONFIG); + }); +} + +void main_window::toggle_tracker_() +{ + qDebug() << "toggle tracker"; + if (work) + stop_tracker_(); + else + start_tracker_(); +} diff --git a/trackmouse/window.hpp b/trackmouse/window.hpp new file mode 100644 index 00000000..2c196852 --- /dev/null +++ b/trackmouse/window.hpp @@ -0,0 +1,94 @@ +#pragma once + +/* Copyright (c) 2013-2016, Stanislaw Halik + + * Permission to use, copy, modify, and/or distribute this + * software for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission + * notice appear in all copies. + */ + +#pragma once + +#include "ui_window.h" +#include "proto-mouse/mouse-settings.hpp" + +#include "api/plugin-support.hpp" +#include "logic/main-settings.hpp" +#include "logic/pipeline.hpp" +#include "logic/shortcuts.h" +#include "logic/work.hpp" +#include "logic/state.hpp" +#include "options/options.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include + +class main_window final : public QMainWindow, private State +{ + Q_OBJECT + + Ui::window ui; + + QTimer save_settings_timer { this }; + + Shortcuts global_shortcuts; + module_settings m; + mouse_settings mouse; + + QShortcut kbd_quit { QKeySequence("Ctrl+Q"), this }; + std::unique_ptr pFilterDialog; + std::unique_ptr pProtocolDialog; + std::unique_ptr pTrackerDialog; + bool exiting_already { false }; + + using dylib_ptr = Modules::dylib_ptr; + using dylib_list = Modules::dylib_list; + + static std::tuple module_by_name(const QString& name, Modules::dylib_list& list); + + dylib_ptr current_tracker(); + dylib_ptr current_protocol(); + dylib_ptr current_filter(); + + void update_button_state(bool running, bool inertialp); + + void set_title(const QString& game_title = QString()); + + void set_profile_in_registry(); + void register_shortcuts(); + + void closeEvent(QCloseEvent *event) override; + + bool maybe_die_on_config_not_writable(const QString& current); + void die_on_config_not_writable(); + + static constexpr int save_settings_interval_ms = 2500; + +private slots: + void save_modules(); + void exit(int status = EXIT_SUCCESS); + bool set_profile(); + + void start_tracker_(); + void stop_tracker_(); + void toggle_tracker_(); + + static void set_working_directory(); + +signals: + void start_tracker(); + void stop_tracker(); + void toggle_tracker(); + +public: + main_window(); + ~main_window() override; +}; diff --git a/trackmouse/window.ui b/trackmouse/window.ui new file mode 100644 index 00000000..c79ae846 --- /dev/null +++ b/trackmouse/window.ui @@ -0,0 +1,458 @@ + + + window + + + + 0 + 0 + 755 + 240 + + + + + 0 + 0 + + + + + 16777215 + 240 + + + + trackmouse prototype + + + + + 0 + 0 + + + + + 16777215 + 240 + + + + + 6 + + + 6 + + + 0 + + + 12 + + + 0 + + + + + + 0 + 0 + + + + + 320 + 240 + + + + + 320 + 240 + + + + + + 0 + 0 + 320 + 240 + + + + + 0 + 0 + + + + + 320 + 240 + + + + + 320 + 240 + + + + + + 0 + 0 + 320 + 240 + + + + + 0 + 0 + + + + + 320 + 240 + + + + + 320 + 240 + + + + + Candara + 37 + 50 + false + true + + + + + + + :/images/tracking-not-started.png + + + false + + + Qt::AlignCenter + + + true + + + + + + + + + + 0 + 0 + + + + + 12 + + + 8 + + + 12 + + + 12 + + + 12 + + + + + Keyboard shortcuts + + + + + + + 0 + 0 + + + + + 12 + 75 + true + PreferAntialias + false + + + + start/stop tracking + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + PreferAntialias + false + + + + Insert + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + PreferAntialias + false + + + + center + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + PreferAntialias + false + + + + Page Up + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + PreferAntialias + false + + + + freeze toggle + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + PreferAntialias + false + + + + Page Down + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + 0 + 0 + + + + Sensitivity + + + + + + + 10 + 0 + + + + 475 + + + 1 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 50 + + + + + + + + 2 + 0 + + + + 100% + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + 0 + 0 + + + + + 3 + + + 3 + + + + + + 0 + 0 + + + + Start + + + + :/images/images/start.png:/images/images/start.png + + + + 43 + 20 + + + + + + + + + 0 + 0 + + + + Stop + + + + :/images/images/stop.png:/images/images/stop.png + + + + + + + + + + + + + + + + + + diff --git a/variant/default/CMakeLists.txt b/variant/default/CMakeLists.txt deleted file mode 100644 index a8829aa5..00000000 --- a/variant/default/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -otr_module(executable EXECUTABLE BIN) - -set_target_properties(opentrack-executable PROPERTIES - SUFFIX "${opentrack-binary-suffix}" - OUTPUT_NAME "opentrack" - PREFIX "" -) - -target_link_libraries(${self} opentrack-user-interface opentrack-version) diff --git a/variant/default/_variant.cmake b/variant/default/_variant.cmake index 7501b0a4..7353b0f4 100644 --- a/variant/default/_variant.cmake +++ b/variant/default/_variant.cmake @@ -25,6 +25,7 @@ function(otr_init_variant) "main-window" "video" "video-*" + "opentrack" ) set_property(GLOBAL PROPERTY opentrack-subprojects "${subprojects}") diff --git a/variant/default/lang/nl_NL.ts b/variant/default/lang/nl_NL.ts deleted file mode 100644 index 7a465820..00000000 --- a/variant/default/lang/nl_NL.ts +++ /dev/null @@ -1,189 +0,0 @@ - - - - - UI_new_config - - Config filename - - - - New file name: - - - - - main_window - - Raw tracker data - - - - Z - - - - Pitch - - - - Y - - - - X - - - - Roll - - - - Yaw - - - - Game data - - - - Profile - - - - Options - - - - Mapping - - - - Tracking - - - - Start - - - - Stop - - - - Input - - - - 🔨 - - - - Output - - - - Filter - - - - Running as root is bad - - - - Do not run as root. Set correct device node permissions. - - - - Running as root is bad, seriously - - - - Do not run as root. I'll keep whining at every startup. - - - - Create new empty config - - - - Create new copied config - - - - Open configuration directory - - - - opentrack - - - - (debug) - - - - Show the Octopus - - - - Hide the Octopus - - - - Tracker settings - - - - Filter settings - - - - Protocol settings - - - - Mappings - - - - Exit - - - - The Octopus is sad - - - - Check permissions for your .ini directory: - -"%1"%2 - -Exiting now. - - - - :: - - - - Be annoyed, comprehensively. - - - - Don't run as root to remove these annoying messages. - - - - - new_file_dialog - - File exists - - - - This file already exists. Pick another name. - - - - diff --git a/variant/default/lang/ru_RU.ts b/variant/default/lang/ru_RU.ts deleted file mode 100644 index 684a8212..00000000 --- a/variant/default/lang/ru_RU.ts +++ /dev/null @@ -1,193 +0,0 @@ - - - - - UI_new_config - - Config filename - Создание профиля - - - New file name: - Новое имя профиля: - - - - main_window - - Create new empty config - Создать новый пустой профиль - - - Create new copied config - Создать новый профиль на основе текущего - - - Open configuration directory - Открыть каталог с профилями - - - opentrack - - - - (debug) - - - - Show the Octopus - Показать осьминожка - - - Hide the Octopus - Спрятать осьминожка - - - Tracker settings - Настройка источника данных - - - Filter settings - Настройка фильтрации/сглаживания - - - Protocol settings - Настройка выходного интерфейса - - - Mappings - Настройка кривых - - - Options - Настройки - - - Exit - Закрыть - - - The Octopus is sad - Осьминожек опечален - - - Check permissions for your .ini directory: - -"%1"%2 - -Exiting now. - Проверьте права доступа на Вашу .ini папку: - -"%1"%2 - -Закрытие программы. - - - :: - :: - - - Raw tracker data - Исходные данные - - - Z - Z - - - Pitch - Pitch - - - Y - Y - - - X - X - - - Roll - Roll - - - Yaw - Yaw - - - Game data - Игровые данные - - - Profile - Профиль - - - Mapping - Кривые - - - Tracking - Статус работы трекера - - - Start - Запустить - - - Stop - Остановить - - - Input - Источник данных - - - 🔨 - - - - Output - Выходной интерфейс - - - Filter - Фильтрация/сглаживание - - - Running as root is bad - - - - Do not run as root. Set correct device node permissions. - - - - Running as root is bad, seriously - - - - Do not run as root. I'll keep whining at every startup. - - - - Be annoyed, comprehensively. - - - - Don't run as root to remove these annoying messages. - - - - - new_file_dialog - - File exists - Файл создан - - - This file already exists. Pick another name. - Данный файл уже создан. Пожалуйста выберите другое имя. - - - diff --git a/variant/default/lang/stub.ts b/variant/default/lang/stub.ts deleted file mode 100644 index 04555dd0..00000000 --- a/variant/default/lang/stub.ts +++ /dev/null @@ -1,189 +0,0 @@ - - - - - UI_new_config - - Config filename - - - - New file name: - - - - - main_window - - Raw tracker data - - - - Z - - - - Pitch - - - - Y - - - - X - - - - Roll - - - - Yaw - - - - Game data - - - - Profile - - - - Options - - - - Mapping - - - - Tracking - - - - Start - - - - Stop - - - - Input - - - - 🔨 - - - - Output - - - - Filter - - - - Running as root is bad - - - - Do not run as root. Set correct device node permissions. - - - - Running as root is bad, seriously - - - - Do not run as root. I'll keep whining at every startup. - - - - Create new empty config - - - - Create new copied config - - - - Open configuration directory - - - - opentrack - - - - (debug) - - - - Show the Octopus - - - - Hide the Octopus - - - - Tracker settings - - - - Filter settings - - - - Protocol settings - - - - Mappings - - - - Exit - - - - The Octopus is sad - - - - Check permissions for your .ini directory: - -"%1"%2 - -Exiting now. - - - - :: - - - - Be annoyed, comprehensively. - - - - Don't run as root to remove these annoying messages. - - - - - new_file_dialog - - File exists - - - - This file already exists. Pick another name. - - - - diff --git a/variant/default/lang/zh_CN.ts b/variant/default/lang/zh_CN.ts deleted file mode 100644 index 15609d70..00000000 --- a/variant/default/lang/zh_CN.ts +++ /dev/null @@ -1,193 +0,0 @@ - - - - - UI_new_config - - Config filename - 配置文件名字: - - - New file name: - 新文件名字: - - - - main_window - - Raw tracker data - 跟踪器原始数据 - - - Z - - - - Pitch - 仰俯 - - - Y - - - - X - - - - Roll - 横滚 - - - Yaw - 偏航 - - - Game data - 游戏得到的数据 - - - Profile - 配置文件 - - - Options - 选项 - - - Mapping - 映射 - - - Tracking - 跟踪 - - - Start - 开始 - - - Stop - 停止 - - - Input - 输入 - - - 🔨 - - - - Output - 输出 - - - Filter - 过滤器 - - - Running as root is bad - 以管理员运行不是什么好主意 - - - Do not run as root. Set correct device node permissions. - 请不要以管理员运行。可以设置何时的设备访问权限来解决。 - - - Running as root is bad, seriously - 再说一遍,以管理员运行不是什么好主意 - - - Do not run as root. I'll keep whining at every startup. - 请不要以管理员运行。这话每次启动我都会强调一遍。 - - - Don't run as root to remove these annoying messages. - 以管理员运行真的非常不好 - - - Be annoyed, comprehensively. - 请不要以管理员运行。烦了吧?赶紧动作起来 - - - Create new empty config - 新建一个空的配置 - - - Create new copied config - 新建一个复制配置 - - - Open configuration directory - 打开配置目录 - - - opentrack - - - - (debug) - (调试) - - - Show the Octopus - 显示八爪鱼 - - - Hide the Octopus - 隐藏八爪鱼 - - - Tracker settings - 跟踪器设置 - - - Filter settings - 过滤器设置 - - - Protocol settings - 协议设置 - - - Mappings - 影射 - - - Exit - 退出 - - - The Octopus is sad - 八爪鱼不开心了 - - - Check permissions for your .ini directory: - -"%1"%2 - -Exiting now. - 检查一下你的 .ini 目录权限: - -"%1"%2 - -退出先. - - - :: - - - - - new_file_dialog - - File exists - 文件已经存在 - - - This file already exists. Pick another name. - 文件重名了,换个其他名字 - - - diff --git a/variant/default/main-window.cpp b/variant/default/main-window.cpp deleted file mode 100644 index b90aa3bd..00000000 --- a/variant/default/main-window.cpp +++ /dev/null @@ -1,920 +0,0 @@ -/* Copyright (c) 2013-2016, Stanislaw Halik - - * Permission to use, copy, modify, and/or distribute this - * software for any purpose with or without fee is hereby granted, - * provided that the above copyright notice and this permission - * notice appear in all copies. - */ - -#include "main-window.hpp" -#include "logic/pipeline.hpp" -#include "options/options.hpp" -#include "new_file_dialog.h" -#include "migration/migration.hpp" -#include "compat/check-visible.hpp" -#include "compat/sleep.hpp" -#include "compat/macros.hpp" -#include "compat/library-path.hpp" -#include "compat/math.hpp" -#include "compat/sysexits.hpp" - -#include -#include - -#include -#include -#include - -extern "C" const char* const opentrack_version; - -using namespace options::globals; -using namespace options; - -main_window::main_window() : State(OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH) -{ - ui.setupUi(this); - -#if !defined _WIN32 && !defined __APPLE__ - annoy_if_root(); -#endif - - init_profiles(); - init_buttons(); - init_tray_menu(); - init_dylibs(); - init_shortcuts(); - - setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | windowFlags()); - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - adjustSize(); - - if (!start_in_tray()) - { - setVisible(true); - show(); - } - else - setVisible(false); - - connect(&pose_update_timer, &QTimer::timeout, - this, &main_window::show_pose, Qt::DirectConnection); - connect(&det_timer, &QTimer::timeout, - this, &main_window::maybe_start_profile_from_executable); - det_timer.start(1000); -} - -void main_window::init_shortcuts() -{ - register_shortcuts(); - - // ctrl+q exits - connect(&kbd_quit, &QShortcut::activated, this, [this]() { main_window::exit(EXIT_SUCCESS); }, Qt::DirectConnection); - kbd_quit.setEnabled(true); -} - -void main_window::init_dylibs() -{ - using dylib_ptr = Modules::dylib_ptr; - using dylib_list = Modules::dylib_list; - - modules.filters().insert(modules.filters().begin(), - std::make_shared("", dylib_type::Filter)); - - for (dylib_ptr& x : modules.trackers()) - ui.iconcomboTrackerSource->addItem(x->icon, x->name, x->module_name); - - for (dylib_ptr& x : modules.protocols()) - ui.iconcomboProtocol->addItem(x->icon, x->name, x->module_name); - - for (dylib_ptr& x : modules.filters()) - ui.iconcomboFilter->addItem(x->icon, x->name, x->module_name); - - connect(ui.iconcomboTrackerSource, &QComboBox::currentTextChanged, - this, [&](const QString&) { pTrackerDialog = nullptr; }); - - connect(ui.iconcomboProtocol, &QComboBox::currentTextChanged, - this, [&](const QString&) { pProtocolDialog = nullptr; }); - - connect(ui.iconcomboFilter, &QComboBox::currentTextChanged, - this, [&](const QString&) { pFilterDialog = nullptr; }); - - connect(&m.tracker_dll, value_::value_changed(), - this, &main_window::save_modules, - Qt::DirectConnection); - - connect(&m.protocol_dll, value_::value_changed(), - this, &main_window::save_modules, - Qt::DirectConnection); - - connect(&m.filter_dll, value_::value_changed(), - this, &main_window::save_modules, - Qt::DirectConnection); - - { - struct list { - dylib_list& libs; - QComboBox* input; - value& place; - }; - - list types[] { - { modules.trackers(), ui.iconcomboTrackerSource, m.tracker_dll }, - { modules.protocols(), ui.iconcomboProtocol, m.protocol_dll }, - { modules.filters(), ui.iconcomboFilter, m.filter_dll }, - }; - - for (list& type : types) - { - list t = type; - tie_setting(t.place, t.input, - [t](const QString& name) { - auto [ptr, idx] = module_by_name(name, t.libs); - return idx; - }, - [t](int, const QVariant& userdata) { - auto [ptr, idx] = module_by_name(userdata.toString(), t.libs); - if (ptr) - return ptr->module_name; - else - return QString(); - }); - } - } -} - -void main_window::init_profiles() -{ - refresh_profile_list(); - // implicitly created by `ini_directory()' - if (ini_directory().isEmpty() || !QDir(ini_directory()).isReadable()) - die_on_profile_not_writable(); - - set_profile(ini_filename()); - - // profile menu - profile_menu.addAction(tr("Create new empty config"), this, &main_window::create_empty_profile); - profile_menu.addAction(tr("Create new copied config"), this, &main_window::create_copied_profile); - profile_menu.addAction(tr("Open configuration directory"), this, &main_window::open_profile_directory); - ui.profile_button->setMenu(&profile_menu); - - connect(&profile_list_timer, &QTimer::timeout, this, &main_window::refresh_profile_list); - profile_list_timer.start(1000 * 5); - - connect(ui.iconcomboProfile, &QComboBox::currentTextChanged, - this, [this](const QString& x) { main_window::set_profile(x); }); -} - -void main_window::init_tray_menu() -{ - tray_menu.clear(); - - QString display_name(opentrack_version); - if (display_name.startsWith("opentrack-")) - display_name = tr("opentrack") + " " + display_name.mid(sizeof("opentrack-") - 1); - if (display_name.endsWith("-DEBUG")) - display_name.replace(display_name.size() - int(sizeof("DEBUG")), display_name.size(), tr(" (debug)")); - - menu_action_header.setEnabled(false); - menu_action_header.setText(display_name); - menu_action_header.setIcon(QIcon(":/images/opentrack.png")); - tray_menu.addAction(&menu_action_header); - - menu_action_show.setIconVisibleInMenu(true); - menu_action_show.setText(isHidden() ? tr("Show the Octopus") : tr("Hide the Octopus")); - menu_action_show.setIcon(QIcon(":/images/opentrack.png")); - QObject::connect(&menu_action_show, &QAction::triggered, this, [&] { toggle_restore_from_tray(QSystemTrayIcon::Trigger); }); - tray_menu.addAction(&menu_action_show); - - tray_menu.addSeparator(); - - menu_action_tracker.setText(tr("Tracker settings")); - menu_action_tracker.setIcon(QIcon(":/images/tools.png")); - QObject::connect(&menu_action_tracker, &QAction::triggered, this, &main_window::show_tracker_settings); - tray_menu.addAction(&menu_action_tracker); - - menu_action_filter.setText(tr("Filter settings")); - menu_action_filter.setIcon(QIcon(":/images/filter-16.png")); - QObject::connect(&menu_action_filter, &QAction::triggered, this, &main_window::show_filter_settings); - tray_menu.addAction(&menu_action_filter); - - menu_action_proto.setText(tr("Protocol settings")); - menu_action_proto.setIcon(QIcon(":/images/settings16.png")); - QObject::connect(&menu_action_proto, &QAction::triggered, this, &main_window::show_proto_settings); - tray_menu.addAction(&menu_action_proto); - - tray_menu.addSeparator(); - - menu_action_mappings.setIcon(QIcon(":/images/curves.png")); - menu_action_mappings.setText(tr("Mappings")); - QObject::connect(&menu_action_mappings, &QAction::triggered, this, &main_window::show_mapping_window); - tray_menu.addAction(&menu_action_mappings); - - menu_action_options.setIcon(QIcon(":/images/tools.png")); - menu_action_options.setText(tr("Options")); - QObject::connect(&menu_action_options, &QAction::triggered, this, &main_window::show_options_dialog); - tray_menu.addAction(&menu_action_options); - - tray_menu.addSeparator(); - - menu_action_exit.setText(tr("Exit")); - QObject::connect(&menu_action_exit, &QAction::triggered, this, &main_window::exit); - tray_menu.addAction(&menu_action_exit); - - connect(&s.tray_enabled, value_::value_changed(), - this, &main_window::ensure_tray); - - ensure_tray(); -} - -void main_window::init_buttons() -{ - update_button_state(false, false); - connect(ui.btnEditCurves, &QPushButton::clicked, this, &main_window::show_mapping_window); - connect(ui.btnShortcuts, &QPushButton::clicked, this, &main_window::show_options_dialog); - connect(ui.btnShowEngineControls, &QPushButton::clicked, this, &main_window::show_tracker_settings); - connect(ui.btnShowServerControls, &QPushButton::clicked, this, &main_window::show_proto_settings); - connect(ui.btnShowFilterControls, &QPushButton::clicked, this, &main_window::show_filter_settings); - connect(ui.btnStartTracker, &QPushButton::clicked, this, &main_window::start_tracker_); - connect(ui.btnStopTracker, &QPushButton::clicked, this, &main_window::stop_tracker_); -} - -void main_window::register_shortcuts() -{ - global_shortcuts.reload({ - { s.key_start_tracking1, [this](bool) { start_tracker(); }, true }, - { s.key_start_tracking2, [this](bool) { start_tracker(); }, true }, - - { s.key_stop_tracking1, [this](bool) { stop_tracker(); }, true }, - { s.key_stop_tracking2, [this](bool) { stop_tracker(); }, true }, - - { s.key_toggle_tracking1, [this](bool) { toggle_tracker(); }, true }, - { s.key_toggle_tracking2, [this](bool) { toggle_tracker(); }, true }, - - { s.key_restart_tracking1, [this](bool) { restart_tracker(); }, true }, - { s.key_restart_tracking2, [this](bool) { restart_tracker(); }, true }, - }); - - if (work) - work->reload_shortcuts(); -} - -void main_window::die_on_profile_not_writable() -{ - stop_tracker_(); - - static const QString pad(16, QChar(' ')); - - QMessageBox::critical(this, - tr("The Octopus is sad"), - tr("Check permissions for your .ini directory:\n\n\"%1\"%2\n\nExiting now.").arg(ini_directory(), pad), - QMessageBox::Close, QMessageBox::NoButton); - - exit(EX_OSFILE); -} - -bool main_window::profile_name_from_dialog(QString& ret) -{ - new_file_dialog dlg; - dlg.exec(); - return dlg.is_ok(ret); -} - -main_window::~main_window() -{ - // stupid ps3 eye has LED issues - if (work && ui.video_frame->layout()) - { - hide(); - stop_tracker_(); - close(); - - constexpr int inc = 25, max = 1000; - - for (int k = 0; k < max; k += inc) - { - QEventLoop ev; - ev.processEvents(); - portable::sleep(inc); - } - } - - exit(); -} - -void main_window::save_modules() -{ - m.b->save(); -} - -void main_window::create_empty_profile() -{ - QString name; - if (profile_name_from_dialog(name)) - { - QFile(ini_combine(name)).open(QFile::ReadWrite); - refresh_profile_list(); - - if (profile_list.contains(name)) - { - QSignalBlocker q(ui.iconcomboProfile); - - set_profile(name, false); - mark_profile_as_not_needing_migration(); - } - } -} - -void main_window::create_copied_profile() -{ - const QString cur = ini_pathname(); - QString name; - if (!cur.isEmpty() && profile_name_from_dialog(name)) - { - const QString new_name = ini_combine(name); - (void) QFile::remove(new_name); - QFile::copy(cur, new_name); - - refresh_profile_list(); - - if (profile_list.contains(name)) - { - QSignalBlocker q(ui.iconcomboProfile); - - set_profile(name, false); - mark_profile_as_not_needing_migration(); - } - } - -} - -void main_window::open_profile_directory() -{ - QDesktopServices::openUrl("file:///" + QDir::toNativeSeparators(ini_directory())); -} - -void main_window::refresh_profile_list() -{ - if (work) - return; - - QStringList list = ini_list(); - QString current = ini_filename(); - - if (list == profile_list) - return; - - if (!list.contains(current)) - current = OPENTRACK_DEFAULT_PROFILE; - - profile_list = list; - - static const QIcon icon(":/images/settings16.png"); - - QSignalBlocker l(ui.iconcomboProfile); - - ui.iconcomboProfile->clear(); - ui.iconcomboProfile->addItems(list); - - for (int i = 0; i < list.size(); i++) - ui.iconcomboProfile->setItemIcon(i, icon); - - ui.iconcomboProfile->setCurrentText(current); -} - - - -void main_window::update_button_state(bool running, bool inertialp) -{ - bool not_running = !running; - ui.iconcomboProfile->setEnabled(not_running); - ui.btnStartTracker->setEnabled(not_running); - ui.btnStopTracker->setEnabled(running); - ui.iconcomboProtocol->setEnabled(not_running); - ui.iconcomboFilter->setEnabled(not_running); - ui.iconcomboTrackerSource->setEnabled(not_running); - ui.profile_button->setEnabled(not_running); - ui.video_frame_label->setVisible(not_running || inertialp); - if(not_running) - { - ui.video_frame_label->setPixmap(QPixmap(":/images/tracking-not-started.png")); - } - else { - ui.video_frame_label->setPixmap(QPixmap(":/images/no-feed.png")); - } -} - -void main_window::start_tracker_() -{ - if (work) - return; - - work = std::make_shared(pose, ev, ui.video_frame, current_tracker(), current_protocol(), current_filter()); - - if (!work->is_ok()) - { - work = nullptr; - return; - } - - { - double p[6] = {0,0,0, 0,0,0}; - show_pose_(p, p); - } - - if (pTrackerDialog) - pTrackerDialog->register_tracker(work->libs.pTracker.get()); - - if (pFilterDialog) - pFilterDialog->register_filter(work->libs.pFilter.get()); - - if (pProtocolDialog) - pProtocolDialog->register_protocol(work->libs.pProtocol.get()); - - pose_update_timer.start(50); - - // NB check valid since SelectedLibraries ctor called - // trackers take care of layout state updates - const bool is_inertial = ui.video_frame->layout() == nullptr; - update_button_state(true, is_inertial); - - ui.btnStopTracker->setFocus(); -} - -void main_window::stop_tracker_() -{ - if (!work) - return; - - force_is_visible(true); - with_tracker_teardown sentinel; - - pose_update_timer.stop(); - ui.pose_display->present(0,0,0, 0,0,0); - - if (pTrackerDialog) - pTrackerDialog->unregister_tracker(); - - if (pProtocolDialog) - pProtocolDialog->unregister_protocol(); - - if (pFilterDialog) - pFilterDialog->unregister_filter(); - - work = nullptr; - - { - double p[6] {}; - show_pose_(p, p); - } - - update_button_state(false, false); - set_title(); - ui.btnStartTracker->setFocus(); -} - -void main_window::show_pose_(const double* mapped, const double* raw) -{ - ui.pose_display->present(mapped[Yaw], mapped[Pitch], -mapped[Roll], - mapped[TX], mapped[TY], mapped[TZ]); - - QLCDNumber* raw_[] = { - ui.raw_x, ui.raw_y, ui.raw_z, - ui.raw_yaw, ui.raw_pitch, ui.raw_roll, - }; - - QLCDNumber* mapped_[] = { - ui.pose_x, ui.pose_y, ui.pose_z, - ui.pose_yaw, ui.pose_pitch, ui.pose_roll, - }; - - for (int k = 0; k < 6; k++) - { - raw_[k]->display(iround(raw[k])); - mapped_[k]->display(iround(mapped[k])); - } - - QString game_title; - if (work && work->libs.pProtocol) - game_title = work->libs.pProtocol->game_name(); - set_title(game_title); -} - -void main_window::set_title(const QString& game_title) -{ - static const QString version{opentrack_version}; - static const QString sep { tr(" :: ") }; - static const QString pat1{ version + sep + "%1" + sep + "%2" }; - static const QString pat2{ version + sep + "%1" }; - - const QString current = ini_filename(); - - if (game_title.isEmpty()) - setWindowTitle(pat2.arg(current)); - else - setWindowTitle(pat1.arg(current, game_title)); -} - -void main_window::show_pose() -{ - set_is_visible(*this); - - if (mapping_widget) - mapping_widget->refresh_tab(); - - if (!check_is_visible()) - return; - - double mapped[6], raw[6]; - - work->pipeline_.raw_and_mapped_pose(mapped, raw); - - show_pose_(mapped, raw); -} - -static void show_window(QWidget& d, bool fresh) -{ - if (fresh) - { - d.setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | d.windowFlags()); - d.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - - d.show(); - d.adjustSize(); - d.raise(); - } - else - { - d.show(); - d.raise(); - } -} - -template -static bool mk_window_common(std::unique_ptr& d, F&& fun) -{ - bool fresh = false; - - if (!d) - d = fun(), fresh = !!d; - - if (d) - show_window(*d, fresh); - - return fresh; -} - -template -static bool mk_window(std::unique_ptr& place, Args&&... params) -{ - return mk_window_common(place, [&] { - return std::make_unique(params...); - }); -} - -template -static bool mk_dialog(std::unique_ptr& place, const std::shared_ptr& lib) -{ - using u = std::unique_ptr; - - return mk_window_common(place, [&] { - if (lib && lib->Dialog) - return u{ (t*)lib->Dialog() }; - else - return u{}; - }); -} - -void main_window::show_tracker_settings() -{ - if (mk_dialog(pTrackerDialog, current_tracker()) && work && work->libs.pTracker) - pTrackerDialog->register_tracker(work->libs.pTracker.get()); - if (pTrackerDialog) - QObject::connect(pTrackerDialog.get(), &ITrackerDialog::closing, - this, [this] { pTrackerDialog = nullptr; }); -} - -void main_window::show_proto_settings() -{ - if (mk_dialog(pProtocolDialog, current_protocol()) && work && work->libs.pProtocol) - pProtocolDialog->register_protocol(work->libs.pProtocol.get()); - if (pProtocolDialog) - QObject::connect(pProtocolDialog.get(), &IProtocolDialog::closing, - this, [this] { pProtocolDialog = nullptr; }); -} - -void main_window::show_filter_settings() -{ - if (mk_dialog(pFilterDialog, current_filter()) && work && work->libs.pFilter) - pFilterDialog->register_filter(work->libs.pFilter.get()); - if (pFilterDialog) - QObject::connect(pFilterDialog.get(), &IFilterDialog::closing, - this, [this] { pFilterDialog = nullptr; }); -} - -void main_window::show_options_dialog() -{ - if (mk_window(options_widget, [&](bool flag) { set_keys_enabled(!flag); })) - { - // XXX this should logically connect to a bundle - // also doesn't work when switching profiles with options dialog open - // move shortcuts to a separate bundle and add a migration -sh 20180218 - connect(options_widget.get(), &options_dialog::closing, - this, &main_window::register_shortcuts); - } -} - -void main_window::show_mapping_window() -{ - mk_window(mapping_widget, pose); -} - -void main_window::exit(int status) -{ - // don't use std::call_once here, leads to freeze in Microsoft's CRT - // this function never needs reentrancy anyway - - // this is probably harmless, but better safe than sorry - if (exiting_already) - return; - exiting_already = true; - - qDebug() << "opentrack: exiting"; - - if (tray) - tray->hide(); - tray = nullptr; - - //close(); - QApplication::setQuitOnLastWindowClosed(true); - QApplication::exit(status); -} - -void main_window::set_profile(const QString& new_name_, bool migrate) -{ - QSignalBlocker b(ui.iconcomboProfile); - - QString new_name = new_name_; - - if (!profile_list.contains(new_name)) - { - new_name = OPENTRACK_DEFAULT_PROFILE; - if (!profile_list.contains(new_name)) - migrate = false; - } - - const bool status = new_name != ini_filename(); - - if (status) - set_profile_in_registry(new_name); - - using bundler = options::detail::bundler; - - bundler::reload_no_notify(); - - if (migrate) - // migrations are for config layout changes and other user-visible - // incompatibilities in future versions - run_migrations(); - else - mark_profile_as_not_needing_migration(); - - bundler::notify(); - - set_title(); - - if (status) - ui.iconcomboProfile->setCurrentText(new_name); -} - -void main_window::ensure_tray() -{ - if (!QSystemTrayIcon::isSystemTrayAvailable()) - { - QApplication::setQuitOnLastWindowClosed(true); - return; - } - - if (s.tray_enabled) - { - if (!tray) - { - tray = std::make_unique(this); - tray->setIcon(QIcon(":/images/opentrack.png")); - tray->setContextMenu(&tray_menu); - tray->show(); - - connect(tray.get(), - &QSystemTrayIcon::activated, - this, - &main_window::toggle_restore_from_tray); - } - - QApplication::setQuitOnLastWindowClosed(false); - } - else - { - if (!isVisible()) - { - show(); - setVisible(true); - - raise(); // for OSX - activateWindow(); // for Windows - } - - if (tray) - tray->hide(); - tray = nullptr; - - QApplication::setQuitOnLastWindowClosed(true); - } -} - -void main_window::toggle_restore_from_tray(QSystemTrayIcon::ActivationReason e) -{ - switch (e) - { - // if we enable double click also then it causes - // toggle back to the original state - //case QSystemTrayIcon::DoubleClick: - case QSystemTrayIcon::Trigger: // single click - break; - default: - return; - } - - ensure_tray(); - - const bool is_minimized = isHidden() || !tray_enabled(); - - menu_action_show.setText(!isHidden() ? tr("Show the Octopus") : tr("Hide the Octopus")); - - setVisible(is_minimized); - setHidden(!is_minimized); - - setWindowState(is_minimized ? windowState() & ~Qt::WindowMinimized : Qt::WindowNoState); - - if (is_minimized) - { - raise(); // for OSX - activateWindow(); // for Windows - } - else - { - lower(); - clearFocus(); - } -} - -bool main_window::maybe_hide_to_tray(QEvent* e) -{ - if (e->type() == QEvent::WindowStateChange && - (windowState() & Qt::WindowMinimized) && - tray_enabled()) - { - e->accept(); - ensure_tray(); - hide(); - - return true; - } - - return false; -} - -void main_window::closeEvent(QCloseEvent*) -{ - exit(); -} - -void main_window::maybe_start_profile_from_executable() -{ - if (!work) - { - QString profile; - if (det.profile_to_start(profile) && profile_list.contains(profile)) - { - set_profile(profile); - start_tracker_(); - } - } - else - { - if (det.should_stop()) - stop_tracker_(); - } -} - -void main_window::set_keys_enabled(bool flag) -{ - if (!flag) - { - if (work) - work->sc.reload({}); - global_shortcuts.reload({}); - } - else - register_shortcuts(); -} - -void main_window::changeEvent(QEvent* e) -{ - if (!maybe_hide_to_tray(e)) - e->ignore(); -} - -bool main_window::event(QEvent* event) -{ - using t = QEvent::Type; - - if (work) - { - switch (event->type()) - { - case t::Hide: - case t::WindowActivate: - case t::WindowDeactivate: - case t::WindowStateChange: - case t::FocusIn: - set_is_visible(*this, true); - break; - default: - break; - } - } - return QMainWindow::event(event); -} - -bool main_window::tray_enabled() -{ - return s.tray_enabled && QSystemTrayIcon::isSystemTrayAvailable(); -} - -bool main_window::start_in_tray() -{ - return tray_enabled() && s.tray_start; -} - -void main_window::set_profile_in_registry(const QString &profile) -{ - with_global_settings_object([&](QSettings& s) { - s.setValue(OPENTRACK_PROFILE_FILENAME_KEY, profile); - }); -} - -void main_window::restart_tracker_() -{ - qDebug() << "restart tracker"; - - stop_tracker_(); - start_tracker_(); -} - -void main_window::toggle_tracker_() -{ - qDebug() << "toggle tracker"; - - if (work) - stop_tracker_(); - else - start_tracker_(); -} - -#if !defined _WIN32 -# include -void main_window::annoy_if_root() -{ - if (geteuid() == 0) - { - struct lst { - QString caption; - QString msg; - int sleep_ms; - }; - - const lst list[] = { - { - tr("Running as root is bad"), - tr("Do not run as root. Set correct device node permissions."), - 1000, - }, - { - tr("Running as root is bad, seriously"), - tr("Do not run as root. I'll keep whining at every startup."), - 3000, - }, - { - tr("Be annoyed, comprehensively."), - tr("Don't run as root to remove these annoying messages."), - 0 - } - }; - - for (const auto& x : list) - { - QMessageBox::critical(this, x.caption, x.msg, QMessageBox::Ok); - portable::sleep(x.sleep_ms); - } - } -} -#endif diff --git a/variant/default/main-window.hpp b/variant/default/main-window.hpp deleted file mode 100644 index 9ffb7019..00000000 --- a/variant/default/main-window.hpp +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright (c) 2013-2016, Stanislaw Halik - - * Permission to use, copy, modify, and/or distribute this - * software for any purpose with or without fee is hereby granted, - * provided that the above copyright notice and this permission - * notice appear in all copies. - */ - -#pragma once - -#include "api/plugin-support.hpp" -#include "gui/mapping-dialog.hpp" -#include "gui/settings.hpp" -#include "gui/process_detector.h" -#include "logic/main-settings.hpp" -#include "logic/pipeline.hpp" -#include "logic/shortcuts.h" -#include "logic/work.hpp" -#include "logic/state.hpp" -#include "options/options.hpp" -#include "compat/qt-signal.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "ui_main-window.h" - -class main_window final : public QMainWindow, private State -{ - Q_DECLARE_TR_FUNCTIONS(main_window) - - Ui::main_window ui; - - std::unique_ptr tray; - QMenu tray_menu { this }; - - QTimer pose_update_timer { this }; - QTimer det_timer; - QTimer profile_list_timer; - - Shortcuts global_shortcuts; - QShortcut kbd_quit { QKeySequence("Ctrl+Q"), this }; - - std::unique_ptr options_widget; - std::unique_ptr mapping_widget; - - std::unique_ptr pFilterDialog; - std::unique_ptr pProtocolDialog; - std::unique_ptr pTrackerDialog; - - process_detector_worker det; - QMenu profile_menu; - - QList profile_list; - - QAction menu_action_header { &tray_menu }, - menu_action_show { &tray_menu }, - menu_action_exit { &tray_menu }, - menu_action_tracker { &tray_menu }, - menu_action_filter { &tray_menu }, - menu_action_proto { &tray_menu }, - menu_action_options { &tray_menu }, - menu_action_mappings { &tray_menu }; - - bool exiting_already { false }; - - qt_sig::nullary start_tracker { this, &main_window::start_tracker_, Qt::QueuedConnection }; - qt_sig::nullary stop_tracker { this, &main_window::stop_tracker_, Qt::QueuedConnection }; - qt_sig::nullary toggle_tracker { this, &main_window::toggle_tracker_, Qt::QueuedConnection }; - qt_sig::nullary restart_tracker { this, &main_window::restart_tracker_, Qt::QueuedConnection }; - - void init_dylibs(); - void init_tray_menu(); - void init_profiles(); - void init_buttons(); - - void init_shortcuts(); - void register_shortcuts(); - void set_keys_enabled(bool flag); - - void update_button_state(bool running, bool inertialp); - -#if !defined _WIN32 - void annoy_if_root(); -#endif - - void changeEvent(QEvent* e) override; - bool maybe_hide_to_tray(QEvent* e); - void closeEvent(QCloseEvent *event) override; - bool event(QEvent *event) override; - - void show_tracker_settings(); - void show_proto_settings(); - void show_filter_settings(); - - void show_options_dialog(); - void show_mapping_window(); - - void show_pose(); - void show_pose_(const double* mapped, const double* raw); - void set_title(const QString& game_title = QString()); - - void start_tracker_(); - void stop_tracker_(); - void restart_tracker_(); - void toggle_tracker_(); - - void set_profile(const QString& new_name, bool migrate = true); - void set_profile_in_registry(const QString& profile); - void refresh_profile_list(); - void die_on_profile_not_writable(); - void maybe_start_profile_from_executable(); - [[nodiscard]] static bool profile_name_from_dialog(QString& ret); - - void create_empty_profile(); - void create_copied_profile(); - void open_profile_directory(); - - void ensure_tray(); - void toggle_restore_from_tray(QSystemTrayIcon::ActivationReason e); - bool tray_enabled(); - bool start_in_tray(); - - void save_modules(); - - void exit(int status = EXIT_SUCCESS); - -public: - main_window(); - ~main_window() override; -}; diff --git a/variant/default/main-window.ui b/variant/default/main-window.ui deleted file mode 100644 index 7aab90e8..00000000 --- a/variant/default/main-window.ui +++ /dev/null @@ -1,1459 +0,0 @@ - - - Lovecraftian Octopus - main_window - - - - 0 - 0 - 646 - 517 - - - - - :/images/opentrack.png:/images/opentrack.png - - - #video_feed { border: 0; } - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 6 - - - 6 - - - - - QFrame::NoFrame - - - QFrame::Raised - - - 0 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 4 - - - - - - 0 - 0 - - - - - 320 - 240 - - - - - 320 - 240 - - - - 0 - - - - - 0 - 0 - 320 - 240 - - - - - 0 - 0 - - - - - 320 - 240 - - - - - 320 - 240 - - - - - - 0 - 0 - 320 - 240 - - - - - 0 - 0 - - - - - 320 - 240 - - - - - 320 - 240 - - - - - Candara - 37 - 50 - false - true - - - - - - - :/images/tracking-not-started.png - - - false - - - Qt::AlignCenter - - - true - - - - - - - - - - 0 - 0 - - - - - 320 - 240 - - - - - 320 - 240 - - - - - - - - - - - - 0 - 0 - - - - QFrame::NoFrame - - - 0 - - - - 6 - - - 5 - - - 0 - - - 0 - - - 6 - - - - - - 0 - 0 - - - - Raw tracker data - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - - 0 - 0 - - - - - NoAntialias - false - - - - QFrame::NoFrame - - - QFrame::Plain - - - 1 - - - true - - - 4 - - - QLCDNumber::Outline - - - - - - - true - - - - 0 - 0 - - - - false - - - QFrame::Raised - - - Z - - - - - - - - 0 - 0 - - - - QFrame::Raised - - - Pitch - - - - - - - true - - - - 0 - 0 - - - - - NoAntialias - false - - - - QFrame::NoFrame - - - QFrame::Plain - - - 1 - - - true - - - 4 - - - QLCDNumber::Outline - - - - - - - true - - - - 0 - 0 - - - - false - - - QFrame::Raised - - - Y - - - - - - - - 0 - 0 - - - - QFrame::Raised - - - X - - - - - - - true - - - - 0 - 0 - - - - - NoAntialias - false - - - - QFrame::NoFrame - - - QFrame::Plain - - - 1 - - - true - - - 4 - - - QLCDNumber::Outline - - - - - - - - 0 - 0 - - - - QFrame::Raised - - - Roll - - - - - - - - 0 - 0 - - - - QFrame::Raised - - - Yaw - - - - - - - true - - - - 0 - 0 - - - - - NoAntialias - false - - - - QFrame::NoFrame - - - QFrame::Plain - - - 1 - - - true - - - 4 - - - QLCDNumber::Outline - - - - - - - true - - - - 0 - 0 - - - - - NoAntialias - false - - - - QFrame::NoFrame - - - QFrame::Plain - - - 1 - - - true - - - 4 - - - QLCDNumber::Outline - - - - - - - true - - - - 0 - 0 - - - - - NoAntialias - false - - - - QFrame::NoFrame - - - QFrame::Plain - - - 1 - - - true - - - 4 - - - QLCDNumber::Outline - - - - - - - - - - - 0 - 0 - - - - Game data - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - - 0 - 0 - - - - - NoAntialias - false - - - - QFrame::NoFrame - - - true - - - 4 - - - QLCDNumber::Flat - - - - - - - true - - - - 0 - 0 - - - - - NoAntialias - false - - - - QFrame::NoFrame - - - true - - - 4 - - - QLCDNumber::Flat - - - - - - - true - - - - 0 - 0 - - - - - NoAntialias - false - - - - QFrame::NoFrame - - - true - - - 4 - - - QLCDNumber::Flat - - - - - - - - 0 - 0 - - - - QFrame::Raised - - - X - - - - - - - true - - - - 0 - 0 - - - - false - - - QFrame::Raised - - - Y - - - - - - - true - - - - 0 - 0 - - - - - NoAntialias - false - - - - QFrame::NoFrame - - - true - - - 4 - - - QLCDNumber::Flat - - - - - - - - 0 - 0 - - - - QFrame::Raised - - - Pitch - - - - - - - - 0 - 0 - - - - QFrame::Raised - - - Roll - - - - - - - - 0 - 0 - - - - QFrame::Raised - - - Yaw - - - - - - - true - - - - 0 - 0 - - - - false - - - QFrame::Raised - - - Z - - - - - - - true - - - - 0 - 0 - - - - - NoAntialias - false - - - - QFrame::NoFrame - - - true - - - 4 - - - QLCDNumber::Flat - - - - - - - true - - - - 0 - 0 - - - - - NoAntialias - false - - - - QFrame::NoFrame - - - true - - - 4 - - - QLCDNumber::Flat - - - - - - - - - - - - - - 0 - 0 - - - - - 6 - - - 0 - - - 0 - - - 0 - - - 6 - - - - - - 4 - 0 - - - - 0 - - - - 3 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - - 0 - 0 - - - - Qt::StrongFocus - - - Profile - - - QToolButton::InstantPopup - - - Qt::ToolButtonTextBesideIcon - - - true - - - Qt::DownArrow - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - 20 - - - - - - - - - - - 0 - 0 - - - - Options - - - - :/images/tools.png:/images/tools.png - - - - 80 - 24 - - - - - - - - - 0 - 0 - - - - Mapping - - - - :/images/curves.png:/images/curves.png - - - - 80 - 24 - - - - - - - - - 3 - 0 - - - - Tracking - - - true - - - - 8 - - - 0 - - - 6 - - - 0 - - - 6 - - - - - - 0 - 0 - - - - - 75 - true - - - - Start - - - - - - - false - - - - 0 - 0 - - - - - 75 - true - - - - Stop - - - - - - - - - - - - - - 4 - 0 - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 2 - - - 3 - - - 2 - - - 3 - - - 8 - - - - - Input - - - - 4 - - - 0 - - - 0 - - - 0 - - - 3 - - - 0 - - - - - - 0 - 0 - - - - Qt::TabFocus - - - - - - - true - - - - 0 - 0 - - - - - DejaVu Sans - PreferAntialias - false - - - - Qt::ClickFocus - - - 🔨 - - - false - - - - - - - - - - Output - - - - 4 - - - 0 - - - 0 - - - 0 - - - 3 - - - 0 - - - - - - 0 - 0 - - - - Qt::TabFocus - - - - - - - true - - - - 0 - 0 - - - - - DejaVu Sans - PreferAntialias - false - - - - Qt::ClickFocus - - - 🔨 - - - false - - - - - - - - - - Filter - - - - 4 - - - 0 - - - 0 - - - 0 - - - 3 - - - 0 - - - - - - 0 - 0 - - - - Qt::TabFocus - - - - - - - true - - - - 0 - 0 - - - - - DejaVu Sans - PreferAntialias - false - - - - Qt::ClickFocus - - - 🔨 - - - false - - - - - - - - - - - - - - - - - - - - - pose_widget - QWidget -
pose-widget/pose-widget.hpp
-
-
- - btnStartTracker - btnStopTracker - profile_button - iconcomboProfile - btnShortcuts - btnEditCurves - - - - - -
diff --git a/variant/default/main.cpp b/variant/default/main.cpp deleted file mode 100644 index 2c1dc607..00000000 --- a/variant/default/main.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "gui/init.hpp" -#include "main-window.hpp" - -#if defined _WIN32 -# include -#endif - -#ifdef __clang__ -# pragma GCC diagnostic ignored "-Wmain" -#endif - -int main(int argc, char** argv) -{ - return run_application(argc, argv, [] { return std::make_unique(); }); -} - -#if defined _MSC_VER - -int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int /* nCmdShow */) -{ - return main(__argc, __argv); -} -#endif diff --git a/variant/default/new_config.ui b/variant/default/new_config.ui deleted file mode 100644 index a262e725..00000000 --- a/variant/default/new_config.ui +++ /dev/null @@ -1,45 +0,0 @@ - - - UI_new_config - - - Qt::ApplicationModal - - - - 0 - 0 - 269 - 67 - - - - Config filename - - - - images/opentrack.pngimages/opentrack.png - - - - - - New file name: - - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - diff --git a/variant/default/new_file_dialog.cpp b/variant/default/new_file_dialog.cpp deleted file mode 100644 index 70816c5d..00000000 --- a/variant/default/new_file_dialog.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "new_file_dialog.h" - -new_file_dialog::new_file_dialog(QWidget* parent) : QDialog(parent) -{ - ui.setupUi(this); - connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(ok_clicked())); - connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(cancel_clicked())); - setFixedSize(size()); -} - -bool new_file_dialog::is_ok(QString& name_) -{ - name_ = name; - return ok; -} - -void new_file_dialog::cancel_clicked() { close(); } - -void new_file_dialog::ok_clicked() -{ - QString text = ui.lineEdit->text(); - text = text.replace('/', ""); - text = text.replace('\\', ""); - if (text != "" && !text.endsWith(".ini")) - text += ".ini"; - if (text == "" || text == ".ini" || QFile(options::globals::ini_directory() + "/" + text).exists()) - { - QMessageBox::warning(this, - tr("File exists"), - tr("This file already exists. Pick another name."), - QMessageBox::Ok, QMessageBox::NoButton); - return; - } - ok = true; - close(); - name = text; -} diff --git a/variant/default/new_file_dialog.h b/variant/default/new_file_dialog.h deleted file mode 100644 index 7244e524..00000000 --- a/variant/default/new_file_dialog.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "ui_new_config.h" -#include "options/options.hpp" -#include -#include -#include -#include - -class new_file_dialog : public QDialog -{ - Q_OBJECT -public: - new_file_dialog(QWidget* parent = nullptr); - bool is_ok(QString& name_); - -private: - Ui::UI_new_config ui; - bool ok = false; - QString name; - -private slots: - void cancel_clicked(); - void ok_clicked(); -}; diff --git a/variant/default/opentrack.ico b/variant/default/opentrack.ico deleted file mode 100644 index 5cac8da1..00000000 Binary files a/variant/default/opentrack.ico and /dev/null differ diff --git a/variant/default/resources.rc b/variant/default/resources.rc deleted file mode 100644 index 6fd0253b..00000000 --- a/variant/default/resources.rc +++ /dev/null @@ -1,2 +0,0 @@ -#include -IDI_ICON1 ICON "opentrack.ico" diff --git a/variant/trackmouse/CMakeLists.txt b/variant/trackmouse/CMakeLists.txt deleted file mode 100644 index 6240d4b3..00000000 --- a/variant/trackmouse/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -otr_module(executable EXECUTABLE BIN) - -set_target_properties(opentrack-executable PROPERTIES - SUFFIX "${opentrack-binary-suffix}" - OUTPUT_NAME "trackmouse" - PREFIX "" -) - -target_link_libraries(${self} opentrack-user-interface opentrack-version) diff --git a/variant/trackmouse/_variant.cmake b/variant/trackmouse/_variant.cmake index 404c28ec..1a65f6df 100644 --- a/variant/trackmouse/_variant.cmake +++ b/variant/trackmouse/_variant.cmake @@ -16,6 +16,7 @@ function(otr_init_variant) "migration" "executable" "pose-widget" + "trackmouse" ) set_property(GLOBAL PROPERTY opentrack-subprojects "${subprojects}") endfunction() diff --git a/variant/trackmouse/images/start.png b/variant/trackmouse/images/start.png deleted file mode 100644 index b8e6f271..00000000 Binary files a/variant/trackmouse/images/start.png and /dev/null differ diff --git a/variant/trackmouse/images/stop.png b/variant/trackmouse/images/stop.png deleted file mode 100644 index 0ff13bd5..00000000 Binary files a/variant/trackmouse/images/stop.png and /dev/null differ diff --git a/variant/trackmouse/lang/nl_NL.ts b/variant/trackmouse/lang/nl_NL.ts deleted file mode 100644 index 92f790af..00000000 --- a/variant/trackmouse/lang/nl_NL.ts +++ /dev/null @@ -1,74 +0,0 @@ - - - - - main_window - - The Octopus is sad - - - - :: - - - - Check permissions for your .ini directory: - -%1"%2 - -Exiting now. - - - - - window - - trackmouse prototype - - - - Keyboard shortcuts - - - - start/stop tracking - - - - Alt+F10 - - - - center - - - - Alt+F11 - - - - Alt+F12 - - - - Sensitivity - - - - 100% - - - - Start - - - - Stop - - - - freeze toggle - - - - diff --git a/variant/trackmouse/lang/ru_RU.ts b/variant/trackmouse/lang/ru_RU.ts deleted file mode 100644 index dd9011c4..00000000 --- a/variant/trackmouse/lang/ru_RU.ts +++ /dev/null @@ -1,74 +0,0 @@ - - - - - main_window - - The Octopus is sad - - - - :: - - - - Check permissions for your .ini directory: - -%1"%2 - -Exiting now. - - - - - window - - trackmouse prototype - - - - Keyboard shortcuts - - - - start/stop tracking - - - - Alt+F10 - - - - center - - - - Alt+F11 - - - - Alt+F12 - - - - Sensitivity - - - - 100% - - - - Start - - - - Stop - - - - freeze toggle - - - - diff --git a/variant/trackmouse/lang/stub.ts b/variant/trackmouse/lang/stub.ts deleted file mode 100644 index 968e31c5..00000000 --- a/variant/trackmouse/lang/stub.ts +++ /dev/null @@ -1,74 +0,0 @@ - - - - - main_window - - The Octopus is sad - - - - :: - - - - Check permissions for your .ini directory: - -%1"%2 - -Exiting now. - - - - - window - - trackmouse prototype - - - - Keyboard shortcuts - - - - start/stop tracking - - - - Alt+F10 - - - - center - - - - Alt+F11 - - - - Alt+F12 - - - - Sensitivity - - - - 100% - - - - Start - - - - Stop - - - - freeze toggle - - - - diff --git a/variant/trackmouse/lang/zh_CN.ts b/variant/trackmouse/lang/zh_CN.ts deleted file mode 100644 index 968e31c5..00000000 --- a/variant/trackmouse/lang/zh_CN.ts +++ /dev/null @@ -1,74 +0,0 @@ - - - - - main_window - - The Octopus is sad - - - - :: - - - - Check permissions for your .ini directory: - -%1"%2 - -Exiting now. - - - - - window - - trackmouse prototype - - - - Keyboard shortcuts - - - - start/stop tracking - - - - Alt+F10 - - - - center - - - - Alt+F11 - - - - Alt+F12 - - - - Sensitivity - - - - 100% - - - - Start - - - - Stop - - - - freeze toggle - - - - diff --git a/variant/trackmouse/main.cpp b/variant/trackmouse/main.cpp deleted file mode 100644 index 2313e1ac..00000000 --- a/variant/trackmouse/main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "gui/init.hpp" -#include "window.hpp" - -#if defined _WIN32 -# include -#endif - -int main(int argc, char** argv) -{ - return run_application(argc, argv, []() { return new main_window; }); -} - -#if defined _MSC_VER -int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int /* nCmdShow */) -{ - return main(__argc, __argv); -} -#endif diff --git a/variant/trackmouse/trackmouse-res.qrc b/variant/trackmouse/trackmouse-res.qrc deleted file mode 100644 index f351b3f2..00000000 --- a/variant/trackmouse/trackmouse-res.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - images/start.png - images/stop.png - - diff --git a/variant/trackmouse/trackmouse-settings.cpp b/variant/trackmouse/trackmouse-settings.cpp deleted file mode 100644 index 45ec36a5..00000000 --- a/variant/trackmouse/trackmouse-settings.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include "logic/main-settings.hpp" -#include "logic/mappings.hpp" - -#include "tracker-pt/pt-settings.hpp" -#include "filter-accela/accela-settings.hpp" -#include "proto-mouse/mouse-settings.hpp" - -#include "options/options.hpp" - -#include - -using namespace options; - -static void force_spline_settings() -{ - main_settings main; - - axis_opts** all_axis_opts = main.all_axis_opts; - Mappings mappings { all_axis_opts }; - - for (unsigned k = 0; k < 6; k++) - { - Map& map = mappings(k); - const QString& prefix = all_axis_opts[k]->prefix(); - - const QString& name1 = map.name; - const QString& name2 = map.alt_name; - - bundle b = make_bundle(prefix); - - spline_detail::settings s1(b, name1, Axis(k)); - spline_detail::settings s2(b, name2, Axis(k)); - - s1.points = QList { { 180, 180 } }; - s2.points = QList { { 180, 180 } }; - - b->save(); - } -} - -static void force_main_settings() -{ - main_settings s; - s.center_at_startup = true; - s.reltrans_mode = reltrans_disabled; - s.neck_enable = false; - - module_settings m; - - m.tracker_dll = "pt"; - m.protocol_dll = "win32-mouse"; - m.filter_dll = "accela"; - - s.b->save(); - s.b_map->save(); -} - -static void force_pt_settings() -{ - pt_settings s("tracker-pt"); - - enum { Clip = 0 }; - - s.active_model_panel = Clip; - // XXX TODO these are Mini Clip Right sizes - s.clip_by = 60; - s.clip_bz = 38.2; - s.clip_ty = 42.2; - s.clip_tz = 12.6; - - s.cam_fps = 60; - s.cam_res_x = 640; - s.cam_res_y = 480; - s.camera_name = "PS3Eye Camera"; - - s.min_point_size = 3.7; - s.max_point_size = 10; - - // XXX TODO auto threshold slider position - s.auto_threshold = true; - s.threshold_slider = slider_value(82., s.threshold_slider->min(), s.threshold_slider->max()); - - s.t_MH_x = 0, s.t_MH_y = 0, s.t_MH_z = 0; - s.blob_color = pt_color_natural; - s.fov = 56; - s.dynamic_pose = false; - - s.b->save(); -} - -static void force_mouse_settings() -{ - - mouse_settings s; - - s.Mouse_X = Yaw + 1; - s.Mouse_Y = Pitch + 1; - - s.b->save(); -} - -static void force_accela_settings() -{ - // XXX TODO -} - -static void force_shortcut_settings() -{ - main_settings s; - s.key_toggle_tracking1.keycode = "Ins"; - s.key_center1.keycode = "PgUp"; - s.key_toggle1.keycode = "PgDown"; - - for (key_opts* k : { &s.key_toggle_tracking1, &s.key_center1, &s.key_toggle_press1 }) - { - k->button = -1; - k->guid = {}; - } - s.b->save(); -} - -void force_trackmouse_settings() -{ - options::globals::with_settings_object([](QSettings&) { - force_main_settings(); - force_spline_settings(); - force_pt_settings(); - force_mouse_settings(); - force_accela_settings(); - force_shortcut_settings(); - }); -} diff --git a/variant/trackmouse/trackmouse.ico b/variant/trackmouse/trackmouse.ico deleted file mode 100644 index 5cac8da1..00000000 Binary files a/variant/trackmouse/trackmouse.ico and /dev/null differ diff --git a/variant/trackmouse/trackmouse.rc b/variant/trackmouse/trackmouse.rc deleted file mode 100644 index 8df1e9b1..00000000 --- a/variant/trackmouse/trackmouse.rc +++ /dev/null @@ -1,2 +0,0 @@ -#include -IDI_ICON1 ICON "trackmouse.ico" diff --git a/variant/trackmouse/window.cpp b/variant/trackmouse/window.cpp deleted file mode 100644 index d6c8a8dd..00000000 --- a/variant/trackmouse/window.cpp +++ /dev/null @@ -1,388 +0,0 @@ -/* Copyright (c) 2013-2018, Stanislaw Halik - - * Permission to use, copy, modify, and/or distribute this - * software for any purpose with or without fee is hereby granted, - * provided that the above copyright notice and this permission - * notice appear in all copies. - */ - -#include "window.hpp" -#include "options/options.hpp" -#include "migration/migration.hpp" -#include "compat/check-visible.hpp" -#include "compat/sleep.hpp" -#include "compat/macros.hpp" -#include "compat/library-path.hpp" -#include "compat/math.hpp" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -extern "C" const char* const opentrack_version; - -using namespace options::globals; -using namespace options; - -#if !defined EXIT_SUCCESS -# define EXIT_SUCCESS 0 -#endif - -#if !defined EXIT_FAILURE -# define EXIT_FAILURE 1 -#endif - -/* FreeBSD sysexits(3) - * - * The input data was incorrect in some way. This - * should only be used for user's data and not system - * files. - */ - -#if !defined EX_OSFILE -# define EX_OSFILE 72 -#endif - -void force_trackmouse_settings(); - -main_window::main_window() : State(OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH) -{ - ui.setupUi(this); - - update_button_state(false, false); - - // ctrl+q exits - connect(&kbd_quit, SIGNAL(activated()), this, SLOT(exit())); - - if (!set_profile()) - { - die_on_config_not_writable(); - exit(EX_OSFILE); - return; - } - - // only tie and connect main screen options after migrations are done - // below is fine, set_profile() is called already - - connect(this, &main_window::start_tracker, - this, [&] { qDebug() << "start tracker"; start_tracker_(); }, - Qt::QueuedConnection); - - connect(this, &main_window::stop_tracker, - this, [&] { qDebug() << "stop tracker"; stop_tracker_(); }, - Qt::QueuedConnection); - - connect(this, &main_window::toggle_tracker, - this, [&] { qDebug() << "toggle tracker"; toggle_tracker_(); }, - Qt::QueuedConnection); - - connect(ui.btnStartTracker, SIGNAL(clicked()), this, SLOT(start_tracker_())); - connect(ui.btnStopTracker, SIGNAL(clicked()), this, SLOT(stop_tracker_())); - - { - tie_setting(mouse.sensitivity_x, ui.sensitivity_slider); - tie_setting(mouse.sensitivity_x, ui.sensitivity_label, - [](double x) { return QString::number(x) + QStringLiteral("%"); }); - // one-way only - tie_setting(mouse.sensitivity_x, this, - [this](double x) { mouse.sensitivity_y = *mouse.sensitivity_x; }); - - // no "ok" button, gotta save on timer - auto save = [this] { - qDebug() << "trackmouse: saving settings"; - mouse.b->save(); - save_settings_timer.stop(); - }; - - auto start_save_timer = [this](double) { - save_settings_timer.start(); - }; - - save_settings_timer.setInterval(save_settings_interval_ms); - save_settings_timer.setSingleShot(true); - - ui.sensitivity_slider->setTracking(false); - connect(&save_settings_timer, &QTimer::timeout, this, save, Qt::DirectConnection); -#if 1 - // this doesn't fire the timer on application load - connect(ui.sensitivity_slider, &QSlider::valueChanged, this, start_save_timer, Qt::DirectConnection); -#else - // but this does so let's not not use it - tie_setting(mouse.sensitivity_x, this, start_save_timer); -#endif - } - - force_trackmouse_settings(); - - register_shortcuts(); - kbd_quit.setEnabled(true); - - setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | windowFlags()); - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - adjustSize(); - - setVisible(true); - show(); -} - -void main_window::register_shortcuts() -{ - global_shortcuts.reload({ - { s.key_toggle_tracking1, [this](bool) { main_window::toggle_tracker(); }, true }, - }); - - if (work) - work->reload_shortcuts(); -} - -void main_window::die_on_config_not_writable() -{ - stop_tracker_(); - - static const QString pad(16, QChar(' ')); - - QMessageBox::critical(this, - tr("The Octopus is sad"), - tr("Check permissions for your .ini directory:\n\n%1\"%2\n\n" - "Exiting now." - ).arg(ini_directory(), pad), - QMessageBox::Close, QMessageBox::NoButton); - - exit(EX_OSFILE); -} - -bool main_window::maybe_die_on_config_not_writable(const QString& current) -{ - const bool writable = - with_settings_object([&](QSettings& s) { - return s.isWritable(); - }); - - if (writable) - return false; - - if (!QFile(ini_combine(current)).open(QFile::ReadWrite)) - { - die_on_config_not_writable(); - return true; - } - - return false; -} - -main_window::~main_window() -{ - // stupid ps3 eye has LED issues - if (work) - { - stop_tracker_(); - close(); - - constexpr int inc = 100, max = 2000; - - for (int k = 0; k < max; k += inc) - { - QEventLoop ev; - ev.processEvents(); - portable::sleep(inc); - } - } - - exit(); -} - -void main_window::set_working_directory() -{ - QDir::setCurrent(OPENTRACK_BASE_PATH); -} - -void main_window::save_modules() -{ - m.b->save(); -} - -std::tuple -main_window::module_by_name(const QString& name, Modules::dylib_list& list) -{ - auto it = std::find_if(list.cbegin(), list.cend(), [&name](const dylib_ptr& lib) { - if (!lib) - return name.isEmpty(); - else - return name == lib->module_name; - }); - - if (it == list.cend()) - return { nullptr, -1 }; - else - return { *it, std::distance(list.cbegin(), it) }; -} - -main_window::dylib_ptr main_window::current_tracker() -{ - auto [ptr, idx] = module_by_name(m.tracker_dll, modules.trackers()); - return ptr; -} - -main_window::dylib_ptr main_window::current_protocol() -{ - auto [ptr, idx] = module_by_name(m.protocol_dll, modules.protocols()); - return ptr; -} - -main_window::dylib_ptr main_window::current_filter() -{ - auto [ptr, idx] = module_by_name(m.filter_dll, modules.filters()); - return ptr; -} - -void main_window::update_button_state(bool running, bool inertialp) -{ - bool not_running = !running; -#if 0 - ui.iconcomboProfile->setEnabled(not_running); - ui.btnStartTracker->setEnabled(not_running); - ui.btnStopTracker->setEnabled(running); - ui.iconcomboProtocol->setEnabled(not_running); - ui.iconcomboFilter->setEnabled(not_running); - ui.iconcomboTrackerSource->setEnabled(not_running); - ui.profile_button->setEnabled(not_running); -#endif - ui.video_frame_label->setVisible(not_running || inertialp); - if(not_running) - { - ui.video_frame_label->setPixmap(QPixmap(":/images/tracking-not-started.png")); - } - else { - ui.video_frame_label->setPixmap(QPixmap(":/images/no-feed.png")); - } -} - -void main_window::start_tracker_() -{ - if (work) - return; - - work = std::make_shared(pose, ev, ui.video_frame, current_tracker(), current_protocol(), current_filter()); - - if (!work->is_ok()) - { - work = nullptr; - return; - } - - if (pTrackerDialog) - pTrackerDialog->register_tracker(work->libs.pTracker.get()); - - if (pFilterDialog) - pFilterDialog->register_filter(work->libs.pFilter.get()); - - if (pProtocolDialog) - pProtocolDialog->register_protocol(work->libs.pProtocol.get()); - - // NB check valid since SelectedLibraries ctor called - // trackers take care of layout state updates - const bool is_inertial = ui.video_frame->layout() == nullptr; - update_button_state(true, is_inertial); - - ui.btnStopTracker->setFocus(); -} - -void main_window::stop_tracker_() -{ - if (!work) - return; - - with_tracker_teardown sentinel; - - if (pTrackerDialog) - pTrackerDialog->unregister_tracker(); - - if (pProtocolDialog) - pProtocolDialog->unregister_protocol(); - - if (pFilterDialog) - pFilterDialog->unregister_filter(); - - work = nullptr; - - update_button_state(false, false); - set_title(); - ui.btnStartTracker->setFocus(); -} - -void main_window::set_title(const QString& game_title) -{ - static const QString version{opentrack_version}; - static const QString sep { tr(" :: ") }; - static const QString pat1{ version + sep + "%1" + sep + "%2" }; - static const QString pat2{ version + sep + "%1" }; - - const QString current = ini_filename(); - - if (game_title.isEmpty()) - setWindowTitle(pat2.arg(current)); - else - setWindowTitle(pat1.arg(current, game_title)); -} - -void main_window::exit(int status) -{ - if (exiting_already) - return; - exiting_already = true; - - qDebug() << "trackmouse: saving settings on app exit"; - save_settings_timer.stop(); - mouse.b->save(); - - //close(); - QApplication::setQuitOnLastWindowClosed(true); - QApplication::exit(status); -} - -bool main_window::set_profile() -{ - if (maybe_die_on_config_not_writable(OPENTRACK_DEFAULT_CONFIG)) - return false; - - set_profile_in_registry(); - - options::detail::bundler::refresh_all_bundles(); - - // migrations are for config layout changes and other user-visible - // incompatibilities in future versions - run_migrations(); - - set_title(); - - return true; -} - -void main_window::closeEvent(QCloseEvent*) -{ - exit(); -} - -void main_window::set_profile_in_registry() -{ - with_global_settings_object([&](QSettings& s) { - s.setValue(OPENTRACK_CONFIG_FILENAME_KEY, OPENTRACK_DEFAULT_CONFIG); - }); -} - -void main_window::toggle_tracker_() -{ - qDebug() << "toggle tracker"; - if (work) - stop_tracker_(); - else - start_tracker_(); -} diff --git a/variant/trackmouse/window.hpp b/variant/trackmouse/window.hpp deleted file mode 100644 index 2c196852..00000000 --- a/variant/trackmouse/window.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once - -/* Copyright (c) 2013-2016, Stanislaw Halik - - * Permission to use, copy, modify, and/or distribute this - * software for any purpose with or without fee is hereby granted, - * provided that the above copyright notice and this permission - * notice appear in all copies. - */ - -#pragma once - -#include "ui_window.h" -#include "proto-mouse/mouse-settings.hpp" - -#include "api/plugin-support.hpp" -#include "logic/main-settings.hpp" -#include "logic/pipeline.hpp" -#include "logic/shortcuts.h" -#include "logic/work.hpp" -#include "logic/state.hpp" -#include "options/options.hpp" - -#include -#include - -#include -#include -#include -#include -#include -#include - -class main_window final : public QMainWindow, private State -{ - Q_OBJECT - - Ui::window ui; - - QTimer save_settings_timer { this }; - - Shortcuts global_shortcuts; - module_settings m; - mouse_settings mouse; - - QShortcut kbd_quit { QKeySequence("Ctrl+Q"), this }; - std::unique_ptr pFilterDialog; - std::unique_ptr pProtocolDialog; - std::unique_ptr pTrackerDialog; - bool exiting_already { false }; - - using dylib_ptr = Modules::dylib_ptr; - using dylib_list = Modules::dylib_list; - - static std::tuple module_by_name(const QString& name, Modules::dylib_list& list); - - dylib_ptr current_tracker(); - dylib_ptr current_protocol(); - dylib_ptr current_filter(); - - void update_button_state(bool running, bool inertialp); - - void set_title(const QString& game_title = QString()); - - void set_profile_in_registry(); - void register_shortcuts(); - - void closeEvent(QCloseEvent *event) override; - - bool maybe_die_on_config_not_writable(const QString& current); - void die_on_config_not_writable(); - - static constexpr int save_settings_interval_ms = 2500; - -private slots: - void save_modules(); - void exit(int status = EXIT_SUCCESS); - bool set_profile(); - - void start_tracker_(); - void stop_tracker_(); - void toggle_tracker_(); - - static void set_working_directory(); - -signals: - void start_tracker(); - void stop_tracker(); - void toggle_tracker(); - -public: - main_window(); - ~main_window() override; -}; diff --git a/variant/trackmouse/window.ui b/variant/trackmouse/window.ui deleted file mode 100644 index c79ae846..00000000 --- a/variant/trackmouse/window.ui +++ /dev/null @@ -1,458 +0,0 @@ - - - window - - - - 0 - 0 - 755 - 240 - - - - - 0 - 0 - - - - - 16777215 - 240 - - - - trackmouse prototype - - - - - 0 - 0 - - - - - 16777215 - 240 - - - - - 6 - - - 6 - - - 0 - - - 12 - - - 0 - - - - - - 0 - 0 - - - - - 320 - 240 - - - - - 320 - 240 - - - - - - 0 - 0 - 320 - 240 - - - - - 0 - 0 - - - - - 320 - 240 - - - - - 320 - 240 - - - - - - 0 - 0 - 320 - 240 - - - - - 0 - 0 - - - - - 320 - 240 - - - - - 320 - 240 - - - - - Candara - 37 - 50 - false - true - - - - - - - :/images/tracking-not-started.png - - - false - - - Qt::AlignCenter - - - true - - - - - - - - - - 0 - 0 - - - - - 12 - - - 8 - - - 12 - - - 12 - - - 12 - - - - - Keyboard shortcuts - - - - - - - 0 - 0 - - - - - 12 - 75 - true - PreferAntialias - false - - - - start/stop tracking - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - PreferAntialias - false - - - - Insert - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - PreferAntialias - false - - - - center - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - PreferAntialias - false - - - - Page Up - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - PreferAntialias - false - - - - freeze toggle - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - PreferAntialias - false - - - - Page Down - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - 0 - 0 - - - - Sensitivity - - - - - - - 10 - 0 - - - - 475 - - - 1 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 50 - - - - - - - - 2 - 0 - - - - 100% - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - 0 - 0 - - - - - 3 - - - 3 - - - - - - 0 - 0 - - - - Start - - - - :/images/images/start.png:/images/images/start.png - - - - 43 - 20 - - - - - - - - - 0 - 0 - - - - Stop - - - - :/images/images/stop.png:/images/images/stop.png - - - - - - - - - - - - - - - - - - -- cgit v1.2.3