Compare commits
2 Commits
c7cd5bad91
...
781e62f041
Author | SHA1 | Date |
---|---|---|
pointer-to-bios | 781e62f041 | |
pointer-to-bios | 77d2d45b20 |
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "deps/SFML"]
|
||||||
|
path = deps/SFML
|
||||||
|
url = https://github.com/SFML/SFML.git
|
|
@ -3,17 +3,15 @@ project(SFTK LANGUAGES CXX)
|
||||||
|
|
||||||
set(CXX_STANDARD_REQUIRED 23)
|
set(CXX_STANDARD_REQUIRED 23)
|
||||||
|
|
||||||
include(FetchContent)
|
add_subdirectory(./deps/SFML)
|
||||||
FetchContent_Declare(SFML
|
|
||||||
GIT_REPOSITORY https://github.com/SFML/SFML.git
|
|
||||||
GIT_TAG 2.6.x)
|
|
||||||
FetchContent_MakeAvailable(SFML)
|
|
||||||
|
|
||||||
set(ROOT src/)
|
set(ROOT src/)
|
||||||
set(CONTAINER src/containers)
|
set(CONTAINER src/containers)
|
||||||
|
|
||||||
set(SOURCES ${SOURCES} ${ROOT}/window.cpp)
|
set(SOURCES ${SOURCES} ${ROOT}/window.cpp)
|
||||||
|
set(SOURCES ${SOURCES} ${ROOT}/font.cpp)
|
||||||
set(SOURCES ${SOURCES} ${CONTAINER}/container.cpp)
|
set(SOURCES ${SOURCES} ${CONTAINER}/container.cpp)
|
||||||
|
set(SOURCES ${SOURCES} ${CONTAINER}/label.cpp)
|
||||||
|
|
||||||
add_library(sftk SHARED ${SOURCES})
|
add_library(sftk SHARED ${SOURCES})
|
||||||
target_link_libraries(sftk PUBLIC sfml-graphics sfml-audio sfml-network)
|
target_link_libraries(sftk PUBLIC sfml-graphics sfml-audio sfml-network)
|
||||||
|
|
Binary file not shown.
|
@ -5,15 +5,9 @@
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
auto &window = sftk::Window::create(800, 600, L"demo1");
|
auto &window = sftk::Window::create(800, 600, L"demo1");
|
||||||
auto container = sftk::Container::create(vec(100.f, 100.f), vec(400.f, 400.f), window.getRoot());
|
window.setBackgroudColor(sf::Color::White);
|
||||||
container->setBackgroudColor(sf::Color::White);
|
auto &label = sftk::Label::create(L"hello SFTK.", sftk::Font("../demo/SarasaUiSC-Regular.ttf", "", 18));
|
||||||
container->registerEvent(
|
label.setColor(sf::Color::Black);
|
||||||
sftk::EventType::MouseDragged,
|
label.setPosition(vec(100.f, 100.f));
|
||||||
std::function(
|
|
||||||
[](sf::Vector2f start, sf::Vector2f now, sf::Mouse::Button button)
|
|
||||||
{ std::cout << "(" << start.x << "," << start.y << ")"
|
|
||||||
<< "->(" << now.x << "," << now.y << ")"
|
|
||||||
<< "|" << button
|
|
||||||
<< std::endl; }));
|
|
||||||
window.exec();
|
window.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 69ea0cd863aed1d4092b970b676924a716ff718b
|
|
@ -2,6 +2,7 @@
|
||||||
#define CONTAINER_HPP
|
#define CONTAINER_HPP
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
@ -25,35 +26,38 @@ namespace sftk
|
||||||
|
|
||||||
void setParent(pContainer parent);
|
void setParent(pContainer parent);
|
||||||
void setPosition(sf::Vector2f pos = sf::Vector2f(0, 0));
|
void setPosition(sf::Vector2f pos = sf::Vector2f(0, 0));
|
||||||
void setSize(sf::Vector2f pos);
|
void setSize(sf::Vector2f size);
|
||||||
void setBackgroudColor(sf::Color color);
|
|
||||||
|
|
||||||
|
pContainer asContainer() const;
|
||||||
pContainer getParent() const;
|
pContainer getParent() const;
|
||||||
const sf::Vector2f &getPosition() const;
|
const sf::Vector2f &getPosition() const;
|
||||||
const sf::Vector2f &getSize() const;
|
const sf::Vector2f &getSize() const;
|
||||||
|
const sf::View &getView() const;
|
||||||
sf::FloatRect getGlobalBouds() const;
|
sf::FloatRect getGlobalBouds() const;
|
||||||
|
|
||||||
virtual bool isRoot() const;
|
virtual bool isRoot() const;
|
||||||
virtual bool hasInternalChange() const;
|
virtual bool hasInternalChange() const;
|
||||||
|
|
||||||
virtual void update() const;
|
void update(sf::RenderWindow &window) const;
|
||||||
|
|
||||||
public: // Event hadler register functions
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void registerEvent(EventType type, std::function<T> handler);
|
void registerEvent(EventType type, std::function<T> handler);
|
||||||
|
|
||||||
public: // Static and operators
|
public: // Static and operators
|
||||||
static pContainer getRoot(Container *p = nullptr);
|
static pContainer getRoot(pContainer p = nullptr);
|
||||||
|
|
||||||
friend bool sftk::operator==(pContainer &shp, Container *rawp);
|
friend bool sftk::operator==(pContainer &shp, Container *rawp);
|
||||||
|
|
||||||
protected: // Must be overrided by child classes
|
protected: // Must be overrided by child classes
|
||||||
Container(pContainer parent = nullptr);
|
Container(pContainer parent = nullptr);
|
||||||
Container(sf::Vector2f pos, sf::Vector2f size, pContainer parent = nullptr);
|
Container(sf::Vector2f pos, sf::Vector2f size, pContainer parent = nullptr);
|
||||||
Container(sf::Vector2f pos, sf::Vector2f size, bool root);
|
// Only call by sftk::Window::Window()
|
||||||
|
Container(sf::Vector2f pos, sf::Vector2f size, bool root = false);
|
||||||
|
|
||||||
virtual sf::RenderWindow &windowSFWindow();
|
virtual sf::RenderWindow &windowSFWindow();
|
||||||
|
|
||||||
|
virtual void draw(sf::RenderWindow &sfwindow) const;
|
||||||
|
|
||||||
// The events bases on sfml's Event,
|
// The events bases on sfml's Event,
|
||||||
// so the Window class must use this function to
|
// so the Window class must use this function to
|
||||||
// pass event to the root container
|
// pass event to the root container
|
||||||
|
@ -61,23 +65,27 @@ namespace sftk
|
||||||
// to process it as Event.
|
// to process it as Event.
|
||||||
void dispatchEvent(sf::Event &event);
|
void dispatchEvent(sf::Event &event);
|
||||||
|
|
||||||
private: // For this class to use
|
private:
|
||||||
|
uint64_t id;
|
||||||
|
|
||||||
sf::RenderWindow &getSfWindow();
|
sf::RenderWindow &getSfWindow();
|
||||||
// When this container did deal with the passed event
|
// When this container did deal with the passed event
|
||||||
// it returns true. On the oppsite case it returns false.
|
// it returns true. On the oppsite case it returns false.
|
||||||
bool dispatchEvent(Event &event);
|
bool dispatchEvent(Event &event);
|
||||||
|
|
||||||
pContainer parent;
|
pContainer parent;
|
||||||
std::vector<pContainer> childs;
|
std::vector<pContainer> children;
|
||||||
sf::Vector2f basepos;
|
sf::Vector2f basepos;
|
||||||
sf::Vector2f pos, size;
|
sf::Vector2f pos, size;
|
||||||
|
|
||||||
sf::View view;
|
sf::View view;
|
||||||
|
|
||||||
sf::Color backgroudColor;
|
|
||||||
|
|
||||||
static const int64_t maxClickTime = 300;
|
static const int64_t maxClickTime = 300;
|
||||||
|
|
||||||
|
static thread_local uint64_t containerCounter;
|
||||||
|
static thread_local std::map<uint64_t, pContainer> globalContainers;
|
||||||
|
static thread_local pContainer root;
|
||||||
|
|
||||||
private: // Called on construction
|
private: // Called on construction
|
||||||
static void rootTest(Container *self);
|
static void rootTest(Container *self);
|
||||||
inline static int64_t currentTime();
|
inline static int64_t currentTime();
|
||||||
|
@ -125,6 +133,13 @@ namespace sftk
|
||||||
HandlerNotMatched(Container *container);
|
HandlerNotMatched(Container *container);
|
||||||
const char *what() const noexcept override;
|
const char *what() const noexcept override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ConstructorCalledIllegally : public SFTKException<Container>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConstructorCalledIllegally(Container *container);
|
||||||
|
const char *what() const noexcept override;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef LABLE_HPP
|
||||||
|
#define LABLE_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <font.hpp>
|
||||||
|
#include <containers/container.hpp>
|
||||||
|
|
||||||
|
namespace sftk
|
||||||
|
{
|
||||||
|
class Label : public Container
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Label &create(pContainer parent = nullptr);
|
||||||
|
static Label &create(sf::Vector2f pos, pContainer parent = nullptr);
|
||||||
|
static Label &create(std::wstring text, pContainer parent = nullptr);
|
||||||
|
static Label &create(Font font, pContainer parent = nullptr);
|
||||||
|
static Label &create(std::wstring text, Font font, pContainer parent = nullptr);
|
||||||
|
|
||||||
|
void setText(std::wstring text);
|
||||||
|
void setFont(Font font);
|
||||||
|
void setColor(sf::Color color);
|
||||||
|
void setSize(sf::Vector2f size) = delete;
|
||||||
|
|
||||||
|
const std::wstring &getText() const;
|
||||||
|
const Font &getFont() const;
|
||||||
|
sf::Color getColor() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Label(pContainer parent = nullptr);
|
||||||
|
Label(sf::Vector2f pos, pContainer parent = nullptr);
|
||||||
|
|
||||||
|
void draw(sf::RenderWindow &sfwindow) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::wstring text;
|
||||||
|
Font font;
|
||||||
|
sf::Color color;
|
||||||
|
|
||||||
|
std::vector<float> linesWidths;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -40,17 +40,23 @@ namespace sftk
|
||||||
* @param msg exception message
|
* @param msg exception message
|
||||||
* @param len message length
|
* @param len message length
|
||||||
*/
|
*/
|
||||||
void formatAddress(char *msg, int len) const
|
void formatAddress(char *msg, int len) const noexcept
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
auto ptr = reinterpret_cast<uintptr_t>(sftkObj);
|
||||||
ss << std::hex << std::setw(16) << std::setfill('0') << reinterpret_cast<uintptr_t>(sftkObj);
|
while (--len >= 0)
|
||||||
auto it = ss.str().begin();
|
|
||||||
for (int i = 0; i < len; i++)
|
|
||||||
{
|
{
|
||||||
if (msg[i] == '*')
|
if (msg[len] == '*')
|
||||||
{
|
{
|
||||||
msg[i] = *it;
|
auto bit = ptr-- & 0xf;
|
||||||
++it;
|
if (bit < 10)
|
||||||
|
{
|
||||||
|
bit += '0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bit -= 10 - 'a';
|
||||||
|
}
|
||||||
|
msg[len] = bit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef FONT_HPP
|
||||||
|
#define FONT_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
#include <exceptions.hpp>
|
||||||
|
|
||||||
|
namespace sftk
|
||||||
|
{
|
||||||
|
class Font
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Font();
|
||||||
|
Font(std::string font, std::string fallback, int size);
|
||||||
|
|
||||||
|
sf::Font font;
|
||||||
|
sf::Font fallback;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
class MainFontIsEmpty : public SFTKException<Font>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MainFontIsEmpty(Font *font);
|
||||||
|
const char *what() const noexcept override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FailedToLoadFont : public SFTKException<Font>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FailedToLoadFont(Font *font);
|
||||||
|
const char *what() const noexcept override;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -4,7 +4,7 @@
|
||||||
#include <gtypes.hpp>
|
#include <gtypes.hpp>
|
||||||
|
|
||||||
#include <window.hpp>
|
#include <window.hpp>
|
||||||
|
|
||||||
#include <containers/container.hpp>
|
#include <containers/container.hpp>
|
||||||
|
#include <containers/label.hpp>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,6 +28,9 @@ namespace sftk
|
||||||
void exec();
|
void exec();
|
||||||
|
|
||||||
void setSize(sf::Vector2u size);
|
void setSize(sf::Vector2u size);
|
||||||
|
void setBackgroudColor(sf::Color color);
|
||||||
|
|
||||||
|
const sf::Color &getBackgroundColor() const;
|
||||||
|
|
||||||
bool isRoot() const;
|
bool isRoot() const;
|
||||||
|
|
||||||
|
@ -45,6 +48,7 @@ namespace sftk
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<std::vector<sf::Vector2f>> v2f_dumpst;
|
std::unique_ptr<std::vector<sf::Vector2f>> v2f_dumpst;
|
||||||
|
sf::Color backgroud;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class WindowMultipleConstructed : public SFTKException<Window>
|
class WindowMultipleConstructed : public SFTKException<Window>
|
||||||
|
|
|
@ -8,11 +8,14 @@
|
||||||
|
|
||||||
using namespace sftk;
|
using namespace sftk;
|
||||||
|
|
||||||
pContainer Container::getRoot(Container *p)
|
thread_local uint64_t Container::containerCounter = 0;
|
||||||
|
thread_local std::map<uint64_t, pContainer> Container::globalContainers;
|
||||||
|
thread_local pContainer Container::root = nullptr;
|
||||||
|
|
||||||
|
pContainer Container::getRoot(pContainer p)
|
||||||
{
|
{
|
||||||
static thread_local pContainer root;
|
|
||||||
if (p)
|
if (p)
|
||||||
root.reset(p);
|
root = p;
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,8 +25,13 @@ void Container::rootTest(Container *self)
|
||||||
throw RootContainerNotPresent(self);
|
throw RootContainerNotPresent(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
Container::Container(pContainer parent) : parent(nullptr)
|
Container::Container(pContainer parent)
|
||||||
|
: parent(nullptr),
|
||||||
|
pos(vec(0.f, 0.f)),
|
||||||
|
size(vec(0.f, 0.f)),
|
||||||
|
view(vec(0.f, 0.f, 0.f, 0.f))
|
||||||
{
|
{
|
||||||
|
id = containerCounter++;
|
||||||
if (!parent.get())
|
if (!parent.get())
|
||||||
{
|
{
|
||||||
Container::rootTest(this);
|
Container::rootTest(this);
|
||||||
|
@ -33,7 +41,9 @@ Container::Container(pContainer parent) : parent(nullptr)
|
||||||
{
|
{
|
||||||
this->parent = parent;
|
this->parent = parent;
|
||||||
}
|
}
|
||||||
this->parent->childs.push_back(pContainer(this));
|
pContainer pthis(this);
|
||||||
|
globalContainers[id] = pthis;
|
||||||
|
this->parent->children.push_back(pthis);
|
||||||
for (auto &p : lastMousePressPos)
|
for (auto &p : lastMousePressPos)
|
||||||
p = vec(-1.f, -1.f);
|
p = vec(-1.f, -1.f);
|
||||||
}
|
}
|
||||||
|
@ -42,10 +52,9 @@ Container::Container(sf::Vector2f pos, sf::Vector2f size, pContainer parent)
|
||||||
: parent(nullptr),
|
: parent(nullptr),
|
||||||
pos(pos),
|
pos(pos),
|
||||||
size(size),
|
size(size),
|
||||||
view(vec(0.f, 0.f, size.x, size.y)),
|
view(vec(0.f, 0.f, size.x, size.y))
|
||||||
basepos(parent->basepos + parent->pos),
|
|
||||||
backgroudColor(sf::Color::Black)
|
|
||||||
{
|
{
|
||||||
|
id = containerCounter++;
|
||||||
if (!parent.get())
|
if (!parent.get())
|
||||||
{
|
{
|
||||||
Container::rootTest(this);
|
Container::rootTest(this);
|
||||||
|
@ -55,7 +64,10 @@ Container::Container(sf::Vector2f pos, sf::Vector2f size, pContainer parent)
|
||||||
{
|
{
|
||||||
this->parent = parent;
|
this->parent = parent;
|
||||||
}
|
}
|
||||||
this->parent->childs.push_back(pContainer(this));
|
basepos = this->parent->basepos + this->parent->pos;
|
||||||
|
pContainer pthis(this);
|
||||||
|
globalContainers[id] = pthis;
|
||||||
|
this->parent->children.push_back(pthis);
|
||||||
auto rootsize = getRoot()->getSize();
|
auto rootsize = getRoot()->getSize();
|
||||||
view.setViewport(vec(
|
view.setViewport(vec(
|
||||||
(parent->basepos.x + pos.x) / rootsize.x, (parent->basepos.y + pos.y) / rootsize.y,
|
(parent->basepos.x + pos.x) / rootsize.x, (parent->basepos.y + pos.y) / rootsize.y,
|
||||||
|
@ -69,9 +81,14 @@ Container::Container(sf::Vector2f pos, sf::Vector2f size, bool root)
|
||||||
pos(pos),
|
pos(pos),
|
||||||
size(size),
|
size(size),
|
||||||
view(vec(0.f, 0.f, size.x, size.y)),
|
view(vec(0.f, 0.f, size.x, size.y)),
|
||||||
basepos(vec(0.f, 0.f)),
|
basepos(vec(0.f, 0.f))
|
||||||
backgroudColor(sf::Color::Black)
|
|
||||||
{
|
{
|
||||||
|
if (!root)
|
||||||
|
{
|
||||||
|
throw new ConstructorCalledIllegally(this);
|
||||||
|
}
|
||||||
|
id = containerCounter++;
|
||||||
|
globalContainers[id] = pContainer(this);
|
||||||
view.setViewport(vec(0.f, 0.f, 1.f, 1.f));
|
view.setViewport(vec(0.f, 0.f, 1.f, 1.f));
|
||||||
for (auto &p : lastMousePressPos)
|
for (auto &p : lastMousePressPos)
|
||||||
p = vec(-1.f, -1.f);
|
p = vec(-1.f, -1.f);
|
||||||
|
@ -79,20 +96,20 @@ Container::Container(sf::Vector2f pos, sf::Vector2f size, bool root)
|
||||||
|
|
||||||
pContainer Container::create(pContainer parent)
|
pContainer Container::create(pContainer parent)
|
||||||
{
|
{
|
||||||
return pContainer(new Container(parent));
|
return (new Container(parent))->asContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
pContainer Container::create(sf::Vector2f pos, sf::Vector2f size, pContainer parent)
|
pContainer Container::create(sf::Vector2f pos, sf::Vector2f size, pContainer parent)
|
||||||
{
|
{
|
||||||
return pContainer(new Container(pos, size, parent));
|
return (new Container(pos, size, parent))->asContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::setParent(pContainer parent)
|
void Container::setParent(pContainer parent)
|
||||||
{
|
{
|
||||||
auto it = std::find(this->parent->childs.begin(), this->parent->childs.end(), this);
|
auto it = std::find(this->parent->children.begin(), this->parent->children.end(), this);
|
||||||
this->parent->childs.erase(it);
|
this->parent->children.erase(it);
|
||||||
this->parent = parent;
|
this->parent = parent;
|
||||||
this->parent->childs.push_back(pContainer(this));
|
this->parent->children.push_back(pContainer(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::setPosition(sf::Vector2f pos)
|
void Container::setPosition(sf::Vector2f pos)
|
||||||
|
@ -100,8 +117,12 @@ void Container::setPosition(sf::Vector2f pos)
|
||||||
this->pos = pos;
|
this->pos = pos;
|
||||||
auto rootsize = getRoot()->getSize();
|
auto rootsize = getRoot()->getSize();
|
||||||
view.setViewport(vec(
|
view.setViewport(vec(
|
||||||
(parent->pos.x + pos.x) / rootsize.x, (parent->pos.y + pos.y) / rootsize.y,
|
(basepos.x + pos.x) / rootsize.x, (basepos.x + pos.y) / rootsize.y,
|
||||||
size.x / rootsize.x, size.y / rootsize.y));
|
size.x / rootsize.x, size.y / rootsize.y));
|
||||||
|
for (auto c : children)
|
||||||
|
{
|
||||||
|
c->basepos = basepos + pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::setSize(sf::Vector2f size)
|
void Container::setSize(sf::Vector2f size)
|
||||||
|
@ -111,11 +132,12 @@ void Container::setSize(sf::Vector2f size)
|
||||||
view.setViewport(vec(
|
view.setViewport(vec(
|
||||||
(basepos.x + pos.x) / rootsize.x, (basepos.y + pos.y) / rootsize.y,
|
(basepos.x + pos.x) / rootsize.x, (basepos.y + pos.y) / rootsize.y,
|
||||||
size.x / rootsize.x, size.y / rootsize.y));
|
size.x / rootsize.x, size.y / rootsize.y));
|
||||||
|
view.setSize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::setBackgroudColor(sf::Color color)
|
pContainer Container::asContainer() const
|
||||||
{
|
{
|
||||||
backgroudColor = color;
|
return globalContainers[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
pContainer Container::getParent() const
|
pContainer Container::getParent() const
|
||||||
|
@ -133,6 +155,11 @@ const sf::Vector2f &Container::getSize() const
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sf::View &Container::getView() const
|
||||||
|
{
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
sf::FloatRect Container::getGlobalBouds() const
|
sf::FloatRect Container::getGlobalBouds() const
|
||||||
{
|
{
|
||||||
return vec(basepos.x + pos.x, basepos.y + pos.y, size.x, size.y);
|
return vec(basepos.x + pos.x, basepos.y + pos.y, size.x, size.y);
|
||||||
|
@ -148,27 +175,18 @@ bool Container::hasInternalChange() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::update() const
|
void Container::update(sf::RenderWindow &window) const
|
||||||
{
|
{
|
||||||
auto &window = getRoot()->windowSFWindow();
|
window.setView(view);
|
||||||
if (isRoot())
|
draw(window);
|
||||||
|
for (auto c : children)
|
||||||
{
|
{
|
||||||
window.clear(backgroudColor);
|
c->update(window);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
window.setView(view);
|
|
||||||
sf::RectangleShape bg(vec(size.x, size.y));
|
|
||||||
bg.setPosition(vec(0.f, 0.f));
|
|
||||||
bg.setFillColor(backgroudColor);
|
|
||||||
window.draw(bg);
|
|
||||||
}
|
|
||||||
for (auto c : childs)
|
|
||||||
{
|
|
||||||
c->update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Container::draw(sf::RenderWindow &sfwindow) const {}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void Container::registerEvent(EventType type, std::function<void()> handler)
|
void Container::registerEvent(EventType type, std::function<void()> handler)
|
||||||
{
|
{
|
||||||
|
@ -507,7 +525,7 @@ bool Container::dispatchEvent(Event &event)
|
||||||
|
|
||||||
bool child_handled;
|
bool child_handled;
|
||||||
bool handler_handled = false;
|
bool handler_handled = false;
|
||||||
for (auto container : childs)
|
for (auto container : children)
|
||||||
{
|
{
|
||||||
if ((child_handled = container->dispatchEvent(event)) && !broadcast)
|
if ((child_handled = container->dispatchEvent(event)) && !broadcast)
|
||||||
{
|
{
|
||||||
|
@ -548,7 +566,7 @@ const char *Container::RootContainerNotPresent::what() const noexcept
|
||||||
{
|
{
|
||||||
static char msg[] = "sftk::Container 0x********_********: Root container not present.";
|
static char msg[] = "sftk::Container 0x********_********: Root container not present.";
|
||||||
SFTKException::formatAddress(msg, sizeof(msg));
|
SFTKException::formatAddress(msg, sizeof(msg));
|
||||||
return msg;
|
return const_cast<const char *>(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Container::NotAWindowObj::NotAWindowObj(Container *container)
|
Container::NotAWindowObj::NotAWindowObj(Container *container)
|
||||||
|
@ -558,7 +576,7 @@ const char *Container::NotAWindowObj::what() const noexcept
|
||||||
{
|
{
|
||||||
static char msg[] = "sftk::Container 0x********_********: Not a sftk::Window.";
|
static char msg[] = "sftk::Container 0x********_********: Not a sftk::Window.";
|
||||||
SFTKException::formatAddress(msg, sizeof(msg));
|
SFTKException::formatAddress(msg, sizeof(msg));
|
||||||
return msg;
|
return const_cast<const char *>(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Container::HandlerNotMatched::HandlerNotMatched(Container *container)
|
Container::HandlerNotMatched::HandlerNotMatched(Container *container)
|
||||||
|
@ -566,7 +584,19 @@ Container::HandlerNotMatched::HandlerNotMatched(Container *container)
|
||||||
|
|
||||||
const char *Container::HandlerNotMatched::what() const noexcept
|
const char *Container::HandlerNotMatched::what() const noexcept
|
||||||
{
|
{
|
||||||
static char msg[] = "sftk::Container 0x********_********: When calling Container::registerEvent(), passed a closure with wrong arguments.";
|
static char msg[] = "sftk::Container 0x********_********:"
|
||||||
|
" When calling Container::registerEvent(), passed a closure with wrong arguments.";
|
||||||
SFTKException::formatAddress(msg, sizeof(msg));
|
SFTKException::formatAddress(msg, sizeof(msg));
|
||||||
return msg;
|
return const_cast<const char *>(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
Container::ConstructorCalledIllegally::ConstructorCalledIllegally(Container *container)
|
||||||
|
: SFTKException(container) {}
|
||||||
|
|
||||||
|
const char *Container::ConstructorCalledIllegally::what() const noexcept
|
||||||
|
{
|
||||||
|
static char msg[] = "sftk::Container 0x********_********:"
|
||||||
|
" This constructor can only be called by sftk::Window::Window().";
|
||||||
|
SFTKException::formatAddress(msg, sizeof(msg));
|
||||||
|
return const_cast<const char *>(msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
#include <containers/label.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <gtypes.hpp>
|
||||||
|
|
||||||
|
using namespace sftk;
|
||||||
|
|
||||||
|
Label::Label(pContainer parent) : Container(parent) {}
|
||||||
|
|
||||||
|
Label::Label(sf::Vector2f pos, pContainer parent)
|
||||||
|
: Container(pos, vec(0.f, 0.f), parent) {}
|
||||||
|
|
||||||
|
Label &Label::create(pContainer parent)
|
||||||
|
{
|
||||||
|
return *new Label(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Label &Label::create(sf::Vector2f pos, pContainer parent)
|
||||||
|
{
|
||||||
|
return *new Label(pos, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Label &Label::create(std::wstring text, pContainer parent)
|
||||||
|
{
|
||||||
|
auto *label = new Label(parent);
|
||||||
|
label->setText(text);
|
||||||
|
return *label;
|
||||||
|
}
|
||||||
|
|
||||||
|
Label &Label::create(Font font, pContainer parent)
|
||||||
|
{
|
||||||
|
auto *label = new Label(parent);
|
||||||
|
label->setFont(font);
|
||||||
|
return *label;
|
||||||
|
}
|
||||||
|
|
||||||
|
Label &Label::create(std::wstring text, Font font, pContainer parent)
|
||||||
|
{
|
||||||
|
auto *label = new Label(parent);
|
||||||
|
label->setFont(font);
|
||||||
|
label->setText(text);
|
||||||
|
return *label;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::setText(std::wstring text)
|
||||||
|
{
|
||||||
|
this->text = text;
|
||||||
|
linesWidths.clear();
|
||||||
|
float currentLineWidth = 0;
|
||||||
|
float maxWidth = 0;
|
||||||
|
for (auto ch : text)
|
||||||
|
{
|
||||||
|
if (ch == L'\n')
|
||||||
|
{
|
||||||
|
linesWidths.push_back(currentLineWidth);
|
||||||
|
if (currentLineWidth > maxWidth)
|
||||||
|
maxWidth = currentLineWidth;
|
||||||
|
currentLineWidth = 0;
|
||||||
|
}
|
||||||
|
auto glyph = font.font.getGlyph(ch, font.size, false);
|
||||||
|
currentLineWidth += glyph.advance;
|
||||||
|
}
|
||||||
|
if (currentLineWidth != 0)
|
||||||
|
{
|
||||||
|
linesWidths.push_back(currentLineWidth);
|
||||||
|
if (currentLineWidth > maxWidth)
|
||||||
|
maxWidth = currentLineWidth;
|
||||||
|
}
|
||||||
|
auto lineSpacing = font.font.getLineSpacing(font.size);
|
||||||
|
Container::setSize(vec(maxWidth, linesWidths.size() * lineSpacing));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::setFont(Font font)
|
||||||
|
{
|
||||||
|
this->font = font;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::setColor(sf::Color color)
|
||||||
|
{
|
||||||
|
this->color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::wstring &Label::getText() const
|
||||||
|
{
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Font &Label::getFont() const
|
||||||
|
{
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Color Label::getColor() const
|
||||||
|
{
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::draw(sf::RenderWindow &sfwindow) const
|
||||||
|
{
|
||||||
|
sf::Text textObj;
|
||||||
|
auto sz = getSize();
|
||||||
|
textObj.setPosition(vec(-sz.x / 2, -sz.y / 2));
|
||||||
|
textObj.setString(text);
|
||||||
|
textObj.setFont(font.font);
|
||||||
|
textObj.setCharacterSize(font.size);
|
||||||
|
textObj.setFillColor(color);
|
||||||
|
sfwindow.draw(textObj);
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include <font.hpp>
|
||||||
|
|
||||||
|
using namespace sftk;
|
||||||
|
|
||||||
|
Font::Font() {}
|
||||||
|
|
||||||
|
Font::Font(std::string font, std::string fallback, int size)
|
||||||
|
: size(size)
|
||||||
|
{
|
||||||
|
if (font.empty())
|
||||||
|
throw new MainFontIsEmpty(this);
|
||||||
|
if (!this->font.loadFromFile(font))
|
||||||
|
throw new FailedToLoadFont(this);
|
||||||
|
if (!fallback.empty())
|
||||||
|
if (!this->fallback.loadFromFile(fallback))
|
||||||
|
throw new FailedToLoadFont(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Font::MainFontIsEmpty::MainFontIsEmpty(Font *font)
|
||||||
|
: SFTKException(font) {}
|
||||||
|
|
||||||
|
const char *Font::MainFontIsEmpty::what() const noexcept
|
||||||
|
{
|
||||||
|
static char msg[] = "sftk::Font 0x********_********: The main font must be set.";
|
||||||
|
SFTKException::formatAddress(msg, sizeof(msg));
|
||||||
|
return const_cast<const char *>(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
Font::FailedToLoadFont::FailedToLoadFont(Font *font)
|
||||||
|
: SFTKException(font) {}
|
||||||
|
|
||||||
|
const char *Font::FailedToLoadFont::what() const noexcept
|
||||||
|
{
|
||||||
|
static char msg[] = "sftk::Font 0x********_********: Failed to load font file.";
|
||||||
|
SFTKException::formatAddress(msg, sizeof(msg));
|
||||||
|
return const_cast<const char *>(msg);
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include <gtypes.hpp>
|
#include <gtypes.hpp>
|
||||||
#include <containers/container.hpp>
|
#include <containers/container.hpp>
|
||||||
|
@ -16,11 +17,12 @@ Window &Window::create(int width, int height, std::wstring name)
|
||||||
Window::Window(int width, int height, std::wstring name)
|
Window::Window(int width, int height, std::wstring name)
|
||||||
: Container(vec(0.f, 0.f), vec((float)width, (float)height), true),
|
: Container(vec(0.f, 0.f), vec((float)width, (float)height), true),
|
||||||
sfwindow(sf::VideoMode(width, height), name),
|
sfwindow(sf::VideoMode(width, height), name),
|
||||||
running(new bool(true))
|
running(new bool(true)),
|
||||||
|
backgroud(sf::Color::Black)
|
||||||
{
|
{
|
||||||
if (Container::getRoot().get())
|
if (Container::getRoot().get())
|
||||||
throw WindowMultipleConstructed(this);
|
throw WindowMultipleConstructed(this);
|
||||||
Container::getRoot(this);
|
Container::getRoot(this->asContainer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::exec()
|
void Window::exec()
|
||||||
|
@ -45,7 +47,8 @@ void Window::exec()
|
||||||
}
|
}
|
||||||
if (event_occured || hasInternalChange())
|
if (event_occured || hasInternalChange())
|
||||||
{
|
{
|
||||||
update();
|
sfwindow.clear(backgroud);
|
||||||
|
update(sfwindow);
|
||||||
sfwindow.display();
|
sfwindow.display();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,6 +60,16 @@ void Window::setSize(sf::Vector2u size)
|
||||||
Container::setSize(vec((float)size.x, (float)size.y));
|
Container::setSize(vec((float)size.x, (float)size.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::setBackgroudColor(sf::Color color)
|
||||||
|
{
|
||||||
|
backgroud = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sf::Color &Window::getBackgroundColor() const
|
||||||
|
{
|
||||||
|
return backgroud;
|
||||||
|
}
|
||||||
|
|
||||||
bool Window::isRoot() const
|
bool Window::isRoot() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -82,5 +95,5 @@ const char *Window::WindowMultipleConstructed::what() const noexcept
|
||||||
{
|
{
|
||||||
static char msg[] = "sftk::Window 0x********_********: Multiply constructed in one thread.";
|
static char msg[] = "sftk::Window 0x********_********: Multiply constructed in one thread.";
|
||||||
SFTKException::formatAddress(msg, sizeof(msg));
|
SFTKException::formatAddress(msg, sizeof(msg));
|
||||||
return msg;
|
return const_cast<const char *>(msg);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue