MDI (MultiDocumentPanel) Question


#1

Hi,

I’ve modified and extended the MultiDocumentPanel to handle things like dockable windows, draggable tabs, etc. I’ve also added functionality that allows you to drag a window, tab, etc. out of the panel to the desktop… very much like Photoshop CS4, etc.

Getting the window to the desktop is the easy part, but I want to be able to drag them back into the panel as well. I have several DnD targets in the panel, for example; between tabs, between docked windows, etc.

What’s the least hacky way to allow those DnD targets to detect the heavyweight window being dragged/dropped into them? Any ideas? Am I missing something obvious?

thx.


#2

Sounds cool. The D+D target gets a pointer to the original component that’s being dragged, so what I often do is to dynamic_cast that component into something that can provide whatever extra information you need about the drag operation.


#3

right, except I can’t get a pointer on the source window if isInterestedInDragSource isn’t even being called :wink: I assumed that was because the panel DnD targets aren’t getting any events when it’s a heavyweight window being dragged over it(?). Maybe I missed something else?


#4

Oh I see. Well, if you’re not using the d+d mechanism, you’d need to just follow the mouse position yourself and search for whatever’s underneath it. Bit fiddly, but possible.


#5

Hello!
I just recreated a Visual Studio like layout, without using multiDocumentPanel.
Basically it’s just a set of nested stretchableLayoutManager classes.
I really would like to see your code!
Mine does exactly the same things as yours: docking, tabs, windows, except for it’s not using multiDocumentPanel.
Would you like to share it? I can give you mine!


#6

thx for the tip! I ended up doing a combination of both, since this gives the same effect as CS4 when the window is over a DnD target the window goes semi transparent, which I like… for example:

[code]void MDIPanelWindow::mouseDrag(const MouseEvent& e)
{
MDIPanel* const owner = getOwner();

if (owner) // we're already in a panel
{
	//... etc.
}
else // we're on the desktop
{
	MDIPanel* const panel = getPanelAt(e.getScreenX(), e.getScreenY());

	// if a panel exists beneath us and were over one of it's targets...
	if (panel && dynamic_cast<MDIDnDTarget*>(panel->getComponentAt(e.getEventRelativeTo(panel).x, e.getEventRelativeTo(panel).y)))
	{
		// ...then swap the real window with the DnD comp
		if (!isDragAndDropActive())
		{
			setVisible(true);
			startDragging(this->getName(), this, 0, true);

			// enforce position and visibility...
			setOffsets(e.getScreenX(), e.getScreenY());
			getDragImageComponent()->setAlwaysOnTop(true);
		}
		else
			setVisible(false);

		getDragImageComponent()->setVisible(true);
	}
	else // swap the DnD comp with the real window...
	{
		setVisible(true);

		if (getDragImageComponent())
			getDragImageComponent()->setVisible(false);

		DocumentWindow::mouseDrag(e);
	}
}

}[/code]


#7

Hey why don't you both share code to all us. it would help others too. I was also thinking to do something like dockable windows. 

If possible please share code to useful tools and components section. 

 

Thanks.


#8

+1. looking at making something like this myself