This commit is contained in:
andrewchilicki
2025-02-08 16:37:29 -05:00
parent 7e0e9d2592
commit 1485f1325e
9 changed files with 183 additions and 257 deletions

View File

@ -11,7 +11,7 @@
namespace ColorValues
{
ImColor lumonBlue = ImColor(101,213,235,255);
ImColor lumonBlue = ImColor(157,227,235,255);
}
class UIManagerImpl : public UIManager
@ -39,26 +39,25 @@ public:
void update() final
{
if (ImGui::IsKeyPressed(ImGuiKey_Tab))
{
debugMode = !debugMode;
// Toggle settings mode with 'TAB'
if (ImGui::IsKeyPressed(ImGuiKey_Tab)) {
settingsMode = !settingsMode;
}
if (ImGui::IsKeyPressed(ImGuiKey_I))
{
// Toggle idle mode with 'I'
if (ImGui::IsKeyPressed(ImGuiKey_I)) {
idleMode = !idleMode;
}
if (idleMode)
{
if (idleMode) {
idleScreen->update();
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{
// Exit idle mode with 'LEFT CLICK'
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
idleMode = false;
numbersPanel->triggerLoadAnimation();
}
} else
{
} else {
numbersPanel->update();
}
}
@ -76,22 +75,18 @@ public:
ImGui::SetNextWindowSize(ImVec2(viewportSize.x, viewportSize.y));
if (ImGui::Begin("Main", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse))
{
if (idleMode)
{
if (idleMode) {
idleScreen->drawIdleScreen();
} else
{
} else {
numbersPanel->drawNumbersPanel();
}
}
ImGui::End();
if (debugMode)
{
if (settingsMode) {
ImGui::SetNextWindowPos(viewportPos);
ImGui::SetNextWindowSize(ImVec2(viewportSize.x * settingsWidthRatio, viewportSize.y));
if (ImGui::Begin("Settings"))
{
if (ImGui::Begin("Settings")) {
numbersPanel->drawSettings();
}
ImGui::End();
@ -107,11 +102,10 @@ public:
private:
std::shared_ptr<ImageDisplay> imageDisplay;
std::shared_ptr<NumbersPanel> numbersPanel;
std::shared_ptr<IdleScreen> idleScreen;
bool debugMode = false;
bool settingsMode = false;
bool idleMode = false;
};

View File

@ -13,10 +13,8 @@ namespace ColorValues
class UIManager {
public:
virtual void init() = 0;
virtual void draw() = 0;
virtual void update() = 0;
virtual void cleanup() = 0;
virtual ~UIManager() = default;

View File

@ -3,7 +3,6 @@
#include "ImageDisplay.h"
#include <imgui.h>
#include <iostream>
#include <ostream>
#include "../UIManager.h"
@ -18,10 +17,9 @@ public:
void update() final
{
// Adjust logo scale and speed based on viewport size so it is consistent
// Want scale proportionally to the window size
auto viewportSize = ImGui::GetMainViewport()->Size;
if (lastViewportSize.x != viewportSize.x || lastViewportSize.y != viewportSize.y)
{
if (lastViewportSize.x != viewportSize.x || lastViewportSize.y != viewportSize.y) {
float displaySizeScalePrev = lastViewportSize.x/1280.f;
float displaySizeScale = viewportSize.x/1280.f;
float adjustedScale = displaySizeScale / displaySizeScalePrev;
@ -46,19 +44,15 @@ public:
ImVec2 minPosition = ImVec2(windowPos.x, windowPos.y);
ImVec2 maxPosition = ImVec2(windowPos.x + windowSize.x - scale*logoSize.x, windowPos.y + windowSize.y - scale*logoSize.y);
if (currentLogoPosition.x >= maxPosition.x)
{
if (currentLogoPosition.x >= maxPosition.x) {
nextOffset.x = -1;
} else if (currentLogoPosition.x < minPosition.x)
{
} else if (currentLogoPosition.x < minPosition.x) {
nextOffset.x = 1;
}
if (currentLogoPosition.y >= maxPosition.y)
{
if (currentLogoPosition.y >= maxPosition.y) {
nextOffset.y = -1;
} else if (currentLogoPosition.y < minPosition.y)
{
} else if (currentLogoPosition.y < minPosition.y) {
nextOffset.y = 1;
}

View File

@ -23,14 +23,12 @@ public:
// Update max bad groups for each bin
auto badGroups = numberGrid->getBadGroups();
for (auto &[id, group] : badGroups)
{
for (auto &[id, group] : badGroups) {
bins[group->binIdx].maxBadGroups++;
}
// Load settings
if (auto loadedSettings = loadSettings(settingsSavePath))
{
if (auto loadedSettings = loadSettings(settingsSavePath)) {
displaySettings = loadedSettings->displaySettings;
controlSettings = loadedSettings->controlSettings;
std::cout << "Successfully loaded settings from disk." << std::endl;
@ -43,8 +41,7 @@ public:
ImGuiIO& io = ImGui::GetIO();
font = io.Fonts->AddFontFromFileTTF("./assets/Montserrat-Bold.ttf", 50.f);
io.Fonts->Build();
if (font == nullptr)
{
if (font == nullptr) {
font = ImGui::GetDefaultFont();
std::cerr << "Failed to load 'Montserrat-Bold' font." << std::endl;
}
@ -82,29 +79,26 @@ public:
void triggerLoadAnimation() final
{
// Reset 'regenerate scale' on all numbers
for (auto &[x, gridY] : numberGrid->getGrid())
{
for (auto &[y, gridNumber] : gridY)
{
for (auto &[x, gridY] : numberGrid->getGrid()) {
for (auto &[y, gridNumber] : gridY) {
gridNumber->regenerateScale = 0.f;
}
}
}
private:
std::optional<int> drawNumbersGrid(const ImVec2& windowPos, const ImVec2& windowSize, const ImVec2& mousePos, bool updateDisplayInfos)
{
std::optional<int> refiningToBin = std::nullopt;
for (auto &[x, gridY] : numberGrid->getGrid())
{
for (auto &[y, gridNumber] : gridY)
{
for (auto &[x, gridY] : numberGrid->getGrid()) {
for (auto &[y, gridNumber] : gridY) {
std::string numberToDraw = "numbers/" + std::to_string(gridNumber->num) + ".png";
auto [width, height] = imageDisplay->getImageSize(numberToDraw);
double badScale = gridNumber->badGroup ? gridNumber->badGroup->scale : 0.0;
if (updateDisplayInfos)
{
if (updateDisplayInfos) {
// Only need to update when viewport has changed
ImVec2 localNumberPos = ImVec2((x * displaySettings.gridSpacing + panelOffset.x)*panelScale, (y * displaySettings.gridSpacing + panelOffset.y)*panelScale);
gridNumber->displayInfos.centerX = localNumberPos.x + windowPos.x;
gridNumber->displayInfos.centerY = localNumberPos.y + windowPos.y;
@ -114,104 +108,97 @@ private:
double heightOffset = (baseNumberScale*height/2.f);
gridNumber->displayInfos.isVisible = gridNumber->displayInfos.centerX + widthOffset < windowPos.x + windowSize.x && gridNumber->displayInfos.centerX - widthOffset > windowPos.x &&
gridNumber->displayInfos.centerY + heightOffset < windowPos.y + windowSize.y - displayPresets.numberWindowBufferBottom && gridNumber->displayInfos.centerY - heightOffset > windowPos.y + displayPresets.numberWindowBufferTop;
}
if (!gridNumber->displayInfos.isVisible)
{
// Don't draw numbers out of viewport
if (!gridNumber->displayInfos.isVisible) {
continue;
}
auto centerPos = ImVec2(gridNumber->displayInfos.centerX, gridNumber->displayInfos.centerY);
if (gridNumber->badGroup && gridNumber->badGroup->refined)
{
float startX = gridNumber->displayInfos.centerX;
float startY = gridNumber->displayInfos.centerY;
if (gridNumber->displayInfos.refinedX == -1)
{
gridNumber->displayInfos.refinedX = startX;
gridNumber->displayInfos.refinedY = startY;
}
auto binIdx = gridNumber->badGroup->binIdx;
if (binIdx > 4)
{
std::cout << "Error: Bin index greater than expected. Setting to max." << std::endl;
binIdx = 4;
}
float distX = bins[binIdx].pos.x - gridNumber->displayInfos.refinedX;
float distY = bins[binIdx].pos.y - gridNumber->displayInfos.refinedY;
float distance = sqrt(distX * distX + distY * distY);
const float moveSpeed = 3.0f;
if (distance > moveSpeed)
{
float dirX = distX / distance;
float dirY = distY / distance;
gridNumber->displayInfos.refinedX += dirX * moveSpeed;
gridNumber->displayInfos.refinedY += dirY * moveSpeed;
centerPos = ImVec2(gridNumber->displayInfos.refinedX, gridNumber->displayInfos.refinedY);
refiningToBin = gridNumber->badGroup->binIdx;
}
else
{
gridNumber->badGroup.reset(); // No longer a bad number
gridNumber->num = numberGrid->randomNumber(0,9);
gridNumber->regenerateScale = 0.f;
}
}
// Animate number on screen
float numberAlpha = 255;
if (gridNumber->regenerateScale < 1.f)
{
if (gridNumber->regenerateScale < 1.f) {
gridNumber->regenerateScale += numberGrid->randomNumber(0,10)*0.001f;
numberAlpha = static_cast<int>(std::clamp(gridNumber->regenerateScale*2.f*255.f, 0.f, 255.f));
}
// Offset from noise scale
double noiseScale = perlin.noise3D((x * displaySettings.noiseScale), (y * displaySettings.noiseScale), t*displaySettings.noiseSpeed);
if (gridNumber->displayInfos.horizontalOffset)
{
if (gridNumber->displayInfos.horizontalOffset) {
centerPos.x += noiseScale*displaySettings.noiseScaleOffset;
} else
{
} else {
centerPos.y += noiseScale*displaySettings.noiseScaleOffset;
}
// Colour
auto col = ColorValues::lumonBlue.Value;
col.w = numberAlpha;
if (revealMap && gridNumber->badGroup)
{
if (revealMap && gridNumber->badGroup) {
col = gridNumber->badGroup->isActive ? ImVec4(255,255,0,numberAlpha) : ImVec4(255,0,0,255);
}
// Scale from mouse hovering
auto numberScale = getScaleFromCursor(centerPos, mousePos);
if (gridNumber->badGroup && gridNumber->badGroup->isActive)
{
if (numberScale > 1.0f)
{
gridNumber->badGroup->superActive = true;
// Handle if part of bad group
if (gridNumber->badGroup) {
if (gridNumber->badGroup->isActive) {
// Make number 'super active'
if (numberScale > 1.0f) {
gridNumber->badGroup->superActive = true;
}
// Mark as refined on 'LEFT CLICK'
if (numberScale >= (0.5f + displaySettings.mouseScaleMultiplier) && ImGui::IsKeyDown(ImGuiKey_MouseLeft)) {
gridNumber->badGroup->refined = true;
bins[gridNumber->badGroup->binIdx].badGroupsRefined++;
}
}
if (numberScale >= (0.5f + displaySettings.mouseScaleMultiplier) && ImGui::IsKeyDown(ImGuiKey_MouseLeft))
{
gridNumber->badGroup->refined = true;
bins[gridNumber->badGroup->binIdx].badGroupsRefined++;
// Add jitter to 'super active' bad numbers
if (gridNumber->badGroup->superActive) {
centerPos.x += numberGrid->randomNumber(-10, 10)*badScale;
centerPos.y += numberGrid->randomNumber(-10, 10)*badScale;
}
// Animate position if number has been refined
if (gridNumber->badGroup->refined) {
float startX = gridNumber->displayInfos.centerX;
float startY = gridNumber->displayInfos.centerY;
if (gridNumber->displayInfos.refinedX == -1) {
gridNumber->displayInfos.refinedX = startX;
gridNumber->displayInfos.refinedY = startY;
}
auto binIdx = gridNumber->badGroup->binIdx;
if (binIdx > 4) {
std::cout << "Error: Bin index greater than expected. Setting to max." << std::endl;
binIdx = 4;
}
float distX = bins[binIdx].pos.x - gridNumber->displayInfos.refinedX;
float distY = bins[binIdx].pos.y - gridNumber->displayInfos.refinedY;
float distance = sqrt(distX * distX + distY * distY);
if (distance > displaySettings.refinedToBinSpeed) {
float dirX = distX / distance;
float dirY = distY / distance;
gridNumber->displayInfos.refinedX += dirX * displaySettings.refinedToBinSpeed;
gridNumber->displayInfos.refinedY += dirY * displaySettings.refinedToBinSpeed;
centerPos = ImVec2(gridNumber->displayInfos.refinedX, gridNumber->displayInfos.refinedY);
refiningToBin = gridNumber->badGroup->binIdx;
} else {
gridNumber->badGroup.reset(); // No longer a bad number
gridNumber->num = numberGrid->randomNumber(0,9);
gridNumber->regenerateScale = 0.f;
}
}
}
if (gridNumber->badGroup && gridNumber->badGroup->superActive)
{
centerPos.x += numberGrid->randomNumber(-10, 10)*badScale;
centerPos.y += numberGrid->randomNumber(-10, 10)*badScale;
}
// Draw number
float combinedScale = gridNumber->regenerateScale*displaySettings.imageScale*numberScale*panelScale + badScale;
ImGui::SetCursorPos(ImVec2(centerPos.x - ImGui::GetWindowPos().x - ((width*combinedScale)/2.f), centerPos.y - ImGui::GetWindowPos().y - ((height*combinedScale)/2.f)));
imageDisplay->drawImGuiImage(numberToDraw, combinedScale, col);
@ -226,10 +213,11 @@ private:
{
std::string binPercentPath = "bins/bin-percent.png";
auto [widthP, heightP] = imageDisplay->getImageSize(binPercentPath);
for (auto &b : bins)
{
for (auto &b : bins) {
// Scale based on viewport size
auto pos = b.updatePos(windowSize, windowPos, displayPresets.numberWindowBufferBottom - displayPresets.binOffset);
// Draw bin images
std::string binPath = "bins/bin0" + std::to_string(b.id) + ".png";
auto [width, height] = imageDisplay->getImageSize(binPath);
ImGui::SetCursorPos(ImVec2(pos.x - windowPos.x - (width*displayPresets.binImageScale/2.f), pos.y - windowPos.y - (height*displayPresets.binImageScale/2.f)));
@ -239,6 +227,7 @@ private:
ImGui::SetCursorPos(ImVec2(percentPos.x - windowPos.x - (widthP*displayPresets.binImageScale/2.f), percentPos.y - windowPos.y - (heightP*displayPresets.binImageScale/2.f)));
imageDisplay->drawImGuiImage(binPercentPath, displayPresets.binImageScale, ColorValues::lumonBlue);
// Draw percentage bar and text
ImVec2 trCorner = ImVec2(percentPos.x - (widthP*displayPresets.binImageScale/2.f), percentPos.y - (heightP*displayPresets.binImageScale/2.f));
ImVec2 brCorner = ImVec2(percentPos.x + (widthP*displayPresets.binImageScale/2.f), percentPos.y + (heightP*displayPresets.binImageScale/2.f));
@ -249,9 +238,8 @@ private:
drawList->AddRectFilled(trCorner, ImVec2(trCorner.x + ((brCorner.x - trCorner.x)* percentD), brCorner.y), ImColor(ColorValues::lumonBlue.Value.x, ColorValues::lumonBlue.Value.y, ColorValues::lumonBlue.Value.z, 0.3f));
// Bin open
if (numberRefiningToBin && *numberRefiningToBin == b.id - 1)
{
// Animate bin open
if (numberRefiningToBin && *numberRefiningToBin == b.id - 1) {
std::string binOpenPath = "bins/bin-open.png";
auto [widthO, heightO] = imageDisplay->getImageSize(binOpenPath);
ImGui::SetCursorPos(ImVec2(pos.x - windowPos.x - (widthO*displayPresets.binImageScale/2.f), pos.y - windowPos.y - (heightO*displayPresets.binImageScale/2.f) - (height*displayPresets.binImageScale)));
@ -268,6 +256,7 @@ private:
drawList->AddRect(headerBoxMin, headerBoxMax, ColorValues::lumonBlue);
ImVec2 headerTextPos = ImVec2(headerBoxMin.x + 25.f, (headerBoxMin.y+headerBoxMax.y)/2.f - displayPresets.fontSize/2.f);
drawList->AddText(font, displayPresets.fontSize, headerTextPos, ColorValues::lumonBlue, "@andrewchilicki");
// Lumon logo
std::string logoPath = "lumon-logo.png";
auto [widthH, heightH] = imageDisplay->getImageSize(logoPath);
@ -275,8 +264,7 @@ private:
imageDisplay->drawImGuiImage(logoPath, displayPresets.headerImageScale, ColorValues::lumonBlue);
// Horizontal lines
auto drawLine = [&](const float y)
{
auto drawLine = [&](const float y) {
drawList->AddLine(ImVec2(windowPos.x, y), ImVec2(windowPos.x + windowSize.x, y), ColorValues::lumonBlue, displayPresets.lineThickness);
};
@ -294,40 +282,33 @@ private:
static bool viewportInit = false;
bool viewportChanged = !viewportInit;
// Handle arrow key input
if (ImGui::IsKeyPressed(ImGuiKey_LeftArrow))
{
if (ImGui::IsKeyPressed(ImGuiKey_LeftArrow)) {
panelOffset.x += controlSettings.arrowSensitivity;
viewportChanged = true;
} else if (ImGui::IsKeyPressed(ImGuiKey_RightArrow))
{
} else if (ImGui::IsKeyPressed(ImGuiKey_RightArrow)) {
panelOffset.x -= controlSettings.arrowSensitivity;
viewportChanged = true;
}
if (ImGui::IsKeyPressed(ImGuiKey_UpArrow))
{
if (ImGui::IsKeyPressed(ImGuiKey_UpArrow)) {
panelOffset.y += controlSettings.arrowSensitivity;
viewportChanged = true;
} else if (ImGui::IsKeyPressed(ImGuiKey_DownArrow))
{
} else if (ImGui::IsKeyPressed(ImGuiKey_DownArrow)) {
panelOffset.y -= controlSettings.arrowSensitivity;
viewportChanged = true;
}
// Handle zoom
if (ImGui::IsKeyPressed(ImGuiKey_Comma))
{
if (ImGui::IsKeyPressed(ImGuiKey_Comma)) {
panelScale -= controlSettings.zoomSensitivity;
viewportChanged = true;
} else if (ImGui::IsKeyPressed(ImGuiKey_Period))
{
} else if (ImGui::IsKeyPressed(ImGuiKey_Period)) {
panelScale += controlSettings.zoomSensitivity;
viewportChanged = true;
}
// panelScale = std::clamp(panelScale, 0.8f, 1.8f);
panelScale = std::clamp(panelScale, displaySettings.minZoomScale, displaySettings.maxZoomScale);
if (viewportChanged)
{
if (viewportChanged) {
// Clamp movement to within grid boundaries
float gridWidthScaled = gridSize * displaySettings.gridSpacing * panelScale;
float gridHeightScaled = gridSize * displaySettings.gridSpacing * panelScale;
@ -337,8 +318,7 @@ private:
float minOffsetY = -gridHeightScaled + windowSize.y - displayPresets.numberWindowBufferTop;
float maxOffsetY = displayPresets.numberWindowBufferTop;
if (!viewportInit)
{
if (!viewportInit) {
// Start at center of grid
panelOffset.x = (windowSize.x - gridWidthScaled) / 2.0f / panelScale;
panelOffset.y = (windowSize.y - gridHeightScaled) / 2.0f / panelScale;
@ -355,8 +335,7 @@ private:
void drawSettings() final
{
ImGui::SetWindowFontScale(displayPresets.settingsFontScale);
if (ImGui::Button("Save Settings"))
{
if (ImGui::Button("Save Settings")) {
saveSettings(Settings{displaySettings, controlSettings}, settingsSavePath);
}
ImGui::Separator();
@ -366,6 +345,9 @@ private:
ImGui::InputFloat("Numbers Grid Spacing", &displaySettings.gridSpacing);
ImGui::InputFloat("Mouse Scale Radius", &displaySettings.mouseScaleRadius);
ImGui::InputFloat("Mouse Scale Multiplier", &displaySettings.mouseScaleMultiplier);
ImGui::InputFloat("Min Scale Multiplier", &displaySettings.minZoomScale);
ImGui::InputFloat("Max Scale Multiplier", &displaySettings.maxZoomScale);
ImGui::InputFloat("Refined to Bin Speed", &displaySettings.refinedToBinSpeed);
ImGui::Text("Noise:");
ImGui::InputFloat("Noise Speed", &displaySettings.noiseSpeed);
ImGui::InputFloat("Noise Scale", &displaySettings.noiseScale);
@ -380,11 +362,12 @@ private:
bool updateDisplaySettings(PresetDisplaySettings &settings, float globalScale)
{
// Want preset display settings to scale proportionally to the window size
auto viewportSize = ImGui::GetMainViewport()->Size;
if (lastViewportSize.x == viewportSize.x && lastViewportSize.y == viewportSize.y && lastGlobalScale == globalScale)
{
if (lastViewportSize.x == viewportSize.x && lastViewportSize.y == viewportSize.y && lastGlobalScale == globalScale) {
return false;
}
float displaySizeScalePrev = lastViewportSize.x/1280.f * lastGlobalScale;
float displaySizeScale = viewportSize.x/1280.f * globalScale;
float newScale = displaySizeScale / displaySizeScalePrev;
@ -415,8 +398,7 @@ private:
float distY = mousePos.y - globalNumberPos.y;
float distance = sqrt(distX * distX + distY * distY);
if (distance < displaySettings.mouseScaleRadius)
{
if (distance < displaySettings.mouseScaleRadius) {
return 1.0f + (displaySettings.mouseScaleRadius - distance) / displaySettings.mouseScaleRadius * displaySettings.mouseScaleMultiplier;
}
return 1.0f;
@ -443,6 +425,7 @@ private:
// Debug options
bool revealMap = false;
// TODO - Move to class
struct Bin
{
int id;
@ -451,8 +434,7 @@ private:
int badGroupsRefined = 0;
int maxBadGroups = 0;
ImVec2 updatePos(const ImVec2 &windowSize, const ImVec2 &windowPos, float offsetY)
{
ImVec2 updatePos(const ImVec2 &windowSize, const ImVec2 &windowPos, float offsetY) {
pos = ImVec2(windowPos.x + (windowSize.x / 6)*id, windowPos.y + windowSize.y - offsetY);
return pos;
}

View File

@ -6,14 +6,13 @@ class ImageDisplay;
class NumbersPanel {
public:
virtual void init() = 0;
virtual void update() = 0;
virtual void drawNumbersPanel() = 0;
virtual void drawSettings() = 0;
virtual void triggerLoadAnimation() = 0;
virtual void drawSettings() = 0;
virtual ~NumbersPanel() = default;
};

View File

@ -7,6 +7,7 @@
struct PresetDisplaySettings
{
// Preset sizing and offsets for UI
float numberWindowBufferTop = 125.f;
float numberWindowBufferBottom = 115.f;
@ -57,8 +58,7 @@ inline void saveSettingsJson(const nlohmann::json& settingsJson, const std::stri
file.flush();
file.close();
std::cout << "Settings saved to disk." << std::endl;
}
catch (const std::exception& e) {
} catch (const std::exception& e) {
std::cerr << "Error saving settings: " << e.what() << std::endl;
}
}
@ -72,20 +72,27 @@ struct DisplaySettings
float mouseScaleRadius = 100.f;
float mouseScaleMultiplier = 2.f;
float maxZoomScale = 0.8f;
float minZoomScale = 0.2f;
float noiseSpeed = 0.004f;
float noiseScale = 1.f;
float noiseScaleOffset = 15;
float refinedToBinSpeed = 3.0f;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(DisplaySettings,
globalScale,
imageScale,
gridSpacing,
mouseScaleRadius,
mouseScaleMultiplier,
maxZoomScale,
minZoomScale,
noiseSpeed,
noiseScale,
noiseScaleOffset
noiseScaleOffset,
refinedToBinSpeed
);
};
@ -107,26 +114,21 @@ struct Settings
inline std::optional<Settings> loadSettings(const std::string& jsonPath)
{
try
{
if (auto json = loadSettingsFromJson(jsonPath))
{
try {
if (auto json = loadSettingsFromJson(jsonPath)) {
return json->get<Settings>();
}
} catch (const std::exception& e)
{
} catch (const std::exception& e) {
std::cerr << "Error loading settings: " << e.what() << std::endl;
}
return std::nullopt;
}
inline void saveSettings(const Settings& settings, const std::string& jsonPath)
{
try
{
try {
nlohmann::json json = settings;
saveSettingsJson(json, jsonPath);
} catch (const std::exception& e)
{
} catch (const std::exception& e) {
std::cerr << "Error saving settings: " << e.what() << std::endl;
}
}

View File

@ -1,11 +1,11 @@
#include "UI/UIManager.h"
#include "imgui.h"
#include "backends/imgui_impl_glfw.h"
#include <GLFW/glfw3.h>
#include <imgui_impl_opengl3.h>
#include <iostream>
#include "UI/UIManager.h"
void glfw_error_callback(int error, const char* description) {
std::cerr << "GLFW Error (" << error << "): " << description << std::endl;
}