Implementado novo layout para OperationControl
This commit is contained in:
parent
7ff339eaf6
commit
d0e58be553
|
|
@ -3,6 +3,7 @@ using AgroBase.Models.Operadores;
|
|||
using AgroBase.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using static AgroBase.Models.Enums;
|
||||
|
||||
|
|
@ -10,66 +11,460 @@ namespace AgroBase.Models.Operacoes
|
|||
{
|
||||
public class OperacaoParametrosModel
|
||||
{
|
||||
public string RoverId { get; set; }
|
||||
public string IP { get; set; }
|
||||
public bool Alive { get; set; }
|
||||
private string _roverId;
|
||||
public string RoverId
|
||||
{
|
||||
get => _roverId;
|
||||
set
|
||||
{
|
||||
if (_roverId != value)
|
||||
{
|
||||
_roverId = value;
|
||||
OnPropertyChanged(nameof(RoverId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _ip;
|
||||
public string IP
|
||||
{
|
||||
get => _ip;
|
||||
set
|
||||
{
|
||||
if (_ip != value)
|
||||
{
|
||||
_ip = value;
|
||||
OnPropertyChanged(nameof(IP));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _alive;
|
||||
public bool Alive
|
||||
{
|
||||
get => _alive;
|
||||
set
|
||||
{
|
||||
if (_alive != value)
|
||||
{
|
||||
_alive = value;
|
||||
OnPropertyChanged(nameof(Alive));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ModoOperacao? _modo;
|
||||
public ModoOperacao? Modo
|
||||
{
|
||||
get => _modo;
|
||||
set
|
||||
{
|
||||
if (_modo != value)
|
||||
{
|
||||
_modo = value;
|
||||
OnPropertyChanged(nameof(Modo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _descricao;
|
||||
public string Descricao
|
||||
{
|
||||
get => _descricao;
|
||||
set
|
||||
{
|
||||
if (_descricao != value)
|
||||
{
|
||||
_descricao = value;
|
||||
OnPropertyChanged(nameof(Descricao));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int? _qtdCamerasSolo;
|
||||
public int? QtdCamerasSolo
|
||||
{
|
||||
get => _qtdCamerasSolo;
|
||||
set
|
||||
{
|
||||
if (_qtdCamerasSolo != value)
|
||||
{
|
||||
_qtdCamerasSolo = value;
|
||||
OnPropertyChanged(nameof(QtdCamerasSolo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int? _qtdBicos;
|
||||
public int? QtdBicos
|
||||
{
|
||||
get => _qtdBicos;
|
||||
set
|
||||
{
|
||||
if (_qtdBicos != value)
|
||||
{
|
||||
_qtdBicos = value;
|
||||
OnPropertyChanged(nameof(QtdBicos));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double? _capacidadeReservatorio;
|
||||
public double? CapacidadeReservatorio
|
||||
{
|
||||
get => _capacidadeReservatorio;
|
||||
set
|
||||
{
|
||||
if (_capacidadeReservatorio != value)
|
||||
{
|
||||
_capacidadeReservatorio = value;
|
||||
OnPropertyChanged(nameof(CapacidadeReservatorio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private OperacaoParametrosControleModel _controle;
|
||||
public OperacaoParametrosControleModel Controle
|
||||
{
|
||||
get => _controle;
|
||||
set
|
||||
{
|
||||
if (_controle != value)
|
||||
{
|
||||
_controle = value;
|
||||
OnPropertyChanged(nameof(Controle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public DateTime UltimoContato { get; set; }
|
||||
public bool Configurado { get; set; }
|
||||
public ModoOperacao? Modo { get; set; }
|
||||
public string Descricao { get; set; }
|
||||
public int? QtdCamerasSolo { get; set; }
|
||||
public int? QtdBicos { get; set; }
|
||||
public double? CapacidadeReservatorio { get; set; }
|
||||
public List<OperacaoModulosMandatoriosModel> ModulosMandatorios { get; set; }
|
||||
public List<OperacaoParametrosMandatoriosModel> ParametrosMandatorios { get; set; }
|
||||
public OperacaoParametrosControleModel Controle { get; set; }
|
||||
|
||||
public MapaFeatureCollectionModel Mapa { get; set; }
|
||||
public List<string> RuasPercorrer { get; set; }
|
||||
|
||||
public OperacaoParametrosDadosModel DadosLeitura { get; set; }
|
||||
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected void OnPropertyChanged(string nome)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||
}
|
||||
}
|
||||
|
||||
public class OperacaoParametrosControleModel
|
||||
public class OperacaoParametrosControleModel : INotifyPropertyChanged
|
||||
{
|
||||
public bool MovimentoAutomatico { get; set; }
|
||||
public bool DirecionalAutomatico { get; set; }
|
||||
public bool PulverizadorAutomatico { get; set; }
|
||||
public bool SonarAtivado { get; set; }
|
||||
public bool OakParadaPorObstaculo { get; set; }
|
||||
public bool ImuParadaPorInclinacao { get; set; }
|
||||
public bool FrenagemAutomaticaAoParar { get; set; }
|
||||
|
||||
public bool RegistrarDadosPosProcessamento { get; set; }
|
||||
|
||||
public int MovVelocidadeSErvasPercent { get; set; }
|
||||
public int MovRpmMax
|
||||
private bool _movimentoAutomatico;
|
||||
public bool MovimentoAutomatico
|
||||
{
|
||||
get
|
||||
get => _movimentoAutomatico;
|
||||
set
|
||||
{
|
||||
return System.Convert.ToInt32(VariaveisEquipamento.RPM_Max_Roda * (MovVelocidadeSErvasPercent / 100.0));
|
||||
if (_movimentoAutomatico != value)
|
||||
{
|
||||
_movimentoAutomatico = value;
|
||||
OnPropertyChanged(nameof(MovimentoAutomatico));
|
||||
}
|
||||
}
|
||||
}
|
||||
public int MovVelocidadeCErvasPercent { get; set; }
|
||||
public int MovRpmMin
|
||||
|
||||
private bool _direcionalAutomatico;
|
||||
public bool DirecionalAutomatico
|
||||
{
|
||||
get
|
||||
get => _direcionalAutomatico;
|
||||
set
|
||||
{
|
||||
return System.Convert.ToInt32(VariaveisEquipamento.RPM_Max_Roda * (MovVelocidadeCErvasPercent / 100.0));
|
||||
if (_direcionalAutomatico != value)
|
||||
{
|
||||
_direcionalAutomatico = value;
|
||||
OnPropertyChanged(nameof(DirecionalAutomatico));
|
||||
}
|
||||
}
|
||||
}
|
||||
public int DirAnguloMaximo { get; set; }
|
||||
public double DirVelocidadeMovimento { get; set; }
|
||||
public TiposControladorDirecional DirTipoMovimento { get; set; }
|
||||
public double AtuPressaoLinha { get; set; }
|
||||
public int AtuDuracaoAtuacao { get; set; }
|
||||
public double AtuPercentualInicioPulverizacao { get; set; }
|
||||
public double AtuAlturaAreaPulverizacao { get; set; }
|
||||
public double AtuPercentualErvasBicoOn { get; set; }
|
||||
public double AtuPercentualErvasBicoOff { get; set; }
|
||||
|
||||
public bool MpcMatrizCusto { get; set; }
|
||||
public double MpcHorizonte { get; set; } = 4.0;
|
||||
private bool _pulverizadorAutomatico;
|
||||
public bool PulverizadorAutomatico
|
||||
{
|
||||
get => _pulverizadorAutomatico;
|
||||
set
|
||||
{
|
||||
if (_pulverizadorAutomatico != value)
|
||||
{
|
||||
_pulverizadorAutomatico = value;
|
||||
OnPropertyChanged(nameof(PulverizadorAutomatico));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _sonarAtivado;
|
||||
public bool SonarAtivado
|
||||
{
|
||||
get => _sonarAtivado;
|
||||
set
|
||||
{
|
||||
if (_sonarAtivado != value)
|
||||
{
|
||||
_sonarAtivado = value;
|
||||
OnPropertyChanged(nameof(SonarAtivado));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _oakParadaPorObstaculo;
|
||||
public bool OakParadaPorObstaculo
|
||||
{
|
||||
get => _oakParadaPorObstaculo;
|
||||
set
|
||||
{
|
||||
if (_oakParadaPorObstaculo != value)
|
||||
{
|
||||
_oakParadaPorObstaculo = value;
|
||||
OnPropertyChanged(nameof(OakParadaPorObstaculo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _imuParadaPorInclinacao;
|
||||
public bool ImuParadaPorInclinacao
|
||||
{
|
||||
get => _imuParadaPorInclinacao;
|
||||
set
|
||||
{
|
||||
if (_imuParadaPorInclinacao != value)
|
||||
{
|
||||
_imuParadaPorInclinacao = value;
|
||||
OnPropertyChanged(nameof(ImuParadaPorInclinacao));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _frenagemAutomaticaAoParar;
|
||||
public bool FrenagemAutomaticaAoParar
|
||||
{
|
||||
get => _frenagemAutomaticaAoParar;
|
||||
set
|
||||
{
|
||||
if (_frenagemAutomaticaAoParar != value)
|
||||
{
|
||||
_frenagemAutomaticaAoParar = value;
|
||||
OnPropertyChanged(nameof(FrenagemAutomaticaAoParar));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _registrarDadosPosProcessamento;
|
||||
public bool RegistrarDadosPosProcessamento
|
||||
{
|
||||
get => _registrarDadosPosProcessamento;
|
||||
set
|
||||
{
|
||||
if (_registrarDadosPosProcessamento != value)
|
||||
{
|
||||
_registrarDadosPosProcessamento = value;
|
||||
OnPropertyChanged(nameof(RegistrarDadosPosProcessamento));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int _movVelocidadeSErvasPercent;
|
||||
public int MovVelocidadeSErvasPercent
|
||||
{
|
||||
get => _movVelocidadeSErvasPercent;
|
||||
set
|
||||
{
|
||||
if (_movVelocidadeSErvasPercent != value)
|
||||
{
|
||||
_movVelocidadeSErvasPercent = value;
|
||||
OnPropertyChanged(nameof(MovVelocidadeSErvasPercent));
|
||||
OnPropertyChanged(nameof(MovRpmMax));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int MovRpmMax => System.Convert.ToInt32(VariaveisEquipamento.RPM_Max_Roda * (MovVelocidadeSErvasPercent / 100.0));
|
||||
|
||||
private int _movVelocidadeCErvasPercent;
|
||||
public int MovVelocidadeCErvasPercent
|
||||
{
|
||||
get => _movVelocidadeCErvasPercent;
|
||||
set
|
||||
{
|
||||
if (_movVelocidadeCErvasPercent != value)
|
||||
{
|
||||
_movVelocidadeCErvasPercent = value;
|
||||
OnPropertyChanged(nameof(MovVelocidadeCErvasPercent));
|
||||
OnPropertyChanged(nameof(MovRpmMin));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int MovRpmMin => System.Convert.ToInt32(VariaveisEquipamento.RPM_Max_Roda * (MovVelocidadeCErvasPercent / 100.0));
|
||||
|
||||
private int _dirAnguloMaximo;
|
||||
public int DirAnguloMaximo
|
||||
{
|
||||
get => _dirAnguloMaximo;
|
||||
set
|
||||
{
|
||||
if (_dirAnguloMaximo != value)
|
||||
{
|
||||
_dirAnguloMaximo = value;
|
||||
OnPropertyChanged(nameof(DirAnguloMaximo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double _dirVelocidadeMovimento;
|
||||
public double DirVelocidadeMovimento
|
||||
{
|
||||
get => _dirVelocidadeMovimento;
|
||||
set
|
||||
{
|
||||
if (_dirVelocidadeMovimento != value)
|
||||
{
|
||||
_dirVelocidadeMovimento = value;
|
||||
OnPropertyChanged(nameof(DirVelocidadeMovimento));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TiposControladorDirecional _dirTipoMovimento;
|
||||
public TiposControladorDirecional DirTipoMovimento
|
||||
{
|
||||
get => _dirTipoMovimento;
|
||||
set
|
||||
{
|
||||
if (_dirTipoMovimento != value)
|
||||
{
|
||||
_dirTipoMovimento = value;
|
||||
OnPropertyChanged(nameof(DirTipoMovimento));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double _atuPressaoLinha;
|
||||
public double AtuPressaoLinha
|
||||
{
|
||||
get => _atuPressaoLinha;
|
||||
set
|
||||
{
|
||||
if (_atuPressaoLinha != value)
|
||||
{
|
||||
_atuPressaoLinha = value;
|
||||
OnPropertyChanged(nameof(AtuPressaoLinha));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int _atuDuracaoAtuacao;
|
||||
public int AtuDuracaoAtuacao
|
||||
{
|
||||
get => _atuDuracaoAtuacao;
|
||||
set
|
||||
{
|
||||
if (_atuDuracaoAtuacao != value)
|
||||
{
|
||||
_atuDuracaoAtuacao = value;
|
||||
OnPropertyChanged(nameof(AtuDuracaoAtuacao));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double _atuPercentualInicioPulverizacao;
|
||||
public double AtuPercentualInicioPulverizacao
|
||||
{
|
||||
get => _atuPercentualInicioPulverizacao;
|
||||
set
|
||||
{
|
||||
if (_atuPercentualInicioPulverizacao != value)
|
||||
{
|
||||
_atuPercentualInicioPulverizacao = value;
|
||||
OnPropertyChanged(nameof(AtuPercentualInicioPulverizacao));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double _atuAlturaAreaPulverizacao;
|
||||
public double AtuAlturaAreaPulverizacao
|
||||
{
|
||||
get => _atuAlturaAreaPulverizacao;
|
||||
set
|
||||
{
|
||||
if (_atuAlturaAreaPulverizacao != value)
|
||||
{
|
||||
_atuAlturaAreaPulverizacao = value;
|
||||
OnPropertyChanged(nameof(AtuAlturaAreaPulverizacao));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double _atuPercentualErvasBicoOn;
|
||||
public double AtuPercentualErvasBicoOn
|
||||
{
|
||||
get => _atuPercentualErvasBicoOn;
|
||||
set
|
||||
{
|
||||
if (_atuPercentualErvasBicoOn != value)
|
||||
{
|
||||
_atuPercentualErvasBicoOn = value;
|
||||
OnPropertyChanged(nameof(AtuPercentualErvasBicoOn));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double _atuPercentualErvasBicoOff;
|
||||
public double AtuPercentualErvasBicoOff
|
||||
{
|
||||
get => _atuPercentualErvasBicoOff;
|
||||
set
|
||||
{
|
||||
if (_atuPercentualErvasBicoOff != value)
|
||||
{
|
||||
_atuPercentualErvasBicoOff = value;
|
||||
OnPropertyChanged(nameof(AtuPercentualErvasBicoOff));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _mpcMatrizCusto;
|
||||
public bool MpcMatrizCusto
|
||||
{
|
||||
get => _mpcMatrizCusto;
|
||||
set
|
||||
{
|
||||
if (_mpcMatrizCusto != value)
|
||||
{
|
||||
_mpcMatrizCusto = value;
|
||||
OnPropertyChanged(nameof(MpcMatrizCusto));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double _mpcHorizonte = 4.0;
|
||||
public double MpcHorizonte
|
||||
{
|
||||
get => _mpcHorizonte;
|
||||
set
|
||||
{
|
||||
if (_mpcHorizonte != value)
|
||||
{
|
||||
_mpcHorizonte = value;
|
||||
OnPropertyChanged(nameof(MpcHorizonte));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected void OnPropertyChanged(string nome)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||
}
|
||||
}
|
||||
|
||||
public class OperacaoParametrosDadosModel
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ using Mapsui.Manipulations;
|
|||
using Mapsui.Extensions;
|
||||
using OperationControl.Models;
|
||||
using static AgroBase.Models.Enums;
|
||||
using System.Windows.Input;
|
||||
|
||||
|
||||
namespace OperationControl.Controls
|
||||
|
|
@ -66,6 +67,34 @@ namespace OperationControl.Controls
|
|||
set => SetValue(ScaleProperty, value);
|
||||
}
|
||||
|
||||
|
||||
public static readonly DependencyProperty MarkerClickedCommandProperty =
|
||||
DependencyProperty.Register(
|
||||
nameof(MarkerClickedCommand),
|
||||
typeof(ICommand),
|
||||
typeof(MapViewControl),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
public ICommand MarkerClickedCommand
|
||||
{
|
||||
get => (ICommand)GetValue(MarkerClickedCommandProperty);
|
||||
set => SetValue(MarkerClickedCommandProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty StreetMapClickedCommandProperty =
|
||||
DependencyProperty.Register(
|
||||
nameof(StreetMapClickedCommand),
|
||||
typeof(ICommand),
|
||||
typeof(MapViewControl),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
public ICommand StreetMapClickedCommand
|
||||
{
|
||||
get => (ICommand)GetValue(StreetMapClickedCommandProperty);
|
||||
set => SetValue(StreetMapClickedCommandProperty, value);
|
||||
}
|
||||
|
||||
|
||||
#region MARCADORES
|
||||
|
||||
public MapMarkerManager markers;
|
||||
|
|
@ -77,22 +106,36 @@ namespace OperationControl.Controls
|
|||
MarkerClicked?.Invoke(this, new MapMarkerManager.MarkerClickedEventArgs(markerId));
|
||||
}
|
||||
|
||||
private void OnMarkerClickedInternal(MapMarkerManager.MarkerClickedEventArgs e)
|
||||
{
|
||||
MarkerClicked?.Invoke(this, e);
|
||||
|
||||
if (MarkerClickedCommand?.CanExecute(e) == true)
|
||||
MarkerClickedCommand.Execute(e);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
#region RUAS PLANTACAO
|
||||
|
||||
private Layer MapaPlantacao_Layer;
|
||||
public List<StreetMapDictionaryModel> RuasMapaCarregado;
|
||||
|
||||
public event EventHandler<StreetMapClickedEventArgs>? StreetMapClicked;
|
||||
private bool ParametrizandoOperacao => !(VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Iniciada ?? false) && (VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Status ?? StatusOperacao.NaoIniciado) == StatusOperacao.Parametrizando;
|
||||
protected virtual void OnStreetMapClicked(string streetId)
|
||||
{
|
||||
StreetMapClicked?.Invoke(this, new StreetMapClickedEventArgs(streetId, RuasMapaCarregado.Where(x => x.Selected).Select(x => x.Id).ToList()));
|
||||
}
|
||||
|
||||
private void OnStreetMapClickedInternal(StreetMapClickedEventArgs e)
|
||||
{
|
||||
StreetMapClicked?.Invoke(this, e);
|
||||
|
||||
if (StreetMapClickedCommand?.CanExecute(e) == true)
|
||||
StreetMapClickedCommand.Execute(e);
|
||||
}
|
||||
|
||||
private void HighlightRoad(MIFeature? feature = null, string? id = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id))
|
||||
|
|
@ -487,7 +530,7 @@ namespace OperationControl.Controls
|
|||
}
|
||||
else if (info?.Layer == MapaPlantacao_Layer && feat is MIFeature roadFeature)
|
||||
{
|
||||
if (!(VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Iniciada ?? false))
|
||||
if (ParametrizandoOperacao)
|
||||
HighlightRoad(roadFeature);
|
||||
}
|
||||
else
|
||||
|
|
@ -509,7 +552,7 @@ namespace OperationControl.Controls
|
|||
|
||||
if (feat != null && markers != null && markers.TryGetIdFromFeature(feat, out _))
|
||||
Mapa.Cursor = System.Windows.Input.Cursors.Hand;
|
||||
else if (feat != null && info?.Layer == MapaPlantacao_Layer && feat is MIFeature roadFeature)
|
||||
else if (feat != null && info?.Layer == MapaPlantacao_Layer && feat is MIFeature roadFeature && ParametrizandoOperacao)
|
||||
Mapa.Cursor = System.Windows.Input.Cursors.Hand;
|
||||
else
|
||||
Mapa.Cursor = System.Windows.Input.Cursors.Arrow;
|
||||
|
|
@ -756,6 +799,24 @@ namespace OperationControl.Controls
|
|||
NavigateToView();
|
||||
}
|
||||
|
||||
|
||||
public void LoadMapFile(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
|
||||
return;
|
||||
|
||||
if (path.EndsWith(".shp", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var geojson = ConvertShpToGeoJson(path);
|
||||
AddGeoJsonLayer(geojson);
|
||||
}
|
||||
else
|
||||
{
|
||||
var geojson = File.ReadAllText(path);
|
||||
AddGeoJsonLayer(geojson);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
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 OperationControl.Converters
|
||||
{
|
||||
public class BoolToVisibilityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is bool b && b)
|
||||
return Visibility.Visible;
|
||||
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value is Visibility v && v == Visibility.Visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
using AgroBase.Models;
|
||||
using AgroBase.Services;
|
||||
using OperationControl.Services;
|
||||
using OperationControl.ViewModels;
|
||||
using OperationControl.Windows;
|
||||
using System.Diagnostics;
|
||||
using static AgroBase.Models.Enums;
|
||||
|
||||
namespace OperationControl.Models
|
||||
{
|
||||
|
|
@ -55,5 +55,21 @@ namespace OperationControl.Models
|
|||
}
|
||||
}
|
||||
|
||||
public void AdicionarAlertaDock(string roverId, T_Code modulo, SeveridadeAlerta severidade, string mensagem, string modId = null)
|
||||
{
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
(Dock?.DataContext as DockWindowViewModel)?.AdicionarAlerta(roverId, modulo, severidade, mensagem, modId);
|
||||
}));
|
||||
}
|
||||
|
||||
public void RemoverAlertaDock(string roverId, T_Code modulo, SeveridadeAlerta? severidade = null, string modId = null)
|
||||
{
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
(Dock?.DataContext as DockWindowViewModel)?.RemoverAlerta(roverId, modulo, severidade, modId);
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace OperationControl.Models.Operacao
|
||||
{
|
||||
public class ResumoOperacionalModel : INotifyPropertyChanged
|
||||
{
|
||||
private string _operacao;
|
||||
private string _modo;
|
||||
private string _status;
|
||||
private string _carro;
|
||||
private string _temperatura;
|
||||
private string _ruaAtual;
|
||||
private string _areaTotal;
|
||||
private string _bateria;
|
||||
private string _herbicida;
|
||||
private string _infestacao;
|
||||
private string _conexao;
|
||||
private string _duracao;
|
||||
|
||||
private double _ruaAtualPercentual;
|
||||
private double _areaTotalPercentual;
|
||||
private double _bateriaPercentual;
|
||||
private double _herbicidaPercentual;
|
||||
private double _infestacaoPercentual;
|
||||
|
||||
public string Operacao { get => _operacao; set => SetField(ref _operacao, value); }
|
||||
public string Modo { get => _modo; set => SetField(ref _modo, value); }
|
||||
public string Status { get => _status; set => SetField(ref _status, value); }
|
||||
public string Carro { get => _carro; set => SetField(ref _carro, value); }
|
||||
public string Temperatura { get => _temperatura; set => SetField(ref _temperatura, value); }
|
||||
public string RuaAtual { get => _ruaAtual; set => SetField(ref _ruaAtual, value); }
|
||||
public string AreaTotal { get => _areaTotal; set => SetField(ref _areaTotal, value); }
|
||||
public string Bateria { get => _bateria; set => SetField(ref _bateria, value); }
|
||||
public string Herbicida { get => _herbicida; set => SetField(ref _herbicida, value); }
|
||||
public string Infestacao { get => _infestacao; set => SetField(ref _infestacao, value); }
|
||||
public string Conexao { get => _conexao; set => SetField(ref _conexao, value); }
|
||||
public string Duracao { get => _duracao; set => SetField(ref _duracao, value); }
|
||||
|
||||
public double RuaAtualPercentual { get => _ruaAtualPercentual; set => SetField(ref _ruaAtualPercentual, value); }
|
||||
public double AreaTotalPercentual { get => _areaTotalPercentual; set => SetField(ref _areaTotalPercentual, value); }
|
||||
public double BateriaPercentual { get => _bateriaPercentual; set => SetField(ref _bateriaPercentual, value); }
|
||||
public double HerbicidaPercentual { get => _herbicidaPercentual; set => SetField(ref _herbicidaPercentual, value); }
|
||||
public double InfestacaoPercentual { get => _infestacaoPercentual; set => SetField(ref _infestacaoPercentual, value); }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
|
||||
{
|
||||
if (Equals(field, value)) return false;
|
||||
field = value;
|
||||
OnPropertyChanged(propertyName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ using OperationControl.Services;
|
|||
using AgroMonitor;
|
||||
using Application = System.Windows.Application;
|
||||
using AgroBase.Models.Operacoes;
|
||||
using OperationControl.ViewModels;
|
||||
|
||||
namespace OperationControl.Models
|
||||
{
|
||||
|
|
@ -150,9 +151,10 @@ namespace OperationControl.Models
|
|||
if (string.IsNullOrEmpty(json)) return;
|
||||
var obj = JsonConvert.DeserializeObject<OperacaoParametrosDadosModel>(json);
|
||||
if (obj == null) return;
|
||||
OperacaoParametrosModel rover;
|
||||
lock (_RoversLock)
|
||||
{
|
||||
var rover = RoversNaRede.FirstOrDefault(x => x.RoverId == device_id);
|
||||
rover = RoversNaRede.FirstOrDefault(x => x.RoverId == device_id);
|
||||
if (rover != null)
|
||||
{
|
||||
obj.Momento = DateTime.Now;
|
||||
|
|
@ -163,6 +165,11 @@ namespace OperationControl.Models
|
|||
}
|
||||
}
|
||||
((App)Application.Current).Shell.Main?.AtualizarDadosTela_Telemetria(device_id);
|
||||
|
||||
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
(((App)Application.Current).Shell.Dock?.DataContext as DockWindowViewModel)?.AtualizarDadosTela(rover);
|
||||
}));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -191,6 +198,7 @@ namespace OperationControl.Models
|
|||
}
|
||||
((App)Application.Current).Shell.Main?.AtualizarDadosTela_ParametrosOperacao(obj.Controle);
|
||||
((App)Application.Current).Shell.Main?.MAP?.CarregarDadosMapa(obj.Mapa, obj.RuasPercorrer);
|
||||
((App)Application.Current).Shell.Dock?._vm?.AtualizarDadosMapa(obj);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -239,12 +247,19 @@ namespace OperationControl.Models
|
|||
rover.DadosLeitura.Operacao.Status = AgroBase.Models.Enums.StatusOperacao.Erro;
|
||||
((App)Application.Current).Shell.Main?.AtualizarDadosTela_Telemetria(rover.RoverId);
|
||||
((App)Application.Current).Shell.Main?.AdicionarAlerta(rover.RoverId, AgroBase.Models.Enums.T_Code.Ipb, SeveridadeAlerta.Critical, "Perda de comunicação com o equipamento!");
|
||||
((App)Application.Current).Shell?.AdicionarAlertaDock(rover.RoverId, AgroBase.Models.Enums.T_Code.Ipb, SeveridadeAlerta.Critical, "Perda de comunicação com o equipamento!");
|
||||
}
|
||||
else
|
||||
{
|
||||
((App)Application.Current).Shell.Main?.RemoverAlerta(rover.RoverId, AgroBase.Models.Enums.T_Code.Ipb);
|
||||
((App)Application.Current).Shell.RemoverAlertaDock(rover.RoverId, AgroBase.Models.Enums.T_Code.Ipb);
|
||||
}
|
||||
}
|
||||
|
||||
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
((App)Application.Current).Shell.Dock?._vm?.AtualizarListaRovers(rovers_atual);
|
||||
}));
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,7 +43,31 @@
|
|||
<Compile Update="Controls\TemperatureIndicator.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Views\ConfigConexaoView.xaml.cs">
|
||||
<Compile Update="Views\ConfigConexao\ConfigConexaoView.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Views\Operacao\OperacaoBottomView.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Views\Operacao\OperacaoCenterView.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Views\Operacao\OperacaoLeftView.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Views\Operacao\OperacaoRightView.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Views\Operacao\OperacaoTopView.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Views\PreparacaoMapa\PreparacaoMapaBottomView.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Views\PreparacaoMapa\PreparacaoMapaTopView.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Views\PreparacaoMapa\PreparacaoMapaView.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Windows\DockWindow.xaml.cs">
|
||||
|
|
@ -90,7 +114,31 @@
|
|||
<Page Update="Controls\TemperatureIndicator.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\ConfigConexaoView.xaml">
|
||||
<Page Update="Views\ConfigConexao\ConfigConexaoView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\Operacao\OperacaoBottomView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\Operacao\OperacaoCenterView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\Operacao\OperacaoLeftView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\Operacao\OperacaoRightView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\Operacao\OperacaoTopView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\PreparacaoMapa\PreparacaoMapaBottomView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\PreparacaoMapa\PreparacaoMapaTopView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\PreparacaoMapa\PreparacaoMapaView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Windows\DockWindow.xaml">
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ using AgroBase.Models;
|
|||
using static AgroBase.Models.Enums;
|
||||
using OperationControl.Models;
|
||||
using Application = System.Windows.Application;
|
||||
using Mapsui.Animations;
|
||||
using OperationControl.ViewModels;
|
||||
|
||||
namespace OperationControl.Services
|
||||
{
|
||||
|
|
@ -245,7 +247,7 @@ namespace OperationControl.Services
|
|||
Models.Variaveis.MostrarLog("Iniciando configuração do módulo GPS...");
|
||||
LeverArm = new GeoLeverArm(VariaveisControleOperacao.LeverArmFrontal, VariaveisControleOperacao.LeverArmLateral);
|
||||
BaseFix = new BaseFixService(PortaGps, this);
|
||||
BaseFix.FixLiberado = true;
|
||||
BaseFix.FixLiberado = fixar;
|
||||
if (fixar)
|
||||
{
|
||||
bool sucesso = await BaseFix.FixarBaseViaNtripAsync(
|
||||
|
|
@ -1137,6 +1139,8 @@ namespace OperationControl.Services
|
|||
try
|
||||
{
|
||||
((App)Application.Current).Shell.Main?.AtualizarDadosTela_Telemetria(VariaveisControleOperacao.BaseMarkerID);
|
||||
|
||||
((App)Application.Current).Shell.Dock?._vm?.AtualizarDadosGnss(UltimaLeitura);
|
||||
}
|
||||
catch (Exception exUi)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,118 +0,0 @@
|
|||
using System.ComponentModel;
|
||||
using System.Windows.Input;
|
||||
using System.Windows;
|
||||
using OperationControl.Views;
|
||||
using OperationControl.Helpers;
|
||||
using OperationControl.Models;
|
||||
|
||||
namespace OperationControl.ViewModels
|
||||
{
|
||||
public class DockWindowViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private readonly ConfigConexaoView _viewConfig;
|
||||
|
||||
public DockWindowViewModel()
|
||||
{
|
||||
// 1) Cria a view do passo 1
|
||||
_viewConfig = new ConfigConexaoView();
|
||||
|
||||
// 2) Escuta quando RedeOk && GnssOk mudar
|
||||
_viewConfig._vm.TudoOkChanged += OnTudoOkChanged;
|
||||
|
||||
// 3) Conteúdo inicial
|
||||
CenterContent = _viewConfig;
|
||||
TopContent = null;
|
||||
BottomContent = null;
|
||||
|
||||
// 4) Commands já usando CanGoBack / CanGoNext
|
||||
BackCommand = new RelayCommand(_ => GoBack(), _ => CanGoBack);
|
||||
NextCommand = new RelayCommand(_ => GoNext(), _ => CanGoNext);
|
||||
|
||||
// 5) Estado inicial do Next (caso já venha tudo ok no boot)
|
||||
ConfigConexaoOk = _viewConfig._vm.TudoOk;
|
||||
}
|
||||
|
||||
private void OnTudoOkChanged(bool ok)
|
||||
{
|
||||
ConfigConexaoOk = ok;
|
||||
|
||||
// avisa bindings
|
||||
OnPropertyChanged(nameof(CanGoNext));
|
||||
|
||||
// força o WPF a reavaliar CanExecute dos botões
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
|
||||
// ====== ESTADO ======
|
||||
private bool _configConexaoOk;
|
||||
public bool ConfigConexaoOk
|
||||
{
|
||||
get => _configConexaoOk;
|
||||
set
|
||||
{
|
||||
if (_configConexaoOk != value)
|
||||
{
|
||||
_configConexaoOk = value;
|
||||
OnPropertyChanged(nameof(ConfigConexaoOk));
|
||||
OnPropertyChanged(nameof(CanGoNext));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanGoBack => false; // passo 1 não volta
|
||||
public bool CanGoNext => ConfigConexaoOk; // libera quando tudo ok
|
||||
|
||||
// ====== CONTEÚDOS ======
|
||||
private object _centerContent;
|
||||
public object CenterContent
|
||||
{
|
||||
get => _centerContent;
|
||||
set { _centerContent = value; OnPropertyChanged(nameof(CenterContent)); }
|
||||
}
|
||||
|
||||
private object _topContent;
|
||||
public object TopContent
|
||||
{
|
||||
get => _topContent;
|
||||
set { _topContent = value; OnPropertyChanged(nameof(TopContent)); }
|
||||
}
|
||||
|
||||
private object _bottomContent;
|
||||
public object BottomContent
|
||||
{
|
||||
get => _bottomContent;
|
||||
set { _bottomContent = value; OnPropertyChanged(nameof(BottomContent)); }
|
||||
}
|
||||
|
||||
// ====== COMMANDS ======
|
||||
public ICommand BackCommand { get; }
|
||||
public ICommand NextCommand { get; }
|
||||
|
||||
private void GoBack()
|
||||
{
|
||||
// depois você implementa quando tiver passo 2/3
|
||||
}
|
||||
|
||||
private void GoNext()
|
||||
{
|
||||
if (!CanGoNext) return;
|
||||
|
||||
// Aqui depois você troca para a próxima tela:
|
||||
// CenterContent = new FixacaoBaseView();
|
||||
// e atualiza CanGoBack/CanGoNext conforme o step
|
||||
|
||||
//System.Windows.MessageBox.Show("Avançou! Próximo passo: Fixação da Base (ainda vamos implementar).");
|
||||
|
||||
((App)System.Windows.Application.Current).Shell.Dock?.Hide();
|
||||
((App)System.Windows.Application.Current).Shell.Main?.Show();
|
||||
}
|
||||
|
||||
// ====== INotifyPropertyChanged ======
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void OnPropertyChanged(string nome)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,9 @@ namespace OperationControl.ViewModels
|
|||
AbrirConfigRedeCommand = new RelayCommand(_ => AbrirConfigRede());
|
||||
AbrirDetalhesGnssCommand = new RelayCommand(_ => AbrirDetalhesGnss());
|
||||
|
||||
SelecionarModoAutomaticoCommand = new RelayCommand(_ => TipoOperacaoSelecionado = ModoOperacao.Automatico);
|
||||
SelecionarModoManualCommand = new RelayCommand(_ => TipoOperacaoSelecionado = ModoOperacao.Manual);
|
||||
|
||||
// aqui você já pode chamar um serviço real depois
|
||||
CarregarStatusInicial();
|
||||
|
||||
|
|
@ -27,6 +30,42 @@ namespace OperationControl.ViewModels
|
|||
_timerGnss.Start();
|
||||
}
|
||||
|
||||
// ====== PROPRIEDADES DE MODO DE OPERACAO ======
|
||||
|
||||
private ModoOperacao _tipoOperacaoSelecionado = ModoOperacao.Automatico;
|
||||
public ModoOperacao TipoOperacaoSelecionado
|
||||
{
|
||||
get => _tipoOperacaoSelecionado;
|
||||
set
|
||||
{
|
||||
if (_tipoOperacaoSelecionado != value)
|
||||
{
|
||||
_tipoOperacaoSelecionado = value;
|
||||
OnPropertyChanged(nameof(TipoOperacaoSelecionado));
|
||||
OnPropertyChanged(nameof(OperacaoAutomaticaSelecionada));
|
||||
OnPropertyChanged(nameof(OperacaoManualSelecionada));
|
||||
OnPropertyChanged(nameof(DescricaoModoOperacao));
|
||||
OnPropertyChanged(nameof(MensagemGeral));
|
||||
OnPropertyChanged(nameof(PodeAvancar));
|
||||
OnTudoOkChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool OperacaoAutomaticaSelecionada => TipoOperacaoSelecionado == ModoOperacao.Automatico;
|
||||
public bool OperacaoManualSelecionada => TipoOperacaoSelecionado == ModoOperacao.Manual;
|
||||
|
||||
public bool PodeAvancar =>
|
||||
TipoOperacaoSelecionado == ModoOperacao.Automatico
|
||||
? RedeOk && GnssOk
|
||||
: RedeOk;
|
||||
public string DescricaoModoOperacao =>
|
||||
TipoOperacaoSelecionado == ModoOperacao.Automatico
|
||||
? "Operação autônoma. Exige rede e GNSS conectados. Na próxima etapa, será necessário carregar o mapa e fixar a base."
|
||||
: "Operação manual. Exige apenas rede conectada. O sistema pulará a preparação de mapa e base, liberando apenas funções manuais.";
|
||||
|
||||
|
||||
|
||||
// ====== PROPRIEDADES DE REDE ======
|
||||
|
||||
private bool _redeOk;
|
||||
|
|
@ -100,14 +139,34 @@ namespace OperationControl.ViewModels
|
|||
private string _mensagemGeral;
|
||||
public string MensagemGeral
|
||||
{
|
||||
get => _mensagemGeral;
|
||||
set { _mensagemGeral = value; OnPropertyChanged(nameof(MensagemGeral)); }
|
||||
get
|
||||
{
|
||||
if (TipoOperacaoSelecionado == ModoOperacao.Automatico)
|
||||
{
|
||||
if (!RedeOk && !GnssOk)
|
||||
return "Conecte a rede e o GNSS para iniciar uma operação automática.";
|
||||
if (!RedeOk)
|
||||
return "Ajuste a rede para avançar.";
|
||||
if (!GnssOk)
|
||||
return "Conecte o GNSS para avançar na operação automática.";
|
||||
|
||||
return "Tudo OK. Você pode avançar para a preparação do mapa e fixação da base.";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!RedeOk)
|
||||
return "Ajuste a rede para habilitar o modo manual.";
|
||||
return "Rede OK. Você pode avançar diretamente para a parametrização manual do rover.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ====== COMANDOS ======
|
||||
|
||||
public ICommand AbrirConfigRedeCommand { get; }
|
||||
public ICommand AbrirDetalhesGnssCommand { get; }
|
||||
public ICommand SelecionarModoAutomaticoCommand { get; }
|
||||
public ICommand SelecionarModoManualCommand { get; }
|
||||
|
||||
private void AbrirConfigRede()
|
||||
{
|
||||
|
|
@ -118,12 +177,15 @@ namespace OperationControl.ViewModels
|
|||
|
||||
private void AbrirDetalhesGnss()
|
||||
{
|
||||
MessageBox.Show("Aqui vai abrir uma tela com detalhes do GNSS/UM982.");
|
||||
string msg = Variaveis.GpsService.IsConnected ?
|
||||
$"Conectado à porta {Variaveis.GpsService.PortName}" :
|
||||
$"Não conectado";
|
||||
MessageBox.Show(msg);
|
||||
}
|
||||
|
||||
// ====== STATUS GERAL PARA AVANÇAR ======
|
||||
|
||||
public bool TudoOk => RedeOk && GnssOk;
|
||||
public bool TudoOk => PodeAvancar;
|
||||
|
||||
// Evento para o DockWindow saber quando ficou tudo ok
|
||||
public event Action<bool> TudoOkChanged;
|
||||
|
|
@ -158,13 +220,12 @@ namespace OperationControl.ViewModels
|
|||
// double? hdop = GnssService.Hdop();
|
||||
|
||||
bool conectado = Variaveis.GpsService?.IsConnected ?? false; // <-- seu método real aqui
|
||||
//conectado = true;
|
||||
conectado = true;
|
||||
|
||||
if (!conectado)
|
||||
{
|
||||
GnssOk = false;
|
||||
DetalhesGnss = "UM982 não detectado. Verifique cabo USB e alimentação.";
|
||||
MensagemGeral = "Conecte o GNSS e ajuste a rede para avançar.";
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -174,17 +235,11 @@ namespace OperationControl.ViewModels
|
|||
// Se você tiver mais infos, mostra aqui:
|
||||
// DetalhesGnss = $"Conectado ({porta}) | Fix: {fix} | HDOP: {hdop:0.0}";
|
||||
DetalhesGnss = "Conectado. Recebendo dados GNSS.";
|
||||
|
||||
// Mensagem geral pode ficar mais positiva se Rede também estiver ok
|
||||
MensagemGeral = TudoOk
|
||||
? "Tudo OK. Você pode avançar para a fixação da base."
|
||||
: "GNSS OK. Agora ajuste a rede para avançar.";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
GnssOk = false;
|
||||
DetalhesGnss = "Erro ao verificar GNSS: " + ex.Message;
|
||||
MensagemGeral = "Erro ao ler GNSS. Verifique conexões.";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -206,7 +261,7 @@ namespace OperationControl.ViewModels
|
|||
|
||||
// 2) Define RedeOk do jeito que faz sentido pra você:
|
||||
// exemplo simples: tem IP válido + gateway válido
|
||||
RedeOk = !string.IsNullOrWhiteSpace(ip) && !string.IsNullOrWhiteSpace(gw);
|
||||
RedeOk = !string.IsNullOrWhiteSpace(ip) && ip != "0.0.0.0";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
using OperationControl.Models;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Threading;
|
||||
using static AgroBase.Models.Enums;
|
||||
using Application = System.Windows.Application;
|
||||
|
||||
namespace OperationControl.ViewModels.Views.Operacao
|
||||
{
|
||||
public class OperacaoBottomViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private AlertaModel _toastAlerta;
|
||||
private AlertaModel _alertaSelecionado;
|
||||
private readonly DispatcherTimer _toastTimer;
|
||||
|
||||
public OperacaoBottomViewModel()
|
||||
{
|
||||
AlertasAtivos = new ObservableCollection<AlertaModel>();
|
||||
|
||||
_toastTimer = new DispatcherTimer
|
||||
{
|
||||
Interval = TimeSpan.FromSeconds(5)
|
||||
};
|
||||
|
||||
_toastTimer.Tick += (s, e) =>
|
||||
{
|
||||
_toastTimer.Stop();
|
||||
ToastAlerta = null;
|
||||
};
|
||||
}
|
||||
|
||||
public ObservableCollection<AlertaModel> AlertasAtivos { get; }
|
||||
|
||||
public AlertaModel ToastAlerta
|
||||
{
|
||||
get => _toastAlerta;
|
||||
set
|
||||
{
|
||||
if (_toastAlerta != value)
|
||||
{
|
||||
_toastAlerta = value;
|
||||
OnPropertyChanged(nameof(ToastAlerta));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AlertaModel AlertaSelecionado
|
||||
{
|
||||
get => _alertaSelecionado;
|
||||
set
|
||||
{
|
||||
if (_alertaSelecionado != value)
|
||||
{
|
||||
_alertaSelecionado = value;
|
||||
OnPropertyChanged(nameof(AlertaSelecionado));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
public event Action<AlertaModel> AlertaSelecionadoChanged;
|
||||
|
||||
public void SelecionarAlerta(AlertaModel alerta)
|
||||
{
|
||||
if (alerta == null) return;
|
||||
|
||||
AlertaSelecionado = alerta;
|
||||
AlertaSelecionadoChanged?.Invoke(alerta);
|
||||
}
|
||||
|
||||
public void AdicionarAlerta(string roverId, T_Code modulo, SeveridadeAlerta severidade, string mensagem, string modId = null)
|
||||
{
|
||||
if (!Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
AdicionarAlerta(roverId, modulo, severidade, mensagem, modId)));
|
||||
return;
|
||||
}
|
||||
|
||||
var existente = AlertasAtivos.FirstOrDefault(x =>
|
||||
x.Rover_ID == roverId &&
|
||||
x.Modulo == modulo &&
|
||||
x.Mod_ID == modId);
|
||||
|
||||
if (existente == null)
|
||||
{
|
||||
var alerta = new AlertaModel
|
||||
{
|
||||
Rover_ID = roverId,
|
||||
Modulo = modulo,
|
||||
Mod_ID = modId,
|
||||
Severidade = severidade,
|
||||
Mensagem = mensagem,
|
||||
Timestamp = DateTime.Now
|
||||
};
|
||||
|
||||
AlertasAtivos.Insert(0, alerta);
|
||||
MostrarToast(alerta);
|
||||
}
|
||||
else
|
||||
{
|
||||
existente.Mensagem = mensagem;
|
||||
existente.Severidade = severidade;
|
||||
existente.Timestamp = DateTime.Now;
|
||||
|
||||
// caso o model nao implemente INotifyPropertyChanged,
|
||||
// forçamos um refresh simples:
|
||||
RecarregarAlerta(existente);
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(AlertasAtivos));
|
||||
}
|
||||
|
||||
public void RemoverAlerta(string roverId, T_Code modulo, SeveridadeAlerta? severidade = null, string modId = null)
|
||||
{
|
||||
if (!Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
RemoverAlerta(roverId, modulo, severidade, modId)));
|
||||
return;
|
||||
}
|
||||
|
||||
var alerta = AlertasAtivos.FirstOrDefault(x =>
|
||||
x.Rover_ID == roverId &&
|
||||
x.Modulo == modulo &&
|
||||
x.Mod_ID == modId &&
|
||||
(severidade != null ? x.Severidade == severidade : true));
|
||||
|
||||
if (alerta != null)
|
||||
{
|
||||
AlertasAtivos.Remove(alerta);
|
||||
|
||||
if (ReferenceEquals(ToastAlerta, alerta))
|
||||
ToastAlerta = null;
|
||||
|
||||
if (ReferenceEquals(AlertaSelecionado, alerta))
|
||||
AlertaSelecionado = null;
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(AlertasAtivos));
|
||||
}
|
||||
|
||||
public void MostrarToast(AlertaModel alerta)
|
||||
{
|
||||
ToastAlerta = alerta;
|
||||
_toastTimer.Stop();
|
||||
_toastTimer.Start();
|
||||
}
|
||||
|
||||
public void LimparToast()
|
||||
{
|
||||
_toastTimer.Stop();
|
||||
ToastAlerta = null;
|
||||
}
|
||||
|
||||
public void DefinirAlertas(params AlertaModel[] alertas)
|
||||
{
|
||||
if (!Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
Application.Current.Dispatcher.BeginInvoke(new Action(() => DefinirAlertas(alertas)));
|
||||
return;
|
||||
}
|
||||
|
||||
AlertasAtivos.Clear();
|
||||
|
||||
if (alertas != null)
|
||||
{
|
||||
foreach (var alerta in alertas)
|
||||
AlertasAtivos.Add(alerta);
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(AlertasAtivos));
|
||||
}
|
||||
|
||||
private void RecarregarAlerta(AlertaModel alerta)
|
||||
{
|
||||
var idx = AlertasAtivos.IndexOf(alerta);
|
||||
if (idx >= 0)
|
||||
{
|
||||
AlertasAtivos.RemoveAt(idx);
|
||||
AlertasAtivos.Insert(idx, alerta);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPropertyChanged(string nome)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void AtualizarListaAlertasRoverSelecionado(string rover_id)
|
||||
{
|
||||
var rover = VariaveisControleOperacao.RoversNaRede.FirstOrDefault(x => x.RoverId == rover_id);
|
||||
if (rover == null) return;
|
||||
var dados_leitura = rover?.DadosLeitura;
|
||||
if (dados_leitura?.ModulosSaude == null) return;
|
||||
|
||||
SeveridadeAlerta DeParaStatus(StatusModulo status, bool mandatorio)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case StatusModulo.Operante:
|
||||
return SeveridadeAlerta.Info;
|
||||
case StatusModulo.Alerta:
|
||||
return SeveridadeAlerta.Warning;
|
||||
case StatusModulo.Falha:
|
||||
return mandatorio ? SeveridadeAlerta.Critical : SeveridadeAlerta.Error;
|
||||
case StatusModulo.Conectado:
|
||||
return mandatorio ? SeveridadeAlerta.Warning : SeveridadeAlerta.Info;
|
||||
case StatusModulo.Desconectado:
|
||||
return mandatorio ? SeveridadeAlerta.Critical : SeveridadeAlerta.Error;
|
||||
default:
|
||||
return SeveridadeAlerta.Info;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var mod in dados_leitura.ModulosSaude)
|
||||
{
|
||||
if (mod.saude_individual.Any())
|
||||
{
|
||||
foreach (var ind in mod.saude_individual)
|
||||
{
|
||||
if (ind.status != StatusModulo.Operante)
|
||||
{
|
||||
AdicionarAlerta(rover.RoverId, mod.modulo, DeParaStatus(ind.status, ind.em_uso), string.Join(", ", ind.motivos), modId: ind.label);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoverAlerta(rover.RoverId, mod.modulo, modId: ind.label);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mod.status != StatusModulo.Operante)
|
||||
{
|
||||
AdicionarAlerta(rover.RoverId, mod.modulo, DeParaStatus(mod.status, rover.ModulosMandatorios?.Any(x => x.Dispositivo == mod.modulo && x.Mandatorio) ?? false), string.Join(", ", mod.motivos));
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoverAlerta(rover.RoverId, mod.modulo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
using OperationControl.Controls;
|
||||
using OperationControl.Models;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace OperationControl.ViewModels.Views.Operacao
|
||||
{
|
||||
public class OperacaoCenterViewModel : INotifyPropertyChanged
|
||||
{
|
||||
|
||||
|
||||
public OperacaoCenterViewModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public event Action<string> RoverSelecionadoChanged;
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
private RoverCardModel? roverSelecionado;
|
||||
private bool _comRoverSelecionado;
|
||||
public bool ComRoverSelecionado
|
||||
{
|
||||
get => _comRoverSelecionado;
|
||||
set
|
||||
{
|
||||
if (_comRoverSelecionado != value)
|
||||
{
|
||||
_comRoverSelecionado = value;
|
||||
OnPropertyChanged(nameof(ComRoverSelecionado));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private OperacaoCenterConteudo _conteudoAtual = OperacaoCenterConteudo.Mapa;
|
||||
public OperacaoCenterConteudo ConteudoAtual
|
||||
{
|
||||
get => _conteudoAtual;
|
||||
set
|
||||
{
|
||||
_conteudoAtual = value;
|
||||
OnPropertyChanged(nameof(ConteudoAtual));
|
||||
OnPropertyChanged(nameof(ExibirMapa));
|
||||
OnPropertyChanged(nameof(ExibirDiagnostico));
|
||||
OnPropertyChanged(nameof(ExibirMonitoramento));
|
||||
OnPropertyChanged(nameof(TituloCentro));
|
||||
OnPropertyChanged(nameof(SubtituloCentro));
|
||||
}
|
||||
}
|
||||
|
||||
public bool ExibirMapa => ConteudoAtual == OperacaoCenterConteudo.Mapa;
|
||||
public bool ExibirDiagnostico => ConteudoAtual == OperacaoCenterConteudo.Diagnostico;
|
||||
public bool ExibirMonitoramento => ConteudoAtual == OperacaoCenterConteudo.Monitoramento;
|
||||
|
||||
public string TituloCentro
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ComRoverSelecionado)
|
||||
return "Nenhum rover selecionado";
|
||||
|
||||
return ConteudoAtual switch
|
||||
{
|
||||
OperacaoCenterConteudo.Diagnostico => "Diagnóstico do Rover",
|
||||
OperacaoCenterConteudo.Monitoramento => "Monitoramento do Rover",
|
||||
OperacaoCenterConteudo.Mapa => "Mapa da Operação",
|
||||
_ => "Área Principal da Operação"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public string SubtituloCentro
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ComRoverSelecionado)
|
||||
return "Selecione um rover para visualizar os dados.";
|
||||
|
||||
return ConteudoAtual switch
|
||||
{
|
||||
OperacaoCenterConteudo.Diagnostico => "Aqui serão exibidos os dados de diagnóstico do rover selecionado.",
|
||||
OperacaoCenterConteudo.Monitoramento => "Aqui serão exibidos os dados de monitoramento em tempo real do rover.",
|
||||
OperacaoCenterConteudo.Mapa => "Aqui será exibido o mapa e os dados operacionais do rover selecionado.",
|
||||
_ => "Conteúdo da operação."
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void SelecionarRoverLista(RoverCardModel? rover)
|
||||
{
|
||||
roverSelecionado = rover;
|
||||
ComRoverSelecionado = roverSelecionado != null;
|
||||
DefinirSecao(ComRoverSelecionado ? SecaoRightBar.Menu : SecaoRightBar.SemRoverSelecionado);
|
||||
}
|
||||
|
||||
public void DefinirSecao(SecaoRightBar secao)
|
||||
{
|
||||
ConteudoAtual = secao switch
|
||||
{
|
||||
SecaoRightBar.Diagnostico => OperacaoCenterConteudo.Diagnostico,
|
||||
|
||||
SecaoRightBar.Resumo => OperacaoCenterConteudo.Monitoramento,
|
||||
SecaoRightBar.Controle => OperacaoCenterConteudo.Monitoramento,
|
||||
SecaoRightBar.Parametrizacao => OperacaoCenterConteudo.Mapa,
|
||||
SecaoRightBar.Menu => OperacaoCenterConteudo.Monitoramento,
|
||||
|
||||
_ => OperacaoCenterConteudo.Mapa
|
||||
};
|
||||
}
|
||||
|
||||
private void OnPropertyChanged(string nome)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void ProcessarMarkerClicked(MapMarkerManager.MarkerClickedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(e.MarkerId))
|
||||
{
|
||||
Variaveis.MostrarLog("Sem rover em foco");
|
||||
RoverSelecionadoChanged?.Invoke(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
Variaveis.MostrarLog($"Rover em foco: {e.MarkerId}");
|
||||
RoverSelecionadoChanged?.Invoke(e.MarkerId);
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessarStreetMapClicked(MapViewControl.StreetMapClickedEventArgs e)
|
||||
{
|
||||
Variaveis.MostrarLog($"Rua clicada: {e.StreetId}. Ruas selecionadas: {string.Join(",", e.SelectedStreetsIds)}");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public enum OperacaoCenterConteudo
|
||||
{
|
||||
Mapa = 1,
|
||||
Diagnostico = 2,
|
||||
Monitoramento = 3
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,349 @@
|
|||
using OperationControl.Helpers;
|
||||
using OperationControl.Models;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using static AgroBase.Models.Enums;
|
||||
|
||||
namespace OperationControl.ViewModels.Views.Operacao
|
||||
{
|
||||
public class OperacaoLeftViewModel : INotifyPropertyChanged
|
||||
{
|
||||
public ICommand AlternarOperacaoCommand { get; }
|
||||
public ICommand ParadaEmergenciaCommand { get; }
|
||||
public ICommand CancelarOperacaoCommand { get; }
|
||||
private bool _operacaoEmExecucao;
|
||||
public bool OperacaoEmExecucao
|
||||
{
|
||||
get => _operacaoEmExecucao;
|
||||
set
|
||||
{
|
||||
if (_operacaoEmExecucao != value)
|
||||
{
|
||||
_operacaoEmExecucao = value;
|
||||
OnPropertyChanged(nameof(OperacaoEmExecucao));
|
||||
OnPropertyChanged(nameof(TextoBotaoOperacao));
|
||||
OnPropertyChanged(nameof(CorBotaoOperacao));
|
||||
OnPropertyChanged(nameof(BordaBotaoOperacao));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string TextoBotaoOperacao => OperacaoEmExecucao ? "⏸ Pausar Operação" : "▶ Iniciar Operação";
|
||||
|
||||
public System.Windows.Media.Brush CorBotaoOperacao =>
|
||||
OperacaoEmExecucao
|
||||
? new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(120, 88, 20))
|
||||
: new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(30, 90, 58));
|
||||
|
||||
public System.Windows.Media.Brush BordaBotaoOperacao =>
|
||||
OperacaoEmExecucao
|
||||
? new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(170, 130, 40))
|
||||
: new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(74, 138, 91));
|
||||
|
||||
|
||||
private bool _roverSelecionado;
|
||||
public bool RoverSelecionado
|
||||
{
|
||||
get => _roverSelecionado;
|
||||
set
|
||||
{
|
||||
if (_roverSelecionado != value)
|
||||
{
|
||||
_roverSelecionado = value;
|
||||
OnPropertyChanged(nameof(RoverSelecionado));
|
||||
OnPropertyChanged(nameof(NomeRover));
|
||||
OnPropertyChanged(nameof(OpacityPainel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _nomeRover = "Nenhum rover selecionado";
|
||||
public string NomeRover
|
||||
{
|
||||
get => RoverSelecionado ? _nomeRover : "Nenhum rover selecionado";
|
||||
set
|
||||
{
|
||||
if (_nomeRover != value)
|
||||
{
|
||||
_nomeRover = value;
|
||||
OnPropertyChanged(nameof(NomeRover));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double OpacityPainel => RoverSelecionado ? 1.0 : 0.45;
|
||||
|
||||
private string _velocidade = "--";
|
||||
public string Velocidade
|
||||
{
|
||||
get => VelocidadeValor(_velocidade);
|
||||
set
|
||||
{
|
||||
if (_velocidade != value)
|
||||
{
|
||||
_velocidade = value;
|
||||
OnPropertyChanged(nameof(Velocidade));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _anguloDirecional = "--";
|
||||
public string AnguloDirecional
|
||||
{
|
||||
get => RoverSelecionado ? $"{_anguloDirecional}°" : "--";
|
||||
set
|
||||
{
|
||||
if (_anguloDirecional != value)
|
||||
{
|
||||
_anguloDirecional = value;
|
||||
OnPropertyChanged(nameof(AnguloDirecional));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TipoMovimentoDirecional _tipoMovimento = TipoMovimentoDirecional.Diagnostico;
|
||||
public TipoMovimentoDirecional TipoMovimento
|
||||
{
|
||||
get => _tipoMovimento;
|
||||
set
|
||||
{
|
||||
if (_tipoMovimento != value)
|
||||
{
|
||||
_tipoMovimento = value;
|
||||
OnPropertyChanged(nameof(TipoMovimento));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _temperatura = "--";
|
||||
public string Temperatura
|
||||
{
|
||||
get => TemperaturaValor(_temperatura);
|
||||
set
|
||||
{
|
||||
if (_temperatura != value)
|
||||
{
|
||||
_temperatura = value;
|
||||
OnPropertyChanged(nameof(Temperatura));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _bateria = "--";
|
||||
public string Bateria
|
||||
{
|
||||
get => PercentualOuTracos(_bateria);
|
||||
set
|
||||
{
|
||||
if (_bateria != value)
|
||||
{
|
||||
_bateria = value;
|
||||
OnPropertyChanged(nameof(Bateria));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _reservatorio = "--";
|
||||
public string Reservatorio
|
||||
{
|
||||
get => PercentualOuTracos(_reservatorio);
|
||||
set
|
||||
{
|
||||
if (_reservatorio != value)
|
||||
{
|
||||
_reservatorio = value;
|
||||
OnPropertyChanged(nameof(Reservatorio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _saudeRede = "--";
|
||||
public string SaudeRede
|
||||
{
|
||||
get => ValorOuTracos(_saudeRede);
|
||||
set
|
||||
{
|
||||
if (_saudeRede != value)
|
||||
{
|
||||
_saudeRede = value;
|
||||
OnPropertyChanged(nameof(SaudeRede));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _saudeGnss = "--";
|
||||
public string SaudeGnss
|
||||
{
|
||||
get => ValorOuTracos(_saudeGnss);
|
||||
set
|
||||
{
|
||||
if (_saudeGnss != value)
|
||||
{
|
||||
_saudeGnss = value;
|
||||
OnPropertyChanged(nameof(SaudeGnss));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Brush CorTemperatura =>
|
||||
!RoverSelecionado ? Brushes.Gray :
|
||||
_temperaturaNumerica >= 55 ? Brushes.OrangeRed :
|
||||
_temperaturaNumerica >= 45 ? Brushes.Gold :
|
||||
Brushes.LightGreen;
|
||||
|
||||
public Brush CorBateria =>
|
||||
!RoverSelecionado ? Brushes.Gray :
|
||||
_bateriaNumerica <= 20 ? Brushes.OrangeRed :
|
||||
_bateriaNumerica <= 40 ? Brushes.Gold :
|
||||
Brushes.LightGreen;
|
||||
|
||||
public Brush CorReservatorio =>
|
||||
!RoverSelecionado ? Brushes.Gray :
|
||||
_reservatorioNumerico <= 15 ? Brushes.OrangeRed :
|
||||
_reservatorioNumerico <= 35 ? Brushes.Gold :
|
||||
Brushes.LightGreen;
|
||||
|
||||
public Brush CorRede =>
|
||||
!RoverSelecionado ? Brushes.Gray :
|
||||
CorPorTexto(_saudeRede);
|
||||
|
||||
public Brush CorGnss =>
|
||||
!RoverSelecionado ? Brushes.Gray :
|
||||
CorPorTexto(_saudeGnss);
|
||||
|
||||
private double _temperaturaNumerica;
|
||||
private double _bateriaNumerica;
|
||||
private double _reservatorioNumerico;
|
||||
|
||||
public OperacaoLeftViewModel()
|
||||
{
|
||||
AlternarOperacaoCommand = new RelayCommand(_ => AlternarOperacao());
|
||||
ParadaEmergenciaCommand = new RelayCommand(_ => ExecutarParadaEmergencia());
|
||||
CancelarOperacaoCommand = new RelayCommand(_ => CancelarOperacao());
|
||||
|
||||
DefinirSemRover();
|
||||
}
|
||||
|
||||
public void DefinirSemRover()
|
||||
{
|
||||
RoverSelecionado = false;
|
||||
NomeRover = "Nenhum rover selecionado";
|
||||
_temperaturaNumerica = 0;
|
||||
_bateriaNumerica = 0;
|
||||
_reservatorioNumerico = 0;
|
||||
|
||||
Velocidade = "--";
|
||||
AnguloDirecional = "--";
|
||||
TipoMovimento = TipoMovimentoDirecional.Diagnostico;
|
||||
Temperatura = "--";
|
||||
Bateria = "--";
|
||||
Reservatorio = "--";
|
||||
SaudeRede = "--";
|
||||
SaudeGnss = "--";
|
||||
|
||||
OnPropertyChanged(nameof(CorTemperatura));
|
||||
OnPropertyChanged(nameof(CorBateria));
|
||||
OnPropertyChanged(nameof(CorReservatorio));
|
||||
OnPropertyChanged(nameof(CorRede));
|
||||
OnPropertyChanged(nameof(CorGnss));
|
||||
}
|
||||
|
||||
public void AtualizarRover(string nomeRover, double velocidadeKmh, double anguloDirecionalGraus, TipoMovimentoDirecional tipoMovimento, double temperaturaC, double bateriaPct, double reservatorioPct, string saudeRede, string saudeGnss)
|
||||
{
|
||||
RoverSelecionado = true;
|
||||
NomeRover = nomeRover;
|
||||
|
||||
_temperaturaNumerica = temperaturaC;
|
||||
_bateriaNumerica = bateriaPct;
|
||||
_reservatorioNumerico = reservatorioPct;
|
||||
|
||||
Velocidade = velocidadeKmh.ToString("0.0");
|
||||
AnguloDirecional = anguloDirecionalGraus.ToString("0.0");
|
||||
TipoMovimento = tipoMovimento;
|
||||
Temperatura = temperaturaC.ToString("0.0");
|
||||
Bateria = bateriaPct.ToString("0");
|
||||
Reservatorio = reservatorioPct.ToString("0");
|
||||
SaudeRede = saudeRede;
|
||||
SaudeGnss = saudeGnss;
|
||||
|
||||
OnPropertyChanged(nameof(CorTemperatura));
|
||||
OnPropertyChanged(nameof(CorBateria));
|
||||
OnPropertyChanged(nameof(CorReservatorio));
|
||||
OnPropertyChanged(nameof(CorRede));
|
||||
OnPropertyChanged(nameof(CorGnss));
|
||||
}
|
||||
|
||||
private void AlternarOperacao()
|
||||
{
|
||||
if (VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Iniciada ?? false)
|
||||
{
|
||||
bool PauseActivated = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Pausa ?? false;
|
||||
PauseActivated = !PauseActivated;
|
||||
VariaveisControleOperacao.EnviarComandoParada(pausa: PauseActivated);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!((VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Modo ?? AgroBase.Models.Enums.ModoOperacao.NaoDefinido) == AgroBase.Models.Enums.ModoOperacao.Manual) && !(VariaveisControleOperacao.RoverEmFoco?.RuasPercorrer?.Any() ?? false))
|
||||
{
|
||||
System.Windows.MessageBox.Show("Para iniciar a operação automática, é necessário carregar um mapa e selecionar as ruas onde o equipamento irá operar!", "Parametrização", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (System.Windows.MessageBox.Show("Deseja iniciar a operação com os parâmetros atuais?", "Iniciar Operação", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
|
||||
{
|
||||
bool simulador = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Gnss?.Iniciado != true;
|
||||
VariaveisControleOperacao.EnviarComandoIniciarOperacao(true, simulador);
|
||||
}
|
||||
}
|
||||
|
||||
OperacaoEmExecucao = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Iniciada ?? false;
|
||||
}
|
||||
|
||||
private void ExecutarParadaEmergencia()
|
||||
{
|
||||
bool EmergencyActivated = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Emergencia ?? false;
|
||||
EmergencyActivated = !EmergencyActivated;
|
||||
//VariaveisControleOperacao.EnviarComandoParada(emergencia: EmergencyActivated);
|
||||
_ = VariaveisControleOperacao.EnviarComandoParadaUDP(emergencia: EmergencyActivated);
|
||||
}
|
||||
|
||||
private void CancelarOperacao()
|
||||
{
|
||||
if (System.Windows.MessageBox.Show("Deseja finalizar a operação em andamento?", "Finalizar Operação", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
|
||||
{
|
||||
VariaveisControleOperacao.EnviarComandoIniciarOperacao(false);
|
||||
OperacaoEmExecucao = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private string ValorOuTracos(string valor) => RoverSelecionado ? valor : "--";
|
||||
private string VelocidadeValor(string valor) => RoverSelecionado ? $"{valor} km/h" : "--";
|
||||
private string TemperaturaValor(string valor) => RoverSelecionado ? $"{valor} °C" : "--";
|
||||
private string PercentualOuTracos(string valor) => RoverSelecionado ? $"{valor}%" : "--";
|
||||
|
||||
private Brush CorPorTexto(string valor)
|
||||
{
|
||||
var txt = (valor ?? "").Trim().ToLower();
|
||||
|
||||
if (txt.Contains("excelente") || txt.Contains("ótima") || txt.Contains("otima") || txt.Contains("boa") || txt.Contains("rtk fixed"))
|
||||
return Brushes.LightGreen;
|
||||
|
||||
if (txt.Contains("média") || txt.Contains("media") || txt.Contains("regular") || txt.Contains("float") || txt.Contains("3d"))
|
||||
return Brushes.Gold;
|
||||
|
||||
if (txt.Contains("ruim") || txt.Contains("sem") || txt.Contains("offline") || txt.Contains("falha"))
|
||||
return Brushes.OrangeRed;
|
||||
|
||||
return Brushes.LightGray;
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
private void OnPropertyChanged(string nome)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,344 @@
|
|||
using AgroBase.Models.Operacoes;
|
||||
using OperationControl.Helpers;
|
||||
using OperationControl.Models;
|
||||
using OperationControl.Models.Operacao;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using static AgroBase.Models.Enums;
|
||||
|
||||
namespace OperationControl.ViewModels.Views.Operacao
|
||||
{
|
||||
public class OperacaoRightViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private bool _isCollapsed;
|
||||
private RoverCardModel _roverSelecionado;
|
||||
public ResumoOperacionalModel Resumo { get; } = new ResumoOperacionalModel();
|
||||
public OperacaoParametrosModel Parametros { get; } = new OperacaoParametrosModel();
|
||||
|
||||
public OperacaoRightViewModel()
|
||||
{
|
||||
Rovers = new ObservableCollection<RoverCardModel>();
|
||||
|
||||
ToggleCollapseCommand = new RelayCommand(_ => ToggleCollapse());
|
||||
SelecionarRoverCommand = new RelayCommand(p => SelecionarRover(p as RoverCardModel));
|
||||
SelecionarSecaoCommand = new RelayCommand(p =>
|
||||
{
|
||||
if (p is SecaoRightBar secao)
|
||||
SelecionarSecao(secao);
|
||||
else if (p != null && Enum.TryParse<SecaoRightBar>(p.ToString(), out var secaoParseada))
|
||||
SelecionarSecao(secaoParseada);
|
||||
});
|
||||
AcaoBotaoTopoCommand = new RelayCommand(_ => ExecutarAcaoBotaoTopo());
|
||||
LerParametrosCommand = new RelayCommand(_ => LerParametrosSolicitado?.Invoke());
|
||||
SalvarParametrosCommand = new RelayCommand(_ => SalvarParametrosSolicitado?.Invoke(Parametros));
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
public event Action<SecaoRightBar> SecaoSelecionadaChanged;
|
||||
public event Action<RoverCardModel> RoverSelecionadoChanged;
|
||||
public event Action? LerParametrosSolicitado;
|
||||
public event Action<OperacaoParametrosModel>? SalvarParametrosSolicitado;
|
||||
|
||||
public ObservableCollection<RoverCardModel> Rovers { get; }
|
||||
|
||||
public ICommand ToggleCollapseCommand { get; }
|
||||
public ICommand SelecionarRoverCommand { get; }
|
||||
public ICommand SelecionarSecaoCommand { get; }
|
||||
public ICommand AcaoBotaoTopoCommand { get; }
|
||||
public ICommand LerParametrosCommand { get; }
|
||||
public ICommand SalvarParametrosCommand { get; }
|
||||
|
||||
public bool IsCollapsed
|
||||
{
|
||||
get => _isCollapsed;
|
||||
set
|
||||
{
|
||||
if (_isCollapsed != value)
|
||||
{
|
||||
_isCollapsed = value;
|
||||
OnPropertyChanged(nameof(IsCollapsed));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RoverCardModel RoverSelecionado
|
||||
{
|
||||
get => _roverSelecionado;
|
||||
set
|
||||
{
|
||||
if (_roverSelecionado != value)
|
||||
{
|
||||
_roverSelecionado = value;
|
||||
OnPropertyChanged(nameof(RoverSelecionado));
|
||||
OnPropertyChanged(nameof(SemRoverSelecionado));
|
||||
OnPropertyChanged(nameof(ComRoverSelecionado));
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool SemRoverSelecionado => RoverSelecionado == null;
|
||||
public bool ComRoverSelecionado => RoverSelecionado != null;
|
||||
|
||||
public string QuantidadeRoversTexto => $"{Rovers.Count} rover(s) encontrado(s)";
|
||||
|
||||
private SecaoRightBar _secaoAtual = SecaoRightBar.Menu;
|
||||
public SecaoRightBar SecaoAtual
|
||||
{
|
||||
get => _secaoAtual;
|
||||
set
|
||||
{
|
||||
if (_secaoAtual != value)
|
||||
{
|
||||
_secaoAtual = value;
|
||||
OnPropertyChanged(nameof(SecaoAtual));
|
||||
OnPropertyChanged(nameof(EmMenu));
|
||||
OnPropertyChanged(nameof(EmResumo));
|
||||
OnPropertyChanged(nameof(EmParametrizacao));
|
||||
OnPropertyChanged(nameof(EmControle));
|
||||
OnPropertyChanged(nameof(BotaoTopoEhVoltar));
|
||||
OnPropertyChanged(nameof(TextoBotaoTopo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool EmMenu => SecaoAtual == SecaoRightBar.Menu || SecaoAtual == SecaoRightBar.Diagnostico;
|
||||
public bool EmResumo => SecaoAtual == SecaoRightBar.Resumo;
|
||||
public bool EmParametrizacao => SecaoAtual == SecaoRightBar.Parametrizacao;
|
||||
public bool EmControle => SecaoAtual == SecaoRightBar.Controle;
|
||||
|
||||
public bool BotaoTopoEhVoltar => EmResumo || EmControle || EmParametrizacao;
|
||||
|
||||
public string TextoBotaoTopo => BotaoTopoEhVoltar ? "◀ Voltar" : "Trocar Rover";
|
||||
|
||||
private void ExecutarAcaoBotaoTopo()
|
||||
{
|
||||
if (BotaoTopoEhVoltar)
|
||||
{
|
||||
SelecionarSecao(SecaoRightBar.Menu);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelecionarRover(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ToggleCollapse()
|
||||
{
|
||||
IsCollapsed = !IsCollapsed;
|
||||
}
|
||||
|
||||
public void SelecionarRover(RoverCardModel rover)
|
||||
{
|
||||
RoverSelecionado = rover;
|
||||
|
||||
if (RoverSelecionado != null)
|
||||
{
|
||||
VariaveisControleOperacao.RequisitarParametrosOperacao();
|
||||
SelecionarSecao(SecaoRightBar.Menu);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelecionarSecao(SecaoRightBar.SemRoverSelecionado);
|
||||
}
|
||||
RoverSelecionadoChanged?.Invoke(rover);
|
||||
}
|
||||
|
||||
public void SelecionarSecao(SecaoRightBar secao)
|
||||
{
|
||||
switch (secao)
|
||||
{
|
||||
case SecaoRightBar.Parametrizacao:
|
||||
AtualizarParametros(VariaveisControleOperacao.RoverEmFoco);
|
||||
break;
|
||||
}
|
||||
|
||||
SecaoAtual = secao;
|
||||
|
||||
SecaoSelecionadaChanged?.Invoke(secao);
|
||||
}
|
||||
|
||||
public void DestacarRoverNoMapa(string? roverId)
|
||||
{
|
||||
foreach (var rover in Rovers)
|
||||
rover.IsDestacadoNoMapa = !string.IsNullOrEmpty(roverId) && rover.NumeroSerie == roverId;
|
||||
}
|
||||
|
||||
public void AtualizarListaRovers(params RoverCardModel[] rovers)
|
||||
{
|
||||
var origem = (rovers ?? Array.Empty<RoverCardModel>()).ToList();
|
||||
|
||||
// Remove os que não existem mais
|
||||
for (int i = Rovers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var atual = Rovers[i];
|
||||
bool aindaExiste = origem.Any(x => x.NumeroSerie == atual.NumeroSerie);
|
||||
|
||||
if (!aindaExiste)
|
||||
Rovers.RemoveAt(i);
|
||||
}
|
||||
|
||||
// Adiciona ou atualiza os existentes
|
||||
foreach (var roverNovo in origem)
|
||||
{
|
||||
var roverExistente = Rovers.FirstOrDefault(x => x.NumeroSerie == roverNovo.NumeroSerie);
|
||||
|
||||
if (roverExistente == null)
|
||||
{
|
||||
Rovers.Add(roverNovo);
|
||||
}
|
||||
else
|
||||
{
|
||||
roverExistente.EquipamentoId = roverNovo.EquipamentoId;
|
||||
roverExistente.Status = roverNovo.Status;
|
||||
|
||||
// se quiser refletir mudança de texto também:
|
||||
// roverExistente.NumeroSerie = roverNovo.NumeroSerie; // normalmente não precisa se NS é a chave
|
||||
|
||||
// dispara props derivadas se necessário
|
||||
// no caso de EquipamentoId, como é auto-property hoje, melhor virar property notificável se isso puder mudar
|
||||
}
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(QuantidadeRoversTexto));
|
||||
OnPropertyChanged(nameof(SemRoverSelecionado));
|
||||
OnPropertyChanged(nameof(ComRoverSelecionado));
|
||||
}
|
||||
|
||||
public void AtualizarResumo(Action<ResumoOperacionalModel> updateAction)
|
||||
{
|
||||
if (!System.Windows.Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() => updateAction?.Invoke(Resumo)));
|
||||
return;
|
||||
}
|
||||
|
||||
updateAction?.Invoke(Resumo);
|
||||
}
|
||||
|
||||
|
||||
public void AtualizarParametros(OperacaoParametrosModel origem)
|
||||
{
|
||||
if (origem == null) return;
|
||||
|
||||
Parametros.Modo = origem.Modo;
|
||||
Parametros.Descricao = origem.Descricao;
|
||||
Parametros.QtdBicos = origem.QtdBicos;
|
||||
Parametros.QtdCamerasSolo = origem.QtdCamerasSolo;
|
||||
Parametros.CapacidadeReservatorio = origem.CapacidadeReservatorio;
|
||||
|
||||
var controle_o = origem.Controle;
|
||||
if (Parametros.Controle == null) Parametros.Controle = new OperacaoParametrosControleModel();
|
||||
var controle_p = Parametros.Controle;
|
||||
|
||||
controle_p.MovimentoAutomatico = controle_o.MovimentoAutomatico;
|
||||
controle_p.DirecionalAutomatico = controle_o.DirecionalAutomatico;
|
||||
controle_p.PulverizadorAutomatico = controle_o.PulverizadorAutomatico;
|
||||
controle_p.SonarAtivado = controle_o.SonarAtivado;
|
||||
controle_p.OakParadaPorObstaculo = controle_o.OakParadaPorObstaculo;
|
||||
controle_p.ImuParadaPorInclinacao = controle_o.ImuParadaPorInclinacao;
|
||||
controle_p.FrenagemAutomaticaAoParar = controle_o.FrenagemAutomaticaAoParar;
|
||||
controle_p.RegistrarDadosPosProcessamento = controle_o.RegistrarDadosPosProcessamento;
|
||||
|
||||
controle_p.MovVelocidadeSErvasPercent = controle_o.MovVelocidadeSErvasPercent;
|
||||
controle_p.MovVelocidadeCErvasPercent = controle_o.MovVelocidadeCErvasPercent;
|
||||
|
||||
controle_p.DirAnguloMaximo = controle_o.DirAnguloMaximo;
|
||||
controle_p.DirVelocidadeMovimento = controle_o.DirVelocidadeMovimento;
|
||||
controle_p.DirTipoMovimento = controle_o.DirTipoMovimento;
|
||||
|
||||
controle_p.AtuPressaoLinha = controle_o.AtuPressaoLinha;
|
||||
controle_p.AtuDuracaoAtuacao = controle_o.AtuDuracaoAtuacao;
|
||||
controle_p.AtuPercentualInicioPulverizacao = controle_o.AtuPercentualInicioPulverizacao;
|
||||
controle_p.AtuAlturaAreaPulverizacao = controle_o.AtuAlturaAreaPulverizacao;
|
||||
controle_p.AtuPercentualErvasBicoOn = controle_o.AtuPercentualErvasBicoOn;
|
||||
controle_p.AtuPercentualErvasBicoOff = controle_o.AtuPercentualErvasBicoOff;
|
||||
|
||||
controle_p.MpcMatrizCusto = controle_o.MpcMatrizCusto;
|
||||
controle_p.MpcHorizonte = controle_o.MpcHorizonte;
|
||||
|
||||
OnPropertyChanged(nameof(Parametros));
|
||||
}
|
||||
|
||||
private void OnPropertyChanged(string nome)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||
}
|
||||
}
|
||||
|
||||
public class RoverCardModel : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
public string EquipamentoId { get; set; }
|
||||
public string NumeroSerie { get; set; }
|
||||
|
||||
private StatusModulo _status;
|
||||
public StatusModulo Status
|
||||
{
|
||||
get => _status;
|
||||
set
|
||||
{
|
||||
if (_status != value)
|
||||
{
|
||||
_status = value;
|
||||
OnPropertyChanged(nameof(Status));
|
||||
OnPropertyChanged(nameof(StatusBrush));
|
||||
OnPropertyChanged(nameof(StatusTexto));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isDestacadoNoMapa;
|
||||
public bool IsDestacadoNoMapa
|
||||
{
|
||||
get => _isDestacadoNoMapa;
|
||||
set
|
||||
{
|
||||
if (_isDestacadoNoMapa != value)
|
||||
{
|
||||
_isDestacadoNoMapa = value;
|
||||
OnPropertyChanged(nameof(IsDestacadoNoMapa));
|
||||
OnPropertyChanged(nameof(BordaCardBrush));
|
||||
OnPropertyChanged(nameof(BordaCardThickness));
|
||||
OnPropertyChanged(nameof(CardBackground));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Brush StatusBrush =>
|
||||
Status == StatusModulo.Operante ? Brushes.Green :
|
||||
Status == StatusModulo.Desconectado ? Brushes.Gray :
|
||||
Status == StatusModulo.Falha ? Brushes.Red :
|
||||
Status == StatusModulo.Alerta ? Brushes.Yellow :
|
||||
Status == StatusModulo.Conectado ? Brushes.Blue :
|
||||
Brushes.Black;
|
||||
|
||||
public System.Windows.Media.Brush CardBackground => IsDestacadoNoMapa ? new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(58, 42, 18)) : new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(38, 38, 38));
|
||||
public Brush BordaCardBrush => IsDestacadoNoMapa ? Brushes.Orange : StatusBrush;
|
||||
public Thickness BordaCardThickness => IsDestacadoNoMapa ? new Thickness(3) : new Thickness(2);
|
||||
|
||||
public string EquipamentoTexto => $"Equipamento: {EquipamentoId}";
|
||||
public string NumeroSerieTexto => $"NS: {NumeroSerie}";
|
||||
public string StatusTexto => $"Status: {Status}";
|
||||
|
||||
private void OnPropertyChanged(string nome)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||
}
|
||||
}
|
||||
|
||||
public enum SecaoRightBar
|
||||
{
|
||||
SemRoverSelecionado = 0,
|
||||
Menu = 1,
|
||||
Resumo = 2,
|
||||
Diagnostico = 3,
|
||||
Parametrizacao = 4,
|
||||
Controle = 5
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
using System.ComponentModel;
|
||||
using System.Windows.Media;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
using Brushes = System.Windows.Media.Brushes;
|
||||
using Color = System.Windows.Media.Color;
|
||||
using ColorConverter = System.Windows.Media.ColorConverter;
|
||||
|
||||
namespace OperationControl.ViewModels.Views.Operacao
|
||||
{
|
||||
public class OperacaoTopViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private string _contextoSelecionado = "BASE";
|
||||
public string ContextoSelecionado
|
||||
{
|
||||
get => _contextoSelecionado;
|
||||
set
|
||||
{
|
||||
if (_contextoSelecionado != value)
|
||||
{
|
||||
_contextoSelecionado = value;
|
||||
OnPropertyChanged(nameof(ContextoSelecionado));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _mensagemStatus = "Sistema inicializado.";
|
||||
public string MensagemStatus
|
||||
{
|
||||
get => _mensagemStatus;
|
||||
set
|
||||
{
|
||||
if (_mensagemStatus != value)
|
||||
{
|
||||
_mensagemStatus = value;
|
||||
OnPropertyChanged(nameof(MensagemStatus));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _badgeTexto = "PRONTO";
|
||||
public string BadgeTexto
|
||||
{
|
||||
get => _badgeTexto;
|
||||
set
|
||||
{
|
||||
if (_badgeTexto != value)
|
||||
{
|
||||
_badgeTexto = value;
|
||||
OnPropertyChanged(nameof(BadgeTexto));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Brush _corFundo = Brushes.DimGray;
|
||||
public Brush CorFundo
|
||||
{
|
||||
get => _corFundo;
|
||||
set
|
||||
{
|
||||
if (_corFundo != value)
|
||||
{
|
||||
_corFundo = value;
|
||||
OnPropertyChanged(nameof(CorFundo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Brush _corBadge = Brushes.SteelBlue;
|
||||
public Brush CorBadge
|
||||
{
|
||||
get => _corBadge;
|
||||
set
|
||||
{
|
||||
if (_corBadge != value)
|
||||
{
|
||||
_corBadge = value;
|
||||
OnPropertyChanged(nameof(CorBadge));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Brush _corTexto = Brushes.White;
|
||||
public Brush CorTexto
|
||||
{
|
||||
get => _corTexto;
|
||||
set
|
||||
{
|
||||
if (_corTexto != value)
|
||||
{
|
||||
_corTexto = value;
|
||||
OnPropertyChanged(nameof(CorTexto));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DefinirStatusNormal(string contexto, string mensagem)
|
||||
{
|
||||
ContextoSelecionado = contexto;
|
||||
MensagemStatus = mensagem;
|
||||
BadgeTexto = "NORMAL";
|
||||
CorFundo = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#1F3A2D"));
|
||||
CorBadge = Brushes.LightGreen;
|
||||
CorTexto = Brushes.White;
|
||||
}
|
||||
|
||||
public void DefinirStatusManual(string contexto, string mensagem)
|
||||
{
|
||||
ContextoSelecionado = contexto;
|
||||
MensagemStatus = mensagem;
|
||||
BadgeTexto = "MANUAL";
|
||||
CorFundo = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#2D3440"));
|
||||
CorBadge = Brushes.Gold;
|
||||
CorTexto = Brushes.White;
|
||||
}
|
||||
|
||||
public void DefinirStatusAtencao(string contexto, string mensagem)
|
||||
{
|
||||
ContextoSelecionado = contexto;
|
||||
MensagemStatus = mensagem;
|
||||
BadgeTexto = "ATENÇÃO";
|
||||
CorFundo = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#4A3315"));
|
||||
CorBadge = Brushes.Orange;
|
||||
CorTexto = Brushes.White;
|
||||
}
|
||||
|
||||
public void DefinirStatusCritico(string contexto, string mensagem)
|
||||
{
|
||||
ContextoSelecionado = contexto;
|
||||
MensagemStatus = mensagem;
|
||||
BadgeTexto = "CRÍTICO";
|
||||
CorFundo = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#4A1F1F"));
|
||||
CorBadge = Brushes.OrangeRed;
|
||||
CorTexto = Brushes.White;
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
private void OnPropertyChanged(string nome)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
using OperationControl.Helpers;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace OperationControl.ViewModels
|
||||
{
|
||||
public class PreparacaoMapaBottomViewModel : INotifyPropertyChanged
|
||||
{
|
||||
public event Action<string>? CarregarMapaSolicitado;
|
||||
public event Action? FixarBaseSolicitado;
|
||||
|
||||
private bool _fixacaoEmAndamento;
|
||||
public bool FixacaoEmAndamento
|
||||
{
|
||||
get => _fixacaoEmAndamento;
|
||||
set
|
||||
{
|
||||
if (_fixacaoEmAndamento != value)
|
||||
{
|
||||
_fixacaoEmAndamento = value;
|
||||
OnPropertyChanged(nameof(FixacaoEmAndamento));
|
||||
OnPropertyChanged(nameof(PodeCarregarMapa));
|
||||
OnPropertyChanged(nameof(PodeFixarBase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool PodeCarregarMapa => !FixacaoEmAndamento;
|
||||
public bool PodeFixarBase => true;
|
||||
|
||||
private double _progressoFixacao;
|
||||
public double ProgressoFixacao
|
||||
{
|
||||
get => _progressoFixacao;
|
||||
set
|
||||
{
|
||||
if (_progressoFixacao != value)
|
||||
{
|
||||
_progressoFixacao = value;
|
||||
OnPropertyChanged(nameof(ProgressoFixacao));
|
||||
OnPropertyChanged(nameof(ProgressoFixacaoTexto));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string ProgressoFixacaoTexto => $"{ProgressoFixacao:F0}%";
|
||||
|
||||
private string _statusTexto = "Pronto para carregar o mapa e fixar a base.";
|
||||
public string StatusTexto
|
||||
{
|
||||
get => _statusTexto;
|
||||
set
|
||||
{
|
||||
if (_statusTexto != value)
|
||||
{
|
||||
_statusTexto = value;
|
||||
OnPropertyChanged(nameof(StatusTexto));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _textoBotaoFixarBase = "Fixar posição da base";
|
||||
public string TextoBotaoFixarBase
|
||||
{
|
||||
get => _textoBotaoFixarBase;
|
||||
set
|
||||
{
|
||||
if (_textoBotaoFixarBase != value)
|
||||
{
|
||||
_textoBotaoFixarBase = value;
|
||||
OnPropertyChanged(nameof(TextoBotaoFixarBase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand CarregarMapaCommand { get; }
|
||||
public ICommand FixarBaseCommand { get; }
|
||||
|
||||
public PreparacaoMapaBottomViewModel()
|
||||
{
|
||||
CarregarMapaCommand = new RelayCommand(_ => ExecutarCarregarMapa(), _ => PodeCarregarMapa);
|
||||
FixarBaseCommand = new RelayCommand(_ => ExecutarFixarBase(), _ => PodeFixarBase);
|
||||
}
|
||||
|
||||
private void ExecutarCarregarMapa()
|
||||
{
|
||||
var dlg = new OpenFileDialog
|
||||
{
|
||||
Filter = "Arquivos de mapa|*.geojson;*.json;*.shp",
|
||||
Title = "Selecione o arquivo de mapa"
|
||||
};
|
||||
|
||||
if (dlg.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
StatusTexto = $"Mapa selecionado: {System.IO.Path.GetFileName(dlg.FileName)}";
|
||||
CarregarMapaSolicitado?.Invoke(dlg.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecutarFixarBase()
|
||||
{
|
||||
FixarBaseSolicitado?.Invoke();
|
||||
}
|
||||
|
||||
public void AtualizarProgresso(double progresso, string status)
|
||||
{
|
||||
ProgressoFixacao = progresso;
|
||||
StatusTexto = status;
|
||||
}
|
||||
|
||||
public void IniciarFixacao()
|
||||
{
|
||||
FixacaoEmAndamento = true;
|
||||
TextoBotaoFixarBase = "Parar";
|
||||
ProgressoFixacao = 0;
|
||||
StatusTexto = "Iniciando fixação da posição da base...";
|
||||
}
|
||||
|
||||
public void FinalizarFixacao(bool sucesso, string? mensagem = null)
|
||||
{
|
||||
FixacaoEmAndamento = false;
|
||||
TextoBotaoFixarBase = "Fixar posição da base";
|
||||
ProgressoFixacao = sucesso ? 100 : ProgressoFixacao;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mensagem))
|
||||
StatusTexto = mensagem;
|
||||
else
|
||||
StatusTexto = sucesso
|
||||
? "Fixação da base concluída com sucesso."
|
||||
: "Fixação da base encerrada.";
|
||||
}
|
||||
|
||||
public void CancelarFixacao(string? mensagem = null)
|
||||
{
|
||||
FixacaoEmAndamento = false;
|
||||
TextoBotaoFixarBase = "Fixar posição da base";
|
||||
StatusTexto = mensagem ?? "Fixação da base cancelada.";
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
private void OnPropertyChanged(string nome)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||
System.Windows.Input.CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
using AgroBase.Models;
|
||||
using System.ComponentModel;
|
||||
using static AgroBase.Models.Enums;
|
||||
|
||||
namespace OperationControl.ViewModels
|
||||
{
|
||||
public class PreparacaoMapaTopViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private string _latitudeTexto = "-";
|
||||
public string LatitudeTexto
|
||||
{
|
||||
get => _latitudeTexto;
|
||||
set { _latitudeTexto = value; OnPropertyChanged(nameof(LatitudeTexto)); }
|
||||
}
|
||||
|
||||
private string _longitudeTexto = "-";
|
||||
public string LongitudeTexto
|
||||
{
|
||||
get => _longitudeTexto;
|
||||
set { _longitudeTexto = value; OnPropertyChanged(nameof(LongitudeTexto)); }
|
||||
}
|
||||
|
||||
private string _altitudeTexto = "-";
|
||||
public string AltitudeTexto
|
||||
{
|
||||
get => _altitudeTexto;
|
||||
set { _altitudeTexto = value; OnPropertyChanged(nameof(AltitudeTexto)); }
|
||||
}
|
||||
|
||||
private string _headingTexto = "-";
|
||||
public string HeadingTexto
|
||||
{
|
||||
get => _headingTexto;
|
||||
set { _headingTexto = value; OnPropertyChanged(nameof(HeadingTexto)); }
|
||||
}
|
||||
|
||||
private string _fixTexto = "Sem fix";
|
||||
public string FixTexto
|
||||
{
|
||||
get => _fixTexto;
|
||||
set { _fixTexto = value; OnPropertyChanged(nameof(FixTexto)); }
|
||||
}
|
||||
|
||||
private Brush _fixCor = Brushes.OrangeRed;
|
||||
public Brush FixCor
|
||||
{
|
||||
get => _fixCor;
|
||||
set { _fixCor = value; OnPropertyChanged(nameof(FixCor)); }
|
||||
}
|
||||
|
||||
private string _precisaoTexto = "-";
|
||||
public string PrecisaoTexto
|
||||
{
|
||||
get => _precisaoTexto;
|
||||
set { _precisaoTexto = value; OnPropertyChanged(nameof(PrecisaoTexto)); }
|
||||
}
|
||||
|
||||
private string _satelitesTexto = "-";
|
||||
public string SatelitesTexto
|
||||
{
|
||||
get => _satelitesTexto;
|
||||
set { _satelitesTexto = value; OnPropertyChanged(nameof(SatelitesTexto)); }
|
||||
}
|
||||
|
||||
private string _idadeCorrecaoTexto = "-";
|
||||
public string IdadeCorrecaoTexto
|
||||
{
|
||||
get => _idadeCorrecaoTexto;
|
||||
set { _idadeCorrecaoTexto = value; OnPropertyChanged(nameof(IdadeCorrecaoTexto)); }
|
||||
}
|
||||
|
||||
public PreparacaoMapaTopViewModel()
|
||||
{
|
||||
// Mock inicial para visualização
|
||||
LatitudeTexto = "-22.172657";
|
||||
LongitudeTexto = "-47.395216";
|
||||
AltitudeTexto = "612.4 m";
|
||||
HeadingTexto = "183°";
|
||||
FixTexto = "RTK FIX";
|
||||
FixCor = Brushes.LimeGreen;
|
||||
PrecisaoTexto = "1.2 cm";
|
||||
SatelitesTexto = "24";
|
||||
IdadeCorrecaoTexto = "0.8 s";
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void OnPropertyChanged(string nome)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||
}
|
||||
|
||||
public void AtualizarDados(GPSModel dados)
|
||||
{
|
||||
LatitudeTexto = dados.Latitude.ToString("F6");
|
||||
LongitudeTexto = dados.Longitude.ToString("F6");
|
||||
AltitudeTexto = $"{dados.Altitude:F1} m";
|
||||
HeadingTexto = $"{dados.OrientacaoReal:F1}°";
|
||||
FixTexto = dados.QualidadeFix.ToString();
|
||||
PrecisaoTexto = $"{dados.PrecisaoCm:F2} cm";
|
||||
SatelitesTexto = dados.NumeroSatelites.ToString();
|
||||
IdadeCorrecaoTexto = $"{dados.IdadeCorrecao:F1} s";
|
||||
|
||||
AtualizarCorFix(dados.QualidadeFix);
|
||||
}
|
||||
|
||||
private void AtualizarCorFix(TiposCorrecaoGPS fix)
|
||||
{
|
||||
var fixUpper = fix.ToString().ToUpperInvariant();
|
||||
|
||||
if (fixUpper.Contains("FIX"))
|
||||
FixCor = Brushes.LimeGreen;
|
||||
else if (fixUpper.Contains("FLOAT"))
|
||||
FixCor = Brushes.Gold;
|
||||
else if (fixUpper.Contains("DGPS"))
|
||||
FixCor = Brushes.DodgerBlue;
|
||||
else
|
||||
FixCor = Brushes.OrangeRed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,751 @@
|
|||
using System.ComponentModel;
|
||||
using System.Windows.Input;
|
||||
using OperationControl.Views;
|
||||
using OperationControl.Helpers;
|
||||
using System.Windows;
|
||||
using OperationControl.Models;
|
||||
using OperationControl.Views.Operacao;
|
||||
using AgroBase.Models.Operacoes;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OperationControl.ViewModels.Views.Operacao;
|
||||
|
||||
namespace OperationControl.ViewModels
|
||||
{
|
||||
public class DockWindowViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private readonly ConfigConexaoView _viewConfig;
|
||||
|
||||
private readonly PreparacaoMapaView _viewPreparacaoMapa;
|
||||
public readonly PreparacaoMapaTopView _viewPreparacaoMapaTop;
|
||||
private readonly PreparacaoMapaBottomView _viewPreparacaoMapaBottom;
|
||||
|
||||
private readonly OperacaoTopView _viewOperacaoTop;
|
||||
private readonly OperacaoCenterView _viewOperacaoCenter;
|
||||
public readonly OperacaoLeftView _viewOperacaoLeft;
|
||||
public readonly OperacaoRightView _viewOperacaoRight;
|
||||
public readonly OperacaoBottomView _viewOperacaoBottom;
|
||||
|
||||
private DockStep _currentStep;
|
||||
|
||||
public DockWindowViewModel()
|
||||
{
|
||||
// Views
|
||||
_viewConfig = new ConfigConexaoView();
|
||||
_viewConfig._vm.TudoOkChanged += OnTudoOkChanged;
|
||||
|
||||
_viewPreparacaoMapa = new PreparacaoMapaView();
|
||||
|
||||
_viewPreparacaoMapaTop = new PreparacaoMapaTopView();
|
||||
|
||||
_viewPreparacaoMapaBottom = new PreparacaoMapaBottomView();
|
||||
_viewPreparacaoMapaBottom._vm.CarregarMapaSolicitado += OnCarregarMapaSolicitado;
|
||||
_viewPreparacaoMapaBottom._vm.FixarBaseSolicitado += OnFixarBaseSolicitado;
|
||||
|
||||
_viewOperacaoTop = new OperacaoTopView();
|
||||
|
||||
_viewOperacaoCenter = new OperacaoCenterView();
|
||||
_viewOperacaoCenter._vm.RoverSelecionadoChanged += OnRoverSelecionadoChanged;
|
||||
|
||||
_viewOperacaoLeft = new OperacaoLeftView();
|
||||
|
||||
_viewOperacaoRight = new OperacaoRightView();
|
||||
_viewOperacaoRight._vm.PropertyChanged += OperacaoRightVm_PropertyChanged;
|
||||
_viewOperacaoRight._vm.RoverSelecionadoChanged += OnRoverSelecionadoChanged;
|
||||
_viewOperacaoRight._vm.SecaoSelecionadaChanged += OnSecaoSelecionadaChanged;
|
||||
_viewOperacaoRight._vm.LerParametrosSolicitado += OnLerParametrosSolicitado;
|
||||
_viewOperacaoRight._vm.SalvarParametrosSolicitado += OnSalvarParametrosSolicitado;
|
||||
|
||||
_viewOperacaoBottom = new OperacaoBottomView();
|
||||
_viewOperacaoBottom._vm.AlertaSelecionadoChanged += OnAlertaSelecionadoChanged;
|
||||
|
||||
// Commands
|
||||
BackCommand = new RelayCommand(_ => GoBack(), _ => CanGoBack);
|
||||
NextCommand = new RelayCommand(_ => GoNext(), _ => CanGoNext);
|
||||
|
||||
// Estado inicial
|
||||
ConfigConexaoOk = _viewConfig._vm.TudoOk;
|
||||
CurrentStep = DockStep.ConfigConexao;
|
||||
}
|
||||
|
||||
private void OnTudoOkChanged(bool ok)
|
||||
{
|
||||
ConfigConexaoOk = ok;
|
||||
|
||||
OnPropertyChanged(nameof(CanGoNext));
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
|
||||
// ====== ETAPA ATUAL ======
|
||||
public ModoOperacao ModoOperacaoAtual => _viewConfig._vm.TipoOperacaoSelecionado;
|
||||
|
||||
public DockStep CurrentStep
|
||||
{
|
||||
get => _currentStep;
|
||||
set
|
||||
{
|
||||
if (_currentStep != value)
|
||||
{
|
||||
_currentStep = value;
|
||||
OnPropertyChanged(nameof(CurrentStep));
|
||||
OnPropertyChanged(nameof(CanGoBack));
|
||||
OnPropertyChanged(nameof(CanGoNext));
|
||||
OnPropertyChanged(nameof(MostrarPainelEsquerdo));
|
||||
OnPropertyChanged(nameof(MostrarBotaoVoltarEsquerda));
|
||||
OnPropertyChanged(nameof(RightPanelWidth));
|
||||
OnPropertyChanged(nameof(LeftPanelWidth));
|
||||
|
||||
AtualizarConteudo();
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ====== ESTADO ======
|
||||
private bool _configConexaoOk;
|
||||
public bool ConfigConexaoOk
|
||||
{
|
||||
get => _configConexaoOk;
|
||||
set
|
||||
{
|
||||
if (_configConexaoOk != value)
|
||||
{
|
||||
_configConexaoOk = value;
|
||||
OnPropertyChanged(nameof(ConfigConexaoOk));
|
||||
OnPropertyChanged(nameof(CanGoNext));
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _mapaCarregado;
|
||||
public bool MapaCarregado
|
||||
{
|
||||
get => _mapaCarregado;
|
||||
set
|
||||
{
|
||||
if (_mapaCarregado != value)
|
||||
{
|
||||
_mapaCarregado = value;
|
||||
OnPropertyChanged(nameof(MapaCarregado));
|
||||
OnPropertyChanged(nameof(CanGoNext));
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _baseFixada = true;
|
||||
public bool BaseFixada
|
||||
{
|
||||
get => _baseFixada;
|
||||
set
|
||||
{
|
||||
if (_baseFixada != value)
|
||||
{
|
||||
_baseFixada = value;
|
||||
OnPropertyChanged(nameof(BaseFixada));
|
||||
OnPropertyChanged(nameof(CanGoNext));
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanGoBack => CurrentStep != DockStep.ConfigConexao;
|
||||
|
||||
public bool CanGoNext
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentStep switch
|
||||
{
|
||||
DockStep.ConfigConexao => PodeAvancarConfigConexao(),
|
||||
DockStep.PreparacaoMapa => MapaCarregado && BaseFixada,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
}
|
||||
private bool PodeAvancarConfigConexao()
|
||||
{
|
||||
return ModoOperacaoAtual switch
|
||||
{
|
||||
ModoOperacao.Automatico => _viewConfig._vm.RedeOk && _viewConfig._vm.GnssOk,
|
||||
ModoOperacao.Manual => _viewConfig._vm.RedeOk,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public bool MostrarPainelEsquerdo => CurrentStep == DockStep.ParametrizacaoRover;
|
||||
public bool MostrarBotaoVoltarEsquerda => CurrentStep != DockStep.ParametrizacaoRover;
|
||||
|
||||
public GridLength LeftPanelWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentStep switch
|
||||
{
|
||||
DockStep.ParametrizacaoRover => new GridLength(280),
|
||||
_ => new GridLength(60)
|
||||
};
|
||||
}
|
||||
}
|
||||
public GridLength RightPanelWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentStep switch
|
||||
{
|
||||
DockStep.ParametrizacaoRover => (_viewOperacaoRight?.DataContext as OperacaoRightViewModel)?.IsCollapsed == true
|
||||
? new GridLength(44)
|
||||
: new GridLength(320),
|
||||
|
||||
_ => new GridLength(60)
|
||||
};
|
||||
}
|
||||
}
|
||||
private void OperacaoRightVm_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(OperacaoRightViewModel.IsCollapsed))
|
||||
{
|
||||
OnPropertyChanged(nameof(RightPanelWidth));
|
||||
}
|
||||
}
|
||||
|
||||
// ====== CONTEÚDOS ======
|
||||
private object _centerContent;
|
||||
public object CenterContent
|
||||
{
|
||||
get => _centerContent;
|
||||
set
|
||||
{
|
||||
_centerContent = value;
|
||||
OnPropertyChanged(nameof(CenterContent));
|
||||
}
|
||||
}
|
||||
|
||||
private object _topContent;
|
||||
public object TopContent
|
||||
{
|
||||
get => _topContent;
|
||||
set
|
||||
{
|
||||
_topContent = value;
|
||||
OnPropertyChanged(nameof(TopContent));
|
||||
}
|
||||
}
|
||||
|
||||
private object _bottomContent;
|
||||
public object BottomContent
|
||||
{
|
||||
get => _bottomContent;
|
||||
set
|
||||
{
|
||||
_bottomContent = value;
|
||||
OnPropertyChanged(nameof(BottomContent));
|
||||
}
|
||||
}
|
||||
private object _leftContent;
|
||||
public object LeftContent
|
||||
{
|
||||
get => _leftContent;
|
||||
set
|
||||
{
|
||||
_leftContent = value;
|
||||
OnPropertyChanged(nameof(LeftContent));
|
||||
}
|
||||
}
|
||||
private object _rightContent;
|
||||
public object RightContent
|
||||
{
|
||||
get => _rightContent;
|
||||
set
|
||||
{
|
||||
_rightContent = value;
|
||||
OnPropertyChanged(nameof(RightContent));
|
||||
}
|
||||
}
|
||||
|
||||
// ====== COMMANDS ======
|
||||
public ICommand BackCommand { get; }
|
||||
public ICommand NextCommand { get; }
|
||||
|
||||
private void GoBack()
|
||||
{
|
||||
switch (CurrentStep)
|
||||
{
|
||||
case DockStep.PreparacaoMapa:
|
||||
CurrentStep = DockStep.ConfigConexao;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void GoNext()
|
||||
{
|
||||
if (!CanGoNext) return;
|
||||
|
||||
switch (CurrentStep)
|
||||
{
|
||||
case DockStep.ConfigConexao:
|
||||
if (ModoOperacaoAtual == ModoOperacao.Manual)
|
||||
CurrentStep = DockStep.ParametrizacaoRover;
|
||||
else
|
||||
CurrentStep = DockStep.PreparacaoMapa;
|
||||
break;
|
||||
|
||||
case DockStep.PreparacaoMapa:
|
||||
CurrentStep = DockStep.ParametrizacaoRover;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private FrameworkElement CriarBotaoNextSimples()
|
||||
{
|
||||
return new System.Windows.Controls.Button
|
||||
{
|
||||
Content = "⮞",
|
||||
FontSize = 24,
|
||||
Width = 40,
|
||||
Height = 40,
|
||||
HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Command = NextCommand
|
||||
};
|
||||
}
|
||||
|
||||
private void AtualizarConteudo()
|
||||
{
|
||||
TopContent = null;
|
||||
BottomContent = null;
|
||||
LeftContent = null;
|
||||
RightContent = null;
|
||||
CenterContent = null;
|
||||
|
||||
switch (CurrentStep)
|
||||
{
|
||||
case DockStep.ConfigConexao:
|
||||
CenterContent = _viewConfig;
|
||||
RightContent = CriarBotaoNextSimples();
|
||||
break;
|
||||
|
||||
case DockStep.PreparacaoMapa:
|
||||
TopContent = _viewPreparacaoMapaTop;
|
||||
CenterContent = _viewPreparacaoMapa;
|
||||
BottomContent = _viewPreparacaoMapaBottom;
|
||||
RightContent = CriarBotaoNextSimples();
|
||||
break;
|
||||
|
||||
case DockStep.ParametrizacaoRover:
|
||||
TopContent = _viewOperacaoTop;
|
||||
LeftContent = _viewOperacaoLeft;
|
||||
CenterContent = _viewOperacaoCenter;
|
||||
RightContent = _viewOperacaoRight;
|
||||
BottomContent = _viewOperacaoBottom;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_ultimoMapaCarregado))
|
||||
_viewOperacaoCenter?.MapaOperacao?.LoadMapFile(_ultimoMapaCarregado);
|
||||
break;
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(MostrarPainelEsquerdo));
|
||||
OnPropertyChanged(nameof(MostrarBotaoVoltarEsquerda));
|
||||
}
|
||||
|
||||
// ====== INotifyPropertyChanged ======
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void OnPropertyChanged(string nome)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||
}
|
||||
|
||||
|
||||
public void AtualizarDadosGnss(AgroBase.Models.GPSModel dados)
|
||||
{
|
||||
var bf = Variaveis.GpsService.BaseFix;
|
||||
if (bf.CorrecaoEmAndamento)
|
||||
{
|
||||
AtualizarProgressoFixacaoBase(bf.Progresso, bf.ProgressoStr);
|
||||
if (bf.Progresso >= 100) FinalizarFixacaoBase(true, bf.ProgressoStr);
|
||||
}
|
||||
switch (CurrentStep)
|
||||
{
|
||||
case DockStep.PreparacaoMapa:
|
||||
System.Windows.Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
_viewPreparacaoMapaTop?._vm?.AtualizarDados(dados);
|
||||
});
|
||||
break;
|
||||
|
||||
case DockStep.ParametrizacaoRover:
|
||||
_viewOperacaoCenter?.MapaOperacao?.markers?.UpdateMarkerPosition(VariaveisControleOperacao.BaseMarkerID, lat: dados?.Latitude, lon: dados?.Longitude, heading: dados?.OrientacaoReal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void AtualizarDadosMapa(OperacaoParametrosModel dados)
|
||||
{
|
||||
_viewOperacaoCenter?.MapaOperacao?.CarregarDadosMapa(dados?.Mapa, dados?.RuasPercorrer);
|
||||
}
|
||||
|
||||
#region TELA 2
|
||||
|
||||
private string? _ultimoMapaCarregado;
|
||||
|
||||
private void OnCarregarMapaSolicitado(string caminhoArquivo)
|
||||
{
|
||||
try
|
||||
{
|
||||
_ultimoMapaCarregado = caminhoArquivo;
|
||||
_viewPreparacaoMapa?.MapControl?.LoadMapFile(caminhoArquivo);
|
||||
MapaCarregado = true;
|
||||
_viewPreparacaoMapaBottom?._vm.AtualizarProgresso(0, $"Mapa carregado: {System.IO.Path.GetFileName(caminhoArquivo)}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MapaCarregado = false;
|
||||
_viewPreparacaoMapaBottom?._vm.AtualizarProgresso(0, $"Erro ao carregar mapa: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnFixarBaseSolicitado()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Variaveis.GpsService.BaseFix.FixLiberado)
|
||||
{
|
||||
bool fixar = false;
|
||||
|
||||
if (Variaveis.GpsService.BaseFix.PosicaoBaseFixada)
|
||||
{
|
||||
var res = System.Windows.MessageBox.Show(
|
||||
"Mudar posição da base?",
|
||||
"Tem certeza que deseja fixar a posição da base novamente?",
|
||||
MessageBoxButton.YesNo,
|
||||
MessageBoxImage.Question);
|
||||
|
||||
if (res == MessageBoxResult.Yes)
|
||||
fixar = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixar = true;
|
||||
}
|
||||
|
||||
if (fixar)
|
||||
{
|
||||
_viewPreparacaoMapaBottom?._vm.IniciarFixacao();
|
||||
await Task.Run(async () => await Variaveis.GpsService.ConfigurarModulo(true));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Variaveis.GpsService.BaseFix.ReiniciarFix();
|
||||
BaseFixada = false;
|
||||
_viewPreparacaoMapaBottom?._vm.CancelarFixacao("Fixação da base interrompida pelo operador.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_viewPreparacaoMapaBottom?._vm.FinalizarFixacao(false, $"Erro na fixação da base: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public void AtualizarProgressoFixacaoBase(double progresso, string status)
|
||||
{
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
_viewPreparacaoMapaBottom?._vm.AtualizarProgresso(progresso, status);
|
||||
}));
|
||||
}
|
||||
|
||||
public void FinalizarFixacaoBase(bool sucesso, string mensagem)
|
||||
{
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
BaseFixada = sucesso;
|
||||
_viewPreparacaoMapaBottom?._vm.FinalizarFixacao(sucesso, mensagem);
|
||||
}));
|
||||
}
|
||||
|
||||
public void CancelarFixacaoBase(string mensagem)
|
||||
{
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
BaseFixada = false;
|
||||
_viewPreparacaoMapaBottom?._vm.CancelarFixacao(mensagem);
|
||||
}));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region TELA 3
|
||||
|
||||
public void AtualizarTopOperacaoBase()
|
||||
{
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
_viewOperacaoTop?._vm.DefinirStatusNormal("BASE", "Base selecionada. Sistema pronto.");
|
||||
}));
|
||||
}
|
||||
|
||||
public void AtualizarTopOperacaoRover(string nomeRover, bool modoManual)
|
||||
{
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
if (modoManual)
|
||||
_viewOperacaoTop?._vm.DefinirStatusManual($"{nomeRover}", "Rover em modo manual. Comandos locais liberados.");
|
||||
else
|
||||
_viewOperacaoTop?._vm.DefinirStatusNormal($"{nomeRover}", "Rover selecionado. Operação pronta.");
|
||||
}));
|
||||
}
|
||||
|
||||
public void AtualizarTopOperacaoAlerta(string contexto, string mensagem)
|
||||
{
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
_viewOperacaoTop?._vm.DefinirStatusAtencao(contexto, mensagem);
|
||||
}));
|
||||
}
|
||||
|
||||
public void AtualizarTopOperacaoCritico(string contexto, string mensagem)
|
||||
{
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
_viewOperacaoTop?._vm.DefinirStatusCritico(contexto, mensagem);
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
private void OnAlertaSelecionadoChanged(AlertaModel alerta)
|
||||
{
|
||||
if (alerta == null) return;
|
||||
|
||||
AtualizarTopOperacaoAlerta(
|
||||
$"ALERTA {alerta.Rover_ID}",
|
||||
$"{alerta.Titulo}: {alerta.Mensagem}"
|
||||
);
|
||||
|
||||
// depois você pode navegar para diagnostico, abrir popup, focar modulo, etc
|
||||
}
|
||||
|
||||
public void AdicionarAlerta(string roverId, AgroBase.Models.Enums.T_Code modulo, SeveridadeAlerta severidade, string mensagem, string modId = null)
|
||||
{
|
||||
(_viewOperacaoBottom.DataContext as OperacaoBottomViewModel)?.AdicionarAlerta(roverId, modulo, severidade, mensagem, modId);
|
||||
}
|
||||
|
||||
public void RemoverAlerta(string roverId, AgroBase.Models.Enums.T_Code modulo, SeveridadeAlerta? severidade = null, string modId = null)
|
||||
{
|
||||
(_viewOperacaoBottom.DataContext as OperacaoBottomViewModel)?.RemoverAlerta(roverId, modulo, severidade, modId);
|
||||
}
|
||||
|
||||
|
||||
public void AtualizarListaRovers(List<OperacaoParametrosModel> rovers_atual)
|
||||
{
|
||||
var cards = rovers_atual.Select(x => new RoverCardModel()
|
||||
{
|
||||
EquipamentoId = x.IP,
|
||||
NumeroSerie = x.RoverId,
|
||||
Status = x.DadosLeitura?.StatusRover ?? AgroBase.Models.Enums.StatusModulo.Desconectado
|
||||
}).ToArray();
|
||||
|
||||
_viewOperacaoRight?._vm?.AtualizarListaRovers(cards);
|
||||
|
||||
foreach (var rover in cards)
|
||||
{
|
||||
if (!_viewOperacaoCenter?.MapaOperacao?.markers?.Added(rover.NumeroSerie) ?? false)
|
||||
{
|
||||
if (rover.NumeroSerie == VariaveisControleOperacao.BaseMarkerID)
|
||||
{
|
||||
_viewOperacaoCenter?.MapaOperacao?.markers?.AddMarker(
|
||||
rover.NumeroSerie,
|
||||
true,
|
||||
lat: Variaveis.GpsService?.UltimaLeitura?.Latitude ?? 0,
|
||||
lon: Variaveis.GpsService?.UltimaLeitura?.Longitude ?? 0,
|
||||
heading: Variaveis.GpsService?.UltimaLeitura?.OrientacaoReal ?? 0,
|
||||
label: "Base"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
var roverDados = VariaveisControleOperacao.RoversNaRede.FirstOrDefault(x => x.RoverId == rover.NumeroSerie);
|
||||
if (roverDados != null)
|
||||
{
|
||||
_viewOperacaoCenter?.MapaOperacao?.markers?.AddMarker(
|
||||
rover.NumeroSerie,
|
||||
false,
|
||||
lat: roverDados.DadosLeitura?.Gnss?.Latitude ?? 0,
|
||||
lon: roverDados.DadosLeitura?.Gnss?.Longitude ?? 0,
|
||||
heading: roverDados.DadosLeitura?.Gnss?.OrientacaoReal ?? 0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AtualizarDadosTela(OperacaoParametrosModel rover)
|
||||
{
|
||||
if (rover == null) return;
|
||||
var obj = rover.DadosLeitura;
|
||||
if (obj == null) return;
|
||||
|
||||
var simulacao = obj.Controle?.SimulacaoMPC?.Select(x => new double[] { x.longitude, x.latitude })?.ToList();
|
||||
_viewOperacaoCenter?.MapaOperacao?.markers.UpdateMarkerPosition(rover.RoverId, lat: obj.Gnss?.Latitude, lon: obj.Gnss?.Longitude, heading: obj.Gnss?.OrientacaoReal, predict: simulacao);
|
||||
_viewOperacaoCenter?.MapaOperacao?.markers.UpdateMarkerInfo(rover.RoverId, status: obj.Operacao?.Status ?? AgroBase.Models.Enums.StatusOperacao.NaoIniciado);
|
||||
|
||||
_viewOperacaoBottom?._vm?.AtualizarListaAlertasRoverSelecionado(rover.RoverId);
|
||||
|
||||
if (rover.RoverId == VariaveisControleOperacao.SelectedRoverId)
|
||||
{
|
||||
var conexao = obj.ModulosSaude?.FirstOrDefault(x => x.modulo == AgroBase.Models.Enums.T_Code.Ipb);
|
||||
double c = conexao?.saude ?? 0;
|
||||
double conexao_latencia = conexao?.detalhes?["avg_rtt"]?.Value<double>() ?? 0.0;
|
||||
double conexao_perda = conexao?.detalhes?["loss_pct"]?.Value<double>() ?? 0.0;
|
||||
double bwTot = conexao?.detalhes?["bw_total_mbps"]?.Value<double>() ?? 0;
|
||||
string comunicacao = $"{conexao_latencia:0.00} ms {bwTot:0.00} Mbps";
|
||||
string comunicacao_extended = $"{conexao_latencia:0.00} ms {conexao_perda:F2}% {bwTot:0.00} Mbps";
|
||||
|
||||
_viewOperacaoLeft?._vm?.AtualizarRover(
|
||||
rover?.Descricao ?? "",
|
||||
obj.Controle?.PercentualVelocidadeSPKmh ?? 0,
|
||||
obj.Controle?.Angulo ?? 0,
|
||||
obj.Controle?.TipoMovimento ?? AgroBase.Models.Enums.TipoMovimentoDirecional.Diagnostico,
|
||||
obj.Refrigeracao?.Temperatura ?? 0,
|
||||
obj.Bateria?.PercentualBateria ?? 0,
|
||||
obj.Atuador?.PercentualReservatorio ?? 0,
|
||||
$"{c}%",
|
||||
$"{obj.Gnss?.QualidadeFix ?? AgroBase.Models.Enums.TiposCorrecaoGPS.SemCorrecao} {obj.Gnss?.PrecisaoCm:F2} cm"
|
||||
);
|
||||
|
||||
_viewOperacaoRight?._vm?.AtualizarResumo(r =>
|
||||
{
|
||||
r.Operacao = (obj.Operacao?.Liberada ?? false) ? "🔓 Liberada" : "🔒 Bloqueada";
|
||||
r.Modo = obj.Operacao == null ? "-" : obj.Operacao.Modo.ToString();
|
||||
r.Status = obj.Operacao == null ? "-" : $"{obj.Operacao.Status}" + (obj.Operacao.Status == AgroBase.Models.Enums.StatusOperacao.Aguardando ? $" ({obj.Operacao.TempoAguardandoSegs:0}s)" : "");
|
||||
r.Carro = obj.Trajetoria == null ? "-" : obj.Trajetoria.StatusCarro.ToString();
|
||||
r.Temperatura = $"{(obj.PerformanceNcp?.CPU_temp ?? 0):0.00} °C";
|
||||
r.RuaAtual = obj.Trajetoria == null ? "-" : $"{obj.Trajetoria.CorredorAtualDistanciaPercorrida:0.00} m / " + $"{obj.Trajetoria.CorredorAtualDistanciaTotal:0.00} m " + $"({obj.Trajetoria.CorredorAtualIdx + 1})";
|
||||
r.AreaTotal = obj.Trajetoria == null ? "-" : $"{obj.Trajetoria.DistanciaPercorrida:0.00} m / " + $"{obj.Trajetoria.DistanciaTotal:0.00} m";
|
||||
r.Bateria = obj.Bateria == null ? "-" : $"{obj.Bateria.TensaoInstantanea:0.00} V " + $"({TimeSpan.FromMinutes(obj.Bateria.TempoEstimadoRestanteMinutos):dd\\.hh\\:mm\\:ss} " + $"{obj.Bateria.DistanciaEstimadaRestanteMetros:0.00} m)";
|
||||
r.Herbicida = obj.Atuador == null ? "-" : $"{obj.Atuador.VolumeReservatorioL:0.00} L " + $"({TimeSpan.FromMinutes(obj.Atuador.TempoEstimadoRestanteMinutos):hh\\:mm\\:ss} " + $"{obj.Atuador.DistanciaEstimadaRestanteMetros:0.00} m)";
|
||||
r.Infestacao = obj.Atuador == null ? "-" : $"{obj.Atuador.HerbicidaPorAtuacaoMl:0.00} mL/atuação";
|
||||
r.Conexao = comunicacao == null ? "-" : $"{comunicacao}";
|
||||
r.Duracao = obj.Operacao == null ? "00:00:00 / 00:00:00" : $"{TimeSpan.FromSeconds(obj.Operacao.TempoDecorridoSegs):hh\\:mm\\:ss} / " + $"{(string.IsNullOrWhiteSpace(obj.Trajetoria?.TempoEstimadoOperacao) ? "00:00:00" : obj.Trajetoria.TempoEstimadoOperacao)}";
|
||||
|
||||
// Opcionais para progress bars, caso queira evoluir o resumo
|
||||
r.RuaAtualPercentual = obj.Trajetoria?.PercentualRuaAtual ?? 0;
|
||||
r.AreaTotalPercentual = obj.Trajetoria?.PercentualOperacao ?? 0;
|
||||
r.BateriaPercentual = obj.Bateria?.PercentualBateria ?? 0;
|
||||
r.HerbicidaPercentual = obj.Atuador?.PercentualReservatorio ?? 0;
|
||||
r.InfestacaoPercentual = obj.Atuador?.PercentualErvasTerreno ?? 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRoverSelecionadoChanged(string roverId)
|
||||
{
|
||||
_viewOperacaoRight?._vm?.DestacarRoverNoMapa(roverId);
|
||||
}
|
||||
|
||||
private void OnRoverSelecionadoChanged(RoverCardModel rover)
|
||||
{
|
||||
bool dados_base = rover == null;
|
||||
if (dados_base)
|
||||
{
|
||||
if (!VariaveisControleOperacao.BaseEmFoco)
|
||||
{
|
||||
_viewOperacaoCenter?.PararStreamCameraFrontal();
|
||||
_viewOperacaoCenter?.PararStreamCameraErvas();
|
||||
VariaveisControleOperacao.EnviarComandoIniciarUDP(VariaveisControleOperacao.RoverEmFoco?.IP, false);
|
||||
}
|
||||
VariaveisControleOperacao.RoverEmFoco?.RuasPercorrer?.Clear();
|
||||
AtualizarDadosMapa(VariaveisControleOperacao.RoverEmFoco);
|
||||
VariaveisControleOperacao.SelectedRoverId = VariaveisControleOperacao.BaseMarkerID;
|
||||
_viewOperacaoCenter?.MapaOperacao?.markers?.SetMarkerFocused(VariaveisControleOperacao.SelectedRoverId, true);
|
||||
|
||||
_viewOperacaoCenter?._vm?.SelecionarRoverLista(rover);
|
||||
|
||||
AtualizarTopOperacaoRover(VariaveisControleOperacao.SelectedRoverId, true);
|
||||
_viewOperacaoLeft?._vm?.DefinirSemRover();
|
||||
}
|
||||
else
|
||||
{
|
||||
VariaveisControleOperacao.SelectedRoverId = rover.NumeroSerie.ToString();
|
||||
_viewOperacaoCenter?.MapaOperacao?.markers?.SetMarkerFocused(VariaveisControleOperacao.SelectedRoverId, true);
|
||||
AtualizarDadosTela(VariaveisControleOperacao.RoverEmFoco);
|
||||
|
||||
VariaveisControleOperacao.RequisitarParametrosOperacao();
|
||||
_viewOperacaoCenter?.IniciarStreamCameraFrontal();
|
||||
_viewOperacaoCenter?.IniciarStreamCameraErvas();
|
||||
VariaveisControleOperacao.EnviarComandoIniciarUDP(VariaveisControleOperacao.RoverEmFoco?.IP, true);
|
||||
|
||||
_viewOperacaoCenter?._vm?.SelecionarRoverLista(rover);
|
||||
|
||||
AtualizarTopOperacaoRover(VariaveisControleOperacao.SelectedRoverId, ModoOperacaoAtual == ModoOperacao.Manual);
|
||||
}
|
||||
}
|
||||
private void OnSecaoSelecionadaChanged(SecaoRightBar secao)
|
||||
{
|
||||
_viewOperacaoCenter?._vm?.DefinirSecao(secao);
|
||||
}
|
||||
|
||||
private void OnLerParametrosSolicitado()
|
||||
{
|
||||
if (VariaveisControleOperacao.RoverEmFoco == null)
|
||||
return;
|
||||
|
||||
VariaveisControleOperacao.RequisitarParametrosOperacao();
|
||||
|
||||
_viewOperacaoRight?._vm?.AtualizarParametros(VariaveisControleOperacao.RoverEmFoco);
|
||||
}
|
||||
private void OnSalvarParametrosSolicitado(OperacaoParametrosModel parametros)
|
||||
{
|
||||
if (VariaveisControleOperacao.RoverEmFoco == null)
|
||||
return;
|
||||
|
||||
var rover = VariaveisControleOperacao.RoverEmFoco;
|
||||
|
||||
VariaveisControleOperacao.EnviarParametrosOperacao(new OperacaoParametrosModel()
|
||||
{
|
||||
Modo = parametros.Modo ?? AgroBase.Models.Enums.ModoOperacao.NaoDefinido,
|
||||
Descricao = parametros.Descricao,
|
||||
QtdCamerasSolo = parametros.QtdCamerasSolo,
|
||||
QtdBicos = parametros.QtdBicos,
|
||||
CapacidadeReservatorio = parametros.CapacidadeReservatorio,
|
||||
|
||||
Controle = parametros.Controle,
|
||||
|
||||
ModulosMandatorios = rover?.ModulosMandatorios,
|
||||
ParametrosMandatorios = rover?.ParametrosMandatorios,
|
||||
|
||||
RuasPercorrer = _viewOperacaoCenter?.MapaOperacao?.RuasMapaCarregado?.Where(x => x.Selected)?.Select(x => x.Id)?.ToList(),
|
||||
Mapa = _viewOperacaoCenter?.MapaOperacao?.CriarDadosMapa()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public enum ModoOperacao
|
||||
{
|
||||
Automatico = 1,
|
||||
Manual = 2
|
||||
}
|
||||
|
||||
public enum DockStep
|
||||
{
|
||||
ConfigConexao = 1,
|
||||
PreparacaoMapa = 2,
|
||||
ParametrizacaoRover = 3
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
<UserControl x:Class="OperationControl.Views.ConfigConexaoView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Background="#161616">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Cards principais -->
|
||||
<Grid Grid.Row="0" Margin="12,12,12,8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Rede -->
|
||||
<Border Grid.Column="0"
|
||||
Margin="8"
|
||||
Padding="18"
|
||||
CornerRadius="10"
|
||||
BorderThickness="2"
|
||||
Background="#202020"
|
||||
BorderBrush="{Binding CorBordaRede}">
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<TextBlock Text="REDE"
|
||||
FontSize="22"
|
||||
FontWeight="Bold"
|
||||
HorizontalAlignment="Center"
|
||||
Foreground="White"/>
|
||||
|
||||
<TextBlock Text="🌐"
|
||||
FontSize="52"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,8,0,8"/>
|
||||
|
||||
<TextBlock Text="{Binding StatusRedeTexto}"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
HorizontalAlignment="Center"
|
||||
Foreground="{Binding CorStatusRede}"
|
||||
Margin="0,0,0,8"/>
|
||||
|
||||
<TextBlock Text="{Binding DetalhesRede}"
|
||||
TextWrapping="Wrap"
|
||||
TextAlignment="Center"
|
||||
Foreground="#DDDDDD"
|
||||
Margin="0,0,0,12"/>
|
||||
|
||||
<Button Content="Configurar rede"
|
||||
Width="180"
|
||||
HorizontalAlignment="Center"
|
||||
Command="{Binding AbrirConfigRedeCommand}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- GNSS -->
|
||||
<Border Grid.Column="1"
|
||||
Margin="8"
|
||||
Padding="18"
|
||||
CornerRadius="10"
|
||||
BorderThickness="2"
|
||||
Background="#202020"
|
||||
BorderBrush="{Binding CorBordaGnss}">
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<TextBlock Text="GNSS"
|
||||
FontSize="22"
|
||||
FontWeight="Bold"
|
||||
HorizontalAlignment="Center"
|
||||
Foreground="White"/>
|
||||
|
||||
<TextBlock Text="📡"
|
||||
FontSize="52"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,8,0,8"/>
|
||||
|
||||
<TextBlock Text="{Binding StatusGnssTexto}"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
HorizontalAlignment="Center"
|
||||
Foreground="{Binding CorStatusGnss}"
|
||||
Margin="0,0,0,8"/>
|
||||
|
||||
<TextBlock Text="{Binding DetalhesGnss}"
|
||||
TextWrapping="Wrap"
|
||||
TextAlignment="Center"
|
||||
Foreground="#DDDDDD"
|
||||
Margin="0,0,0,12"/>
|
||||
|
||||
<Button Content="Ver detalhes GNSS"
|
||||
Width="180"
|
||||
HorizontalAlignment="Center"
|
||||
Command="{Binding AbrirDetalhesGnssCommand}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!-- Seleção do modo -->
|
||||
<Border Grid.Row="1"
|
||||
Margin="20,0,20,8"
|
||||
Padding="16"
|
||||
Background="#202020"
|
||||
CornerRadius="10"
|
||||
BorderBrush="#3A3A3A"
|
||||
BorderThickness="1">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Tipo de operação"
|
||||
FontSize="18"
|
||||
FontWeight="Bold"
|
||||
Foreground="White"
|
||||
Margin="0,0,0,10"/>
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<RadioButton Content="Automático"
|
||||
GroupName="ModoOperacao"
|
||||
Margin="0,0,20,0"
|
||||
FontSize="15"
|
||||
Foreground="White"
|
||||
IsChecked="{Binding OperacaoAutomaticaSelecionada, Mode=OneWay}"
|
||||
Command="{Binding SelecionarModoAutomaticoCommand}"/>
|
||||
|
||||
<RadioButton Content="Manual"
|
||||
GroupName="ModoOperacao"
|
||||
FontSize="15"
|
||||
Foreground="White"
|
||||
IsChecked="{Binding OperacaoManualSelecionada, Mode=OneWay}"
|
||||
Command="{Binding SelecionarModoManualCommand}"/>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock Text="{Binding DescricaoModoOperacao}"
|
||||
Margin="0,12,0,0"
|
||||
TextWrapping="Wrap"
|
||||
TextAlignment="Center"
|
||||
Foreground="#D0D0D0"
|
||||
FontSize="13"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Rodapé / resumo -->
|
||||
<Border Grid.Row="2"
|
||||
Margin="20,0,20,12"
|
||||
Padding="12"
|
||||
Background="#252525"
|
||||
CornerRadius="8"
|
||||
BorderBrush="#3A3A3A"
|
||||
BorderThickness="1">
|
||||
<TextBlock Text="{Binding MensagemGeral}"
|
||||
FontSize="14"
|
||||
Foreground="White"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
<UserControl x:Class="OperationControl.Views.ConfigConexaoView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Blocos principais -->
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Bloco Rede -->
|
||||
<Border Grid.Column="0"
|
||||
Margin="16"
|
||||
Padding="16"
|
||||
CornerRadius="8"
|
||||
BorderThickness="2"
|
||||
BorderBrush="{Binding CorBordaRede}">
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<TextBlock Text="REDE"
|
||||
FontSize="24"
|
||||
FontWeight="Bold"
|
||||
Margin="0,0,0,8"
|
||||
HorizontalAlignment="Center"/>
|
||||
|
||||
<!-- Ícone grandão - pode trocar por Path/Image depois -->
|
||||
<TextBlock Text="🌐"
|
||||
FontSize="64"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,8"/>
|
||||
|
||||
<TextBlock Text="{Binding StatusRedeTexto}"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,4"
|
||||
Foreground="{Binding CorStatusRede}"/>
|
||||
|
||||
<TextBlock Text="{Binding DetalhesRede}"
|
||||
TextWrapping="Wrap"
|
||||
TextAlignment="Center"
|
||||
Margin="0,0,0,8"/>
|
||||
|
||||
<Button Content="Configurar rede..."
|
||||
Width="180"
|
||||
Margin="0,8,0,0"
|
||||
Command="{Binding AbrirConfigRedeCommand}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Bloco GNSS -->
|
||||
<Border Grid.Column="1"
|
||||
Margin="16"
|
||||
Padding="16"
|
||||
CornerRadius="8"
|
||||
BorderThickness="2"
|
||||
BorderBrush="{Binding CorBordaGnss}">
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<TextBlock Text="GNSS / UM982"
|
||||
FontSize="24"
|
||||
FontWeight="Bold"
|
||||
Margin="0,0,0,8"
|
||||
HorizontalAlignment="Center"/>
|
||||
|
||||
<!-- Ícone -->
|
||||
<TextBlock Text="📡"
|
||||
FontSize="64"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,8"/>
|
||||
|
||||
<TextBlock Text="{Binding StatusGnssTexto}"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,4"
|
||||
Foreground="{Binding CorStatusGnss}"/>
|
||||
|
||||
<TextBlock Text="{Binding DetalhesGnss}"
|
||||
TextWrapping="Wrap"
|
||||
TextAlignment="Center"
|
||||
Margin="0,0,0,8"/>
|
||||
|
||||
<Button Content="Ver detalhes GNSS..."
|
||||
Width="180"
|
||||
Margin="0,8,0,0"
|
||||
Command="{Binding AbrirDetalhesGnssCommand}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!-- Linha embaixo para uma mensagem geral -->
|
||||
<TextBlock Grid.Row="1"
|
||||
Text="{Binding MensagemGeral}"
|
||||
Margin="16"
|
||||
FontSize="14"
|
||||
TextWrapping="Wrap"
|
||||
TextAlignment="Center"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
<UserControl x:Class="OperationControl.Views.Operacao.OperacaoBottomView"
|
||||
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:OperationControl.Views.Operacao"
|
||||
xmlns:conv="clr-namespace:OperationControl.Converters"
|
||||
xmlns:models="clr-namespace:OperationControl.Models"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<conv:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
|
||||
<Style x:Key="ThinScrollBar" TargetType="ScrollBar">
|
||||
<Setter Property="Height" Value="6"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ScrollBar">
|
||||
<Grid Background="Transparent">
|
||||
<Track x:Name="PART_Track" Height="6">
|
||||
<Track.DecreaseRepeatButton>
|
||||
<RepeatButton Command="ScrollBar.LineLeftCommand" Visibility="Collapsed" />
|
||||
</Track.DecreaseRepeatButton>
|
||||
<Track.IncreaseRepeatButton>
|
||||
<RepeatButton Command="ScrollBar.LineRightCommand" Visibility="Collapsed" />
|
||||
</Track.IncreaseRepeatButton>
|
||||
<Track.Thumb>
|
||||
<Thumb Height="6"
|
||||
Background="#4B5563"
|
||||
Margin="0"
|
||||
BorderThickness="0"/>
|
||||
</Track.Thumb>
|
||||
</Track>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="Transparent">
|
||||
<!-- Barra inferior -->
|
||||
<Border x:Name="brdBottom"
|
||||
Height="80"
|
||||
VerticalAlignment="Top"
|
||||
BorderBrush="#222"
|
||||
BorderThickness="1"
|
||||
Background="#11161C">
|
||||
<Grid>
|
||||
<ScrollViewer x:Name="svAlertas"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
CanContentScroll="False"
|
||||
Margin="6,0,6,0">
|
||||
<ScrollViewer.Resources>
|
||||
<Style TargetType="ScrollBar" BasedOn="{StaticResource ThinScrollBar}" />
|
||||
</ScrollViewer.Resources>
|
||||
|
||||
<ItemsControl ItemsSource="{Binding AlertasAtivos}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type models:AlertaModel}">
|
||||
<Border Margin="6,4,0,4"
|
||||
Padding="8,4"
|
||||
CornerRadius="6"
|
||||
Cursor="Hand"
|
||||
MouseLeftButtonUp="Alerta_MouseLeftButtonUp">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="#1C1F23"/>
|
||||
<Setter Property="BorderBrush" Value="#3A424F"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Severidade}" Value="Warning">
|
||||
<Setter Property="BorderBrush" Value="#EFBF2F"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Severidade}" Value="Error">
|
||||
<Setter Property="BorderBrush" Value="#FF5656"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Severidade}" Value="Critical">
|
||||
<Setter Property="BorderBrush" Value="#FF5656"/>
|
||||
<Setter Property="Background" Value="#3A171C"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Icone}"
|
||||
FontSize="14"
|
||||
Margin="0,0,6,0"/>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Titulo}"
|
||||
FontWeight="Bold"
|
||||
Foreground="#F5F7FA"
|
||||
FontSize="11"/>
|
||||
|
||||
<TextBlock Text="{Binding Mensagem}"
|
||||
Foreground="#B7C0CC"
|
||||
FontSize="10"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
MaxWidth="260"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
|
||||
<TextBlock Text="Nenhum alerta ativo"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="#636C7A"
|
||||
FontSize="11">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding AlertasAtivos.Count}" Value="0">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Toast -->
|
||||
<Border x:Name="brdToastAlerta"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Margin="0,-78,20,0"
|
||||
Padding="10,8"
|
||||
CornerRadius="8"
|
||||
Background="#1C1F23"
|
||||
BorderBrush="#3A424F"
|
||||
BorderThickness="1"
|
||||
Cursor="Hand"
|
||||
Visibility="{Binding ToastAlerta, Converter={StaticResource NullToVisibilityConverter}}"
|
||||
MouseLeftButtonUp="ToastAlerta_MouseLeftButtonUp">
|
||||
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Opacity" Value="0.95"/>
|
||||
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding ToastAlerta.Severidade}" Value="Warning">
|
||||
<Setter Property="BorderBrush" Value="#EFBF2F"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding ToastAlerta.Severidade}" Value="Error">
|
||||
<Setter Property="BorderBrush" Value="#FF5656"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding ToastAlerta.Severidade}" Value="Critical">
|
||||
<Setter Property="BorderBrush" Value="#FF5656"/>
|
||||
<Setter Property="Background" Value="#3A171C"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding ToastAlerta.Icone}"
|
||||
FontSize="16"
|
||||
Margin="0,0,6,0"/>
|
||||
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Background="#2F3B4A"
|
||||
CornerRadius="4"
|
||||
Padding="4,1"
|
||||
Margin="0,0,6,0">
|
||||
<TextBlock Text="{Binding ToastAlerta.Rover_ID}"
|
||||
Foreground="White"
|
||||
FontSize="10"
|
||||
FontWeight="Bold"/>
|
||||
</Border>
|
||||
|
||||
<TextBlock Text="{Binding ToastAlerta.Titulo}"
|
||||
FontWeight="Bold"
|
||||
Foreground="#F5F7FA"
|
||||
FontSize="11"/>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock Text="{Binding ToastAlerta.Mensagem}"
|
||||
Foreground="#B7C0CC"
|
||||
FontSize="10"
|
||||
TextWrapping="Wrap"
|
||||
MaxWidth="320"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
using OperationControl.Models;
|
||||
using OperationControl.ViewModels.Views.Operacao;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
namespace OperationControl.Views.Operacao
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for OperacaoBottomView.xaml
|
||||
/// </summary>
|
||||
public partial class OperacaoBottomView : System.Windows.Controls.UserControl
|
||||
{
|
||||
public OperacaoBottomViewModel _vm;
|
||||
|
||||
public OperacaoBottomView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = new OperacaoBottomViewModel();
|
||||
DataContext = _vm;
|
||||
}
|
||||
|
||||
public OperacaoBottomView(OperacaoBottomViewModel vm)
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = vm;
|
||||
DataContext = _vm;
|
||||
}
|
||||
|
||||
private void Alerta_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is Border border && border.DataContext is AlertaModel alerta)
|
||||
{
|
||||
_vm?.SelecionarAlerta(alerta);
|
||||
|
||||
System.Windows.MessageBox.Show(
|
||||
$"Rover: {alerta.Rover_ID}\n" +
|
||||
$"Módulo: {alerta.Modulo}\n" +
|
||||
$"Severidade: {alerta.Severidade}\n" +
|
||||
$"Mensagem: {alerta.Mensagem}\n\n" +
|
||||
$"Aqui depois podemos navegar para a ação correspondente.",
|
||||
"Alerta selecionado",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Information);
|
||||
}
|
||||
}
|
||||
|
||||
private void ToastAlerta_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
var alerta = _vm?.ToastAlerta;
|
||||
if (alerta == null)
|
||||
return;
|
||||
|
||||
_vm.LimparToast();
|
||||
_vm.SelecionarAlerta(alerta);
|
||||
|
||||
System.Windows.MessageBox.Show(
|
||||
$"Toast clicado\n\n" +
|
||||
$"Rover: {alerta.Rover_ID}\n" +
|
||||
$"Módulo: {alerta.Modulo}\n" +
|
||||
$"Severidade: {alerta.Severidade}\n" +
|
||||
$"Mensagem: {alerta.Mensagem}\n\n" +
|
||||
$"Aqui depois podemos disparar a navegação ou foco no diagnóstico.",
|
||||
"Toast de alerta",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Information);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
<UserControl x:Class="OperationControl.Views.Operacao.OperacaoCenterView"
|
||||
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:OperationControl.Views.Operacao"
|
||||
xmlns:controls="clr-namespace:OperationControl.Controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800">
|
||||
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="#181818">
|
||||
|
||||
<!-- MAPA -->
|
||||
<Grid Visibility="{Binding ExibirMapa, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Border Margin="12" Padding="0" CornerRadius="10" Background="#202020" BorderBrush="#353535" BorderThickness="1" ClipToBounds="True">
|
||||
<controls:MapViewControl x:Name="MapaOperacao" MarkerClicked="MAP_MarkerClicked" StreetMapClicked="MAP_StreetMapClicked" Latitude="-22.1726572492617" Longitude="-47.3952163870556" Scale="5000" />
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!-- DIAGNÓSTICO -->
|
||||
<Grid Visibility="{Binding ExibirDiagnostico, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Border Margin="12" Padding="20" CornerRadius="10" Background="#202020" BorderBrush="#353535" BorderThickness="1">
|
||||
<Grid>
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding TituloCentro}" HorizontalAlignment="Center" FontSize="24" FontWeight="SemiBold" Foreground="#DDDDDD" TextAlignment="Center"/>
|
||||
<TextBlock Text="{Binding SubtituloCentro}" HorizontalAlignment="Center" Margin="0,14,0,0" FontSize="14" Foreground="#AAAAAA" TextAlignment="Center" TextWrapping="Wrap" MaxWidth="500"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!-- MONITORAMENTO -->
|
||||
<Grid Visibility="{Binding ExibirMonitoramento, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Border Margin="12" Padding="20" CornerRadius="10" Background="#202020" BorderBrush="#353535" BorderThickness="1">
|
||||
<Grid>
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding TituloCentro}" HorizontalAlignment="Center" FontSize="24" FontWeight="SemiBold" Foreground="#DDDDDD" TextAlignment="Center"/>
|
||||
<TextBlock Text="{Binding SubtituloCentro}" HorizontalAlignment="Center" Margin="0,14,0,0" FontSize="14" Foreground="#AAAAAA" TextAlignment="Center" TextWrapping="Wrap" MaxWidth="500"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border x:Name="brdCameraFrontal" BorderBrush="Black" BorderThickness="1" CornerRadius="8" Margin="1453,0,7,735">
|
||||
<Canvas>
|
||||
<Label Content="Câmera frontal | 12 fps | 230 kbps | 0,00% cana | 43 cm - 27 cm | 12,95° | CaminhandoRua" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="-3"/>
|
||||
<!--<vlc:VideoView x:Name="VideoFront" Background="Black" Height="237" Width="438" HorizontalAlignment="Center" Canvas.Top="25" VerticalAlignment="Top" Canvas.Left="10"/>-->
|
||||
<Grid Width="438" Height="237" Canvas.Top="25" Canvas.Left="10" Background="Black">
|
||||
<TextBlock Text="SEM SINAL" Foreground="Gray" FontSize="18" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
<Image x:Name="imgVideoFront" Stretch="Uniform" RenderOptions.BitmapScalingMode="LowQuality" />
|
||||
</Grid>
|
||||
<ComboBox x:Name="cmbCameraFrontalFrameTipo" Canvas.Left="10" Canvas.Top="25" HorizontalAlignment="Left" VerticalAlignment="Center" Width="100" SelectionChanged="cmbCameraFrontalFrameTipo_SelectionChanged" />
|
||||
</Canvas>
|
||||
</Border>
|
||||
|
||||
<Border x:Name="brdCameraTraseira" BorderBrush="Black" BorderThickness="1" CornerRadius="8" Margin="1453,281,7,491">
|
||||
<Canvas>
|
||||
<Label Content="Câmera traseira | 10 fps | 193 kbps | 5,41% erva | 0,00% cana" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="-3"/>
|
||||
<!--<vlc:VideoView x:Name="VideoWeed" Background="Black" Height="200" Width="438" HorizontalAlignment="Center" Canvas.Top="25" VerticalAlignment="Top" Canvas.Left="10"/>-->
|
||||
<Grid Width="438" Height="200" Canvas.Top="25" Canvas.Left="10" Background="Black">
|
||||
<TextBlock Text="SEM SINAL" Foreground="Gray" FontSize="18" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
<Image x:Name="imgVideoWeed" Stretch="Uniform" RenderOptions.BitmapScalingMode="LowQuality" />
|
||||
</Grid>
|
||||
<ComboBox x:Name="cmbCameraTraseiraFrameTipo" Canvas.Left="10" Canvas.Top="25" HorizontalAlignment="Left" VerticalAlignment="Center" Width="100" SelectionChanged="cmbCameraTraseiraFrameTipo_SelectionChanged" />
|
||||
</Canvas>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
using OperationControl.Controls;
|
||||
using OperationControl.Models;
|
||||
using OperationControl.ViewModels.Views.Operacao;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace OperationControl.Views.Operacao
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for OperacaoCenterView.xaml
|
||||
/// </summary>
|
||||
public partial class OperacaoCenterView : System.Windows.Controls.UserControl
|
||||
{
|
||||
public OperacaoCenterViewModel _vm;
|
||||
|
||||
public OperacaoCenterView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = new OperacaoCenterViewModel();
|
||||
DataContext = _vm;
|
||||
|
||||
videoFront = new TcpVideoReceiver(5000, imgVideoFront);
|
||||
videoWeed = new TcpVideoReceiver(5002, imgVideoWeed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private TcpVideoReceiver videoFront;
|
||||
private TcpVideoReceiver videoWeed;
|
||||
|
||||
#region CAMERA FRONTAL
|
||||
|
||||
private void cmbCameraFrontalFrameTipo_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (VariaveisControleOperacao.SelectedRoverId == VariaveisControleOperacao.BaseMarkerID) return;
|
||||
PararStreamCameraFrontal();
|
||||
IniciarStreamCameraFrontal();
|
||||
}
|
||||
|
||||
public void IniciarStreamCameraFrontal()
|
||||
{
|
||||
videoFront.Iniciar();
|
||||
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Snr, true, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraFrontalFrameTipo.SelectedIndex));
|
||||
}
|
||||
|
||||
public void PararStreamCameraFrontal(bool finalizar = false)
|
||||
{
|
||||
videoFront.Parar();
|
||||
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Snr, false, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraFrontalFrameTipo.SelectedIndex));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CAMERA ERVAS
|
||||
|
||||
private void cmbCameraTraseiraFrameTipo_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (VariaveisControleOperacao.SelectedRoverId == VariaveisControleOperacao.BaseMarkerID) return;
|
||||
PararStreamCameraErvas();
|
||||
IniciarStreamCameraErvas();
|
||||
}
|
||||
|
||||
public void IniciarStreamCameraErvas()
|
||||
{
|
||||
videoWeed.Iniciar();
|
||||
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Cam, true, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraTraseiraFrameTipo.SelectedIndex));
|
||||
}
|
||||
|
||||
public void PararStreamCameraErvas(bool finalizar = false)
|
||||
{
|
||||
videoWeed.Parar();
|
||||
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Cam, false, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraTraseiraFrameTipo.SelectedIndex));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
private void MAP_MarkerClicked(object? sender, MapMarkerManager.MarkerClickedEventArgs e)
|
||||
{
|
||||
_vm.ProcessarMarkerClicked(e);
|
||||
}
|
||||
|
||||
private void MAP_StreetMapClicked(object? sender, MapViewControl.StreetMapClickedEventArgs e)
|
||||
{
|
||||
_vm.ProcessarStreetMapClicked(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
<UserControl x:Class="OperationControl.Views.Operacao.OperacaoLeftView"
|
||||
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:OperationControl.Views.Operacao"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="700" d:DesignWidth="280">
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="LeftInfoCardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#2A2A2A"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Padding" Value="10,8"/>
|
||||
<Setter Property="Margin" Value="0,0,0,8"/>
|
||||
<Setter Property="BorderBrush" Value="#3A3A3A"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="LeftActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Height" Value="42"/>
|
||||
<Setter Property="Margin" Value="0,0,0,8"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="8">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="#181818">
|
||||
<Border Margin="10"
|
||||
Padding="12"
|
||||
CornerRadius="10"
|
||||
Background="#202020"
|
||||
BorderBrush="#343434"
|
||||
BorderThickness="1">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- CONTEÚDO SUPERIOR -->
|
||||
<ScrollViewer Grid.Row="0"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
<StackPanel Opacity="{Binding OpacityPainel}">
|
||||
<TextBlock Text="Operação em Andamento"
|
||||
FontSize="18"
|
||||
FontWeight="Bold"
|
||||
Foreground="White"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,6"/>
|
||||
|
||||
<TextBlock Text="{Binding NomeRover}"
|
||||
FontSize="14"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="#D0D0D0"
|
||||
HorizontalAlignment="Center"
|
||||
TextAlignment="Center"
|
||||
Margin="0,0,0,14"/>
|
||||
|
||||
<Border Style="{StaticResource LeftInfoCardStyle}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="36"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="🚜" FontSize="18" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1" Text="Velocidade" Foreground="White" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2" Text="{Binding Velocidade}" Foreground="White" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource LeftInfoCardStyle}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="36"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="↩" FontSize="18" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1" Text="Ângulo direcional" Foreground="White" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2" Text="{Binding AnguloDirecional}" Foreground="White" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource LeftInfoCardStyle}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="36"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="⇄" FontSize="18" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1" Text="Movimento" Foreground="White" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2" Text="{Binding TipoMovimento}" Foreground="White" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource LeftInfoCardStyle}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="36"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="🌡" FontSize="18" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1" Text="Temperatura" Foreground="White" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2" Text="{Binding Temperatura}" Foreground="{Binding CorTemperatura}" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource LeftInfoCardStyle}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="36"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="🔋" FontSize="18" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1" Text="Bateria" Foreground="White" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2" Text="{Binding Bateria}" Foreground="{Binding CorBateria}" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource LeftInfoCardStyle}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="36"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="🧪" FontSize="18" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1" Text="Reservatório" Foreground="White" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2" Text="{Binding Reservatorio}" Foreground="{Binding CorReservatorio}" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource LeftInfoCardStyle}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="36"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="📶" FontSize="18" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1" Text="Rede" Foreground="White" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2" Text="{Binding SaudeRede}" Foreground="{Binding CorRede}" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource LeftInfoCardStyle}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="36"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="📡" FontSize="18" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1" Text="GNSS" Foreground="White" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2" Text="{Binding SaudeGnss}" Foreground="{Binding CorGnss}" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- RODAPÉ FIXO -->
|
||||
<Border Grid.Row="1"
|
||||
Margin="0,12,0,0"
|
||||
Padding="10"
|
||||
CornerRadius="10"
|
||||
Background="#1A1A1A"
|
||||
BorderBrush="#343434"
|
||||
BorderThickness="1"
|
||||
IsEnabled="{Binding RoverSelecionado}"
|
||||
Opacity="{Binding OpacityPainel}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Ações principais"
|
||||
Foreground="#CFCFCF"
|
||||
FontSize="13"
|
||||
FontWeight="SemiBold"
|
||||
Margin="0,0,0,10"/>
|
||||
|
||||
<Button Content="{Binding TextoBotaoOperacao}"
|
||||
Command="{Binding AlternarOperacaoCommand}"
|
||||
Style="{StaticResource LeftActionButtonStyle}"
|
||||
Background="{Binding CorBotaoOperacao}"
|
||||
BorderBrush="{Binding BordaBotaoOperacao}"/>
|
||||
|
||||
<Button Content="⛔ Parada de Emergência"
|
||||
Command="{Binding ParadaEmergenciaCommand}"
|
||||
Style="{StaticResource LeftActionButtonStyle}"
|
||||
Background="#7A1E1E"
|
||||
BorderBrush="#B83A3A"/>
|
||||
|
||||
<Button Content="✖ Cancelar Operação"
|
||||
Command="{Binding CancelarOperacaoCommand}"
|
||||
Style="{StaticResource LeftActionButtonStyle}"
|
||||
Background="#3A3A3A"
|
||||
BorderBrush="#666666"
|
||||
Margin="0,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using OperationControl.ViewModels.Views.Operacao;
|
||||
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 OperationControl.Views.Operacao
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for OperacaoLeftView.xaml
|
||||
/// </summary>
|
||||
public partial class OperacaoLeftView : System.Windows.Controls.UserControl
|
||||
{
|
||||
public OperacaoLeftViewModel _vm;
|
||||
|
||||
public OperacaoLeftView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = new OperacaoLeftViewModel();
|
||||
DataContext = _vm;
|
||||
|
||||
_vm.DefinirSemRover();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,497 @@
|
|||
<UserControl x:Class="OperationControl.Views.Operacao.OperacaoRightView"
|
||||
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:OperationControl.Views.Operacao"
|
||||
mc:Ignorable="d">
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
||||
|
||||
<Style x:Key="MenuButtonStyle" TargetType="Button">
|
||||
<Setter Property="Margin" Value="0,0,0,10"/>
|
||||
<Setter Property="Height" Value="52"/>
|
||||
<Setter Property="FontSize" Value="16"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Background" Value="#2A2A2A"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#4A4A4A"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="10"
|
||||
Padding="12">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#343434"/>
|
||||
<Setter Property="BorderBrush" Value="#6A6A6A"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="RoverCardButtonStyle" TargetType="Button">
|
||||
<Setter Property="Margin" Value="0,0,0,12"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ThinScrollBar" TargetType="ScrollBar">
|
||||
<Setter Property="Width" Value="8"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ScrollBar">
|
||||
<Grid Width="8" Background="Transparent">
|
||||
<Border Margin="2,0,2,0" Background="#2F2F2F" CornerRadius="3"/>
|
||||
<Track x:Name="PART_Track" Margin="2,0,2,0" IsDirectionReversed="True">
|
||||
<Track.DecreaseRepeatButton>
|
||||
<RepeatButton Opacity="0" IsHitTestVisible="False"/>
|
||||
</Track.DecreaseRepeatButton>
|
||||
<Track.Thumb>
|
||||
<Thumb>
|
||||
<Thumb.Template>
|
||||
<ControlTemplate TargetType="Thumb">
|
||||
<Border Background="#6B7280" CornerRadius="3" MinHeight="30"/>
|
||||
</ControlTemplate>
|
||||
</Thumb.Template>
|
||||
</Thumb>
|
||||
</Track.Thumb>
|
||||
<Track.IncreaseRepeatButton>
|
||||
<RepeatButton Opacity="0" IsHitTestVisible="False"/>
|
||||
</Track.IncreaseRepeatButton>
|
||||
</Track>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="#1C1C1C">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="60"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Cabeçalho -->
|
||||
<Border Grid.Row="0" Background="#222222" BorderBrush="#343434" BorderThickness="0,0,0,1">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="44"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Text="Painel do Operador" VerticalAlignment="Center" Margin="16,0,0,0" Foreground="White" FontSize="18" FontWeight="SemiBold"/>
|
||||
|
||||
<Button Grid.Column="1" Content="❯" Width="32" Height="32" Margin="0,0,8,0" HorizontalAlignment="Center" VerticalAlignment="Center" Command="{Binding ToggleCollapseCommand}">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="#2E2E2E"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#505050"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="8">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsCollapsed}" Value="True">
|
||||
<Setter Property="Content" Value="❮"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Conteúdo -->
|
||||
<Grid Grid.Row="1" Margin="14">
|
||||
<Grid.Style>
|
||||
<Style TargetType="Grid">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsCollapsed}" Value="True">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
|
||||
<!-- Sem rover selecionado -->
|
||||
<Grid Visibility="{Binding SemRoverSelecionado, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Margin="0,0,0,12">
|
||||
<TextBlock Text="Selecione um rover disponível na rede" Foreground="#D0D0D0" FontSize="14" Margin="0,0,0,4"/>
|
||||
<TextBlock Text="{Binding QuantidadeRoversTexto}" Foreground="#8E8E8E" FontSize="12"/>
|
||||
</StackPanel>
|
||||
|
||||
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
|
||||
<ItemsControl ItemsSource="{Binding Rovers}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Button Style="{StaticResource RoverCardButtonStyle}" Command="{Binding DataContext.SelecionarRoverCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" CommandParameter="{Binding}">
|
||||
<Border Background="{Binding CardBackground}" BorderBrush="{Binding BordaCardBrush}" BorderThickness="{Binding BordaCardThickness}" CornerRadius="12" Padding="14" SnapsToDevicePixels="True">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding EquipamentoTexto}" Foreground="White" FontSize="16" FontWeight="Bold"/>
|
||||
<TextBlock Text="{Binding NumeroSerieTexto}" Foreground="#CFCFCF" Margin="0,8,0,0" FontSize="13"/>
|
||||
<TextBlock Text="{Binding StatusTexto}" Foreground="{Binding StatusBrush}" Margin="0,8,0,0" FontSize="13" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
|
||||
<!-- Com rover selecionado -->
|
||||
<Grid Visibility="{Binding ComRoverSelecionado, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.Row="0" Background="#262626" BorderBrush="#4E8EF7" BorderThickness="1" CornerRadius="12" Padding="14" Margin="0,0,0,14">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding RoverSelecionado.EquipamentoTexto}" Foreground="White" FontSize="16" FontWeight="Bold"/>
|
||||
<TextBlock Text="{Binding RoverSelecionado.NumeroSerieTexto}" Foreground="#CFCFCF" Margin="0,8,0,0" FontSize="13"/>
|
||||
<TextBlock Text="{Binding RoverSelecionado.StatusTexto}" Foreground="{Binding RoverSelecionado.StatusBrush}" Margin="0,8,0,0" FontSize="13" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Button Grid.Row="1" Content="{Binding TextoBotaoTopo}" Command="{Binding AcaoBotaoTopoCommand}" Margin="0,0,0,14" Height="42" Background="#2E2E2E" Foreground="White" BorderBrush="#555555" BorderThickness="1"/>
|
||||
|
||||
<Grid Grid.Row="2">
|
||||
|
||||
<!-- MENU -->
|
||||
<StackPanel Visibility="{Binding EmMenu, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Button Content="Diagnóstico" Style="{StaticResource MenuButtonStyle}" Command="{Binding SelecionarSecaoCommand}" CommandParameter="Diagnostico"/>
|
||||
|
||||
<Button Content="Parametrização ▶" Style="{StaticResource MenuButtonStyle}" Command="{Binding SelecionarSecaoCommand}" CommandParameter="Parametrizacao"/>
|
||||
|
||||
<Button Content="Controle ▶" Style="{StaticResource MenuButtonStyle}" Command="{Binding SelecionarSecaoCommand}" CommandParameter="Controle"/>
|
||||
|
||||
<Button Content="Resumo ▶" Style="{StaticResource MenuButtonStyle}" Command="{Binding SelecionarSecaoCommand}" CommandParameter="Resumo"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- RESUMO -->
|
||||
<ScrollViewer Visibility="{Binding EmResumo, Converter={StaticResource BoolToVisibilityConverter}}" VerticalScrollBarVisibility="Auto">
|
||||
<ScrollViewer.Resources>
|
||||
<Style TargetType="ScrollBar" BasedOn="{StaticResource ThinScrollBar}" />
|
||||
</ScrollViewer.Resources>
|
||||
<StackPanel>
|
||||
<!-- CARD ESTADO GERAL -->
|
||||
<Border Background="#262626" BorderBrush="#3E3E3E" BorderThickness="1" CornerRadius="10" Padding="12" Margin="0,0,0,10">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Estado Geral" Foreground="White" FontSize="16" FontWeight="Bold" Margin="0,0,0,12"/>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="100"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="Operação" Foreground="#CFCFCF" Margin="0,0,0,8"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Resumo.Operacao}" Foreground="White" Margin="12,0,0,8"/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="Modo" Foreground="#CFCFCF" Margin="0,0,0,8"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Resumo.Modo}" Foreground="White" Margin="12,0,0,8"/>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Status" Foreground="#CFCFCF" Margin="0,0,0,8"/>
|
||||
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Resumo.Status}" Foreground="White" Margin="12,0,0,8" TextWrapping="Wrap"/>
|
||||
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="Carro" Foreground="#CFCFCF" Margin="0,0,0,8"/>
|
||||
<TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding Resumo.Carro}" Foreground="White" Margin="12,0,0,8"/>
|
||||
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" Text="Temperatura" Foreground="#CFCFCF" Margin="0,0,0,8"/>
|
||||
<TextBlock Grid.Row="4" Grid.Column="1" Text="{Binding Resumo.Temperatura}" Foreground="White" Margin="12,0,0,8"/>
|
||||
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" Text="Conexão" Foreground="#CFCFCF" Margin="0,0,0,8"/>
|
||||
<TextBlock Grid.Row="5" Grid.Column="1" Text="{Binding Resumo.Conexao}" Foreground="White" Margin="12,0,0,8"/>
|
||||
|
||||
<TextBlock Grid.Row="6" Grid.Column="0" Text="Duração" Foreground="#CFCFCF" Margin="0,0,0,0"/>
|
||||
<TextBlock Grid.Row="6" Grid.Column="1" Text="{Binding Resumo.Duracao}" Foreground="White" Margin="12,0,0,0"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- CARD PROGRESSO -->
|
||||
<Border Background="#262626" BorderBrush="#3E3E3E" BorderThickness="1" CornerRadius="10" Padding="12" Margin="0,0,0,10">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Progresso e Recursos" Foreground="White" FontSize="16" FontWeight="Bold" Margin="0,0,0,12"/>
|
||||
|
||||
<!-- Rua Atual -->
|
||||
<TextBlock Text="Rua Atual" Foreground="#CFCFCF"/>
|
||||
<ProgressBar Value="{Binding Resumo.RuaAtualPercentual}" Maximum="100" Height="12" Margin="0,6,0,4"/>
|
||||
<TextBlock Text="{Binding Resumo.RuaAtual}" Foreground="White" Margin="0,0,0,12"/>
|
||||
|
||||
<!-- Área Total -->
|
||||
<TextBlock Text="Área Total" Foreground="#CFCFCF"/>
|
||||
<ProgressBar Value="{Binding Resumo.AreaTotalPercentual}" Maximum="100" Height="12" Margin="0,6,0,4"/>
|
||||
<TextBlock Text="{Binding Resumo.AreaTotal}" Foreground="White" Margin="0,0,0,12"/>
|
||||
|
||||
<!-- Bateria -->
|
||||
<TextBlock Text="Bateria" Foreground="#CFCFCF"/>
|
||||
<ProgressBar Value="{Binding Resumo.BateriaPercentual}" Maximum="100" Height="12" Margin="0,6,0,4"/>
|
||||
<TextBlock Text="{Binding Resumo.Bateria}" Foreground="White" Margin="0,0,0,12"/>
|
||||
|
||||
<!-- Herbicida -->
|
||||
<TextBlock Text="Herbicida" Foreground="#CFCFCF"/>
|
||||
<ProgressBar Value="{Binding Resumo.HerbicidaPercentual}" Maximum="100" Height="12" Margin="0,6,0,4"/>
|
||||
<TextBlock Text="{Binding Resumo.Herbicida}" Foreground="White" Margin="0,0,0,12"/>
|
||||
|
||||
<!-- Infestação -->
|
||||
<TextBlock Text="Infestação" Foreground="#CFCFCF"/>
|
||||
<ProgressBar Value="{Binding Resumo.InfestacaoPercentual}" Maximum="100" Height="12" Margin="0,6,0,4"/>
|
||||
<TextBlock Text="{Binding Resumo.Infestacao}" Foreground="White"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- PARAMETRIZAÇÃO -->
|
||||
<ScrollViewer Visibility="{Binding EmParametrizacao, Converter={StaticResource BoolToVisibilityConverter}}" VerticalScrollBarVisibility="Auto">
|
||||
<ScrollViewer.Resources>
|
||||
<Style TargetType="ScrollBar" BasedOn="{StaticResource ThinScrollBar}" />
|
||||
|
||||
<Style x:Key="ParamLabelStyle" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#D0D0D0"/>
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Margin" Value="0,0,0,6"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ParamTextBoxStyle" TargetType="TextBox">
|
||||
<Setter Property="Height" Value="34"/>
|
||||
<Setter Property="Margin" Value="0,0,0,12"/>
|
||||
<Setter Property="Padding" Value="8,4"/>
|
||||
<Setter Property="Background" Value="#2B2B2B"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#5A5A5A"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SectionCardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#262626"/>
|
||||
<Setter Property="BorderBrush" Value="#3E3E3E"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="CornerRadius" Value="10"/>
|
||||
<Setter Property="Padding" Value="12"/>
|
||||
<Setter Property="Margin" Value="0,0,0,12"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Height" Value="40"/>
|
||||
<Setter Property="Margin" Value="0,0,0,10"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="8">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ParamCheckBoxStyle" TargetType="CheckBox">
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="Margin" Value="0,0,0,10"/>
|
||||
</Style>
|
||||
</ScrollViewer.Resources>
|
||||
|
||||
<StackPanel Margin="0,0,2,0">
|
||||
<TextBlock Text="Parametrização" Foreground="White" FontSize="18" FontWeight="Bold" Margin="0,0,0,4"/>
|
||||
|
||||
<TextBlock Text="Configure os parâmetros operacionais do rover." Foreground="#A8A8A8" FontSize="12" Margin="0,0,0,14"/>
|
||||
|
||||
<!-- OPERACAO -->
|
||||
<Border Style="{StaticResource SectionCardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Operação" Foreground="White" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,12"/>
|
||||
|
||||
<TextBlock Text="Descrição" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Descricao}" Style="{StaticResource ParamTextBoxStyle}" Margin="0,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- AUTOMAÇÃO GERAL -->
|
||||
<Border Style="{StaticResource SectionCardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Automação Geral" Foreground="White" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,12"/>
|
||||
|
||||
<CheckBox Content="Movimento Automático" IsChecked="{Binding Parametros.Controle.MovimentoAutomatico}" Style="{StaticResource ParamCheckBoxStyle}"/>
|
||||
|
||||
<CheckBox Content="Direcional Automático" IsChecked="{Binding Parametros.Controle.DirecionalAutomatico}" Style="{StaticResource ParamCheckBoxStyle}"/>
|
||||
|
||||
<CheckBox Content="Pulverizador Automático" IsChecked="{Binding Parametros.Controle.PulverizadorAutomatico}" Style="{StaticResource ParamCheckBoxStyle}"/>
|
||||
|
||||
<CheckBox Content="Sonar Ativado" IsChecked="{Binding Parametros.Controle.SonarAtivado}" Style="{StaticResource ParamCheckBoxStyle}"/>
|
||||
|
||||
<CheckBox Content="Parada por Obstáculo (OAK)" IsChecked="{Binding Parametros.Controle.OakParadaPorObstaculo}" Style="{StaticResource ParamCheckBoxStyle}"/>
|
||||
|
||||
<CheckBox Content="Parada por Inclinação (IMU)" IsChecked="{Binding Parametros.Controle.ImuParadaPorInclinacao}" Style="{StaticResource ParamCheckBoxStyle}"/>
|
||||
|
||||
<CheckBox Content="Frenagem Automática ao Parar" IsChecked="{Binding Parametros.Controle.FrenagemAutomaticaAoParar}" Style="{StaticResource ParamCheckBoxStyle}"/>
|
||||
|
||||
<CheckBox Content="Registrar Dados Pós-Processamento" IsChecked="{Binding Parametros.Controle.RegistrarDadosPosProcessamento}" Style="{StaticResource ParamCheckBoxStyle}" Margin="0,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- MOVIMENTO -->
|
||||
<Border Style="{StaticResource SectionCardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Movimento" Foreground="White" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,12"/>
|
||||
|
||||
<TextBlock Text="Velocidade sem Ervas (%)" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.MovVelocidadeSErvasPercent, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Velocidade com Ervas (%)" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.MovVelocidadeCErvasPercent, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="RPM Máx Calculado" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.MovRpmMax, Mode=OneWay}" IsReadOnly="True" Style="{StaticResource ParamTextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="RPM Mín Calculado" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.MovRpmMin, Mode=OneWay}" IsReadOnly="True" Style="{StaticResource ParamTextBoxStyle}" Margin="0,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- DIRECIONAL -->
|
||||
<Border Style="{StaticResource SectionCardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Direcional" Foreground="White" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,12"/>
|
||||
|
||||
<TextBlock Text="Ângulo Máximo (°)" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.DirAnguloMaximo, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Velocidade Movimento" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.DirVelocidadeMovimento, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Tipo de Movimento" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.DirTipoMovimento, Mode=OneWay}" IsReadOnly="True" Style="{StaticResource ParamTextBoxStyle}" Margin="0,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- PULVERIZAÇÃO -->
|
||||
<Border Style="{StaticResource SectionCardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Pulverização" Foreground="White" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,12"/>
|
||||
|
||||
<TextBlock Text="Quantidade de Bicos" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.QtdBicos, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Capacidade do Reservatório (L)" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.CapacidadeReservatorio, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Pressão Linha" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.AtuPressaoLinha, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Duração Atuação (ms)" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.AtuDuracaoAtuacao, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Início Pulverização (%)" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.AtuPercentualInicioPulverizacao, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Altura Área Pulverização" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.AtuAlturaAreaPulverizacao, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Ervas Bico On (%)" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.AtuPercentualErvasBicoOn, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Ervas Bico Off (%)" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.AtuPercentualErvasBicoOff, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}" Margin="0,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- MPC -->
|
||||
<Border Style="{StaticResource SectionCardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="MPC" Foreground="White" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,12"/>
|
||||
|
||||
<CheckBox Content="Matriz de Custo" IsChecked="{Binding Parametros.Controle.MpcMatrizCusto}" Style="{StaticResource ParamCheckBoxStyle}"/>
|
||||
|
||||
<TextBlock Text="Horizonte (m)" Style="{StaticResource ParamLabelStyle}"/>
|
||||
<TextBox Text="{Binding Parametros.Controle.MpcHorizonte, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ParamTextBoxStyle}" Margin="0,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- AÇÕES -->
|
||||
<Border Style="{StaticResource SectionCardStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Ações" Foreground="White" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,12"/>
|
||||
|
||||
<Button Content="↻ Ler do Rover" Command="{Binding LerParametrosCommand}" Background="#2E2E2E" BorderBrush="#5C5C5C" Style="{StaticResource ActionButtonStyle}"/>
|
||||
|
||||
<Button Content="💾 Salvar no Rover" Command="{Binding SalvarParametrosCommand}" Background="#2F5D3A" BorderBrush="#4A8A5B" Style="{StaticResource ActionButtonStyle}" Margin="0,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- CONTROLE -->
|
||||
<ScrollViewer Visibility="{Binding EmControle, Converter={StaticResource BoolToVisibilityConverter}}" VerticalScrollBarVisibility="Auto">
|
||||
<ScrollViewer.Resources>
|
||||
<Style TargetType="ScrollBar" BasedOn="{StaticResource ThinScrollBar}" />
|
||||
</ScrollViewer.Resources>
|
||||
<StackPanel>
|
||||
<TextBlock Text="Controle" Foreground="White" FontSize="16" FontWeight="Bold"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
using OperationControl.ViewModels.Views.Operacao;
|
||||
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 OperationControl.Views.Operacao
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for OperacaoRightView.xaml
|
||||
/// </summary>
|
||||
public partial class OperacaoRightView : System.Windows.Controls.UserControl
|
||||
{
|
||||
public OperacaoRightViewModel _vm;
|
||||
|
||||
public OperacaoRightView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = new OperacaoRightViewModel();
|
||||
DataContext = _vm;
|
||||
}
|
||||
|
||||
public OperacaoRightView(OperacaoRightViewModel vm)
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = vm;
|
||||
DataContext = _vm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
<UserControl x:Class="OperationControl.Views.Operacao.OperacaoTopView"
|
||||
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:OperationControl.Views.Operacao"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="70" d:DesignWidth="1200">
|
||||
<Border Background="{Binding CorFundo}"
|
||||
CornerRadius="10"
|
||||
Padding="14,10"
|
||||
Margin="10,8,10,6">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="260"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="160"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Contexto -->
|
||||
<Border Grid.Column="0"
|
||||
Background="#22000000"
|
||||
CornerRadius="8"
|
||||
Padding="12,8"
|
||||
Margin="0,0,12,0">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock Text="Selecionado: "
|
||||
Foreground="#D8D8D8"
|
||||
FontSize="14"
|
||||
VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding ContextoSelecionado}"
|
||||
Foreground="{Binding CorTexto}"
|
||||
FontSize="16"
|
||||
FontWeight="Bold"
|
||||
VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Mensagem principal -->
|
||||
<Border Grid.Column="1"
|
||||
Background="#16000000"
|
||||
CornerRadius="8"
|
||||
Padding="14,8"
|
||||
Margin="0,0,12,0">
|
||||
<TextBlock Text="{Binding MensagemStatus}"
|
||||
Foreground="{Binding CorTexto}"
|
||||
FontSize="17"
|
||||
FontWeight="SemiBold"
|
||||
TextWrapping="Wrap"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
TextAlignment="Center"/>
|
||||
</Border>
|
||||
|
||||
<!-- Badge -->
|
||||
<Border Grid.Column="2"
|
||||
Background="{Binding CorBadge}"
|
||||
CornerRadius="18"
|
||||
Padding="12,8"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
MinWidth="120">
|
||||
<TextBlock Text="{Binding BadgeTexto}"
|
||||
Foreground="Black"
|
||||
FontWeight="Bold"
|
||||
FontSize="14"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
TextAlignment="Center"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using OperationControl.ViewModels.Views.Operacao;
|
||||
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 OperationControl.Views.Operacao
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for OperacaoTopView.xaml
|
||||
/// </summary>
|
||||
public partial class OperacaoTopView : System.Windows.Controls.UserControl
|
||||
{
|
||||
public OperacaoTopViewModel _vm;
|
||||
|
||||
public OperacaoTopView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = new OperacaoTopViewModel();
|
||||
DataContext = _vm;
|
||||
|
||||
_vm.DefinirStatusNormal("BASE", "Sistema pronto para operação.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<UserControl x:Class="OperationControl.Views.PreparacaoMapaBottomView"
|
||||
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:OperationControl.Views"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
|
||||
<Grid Background="#181818" Margin="0">
|
||||
|
||||
<!-- Duas linhas -->
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Linha 1 -->
|
||||
<Grid Grid.Row="0">
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="320"/>
|
||||
<ColumnDefinition Width="70"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Botão carregar mapa -->
|
||||
<Button Grid.Column="0"
|
||||
Content="Carregar mapa"
|
||||
Margin="12,12,8,6"
|
||||
Padding="18,10"
|
||||
MinWidth="150"
|
||||
Command="{Binding CarregarMapaCommand}"
|
||||
IsEnabled="{Binding PodeCarregarMapa}"/>
|
||||
|
||||
<!-- Botão fixar base -->
|
||||
<Button Grid.Column="1"
|
||||
Content="{Binding TextoBotaoFixarBase}"
|
||||
Margin="8,12,12,6"
|
||||
Padding="18,10"
|
||||
MinWidth="180"
|
||||
Command="{Binding FixarBaseCommand}"/>
|
||||
|
||||
<!-- Barra de progresso -->
|
||||
<ProgressBar Grid.Column="2"
|
||||
Margin="12,20,8,8"
|
||||
Height="22"
|
||||
Minimum="0"
|
||||
Maximum="100"
|
||||
Value="{Binding ProgressoFixacao}"/>
|
||||
|
||||
<!-- Texto % -->
|
||||
<TextBlock Grid.Column="3"
|
||||
Text="{Binding ProgressoFixacaoTexto}"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Foreground="White"
|
||||
FontWeight="SemiBold"
|
||||
FontSize="14"
|
||||
Margin="0,0,8,0"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Linha 2 : Status -->
|
||||
<Border Grid.Row="1"
|
||||
Margin="12,4,12,10"
|
||||
Padding="8"
|
||||
Background="#222"
|
||||
CornerRadius="6">
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="Status da operação" Foreground="#AAAAAA" FontSize="11"/>
|
||||
<TextBlock Text="{Binding StatusTexto}" Foreground="White" FontSize="14" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using OperationControl.ViewModels;
|
||||
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 OperationControl.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for PreparacaoMapaBottomView.xaml
|
||||
/// </summary>
|
||||
public partial class PreparacaoMapaBottomView : System.Windows.Controls.UserControl
|
||||
{
|
||||
public PreparacaoMapaBottomViewModel _vm;
|
||||
|
||||
public PreparacaoMapaBottomView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = new PreparacaoMapaBottomViewModel();
|
||||
DataContext = _vm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
<UserControl x:Class="OperationControl.Views.PreparacaoMapaTopView"
|
||||
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:OperationControl.Views"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid Background="#222222" Margin="0">
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Disabled">
|
||||
<StackPanel Orientation="Horizontal" Margin="8,6">
|
||||
|
||||
<Border Background="#2E2E2E" CornerRadius="8" Padding="12" Margin="4,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Latitude" Foreground="#BFBFBF" FontSize="11"/>
|
||||
<TextBlock Text="{Binding LatitudeTexto}" Foreground="White" FontSize="16" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Background="#2E2E2E" CornerRadius="8" Padding="12" Margin="4,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Longitude" Foreground="#BFBFBF" FontSize="11"/>
|
||||
<TextBlock Text="{Binding LongitudeTexto}" Foreground="White" FontSize="16" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Background="#2E2E2E" CornerRadius="8" Padding="12" Margin="4,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Altitude" Foreground="#BFBFBF" FontSize="11"/>
|
||||
<TextBlock Text="{Binding AltitudeTexto}" Foreground="White" FontSize="16" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Background="#2E2E2E" CornerRadius="8" Padding="12" Margin="4,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Heading" Foreground="#BFBFBF" FontSize="11"/>
|
||||
<TextBlock Text="{Binding HeadingTexto}" Foreground="White" FontSize="16" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Background="#2E2E2E" CornerRadius="8" Padding="12" Margin="4,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Fix" Foreground="#BFBFBF" FontSize="11"/>
|
||||
<TextBlock Text="{Binding FixTexto}" Foreground="{Binding FixCor}" FontSize="16" FontWeight="Bold"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Background="#2E2E2E" CornerRadius="8" Padding="12" Margin="4,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Precisão" Foreground="#BFBFBF" FontSize="11"/>
|
||||
<TextBlock Text="{Binding PrecisaoTexto}" Foreground="White" FontSize="16" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Background="#2E2E2E" CornerRadius="8" Padding="12" Margin="4,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Satélites" Foreground="#BFBFBF" FontSize="11"/>
|
||||
<TextBlock Text="{Binding SatelitesTexto}" Foreground="White" FontSize="16" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Background="#2E2E2E" CornerRadius="8" Padding="12" Margin="4,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Idade Correção" Foreground="#BFBFBF" FontSize="11"/>
|
||||
<TextBlock Text="{Binding IdadeCorrecaoTexto}" Foreground="White" FontSize="16" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using OperationControl.ViewModels;
|
||||
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 OperationControl.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for PreparacaoMapaTopView.xaml
|
||||
/// </summary>
|
||||
public partial class PreparacaoMapaTopView : System.Windows.Controls.UserControl
|
||||
{
|
||||
public PreparacaoMapaTopViewModel _vm;
|
||||
|
||||
public PreparacaoMapaTopView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = new PreparacaoMapaTopViewModel();
|
||||
DataContext = _vm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<UserControl x:Class="OperationControl.Views.PreparacaoMapaView"
|
||||
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:OperationControl.Controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid Background="#111111">
|
||||
<Border Margin="8" CornerRadius="8" BorderThickness="1" BorderBrush="#3A3A3A" Background="#1A1A1A">
|
||||
<controls:MapViewControl x:Name="MapaPreparacao" MbTilesPath="Data/basemap.mbtiles" Latitude="-22.1726572492617" Longitude="-47.3952163870556" Scale="5000" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
using OperationControl.Controls;
|
||||
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 OperationControl.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for PreparacaoMapaView.xaml
|
||||
/// </summary>
|
||||
public partial class PreparacaoMapaView : System.Windows.Controls.UserControl
|
||||
{
|
||||
public MapViewControl MapControl => MapaPreparacao;
|
||||
|
||||
public PreparacaoMapaView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,11 +4,16 @@
|
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:OperationControl.Windows"
|
||||
xmlns:localHelpers="clr-namespace:OperationControl.Helpers"
|
||||
mc:Ignorable="d"
|
||||
Title="DockWindow" Height="1025" Width="1920" WindowStartupLocation="CenterScreen" WindowState="Maximized">
|
||||
<Window.Resources>
|
||||
<!--<localHelpers:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>-->
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="80"/>
|
||||
<RowDefinition Height="100"/>
|
||||
<!-- Topo -->
|
||||
<RowDefinition Height="*"/>
|
||||
<!-- Centro -->
|
||||
|
|
@ -17,11 +22,11 @@
|
|||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="60"/>
|
||||
<ColumnDefinition Width="{Binding LeftPanelWidth}"/>
|
||||
<!-- Lateral esquerda (voltar) -->
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!-- Centro -->
|
||||
<ColumnDefinition Width="60"/>
|
||||
<ColumnDefinition Width="{Binding RightPanelWidth}"/>
|
||||
<!-- Lateral direita (avançar) -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
|
|
@ -47,26 +52,44 @@
|
|||
<ContentControl Content="{Binding BottomContent}"/>
|
||||
</Border>
|
||||
|
||||
<!-- Lateral esquerda: botão voltar -->
|
||||
<Grid Grid.Row="1" Grid.Column="0">
|
||||
<Button Content="⮜"
|
||||
FontSize="24"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Width="40" Height="40"
|
||||
Command="{Binding BackCommand}"
|
||||
IsEnabled="{Binding CanGoBack}"/>
|
||||
<!-- Lateral esquerda -->
|
||||
<Grid Grid.Row="1" Grid.Column="0" Margin="8">
|
||||
<ContentControl Content="{Binding LeftContent}">
|
||||
<ContentControl.Style>
|
||||
<Style TargetType="ContentControl">
|
||||
<Setter Property="Content" Value="{x:Null}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding LeftContent}" Value="{x:Null}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ContentControl">
|
||||
<Grid>
|
||||
<Button Content="⮜"
|
||||
FontSize="24"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Width="40"
|
||||
Height="40"
|
||||
Command="{Binding BackCommand}"
|
||||
IsEnabled="{Binding CanGoBack}"/>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ContentControl.Style>
|
||||
</ContentControl>
|
||||
</Grid>
|
||||
|
||||
<!-- Lateral direita: botão avançar -->
|
||||
<Grid Grid.Row="1" Grid.Column="2">
|
||||
<Button Content="⮞"
|
||||
FontSize="24"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Width="40" Height="40"
|
||||
Command="{Binding NextCommand}"
|
||||
IsEnabled="{Binding CanGoNext}"/>
|
||||
</Grid>
|
||||
<!-- Lateral direita -->
|
||||
<Border Grid.Row="1" Grid.Column="2"
|
||||
Margin="8"
|
||||
BorderThickness="1"
|
||||
BorderBrush="#404040"
|
||||
Background="#1C1C1C">
|
||||
<ContentControl Content="{Binding RightContent}"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
|
|
|||
|
|
@ -20,10 +20,12 @@ namespace OperationControl.Windows
|
|||
/// </summary>
|
||||
public partial class DockWindow : Window
|
||||
{
|
||||
public DockWindowViewModel _vm;
|
||||
public DockWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = new DockWindowViewModel();
|
||||
_vm = new DockWindowViewModel();
|
||||
DataContext = _vm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue