aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDS <vorunbekannt75@web.de>2020-04-18 17:21:10 +0200
committerGitHub <noreply@github.com>2020-04-18 17:21:10 +0200
commit4fb6b6afa7329676166bbbccb897bd625155d038 (patch)
treeca6437170e246525c6273079a9757c9e3e896692 /src
parent241bf442608d27df0ce3c74889c357fb5589ab20 (diff)
downloadminetest-4fb6b6afa7329676166bbbccb897bd625155d038.tar.gz
minetest-4fb6b6afa7329676166bbbccb897bd625155d038.tar.bz2
minetest-4fb6b6afa7329676166bbbccb897bd625155d038.zip
Formspec: allow lists to change size and existence while the formspec is open (#9700)
Fixes #9640.
Diffstat (limited to 'src')
-rw-r--r--src/gui/guiFormSpecMenu.cpp30
-rw-r--r--src/gui/guiInventoryList.cpp42
-rw-r--r--src/gui/guiInventoryList.h5
3 files changed, 36 insertions, 41 deletions
diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp
index b0255cf1b..85ab2eb50 100644
--- a/src/gui/guiFormSpecMenu.cpp
+++ b/src/gui/guiFormSpecMenu.cpp
@@ -489,38 +489,10 @@ void GUIFormSpecMenu::parseList(parserData *data, const std::string &element)
start_i = stoi(startindex);
if (geom.X < 0 || geom.Y < 0 || start_i < 0) {
- errorstream<< "Invalid list element: '" << element << "'" << std::endl;
+ errorstream << "Invalid list element: '" << element << "'" << std::endl;
return;
}
- // check for the existence of inventory and list
- Inventory *inv = m_invmgr->getInventory(loc);
- if (!inv) {
- warningstream << "GUIFormSpecMenu::parseList(): "
- << "The inventory location "
- << "\"" << loc.dump() << "\" doesn't exist"
- << std::endl;
- return;
- }
- InventoryList *ilist = inv->getList(listname);
- if (!ilist) {
- warningstream << "GUIFormSpecMenu::parseList(): "
- << "The inventory list \"" << listname << "\" "
- << "@ \"" << loc.dump() << "\" doesn't exist"
- << std::endl;
- return;
- }
-
- // trim geom if it is larger than the actual inventory size
- s32 list_size = (s32)ilist->getSize();
- if (list_size < geom.X * geom.Y + start_i) {
- list_size -= MYMAX(start_i, 0);
- geom.Y = list_size / geom.X;
- geom.Y += list_size % geom.X > 0 ? 1 : 0;
- if (geom.Y <= 1)
- geom.X = list_size;
- }
-
if (!data->explicit_size)
warningstream << "invalid use of list without a size[] element" << std::endl;
diff --git a/src/gui/guiInventoryList.cpp b/src/gui/guiInventoryList.cpp
index 536471229..dfdb60448 100644
--- a/src/gui/guiInventoryList.cpp
+++ b/src/gui/guiInventoryList.cpp
@@ -47,7 +47,8 @@ GUIInventoryList::GUIInventoryList(gui::IGUIEnvironment *env,
m_fs_menu(fs_menu),
m_options(options),
m_font(font),
- m_hovered_i(-1)
+ m_hovered_i(-1),
+ m_already_warned(false)
{
}
@@ -58,20 +59,27 @@ void GUIInventoryList::draw()
Inventory *inv = m_invmgr->getInventory(m_inventoryloc);
if (!inv) {
- warningstream << "GUIInventoryList::draw(): "
- << "The inventory location "
- << "\"" << m_inventoryloc.dump() << "\" doesn't exist anymore"
- << std::endl;
+ if (!m_already_warned) {
+ warningstream << "GUIInventoryList::draw(): "
+ << "The inventory location "
+ << "\"" << m_inventoryloc.dump() << "\" doesn't exist"
+ << std::endl;
+ m_already_warned = true;
+ }
return;
}
InventoryList *ilist = inv->getList(m_listname);
if (!ilist) {
- warningstream << "GUIInventoryList::draw(): "
- << "The inventory list \"" << m_listname << "\" @ \""
- << m_inventoryloc.dump() << "\" doesn't exist anymore"
- << std::endl;
+ if (!m_already_warned) {
+ warningstream << "GUIInventoryList::draw(): "
+ << "The inventory list \"" << m_listname << "\" @ \""
+ << m_inventoryloc.dump() << "\" doesn't exist"
+ << std::endl;
+ m_already_warned = true;
+ }
return;
}
+ m_already_warned = false;
video::IVideoDriver *driver = Environment->getVideoDriver();
Client *client = m_fs_menu->getClient();
@@ -80,9 +88,11 @@ void GUIInventoryList::draw()
core::rect<s32> imgrect(0, 0, m_slot_size.X, m_slot_size.Y);
v2s32 base_pos = AbsoluteRect.UpperLeftCorner;
+ const s32 list_size = (s32)ilist->getSize();
+
for (s32 i = 0; i < m_geom.X * m_geom.Y; i++) {
s32 item_i = i + m_start_item_i;
- if (item_i >= (s32)ilist->getSize())
+ if (item_i >= list_size)
break;
v2s32 p((i % m_geom.X) * m_slot_spacing.X,
@@ -192,10 +202,19 @@ bool GUIInventoryList::OnEvent(const SEvent &event)
s32 GUIInventoryList::getItemIndexAtPos(v2s32 p) const
{
+ // no item if no gui element at pointer
if (!IsVisible || AbsoluteClippingRect.getArea() <= 0 ||
!AbsoluteClippingRect.isPointInside(p))
return -1;
+ // there can not be an item if the inventory or the inventorylist does not exist
+ Inventory *inv = m_invmgr->getInventory(m_inventoryloc);
+ if (!inv)
+ return -1;
+ InventoryList *ilist = inv->getList(m_listname);
+ if (!ilist)
+ return -1;
+
core::rect<s32> imgrect(0, 0, m_slot_size.X, m_slot_size.Y);
v2s32 base_pos = AbsoluteRect.UpperLeftCorner;
@@ -210,7 +229,8 @@ s32 GUIInventoryList::getItemIndexAtPos(v2s32 p) const
rect.clipAgainst(AbsoluteClippingRect);
- if (rect.getArea() > 0 && rect.isPointInside(p))
+ if (rect.getArea() > 0 && rect.isPointInside(p) &&
+ i + m_start_item_i < (s32)ilist->getSize())
return i + m_start_item_i;
return -1;
diff --git a/src/gui/guiInventoryList.h b/src/gui/guiInventoryList.h
index fd2c3601b..28e95fbbf 100644
--- a/src/gui/guiInventoryList.h
+++ b/src/gui/guiInventoryList.h
@@ -107,7 +107,7 @@ private:
const InventoryLocation m_inventoryloc;
const std::string m_listname;
- // specifies the width and height of the inventorylist in itemslots
+ // the specified width and height of the shown inventorylist in itemslots
const v2s32 m_geom;
// the first item's index in inventory
const s32 m_start_item_i;
@@ -127,4 +127,7 @@ private:
// the index of the hovered item; -1 if no item is hovered
s32 m_hovered_i;
+
+ // we do not want to write a warning on every draw
+ bool m_already_warned;
};