#pragma once #include "interfaces/cursor.hpp" #include "engine/data/bounds.hpp" #include "engine/data/vector2.hpp" #include #include #include #include #include #include constexpr std::string_view MOVE_CURSOR_UP = "{esc}[{amount}A"; constexpr std::string_view MOVE_CURSOR_DOWN = "{esc}[{amount}B"; constexpr std::string_view MOVE_CURSOR_LEFT = "{esc}[{amount}D"; constexpr std::string_view MOVE_CURSOR_RIGHT = "{esc}[{amount}C"; constexpr fmt::string_view MOVE_CURSOR_TO = "{esc}[{row};{column}H"; constexpr fmt::string_view REQUEST_CURSOR_POSITION = "{esc}[6n"; constexpr fmt::string_view CURSOR_VISIBLE = "{esc}[?25h"; constexpr fmt::string_view CURSOR_INVISIBLE = "{esc}[?25l"; constexpr fmt::string_view SET_CURSOR_STYLE = "{esc}[{style} q"; const std::unordered_map direction_format_map = {{Vector2::up(), MOVE_CURSOR_UP}, {Vector2::down(), MOVE_CURSOR_DOWN}, {Vector2::left(), MOVE_CURSOR_LEFT}, {Vector2::right(), MOVE_CURSOR_RIGHT}}; class CursorController : public ICursorController, public yacppdic::AutoWirable { public: CursorController() noexcept; void move(const Vector2 &direction, const std::uint32_t &amount, bool flush_cout) noexcept override; void move_to(const Vector2 &position, bool flush_cout) noexcept override; [[nodiscard]] auto where() const noexcept -> Vector2 override; void update_position(const Vector2 &position) noexcept override; void hide(bool flush_cout) noexcept override; void show(bool flush_cout) noexcept override; void set_cursor_style(CursorStyle cursor_style, bool flush_cout) noexcept override; void set_bounds(const Bounds &bounds) noexcept override; private: Vector2 _position; Bounds _bounds; [[nodiscard]] auto _invert_position_y(const Vector2 &position) const noexcept -> Vector2; };