Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Any easy way to make ContainerNode resizable? (Read 5036 times)
David Cater
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 12
Joined: May 12th, 2012
Any easy way to make ContainerNode resizable?
Oct 29th, 2012 at 12:58pm
Print Post  
I am about to add support to my program that will allow my users to create grouped "panels" of controls. The goal is to allow them to move the controls as a group, hide/show them as a group, and style the group (perhaps showing the panel as a raised or sunken box, for example, to visually distinguish it from the other parts of the diagram).

I'm starting by looking at the ContainerNode object. That looks like it has some real potential, but I don't see any easy way to allow it to be resized manually. It automatically adjusts its size to fit the elements that it contains.

My users use the program to create detailed & intricate circuit board diagrams, and they want very precise control over how everything is laid out. They won't be happy with a control that decides for itself how big it's going to be.

I have the WpfDiagram source code, so I'm going to be looking at modifying the ContainerNode to allow resizing. In the meantime, though, I thought I'd ask the question to see if there was some easy mechanism that I'm overlooking.

Thanks,

David Cater
  
Back to top
 
IP Logged
 
David Cater
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 12
Joined: May 12th, 2012
Re: Any easy way to make ContainerNode resizable?
Reply #1 - Oct 29th, 2012 at 1:33pm
Print Post  
I'm going to start answering my own question. It's going to take some work to get it all working the way I want, but the first steps turned out to be easy. The ContainerNode can't be resized because of the EnabledHandles setting. I was able to get resizing and appropriate move behavior by modifying the node in Xaml:

Code (HTML)
Select All
<diag:ContainerNode EnabledHandles="ResizeHandles,Move" HandlesStyle="EasyMove" /> 

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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Any easy way to make ContainerNode resizable?
Reply #2 - Oct 29th, 2012 at 2:14pm
Print Post  
Hi,

ContainerNodes resize automatically mostly because they do not support scrolling and clipping for the child nodes at this time. If you enable resizing containers manually, you could set MinWidth and MinHeight in their Constraints to disallow making containers smaller than their content. You might also try overriding the OnChildModified method in a custom container class to restore Bounds to its value from before calling the base method.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
David Cater
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 12
Joined: May 12th, 2012
Re: Any easy way to make ContainerNode resizable?
Reply #3 - Oct 29th, 2012 at 2:38pm
Print Post  
Yes, it does.  I think using MinWidth/MinHeight will be the way to go, in addition to handling what happens when a node is dragged partway out of the container. 

I was also looking at what happens when you drag a node from NodeListView into the Diagram.  It looks like you can't drag a node directly into a container, because the drag handling you get when starting a drag from within the diagram is different from the drag handling when starting the drag in NodeListView.  From looking at the code, it doesn't look like there is a quick solution for that, so I suspect I'll just tell my users they need to drag the item into the diagram, and then drag it again to put it into the container.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Any easy way to make ContainerNode resizable?
Reply #4 - Oct 29th, 2012 at 3:04pm
Print Post  
Drag and drop from the NodeListView should raise NodeCreated event. You can handle it by calling container.Add(e.Node) if you detect there is a container behind the new node. Here is some sample code that should do that, where "node" is the new node:

Code
Select All
var nodes = diagram.GetNodesAt(node.GetCenter());
if (nodes.Count > 1 && nodes[1] is ContainerNode)
{
	((ContainerNode)nodes[1]).Add(node);
} 



I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
David Cater
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 12
Joined: May 12th, 2012
Re: Any easy way to make ContainerNode resizable?
Reply #5 - Oct 29th, 2012 at 4:44pm
Print Post  
Excellent!  I still need to make the container node highlight when a drop will add a node to the container, but that shouldn't be too bad.

I believe I'm going to do a cheap sort of clipping by watching for the bounds of the container node to change and dynamically setting the Visibility of the contained nodes if any part of them fall outside the bounds of the container node.  Not ideal, but I'm sure my client doesn't want partial elements being shown anyway.
  
Back to top
 
IP Logged
 
David Cater
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 12
Joined: May 12th, 2012
Re: Any easy way to make ContainerNode resizable?
Reply #6 - Oct 29th, 2012 at 4:49pm
Print Post  
FWIW, it's also worth noting that I need to re-template the container node.  I want to be able to visually style it as well as add my own functionality.  In particular, my client wants to be able to have a "normal" size and an "expanded" size.  (This is different from Folding, which collapses the container completely).  Their goal is to create diagrams that have boxes that show basic functionality, which you can then expand to show additional functionality.

I have changed ContainerNode to inherit from TemplatedNode, and then created my own ContainerNodeExpandable class derived from that. So far that seems to be working fine.  The ContainerNodeExpandable retains all of the container functionality, and I have been able to re-style it.
  
Back to top
 
IP Logged
 
David Cater
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 12
Joined: May 12th, 2012
Re: Any easy way to make ContainerNode resizable?
Reply #7 - Oct 29th, 2012 at 5:13pm
Print Post  
I added some code to highlight the ContainerNode during the drag off the NodeListView. I had to make ContainerNode.highlight public so I could trigger on it and set it externally (from the Diagram). This code also references a DragFinished event I added earlier to NodeListView. That gets raised whether a drop actually occurs or not, and gives me a chance to clear the highlight if it was set during the drag.

Here's the code I added to the Diagram object:

Code (C++)
Select All
	    private ContainerNode m_highlightedDuringDrag;
            public void ClearDragHighlight() {
                // This must be called when NodeListView.DragFinished is raised.
                if (m_highlightedDuringDrag == null) return;
                m_highlightedDuringDrag.Highlight = false;
                m_highlightedDuringDrag = null;
            }
            void SetDragHighlight(ContainerNode node) {
                if (node == null) return;
                m_highlightedDuringDrag = node;
                m_highlightedDuringDrag.Highlight = true;
            }

            protected override void OnDragOver(DragEventArgs e) {
                base.OnDragOver(e);
                var dn = (DraggedNode)e.Data.GetData(typeof(DraggedNode));
                var center = e.GetPosition(this);
                center.X += dn.Node.Bounds.Width/2;
                center.Y += dn.Node.Bounds.Height/2;
                var nodes = GetNodesAt(center);
                var container = nodes.OfType<ContainerNode>().FirstOrDefault();

                if (m_highlightedDuringDrag == container) return;
                ClearDragHighlight();
                SetDragHighlight(container);
            } 


  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint