From f7e4d9848ae87bc3f87d3decd625c897be4ca613 Mon Sep 17 00:00:00 2001 From: tobid7 Date: Sat, 22 Jun 2024 14:36:17 +0200 Subject: [PATCH] Changes: Scrolling/Scrollbar Fixes Open Up UI7 API for Custom Objects outside of UI7 Add Text Shorter to R2 --- include/renderd7/Render2.hpp | 1 + include/renderd7/UI7.hpp | 10 +- source/Render2.cpp | 32 +++++- source/UI7.cpp | 182 +++++++++++++++++------------------ source/renderd7.cpp | 4 +- 5 files changed, 128 insertions(+), 101 deletions(-) diff --git a/include/renderd7/Render2.hpp b/include/renderd7/Render2.hpp index 2b0ef31..05f5123 100644 --- a/include/renderd7/Render2.hpp +++ b/include/renderd7/Render2.hpp @@ -85,6 +85,7 @@ class R2Base { void Process(); R7Vec2 GetTextDimensions(const std::string& text); std::string WrapText(const std ::string& in, int maxlen); + std::string ShortText(const std::string& in, int maxlen); // Draw Functions void AddRect(R7Vec2 pos, R7Vec2 size, RD7Color clr); void AddRect(R7Vec2 pos, R7Vec2 size, unsigned int clr); diff --git a/include/renderd7/UI7.hpp b/include/renderd7/UI7.hpp index 9f0dcb2..4d1a3af 100644 --- a/include/renderd7/UI7.hpp +++ b/include/renderd7/UI7.hpp @@ -102,12 +102,20 @@ R7Vec2 GetCursorPos(); void SetCursorPos(R7Vec2 cp); void RestoreCursor(); void SameLine(); -float GetScrollingOffset(); +// Internal API (For Creating Custom Objects) +bool InBox(R7Vec2 inpos, R7Vec2 boxpos, R7Vec2 boxsize); +void MoveCursor(R7Vec2 size); +bool HandleScrolling(R7Vec2 &pos, R7Vec2 size); +bool InMenu(); namespace Menu { // All of them return the Main BG DrawList if Menu is null UI7DrawList::Ref GetBackgroundList(); UI7DrawList::Ref GetList(); UI7DrawList::Ref GetForegroundList(); +// Other Menu Specific Functions +float GetScrollingOffset(); +void SetScrollingOffset(float off); +bool IsScrolling(); } // namespace Menu // DrawLists UI7DrawList::Ref GetForegroundList(); diff --git a/source/Render2.cpp b/source/Render2.cpp index a777b91..11507e8 100644 --- a/source/Render2.cpp +++ b/source/Render2.cpp @@ -79,6 +79,34 @@ std::string R2Base::WrapText(const std ::string& in, int maxlen) { return out; } +std::string R2Base::ShortText(const std::string& in, int maxlen) { + auto textdim = this->GetTextDimensions(in); + if (textdim.x < (float)maxlen) return in; + std::string ft = ""; + std::string worker = in; + if (in.find_last_of('.') != in.npos) { + ft = in.substr(in.find_last_of('.')); + worker = in.substr(0, in.find_last_of('.')); + } + + maxlen -= this->GetTextDimensions(ft).x - this->GetTextDimensions("(...)").x; + float len_mod = (float)maxlen / textdim.x; + int pos = (in.length() * len_mod) / rd7_draw2_tsm; + std::string out; + + out = in.substr(0, pos); + + for (size_t i = pos; i < worker.length(); i++) { + out += worker[i]; + if (this->GetTextDimensions(out + "(...)" + ft).x > (float)maxlen) { + out += "(...)"; + out += ft; + return out; + } + } + return out; // Impossible to reach +} + R7Vec2 R2Base::GetCurrentScreenSize() { return R7Vec2(this->current_screen == R2Screen_Bottom ? 320 : 400, 240); } @@ -142,8 +170,8 @@ void R2Base::Process() { while (edit_text.find('\n') != edit_text.npos) { std::string current_line = edit_text.substr(0, edit_text.find('\n')); - // if (it->flags & RD7TextFlags_Short) - // current_line = GetShortedText(current_line, it->pszs.x - it->pos.x); + if (it->flags & RD7TextFlags_Short) + current_line = this->ShortText(current_line, it->pszs.x - it->pos.x); R7Vec2 newpos = it->pos; // Check Flags R7Vec2 dim = this->GetTextDimensions(current_line); diff --git a/source/UI7.cpp b/source/UI7.cpp index 4d2055d..5d7f351 100644 --- a/source/UI7.cpp +++ b/source/UI7.cpp @@ -333,17 +333,18 @@ void UI7DrawList::AddDebugCall(std::shared_ptr cmd) { struct UI7Menu { UI7Menu() {} - UI7ID menuid; // menu ID - R7Vec2 cursor; // cursor - R7Vec2 cb; // backup cursor - R7Vec2 slc; // sameline cursor - float scrolling_offset = 0.f; // MenuScrolling Pos - bool enable_scrolling = false; // Menu Scrolling - float scrolling_mod = 0.f; // For Menu Scrolling effect - float tbh; // TabBar Height - bool show_scroolbar = true; // Show Scrollbar - bool has_touch = false; // To Disable touch on Top Screen - NTCtrl::Ref ctrl; // NonTouchControl + UI7ID menuid; // menu ID + R7Vec2 cursor; // cursor + R7Vec2 cb; // backup cursor + R7Vec2 slc; // sameline cursor + float scrolling_offset = 0.f; // MenuScrolling Pos + bool enable_scrolling = false; // Menu Scrolling + float scrolling_mod = 0.f; // For Menu Scrolling effect + float tbh; // TabBar Height + bool show_scroolbar = true; // Show Scrollbar + bool scrolling_possible = true; // Scrolling Possible? + bool has_touch = false; // To Disable touch on Top Screen + NTCtrl::Ref ctrl; // NonTouchControl // SubMenu std::string submenu; @@ -428,7 +429,8 @@ void UI7CtxEndMenu() { RenderD7::Ftrace::ScopedTrace tr("ui7", "EndMenu"); // Draw Scrollbar if (ui7_ctx->cm->enable_scrolling) { - ui7_ctx->cm->show_scroolbar = (ui7_ctx->cm->ms.y < 235 ? false : true); + ui7_ctx->cm->scrolling_possible = (ui7_ctx->cm->ms.y < 235 ? false : true); + ui7_ctx->cm->show_scroolbar = ui7_ctx->cm->scrolling_possible; if (ui7_ctx->cm->show_scroolbar) { // Screen Width @@ -447,19 +449,19 @@ void UI7CtxEndMenu() { // Create Real Slider Height int slider_rh = d7min(d7max(slider_h, (float)lszs), (float)(szs - 4)); // Calculate Slider Position - int slider_pos = d7min( - static_cast(tsp + szs - slider_rh - 4), - d7max(static_cast(tsp), - static_cast(tsp) + - static_cast( - (szs - slider_rh) * - (static_cast(ui7_ctx->cm->scrolling_offset) / - static_cast(ui7_ctx->cm->ms.y - 240.f))))); + int slider_pos = + tsp + + d7min(static_cast(szs - slider_rh - 4), + d7max(0.f, + static_cast( + (szs - slider_rh) * + (static_cast(ui7_ctx->cm->scrolling_offset) / + static_cast(ui7_ctx->cm->ms.y - 240.f))))); // Render Slider ui7_ctx->cm->front->AddRectangle( R7Vec2(sw - 12, tsp), R7Vec2(slider_w * 2, szs), RD7Color_List0); ui7_ctx->cm->front->AddRectangle(R7Vec2(sw - 10, slider_pos + 2), - R7Vec2(slider_w, slider_h), + R7Vec2(slider_w, slider_rh), RD7Color_Selector); } } @@ -504,21 +506,6 @@ void UI7CtxEndMenu() { ui7_ctx->in_menu = false; } -void UI7CtxCursorMove(R7Vec2 size) { - if (!UI7CtxValidate()) return; - if (!UI7CtxInMenu()) return; - ui7_ctx->cm->lszs = size; - ui7_ctx->cm->slc = ui7_ctx->cm->cursor + R7Vec2(size.x + 5, 0); - ui7_ctx->cm->cursor.x = 5; - if (ui7_ctx->cm->bslp.y) { - ui7_ctx->cm->cursor += R7Vec2(0, ui7_ctx->cm->bslp.y + 5); - ui7_ctx->cm->bslp = R7Vec2(); - } else { - ui7_ctx->cm->cursor += R7Vec2(0, size.y + 5); - } - ui7_ctx->cm->ms = R7Vec2(ui7_ctx->cm->slc.x, ui7_ctx->cm->cursor.y); -} - namespace UI7 { bool InBox(R7Vec2 inpos, R7Vec2 boxpos, R7Vec2 boxsize) { if ((inpos.x > boxpos.x) && (inpos.y > boxpos.y) && @@ -589,16 +576,10 @@ bool Button(const std::string &label, R7Vec2 size) { RD7Color btn = RD7Color_Button; R7Vec2 pos = GetCursorPos(); - UI7CtxCursorMove(size); + MoveCursor(size); ui7_ctx->cm->ctrl->AddObj(); - if (ui7_ctx->cm->enable_scrolling) { - R7Vec2 pb = pos; - pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset); - if (pos.y > 240 || - (pos.y + size.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh)) - return false; - } + if (HandleScrolling(pos, size)) return false; if (ui7_ctx->cm->has_touch) { if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Up) && @@ -628,16 +609,10 @@ void Checkbox(const std::string &label, bool &c) { R7Vec2 pos = GetCursorPos(); - UI7CtxCursorMove(inp); + MoveCursor(inp); ui7_ctx->cm->ctrl->AddObj(); - if (ui7_ctx->cm->enable_scrolling) { - R7Vec2 pb = pos; - pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset); - if (pos.y > 240 || - (pos.y + cbs.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh)) - return; - } + if (HandleScrolling(pos, inp)) return; if (ui7_ctx->cm->has_touch) { if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Up) && @@ -666,16 +641,10 @@ void Label(const std::string &label, RD7TextFlags flags) { R7Vec2 pos = GetCursorPos(); auto upos = pos; // Remove some y offset cause texts have some offset - UI7CtxCursorMove(textdim - R7Vec2(0, 4)); + MoveCursor(textdim - R7Vec2(0, 4)); ui7_ctx->cm->ctrl->AddObj(); - if (ui7_ctx->cm->enable_scrolling) { - R7Vec2 pb = pos; - pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset); - if (pos.y > 240 || - (pos.y + textdim.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh)) - return; - } + if (HandleScrolling(pos, textdim)) return; float tbh = RenderD7::R2()->GetTextSize() * 40; auto &list = @@ -695,16 +664,10 @@ void Progressbar(float value) { R7Vec2(RenderD7::R2()->GetCurrentScreenSize().x - (pos.x * 2), 20); if (ui7_ctx->cm->show_scroolbar && ui7_ctx->cm->enable_scrolling) size.x -= 16; - UI7CtxCursorMove(size); + MoveCursor(size); ui7_ctx->cm->ctrl->AddObj(); - if (ui7_ctx->cm->enable_scrolling) { - R7Vec2 pb = pos; - pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset); - if (pos.y > 240 || - (pos.y + size.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh)) - return; - } + if (HandleScrolling(pos, size)) return; ui7_ctx->cm->main->AddRectangle(pos, size, RD7Color_FrameBg); ui7_ctx->cm->main->AddRectangle(pos + R7Vec2(2, 2), size - R7Vec2(4, 4), @@ -719,16 +682,10 @@ void Progressbar(float value) { void Image(RenderD7::Image::Ref img) { if (!UI7CtxValidate()) return; R7Vec2 pos = GetCursorPos(); - UI7CtxCursorMove(R7Vec2(img->GetSize().x, img->GetSize().y)); + MoveCursor(R7Vec2(img->GetSize().x, img->GetSize().y)); ui7_ctx->cm->ctrl->AddObj(); - if (ui7_ctx->cm->enable_scrolling) { - R7Vec2 pb = pos; - pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset); - if (pos.y > 240 || (pos.y + img->GetSize().y < ui7_ctx->cm->tbh - 5 && - pb.y > ui7_ctx->cm->tbh)) - return; - } + if (HandleScrolling(pos, img->GetSize())) return; ui7_ctx->cm->main->AddImage(pos, img); } @@ -744,7 +701,7 @@ void BrowserList(const std::vector &entrys, int &selection, if (size.x == 0) size.x = RenderD7::R2()->GetCurrentScreenSize().x - (pos.x * 2); if (size.y == 0) size.y = (max_entrys * 15); - UI7CtxCursorMove(size); + MoveCursor(size); ui7_ctx->cm->ctrl->AddObj(); int selindex = (selection < max_entrys ? selection : (max_entrys - 1)); @@ -789,16 +746,10 @@ void InputText(const std::string &label, std::string &text, RD7KeyboardState kbd_state; // tmp (goes out of scope) R7Vec2 pos = GetCursorPos(); - UI7CtxCursorMove(inp); + MoveCursor(inp); ui7_ctx->cm->ctrl->AddObj(); - if (ui7_ctx->cm->enable_scrolling) { - R7Vec2 pb = pos; - pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset); - if (pos.y > 240 || - (pos.y + cbs.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh)) - return; - } + if (HandleScrolling(pos, inp)) return; if (ui7_ctx->cm->has_touch) { if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Up) && @@ -843,7 +794,8 @@ bool BeginMenu(const std::string &title, R7Vec2 size, UI7MenuFlags flags) { } if (flags & UI7MenuFlags_TitleMid) txtflags = RD7TextFlags_AlignMid; ui7_ctx->cm->enable_scrolling = (flags & UI7MenuFlags_Scrolling); - if (ui7_ctx->cm->enable_scrolling && !RenderD7::R2()->GetCurrentScreen()) { + if (ui7_ctx->cm->enable_scrolling && !RenderD7::R2()->GetCurrentScreen() && + ui7_ctx->cm->scrolling_possible) { // Patch that sets scrolling to 0 if max pos is not out of screen if (ui7_ctx->cm->scrolling_offset != 0.f && ui7_ctx->cm->ms.y < 235) { ui7_ctx->cm->scrolling_offset = 0.f; @@ -972,7 +924,7 @@ void Grid(const std::string &name, const R7Vec2 &size, const R7Vec2 &entry_size, } } - UI7CtxCursorMove(size); + MoveCursor(size); } void ColorSelector(const std::string &label, unsigned int &color) { @@ -986,16 +938,10 @@ void ColorSelector(const std::string &label, unsigned int &color) { auto id = UI7ID(label); R7Vec2 pos = GetCursorPos(); - UI7CtxCursorMove(inp); + MoveCursor(inp); ui7_ctx->cm->ctrl->AddObj(); - if (ui7_ctx->cm->enable_scrolling) { - R7Vec2 pb = pos; - pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset); - if (pos.y > 240 || - (pos.y + cbs.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh)) - return; - } + if (HandleScrolling(pos, inp)) return; if (ui7_ctx->cm->has_touch) { if (RenderD7::Hid::IsEvent("touch", RenderD7::Hid::Up) && @@ -1212,12 +1158,56 @@ void Debug() { ui7_ctx->debug_calls->Clear(); } -float GetScrollingOffset() { +float Menu::GetScrollingOffset() { if (!UI7CtxValidate()) return 0.f; if (!UI7CtxInMenu()) return 0.f; return ui7_ctx->cm->scrolling_offset; } +void Menu::SetScrollingOffset(float off) { + if (!UI7CtxValidate()) return; + if (!UI7CtxInMenu()) return; + ui7_ctx->cm->scrolling_offset = off; + ui7_ctx->cm->scrolling_mod = 0.f; +} + +bool Menu::IsScrolling() { + if (!UI7CtxValidate()) return false; + if (!UI7CtxInMenu()) return false; + return ui7_ctx->cm->scrolling_mod != 0.f; +} + +void MoveCursor(R7Vec2 size) { + if (!UI7CtxValidate()) return; + if (!UI7CtxInMenu()) return; + ui7_ctx->cm->lszs = size; + ui7_ctx->cm->slc = ui7_ctx->cm->cursor + R7Vec2(size.x + 5, 0); + ui7_ctx->cm->cursor.x = 5; + if (ui7_ctx->cm->bslp.y) { + ui7_ctx->cm->cursor += R7Vec2(0, ui7_ctx->cm->bslp.y + 5); + ui7_ctx->cm->bslp = R7Vec2(); + } else { + ui7_ctx->cm->cursor += R7Vec2(0, size.y + 5); + } + ui7_ctx->cm->ms = R7Vec2(ui7_ctx->cm->slc.x, ui7_ctx->cm->cursor.y); +} + +bool HandleScrolling(R7Vec2 &pos, R7Vec2 size) { + if (ui7_ctx->cm->enable_scrolling) { + R7Vec2 pb = pos; + pos -= R7Vec2(0, ui7_ctx->cm->scrolling_offset); + if (pos.y > 240 || + (pos.y + size.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh)) + return true; + } + return false; +} + +bool InMenu() { + if (!UI7CtxValidate()) return false; + return UI7CtxInMenu(); +} + bool &IsDebugging() { if (!UI7CtxValidate()) { // Return a Default Val diff --git a/source/renderd7.cpp b/source/renderd7.cpp index 4dd430a..4b501c4 100644 --- a/source/renderd7.cpp +++ b/source/renderd7.cpp @@ -683,10 +683,10 @@ void RenderD7::RSettings::Draw(void) const { // List Bg for (int i = 0; i < 12; i++) { if ((i % 2 == 0)) - UI7::GetBackgroundList()->AddRectangle(R7Vec2(0, 40 + (i) * 15), + UI7::GetBackgroundList()->AddRectangle(R7Vec2(0, 40 + (i)*15), R7Vec2(400, 15), RD7Color_List0); else - UI7::GetBackgroundList()->AddRectangle(R7Vec2(0, 40 + (i) * 15), + UI7::GetBackgroundList()->AddRectangle(R7Vec2(0, 40 + (i)*15), R7Vec2(400, 15), RD7Color_List1); }