diff options
Diffstat (limited to 'src/engine/user')
| -rw-r--r-- | src/engine/user/cursor.cpp | 43 | ||||
| -rw-r--r-- | src/engine/user/cursor.hpp | 45 | ||||
| -rw-r--r-- | src/engine/user/cursor.tpp | 31 | 
3 files changed, 119 insertions, 0 deletions
diff --git a/src/engine/user/cursor.cpp b/src/engine/user/cursor.cpp new file mode 100644 index 0000000..9d6e28c --- /dev/null +++ b/src/engine/user/cursor.cpp @@ -0,0 +1,43 @@ +#include "cursor.hpp" + +#include "engine/escape.hpp" + +#include <cstdlib> +#include <iostream> + +CursorController::CursorController(IVector2Factory vector2_factory) +	: _vector2_factory(vector2_factory) +{ +} + +void CursorController::move_to(const IVector2 &pos) +{ +	fmt::print(MOVE_CURSOR_TO, fmt::arg("esc", ESC), fmt::arg("row", pos.y()), +			   fmt::arg("column", pos.x())); +	std::cout.flush(); +} + +std::shared_ptr<IVector2> CursorController::where() +{ +	fmt::print(REQUEST_CURSOR_POSITION, fmt::arg("esc", ESC)); +	std::cout.flush(); + +	IVector2Options vector2_options = {}; + +	// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) +	scanf("\033[%u;%uR", &vector2_options.y, &vector2_options.x); + +	return _vector2_factory(vector2_options); +} + +void CursorController::hide() +{ +	fmt::print(CURSOR_INVISIBLE, fmt::arg("esc", ESC)); +	std::cout.flush(); +} + +void CursorController::show() +{ +	fmt::print(CURSOR_VISIBLE, fmt::arg("esc", ESC)); +	std::cout.flush(); +} diff --git a/src/engine/user/cursor.hpp b/src/engine/user/cursor.hpp new file mode 100644 index 0000000..0317dc5 --- /dev/null +++ b/src/engine/user/cursor.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include "DI/auto_wirable.hpp" +#include "interfaces/direction.hpp" +#include "interfaces/vector2.hpp" + +#include "fmt/core.h" +#include <array> +#include <memory> +#include <unordered_map> + +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"; + +class CursorController +	: public AutoWirable<CursorController, CursorController, IVector2Factory> +{ +public: +	explicit CursorController(IVector2Factory vector2_factory); + +	template <Direction::value_type direction> +	constexpr void move(const unsigned int &amount) const; + +	static void move_to(const IVector2 &pos); + +	static void hide(); + +	static void show(); + +	[[nodiscard]] std::shared_ptr<IVector2> where(); + +private: +	IVector2Factory _vector2_factory; +}; + +#include "cursor.tpp" diff --git a/src/engine/user/cursor.tpp b/src/engine/user/cursor.tpp new file mode 100644 index 0000000..224418e --- /dev/null +++ b/src/engine/user/cursor.tpp @@ -0,0 +1,31 @@ +#pragma once + +#include "cursor.hpp" + +#include "engine/escape.hpp" + +#include <iostream> + +constexpr auto get_direction_format_map() +{ +	std::array<std::string_view, 4> direction_format_map; + +	direction_format_map[Direction::UP] = MOVE_CURSOR_UP; +	direction_format_map[Direction::DOWN] = MOVE_CURSOR_DOWN; +	direction_format_map[Direction::LEFT] = MOVE_CURSOR_LEFT; +	direction_format_map[Direction::RIGHT] = MOVE_CURSOR_RIGHT; + +	return direction_format_map; +} + +template <Direction::value_type direction> +constexpr void CursorController::move(const unsigned int &amount) const +{ +	constexpr auto direction_format_map = get_direction_format_map(); + +	constexpr auto format = direction_format_map[direction]; + +	fmt::vprint(format, +				fmt::make_format_args(fmt::arg("esc", ESC), fmt::arg("amount", amount))); +	std::cout.flush(); +}  | 
