R-Type
Distributed multiplayer game engine in C++
Loading...
Searching...
No Matches
ChatWidget.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** r-type
4** File description:
5** ChatWidget implementation
6*/
7
8#include "UI/ChatWidget.hpp"
9#include <raylib.h>
10#include "../common/Logger/Logger.hpp"
11
12namespace Game {
13
15 : _uiFactory(uiFactory), _graphics(graphics) {}
16
18 // Create text input for chat
20
21 if (!_textInput) {
22 LOG_ERROR("[ChatWidget] Failed to create text input");
23 return;
24 }
25
26 // Configure text input
27 _textInput->SetMaxLength(MAX_CHAR_PER_MESSAGE);
28 _textInput->SetPlaceholder("Type a message...");
30
31 // Colors (dark theme)
32 _textInput->SetBackgroundColor(0xFF1A1A1A); // Dark gray
33 _textInput->SetBorderColor(0xFF444444); // Medium gray
34 _textInput->SetActiveBorderColor(0xFF00AAFF); // Blue when active
35 _textInput->SetTextColor(0xFFFFFFFF); // White
36 _textInput->SetPlaceholderColor(0xFF888888); // Light gray
37
38 // Set callback for when Enter is pressed
39 _textInput->SetOnTextChanged([this](const std::string &text) { OnTextChanged(text); });
40
41 LOG_INFO("[ChatWidget] Initialized");
42 }
43
45 if (!_visible || !_textInput) {
46 return;
47 }
48
49 _textInput->Update();
50
51 // Check if Enter key is pressed to send message
52 if (IsKeyPressed(KEY_ENTER)) {
54 }
55 }
56
58 if (!_visible) {
59 return;
60 }
61
62 // Draw semi-transparent background for chat area
63 int bgX = static_cast<int>(_posX);
64 int bgY = static_cast<int>(_posY);
65 int bgWidth = static_cast<int>(WIDGET_WIDTH);
66 int bgHeight = static_cast<int>(WIDGET_HEIGHT);
67
68 _graphics.DrawRectangle(bgX, bgY, bgWidth, bgHeight, 0xAA000000); // Semi-transparent black
69 _graphics.DrawRectangleLines(bgX, bgY, bgWidth, bgHeight, 0xFF444444); // Gray border
70
71 // Render messages
72 float messageY = _posY + PADDING;
73 size_t startIdx =
75
76 for (size_t i = startIdx; i < _messages.size(); ++i) {
77 std::string formatted = FormatMessage(_messages[i]);
78 _graphics.DrawText(-1, formatted.c_str(), static_cast<int>(_posX + PADDING),
79 static_cast<int>(messageY), 12, 0xFFFFFFFF);
81 }
82
83 // Render text input at bottom
84 if (_textInput) {
86 _textInput->Render();
87 }
88 }
89
90 void ChatWidget::SetOnMessageSent(std::function<void(const std::string &)> callback) {
91 _onMessageSent = callback;
92 }
93
94 void ChatWidget::AddMessage(uint32_t playerId, const std::string &playerName, const std::string &message,
95 uint64_t timestamp) {
96 _messages.emplace_back(playerId, playerName, message, timestamp);
97
98 // Limit buffer size
99 while (_messages.size() > MAX_MESSAGE_BUFFER) {
100 _messages.pop_front();
101 }
102
103 LOG_DEBUG("[ChatWidget] Added message from ", playerName, ": ", message);
104 }
105
107 _messages.clear();
108 }
109
110 void ChatWidget::SetVisible(bool visible) {
111 _visible = visible;
112 if (!visible && _textInput) {
113 _textInput->SetText(""); // Clear input when hidden
114 }
115 }
116
117 void ChatWidget::SetPosition(float x, float y) {
118 _posX = x;
119 _posY = y;
120 }
121
122 void ChatWidget::OnTextChanged(const std::string &text) {
123 // Could add real-time validation here if needed
124 (void)text;
125 }
126
128 if (!_textInput) {
129 return;
130 }
131
132 std::string message = _textInput->GetText();
133
134 // Trim whitespace
135 while (!message.empty() && std::isspace(static_cast<unsigned char>(message.front()))) {
136 message.erase(message.begin());
137 }
138 while (!message.empty() && std::isspace(static_cast<unsigned char>(message.back()))) {
139 message.pop_back();
140 }
141
142 if (message.empty()) {
143 return;
144 }
145
146 LOG_DEBUG("[ChatWidget] Sending message: '", message,
147 "', callback exists: ", (_onMessageSent ? "YES" : "NO"));
148
149 // Send message via callback
150 if (_onMessageSent) {
151 LOG_DEBUG("[ChatWidget] Calling onMessageSent callback...");
152 _onMessageSent(message);
153 LOG_DEBUG("[ChatWidget] Callback completed");
154 } else {
155 LOG_ERROR("[ChatWidget] No callback registered!");
156 }
157
158 // Clear input
159 _textInput->SetText("");
160
161 LOG_DEBUG("[ChatWidget] Message sent and input cleared");
162 }
163
165 // Format: [PlayerName]: Message
166 return "[" + msg.playerName + "]: " + msg.message;
167 }
168
169} // namespace Game
#define LOG_INFO(...)
Definition Logger.hpp:181
#define LOG_DEBUG(...)
Definition Logger.hpp:180
#define LOG_ERROR(...)
Definition Logger.hpp:183
void SetPosition(float x, float y)
Set widget position.
static constexpr size_t MAX_VISIBLE_MESSAGES
static constexpr float PADDING
static constexpr float INPUT_HEIGHT
void Render()
Render the chat widget.
static constexpr float MESSAGE_SPACING
std::shared_ptr< UI::ITextInput > _textInput
void SetOnMessageSent(std::function< void(const std::string &)> callback)
Set callback for when a message is sent.
std::string FormatMessage(const ChatMessageData &msg)
void ClearMessages()
Clear all messages.
static constexpr float WIDGET_HEIGHT
void SetVisible(bool visible)
Set widget visibility.
static constexpr float MESSAGE_LINE_HEIGHT
void OnTextChanged(const std::string &text)
static constexpr size_t MAX_MESSAGE_BUFFER
UI::IUIFactory & _uiFactory
static constexpr size_t MAX_CHAR_PER_MESSAGE
static constexpr float WIDGET_WIDTH
Graphics::IGraphics & _graphics
std::deque< ChatMessageData > _messages
void Initialize()
Initialize the chat widget.
void Update()
Update the chat widget.
void AddMessage(uint32_t playerId, const std::string &playerName, const std::string &message, uint64_t timestamp)
Add a message to the chat history.
std::function< void(const std::string &)> _onMessageSent
ChatWidget(UI::IUIFactory &uiFactory, Graphics::IGraphics &graphics)
Abstract interface for graphics rendering operations.
Definition IGraphics.hpp:32
virtual void DrawText(int fontHandle, const char *text, int x, int y, int fontSize, unsigned int color)=0
Draw text using a loaded font.
virtual void DrawRectangleLines(int x, int y, int width, int height, unsigned int color)=0
Draw a rectangle outline (alias for DrawRect)
virtual void DrawRectangle(int x, int y, int width, int height, unsigned int color)=0
Draw a filled rectangle (alias for DrawRectFilled)
Abstract factory interface for creating UI elements.
virtual std::unique_ptr< ITextInput > CreateTextInput()=0
Create a text input instance.
Chat message data.