#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(); }
}
}
}