# 0.2.7-2

- Start dev on UI7 IO
- Add NoRezize flag and rezising
- Fix Bug in DebugLabels
- Use view Area for Menu Pos and Size
- Only set Viewarea once in BeginMenu
This commit is contained in:
tobid7 2025-03-07 14:05:43 +01:00
parent 85e12c45c0
commit e282d0ec7e
6 changed files with 153 additions and 46 deletions

View File

@ -38,7 +38,8 @@ enum UI7MenuFlags_ {
UI7MenuFlags_NoBackground = 1 << 4, ///< Dont Render Menu Background
UI7MenuFlags_NoClipRect = 1 << 5, ///< Disable clip render area of the Menu
UI7MenuFlags_NoCollapse = 1 << 6, ///< Disable Menu Collapse
UI7MenuFlags_NoMove = 1 << 7, ///< Disable Window Movement
UI7MenuFlags_NoMove = 1 << 7, ///< Disable Menu Movement
UI7MenuFlags_NoResize = 1 << 8, ///< Disable Menu Resize
// Enable Horizontal and Vertical Scrolling
UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling,
};

60
include/pd/ui7/io.hpp Normal file
View File

@ -0,0 +1,60 @@
#pragma once
/*
MIT License
Copyright (c) 2024 - 2025 René Amthor (tobid7)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <pd/core/common.hpp>
#include <pd/core/timer.hpp>
#include <pd/ui7/drawlist.hpp>
#include <pd/ui7/flags.hpp>
#include <pd/ui7/menu.hpp>
#include <pd/ui7/theme.hpp>
namespace PD {
namespace UI7 {
/**
* Shared Configuration and Runtime Data for a UI7 Context
*/
class IO : public SmartCtor<IO> {
public:
/**
* IO Constructor setting UP References
*/
IO(Hid::Ref input_driver) {
Time = Timer::New();
Theme = UI7::Theme::New();
Inp = input_driver;
};
~IO() = default;
float Framerate = 0.f;
float Delta = 0.f;
Timer::Ref Time;
Hid::Ref Inp;
UI7::Theme::Ref Theme;
float MenuPadding = 5.f;
DrawList::Ref Back;
DrawList::Ref Front;
};
} // namespace UI7
} // namespace PD

View File

@ -158,7 +158,7 @@ class Menu : public SmartCtor<Menu> {
* Get the Cursor Position
* @return Cursor Pos
*/
vec2 Cursor() const { return pos + cursor; }
vec2 Cursor() const { return view_area.xy() + cursor; }
/**
* Set the Cursor position
* @note The old Position can be restored with RestoreCursor
@ -347,7 +347,7 @@ class Menu : public SmartCtor<Menu> {
vec2 cursor; ///< Current Cursor Position
vec2 bcursor; ///< Backup Cursor
vec2 slcursor; ///< Sameline Cursor
vec4 view_area; ///< view Area
vec4 view_area; ///< view Area (Position and Size)
vec4 main_area; ///< Main Area [Input related]
vec2 scrolling_off; ///< Scrolling Position
bool scrolling[2]; ///< Is Hz or Vt Scrolling Enabled
@ -356,7 +356,7 @@ class Menu : public SmartCtor<Menu> {
bool scrollbar[2]; ///< Is Hz or Vt Scrollbar rendered
bool scroll_allowed[2]; ///< Is Hz or Vt Scrolling Alowed
bool has_touch; ///< Menu has touch (depends on screen)
bool is_open = true; ///< For Collapse Event
bool is_open = true; ///< For Collapse Event
Container::Ref tmp_parent; ///< Parent Container (for better alignment etc)
@ -378,7 +378,6 @@ class Menu : public SmartCtor<Menu> {
vec2 mouse; ///< Mouse/Touch Position
vec2 bslpos; ///< Before Sameline Position
vec2 last_size; ///< Last Object Size
vec2 pos; ///< Menu Position
// Theme
Theme::Ref theme;

View File

@ -28,6 +28,7 @@ SOFTWARE.
#include <pd/ui7/drawlist.hpp>
#include <pd/ui7/flags.hpp>
#include <pd/ui7/id.hpp>
#include <pd/ui7/io.hpp>
#include <pd/ui7/menu.hpp>
#include <pd/ui7/theme.hpp>
/**
@ -36,7 +37,7 @@ SOFTWARE.
* Major Minor Patch Build
* 0x01010000 -> 1.1.0-0
*/
#define UI7_VERSION 0x00020701
#define UI7_VERSION 0x00020702
namespace PD {
namespace UI7 {
@ -58,6 +59,7 @@ class Context : public SmartCtor<Context> {
/// Set the Internal References
this->ren = ren;
this->inp = hid;
io = IO::New(hid);
/// Init Theme and Front / Back Drawlists
theme = Theme::New();
back = DrawList::New(ren);
@ -125,6 +127,9 @@ class Context : public SmartCtor<Context> {
/** Get the Root Layer of the Menu */
int RootLayer() const { return root_layer; }
/** Get IO Reference */
IO::Ref GetIO() { return io; }
// Debugging / Demo / About
/** About Menu */
@ -167,6 +172,9 @@ class Context : public SmartCtor<Context> {
// Deltatime Average
TimeStats::Ref s_delta;
// IO
IO::Ref io;
};
} // namespace UI7
} // namespace PD

View File

@ -79,6 +79,9 @@ void UI7::Menu::Image(Texture::Ref img, vec2 size) {
}
void UI7::Menu::DebugLabels(Menu::Ref m, Menu::Ref t) {
if (!m) {
return;
}
if (t == nullptr) {
t = m;
}
@ -87,7 +90,11 @@ void UI7::Menu::DebugLabels(Menu::Ref m, Menu::Ref t) {
s << std::hex << std::setw(8) << std::setfill('0') << m->id;
s << std::dec << "]";
t->Label(s.str());
t->Label(std::format("Size: {:.2f}, {:.2f}", m->max.x(), m->max.y()));
t->Label(std::format("Max Size: {:.2f}, {:.2f}", m->max.x(), m->max.y()));
t->Label(std::format("Pos: {:.2f}, {:.2f} Size: {:.2f}, {:.2f}",
m->view_area.x(), m->view_area.y(), m->view_area.z(),
m->view_area.w()));
t->Label(std::format("Flags: {:#08x}", m->flags));
t->Label(
"Pre: " +
Strings::FormatNanos(
@ -113,9 +120,9 @@ void UI7::Menu::Update(float delta) {
scrolling_off = scroll_anim;
}
if (!(flags & UI7MenuFlags_NoClipRect)) {
main->PushClipRect(vec4(pos.x() + 5, pos.y() + tbh,
pos.x() + view_area.z() - 12,
pos.y() + view_area.w()));
main->PushClipRect(vec4(view_area.x() + 5, view_area.y() + tbh,
view_area.x() + view_area.z() - 12,
view_area.y() + view_area.w()));
}
std::vector<int> tbr;
for (int i = 0; i < (int)objects.size(); i++) {
@ -174,16 +181,19 @@ void UI7::Menu::PreHandler(UI7MenuFlags flags) {
this->scrolling[1] = flags & UI7MenuFlags_VtScrolling;
has_touch = main->ren->CurrentScreen()->ScreenType() == Screen::Bottom;
if (!(flags & UI7MenuFlags_NoBackground) && is_open) {
back->AddRectangle(pos, view_area.zw(), theme->Get(UI7Color_Background));
back->AddRectangle(view_area.xy() + vec2(0, tbh),
view_area.zw() - vec2(0, tbh),
theme->Get(UI7Color_Background));
}
if (!(flags & UI7MenuFlags_NoTitlebar)) {
// Title bar setup and Rendering
tbh = front->ren->TextScale() * 30.f;
front->AddRectangle(pos, vec2(view_area.z(), tbh),
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);
if (!(flags & UI7MenuFlags_NoCollapse)) {
tpos.x() += 18;
vec2 cpos = pos + 5;
vec2 cpos = view_area.xy() + 5;
UI7Color clr = UI7Color_FrameBackground;
if (inp->IsUp(inp->Touch) &&
LI::Renderer::InBox(inp->TouchPosLast(), vec4(cpos, vec2(18, tbh))) &&
@ -213,43 +223,69 @@ void UI7::Menu::PreHandler(UI7MenuFlags flags) {
tflags = LITextFlags_AlignMid;
}
front->Layer(front->Layer() + 1);
front->AddText(pos + tpos, this->name, theme->Get(UI7Color_Text), tflags,
vec2(view_area.z(), tbh));
front->AddText(view_area.xy() + tpos, this->name, theme->Get(UI7Color_Text),
tflags, vec2(view_area.z(), tbh));
main_area[1] = tbh;
CursorInit();
// Add a clip Rect for Separators
if (!(flags & UI7MenuFlags_NoClipRect)) {
main->PushClipRect(vec4(pos.x() + 5, pos.y() + tbh,
pos.x() + view_area.z() - 12,
pos.y() + view_area.w()));
// 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) {
view_area =
vec4(view_area.xy() + (inp->TouchPos() - mouse), view_area.zw());
mouse = inp->TouchPos();
}
}
}
// 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,
view_area.y() + view_area.w()));
}
}
void UI7::Menu::PostHandler() {
TT::Scope st("MPOS_" + name);
if (!(flags & UI7MenuFlags_NoMove)) {
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(pos + vec2(18, 0),
vec2(view_area.z(), tbh))) &&
LI::Renderer::InBox(inp->TouchPos(),
vec4(view_area.xy() + view_area.zw() - 20, 20)) &&
has_touch) {
mouse = inp->TouchPos();
} else if (inp->IsUp(inp->Touch) &&
LI::Renderer::InBox(
inp->TouchPos(),
vec4(pos + vec2(18, 0), vec2(view_area.z(), tbh))) &&
has_touch) {
mouse = 0;
} else if (inp->IsHeld(inp->Touch) &&
LI::Renderer::InBox(
inp->TouchPosLast(),
vec4(pos + vec2(18, 0), vec2(view_area.z(), tbh))) &&
has_touch) {
pos = inp->TouchPos() - mouse;
}
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);
}
if (scrolling[1]) {
scroll_allowed[1] = (max[1] > 235);
scroll_allowed[1] = (max[1] > view_area.w() - 5);
if (max[1] < view_area.w() - 5) {
scrolling_off[1] = 0.f;
}
scrollbar[1] = scroll_allowed[1];
if (scrollbar[1]) {
@ -298,7 +334,8 @@ void UI7::Menu::PostHandler() {
mouse = vec2();
}
if (inp->IsHeld(inp->Touch)) {
if (front->ren->InBox(tpos, main_area)) {
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 &&
scrolling_off[1] > -40) {
/// Cursor Mod
@ -333,7 +370,8 @@ void UI7::Menu::PostHandler() {
/// Probably need a new API for this
auto tp = inp->TouchPos();
if (inp->IsHeld(inp->Touch) &&
LI::Renderer::InBox(tp, vec4(screen_w - 12, tsp, 8, szs))) {
LI::Renderer::InBox(tp, vec4(view_area.x() + screen_w - 12,
view_area.y() + tsp, 8, szs))) {
float drag_center = vslider_h / 2.0f;
float drag_pos =
std::clamp(static_cast<float>((tp[1] - tsp - drag_center) /
@ -349,13 +387,13 @@ void UI7::Menu::PostHandler() {
0.f, float(szs - vslider_h - 4));
/// Rendering Stage
front->AddRectangle(pos + vec2(screen_w - 12, tsp),
front->AddRectangle(view_area.xy() + vec2(screen_w - 12, tsp),
vec2(slider_w * 2, szs),
theme->Get(UI7Color_FrameBackground));
front->AddRectangle(pos + vec2(screen_w - 10, tsp + 2),
front->AddRectangle(view_area.xy() + vec2(screen_w - 10, tsp + 2),
vec2(slider_w, szs - 4),
theme->Get(UI7Color_FrameBackgroundHovered));
front->AddRectangle(pos + vec2(screen_w - 10, srpos + 2),
front->AddRectangle(view_area.xy() + vec2(screen_w - 10, srpos + 2),
vec2(slider_w, vslider_h),
theme->Get(UI7Color_Button));
}
@ -405,12 +443,12 @@ void UI7::Menu::SeparatorText(const std::string& label) {
}
}
if (!(alignment & UI7Align_Left)) {
main->AddRectangle(pos + vec2(0, tdim.y() * 0.5),
vec2(lpos.x() - pos.x() - 5, size.y()),
main->AddRectangle(rpos + vec2(0, tdim.y() * 0.5),
vec2(lpos.x() - rpos.x() - 5, size.y()),
theme->Get(UI7Color_TextDead));
}
if (!(alignment & UI7Align_Right)) {
main->AddRectangle(pos + vec2(lpos.x() + tdim.x(), tdim.y() * 0.5),
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));
}

View File

@ -40,6 +40,7 @@ bool UI7::Context::BeginMenu(const ID& id, UI7MenuFlags flags) {
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());
menu = this->menus.find(id);
}
this->current = menu->second;
@ -55,7 +56,6 @@ bool UI7::Context::BeginMenu(const ID& id, UI7MenuFlags flags) {
this->current->FrontList(DrawList::New(ren));
this->current->FrontList()->BaseLayer(root_layer + 50);
}
this->current->ViewArea(this->ren->GetViewport());
this->current->PreHandler(flags);
amenus.push_back(this->current->GetID());
if (!this->current->is_open) {
@ -129,10 +129,11 @@ void UI7::Context::MetricsMenu() {
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("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("Menus: " + std::to_string(menus.size()));
this->EndMenu();
}
}