# Changes 0.2.7

- Add UI7 32Bit Version Num
- Fix ClipRect Bug with Separators
- Fix Triangle/Rect Render order Bug (UI7 - Bug of Lithium)
- Add Position to Menus and Movement by dragging the Title bar
- Add Menu Collabse (+ Flag to disable)
- Add About and Metrics Menus to Context
This commit is contained in:
tobid7 2025-03-06 18:14:39 +01:00
parent 5375d0f3a9
commit e45598f9f6
8 changed files with 185 additions and 30 deletions

View File

@ -52,7 +52,7 @@ execute_process(
)
# Set Project
project(palladium LANGUAGES C CXX VERSION 0.2.6)
project(palladium LANGUAGES C CXX VERSION 0.2.7)
option(PD_BUILD_TESTS "Sets if TestApp and TestBench get build" OFF)

View File

@ -27,16 +27,16 @@ make install
| Name | Last Updated | Platform | Depends |
|---|---|---|---|
| pd-core | 0.2.4 | multi | none |
| pd-core | 0.2.6 | multi | none |
| pd-external | 0.1.0 | multi | none |
| pd-image | 0.2.6 | multi | pd-core |
| pd-drivers | 0.2.4 | multi | pd-core |
| pd-lib3ds | 0.2.4 | 3ds | pd-core, pd-drivers |
| pd-net | 0.2.4 | 3ds | pd-core, pd-lib3ds |
| pd-lithium | 0.2.6 | 3ds | pd-core, pd-image pd-lib3ds, citro3d |
| pd-lithium | 0.2.7 | 3ds | pd-core, pd-image pd-lib3ds, citro3d |
| pd-sound | 0.2.4 | 3ds | pd-core, mpg123 |
| pd-overlays | 0.2.4 | 3ds | pd-core, pd-image, pd-lib3ds, pd-lithium, pd-ui7 |
| pd-ui7 | 0.2.6 | 3ds | pd-core, pd-image, pd-lib3ds, pd-lithium |
| pd-ui7 | 0.2.7 | 3ds | pd-core, pd-image, pd-lib3ds, pd-lithium |
| pd-app | 0.2.4 | 3ds | pd-core, pd-image, pd-lib3ds, pd-lithium |
## Credits

View File

@ -36,6 +36,8 @@ enum UI7MenuFlags_ {
UI7MenuFlags_HzScrolling = 1 << 2, ///< Enable Horizontal Scrolling
UI7MenuFlags_VtScrolling = 1 << 3, ///< Enable Vertical Scrolling
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
// Enable Horizontal and Vertical Scrolling
UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling,
};

View File

@ -158,7 +158,7 @@ class Menu : public SmartCtor<Menu> {
* Get the Cursor Position
* @return Cursor Pos
*/
vec2 Cursor() const { return cursor; }
vec2 Cursor() const { return pos + cursor; }
/**
* Set the Cursor position
* @note The old Position can be restored with RestoreCursor
@ -268,8 +268,12 @@ class Menu : public SmartCtor<Menu> {
// Advanced
/** Display Debug Labels of the Menu */
void DebugLabels();
/**
* Display Debug Labels of a Menu
* @param m Menu to display Data from
* @param t Target to Write the Labels into
*/
static void DebugLabels(Menu::Ref m, Menu::Ref t = nullptr);
// Uneditable Stuff
@ -352,6 +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
Container::Ref tmp_parent; ///< Parent Container (for better alignment etc)
@ -373,6 +378,7 @@ 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

@ -23,15 +23,29 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <pd/core/timetrace.hpp>
#include <pd/drivers/hid.hpp>
#include <pd/ui7/drawlist.hpp>
#include <pd/ui7/flags.hpp>
#include <pd/ui7/id.hpp>
#include <pd/ui7/menu.hpp>
#include <pd/ui7/theme.hpp>
/**
* Declare UI7 Version
* Format: 00 00 00 00
* Major Minor Patch Build
* 0x01010000 -> 1.1.0-0
*/
#define UI7_VERSION 0x00020700
namespace PD {
namespace UI7 {
/**
* Get UI7 Version String
* @param show_build Ahow build num (mostly unused)
* @return Version String (1.0.0-1 for example)
*/
std::string GetVersion(bool show_build = false);
/** Base Context for UI7 */
class Context : public SmartCtor<Context> {
public:
@ -48,6 +62,7 @@ class Context : public SmartCtor<Context> {
theme = Theme::New();
back = DrawList::New(ren);
front = DrawList::New(ren);
s_delta = TimeStats::New(60);
}
~Context() = default;
@ -110,6 +125,14 @@ class Context : public SmartCtor<Context> {
/** Get the Root Layer of the Menu */
int RootLayer() const { return root_layer; }
// Debugging / Demo / About
/** About Menu */
void AboutMenu();
/** Metrics */
void MetricsMenu();
private:
// Used in Overlays
int root_layer = 0;
@ -139,6 +162,11 @@ class Context : public SmartCtor<Context> {
DrawList::Ref back;
// Active Theme
Theme::Ref theme;
// Metrics
// Deltatime Average
TimeStats::Ref s_delta;
};
} // namespace UI7
} // namespace PD

View File

@ -152,7 +152,6 @@ void Renderer::QuadCommand(Command::Ref cmd, const Rect& quad, const Rect& uv,
void Renderer::TriangleCommand(Command::Ref cmd, const vec2& a, const vec2& b,
const vec2& c, u32 col) {
cmd->Index(cmd_idx++).Layer(current_layer).Tex(current_tex);
cmd->PushIndex(2).PushIndex(1).PushIndex(0);
cmd->PushVertex(Vertex(a, vec2(0.f, 1.f), col));
cmd->PushVertex(Vertex(b, vec2(1.f, 1.f), col));

View File

@ -78,28 +78,32 @@ void UI7::Menu::Image(Texture::Ref img, vec2 size) {
r->HandleScrolling(scrolling_off, view_area);
}
void UI7::Menu::DebugLabels() {
void UI7::Menu::DebugLabels(Menu::Ref m, Menu::Ref t) {
if (t == nullptr) {
t = m;
}
std::stringstream s;
s << "Name: " << name << " [";
s << std::hex << std::setw(8) << std::setfill('0') << id;
s << "Name: " << m->name << " [";
s << std::hex << std::setw(8) << std::setfill('0') << m->id;
s << std::dec << "]";
this->Label(s.str());
this->Label(
t->Label(s.str());
t->Label(std::format("Size: {:.2f}, {:.2f}", m->max.x(), m->max.y()));
t->Label(
"Pre: " +
Strings::FormatNanos(
Sys::GetTraceRef("MPRE_" + name)->GetProtocol()->GetAverage()));
this->Label(
Sys::GetTraceRef("MPRE_" + m->name)->GetProtocol()->GetAverage()));
t->Label(
"Post: " +
Strings::FormatNanos(
Sys::GetTraceRef("MPOS_" + name)->GetProtocol()->GetAverage()));
this->Label(
Sys::GetTraceRef("MPOS_" + m->name)->GetProtocol()->GetAverage()));
t->Label(
"Update: " +
Strings::FormatNanos(
Sys::GetTraceRef("MUPT_" + name)->GetProtocol()->GetAverage()));
this->Label(
Sys::GetTraceRef("MUPT_" + m->name)->GetProtocol()->GetAverage()));
t->Label(
"MUser: " +
Strings::FormatNanos(
Sys::GetTraceRef("MUSR_" + name)->GetProtocol()->GetAverage()));
Sys::GetTraceRef("MUSR_" + m->name)->GetProtocol()->GetAverage()));
}
void UI7::Menu::Update(float delta) {
@ -108,7 +112,11 @@ void UI7::Menu::Update(float delta) {
if (!scroll_anim.IsFinished()) {
scrolling_off = scroll_anim;
}
main->PushClipRect(vec4(5, tbh, view_area.z() - 12, view_area.w()));
if (!(flags & UI7MenuFlags_NoClipRect)) {
main->PushClipRect(vec4(pos.x() + 5, pos.y() + tbh,
pos.x() + view_area.z() - 12,
pos.y() + view_area.w()));
}
std::vector<int> tbr;
for (int i = 0; i < (int)objects.size(); i++) {
auto& it = objects[i];
@ -132,7 +140,9 @@ void UI7::Menu::Update(float delta) {
for (auto it : tbr) {
idobjs.erase(idobjs.begin() + it);
}
main->PopClipRect();
if (!(flags & UI7MenuFlags_NoClipRect)) {
main->PopClipRect();
}
this->back->Process();
this->main->Process();
this->front->Process();
@ -163,28 +173,79 @@ void UI7::Menu::PreHandler(UI7MenuFlags flags) {
this->scrolling[0] = flags & UI7MenuFlags_HzScrolling;
this->scrolling[1] = flags & UI7MenuFlags_VtScrolling;
has_touch = main->ren->CurrentScreen()->ScreenType() == Screen::Bottom;
if (!(flags & UI7MenuFlags_NoBackground)) {
back->AddRectangle(0, view_area.zw(), theme->Get(UI7Color_Background));
if (!(flags & UI7MenuFlags_NoBackground) && is_open) {
back->AddRectangle(pos, view_area.zw(), theme->Get(UI7Color_Background));
}
if (!(flags & UI7MenuFlags_NoTitlebar)) {
tbh = front->ren->TextScale() * 30.f;
front->AddRectangle(0, vec2(view_area.z(), tbh),
front->AddRectangle(pos, 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;
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) {
clr = UI7Color_FrameBackgroundHovered;
}
vec2 positions[2] = {
vec2(12, 6),
vec2(0, 12),
};
if (is_open) {
float t = positions[0].y();
positions[0].y() = positions[1].x();
positions[1].x() = t;
}
this->front->AddTriangle(cpos, cpos + positions[0], cpos + positions[1],
theme->Get(clr));
}
LITextFlags tflags = LITextFlags_None;
if (flags & UI7MenuFlags_CenterTitle) {
tpos = 0;
tflags = LITextFlags_AlignMid;
}
front->AddText(tpos, this->name, theme->Get(UI7Color_Text), tflags,
front->Layer(front->Layer() + 1);
front->AddText(pos + 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()));
}
}
}
void UI7::Menu::PostHandler() {
TT::Scope st("MPOS_" + name);
if (inp->IsDown(inp->Touch) &&
LI::Renderer::InBox(inp->TouchPos(),
vec4(pos + 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(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 (scrolling[1]) {
scroll_allowed[1] = (max[1] > 235);
scrollbar[1] = scroll_allowed[1];
@ -286,15 +347,21 @@ void UI7::Menu::PostHandler() {
0.f, float(szs - vslider_h - 4));
/// Rendering Stage
front->AddRectangle(vec2(screen_w - 12, tsp), vec2(slider_w * 2, szs),
front->AddRectangle(pos + vec2(screen_w - 12, tsp),
vec2(slider_w * 2, szs),
theme->Get(UI7Color_FrameBackground));
front->AddRectangle(vec2(screen_w - 10, tsp + 2), vec2(slider_w, szs - 4),
front->AddRectangle(pos + vec2(screen_w - 10, tsp + 2),
vec2(slider_w, szs - 4),
theme->Get(UI7Color_FrameBackgroundHovered));
front->AddRectangle(vec2(screen_w - 10, srpos + 2),
front->AddRectangle(pos + vec2(screen_w - 10, srpos + 2),
vec2(slider_w, vslider_h),
theme->Get(UI7Color_Button));
}
}
// Remove the Clip Rect
if (!(flags & UI7MenuFlags_NoClipRect)) {
main->PopClipRect();
}
TT::End("MUSR_" + name);
}

View File

@ -25,6 +25,14 @@ SOFTWARE.
#include <pd/ui7/ui7.hpp>
namespace PD {
std::string UI7::GetVersion(bool show_build) {
std::stringstream s;
s << ((UI7_VERSION >> 24) & 0xFF) << ".";
s << ((UI7_VERSION >> 16) & 0xFF) << ".";
s << ((UI7_VERSION >> 8) & 0xFF);
if (show_build) s << "-" << ((UI7_VERSION) & 0xFF);
return s.str();
}
bool UI7::Context::BeginMenu(const ID& id, UI7MenuFlags flags) {
Assert(!this->current, "You are already in another Menu!");
Assert(std::find(amenus.begin(), amenus.end(), (u32)id) == amenus.end(),
@ -50,7 +58,10 @@ bool UI7::Context::BeginMenu(const ID& id, UI7MenuFlags flags) {
this->current->ViewArea(this->ren->GetViewport());
this->current->PreHandler(flags);
amenus.push_back(this->current->GetID());
return true;
if (!this->current->is_open) {
this->current = nullptr;
}
return this->current->is_open;
}
UI7::Menu::Ref UI7::Context::GetCurrentMenu() {
@ -74,6 +85,8 @@ 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();
for (auto it : amenus) {
@ -83,4 +96,44 @@ void UI7::Context::Update(float delta) {
this->front->Process();
this->amenus.clear();
}
void UI7::Context::AboutMenu() {
if (this->BeginMenu("About UI7", UI7MenuFlags_Scrolling)) {
auto m = this->GetCurrentMenu();
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 -> " + LibInfo::CompiledWith());
}
this->EndMenu();
}
}
void UI7::Context::MetricsMenu() {
if (this->BeginMenu("UI7 Metrics", UI7MenuFlags_Scrolling)) {
auto m = this->GetCurrentMenu();
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("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();
}
}
} // namespace PD