From 1558a2df5425eb658d19c85fa50de833b641b1e4 Mon Sep 17 00:00:00 2001 From: luk3yx Date: Thu, 11 May 2023 21:15:33 +1200 Subject: [PATCH] Add list[] bgimg --- doc/lua_api.txt | 3 ++ src/gui/guiFormSpecMenu.cpp | 8 +++- src/gui/guiInventoryList.cpp | 79 ++++++++++++++++++++++++------------ src/gui/guiInventoryList.h | 8 ++++ 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 4f42b6ae1..c67c7562a 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2911,6 +2911,9 @@ Some types may inherit styles from parent types. * noclip - boolean, set to true to allow the element to exceed formspec bounds. * size - 2d vector, sets the size of inventory slots in coordinates. * spacing - 2d vector, sets the space between inventory slots in coordinates. + * bgimg - slot background image. Defaults to none. + * bgimg_hovered - hovered slot background image. + * bgimg_middle - Makes the bgimg textures render in 9-sliced mode and defines the middle rect. * image_button (additional properties) * fgimg - standard image. Defaults to none. * fgimg_hovered - image when hovered. Defaults to fgimg when not provided. diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 04b7c62d8..88eccbbb8 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -538,10 +538,14 @@ void GUIFormSpecMenu::parseList(parserData *data, const std::string &element) pos.X + (geom.X - 1) * slot_spacing.X + slot_size.X, pos.Y + (geom.Y - 1) * slot_spacing.Y + slot_size.Y); + video::ITexture *bgimg = style.getTexture(StyleSpec::BGIMG, m_tsrc, nullptr); + video::ITexture *bgimg_hovered = style.getTexture(StyleSpec::BGIMG_HOVERED, m_tsrc, nullptr); + core::rect bgimg_middle = style.getRect(StyleSpec::BGIMG_MIDDLE, core::rect()); + GUIInventoryList *e = new GUIInventoryList(Environment, data->current_parent, spec.fid, rect, m_invmgr, loc, listname, geom, start_i, - v2s32(slot_size.X, slot_size.Y), slot_spacing, this, - data->inventorylist_options, m_font); + v2s32(slot_size.X, slot_size.Y), slot_spacing, bgimg, bgimg_hovered, + bgimg_middle, this, data->inventorylist_options, m_font); e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); diff --git a/src/gui/guiInventoryList.cpp b/src/gui/guiInventoryList.cpp index 4b10b7cd4..fb59ce76a 100644 --- a/src/gui/guiInventoryList.cpp +++ b/src/gui/guiInventoryList.cpp @@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "guiInventoryList.h" #include "guiFormSpecMenu.h" +#include "client/guiscalingfilter.h" #include "client/hud.h" #include "client/client.h" @@ -33,6 +34,9 @@ GUIInventoryList::GUIInventoryList(gui::IGUIEnvironment *env, const s32 start_item_i, const v2s32 &slot_size, const v2f32 &slot_spacing, + video::ITexture* slotbg_n_texture, + video::ITexture* slotbg_h_texture, + const core::rect &slotbg_middle, GUIFormSpecMenu *fs_menu, const Options &options, gui::IGUIFont *font) : @@ -44,6 +48,9 @@ GUIInventoryList::GUIInventoryList(gui::IGUIEnvironment *env, m_start_item_i(start_item_i), m_slot_size(slot_size), m_slot_spacing(slot_spacing), + m_slotbg_n_texture(slotbg_n_texture), + m_slotbg_h_texture(slotbg_h_texture), + m_slotbg_middle(slotbg_middle), m_fs_menu(fs_menu), m_options(options), m_font(font), @@ -109,34 +116,52 @@ void GUIInventoryList::draw() (hovering ? IT_ROT_HOVERED : IT_ROT_NONE); // layer 0 - if (hovering) { - driver->draw2DRectangle(m_options.slotbg_h, rect, &AbsoluteClippingRect); - } else { - driver->draw2DRectangle(m_options.slotbg_n, rect, &AbsoluteClippingRect); - } + if (m_slotbg_n_texture) { + video::ITexture *texture = m_slotbg_n_texture; + if (hovering && m_slotbg_h_texture) + texture = m_slotbg_h_texture; - // Draw inv slot borders - if (m_options.slotborder) { - s32 x1 = rect.UpperLeftCorner.X; - s32 y1 = rect.UpperLeftCorner.Y; - s32 x2 = rect.LowerRightCorner.X; - s32 y2 = rect.LowerRightCorner.Y; - s32 border = 1; - core::rect clipping_rect = Parent ? Parent->getAbsoluteClippingRect() - : core::rect(); - core::rect *clipping_rect_ptr = Parent ? &clipping_rect : nullptr; - driver->draw2DRectangle(m_options.slotbordercolor, - core::rect(v2s32(x1 - border, y1 - border), - v2s32(x2 + border, y1)), clipping_rect_ptr); - driver->draw2DRectangle(m_options.slotbordercolor, - core::rect(v2s32(x1 - border, y2), - v2s32(x2 + border, y2 + border)), clipping_rect_ptr); - driver->draw2DRectangle(m_options.slotbordercolor, - core::rect(v2s32(x1 - border, y1), - v2s32(x1, y2)), clipping_rect_ptr); - driver->draw2DRectangle(m_options.slotbordercolor, - core::rect(v2s32(x2, y1), - v2s32(x2 + border, y2)), clipping_rect_ptr); + core::rect srcrect(core::position2d(0, 0), + core::dimension2di(texture->getOriginalSize())); + if (m_slotbg_middle.getArea() == 0) { + const video::SColor color(255, 255, 255, 255); + const video::SColor colors[] = {color, color, color, color}; + draw2DImageFilterScaled(driver, texture, rect, srcrect, + &AbsoluteClippingRect, colors, true); + } else { + draw2DImage9Slice(driver, texture, rect, srcrect, m_slotbg_middle, + &AbsoluteClippingRect); + } + } else { + if (hovering) { + driver->draw2DRectangle(m_options.slotbg_h, rect, &AbsoluteClippingRect); + } else { + driver->draw2DRectangle(m_options.slotbg_n, rect, &AbsoluteClippingRect); + } + + // Draw inv slot borders + if (m_options.slotborder) { + s32 x1 = rect.UpperLeftCorner.X; + s32 y1 = rect.UpperLeftCorner.Y; + s32 x2 = rect.LowerRightCorner.X; + s32 y2 = rect.LowerRightCorner.Y; + s32 border = 1; + core::rect clipping_rect = Parent ? Parent->getAbsoluteClippingRect() + : core::rect(); + core::rect *clipping_rect_ptr = Parent ? &clipping_rect : nullptr; + driver->draw2DRectangle(m_options.slotbordercolor, + core::rect(v2s32(x1 - border, y1 - border), + v2s32(x2 + border, y1)), clipping_rect_ptr); + driver->draw2DRectangle(m_options.slotbordercolor, + core::rect(v2s32(x1 - border, y2), + v2s32(x2 + border, y2 + border)), clipping_rect_ptr); + driver->draw2DRectangle(m_options.slotbordercolor, + core::rect(v2s32(x1 - border, y1), + v2s32(x1, y2)), clipping_rect_ptr); + driver->draw2DRectangle(m_options.slotbordercolor, + core::rect(v2s32(x2, y1), + v2s32(x2 + border, y2)), clipping_rect_ptr); + } } // layer 1 diff --git a/src/gui/guiInventoryList.h b/src/gui/guiInventoryList.h index 9d4f3ef51..712c6905c 100644 --- a/src/gui/guiInventoryList.h +++ b/src/gui/guiInventoryList.h @@ -69,6 +69,9 @@ public: const s32 start_item_i, const v2s32 &slot_size, const v2f32 &slot_spacing, + video::ITexture* slotbg_n_texture, + video::ITexture* slotbg_h_texture, + const core::rect &slotbg_middle, GUIFormSpecMenu *fs_menu, const Options &options, gui::IGUIFont *font); @@ -117,6 +120,11 @@ private: // specifies how large the space between slots is (space between is spacing-size) const v2f32 m_slot_spacing; + // Slot textures + video::ITexture* m_slotbg_n_texture; + video::ITexture* m_slotbg_h_texture; + core::rect m_slotbg_middle; + // the GUIFormSpecMenu can have an item selected and co. GUIFormSpecMenu *m_fs_menu;