Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Visualization/HeuristicLab.Visualization/3.3/ChartControl.cs @ 7780

Last change on this file since 7780 was 7780, checked in by bburlacu, 12 years ago

#1265: Fixed zoom and small issue with selection. Added tool tips.

File size: 9.7 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.Drawing;
25using System.Drawing.Drawing2D;
26using System.Windows.Forms;
27
28namespace HeuristicLab.Visualization {
29  public partial class ChartControl : UserControl {
30    private Bitmap bitmap;
31    private bool renderingRequired;
32    private Point buttonDownPoint;
33    private Point mousePosition;
34    private int mouseClickCount;
35
36    private Chart myChart;
37    public Chart Chart {
38      get { return myChart; }
39      set {
40        if (myChart != null) myChart.Update -= new EventHandler(myChart_Update);
41        myChart = value;
42        if (myChart != null) {
43          myChart.Update += new EventHandler(myChart_Update);
44          SetMode(Chart.Mode);
45        }
46        GenerateImage();
47      }
48    }
49    private bool myScaleOnResize;
50    public bool ScaleOnResize {
51      get { return myScaleOnResize; }
52      set { myScaleOnResize = value; }
53    }
54
55    public ChartControl() {
56      InitializeComponent();
57      myScaleOnResize = true;
58      GenerateImage();
59    }
60
61    private void myChart_Update(object sender, EventArgs e) {
62      GenerateImage();
63    }
64    private void pictureBox_SizeChanged(object sender, EventArgs e) {
65      if (ScaleOnResize) {
66        if ((pictureBox.Width > 0) && (pictureBox.Height > 0) && (Chart != null)) {
67          PointD point = Chart.TransformPixelToWorld(new Point(pictureBox.Width, Chart.SizeInPixels.Height - pictureBox.Height));
68          Chart.SetPosition(Chart.LowerLeft, point);
69        }
70      }
71      GenerateImage();
72    }
73    private void pictureBox_VisibleChanged(object sender, EventArgs e) {
74      if (pictureBox.Visible && renderingRequired) {
75        GenerateImage();
76      }
77    }
78
79    private void pictureBox_MouseDown(object sender, MouseEventArgs e) {
80      buttonDownPoint = e.Location;
81      mouseClickCount = e.Clicks;
82    }
83    protected virtual void pictureBox_MouseUp(object sender, MouseEventArgs e) {
84      if (e.Button == MouseButtons.Left) {
85        if (Chart.Mode == ChartMode.Zoom) {
86          pictureBox.Refresh();
87          // some code to preserve the aspect ratio when zooming
88          //       +---------------------+ (Width,Height)
89          //       |  (x1,y1)            |
90          //       |      +-------+      |
91          //       |      |       |      |
92          //       |      |       |      |
93          //       |      +-------+      |
94          //       |             (x2,y2) |
95          // (0,0) +---------------------+
96          //
97          double aspectRatio = (double)Width / Height;
98          double x1 = Math.Min(e.X, buttonDownPoint.X);
99          double y1 = Math.Max(e.Y, buttonDownPoint.Y);
100          double x2 = Math.Max(e.X, buttonDownPoint.X);
101          double y2 = Math.Min(e.Y, buttonDownPoint.Y);
102          // consider the relative ratios between the X and Y dimensions of the selection
103          // area and the Width and Height, respectively. The "dominant" dimension is the
104          // one with a ratio closer to 1, and it stays fixed while the other is adjusted
105          // in order to preserve the aspect ratio
106          if ((x2 - x1) / Width > (y1 - y2) / Height) {
107            y1 = y2 + (x2 - x1) / aspectRatio;
108          } else {
109            x2 = aspectRatio * (y1 - y2) + x1;
110          }
111          var lowerLeft = new Point((int)x1, (int)y1);
112          var upperRight = new Point((int)x2, (int)y2);
113          if ((lowerLeft.X != upperRight.X) && (lowerLeft.Y != upperRight.Y)) {
114            Chart.ZoomIn(lowerLeft, upperRight);
115          }
116        }
117      } else if (e.Button == MouseButtons.Right) {
118        propertiesToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
119        oneLayerUpToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
120        oneLayerDownToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
121        intoForegroundToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
122        intoBackgroundToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
123      } else if (e.Button == MouseButtons.Middle) {
124        if (Chart.Mode == ChartMode.Zoom) {
125          if (mouseClickCount == 1) Chart.ZoomOut();
126          else if (mouseClickCount == 2) Chart.Unzoom();
127        }
128      }
129      if (buttonDownPoint == e.Location) {
130        if (mouseClickCount == 1)
131          Chart.MouseClick(e.Location, e.Button);
132        else if (mouseClickCount == 2)
133          Chart.MouseDoubleClick(e.Location, e.Button);
134      }
135    }
136
137    private void pictureBox_MouseMove(object sender, MouseEventArgs e) {
138      var text = Chart.GetToolTipText(e.Location);
139      if (toolTip.GetToolTip(pictureBox) != text)
140        toolTip.SetToolTip(pictureBox, text);
141      Cursor cursor = Chart.GetCursor(e.Location);
142      if (cursor != null) pictureBox.Cursor = cursor;
143      else pictureBox.Cursor = Cursors.Default;
144
145      if (e.Button != MouseButtons.None) {
146        if ((Chart.Mode == ChartMode.Zoom) && (e.Button == MouseButtons.Left)) {
147          pictureBox.Refresh();
148          Graphics graphics = pictureBox.CreateGraphics();
149          Pen pen = new Pen(Color.Gray);
150          pen.DashStyle = DashStyle.Dash;
151          graphics.DrawRectangle(pen,
152                                 Math.Min(e.X, buttonDownPoint.X),
153                                 Math.Min(e.Y, buttonDownPoint.Y),
154                                 Math.Abs(e.X - buttonDownPoint.X),
155                                 Math.Abs(e.Y - buttonDownPoint.Y));
156          pen.Dispose();
157          graphics.Dispose();
158        }
159        Chart.MouseDrag(mousePosition, e.Location, e.Button);
160      } else {
161        Chart.MouseMove(mousePosition, e.Location);
162      }
163      mousePosition = e.Location;
164    }
165
166    private void ChartControl_KeyDown(object sender, KeyEventArgs e) {
167      if (Chart.Mode == ChartMode.Select) {
168        if (e.KeyCode == Keys.Delete) {
169          IList<IPrimitive> selected = Chart.Group.SelectedPrimitives;
170          Chart.UpdateEnabled = false;
171          foreach (IPrimitive primitive in selected)
172            Chart.Group.Remove(primitive);
173          Chart.UpdateEnabled = true;
174          Chart.EnforceUpdate();
175        }
176      }
177    }
178
179    private void moveToolStripMenuItem_Click(object sender, EventArgs e) {
180      SetMode(ChartMode.Move);
181    }
182    private void zoomToolStripMenuItem_Click(object sender, EventArgs e) {
183      SetMode(ChartMode.Zoom);
184    }
185    private void selectToolStripMenuItem_Click(object sender, EventArgs e) {
186      SetMode(ChartMode.Select);
187    }
188    private void oneLayerUpToolStripMenuItem_Click(object sender, EventArgs e) {
189      if (Chart.Group.SelectedPrimitives.Count == 1) {
190        Chart.Group.SelectedPrimitives[0].OneLayerUp();
191      }
192    }
193    private void oneLayerDownToolStripMenuItem_Click(object sender, EventArgs e) {
194      if (Chart.Group.SelectedPrimitives.Count == 1) {
195        Chart.Group.SelectedPrimitives[0].OneLayerDown();
196      }
197    }
198    private void intoForegroundToolStripMenuItem_Click(object sender, EventArgs e) {
199      if (Chart.Group.SelectedPrimitives.Count == 1) {
200        Chart.Group.SelectedPrimitives[0].IntoForeground();
201      }
202    }
203    private void intoBackgroundToolStripMenuItem_Click(object sender, EventArgs e) {
204      if (Chart.Group.SelectedPrimitives.Count == 1) {
205        Chart.Group.SelectedPrimitives[0].IntoBackground();
206      }
207    }
208    private void propertiesToolStripMenuItem_Click(object sender, EventArgs e) {
209      if (Chart.Group.SelectedPrimitives.Count == 1) {
210        PropertiesDialog dialog = new PropertiesDialog(Chart.Group.SelectedPrimitives[0]);
211        dialog.ShowDialog(this);
212        dialog.Dispose();
213      }
214    }
215
216    private void GenerateImage() {
217      if (!Visible) {
218        renderingRequired = true;
219      } else {
220        if ((pictureBox.Width == 0) || (pictureBox.Height == 0)) {
221          bitmap = null;
222        } else {
223          bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
224          if (Chart != null) {
225            Graphics graphics = Graphics.FromImage(bitmap);
226            graphics.SetClip(new System.Drawing.Rectangle(0, 0, pictureBox.Width, pictureBox.Height));
227            Chart.Render(graphics, pictureBox.Width, pictureBox.Height);
228            graphics.Dispose();
229          }
230        }
231        if (pictureBox.Image != null) pictureBox.Image.Dispose();
232        pictureBox.Image = bitmap;
233        renderingRequired = false;
234      }
235    }
236
237    private void SetMode(ChartMode mode) {
238      moveToolStripMenuItem.Checked = false;
239      zoomToolStripMenuItem.Checked = false;
240      selectToolStripMenuItem.Checked = false;
241      if (mode == ChartMode.Move) moveToolStripMenuItem.Checked = true;
242      else if (mode == ChartMode.Zoom) zoomToolStripMenuItem.Checked = true;
243      else if (mode == ChartMode.Select) selectToolStripMenuItem.Checked = true;
244      Chart.Mode = mode;
245    }
246  }
247}
Note: See TracBrowser for help on using the repository browser.