/// <summary>
        /// Delegate called when the control is initialized.
        /// </summary>
        /// <param name="pEventArgs">The event arguments.</param>
        protected override void OnInitialized(EventArgs pEventArgs)
        {
            PortViewModel lPortViewModel = this.DataContext as PortViewModel;

            if (lPortViewModel == null)
            {
                return;
            }

            PortContainer lParentContainer = this.FindVisualParent <PortContainer>();

            if (lParentContainer == null)
            {
                return;
            }

            PortView lPortView = lParentContainer.GetContainerForViewModel(lPortViewModel);

            if (lPortView != null)
            {
                AdornerLayeredCanvas lCanvas = this.FindVisualParent <AdornerLayeredCanvas>();
                if (lCanvas != null)
                {
                    // Creating the adorner layer.
                    AdornerLayer lLayer = lCanvas.AdornerLayer;

                    // Creating the adorner and propagating this control background.
                    this.mAdorner = new ConnectorAdorner(lPortView);
                    this.UpdateConnectorsBackground();

                    // Adding the adorner to the layer.
                    lLayer.Add(this.mAdorner);
                }
            }
        }
示例#2
0
        /// <summary>
        /// Arranges the port views by taking in account the computed size of the panel viewport.
        /// </summary>
        /// <param name="pFinalSize">The available size.</param>
        /// <returns>The size used (here equals to the available size).</returns>
        protected override Size ArrangeOverride(Size pFinalSize)
        {
            // (1) Calling this base method is the key for the width of each port view to be well computed !!!
            base.ArrangeOverride(pFinalSize);

            int lInputPortsIndex  = 0;
            int lOutputPortsIndex = 0;

            if (this.InternalChildren.Count > 0)
            {
                // Using the ActualWidth computed by the base arrange (1) method to have the good column width.
                double     lInputPortsWidth = -1;
                PortView[] lInputPorts      = this.InternalChildren.Cast <PortView>().Where(pPort => pPort.Direction == PortDirection.Input).ToArray();
                if (lInputPorts.Any())
                {
                    lInputPortsWidth = Math.Round(lInputPorts.Max(pPort => pPort.ActualWidth) - this.LineWidth / 2.0);
                }

                double     lOutputPortsWidth = -1;
                PortView[] lOutputPorts      = this.InternalChildren.Cast <PortView>().Where(pPort => pPort.Direction == PortDirection.Output).ToArray();
                if (lOutputPorts.Any())
                {
                    lOutputPortsWidth = Math.Round(lOutputPorts.Max(pPort => pPort.ActualWidth) - this.LineWidth / 2.0);
                }

                if (lInputPortsWidth == -1 && lOutputPortsWidth != -1)
                {
                    lInputPortsWidth = lOutputPortsWidth;
                }

                if (lInputPortsWidth != -1 && lOutputPortsWidth == -1)
                {
                    lOutputPortsWidth = lInputPortsWidth;
                }

                for (int i = 0, lCount = this.InternalChildren.Count; i < lCount; ++i)
                {
                    PortView lPort = this.InternalChildren[i] as PortView;
                    if (lPort != null)
                    {
                        if (lPort.Direction == PortDirection.Input)
                        {
                            // Input ports are in the first column.
                            lPort.Arrange(new Rect(0.0, lInputPortsIndex * (lPort.DesiredSize.Height + this.LineWidth), lInputPortsWidth, lPort.DesiredSize.Height));
                            lInputPortsIndex++;
                        }
                        else
                        {
                            // Output ports are in the second column.
                            lPort.Arrange(new Rect(lInputPortsWidth + this.LineWidth, lOutputPortsIndex * (lPort.DesiredSize.Height + this.LineWidth), lOutputPortsWidth, lPort.DesiredSize.Height));
                            lOutputPortsIndex++;
                        }
                    }
                }
            }

            return(pFinalSize);
        }
示例#3
0
        /// <summary>
        /// Innitializes a new instance of the <see cref="ConnectorsAdorner"/> class.
        /// </summary>
        /// <param name="pAdornedElement">The orned prot view.</param>
        public ConnectorsAdorner(PortView pAdornedElement)
            : base(pAdornedElement)
        {
            // Creating the connectors contained in the adorner.
            this.mVisualChildren = new VisualCollection(this);
            this.mVisualChildren.Add(new InputConnector(pAdornedElement));
            this.mVisualChildren.Add(new OutputConnector(pAdornedElement));

            // Ensuring the measure is well computed.
            this.AdornedPortView.SizeChanged += new SizeChangedEventHandler(this.OnPortViewSizeChanged);
        }
示例#4
0
        /// <summary>
        /// Innitializes a new instance of the <see cref="ConnectorsAdorner"/> class.
        /// </summary>
        /// <param name="pAdornedElement">The orned prot view.</param>
        public ConnectorsAdorner(PortView pAdornedElement)
            : base(pAdornedElement)
        {
            // Creating the connectors contained in the adorner.
            this.mVisualChildren = new VisualCollection(this);
            this.mVisualChildren.Add(new InputConnector(pAdornedElement));
            this.mVisualChildren.Add(new OutputConnector(pAdornedElement));

            // Ensuring the measure is well computed.
            this.AdornedPortView.SizeChanged += new SizeChangedEventHandler(this.OnPortViewSizeChanged);
        }
示例#5
0
        /// <summary>
        /// Prespares the container for the given item.
        /// </summary>
        /// <param name="pElement">The item container.</param>
        /// <param name="pItem">The contained item.</param>
        protected override void PrepareContainerForItemOverride(DependencyObject pElement, object pItem)
        {
            base.PrepareContainerForItemOverride(pElement, pItem);

            PortView lContainer = pElement as PortView;

            if (lContainer != null)
            {
                // Updating the background.
                lContainer.Background = this.Background;
            }
        }
示例#6
0
 /// <summary>
 /// Updates the items background brush by applying the background of this container.
 /// </summary>
 private void UpdateItemsBackground()
 {
     if (this.ItemsSource != null)
     {
         foreach (PortViewModel lItem in this.ItemsSource)
         {
             PortView lPortView = this.ItemContainerGenerator.ContainerFromItem(lItem) as PortView;
             if (lPortView != null)
             {
                 lPortView.Background = this.Background;
             }
         }
     }
 }
示例#7
0
        /// <summary>
        /// Delegate called when the control is initialized.
        /// </summary>
        /// <param name="pEventArgs">The event arguments.</param>
        protected override void OnInitialized(EventArgs pEventArgs)
        {
            // The adorned port view is given to the control by the DataContext property.
            PortView lPortView = this.DataContext as PortView;

            if (lPortView != null)
            {
                AdornerLayeredCanvas lCanvas = this.FindVisualParent <AdornerLayeredCanvas>();
                if (lCanvas != null)
                {
                    // Creating the adorner layer.
                    AdornerLayer lLayer = lCanvas.AdornerLayer;

                    // Creating the adorner and propagating this control background.
                    this.Adorner = new ConnectorsAdorner(lPortView);
                    this.UpdateConnectorsBackground();

                    // Adding the adorner to the layer.
                    lLayer.Add(this.Adorner);
                }
            }
        }
示例#8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OutputConnector"/> class.
 /// </summary>
 /// <param name="pParentPort">The connector parent port.</param>
 public OutputConnector(PortView pParentPort)
     : base(pParentPort)
 {
 }
示例#9
0
        /// <summary>
        /// Method called when the control content changed.
        /// </summary>
        /// <param name="pOldContent">The previous content.</param>
        /// <param name="pNewContent">The new content.</param>
        protected override void OnContentChanged(object pOldContent, object pNewContent)
        {
            // Calling ancestor methods.
            base.OnContentChanged(pOldContent, pNewContent);

            BindingOperations.ClearAllBindings(this);

            // The content is the view model.
            ConnectionViewModel lViewModel = pNewContent as ConnectionViewModel;

            if (lViewModel == null)
            {
                // Unreferencing the connectors to avoid memory leaks.
                this.OutputConnector.ConnectionsCount--;
                this.InputConnector.ConnectionsCount--;
                this.OutputConnector.PositionChanged -= this.OnConnectorPositionChanged;
                this.InputConnector.PositionChanged  -= this.OnConnectorPositionChanged;
                this.OutputConnector = null;
                this.InputConnector  = null;
            }
            else
            {
                // Binding the Background property.
                Binding lBackgroundBinding = new Binding("Brush");
                lBackgroundBinding.Source = lViewModel;
                lBackgroundBinding.Mode   = BindingMode.OneWay;
                this.SetBinding(Connection.BackgroundProperty, lBackgroundBinding);

                // Filling the output and input connectors.
                SimpleGraphView lParentCanvas = this.FindVisualParent <SimpleGraphView>();
                if (lViewModel != null && lParentCanvas != null)
                {
                    NodeView lOutputNode = lParentCanvas.GetContainerForViewModel <NodeViewModel, NodeView>(lViewModel.Output.ParentNode);
                    if (lOutputNode != null)
                    {
                        PortView lOutputPort = lOutputNode.GetContainerForPortViewModel(lViewModel.Output);
                        if (lOutputPort != null)
                        {
                            this.OutputConnector = lOutputPort.Connector as OutputConnector;
                            if (this.OutputConnector != null)
                            {
                                this.OutputConnector.PositionChanged += this.OnConnectorPositionChanged;
                                this.OutputConnector.ConnectionsCount++;
                            }
                        }
                    }

                    NodeView lInputNode = lParentCanvas.GetContainerForViewModel <NodeViewModel, NodeView>(lViewModel.Input.ParentNode);
                    if (lInputNode != null)
                    {
                        PortView lInputPort = lInputNode.GetContainerForPortViewModel(lViewModel.Input);
                        if (lInputPort != null)
                        {
                            this.InputConnector = lInputPort.Connector as InputConnector;
                            if (this.InputConnector != null)
                            {
                                this.InputConnector.PositionChanged += this.OnConnectorPositionChanged;
                                this.InputConnector.ConnectionsCount++;
                            }
                        }
                    }
                }
            }

            this.UpdateRendering();
        }
示例#10
0
        /// <summary>
        /// Computes the size of the panel viewport.
        /// </summary>
        /// <param name="pAvailableSize">The initial available size.</param>
        /// <returns>The viewport desired size.</returns>
        protected override Size MeasureOverride(Size pAvailableSize)
        {
            Size lColumnSize = base.MeasureOverride(pAvailableSize);

            Size lInputPortsSize  = new Size();
            Size lOutputPortsSize = new Size();

            int lInputPortsIndex  = 0;
            int lOutputPortsIndex = 0;

            int lInputPortsCount  = this.InternalChildren.Cast <PortView>().Where(lPort => lPort.Direction == PortDirection.Input).Count();
            int lOutputPortsCount = this.InternalChildren.Cast <PortView>().Where(lPort => lPort.Direction == PortDirection.Output).Count();

            // Width is the column width.
            lInputPortsSize.Width  = lColumnSize.Width + this.LineWidth / 2.0;
            lOutputPortsSize.Width = lColumnSize.Width + this.LineWidth / 2.0;

            // Iterating threw the ports to compute the height.
            for (int i = 0, lCount = this.InternalChildren.Count; i < lCount; ++i)
            {
                PortView lPort = this.InternalChildren[i] as PortView;
                if (lPort != null)
                {
                    lPort.Measure(pAvailableSize);

                    if (lPort.Direction == PortDirection.Input)
                    {
                        if (lInputPortsIndex == 0 || lInputPortsIndex == lInputPortsCount - 1)
                        {
                            lInputPortsSize.Height += lPort.DesiredSize.Height + this.LineWidth / 2.0;
                        }
                        else
                        {
                            lInputPortsSize.Height += lPort.DesiredSize.Height + this.LineWidth;
                        }
                        lInputPortsIndex++;
                    }
                    else
                    {
                        if (lOutputPortsIndex == 0 || lOutputPortsIndex == lOutputPortsCount - 1)
                        {
                            lOutputPortsSize.Height += lPort.DesiredSize.Height + this.LineWidth / 2.0;
                        }
                        else
                        {
                            lOutputPortsSize.Height += lPort.DesiredSize.Height + this.LineWidth;
                        }
                        lOutputPortsIndex++;
                    }
                }
            }

            // Computing the size of the panel.
            Size lAvailableSize = new Size
            {
                Height = Math.Max(lInputPortsSize.Height, lOutputPortsSize.Height),
                Width  = lInputPortsSize.Width + lOutputPortsSize.Width
            };

            // This is the minimum size the control must have.
            return(lAvailableSize);
        }
示例#11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AConnector"/> class.
 /// </summary>
 /// <param name="pParentPort">The connector parent port.</param>
 protected AConnector(PortView pParentPort)
 {
     this.ParentPort = pParentPort;
     this.LayoutUpdated += this.OnLayoutUpdated;
 }