From 09b1937a8d70a862352c07666fd00d723a94350f Mon Sep 17 00:00:00 2001 From: tobid7 Date: Sat, 8 Mar 2025 13:52:11 +0100 Subject: [PATCH] # Changes 0.2.8 - Fix Flickering problem in StaticText api - Fix Lagacy and Container HandleScrolling InBox checks - Add IO Flags define for future - Implement Single Object Dragging API by IO Context - Add TreeNodes - Use ioMenuPadding and ItemSpace - Add StyleEditorMenu - Rework ContainerApi to take functions from IO and add an Update function template for Updating internal values if required - Use new DragApi for MenuCollabse, MenuDragging, MenuResize, SliderDragging and TreeNodes Open/Close - Add Helper Defines for Metrics Menu [INTERNAL] - Add TimeTrace as Tree to Metrics as well as other new Data - Add GetRawObject to StaticText for custom rendering like ui7 - Add DrawlistRegestry to correctly render Menus in their own layer ranges --- CMakeLists.txt | 3 +- README.md | 2 +- include/pd/lithium/objects.hpp | 3 + include/pd/ui7/container/button.hpp | 20 +- include/pd/ui7/container/checkbox.hpp | 25 ++- include/pd/ui7/container/container.hpp | 18 +- include/pd/ui7/container/image.hpp | 6 +- include/pd/ui7/container/label.hpp | 12 +- include/pd/ui7/flags.hpp | 9 + include/pd/ui7/io.hpp | 97 +++++++++- include/pd/ui7/menu.hpp | 39 ++-- include/pd/ui7/ui7.hpp | 50 +---- source/lithium/objects.cpp | 3 + source/ui7/container/button.cpp | 14 +- source/ui7/container/checkbox.cpp | 20 +- source/ui7/container/container.cpp | 3 +- source/ui7/container/image.cpp | 4 +- source/ui7/container/label.cpp | 7 +- source/ui7/drawlist.cpp | 34 ++-- source/ui7/io.cpp | 34 ++++ source/ui7/menu.cpp | 246 ++++++++++++++----------- source/ui7/ui7.cpp | 153 ++++++++++++--- 22 files changed, 536 insertions(+), 266 deletions(-) create mode 100644 source/ui7/io.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f946bb3..c95e0c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,7 @@ execute_process( ) # Set Project -project(palladium LANGUAGES C CXX VERSION 0.2.7) +project(palladium LANGUAGES C CXX VERSION 0.2.8) option(PD_BUILD_TESTS "Sets if TestApp and TestBench get build" OFF) @@ -130,6 +130,7 @@ source/app/error.cpp) ## UI7 Source Code set(UI7_SRC source/ui7/drawlist.cpp +source/ui7/io.cpp source/ui7/menu.cpp source/ui7/theme.cpp source/ui7/ui7.cpp diff --git a/README.md b/README.md index 92c8fc5..3a4b3a5 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ make install | pd-lithium | 0.2.7 | 3ds | pd-core, pd-image pd-lib3ds, citro3d | | pd-sound | 0.2.4 | 3ds | pd-core, mpg123 | | pd-overlays | 0.2.4 | 3ds | pd-core, pd-image, pd-lib3ds, pd-lithium, pd-ui7 | -| pd-ui7 | 0.2.7 | 3ds | pd-core, pd-image, pd-lib3ds, pd-lithium | +| pd-ui7 | 0.2.8 | 3ds | pd-core, pd-image, pd-lib3ds, pd-lithium | | pd-app | 0.2.4 | 3ds | pd-core, pd-image, pd-lib3ds, pd-lithium | ## Credits diff --git a/include/pd/lithium/objects.hpp b/include/pd/lithium/objects.hpp index d052366..13f70af 100644 --- a/include/pd/lithium/objects.hpp +++ b/include/pd/lithium/objects.hpp @@ -305,6 +305,9 @@ class StaticText : public SmartCtor { */ void Draw(); + /** Get the Raw Object for Custom API's */ + StaticObject::Ref GetRawObject() { return text; } + /** * Set Font used by the static Text * @param fnt Font used diff --git a/include/pd/ui7/container/button.hpp b/include/pd/ui7/container/button.hpp index 8ec8ac4..31514bd 100644 --- a/include/pd/ui7/container/button.hpp +++ b/include/pd/ui7/container/button.hpp @@ -24,6 +24,7 @@ SOFTWARE. */ #include +#include namespace PD { namespace UI7 { @@ -42,13 +43,9 @@ class Button : public Container { * @param pos Base Position * @param lr Reference to the Renderer */ - Button(const std::string& label, vec2 pos, LI::Renderer::Ref lr) { - this->screen = lr->CurrentScreen(); + Button(const std::string& label, UI7::IO::Ref io) { this->label = label; - this->SetPos(pos); - this->tdim = lr->GetTextDimensions(label); - color = UI7Color_Button; - this->SetSize(tdim + vec2(8, 4)); + this->tdim = io->Ren->GetTextDimensions(label); } ~Button() = default; @@ -66,11 +63,14 @@ class Button : public Container { * */ void Draw() override; + /** Function to Update Size if framepadding changes */ + void Update() override; + private: - vec2 tdim; ///< Text size - UI7Color color; ///< current button color - std::string label; ///< Label of the Button - bool pressed = false; ///< ispressed value + vec2 tdim; ///< Text size + UI7Color color = UI7Color_Button; ///< current button color + std::string label; ///< Label of the Button + bool pressed = false; ///< ispressed value }; } // namespace UI7 } // namespace PD \ No newline at end of file diff --git a/include/pd/ui7/container/checkbox.hpp b/include/pd/ui7/container/checkbox.hpp index 556e90c..363a2a3 100644 --- a/include/pd/ui7/container/checkbox.hpp +++ b/include/pd/ui7/container/checkbox.hpp @@ -38,19 +38,13 @@ class Checkbox : public Container { /** * Constructor for Checkbox Object * @param label Label of the Checkbox - * @param pos Base Position * @param usr_ref Reference to the bool value to update - * @param lr Reference to the renderer (for text size calculation) + * @param io IO Reference */ - Checkbox(const std::string& label, vec2 pos, bool& usr_ref, - LI::Renderer::Ref lr) + Checkbox(const std::string& label, bool& usr_ref, UI7::IO::Ref io) : usr_ref(usr_ref) { - this->screen = lr->CurrentScreen(); this->label = label; - this->SetPos(pos); - this->tdim = lr->GetTextDimensions(label); - color = UI7Color_FrameBackground; - this->SetSize(cbs + vec2(tdim.x() + 5, 0)); + this->tdim = io->Ren->GetTextDimensions(label); } ~Checkbox() = default; /** @@ -65,12 +59,15 @@ class Checkbox : public Container { * */ void Draw() override; + /** Update Size if framepadding changed */ + void Update() override; + private: - vec2 tdim; ///< Text Size - vec2 cbs = vec2(18); ///< Checkbox size - UI7Color color; ///< Checkbox background Color - std::string label; ///< Checkbox Label - bool& usr_ref; ///< User bool reference + vec2 tdim; ///< Text Size + vec2 cbs = vec2(18); ///< Checkbox size + UI7Color color = UI7Color_FrameBackground; ///< Checkbox background Color + std::string label; ///< Checkbox Label + bool& usr_ref; ///< User bool reference }; } // namespace UI7 } // namespace PD \ No newline at end of file diff --git a/include/pd/ui7/container/container.hpp b/include/pd/ui7/container/container.hpp index b1ddae5..31cb550 100644 --- a/include/pd/ui7/container/container.hpp +++ b/include/pd/ui7/container/container.hpp @@ -28,6 +28,7 @@ SOFTWARE. #include #include #include +#include namespace PD { namespace UI7 { @@ -54,14 +55,13 @@ class Container : public SmartCtor { /** * Init Function Required by every Object that uses * Render or Input functions - * @param r Renderer Reference + * @param io IO Reference * @param l DrawList Reference - * @param lt Theme Reference */ - void Init(LI::Renderer::Ref r, UI7::DrawList::Ref l, UI7::Theme::Ref lt) { + void Init(UI7::IO::Ref io, UI7::DrawList::Ref l) { list = l; - theme = lt; - ren = r; + this->io = io; + this->screen = io->Ren->CurrentScreen(); } /** Setter for Position */ @@ -106,6 +106,8 @@ class Container : public SmartCtor { virtual void HandleInput(Hid::Ref inp) {} /** Tamplate function for Object rendering */ virtual void Draw() {} + /** Template function to update internal data (if needed) */ + virtual void Update() {} /** * Function to unlock Input after Rendering is done in @@ -140,10 +142,8 @@ class Container : public SmartCtor { vec2 size; /** Reference to the Drawlist to Draw to*/ UI7::DrawList::Ref list; - /** Reference to the theme to use*/ - UI7::Theme::Ref theme; - /** Reference to the Renderer*/ - LI::Renderer::Ref ren; + /** IO Reference for Renderer and Theme */ + UI7::IO::Ref io; /** Reference to the parent container*/ Container::Ref parent; /** Object ID (0 if unused)*/ diff --git a/include/pd/ui7/container/image.hpp b/include/pd/ui7/container/image.hpp index 6991719..784b6bf 100644 --- a/include/pd/ui7/container/image.hpp +++ b/include/pd/ui7/container/image.hpp @@ -35,14 +35,10 @@ class Image : public Container { /** * Constructor for the Image Object * @param img Image Texture Reference - * @param pos Base Position - * @param lr Renderer Reference [to determinate screen] * @param size Custom Size of the Image */ - Image(Texture::Ref img, vec2 pos, LI::Renderer::Ref lr, vec2 size = 0.f) { - this->screen = lr->CurrentScreen(); + Image(Texture::Ref img, vec2 size = 0.f) { this->img = img; - this->SetPos(pos); this->newsize = size; if (size.x() != 0 || size.y() != 0) { this->SetSize(size); diff --git a/include/pd/ui7/container/label.hpp b/include/pd/ui7/container/label.hpp index e5e8880..6e3caee 100644 --- a/include/pd/ui7/container/label.hpp +++ b/include/pd/ui7/container/label.hpp @@ -35,15 +35,11 @@ class Label : public Container { /** * Constructor for Label Object * @param label Label [Text] to Draw - * @param pos Base Position * @param lr Renderer Reference */ - Label(const std::string& label, vec2 pos, LI::Renderer::Ref lr) { - this->screen = lr->CurrentScreen(); + Label(const std::string& label, LI::Renderer::Ref lr) { this->label = label; - this->SetPos(pos); this->tdim = lr->GetTextDimensions(label); - color = UI7Color_Text; this->SetSize(tdim); } ~Label() = default; @@ -55,9 +51,9 @@ class Label : public Container { void Draw() override; private: - vec2 tdim; ///< Text Size - UI7Color color; ///< Color - std::string label; ///< Text to Render + vec2 tdim; ///< Text Size + UI7Color color = UI7Color_Text; ///< Color + std::string label; ///< Text to Render }; } // namespace UI7 } // namespace PD \ No newline at end of file diff --git a/include/pd/ui7/flags.hpp b/include/pd/ui7/flags.hpp index fd869cd..ebaab76 100644 --- a/include/pd/ui7/flags.hpp +++ b/include/pd/ui7/flags.hpp @@ -27,6 +27,8 @@ SOFTWARE. using UI7MenuFlags = unsigned int; /** 32Bit Value to store Alignment Flags */ using UI7Align = unsigned int; +/** 32Bit Value to store Context (IO) flags */ +using UI7IOFlags = unsigned int; /** Menu Flags */ enum UI7MenuFlags_ { @@ -44,6 +46,13 @@ enum UI7MenuFlags_ { UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling, }; +/** UI7 Context Flags */ +enum UI7IOFlags_ { + UI7IOFlags_None = 0, ///< No Additional Config available + UI7IOFlags_HasTouch = 1 << 0, ///< Enable touch support [future] + UI7IOFlags_HasMouseCursor = 1 << 1, ///< Enable Mouse support [future] +}; + /** Probably need to update this */ enum UI7Align_ { UI7Align_Left = 1 << 0, ///< [Hz Op] Align Left (Default) diff --git a/include/pd/ui7/io.hpp b/include/pd/ui7/io.hpp index ba5559f..6fbcfba 100644 --- a/include/pd/ui7/io.hpp +++ b/include/pd/ui7/io.hpp @@ -25,9 +25,10 @@ SOFTWARE. #include #include +#include #include #include -#include +#include #include namespace PD { @@ -40,21 +41,111 @@ class IO : public SmartCtor { /** * IO Constructor setting UP References */ - IO(Hid::Ref input_driver) { + IO(Hid::Ref input_driver, LI::Renderer::Ref ren) { Time = Timer::New(); + DragTime = Timer::New(false); Theme = UI7::Theme::New(); Inp = input_driver; + Ren = ren; + Back = UI7::DrawList::New(Ren); + Front = UI7::DrawList::New(Ren); + DrawListRegestry["CtxBackList"] = Back; + DrawListRegestry["CtxFrontList"] = Front; + DeltaStats = TimeStats::New(60); }; ~IO() = default; + /** + * IO Update Internal Variables + */ + void Update(); + float Framerate = 0.f; float Delta = 0.f; + TimeStats::Ref DeltaStats; Timer::Ref Time; Hid::Ref Inp; + LI::Renderer::Ref Ren; UI7::Theme::Ref Theme; - float MenuPadding = 5.f; + vec2 MenuPadding = 5.f; + vec2 FramePadding = 5.f; + vec2 ItemSpace = vec2(5.f, 2.f); + std::map DrawListRegestry; DrawList::Ref Back; DrawList::Ref Front; + + // Layer Rules + int ContextBackLayer = 10; + int MenuBackLayer = 20; + int MenuMainLayer = 30; + int MenuFrontLayer = 40; + int ContextFrontLayer = 50; + + // DrawListApi + void RegisterDrawList(const UI7::ID& id, DrawList::Ref v) { + DrawListRegestry[id] = v; + } + + // Input API + + u32 DraggedObject = 0; + vec2 DragSourcePos = 0; + vec2 DragPosition = 0; + vec2 DragLastPosition = 0; + vec4 DragDestination = 0; + Timer::Ref DragTime; + bool DragReleased = false; + /** Check if an object is Dragged already */ + bool IsObjectDragged() const { return DraggedObject != 0; } + /** + * Function to Check if current Object is dragged + * or set it dragged + * @param id ID to identify this specific Object + * @param area Area where to start dragging + * @return if inputs to this objects are alowed or not + */ + bool DragObject(const UI7::ID& id, vec4 area) { + if (IsObjectDragged()) { + // Only block if the Dragged Object has a difrent id + if (DraggedObject != id) { + return false; + } + } + // Get a Short define for touch pos + vec2 p = Inp->TouchPos(); + // Check if Drag starts in the area position + if (Inp->IsDown(Inp->Touch) && Ren->InBox(p, area)) { + // Set ID and iniatial Positions + DraggedObject = id; + DragSourcePos = p; + DragPosition = p; + DragLastPosition = p; + DragDestination = area; + // Reset and Start DragTimer + DragTime->Reset(); + DragTime->Rseume(); + return false; // To make sure the Object is "Dragged" + } else if (Inp->IsHeld(Inp->Touch) && IsObjectDragged()) { + // Update DragLast and DragPoisition + DragLastPosition = DragPosition; + DragPosition = p; + } else if (Inp->IsUp(Inp->Touch) && IsObjectDragged()) { + // Released... Everything gets reset + DraggedObject = 0; + DragPosition = 0; + DragSourcePos = 0; + DragLastPosition = 0; + DragDestination = 0; + DragReleased = true; // Set Drag released to true (only one frame) + // Ensure timer is paused + DragTime->Pause(); + DragTime->Reset(); + // Still return The Object is Dragged to ensure + // the DragReleased var can be used + return true; + } + return IsObjectDragged(); + } }; } // namespace UI7 } // namespace PD \ No newline at end of file diff --git a/include/pd/ui7/menu.hpp b/include/pd/ui7/menu.hpp index 842498b..6740556 100644 --- a/include/pd/ui7/menu.hpp +++ b/include/pd/ui7/menu.hpp @@ -29,6 +29,7 @@ SOFTWARE. #include #include #include +#include namespace PD { namespace UI7 { @@ -38,13 +39,11 @@ class Menu : public SmartCtor { /** * Menu COnstructor (Unly used by UI7::Context) * @param id ID of the Menu - * @param tl Theme Reference - * @param h Input Driver Reference + * @param io IO Config Reference */ - Menu(ID id, Theme::Ref tl, Hid::Ref h) { + Menu(ID id, UI7::IO::Ref io) { /// Setup the Input Data - theme = tl; - this->inp = h; + this->io = io; this->id = id; this->name = id.GetName(); /// Set Default Values here @@ -85,6 +84,17 @@ class Menu : public SmartCtor { // Basic API + /** + * Create a Tree Node + * @param id String ID of the Node + * @return node open or not + */ + bool BeginTreeNode(const UI7::ID& id); + /** + * End a Tree Node + */ + void EndTreeNode(); + /** Add the Next Objext to the same line */ void SameLine(); /** Add a Separator Line */ @@ -133,14 +143,20 @@ class Menu : public SmartCtor { * Returns a Reference to the theme * @return Reference to the base Theme of the context */ - Theme::Ref GetTheme() { return theme; } + Theme::Ref GetTheme() { return io->Theme; } /** * Directly return a Color by using the * m->ThemeColor(UI7Color_Text) for example * @param clr The Input UI7 Color * @return The 32bit color value */ - u32 ThemeColor(UI7Color clr) const { return theme->Get(clr); } + u32 ThemeColor(UI7Color clr) const { return io->Theme->Get(clr); } + + /** + * Get IO Reference + * @return io Reference + */ + UI7::IO::Ref GetIO() { return io; } // API for Custom Objects @@ -188,7 +204,7 @@ class Menu : public SmartCtor { * Init the Cursor * @note Useful when using with a Custom TitlebarHeight */ - void CursorInit() { Cursor(vec2(5, tbh + 5)); } + void CursorInit() { Cursor(io->MenuPadding + vec2(0, tbh)); } /** * Move the Cursor for new Object * @param szs Size of the current Object @@ -345,6 +361,7 @@ class Menu : public SmartCtor { u32 id; ///< Menu ID std::string name; ///< Menu Name vec2 cursor; ///< Current Cursor Position + vec2 icursoroff; ///< Initial Cursor Offset (Also in Newline) vec2 bcursor; ///< Backup Cursor vec2 slcursor; ///< Sameline Cursor vec4 view_area; ///< view Area (Position and Size) @@ -379,11 +396,9 @@ class Menu : public SmartCtor { vec2 bslpos; ///< Before Sameline Position vec2 last_size; ///< Last Object Size - // Theme - Theme::Ref theme; + UI7::IO::Ref io; ///< IO Reference - // Input Reference - Hid::Ref inp; + std::map tree_nodes; ///< Map of Tree nodes // Animations System diff --git a/include/pd/ui7/ui7.hpp b/include/pd/ui7/ui7.hpp index 4855d6c..a249e07 100644 --- a/include/pd/ui7/ui7.hpp +++ b/include/pd/ui7/ui7.hpp @@ -37,7 +37,7 @@ SOFTWARE. * Major Minor Patch Build * 0x01010000 -> 1.1.0-0 */ -#define UI7_VERSION 0x00020702 +#define UI7_VERSION 0x00020800 namespace PD { namespace UI7 { @@ -57,14 +57,7 @@ class Context : public SmartCtor { */ Context(LI::Renderer::Ref ren, Hid::Ref hid) { /// Set the Internal References - this->ren = ren; - this->inp = hid; - io = IO::New(hid); - /// Init Theme and Front / Back Drawlists - theme = Theme::New(); - back = DrawList::New(ren); - front = DrawList::New(ren); - s_delta = TimeStats::New(60); + io = IO::New(hid, ren); } ~Context() = default; @@ -97,14 +90,14 @@ class Context : public SmartCtor { * Get Theme reference * @return Reference to the base Theme of the context */ - Theme::Ref GetTheme() { return theme; } + Theme::Ref GetTheme() { return io->Theme; } /** *Directly return a Color by using the * ctx->ThemeColor(UI7Color_Text) for example * @param clr The Input UI7 Color * @return The 32bit color value */ - u32 ThemeColor(UI7Color clr) const { return theme->Get(clr); } + u32 ThemeColor(UI7Color clr) const { return io->Theme->Get(clr); } /** * Update Context (Render menus) @@ -115,9 +108,9 @@ class Context : public SmartCtor { // Expose DrawLists /** Background DrawList Reference */ - DrawList::Ref BackList() { return back; } + DrawList::Ref BackList() { return io->Back; } /** Foreground DrawList Reference */ - DrawList::Ref FrontList() { return front; } + DrawList::Ref FrontList() { return io->Front; } /** * Set the Root Layer of the Menu @@ -138,41 +131,16 @@ class Context : public SmartCtor { /** Metrics */ void MetricsMenu(); + /** Style Editor Menu (Includes Theme Editor) */ + void StyleEditor(); + private: // Used in Overlays int root_layer = 0; - // Linked Renderer - LI::Renderer::Ref ren; - // Input Driver Reference - Hid::Ref inp; - // Delta time - float delta; - // Context Run Time - float time; - /// @brief Last Time [unused ?] - float last; - // In Menu [unused ?] - bool in_menu; - // Is Debugging [unused ?] - bool debugging; // Map of The Menus by ID std::unordered_map menus; std::vector amenus; ///< Active ones Menu::Ref current; ///< Current Menu - // Debug Drawlist - DrawList::Ref debug; - // Foreground Drawlist - DrawList::Ref front; - // Background Drawlist - DrawList::Ref back; - // Active Theme - Theme::Ref theme; - - // Metrics - - // Deltatime Average - TimeStats::Ref s_delta; - // IO IO::Ref io; }; diff --git a/source/lithium/objects.cpp b/source/lithium/objects.cpp index c790e2d..678d8e9 100644 --- a/source/lithium/objects.cpp +++ b/source/lithium/objects.cpp @@ -42,6 +42,9 @@ void StaticText::Setup(Renderer* ren, const vec2& pos, u32 clr, ren->TextCommand(this->text->List(), pos, clr, text, flags | LITextFlags_RenderOOS, box); Renderer::OptiCommandList(this->text->List()); + // Make sure to bring the text in edit mode + // Fixes flickering problems in ui7 + this->text->ReCopy(); } void StaticText::Draw() { diff --git a/source/ui7/container/button.cpp b/source/ui7/container/button.cpp index 22552b0..04d9d3a 100644 --- a/source/ui7/container/button.cpp +++ b/source/ui7/container/button.cpp @@ -48,12 +48,16 @@ void Button::HandleInput(Hid::Ref inp) { inp_done = true; } void Button::Draw() { - Assert(ren.get() && list.get() && theme, - "Did you run Container::Init correctly?"); - ren->OnScreen(screen); - list->AddRectangle(FinalPos(), size, theme->Get(color)); + Assert(io.get() && list.get(), "Did you run Container::Init correctly?"); + io->Ren->OnScreen(screen); + list->AddRectangle(FinalPos(), size, io->Theme->Get(color)); list->AddText(FinalPos() + size * 0.5 - tdim * 0.5, label, - theme->Get(UI7Color_Text)); + io->Theme->Get(UI7Color_Text)); +} + +void Button::Update() { + Assert(io.get(), "Did you run Container::Init correctly?"); + this->SetSize(tdim + io->FramePadding); } } // namespace UI7 } // namespace PD \ No newline at end of file diff --git a/source/ui7/container/checkbox.cpp b/source/ui7/container/checkbox.cpp index 353edd4..6c1025e 100644 --- a/source/ui7/container/checkbox.cpp +++ b/source/ui7/container/checkbox.cpp @@ -47,15 +47,21 @@ void Checkbox::HandleInput(Hid::Ref inp) { inp_done = true; } void Checkbox::Draw() { - Assert(ren.get() && list.get() && theme, - "Did you run Container::Init correctly?"); - ren->OnScreen(screen); - list->AddRectangle(FinalPos(), cbs, theme->Get(color)); + Assert(list.get() && io.get(), "Did you run Container::Init correctly?"); + io->Ren->OnScreen(screen); + list->AddRectangle(FinalPos(), cbs, io->Theme->Get(color)); if (usr_ref) { - list->AddRectangle(FinalPos() + 2, cbs - 4, theme->Get(UI7Color_Checkmark)); + list->AddRectangle(FinalPos() + 2, cbs - 4, + io->Theme->Get(UI7Color_Checkmark)); } - list->AddText(FinalPos() + vec2(cbs.x() + 5, cbs.y() * 0.5 - tdim.y() * 0.5), - label, theme->Get(UI7Color_Text)); + list->AddText(FinalPos() + vec2(cbs.x() + io->ItemSpace.x(), + cbs.y() * 0.5 - tdim.y() * 0.5), + label, io->Theme->Get(UI7Color_Text)); +} + +void Checkbox::Update() { + Assert(io.get(), "Did you run Container::Init correctly?"); + this->SetSize(cbs + vec2(tdim.x() + io->ItemSpace.x(), 0)); } } // namespace UI7 } // namespace PD \ No newline at end of file diff --git a/source/ui7/container/container.cpp b/source/ui7/container/container.cpp index 5791149..2a99b61 100644 --- a/source/ui7/container/container.cpp +++ b/source/ui7/container/container.cpp @@ -32,7 +32,8 @@ void Container::HandleScrolling(vec2 scrolling, vec4 viewport) { } last_use = Sys::GetTime(); pos -= vec2(0, scrolling.y()); - skippable = !LI::Renderer::InBox(pos, size, viewport); + skippable = !LI::Renderer::InBox( + pos, size, vec4(viewport.xy(), viewport.xy() + viewport.zw())); } } // namespace UI7 } // namespace PD \ No newline at end of file diff --git a/source/ui7/container/image.cpp b/source/ui7/container/image.cpp index 9157592..3567b70 100644 --- a/source/ui7/container/image.cpp +++ b/source/ui7/container/image.cpp @@ -26,9 +26,9 @@ SOFTWARE. namespace PD { namespace UI7 { void Image::Draw() { - Assert(ren.get() && list.get(), "Did you run Container::Init correctly?"); + Assert(io.get() && list.get(), "Did you run Container::Init correctly?"); Assert(img.get(), "Image is nullptr!"); - ren->OnScreen(screen); + io->Ren->OnScreen(screen); list->AddImage(FinalPos(), img, newsize); } } // namespace UI7 diff --git a/source/ui7/container/label.cpp b/source/ui7/container/label.cpp index e074198..83fabc9 100644 --- a/source/ui7/container/label.cpp +++ b/source/ui7/container/label.cpp @@ -26,10 +26,9 @@ SOFTWARE. namespace PD { namespace UI7 { void Label::Draw() { - Assert(ren.get() && list.get() && theme, - "Did you run Container::Init correctly?"); - ren->OnScreen(screen); - list->AddText(FinalPos(), label, theme->Get(UI7Color_Text)); + Assert(io.get() && list.get(), "Did you run Container::Init correctly?"); + io->Ren->OnScreen(screen); + list->AddText(FinalPos(), label, io->Theme->Get(UI7Color_Text)); } } // namespace UI7 } // namespace PD \ No newline at end of file diff --git a/source/ui7/drawlist.cpp b/source/ui7/drawlist.cpp index 152e504..504a804 100644 --- a/source/ui7/drawlist.cpp +++ b/source/ui7/drawlist.cpp @@ -68,27 +68,33 @@ void DrawList::AddText(vec2 pos, const std::string& text, const UI7Color& clr, return; } u32 id = Strings::FastHash(text); - auto e = static_text.find(id); - if (e == static_text.end()) { - static_text[id] = LI::StaticText::New(); - e = static_text.find(id); + LI::StaticText::Ref e; + auto f = static_text.find(id); + if (static_text.find(id) == static_text.end()) { + e = LI::StaticText::New(); + static_text[id] = e; + } else { + e = f->second; } - if (!e->second->IsSetup() || e->second->Font() != ren->Font()) { + if (!e->IsSetup() || e->Font() != ren->Font()) { int l = ren->Layer(); ren->Layer(base); - /// Probably a simple ren.get() would handle the job too - e->second->Setup(&(*ren), pos, clr, text, flags, box); - e->second->Font(ren->Font()); + e->Setup(ren.get(), pos, clr, text, flags, box); + e->Font(ren->Font()); ren->Layer(l); } - e->second->SetPos(pos); - e->second->SetColor(clr); - e->second->SetLayer(layer); + e->SetPos(pos); + e->SetColor(clr); + e->SetLayer(layer); if (!clip_rects.empty()) { - e->second->SetScissorMode(LI::ScissorMode_Normal); - e->second->ScissorRect(clip_rects.top()); + e->SetScissorMode(LI::ScissorMode_Normal); + e->ScissorRect(clip_rects.top()); } - e->second->Draw(); + for (auto it : e->GetRawObject()->List()) { + this->commands.push_back(std::make_pair( + ren->CurrentScreen()->ScreenType() == Screen::Bottom, it)); + } + e->GetRawObject()->ReCopy(); ////// STILL LEAVING THE OLD CODE BELOW AS IT IS MAYBE NEEDED ////// ////// IF STATIC TEXT SYSTEM SHOULD HAVE AN DISABLE OPTION ////// diff --git a/source/ui7/io.cpp b/source/ui7/io.cpp new file mode 100644 index 0000000..8c748d5 --- /dev/null +++ b/source/ui7/io.cpp @@ -0,0 +1,34 @@ +/* +MIT License +Copyright (c) 2024 - 2025 René Amthor (tobid7) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +#include +#include + +namespace PD { +void UI7::IO::Update() { + Time->Update(); + DragTime->Update(); + DragReleased = false; + Framerate = 1000.f / Delta; +} +} // namespace PD \ No newline at end of file diff --git a/source/ui7/menu.cpp b/source/ui7/menu.cpp index 0d479a7..7516055 100644 --- a/source/ui7/menu.cpp +++ b/source/ui7/menu.cpp @@ -28,11 +28,10 @@ SOFTWARE. namespace PD { namespace UI7 { void UI7::Menu::Label(const std::string& label) { - Container::Ref r = - ObjectPush(PD::New(label, Cursor(), this->back->ren)); - r->SetPos(AlignPos(r->GetPos(), r->GetSize(), view_area, GetAlignment())); + Container::Ref r = ObjectPush(PD::New(label, io->Ren)); + r->SetPos(AlignPos(Cursor(), r->GetSize(), view_area, GetAlignment())); CursorMove(r->GetSize()); - r->Init(main->ren, main, theme); + r->Init(io, main); r->HandleScrolling(scrolling_off, view_area); } @@ -41,12 +40,13 @@ bool UI7::Menu::Button(const std::string& label) { u32 id = Strings::FastHash("btn" + label + std::to_string(count_btn++)); Container::Ref r = FindIDObj(id); if (!r) { - r = PD::New(label, Cursor(), this->back->ren); + r = PD::New(label, io); r->SetID(id); - r->Init(main->ren, main, theme); + r->Init(io, main); } ObjectPush(r); r->SetPos(AlignPos(Cursor(), r->GetSize(), view_area, GetAlignment())); + r->Update(); CursorMove(r->GetSize()); r->HandleScrolling(scrolling_off, view_area); if (!r->Skippable()) { @@ -59,22 +59,22 @@ void UI7::Menu::Checkbox(const std::string& label, bool& v) { u32 id = Strings::FastHash("cbx" + label + std::to_string(count_cbx++)); Container::Ref r = FindIDObj(id); if (!r) { - r = PD::New(label, Cursor(), v, this->back->ren); + r = PD::New(label, v, io); r->SetID(id); - r->Init(main->ren, main, theme); + r->Init(io, main); } ObjectPush(r); r->SetPos(AlignPos(Cursor(), r->GetSize(), view_area, GetAlignment())); + r->Update(); CursorMove(r->GetSize()); r->HandleScrolling(scrolling_off, view_area); } void UI7::Menu::Image(Texture::Ref img, vec2 size) { - Container::Ref r = - ObjectPush(PD::New(img, Cursor(), this->back->ren, size)); - r->SetPos(AlignPos(r->GetPos(), r->GetSize(), view_area, GetAlignment())); + Container::Ref r = ObjectPush(PD::New(img, size)); + r->SetPos(AlignPos(Cursor(), r->GetSize(), view_area, GetAlignment())); CursorMove(r->GetSize()); - r->Init(main->ren, main, theme); + r->Init(io, main); r->HandleScrolling(scrolling_off, view_area); } @@ -120,8 +120,9 @@ void UI7::Menu::Update(float delta) { scrolling_off = scroll_anim; } if (!(flags & UI7MenuFlags_NoClipRect)) { - main->PushClipRect(vec4(view_area.x() + 5, view_area.y() + tbh, - view_area.x() + view_area.z() - 12, + main->PushClipRect(vec4(view_area.x() + io->MenuPadding[0], + view_area.y() + tbh, + view_area.x() + view_area.z() - io->MenuPadding[0], view_area.y() + view_area.w())); } std::vector tbr; @@ -132,7 +133,7 @@ void UI7::Menu::Update(float delta) { } if (!it->Skippable()) { if (scroll_mod[1] == 0.f) { - it->HandleInput(inp); + it->HandleInput(io->Inp); } /// Unlock Input after to ensure nothing is checked twice it->UnlockInput(); @@ -150,20 +151,18 @@ void UI7::Menu::Update(float delta) { if (!(flags & UI7MenuFlags_NoClipRect)) { main->PopClipRect(); } - this->back->Process(); - this->main->Process(); - this->front->Process(); this->objects.clear(); } void UI7::Menu::CursorMove(const vec2& size) { last_size = size; - slcursor = cursor + vec2(size[0] + 5, 0); + slcursor = cursor + vec2(size[0] + io->ItemSpace[0], 0); if (bslpos[1]) { - cursor = vec2(5, cursor[1] + bslpos[1] + 5); + cursor = vec2(io->MenuPadding[0], cursor[1] + bslpos[1] + io->ItemSpace[1]); bslpos = vec2(); } else { - cursor = vec2(5, cursor[1] + size[1] + 5); + cursor = vec2(io->MenuPadding[0] + icursoroff[0], + cursor[1] + size[1] + io->ItemSpace[1]); } max = vec2(slcursor[0], cursor[1]); } @@ -183,26 +182,24 @@ void UI7::Menu::PreHandler(UI7MenuFlags flags) { if (!(flags & UI7MenuFlags_NoBackground) && is_open) { back->AddRectangle(view_area.xy() + vec2(0, tbh), view_area.zw() - vec2(0, tbh), - theme->Get(UI7Color_Background)); + io->Theme->Get(UI7Color_Background)); } if (!(flags & UI7MenuFlags_NoTitlebar)) { // Title bar setup and Rendering tbh = front->ren->TextScale() * 30.f; front->AddRectangle(view_area.xy(), vec2(view_area.z(), tbh), - theme->Get(UI7Color_Header)); - vec2 tpos(5, tbh * 0.5 - front->ren->GetTextDimensions(name).y() * 0.5); + io->Theme->Get(UI7Color_Header)); + vec2 tpos(io->MenuPadding[0], + tbh * 0.5 - front->ren->GetTextDimensions(name).y() * 0.5); if (!(flags & UI7MenuFlags_NoCollapse)) { tpos.x() += 18; - vec2 cpos = view_area.xy() + 5; + vec2 cpos = view_area.xy() + io->FramePadding; UI7Color clr = UI7Color_FrameBackground; - if (inp->IsUp(inp->Touch) && - LI::Renderer::InBox(inp->TouchPosLast(), vec4(cpos, vec2(18, tbh))) && - has_touch) { - is_open = !is_open; - } - if (inp->IsHeld(inp->Touch) && - LI::Renderer::InBox(inp->TouchPos(), vec4(cpos, vec2(18, tbh))) && - has_touch) { + if (has_touch && + io->DragObject(UI7::ID(name + "clbse"), vec4(cpos, vec2(18, tbh)))) { + if (io->DragReleased) { + is_open = !is_open; + } clr = UI7Color_FrameBackgroundHovered; } vec2 positions[2] = { @@ -215,7 +212,7 @@ void UI7::Menu::PreHandler(UI7MenuFlags flags) { positions[1].x() = t; } this->front->AddTriangle(cpos, cpos + positions[0], cpos + positions[1], - theme->Get(clr)); + io->Theme->Get(clr)); } LITextFlags tflags = LITextFlags_None; if (flags & UI7MenuFlags_CenterTitle) { @@ -223,39 +220,27 @@ void UI7::Menu::PreHandler(UI7MenuFlags flags) { tflags = LITextFlags_AlignMid; } front->Layer(front->Layer() + 1); - front->AddText(view_area.xy() + tpos, this->name, theme->Get(UI7Color_Text), - tflags, vec2(view_area.z(), tbh)); + front->AddText(view_area.xy() + tpos, this->name, + io->Theme->Get(UI7Color_Text), tflags, + vec2(view_area.z(), tbh)); main_area[1] = tbh; CursorInit(); // Menu Movement if (!(flags & UI7MenuFlags_NoMove)) { - if (inp->IsDown(inp->Touch) && - LI::Renderer::InBox( - inp->TouchPos(), - vec4(view_area.xy() + vec2(18, 0), vec2(view_area.z(), tbh))) && - has_touch) { - mouse = inp->TouchPos(); - } else if (inp->IsUp(inp->Touch) && - LI::Renderer::InBox(inp->TouchPos(), - vec4(view_area.xy() + vec2(18, 0), - vec2(view_area.z(), tbh))) && - has_touch) { - mouse = 0; - } else if (inp->IsHeld(inp->Touch) && - LI::Renderer::InBox(inp->TouchPos(), - vec4(view_area.xy() + vec2(18, 0), - vec2(view_area.z(), tbh))) && - has_touch) { + if (has_touch && + io->DragObject(name + "tmv", vec4(view_area.xy() + vec2(18, 0), + vec2(view_area.z(), tbh)))) { view_area = - vec4(view_area.xy() + (inp->TouchPos() - mouse), view_area.zw()); - mouse = inp->TouchPos(); + vec4(view_area.xy() + (io->DragPosition - io->DragLastPosition), + view_area.zw()); } } } // Add a clip Rect for Separators if (!(flags & UI7MenuFlags_NoClipRect)) { - main->PushClipRect(vec4(view_area.x() + 5, view_area.y() + tbh, - view_area.x() + view_area.z() - 12, + main->PushClipRect(vec4(view_area.x() + io->MenuPadding[0], + view_area.y() + tbh, + view_area.x() + view_area.z() - io->MenuPadding[0], view_area.y() + view_area.w())); } } @@ -263,27 +248,22 @@ void UI7::Menu::PreHandler(UI7MenuFlags flags) { void UI7::Menu::PostHandler() { TT::Scope st("MPOS_" + name); if (!(flags & UI7MenuFlags_NoResize)) { - front->AddRectangle(view_area.xy() + view_area.zw() - 20, 20, 0xffffffff); - if (inp->IsDown(inp->Touch) && - LI::Renderer::InBox(inp->TouchPos(), - vec4(view_area.xy() + view_area.zw() - 20, 20)) && - has_touch) { - mouse = inp->TouchPos(); + if (has_touch && + io->DragObject(name + "rszs", + vec4(view_area.xy() + view_area.zw() - 20, 20))) { + view_area = vec4(view_area.xy(), view_area.zw() + (io->DragPosition - + io->DragLastPosition)); } - if (inp->IsHeld(inp->Touch) && - LI::Renderer::InBox(inp->TouchPos(), - vec4(view_area.xy() + view_area.zw() - 20, 20)) && - has_touch) { - view_area = - vec4(view_area.xy(), view_area.zw() + (inp->TouchPos() - mouse)); - mouse = inp->TouchPos(); - } - // Not vidible dor some reason - // front->AddTriangle(10, vec2(10, 0), vec2(10, 0), 0xffffffff); + // front->AddRectangle(view_area.xy() + view_area.zw() - 20, 20, + // 0xffffffff); Not vidible dor some reason + int l = front->Layer(); + front->Layer(l + 1); + front->AddTriangle(10, vec2(10, 0), vec2(10, 0), 0xffffffff); + front->Layer(l); } if (scrolling[1]) { - scroll_allowed[1] = (max[1] > view_area.w() - 5); - if (max[1] < view_area.w() - 5) { + scroll_allowed[1] = (max[1] > view_area.w() - io->MenuPadding[1]); + if (max[1] < view_area.w() - io->MenuPadding[1]) { scrolling_off[1] = 0.f; } scrollbar[1] = scroll_allowed[1]; @@ -291,9 +271,9 @@ void UI7::Menu::PostHandler() { if (scrollbar[1]) { /// Setup Some Variables hare [they are self described] int screen_w = view_area.z(); - int tsp = 5 + tbh; + int tsp = io->MenuPadding[1] + tbh; int slider_w = 4; - int szs = view_area.w() - tsp - 5; + int szs = view_area.w() - tsp - io->MenuPadding[1]; /// Actually dont have a Horizontal bar yet if (scrollbar[0]) szs -= slider_w - 2; int lslider_h = 20; // Dont go less heigt for the drag @@ -304,7 +284,7 @@ void UI7::Menu::PostHandler() { /// Check if we overscroll to the bottom and Auto scroll back... /// Probably schould use Tween ENgine here if (scrolling_off[1] > max[1] - view_area[3] && max[1] != 0.f && - max[1] >= view_area[3] - 5) { + max[1] >= view_area[3] - io->MenuPadding[1]) { scrolling_off[1] -= 3.f; if (scrolling_off[1] < max[1] - view_area[3]) { scrolling_off[1] = max[1] - view_area[3]; @@ -326,14 +306,14 @@ void UI7::Menu::PostHandler() { } /// The pain :( - if (has_touch) { - vec2 tpos = inp->TouchPos(); - if (inp->IsDown(inp->Touch)) { + if (has_touch && !io->IsObjectDragged()) { + vec2 tpos = io->Inp->TouchPos(); + if (io->Inp->IsDown(io->Inp->Touch)) { mouse = tpos; - } else if (inp->IsUp(inp->Touch)) { + } else if (io->Inp->IsUp(io->Inp->Touch)) { mouse = vec2(); } - if (inp->IsHeld(inp->Touch)) { + if (io->Inp->IsHeld(io->Inp->Touch)) { if (front->ren->InBox(tpos, vec4(view_area.xy() + main_area.xy(), main_area.zw()))) { if (scrolling_off[1] < max[1] - view_area[3] + 40 && @@ -365,22 +345,22 @@ void UI7::Menu::PostHandler() { scroll_mod[1] = 0; } } - + UI7Color sldr_drag = UI7Color_Button; /// Slider Dragging???? /// Probably need a new API for this - auto tp = inp->TouchPos(); - if (inp->IsHeld(inp->Touch) && - LI::Renderer::InBox(tp, vec4(view_area.x() + screen_w - 12, - view_area.y() + tsp, 8, szs))) { + if (has_touch && + io->DragObject(name + "sldr", vec4(view_area.x() + screen_w - 12, + view_area.y() + tsp, 8, szs)) && + !io->DragReleased) { + sldr_drag = UI7Color_ButtonHovered; float drag_center = vslider_h / 2.0f; - float drag_pos = - std::clamp(static_cast((tp[1] - tsp - drag_center) / - (szs - vslider_h - 4)), - 0.0f, 1.0f); + float drag_pos = std::clamp( + static_cast((io->DragPosition[1] - tsp - drag_center) / + (szs - vslider_h - 4)), + 0.0f, 1.0f); scrolling_off[1] = drag_pos * (max[1] - 240.f); } - int srpos = tsp + std::clamp(float(szs - vslider_h - 4) * (scrolling_off[1] / (max[1] - view_area[3])), @@ -389,13 +369,12 @@ void UI7::Menu::PostHandler() { /// Rendering Stage front->AddRectangle(view_area.xy() + vec2(screen_w - 12, tsp), vec2(slider_w * 2, szs), - theme->Get(UI7Color_FrameBackground)); + io->Theme->Get(UI7Color_FrameBackground)); front->AddRectangle(view_area.xy() + vec2(screen_w - 10, tsp + 2), vec2(slider_w, szs - 4), - theme->Get(UI7Color_FrameBackgroundHovered)); + io->Theme->Get(UI7Color_FrameBackgroundHovered)); front->AddRectangle(view_area.xy() + vec2(screen_w - 10, srpos + 2), - vec2(slider_w, vslider_h), - theme->Get(UI7Color_Button)); + vec2(slider_w, vslider_h), io->Theme->Get(sldr_drag)); } } // Remove the Clip Rect @@ -417,49 +396,51 @@ void UI7::Menu::Separator() { if (HandleScrolling(pos, size)) { return; } - main->AddRectangle(pos, size, theme->Get(UI7Color_TextDead)); + main->AddRectangle(pos, size, io->Theme->Get(UI7Color_TextDead)); } void UI7::Menu::SeparatorText(const std::string& label) { vec2 size = vec2(view_area.z() - (scrollbar[1] ? 24 : 10), 1); vec2 tdim = this->back->ren->GetTextDimensions(label); vec2 pos = Cursor(); - CursorMove(vec2(size.x(), tdim.y() - 4)); // Fix to make gap not to large + CursorMove(vec2(size.x(), tdim.y())); if (HandleScrolling(pos, size)) { return; } auto alignment = GetAlignment(); - vec2 rpos = - AlignPos(pos, view_area.z() - 10, view_area, alignment); // RenderPos + vec2 rpos = AlignPos(pos, view_area.z() - (io->MenuPadding[0] * 2), view_area, + alignment); // RenderPos /// Label pos for better overview vec2 lpos = rpos; if (alignment & UI7Align_Center) { - lpos += vec2((view_area.z() - 10) * 0.5 - tdim.x() * 0.5, 0); + lpos += vec2( + (view_area.z() - (io->MenuPadding[0] * 2)) * 0.5 - tdim.x() * 0.5, 0); } else if (alignment & UI7Align_Right) { - lpos = vec2(view_area.z() - 10 - tdim.x(), rpos.y()); + lpos = vec2(view_area.z() - (io->MenuPadding[0] * 2) - tdim.x(), rpos.y()); if (scrolling[1]) { lpos.x() -= 8; } } if (!(alignment & UI7Align_Left)) { main->AddRectangle(rpos + vec2(0, tdim.y() * 0.5), - vec2(lpos.x() - rpos.x() - 5, size.y()), - theme->Get(UI7Color_TextDead)); + vec2(lpos.x() - rpos.x() - io->MenuPadding[0], size.y()), + io->Theme->Get(UI7Color_TextDead)); } if (!(alignment & UI7Align_Right)) { main->AddRectangle(rpos + vec2(lpos.x() + tdim.x(), tdim.y() * 0.5), vec2(size.x() - (lpos.x() + tdim.x()), size.y()), - theme->Get(UI7Color_TextDead)); + io->Theme->Get(UI7Color_TextDead)); } - main->AddText(lpos, label, theme->Get(UI7Color_Text), 0, + main->AddText(lpos, label, io->Theme->Get(UI7Color_Text), 0, vec2(view_area.z(), 20)); } bool UI7::Menu::HandleScrolling(vec2& pos, const vec2& size) { if (scrolling[1]) { pos -= vec2(0, scrolling_off.y()); - if (pos.y() > view_area.w() || (pos.y() + size.y() < view_area.y())) { + if (!io->Ren->InBox( + pos, size, vec4(view_area.xy(), view_area.xy() + view_area.zw()))) { return true; } } @@ -542,5 +523,54 @@ void UI7::Menu::CreateParent() { tmp_parent->SetPos(0); tmp_parent->SetSize(0); } + +bool UI7::Menu::BeginTreeNode(const UI7::ID& id) { + auto n = tree_nodes.find((u32)id); + if (n == tree_nodes.end()) { + tree_nodes[(u32)id] = false; + n = tree_nodes.find((u32)id); + } + vec2 pos = Cursor(); + vec2 tdim = io->Ren->GetTextDimensions(id.GetName()); + vec2 size = vec2(tdim.x() + 10 + io->ItemSpace[0], tdim.y()); + if (n->second) { + icursoroff.x() += 10.f; + } + CursorMove(size); + if (HandleScrolling(pos, size)) { + return n->second; + } + vec2 ts = pos + vec2(0, 3); + vec2 positions[2] = { + vec2(10, 5), + vec2(0, 10), + }; + if (n->second) { + float t = positions[0].y(); + positions[0].y() = positions[1].x(); + positions[1].x() = t; + } + main->AddTriangle(ts, ts + positions[0], ts + positions[1], + io->Theme->Get(UI7Color_FrameBackground)); + main->AddText(pos + vec2(10 + io->ItemSpace[0], 0), id.GetName(), + io->Theme->Get(UI7Color_Text)); + if (has_touch && io->DragObject(name + id.GetName(), vec4(pos, size))) { + if (io->DragReleased) { + n->second = !n->second; + if (!n->second) { + icursoroff.x() -= 10.f; + cursor.x() -= 10; + } + } + } + return n->second; +} +void UI7::Menu::EndTreeNode() { + icursoroff.x() -= 10.f; + cursor.x() -= 10; + if (icursoroff.x() < 0.f) { + icursoroff.x() = 0.f; + } +} } // namespace UI7 } // namespace PD \ No newline at end of file diff --git a/source/ui7/ui7.cpp b/source/ui7/ui7.cpp index b15fb0e..4b01d9c 100644 --- a/source/ui7/ui7.cpp +++ b/source/ui7/ui7.cpp @@ -24,6 +24,18 @@ SOFTWARE. #include #include +// Helpers + +#define UI7DV4(x) \ + std::format("{}: [{:.2f}, {:.2f}, {:.2f}, {:.2f}]", #x, x[0], x[1], x[2], \ + x[3]) +#define UI7DV4N(x) \ + std::format("[{:.2f}, {:.2f}, {:.2f}, {:.2f}]", x[0], x[1], x[2], x[3]) +#define UI7DV2(x) std::format("{}: [{:.2f}, {:.2f}]", #x, x[0], x[1]) +#define UI7DV2N(x) std::format("[{:.2f}, {:.2f}]", x[0], x[1]) +#define UI7DHX32(x) std::format("{}: {:#08x}", #x, x) +#define UI7DTF(x) PD::Strings::FormatNanos(x) + namespace PD { std::string UI7::GetVersion(bool show_build) { std::stringstream s; @@ -39,22 +51,22 @@ bool UI7::Context::BeginMenu(const ID& id, UI7MenuFlags flags) { "Menu Name Already used or\nContext::Update not called!"); auto menu = this->menus.find(id); if (menu == this->menus.end()) { - this->menus[id] = Menu::New(id, theme, inp); - this->menus[id]->ViewArea(this->ren->GetViewport()); + this->menus[id] = Menu::New(id, io); + this->menus[id]->ViewArea(this->io->Ren->GetViewport()); menu = this->menus.find(id); } this->current = menu->second; if (!this->current->BackList()) { - this->current->BackList(DrawList::New(ren)); - this->current->BackList()->BaseLayer(root_layer + 30); + this->current->BackList(DrawList::New(io->Ren)); + io->RegisterDrawList(this->current->name + "back", this->current->back); } if (!this->current->MainList()) { - this->current->MainList(DrawList::New(ren)); - this->current->MainList()->BaseLayer(root_layer + 40); + this->current->MainList(DrawList::New(io->Ren)); + io->RegisterDrawList(this->current->name + "main", this->current->main); } if (!this->current->FrontList()) { - this->current->FrontList(DrawList::New(ren)); - this->current->FrontList()->BaseLayer(root_layer + 50); + this->current->FrontList(DrawList::New(io->Ren)); + io->RegisterDrawList(this->current->name + "front", this->current->front); } this->current->PreHandler(flags); amenus.push_back(this->current->GetID()); @@ -85,16 +97,19 @@ void UI7::Context::EndMenu() { void UI7::Context::Update(float delta) { TT::Scope st("UI7_Update"); Assert(current == nullptr, "Still in a Menu!"); - this->delta = delta; - s_delta->Add(delta * 1000); - this->back->BaseLayer(root_layer + 10); - this->back->Process(); + this->io->Delta = delta; + io->DeltaStats->Add(io->Delta * 1000); for (auto it : amenus) { - menus[it]->Update(delta); + menus[it]->Update(io->Delta); + } + int list = 1; + for (auto it : io->DrawListRegestry) { + it.second->BaseLayer(list * 10); + it.second->Process(); + list++; } - this->front->BaseLayer(root_layer + 60); - this->front->Process(); this->amenus.clear(); + this->io->Update(); } void UI7::Context::AboutMenu() { @@ -126,14 +141,110 @@ void UI7::Context::MetricsMenu() { m->Label("Palladium - UI7 " + GetVersion()); m->Separator(); - m->Label(std::format("Average {:.3f} ms/f ({:.1f} FPS)", - ((float)s_delta->GetAverage() / 1000.f), - 1000.f / ((float)s_delta->GetAverage() / 1000.f))); + m->Label( + std::format("Average {:.3f} ms/f ({:.1f} FPS)", + ((float)io->DeltaStats->GetAverage() / 1000.f), + 1000.f / ((float)io->DeltaStats->GetAverage() / 1000.f))); m->Label("Menus: " + std::to_string(menus.size())); m->SeparatorText("Lithium"); - m->Label(std::format("Vertices: {} Indices: {}", ren->Vertices(), - ren->Indices())); - m->Label("Triangles: " + std::to_string(ren->Indices() / 3)); + m->Label(std::format("Vertices: {} Indices: {}", io->Ren->Vertices(), + io->Ren->Indices())); + m->Label("Triangles: " + std::to_string(io->Ren->Indices() / 3)); + m->SeparatorText("TimeTrace"); + if (m->BeginTreeNode("Traces (" + + std::to_string(Sys::GetTraceMap().size()) + ")")) { + for (auto& it : Sys::GetTraceMap()) { + if (m->BeginTreeNode(it.second->GetID())) { + m->Label("Diff: " + UI7DTF(it.second->GetLastDiff())); + m->Label("Protocol Len: " + + std::to_string(it.second->GetProtocol()->GetLen())); + m->Label("Average: " + + UI7DTF(it.second->GetProtocol()->GetAverage())); + m->Label("Min: " + UI7DTF(it.second->GetProtocol()->GetMin())); + m->Label("Max: " + UI7DTF(it.second->GetProtocol()->GetMax())); + m->EndTreeNode(); + } + } + m->EndTreeNode(); + } + m->SeparatorText("IO"); + if (m->BeginTreeNode("Menus (" + std::to_string(menus.size()) + ")")) { + for (auto& it : menus) { + if (m->BeginTreeNode(it.second->name)) { + m->Label("Name: " + it.second->name); + m->Label("Pos: " + UI7DV2N(it.second->view_area.xy())); + m->Label("Size: " + UI7DV2N(it.second->view_area.zw())); + m->Label("Main Area: " + UI7DV4N(it.second->main_area)); + m->Label("Cursor: " + UI7DV2N(it.second->cursor)); + if (m->BeginTreeNode("ID Objects (" + + std::to_string(it.second->idobjs.size()) + + ")")) { + for (auto& jt : it.second->idobjs) { + m->Label(UI7DHX32(jt->GetID())); + } + m->EndTreeNode(); + } + m->EndTreeNode(); + } + } + m->EndTreeNode(); + } + if (m->BeginTreeNode("DrawLists (" + + std::to_string(io->DrawListRegestry.size()) + ")")) { + for (auto& it : io->DrawListRegestry) { + m->Label(it.first.GetName()); + } + m->EndTreeNode(); + } + m->Label("io->Time: " + Strings::FormatMillis(io->Time->Get())); + m->Label(std::format("io->Delta: {:.3f}", io->Delta)); + m->Label(std::format("io->Framerate: {:.2f}", io->Framerate)); + m->Label(UI7DHX32(io->DraggedObject)); + m->Label(std::format("io->DragTime: {:.2f}s", io->DragTime->GetSeconds())); + m->Label(UI7DV4(io->DragDestination)); + m->Label(UI7DV2(io->DragSourcePos)); + m->Label(UI7DV2(io->DragPosition)); + m->Label(UI7DV2(io->DragLastPosition)); + this->EndMenu(); + } +} + +void UI7::Context::StyleEditor() { + if (this->BeginMenu("UI7 Style Editor", UI7MenuFlags_Scrolling)) { + auto m = this->GetCurrentMenu(); + + m->Label("Palladium - UI7 " + GetVersion() + " Style Editor"); + m->Separator(); + m->Label(std::format("MenuPadding: {}, {}", io->MenuPadding.x(), + io->MenuPadding.y())); + m->SameLine(); + if (m->Button("-")) { + io->MenuPadding -= 1; + } + m->SameLine(); + if (m->Button("+")) { + io->MenuPadding += 1; + } + m->Label(std::format("FramePadding: {}, {}", io->FramePadding.x(), + io->FramePadding.y())); + m->SameLine(); + if (m->Button("-")) { + io->FramePadding -= 1; + } + m->SameLine(); + if (m->Button("+")) { + io->FramePadding += 1; + } + m->Label( + std::format("ItemSpace: {}, {}", io->ItemSpace.x(), io->ItemSpace.y())); + m->SameLine(); + if (m->Button("-")) { + io->ItemSpace -= 1; + } + m->SameLine(); + if (m->Button("+")) { + io->ItemSpace += 1; + } this->EndMenu(); } }