Skip to content

Commit 60544ac

Browse files
Hugues Rossrubenwardy
Hugues Ross
authored andcommittedJan 26, 2020
Add 9-slice background support to button formspec elements (#9290)
1 parent cde2a7f commit 60544ac

File tree

9 files changed

+86
-4
lines changed

9 files changed

+86
-4
lines changed
 

Diff for: ‎doc/lua_api.txt

+2
Original file line numberDiff line numberDiff line change
@@ -2573,6 +2573,8 @@ Some types may inherit styles from parent types.
25732573
* bgcolor_pressed - color when pressed. Defaults to a darker bgcolor when not provided.
25742574
* bgimg - standard background image. Defaults to none.
25752575
* bgimg_hovered - background image when hovered. Defaults to bgimg when not provided.
2576+
* bgimg_middle - Makes the bgimg textures render in 9-sliced mode and defines the middle rect.
2577+
See background9[] documentation for more details
25762578
* bgimg_pressed - background image when pressed. Defaults to bgimg when not provided.
25772579
* border - boolean, draw border. Set to false to hide the bevelled button pane. Default true.
25782580
* noclip - boolean, set to true to allow the element to exceed formspec bounds.

Diff for: ‎games/minimal/mods/test/formspec.lua

+3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ local style_fs = [[
7878
style[one_btn15;border=false;bgimg=test_bg.png;bgimg_hovered=test_bg_hovered.png;bgimg_pressed=test_bg_pressed.png]
7979
item_image_button[1.25,9.6;1,1;default:sword_steel;one_btn15;Bg]
8080
81+
style[one_btn16;border=false;bgimg=test_bg_9slice.png;bgimg_hovered=test_bg_9slice_hovered.png;bgimg_pressed=test_bg_9slice_pressed.png;bgimg_middle=4,6]
82+
button[2.5,9.6;2,1;one_btn16;9-Slice Bg]
83+
8184
8285
8386
container[2.75,0]

Diff for: ‎games/minimal/mods/test/textures/test_bg_9slice.png

1017 Bytes
Loading
1016 Bytes
Loading
1016 Bytes
Loading

Diff for: ‎src/gui/StyleSpec.h

+58
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class StyleSpec
3737
BORDER,
3838
BGIMG,
3939
BGIMG_HOVERED,
40+
BGIMG_MIDDLE,
4041
BGIMG_PRESSED,
4142
FGIMG,
4243
FGIMG_HOVERED,
@@ -69,6 +70,8 @@ class StyleSpec
6970
return BGIMG;
7071
} else if (name == "bgimg_hovered") {
7172
return BGIMG_HOVERED;
73+
} else if (name == "bgimg_middle") {
74+
return BGIMG_MIDDLE;
7275
} else if (name == "bgimg_pressed") {
7376
return BGIMG_PRESSED;
7477
} else if (name == "fgimg") {
@@ -117,6 +120,29 @@ class StyleSpec
117120
return color;
118121
}
119122

123+
irr::core::rect<s32> getRect(Property prop, irr::core::rect<s32> def) const
124+
{
125+
const auto &val = properties[prop];
126+
if (val.empty())
127+
return def;
128+
129+
irr::core::rect<s32> rect;
130+
if (!parseRect(val, &rect))
131+
return def;
132+
133+
return rect;
134+
}
135+
136+
irr::core::rect<s32> getRect(Property prop) const
137+
{
138+
const auto &val = properties[prop];
139+
FATAL_ERROR_IF(val.empty(), "Unexpected missing property");
140+
141+
irr::core::rect<s32> rect;
142+
parseRect(val, &rect);
143+
return rect;
144+
}
145+
120146
video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc,
121147
video::ITexture *def) const
122148
{
@@ -175,4 +201,36 @@ class StyleSpec
175201
newspec |= other;
176202
return newspec;
177203
}
204+
205+
private:
206+
bool parseRect(const std::string &value, irr::core::rect<s32> *parsed_rect) const
207+
{
208+
irr::core::rect<s32> rect;
209+
std::vector<std::string> v_rect = split(value, ',');
210+
211+
if (v_rect.size() == 1) {
212+
s32 x = stoi(v_rect[0]);
213+
rect.UpperLeftCorner = irr::core::vector2di(x, x);
214+
rect.LowerRightCorner = irr::core::vector2di(-x, -x);
215+
} else if (v_rect.size() == 2) {
216+
s32 x = stoi(v_rect[0]);
217+
s32 y = stoi(v_rect[1]);
218+
rect.UpperLeftCorner = irr::core::vector2di(x, y);
219+
rect.LowerRightCorner = irr::core::vector2di(-x, -y);
220+
// `-x` is interpreted as `w - x`
221+
} else if (v_rect.size() == 4) {
222+
rect.UpperLeftCorner = irr::core::vector2di(
223+
stoi(v_rect[0]), stoi(v_rect[1]));
224+
rect.LowerRightCorner = irr::core::vector2di(
225+
stoi(v_rect[2]), stoi(v_rect[3]));
226+
} else {
227+
warningstream << "Invalid rectangle string format: \"" << value
228+
<< "\"" << std::endl;
229+
return false;
230+
}
231+
232+
*parsed_rect = rect;
233+
234+
return true;
235+
}
178236
};

Diff for: ‎src/gui/guiButton.cpp

+20-4
Original file line numberDiff line numberDiff line change
@@ -307,10 +307,25 @@ void GUIButton::draw()
307307
}
308308
}
309309

310-
driver->draw2DImage(ButtonImages[(u32)imageState].Texture,
311-
ScaleImage? AbsoluteRect : core::rect<s32>(pos, sourceRect.getSize()),
312-
sourceRect, &AbsoluteClippingRect,
313-
0, UseAlphaChannel);
310+
// PATCH
311+
video::ITexture* texture = ButtonImages[(u32)imageState].Texture;
312+
if (BgMiddle.getArea() == 0) {
313+
driver->draw2DImage(texture,
314+
ScaleImage? AbsoluteRect : core::rect<s32>(pos, sourceRect.getSize()),
315+
sourceRect, &AbsoluteClippingRect,
316+
0, UseAlphaChannel);
317+
} else {
318+
core::rect<s32> middle = BgMiddle;
319+
// `-x` is interpreted as `w - x`
320+
if (middle.LowerRightCorner.X < 0)
321+
middle.LowerRightCorner.X += texture->getOriginalSize().Width;
322+
if (middle.LowerRightCorner.Y < 0)
323+
middle.LowerRightCorner.Y += texture->getOriginalSize().Height;
324+
draw2DImage9Slice(driver, texture,
325+
ScaleImage ? AbsoluteRect : core::rect<s32>(pos, sourceRect.getSize()),
326+
middle, &AbsoluteClippingRect);
327+
}
328+
// END PATCH
314329
}
315330

316331
if (SpriteBank)
@@ -804,5 +819,6 @@ void GUIButton::setFromStyle(const StyleSpec& style, ISimpleTextureSource *tsrc)
804819
Environment->getVideoDriver(), pressed_texture, geom.X, geom.Y));
805820
setScaleImage(true);
806821
}
822+
BgMiddle = style.getRect(StyleSpec::BGIMG_MIDDLE, BgMiddle);
807823
}
808824
// END PATCH

Diff for: ‎src/gui/guiButton.h

+2
Original file line numberDiff line numberDiff line change
@@ -330,5 +330,7 @@ class GUIButton : public gui::IGUIButton
330330
video::SColor PressedColors[4];
331331

332332
gui::IGUIStaticText *StaticText;
333+
334+
core::rect<s32> BgMiddle;
333335
// END PATCH
334336
};

Diff for: ‎util/travis/clang-format-whitelist.txt

+1
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ src/gui/mainmenumanager.h
196196
src/gui/modalMenu.h
197197
src/guiscalingfilter.cpp
198198
src/guiscalingfilter.h
199+
src/gui/StyleSpec.h
199200
src/gui/touchscreengui.cpp
200201
src/httpfetch.cpp
201202
src/hud.cpp

0 commit comments

Comments
 (0)
Please sign in to comment.