Button click logic with SFML I wrote some functionality that works as intended in order to create functional clickable rectangles. I inherit from RectangleShape in SFML and I have several objects (not just buttons) that inherit from this. The intended logic is to check if a downpress and release pair both happen inside of the same object.

clickableRect.h

#ifndef CLICKABLERECT
#define CLICKABLERECT

#include &lt;SFML\Graphics.hpp&gt;

class clickableRect : public sf::RectangleShape
{
public:
    clickableRect();

    bool click(const sf::RenderWindow &amp; window, const sf::Event &amp; ev);

    void reset();
private:
    bool m_mouseHeld;
    bool m_pressed;
    bool m_active;

    bool isInside(const sf::RenderWindow &amp; window) const;
};
#endif // !CLICKABLERECT


and

clickableRect.cpp

#include "clickableRect.h"

clickableRect::clickableRect() :
    m_pressed(false),
    m_mouseHeld(false),
    m_active(false)
{
     //do nothing
}

bool clickableRect::click(const sf::RenderWindow &amp; window, const sf::Event &amp; ev)
{
    if (ev.type == sf::Event::MouseButtonPressed &amp;&amp; isInside(window) &amp;&amp; !m_mouseHeld)
    {
        m_pressed = true;
        m_mouseHeld = true;
    }
    else if (ev.type == sf::Event::MouseButtonPressed)
    {
        m_mouseHeld = true;
    }

    if (ev.type == sf::Event::MouseButtonReleased)
    {
        if (isInside(window) &amp;&amp; m_pressed)
        {
            m_active = true;
        }
        m_pressed = false;
        m_mouseHeld = false;
    }

    return m_active;
}

void clickableRect::reset()
{
    m_active = false;
}

bool clickableRect::isInside(const sf::RenderWindow &amp; window) const
{
    return sf::Mouse::getPosition(window).x &gt; getPosition().x
        &amp;&amp; sf::Mouse::getPosition(window).x &lt; getPosition().x + getSize().x
        &amp;&amp; sf::Mouse::getPosition(window).y &gt; getPosition().y
        &amp;&amp; sf::Mouse::getPosition(window).y &lt; getPosition().y + getSize().y;
}


I would love any and all feedback on all aspects of the code provided but request specifically to know about:


Is this a good use of inheritance and am I doing it right? Should I use a component pattern instead?
Can I clean up the logic itself inside the click function. It seems a bit messy to me and also requires me to call reset on the objects immediately after returning a true value.
Compile with all warnings  


If you compile this code with all warnings enabled (e.g. -Wall -Wextra -pedantic) the compiler will tell you that your initialization is out of order.
This simply means you initialize your members in a different order than they have been declared in. In your example this is not bad but if you have members that depend on others being initialized before them this can lead to problems.


&amp; is part of the type in C++


While this is not an error it can look like bitwise AND at a glance and be a potential source of confusion. Prefer to write foo&amp; bar instead of foo &amp; bar.


User defined types


Also just a minor nitpick but usually user defined types start with an uppercase letter i.e. ClickableRect.
Since you inherit from Shape I think it would make more sense to name your class ClickableShape but this is just personal preference.


Design


You expose window to your class only to get access to the mouse coordinates. Unless you plan to use window in a different matter in the future it'd be better to hide this info from your class.
A simple approach to testing for a click within your shape could be:

class ClickableShape : public sf::RectangleShape {
public:
    bool click(const sf::Vector2i&amp; mouse_pos) const {
        return getGlobalBounds().contains(mouse_pos.x, mouse_pos.y);
    }
};


Which can then be called as:

ClickableShape cs{};
cs.setSize(sf::Vector2f(50, 50));
cs.setFillColor(sf::Color(0xffffffff));


And finally in your event loop:

case sf::Event::MouseButtonPressed:
    cs.click(sf::Mouse::getPosition(window));
    break;


This way you avoid exposing unnecessary data to your class and can still check if the shape was clicked.

Approach #2:

I'm not sure what you're planning to do with this in the future but another approach to this would be to keep the inheritance short and have the rectangle as a member.

class MyButton : public sf::Drawable {
public:
    MyButton() {
        shape.setSize(sf::Vector2f(50, 50));
        shape.setFillColor(sf::Color(0xffffffff));
    }

    bool click(const sf::Event&amp; event) const {
        return shape.getGlobalBounds().contains(event.mouseButton.x, event.mouseButton.y);
    }

    void draw(sf::RenderTarget&amp; target, sf::RenderStates states) const {
        target.draw(shape);
    }

private:
    sf::RectangleShape shape;
};