-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathConsoleUtils.hpp
More file actions
273 lines (246 loc) · 10.4 KB
/
ConsoleUtils.hpp
File metadata and controls
273 lines (246 loc) · 10.4 KB
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
#pragma once
#include <string>
#include <unordered_map>
#include <vector>
// Cross-platform console colors and formatting
#ifdef _WIN32
#include <windows.h>
// ANSI escape codes for Windows (with virtual terminal processing)
#define RESET_COLOR "\033[0m"
#define RED_COLOR "\033[31m"
#define GREEN_COLOR "\033[32m"
#define BLUE_COLOR "\033[34m"
#define YELLOW_COLOR "\033[33m"
#define MAGENTA_COLOR "\033[35m"
#define CYAN_COLOR "\033[36m"
#define WHITE_COLOR "\033[37m"
#define BRIGHT_RED_COLOR "\033[91m"
#define BRIGHT_GREEN_COLOR "\033[92m"
#define BRIGHT_BLUE_COLOR "\033[94m"
#define BRIGHT_YELLOW_COLOR "\033[93m"
#define BRIGHT_MAGENTA_COLOR "\033[95m"
#define BRIGHT_CYAN_COLOR "\033[96m"
#define BRIGHT_WHITE_COLOR "\033[97m"
#define BOLD_TEXT "\033[1m"
#define ITALIC_TEXT "\033[3m"
#define UNDERLINE_TEXT "\033[4m"
#define DIM_TEXT "\033[2m"
// Windows console color initialization function
inline void initConsoleColors()
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode = 0;
GetConsoleMode(hConsole, &mode);
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
SetConsoleMode(hConsole, mode);
}
#else
// ANSI escape codes for Linux/macOS
#define RESET_COLOR "\033[0m"
#define RED_COLOR "\033[31m"
#define GREEN_COLOR "\033[32m"
#define BLUE_COLOR "\033[34m"
#define YELLOW_COLOR "\033[33m"
#define MAGENTA_COLOR "\033[35m"
#define CYAN_COLOR "\033[36m"
#define WHITE_COLOR "\033[37m"
#define BRIGHT_RED_COLOR "\033[91m"
#define BRIGHT_GREEN_COLOR "\033[92m"
#define BRIGHT_BLUE_COLOR "\033[94m"
#define BRIGHT_YELLOW_COLOR "\033[93m"
#define BRIGHT_MAGENTA_COLOR "\033[95m"
#define BRIGHT_CYAN_COLOR "\033[96m"
#define BRIGHT_WHITE_COLOR "\033[97m"
#define BOLD_TEXT "\033[1m"
#define ITALIC_TEXT "\033[3m"
#define UNDERLINE_TEXT "\033[4m"
#define DIM_TEXT "\033[2m"
// No initialization needed for Linux/macOS
inline void initConsoleColors() {}
// Border characters and styles for Linux/macOS (Unicode box-drawing)
#define TOP_LEFT_CORNER "┌"
#define TOP_RIGHT_CORNER "┐"
#define BOTTOM_LEFT_CORNER "└"
#define BOTTOM_RIGHT_CORNER "┘"
#define HORIZONTAL_LINE "─"
#define VERTICAL_LINE "│"
#define BORDER_PADDING " "
#define SYSTEM_BOX_TOP "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
#define SYSTEM_BOX_BOTTOM "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
#define SYSTEM_BOX_SIDE "┃"
#define JOIN_BOX_TOP "╔══════════════════════════════════════════╗"
#define JOIN_BOX_BOTTOM "╚══════════════════════════════════════════╝"
#define JOIN_BOX_SIDE "║"
#define LEAVE_BOX_TOP "╔══════════════════════════════════════════╗"
#define LEAVE_BOX_BOTTOM "╚══════════════════════════════════════════╝"
#define LEAVE_BOX_SIDE "║"
#endif
#ifdef _WIN32
// Windows-compatible border characters (ASCII-based)
#define TOP_LEFT_CORNER "+"
#define TOP_RIGHT_CORNER "+"
#define BOTTOM_LEFT_CORNER "+"
#define BOTTOM_RIGHT_CORNER "+"
#define HORIZONTAL_LINE "-"
#define VERTICAL_LINE "|"
#define BORDER_PADDING " "
#define SYSTEM_BOX_TOP "+------------------------------------------+"
#define SYSTEM_BOX_BOTTOM "+------------------------------------------+"
#define SYSTEM_BOX_SIDE "|"
#define JOIN_BOX_TOP "+==========================================+"
#define JOIN_BOX_BOTTOM "+==========================================+"
#define JOIN_BOX_SIDE "|"
#define LEAVE_BOX_TOP "+==========================================+"
#define LEAVE_BOX_BOTTOM "+==========================================+"
#define LEAVE_BOX_SIDE "|"
#endif
// User color assignment system using static local variables to avoid multiple definition
inline std::string getUserColor(const std::string &username)
{
static std::unordered_map<std::string, std::string> userColors;
static std::vector<std::string> colorPalette = {
// Extended diverse color palette with 256-color ANSI codes
"\033[38;5;208m", // Bright orange
"\033[38;5;129m", // Purple
"\033[38;5;213m", // Pink
"\033[38;5;154m", // Lime green
"\033[38;5;80m", // Teal
"\033[38;5;99m", // Indigo
"\033[38;5;203m", // Coral
"\033[38;5;220m", // Gold
"\033[38;5;177m", // Violet
"\033[38;5;86m", // Turquoise
"\033[38;5;209m", // Salmon
"\033[38;5;46m", // Emerald
"\033[38;5;196m", // Ruby red
"\033[38;5;33m", // Sapphire blue
"\033[38;5;214m", // Amber
"\033[38;5;160m", // Crimson
"\033[38;5;22m", // Forest green
"\033[38;5;201m", // Hot pink
"\033[38;5;51m", // Cyan blue
"\033[38;5;226m", // Bright yellow
"\033[38;5;165m", // Magenta pink
"\033[38;5;39m", // Sky blue
"\033[38;5;202m", // Orange red
"\033[38;5;118m", // Spring green
"\033[38;5;207m", // Bright magenta
"\033[38;5;87m", // Light cyan
"\033[38;5;228m", // Khaki
"\033[38;5;171m", // Orchid
"\033[38;5;75m", // Steel blue
"\033[38;5;215m" // Light orange
};
static size_t colorIndex = 0;
if (userColors.find(username) == userColors.end())
{
userColors[username] = colorPalette[colorIndex % colorPalette.size()];
colorIndex++;
}
return userColors[username];
}
// Helper function to create bordered messages
inline std::string createBorderedMessage(const std::string &username, const std::string &message, const std::string &borderColor)
{
std::string result = "";
std::string content = username + ": " + message;
size_t contentLength = content.length();
size_t boxWidth = std::max(contentLength + 4, static_cast<size_t>(20)); // Minimum width of 20
// Top border
result += borderColor + std::string(TOP_LEFT_CORNER);
for (size_t i = 0; i < boxWidth; ++i)
{
result += std::string(HORIZONTAL_LINE);
}
result += std::string(TOP_RIGHT_CORNER) + std::string(RESET_COLOR) + "\n";
// Content with side borders
result += borderColor + std::string(VERTICAL_LINE) + std::string(RESET_COLOR) + std::string(BORDER_PADDING);
result += borderColor + std::string(BOLD_TEXT) + username + std::string(RESET_COLOR) + ": " + message;
// Add padding to reach box width
size_t paddingNeeded = boxWidth - contentLength - 2;
for (size_t i = 0; i < paddingNeeded; ++i)
{
result += " ";
}
result += borderColor + std::string(VERTICAL_LINE) + std::string(RESET_COLOR) + "\n";
// Bottom border
result += borderColor + std::string(BOTTOM_LEFT_CORNER);
for (size_t i = 0; i < boxWidth; ++i)
{
result += std::string(HORIZONTAL_LINE);
}
result += std::string(BOTTOM_RIGHT_CORNER) + std::string(RESET_COLOR);
return result;
}
// Enhanced message formatting functions
inline std::string formatSystemMessage(const std::string &msg)
{
std::string result = std::string(YELLOW_COLOR) + SYSTEM_BOX_TOP + std::string(RESET_COLOR) + "\n";
result += std::string(YELLOW_COLOR) + SYSTEM_BOX_SIDE + std::string(RESET_COLOR) + std::string(BOLD_TEXT) + " [SYSTEM] " + std::string(RESET_COLOR) + msg;
size_t padding = 35;
if (msg.length() < padding)
{
result += std::string(padding - msg.length(), ' ');
}
result += std::string(YELLOW_COLOR) + SYSTEM_BOX_SIDE + std::string(RESET_COLOR) + "\n";
result += std::string(YELLOW_COLOR) + SYSTEM_BOX_BOTTOM + std::string(RESET_COLOR);
return result;
}
inline std::string formatUserJoin(const std::string &user)
{
std::string result = std::string(BRIGHT_GREEN_COLOR) + JOIN_BOX_TOP + std::string(RESET_COLOR) + "\n";
#ifdef _WIN32
// Windows-friendly emoji alternative
result += std::string(BRIGHT_GREEN_COLOR) + JOIN_BOX_SIDE + std::string(RESET_COLOR) + " * " + std::string(BOLD_TEXT) + user + " joined the chat!" + std::string(RESET_COLOR);
#else
// Linux/macOS with emoji support
result += std::string(BRIGHT_GREEN_COLOR) + JOIN_BOX_SIDE + std::string(RESET_COLOR) + " 🎉 " + std::string(BOLD_TEXT) + user + " joined the chat!" + std::string(RESET_COLOR);
#endif
size_t padding = 32;
if (user.length() < padding)
{
result += std::string(padding - user.length(), ' ');
}
result += std::string(BRIGHT_GREEN_COLOR) + JOIN_BOX_SIDE + std::string(RESET_COLOR) + "\n";
result += std::string(BRIGHT_GREEN_COLOR) + JOIN_BOX_BOTTOM + std::string(RESET_COLOR);
return result;
}
inline std::string formatUserLeave(const std::string &user)
{
std::string result = std::string(BRIGHT_RED_COLOR) + LEAVE_BOX_TOP + std::string(RESET_COLOR) + "\n";
#ifdef _WIN32
// Windows-friendly emoji alternative
result += std::string(BRIGHT_RED_COLOR) + LEAVE_BOX_SIDE + std::string(RESET_COLOR) + " - " + std::string(BOLD_TEXT) + user + " left the chat" + std::string(RESET_COLOR);
#else
// Linux/macOS with emoji support
result += std::string(BRIGHT_RED_COLOR) + LEAVE_BOX_SIDE + std::string(RESET_COLOR) + " 👋 " + std::string(BOLD_TEXT) + user + " left the chat" + std::string(RESET_COLOR);
#endif
size_t padding = 33;
if (user.length() < padding)
{
result += std::string(padding - user.length(), ' ');
}
result += std::string(BRIGHT_RED_COLOR) + LEAVE_BOX_SIDE + std::string(RESET_COLOR) + "\n";
result += std::string(BRIGHT_RED_COLOR) + LEAVE_BOX_BOTTOM + std::string(RESET_COLOR);
return result;
}
// Updated macros using the functions
#define FORMAT_SYSTEM_MESSAGE(msg) formatSystemMessage(msg)
#define FORMAT_USER_JOIN(user) formatUserJoin(user)
#define FORMAT_USER_LEAVE(user) formatUserLeave(user)
#define FORMAT_SENT_MESSAGE(user, msg) createBorderedMessage("You", msg, std::string(BRIGHT_CYAN_COLOR))
// Function to format received messages with user-specific colors
inline std::string formatReceivedMessage(const std::string &username, const std::string &message)
{
std::string userColor = getUserColor(username);
return createBorderedMessage(username, message, userColor);
}
// Utility function to print a separator line
inline std::string createSeparator()
{
#ifdef _WIN32
return std::string(DIM_TEXT) + "-------------------------------------------------" + std::string(RESET_COLOR);
#else
return std::string(DIM_TEXT) + "─────────────────────────────────────────────────" + std::string(RESET_COLOR);
#endif
}