Game Development Community

dev|Pro Game Development Curriculum

DragDropGui Control

by Stefan Beffy Moises · 04/07/2004 (12:47 pm) · 60 comments

This gui was originally written by Jarred Schnelle (Jafa Rykos) in 2003 and I have updated it to work with the current HEAD and to show the functionality in a little demo gui...
The demo gui artwork was kindly provided by Timothy Aste, www.gremlinstudios.com - thanks dude!

Please note: this is not a working inventory system, it's only the fancy gui/frontend part of it...
any inventory or whatever logic has to be implemented by the user... :-)

The zip contains a readme file, the source files, images as well as a patch file so that you don't have to make the necessary changes manually if you don't want to...

Here is what it looks like:
tork.beffy.de/images/remository_pics/dragdrop.jpg
and here is a little video showing it in action:
tork.beffy.de/downloads/videos/dragdrop1.avi (~1 MB, DivX 5.05)

Since the file is too large for the resource, you can grab it
here.

Have a lot of fun! :-)
Page «Previous 1 2 3 Last »
#1
04/07/2004 (1:51 pm)
Impressive!
#2
04/13/2004 (8:14 pm)
Beffy, you rock! Now all I gotta do is tie these functions into my inventory and database, and my persistent world tradeskill system will be done =)

An addition to this snippet, here's a little something for anyone who(like me) isn't using HEAD because they threw a million snippets at their project ;)...

I was getting errors about the "object" variable in the ConsoleMethods not being a member of the SimObject class, so I did the following to clear it up:

Changed:
ConsoleMethod( GuiDragDropButtonCtrl, setValue, void, 4, 4, "(int a, int b)"
"Set the value of the dragdrop control.")
{
object->setValue(dAtoi(argv[2]), dAtoi(argv[3]));
}

To:

ConsoleMethod( GuiDragDropButtonCtrl, setValue, void, 4, 4, "(int a, int b)"
"Set the value of the dragdrop control.")
{
GuiDragDropButtonCtrl *buttonCtrl = dynamic_cast(object);
buttonCtrl->setValue(dAtoi(argv[2]), dAtoi(argv[3]));
}

Of course, if someone with better knowledge of TGE sees a problem with this or a better way to do it, by all means let me know. To quote Gunny Highway in Heartbreak Ridge: "Well, it seemed like the thing to do at the time..."
#3
04/13/2004 (10:12 pm)
Glad you can use this, Ted :)
Thanks for the heads-up, the console functions were one thing I've changed when I updated this for HEAD, they were using the now deprecated (I think) syntax:
static void cBitmapSetValue(SimObject *obj, S32, const char **argv)
{
   GuiDragDropButtonCtrl *ctrl = static_cast<GuiDragDropButtonCtrl*>(obj);
   ctrl->setValue(dAtoi(argv[2]), dAtoi(argv[3]));
}
...
void GuiDragDropButtonCtrl::consoleInit()
{
   Con::addCommand("GuiDragDropButtonCtrl", "setValue",            cBitmapSetValue,            "guiDragDropButtonCtrl.setValue(xAxis, yAxis)", 4, 4);
...
which also was more cumbersome imho, so I've changed that...
Your changes should make it compatible with older TGE versions, too, though, so thx a lot for sharing! :)
#4
07/14/2004 (9:09 pm)
Thanks again Stefan,
With some wrenching I got this in.
Works fine in the new HEAD.
Hoping to use for character "equip" windows and combat toolbars.
Keep it up Beffy!

This resource has been assimilated!

Ari
#5
07/16/2004 (2:18 pm)
Has anyone integrated any one of the many inventory resources into a game with this one? If so, which one and how difficult was it?
#6
08/27/2004 (3:57 am)
This is a great resource.

I have an optional tweak for those who perfer the mouse cursor to grab the center of the image instead of the far upper left corner.

Around line 472:
void GuiDragDropButtonCtrl::onMouseDown(const GuiEvent & event)
{
   Parent::onMouseDown(event);

   mOrigBounds = mBounds;
   mMouseDownPosition = event.mousePoint;
   mMouseDownPositionOffset = event.mousePoint;
   [B]mMouseDownPositionOffset.x -= mBounds.extent.x / 2;[/B]
   [B]mMouseDownPositionOffset.y -= mBounds.extent.y / 2;[/B]
   if(mDownTextureHandle)

Now when you grab the button, you "hold" it by the middle. Personally, I like the effect a little better.

Joe
#7
09/01/2004 (8:01 am)
which inventory system have people been using as a base for this GUI overlay?
Cheers, Ashley
#8
09/01/2004 (9:55 am)
I've been cooking up my own inventory system using this control. Works nicely, and you can even change a few things around in the C++ part very easily, though there's very little need for that since it's very basic and flexible.

Right now, I'm hooking it into my database and getting it to pull icons, stats and (hopefully tonight) execute actions stored in that database when you drag and drop on each other. I'm using right-clicks to execute/use objects, and left-click dragging for drag and drop. Also, I'm considering a ctrl-click function to bring up a small information window about the object. This control is awesome!
#9
09/07/2004 (11:19 pm)
can you post the basics of your control then ted?
#10
09/08/2004 (7:44 am)
Synditech: It's the same as here, except I moved the call to OnAction to the function for the right mouse-click. The script functions for the clicks and drag and drops are implemented on the server-side because it's a persistent world and you can't trust the client with information. Pretty simple really(really, if I can pull it off, anyone can, haha).

For hooking it into the database, that's a different snippet altogether, so whatever you want to use to do that, but what I do right now is pull the icon filenames from the database of a character's inventory, and then use the SetBitmap() function for the controls to change the bitmaps to the inventory upon character loading. The only problem I have to overcome now is the exact structure for the inventory data, and the way to implement tradeskill functions using that data.
#11
09/12/2004 (10:52 am)
An improvement upon Joe's improvement :)

Rather than drag from the center of the icon, which can still cause a jerky jump, I like to drag from where I clicked. Whereever in the icon image I click, is where its held while dragging.

Still around line 472
mOrigBounds = mBounds;
   mMouseDownPosition = event.mousePoint;
   mMouseDownPositionOffset = event.mousePoint;[b]
   Point2I grabbedPos = globalToLocalCoord(event.mousePoint);
   mMouseDownPositionOffset.x -= grabbedPos.x;
   mMouseDownPositionOffset.y -= grabbedPos.y;[/b]
#12
10/24/2004 (3:33 am)
Here's another little fix.
I have a main menu that pulls up additional menus via the magic of setvisible. Click the backpack, and 10 more slots open. Same thing for a few pouches. The problem is, when the dragdrop slots are in the same spot, the gui gets confused on which one you want., ie, drop the item in the backpack slot, and it winds up in the pouch. So, we need to tell the controls to use the visiblity of its parent gui.
So, around line 790, find
if(DDBCtrl->mIsReceiver && this->getDropBorderSearch() == DDBCtrl->getDropBorderType())
and change to
if(DDBCtrl->mIsReceiver && this->getDropBorderSearch() == DDBCtrl->getDropBorderType() && DDCtrl->getParent()->isVisible())
#13
10/27/2004 (3:41 am)
Here is a bug I found. You assign pointers to mDropBorderType and mDropBorderSearch, of course this cause some trouble, here is the original code :

//DropBorderType Member Function - Setter
void GuiDragDropButtonCtrl::setDropBorderType(const char* temp)
{
   mDropBorderType = temp;
}


//DropBorderSearch Member Function - Setter
void GuiDragDropButtonCtrl::setDropBorderSearch(const char* temp)
{
   mDropBorderSearch = temp;
}

Here is corrected code :

//DropBorderType Member Function - Setter
void GuiDragDropButtonCtrl::setDropBorderType(const char* temp)
{
   mDropBorderType = [b]StringTable->insert(temp);[/b]
}


//DropBorderSearch Member Function - Setter
void GuiDragDropButtonCtrl::setDropBorderSearch(const char* temp)
{
   mDropBorderSearch = [b]StringTable->insert(temp);[/b]
}

That bug made me searching for a long time. I 1st thought that my script code was the problem (it is quit complex) then only thru extensive debugging I could grab this bug. It's pretty obvious but you never look (at least me) for the easy way.

CAF
#14
10/27/2004 (3:50 am)
Erik thanks for your 2 last posts, they solve exactly 2 problems I am having.

Thanks

CAF
#15
10/29/2004 (3:51 am)
Another bug I found.

When you try to drag drop a button which has canMove = "0" and you let the mouse up on another button the system crash. The mouse up is done on the other button and not on the dragged (the one you tried).

The following code change (in bold) correct that problem.

void GuiDragDropButtonCtrl::onMouseUp(const GuiEvent & event)
{
   bool executedFunction = false;
   
[b]  if(!mIsButtonMoving)
	   return ;[/b]
   
   Parent::onMouseUp(event);
   mIsButtonMoving = false;
   mouseUnlock();


I know that this is not a bug that will show up very often, but it happen.... Specially when you do fast actions, you release the mouse button when you realise the icon cannot be dragged but you are already near or at the target button when you do....
#16
11/16/2004 (11:46 am)
This resource was so easy to implement I didn't even have to make a single change! Except for the bug fixes. Now it's just a matter of time before I glue it with my inventory system and database similar to what Ted Southard is doing! Really nice work Beffy!

I wonder though. How hard would it be to expand on this and make it so that:
When you drag an item away from the "slots" and into the world, the item image goes away and gets replaced by a DTS model equivalent. Then using a cast ray or something you are able to drop the object onto the terrain?

Anyone have any ideas where to start?

Nick
#17
11/16/2004 (4:19 pm)
@Nick: What you can do is that when you drag and drop over an area that is part of the environment, your mouse cursor shoots a vector out and will place the object where that vector intersects with the terrain(creating the object is easy so I won't go into that). How to know what object to create? When you click and drag, have an action function transfer the data of that item into the variables needed for the creation function. So you click on the item, which creates the variables for the object, and drag it, then let go on the screen, which shoots a vector out to the terrain, intersects it, and uses the variables to create an object at the position where the vector hit the terrain.

This resource has everything you need for the drag and drop portion, but you'll want to check out the World Click or Click n Pick resources and modify them to work with the onMouseUp(?) events as well as checking at that point to see if those variables are in use(maybe a bool value tripped when you drag something, as opposed to just clicking and dragging nothing).

Hope that helps(it should, that's the step-by-step, lol) ;)
#18
11/16/2004 (10:16 pm)
Thanks Ted! Your steps seem very logical. While I fully understand what you're talking about, it'd be interesting to see if I can pull this off as it's probably the hardest task I've tried with Torque.
However, it seems a little easier that I initially thought.

We'll see how it goes.

Nick
#19
03/23/2005 (8:28 pm)
@Stefan or anyone else with a good understanding of this resource or GUI creation in general, please check out this post I made, in which I am asking for some help. Thank you!
#20
04/02/2005 (7:42 pm)
This is the most unintrusive mod I've seen yet. AMAZING!
Page «Previous 1 2 3 Last »