diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-03-13 15:27:16 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-03-13 15:27:16 +0200 |
| commit | 37b740c1d128d694b9dcbc3669808435b5d88fec (patch) | |
| tree | e94cc6ddc9712dfdad00b7d6041606a0e024e65a /Software/Visual_Studio/Tango.CircularGauge | |
| parent | e75cf513acb73558e948d6012b45f221c718dcf7 (diff) | |
| download | Tango-37b740c1d128d694b9dcbc3669808435b5d88fec.tar.gz Tango-37b740c1d128d694b9dcbc3669808435b5d88fec.zip | |
Implemented Gauge Control & Technician module controller item !
Auto generated diagnostics monitors & controllers PMR.
Diffstat (limited to 'Software/Visual_Studio/Tango.CircularGauge')
9 files changed, 2229 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Tango.CircularGauge/CircularGaugeControl.cs b/Software/Visual_Studio/Tango.CircularGauge/CircularGaugeControl.cs new file mode 100644 index 000000000..1d1d598c6 --- /dev/null +++ b/Software/Visual_Studio/Tango.CircularGauge/CircularGaugeControl.cs @@ -0,0 +1,1419 @@ +/*Copyright (c) 2009 T.Evelyn (evescode@gmail.com) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1.Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2.Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + +DAMAGE.*/ + + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +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 System.Windows.Media.Animation; + +namespace Tango.CircularGauge +{ + /// <summary> + /// Represents a Circular Gauge control + /// </summary> + [TemplatePart(Name = "LayoutRoot", Type = typeof(Grid))] + [TemplatePart(Name = "Pointer", Type = typeof(Path))] + [TemplatePart(Name = "RangeIndicatorLight", Type = typeof(Ellipse))] + [TemplatePart(Name = "PointerCap", Type = typeof(Ellipse))] + public class CircularGaugeControl : Control + { + #region Private variables + + //Private variables + private Grid rootGrid; + private Path rangeIndicator; + private Path pointer; + private Ellipse pointerCap; + private Ellipse lightIndicator; + private bool isInitialValueSet = false; + private Double arcradius1; + private Double arcradius2; + private int animatingSpeedFactor = 6; + + #endregion + + #region Dependency properties + + /// <summary> + /// Dependency property to Get/Set the current value + /// </summary> + public static readonly DependencyProperty CurrentValueProperty = + DependencyProperty.Register("CurrentValue", typeof(double), typeof(CircularGaugeControl), + new PropertyMetadata(Double.MinValue, new PropertyChangedCallback(CircularGaugeControl.OnCurrentValuePropertyChanged))); + + /// <summary> + /// Dependency property to Get/Set the Minimum Value + /// </summary> + public static readonly DependencyProperty MinValueProperty = + DependencyProperty.Register("MinValue", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Maximum Value + /// </summary> + public static readonly DependencyProperty MaxValueProperty = + DependencyProperty.Register("MaxValue", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Radius of the gauge + /// </summary> + public static readonly DependencyProperty RadiusProperty = + DependencyProperty.Register("Radius", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Pointer cap Radius + /// </summary> + public static readonly DependencyProperty PointerCapRadiusProperty = + DependencyProperty.Register("PointerCapRadius", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the pointer length + /// </summary> + public static readonly DependencyProperty PointerLengthProperty = + DependencyProperty.Register("PointerLength", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the scale Radius + /// </summary> + public static readonly DependencyProperty ScaleRadiusProperty = + DependencyProperty.Register("ScaleRadius", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the starting angle of scale + /// </summary> + public static readonly DependencyProperty ScaleStartAngleProperty = + DependencyProperty.Register("ScaleStartAngle", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the sweep angle of scale + /// </summary> + public static readonly DependencyProperty ScaleSweepAngleProperty = + DependencyProperty.Register("ScaleSweepAngle", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the number of major divisions on the scale + /// </summary> + public static readonly DependencyProperty MajorDivisionsCountProperty = + DependencyProperty.Register("MajorDivisionsCount", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the number of minor divisions on the scale + /// </summary> + public static readonly DependencyProperty MinorDivisionsCountProperty = + DependencyProperty.Register("MinorDivisionsCount", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set Optimal Range End Value + /// </summary> + public static readonly DependencyProperty OptimalRangeEndValueProperty = + DependencyProperty.Register("OptimalRangeEndValue", typeof(double), typeof(CircularGaugeControl), new PropertyMetadata(new PropertyChangedCallback(CircularGaugeControl.OnOptimalRangeEndValuePropertyChanged))); + + /// <summary> + /// Dependency property to Get/Set Optimal Range Start Value + /// </summary> + public static readonly DependencyProperty OptimalRangeStartValueProperty = + DependencyProperty.Register("OptimalRangeStartValue", typeof(double), typeof(CircularGaugeControl), new PropertyMetadata(new PropertyChangedCallback(CircularGaugeControl.OnOptimalRangeStartValuePropertyChanged))); + + /// <summary> + /// Dependency property to Get/Set the image source + /// </summary> + public static readonly DependencyProperty ImageSourceProperty = + DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the image offset + /// </summary> + public static readonly DependencyProperty ImageOffsetProperty = + DependencyProperty.Register("ImageOffset", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the range indicator light offset + /// </summary> + public static readonly DependencyProperty RangeIndicatorLightOffsetProperty = + DependencyProperty.Register("RangeIndicatorLightOffset", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the image Size + /// </summary> + public static readonly DependencyProperty ImageSizeProperty = + DependencyProperty.Register("ImageSize", typeof(Size), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Range Indicator Radius + /// </summary> + public static readonly DependencyProperty RangeIndicatorRadiusProperty = + DependencyProperty.Register("RangeIndicatorRadius", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Range Indicator Thickness + /// </summary> + public static readonly DependencyProperty RangeIndicatorThicknessProperty = + DependencyProperty.Register("RangeIndicatorThickness", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the scale label Radius + /// </summary> + public static readonly DependencyProperty ScaleLabelRadiusProperty = + DependencyProperty.Register("ScaleLabelRadius", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Scale Label Size + /// </summary> + public static readonly DependencyProperty ScaleLabelSizeProperty = + DependencyProperty.Register("ScaleLabelSize", typeof(Size), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Scale Label FontSize + /// </summary> + public static readonly DependencyProperty ScaleLabelFontSizeProperty = + DependencyProperty.Register("ScaleLabelFontSize", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Scale Label Foreground + /// </summary> + + public static readonly DependencyProperty ScaleLabelForegroundProperty = + DependencyProperty.Register("ScaleLabelForeground", typeof(Color), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Major Tick Size + /// </summary> + public static readonly DependencyProperty MajorTickSizeProperty = + DependencyProperty.Register("MajorTickRectSize", typeof(Size), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Minor Tick Size + /// </summary> + public static readonly DependencyProperty MinorTickSizeProperty = + DependencyProperty.Register("MinorTickSize", typeof(Size), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Major Tick Color + /// </summary> + public static readonly DependencyProperty MajorTickColorProperty = + DependencyProperty.Register("MajorTickColor", typeof(Color), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Minor Tick Color + /// </summary> + public static readonly DependencyProperty MinorTickColorProperty = + DependencyProperty.Register("MinorTickColor", typeof(Color), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Gauge Background Color + /// </summary> + public static readonly DependencyProperty GaugeBackgroundColorProperty = + DependencyProperty.Register("GaugeBackgroundColor", typeof(Color), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Pointer Thickness + /// </summary> + public static readonly DependencyProperty PointerThicknessProperty = + DependencyProperty.Register("PointerThickness", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the an option to reset the pointer on start up to the minimum value + /// </summary> + public static readonly DependencyProperty ResetPointerOnStartUpProperty = + DependencyProperty.Register("ResetPointerOnStartUp", typeof(bool), typeof(CircularGaugeControl), new PropertyMetadata(false, null)); + + /// <summary> + /// Dependency property to Get/Set the Scale Value Precision + /// </summary> + public static readonly DependencyProperty ScaleValuePrecisionProperty = + DependencyProperty.Register("ScaleValuePrecision", typeof(int), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Below Optimal Range Color + /// </summary> + + public static readonly DependencyProperty BelowOptimalRangeColorProperty = + DependencyProperty.Register("BelowOptimalRangeColor", typeof(Color), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Optimal Range Color + /// </summary> + + public static readonly DependencyProperty OptimalRangeColorProperty = + DependencyProperty.Register("OptimalRangeColor", typeof(Color), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Above Optimal Range Color + /// </summary> + + public static readonly DependencyProperty AboveOptimalRangeColorProperty = + DependencyProperty.Register("AboveOptimalRangeColor", typeof(Color), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Dial Text + /// </summary> + + public static readonly DependencyProperty DialTextProperty = + DependencyProperty.Register("DialText", typeof(string), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Dial Text Color + /// </summary> + + public static readonly DependencyProperty DialTextColorProperty = + DependencyProperty.Register("DialTextColor", typeof(Color), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Dial Text Font Size + /// </summary> + + public static readonly DependencyProperty DialTextFontSizeProperty = + DependencyProperty.Register("DialTextFontSize", typeof(int), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Dial Text Offset + /// </summary> + + public static readonly DependencyProperty DialTextOffsetProperty = + DependencyProperty.Register("DialTextOffset", typeof(double), typeof(CircularGaugeControl), null); + + /// <summary> + /// Dependency property to Get/Set the Range Indicator light Radius + /// </summary> + + public static readonly DependencyProperty RangeIndicatorLightRadiusProperty = + DependencyProperty.Register("RangeIndicatorLightRadius", typeof(double), typeof(CircularGaugeControl), null); + + + #endregion + + #region Wrapper properties + + /// <summary> + /// Gets/Sets the current value + /// </summary> + public double CurrentValue + { + get + { + return (double)GetValue(CurrentValueProperty); + } + set + { + SetValue(CurrentValueProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Minimum Value + /// </summary> + public double MinValue + { + get + { + return (double)GetValue(MinValueProperty); + } + set + { + SetValue(MinValueProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Maximum Value + /// </summary> + public double MaxValue + { + get + { + return (double)GetValue(MaxValueProperty); + } + set + { + SetValue(MaxValueProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Minimum Value + /// </summary> + public double Radius + { + get + { + return (double)GetValue(RadiusProperty); + } + set + { + SetValue(RadiusProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Pointer cap radius + /// </summary> + public double PointerCapRadius + { + get + { + return (double)GetValue(PointerCapRadiusProperty); + } + set + { + SetValue(PointerCapRadiusProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Pointer Length + /// </summary> + public double PointerLength + { + get + { + return (double)GetValue(PointerLengthProperty); + } + set + { + SetValue(PointerLengthProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Pointer Thickness + /// </summary> + public double PointerThickness + { + get + { + return (double)GetValue(PointerThicknessProperty); + } + set + { + SetValue(PointerThicknessProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Scale radius + /// </summary> + public double ScaleRadius + { + get + { + return (double)GetValue(ScaleRadiusProperty); + } + set + { + SetValue(ScaleRadiusProperty, value); + } + } + + /// <summary> + /// Gets/Sets the scale start angle + /// </summary> + public double ScaleStartAngle + { + get + { + return (double)GetValue(ScaleStartAngleProperty); + } + set + { + SetValue(ScaleStartAngleProperty, value); + } + } + + /// <summary> + /// Gets/Sets the scale sweep angle + /// </summary> + public double ScaleSweepAngle + { + get + { + return (double)GetValue(ScaleSweepAngleProperty); + } + set + { + SetValue(ScaleSweepAngleProperty, value); + } + } + + /// <summary> + /// Gets/Sets the number of major divisions on the scale + /// </summary> + public double MajorDivisionsCount + { + get + { + return (double)GetValue(MajorDivisionsCountProperty); + } + set + { + SetValue(MajorDivisionsCountProperty, value); + } + } + + /// <summary> + /// Gets/Sets the number of minor divisions on the scale + /// </summary> + public double MinorDivisionsCount + { + get + { + return (double)GetValue(MinorDivisionsCountProperty); + } + set + { + SetValue(MinorDivisionsCountProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Optimal range end value + /// </summary> + public double OptimalRangeEndValue + { + get + { + return (double)GetValue(OptimalRangeEndValueProperty); + } + set + { + SetValue(OptimalRangeEndValueProperty, value); + } + } + /// <summary> + /// Gets/Sets the Optimal Range Start Value + /// </summary> + public double OptimalRangeStartValue + { + get + { + return (double)GetValue(OptimalRangeStartValueProperty); + } + set + { + SetValue(OptimalRangeStartValueProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Gauge image source + /// </summary> + public ImageSource ImageSource + { + get + { + return (ImageSource)GetValue(ImageSourceProperty); + } + set + { + SetValue(ImageSourceProperty, value); + } + } + + + /// <summary> + /// Gets/Sets the Image offset + /// </summary> + public double ImageOffset + { + get + { + return (double)GetValue(ImageOffsetProperty); + } + set + { + SetValue(ImageOffsetProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Range Indicator Light offset + /// </summary> + public double RangeIndicatorLightOffset + { + get + { + return (double)GetValue(RangeIndicatorLightOffsetProperty); + } + set + { + SetValue(RangeIndicatorLightOffsetProperty, value); + } + } + + + /// <summary> + /// Gets/Sets the Image width and height + /// </summary> + public Size ImageSize + { + get + { + return (Size)GetValue(ImageSizeProperty); + } + set + { + SetValue(ImageSizeProperty, value); + } + } + /// <summary> + /// Gets/Sets the Range Indicator Radius + /// </summary> + public double RangeIndicatorRadius + { + get + { + return (double)GetValue(RangeIndicatorRadiusProperty); + } + set + { + SetValue(RangeIndicatorRadiusProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Range Indicator Thickness + /// </summary> + public double RangeIndicatorThickness + { + get + { + return (double)GetValue(RangeIndicatorThicknessProperty); + } + set + { + SetValue(RangeIndicatorThicknessProperty, value); + } + } + /// <summary> + /// Gets/Sets the Scale Label Radius + /// </summary> + public double ScaleLabelRadius + { + get + { + return (double)GetValue(ScaleLabelRadiusProperty); + } + set + { + SetValue(ScaleLabelRadiusProperty, value); + } + } + /// <summary> + /// Gets/Sets the Scale Label Size + /// </summary> + public Size ScaleLabelSize + { + get + { + return (Size)GetValue(ScaleLabelSizeProperty); + } + set + { + SetValue(ScaleLabelSizeProperty, value); + } + } + /// <summary> + /// Gets/Sets the Scale Label Font Size + /// </summary> + public double ScaleLabelFontSize + { + get + { + return (double)GetValue(ScaleLabelFontSizeProperty); + } + set + { + SetValue(ScaleLabelFontSizeProperty, value); + } + } + /// <summary> + /// Gets/Sets the Scale Label Foreground + /// </summary> + public Color ScaleLabelForeground + { + get + { + return (Color)GetValue(ScaleLabelForegroundProperty); + } + set + { + SetValue(ScaleLabelForegroundProperty, value); + } + } + /// <summary> + /// Gets/Sets the Major Tick Size + /// </summary> + public Size MajorTickSize + { + get + { + return (Size)GetValue(MajorTickSizeProperty); + } + set + { + SetValue(MajorTickSizeProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Minor Tick Size + /// </summary> + public Size MinorTickSize + { + get + { + return (Size)GetValue(MinorTickSizeProperty); + } + set + { + SetValue(MinorTickSizeProperty, value); + } + } + /// <summary> + /// Gets/Sets the Major Tick Color + /// </summary> + public Color MajorTickColor + { + get + { + return (Color)GetValue(MajorTickColorProperty); + } + set + { + SetValue(MajorTickColorProperty, value); + } + } + /// <summary> + /// Gets/Sets the Minor Tick Color + /// </summary> + public Color MinorTickColor + { + get + { + return (Color)GetValue(MinorTickColorProperty); + } + set + { + SetValue(MinorTickColorProperty, value); + } + } + + /// <summary> + /// Gets/Sets the Gauge Background color + /// </summary> + public Color GaugeBackgroundColor + { + get + { + return (Color)GetValue(GaugeBackgroundColorProperty); + } + set + { + SetValue(GaugeBackgroundColorProperty, value); + } + } + + + /// <summary> + /// Gets/Sets option to reset the pointer to minimum on start up, Default is true + /// </summary> + public bool ResetPointerOnStartUp + { + get + { + return (bool)GetValue(ResetPointerOnStartUpProperty); + } + set + { + SetValue(ResetPointerOnStartUpProperty, value); + } + } + + /// <summary> + /// Gets/Sets scale value precision + /// </summary> + public int ScaleValuePrecision + { + get + { + return (int)GetValue(ScaleValuePrecisionProperty); + } + set + { + SetValue(ScaleValuePrecisionProperty, value); + } + } + /// <summary> + /// Gets/Sets Below Optimal Range Color + /// </summary> + public Color BelowOptimalRangeColor + { + get + { + return (Color)GetValue(BelowOptimalRangeColorProperty); + } + set + { + SetValue(BelowOptimalRangeColorProperty, value); + } + } + + /// <summary> + /// Gets/Sets Optimal Range Color + /// </summary> + public Color OptimalRangeColor + { + get + { + return (Color)GetValue(OptimalRangeColorProperty); + } + set + { + SetValue(OptimalRangeColorProperty, value); + } + } + + /// <summary> + /// Gets/Sets Above Optimal Range Color + /// </summary> + public Color AboveOptimalRangeColor + { + get + { + return (Color)GetValue(AboveOptimalRangeColorProperty); + } + set + { + SetValue(AboveOptimalRangeColorProperty, value); + } + } + /// <summary> + /// Gets/Sets Dial Text + /// </summary> + public string DialText + { + get + { + return (string)GetValue(DialTextProperty); + } + set + { + SetValue(DialTextProperty, value); + } + } + /// <summary> + /// Gets/Sets Dial Text Color + /// </summary> + public Color DialTextColor + { + get + { + return (Color)GetValue(DialTextColorProperty); + } + set + { + SetValue(DialTextColorProperty, value); + } + } + /// <summary> + /// Gets/Sets Dial Text Font Size + /// </summary> + public int DialTextFontSize + { + get + { + return (int)GetValue(DialTextFontSizeProperty); + } + set + { + SetValue(DialTextFontSizeProperty, value); + } + } + /// <summary> + /// Gets/Sets Dial Text Offset + /// </summary> + public double DialTextOffset + { + get + { + return (double)GetValue(DialTextOffsetProperty); + } + set + { + SetValue(DialTextOffsetProperty, value); + } + } + + /// <summary> + /// Gets/Sets Range Indicator Light Radius + /// </summary> + public double RangeIndicatorLightRadius + { + get + { + return (double)GetValue(RangeIndicatorLightRadiusProperty); + } + set + { + SetValue(RangeIndicatorLightRadiusProperty, value); + } + } + + #endregion + + #region Constructor + static CircularGaugeControl() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(CircularGaugeControl), new FrameworkPropertyMetadata(typeof(CircularGaugeControl))); + } + #endregion + + #region Methods + private static void OnCurrentValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + //Get access to the instance of CircularGaugeConrol whose property value changed + CircularGaugeControl gauge = d as CircularGaugeControl; + gauge.OnCurrentValueChanged(e); + + } + + private static void OnOptimalRangeEndValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + //Get access to the instance of CircularGaugeConrol whose property value changed + CircularGaugeControl gauge = d as CircularGaugeControl; + if ((double)e.NewValue > gauge.MaxValue) + { + gauge.OptimalRangeEndValue = gauge.MaxValue; + } + + } + private static void OnOptimalRangeStartValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + //Get access to the instance of CircularGaugeConrol whose property value changed + CircularGaugeControl gauge = d as CircularGaugeControl; + if ((double)e.NewValue < gauge.MinValue) + { + gauge.OptimalRangeStartValue = gauge.MinValue; + } + + + } + + public virtual void OnCurrentValueChanged(DependencyPropertyChangedEventArgs e) + { + //Validate and set the new value + double newValue = (double)e.NewValue; + double oldValue = (double)e.OldValue; + + if (newValue > this.MaxValue) + { + newValue = this.MaxValue; + } + else if (newValue < this.MinValue) + { + newValue = this.MinValue; + } + + if (oldValue > this.MaxValue) + { + oldValue = this.MaxValue; + } + else if (oldValue < this.MinValue) + { + oldValue = this.MinValue; + } + + if (pointer != null) + { + double db1 = 0; + Double oldcurr_realworldunit = 0; + Double newcurr_realworldunit = 0; + Double realworldunit = (ScaleSweepAngle / (MaxValue - MinValue)); + //Resetting the old value to min value the very first time. + if (oldValue == 0 && !isInitialValueSet) + { + oldValue = MinValue; + isInitialValueSet = true; + + } + if (oldValue < 0) + { + db1 = MinValue + Math.Abs(oldValue); + oldcurr_realworldunit = ((double)(Math.Abs(db1 * realworldunit))); + } + else + { + db1 = Math.Abs(MinValue) + oldValue; + oldcurr_realworldunit = ((double)(db1 * realworldunit)); + } + if (newValue < 0) + { + db1 = MinValue + Math.Abs(newValue); + newcurr_realworldunit = ((double)(Math.Abs(db1 * realworldunit))); + } + else + { + db1 = Math.Abs(MinValue) + newValue; + newcurr_realworldunit = ((double)(db1 * realworldunit)); + } + + Double oldcurrentvalueAngle = (ScaleStartAngle + oldcurr_realworldunit); + Double newcurrentvalueAngle = (ScaleStartAngle + newcurr_realworldunit); + + //Animate the pointer from the old value to the new value + AnimatePointer(oldcurrentvalueAngle, newcurrentvalueAngle); + + } + + } + + /// <summary> + /// Animates the pointer to the current value to the new one + /// </summary> + /// <param name="oldcurrentvalueAngle"></param> + /// <param name="newcurrentvalueAngle"></param> + void AnimatePointer(double oldcurrentvalueAngle, double newcurrentvalueAngle) + { + if (pointer != null) + { + DoubleAnimation da = new DoubleAnimation(); + da.From = oldcurrentvalueAngle; + da.To = newcurrentvalueAngle; + + double animDuration = Math.Abs(oldcurrentvalueAngle - newcurrentvalueAngle) * animatingSpeedFactor; + da.Duration = new Duration(TimeSpan.FromMilliseconds(animDuration)); + + Storyboard sb = new Storyboard(); + sb.Completed += new EventHandler(sb_Completed); + sb.Children.Add(da); + Storyboard.SetTarget(da, pointer); + Storyboard.SetTargetProperty(da, new PropertyPath("(Path.RenderTransform).(TransformGroup.Children)[0].(RotateTransform.Angle)")); + + if (newcurrentvalueAngle != oldcurrentvalueAngle) + { + sb.Begin(); + } + } + } + + /// <summary> + /// Move pointer without animating + /// </summary> + /// <param name="angleValue"></param> + void MovePointer(double angleValue) + { + if (pointer != null) + { + TransformGroup tg = pointer.RenderTransform as TransformGroup; + RotateTransform rt = tg.Children[0] as RotateTransform; + rt.Angle = angleValue; + + } + } + + /// <summary> + /// Switch on the Range indicator light after the pointer completes animating + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void sb_Completed(object sender, EventArgs e) + { + if (this.CurrentValue > OptimalRangeEndValue) + { + lightIndicator.Fill = GetRangeIndicatorGradEffect(AboveOptimalRangeColor); + + } + else if (this.CurrentValue <= OptimalRangeEndValue && this.CurrentValue >= OptimalRangeStartValue) + { + lightIndicator.Fill = GetRangeIndicatorGradEffect(OptimalRangeColor); + + } + else if (this.CurrentValue < OptimalRangeStartValue) + { + lightIndicator.Fill = GetRangeIndicatorGradEffect(BelowOptimalRangeColor); + } + + } + + /// <summary> + /// Get gradient brush effect for the range indicator light + /// </summary> + /// <param name="gradientColor"></param> + /// <returns></returns> + private GradientBrush GetRangeIndicatorGradEffect(Color gradientColor) + { + + LinearGradientBrush gradient = new LinearGradientBrush(); + gradient.StartPoint = new Point(0, 0); + gradient.EndPoint = new Point(1, 1); + GradientStop color1 = new GradientStop(); + if (gradientColor == Colors.Transparent) + { + color1.Color = gradientColor; + } + else + color1.Color = Colors.LightGray; + + color1.Offset = 0.2; + gradient.GradientStops.Add(color1); + GradientStop color2 = new GradientStop(); + color2.Color = gradientColor; color2.Offset = 0.5; + gradient.GradientStops.Add(color2); + GradientStop color3 = new GradientStop(); + color3.Color = gradientColor; color3.Offset = 0.8; + gradient.GradientStops.Add(color3); + return gradient; + } + + + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + //Get reference to known elements on the control template + rootGrid = GetTemplateChild("LayoutRoot") as Grid; + pointer = GetTemplateChild("Pointer") as Path; + pointerCap = GetTemplateChild("PointerCap") as Ellipse; + lightIndicator = GetTemplateChild("RangeIndicatorLight") as Ellipse; + + //Draw scale and range indicator + DrawScale(); + DrawRangeIndicator(); + + //Set Zindex of pointer and pointer cap to a really high number so that it stays on top of the + //scale and the range indicator + Canvas.SetZIndex(pointer, 100000); + Canvas.SetZIndex(pointerCap, 100001); + + if (ResetPointerOnStartUp) + { + //Reset Pointer + MovePointer(ScaleStartAngle); + } + + + + } + + + //Drawing the scale with the Scale Radius + private void DrawScale() + { + //Calculate one major tick angle + Double majorTickUnitAngle = ScaleSweepAngle / MajorDivisionsCount; + + //Obtaining One minor tick angle + Double minorTickUnitAngle = ScaleSweepAngle / MinorDivisionsCount; + + //Obtaining One major ticks value + Double majorTicksUnitValue = (MaxValue - MinValue) / MajorDivisionsCount; + majorTicksUnitValue = Math.Round(majorTicksUnitValue, ScaleValuePrecision); + + Double minvalue = MinValue; ; + + // Drawing Major scale ticks + for (Double i = ScaleStartAngle; i <= (ScaleStartAngle + ScaleSweepAngle); i = i + majorTickUnitAngle) + { + + //Majortick is drawn as a rectangle + Rectangle majortickrect = new Rectangle(); + majortickrect.Height = MajorTickSize.Height; + majortickrect.Width = MajorTickSize.Width; + majortickrect.Fill = new SolidColorBrush(MajorTickColor); + Point p = new Point(0.5, 0.5); + majortickrect.RenderTransformOrigin = p; + majortickrect.HorizontalAlignment = HorizontalAlignment.Center; + majortickrect.VerticalAlignment = VerticalAlignment.Center; + + TransformGroup majortickgp = new TransformGroup(); + RotateTransform majortickrt = new RotateTransform(); + + //Obtaining the angle in radians for calulating the points + Double i_radian = (i * Math.PI) / 180; + majortickrt.Angle = i; + majortickgp.Children.Add(majortickrt); + TranslateTransform majorticktt = new TranslateTransform(); + + //Finding the point on the Scale where the major ticks are drawn + //here drawing the points with center as (0,0) + majorticktt.X = (int)((ScaleRadius) * Math.Cos(i_radian)); + majorticktt.Y = (int)((ScaleRadius) * Math.Sin(i_radian)); + + //Points for the textblock which hold the scale value + TranslateTransform majorscalevaluett = new TranslateTransform(); + //here drawing the points with center as (0,0) + majorscalevaluett.X = (int)((ScaleLabelRadius) * Math.Cos(i_radian)); + majorscalevaluett.Y = (int)((ScaleLabelRadius) * Math.Sin(i_radian)); + + //Defining the properties of the scale value textbox + TextBlock tb = new TextBlock(); + + tb.Height = ScaleLabelSize.Height; + tb.Width = ScaleLabelSize.Width; + tb.FontSize = ScaleLabelFontSize; + tb.Foreground = new SolidColorBrush(ScaleLabelForeground); + tb.TextAlignment = TextAlignment.Center; + tb.VerticalAlignment = VerticalAlignment.Center; + tb.HorizontalAlignment = HorizontalAlignment.Center; + + //Writing and appending the scale value + + //checking minvalue < maxvalue w.r.t scale precion value + if (Math.Round(minvalue, ScaleValuePrecision) <= Math.Round(MaxValue, ScaleValuePrecision)) + { + minvalue = Math.Round(minvalue, ScaleValuePrecision); + tb.Text = minvalue.ToString(); + minvalue = minvalue + majorTicksUnitValue; + + } + else + { + break; + } + majortickgp.Children.Add(majorticktt); + majortickrect.RenderTransform = majortickgp; + tb.RenderTransform = majorscalevaluett; + rootGrid.Children.Add(majortickrect); + rootGrid.Children.Add(tb); + + + //Drawing the minor axis ticks + Double onedegree = ((i + majorTickUnitAngle) - i) / (MinorDivisionsCount); + + if ((i < (ScaleStartAngle + ScaleSweepAngle)) && (Math.Round(minvalue, ScaleValuePrecision) <= Math.Round(MaxValue, ScaleValuePrecision))) + { + //Drawing the minor scale + for (Double mi = i + onedegree; mi < (i + majorTickUnitAngle); mi = mi + onedegree) + { + //here the minortick is drawn as a rectangle + Rectangle mr = new Rectangle(); + mr.Height = MinorTickSize.Height; + mr.Width = MinorTickSize.Width; + mr.Fill = new SolidColorBrush(MinorTickColor); + mr.HorizontalAlignment = HorizontalAlignment.Center; + mr.VerticalAlignment = VerticalAlignment.Center; + Point p1 = new Point(0.5, 0.5); + mr.RenderTransformOrigin = p1; + + TransformGroup minortickgp = new TransformGroup(); + RotateTransform minortickrt = new RotateTransform(); + minortickrt.Angle = mi; + minortickgp.Children.Add(minortickrt); + TranslateTransform minorticktt = new TranslateTransform(); + + //Obtaining the angle in radians for calulating the points + Double mi_radian = (mi * Math.PI) / 180; + //Finding the point on the Scale where the minor ticks are drawn + minorticktt.X = (int)((ScaleRadius) * Math.Cos(mi_radian)); + minorticktt.Y = (int)((ScaleRadius) * Math.Sin(mi_radian)); + + minortickgp.Children.Add(minorticktt); + mr.RenderTransform = minortickgp; + rootGrid.Children.Add(mr); + + + } + + } + + } + } + + /// <summary> + /// Obtaining the Point (x,y) in the circumference + /// </summary> + /// <param name="angle"></param> + /// <param name="radius"></param> + /// <returns></returns> + private Point GetCircumferencePoint(Double angle, Double radius) + { + Double angle_radian = (angle * Math.PI) / 180; + //Radius-- is the Radius of the gauge + Double X = (Double)((Radius) + (radius) * Math.Cos(angle_radian)); + Double Y = (Double)((Radius) + (radius) * Math.Sin(angle_radian)); + Point p = new Point(X, Y); + return p; + } + + /// <summary> + /// Draw the range indicator + /// </summary> + private void DrawRangeIndicator() + { + Double realworldunit = (ScaleSweepAngle / (MaxValue - MinValue)); + Double optimalStartAngle; + Double optimalEndAngle; + double db; + + //Checking whether the OptimalRangeStartvalue is -ve + if (OptimalRangeStartValue < 0) + { + db = MinValue + Math.Abs(OptimalRangeStartValue); + optimalStartAngle = ((double)(Math.Abs(db * realworldunit))); + } + else + { + db = Math.Abs(MinValue) + OptimalRangeStartValue; + optimalStartAngle = ((double)(db * realworldunit)); + } + + //Checking whether the OptimalRangeEndvalue is -ve + if (OptimalRangeEndValue < 0) + { + db = MinValue + Math.Abs(OptimalRangeEndValue); + optimalEndAngle = ((double)(Math.Abs(db * realworldunit))); + } + else + { + db = Math.Abs(MinValue) + OptimalRangeEndValue; + optimalEndAngle = ((double)(db * realworldunit)); + } + // calculating the angle for optimal Start value + + Double optimalStartAngleFromStart = (ScaleStartAngle + optimalStartAngle); + + // calculating the angle for optimal Start value + + Double optimalEndAngleFromStart = (ScaleStartAngle + optimalEndAngle); + + //Calculating the Radius of the two arc for segment + arcradius1 = (RangeIndicatorRadius + RangeIndicatorThickness); + arcradius2 = RangeIndicatorRadius; + + double endAngle = ScaleStartAngle + ScaleSweepAngle; + + // Calculating the Points for the below Optimal Range segment from the center of the gauge + + Point A = GetCircumferencePoint(ScaleStartAngle, arcradius1); + Point B = GetCircumferencePoint(ScaleStartAngle, arcradius2); + Point C = GetCircumferencePoint(optimalStartAngleFromStart, arcradius2); + Point D = GetCircumferencePoint(optimalStartAngleFromStart, arcradius1); + + bool isReflexAngle = Math.Abs(optimalStartAngleFromStart - ScaleStartAngle) > 180.0; + DrawSegment(A, B, C, D, isReflexAngle, BelowOptimalRangeColor); + + // Calculating the Points for the Optimal Range segment from the center of the gauge + + Point A1 = GetCircumferencePoint(optimalStartAngleFromStart, arcradius1); + Point B1 = GetCircumferencePoint(optimalStartAngleFromStart, arcradius2); + Point C1 = GetCircumferencePoint(optimalEndAngleFromStart, arcradius2); + Point D1 = GetCircumferencePoint(optimalEndAngleFromStart, arcradius1); + bool isReflexAngle1 = Math.Abs(optimalEndAngleFromStart - optimalStartAngleFromStart) > 180.0; + DrawSegment(A1, B1, C1, D1, isReflexAngle1, OptimalRangeColor); + + // Calculating the Points for the Above Optimal Range segment from the center of the gauge + + Point A2 = GetCircumferencePoint(optimalEndAngleFromStart, arcradius1); + Point B2 = GetCircumferencePoint(optimalEndAngleFromStart, arcradius2); + Point C2 = GetCircumferencePoint(endAngle, arcradius2); + Point D2 = GetCircumferencePoint(endAngle, arcradius1); + bool isReflexAngle2 = Math.Abs(endAngle - optimalEndAngleFromStart) > 180.0; + DrawSegment(A2, B2, C2, D2, isReflexAngle2, AboveOptimalRangeColor); + } + + //Drawing the segment with two arc and two line + + private void DrawSegment(Point p1, Point p2, Point p3, Point p4, bool reflexangle, Color clr) + { + + // Segment Geometry + PathSegmentCollection segments = new PathSegmentCollection(); + + // First line segment from pt p1 - pt p2 + segments.Add(new LineSegment() { Point = p2 }); + + //Arc drawn from pt p2 - pt p3 with the RangeIndicatorRadius + segments.Add(new ArcSegment() + { + Size = new Size(arcradius2, arcradius2), + Point = p3, + SweepDirection = SweepDirection.Clockwise, + IsLargeArc = reflexangle + + }); + + // Second line segment from pt p3 - pt p4 + segments.Add(new LineSegment() { Point = p4 }); + + //Arc drawn from pt p4 - pt p1 with the Radius of arcradius1 + segments.Add(new ArcSegment() + { + Size = new Size(arcradius1, arcradius1), + Point = p1, + SweepDirection = SweepDirection.Counterclockwise, + IsLargeArc = reflexangle + + }); + + // Defining the segment path properties + Color rangestrokecolor; + if (clr == Colors.Transparent) + { + rangestrokecolor = clr; + } + else + rangestrokecolor = Colors.White; + + + + rangeIndicator = new Path() + { + StrokeLineJoin = PenLineJoin.Round, + Stroke = new SolidColorBrush(rangestrokecolor), + //Color.FromArgb(0xFF, 0xF5, 0x9A, 0x86) + Fill = new SolidColorBrush(clr), + Opacity = 0.65, + StrokeThickness = 0.25, + Data = new PathGeometry() + { + Figures = new PathFigureCollection() + { + new PathFigure() + { + IsClosed = true, + StartPoint = p1, + Segments = segments + } + } + } + }; + + //Set Z index of range indicator + rangeIndicator.SetValue(Canvas.ZIndexProperty, 150); + // Adding the segment to the root grid + rootGrid.Children.Add(rangeIndicator); + + } + + #endregion + } +} diff --git a/Software/Visual_Studio/Tango.CircularGauge/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.CircularGauge/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..eaecfc80d --- /dev/null +++ b/Software/Visual_Studio/Tango.CircularGauge/Properties/AssemblyInfo.cs @@ -0,0 +1,18 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +[assembly: AssemblyTitle("Tango - Circular Gauge Control")] +[assembly: ComVisible(false)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/Software/Visual_Studio/Tango.CircularGauge/Properties/Resources.Designer.cs b/Software/Visual_Studio/Tango.CircularGauge/Properties/Resources.Designer.cs new file mode 100644 index 000000000..92a65f881 --- /dev/null +++ b/Software/Visual_Studio/Tango.CircularGauge/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace Tango.CircularGauge.Properties { + using System; + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [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() { + } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [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("Tango.CircularGauge.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [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/Software/Visual_Studio/Tango.CircularGauge/Properties/Resources.resx b/Software/Visual_Studio/Tango.CircularGauge/Properties/Resources.resx new file mode 100644 index 000000000..af7dbebba --- /dev/null +++ b/Software/Visual_Studio/Tango.CircularGauge/Properties/Resources.resx @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root>
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.CircularGauge/Properties/Settings.Designer.cs b/Software/Visual_Studio/Tango.CircularGauge/Properties/Settings.Designer.cs new file mode 100644 index 000000000..791f73266 --- /dev/null +++ b/Software/Visual_Studio/Tango.CircularGauge/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace Tango.CircularGauge.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.1.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Software/Visual_Studio/Tango.CircularGauge/Properties/Settings.settings b/Software/Visual_Studio/Tango.CircularGauge/Properties/Settings.settings new file mode 100644 index 000000000..033d7a5e9 --- /dev/null +++ b/Software/Visual_Studio/Tango.CircularGauge/Properties/Settings.settings @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8'?> +<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> + <Profiles> + <Profile Name="(Default)" /> + </Profiles> + <Settings /> +</SettingsFile>
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.CircularGauge/Tango.CircularGauge.csproj b/Software/Visual_Studio/Tango.CircularGauge/Tango.CircularGauge.csproj new file mode 100644 index 000000000..1773852f7 --- /dev/null +++ b/Software/Visual_Studio/Tango.CircularGauge/Tango.CircularGauge.csproj @@ -0,0 +1,128 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>9.0.30729</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{6EFD5895-177B-4BBB-AF52-29F4D53B3FBD}</ProjectGuid> + <OutputType>library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Tango.CircularGauge</RootNamespace> + <AssemblyName>Tango.CircularGauge</AssemblyName> + <TargetFrameworkVersion>v4.6</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <WarningLevel>4</WarningLevel> + <FileUpgradeFlags> + </FileUpgradeFlags> + <UpgradeBackupLocation> + </UpgradeBackupLocation> + <OldToolsVersion>3.5</OldToolsVersion> + <PublishUrl>publish\</PublishUrl> + <Install>true</Install> + <InstallFrom>Disk</InstallFrom> + <UpdateEnabled>false</UpdateEnabled> + <UpdateMode>Foreground</UpdateMode> + <UpdateInterval>7</UpdateInterval> + <UpdateIntervalUnits>Days</UpdateIntervalUnits> + <UpdatePeriodically>false</UpdatePeriodically> + <UpdateRequired>false</UpdateRequired> + <MapFileExtensions>true</MapFileExtensions> + <ApplicationRevision>0</ApplicationRevision> + <ApplicationVersion>1.0.0.%2a</ApplicationVersion> + <IsWebBootstrapper>false</IsWebBootstrapper> + <UseApplicationTrust>false</UseApplicationTrust> + <BootstrapperEnabled>true</BootstrapperEnabled> + <TargetFrameworkProfile /> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>..\Build\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <Prefer32Bit>false</Prefer32Bit> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>..\Build\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <Prefer32Bit>false</Prefer32Bit> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Xaml" /> + <Reference Include="System.Xml.Linq"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Data.DataSetExtensions"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + <Reference Include="WindowsBase" /> + <Reference Include="PresentationCore" /> + <Reference Include="PresentationFramework" /> + </ItemGroup> + <ItemGroup> + <Page Include="Themes\Generic.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + <Compile Include="..\Versioning\GlobalVersionInfo.cs"> + <Link>GlobalVersionInfo.cs</Link> + </Compile> + <Compile Include="CircularGaugeControl.cs"> + <SubType>Code</SubType> + </Compile> + </ItemGroup> + <ItemGroup> + <Compile Include="Properties\AssemblyInfo.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + <Compile Include="Properties\Settings.Designer.cs"> + <AutoGen>True</AutoGen> + <DependentUpon>Settings.settings</DependentUpon> + <DesignTimeSharedInput>True</DesignTimeSharedInput> + </Compile> + <Compile Include="TypeConverters.cs" /> + <EmbeddedResource Include="Properties\Resources.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + </EmbeddedResource> + <None Include="Properties\Settings.settings"> + <Generator>SettingsSingleFileGenerator</Generator> + <LastGenOutput>Settings.Designer.cs</LastGenOutput> + </None> + <AppDesigner Include="Properties\" /> + </ItemGroup> + <ItemGroup> + <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5 SP1</ProductName> + <Install>true</Install> + </BootstrapperPackage> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.CircularGauge/Themes/Generic.xaml b/Software/Visual_Studio/Tango.CircularGauge/Themes/Generic.xaml new file mode 100644 index 000000000..edef67f07 --- /dev/null +++ b/Software/Visual_Studio/Tango.CircularGauge/Themes/Generic.xaml @@ -0,0 +1,174 @@ +<!--Copyright (c) 2009 T.Evelyn (evescode@gmail.com)
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+1.Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+2.Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.-->
+
+ <ResourceDictionary
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:Tango.CircularGauge">
+ <!-- Type converters-->
+ <local:ImageOffsetConverter x:Key="imageOffsetConverter" />
+ <local:RadiusToDiameterConverter x:Key="radiusToDiameterConverter"/>
+ <local:PointerCenterConverter x:Key="pointerCenterConverter"/>
+ <local:RangeIndicatorLightPositionConverter x:Key="rangeIndicatorLightPositionConverter"/>
+ <local:SizeConverter x:Key="sizeConverter" />
+ <local:BackgroundColorConverter x:Key="backgroundColorConverter" />
+ <local:GlassEffectWidthConverter x:Key="glassEffectWidthConverter" />
+ <local:ColorToSolidColorBrushConverter x:Key="colorToSolidColorBrushConverter" />
+
+
+ <Style TargetType="local:CircularGaugeControl" >
+ <Setter Property="ResetPointerOnStartUp" Value="True" />
+ <Setter Property="ScaleValuePrecision" Value="5" />
+ <Setter Property="BorderBrush">
+ <Setter.Value>
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+ <GradientStop Color="#FFA3AFD6" Offset="0.321"/>
+ <GradientStop Color="#FF8399A9" Offset="0.674"/>
+ <GradientStop Color="#FF718597" Offset="0.375"/>
+ <GradientStop Color="#FF617584" Offset="1"/>
+ </LinearGradientBrush>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="RangeIndicatorThickness" Value="5"/>
+ <Setter Property="GaugeBackgroundColor" Value="Black" />
+ <Setter Property="BelowOptimalRangeColor" Value="Yellow" />
+ <Setter Property="OptimalRangeColor" Value="Green" />
+ <Setter Property="AboveOptimalRangeColor" Value="Red" />
+ <Setter Property="DialTextColor" Value="White" />
+ <Setter Property="DialTextFontSize" Value="8" />
+
+ <Setter Property="Template" >
+ <Setter.Value>
+ <ControlTemplate TargetType="local:CircularGaugeControl">
+ <!-- Root Grid-->
+ <Grid x:Name="LayoutRoot"
+ Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Radius, Converter={StaticResource radiusToDiameterConverter}}"
+ Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Radius, Converter={StaticResource radiusToDiameterConverter}}" >
+
+
+ <Ellipse x:Name="OuterFrame" StrokeThickness="16"
+ Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Radius, Converter={StaticResource radiusToDiameterConverter}}"
+ Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Radius, Converter={StaticResource radiusToDiameterConverter}}"
+ Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=GaugeBackgroundColor, Converter={StaticResource backgroundColorConverter}}">
+
+ <Ellipse.Stroke>
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+ <GradientStop Color="#FF636060" Offset="1"/>
+ <GradientStop Color="#FF5F5C5C" Offset="0"/>
+ <GradientStop Color="#FFEEDEDE" Offset="0.35"/>
+ <GradientStop Color="#FFA09595" Offset="0.705"/>
+ </LinearGradientBrush>
+ </Ellipse.Stroke>
+ </Ellipse>
+
+
+ <!-- Gauge Image -->
+ <Image Source="{TemplateBinding ImageSource}"
+ Width="{Binding RelativeSource={RelativeSource TemplatedParent},
+ Path=ImageSize, Converter={StaticResource sizeConverter}, ConverterParameter=Width }"
+
+ Height="{Binding RelativeSource={RelativeSource TemplatedParent},
+ Path=ImageSize, Converter={StaticResource sizeConverter}, ConverterParameter=Height }"
+
+ RenderTransform="{Binding RelativeSource={RelativeSource TemplatedParent},
+ Path=ImageOffset, Converter={StaticResource imageOffsetConverter}}">
+
+ </Image>
+
+ <!-- Dial Text -->
+ <TextBlock Text="{TemplateBinding DialText}"
+ HorizontalAlignment="Center" VerticalAlignment="Center"
+ Foreground="{Binding RelativeSource={RelativeSource TemplatedParent},
+ Path=DialTextColor, Converter={StaticResource colorToSolidColorBrushConverter}}"
+ FontSize="{TemplateBinding DialTextFontSize}"
+ FontWeight="Bold"
+
+ RenderTransform="{Binding RelativeSource={RelativeSource TemplatedParent},
+ Path=DialTextOffset, Converter={StaticResource rangeIndicatorLightPositionConverter}}">
+
+ </TextBlock>
+
+ <!-- Pointer -->
+ <Path x:Name="Pointer" Stroke="#FFE91C1C" StrokeThickness="2"
+ Width="{TemplateBinding PointerLength}"
+ Height="{TemplateBinding PointerThickness}" HorizontalAlignment="Center"
+ Data="M1,1 L1,10 L156,6 z" Stretch="Fill" RenderTransformOrigin="0,0.5"
+ RenderTransform="{Binding RelativeSource={RelativeSource TemplatedParent},
+ Path=PointerLength, Converter={StaticResource pointerCenterConverter}}">
+ <Path.Fill>
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+ <GradientStop Color="#FF890A0A" Offset="0.197"/>
+ <GradientStop Color="#FFC40808" Offset="1"/>
+ <GradientStop Color="#FFE32323" Offset="0.61"/>
+ </LinearGradientBrush>
+ </Path.Fill>
+
+ </Path>
+
+
+ <!--Pointer Cap-->
+ <Ellipse x:Name="PointerCap" Height="{TemplateBinding PointerCapRadius}" Width="{TemplateBinding PointerCapRadius}" StrokeThickness="4" Opacity="1" >
+ <Ellipse.Stroke>
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+ <GradientStop Color="#FF000000" Offset="0.675"/>
+ <GradientStop Color="#FFC1B5B5" Offset="0.031"/>
+ </LinearGradientBrush>
+ </Ellipse.Stroke>
+ <Ellipse.Fill>
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+ <GradientStop Color="#FF152029" Offset="0.846"/>
+ <GradientStop Color="#FF140204" Offset="0.342"/>
+ </LinearGradientBrush>
+ </Ellipse.Fill>
+ </Ellipse>
+
+ <!--Range indicator light-->
+ <Ellipse x:Name="RangeIndicatorLight"
+ Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=RangeIndicatorLightRadius, Converter={StaticResource radiusToDiameterConverter}}"
+ Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=RangeIndicatorLightRadius, Converter={StaticResource radiusToDiameterConverter}}"
+
+ RenderTransform="{Binding RelativeSource={RelativeSource TemplatedParent},
+ Path=RangeIndicatorLightOffset, Converter={StaticResource rangeIndicatorLightPositionConverter}}">
+ <!--Range indicator light off position effect-->
+ <Ellipse.Fill>
+ <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
+ <GradientStop Color="LightGray" Offset="0.2" />
+ <GradientStop Color="Gray" Offset="0.5" />
+ <GradientStop Color="Black" Offset="0.8" />
+ </LinearGradientBrush>
+ </Ellipse.Fill>
+ </Ellipse>
+
+ <!--Glass effect ellipse-->
+ <Path x:Name="GlassEffect" StrokeThickness="1" Stretch="Fill" VerticalAlignment="Bottom"
+ Height="{TemplateBinding Radius}"
+ Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Radius, Converter={StaticResource glassEffectWidthConverter}}"
+ Opacity="0.18" Data="M265.99997,151.00005 C263.99994,194.00003 209.55908,259 135.00064,259 C60.442207,259 11,200.00003 5.9999995,157.00005 C5.0181994,148.55656 73.000877,112.00006 137.00053,112.00007 C199.00887,112.00008 266.72015,135.5164 265.99997,151.00005 z">
+ <Path.Fill>
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+ <GradientStop Color="#68FCFCFC"/>
+ <GradientStop Color="#FFF8FCF8" Offset="1"/>
+ </LinearGradientBrush>
+ </Path.Fill>
+ </Path>
+
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+</ResourceDictionary>
diff --git a/Software/Visual_Studio/Tango.CircularGauge/TypeConverters.cs b/Software/Visual_Studio/Tango.CircularGauge/TypeConverters.cs new file mode 100644 index 000000000..98ef8933c --- /dev/null +++ b/Software/Visual_Studio/Tango.CircularGauge/TypeConverters.cs @@ -0,0 +1,277 @@ +/*Copyright (c) 2009 T.Evelyn (evescode@gmail.com)
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+1.Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+2.Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.*/
+
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using System.Windows.Data;
+using System.Globalization;
+
+namespace Tango.CircularGauge
+{
+
+ /// <summary>
+ /// Converts the given color to a SolidColorBrush
+ /// </summary>
+ public class ColorToSolidColorBrushConverter : IValueConverter
+ {
+ public object Convert(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ Color c = (Color)value;
+
+ return new SolidColorBrush(c);
+ }
+
+ public object ConvertBack(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+
+ /// <summary>
+ /// A type converter for converting image offset into render transform
+ /// </summary>
+ public class ImageOffsetConverter : IValueConverter
+ {
+ public object Convert(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ double dblVal = (double)value;
+ TranslateTransform tt = new TranslateTransform();
+ tt.Y = dblVal;
+ return tt;
+ }
+
+ public object ConvertBack(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+
+ /// <summary>
+ /// Converts radius to diameter
+ /// </summary>
+ public class RadiusToDiameterConverter : IValueConverter
+ {
+ public object Convert(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ double dblVal = (double)value;
+
+ return (dblVal *2);
+ }
+
+ public object ConvertBack(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ /// <summary>
+ /// Calculates the pointer position
+ /// </summary>
+ public class PointerCenterConverter : IValueConverter
+ {
+ public object Convert(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ double dblVal = (double)value;
+ TransformGroup tg = new TransformGroup();
+ RotateTransform rt = new RotateTransform();
+ TranslateTransform tt = new TranslateTransform();
+
+ tt.X = dblVal / 2;
+ tg.Children.Add(rt);
+ tg.Children.Add(tt);
+
+ return tg;
+ }
+
+ public object ConvertBack(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ /// <summary>
+ /// Calculates the range indicator light position
+ /// </summary>
+ public class RangeIndicatorLightPositionConverter : IValueConverter
+ {
+ public object Convert(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ double dblVal = (double)value;
+ TransformGroup tg = new TransformGroup();
+ RotateTransform rt = new RotateTransform();
+ TranslateTransform tt = new TranslateTransform();
+
+ tt.Y = dblVal ;
+ tg.Children.Add(rt);
+ tg.Children.Add(tt);
+
+ return tg;
+ }
+
+ public object ConvertBack(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ /// <summary>
+ /// Converts the given Size to height and width
+ /// </summary>
+ public class SizeConverter : IValueConverter
+ {
+ public object Convert(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ double i = 0;
+ Size s = (Size)value;
+ if (parameter.ToString() == "Height")
+ {
+ i = s.Height;
+ }
+ else if (parameter.ToString() == "Width")
+ {
+ i = s.Width;
+ }
+
+ return i;
+
+ }
+
+ public object ConvertBack(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ /// <summary>
+ /// Scaling factor for drawing the glass effect.
+ /// </summary>
+ public class GlassEffectWidthConverter : IValueConverter
+ {
+ public object Convert(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ double dbl = (double)value;
+ return (dbl*2) * 0.94;
+
+ }
+
+ public object ConvertBack(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ /// <summary>
+ /// Converts background color to Gradient effect
+ /// </summary>
+ public class BackgroundColorConverter : IValueConverter
+ {
+ public object Convert(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ Color c = (Color)value;
+ RadialGradientBrush radBrush = new RadialGradientBrush();
+ GradientStop g1 = new GradientStop();
+ g1.Offset = 0.982;
+ g1.Color = c;
+ GradientStop g2 = new GradientStop();
+ g2.Color = Color.FromArgb(0xFF, 0xAF, 0xB2, 0xB0);
+ radBrush.GradientStops.Add(g1);
+ radBrush.GradientStops.Add(g2);
+ return radBrush;
+
+ }
+
+ public object ConvertBack(
+ object value,
+ Type targetType,
+ object parameter,
+ CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
|
