using OperationControl.Mapas.Creation; using System.Windows; using System.Windows.Controls; namespace OperationControl.Mapas.Creation.Views { /// /// Cockpit passivo da criação de mapas. /// Exibe estado e emite intenções. Não altera mapa ou GNSS. /// public partial class MapaCriacaoOverlay : System.Windows.Controls.UserControl { public event Action? NomeMapaAlterado; public event Action? ModoCapturaAlterado; public event Action? RegistrarPontoSolicitado; public event Action? RemoverUltimoPontoSolicitado; public event Action? IniciarCapturaAutomaticaSolicitado; public event Action? FinalizarCapturaAutomaticaSolicitado; public event Action? NovaRuaSolicitada; public event Action? RuaSelecionada; public event Action? ExcluirRuaSolicitada; public event Action? LimparSolicitado; public event Action? SalvarSolicitado; public event Action? CancelarSolicitado; private bool _atualizandoEstado; private MapaResumoCriacao? _ultimoResumo; public MapaCriacaoOverlay() { InitializeComponent(); } public void AtualizarEstado(MapaResumoCriacao? resumo) { _atualizandoEstado = true; try { _ultimoResumo = resumo; bool ativo = resumo?.EmCriacao == true; Visibility = ativo ? Visibility.Visible : Visibility.Collapsed; IsHitTestVisible = ativo; if (!ativo) return; string nome = resumo!.Nome ?? string.Empty; if (!string.Equals(txtNomeMapa.Text, nome, StringComparison.Ordinal)) { int caret = txtNomeMapa.CaretIndex; txtNomeMapa.Text = nome; txtNomeMapa.CaretIndex = Math.Min(caret, txtNomeMapa.Text.Length); } txtRuaAtual.Text = resumo.RuaAtual > 0 ? $"Rua {resumo.RuaAtual}" : "Sem rua"; txtResumoRua.Text = $"{resumo.PontosRuaAtual} pts • {resumo.ComprimentoRuaAtualMetros:F1} m"; txtStatusGnss.Text = string.IsNullOrWhiteSpace(resumo.StatusGnss) ? "GNSS sem leitura." : resumo.StatusGnss; rbManual.IsChecked = resumo.ModoCaptura == MapaModoCapturaCriacao.Manual; rbAutomatico.IsChecked = resumo.ModoCaptura == MapaModoCapturaCriacao.Automatico; cmbRuas.ItemsSource = resumo.Ruas; cmbRuas.SelectedValue = resumo.RuaAtual; bool gravando = resumo.GravacaoAutomaticaAtiva; btnRegistrarPonto.Visibility = resumo.ModoCaptura == MapaModoCapturaCriacao.Manual ? Visibility.Visible : Visibility.Collapsed; btnCapturaAutomatica.Visibility = resumo.ModoCaptura == MapaModoCapturaCriacao.Automatico ? Visibility.Visible : Visibility.Collapsed; btnRegistrarPonto.IsEnabled = !gravando && resumo.LeituraGnssValida; btnCapturaAutomatica.Content = gravando ? "■ Finalizar captura automática" : "▶ Iniciar captura automática"; btnCapturaAutomatica.IsEnabled = gravando || resumo.LeituraGnssValida; btnRemoverUltimoPonto.IsEnabled = !gravando && resumo.PontosRuaAtual > 0; btnNovaRua.IsEnabled = resumo.PodeNovaRua; btnExcluirRua.IsEnabled = !gravando && resumo.QuantidadeRuas > 0; btnLimpar.IsEnabled = !gravando && resumo.PontosTotal > 0; cmbRuas.IsEnabled = !gravando && resumo.QuantidadeRuas > 0; rbManual.IsEnabled = !gravando; rbAutomatico.IsEnabled = !gravando; txtNomeMapa.IsEnabled = !gravando; btnSalvar.IsEnabled = resumo.PodeSalvar; txtResumoTotal.Text = $"{resumo.QuantidadeRuas} {(resumo.QuantidadeRuas == 1 ? "rua" : "ruas")} • " + $"{resumo.PontosTotal} {(resumo.PontosTotal == 1 ? "ponto" : "pontos")} • " + $"{resumo.ComprimentoTotalMetros:F1} m" + Environment.NewLine + $"{resumo.QuantidadeRuasValidas}/{resumo.QuantidadeRuas} ruas válidas"; } finally { _atualizandoEstado = false; } } private void txtNomeMapa_TextChanged(object sender, TextChangedEventArgs e) { if (_atualizandoEstado) return; NomeMapaAlterado?.Invoke(txtNomeMapa.Text); } private void rbModo_Checked(object sender, RoutedEventArgs e) { if (_atualizandoEstado) return; if (rbAutomatico.IsChecked == true) ModoCapturaAlterado?.Invoke(MapaModoCapturaCriacao.Automatico); else if (rbManual.IsChecked == true) ModoCapturaAlterado?.Invoke(MapaModoCapturaCriacao.Manual); } private void btnRegistrarPonto_Click(object sender, RoutedEventArgs e) => RegistrarPontoSolicitado?.Invoke(); private void btnRemoverUltimoPonto_Click(object sender, RoutedEventArgs e) => RemoverUltimoPontoSolicitado?.Invoke(); private void btnCapturaAutomatica_Click(object sender, RoutedEventArgs e) { if (_ultimoResumo?.GravacaoAutomaticaAtiva == true) FinalizarCapturaAutomaticaSolicitado?.Invoke(); else IniciarCapturaAutomaticaSolicitado?.Invoke(); } private void btnNovaRua_Click(object sender, RoutedEventArgs e) => NovaRuaSolicitada?.Invoke(); private void cmbRuas_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (_atualizandoEstado) return; if (cmbRuas.SelectedValue is int numeroRua) RuaSelecionada?.Invoke(numeroRua); } private void btnExcluirRua_Click(object sender, RoutedEventArgs e) { int numeroRua = _ultimoResumo?.RuaAtual ?? 0; if (numeroRua > 0) ExcluirRuaSolicitada?.Invoke(numeroRua); } private void btnLimpar_Click(object sender, RoutedEventArgs e) => LimparSolicitado?.Invoke(); private void btnSalvar_Click(object sender, RoutedEventArgs e) => SalvarSolicitado?.Invoke(); private void btnCancelar_Click(object sender, RoutedEventArgs e) => CancelarSolicitado?.Invoke(); } }