aboutsummaryrefslogtreecommitdiff
path: root/src/engine/user
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/user')
-rw-r--r--src/engine/user/cursor.cpp43
-rw-r--r--src/engine/user/cursor.hpp45
-rw-r--r--src/engine/user/cursor.tpp31
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();
+}