24 template <
typename RendererImpl,
typename Canvas>
53 GLFWmonitor* primaryMonitor = glfwGetPrimaryMonitor();
54 if (primaryMonitor ==
nullptr) {
55 throw std::runtime_error(
"Failed to get primary monitor");
59 const GLFWvidmode* videoMode = glfwGetVideoMode(primaryMonitor);
60 if (videoMode ==
nullptr) {
61 throw std::runtime_error(
"Failed to get primary monitor's video mode");
65 std::round(videoMode->width * 0.6), std::round(videoMode->height * 0.6), title);
82 glfwGetCursorPos(
glfwWindow, &mouseX, &mouseY);
91 logger->info(
"GLFWQtWindowImpl {} is being destroyed",
99 logger->info(
"GLFWQtWindowImpl {} has been destroyed",
116 logger->info(
"shouldClose() returned true, exiting gracefully");
142 std::cout <<
"Initializing GLFW" << std::endl;
144 if (glfwInit() != 0) {
145 glfwSetErrorCallback([](
int error,
const char* description) {
146 std::cerr <<
"GLFW Error " << error <<
": " << description << std::endl;
149 std::cout <<
"Initialized GLFW" << std::endl;
153 throw std::runtime_error(
"Failed to initialize GLFW");
170 glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
171 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
172 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
173 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
174 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
175 glfwWindowHint(GLFW_STENCIL_BITS, 0);
176 glfwWindowHint(GLFW_DEPTH_BITS, 0);
178 glfwWindow = glfwCreateWindow(width, height, title,
nullptr,
nullptr);
181 "Creating window with title: {} and initial size: {}x{}", title, width, height);
185 throw std::runtime_error(
"Failed to create GLFW window");
192 [](GLFWwindow*
glfwWindow,
int winWidth,
int winHeight) {
199 [[maybe_unused]]
int scancode,
201 [[maybe_unused]]
int mods) {
202 if (action == GLFW_PRESS) {
203 if (key >= GLFW_KEY_0 && key <= GLFW_KEY_9) {
207 int number = key - GLFW_KEY_0;
209 }
else if (key == GLFW_KEY_ESCAPE) {
218 glfwSetMouseButtonCallback(
220 [](GLFWwindow*
glfwWindow,
int button,
int action, [[maybe_unused]]
int mods) {
221 if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
226 }
else if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) {
231 }
else if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS) {
249 glfwGetFramebufferSize(
glfwWindow, &fbWidth, &fbHeight);
263 auto* self =
static_cast<GLFWQtWindowImpl*
>(glfwGetWindowUserPointer(window));
265 if (self && self->renderer) {
270 glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
272 self->winSize = {.width = winWidth, .height = winHeight};
273 self->framebufferSize = {.width = fbWidth, .height = fbHeight};
275 float xScale =
static_cast<float>(fbWidth) /
static_cast<float>(winWidth);
276 float yScale =
static_cast<float>(fbHeight) /
static_cast<float>(winHeight);
279 "Informing renderer {} of window size change to {}x{}, framebuffer size to "
281 "and scales to {:.2f}x{:.2f}",
290 self->renderer->handleWindowResized(self, xScale, yScale);
302 void showWarning(
const std::string& title,
const std::string& message)
override {
310 const std::string& title,
311 const std::string& message,
312 const std::optional<FloatingPoint>& defaultValue)
override {
314 title, message, defaultValue,
this);
Class that provides a logger for the given class; automatically deduces the logger.
Class responsible for managing the GLFW main window, any Qt dialogs / modals and their lifecycle.
static GLFWQtWindowImpl< RendererImpl, Canvas > MakeFullscreen(const char *title)
Constructs a new GLFWQtWindowImpl that takes the full size of the primary monitor.
GLFWQtWindowImpl & operator=(const GLFWQtWindowImpl &)=delete
void run() override
Runs the main window loop.
GLFWQtWindowImpl & operator=(GLFWQtWindowImpl &&)=delete
void showWarning(const std::string &title, const std::string &message) override
Show a warning message.
std::optional< FloatingPoint > promptFloatingPointInput(const std::string &title, const std::string &message, const std::optional< FloatingPoint > &defaultValue) override
Prompt for a floating point input.
static void initGLFW()
Initializes GLFW.
std::unique_ptr< RendererImpl > renderer
bool shouldClose() const override
Whether the window should close.
static bool initializedGLFW
bool promptConfirmation(const std::string &title, const std::string &message) override
Prompt for user confirmation.
GLFWQtWindowImpl(GLFWQtWindowImpl &&)=delete
void initializeGLFWWindow(int width, int height, const char *title)
Initializes the GLFW window.
GLFWQtWindowImpl(const GLFWQtWindowImpl &)=delete
void focusWindow() override
Focus the window.
static void handleWindowResized(GLFWwindow *window, int winWidth, int winHeight)
Handles the window resized event.
GLFWQtWindowImpl(int width, int height, const char *title)
Constructs a new GLFWQtWindowImpl.
~GLFWQtWindowImpl() override
Destructor that cleans up the GLFW window and terminates GLFW.
The abstract base class for implementing a window.
void handleNumericKeyPress(int number)
Handles the numeric key press event; should be called internally by the window implementation.
void handleRightClick()
Handles the right click event; should be called internally by the window implementation.
std::shared_ptr< spdlog::logger > logger
void handleMouseUp()
Handles the mouse up event; should be called internally by the window implementation.
std::shared_ptr< business_logic::BlocksManager > blocksManager
void handleMouseDown()
Handles the mouse down event; should be called internally by the window implementation.
void handleMouseMove(int x, int y)
Handles the mouse move event; should be called internally by the window implementation.
void handleEscapeKeyPress()
Handles the ESC key press event; should be called internally by the window implementation.
static bool promptConfirmation(const std::string &title, const std::string &message, business_logic::delegate::IWindowDelegate *windowDelegate)
static void showWarning(const std::string &title, const std::string &message, business_logic::delegate::IWindowDelegate *windowDelegate)
static std::optional< FloatingPoint > promptForFloatingPointInput(const std::string &title, const std::string &prompt, const std::optional< FloatingPoint > &defaultValue, business_logic::delegate::IWindowDelegate *windowDelegate)
The business logic module.
std::string stringifyAddressOf(const T *value)
Convert a pointer to a string in format "0x..." containing its hexadecimal address.
The GUI window abstraction & implementation.