#pragma once #include #include #include #include #include #include #include #include #include #include namespace luma { class window_manager; struct window_options { std::string title{}; luma::rect bounds{}; std::bool_t modal{false}; std::bool_t decorated{true}; std::bool_t visible{true}; }; class window { public: window(luma::window const &) = delete; window(luma::window &&) noexcept = default; auto operator=(luma::window const &) -> luma::window & = delete; auto operator=(luma::window &&) noexcept -> luma::window & = default; auto id() const -> std::uint64_t; auto options() const -> luma::window_options const &; auto set_bounds(luma::rect bounds) -> std::expected; auto set_visible(std::bool_t value) -> void; auto visible() const -> std::bool_t; auto content() -> luma::control *; auto content() const -> luma::control const *; private: friend class luma::window_manager; window(std::uint64_t id, luma::window_options options, std::unique_ptr content); std::uint64_t id_{}; luma::window_options options_{}; std::unique_ptr content_{}; }; class window_manager final : public luma::control { public: auto open(luma::window_options options, std::unique_ptr content) -> std::expected; auto close(std::uint64_t id) -> std::expected; auto bring_to_front(std::uint64_t id) -> std::expected; auto set_bounds(std::uint64_t id, luma::rect bounds) -> std::expected; auto set_visible(std::uint64_t id, std::bool_t visible) -> std::expected; auto find(std::uint64_t id) -> luma::window *; auto clear() -> void; auto measure(luma::draw_context &context, luma::theme const &theme, luma::constraints limits) -> luma::size override; auto arrange(luma::rect bounds) -> void override; auto draw(luma::draw_context &context, luma::theme const &theme) const -> void override; auto handle_touch(luma::touch_event const &event) -> std::bool_t override; auto invalidate_layout() -> void override; auto bind_layout_invalidator(std::function invalidator) -> void override; private: enum class pending_kind { OPEN, CLOSE, BRING_TO_FRONT, SET_BOUNDS, SET_VISIBLE, CLEAR, }; struct pending_operation { luma::window_manager::pending_kind kind{luma::window_manager::pending_kind::CLEAR}; std::uint64_t id{}; std::unique_ptr window{}; luma::rect bounds{}; std::bool_t visible{}; }; auto contains_effective(std::uint64_t id) const -> std::bool_t; auto close_now(std::uint64_t id) const -> void; auto bring_to_front_now(std::uint64_t id) const -> void; auto set_bounds_now(std::uint64_t id, luma::rect bounds) const -> void; auto set_visible_now(std::uint64_t id, std::bool_t visible) const -> void; auto apply_pending_operations() const -> void; std::uint64_t next_id_{1}; mutable std::float32_t title_line_height_{30.0F}; mutable std::vector> windows_{}; mutable std::unordered_map active_touches_{}; mutable std::vector pending_operations_{}; mutable std::uint32_t mutation_depth_{}; }; }