Skip to content

Commit

Permalink
GUI: More refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
pierre-dejoue committed Aug 26, 2023
1 parent b5129b7 commit 91366f7
Show file tree
Hide file tree
Showing 13 changed files with 429 additions and 127 deletions.
3 changes: 3 additions & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ include(pfd)
set(GUI_SOURCES
src/draw_grid.cpp
src/err_window.cpp
src/glfw_context.cpp
src/imgui_helpers.cpp
src/goal_window.cpp
src/grid_info.cpp
src/grid_window.cpp
src/main.cpp
src/picross_file.cpp
src/settings.cpp
src/settings_window.cpp
src/style.cpp
)

file(GLOB GUI_HEADERS src/*.h)
Expand Down
4 changes: 3 additions & 1 deletion src/gui/src/err_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ void ErrWindow::visit(bool& can_be_erased)
{
ImGui::SetNextWindowSizeConstraints(ImVec2(0, 300), ImVec2(FLT_MAX, 600));

constexpr ImGuiWindowFlags win_flags = ImGuiWindowFlags_AlwaysAutoResize;
constexpr ImGuiWindowFlags win_flags = ImGuiWindowFlags_AlwaysAutoResize
| ImGuiWindowFlags_NoSavedSettings;

bool is_window_open = true;
if (!ImGui::Begin(pImpl->title.c_str(), &is_window_open, win_flags))
{
Expand Down
78 changes: 78 additions & 0 deletions src/gui/src/glfw_context.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "glfw_context.h"


#include <GLFW/glfw3.h>


namespace
{

// Target OpenGL 3.3 for this project
constexpr int TARGET_OPENGL_MAJOR = 3;
constexpr int TARGET_OPENGL_MINOR = 0;
constexpr bool TARGET_OPENGL_CORE_PROFILE = false; // 3.2+ only
constexpr bool TARGET_OPENGL_FORWARD_COMPATIBILITY = true; // 3.0 only, recommended for MacOS
constexpr const char* TARGET_GLSL_VERSION_STR = "#version 130";

// GLFW error handling function
stdutils::io::ErrorHandler s_glfw_err_handler;
void glfw_error_callback(int error, const char* description)
{
if(!s_glfw_err_handler) { return; }
std::stringstream out;
out << "GLFW Error " << error << ": " << description;
s_glfw_err_handler(stdutils::io::Severity::ERR, out.str());
}

} // Anonymous namespace

GLFWWindowContext::GLFWWindowContext(int width, int height, const std::string_view& title, const stdutils::io::ErrorHandler* err_handler)
: m_window_ptr(nullptr)
, m_glfw_init(false)
{
static bool call_once = false;
if (call_once)
return;
call_once = true;

if (err_handler)
{
s_glfw_err_handler = *err_handler;
glfwSetErrorCallback(glfw_error_callback);
}
if (!glfwInit())
{
if (err_handler) { (*err_handler)(stdutils::io::Severity::FATAL, "GLFW failed to initialize"); }
return;
}
m_glfw_init = true;

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, TARGET_OPENGL_MAJOR);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, TARGET_OPENGL_MINOR);
if constexpr (TARGET_OPENGL_CORE_PROFILE)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
if constexpr (TARGET_OPENGL_FORWARD_COMPATIBILITY)
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
m_window_ptr = glfwCreateWindow(width, height, title.data(), nullptr, nullptr);
if (m_window_ptr == nullptr)
{
if (err_handler) { (*err_handler)(stdutils::io::Severity::FATAL, "GLFW failed to create the window"); }
return;
}
glfwMakeContextCurrent(m_window_ptr);
glfwSwapInterval(1);
}

GLFWWindowContext::~GLFWWindowContext()
{
if(m_window_ptr)
glfwDestroyWindow(m_window_ptr);
m_window_ptr = nullptr;
if (m_glfw_init)
glfwTerminate();
}

const char* glsl_version()
{
return TARGET_GLSL_VERSION_STR;
}
20 changes: 20 additions & 0 deletions src/gui/src/glfw_context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include <stdutils/io.h>
#include <string_view>

// Wrapper class for GLFW initialization and window
struct GLFWwindow;
class GLFWWindowContext
{
public:
GLFWWindowContext(int width, int height, const std::string_view& title, const stdutils::io::ErrorHandler* err_handler = nullptr);
~GLFWWindowContext();
GLFWwindow* window() { return m_window_ptr; }

private:
GLFWwindow* m_window_ptr;
bool m_glfw_init;
};

const char* glsl_version();
4 changes: 3 additions & 1 deletion src/gui/src/goal_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ void GoalWindow::visit(bool& can_be_erased, Settings& settings)
const float min_win_height = 80.f + static_cast<float>(height * tile_size);
ImGui::SetNextWindowSizeConstraints(ImVec2(min_win_width, min_win_height), ImVec2(FLT_MAX, FLT_MAX));

constexpr ImGuiWindowFlags win_flags = ImGuiWindowFlags_AlwaysAutoResize;
constexpr ImGuiWindowFlags win_flags = ImGuiWindowFlags_AlwaysAutoResize
| ImGuiWindowFlags_NoSavedSettings;

bool is_window_open = true;
if (!ImGui::Begin(title.c_str(), &is_window_open, win_flags))
{
Expand Down
4 changes: 3 additions & 1 deletion src/gui/src/grid_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ void GridWindow::visit(bool& can_be_erased, Settings& settings)
const float min_win_height = 100.f + static_cast<float>(height * tile_size);
ImGui::SetNextWindowSizeConstraints(ImVec2(min_win_width, min_win_height), ImVec2(FLT_MAX, FLT_MAX));

constexpr ImGuiWindowFlags win_flags = ImGuiWindowFlags_AlwaysAutoResize;
constexpr ImGuiWindowFlags win_flags = ImGuiWindowFlags_AlwaysAutoResize
| ImGuiWindowFlags_NoSavedSettings;

bool is_window_open = true;
if (!ImGui::Begin(title.c_str(), &is_window_open, win_flags))
{
Expand Down
86 changes: 86 additions & 0 deletions src/gui/src/imgui_helpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include "imgui_helpers.h"

#include <imgui_wrap.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <GLFW/glfw3.h>
#include "glfw_context.h"


namespace ImGui
{

void HelpMarker(const char* desc)
{
ImGui::TextDisabled("(?)");
if (ImGui::BeginItemTooltip())
{
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(desc);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
}

// Place the window in the working area, that is the position of the viewport minus task bars, menus bars, status bars, etc.
void SetNextWindowPosAndSize(const WindowLayout& window_layout, ImGuiCond cond)
{
const auto work_tl_corner = ImGui::GetMainViewport()->WorkPos;
const auto work_size = ImGui::GetMainViewport()->WorkSize;
const ImVec2 tl_corner(window_layout.m_position.x + work_tl_corner.x, window_layout.m_position.y + work_tl_corner.y);
ImGui::SetNextWindowPos(tl_corner, cond);
ImGui::SetNextWindowSize(to_imgui_vec2(window_layout.window_size(to_screen_size(work_size))), cond);
}

} // namespace ImGui

DearImGuiContext::DearImGuiContext(GLFWwindow* glfw_window, bool& any_fatal_error) noexcept
{
any_fatal_error = false;
try
{
const bool versions_ok = IMGUI_CHECKVERSION();
const auto* ctx = ImGui::CreateContext();

// Setup Platform/Renderer backends
const bool init_glfw = ImGui_ImplGlfw_InitForOpenGL(glfw_window, true);
const bool init_opengl3 = ImGui_ImplOpenGL3_Init(glsl_version());

any_fatal_error = !versions_ok || (ctx == nullptr) || !init_glfw || !init_opengl3;
}
catch(const std::exception&)
{
any_fatal_error = true;
}
}

DearImGuiContext::~DearImGuiContext()
{
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}

void DearImGuiContext::new_frame() const
{
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
}

void DearImGuiContext::render() const
{
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}

void DearImGuiContext::backend_info(std::ostream& out) const
{
const ImGuiIO& io = ImGui::GetIO();
out << "Dear ImGui " << IMGUI_VERSION
<< " (Backend platform: " << (io.BackendPlatformName ? io.BackendPlatformName : "NULL")
<< ", renderer: " << (io.BackendRendererName ? io.BackendRendererName : "NULL") << ")" << std::endl;
out << "GLFW " << GLFW_VERSION_MAJOR << "." << GLFW_VERSION_MINOR << "." << GLFW_VERSION_REVISION << std::endl;
out << "OpenGL Version " << glGetString(GL_VERSION) << std::endl;
out << "OpenGL Renderer " << glGetString(GL_RENDERER) << std::endl;
}
46 changes: 46 additions & 0 deletions src/gui/src/imgui_helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once

#include "screen.h"
#include "window_layout.h"

#include <imgui_wrap.h>

#include <ostream>

inline ScreenPos to_screen_pos(ImVec2 vec2)
{
return ScreenPos(vec2.x, vec2.y);
}

inline ScreenSize to_screen_size(ImVec2 vec2)
{
return ScreenSize(vec2.x, vec2.y);
}

inline ImVec2 to_imgui_vec2(ScreenPos pos)
{
return ImVec2(pos.x, pos.y);
}

namespace ImGui
{
void HelpMarker(const char* desc); // Function taken from imgui_demo.cpp
void SetNextWindowPosAndSize(const WindowLayout& window_layout, ImGuiCond cond = 0);
}

// Do not call this class ImGuiContext because this is an internal class of Dear ImGui
struct GLFWwindow;
class DearImGuiContext
{
public:
explicit DearImGuiContext(GLFWwindow* glfw_window, bool& any_fatal_error) noexcept;
~DearImGuiContext();
DearImGuiContext(const DearImGuiContext&) = delete;
DearImGuiContext(DearImGuiContext&&) = delete;
DearImGuiContext& operator=(const DearImGuiContext&) = delete;
DearImGuiContext& operator=(DearImGuiContext&&) = delete;

void new_frame() const;
void render() const;
void backend_info(std::ostream& out) const;
};
Loading

0 comments on commit 91366f7

Please sign in to comment.