8 Commits
Author SHA1 Message Date
tobid7 3575a6787d hotfix 2025-12-28 21:38:41 +01:00
tobid7 7fc7a2ecb9 QoL Changes
fix timetrace last diff
2025-12-27 23:35:23 +01:00
tobid7 03f65e069f Add TextMapSystem WIP 2025-12-24 18:17:58 +01:00
tobid7 c618c616fe Fix UI7 Crash by safe deleting the elements 2025-12-24 15:05:05 +01:00
tobid7 ac281dc7a9 Update
- Add data getter to DrawList
- Add NoOOS (Out Of screen Rendering) flag to text renderer (requires a textbox)
- UI7 Label Wrapping (optinal and beta)
2025-12-23 19:20:31 +01:00
tobid7 0cb5de882f Fixes and function additions
- Fixed Text pos at NoCollapse flag
- Fix Button Input Api (HandleScrolling after layout Update)
- Add getter for IO and Current Menu
- Add AdObject func wrappers to Menu
2025-12-20 19:25:20 +01:00
tobid7 b3d621a847 Add LayerOptimisation / QoL change 2025-12-19 21:08:32 +01:00
tobid7 4ad00cd2be pd-3ds: Add sysfont loader
- add support for Alpha only textures in rendering
2025-12-19 21:07:57 +01:00
23 changed files with 316 additions and 59 deletions
+2 -1
View File
@@ -28,5 +28,6 @@ SOFTWARE.
#include <pd-3ds/bknd-hid.hpp> #include <pd-3ds/bknd-hid.hpp>
namespace PD { namespace PD {
PD::Li::Font::Ref LoadSystemFont();
void Init(void* data = nullptr); void Init(void* data = nullptr);
} } // namespace PD
+22 -5
View File
@@ -82,6 +82,27 @@ int GetBPP(Li::Texture::Type type) {
return 0; // Error return 0; // Error
} }
void FragCfg(GPU_TEXCOLOR clr) {
C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL);
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvInit(env);
switch (clr) {
case GPU_A4:
case GPU_A8:
case GPU_L4:
case GPU_L8:
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0);
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);
C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE);
break;
default:
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
break;
}
}
void GfxC3D::Init() { void GfxC3D::Init() {
VertexBuffer.resize(4 * 8192); VertexBuffer.resize(4 * 8192);
IndexBuffer.resize(6 * 8192); IndexBuffer.resize(6 * 8192);
@@ -129,11 +150,6 @@ void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, &proj); C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, &proj);
// Mat4 proj = Mat4::Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f); // Mat4 proj = Mat4::Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f);
// C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, (C3D_Mtx*)&proj); // C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, (C3D_Mtx*)&proj);
C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL);
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvInit(env);
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
size_t index = 0; size_t index = 0;
while (index < Commands.size()) { while (index < Commands.size()) {
PD::Li::Texture::Ref Tex = Commands[index]->Tex; PD::Li::Texture::Ref Tex = Commands[index]->Tex;
@@ -166,6 +182,7 @@ void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
} else { } else {
C3D_SetScissor(GPU_SCISSOR_DISABLE, 0, 0, 0, 0); C3D_SetScissor(GPU_SCISSOR_DISABLE, 0, 0, 0, 0);
} }
FragCfg(((C3D_Tex*)Tex->Address)->fmt);
BindTex(Tex->Address); BindTex(Tex->Address);
auto bufInfo = C3D_GetBufInfo(); auto bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo); BufInfo_Init(bufInfo);
+96
View File
@@ -22,10 +22,106 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#include <3ds.h>
#include <palladium> #include <palladium>
#include <pd-3ds.hpp> #include <pd-3ds.hpp>
namespace PD { namespace PD {
PD::Li::Font::Ref LoadSystemFont() {
TT::Scope st("LI_SystemFont"); // Trace loading time
Li::Font::Ref ret = Li::Font::New();
fontEnsureMapped(); // Call this to be sure the font is mapped
// Get some const references for system font loading
const auto fnt = fontGetSystemFont();
const auto fnt_info = fontGetInfo(fnt);
const auto glyph_info = fontGetGlyphInfo(fnt);
// Resize the Texture list by the num of sysfont textures
ret->Textures.resize(glyph_info->nSheets + 1);
/// Modify the Pixel Height by 1.1f to fit the
/// Size og ttf font Rendering
ret->PixelHeight = glyph_info->cellHeight;
// Load the Textures and make sure they don't auto unload
for (size_t i = 0; i < glyph_info->nSheets; i++) {
auto stex = Li::Texture::New();
auto tx = new C3D_Tex;
tx->data = fontGetGlyphSheetTex(fnt, i);
tx->fmt = (GPU_TEXCOLOR)glyph_info->sheetFmt;
tx->size = glyph_info->sheetSize;
tx->width = glyph_info->sheetWidth;
tx->height = glyph_info->sheetHeight;
tx->param = GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) |
GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) |
GPU_TEXTURE_WRAP_S(GPU_REPEAT) | GPU_TEXTURE_WRAP_T(GPU_REPEAT);
tx->border = 0xffffffff;
tx->lodParam = 0;
stex->Address = (Li::TexAddress)tx;
stex->Size = fvec2(tx->width, tx->height);
stex->UV = fvec4(0, 1, 1, 0);
ret->Textures[i] = stex;
}
std::vector<unsigned int> charSet;
// Write the Charset into a vector
for (auto cmap = fnt_info->cmap; cmap; cmap = cmap->next) {
if (cmap->mappingMethod == CMAP_TYPE_DIRECT) {
if (cmap->codeEnd >= cmap->codeBegin) {
charSet.reserve(charSet.size() + cmap->codeEnd - cmap->codeBegin + 1);
for (auto i = cmap->codeBegin; i <= cmap->codeEnd; ++i) {
if (cmap->indexOffset + (i - cmap->codeBegin) == 0xFFFF) break;
charSet.emplace_back(i);
}
}
} else if (cmap->mappingMethod == CMAP_TYPE_TABLE) {
if (cmap->codeEnd >= cmap->codeBegin) {
charSet.reserve(charSet.size() + cmap->codeEnd - cmap->codeBegin + 1);
for (auto i = cmap->codeBegin; i <= cmap->codeEnd; ++i) {
if (cmap->indexTable[i - cmap->codeBegin] == 0xFFFF) continue;
charSet.emplace_back(i);
}
}
} else if (cmap->mappingMethod == CMAP_TYPE_SCAN) {
charSet.reserve(charSet.size() + cmap->nScanEntries);
for (unsigned i = 0; i < cmap->nScanEntries; ++i) {
if (cmap->scanEntries[i].code >= cmap->codeBegin &&
cmap->scanEntries[i].code <= cmap->codeEnd) {
if (cmap->scanEntries[i].glyphIndex != 0xFFFF) {
charSet.emplace_back(cmap->scanEntries[i].code);
}
}
}
} else {
continue;
}
}
// Sort the charset and make sure all values are unique
std::sort(charSet.begin(), charSet.end());
charSet.erase(std::unique(charSet.begin(), charSet.end()));
// Setup the Codepoint map by the charset
for (auto cp : charSet) {
int gidx = fontGlyphIndexFromCodePoint(fnt, cp);
if (gidx >= 0xFFFF) continue;
Li::Font::Codepoint codepoint;
fontGlyphPos_s dat;
fontCalcGlyphPos(&dat, fnt, gidx, GLYPH_POS_CALC_VTXCOORD, 1.f, 1.f);
codepoint.pCodepoint = cp;
codepoint.SimpleUV = fvec4(dat.texcoord.left, dat.texcoord.top,
dat.texcoord.right, dat.texcoord.bottom);
if (dat.sheetIndex < (int)ret->Textures.size()) {
codepoint.Tex = ret->Textures[dat.sheetIndex];
} else {
codepoint.pInvalid = true;
}
codepoint.Size = fvec2(dat.vtxcoord.right, dat.vtxcoord.bottom);
codepoint.Offset = 0;
ret->CodeMap[cp] = codepoint;
}
return ret;
}
void Init(void* data) { void Init(void* data) {
// Dekstop Init Stage // Dekstop Init Stage
// First use default OS Driver // First use default OS Driver
+13 -13
View File
@@ -30,7 +30,7 @@ namespace PD {
* Class to calculate Maximum/Minimum and Average Timings * Class to calculate Maximum/Minimum and Average Timings
*/ */
class TimeStats { class TimeStats {
public: public:
/** /**
* Constructor taking a lengh for the List * Constructor taking a lengh for the List
* @param l Lengh of the data list * @param l Lengh of the data list
@@ -55,8 +55,7 @@ public:
* @return Average * @return Average
*/ */
u64 GetAverage() { u64 GetAverage() {
if (!num_val) if (!num_val) return 0.f;
return 0.f;
u64 res = 0; u64 res = 0;
for (int i = 0; i < num_val; i++) { for (int i = 0; i < num_val; i++) {
res += val[smart_idx(i)]; res += val[smart_idx(i)];
@@ -69,8 +68,7 @@ public:
* @return Minimum value * @return Minimum value
*/ */
u64 GetMin() { u64 GetMin() {
if (!num_val) if (!num_val) return 0.f;
return 0.f;
u64 res = std::numeric_limits<u64>::max(); u64 res = std::numeric_limits<u64>::max();
for (int i = 0; i < num_val; i++) { for (int i = 0; i < num_val; i++) {
res = std::min(val[smart_idx(i)], res); res = std::min(val[smart_idx(i)], res);
@@ -83,8 +81,7 @@ public:
* @return Max Value * @return Max Value
*/ */
u64 GetMax() { u64 GetMax() {
if (!num_val) if (!num_val) return 0.f;
return 0.f;
u64 res = 0; u64 res = 0;
for (int i = 0; i < num_val; i++) { for (int i = 0; i < num_val; i++) {
res = std::max(val[smart_idx(i)], res); res = std::max(val[smart_idx(i)], res);
@@ -122,7 +119,7 @@ public:
*/ */
const size_t GetNumValues() { return num_val; } const size_t GetNumValues() { return num_val; }
private: private:
/** /**
* Get the Next Position to write to * Get the Next Position to write to
* @param c current position * @param c current position
@@ -152,7 +149,7 @@ namespace TT {
* Data Structure for a TimeTrace Result * Data Structure for a TimeTrace Result
*/ */
class Res { class Res {
public: public:
/** Constructore that Inits a protocol at size of 60 frames */ /** Constructore that Inits a protocol at size of 60 frames */
Res() : start(0), end(0) { protocol = TimeStats::New(60); } Res() : start(0), end(0) { protocol = TimeStats::New(60); }
~Res() = default; ~Res() = default;
@@ -185,6 +182,7 @@ public:
*/ */
void SetEnd(u64 v) { void SetEnd(u64 v) {
end = v; end = v;
diff = end - start;
protocol->Add(GetLastDiff()); protocol->Add(GetLastDiff());
} }
/** /**
@@ -197,20 +195,22 @@ public:
* Get Last Diffrence between end and start * Get Last Diffrence between end and start
* @return end - start * @return end - start
*/ */
u64 GetLastDiff() { return end - start; } u64 GetLastDiff() { return diff; }
/** /**
* Get Protcol Reference * Get Protcol Reference
* @return Protocol Ref * @return Protocol Ref
*/ */
TimeStats::Ref GetProtocol() { return protocol; } TimeStats::Ref GetProtocol() { return protocol; }
private: private:
/** Trace ID */ /** Trace ID */
std::string id; std::string id;
/** Start time */ /** Start time */
u64 start; u64 start;
/** End Time */ /** End Time */
u64 end; u64 end;
/** Last Diff */
u64 diff;
/** Protocol */ /** Protocol */
TimeStats::Ref protocol; TimeStats::Ref protocol;
}; };
@@ -240,7 +240,7 @@ PD_CORE_API void End(const std::string &id);
* ``` * ```
*/ */
class Scope { class Scope {
public: public:
/** /**
* Constructor requiring a Name for the Trace * Constructor requiring a Name for the Trace
* @param id Name of the Trace * @param id Name of the Trace
@@ -254,7 +254,7 @@ public:
*/ */
~Scope() { End(ID); } ~Scope() { End(ID); }
private: private:
/** Trace Name/ID */ /** Trace Name/ID */
std::string ID; std::string ID;
}; };
+1
View File
@@ -94,6 +94,7 @@ class Gfx {
static void BindTex(Li::TexAddress addr) { pGfx->BindTex(addr); } static void BindTex(Li::TexAddress addr) { pGfx->BindTex(addr); }
static void SetViewPort(const ivec2& vp) { pGfx->SetViewPort(vp); } static void SetViewPort(const ivec2& vp) { pGfx->SetViewPort(vp); }
static void SetViewPort(int w, int h) { pGfx->SetViewPort(PD::ivec2(w, h)); }
static void RenderDrawData(const std::vector<Li::Command::Ref>& Commands) { static void RenderDrawData(const std::vector<Li::Command::Ref>& Commands) {
pGfx->RenderDrawData(Commands); pGfx->RenderDrawData(Commands);
+6
View File
@@ -40,6 +40,12 @@ class Command {
IndexBuffer.push_back(VertexBuffer.size() + idx); IndexBuffer.push_back(VertexBuffer.size() + idx);
return *this; return *this;
} }
Command& AddIdxs(const u16& a, const u16& b, const u16& c) {
IndexBuffer.push_back(VertexBuffer.size() + a);
IndexBuffer.push_back(VertexBuffer.size() + b);
IndexBuffer.push_back(VertexBuffer.size() + c);
return *this;
}
Command& AddVtx(const Vertex& v) { Command& AddVtx(const Vertex& v) {
VertexBuffer.push_back(std::move(v)); VertexBuffer.push_back(std::move(v));
+19 -2
View File
@@ -64,14 +64,30 @@ class PD_LITHIUM_API DrawList {
/** /**
* Append an input drawlist on top of this one * Append an input drawlist on top of this one
* This Function will clear the Input list to make sure * This Function will clear the Input list to make sure
* THat the moved memory blocks don't get used * That the moved memory blocks don't get used
* @param list DrawList to move into current * @param list DrawList to move into current
*/ */
void Merge(DrawList::Ref list); void Merge(DrawList::Ref list);
/**
* Copy another drawlist to this drawist.
* This is important for static prerendered Drawlists
* @param list DrawList Reference to copy from
*/
void Copy(DrawList::Ref list);
/**
* Optimize a Drawlist to a more or less perfect order
* to reduce drawcall overhead... This function also uses
* the Layersystem to keep specific stuff in the correct order
*/
void Optimize();
Command::Ref PreGenerateCmd(); Command::Ref PreGenerateCmd();
void AddCommand(Command::Ref v); void AddCommand(Command::Ref v);
void Clear(); void Clear();
void Layer(int l) { this->pLayer = l; }
int Layer() { return this->pLayer; }
void LayerUp() { this->pLayer++; }
void LayerDown() { this->pLayer--; }
void SetFont(Font::Ref font) { pCurrentFont = font; } void SetFont(Font::Ref font) { pCurrentFont = font; }
void SetFontScale(float scale) { pFontScale = scale; } void SetFontScale(float scale) { pFontScale = scale; }
@@ -190,13 +206,14 @@ class PD_LITHIUM_API DrawList {
} }
pClipRects.pop(); pClipRects.pop();
} }
const std::vector<Command::Ref>& Data() const { return pDrawList; }
/** One linear Clip rect Setup */ /** One linear Clip rect Setup */
void pClipCmd(Command* cmd); void pClipCmd(Command* cmd);
/** Data Section */ /** Data Section */
std::stack<fvec4> pClipRects; std::stack<fvec4> pClipRects;
int Layer; int pLayer;
float pFontScale = 0.7f; float pFontScale = 0.7f;
Font::Ref pCurrentFont; Font::Ref pCurrentFont;
Texture::Ref CurrentTex; Texture::Ref CurrentTex;
+14
View File
@@ -39,6 +39,7 @@ enum LiTextFlags_ {
LiTextFlags_Wrap = 1 << 3, ///< Wrap Text: May be runs better with TMS LiTextFlags_Wrap = 1 << 3, ///< Wrap Text: May be runs better with TMS
LiTextFlags_Short = 1 << 4, ///< Short Text: May be runs better with TMS LiTextFlags_Short = 1 << 4, ///< Short Text: May be runs better with TMS
LiTextFlags_Scroll = 1 << 5, ///< Not implemented [scoll text if to long] LiTextFlags_Scroll = 1 << 5, ///< Not implemented [scoll text if to long]
LiTextFlags_NoOOS = 1 << 6, ///< No Out of Screen Rendering
}; };
namespace PD { namespace PD {
@@ -95,6 +96,11 @@ class PD_LITHIUM_API Font {
void CmdTextEx(std::vector<Command::Ref>& cmds, const fvec2& pos, u32 color, void CmdTextEx(std::vector<Command::Ref>& cmds, const fvec2& pos, u32 color,
float scale, const std::string& text, LiTextFlags flags = 0, float scale, const std::string& text, LiTextFlags flags = 0,
const fvec2& box = 0); const fvec2& box = 0);
/**
* Garbage collection for TextMapSystem
*/
void CleanupTMS();
/** /**
* Utility function to create a font atlas * Utility function to create a font atlas
* During TTF loading (Internal and should not be called) * During TTF loading (Internal and should not be called)
@@ -115,6 +121,14 @@ class PD_LITHIUM_API Font {
* **Now using unordered map** * **Now using unordered map**
*/ */
std::unordered_map<u32, Codepoint> CodeMap; std::unordered_map<u32, Codepoint> CodeMap;
/** TMS */
struct TMELEM {
PD::u32 ID;
PD::fvec2 Size;
std::string Text;
u64 TimeStamp;
};
std::unordered_map<u32, TMELEM> pTMS;
}; };
} // namespace Li } // namespace Li
} // namespace PD } // namespace PD
+4
View File
@@ -51,6 +51,10 @@ class PD_UI7_API Label : public Container {
* @note This function is usally called by Menu::Update * @note This function is usally called by Menu::Update
* */ * */
void Draw() override; void Draw() override;
/**
* Override Update func to support Text modifications
*/
void Update() override;
private: private:
fvec2 tdim; ///< Text Size fvec2 tdim; ///< Text Size
+1
View File
@@ -77,6 +77,7 @@ class PD_UI7_API IO {
fvec2 MinSliderDragSize = 10.f; // Min height (Vt) and Min Width (Hz) fvec2 MinSliderDragSize = 10.f; // Min height (Vt) and Min Width (Hz)
bool ShowMenuBorder = true; bool ShowMenuBorder = true;
bool ShowFrameBorder = false; // not implemented yet bool ShowFrameBorder = false; // not implemented yet
bool WrapLabels = false; // Beta state
float OverScrollMod = 0.15f; float OverScrollMod = 0.15f;
u64 DoubleClickTime = 500; // Milliseconds u64 DoubleClickTime = 500; // Milliseconds
std::list<std::pair<UI7::ID, Li::DrawList::Ref>> DrawListRegestry; std::list<std::pair<UI7::ID, Li::DrawList::Ref>> DrawListRegestry;
+2
View File
@@ -103,6 +103,8 @@ class PD_UI7_API Layout {
void Update(); void Update();
fvec2 DbgScrollOffset() { return ScrollOffset; }
private: private:
friend class Menu; friend class Menu;
friend class Context; friend class Context;
+5
View File
@@ -103,6 +103,11 @@ class PD_UI7_API Menu {
void HandleTitlebarActions(); void HandleTitlebarActions();
void DrawBaseLayout(); void DrawBaseLayout();
void AddObject(PD::UI7::Container::Ref obj) { pLayout->AddObject(obj); }
void AddObjectEx(PD::UI7::Container::Ref obj, PD::u32 flags) {
pLayout->AddObjectEx(obj, flags);
}
void Update(); void Update();
/** Data Section */ /** Data Section */
+2
View File
@@ -55,10 +55,12 @@ class PD_UI7_API Context {
PD_SHARED(Context); PD_SHARED(Context);
IO::Ref GetIO() { return pIO; }
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 = 0, bool* pShow = nullptr); bool BeginMenu(const ID& id, UI7MenuFlags flags = 0, bool* pShow = nullptr);
Menu::Ref CurrentMenu() { return pCurrent; }
void EndMenu(); void EndMenu();
void AboutMenu(bool* show = nullptr); void AboutMenu(bool* show = nullptr);
void MetricsMenu(bool* show = nullptr); void MetricsMenu(bool* show = nullptr);
+1 -1
View File
@@ -32,7 +32,7 @@ PD_CORE_API std::string Color::Hex(bool rgba) const {
s << std::hex << std::setw(2) << std::setfill('0') << (int)r; s << std::hex << std::setw(2) << std::setfill('0') << (int)r;
s << std::hex << std::setw(2) << std::setfill('0') << (int)g; s << std::hex << std::setw(2) << std::setfill('0') << (int)g;
s << std::hex << std::setw(2) << std::setfill('0') << (int)b; s << std::hex << std::setw(2) << std::setfill('0') << (int)b;
if (rgba) { if (rgba || a != 255) { // QoL change btw
s << std::hex << std::setw(2) << std::setfill('0') << (int)a; s << std::hex << std::setw(2) << std::setfill('0') << (int)a;
} }
return s.str(); return s.str();
+1 -1
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.22) cmake_minimum_required(VERSION 3.22)
## The Core Core Library ## The Core Core Library
project(pd-drivers LANGUAGES CXX VERSION 0.5.1) project(pd-drivers LANGUAGES CXX VERSION 0.6.0)
set(SRC set(SRC
source/hid.cpp source/hid.cpp
+24 -5
View File
@@ -38,6 +38,9 @@ PD_LITHIUM_API void DrawList::Clear() {
pNumVertices = 0; pNumVertices = 0;
pDrawList.clear(); pDrawList.clear();
pPath.clear(); pPath.clear();
if (pCurrentFont) {
pCurrentFont->CleanupTMS();
}
while (!pClipRects.empty()) { while (!pClipRects.empty()) {
pClipRects.pop(); pClipRects.pop();
} }
@@ -59,9 +62,25 @@ PD_LITHIUM_API void DrawList::Merge(DrawList::Ref list) {
list->Clear(); list->Clear();
} }
PD_LITHIUM_API void DrawList::Optimize() {
#ifndef NDEBUG
PD::TT::Scope s("Optimize");
#endif
std::sort(pDrawList.begin(), pDrawList.end(),
[](const PD::Li::Command::Ref &a, const PD::Li::Command::Ref &b) {
if (a->Layer == b->Layer) { // Same layer
if (a->Tex == b->Tex) { // same tex
return a->Index < b->Index;
}
return a->Tex < b->Tex; // order by address
}
return a->Layer < b->Layer; // Order by layer
});
}
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 = pLayer;
cmd->Index = pDrawList.size(); cmd->Index = pDrawList.size();
cmd->Tex = CurrentTex; cmd->Tex = CurrentTex;
pClipCmd(cmd.get()); pClipCmd(cmd.get());
@@ -275,8 +294,8 @@ PD_LITHIUM_API void DrawList::DrawText(const fvec2 &pos,
std::vector<Command::Ref> cmds; std::vector<Command::Ref> cmds;
pCurrentFont->CmdTextEx(cmds, pos, color, pFontScale, text); pCurrentFont->CmdTextEx(cmds, pos, color, pFontScale, text);
for (size_t i = 0; i < cmds.size(); i++) { for (size_t i = 0; i < cmds.size(); i++) {
cmds[i]->Index = pDrawList.size(); cmds[i]->Index = pDrawList.size() + i;
cmds[i]->Layer = Layer; cmds[i]->Layer = pLayer;
AddCommand(std::move(cmds[i])); AddCommand(std::move(cmds[i]));
} }
} }
@@ -290,8 +309,8 @@ PD_LITHIUM_API void DrawList::DrawTextEx(const fvec2 &p,
std::vector<Command::Ref> cmds; std::vector<Command::Ref> cmds;
pCurrentFont->CmdTextEx(cmds, p, color, pFontScale, text, flags, box); pCurrentFont->CmdTextEx(cmds, p, color, pFontScale, text, flags, box);
for (size_t i = 0; i < cmds.size(); i++) { for (size_t i = 0; i < cmds.size(); i++) {
cmds[i]->Index = pDrawList.size(); cmds[i]->Index = pDrawList.size() + i;
cmds[i]->Layer = Layer; cmds[i]->Layer = pLayer;
AddCommand(std::move(cmds[i])); AddCommand(std::move(cmds[i]));
} }
} }
+52
View File
@@ -196,6 +196,11 @@ PD_LITHIUM_API Font::Codepoint &Font::GetCodepoint(u32 cp) {
} }
PD_LITHIUM_API fvec2 Font::GetTextBounds(const std::string &text, float scale) { PD_LITHIUM_API fvec2 Font::GetTextBounds(const std::string &text, float scale) {
u32 id = PD::FNV1A32(text);
if (pTMS.find(id) != pTMS.end()) {
pTMS[id].TimeStamp = PD::OS::GetTime();
return pTMS[id].Size;
}
// Use wstring for exemple for german äöü // Use wstring for exemple for german äöü
auto wtext = Strings::MakeWstring(text); auto wtext = Strings::MakeWstring(text);
// Create a temp position and offset as [0, 0] // Create a temp position and offset as [0, 0]
@@ -237,6 +242,9 @@ PD_LITHIUM_API fvec2 Font::GetTextBounds(const std::string &text, float scale) {
} }
res.x = std::max(res.x, x); res.x = std::max(res.x, x);
res.y += lh; res.y += lh;
pTMS[id].ID = id;
pTMS[id].Size = res;
pTMS[id].TimeStamp = PD::OS::GetTime();
return res; return res;
} }
@@ -272,6 +280,15 @@ PD_LITHIUM_API void Font::CmdTextEx(std::vector<Command::Ref> &cmds,
} }
for (auto &it : lines) { for (auto &it : lines) {
if (flags & LiTextFlags_NoOOS) {
if (rpos.y + off.y + lh < 0) {
off.y += lh;
continue;
}
if (rpos.y + off.y > box.y && box.y != 0) {
break;
}
}
if (flags & LiTextFlags_Short) { if (flags & LiTextFlags_Short) {
fvec2 tmp_dim; fvec2 tmp_dim;
it = pShortText(it, scale, box - pos, tmp_dim); it = pShortText(it, scale, box - pos, tmp_dim);
@@ -322,6 +339,14 @@ PD_LITHIUM_API void Font::CmdTextEx(std::vector<Command::Ref> &cmds,
PD_LITHIUM_API std::string Font::pWrapText(const std::string &txt, float scale, PD_LITHIUM_API std::string Font::pWrapText(const std::string &txt, float scale,
const PD::fvec2 &max, const PD::fvec2 &max,
PD::fvec2 &dim) { PD::fvec2 &dim) {
u32 id = PD::FNV1A32(txt);
if (pTMS.find(id) != pTMS.end()) {
if (pTMS[id].Text.size()) {
dim = pTMS[id].Size;
pTMS[id].TimeStamp = PD::OS::GetTime();
return pTMS[id].Text;
}
}
std::string ret; std::string ret;
std::string line; std::string line;
int lx = 0; int lx = 0;
@@ -341,12 +366,24 @@ PD_LITHIUM_API std::string Font::pWrapText(const std::string &txt, float scale,
} }
ret += line; ret += line;
dim = GetTextBounds(ret, scale); dim = GetTextBounds(ret, scale);
pTMS[id].ID = id;
pTMS[id].Size = dim;
pTMS[id].Text = ret;
pTMS[id].TimeStamp = PD::OS::GetTime();
return ret; return ret;
} }
PD_LITHIUM_API std::string Font::pShortText(const std::string &txt, float scale, PD_LITHIUM_API std::string Font::pShortText(const std::string &txt, float scale,
const PD::fvec2 &max, const PD::fvec2 &max,
PD::fvec2 &dim) { PD::fvec2 &dim) {
u32 id = PD::FNV1A32(txt);
if (pTMS.find(id) != pTMS.end()) {
if (pTMS[id].Text.size()) {
dim = pTMS[id].Size;
pTMS[id].TimeStamp = PD::OS::GetTime();
return pTMS[id].Text;
}
}
auto test = GetTextBounds(txt, scale); auto test = GetTextBounds(txt, scale);
if (test.x < max.x) { if (test.x < max.x) {
return txt; return txt;
@@ -373,8 +410,23 @@ PD_LITHIUM_API std::string Font::pShortText(const std::string &txt, float scale,
} }
ret += it; ret += it;
} }
pTMS[id].ID = id;
pTMS[id].Size = dim;
pTMS[id].Text = ret;
pTMS[id].TimeStamp = PD::OS::GetTime();
return ret; return ret;
} }
PD_LITHIUM_API void Font::CleanupTMS() {
u64 t = PD::OS::GetTime();
for (auto it = pTMS.begin(); it != pTMS.end();) {
if (t - it->second.TimeStamp > 1000) {
it = pTMS.erase(it);
} else {
it++;
}
}
}
} // namespace Li } // namespace Li
} // namespace PD } // namespace PD
+2 -2
View File
@@ -50,10 +50,10 @@ PD_UI7_API void Button::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);
list->DrawRectFilled(FinalPos(), size, io->Theme->Get(color)); list->DrawRectFilled(FinalPos(), size, io->Theme->Get(color));
list->Layer++; list->pLayer++;
list->DrawText(FinalPos() + size * 0.5 - tdim * 0.5, label, list->DrawText(FinalPos() + size * 0.5 - tdim * 0.5, label,
io->Theme->Get(UI7Color_Text)); io->Theme->Get(UI7Color_Text));
list->Layer--; list->pLayer--;
} }
PD_UI7_API void Button::Update() { PD_UI7_API void Button::Update() {
+2 -2
View File
@@ -83,11 +83,11 @@ PD_UI7_API void DragData<T>::Draw() {
vec2 td = io->Font->GetTextBounds(p, io->FontScale); vec2 td = io->Font->GetTextBounds(p, io->FontScale);
list->DrawRectFilled(FinalPos() + fvec2(off_x, 0), td + io->FramePadding, list->DrawRectFilled(FinalPos() + fvec2(off_x, 0), td + io->FramePadding,
io->Theme->Get(UI7Color_Button)); io->Theme->Get(UI7Color_Button));
list->Layer++; list->pLayer++;
list->DrawTextEx(FinalPos() + fvec2(off_x, 0), p, list->DrawTextEx(FinalPos() + fvec2(off_x, 0), p,
io->Theme->Get(UI7Color_Text), LiTextFlags_AlignMid, io->Theme->Get(UI7Color_Text), LiTextFlags_AlignMid,
td + io->FramePadding); td + io->FramePadding);
list->Layer--; list->pLayer--;
off_x += td.x + io->ItemSpace.x + io->FramePadding.x; off_x += td.x + io->ItemSpace.x + io->FramePadding.x;
} }
list->DrawText(FinalPos() + fvec2(off_x, io->FramePadding.y * 0.5), label, list->DrawText(FinalPos() + fvec2(off_x, io->FramePadding.y * 0.5), label,
+2 -2
View File
@@ -29,11 +29,11 @@ PD_UI7_API void Image::Draw() {
// Assert(io.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!"); // Assert(img.get(), "Image is nullptr!");
// io->Ren->OnScreen(screen); // io->Ren->OnScreen(screen);
list->Layer++; list->pLayer++;
list->DrawTexture(img); list->DrawTexture(img);
list->DrawRectFilled(FinalPos(), newsize, 0xffffffff); list->DrawRectFilled(FinalPos(), newsize, 0xffffffff);
list->DrawSolid(); list->DrawSolid();
list->Layer--; list->pLayer--;
} }
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD
+18 -1
View File
@@ -31,10 +31,27 @@ PD_UI7_API void Label::Draw() {
if (pCLipRectUsed) { if (pCLipRectUsed) {
list->PushClipRect(pClipRect); list->PushClipRect(pClipRect);
} }
list->DrawText(FinalPos(), label, io->Theme->Get(UI7Color_Text)); list->DrawTextEx(FinalPos(), label, io->Theme->Get(UI7Color_Text),
LiTextFlags_NoOOS, PD::fvec2(0, io->CurrentViewPort.w));
if (pCLipRectUsed) { if (pCLipRectUsed) {
list->PopClipRect(); list->PopClipRect();
} }
} }
PD_UI7_API void Label::Update() {
/**
* Todo: This is a hacky workaround
* Needs proper optimisation
* Needs a max size (to support sligning dynaically by the window size)
*/
if (io->WrapLabels) {
this->label =
io->Font->pWrapText(this->label, io->FontScale,
PD::fvec2(io->CurrentViewPort.z - FinalPos().x * 4,
io->CurrentViewPort.w),
this->tdim);
SetSize(tdim);
}
}
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD
+7 -7
View File
@@ -124,15 +124,15 @@ PD_UI7_API void Layout::Update() {
it->Draw(); it->Draw();
} }
} }
std::vector<size_t> tbr;
for (size_t i = 0; i < IDObjects.size(); i++) { for (auto it = IDObjects.begin(); it != IDObjects.end();) {
if (IDObjects[i]->Removable()) { if ((*it)->Removable()) {
tbr.push_back(i); it = IDObjects.erase(it);
} else {
it++;
} }
} }
for (auto& it : tbr) {
IDObjects.erase(IDObjects.begin() + it);
}
Objects.clear(); Objects.clear();
WorkRect = fvec4(fvec2(WorkRect.x, WorkRect.y), Size - IO->MenuPadding); WorkRect = fvec4(fvec2(WorkRect.x, WorkRect.y), Size - IO->MenuPadding);
CursorInit(); CursorInit();
+17 -14
View File
@@ -81,7 +81,9 @@ PD_UI7_API void Menu::Separator() {
pIO->Theme->Get(UI7Color_TextDead)); pIO->Theme->Get(UI7Color_TextDead));
}); });
// Set size before pushing (cause Cursor Move will require it) // Set size before pushing (cause Cursor Move will require it)
r->SetSize(fvec2(pLayout->Size.x - 10, 1)); r->SetSize(fvec2(
pLayout->Size.x - pIO->MenuPadding.x * 2 - pLayout->InitialCursorOffset.x,
1));
pLayout->AddObject(r); pLayout->AddObject(r);
} }
@@ -109,8 +111,9 @@ PD_UI7_API void Menu::SeparatorText(const std::string& label) {
fvec2(pLayout->Size.x, self->GetSize().y)); fvec2(pLayout->Size.x, self->GetSize().y));
}); });
// Set size before pushing (cause Cursor Move will require it) // Set size before pushing (cause Cursor Move will require it)
r->SetSize( r->SetSize(fvec2(
fvec2(pLayout->Size.x - 10, pIO->Font->PixelHeight * pIO->FontScale)); pLayout->Size.x - pIO->MenuPadding.x * 2 - pLayout->InitialCursorOffset.x,
pIO->Font->PixelHeight * pIO->FontScale));
pLayout->AddObject(r); pLayout->AddObject(r);
} }
PD_UI7_API void Menu::HandleFocus() { PD_UI7_API void Menu::HandleFocus() {
@@ -148,7 +151,7 @@ PD_UI7_API void Menu::HandleScrolling() {
pLayout->ScrollOffset.y = std::clamp( pLayout->ScrollOffset.y = std::clamp(
pLayout->ScrollStart.y + pIO->InputHandler->DragSourcePos.y - pLayout->ScrollStart.y + pIO->InputHandler->DragSourcePos.y -
pIO->InputHandler->DragPosition.y, pIO->InputHandler->DragPosition.y,
20.f, pLayout->MaxPosition.y - 220); -20.f, pLayout->MaxPosition.y - 220);
} }
} }
} else { } else {
@@ -239,7 +242,7 @@ PD_UI7_API void Menu::DrawBaseLayout() {
if (!(Flags & UI7MenuFlags_NoResize)) { if (!(Flags & UI7MenuFlags_NoResize)) {
Container::Ref r = DynObj::New( Container::Ref r = DynObj::New(
[](IO::Ref io, Li::DrawList::Ref l, UI7::Container* self) { [](IO::Ref io, Li::DrawList::Ref l, UI7::Container* self) {
l->Layer = 1; l->pLayer = 1;
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(0, 20)); l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(0, 20));
l->PathAdd(self->FinalPos() + self->GetSize()); l->PathAdd(self->FinalPos() + self->GetSize());
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(20, 0)); l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(20, 0));
@@ -255,7 +258,7 @@ PD_UI7_API void Menu::DrawBaseLayout() {
/** Background */ /** 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->pLayer = 0;
l->PathRectEx(self->FinalPos(), self->FinalPos() + self->GetSize(), 10.f, l->PathRectEx(self->FinalPos(), self->FinalPos() + self->GetSize(), 10.f,
LiPathRectFlags_KeepTop | LiPathRectFlags_KeepBot); LiPathRectFlags_KeepTop | LiPathRectFlags_KeepBot);
l->PathFill(io->Theme->Get(UI7Color_Background)); l->PathFill(io->Theme->Get(UI7Color_Background));
@@ -272,19 +275,19 @@ PD_UI7_API void Menu::DrawBaseLayout() {
if (!(Flags & UI7MenuFlags_NoTitlebar)) { if (!(Flags & UI7MenuFlags_NoTitlebar)) {
Container::Ref r = DynObj::New( Container::Ref r = DynObj::New(
[=, this](UI7::IO::Ref io, Li::DrawList::Ref l, UI7::Container* self) { [=, this](UI7::IO::Ref io, Li::DrawList::Ref l, UI7::Container* self) {
l->Layer = 20; l->pLayer = 20;
/** Header Bar */ /** Header Bar */
l->DrawRectFilled(self->FinalPos(), self->GetSize(), l->DrawRectFilled(self->FinalPos(), self->GetSize(),
io->Theme->Get(UI7Color_Header)); io->Theme->Get(UI7Color_Header));
l->Layer = 21; l->pLayer = 21;
/** Inline if statement to shift the Text if collapse sym is shown */ /** Inline if statement to shift the Text if collapse sym is shown */
/** What the hell is this code btw (didn't found a better way) */ /** What the hell is this code btw (didn't found a better way) */
l->DrawText(self->FinalPos() + fvec2(Flags & UI7MenuFlags_NoClose l->DrawText(self->FinalPos() + fvec2((Flags & UI7MenuFlags_NoCollapse)
? 0 ? pIO->FramePadding.x
: (TitleBarHeight - : (TitleBarHeight -
pIO->FramePadding.y * 2 + pIO->FramePadding.y * 2 +
(io->FramePadding.x * 2)), (io->FramePadding.x * 2)),
0), 2),
pID.GetName(), io->Theme->Get(UI7Color_Text)); pID.GetName(), io->Theme->Get(UI7Color_Text));
}); });
r->SetSize(fvec2(pLayout->GetSize().x, TitleBarHeight)); r->SetSize(fvec2(pLayout->GetSize().x, TitleBarHeight));
@@ -297,7 +300,7 @@ PD_UI7_API void Menu::DrawBaseLayout() {
r = DynObj::New([=, this](UI7::IO::Ref io, Li::DrawList::Ref l, r = DynObj::New([=, this](UI7::IO::Ref io, Li::DrawList::Ref l,
UI7::Container* self) { UI7::Container* self) {
/** This sym actually requires layer 21 (i dont know why) */ /** This sym actually requires layer 21 (i dont know why) */
l->Layer = 21; l->pLayer = 21;
/** /**
* Symbol (Position Swapping set by pIsOpen ? openpos : closepos;) * Symbol (Position Swapping set by pIsOpen ? openpos : closepos;)
*/ */
@@ -344,11 +347,11 @@ PD_UI7_API void Menu::Update() {
TitleBarHeight = 0.f; TitleBarHeight = 0.f;
pLayout->WorkRect.y = 5.f; pLayout->WorkRect.y = 5.f;
} }
DrawBaseLayout();
pLayout->Update();
if (Flags & UI7MenuFlags_VtScrolling || Flags & UI7MenuFlags_HzScrolling) { if (Flags & UI7MenuFlags_VtScrolling || Flags & UI7MenuFlags_HzScrolling) {
HandleScrolling(); HandleScrolling();
} }
DrawBaseLayout();
pLayout->Update();
} }
PD_UI7_API bool Menu::BeginTreeNode(const ID& id) { PD_UI7_API bool Menu::BeginTreeNode(const ID& id) {