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:
parent
5c6e4d35b0
commit
0cf1c47f6c
4 changed files with 108 additions and 60 deletions
|
@ -310,9 +310,17 @@ local function get_formspec(dlgdata)
|
|||
})
|
||||
local img_w = cell_h * 3 / 2
|
||||
|
||||
-- Use as much of the available space as possible (so no padding on the
|
||||
-- right/bottom), but don't quite allow the text to touch the border.
|
||||
local text_w = cell_w - img_w - 0.25 - 0.025
|
||||
local text_h = cell_h - 0.25 - 0.025
|
||||
|
||||
local start_idx = (cur_page - 1) * num_per_page + 1
|
||||
for i=start_idx, math.min(#contentdb.packages, start_idx+num_per_page-1) do
|
||||
local package = contentdb.packages[i]
|
||||
local text = core.colorize(mt_color_green, package.title) ..
|
||||
core.colorize("#BFBFBF", " by " .. package.author) .. "\n" ..
|
||||
package.short_description
|
||||
|
||||
table.insert_all(formspec, {
|
||||
"container[",
|
||||
|
@ -327,13 +335,14 @@ local function get_formspec(dlgdata)
|
|||
"image[0,0;", img_w, ",", cell_h, ";",
|
||||
core.formspec_escape(get_screenshot(package, package.thumbnail, 2)), "]",
|
||||
|
||||
"label[", img_w + 0.25 + 0.05, ",0.5;",
|
||||
core.formspec_escape(
|
||||
core.colorize(mt_color_green, package.title) ..
|
||||
core.colorize("#BFBFBF", " by " .. package.author)), "]",
|
||||
"label[", img_w + 0.25, ",0.25;", text_w, ",", text_h, ";",
|
||||
core.formspec_escape(text), "]",
|
||||
|
||||
"textarea[", img_w + 0.25, ",0.75;", cell_w - img_w - 0.25, ",", cell_h - 0.75, ";;;",
|
||||
core.formspec_escape(package.short_description), "]",
|
||||
-- Add a tooltip in case the label overflows and the short description is cut off.
|
||||
"tooltip[", img_w + 0.25, ",0.25;", text_w, ",", text_h, ";",
|
||||
-- Text in tooltips doesn't wrap automatically, so we do it manually to
|
||||
-- avoid everything being one long line.
|
||||
core.formspec_escape(core.wrap_text(package.short_description, 80)), "]",
|
||||
|
||||
"style[view_", i, ";border=false]",
|
||||
"style[view_", i, ":hovered;bgimg=", core.formspec_escape(defaulttexturedir .. "button_hover_semitrans.png"), "]",
|
||||
|
@ -349,7 +358,7 @@ local function get_formspec(dlgdata)
|
|||
end
|
||||
|
||||
table.insert_all(formspec, {
|
||||
"container[", cell_w - 0.625,",", 0.25, "]",
|
||||
"container[", cell_w - 0.625,",", 0.125, "]",
|
||||
})
|
||||
|
||||
if package.downloading then
|
||||
|
|
|
@ -2842,6 +2842,9 @@ Version History
|
|||
* Add field_enter_after_edit[] (experimental)
|
||||
* Formspec version 8 (5.10.0)
|
||||
* scroll_container[]: content padding parameter
|
||||
* Formspec version 9 (5.12.0)
|
||||
* Add allow_close[]
|
||||
* label[]: Add "area label" variant
|
||||
|
||||
Elements
|
||||
--------
|
||||
|
@ -3154,9 +3157,11 @@ Elements
|
|||
### `textarea[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]`
|
||||
|
||||
* Same as fields above, but with multi-line input
|
||||
* Text is wrapped to fit within the given bounds.
|
||||
* If the text overflows, a vertical scrollbar is added.
|
||||
* If the name is empty, the textarea is read-only and
|
||||
the background is not shown, which corresponds to a multi-line label.
|
||||
See also `label[<X>,<Y>;<W>,<H>;<label>]` for an alternative.
|
||||
|
||||
### `label[<X>,<Y>;<label>]`
|
||||
|
||||
|
@ -3171,6 +3176,16 @@ Elements
|
|||
half a coordinate. With the old system, newlines are spaced 2/5 of
|
||||
an inventory slot.
|
||||
|
||||
### `label[<X>,<Y>;<W>,<H>;<label>]`
|
||||
|
||||
* The "area label" formspec element displays the text set in `label`
|
||||
at the specified position and size.
|
||||
* Text is wrapped to fit within the given bounds.
|
||||
* If the text overflows, it is currently simply truncated, but this behavior is
|
||||
subject to change. There is no scrollbar.
|
||||
* See also `textarea` for an alternative.
|
||||
* Only available with the new coordinate system.
|
||||
|
||||
### `hypertext[<X>,<Y>;<W>,<H>;<name>;<text>]`
|
||||
* Displays a static formatted text with hyperlinks.
|
||||
* **Note**: This element is currently unstable and subject to change.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,4 +71,4 @@
|
|||
const u16 LATEST_PROTOCOL_VERSION = 48;
|
||||
|
||||
// See also formspec [Version History] in doc/lua_api.md
|
||||
const u16 FORMSPEC_API_VERSION = 8;
|
||||
const u16 FORMSPEC_API_VERSION = 9;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue