[Add] Desktop and draggable UI windows.

This commit is contained in:
Ritchie Cunningham 2025-09-20 13:48:12 +01:00
parent 1bce18e993
commit 8a902d3034
5 changed files with 94 additions and 7 deletions

View File

@ -5,6 +5,7 @@
#include "terminal.h" #include "terminal.h"
#include "gfx/shape_renderer.h" #include "gfx/shape_renderer.h"
#include "ui/desktop.h"
#include "ui/ui_window.h" #include "ui/ui_window.h"
const int SCREEN_WIDTH = 1280; const int SCREEN_WIDTH = 1280;
@ -63,13 +64,17 @@ int main(int argc, char** argv) {
/* Init shape renderer. */ /* Init shape renderer. */
ShapeRenderer* shape_renderer_instance = new ShapeRenderer(SCREEN_WIDTH, SCREEN_HEIGHT); ShapeRenderer* shape_renderer_instance = new ShapeRenderer(SCREEN_WIDTH, SCREEN_HEIGHT);
/* Create UI window. */
UIWindow* test_window = new UIWindow("Terminal", 100, 100, 800, 500);
/* Create terminal. */ /* Create terminal. */
Terminal* term = new Terminal(); Terminal* term = new Terminal();
/* Create UI window and pass it a terminal. */
UIWindow* test_window = new UIWindow("Terminal", 100, 100, 800, 500);
test_window->set_content(term); test_window->set_content(term);
/* Create desktop and add the window. */
Desktop* desktop = new Desktop();
desktop->add_window(test_window);
bool running = true; bool running = true;
while(running) { while(running) {
/* Event handling. */ /* Event handling. */
@ -77,6 +82,7 @@ int main(int argc, char** argv) {
while(SDL_PollEvent(&event)) { while(SDL_PollEvent(&event)) {
if(event.type == SDL_EVENT_QUIT) { running = false; } if(event.type == SDL_EVENT_QUIT) { running = false; }
/* Pass input to terminal. */ /* Pass input to terminal. */
desktop->handle_event(&event);
term->handle_input(&event); term->handle_input(&event);
} }
@ -84,13 +90,14 @@ int main(int argc, char** argv) {
glClearColor(0.1f, 0.1f, 0.1, 1.0f); glClearColor(0.1f, 0.1f, 0.1, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
test_window->render(shape_renderer_instance, txt_render_instance, SCREEN_HEIGHT); desktop->render(shape_renderer_instance, txt_render_instance, SCREEN_HEIGHT);
/* It's really odd to call it SwapWindow now, rather than SwapBuffer. */ /* It's really odd to call it SwapWindow now, rather than SwapBuffer. */
SDL_GL_SwapWindow(window); SDL_GL_SwapWindow(window);
} }
/* Cleanup. */ /* Cleanup. */
delete desktop;
delete term; delete term;
delete test_window; delete test_window;
delete shape_renderer_instance; delete shape_renderer_instance;

29
client/src/ui/desktop.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "desktop.h"
#include "gfx/shape_renderer.h"
#include "gfx/txt_renderer.h"
#include "ui/ui_window.h"
Desktop::Desktop(void) {}
/* Desktop won't own the windows, so doesn't delete them. */
Desktop::~Desktop(void) {}
void Desktop::add_window(UIWindow* window) {
_windows.push_back(window);
}
void Desktop::handle_event(SDL_Event* event) {
/* Just pass the even to all windows for the moment.
* TODO: Only send event to the focused window.
*/
for(auto win : _windows) {
win->handle_event(event);
}
}
void Desktop::render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer,
int screen_height) {
for(auto win: _windows) {
win->render(shape_renderer, txt_renderer, screen_height);
}
}

21
client/src/ui/desktop.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
#include <vector>
#include <SDL3/SDL.h>
#include "gfx/shape_renderer.h"
#include "gfx/txt_renderer.h"
#include "ui/ui_window.h"
class Desktop {
public:
Desktop(void);
~Desktop(void);
void add_window(UIWindow* window);
void handle_event(SDL_Event* event);
void render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, int screen_height);
private:
std::vector<UIWindow*> _windows;
};

View File

@ -1,4 +1,5 @@
#include "ui_window.h" #include "ui_window.h"
#include <SDL3/SDL_events.h>
#include "gfx/shape_renderer.h" #include "gfx/shape_renderer.h"
#include "gfx/txt_renderer.h" #include "gfx/txt_renderer.h"
@ -9,6 +10,7 @@ UIWindow::UIWindow(const char* title, int x, int y, int width, int height) {
_width = width; _width = width;
_height = height; _height = height;
_content = nullptr; _content = nullptr;
_is_dragging = false;
} }
void UIWindow::set_content(Terminal* term) { void UIWindow::set_content(Terminal* term) {
@ -45,3 +47,27 @@ void UIWindow::render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer,
} }
} }
void UIWindow::handle_event(SDL_Event* event) {
int title_bar_height = 30;
if(event->type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
int mouse_x = event->button.x;
int mouse_y = event->button.y;
/* Is click within title bar? */
if(mouse_x >= _x && mouse_x <= _x + _width &&
mouse_y >= _y && mouse_y <= _y + title_bar_height) {
_is_dragging = true;
_drag_offset_x = mouse_x - _x;
_drag_offset_y = mouse_y - _y;
}
} else if(event->type == SDL_EVENT_MOUSE_BUTTON_UP) {
_is_dragging = false;
} else if(event->type == SDL_EVENT_MOUSE_MOTION) {
if(_is_dragging) {
_x = event->motion.x - _drag_offset_x;
_y = event->motion.y - _drag_offset_y;
}
}
}

View File

@ -11,11 +11,15 @@ public:
UIWindow(const char* title, int x, int y, int width, int height); UIWindow(const char* title, int x, int y, int width, int height);
void render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, int screen_height); void render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, int screen_height);
void handle_event(SDL_Event* event);
void set_content(Terminal* term); void set_content(Terminal* term);
private: private:
int _x, _y, _width, _height; int _x, _y, _width, _height;
std::string _title; std::string _title;
Terminal* _content; Terminal* _content;
bool _is_dragging;
int _drag_offset_x, _drag_offset_y;
}; };