Implement button classification

This commit is contained in:
NaiJi ✨ 2021-08-24 22:03:58 +03:00
parent 5540361f94
commit be0367bba0
12 changed files with 268 additions and 110 deletions

View File

@ -1,42 +1,12 @@
#include "button.h" #include "button.h"
Button::Button(const std::string &text) : Button::Button(const std::string &text)
_pressed(false)
{ {
setText(text); setText(text);
_button_text.setFillColor(sf::Color::Black); _button_text.setFillColor(sf::Color::Black);
_button_content.setFillColor(sf::Color::White); _button_content.setFillColor(sf::Color::White);
} }
void Button::input(const sf::Event& event)
{
switch (event.type)
{
default:
break;
case sf::Event::MouseButtonPressed:
if (isUnderMouse(event.mouseButton.x, event.mouseButton.y))
{
_pressed = true;
_button_content.setFillColor(sf::Color(155, 155, 155));
}
break;
case sf::Event::MouseButtonReleased:
if (_pressed)
{
_button_content.setFillColor(sf::Color::White);
_pressed = false;
if (isUnderMouse(event.mouseButton.x, event.mouseButton.y))
_on_click_callback();
}
break;
}
Widget::input(event);
}
void Button::update() void Button::update()
{ {
Widget::update(); Widget::update();
@ -63,7 +33,7 @@ void Button::setPosition(const sf::Vector2f &position)
bool Button::isUnderMouse(int mouse_x, int mouse_y) const bool Button::isUnderMouse(int mouse_x, int mouse_y) const
{ {
return _button_content.getGlobalBounds().contains(mouse_x, mouse_y); return _is_visible && _button_content.getGlobalBounds().contains(mouse_x, mouse_y);
} }
void Button::setFillColor(sf::Color&& color) void Button::setFillColor(sf::Color&& color)
@ -75,9 +45,3 @@ void Button::setText(const std::string& text)
{ {
_button_text.setString(text); _button_text.setString(text);
} }
void Button::setCallback(std::function<void(void)> callback)
{
_on_click_callback = callback;
}

View File

@ -8,24 +8,20 @@
class Button : public Widget class Button : public Widget
{ {
public: public:
Button(const std::string& text); explicit Button(const std::string& text);
virtual void input(const sf::Event& event) override; virtual void input(const sf::Event& event) override = 0;
virtual void update() override; virtual void update() override final;
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override final;
virtual void setRect(const sf::FloatRect& rect) override; virtual void setRect(const sf::FloatRect& rect) override final;
virtual void setPosition(const sf::Vector2f& position) override; virtual void setPosition(const sf::Vector2f& position) override final;
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override; virtual bool isUnderMouse(int mouse_x, int mouse_y) const override final;
void setFillColor(sf::Color&& color); virtual void setFillColor(sf::Color&& color);
void setText(const std::string& text); virtual void setText(const std::string& text);
void setCallback(std::function<void(void)> callback);
private: protected:
sf::RectangleShape _button_content; sf::RectangleShape _button_content;
sf::Text _button_text; sf::Text _button_text;
bool _pressed;
std::function<void(void)> _on_click_callback;
}; };

View File

@ -0,0 +1,35 @@
#include "cascademenubutton.h"
#include "menudrop.h"
CascadeMenuButton::CascadeMenuButton(const std::string& text) :
Button(text)
{}
void CascadeMenuButton::input(const sf::Event& event)
{
Button::input(event);
switch (event.type)
{
default:
break;
case sf::Event::MouseMoved:
if (isUnderMouse(event.mouseButton.x, event.mouseButton.y))
{
_button_content.setFillColor(sf::Color(84, 158, 253));
_submenu->lock();
}
else
{
_button_content.setFillColor(sf::Color::White);
_submenu->unlock();
}
break;
}
}
void CascadeMenuButton::setSubmenu(const std::shared_ptr<MenuDrop>& submenu)
{
_submenu = submenu;
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "button.h"
class MenuDrop;
class CascadeMenuButton : public Button
{
public:
explicit CascadeMenuButton(const std::string& text);
virtual void input(const sf::Event& event) override final;
void setSubmenu(const std::shared_ptr<MenuDrop>& submenu);
private:
std::shared_ptr<MenuDrop> _submenu;
};

View File

@ -1,22 +0,0 @@
#pragma once
#include "widget.h"
#include <SFML/Graphics/RectangleShape.hpp>
class MenuButton : public Widget
{
public:
explicit MenuButton(std::string&& text);
virtual void input(const sf::Event& event) = 0;
virtual void update() = 0;
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const = 0;
virtual void setRect(const sf::FloatRect& rect) = 0;
virtual void setPosition(const sf::Vector2f& position) = 0;
virtual bool isUnderMouse(int mouse_x, int mouse_y) const = 0;
virtual bool isActive() const = 0;
virtual void setActive(bool is_active) = 0;
virtual void setHovered(bool is_hovered) = 0;
};

View File

@ -1,53 +1,98 @@
#include "menudrop.h" #include "menudrop.h"
#include "menuseparator.h"
void MenuDrop::input(const sf::Event &event) MenuDrop::MenuDrop() :
{ _is_locked(false),
for (auto& child : _children) _button_height(27),
child->input(event); _button_index(0)
} {}
void MenuDrop::update() void MenuDrop::input(const sf::Event& event)
{
for (auto& child : _children)
child->update();
}
void MenuDrop::draw(sf::RenderTarget& target, sf::RenderStates states) const
{ {
if (!_is_visible) if (!_is_visible)
return; return;
for (auto& child : _children) switch (event.type)
child->draw(target, states); {
default:
break;
case sf::Event::MouseMoved:
if (isUnderMouse(event.mouseButton.x, event.mouseButton.y))
{
Widget::input(event);
}
else
{
if (!isLocked())
setVisibility(false);
}
break;
}
}
void MenuDrop::update()
{
Widget::update();
}
void MenuDrop::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
target.draw(_content_rect);
Widget::draw(target, states);
} }
void MenuDrop::setRect(const sf::FloatRect& rect) void MenuDrop::setRect(const sf::FloatRect& rect)
{ {
(void)rect; _content_rect.setPosition(rect.left, rect.top);
/*_bar_rect.setPosition(rect.left, rect.top); _content_rect.setSize({rect.width, rect.height});
_bar_rect.setSize({rect.width, rect.height});
_bar_button_rect.setSize(sf::Vector2f(100, _bar_rect.getSize().y));*/
} }
void MenuDrop::setPosition(const sf::Vector2f& position) void MenuDrop::setPosition(const sf::Vector2f& position)
{ {
(void)position; _content_rect.setPosition(position);
//_bar_rect.setPosition(position);
} }
bool MenuDrop::isUnderMouse(int mouse_x, int mouse_y) const bool MenuDrop::isUnderMouse(int mouse_x, int mouse_y) const
{ {
(void)mouse_x; return _is_visible && _content_rect.getGlobalBounds().contains(mouse_x, mouse_y);
(void)mouse_y;
return false;//_bar_rect.getGlobalBounds().contains(mouse_x, mouse_y);
} }
void MenuDrop::trigger() void MenuDrop::addButton(const std::shared_ptr<Button>& button)
{ {
bool new_visibility = !_is_visible; add(button);
setVisibility(new_visibility);
for (const auto& child : _children)
child->setVisibility(new_visibility);
} }
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);
}
void MenuDrop::lock()
{
_is_locked = true;
}
void MenuDrop::unlock()
{
_is_locked = false;
}
bool MenuDrop::isLocked() const
{
return _is_locked;
}

View File

@ -1,13 +1,14 @@
#pragma once #pragma once
#include "widget.h" #include "widget.h"
#include "menubutton.h" #include "button.h"
#include <SFML/Graphics/RectangleShape.hpp> #include <SFML/Graphics/RectangleShape.hpp>
class MenuDrop : public Widget class MenuDrop : public Widget
{ {
public: public:
explicit MenuDrop();
virtual void input(const sf::Event& event) override; virtual void input(const sf::Event& event) override;
virtual void update() override; virtual void update() override;
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
@ -15,12 +16,19 @@ public:
virtual void setPosition(const sf::Vector2f& position) override; virtual void setPosition(const sf::Vector2f& position) override;
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override; virtual bool isUnderMouse(int mouse_x, int mouse_y) const override;
void trigger(); void addButton(const std::shared_ptr<Button>& button);
void addSeparator();
void lock();
void unlock();
bool isLocked() const;
private: private:
sf::RectangleShape _content_rect; sf::RectangleShape _content_rect;
sf::RectangleShape _bar_button_rect; bool _is_locked;
sf::RectangleShape _drop_rect; std::size_t _button_height;
sf::RectangleShape _drop_button_rect; std::size_t _button_index;
void add(const std::shared_ptr<Widget>& widget);
}; };

View File

@ -0,0 +1,34 @@
#include "menuseparator.h"
void MenuSeparator::input(const sf::Event& event)
{
Widget::input(event);
}
void MenuSeparator::update()
{
Widget::update();
}
void MenuSeparator::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
target.draw(_line, states);
}
void MenuSeparator::setRect(const sf::FloatRect& rect)
{
_rect = rect;
//_line
}
void MenuSeparator::setPosition(const sf::Vector2f& position)
{
(void)position;
}
bool MenuSeparator::isUnderMouse(int mouse_x, int mouse_y) const
{
return _is_visible && _rect.contains(mouse_x, mouse_y);
}

View File

@ -0,0 +1,21 @@
#pragma once
#include "widget.h"
#include <SFML/Graphics/VertexArray.hpp>
class MenuSeparator : public Widget
{
public:
virtual void input(const sf::Event& event) override;
virtual void update() override;
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
virtual void setRect(const sf::FloatRect& rect) override;
virtual void setPosition(const sf::Vector2f& position) override;
virtual bool isUnderMouse(int mouse_x, int mouse_y) const override;
private:
sf::VertexArray _line;
sf::FloatRect _rect;
};

View File

@ -0,0 +1,40 @@
#include "pushbutton.h"
PushButton::PushButton(const std::string& text) :
Button(text),
_pressed(false)
{}
void PushButton::input(const sf::Event& event)
{
Button::input(event);
switch (event.type)
{
default:
break;
case sf::Event::MouseButtonPressed:
if (isUnderMouse(event.mouseButton.x, event.mouseButton.y))
{
_pressed = true;
_button_content.setFillColor(sf::Color(155, 155, 155));
}
break;
case sf::Event::MouseButtonReleased:
if (_pressed)
{
_button_content.setFillColor(sf::Color::White);
_pressed = false;
if (isUnderMouse(event.mouseButton.x, event.mouseButton.y))
_on_click_callback();
}
break;
}
}
void PushButton::setCallback(std::function<void(void)> callback)
{
_on_click_callback = callback;
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "button.h"
class PushButton : public Button
{
public:
explicit PushButton(const std::string& text);
virtual void input(const sf::Event& event) override final;
void setCallback(std::function<void(void)> callback);
private:
bool _pressed;
std::function<void(void)> _on_click_callback;
};

View File

@ -24,6 +24,8 @@ void Widget::draw(sf::RenderTarget& target, sf::RenderStates states) const
void Widget::setVisibility(bool is_visible) void Widget::setVisibility(bool is_visible)
{ {
_is_visible = is_visible; _is_visible = is_visible;
for (auto& child : _children)
child->setVisibility(false);
} }
void Widget::addChild(const std::shared_ptr<Widget> &child) void Widget::addChild(const std::shared_ptr<Widget> &child)