Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1265: worked on visualization

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