Page Index Toggle Pages: [1] 2  Send TopicPrint
Hot Topic (More than 10 Replies) Ways to generate ShapeNode (Read 10103 times)
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Ways to generate ShapeNode
Aug 31st, 2020 at 1:02pm
Print Post  
Hi, Slavcho Smiley

protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
     diagram.ModifierKeyActions.Control = ModifierKeyAction.None;
     if (Keyboard.Modifiers == ModifierKeys.Control)
     {
           diagram.Behavior = Behavior.DrawShapes;
     }
     else
     {
           diagram.Behavior = Behavior.Modify;
     }
}

I can achieve it after using this code. However, another ShapeNode cannot be dragged while holding down the left mouse button. How do I need to change it?

Any assistance would be appreciated.

Cheers,

Best regards.
  

8_31_7.png (Attachment deleted)
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3447
Joined: Oct 19th, 2005
Re: Ways to generate ShapeNode
Reply #1 - Sep 1st, 2020 at 6:24am
Print Post  
Hi,

Best create a custom Behavior-derived class to implement all your custom logic instead of handling the multiple mouse events so far. Search the forum for "StartDraw" to find many examples. So you'd want your StartDraw override to immediately return InteractionState(new ShapeNode(), Create) if Ctrl key is down, and otherwise call base implementation to move / resize nodes as usual.

Regards,
Slavcho
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Ways to generate ShapeNode
Reply #2 - Sep 1st, 2020 at 7:41am
Print Post  
Thanks, Slavcho Smiley

I tried to create a new custom Behavior-derived class to implement InteractionState (new ShapeNode(), Create), but I need to enter a Diagram parameter in the parameter list of the constructor. I have instantiated it in xaml, why should I report an error? Shouldn't it be created like this? How can I modify it? Could you write an example of such a subclass for me? According to all previous mouse click events implemented into this class. I really need it.

Best regards.
  

9_1_1.png (Attachment deleted)
9_1_2.png (Attachment deleted)
9_1_3.png (Attachment deleted)
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Ways to generate ShapeNode
Reply #3 - Sep 1st, 2020 at 8:09am
Print Post  
Hi, Slavcho Smiley

I don’t understand this format. Does prototype refer to a collection of functions? I have not seen this format. Why "=" can be directly connected to a "{}", and what does the left and right sides of the format ":" mean?

Best regards.
  

9_1_4.png (Attachment deleted)
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3447
Joined: Oct 19th, 2005
Re: Ways to generate ShapeNode
Reply #4 - Sep 1st, 2020 at 11:50am
Print Post  
That's JavaScript code. Search only in the WPF forums to find .NET examples.

Regards,
Slavcho
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Ways to generate ShapeNode
Reply #5 - Sep 1st, 2020 at 1:18pm
Print Post  
Hi, Slavcho Smiley

Before I implement this code, the ShapeNode with the green border can be dragged, as shown in Figure 8_31_7, but after implementing this code, it won’t work. I found the following example in the WPF forum:

diagram.CustomBehavior = new SelectionBehaviorEx(diagram);

class SelectionBehaviorEx : LinkShapesBehavior
{
     protected internal SelectionBehaviorEx(Diagram diagram) :
           base(diagram)
     {
     }

     public override InteractionState StartDraw(Point point)
     {
           var interaction = base.StartDraw(point);

           if (interaction.Action == Action.Modify &&
                 interaction.AdjustmentHandle == 8 /* move */ &&
                 interaction.CurrentItem is DiagramNode)
           {
                 // select extra nodes
                 Diagram.Nodes[1].Selected = true;
                 return new InteractionState(Diagram.Selection,
                       interaction.AdjustmentHandle, interaction.Action);
           }

           return interaction;
     }
}

But I don't know the implementation part very well, and I tried to create a new class in my project to inherit from LinkShapesBehavior, but it still reported that Diagram was not instantiated. Shouldn't Diagram have been instantiated in xaml? As shown in Figure 9_1_2. How can I achieve this with code?

Best regards.
  

9_1_6.png (Attachment deleted)
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3447
Joined: Oct 19th, 2005
Re: Ways to generate ShapeNode
Reply #6 - Sep 2nd, 2020 at 6:31am
Print Post  
This class always draws new nodes when Ctrl is pressed, even if over a handle, and otherwise lets you modify selected nodes:

Code
Select All
class RectanglesBehavior : DrawShapesBehavior
{
	public RectanglesBehavior(Diagram diagram) : base(diagram)
	{
	}

	public override InteractionState StartDraw(Point point)
	{
		Diagram.ModifierKeyActions.Control = ModifierKeyAction.None;
		if (Keyboard.Modifiers == ModifierKeys.Control)
			return new InteractionState(new ShapeNode(Diagram), null, Action.Create);

		var selected = Diagram.ActiveItem as ShapeNode;
		if (selected != null )
		{
			var handle = selected.HitTestHandle(point);
			if (handle != null)
				return new InteractionState(selected, handle, Action.Modify);
		}

		/*
		var rect = NearestRect(point);
		if (rect != null)
		{
			var handlesStyle = rect.HandlesStyle;
			rect.HandlesStyle = HandlesStyle.SquareHandles2;
			var handle = rect.HitTestHandle(point);
			rect.HandlesStyle = handlesStyle;
			if (handle != null)
				return new InteractionState(rect, handle, Action.Modify);
		}*/

		return base.StartDraw(point);
	}

	/*public override CursorHint SetMouseCursor(Point point, out bool startInteraction)
	{
		return base.SetMouseCursor(point, out startInteraction);
	}*/

	/*protected override void OnMouseUp(Point mousePosition, MindFusion.Diagramming.Wpf.MouseButton mouseButton)
	{
		base.OnMouseUp(mousePosition, mouseButton);
	}*/

	DiagramNode NearestRect(Point point)
	{
		DiagramNode nearest = null;
		double minDist = double.MaxValue;
		foreach (var node in Diagram.Nodes)
		{
			if (node.Locked)
				continue;
			var dist = DistToRect(point, node.Bounds);
			if (dist < minDist)
			{
				minDist = dist;
				nearest = node;
			}
		}
		return nearest;
	}

	double DistToRect(Point point, Rect rect)
	{
		var v = new[]
        {
        	new Point(rect.Left, rect.Top),
			new Point(rect.Right, rect.Top),
			new Point(rect.Right, rect.Bottom),
			new Point(rect.Left, rect.Bottom),
        };
		double minDist = double.MaxValue;
		for (var i = 0; i < 4; i++)
		{
			var v1 = v[i];
			var v2 = v[(i + 1) % 4];
			var dist = MindFusion.Utilities.DistToLineSegment(point, v1, v2);
			if (dist < minDist)
				minDist = dist;
		}
		return minDist;
	}
}

diagram.ModifierKeyActions.Control = ModifierKeyAction.None;
diagram.CustomBehavior = new RectanglesBehavior(diagram);
 



With that, you will not need the MouseDown override from your other forum post. If you uncomment the var rect = NearestRect(point) part, it will also let you resize non-selected nodes by grabbing their border. If you want different priorities for handles / border dragging / creation, just rearrange the code.

You might want to override the SetMouseCursor method too, so it does not show resize cursors when Ctrl is down over a handle. You could also move your selection code from previous posts to the MouseUp override in custom behavior class, to keep all the interaction logic together.

Regards,
Slavcho
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Ways to generate ShapeNode
Reply #7 - Sep 4th, 2020 at 3:40am
Print Post  
Thank you very much, Slavcho Smiley

What is the reason why the display context of the diagram here does not exist?

Let me talk about my understanding. Do you see it right? It is to rewrite all the message processing events of the previous diagram into this RectanglesBehavior class. The function of this class is to generate a custom ShapeNode graph, including its attributes and triggers. The event is finally displayed in the diagram. The advantage of the comparison is that it is directly processed as a class object. But there is one thing I don't understand. How to trigger the generation of this custom ShapeNode graph?

Best regards.
  

9_4_0.png (Attachment deleted)
9_4_1.png (Attachment deleted)
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3447
Joined: Oct 19th, 2005
Re: Ways to generate ShapeNode
Reply #8 - Sep 4th, 2020 at 11:12am
Print Post  
If you mean the underlined diagram.ModifierKeyActions and diagram.CustomBehavior assignments from screenshot, that should not be inside your RectanglesBehavior class file, but a part of diagram's initialization code - e.g. in your Window_Loaded handler. Once you set CustomBehavior, the diagram will start calling its StartDraw function where you determine exactly how to proceed depending on modifier keys, what's at mouse position etc.

Regards,
Slavcho
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Ways to generate ShapeNode
Reply #9 - Sep 4th, 2020 at 12:30pm
Print Post  
Thanks, Slavcho Smiley

In response to the current problems, I described the following points:
1. What does the attribute ModifierKeyActions.Control of the graph refer to?
2. I placed it and the instance of CustomBehavior in the Window_Loaded event of the main window, but after starting the program, double-clicking the left mouse button on the graph did not enter the breakpoint set by the StartDraw of RectangleBehavior. The strange phenomenon is to hold down the Ctrl key and double-click the left mouse button or click repeatedly, sometimes inexplicably enter. What is the problem, please? How to correct it?
3. If I want to create the required graphic style, am I need to change the parameter MindFusion.Diagramming.Wpf.Action.Create in InteractionState? If not, how to modify it?

Best regards.
  

9_4_2.png (Attachment deleted)
9_4_4.png (Attachment deleted)
9_4_5.png (Attachment deleted)
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3447
Joined: Oct 19th, 2005
Re: Ways to generate ShapeNode
Reply #10 - Sep 7th, 2020 at 7:02am
Print Post  
ModifierKeyActions.Control specifies how the diagram treats the Ctrl key. By default it's set to ModifierKeyAction.Select and Ctrl draws selection lasso. Since you want custom processing for Ctrl, better set the action to None as in the example, to avoid it interfering with your code.
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3447
Joined: Oct 19th, 2005
Re: Ways to generate ShapeNode
Reply #11 - Sep 7th, 2020 at 7:03am
Print Post  
StartDraw is called when you drag with the mouse, and not for double-clicking.
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Ways to generate ShapeNode
Reply #12 - Sep 7th, 2020 at 7:58am
Print Post  
Thank you so much, Slavcho, you are right! Smiley

How to change the ShapeNode style in this code: return new InteractionState(new ShapeNode(Diagram), null, MindFusion.Diagramming.Wpf.Action.Create);
And what type of InteractionState refers to and what is included?

According to the idea you prompted me before: all the settings of custom graphics properties and its behavior should be written into this custom class RectanglesBehavior.
The NodeDoubleClicked event written in the main window before: to achieve a custom ShapeNode drawn in the instance of Diagram by double-clicking the left mouse button while holding down the Ctrl key. How can I re-implement it in this custom class RectanglesBehavior?
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3447
Joined: Oct 19th, 2005
Re: Ways to generate ShapeNode
Reply #13 - Sep 7th, 2020 at 8:29am
Print Post  
If you prefer adding nodes from double-click instead of drawing with mouse, keep using the Diagram.DoubleClicked event. You can still handle it within the behavior class to keep interaction code together. If you don't want to ctrl+mouse draw, remove the InteractionState(Create) code from StartDraw, but keep the InteractionState(Modify) code to allow resizing nodes by borders.
  
Back to top
 
IP Logged
 
JackPan
Full Member
***
Offline


I Love MindFusion!

Posts: 134
Joined: Apr 9th, 2020
Re: Ways to generate ShapeNode
Reply #14 - Sep 7th, 2020 at 8:45am
Print Post  
Thanks, Slavcho Smiley

I want to change the style of ShapeNode drawn by Ctrl + mouse to rectangle. How do I achieve this?
I need Ctrl+mouse drawing and Ctrl+double-click to exist and do not affect each other. How do I achieve this?
Can Ctrl+double-click also be placed in the custom class RectanglesBehavior?
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: [1] 2 
Send TopicPrint