You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
3.3 KiB
C++

#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<PushButton>& button)
{
add(button);
}
void MenuDrop::addCascadeButton(const std::shared_ptr<CascadeMenuButton>& button)
{
auto& submenu = button->submenu();
_submenus.emplace_back(submenu);
add(button);
submenu->setParent(_parent);
}
void MenuDrop::addSeparator()
{
add(std::make_shared<MenuSeparator>());
}
void MenuDrop::add(const std::shared_ptr<Widget> &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();
}