aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Rendering/TextLayer.cs
blob: 3f4b8299be88d1135723c325c47e6dc8dbb723a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace Tango.Scripting.Editors.Rendering
{
	/// <summary>
	/// The control that contains the text.
	/// 
	/// This control is used to allow other UIElements to be placed inside the TextView but
	/// behind the text.
	/// The text rendering process (VisualLine creation) is controlled by the TextView, this
	/// class simply displays the created Visual Lines.
	/// </summary>
	/// <remarks>
	/// This class does not contain any input handling and is invisible to hit testing. Input
	/// is handled by the TextView.
	/// This allows UIElements that are displayed behind the text, but still can react to mouse input.
	/// </remarks>
	sealed class TextLayer : Layer
	{
		/// <summary>
		/// the index of the text layer in the layers collection
		/// </summary>
		internal int index;
		
		public TextLayer(TextView textView) : base(textView, KnownLayer.Text)
		{
		}
		
		List<VisualLineDrawingVisual> visuals = new List<VisualLineDrawingVisual>();
		
		internal void SetVisualLines(ICollection<VisualLine> visualLines)
		{
			foreach (VisualLineDrawingVisual v in visuals) {
				if (v.VisualLine.IsDisposed)
					RemoveVisualChild(v);
			}
			visuals.Clear();
			foreach (VisualLine newLine in visualLines) {
				VisualLineDrawingVisual v = newLine.Render();
				if (!v.IsAdded) {
					AddVisualChild(v);
					v.IsAdded = true;
				}
				visuals.Add(v);
			}
			InvalidateArrange();
		}
		
		protected override int VisualChildrenCount {
			get { return visuals.Count; }
		}
		
		protected override Visual GetVisualChild(int index)
		{
			return visuals[index];
		}
		
		protected override void ArrangeCore(Rect finalRect)
		{
			textView.ArrangeTextLayer(visuals);
		}
	}
}
s="p">; protected Rectangle rectangle; protected double lastValue; #endregion #region Cross Thread Fields protected Brush _stroke; protected Brush _fill; protected GraphController _graphController; #endregion #region Properties /// <summary> /// Gets or sets the graph strokes color. /// </summary> public Brush Stroke { get { return (Brush)GetValue(StrokeProperty); } set { SetValue(StrokeProperty, value); } } public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register("Stroke", typeof(Brush), typeof(RealTimeGraphExReachVUMeter), new PropertyMetadata(Brushes.Black, new PropertyChangedCallback(CrossModelChanged))); /// <summary> /// Gets or sets the graph fill color. /// </summary> public Brush Fill { get { return (Brush)GetValue(FillProperty); } set { SetValue(FillProperty, value); } } public static readonly DependencyProperty FillProperty = DependencyProperty.Register("Fill", typeof(Brush), typeof(RealTimeGraphExReachVUMeter), new PropertyMetadata(Brushes.Gray, new PropertyChangedCallback(CrossModelChanged))); /// <summary> /// Gets or sets the IDataSeries used to push data points to the graph. /// </summary> public GraphController Controller { get { return (GraphController)GetValue(ControllerProperty); } set { SetValue(ControllerProperty, value); } } public static readonly DependencyProperty ControllerProperty = DependencyProperty.Register("Controller", typeof(GraphController), typeof(RealTimeGraphExReachVUMeter), new PropertyMetadata(null, new PropertyChangedCallback(GraphControllerChanged))); private static void GraphControllerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = d as RealTimeGraphExReachVUMeter; if (control.Controller != null) { control.Controller.RegisterMethods(control.ClearGraph, control.StartPushThread, control.SetPaused,control.ChangeRenderMode,null); control._graphController = control.Controller; } } /// <summary> /// Gets or sets the collection of VU range data determines how to fill the VU graph. /// </summary> public ObservableCollection<Models.RangeData> Ranges { get { return (ObservableCollection<Models.RangeData>)GetValue(RangesProperty); } set { SetValue(RangesProperty, value); } } public static readonly DependencyProperty RangesProperty = DependencyProperty.Register("Ranges", typeof(ObservableCollection<Models.RangeData>), typeof(RealTimeGraphExReachVUMeter), new PropertyMetadata(null)); /// <summary> /// Gets or sets whether to animate the VU when when it's value doens not change. /// </summary> public bool Animate { get { return (bool)GetValue(AnimateProperty); } set { SetValue(AnimateProperty, value); } } public static readonly DependencyProperty AnimateProperty = DependencyProperty.Register("Animate", typeof(bool), typeof(RealTimeGraphExReachVUMeter), new PropertyMetadata(false)); /// <summary> /// Gets or sets the height value to animate when the Animate property is set to true. /// </summary> public double AnimationAmount { get { return (double)GetValue(AnimationAmountProperty); } set { SetValue(AnimationAmountProperty, value); } } public static readonly DependencyProperty AnimationAmountProperty = DependencyProperty.Register("AnimationAmount", typeof(double), typeof(RealTimeGraphExReachVUMeter), new PropertyMetadata(10.0)); /// <summary> /// Gets or sets the duration of the animation when the Animate property is set to true. /// </summary> public Duration AnimationDuration { get { return (Duration)GetValue(AnimationDurationProperty); } set { SetValue(AnimationDurationProperty, value); } } public static readonly DependencyProperty AnimationDurationProperty = DependencyProperty.Register("AnimationDuration", typeof(Duration), typeof(RealTimeGraphExReachVUMeter), new PropertyMetadata(new Duration(TimeSpan.FromMilliseconds(500)))); #endregion #region Constructors public RealTimeGraphExReachVUMeter() : base() { Ranges = new ObservableCollection<Models.RangeData>(); } #endregion #region Override Methods protected override void Initialize() { base.Initialize(); if (rectangle == null) { rectangle = new Rectangle() { Tag = "Default" }; rectangle.Height = 0; } gridLinesAndImageWrapperGrid.Children.Remove(img); if (!gridLinesAndImageWrapperGrid.Children.Contains(rectangle)) { gridLinesAndImageWrapperGrid.Children.Add(rectangle); } //TODO: Base on developer selection vertical/horizontal VU. rectangle.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch; rectangle.VerticalAlignment = System.Windows.VerticalAlignment.Bottom; } protected override void OnSetCrossThreadFields() { base.OnSetCrossThreadFields(); this.Dispatcher.Invoke(() => { _graphController = Controller; _stroke = Stroke; _fill = Fill; if (rectangle.Tag != null && rectangle.Tag.ToString() == "Default") { rectangle.Fill = Fill; rectangle.Stroke = Stroke; } if (_graphController != null && _graphController.dataSeries != null && _graphController.dataSeries.useFillandStroke) { rectangle.Fill = _graphController.dataSeries.fill; rectangle.Stroke = _graphController.dataSeries.stroke; } }, DispatcherPriority.Send); } protected override void OnClearGraph() { base.OnClearGraph(); this.Dispatcher.Invoke(() => { rectangle.BeginAnimation(Rectangle.HeightProperty, null); rectangle.Height = 0; }); } protected internal override void OnRenderGraph() { if (_graphController != null && _graphController.dataSeries.Points != null && _graphController.dataSeries.Points.Count > 0 && _width > 1 && _height > 1) { double value = _graphController.dataSeries.Points[_graphController.dataSeries.Points.Count - 1]; //Get last value. if (value == lastValue) { _graphController.ClearPoints(); return; } lastValue = value; double valuePrecentage = ConvertYToImageY(value); updateCounter++; if (updateCounter >= 1 && !_isPaused) { updateCounter = 0; OnDrawVisuals(valuePrecentage); } _graphController.ClearPoints(); } } #endregion #region Virtual Methods protected virtual void OnDrawVisuals(double valuePrecentage) { this.Dispatcher.Invoke(() => { rectangle.BeginAnimation(Rectangle.HeightProperty, null); rectangle.Height = valuePrecentage; rectangle.Fill = GetRectangleBrush(); if (Animate) { DoubleAnimation ani = new DoubleAnimation(); ani.CurrentTimeInvalidated += (x, y) => { rectangle.Fill = GetRectangleBrush(); }; ani.To = rectangle.Height - AnimationAmount; ani.From = rectangle.Height; ani.RepeatBehavior = RepeatBehavior.Forever; ani.AutoReverse = true; ani.Duration = AnimationDuration; rectangle.BeginAnimation(HeightProperty, ani); } }); } private Brush GetRectangleBrush() { if (Ranges != null && Ranges.Count > 0) { LinearGradientBrush brush = new LinearGradientBrush(); brush.MappingMode = BrushMappingMode.Absolute; brush.StartPoint = new Point(0, _height - rectangle.Height); brush.EndPoint = new Point(0, (rectangle.Height * -1)); brush.Transform = new RotateTransform() { Angle = 180 }; for (int i = Ranges.Count - 1; i >= 0; i--) { var range = Ranges[i]; double rangeValuePrecentage = ConvertYToImageY(range.Value); GradientStop stop = new GradientStop(); stop.Color = range.Color; stop.Offset = ((rangeValuePrecentage * 100) / _height) / 100; brush.GradientStops.Add(stop); } return brush; } else { return Fill; } } #endregion } }