mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Merge bd0d9a7f95
into 2d36d32da8
This commit is contained in:
commit
23aba644cd
14 changed files with 286 additions and 48 deletions
|
@ -3653,6 +3653,8 @@ Some types may inherit styles from parent types.
|
|||
* `+<number>`/`-<number>`: Offsets default font size by `number` points.
|
||||
* `*<number>`: Multiplies default font size by `number`, similar to CSS `em`.
|
||||
* border - boolean, draw border. Set to false to hide the bevelled button pane. Default true.
|
||||
* border_img - string, a texture that overrides the border style.
|
||||
* border_img_middle - rect, to render `border_img` in 9-sliced mode. Refer to `background9[...]`.
|
||||
* content_offset - 2d vector, shifts the position of the button's content without resizing it.
|
||||
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
||||
* padding - rect, adds space between the edges of the button and the content. This value is
|
||||
|
|
|
@ -38,6 +38,10 @@ 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. 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.
|
||||
|
||||
### `description.txt`
|
||||
**Deprecated**, you should use texture_pack.conf instead.
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#endif
|
||||
#include "os.h"
|
||||
|
||||
irr::gui::IGUISkin *impl_create_irr_guiskin(irr::video::IVideoDriver *driver);
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace gui
|
||||
|
@ -590,7 +592,7 @@ If you no longer need the skin, you should call IGUISkin::drop().
|
|||
See IReferenceCounted::drop() for more information. */
|
||||
IGUISkin *CGUIEnvironment::createSkin()
|
||||
{
|
||||
IGUISkin *skin = new CGUISkin(Driver);
|
||||
IGUISkin *skin = impl_create_irr_guiskin(Driver);
|
||||
|
||||
IGUIFont *builtinfont = getBuiltInFont();
|
||||
IGUIFontBitmap *bitfont = 0;
|
||||
|
|
|
@ -291,7 +291,7 @@ namespace gui
|
|||
//! gets the colors
|
||||
virtual void getColors(video::SColor* colors); // ::PATCH:
|
||||
|
||||
private:
|
||||
protected:
|
||||
|
||||
float Scale = 1.0f;
|
||||
video::SColor Colors[EGDC_COUNT];
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "inputhandler.h"
|
||||
#include "profiler.h"
|
||||
#include "gui/guiEngine.h"
|
||||
#include "gui/guiSkin.h"
|
||||
#include "fontengine.h"
|
||||
#include "clientlauncher.h"
|
||||
#include "version.h"
|
||||
|
@ -338,6 +339,11 @@ static video::ITexture *loadTexture(video::IVideoDriver *driver, const char *pat
|
|||
return texture;
|
||||
}
|
||||
|
||||
gui::IGUISkin *impl_create_irr_guiskin(video::IVideoDriver *driver)
|
||||
{
|
||||
return new GUISkin(driver);
|
||||
}
|
||||
|
||||
void ClientLauncher::config_guienv()
|
||||
{
|
||||
gui::IGUISkin *skin = guienv->getSkin();
|
||||
|
|
|
@ -19,6 +19,7 @@ set(gui_SRCS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/guiScene.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiScrollBar.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiScrollContainer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiSkin.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiTable.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiHyperText.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/guiVolumeChange.cpp
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
class StyleSpec;
|
||||
|
||||
using StyleSpecMap = std::unordered_map<std::string, std::vector<StyleSpec>>;
|
||||
|
||||
class StyleSpec
|
||||
{
|
||||
|
@ -59,6 +62,8 @@ public:
|
|||
STATE_INVALID = 1 << 4,
|
||||
};
|
||||
|
||||
using StateMap = std::array<StyleSpec, NUM_STATES>;
|
||||
|
||||
private:
|
||||
std::array<bool, NUM_PROPERTIES> property_set{};
|
||||
std::array<std::string, NUM_PROPERTIES> properties;
|
||||
|
@ -380,12 +385,24 @@ public:
|
|||
|
||||
StyleSpec &operator|=(const StyleSpec &other)
|
||||
{
|
||||
u32 props_set = 0;
|
||||
static_assert(sizeof(props_set) * 8 > NUM_PROPERTIES);
|
||||
|
||||
for (size_t i = 0; i < NUM_PROPERTIES; i++) {
|
||||
auto prop = (Property)i;
|
||||
if (other.hasProperty(prop)) {
|
||||
props_set |= (1 << i);
|
||||
set(prop, other.get(prop, ""));
|
||||
}
|
||||
}
|
||||
if ((props_set & (1 << FGIMG | 1 << FGIMG_MIDDLE)) == (1 << FGIMG)) {
|
||||
// Image was specified without 9-slice. Reset to non-9-slice.
|
||||
set(FGIMG_MIDDLE, "");
|
||||
}
|
||||
if ((props_set & (1 << BGIMG | 1 << BGIMG_MIDDLE)) == (1 << BGIMG)) {
|
||||
// Image was specified without 9-slice. Reset to non-9-slice.
|
||||
set(BGIMG_MIDDLE, "");
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -303,13 +303,17 @@ void GUIButton::draw()
|
|||
|
||||
// PATCH
|
||||
video::ITexture* texture = ButtonImages[(u32)imageState].Texture;
|
||||
// FIXME: Vertices can only be darkened because [0, 255] is normalized to [0, 1]
|
||||
// For reference: irr/src/OpenGL/Driver.cpp -> `vt2DImage`
|
||||
video::SColor image_colors[] = { BgColor, BgColor, BgColor, BgColor };
|
||||
if (BgMiddle.getArea() == 0) {
|
||||
// Regular image button
|
||||
driver->draw2DImage(texture,
|
||||
ScaleImage? AbsoluteRect : core::rect<s32>(pos, sourceRect.getSize()),
|
||||
sourceRect, &AbsoluteClippingRect,
|
||||
image_colors, UseAlphaChannel);
|
||||
} else {
|
||||
// This is generally used to replace the default border style
|
||||
draw2DImage9Slice(driver, texture,
|
||||
ScaleImage ? AbsoluteRect : core::rect<s32>(pos, sourceRect.getSize()),
|
||||
sourceRect, BgMiddle, &AbsoluteClippingRect, image_colors);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "client/guiscalingfilter.h"
|
||||
#include "client/renderingengine.h"
|
||||
#include "client/shader.h"
|
||||
#include "client/texturepaths.h"
|
||||
#include "client/tile.h"
|
||||
#include "clientdynamicinfo.h"
|
||||
#include "config.h"
|
||||
|
@ -43,14 +44,18 @@ void TextDestGuiEngine::gotText(const StringMap &fields)
|
|||
}
|
||||
|
||||
/******************************************************************************/
|
||||
MenuTextureSource::MenuTextureSource(video::IVideoDriver* driver) :
|
||||
m_driver(driver)
|
||||
{
|
||||
g_settings->registerChangedCallback("texture_path", onTxpSettingChanged, this);
|
||||
}
|
||||
|
||||
MenuTextureSource::~MenuTextureSource()
|
||||
{
|
||||
u32 before = m_driver->getTextureCount();
|
||||
g_settings->deregisterAllChangedCallbacks(this);
|
||||
|
||||
for (const auto &it: m_to_delete) {
|
||||
m_driver->removeTexture(it);
|
||||
}
|
||||
m_to_delete.clear();
|
||||
u32 before = m_driver->getTextureCount();
|
||||
cleanupTextures();
|
||||
|
||||
infostream << "~MenuTextureSource() before cleanup: "<< before
|
||||
<< " after: " << m_driver->getTextureCount() << std::endl;
|
||||
|
@ -70,8 +75,14 @@ video::ITexture *MenuTextureSource::getTexture(const std::string &name, u32 *id)
|
|||
if (retval)
|
||||
return retval;
|
||||
|
||||
verbosestream << "MenuTextureSource: loading " << name << std::endl;
|
||||
video::IImage *image = m_driver->createImageFromFile(name.c_str());
|
||||
// Try to find the texture in the active texture pack
|
||||
std::string path;
|
||||
if (!fs::IsPathAbsolute(name))
|
||||
path = getTexturePath(name, nullptr);
|
||||
|
||||
const char *filepath = path.empty() ? name.c_str() : path.c_str();
|
||||
verbosestream << "MenuTextureSource: loading " << filepath << std::endl;
|
||||
video::IImage *image = m_driver->createImageFromFile(filepath);
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
|
@ -83,6 +94,20 @@ video::ITexture *MenuTextureSource::getTexture(const std::string &name, u32 *id)
|
|||
return retval;
|
||||
}
|
||||
|
||||
void MenuTextureSource::cleanupTextures()
|
||||
{
|
||||
for (const auto &it: m_to_delete) {
|
||||
m_driver->removeTexture(it);
|
||||
}
|
||||
m_to_delete.clear();
|
||||
}
|
||||
|
||||
void MenuTextureSource::onTxpSettingChanged(const std::string &name, void *data)
|
||||
{
|
||||
((MenuTextureSource *)data)->cleanupTextures();
|
||||
clearTextureNameCache();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/** MenuMusicFetcher */
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
* default constructor
|
||||
* @param driver the video driver to load textures from
|
||||
*/
|
||||
MenuTextureSource(video::IVideoDriver *driver) : m_driver(driver) {};
|
||||
MenuTextureSource(video::IVideoDriver *driver);
|
||||
|
||||
/**
|
||||
* destructor, removes all loaded textures
|
||||
|
@ -91,6 +91,12 @@ public:
|
|||
video::ITexture *getTexture(const std::string &name, u32 *id = NULL);
|
||||
|
||||
private:
|
||||
/** Unloads all textures in `m_to_delete` */
|
||||
void cleanupTextures();
|
||||
|
||||
/** Update the texture cache */
|
||||
static void onTxpSettingChanged(const std::string &name, void *data);
|
||||
|
||||
/** driver to get textures from */
|
||||
video::IVideoDriver *m_driver = nullptr;
|
||||
/** set of textures to delete */
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "guiScrollContainer.h"
|
||||
#include "guiHyperText.h"
|
||||
#include "guiScene.h"
|
||||
#include "guiSkin.h"
|
||||
|
||||
#define MY_CHECKPOS(a,b) \
|
||||
if (v_pos.size() != 2) { \
|
||||
|
@ -114,10 +115,15 @@ GUIFormSpecMenu::GUIFormSpecMenu(JoystickController *joystick,
|
|||
|
||||
m_tooltip_show_delay = (u32)g_settings->getS32("tooltip_show_delay");
|
||||
m_tooltip_append_itemname = g_settings->getBool("tooltip_append_itemname");
|
||||
|
||||
g_settings->registerChangedCallback("texture_path", onTxpSettingChanged, this);
|
||||
setThemeFromSettings();
|
||||
}
|
||||
|
||||
GUIFormSpecMenu::~GUIFormSpecMenu()
|
||||
{
|
||||
g_settings->deregisterAllChangedCallbacks(this);
|
||||
|
||||
removeAll();
|
||||
|
||||
delete m_selected_item;
|
||||
|
@ -2618,15 +2624,9 @@ void GUIFormSpecMenu::parsePadding(parserData *data, const std::string &element)
|
|||
<< "'" << std::endl;
|
||||
}
|
||||
|
||||
void GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element)
|
||||
void GUIFormSpecMenu::parse_style_to_map(StyleSpecMap &out, const std::string &element,
|
||||
std::unordered_set<std::string> *prop_warned)
|
||||
{
|
||||
if (data->type != "style" && data->type != "style_type") {
|
||||
errorstream << "Invalid style element type: '" << data->type << "'" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
bool style_type = (data->type == "style_type");
|
||||
|
||||
std::vector<std::string> parts = split(element, ';');
|
||||
|
||||
if (parts.size() < 2) {
|
||||
|
@ -2653,11 +2653,11 @@ void GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element)
|
|||
|
||||
StyleSpec::Property prop = StyleSpec::GetPropertyByName(propname);
|
||||
if (prop == StyleSpec::NONE) {
|
||||
if (property_warned.find(propname) != property_warned.end()) {
|
||||
if (prop_warned && prop_warned->find(propname) != prop_warned->end()) {
|
||||
warningstream << "Invalid style element (Unknown property " << propname << "): '"
|
||||
<< element
|
||||
<< "'" << std::endl;
|
||||
property_warned.insert(propname);
|
||||
prop_warned->insert(propname);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -2705,11 +2705,7 @@ void GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (style_type) {
|
||||
theme_by_type[selector].push_back(selector_spec);
|
||||
} else {
|
||||
theme_by_name[selector].push_back(selector_spec);
|
||||
}
|
||||
out[selector].push_back(selector_spec);
|
||||
|
||||
// Backwards-compatibility for existing _hovered/_pressed properties
|
||||
if (selector_spec.hasProperty(StyleSpec::BGCOLOR_HOVERED)
|
||||
|
@ -2728,11 +2724,7 @@ void GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element)
|
|||
hover_spec.set(StyleSpec::FGIMG, selector_spec.get(StyleSpec::FGIMG_HOVERED, ""));
|
||||
}
|
||||
|
||||
if (style_type) {
|
||||
theme_by_type[selector].push_back(hover_spec);
|
||||
} else {
|
||||
theme_by_name[selector].push_back(hover_spec);
|
||||
}
|
||||
out[selector].push_back(hover_spec);
|
||||
}
|
||||
if (selector_spec.hasProperty(StyleSpec::BGCOLOR_PRESSED)
|
||||
|| selector_spec.hasProperty(StyleSpec::BGIMG_PRESSED)
|
||||
|
@ -2750,15 +2742,31 @@ void GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element)
|
|||
press_spec.set(StyleSpec::FGIMG, selector_spec.get(StyleSpec::FGIMG_PRESSED, ""));
|
||||
}
|
||||
|
||||
if (style_type) {
|
||||
theme_by_type[selector].push_back(press_spec);
|
||||
} else {
|
||||
theme_by_name[selector].push_back(press_spec);
|
||||
out[selector].push_back(press_spec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element)
|
||||
{
|
||||
if (data->type != "style" && data->type != "style_type") {
|
||||
errorstream << "Invalid style element type: '" << data->type << "'" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
bool style_type = (data->type == "style_type");
|
||||
bool do_warn = m_formspec_version <= FORMSPEC_API_VERSION;
|
||||
|
||||
StyleSpecMap *map = style_type ? &theme_by_type : &theme_by_name;
|
||||
if (data->reading_theme) {
|
||||
GUISkin *skin = (GUISkin *)Environment->getSkin();
|
||||
map = &skin->getThemeRef();
|
||||
}
|
||||
parse_style_to_map(
|
||||
*map,
|
||||
element,
|
||||
do_warn ? &property_warned : nullptr
|
||||
);
|
||||
}
|
||||
|
||||
void GUIFormSpecMenu::parseSetFocus(parserData*, const std::string &element)
|
||||
|
@ -2898,8 +2906,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},
|
||||
|
@ -2948,14 +2956,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('[');
|
||||
|
@ -2968,8 +2982,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;
|
||||
}
|
||||
|
@ -5054,6 +5069,40 @@ std::wstring GUIFormSpecMenu::getLabelByID(s32 id)
|
|||
return L"";
|
||||
}
|
||||
|
||||
|
||||
void GUIFormSpecMenu::setThemeFromSettings()
|
||||
{
|
||||
GUISkin *skin = (GUISkin *)Environment->getSkin();
|
||||
skin->getThemeRef().clear();
|
||||
skin->setTextureSource(m_tsrc);
|
||||
|
||||
const std::string settingspath = g_settings->get("texture_path") + DIR_DELIM + "texture_pack.conf";
|
||||
Settings settings;
|
||||
if (!settings.readConfigFile(settingspath.c_str()))
|
||||
return;
|
||||
if (!settings.exists("formspec_theme"))
|
||||
return;
|
||||
|
||||
settings.getU16NoEx("formspec_version_theme", m_theme_formspec_version);
|
||||
auto theme_elements = split(settings.get("formspec_theme"), ']');
|
||||
|
||||
parserData mydata;
|
||||
mydata.reading_theme = true;
|
||||
|
||||
const u16 version_backup = m_formspec_version;
|
||||
m_formspec_version = m_theme_formspec_version;
|
||||
for (const std::string &element : theme_elements)
|
||||
parseElement(&mydata, element, true);
|
||||
m_formspec_version = version_backup;
|
||||
}
|
||||
|
||||
void GUIFormSpecMenu::onTxpSettingChanged(const std::string &name, void *data)
|
||||
{
|
||||
GUIFormSpecMenu *me = (GUIFormSpecMenu *)data;
|
||||
me->setThemeFromSettings();
|
||||
me->regenerateGui(me->m_screensize_old);
|
||||
}
|
||||
|
||||
StyleSpec GUIFormSpecMenu::getDefaultStyleForElement(const std::string &type,
|
||||
const std::string &name, const std::string &parent_type) {
|
||||
return getStyleForElement(type, name, parent_type)[StyleSpec::STATE_DEFAULT];
|
||||
|
|
|
@ -302,10 +302,14 @@ protected:
|
|||
bool precheckElement(const std::string &name, const std::string &element,
|
||||
size_t args_min, size_t args_max, std::vector<std::string> &parts);
|
||||
|
||||
std::unordered_map<std::string, std::vector<StyleSpec>> theme_by_type;
|
||||
std::unordered_map<std::string, std::vector<StyleSpec>> theme_by_name;
|
||||
StyleSpecMap theme_by_type, theme_by_name;
|
||||
std::unordered_set<std::string> property_warned;
|
||||
|
||||
// Texturepack-definied formspec theming support
|
||||
u16 m_theme_formspec_version;
|
||||
void setThemeFromSettings();
|
||||
static void onTxpSettingChanged(const std::string &name, void *data);
|
||||
|
||||
StyleSpec getDefaultStyleForElement(const std::string &type,
|
||||
const std::string &name="", const std::string &parent_type="");
|
||||
std::array<StyleSpec, StyleSpec::NUM_STATES> getStyleForElement(const std::string &type,
|
||||
|
@ -387,8 +391,9 @@ private:
|
|||
bool m_show_debug = false;
|
||||
|
||||
struct parserData {
|
||||
bool explicit_size;
|
||||
bool real_coordinates;
|
||||
bool explicit_size = false;
|
||||
bool real_coordinates = false;
|
||||
bool reading_theme = false;
|
||||
u8 simple_field_count;
|
||||
v2f invsize;
|
||||
v2s32 size;
|
||||
|
@ -419,7 +424,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;
|
||||
|
@ -433,7 +440,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);
|
||||
|
@ -483,6 +490,8 @@ private:
|
|||
void parseAnchor(parserData *data, const std::string &element);
|
||||
bool parsePaddingDirect(parserData *data, const std::string &element);
|
||||
void parsePadding(parserData *data, const std::string &element);
|
||||
static void parse_style_to_map(StyleSpecMap &out, const std::string &element,
|
||||
std::unordered_set<std::string> *prop_warned);
|
||||
void parseStyle(parserData *data, const std::string &element);
|
||||
void parseSetFocus(parserData *, const std::string &element);
|
||||
void parseModel(parserData *data, const std::string &element);
|
||||
|
|
76
src/gui/guiSkin.cpp
Normal file
76
src/gui/guiSkin.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
// Luanti
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
// Copyright (C) 2025 Krock/SmallJoker <mk939@ymail.com>
|
||||
|
||||
#include "guiSkin.h"
|
||||
#include "client/guiscalingfilter.h"
|
||||
|
||||
|
||||
GUISkin::GUISkin(video::IVideoDriver *driver) : gui::CGUISkin(driver)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
GUISkin::~GUISkin()
|
||||
{
|
||||
}
|
||||
|
||||
void GUISkin::drawColored3DButtonPanePressed(gui::IGUIElement *element,
|
||||
const core::rect<s32> &rect,
|
||||
const core::rect<s32> *clip,
|
||||
const video::SColor *colors)
|
||||
{
|
||||
if (!Driver)
|
||||
return;
|
||||
|
||||
if (tryDrawPane("_skin_button", StyleSpec::STATE_PRESSED, rect, clip))
|
||||
return;
|
||||
|
||||
gui::CGUISkin::drawColored3DButtonPanePressed(element, rect, clip, colors);
|
||||
}
|
||||
|
||||
void GUISkin::drawColored3DButtonPaneStandard(gui::IGUIElement *element,
|
||||
const core::rect<s32> &rect,
|
||||
const core::rect<s32> *clip,
|
||||
const video::SColor *colors)
|
||||
{
|
||||
if (!Driver)
|
||||
return;
|
||||
|
||||
if (tryDrawPane("_skin_button", StyleSpec::STATE_DEFAULT, rect, clip))
|
||||
return;
|
||||
|
||||
gui::CGUISkin::drawColored3DButtonPaneStandard(element, rect, clip, colors);
|
||||
}
|
||||
|
||||
bool GUISkin::tryDrawPane(const char *type, StyleSpec::State state,
|
||||
const core::rect<s32> &rect,
|
||||
const core::rect<s32> *clip)
|
||||
{
|
||||
auto it = m_theme.find(type);
|
||||
if (it == m_theme.end())
|
||||
return false;
|
||||
|
||||
video::SColor c = 0xFFFFFFFF;
|
||||
video::SColor image_colors[] = { c, c, c, c };
|
||||
|
||||
// Similar to GUIFormSpecMenu::getStyleForElement
|
||||
StyleSpec::StateMap states;
|
||||
for (const StyleSpec &spec : it->second)
|
||||
states[(u32)spec.getState()] |= spec;
|
||||
|
||||
StyleSpec style = StyleSpec::getStyleFromStatePropagation(states, state);
|
||||
video::ITexture *texture = style.getTexture(StyleSpec::BGIMG, m_texture_source);
|
||||
core::recti source_rect = core::rect<s32>(core::position2di(0,0), texture->getOriginalSize());
|
||||
|
||||
core::recti bg_middle = style.getRect(StyleSpec::BGIMG_MIDDLE, core::recti());
|
||||
if (bg_middle.getArea() == 0) {
|
||||
Driver->draw2DImage(texture, rect, source_rect, clip, image_colors, true);
|
||||
} else {
|
||||
draw2DImage9Slice(Driver, texture, rect, source_rect, bg_middle, clip, image_colors);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
37
src/gui/guiSkin.h
Normal file
37
src/gui/guiSkin.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Luanti
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
// Copyright (C) 2025 Krock/SmallJoker <mk939@ymail.com>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "StyleSpec.h" // StyleSpecMap
|
||||
#include "../../irr/src/CGUISkin.h"
|
||||
|
||||
class GUISkin : public gui::CGUISkin {
|
||||
public:
|
||||
GUISkin(video::IVideoDriver *driver);
|
||||
virtual ~GUISkin();
|
||||
|
||||
void setTextureSource(ISimpleTextureSource *src) { m_texture_source = src; }
|
||||
|
||||
virtual void drawColored3DButtonPaneStandard(gui::IGUIElement *element,
|
||||
const core::rect<s32> &rect,
|
||||
const core::rect<s32> *clip = 0,
|
||||
const video::SColor *colors = 0) override;
|
||||
|
||||
virtual void drawColored3DButtonPanePressed(gui::IGUIElement *element,
|
||||
const core::rect<s32> &rect,
|
||||
const core::rect<s32> *clip = 0,
|
||||
const video::SColor *colors = 0) override;
|
||||
|
||||
StyleSpecMap &getThemeRef() { return m_theme; }
|
||||
|
||||
private:
|
||||
bool tryDrawPane(const char *type, StyleSpec::State state,
|
||||
const core::rect<s32> &rect,
|
||||
const core::rect<s32> *clip = 0);
|
||||
|
||||
ISimpleTextureSource *m_texture_source = nullptr;
|
||||
StyleSpecMap m_theme;
|
||||
};
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue