SFTK/include/containers/container.hpp

133 lines
4.2 KiB
C++

#ifndef CONTAINER_HPP
#define CONTAINER_HPP
#include <vector>
#include <memory>
#include <functional>
#include <exceptions.hpp>
#include <event.hpp>
#include <SFML/Graphics.hpp>
namespace sftk
{
class Container;
typedef std::shared_ptr<Container> pContainer;
bool operator==(pContainer &shp, Container *rawp);
class Container
{
public: // Public base functions
static pContainer create(pContainer parent = nullptr);
static pContainer create(sf::Vector2f pos, sf::Vector2f size, pContainer parent = nullptr);
void setParent(pContainer parent);
void setPosition(sf::Vector2f pos = sf::Vector2f(0, 0));
void setSize(sf::Vector2f pos);
void setBackgroudColor(sf::Color color);
pContainer getParent() const;
const sf::Vector2f &getPosition() const;
const sf::Vector2f &getSize() const;
sf::FloatRect getGlobalBouds() const;
virtual bool isRoot() const;
virtual bool hasInternalChange() const;
virtual void update() const;
public: // Event hadler register functions
template <class T>
void registerEvent(EventType type, std::function<T> handler);
public: // Static and operators
static pContainer getRoot(Container *p = nullptr);
friend bool sftk::operator==(pContainer &shp, Container *rawp);
protected: // Must be overrided by child classes
Container(pContainer parent = nullptr);
Container(sf::Vector2f pos, sf::Vector2f size, pContainer parent = nullptr);
Container(sf::Vector2f pos, sf::Vector2f size, bool root);
virtual sf::RenderWindow &windowSFWindow();
// The events bases on sfml's Event,
// so the Window class must use this function to
// pass event to the root container
// (itself's parent class)'s dispatchEvent(Event&)
// to process it as Event.
void dispatchEvent(sf::Event &event);
private: // For this class to use
sf::RenderWindow &getSfWindow();
// When this container did deal with the passed event
// it returns true. On the oppsite case it returns false.
bool dispatchEvent(Event &event);
pContainer parent;
std::vector<pContainer> childs;
sf::Vector2f basepos;
sf::Vector2f pos, size;
sf::View view;
sf::Color backgroudColor;
static const int64_t maxClickTime = 300;
private: // Called on construction
static void rootTest(Container *self);
inline static int64_t currentTime();
private: // Event handlers
std::function<void()> closed;
std::function<void(sf::Vector2f)> resized;
std::function<void(sf::Vector2f, sf::Mouse::Button)> mousePressed;
std::function<void(sf::Vector2f, sf::Mouse::Button)> mouseReleased;
std::function<void(sf::Vector2f, sf::Mouse::Button)> mouseClicked;
std::function<void(sf::Vector2f)> mouseEntered;
std::function<void(sf::Vector2f)> mouseLeft;
std::function<void(sf::Vector2f)> mouseMoved;
std::function<void(sf::Vector2f, sf::Vector2f, sf::Mouse::Button)> mouseDragged;
std::function<void(float)> mouseScrolled;
std::function<void(wchar_t)> textInputed;
private: // Second events asistant vars
// When the values is not -1, mouse had pressed.
int64_t lastMousePressTime[sf::Mouse::Button::ButtonCount];
// When the values is not (-1, -1), mouse had pressed.
sf::Vector2f lastMousePressPos[sf::Mouse::Button::ButtonCount];
bool focused;
bool mouseLocated;
public: // Exceptions
class RootContainerNotPresent : public SFTKException<Container>
{
public:
RootContainerNotPresent(Container *container);
const char *what() const noexcept override;
};
class NotAWindowObj : public SFTKException<Container>
{
public:
NotAWindowObj(Container *container);
const char *what() const noexcept override;
};
class HandlerNotMatched : public SFTKException<Container>
{
public:
HandlerNotMatched(Container *container);
const char *what() const noexcept override;
};
};
};
#endif