Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 13114 was 13114, checked in by jkarder, 8 years ago

#1265: worked on visualization

  • removed BackgroundColor and PictureBox from ChartControl
  • updated chart modes
File size: 12.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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.ComponentModel;
25using System.Drawing;
26using System.Drawing.Imaging;
27using System.Linq;
28using System.Windows.Forms;
29
30namespace HeuristicLab.Visualization {
31  public partial class ChartControl : UserControl {
32    protected Bitmap Picture;
33    protected bool RenderingRequired;
34    protected Dictionary<Type, ChartMode> Modes = new Dictionary<Type, ChartMode>();
35
36    protected bool SuppressEvents { get; set; }
37    private bool SuppressRender { get; set; }
38
39    private IChart chart;
40    public IChart Chart {
41      get { return chart; }
42      protected set {
43        if (chart != null) DeregisterChartEvents(chart);
44        chart = value;
45        chart.Enabled = Enabled;
46        pictureBox.Enabled = Enabled;
47        if (chart != null) RegisterChartEvents(chart);
48      }
49    }
50
51    private ChartMode mode;
52    public ChartMode Mode {
53      get { return mode; }
54      set {
55        if (mode == value) return;
56        mode = value;
57        SetButtonCheckedSate();
58        SetPictureBoxCursor(GetPictureBoxCursor());
59        OnModeChanged();
60        if (chart != null) {
61          GenerateImage();
62        }
63      }
64    }
65
66    public bool ScaleOnResize { get; set; }
67
68    public bool IsRenderingPaused { get { return SuppressRender; } }
69
70    public ChartControl() : this(null) { }
71    public ChartControl(IChart defaultChart) {
72      InitializeComponent();
73      ScaleOnResize = true;
74      Chart = defaultChart ?? new Chart(0, 0, Width, Height);
75    }
76
77    public void AddChartModes(params ChartMode[] chartModes) {
78      foreach (var chartMode in chartModes)
79        Modes.Add(chartMode.GetType(), chartMode);
80
81      RebuildButtonPanel();
82    }
83
84    protected virtual void RebuildButtonPanel() {
85      buttonPanel.Controls.Clear();
86
87      int locationY = 3;
88      foreach (var chartMode in Modes.Values) {
89        var rb = CreateChartModeRadioButton(chartMode);
90        rb.Location = new Point(3, locationY);
91        toolTip.SetToolTip(rb, chartMode.ToolTip);
92        buttonPanel.Controls.Add(rb);
93        locationY += rb.Height + rb.Margin.Vertical;
94      }
95    }
96
97    public void SuspendRendering() {
98      SuppressRender = true;
99    }
100
101    public void ResumeRendering() {
102      SuppressRender = false;
103      if (Chart != null) GenerateImage();
104    }
105
106    public void RefreshPicture() {
107      pictureBox.Refresh();
108    }
109
110    public void UpdatePicture() {
111      pictureBox.Update();
112    }
113
114    public Graphics CreatePictureGraphics() {
115      return pictureBox.CreateGraphics();
116    }
117
118    protected virtual void SetButtonCheckedSate() {
119      foreach (var rb in buttonPanel.Controls.OfType<RadioButton>())
120        rb.Checked = rb.Tag == Mode;
121    }
122
123    protected virtual void SetPictureBoxCursor(Cursor cursor) {
124      if (pictureBox.Cursor != cursor) pictureBox.Cursor = cursor;
125    }
126
127    protected virtual Cursor GetPictureBoxCursor() {
128      if (mode == null) return null;
129
130      return mode.Cursor;
131    }
132
133    protected virtual void RegisterChartEvents(IChart chart) {
134      chart.RedrawRequired += ChartOnUpdateRequired;
135    }
136
137    protected virtual void DeregisterChartEvents(IChart chart) {
138      chart.RedrawRequired -= ChartOnUpdateRequired;
139    }
140
141    protected virtual void ChartOnUpdateRequired(object sender, EventArgs e) {
142      if (SuppressRender) return;
143      GenerateImage();
144    }
145
146    #region PictureBox Events
147    protected virtual void PictureBoxOnSizeChanged(object sender, EventArgs e) {
148      if (Chart == null) return;
149      if (ScaleOnResize) {
150        if ((pictureBox.Width > 0) && (pictureBox.Height > 0) && (Chart != null)) {
151          var point = Chart.TransformPixelToWorld(new Point(pictureBox.Width, Chart.SizeInPixels.Height - pictureBox.Height));
152          var diff = Chart.UpperRight - point;
153          Chart.SetPosition(new PointD(Chart.LowerLeft.X + (diff.DX / 2.0), Chart.LowerLeft.Y + (diff.DY / 2.0)),
154            new PointD(Chart.UpperRight.X - (diff.DX / 2.0), Chart.UpperRight.Y - (diff.DY / 2.0)));
155        }
156      }
157      GenerateImage();
158    }
159
160    protected virtual void PictureBoxOnVisibleChanged(object sender, EventArgs e) {
161      if (pictureBox.Visible && RenderingRequired) GenerateImage();
162    }
163
164    protected virtual void PictureBoxOnMouseClick(object sender, MouseEventArgs e) {
165      if (mode == null) return;
166      mode.HandleOnMouseClick(sender, e);
167    }
168
169    protected virtual void PictureBoxOnMouseDoubleClick(object sender, MouseEventArgs e) {
170      if (mode == null) return;
171      mode.HandleOnMouseDoubleClick(sender, e);
172    }
173
174    protected virtual void OnKeyDown(object sender, KeyEventArgs e) {
175      if (mode == null) return;
176      mode.HandleOnKeyDown(sender, e);
177    }
178
179    protected virtual void OnKeyUp(object sender, KeyEventArgs e) {
180      if (mode == null) return;
181      mode.HandleOnKeyUp(sender, e);
182    }
183
184    protected virtual void PictureBoxOnMouseWheel(object sender, MouseEventArgs e) {
185      if (mode == null) return;
186      mode.HandleOnMouseWheel(sender, e);
187    }
188
189    protected virtual void PictureBoxOnMouseDown(object sender, MouseEventArgs e) {
190      if (mode == null) return;
191      mode.HandleOnMouseDown(sender, e);
192    }
193
194    protected virtual void PictureBoxOnMouseUp(object sender, MouseEventArgs e) {
195      if (mode == null) return;
196      mode.HandleOnMouseUp(sender, e);
197
198      if (Chart == null) return;
199
200      if (e.Button == MouseButtons.Right) {
201        propertiesToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count() == 1;
202        oneLayerUpToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count() == 1;
203        oneLayerDownToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count() == 1;
204        intoForegroundToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count() == 1;
205        intoBackgroundToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count() == 1;
206      }
207    }
208
209    protected virtual void PictureBoxOnMouseMove(object sender, MouseEventArgs e) {
210      if (InvokeRequired) {
211        Invoke((Action<object, MouseEventArgs>)PictureBoxOnMouseMove, sender, e);
212      } else {
213        var toolTipText = Chart.GetToolTipText(e.Location);
214        if (toolTip.GetToolTip(pictureBox) != toolTipText) toolTip.SetToolTip(pictureBox, toolTipText);
215
216        if (mode == null) return;
217
218        mode.HandleOnMouseMove(sender, e);
219
220        SetPictureBoxCursor(mode.Cursor);
221      }
222    }
223
224    protected virtual void PictureBoxOnMouseEnter(object sender, EventArgs e) {
225      if (InvokeRequired) {
226        Invoke((Action<object, MouseEventArgs>)PictureBoxOnMouseEnter, sender, e);
227        return;
228      }
229      if (!Focused) this.pictureBox.Focus();
230
231      if (mode == null) return;
232
233      mode.HandleOnMouseEnter(sender, e);
234    }
235
236    protected virtual void PictureBoxOnMouseLeave(object sender, EventArgs e) {
237      if (mode == null) return;
238      mode.HandleOnMouseLeave(sender, e);
239    }
240
241    protected virtual void PictureBoxOnClick(object sender, EventArgs e) {
242      if (InvokeRequired) {
243        Invoke((Action<Object, MouseEventArgs>)PictureBoxOnClick, sender, e);
244        return;
245      }
246      if (!Focused) this.pictureBox.Focus();
247
248      if (mode == null) return;
249
250      mode.HandleOnClick(sender, e);
251    }
252    #endregion
253
254    protected virtual void PictureBoxContextMenuStripOnOpening(object sender, CancelEventArgs e) { }
255
256    protected virtual void oneLayerUpToolStripMenuItem_Click(object sender, EventArgs e) {
257      if (Chart == null) return;
258      if (Chart.Group.SelectedPrimitives.Count() == 1) {
259        Chart.OneLayerUp(Chart.Group.SelectedPrimitives.First());
260      }
261    }
262    protected virtual void oneLayerDownToolStripMenuItem_Click(object sender, EventArgs e) {
263      if (Chart == null) return;
264      if (Chart.Group.SelectedPrimitives.Count() == 1) {
265        Chart.OneLayerDown(Chart.Group.SelectedPrimitives.First());
266      }
267    }
268    protected virtual void intoForegroundToolStripMenuItem_Click(object sender, EventArgs e) {
269      if (Chart == null) return;
270      if (Chart.Group.SelectedPrimitives.Count() == 1) {
271        Chart.IntoForeground(Chart.Group.SelectedPrimitives.First());
272      }
273    }
274    protected virtual void intoBackgroundToolStripMenuItem_Click(object sender, EventArgs e) {
275      if (Chart == null) return;
276      if (Chart.Group.SelectedPrimitives.Count() == 1) {
277        Chart.IntoBackground(Chart.Group.SelectedPrimitives.First());
278      }
279    }
280    protected virtual void propertiesToolStripMenuItem_Click(object sender, EventArgs e) {
281      if (Chart == null) return;
282      if (Chart.Group.SelectedPrimitives.Count() == 1) {
283        using (var dialog = new PropertiesDialog(Chart.Group.SelectedPrimitives.First())) {
284          dialog.ShowDialog(this);
285        }
286      }
287    }
288    protected virtual void saveImageToolStripMenuItem_Click(object sender, EventArgs e) {
289      if (Picture == null) return;
290
291      if (saveFileDialog.ShowDialog() == DialogResult.OK) {
292        var format = ImageFormat.Bmp;
293        var filename = saveFileDialog.FileName.ToLower();
294        if (filename.EndsWith("emf")) {
295          using (var g1 = Graphics.FromImage(Picture)) {
296            var rectangle = new System.Drawing.Rectangle(0, 0, Picture.Width, Picture.Height);
297            using (var metafile = new Metafile(filename, g1.GetHdc(), rectangle, MetafileFrameUnit.Pixel, EmfType.EmfPlusDual))
298            using (var g2 = Graphics.FromImage(metafile))
299              Chart.Render(g2, pictureBox.Width, pictureBox.Height);
300          }
301        } else {
302          using (var graphics = Graphics.FromImage(Picture))
303            Chart.Render(graphics, Picture.Width, Picture.Height);
304
305          if (filename.EndsWith("jpg")) {
306            format = ImageFormat.Jpeg;
307          } else if (filename.EndsWith("gif")) {
308            format = ImageFormat.Gif;
309          } else if (filename.EndsWith("png")) {
310            format = ImageFormat.Png;
311          } else if (filename.EndsWith("tif")) {
312            format = ImageFormat.Tiff;
313          }
314
315          Picture.Save(saveFileDialog.FileName, format);
316        }
317      }
318    }
319
320    protected virtual void GenerateImage() {
321      if (InvokeRequired) {
322        Invoke((Action)GenerateImage);
323        return;
324      }
325      if (!Visible) {
326        RenderingRequired = true;
327      } else {
328        if ((pictureBox.Width == 0) || (pictureBox.Height == 0)) {
329          pictureBox.Image = pictureBox.ErrorImage;
330          if (Picture != null) Picture.Dispose();
331          Picture = null;
332        } else {
333          if (Picture != null) Picture.Dispose();
334          Picture = new Bitmap(pictureBox.Width, pictureBox.Height);
335          using (var graphics = Graphics.FromImage(Picture)) {
336            graphics.SetClip(new System.Drawing.Rectangle(0, 0, pictureBox.Width, pictureBox.Height));
337            Chart.Render(graphics, pictureBox.Width, pictureBox.Height);
338          }
339        }
340        pictureBox.Image = Picture;
341        RenderingRequired = false;
342      }
343    }
344
345    public event EventHandler ModeChanged;
346    protected void OnModeChanged() {
347      var handler = ModeChanged;
348      if (handler != null) handler(this, EventArgs.Empty);
349    }
350
351    private void ChartControl_Load(object sender, EventArgs e) {
352      if (!SuppressRender) GenerateImage();
353    }
354
355    #region Helpers
356    private RadioButton CreateChartModeRadioButton(ChartMode chartMode) {
357      var rb = new RadioButton {
358        Appearance = Appearance.Button,
359        Image = chartMode.Image,
360        Size = new Size(24, 24),
361        TabStop = true,
362        Tag = chartMode,
363        UseVisualStyleBackColor = true
364      };
365
366      rb.CheckedChanged += (sender, args) => { if (rb.Checked) Mode = chartMode; };
367
368      return rb;
369    }
370    #endregion
371  }
372}
Note: See TracBrowser for help on using the repository browser.