feat: redesign Bench page with Fluent card layout and radial advance monitor

Three-column layout replacing the old HMI grid:
- BenchRpmCommandCard: inline numeric input, 2×4 preset grid, Start/Stop
- BenchActuatorsCard: direction toggle, oil pump, temperature PID, misc relays
  with FluentStateToggle showing checked state via AccentFillColor
- BenchLiveDataCard: 2×5 KPI tiles (RPM, P1, P2, Q-Delivery, Q-Over, temps)
- BenchChartsCard: 2×2 compact chart grid (Delivery, Over, P1, P2)
- AdvanceMonitorCard: RadialAngleGauge custom FrameworkElement + PSG/INJ readouts,
  Δ° lock offset input, Zero PSG / Zero INJ buttons

Supporting changes:
- AngleDisplayViewModel: promote _currentManualDegrees, _isLockSet to
  [ObservableProperty]; add PsgRelativeDegrees, InjEncoderDegreesValue,
  TargetLockAngle, IsRunningMode (29/31 hysteresis); computed PrimaryGaugeAngle,
  TargetAngleForGauge, SecondaryGaugeAngle
- BenchControlViewModel: add IsDirectionLeft computed property,
  SetDirectionRightCommand, SetDirectionLeftCommand, ApplyRpmCommand
- FlowmeterChartView: add IsCompact DP (false default) for 90px compact height
- Styles.xaml: add IsChecked trigger to FluentStateToggle (accent fill + white text)
- Strings.en/es.xaml: add all new card and actuator string keys

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 17:45:59 +02:00
parent 70be693116
commit 69bfda54e1
19 changed files with 1361 additions and 59 deletions

View File

@@ -0,0 +1,235 @@
<UserControl x:Class="HC_APTBS.Views.UserControls.BenchLiveDataCard"
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:ui="http://schemas.lepo.co/wpfui/2022/xaml"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="800">
<!--
Live bench readings as two rows of five KPI tiles.
Row 1: RPM, P1, P2, Q-Delivery, Q-Over.
Row 2: T-In, T-Out, T4, T-Tank, Bench Temp.
DataContext = BenchPageViewModel.
-->
<UserControl.Resources>
<Style x:Key="BenchKpiTile" TargetType="Border" BasedOn="{StaticResource KpiTile}">
<Setter Property="MinHeight" Value="100"/>
</Style>
</UserControl.Resources>
<Border Style="{StaticResource PumpCard}">
<DockPanel LastChildFill="True">
<!-- ── Card header ─────────────────────────────────────────── -->
<DockPanel DockPanel.Dock="Top" Margin="0,0,0,10">
<ui:SymbolIcon DockPanel.Dock="Left" Symbol="DataLine24" FontSize="16"
Foreground="{DynamicResource AccentTextFillColorPrimaryBrush}"
Margin="0,0,8,0" VerticalAlignment="Center"/>
<TextBlock Text="{DynamicResource Bench.LiveData.Title}"
Style="{StaticResource PumpCardHeader}" Margin="0"/>
</DockPanel>
<!-- ── Row 2: T-In, T-Out, T4, T-Tank, Bench Temp ─────────── -->
<UniformGrid DockPanel.Dock="Bottom" Rows="1" Columns="5" Margin="0,6,0,0">
<Border Style="{StaticResource BenchKpiTile}">
<Grid>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="Temperature24" FontSize="13"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
Margin="0,0,4,0" VerticalAlignment="Center"/>
<TextBlock Text="{DynamicResource Bench.Kpi.TIn}"
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Root.TempIn, StringFormat=F1}"
Style="{StaticResource KpiValueText}" FontSize="28"/>
<TextBlock Text="{DynamicResource Pump.UnitCelsius}"
Style="{StaticResource KpiUnitText}"/>
</StackPanel>
</Grid>
</Border>
<Border Style="{StaticResource BenchKpiTile}">
<Grid>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="Temperature24" FontSize="13"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
Margin="0,0,4,0" VerticalAlignment="Center"/>
<TextBlock Text="{DynamicResource Bench.Kpi.TOut}"
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Root.TempOut, StringFormat=F1}"
Style="{StaticResource KpiValueText}" FontSize="28"/>
<TextBlock Text="{DynamicResource Pump.UnitCelsius}"
Style="{StaticResource KpiUnitText}"/>
</StackPanel>
</Grid>
</Border>
<Border Style="{StaticResource BenchKpiTile}">
<Grid>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="Temperature24" FontSize="13"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
Margin="0,0,4,0" VerticalAlignment="Center"/>
<TextBlock Text="{DynamicResource Bench.Kpi.T4}"
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Root.Temp4, StringFormat=F1}"
Style="{StaticResource KpiValueText}" FontSize="28"/>
<TextBlock Text="{DynamicResource Pump.UnitCelsius}"
Style="{StaticResource KpiUnitText}"/>
</StackPanel>
</Grid>
</Border>
<Border Style="{StaticResource BenchKpiTile}">
<Grid>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="Temperature24" FontSize="13"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
Margin="0,0,4,0" VerticalAlignment="Center"/>
<TextBlock Text="{DynamicResource Bench.Kpi.TTank}"
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Root.BenchTemp, StringFormat=F1}"
Style="{StaticResource KpiValueText}" FontSize="28"/>
<TextBlock Text="{DynamicResource Pump.UnitCelsius}"
Style="{StaticResource KpiUnitText}"/>
</StackPanel>
</Grid>
</Border>
<Border Style="{StaticResource BenchKpiTile}">
<Grid>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="Temperature24" FontSize="13"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
Margin="0,0,4,0" VerticalAlignment="Center"/>
<TextBlock Text="{DynamicResource Bench.Kpi.BenchTemp}"
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Root.BenchTemp, StringFormat=F1}"
Style="{StaticResource KpiValueText}" FontSize="28"/>
<TextBlock Text="{DynamicResource Pump.UnitCelsius}"
Style="{StaticResource KpiUnitText}"/>
</StackPanel>
</Grid>
</Border>
</UniformGrid>
<!-- ── Row 1: RPM, P1, P2, Q-Delivery, Q-Over ─────────────── -->
<UniformGrid Rows="1" Columns="5">
<Border Style="{StaticResource BenchKpiTile}">
<Grid>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="Gauge24" FontSize="13"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
Margin="0,0,4,0" VerticalAlignment="Center"/>
<TextBlock Text="{DynamicResource Bench.Kpi.Rpm}"
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Root.BenchRpm, StringFormat=F0}"
Style="{StaticResource KpiValueText}" FontSize="28"/>
<TextBlock Text="{DynamicResource Bench.Rpm}"
Style="{StaticResource KpiUnitText}"/>
</StackPanel>
</Grid>
</Border>
<Border Style="{StaticResource BenchKpiTile}">
<Grid>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="ArrowTrendingLines24" FontSize="13"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
Margin="0,0,4,0" VerticalAlignment="Center"/>
<TextBlock Text="{DynamicResource Bench.Kpi.P1}"
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Root.Pressure, StringFormat=F2}"
Style="{StaticResource KpiValueText}" FontSize="28"/>
<TextBlock Text="{DynamicResource Bench.Kpi.Unit.Bar}"
Style="{StaticResource KpiUnitText}"/>
</StackPanel>
</Grid>
</Border>
<Border Style="{StaticResource BenchKpiTile}">
<Grid>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="ArrowTrendingLines24" FontSize="13"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
Margin="0,0,4,0" VerticalAlignment="Center"/>
<TextBlock Text="{DynamicResource Bench.Kpi.P2}"
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Root.Pressure2, StringFormat=F2}"
Style="{StaticResource KpiValueText}" FontSize="28"/>
<TextBlock Text="{DynamicResource Bench.Kpi.Unit.Bar}"
Style="{StaticResource KpiUnitText}"/>
</StackPanel>
</Grid>
</Border>
<Border Style="{StaticResource BenchKpiTile}">
<Grid>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="Drop24" FontSize="13"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
Margin="0,0,4,0" VerticalAlignment="Center"/>
<TextBlock Text="{DynamicResource Bench.Kpi.QDelivery}"
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Root.QDelivery, StringFormat=F1}"
Style="{StaticResource KpiValueText}" FontSize="28"/>
<TextBlock Text="{DynamicResource Bench.Kpi.Unit.CcS}"
Style="{StaticResource KpiUnitText}"/>
</StackPanel>
</Grid>
</Border>
<Border Style="{StaticResource BenchKpiTile}">
<Grid>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="Drop24" FontSize="13"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
Margin="0,0,4,0" VerticalAlignment="Center"/>
<TextBlock Text="{DynamicResource Bench.Kpi.QOver}"
Style="{StaticResource KpiHeaderText}" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Root.QOver, StringFormat=F1}"
Style="{StaticResource KpiValueText}" FontSize="28"/>
<TextBlock Text="{DynamicResource Bench.Kpi.Unit.CcS}"
Style="{StaticResource KpiUnitText}"/>
</StackPanel>
</Grid>
</Border>
</UniformGrid>
</DockPanel>
</Border>
</UserControl>