bettola/client/src/ui/desktop.cpp
Ritchie Cunningham 00e78cc2ba [Refactor] One GameState to rule them all!
Introduces a central GameState class to manage the client's lifecycle,
network connection and UI components. The Terminal has been demoted to a
pure UI widget and main has been simplified to a basic entrypoint as
they should be!
2025-09-27 18:07:01 +01:00

77 lines
2.3 KiB
C++

#include <algorithm>
#include <memory>
#include "desktop.h"
#include <SDL3/SDL_events.h>
#include "gfx/shape_renderer.h"
#include "gfx/txt_renderer.h"
#include "terminal.h"
#include "ui/ui_window.h"
Desktop::Desktop(void) {
_focused_window = nullptr;
}
/* Desktop owns UIWindow, make sure we delete them. */
Desktop::~Desktop(void) {}
void Desktop::add_window(std::unique_ptr<UIWindow> window) {
_windows.push_back(std::move(window));
}
void Desktop::handle_event(SDL_Event* event) {
if(event->type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
int mouse_x = event->button.x;
int mouse_y = event->button.y;
/* Find the top-most window that was clicked. */
for(int i = _windows.size()-1; i >= 0; --i) {
if(_windows[i].get()->is_point_inside(mouse_x, mouse_y)) {
/* If not focused, focus it. */
if(_windows[i].get() != _focused_window) {
if(_focused_window) {
_focused_window->set_focused(false);
}
_focused_window = _windows[i].get();
_focused_window->set_focused(true);
/* Move window to the front. */
auto window_to_move = std::move(_windows[i]);
_windows.erase(_windows.begin() + i);
_windows.push_back(std::move(window_to_move));
}
break;
}
}
}
if(_focused_window) {
_focused_window->handle_event(event);
Terminal* content = _focused_window->get_content();
if(content && (event->type == SDL_EVENT_TEXT_INPUT || event->type == SDL_EVENT_KEY_DOWN)) {
content->handle_input(event);
}
}
}
void Desktop::update(void) {
/* Remove closed windows. */
_windows.erase(std::remove_if(_windows.begin(), _windows.end(),
[](const std::unique_ptr<UIWindow>& window) {
Terminal* term = window->get_content();
return term && term->close();
}),
_windows.end());
}
UIWindow* Desktop::get_focused_window(void) {
return _focused_window;
}
void Desktop::render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer,
int screen_height, bool show_cursor) {
for(const auto& win : _windows) {
win.get()->render(shape_renderer, txt_renderer, screen_height, show_cursor);
}
}