ItemBox

TWO

11-07-2009 18:03:25

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.

TWO

12-07-2009 12:09:11

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);
}

TWO

23-07-2009 09:19:24

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.

TWO

25-07-2009 16:59:03

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!

TWO

27-07-2009 21:41:02

Yes?

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.

TWO

07-08-2009 20:39:24

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.

Jdog

17-08-2009 17:58:42

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

TWO

17-08-2009 21:07:21

@ 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 :)

Jdog

17-08-2009 22:55:47

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!

Jdog

06-09-2009 09:38:55

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

Jdog

06-09-2009 12:58:14

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.

Jdog

12-09-2009 11:51:55

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.