using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Text; using Avalonia.Controls; using Avalonia.Markup.Xaml; using Avalonia.Media; using Avalonia.Threading; using PolyTrader.App.Avalonia.ViewModels; using PolyTrader.Core.Modularity; using PolyTraderSharp.Services; namespace PolyTrader.App.Avalonia.Views { /// /// Terminal-/Log-Ansicht. Live-Ausgabe des plus Viewer für die /// JSONL-Tagesdateien. Layout vollständig in TerminalWindow.axaml. /// public partial class TerminalWindow : Window { /// /// Obergrenze der angezeigten Zeilen. Die WinForms-Fassung leerte bei Erreichen einer /// Zeichengrenze das GESAMTE Terminal; hier werden stattdessen nur die ältesten Zeilen /// verdrängt, der jüngste Verlauf bleibt also immer sichtbar. /// private const int MaxLines = 5000; /// Höchstzahl je UI-Takt verarbeiteter Meldungen – hält die Oberfläche flüssig. private const int MaxPerTick = 500; private static readonly IBrush BrushDefault = Brushes.WhiteSmoke; private static readonly IBrush BrushError = Brushes.Tomato; private static readonly IBrush BrushWarning = Brushes.Gold; private static readonly IBrush BrushTrade = Brushes.LightGreen; private static readonly IBrush BrushReasoning = Brushes.Orange; private readonly ConcurrentQueue _queue = new(); private readonly ObservableCollection _lines = new(); private readonly ObservableCollection _viewerRows = new(); private readonly DispatcherTimer _timer = new() { Interval = TimeSpan.FromMilliseconds(250) }; private TerminalLogger? _logger; private EventHandler? _logHandler; private bool _autoScroll = true; public TerminalWindow() => AvaloniaXamlLoader.Load(this); public TerminalWindow(IModuleUiHost host, TerminalLogger logger) : this() { this.FindControl("menuBar")!.Attach(host, "core.terminal", this); _logger = logger; this.FindControl("logLines")!.ItemsSource = _lines; this.FindControl("gridLogs")!.ItemsSource = _viewerRows; var levels = new[] { "Alle" }.Concat(Enum.GetNames()).ToArray(); var cbLevel = this.FindControl("cbLogLevel")!; var cbViewerLevel = this.FindControl("cbViewerLevel")!; cbLevel.ItemsSource = levels; cbViewerLevel.ItemsSource = levels; cbLevel.SelectedIndex = 0; cbViewerLevel.SelectedIndex = 0; this.FindControl("dtViewerDate")!.SelectedDate = DateTime.Now; this.FindControl