#pragma once #include "graphics/opengl/framebuffer.hpp" #include "window/input_system.hpp" #include "window/window.hpp" #include #include #include #include #include namespace kuiper { class glfw_window : public window { public: glfw_window( std::uint32_t width, std::uint32_t height, std::u8string_view title, GLFWmonitor* monitor, GLFWwindow* share); ~glfw_window() override; // Only allow moving glfw_window(const glfw_window& other) = delete; glfw_window& operator=(const glfw_window& other) = delete; glfw_window(glfw_window&& other) noexcept = default; glfw_window& operator=(glfw_window&& other) noexcept = default; public: // Implement window virtual void* get_native_handle() const noexcept override; virtual void set_title(std::u8string_view title) noexcept override; virtual void poll_events() noexcept override; virtual void swap_buffers() noexcept override; virtual void set_swap_interval(std::uint32_t interval) noexcept override; virtual void bind_context() noexcept override; virtual gl::framebuffer::s_ptr back_buffer() const noexcept override; virtual bool should_close() const noexcept override; virtual bool is_minimised() const noexcept override; virtual bool is_cursor_locked() const noexcept override; virtual void lock_cursor() noexcept override; virtual void unlock_cursor() noexcept override; virtual void enable_raw_input() noexcept override; virtual void disable_raw_input() noexcept override; virtual glm::uvec2 get_size() const noexcept override; virtual glm::uvec2 get_framebuffer_size() const noexcept override; // should this go in render context? virtual glm::vec2 get_content_scale() const noexcept override; input_system& input() noexcept { return m_input_state; } private: void resize_back_buffer() noexcept; public: static void initialise_glfw(bool prefer_x11); private: static GLFWwindow* create_glfw_window(std::uint32_t width, std::uint32_t height, std::u8string_view title, GLFWmonitor* monitor, GLFWwindow* share) noexcept; static void push_window_hints() noexcept; // GLFW Callbacks static void glfw_error_callback(int error_code, const char* description); static void glfw_framebuffer_size_callback(GLFWwindow* window, int width, int height); static void glfw_content_scale_callback(GLFWwindow* window, float xscale, float yscale); static void glfw_key_event_callback(GLFWwindow* window, int key, int scancode, int action, int mods); static void glfw_cursor_pos_callback(GLFWwindow* window, double xpos, double ypos); static void glfw_scroll_callback(GLFWwindow* window, double xoffset, double yoffset); static void glfw_dragdrop_callback(GLFWwindow* window, int path_count, const char* paths[]); private: GLFWwindow* m_window_handle = nullptr; input_system m_input_state {}; bool m_cursor_locked = false; gl::framebuffer::s_ptr m_default_framebuffer = nullptr; }; } // namespace kuiper