Skip to content

Commit 8f5d171

Browse files
committed
Window improvements.
Added handling for content scaling changes to update UI. Refactored Window constructed in windowed mode to begin in the middle of the screen at half its size. Fixed bad state sync for size and position via set_size and set_position by adding on_x_callback.
1 parent 380f8a3 commit 8f5d171

File tree

4 files changed

+72
-31
lines changed

4 files changed

+72
-31
lines changed

source/Application.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ int main(int argc, char* argv[])
194194
Platform::Core::initialise_directories();
195195
Platform::Core::initialise_GLFW();
196196
Platform::Input input = Platform::Input();
197-
Platform::Window window = Platform::Window(1920, 1080, input);
197+
Platform::Window window = Platform::Window(glm::vec2{0.5f, 0.5f}, input);
198198
Platform::Core::initialise_OpenGL();
199199
OpenGL::DebugRenderer::init();
200200
Platform::Core::initialise_ImGui(window);

source/Platform/Core.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,14 @@ namespace Platform
111111
{
112112
IMGUI_CHECKVERSION();
113113
ImGui::CreateContext();
114-
ImGuiIO& io = ImGui::GetIO();
115-
(void)io;
116-
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable docking
117114
ImGui_ImplGlfw_InitForOpenGL(p_window.m_handle, true);
118115
ImGui_ImplOpenGL3_Init(Config::GLSL_Version_String);
119-
glm::uvec2 size = p_window.size();
120-
io.DisplaySize = ImVec2(static_cast<float>(size.x), static_cast<float>(size.y));
116+
117+
ImGuiIO& io = ImGui::GetIO();
118+
io.FontGlobalScale = p_window.get_content_scale();
119+
glm::uvec2 size = p_window.size();
120+
io.DisplaySize = ImVec2(static_cast<float>(size.x), static_cast<float>(size.y));
121+
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
121122

122123
LOG("[INIT] Initialised ImGui");
123124
}

source/Platform/Window.cpp

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121

2222
namespace Platform
2323
{
24-
Window::Window(const int& p_width, const int& p_height, Input& p_input_state) noexcept
24+
Window::Window(const glm::vec2& p_screen_factor, Input& p_input_state) noexcept
2525
: m_size_fullscreen{get_max_resolution()}
26-
, m_position_fullscreen{0, 0}
27-
, m_size_windowed{p_width, p_height}
28-
, m_position_windowed{0, get_window_title_bar_height()} // Offset starting position by height of title bar.
26+
, m_position_fullscreen{0, 0} // init in body
27+
, m_size_windowed{0, 0} // init in body
28+
, m_position_windowed{0, 0} // init in body
2929
, m_fullscreen{false}
30-
, m_aspect_ratio{m_fullscreen ? static_cast<float>(m_size_fullscreen.x) / static_cast<float>(m_size_fullscreen.y) : static_cast<float>(m_size_windowed.x) / static_cast<float>(m_size_windowed.y)}
30+
, m_aspect_ratio{0.f}
3131
, m_VSync{true}
3232
, m_close_requested{false}
3333
, m_handle{nullptr}
@@ -36,23 +36,37 @@ namespace Platform
3636
{
3737
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
3838
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
39-
const auto window_size = size();
40-
const auto window_position = position();
41-
m_handle = glfwCreateWindow(window_size.x, window_size.y, Config::Is_Debug ? "Spirit - Debug" : "Spirit", m_fullscreen ? glfwGetPrimaryMonitor() : NULL, NULL);
39+
auto monitor = glfwGetPrimaryMonitor();
40+
41+
int wa_xpos, wa_ypos, wa_width, wa_height;
42+
glfwGetMonitorWorkarea(monitor, &wa_xpos, &wa_ypos, &wa_width, &wa_height);
43+
m_size_windowed = {(unsigned int)(wa_width * p_screen_factor.x), (unsigned int)(wa_height * p_screen_factor.y)};
44+
m_position_windowed = {wa_xpos + (wa_width - m_size_windowed.x) / 2, wa_ypos + (wa_height - m_size_windowed.y) / 2};
45+
46+
if (m_fullscreen)
47+
m_handle = glfwCreateWindow(m_size_fullscreen.x, m_size_fullscreen.y, Config::Is_Debug ? "Spirit - Debug" : "Spirit", m_fullscreen ? monitor : NULL, NULL);
48+
else
49+
{
50+
m_handle = glfwCreateWindow(m_size_windowed.x, m_size_windowed.y, Config::Is_Debug ? "Spirit - Debug" : "Spirit", NULL, NULL);
51+
glfwSetWindowPos(m_handle, m_position_windowed.x, m_position_windowed.y);
52+
}
53+
54+
auto set_size = size();
55+
m_aspect_ratio = static_cast<float>(set_size.x) / static_cast<float>(set_size.y);
56+
4257
ASSERT(m_handle != nullptr, "[WINDOW] Failed to construct Window");
4358

4459
glfwMakeContextCurrent(m_handle); // Set this window as the context for GL render calls.
45-
glfwSetWindowPos(m_handle, window_position.x, window_position.y);
46-
glfwSetWindowSize(m_handle, window_size.x, window_size.y); // glfwCreateWindow size requests are not hard constraints. Have to ensure size was set by calling glfwSetWindowSize.
4760
set_VSync(m_VSync);
4861

4962
{ // Set the GLFW callbacks.
5063
// GLFW is a C library requiring static || global functions for callbacks.
5164
// We use the glfwSetWindowUserPointer and glfwGetWindowUserPointer to retrieve this instance of Window from the library and call the member functions.
5265
glfwSetWindowUserPointer(m_handle, this);
53-
glfwSetWindowCloseCallback(m_handle, [](GLFWwindow* p_handle){((Window*)glfwGetWindowUserPointer(p_handle))->request_close();});
54-
glfwSetWindowSizeCallback(m_handle, [](GLFWwindow* p_handle, int p_size_x, int p_size_y){((Window*)glfwGetWindowUserPointer(p_handle))->set_size({p_size_x, p_size_y});});
55-
glfwSetWindowPosCallback(m_handle, [](GLFWwindow* p_handle, int p_pos_x, int p_pos_y){((Window*)glfwGetWindowUserPointer(p_handle))->set_position({p_pos_x, p_pos_y});});
66+
glfwSetWindowCloseCallback(m_handle, [](GLFWwindow* p_handle){((Window*)glfwGetWindowUserPointer(p_handle))->request_close();});
67+
glfwSetWindowSizeCallback(m_handle, [](GLFWwindow* p_handle, int p_size_x, int p_size_y){((Window*)glfwGetWindowUserPointer(p_handle))->on_size_callback({p_size_x, p_size_y});});
68+
glfwSetWindowPosCallback(m_handle, [](GLFWwindow* p_handle, int p_pos_x, int p_pos_y){((Window*)glfwGetWindowUserPointer(p_handle))->on_position_callback({p_pos_x, p_pos_y});});
69+
glfwSetWindowContentScaleCallback(m_handle, [](GLFWwindow* p_handle, float p_scale_x, float p_scale_y){((Window*)glfwGetWindowUserPointer(p_handle))->on_content_scale_callback((p_scale_x + p_scale_y) * 0.5f);});
5670

5771
{ // INPUT CALLBACKS - Because we only have access to the WindowUserPointer via GLFW, we have to access the Input and set it from the window.
5872
glfwSetKeyCallback(m_handle, [](GLFWwindow* p_handle, int p_key, int p_scancode, int p_action, int p_mode){((Window*)glfwGetWindowUserPointer(p_handle))->m_input.glfw_key_press(p_key, p_scancode, p_action, p_mode);});
@@ -76,6 +90,8 @@ namespace Platform
7690
icon.height = icon_image.height;
7791
glfwSetWindowIcon(m_handle, 1, &icon);
7892
}
93+
94+
ASSERT(m_aspect_ratio != 0.f, "[WINDOW] Aspect ratio badly initialised");
7995
LOG("[WINDOW] Created Window with resolution {}x{}", size().x, size().y);
8096
}
8197
Window::~Window() noexcept
@@ -85,13 +101,12 @@ namespace Platform
85101
LOG("[WINDOW] Closed window");
86102
}
87103

88-
void Window::set_size(glm::uvec2 p_new_size)
104+
void Window::on_size_callback(const glm::uvec2& p_new_size)
89105
{
90106
if (p_new_size.x == 0 || p_new_size.y == 0) // When the window is minimised the size can be 0. Ignore and keep original size data.
91107
return;
92108

93109
ImGuiIO& io = ImGui::GetIO();
94-
io.FontGlobalScale = std::round(ImGui::GetMainViewport()->DpiScale);
95110

96111
if (m_fullscreen)
97112
{
@@ -106,19 +121,27 @@ namespace Platform
106121
io.DisplaySize = ImVec2(static_cast<float>(m_size_windowed.x), static_cast<float>(m_size_windowed.y));
107122
}
108123

109-
//mWindowResizeEvent.dispatch(new_size.x, new_size.y);
110-
111124
LOG("[WINDOW] Resized to {}x{} aspect: {}", size().x, size().y, aspect_ratio());
112125
}
113-
void Window::set_position(glm::uvec2 p_new_position)
126+
void Window::set_size(const glm::uvec2& p_new_size)
127+
{
128+
glfwSetWindowSize(m_handle, p_new_size.x, p_new_size.y);
129+
on_size_callback(p_new_size);
130+
}
131+
void Window::on_position_callback(const glm::uvec2& new_position)
114132
{
115133
if (m_fullscreen)
116-
m_position_fullscreen = p_new_position;
134+
m_position_fullscreen = new_position;
117135
else
118-
m_position_windowed = p_new_position;
136+
m_position_windowed = new_position;
119137

120138
LOG("[WINDOW] Moved to {}, {}", position().x, position().y, aspect_ratio());
121139
}
140+
void Window::set_position(const glm::uvec2& p_new_position)
141+
{
142+
glfwSetWindowPos(m_handle, p_new_position.x, p_new_position.y);
143+
on_position_callback(p_new_position);
144+
}
122145

123146
void Window::request_close()
124147
{
@@ -142,8 +165,8 @@ namespace Platform
142165
{
143166
const auto max_res = get_max_resolution();
144167
glfwSetWindowMonitor(m_handle, glfwGetPrimaryMonitor(), 0, 0, max_res.x, max_res.y, GLFW_DONT_CARE);
145-
set_position({0, 0});
146-
set_size(max_res);
168+
on_position_callback({0, 0});
169+
on_size_callback(max_res);
147170
LOG("[WINDOW] Set to fullscreen. Position: {},{} Resolution: {}x{} Aspect ratio: {}", 0, 0, m_size_fullscreen.x, m_size_fullscreen.y, m_aspect_ratio);
148171
}
149172
else // Windowed mode. Reuse the old size and position
@@ -217,6 +240,18 @@ namespace Platform
217240
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
218241
}
219242

243+
void Window::on_content_scale_callback(float new_scale)
244+
{
245+
ImGuiIO& io = ImGui::GetIO();
246+
io.FontGlobalScale = new_scale;
247+
}
248+
float Window::get_content_scale() const
249+
{
250+
float xscale, yscale;
251+
glfwGetWindowContentScale(m_handle, &xscale, &yscale);
252+
return (xscale + yscale) * 0.5f;
253+
}
254+
220255
int Window::get_window_title_bar_height()
221256
{
222257
#ifdef _WIN32

source/Platform/Window.hpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,19 @@ namespace Platform
2727
// Creates a OS window of p_width and p_height.
2828
// Takes an Input and sets its GLFW callback functions. Input depends on a Window.
2929
// Window construction requires GLFW and ImGui to be initialised before.
30-
Window(const int& p_width, const int& p_height, Input& p_input_state) noexcept;
30+
Window(const glm::vec2& p_screen_factor, Input& p_input_state) noexcept;
3131
~Window() noexcept;
3232

3333
void set_VSync(bool p_enabled);
3434
bool get_VSync() const { return m_VSync; };
3535

3636
glm::uvec2 size() const { return m_fullscreen ? m_size_fullscreen : m_size_windowed; };
37-
void set_size(glm::uvec2 p_new_size);
37+
void on_size_callback(const glm::uvec2& p_new_size);
38+
void set_size(const glm::uvec2& p_new_size);
3839

3940
glm::uvec2 position() const { return m_fullscreen ? m_position_fullscreen : m_position_windowed; };
40-
void set_position(glm::uvec2 p_new_position);
41+
void on_position_callback(const glm::uvec2& p_new_position);
42+
void set_position(const glm::uvec2& p_new_position);
4143

4244
void toggle_fullscreen();
4345
void swap_buffers();
@@ -47,6 +49,9 @@ namespace Platform
4749
bool close_requested() const { return m_close_requested; };
4850
float aspect_ratio() const { return m_aspect_ratio; };
4951

52+
void on_content_scale_callback(float new_scale);
53+
float get_content_scale() const;
54+
5055
// Returns the hight of the window title bar in pixels.
5156
static int get_window_title_bar_height();
5257
// Get the max resolution of the primary monitor.

0 commit comments

Comments
 (0)