#region License Information /* HeuristicLab * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using HeuristicLab.Core.Networks; using HeuristicLab.Networks.Programmable; using HeuristicLab.Visualization; namespace HeuristicLab.Networks.Views.NetworkVisualization.Views { public class SelectChartMode : Visualization.SelectChartMode { protected PortRectangle selectedPortRectangle; protected NodeRectangle constrainingNodeRectangle; public SelectChartMode(ChartControl control) : base(control) { } protected override void OnDeselected() { try { chartControl.SuspendRendering(); if (selectedPortRectangle != null) { selectedPortRectangle.Selected = false; selectedPortRectangle = null; constrainingNodeRectangle = null; } } finally { chartControl.ResumeRendering(); base.OnDeselected(); } } public override void HandleOnMouseDown(object sender, MouseEventArgs e) { try { switch (e.Button) { case MouseButtons.Left: chartControl.SuspendRendering(); if (selectedPortRectangle != null) { selectedPortRectangle.Selected = false; selectedPortRectangle = null; constrainingNodeRectangle = null; } var worldLocation = chartControl.Chart.TransformPixelToWorld(e.Location); var nodeRectangles = chartControl.Chart.Group.Primitives.OfType(); foreach (var nodeRectangle in nodeRectangles) { var node = nodeRectangle.NetworkItem; var portRectangles = node.Ports.Select(nodeRectangle.GetPortPrimitive).OfType(); foreach (var portRectangle in portRectangles) { portRectangle.Selected = selectedPortRectangle == null && portRectangle.ContainsPoint(worldLocation); if (portRectangle.Selected) { selectedPortRectangle = portRectangle; constrainingNodeRectangle = nodeRectangle; break; } } } if (selectedPortRectangle != null) foreach (var sp in chartControl.Chart.Group.SelectedPrimitives) { sp.Selected = false; OnSelectedPrimitivesChanged(); } else base.HandleOnMouseDown(sender, e); break; } } finally { chartControl.ResumeRendering(); } } public override void HandleOnMouseMove(object sender, MouseEventArgs e) { if (selectedPortRectangle != null) { switch (e.Button) { case MouseButtons.Left: var point = chartControl.Chart.TransformPixelToWorld(e.Location); var lowerLeft = constrainingNodeRectangle.LowerLeft; var upperRight = constrainingNodeRectangle.UpperRight; if (point.X < lowerLeft.X) point.X = lowerLeft.X; else if (point.X > upperRight.X) point.X = upperRight.X; if (point.Y < lowerLeft.Y) point.Y = lowerLeft.Y; else if (point.Y > upperRight.Y) point.Y = upperRight.Y; double dS = lowerLeft.Y - point.Y; double dW = lowerLeft.X - point.X; double dX = upperRight.X - point.X; // dE if (Math.Abs(dX) > Math.Abs(dW)) dX = dW; double dY = upperRight.Y - point.Y; // dN if (Math.Abs(dY) > Math.Abs(dS)) dY = dS; var offset = Offset.Empty; if (Math.Abs(dX) < Math.Abs(dY)) offset.DX = dX; else offset.DY = dY; point = point + offset; offset = point - selectedPortRectangle.Point; try { chartControl.SuspendRendering(); selectedPortRectangle.Move(offset); } finally { chartControl.ResumeRendering(); } break; } } else base.HandleOnMouseMove(sender, e); previousLocation = e.Location; } public override void HandleOnMouseDoubleClick(object sender, MouseEventArgs e) { try { switch (e.Button) { case MouseButtons.Left: var nodeRectangle = chartControl.Chart.GetPrimitive(e.Location) as NodeRectangle; if (nodeRectangle != null) MainForm.MainFormManager.MainForm.ShowContent(nodeRectangle.NetworkItem); break; } } finally { base.HandleOnMouseDoubleClick(sender, e); } } protected override void DeleteSelectedPrimitives() { if (!(chartControl.Tag is IUserDefinedNetwork)) return; try { chartControl.SuspendRendering(); var connectionLines = chartControl.Chart.Group.Primitives.OfType().ToList(); var nodeRectangles = chartControl.Chart.Group.Primitives.OfType().ToList(); var portRectangles = nodeRectangles.SelectMany(x => x.NetworkItem.Ports.Select(x.GetPortPrimitive)).OfType().ToList(); var deletedNodes = new HashSet(); var deletedPorts = new HashSet(); foreach (var nodeRectangle in nodeRectangles) { if (nodeRectangle.Selected) { var node = nodeRectangle.NetworkItem; if (node == null) continue; deletedNodes.Add(node); foreach (var port in node.Ports.OfType()) deletedPorts.Add(port); } } foreach (var portRectangle in portRectangles) { if (portRectangle.Selected) { var port = portRectangle.NetworkItem as IMessagePort; if (port == null) continue; port.Parent.Ports.Remove(port); deletedPorts.Add(port); } } selectedPortRectangle = null; foreach (var connectionLine in connectionLines) { var startPortRectangle = connectionLine.StartPortRectangle; var endPortRectangle = connectionLine.EndPortRectangle; if (startPortRectangle == null || endPortRectangle == null) continue; var startPort = startPortRectangle.NetworkItem as IMessagePort; var endPort = endPortRectangle.NetworkItem as IMessagePort; if (startPort == null || endPort == null) continue; if (connectionLine.Selected || deletedPorts.Contains(startPort) || deletedPorts.Contains(endPort)) startPort.ConnectedPort = null; } foreach (var node in deletedNodes) node.Parent.Nodes.Remove(node); } finally { chartControl.ResumeRendering(); } } } }