Hey everyone,
Creating some classes here and wanted to make sure I was doing my interface stuff in a maintainable way.
I created a TextButton that reacts to mouse overs, clicks, position/scale/rotation can be manipulated, and has a label. I created an interface for each of those 'elements'.
ILabel
IButton
IMouseOver
IMouseLeftClick
GameObject
My TextButton inherits them works perfectly as designed. As I was moving onto creating other elements, such as an ImageButton which will react the same as the TextButton but display an image instead, I wanted to get some feedback to make sure my current interfaces are pretty scale-able..
One note of concern that sticks out to me. In my IMouseOver interface I added a protected member for keeping track of the mousesState. Now I know, typically, interfaces are supposed to be explicit contracts which should only contain methods and not members. I felt having to define that particular member in every single class that inherits it would be super redundant - it's only accessed by the Setter/Getter in the same interface. (Which I also feel is a bit odd to implement those methods in every derived class since their behavior would never alter).
So if anyone could give this a once over and offer up their advice on the way I'm headed, I'd really appreciate it!
Thanks!
ILabel.hpp
#pragma once
#include <string>
class ILabel
{
public:
virtual ~ILabel(void) {};
virtual void SetString(std::string string) =0;
virtual std::string GetString(void) const =0;
};
IButton.hpp
#pragma once
class IButton
{
public:
virtual ~IButton(void) {};
virtual void Enable(void) =0;
virtual void Disable(void) =0;
virtual bool IsEnabled(void) const =0;
};
IMouseOver.hpp
#pragma once
namespace MouseOverState
{
enum MouseOverState
{
None =0,
Begin,
Stay,
End
};
};
class IMouseOver
{
public:
virtual ~IMouseOver(void) {};
virtual bool IsMouseOver(sf::Vector2i mousePosition) =0;
virtual void OnMouseOverBegin(void) =0;
virtual void OnMouseOverStay(void) = 0;
virtual void OnMouseOverEnd(void) =0;
virtual void SetMouseOverState(MouseOverState::MouseOverState mos) { mouseOverState = mos;};
virtual MouseOverState::MouseOverState GetMouseOverState(void) const { return mouseOverState; };
protected:
MouseOverState::MouseOverState mouseOverState;
};
IMouseLeftClick.hpp
#pragma once
class IMouseLeftClick
{
public:
virtual ~IMouseLeftClick(void) {};
virtual void OnMouseLeftClickPressed(void) =0;
virtual void OnMouseLeftClickReleased(void) =0;
virtual void AddLeftClickEvent(boost::function<void()> signal) =0;
};
TextButton.hpp
#pragma once
#include <string>
#include "boost/signals2.hpp"
#include "GameObject.hpp"
#include "ILabel.hpp"
#include "IButton.hpp"
#include "IMouseOver.hpp"
#include "IMouseLeftClick.hpp"
#include "Text.hpp"
#include "Input.hpp"
class TextButton: public GameObject, public virtual ILabel, public virtual IButton, virtual IMouseOver, virtual IMouseLeftClick
{
public:
TextButton(void);
TextButton(std::string fontName, int fontSize, sf::Color idleColor, sf::Color hoverColor, sf::Color pressedColor, sf::Color disabledColor, std::string string);
~TextButton(void);
//TextButton
void HandleInput(Key key, Mouse mouse);
//GameObject
void Update(float gameTime);
void Draw(sf::RenderWindow* window, float gameTime);
void SetPosition(sf::Vector2f);
//ILabel
void SetString(std::string string);
std::string GetString(void) const;
//IButton
void Enable(void);
void Disable(void);
bool IsEnabled(void) const;
sf::FloatRect GetWorldBounds(void) const;
//IMouseOver
bool IsMouseOver(sf::Vector2i mousePosition);
void OnMouseOverBegin(void);
void OnMouseOverStay(void);
void OnMouseOverEnd(void);
//IMouseLeftClick
void OnMouseLeftClickPressed(void);
void OnMouseLeftClickReleased(void);
void AddLeftClickEvent(boost::function<void()> signal);
private:
Text text;
sf::FloatRect bounds;
bool isEnabled;
sf::Color idleColor;
sf::Color hoverColor;
sf::Color pressedColor;
sf::Color disabledColor;
boost::signals2::signal<void ()> leftClickSignals;
};