ItemBox
When trying to use ItemBox, I get this assert.
MYGUI_ASSERT(nullptr != mWidgetClient, "Child Widget Client not found in skin (ItemBox must have Client)")
What does that mean? I can't find any Client skin parts in the ItemBox demo.
I would be very nice if anyone could give an example how he uses the ItemBox in his project. Even better if the code does not use any layout files and is not based on the included ItemBox example project.
my.name
12-07-2009 23:47:29
wait ...
Illidanz
13-07-2009 13:09:25
I'm interested in this too.
In the past I've experimented with the ItemBox example project files but I ended up having an incredible mess that wasn't working as intended
A "simple sample" would be very nice!
my.name
14-07-2009 20:36:48
small example only for view
void requestCreateWidgetItem(MyGUI::ItemBoxPtr _sender, MyGUI::WidgetPtr _item)
{
MyGUI::StaticTextPtr text = _item->createWidget<MyGUI::StaticText>("StaticText", MyGUI::IntCoord(0, 0, _item->getWidth(), _item->getHeight()), MyGUI::Align::Stretch);
text->setNeedMouseFocus(false);
_item->setUserData(text);
}
void requestCoordItem(MyGUI::ItemBoxPtr _sender, MyGUI::IntCoord& _coord, bool _drag)
{
_coord.set(0, 0, 100, 100);
}
void requestDrawItem(MyGUI::ItemBoxPtr _sender, MyGUI::WidgetPtr _item, const MyGUI::IBDrawItemInfo& _info)
{
MyGUI::StaticTextPtr text = *_item->getUserData<MyGUI::StaticTextPtr>();
int data = *_sender->getItemDataAt<int>(_info.index);
text->setCaption(MyGUI::utility::toString(
"index : ", _info.index,
"\ndata : ", data,
_info.active ? "\n#00FF00focus" : "\n#800000focus",
_info.select ? "\n#00FF00select" : "\n#800000select"));
}
void init(MyGUI::Gui* _gui)
{
MyGUI::ItemBoxPtr box1 = _gui->createWidget<MyGUI::ItemBox>("ItemBoxV", MyGUI::IntCoord(10, 10, 300, 300), MyGUI::Align::Default, "Overlapped");
box1->requestCreateWidgetItem = MyGUI::newDelegate(requestCreateWidgetItem);
box1->requestCoordItem = MyGUI::newDelegate(requestCoordItem);
box1->requestDrawItem = MyGUI::newDelegate(requestDrawItem);
box1->addItem((int)101);
box1->addItem((int)43);
box1->addItem((int)54);
}
my.name
14-07-2009 21:54:43
full version 1
void requestCreateWidgetItem(MyGUI::ItemBoxPtr _sender, MyGUI::WidgetPtr _item)
{
MyGUI::StaticTextPtr text = _item->createWidget<MyGUI::StaticText>("StaticText", MyGUI::IntCoord(0, 0, _item->getWidth(), _item->getHeight()), MyGUI::Align::Stretch);
text->setNeedMouseFocus(false);
_item->setUserData(text);
}
void requestCoordItem(MyGUI::ItemBoxPtr _sender, MyGUI::IntCoord& _coord, bool _drag)
{
_coord.set(0, 0, 100, 100);
}
void requestDrawItem(MyGUI::ItemBoxPtr _sender, MyGUI::WidgetPtr _item, const MyGUI::IBDrawItemInfo& _info)
{
MyGUI::StaticTextPtr text = *_item->getUserData<MyGUI::StaticTextPtr>();
int data = *_sender->getItemDataAt<int>(_info.index);
if (_info.drag)
{
text->setCaption(MyGUI::utility::toString(
_info.drop_accept ? "#00FF00drag accept" : (_info.drop_refuse ? "#FF0000drag refuse" : "#0000FFdrag miss"),
"\n#000000data : ", data));
}
else
{
text->setCaption(MyGUI::utility::toString(
_info.drop_accept ? "#00FF00" : (_info.drop_refuse ? "#FF0000" : "#000000"), "index : ", _info.index,
"\n#000000data : ", data,
_info.active ? "\n#00FF00focus" : "\n#800000focus",
_info.select ? "\n#00FF00select" : "\n#800000select"));
}
}
void eventStartDrag(MyGUI::DDContainerPtr _sender, const MyGUI::DDItemInfo& _info, bool& _result)
{
MyGUI::ItemBoxPtr sender = _info.sender->castType<MyGUI::ItemBox>();
int data = *sender->getItemDataAt<int>(_info.sender_index);
_result = (data & 1) == 1;
}
void eventRequestDrop(MyGUI::DDContainerPtr _sender, const MyGUI::DDItemInfo& _info, bool& _result)
{
if (_info.receiver_index == MyGUI::ITEM_NONE)
{
_result = false;
}
else
{
MyGUI::ItemBoxPtr receiver = _info.receiver->castType<MyGUI::ItemBox>();
int data = *receiver->getItemDataAt<int>(_info.receiver_index);
_result = (data & 1) != 1;
}
}
void eventDropResult(MyGUI::DDContainerPtr _sender, const MyGUI::DDItemInfo& _info, bool _result)
{
if (!_result) return;
MyGUI::ItemBoxPtr sender = _info.sender->castType<MyGUI::ItemBox>();
MyGUI::ItemBoxPtr receiver = _info.receiver->castType<MyGUI::ItemBox>();
int data = *sender->getItemDataAt<int>(_info.sender_index);
int data2 = *receiver->getItemDataAt<int>(_info.receiver_index);
sender->setItemDataAt(_info.sender_index, (int)0);
receiver->setItemDataAt(_info.receiver_index, data + data2);
}
void init(MyGUI::Gui* _gui)
{
MyGUI::ItemBoxPtr box1 = _gui->createWidget<MyGUI::ItemBox>("ItemBoxV", MyGUI::IntCoord(10, 10, 300, 300), MyGUI::Align::Default, "Overlapped");
box1->requestCreateWidgetItem = MyGUI::newDelegate(requestCreateWidgetItem);
box1->requestCoordItem = MyGUI::newDelegate(requestCoordItem);
box1->requestDrawItem = MyGUI::newDelegate(requestDrawItem);
box1->eventStartDrag = MyGUI::newDelegate(eventStartDrag);
box1->eventRequestDrop = MyGUI::newDelegate(eventRequestDrop);
box1->eventDropResult = MyGUI::newDelegate(eventDropResult);
box1->addItem((int)101);
box1->addItem((int)43);
box1->addItem((int)54);
MyGUI::ItemBoxPtr box2 = _gui->createWidget<MyGUI::ItemBox>("ItemBoxV", MyGUI::IntCoord(410, 10, 300, 300), MyGUI::Align::Default, "Overlapped");
box2->requestCreateWidgetItem = MyGUI::newDelegate(requestCreateWidgetItem);
box2->requestCoordItem = MyGUI::newDelegate(requestCoordItem);
box2->requestDrawItem = MyGUI::newDelegate(requestDrawItem);
box2->eventStartDrag = MyGUI::newDelegate(eventStartDrag);
box2->eventRequestDrop = MyGUI::newDelegate(eventRequestDrop);
box2->eventDropResult = MyGUI::newDelegate(eventDropResult);
box2->addItem((int)14);
box2->addItem((int)273);
box2->addItem((int)75);
}
my.name
14-07-2009 22:20:20
full version 2
void requestCreateWidgetItem(MyGUI::ItemBoxPtr _sender, MyGUI::WidgetPtr _item)
{
MyGUI::StaticTextPtr text = _item->createWidget<MyGUI::StaticText>("StaticText", MyGUI::IntCoord(0, 0, _item->getWidth(), _item->getHeight()), MyGUI::Align::Stretch);
text->setNeedMouseFocus(false);
_item->setUserData(text);
}
void requestCoordItem(MyGUI::ItemBoxPtr _sender, MyGUI::IntCoord& _coord, bool _drag)
{
_coord.set(0, 0, 100, 100);
}
void requestDrawItem(MyGUI::ItemBoxPtr _sender, MyGUI::WidgetPtr _item, const MyGUI::IBDrawItemInfo& _info)
{
MyGUI::StaticTextPtr text = *_item->getUserData<MyGUI::StaticTextPtr>();
int data = *_sender->getItemDataAt<int>(_info.index);
if (_info.drag)
{
text->setCaption(MyGUI::utility::toString(
_info.drop_accept ? "#00FF00drag accept" : (_info.drop_refuse ? "#FF0000drag refuse" : "#0000FFdrag miss"),
"\n#000000data : ", data));
}
else
{
text->setCaption(MyGUI::utility::toString(
_info.drop_accept ? "#00FF00" : (_info.drop_refuse ? "#FF0000" : "#000000"), "index : ", _info.index,
"\n#000000data : ", data,
_info.active ? "\n#00FF00focus" : "\n#800000focus",
_info.select ? "\n#00FF00select" : "\n#800000select"));
}
}
void eventStartDrag(MyGUI::DDContainerPtr _sender, const MyGUI::DDItemInfo& _info, bool& _result)
{
MyGUI::ItemBoxPtr sender = _info.sender->castType<MyGUI::ItemBox>();
int data = *sender->getItemDataAt<int>(_info.sender_index);
_result = (data & 1) == 1;
}
void eventRequestDrop(MyGUI::DDContainerPtr _sender, const MyGUI::DDItemInfo& _info, bool& _result)
{
if (_info.receiver_index == MyGUI::ITEM_NONE)
{
_result = true;
}
else
{
MyGUI::ItemBoxPtr receiver = _info.receiver->castType<MyGUI::ItemBox>();
int data = *receiver->getItemDataAt<int>(_info.receiver_index);
_result = (data & 1) != 1;
}
}
void eventDropResult(MyGUI::DDContainerPtr _sender, const MyGUI::DDItemInfo& _info, bool _result)
{
if (!_result) return;
if (_info.receiver_index == MyGUI::ITEM_NONE)
{
MyGUI::ItemBoxPtr sender = _info.sender->castType<MyGUI::ItemBox>();
MyGUI::ItemBoxPtr receiver = _info.receiver->castType<MyGUI::ItemBox>();
int data = *sender->getItemDataAt<int>(_info.sender_index);
sender->removeItemAt(_info.sender_index);
receiver->addItem((int)data);
}
else
{
MyGUI::ItemBoxPtr sender = _info.sender->castType<MyGUI::ItemBox>();
MyGUI::ItemBoxPtr receiver = _info.receiver->castType<MyGUI::ItemBox>();
int data = *sender->getItemDataAt<int>(_info.sender_index);
int data2 = *receiver->getItemDataAt<int>(_info.receiver_index);
sender->removeItemAt(_info.sender_index);
receiver->setItemDataAt(_info.receiver_index, data + data2);
}
}
void init(MyGUI::Gui* _gui)
{
MyGUI::ItemBoxPtr box1 = _gui->createWidget<MyGUI::ItemBox>("ItemBoxV", MyGUI::IntCoord(10, 10, 300, 300), MyGUI::Align::Default, "Overlapped");
box1->requestCreateWidgetItem = MyGUI::newDelegate(requestCreateWidgetItem);
box1->requestCoordItem = MyGUI::newDelegate(requestCoordItem);
box1->requestDrawItem = MyGUI::newDelegate(requestDrawItem);
box1->eventStartDrag = MyGUI::newDelegate(eventStartDrag);
box1->eventRequestDrop = MyGUI::newDelegate(eventRequestDrop);
box1->eventDropResult = MyGUI::newDelegate(eventDropResult);
box1->addItem((int)101);
box1->addItem((int)43);
box1->addItem((int)54);
MyGUI::ItemBoxPtr box2 = _gui->createWidget<MyGUI::ItemBox>("ItemBoxV", MyGUI::IntCoord(410, 10, 300, 300), MyGUI::Align::Default, "Overlapped");
box2->requestCreateWidgetItem = MyGUI::newDelegate(requestCreateWidgetItem);
box2->requestCoordItem = MyGUI::newDelegate(requestCoordItem);
box2->requestDrawItem = MyGUI::newDelegate(requestDrawItem);
box2->eventStartDrag = MyGUI::newDelegate(eventStartDrag);
box2->eventRequestDrop = MyGUI::newDelegate(eventRequestDrop);
box2->eventDropResult = MyGUI::newDelegate(eventDropResult);
box2->addItem((int)14);
box2->addItem((int)273);
box2->addItem((int)75);
}
Great, thanks for your efforts!
Edit: The error in my first post was because I used "ItemBox" instead of "ItemBoxV" or "ItemBoxH" when creating the widget. You should place a comment in that line.
Your 2nd version crashes at
sender->removeItemAt(_info.sender_index);
Log: Item index 0 is out of range [1]
Bug?
my.name
25-07-2009 23:42:05
Bug!
Altren
28-07-2009 01:16:13
Download MyGUI 2.2.2 once again - I remember that this fix was included in 2.2.2 a bit later.
Is there a way to detect if the mouse hovers over an item? I want to show a complex tooltip in an extra window.
void Inventory::requestCreateWidgetItem( MyGUI::ItemBoxPtr _sender, MyGUI::WidgetPtr _item )
{
ItemRendable rendable;
rendable.Image = _item->createWidget< MyGUI::StaticImage >( "StaticImage", MyGUI::IntCoord( 2, 2, _item->getWidth() - 2, _item->getHeight() - 2 ), MyGUI::Align::Stretch );
rendable.Image->setNeedMouseFocus( false );
rendable.Quantity = _item->createWidget< MyGUI::StaticText >( "StaticText", MyGUI::IntCoord( 4, _item->getHeight() - 22, _item->getWidth() - 4, 20 ), MyGUI::Align::Default );
rendable.Quantity->setEnabled( false );
_item->setUserData( rendable );
}
StaticImage has no mouse over event.
Altren
07-08-2009 23:59:01
You always know if your item have focus: _info.active. And about StaticImage - it have no hover even because you disable it for taking that event by whole item instead imagerendable.Image->setNeedMouseFocus( false );
, so use hover event of item, not by child widget. Also look at Demo_ItemBox - it have tooltips.
Having some trouble with this... when I try to Init. this itembox code (exact code, just put into its own class) I get the following error:
"Child Widget Client not found in skin (ItemBox must have Client)"
...what does this mean? How do I resolve it?
Thanks for MyGUI by the way, it's a great library and it works well, but unfortunately the lack of comments can make it very difficult to learn / understand sometimes
my.name
17-08-2009 19:59:22
show code
@ Jdog
The error in my first post was because I used "ItemBox" instead of "ItemBoxV" or "ItemBoxH" when creating the widget. You (the devs) should place a comment in that line.
@ devs
Thanks for you help and this great library
Thanks! That was indeed the problem... changed the name to ItemBoxV and it worked. I'm not sure why this happens though? Is this because of skinning or something?
Also, I would like to use this to create an inventory system for a steampunk game. I've got the fundamentals working now, but I'd like to use a StaticImage widget as a background to give it a decorative outline... where would I do this?
I thought it might be in requestCreateWidgetItem, but that seems to create individual items? Thanks for a great library though, this is exactly what I needed!
Hi everyone, I have it working OK but I can't seem to make the itembox translucent... what I mean is, I'm trying to hide the background and the scrollbar and keep only the icons... I've made a background design for the itembox which is a separate StaticImage. How can I hide the scrollbar and background of the itembox?
I've tried this:
box->getClientWidget()->setVisible(false);
...but it makes the icons dissapear too, and I really need to see those. The scrollbar is still visible. Please help!
my.name
06-09-2009 11:37:23
show code
Well, it's very similar to the examples used here. I'm not using icons yet, but text like in the example here. This is my code, from in the inventory.cpp constructor:
// create inventory frame graphic
inventoryFrame = mGUI->createWidget<MyGUI::StaticImage>("StaticImage",MyGUI::IntCoord(300, 300, 447, 358), MyGUI::Align::Default, "Overlapped");
inventoryFrame->setItemResource("inventory_outline");
inventoryFrame->setItemGroup("Regular");
inventoryFrame->setItemName("Normal");
// create itembox
box = _gui->createWidget<MyGUI::ItemBox>("ItemBoxH", MyGUI::IntCoord(397, 422, 255, 145), MyGUI::Align::Default, "Overlapped");
box->requestCreateWidgetItem = MyGUI::newDelegate(this, &InventoryWindow::requestCreateWidgetItem);
box->requestCoordItem = MyGUI::newDelegate(this, &InventoryWindow::requestCoordItem);
box->requestDrawItem = MyGUI::newDelegate(this, &InventoryWindow::requestDrawItem);
box->eventStartDrag = MyGUI::newDelegate(this, &InventoryWindow::eventStartDrag);
box->eventRequestDrop = MyGUI::newDelegate(this, &InventoryWindow::eventRequestDrop);
box->eventDropResult = MyGUI::newDelegate(this, &InventoryWindow::eventDropResult);
// hide itembox except for icons (items) here
box->getClientWidget()->setVisible(false);
...compiles and runs OK. But that last part makes the itembox go invisible + icons... I need to see the icons, but not the itembox or scrollbar
Altren
06-09-2009 15:08:35
What exactly you want to get? Itembox without skin and scrollbar? Or you want optional hiding?
Hiding widget also hides it's child widgets, so it's correct behaviour that your icons is hidden. If you want to see items, but don't want to see item box skin and scrolls create and use empty skin for it. Just copy ItemBoxV skin and remove subskins and change Client widget skin to Default.
That worked fine, thanks guys
I have one last problem though. What I'm trying to do is a little funny, but I really hope it's possible:
The idea is, I have 3 characters in my game. There are 3 icons on the HUD, one for each character - if you open the Inventory (this ItemBox), then it opens the ItemBox ONLY for the current character - to trade, you have to drag and drop an item onto the HUD icon of another character. The HUD icons are StaticImagePtrs.
Here's my code in the itembox - this doesn't work because of the type conversion - all I need to do is be able to drag an item onto a StaticImage to get a result - how can I do this?
(The whole method is here, but the code I have trouble with is at the bottom --- smallPortrait1 is of type StaticImagePtr, I need a way to be able to drop on here.)
void InventoryWindow::eventDropResult(MyGUI::DDContainerPtr _sender, const MyGUI::DDItemInfo& _info, bool _result)
{
// nothing being dragged
if (!_result) return;
// item dropped on an empty cell (this shouldn't actually happen though...)
if (_info.receiver_index == MyGUI::ITEM_NONE)
{
}
// item dropped on a cell containing something else
else
{
MyGUI::ItemBoxPtr sender = _info.sender->castType<MyGUI::ItemBox>();
MyGUI::ItemBoxPtr receiver = _info.receiver->castType<MyGUI::ItemBox>();
// cell1 = item being dropped onto cell2
InventoryCell* cell1 = *sender->getItemDataAt<InventoryCell*>(_info.sender_index);
InventoryCell* cell2 = *receiver->getItemDataAt<InventoryCell*>(_info.receiver_index);
// if the two items are of the same type, stack...
if (cell1->getType() == cell2->getType())
{
InventoryCell* stackedItem = new InventoryCell(cell1->getType(), cell1->getQuantity() + cell2->getQuantity());
receiver->setItemDataAt(_info.receiver_index, stackedItem);
// ...and set the old one to an empty cell...
sender->setItemDataAt(_info.sender_index, new InventoryCell());
}
// ...otherwise, swap them.
else
{
sender->setItemDataAt(_info.sender_index, cell2);
receiver->setItemDataAt(_info.receiver_index, cell1);
}
}
// trading code! -----------------------------------------------
// attempting trade with character in small portrait 1...
if (_info.receiver->castType<MyGUI::StaticImage>() == smallPortrait1)
{
MyGUI::ItemBoxPtr sender = _info.sender->castType<MyGUI::ItemBox>();
// ADD CODE HERE... GIVE ITEM TO CHARACTER 2
sender->setItemDataAt(_info.sender_index, new InventoryCell());
}
}
... I know I'm probably being really annoying here but I'm quite lost... please help me out! Thank you guys for a great library.