135 lines
4.4 KiB
C++
135 lines
4.4 KiB
C++
#include "display.hpp"
|
|
|
|
#include <stdexcept>
|
|
#include <utility>
|
|
|
|
namespace rog::ui {
|
|
|
|
GLFWwindow *display::create_window(glm::uvec2 extent, std::string_view title,
|
|
void *user_data) {
|
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
|
const auto window =
|
|
glfwCreateWindow(extent.x, extent.y, title.data(), nullptr, nullptr);
|
|
if (window == nullptr) {
|
|
auto description = static_cast<const char *>(nullptr);
|
|
glfwGetError(&description);
|
|
throw std::runtime_error(description);
|
|
}
|
|
glfwSetWindowUserPointer(window, user_data);
|
|
return window;
|
|
}
|
|
|
|
display::display(user_input *input, glm::uvec2 extent, std::string_view title)
|
|
: handle(create_window(extent, title, this)), title(title), input(input) {
|
|
glfwSetWindowSizeCallback(
|
|
handle, [](GLFWwindow *window, int width, int height) {
|
|
auto self = static_cast<display *>(glfwGetWindowUserPointer(window));
|
|
for (const auto &cb : self->resize_callbacks) {
|
|
cb(glm::uvec2(width, height));
|
|
}
|
|
});
|
|
glfwSetKeyCallback(handle, [](GLFWwindow *window, int key,
|
|
[[maybe_unused]] int scancode, int action,
|
|
[[maybe_unused]] int mods) {
|
|
auto self = static_cast<display *>(glfwGetWindowUserPointer(window));
|
|
if (action == GLFW_RELEASE) {
|
|
self->input->set_key_state(static_cast<key_code>(key),
|
|
key_state::released);
|
|
} else if (action == GLFW_REPEAT) {
|
|
self->input->set_key_state(static_cast<key_code>(key), key_state::repeat);
|
|
} else if (action == GLFW_PRESS) {
|
|
self->input->set_key_state(static_cast<key_code>(key),
|
|
key_state::pressed);
|
|
}
|
|
});
|
|
glfwSetCursorPosCallback(handle, [](GLFWwindow *window, double x, double y) {
|
|
static_cast<display *>(glfwGetWindowUserPointer(window))
|
|
->input->set_mouse_pos(glm::vec2{x, y});
|
|
});
|
|
glfwSetMouseButtonCallback(
|
|
handle, [](GLFWwindow *window, int button, int action, int mods) {
|
|
auto self = static_cast<display *>(glfwGetWindowUserPointer(window));
|
|
|
|
auto mouse_button = ui::mouse_button::left;
|
|
switch (button) {
|
|
case GLFW_MOUSE_BUTTON_LEFT:
|
|
mouse_button = ui::mouse_button::left;
|
|
break;
|
|
case GLFW_MOUSE_BUTTON_RIGHT:
|
|
mouse_button = ui::mouse_button::right;
|
|
break;
|
|
case GLFW_MOUSE_BUTTON_MIDDLE:
|
|
mouse_button = ui::mouse_button::middle;
|
|
break;
|
|
default:;
|
|
}
|
|
|
|
auto mouse_action = ui::button_state::down;
|
|
switch (action) {
|
|
case GLFW_PRESS:
|
|
mouse_action = ui::button_state::down;
|
|
break;
|
|
case GLFW_RELEASE:
|
|
mouse_action = ui::button_state::up;
|
|
break;
|
|
default:;
|
|
}
|
|
|
|
self->input->set_mouse_button(mouse_button, mouse_action);
|
|
});
|
|
}
|
|
|
|
display::~display() { glfwDestroyWindow(handle); }
|
|
|
|
display::display(const display &rhs)
|
|
: handle(create_window(rhs.extent(), rhs.title, this)), title(rhs.title) {
|
|
glfwSetWindowSizeCallback(
|
|
handle, [](GLFWwindow *window, int width, int height) {
|
|
auto self = static_cast<display *>(glfwGetWindowUserPointer(window));
|
|
for (const auto &cb : self->resize_callbacks) {
|
|
cb(glm::uvec2(width, height));
|
|
}
|
|
});
|
|
}
|
|
|
|
display::display(display &&rhs) noexcept
|
|
: handle(std::exchange(rhs.handle, nullptr)), title(rhs.title) {}
|
|
|
|
display &display::operator=(const display &rhs) { return *this = display(rhs); }
|
|
|
|
display &display::operator=(display &&rhs) noexcept {
|
|
std::swap(handle, rhs.handle);
|
|
std::swap(title, rhs.title);
|
|
return *this;
|
|
}
|
|
|
|
bool display::should_close() const noexcept {
|
|
return glfwWindowShouldClose(handle);
|
|
}
|
|
|
|
glm::uvec2 display::extent() const noexcept {
|
|
auto extent = glm::ivec2();
|
|
glfwGetFramebufferSize(handle, &extent.x, &extent.y);
|
|
return extent;
|
|
}
|
|
|
|
void display::poll_events() { glfwPollEvents(); }
|
|
|
|
vk::raii::SurfaceKHR
|
|
display::create_surface(const vk::raii::Instance &instance) {
|
|
auto c_surface = VkSurfaceKHR();
|
|
glfwCreateWindowSurface(*instance, handle, nullptr, &c_surface);
|
|
return vk::raii::SurfaceKHR(instance, c_surface);
|
|
}
|
|
|
|
void display::resize_callback(std::function<void(glm::uvec2 extent)> callback) {
|
|
resize_callbacks.push_back(callback);
|
|
}
|
|
|
|
GLFWwindow *display::raw() const noexcept { return handle; }
|
|
|
|
void display::request_close() noexcept {
|
|
glfwSetWindowShouldClose(handle, true);
|
|
}
|
|
} // namespace rog::ui
|