diff options
| author | Avi Levkovich <avi@twine-s.com> | 2018-02-20 16:45:00 +0200 |
|---|---|---|
| committer | Avi Levkovich <avi@twine-s.com> | 2018-02-20 16:45:00 +0200 |
| commit | 6c208c90bc45aff4a7fa214356a42fe7757c5e6f (patch) | |
| tree | 0d77bc6a0ecfbb53cf42c5462ee19212197ee1bd /Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls | |
| parent | b0823127f152fe97a6e8fce29e427c7f3db9cf5a (diff) | |
| parent | 1a573aaa346ec4b8bd58a0e35ab9df571a09b855 (diff) | |
| download | Tango-6c208c90bc45aff4a7fa214356a42fe7757c5e6f.tar.gz Tango-6c208c90bc45aff4a7fa214356a42fe7757c5e6f.zip | |
MERGE
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls')
10 files changed, 790 insertions, 2 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml new file mode 100644 index 000000000..6a9bf9cc9 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml @@ -0,0 +1,23 @@ +<UserControl x:Class="Tango.MachineStudio.Common.Controls.HiveColorPickerControl" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:colorPicker="clr-namespace:Tango;assembly=Tango.ColorPicker" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:local="clr-namespace:Tango.MachineStudio.Common.Controls" + mc:Ignorable="d" + d:DesignHeight="250" d:DesignWidth="500" > + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="235"/> + <ColumnDefinition Width="43*"/> + </Grid.ColumnDefinitions> + + <colorPicker:ColorCanvas SelectedColor="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=SelectedColor,Mode=TwoWay}" Background="Transparent" BorderThickness="0" UsingAlphaChannel="False" /> + + <Viewbox Stretch="Uniform" Grid.Column="1" Margin="5"> + <controls:HiveControl x:Name="hive" Height="250" HexagonSelected="hive_HexagonSelected" MaxSelections="1" Width="250" BorderThickness="1" /> + </Viewbox> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml.cs new file mode 100644 index 000000000..9432ae9ef --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml.cs @@ -0,0 +1,102 @@ +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; + +namespace Tango.MachineStudio.Common.Controls +{ + /// <summary> + /// Interaction logic for HiveColorPickerControl.xaml + /// </summary> + public partial class HiveColorPickerControl : UserControl + { + public event EventHandler<Color> SelectedColorChanged; + private bool _preventHiveSelectedColorChange; + + public bool DemoMode + { + get { return (bool)GetValue(DemoModeProperty); } + set { SetValue(DemoModeProperty, value); } + } + public static readonly DependencyProperty DemoModeProperty = + DependencyProperty.Register("DemoMode", typeof(bool), typeof(HiveColorPickerControl), new PropertyMetadata(false)); + + public Color SelectedColor + { + get { return (Color)GetValue(SelectedColorProperty); } + set { SetValue(SelectedColorProperty, value); } + } + public static readonly DependencyProperty SelectedColorProperty = + DependencyProperty.Register("SelectedColor", typeof(Color), typeof(HiveColorPickerControl), new PropertyMetadata(Colors.Red, (d, e) => (d as HiveColorPickerControl).OnSelectedColorChanged())); + + public Color SelectedHiveColor + { + get { return (Color)GetValue(SelectedHiveColorProperty); } + set { SetValue(SelectedHiveColorProperty, value); } + } + public static readonly DependencyProperty SelectedHiveColorProperty = + DependencyProperty.Register("SelectedHiveColor", typeof(Color), typeof(HiveColorPickerControl), new PropertyMetadata(Colors.Red)); + + public HiveColorPickerControl() + { + InitializeComponent(); + + hive.Loaded += Hive_Loaded; + } + + private void Hive_Loaded(object sender, RoutedEventArgs e) + { + OnSelectedColorChanged(); + } + + private void OnSelectedColorChanged() + { + if (DemoMode) + { + if (!_preventHiveSelectedColorChange) + { + GenerateDemoModeHiveColors(); + } + SelectedColorChanged?.Invoke(this, SelectedColor); + } + } + + private void hive_HexagonSelected(object sender, SharedUI.Controls.HexagonControl hexagon) + { + SelectedHiveColor = (hexagon.Fill as SolidColorBrush).Color; + + _preventHiveSelectedColorChange = true; + SelectedColor = SelectedHiveColor; + _preventHiveSelectedColorChange = false; + } + + private void GenerateDemoModeHiveColors() + { + if (hive.CenterHexagon != null) + { + Random rnd = new Random(); + + (hive.CenterHexagon.Fill as SolidColorBrush).Color = SelectedColor; + + int counter = 0; + + foreach (var hexagon in hive.Hexagons.Where(x => x != hive.CenterHexagon).OrderBy(x => rnd.Next())) + { + (hexagon.Fill as SolidColorBrush).Color = Color.FromRgb((byte)Math.Min(SelectedColor.R + counter++, 255), (byte)Math.Min((SelectedColor.G + counter++), 255), (byte)Math.Min((SelectedColor.B + counter++), 255)); + + counter += 4; + } + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/IRealTimeGraph.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/IRealTimeGraph.cs new file mode 100644 index 000000000..bf40d459e --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/IRealTimeGraph.cs @@ -0,0 +1,53 @@ +using RealTimeGraphEx; +using RealTimeGraphEx.Controllers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.MachineStudio.Common.Controls +{ + public interface IRealTimeGraph + { + /// <summary> + /// Gets or sets the name of the sensor. + /// </summary> + String SensorName { get; set; } + + /// <summary> + /// Gets or sets the tag. + /// </summary> + Object Tag { get; set; } + + /// <summary> + /// Gets or sets the sensor units. + /// </summary> + String SensorUnits { get; set; } + + /// <summary> + /// Occurs when the graph remove button has been pressed. + /// </summary> + event EventHandler GraphRemoveButtonPressed; + + /// <summary> + /// Occurs when the graph full screen button has been pressed. + /// </summary> + event EventHandler GraphFullScreenButtonPressed; + + /// <summary> + /// Gets or sets the inner real-time graph control. + /// </summary> + RealTimeGraphExBase InnerGraph { get; set; } + + /// <summary> + /// Gets or sets the inner graph controller. + /// </summary> + GraphControllerBase Controller { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether to enable toolbar buttons. + /// </summary> + bool EnableToolBar { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiChild.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiChild.cs index 469e3fda5..109b00531 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiChild.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiChild.cs @@ -10,19 +10,34 @@ using Tango.Core.Commands; namespace Tango.MachineStudio.Common.Controls { + /// <summary> + /// Represents an <see cref="MdiContainerControl"/> child control. + /// </summary> + /// <seealso cref="System.Windows.DependencyObject" /> public class MdiChild : DependencyObject { + /// <summary> + /// Initializes a new instance of the <see cref="MdiChild"/> class. + /// </summary> public MdiChild() { } + /// <summary> + /// Initializes a new instance of the <see cref="MdiChild"/> class. + /// </summary> + /// <param name="header">The header.</param> + /// <param name="view">The view.</param> public MdiChild(String header, FrameworkElement view) : this() { Header = header; View = view; } + /// <summary> + /// Gets or sets the icon. + /// </summary> public PackIconKind Icon { get { return (PackIconKind)GetValue(IconProperty); } @@ -31,6 +46,9 @@ namespace Tango.MachineStudio.Common.Controls public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(PackIconKind), typeof(MdiChild), new PropertyMetadata(PackIconKind.LaptopWindows)); + /// <summary> + /// Gets or sets the header. + /// </summary> public String Header { get { return (String)GetValue(HeaderProperty); } @@ -39,6 +57,9 @@ namespace Tango.MachineStudio.Common.Controls public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(String), typeof(MdiChild), new PropertyMetadata(null)); + /// <summary> + /// Gets or sets the view. + /// </summary> public FrameworkElement View { get { return (FrameworkElement)GetValue(ViewProperty); } @@ -47,6 +68,9 @@ namespace Tango.MachineStudio.Common.Controls public static readonly DependencyProperty ViewProperty = DependencyProperty.Register("View", typeof(FrameworkElement), typeof(MdiChild), new PropertyMetadata(null)); + /// <summary> + /// Gets or sets the location. + /// </summary> public Point Location { get { return (Point)GetValue(LocationProperty); } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiContainerControl.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiContainerControl.xaml.cs index dbf4ee74b..ceeda050b 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiContainerControl.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiContainerControl.xaml.cs @@ -20,8 +20,11 @@ using Tango.SharedUI.Helpers; namespace Tango.MachineStudio.Common.Controls { /// <summary> - /// Interaction logic for MdiContainerControl.xaml + /// Represents an MDI-style container /// </summary> + /// <seealso cref="System.Windows.Controls.UserControl" /> + /// <seealso cref="System.Windows.Markup.IComponentConnector" /> + /// <seealso cref="System.Windows.Markup.IStyleConnector" /> public partial class MdiContainerControl : UserControl { private const int MIN_SIZE = 200; @@ -63,7 +66,6 @@ namespace Tango.MachineStudio.Common.Controls return UIHelper.FindChild<Canvas>(itemsControl, "canvas"); } - private void OnControlMouseDown(object sender, MouseButtonEventArgs e) { Canvas.SetZIndex(sender as FrameworkElement, GetCanvas().Children.OfType<FrameworkElement>().Max(x => Canvas.GetZIndex(x) + 1)); diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml new file mode 100644 index 000000000..2f43869d5 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml @@ -0,0 +1,90 @@ +<UserControl x:Class="Tango.MachineStudio.Common.Controls.RealTimeGraphControl" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:graphEx="clr-namespace:RealTimeGraphEx.FastGraphs;assembly=RealTimeGraphEx" + xmlns:components="clr-namespace:RealTimeGraphEx.Components;assembly=RealTimeGraphEx" + xmlns:converters="clr-namespace:Tango.MachineStudio.Common.Converters" + xmlns:local="clr-namespace:Tango.MachineStudio.Common.Controls" + mc:Ignorable="d" + d:DesignHeight="150" d:DesignWidth="300"> + + <UserControl.Resources> + <ResourceDictionary> + <ResourceDictionary.MergedDictionaries> + <!--RealTimeGraphEx--> + <ResourceDictionary Source="pack://application:,,,/RealTimeGraphEx;component/Resources/Resources.xaml"></ResourceDictionary> + <ResourceDictionary Source="../Resources/MaterialDesign.xaml"></ResourceDictionary> + + <ResourceDictionary> + <Style TargetType="ContentControl" x:Key="graphContent"> + <Style.Setters> + <Setter Property="ContentTemplate"> + <Setter.Value> + <DataTemplate> + <Grid MouseEnter="Graph_MouseEnter" MouseLeave="Graph_MouseLeave" ClipToBounds="True"> + <ContentControl Content="{Binding}"></ContentControl> + <Grid Opacity="0.8" HorizontalAlignment="Stretch" VerticalAlignment="Top" ClipToBounds="True" Height="35" Margin="0 -35 0 0"> + <StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right" VerticalAlignment="Top"> + <Button Margin="0 0 5 0" Click="OnGraphFullScreen" ToolTip="Full Screen" Width="24" Height="24" BorderBrush="Transparent" Background="{StaticResource AccentColorBrush}" Style="{StaticResource MaterialDesignFloatingActionAccentButton}" > + <materialDesign:PackIcon Kind="Fullscreen" HorizontalAlignment="Right" Width="20" Height="20" Foreground="{StaticResource WhiteBrush}" /> + </Button> + <Button Click="OnGraphRemove" ToolTip="Remove" Width="24" Height="24" BorderBrush="Transparent" Background="#FF7777" Style="{StaticResource MaterialDesignFloatingActionAccentButton}" > + <materialDesign:PackIcon Kind="CloseCircle" HorizontalAlignment="Right" Width="20" Height="20" Foreground="{StaticResource WhiteBrush}" /> + </Button> + </StackPanel> + </Grid> + </Grid> + </DataTemplate> + </Setter.Value> + </Setter> + </Style.Setters> + </Style> + </ResourceDictionary> + + <ResourceDictionary> + <converters:SecondsToGraphPointsConverter x:Key="secondsToPoints"></converters:SecondsToGraphPointsConverter> + </ResourceDictionary> + </ResourceDictionary.MergedDictionaries> + </ResourceDictionary> + </UserControl.Resources> + + <Grid> + <!--Temperature--> + <ContentControl Style="{StaticResource graphContent}" Margin="0 0 0 0" MinHeight="5"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="40"/> + <ColumnDefinition Width="438*"/> + </Grid.ColumnDefinitions> + + <Border BorderBrush="{StaticResource AccentColorBrush}" BorderThickness="1 1 0 1" Background="#90FFFFFF"> + <StackPanel Orientation="Horizontal"> + <components:YAxisScroll x:Name="yAxis" Interval="6" Graph="{Binding ElementName=Graph}" Width="35" Foreground="{StaticResource MaterialDesignLightForeground}" VerticalOffset="-5" FontSize="8" StringFormat="#0.0"></components:YAxisScroll> + <components:YAxisTicks x:Name="yAxisTicks" SmallTickTemplate="{StaticResource graphTicksTemplate}" Width="5" SmallTicks="6" Foreground="{StaticResource MaterialDesignLightForeground}" BigTicks="10" Graph="{Binding ElementName=Graph}"></components:YAxisTicks> + </StackPanel> + </Border> + <Border Grid.Column="1" BorderThickness="1" BorderBrush="{StaticResource borderBrush}" Background="{DynamicResource graphBackground}" Margin="5 0 0 0"> + <graphEx:RealTimeGraphExLineErase x:Name="Graph" x:FieldModifier="public" Controller="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Controller}" Antialiased="True" RefreshRate="30" MarkerColor="{StaticResource graphsMarkerColor}" FillGraph="False" Stroke="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Color}" Minimum="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Minimum}" Maximum="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Maximum}"> + <graphEx:RealTimeGraphExLineErase.Components> + <components:MouseValueToolTip ToolTipTemplate="{StaticResource graphTooltipTemplate}" /> + <components:GridLines Rows="4" Columns="6" GridBrush="{DynamicResource graphGridLinesBrush}"></components:GridLines> + </graphEx:RealTimeGraphExLineErase.Components> + <graphEx:RealTimeGraphExLineErase.InnerContent> + <Grid> + <Label Style="{StaticResource graphLabel}"> + <StackPanel Orientation="Horizontal"> + <TextBlock VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl,AncestorLevel=2},Path=SensorName,FallbackValue='Dispenser Motor'}"></TextBlock> + <TextBlock Foreground="Gray" Margin="10 0 0 0" FontFamily="Sylfaen Regular" VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl,AncestorLevel=2},Path=SensorUnits,FallbackValue='(hz)'}"></TextBlock> + </StackPanel> + </Label> + </Grid> + </graphEx:RealTimeGraphExLineErase.InnerContent> + </graphEx:RealTimeGraphExLineErase> + </Border> + </Grid> + </ContentControl> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml.cs new file mode 100644 index 000000000..dd9aa1414 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml.cs @@ -0,0 +1,179 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +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.Animation; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using RealTimeGraphEx; +using RealTimeGraphEx.Controllers; + +namespace Tango.MachineStudio.Common.Controls +{ + /// <summary> + /// Interaction logic for RealTimeGraphControl.xaml + /// </summary> + public partial class RealTimeGraphControl : UserControl, IRealTimeGraph + { + private Grid headerGrid; + + #region Properties + + /// <summary> + /// Gets or sets the name of the sensor. + /// </summary> + public String SensorName + { + get { return (String)GetValue(SensorNameProperty); } + set { SetValue(SensorNameProperty, value); } + } + public static readonly DependencyProperty SensorNameProperty = + DependencyProperty.Register("SensorName", typeof(String), typeof(RealTimeGraphControl), new PropertyMetadata(null)); + + /// <summary> + /// Gets or sets the sensor units. + /// </summary> + public String SensorUnits + { + get { return (String)GetValue(SensorUnitsProperty); } + set { SetValue(SensorUnitsProperty, value); } + } + public static readonly DependencyProperty SensorUnitsProperty = + DependencyProperty.Register("SensorUnits", typeof(String), typeof(RealTimeGraphControl), new PropertyMetadata(null)); + + + + public double Minimum + { + get { return (double)GetValue(MinimumProperty); } + set { SetValue(MinimumProperty, value); } + } + public static readonly DependencyProperty MinimumProperty = + DependencyProperty.Register("Minimum", typeof(double), typeof(RealTimeGraphControl), new PropertyMetadata(0.0)); + + + + public double Maximum + { + get { return (double)GetValue(MaximumProperty); } + set { SetValue(MaximumProperty, value); } + } + public static readonly DependencyProperty MaximumProperty = + DependencyProperty.Register("Maximum", typeof(double), typeof(RealTimeGraphControl), new PropertyMetadata(100.0)); + + + + public Color Color + { + get { return (Color)GetValue(ColorProperty); } + set { SetValue(ColorProperty, value); } + } + public static readonly DependencyProperty ColorProperty = + DependencyProperty.Register("Color", typeof(Color), typeof(RealTimeGraphControl), new PropertyMetadata(Colors.DodgerBlue)); + + + + public void InvalidateGraph() + { + InnerGraph.Clear(); + yAxis.Render(InnerGraph); + yAxisTicks.Render(InnerGraph); + } + + /// <summary> + /// Gets or sets the inner real-time graph control. + /// </summary> + public RealTimeGraphExBase InnerGraph { get; set; } + + /// <summary> + /// Gets or sets the inner graph controller. + /// </summary> + public GraphControllerBase Controller { get; set; } + + + private bool _enableToolbar; + /// <summary> + /// Gets or sets a value indicating whether to enable toolbar buttons. + /// </summary> + public bool EnableToolBar + { + get { return _enableToolbar; } + set + { + _enableToolbar = value; + + if (!value) + { + if (headerGrid != null) + { + ThicknessAnimation ani = new ThicknessAnimation(); + ani.To = new Thickness(0, -35, 0, 0); + ani.Duration = TimeSpan.FromSeconds(0.2); + headerGrid.BeginAnimation(Grid.MarginProperty, ani); + } + } + } + } + + + #endregion + + #region Events + + public event EventHandler GraphRemoveButtonPressed; + public event EventHandler GraphFullScreenButtonPressed; + + #endregion + + public RealTimeGraphControl() + { + InitializeComponent(); + EnableToolBar = true; + InnerGraph = Graph; + Controller = new GraphController(); + } + + private void OnGraphFullScreen(object sender, RoutedEventArgs e) + { + GraphFullScreenButtonPressed?.Invoke(this, new EventArgs()); + } + + private void Graph_MouseEnter(object sender, MouseEventArgs e) + { + if (EnableToolBar) + { + Grid mainGrid = sender as Grid; + headerGrid = mainGrid.Children.OfType<Grid>().ToList().First(); + ThicknessAnimation ani = new ThicknessAnimation(); + ani.To = new Thickness(0, 0, 0, 0); + ani.Duration = TimeSpan.FromSeconds(0.2); + headerGrid.BeginAnimation(Grid.MarginProperty, ani); + } + } + + private void Graph_MouseLeave(object sender, MouseEventArgs e) + { + Grid mainGrid = sender as Grid; + headerGrid = mainGrid.Children.OfType<Grid>().ToList().First(); + ThicknessAnimation ani = new ThicknessAnimation(); + ani.To = new Thickness(0, -35, 0, 0); + ani.Duration = TimeSpan.FromSeconds(0.2); + headerGrid.BeginAnimation(Grid.MarginProperty, ani); + } + + private void OnGraphRemove(object sender, RoutedEventArgs e) + { + GraphRemoveButtonPressed?.Invoke(this, new EventArgs()); + } + + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml new file mode 100644 index 000000000..5548c452e --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml @@ -0,0 +1,95 @@ +<UserControl x:Class="Tango.MachineStudio.Common.Controls.RealTimeGraphMultiControl" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:graphEx="clr-namespace:RealTimeGraphEx.FastGraphs;assembly=RealTimeGraphEx" + xmlns:components="clr-namespace:RealTimeGraphEx.Components;assembly=RealTimeGraphEx" + xmlns:converters="clr-namespace:Tango.MachineStudio.Common.Converters" + xmlns:local="clr-namespace:Tango.MachineStudio.Common.Controls" + mc:Ignorable="d" + d:DesignHeight="150" d:DesignWidth="300"> + + <UserControl.Resources> + <ResourceDictionary> + <ResourceDictionary.MergedDictionaries> + <!--RealTimeGraphEx--> + <ResourceDictionary Source="pack://application:,,,/RealTimeGraphEx;component/Resources/Resources.xaml"></ResourceDictionary> + <ResourceDictionary Source="../Resources/MaterialDesign.xaml"></ResourceDictionary> + + <ResourceDictionary> + <Style TargetType="ContentControl" x:Key="graphContent"> + <Style.Setters> + <Setter Property="ContentTemplate"> + <Setter.Value> + <DataTemplate> + <Grid MouseEnter="Graph_MouseEnter" MouseLeave="Graph_MouseLeave" ClipToBounds="True"> + <ContentControl Content="{Binding}"></ContentControl> + <Grid Opacity="0.8" HorizontalAlignment="Stretch" VerticalAlignment="Top" ClipToBounds="True" Height="35" Margin="0 -35 0 0"> + <StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right" VerticalAlignment="Top"> + <Button Margin="0 0 5 0" Click="OnGraphFullScreen" ToolTip="Full Screen" Width="24" Height="24" BorderBrush="Transparent" Background="{StaticResource AccentColorBrush}" Style="{StaticResource MaterialDesignFloatingActionAccentButton}" > + <materialDesign:PackIcon Kind="Fullscreen" HorizontalAlignment="Right" Width="20" Height="20" Foreground="{StaticResource WhiteBrush}" /> + </Button> + <Button Click="OnGraphRemove" ToolTip="Remove" Width="24" Height="24" BorderBrush="Transparent" Background="#FF7777" Style="{StaticResource MaterialDesignFloatingActionAccentButton}" > + <materialDesign:PackIcon Kind="CloseCircle" HorizontalAlignment="Right" Width="20" Height="20" Foreground="{StaticResource WhiteBrush}" /> + </Button> + </StackPanel> + </Grid> + </Grid> + </DataTemplate> + </Setter.Value> + </Setter> + </Style.Setters> + </Style> + </ResourceDictionary> + + <ResourceDictionary> + <converters:SecondsToGraphPointsConverter x:Key="secondsToPoints"></converters:SecondsToGraphPointsConverter> + </ResourceDictionary> + </ResourceDictionary.MergedDictionaries> + </ResourceDictionary> + </UserControl.Resources> + + <Grid> + <!--Temperature--> + <ContentControl Style="{StaticResource graphContent}" Margin="0 0 0 0" MinHeight="5"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="40"/> + <ColumnDefinition Width="438*"/> + </Grid.ColumnDefinitions> + + <Border BorderBrush="{StaticResource AccentColorBrush}" BorderThickness="1 1 0 1" Background="#90FFFFFF"> + <StackPanel Orientation="Horizontal"> + <components:YAxisScroll x:Name="yAxis" Interval="6" Graph="{Binding ElementName=Graph}" Width="35" Foreground="{StaticResource MaterialDesignLightForeground}" VerticalOffset="-5" FontSize="8" StringFormat="#0.0"></components:YAxisScroll> + <components:YAxisTicks x:Name="yAxisTicks" SmallTickTemplate="{StaticResource graphTicksTemplate}" Width="5" SmallTicks="6" Foreground="{StaticResource MaterialDesignLightForeground}" BigTicks="10" Graph="{Binding ElementName=Graph}"></components:YAxisTicks> + </StackPanel> + </Border> + <Border Grid.Column="1" BorderThickness="1" BorderBrush="{StaticResource borderBrush}" Background="{DynamicResource graphBackground}" Margin="5 0 0 0"> + <graphEx:RealTimeGraphExMultiLineErase x:Name="Graph" x:FieldModifier="public" Controller="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Controller}" Antialiased="True" RefreshRate="30" MarkerColor="{StaticResource graphsMarkerColor}" FillGraph="False" Minimum="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Minimum}" Maximum="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Maximum}" Stroke="DodgerBlue"> + <graphEx:RealTimeGraphExMultiLineErase.Components> + <components:MouseValueToolTip ToolTipTemplate="{StaticResource graphTooltipTemplate}" /> + <components:GridLines Rows="4" Columns="6" GridBrush="{DynamicResource graphGridLinesBrush}"></components:GridLines> + </graphEx:RealTimeGraphExMultiLineErase.Components> + <graphEx:RealTimeGraphExMultiLineErase.InnerContent> + <Grid> + <Label Style="{StaticResource graphLabel}"> + <StackPanel Orientation="Horizontal"> + <TextBlock VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl,AncestorLevel=2},Path=SensorName,FallbackValue='Dispensers Motors'}"></TextBlock> + <TextBlock Foreground="Gray" Margin="10 0 0 0" FontFamily="Sylfaen Regular" VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl,AncestorLevel=2},Path=SensorUnits,FallbackValue='(hz)'}"></TextBlock> + </StackPanel> + </Label> + </Grid> + </graphEx:RealTimeGraphExMultiLineErase.InnerContent> + </graphEx:RealTimeGraphExMultiLineErase> + </Border> + + <Border Grid.Column="2" Margin="5 0 0 0" HorizontalAlignment="Right" Opacity="0.8"> + <components:YAxisLegends VerticalAlignment="Center" Margin="0 0 5 0" Graph="{Binding ElementName=Graph}" Width="70" FlowDirection="RightToLeft" LegendTemplate="{StaticResource graphLegendTemplate}"> + </components:YAxisLegends> + </Border> + </Grid> + </ContentControl> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml.cs new file mode 100644 index 000000000..8e3b6b6e3 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml.cs @@ -0,0 +1,162 @@ +using RealTimeGraphEx; +using RealTimeGraphEx.Controllers; +using System; +using System.Collections.Generic; +using System.ComponentModel; +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.Animation; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.MachineStudio.Common.Controls +{ + /// <summary> + /// Interaction logic for RealTimeGraphControl.xaml + /// </summary> + public partial class RealTimeGraphMultiControl : UserControl , IRealTimeGraph + { + private Grid headerGrid; + + #region Properties + + /// <summary> + /// Gets or sets the name of the sensor. + /// </summary> + public String SensorName + { + get { return (String)GetValue(SensorNameProperty); } + set { SetValue(SensorNameProperty, value); } + } + public static readonly DependencyProperty SensorNameProperty = + DependencyProperty.Register("SensorName", typeof(String), typeof(RealTimeGraphMultiControl), new PropertyMetadata(null)); + + /// <summary> + /// Gets or sets the sensor units. + /// </summary> + public String SensorUnits + { + get { return (String)GetValue(SensorUnitsProperty); } + set { SetValue(SensorUnitsProperty, value); } + } + public static readonly DependencyProperty SensorUnitsProperty = + DependencyProperty.Register("SensorUnits", typeof(String), typeof(RealTimeGraphMultiControl), new PropertyMetadata(null)); + + public double Minimum + { + get { return (double)GetValue(MinimumProperty); } + set { SetValue(MinimumProperty, value); } + } + public static readonly DependencyProperty MinimumProperty = + DependencyProperty.Register("Minimum", typeof(double), typeof(RealTimeGraphMultiControl), new PropertyMetadata(0.0)); + + + + public double Maximum + { + get { return (double)GetValue(MaximumProperty); } + set { SetValue(MaximumProperty, value); } + } + public static readonly DependencyProperty MaximumProperty = + DependencyProperty.Register("Maximum", typeof(double), typeof(RealTimeGraphMultiControl), new PropertyMetadata(100.0)); + + public void InvalidateGraph() + { + InnerGraph.Clear(); + yAxis.Render(InnerGraph); + yAxisTicks.Render(InnerGraph); + } + + /// <summary> + /// Gets or sets the inner real-time graph control. + /// </summary> + public RealTimeGraphExBase InnerGraph { get; set; } + + /// <summary> + /// Gets or sets the inner graph controller. + /// </summary> + public GraphControllerBase Controller { get; set; } + + private bool _enableToolbar; + /// <summary> + /// Gets or sets a value indicating whether to enable toolbar buttons. + /// </summary> + public bool EnableToolBar + { + get { return _enableToolbar; } + set + { + _enableToolbar = value; + + if (!value) + { + if (headerGrid != null) + { + ThicknessAnimation ani = new ThicknessAnimation(); + ani.To = new Thickness(0, -35, 0, 0); + ani.Duration = TimeSpan.FromSeconds(0.2); + headerGrid.BeginAnimation(Grid.MarginProperty, ani); + } + } + } + } + + #endregion + + #region Events + + public event EventHandler GraphRemoveButtonPressed; + public event EventHandler GraphFullScreenButtonPressed; + + #endregion + + public RealTimeGraphMultiControl() + { + InitializeComponent(); + EnableToolBar = true; + InnerGraph = Graph; + Controller = new GraphMultiController(); + } + + private void OnGraphFullScreen(object sender, RoutedEventArgs e) + { + GraphFullScreenButtonPressed?.Invoke(this, new EventArgs()); + } + + private void Graph_MouseEnter(object sender, MouseEventArgs e) + { + if (EnableToolBar) + { + Grid mainGrid = sender as Grid; + headerGrid = mainGrid.Children.OfType<Grid>().ToList().First(); + ThicknessAnimation ani = new ThicknessAnimation(); + ani.To = new Thickness(0, 0, 0, 0); + ani.Duration = TimeSpan.FromSeconds(0.2); + headerGrid.BeginAnimation(Grid.MarginProperty, ani); + } + } + + private void Graph_MouseLeave(object sender, MouseEventArgs e) + { + Grid mainGrid = sender as Grid; + headerGrid = mainGrid.Children.OfType<Grid>().ToList().First(); + ThicknessAnimation ani = new ThicknessAnimation(); + ani.To = new Thickness(0, -35, 0, 0); + ani.Duration = TimeSpan.FromSeconds(0.2); + headerGrid.BeginAnimation(Grid.MarginProperty, ani); + } + + private void OnGraphRemove(object sender, RoutedEventArgs e) + { + GraphRemoveButtonPressed?.Invoke(this, new EventArgs()); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/TableGrid.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/TableGrid.cs new file mode 100644 index 000000000..07fd0c446 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/TableGrid.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace Tango.MachineStudio.Common.Controls +{ + public class TableGrid : Grid + { + public TableGrid() + { + ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) }); + ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }); + this.Loaded += TableGrid_Loaded; + } + + private void TableGrid_Loaded(object sender, RoutedEventArgs e) + { + InvalidateGrid(); + } + + protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved) + { + base.OnVisualChildrenChanged(visualAdded, visualRemoved); + } + + protected override Size ArrangeOverride(Size arrangeSize) + { + return base.ArrangeOverride(arrangeSize); + } + + private void InvalidateGrid() + { + RowDefinitions.Clear(); + RowDefinitions.Add(new RowDefinition() { Height = new GridLength(50, GridUnitType.Pixel) }); + + int currentRow = 0; + + for (int i = 0; i < Children.Count; i++) + { + SetRow(Children[i], currentRow); + + if (i % 2 != 0) + { + SetColumn(Children[i], 1); + (Children[i] as FrameworkElement).Margin = new Thickness(20, 0, 0, 0); + currentRow++; + RowDefinitions.Add(new RowDefinition() { Height = new GridLength(50, GridUnitType.Pixel) }); + } + + (Children[i] as FrameworkElement).VerticalAlignment = VerticalAlignment.Bottom; + } + } + } +} |
