>>I have no idea how a wiki page would be written differently from a manual page
I think the main difference is that the wiki entries are standalone topics whereas a manual would show a progression of topics. In a way the manual could go through the source code to explain the basic widgets and then go through the wiki to show what could be built from these basic widgets. This is sort of what I'm doing with the drag and drop thing (and what I've apparently done with nearly everything I've contributed so far). From basic widgets I'm building something bigger. It should cover most situations but if it does not then hopefully that programmer can modify the wiki to let everyone benefit.
Need help with Drag and Drop for Wiki how-to
Moderators: CEGUI MVP, CEGUI Team
CrazyEddie wrote:new setting that I'll be putting in to allow a window to 'opt out' of getting those events.
I'm not sure if that's the answer. Let's say that (for whatever reason) I have a DropTarget with 4 children arranged in a 2x2 grid that entirely covers the DropTarget window. These 4 children will opt out and not receive the events but would the DropTarget receive them? That window is the one that's really interested the drag and drop events, not its children.
Or maybe you meant that the children would not trigger the EventDragDropTargetChanged, which is what I've resorted to in my code. Hrm, I'll try to post an alpha version very soon. Hopefully it can provide some idea of what I'm working on / talking about. Here's a preview.
This is within the DragItem class:
Code: Select all
// Register events to override their behavior
Window* dragWindow = WindowManager::getSingleton().getWindow(mWindow);
dragWindow->subscribeEvent(DragContainer::EventDragDropTargetChanged, Event::Subscriber(&DragItem::handleDropTargetChanged, this));
dragWindow->subscribeEvent(DragContainer::EventDragEnded, Event::Subscriber(&DragItem::handleDragEnded, this));
//---------------------------------------------------------------------------
bool DragItem::handleDropTargetChanged(const CEGUI::EventArgs& args)
{
// This code ensures that the "enter" and "leave" events are generated only
// once even when dragging over the children of a drag item
// We only care if our target is a drop target or if we are over a drag item
// slotted into a drop target.
using namespace CEGUI;
const DragDropEventArgs& ddea = static_cast<const DragDropEventArgs&>(args);
// Check if we're over a drop target
DropTarget* newDropTarget = DropTarget::findDropTarget(ddea.window->getName());
if(!newDropTarget)
{
// Not over a drop target so check if we're over a drag item slotted into a DropTarget
Window* parent = ddea.window;
while(parent)
{
if(parent->testClassName(CEGUI::DragContainer::WidgetTypeName))
{
// We found a drag item
//newDropTarget = DropTarget::findDropTarget(parent->getName());
DragItem* dragItem = findDragItem(parent->getName());
if(dragItem)
newDropTarget = dragItem->getDropTarget();
break;
}
parent = parent->getParent();
}
}
// Trigger the "leaves" and "enter" events to the appropriate windows
if( !(mHoveringDropTarget
&& newDropTarget
&& mHoveringDropTarget->getWindow().compare(newDropTarget->getWindow()) == 0) )
{
if(mHoveringDropTarget)
mHoveringDropTarget->onDragItemLeave(this);
if(newDropTarget)
newDropTarget->onDragItemEnter(this, newDropTarget->isValid(this));
mHoveringDropTarget = newDropTarget;
}
return true;
}
//---------------------------------------------------------------------------
bool DragItem::handleDragEnded(const CEGUI::EventArgs& args)
{
using namespace CEGUI;
if(mHoveringDropTarget && mHoveringDropTarget->isValid(this))
{
//mHoveringDropTarget->onDragItemDropped(this);
DragDropConfig::getSingleton().processDrop(getDropTarget(), this, mHoveringDropTarget);
}
return true;
}
DragDropConfig is my latest addition, to handle the cases I've mentioned recently, moving a DragItem from spellbook to spellbook, spellbook to toolbar, and toolbar to toolbar.
I have tested the case of a DropTarget containing 1 child, which does not interfere with my processing. Next test would be a DropTarget with multiple children.
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Rackle wrote:CrazyEddie wrote:new setting that I'll be putting in to allow a window to 'opt out' of getting those events.
I'm not sure if that's the answer. Let's say that (for whatever reason) I have a DropTarget with 4 children arranged in a 2x2 grid that entirely covers the DropTarget window. These 4 children will opt out and not receive the events but would the DropTarget receive them? That window is the one that's really interested the drag and drop events, not its children.
If the drop target (i.e. the one that want's the events) has the option enabled, and all the child 'items' do not, even if the entire drop target is obscured by it's children it will be the drop target that gets the events. Also, it's not some hack whereby the children "pass it on", it's all done properly The only event generated is by the window that ultimately wanted the drop notification.
I actually implemented this yesterday (for inclusion in future releases). If you want to try it out (not for the tutorial, but to check the behaviour), then you could try the latest code in "cegui_mk2/branches/v0-5" - the members are called isDragDropTarget / setDragDropTarget, and the property is "DragDropTarget" - all are booleans.
CE.
>> it's all done properly
I don't doubt it.
>> isDragDropTarget() and setDragDropTarget()
Sounds like any window can become a DropTarget, including a listbox, which allows items to be dropped onto the listbox to add entries...fun possibilities.
>> try the latest code
I've looked at onDragPositionChanged() which compares the window under the DragItem to the old d_dropTarget. Seems like there would be multiple enter/leave events fired for a single DropTarget composed of multiple items.
This would not handle the case of a DropTarget having multiple child windows stacked one on top of the other.
Grr, I'm going to be late for work...
I don't doubt it.
>> isDragDropTarget() and setDragDropTarget()
Sounds like any window can become a DropTarget, including a listbox, which allows items to be dropped onto the listbox to add entries...fun possibilities.
>> try the latest code
I've looked at onDragPositionChanged() which compares the window under the DragItem to the old d_dropTarget. Seems like there would be multiple enter/leave events fired for a single DropTarget composed of multiple items.
Code: Select all
if ((d_dropTarget != 0) && !d_dropTarget->isDragDropTarget())
d_dropTarget = d_dropTarget->getParent();
This would not handle the case of a DropTarget having multiple child windows stacked one on top of the other.
Grr, I'm going to be late for work...
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Rackle wrote:Code: Select all
if ((d_dropTarget != 0) && !d_dropTarget->isDragDropTarget())
d_dropTarget = d_dropTarget->getParent();
This would not handle the case of a DropTarget having multiple child windows stacked one on top of the other.
Gah! Thanks for that - the 'if' should be a 'while'.
CE.
I finally came up with a scenario where the number of enter and leave events is important (I can't seem to let go of that point). If I play a sound when a drag item enters a drop target and another when it leaves that drop target then I would play those sounds too often.
I would modify the code within onDragPositionChanged to something like this:
However it does not handle dropping a DragItem into emptiness/emptyness, such as when removing a slotted DragItem from a DropTarget/toolbar. Maybe something along the lines of:
would work (this is a revised version of the IF after the WHILE)..
I would modify the code within onDragPositionChanged to something like this:
Code: Select all
Window* eventWindow = root->getChildAtPosition(MouseCursor::getSingleton().getPosition());
d_enabled = wasEnabled;
if (eventWindow)
{
while((eventWindow != 0) && !eventWindow->isDragDropTarget())
eventWindow = eventWindow->getParent();
if (eventWindow && eventWindow != d_dropTarget)
{
DragDropEventArgs args(eventWindow);
args.dragDropItem = this;
onDragDropTargetChanged(args);
}
}
However it does not handle dropping a DragItem into emptiness/emptyness, such as when removing a slotted DragItem from a DropTarget/toolbar. Maybe something along the lines of:
Code: Select all
if (!eventWindow || eventWindow && eventWindow != d_dropTarget)
{
if(!eventWindow)
eventWindow = System::getSingleton().getGUISheet(); // root
would work (this is a revised version of the IF after the WHILE)..
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Well, to be honest I can't see how there can be multiple events fired for attached item windows if they have the DragDropTarget setting at False.
As it stands now (fixed with the while, of course), notifyDragDropItemEnters is only ever called for a window that has DragDropTarget set to true, and therefore such windows are also the only ones to ever have notifyDragDropItemLeaves on them. Thus, if all "items" attached to a target have this setting disabled, you will only ever get the notifications, and therefore the events fired, on the parent window which is enabled as a drop target window.
You actually have me doubting myself a little, so I will test the scenario you describe tomorrow - just to be sure!
CE.
As it stands now (fixed with the while, of course), notifyDragDropItemEnters is only ever called for a window that has DragDropTarget set to true, and therefore such windows are also the only ones to ever have notifyDragDropItemLeaves on them. Thus, if all "items" attached to a target have this setting disabled, you will only ever get the notifications, and therefore the events fired, on the parent window which is enabled as a drop target window.
You actually have me doubting myself a little, so I will test the scenario you describe tomorrow - just to be sure!
CE.
Re: Need help with Drag and Drop for Wiki how-to
Draging from toolbar and dropping to workspace window in Lua
I use getChildAtIdx(1), because I have two windows attached to DragContainer. One of which is visible only when dragging, and second is visible when showing on toolbar.
Code: Select all
function handleDragDropped(args)
local dragContainer = CEGUI.toDragDropEventArgs(args).dragDropItem;
local staticWindow = CEGUI.toDragDropEventArgs(args).window;
local clonedWindow = dragContainer:getChildAtIdx(1):clone("root/Workspace/Operator"..tostring(G_wndId), false);
G_wndId = G_wndId + 1;
clonedWindow:setVisible(true);
local pos = CEGUI.CoordConverter:screenToWindow(staticWindow, dragContainer:getPosition());
local parentSize = dragContainer:getParentPixelSize();
local parentPos = dragContainer:getParent():getPosition():asAbsolute(parentSize);
clonedWindow:setPosition(CEGUI.UVector2(CEGUI.UDim(0,pos.x+parentPos.x),CEGUI.UDim(0,pos.y+parentPos.y)));
clonedWindow:setSize(CEGUI.UVector2(CEGUI.UDim(0,64),CEGUI.UDim(0,18)));
staticWindow:addChildWindow(clonedWindow);
end
...
winMgr:getWindow("root/Workspace"):subscribeEvent("DragDropItemDropped", "handleDragDropped");
G_wndId = 0;
I use getChildAtIdx(1), because I have two windows attached to DragContainer. One of which is visible only when dragging, and second is visible when showing on toolbar.
helper to newbies
"i help you, dear newbie
but nobody helps me!"
"i help you, dear newbie
but nobody helps me!"
Return to “Modifications / Integrations / Customisations”
Who is online
Users browsing this forum: No registered users and 3 guests