diff --git a/source/BasicAbstractions/Command.h b/source/BasicAbstractions/Command.h index b0082eb8a8cfbf5f0b51f124a02131df081571f3..9ec6a7be6b77dcc89e69262787aadfb6ee04b03a 100644 --- a/source/BasicAbstractions/Command.h +++ b/source/BasicAbstractions/Command.h @@ -1,6 +1,6 @@ #pragma once struct ISelectCommand { - virtual void execute() = 0; - virtual ~ISelectCommand() = default; + virtual void execute() = 0; + virtual ~ISelectCommand() = default; }; \ No newline at end of file diff --git a/source/States/ChangeStateCommand.h b/source/States/ChangeStateCommand.h new file mode 100644 index 0000000000000000000000000000000000000000..d95f687fdd32ad98460ae34524bd38b7d6bde323 --- /dev/null +++ b/source/States/ChangeStateCommand.h @@ -0,0 +1,16 @@ +#pragma once +#include "../BasicAbstractions/Command.h" +#include "../Application/IState.h" +#include "ExitState/ExitState.h" + +struct ChangeStateCommand : ISelectCommand { + explicit ChangeStateCommand(IStateManager& state_manager) : m_state_manager(state_manager) {} +protected: + IStateManager& m_state_manager; +}; + +struct ExitCommand : ChangeStateCommand { + using ChangeStateCommand::ChangeStateCommand; + void execute() override { m_state_manager.set_next_state(std::make_unique<ExitState>(m_state_manager)); } +}; + diff --git a/source/States/ExitState/ExitState.h b/source/States/ExitState/ExitState.h index 26508f03574852ab17c21c8cc93f3eb0c45de4a0..22ce415cccb9648efc109dcd25aba17605315fcb 100644 --- a/source/States/ExitState/ExitState.h +++ b/source/States/ExitState/ExitState.h @@ -1,12 +1,7 @@ #pragma once -#include <iostream> /// @todo remove it #include "../../Application/IState.h" -#include "../../Application/IWindowKeeper.h" struct ExitState : IState { - explicit ExitState(IStateManager& state_manager) : IState(state_manager) {} - bool do_step() override { - std::cout << "Exiting..." << std::endl; - return false; - } + using IState::IState; + bool do_step() override { return false; } }; \ No newline at end of file diff --git a/source/States/SelectState/SelectState.cpp b/source/States/SelectState/SelectState.cpp index d849f725b89c87bd0853d01065b5426f6fe0646e..769204951bdb95b34daac4530f33382f2ad97b19 100644 --- a/source/States/SelectState/SelectState.cpp +++ b/source/States/SelectState/SelectState.cpp @@ -1,14 +1,9 @@ #include "SelectState.h" -#include "../ExitState/ExitState.h" +#include "../ChangeStateCommand.h" #include "../../Configuration.h" #include "../../BasicAbstractions/Font.h" -void Button::draw_into(sf::RenderWindow& window) const { - window.draw(m_rectangle); - window.draw(m_text); -} - -void Button::set(const sf::Vector2f pos, const sf::Vector2f size, const std::string& text, const size_t font_size) {//, std::shared_ptr<ISelectCommand> ptr_command) { +void Button::set(const sf::Vector2f pos, const sf::Vector2f size, const std::string& text, const size_t font_size, std::unique_ptr<ISelectCommand> ptr_command) { m_rectangle.setSize(size); m_rectangle.setPosition(pos); m_rectangle.setFillColor(config::BUTTON_COLOR_FILL); @@ -25,6 +20,7 @@ void Button::set(const sf::Vector2f pos, const sf::Vector2f size, const std::str round(button_pos.x + (button_size.x - text_bounds.width) / 2 - text_bounds.left), round(button_pos.y + (button_size.y - text_bounds.height) / 2 - text_bounds.top) ); + m_ptr_command = std::move(ptr_command); } void Button::select() { @@ -40,26 +36,41 @@ bool Button::is_position_in(const sf::Vector2f pos) const { && pos.y >= m_rectangle.getPosition().y && pos.y <= (m_rectangle.getPosition().y + m_rectangle.getSize().y); } +void Button::push() const { + m_ptr_command->execute(); +} + +void Button::draw_into(sf::RenderWindow& window) const { + window.draw(m_rectangle); + window.draw(m_text); +} + Menu::Menu(IStateManager& state_manager) { const float pos_left = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.width) - config::BUTTON_SIZE.x) / 2; const float pos_diff = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.height) - config::BUTTON_SIZE.y * 4) / 10; const float pos_top = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.height) - config::BUTTON_SIZE.y*4 - pos_diff*3) / 2; - m_buttons[0].set(sf::Vector2f{pos_left, pos_top}, - config::BUTTON_SIZE, config::BUTTON_TEXT_EASY, config::BUTTON_FONT_SIZE); - m_buttons[1].set(sf::Vector2f{pos_left, pos_top + config::BUTTON_SIZE.y + pos_diff}, - config::BUTTON_SIZE, config::BUTTON_TEXT_MEDIUM, config::BUTTON_FONT_SIZE); - m_buttons[2].set(sf::Vector2f{pos_left, pos_top + 2*(config::BUTTON_SIZE.y + pos_diff)}, - config::BUTTON_SIZE, config::BUTTON_TEXT_HARD, config::BUTTON_FONT_SIZE); - m_buttons[3].set(sf::Vector2f{pos_left, pos_top + 3*(config::BUTTON_SIZE.y + pos_diff)}, - config::BUTTON_SIZE, config::BUTTON_TEXT_EXIT, config::BUTTON_FONT_SIZE); + m_buttons[0].set(sf::Vector2f{pos_left, pos_top}, config::BUTTON_SIZE, config::BUTTON_TEXT_EASY, + config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(state_manager)); + m_buttons[1].set(sf::Vector2f{pos_left, pos_top + config::BUTTON_SIZE.y + pos_diff}, config::BUTTON_SIZE, + config::BUTTON_TEXT_MEDIUM, config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(state_manager)); + m_buttons[2].set(sf::Vector2f{pos_left, pos_top + 2*(config::BUTTON_SIZE.y + pos_diff)}, config::BUTTON_SIZE, + config::BUTTON_TEXT_HARD, config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(state_manager)); + m_buttons[3].set(sf::Vector2f{pos_left, pos_top + 3*(config::BUTTON_SIZE.y + pos_diff)}, config::BUTTON_SIZE, + config::BUTTON_TEXT_EXIT, config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(state_manager)); } -void Menu::process_mouse(const sf::Vector2f pos, bool is_pressed) { +bool Menu::process_mouse(const sf::Vector2f pos, const bool is_pressed) { for (auto& button : m_buttons) { - if (button.is_position_in(pos)) + if (button.is_position_in(pos)) { button.select(); + if (is_pressed) { + button.push(); + return false; + } + } else button.unselect(); } + return true; } void Menu::draw_into(sf::RenderWindow& window) const { @@ -79,7 +90,9 @@ void SelectState::event_handling() { } void SelectState::update() { - m_menu.process_mouse(m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window)), true); + if (!m_menu.process_mouse(m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window)), + sf::Mouse::isButtonPressed(sf::Mouse::Left))) + m_window.close(); } void SelectState::render() { diff --git a/source/States/SelectState/SelectState.h b/source/States/SelectState/SelectState.h index 1c793286c525feb64f88b736b71f9211ee367162..063d351b457110979831466cd74f982435ecda28 100644 --- a/source/States/SelectState/SelectState.h +++ b/source/States/SelectState/SelectState.h @@ -7,22 +7,22 @@ class Button: public IDrawable { public: Button() = default; - void set(sf::Vector2f pos, sf::Vector2f size, const std::string& text, size_t font_size);//, std::shared_ptr<ISelectCommand> ptr_command); + void set(sf::Vector2f pos, sf::Vector2f size, const std::string& text, size_t font_size, std::unique_ptr<ISelectCommand> ptr_command); void select(); void unselect(); bool is_position_in(sf::Vector2f pos) const; - // void push(); + void push() const; void draw_into(sf::RenderWindow& window) const override; private: sf::Text m_text; sf::RectangleShape m_rectangle; - //std::shared_ptr<ISelectCommand> m_ptr_command; /// @todo shared_ptr? + std::unique_ptr<ISelectCommand> m_ptr_command; }; class Menu: public IDrawable { public: explicit Menu(IStateManager& state_manager); - void process_mouse(sf::Vector2f pos, bool is_pressed); + bool process_mouse(sf::Vector2f pos, bool is_pressed); void draw_into(sf::RenderWindow& window) const override; private: std::array<Button, 4> m_buttons;