2024-08-03 04:11:49 +08:00
|
|
|
#ifndef CONTAINER_HPP
|
|
|
|
#define CONTAINER_HPP
|
|
|
|
|
|
|
|
#include <vector>
|
2024-08-20 10:39:38 +08:00
|
|
|
#include <map>
|
2024-08-03 04:11:49 +08:00
|
|
|
#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));
|
2024-08-20 10:39:38 +08:00
|
|
|
void setSize(sf::Vector2f size);
|
2024-08-03 04:11:49 +08:00
|
|
|
|
2024-08-20 10:39:38 +08:00
|
|
|
pContainer asContainer() const;
|
2024-08-03 04:11:49 +08:00
|
|
|
pContainer getParent() const;
|
|
|
|
const sf::Vector2f &getPosition() const;
|
|
|
|
const sf::Vector2f &getSize() const;
|
2024-08-20 10:39:38 +08:00
|
|
|
const sf::View &getView() const;
|
2024-08-03 04:11:49 +08:00
|
|
|
sf::FloatRect getGlobalBouds() const;
|
|
|
|
|
|
|
|
virtual bool isRoot() const;
|
|
|
|
virtual bool hasInternalChange() const;
|
|
|
|
|
2024-08-20 10:39:38 +08:00
|
|
|
void update(sf::RenderWindow &window) const;
|
2024-08-03 04:11:49 +08:00
|
|
|
|
|
|
|
template <class T>
|
|
|
|
void registerEvent(EventType type, std::function<T> handler);
|
|
|
|
|
|
|
|
public: // Static and operators
|
2024-08-20 10:39:38 +08:00
|
|
|
static pContainer getRoot(pContainer p = nullptr);
|
2024-08-03 04:11:49 +08:00
|
|
|
|
|
|
|
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);
|
2024-08-20 10:39:38 +08:00
|
|
|
// Only call by sftk::Window::Window()
|
|
|
|
Container(sf::Vector2f pos, sf::Vector2f size, bool root = false);
|
2024-08-03 04:11:49 +08:00
|
|
|
|
|
|
|
virtual sf::RenderWindow &windowSFWindow();
|
|
|
|
|
2024-08-20 10:39:38 +08:00
|
|
|
virtual void draw(sf::RenderWindow &sfwindow) const;
|
|
|
|
|
2024-08-03 04:11:49 +08:00
|
|
|
// 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);
|
|
|
|
|
2024-08-20 10:39:38 +08:00
|
|
|
private:
|
|
|
|
uint64_t id;
|
|
|
|
|
2024-08-03 04:11:49 +08:00
|
|
|
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;
|
2024-08-20 10:39:38 +08:00
|
|
|
std::vector<pContainer> children;
|
2024-08-03 04:11:49 +08:00
|
|
|
sf::Vector2f basepos;
|
|
|
|
sf::Vector2f pos, size;
|
|
|
|
|
|
|
|
sf::View view;
|
|
|
|
|
|
|
|
static const int64_t maxClickTime = 300;
|
|
|
|
|
2024-08-20 10:39:38 +08:00
|
|
|
static thread_local uint64_t containerCounter;
|
|
|
|
static thread_local std::map<uint64_t, pContainer> globalContainers;
|
|
|
|
static thread_local pContainer root;
|
|
|
|
|
2024-08-03 04:11:49 +08:00
|
|
|
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
|
2024-08-04 00:19:19 +08:00
|
|
|
// When the values is not -1, mouse had pressed.
|
2024-08-03 04:11:49 +08:00
|
|
|
int64_t lastMousePressTime[sf::Mouse::Button::ButtonCount];
|
2024-08-04 00:19:19 +08:00
|
|
|
// When the values is not (-1, -1), mouse had pressed.
|
2024-08-03 04:11:49 +08:00
|
|
|
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;
|
|
|
|
};
|
2024-08-04 00:19:19 +08:00
|
|
|
|
|
|
|
class HandlerNotMatched : public SFTKException<Container>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
HandlerNotMatched(Container *container);
|
|
|
|
const char *what() const noexcept override;
|
|
|
|
};
|
2024-08-20 10:39:38 +08:00
|
|
|
|
|
|
|
class ConstructorCalledIllegally : public SFTKException<Container>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ConstructorCalledIllegally(Container *container);
|
|
|
|
const char *what() const noexcept override;
|
|
|
|
};
|
2024-08-03 04:11:49 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|