diff --git a/CMakeLists.txt b/CMakeLists.txt index 333ee3b..77d5bf7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,11 +8,11 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if(WIN32) - set(IMGUI_BACKEND "imgui_impl_dx11.cpp") # DirectX 11 for Windows + set(IMGUI_BACKEND "imgui_impl_dx11.cpp") # DirectX 11 for Windows elseif(APPLE) - set(IMGUI_BACKEND "imgui_impl_metal.mm") # Metal for macOS + set(IMGUI_BACKEND "imgui_impl_metal.mm") # Metal for macOS elseif(UNIX) - set(IMGUI_BACKEND "imgui_impl_opengl3.cpp") # OpenGL for Linux + set(IMGUI_BACKEND "imgui_impl_opengl3.cpp") # OpenGL for Linux endif() # includes @@ -21,25 +21,25 @@ include_directories(./includes) # raylib include(FetchContent) FetchContent_Declare( - raylib - GIT_REPOSITORY https://github.com/raysan5/raylib.git - GIT_TAG 5.5 - GIT_SHALLOW 1 + raylib + GIT_REPOSITORY https://github.com/raysan5/raylib.git + GIT_TAG 5.5 + GIT_SHALLOW 1 ) FetchContent_GetProperties(raylib) if (NOT raylib_POPULATED) - set(FETCHCONTENT_QUIET NO) - FetchContent_Populate(raylib) - set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) - set(BUILD_GAMES OFF CACHE BOOL "" FORCE) - add_subdirectory(${raylib_SOURCE_DIR} ${raylib_BINARY_DIR}) + set(FETCHCONTENT_QUIET NO) + FetchContent_Populate(raylib) + set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) + set(BUILD_GAMES OFF CACHE BOOL "" FORCE) + add_subdirectory(${raylib_SOURCE_DIR} ${raylib_BINARY_DIR}) endif() # imgui FetchContent_Declare( - imgui - GIT_REPOSITORY https://github.com/ocornut/imgui.git - GIT_TAG docking + imgui + GIT_REPOSITORY https://github.com/ocornut/imgui.git + GIT_TAG docking ) FetchContent_MakeAvailable(imgui) @@ -48,9 +48,9 @@ set(imgui_SOURCE_DIR ${CMAKE_BINARY_DIR}/_deps/imgui-src) # rlimgui FetchContent_Declare( - rlImGui - GIT_REPOSITORY https://github.com/raylib-extras/rlImGui.git - GIT_TAG main + rlImGui + GIT_REPOSITORY https://github.com/raylib-extras/rlImGui.git + GIT_TAG main ) FetchContent_MakeAvailable(rlImGui) set(rlImGui_SOURCE_DIR ${CMAKE_BINARY_DIR}/_deps/rlimgui-src) @@ -58,25 +58,26 @@ set(rlImGui_SOURCE_DIR ${CMAKE_BINARY_DIR}/_deps/rlimgui-src) # nlohmann::json FetchContent_Declare( - json - GIT_REPOSITORY https://github.com/nlohmann/json.git - GIT_TAG v3.11.3 + json + GIT_REPOSITORY https://github.com/nlohmann/json.git + GIT_TAG v3.11.3 ) FetchContent_MakeAvailable(json) include_directories(${imgui_SOURCE_DIR} ${rlImGui_SOURCE_DIR}) -set(SRC_CXX_FILES "./src/main.cpp" - "./src/rules.cpp" - "./src/world.cpp" - "./src/render.cpp" +set(SRC_CXX_FILES "./src/main.cpp" + "./src/rules.cpp" + "./src/world.cpp" + "./src/render.cpp" "./src/control_menu.cpp" - "${rlImGui_SOURCE_DIR}/rlImGui.cpp" - "${imgui_SOURCE_DIR}/imgui.cpp" - "${imgui_SOURCE_DIR}/imgui_draw.cpp" - "${imgui_SOURCE_DIR}/imgui_widgets.cpp" - "${imgui_SOURCE_DIR}/imgui_tables.cpp" - "${imgui_SOURCE_DIR}/backends/${IMGUI_BACKEND}" + "./src/settings_menu.cpp" + "${rlImGui_SOURCE_DIR}/rlImGui.cpp" + "${imgui_SOURCE_DIR}/imgui.cpp" + "${imgui_SOURCE_DIR}/imgui_draw.cpp" + "${imgui_SOURCE_DIR}/imgui_widgets.cpp" + "${imgui_SOURCE_DIR}/imgui_tables.cpp" + "${imgui_SOURCE_DIR}/backends/${IMGUI_BACKEND}" ) # Setup the example diff --git a/includes/context.hpp b/includes/context.hpp index c03587c..21fa3db 100644 --- a/includes/context.hpp +++ b/includes/context.hpp @@ -2,7 +2,7 @@ * File name: context.hpp * Author: lejulien * Date created: 01-01-1970 00:59:59 -// Date modified: 12-01-2026 20:31:50 +// Date modified: 12-01-2026 21:30:10 * ------ */ @@ -14,12 +14,16 @@ class World; class Rules; +class Render; namespace gol { +class SettingsMenu; typedef struct ctx { std::shared_ptr world = nullptr; std::shared_ptr rules = nullptr; + std::shared_ptr render = nullptr; + std::shared_ptr settings_menu = nullptr; nlohmann::json config_json; } ctx; diff --git a/includes/control_menu.hpp b/includes/control_menu.hpp index 2aa0c2e..7c20a7d 100644 --- a/includes/control_menu.hpp +++ b/includes/control_menu.hpp @@ -2,12 +2,14 @@ * File name: control_menu.hpp * Author: lejulien * Date created: 10-01-2026 22:00:33 -// Date modified: 10-01-2026 22:45:10 +// Date modified: 12-01-2026 22:18:26 * ------ */ #pragma once +#include + #include #include @@ -15,28 +17,21 @@ namespace gol { class ControlMenu { public: - ControlMenu(ctx context); + ControlMenu(std::shared_ptr context); ~ControlMenu() = default; void update(); void display(); private: - ctx context_; + std::shared_ptr context_; public: // Keep those public for easy access MenuState menu_state_ = MenuState::NONE; - int fps_ctrl_ = false; - int cell_size_ctrl_ = false; bool play_ctrl_ = true; bool step_ctrl_ = false; bool step_back_ctrl_ = false; bool rand_ctrl_ = false; bool edit_ctrl_ = false; bool clear_ctrl_ = false; - bool settings_window_ = false; bool paterns_ctrl_ = false; - int width_ctrl_ = false; - int height_ctrl_ = false; - bool dark_theme_ctrl_ = false; - bool apply_ctrl_ = false; }; } // namespace gol diff --git a/includes/render.hpp b/includes/render.hpp index 60651ab..0714998 100644 --- a/includes/render.hpp +++ b/includes/render.hpp @@ -2,10 +2,12 @@ * File name: render.hpp * Author: lejulien * Date created: 10-01-2026 21:54:12 -// Date modified: 10-01-2026 22:00:37 +// Date modified: 12-01-2026 21:56:03 * ------ */ +#include + #include "world.hpp" #pragma once @@ -16,7 +18,7 @@ public: Render(int cell_size); // Member function - void display(World *world); + void display(std::shared_ptr world); void updateCellSize(int new_size); private: diff --git a/includes/rules.hpp b/includes/rules.hpp index cae4c57..32b120e 100644 --- a/includes/rules.hpp +++ b/includes/rules.hpp @@ -2,7 +2,7 @@ * File name: rules.hpp * Author: lejulien * Date created: 09-01-2026 23:59:55 -* Date modified: 10-01-2026 21:49:44 +// Date modified: 12-01-2026 21:58:17 * ------ */ @@ -19,12 +19,12 @@ private: public: Rules(); - void setup(World *world); - void newWorld(World *world); + void setup(std::shared_ptr world); + void newWorld(std::shared_ptr world); void update(); private: - World *_world; + std::shared_ptr _world; std::vector _buffer; int _width; int _height; diff --git a/includes/settings_menu.hpp b/includes/settings_menu.hpp new file mode 100644 index 0000000..965fade --- /dev/null +++ b/includes/settings_menu.hpp @@ -0,0 +1,46 @@ +/* +* File name: settings_menu.hpp +* Author: lejulien +* Date created: 01-01-1970 00:59:59 +// Date modified: 12-01-2026 22:16:29 +* ------ +*/ + +#pragma once + +#include + +#include + +namespace gol { + +class SettingsMenu { +public: + SettingsMenu(std::shared_ptr context); + ~SettingsMenu() = default; + void update(); + void display(); + bool isOpen(); + void Toogle(); + // Getter/Setters + int getFPS(); + void setFPS(int); + int getCellSize(); + void setCellSize(int); + int getWidth(); + void setWidth(int); + int getHeight(); + void setHeight(int); +private: + std::shared_ptr context_ = nullptr; + int fps_ctrl_ = false; + int cell_size_ctrl_ = false; + bool settings_window_ = false; + int width_ctrl_ = false; + int height_ctrl_ = false; + bool dark_theme_ctrl_ = false; + bool apply_ctrl_ = false; +}; + + +} // namespace gol diff --git a/includes/world.hpp b/includes/world.hpp index 668609d..c61e373 100644 --- a/includes/world.hpp +++ b/includes/world.hpp @@ -2,14 +2,14 @@ * File name: world.hpp * Author: lejulien * Date created: 09-01-2026 23:59:55 -* Date modified: 10-01-2026 21:49:31 +// Date modified: 12-01-2026 22:20:26 * ------ */ #include #include #include -#include +#include #include #include @@ -23,7 +23,7 @@ class World { public: - World(gol::ctx &ctx); + World(std::shared_ptr ctx); ~World(); std::vector *getWorldData(); diff --git a/src/control_menu.cpp b/src/control_menu.cpp index f9aa76b..d91d3ff 100644 --- a/src/control_menu.cpp +++ b/src/control_menu.cpp @@ -2,7 +2,7 @@ * File name: control_menu.cpp * Author: lejulien * Date created: 10-01-2026 22:12:44 -// Date modified: 12-01-2026 20:36:39 +// Date modified: 12-01-2026 22:18:58 * ------ */ @@ -11,26 +11,20 @@ #include #include +#include #include #include namespace gol { -ControlMenu::ControlMenu(ctx context):context_(context) { - fps_ctrl_ = context.config_json["fps"].get(); - cell_size_ctrl_ = context.config_json["cell_size"].get(); +ControlMenu::ControlMenu(std::shared_ptr context):context_(context) { play_ctrl_ = true; step_ctrl_ = false; step_back_ctrl_ = false; rand_ctrl_ = false; edit_ctrl_ = false; clear_ctrl_ = false; - settings_window_ = false; paterns_ctrl_ = false; - width_ctrl_ = context.config_json["screen_width"].get(); - height_ctrl_ = context.config_json["screen_height"].get(); - dark_theme_ctrl_ = context.config_json["dark_theme"].get(); - apply_ctrl_ = false; } void ControlMenu::update() { @@ -40,11 +34,11 @@ void ControlMenu::update() { } } if (rand_ctrl_) { - context_.world->randomize(); + context_->world->randomize(); rand_ctrl_ = false; } if (clear_ctrl_) { - context_.world->clear(); + context_->world->clear(); clear_ctrl_ = false; } if (edit_ctrl_ && play_ctrl_) { @@ -61,12 +55,12 @@ void ControlMenu::update() { menu_state_ = MenuState::EDIT; } if (step_ctrl_) { - context_.world->saveCompressed(); - context_.rules->update(); + context_->world->saveCompressed(); + context_->rules->update(); step_ctrl_ = false; } if (step_back_ctrl_) { - context_.world->stepBack(); + context_->world->stepBack(); step_back_ctrl_ = false; } } @@ -91,10 +85,10 @@ void ControlMenu::display() { if (ImGui::Button((paterns_ctrl_) ? "Hide paterns" : "Show paterns")) { paterns_ctrl_ = !paterns_ctrl_; } - if (ImGui::Button((settings_window_) ? "Hide settings" : "Show settings")) { - settings_window_ = !settings_window_; + if (ImGui::Button((context_->settings_menu->isOpen()) ? "Hide settings" : "Show settings")) { + context_->settings_menu->Toogle(); } - ImGui::Text("Generation: %zu", context_.world->getCycle()); + ImGui::Text("Generation: %zu", context_->world->getCycle()); ImGui::End();} } // namespace gol diff --git a/src/main.cpp b/src/main.cpp index cb95fde..bf07e5b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,7 @@ * File name: main.cpp * Author: lejulien * Date created: 10-01-2026 21:59:32 -// Date modified: 12-01-2026 20:34:37 +// Date modified: 12-01-2026 22:17:54 * ------ */ @@ -22,6 +22,7 @@ #include #include #include +#include Vector2 snapToGrid(Vector2 screen, int cell_size) { return {static_cast(round(screen.x / cell_size) * cell_size), @@ -34,7 +35,7 @@ Vector2i screenToGrid(Vector2 screen, int cell_size) { } int main(int ac, char **av) { - gol::ctx context; + std::shared_ptr context = std::make_shared(); // Load or default config const std::string config_file_name = "config.json"; @@ -56,7 +57,7 @@ int main(int ac, char **av) { // Try reading the configuration try { config_file.seekg(0); - config_file >> context.config_json; + config_file >> context->config_json; } catch (const nlohmann::json::parse_error &e) { std::cerr << "An error occured while loading config : " << e.what() << std::endl; @@ -67,42 +68,43 @@ int main(int ac, char **av) { config_file.close(); // Check config values or populate them - if (!context.config_json.contains("cell_size") || - (context.config_json["cell_size"] < 4 || context.config_json["cell_size"] > 100)) { - context.config_json["cell_size"] = 10; + if (!context->config_json.contains("cell_size") || + (context->config_json["cell_size"] < 4 || context->config_json["cell_size"] > 100)) { + context->config_json["cell_size"] = 10; } - if (!context.config_json.contains("screen_width") || - (context.config_json["screen_width"] < 800 || - context.config_json["screen_width"] > 1920)) { - context.config_json["screen_width"] = 800; + if (!context->config_json.contains("screen_width") || + (context->config_json["screen_width"] < 800 || + context->config_json["screen_width"] > 1920)) { + context->config_json["screen_width"] = 800; } - if (!context.config_json.contains("screen_height") || - (context.config_json["screen_height"] < 600 || - context.config_json["screen_height"] > 1200)) { - context.config_json["screen_height"] = 600; + if (!context->config_json.contains("screen_height") || + (context->config_json["screen_height"] < 600 || + context->config_json["screen_height"] > 1200)) { + context->config_json["screen_height"] = 600; } - if (!context.config_json.contains("dark_theme")) { - context.config_json["dark_theme"] = true; + if (!context->config_json.contains("dark_theme")) { + context->config_json["dark_theme"] = true; } - if (!context.config_json.contains("fps") || - (context.config_json["fps"] < 0 || context.config_json["fps"] > 30)) { - context.config_json["fps"] = 800; + if (!context->config_json.contains("fps") || + (context->config_json["fps"] < 0 || context->config_json["fps"] > 30)) { + context->config_json["fps"] = 800; } - InitWindow(context.config_json["screen_width"], context.config_json["screen_height"], + InitWindow(context->config_json["screen_width"], context->config_json["screen_height"], &av[0][2]); SetTargetFPS(60); - rlImGuiSetup(context.config_json["dark_theme"]); + rlImGuiSetup(context->config_json["dark_theme"]); // Selection window RenderTexture2D selectionTexture = LoadRenderTexture(200, 200); // Initialize objects - context.world = std::make_shared(context); - context.rules = std::make_shared(); - Render render(context.config_json["cell_size"]); + context->world = std::make_shared(context); + context->rules = std::make_shared(); + context->settings_menu = std::make_shared(context); + context->render = std::make_shared(context->settings_menu->getCellSize()); // Imgui control menu gol::ControlMenu control_menu(context); @@ -122,12 +124,12 @@ int main(int ac, char **av) { std::string sel_txt_input_hint("patern name"); // Setups - context.rules->setup(&(*context.world)); + context->rules->setup(context->world); // Diplay generations while (!WindowShouldClose()) { // Frames shinenigans float deltaTime = GetFrameTime(); - sim_speed = control_menu.fps_ctrl_ / 10.0f; + sim_speed = context->settings_menu->getFPS() / 10.0f; timePerUpdate = (1.0f / 10.0f) / sim_speed; control_menu.update(); @@ -137,20 +139,20 @@ int main(int ac, char **av) { if (control_menu.edit_ctrl_ && IsMouseButtonPressed(0) && !ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow)) { control_menu.menu_state_ = MenuState::EDIT; - context.world->setCell(mousePos.x / context.config_json["cell_size"].get(), - mousePos.y / context.config_json["cell_size"].get()); + context->world->setCell(mousePos.x / context->config_json["cell_size"].get(), + mousePos.y / context->config_json["cell_size"].get()); } // Selection behaviour - if (!control_menu.edit_ctrl_ && !control_menu.play_ctrl_ && !control_menu.paterns_ctrl_ && !control_menu.settings_window_) { + if (!control_menu.edit_ctrl_ && !control_menu.play_ctrl_ && !control_menu.paterns_ctrl_ && !context->settings_menu->isOpen()) { if (gesture == GESTURE_TAP && !ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow)) { - sel_pos = snapToGrid(mousePos, control_menu.cell_size_ctrl_); + sel_pos = snapToGrid(mousePos, context->settings_menu->getCellSize()); selecting = true; } - if (ImGui::IsMouseReleased(0) && selecting == true && mousePos.x >=0 && mousePos.x < control_menu.width_ctrl_ && mousePos.y >=0 && mousePos.y < control_menu.height_ctrl_ ) { + if (ImGui::IsMouseReleased(0) && selecting == true && mousePos.x >=0 && mousePos.x < context->settings_menu->getWidth() && mousePos.y >=0 && mousePos.y < context->settings_menu->getHeight() ) { selecting = false; - Vector2i p1 = screenToGrid(sel_pos, control_menu.cell_size_ctrl_); - Vector2i p2 = screenToGrid(mousePos, control_menu.cell_size_ctrl_); + Vector2i p1 = screenToGrid(sel_pos, context->settings_menu->getCellSize()); + Vector2i p2 = screenToGrid(mousePos, context->settings_menu->getCellSize()); // Get origin Vector2i orig = { (p1.x < p2.x)?p1.x:p2.x, @@ -163,7 +165,7 @@ int main(int ac, char **av) { }; // Ensure there is at least one cell selected if (!(sel_size.x == 0 || sel_size.y == 0)) { - sel_data = std::move(context.world->getSelection(orig, sel_size)); + sel_data = std::move(context->world->getSelection(orig, sel_size)); sel_ctrl = true; } } @@ -171,35 +173,7 @@ int main(int ac, char **av) { if (!sel_ctrl) { patern_name[0] = '\0'; } - - if (control_menu.apply_ctrl_) { - bool resize_needed = false; - context.config_json["fps"] = control_menu.fps_ctrl_; - if (context.config_json["screen_width"].get() != control_menu.width_ctrl_ || - context.config_json["screen_height"].get() != control_menu.height_ctrl_) { - context.config_json["screen_width"] = control_menu.width_ctrl_; - context.config_json["screen_height"] = control_menu.height_ctrl_; - rlImGuiShutdown(); - SetWindowSize(control_menu.width_ctrl_, control_menu.height_ctrl_); - rlImGuiSetup(control_menu.dark_theme_ctrl_); - resize_needed = true; - } - if (control_menu.cell_size_ctrl_ != context.config_json["cell_size"].get() || - resize_needed) { - context.world->resize(context.config_json["screen_width"].get() / control_menu.cell_size_ctrl_, - context.config_json["screen_height"].get() / control_menu.cell_size_ctrl_); - render.updateCellSize(control_menu.cell_size_ctrl_); - context.rules->newWorld(&(*context.world)); - context.config_json["cell_size"] = control_menu.cell_size_ctrl_; - } - if (control_menu.dark_theme_ctrl_ != context.config_json["dark_theme"]) { - rlImGuiShutdown(); - rlImGuiSetup(control_menu.dark_theme_ctrl_); - context.config_json["dark_theme"] = control_menu.dark_theme_ctrl_; - } - control_menu.apply_ctrl_ = false; - control_menu.settings_window_ = false; - } + context->settings_menu->update(); // Accumulate time and update simulation at the adjusted speed deltaTimeAccumulator += deltaTime; @@ -208,15 +182,15 @@ int main(int ac, char **av) { // Reset accumulator deltaTimeAccumulator -= timePerUpdate; if (control_menu.menu_state_ == MenuState::PLAY) { - context.world->saveCompressed(); - context.rules->update(); + context->world->saveCompressed(); + context->rules->update(); } } BeginDrawing(); ClearBackground(BLACK); - render.display(&(*context.world)); + context->render->display(context->world); if (selecting) { - auto grid_mouse = snapToGrid(mousePos, control_menu.cell_size_ctrl_); + auto grid_mouse = snapToGrid(mousePos, context->settings_menu->getCellSize()); bool sel_x_less = (sel_pos.x < grid_mouse.x); bool sel_y_less = (sel_pos.y < grid_mouse.y); DrawRectangleLines(((sel_x_less)? sel_pos.x: grid_mouse.x), ((sel_y_less)? sel_pos.y: grid_mouse.y), @@ -235,20 +209,7 @@ int main(int ac, char **av) { ImGui::Button("refresh"); ImGui::End(); } - if (control_menu.settings_window_) { - ImGuiWindowFlags settings_flags = - ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize; - ImGui::Begin("Settings", &control_menu.settings_window_, settings_flags); - ImGui::SliderInt("Window Width", &control_menu.width_ctrl_, 800, 1920); - ImGui::SliderInt("Window Height", &control_menu.height_ctrl_, 600, 1200); - ImGui::SliderInt("FPS", &control_menu.fps_ctrl_, 0, 30); - ImGui::SliderInt("Cell Size", &control_menu.cell_size_ctrl_, 4, 100); - ImGui::Checkbox("Dark Theme", &control_menu.dark_theme_ctrl_); - if (ImGui::Button("Save & Apply")) { - control_menu.apply_ctrl_ = true; - } - ImGui::End(); - } + context->settings_menu->display(); if (sel_ctrl) { BeginTextureMode(selectionTexture); ClearBackground(BLACK); @@ -318,7 +279,7 @@ int main(int ac, char **av) { EndDrawing(); } config_file.open(config_file_name, std::ios::out | std::ios::trunc); - config_file << context.config_json.dump(2); + config_file << context->config_json.dump(2); config_file.close(); // Cleanup Selection texture UnloadRenderTexture(selectionTexture); diff --git a/src/render.cpp b/src/render.cpp index 6f2a9fa..f4c995e 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -2,7 +2,7 @@ * File name: render.cpp * Author: lejulien * Date created: 10-01-2026 21:49:04 -// Date modified: 10-01-2026 21:59:56 +// Date modified: 12-01-2026 21:54:56 * ------ */ @@ -71,7 +71,7 @@ void Render::display_world(std::vector *data, int width, int height) { // Render loop -void Render::display(World *world) { +void Render::display(std::shared_ptr world) { display_world(world->getWorldData(), world->getWidth(), world->getHeight()); } diff --git a/src/rules.cpp b/src/rules.cpp index 55beb2f..5094c00 100644 --- a/src/rules.cpp +++ b/src/rules.cpp @@ -2,7 +2,7 @@ * File name: rules.cpp * Author: lejulien * Date created: 10-01-2026 21:49:14 -// Date modified: 10-01-2026 22:00:16 +// Date modified: 12-01-2026 21:59:00 * ------ */ @@ -67,13 +67,13 @@ void Rules::diag_neighbors(int &neighbors, int i, int j) { // Member function -void Rules::setup(World *world) { +void Rules::setup(std::shared_ptr world) { _world = world; _width = world->getWidth(); _height = world->getHeight(); } -void Rules::newWorld(World *world) { +void Rules::newWorld(std::shared_ptr world) { _world = world; _width = world->getWidth(); _height = world->getHeight(); diff --git a/src/settings_menu.cpp b/src/settings_menu.cpp new file mode 100644 index 0000000..0ce1e54 --- /dev/null +++ b/src/settings_menu.cpp @@ -0,0 +1,122 @@ +/* +* File name: settings_menu.cpp +* Author: lejulien +* Date created: 01-01-1970 00:59:59 +// Date modified: 12-01-2026 22:21:49 +* ------ +*/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace gol { + +SettingsMenu::SettingsMenu(std::shared_ptr context): context_(context) { + fps_ctrl_ = context->config_json["fps"].get(); + cell_size_ctrl_ = context->config_json["cell_size"].get(); + settings_window_ = false; + width_ctrl_ = context->config_json["screen_width"].get(); + height_ctrl_ = context->config_json["screen_height"].get(); + dark_theme_ctrl_ = context->config_json["dark_theme"].get(); + apply_ctrl_ = false; +} + +void SettingsMenu::update() { + if (apply_ctrl_) { + bool resize_needed = false; + context_->config_json["fps"] = fps_ctrl_; + if (context_->config_json["screen_width"].get() != width_ctrl_ || + context_->config_json["screen_height"].get() != height_ctrl_) { + context_->config_json["screen_width"] = width_ctrl_; + context_->config_json["screen_height"] = height_ctrl_; + rlImGuiShutdown(); + SetWindowSize(width_ctrl_, height_ctrl_); + rlImGuiSetup(dark_theme_ctrl_); + resize_needed = true; + } + if (cell_size_ctrl_ != context_->config_json["cell_size"].get() || + resize_needed) { + context_->world->resize(context_->config_json["screen_width"].get() / cell_size_ctrl_, + context_->config_json["screen_height"].get() / cell_size_ctrl_); + context_->render->updateCellSize(cell_size_ctrl_); + context_->rules->newWorld(context_->world); + context_->config_json["cell_size"] = cell_size_ctrl_; + } + if (dark_theme_ctrl_ != context_->config_json["dark_theme"]) { + rlImGuiShutdown(); + rlImGuiSetup(dark_theme_ctrl_); + context_->config_json["dark_theme"] = dark_theme_ctrl_; + } + apply_ctrl_ = false; + settings_window_ = false; + } +} + +void SettingsMenu::display() { + if (settings_window_) { + ImGuiWindowFlags settings_flags = + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize; + ImGui::Begin("Settings", &settings_window_, settings_flags); + ImGui::SliderInt("Window Width", &width_ctrl_, 800, 1920); + ImGui::SliderInt("Window Height", &height_ctrl_, 600, 1200); + ImGui::SliderInt("FPS", &fps_ctrl_, 0, 30); + ImGui::SliderInt("Cell Size", &cell_size_ctrl_, 4, 100); + ImGui::Checkbox("Dark Theme", &dark_theme_ctrl_); + if (ImGui::Button("Save & Apply")) { + apply_ctrl_ = true; + } + ImGui::End(); + } +} + +bool SettingsMenu::isOpen() { + return settings_window_; +} + +void SettingsMenu::Toogle() { + settings_window_ = !settings_window_; +} + +// Getters/Setters +int SettingsMenu::getFPS() { + return fps_ctrl_; +} + +void SettingsMenu::setFPS(int new_fps) { + fps_ctrl_ = new_fps; +} + +int SettingsMenu::getCellSize() { + return cell_size_ctrl_; +} + +void SettingsMenu::setCellSize(int new_cell_size) { + cell_size_ctrl_ = new_cell_size; +} + +int SettingsMenu::getWidth() { + return width_ctrl_; +} + +void SettingsMenu::setWidth(int new_width) { + width_ctrl_ = new_width; +} + +int SettingsMenu::getHeight() { + return height_ctrl_; +} + +void SettingsMenu::setHeight(int new_height) { + height_ctrl_ = new_height; +} + +} // namespace gol diff --git a/src/world.cpp b/src/world.cpp index 3e371e0..ae653ba 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -2,7 +2,7 @@ * File name: world.cpp * Author: lejulien * Date created: 09-01-2026 23:59:55 -// Date modified: 10-01-2026 22:00:23 +// Date modified: 12-01-2026 22:14:46 * ------ */ @@ -12,11 +12,11 @@ // Constructor and destructor -World::World(gol::ctx &context) { - _width = context.config_json["screen_width"].get() / - context.config_json["cell_size"].get(); - _height = context.config_json["screen_height"].get() / - context.config_json["cell_size"].get(); +World::World(std::shared_ptr context) { + _width = context->config_json["screen_width"].get() / + context->config_json["cell_size"].get(); + _height = context->config_json["screen_height"].get() / + context->config_json["cell_size"].get(); // create world data this->_data = new std::vector(_width * _height, false); }