1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-11 17:51:04 +00:00

style_type and bgcolor

This commit is contained in:
SmallJoker 2025-05-25 14:29:03 +02:00
parent 810bbc5472
commit cd62a39dcc
3 changed files with 43 additions and 29 deletions

View file

@ -38,8 +38,8 @@ A key-value config file with the following keys:
* `textdomain`: Textdomain used to translate title and description.
Defaults to the texture pack name.
See [Translating content meta](lua_api.md#translating-content-meta).
* `formspec_theme`: optional. Default formspec styling.
This is a newline separated list of `style_type[...]` values.
* `formspec_theme`: optional. Formspec elements that define the defaut style.
* Allowed elements: `bgcolor`, `style_type`
* `formspec_version_theme`: optional. Indicates the minimal [formspec version](lua_api.md)
needed to properly display `formspec_theme`. On older clients, this suppresses warnings.

View file

@ -2754,9 +2754,13 @@ void GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element)
}
bool style_type = (data->type == "style_type");
bool do_warn = m_formspec_version <= FORMSPEC_API_VERSION;
parse_style_to_map(style_type ? theme_by_type : theme_by_name,
element, &property_warned);
parse_style_to_map(
style_type ? theme_by_type : theme_by_name,
element,
do_warn ? &property_warned : nullptr
);
}
void GUIFormSpecMenu::parseSetFocus(parserData*, const std::string &element)
@ -2895,8 +2899,8 @@ void GUIFormSpecMenu::removeAll()
scroll_container_it.second->drop();
}
const std::unordered_map<std::string, std::function<void(GUIFormSpecMenu*, GUIFormSpecMenu::parserData *data,
const std::string &description)>> GUIFormSpecMenu::element_parsers = {
const std::unordered_map<std::string, GUIFormSpecMenu::parser_function_t>
GUIFormSpecMenu::element_parsers = {
{"container", &GUIFormSpecMenu::parseContainer},
{"container_end", &GUIFormSpecMenu::parseContainerEnd},
{"list", &GUIFormSpecMenu::parseList},
@ -2945,14 +2949,20 @@ const std::unordered_map<std::string, std::function<void(GUIFormSpecMenu*, GUIFo
{"allow_close", &GUIFormSpecMenu::parseAllowClose},
};
// Formspec elements allowed for themes
const std::unordered_map<std::string, GUIFormSpecMenu::parser_function_t>
GUIFormSpecMenu::element_parsers_theme = {
{"bgcolor", &GUIFormSpecMenu::parseBackgroundColor},
{"style_type", &GUIFormSpecMenu::parseStyle},
};
void GUIFormSpecMenu::parseElement(parserData* data, const std::string &element)
void GUIFormSpecMenu::parseElement(parserData *data, const std::string &element, bool is_theme)
{
//some prechecks
if (element.empty())
return;
if (parseVersionDirect(element))
if (!is_theme && parseVersionDirect(element))
return;
size_t pos = element.find('[');
@ -2965,8 +2975,9 @@ void GUIFormSpecMenu::parseElement(parserData* data, const std::string &element)
// They remain here due to bool flags, for now
data->type = type;
auto it = element_parsers.find(type);
if (it != element_parsers.end()) {
auto &parser_lut = is_theme ? element_parsers_theme : element_parsers;
auto it = parser_lut.find(type);
if (it != parser_lut.end()) {
it->second(this, data, description);
return;
}
@ -3039,7 +3050,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
m_dropdowns.clear();
m_scroll_containers.clear();
theme_by_name.clear();
theme_by_type = theme_by_type_default;
theme_by_type.clear();
m_clickthrough_elements.clear();
field_enter_after_edit.clear();
field_close_on_enter.clear();
@ -3237,6 +3248,16 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
pos_offset = v2f32();
if (!m_theme_elements.empty()) {
// Formspec theming
const u16 version_backup = m_formspec_version;
m_formspec_version = m_theme_formspec_version;
for (const std::string &element : m_theme_elements)
parseElement(&mydata, element, true);
m_formspec_version = version_backup;
}
// used for formspec versions < 3
auto legacy_sort_start = std::prev(Children.end()); // last element
@ -5029,7 +5050,7 @@ std::wstring GUIFormSpecMenu::getLabelByID(s32 id)
void GUIFormSpecMenu::setThemeFromSettings()
{
theme_by_type_default.clear();
m_theme_elements.clear();
const std::string settingspath = g_settings->get("texture_path") + DIR_DELIM + "texture_pack.conf";
Settings settings;
@ -5038,19 +5059,8 @@ void GUIFormSpecMenu::setThemeFromSettings()
if (!settings.exists("formspec_theme"))
return;
std::unordered_set<std::string> *prop_warned = nullptr;
{
u16 fs_ver = FORMSPEC_API_VERSION;
settings.getU16NoEx("formspec_version_theme", fs_ver);
if (fs_ver <= FORMSPEC_API_VERSION)
prop_warned = &property_warned;
// else: silence
}
auto splits = split(settings.get("formspec_theme"), '\n');
for (const std::string &s : splits) {
parse_style_to_map(theme_by_type_default, s, prop_warned);
}
settings.getU16NoEx("formspec_version_theme", m_theme_formspec_version);
m_theme_elements = split(settings.get("formspec_theme"), ']');
}
void GUIFormSpecMenu::onTxpSettingChanged(const std::string &name, void *data)

View file

@ -303,10 +303,12 @@ protected:
size_t args_min, size_t args_max, std::vector<std::string> &parts);
using StyleSpecMap = std::unordered_map<std::string, std::vector<StyleSpec>>;
StyleSpecMap theme_by_type, theme_by_name,
theme_by_type_default;
StyleSpecMap theme_by_type, theme_by_name;
std::unordered_set<std::string> property_warned;
// Texturepack-definied formspec theming support
std::vector<std::string> m_theme_elements;
u16 m_theme_formspec_version;
void setThemeFromSettings();
static void onTxpSettingChanged(const std::string &name, void *data);
@ -423,7 +425,9 @@ private:
std::string type;
};
static const std::unordered_map<std::string, std::function<void(GUIFormSpecMenu*, GUIFormSpecMenu::parserData *data, const std::string &description)>> element_parsers;
using parser_function_t = std::function<void(GUIFormSpecMenu*, parserData *, const std::string &)>;
static const std::unordered_map<std::string, parser_function_t>
element_parsers, element_parsers_theme;
struct fs_key_pending {
bool key_up;
@ -437,7 +441,7 @@ private:
void removeAll();
void parseElement(parserData* data, const std::string &element);
void parseElement(parserData* data, const std::string &element, bool is_theme = false);
void parseSize(parserData* data, const std::string &element);
void parseContainer(parserData* data, const std::string &element);