source: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Chart.cs @ 4773

Last change on this file since 4773 was 4773, checked in by abeham, 8 years ago

#1265

  • Created branch for HeuristicLab.Drawing
  • Updated license headers, namespaces and versions
File size: 9.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Text;
25using System.Drawing;
26using System.Windows.Forms;
27
28namespace HeuristicLab.Drawing {
29  public class Chart : IChart {
30    private PointD originalLowerLeft;
31    private PointD originalUpperRight;
32    private List<Offset> zoomHistory;
33
34    private ChartMode myMode;
35    public virtual ChartMode Mode {
36      get { return myMode; }
37      set {
38        myMode = value;
39        OnUpdate();
40      }
41    }
42
43    private PointD myLowerLeft;
44    public virtual PointD LowerLeft {
45      get { return myLowerLeft; }
46    }
47    private PointD myUpperRight;
48    public virtual PointD UpperRight {
49      get { return myUpperRight; }
50    }
51    public virtual SizeD Size {
52      get { return new SizeD(UpperRight.X - LowerLeft.X, UpperRight.Y - LowerLeft.Y); }
53    }
54    private Size mySizeInPixels;
55    public Size SizeInPixels {
56      get { return mySizeInPixels; }
57    }
58    public SizeD PixelToWorldRatio {
59      get { return new SizeD(Size.Width / SizeInPixels.Width, Size.Height / SizeInPixels.Height); }
60    }
61    public SizeD WorldToPixelRatio {
62      get { return new SizeD(SizeInPixels.Width / Size.Width, SizeInPixels.Height / Size.Height); }
63    }
64
65    private IGroup myGroup;
66    public IGroup Group {
67      get { return myGroup; }
68    }
69
70    private bool myUpdateEnabled;
71    public bool UpdateEnabled {
72      get { return myUpdateEnabled; }
73      set { myUpdateEnabled = value; }
74    }
75
76    public Chart(PointD lowerLeft, PointD upperRight) {
77      myUpdateEnabled = false;
78      zoomHistory = new List<Offset>();
79      myMode = ChartMode.Move;
80      SetPosition(lowerLeft, upperRight);
81      mySizeInPixels = new Size(100, 100);
82      myGroup = new Group(this);
83      Group.Update += new EventHandler(Group_Update);
84      myUpdateEnabled = true;
85    }
86    public Chart(double x1, double y1, double x2, double y2)
87      : this(new PointD(x1, y1), new PointD(x2, y2)) {
88    }
89
90    public PointD TransformPixelToWorld(Point point) {
91      double x = LowerLeft.X + point.X * PixelToWorldRatio.Width;
92      double y = LowerLeft.Y + (SizeInPixels.Height - point.Y) * PixelToWorldRatio.Height;
93      return new PointD(x, y);
94    }
95    public SizeD TransformPixelToWorld(Size size) {
96      double width = size.Width * PixelToWorldRatio.Width;
97      double height = size.Height * PixelToWorldRatio.Height;
98      return new SizeD(width, height);
99    }
100    public Point TransformWorldToPixel(PointD point) {
101      int x = (int)((point.X - LowerLeft.X) * WorldToPixelRatio.Width);
102      int y = (int)((UpperRight.Y - point.Y) * WorldToPixelRatio.Height);
103      return new Point(x, y);
104    }
105    public Size TransformWorldToPixel(SizeD size) {
106      int width = (int)(size.Width * WorldToPixelRatio.Width);
107      int height = (int)(size.Height * WorldToPixelRatio.Height);
108      return new Size(width, height);
109    }
110
111    public virtual void SetPosition(PointD lowerLeft, PointD upperRight) {
112      if ((lowerLeft.X >= upperRight.X) || (lowerLeft.Y >= upperRight.Y))
113        throw new ArgumentException("Lower left point is greater or equal than upper right point");
114
115      originalLowerLeft = lowerLeft;
116      originalUpperRight = upperRight;
117      if (zoomHistory != null) zoomHistory.Clear();
118      myLowerLeft = lowerLeft;
119      myUpperRight = upperRight;
120      OnUpdate();
121    }
122    public void SetPosition(double x1, double y1, double x2, double y2) {
123      SetPosition(new PointD(x1, y1), new PointD(x2, y2));
124    }
125    public virtual void Move(Offset delta) {
126      myLowerLeft += delta;
127      myUpperRight += delta;
128      OnUpdate();
129    }
130    public void Move(double dx, double dy) {
131      Move(new Offset(dx, dy));
132    }
133
134    public virtual void ZoomIn(PointD lowerLeft, PointD upperRight) {
135      zoomHistory.Insert(0, LowerLeft - lowerLeft);
136      zoomHistory.Insert(0, UpperRight - upperRight);
137      myLowerLeft = lowerLeft;
138      myUpperRight = upperRight;
139      OnUpdate();
140    }
141    public void ZoomIn(double x1, double y1, double x2, double y2) {
142      ZoomIn(new PointD(x1, y1), new PointD(x2, y2));
143    }
144    public virtual void ZoomIn(Point lowerLeft, Point upperRight) {
145      ZoomIn(TransformPixelToWorld(lowerLeft), TransformPixelToWorld(upperRight));
146    }
147    public void ZoomIn(int x1, int y1, int x2, int y2) {
148      ZoomIn(new Point(x1, y1), new Point(x2, y2));
149    }
150    public virtual void ZoomOut() {
151      if (zoomHistory.Count > 0) {
152        Offset upperRight = zoomHistory[0];
153        zoomHistory.RemoveAt(0);
154        Offset lowerLeft = zoomHistory[0];
155        zoomHistory.RemoveAt(0);
156        myLowerLeft = LowerLeft + lowerLeft;
157        myUpperRight = UpperRight + upperRight;
158        OnUpdate();
159      } else {
160        myLowerLeft.X -= Size.Width / 4;
161        myLowerLeft.Y -= Size.Height / 4;
162        myUpperRight.X += Size.Width / 4;
163        myUpperRight.Y += Size.Height / 4;
164        OnUpdate();
165      }
166    }
167    public virtual void Unzoom() {
168      SetPosition(originalLowerLeft, originalUpperRight);
169    }
170
171    public virtual IPrimitive GetPrimitive(Point point) {
172      return Group.GetPrimitive(TransformPixelToWorld(point));
173    }
174    public IPrimitive GetPrimitive(int x, int y) {
175      return GetPrimitive(new Point(x, y));
176    }
177    public virtual IList<IPrimitive> GetAllPrimitives(Point point) {
178      return Group.GetAllPrimitives(TransformPixelToWorld(point));
179    }
180    public IList<IPrimitive> GetAllPrimitives(int x, int y) {
181      return GetAllPrimitives(new Point(x, y));
182    }
183
184    public virtual Cursor GetCursor(Point point) {
185      Cursor cursor = Group.GetCursor(TransformPixelToWorld(point));
186      if (cursor != null) return cursor;
187
188      if (Mode == ChartMode.Move) return Cursors.Hand;
189      if (Mode == ChartMode.Select) return Cursors.Arrow;
190      if (Mode == ChartMode.Zoom) return Cursors.Arrow;
191      return Cursors.Default;
192    }
193    public Cursor GetCursor(int x, int y) {
194      return GetCursor(new Point(x, y));
195    }
196    public virtual string GetToolTipText(Point point) {
197      return Group.GetToolTipText(TransformPixelToWorld(point));
198    }
199    public string GetToolTipText(int x, int y) {
200      return GetToolTipText(new Point(x, y));
201    }
202
203    public virtual void MouseClick(Point point, MouseButtons button) {
204      if (Mode == ChartMode.Select) {
205        if (button == MouseButtons.Left) {
206          IPrimitive clicked = GetPrimitive(point);
207          UpdateEnabled = false;
208          foreach (IPrimitive primitive in Group.SelectedPrimitives)
209            primitive.Selected = false;
210          UpdateEnabled = true;
211          if (clicked != null) {
212            PointD p = TransformPixelToWorld(point);
213            clicked.MouseClick(p, button);
214          } else OnUpdate();
215        }
216      } else if (Mode == ChartMode.Move) {
217        if (button == MouseButtons.Middle) {
218          PointD center = LowerLeft + new Offset(Size.Width / 2, Size.Height / 2);
219          Move(TransformPixelToWorld(point) - center);
220        }
221      }
222    }
223    public void MouseClick(int x, int y, MouseButtons button) {
224      MouseClick(new Point(x, y), button);
225    }
226    public virtual void MouseDoubleClick(Point point, MouseButtons button) {
227    }
228    public void MouseDoubleClick(int x, int y, MouseButtons button) {
229      MouseDoubleClick(new Point(x, y), button);
230    }
231    public virtual void MouseMove(Point start, Point end) {
232    }
233    public void MouseMove(int x1, int y1, int x2, int y2) {
234      MouseMove(new Point(x1, y1), new Point(x2, y2));
235    }
236    public virtual void MouseDrag(Point start, Point end, MouseButtons button) {
237      PointD p1 = TransformPixelToWorld(start);
238      PointD p2 = TransformPixelToWorld(end);
239      Offset offset = p2 - p1;
240      if (Mode == ChartMode.Move) {
241        Move(-1 * offset.DX, -1 * offset.DY);
242      } else if (Mode == ChartMode.Select) {
243        if (button == MouseButtons.Left) {
244          IList<IPrimitive> selected = Group.SelectedPrimitives;
245          UpdateEnabled = false;
246          foreach (IPrimitive primitive in selected)
247            primitive.MouseDrag(p1, offset, button);
248          UpdateEnabled = true;
249          OnUpdate();
250        }
251      }
252    }
253    public void MouseDrag(int x1, int y1, int x2, int y2, MouseButtons button) {
254      MouseDrag(new Point(x1, y1), new Point(x2, y2), button);
255    }
256
257    public virtual void Render(Graphics graphics, int width, int height) {
258      mySizeInPixels = new Size(width, height);
259      Group.PreDraw(graphics);
260      Group.Draw(graphics);
261      Group.PostDraw(graphics);
262    }
263
264    public event EventHandler Update;
265    public void EnforceUpdate() {
266      if (Update != null) {
267        Update(this, new EventArgs());
268      }
269    }
270    protected virtual void OnUpdate() {
271      if ((UpdateEnabled) && (Update != null)) {
272        Update(this, new EventArgs());
273      }
274    }
275    private void Group_Update(object sender, EventArgs e) {
276      OnUpdate();
277    }
278  }
279}
Note: See TracBrowser for help on using the repository browser.