# Changes 0.3.1

- Add Layout API and let Menu use it
- Add DragData (for float, double, int, etc)
- Add IO Delta calculation to not require a users delta value
- Add Config Var for SLider drag min size
- Remove Hid::Ref input of Containers as IO DragApi is used
- Containers that accept input will require an ID to function
This commit is contained in:
2025-03-14 15:14:45 +01:00
parent ba77dc9b42
commit 35272687f6
21 changed files with 688 additions and 469 deletions

View File

@ -54,9 +54,8 @@ class Button : public Container {
/**
* Override for the Input Handler
* @note This function is usally called by Menu::Update
* @param inp Reference to the Input Handler
*/
void HandleInput(Hid::Ref inp) override;
void HandleInput() override;
/**
* Override for the Rendering Handler
* @note This function is usally called by Menu::Update

View File

@ -50,9 +50,8 @@ class Checkbox : public Container {
/**
* Override for the Input Handler
* @note This function is usally called by Menu::Update
* @param inp Reference to the Input Handler
*/
void HandleInput(Hid::Ref inp) override;
void HandleInput() override;
/**
* Override for the Rendering Handler
* @note This function is usally called by Menu::Update

View File

@ -25,6 +25,7 @@ SOFTWARE.
#include <pd/ui7/container/container.hpp>
#include <pd/ui7/io.hpp>
#include <pd/ui7/layout.hpp>
namespace PD {
namespace UI7 {
@ -51,9 +52,8 @@ class ColorEdit : public Container {
/**
* Override for the Input Handler
* @note This function is usally called by Menu::Update
* @param inp Reference to the Input Handler
*/
void HandleInput(Hid::Ref inp) override;
void HandleInput() override;
/**
* Override for the Rendering Handler
* @note This function is usally called by Menu::Update
@ -68,6 +68,8 @@ class ColorEdit : public Container {
u32* color_ref = nullptr; ///< Color Reference
u32 initial_color; ///< Initial Color
std::string label; ///< Label of the Button
Layout::Ref layout; ///< Layout to open
bool is_shown = false; ///< AHow Layout Editor
};
} // namespace UI7
} // namespace PD

View File

@ -103,7 +103,7 @@ class Container : public SmartCtor<Container> {
*/
void HandleScrolling(vec2 scrolling, vec4 viewport);
/** Template function for Input Handling */
virtual void HandleInput(Hid::Ref inp) {}
virtual void HandleInput() {}
/** Tamplate function for Object rendering */
virtual void Draw() {}
/** Template function to update internal data (if needed) */

View File

@ -0,0 +1,79 @@
#pragma once
/*
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/ui7/container/container.hpp>
#include <pd/ui7/io.hpp>
namespace PD {
namespace UI7 {
/**
* DragData Object can take a datatype or a list
* and modifys these by moving left or right when dragging
*/
template <typename T>
class DragData : public Container {
public:
/**
* Constructor
* @param label Label of the Button
* @param pos Base Position
* @param lr Reference to the Renderer
*/
DragData(const std::string& label, T* data, size_t num_elms, UI7::IO::Ref io,
T min = 0, T max = 100) {
PD::Assert(data != nullptr, "Input Data Address is null!");
this->label = label;
this->data = data;
this->elm_count = num_elms;
this->min = min;
this->max = max;
this->tdim = io->Ren->GetTextDimensions(label);
}
~DragData() = default;
/**
* Override for the Input Handler
* @note This function is usally called by Menu::Update
*/
void HandleInput() override;
/**
* Override for the Rendering Handler
* @note This function is usally called by Menu::Update
* */
void Draw() override;
/** Function to Update Size if framepadding changes */
void Update() override;
private:
vec2 tdim; ///< Text size
std::string label; ///< Label of the Button
T* data;
size_t elm_count = 0;
T min;
T max;
};
} // namespace UI7
} // namespace PD

View File

@ -26,5 +26,6 @@ SOFTWARE.
#include <pd/ui7/container/button.hpp>
#include <pd/ui7/container/checkbox.hpp>
#include <pd/ui7/container/coloredit.hpp>
#include <pd/ui7/container/dragdata.hpp>
#include <pd/ui7/container/image.hpp>
#include <pd/ui7/container/label.hpp>
#include <pd/ui7/container/label.hpp>

View File

@ -29,6 +29,8 @@ using UI7MenuFlags = unsigned int;
using UI7Align = unsigned int;
/** 32Bit Value to store Context (IO) flags */
using UI7IOFlags = unsigned int;
/** 32Bit Value for Layout Flags */
using UI7LayoutFlags = unsigned int;
/** Menu Flags */
enum UI7MenuFlags_ {
@ -48,6 +50,12 @@ enum UI7MenuFlags_ {
UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling,
};
/** UI7 Layout Flags */
enum UI7LayoutFlags_ {
UI7LayoutFlags_None = 0, ///< No Flags used
UI7LayoutFlags_UseClipRect = 1 << 0, ///< Enable ClipRect
};
/** UI7 Context Flags */
enum UI7IOFlags_ {
UI7IOFlags_None = 0, ///< No Additional Config available

View File

@ -61,6 +61,7 @@ class IO : public SmartCtor<IO> {
float Framerate = 0.f;
float Delta = 0.f;
u64 LastTime = 0;
TimeStats::Ref DeltaStats;
Timer::Ref Time;
Hid::Ref Inp;
@ -69,7 +70,8 @@ class IO : public SmartCtor<IO> {
vec2 MenuPadding = 5.f;
vec2 FramePadding = 5.f;
vec2 ItemSpace = vec2(5.f, 2.f);
u64 DoubleClickTime = 500; // Milliseconds
vec2 MinSliderDragSize = 10.f; // Min height (Vt) and Min Width (Hz)
u64 DoubleClickTime = 500; // Milliseconds
std::vector<std::pair<UI7::ID, DrawList::Ref>> DrawListRegestry;
DrawList::Ref Back;
DrawList::Ref Front;

119
include/pd/ui7/layout.hpp Normal file
View File

@ -0,0 +1,119 @@
#pragma once
/*
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/common.hpp>
#include <pd/ui7/container/container.hpp>
#include <pd/ui7/drawlist.hpp>
#include <pd/ui7/flags.hpp>
#include <pd/ui7/io.hpp>
namespace PD {
namespace UI7 {
class Layout : public PD::SmartCtor<Layout> {
public:
Layout(const ID& id, IO::Ref io) : ID(id) {
this->IO = io;
DrawList = UI7::DrawList::New(io->Ren);
Scrolling[0] = false;
Scrolling[1] = false;
CursorInit();
Pos = vec2(0, 0);
Size = vec2(320, 240);
WorkRect = vec4(IO->MenuPadding, Size - (vec2(2) * IO->MenuPadding));
}
~Layout() = default;
const std::string& GetName() const { return ID.GetName(); }
const UI7::ID& GetID() const { return this->ID; }
const vec2& GetPosition() const { return Pos; }
void SetPosition(const vec2& v) { Pos = v; }
const vec2& GetSize() const { return Size; }
void SetSize(const vec2& v) { Size = v; }
UI7::DrawList::Ref GetDrawList() { return DrawList; }
void CursorInit();
void SameLine();
void CursorMove(const vec2& size);
bool ObjectWorkPos(vec2& movpos);
void AddObject(Container::Ref obj);
Container::Ref FindObject(u32 id);
vec2 AlignPosition(vec2 pos, vec2 size, vec4 area, UI7Align alignment);
/** Get the Alignment for Current State */
UI7Align GetAlignment() {
/// if temp alignment is used then return it and
/// reset tmpalign
if (TempAlign) {
auto t = TempAlign;
TempAlign = 0;
return t;
}
return Alignment;
}
void SetAlign(UI7Align a) { Alignment = a; }
void NextAlign(UI7Align a) { TempAlign = a; }
void Update();
private:
friend class Menu;
friend class Context;
// Base Components
UI7::ID ID;
UI7::IO::Ref IO;
UI7::DrawList::Ref DrawList;
// Positioning
vec2 Pos;
vec2 Size;
UI7Align Alignment = UI7Align_Default;
UI7Align TempAlign;
// Cursor
vec2 Cursor;
vec2 InitialCursorOffset;
vec2 BackupCursor;
vec2 SamelineCursor;
vec2 BeforeSameLine;
vec2 LastObjSize;
vec2 MaxPosition;
vec4 WorkRect;
// Scrolling
vec2 ScrollOffset;
bool Scrolling[2];
// Objects
std::vector<Container::Ref> Objects;
std::vector<Container::Ref> IDObjects;
};
} // namespace UI7
} // namespace PD

View File

@ -30,6 +30,7 @@ SOFTWARE.
#include <pd/ui7/flags.hpp>
#include <pd/ui7/id.hpp>
#include <pd/ui7/io.hpp>
#include <pd/ui7/layout.hpp>
namespace PD {
namespace UI7 {
@ -47,12 +48,11 @@ class Menu : public SmartCtor<Menu> {
this->id = id;
this->name = id.GetName();
/// Set Default Values here
scrolling[0] = false;
scrolling[1] = false;
scrollbar[0] = false;
scrollbar[1] = false;
scroll_allowed[0] = false;
scroll_allowed[1] = false;
Layout = UI7::Layout::New(id, io);
}
~Menu() = default;
@ -88,6 +88,19 @@ class Menu : public SmartCtor<Menu> {
* @param color Color reference to edit
*/
void ColorEdit(const std::string& label, u32* color);
void DragFloat(const std::string& label, float* data, size_t num_elms);
template <typename T>
void DragData(const std::string& label, T* data, size_t num_elms = 1,
T min = 0, T max = 100) {
u32 id = Strings::FastHash("dfl" + label + std::to_string(count_btn++));
Container::Ref r = Layout->FindObject(id);
if (!r) {
r = PD::New<UI7::DragData<T>>(label, data, num_elms, io, min, max);
r->SetID(id);
}
Layout->AddObject(r);
}
// Basic API
/**
@ -102,7 +115,7 @@ class Menu : public SmartCtor<Menu> {
void EndTreeNode();
/** Add the Next Objext to the same line */
void SameLine();
void SameLine() { Layout->SameLine(); }
/** Add a Separator Line */
void Separator();
/**
@ -128,23 +141,14 @@ class Menu : public SmartCtor<Menu> {
* Set a Temp alignment op for the next Object
* @param a Alignment Operation
*/
void NextAlign(UI7Align a) { tmpalign = a; }
void NextAlign(UI7Align a) { Layout->NextAlign(a); }
/**
* Align Every Single Object by this operationset
* @param a Alignment
*/
void PushAlignment(UI7Align a) { alignment = a; }
void PushAlignment(UI7Align a) { Layout->SetAlign(a); }
/** Use default alignment */
void PopAlignment() { alignment = UI7Align_Default; }
/**
* Get a New Position depending on the Alignment
* @param pos Current Position
* @param size Object size
* @param view Viewport [position and size]
* @param a Alignment Operations
* @return new position based on the alignment
*/
static vec2 AlignPos(vec2 pos, vec2 size, vec4 view, UI7Align a);
void PopAlignment() { Layout->Alignment = UI7Align_Default; }
/**
* Returns a Reference to the theme
* @return Reference to the base Theme of the context
@ -166,35 +170,6 @@ class Menu : public SmartCtor<Menu> {
// API for Custom Objects
/**
* Handles the Position of Objects in Scrolling Menu
* @note As Containers have their own FUnc to handle this, this
* function is only useful to Render Live Objects whicch cannot be aligned
* by the internal Alignment Api
* @param pos position reference to write the new position to
* @param size size of the Object
* @return if the object can be skipped in rendering
*/
bool HandleScrolling(vec2& pos, const vec2& size);
/**
* Get the Cursor Position
* @return Cursor Pos
*/
vec2 Cursor() const { return view_area.xy() + cursor; }
/**
* Set the Cursor position
* @note The old Position can be restored with RestoreCursor
* @param v New Position
*/
void Cursor(const vec2& v) {
bcursor = cursor;
cursor = v;
}
/** Restore to the last cursor Position */
void RestoreCursor() {
cursor = bcursor;
bcursor = vec2();
}
/** Return if a Vertical Scrollbar exists */
bool HasVerticalScrollbar() { return scrollbar[1]; }
/** Return if a Horizontal Scrollbar exists */
@ -206,43 +181,13 @@ class Menu : public SmartCtor<Menu> {
* @note Could destroy some basic functionality
*/
void TitleBarHeight(float v) { tbh = v; }
/**
* Init the Cursor
* @note Useful when using with a Custom TitlebarHeight
*/
void CursorInit() { Cursor(io->MenuPadding + vec2(0, tbh)); }
/**
* Move the Cursor for new Object
* @param szs Size of the current Object
*/
void CursorMove(const vec2& szs);
/** Get the ViewArea of the Menu */
vec4 ViewArea() const { return view_area; }
/**
* Get the Main Area of the Menu
* (only relevant for input)
*/
vec4 MainArea() const { return main_area; }
/**
* Set a MainArea for input
* @param v Area where Objects can receive inputs
*/
void MainArea(const vec4& v) { main_area = v; }
/** Get The Scrolling offset */
vec2 ScrollOffset() const { return scrolling_off; }
/**
* Set a Scrolling offset
* @param v Custom Scrolling offset
*/
void ScrollOffset(const vec2& v) { scrolling_off = v; }
/** Get the Current Scrollmodification value */
vec2 ScrollMod() const { return scroll_mod; }
/**
* Animated Scroll to Position
* @param pos Destination Position
*/
void ScrollTo(vec2 pos) {
scroll_anim.From(scrolling_off)
scroll_anim.From(Layout->ScrollOffset)
.To(pos)
.In(1.f)
.As(scroll_anim.EaseInOutSine);
@ -252,19 +197,6 @@ class Menu : public SmartCtor<Menu> {
// Objects API
/**
* Push an object to the current ListHandler
* @param obj Object reference to use
* @return Reference to the Object (from a time
* where ObjectPush(Container::New()) was used)
*/
Container::Ref ObjectPush(Container::Ref obj);
/**
* Search for an Object by an id
* @param id 32 Bit hash/id
* @return the found Object or nullptr
*/
Container::Ref FindIDObj(u32 id);
/**
* Create a Parent Container to move and edit all sub
* instances at once
@ -276,7 +208,8 @@ class Menu : public SmartCtor<Menu> {
// Draw List
/** Get DrawList */
DrawList::Ref GetDrawList() { return main; }
DrawList::Ref GetDrawList() { return Layout->DrawList; }
UI7::Layout::Ref GetLayout() { return Layout; }
// Advanced
@ -305,43 +238,6 @@ class Menu : public SmartCtor<Menu> {
/** Handle things like scrolling */
void PostHandler();
// Basic Settings
/**
* Set Backup Cursor
* @param v Position
*/
void BackupCursor(const vec2& v) { bcursor = v; }
/** Get Sameline Cursor */
vec2 SameLineCursor() const { return slcursor; }
/**
* Set Sameline Cursor
* @param v Position
*/
void SameLineCursor(const vec2& v) { slcursor = v; }
/**
* Set View Area
* @param v vec4 containing pos and size
*/
void ViewArea(const vec4& v) { view_area = v; }
/**
* Set Scroll Modification
* @param v Mod
*/
void ScrollMod(const vec2& v) { scroll_mod = v; }
/** Get the Alignment for Current State */
UI7Align GetAlignment() {
/// if temp alignment is used then return it and
/// reset tmpalign
if (tmpalign) {
auto t = tmpalign;
tmpalign = 0;
return t;
}
return alignment;
}
/** Internal Processing */
void Update(float delta);
@ -363,21 +259,9 @@ class Menu : public SmartCtor<Menu> {
// Data
// Default Alignment for all Objects
UI7Align alignment = UI7Align_Default;
UI7Align tmpalign = 0; ///< Temp Alignment [only used once]
UI7MenuFlags flags = 0; ///< Menu Flags
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)
vec4 main_area; ///< Main Area [Input related]
vec2 scrolling_off; ///< Scrolling Position
bool scrolling[2]; ///< Is Hz or Vt Scrolling Enabled
vec2 scroll_mod; ///< Scroll Modificator
float tbh; ///< Titlebar height
bool scrollbar[2]; ///< Is Hz or Vt Scrollbar rendered
bool scroll_allowed[2]; ///< Is Hz or Vt Scrolling Alowed
@ -389,20 +273,9 @@ class Menu : public SmartCtor<Menu> {
// Objects API
std::vector<Container::Ref> objects; ///< Current frame Objects
std::vector<Container::Ref> idobjs; ///< Objects using an ID
std::vector<Container*> join; ///< List of Combined Objects
int count_btn = 0; ///< Count for Button ID Prefix
int count_cbx = 0; ///< Cound for Checkbox ID Prefix
// DrawList
DrawList::Ref main; ///< Main Drawlist
vec2 max; ///< Max Position
vec2 mouse; ///< Mouse/Touch Position
vec2 bslpos; ///< Before Sameline Position
vec2 last_size; ///< Last Object Size
std::vector<Container*> join; ///< List of Combined Objects
int count_btn = 0; ///< Count for Button ID Prefix
int count_cbx = 0; ///< Cound for Checkbox ID Prefix
UI7::IO::Ref io; ///< IO Reference
@ -411,6 +284,9 @@ class Menu : public SmartCtor<Menu> {
// Animations System
Tween<vec2> scroll_anim; ///< for Scroll to Animation
// Layout API
PD::UI7::Layout::Ref Layout;
};
} // namespace UI7
} // namespace PD

View File

@ -37,7 +37,7 @@ SOFTWARE.
* Major Minor Patch Build
* 0x01010000 -> 1.1.0-0
*/
#define UI7_VERSION 0x00030000
#define UI7_VERSION 0x00030100
namespace PD {
namespace UI7 {