#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.Drawing; using System.Drawing.Drawing2D; using HeuristicLab.Visualization; namespace HeuristicLab.Networks.Views.NetworkVisualization { public class ConnectionLine : Line { protected PortRectangle startPortRectangle; public PortRectangle StartPortRectangle { get { return startPortRectangle; } set { if (startPortRectangle == value) return; if (startPortRectangle != null) DeregisterPortRectangleEvents(startPortRectangle); startPortRectangle = value; if (startPortRectangle != null) RegisterPortRectangleEvents(startPortRectangle); OnStartPortRectangleChanged(); } } protected PortRectangle endPortRectangle; public PortRectangle EndPortRectangle { get { return endPortRectangle; } set { if (endPortRectangle == value) return; if (endPortRectangle != null) DeregisterPortRectangleEvents(endPortRectangle); endPortRectangle = value; if (endPortRectangle != null) RegisterPortRectangleEvents(endPortRectangle); OnEndPortRectangleChanged(); } } public ConnectionLine(IChart chart, PortRectangle start, PortRectangle end) : base(chart, start.Point, end.Point) { StartPortRectangle = start; EndPortRectangle = end; } protected virtual void RegisterPortRectangleEvents(PortRectangle portRectangle) { portRectangle.RedrawRequired += PortRectangle_RedrawRequired; } protected virtual void DeregisterPortRectangleEvents(PortRectangle portRectangle) { portRectangle.RedrawRequired -= PortRectangle_RedrawRequired; } #region Overrides public override void Move(Offset delta) { } public override void Move(PointD point, Offset delta) { } public override void Draw(Graphics graphics) { base.Draw(graphics); var startP = Chart.TransformWorldToPixel(Start); var endP = Chart.TransformWorldToPixel(End); if (startP == endP) return; double length = Math.Sqrt(Math.Pow(startP.X - endP.X, 2.0) + Math.Pow(startP.Y - endP.Y, 2)); double ax = (endP.X - startP.X) / length, ay = (endP.Y - startP.Y) / length; double bx = -2.5 * ax - ay, by = -2.5 * ay + ax; double cx = -2.5 * ax + ay, cy = -2.5 * ay - ax; double mul = 4 * Chart.WorldToPixelRatio.Width; bx *= mul; by *= mul; cx *= mul; cy *= mul; var p1 = new Point((int)Math.Round(endP.X + bx), (int)Math.Round(endP.Y + by)); var p2 = new Point((int)Math.Round(endP.X + cx), (int)Math.Round(endP.Y + cy)); graphics.FillPolygon(Pen.Brush, new[] { p1, endP, p2 }); } public override void PostDraw(Graphics graphics) { if (Selected) { using (var pen = new Pen(Color.LightGray, 3) { DashStyle = DashStyle.Dash }) graphics.DrawLine(pen, Chart.TransformWorldToPixel(Start), Chart.TransformWorldToPixel(End)); } } #endregion #region Events public event EventHandler StartPortRectangleChanged; protected virtual void OnStartPortRectangleChanged() { var handler = StartPortRectangleChanged; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler EndPortRectangleChanged; protected virtual void OnEndPortRectangleChanged() { var handler = EndPortRectangleChanged; if (handler != null) handler(this, EventArgs.Empty); } #endregion #region Event Handlers private void PortRectangle_RedrawRequired(object sender, EventArgs e) { SetPosition(startPortRectangle.Point, endPortRectangle.Point); } #endregion } }