New link for you B@z, but in my game, the application crash when I try to drag and drop.B@z wrote:HTTP1.1 STATUS 403 Remote Access to this object forbidden
Direct Access Forbidden
This file cannot be directly accessed from a remote site, but must be linked through the Brinkster Member's site.
(C++) icon/slot drag/drop rpg style gui
Project homepage: http://fosp.wordpress.com/
Project Forum URL: http://forum.gamedev.vn/index.php?showforum=74
Project Google Group: http://groups.google.com/group/fosproject
Engine Project: http://code.google.com/p/fosengine/
Project Forum URL: http://forum.gamedev.vn/index.php?showforum=74
Project Google Group: http://groups.google.com/group/fosproject
Engine Project: http://code.google.com/p/fosengine/
You are right. But, this code have 2 logic error when processing event.pera wrote:This code works only from main function... if you have icon touch crash, that is because slotArray went out of scope, like the man said few years ago. Make slotArray global, or do some intelligent modification.
Project homepage: http://fosp.wordpress.com/
Project Forum URL: http://forum.gamedev.vn/index.php?showforum=74
Project Google Group: http://groups.google.com/group/fosproject
Engine Project: http://code.google.com/p/fosengine/
Project Forum URL: http://forum.gamedev.vn/index.php?showforum=74
Project Google Group: http://groups.google.com/group/fosproject
Engine Project: http://code.google.com/p/fosengine/
Yes, that is correct.
When code was moved to Irrlicht 1.4, only compiler errors were fixed.
In order to make it work, you have to use 1.4 OnEvent functions for GUIWindow, and CIcon. I There were some changes in event handling, so you have to do it like that for it to work properly.
I made those changes and succeded to make code work fine, I can post changes later, but during code exploration I relized this GUI component was pretty awkwardly coded. There is two new classes CSlotWindow and that BringUpButton wich don't do anything different then regular component (CSlotWindow creates slotArray and returns it but its not even member component of CSlotWindow, and BringUpButton shows/hides window wich any regular button can do - no need for special class I think).
my favorite is
Dragged = true*Movable;
Anyhow, I think This inventory should be one GUI class that can be added to window like any other button or list or text. It should have addItem and couple of more functions and thats about it. If I make something like that usable, I'll post it.
When code was moved to Irrlicht 1.4, only compiler errors were fixed.
In order to make it work, you have to use 1.4 OnEvent functions for GUIWindow, and CIcon. I There were some changes in event handling, so you have to do it like that for it to work properly.
I made those changes and succeded to make code work fine, I can post changes later, but during code exploration I relized this GUI component was pretty awkwardly coded. There is two new classes CSlotWindow and that BringUpButton wich don't do anything different then regular component (CSlotWindow creates slotArray and returns it but its not even member component of CSlotWindow, and BringUpButton shows/hides window wich any regular button can do - no need for special class I think).
my favorite is
Dragged = true*Movable;
Anyhow, I think This inventory should be one GUI class that can be added to window like any other button or list or text. It should have addItem and couple of more functions and thats about it. If I make something like that usable, I'll post it.
This are my modifications to Window class in order to make it work in Irrlicht 1.4:
These are modifications to CIcon class:
And use addUsableSlotArray instead of setUsableSlotArray to avoid global variable error...
Code: Select all
#include "CGUISlotWindow.h"
#include "CGUIBringUpSlotWindowButton.h"
#include "CGUIIconSlot.h"
namespace irr
{
namespace gui
{
//! constructor
CGUISlotWindow::CGUISlotWindow(IrrlichtDevice* device, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
: IGUIWindow(device->getGUIEnvironment(), parent, id, rectangle), Dragging(false), Device(device)
{
#ifdef _DEBUG
setDebugName("CGUISlotWindow");
#endif
IGUISkin* skin = 0;
if (Environment)
skin = Environment->getSkin();
IGUISpriteBank* sprites = 0;
video::SColor color(255,255,255,255);
s32 buttonw = 15;
if (skin)
{
buttonw = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH);
sprites = skin->getSpriteBank();
color = skin->getColor(EGDC_WINDOW_SYMBOL);
}
s32 posx = RelativeRect.getWidth() - buttonw - 4;
CloseButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close" );
CloseButton->setSubElement(true);
CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
if (sprites)
{
CloseButton->setSpriteBank(sprites);
CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), color);
CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), color);
}
posx -= buttonw + 2;
RestoreButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
L"", skin ? skin->getDefaultText(EGDT_WINDOW_RESTORE) : L"Restore" );
RestoreButton->setVisible(false);
RestoreButton->setSubElement(true);
RestoreButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
if (sprites)
{
RestoreButton->setSpriteBank(sprites);
RestoreButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_RESTORE), color);
RestoreButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_RESTORE), color);
}
posx -= buttonw + 2;
MinButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
L"", skin ? skin->getDefaultText(EGDT_WINDOW_MINIMIZE) : L"Minimize" );
MinButton->setVisible(false);
MinButton->setSubElement(true);
MinButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
if (sprites)
{
MinButton->setSpriteBank(sprites);
MinButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_MINIMIZE), color);
MinButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_MINIMIZE), color);
}
MinButton->grab();
RestoreButton->grab();
CloseButton->grab();
}
//! destructor
CGUISlotWindow::~CGUISlotWindow()
{
if (MinButton)
MinButton->drop();
if (RestoreButton)
RestoreButton->drop();
if (CloseButton)
CloseButton->drop();
}
//! called if an event happened.
bool CGUISlotWindow::OnEvent(const SEvent& event)
{
switch(event.EventType)
{
case EET_GUI_EVENT:
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
{
Dragging = false;
}
else
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED)
{
if (event.GUIEvent.Caller == this && Parent)
{
Parent->bringToFront(this);
}
}
else
if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
{
if (event.GUIEvent.Caller == CloseButton)
{
if (Parent)
{
// send close event to parent
SEvent e;
e.EventType = EET_GUI_EVENT;
e.GUIEvent.Caller = this;
e.GUIEvent.Element = 0;
e.GUIEvent.EventType = EGET_ELEMENT_CLOSED;
// if the event was not absorbed
if (!Parent->OnEvent(e))
{
remove();
}
return true;
}
else
{
remove();
return true;
}
}
}
break;
case EET_MOUSE_INPUT_EVENT:
switch(event.MouseInput.Event)
{
case EMIE_LMOUSE_PRESSED_DOWN:
DragStart.X = event.MouseInput.X;
DragStart.Y = event.MouseInput.Y;
Dragging = true;
if (!Environment->hasFocus(this))
{
Environment->setFocus(this);
if (Parent)
Parent->bringToFront(this);
}
return true;
case EMIE_LMOUSE_LEFT_UP:
Dragging = false;
return true;
case EMIE_MOUSE_MOVED:
if (Dragging)
{
// gui window should not be dragged outside its parent
if (Parent)
if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 ||
event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 ||
event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 ||
event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1)
return true;
move(core::position2d<s32>(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y));
DragStart.X = event.MouseInput.X;
DragStart.Y = event.MouseInput.Y;
return true;
}
break;
default:
break;
}
default:
break;
}
return IGUIElement::OnEvent(event);
}
//! Updates the absolute position.
void CGUISlotWindow::updateAbsolutePosition()
{
IGUIElement::updateAbsolutePosition();
}
//! draws the element and its children
void CGUISlotWindow::draw()
{
if (!IsVisible)
return;
IGUISkin* skin = Environment->getSkin();
core::rect<s32> rect = AbsoluteRect;
core::rect<s32> *cl = &AbsoluteClippingRect;
// draw body fast
rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER),
AbsoluteRect, &AbsoluteClippingRect);
if (Text.size())
{
rect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X);
rect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y);
rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5;
IGUIFont* font = skin->getFont(EGDF_WINDOW);
if (font)
font->draw(Text.c_str(), rect, skin->getColor(EGDC_ACTIVE_CAPTION), false, true, cl);
}
IGUIElement::draw();
}
//! Returns pointer to the close button
IGUIButton* CGUISlotWindow::getCloseButton() const
{
return CloseButton;
}
//! Returns pointer to the minimize button
IGUIButton* CGUISlotWindow::getMinimizeButton() const
{
return MinButton;
}
//! Returns pointer to the maximize button
IGUIButton* CGUISlotWindow::getMaximizeButton() const
{
return RestoreButton;
}
//! adds a bring-up button
CGUIBringUpSlotWindowButton* CGUISlotWindow::createBringUpButton(core::rect<s32> rectangle, IGUIElement* parent,
s32 id, const wchar_t* text,
const wchar_t* tooltip)
{
if(!parent)
parent = Environment->getRootGUIElement();
CGUIBringUpSlotWindowButton* button = new CGUIBringUpSlotWindowButton(Device, parent, id, rectangle, this);
if(text)
button->setText(text);
if(tooltip)
button->setToolTipText(tooltip);
return button;
}
//! adds a slot array to the window
core::array<IGUIElement*> CGUISlotWindow::addSlotArray(core::rect<s32> slotRect, video::ITexture* texture,
IGUIElement* parent, s32 id ,
core::position2d<s32> relPos,
core::dimension2d<s32> arrayDim,
core::dimension2d<s32> spacing)
{
if(!parent)
parent = this;
//create the array
core::array<IGUIElement*> slotArray;
for(s32 x = 0; x < arrayDim.Width; x++)
{
for(s32 y = 0; y < arrayDim.Height; y++)
{
CGUIIconSlot* slot = new CGUIIconSlot(Environment, parent, id, slotRect);
slot->setImage(texture);
slot->setRelativePosition(core::rect<s32>(relPos.X + x*(spacing.Width + slotRect.LowerRightCorner.X),
relPos.Y + y*(spacing.Height + slotRect.LowerRightCorner.Y),
slotRect.LowerRightCorner.X + (relPos.X + x*(spacing.Width + slotRect.LowerRightCorner.X)),
slotRect.LowerRightCorner.Y +(relPos.Y + y*(spacing.Height + slotRect.LowerRightCorner.Y))));
slotArray.push_back(slot);
slot->drop();
}
}
return slotArray;
}
}//end namespace gui
}//end namespace irr
These are modifications to CIcon class:
Code: Select all
#include "CGUIIcon.h"
#include "CGUIIconSlot.h"
namespace irr
{
namespace gui
{
//! Constructor
CGUIIcon::CGUIIcon(gui::IGUIEnvironment* environment, gui::IGUIElement* parent, s32 id, core::rect<s32> rectangle)
: IGUIElement(gui::EGUIET_ELEMENT , environment, parent, id, rectangle), Texture(0),
Moveable(true), CanBeOutsideSlot(false), Slot(0), Dragging(false) {
UsableSlots.clear();
}
//! Destructor
CGUIIcon::~CGUIIcon()
{
if(Texture)
Texture->drop();
}
//! Sets an image which should be displayed as the icon
void CGUIIcon::setImage(video::ITexture *img)
{
if(Texture)
Texture->drop();
Texture = img;
if(Texture)
Texture->grab();
}
//! draws the element and its children
void CGUIIcon::draw()
{
if (!IsVisible)
return;
irr::video::IVideoDriver* driver = Environment->getVideoDriver();
if (Texture)
{
driver->draw2DImage(Texture, AbsoluteRect.UpperLeftCorner,
core::rect<s32>(core::position2d<s32>(0,0), Texture->getOriginalSize()));
IGUIElement::draw();
}
}
//! called if an event happened.
bool CGUIIcon::OnEvent(const SEvent& event)
{
switch(event.EventType)
{
case EET_GUI_EVENT:
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
{
Dragging = false;
}
else
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED)
{
if (event.GUIEvent.Caller == this && Parent)
{
Parent->bringToFront(this);
}
}
break;
case EET_MOUSE_INPUT_EVENT:
switch(event.MouseInput.Event)
{
case EMIE_LMOUSE_PRESSED_DOWN:
DragStart.X = event.MouseInput.X;
DragStart.Y = event.MouseInput.Y;
Dragging = Moveable;
if (!Environment->hasFocus(this))
{
Environment->setFocus(this);
if (Parent)
{
Parent->bringToFront(this);
//if the icon is in a slot (if the parent isn't the gui root element)
if(!(Parent == Environment->getRootGUIElement()))
{
//make the icon a child of the root element (removing it from the slot)
Environment->getRootGUIElement()->addChild(this);
//the current position
core::rect<s32> currPos = getAbsolutePosition();
//move the icon the the right position (ready for dragging)
move(core::position2d<s32>(event.MouseInput.X - (event.MouseInput.X-currPos.UpperLeftCorner.X),
event.MouseInput.Y - (event.MouseInput.Y-currPos.UpperLeftCorner.Y)));
}
}
}
return true;
case EMIE_LMOUSE_LEFT_UP:
{
Dragging = false;
bool movedToSlot = false;
//is the icon droped in a useable slot's rect
u32 size = UsableSlots.size();
IGUIElement *slot = 0;
for(u32 i = 0; i < size; i++)
{
//get the slot
slot = UsableSlots[i];
if(slot)
{
//get the slot rect
core::rect<s32> slotRect = slot->getAbsolutePosition();
//if the position the icon is dropped in, is inside the rect
if(slotRect.isPointInside(DragStart))
{
//move the icon to the slot
moveToSlot(slot);
movedToSlot = true;
}
}
}
//if the icon is dropped outside a slot, and it's not supposed to
if(!movedToSlot && !CanBeOutsideSlot)
{
if(Slot)
{
//move it back to where it came from
moveToSlot(Slot);
}
}
}
return true;
case EMIE_MOUSE_MOVED:
if (Dragging)
{
move(core::position2d<s32>(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y));
DragStart.X = event.MouseInput.X;
DragStart.Y = event.MouseInput.Y;
return true;
}
break;
default:
break;
}
default:
break;
}
return IGUIElement::OnEvent(event);
}//end function OnEvent
//! Sets whether the icon can be moved
void CGUIIcon::setMoveable(bool state)
{
Moveable = state;
}
//! Sets whether the icon can be dropped outside a slot
void CGUIIcon::setCanBeOutsideSlot(bool state)
{
CanBeOutsideSlot = state;
}
//! Adds a single slot to the usable slots
void CGUIIcon::addUsableSlot(IGUIElement* slot)
{
UsableSlots.push_back(slot);
}
//! Adds the slots in the array to the usable slots
void CGUIIcon::addUsableSlotArray(const core::array<IGUIElement*>& slotArray)
{
s32 arraySize = slotArray.size();
for(s32 i = 0; i < arraySize; i++)
{
UsableSlots.push_back(slotArray[i]);
}
}
//! Moves the icon to the passed slot
void CGUIIcon::moveToSlot(IGUIElement* slot)
{
//check if the slot is usable
bool usable = false;
u32 size = UsableSlots.size();
for(u32 i = 0; i < size; i++)
{
if(UsableSlots[i] == slot)
usable = true;
}
//if the slot is not usable - make it usable
if(!usable)
UsableSlots.push_back(slot);
//if the slot is in use (if the slot has a children)
if(slot->getChildren().getSize())
{
/* get the icon from the slot. Gets the last child of the child list,
asuming that this is the only child the slot has,
and that this child is an CGUIIcon */
CGUIIcon* icon = (CGUIIcon*)(*slot->getChildren().getLast());
//move the icon to where the currently moving icon came from
//if(Slot)
//{
// icon->moveToSlot(Slot);
//}
}
//add the currently moving icon to the slot
slot->addChild(this);
//save the slot
Slot = slot;
//set the relative position
setRelativePosition(core::rect<s32>(core::position2d<s32>(0,0), Texture->getOriginalSize()));
}
//! Gets the slot the icon is in
IGUIElement* CGUIIcon::getSlot()
{
return Slot;
}
}//end namespace gui
}//end namespace irr
We have a 1.4.1 runable version too.
http://code.google.com/p/fosengine/source/browse
Copyright notice file: http://fosengine.googlecode.com/svn/tru ... me-GUI.txt
Source code files:
http://fosengine.googlecode.com/svn/tru ... Button.cpp 10.5 KB r245 Jun 20, 2008 doqkhanh
http://fosengine.googlecode.com/svn/tru ... owButton.h 4.2 KB r245 Jun 20, 2008 doqkhanh
http://fosengine.googlecode.com/svn/tru ... UIIcon.cpp 8.8 KB r310 Jul 01 (6 days ago) doqkhanh
http://fosengine.googlecode.com/svn/tru ... CGUIIcon.h[/url] 1.9 KB r300 Jun 29, 2008 doqkhanh
http://fosengine.googlecode.com/svn/tru ... IconSlot.h 1.3 KB r300 Jun 29, 2008 doqkhanh
http://fosengine.googlecode.com/svn/tru ... Window.cpp 8.5 KB r301 Jun 29, 2008 doqkhanh
http://fosengine.googlecode.com/svn/tru ... otWindow.h 2.8 KB r246 Jun 21, 2008 doqkhanh
http://code.google.com/p/fosengine/source/browse
Copyright notice file: http://fosengine.googlecode.com/svn/tru ... me-GUI.txt
Source code files:
http://fosengine.googlecode.com/svn/tru ... Button.cpp 10.5 KB r245 Jun 20, 2008 doqkhanh
http://fosengine.googlecode.com/svn/tru ... owButton.h 4.2 KB r245 Jun 20, 2008 doqkhanh
http://fosengine.googlecode.com/svn/tru ... UIIcon.cpp 8.8 KB r310 Jul 01 (6 days ago) doqkhanh
http://fosengine.googlecode.com/svn/tru ... CGUIIcon.h[/url] 1.9 KB r300 Jun 29, 2008 doqkhanh
http://fosengine.googlecode.com/svn/tru ... IconSlot.h 1.3 KB r300 Jun 29, 2008 doqkhanh
http://fosengine.googlecode.com/svn/tru ... Window.cpp 8.5 KB r301 Jun 29, 2008 doqkhanh
http://fosengine.googlecode.com/svn/tru ... otWindow.h 2.8 KB r246 Jun 21, 2008 doqkhanh
Project homepage: http://fosp.wordpress.com/
Project Forum URL: http://forum.gamedev.vn/index.php?showforum=74
Project Google Group: http://groups.google.com/group/fosproject
Engine Project: http://code.google.com/p/fosengine/
Project Forum URL: http://forum.gamedev.vn/index.php?showforum=74
Project Google Group: http://groups.google.com/group/fosproject
Engine Project: http://code.google.com/p/fosengine/
-
- Posts: 27
- Joined: Mon Apr 05, 2010 7:33 am
Please help! I am getting errors:
What happens?
Code: Select all
CGUISlotWindow.cpp:233: error: cannot allocate an object of type `irr::gui::CGUIBringUpSlotWindowButton'
CGUISlotWindow.cpp:233: error: because the following virtual functions are abstract:
IGUIButton.h:128: error: virtual void irr::gui::IGUIButton::setScaleImage(bool)
IGUIButton.h:131: error: virtual bool irr::gui::IGUIButton::isScalingImage() const
Sorry, my english is very bad. | I use minGW+CodeBlocks+Irrlicht 1.7.1(1.6,1.5)