Manually starting dragging on a DragContainer
Moderators: CEGUI MVP, CEGUI Team
Manually starting dragging on a DragContainer
Hey,
I'm writing an inventory system currently where I have the following problem:
Two inventory slots A and B containing two items (drag container containing a staticImage) 1 and 2
A contains 1
B contains 2
now I'm picking 1 and dragging it to B, which already contains 2. Now I'm dropping 1 into B.
What I want to achieve now is that 1 "replaces" 2, so that B contains 1 and 2 is being dragged automatically now.
I could think off two ways for that:
1) manually firing the dragStart on 2 by some nasty hacks in CEGUI
2) exchanging the icons contained by 1's and 2's DragContainers and somehow dismissing the Dropped event (which would require CEGUI hacks too and even more tricky code on my side)
both of them require some hacky modifications in CEGUI I guess, so I'd be really happy about any advice on this one
Greetings,
-BigG
I'm writing an inventory system currently where I have the following problem:
Two inventory slots A and B containing two items (drag container containing a staticImage) 1 and 2
A contains 1
B contains 2
now I'm picking 1 and dragging it to B, which already contains 2. Now I'm dropping 1 into B.
What I want to achieve now is that 1 "replaces" 2, so that B contains 1 and 2 is being dragged automatically now.
I could think off two ways for that:
1) manually firing the dragStart on 2 by some nasty hacks in CEGUI
2) exchanging the icons contained by 1's and 2's DragContainers and somehow dismissing the Dropped event (which would require CEGUI hacks too and even more tricky code on my side)
both of them require some hacky modifications in CEGUI I guess, so I'd be really happy about any advice on this one
Greetings,
-BigG
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Re: Manually starting dragging on a DragContainer
Hi,
I'm guessing this is with the 'sticky' mode enabled, since it makes no sense otherwise?
It's something I'd not considered actually, but I think it's a useful feature to provide. Due to the internal states that needs to be adjusted to affect such a switch, I think a new function for this purpose can be added (there's no real way of doing it currently without some kind of hack, none of which are really ideal). With the new function in place, I think I would still leave it up to the user code to detect the 'drop' and subsequently call the as yet unnamed function on any existing DragContainer to pick it up (it's more flexible when left to the user to call the function, and saves us from having a thousand 'modes' for all the various options!).
I can try and get this function in for 0.7.1, since it's just a single function to add.
CE.
I'm guessing this is with the 'sticky' mode enabled, since it makes no sense otherwise?
It's something I'd not considered actually, but I think it's a useful feature to provide. Due to the internal states that needs to be adjusted to affect such a switch, I think a new function for this purpose can be added (there's no real way of doing it currently without some kind of hack, none of which are really ideal). With the new function in place, I think I would still leave it up to the user code to detect the 'drop' and subsequently call the as yet unnamed function on any existing DragContainer to pick it up (it's more flexible when left to the user to call the function, and saves us from having a thousand 'modes' for all the various options!).
I can try and get this function in for 0.7.1, since it's just a single function to add.
CE.
Useful Links: Forum Guidelines | Documentation | Tutorials | HOWTO | Videos | Donate to CEGUI | CEGUI Twitter
Re: Manually starting dragging on a DragContainer
Thanks for your reply CE!
Yea, having such a function would be really cool I had an idea about it, how about if the CEGUI::Window::EventDragDropItemDropped event would have a specialised CEGUI::DragDropEventArgs argument that contains an additional CEGUI::DragContainer pointer to be set by the event handler, which, if set to 0, does nothing, otherwise starts a new drag event with the pointed drag container? This would require only a little amount of work and not even an additional function or anything
about your question whether sticky mode is enabled... well it's a tricky one. To actually drag&drop 1 to slot B, it doesn't matter whether it is enabled/being used or not. But as soon as the exchanging takes place, it has to be enabled in any case, as the user is no longer pressing any mouse button yet you need to have the container sticked to the cursor. This is because 1 has now replaced 2 in slot B (the item itself, not only the GUI part of it), so 2 is kind of 'slotless' now and MUST be put into another slot.
-BigG
Yea, having such a function would be really cool I had an idea about it, how about if the CEGUI::Window::EventDragDropItemDropped event would have a specialised CEGUI::DragDropEventArgs argument that contains an additional CEGUI::DragContainer pointer to be set by the event handler, which, if set to 0, does nothing, otherwise starts a new drag event with the pointed drag container? This would require only a little amount of work and not even an additional function or anything
about your question whether sticky mode is enabled... well it's a tricky one. To actually drag&drop 1 to slot B, it doesn't matter whether it is enabled/being used or not. But as soon as the exchanging takes place, it has to be enabled in any case, as the user is no longer pressing any mouse button yet you need to have the container sticked to the cursor. This is because 1 has now replaced 2 in slot B (the item itself, not only the GUI part of it), so 2 is kind of 'slotless' now and MUST be put into another slot.
-BigG
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Re: Manually starting dragging on a DragContainer
Thanks for the suggestions and such. The issue with the event args suggestion is (of course?) that the args struct is const, so you can't set the field from a normally subscribed handler
I think the function is the way we'll go, and basically it will be able to be called at any time - if the container is non-sticky, nothing will happen, otherwise the item will immediately show as attached to the mouse. I'll get this added tomorrow most likely.
CE.
I think the function is the way we'll go, and basically it will be able to be called at any time - if the container is non-sticky, nothing will happen, otherwise the item will immediately show as attached to the mouse. I'll get this added tomorrow most likely.
CE.
Useful Links: Forum Guidelines | Documentation | Tutorials | HOWTO | Videos | Donate to CEGUI | CEGUI Twitter
Re: Manually starting dragging on a DragContainer
CrazyEddie wrote:Thanks for the suggestions and such. The issue with the event args suggestion is (of course?) that the args struct is const, so you can't set the field from a normally subscribed handler
duh, totally forgot about that xD well yea, I guess a function to manually start drag&drop would be the best way to go then. Thanks for helping me out on this and in advance for the patches
-BigG
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Re: Manually starting dragging on a DragContainer
This has been added in the stable v0-7 branch as of rev 2321.
There is a new CEGUI::DragContainer::pickUp function (which takes an optional boolean argument that specifies whether to automatically switch the DragContainer to sticky mode, default is false).
I've tested it for a bit in a hacked around version of our Drag&Drop demo and it all works pretty well. With regard to the sticky mode change, in my test I had it off to start with, used the force option on the new function to force it on, then manually reset it again upon the drop notification.
Exactly how you'll use the function will depend on what you're doing currently, but I think you should be able to fathom it out fairly easily
CE.
There is a new CEGUI::DragContainer::pickUp function (which takes an optional boolean argument that specifies whether to automatically switch the DragContainer to sticky mode, default is false).
I've tested it for a bit in a hacked around version of our Drag&Drop demo and it all works pretty well. With regard to the sticky mode change, in my test I had it off to start with, used the force option on the new function to force it on, then manually reset it again upon the drop notification.
Exactly how you'll use the function will depend on what you're doing currently, but I think you should be able to fathom it out fairly easily
CE.
Useful Links: Forum Guidelines | Documentation | Tutorials | HOWTO | Videos | Donate to CEGUI | CEGUI Twitter
Re: Manually starting dragging on a DragContainer
Thanks again for your support, CE
Checking out the branch right now; I will post back after trying around with the new function
-BigG
//Edit:
OK, played around with the new function and I got to say that it works as I wanted it
Yet I have another question/request xD the DragContainer is always kept in a static offset to the cursor when the cursor moves. This offset is set when the dragging starts, calculated from the current DragContainer position and the current Mouse position (I think). Would it be possible to add a function like CEGUI::DragContainer::setMouseCursorOffset taking a CEGUI::UVector2 as parameter where you can specify that offset overwriting the dynamic calculation if set.The current DragContainer position would the be calculated as CursorPosition + MouseCursorOffset. That would make it possible to, for example, keep the item icon aligned to the cursor's head in my case Should not be a big change either
Thanks again
- BigG
//Edit2:
I found a small visual bug:
When calling pickUp(), the DragContainer itself stays where it is until you move the mouse, then it all works fine and it is dynamically aligned (as described above) to the mouse. But until then, it stays at its origin position, and then jumps to the cursor as soon as you move the mouse. I don't know if this is a problem in the rendering itself or in the positioning, I'll investigate on that.
Checking out the branch right now; I will post back after trying around with the new function
-BigG
//Edit:
OK, played around with the new function and I got to say that it works as I wanted it
Yet I have another question/request xD the DragContainer is always kept in a static offset to the cursor when the cursor moves. This offset is set when the dragging starts, calculated from the current DragContainer position and the current Mouse position (I think). Would it be possible to add a function like CEGUI::DragContainer::setMouseCursorOffset taking a CEGUI::UVector2 as parameter where you can specify that offset overwriting the dynamic calculation if set.The current DragContainer position would the be calculated as CursorPosition + MouseCursorOffset. That would make it possible to, for example, keep the item icon aligned to the cursor's head in my case Should not be a big change either
Thanks again
- BigG
//Edit2:
I found a small visual bug:
When calling pickUp(), the DragContainer itself stays where it is until you move the mouse, then it all works fine and it is dynamically aligned (as described above) to the mouse. But until then, it stays at its origin position, and then jumps to the cursor as soon as you move the mouse. I don't know if this is a problem in the rendering itself or in the positioning, I'll investigate on that.
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Re: Manually starting dragging on a DragContainer
Yeah, I saw that issue too (and chose to ignore it ). Should be a simple fix.
CE.
CE.
Useful Links: Forum Guidelines | Documentation | Tutorials | HOWTO | Videos | Donate to CEGUI | CEGUI Twitter
Re: Manually starting dragging on a DragContainer
Hey,
Still couldn't figure out the reason for that bug but I modified the DragContainer class a bit to realise my request about having the DragContainer sticked to the mouse at a fixed offset instead of taking the offset it has when dragging starts. As I do not know how to submit the changes to you, I'll try to do so in this post . Feel free to do whatever you want to do with this code
CEGUIDragContainer.h
In data, add two protected members:
and get/set functions for these:
CEGUIDragContainer.cpp
code of the get/set functions:
and a small change in void DragContainer::doDragging(const Point& local_mouse) - replace
with
and that's it usage is like:
which will, for example, position the DragContainer always at the cursor's head
Maybe it's worth adding this configuration as property settable in the .layout files too (can DragContainers even be created in .layout files? )
I must say, I'm still being impressed by the flexibility of this engine
Greetings,
-BigG
Still couldn't figure out the reason for that bug but I modified the DragContainer class a bit to realise my request about having the DragContainer sticked to the mouse at a fixed offset instead of taking the offset it has when dragging starts. As I do not know how to submit the changes to you, I'll try to do so in this post . Feel free to do whatever you want to do with this code
CEGUIDragContainer.h
In data, add two protected members:
Code: Select all
//! true to always position at a fixed offset to the mouse cursor instead of taking the offset
// from when dragging started
bool d_hasFixedMouseOffset;
//! the fixed mouse offset
UVector2 d_fixedMouseOffset;
and get/set functions for these:
Code: Select all
/*!
\brief
Set the fixed mouse offset moving mode data
\param has_offset
- true to use a fixed offset, false to dynamically calculate it when dragging starts
\param fixed_offset
- UVector2 containing the fixed offset relative to the cursor's position
*/
void setFixedMouseOffset(const bool has_offset, const UVector2& fixed_offset);
/*!
\brief
Retrieve the fixed mouse offset moving mode data
\param has_offset
see setFixedMouseOffset
\param fixed_offset
see setFixedMouseOffset
*/
void getFixedMouseOffset(bool& has_offset,UVector2& fixed_offset);
CEGUIDragContainer.cpp
code of the get/set functions:
Code: Select all
void DragContainer::setFixedMouseOffset(const bool has_offset, const UVector2& fixed_offset)
{
d_hasFixedMouseOffset = has_offset;
d_fixedMouseOffset = fixed_offset;
}
//----------------------------------------------------------------------------//
void DragContainer::getFixedMouseOffset(bool& has_offset, UVector2& fixed_offset)
{
has_offset = d_hasFixedMouseOffset;
fixed_offset = d_fixedMouseOffset;
}
and a small change in void DragContainer::doDragging(const Point& local_mouse) - replace
Code: Select all
offset -= d_dragPoint;
with
Code: Select all
offset -= (d_hasFixedMouseOffset) ? d_fixedMouseOffset : d_dragPoint;
and that's it usage is like:
Code: Select all
this->m_IconDragContainer->setFixedMouseOffset(true,CEGUI::UVector2(cegui_absdim(0),cegui_absdim(0)));
which will, for example, position the DragContainer always at the cursor's head
Maybe it's worth adding this configuration as property settable in the .layout files too (can DragContainers even be created in .layout files? )
I must say, I'm still being impressed by the flexibility of this engine
Greetings,
-BigG
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Re: Manually starting dragging on a DragContainer
I missed the first edit yesterday, which is why I did not respond to it
It turns out the minor glitch is due to not re/setting the drag point when manually picking up the item. While it's possible to set that in the pickUP function ot the cursor offset used elsewhere, this could lead to issues if, for example, some user code decides to 'pick up' an item when the mouse is nowhere near the item being picked up (the item would then be floating in mid-air far from the mouse cursor). So my solution to this part of the issue will be to instead set the drag point to the centre of the DargContainer.
Following on from the above, your suggestion is then even more valuable since it allows the user to effectively customise the above positioning. I may implemented it as two functions or one function with just the offset, firstly because it makes property processing easier and secondly for consistency reasons with the rest of the API (largely the public getters all return the got value as opposed to setting output variables, so while your code as presented is perfectly reasonable, where possible (and I know we fail at times!) it's preferred to keep a consistent approach).
As you may infer from the above mention of properties, yes it's possible to have a DargContainer in a layout, indeed we take this approach in the drag and drop demo layout
CE.
It turns out the minor glitch is due to not re/setting the drag point when manually picking up the item. While it's possible to set that in the pickUP function ot the cursor offset used elsewhere, this could lead to issues if, for example, some user code decides to 'pick up' an item when the mouse is nowhere near the item being picked up (the item would then be floating in mid-air far from the mouse cursor). So my solution to this part of the issue will be to instead set the drag point to the centre of the DargContainer.
Following on from the above, your suggestion is then even more valuable since it allows the user to effectively customise the above positioning. I may implemented it as two functions or one function with just the offset, firstly because it makes property processing easier and secondly for consistency reasons with the rest of the API (largely the public getters all return the got value as opposed to setting output variables, so while your code as presented is perfectly reasonable, where possible (and I know we fail at times!) it's preferred to keep a consistent approach).
As you may infer from the above mention of properties, yes it's possible to have a DargContainer in a layout, indeed we take this approach in the drag and drop demo layout
CE.
Useful Links: Forum Guidelines | Documentation | Tutorials | HOWTO | Videos | Donate to CEGUI | CEGUI Twitter
Re: Manually starting dragging on a DragContainer
Wow, didn't think about that cause for the bug well, about the way to implement the get/set functions, I came across one problem when only having one get/set function for only the offset: there is no way to determine whether the user actually _wants_ the fixed offset on or off. So you'd either need two functions like DragContainer::setFixedCursorOffset and DragContainer::setNoFixedCursorOffset or, similar my approach, two get/set pairs for both variables.
Anyway, I'm happy to see my work helps to improve CEGUI
-BigG
Anyway, I'm happy to see my work helps to improve CEGUI
-BigG
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Re: Manually starting dragging on a DragContainer
You are of course correct - although I would have spotted this deliberate mistake before implementing it (honest! ). I'll attempt to finish this up later this afternoon.
CE.
CE.
Useful Links: Forum Guidelines | Documentation | Tutorials | HOWTO | Videos | Donate to CEGUI | CEGUI Twitter
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Re: Manually starting dragging on a DragContainer
I have added:
functions:
void DragContainer::setFixedDragOffset(const UVector2& offset);
const UVector2& DragContainer::getFixedDragOffset() const;
void DragContainer::setUsingFixedDragOffset(bool enable);
bool DragContainer::isUsingFixedDragOffset() const;
Properties:
FixedDragOffset
UsingFixedDragOffset
I also fixed that issue with the initial position glitch, and also a small bug (not checking whether dragging is even enabled).
CE.
functions:
void DragContainer::setFixedDragOffset(const UVector2& offset);
const UVector2& DragContainer::getFixedDragOffset() const;
void DragContainer::setUsingFixedDragOffset(bool enable);
bool DragContainer::isUsingFixedDragOffset() const;
Properties:
FixedDragOffset
UsingFixedDragOffset
I also fixed that issue with the initial position glitch, and also a small bug (not checking whether dragging is even enabled).
CE.
Useful Links: Forum Guidelines | Documentation | Tutorials | HOWTO | Videos | Donate to CEGUI | CEGUI Twitter
Re: Manually starting dragging on a DragContainer
Thumbs up, CE
Checking out newest revision now and if I find anything, I'll post back^^
-BigG
//Edit:
It's all working flawlessly as far as I tested it thanks again for your help, CE!
Checking out newest revision now and if I find anything, I'll post back^^
-BigG
//Edit:
It's all working flawlessly as far as I tested it thanks again for your help, CE!
Who is online
Users browsing this forum: No registered users and 7 guests