Inital commit

This commit is contained in:
2022-08-04 13:35:22 +02:00
parent b8161a96ef
commit 7551ca0143
68 changed files with 77726 additions and 0 deletions

174
src/UCTGui.cpp Normal file
View 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
View 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
View 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
View 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;
}