R-Type
Distributed multiplayer game engine in C++
Loading...
Searching...
No Matches
CreateRoomMenu.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** r-type
4** File description:
5** CreateRoomMenu - Menu for creating a new room
6*/
7
9#include <cstring>
10#include "../common/Logger/Logger.hpp"
11
12namespace Game {
14 : BaseMenu(uiFactory), _graphics(graphics) {}
15
17 std::function<void(const std::string &, uint32_t, bool, float)> onCreate) {
18 _onCreate = std::move(onCreate);
19 }
20
21 void CreateRoomMenu::SetOnCancel(std::function<void()> onCancel) {
22 _onCancel = std::move(onCancel);
23 }
24
26 if (!_menu) {
27 return;
28 }
29
30 _menu->Clear();
31
32 float screenWidth = static_cast<float>(_graphics.GetScreenWidth());
33 float centerX = screenWidth / 2.0f;
34
35 // Room Name Input
37 _roomNameInput->SetPosition(centerX - 200.0f, 150.0f);
38 _roomNameInput->SetSize(400.0f, 40.0f);
39 _roomNameInput->SetPlaceholder("Enter room name (3-30 characters)");
40 _roomNameInput->SetMaxLength(30);
41 _roomNameInput->SetValidationRegex("[a-zA-Z0-9_ -]+");
42 _roomNameInput->SetTextSize(18);
43 _roomNameInput->SetBackgroundColor(0xFF2A2A2A);
44 _roomNameInput->SetBorderColor(0xFF505050);
45 _roomNameInput->SetActiveBorderColor(0xFF4CAF50);
46 _roomNameInput->SetTextColor(0xFFFFFFFF);
47 _roomNameInput->SetPlaceholderColor(0xFF808080);
48 _roomNameInput->SetOnTextChanged([this](const std::string &) {
49 // Clear error when user types
50 _errorMessage.clear();
51 });
52
53 // Max Players Toggle Button
55 _maxPlayersButton->SetPosition(centerX - 200.0f, 220.0f);
56 _maxPlayersButton->SetSize(400.0f, 40.0f);
57 _maxPlayersButton->SetText("Max Players: 4");
58 _maxPlayersButton->SetBackgroundColor(0xFF2196F3);
59 _maxPlayersButton->SetHoverColor(0xFF64B5F6);
60 _maxPlayersButton->SetTextColor(0xFFFFFFFF);
61 _maxPlayersButton->SetCallback(WrapWithClickSound([this]() {
62 // Cycle through 2, 4, 8 players
63 if (_selectedMaxPlayers == 4) {
65 } else if (_selectedMaxPlayers == 8) {
67 } else {
69 }
70 _maxPlayersButton->SetText("Max Players: " + std::to_string(_selectedMaxPlayers));
71 }));
72 _menu->AddButton(_maxPlayersButton);
73
74 // Private Toggle Button
76 _privateButton->SetPosition(centerX - 200.0f, 280.0f);
77 _privateButton->SetSize(400.0f, 40.0f);
78 _privateButton->SetText("Private: No");
79 _privateButton->SetBackgroundColor(0xFF9E9E9E);
80 _privateButton->SetHoverColor(0xFFBDBDBD);
81 _privateButton->SetTextColor(0xFFFFFFFF);
82 _privateButton->SetCallback(WrapWithClickSound([this]() {
84 _privateButton->SetText(_isPrivate ? "Private: Yes" : "Private: No");
85 _privateButton->SetBackgroundColor(_isPrivate ? 0xFFFFA726 : 0xFF9E9E9E);
86 _privateButton->SetHoverColor(_isPrivate ? 0xFFFFB74D : 0xFFBDBDBD);
87 }));
88 _menu->AddButton(_privateButton);
89
90 // Game Speed Button (cycles through speed options: 100%, 75%, 50%, 25%)
92 _gameSpeedButton->SetPosition(centerX - 200.0f, 340.0f);
93 _gameSpeedButton->SetSize(400.0f, 40.0f);
95 _gameSpeedButton->SetBackgroundColor(0xFFFF9800); // Orange for speed
96 _gameSpeedButton->SetHoverColor(0xFFFFB74D);
97 _gameSpeedButton->SetTextColor(0xFFFFFFFF);
98 _gameSpeedButton->SetCallback([this]() {
99 // Cycle through: 100% -> 75% -> 50% -> 25% -> 100%
100 if (_gameSpeedMultiplier >= 1.0f) {
101 _gameSpeedMultiplier = 0.75f;
102 } else if (_gameSpeedMultiplier >= 0.75f) {
103 _gameSpeedMultiplier = 0.50f;
104 } else if (_gameSpeedMultiplier >= 0.50f) {
105 _gameSpeedMultiplier = 0.25f;
106 } else {
108 }
110 });
111 _menu->AddButton(_gameSpeedButton);
112
113 // Create Button
115 _createButton->SetPosition(centerX - 100.0f, 420.0f);
116 _createButton->SetSize(90.0f, 40.0f);
117 _createButton->SetText("CREATE");
118 _createButton->SetBackgroundColor(0xFF4CAF50);
119 _createButton->SetHoverColor(0xFF66BB6A);
120 _createButton->SetTextColor(0xFFFFFFFF);
121 _createButton->SetCallback(WrapWithClickSound([this]() { OnCreateClicked(); }));
122 _menu->AddButton(_createButton);
123
124 // Cancel Button
126 _cancelButton->SetPosition(centerX + 10.0f, 420.0f);
127 _cancelButton->SetSize(90.0f, 40.0f);
128 _cancelButton->SetText("CANCEL");
129 _cancelButton->SetBackgroundColor(0xFF424242);
130 _cancelButton->SetHoverColor(0xFF616161);
131 _cancelButton->SetTextColor(0xFFFFFFFF);
132 _cancelButton->SetCallback(WrapWithClickSound([this]() { OnCancelClicked(); }));
133 _menu->AddButton(_cancelButton);
134 }
135
137 if (!_menu || !_menu->IsVisible()) {
138 return;
139 }
140
141 // Update text input
142 if (_roomNameInput) {
143 _roomNameInput->Update();
144 }
145
147 }
148
150 if (!_menu || !_menu->IsVisible()) {
151 return;
152 }
153
154 // Draw title
155 const char *title = "Create New Room";
156 int screenWidth = _graphics.GetScreenWidth();
157 int titleFontSize = 32;
158 int titleWidth = static_cast<int>(strlen(title) * titleFontSize * 0.5f);
159 int titleX = (screenWidth - titleWidth) / 2;
160 _graphics.DrawText(title, titleX, 50, titleFontSize, 0xFFFFFFFF);
161
162 // Render text input
163 if (_roomNameInput) {
164 _roomNameInput->Render();
165 }
166
167 // Draw error message if present
168 if (!_errorMessage.empty()) {
169 int errorFontSize = 18;
170 int errorWidth = static_cast<int>(_errorMessage.length() * errorFontSize * 0.5f);
171 int errorX = (screenWidth - errorWidth) / 2;
172 _graphics.DrawText(_errorMessage.c_str(), errorX, 480, errorFontSize, 0xFFFF0000);
173 }
174
176 }
177
179 std::string roomName = _roomNameInput->GetText();
180
181 if (roomName.empty()) {
182 _errorMessage = "Room name cannot be empty!";
183 return false;
184 }
185
186 if (roomName.length() < 3) {
187 _errorMessage = "Room name must be at least 3 characters!";
188 return false;
189 }
190
191 if (roomName.length() > 30) {
192 _errorMessage = "Room name must be less than 30 characters!";
193 return false;
194 }
195
196 _errorMessage.clear();
197 return true;
198 }
199
201 LOG_INFO("[CreateRoomMenu] Create button clicked");
202
203 if (!ValidateInput()) {
204 LOG_WARNING("[CreateRoomMenu] Validation failed: ", _errorMessage);
205 return;
206 }
207
208 std::string roomName = _roomNameInput->GetText();
209 LOG_INFO("[CreateRoomMenu] Creating room: ", roomName, " (Max: ", _selectedMaxPlayers,
210 ", Private: ", _isPrivate ? "Yes" : "No",
211 ", Speed: ", static_cast<int>(_gameSpeedMultiplier * 100), "%)");
212
213 if (_onCreate) {
215 }
216
217 // Reset form
218 _roomNameInput->SetText("");
220 _isPrivate = false;
222 _maxPlayersButton->SetText("Max Players: 4");
223 _privateButton->SetText("Private: No");
224 _privateButton->SetBackgroundColor(0xFF9E9E9E);
225 _privateButton->SetHoverColor(0xFFBDBDBD);
227 _errorMessage.clear();
228 }
229
231 LOG_INFO("[CreateRoomMenu] Cancel button clicked");
232
233 // Reset form
234 _roomNameInput->SetText("");
237 _errorMessage.clear();
238
239 if (_onCancel) {
240 _onCancel();
241 }
242 }
243
245 int speedPercent = static_cast<int>(_gameSpeedMultiplier * 100);
246 std::string speedText = "Game Speed: " + std::to_string(speedPercent) + "%";
247 if (_gameSpeedButton) {
248 _gameSpeedButton->SetText(speedText);
249 }
250 }
251} // namespace Game
#define LOG_INFO(...)
Definition Logger.hpp:181
#define LOG_WARNING(...)
Definition Logger.hpp:182
Base class for all menu implementations.
Definition BaseMenu.hpp:26
virtual void Update()
Update menu state (should be called every frame).
Definition BaseMenu.cpp:16
std::shared_ptr< UI::IMenu > _menu
Definition BaseMenu.hpp:101
virtual void Render()
Render menu (should be called every frame).
Definition BaseMenu.cpp:22
std::function< void()> WrapWithClickSound(std::function< void()> callback)
Wrap a callback to play click sound before executing.
Definition BaseMenu.cpp:48
UI::IUIFactory & _uiFactory
Definition BaseMenu.hpp:100
std::shared_ptr< UI::IButton > _cancelButton
std::shared_ptr< UI::ITextInput > _roomNameInput
std::shared_ptr< UI::IButton > _createButton
void Initialize() override
Initialize menu (must be implemented by derived classes).
CreateRoomMenu(UI::IUIFactory &uiFactory, Graphics::IGraphics &graphics)
Graphics::IGraphics & _graphics
std::function< void()> _onCancel
std::function< void(const std::string &, uint32_t, bool, float)> _onCreate
void Render() override
Render menu (should be called every frame).
std::shared_ptr< UI::IButton > _maxPlayersButton
std::shared_ptr< UI::IButton > _gameSpeedButton
void SetOnCancel(std::function< void()> onCancel)
Set callback triggered when Cancel button is clicked.
void SetOnCreate(std::function< void(const std::string &, uint32_t, bool, float)> onCreate)
Set callback triggered when Create button is clicked.
std::shared_ptr< UI::IButton > _privateButton
void Update() override
Update menu state (should be called every frame).
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 int GetScreenWidth() const =0
Get the screen width (same as window width)
Abstract factory interface for creating UI elements.
virtual std::unique_ptr< ITextInput > CreateTextInput()=0
Create a text input instance.
virtual std::unique_ptr< IButton > CreateButton()=0
Create a button instance.