1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Fix scrollbar on ContentDB grid by adding an area label (#16042)

Co-authored-by: rubenwardy <rw@rubenwardy.com>
This commit is contained in:
grorp 2025-04-21 06:33:41 -04:00 committed by GitHub
parent 5c6e4d35b0
commit 0cf1c47f6c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 108 additions and 60 deletions

View file

@ -1768,12 +1768,19 @@ void GUIFormSpecMenu::parseHyperText(parserData *data, const std::string &elemen
void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
{
std::vector<std::string> parts;
if (!precheckElement("label", element, 2, 2, parts))
if (!precheckElement("label", element, 2, data->real_coordinates ? 3 : 2, parts))
return;
std::vector<std::string> v_pos = split(parts[0],',');
std::vector<std::string> v_pos = split(parts[0], ',');
MY_CHECKPOS("label", 0);
MY_CHECKPOS("label",0);
bool has_size = parts.size() >= 3;
v2s32 geom;
if (has_size) {
std::vector<std::string> v_geom = split(parts[1], ',');
MY_CHECKGEOM("label", 1);
geom = getRealCoordinateGeometry(v_geom);
}
if(!data->explicit_size)
warningstream<<"invalid use of label without a size[] element"<<std::endl;
@ -1783,53 +1790,8 @@ void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
if (!font)
font = m_font;
EnrichedString str(unescape_string(utf8_to_wide(parts[1])));
size_t str_pos = 0;
for (size_t i = 0; str_pos < str.size(); ++i) {
EnrichedString line = str.getNextLine(&str_pos);
core::rect<s32> rect;
if (data->real_coordinates) {
// Lines are spaced at the distance of 1/2 imgsize.
// This alows lines that line up with the new elements
// easily without sacrificing good line distance. If
// it was one whole imgsize, it would have too much
// spacing.
v2s32 pos = getRealCoordinateBasePos(v_pos);
// Labels are positioned by their center, not their top.
pos.Y += (((float) imgsize.Y) / -2) + (((float) imgsize.Y) * i / 2);
rect = core::rect<s32>(
pos.X, pos.Y,
pos.X + font->getDimension(line.c_str()).Width,
pos.Y + imgsize.Y);
} else {
// Lines are spaced at the nominal distance of
// 2/5 inventory slot, even if the font doesn't
// quite match that. This provides consistent
// form layout, at the expense of sometimes
// having sub-optimal spacing for the font.
// We multiply by 2 and then divide by 5, rather
// than multiply by 0.4, to get exact results
// in the integer cases: 0.4 is not exactly
// representable in binary floating point.
v2s32 pos = getElementBasePos(nullptr);
pos.X += stof(v_pos[0]) * spacing.X;
pos.Y += (stof(v_pos[1]) + 7.0f / 30.0f) * spacing.Y;
pos.Y += ((float) i) * spacing.Y * 2.0 / 5.0;
rect = core::rect<s32>(
pos.X, pos.Y - m_btn_height,
pos.X + font->getDimension(line.c_str()).Width,
pos.Y + m_btn_height);
}
auto add_label = [&](core::rect<s32> rect, const EnrichedString &text,
EGUI_ALIGNMENT align_h, EGUI_ALIGNMENT align_v, bool word_wrap) {
FieldSpec spec(
"",
L"",
@ -1838,9 +1800,10 @@ void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
4
);
gui::IGUIStaticText *e = gui::StaticText::add(Environment,
line, rect, false, false, data->current_parent,
text, rect, false, false, data->current_parent,
spec.fid);
e->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_CENTER);
e->setTextAlignment(align_h, align_v);
e->setWordWrap(word_wrap);
e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
@ -1851,6 +1814,67 @@ void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
// labels should let events through
e->grab();
m_clickthrough_elements.push_back(e);
};
EnrichedString str(unescape_string(utf8_to_wide(parts[has_size ? 2 : 1])));
if (geom == v2s32()) {
size_t str_pos = 0;
for (size_t i = 0; str_pos < str.size(); ++i) {
EnrichedString line = str.getNextLine(&str_pos);
core::rect<s32> rect;
if (data->real_coordinates) {
// Lines are spaced at the distance of 1/2 imgsize.
// This alows lines that line up with the new elements
// easily without sacrificing good line distance. If
// it was one whole imgsize, it would have too much
// spacing.
v2s32 pos = getRealCoordinateBasePos(v_pos);
// Labels are positioned by their center, not their top.
pos.Y += (((float) imgsize.Y) / -2) + (((float) imgsize.Y) * i / 2);
rect = core::rect<s32>(
pos.X, pos.Y,
pos.X + font->getDimension(line.c_str()).Width,
pos.Y + imgsize.Y);
} else {
// Lines are spaced at the nominal distance of
// 2/5 inventory slot, even if the font doesn't
// quite match that. This provides consistent
// form layout, at the expense of sometimes
// having sub-optimal spacing for the font.
// We multiply by 2 and then divide by 5, rather
// than multiply by 0.4, to get exact results
// in the integer cases: 0.4 is not exactly
// representable in binary floating point.
v2s32 pos = getElementBasePos(nullptr);
pos.X += stof(v_pos[0]) * spacing.X;
pos.Y += (stof(v_pos[1]) + 7.0f / 30.0f) * spacing.Y;
pos.Y += ((float) i) * spacing.Y * 2.0 / 5.0;
rect = core::rect<s32>(
pos.X, pos.Y - m_btn_height,
pos.X + font->getDimension(line.c_str()).Width,
pos.Y + m_btn_height);
}
add_label(rect, line, gui::EGUIA_UPPERLEFT, gui::EGUIA_CENTER, false);
}
} else {
v2s32 pos = getRealCoordinateBasePos(v_pos);
core::rect<s32> rect(
pos.X, pos.Y,
pos.X + geom.X,
pos.Y + geom.Y);
add_label(rect, str, gui::EGUIA_UPPERLEFT, gui::EGUIA_UPPERLEFT, true);
}
}