diff options
Diffstat (limited to 'Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphSurface.cs')
| -rw-r--r-- | Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphSurface.cs | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphSurface.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphSurface.cs new file mode 100644 index 000000000..ebcff3472 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphSurface.cs @@ -0,0 +1,380 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using RealTimeGraphX.EventArguments; + +namespace RealTimeGraphX.WPF +{ + /// <summary> + /// Represents a WPF <see cref="IGraphSurface{TDataSeries}">graph surface</see>. + /// </summary> + /// <seealso cref="System.Windows.Controls.Control" /> + /// <seealso cref="RealTimeGraphX.IGraphSurface{RealTimeGraphX.WPF.WpfGraphDataSeries}" /> + public class WpfGraphSurface : Control, IGraphSurface<WpfGraphDataSeries> + { + private WriteableBitmap _writeable_bitmap; + private System.Drawing.Bitmap _gdi_bitmap; + private System.Drawing.Graphics _g; + + private bool _size_changed; + private System.Drawing.SizeF _size; + private System.Drawing.RectangleF _zoom_rect; + private Rectangle _selection_rectangle; + private Canvas _selection_canvas; + private bool _is_selection_mouse_down_zoom; + private bool _is_selection_mouse_down_pan; + private Point _selection_start_point; + private bool _is_scaled; + private Point _current_mouse_position; + private Point _last_mouse_position; + private Grid _grid; + + #region Properties + + /// <summary> + /// Gets or sets current graph rendered image. + /// </summary> + public BitmapSource Image + { + get { return (BitmapSource)GetValue(ImageProperty); } + private set { SetValue(ImageProperty, value); } + } + public static readonly DependencyProperty ImageProperty = + DependencyProperty.Register("Image", typeof(BitmapSource), typeof(WpfGraphSurface), new PropertyMetadata(null)); + + /// <summary> + /// Gets or sets the graph controller. + /// </summary> + public IGraphController<WpfGraphDataSeries> Controller + { + get { return (IGraphController<WpfGraphDataSeries>)GetValue(ControllerProperty); } + set { SetValue(ControllerProperty, value); } + } + public static readonly DependencyProperty ControllerProperty = + DependencyProperty.Register("Controller", typeof(IGraphController<WpfGraphDataSeries>), typeof(WpfGraphSurface), new PropertyMetadata(null, (d, e) => (d as WpfGraphSurface).OnControllerChanged(e.OldValue as IGraphController<WpfGraphDataSeries>, e.NewValue as IGraphController<WpfGraphDataSeries>))); + + #endregion + + #region Constructors + + /// <summary> + /// Initializes the <see cref="WpfGraphSurface"/> class. + /// </summary> + static WpfGraphSurface() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(WpfGraphSurface), new FrameworkPropertyMetadata(typeof(WpfGraphSurface))); + } + + /// <summary> + /// Initializes a new instance of the <see cref="WpfGraphSurface"/> class. + /// </summary> + public WpfGraphSurface() + { + SizeChanged += WpfGraphSurface_SizeChanged; + } + + #endregion + + #region Apply Template + + /// <summary> + /// When overridden in a derived class, is invoked whenever application code or internal processes call <see cref="M:System.Windows.FrameworkElement.ApplyTemplate" />. + /// </summary> + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _selection_rectangle = GetTemplateChild("PART_SelectionRectangle") as Rectangle; + _selection_canvas = GetTemplateChild("PART_SelectionCanvas") as Canvas; + _grid = GetTemplateChild("PART_Grid") as Grid; + + _selection_canvas.MouseDown += OnSelectionCanvasMouseDown; + _selection_canvas.MouseUp += OnSelectionCanvasMouseUp; + _selection_canvas.MouseMove += OnSelectionCanvasMouseMove; + } + + #endregion + + #region Protected Methods + + /// <summary> + /// Called when the mouse moves over the zoom/pan selection canvas. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param> + protected virtual void OnSelectionCanvasMouseMove(object sender, MouseEventArgs e) + { + _current_mouse_position = e.GetPosition(_selection_canvas); + + if (_is_selection_mouse_down_zoom && Keyboard.IsKeyDown(Key.LeftCtrl)) + { + Canvas.SetLeft(_selection_rectangle, _selection_start_point.X); + Canvas.SetTop(_selection_rectangle, _selection_start_point.Y); + + Point _selection_current_point = e.GetPosition(_selection_canvas); + + if (_selection_current_point.X - _selection_start_point.X > 1) + { + _selection_rectangle.Width = _selection_current_point.X - _selection_start_point.X; + } + + if (_selection_current_point.Y - _selection_start_point.Y > 1) + { + _selection_rectangle.Height = _selection_current_point.Y - _selection_start_point.Y; + } + + if (_selection_current_point.X < _selection_start_point.X) + { + Canvas.SetLeft(_selection_rectangle, _selection_current_point.X); + _selection_rectangle.Width = _selection_start_point.X - _selection_current_point.X; + } + + if (_selection_current_point.Y < _selection_start_point.Y) + { + Canvas.SetTop(_selection_rectangle, _selection_current_point.Y); + _selection_rectangle.Height = _selection_start_point.Y - _selection_current_point.Y; + } + } + else if (_is_selection_mouse_down_pan && _is_scaled) + { + Point _selection_current_point = e.GetPosition(_selection_canvas); + + double delta_x = _current_mouse_position.X - _last_mouse_position.X; + double delta_y = _current_mouse_position.Y - _last_mouse_position.Y; + + double x = _zoom_rect.Left - delta_x; + double y = _zoom_rect.Top - delta_y; + + if (x < 0) + { + x = 0; + } + + if (y < 0) + { + y = 0; + } + + if (x + _zoom_rect.Width > _size.Width) + { + x = x - (x + _zoom_rect.Width - _size.Width); + } + + if (y + _zoom_rect.Height > _size.Height) + { + y = y - (y + _zoom_rect.Height - _size.Height); + } + + _zoom_rect = new System.Drawing.RectangleF((float)x, (float)y, _zoom_rect.Width, _zoom_rect.Height); + } + + _last_mouse_position = _current_mouse_position; + } + + /// <summary> + /// Called when the mouse released from the zoom/pan selection canvas. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="MouseButtonEventArgs"/> instance containing the event data.</param> + protected virtual void OnSelectionCanvasMouseUp(object sender, MouseButtonEventArgs e) + { + _selection_canvas.ReleaseMouseCapture(); + + if (_is_selection_mouse_down_pan) + { + _is_selection_mouse_down_pan = false; + } + else if (_is_selection_mouse_down_zoom) + { + _is_selection_mouse_down_zoom = false; + + _zoom_rect = new System.Drawing.RectangleF((float)Canvas.GetLeft(_selection_rectangle), (float)Canvas.GetTop(_selection_rectangle), (float)_selection_rectangle.Width, (float)_selection_rectangle.Height); + _selection_rectangle.Visibility = Visibility.Hidden; + _is_scaled = true; + } + } + + /// <summary> + /// Called when the mouse pressed on the zoom/pan selection canvas. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="MouseButtonEventArgs"/> instance containing the event data.</param> + protected virtual void OnSelectionCanvasMouseDown(object sender, MouseButtonEventArgs e) + { + Mouse.Capture(_selection_canvas); + + _selection_start_point = e.GetPosition(_selection_canvas); + _current_mouse_position = _selection_start_point; + _last_mouse_position = _current_mouse_position; + + if (e.ClickCount == 2) + { + _zoom_rect = new System.Drawing.RectangleF(); + _is_scaled = false; + } + else if (Keyboard.IsKeyDown(Key.LeftCtrl)) + { + _selection_rectangle.Width = 0; + _selection_rectangle.Height = 0; + _is_selection_mouse_down_zoom = true; + _is_selection_mouse_down_pan = false; + _selection_rectangle.Visibility = Visibility.Visible; + } + else + { + _is_selection_mouse_down_pan = true; + } + } + + /// <summary> + /// Called when the <see cref="Controller"/> property has changed. + /// </summary> + /// <param name="oldController">The old controller.</param> + /// <param name="newController">The new controller.</param> + protected virtual void OnControllerChanged(IGraphController<WpfGraphDataSeries> oldController, IGraphController<WpfGraphDataSeries> newController) + { + if (oldController != null) + { + oldController.Surface = null; + } + + if (newController != null) + { + newController.Surface = this; + } + } + + #endregion + + #region IGraphSurface + + /// <summary> + /// Called before drawing has started. + /// </summary> + public void BeginDraw() + { + if (_size_changed) + { + _writeable_bitmap = new WriteableBitmap((int)Math.Max(_size.Width, 1), (int)Math.Max(_size.Height, 1), 96.0, 96.0, PixelFormats.Pbgra32, null); + + _gdi_bitmap = new System.Drawing.Bitmap(_writeable_bitmap.PixelWidth, _writeable_bitmap.PixelHeight, + _writeable_bitmap.BackBufferStride, + System.Drawing.Imaging.PixelFormat.Format32bppPArgb, + _writeable_bitmap.BackBuffer); + + _size_changed = false; + } + + _writeable_bitmap.Lock(); + + _g = System.Drawing.Graphics.FromImage(_gdi_bitmap); + _g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + + _g.Clear(System.Drawing.Color.Transparent); + } + + /// <summary> + /// Applies transformation on the current pass. + /// </summary> + /// <param name="transform">The transform.</param> + public void SetTransform(GraphTransform transform) + { + _g.TranslateTransform((float)transform.TranslateX, (float)transform.TranslateY); + _g.ScaleTransform((float)transform.ScaleX, (float)transform.ScaleY); + } + + /// <summary> + /// Draws the stroke of the specified data series points. + /// </summary> + /// <param name="dataSeries">The data series.</param> + /// <param name="points">The points.</param> + public void DrawSeries(WpfGraphDataSeries dataSeries, IEnumerable<System.Drawing.PointF> points) + { + _g.DrawCurve(dataSeries.GdiPen, points.ToArray()); + } + + /// <summary> + /// Fills the specified data series points. + /// </summary> + /// <param name="dataSeries">The data series.</param> + /// <param name="points">The points.</param> + public void FillSeries(WpfGraphDataSeries dataSeries, IEnumerable<System.Drawing.PointF> points) + { + var brush = dataSeries.GdiFill; + + if (dataSeries.GdiFill is System.Drawing.Drawing2D.LinearGradientBrush) + { + var gradient = dataSeries.GdiFill as System.Drawing.Drawing2D.LinearGradientBrush; + gradient.ResetTransform(); + gradient.ScaleTransform((_size.Width / gradient.Rectangle.Width), (_size.Height / gradient.Rectangle.Height)); + } + + _g.FillPolygon(dataSeries.GdiFill, points.ToArray()); + } + + /// <summary> + /// Called when drawing has completed. + /// </summary> + public void EndDraw() + { + _writeable_bitmap.AddDirtyRect(new Int32Rect(0, 0, _writeable_bitmap.PixelWidth, _writeable_bitmap.PixelHeight)); + _writeable_bitmap.Unlock(); + + var cloned = _writeable_bitmap.Clone(); + cloned.Freeze(); + + Dispatcher.BeginInvoke(new Action((() => + { + Image = cloned; + }))); + + _g.Dispose(); + } + + /// <summary> + /// Returns the actual size of the surface. + /// </summary> + /// <returns></returns> + public System.Drawing.SizeF GetSize() + { + return _size; + } + + /// <summary> + /// Returns the current bounds of the zooming rectangle. + /// </summary> + /// <returns></returns> + public System.Drawing.RectangleF GetZoomRect() + { + return _zoom_rect; + } + + #endregion + + #region Event Handlers + + /// <summary> + /// Handles the WPF Graph Surface Size Changed event. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The event arguments.</param> + private void WpfGraphSurface_SizeChanged(object sender, SizeChangedEventArgs e) + { + _size = new System.Drawing.SizeF((float)e.NewSize.Width, (float)e.NewSize.Height); + _size_changed = true; + } + + #endregion + } +} |
