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

Introduce skin styles (currently discards colors)

This commit is contained in:
SmallJoker 2025-06-05 20:35:27 +02:00
parent bc981a2e29
commit bd0d9a7f95
9 changed files with 149 additions and 18 deletions

View file

@ -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;

View file

@ -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];

View file

@ -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();

View file

@ -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

View file

@ -62,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;

View file

@ -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) { \
@ -2756,8 +2757,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;
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(
style_type ? theme_by_type : theme_by_name,
*map,
element,
do_warn ? &property_warned : nullptr
);
@ -3248,16 +3254,6 @@ 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
@ -5050,7 +5046,9 @@ std::wstring GUIFormSpecMenu::getLabelByID(s32 id)
void GUIFormSpecMenu::setThemeFromSettings()
{
m_theme_elements.clear();
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;
@ -5060,7 +5058,16 @@ void GUIFormSpecMenu::setThemeFromSettings()
return;
settings.getU16NoEx("formspec_version_theme", m_theme_formspec_version);
m_theme_elements = split(settings.get("formspec_theme"), ']');
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)

View file

@ -306,7 +306,6 @@ protected:
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);
@ -392,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;

76
src/gui/guiSkin.cpp Normal file
View 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
View 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;
};