diff options
-rw-r--r-- | main-window/CMakeLists.txt | 4 | ||||
-rw-r--r-- | main-window/export.hpp | 11 | ||||
-rw-r--r-- | main-window/lang/nl_NL.ts | 4 | ||||
-rw-r--r-- | main-window/lang/ru_RU.ts | 4 | ||||
-rw-r--r-- | main-window/lang/stub.ts | 4 | ||||
-rw-r--r-- | main-window/lang/zh_CN.ts | 4 | ||||
-rw-r--r-- | main-window/mixin-traits.cpp | 39 | ||||
-rw-r--r-- | main-window/mixin-traits.hpp | 63 | ||||
-rw-r--r-- | main-window/mixins.hpp | 13 | ||||
-rw-r--r-- | main-window/module-mixin.cpp | 132 | ||||
-rw-r--r-- | main-window/module-mixin.hpp | 58 | ||||
-rw-r--r-- | main-window/tracking-mixin.cpp | 5 | ||||
-rw-r--r-- | main-window/tracking-mixin.hpp | 19 | ||||
-rw-r--r-- | variant/default/_variant.cmake | 3 |
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() |