diff --git a/README.md b/README.md index c7b4238..b1910e7 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,40 @@ -# cigus +# cigui +# Goal + +```cpp +#include + +struct ContentView : public cig::View { + void body() { + cig::VStack( + cig::SystemIcon("globe.fill"), + cig::Text("Welcome to Cigui") + ) + } +} + +struct SettingsView : public cig::View { + void body() { + cig::Tabbed( + cig::Tab( + + ).tag("Tab 1"), + cig::Tab( + cig::VStack( + cig::Text("Other Tab") + ) + ) + ); + } +} + +struct MainApp : public cig::App { + void body() { + cig::WindowGroup()( + cig::ViewWindow(new ContentView()), + cig::SettingsWindow(new SettingsView()) + ) + } +} +``` \ No newline at end of file diff --git a/cigus.hpp b/cigus.hpp index 8e2b806..a644f4b 100644 --- a/cigus.hpp +++ b/cigus.hpp @@ -5,228 +5,200 @@ #include #include -namespace cigus { + +#define TYPEDEF_VECTOR(NAME, T, N, s) typedef NAME vec##N##s; + +#define TYPEDEF_VECTORS(NAME, N) \ + typedef NAME vec##N##; \ + TYPEDEF_VECTOR(NAME, float, N, f) \ + TYPEDEF_VECTOR(NAME, double, N, d) \ + TYPEDEF_VECTOR(NAME, long double, N, ld) \ + TYPEDEF_VECTOR(NAME, size_t, N, sz) \ + TYPEDEF_VECTOR(NAME, int, N, i) \ + TYPEDEF_VECTOR(NAME, unsigned int, N, u) \ + TYPEDEF_VECTOR(NAME, short, N, s) \ + TYPEDEF_VECTOR(NAME, unsigned short, N, us) \ + TYPEDEF_VECTOR(NAME, long, N, l) \ + TYPEDEF_VECTOR(NAME, unsigned long, N, ul) \ + TYPEDEF_VECTOR(NAME, long long, N, ll) \ + TYPEDEF_VECTOR(NAME, unsigned long long, N, ull) + + + + +namespace UI +{ using json = nlohmann::json; - template class Ref; - template class OriginRef; - template class MutRef; - template class ConstRef; - template - class Ref { - protected: - T *ptr = nullptr; - - public: - virtual ~Ref() {} - Ref() = delete; - Ref(const Ref &other) = delete; - Ref(Ref &&other) = delete; - - Ref(const OriginRef& ptr) : ptr(ptr.ptr) { - } - - Ref(T* ptr) : ptr(ptr) - { - - } - - virtual bool operator!() const { - return ptr == nullptr; - } - - virtual void check() const { - assert(ptr != nullptr || "Dereferencing null pointer"); - } - - virtual const T &operator*() const { - check(); - return *ptr; - } - - virtual const T *operator->() const { - check(); - return ptr; - } - - static Ref Null() - { - return Ref(nullptr); - } + union Vector2 { + struct { T x, y; }; + struct { T a, b; }; }; + TYPEDEF_VECTORS(Vector2, 2) + template - class OriginRef final : public MutRef { - public: - friend class Ref; - - template - OriginRef(Args... args) : Ref(new G(std::forward(args)...)) { - } - - OriginRef(T* ptr) : MutRef(ptr) { - } - - ~OriginRef() override { - if (this->ptr != nullptr) { - delete this->ptr; - } - } - - [[nodiscard]] MutRef mut() { - return MutRef(this->ptr); - } - - [[nodiscard]] ConstRef immute() const { - return ConstRef(this->ptr); - } + union Vector3 { + struct { T x, y, z; }; + struct { T r, g, b; }; }; + TYPEDEF_VECTORS(Vector3, 3) template - class MutRef : public Ref { - protected: - using Ref::ptr; - public: - friend class Ref; - - using Ref::check; - using Ref::operator*; - using Ref::operator->; - - MutRef(const OriginRef& other) : Ref(other.ptr) {} - - MutRef(T* ptr) : Ref(ptr) {} - - MutRef(const MutRef &other) : Ref(other.ptr) { - } - - MutRef(MutRef &&other) noexcept : Ref(other.ptr) { - } - - MutRef &operator=(MutRef &&other) noexcept { - if (this->ptr != other.ptr) { - ptr = other.ptr; - } - return *this; - } - - T &operator*() { - check(); - return *ptr; - } - - T *operator->() { - check(); - return ptr; - } + union Vector4 { + struct { T x, y, z, w; }; + struct { T r, g, b, a; }; + struct { T left, top, right, bottom; }; }; + TYPEDEF_VECTORS(Vector4, 4) - template - class ConstRef : public Ref + + + class RenderCall { - protected: - using Ref::ptr; - using Ref::check; - public: - friend class Ref; - - ConstRef(const OriginRef other) : Ref(other.ptr) { - } - - ConstRef(const MutRef other) : Ref(other.ptr) { - } - }; - - template - class NullRef - { - public: - friend class Ref; - - NullRef(const NullRef &other) = delete; - NullRef(NullRef &&other) = delete; - - NullRef &operator=(NullRef &&other) = delete; - - NullRef() : Ref(nullptr) { - } - - T *ptr = nullptr; - - bool operator!() const { - return false; - } - }; -} - -namespace cigus::UI { - class RenderCall { - OriginRef drawable; + std::unique_ptr drawable; sf::RenderStates states; public: - explicit RenderCall(const sf::RenderStates& states, sf::Drawable *ptr) : drawable(ptr), states(states) { - drawable.check(); + explicit RenderCall(const sf::RenderStates& states, sf::Drawable* ptr) : drawable(ptr), states(states) + { + if (!drawable) { throw std::runtime_error("RenderCall::RenderCall(): Drawable is null"); } } - void draw(sf::RenderTarget &target, const sf::RenderStates &states) const { - target.draw(*drawable, states); - } - - MutRef operator->() { - drawable.check(); - return drawable.mut(); - } + void draw(sf::RenderTarget& target, const sf::RenderStates& states) const { target.draw(*drawable, states); } }; - class View { - std::vector m_RenderCalls; + enum class LayoutSizes : uint8_t + { + None = 0, + Min, + Max, + Fixed, + }; + enum class LayoutAlignment : uint8_t + { + None = 0, + Left, + Right, + Top, + Bottom, + Center, + }; + + enum class LayoutDirection : uint8_t + { + None = 0, + LeftToRight, + RightToLeft, + TopToBottom, + BottomToTop, + }; + + enum class LayoutPosition : uint8_t + { + None = 0, + Absolute, + Left, + Right, + Top, + Bottom, + Center, + }; + + struct Layout + { + struct { + LayoutSizes rule = LayoutSizes::None; + vec2f minSize = {0.f, 0.f}; + vec2f maxSize = {0.f, 0.f}; + } size; + + struct { + LayoutAlignment rule = LayoutAlignment::None; + vec4f padding = {0.f, 0.f, 0.f, 0.f}; + vec4f margin = {0.f, 0.f, 0.f, 0.f}; + } alignment; + + struct { + LayoutDirection rule = LayoutDirection::None; + vec2f spacing = {0.f, 0.f}; + } direction; + + struct { + LayoutPosition rule = LayoutPosition::None; + vec2f position = {0.f, 0.f}; + } position; + }; + + class View + { protected: - void Rectangle(const float x, const float y, sf::Color color = sf::Color::White) { - auto shape = new sf::RectangleShape(sf::Vector2f(x, y)); - shape->setFillColor(color); - m_RenderCalls.emplace_back(sf::RenderStates(), shape); - } + std::vector m_RenderCalls; + Layout m_Layout; public: virtual ~View() = default; - [[nodiscard]] const std::vector &renderCalls() const { - return m_RenderCalls; - } + [[nodiscard]] const std::vector& renderCalls() const { return m_RenderCalls; } - virtual bool update() + virtual bool update() { return false; } + + void draw() { - return false; - } - - void draw() { - if (!m_RenderCalls.empty()) - { - m_RenderCalls.clear(); - } + if (!m_RenderCalls.empty()) { m_RenderCalls.clear(); } body(); } + virtual void body() = 0; }; - class Renderer { + class Rectangle : public View + { + + vec2f m_Size; + sf::Color m_Color; + sf::Color m_BorderColor; + float m_BorderThickness = 0; + + + void setBorderColor(const sf::Color& color) { m_BorderColor = color; } + void setBorderThickness(float thickness) { m_BorderThickness = thickness; } + void setColor(const sf::Color& color) { m_Color = color; } + void setSize(const vec2f& size) { m_Size = size; } + + void body() override + { + auto m_Shape = new sf::RectangleShape(sf::Vector2f{m_Size.x, m_Size.y}); + m_Shape->setFillColor(m_Color); + if (m_BorderThickness > 0) + { + m_Shape->setOutlineThickness(m_BorderThickness); + m_Shape->setOutlineColor(m_BorderColor); + } + m_RenderCalls.emplace_back(sf::RenderStates(), m_Shape); + } + + Rectangle(const vec2f& size) : m_Size(size) {} + }; + + class Renderer + { public: - explicit Renderer(const MutRef &_view) : view(_view) { view->body(); } + explicit Renderer(View* _view) : view(_view) { view->body(); } - MutRef view; + std::unique_ptr view; - void update() { + void update() const + { if (view->update()) view->draw(); } - void render(sf::RenderTarget &target, const sf::RenderStates &states) const { - for (const auto &renderCall: view->renderCalls()) { - renderCall.draw(target, states); - } + void render(sf::RenderTarget& target, const sf::RenderStates& states) const + { + for (const auto& renderCall : view->renderCalls()) { renderCall.draw(target, states); } } }; } diff --git a/src/main.cpp b/src/main.cpp index 8699510..ecd7d9a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,7 +16,8 @@ public: void body() override { std::cout << "Body\n"; - //Rectangle(100, 100, sf::Color(250,250,250)); + Rectangle(400,400, sf::Color(20,20,120)); + Rectangle(100, 100, sf::Color(250,250,250)); Rectangle(10,20, sf::Color(120,120,120)); } }; @@ -27,8 +28,8 @@ int main(int argc, char** argv) { sf::RenderWindow window(sf::VideoMode({800, 600}), "Hello World!"); window.setFramerateLimit(60); - cigus::OriginRef view = cigus::OriginRef(new NewView); - UI::Renderer renderer(view); + const auto view = new NewView(); + const UI::Renderer renderer(view); while (window.isOpen()) {