mirror of
https://github.com/obsqrbtz/clrsync.git
synced 2026-04-08 20:19:04 +03:00
wip: moving backend-related stuff out of the app logic
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
namespace clrsync::core
|
namespace clrsync::core
|
||||||
{
|
{
|
||||||
|
|
||||||
const std::string GIT_SEMVER = "0.1.6+git.g7641846";
|
const std::string GIT_SEMVER = "0.1.6+git.g292a748";
|
||||||
|
|
||||||
const std::string version_string();
|
const std::string version_string();
|
||||||
} // namespace clrsync::core
|
} // namespace clrsync::core
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ set(GUI_SOURCES
|
|||||||
platform/linux/font_loader_linux.cpp
|
platform/linux/font_loader_linux.cpp
|
||||||
platform/macos/font_loader_macos.cpp
|
platform/macos/font_loader_macos.cpp
|
||||||
platform/windows/font_loader_windows.cpp
|
platform/windows/font_loader_windows.cpp
|
||||||
|
backend/glfw_opengl.cpp
|
||||||
|
ui_manager.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|||||||
38
src/gui/backend/backend.hpp
Normal file
38
src/gui/backend/backend.hpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef CLRSYNC_BACKEND_HPP
|
||||||
|
#define CLRSYNC_BACKEND_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace clrsync::gui::backend{
|
||||||
|
|
||||||
|
struct window_config{
|
||||||
|
std::string title = "clrsync";
|
||||||
|
int width = 1280;
|
||||||
|
int height = 720;
|
||||||
|
bool resizable = true;
|
||||||
|
bool decorated = true;
|
||||||
|
bool transparent_framebuffer = true;
|
||||||
|
float clear_color[4] = {0.1f, 0.1f, 0.1f, 0.0f};
|
||||||
|
};
|
||||||
|
class backend_interface{
|
||||||
|
public:
|
||||||
|
virtual ~backend_interface() = default;
|
||||||
|
|
||||||
|
virtual bool initialize(const window_config& config) = 0;
|
||||||
|
virtual void shutdown() = 0;
|
||||||
|
virtual bool should_close() const = 0;
|
||||||
|
virtual void begin_frame() = 0;
|
||||||
|
virtual void end_frame() = 0;
|
||||||
|
|
||||||
|
virtual void* get_native_window() const = 0;
|
||||||
|
virtual void* get_graphics_context() const = 0;
|
||||||
|
|
||||||
|
virtual bool init_imgui_backend() = 0;
|
||||||
|
virtual void shutdown_imgui_backend() = 0;
|
||||||
|
virtual void imgui_new_frame() = 0;
|
||||||
|
virtual void imgui_render_draw_data(void* draw_data) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CLRSYNC_BACKEND_HPP
|
||||||
141
src/gui/backend/glfw_opengl.cpp
Normal file
141
src/gui/backend/glfw_opengl.cpp
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
#include "gui/backend/glfw_opengl.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <imgui_impl_glfw.h>
|
||||||
|
#include <imgui_impl_opengl3.h>
|
||||||
|
|
||||||
|
namespace clrsync::gui::backend
|
||||||
|
{
|
||||||
|
|
||||||
|
glfw_opengl_backend::glfw_opengl_backend() = default;
|
||||||
|
|
||||||
|
glfw_opengl_backend::~glfw_opengl_backend()
|
||||||
|
{
|
||||||
|
glfw_opengl_backend::shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool glfw_opengl_backend::initialize(const window_config &config)
|
||||||
|
{
|
||||||
|
glfwSetErrorCallback([](int error, const char* description) {
|
||||||
|
std::cerr << "GLFW Error " << error << ": " << description << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!glfwInit())
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to initialize GLFW" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
|
||||||
|
#else
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||||
|
#endif
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, config.resizable ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
glfwWindowHint(GLFW_DECORATED, config.decorated ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, config.transparent_framebuffer ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
|
||||||
|
m_window = glfwCreateWindow(config.width, config.height, config.title.c_str(), nullptr, nullptr);
|
||||||
|
if (!m_window)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to create GLFW window" << std::endl;
|
||||||
|
glfwTerminate();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(m_window);
|
||||||
|
glfwSwapInterval(1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glfw_opengl_backend::shutdown()
|
||||||
|
{
|
||||||
|
if (m_window)
|
||||||
|
{
|
||||||
|
glfwDestroyWindow(m_window);
|
||||||
|
m_window = nullptr;
|
||||||
|
}
|
||||||
|
glfwTerminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool glfw_opengl_backend::should_close() const
|
||||||
|
{
|
||||||
|
return m_window && glfwWindowShouldClose(m_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glfw_opengl_backend::begin_frame()
|
||||||
|
{
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
|
if (m_window)
|
||||||
|
{
|
||||||
|
int display_w, display_h;
|
||||||
|
glfwGetFramebufferSize(m_window, &display_w, &display_h);
|
||||||
|
glViewport(0, 0, display_w, display_h);
|
||||||
|
glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void glfw_opengl_backend::end_frame()
|
||||||
|
{
|
||||||
|
if (m_window)
|
||||||
|
{
|
||||||
|
glfwSwapBuffers(m_window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *glfw_opengl_backend::get_native_window() const
|
||||||
|
{
|
||||||
|
return static_cast<void *>(m_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *glfw_opengl_backend::get_graphics_context() const
|
||||||
|
{
|
||||||
|
return static_cast<void *>(m_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool glfw_opengl_backend::init_imgui_backend()
|
||||||
|
{
|
||||||
|
if (!m_window)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!ImGui_ImplGlfw_InitForOpenGL(m_window, true))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
const char* glsl_version = "#version 150";
|
||||||
|
#else
|
||||||
|
const char* glsl_version = "#version 120";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!ImGui_ImplOpenGL3_Init(glsl_version))
|
||||||
|
{
|
||||||
|
ImGui_ImplGlfw_Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glfw_opengl_backend::shutdown_imgui_backend()
|
||||||
|
{
|
||||||
|
ImGui_ImplOpenGL3_Shutdown();
|
||||||
|
ImGui_ImplGlfw_Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void glfw_opengl_backend::imgui_new_frame()
|
||||||
|
{
|
||||||
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
|
ImGui_ImplGlfw_NewFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void glfw_opengl_backend::imgui_render_draw_data(void* draw_data)
|
||||||
|
{
|
||||||
|
ImGui_ImplOpenGL3_RenderDrawData(static_cast<ImDrawData*>(draw_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace clrsync::gui::backend
|
||||||
36
src/gui/backend/glfw_opengl.hpp
Normal file
36
src/gui/backend/glfw_opengl.hpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef CLRSYNC_GLFW_OPENGL_HPP
|
||||||
|
#define CLRSYNC_GLFW_OPENGL_HPP
|
||||||
|
|
||||||
|
#define GL_SILENCE_DEPRECATION
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include "gui/backend/backend.hpp"
|
||||||
|
|
||||||
|
namespace clrsync::gui::backend{
|
||||||
|
|
||||||
|
class glfw_opengl_backend : public backend_interface{
|
||||||
|
public:
|
||||||
|
glfw_opengl_backend();
|
||||||
|
~glfw_opengl_backend();
|
||||||
|
|
||||||
|
bool initialize(const window_config& config) override;
|
||||||
|
void shutdown() override;
|
||||||
|
bool should_close() const override;
|
||||||
|
void begin_frame() override;
|
||||||
|
void end_frame() override;
|
||||||
|
|
||||||
|
void* get_native_window() const override;
|
||||||
|
void* get_graphics_context() const override;
|
||||||
|
|
||||||
|
bool init_imgui_backend() override;
|
||||||
|
void shutdown_imgui_backend() override;
|
||||||
|
void imgui_new_frame() override;
|
||||||
|
void imgui_render_draw_data(void* draw_data) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLFWwindow* m_window = nullptr;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CLRSYNC_GLFW_OPENGL_HPP
|
||||||
@@ -9,8 +9,10 @@
|
|||||||
#include "core/config/config.hpp"
|
#include "core/config/config.hpp"
|
||||||
#include "core/io/toml_file.hpp"
|
#include "core/io/toml_file.hpp"
|
||||||
|
|
||||||
|
#include "gui/backend/glfw_opengl.hpp"
|
||||||
#include "gui/helpers/imgui_helpers.hpp"
|
#include "gui/helpers/imgui_helpers.hpp"
|
||||||
#include "gui/platform/font_loader.hpp"
|
#include "gui/platform/font_loader.hpp"
|
||||||
|
#include "gui/ui_manager.hpp"
|
||||||
#include "gui/views/about_window.hpp"
|
#include "gui/views/about_window.hpp"
|
||||||
#include "gui/views/color_scheme_editor.hpp"
|
#include "gui/views/color_scheme_editor.hpp"
|
||||||
#include "gui/views/settings_window.hpp"
|
#include "gui/views/settings_window.hpp"
|
||||||
@@ -35,32 +37,42 @@ int main(int, char **)
|
|||||||
static std::string ini_path = (base.parent_path() / "layout.ini").string();
|
static std::string ini_path = (base.parent_path() / "layout.ini").string();
|
||||||
bool first_time = !std::filesystem::exists(ini_path);
|
bool first_time = !std::filesystem::exists(ini_path);
|
||||||
|
|
||||||
GLFWwindow *window = init_glfw();
|
printf("GLFW Version: %s\n", glfwGetVersionString());
|
||||||
if (!window)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
printf("GLFV Version: %s\n", glfwGetVersionString());
|
auto backend = clrsync::gui::backend::glfw_opengl_backend();
|
||||||
|
auto window_config = clrsync::gui::backend::window_config();
|
||||||
|
window_config.title = "clrsync";
|
||||||
|
window_config.width = 1280;
|
||||||
|
window_config.height = 720;
|
||||||
|
window_config.transparent_framebuffer = true;
|
||||||
|
|
||||||
std::cout << "GLFW runtime platform: ";
|
if (!backend.initialize(window_config))
|
||||||
switch (glfwGetPlatform())
|
|
||||||
{
|
{
|
||||||
case GLFW_PLATFORM_WAYLAND:
|
std::cerr << "Failed to initialize backend." << std::endl;
|
||||||
std::cout << "Wayland\n";
|
return 1;
|
||||||
break;
|
|
||||||
case GLFW_PLATFORM_X11:
|
|
||||||
std::cout << "X11\n";
|
|
||||||
break;
|
|
||||||
case GLFW_PLATFORM_COCOA:
|
|
||||||
std::cout << "Cocoa\n";
|
|
||||||
break;
|
|
||||||
case GLFW_PLATFORM_WIN32:
|
|
||||||
std::cout << "Win32\n";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
std::cout << "Unknown\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init_imgui(window, ini_path);
|
std::cout << "GLFW runtime platform: ";
|
||||||
|
switch (glfwGetPlatform()) {
|
||||||
|
case GLFW_PLATFORM_WAYLAND: std::cout << "Wayland\n"; break;
|
||||||
|
case GLFW_PLATFORM_X11: std::cout << "X11\n"; break;
|
||||||
|
case GLFW_PLATFORM_COCOA: std::cout << "Cocoa\n"; break;
|
||||||
|
case GLFW_PLATFORM_WIN32: std::cout << "Win32\n"; break;
|
||||||
|
default: std::cout << "Unknown\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
clrsync::gui::ui_manager ui_manager(&backend);
|
||||||
|
|
||||||
|
clrsync::gui::ui_config ui_cfg;
|
||||||
|
ui_cfg.ini_path = ini_path;
|
||||||
|
ui_cfg.enable_docking = true;
|
||||||
|
ui_cfg.enable_keyboard_nav = true;
|
||||||
|
|
||||||
|
if (!ui_manager.initialize(ui_cfg))
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to initialize UI manager." << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
font_loader loader;
|
font_loader loader;
|
||||||
|
|
||||||
@@ -80,11 +92,12 @@ int main(int, char **)
|
|||||||
templateEditor.apply_current_palette(colorEditor.controller().current_palette());
|
templateEditor.apply_current_palette(colorEditor.controller().current_palette());
|
||||||
settingsWindow.set_palette(colorEditor.controller().current_palette());
|
settingsWindow.set_palette(colorEditor.controller().current_palette());
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!backend.should_close())
|
||||||
{
|
{
|
||||||
glfwPollEvents();
|
backend.begin_frame();
|
||||||
|
|
||||||
loader.push_default_font();
|
loader.push_default_font();
|
||||||
begin_frame();
|
ui_manager.begin_frame();
|
||||||
|
|
||||||
render_menu_bar(&aboutWindow, &settingsWindow);
|
render_menu_bar(&aboutWindow, &settingsWindow);
|
||||||
setup_main_dockspace(first_time);
|
setup_main_dockspace(first_time);
|
||||||
@@ -95,8 +108,12 @@ int main(int, char **)
|
|||||||
settingsWindow.render();
|
settingsWindow.render();
|
||||||
|
|
||||||
loader.pop_font();
|
loader.pop_font();
|
||||||
end_frame(window);
|
|
||||||
|
ui_manager.end_frame();
|
||||||
|
backend.end_frame();
|
||||||
}
|
}
|
||||||
shutdown(window);
|
|
||||||
|
ui_manager.shutdown();
|
||||||
|
backend.shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
71
src/gui/ui_manager.cpp
Normal file
71
src/gui/ui_manager.cpp
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#include "gui/ui_manager.hpp"
|
||||||
|
#include "gui/backend/backend.hpp"
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace clrsync::gui
|
||||||
|
{
|
||||||
|
ui_manager::ui_manager(backend::backend_interface* backend)
|
||||||
|
: m_backend(backend)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_manager::~ui_manager()
|
||||||
|
{
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ui_manager::initialize(const ui_config& config)
|
||||||
|
{
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
m_imgui_context = ImGui::CreateContext();
|
||||||
|
if (!m_imgui_context)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
if (config.enable_docking)
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
|
|
||||||
|
if (config.enable_keyboard_nav)
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||||
|
|
||||||
|
if (!config.ini_path.empty())
|
||||||
|
io.IniFilename = config.ini_path.c_str();
|
||||||
|
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
|
||||||
|
if (!m_backend->init_imgui_backend())
|
||||||
|
{
|
||||||
|
ImGui::DestroyContext(static_cast<ImGuiContext*>(m_imgui_context));
|
||||||
|
m_imgui_context = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_manager::shutdown()
|
||||||
|
{
|
||||||
|
if (m_imgui_context)
|
||||||
|
{
|
||||||
|
m_backend->shutdown_imgui_backend();
|
||||||
|
ImGui::DestroyContext(static_cast<ImGuiContext*>(m_imgui_context));
|
||||||
|
m_imgui_context = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_manager::begin_frame()
|
||||||
|
{
|
||||||
|
m_backend->imgui_new_frame();
|
||||||
|
ImGui::NewFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_manager::end_frame()
|
||||||
|
{
|
||||||
|
ImGui::Render();
|
||||||
|
m_backend->imgui_render_draw_data(ImGui::GetDrawData());
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/gui/ui_manager.hpp
Normal file
38
src/gui/ui_manager.hpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef CLRSYNC_UI_MANAGER_HPP
|
||||||
|
#define CLRSYNC_UI_MANAGER_HPP
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace clrsync::gui::backend
|
||||||
|
{
|
||||||
|
class backend_interface;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace clrsync::gui
|
||||||
|
{
|
||||||
|
|
||||||
|
struct ui_config
|
||||||
|
{
|
||||||
|
std::string ini_path = "";
|
||||||
|
bool enable_docking = true;
|
||||||
|
bool enable_keyboard_nav = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ui_manager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ui_manager(backend::backend_interface *backend);
|
||||||
|
~ui_manager();
|
||||||
|
|
||||||
|
bool initialize(const ui_config& config = ui_config());
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
void begin_frame();
|
||||||
|
void end_frame();
|
||||||
|
|
||||||
|
private:
|
||||||
|
backend::backend_interface *m_backend;
|
||||||
|
void *m_imgui_context = nullptr;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user