-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
TextModifier.mpp
96 lines (83 loc) · 2.67 KB
/
TextModifier.mpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
module;
#include <CppUtils/System/Windows.hpp>
export module CppUtils.Terminal.TextModifier;
import std;
import CppUtils.Terminal.BackgroundColor;
import CppUtils.Terminal.Utility;
import CppUtils.Terminal.TextColor;
import CppUtils.Terminal.TextStyle;
export namespace CppUtils::Terminal
{
using namespace std::literals;
#if defined(OS_LINUX) or defined(OS_MACOS)
namespace ANSIEscapeCode
{
[[maybe_unused]] inline constexpr auto Reset = "\x1B[0m"sv;
[[maybe_unused]] inline constexpr auto EraseCurrentLine = "\x1B[2K0E"sv;
}
#endif
class TextModifier final
{
public:
TextModifier() = default;
inline explicit TextModifier(
std::FILE* file,
TextColor::TextColorEnum textColor = TextColor::TextColorEnum::Default,
BackgroundColor::BackgroundColorEnum backgroundColor = BackgroundColor::BackgroundColorEnum::Default,
[[maybe_unused]] std::optional<TextStyle::TextStyleEnum> textStyle = std::nullopt):
m_modify{true},
m_file{file}
{
[[maybe_unused]] auto text = TextColor::getTextColorCode(textColor);
[[maybe_unused]] auto background = BackgroundColor::getBackgroundColorCode(backgroundColor);
#if defined(OS_WINDOWS)
m_attributes = getTextColor(m_file);
SetConsoleTextAttribute(getTerminalHandle(m_file), static_cast<std::uint16_t>((background << 4) + text));
#elif defined(OS_LINUX) or defined(OS_MACOS)
std::print(m_file, "{}{}", text, background);
if (textStyle)
std::print(m_file, "{}", TextStyle::getTextStyleCode(*textStyle));
#endif
}
TextModifier(TextModifier&& other) noexcept = default;
TextModifier& operator=(TextModifier&& other) noexcept = default;
inline ~TextModifier()
{
if (!m_modify)
return;
#if defined(OS_WINDOWS)
SetConsoleTextAttribute(getTerminalHandle(m_file), m_attributes);
#elif defined(OS_LINUX) or defined(OS_MACOS)
std::print(m_file, "{}", ANSIEscapeCode::Reset);
#endif
}
#if defined(OS_WINDOWS)
[[nodiscard]] inline static auto getTextColor(std::FILE* file) -> std::uint16_t
{
CONSOLE_SCREEN_BUFFER_INFO info;
if (!GetConsoleScreenBufferInfo(getTerminalHandle(file), &info))
return 0;
return info.wAttributes;
}
[[nodiscard]] inline static auto getTextColor(std::ostream& stream) -> std::uint16_t
{
CONSOLE_SCREEN_BUFFER_INFO info;
if (!GetConsoleScreenBufferInfo(getTerminalHandle(stream), &info))
return 0;
return info.wAttributes;
}
#endif
static inline auto eraseCurrentLine([[maybe_unused]] std::ostream& stream) -> void
{
#if defined(OS_LINUX) or defined(OS_MACOS)
stream << ANSIEscapeCode::EraseCurrentLine;
#endif
}
private:
bool m_modify = false;
std::FILE* m_file = nullptr;
#if defined(OS_WINDOWS)
std::uint16_t m_attributes;
#endif
};
}