[Add] Window focus and event routing.
This commit is contained in:
parent
8a902d3034
commit
2d79aba17a
@ -81,9 +81,7 @@ int main(int argc, char** argv) {
|
|||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
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. */
|
|
||||||
desktop->handle_event(&event);
|
desktop->handle_event(&event);
|
||||||
term->handle_input(&event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear screen. */
|
/* Clear screen. */
|
||||||
|
|||||||
@ -1,9 +1,14 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "desktop.h"
|
#include "desktop.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"
|
||||||
#include "ui/ui_window.h"
|
#include "ui/ui_window.h"
|
||||||
|
|
||||||
Desktop::Desktop(void) {}
|
Desktop::Desktop(void) {
|
||||||
|
_focused_window = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/* Desktop won't own the windows, so doesn't delete them. */
|
/* Desktop won't own the windows, so doesn't delete them. */
|
||||||
Desktop::~Desktop(void) {}
|
Desktop::~Desktop(void) {}
|
||||||
@ -13,11 +18,36 @@ void Desktop::add_window(UIWindow* window) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Desktop::handle_event(SDL_Event* event) {
|
void Desktop::handle_event(SDL_Event* event) {
|
||||||
/* Just pass the even to all windows for the moment.
|
if(event->type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
|
||||||
* TODO: Only send event to the focused window.
|
int mouse_x = event->button.x;
|
||||||
*/
|
int mouse_y = event->button.y;
|
||||||
for(auto win : _windows) {
|
|
||||||
win->handle_event(event);
|
/* Find the top-most window that was clicked. */
|
||||||
|
for(int i = _windows.size()-1; i >= 0; --i) {
|
||||||
|
if(_windows[i]->is_point_inside(mouse_x, mouse_y)) {
|
||||||
|
/* If not focused, focus it. */
|
||||||
|
if(_windows[i] != _focused_window) {
|
||||||
|
if(_focused_window) {
|
||||||
|
_focused_window->set_focused(false);
|
||||||
|
}
|
||||||
|
_focused_window = _windows[i];
|
||||||
|
_focused_window->set_focused(true);
|
||||||
|
|
||||||
|
/* Move window to the front. */
|
||||||
|
_windows.erase(_windows.begin() + i);
|
||||||
|
_windows.push_back(_focused_window);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,4 +18,5 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<UIWindow*> _windows;
|
std::vector<UIWindow*> _windows;
|
||||||
|
UIWindow* _focused_window;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,20 +11,35 @@ UIWindow::UIWindow(const char* title, int x, int y, int width, int height) {
|
|||||||
_height = height;
|
_height = height;
|
||||||
_content = nullptr;
|
_content = nullptr;
|
||||||
_is_dragging = false;
|
_is_dragging = false;
|
||||||
|
_is_focused = false; /* Not focused by default? */
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIWindow::set_content(Terminal* term) {
|
void UIWindow::set_content(Terminal* term) {
|
||||||
_content = term;
|
_content = term;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UIWindow::set_focused(bool focused) {
|
||||||
|
_is_focused = focused;
|
||||||
|
}
|
||||||
|
|
||||||
|
Terminal* UIWindow::get_content(void) {
|
||||||
|
return _content;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UIWindow::is_point_inside(int x, int y) {
|
||||||
|
return (x >= _x && x <= _x + _width &&
|
||||||
|
y >= _y && y <= _y + _height);
|
||||||
|
}
|
||||||
|
|
||||||
void UIWindow::render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer,
|
void UIWindow::render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer,
|
||||||
int screen_height) {
|
int screen_height) {
|
||||||
int title_bar_height = 30;
|
int title_bar_height = 30;
|
||||||
|
|
||||||
/* Define colours. */
|
/* Define colours. */
|
||||||
float frame_color[] = { 0.2f, 0.2f, 0.25f };
|
float frame_color[] = { 0.2f, 0.2f, 0.25f };
|
||||||
float title_bar_color[] = { 0.15f, 0.15f, 0.2f };
|
float title_bar_color[] = { 0.15f, 0.15f, 0.2f };
|
||||||
float title_text_color[] = { 0.9f, 0.9f, 0.9f };
|
float focused_title_bar_color[] = { 0.3f, 0.3f, 0.4f };
|
||||||
|
float title_text_color[] = { 0.9f, 0.9f, 0.9f };
|
||||||
|
|
||||||
/* Convert top-left coords to bottom-left for OpenGL. */
|
/* Convert top-left coords to bottom-left for OpenGL. */
|
||||||
int y_gl = screen_height - _y - _height;
|
int y_gl = screen_height - _y - _height;
|
||||||
@ -33,8 +48,13 @@ void UIWindow::render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer,
|
|||||||
shape_renderer->draw_rect(_x, y_gl, _width, _height, frame_color);
|
shape_renderer->draw_rect(_x, y_gl, _width, _height, frame_color);
|
||||||
|
|
||||||
/* Draw title bar. */
|
/* Draw title bar. */
|
||||||
shape_renderer->draw_rect(_x, y_gl+_height-title_bar_height, _width, title_bar_height,
|
if(_is_focused) {
|
||||||
title_bar_color);
|
shape_renderer->draw_rect(_x, y_gl+_height-title_bar_height, _width, title_bar_height,
|
||||||
|
focused_title_bar_color);
|
||||||
|
} else {
|
||||||
|
shape_renderer->draw_rect(_x, y_gl+_height-title_bar_height, _width, title_bar_height,
|
||||||
|
title_bar_color);
|
||||||
|
}
|
||||||
|
|
||||||
/* Draw title text. */
|
/* Draw title text. */
|
||||||
txt_renderer->render_text(_title.c_str(), _x+5, y_gl+_height-title_bar_height+8,
|
txt_renderer->render_text(_title.c_str(), _x+5, y_gl+_height-title_bar_height+8,
|
||||||
|
|||||||
@ -12,12 +12,16 @@ public:
|
|||||||
|
|
||||||
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 handle_event(SDL_Event* event);
|
||||||
|
void set_focused(bool focused);
|
||||||
|
bool is_point_inside(int x, int y);
|
||||||
void set_content(Terminal* term);
|
void set_content(Terminal* term);
|
||||||
|
Terminal* get_content(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _x, _y, _width, _height;
|
int _x, _y, _width, _height;
|
||||||
std::string _title;
|
std::string _title;
|
||||||
Terminal* _content;
|
Terminal* _content;
|
||||||
|
bool _is_focused; /* Managed by desktop. */
|
||||||
|
|
||||||
bool _is_dragging;
|
bool _is_dragging;
|
||||||
int _drag_offset_x, _drag_offset_y;
|
int _drag_offset_x, _drag_offset_y;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user