Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic A question about moving selection shape/shapes (Read 3296 times)
CanadaProgrammer
Full Member
***
Offline


I love YaBB 1G - SP1!

Posts: 113
Joined: Jun 30th, 2011
A question about moving selection shape/shapes
Apr 15th, 2013 at 11:40pm
Print Post  
When user move selected shape/shapes, the default behave is to show a visual effection. In my case, I want to show a rectangle, just a rectangle. Is there any easy way to do it? such as to set a value to a property.

Thanks.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: A question about moving selection shape/shapes
Reply #1 - Apr 16th, 2013 at 6:53am
Print Post  
There isn't; you could implement that yourself using a custom behavior class:

Code
Select All
class MoveRectBehavior : LinkShapesBehavior
{
	protected internal MoveRectBehavior(DiagramView diagramView) :
		base(diagramView)
	{
		Diagram.NodeModified += OnNodeModified;
	}

	protected override InteractionState  StartDrawCommon(
		PointF point, System.Windows.Forms.MouseButtons button)
	{
		var ist =  base.StartDrawCommon(point, button);
		if (ist.Action != Action.Modify ||
			ist.CurrentItem is DiagramLink ||
			ist.AdjustmentHandle != 8)
			return ist;

		trackerRect = new ShapeNode
		{
			Obstacle = false,
			Bounds = ist.CurrentItem.GetBounds(),
			Shape = Shapes.Rectangle,
			Brush = new SolidBrush(Color.Transparent),
			ShadowBrush = new SolidBrush(Color.Transparent),
			HandlesStyle = HandlesStyle.InvisibleMove
		};
		Diagram.Nodes.Add(trackerRect);
		return new InteractionState(trackerRect, 8, Action.Modify);
	}

	private void OnNodeModified(object sender, NodeEventArgs e)
	{
		if (e.Node == trackerRect)
		{
			MoveSelection(trackerRect.Bounds.Location);
			Diagram.Nodes.Remove(trackerRect);
			trackerRect = null;
		}
	}

	private void MoveSelection(PointF newPosition)
	{
		var oldPosition = Diagram.Selection.Bounds.Location;
		var ist = new InteractionState(Diagram.Selection, 8, Action.Modify);
		ist.Start(oldPosition, Diagram);
		ist.Update(newPosition, Diagram);
		ist.Complete(newPosition, Diagram);
	}

	ShapeNode trackerRect;
} 



I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
CanadaProgrammer
Full Member
***
Offline


I love YaBB 1G - SP1!

Posts: 113
Joined: Jun 30th, 2011
Re: A question about moving selection shape/shapes
Reply #2 - Apr 17th, 2013 at 11:07pm
Print Post  
Thanks for reply. How about several shapes ?such as 2 nodes and 2 links。
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: A question about moving selection shape/shapes
Reply #3 - Apr 18th, 2013 at 6:38am
Print Post  
The code above can move multiple selected items as well. If you need a rectangle drawn for each item, you could create several temporary nodes at respective positions, select them, and return InteractionState(Diagram.Selection). Or otherwise, enable custom drawing for the currently used single node and draw multiple rectangles corresponding to item positions from the DrawNode event handler.

If using custom drawing code, I suppose you could implement that even without overriding Behavior classes and adding temporary nodes, but just draw selected items at their original positions and draw an additional rectangle from the DrawNode and DrawLink handlers.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
CanadaProgrammer
Full Member
***
Offline


I love YaBB 1G - SP1!

Posts: 113
Joined: Jun 30th, 2011
Re: A question about moving selection shape/shapes
Reply #4 - Apr 18th, 2013 at 1:37pm
Print Post  
Thanks for you reply. Yes, I tried and can implement what I want. But the point is I am not sure this is a best way and it is stable enough. Base on some questions that asked you, I know that if user select several shapes and try to move it, then I only can customize my InteractionState object in OnMouseMove method of ModifyBehavior. So far there are three choices:

1. Without calling base.OnMouseMove and create my InteractionState object:
protected override void OnMouseMove(Point mousePosition)
{
     InteractionState state = this.Diagram.Interaction;
     PointF pointDoc = this.DiagramView.ClientToDoc(mousePosition);
     
     if (IsReadyToMoveMultiShapes(pointDoc, state) == true)
     {
           this.Diagram.Interaction = new InteractionState(this.trackerShape, 8, MindFusion.Diagramming.Action.Modify);
           this.Diagram.Interaction.MouseMoved = true;
           this.Diagram.Interaction.Start(pointDoc, this.Diagram);
     }

     ...      // other code here
}
But this way cause a exception is thrown

2. Calling base.OnMouseMove and create my InteractionState object:
protected override void OnMouseMove(Point mousePosition)
{
     InteractionState state = this.Diagram.Interaction;
     PointF pointDoc = this.DiagramView.ClientToDoc(mousePosition);

     if (IsReadyToMoveMultiShapes(pointDoc, state) == true)
     {
           base.OnMouseMove(mousePosition);

           this.Diagram.Interaction = new InteractionState(this.trackerShape, 8, MindFusion.Diagramming.Action.Modify);
           this.Diagram.Interaction.MouseMoved = true;
           this.Diagram.Interaction.Start(pointDoc, this.Diagram);
     }
     ...      // other code here
}
This way can work but when user is moving shape there are some problems, I fix all expcept one. The left problem is when user is moving trackerShape, trackerShape covers these links that connect to selected shapes. So I choose third way

3. Without calling base.OnMouseMove, create my InteractionState object and move trackerShape by myself:
protected override void OnMouseMove(Point mousePosition)
{
     InteractionState state = this.Diagram.Interaction;
     PointF pointDoc = this.DiagramView.ClientToDoc(mousePosition);

     if (IsReadyToMoveMultiShapes(pointDoc, state) == true)
     {
           this.Diagram.Interaction = new InteractionState(this.trackerShape, 8, MindFusion.Diagramming.Action.Modify);
           this.Diagram.Interaction.MouseMoved = true;
           this.Diagram.Interaction.Start(pointDoc, this.Diagram);
     }
     else if (state != null &&
            (state.CurrentItem is TrackerNode) == true &&
            state.Action == MindFusion.Diagramming.Action.Modify)
     {
           TrackerNode item = (TrackerNode)state.CurrentItem;

           rect.X = pointDoc.X - state.StartPoint.X + item.OriginX;
           rect.Y = pointDoc.Y - state.StartPoint.Y + item.OriginY;
           item.Move(rect.X, rect.Y);
     }

     ...      // other code here
}
This is the way I choose and looks can work well so far. But compare with your code, your code is simple, I like it.

So could you give me a better way that is simpler and stabler to do same thing ? We will buy new version maybe include source code sooner or later. Because of:
1. This is a good production
2. we will not choose other production and spend extra time to learn new SDK.

So do not worry we are stable customers. Thanks a lot.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: A question about moving selection shape/shapes
Reply #5 - Apr 19th, 2013 at 7:09am
Print Post  
Why would you want it done from OnMouseMove instead of StartDrawCommon, are you using old version where it's not available? In such case, check if your version has an overridable BehaviorBase.ShouldMoveSelection method. You could return false from it to prevent the base class from moving the multiple selection, and run the above code from StartDraw instead of StartDrawCommon.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
CanadaProgrammer
Full Member
***
Offline


I love YaBB 1G - SP1!

Posts: 113
Joined: Jun 30th, 2011
Re: A question about moving selection shape/shapes
Reply #6 - Apr 19th, 2013 at 8:19pm
Print Post  
Thanks. After spending hours I made it. But I found a new problem. Because it is a new topic so I post a new thread.
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint