ClickButton - JayhawkZombie/EECS581Project GitHub Wiki

##Click Button

ClickButton is a UI element that comes with the Engine

This element derives from BaseUIElement

class ClickButton : public BaseUIElement
{
public:
  static std::shared_ptr<ClickButton> Create();

  ClickButton();
  ClickButton(const ClickButton &) = delete;
  ~ClickButton();
  
  virtual void TickUpdate(const double &delta);
  virtual void Render();
  virtual void OnShutDown();

  virtual void SetSize(const sf::Vector2f &size);
  virtual void SetPosition(const sf::Vector2f &Position);
  virtual void Align();

protected:
  virtual void HandleMouseOver(const sf::Vector2i &pos);
  virtual void HandleMouseExit(const sf::Vector2i &pos);
  virtual void HandleMouseMovement(const sf::Vector2i &pos);
  virtual void HandleMousePress(const sf::Vector2i &pos, const sf::Mouse::Button &b);
  virtual void HandleMouseRelease(const sf::Vector2i &pos, const sf::Mouse::Button &b);
  virtual void HandleFocusGained(const sf::Vector2i &pos);
  virtual void HandleFocusLost(const sf::Vector2i &pos);
  virtual void HandleKeyPress(const sf::Keyboard::Key &key);
  virtual void HandleKeyRelease(const sf::Keyboard::Key &key);

  void GetBGTexture(std::shared_ptr<sf::Texture> tex, const std::string &ID);
  void GetHighlightedTexture(std::shared_ptr<sf::Texture> tex, const std::string &ID);
  void GetPressedTexture(std::shared_ptr<sf::Texture> tex, const std::string &ID);
  void GetFont(std::shared_ptr<sf::Font> fnt, const std::string &ID);

  std::shared_ptr<sf::RectangleShape> ButtonShape;
  std::shared_ptr<sf::Texture> ButtonTexture;
  std::shared_ptr<sf::Texture> ButtonHighlightedTexture;
  std::shared_ptr<sf::Texture> ButtonPressedTexture;
  std::shared_ptr<sf::Text> ButtonText;
  std::shared_ptr<sf::Font> ButtonFont;

  bool GotBGTexture;
  bool GotHighlightedTexture;
  bool GotPressedTexture;
  
  sf::Color ButtonColor;
};  

Let's break it down

static std::shared_ptr<ClickButton> Create()
This method creates a new ClickButton object on the heap, wrapped in a smart pointer. It is highly recommended you use this to manage the lifetime of the object, as the smart pointer will automatically manage the storage for you.

virtual void TickUpdate(const double &delta)
The method is virtual to allow you to derive from ClickButton if you so wish.
This method is required because BaseUIElement derives from BaseEngineInterface

virtual void Render()
The method is virtual to allow you to derive from ClickButton if you so wish

virtual void OnShutDown()
The method is virtual to allow you to derive from ClickButton if you so wish

'virtual void SetSize(const sf::Vector2f &size)'
Sets the size of the Button on the screen in (length, width)

virtual void SetPosition(const sf::Vector2f &Position)
Sets the position of the Button on the screen in (x, y)

virtual void Align()
The method is virtual to allow you to derive from ClickButton if you so wish

These methods are for handling events. These are overridden from the BaseUIElement class, and these do INTERNAL button logic, like changing textures when you mouse over, etc. They do NOT do custom behavior, like calling a method when the button is pressed. Those actions are stored in the function pointer objects.

  virtual void HandleMouseOver(const sf::Vector2i &pos)  
  virtual void HandleMouseExit(const sf::Vector2i &pos)  
  virtual void HandleMouseMovement(const sf::Vector2i &pos)  
  virtual void HandleMousePress(const sf::Vector2i &pos, const sf::Mouse::Button &b)  
  virtual void HandleMouseRelease(const sf::Vector2i &pos, const sf::Mouse::Button &b)  
  virtual void HandleFocusGained(const sf::Vector2i &pos)  
  virtual void HandleFocusLost(const sf::Vector2i &pos)  
  virtual void HandleKeyPress(const sf::Keyboard::Key &key)  
  virtual void HandleKeyRelease(const sf::Keyboard::Key &key)  

Function objects used for custom behavior are stored in the Targets, and they can be bound using

`BindCallback` from the base UI class  

Example:

Button->OnMouseRelease = [this](const sf::Vector2i &v, const sf::Mouse::Button &b) {
  ResourceManager->RequestTexture("./SFEngine/Samples/Textures/UI/ButtonBG.png", "ButtonBG2", SomeCallback);
};

The logic you do inside the callback you set is totally up to you. You can do anything you wish (but be safe about it, don't try to make the engine explode)

To use the UI, you must have a UI controller object to store them, unless for some reason you want to do all the collision and state management yourself.

UIController mycontroller;  
auto MyButton = ClickButton::Create();  
MyButton->SetPosition(sf::Vector2f(100, 100));   
MyButton->SetSize(sf::Vector2f(150, 300));  
mycontroller.AddElement(MyButton);  

Now that controller object will have MyButton stored inside and will do everything it needs to for the UI element logic.
The button will be at the position (100px, 100px) and have a width of 150px and a height of 300px. The position uses the upper left-hand corner of the screen as (0, 0) and the values increase as you go down the screen and as you go to the right along the screen. Think of it like an upside-down coordinate plane.

If you wish you pass events to the handler, you will have to do that automatically

MyEventHandlingMethod(...)  
{
  mycontoller.HandleSomeEvent(...);
 ...

That is because the Engine cannot see all the way into your special class to see what it has a UI handler and it has no way of knowing that it is supposed to pass events to it. Thus it is up to you to do that.

You do not need to render the button yourself. Call mycontroller.Render() and the UI Controller will render the button for you. Of course, if you do not actually add the render target, then it will never be rendered.

The ClickButton internally uses a sf::RectangleShape and sf::Texture and sf::Text to render itself. They are added to render targets like:

RenderTarget tgt;
std::shared_ptr<sf::RectangleShape> shape = std::make_shared<sf::RectangleShape>();  
//do stuff with shape  
AddRenderTarget(tgt)  

RenderTarget txtTarget  
std::shared_ptr<sf::Text> text = std::make_shared<sf::Text>();  
///do stuff with text  
AddRenderTarget(txtTarget)  

You can see the page on the base ui element for more info on how to use the targets: BaseUIElement

⚠️ **GitHub.com Fallback** ⚠️