diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-05-05 00:35:57 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-05-05 00:35:57 +0300 |
| commit | dd81a94133e1c5117e06e84cbddf45ffec30acfc (patch) | |
| tree | 13640f05cae1caf4d893d94e73bb0b7a2705110a /Software | |
| parent | a64398732031132ddedd6584c1990a5caa1ae049 (diff) | |
| download | Tango-dd81a94133e1c5117e06e84cbddf45ffec30acfc.tar.gz Tango-dd81a94133e1c5117e06e84cbddf45ffec30acfc.zip | |
Dashboard completed ?
Remote job tracking.
Diffstat (limited to 'Software')
56 files changed, 1728 insertions, 156 deletions
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/CircularProgressBarBehavior.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/CircularProgressBarBehavior.cs new file mode 100644 index 000000000..24162d176 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/CircularProgressBarBehavior.cs @@ -0,0 +1,38 @@ +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.Shapes; + +namespace Tango.FSE.Common.Behaviors +{ + public class CircularProgressBarBehavior : StyleBehavior<ProgressBar, CircularProgressBarBehavior> + { + public static readonly DependencyProperty StrokeThicknessProperty = + DependencyProperty.RegisterAttached("StrokeThickness", typeof(double), typeof(CircularProgressBarBehavior), new PropertyMetadata(3d)); + + public static double GetStrokeThickness(DependencyObject dependencyObject) + { + return (double)dependencyObject.GetValue(StrokeThicknessProperty); + } + + protected override void OnAttached() + { + base.OnAttached(); + + // ReSharper disable once CompareOfFloatsByEqualityOperator + var path = AssociatedObject.FindVisualChildren<Path>().FirstOrDefault(e => e.Name.Equals("Path")); + + if (path != null) + path.StrokeThickness = GetStrokeThickness(AssociatedObject); + } + + public static void SetStrokeThickness(DependencyObject dependencyObject, double value) + { + dependencyObject.SetValue(StrokeThicknessProperty, value); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/StyleBehavior.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/StyleBehavior.cs new file mode 100644 index 000000000..f8ff649ff --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/StyleBehavior.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Interactivity; + +namespace Tango.FSE.Common.Behaviors +{ + public class StyleBehavior<TComponent, TBehavior> : Behavior<TComponent> + where TComponent : System.Windows.DependencyObject + where TBehavior : StyleBehavior<TComponent, TBehavior>, new() + { + public static DependencyProperty IsEnabledForStyleProperty = + DependencyProperty.RegisterAttached("IsEnabledForStyle", typeof(bool), + typeof(StyleBehavior<TComponent, TBehavior>), new FrameworkPropertyMetadata(false, OnIsEnabledForStyleChanged)); + + public bool IsEnabledForStyle + { + get { return (bool)GetValue(IsEnabledForStyleProperty); } + set { SetValue(IsEnabledForStyleProperty, value); } + } + + private static void OnIsEnabledForStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + UIElement uie = d as UIElement; + + if (uie != null) + { + var behColl = Interaction.GetBehaviors(uie); + var existingBehavior = behColl.FirstOrDefault(b => b.GetType() == + typeof(TBehavior)) as TBehavior; + + if ((bool)e.NewValue == false && existingBehavior != null) + { + behColl.Remove(existingBehavior); + } + + else if ((bool)e.NewValue == true && existingBehavior == null) + { + behColl.Add(new TBehavior()); + } + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.cs new file mode 100644 index 000000000..9da818073 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.cs @@ -0,0 +1,26 @@ +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.FSE.Common.Controls +{ + public class ProgressRing : ProgressBar + { + public double Thickness + { + get { return (double)GetValue(ThicknessProperty); } + set { SetValue(ThicknessProperty, value); } + } + public static readonly DependencyProperty ThicknessProperty = + DependencyProperty.Register("Thickness", typeof(double), typeof(ProgressRing), new PropertyMetadata(3.0)); + + static ProgressRing() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ProgressRing), new FrameworkPropertyMetadata(typeof(ProgressRing))); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.xaml new file mode 100644 index 000000000..ca33aab58 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.xaml @@ -0,0 +1,121 @@ +<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="clr-namespace:Tango.FSE.Common.Controls" + xmlns:sys="clr-namespace:System;assembly=mscorlib" + xmlns:circularProgressBar="clr-namespace:MaterialDesignThemes.Wpf.Converters.CircularProgressBar" + xmlns:transitions="clr-namespace:MaterialDesignThemes.Wpf.Transitions" + xmlns:converters="clr-namespace:MaterialDesignThemes.Wpf.Converters"> + + <Style TargetType="{x:Type local:ProgressRing}"> + <Setter Property="Foreground" Value="{DynamicResource PrimaryHueMidBrush}" /> + <Setter Property="Background" Value="Transparent" /> + <Setter Property="Width" Value="50" /> + <Setter Property="Height" Value="50" /> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type local:ProgressRing}"> + <ControlTemplate.Resources> + <Storyboard x:Key="IsIndeterminateStoryboard" TargetName="RotateTransform" TargetProperty="Angle" RepeatBehavior="Forever"> + <DoubleAnimation From="0" To="359" Duration="0:0:2" /> + </Storyboard> + <Storyboard x:Key="IsFullyIndeterminateScaleStoryboard"> + <DoubleAnimationUsingKeyFrames Storyboard.TargetName="FullyIndeterminateGridScaleTransform" + Storyboard.TargetProperty="ScaleX" + RepeatBehavior="Forever"> + <SplineDoubleKeyFrame KeyTime="0" Value="0.0" /> + <SplineDoubleKeyFrame KeyTime="0:0:1" Value="1.0" /> + <SplineDoubleKeyFrame KeyTime="0:0:4" Value="0.0" /> + </DoubleAnimationUsingKeyFrames> + <DoubleAnimation Storyboard.TargetName="RotateTransform" + Storyboard.TargetProperty="Angle" + RepeatBehavior="Forever" + From="00" To="359" Duration="0:0:1.25" /> + </Storyboard> + </ControlTemplate.Resources> + <Grid x:Name="TemplateRoot" ClipToBounds="False"> + <Grid x:Name="FullyIndeterminateGrid"> + <Grid.RenderTransform> + <ScaleTransform x:Name="FullyIndeterminateGridScaleTransform" ScaleX="0" /> + </Grid.RenderTransform> + </Grid> + <Grid x:Name="PathGrid" Margin="2"/> + <Canvas> + <Path x:Name="Path" Stroke="{TemplateBinding Foreground}" StrokeThickness="{TemplateBinding Thickness}" + Canvas.Top="2" Canvas.Left="2" + RenderTransformOrigin="0, 0"> + <Path.Data> + <PathGeometry> + <PathFigure StartPoint="{Binding ElementName=PathGrid, Path=ActualWidth, Converter={StaticResource StartPointConverter}, Mode=OneWay}"> + <ArcSegment Size="{Binding ElementName=PathGrid, Path=ActualWidth, Converter={StaticResource ArcSizeConverter}, Mode=OneWay}" + SweepDirection="Clockwise"> + <ArcSegment.IsLargeArc> + <MultiBinding Converter="{StaticResource LargeArcConverter}"> + <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value" /> + <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Minimum" /> + <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum" /> + <Binding ElementName="FullyIndeterminateGridScaleTransform" Path="ScaleX" /> + </MultiBinding> + </ArcSegment.IsLargeArc> + <ArcSegment.Point> + <MultiBinding Converter="{StaticResource ArcEndPointConverter}"> + <Binding ElementName="PathGrid" Path="ActualWidth" /> + <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value" /> + <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Minimum" /> + <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum" /> + <Binding ElementName="FullyIndeterminateGridScaleTransform" Path="ScaleX" /> + </MultiBinding> + </ArcSegment.Point> + </ArcSegment> + </PathFigure> + </PathGeometry> + </Path.Data> + <Path.RenderTransform> + <TransformGroup> + <RotateTransform x:Name="RotateTransform" + CenterX="{Binding ElementName=PathGrid, Path=ActualWidth, Converter={StaticResource RotateTransformCentreConverter}, Mode=OneWay}" + CenterY="{Binding ElementName=PathGrid, Path=ActualWidth, Converter={StaticResource RotateTransformCentreConverter}, Mode=OneWay}" /> + </TransformGroup> + </Path.RenderTransform> + </Path> + </Canvas> + </Grid> + <ControlTemplate.Triggers> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding IsIndeterminate, RelativeSource={RelativeSource Self}}" Value="True" /> + <Condition Binding="{Binding IsVisible, RelativeSource={RelativeSource Self}}" Value="True" /> + <Condition Binding="{Binding Value, RelativeSource={RelativeSource Self}, Converter={StaticResource NotZeroConverter}}" Value="True" /> + </MultiDataTrigger.Conditions> + <MultiDataTrigger.EnterActions> + <RemoveStoryboard BeginStoryboardName="IsFullyIndeterminateStoryboard" /> + <BeginStoryboard Storyboard="{StaticResource IsIndeterminateStoryboard}" + Name="IsIndeterminateStoryboard"/> + </MultiDataTrigger.EnterActions> + <MultiDataTrigger.ExitActions> + <RemoveStoryboard BeginStoryboardName="IsIndeterminateStoryboard" /> + </MultiDataTrigger.ExitActions> + </MultiDataTrigger> + <MultiTrigger> + <MultiTrigger.Conditions> + <Condition Property="IsIndeterminate" Value="True" /> + <Condition Property="Value" Value="0" /> + <Condition Property="IsVisible" Value="True" /> + </MultiTrigger.Conditions> + <MultiTrigger.EnterActions> + <RemoveStoryboard BeginStoryboardName="IsIndeterminateStoryboard" /> + <BeginStoryboard Storyboard="{StaticResource IsFullyIndeterminateScaleStoryboard}" + Name="IsFullyIndeterminateStoryboard"/> + </MultiTrigger.EnterActions> + <MultiTrigger.ExitActions> + <RemoveStoryboard BeginStoryboardName="IsFullyIndeterminateStoryboard" /> + </MultiTrigger.ExitActions> + </MultiTrigger> + </ControlTemplate.Triggers> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + + + +</ResourceDictionary>
\ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.cs new file mode 100644 index 000000000..36c0b60a3 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace Tango.FSE.Common.Controls +{ + public class ProgressRingDouble : ProgressRing + { + static ProgressRingDouble() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ProgressRingDouble), new FrameworkPropertyMetadata(typeof(ProgressRingDouble))); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.xaml new file mode 100644 index 000000000..6466e37e3 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.xaml @@ -0,0 +1,23 @@ +<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="clr-namespace:Tango.FSE.Common.Controls"> + + + <Style TargetType="{x:Type local:ProgressRingDouble}"> + <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryAccentBrush}" /> + <Setter Property="Background" Value="{StaticResource FSE_PrimaryBackgroundLighterBrush}" /> + <Setter Property="Width" Value="100" /> + <Setter Property="Height" Value="100" /> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type local:ProgressRingDouble}"> + <Grid> + <local:ProgressRing Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Foreground="{TemplateBinding Background}" Thickness="{TemplateBinding Thickness}" Minimum="0" Maximum="100" Value="99.999999" IsIndeterminate="False" /> + <local:ProgressRing Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Foreground="{TemplateBinding Foreground}" Thickness="{TemplateBinding Thickness}" Minimum="{TemplateBinding Minimum}" Maximum="{TemplateBinding Maximum}" Value="{TemplateBinding Value}" IsIndeterminate="{TemplateBinding IsIndeterminate}" /> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + +</ResourceDictionary>
\ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml new file mode 100644 index 000000000..d0121afa5 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml @@ -0,0 +1,81 @@ +<UserControl x:Class="Tango.FSE.Common.Controls.RunningJobRingProgress" + 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:behaviors="clr-namespace:Tango.FSE.Common.Behaviors" + xmlns:local="clr-namespace:Tango.FSE.Common.Controls" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" + mc:Ignorable="d" + d:DesignHeight="450" d:DesignWidth="450" x:Name="control"> + <Grid Opacity="0.7"> + <Viewbox> + <Grid> + <local:ProgressRingDouble Width="250" Height="250" Thickness="10" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}"> + <ProgressBar.Style> + <Style TargetType="local:ProgressRingDouble" BasedOn="{StaticResource {x:Type local:ProgressRingDouble}}"> + <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryAccentBrush}"></Setter> + <Setter Property="IsIndeterminate" Value="False"></Setter> + <Setter Property="Maximum" Value="{Binding ElementName=control,Path=RunningJobStatus.TotalProgressMinusSettingUp}"></Setter> + <Setter Property="Value" Value="{Binding ElementName=control,Path=RunningJobStatus.ProgressMinusSettingUp}"></Setter> + <Style.Triggers> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding ElementName=control,Path=IsRunning}" Value="True" /> + <Condition Binding="{Binding ElementName=control,Path=RunningJobStatus.IsSettingUp}" Value="True" /> + </MultiDataTrigger.Conditions> + <Setter Property="IsIndeterminate" Value="True"></Setter> + </MultiDataTrigger> + <DataTrigger Binding="{Binding ElementName=control,Path=RunningJobStatus.IsCompleted}" Value="True"> + <!--<Setter Property="Foreground" Value="{StaticResource FSE_SuccessBrush}"></Setter>--> + <Setter Property="Maximum" Value="100"></Setter> + <Setter Property="Value" Value="99.99999"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding ElementName=control,Path=RunningJobStatus.IsCanceled}" Value="True"> + <Setter Property="Foreground" Value="{StaticResource FSE_WarningBrush}"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding ElementName=control,Path=RunningJobStatus.IsFailed}" Value="True"> + <Setter Property="Foreground" Value="{StaticResource FSE_ErrorBrush}"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </ProgressBar.Style> + </local:ProgressRingDouble> + + <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center"> + + <StackPanel Visibility="{Binding ElementName=control,Path=RunningJobStatus.IsSettingUp,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> + <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> + <material:PackIcon Kind="DropOutline" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Completed</TextBlock> + </StackPanel> + + <TextBlock FontWeight="Light" FontSize="25" Margin="0 10 0 0" HorizontalAlignment="Center"> + <Run Text="{Binding ElementName=control,Path=RunningJobStatus.ProgressMinusSettingUp,StringFormat=0,FallbackValue=0}"></Run><Run Text="/" /><Run Text="{Binding RunningJobStatus.TotalProgressMinusSettingUp,StringFormat=0,FallbackValue=0}"/> + <Run FontSize="16">m</Run> + </TextBlock> + </StackPanel> + + <StackPanel Height="90" Visibility="{Binding ElementName=control,Path=RunningJobStatus.IsSettingUp,Converter={StaticResource BooleanToVisibilityConverter}}"> + <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> + <material:PackIcon Kind="DropOutline" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Visibility="{Binding ElementName=control,Path=IsRunning,Converter={StaticResource BooleanToVisibilityConverter}}">Getting ready...</TextBlock> + </StackPanel> + </StackPanel> + + <Rectangle Margin="0 10 0 0" Width="210" Stroke="{StaticResource FSE_PrimaryBackgroundLightBrush}" /> + + <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0 15 0 0"> + <material:PackIcon Kind="ClockOutline" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" >Time Left</TextBlock> + </StackPanel> + + <TextBlock FontWeight="Light" FontSize="25" Margin="0 10 0 0" HorizontalAlignment="Center"> + <Run Text="{Binding ElementName=control,Path=RunningJobStatus.RemainingTime,Converter={StaticResource TimeSpanToTwoDigitsTimeConverter},FallbackValue=5}"></Run> + <Run FontSize="16" Text="{Binding ElementName=control,Path=RunningJobStatus.RemainingTime,Converter={StaticResource TimeSpanToLabelConverter},FallbackValue=min}"></Run> + </TextBlock> + </StackPanel> + </Grid> + </Viewbox> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml.cs new file mode 100644 index 000000000..5e0f28419 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Tango.Integration.Operation; + +namespace Tango.FSE.Common.Controls +{ + /// <summary> + /// Interaction logic for RunningJobRingProgress.xaml + /// </summary> + public partial class RunningJobRingProgress : UserControl + { + /// <summary> + /// Gets or sets the running job status. + /// </summary> + public RunningJobStatus RunningJobStatus + { + get { return (RunningJobStatus)GetValue(RunningJobStatusProperty); } + set { SetValue(RunningJobStatusProperty, value); } + } + public static readonly DependencyProperty RunningJobStatusProperty = + DependencyProperty.Register("RunningJobStatus", typeof(RunningJobStatus), typeof(RunningJobRingProgress), new PropertyMetadata(null)); + + public bool IsRunning + { + get { return (bool)GetValue(IsRunningProperty); } + set { SetValue(IsRunningProperty, value); } + } + public static readonly DependencyProperty IsRunningProperty = + DependencyProperty.Register("IsRunning", typeof(bool), typeof(RunningJobRingProgress), new PropertyMetadata(false)); + + + + public RunningJobRingProgress() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml new file mode 100644 index 000000000..427a04c64 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml @@ -0,0 +1,225 @@ +<UserControl x:Class="Tango.FSE.Common.Controls.RunningJobViewer" + 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:enumerations="clr-namespace:Tango.BL.Enumerations;assembly=Tango.BL" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:local="clr-namespace:Tango.FSE.Common.Controls" + mc:Ignorable="d" + d:DesignHeight="120" d:DesignWidth="800"> + + <DockPanel> + <Canvas Height="50" Margin="5 0" DockPanel.Dock="Top"> + <StackPanel> + <StackPanel.Style> + <Style TargetType="StackPanel"> + <Setter Property="Canvas.Left"> + <Setter.Value> + <MultiBinding Converter="{StaticResource JobProgressToPositionConverter}"> + <Binding RelativeSource="{RelativeSource AncestorType=local:RunningJobViewer}" Path="RunningJobStatus.CurrentUnitProgress" /> + <Binding RelativeSource="{RelativeSource AncestorType=local:RunningJobViewer}" Path="RunningJobStatus.CurrentUnitTotalProgress" /> + <Binding RelativeSource="{RelativeSource AncestorType=Canvas}" Path="ActualWidth" /> + </MultiBinding> + </Setter.Value> + </Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=RunningJobStatus.IsSettingUp}" Value="True"> + <Setter Property="Canvas.Left" Value="0"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </StackPanel.Style> + <StackPanel Margin="-50 0 0 0"> + <ContentControl> + <ContentControl.Style> + <Style TargetType="ContentControl"> + <Setter Property="Content"> + <Setter.Value> + <StackPanel> + <TextBlock HorizontalAlignment="Center" FontSize="{StaticResource FSE_LargeFontSize}"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Setter Property="Text" Value="ready"></Setter> + <Style.Triggers> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=RunningJobStatus.IsSettingUp}" Value="True" /> + <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=IsRunning}" Value="True" /> + </MultiDataTrigger.Conditions> + <Setter Property="Text" Value="getting ready"></Setter> + </MultiDataTrigger> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=RunningJobStatus.IsSettingUp}" Value="False" /> + <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=IsRunning}" Value="True" /> + </MultiDataTrigger.Conditions> + <Setter Property="Text" Value="now dyeing"></Setter> + </MultiDataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + </TextBlock> + <material:PackIcon RenderTransformOrigin="0.5,0.5" Margin="0 8 0 0" HorizontalAlignment="Center" Kind="Water" Foreground="{StaticResource FSE_PrimaryAccentBrush}" Width="40" Height="40"> + <material:PackIcon.RenderTransform> + <RotateTransform Angle="180" /> + </material:PackIcon.RenderTransform> + </material:PackIcon> + </StackPanel> + </Setter.Value> + </Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=RunningJobStatus.IsCanceled}" Value="True"> + <Setter Property="Content"> + <Setter.Value> + <StackPanel> + <TextBlock HorizontalAlignment="Center" FontSize="{StaticResource FSE_LargeFontSize}">job canceled</TextBlock> + <material:PackIcon Margin="0 8 0 0" HorizontalAlignment="Center" Kind="Alert" Foreground="{StaticResource FSE_WarningBrush}" Width="40" Height="40" /> + </StackPanel> + </Setter.Value> + </Setter> + </DataTrigger> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=RunningJobStatus.IsFailed}" Value="True"> + <Setter Property="Content"> + <Setter.Value> + <StackPanel> + <TextBlock HorizontalAlignment="Center" FontSize="{StaticResource FSE_LargeFontSize}">job failed</TextBlock> + <material:PackIcon Margin="0 8 0 0" HorizontalAlignment="Center" Kind="AlertOctagon" Foreground="{StaticResource FSE_ErrorBrush}" Width="40" Height="40" /> + </StackPanel> + </Setter.Value> + </Setter> + </DataTrigger> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=RunningJobStatus.IsCompleted}" Value="True"> + <Setter Property="Content"> + <Setter.Value> + <StackPanel> + <TextBlock HorizontalAlignment="Center" FontSize="{StaticResource FSE_LargeFontSize}">job completed</TextBlock> + <material:PackIcon Margin="0 8 0 0" HorizontalAlignment="Center" Kind="Check" Foreground="{StaticResource FSE_SuccessBrush}" Width="40" Height="40" /> + </StackPanel> + </Setter.Value> + </Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </ContentControl.Style> + </ContentControl> + </StackPanel> + </StackPanel> + </Canvas> + <Grid> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="1*"/> + <ColumnDefinition Width="Auto"/> + </Grid.ColumnDefinitions> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition Height="1*" /> + </Grid.RowDefinitions> + + <ItemsControl ClipToBounds="False" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=RunningJobStatus.CurrentUnitSegments}" Visibility="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DisplayMarkers,Converter={StaticResource BooleanToVisibilityConverter}}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel Orientation="Horizontal" ClipToBounds="False"></StackPanel> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Grid> + <Grid.Width> + <MultiBinding Converter="{StaticResource SegmentLengthToWidthConverter}"> + <Binding RelativeSource="{RelativeSource AncestorType=UserControl}" Path="RunningJobStatus.CurrentUnitTotalProgress"></Binding> + <Binding RelativeSource="{RelativeSource AncestorType=ItemsControl}" Path="ActualWidth"></Binding> + <Binding Path="LengthWithFactor"></Binding> + </MultiBinding> + </Grid.Width> + + <TextBlock HorizontalAlignment="Center" FontSize="{StaticResource FSE_SmallFontSize}"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Setter Property="Visibility" Value="Visible"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Grid},Path=ActualWidth,Converter={StaticResource SmallerThanToBooleanConverter},ConverterParameter=20}" Value="True"> + <Setter Property="Visibility" Value="Collapsed"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + <Run Text="{Binding LengthWithFactor,Mode=OneWay,StringFormat=N0}"></Run><Run Text="m"></Run> + </TextBlock> + </Grid> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + + <Border Grid.Row="1" x:Name="brush_border" ClipToBounds="False" CornerRadius="10" Margin="0 5 0 0"> + <Border.Background> + <ImageBrush ImageSource="../Images/transparent_small.jpg" Stretch="None" TileMode="Tile" AlignmentX="Left" ViewportUnits="Absolute" Viewport="0,0,94,30" /> + </Border.Background> + <Border.Clip> + <RectangleGeometry RadiusX="10" RadiusY="10"> + <RectangleGeometry.Rect> + <MultiBinding Converter="{StaticResource WidthHeightToRectConverter}"> + <Binding ElementName="brush_border" Path="ActualWidth" /> + <Binding ElementName="brush_border" Path="ActualHeight" /> + </MultiBinding> + </RectangleGeometry.Rect> + </RectangleGeometry> + </Border.Clip> + <Grid> + <ItemsControl ClipToBounds="False" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=RunningJobStatus.CurrentUnitSegments}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel Orientation="Horizontal" ClipToBounds="False"></StackPanel> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Grid> + <Grid.Width> + <MultiBinding Converter="{StaticResource SegmentLengthToWidthConverter}"> + <Binding RelativeSource="{RelativeSource AncestorType=UserControl}" Path="RunningJobStatus.CurrentUnitTotalProgress"></Binding> + <Binding RelativeSource="{RelativeSource AncestorType=ItemsControl}" Path="ActualWidth"></Binding> + <Binding Path="LengthWithFactor"></Binding> + </MultiBinding> + </Grid.Width> + <Rectangle Fill="{Binding SegmentBrush}"></Rectangle> + </Grid> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + + <Rectangle Stroke="{StaticResource FSE_PrimaryBackgroundLightBrush}" StrokeThickness="1" RadiusX="8" RadiusY="8" /> + </Grid> + </Border> + </Grid> + + <Grid Grid.Column="1" VerticalAlignment="Bottom"> + <Grid.Style> + <Style TargetType="Grid"> + <Setter Property="Visibility" Value="Collapsed"></Setter> + <Style.Triggers> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=Job.JobType}" Value="{x:Static enumerations:JobTypes.Embroidery}" /> + <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=IsActive}" Value="False" /> + </MultiDataTrigger.Conditions> + <Setter Property="Visibility" Value="Visible"></Setter> + </MultiDataTrigger> + </Style.Triggers> + </Style> + </Grid.Style> + + <TextBlock Margin="10 0 0 -2" VerticalAlignment="Center"> + <Run Text="x"></Run><Run Text="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=Job.NumberOfUnits}"></Run> + </TextBlock> + </Grid> + </Grid> + + <TextBlock Margin="0 0 -30 -18" VerticalAlignment="Center" FontSize="{StaticResource FSE_LargeFontSize}" HorizontalAlignment="Right"> + <Run Text="x"></Run><Run Text="{Binding RelativeSource={RelativeSource AncestorType=local:RunningJobViewer},Path=RunningJobStatus.RemainingUnits}"></Run> + </TextBlock> + </Grid> + </DockPanel> +</UserControl> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml.cs new file mode 100644 index 000000000..4a970ffda --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Tango.BL.Entities; +using Tango.Integration.Operation; + +namespace Tango.FSE.Common.Controls +{ + /// <summary> + /// Interaction logic for RunningJobViewer.xaml + /// </summary> + public partial class RunningJobViewer : UserControl + { + /// <summary> + /// Maybe not necessary! + /// </summary> + public bool IsActive + { + get { return (bool)GetValue(IsActiveProperty); } + set { SetValue(IsActiveProperty, value); } + } + public static readonly DependencyProperty IsActiveProperty = + DependencyProperty.Register("IsActive", typeof(bool), typeof(RunningJobViewer), new PropertyMetadata(false)); + + /// <summary> + /// Gets or sets a value indicating whether summary markers. + /// </summary> + public bool DisplayMarkers + { + get { return (bool)GetValue(DisplayMarkersProperty); } + set { SetValue(DisplayMarkersProperty, value); } + } + public static readonly DependencyProperty DisplayMarkersProperty = + DependencyProperty.Register("DisplayMarkers", typeof(bool), typeof(RunningJobViewer), new PropertyMetadata(true)); + + /// <summary> + /// Gets or sets the job. + /// </summary> + public Job Job + { + get { return (Job)GetValue(JobProperty); } + set { SetValue(JobProperty, value); } + } + public static readonly DependencyProperty JobProperty = + DependencyProperty.Register("Job", typeof(Job), typeof(RunningJobViewer), new PropertyMetadata(null)); + + /// <summary> + /// Gets or sets the running job status. + /// </summary> + public RunningJobStatus RunningJobStatus + { + get { return (RunningJobStatus)GetValue(RunningJobStatusProperty); } + set { SetValue(RunningJobStatusProperty, value); } + } + public static readonly DependencyProperty RunningJobStatusProperty = + DependencyProperty.Register("RunningJobStatus", typeof(RunningJobStatus), typeof(RunningJobViewer), new PropertyMetadata(null)); + + public bool IsRunning + { + get { return (bool)GetValue(IsRunningProperty); } + set { SetValue(IsRunningProperty, value); } + } + public static readonly DependencyProperty IsRunningProperty = + DependencyProperty.Register("IsRunning", typeof(bool), typeof(RunningJobViewer), new PropertyMetadata(false)); + + + + public RunningJobViewer() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Converters/JobProgressToPositionConverter.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Converters/JobProgressToPositionConverter.cs new file mode 100644 index 000000000..12f0c30db --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Converters/JobProgressToPositionConverter.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; + +namespace Tango.FSE.Common.Converters +{ + /// <summary> + /// Converts a job progress to X position using the specified UI element width. + /// </summary> + /// <seealso cref="System.Windows.Data.IMultiValueConverter" /> + public class JobProgressToPositionConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length == 3 && values[1] != DependencyProperty.UnsetValue) + { + double progress = (double)values[0]; + double total = (double)values[1]; + double ui_width = (double)values[2]; + return (progress / total) * ui_width; + } + + return 0d; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/DashboardTile.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/DashboardTile.cs index f3c8412c2..9d8b3b24e 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/DashboardTile.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/DashboardTile.cs @@ -15,6 +15,7 @@ namespace Tango.FSE.Common public bool AutoContainerStyle { get; set; } = true; public bool AutoTitleStyle { get; set; } = true; public Dock AutoTitleAlignment { get; set; } = Dock.Left; + public double AutoTitleLineOffset { get; set; } = 30; public int Column { get; set; } public int Row { get; set; } public int ColumnSpan { get; set; } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/ExtensionMethods/ViewModelExtensionMethods.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/ExtensionMethods/ViewModelExtensionMethods.cs index 73ecd990b..d4f8fdfaa 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/ExtensionMethods/ViewModelExtensionMethods.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/ExtensionMethods/ViewModelExtensionMethods.cs @@ -35,14 +35,25 @@ public static class ViewModelExtensionMethods /// <param name="propertyName">The property name.</param> public static void SetFocus(this ViewModel vm, string propertyName) { - Application.Current.Dispatcher.BeginInvoke(new Action(() => + Application.Current.Dispatcher.BeginInvoke(new Action(async () => { - var element = FindElementByPropertyName(vm, Application.Current.MainWindow, propertyName); + await Task.Delay(200); - if (element != null) + var control = GetUserControl(vm, Application.Current.MainWindow); + + if (control != null) { - element.Focusable = true; - Keyboard.Focus(element); + var element = FindElementByPropertyName(vm, control, propertyName); + + if (element != null) + { + element.Focusable = true; + Keyboard.Focus(element); + } + else + { + Debug.WriteLine($"SetFocus: {propertyName} not found!"); + } } else { @@ -52,7 +63,31 @@ public static class ViewModelExtensionMethods }), DispatcherPriority.ApplicationIdle); } - private static FrameworkElement FindElementByPropertyName(ViewModel vm, UIElement parent, string propName) + private static UserControl GetUserControl(ViewModel vm, FrameworkElement parent) + { + var children = parent.FindVisualChildren<UserControl>(); + + foreach (var child in children) + { + if (child.DataContext == vm) + { + return child; + } + else + { + var innerChild = GetUserControl(vm, child); + + if (innerChild != null) + { + return innerChild; + } + } + } + + return null; + } + + private static FrameworkElement FindElementByPropertyName(ViewModel vm, FrameworkElement parent, string propName) { FrameworkElement foundChild = null; diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs index 4cebdef59..dbded7041 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs @@ -40,6 +40,7 @@ using Tango.FSE.Common.Firmware; using Tango.FSE.Common.Threading; using Tango.FSE.Common.Events; using Tango.FSE.Common.Tiles; +using Tango.FSE.Common.RemoteJob; namespace Tango.FSE.Common { @@ -178,6 +179,12 @@ namespace Tango.FSE.Common public IEventsProvider EventsProvider { get; set; } /// <summary> + /// Gets or sets the remote job provider. + /// </summary> + [TangoInject] + public IRemoteJobProvider RemoteJobProvider { get; set; } + + /// <summary> /// Gets or sets the dashboard manager. /// </summary> [TangoInject] diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Graphs/RealTimeGraph.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Graphs/RealTimeGraph.xaml index 44bbad085..b2a61518f 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Graphs/RealTimeGraph.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Graphs/RealTimeGraph.xaml @@ -89,7 +89,7 @@ <Viewbox IsHitTestVisible="False" Stretch="Uniform" Margin="{TemplateBinding CurrentValueMargin}" Visibility="{TemplateBinding CurrentValueVisibility}"> <Grid Width="200" Height="200"> - <Ellipse Stroke="#38FFFFFF" StrokeThickness="20" /> + <!--<Ellipse Stroke="#38FFFFFF" StrokeThickness="20" />--> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBlock Opacity="0.8" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="SemiBold" FontSize="{TemplateBinding CurrentValueFontSize}" Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=Controller.DataSeriesCollection[0].CurrentValue}"></TextBlock> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/transparent_small.jpg b/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/transparent_small.jpg Binary files differnew file mode 100644 index 000000000..c682a4c7e --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/transparent_small.jpg diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/IRemoteJobProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/IRemoteJobProvider.cs new file mode 100644 index 000000000..65299eac9 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/IRemoteJobProvider.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.FSE.Common.RemoteJob +{ + public interface IRemoteJobProvider : INotifyApplicationStarted + { + event EventHandler<RemoteJobStartedEventArgs> RemoteJobStarted; + event EventHandler<RemoteJobStoppedEventArgs> RemoteJobStopped; + + bool IsRemoteJobRunning { get; } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobProgressEventArgs.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobProgressEventArgs.cs new file mode 100644 index 000000000..039bcfd15 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobProgressEventArgs.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Shared.Jobs; + +namespace Tango.FSE.Common.RemoteJob +{ + public class RemoteJobProgressEventArgs : EventArgs + { + public RemoteJobProgress Progress { get; set; } + + public RemoteJobProgressEventArgs() + { + Progress = new RemoteJobProgress(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStartedEventArgs.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStartedEventArgs.cs new file mode 100644 index 000000000..001263044 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStartedEventArgs.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Integration.Operation; + +namespace Tango.FSE.Common.RemoteJob +{ + public class RemoteJobStartedEventArgs : EventArgs + { + public JobHandler JobHandler { get; set; } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStoppedEventArgs.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStoppedEventArgs.cs new file mode 100644 index 000000000..ed71555d7 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStoppedEventArgs.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Shared.Jobs; + +namespace Tango.FSE.Common.RemoteJob +{ + public class RemoteJobStoppedEventArgs : EventArgs + { + + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml index 5bfc5cc2b..792826d31 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml @@ -4,6 +4,7 @@ <!--COLORS--> <Color x:Key="FSE_PrimaryBackgroundDarkColor">#202020</Color> + <Color x:Key="FSE_PrimaryBackgroundMidColor">#262626</Color> <Color x:Key="FSE_PrimaryBackgroundColor">#303030</Color> <Color x:Key="FSE_PrimaryBackgroundLightColor">#404040</Color> <Color x:Key="FSE_PrimaryBackgroundLighterColor">#505050</Color> @@ -46,6 +47,7 @@ <!--BRUSHES--> <SolidColorBrush x:Key="FSE_PrimaryBackgroundDarkBrush" Color="{StaticResource FSE_PrimaryBackgroundDarkColor}"></SolidColorBrush> + <SolidColorBrush x:Key="FSE_PrimaryBackgroundMidBrush" Color="{StaticResource FSE_PrimaryBackgroundMidColor}"></SolidColorBrush> <SolidColorBrush x:Key="FSE_PrimaryBackgroundBrush" Color="{StaticResource FSE_PrimaryBackgroundColor}"></SolidColorBrush> <SolidColorBrush x:Key="FSE_PrimaryBackgroundLightBrush" Color="{StaticResource FSE_PrimaryBackgroundLightColor}"></SolidColorBrush> <SolidColorBrush x:Key="FSE_PrimaryBackgroundLighterBrush" Color="{StaticResource FSE_PrimaryBackgroundLighterColor}"></SolidColorBrush> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml index 420af935c..99aeb7bf3 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml @@ -9,6 +9,8 @@ <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/FSEPanel.xaml" /> <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/ToggleIconButton.xaml" /> <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/FileSystemControl.xaml" /> + <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/ProgressRing.xaml" /> + <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/ProgressRingDouble.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary>
\ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml index c09ca61c2..019206d15 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml @@ -42,4 +42,5 @@ <converters:IsEqualToVisibilityConverter x:Key="IsEqualToVisibilityConverter" /> <localConverters:DateTimeUtcHumanizeConverter x:Key="DateTimeUtcHumanizeConverter" /> <localConverters:TimeSpanHumanizeConverter x:Key="TimeSpanHumanizeConverter" /> + <localConverters:JobProgressToPositionConverter x:Key="JobProgressToPositionConverter" /> </ResourceDictionary>
\ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj index 86f163582..0d89c64ba 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj @@ -100,6 +100,8 @@ <Compile Include="Authentication\AuthenticationResult.cs" /> <Compile Include="Authentication\IAuthenticationProvider.cs" /> <Compile Include="AutoComplete\AutoCompleteSource.cs" /> + <Compile Include="Behaviors\CircularProgressBarBehavior.cs" /> + <Compile Include="Behaviors\StyleBehavior.cs" /> <Compile Include="BugReporting\Bug.cs" /> <Compile Include="BugReporting\BugType.cs" /> <Compile Include="BugReporting\IBugReporter.cs" /> @@ -121,10 +123,19 @@ <Compile Include="Controls\MachineView.xaml.cs"> <DependentUpon>MachineView.xaml</DependentUpon> </Compile> + <Compile Include="Controls\ProgressRing.cs" /> + <Compile Include="Controls\ProgressRingDouble.cs" /> + <Compile Include="Controls\RunningJobRingProgress.xaml.cs"> + <DependentUpon>RunningJobRingProgress.xaml</DependentUpon> + </Compile> + <Compile Include="Controls\RunningJobViewer.xaml.cs"> + <DependentUpon>RunningJobViewer.xaml</DependentUpon> + </Compile> <Compile Include="Controls\TextIconButton.cs" /> <Compile Include="Controls\ToggleIconButton.cs" /> <Compile Include="Converters\DateTimeUtcHumanizeConverter.cs" /> <Compile Include="Converters\DoubleToChartValuesConverter.cs" /> + <Compile Include="Converters\JobProgressToPositionConverter.cs" /> <Compile Include="Converters\TimeSpanHumanizeConverter.cs" /> <Compile Include="Core\FSEProgress.cs" /> <Compile Include="DashboardTile.cs" /> @@ -194,6 +205,10 @@ <Compile Include="Resolution\IResolutionService.cs" /> <Compile Include="Resolution\ResolutionHelper.cs" /> <Compile Include="Resolution\ResolutionMode.cs" /> + <Compile Include="RemoteJob\IRemoteJobProvider.cs" /> + <Compile Include="RemoteJob\RemoteJobProgressEventArgs.cs" /> + <Compile Include="RemoteJob\RemoteJobStartedEventArgs.cs" /> + <Compile Include="RemoteJob\RemoteJobStoppedEventArgs.cs" /> <Compile Include="Storage\IStorageProvider.cs" /> <Compile Include="Storage\IStorageResult.cs" /> <Compile Include="Storage\SingleStorageResult.cs" /> @@ -231,6 +246,22 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </Page> + <Page Include="Controls\ProgressRing.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Controls\ProgressRingDouble.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Controls\RunningJobRingProgress.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Controls\RunningJobViewer.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Controls\TextIconButton.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -463,6 +494,9 @@ <Resource Include="Images\tank.png" /> <Resource Include="Images\ti-tm4c129x.png" /> </ItemGroup> + <ItemGroup> + <Resource Include="Images\transparent_small.jpg" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <PropertyGroup> <PreBuildEvent> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Images/Abstracts/lines_gray.png b/Software/Visual_Studio/FSE/Tango.FSE.UI/Images/Abstracts/lines_gray.png Binary files differnew file mode 100644 index 000000000..3f2e42054 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Images/Abstracts/lines_gray.png diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteJob/DefaultRemoteJobProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteJob/DefaultRemoteJobProvider.cs new file mode 100644 index 000000000..586bf2105 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteJob/DefaultRemoteJobProvider.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.DI; +using Tango.FSE.Common.Connection; +using Tango.FSE.Common.Notifications; +using Tango.FSE.Common.RemoteJob; +using Tango.Integration.Operation; +using Tango.PPC.Shared.Jobs; +using Tango.Transport; + +namespace Tango.FSE.UI.RemoteJob +{ + [TangoCreateWhenRegistered] + public class DefaultRemoteJobProvider : IRemoteJobProvider + { + private JobHandler _handler; + + public event EventHandler<RemoteJobStartedEventArgs> RemoteJobStarted; + public event EventHandler<RemoteJobStoppedEventArgs> RemoteJobStopped; + + public bool IsRemoteJobRunning { get; private set; } + + [TangoInject] + private IMachineProvider MachineProvider { get; set; } + + [TangoInject] + private INotificationProvider NotificationProvider { get; set; } + + public void OnApplicationStarted() + { + MachineProvider.MachineConnected += MachineProvider_MachineConnected; + } + + private void MachineProvider_MachineConnected(object sender, MachineConnectedEventArgs e) + { + init(); + } + + private void init() + { + try + { + MachineProvider.MachineOperator.SendGenericContinuousRequest<RemoteJobUpdateRequest, RemoteJobUpdateResponse>(new RemoteJobUpdateRequest() + { + //Request + }, new TransportContinuousRequestConfig() + { + Timeout = TimeSpan.FromSeconds(30) + }).Subscribe((response) => + { + //Response + InvalidateJobResponse(response); + }, (ex) => + { + //Failed + NotificationProvider.PushErrorReportingSnackbar(ex, "Remote Job Module Error", "Remote job display failed to initialize."); + }, () => + { + //Completed ? (never) + }); + } + catch (Exception ex) + { + NotificationProvider.PushErrorReportingSnackbar(ex, "Remote Job Module Error", "Remote job display failed to initialize."); + } + } + + private void InvalidateJobResponse(RemoteJobUpdateResponse response) + { + var stage = response.Progress.Stage; + + if (stage == RemoteJobStage.None) + { + return; + } + + if (stage == RemoteJobStage.Started && !IsRemoteJobRunning) + { + _handler = new JobHandler(() => { }, response.Job.ToObservable(), null, response.ProcessParameters.ToObservable(), JobHandlerModes.SettingUp); + + IsRemoteJobRunning = true; + RemoteJobStarted?.Invoke(this, new RemoteJobStartedEventArgs() + { + JobHandler = _handler + }); + + return; + } + + if (_handler != null) + { + if (response.Progress.JobStatus != null) + { + _handler.RaiseStatusReceived(response.Progress.JobStatus); + } + + if (stage == RemoteJobStage.Failed && IsRemoteJobRunning) + { + IsRemoteJobRunning = false; + _handler.RaiseFailed(new Exception("Job failed")); + _handler = null; + } + else if (stage == RemoteJobStage.Aborted && IsRemoteJobRunning) + { + IsRemoteJobRunning = false; + _handler.RaiseCanceled(); + _handler = null; + } + else if (stage == RemoteJobStage.Completed && IsRemoteJobRunning) + { + IsRemoteJobRunning = false; + RemoteJobStopped?.Invoke(this, new RemoteJobStoppedEventArgs()); + _handler.RaiseCompleted(); + _handler = null; + } + } + } + + public void OnApplicationReady() + { + //Do Nothing. + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj index 933863104..a15d7cfda 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj @@ -285,6 +285,7 @@ <Compile Include="RemoteDesktop\DefaultRemoteDesktopProvider.cs" /> <Compile Include="RemoteUpgrade\DefaultRemoteUpgradeManager.cs" /> <Compile Include="Resolution\DefaultResolutionService.cs" /> + <Compile Include="RemoteJob\DefaultRemoteJobProvider.cs" /> <Compile Include="Storage\DefaultStorageProvider.cs" /> <Compile Include="Storage\ExplorerControlDialog.xaml.cs"> <DependentUpon>ExplorerControlDialog.xaml</DependentUpon> @@ -302,19 +303,27 @@ <Compile Include="Tiles\Events\EventsTileView.xaml.cs"> <DependentUpon>EventsTileView.xaml</DependentUpon> </Compile> - <Compile Include="Tiles\Events\EventsTileViewVM.cs" /> + <Compile Include="Tiles\Events\EventsTile.cs" /> <Compile Include="Tiles\Machine\MachineTileView.xaml.cs"> <DependentUpon>MachineTileView.xaml</DependentUpon> </Compile> - <Compile Include="Tiles\Machine\MachineTileViewVM.cs" /> + <Compile Include="Tiles\Machine\MachineTile.cs" /> <Compile Include="Tiles\MidTankLevels\MidTankLevelsTileView.xaml.cs"> <DependentUpon>MidTankLevelsTileView.xaml</DependentUpon> </Compile> - <Compile Include="Tiles\MidTankLevels\MidTankLevelsTileViewVM.cs" /> + <Compile Include="Tiles\MidTankLevels\MidTankLevelsTile.cs" /> <Compile Include="Tiles\OverallTemperature\OverallTemperatureTileView.xaml.cs"> <DependentUpon>OverallTemperatureTileView.xaml</DependentUpon> </Compile> - <Compile Include="Tiles\OverallTemperature\OverallTemperatureTileViewVM.cs" /> + <Compile Include="Tiles\OverallTemperature\OverallTemperatureTile.cs" /> + <Compile Include="Tiles\RemoteJob\RemoteJobProgressRingTileView.xaml.cs"> + <DependentUpon>RemoteJobProgressRingTileView.xaml</DependentUpon> + </Compile> + <Compile Include="Tiles\RemoteJob\RemoteJobProgressRingTile.cs" /> + <Compile Include="Tiles\RemoteJob\RemoteJobTileView.xaml.cs"> + <DependentUpon>RemoteJobTileView.xaml</DependentUpon> + </Compile> + <Compile Include="Tiles\RemoteJob\RemoteJobTile.cs" /> <Compile Include="Updates\DefaultUpdatesManager.cs" /> <Compile Include="ViewModelLocator.cs" /> <Compile Include="ViewModels\AccountViewVM.cs" /> @@ -429,6 +438,14 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Tiles\RemoteJob\RemoteJobProgressRingTileView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Tiles\RemoteJob\RemoteJobTileView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Views\EventsView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -718,7 +735,12 @@ <Resource Include="Images\l-full.png" /> <Resource Include="Images\lubricant2.png" /> </ItemGroup> - <ItemGroup /> + <ItemGroup> + <Folder Include="Tiles\QuickActions\" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Images\Abstracts\lines_gray.png" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <PropertyGroup> <PostBuildEvent>call "$(DevEnvDir)..\..\vc\vcvarsall.bat" x86 diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTile.cs index 0b9670a1d..9730acd32 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileViewVM.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTile.cs @@ -10,7 +10,7 @@ using Tango.FSE.Common; namespace Tango.FSE.UI.Tiles.Events { - public class EventsTileViewVM : DashboardTile + public class EventsTile : DashboardTile { private double _InfoEvents; public double InfoEvents @@ -47,7 +47,7 @@ namespace Tango.FSE.UI.Tiles.Events set { _canExecuteJob = value; RaisePropertyChangedAuto(); } } - public EventsTileViewVM() + public EventsTile() { Name = "Active Events"; AutoContainerStyle = false; diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileView.xaml index ee3857a97..14116ab91 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileView.xaml @@ -8,7 +8,7 @@ xmlns:resolution="clr-namespace:Tango.FSE.Common.Resolution;assembly=Tango.FSE.Common" xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:EventsTileViewVM, IsDesignTimeCreatable=False}"> + d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:EventsTile, IsDesignTimeCreatable=False}"> <Grid Opacity="0.6"> <StackPanel Margin="0 20 0 0"> <DockPanel Margin="0 10 0 0"> @@ -46,7 +46,7 @@ <material:PackIcon Kind="BellAlert" Foreground="{StaticResource FSE_CriticalBrush}" /> <TextBlock Margin="5 0 0 0" VerticalAlignment="Center"> <Run Text="{Binding CriticalEvents}"></Run> - <Run>critical errors</Run> + <Run>critical</Run> </TextBlock> </DockPanel> <DockPanel Margin="0 5"> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTile.cs index ffa8e586a..611c4d93e 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileViewVM.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTile.cs @@ -8,9 +8,9 @@ using Tango.FSE.Common; namespace Tango.FSE.UI.Tiles.Machine { - public class MachineTileViewVM : DashboardTile + public class MachineTile : DashboardTile { - public MachineTileViewVM() + public MachineTile() { Name = "Machine Configuration"; AutoContainerStyle = false; diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileView.xaml index f87541676..625f0df7d 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileView.xaml @@ -6,8 +6,8 @@ xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" xmlns:local="clr-namespace:Tango.FSE.UI.Tiles.Machine" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:MachineTileViewVM, IsDesignTimeCreatable=False}"> - <Grid> + d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:MachineTile, IsDesignTimeCreatable=False}"> + <Grid Margin="20"> <controls:MachineView Opacity="0.6" DataContext="{Binding MachineProvider.Machine}" /> </Grid> </UserControl> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTile.cs index c643bedf6..633a346e5 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileViewVM.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTile.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -16,7 +17,7 @@ using Tango.PMR.MachineStatus; namespace Tango.FSE.UI.Tiles.MidTankLevels { - public class MidTankLevelsTileViewVM : DashboardTile + public class MidTankLevelsTile : DashboardTile { public class MidTankLevelModel : ExtendedObject { @@ -49,7 +50,7 @@ namespace Tango.FSE.UI.Tiles.MidTankLevels set { _midTankLevels = value; RaisePropertyChangedAuto(); } } - public MidTankLevelsTileViewVM() + public MidTankLevelsTile() { Name = "Mid Tank Levels"; Column = 4; @@ -146,15 +147,22 @@ namespace Tango.FSE.UI.Tiles.MidTankLevels { if (IsVisible) { - foreach (var item in status.IDSPacksLevels) + try { - var model = MidTankLevels.SingleOrDefault(x => x.IDSPack.PackIndex == item.Index); - - if (model != null) + foreach (var item in status.IDSPacksLevels) { - model.Level = item.MidTankLevel; + var model = MidTankLevels.SingleOrDefault(x => x.IDSPack.PackIndex == item.Index); + + if (model != null) + { + model.Level = item.MidTankLevel; + } } } + catch + { + Debug.WriteLine("Error on update mid tank levels. (probably because of machine status arrived before machine connected event..)"); + } } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileView.xaml index 6409e6015..fa3a5f853 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileView.xaml @@ -8,7 +8,7 @@ xmlns:resolution="clr-namespace:Tango.FSE.Common.Resolution;assembly=Tango.FSE.Common" xmlns:localConverters="clr-namespace:Tango.FSE.UI.Converters" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:MidTankLevelsTileViewVM, IsDesignTimeCreatable=False}"> + d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:MidTankLevelsTile, IsDesignTimeCreatable=False}"> <UserControl.Resources> <localConverters:StringToFirstLetterConverter x:Key="StringToFirstLetterConverter" /> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTile.cs index 05709e648..82552f830 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileViewVM.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTile.cs @@ -14,11 +14,11 @@ using Tango.Integration.Operation; namespace Tango.FSE.UI.Tiles.OverallTemperature { - public class OverallTemperatureTileViewVM : DashboardTile + public class OverallTemperatureTile : DashboardTile { public WpfGraphController<DateTimeDataPoint, DoubleDataPoint> OverallTemperatureController { get; set; } - public OverallTemperatureTileViewVM() + public OverallTemperatureTile() { Name = "Overall Temperature"; Column = 4; diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileView.xaml index 5f9714c87..825f60ab9 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileView.xaml @@ -6,9 +6,9 @@ xmlns:local="clr-namespace:Tango.FSE.UI.Tiles.OverallTemperature" xmlns:graphs="clr-namespace:Tango.FSE.Common.Graphs;assembly=Tango.FSE.Common" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:OverallTemperatureTileViewVM, IsDesignTimeCreatable=False}"> + d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:OverallTemperatureTile, IsDesignTimeCreatable=False}"> <Grid> - <graphs:RealTimeGraph Opacity="1" CurrentValueFontSize="45" CurrentValueMargin="10" CurrentValueVisibility="Visible" Style="{StaticResource FSE_RealTimeGraph_Flat}" HorizontalAxisVisibility="Collapsed" VerticalAxisVisibility="Collapsed" GridLinesBrush="#252525" Controller="{Binding OverallTemperatureController}"> + <graphs:RealTimeGraph Opacity="0.8" CurrentValueFontSize="45" CurrentValueMargin="25" CurrentValueVisibility="Visible" Style="{StaticResource FSE_RealTimeGraph_Flat}" HorizontalAxisVisibility="Collapsed" VerticalAxisVisibility="Collapsed" GridLinesBrush="#303030" Foreground="{StaticResource FSE_PrimaryAccentBrush}" Controller="{Binding OverallTemperatureController}"> </graphs:RealTimeGraph> </Grid> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTile.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTile.cs new file mode 100644 index 000000000..f5519ec48 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTile.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Tango.FSE.Common; +using Tango.Integration.Operation; + +namespace Tango.FSE.UI.Tiles.RemoteJob +{ + public class RemoteJobProgressRingTile : RemoteJobTile + { + public RemoteJobProgressRingTile() : base() + { + Name = "Remote Job Timer"; + AutoContainerStyle = false; + AutoTitleStyle = false; + AutoTitleAlignment = System.Windows.Controls.Dock.Right; + Column = 4; + Row = 6; + ColumnSpan = 4; + RowSpan = 4; + AutoTitleLineOffset = 60; + RunningJobStatus.RemainingTime = TimeSpan.Zero; + } + + public override FrameworkElement GetView() + { + return new RemoteJobProgressRingTileView(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml new file mode 100644 index 000000000..62e7c4798 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml @@ -0,0 +1,14 @@ +<UserControl x:Class="Tango.FSE.UI.Tiles.RemoteJob.RemoteJobProgressRingTileView" + 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:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" + xmlns:local="clr-namespace:Tango.FSE.UI.Tiles.RemoteJob" + xmlns:fs="clr-namespace:Tango.SharedUI.Effects;assembly=Tango.SharedUI" + mc:Ignorable="d" + d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:RemoteJobProgressRingTile, IsDesignTimeCreatable=False}"> + <Grid Margin="30"> + <controls:RunningJobRingProgress RunningJobStatus="{Binding RunningJobStatus}" IsRunning="{Binding IsRunning}" /> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml.cs new file mode 100644 index 000000000..4279f51b8 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml.cs @@ -0,0 +1,28 @@ +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.FSE.UI.Tiles.RemoteJob +{ + /// <summary> + /// Interaction logic for RemoteJobProgressRingTileView.xaml + /// </summary> + public partial class RemoteJobProgressRingTileView : UserControl + { + public RemoteJobProgressRingTileView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTile.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTile.cs new file mode 100644 index 000000000..cb99ef6ca --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTile.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; +using Tango.BL.Entities; +using Tango.FSE.Common; +using Tango.Integration.Operation; +using Tango.PPC.Shared.Jobs; + +namespace Tango.FSE.UI.Tiles.RemoteJob +{ + public class RemoteJobTile : DashboardTile + { + private Job _job; + public Job Job + { + get { return _job; } + set { _job = value; RaisePropertyChangedAuto(); } + } + + private JobHandler _handler; + public JobHandler Handler + { + get { return _handler; } + set { _handler = value; RaisePropertyChangedAuto(); } + } + + private RunningJobStatus _runningJobStatus; + public RunningJobStatus RunningJobStatus + { + get { return _runningJobStatus; } + set { _runningJobStatus = value; RaisePropertyChangedAuto(); } + } + + private bool _isRunning; + public bool IsRunning + { + get { return _isRunning; } + set { _isRunning = value; RaisePropertyChangedAuto(); } + } + + public RemoteJobTile() + { + Name = "Remote Job"; + AutoTitleStyle = true; + AutoContainerStyle = false; + AutoTitleAlignment = System.Windows.Controls.Dock.Top; + Column = 0; + Row = 10; + ColumnSpan = 12; + RowSpan = 2; + + InitDemoJob(); + } + + private void InitDemoJob() + { + Job = new Job(); + Job.NumberOfUnits = 1; + Job.Name = "N/A"; + Job.AddSolidSegment(Color.FromRgb(70, 70, 70), 5); + Job.AddSolidSegment(Colors.Gray, 5); + Job.AddSolidSegment(Color.FromRgb(70, 70, 70), 5); + Job.AddSolidSegment(Colors.Gray, 5); + + Handler = new JobHandler(() => { }, Job, null, new ProcessParametersTable() { DyeingSpeed = 50 }, JobHandlerModes.SettingUp); + Handler.RaiseStatusReceived(new PMR.Printing.JobStatus() + { + Message = "Ready", + CurrentSegmentIndex = 0, + Progress = 0, + }); + + RunningJobStatus = Handler.Status; + } + + public override FrameworkElement GetView() + { + return new RemoteJobTileView(); + } + + public override void OnApplicationStarted() + { + base.OnApplicationStarted(); + + RemoteJobProvider.RemoteJobStarted += RemoteJobProvider_RemoteJobStarted; + RemoteJobProvider.RemoteJobStopped += RemoteJobProvider_RemoteJobStopped; + } + + private void RemoteJobProvider_RemoteJobStopped(object sender, Common.RemoteJob.RemoteJobStoppedEventArgs e) + { + IsRunning = false; + } + + private void RemoteJobProvider_RemoteJobStarted(object sender, Common.RemoteJob.RemoteJobStartedEventArgs e) + { + Handler = e.JobHandler; + Handler.StatusChanged += Handler_StatusChanged; + Job = e.JobHandler.Job; + IsRunning = true; + } + + private void Handler_StatusChanged(object sender, RunningJobStatus status) + { + RunningJobStatus = status; + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml new file mode 100644 index 000000000..ee05314ce --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml @@ -0,0 +1,17 @@ +<UserControl x:Class="Tango.FSE.UI.Tiles.RemoteJob.RemoteJobTileView" + 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:local="clr-namespace:Tango.FSE.UI.Tiles.RemoteJob" + xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" + mc:Ignorable="d" + d:DesignHeight="100" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:RemoteJobTile, IsDesignTimeCreatable=False}"> + <Grid TextElement.Foreground="{StaticResource FSE_PrimaryAccentBrush}"> + <Viewbox Width="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=ActualWidth}"> + <Border Background="#292929" CornerRadius="10" VerticalAlignment="Bottom" Padding="20 0" Width="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=ActualWidth}"> + <controls:RunningJobViewer IsRunning="{Binding IsRunning}" Job="{Binding Job}" RunningJobStatus="{Binding RunningJobStatus}" IsActive="True" Margin="30 10" Height="90" /> + </Border> + </Viewbox> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml.cs new file mode 100644 index 000000000..174fdfd01 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml.cs @@ -0,0 +1,28 @@ +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.FSE.UI.Tiles.RemoteJob +{ + /// <summary> + /// Interaction logic for RemoteJobTileView.xaml + /// </summary> + public partial class RemoteJobTileView : UserControl + { + public RemoteJobTileView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs index 04c298e5c..7f2c073f0 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs @@ -56,6 +56,8 @@ using Tango.FSE.Common.Updates; using Tango.FSE.UI.Updates; using Tango.FSE.Common.Tiles; using Tango.FSE.UI.Tiles; +using Tango.FSE.Common.RemoteJob; +using Tango.FSE.UI.RemoteJob; namespace Tango.FSE.UI { @@ -89,6 +91,7 @@ namespace Tango.FSE.UI TangoIOC.Default.Unregister<IEventsProvider>(); TangoIOC.Default.Unregister<IUpdatesManager>(); TangoIOC.Default.Unregister<IDashboardManager>(); + TangoIOC.Default.Unregister<IRemoteJobProvider>(); //TangoIOC.Default.Unregister<ExternalBridgeScanner>(); //TangoIOC.Default.Unregister<IDiagnosticsFrameProvider>(); //TangoIOC.Default.Unregister<IEventLogger>(); @@ -121,6 +124,7 @@ namespace Tango.FSE.UI TangoIOC.Default.Register<IFirmwareStorageProvider, DefaultFirmwareStorageProvider>(); TangoIOC.Default.Register<IEventsProvider, DefaultEventsProvider>(); TangoIOC.Default.Register<IUpdatesManager, DefaultUpdatesManager>(); + TangoIOC.Default.Register<IRemoteJobProvider, DefaultRemoteJobProvider>(); TangoIOC.Default.Register<IDashboardManager, DefaultDashboardManager>(); diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/DashboardViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/DashboardViewVM.cs index 5cee1e8f1..586d57c0a 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/DashboardViewVM.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/DashboardViewVM.cs @@ -21,10 +21,12 @@ namespace Tango.FSE.UI.ViewModels public override void OnApplicationStarted() { base.OnApplicationStarted(); - DashboardManager.Tiles.Add(new Tiles.Machine.MachineTileViewVM()); - DashboardManager.Tiles.Add(new Tiles.MidTankLevels.MidTankLevelsTileViewVM()); - DashboardManager.Tiles.Add(new Tiles.OverallTemperature.OverallTemperatureTileViewVM()); - DashboardManager.Tiles.Add(new Tiles.Events.EventsTileViewVM()); + DashboardManager.Tiles.Add(new Tiles.Machine.MachineTile()); + DashboardManager.Tiles.Add(new Tiles.MidTankLevels.MidTankLevelsTile()); + DashboardManager.Tiles.Add(new Tiles.OverallTemperature.OverallTemperatureTile()); + DashboardManager.Tiles.Add(new Tiles.Events.EventsTile()); + DashboardManager.Tiles.Add(new Tiles.RemoteJob.RemoteJobTile()); + DashboardManager.Tiles.Add(new Tiles.RemoteJob.RemoteJobProgressRingTile()); } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/DashboardView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/DashboardView.xaml index 35668a10a..3cfcd53d3 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/DashboardView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/DashboardView.xaml @@ -16,113 +16,123 @@ <localConverters:DashboardTileToViewConverter x:Key="DashboardTileToViewConverter" /> </UserControl.Resources> + <Grid> - <Grid Margin="20"> - <Grid.Style> - <Style TargetType="Grid"> - <Setter Property="Effect" Value="{x:Null}"></Setter> - <Style.Triggers> - <DataTrigger Binding="{Binding MachineProvider.IsConnected}" Value="False"> - <Setter Property="Effect"> - <Setter.Value> - <fx:DisplaySettingEffect SaturationLevel="0" /> - </Setter.Value> - </Setter> - </DataTrigger> - </Style.Triggers> - </Style> - </Grid.Style> - <ItemsControl ItemsSource="{Binding DashboardManager.Tiles}"> - <ItemsControl.ItemsPanel> - <ItemsPanelTemplate> - <Grid IsItemsHost="True"> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="1*" /> - <ColumnDefinition Width="1*" /> - <ColumnDefinition Width="1*" /> - <ColumnDefinition Width="1*" /> - <ColumnDefinition Width="1*" /> - <ColumnDefinition Width="1*" /> - <ColumnDefinition Width="1*" /> - <ColumnDefinition Width="1*" /> - <ColumnDefinition Width="1*" /> - <ColumnDefinition Width="1*" /> - <ColumnDefinition Width="1*" /> - <ColumnDefinition Width="1*" /> - </Grid.ColumnDefinitions> - <Grid.RowDefinitions> - <RowDefinition Height="1*" /> - <RowDefinition Height="1*" /> - <RowDefinition Height="1*" /> - <RowDefinition Height="1*" /> - <RowDefinition Height="1*" /> - <RowDefinition Height="1*" /> - <RowDefinition Height="1*" /> - <RowDefinition Height="1*" /> - <RowDefinition Height="1*" /> - <RowDefinition Height="1*" /> - <RowDefinition Height="1*" /> - <RowDefinition Height="1*" /> - </Grid.RowDefinitions> - </Grid> - </ItemsPanelTemplate> - </ItemsControl.ItemsPanel> - <ItemsControl.ItemContainerStyle> - <Style TargetType="FrameworkElement"> - <Setter Property="Grid.Column" Value="{Binding Column}"></Setter> - <Setter Property="Grid.Row" Value="{Binding Row}"></Setter> - <Setter Property="Grid.ColumnSpan" Value="{Binding ColumnSpan}"></Setter> - <Setter Property="Grid.RowSpan" Value="{Binding RowSpan}"></Setter> - <Setter Property="Margin" Value="10"></Setter> + <Image Source="/Images/Abstracts/lines_gray.png" Stretch="Fill" RenderOptions.BitmapScalingMode="Fant" Opacity="0.05" /> + + <Grid Margin="20"> + <Grid.Style> + <Style TargetType="Grid"> + <Setter Property="Effect" Value="{x:Null}"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding MachineProvider.IsConnected}" Value="False"> + <Setter Property="Effect"> + <Setter.Value> + <fx:DisplaySettingEffect SaturationLevel="0" /> + </Setter.Value> + </Setter> + </DataTrigger> + </Style.Triggers> </Style> - </ItemsControl.ItemContainerStyle> - <ItemsControl.ItemTemplate> - <DataTemplate> - <DockPanel> - <Border CornerRadius="3 3 0 0" Visibility="{Binding AutoTitleStyle,Converter={StaticResource BooleanToVisibilityConverter}}" DockPanel.Dock="Top" Padding="8" BorderThickness="0 0 0 0"> + </Grid.Style> + <ItemsControl ItemsSource="{Binding DashboardManager.Tiles}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <Grid IsItemsHost="True"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="1*" /> + <ColumnDefinition Width="1*" /> + <ColumnDefinition Width="1*" /> + <ColumnDefinition Width="1*" /> + <ColumnDefinition Width="1*" /> + <ColumnDefinition Width="1*" /> + <ColumnDefinition Width="1*" /> + <ColumnDefinition Width="1*" /> + <ColumnDefinition Width="1*" /> + <ColumnDefinition Width="1*" /> + <ColumnDefinition Width="1*" /> + <ColumnDefinition Width="1*" /> + </Grid.ColumnDefinitions> + <Grid.RowDefinitions> + <RowDefinition Height="1*" /> + <RowDefinition Height="1*" /> + <RowDefinition Height="1*" /> + <RowDefinition Height="1*" /> + <RowDefinition Height="1*" /> + <RowDefinition Height="1*" /> + <RowDefinition Height="1*" /> + <RowDefinition Height="1*" /> + <RowDefinition Height="1*" /> + <RowDefinition Height="1*" /> + <RowDefinition Height="1*" /> + <RowDefinition Height="1*" /> + </Grid.RowDefinitions> + </Grid> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemContainerStyle> + <Style TargetType="FrameworkElement"> + <Setter Property="Grid.Column" Value="{Binding Column}"></Setter> + <Setter Property="Grid.Row" Value="{Binding Row}"></Setter> + <Setter Property="Grid.ColumnSpan" Value="{Binding ColumnSpan}"></Setter> + <Setter Property="Grid.RowSpan" Value="{Binding RowSpan}"></Setter> + <Setter Property="Margin" Value="10"></Setter> + </Style> + </ItemsControl.ItemContainerStyle> + <ItemsControl.ItemTemplate> + <DataTemplate> + <DockPanel> + <Border Panel.ZIndex="100" CornerRadius="3 3 0 0" Visibility="{Binding AutoTitleStyle,Converter={StaticResource BooleanToVisibilityConverter}}" DockPanel.Dock="Top" Padding="8" BorderThickness="0 0 0 0"> + <Grid> + <StackPanel Margin="-30 0 0 0" Orientation="Horizontal" Visibility="{Binding AutoTitleAlignment,Converter={StaticResource EnumToVisibilityConverter},ConverterParameter='Left'}"> + <TextBlock Text="{Binding Name}" FontFamily="{StaticResource hand}" FontSize="{StaticResource FSE_LargerFontSize}" Foreground="{StaticResource FSE_PrimaryAccentBrush}"></TextBlock> + <Canvas Margin="8 10 0 0" VerticalAlignment="Center"> + <Line X1="0" Y1="0" Y2="{Binding AutoTitleLineOffset}" X2="{Binding AutoTitleLineOffset}" Stroke="{StaticResource FSE_PrimaryAccentBrush}" StrokeDashArray="5"></Line> + </Canvas> + </StackPanel> + <StackPanel HorizontalAlignment="Center" Visibility="{Binding AutoTitleAlignment,Converter={StaticResource EnumToVisibilityConverter},ConverterParameter='Top'}"> + <TextBlock Text="{Binding Name}" Margin="0 -30 0 0" HorizontalAlignment="Center" TextAlignment="Center" FontFamily="{StaticResource hand}" FontSize="{StaticResource FSE_LargerFontSize}" Foreground="{StaticResource FSE_PrimaryAccentBrush}"></TextBlock> + <Canvas VerticalAlignment="Center" HorizontalAlignment="Center"> + <Line X1="0" Y1="0" Y2="{Binding AutoTitleLineOffset}" X2="0" Stroke="{StaticResource FSE_PrimaryAccentBrush}" StrokeDashArray="5"></Line> + </Canvas> + </StackPanel> + <StackPanel Margin="0 0 -30 0" HorizontalAlignment="Right" Orientation="Horizontal" Visibility="{Binding AutoTitleAlignment,Converter={StaticResource EnumToVisibilityConverter},ConverterParameter='Right'}"> + <Canvas Margin="0 10 8 0" VerticalAlignment="Center"> + <Line X1="0" Y1="0" Y2="{Binding AutoTitleLineOffset}" X2="{Binding AutoTitleLineOffset,Converter={StaticResource MathOperatorConverter},ConverterParameter='*-1'}" Stroke="{StaticResource FSE_PrimaryAccentBrush}" StrokeDashArray="5"></Line> + </Canvas> + <TextBlock Text="{Binding Name}" FontFamily="{StaticResource hand}" FontSize="{StaticResource FSE_LargerFontSize}" Foreground="{StaticResource FSE_PrimaryAccentBrush}"></TextBlock> + </StackPanel> + </Grid> + </Border> <Grid> - <StackPanel Margin="-30 0 0 0" Orientation="Horizontal" Visibility="{Binding AutoTitleAlignment,Converter={StaticResource EnumToVisibilityConverter},ConverterParameter='Left'}"> - <TextBlock Text="{Binding Name}" FontFamily="{StaticResource hand}" FontSize="{StaticResource FSE_LargerFontSize}" Foreground="{StaticResource FSE_PrimaryAccentBrush}"></TextBlock> - <Canvas Margin="8 10 0 0" VerticalAlignment="Center"> - <Line X1="0" Y1="0" Y2="30" X2="30" Stroke="{StaticResource FSE_PrimaryAccentBrush}" StrokeDashArray="5"></Line> - </Canvas> - </StackPanel> - <StackPanel Margin="0 0 -30 0" HorizontalAlignment="Right" Orientation="Horizontal" Visibility="{Binding AutoTitleAlignment,Converter={StaticResource EnumToVisibilityConverter},ConverterParameter='Right'}"> - <Canvas Margin="0 10 8 0" VerticalAlignment="Center"> - <Line X1="0" Y1="0" Y2="30" X2="-30" Stroke="{StaticResource FSE_PrimaryAccentBrush}" StrokeDashArray="5"></Line> - </Canvas> - <TextBlock Text="{Binding Name}" FontFamily="{StaticResource hand}" FontSize="{StaticResource FSE_LargerFontSize}" Foreground="{StaticResource FSE_PrimaryAccentBrush}"></TextBlock> - </StackPanel> + <Border CornerRadius="0 0 3 3" BorderBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}"> + <Border.Style> + <Style TargetType="Border"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="BorderThickness" Value="0"></Setter> + <Setter Property="Opacity" Value="1"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding AutoContainerStyle}" Value="True"> + <Setter Property="Background" Value="{StaticResource FSE_PrimaryBackgroundMidBrush}"></Setter> + <Setter Property="BorderThickness" Value="1"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding MachineProvider.IsConnected}" Value="False"> + <Setter Property="Opacity" Value="0.2"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Border.Style> + <ContentPresenter Content="{Binding Converter={StaticResource DashboardTileToViewConverter}}" /> + </Border> + <DockPanel HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding MachineProvider.IsConnected,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> + <material:PackIcon Kind="InfoOutline" /> + <TextBlock Margin="5 0 0 0" Foreground="{StaticResource FSE_GrayBrush}" FontWeight="SemiBold">No Machine Connection</TextBlock> + </DockPanel> </Grid> - </Border> - <Grid> - <Border CornerRadius="0 0 3 3" BorderBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}"> - <Border.Style> - <Style TargetType="Border"> - <Setter Property="Background" Value="Transparent"></Setter> - <Setter Property="BorderThickness" Value="0"></Setter> - <Setter Property="Opacity" Value="1"></Setter> - <Style.Triggers> - <DataTrigger Binding="{Binding AutoContainerStyle}" Value="True"> - <Setter Property="Background" Value="{StaticResource FSE_PrimaryBackgroundDarkBrush}"></Setter> - <Setter Property="BorderThickness" Value="1"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding MachineProvider.IsConnected}" Value="False"> - <Setter Property="Opacity" Value="0.2"></Setter> - </DataTrigger> - </Style.Triggers> - </Style> - </Border.Style> - <ContentPresenter Content="{Binding Converter={StaticResource DashboardTileToViewConverter}}" /> - </Border> - <DockPanel HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding MachineProvider.IsConnected,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> - <material:PackIcon Kind="InfoOutline" /> - <TextBlock Margin="5 0 0 0" Foreground="{StaticResource FSE_GrayBrush}" FontWeight="SemiBold">No Machine Connection</TextBlock> - </DockPanel> - </Grid> - </DockPanel> - </DataTemplate> - </ItemsControl.ItemTemplate> - </ItemsControl> + </DockPanel> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </Grid> </Grid> </UserControl> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/EventsView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/EventsView.xaml index 6937856fe..8789cc05c 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/EventsView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/EventsView.xaml @@ -183,7 +183,7 @@ <material:PackIcon Kind="BellAlert" Foreground="{StaticResource FSE_CriticalBrush}" /> <TextBlock Margin="5 0 0 0" VerticalAlignment="Center"> <Run Text="{Binding CriticalEvents}"></Run> - <Run>critical errors</Run> + <Run>critical</Run> </TextBlock> </DockPanel> <DockPanel Margin="0 5"> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/DefaultRemoteJobService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/DefaultRemoteJobService.cs new file mode 100644 index 000000000..33e002950 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/DefaultRemoteJobService.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.DTO; +using Tango.Core; +using Tango.Core.DI; +using Tango.Integration.ExternalBridge; +using Tango.Integration.Operation; +using Tango.PPC.Common.Connection; +using Tango.PPC.Common.ExternalBridge; +using Tango.PPC.Shared.Jobs; + +namespace Tango.PPC.Common.RemoteJob +{ + [TangoCreateWhenRegistered] + public class DefaultRemoteJobService : IRemoteJobService, IExternalBridgeRequestHandler + { + private class RunningJobUpdateClient + { + public String Token { get; set; } + public ExternalBridgeReceiver Receiver { get; set; } + public bool JobSent { get; set; } + } + + private List<RunningJobUpdateClient> _clients; + private JobHandler _handler; + + public bool Enabled { get; set; } = true; + + private IMachineProvider MachineProvider { get; set; } + + public DefaultRemoteJobService(IPPCExternalBridgeService externalBridge, IMachineProvider machineProvider) + { + externalBridge.RegisterRequestHandler(this); + + MachineProvider = machineProvider; + + _clients = new List<RunningJobUpdateClient>(); + MachineProvider.MachineOperator.PrintingStarted += MachineOperator_PrintingStarted; + } + + private async void MachineOperator_PrintingStarted(object sender, Integration.Operation.PrintingEventArgs e) + { + _handler = e.JobHandler; + + e.JobHandler.StatusChanged += JobHandler_StatusChanged; + e.JobHandler.Stopped += JobHandler_Stopped; + + var jobDTO = JobDTO.FromObservable(e.Job); + var processParametersDTO = ProcessParametersTableDTO.FromObservable(_handler.ProcessParameters); + + foreach (var client in _clients.ToList()) + { + try + { + RemoteJobProgress progress = new RemoteJobProgress(); + progress.Stage = RemoteJobStage.Started; + progress.JobStatus = _handler.JobStatus; + + await client.Receiver.SendGenericResponse(new RemoteJobUpdateResponse() + { + Job = jobDTO, + ProcessParameters = processParametersDTO, + Progress = progress + }, client.Token); + + client.JobSent = true; + } + catch { } + } + } + + private async void JobHandler_StatusChanged(object sender, RunningJobStatus e) + { + foreach (var client in _clients.ToList().Where(x => x.JobSent)) + { + try + { + await client.Receiver.SendGenericResponse(new RemoteJobUpdateResponse() + { + Progress = GetJobProgress(_handler) + }, client.Token); + } + catch { } + } + } + + private async void JobHandler_Stopped(object sender, EventArgs e) + { + foreach (var client in _clients.ToList().Where(x => x.JobSent)) + { + try + { + await client.Receiver.SendGenericResponse(new RemoteJobUpdateResponse() + { + Progress = GetJobProgress(_handler), + }, client.Token); + + client.JobSent = false; + } + catch { } + } + } + + private RemoteJobProgress GetJobProgress(JobHandler handler) + { + RemoteJobStage stage = RemoteJobStage.Running; + + if (_handler.Status.IsCanceled) + { + stage = RemoteJobStage.Aborted; + } + else if (_handler.Status.IsCompleted) + { + stage = RemoteJobStage.Completed; + } + else if (_handler.Status.IsFailed) + { + stage = RemoteJobStage.Failed; + } + + return new RemoteJobProgress() + { + Stage = stage, + JobStatus = handler.JobStatus, + }; + } + + [ExternalBridgeRequestHandlerMethod(typeof(RemoteJobUpdateRequest), RequestHandlerLoggingMode.LogRequestName)] + public async Task OnRunningJobUpdateRequest(RemoteJobUpdateRequest request, String token, ExternalBridgeReceiver receiver) + { + this.ThrowIfDisabled(); + + if (!_clients.ToList().Exists(x => x.Receiver == receiver)) + { + _clients.Add(new RunningJobUpdateClient() + { + Receiver = receiver, + Token = token + }); + } + + await receiver.SendGenericResponse(new RemoteJobUpdateResponse(), token); + } + + public void OnReceiverDisconnected(ExternalBridgeReceiver receiver) + { + _clients.RemoveAll(x => x.Receiver == receiver); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/IRemoteJobService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/IRemoteJobService.cs new file mode 100644 index 000000000..e7bfdbec1 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/IRemoteJobService.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Integration.ExternalBridge; + +namespace Tango.PPC.Common.RemoteJob +{ + public interface IRemoteJobService : IPPCService + { + + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj index e97fd9d32..9bdba2c63 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj @@ -173,6 +173,8 @@ <Compile Include="RemoteDesktop\DefaultRemoteDesktopService.cs" /> <Compile Include="RemoteDesktop\IRemoteDesktopService.cs" /> <Compile Include="RemoteDesktop\RemoteDesktopClient.cs" /> + <Compile Include="RemoteJob\DefaultRemoteJobService.cs" /> + <Compile Include="RemoteJob\IRemoteJobService.cs" /> <Compile Include="Synchronization\DefaultMachineDataSynchronizer.cs" /> <Compile Include="Synchronization\IMachineDataSynchronizer.cs" /> <Compile Include="Synchronization\SynchronizationEndedEventArgs.cs" /> @@ -460,7 +462,7 @@ </Target> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> + <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobProgress.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobProgress.cs new file mode 100644 index 000000000..d91d612d1 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobProgress.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; +using Tango.PMR.Printing; + +namespace Tango.PPC.Shared.Jobs +{ + public class RemoteJobProgress + { + public RemoteJobStage Stage { get; set; } + public JobStatus JobStatus { get; set; } + + public RemoteJobProgress() + { + JobStatus = new JobStatus(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobStage.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobStage.cs new file mode 100644 index 000000000..5235b995b --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobStage.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Shared.Jobs +{ + public enum RemoteJobStage + { + None, + Started, + Running, + Failed, + Aborted, + Completed + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateRequest.cs new file mode 100644 index 000000000..1322031ac --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateRequest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Shared.Jobs +{ + public class RemoteJobUpdateRequest + { + + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateResponse.cs new file mode 100644 index 000000000..0bb32d266 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateResponse.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.DTO; +using Tango.Core; + +namespace Tango.PPC.Shared.Jobs +{ + public class RemoteJobUpdateResponse + { + public JobDTO Job { get; set; } + public ProcessParametersTableDTO ProcessParameters { get; set; } + public RemoteJobProgress Progress { get; set; } + + public RemoteJobUpdateResponse() + { + Progress = new RemoteJobProgress(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj index 153352c20..221cea81e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj @@ -60,6 +60,10 @@ <Compile Include="Information\GetMachineInformationRequest.cs" /> <Compile Include="Information\GetMachineInformationResponse.cs" /> <Compile Include="Information\InformationPackage.cs" /> + <Compile Include="Jobs\RemoteJobProgress.cs" /> + <Compile Include="Jobs\RemoteJobStage.cs" /> + <Compile Include="Jobs\RemoteJobUpdateRequest.cs" /> + <Compile Include="Jobs\RemoteJobUpdateResponse.cs" /> <Compile Include="Logs\GetLogFilesRequest.cs" /> <Compile Include="Logs\GetLogFilesResponse.cs" /> <Compile Include="Logs\RemoteLogFile.cs" /> @@ -107,6 +111,10 @@ <Project>{A34EE0F0-649D-41C8-8489-B6F1CC6924EE}</Project> <Name>Tango.Core</Name> </ProjectReference> + <ProjectReference Include="..\..\Tango.PMR\Tango.PMR.csproj"> + <Project>{E4927038-348D-4295-AAF4-861C58CB3943}</Project> + <Name>Tango.PMR</Name> + </ProjectReference> <ProjectReference Include="..\..\Tango.SystemInfo\Tango.SystemInfo.csproj"> <Project>{997a961c-beda-4b56-aa0f-c39e532f7ffa}</Project> <Name>Tango.SystemInfo</Name> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs index c146de51b..8b75b4517 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs @@ -25,6 +25,7 @@ using Tango.PPC.Common.Performance; using Tango.PPC.Common.Printing; using Tango.PPC.Common.RemoteAssistance; using Tango.PPC.Common.RemoteDesktop; +using Tango.PPC.Common.RemoteJob; using Tango.PPC.Common.Storage; using Tango.PPC.Common.Synchronization; using Tango.PPC.Common.SystemInfo; @@ -88,6 +89,7 @@ namespace Tango.PPC.UI TangoIOC.Default.Unregister<IPerformanceService>(); TangoIOC.Default.Unregister<ISystemInfoService>(); TangoIOC.Default.Unregister<IFileSystemService>(); + TangoIOC.Default.Unregister<IRemoteJobService>(); if (App.StartupArgs.Contains("-webDebug")) { @@ -126,6 +128,7 @@ namespace Tango.PPC.UI TangoIOC.Default.Register<ISystemInfoService, DefaultSystemInfoService>(); TangoIOC.Default.Register<IFileSystemService, DefaultFileSystemService>(); TangoIOC.Default.Register<IRemoteDesktopService, DefaultRemoteDesktopService>(); + TangoIOC.Default.Register<IRemoteJobService, DefaultRemoteJobService>(); TangoIOC.Default.Register<LoadingViewVM>(); TangoIOC.Default.Register<MainViewVM>(); diff --git a/Software/Visual_Studio/Tango.Core/TangoProgress.cs b/Software/Visual_Studio/Tango.Core/TangoProgress.cs index be684ece9..ccec0e546 100644 --- a/Software/Visual_Studio/Tango.Core/TangoProgress.cs +++ b/Software/Visual_Studio/Tango.Core/TangoProgress.cs @@ -10,7 +10,7 @@ namespace Tango.Core /// Represents a progress of some process. /// </summary> /// <typeparam name="T"></typeparam> - public class TangoProgress<T> where T : IComparable, IFormattable, IConvertible + public class TangoProgress<T> where T : IComparable, IFormattable { /// <summary> /// Gets or sets the progress message. @@ -39,14 +39,21 @@ namespace Tango.Core { get { - double max = Convert.ToDouble(Maximum); - double value = Convert.ToDouble(Value); - - if (max > 0) + try { - return Math.Round(value / max * 100d, 0); + double max = Convert.ToDouble(Maximum); + double value = Convert.ToDouble(Value); + + if (max > 0) + { + return Math.Round(value / max * 100d, 0); + } + else + { + return 0; + } } - else + catch { return 0; } @@ -87,7 +94,7 @@ namespace Tango.Core /// </summary> /// <typeparam name="T"></typeparam> /// <seealso cref="System.EventArgs" /> - public class TangoProgressChangedEventArgs<T> : EventArgs where T : IComparable, IFormattable, IConvertible + public class TangoProgressChangedEventArgs<T> : EventArgs where T : IComparable, IFormattable { /// <summary> /// Gets or sets the progress. diff --git a/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs b/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs index 96c2ea4c4..f0ed109cc 100644 --- a/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs +++ b/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs @@ -88,6 +88,17 @@ namespace Tango.Integration.Operation #region Properties + private JobStatus _jobStatus; + /// <summary> + /// Gets or sets the current job status that was used to invalidate this handler. + /// </summary> + public JobStatus JobStatus + { + get { return _jobStatus; } + set { _jobStatus = value; RaisePropertyChangedAuto(); } + } + + /// <summary> /// Gets a value indicating whether this handler job has been canceled. /// </summary> @@ -144,7 +155,7 @@ namespace Tango.Integration.Operation /// Initializes a new instance of the <see cref="JobHandler"/> class. /// </summary> /// <param name="cancelAction">The cancel action.</param> - internal JobHandler(Action cancelAction, Job job, JobTicket jobTicket, ProcessParametersTable processParameters, JobHandlerModes mode) : this() + public JobHandler(Action cancelAction, Job job, JobTicket jobTicket, ProcessParametersTable processParameters, JobHandlerModes mode) : this() { _mode = mode; @@ -195,7 +206,7 @@ namespace Tango.Integration.Operation //Create all segments int segment_index = 1; - for (int j = 0; j < Job.NumberOfUnits; j++) + for (int j = 0; j < Math.Max(Job.NumberOfUnits, 1); j++) { for (int i = 0; i < _effectiveSegments.Count; i++) { @@ -231,7 +242,7 @@ namespace Tango.Integration.Operation /// Raises the status received event. /// </summary> /// <param name="status">The status.</param> - internal void RaiseStatusReceived(JobStatus status) + public void RaiseStatusReceived(JobStatus status) { InvalidateJobProgress(status); } @@ -240,7 +251,7 @@ namespace Tango.Integration.Operation /// Raises the failed event. /// </summary> /// <param name="ex">The ex.</param> - internal void RaiseFailed(Exception ex) + public void RaiseFailed(Exception ex) { LogManager.Log($"Job failed at position {Status.Progress}/{Status.TotalProgress}..."); Status.IsFailed = true; @@ -253,7 +264,7 @@ namespace Tango.Integration.Operation /// <summary> /// Raises the completed event. /// </summary> - internal void RaiseCompleted() + public void RaiseCompleted() { //This will compensate on any missing progress from Shlomo, but also will tell the wrong progress if job is really completed with a large progress mistake. // Might be worth to compensate only on small drifts like the below (ProgressMinusSettingsUp)... @@ -285,7 +296,7 @@ namespace Tango.Integration.Operation /// <summary> /// Raises the canceled event. /// </summary> - internal void RaiseCanceled() + public void RaiseCanceled() { LogManager.Log($"Job canceled at position {Status.Progress}/{Status.TotalProgress}..."); Status.IsCanceled = true; @@ -313,6 +324,7 @@ namespace Tango.Integration.Operation private void InvalidateJobProgress(JobStatus s) { + JobStatus = s; bool invalidProgress = false; if (_last_progress != s.Progress) |
