#region License Information /* HeuristicLab * Copyright (C) 2002-2016 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 System.Windows.Forms; namespace HeuristicLab.Visualization { public abstract class RectangularPrimitiveBase : PrimitiveBase { protected IGroup selectionRectangles; private PointD myLowerLeft; public virtual PointD LowerLeft { get { return myLowerLeft; } } private PointD myUpperRight; public virtual PointD UpperRight { get { return myUpperRight; } } public virtual SizeD Size { get { return new SizeD(UpperRight.X - LowerLeft.X, UpperRight.Y - LowerLeft.Y); } } protected RectangularPrimitiveBase(IChart chart, PointD lowerLeft, PointD upperRight) : base(chart) { selectionRectangles = new Group(chart); SetPosition(lowerLeft, upperRight); } protected RectangularPrimitiveBase(IChart chart, PointD lowerLeft, PointD upperRight, Pen pen, Brush brush) : base(chart, pen, brush) { selectionRectangles = new Group(chart); SetPosition(lowerLeft, upperRight); } public virtual void SetPosition(PointD lowerLeft, PointD upperRight) { if ((lowerLeft.X > upperRight.X) || (lowerLeft.Y > upperRight.Y)) throw new ArgumentException("Lower left point is greater than upper right point"); myLowerLeft = lowerLeft; myUpperRight = upperRight; OnRedrawRequired(); } public override void Move(Offset delta) { SetPosition(LowerLeft + delta, UpperRight + delta); } public override void Move(PointD point, Offset delta) { if (Selected && selectionRectangles.ContainsPoint(point)) { var rect = (SelectionRectangle)selectionRectangles.GetPrimitive(point); var point1 = PointD.Empty; var point2 = PointD.Empty; if (rect.Point == LowerLeft) { point1 = LowerLeft + delta; point2 = UpperRight; } else if (rect.Point == UpperRight) { point1 = LowerLeft; point2 = UpperRight + delta; } else if (rect.Point.X == LowerLeft.X && rect.Point.Y == UpperRight.Y) { point1 = new PointD(LowerLeft.X + delta.DX, LowerLeft.Y); point2 = new PointD(UpperRight.X, UpperRight.Y + delta.DY); } else if (rect.Point.X == UpperRight.X && rect.Point.Y == LowerLeft.Y) { point1 = new PointD(LowerLeft.X, LowerLeft.Y + delta.DY); point2 = new PointD(UpperRight.X + delta.DX, UpperRight.Y); } SetPosition(new PointD(Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y)), new PointD(Math.Max(point1.X, point2.X), Math.Max(point1.Y, point2.Y))); } else SetPosition(LowerLeft + delta, UpperRight + delta); } public override void SnapToGrid(IGrid grid) { var bl = grid.GetBottomLeftGridPoint(LowerLeft); var ur = grid.GetUpperRightGridPoint(LowerLeft); var sx = Math.Abs(bl.X - LowerLeft.X) <= Math.Abs(ur.X - LowerLeft.X) ? bl.X : ur.X; var sy = Math.Abs(bl.Y - LowerLeft.Y) <= Math.Abs(ur.Y - LowerLeft.Y) ? bl.Y : ur.Y; var end = new PointD(UpperRight.X + (sx - LowerLeft.X), UpperRight.Y + (sy - LowerLeft.Y)); bl = grid.GetBottomLeftGridPoint(end); ur = grid.GetUpperRightGridPoint(end); var ex = Math.Abs(bl.X - end.X) <= Math.Abs(ur.X - end.X) ? bl.X : ur.X; var ey = Math.Abs(bl.Y - end.Y) <= Math.Abs(ur.Y - end.Y) ? bl.Y : ur.Y; SetPosition(new PointD(sx, sy), new PointD(ex, ey)); } public override void SnapToGrid(PointD point, IGrid grid) { if (Selected && selectionRectangles.ContainsPoint(point)) { var rect = (SelectionRectangle)selectionRectangles.GetPrimitive(point); var point1 = LowerLeft; var point2 = UpperRight; if (rect.Point == LowerLeft) { var bl = grid.GetBottomLeftGridPoint(LowerLeft); var ur = grid.GetUpperRightGridPoint(LowerLeft); var x = Math.Abs(bl.X - LowerLeft.X) <= Math.Abs(ur.X - LowerLeft.X) ? bl.X : ur.X; var y = Math.Abs(bl.Y - LowerLeft.Y) <= Math.Abs(ur.Y - LowerLeft.Y) ? bl.Y : ur.Y; point1 = new PointD(x, y); } else if (rect.Point == UpperRight) { var bl = grid.GetBottomLeftGridPoint(UpperRight); var ur = grid.GetUpperRightGridPoint(UpperRight); var x = Math.Abs(bl.X - UpperRight.X) <= Math.Abs(ur.X - UpperRight.X) ? bl.X : ur.X; var y = Math.Abs(bl.Y - UpperRight.Y) <= Math.Abs(ur.Y - UpperRight.Y) ? bl.Y : ur.Y; point2 = new PointD(x, y); } else if (rect.Point.X == LowerLeft.X && rect.Point.Y == UpperRight.Y) { var upperLeft = new PointD(LowerLeft.X, UpperRight.Y); var bl = grid.GetBottomLeftGridPoint(upperLeft); var ur = grid.GetUpperRightGridPoint(upperLeft); var x = Math.Abs(bl.X - upperLeft.X) <= Math.Abs(ur.X - upperLeft.X) ? bl.X : ur.X; var y = Math.Abs(bl.Y - upperLeft.Y) <= Math.Abs(ur.Y - upperLeft.Y) ? bl.Y : ur.Y; point1 = new PointD(x, LowerLeft.Y); point2 = new PointD(UpperRight.X, y); } else if (rect.Point.X == UpperRight.X && rect.Point.Y == LowerLeft.Y) { var lowerRight = new PointD(UpperRight.X, LowerLeft.Y); var bl = grid.GetBottomLeftGridPoint(lowerRight); var ur = grid.GetUpperRightGridPoint(lowerRight); var x = Math.Abs(bl.X - lowerRight.X) <= Math.Abs(ur.X - lowerRight.X) ? bl.X : ur.X; var y = Math.Abs(bl.Y - lowerRight.Y) <= Math.Abs(ur.Y - lowerRight.Y) ? bl.Y : ur.Y; point1 = new PointD(LowerLeft.X, y); point2 = new PointD(x, UpperRight.Y); } SetPosition(new PointD(Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y)), new PointD(Math.Max(point1.X, point2.X), Math.Max(point1.Y, point2.Y))); } else SnapToGrid(grid); } public override bool ContainsPoint(PointD point) { if (Selected) { if (selectionRectangles.ContainsPoint(point)) return true; } return false; } public override Cursor GetCursor(PointD point) { if (Selected) { var cursor = selectionRectangles.GetCursor(point); if (cursor != null) return cursor; } return base.GetCursor(point); } public override void PostDraw(Graphics graphics) { selectionRectangles.Clear(); if (Selected) { Pen pen = new Pen(Color.LightGray, 3); pen.DashStyle = DashStyle.Dash; Point p = Chart.TransformWorldToPixel(new PointD(LowerLeft.X, LowerLeft.Y + Size.Height)); Size s = Chart.TransformWorldToPixel(Size); graphics.DrawRectangle(pen, p.X, p.Y, s.Width, s.Height); selectionRectangles.Add(new SelectionRectangle(Chart, UpperRight.X, LowerLeft.Y, Cursors.SizeNWSE)); selectionRectangles.Add(new SelectionRectangle(Chart, LowerLeft.X, LowerLeft.Y, Cursors.SizeNESW)); selectionRectangles.Add(new SelectionRectangle(Chart, UpperRight.X, UpperRight.Y, Cursors.SizeNESW)); selectionRectangles.Add(new SelectionRectangle(Chart, LowerLeft.X, UpperRight.Y, Cursors.SizeNWSE)); selectionRectangles.Draw(graphics); } } } }