aboutsummaryrefslogtreecommitdiff
path: root/src/client/window.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/window.cc')
-rw-r--r--src/client/window.cc449
1 files changed, 0 insertions, 449 deletions
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<long>(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 <typename... Args>
- text_input_window(Args&&... args) noexcept
- : basic_window(std::forward<Args>(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<void()> 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 <typename... Args>
- button_window(const std::string_view n, const decltype(callback)& c,
- Args&&... args) noexcept
- : basic_window(std::forward<Args>(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 <typename T>
-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 <typename... Args>
- 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>(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<std::unique_ptr<basic_window>>;
-using layers = std::forward_list<layer>;
-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 <typename T, typename... Args>
-void push_window(Args&&... args) noexcept {
- get_layers().front().push_front(
- std::make_unique<T>(std::forward<Args>(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<float>>(
- "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<button_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<button_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<button_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<button_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<button_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<button_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<text_input_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<int>(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