From 84c30d32a111658507b7eddedbea1ca2e7b9a36a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=BD=20=D0=94=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=BB=D0=B0=20=D0=9C=D0=B8=D1=85=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=D0=B8=D1=87?= <dmpechenin@edu.hse.ru> Date: Tue, 4 Mar 2025 18:58:19 +0300 Subject: [PATCH] All buttons in SelectState work. They close app. --- source/BasicAbstractions/Command.h | 4 +- source/States/ChangeStateCommand.h | 16 ++++++++ source/States/ExitState/ExitState.h | 9 +---- source/States/SelectState/SelectState.cpp | 49 ++++++++++++++--------- source/States/SelectState/SelectState.h | 8 ++-- 5 files changed, 55 insertions(+), 31 deletions(-) create mode 100644 source/States/ChangeStateCommand.h diff --git a/source/BasicAbstractions/Command.h b/source/BasicAbstractions/Command.h index b0082eb..9ec6a7b 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 0000000..d95f687 --- /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 26508f0..22ce415 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 d849f72..7692049 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 1c79328..063d351 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; -- GitLab