# Changes 0.2.8

- Fix Flickering problem in StaticText api
- Fix Lagacy and Container HandleScrolling InBox checks
- Add IO Flags define for future
- Implement Single Object Dragging API by IO Context
- Add TreeNodes
- Use ioMenuPadding and ItemSpace
- Add StyleEditorMenu
- Rework ContainerApi to take functions from IO and add an Update function template for Updating internal values if required
- Use new DragApi for MenuCollabse, MenuDragging, MenuResize, SliderDragging and TreeNodes Open/Close
- Add Helper Defines for Metrics Menu [INTERNAL]
- Add TimeTrace as Tree to Metrics as well as other new Data
- Add GetRawObject to StaticText for custom rendering like ui7
- Add DrawlistRegestry to correctly render Menus in their own layer ranges
This commit is contained in:
2025-03-08 13:52:11 +01:00
parent e282d0ec7e
commit 09b1937a8d
22 changed files with 536 additions and 266 deletions

View File

@ -42,6 +42,9 @@ void StaticText::Setup(Renderer* ren, const vec2& pos, u32 clr,
ren->TextCommand(this->text->List(), pos, clr, text,
flags | LITextFlags_RenderOOS, box);
Renderer::OptiCommandList(this->text->List());
// Make sure to bring the text in edit mode
// Fixes flickering problems in ui7
this->text->ReCopy();
}
void StaticText::Draw() {

View File

@ -48,12 +48,16 @@ void Button::HandleInput(Hid::Ref inp) {
inp_done = true;
}
void Button::Draw() {
Assert(ren.get() && list.get() && theme,
"Did you run Container::Init correctly?");
ren->OnScreen(screen);
list->AddRectangle(FinalPos(), size, theme->Get(color));
Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
io->Ren->OnScreen(screen);
list->AddRectangle(FinalPos(), size, io->Theme->Get(color));
list->AddText(FinalPos() + size * 0.5 - tdim * 0.5, label,
theme->Get(UI7Color_Text));
io->Theme->Get(UI7Color_Text));
}
void Button::Update() {
Assert(io.get(), "Did you run Container::Init correctly?");
this->SetSize(tdim + io->FramePadding);
}
} // namespace UI7
} // namespace PD

View File

@ -47,15 +47,21 @@ void Checkbox::HandleInput(Hid::Ref inp) {
inp_done = true;
}
void Checkbox::Draw() {
Assert(ren.get() && list.get() && theme,
"Did you run Container::Init correctly?");
ren->OnScreen(screen);
list->AddRectangle(FinalPos(), cbs, theme->Get(color));
Assert(list.get() && io.get(), "Did you run Container::Init correctly?");
io->Ren->OnScreen(screen);
list->AddRectangle(FinalPos(), cbs, io->Theme->Get(color));
if (usr_ref) {
list->AddRectangle(FinalPos() + 2, cbs - 4, theme->Get(UI7Color_Checkmark));
list->AddRectangle(FinalPos() + 2, cbs - 4,
io->Theme->Get(UI7Color_Checkmark));
}
list->AddText(FinalPos() + vec2(cbs.x() + 5, cbs.y() * 0.5 - tdim.y() * 0.5),
label, theme->Get(UI7Color_Text));
list->AddText(FinalPos() + vec2(cbs.x() + io->ItemSpace.x(),
cbs.y() * 0.5 - tdim.y() * 0.5),
label, io->Theme->Get(UI7Color_Text));
}
void Checkbox::Update() {
Assert(io.get(), "Did you run Container::Init correctly?");
this->SetSize(cbs + vec2(tdim.x() + io->ItemSpace.x(), 0));
}
} // namespace UI7
} // namespace PD

View File

@ -32,7 +32,8 @@ void Container::HandleScrolling(vec2 scrolling, vec4 viewport) {
}
last_use = Sys::GetTime();
pos -= vec2(0, scrolling.y());
skippable = !LI::Renderer::InBox(pos, size, viewport);
skippable = !LI::Renderer::InBox(
pos, size, vec4(viewport.xy(), viewport.xy() + viewport.zw()));
}
} // namespace UI7
} // namespace PD

View File

@ -26,9 +26,9 @@ SOFTWARE.
namespace PD {
namespace UI7 {
void Image::Draw() {
Assert(ren.get() && list.get(), "Did you run Container::Init correctly?");
Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
Assert(img.get(), "Image is nullptr!");
ren->OnScreen(screen);
io->Ren->OnScreen(screen);
list->AddImage(FinalPos(), img, newsize);
}
} // namespace UI7

View File

@ -26,10 +26,9 @@ SOFTWARE.
namespace PD {
namespace UI7 {
void Label::Draw() {
Assert(ren.get() && list.get() && theme,
"Did you run Container::Init correctly?");
ren->OnScreen(screen);
list->AddText(FinalPos(), label, theme->Get(UI7Color_Text));
Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
io->Ren->OnScreen(screen);
list->AddText(FinalPos(), label, io->Theme->Get(UI7Color_Text));
}
} // namespace UI7
} // namespace PD

View File

@ -68,27 +68,33 @@ void DrawList::AddText(vec2 pos, const std::string& text, const UI7Color& clr,
return;
}
u32 id = Strings::FastHash(text);
auto e = static_text.find(id);
if (e == static_text.end()) {
static_text[id] = LI::StaticText::New();
e = static_text.find(id);
LI::StaticText::Ref e;
auto f = static_text.find(id);
if (static_text.find(id) == static_text.end()) {
e = LI::StaticText::New();
static_text[id] = e;
} else {
e = f->second;
}
if (!e->second->IsSetup() || e->second->Font() != ren->Font()) {
if (!e->IsSetup() || e->Font() != ren->Font()) {
int l = ren->Layer();
ren->Layer(base);
/// Probably a simple ren.get() would handle the job too
e->second->Setup(&(*ren), pos, clr, text, flags, box);
e->second->Font(ren->Font());
e->Setup(ren.get(), pos, clr, text, flags, box);
e->Font(ren->Font());
ren->Layer(l);
}
e->second->SetPos(pos);
e->second->SetColor(clr);
e->second->SetLayer(layer);
e->SetPos(pos);
e->SetColor(clr);
e->SetLayer(layer);
if (!clip_rects.empty()) {
e->second->SetScissorMode(LI::ScissorMode_Normal);
e->second->ScissorRect(clip_rects.top());
e->SetScissorMode(LI::ScissorMode_Normal);
e->ScissorRect(clip_rects.top());
}
e->second->Draw();
for (auto it : e->GetRawObject()->List()) {
this->commands.push_back(std::make_pair(
ren->CurrentScreen()->ScreenType() == Screen::Bottom, it));
}
e->GetRawObject()->ReCopy();
////// STILL LEAVING THE OLD CODE BELOW AS IT IS MAYBE NEEDED //////
////// IF STATIC TEXT SYSTEM SHOULD HAVE AN DISABLE OPTION //////

34
source/ui7/io.cpp Normal file
View File

@ -0,0 +1,34 @@
/*
MIT License
Copyright (c) 2024 - 2025 René Amthor (tobid7)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <pd/core/timetrace.hpp>
#include <pd/ui7/io.hpp>
namespace PD {
void UI7::IO::Update() {
Time->Update();
DragTime->Update();
DragReleased = false;
Framerate = 1000.f / Delta;
}
} // namespace PD

View File

@ -28,11 +28,10 @@ SOFTWARE.
namespace PD {
namespace UI7 {
void UI7::Menu::Label(const std::string& label) {
Container::Ref r =
ObjectPush(PD::New<UI7::Label>(label, Cursor(), this->back->ren));
r->SetPos(AlignPos(r->GetPos(), r->GetSize(), view_area, GetAlignment()));
Container::Ref r = ObjectPush(PD::New<UI7::Label>(label, io->Ren));
r->SetPos(AlignPos(Cursor(), r->GetSize(), view_area, GetAlignment()));
CursorMove(r->GetSize());
r->Init(main->ren, main, theme);
r->Init(io, main);
r->HandleScrolling(scrolling_off, view_area);
}
@ -41,12 +40,13 @@ bool UI7::Menu::Button(const std::string& label) {
u32 id = Strings::FastHash("btn" + label + std::to_string(count_btn++));
Container::Ref r = FindIDObj(id);
if (!r) {
r = PD::New<UI7::Button>(label, Cursor(), this->back->ren);
r = PD::New<UI7::Button>(label, io);
r->SetID(id);
r->Init(main->ren, main, theme);
r->Init(io, main);
}
ObjectPush(r);
r->SetPos(AlignPos(Cursor(), r->GetSize(), view_area, GetAlignment()));
r->Update();
CursorMove(r->GetSize());
r->HandleScrolling(scrolling_off, view_area);
if (!r->Skippable()) {
@ -59,22 +59,22 @@ void UI7::Menu::Checkbox(const std::string& label, bool& v) {
u32 id = Strings::FastHash("cbx" + label + std::to_string(count_cbx++));
Container::Ref r = FindIDObj(id);
if (!r) {
r = PD::New<UI7::Checkbox>(label, Cursor(), v, this->back->ren);
r = PD::New<UI7::Checkbox>(label, v, io);
r->SetID(id);
r->Init(main->ren, main, theme);
r->Init(io, main);
}
ObjectPush(r);
r->SetPos(AlignPos(Cursor(), r->GetSize(), view_area, GetAlignment()));
r->Update();
CursorMove(r->GetSize());
r->HandleScrolling(scrolling_off, view_area);
}
void UI7::Menu::Image(Texture::Ref img, vec2 size) {
Container::Ref r =
ObjectPush(PD::New<UI7::Image>(img, Cursor(), this->back->ren, size));
r->SetPos(AlignPos(r->GetPos(), r->GetSize(), view_area, GetAlignment()));
Container::Ref r = ObjectPush(PD::New<UI7::Image>(img, size));
r->SetPos(AlignPos(Cursor(), r->GetSize(), view_area, GetAlignment()));
CursorMove(r->GetSize());
r->Init(main->ren, main, theme);
r->Init(io, main);
r->HandleScrolling(scrolling_off, view_area);
}
@ -120,8 +120,9 @@ void UI7::Menu::Update(float delta) {
scrolling_off = scroll_anim;
}
if (!(flags & UI7MenuFlags_NoClipRect)) {
main->PushClipRect(vec4(view_area.x() + 5, view_area.y() + tbh,
view_area.x() + view_area.z() - 12,
main->PushClipRect(vec4(view_area.x() + io->MenuPadding[0],
view_area.y() + tbh,
view_area.x() + view_area.z() - io->MenuPadding[0],
view_area.y() + view_area.w()));
}
std::vector<int> tbr;
@ -132,7 +133,7 @@ void UI7::Menu::Update(float delta) {
}
if (!it->Skippable()) {
if (scroll_mod[1] == 0.f) {
it->HandleInput(inp);
it->HandleInput(io->Inp);
}
/// Unlock Input after to ensure nothing is checked twice
it->UnlockInput();
@ -150,20 +151,18 @@ void UI7::Menu::Update(float delta) {
if (!(flags & UI7MenuFlags_NoClipRect)) {
main->PopClipRect();
}
this->back->Process();
this->main->Process();
this->front->Process();
this->objects.clear();
}
void UI7::Menu::CursorMove(const vec2& size) {
last_size = size;
slcursor = cursor + vec2(size[0] + 5, 0);
slcursor = cursor + vec2(size[0] + io->ItemSpace[0], 0);
if (bslpos[1]) {
cursor = vec2(5, cursor[1] + bslpos[1] + 5);
cursor = vec2(io->MenuPadding[0], cursor[1] + bslpos[1] + io->ItemSpace[1]);
bslpos = vec2();
} else {
cursor = vec2(5, cursor[1] + size[1] + 5);
cursor = vec2(io->MenuPadding[0] + icursoroff[0],
cursor[1] + size[1] + io->ItemSpace[1]);
}
max = vec2(slcursor[0], cursor[1]);
}
@ -183,26 +182,24 @@ void UI7::Menu::PreHandler(UI7MenuFlags flags) {
if (!(flags & UI7MenuFlags_NoBackground) && is_open) {
back->AddRectangle(view_area.xy() + vec2(0, tbh),
view_area.zw() - vec2(0, tbh),
theme->Get(UI7Color_Background));
io->Theme->Get(UI7Color_Background));
}
if (!(flags & UI7MenuFlags_NoTitlebar)) {
// Title bar setup and Rendering
tbh = front->ren->TextScale() * 30.f;
front->AddRectangle(view_area.xy(), vec2(view_area.z(), tbh),
theme->Get(UI7Color_Header));
vec2 tpos(5, tbh * 0.5 - front->ren->GetTextDimensions(name).y() * 0.5);
io->Theme->Get(UI7Color_Header));
vec2 tpos(io->MenuPadding[0],
tbh * 0.5 - front->ren->GetTextDimensions(name).y() * 0.5);
if (!(flags & UI7MenuFlags_NoCollapse)) {
tpos.x() += 18;
vec2 cpos = view_area.xy() + 5;
vec2 cpos = view_area.xy() + io->FramePadding;
UI7Color clr = UI7Color_FrameBackground;
if (inp->IsUp(inp->Touch) &&
LI::Renderer::InBox(inp->TouchPosLast(), vec4(cpos, vec2(18, tbh))) &&
has_touch) {
is_open = !is_open;
}
if (inp->IsHeld(inp->Touch) &&
LI::Renderer::InBox(inp->TouchPos(), vec4(cpos, vec2(18, tbh))) &&
has_touch) {
if (has_touch &&
io->DragObject(UI7::ID(name + "clbse"), vec4(cpos, vec2(18, tbh)))) {
if (io->DragReleased) {
is_open = !is_open;
}
clr = UI7Color_FrameBackgroundHovered;
}
vec2 positions[2] = {
@ -215,7 +212,7 @@ void UI7::Menu::PreHandler(UI7MenuFlags flags) {
positions[1].x() = t;
}
this->front->AddTriangle(cpos, cpos + positions[0], cpos + positions[1],
theme->Get(clr));
io->Theme->Get(clr));
}
LITextFlags tflags = LITextFlags_None;
if (flags & UI7MenuFlags_CenterTitle) {
@ -223,39 +220,27 @@ void UI7::Menu::PreHandler(UI7MenuFlags flags) {
tflags = LITextFlags_AlignMid;
}
front->Layer(front->Layer() + 1);
front->AddText(view_area.xy() + tpos, this->name, theme->Get(UI7Color_Text),
tflags, vec2(view_area.z(), tbh));
front->AddText(view_area.xy() + tpos, this->name,
io->Theme->Get(UI7Color_Text), tflags,
vec2(view_area.z(), tbh));
main_area[1] = tbh;
CursorInit();
// Menu Movement
if (!(flags & UI7MenuFlags_NoMove)) {
if (inp->IsDown(inp->Touch) &&
LI::Renderer::InBox(
inp->TouchPos(),
vec4(view_area.xy() + vec2(18, 0), vec2(view_area.z(), tbh))) &&
has_touch) {
mouse = inp->TouchPos();
} else if (inp->IsUp(inp->Touch) &&
LI::Renderer::InBox(inp->TouchPos(),
vec4(view_area.xy() + vec2(18, 0),
vec2(view_area.z(), tbh))) &&
has_touch) {
mouse = 0;
} else if (inp->IsHeld(inp->Touch) &&
LI::Renderer::InBox(inp->TouchPos(),
vec4(view_area.xy() + vec2(18, 0),
vec2(view_area.z(), tbh))) &&
has_touch) {
if (has_touch &&
io->DragObject(name + "tmv", vec4(view_area.xy() + vec2(18, 0),
vec2(view_area.z(), tbh)))) {
view_area =
vec4(view_area.xy() + (inp->TouchPos() - mouse), view_area.zw());
mouse = inp->TouchPos();
vec4(view_area.xy() + (io->DragPosition - io->DragLastPosition),
view_area.zw());
}
}
}
// Add a clip Rect for Separators
if (!(flags & UI7MenuFlags_NoClipRect)) {
main->PushClipRect(vec4(view_area.x() + 5, view_area.y() + tbh,
view_area.x() + view_area.z() - 12,
main->PushClipRect(vec4(view_area.x() + io->MenuPadding[0],
view_area.y() + tbh,
view_area.x() + view_area.z() - io->MenuPadding[0],
view_area.y() + view_area.w()));
}
}
@ -263,27 +248,22 @@ void UI7::Menu::PreHandler(UI7MenuFlags flags) {
void UI7::Menu::PostHandler() {
TT::Scope st("MPOS_" + name);
if (!(flags & UI7MenuFlags_NoResize)) {
front->AddRectangle(view_area.xy() + view_area.zw() - 20, 20, 0xffffffff);
if (inp->IsDown(inp->Touch) &&
LI::Renderer::InBox(inp->TouchPos(),
vec4(view_area.xy() + view_area.zw() - 20, 20)) &&
has_touch) {
mouse = inp->TouchPos();
if (has_touch &&
io->DragObject(name + "rszs",
vec4(view_area.xy() + view_area.zw() - 20, 20))) {
view_area = vec4(view_area.xy(), view_area.zw() + (io->DragPosition -
io->DragLastPosition));
}
if (inp->IsHeld(inp->Touch) &&
LI::Renderer::InBox(inp->TouchPos(),
vec4(view_area.xy() + view_area.zw() - 20, 20)) &&
has_touch) {
view_area =
vec4(view_area.xy(), view_area.zw() + (inp->TouchPos() - mouse));
mouse = inp->TouchPos();
}
// Not vidible dor some reason
// front->AddTriangle(10, vec2(10, 0), vec2(10, 0), 0xffffffff);
// front->AddRectangle(view_area.xy() + view_area.zw() - 20, 20,
// 0xffffffff); Not vidible dor some reason
int l = front->Layer();
front->Layer(l + 1);
front->AddTriangle(10, vec2(10, 0), vec2(10, 0), 0xffffffff);
front->Layer(l);
}
if (scrolling[1]) {
scroll_allowed[1] = (max[1] > view_area.w() - 5);
if (max[1] < view_area.w() - 5) {
scroll_allowed[1] = (max[1] > view_area.w() - io->MenuPadding[1]);
if (max[1] < view_area.w() - io->MenuPadding[1]) {
scrolling_off[1] = 0.f;
}
scrollbar[1] = scroll_allowed[1];
@ -291,9 +271,9 @@ void UI7::Menu::PostHandler() {
if (scrollbar[1]) {
/// Setup Some Variables hare [they are self described]
int screen_w = view_area.z();
int tsp = 5 + tbh;
int tsp = io->MenuPadding[1] + tbh;
int slider_w = 4;
int szs = view_area.w() - tsp - 5;
int szs = view_area.w() - tsp - io->MenuPadding[1];
/// Actually dont have a Horizontal bar yet
if (scrollbar[0]) szs -= slider_w - 2;
int lslider_h = 20; // Dont go less heigt for the drag
@ -304,7 +284,7 @@ void UI7::Menu::PostHandler() {
/// Check if we overscroll to the bottom and Auto scroll back...
/// Probably schould use Tween ENgine here
if (scrolling_off[1] > max[1] - view_area[3] && max[1] != 0.f &&
max[1] >= view_area[3] - 5) {
max[1] >= view_area[3] - io->MenuPadding[1]) {
scrolling_off[1] -= 3.f;
if (scrolling_off[1] < max[1] - view_area[3]) {
scrolling_off[1] = max[1] - view_area[3];
@ -326,14 +306,14 @@ void UI7::Menu::PostHandler() {
}
/// The pain :(
if (has_touch) {
vec2 tpos = inp->TouchPos();
if (inp->IsDown(inp->Touch)) {
if (has_touch && !io->IsObjectDragged()) {
vec2 tpos = io->Inp->TouchPos();
if (io->Inp->IsDown(io->Inp->Touch)) {
mouse = tpos;
} else if (inp->IsUp(inp->Touch)) {
} else if (io->Inp->IsUp(io->Inp->Touch)) {
mouse = vec2();
}
if (inp->IsHeld(inp->Touch)) {
if (io->Inp->IsHeld(io->Inp->Touch)) {
if (front->ren->InBox(tpos, vec4(view_area.xy() + main_area.xy(),
main_area.zw()))) {
if (scrolling_off[1] < max[1] - view_area[3] + 40 &&
@ -365,22 +345,22 @@ void UI7::Menu::PostHandler() {
scroll_mod[1] = 0;
}
}
UI7Color sldr_drag = UI7Color_Button;
/// Slider Dragging????
/// Probably need a new API for this
auto tp = inp->TouchPos();
if (inp->IsHeld(inp->Touch) &&
LI::Renderer::InBox(tp, vec4(view_area.x() + screen_w - 12,
view_area.y() + tsp, 8, szs))) {
if (has_touch &&
io->DragObject(name + "sldr", vec4(view_area.x() + screen_w - 12,
view_area.y() + tsp, 8, szs)) &&
!io->DragReleased) {
sldr_drag = UI7Color_ButtonHovered;
float drag_center = vslider_h / 2.0f;
float drag_pos =
std::clamp(static_cast<float>((tp[1] - tsp - drag_center) /
(szs - vslider_h - 4)),
0.0f, 1.0f);
float drag_pos = std::clamp(
static_cast<float>((io->DragPosition[1] - tsp - drag_center) /
(szs - vslider_h - 4)),
0.0f, 1.0f);
scrolling_off[1] = drag_pos * (max[1] - 240.f);
}
int srpos =
tsp + std::clamp(float(szs - vslider_h - 4) *
(scrolling_off[1] / (max[1] - view_area[3])),
@ -389,13 +369,12 @@ void UI7::Menu::PostHandler() {
/// Rendering Stage
front->AddRectangle(view_area.xy() + vec2(screen_w - 12, tsp),
vec2(slider_w * 2, szs),
theme->Get(UI7Color_FrameBackground));
io->Theme->Get(UI7Color_FrameBackground));
front->AddRectangle(view_area.xy() + vec2(screen_w - 10, tsp + 2),
vec2(slider_w, szs - 4),
theme->Get(UI7Color_FrameBackgroundHovered));
io->Theme->Get(UI7Color_FrameBackgroundHovered));
front->AddRectangle(view_area.xy() + vec2(screen_w - 10, srpos + 2),
vec2(slider_w, vslider_h),
theme->Get(UI7Color_Button));
vec2(slider_w, vslider_h), io->Theme->Get(sldr_drag));
}
}
// Remove the Clip Rect
@ -417,49 +396,51 @@ void UI7::Menu::Separator() {
if (HandleScrolling(pos, size)) {
return;
}
main->AddRectangle(pos, size, theme->Get(UI7Color_TextDead));
main->AddRectangle(pos, size, io->Theme->Get(UI7Color_TextDead));
}
void UI7::Menu::SeparatorText(const std::string& label) {
vec2 size = vec2(view_area.z() - (scrollbar[1] ? 24 : 10), 1);
vec2 tdim = this->back->ren->GetTextDimensions(label);
vec2 pos = Cursor();
CursorMove(vec2(size.x(), tdim.y() - 4)); // Fix to make gap not to large
CursorMove(vec2(size.x(), tdim.y()));
if (HandleScrolling(pos, size)) {
return;
}
auto alignment = GetAlignment();
vec2 rpos =
AlignPos(pos, view_area.z() - 10, view_area, alignment); // RenderPos
vec2 rpos = AlignPos(pos, view_area.z() - (io->MenuPadding[0] * 2), view_area,
alignment); // RenderPos
/// Label pos for better overview
vec2 lpos = rpos;
if (alignment & UI7Align_Center) {
lpos += vec2((view_area.z() - 10) * 0.5 - tdim.x() * 0.5, 0);
lpos += vec2(
(view_area.z() - (io->MenuPadding[0] * 2)) * 0.5 - tdim.x() * 0.5, 0);
} else if (alignment & UI7Align_Right) {
lpos = vec2(view_area.z() - 10 - tdim.x(), rpos.y());
lpos = vec2(view_area.z() - (io->MenuPadding[0] * 2) - tdim.x(), rpos.y());
if (scrolling[1]) {
lpos.x() -= 8;
}
}
if (!(alignment & UI7Align_Left)) {
main->AddRectangle(rpos + vec2(0, tdim.y() * 0.5),
vec2(lpos.x() - rpos.x() - 5, size.y()),
theme->Get(UI7Color_TextDead));
vec2(lpos.x() - rpos.x() - io->MenuPadding[0], size.y()),
io->Theme->Get(UI7Color_TextDead));
}
if (!(alignment & UI7Align_Right)) {
main->AddRectangle(rpos + vec2(lpos.x() + tdim.x(), tdim.y() * 0.5),
vec2(size.x() - (lpos.x() + tdim.x()), size.y()),
theme->Get(UI7Color_TextDead));
io->Theme->Get(UI7Color_TextDead));
}
main->AddText(lpos, label, theme->Get(UI7Color_Text), 0,
main->AddText(lpos, label, io->Theme->Get(UI7Color_Text), 0,
vec2(view_area.z(), 20));
}
bool UI7::Menu::HandleScrolling(vec2& pos, const vec2& size) {
if (scrolling[1]) {
pos -= vec2(0, scrolling_off.y());
if (pos.y() > view_area.w() || (pos.y() + size.y() < view_area.y())) {
if (!io->Ren->InBox(
pos, size, vec4(view_area.xy(), view_area.xy() + view_area.zw()))) {
return true;
}
}
@ -542,5 +523,54 @@ void UI7::Menu::CreateParent() {
tmp_parent->SetPos(0);
tmp_parent->SetSize(0);
}
bool UI7::Menu::BeginTreeNode(const UI7::ID& id) {
auto n = tree_nodes.find((u32)id);
if (n == tree_nodes.end()) {
tree_nodes[(u32)id] = false;
n = tree_nodes.find((u32)id);
}
vec2 pos = Cursor();
vec2 tdim = io->Ren->GetTextDimensions(id.GetName());
vec2 size = vec2(tdim.x() + 10 + io->ItemSpace[0], tdim.y());
if (n->second) {
icursoroff.x() += 10.f;
}
CursorMove(size);
if (HandleScrolling(pos, size)) {
return n->second;
}
vec2 ts = pos + vec2(0, 3);
vec2 positions[2] = {
vec2(10, 5),
vec2(0, 10),
};
if (n->second) {
float t = positions[0].y();
positions[0].y() = positions[1].x();
positions[1].x() = t;
}
main->AddTriangle(ts, ts + positions[0], ts + positions[1],
io->Theme->Get(UI7Color_FrameBackground));
main->AddText(pos + vec2(10 + io->ItemSpace[0], 0), id.GetName(),
io->Theme->Get(UI7Color_Text));
if (has_touch && io->DragObject(name + id.GetName(), vec4(pos, size))) {
if (io->DragReleased) {
n->second = !n->second;
if (!n->second) {
icursoroff.x() -= 10.f;
cursor.x() -= 10;
}
}
}
return n->second;
}
void UI7::Menu::EndTreeNode() {
icursoroff.x() -= 10.f;
cursor.x() -= 10;
if (icursoroff.x() < 0.f) {
icursoroff.x() = 0.f;
}
}
} // namespace UI7
} // namespace PD

View File

@ -24,6 +24,18 @@ SOFTWARE.
#include <pd/core/timetrace.hpp>
#include <pd/ui7/ui7.hpp>
// Helpers
#define UI7DV4(x) \
std::format("{}: [{:.2f}, {:.2f}, {:.2f}, {:.2f}]", #x, x[0], x[1], x[2], \
x[3])
#define UI7DV4N(x) \
std::format("[{:.2f}, {:.2f}, {:.2f}, {:.2f}]", x[0], x[1], x[2], x[3])
#define UI7DV2(x) std::format("{}: [{:.2f}, {:.2f}]", #x, x[0], x[1])
#define UI7DV2N(x) std::format("[{:.2f}, {:.2f}]", x[0], x[1])
#define UI7DHX32(x) std::format("{}: {:#08x}", #x, x)
#define UI7DTF(x) PD::Strings::FormatNanos(x)
namespace PD {
std::string UI7::GetVersion(bool show_build) {
std::stringstream s;
@ -39,22 +51,22 @@ bool UI7::Context::BeginMenu(const ID& id, UI7MenuFlags flags) {
"Menu Name Already used or\nContext::Update not called!");
auto menu = this->menus.find(id);
if (menu == this->menus.end()) {
this->menus[id] = Menu::New(id, theme, inp);
this->menus[id]->ViewArea(this->ren->GetViewport());
this->menus[id] = Menu::New(id, io);
this->menus[id]->ViewArea(this->io->Ren->GetViewport());
menu = this->menus.find(id);
}
this->current = menu->second;
if (!this->current->BackList()) {
this->current->BackList(DrawList::New(ren));
this->current->BackList()->BaseLayer(root_layer + 30);
this->current->BackList(DrawList::New(io->Ren));
io->RegisterDrawList(this->current->name + "back", this->current->back);
}
if (!this->current->MainList()) {
this->current->MainList(DrawList::New(ren));
this->current->MainList()->BaseLayer(root_layer + 40);
this->current->MainList(DrawList::New(io->Ren));
io->RegisterDrawList(this->current->name + "main", this->current->main);
}
if (!this->current->FrontList()) {
this->current->FrontList(DrawList::New(ren));
this->current->FrontList()->BaseLayer(root_layer + 50);
this->current->FrontList(DrawList::New(io->Ren));
io->RegisterDrawList(this->current->name + "front", this->current->front);
}
this->current->PreHandler(flags);
amenus.push_back(this->current->GetID());
@ -85,16 +97,19 @@ void UI7::Context::EndMenu() {
void UI7::Context::Update(float delta) {
TT::Scope st("UI7_Update");
Assert(current == nullptr, "Still in a Menu!");
this->delta = delta;
s_delta->Add(delta * 1000);
this->back->BaseLayer(root_layer + 10);
this->back->Process();
this->io->Delta = delta;
io->DeltaStats->Add(io->Delta * 1000);
for (auto it : amenus) {
menus[it]->Update(delta);
menus[it]->Update(io->Delta);
}
int list = 1;
for (auto it : io->DrawListRegestry) {
it.second->BaseLayer(list * 10);
it.second->Process();
list++;
}
this->front->BaseLayer(root_layer + 60);
this->front->Process();
this->amenus.clear();
this->io->Update();
}
void UI7::Context::AboutMenu() {
@ -126,14 +141,110 @@ void UI7::Context::MetricsMenu() {
m->Label("Palladium - UI7 " + GetVersion());
m->Separator();
m->Label(std::format("Average {:.3f} ms/f ({:.1f} FPS)",
((float)s_delta->GetAverage() / 1000.f),
1000.f / ((float)s_delta->GetAverage() / 1000.f)));
m->Label(
std::format("Average {:.3f} ms/f ({:.1f} FPS)",
((float)io->DeltaStats->GetAverage() / 1000.f),
1000.f / ((float)io->DeltaStats->GetAverage() / 1000.f)));
m->Label("Menus: " + std::to_string(menus.size()));
m->SeparatorText("Lithium");
m->Label(std::format("Vertices: {} Indices: {}", ren->Vertices(),
ren->Indices()));
m->Label("Triangles: " + std::to_string(ren->Indices() / 3));
m->Label(std::format("Vertices: {} Indices: {}", io->Ren->Vertices(),
io->Ren->Indices()));
m->Label("Triangles: " + std::to_string(io->Ren->Indices() / 3));
m->SeparatorText("TimeTrace");
if (m->BeginTreeNode("Traces (" +
std::to_string(Sys::GetTraceMap().size()) + ")")) {
for (auto& it : Sys::GetTraceMap()) {
if (m->BeginTreeNode(it.second->GetID())) {
m->Label("Diff: " + UI7DTF(it.second->GetLastDiff()));
m->Label("Protocol Len: " +
std::to_string(it.second->GetProtocol()->GetLen()));
m->Label("Average: " +
UI7DTF(it.second->GetProtocol()->GetAverage()));
m->Label("Min: " + UI7DTF(it.second->GetProtocol()->GetMin()));
m->Label("Max: " + UI7DTF(it.second->GetProtocol()->GetMax()));
m->EndTreeNode();
}
}
m->EndTreeNode();
}
m->SeparatorText("IO");
if (m->BeginTreeNode("Menus (" + std::to_string(menus.size()) + ")")) {
for (auto& it : menus) {
if (m->BeginTreeNode(it.second->name)) {
m->Label("Name: " + it.second->name);
m->Label("Pos: " + UI7DV2N(it.second->view_area.xy()));
m->Label("Size: " + UI7DV2N(it.second->view_area.zw()));
m->Label("Main Area: " + UI7DV4N(it.second->main_area));
m->Label("Cursor: " + UI7DV2N(it.second->cursor));
if (m->BeginTreeNode("ID Objects (" +
std::to_string(it.second->idobjs.size()) +
")")) {
for (auto& jt : it.second->idobjs) {
m->Label(UI7DHX32(jt->GetID()));
}
m->EndTreeNode();
}
m->EndTreeNode();
}
}
m->EndTreeNode();
}
if (m->BeginTreeNode("DrawLists (" +
std::to_string(io->DrawListRegestry.size()) + ")")) {
for (auto& it : io->DrawListRegestry) {
m->Label(it.first.GetName());
}
m->EndTreeNode();
}
m->Label("io->Time: " + Strings::FormatMillis(io->Time->Get()));
m->Label(std::format("io->Delta: {:.3f}", io->Delta));
m->Label(std::format("io->Framerate: {:.2f}", io->Framerate));
m->Label(UI7DHX32(io->DraggedObject));
m->Label(std::format("io->DragTime: {:.2f}s", io->DragTime->GetSeconds()));
m->Label(UI7DV4(io->DragDestination));
m->Label(UI7DV2(io->DragSourcePos));
m->Label(UI7DV2(io->DragPosition));
m->Label(UI7DV2(io->DragLastPosition));
this->EndMenu();
}
}
void UI7::Context::StyleEditor() {
if (this->BeginMenu("UI7 Style Editor", UI7MenuFlags_Scrolling)) {
auto m = this->GetCurrentMenu();
m->Label("Palladium - UI7 " + GetVersion() + " Style Editor");
m->Separator();
m->Label(std::format("MenuPadding: {}, {}", io->MenuPadding.x(),
io->MenuPadding.y()));
m->SameLine();
if (m->Button("-")) {
io->MenuPadding -= 1;
}
m->SameLine();
if (m->Button("+")) {
io->MenuPadding += 1;
}
m->Label(std::format("FramePadding: {}, {}", io->FramePadding.x(),
io->FramePadding.y()));
m->SameLine();
if (m->Button("-")) {
io->FramePadding -= 1;
}
m->SameLine();
if (m->Button("+")) {
io->FramePadding += 1;
}
m->Label(
std::format("ItemSpace: {}, {}", io->ItemSpace.x(), io->ItemSpace.y()));
m->SameLine();
if (m->Button("-")) {
io->ItemSpace -= 1;
}
m->SameLine();
if (m->Button("+")) {
io->ItemSpace += 1;
}
this->EndMenu();
}
}