fix(ui): trunca el value al menú amb "..." quan se sol·lapa amb la label
This commit is contained in:
1 parent
996ff0053e
commit
f3977170b7
1 file changed
+48
-7
@@ -35,6 +35,10 @@ namespace {
|
||||
constexpr int PAD_X = 10;
|
||||
constexpr int GAP_Y = 6;
|
||||
constexpr int ITEM_GAP_Y = 2;
|
||||
// Mínim buit entre la label (a l'esquerra) i el value (a la dreta).
|
||||
// Si amb el value sencer no queda aquest gap, truncam amb "..." des
|
||||
// del final del value.
|
||||
constexpr int MIN_LABEL_VALUE_GAP = 6;
|
||||
// Les fonts display reserven ~2 px de descendent al fons de la seua
|
||||
// caixa (per a `g`, `p`, `q`...). Quan el títol no porta cap d'aquests
|
||||
// glifs, eixos 2 px queden buits i el gap visual sota el títol sembla
|
||||
@@ -755,6 +759,48 @@ auto ServiceMenu::buildKeyboardControls() -> Page {
|
||||
|
||||
namespace {
|
||||
|
||||
// Trunca `text` amb "..." perquè la seua amplada renderitzada no
|
||||
// supere `max_w` píxels amb la font i el kerning donats. Port del
|
||||
// helper de coffee_crisis_arcade_edition: estimació inicial a partir
|
||||
// de l'amplada mitjana per caràcter i ajust iteratiu mesurant amb
|
||||
// `Text::length`, per a fonts d'amplada variable on l'estimació
|
||||
// només és aproximada.
|
||||
auto truncateToFit(const Text& font, const std::string& text, int max_w, int kerning) -> std::string {
|
||||
if (font.length(text, kerning) <= max_w) { return text; }
|
||||
static constexpr const char* ELLIPSIS = "...";
|
||||
const int ELLIPSIS_W = font.length(ELLIPSIS, kerning);
|
||||
if (max_w <= ELLIPSIS_W || text.empty()) { return ELLIPSIS; }
|
||||
const auto TOTAL_W = static_cast<float>(font.length(text, kerning));
|
||||
const auto AVG_CHAR_W = TOTAL_W / static_cast<float>(text.size());
|
||||
auto keep = static_cast<std::size_t>(static_cast<float>(max_w - ELLIPSIS_W) / AVG_CHAR_W);
|
||||
keep = std::min(keep, text.size());
|
||||
std::string out = text.substr(0, keep) + ELLIPSIS;
|
||||
while (keep > 0 && font.length(out, kerning) > max_w) {
|
||||
--keep;
|
||||
out = text.substr(0, keep) + ELLIPSIS;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Dibuixa el value d'un item a la dreta del box, truncant-lo amb
|
||||
// "..." si no cap a l'esquerra de la label. Extret de `renderPage`
|
||||
// per a mantenir la complexitat cognitiva sota el llindar de
|
||||
// clang-tidy.
|
||||
void drawItemValue(Text& font, int box_x, int box_w, int cursor_y, int cursor_width, const std::string& label, const std::string& value, int kerning, Uint8 color) {
|
||||
const int LABEL_W = font.length(label, kerning);
|
||||
const int AVAILABLE_W = box_w - (2 * PAD_X) - cursor_width - LABEL_W - MIN_LABEL_VALUE_GAP;
|
||||
if (AVAILABLE_W <= 0) { return; }
|
||||
const std::string DISPLAY = truncateToFit(font, value, AVAILABLE_W, kerning);
|
||||
if (DISPLAY.empty()) { return; }
|
||||
const int VALUE_W = font.length(DISPLAY, kerning);
|
||||
font.writeDX(Text::COLOR_FLAG,
|
||||
box_x + box_w - PAD_X - VALUE_W,
|
||||
cursor_y,
|
||||
DISPLAY,
|
||||
kerning,
|
||||
color);
|
||||
}
|
||||
|
||||
// Mandos visibles al cycle d'un jugador: tots els connectats
|
||||
// EXCEPTE els reclamats per l'altre jugador. Així l'usuari mai pot
|
||||
// assignar el mateix mando a dos jugadors des de la UI — per
|
||||
@@ -1025,13 +1071,8 @@ void ServiceMenu::renderPage(const Page& page, int box_x, int box_y, int box_w)
|
||||
// només tenen ACTION / LABEL); els Toggle/Cycle viuen en pàgines
|
||||
// d'opcions amb layout esquerra-dreta.
|
||||
if (!page.center_items && !VALUE.empty()) {
|
||||
const int VALUE_W = items_font_->length(VALUE, ITEM_KERNING);
|
||||
items_font_->writeDX(Text::COLOR_FLAG,
|
||||
box_x + box_w - PAD_X - VALUE_W,
|
||||
cursor_y,
|
||||
VALUE,
|
||||
ITEM_KERNING,
|
||||
SELECTED ? UiConfig::get().menuCursor() : UiConfig::get().menuValue());
|
||||
const Uint8 VALUE_COLOR = SELECTED ? UiConfig::get().menuCursor() : UiConfig::get().menuValue();
|
||||
drawItemValue(*items_font_, box_x, box_w, cursor_y, CURSOR_WIDTH, LABEL_TEXT, VALUE, ITEM_KERNING, VALUE_COLOR);
|
||||
}
|
||||
|
||||
cursor_y += ITEM_H;
|
||||
|
||||
Reference in new issue
Block a user