From e4483eca01b48b943cd0461e24a74ae1a3139ed4 Mon Sep 17 00:00:00 2001 From: Nicolas James Date: Wed, 12 Feb 2025 21:57:46 +1100 Subject: Update to most recent version (old initial commit) --- src/client/window.cc | 449 --------------------------------------------------- 1 file changed, 449 deletions(-) delete mode 100644 src/client/window.cc (limited to 'src/client/window.cc') diff --git a/src/client/window.cc b/src/client/window.cc deleted file mode 100644 index 6a11252..0000000 --- a/src/client/window.cc +++ /dev/null @@ -1,449 +0,0 @@ -#include "window.hh" - -namespace client { -namespace window { - -// All window objects should derive from basic_window, and make use of multiple -// inheritance for specific behaviours. -class basic_window { -protected: - // Colours borrowed from arc-dark(er). - static constexpr glm::vec3 primary_clr{0.21f, 0.23f, 0.29f}; // dark - static constexpr glm::vec3 secondary_clr{0.29f, 0.32f, 0.38f}; // less dark - static constexpr glm::vec3 tertiary_clr{0.48, 0.50, 0.54}; // less dark ^2 - static constexpr glm::vec3 highlight_clr{0.32, 0.58, 0.88}; // light blue - static constexpr glm::vec3 font_colour{0.88, 0.88, 0.88}; // light grey - -protected: - glm::vec2 pos; - glm::vec2 size; - -public: - bool is_inside(const glm::vec2& v) const noexcept { - if (v.x < this->pos.x || v.x > this->pos.x + this->size.x) { - return false; - } - if (v.y < this->pos.y || v.y > this->pos.y + this->size.y) { - return false; - } - return true; - } - -public: - basic_window(const client::draw::relative_arg& p, - const client::draw::relative_arg& s) noexcept - : pos(p.to_vec2()), size(s.to_vec2()) {} - virtual ~basic_window() noexcept {} - - virtual bool maybe_handle_event(const SDL_Event&) noexcept { return false; } - virtual void draw() noexcept { - client::draw::draw_rectangle({.pos = {.offset = this->pos + 6.0f}, - .size = {.offset = this->size}, - .colour = {this->tertiary_clr, 0.9f}}); - client::draw::draw_rectangle({.pos = {.offset = this->pos}, - .size = {.offset = this->size}, - .colour = {this->primary_clr, 1.0f}}); - } -}; - -static void remove_top_layer() noexcept; -class text_input_window : public basic_window { -private: - // text restricted to a size of 32. - static const std::string& get_send_text() noexcept { - auto& text = client::input::state.text_input; - text = std::string{std::begin(text), - std::begin(text) + - static_cast(std::min( - std::size(text), shared::MAX_SAY_LENGTH))}; - return text; - } - static bool maybe_handle_keydown(const SDL_Event& event) noexcept { - if (event.key.keysym.sym == SDLK_BACKSPACE) { - if (!client::input::state.text_input.empty()) { - client::input::state.text_input.pop_back(); - } - return true; - } - - if (event.key.keysym.sym != SDLK_RETURN || event.key.repeat) { - return false; - } - - if (!client::input::state.text_input.empty()) { - client::send_say_packet(get_send_text()); - } - - remove_top_layer(); // DELETE ME - return true; - } - static const glm::vec3& get_draw_colour() noexcept { - if (client::input::state.text_input.length() >= - shared::MAX_SAY_LENGTH) { - return basic_window::highlight_clr; - } - return basic_window::primary_clr; - } - -public: - template - text_input_window(Args&&... args) noexcept - : basic_window(std::forward(args)...) { - client::input::set_text_input(true); - } - virtual ~text_input_window() noexcept { - client::input::set_text_input(false); - } - virtual bool maybe_handle_event(const SDL_Event& event) noexcept override { - switch (event.type) { - case SDL_KEYDOWN: - return this->maybe_handle_keydown(event); - } - - return basic_window::maybe_handle_event(event); - } - - virtual void draw() noexcept override { - basic_window::draw(); - - client::draw::draw_rectangle( - {.pos = {.offset = this->pos}, - .size = {.offset = this->size}, - .colour = {this->get_draw_colour(), 1.0f}}); - - client::draw::draw_text( - this->get_send_text(), - {.pos = {.extent = {0.0f, 0.0f}, - .offset = this->pos + (this->size / 2.0f)}, - .offset_height = this->size.y / 2.0f, - .colour = {this->font_colour, 1.0f}, - .has_backing = false, - .is_centered = true, - .is_vcentered = true}); - }; -}; - -class button_window : public basic_window { -protected: - std::string name; - std::function callback; - bool is_pressed; - -private: - void handle_mousebuttondown(const SDL_Event& event) noexcept { - if (event.button.button != SDL_BUTTON_LEFT) { - return; - } - this->is_pressed = true; - } - void handle_mousebuttonup(const SDL_Event& event) noexcept { - if (event.button.button != SDL_BUTTON_LEFT) { - return; - } - if (!this->is_pressed) { - return; - } - this->is_pressed = false; - std::invoke(this->callback); // edge - } - const glm::vec3& get_draw_colour() noexcept { - if (!this->is_inside(client::input::state.mouse_pos)) { - this->is_pressed = false; - return this->primary_clr; - } - - if (!this->is_pressed) { - return this->secondary_clr; - } - - return this->highlight_clr; - } - -public: - template - button_window(const std::string_view n, const decltype(callback)& c, - Args&&... args) noexcept - : basic_window(std::forward(args)...), name(n), callback(c) {} - - virtual bool maybe_handle_event(const SDL_Event& event) noexcept override { - if (this->is_inside(client::input::state.mouse_pos)) { - switch (event.type) { - case SDL_MOUSEBUTTONDOWN: - this->handle_mousebuttondown(event); - return true; - case SDL_MOUSEBUTTONUP: - this->handle_mousebuttonup(event); - return true; - } - } - - return basic_window::maybe_handle_event(event); - } - virtual void draw() noexcept override { - basic_window::draw(); - - client::draw::draw_rectangle( - {.pos = {.offset = this->pos}, - .size = {.offset = this->size}, - .colour = {this->get_draw_colour(), 1.0f}}); - client::draw::draw_text( - this->name, {.pos = {.extent = {0.0f, 0.0f}, - .offset = this->pos + (this->size / 2.0f)}, - .offset_height = this->size.y / 2.0f, - .colour = {this->font_colour, 1.0f}, - .has_backing = false, - .is_centered = true, - .is_vcentered = true}); - }; -}; - -// Sliders are for numerical values of some type T. -// TODO -/* -template -class slider_window : public basic_window { -protected: - std::string name; - T min; - T cur; - T max; - T& var; - -private: - void handle_mousebuttondown(const SDL_Event& event) noexcept {} - void handle_mousebuttonup(const SDL_Event& event) noexcept {} - -public: - template - slider_window(const std::string_view name, const T& min, const T& cur, - const T& max, T& var, Args&&... args) noexcept - : basic_window(std::forward(args)...), name(name), min(min), - cur(cur), max(max), var(var) {} - - // slider_window( - virtual bool maybe_handle_event(const SDL_Event& event) noexcept -override { switch (event.type) { case SDL_MOUSEBUTTONDOWN: - this->handle_mousebuttondown(event); - return true; - case SDL_MOUSEBUTTONUP: - this->handle_mousebuttonup(event); - return true; - } - return basic_window::maybe_handle_event(event); - } - virtual void draw() noexcept override { basic_window::draw(); } -}; -*/ - -static void handle_event(const SDL_Event& event) noexcept; // ignore - -// All windows go in this list! -using layer = std::forward_list>; -using layers = std::forward_list; -static layers& get_layers() noexcept { - // We callbacks for our window manager are initialised here too. - static layers ret = []() -> layers { - client::input::register_event_handler(&handle_event); - client::input::set_text_input(false); - client::input::set_mouse_relative(true); - return {}; - }(); - return ret; -} - -static void remove_top_layer() noexcept { - if (!get_layers().empty()) { - get_layers().pop_front(); - } - // Our windows might be empty here, so set our mouse mode accordingly. - if (!client::window::is_open()) { - client::input::set_mouse_relative(true); - } -} - -// Constants used for uniform ui sizes. -constexpr glm::vec2 lsize_extent{0.4, 0.075}; -constexpr glm::vec2 ssize_extent{0.15, 0.075}; - -static void center_mouse_position() noexcept { - const glm::vec2& window = client::render::get_window_size(); - client::input::set_mouse_position({window.x / 2.0f, window.y / 2.0f}); -} - -template -void push_window(Args&&... args) noexcept { - get_layers().front().push_front( - std::make_unique(std::forward(args)...)); -} - -constexpr glm::vec2 center_extent(const glm::vec2 pos, - const glm::vec2 size) noexcept { - return {pos.x, pos.y - size.y / 2.0f}; -} - -static void make_options_menu() noexcept { - get_layers().push_front({}); - - /* - push_window<::slider_window>( - "Field of Vision", 0.0f, - settings::get(std::make_pair("gameplay", "fov"), 100.0f), 145.0f, - remove_top_layer, - client::draw::relative_arg{.extent = - center_extent({0.3, 0.7}, - lsize_extent)}, client::draw::relative_arg{.extent = lsize_extent}); - */ - - push_window( - "Back", remove_top_layer, - client::draw::relative_arg{.extent = - center_extent({0.3, 0.3}, ssize_extent)}, - client::draw::relative_arg{.extent = ssize_extent}); -} - -static void make_main_menu() noexcept { - get_layers().push_front({}); - - push_window( - "Return to Game", remove_top_layer, - client::draw::relative_arg{.extent = - center_extent({0.3, 0.7}, lsize_extent)}, - client::draw::relative_arg{.extent = lsize_extent}); - - push_window( - "Options", make_options_menu, - client::draw::relative_arg{ - .extent = center_extent({0.55, 0.6}, ssize_extent)}, - client::draw::relative_arg{.extent = ssize_extent}); - - push_window( - "?", remove_top_layer, - client::draw::relative_arg{ - .extent = center_extent({0.55, 0.5}, ssize_extent)}, - client::draw::relative_arg{.extent = ssize_extent}); - - push_window( - "?", remove_top_layer, - client::draw::relative_arg{ - .extent = center_extent({0.55, 0.4}, ssize_extent)}, - client::draw::relative_arg{.extent = ssize_extent}); - - push_window( - "Exit Game", [] { shared::should_exit = true; }, - client::draw::relative_arg{.extent = - center_extent({0.3, 0.3}, lsize_extent)}, - client::draw::relative_arg{.extent = lsize_extent}); - - client::input::set_mouse_relative(false); - center_mouse_position(); -} - -static void make_chat_window() noexcept { - get_layers().push_front({}); - - push_window( - client::draw::relative_arg{.extent = - center_extent({0.3, 0.3}, lsize_extent)}, - client::draw::relative_arg{.extent = lsize_extent}); - - client::input::set_mouse_relative(false); - center_mouse_position(); -} - -static void handle_meta_return() noexcept { - if (!is_open()) { - make_chat_window(); - return; - } -} - -static void handle_meta_escape() noexcept { - if (!is_open()) { - make_main_menu(); - return; - } - - remove_top_layer(); -} - -static void handle_meta_keydown(const SDL_Event& event) noexcept { - if (event.key.repeat) { // only handle keypresses - return; - } - - switch (event.key.keysym.sym) { - case SDLK_ESCAPE: - handle_meta_escape(); - break; - case SDLK_RETURN: - handle_meta_return(); - break; - } -} - -static void handle_meta_mousemotion(const SDL_Event& event) noexcept { - // We convert SDL's weird coordinates into useful ones (0,0 = bottom - // left). - client::input::state.mouse_pos = { - event.motion.x, - static_cast(client::render::get_window_size().y) - event.motion.y}; -} - -static void handle_meta_windowevent(const SDL_Event& event) noexcept { - if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { - if (!is_open()) { - make_main_menu(); - return; - } - } -} - -static void handle_meta_event(const SDL_Event& event) noexcept { - switch (event.type) { - case SDL_KEYDOWN: - handle_meta_keydown(event); - break; - case SDL_MOUSEMOTION: - handle_meta_mousemotion(event); - break; - case SDL_WINDOWEVENT: - handle_meta_windowevent(event); - break; - } -} - -static void handle_event(const SDL_Event& event) noexcept { - // We ALWAYS update our mouse position. - if (event.type == SDL_MOUSEMOTION) { - handle_meta_mousemotion(event); - } - - // Either a window consumes our event, or no window does - so we send - // the event to our "meta handler" which does things like closing - // windows etc. - if (is_open()) { - for (const auto& window : get_layers().front()) { - if (window->maybe_handle_event(event)) { - return; - } - } - } - - handle_meta_event(event); -} - -void draw() noexcept { - if (!is_open()) { - return; - } - - client::draw::draw_colour({0.0f, 0.0f, 0.0f, 0.10f}); // very light shade - for (const auto& window : get_layers().front()) { - window->draw(); - } -} - -bool is_open() noexcept { return !get_layers().empty(); } - -} // namespace window -} // namespace client -- cgit v1.2.3