forked from Mirrorlandia_minetest/minetest
Formspec: allow lists to change size and existence while the formspec is open (#9700)
Fixes #9640.
This commit is contained in:
parent
241bf44260
commit
4fb6b6afa7
@ -493,34 +493,6 @@ void GUIFormSpecMenu::parseList(parserData *data, const std::string &element)
|
|||||||
return;
|
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)
|
if (!data->explicit_size)
|
||||||
warningstream << "invalid use of list without a size[] element" << std::endl;
|
warningstream << "invalid use of list without a size[] element" << std::endl;
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@ GUIInventoryList::GUIInventoryList(gui::IGUIEnvironment *env,
|
|||||||
m_fs_menu(fs_menu),
|
m_fs_menu(fs_menu),
|
||||||
m_options(options),
|
m_options(options),
|
||||||
m_font(font),
|
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);
|
Inventory *inv = m_invmgr->getInventory(m_inventoryloc);
|
||||||
if (!inv) {
|
if (!inv) {
|
||||||
|
if (!m_already_warned) {
|
||||||
warningstream << "GUIInventoryList::draw(): "
|
warningstream << "GUIInventoryList::draw(): "
|
||||||
<< "The inventory location "
|
<< "The inventory location "
|
||||||
<< "\"" << m_inventoryloc.dump() << "\" doesn't exist anymore"
|
<< "\"" << m_inventoryloc.dump() << "\" doesn't exist"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
m_already_warned = true;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
InventoryList *ilist = inv->getList(m_listname);
|
InventoryList *ilist = inv->getList(m_listname);
|
||||||
if (!ilist) {
|
if (!ilist) {
|
||||||
|
if (!m_already_warned) {
|
||||||
warningstream << "GUIInventoryList::draw(): "
|
warningstream << "GUIInventoryList::draw(): "
|
||||||
<< "The inventory list \"" << m_listname << "\" @ \""
|
<< "The inventory list \"" << m_listname << "\" @ \""
|
||||||
<< m_inventoryloc.dump() << "\" doesn't exist anymore"
|
<< m_inventoryloc.dump() << "\" doesn't exist"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
m_already_warned = true;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
m_already_warned = false;
|
||||||
|
|
||||||
video::IVideoDriver *driver = Environment->getVideoDriver();
|
video::IVideoDriver *driver = Environment->getVideoDriver();
|
||||||
Client *client = m_fs_menu->getClient();
|
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);
|
core::rect<s32> imgrect(0, 0, m_slot_size.X, m_slot_size.Y);
|
||||||
v2s32 base_pos = AbsoluteRect.UpperLeftCorner;
|
v2s32 base_pos = AbsoluteRect.UpperLeftCorner;
|
||||||
|
|
||||||
|
const s32 list_size = (s32)ilist->getSize();
|
||||||
|
|
||||||
for (s32 i = 0; i < m_geom.X * m_geom.Y; i++) {
|
for (s32 i = 0; i < m_geom.X * m_geom.Y; i++) {
|
||||||
s32 item_i = i + m_start_item_i;
|
s32 item_i = i + m_start_item_i;
|
||||||
if (item_i >= (s32)ilist->getSize())
|
if (item_i >= list_size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
v2s32 p((i % m_geom.X) * m_slot_spacing.X,
|
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
|
s32 GUIInventoryList::getItemIndexAtPos(v2s32 p) const
|
||||||
{
|
{
|
||||||
|
// no item if no gui element at pointer
|
||||||
if (!IsVisible || AbsoluteClippingRect.getArea() <= 0 ||
|
if (!IsVisible || AbsoluteClippingRect.getArea() <= 0 ||
|
||||||
!AbsoluteClippingRect.isPointInside(p))
|
!AbsoluteClippingRect.isPointInside(p))
|
||||||
return -1;
|
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);
|
core::rect<s32> imgrect(0, 0, m_slot_size.X, m_slot_size.Y);
|
||||||
v2s32 base_pos = AbsoluteRect.UpperLeftCorner;
|
v2s32 base_pos = AbsoluteRect.UpperLeftCorner;
|
||||||
|
|
||||||
@ -210,7 +229,8 @@ s32 GUIInventoryList::getItemIndexAtPos(v2s32 p) const
|
|||||||
|
|
||||||
rect.clipAgainst(AbsoluteClippingRect);
|
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 i + m_start_item_i;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -107,7 +107,7 @@ private:
|
|||||||
const InventoryLocation m_inventoryloc;
|
const InventoryLocation m_inventoryloc;
|
||||||
const std::string m_listname;
|
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;
|
const v2s32 m_geom;
|
||||||
// the first item's index in inventory
|
// the first item's index in inventory
|
||||||
const s32 m_start_item_i;
|
const s32 m_start_item_i;
|
||||||
@ -127,4 +127,7 @@ private:
|
|||||||
|
|
||||||
// the index of the hovered item; -1 if no item is hovered
|
// the index of the hovered item; -1 if no item is hovered
|
||||||
s32 m_hovered_i;
|
s32 m_hovered_i;
|
||||||
|
|
||||||
|
// we do not want to write a warning on every draw
|
||||||
|
bool m_already_warned;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user