diff --git a/.gitignore b/.gitignore
index 84632ef8f..b0aa39e64 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@ DeviceTest/bin/
DeviceTest/obj/
Dirichlet.Numerics/bin
Dirichlet.Numerics/obj
+GraphLib/bin
+GraphLib/obj
Results/bin/
Results/obj/
ResultsBrowser/bin/
diff --git a/GraphLib/BackBuffer.cs b/GraphLib/BackBuffer.cs
new file mode 100644
index 000000000..8af129bd7
--- /dev/null
+++ b/GraphLib/BackBuffer.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Drawing;
+
+
+
+/* Copyright (c) 2008-2014 DI Zimmermann Stephan (stefan.zimmermann@tele2.at)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+namespace GraphLib
+{
+ public class BackBuffer
+ {
+ private Graphics graphics;
+ private Bitmap memoryBitmap;
+ private int width;
+ private int height;
+
+ public BackBuffer()
+ {
+ width = 0;
+ height = 0;
+ }
+
+ public bool Init(Graphics g, int width, int height)
+ {
+ if (memoryBitmap != null)
+ {
+ memoryBitmap.Dispose();
+ memoryBitmap = null;
+ }
+
+ if (graphics != null)
+ {
+ graphics.Dispose();
+ graphics = null;
+ }
+
+ if (width == 0 || height == 0)
+ return false;
+
+ if ((width != this.width) || (height != this.height) || graphics == null)
+ {
+ this.width = width;
+ this.height = height;
+
+ memoryBitmap = new Bitmap(width, height);
+ graphics = Graphics.FromImage(memoryBitmap);
+ }
+
+ return true;
+ }
+
+ public void Render(Graphics g)
+ {
+ if (memoryBitmap != null)
+ {
+ g.DrawImage(memoryBitmap,
+ new Rectangle(0, 0, width, height),
+ 0, 0, width, height,
+ GraphicsUnit.Pixel);
+ }
+ }
+
+ public bool CanDoubleBuffer() { return graphics != null; }
+
+ public Graphics Graphics { get { return graphics; } }
+ }
+}
diff --git a/GraphLib/DataSource.cs b/GraphLib/DataSource.cs
new file mode 100644
index 000000000..052b7b78b
--- /dev/null
+++ b/GraphLib/DataSource.cs
@@ -0,0 +1,214 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.ComponentModel;
+using System.Drawing;
+
+/* Copyright (c) 2008-2014 DI Zimmermann Stephan (stefan.zimmermann@tele2.at)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace GraphLib
+{
+ public class DataSource
+ {
+ public delegate String OnDrawXAxisLabelEvent(DataSource src, int idx);
+ public delegate String OnDrawYAxisLabelEvent(DataSource src, float value);
+
+ public OnDrawXAxisLabelEvent OnRenderXAxisLabel = null;
+ public OnDrawYAxisLabelEvent OnRenderYAxisLabel = null;
+
+ private PointF[] samples = null;
+ private int length = 0;
+
+ private String name = String.Empty;
+ private int downSample = 1;
+ private Color color = Color.Black;
+
+ public float VisibleDataRange_X = 0;
+ public float DY = 0;
+ public float YD0 = -200;
+ public float YD1 = 200;
+ public float Cur_YD0 = -200;
+ public float Cur_YD1 = 200;
+
+ public float grid_distance_y = 200; // grid distance in units ( draw a horizontal line every 200 units )
+
+ public float off_Y = 0;
+ public float grid_off_y = 0;
+
+ public bool yFlip = true;
+
+ public bool Active = true;
+
+ public float XAutoScaleOffset = 100;
+
+ public float CurGraphHeight = 1.0f;
+
+ public float CurGraphWidth = 1.0f;
+
+ private bool autoScaleY = false;
+ private bool autoScaleX = false;
+
+
+ public bool AutoScaleY
+ {
+ get { return autoScaleY; }
+ set { autoScaleY = value; }
+ }
+
+ public bool AutoScaleX
+ {
+ get { return autoScaleX; }
+ set { autoScaleX = value; }
+ }
+
+ public PointF[] Samples
+ {
+ get { return samples; }
+ set
+ {
+ samples = value;
+ length = samples.Length;
+ }
+ }
+
+ public float XMin
+ {
+ get
+ {
+ float x_min = float.MaxValue;
+ if (samples != null && samples.Length > 0)
+ {
+ foreach (PointF p in samples) if (p.X < x_min) x_min=p.X;
+ }
+ return x_min;
+ }
+ }
+
+ public float XMax
+ {
+ get
+ {
+ float x_max = float.MinValue;
+ if (samples != null && samples.Length > 0)
+ {
+ foreach (PointF p in samples) if (p.X > x_max) x_max = p.X;
+ }
+ return x_max;
+ }
+ }
+
+ public float YMin
+ {
+ get
+ {
+ float y_min = float.MaxValue;
+ if (samples != null && samples.Length > 0)
+ {
+ foreach (PointF p in samples) if (p.Y < y_min) y_min = p.Y;
+ }
+ return y_min;
+ }
+ }
+
+ public float YMax
+ {
+ get
+ {
+ float y_max = float.MinValue;
+ if (samples.Length > 0)
+ {
+ foreach (PointF p in samples) if (p.Y > y_max) y_max = p.Y;
+ }
+ return y_max;
+ }
+ }
+
+ public void SetDisplayRangeY(float y_start, float y_end)
+ {
+ YD0 = y_start;
+ YD1 = y_end;
+ }
+
+ public void SetGridDistanceY(float grid_dist_y_units)
+ {
+ grid_distance_y = grid_dist_y_units;
+ }
+
+ public void SetGridOriginY(float off_y)
+ {
+ grid_off_y = off_y;
+ }
+
+ [Category("Properties")] // Take this out, and you will soon have problems with serialization;
+ [DefaultValue(typeof(string), "")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
+ public String Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ [Category("Properties")] // Take this out, and you will soon have problems with serialization;
+ [DefaultValue(typeof(Color), "")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
+ public Color GraphColor
+ {
+ get { return color; }
+ set { color = value; }
+ }
+
+ [Category("Properties")] // Take this out, and you will soon have problems with serialization;
+ [DefaultValue(typeof(int), "0")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
+ public int Length
+ {
+ get { return length; }
+ set
+ {
+ length = value;
+ if (length != 0)
+ {
+ samples = new PointF[length];
+ }
+ else
+ {
+ // length is 0
+ if (samples != null)
+ {
+ samples = null;
+ }
+ }
+ }
+ }
+
+ [Category("Properties")] // Take this out, and you will soon have problems with serialization;
+ [DefaultValue(typeof(int), "1")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
+ public int Downsampling
+ {
+ get { return downSample; }
+ set { downSample = value; }
+ }
+ }
+}
diff --git a/GraphLib/GraphLib.csproj b/GraphLib/GraphLib.csproj
new file mode 100644
index 000000000..049688a55
--- /dev/null
+++ b/GraphLib/GraphLib.csproj
@@ -0,0 +1,116 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.50727
+ 2.0
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}
+ Library
+ Properties
+ ClassLibrary1
+ GraphLib
+ v4.0
+
+
+
+
+ 2.0
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+ UserControl
+
+
+ PlotterGraphPaneEx.cs
+
+
+ UserControl
+
+
+ PlotterDisplayEx.cs
+
+
+
+ Form
+
+
+ PlotterGraphSelectCurvesForm.cs
+
+
+
+ Form
+
+
+ PrintPreviewForm.cs
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+
+ PlotterGraphPaneEx.cs
+ Designer
+
+
+ PlotterDisplayEx.cs
+ Designer
+
+
+ Designer
+ PlotterGraphSelectCurvesForm.cs
+
+
+ Designer
+ PrintPreviewForm.cs
+
+
+ Designer
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GraphLib/GraphLib.sln b/GraphLib/GraphLib.sln
new file mode 100644
index 000000000..53a616e76
--- /dev/null
+++ b/GraphLib/GraphLib.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphLib", "GraphLib.csproj", "{0C0A1F4D-1363-4544-A7C5-196C76D26CCA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/GraphLib/PlotterDisplayEx.cs b/GraphLib/PlotterDisplayEx.cs
new file mode 100644
index 000000000..4f5e6f4e0
--- /dev/null
+++ b/GraphLib/PlotterDisplayEx.cs
@@ -0,0 +1,433 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using System.Threading;
+using System.ComponentModel.Design;
+using System.Drawing.Drawing2D;
+
+
+/* Copyright (c) 2008-2014 DI Zimmermann Stephan (stefan.zimmermann@tele2.at)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+namespace GraphLib
+{
+ public partial class PlotterDisplayEx : UserControl
+ {
+ #region MEMBERS
+
+ delegate void InvokeVoidFuncDelegate();
+
+ PlotterGraphSelectCurvesForm GraphPropertiesForm = null;
+ PrintPreviewForm printPreviewForm = null;
+
+ private PrecisionTimer.Timer mTimer = null;
+ private float play_speed = 0.5f;
+ private float play_speed_max = 10f;
+ private float play_speed_min = 0.5f;
+
+ private bool paused = false;
+ private bool isRunning = false;
+
+ #endregion
+
+ #region CONSTRUCTOR
+
+ public PlotterDisplayEx()
+ {
+ InitializeComponent();
+ mTimer = new PrecisionTimer.Timer();
+ mTimer.Period = 50; // 20 fps
+ mTimer.Tick += new EventHandler(OnTimerTick);
+ play_speed = 0.5f; // 20x10 = 200 values per second == sample frequency
+ mTimer.Start();
+ isRunning = false;
+ }
+
+ void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
+ {
+ String text = e.ClickedItem.Text;
+ foreach (DataSource s in gPane.Sources)
+ {
+ if (s.Name == text)
+ {
+ s.Active ^= true;
+ gPane.Invalidate();
+ break;
+ }
+ }
+ }
+
+ #endregion
+
+ #region PROPERTIES
+
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
+ [Editor(typeof(System.ComponentModel.Design.CollectionEditor),
+ typeof(System.Drawing.Design.UITypeEditor))]
+ public IList DataSources
+ {
+ get { return gPane.Sources; }
+ }
+
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
+ [Editor(typeof(System.ComponentModel.Design.CollectionEditor),
+ typeof(System.Drawing.Design.UITypeEditor))]
+ public PlotterGraphPaneEx.LayoutMode PanelLayout
+ {
+ get { return gPane.layout; }
+ set { gPane.layout = value; }
+ }
+
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
+ [Editor(typeof(System.ComponentModel.Design.CollectionEditor),
+ typeof(System.Drawing.Design.UITypeEditor))]
+ public SmoothingMode Smoothing
+ {
+ get { return gPane.smoothing; }
+ set { gPane.smoothing = value; }
+ }
+
+ [Category("Playback")]
+ [DefaultValue(typeof(float), "2")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
+ public float PlaySpeed
+ {
+ get { return play_speed; }
+ set { play_speed = value; }
+ }
+
+ [Category("Playback")]
+ [DefaultValue(typeof(bool), "true")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
+ public bool ShowMovingGrid
+ {
+ get { return gPane.hasMovingGrid; }
+ set { gPane.hasMovingGrid = value; }
+ }
+
+
+ [Category("Properties")]
+ [DefaultValue(typeof(Color), "")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
+ public Color BackgroundColorTop
+ {
+ get { return gPane.BgndColorTop; }
+ set { gPane.BgndColorTop = value; }
+ }
+
+ [Category("Properties")]
+ [DefaultValue(typeof(Color), "")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
+ public Color BackgroundColorBot
+ {
+ get { return gPane.BgndColorBot; }
+ set { gPane.BgndColorBot = value; }
+ }
+
+ [Category("Properties")]
+ [DefaultValue(typeof(Color), "")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
+ public Color DashedGridColor
+ {
+ get { return gPane.MinorGridColor; }
+ set { gPane.MinorGridColor = value; }
+ }
+
+ [Category("Properties")]
+ [DefaultValue(typeof(Color), "")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
+ public Color SolidGridColor
+ {
+ get { return gPane.MajorGridColor; }
+ set { gPane.MajorGridColor = value; }
+ }
+
+
+ public bool DoubleBuffering
+ {
+ get { return gPane.useDoubleBuffer; }
+ set { gPane.useDoubleBuffer = value; }
+ }
+
+ #endregion
+
+ #region PUBLIC METHODS
+
+ public void SetDisplayRangeX(float x_start, float x_end )
+ {
+ gPane.XD0 = x_start;
+ gPane.XD1 = x_end;
+ gPane.CurXD0 = gPane.XD0;
+ gPane.CurXD1 = gPane.XD1;
+ }
+
+ public void SetGridDistanceX(float grid_dist_x_samples)
+ {
+ gPane.grid_distance_x = grid_dist_x_samples;
+ }
+
+ public void SetGridOriginX(float off_x)
+ {
+ gPane.grid_off_x = off_x;
+ }
+
+
+ #endregion
+
+ #region PRIVATE METHODS
+
+ protected override void Dispose(bool disposing)
+ {
+ paused = true;
+
+ if (mTimer.IsRunning)
+ {
+ mTimer.Stop();
+ mTimer.Dispose();
+ }
+
+ base.Dispose(disposing);
+ }
+
+ public void Start()
+ {
+ if (isRunning == false && paused == false)
+ {
+ gPane.starting_idx = 0;
+ paused = false;
+ isRunning = true;
+ // mTimer.Start();
+ tb1.Buttons[0].ImageIndex = 2;
+ }
+ else
+ {
+ if (paused == false)
+ {
+ //mTimer.Stop();
+ paused = true;
+ }
+ else
+ {
+ // mTimer.Start();
+ paused = false;
+ }
+
+ if (paused)
+ {
+
+ tb1.Buttons[0].ImageIndex = 0;
+ }
+ else
+ {
+
+ tb1.Buttons[0].ImageIndex = 2;
+ }
+ }
+ }
+
+ public void Stop()
+ {
+ if (isRunning)
+ {
+ // mTimer.Stop();
+ isRunning = false;
+ paused = false;
+ hScrollBar1.Value = 0;
+ tb1.Buttons[0].ImageIndex = 0;
+ }
+ }
+
+
+ private void tb1_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
+ {
+ bool pushed = e.Button.Pushed;
+ switch (e.Button.Tag.ToString().ToLower())
+ {
+ case "play":
+
+ Start();
+
+ break;
+
+ case "stop":
+
+ Stop();
+
+ break;
+
+ case "print":
+
+ // // todo implement print preview
+ ShowPrintPreview();
+
+ break;
+ }
+ }
+
+ private void SetPlayPanelVisible()
+ {
+ panel1.Visible = true;
+ tb1.Buttons[0].Visible = true;
+ tb1.Buttons[1].Visible = true;
+ }
+
+ private void SetPlayPanelInvisible()
+ {
+ panel1.Visible = false;
+ tb1.Buttons[0].Visible = false;
+ tb1.Buttons[1].Visible = false;
+
+ }
+
+ private void UpdateControl()
+ {
+ try
+ {
+ bool AllAutoscaled = true;
+
+ foreach (DataSource s in gPane.Sources)
+ {
+ AllAutoscaled &= s.AutoScaleX;
+ }
+
+
+ if (AllAutoscaled == true)
+ {
+ if (panel1.Visible == true)
+ {
+ this.Invoke(new MethodInvoker(SetPlayPanelInvisible));
+ }
+ }
+ else
+ {
+ if (panel1.Visible == false)
+ {
+ this.Invoke(new MethodInvoker(SetPlayPanelVisible));
+ }
+ }
+ }
+ catch
+ {
+ }
+ }
+
+ private void UpdatePlayback()
+ {
+ if (!paused && isRunning == true)
+ {
+ try
+ {
+ gPane.starting_idx += play_speed;
+ UpdateScrollBar();
+ gPane.Invalidate();
+ }
+ catch { }
+ }
+ }
+
+ private void OnTimerTick(object sender, EventArgs e)
+ {
+ UpdateControl();
+
+ UpdatePlayback();
+ }
+
+ private void UpdateScrollBar()
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new MethodInvoker(UpdateScrollBar));
+ }
+ else
+ {
+ if (gPane.Sources.Count > 0)
+ {
+ if (gPane.starting_idx > gPane.Sources[0].Length)
+ {
+ hScrollBar1.Value = 10000;
+ }
+ else if (gPane.starting_idx >= 0)
+ {
+ hScrollBar1.Value = 10000 * (int)gPane.starting_idx / gPane.Sources[0].Length;
+ }
+ else
+ {
+ hScrollBar1.Value = 0;
+ }
+ }
+ else
+ {
+ hScrollBar1.Value = 0;
+ }
+ }
+ }
+
+ private void OnScrollbarScroll(object sender, ScrollEventArgs e)
+ {
+ if (gPane.Sources.Count > 0)
+ {
+ int val = hScrollBar1.Value;
+ gPane.starting_idx = (int)(gPane.Sources[0].Length * (float)val / 10000.0f);
+ gPane.Invalidate();
+ }
+ }
+
+ private void OnScrollBarSpeedScroll(object sender, ScrollEventArgs e)
+ {
+ float Percentage = hScrollBar2.Value / 10000.0f;
+ float delta = play_speed_max - play_speed_min;
+ play_speed = play_speed_min + Percentage * delta;
+ }
+
+ #endregion
+
+ private void ShowPrintPreview()
+ {
+ if (printPreviewForm == null)
+ {
+ printPreviewForm = new PrintPreviewForm();
+ }
+
+ printPreviewForm.GraphPanel = this.gPane;
+ printPreviewForm.Show();
+ printPreviewForm.TopMost = true;
+ printPreviewForm.Invalidate();
+ }
+
+ private void selectGraphsToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ if (GraphPropertiesForm == null)
+ {
+ GraphPropertiesForm = new PlotterGraphSelectCurvesForm();
+ }
+
+ GraphPropertiesForm.GraphPanel = this.gPane;
+ GraphPropertiesForm.Show();
+ // GraphPropertiesForm.BringToFront();
+
+ }
+ }
+}
diff --git a/GraphLib/PlotterDisplayEx.designer.cs b/GraphLib/PlotterDisplayEx.designer.cs
new file mode 100644
index 000000000..0fe6fde47
--- /dev/null
+++ b/GraphLib/PlotterDisplayEx.designer.cs
@@ -0,0 +1,249 @@
+namespace GraphLib
+{
+ partial class PlotterDisplayEx
+ {
+
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PlotterDisplayEx));
+ this.tb1 = new System.Windows.Forms.ToolBar();
+ this.tbbSave = new System.Windows.Forms.ToolBarButton();
+ this.tbbOpen = new System.Windows.Forms.ToolBarButton();
+ this.tbbSeparator3 = new System.Windows.Forms.ToolBarButton();
+ this.tbbPrint = new System.Windows.Forms.ToolBarButton();
+ this.toolBarButton2 = new System.Windows.Forms.ToolBarButton();
+ this.imgList1 = new System.Windows.Forms.ImageList(this.components);
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.lb_Position = new System.Windows.Forms.Label();
+ this.label1 = new System.Windows.Forms.Label();
+ this.hScrollBar2 = new System.Windows.Forms.HScrollBar();
+ this.hScrollBar1 = new System.Windows.Forms.HScrollBar();
+ this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.selectGraphsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.gPane = new GraphLib.PlotterGraphPaneEx();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.contextMenuStrip1.SuspendLayout();
+ this.panel1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // tb1
+ //
+ this.tb1.Appearance = System.Windows.Forms.ToolBarAppearance.Flat;
+ this.tb1.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
+ this.tbbSave,
+ this.tbbOpen,
+ this.tbbSeparator3,
+ this.tbbPrint,
+ this.toolBarButton2});
+ this.tb1.ButtonSize = new System.Drawing.Size(16, 16);
+ this.tb1.Divider = false;
+ this.tb1.Dock = System.Windows.Forms.DockStyle.None;
+ this.tb1.DropDownArrows = true;
+ this.tb1.ImageList = this.imgList1;
+ this.tb1.Location = new System.Drawing.Point(11, 5);
+ this.tb1.Name = "tb1";
+ this.tb1.ShowToolTips = true;
+ this.tb1.Size = new System.Drawing.Size(80, 26);
+ this.tb1.TabIndex = 1;
+ this.tb1.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.tb1_ButtonClick);
+ //
+ // tbbSave
+ //
+ this.tbbSave.ImageIndex = 0;
+ this.tbbSave.Name = "tbbSave";
+ this.tbbSave.Tag = "play";
+ //
+ // tbbOpen
+ //
+ this.tbbOpen.ImageIndex = 1;
+ this.tbbOpen.Name = "tbbOpen";
+ this.tbbOpen.Tag = "stop";
+ //
+ // tbbSeparator3
+ //
+ this.tbbSeparator3.Name = "tbbSeparator3";
+ this.tbbSeparator3.Style = System.Windows.Forms.ToolBarButtonStyle.Separator;
+ //
+ // tbbPrint
+ //
+ this.tbbPrint.ImageIndex = 3;
+ this.tbbPrint.Name = "tbbPrint";
+ this.tbbPrint.Tag = "print";
+ //
+ // toolBarButton2
+ //
+ this.toolBarButton2.Name = "toolBarButton2";
+ this.toolBarButton2.Style = System.Windows.Forms.ToolBarButtonStyle.Separator;
+ //
+ // imgList1
+ //
+ this.imgList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList1.ImageStream")));
+ this.imgList1.TransparentColor = System.Drawing.Color.Transparent;
+ this.imgList1.Images.SetKeyName(0, "media-playback-start.png");
+ this.imgList1.Images.SetKeyName(1, "media-playback-stop.png");
+ this.imgList1.Images.SetKeyName(2, "media-playback-pause.png");
+ this.imgList1.Images.SetKeyName(3, "printer.png");
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.BackColor = System.Drawing.SystemColors.Control;
+ this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+ this.splitContainer1.IsSplitterFixed = true;
+ this.splitContainer1.Location = new System.Drawing.Point(0, 0);
+ this.splitContainer1.Name = "splitContainer1";
+ this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.BackColor = System.Drawing.SystemColors.ControlDarkDark;
+ this.splitContainer1.Panel1.Controls.Add(this.tb1);
+ this.splitContainer1.Panel1.Controls.Add(this.panel1);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.BackColor = System.Drawing.Color.Transparent;
+ this.splitContainer1.Panel2.Controls.Add(this.gPane);
+ this.splitContainer1.Size = new System.Drawing.Size(598, 339);
+ this.splitContainer1.SplitterDistance = 34;
+ this.splitContainer1.TabIndex = 2;
+ this.splitContainer1.TabStop = false;
+ //
+ // lb_Position
+ //
+ this.lb_Position.AutoSize = true;
+ this.lb_Position.ForeColor = System.Drawing.SystemColors.ControlLightLight;
+ this.lb_Position.Location = new System.Drawing.Point(6, 8);
+ this.lb_Position.Name = "lb_Position";
+ this.lb_Position.Size = new System.Drawing.Size(44, 13);
+ this.lb_Position.TabIndex = 3;
+ this.lb_Position.Text = "Position";
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.ForeColor = System.Drawing.SystemColors.ControlLightLight;
+ this.label1.Location = new System.Drawing.Point(180, 8);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(85, 13);
+ this.label1.TabIndex = 2;
+ this.label1.Text = "Playback Speed";
+ //
+ // hScrollBar2
+ //
+ this.hScrollBar2.Location = new System.Drawing.Point(268, 10);
+ this.hScrollBar2.Maximum = 10000;
+ this.hScrollBar2.Name = "hScrollBar2";
+ this.hScrollBar2.Size = new System.Drawing.Size(111, 10);
+ this.hScrollBar2.TabIndex = 6;
+ this.hScrollBar2.Value = 1;
+ this.hScrollBar2.Scroll += new System.Windows.Forms.ScrollEventHandler(this.OnScrollBarSpeedScroll);
+ //
+ // hScrollBar1
+ //
+ this.hScrollBar1.Location = new System.Drawing.Point(57, 10);
+ this.hScrollBar1.Maximum = 10000;
+ this.hScrollBar1.Name = "hScrollBar1";
+ this.hScrollBar1.Size = new System.Drawing.Size(118, 10);
+ this.hScrollBar1.TabIndex = 4;
+ this.hScrollBar1.Scroll += new System.Windows.Forms.ScrollEventHandler(this.OnScrollbarScroll);
+ //
+ // contextMenuStrip1
+ //
+ this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.selectGraphsToolStripMenuItem,
+ this.toolStripSeparator1});
+ this.contextMenuStrip1.Name = "contextMenuStrip1";
+ this.contextMenuStrip1.Size = new System.Drawing.Size(117, 32);
+ //
+ // selectGraphsToolStripMenuItem
+ //
+ this.selectGraphsToolStripMenuItem.Name = "selectGraphsToolStripMenuItem";
+ this.selectGraphsToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
+ this.selectGraphsToolStripMenuItem.Text = "Options";
+ this.selectGraphsToolStripMenuItem.Click += new System.EventHandler(this.selectGraphsToolStripMenuItem_Click);
+ //
+ // toolStripSeparator1
+ //
+ this.toolStripSeparator1.Name = "toolStripSeparator1";
+ this.toolStripSeparator1.Size = new System.Drawing.Size(113, 6);
+ //
+ // panel1
+ //
+ this.panel1.Controls.Add(this.lb_Position);
+ this.panel1.Controls.Add(this.label1);
+ this.panel1.Controls.Add(this.hScrollBar1);
+ this.panel1.Controls.Add(this.hScrollBar2);
+ this.panel1.Location = new System.Drawing.Point(99, 3);
+ this.panel1.Name = "panel1";
+ this.panel1.Size = new System.Drawing.Size(496, 28);
+ this.panel1.TabIndex = 7;
+ //
+ // gPane
+ //
+ this.gPane.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.gPane.Location = new System.Drawing.Point(0, 0);
+ this.gPane.Name = "gPane";
+ this.gPane.Size = new System.Drawing.Size(598, 301);
+ this.gPane.TabIndex = 1;
+ //
+ // PlotterDisplayEx
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.BackColor = System.Drawing.Color.Transparent;
+ this.ContextMenuStrip = this.contextMenuStrip1;
+ this.Controls.Add(this.splitContainer1);
+ this.Name = "PlotterDisplayEx";
+ this.Size = new System.Drawing.Size(598, 339);
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel1.PerformLayout();
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ this.splitContainer1.ResumeLayout(false);
+ this.contextMenuStrip1.ResumeLayout(false);
+ this.panel1.ResumeLayout(false);
+ this.panel1.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ToolBar tb1;
+ private System.Windows.Forms.ToolBarButton tbbSeparator3;
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ private System.Windows.Forms.ToolBarButton tbbSave;
+ private System.Windows.Forms.ToolBarButton tbbOpen;
+ private System.Windows.Forms.HScrollBar hScrollBar1;
+ private PlotterGraphPaneEx gPane;
+ private System.Windows.Forms.HScrollBar hScrollBar2;
+ private System.Windows.Forms.Label lb_Position;
+ private System.Windows.Forms.Label label1;
+ public System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
+ private System.Windows.Forms.ToolStripMenuItem selectGraphsToolStripMenuItem;
+ private System.Windows.Forms.ImageList imgList1;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
+ private System.Windows.Forms.ToolBarButton tbbPrint;
+ private System.Windows.Forms.ToolBarButton toolBarButton2;
+ private System.Windows.Forms.Panel panel1;
+
+ }
+}
diff --git a/GraphLib/PlotterDisplayEx.resx b/GraphLib/PlotterDisplayEx.resx
new file mode 100644
index 000000000..553fc67fc
--- /dev/null
+++ b/GraphLib/PlotterDisplayEx.resx
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
+ LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACO
+ DgAAAk1TRnQBSQFMAgEBBAEAAQwBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+ AwABIAMAAQEBAAEgBgABIP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AKgADAQECwAABuAGV
+ AVEB/QHKAZgBWwH/AcoBlwFbAf8BygGXAVsB/wHKAZcBWwH/AcoBlwFaAf8ByQGXAVoB/wHJAZcBWgH/
+ AcoBmAFbAf8BuAGUAVEB/RQAAxQBHAMRARcDAgEDrAADTgGZA10B0gNOAf8BxwGVAVcB/wH5AfcB9gH/
+ AfkB8QHsAf8B+QHxAesB/wH4AfAB6QH/AfcB7QHmAf8B9AHqAeEB/wHyAegB3gH/AfoB+AH2Af8BxwGU
+ AVcB/wMaAf8DWAHRA0QBeggAAxUBHQFiAlgB6QM6AWEDDQESAwABASwAAxsBJgMbASYDGwEmAxsBJgMb
+ ASYDGwEmAxsBJgMbASYDGwEmAxsBJgMbASYDGwEmEAADGwEmAxsBJgMbASYDGwEmAxsBJgMbASYDGwEm
+ AxsBJgMbASYDGwEmAxsBJgMbASYIAANXAf0DpwH/A7UB/wOBAf8BrwGsAaoB/wHFAcABvQH/AcUBwAG9
+ Af8BxQHAAb0B/wHFAcABvQH/AcUBwAG9Af8BxQHAAb0B/wGtAaoBqAH/AyIB/wO1Af8DmwH/AxkB/wgA
+ AxUBHQNNAfoBPAIrAfwDXwHgAysBQgMNARIoAAMbASYBLAIrAfwBgAKBAf8BgAKBAf8BgAKBAf8BgAKB
+ Af8BgAKBAf8BgAKBAf8BgAKBAf8BgAKBAf8BgAKBAf8DGwEmEAADGwEmASwCKwH8AYACgQH/AYACgQH/
+ AYACgQH/AyMBNAMbASYBLAIrAfwBgAKBAf8BgAKBAf8BgAKBAf8DIwE0CAADZgH/A7UB/wO1Af8DlQH/
+ A4EB/wOBAf8DbwH/A2QB/wNXAf8DSAH/AzkB/wM4Af8DZAH/A7UB/wO1Af8DGwH/CAADFQEdAV8CSgH7
+ AfkB+gH5Af8DfwH+AV8BUwFSAfsDVQGyAx0BKgMIAQsgAAMbASYDQAH9IP8DQAH9AxsBJgMAAQEMAAMb
+ ASYDQAH9AfwB/QH8Bf8DQAH9AxsBJgMbASYDQAH9AfwB/QH8Bf8DQAH9AxsBJgMAAQEEAANrAf8DuwH/
+ A7sB/wONAf8D1AH/A7kB/wO5Af8DuQH/A7kB/wO5Af8DuQH/A9MB/wODAf8DuwH/A7sB/wMgAf8IAAMV
+ AR0DKwH8AfoC+wH/AfUC9gH/AfkC+gH/AT0BMAEvAfwBbQJRAfcDQgF2AxYBHgMFAQcYAAMbASYDQAH9
+ BP8B1QHbAdgB/wHUAdsB1wH/AdQB2wHYAf8B0wHbAdcB/wHRAdkB1QH/Ac8B1wHTBf8DQAH9AxsBJgMB
+ AQIMAAMbASYDQAH9AeIB5QHkAf8B2AHfAdwB/wNAAf0DGwEmAxsBJgNAAf0D8wH/AfcB+AH3Af8DQAH9
+ AxsBJgMBAQIEAANwAf8D1wH/A9cB/wOXAf8D2AH/A78B/wO/Af8DvwH/A78B/wO/Af8DvwH/A9cB/wOO
+ Af8D1wH/A9cB/wM1Af8IAAMWAR4DKwH8A/sB/wHTAdoB1wH/AdoB3wHcAf8B9gH3AfYB/wHyAvMB/wE8
+ AisB/AFgAlkB6wMzAVMDEgEZAwQBBRAAAxsBJgNAAf0E/wHaAeAB3QH/AdsB4QHeAf8B3QHiAeAB/wHd
+ AeIB4AH/AdsB4QHeAf8B2AHeAdsF/wNAAf0DGwEmAwEBAgwAAxsBJgNAAf0B4gHmAeQB/wHcAeIB3wH/
+ A0AB/QMbASYDGwEmA0AB/QHvAfEB8AH/AfAB8wHxAf8DQAH9AxsBJgMBAQIEAAN0Af8D+QH/A/kB/wOr
+ Af8D3wH/A8sB/wPLAf8DywH/A8sB/wPLAf8DywH/A98B/wOjAf8D+QH/A/kB/wNXAf8IAAMWAR4DKwH8
+ A/sB/wHfAeQB4QH/Ad4B4wHhAf8B3gHjAeAB/wHjAecB5QH/AfQC9QH/A38B/gGRAkAB/QNWAbYDJgE5
+ AxABFQwAAxsBJgNAAf0E/wHdAeMB4AH/AeEB5gHjAf8B5AHpAecB/wHmAeoB6AH/AeUB6QHnAf8B4gHn
+ AeQF/wNAAf0DGwEmAwEBAgwAAxsBJgNAAf0B5AHoAeUB/wHeAeMB4QH/A0AB/QMbASYDGwEmA0AB/QHs
+ Ae8B7gH/AecB6wHpAf8DQAH9AxsBJgMBAQIEAANqAfkD/AH/A/wB/wPLAf8D8gH/A/IB/wPyAf8D8gH/
+ A/IB/wPyAf8D8gH/A/IB/wPGAf8D/AH/A/wB/wNwAf4IAAMWAR4DKwH8A/sB/wHqAe4B7AH/AewB7wHu
+ Af8B7AHvAe4B/wHrAe4B7QH/AekB7AHrAf8DfwH+ATwCKwH8AVgCVgG7Ax0BKgMGAQgMAAMbASYDQAH9
+ BP8B3wHkAeEB/wHkAekB5gH/AeoB7QHrAf8B7gHxAe8B/wHvAfEB8AH/AewB7wHuBf8DQAH9AxsBJgMB
+ AQIMAAMbASYDQAH9AesB7QHsAf8B3QHjAeAB/wNAAf0DGwEmAxsBJgNAAf0B7QHwAe8B/wHfAeQB4QH/
+ A0AB/QMbASYDAQECBAADXQTSAf8D6AH/A3MB/wNzAf8DcwH/A3MB/wNzAf8DcwH/A3MB/wNzAf8DcwH/
+ A3MB/wPoAf8DxAH/A1wB3AgAAxYBHgMrAfwD+wH/AfUC9gH/AfoB+wH6Af8D+QH/Ad0C3gH/AWoCRwH5
+ A10B7QE6AjkBYAMNAREUAAMbASYDQAH9BP8B3AHiAd8B/wHkAegB5gH/AesB7gHtAf8B8gH0AfMB/wH3
+ AvgB/wH2AfgB9wX/A0AB/QMbASYDAQECDAADGwEmA0AB/QHyAfQB8wH/AdoB3wHdAf8DQAH9AxsBJgMc
+ ASgDQAH9AfMB9QH0Af8B1gHdAdkB/wNAAf0DGwEmAwEBAgQAAy0BRQOaAf8DzAH/AccBiwFEAf8B+QH0
+ Ae0B/wH+AegB2AH/Af4B6AHXAf8B/QHlAdMB/wH8AeQB0QH/AfoB4AHHAf8B+QHdAcMB/wH6AfQB7QH/
+ AccBhQFAAf8DwwH/A2oB/wMtAUUIAAMWAR4DKwH8A/sB/wHwAfMB8gH/AeYC6AH/A00B+gFiAlIB9AFR
+ Ak8BpQMUARwDAAEBGAADGwEmA0AB/QT/AdgB3wHcAf8B4AHlAeMB/wHoAesB6gH/Ae8B8gHwAf8B9wH4
+ AfcB/wP9Bf8DQAH9AxsBJgMBAQIMAAMbASYDQAH9A/wB/wHVAdsB2AH/A0AB/QMbASYDHAEoA0AB/QP8
+ Af8B0gHaAdYB/wNAAf0DGwEmAwEBAggAAzsBYwNsAfMBxQGJAUIB/wH5AfQB7wH/Af4B5wHXAf8B/QHn
+ AdUB/wH8AeYB0gH/AfsB4QHMAf8B+AHcAcIB/wH2AdoBvQH/AfoB9AHvAf8BxAGDAT4B/wNdAfMDOwFj
+ DAADFgEeAysB/AP7Af8BQQI0AfwDTQH6AVoCVwG9AxgBIgMCAQMgAAMbASYDQAH9IP8DQAH9AxsBJgMB
+ AQIMAAMbASYDQAH9CP8DQAH9AxsBJgMcASgDQAH9CP8DQAH9AxsBJgMBAQIMAAMHAQkBngF/AUcC+QH0
+ AfAB/wH8AeYB0wH/Af0B5wHTAf8B+wHjAc0B/wH6AeAByAH/AfUB1gG7Af8B8wHUAbUB/wH4AfQB8AH/
+ AZ0BawFHAfkDBwEJEAADFgEeA0AB/QFbAjIB+wFgAlwB1AMjATMDBwEKKAADGwEmAysB/AErAS8BLQH/
+ ASsBLwEtAf8BKwEvAS0B/wErAS8BLQH/ASsBLwEtAf8BKwEvAS0B/wErAS8BLQH/ASsBLwEtAf8BKwEv
+ AS0B/wMbASYDAQECDAADGwEmAWMBVwFVAf4BKwEvAS0B/wErAS8BLQH/ASsBLwEtAf8DGwEmAxwBKAFj
+ AVcBVQH+ASsBLwEtAf8BKwEvAS0B/wErAS8BLQH/AxsBJgMBAQIQAAGaAX8BUQH3AfkB9QHxAf8B/AHj
+ Ac8B/wH8AeQBzwH/AfoB4QHKAf8B+QHdAcQB/wH0AekB3wH/AfcB8gHsAf8B9QHvAekB/wGdAWIBRQH7
+ FAADFgEfAV4CWgHYAygBPQMNAREwAAMbASYDGwEmAxsBJgMbASYDGwEmAxsBJgMbASYDGwEmAxsBJgMb
+ ASYDGwEmAxsBJgMAAQEMAAMbASYDGwEmAxsBJgMbASYDGwEmAxsBJgMbASYDGwEmAxsBJgMbASYDGwEm
+ AxsBJgMAAQEQAAGQAXABSQH2AfkB9QHxAf8B/AHjAc0B/wH7AeMBzQH/AfkB4AHIAf8B+AHcAcIB/wH9
+ AfsB+AH/AfwB5gHNAf8B4gG2AYQB/wJUAVIBphQAAxYBHwMRARcDAgEDuAABogF3AU0B+gH3AfIB7AH/
+ AfgB9AHuAf8B+AHzAe0B/wH4AfMB7QH/AfgB8gHsAf8B8gHmAdcB/wHiAbIBcwH/AZcBdQFiAfYDBQEH
+ FAADAwEEwAADOgFgAlgBVgG7AbUBfwFPAf4ByAGMAUUB/wGaAYEBUQH3AZoBgQFRAfcBsgF/AUwB/gNO
+ AZQUAAFCAU0BPgcAAT4DAAEoAwABQAMAASADAAEBAQABAQYAAQEWAAP/gQAB3wX/AeABBwHHBf8CAAHB
+ Af8BwAEDAcABAwIAAcAB/wHAAQMBwAEDAgABwAE/AcABAQHAAQECAAHAAQ8BwAEBAcABAQIAAcABAwHA
+ AQEBwAEBAgABwAEBAcABAQHAAQECAAHAAQEBwAEBAcABAQIAAcABBwHAAQEBwAEBAgABwAEPAcABAQHA
+ AQEBgAEBAcABPwHAAQEBwAEBAcABAwHAAf8BwAEBAcABAQHgAQcBwwH/AcABAQHAAQEB4AEHAccF/wHg
+ AQcB3wX/AeABHws=
+
+
+
+ 84, 17
+
+
\ No newline at end of file
diff --git a/GraphLib/PlotterGraphPaneEx.Designer.cs b/GraphLib/PlotterGraphPaneEx.Designer.cs
new file mode 100644
index 000000000..9c05883dd
--- /dev/null
+++ b/GraphLib/PlotterGraphPaneEx.Designer.cs
@@ -0,0 +1,46 @@
+namespace GraphLib
+{
+ partial class PlotterGraphPaneEx
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.SuspendLayout();
+ //
+ // PlotterGraphPane
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Name = "PlotterGraphPane";
+ this.Size = new System.Drawing.Size(409, 150);
+ this.Load += new System.EventHandler(this.OnLoadControl);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+ }
+}
diff --git a/GraphLib/PlotterGraphPaneEx.cs b/GraphLib/PlotterGraphPaneEx.cs
new file mode 100644
index 000000000..39d200573
--- /dev/null
+++ b/GraphLib/PlotterGraphPaneEx.cs
@@ -0,0 +1,1062 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using System.Drawing.Drawing2D;
+
+ /* Copyright (c) 2008-2014 DI Zimmermann Stephan (stefan.zimmermann@tele2.at)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace GraphLib
+{
+ public partial class PlotterGraphPaneEx : UserControl
+ {
+ #region MEMBERS
+
+ public enum LayoutMode
+ {
+ NORMAL,
+ STACKED,
+ VERTICAL_ARRANGED,
+ TILES_VER,
+ TILES_HOR,
+ }
+
+ private BackBuffer backBuffer;
+ private int ActiveSources = 0;
+
+ public LayoutMode layout = LayoutMode.NORMAL;
+
+ public Color MajorGridColor = Color.DarkGray;
+ public Color MinorGridColor = Color.DarkGray;
+ public Color GraphColor = Color.DarkGreen;
+ public Color BgndColorTop = Color.White;
+ public Color BgndColorBot = Color.White;
+ public Color LabelColor = Color.White;
+ public Color GraphBoxColor = Color.White;
+ public bool useDoubleBuffer = false;
+ public Font legendFont = new Font(FontFamily.GenericSansSerif, 8.25f);
+
+ private IList sources = new List();
+
+ public SmoothingMode smoothing = SmoothingMode.None;
+
+ public bool hasMovingGrid = true;
+ public bool hasBoundingBox = true;
+
+ private Point mousePos = new Point();
+ private bool mouseDown = false;
+
+
+ public float starting_idx = 0;
+
+
+ public float XD0 = -50;
+
+ public float XD1 = 100;
+
+ public float DX = 0;
+
+ public float off_X = 0;
+
+ public float CurXD0 = 0;
+
+ public float CurXD1 = 0;
+
+ public float grid_distance_x = 200; // grid distance in samples ( draw a vertical line every 200 samples )
+ public float grid_off_x = 0;
+ public float GraphCaptionLineHeight = 28;
+
+ public float pad_inter = 4; // padding between graphs
+ public float pad_left = 10; // left padding
+ public float pad_right = 10; // right padding
+ public float pad_top = 10; // top
+ public float pad_bot = 10; // bottom padding
+
+ public float graph_distance_x = 10; // distance between graphs, x direction
+ public float graph_distance_y = 10; // distance between graphs, y direction
+
+ public float yLabelAreaWidth = 40; // y-label area width
+
+ public float xLabelAreaheight = 8; // x-label padding ( bottom area left and right were x labels are still visible )
+
+ PointF graphCaptionOffset = new PointF(12, 2);
+
+ public float[] MinorGridPattern = new float[] { 2,4 };
+ public float[] MajorGridPattern = new float[] { 2,2 };
+
+ DashStyle MinorGridDashStyle = DashStyle.Custom;
+ DashStyle MajorGridDashStyle = DashStyle.Custom;
+ public bool MoveMinorGrid = true;
+
+ #endregion
+
+ #region CONSTRUCTOR
+
+ public PlotterGraphPaneEx()
+ {
+ backBuffer = new BackBuffer();
+
+ InitializeComponent();
+
+ this.Resize += new System.EventHandler(this.OnResizeForm);
+ this.MouseDown += new MouseEventHandler(OnMouseDown);
+ this.MouseUp += new MouseEventHandler(OnMouseUp);
+ this.MouseMove += new MouseEventHandler(OnMouseMove);
+ }
+
+ #endregion
+
+ public IList Sources { get { return sources; } }
+
+ private void OnLoadControl(object sender, EventArgs e)
+ {
+ backBuffer.Init(this.CreateGraphics(), this.ClientRectangle.Width, this.ClientRectangle.Height);
+ }
+
+ protected override void OnPaintBackground(PaintEventArgs e)
+ {
+ if (ParentForm == null)
+ {
+ // paint background when control is used in editor
+ base.OnPaintBackground(e);
+
+ }
+ else
+ {
+ // do not repaint background to avoid flickering
+ }
+ }
+
+ private void OnResizeForm(object sender, System.EventArgs e)
+ {
+ backBuffer.Init(this.CreateGraphics(), ClientRectangle.Width, ClientRectangle.Height);
+ Invalidate();
+ }
+
+ private void OnMouseUp(object sender, MouseEventArgs e)
+ {
+ if (mouseDown == true)
+ {
+ mouseDown = false;
+ Cursor = Cursors.Default;
+ }
+ }
+
+ private void OnMouseDown(object sender, MouseEventArgs e)
+ {
+ if (mouseDown == false)
+ {
+ mouseDown = true;
+ mousePos = e.Location;
+ Cursor = Cursors.Hand;
+ }
+ }
+
+ private void OnMouseMove(object sender, MouseEventArgs e)
+ {
+ if (mouseDown)
+ {
+ float dx = mousePos.X - e.Location.X;
+
+ mousePos = e.Location;
+
+ float DX = CurXD1 - CurXD0;
+
+ float off_X = dx * DX / this.Width;
+
+ if (Math.Abs(off_X) > 0)
+ {
+ starting_idx += off_X;
+ }
+
+ Invalidate();
+ }
+ }
+
+ public void PaintGraphs(Graphics CurGraphics, float CurWidth, float CurHeight, float OFFX, float OFFY)
+ {
+ int CurGraphIdx = 0;
+ int VertTileCount = 1;
+ int HorTileCount = 1;
+
+ float curOffY = 0;
+ float CurOffX = 0;
+
+ if ((layout == LayoutMode.TILES_VER || layout == LayoutMode.TILES_HOR) && ActiveSources >= 1)
+ {
+ // calculate number of tiles
+ if (layout == LayoutMode.TILES_VER)
+ {
+ VertTileCount = 1;
+ HorTileCount = 1;
+ while (true)
+ {
+ if (VertTileCount * HorTileCount >= ActiveSources) break;
+ VertTileCount++;
+ if (VertTileCount * HorTileCount >= ActiveSources) break;
+ HorTileCount++;
+ }
+ }
+ else if (layout == LayoutMode.TILES_HOR)
+ {
+ VertTileCount = 1;
+ HorTileCount = 1;
+ while (true)
+ {
+ if (VertTileCount * HorTileCount >= ActiveSources) break;
+ HorTileCount++;
+ if (VertTileCount * HorTileCount >= ActiveSources) break;
+ VertTileCount++;
+ }
+ }
+ }
+
+ foreach (DataSource source in sources)
+ {
+ source.Cur_YD0 = source.YD0;
+ source.Cur_YD1 = source.YD1;
+
+ source.CurGraphHeight = CurHeight;
+ source.CurGraphWidth = CurWidth - pad_left - yLabelAreaWidth - pad_right;
+
+ if (source.yFlip)
+ {
+ DX = XD1 - XD0;
+ }
+ else
+ {
+ DX = XD1 - XD0;
+ }
+
+ CurXD0 = XD0;
+ CurXD1 = XD1;
+
+ if (source.AutoScaleX && source.Samples.Length > 0)
+ {
+ CurXD0 = source.XMin - source.XAutoScaleOffset;
+ CurXD1 = source.XMax + source.XAutoScaleOffset;
+ DX = CurXD1 - CurXD0;
+ }
+
+ if (source.Active)
+ {
+ if (source.AutoScaleY == true)
+ {
+ int idx_start = -1;
+ int idx_stop = -1;
+ float ymin = 0.0f;
+ float ymax = 0.0f;
+ float ymin_range = 0;
+ float ymax_range = 0;
+
+ int DownSample = source.Downsampling;
+ PointF[] data = source.Samples;
+ float mult_y = source.CurGraphHeight / source.DY;
+ float mult_x = source.CurGraphWidth / DX;
+ float coff_x = off_X - starting_idx * mult_x;
+
+ if (source.AutoScaleX)
+ {
+ coff_x = off_X ;
+ }
+
+ for (int i = 0; i < data.Length - 1; i += DownSample)
+ {
+ float x = data[i].X * mult_x + coff_x;
+
+ if (data[i].Y > ymax) ymax = data[i].Y;
+ if (data[i].Y < ymin) ymin = data[i].Y;
+
+ if (x > 0 && x < (source.CurGraphWidth))
+ {
+ if (idx_start == -1) idx_start = i;
+ idx_stop = i;
+
+ if (data[i].Y > ymax_range) ymax_range = data[i].Y;
+ if (data[i].Y < ymin_range) ymin_range = data[i].Y;
+ }
+ }
+
+ if (idx_start >= 0 && idx_stop >= 0)
+ {
+ float data_range = ymax - ymin; // this is range in the data
+ float delta_range = ymax_range - ymin_range; // this is the visible data range -> might be smaller
+
+ source.Cur_YD0 = ymin_range;
+ source.Cur_YD1 = ymax_range;
+ }
+ }
+
+ if (layout == LayoutMode.VERTICAL_ARRANGED && ActiveSources >= 1)
+ {
+ if (ActiveSources > 1)
+ {
+ source.CurGraphHeight = (float)(CurHeight - pad_top - pad_bot) / ActiveSources - GraphCaptionLineHeight;
+ float Diff = ((ActiveSources - 1) * pad_inter) / ActiveSources;
+ source.CurGraphHeight -= Diff;
+ }
+ else
+ {
+ source.CurGraphHeight = (float)(CurHeight - pad_top - pad_bot) - GraphCaptionLineHeight;
+ }
+ }
+ else if (layout == LayoutMode.STACKED && ActiveSources >= 1)
+ {
+ if (ActiveSources > 1)
+ {
+ source.CurGraphHeight = (float)(CurHeight - pad_top - pad_bot) / ActiveSources - GraphCaptionLineHeight;
+ }
+ else
+ {
+ source.CurGraphHeight = (float)(CurHeight - pad_top - pad_bot) - GraphCaptionLineHeight;
+ }
+ }
+ else if ((layout == LayoutMode.TILES_VER || layout == LayoutMode.TILES_HOR) && ActiveSources >= 1)
+ {
+ if (ActiveSources > 1)
+ {
+ source.CurGraphHeight = (float)(CurHeight - pad_top - pad_bot) / VertTileCount - GraphCaptionLineHeight;
+ float Diff = ((ActiveSources - 1) * pad_inter) / VertTileCount;
+ source.CurGraphHeight -= Diff;
+ source.CurGraphWidth = (float)(CurWidth - pad_left - pad_right) / HorTileCount - yLabelAreaWidth;
+ }
+ else
+ {
+ source.CurGraphHeight = (float)(CurHeight - pad_top - pad_bot) - GraphCaptionLineHeight;
+ }
+ }
+ else
+ {
+ source.CurGraphHeight = (float)(CurHeight - pad_top - pad_bot) - GraphCaptionLineHeight;
+ source.CurGraphWidth = CurWidth - pad_left - yLabelAreaWidth * ActiveSources - pad_right;
+
+ }
+
+ if (source.yFlip)
+ {
+ source.DY = source.Cur_YD0 - source.Cur_YD1;
+
+ if (DX != 0 && source.DY != 0)
+ {
+ source.off_Y = -source.Cur_YD1 * source.CurGraphHeight / source.DY;
+ off_X = -CurXD0 * source.CurGraphWidth / DX;
+ }
+ }
+ else
+ {
+ source.DY = source.Cur_YD1 - source.Cur_YD0;
+
+ if (DX != 0 && source.DY != 0)
+ {
+ source.off_Y = -source.Cur_YD0 * source.CurGraphHeight / source.DY;
+ off_X = -CurXD0 * source.CurGraphWidth / DX;
+ }
+ }
+
+ if ((layout == LayoutMode.TILES_VER || layout == LayoutMode.TILES_HOR))
+ {
+ if (ActiveSources > 1)
+ {
+ if (layout == LayoutMode.TILES_VER)
+ {
+ // TODO: calc curOffX and CurrOffY for CurGraphIdx!!
+ int CurIdxY = CurGraphIdx % VertTileCount;
+ int CurIdxX = CurGraphIdx / VertTileCount;
+
+ curOffY = OFFY + pad_top + CurIdxY * (source.CurGraphHeight + GraphCaptionLineHeight);
+ CurOffX = OFFX + yLabelAreaWidth + pad_left + CurIdxX * (yLabelAreaWidth + source.CurGraphWidth);
+ }
+ else
+ {
+ int CurIdxX = CurGraphIdx % HorTileCount;
+ int CurIdxY = CurGraphIdx / HorTileCount;
+
+ curOffY = OFFY + pad_top + CurIdxY * (source.CurGraphHeight + GraphCaptionLineHeight);
+ CurOffX = OFFX + yLabelAreaWidth + pad_left + CurIdxX * (yLabelAreaWidth + source.CurGraphWidth);
+ }
+
+ }
+ else
+ {
+ // one active source
+ curOffY = OFFY + pad_top + CurGraphIdx * (source.CurGraphHeight + GraphCaptionLineHeight);
+ CurOffX = OFFX + pad_left + yLabelAreaWidth;
+ }
+ }
+ else if (layout == LayoutMode.VERTICAL_ARRANGED)
+ {
+ if (ActiveSources > 1)
+ {
+ curOffY = OFFY + pad_top + CurGraphIdx * (source.CurGraphHeight + GraphCaptionLineHeight + pad_inter);
+ }
+ else
+ {
+ curOffY = OFFY + pad_top + CurGraphIdx * (source.CurGraphHeight + GraphCaptionLineHeight);
+ }
+
+ CurOffX = OFFX + pad_left + yLabelAreaWidth;
+ }
+ else if (layout == LayoutMode.STACKED)
+ {
+ if (ActiveSources > 1)
+ {
+ curOffY = OFFY + pad_top + CurGraphIdx * (source.CurGraphHeight);
+ }
+ else
+ {
+ curOffY = OFFY + pad_top + CurGraphIdx * (source.CurGraphHeight);
+ }
+
+ CurOffX = OFFX + pad_left + yLabelAreaWidth;
+ }
+ else
+ {
+ CurOffX = OFFX + pad_left + yLabelAreaWidth * ActiveSources;
+ curOffY = OFFY + pad_top;
+ }
+
+ DrawGrid(CurGraphics, source, CurOffX, curOffY + GraphCaptionLineHeight / 2);
+
+ if (hasBoundingBox)
+ {
+ float w = source.CurGraphWidth;
+ float h = source.CurGraphHeight + GraphCaptionLineHeight / 2;
+
+ DrawGraphBox(CurGraphics, CurOffX, curOffY, w, h);
+
+ }
+
+ List marker_pos = DrawGraphCurve(CurGraphics, source, CurOffX, curOffY + GraphCaptionLineHeight / 2);
+
+ if (layout == LayoutMode.NORMAL)
+ {
+ DrawGraphCaption(CurGraphics, source, marker_pos, CurOffX + CurGraphIdx * (10 + yLabelAreaWidth), curOffY);
+
+ if (CurGraphIdx == 0)
+ {
+ DrawXLabels(CurGraphics, source, marker_pos, CurOffX, curOffY);
+ }
+
+ DrawYLabels(CurGraphics, source, marker_pos, CurOffX + yLabelAreaWidth * (CurGraphIdx - ActiveSources + 1), curOffY);
+ }
+ else
+ {
+ DrawGraphCaption(CurGraphics, source, marker_pos, CurOffX, curOffY);
+
+ DrawXLabels(CurGraphics, source, marker_pos, CurOffX, curOffY);
+
+ DrawYLabels(CurGraphics, source, marker_pos, CurOffX, curOffY);
+ }
+
+
+
+ CurGraphIdx++;
+ }
+ }
+ }
+
+ private void PaintStackedGraphs(Graphics CurGraphics,float CurWidth,float CurHeigth, float OFFX, float OFFY)
+ {
+ int CurGraphIdx = 0;
+ float curOffY = 0;
+ float CurOffX = 0;
+
+ foreach (DataSource source in sources)
+ {
+ source.Cur_YD0 = source.YD0;
+ source.Cur_YD1 = source.YD1;
+
+ source.CurGraphHeight = CurHeigth;
+ source.CurGraphWidth = CurWidth - pad_left - yLabelAreaWidth - pad_right;
+
+ DX = XD1 - XD0;
+
+ if (source.AutoScaleX && source.Samples.Length > 0)
+ {
+ DX = source.Samples[source.Samples.Length - 1].X;
+ }
+
+ CurXD0 = XD0;
+ CurXD1 = XD1;
+
+ if (source.Active)
+ {
+ if (source.AutoScaleY == true)
+ {
+ int idx_start = -1;
+ int idx_stop = -1;
+ float ymin = 0.0f;
+ float ymax = 0.0f;
+ float ymin_range = 0;
+ float ymax_range = 0;
+
+ int DownSample = source.Downsampling;
+ PointF[] data = source.Samples;
+ float mult_y = source.CurGraphHeight / source.DY;
+ float mult_x = source.CurGraphWidth / DX;
+ float coff_x = off_X - starting_idx * mult_x;
+
+ if (source.AutoScaleX)
+ {
+ coff_x = off_X; // avoid dragging in x-autoscale mode
+ }
+
+ for (int i = 0; i < data.Length - 1; i += DownSample)
+ {
+ float x = data[i].X * mult_x + coff_x;
+
+ if (data[i].Y > ymax) ymax = data[i].Y;
+ if (data[i].Y < ymin) ymin = data[i].Y;
+
+ if (x > 0 && x < (source.CurGraphWidth))
+ {
+ if (idx_start == -1) idx_start = i;
+ idx_stop = i;
+
+ if (data[i].Y > ymax_range) ymax_range = data[i].Y;
+ if (data[i].Y < ymin_range) ymin_range = data[i].Y;
+ }
+ }
+
+ if (idx_start >= 0 && idx_stop >= 0)
+ {
+ float data_range = ymax - ymin; // this is range in the data
+ float delta_range = ymax_range - ymin_range; // this is the visible data range -> might be smaller
+
+ source.Cur_YD0 = ymin_range;
+ source.Cur_YD1 = ymax_range;
+ }
+ }
+
+ if (ActiveSources > 1)
+ {
+ source.CurGraphHeight = (float)(CurHeigth - GraphCaptionLineHeight - pad_top - pad_bot) / ActiveSources;
+ }
+ else
+ {
+ source.CurGraphHeight = (float)(CurHeigth - GraphCaptionLineHeight - pad_top - pad_bot);
+ }
+
+ if (source.yFlip)
+ {
+ source.DY = source.Cur_YD0 - source.Cur_YD1;
+
+ if (DX != 0 && source.DY != 0)
+ {
+ source.off_Y = -source.Cur_YD1 * source.CurGraphHeight / source.DY;
+ off_X = -CurXD0 * source.CurGraphWidth / DX;
+ }
+ }
+ else
+ {
+ source.DY = source.Cur_YD1 - source.Cur_YD0;
+
+ if (DX != 0 && source.DY != 0)
+ {
+ source.off_Y = -source.Cur_YD0 * source.CurGraphHeight / source.DY;
+ off_X = -CurXD0 * source.CurGraphWidth / DX;
+ }
+ }
+
+ if (ActiveSources > 1)
+ {
+ curOffY = OFFY + pad_top + CurGraphIdx * (source.CurGraphHeight);
+ }
+ else
+ {
+ curOffY = OFFY + pad_top + CurGraphIdx * (source.CurGraphHeight);
+ }
+
+ CurOffX = OFFX + pad_left + yLabelAreaWidth;
+
+ DrawGrid(CurGraphics, source, CurOffX, curOffY + GraphCaptionLineHeight / 2);
+
+ if (hasBoundingBox && CurGraphIdx == ActiveSources - 1)
+ {
+ DrawGraphBox(CurGraphics, pad_left + yLabelAreaWidth, pad_top, source.CurGraphWidth, CurHeigth - pad_top - GraphCaptionLineHeight);
+ }
+
+ List marker_pos = DrawGraphCurve(CurGraphics, source, CurOffX, curOffY + GraphCaptionLineHeight / 2);
+
+ DrawGraphCaption(CurGraphics, source, marker_pos, CurOffX + CurGraphIdx * (10 + yLabelAreaWidth), pad_top);
+
+ DrawYLabels(CurGraphics, source, marker_pos, CurOffX, curOffY);
+
+ if (CurGraphIdx == ActiveSources - 1)
+ {
+ DrawXLabels(CurGraphics, source, marker_pos, pad_left, Height - pad_top - GraphCaptionLineHeight - source.CurGraphHeight);
+ }
+
+ /*
+ if (hasBoundingBox && CurGraphIdx == ActiveSources - 1)
+ {
+ DrawGraphBox(CurGraphics, pad_left + yLabelAreaWidth, pad_top, source.CurGraphWidth, CurHeigth - pad_top - GraphCaptionLineHeight);
+ }
+ * */
+
+ CurGraphIdx++;
+ }
+ }
+ }
+
+ public void PaintControl(Graphics CurGraphics, float CurWidth, float CurHeight, float OffX, float OffY, bool PaintBgnd)
+ {
+ if (PaintBgnd)
+ {
+ DrawBackground(CurGraphics,CurWidth,CurHeight,OffX,OffY);
+ }
+
+ ActiveSources = 0;
+
+ foreach (DataSource source in sources)
+ {
+ if (source.Samples != null &&
+ source.Samples.Length > 0 &&
+ source.Active == true)
+ {
+ ActiveSources++;
+ }
+ }
+
+ switch (layout)
+ {
+ case LayoutMode.NORMAL:
+
+ case LayoutMode.TILES_HOR:
+ case LayoutMode.TILES_VER:
+ case LayoutMode.VERTICAL_ARRANGED:
+
+ PaintGraphs(CurGraphics, CurWidth, CurHeight, OffX, OffY);
+
+ break;
+
+ case LayoutMode.STACKED:
+
+ PaintStackedGraphs(CurGraphics, CurWidth, CurHeight, OffX, OffY);
+
+ break;
+ }
+ }
+
+ protected override void OnPaint(PaintEventArgs e)
+ {
+ try
+ {
+ if (ParentForm != null)
+ {
+ Graphics CurGraphics = e.Graphics;
+
+ if (backBuffer.Graphics != null && useDoubleBuffer == true)
+ {
+ CurGraphics = backBuffer.Graphics;
+ }
+
+ CurGraphics.SmoothingMode = smoothing;
+
+ PaintControl(CurGraphics,this.Width,this.Height,0,0,true);
+
+ if (backBuffer.Graphics != null && useDoubleBuffer == true)
+ {
+ backBuffer.Render(e.Graphics);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.Write("exception : " + ex.Message);
+ }
+
+ base.OnPaint(e);
+ }
+
+
+ private void DrawBackground(Graphics g,float CurWidth, float CurHeight, float CurOFFX, float CurOFFY)
+ {
+ Rectangle rbgn = new Rectangle((int)CurOFFX, (int)CurOFFY, (int)CurWidth, (int)CurHeight);
+
+ if (BgndColorTop != BgndColorBot)
+ {
+ using (LinearGradientBrush lb1 = new LinearGradientBrush(new Point((int)0, (int)0),
+ new Point((int)0, (int)(CurHeight)),
+ BgndColorTop,
+ BgndColorBot))
+ {
+ g.FillRectangle(lb1, rbgn);
+ }
+ }
+ else
+ {
+ using (SolidBrush sb1 = new SolidBrush(BgndColorTop))
+ {
+ g.FillRectangle(sb1, rbgn);
+ }
+ }
+ }
+
+
+ private void DrawGrid( Graphics g, DataSource source, float CurrOffX, float CurOffY )
+ {
+ int Idx = 0;
+ float mult_x = source.CurGraphWidth / DX;
+ float coff_x = off_X - starting_idx * mult_x;
+
+ if (source.AutoScaleX)
+ {
+ coff_x = off_X; // avoid dragging in x-autoscale mode
+ }
+
+ Color CurGridColor = MajorGridColor;
+ Color CurMinGridClor = MinorGridColor;
+
+ if (layout == LayoutMode.NORMAL && source.AutoScaleY)
+ {
+ CurGridColor = source.GraphColor;
+ CurMinGridClor = source.GraphColor;
+ }
+
+ using (Pen minorGridPen = new Pen(CurMinGridClor))
+ {
+ minorGridPen.DashPattern = MinorGridPattern;
+ minorGridPen.DashStyle = MinorGridDashStyle;
+
+ using (Pen p2 = new Pen(CurGridColor))
+ {
+ p2.DashPattern = MajorGridPattern;
+ p2.DashStyle = MajorGridDashStyle;
+
+ if (DX != 0)
+ {
+ while (true)
+ {
+ float x = Idx * grid_distance_x * source.CurGraphWidth / DX + grid_off_x * source.CurGraphWidth / DX;
+
+ if (MoveMinorGrid)
+ {
+ x += coff_x;
+ }
+
+ if (x > 0 && x < source.CurGraphWidth)
+ {
+ g.DrawLine(minorGridPen, new Point((int)(x + CurrOffX - 0.5f), (int)(CurOffY)),
+ new Point((int)(x + CurrOffX - 0.5f), (int)(CurOffY + source.CurGraphHeight)));
+ }
+ if (x > source.CurGraphWidth)
+ {
+ break;
+ }
+
+ Idx++;
+ }
+ }
+
+ if (source.DY != 0)
+ {
+ float y0 = (float)(source.grid_off_y * source.CurGraphHeight / source.DY + source.off_Y);
+
+ // draw horizontal zero grid lines
+ g.DrawLine(p2, new Point((int)CurrOffX, (int)(CurOffY + y0 + 0.5f)), new Point((int)(CurrOffX + source.CurGraphWidth + 0.5f), (int)(CurOffY + y0 + 0.5f)));
+
+ // draw horizontal grid lines
+ for (Idx = (int)(source.grid_off_y);Idx > (int)(source.YD0 ); Idx -= (int)source.grid_distance_y)
+ {
+ float y = (float)(Idx * source.CurGraphHeight) / source.DY + source.off_Y;
+
+ if (y >= 0 && y < source.CurGraphHeight)
+ {
+ g.DrawLine(minorGridPen,
+ new Point((int)CurrOffX, (int)(CurOffY + y + 0.5f)),
+ new Point((int)(CurrOffX + source.CurGraphWidth + 0.5f), (int)(0.5f + CurOffY + y)));
+ }
+ }
+
+ // draw horizontal grid lines
+ for (Idx = (int)(source.grid_off_y); Idx < (int)(source.YD1 ); Idx += (int)source.grid_distance_y)
+ {
+ float y = (float)Idx * source.CurGraphHeight / source.DY + source.off_Y;
+
+ if (y >= 0 && y < source.CurGraphHeight)
+ {
+ g.DrawLine(minorGridPen,
+ new Point((int)CurrOffX, (int)(CurOffY + y + 0.5f)),
+ new Point((int)(CurrOffX + source.CurGraphWidth + 0.5f), (int)(0.5f + CurOffY + y)));
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ private List DrawGraphCurve(Graphics g, DataSource source, float offset_x, float offset_y)
+ {
+ List marker_positions = new List();
+
+ if (DX != 0 && source.DY != 0)
+ {
+ List ps = new List();
+
+ if (source.Samples != null && source.Samples.Length > 1)
+ {
+
+ int DownSample = source.Downsampling;
+ PointF[] data = source.Samples;
+ float mult_y = source.CurGraphHeight / source.DY;
+ float mult_x = source.CurGraphWidth / DX;
+ float coff_x = off_X - starting_idx * mult_x;
+
+ if (source.AutoScaleX)
+ {
+ coff_x = off_X; // avoid dragging in x-autoscale mode
+ }
+
+ for (int i = 0; i < data.Length - 1; i += DownSample)
+ {
+ float x = data[i].X * mult_x + coff_x;
+ float y = data[i].Y * mult_y + source.off_Y;
+
+ int xi = (int)(data[i].X);
+
+ if (xi % grid_distance_x == 0)
+ {
+ if (x >= (0 - xLabelAreaheight) && x <= (source.CurGraphWidth + xLabelAreaheight))
+ {
+ marker_positions.Add(i);
+ }
+ }
+
+ if (x > 0 && x < (source.CurGraphWidth))
+ {
+ ps.Add(new Point((int)(x + offset_x+0.5f), (int)(y + offset_y + 0.5f)));
+ }
+ else if (x > source.CurGraphWidth)
+ {
+ break;
+ }
+ }
+
+ using (Pen p = new Pen(source.GraphColor))
+ {
+ if (ps.Count > 0)
+ {
+ g.DrawLines(p, ps.ToArray());
+ }
+ }
+ }
+ }
+ return marker_positions;
+ }
+
+
+ private void DrawGraphCaption(Graphics g, DataSource source, IList marker_pos, float offset_x, float offset_y)
+ {
+ using (Brush brush = new SolidBrush(source.GraphColor))
+ {
+ using (Pen pen = new Pen(brush))
+ {
+ pen.DashPattern = MajorGridPattern;
+
+ g.DrawString(source.Name, legendFont, brush, new PointF(offset_x + graphCaptionOffset.X + 12, offset_y +graphCaptionOffset.Y+ 2));
+
+ }
+ }
+ }
+
+
+ private void DrawXLabels(Graphics g, DataSource source, IList marker_pos, float offset_x, float offset_y)
+ {
+ Color XLabColor = source.GraphColor;
+
+ if (layout == LayoutMode.NORMAL || layout == LayoutMode.STACKED)
+ {
+ XLabColor = GraphBoxColor;
+ }
+
+ using (Brush brush = new SolidBrush(XLabColor))
+ {
+ using (Pen pen = new Pen(brush))
+ {
+ pen.DashPattern = MajorGridPattern;
+
+ if (DX != 0 && source.DY != 0)
+ {
+ if (source.Samples != null && source.Samples.Length > 1)
+ {
+ PointF[] data = source.Samples;
+
+ float mult_y = source.CurGraphHeight / source.DY;
+ float mult_x = source.CurGraphWidth / DX;
+
+ float coff_x = off_X - starting_idx * mult_x;
+
+ if (source.AutoScaleX)
+ {
+ coff_x = off_X; // avoid dragging in x-autoscale mode
+ }
+
+ foreach (int i in marker_pos)
+ {
+ int xi = (int)(data[i].X);
+
+ if (xi % grid_distance_x == 0)
+ {
+ float x = data[i].X * mult_x + coff_x;
+
+ String value = "" + data[i].X;
+
+ if (source.OnRenderXAxisLabel != null)
+ {
+ value = source.OnRenderXAxisLabel(source, i);
+ }
+
+ /// TODO: find out how to calculate this offset. Must be padding + something else
+ float unknownOffset = -14;// -14;
+
+ if (MoveMinorGrid == false)
+ {
+ g.DrawLine(pen, x, offset_y + GraphCaptionLineHeight + source.CurGraphHeight + unknownOffset,
+ x, offset_y + GraphCaptionLineHeight + source.CurGraphHeight);
+
+ g.DrawString(value, legendFont, brush,
+ new PointF((int)(0.5f + x + offset_x + 4),
+ GraphCaptionLineHeight + offset_y + source.CurGraphHeight + unknownOffset));
+ }
+ else
+ {
+ SizeF dim = g.MeasureString(value, legendFont);
+ g.DrawString(value, legendFont, brush,
+ new PointF((int)(0.5f + x + offset_x + 4 - dim.Width / 2),
+ GraphCaptionLineHeight + offset_y + source.CurGraphHeight + unknownOffset));
+
+ }
+ }
+ }
+ }
+ }
+
+
+ }
+ }
+ }
+
+
+ private void DrawYLabels(Graphics g, DataSource source, IList marker_pos, float offset_x, float offset_y )
+ {
+ using (Brush b = new SolidBrush(source.GraphColor))
+ {
+ using (Pen pen = new Pen(b))
+ {
+ pen.DashPattern = new float[] { 2, 2 };
+
+ // draw labels for horizontal lines
+ if (source.DY != 0)
+ {
+ float Idx = 0;
+
+ float y0 = (float)(source.grid_off_y * source.CurGraphHeight / source.DY + source.off_Y);
+
+ String value = "" + Idx;
+
+ if (source.OnRenderYAxisLabel != null)
+ {
+ value = source.OnRenderYAxisLabel(source, Idx);
+ }
+
+ SizeF dim = g.MeasureString(value, legendFont);
+ g.DrawString(value, legendFont, b, new PointF((int)offset_x - dim.Width, (int)(offset_y + y0 + 0.5f + dim.Height / 2)));
+
+ float GridDistY = source.grid_distance_y;
+
+ if (source.AutoScaleY)
+ {
+ // calculate a matching grid distance
+ GridDistY = - Utilities.MostSignificantDigit(source.DY );
+
+ if (GridDistY == 0)
+ {
+ GridDistY = source.grid_distance_y;
+
+ }
+ }
+
+ for (Idx = (source.grid_off_y); Idx > (source.Cur_YD0); Idx -= GridDistY)
+ {
+ if (Idx != 0)
+ {
+ float y1 = (float)((Idx) * source.CurGraphHeight) / source.DY + source.off_Y;
+
+ value = "" + (Idx);
+
+ if (source.OnRenderYAxisLabel != null)
+ {
+ value = source.OnRenderYAxisLabel(source, Idx);
+ }
+
+ dim = g.MeasureString(value, legendFont);
+ g.DrawString(value, legendFont, b, new PointF((int)offset_x - dim.Width, (int)(offset_y + y1 + 0.5f + dim.Height / 2)));
+ }
+ }
+
+ for (Idx = (source.grid_off_y); Idx < (source.Cur_YD1); Idx += GridDistY)
+ {
+ if (Idx != 0)
+ {
+ float y2 = (float)((Idx) * source.CurGraphHeight) / source.DY + source.off_Y;
+
+ value = "" + (Idx);
+
+ if (source.OnRenderYAxisLabel != null)
+ {
+ value = source.OnRenderYAxisLabel(source, Idx);
+ }
+
+ dim = g.MeasureString(value, legendFont);
+ g.DrawString(value, legendFont, b, new PointF((int)offset_x - dim.Width, (int)(offset_y + y2 + 0.5f + dim.Height / 2)));
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ private void DrawGraphBox(Graphics g, float offset_x, float offset_y, float w, float h )
+ {
+ using (Pen p2 = new Pen(GraphBoxColor))
+ {
+ g.DrawLine(p2, new Point((int)(offset_x + 0.5f), (int)(offset_y + 0.5f)),
+ new Point((int)(offset_x + w - 0.5f), (int)(offset_y + 0.5f)));
+
+ g.DrawLine(p2, new Point((int)(offset_x + w - 0.5f), (int)(offset_y + 0.5f)),
+ new Point((int)(offset_x + w - 0.5f), (int)(offset_y + h + 0.5f)));
+
+ g.DrawLine(p2, new Point((int)(offset_x + w - 0.5f), (int)(offset_y + h + 0.5f)),
+ new Point((int)(offset_x + 0.5f), (int)(offset_y + h + 0.5f)));
+
+ g.DrawLine(p2, new Point((int)(offset_x + 0.5f), (int)(offset_y + h + 0.5f)),
+ new Point((int)(offset_x + 0.5f), (int)(offset_y + 0.5f)));
+ }
+ }
+ }
+}
diff --git a/GraphLib/PlotterGraphPaneEx.resx b/GraphLib/PlotterGraphPaneEx.resx
new file mode 100644
index 000000000..19dc0dd8b
--- /dev/null
+++ b/GraphLib/PlotterGraphPaneEx.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/GraphLib/PlotterGraphSelectCurvesForm.Designer.cs b/GraphLib/PlotterGraphSelectCurvesForm.Designer.cs
new file mode 100644
index 000000000..331db07ec
--- /dev/null
+++ b/GraphLib/PlotterGraphSelectCurvesForm.Designer.cs
@@ -0,0 +1,365 @@
+namespace GraphLib
+{
+ partial class PlotterGraphSelectCurvesForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.lb_Graphs = new System.Windows.Forms.CheckedListBox();
+ this.gB_SelectedGraph = new System.Windows.Forms.GroupBox();
+ this.cb_X_AutoScale = new System.Windows.Forms.CheckBox();
+ this.tb_GraphName = new System.Windows.Forms.TextBox();
+ this.label3 = new System.Windows.Forms.Label();
+ this.cbDownSampling = new System.Windows.Forms.ComboBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.btn_GraphColor = new System.Windows.Forms.Button();
+ this.cb_Y_AutoScale = new System.Windows.Forms.CheckBox();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.label7 = new System.Windows.Forms.Label();
+ this.label5 = new System.Windows.Forms.Label();
+ this.bt_MinorGridColor = new System.Windows.Forms.Button();
+ this.bt_bg_col_bot = new System.Windows.Forms.Button();
+ this.label6 = new System.Windows.Forms.Label();
+ this.bt_MajorGridColor = new System.Windows.Forms.Button();
+ this.label4 = new System.Windows.Forms.Label();
+ this.bt_bg_col_top = new System.Windows.Forms.Button();
+ this.btn_AutoScaleAll = new System.Windows.Forms.Button();
+ this.label1 = new System.Windows.Forms.Label();
+ this.cb_Layout = new System.Windows.Forms.ComboBox();
+ this.button1 = new System.Windows.Forms.Button();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.gB_SelectedGraph.SuspendLayout();
+ this.groupBox1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
+ this.splitContainer1.Location = new System.Drawing.Point(0, 0);
+ this.splitContainer1.Name = "splitContainer1";
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.Controls.Add(this.lb_Graphs);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.Controls.Add(this.gB_SelectedGraph);
+ this.splitContainer1.Panel2.Controls.Add(this.groupBox1);
+ this.splitContainer1.Panel2.Controls.Add(this.button1);
+ this.splitContainer1.Size = new System.Drawing.Size(395, 431);
+ this.splitContainer1.SplitterDistance = 171;
+ this.splitContainer1.TabIndex = 0;
+ //
+ // lb_Graphs
+ //
+ this.lb_Graphs.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.lb_Graphs.FormattingEnabled = true;
+ this.lb_Graphs.Location = new System.Drawing.Point(0, 0);
+ this.lb_Graphs.Name = "lb_Graphs";
+ this.lb_Graphs.Size = new System.Drawing.Size(171, 424);
+ this.lb_Graphs.TabIndex = 0;
+ this.lb_Graphs.SelectedIndexChanged += new System.EventHandler(this.checkedListBox1_SelectedIndexChanged_1);
+ //
+ // gB_SelectedGraph
+ //
+ this.gB_SelectedGraph.Controls.Add(this.cb_X_AutoScale);
+ this.gB_SelectedGraph.Controls.Add(this.tb_GraphName);
+ this.gB_SelectedGraph.Controls.Add(this.label3);
+ this.gB_SelectedGraph.Controls.Add(this.cbDownSampling);
+ this.gB_SelectedGraph.Controls.Add(this.label2);
+ this.gB_SelectedGraph.Controls.Add(this.btn_GraphColor);
+ this.gB_SelectedGraph.Controls.Add(this.cb_Y_AutoScale);
+ this.gB_SelectedGraph.Location = new System.Drawing.Point(6, 232);
+ this.gB_SelectedGraph.Name = "gB_SelectedGraph";
+ this.gB_SelectedGraph.Size = new System.Drawing.Size(206, 158);
+ this.gB_SelectedGraph.TabIndex = 6;
+ this.gB_SelectedGraph.TabStop = false;
+ this.gB_SelectedGraph.Text = "Selected Graph Options";
+ this.gB_SelectedGraph.Visible = false;
+ //
+ // cb_X_AutoScale
+ //
+ this.cb_X_AutoScale.AutoSize = true;
+ this.cb_X_AutoScale.Location = new System.Drawing.Point(12, 102);
+ this.cb_X_AutoScale.Name = "cb_X_AutoScale";
+ this.cb_X_AutoScale.Size = new System.Drawing.Size(93, 17);
+ this.cb_X_AutoScale.TabIndex = 8;
+ this.cb_X_AutoScale.Text = "X AutoScaling";
+ this.cb_X_AutoScale.UseVisualStyleBackColor = true;
+ this.cb_X_AutoScale.CheckedChanged += new System.EventHandler(this.cb_X_AutoScale_CheckedChanged);
+ //
+ // tb_GraphName
+ //
+ this.tb_GraphName.Location = new System.Drawing.Point(12, 24);
+ this.tb_GraphName.Name = "tb_GraphName";
+ this.tb_GraphName.Size = new System.Drawing.Size(167, 20);
+ this.tb_GraphName.TabIndex = 7;
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(52, 133);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(76, 13);
+ this.label3.TabIndex = 6;
+ this.label3.Text = "Downsampling";
+ //
+ // cbDownSampling
+ //
+ this.cbDownSampling.FormattingEnabled = true;
+ this.cbDownSampling.Items.AddRange(new object[] {
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6"});
+ this.cbDownSampling.Location = new System.Drawing.Point(7, 130);
+ this.cbDownSampling.Name = "cbDownSampling";
+ this.cbDownSampling.Size = new System.Drawing.Size(39, 21);
+ this.cbDownSampling.TabIndex = 5;
+ this.cbDownSampling.Text = "1";
+ this.cbDownSampling.SelectedIndexChanged += new System.EventHandler(this.OnDownsamplingChanged);
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(57, 55);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(63, 13);
+ this.label2.TabIndex = 4;
+ this.label2.Text = "Graph Color";
+ //
+ // btn_GraphColor
+ //
+ this.btn_GraphColor.Location = new System.Drawing.Point(11, 50);
+ this.btn_GraphColor.Name = "btn_GraphColor";
+ this.btn_GraphColor.Size = new System.Drawing.Size(26, 23);
+ this.btn_GraphColor.TabIndex = 3;
+ this.btn_GraphColor.UseVisualStyleBackColor = true;
+ this.btn_GraphColor.Click += new System.EventHandler(this.btn_GraphColor_Click);
+ //
+ // cb_Y_AutoScale
+ //
+ this.cb_Y_AutoScale.AutoSize = true;
+ this.cb_Y_AutoScale.Location = new System.Drawing.Point(12, 79);
+ this.cb_Y_AutoScale.Name = "cb_Y_AutoScale";
+ this.cb_Y_AutoScale.Size = new System.Drawing.Size(93, 17);
+ this.cb_Y_AutoScale.TabIndex = 2;
+ this.cb_Y_AutoScale.Text = "Y AutoScaling";
+ this.cb_Y_AutoScale.UseVisualStyleBackColor = true;
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.label7);
+ this.groupBox1.Controls.Add(this.label5);
+ this.groupBox1.Controls.Add(this.bt_MinorGridColor);
+ this.groupBox1.Controls.Add(this.bt_bg_col_bot);
+ this.groupBox1.Controls.Add(this.label6);
+ this.groupBox1.Controls.Add(this.bt_MajorGridColor);
+ this.groupBox1.Controls.Add(this.label4);
+ this.groupBox1.Controls.Add(this.bt_bg_col_top);
+ this.groupBox1.Controls.Add(this.btn_AutoScaleAll);
+ this.groupBox1.Controls.Add(this.label1);
+ this.groupBox1.Controls.Add(this.cb_Layout);
+ this.groupBox1.Location = new System.Drawing.Point(6, 5);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(206, 221);
+ this.groupBox1.TabIndex = 4;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "General Options";
+ //
+ // label7
+ //
+ this.label7.AutoSize = true;
+ this.label7.Location = new System.Drawing.Point(57, 194);
+ this.label7.Name = "label7";
+ this.label7.Size = new System.Drawing.Size(82, 13);
+ this.label7.TabIndex = 10;
+ this.label7.Text = "Minor Grid Color";
+ //
+ // label5
+ //
+ this.label5.AutoSize = true;
+ this.label5.Location = new System.Drawing.Point(57, 136);
+ this.label5.Name = "label5";
+ this.label5.Size = new System.Drawing.Size(128, 13);
+ this.label5.TabIndex = 8;
+ this.label5.Text = "Background Color Bottom";
+ //
+ // bt_MinorGridColor
+ //
+ this.bt_MinorGridColor.Location = new System.Drawing.Point(11, 189);
+ this.bt_MinorGridColor.Name = "bt_MinorGridColor";
+ this.bt_MinorGridColor.Size = new System.Drawing.Size(26, 23);
+ this.bt_MinorGridColor.TabIndex = 9;
+ this.bt_MinorGridColor.UseVisualStyleBackColor = true;
+ this.bt_MinorGridColor.Click += new System.EventHandler(this.bt_MinorGridColor_Click);
+ //
+ // bt_bg_col_bot
+ //
+ this.bt_bg_col_bot.Location = new System.Drawing.Point(11, 131);
+ this.bt_bg_col_bot.Name = "bt_bg_col_bot";
+ this.bt_bg_col_bot.Size = new System.Drawing.Size(26, 23);
+ this.bt_bg_col_bot.TabIndex = 7;
+ this.bt_bg_col_bot.UseVisualStyleBackColor = true;
+ this.bt_bg_col_bot.Click += new System.EventHandler(this.bt_bg_col_bot_Click);
+ //
+ // label6
+ //
+ this.label6.AutoSize = true;
+ this.label6.Location = new System.Drawing.Point(57, 165);
+ this.label6.Name = "label6";
+ this.label6.Size = new System.Drawing.Size(82, 13);
+ this.label6.TabIndex = 8;
+ this.label6.Text = "Major Grid Color";
+ //
+ // bt_MajorGridColor
+ //
+ this.bt_MajorGridColor.Location = new System.Drawing.Point(11, 160);
+ this.bt_MajorGridColor.Name = "bt_MajorGridColor";
+ this.bt_MajorGridColor.Size = new System.Drawing.Size(26, 23);
+ this.bt_MajorGridColor.TabIndex = 7;
+ this.bt_MajorGridColor.UseVisualStyleBackColor = true;
+ this.bt_MajorGridColor.Click += new System.EventHandler(this.bt_MajorGridColor_Click);
+ //
+ // label4
+ //
+ this.label4.AutoSize = true;
+ this.label4.Location = new System.Drawing.Point(57, 107);
+ this.label4.Name = "label4";
+ this.label4.Size = new System.Drawing.Size(114, 13);
+ this.label4.TabIndex = 6;
+ this.label4.Text = "Background Color Top";
+ //
+ // bt_bg_col_top
+ //
+ this.bt_bg_col_top.Location = new System.Drawing.Point(11, 102);
+ this.bt_bg_col_top.Name = "bt_bg_col_top";
+ this.bt_bg_col_top.Size = new System.Drawing.Size(26, 23);
+ this.bt_bg_col_top.TabIndex = 5;
+ this.bt_bg_col_top.UseVisualStyleBackColor = true;
+ this.bt_bg_col_top.Click += new System.EventHandler(this.bt_bg_col_top_Click);
+ //
+ // btn_AutoScaleAll
+ //
+ this.btn_AutoScaleAll.Location = new System.Drawing.Point(11, 69);
+ this.btn_AutoScaleAll.Name = "btn_AutoScaleAll";
+ this.btn_AutoScaleAll.Size = new System.Drawing.Size(167, 25);
+ this.btn_AutoScaleAll.TabIndex = 4;
+ this.btn_AutoScaleAll.Text = "Auto Scale All";
+ this.btn_AutoScaleAll.UseVisualStyleBackColor = true;
+ this.btn_AutoScaleAll.Click += new System.EventHandler(this.OnButtonAutoScallOnClicked);
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(9, 26);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(39, 13);
+ this.label1.TabIndex = 3;
+ this.label1.Text = "Layout";
+ //
+ // cb_Layout
+ //
+ this.cb_Layout.FormattingEnabled = true;
+ this.cb_Layout.Items.AddRange(new object[] {
+ "Normal",
+ "Stacked",
+ "Tiles - Fill Vertical",
+ "Tiles - Fill Horizontal",
+ "Vertically"});
+ this.cb_Layout.Location = new System.Drawing.Point(11, 42);
+ this.cb_Layout.Name = "cb_Layout";
+ this.cb_Layout.Size = new System.Drawing.Size(168, 21);
+ this.cb_Layout.TabIndex = 2;
+ this.cb_Layout.Text = "Select";
+ this.cb_Layout.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
+ //
+ // button1
+ //
+ this.button1.Location = new System.Drawing.Point(66, 396);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(68, 23);
+ this.button1.TabIndex = 0;
+ this.button1.Text = "Exit";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_Click);
+ //
+ // PlotterGraphSelectCurvesForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(395, 431);
+ this.Controls.Add(this.splitContainer1);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.MinimumSize = new System.Drawing.Size(16, 246);
+ this.Name = "PlotterGraphSelectCurvesForm";
+ this.Text = "Graph Properties";
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ this.splitContainer1.ResumeLayout(false);
+ this.gB_SelectedGraph.ResumeLayout(false);
+ this.gB_SelectedGraph.PerformLayout();
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.CheckedListBox lb_Graphs;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.ComboBox cb_Layout;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Button btn_GraphColor;
+ private System.Windows.Forms.CheckBox cb_Y_AutoScale;
+ private System.Windows.Forms.Button btn_AutoScaleAll;
+ private System.Windows.Forms.GroupBox gB_SelectedGraph;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.ComboBox cbDownSampling;
+ private System.Windows.Forms.Label label4;
+ private System.Windows.Forms.Button bt_bg_col_top;
+ private System.Windows.Forms.Label label5;
+ private System.Windows.Forms.Button bt_bg_col_bot;
+ private System.Windows.Forms.Label label7;
+ private System.Windows.Forms.Button bt_MinorGridColor;
+ private System.Windows.Forms.Label label6;
+ private System.Windows.Forms.Button bt_MajorGridColor;
+ private System.Windows.Forms.TextBox tb_GraphName;
+ private System.Windows.Forms.CheckBox cb_X_AutoScale;
+ }
+}
\ No newline at end of file
diff --git a/GraphLib/PlotterGraphSelectCurvesForm.cs b/GraphLib/PlotterGraphSelectCurvesForm.cs
new file mode 100644
index 000000000..115e44dc3
--- /dev/null
+++ b/GraphLib/PlotterGraphSelectCurvesForm.cs
@@ -0,0 +1,369 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+
+/* Copyright (c) 2008-2014 DI Zimmermann Stephan (stefan.zimmermann@tele2.at)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+namespace GraphLib
+{
+ public partial class PlotterGraphSelectCurvesForm : Form
+ {
+ private int selectetGraphIndex = -1;
+
+ private PlotterGraphPaneEx gpane = null;
+
+ public PlotterGraphSelectCurvesForm()
+ {
+ InitializeComponent();
+ FormClosing += new FormClosingEventHandler(OnFormClosing);
+ lb_Graphs.SelectedIndexChanged += new EventHandler(OnSelectedGraphIndexChanged);
+ VisibleChanged += new EventHandler(OnVisibleChanged);
+ tb_GraphName.TextChanged += new EventHandler(tb_GraphName_TextChanged);
+ }
+
+ void tb_GraphName_TextChanged(object sender, EventArgs e)
+ {
+ if (selectetGraphIndex >= 0 && selectetGraphIndex < gpane.Sources.Count)
+ {
+ DataSource src = gpane.Sources[selectetGraphIndex];
+ String Text = tb_GraphName.Text;
+
+ if (String.IsNullOrEmpty(Text) == false)
+ {
+ src.Name = Text;
+ gpane.Invalidate();
+ }
+ }
+ }
+
+ public PlotterGraphPaneEx GraphPanel
+ {
+ set
+ {
+ gpane = value;
+ if (gpane != null)
+ {
+ this.lb_Graphs.Items.Clear();
+
+ foreach (DataSource s in gpane.Sources)
+ {
+ if (s.Active)
+ {
+ this.lb_Graphs.Items.Add(s.Name, CheckState.Checked);
+ }
+ else
+ {
+ this.lb_Graphs.Items.Add(s.Name, CheckState.Unchecked);
+ }
+ }
+
+ UpdateAllCheckedState();
+ }
+ }
+ }
+
+ void UpdateAllCheckedState()
+ {
+ int AutoScaleOn = 0;
+
+ foreach (DataSource src in gpane.Sources)
+ {
+ if (src.AutoScaleY)
+ {
+ AutoScaleOn++;
+ }
+ }
+
+ if (AutoScaleOn == 0)
+ {
+ btn_AutoScaleAll.Visible = true;
+ btn_AutoScaleAll.Text = "Auto Y-Scale all Graphs";
+ }
+ else
+ {
+ btn_AutoScaleAll.Visible = true;
+ btn_AutoScaleAll.Text = "Normal Y-Scale all Graphs";
+ }
+ }
+
+ void OnVisibleChanged(object sender, EventArgs e)
+ {
+ if (this.Visible == true)
+ {
+ selectetGraphIndex = -1;
+ gB_SelectedGraph.Visible = false;
+
+ if (gpane != null)
+ {
+ UpdateAllCheckedState();
+
+ if (gpane.layout == PlotterGraphPaneEx.LayoutMode.NORMAL)
+ {
+ cb_Layout.SelectedIndex = 0;
+ }
+ else if (gpane.layout == PlotterGraphPaneEx.LayoutMode.STACKED)
+ {
+ cb_Layout.SelectedIndex = 1;
+ }
+ else if (gpane.layout == PlotterGraphPaneEx.LayoutMode.TILES_HOR)
+ {
+ cb_Layout.SelectedIndex = 2;
+ }
+ else if (gpane.layout == PlotterGraphPaneEx.LayoutMode.TILES_VER)
+ {
+ cb_Layout.SelectedIndex = 3;
+ }
+ else if (gpane.layout == PlotterGraphPaneEx.LayoutMode.VERTICAL_ARRANGED)
+ {
+ cb_Layout.SelectedIndex = 4;
+ }
+
+ bt_bg_col_top.BackColor = gpane.BgndColorTop;
+ bt_bg_col_bot.BackColor = gpane.BgndColorBot;
+ bt_MajorGridColor.BackColor = gpane.MajorGridColor;
+ bt_MinorGridColor.BackColor = gpane.MinorGridColor;
+
+ }
+ }
+ }
+
+
+ void OnSelectedGraphIndexChanged(object sender, EventArgs e)
+ {
+ if (gpane != null)
+ {
+ for (int i = 0; i < gpane.Sources.Count; i++)
+ {
+ if (lb_Graphs.CheckedIndices.Contains(i))
+ {
+ gpane.Sources[i].Active = true;
+ }
+ else
+ {
+ gpane.Sources[i].Active = false;
+ }
+ }
+ gpane.Invalidate();
+ }
+ }
+
+ void OnFormClosing(object sender, FormClosingEventArgs e)
+ {
+ this.Hide();
+ e.Cancel = true;
+ }
+
+ private void button1_Click(object sender, EventArgs e)
+ {
+ this.Hide();
+ }
+
+ private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (cb_Layout.SelectedIndex == 0)
+ {
+ gpane.layout = PlotterGraphPaneEx.LayoutMode.NORMAL;
+ }
+ if (cb_Layout.SelectedIndex == 1)
+ {
+ gpane.layout = PlotterGraphPaneEx.LayoutMode.STACKED;
+ }
+
+ if (cb_Layout.SelectedIndex == 2)
+ {
+ gpane.layout = PlotterGraphPaneEx.LayoutMode.TILES_VER;
+ }
+ if (cb_Layout.SelectedIndex == 3)
+ {
+ gpane.layout = PlotterGraphPaneEx.LayoutMode.TILES_HOR;
+ }
+ if (cb_Layout.SelectedIndex == 4)
+ {
+ gpane.layout = PlotterGraphPaneEx.LayoutMode.VERTICAL_ARRANGED;
+ }
+ gpane.Invalidate();
+ }
+
+ private void checkedListBox1_SelectedIndexChanged_1(object sender, EventArgs e)
+ {
+ selectetGraphIndex = lb_Graphs.SelectedIndex;
+
+ UpdateSelectedGraphInfo();
+ gB_SelectedGraph.Visible = true;
+ }
+
+ private void UpdateSelectedGraphInfo()
+ {
+ if (selectetGraphIndex >= 0 && selectetGraphIndex < gpane.Sources.Count)
+ {
+ DataSource src = gpane.Sources[selectetGraphIndex];
+ btn_GraphColor.BackColor = src.GraphColor;
+
+ cb_Y_AutoScale.Checked = src.AutoScaleY;
+ cb_X_AutoScale.Checked = src.AutoScaleX;
+
+ cbDownSampling.SelectedIndex = (src.Downsampling - 1);
+ tb_GraphName.Text = src.Name;
+ }
+ }
+
+ private void btn_GraphColor_Click(object sender, EventArgs e)
+ {
+ if (selectetGraphIndex >= 0 && selectetGraphIndex < gpane.Sources.Count)
+ {
+ DataSource src = gpane.Sources[selectetGraphIndex];
+ ColorDialog d = new ColorDialog();
+ if (d.ShowDialog() == DialogResult.OK)
+ {
+ btn_GraphColor.BackColor = d.Color;
+ src.GraphColor = d.Color;
+ gpane.Invalidate();
+ }
+ }
+ }
+
+
+ private void OnButtonAutoScallOnClicked(object sender, EventArgs e)
+ {
+ int AutoScaleOn = 0;
+
+ foreach (DataSource src in gpane.Sources)
+ {
+ if (src.AutoScaleY)
+ {
+ AutoScaleOn++;
+ }
+ }
+
+ if (AutoScaleOn == 0)
+ {
+ btn_AutoScaleAll.Text = "Normal scale for all graphs";
+ foreach (DataSource src in gpane.Sources)
+ {
+ src.AutoScaleY = true;
+ }
+ }
+ else
+ {
+ btn_AutoScaleAll.Text = "Auto scale for all graphs";
+ foreach (DataSource src in gpane.Sources)
+ {
+ src.AutoScaleY = false;
+ }
+ }
+
+ UpdateSelectedGraphInfo();
+ gpane.Invalidate();
+ }
+
+ private void OnDownsamplingChanged(object sender, EventArgs e)
+ {
+ if (selectetGraphIndex >= 0 && selectetGraphIndex < gpane.Sources.Count)
+ {
+ DataSource src = gpane.Sources[selectetGraphIndex];
+
+ src.Downsampling = (cbDownSampling.SelectedIndex + 1);
+ }
+
+ gpane.Invalidate();
+ }
+
+ private void bt_bg_col_top_Click(object sender, EventArgs e)
+ {
+ ColorDialog d = new ColorDialog();
+ if (d.ShowDialog() == DialogResult.OK)
+ {
+ bt_bg_col_top.BackColor = d.Color;
+ gpane.BgndColorTop = d.Color;
+
+ gpane.Invalidate();
+ }
+ }
+
+ private void bt_bg_col_bot_Click(object sender, EventArgs e)
+ {
+ ColorDialog d = new ColorDialog();
+ if (d.ShowDialog() == DialogResult.OK)
+ {
+ bt_bg_col_bot.BackColor = d.Color;
+ gpane.BgndColorBot = d.Color;
+ gpane.Invalidate();
+ }
+ }
+
+ private void bt_MajorGridColor_Click(object sender, EventArgs e)
+ {
+ ColorDialog d = new ColorDialog();
+ if (d.ShowDialog() == DialogResult.OK)
+ {
+ bt_MajorGridColor.BackColor = d.Color;
+ gpane.MajorGridColor = d.Color;
+ gpane.Invalidate();
+ }
+ }
+
+ private void bt_MinorGridColor_Click(object sender, EventArgs e)
+ {
+ ColorDialog d = new ColorDialog();
+ if (d.ShowDialog() == DialogResult.OK)
+ {
+ bt_MinorGridColor.BackColor = d.Color;
+ gpane.MinorGridColor = d.Color;
+ gpane.Invalidate();
+ }
+ }
+
+ private void cb_Y_AutoScale_CheckedChanged(object sender, EventArgs e)
+ {
+ if (selectetGraphIndex >= 0 && selectetGraphIndex < gpane.Sources.Count)
+ {
+ DataSource src = gpane.Sources[selectetGraphIndex];
+
+ src.AutoScaleY = cb_Y_AutoScale.Checked;
+
+ UpdateAllCheckedState();
+
+ gpane.Invalidate();
+ }
+ }
+
+ private void cb_X_AutoScale_CheckedChanged(object sender, EventArgs e)
+ {
+ if (selectetGraphIndex >= 0 && selectetGraphIndex < gpane.Sources.Count)
+ {
+ DataSource src = gpane.Sources[selectetGraphIndex];
+
+ src.AutoScaleX = cb_X_AutoScale.Checked;
+
+ UpdateAllCheckedState();
+
+ gpane.Invalidate();
+ }
+ }
+ }
+}
diff --git a/GraphLib/PlotterGraphSelectCurvesForm.resx b/GraphLib/PlotterGraphSelectCurvesForm.resx
new file mode 100644
index 000000000..19dc0dd8b
--- /dev/null
+++ b/GraphLib/PlotterGraphSelectCurvesForm.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/GraphLib/PrecisionTimer.cs b/GraphLib/PrecisionTimer.cs
new file mode 100644
index 000000000..5480f2e1d
--- /dev/null
+++ b/GraphLib/PrecisionTimer.cs
@@ -0,0 +1,490 @@
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+#region License
+
+/*
+ * Based on the work of Leslie Sanford
+ */
+
+#endregion
+
+
+namespace PrecisionTimer
+{
+ public enum Mode
+ {
+ OneShot,
+ Periodic
+ };
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct TimerCaps
+ {
+ public int periodMin;
+ public int periodMax;
+ }
+
+
+ public sealed class Timer : IComponent
+ {
+ private delegate void TimeProc(int id, int msg, int user, int param1, int param2);
+
+ private delegate void EventRaiser(EventArgs e);
+
+ [DllImport("winmm.dll")]
+ private static extern int timeGetDevCaps(ref TimerCaps caps,
+ int sizeOfTimerCaps);
+
+ [DllImport("winmm.dll")]
+ private static extern int timeSetEvent(int delay,
+ int resolution,
+ TimeProc proc,
+ int user,
+ int mode);
+
+ [DllImport("winmm.dll")]
+ private static extern int timeKillEvent(int id);
+
+ private const int TIMERR_NOERROR = 0;
+
+ private int timerID;
+
+ private volatile Mode mode;
+
+ private volatile int period;
+
+ private volatile int resolution;
+
+ private TimeProc timeProcPeriodic;
+
+ private TimeProc timeProcOneShot;
+
+ private EventRaiser tickRaiser;
+
+ private bool running = false;
+
+ private volatile bool disposed = false;
+
+ private ISynchronizeInvoke synchronizingObject = null;
+
+ private ISite site = null;
+
+ private static TimerCaps caps;
+
+ public event EventHandler Started;
+
+ public event EventHandler Stopped;
+
+ public event EventHandler Tick;
+
+ static Timer()
+ {
+ // Get multimedia timer capabilities.
+ timeGetDevCaps(ref caps, Marshal.SizeOf(caps));
+ }
+
+
+ public Timer(IContainer container)
+ {
+
+ container.Add(this);
+
+ Initialize();
+ }
+
+
+ public Timer()
+ {
+ Initialize();
+ }
+
+ ~Timer()
+ {
+ if(IsRunning)
+ {
+ // Stop and destroy timer.
+ timeKillEvent(timerID);
+ }
+ }
+
+ private void Initialize()
+ {
+ this.mode = Mode.Periodic;
+ this.period = Capabilities.periodMin;
+ this.resolution = 1;
+
+ running = false;
+
+ timeProcPeriodic = new TimeProc(TimerPeriodicEventCallback);
+ timeProcOneShot = new TimeProc(TimerOneShotEventCallback);
+ tickRaiser = new EventRaiser(OnTick);
+ }
+
+
+ public void Start()
+ {
+
+ if(disposed)
+ {
+ throw new ObjectDisposedException("Timer");
+ }
+
+ if(IsRunning)
+ {
+ return;
+ }
+
+ if(Mode == Mode.Periodic)
+ {
+ timerID = timeSetEvent(Period, Resolution, timeProcPeriodic, 0, (int)Mode);
+ }
+ else
+ {
+ timerID = timeSetEvent(Period, Resolution, timeProcOneShot, 0, (int)Mode);
+ }
+
+ if(timerID != 0)
+ {
+ running = true;
+
+ if(SynchronizingObject != null && SynchronizingObject.InvokeRequired)
+ {
+ SynchronizingObject.BeginInvoke(
+ new EventRaiser(OnStarted),
+ new object[] { EventArgs.Empty });
+ }
+ else
+ {
+ OnStarted(EventArgs.Empty);
+ }
+ }
+ else
+ {
+ throw new TimerException("Unable to start timer.");
+ }
+ }
+
+
+ public void Stop()
+ {
+
+ if(disposed)
+ {
+ throw new ObjectDisposedException("Timer");
+ }
+
+ if(!running)
+ {
+ return;
+ }
+
+
+ int result = timeKillEvent(timerID);
+
+ Debug.Assert(result == TIMERR_NOERROR);
+
+ running = false;
+
+ if(SynchronizingObject != null && SynchronizingObject.InvokeRequired)
+ {
+ SynchronizingObject.BeginInvoke(
+ new EventRaiser(OnStopped),
+ new object[] { EventArgs.Empty });
+ }
+ else
+ {
+ OnStopped(EventArgs.Empty);
+ }
+ }
+
+
+ private void TimerPeriodicEventCallback(int id, int msg, int user, int param1, int param2)
+ {
+ if(synchronizingObject != null)
+ {
+ synchronizingObject.BeginInvoke(tickRaiser, new object[] { EventArgs.Empty });
+ }
+ else
+ {
+ OnTick(EventArgs.Empty);
+ }
+ }
+
+ private void TimerOneShotEventCallback(int id, int msg, int user, int param1, int param2)
+ {
+ if(synchronizingObject != null)
+ {
+ synchronizingObject.BeginInvoke(tickRaiser, new object[] { EventArgs.Empty });
+ Stop();
+ }
+ else
+ {
+ OnTick(EventArgs.Empty);
+ Stop();
+ }
+ }
+
+
+
+ // Raises the Disposed event.
+ private void OnDisposed(EventArgs e)
+ {
+ EventHandler handler = Disposed;
+
+ if(handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ // Raises the Started event.
+ private void OnStarted(EventArgs e)
+ {
+ EventHandler handler = Started;
+
+ if(handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ // Raises the Stopped event.
+ private void OnStopped(EventArgs e)
+ {
+ EventHandler handler = Stopped;
+
+ if(handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ // Raises the Tick event.
+ private void OnTick(EventArgs e)
+ {
+ EventHandler handler = Tick;
+
+ if(handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+
+
+
+
+ ///
+ /// Gets or sets the object used to marshal event-handler calls.
+ ///
+ public ISynchronizeInvoke SynchronizingObject
+ {
+ get
+ {
+ #region Require
+
+ if(disposed)
+ {
+ throw new ObjectDisposedException("Timer");
+ }
+
+ #endregion
+
+ return synchronizingObject;
+ }
+ set
+ {
+ #region Require
+
+ if(disposed)
+ {
+ throw new ObjectDisposedException("Timer");
+ }
+
+ #endregion
+
+ synchronizingObject = value;
+ }
+ }
+
+
+ public int Period
+ {
+ get
+ {
+ #region Require
+
+ if(disposed)
+ {
+ throw new ObjectDisposedException("Timer");
+ }
+
+ #endregion
+
+ return period;
+ }
+ set
+ {
+ #region Require
+
+ if(disposed)
+ {
+ throw new ObjectDisposedException("Timer");
+ }
+ else if(value < Capabilities.periodMin || value > Capabilities.periodMax)
+ {
+ throw new ArgumentOutOfRangeException("Period", value,
+ "Multimedia Timer period out of range.");
+ }
+
+ #endregion
+
+ period = value;
+
+ if(IsRunning)
+ {
+ Stop();
+ Start();
+ }
+ }
+ }
+
+
+ public int Resolution
+ {
+ get
+ {
+
+ if(disposed)
+ {
+ throw new ObjectDisposedException("Timer");
+ }
+
+ return resolution;
+ }
+ set
+ {
+ if(disposed)
+ {
+ throw new ObjectDisposedException("Timer");
+ }
+ else if(value < 0)
+ {
+ throw new ArgumentOutOfRangeException("Resolution", value,
+ "timer resolution out of range.");
+ }
+
+ resolution = value;
+
+ if(IsRunning)
+ {
+ Stop();
+ Start();
+ }
+ }
+ }
+
+ public Mode Mode
+ {
+ get
+ {
+
+ if(disposed)
+ {
+ throw new ObjectDisposedException("Timer");
+ }
+
+
+ return mode;
+ }
+ set
+ {
+
+ if(disposed)
+ {
+ throw new ObjectDisposedException("Timer");
+ }
+
+
+ mode = value;
+
+ if(IsRunning)
+ {
+ Stop();
+ Start();
+ }
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether the Timer is running.
+ ///
+ public bool IsRunning
+ {
+ get
+ {
+ return running;
+ }
+ }
+
+ ///
+ /// Gets the timer capabilities.
+ ///
+ public static TimerCaps Capabilities
+ {
+ get
+ {
+ return caps;
+ }
+ }
+
+
+
+
+ public event System.EventHandler Disposed;
+
+ public ISite Site
+ {
+ get
+ {
+ return site;
+ }
+ set
+ {
+ site = value;
+ }
+ }
+
+
+ public void Dispose()
+ {
+
+ if(disposed)
+ {
+ return;
+ }
+
+ if(IsRunning)
+ {
+ Stop();
+ }
+
+ disposed = true;
+
+ OnDisposed(EventArgs.Empty);
+ }
+
+
+ }
+
+
+ public class TimerException : ApplicationException
+ {
+ public TimerException(string message) : base(message)
+ {
+ }
+ }
+}
diff --git a/GraphLib/PrintPreviewForm.Designer.cs b/GraphLib/PrintPreviewForm.Designer.cs
new file mode 100644
index 000000000..fd880fb8f
--- /dev/null
+++ b/GraphLib/PrintPreviewForm.Designer.cs
@@ -0,0 +1,264 @@
+namespace GraphLib
+{
+ partial class PrintPreviewForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.printPreviewCtrl = new System.Windows.Forms.PrintPreviewControl();
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.rb_Unscaled = new System.Windows.Forms.RadioButton();
+ this.rb_BestFit = new System.Windows.Forms.RadioButton();
+ this.rb_Scale = new System.Windows.Forms.RadioButton();
+ this.cb_PrintBackground = new System.Windows.Forms.CheckBox();
+ this.label3 = new System.Windows.Forms.Label();
+ this.cb_Printer = new System.Windows.Forms.ComboBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.cb_Orientation = new System.Windows.Forms.ComboBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.cb_PaperSize = new System.Windows.Forms.ComboBox();
+ this.bt_Cancel = new System.Windows.Forms.Button();
+ this.bt_print = new System.Windows.Forms.Button();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.groupBox1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // printPreviewCtrl
+ //
+ this.printPreviewCtrl.BackColor = System.Drawing.SystemColors.ControlLight;
+ this.printPreviewCtrl.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.printPreviewCtrl.Location = new System.Drawing.Point(0, 0);
+ this.printPreviewCtrl.Name = "printPreviewCtrl";
+ this.printPreviewCtrl.Size = new System.Drawing.Size(453, 501);
+ this.printPreviewCtrl.TabIndex = 1;
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+ this.splitContainer1.IsSplitterFixed = true;
+ this.splitContainer1.Location = new System.Drawing.Point(0, 0);
+ this.splitContainer1.Name = "splitContainer1";
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.Controls.Add(this.printPreviewCtrl);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.Controls.Add(this.groupBox1);
+ this.splitContainer1.Panel2.Controls.Add(this.cb_PrintBackground);
+ this.splitContainer1.Panel2.Controls.Add(this.label3);
+ this.splitContainer1.Panel2.Controls.Add(this.cb_Printer);
+ this.splitContainer1.Panel2.Controls.Add(this.label2);
+ this.splitContainer1.Panel2.Controls.Add(this.cb_Orientation);
+ this.splitContainer1.Panel2.Controls.Add(this.label1);
+ this.splitContainer1.Panel2.Controls.Add(this.cb_PaperSize);
+ this.splitContainer1.Panel2.Controls.Add(this.bt_Cancel);
+ this.splitContainer1.Panel2.Controls.Add(this.bt_print);
+ this.splitContainer1.Size = new System.Drawing.Size(681, 501);
+ this.splitContainer1.SplitterDistance = 453;
+ this.splitContainer1.TabIndex = 2;
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.rb_Unscaled);
+ this.groupBox1.Controls.Add(this.rb_BestFit);
+ this.groupBox1.Controls.Add(this.rb_Scale);
+ this.groupBox1.Location = new System.Drawing.Point(18, 188);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(93, 93);
+ this.groupBox1.TabIndex = 12;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "Scaling";
+ //
+ // rb_Unscaled
+ //
+ this.rb_Unscaled.AutoSize = true;
+ this.rb_Unscaled.Location = new System.Drawing.Point(13, 19);
+ this.rb_Unscaled.Name = "rb_Unscaled";
+ this.rb_Unscaled.Size = new System.Drawing.Size(70, 17);
+ this.rb_Unscaled.TabIndex = 8;
+ this.rb_Unscaled.TabStop = true;
+ this.rb_Unscaled.Text = "Unscaled";
+ this.rb_Unscaled.UseVisualStyleBackColor = true;
+ this.rb_Unscaled.CheckedChanged += new System.EventHandler(this.rb_Unscaled_CheckedChanged);
+ //
+ // rb_BestFit
+ //
+ this.rb_BestFit.AutoSize = true;
+ this.rb_BestFit.Location = new System.Drawing.Point(13, 65);
+ this.rb_BestFit.Name = "rb_BestFit";
+ this.rb_BestFit.Size = new System.Drawing.Size(60, 17);
+ this.rb_BestFit.TabIndex = 6;
+ this.rb_BestFit.TabStop = true;
+ this.rb_BestFit.Text = "Best Fit";
+ this.rb_BestFit.UseVisualStyleBackColor = true;
+ this.rb_BestFit.CheckedChanged += new System.EventHandler(this.rb_BestFit_CheckedChanged);
+ //
+ // rb_Scale
+ //
+ this.rb_Scale.AutoSize = true;
+ this.rb_Scale.Location = new System.Drawing.Point(13, 42);
+ this.rb_Scale.Name = "rb_Scale";
+ this.rb_Scale.Size = new System.Drawing.Size(52, 17);
+ this.rb_Scale.TabIndex = 7;
+ this.rb_Scale.TabStop = true;
+ this.rb_Scale.Text = "Scale";
+ this.rb_Scale.UseVisualStyleBackColor = true;
+ this.rb_Scale.CheckedChanged += new System.EventHandler(this.rb_Scale_CheckedChanged);
+ //
+ // cb_PrintBackground
+ //
+ this.cb_PrintBackground.AutoSize = true;
+ this.cb_PrintBackground.Location = new System.Drawing.Point(22, 321);
+ this.cb_PrintBackground.Name = "cb_PrintBackground";
+ this.cb_PrintBackground.Size = new System.Drawing.Size(108, 17);
+ this.cb_PrintBackground.TabIndex = 11;
+ this.cb_PrintBackground.Text = "Print Background";
+ this.cb_PrintBackground.UseVisualStyleBackColor = true;
+ this.cb_PrintBackground.Visible = false;
+ this.cb_PrintBackground.CheckedChanged += new System.EventHandler(this.cb_PrintBackground_CheckedChanged);
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(19, 29);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(37, 13);
+ this.label3.TabIndex = 10;
+ this.label3.Text = "Printer";
+ //
+ // cb_Printer
+ //
+ this.cb_Printer.FormattingEnabled = true;
+ this.cb_Printer.Location = new System.Drawing.Point(18, 45);
+ this.cb_Printer.Name = "cb_Printer";
+ this.cb_Printer.Size = new System.Drawing.Size(195, 21);
+ this.cb_Printer.TabIndex = 9;
+ this.cb_Printer.SelectedIndexChanged += new System.EventHandler(this.cb_Printer_SelectedIndexChanged);
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(19, 134);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(58, 13);
+ this.label2.TabIndex = 5;
+ this.label2.Text = "Orientation";
+ //
+ // cb_Orientation
+ //
+ this.cb_Orientation.FormattingEnabled = true;
+ this.cb_Orientation.Items.AddRange(new object[] {
+ "Portrait",
+ "Landscape"});
+ this.cb_Orientation.Location = new System.Drawing.Point(18, 150);
+ this.cb_Orientation.Name = "cb_Orientation";
+ this.cb_Orientation.Size = new System.Drawing.Size(93, 21);
+ this.cb_Orientation.TabIndex = 4;
+ this.cb_Orientation.SelectedIndexChanged += new System.EventHandler(this.cb_Orientation_SelectedIndexChanged);
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(19, 81);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(58, 13);
+ this.label1.TabIndex = 3;
+ this.label1.Text = "Paper Size";
+ //
+ // cb_PaperSize
+ //
+ this.cb_PaperSize.FormattingEnabled = true;
+ this.cb_PaperSize.Location = new System.Drawing.Point(18, 97);
+ this.cb_PaperSize.Name = "cb_PaperSize";
+ this.cb_PaperSize.Size = new System.Drawing.Size(93, 21);
+ this.cb_PaperSize.TabIndex = 2;
+ this.cb_PaperSize.SelectedIndexChanged += new System.EventHandler(this.cb_PaperSize_SelectedIndexChanged);
+ //
+ // bt_Cancel
+ //
+ this.bt_Cancel.Location = new System.Drawing.Point(118, 450);
+ this.bt_Cancel.Name = "bt_Cancel";
+ this.bt_Cancel.Size = new System.Drawing.Size(69, 26);
+ this.bt_Cancel.TabIndex = 1;
+ this.bt_Cancel.Text = "Cancel";
+ this.bt_Cancel.UseVisualStyleBackColor = true;
+ this.bt_Cancel.Click += new System.EventHandler(this.bt_Cancel_Click);
+ //
+ // bt_print
+ //
+ this.bt_print.Location = new System.Drawing.Point(22, 450);
+ this.bt_print.Name = "bt_print";
+ this.bt_print.Size = new System.Drawing.Size(69, 26);
+ this.bt_print.TabIndex = 0;
+ this.bt_print.Text = "Print";
+ this.bt_print.UseVisualStyleBackColor = true;
+ this.bt_print.Click += new System.EventHandler(this.bt_print_Click);
+ //
+ // PrintPreviewForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(681, 501);
+ this.Controls.Add(this.splitContainer1);
+ this.MaximumSize = new System.Drawing.Size(697, 537);
+ this.MinimumSize = new System.Drawing.Size(697, 537);
+ this.Name = "PrintPreviewForm";
+ this.Text = "PrintPreviewForm";
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ this.splitContainer1.Panel2.PerformLayout();
+ this.splitContainer1.ResumeLayout(false);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.PrintPreviewControl printPreviewCtrl;
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ private System.Windows.Forms.Button bt_Cancel;
+ private System.Windows.Forms.Button bt_print;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.ComboBox cb_PaperSize;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.ComboBox cb_Orientation;
+ private System.Windows.Forms.RadioButton rb_Scale;
+ private System.Windows.Forms.RadioButton rb_BestFit;
+ private System.Windows.Forms.RadioButton rb_Unscaled;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.ComboBox cb_Printer;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.CheckBox cb_PrintBackground;
+ }
+}
\ No newline at end of file
diff --git a/GraphLib/PrintPreviewForm.cs b/GraphLib/PrintPreviewForm.cs
new file mode 100644
index 000000000..bb6ece574
--- /dev/null
+++ b/GraphLib/PrintPreviewForm.cs
@@ -0,0 +1,336 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Drawing.Printing;
+
+namespace GraphLib
+{
+ public partial class PrintPreviewForm : Form
+ {
+ private PrintDocument printDoc = new PrintDocument();
+ private PlotterGraphPaneEx gpane = null;
+ private String strDefaultPrinter = String.Empty;
+
+ private bool bBestScale = false;
+ private bool bPageScale = false;
+ private bool bUnscaled = false;
+ private bool bLandscape = false;
+ private int selPrinterIndex = -1;
+
+ public PrintPreviewForm()
+ {
+ InitializeComponent();
+
+ printPreviewCtrl.Zoom = 1;
+ rb_BestFit.Checked = true;
+ rb_Scale.Checked = false;
+ rb_Unscaled.Checked = false;
+ cb_Orientation.SelectedIndex = 0;
+ printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);
+ this.VisibleChanged += new EventHandler(OnVisibleChanged);
+ FormClosing += new FormClosingEventHandler(OnFormClosing);
+ }
+
+ void FillInInstalledPrinters()
+ {
+ strDefaultPrinter = printDoc.PrinterSettings.PrinterName;
+ cb_Printer.Items.Clear();
+ foreach (String strPrinter in PrinterSettings.InstalledPrinters)
+ {
+ cb_Printer.Items.Add(strPrinter);
+
+ if (strPrinter == strDefaultPrinter)
+ {
+ cb_Printer.SelectedIndex = cb_Printer.Items.IndexOf(strPrinter);
+ }
+ }
+ }
+
+ void OnVisibleChanged(object sender, EventArgs e)
+ {
+ if (this.Visible)
+ {
+ bLandscape = cb_Orientation.SelectedIndex == 1;
+
+ FillInInstalledPrinters();
+
+ FillInPaperSizes();
+
+ UpdateScaleRadioButtons();
+
+ InvalidatePrintPreview();
+ }
+ else
+ {
+
+ }
+ }
+
+ void OnFormClosing(object sender, FormClosingEventArgs e)
+ {
+ this.Hide();
+ e.Cancel = true;
+ }
+
+ void UpdateScaleRadioButtons()
+ {
+ bBestScale = rb_BestFit.Checked;
+ bPageScale = rb_Scale.Checked;
+ bUnscaled = rb_Unscaled.Checked;
+ }
+
+ double AutoZoomPreview()
+ {
+ float zoom = 1.0f;
+ float step = 0.05f;
+
+ float PaperWidth = printDoc.DefaultPageSettings.PaperSize.Width;
+ float PaperHeight = printDoc.DefaultPageSettings.PaperSize.Height;
+
+ if (bLandscape)
+ {
+ PaperHeight = printDoc.DefaultPageSettings.PaperSize.Width * zoom;
+ PaperWidth = printDoc.DefaultPageSettings.PaperSize.Height * zoom;
+ }
+
+ while (zoom > 0.1f)
+ {
+ double CurW = PaperWidth * zoom;
+ double CurH = PaperHeight * zoom;
+
+ if (splitContainer1.Panel1.Width < (CurW+10) || splitContainer1.Panel1.Height < (CurH+10))
+ {
+ zoom -= step;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return zoom;
+ }
+
+ void FillInPaperSizes()
+ {
+ cb_PaperSize.Items.Clear();
+
+ foreach (PaperSize s in printDoc.PrinterSettings.PaperSizes)
+ {
+ cb_PaperSize.Items.Add(s.PaperName.ToString());
+ }
+
+ if (cb_PaperSize.SelectedIndex == -1 || cb_PaperSize.SelectedIndex >= cb_PaperSize.Items.Count)
+ {
+ int idx = cb_PaperSize.Items.IndexOf(printDoc.DefaultPageSettings.PaperSize.PaperName);
+
+ if (idx >= 0 && idx < cb_PaperSize.Items.Count)
+ {
+ cb_PaperSize.SelectedIndex = idx;
+ }
+ else
+ {
+ cb_PaperSize.SelectedIndex = 0;
+ }
+ }
+ }
+
+ void InvalidatePrintPreview()
+ {
+ printDoc.DefaultPageSettings.Landscape = bLandscape;
+ printPreviewCtrl.Document = printDoc;
+ printPreviewCtrl.Document.DocumentName = "Preview";
+ printPreviewCtrl.Zoom = AutoZoomPreview();
+ printPreviewCtrl.InvalidatePreview();
+ }
+
+
+ public PlotterGraphPaneEx GraphPanel
+ {
+ set
+ {
+ gpane = value;
+ }
+ }
+
+ private void AutoScaleDocument(ref float w, ref float h, ref float x, ref float y)
+ {
+ float CurGraphWidth = gpane.Width;
+ float CurGraphHeight = gpane.Height;
+ float CurPaperWidth = printDoc.DefaultPageSettings.PaperSize.Width;
+ float CurPaperHeight = printDoc.DefaultPageSettings.PaperSize.Height;
+
+ if (bLandscape)
+ {
+ CurPaperWidth = printDoc.DefaultPageSettings.PaperSize.Height;
+ CurPaperHeight = printDoc.DefaultPageSettings.PaperSize.Width;
+ }
+
+ if (bUnscaled)
+ {
+ // do nothing
+ }
+
+ if (bPageScale) // scale to page
+ {
+ CurGraphWidth = CurPaperWidth;
+ CurGraphHeight = CurPaperHeight;
+ }
+
+ if (bBestScale) // scale to best fit
+ {
+ float zoom = 1.0f;
+ float step = 0.05f;
+
+ if (CurGraphWidth > (CurPaperWidth ) || CurGraphHeight > (CurPaperHeight ))
+ {
+ // scale down
+ while ((zoom * gpane.Width > CurPaperWidth || zoom * gpane.Height > CurPaperHeight) && zoom > step)
+ {
+ zoom -= step;
+ }
+ zoom -= step;
+
+ }
+ else if (CurGraphWidth < CurPaperWidth && CurGraphHeight < CurPaperHeight)
+ {
+ // scale up
+ while (((zoom+step) * gpane.Width < CurPaperWidth && (zoom+step) * gpane.Height < CurPaperHeight) && zoom > step)
+ {
+ zoom += step;
+ }
+
+ }
+ CurGraphWidth = zoom * gpane.Width;
+ CurGraphHeight = zoom * gpane.Height;
+ }
+
+ w = CurGraphWidth;
+ h = CurGraphHeight;
+
+ // center print
+ x = (CurPaperWidth - w) / 2.0f;
+ y = (CurPaperHeight - h) / 2.0f;
+ }
+
+ private void printDoc_PrintPage(object sender, PrintPageEventArgs e)
+ {
+ if (gpane != null)
+ {
+ float x=0, y=0, w=gpane.Width, h=gpane.Height;
+
+ AutoScaleDocument(ref w, ref h, ref x, ref y);
+ e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+ //gpane.PaintControl(e.Graphics, w, h,x,y,cb_PrintBackground.Checked);
+ gpane.PaintControl(e.Graphics, w, h, x, y, false);
+ }
+ }
+
+ private void bt_print_Click(object sender, EventArgs e)
+ {
+ if (printDoc != null)
+ {
+ printDoc.Print();
+ this.Hide();
+ }
+ }
+
+ private void bt_Cancel_Click(object sender, EventArgs e)
+ {
+ this.Hide();
+ }
+
+ private void cb_PaperSize_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (cb_PaperSize.SelectedIndex >= 0 && cb_PaperSize.SelectedIndex < cb_PaperSize.Items.Count)
+ {
+
+ foreach (PaperSize s in printDoc.PrinterSettings.PaperSizes)
+ {
+ if (s.PaperName == (string)cb_PaperSize.Items[cb_PaperSize.SelectedIndex])
+ {
+ printDoc.DefaultPageSettings.PaperSize = s;
+ InvalidatePrintPreview();
+ }
+ }
+ }
+ }
+
+
+ private void rb_BestFit_CheckedChanged(object sender, EventArgs e)
+ {
+ if (rb_BestFit.Checked)
+ {
+ rb_Scale.Checked = !rb_BestFit.Checked;
+ rb_Unscaled.Checked = !rb_BestFit.Checked;
+ }
+
+ UpdateScaleRadioButtons();
+ InvalidatePrintPreview();
+ }
+
+ private void rb_Scale_CheckedChanged(object sender, EventArgs e)
+ {
+ if (rb_Scale.Checked)
+ {
+ rb_BestFit.Checked = !rb_Scale.Checked;
+ rb_Unscaled.Checked = !rb_Scale.Checked;
+ }
+
+ UpdateScaleRadioButtons();
+ InvalidatePrintPreview();
+ }
+
+ private void rb_Unscaled_CheckedChanged(object sender, EventArgs e)
+ {
+ if (rb_Unscaled.Checked)
+ {
+ rb_Scale.Checked = !rb_Unscaled.Checked;
+ rb_BestFit.Checked = !rb_Unscaled.Checked;
+ }
+
+ UpdateScaleRadioButtons();
+ InvalidatePrintPreview();
+ }
+
+ private void cb_Printer_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ selPrinterIndex = cb_Printer.SelectedIndex;
+
+ if (selPrinterIndex >= 0 && selPrinterIndex < cb_Printer.Items.Count)
+ {
+ printDoc.PrinterSettings.PrinterName = (string)cb_Printer.Items[selPrinterIndex];
+ this.Text = "Print Preview - " + printDoc.PrinterSettings.PrinterName;
+ }
+
+ FillInPaperSizes();
+
+ InvalidatePrintPreview();
+ }
+
+ private void cb_Orientation_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (cb_Orientation.SelectedIndex == 0)
+ {
+ bLandscape = false;
+ }
+ else
+ {
+ bLandscape = true;
+ }
+
+ InvalidatePrintPreview();
+ }
+
+ private void cb_PrintBackground_CheckedChanged(object sender, EventArgs e)
+ {
+ InvalidatePrintPreview();
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/GraphLib/PrintPreviewForm.resx b/GraphLib/PrintPreviewForm.resx
new file mode 100644
index 000000000..19dc0dd8b
--- /dev/null
+++ b/GraphLib/PrintPreviewForm.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/GraphLib/Properties/AssemblyInfo.cs b/GraphLib/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..42e2343ec
--- /dev/null
+++ b/GraphLib/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GraphLibrary")]
+[assembly: AssemblyDescription("Library for easy and simple graph drawing")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("GraphLibrary")]
+[assembly: AssemblyCopyright("Copyright © 2008-2014 ZIMMERMANN STEPHAN")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b23e30ac-c4b8-4863-90d0-cf0ad837c050")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.1")]
+[assembly: AssemblyFileVersion("1.0.0.1")]
diff --git a/GraphLib/Properties/Resources.Designer.cs b/GraphLib/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..00cd8089f
--- /dev/null
+++ b/GraphLib/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// Dieser Code wurde von einem Tool generiert.
+// Laufzeitversion:4.0.30319.18408
+//
+// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+// der Code erneut generiert wird.
+//
+//------------------------------------------------------------------------------
+
+namespace ClassLibrary1.Properties {
+ using System;
+
+
+ ///
+ /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
+ ///
+ // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
+ // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
+ // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
+ // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ClassLibrary1.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
+ /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/GraphLib/Properties/Resources.resx b/GraphLib/Properties/Resources.resx
new file mode 100644
index 000000000..7080a7d11
--- /dev/null
+++ b/GraphLib/Properties/Resources.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/GraphLib/Utils.cs b/GraphLib/Utils.cs
new file mode 100644
index 000000000..d260a98da
--- /dev/null
+++ b/GraphLib/Utils.cs
@@ -0,0 +1,45 @@
+using System;
+
+namespace GraphLib
+{
+ public class Utilities
+ {
+ ///
+ /// returns the most significant decimal digit
+ /// 250 -> 100
+ /// 350 -> 100
+ /// 12 -> 10
+ /// 5 -> 1
+ /// 0.5 .> 0.1
+ /// .....
+ ///
+ ///
+ ///
+ static public float MostSignificantDigit(float Value)
+ {
+ float n = 1;
+
+ float val_abs = Math.Abs(Value);
+ float sig = 1.0f * Math.Sign(Value);
+
+ if (val_abs > 1)
+ {
+ while (n < val_abs)
+ {
+ n *= 10.0f;
+ }
+
+ return (float)((int)(sig * n / 10));
+ }
+ else // n <= 1
+ {
+ while (n > val_abs)
+ {
+ n /= 10.0f;
+ }
+
+ return sig * n;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/TestBenchFramework.sln b/TestBenchFramework.sln
index deac4d74f..5f6c5b019 100644
--- a/TestBenchFramework.sln
+++ b/TestBenchFramework.sln
@@ -2,6 +2,9 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TBF", "TestBenchFramework\TBF.csproj", "{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}"
+ ProjectSection(ProjectDependencies) = postProject
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA} = {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}
+ EndProjectSection
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "TBFSetup", "TBFSetup\TBFSetup.vdproj", "{4890DE5C-9F68-40D7-B075-92C8EAB79833}"
EndProject
@@ -30,6 +33,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserManagement", "UserManag
{743DF7DB-C7B6-42EB-986D-0F485E5588E4} = {743DF7DB-C7B6-42EB-986D-0F485E5588E4}
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphLib", "GraphLib\GraphLib.csproj", "{0C0A1F4D-1363-4544-A7C5-196C76D26CCA}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -126,6 +131,16 @@ Global
{B2CD81B3-AF09-4978-996C-02EDB5F819B7}.Release|Mixed Platforms.Build.0 = Release|x86
{B2CD81B3-AF09-4978-996C-02EDB5F819B7}.Release|x86.ActiveCfg = Release|x86
{B2CD81B3-AF09-4978-996C-02EDB5F819B7}.Release|x86.Build.0 = Release|x86
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {0C0A1F4D-1363-4544-A7C5-196C76D26CCA}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/TestBenchFramework/Properties/AssemblyInfo.cs b/TestBenchFramework/Properties/AssemblyInfo.cs
index a923de5d3..3819db0f3 100644
--- a/TestBenchFramework/Properties/AssemblyInfo.cs
+++ b/TestBenchFramework/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
-[assembly: AssemblyVersion("2.16.660.1")]
-[assembly: AssemblyFileVersion("2.16.660.1")]
+[assembly: AssemblyVersion("2.16.661.1")]
+[assembly: AssemblyFileVersion("2.16.661.1")]
diff --git a/TestBenchFramework/Screens/GraphsTabPageCtrl.cs b/TestBenchFramework/Screens/GraphsTabPageCtrl.cs
new file mode 100644
index 000000000..c19bdf75a
--- /dev/null
+++ b/TestBenchFramework/Screens/GraphsTabPageCtrl.cs
@@ -0,0 +1,38 @@
+///
+/// Copyright (c) 2017 Sensus Metering Systems
+///
+using System;
+using System.Windows.Forms;
+using TBF.Resources;
+using TBF.UiBridge;
+
+namespace TBF.Screens
+{
+ public partial class GraphsTabPageCtrl : UserControl
+ {
+ public GraphsTabPageCtrl()
+ {
+ InitializeComponent();
+ button1.Text = Strings.ClearBtnText;
+
+ Bridge.ProcessDataHandler += delegate(object sender, ProcessDataEventArgs args)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(OnProcessData), sender, args);
+ }
+ else OnProcessData(sender, args);
+ };
+ }
+
+ private void button1_Click(object sender, EventArgs e)
+ {
+ /// TODO: implement
+ }
+
+ void OnProcessData(object sender, ProcessDataEventArgs args)
+ {
+ /// TODO: implement
+ }
+ }
+}
diff --git a/TestBenchFramework/Screens/GraphsTabPageCtrl.designer.cs b/TestBenchFramework/Screens/GraphsTabPageCtrl.designer.cs
new file mode 100644
index 000000000..68ac0f4c1
--- /dev/null
+++ b/TestBenchFramework/Screens/GraphsTabPageCtrl.designer.cs
@@ -0,0 +1,79 @@
+///
+/// Copyright (c) 2017 Sensus Metering Systems
+///
+namespace TBF.Screens
+{
+ partial class GraphsTabPageCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GraphsTabPageCtrl));
+ this.button1 = new System.Windows.Forms.Button();
+ this.splitContainer = new System.Windows.Forms.SplitContainer();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+ this.splitContainer.Panel1.SuspendLayout();
+ this.splitContainer.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // button1
+ //
+ resources.ApplyResources(this.button1, "button1");
+ this.button1.Name = "button1";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_Click);
+ //
+ // splitContainer
+ //
+ resources.ApplyResources(this.splitContainer, "splitContainer");
+ this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+ this.splitContainer.Name = "splitContainer";
+ //
+ // splitContainer.Panel1
+ //
+ this.splitContainer.Panel1.BackColor = System.Drawing.SystemColors.Control;
+ this.splitContainer.Panel1.Controls.Add(this.button1);
+ //
+ // GraphsTabPageCtrl
+ //
+ resources.ApplyResources(this, "$this");
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.BackColor = System.Drawing.Color.Silver;
+ this.Controls.Add(this.splitContainer);
+ this.Name = "GraphsTabPageCtrl";
+ this.splitContainer.Panel1.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+ this.splitContainer.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.SplitContainer splitContainer;
+ }
+}
diff --git a/TestBenchFramework/Screens/GraphsTabPageCtrl.resx b/TestBenchFramework/Screens/GraphsTabPageCtrl.resx
new file mode 100644
index 000000000..760ae01d8
--- /dev/null
+++ b/TestBenchFramework/Screens/GraphsTabPageCtrl.resx
@@ -0,0 +1,228 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ Microsoft Sans Serif, 8.25pt
+
+
+
+ NoControl
+
+
+ 12, 34
+
+
+ 2, 2, 2, 2
+
+
+ 42, 30
+
+
+
+ 1
+
+
+ &Btn1
+
+
+ button1
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ splitContainer.Panel1
+
+
+ 0
+
+
+ Fill
+
+
+ True
+
+
+ 0, 0
+
+
+ splitContainer.Panel1
+
+
+ System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ splitContainer
+
+
+ 0
+
+
+ splitContainer.Panel2
+
+
+ System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ splitContainer
+
+
+ 1
+
+
+ 965, 689
+
+
+ 65
+
+
+ 2
+
+
+ splitContainer
+
+
+ System.Windows.Forms.SplitContainer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 0
+
+
+ True
+
+
+ 6, 13
+
+
+ Microsoft Sans Serif, 8.25pt
+
+
+ 965, 689
+
+
+ GraphsTabPageCtrl
+
+
+ System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/TestBenchFramework/TBF.csproj b/TestBenchFramework/TBF.csproj
index 526d5b81a..8c04cc599 100644
--- a/TestBenchFramework/TBF.csproj
+++ b/TestBenchFramework/TBF.csproj
@@ -39,7 +39,7 @@
full
false
bin\Debug\
- TRACE;DEBUG;MUNICH
+ TRACE;DEBUG;MUNICH;CAMERA
prompt
4
true
@@ -49,7 +49,7 @@
pdbonly
true
bin\Release\
- TRACE;MUNICH
+ TRACE;MUNICH;CAMERA
prompt
4
x86
@@ -58,7 +58,7 @@
true
bin\Debug\
- TRACE;DEBUG;MUNICH
+ TRACE;DEBUG;MUNICH;CAMERA
full
x86
prompt
@@ -67,7 +67,7 @@
bin\x86\Release\
- TRACE;MUNICH
+ TRACE;MUNICH;CAMERA
true
pdbonly
x86
@@ -1420,6 +1420,12 @@
True
Strings.zh-CN.resx
+
+ UserControl
+
+
+ GraphsTabPageCtrl.cs
+
UserControl
@@ -2327,6 +2333,9 @@
ResXFileCodeGenerator
Strings.zh-CN.Designer.cs
+
+ GraphsTabPageCtrl.cs
+
PicturesTabPageCtrl.cs
diff --git a/clean.bat b/clean.bat
index 7e5a094da..50ed517c4 100644
--- a/clean.bat
+++ b/clean.bat
@@ -4,6 +4,8 @@ rmdir /s /q DeviceTest\bin
rmdir /s /q DeviceTest\obj
rmdir /s /q Dirichlet.Numerics\bin
rmdir /s /q Dirichlet.Numerics\obj
+rmdir /s /q GraphLib\bin
+rmdir /s /q GraphLib\obj
rmdir /s /q Results\bin
rmdir /s /q Results\obj
rmdir /s /q ResultsBrowser\bin