diff --git a/games/devtest/mods/testformspec/formspec.lua b/games/devtest/mods/testformspec/formspec.lua index c0db695b7..9f867631f 100644 --- a/games/devtest/mods/testformspec/formspec.lua +++ b/games/devtest/mods/testformspec/formspec.lua @@ -430,6 +430,33 @@ mouse control = true] checkbox[0.5,5.5.5;snd_chk;Sound;] tabheader[0.5,7;8,0.65;snd_tab;Soundtab1,Soundtab2,Soundtab3;1;false;false] ]], + + -- Background + [[ + formspec_version[3] + size[12,13] + box[0,0;12,13;#f0f1] + background[0,0;0,0;testformspec_bg.png;true] + box[3.9,2.9;6.2,4.2;#d00f] + scroll_container[4,3;6,4;scrbar;vertical] + background9[1,0.5;0,0;testformspec_bg_9slice.png;true;4,6] + label[0,0.2;Backgrounds are not be applied to scroll containers,] + label[0,0.5;but to the whole form.] + scroll_container_end[] + scrollbar[3.5,3;0.3,4;vertical;scrbar;0] + container[2,11] + box[-0.1,0.5;3.2,1;#fff5] + background[0,0;2,3;testformspec_bg.png;false] + background9[1,0;2,3;testformspec_bg_9slice.png;false;4,6] + container_end[] + ]], + + -- Unsized + [[ + formspec_version[3] + background9[0,0;0,0;testformspec_bg_9slice.png;true;4,6] + background[1,1;0,0;testformspec_bg.png;true] + ]], } local page_id = 2 @@ -439,7 +466,7 @@ local function show_test_formspec(pname) page = page() end - local fs = page .. "tabheader[0,0;8,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Invs,Window,Anim,Model,ScrollC,Sound;" .. page_id .. ";false;false]" + local fs = page .. "tabheader[0,0;11,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Invs,Window,Anim,Model,ScrollC,Sound,Background,Unsized;" .. page_id .. ";false;false]" minetest.show_formspec(pname, "testformspec:formspec", fs) end diff --git a/src/gui/guiBackgroundImage.cpp b/src/gui/guiBackgroundImage.cpp index 21c1e88cf..85e870771 100644 --- a/src/gui/guiBackgroundImage.cpp +++ b/src/gui/guiBackgroundImage.cpp @@ -44,7 +44,7 @@ void GUIBackgroundImage::draw() core::rect rect = AbsoluteRect; if (m_autoclip) - rect.LowerRightCorner += Parent->getAbsolutePosition().getSize(); + rect.LowerRightCorner += Parent->getAbsoluteClippingRect().getSize(); video::IVideoDriver *driver = Environment->getVideoDriver(); diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 85bd04900..f3570ccaf 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -137,8 +137,6 @@ GUIFormSpecMenu::~GUIFormSpecMenu() checkbox_it.second->drop(); for (auto &scrollbar_it : m_scrollbars) scrollbar_it.second->drop(); - for (auto &background_it : m_backgrounds) - background_it->drop(); for (auto &tooltip_rect_it : m_tooltip_rects) tooltip_rect_it.first->drop(); for (auto &clickthrough_it : m_clickthrough_elements) @@ -1124,17 +1122,15 @@ void GUIFormSpecMenu::parseBackground(parserData* data, const std::string &eleme rect = core::rect(-pos, pos); } - GUIBackgroundImage *e = new GUIBackgroundImage(Environment, this, spec.fid, - rect, name, middle, m_tsrc, clip); + GUIBackgroundImage *e = new GUIBackgroundImage(Environment, data->background_parent.get(), + spec.fid, rect, name, middle, m_tsrc, clip); FATAL_ERROR_IF(!e, "Failed to create background formspec element"); e->setNotClipped(true); - e->setVisible(false); // the element is drawn manually before all others - - m_backgrounds.push_back(e); m_fields.push_back(spec); + e->drop(); } void GUIFormSpecMenu::parseTableOptions(parserData* data, const std::string &element) @@ -3059,8 +3055,6 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) checkbox_it.second->drop(); for (auto &scrollbar_it : m_scrollbars) scrollbar_it.second->drop(); - for (auto &background_it : m_backgrounds) - background_it->drop(); for (auto &tooltip_rect_it : m_tooltip_rects) tooltip_rect_it.first->drop(); for (auto &clickthrough_it : m_clickthrough_elements) @@ -3082,7 +3076,6 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) mydata.current_parent = this; m_inventorylists.clear(); - m_backgrounds.clear(); m_tables.clear(); m_checkboxes.clear(); m_scrollbars.clear(); @@ -3336,6 +3329,15 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) gui::IGUIFont *old_font = skin->getFont(); skin->setFont(m_font); + // Add a new element that will hold all the background elements as its children. + // Because it is the first added element, all backgrounds will be behind all + // the other elements. + // (We use an arbitrarily big rect. The actual size is determined later by + // clipping to `this`.) + core::rect background_parent_rect(0, 0, 100000, 100000); + mydata.background_parent.reset(new gui::IGUIElement(EGUIET_ELEMENT, Environment, + this, -1, background_parent_rect)); + pos_offset = v2f32(); // used for formspec versions < 3 @@ -3591,15 +3593,6 @@ void GUIFormSpecMenu::drawMenu() } } - /* - Draw backgrounds - */ - for (gui::IGUIElement *e : m_backgrounds) { - e->setVisible(true); - e->draw(); - e->setVisible(false); - } - // Some elements are only visible while being drawn for (gui::IGUIElement *e : m_clickthrough_elements) e->setVisible(true); diff --git a/src/gui/guiFormSpecMenu.h b/src/gui/guiFormSpecMenu.h index 0b4d3879d..3fedb3b78 100644 --- a/src/gui/guiFormSpecMenu.h +++ b/src/gui/guiFormSpecMenu.h @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "irrlichttypes_extrabloated.h" +#include "irr_ptr.h" #include "inventorymanager.h" #include "modalMenu.h" #include "guiInventoryList.h" @@ -313,7 +314,6 @@ protected: std::vector m_inventorylists; std::vector m_inventory_rings; - std::vector m_backgrounds; std::unordered_map field_close_on_enter; std::unordered_map m_dropdown_index_event; std::vector m_fields; @@ -375,6 +375,7 @@ private: GUITable::TableOptions table_options; GUITable::TableColumns table_columns; gui::IGUIElement *current_parent = nullptr; + irr_ptr background_parent; GUIInventoryList::Options inventorylist_options;