agrobot_base/AgroBase/OperationControl/Controls/AttitudeIndicator.xaml

174 lines
11 KiB
XML

<UserControl x:Class="OperationControl.Controls.AttitudeIndicator"
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:sys="clr-namespace:System;assembly=mscorlib"
xmlns:conv="clr-namespace:OperationControl.Converters"
mc:Ignorable="d"
d:DesignWidth="160" d:DesignHeight="180">
<UserControl.Resources>
<!-- Escova padrão -->
<LinearGradientBrush x:Key="SkyBrush" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#4A90E2" Offset="0"/>
<GradientStop Color="#6FB1FF" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="GroundBrush" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#5F6A36" Offset="0"/>
<GradientStop Color="#7F8A56" Offset="1"/>
</LinearGradientBrush>
<conv:MultiplyConverter x:Key="MultiplyConverter"/>
<conv:LateralErrorToOffsetConverter x:Key="LateralErrorToOffsetConverter"/>
</UserControl.Resources>
<!-- MOLDURA -->
<Border x:Name="Chrome"
CornerRadius="12"
Padding="8"
BorderThickness="2"
Background="#111"
BorderBrush="#2ECC71">
<Grid>
<Grid.RowDefinitions>
<!-- parte de cima: horizonte / attitude -->
<RowDefinition/>
<!-- parte de baixo: barra de erro lateral -->
<RowDefinition Height="24"/>
</Grid.RowDefinitions>
<!-- VIEWPORT: corta o conteúdo dentro do quadro -->
<Grid x:Name="Viewport" ClipToBounds="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<!-- WORLD: é quem gira/anda e é BEM MAIOR que o viewport -->
<Grid x:Name="World" RenderTransformOrigin="0.5,0.5"
Width="{Binding ActualWidth, ElementName=Viewport, Converter={StaticResource MultiplyConverter}, ConverterParameter=1.52}" HorizontalAlignment="Center"
Height="{Binding ActualHeight, ElementName=Viewport, Converter={StaticResource MultiplyConverter}, ConverterParameter=2}" VerticalAlignment="Center">
<!-- HORIZON: mesmo tamanho do World; só TRANSLADA (pitch) -->
<Grid x:Name="Horizon" HorizontalAlignment="Center" VerticalAlignment="Center" Width="{Binding Width, ElementName=World}" Height="{Binding Height, ElementName=World}" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<RotateTransform Angle="{Binding RollDeg, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
<TranslateTransform Y="{Binding PitchOffsetPx, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</TransformGroup>
</Grid.RenderTransform>
<!-- FUNDO "infinito": use Viewbox para preencher sempre -->
<Viewbox Stretch="Fill">
<Grid Height="320" Width="210">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- Céu / Solo -->
<Rectangle Grid.Row="0" Fill="{StaticResource SkyBrush}"/>
<Rectangle Grid.Row="1" Fill="{StaticResource GroundBrush}"/>
<!-- Horizonte -->
<Rectangle Grid.RowSpan="2" Height="3" Fill="White" Opacity="0.9" VerticalAlignment="Center"/>
<Grid Grid.RowSpan="2">
<Rectangle Width="60" Height="2" Fill="White" VerticalAlignment="Center" Margin="0,-80,0,0" HorizontalAlignment="Center"/>
<TextBlock Text="20" Foreground="White" FontSize="11" FontWeight="SemiBold" VerticalAlignment="Center" Margin="0,-84,-115,0" HorizontalAlignment="Center"/>
<Rectangle Width="50" Height="2" Fill="White" VerticalAlignment="Center" Margin="0,-40,0,0" HorizontalAlignment="Center"/>
<TextBlock Text="10" Foreground="White" FontSize="11" FontWeight="SemiBold" VerticalAlignment="Center" Margin="0,-40,-115,0" HorizontalAlignment="Center"/>
<Rectangle Width="30" Height="2" Fill="White" VerticalAlignment="Center" Margin="0,-20,0,0" HorizontalAlignment="Center"/>
<Rectangle Width="30" Height="2" Fill="White" VerticalAlignment="Center" Margin="0,20,0,0" HorizontalAlignment="Center"/>
<Rectangle Width="50" Height="2" Fill="White" VerticalAlignment="Center" Margin="0,40,0,0" HorizontalAlignment="Center"/>
<TextBlock Text="10" Foreground="White" FontSize="11" FontWeight="SemiBold" VerticalAlignment="Center" Margin="0,40,-115,0" HorizontalAlignment="Center"/>
<Rectangle Width="60" Height="2" Fill="White" VerticalAlignment="Center" Margin="0,80,0,0" HorizontalAlignment="Center"/>
<TextBlock Text="20" Foreground="White" FontSize="11" FontWeight="SemiBold" VerticalAlignment="Center" Margin="0,78,-115,0" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</Viewbox>
</Grid>
</Grid>
<!-- ARCO DO ROLL (fixo e centralizado via Viewbox) -->
<Viewbox Stretch="Uniform" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="0,6,0,0">
<Canvas Width="160" Height="60">
<!-- arco -->
<Path Stroke="White" StrokeThickness="2" Opacity="0.9" Data="M 15,55 A 60,60 0 0 1 140,55" HorizontalAlignment="Center" VerticalAlignment="Center" Height="55" Stretch="Fill" Canvas.Left="16.5" Canvas.Top="-14.762"/>
<!-- ticks principais (-30, 0, +30) -->
<Rectangle Width="2" Height="8" Fill="White" Canvas.Left="40" Canvas.Top="25"/>
<Rectangle Width="2" Height="10" Fill="White" Canvas.Left="79" Canvas.Top="24"/>
<Rectangle Width="2" Height="8" Fill="White" Canvas.Left="118" Canvas.Top="25"/>
<!-- marcador de roll -->
<Polygon Points="74,8 86,8 80,18" Fill="#FFD93D"/>
</Canvas>
</Viewbox>
<!-- SÍMBOLO CENTRAL (fixo) -->
<Grid>
<Rectangle Width="38" Height="2" Fill="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Rectangle Width="2" Height="14" Fill="White" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="-18,0,0,0"/>
<Rectangle Width="2" Height="14" Fill="White" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="18,0,0,0"/>
<Rectangle Width="8" Height="8" Stroke="White" StrokeThickness="2" Fill="#22FFFFFF" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<!-- HUD NUMÉRICO DE INCLINAÇÃO -->
<Grid VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Margin="4,0,4,6" IsHitTestVisible="False">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- Inclinação lateral / Roll -->
<Border Grid.Column="0" CornerRadius="5" Background="#AA000000" BorderBrush="#55FFFFFF" BorderThickness="1" Padding="4,2" HorizontalAlignment="Left">
<TextBlock Text="{Binding RollTexto, RelativeSource={RelativeSource AncestorType=UserControl}}" Foreground="White" FontSize="11" FontWeight="SemiBold"/>
</Border>
<!-- Inclinação frontal / Pitch -->
<Border Grid.Column="1" CornerRadius="5" Background="#AA000000" BorderBrush="#55FFFFFF" BorderThickness="1" Padding="4,2" HorizontalAlignment="Right">
<TextBlock Text="{Binding PitchTexto, RelativeSource={RelativeSource AncestorType=UserControl}}" Foreground="White" FontSize="11" FontWeight="SemiBold"/>
</Border>
</Grid>
</Grid>
<!-- BARRA DE ERRO LATERAL (linha 1) -->
<Grid Grid.Row="1" Margin="2,6,2,0">
<Border x:Name="LateralTrack" CornerRadius="4" Background="#222" BorderBrush="#555" BorderThickness="1">
<Grid>
<!-- linha de referência (meio da rua) -->
<Rectangle Width="2" Fill="#666" HorizontalAlignment="Center" RadiusX="1" RadiusY="1"/>
<!-- barrinha que se move com o erro -->
<Rectangle Width="32" Height="6" RadiusX="3" RadiusY="3" Fill="#F1C40F" Stroke="#222" StrokeThickness="0.5">
<Rectangle.RenderTransform>
<TranslateTransform>
<TranslateTransform.X>
<MultiBinding Converter="{StaticResource LateralErrorToOffsetConverter}">
<!-- Largura do trilho -->
<Binding ElementName="LateralTrack" Path="ActualWidth"/>
<!-- Erro normalizado (-1 a +1) -->
<Binding Path="LateralNormalized" RelativeSource="{RelativeSource AncestorType=UserControl}"/>
</MultiBinding>
</TranslateTransform.X>
</TranslateTransform>
</Rectangle.RenderTransform>
</Rectangle>
<!-- valor numérico opcional (no canto direito) -->
<TextBlock Text="{Binding LateralError, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat={}{0:0.00} cm}" Foreground="#AAA" FontSize="10" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0"/>
</Grid>
</Border>
</Grid>
</Grid>
</Border>
<!-- BORDAS por nível de risco -->
<UserControl.Style>
<Style TargetType="UserControl">
<Style.Triggers>
<!-- Crítico -->
</Style.Triggers>
</Style>
</UserControl.Style>
</UserControl>