From b5ff44d79373f5cdc7a2ba46b3cda398bfdbc985 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Mon, 11 Aug 2025 19:47:55 +0200 Subject: [PATCH] add (very) basic main menu --- include/td/common/StateMachine.h | 7 ++- include/td/common/StateStack.h | 69 +++++++++++++++++++++++ include/td/display/menu/CreatePartyMenu.h | 15 +++++ include/td/display/menu/JoinPartyMenu.h | 15 +++++ include/td/display/menu/MainMenu.h | 15 +++++ include/td/display/menu/SettingsMenu.h | 15 +++++ include/td/display/state/MainMenuState.h | 14 ++++- src/td/display/Display.cpp | 8 ++- src/td/display/menu/CreatePartyMenu.cpp | 16 ++++++ src/td/display/menu/JoinPartyMenu.cpp | 16 ++++++ src/td/display/menu/MainMenu.cpp | 28 +++++++++ src/td/display/menu/SettingsMenu.cpp | 16 ++++++ src/td/display/state/MainMenuState.cpp | 21 +++++-- src/td/render/renderer/WorldRenderer.cpp | 1 - 14 files changed, 246 insertions(+), 10 deletions(-) create mode 100644 include/td/common/StateStack.h create mode 100644 include/td/display/menu/CreatePartyMenu.h create mode 100644 include/td/display/menu/JoinPartyMenu.h create mode 100644 include/td/display/menu/MainMenu.h create mode 100644 include/td/display/menu/SettingsMenu.h create mode 100644 src/td/display/menu/CreatePartyMenu.cpp create mode 100644 src/td/display/menu/JoinPartyMenu.cpp create mode 100644 src/td/display/menu/MainMenu.cpp create mode 100644 src/td/display/menu/SettingsMenu.cpp diff --git a/include/td/common/StateMachine.h b/include/td/common/StateMachine.h index 6f4f7de..1bf0fb4 100644 --- a/include/td/common/StateMachine.h +++ b/include/td/common/StateMachine.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include namespace td { @@ -15,6 +15,11 @@ class StateMachine { virtual TReturn Update(TArgs... args) = 0; + template + T* ChangeState(Args&&... args) { + return m_StateMachine.template ChangeState(std::forward(args)...); + } + protected: TDerived& m_StateMachine; }; diff --git a/include/td/common/StateStack.h b/include/td/common/StateStack.h new file mode 100644 index 0000000..fe2037d --- /dev/null +++ b/include/td/common/StateStack.h @@ -0,0 +1,69 @@ +#pragma once + +#include +#include +#include + +namespace td { + +template +class StateStack { + public: + class State { + public: + State(TDerived& a_StateStack) : m_StateStack(a_StateStack) {} + virtual ~State() {} + + virtual TReturn Update(TArgs... args) = 0; + + protected: + /** + * \brief Called when enabled (can be used to connect signals) + */ + virtual void OnEnable() {} + + /** + * \brief Called when disabled (can be used to disconnect signals) + */ + virtual void OnDisable() {} + + protected: + TDerived& m_StateStack; + + friend class StateStack; + }; + + StateStack() {} + StateStack(StateStack&&) = default; + virtual ~StateStack() {} + + virtual TReturn Update(TArgs... args) { + assert(!m_States.empty() && "You must push at least one state before updating !"); + return m_States.back()->Update(args...); + } + + void PopState() { + assert(!m_States.empty() && "You must push at least one state before poping !"); + m_States.back()->OnDisable(); + m_States.pop_back(); + if (m_States.empty()) + return; + m_States.back()->OnEnable(); + } + + template + T* PushState(Args&&... args) { + if (!m_States.empty()) + m_States.back()->OnDisable(); + auto newState = std::make_unique(static_cast(*this), std::forward(args)...); + newState->OnEnable(); + m_States.push_back(std::move(newState)); + return static_cast(newState.get()); + } + + private: + std::vector> m_States; +}; + + +} // namespace td diff --git a/include/td/display/menu/CreatePartyMenu.h b/include/td/display/menu/CreatePartyMenu.h new file mode 100644 index 0000000..ebdbf40 --- /dev/null +++ b/include/td/display/menu/CreatePartyMenu.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace td { + +class CreatePartyMenu : public MainMenuState::Menu { + public: + CreatePartyMenu(MainMenuState& a_MainMenu); + ~CreatePartyMenu(); + + virtual void Update() override; +}; + +} // namespace td diff --git a/include/td/display/menu/JoinPartyMenu.h b/include/td/display/menu/JoinPartyMenu.h new file mode 100644 index 0000000..eb594ed --- /dev/null +++ b/include/td/display/menu/JoinPartyMenu.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace td { + +class JoinPartyMenu : public MainMenuState::Menu { + public: + JoinPartyMenu(MainMenuState& a_MainMenu); + ~JoinPartyMenu(); + + virtual void Update() override; +}; + +} // namespace td diff --git a/include/td/display/menu/MainMenu.h b/include/td/display/menu/MainMenu.h new file mode 100644 index 0000000..9c321f6 --- /dev/null +++ b/include/td/display/menu/MainMenu.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace td { + +class MainMenu : public MainMenuState::Menu { + public: + MainMenu(MainMenuState& a_MainMenu); + ~MainMenu(); + + virtual void Update() override; +}; + +} // namespace td diff --git a/include/td/display/menu/SettingsMenu.h b/include/td/display/menu/SettingsMenu.h new file mode 100644 index 0000000..3168013 --- /dev/null +++ b/include/td/display/menu/SettingsMenu.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace td { + +class SettingsMenu : public MainMenuState::Menu { + public: + SettingsMenu(MainMenuState& a_MainMenu); + ~SettingsMenu(); + + virtual void Update() override; +}; + +} // namespace td diff --git a/include/td/display/state/MainMenuState.h b/include/td/display/state/MainMenuState.h index f4b250c..7449b6f 100644 --- a/include/td/display/state/MainMenuState.h +++ b/include/td/display/state/MainMenuState.h @@ -1,15 +1,27 @@ #pragma once +#include #include namespace td { -class MainMenuState : public DisplayState { +class MainMenuState; + +using MainMenuStateStack = StateStack; + +class MainMenuState : public DisplayState, public MainMenuStateStack { public: + using Menu = MainMenuStateStack::State; + MainMenuState(Display& a_Display); ~MainMenuState(); virtual void Update(float a_Delta) override; + + void RenderBackButton(); + + protected: + virtual void OnKeyDown(SDL_Keycode a_Key) override; }; } // namespace td diff --git a/src/td/display/Display.cpp b/src/td/display/Display.cpp index 88499b8..3419f9e 100644 --- a/src/td/display/Display.cpp +++ b/src/td/display/Display.cpp @@ -80,8 +80,7 @@ Display::Display(int a_Width, int a_Height, const std::string& a_Title) : utils::LOG(utils::Format( "GL Context : %i.%i %s, Color : R:%i G:%i B:%i A:%i, Depth bits : %i", major, minor, mask_desc, r, g, b, a, depth)); - utils::LOG(utils::Format( - "MultiSamples : Buffers : %i, Samples : %i", mBuffers, mSamples)); + utils::LOG(utils::Format("MultiSamples : Buffers : %i, Samples : %i", mBuffers, mSamples)); SDL_GL_MakeCurrent(m_Window, m_GLContext); @@ -148,7 +147,7 @@ void Display::PollEvents() { } case SDL_EVENT_KEY_DOWN: { - if(!event.key.repeat) + if (!event.key.repeat) OnKeyDown(event.key.key); break; } @@ -166,6 +165,9 @@ void Display::PollEvents() { void Display::Update(float a_Delta) { StateMachine::Update(a_Delta); +#ifndef NDEBUG + ImGui::ShowDemoWindow(); +#endif ImGui::Render(); ImGuiIO& io = ImGui::GetIO(); glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); diff --git a/src/td/display/menu/CreatePartyMenu.cpp b/src/td/display/menu/CreatePartyMenu.cpp new file mode 100644 index 0000000..f56bb71 --- /dev/null +++ b/src/td/display/menu/CreatePartyMenu.cpp @@ -0,0 +1,16 @@ +#include + +#include + +namespace td { + +CreatePartyMenu::CreatePartyMenu(MainMenuState& a_MainMenu) : MainMenuState::Menu(a_MainMenu) {} + +CreatePartyMenu::~CreatePartyMenu() {} + +void CreatePartyMenu::Update() { + ImGui::Text("CreatePartyMenu"); + m_StateStack.RenderBackButton(); +} + +} // namespace td diff --git a/src/td/display/menu/JoinPartyMenu.cpp b/src/td/display/menu/JoinPartyMenu.cpp new file mode 100644 index 0000000..d415456 --- /dev/null +++ b/src/td/display/menu/JoinPartyMenu.cpp @@ -0,0 +1,16 @@ +#include + +#include + +namespace td { + +JoinPartyMenu::JoinPartyMenu(MainMenuState& a_MainMenu) : MainMenuState::Menu(a_MainMenu) {} + +JoinPartyMenu::~JoinPartyMenu() {} + +void JoinPartyMenu::Update() { + ImGui::Text("JoinPartyMenu"); + m_StateStack.RenderBackButton(); +} + +} // namespace td diff --git a/src/td/display/menu/MainMenu.cpp b/src/td/display/menu/MainMenu.cpp new file mode 100644 index 0000000..30c8724 --- /dev/null +++ b/src/td/display/menu/MainMenu.cpp @@ -0,0 +1,28 @@ +#include + +#include +#include +#include +#include +#include + +namespace td { + +MainMenu::MainMenu(MainMenuState& a_MainMenu) : MainMenuState::Menu(a_MainMenu) {} + +MainMenu::~MainMenu() {} + +void MainMenu::Update() { + if (ImGui::Button("Create Party")) + m_StateStack.PushState(); + if (ImGui::Button("Join Party")) + m_StateStack.PushState(); + if (ImGui::Button("Settings")) + m_StateStack.PushState(); +#ifndef NDEBUG + if (ImGui::Button("Debug world")) + m_StateStack.ChangeState(); +#endif +} + +} // namespace td diff --git a/src/td/display/menu/SettingsMenu.cpp b/src/td/display/menu/SettingsMenu.cpp new file mode 100644 index 0000000..2b15cf1 --- /dev/null +++ b/src/td/display/menu/SettingsMenu.cpp @@ -0,0 +1,16 @@ +#include + +#include + +namespace td { + +SettingsMenu::SettingsMenu(MainMenuState& a_MainMenu) : MainMenuState::Menu(a_MainMenu) {} + +SettingsMenu::~SettingsMenu() {} + +void SettingsMenu::Update() { + ImGui::Text("SettingsMenu"); + m_StateStack.RenderBackButton(); +} + +} // namespace td diff --git a/src/td/display/state/MainMenuState.cpp b/src/td/display/state/MainMenuState.cpp index a71bf6e..b90741c 100644 --- a/src/td/display/state/MainMenuState.cpp +++ b/src/td/display/state/MainMenuState.cpp @@ -1,18 +1,31 @@ #include -#include #include +#include +#include namespace td { -MainMenuState::MainMenuState(Display& a_Display) : DisplayState(a_Display) {} +MainMenuState::MainMenuState(Display& a_Display) : DisplayState(a_Display) { + PushState(); +} + MainMenuState::~MainMenuState() {} void MainMenuState::Update(float a_Delta) { ImGui::Begin("MainWindow"); - if(ImGui::Button("Start debug world")) - m_StateMachine.ChangeState(); + MainMenuStateStack::Update(); ImGui::End(); } +void MainMenuState::RenderBackButton() { + if (ImGui::Button("Back")) + PopState(); +} + +void MainMenuState::OnKeyDown(SDL_Keycode a_Key) { + if (a_Key == SDLK_ESCAPE) + PopState(); +} + } // namespace td diff --git a/src/td/render/renderer/WorldRenderer.cpp b/src/td/render/renderer/WorldRenderer.cpp index 078dc5d..40ede12 100644 --- a/src/td/render/renderer/WorldRenderer.cpp +++ b/src/td/render/renderer/WorldRenderer.cpp @@ -16,7 +16,6 @@ WorldRenderer::~WorldRenderer() {} void WorldRenderer::Render(float a_Lerp) { m_Shader->Start(); Renderer::Render(*m_WorldVao); - ImGui::ShowDemoWindow(); } } // namespace render