Inital commit
This commit is contained in:
174
src/UCTGui.cpp
Normal file
174
src/UCTGui.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
#include "UCTGui.h"
|
||||
#include "UCTSave.h"
|
||||
#include "UCTUtils.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
namespace uct {
|
||||
namespace gui {
|
||||
|
||||
static save::UCTSave save;
|
||||
|
||||
void Init() {
|
||||
save = save::LoadConfig();
|
||||
|
||||
for (save::Template& t : save.templates) {
|
||||
for (save::TemplateSlot& slot : t.templateSlots) {
|
||||
std::memcpy(slot.valueBuffer, slot.defaultValue.data(), slot.defaultValue.size() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr float DELETE_SLOT_BUTTON_OFFSET = 50.0f;
|
||||
|
||||
static void RenderTemplate(save::Template& t, std::size_t index) {
|
||||
if (ImGui::CollapsingHeader(t.name.c_str())) {
|
||||
ImGui::InputTextMultiline(std::string("Template##" + t.name).c_str(), t.templateRaw, sizeof(t.templateRaw), ImVec2(1000, 500));
|
||||
for (save::TemplateSlot& slot : t.templateSlots) {
|
||||
ImGui::InputText(slot.name.c_str(), slot.valueBuffer, sizeof(slot.valueBuffer));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + DELETE_SLOT_BUTTON_OFFSET);
|
||||
ImGui::Button(std::string("Supprimer##" + slot.name).c_str());
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Ajouter un slot")) {
|
||||
ImGui::OpenPopup("NewSlot");
|
||||
}
|
||||
if (ImGui::IsPopupOpen("NewSlot")) {
|
||||
ImGui::BeginPopup("NewSlot");
|
||||
static char nameBuffer[512] = "\0";
|
||||
static char valueBuffer[512] = "\0";
|
||||
ImGui::InputText("Nom", nameBuffer, sizeof(nameBuffer));
|
||||
ImGui::InputText("Valeur par défaut", valueBuffer, sizeof(valueBuffer));
|
||||
if (ImGui::Button("Créer")) {
|
||||
save::TemplateSlot newSlot;
|
||||
newSlot.name = nameBuffer;
|
||||
newSlot.defaultValue = valueBuffer;
|
||||
std::memcpy(newSlot.valueBuffer, valueBuffer, sizeof(valueBuffer));
|
||||
t.templateSlots.push_back(newSlot);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Renommer")){
|
||||
ImGui::OpenPopup("RenameTemplate");
|
||||
}
|
||||
if (ImGui::IsPopupOpen("RenameTemplate")) {
|
||||
ImGui::BeginPopup("RenameTemplate");
|
||||
static char newNameBuffer[512] = "\0";
|
||||
ImGui::InputText("Nouveau nom", newNameBuffer, sizeof(newNameBuffer));
|
||||
if (ImGui::Button("Renommer")) {
|
||||
t.name = newNameBuffer;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Supprimer")) {
|
||||
save.templates.erase(save.templates.begin() + index);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Aperçu")) {
|
||||
ImGui::OpenPopup("ViewTemplate");
|
||||
}
|
||||
if(ImGui::IsPopupOpen("ViewTemplate")) {
|
||||
ImGui::BeginPopup("ViewTemplate");
|
||||
std::string view = utils::format(t);
|
||||
ImGui::InputTextMultiline("Aperçu", view.data(), view.size(), ImVec2(1000, 500), ImGuiInputTextFlags_ReadOnly);
|
||||
if (ImGui::Button("Copier dans le presse-papier")) {
|
||||
ImGui::SetClipboardText(view.c_str());
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Copier dans le presse-papier")) {
|
||||
ImGui::SetClipboardText(utils::format(t).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void RenderTemplatesHeader() {
|
||||
if (ImGui::Button("Nouveau")) {
|
||||
ImGui::OpenPopup("NewTemplate");
|
||||
}
|
||||
if (ImGui::IsPopupOpen("NewTemplate")) {
|
||||
ImGui::BeginPopup("NewTemplate");
|
||||
static char buffer[512] = "\0";
|
||||
ImGui::InputText("Nom", buffer, sizeof(buffer));
|
||||
if (ImGui::Button("Créer")) {
|
||||
save::Template newTemplate;
|
||||
newTemplate.name = buffer;
|
||||
save.templates.push_back(newTemplate);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
static void RenderTemplates() {
|
||||
if (ImGui::BeginTabItem("Templates")) {
|
||||
RenderTemplatesHeader();
|
||||
ImGui::Separator();
|
||||
for (std::size_t i = 0; i < save.templates.size(); i++) {
|
||||
save::Template& t = save.templates[i];
|
||||
RenderTemplate(t, i);
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
static void RenderCaisseTab() {
|
||||
if (ImGui::BeginTabItem("Compte Caisse")) {
|
||||
static float prices[] = {
|
||||
50, 20, 10, 5, 2, 1, 0.50, 0.20, 0.10,
|
||||
0.05, 0.02, 0.01
|
||||
};
|
||||
static std::array<int, 12> count{};
|
||||
for (int i = 0; i < count.size(); i++) {
|
||||
ImGui::InputInt(utils::format("%.2f euros", prices[i]).c_str(), &count[i]);
|
||||
}
|
||||
float total = 0;
|
||||
for (int i = 0; i < count.size(); i++) {
|
||||
total += prices[i] * count[i];
|
||||
}
|
||||
ImGui::Separator();
|
||||
ImGui::InputFloat("Fond de caisse", &save.fondDeCaisse, 1, 1, "%.2f");
|
||||
ImGui::Text("Bénéfice : %.2f euros", total - save.fondDeCaisse);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
static void RenderOptionsTab() {
|
||||
if (ImGui::BeginTabItem("Options")) {
|
||||
if (ImGui::Button("Enregistrer")) {
|
||||
save::SaveConfig(save);
|
||||
}
|
||||
static std::string configFilePath = save::GetConfigFilePath();
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Config : %s", configFilePath.c_str());
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
static void RenderMainTabBar() {
|
||||
ImGui::BeginTabBar("MainTabBar");
|
||||
RenderTemplates();
|
||||
RenderCaisseTab();
|
||||
RenderOptionsTab();
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
void Render() {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui::Begin("UCTWindow", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove);
|
||||
ImGui::SetWindowPos({ 0, 0 });
|
||||
ImGui::SetWindowSize({ io.DisplaySize.x, io.DisplaySize.y });
|
||||
RenderMainTabBar();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
} // namespace gui
|
||||
} // namespace uct
|
||||
89
src/UCTSave.cpp
Normal file
89
src/UCTSave.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#include "UCTSave.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace uct {
|
||||
namespace save {
|
||||
|
||||
static void to_json(json& j, const TemplateSlot& slot) {
|
||||
j["name"] = slot.name;
|
||||
j["default"] = slot.defaultValue;
|
||||
}
|
||||
|
||||
static void to_json(json& j, const Template& t) {
|
||||
j["name"] = t.name;
|
||||
j["raw"] = t.templateRaw;
|
||||
j["slots"] = t.templateSlots;
|
||||
}
|
||||
|
||||
static void to_json(json& j, const UCTSave& save) {
|
||||
j["templates"] = save.templates;
|
||||
j["fondDeCaisse"] = save.fondDeCaisse;
|
||||
}
|
||||
|
||||
static void from_json(const json& j, TemplateSlot& slot) {
|
||||
j["name"].get_to(slot.name);
|
||||
j["default"].get_to(slot.defaultValue);
|
||||
}
|
||||
|
||||
static void from_json(const json& j, Template& t) {
|
||||
j["name"].get_to(t.name);
|
||||
std::string templateRaw;
|
||||
j["raw"].get_to(templateRaw);
|
||||
std::memcpy(t.templateRaw, templateRaw.data(), templateRaw.size());
|
||||
j["slots"].get_to(t.templateSlots);
|
||||
}
|
||||
|
||||
static void from_json(const json& j, UCTSave& t) {
|
||||
j["templates"].get_to(t.templates);
|
||||
j["fondDeCaisse"].get_to(t.fondDeCaisse);
|
||||
}
|
||||
|
||||
std::string GetConfigFilePath() {
|
||||
#if defined(__linux__)
|
||||
return std::string(std::getenv("HOME")) + "/.config/UCT/config.json";
|
||||
#elif defined(_WIN32)
|
||||
return std::string(std::getenv("APPDATA")) + "\\UCT\\config.json";
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool InitConfigPath() {
|
||||
std::string path = GetConfigFilePath();
|
||||
if (!fs::exists(path))
|
||||
{
|
||||
fs::path configFile(path);
|
||||
fs::create_directories(configFile.parent_path());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SaveConfig(const UCTSave& save) {
|
||||
InitConfigPath();
|
||||
std::ofstream fileStream(GetConfigFilePath());
|
||||
|
||||
json jsonOutput = save;
|
||||
|
||||
fileStream << jsonOutput;
|
||||
}
|
||||
|
||||
UCTSave LoadConfig() {
|
||||
if (!InitConfigPath())
|
||||
return {};
|
||||
std::ifstream fileStream(GetConfigFilePath());
|
||||
|
||||
json input;
|
||||
fileStream >> input;
|
||||
std::cout << input << std::endl;
|
||||
UCTSave save = input;
|
||||
return save;
|
||||
}
|
||||
|
||||
} // namespace save
|
||||
} // namespace uct
|
||||
31
src/UCTUtils.cpp
Normal file
31
src/UCTUtils.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "UCTUtils.h"
|
||||
#include "UCTSave.h"
|
||||
|
||||
namespace uct {
|
||||
namespace utils {
|
||||
|
||||
std::string format(std::string formatString, const std::vector<std::string>& args) {
|
||||
for (std::size_t i = 0; i < args.size(); i++) {
|
||||
std::size_t formatPos = formatString.find_first_of("%") + 2;
|
||||
std::string start = formatString.substr(0, formatPos);
|
||||
std::string end = formatString.substr(formatPos, formatString.size() - formatPos);
|
||||
start = format(start, args[i]);
|
||||
formatString = start + end;
|
||||
}
|
||||
return formatString;
|
||||
}
|
||||
|
||||
std::string format(const save::Template& t) {
|
||||
std::string formatString = t.templateRaw;
|
||||
for (std::size_t i = 0; i < t.templateSlots.size(); i++) {
|
||||
std::size_t formatPos = formatString.find_first_of("%") + 2;
|
||||
std::string start = formatString.substr(0, formatPos);
|
||||
std::string end = formatString.substr(formatPos, formatString.size() - formatPos);
|
||||
start = format(start, t.templateSlots[i].valueBuffer);
|
||||
formatString = start + end;
|
||||
}
|
||||
return formatString;
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
} // namespace uct
|
||||
141
src/main.cpp
Normal file
141
src/main.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
// Dear ImGui: standalone example application for GLFW + OpenGL 3, using programmable pipeline
|
||||
// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
#include "imgui.h"
|
||||
#include "backends/imgui_impl_glfw.h"
|
||||
#include "backends/imgui_impl_opengl3.h"
|
||||
#include <GL/glew.h>
|
||||
#include <stdio.h>
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
#include <GLES2/gl2.h>
|
||||
#endif
|
||||
#include <GLFW/glfw3.h> // Will drag system OpenGL headers
|
||||
|
||||
// [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers.
|
||||
// To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma.
|
||||
// Your own project should not be affected, as you are likely to link with a newer binary of GLFW that is adequate for your version of Visual Studio.
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS)
|
||||
#pragma comment(lib, "legacy_stdio_definitions")
|
||||
#endif
|
||||
|
||||
#include "UCTGui.h"
|
||||
|
||||
static void glfw_error_callback(int error, const char* description)
|
||||
{
|
||||
fprintf(stderr, "Glfw Error %d: %s\n", error, description);
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
// Setup window
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
if (!glfwInit())
|
||||
return 1;
|
||||
|
||||
// Decide GL+GLSL versions
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
// GL ES 2.0 + GLSL 100
|
||||
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(__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, "UCT", NULL, NULL);
|
||||
if (window == NULL)
|
||||
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();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
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 NULL. 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.
|
||||
// - 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 \\ !
|
||||
//io.Fonts->AddFontDefault();
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f);
|
||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
|
||||
//IM_ASSERT(font != NULL);
|
||||
|
||||
// Our state
|
||||
bool show_demo_window = true;
|
||||
bool show_another_window = false;
|
||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
|
||||
uct::gui::Init();
|
||||
|
||||
// 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();
|
||||
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
// Rendering
|
||||
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);
|
||||
|
||||
uct::gui::Render();
|
||||
ImGui::Render();
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user