diff options
Diffstat (limited to 'main-window')
| -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 | 
13 files changed, 360 insertions, 0 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(); +}; + +} | 
