47 auto &buttons = buttonsResult.value().get();
48 for (
const auto &entity : buttons.entities()) {
49 auto &button = buttons[entity];
51 sf::RectangleShape rect(sf::Vector2f(button.size.x, button.size.y));
53 sf::Vector2f(button.position.x, button.position.y));
55 const uint8_t *color = button.idleColor;
58 color = button.hoverColor;
59 }
else if (button.state ==
61 color = button.pressedColor;
64 rect.setFillColor(sf::Color(color[0], color[1], color[2]));
65 rect.setOutlineColor(sf::Color::White);
66 rect.setOutlineThickness(2.0f);
71 sf::Font &font =
loadFont(
"assets/fonts/main.ttf");
73 text.setString(sf::String::fromUtf8(button.text.begin(),
75 text.setCharacterSize(24);
77 sf::FloatRect textBounds = text.getLocalBounds();
78 text.setOrigin(sf::Vector2f(textBounds.size.x / 2.0f,
79 textBounds.size.y / 2.0f));
80 text.setPosition(sf::Vector2f(
81 button.position.x + button.size.x / 2.0f,
82 button.position.y + button.size.y / 2.0f - 5.0f));
83 text.setFillColor(sf::Color::White);
86 }
catch (
const std::exception &e) {
87 log::error(
"Failed to render button text: {}", e.what());
98 auto &texts = textsResult.value().get();
99 for (
const auto &entity : texts.entities()) {
100 auto &textComp = texts[entity];
103 sf::Font &font =
loadFont(textComp.fontPath);
105 text.setString(sf::String::fromUtf8(textComp.content.begin(),
106 textComp.content.end()));
107 text.setCharacterSize(textComp.fontSize);
109 sf::Vector2f(textComp.position.x, textComp.position.y));
110 text.setFillColor(sf::Color(textComp.red, textComp.green,
111 textComp.blue, textComp.alpha));
114 }
catch (
const std::exception &e) {
115 log::error(
"Failed to render text '{}': {}", textComp.content,
143 auto &sliders = slidersResult.value().get();
144 for (
const auto &entity : sliders.entities()) {
145 auto &slider = sliders[entity];
147 sf::RectangleShape track(
148 sf::Vector2f(slider.size.x, slider.size.y));
150 sf::Vector2f(slider.position.x, slider.position.y));
151 track.setFillColor(sf::Color(slider.trackColor[0],
152 slider.trackColor[1],
153 slider.trackColor[2]));
156 float fillWidth = slider.size.x * slider.getNormalized();
157 sf::RectangleShape fill(sf::Vector2f(fillWidth, slider.size.y));
159 sf::Vector2f(slider.position.x, slider.position.y));
160 fill.setFillColor(sf::Color(
161 slider.fillColor[0], slider.fillColor[1], slider.fillColor[2]));
164 float handleX = slider.position.x + fillWidth - 5.0f;
165 sf::RectangleShape handle(
166 sf::Vector2f(10.0f, slider.size.y + 8.0f));
167 handle.setPosition(sf::Vector2f(handleX, slider.position.y - 4.0f));
168 handle.setFillColor(sf::Color(slider.handleColor[0],
169 slider.handleColor[1],
170 slider.handleColor[2]));
177 auto dropdownsResult =
179 if (!dropdownsResult)
182 auto &dropdowns = dropdownsResult.value().get();
184 for (
const auto &entity : dropdowns.entities()) {
185 auto &dropdown = dropdowns[entity];
187 sf::RectangleShape button(
188 sf::Vector2f(dropdown.size.x, dropdown.size.y));
190 sf::Vector2f(dropdown.position.x, dropdown.position.y));
191 button.setFillColor(sf::Color(
192 dropdown.bgColor[0], dropdown.bgColor[1], dropdown.bgColor[2]));
193 button.setOutlineColor(sf::Color::White);
194 button.setOutlineThickness(2.0f);
198 sf::Font &font =
loadFont(
"assets/fonts/main.ttf");
199 std::string selectedText = dropdown.getSelected();
201 text.setString(sf::String::fromUtf8(selectedText.begin(),
202 selectedText.end()));
203 text.setCharacterSize(20);
204 text.setPosition(sf::Vector2f(dropdown.position.x + 10.0f,
205 dropdown.position.y + 8.0f));
206 text.setFillColor(sf::Color(dropdown.textColor[0],
207 dropdown.textColor[1],
208 dropdown.textColor[2]));
211 sf::Text arrow(font);
212 arrow.setString(dropdown.isOpen ?
"^" :
"v");
213 arrow.setCharacterSize(16);
215 sf::Vector2f(dropdown.position.x + dropdown.size.x - 30.0f,
216 dropdown.position.y + 10.0f));
217 arrow.setFillColor(sf::Color::White);
219 }
catch (
const std::exception &e) {
220 log::error(
"Failed to render dropdown: {}", e.what());
224 for (
const auto &entity : dropdowns.entities()) {
225 auto &dropdown = dropdowns[entity];
227 if (dropdown.isOpen) {
229 sf::Font &font =
loadFont(
"assets/fonts/main.ttf");
230 float optionY = dropdown.position.y + dropdown.size.y;
232 for (
size_t i = 0; i < dropdown.options.size(); ++i) {
233 sf::RectangleShape optionBg(
234 sf::Vector2f(dropdown.size.x, dropdown.size.y));
235 optionBg.setPosition(
236 sf::Vector2f(dropdown.position.x, optionY));
238 if (
static_cast<int>(i) == dropdown.hoveredIndex) {
239 optionBg.setFillColor(sf::Color(
240 dropdown.hoverColor[0], dropdown.hoverColor[1],
241 dropdown.hoverColor[2]));
243 optionBg.setFillColor(sf::Color(
244 dropdown.bgColor[0], dropdown.bgColor[1],
245 dropdown.bgColor[2]));
247 optionBg.setOutlineColor(sf::Color::White);
248 optionBg.setOutlineThickness(1.0f);
251 sf::Text optionText(font);
252 optionText.setString(
253 sf::String::fromUtf8(dropdown.options[i].begin(),
254 dropdown.options[i].end()));
255 optionText.setCharacterSize(20);
256 optionText.setPosition(sf::Vector2f(
257 dropdown.position.x + 10.0f, optionY + 8.0f));
258 optionText.setFillColor(sf::Color::White);
261 optionY += dropdown.size.y;
263 }
catch (
const std::exception &e) {
264 log::error(
"Failed to render dropdown options: {}",
278 auto &inputs = inputsResult.
value().get();
280 for (
const auto &entity : inputs.entities()) {
281 auto &input = inputs[entity];
283 if (input.isFocused) {
284 input.blinkTimer += dt;
285 if (input.blinkTimer >= input.blinkInterval) {
286 input.blinkTimer = 0.0f;
287 input.showCursor = !input.showCursor;
290 input.showCursor =
false;
291 input.blinkTimer = 0.0f;
294 sf::RectangleShape box(sf::Vector2f(input.size.x, input.size.y));
295 box.setPosition(sf::Vector2f(input.position.x, input.position.y));
296 box.setFillColor(sf::Color(input.bgColor[0], input.bgColor[1],
297 input.bgColor[2], input.alpha));
300 input.isFocused ? input.focusBorderColor : input.borderColor;
301 box.setOutlineColor(sf::Color(bc[0], bc[1], bc[2], input.alpha));
302 box.setOutlineThickness(2.0f);
307 sf::Font &font =
loadFont(input.fontPath);
309 const bool empty = input.value.empty();
310 std::string display =
311 empty ? input.placeholder : input.getDisplayValue();
315 sf::String::fromUtf8(display.begin(), display.end()));
316 text.setCharacterSize(input.fontSize);
317 text.setPosition(sf::Vector2f(input.position.x + 10.0f,
318 input.position.y + 8.0f));
321 text.setFillColor(sf::Color(
322 input.placeholderColor[0], input.placeholderColor[1],
323 input.placeholderColor[2], input.alpha));
326 sf::Color(input.textColor[0], input.textColor[1],
327 input.textColor[2], input.alpha));
332 if (input.isFocused && input.showCursor) {
333 sf::FloatRect bounds = text.getLocalBounds();
335 input.position.x + 10.0f + bounds.size.x + 2.0f;
336 float cursorY = input.position.y + 10.0f;
338 sf::RectangleShape cursor(
339 sf::Vector2f(2.0f,
static_cast<float>(input.fontSize)));
340 cursor.setPosition(sf::Vector2f(cursorX, cursorY));
341 cursor.setFillColor(sf::Color(255, 255, 255, input.alpha));
344 }
catch (
const std::exception &e) {
345 log::error(
"Failed to render TextInput: {}", e.what());
357 auto &sprites = spritesResult.value().get();
358 for (
const auto &entity : sprites.entities()) {
359 auto &spritePreview = sprites[entity];
362 sf::Texture &texture =
loadTexture(spritePreview.texturePath);
363 sf::Sprite sprite(texture);
367 bool isCustomSprite =
368 spritePreview.texturePath.find(
"custom/") !=
371 if (!isCustomSprite) {
374 sprite.setTextureRect(sf::IntRect(
375 sf::Vector2i(spritePreview.rectLeft,
376 spritePreview.rectTop),
377 sf::Vector2i(spritePreview.rectWidth,
378 spritePreview.rectHeight)));
381 if (spritePreview.texturePath.find(
"r-typesheet1.gif") !=
383 spritePreview.rectLeft == 0 &&
384 spritePreview.rectTop == 0) {
386 "Rendering Player Ship sprite: rect({},{}) "
388 spritePreview.rectLeft, spritePreview.rectTop,
389 spritePreview.rectWidth, spritePreview.rectHeight);
395 sprite.setScale(sf::Vector2f(spritePreview.scale,
396 spritePreview.scale));
398 sf::Vector2f(spritePreview.x, spritePreview.y));
401 }
catch (
const std::exception &e) {
402 log::error(
"Failed to render sprite preview '{}': {}",
403 spritePreview.texturePath, e.what());
Component representing text to render.