# 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
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -305,6 +305,9 @@ class StaticText : public SmartCtor<StaticText> { | ||||
|    */ | ||||
|   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 | ||||
|   | ||||
| @@ -24,6 +24,7 @@ SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| #include <pd/ui7/container/container.hpp> | ||||
| #include <pd/ui7/io.hpp> | ||||
|  | ||||
| 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 | ||||
| @@ -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 | ||||
| @@ -28,6 +28,7 @@ SOFTWARE. | ||||
| #include <pd/core/vec.hpp> | ||||
| #include <pd/drivers/hid.hpp> | ||||
| #include <pd/ui7/drawlist.hpp> | ||||
| #include <pd/ui7/io.hpp> | ||||
|  | ||||
| namespace PD { | ||||
| namespace UI7 { | ||||
| @@ -54,14 +55,13 @@ class Container : public SmartCtor<Container> { | ||||
|   /** | ||||
|    * 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<Container> { | ||||
|   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<Container> { | ||||
|   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)*/ | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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 | ||||
| @@ -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) | ||||
|   | ||||
| @@ -25,9 +25,10 @@ SOFTWARE. | ||||
|  | ||||
| #include <pd/core/common.hpp> | ||||
| #include <pd/core/timer.hpp> | ||||
| #include <pd/drivers/hid.hpp> | ||||
| #include <pd/ui7/drawlist.hpp> | ||||
| #include <pd/ui7/flags.hpp> | ||||
| #include <pd/ui7/menu.hpp> | ||||
| #include <pd/ui7/id.hpp> | ||||
| #include <pd/ui7/theme.hpp> | ||||
|  | ||||
| namespace PD { | ||||
| @@ -40,21 +41,111 @@ class IO : public SmartCtor<IO> { | ||||
|   /** | ||||
|    * 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<UI7::ID, DrawList::Ref> 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 | ||||
| @@ -29,6 +29,7 @@ SOFTWARE. | ||||
| #include <pd/ui7/drawlist.hpp> | ||||
| #include <pd/ui7/flags.hpp> | ||||
| #include <pd/ui7/id.hpp> | ||||
| #include <pd/ui7/io.hpp> | ||||
|  | ||||
| namespace PD { | ||||
| namespace UI7 { | ||||
| @@ -38,13 +39,11 @@ class Menu : public SmartCtor<Menu> { | ||||
|   /** | ||||
|    * 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<Menu> { | ||||
|  | ||||
|   // 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<Menu> { | ||||
|    * 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<Menu> { | ||||
|    * 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<Menu> { | ||||
|   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<Menu> { | ||||
|   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<u32, bool> tree_nodes;  ///< Map of Tree nodes | ||||
|  | ||||
|   // Animations System | ||||
|  | ||||
|   | ||||
| @@ -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> { | ||||
|    */ | ||||
|   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<Context> { | ||||
|    * 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<Context> { | ||||
|   // 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<Context> { | ||||
|   /** 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<u32, Menu::Ref> menus; | ||||
|   std::vector<u32> 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; | ||||
| }; | ||||
|   | ||||
| @@ -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() { | ||||
|   | ||||
| @@ -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 | ||||
| @@ -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 | ||||
| @@ -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 | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
| @@ -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  ////// | ||||
|   | ||||
							
								
								
									
										34
									
								
								source/ui7/io.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								source/ui7/io.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -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 <pd/core/timetrace.hpp> | ||||
| #include <pd/ui7/io.hpp> | ||||
|  | ||||
| namespace PD { | ||||
| void UI7::IO::Update() { | ||||
|   Time->Update(); | ||||
|   DragTime->Update(); | ||||
|   DragReleased = false; | ||||
|   Framerate = 1000.f / Delta; | ||||
| } | ||||
| }  // namespace PD | ||||
| @@ -28,11 +28,10 @@ SOFTWARE. | ||||
| namespace PD { | ||||
| namespace UI7 { | ||||
| void UI7::Menu::Label(const std::string& label) { | ||||
|   Container::Ref r = | ||||
|       ObjectPush(PD::New<UI7::Label>(label, Cursor(), this->back->ren)); | ||||
|   r->SetPos(AlignPos(r->GetPos(), r->GetSize(), view_area, GetAlignment())); | ||||
|   Container::Ref r = ObjectPush(PD::New<UI7::Label>(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<UI7::Button>(label, Cursor(), this->back->ren); | ||||
|     r = PD::New<UI7::Button>(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<UI7::Checkbox>(label, Cursor(), v, this->back->ren); | ||||
|     r = PD::New<UI7::Checkbox>(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<UI7::Image>(img, Cursor(), this->back->ren, size)); | ||||
|   r->SetPos(AlignPos(r->GetPos(), r->GetSize(), view_area, GetAlignment())); | ||||
|   Container::Ref r = ObjectPush(PD::New<UI7::Image>(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<int> 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<float>((tp[1] - tsp - drag_center) / | ||||
|                                           (szs - vslider_h - 4)), | ||||
|                        0.0f, 1.0f); | ||||
|         float drag_pos = std::clamp( | ||||
|             static_cast<float>((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 | ||||
| @@ -24,6 +24,18 @@ SOFTWARE. | ||||
| #include <pd/core/timetrace.hpp> | ||||
| #include <pd/ui7/ui7.hpp> | ||||
|  | ||||
| // 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(); | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user