# Changes

- Remove () from vec formatter
 -Add Merge function to DrawList to Move Data into the Current DrawList
- Fix stupid bug in Rect.hpp which caused some problems in line rendering
- Remove some unused UI7 Flags
- io: Allocate FinalDrawList and add GetViewPort func
- Readd TreeNodes to Menu
- Add ABout/Style and Metrics Menu to Context
- Add some Variables for cliprects in ui7 container.hpp
- Add InputHandler functionality to DynObj
- Fix Menu Layout Render Order
- Add Better Menu Sorting to Context
# ppam
- Use stringview instead of hardcoded const char*
# Todos
- Work on the Lithium 3D System
- Fix UI7 Menu Order to Pop new Menus into the front instead of the background
- Add Scrolling support to menu (or integrate it into layout maybe)
This commit is contained in:
2025-07-01 21:43:35 +02:00
parent 01fb149e71
commit 31a0c3656f
18 changed files with 558 additions and 81 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
build/ build/
.cache .cache
.vscode

View File

@ -39,7 +39,7 @@ template <typename T, typename CharT>
struct std::formatter<PD::vec2<T>, CharT> : std::formatter<T, CharT> { struct std::formatter<PD::vec2<T>, CharT> : std::formatter<T, CharT> {
template <typename FormatContext> template <typename FormatContext>
auto format(const PD::vec2<T>& v, FormatContext& ctx) const { auto format(const PD::vec2<T>& v, FormatContext& ctx) const {
return std::format_to(ctx.out(), "({}, {})", v.x, v.y); return std::format_to(ctx.out(), "{}, {}", v.x, v.y);
} }
}; };
@ -47,7 +47,7 @@ template <typename T, typename CharT>
struct std::formatter<PD::vec3<T>, CharT> : std::formatter<T, CharT> { struct std::formatter<PD::vec3<T>, CharT> : std::formatter<T, CharT> {
template <typename FormatContext> template <typename FormatContext>
auto format(const PD::vec3<T>& v, FormatContext& ctx) const { auto format(const PD::vec3<T>& v, FormatContext& ctx) const {
return std::format_to(ctx.out(), "({}, {}, {})", v.x, v.y, v.z); return std::format_to(ctx.out(), "{}, {}, {}", v.x, v.y, v.z);
} }
}; };
@ -55,6 +55,6 @@ template <typename T, typename CharT>
struct std::formatter<PD::vec4<T>, CharT> : std::formatter<T, CharT> { struct std::formatter<PD::vec4<T>, CharT> : std::formatter<T, CharT> {
template <typename FormatContext> template <typename FormatContext>
auto format(const PD::vec4<T>& v, FormatContext& ctx) const { auto format(const PD::vec4<T>& v, FormatContext& ctx) const {
return std::format_to(ctx.out(), "({}, {}, {}, {})", v.x, v.y, v.z, v.w); return std::format_to(ctx.out(), "{}, {}, {}, {}", v.x, v.y, v.z, v.w);
} }
}; };

View File

@ -61,6 +61,14 @@ class PD_LITHIUM_API DrawList {
PD_SHARED(DrawList); PD_SHARED(DrawList);
/**
* Append an input drawlist on top of this one
* This Function will clear the Input list to make sure
* THat the moved memory blocks don't get used
* @param list DrawList to move into current
*/
void Merge(DrawList::Ref list);
Command::Ref PreGenerateCmd(); Command::Ref PreGenerateCmd();
void AddCommand(Command::Ref v) { pDrawList.push_back(std::move(v)); } void AddCommand(Command::Ref v) { pDrawList.push_back(std::move(v)); }
void Clear() { pDrawList.clear(); } void Clear() { pDrawList.clear(); }

View File

@ -85,7 +85,7 @@ class Rect {
* Get the bottom-right corner position. * Get the bottom-right corner position.
* @return Bottom-right position as vec2. * @return Bottom-right position as vec2.
*/ */
fvec2 BotRight() const { return fvec2(Bot.z, Bot.y); } fvec2 BotRight() const { return fvec2(Bot.z, Bot.w); }
/** /**
* Set the top-left corner position. * Set the top-left corner position.

View File

@ -63,6 +63,11 @@ class PD_UI7_API Container {
// this->screen = io->Ren->CurrentScreen(); // this->screen = io->Ren->CurrentScreen();
} }
void SetClipRect(fvec4 clip) {
pClipRect = clip;
pCLipRectUsed = true;
}
/** Setter for Position */ /** Setter for Position */
void SetPos(const fvec2& pos) { this->pos = pos; } void SetPos(const fvec2& pos) { this->pos = pos; }
/** Setter for Size */ /** Setter for Size */
@ -161,6 +166,10 @@ class PD_UI7_API Container {
bool pPressed = false; bool pPressed = false;
/** Was Pressed Twice */ /** Was Pressed Twice */
bool pPressedTwice = false; bool pPressedTwice = false;
/** ClipRect */
fvec4 pClipRect;
/** Clip Rect used */
bool pCLipRectUsed = false;
}; };
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD

View File

@ -52,6 +52,10 @@ class PD_UI7_API DynObj : public Container {
PD_SHARED(DynObj); PD_SHARED(DynObj);
void AddInputHandler(std::function<void(UI7::IO::Ref, Container*)> inp) {
pInp = inp;
}
/** Return true if butten is pressed*/ /** Return true if butten is pressed*/
bool IsPressed() { return pressed; } bool IsPressed() { return pressed; }
/** /**
@ -72,6 +76,7 @@ class PD_UI7_API DynObj : public Container {
UI7Color color = UI7Color_Button; ///< current button color UI7Color color = UI7Color_Button; ///< current button color
bool pressed = false; ///< ispressed value bool pressed = false; ///< ispressed value
std::function<void(UI7::IO::Ref, Li::DrawList::Ref, Container*)> pRenFun; std::function<void(UI7::IO::Ref, Li::DrawList::Ref, Container*)> pRenFun;
std::function<void(UI7::IO::Ref, Container*)> pInp;
}; };
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD

View File

@ -31,8 +31,6 @@ using UI7Align = unsigned int;
using UI7IOFlags = unsigned int; using UI7IOFlags = unsigned int;
/** 32Bit Value for Layout Flags */ /** 32Bit Value for Layout Flags */
using UI7LayoutFlags = unsigned int; using UI7LayoutFlags = unsigned int;
/** 32Bit value for DrawFlags */
using UI7DrawFlags = unsigned int;
/** Menu Flags */ /** Menu Flags */
enum UI7MenuFlags_ { enum UI7MenuFlags_ {
@ -48,6 +46,9 @@ enum UI7MenuFlags_ {
UI7MenuFlags_NoResize = 1 << 8, ///< Disable Menu Resize UI7MenuFlags_NoResize = 1 << 8, ///< Disable Menu Resize
UI7MenuFlags_NoClose = 1 << 9, ///< Disable Close Button UI7MenuFlags_NoClose = 1 << 9, ///< Disable Close Button
UI7MenuFlags_NoScrollbar = 1 << 10, ///< Hide the Scrollbar UI7MenuFlags_NoScrollbar = 1 << 10, ///< Hide the Scrollbar
// POC
UI7MenuFlags_Maximize = 1 << 11, ///< Add a Maximize Button
UI7MenuFlags_Minimize = 1 << 12, ///< Add a Minimize Button
// Enable Horizontal and Vertical Scrolling // Enable Horizontal and Vertical Scrolling
UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling, UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling,
}; };
@ -58,12 +59,6 @@ enum UI7LayoutFlags_ {
UI7LayoutFlags_UseClipRect = 1 << 0, ///< Enable ClipRect UI7LayoutFlags_UseClipRect = 1 << 0, ///< Enable ClipRect
}; };
enum UI7DrawFlags_ {
UI7DrawFlags_None = 0,
UI7DrawFlags_Close = 1 << 0, ///< Close a PolyLine
UI7DrawFlags_AALines = 1 << 1, ///< Anti aliased Lines
};
/** UI7 Context Flags */ /** UI7 Context Flags */
enum UI7IOFlags_ { enum UI7IOFlags_ {
UI7IOFlags_None = 0, ///< No Additional Config available UI7IOFlags_None = 0, ///< No Additional Config available
@ -91,6 +86,11 @@ enum UI7LytAdd_ {
UI7LytAdd_Front = 1 << 2, ///< Add in front of the list UI7LytAdd_Front = 1 << 2, ///< Add in front of the list
}; };
/**
* Todo: Look at this
* Maybe proof of concept ???
* Didnt remember that this exists
*/
enum UI7ContainerFlags_ { enum UI7ContainerFlags_ {
UI7ContainerFlags_None = 0, UI7ContainerFlags_None = 0,
UI7ContainerFlags_EnableInternalInput = 1 << 0, UI7ContainerFlags_EnableInternalInput = 1 << 0,

View File

@ -40,6 +40,7 @@ class PD_UI7_API IO {
Theme = UI7::Theme::New(); Theme = UI7::Theme::New();
Back = Li::DrawList::New(); Back = Li::DrawList::New();
Front = Li::DrawList::New(); Front = Li::DrawList::New();
FDL = Li::DrawList::New();
DeltaStats = TimeStats::New(60); DeltaStats = TimeStats::New(60);
/** Probably not the best solution i guess */ /** Probably not the best solution i guess */
CurrentViewPort.z = PD::Li::Gfx::pGfx->ViewPort.x; CurrentViewPort.z = PD::Li::Gfx::pGfx->ViewPort.x;
@ -54,6 +55,12 @@ class PD_UI7_API IO {
*/ */
void Update(); void Update();
/**
* Final Draw List for PD::Li::Gfx::RednerDrawData
*
* Possible thanks to the DrawList::Merge Feature
*/
Li::DrawList::Ref FDL = nullptr;
ivec4 CurrentViewPort = ivec4(0, 0, 0, 0); ivec4 CurrentViewPort = ivec4(0, 0, 0, 0);
std::unordered_map<u32, ViewPort::Ref> ViewPorts; std::unordered_map<u32, ViewPort::Ref> ViewPorts;
float Framerate = 0.f; float Framerate = 0.f;
@ -94,6 +101,13 @@ class PD_UI7_API IO {
ViewPorts[id] = ViewPort::New(id, size); ViewPorts[id] = ViewPort::New(id, size);
} }
ViewPort::Ref GetViewPort(const ID& id) {
if (ViewPorts.count(id)) {
return nullptr;
}
return ViewPorts[id];
}
UI7::InputHandler::Ref InputHandler; UI7::InputHandler::Ref InputHandler;
}; };
} // namespace UI7 } // namespace UI7

View File

@ -126,7 +126,8 @@ class PD_UI7_API Layout {
fvec2 MaxPosition; fvec2 MaxPosition;
fvec4 WorkRect; fvec4 WorkRect;
// Scrolling // Scrolling (Only theoretical)
// Rendering must be done by the Objective that uses the Lyt
fvec2 ScrollOffset; fvec2 ScrollOffset;
bool Scrolling[2]; bool Scrolling[2];

View File

@ -24,16 +24,17 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#include "pd/ui7/container/dragdata.hpp"
#include <pd/core/core.hpp> #include <pd/core/core.hpp>
#include <pd/ui7/io.hpp> #include <pd/ui7/io.hpp>
#include <pd/ui7/layout.hpp> #include <pd/ui7/layout.hpp>
#include <pd/ui7/pd_p_api.hpp> #include <pd/ui7/pd_p_api.hpp>
#include "pd/ui7/container/dragdata.hpp"
namespace PD { namespace PD {
namespace UI7 { namespace UI7 {
class PD_UI7_API Menu { class PD_UI7_API Menu {
public: public:
Menu(const UI7::ID &id, UI7::IO::Ref pIO); Menu(const UI7::ID &id, UI7::IO::Ref pIO);
~Menu() {} ~Menu() {}
@ -87,9 +88,11 @@ public:
} }
pLayout->AddObject(r); pLayout->AddObject(r);
} }
void Sameline() { pLayout->SameLine(); } void SameLine() { pLayout->SameLine(); }
void Separator(); void Separator();
void SeparatorText(const std::string &label); void SeparatorText(const std::string &label);
bool BeginTreeNode(const ID &id);
void EndTreeNode();
void HandleFocus(); void HandleFocus();
void HandleScrolling(); void HandleScrolling();
@ -106,8 +109,9 @@ public:
ID pID; ID pID;
bool *pIsShown = nullptr; bool *pIsShown = nullptr;
bool pIsOpen = true; bool pIsOpen = true;
std::unordered_map<u32, bool> pTreeNodes;
float TitleBarHeight = 0.f; float TitleBarHeight = 0.f;
}; };
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD

View File

@ -24,12 +24,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#include "pd/ui7/flags.hpp"
#include <pd/core/core.hpp> #include <pd/core/core.hpp>
#include <pd/ui7/io.hpp> #include <pd/ui7/io.hpp>
#include <pd/ui7/menu.hpp> #include <pd/ui7/menu.hpp>
#include <pd/ui7/pd_p_api.hpp> #include <pd/ui7/pd_p_api.hpp>
#include "pd/ui7/flags.hpp"
/** /**
* Declare UI7 Version * Declare UI7 Version
* Format: 00 00 00 00 * Format: 00 00 00 00
@ -48,7 +49,7 @@ namespace UI7 {
PD_UI7_API std::string GetVersion(bool show_build = false); PD_UI7_API std::string GetVersion(bool show_build = false);
/** Base Context for UI7 */ /** Base Context for UI7 */
class PD_UI7_API Context { class PD_UI7_API Context {
public: public:
Context() { pIO = IO::New(); } Context() { pIO = IO::New(); }
~Context() = default; ~Context() = default;
@ -57,8 +58,13 @@ public:
void AddViewPort(const ID &id, const ivec4 &vp); void AddViewPort(const ID &id, const ivec4 &vp);
void UseViewPort(const ID &id); void UseViewPort(const ID &id);
void Update(); void Update();
bool BeginMenu(const ID &id, UI7MenuFlags flags, bool *pShow = nullptr); bool BeginMenu(const ID &id, UI7MenuFlags flags = 0, bool *pShow = nullptr);
void EndMenu(); void EndMenu();
void AboutMenu(bool *show = nullptr);
void MetricsMenu(bool *show = nullptr);
void StyleEditor(bool *show = nullptr);
Li::DrawList::Ref GetDrawData() { return pIO->FDL; }
Menu::Ref pGetOrCreateMenu(const ID &id) { Menu::Ref pGetOrCreateMenu(const ID &id) {
auto menu = pMenus.find(id); auto menu = pMenus.find(id);
@ -73,7 +79,8 @@ public:
/** Current Menu */ /** Current Menu */
Menu::Ref pCurrent = nullptr; Menu::Ref pCurrent = nullptr;
std::vector<u32> pCurrentMenus; std::vector<u32> pCurrentMenus;
std::vector<u32> pDFO; /** Debug Final Order */
std::unordered_map<u32, Menu::Ref> pMenus; std::unordered_map<u32, Menu::Ref> pMenus;
}; };
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD

View File

@ -33,13 +33,21 @@ namespace PD {
namespace Li { namespace Li {
PD_LITHIUM_API void DrawList::DrawSolid() { CurrentTex = Gfx::GetSolidTex(); } PD_LITHIUM_API void DrawList::DrawSolid() { CurrentTex = Gfx::GetSolidTex(); }
PD_LITHIUM_API void DrawList::Merge(DrawList::Ref list) {
for (size_t i = 0; i < list->pDrawList.size(); i++) {
pDrawList.push_back(std::move(list->pDrawList[i]));
}
/** Make sure The list gets cleared */
list->Clear();
}
PD_LITHIUM_API Command::Ref DrawList::PreGenerateCmd() { PD_LITHIUM_API Command::Ref DrawList::PreGenerateCmd() {
Command::Ref cmd = Command::New(); Command::Ref cmd = Command::New();
cmd->Layer = Layer; cmd->Layer = Layer;
cmd->Index = pDrawList.size(); cmd->Index = pDrawList.size();
cmd->Tex = CurrentTex; cmd->Tex = CurrentTex;
pClipCmd(cmd.get()); pClipCmd(cmd.get());
return std::move(cmd); return cmd;
} }
PD_LITHIUM_API void DrawList::pClipCmd(Command *cmd) { PD_LITHIUM_API void DrawList::pClipCmd(Command *cmd) {
@ -193,7 +201,7 @@ PD_LITHIUM_API void DrawList::DrawCircle(const fvec2 &center, float rad,
float am = (M_PI * 2.0f) * ((float)num_segments) / (float)num_segments; float am = (M_PI * 2.0f) * ((float)num_segments) / (float)num_segments;
PathArcToN(center, rad, 0.f, am, num_segments); PathArcToN(center, rad, 0.f, am, num_segments);
} }
DrawSolid(); // Only Solid Color Supported DrawSolid(); // Only Solid Color Supported
PathStroke(color, thickness, (1 << 0)); PathStroke(color, thickness, (1 << 0));
} }
@ -234,7 +242,7 @@ PD_LITHIUM_API void DrawList::DrawPolyLine(const Vec<fvec2> &points, u32 clr,
PD_LITHIUM_API void DrawList::DrawConvexPolyFilled(const Vec<fvec2> &points, PD_LITHIUM_API void DrawList::DrawConvexPolyFilled(const Vec<fvec2> &points,
u32 clr) { u32 clr) {
if (points.Size() < 3) { if (points.Size() < 3) {
return; // Need at least three points return; // Need at least three points
} }
auto cmd = PreGenerateCmd(); auto cmd = PreGenerateCmd();
Renderer::CmdConvexPolyFilled(cmd.get(), points, clr, CurrentTex); Renderer::CmdConvexPolyFilled(cmd.get(), points, clr, CurrentTex);
@ -276,5 +284,5 @@ PD_LITHIUM_API void DrawList::DrawLine(const fvec2 &a, const fvec2 &b,
PathAdd(b); PathAdd(b);
PathStroke(color, t); PathStroke(color, t);
} }
} // namespace Li } // namespace Li
} // namespace PD } // namespace PD

View File

@ -27,7 +27,13 @@ SOFTWARE.
namespace PD { namespace PD {
namespace UI7 { namespace UI7 {
PD_UI7_API void DynObj::Draw() { pRenFun(io, list, this); } PD_UI7_API void DynObj::Draw() { pRenFun(io, list, this); }
PD_UI7_API void DynObj::HandleInput() {}
PD_UI7_API void DynObj::HandleInput() {
if (pInp) {
pInp(io, this);
}
}
PD_UI7_API void DynObj::Update() {} PD_UI7_API void DynObj::Update() {}
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD

View File

@ -28,7 +28,13 @@ namespace UI7 {
PD_UI7_API void Label::Draw() { PD_UI7_API void Label::Draw() {
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?"); // Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
// io->Ren->OnScreen(screen); // io->Ren->OnScreen(screen);
if (pCLipRectUsed) {
list->PushClipRect(pClipRect);
}
list->DrawText(FinalPos(), label, io->Theme->Get(UI7Color_Text)); list->DrawText(FinalPos(), label, io->Theme->Get(UI7Color_Text));
if (pCLipRectUsed) {
list->PopClipRect();
}
} }
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD

View File

@ -37,6 +37,7 @@ Menu::Menu(const ID &id, IO::Ref io) : pIO(io), pID(id) {
PD_UI7_API void Menu::Label(const std::string &label) { PD_UI7_API void Menu::Label(const std::string &label) {
// Layout API // Layout API
auto r = Label::New(label, pIO); auto r = Label::New(label, pIO);
r->SetClipRect(fvec4(pLayout->GetPosition(), pLayout->GetSize()));
pLayout->AddObject(r); pLayout->AddObject(r);
} }
@ -128,7 +129,10 @@ PD_UI7_API void Menu::HandleFocus() {
pIO->InputHandler->FocusedMenuRect = newarea; pIO->InputHandler->FocusedMenuRect = newarea;
} }
} }
/** Todo: (func name is self describing) */
PD_UI7_API void Menu::HandleScrolling() {} PD_UI7_API void Menu::HandleScrolling() {}
PD_UI7_API void Menu::HandleTitlebarActions() { PD_UI7_API void Menu::HandleTitlebarActions() {
// Collapse // Collapse
if (!(Flags & UI7MenuFlags_NoCollapse)) { if (!(Flags & UI7MenuFlags_NoCollapse)) {
@ -157,6 +161,21 @@ PD_UI7_API void Menu::HandleTitlebarActions() {
// clr_close_btn = UI7Color_FrameBackgroundHovered; // clr_close_btn = UI7Color_FrameBackgroundHovered;
} }
} }
// Resize logic
if (!(Flags & UI7MenuFlags_NoResize)) {
vec2 cpos = pLayout->Pos + pLayout->Size - fvec2(20);
// clr_close_btn = UI7Color_FrameBackground;
if (pIO->InputHandler->DragObject(UI7::ID(pID.GetName() + "rszs"),
fvec4(cpos, fvec2(20)))) {
fvec2 szs = pLayout->Size + (pIO->InputHandler->DragPosition -
pIO->InputHandler->DragLastPosition);
if (szs.x < 30) szs.x = 30;
if (szs.y < 30) szs.y = 30;
pLayout->Size = szs;
// clr_close_btn = UI7Color_FrameBackgroundHovered;
}
}
// Menu Movement // Menu Movement
if (!(Flags & UI7MenuFlags_NoMove)) { if (!(Flags & UI7MenuFlags_NoMove)) {
if (pIO->InputHandler->DragObject( if (pIO->InputHandler->DragObject(
@ -167,13 +186,35 @@ PD_UI7_API void Menu::HandleTitlebarActions() {
} }
pLayout->Pos = pLayout->Pos + (pIO->InputHandler->DragPosition - pLayout->Pos = pLayout->Pos + (pIO->InputHandler->DragPosition -
pIO->InputHandler->DragLastPosition); pIO->InputHandler->DragLastPosition);
// Have no ViewPort Yet :( // Keep Window In Viewport
// pLayout->Pos = std::clamp(pLayout->Pos, fvec2(10), fvec2(1270, 710)); // Maybe i need to add some operators to vec
pLayout->Pos.x = std::clamp<float>(pLayout->Pos.x, -pLayout->Size.x + 10,
pIO->CurrentViewPort.z - 10);
pLayout->Pos.y =
std::clamp<float>(pLayout->Pos.y, 0.f, pIO->CurrentViewPort.w - 10);
} }
} }
} }
PD_UI7_API void Menu::DrawBaseLayout() { PD_UI7_API void Menu::DrawBaseLayout() {
if (pIsOpen) { if (pIsOpen) {
/** Resize Sym (Render on Top of Everything) */
if (!(Flags & UI7MenuFlags_NoResize)) {
Container::Ref r = DynObj::New(
[](IO::Ref io, Li::DrawList::Ref l, UI7::Container *self) {
l->Layer = 1;
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(0, 20));
l->PathAdd(self->FinalPos() + self->GetSize());
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(20, 0));
l->PathFill(io->Theme->Get(UI7Color_Button));
});
r->SetSize(
fvec2(pLayout->GetSize().x, pLayout->GetSize().y - TitleBarHeight));
r->SetPos(fvec2(0, TitleBarHeight));
pLayout->AddObjectEx(r,
UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle);
}
/** Background */
Container::Ref r = DynObj::New([](IO::Ref io, Li::DrawList::Ref l, Container::Ref r = DynObj::New([](IO::Ref io, Li::DrawList::Ref l,
UI7::Container *self) { UI7::Container *self) {
l->Layer = 0; l->Layer = 0;
@ -237,7 +278,7 @@ PD_UI7_API void Menu::DrawBaseLayout() {
} }
/** Close Sym (only shown if pIsShown is not nullptr) */ /** Close Sym (only shown if pIsShown is not nullptr) */
if (!(Flags & UI7MenuFlags_NoClose) && pIsShown) { if (!(Flags & UI7MenuFlags_NoClose) && pIsShown) {
fvec2 size = TitleBarHeight - pIO->FramePadding.y * 2; // Fixed quad size fvec2 size = TitleBarHeight - pIO->FramePadding.y * 2; // Fixed quad size
// Need to clamp this way as the math lib lacks a less and greater // Need to clamp this way as the math lib lacks a less and greater
// operator in vec2 (don't checked if it would make sense yet) // operator in vec2 (don't checked if it would make sense yet)
size.x = std::clamp(size.x, 5.f, std::numeric_limits<float>::max()); size.x = std::clamp(size.x, 5.f, std::numeric_limits<float>::max());
@ -254,6 +295,7 @@ PD_UI7_API void Menu::DrawBaseLayout() {
} }
} }
} }
PD_UI7_API void Menu::Update() { PD_UI7_API void Menu::Update() {
HandleFocus(); HandleFocus();
if (!(Flags & UI7MenuFlags_NoTitlebar)) { if (!(Flags & UI7MenuFlags_NoTitlebar)) {
@ -262,5 +304,62 @@ PD_UI7_API void Menu::Update() {
DrawBaseLayout(); DrawBaseLayout();
pLayout->Update(); pLayout->Update();
} }
} // namespace UI7
} // namespace PD PD_UI7_API bool Menu::BeginTreeNode(const ID &id) {
// As of some notes this should work:
auto n = pTreeNodes.find(id);
if (n == pTreeNodes.end()) {
pTreeNodes[id] = false;
n = pTreeNodes.find(id);
}
fvec2 pos = pLayout->Cursor;
fvec2 tdim = pIO->Font->GetTextBounds(id.GetName(), pIO->FontScale);
fvec2 szs = tdim + fvec2(pIO->ItemSpace.x + 10, 0);
if (n->second) {
pLayout->InitialCursorOffset += 10.f;
}
// Object
auto r =
DynObj::New([=, this](IO::Ref io, Li::DrawList::Ref l, Container *self) {
fvec2 ts = self->FinalPos() + fvec2(0, 7);
fvec2 pl[2] = {fvec2(10, 5), fvec2(0, 10)};
if (n->second) {
float t = pl[0].y;
pl[0].y = pl[1].x;
pl[1].x = t;
}
l->DrawTriangleFilled(ts, ts + pl[0], ts + pl[1],
io->Theme->Get(UI7Color_FrameBackground));
l->DrawText(self->FinalPos() + fvec2(10 + io->ItemSpace.x, 0),
id.GetName(), io->Theme->Get(UI7Color_Text));
});
/** Yes this new function handler was created for tree nodes */
r->AddInputHandler([=, this](IO::Ref io, Container *self) {
if (io->InputHandler->DragObject(
ID(pID.GetName() + id.GetName()),
fvec4(self->FinalPos(), self->GetSize()))) {
if (io->InputHandler->DragReleased) {
n->second = !n->second;
}
}
});
r->SetPos(pos);
r->SetSize(szs);
/** Use Add Object as it is faster */
pLayout->AddObject(r);
return n->second;
}
PD_UI7_API void UI7::Menu::EndTreeNode() {
pLayout->InitialCursorOffset.x -= 10.f;
pLayout->Cursor.x -= 10.f;
if (pLayout->InitialCursorOffset.x < 0.f) {
pLayout->InitialCursorOffset.x = 0.f;
}
}
} // namespace UI7
} // namespace PD

View File

@ -21,9 +21,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#include <pd/ui7/ui7.hpp>
#include "pd/ui7/flags.hpp" #include "pd/ui7/flags.hpp"
#include "pd/ui7/pd_p_api.hpp" #include "pd/ui7/pd_p_api.hpp"
#include <pd/ui7/ui7.hpp>
#define UI7DHX32(x) std::format("{}: {:#08x}", #x, x)
#define UI7DTF(x) PD::Strings::FormatNanos(x)
namespace PD { namespace PD {
namespace UI7 { namespace UI7 {
@ -32,8 +36,7 @@ PD_UI7_API std::string GetVersion(bool show_build) {
s << ((UI7_VERSION >> 24) & 0xFF) << "."; s << ((UI7_VERSION >> 24) & 0xFF) << ".";
s << ((UI7_VERSION >> 16) & 0xFF) << "."; s << ((UI7_VERSION >> 16) & 0xFF) << ".";
s << ((UI7_VERSION >> 8) & 0xFF); s << ((UI7_VERSION >> 8) & 0xFF);
if (show_build) if (show_build) s << "-" << ((UI7_VERSION) & 0xFF);
s << "-" << ((UI7_VERSION) & 0xFF);
return s.str(); return s.str();
} }
@ -63,11 +66,271 @@ PD_UI7_API bool Context::BeginMenu(const ID &id, UI7MenuFlags flags,
} }
pCurrent = pGetOrCreateMenu(id); pCurrent = pGetOrCreateMenu(id);
this->pCurrent->pIsShown = pShow; this->pCurrent->pIsShown = pShow;
this->pIO->InputHandler->CurrentMenu = id; if (pCurrent->pIsShown != nullptr) {
if (!*pCurrent->pIsShown) {
pCurrent = nullptr;
return false;
}
}
/** Probably we dont even need Input Handling in this stage */
// this->pIO->InputHandler->CurrentMenu = id;
pCurrentMenus.push_back(id);
pCurrent->Flags = flags;
if (!pCurrent->pIsOpen) {
pCurrent = nullptr;
}
return pCurrent != nullptr; return pCurrent != nullptr;
} }
PD_UI7_API void Context::Update() { pIO->Update(); } PD_UI7_API void Context::EndMenu() {
} // namespace UI7 /**
} // namespace PD * Currently it would be a better wy to handle menus as follows
*
* The folowing context will generate a new menu as normally but instead
* of true or false we have m is false (nullptr) or true (some ptr returned)
* and after that it should simply out of scope
* (This would probably require some wrapper class to find out if m goes
* out of scope)
* ```cpp
* if(auto m = ui7->BeginMenu("Test")) {
* m->Label("Show some Text");
* }
* ```
*/
if (!pCurrent) {
return;
}
pCurrent = nullptr;
// pIO->InputHandler->CurrentMenu = 0;
}
PD_UI7_API void Context::Update() {
/**
* Cause Commenting each line looks carbage...
* This function simply clears the FinalDrawList, Searches for Menu ID's in
* The sorted menu List from last frame to insert them as same order into
* the final list. After that it adds new menus to the begin to 'add' new
* menus on top. As final step the focused menu gets add to begin
* Then the menus update their Input and DraeList Generation in List Order
* and the DrawLists get Merged into the FDL in reverse Order. At end the List
* gets cleanup and io gets updated
*
* Very simple ...
*/
pIO->FDL->Clear();
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(),
pIO->InputHandler->FocusedMenu) == pCurrentMenus.end()) {
pIO->InputHandler->FocusedMenu = 0;
pIO->InputHandler->FocusedMenuRect = fvec4(0);
}
std::vector<u32> FinalList;
for (auto it : pDFO) {
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(), it) !=
pCurrentMenus.end() &&
it != pIO->InputHandler->FocusedMenu) {
FinalList.push_back(it);
}
}
for (auto it : pCurrentMenus) {
if (std::find(FinalList.begin(), FinalList.end(), it) == FinalList.end() &&
it != pIO->InputHandler->FocusedMenu) {
FinalList.push_back(it);
}
}
if (pMenus.count(pIO->InputHandler->FocusedMenu)) {
FinalList.insert(FinalList.begin(), pIO->InputHandler->FocusedMenu);
}
pDFO = FinalList;
for (auto &it : FinalList) {
this->pIO->InputHandler->CurrentMenu = it;
pMenus[it]->Update(); /** Render */
this->pIO->InputHandler->CurrentMenu = 0;
}
for (int i = (int)FinalList.size() - 1; i >= 0; i--) {
pIO->FDL->Merge(pMenus[FinalList[i]]->pLayout->GetDrawList());
}
pCurrentMenus.clear();
pIO->Update();
}
PD_UI7_API void Context::AboutMenu(bool *show) {
if (BeginMenu("About UI7", UI7MenuFlags_Scrolling, show)) {
auto m = pCurrent;
m->Label("Palladium UI7 " + GetVersion());
m->Separator();
m->Label("(c) 2023-2025 René Amthor");
m->Label("UI7 is licensed under the MIT License.");
m->Label("See LICENSE for more information.");
static bool show_build;
m->Checkbox("Show Build Info", show_build);
if (show_build) {
m->SeparatorText("Build Info");
m->Label("Full Version -> " + GetVersion(true));
m->Label("sizeof(size_t) -> " + std::to_string(sizeof(size_t)));
m->Label("sizeof(LI::Vertex) -> " + std::to_string(sizeof(Li::Vertex)));
m->Label("__cplusplus -> " + std::to_string(__cplusplus));
m->Label("Compiler -> (hidden)"); // + LibInfo::CompiledWith());
}
EndMenu();
}
}
PD_UI7_API void Context::MetricsMenu(bool *show) {
if (BeginMenu("UI7 Metrics", UI7MenuFlags_Scrolling, show)) {
auto m = pCurrent;
m->Label("Palladium - UI7 " + GetVersion());
m->Separator();
m->Label(
std::format("Average {:.3f} ms/f ({:.1f} FPS)",
((float)pIO->DeltaStats->GetAverage() / 1000.f),
1000.f / ((float)pIO->DeltaStats->GetAverage() / 1000.f)));
m->Label(std::format("NumVertices: {}", pIO->NumVertices));
m->Label(std::format("NumIndices: {} -> {} Tris", pIO->NumIndices,
pIO->NumIndices / 3));
m->Label("Menus: " + std::to_string(pMenus.size()));
/** Section TimeTrace */
m->SeparatorText("TimeTrace");
if (m->BeginTreeNode("Traces (" + std::to_string(OS::GetTraceMap().size()) +
")")) {
for (auto &it : OS::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();
}
/** Section IO */
m->SeparatorText("IO");
if (m->BeginTreeNode("Menus (" + std::to_string(pMenus.size()) + ")")) {
for (auto &it : pMenus) {
if (m->BeginTreeNode(it.second->pID.GetName())) {
m->Label("Name: " + it.second->pID.GetName());
m->Label(std::format("Pos: {}", it.second->pLayout->GetPosition()));
m->Label(std::format("Size: {}", it.second->pLayout->GetSize()));
m->Label(std::format("WorkRect: {}", it.second->pLayout->WorkRect));
m->Label(std::format("Cursor: {}", it.second->pLayout->Cursor));
if (m->BeginTreeNode(
"ID Objects (" +
std::to_string(it.second->pLayout->IDObjects.size()) + ")")) {
for (auto &jt : it.second->pLayout->IDObjects) {
m->Label(std::format("{:08X}", jt->GetID()));
}
m->EndTreeNode();
}
m->EndTreeNode();
}
}
m->EndTreeNode();
}
if (m->BeginTreeNode("Active Menus (" +
std::to_string(pCurrentMenus.size()) + ")")) {
for (auto &it : pCurrentMenus) {
if (m->BeginTreeNode(pMenus[it]->pID.GetName())) {
m->Label("Name: " + pMenus[it]->pID.GetName());
m->Label(std::format("Pos: {}", pMenus[it]->pLayout->GetPosition()));
m->Label(std::format("Size: {}", pMenus[it]->pLayout->GetSize()));
m->Label(std::format("WorkRect: {}", pMenus[it]->pLayout->WorkRect));
m->Label(std::format("Cursor: {}", pMenus[it]->pLayout->Cursor));
if (m->BeginTreeNode(
"ID Objects (" +
std::to_string(pMenus[it]->pLayout->IDObjects.size()) +
")")) {
for (auto &jt : pMenus[it]->pLayout->IDObjects) {
m->Label(std::format("{:08X}", jt->GetID()));
}
m->EndTreeNode();
}
m->EndTreeNode();
}
}
m->EndTreeNode();
}
// Well this are Li Drawlists now and they do not count their stats (yet)
/*if (m->BeginTreeNode("DrawLists (" +
std::to_string(pIO->DrawListRegestry.Size()) + ")")) {
for (auto &it : pIO->DrawListRegestry) {
if (m->BeginTreeNode(it.First.GetName())) {
m->Label("Vertices: " + std::to_string(it.Second->NumVertices));
m->Label("Indices: " + std::to_string(it.Second->NumIndices));
m->Label("Base Layer: " + std::to_string(it.Second->Base));
m->EndTreeNode();
}
}
m->EndTreeNode();
}*/
m->Label("io->Time: " + Strings::FormatMillis(pIO->Time->Get()));
m->Label(std::format("Delta: {:.3f}", pIO->Delta));
m->Label(std::format("Framerate: {:.2f}", pIO->Framerate));
m->Label(
std::format("Focused Menu: {:08X}", pIO->InputHandler->FocusedMenu));
m->Label(std::format("Dragged Object: {:08X}",
pIO->InputHandler->DraggedObject));
m->Label(std::format("DragTime: {:.2f}s",
pIO->InputHandler->DragTime->GetSeconds()));
m->Label(std::format("DragDestination: [{}]",
pIO->InputHandler->DragDestination));
m->Label(std::format("DragSource: [{}]", pIO->InputHandler->DragSourcePos));
m->Label(std::format("DragPos: [{}]", pIO->InputHandler->DragPosition));
m->Label(
std::format("DragLastPos: [{}]", pIO->InputHandler->DragLastPosition));
EndMenu();
}
}
PD_UI7_API void UI7::Context::StyleEditor(bool *show) {
if (this->BeginMenu("UI7 Style Editor", UI7MenuFlags_Scrolling, show)) {
auto m = pCurrent;
m->Label("Palladium - UI7 " + GetVersion() + " Style Editor");
m->Separator();
m->DragData("MenuPadding", (float *)&pIO->MenuPadding, 2, 0.f, 100.f);
m->DragData("FramePadding", (float *)&pIO->FramePadding, 2, 0.f, 100.f);
m->DragData("ItemSpace", (float *)&pIO->ItemSpace, 2, 0.f, 100.f);
m->DragData("MinSliderSize", (float *)&pIO->MinSliderDragSize, 2, 1.f,
100.f);
m->DragData("OverScroll Modifier", &pIO->OverScrollMod, 1, 0.01f,
std::numeric_limits<float>::max(), 0.01f, 2);
m->Checkbox("Menu Border", pIO->ShowMenuBorder);
m->Checkbox("Frame Border", pIO->ShowFrameBorder);
m->SeparatorText("Theme");
if (m->Button("Dark")) {
UI7::Theme::Default(*pIO->Theme.get());
}
m->SameLine();
if (m->Button("Flashbang")) {
UI7::Theme::Flashbang(*pIO->Theme.get());
}
/// Small trick to print without prefix
#define ts(x) m->ColorEdit(std::string(#x).substr(9), &pIO->Theme->GetRef(x));
#define ts2(x) \
m->DragData(std::string(#x).substr(9), (u8 *)&pIO->Theme->GetRef(x), 4, \
(u8)0, (u8)255);
ts2(UI7Color_Background);
ts2(UI7Color_Border);
ts2(UI7Color_Button);
ts2(UI7Color_ButtonDead);
ts2(UI7Color_ButtonActive);
ts2(UI7Color_ButtonHovered);
ts2(UI7Color_Text);
ts2(UI7Color_TextDead);
ts2(UI7Color_Header);
ts2(UI7Color_HeaderDead);
ts2(UI7Color_Selector);
ts2(UI7Color_Checkmark);
ts2(UI7Color_FrameBackground);
ts2(UI7Color_FrameBackgroundHovered);
ts2(UI7Color_Progressbar);
ts2(UI7Color_ListEven);
ts2(UI7Color_ListOdd);
this->EndMenu();
}
}
} // namespace UI7
} // namespace PD

View File

@ -17,6 +17,8 @@ void RoundedRect(PD::Li::DrawList::Ref l, PD::fvec2 p, PD::fvec2 s, PD::u32 clr,
} }
int v = 20; int v = 20;
int TheScale = 1;
bool AboutOderSo = true;
int main() { int main() {
void *PD_INIT_DATA = nullptr; void *PD_INIT_DATA = nullptr;
@ -63,9 +65,6 @@ int main() {
ui7->AddViewPort(VpTop, PD::ivec4(0, 0, 400, 240)); ui7->AddViewPort(VpTop, PD::ivec4(0, 0, 400, 240));
ui7->UseViewPort(VpTop); ui7->UseViewPort(VpTop);
ui7->pIO->Font = font; ui7->pIO->Font = font;
PD::UI7::Menu::Ref menu = PD::UI7::Menu::New("Test", ui7->pIO);
bool open_haxx = true;
menu->pIsShown = &open_haxx;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** MainLoop */ /** MainLoop */
#ifndef __3DS__ #ifndef __3DS__
@ -81,6 +80,7 @@ int main() {
int wx, wy; int wx, wy;
glfwGetWindowSize(win, &wx, &wy); glfwGetWindowSize(win, &wx, &wy);
PD::Li::Gfx::pGfx->ViewPort = PD::ivec2(wx, wy); PD::Li::Gfx::pGfx->ViewPort = PD::ivec2(wx, wy);
// ui7->pIO->GetViewPort(VpTop)->pSize = PD::ivec4(0, 0, wx, wy);
#endif #endif
/** Rendering some stuff */ /** Rendering some stuff */
List->DrawSolid(); List->DrawSolid();
@ -90,7 +90,10 @@ int main() {
RoundedRect(List, PD::fvec2(200, 50), 100, 0xffffffff, RoundedRect(List, PD::fvec2(200, 50), 100, 0xffffffff,
((1 + std::sin(PD::OS::GetTime() / 1000.f)) * 0.5f) * 100.f); ((1 + std::sin(PD::OS::GetTime() / 1000.f)) * 0.5f) * 100.f);
List->DrawText(PD::fvec2(50, 190), "OK", 0xffffffff); List->DrawText(PD::fvec2(50, 190), "OK", 0xffffffff);
List->DrawLine(PD::fvec2(0), PD::fvec2(1000, 600), 0xffffffff); // List->DrawLine(PD::fvec2(0), PD::fvec2(1000, 600), 0xffffffff);
List->PathAdd(500);
List->PathAdd(550);
List->PathStroke(0xff00ffff, TheScale);
// List->DrawRectFilled(PD::fvec2(10, 10), PD::fvec2(1260, 700), // List->DrawRectFilled(PD::fvec2(10, 10), PD::fvec2(1260, 700),
// 0xffffffff); // 0xffffffff);
/** Draw text */ /** Draw text */
@ -103,10 +106,12 @@ int main() {
PD::Hid::MousePos()) + PD::Hid::MousePos()) +
"\nUI7 Version: " + PD::UI7::GetVersion(), "\nUI7 Version: " + PD::UI7::GetVersion(),
0xff000000); 0xff000000);
ui7->pIO->InputHandler->CurrentMenu = menu->pID; if (ui7->BeginMenu("Test")) {
if (menu->pIsOpen) { auto menu = ui7->pCurrent;
menu->Label("Hello"); menu->Label("Hello");
menu->Label("World!"); menu->Label("World!");
menu->Checkbox("About Menu", AboutOderSo);
menu->DragData("Line", &TheScale);
if (menu->Button("Test")) { if (menu->Button("Test")) {
break; break;
} }
@ -117,9 +122,50 @@ int main() {
menu->Label( menu->Label(
std::format("Left: {}", PD::Hid::IsHeld(PD::Hid::Key::Touch))); std::format("Left: {}", PD::Hid::IsHeld(PD::Hid::Key::Touch)));
menu->DragData("Value", &v, 1); menu->DragData("Value", &v, 1);
ui7->EndMenu();
} }
menu->Update(); if (ui7->BeginMenu("Yet another Window")) {
auto menu = ui7->pCurrent;
menu->Label(std::format("this->Pos: {}", menu->pLayout->GetPosition()));
menu->Label(
std::format("Vertices: {}", PD::Li::Gfx::pGfx->VertexCounter));
menu->Label(std::format("Indices: {}", PD::Li::Gfx::pGfx->IndexCounter));
ui7->EndMenu();
}
if (ui7->BeginMenu("#Debug (UI7)")) {
auto menu = ui7->pCurrent;
menu->Label(std::format("Framerate: {:.1f} [{:.2f}]", ui7->pIO->Framerate,
ui7->pIO->Delta));
menu->SeparatorText("Input");
menu->Label(std::format("FocusedMenu: #{:08X}",
ui7->pIO->InputHandler->FocusedMenu));
menu->Label(std::format("FocusedMenuRect: {}",
ui7->pIO->InputHandler->FocusedMenuRect));
menu->SeparatorText("Menu Order");
for (auto &it : ui7->pDFO) {
menu->Label(std::format("{}", ui7->pMenus[it]->pID.GetName()));
}
ui7->EndMenu();
}
if (ui7->BeginMenu("NoDebug")) {
auto m = ui7->pCurrent;
if (m->BeginTreeNode("Test")) {
m->Label("Hello World!");
if (m->BeginTreeNode("AnotherNode")) {
m->Label("Another Label!");
m->EndTreeNode();
}
m->EndTreeNode();
}
m->Label("Yes another Label!");
ui7->EndMenu();
}
ui7->AboutMenu(&AboutOderSo);
ui7->MetricsMenu();
ui7->StyleEditor();
PD::TT::Beg("ui7->Update");
ui7->Update(); ui7->Update();
PD::TT::End("ui7->Update");
/** Render DrawData */ /** Render DrawData */
#ifdef __3DS__ #ifdef __3DS__
C3D_FrameBegin(C3D_FRAME_SYNCDRAW); C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
@ -129,10 +175,9 @@ int main() {
PD::TT::Beg("REN"); PD::TT::Beg("REN");
PD::Li::Gfx::NewFrame(); PD::Li::Gfx::NewFrame();
PD::Li::Gfx::RenderDrawData(List->pDrawList); PD::Li::Gfx::RenderDrawData(List->pDrawList);
PD::Li::Gfx::RenderDrawData(menu->pLayout->GetDrawList()->pDrawList); PD::Li::Gfx::RenderDrawData(ui7->GetDrawData()->pDrawList);
/** Clear The List */ /** Clear The List */
List->Clear(); List->Clear();
menu->pLayout->GetDrawList()->pDrawList.clear();
PD::TT::End("REN"); PD::TT::End("REN");
#ifndef __3DS__ #ifndef __3DS__
/** Do OS Specifc Stuff (swapp buffers / window buttan events) */ /** Do OS Specifc Stuff (swapp buffers / window buttan events) */

View File

@ -28,7 +28,9 @@ SOFTWARE.
#include <iostream> #include <iostream>
#include <string> #include <string>
const char* license_text = R"(/* constexpr std::string_view ppa_text = R"(#pragma once
/*
MIT License MIT License
Copyright (c) 2024 - 2025 René Amthor (tobid7) Copyright (c) 2024 - 2025 René Amthor (tobid7)
@ -50,35 +52,34 @@ 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
)";
constexpr std::string_view ppa_text = /** Generated with ppam */
"#pragma once\n\n{0}\n"
"/** Generated with ppam */\n\n" #ifdef _WIN32 // Windows (MSVC Tested)
"#ifdef _WIN32 // Windows (MSVC Tested)\n" #ifdef {0}_BUILD_SHARED
"#ifdef {1}_BUILD_SHARED\n" #define {0}_API __declspec(dllexport)
"#define {1}_API __declspec(dllexport)\n" #else
"#else\n" #define {0}_API __declspec(dllimport)
"#define {1}_API __declspec(dllimport)\n" #endif
"#endif\n" #elif defined(__APPLE__) // macOS (untested yet)
"#elif defined(__APPLE__) // macOS (untested yet)\n" #ifdef {0}_BUILD_SHARED
"#ifdef {1}_BUILD_SHARED\n" #define {0}_API __attribute__((visibility("default")))
"#define {1}_API __attribute__((visibility(\"default\")))\n" #else
"#else\n" #define {0}_API
"#define {1}_API\n" #endif
"#endif\n" #elif defined(__linux__) // Linux (untested yet)
"#elif defined(__linux__) // Linux (untested yet)\n" #ifdef {0}_BUILD_SHARED
"#ifdef {1}_BUILD_SHARED\n" #define {0}_API __attribute__((visibility("default")))
"#define {1}_API __attribute__((visibility(\"default\")))\n" #else
"#else\n" #define {0}_API
"#define {1}_API\n" #endif
"#endif\n" #elif defined(__3DS__) // 3ds Specific
"#elif defined(__3DS__) // 3ds Specific\n" // Only Static supported
"// Only Static supported\n" #define {0}_API
"#define {1}_API\n" #else
"#else\n" #define {0}_API
"#define {1}_API\n" #endif
"#endif\n"; )";
/** /**
* Tool to generate the `pd_p_api.hpp` (Palladium Platform Api) * Tool to generate the `pd_p_api.hpp` (Palladium Platform Api)
@ -91,7 +92,7 @@ int main(int argc, char* argv[]) {
return 0; return 0;
} }
std::fstream off("pd_p_api.hpp", std::ios::out); std::fstream off("pd_p_api.hpp", std::ios::out);
off << std::format(ppa_text, license_text, argv[1]); off << std::format(ppa_text, argv[1]);
off.close(); off.close();
return 0; return 0;
} }