-
Notifications
You must be signed in to change notification settings - Fork 1
/
MessageHandler.h
156 lines (141 loc) · 4.25 KB
/
MessageHandler.h
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//
// MessageHandler.h
// Termin8or
//
// Created by Rasmus Anthin on 2024-06-18.
//
#pragma once
#include "Color.h"
#include "UI.h"
#include <execution>
#include <queue>
struct MessageBoxDrawingArgs
{
bool draw_box_outline = true;
bool draw_box_bkg = true;
int box_padding_ud = 0;
int box_padding_lr = 1;
drawing::OutlineType outline_type = drawing::OutlineType::Line;
ui::VerticalAlignment v_align = ui::VerticalAlignment::CENTER;
ui::HorizontalAlignment h_align = ui::HorizontalAlignment::CENTER;
int v_align_offs = 0;
int h_align_offs = 0;
bool framed_mode = true;
};
class MessageHandler
{
public:
enum class Level { Guide, Warning, Fatal };
private:
float trg_time = 0.f;
bool message_empty = true;
std::queue<std::pair<std::string, float>> messages_guide;
std::queue<std::pair<std::string, float>> messages_warning;
std::queue<std::pair<std::string, float>> messages_fatal;
std::string curr_message;
Level curr_level;
float curr_duration_s = 1.5f;
ui::TextBox tb;
int str_len = 0;
Color get_fg_color() const
{
switch (curr_level)
{
case Level::Guide: return Color::White;
case Level::Warning: return Color::White;
case Level::Fatal: return Color::White;
default: return Color::Default;
}
}
Color get_bg_color() const
{
switch (curr_level)
{
case Level::Guide: return Color::DarkBlue;
case Level::Warning: return Color::DarkYellow;
case Level::Fatal: return Color::DarkRed;
default: return Color::Default;
}
}
bool has_messages() const
{
return !messages_guide.empty() || !messages_warning.empty() || !messages_fatal.empty();
}
std::tuple<std::string, Level, float> fetch_next_message()
{
if (!messages_fatal.empty())
{
const auto& msg = messages_fatal.front();
const auto ret = std::make_tuple(msg.first, Level::Fatal, msg.second);
messages_fatal.pop();
return ret;
}
if (!messages_warning.empty())
{
const auto& msg = messages_warning.front();
const auto ret = std::make_tuple(msg.first, Level::Warning, msg.second);
messages_warning.pop();
return ret;
}
if (!messages_guide.empty())
{
const auto& msg = messages_guide.front();
const auto ret = std::make_tuple(msg.first, Level::Guide, msg.second);
messages_guide.pop();
return ret;
}
return { "<Invalid Message>", Level::Guide, 0.5f };
}
public:
void add_message(float time, const std::string& msg, Level lvl, float duration_s = 1.5f)
{
switch (lvl)
{
case Level::Guide:
messages_guide.push({ msg, duration_s });
break;
case Level::Warning:
messages_warning.push({ msg, duration_s });
break;
case Level::Fatal:
messages_fatal.push({ msg, duration_s });
break;
}
}
template<int NR, int NC>
void update(ScreenHandler<NR, NC>& sh, float time, const MessageBoxDrawingArgs& args = {})
{
if (message_empty && has_messages())
{
trg_time = time;
std::tie(curr_message, curr_level, curr_duration_s) = fetch_next_message();
str_len = static_cast<int>(curr_message.size());
message_empty = false;
}
if (time - trg_time <= curr_duration_s && !curr_message.empty())
{
auto fg_color = get_fg_color();
auto bg_color = get_bg_color();
tb.set_text(curr_message);
tb.calc_pre_draw(str::Adjustment::Center);
ui::TextBoxDrawingArgsAlign aargs;
aargs.v_align = args.v_align;
aargs.h_align = args.h_align;
aargs.v_align_offs = args.v_align_offs;
aargs.h_align_offs = args.h_align_offs;
aargs.base.box_style = { fg_color, bg_color };
aargs.base.draw_box_outline = args.draw_box_outline;
aargs.base.draw_box_bkg = args.draw_box_bkg;
aargs.base.box_padding_ud = args.box_padding_ud;
aargs.base.box_padding_lr = args.box_padding_lr;
aargs.base.box_outline_style = std::nullopt;
aargs.base.outline_type = args.outline_type;
aargs.framed_mode = args.framed_mode;
tb.draw(sh, aargs);
}
else
message_empty = true;
}
bool has_message(float time) const { return !message_empty; }
void clear_curr_message() { curr_message.clear(); }
};