1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-06 17:41: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. * `textdomain`: Textdomain used to translate title and description.
Defaults to the texture pack name. Defaults to the texture pack name.
See [Translating content meta](lua_api.md#translating-content-meta). See [Translating content meta](lua_api.md#translating-content-meta).
* `formspec_theme`: optional. Default formspec styling. * `formspec_theme`: optional. Formspec elements that define the defaut style.
This is a newline separated list of `style_type[...]` values. * Allowed elements: `bgcolor`, `style_type`
* `formspec_version_theme`: optional. Indicates the minimal [formspec version](lua_api.md) * `formspec_version_theme`: optional. Indicates the minimal [formspec version](lua_api.md)
needed to properly display `formspec_theme`. On older clients, this suppresses warnings. 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 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, parse_style_to_map(
element, &property_warned); style_type ? theme_by_type : theme_by_name,
element,
do_warn ? &property_warned : nullptr
);
} }
void GUIFormSpecMenu::parseSetFocus(parserData*, const std::string &element) void GUIFormSpecMenu::parseSetFocus(parserData*, const std::string &element)
@ -2895,8 +2899,8 @@ void GUIFormSpecMenu::removeAll()
scroll_container_it.second->drop(); scroll_container_it.second->drop();
} }
const std::unordered_map<std::string, std::function<void(GUIFormSpecMenu*, GUIFormSpecMenu::parserData *data, const std::unordered_map<std::string, GUIFormSpecMenu::parser_function_t>
const std::string &description)>> GUIFormSpecMenu::element_parsers = { GUIFormSpecMenu::element_parsers = {
{"container", &GUIFormSpecMenu::parseContainer}, {"container", &GUIFormSpecMenu::parseContainer},
{"container_end", &GUIFormSpecMenu::parseContainerEnd}, {"container_end", &GUIFormSpecMenu::parseContainerEnd},
{"list", &GUIFormSpecMenu::parseList}, {"list", &GUIFormSpecMenu::parseList},
@ -2945,14 +2949,20 @@ const std::unordered_map<std::string, std::function<void(GUIFormSpecMenu*, GUIFo
{"allow_close", &GUIFormSpecMenu::parseAllowClose}, {"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 //some prechecks
if (element.empty()) if (element.empty())
return; return;
if (parseVersionDirect(element)) if (!is_theme && parseVersionDirect(element))
return; return;
size_t pos = element.find('['); 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 // They remain here due to bool flags, for now
data->type = type; data->type = type;
auto it = element_parsers.find(type); auto &parser_lut = is_theme ? element_parsers_theme : element_parsers;
if (it != element_parsers.end()) { auto it = parser_lut.find(type);
if (it != parser_lut.end()) {
it->second(this, data, description); it->second(this, data, description);
return; return;
} }
@ -3039,7 +3050,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
m_dropdowns.clear(); m_dropdowns.clear();
m_scroll_containers.clear(); m_scroll_containers.clear();
theme_by_name.clear(); theme_by_name.clear();
theme_by_type = theme_by_type_default; theme_by_type.clear();
m_clickthrough_elements.clear(); m_clickthrough_elements.clear();
field_enter_after_edit.clear(); field_enter_after_edit.clear();
field_close_on_enter.clear(); field_close_on_enter.clear();
@ -3237,6 +3248,16 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
pos_offset = v2f32(); 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 // used for formspec versions < 3
auto legacy_sort_start = std::prev(Children.end()); // last element auto legacy_sort_start = std::prev(Children.end()); // last element
@ -5029,7 +5050,7 @@ std::wstring GUIFormSpecMenu::getLabelByID(s32 id)
void GUIFormSpecMenu::setThemeFromSettings() 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"; const std::string settingspath = g_settings->get("texture_path") + DIR_DELIM + "texture_pack.conf";
Settings settings; Settings settings;
@ -5038,19 +5059,8 @@ void GUIFormSpecMenu::setThemeFromSettings()
if (!settings.exists("formspec_theme")) if (!settings.exists("formspec_theme"))
return; return;
std::unordered_set<std::string> *prop_warned = nullptr; settings.getU16NoEx("formspec_version_theme", m_theme_formspec_version);
{ m_theme_elements = split(settings.get("formspec_theme"), ']');
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);
}
} }
void GUIFormSpecMenu::onTxpSettingChanged(const std::string &name, void *data) 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); size_t args_min, size_t args_max, std::vector<std::string> &parts);
using StyleSpecMap = std::unordered_map<std::string, std::vector<StyleSpec>>; using StyleSpecMap = std::unordered_map<std::string, std::vector<StyleSpec>>;
StyleSpecMap theme_by_type, theme_by_name, StyleSpecMap theme_by_type, theme_by_name;
theme_by_type_default;
std::unordered_set<std::string> property_warned; 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(); void setThemeFromSettings();
static void onTxpSettingChanged(const std::string &name, void *data); static void onTxpSettingChanged(const std::string &name, void *data);
@ -423,7 +425,9 @@ private:
std::string type; 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 { struct fs_key_pending {
bool key_up; bool key_up;
@ -437,7 +441,7 @@ private:
void removeAll(); 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 parseSize(parserData* data, const std::string &element);
void parseContainer(parserData* data, const std::string &element); void parseContainer(parserData* data, const std::string &element);