#include "menudrop.h" #include "menuseparator.h" MenuDrop::MenuDrop() : _is_locked(false), _button_height(27), _button_index(0) { _is_visible = false; _content_rect.setFillColor(sf::Color(200, 200, 200)); } void MenuDrop::input(const sf::Event& event) { if (!_is_visible) return; Widget::input(event); switch (event.type) { default: break; case sf::Event::MouseButtonReleased: if (isUnderMouse(event.mouseButton.x, event.mouseButton.y)) { setVisibility(false); for (auto& submenu : _submenus) { submenu->unlock(); submenu->setVisibility(false); } } break; case sf::Event::MouseMoved: if (!isUnderMouse(event.mouseMove.x, event.mouseMove.y)) { if (!isLocked() && !hasActiveSubmenus()) setVisibility(false); } break; } } bool MenuDrop::hasActiveSubmenus() const { return std::any_of(_submenus.begin(), _submenus.end(), [](const auto& submenu) -> bool { return submenu->_is_visible; }); } void MenuDrop::update(const sf::Time& dt) { Widget::update(dt); } void MenuDrop::draw(sf::RenderTarget& target, sf::RenderStates states) const { if (_is_visible) target.draw(_content_rect); Widget::draw(target, states); } void MenuDrop::setRect(const sf::FloatRect& rect) { _content_rect.setPosition(rect.left, rect.top); _content_rect.setSize({rect.width, rect.height}); } void MenuDrop::setPosition(const sf::Vector2f& position) { _content_rect.setPosition(position); } void MenuDrop::move(const sf::Vector2f& delta) { _content_rect.move(delta); Widget::move(delta); for (auto& submenu : _submenus) submenu->move(delta); } bool MenuDrop::isUnderMouse(int mouse_x, int mouse_y) const { return _is_visible && _content_rect.getGlobalBounds().contains(mouse_x, mouse_y); } void MenuDrop::setVisibility(bool is_visible) { Widget::setVisibility(is_visible); if (!is_visible) _is_locked = false; } void MenuDrop::addPushButton(const std::shared_ptr& button) { add(button); } void MenuDrop::addCascadeButton(const std::shared_ptr& button) { auto& submenu = button->submenu(); _submenus.emplace_back(submenu); add(button); submenu->setParent(_parent); } void MenuDrop::addSeparator() { add(std::make_shared()); } void MenuDrop::add(const std::shared_ptr &widget) { const auto& parent_size = _content_rect.getSize(); const auto& parent_position = _content_rect.getPosition(); widget->setRect(sf::FloatRect(parent_position.x, parent_position.y + (_button_height * _button_index), parent_size.x, _button_height)); addChild(widget); ++_button_index; } void MenuDrop::lock() { _is_locked = true; } void MenuDrop::unlock() { _is_locked = false; } bool MenuDrop::isLocked() const { return _is_locked; } sf::FloatRect MenuDrop::rect() const { return _content_rect.getGlobalBounds(); } sf::Vector2f MenuDrop::position() const { return _content_rect.getPosition(); }