Hello,
The SubGraphApp included in Samples allows dragging in & out when of subgraphs when you hold the shift key.
Thank you. I got it.
Jake,
If you look at SubGraphDraggingTool in SubGraphApp, you see the line
if (MustBeMoving() && this.Selection.Primary != null) {
in DoDragging… and that’s where it does the drag in / drag out logic.
GoToolDragging.MustBeMoving() returns true if the Shift key is down.
so, if you add this override in SubGraphDraggingTool :
public override bool MustBeMoving() { return true; }
you get a SubGraphApp where everything is a forced move.
And a side effect is that GoView. DragsRealtime is turned off, which also hurts usability.
If you use the BoxArea example class in Demo1 instead of GoSubGraph, you can get the effect you want pretty easily.
I have put up a modified version of BoxArea: http://www.nwoods.com/forum/uploads/BoxArea.cs. This also requires implementing a GoView.BackgroundSelectionDropped event handler, as shown in http://www.nwoods.com/forum/uploads/GraphView.cs. You can replace these two files in your 2.6.2 Demo1 sample directory.
This code works whether GoView.DragsRealtime is true or false.
It also allows the user to resize the BoxArea explicitly or to extend it a little bit to automatically include the GoView.Selection if, when the selection is dropped, it extends past (crosses over) the border.
The GoView.BackgroundSelectionDropped event handler handles the case of dragging something out of a BoxArea without dropping it into another BoxArea.
- Dragging multiple selected nodes into a box. Still can drag box(es) with nodes in it(them) and drop into another box (very similar to subgraph in subgraph).
- Dragging entity inside box.
- Dragging entity out of the box.
- The layouts could be different inside box and outside of box.
The BoxArea sample inherits from GoSubGraphBase. It doesn’t have support for collapse/expand or CollapsedObject, or the same model for defining the border. But if you need those features, you could implement them yourself in the BoxArea class
Walter,
Hi,
Are you using Express or full GoDiagram?
I’m using the full version for this.
for #1, are you talking about resizing the BoxArea, or dragging it over some other objects?
same question for #2… dragging, resizing or both? Are you using a Grid?
This handles #2 for the dragging case, add this to the BoxArea class
// this DoMove prevents a BoxArea from being moved so that it intersects with another BoxArea.
public override void DoMove(GoView view, PointF origLoc, PointF newLoc) {
PointF pnt = ComputeMove(origLoc, newLoc);
// compute bounds if we were to move the box
RectangleF r = this.Bounds;
r.X = pnt.X;
r.Y = pnt.Y;
// pick any objects that intersect with this BoxArea
GoCollection picks = (GoCollection)view.Document.PickObjectsInRectangle(r, GoPickInRectangleStyle.SelectableOnlyIntersectsBounds, null, 999999);
foreach (GoObject o in picks) {
if (o is BoxArea && o != this) {
pnt = origLoc;
break;
}
}
this.Location = pnt;
}
#1 Both if possible. I’d like to have the Box area in my palette, and when its dropped onto the document, if a node is inside, that node to become a member of the BoxArea. If the BoxArea is then resized to include another node, this should also be included.
foreach (GoObject obj in view.Selection)
{
if (obj is BoxArea && obj != this)
{
return false;
}
}
This handles drop from a palette and drop within a view, and adds the contained objects to BoxArea. (Note this is an extension of the existing BoxArea sample code for handling BackgroundSelectionDropped.
in your GoView class:
// Needed for BoxArea
protected override void OnBackgroundSelectionDropped(GoInputEventArgs evt) {
BoxArea box = this.Selection.Primary as BoxArea;
if (box != null && this.Selection.Count == 1) {
// pick any objects that are contained with this BoxArea
GoCollection within = (GoCollection)this.Document.PickObjectsInRectangle(box.Border.Bounds, GoPickInRectangleStyle.SelectableOnlyContained, null, 999999);
box.AddCollection(within, true);
}
else {
bool wasinbox = false;
foreach (GoObject obj in this.Selection) {
if (obj.Parent is BoxArea) {
wasinbox = true;
break;
}
}
if (wasinbox) {
// add all selected objects as top-level objects in the DefaultLayer
this.Document.DefaultLayer.AddCollection(this.Selection, true);
}
}
base.OnBackgroundSelectionDropped(evt);
}
Want to try the resizing code on your own? You should have enough of the flavor now…
oh… my OnBackgroundSelectionDropped code doesn’t avoid adding a BoxArea to a BoxArea. Just create a within2 collection and iterate within, adding all non-BoxArea objects to within2.
Thanks for all your help Jake,
I've implemented the resize functionality, with your code samples it was easy! One small thing, sometimes, when I drag a BoxArea over a node, the OnBackgroundSelectionDropped function does not get called. Any ideas?