From a776addf11ebd2b1d4a02232bd1825c09f4f5388 Mon Sep 17 00:00:00 2001 From: tobid7 Date: Fri, 3 Apr 2026 12:43:49 +0200 Subject: [PATCH] Implement VCanvas and Update TextElem - Text now requires a font and is able to take an individual scale - Container requires &ref for Elements to make sure they always exist - SetViewport now sets the canvas as well - SetBaseViewport Sets the Virtual Canvas Size - Layout Now requires a Drawlist reference in Render function - main.cpp: updated the template --- include/pd/ultra/container.hpp | 15 ++++-- include/pd/ultra/elems/element.hpp | 18 ++++++- include/pd/ultra/elems/text.hpp | 5 ++ include/pd/ultra/layout.hpp | 9 +--- source/ultra/elems/element.cpp | 6 ++- source/ultra/elems/text.cpp | 13 +++++ source/ultra/layout.cpp | 15 +++--- tests/gfx/source/main.cpp | 76 ++++++++++++++++-------------- 8 files changed, 97 insertions(+), 60 deletions(-) diff --git a/include/pd/ultra/container.hpp b/include/pd/ultra/container.hpp index 9f2156e..5b47ec8 100644 --- a/include/pd/ultra/container.hpp +++ b/include/pd/ultra/container.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace PD { @@ -11,14 +12,18 @@ class Container { Container(const PD::Li::Rect& r) : pRect(r) {} virtual ~Container() {} - void Push(PD::Ultra::ElementBase* elem) { - elem->SetParent(this); - pElems.Push(elem); + void Push(PD::Ultra::ElementBase& elem) { + elem.SetParent(this); + pElems.Push(&elem); } void Reset() { pElems.ResetFast(); } const PD::Li::Rect& GetRenderspace() const { return pRect; } - void SetViewport(const PD::fvec2& vp) { pRect = PD::fvec4(PD::fvec2(0), vp); } + void SetViewport(const PD::fvec2& vp) { + pCanvas.SetViewport(vp); + pRect = PD::fvec4(PD::fvec2(0), vp); + } + void SetBaseViewport(const PD::ivec2& vp) { pCanvas.SetVirtualViewport(vp); } const PD::fvec2 GetTopLeft() const { return pRect.TopLeft(); } const PD::fvec2 GetTopRight() const { return pRect.TopRight(); } @@ -26,12 +31,14 @@ class Container { const PD::fvec2 GetBotRight() const { return pRect.BotRight(); } const PD::fvec2 GetSize() const { return pRect.BotRight() - pRect.TopLeft(); } const PD::fvec2 GetPosition() const { return pRect.TopLeft(); } + const Canvas& GetCanvas() const { return pCanvas; } protected: PD::Pool& GetElements() { return pElems; } private: PD::Li::Rect pRect; + Canvas pCanvas; PD::Pool pElems; }; } // namespace Ultra diff --git a/include/pd/ultra/elems/element.hpp b/include/pd/ultra/elems/element.hpp index 55cdaba..e186ee6 100644 --- a/include/pd/ultra/elems/element.hpp +++ b/include/pd/ultra/elems/element.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -7,6 +8,7 @@ namespace PD { namespace Ultra { class Canvas; class Container; +using EventFunc = std::function; class PD_API ElementBase { public: ElementBase() {} @@ -17,24 +19,36 @@ class PD_API ElementBase { * Reset Function (for PD::Pool::FastReset) */ virtual void Reset() {} - void Update(); + virtual void Update(); void SetAlignment(UltraAlignment a) { pAlignment = a; } void SetPosition(const PD::fvec2& pos) { pPos = pos; } void SetPosition(float x, float y) { pPos = PD::fvec2(x, y); } void SetSize(const PD::fvec2& size) { pSize = size; } void SetSize(float w, float h) { pSize = PD::fvec2(w, h); } + /** + * Executed every frame + * Elemnents can override / discard this func + */ + virtual void OnHover(EventFunc func) { pHover = func; } + /** + * Executrd on KeyUp event + * Elemnents can override / discard this func + */ + virtual void OnPress(EventFunc func) { pPress = func; } protected: friend class Container; void SetParent(Container* c) { pParent = c; } bool RevisionUpdate(PD::u32 req); - Container* pParent; + Container* pParent = nullptr; PD::u32 pCanvasRev = 0; UltraAlignment pAlignment = 0; PD::fvec2 pPos; PD::fvec2 pSize; PD::Li::Rect pRenderspace; + EventFunc pHover = nullptr; + EventFunc pPress = nullptr; }; } // namespace Ultra } // namespace PD \ No newline at end of file diff --git a/include/pd/ultra/elems/text.hpp b/include/pd/ultra/elems/text.hpp index 0eff46e..148dd01 100644 --- a/include/pd/ultra/elems/text.hpp +++ b/include/pd/ultra/elems/text.hpp @@ -11,13 +11,18 @@ class PD_API Text : public ElementBase { ~Text() {} void Draw(PD::Li::Drawlist& l) override; + void Update() override; void SetColor(const PD::Color& color) { pColor = color; } void SetText(const std::string& text) { pText = text; } + void SetFont(PD::Li::Font& font) { pFont = &font; } + void SetScale(float scale) { pScale = scale; } private: PD::Color pColor; + float pScale = 1.f; std::string pText; + PD::Li::Font* pFont = nullptr; }; } // namespace Ultra diff --git a/include/pd/ultra/layout.hpp b/include/pd/ultra/layout.hpp index b0e590a..df665c0 100644 --- a/include/pd/ultra/layout.hpp +++ b/include/pd/ultra/layout.hpp @@ -11,14 +11,7 @@ class PD_API Layout : public Container { Layout() {} ~Layout() {} - void SetFont(PD::Li::Font& font); - - void Render(); - - const PD::Li::Drawlist& Data() const { return pList; } - - private: - PD::Li::Drawlist pList; + void Render(PD::Li::Drawlist& list); }; } // namespace Ultra } // namespace PD \ No newline at end of file diff --git a/source/ultra/elems/element.cpp b/source/ultra/elems/element.cpp index 14b3068..b86fc8b 100644 --- a/source/ultra/elems/element.cpp +++ b/source/ultra/elems/element.cpp @@ -13,8 +13,10 @@ PD_API bool ElementBase::RevisionUpdate(PD::u32 req) { } PD_API void ElementBase::Update() { if (!pParent) pRenderspace = PD::fvec4(pPos, pPos + pSize); - pRenderspace = PD::fvec4(pParent->GetTopLeft() + pPos, - pParent->GetTopLeft() + pPos + pSize); + pRenderspace = pParent->GetCanvas().VTranslateObject( + pParent->GetTopLeft() + pPos, pSize, pAlignment); + /*pRenderspace = PD::fvec4(pParent->GetTopLeft() + pPos, + pParent->GetTopLeft() + pPos + pSize);*/ } } // namespace Ultra } // namespace PD \ No newline at end of file diff --git a/source/ultra/elems/text.cpp b/source/ultra/elems/text.cpp index 5680967..08472d1 100644 --- a/source/ultra/elems/text.cpp +++ b/source/ultra/elems/text.cpp @@ -1,9 +1,22 @@ +#include #include namespace PD { namespace Ultra { PD_API void Text::Draw(PD::Li::Drawlist& l) { + if (!pFont) return; + l.SetFont(pFont); l.DrawText(pRenderspace.TopLeft(), pText.c_str(), pColor); } + +PD_API void Text::Update() { + if (!pFont) return; + if (!pParent) ElementBase::Update(); + pRenderspace = pParent->GetCanvas().VTranslateObject( + pParent->GetTopLeft() + pPos, + pFont->GetTextBounds(pText.c_str(), + pParent->GetCanvas().VTranslateFontscale(pScale)), + pAlignment, true); +} } // namespace Ultra } // namespace PD \ No newline at end of file diff --git a/source/ultra/layout.cpp b/source/ultra/layout.cpp index 07c916b..737c25e 100644 --- a/source/ultra/layout.cpp +++ b/source/ultra/layout.cpp @@ -3,17 +3,16 @@ namespace PD { namespace Ultra { -PD_API void Layout::SetFont(PD::Li::Font& font) { pList.SetFont(&font); } - -PD_API void Layout::Render() { - pList.Clear(); +PD_API void Layout::Render(PD::Li::Drawlist& list) { + float fc = list.GetFontScale(); + list.SetFontscale(GetCanvas().VTranslateFontscale(fc)); for (auto& it : GetElements()) { it->Update(); - it->Draw(pList); + it->Draw(list); } - pList.DrawText(PD::fvec2(5, GetBotLeft().y - 40), - std::format("Lyt: [{}]", GetRenderspace()).c_str(), - 0xffff00ff); + list.DrawText(PD::fvec2(5, GetBotLeft().y - 40), + std::format("Lyt: [{}]", GetRenderspace()).c_str(), 0xffff00ff); + list.SetFontscale(fc); } } // namespace Ultra } // namespace PD \ No newline at end of file diff --git a/tests/gfx/source/main.cpp b/tests/gfx/source/main.cpp index 04e6095..bcc43cb 100644 --- a/tests/gfx/source/main.cpp +++ b/tests/gfx/source/main.cpp @@ -22,6 +22,43 @@ const char* ResourcePath(const char* in) { #endif } +class MainMenu : public PD::Ultra::Layout { + public: + MainMenu(PD::Li::Font& font) { + SetBaseViewport(PD::ivec2(1280, 720)); + pBackground.SetSize(800, 450); + pBackground.SetColor(PD::Color("#ffffffff")); + pBackground.SetAlignment(UltraAlignment_CenterHorizontal | + UltraAlignment_CenterVertical); + Push(pBackground); + pText.SetColor(PD::Color("#000000")); + pText.SetText("Hello World"); + pText.SetAlignment(UltraAlignment_CenterHorizontal | + UltraAlignment_CenterVertical); + pText.SetFont(font); + Push(pText); + } + ~MainMenu() {} + + private: + PD::Ultra::Rect pBackground; + PD::Ultra::Text pText; +}; + +class App { + public: + App(PD::Li::Font& font) : main(font) {} + ~App() {} + + void Update(PD::ivec2 vp, PD::Li::Drawlist& list) { + main.SetViewport(vp); + main.Render(list); + } + + private: + MainMenu main; +}; + int main(int argc, char** argv) { // PD::LogFilter(PD::LogLevel::Warning); Driver drv = Driver::OpenGL3; @@ -49,46 +86,13 @@ int main(int argc, char** argv) { PD::Li::Font font; font.LoadTTF(ResourcePath("default.ttf"), 64); pList.SetFont(&font); - PD::Ultra::Layout lyt; - lyt.SetViewport(PD::fvec2(1280, 720)); - lyt.SetFont(font); - PD::Ultra::Rect r; - r.SetColor(0xff0000ff); - r.SetRounding(10.f); - r.SetLined(true); - r.SetPosition(250, 150); - r.SetSize(100, 70); - PD::Ultra::Rect rr; - rr.SetColor(0x880000ff); - rr.SetRounding(10.f); - rr.SetPosition(250, 150); - rr.SetSize(100, 70); - lyt.Push(&rr); - lyt.Push(&r); - PD::Ultra::Text txt; - txt.SetPosition(PD::fvec2(5, 200)); - txt.SetText("OpenGL"); - txt.SetColor(PD::Color("#ffffffff")); - lyt.Push(&txt); + App app(font); while (pOs->Mainloop()) { pOs->ClearViewPort(); - lyt.SetViewport(pOs->GetViewport()); - PD::Li::ResetPools(); - pList.DrawRectFilled(150, 50, 0x88ffffff); - pList.DrawRect(150, 50, 0xffffffff); - lyt.Render(); - pList.DrawText( - 5, - std::format( - "Font Scale: {}\nVP: [{}]\nVIDC: [{}, {}, {}, {}]\nGfxDriver: {}", - pList.GetFontScale(), pOs->GetViewport(), PD::Gfx::GetNumVertices(), - PD::Gfx::GetNumIndices(), PD::Gfx::GetNumDrawcalls(), - PD::Gfx::GetNumCommands(), PD::Gfx::GetDriverName()) - .c_str(), - 0xffffffff); + PD::Li::ResetPools(); // Move to other place (or refactor this) + app.Update(pOs->GetViewport(), pList); PD::Gfx::Reset(); PD::Gfx::Draw(pList); - PD::Gfx::Draw(lyt.Data()); pList.Clear(); pOs->SwapBuffers(); }