# 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

View File

@ -21,9 +21,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <pd/ui7/ui7.hpp>
#include "pd/ui7/flags.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 UI7 {
@ -32,8 +36,7 @@ PD_UI7_API std::string GetVersion(bool show_build) {
s << ((UI7_VERSION >> 24) & 0xFF) << ".";
s << ((UI7_VERSION >> 16) & 0xFF) << ".";
s << ((UI7_VERSION >> 8) & 0xFF);
if (show_build)
s << "-" << ((UI7_VERSION) & 0xFF);
if (show_build) s << "-" << ((UI7_VERSION) & 0xFF);
return s.str();
}
@ -63,11 +66,271 @@ PD_UI7_API bool Context::BeginMenu(const ID &id, UI7MenuFlags flags,
}
pCurrent = pGetOrCreateMenu(id);
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;
}
PD_UI7_API void Context::Update() { pIO->Update(); }
} // namespace UI7
} // namespace PD
PD_UI7_API void Context::EndMenu() {
/**
* 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