summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--main-window/CMakeLists.txt4
-rw-r--r--main-window/export.hpp11
-rw-r--r--main-window/lang/nl_NL.ts4
-rw-r--r--main-window/lang/ru_RU.ts4
-rw-r--r--main-window/lang/stub.ts4
-rw-r--r--main-window/lang/zh_CN.ts4
-rw-r--r--main-window/mixin-traits.cpp39
-rw-r--r--main-window/mixin-traits.hpp63
-rw-r--r--main-window/mixins.hpp13
-rw-r--r--main-window/module-mixin.cpp132
-rw-r--r--main-window/module-mixin.hpp58
-rw-r--r--main-window/tracking-mixin.cpp5
-rw-r--r--main-window/tracking-mixin.hpp19
-rw-r--r--variant/default/_variant.cmake3
14 files changed, 362 insertions, 1 deletions
diff --git a/main-window/CMakeLists.txt b/main-window/CMakeLists.txt
new file mode 100644
index 00000000..3edd241b
--- /dev/null
+++ b/main-window/CMakeLists.txt
@@ -0,0 +1,4 @@
+otr_module(main-window BIN)
+foreach(k user-interface logic pose-widget migration spline)
+ target_link_libraries(${self} opentrack-${k})
+endforeach()
diff --git a/main-window/export.hpp b/main-window/export.hpp
new file mode 100644
index 00000000..184cf035
--- /dev/null
+++ b/main-window/export.hpp
@@ -0,0 +1,11 @@
+// generates export.hpp for each module from compat/linkage.hpp
+
+#pragma once
+
+#include "compat/linkage-macros.hpp"
+
+#ifdef BUILD_MAIN_WINDOW
+# define OTR_MAIN_EXPORT OTR_GENERIC_EXPORT
+#else
+# define OTR_MAIN_EXPORT OTR_GENERIC_IMPORT
+#endif
diff --git a/main-window/lang/nl_NL.ts b/main-window/lang/nl_NL.ts
new file mode 100644
index 00000000..6401616d
--- /dev/null
+++ b/main-window/lang/nl_NL.ts
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+</TS>
diff --git a/main-window/lang/ru_RU.ts b/main-window/lang/ru_RU.ts
new file mode 100644
index 00000000..6401616d
--- /dev/null
+++ b/main-window/lang/ru_RU.ts
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+</TS>
diff --git a/main-window/lang/stub.ts b/main-window/lang/stub.ts
new file mode 100644
index 00000000..6401616d
--- /dev/null
+++ b/main-window/lang/stub.ts
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+</TS>
diff --git a/main-window/lang/zh_CN.ts b/main-window/lang/zh_CN.ts
new file mode 100644
index 00000000..6401616d
--- /dev/null
+++ b/main-window/lang/zh_CN.ts
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+</TS>
diff --git a/main-window/mixin-traits.cpp b/main-window/mixin-traits.cpp
new file mode 100644
index 00000000..4b34eb5b
--- /dev/null
+++ b/main-window/mixin-traits.cpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#define MIXIN_TRAIT_TESTS
+
+#ifdef MIXIN_TRAIT_TESTS
+# include "mixin-traits.hpp"
+
+namespace mixins::traits_detail {
+
+struct A {};
+struct B : A {};
+struct C {};
+
+template<> struct mixin_traits<B>
+{
+ using depends = tuple<A>;
+};
+
+template<> struct mixin_traits<A>
+{
+ using depends = tuple<B>;
+};
+
+template<> struct mixin_traits<C>
+{
+ using depends = tuple<B, A>;
+};
+
+extern void test1();
+
+void test1()
+{
+ //impl<A> fail1;
+ impl<B> ok1;
+}
+
+} // ns mixins::traits_detail
+
+#endif
diff --git a/main-window/mixin-traits.hpp b/main-window/mixin-traits.hpp
new file mode 100644
index 00000000..e7d02c85
--- /dev/null
+++ b/main-window/mixin-traits.hpp
@@ -0,0 +1,63 @@
+#pragma once
+
+#include "compat/linkage-macros.hpp"
+#include "compat/macros.hpp"
+#include "compat/meta.hpp"
+
+#include <type_traits>
+
+namespace mixins::traits_detail {
+
+ using namespace meta;
+ template<typename... xs>
+ using tuple = meta::detail::tuple<xs...>;
+
+ template<typename t>
+ struct mixin_traits {
+ using depends = tuple<>;
+ };
+
+ template<typename klass, typename...> struct check_depends_;
+
+ template<typename klass>
+ struct check_depends_<klass>
+ {
+ static constexpr bool recurse() { return true; }
+ };
+
+ template<typename klass, typename x, typename... xs>
+ struct check_depends_<klass, x, xs...>
+ {
+ static constexpr bool recurse()
+ {
+ using depends = typename mixin_traits<x>::depends;
+
+ return (std::is_base_of_v<x, klass> || std::is_same_v<x, klass>) &&
+ check_depends_<klass, xs...>::recurse() &&
+ lift<check_depends_, cons<klass, depends>>::recurse();
+ }
+ };
+
+#if 0
+ template<typename final_class, typename t>
+ static constexpr void check_depends_recursively()
+ {
+ std::is_base_of_v<x, final_class> &&
+ assert_depends<final_class, xs...>::check_depends()
+
+ using depends = typename mixin_traits<t>::depends;
+ static_assert(lift<assert_depends, cons<t, depends>>::check_depends());
+
+ using car = first<depends>;
+ using cdr = rest<depends>;
+
+ check_depends_recursively<car>();
+ }
+#endif
+
+ template<typename t>
+ class impl
+ {
+ static_assert(lift<check_depends_, cons<t, typename mixin_traits<t>::depends>>::recurse());
+ };
+} // ns mixins::traits_detail
diff --git a/main-window/mixins.hpp b/main-window/mixins.hpp
new file mode 100644
index 00000000..b85e6498
--- /dev/null
+++ b/main-window/mixins.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "export.hpp"
+
+// XXX TODO add is_base_of and void_t stuff
+
+#define OTR_MIXIN_NS(name) \
+ mixins :: detail :: name
+
+#define OTR_DECLARE_MIXIN(name) \
+ namespace mixins { \
+ using name = :: OTR_MIXIN_NS(name) :: name; \
+ }
diff --git a/main-window/module-mixin.cpp b/main-window/module-mixin.cpp
new file mode 100644
index 00000000..67485ba2
--- /dev/null
+++ b/main-window/module-mixin.cpp
@@ -0,0 +1,132 @@
+#include "module-mixin.hpp"
+
+#include <algorithm>
+
+namespace OTR_MIXIN_NS(module_mixin) {
+
+std::tuple<dylib_ptr, int>
+module_mixin::module_by_name(const QString& name, const dylib_list& list) const
+{
+ 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, int(std::distance(list.cbegin(), it)) };
+}
+
+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<typename t, typename F>
+static bool mk_window_common(std::unique_ptr<t>& d, F&& fun)
+{
+ bool fresh = false;
+
+ if (!d)
+ d = fun(), fresh = !!d;
+
+ if (d)
+ show_window(*d, fresh);
+
+ return fresh;
+}
+
+template<typename t>
+static bool mk_dialog(std::unique_ptr<t>& place, const std::shared_ptr<dylib>& lib)
+{
+ using u = std::unique_ptr<t>;
+
+ return mk_window_common(place, [&] {
+ if (lib && lib->Dialog)
+ return u{ (t*)lib->Dialog() };
+ else
+ return nullptr;
+ });
+}
+
+dylib_ptr module_mixin::current_tracker()
+{
+ auto [ptr, idx] = module_by_name(s.tracker_dll, modules.trackers());
+ return ptr;
+}
+
+dylib_ptr module_mixin::current_protocol()
+{
+ auto [ptr, idx] = module_by_name(s.protocol_dll, modules.protocols());
+ return ptr;
+}
+
+dylib_ptr module_mixin::current_filter()
+{
+ auto [ptr, idx] = module_by_name(s.filter_dll, modules.filters());
+ return ptr;
+}
+
+void module_mixin::show_tracker_settings()
+{
+#if 0
+ if (mk_dialog(tracker_dialog, current_tracker()) && work && work->libs.pTracker)
+ tracker_dialog->register_tracker(work->libs.pTracker.get());
+ if (tracker_dialog)
+ QObject::connect(tracker_dialog.get(), &ITrackerDialog::closing,
+ this, [this] { tracker_dialog = nullptr; });
+#endif
+}
+
+void module_mixin::show_proto_settings()
+{
+#if 0
+ if (mk_dialog(proto_dialog, current_protocol()) && work && work->libs.pProtocol)
+ proto_dialog->register_protocol(work->libs.pProtocol.get());
+ if (proto_dialog)
+ QObject::connect(proto_dialog.get(), &IProtocolDialog::closing,
+ this, [this] { proto_dialog = nullptr; });
+#endif
+}
+
+void module_mixin::show_filter_settings()
+{
+#if 0
+ if (mk_dialog(filter_dialog, current_filter()) && work && work->libs.pFilter)
+ filter_dialog->register_filter(work->libs.pFilter.get());
+ if (filter_dialog)
+ QObject::connect(filter_dialog.get(), &IFilterDialog::closing,
+ this, [this] { filter_dialog = nullptr; });
+#endif
+}
+
+template<typename t, typename... Args>
+static bool mk_window(std::unique_ptr<t>& place, Args&&... params)
+{
+ return mk_window_common(place, [&] {
+ return std::make_unique<t>(params...);
+ });
+}
+
+module_mixin::module_mixin() = default;
+module_mixin::~module_mixin() = default;
+
+module_settings::module_settings() = default;
+
+} // ns
diff --git a/main-window/module-mixin.hpp b/main-window/module-mixin.hpp
new file mode 100644
index 00000000..307d79b8
--- /dev/null
+++ b/main-window/module-mixin.hpp
@@ -0,0 +1,58 @@
+#pragma once
+
+#include "mixins.hpp"
+#include "compat/library-path.hpp"
+#include "api/plugin-api.hpp"
+#include "logic/extensions.hpp"
+#include "logic/work.hpp"
+
+#include <memory>
+#include <utility>
+
+#include <QObject>
+#include <QString>
+
+namespace OTR_MIXIN_NS(module_mixin) {
+
+using namespace options;
+
+using dylib_ptr = Modules::dylib_ptr;
+using dylib_list = Modules::dylib_list;
+
+struct OTR_MAIN_EXPORT module_settings final
+{
+ bundle b { make_bundle("modules") };
+ value<QString> tracker_dll { b, "tracker-dll", "pt" },
+ filter_dll { b, "filter-dll", "accela" },
+ protocol_dll { b, "protocol-dll", "freetrack" };
+ module_settings();
+};
+
+struct OTR_MAIN_EXPORT module_mixin
+{
+ module_mixin();
+ virtual ~module_mixin();
+
+ std::unique_ptr<ITrackerDialog> tracker_dialog;
+ std::unique_ptr<IProtocolDialog> proto_dialog;
+ std::unique_ptr<IFilterDialog> filter_dialog;
+
+ std::tuple<dylib_ptr, int> module_by_name(const QString& name, const dylib_list& list) const;
+
+ dylib_ptr current_tracker();
+ dylib_ptr current_protocol();
+ dylib_ptr current_filter();
+
+ void show_tracker_settings();
+ void show_proto_settings();
+ void show_filter_settings();
+
+private:
+ Modules modules { OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH };
+ event_handler ev { modules.extensions() };
+ module_settings s;
+};
+
+}
+
+OTR_DECLARE_MIXIN(module_mixin)
diff --git a/main-window/tracking-mixin.cpp b/main-window/tracking-mixin.cpp
new file mode 100644
index 00000000..1ec6f3d5
--- /dev/null
+++ b/main-window/tracking-mixin.cpp
@@ -0,0 +1,5 @@
+#include "tracking-mixin.hpp"
+
+using namespace OTR_MIXIN_NS(tracking_mixin);
+
+has_work::has_work::~has_work() = default;
diff --git a/main-window/tracking-mixin.hpp b/main-window/tracking-mixin.hpp
new file mode 100644
index 00000000..e48ca630
--- /dev/null
+++ b/main-window/tracking-mixin.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "mixins.hpp"
+
+#include "logic/work.hpp"
+
+#include <memory>
+
+namespace OTR_MIXIN_NS(tracking_mixin) {
+
+using work_ptr = std::shared_ptr<Work>;
+
+struct OTR_MAIN_EXPORT has_work {
+ virtual explicit operator work_ptr() = 0;
+ inline has_work() = default;
+ virtual ~has_work();
+};
+
+}
diff --git a/variant/default/_variant.cmake b/variant/default/_variant.cmake
index cdf9da56..b7ba90b3 100644
--- a/variant/default/_variant.cmake
+++ b/variant/default/_variant.cmake
@@ -21,7 +21,8 @@ function(otr_init_variant)
"qxt-mini"
"macosx"
"cv"
- "migration")
+ "migration"
+ "main-window")
set_property(GLOBAL PROPERTY opentrack-subprojects "${subprojects}")
endfunction()