From 3e1ee817a9abde927a256c94563d510f2db55367 Mon Sep 17 00:00:00 2001 From: djairoh Date: Wed, 29 Jan 2025 02:40:38 +0100 Subject: [PATCH] feat (wip): gui --- src/core/CLI.cpp | 0 src/core/CLI.h | 0 src/core/CLIParser.cpp | 25 +++ src/core/CLIParser.h | 0 src/core/Colour.cpp | 35 ++++ src/core/Colour.h | 22 +++ src/core/ImageMatcher.h | 10 ++ src/core/RGBMatcher.cpp | 0 src/core/RGBMatcher.h | 0 src/gui/Window.cpp | 300 +++++++++++++++++++++++++++++++ src/gui/Window.h | 28 +++ src/gui/layouts/Layout.h | 8 + src/gui/layouts/SquareLayout.cpp | 127 +++++++++++++ src/gui/layouts/SquareLayout.h | 25 +++ src/main.cpp | 9 + 15 files changed, 589 insertions(+) create mode 100644 src/core/CLI.cpp create mode 100644 src/core/CLI.h create mode 100644 src/core/CLIParser.cpp create mode 100644 src/core/CLIParser.h create mode 100644 src/core/Colour.cpp create mode 100644 src/core/Colour.h create mode 100644 src/core/ImageMatcher.h create mode 100644 src/core/RGBMatcher.cpp create mode 100644 src/core/RGBMatcher.h create mode 100644 src/gui/Window.cpp create mode 100644 src/gui/Window.h create mode 100644 src/gui/layouts/Layout.h create mode 100644 src/gui/layouts/SquareLayout.cpp create mode 100644 src/gui/layouts/SquareLayout.h create mode 100644 src/main.cpp diff --git a/src/core/CLI.cpp b/src/core/CLI.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/core/CLI.h b/src/core/CLI.h new file mode 100644 index 0000000..e69de29 diff --git a/src/core/CLIParser.cpp b/src/core/CLIParser.cpp new file mode 100644 index 0000000..7abf112 --- /dev/null +++ b/src/core/CLIParser.cpp @@ -0,0 +1,25 @@ +// #include +// #include +// int main(int argc, char* argv[]) { +// // CLI parsing code. TODO: move to core somewhere +// option longopts[] = { +// {"number", optional_argument, NULL, 'n'}, +// {"show-ends", optional_argument, NULL, 'E'}, {0}}; +// +// while (1) { +// const int opt = getopt_long(argc, argv, "nE::", longopts, 0); +// +// if (opt == -1) { +// break; +// } +// +// switch (opt) { +// case 'n': +// // ... +// case 'E': +// // ... +// } +// } +// +// //... +// } diff --git a/src/core/CLIParser.h b/src/core/CLIParser.h new file mode 100644 index 0000000..e69de29 diff --git a/src/core/Colour.cpp b/src/core/Colour.cpp new file mode 100644 index 0000000..5bc0183 --- /dev/null +++ b/src/core/Colour.cpp @@ -0,0 +1,35 @@ +#include "Colour.h" +#include +#include +#include + + +using namespace core; + + +Colour::Colour(const float r, const float g, const float b) { + this->len = sqrt(r*r + g*g + b*b); + + this->r = r; + this->g = g; + this->b = b; +} + + +Colour::~Colour() { +} + + +char* Colour::toString() { + sprintf(this->str, "%3.0f %3.0f %3.0f", round(this->r*255.0f),round(this->g*255.0f),round(this->b*255.0f)); + return this->str; +} + + +float Colour::getLength() const { + return this->len; +} + +bool Colour::operator<(const Colour& other) const { + return getLength() < other.getLength(); +} diff --git a/src/core/Colour.h b/src/core/Colour.h new file mode 100644 index 0000000..bb6c559 --- /dev/null +++ b/src/core/Colour.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + + +namespace core { + class Colour { + public: + Colour(const float r, const float g, const float b); + ~Colour(); + char* toString(); + float getLength() const; + bool operator<(const Colour& other) const; + float r; // FIXME: should be private + float g; + float b; + private: + char str[128]; + float len; + }; +} diff --git a/src/core/ImageMatcher.h b/src/core/ImageMatcher.h new file mode 100644 index 0000000..73e7ae5 --- /dev/null +++ b/src/core/ImageMatcher.h @@ -0,0 +1,10 @@ +#pragma once + + + +class ImageMatcher{ +public: + +private: + +}; diff --git a/src/core/RGBMatcher.cpp b/src/core/RGBMatcher.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/core/RGBMatcher.h b/src/core/RGBMatcher.h new file mode 100644 index 0000000..e69de29 diff --git a/src/gui/Window.cpp b/src/gui/Window.cpp new file mode 100644 index 0000000..a07b1ac --- /dev/null +++ b/src/gui/Window.cpp @@ -0,0 +1,300 @@ +#include "imgui.h" +#include "imgui/backends/imgui_impl_glfw.h" +#include "imgui/backends/imgui_impl_opengl3.h" +#include "layouts/SquareLayout.h" +#include +#include "Window.h" +#include +#include + +using namespace Gui; + + +// This function is called by glfw when the window is resized. +void framebuffer_size_callback(GLFWwindow* window, int w, int h) { + glViewport(0 , 0, w, h); + Window* newWin = reinterpret_cast(glfwGetWindowUserPointer(window)); + newWin->resize(w, h); +} + + +Window::Window() {Window(w, h);} + + +Window::Window(const int w, const int h) : w(w), h(h) { + init(); + this->layoutSelected = 0; + this->layouts.push_back(new SquareLayout()); +} + + +Window::~Window() { + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + glfwDestroyWindow(this->window); + glfwTerminate(); +} + + +void Window::init() { + glfwInit(); + // requesting context version 1.0 makes glfw try to provide the latest version if possible + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + + this->window = glfwCreateWindow(this->w, this->h, "C0l0ur M4tch3r", NULL, NULL); + if (this->window == NULL) { + // TODO: error handling/graceful shutdown + std::cout << "Failed to create GLFW Window\n"; + glfwTerminate(); + return; + } + + glfwMakeContextCurrent(this->window); + glfwSetWindowUserPointer(this->window, reinterpret_cast(this)); + + glViewport(0, 0, this->w, this->h); + if (glfwSetFramebufferSizeCallback(this->window, framebuffer_size_callback) != 0) { + // TODO: error handling/graceful shutdown + std::cout << "Failed to set resize callback function\n"; + return; + } + + // ImGui + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + + this->io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + ImGui::StyleColorsDark(); + + ImGui_ImplGlfw_InitForOpenGL(this->window, true); + ImGui_ImplOpenGL3_Init(); + + // TODO: font support +} + +int Window::run() { + while (!glfwWindowShouldClose(window)) { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + glfwPollEvents(); + if (glfwGetWindowAttrib(window, GLFW_ICONIFIED) != 0) + { + ImGui_ImplGlfw_Sleep(10); + continue; + } + + // Start the Dear ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + this->layouts[0]->draw(this->w, this->h); + + // Rendering + ImGui::Render(); + int display_w, display_h; + + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + + glClear(GL_COLOR_BUFFER_BIT); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + glfwSwapBuffers(this->window); + } + return 0; +} + +void Window::resize(const int w, const int h) { + this->w = w; + this->h = h; +} + + +// #include "imgui.h" +// #include "imgui/backends/imgui_impl_glfw.h" +// #include "imgui/backends/imgui_impl_opengl3.h" +// #include +// +// #define GL_SILENCE_DEPRECATION +// +// #if defined(IMGUI_IMPL_OPENGL_ES2) +// #include +// #endif +// +// #include // Will drag system OpenGL headers +// +// static void glfw_error_callback(int error, const char* description) +// { +// fprintf(stderr, "GLFW Error %d: %s\n", error, description); +// } +// +// // Main code +// int main(int, char**) +// { +// glfwSetErrorCallback(glfw_error_callback); +// if (!glfwInit()) +// return 1; +// +// // Decide GL+GLSL versions +// #if defined(IMGUI_IMPL_OPENGL_ES2) +// // GL ES 2.0 + GLSL 100 (WebGL 1.0) +// const char* glsl_version = "#version 100"; +// glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); +// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); +// glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); +// #elif defined(IMGUI_IMPL_OPENGL_ES3) +// // GL ES 3.0 + GLSL 300 es (WebGL 2.0) +// const char* glsl_version = "#version 300 es"; +// glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); +// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); +// glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); +// #elif defined(__APPLE__) +// // GL 3.2 + GLSL 150 +// const char* glsl_version = "#version 150"; +// glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); +// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); +// glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only +// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac +// #else +// // GL 3.0 + GLSL 130 +// const char* glsl_version = "#version 130"; +// glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); +// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); +// //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only +// //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only +// #endif +// +// // Create window with graphics context +// GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+OpenGL3 example", nullptr, nullptr); +// if (window == nullptr) +// return 1; +// glfwMakeContextCurrent(window); +// glfwSwapInterval(1); // Enable vsync +// +// // Setup Dear ImGui context +// IMGUI_CHECKVERSION(); +// ImGui::CreateContext(); +// ImGuiIO& io = ImGui::GetIO(); (void)io; +// io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls +// io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls +// +// // Setup Dear ImGui style +// ImGui::StyleColorsDark(); +// +// // Setup Platform/Renderer backends +// ImGui_ImplGlfw_InitForOpenGL(window, true); +// #ifdef __EMSCRIPTEN__ +// ImGui_ImplGlfw_InstallEmscriptenCallbacks(window, "#canvas"); +// #endif +// ImGui_ImplOpenGL3_Init(glsl_version); +// +// // Load Fonts +// // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. +// // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. +// // - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). +// // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. +// // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. +// // - Read 'docs/FONTS.md' for more instructions and details. +// // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! +// // - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details. +// //io.Fonts->AddFontDefault(); +// //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); +// //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); +// //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); +// //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); +// //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese()); +// //IM_ASSERT(font != nullptr); +// +// // Our state +// bool show_demo_window = true; +// bool show_another_window = false; +// ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); +// +// // Main loop +// while (!glfwWindowShouldClose(window)) { +// // Poll and handle events (inputs, window resize, etc.) +// // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data. +// // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data. +// // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. +// glfwPollEvents(); +// if (glfwGetWindowAttrib(window, GLFW_ICONIFIED) != 0) +// { +// ImGui_ImplGlfw_Sleep(10); +// continue; +// } +// +// // Start the Dear ImGui frame +// ImGui_ImplOpenGL3_NewFrame(); +// ImGui_ImplGlfw_NewFrame(); +// ImGui::NewFrame(); +// +// // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). +// if (show_demo_window) +// ImGui::ShowDemoWindow(&show_demo_window); +// +// // 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window. +// { +// static float f = 0.0f; +// static int counter = 0; +// +// ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. +// +// ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) +// ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state +// ImGui::Checkbox("Another Window", &show_another_window); +// +// ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f +// ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color +// +// if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) +// counter++; +// ImGui::SameLine(); +// ImGui::Text("counter = %d", counter); +// +// ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); +// ImGui::End(); +// } +// +// // 3. Show another simple window. +// if (show_another_window) +// { +// ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) +// ImGui::Text("Hello from another window!"); +// if (ImGui::Button("Close Me")) +// show_another_window = false; +// ImGui::End(); +// } +// +// // Rendering +// ImGui::Render(); +// int display_w, display_h; +// glfwGetFramebufferSize(window, &display_w, &display_h); +// glViewport(0, 0, display_w, display_h); +// glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); +// glClear(GL_COLOR_BUFFER_BIT); +// ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); +// +// glfwSwapBuffers(window); +// } +// +// // Cleanup +// ImGui_ImplOpenGL3_Shutdown(); +// ImGui_ImplGlfw_Shutdown(); +// ImGui::DestroyContext(); +// +// glfwDestroyWindow(window); +// glfwTerminate(); +// +// return 0; +// } diff --git a/src/gui/Window.h b/src/gui/Window.h new file mode 100644 index 0000000..c814529 --- /dev/null +++ b/src/gui/Window.h @@ -0,0 +1,28 @@ +#pragma once + +#include "imgui.h" +#include "layouts/Layout.h" +#include +#include + +namespace Gui { + class Window { + public: + Window(); + Window(const int w, const int h); + void resize(const int w, const int h); + ~Window(); + int run(); + private: + int w; + int h; + ImGuiIO io; + GLFWwindow* window; + std::vector layouts; + int layoutSelected; + + void init(); + void cleanup(); + }; +} + diff --git a/src/gui/layouts/Layout.h b/src/gui/layouts/Layout.h new file mode 100644 index 0000000..a825f07 --- /dev/null +++ b/src/gui/layouts/Layout.h @@ -0,0 +1,8 @@ +#pragma once + +namespace Gui { + class Layout { + public: + virtual void draw(const int w, const int h) = 0; + }; +} diff --git a/src/gui/layouts/SquareLayout.cpp b/src/gui/layouts/SquareLayout.cpp new file mode 100644 index 0000000..3d45255 --- /dev/null +++ b/src/gui/layouts/SquareLayout.cpp @@ -0,0 +1,127 @@ +#include "SquareLayout.h" +#include "imgui.h" +#include "imgui/backends/imgui_impl_glfw.h" +#include "imgui/backends/imgui_impl_opengl3.h" +#include + +using namespace Gui; + +auto flags = ImGuiWindowFlags_NoTitleBar |ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse; + +SquareLayout::SquareLayout() : run(false), refImg("") { + this->selectedColour = new float[3]; + this->selectedColour[0] = 0.0f; + this->selectedColour[1] = 1.0f; + this->selectedColour[2] = 2.0f; + // this->selectedColour = (float *)malloc(3*sizeof(float)); +} + + +SquareLayout::~SquareLayout() { + // free(this->selectedColour); +} + + +bool SquareLayout::shouldRun() { + return this->run; +} + + + +void SquareLayout::draw(const int w, const int h) { + drawSettings(w, h); + drawColours(w, h); +} + +void SquareLayout::drawSettings(const int w, const int h) { + ImGui::SetNextWindowPos(ImVec2(0,0)); + ImGui::SetNextWindowSize(ImVec2(w/2,h/2)); + ImGui::Begin("SettingsPanel", 0, flags); + + ImGui::Text("Select reference image"); + // TODO: file picker + + float wi = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.y) * 0.60f; + ImGui::SetNextItemWidth(wi); + ImGui::ColorPicker3("##MyColor##1", this->selectedColour, ImGuiColorEditFlags_DisplayRGB|ImGuiColorEditFlags_DisplayHex); + + if (ImGui::Button("Add Colour")) { + auto c3 = this->selectedColour; + this->colours.insert(core::Colour(c3[0], c3[1], c3[2])); + } + + ImGui::End(); +} + +int makeComboBox(std::set &cols, const char* title, const int wi) { + ImGui::SetNextItemWidth(wi); + + static int selected = 0; + int n=0; + std::vector toErase; + if (ImGui::BeginListBox(title, ImVec2(wi, ImGui::GetContentRegionAvail().y))) { + for (auto it = cols.begin(); it != cols.end(); ++it) { + core::Colour c = *it; + const bool is_selected = (selected == n); + + if (ImGui::Selectable(c.toString(), is_selected)) + selected = n; + + ImGui::SameLine(); + ImGui::PushID(n); + if (ImGui::Button("D")) + toErase.push_back(c); + + ImGui::PopID(); + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + n++; + } + + for (core::Colour c: toErase) { + cols.erase(c); + } + + ImGui::EndListBox(); + } + return selected; + +} + +void SquareLayout::drawColours(const int w, const int h) { + ImGui::SetNextWindowPos(ImVec2(0,h/2)); + ImGui::SetNextWindowSize(ImVec2(w/2,h/2)); + ImGui::Begin("ColourViewer", 0, flags); + + int wi = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.y) * 0.80f; + int selected = makeComboBox(this->colours, "##box1", wi); + + wi = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.y) * 0.195f; + ImGui::SameLine(); + if (this->colours.size()) { + auto c = *next(this->colours.begin(), selected); + ImGui::ColorButton("##3c", ImVec4(c.r, c.g, c.b, 0.0f), ImGuiColorEditFlags_NoBorder, ImVec2(wi, ImGui::GetContentRegionAvail().y)); + } else { + ImGui::ColorButton("##3c", ImVec4(0,0,0,0), ImGuiColorEditFlags_NoBorder, ImVec2(wi, ImGui::GetContentRegionAvail().y)); + } + ImGui::End(); + + ImGui::SetNextWindowPos(ImVec2(w/2,h/2)); + ImGui::SetNextWindowSize(ImVec2(w/2,h/2)); + ImGui::Begin("ColourViewer##2", 0, flags); + wi = ((ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.y) * 0.20f); + if (this->colours.size()) { + auto c = *next(this->colours.begin(), selected); + ImGui::ColorButton("##3d", ImVec4(c.r, c.g, c.b, 0.0f), ImGuiColorEditFlags_NoBorder, ImVec2(wi, ImGui::GetContentRegionAvail().y)); + } else { + ImGui::ColorButton("##3d", ImVec4(0,0,0,0), ImGuiColorEditFlags_NoBorder, ImVec2(wi, ImGui::GetContentRegionAvail().y)); + } + + ImGui::SameLine(); + // TODO: change this->colours to the new (calculated) colours + int newselected = makeComboBox(this->colours, "##box2", ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.y); + + ImGui::End(); +} diff --git a/src/gui/layouts/SquareLayout.h b/src/gui/layouts/SquareLayout.h new file mode 100644 index 0000000..9a31dda --- /dev/null +++ b/src/gui/layouts/SquareLayout.h @@ -0,0 +1,25 @@ +#pragma once + +#include "../../core/Colour.h" +#include "Layout.h" +#include +#include +#include + + +namespace Gui { + class SquareLayout : public Layout { + public: + SquareLayout(); + ~SquareLayout(); + bool shouldRun(); + void draw(const int w, const int h); + private: + std::set colours; + std::string refImg; + float* selectedColour; + bool run; + void drawSettings(const int w, const int h); + void drawColours(const int w, const int h); + }; +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..339e955 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,9 @@ +#include "gui/Window.h" + + +int main(int argc, char* argv[]) { + Gui::Window window(800, 600); + int out = window.run(); + return out; +} +