diff --git a/client/src/game_state.cpp b/client/src/game_state.cpp index 014909a..9c937ff 100644 --- a/client/src/game_state.cpp +++ b/client/src/game_state.cpp @@ -70,7 +70,7 @@ void GameState::start_single_player_now(int screen_width, int screen_height) { _init_desktop(); } -void GameState::handle_event(SDL_Event* event) { +void GameState::handle_event(SDL_Event* event, int screen_width, int screen_height) { switch(_current_screen) { case Screen::MAIN_MENU: if(_main_menu) { @@ -82,7 +82,7 @@ void GameState::handle_event(SDL_Event* event) { break; case Screen::DESKTOP: if(_desktop) { - _desktop->handle_event(event, _screen_height); + _desktop->handle_event(event, screen_width, screen_height); } break; } diff --git a/client/src/game_state.h b/client/src/game_state.h index d45cc18..15d2570 100644 --- a/client/src/game_state.h +++ b/client/src/game_state.h @@ -23,7 +23,7 @@ public: void init(int screen_width, int screen_height); void start_single_player_now(int screen_width, int screen_height); - void handle_event(SDL_Event* event); + void handle_event(SDL_Event* event, int screen_width, int screen_height); void update(void); void render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, int screen_height, bool show_cursor); diff --git a/client/src/main.cpp b/client/src/main.cpp index 7879c7d..e257b37 100644 --- a/client/src/main.cpp +++ b/client/src/main.cpp @@ -94,7 +94,7 @@ int main(int argc, char** argv) { SDL_Event event; while(SDL_PollEvent(&event)) { if(event.type == SDL_EVENT_QUIT) { running = false; } - game_state->handle_event(&event); + game_state->handle_event(&event, SCREEN_WIDTH, SCREEN_HEIGHT); } game_state->update(); diff --git a/client/src/ui/desktop.cpp b/client/src/ui/desktop.cpp index 947f547..a8c3640 100644 --- a/client/src/ui/desktop.cpp +++ b/client/src/ui/desktop.cpp @@ -55,7 +55,7 @@ void Desktop::_set_focused_window(UIWindow* window) { } } -void Desktop::handle_event(SDL_Event* event, int screen_height) { +void Desktop::handle_event(SDL_Event* event, int screen_width, int screen_height) { if(event->type == SDL_EVENT_MOUSE_BUTTON_DOWN) { int mouse_x = event->button.x; int mouse_y = event->button.y; @@ -95,7 +95,8 @@ void Desktop::handle_event(SDL_Event* event, int screen_height) { } if(_focused_window) { - _focused_window->handle_event(event); + _focused_window->handle_event(event, screen_width, screen_height, + _taskbar->get_height()); Terminal* content = _focused_window->get_content(); if(content && (event->type == SDL_EVENT_TEXT_INPUT || event->type == SDL_EVENT_KEY_DOWN)) { content->handle_input(event); diff --git a/client/src/ui/desktop.h b/client/src/ui/desktop.h index de8c8f4..2418bf1 100644 --- a/client/src/ui/desktop.h +++ b/client/src/ui/desktop.h @@ -15,7 +15,7 @@ public: ~Desktop(void); void add_window(std::unique_ptr window); - void handle_event(SDL_Event* event, int screen_height); + void handle_event(SDL_Event* event, int screen_width, int screen_height); void update(void); void render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, int screen_height, bool show_cursor); diff --git a/client/src/ui/ui_window.cpp b/client/src/ui/ui_window.cpp index e20dd37..f1479cc 100644 --- a/client/src/ui/ui_window.cpp +++ b/client/src/ui/ui_window.cpp @@ -18,7 +18,12 @@ UIWindow::UIWindow(const char* title, int x, int y, int width, int height) : _should_close(false), _state(WindowState::NORMAL), _is_resizing(false), - _resize_margin(10) {} + _resize_margin(10) { + /* Init title bar buttons. */ + _title_bar_buttons.push_back({WindowButtonAction::CLOSE, {0.8f, 0.2f, 0.2f}}); + _title_bar_buttons.push_back({WindowButtonAction::MAXIMIZE, {0.2f, 0.8f, 0.2f}}); + _title_bar_buttons.push_back({WindowButtonAction::MINIMIZE, {0.8f, 0.8f, 0.2f}}); +} UIWindow::~UIWindow(void) {} @@ -74,8 +79,6 @@ void UIWindow::render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, const Color title_bar_color = { 0.15f, 0.15f, 0.2f }; const Color focused_title_bar_color = { 0.3f, 0.3f, 0.4f }; const Color title_text_color = { 0.9f, 0.9f, 0.9f }; - const Color close_button_color = { 0.8f, 0.2f, 0.2f }; - const Color minimize_button_color = { 0.8f, 0.8f, 0.2f }; const Color resize_handle_color = { 0.9f, 0.9f, 0.9f }; /* Convert top-left coords to bottom-left for OpenGL. */ @@ -97,14 +100,15 @@ void UIWindow::render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, txt_renderer->render_text(_title.c_str(), _x+5, y_gl+_height-title_bar_height+8, 1.0f, title_text_color); - /* Draw close button. */ - shape_renderer->draw_rect(_x + _width - 25, y_gl + _height - title_bar_height + 5, - 20, 20, close_button_color); - - /* Draw minimize button. */ - shape_renderer->draw_rect(_x + _width - 50, - y_gl + _height - title_bar_height + 5, 20, 20, - minimize_button_color); + /* Draw title bar buttons. */ + int button_size = 20; + int button_margin = 5; + int x_offset = _x + _width - button_size - button_margin; + for(const auto& button : _title_bar_buttons) { + shape_renderer->draw_rect(x_offset, y_gl + _height - title_bar_height + button_margin, + button_size, button_size, button.color); + x_offset -= (button_size + button_margin); + } /* Draw Resize handle. */ int corner_x = _x + _width; @@ -119,36 +123,55 @@ void UIWindow::render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, } } -void UIWindow::handle_event(SDL_Event* event) { +void UIWindow::handle_event(SDL_Event* event, int screen_width, + int screen_height, int taskbar_height) { 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; - /* Check for close button click. */ - int close_button_x = _x + _width - 25; - int close_button_y = _y + 5; - if(mouse_x >= close_button_x && mouse_x <= close_button_x + 20 && - mouse_y >= close_button_y && mouse_y <= close_button_y + 20) { - _should_close = true; - return; /* Stop processing this event. */ - } - - /* Check for minimize button click. */ - int minimize_button_x = _x + _width - 50; - int minimize_button_y = _y + 5; - if(mouse_x >= minimize_button_x && mouse_x <= minimize_button_x + 20 && - mouse_y >= minimize_button_y && mouse_y <= minimize_button_y + 20) { - minimize(); - return; /* Stop processing this event. */ + /* Check for title bar button clicks. */ + int button_size = 20; + int button_margin = 5; + int x_offset = _x + _width - button_size - button_margin; + for(const auto& button : _title_bar_buttons) { + if(mouse_x >= x_offset && mouse_x <= x_offset + button_size && + mouse_y >= _y + button_margin && mouse_y <= _y + button_margin + button_size) { + switch(button.action) { + case WindowButtonAction::CLOSE: + _should_close = true; + break; + case WindowButtonAction::MAXIMIZE: + if(_state == WindowState::MAXIMIZED) { + _x = _pre_maximize_rect.x; + _y = _pre_maximize_rect.y; + _width = _pre_maximize_rect.w; + _height = _pre_maximize_rect.h; + _state = WindowState::NORMAL; + } else { + _pre_maximize_rect = { _x, _y, _width, _height }; + _x = 0; _y = taskbar_height; + _width = screen_width; _height = screen_height - taskbar_height; + _state = WindowState::MAXIMIZED; + } + break; + case WindowButtonAction::MINIMIZE: + minimize(); + break; + } + return; /* Button clicked, no need to process further. */ + } + x_offset -= (button_size + button_margin); } /* Check for resize handle click (bottom-right corner). */ - if(is_mouse_over_resize_handle(mouse_x, mouse_y)) { + if(is_mouse_over_resize_handle(mouse_x, mouse_y) && + _state != WindowState::MAXIMIZED) { _is_resizing = true; } else if(mouse_x >= _x && mouse_x <= _x + _width && - mouse_y >= _y && mouse_y <= _y + title_bar_height) { + mouse_y >= _y && mouse_y <= _y + title_bar_height && + _state != WindowState::MAXIMIZED) { /* Is click within title bar? */ _is_dragging = true; _drag_offset_x = mouse_x - _x; diff --git a/client/src/ui/ui_window.h b/client/src/ui/ui_window.h index 129cc4b..666080f 100644 --- a/client/src/ui/ui_window.h +++ b/client/src/ui/ui_window.h @@ -13,6 +13,17 @@ enum class WindowState { MAXIMIZED }; +enum class WindowButtonAction { + CLOSE, + MAXIMIZE, + MINIMIZE +}; + +struct TitleBarButton { + WindowButtonAction action; + Color color; +}; + class UIWindow { public: UIWindow(const char* title, int x, int y, int width, int height); @@ -20,7 +31,8 @@ public: void render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, int screen_height, bool show_cursor); - void handle_event(SDL_Event* event); + void handle_event(SDL_Event* event, int screen_width, int screen_height, + int taskbar_height); void minimize(void); void restore(void); bool is_minimized(void) const; @@ -42,6 +54,7 @@ private: bool _is_hovered; /* Send scroll events even if not focused. */ bool _should_close; + std::vector _title_bar_buttons; WindowState _state; bool _is_dragging;