171 lines
5.7 KiB
C#
171 lines
5.7 KiB
C#
using System.Collections.Specialized;
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Controls.Documents;
|
|
using Avalonia.Controls.Shapes;
|
|
using Avalonia.Input;
|
|
using Avalonia.Media;
|
|
using Automata.Core;
|
|
using Automata.Ui.ViewModels;
|
|
|
|
namespace Automata.Ui.Views;
|
|
|
|
public partial class MainWindow : Window
|
|
{
|
|
private ConfigStore? _store;
|
|
|
|
private static readonly IBrush TimeBrush = new SolidColorBrush(Color.Parse("#484f58"));
|
|
private static readonly IBrush InfoBrush = new SolidColorBrush(Color.Parse("#58a6ff"));
|
|
private static readonly IBrush WarnBrush = new SolidColorBrush(Color.Parse("#d29922"));
|
|
private static readonly IBrush ErrorBrush = new SolidColorBrush(Color.Parse("#f85149"));
|
|
private static readonly IBrush DebugBrush = new SolidColorBrush(Color.Parse("#8b949e"));
|
|
private static readonly IBrush DefaultBrush = new SolidColorBrush(Color.Parse("#e6edf3"));
|
|
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
public void SetConfigStore(ConfigStore store)
|
|
{
|
|
_store = store;
|
|
var s = store.Settings;
|
|
if (s.WindowWidth.HasValue && s.WindowHeight.HasValue)
|
|
{
|
|
Width = s.WindowWidth.Value;
|
|
Height = s.WindowHeight.Value;
|
|
}
|
|
if (s.WindowX.HasValue && s.WindowY.HasValue)
|
|
{
|
|
Position = new PixelPoint((int)s.WindowX.Value, (int)s.WindowY.Value);
|
|
WindowStartupLocation = WindowStartupLocation.Manual;
|
|
}
|
|
else
|
|
{
|
|
WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
|
}
|
|
}
|
|
|
|
protected override void OnDataContextChanged(EventArgs e)
|
|
{
|
|
base.OnDataContextChanged(e);
|
|
if (DataContext is MainWindowViewModel vm)
|
|
{
|
|
vm.Logs.CollectionChanged += (_, args) =>
|
|
{
|
|
var block = this.FindControl<SelectableTextBlock>("LogBlock");
|
|
var scroll = this.FindControl<ScrollViewer>("LogScroll");
|
|
if (block == null) return;
|
|
|
|
if (args.Action == NotifyCollectionChangedAction.Add && args.NewItems != null)
|
|
{
|
|
foreach (LogEntry entry in args.NewItems)
|
|
AppendLogEntry(block, entry);
|
|
}
|
|
else if (args.Action == NotifyCollectionChangedAction.Remove)
|
|
{
|
|
// Rebuild when old entries trimmed
|
|
RebuildLog(block, vm);
|
|
}
|
|
|
|
scroll?.ScrollToEnd();
|
|
};
|
|
}
|
|
}
|
|
|
|
private static void AppendLogEntry(SelectableTextBlock block, LogEntry entry)
|
|
{
|
|
if (block.Inlines?.Count > 0)
|
|
block.Inlines.Add(new Run("\n"));
|
|
|
|
block.Inlines ??= [];
|
|
block.Inlines.Add(new Run(entry.Time + " ") { Foreground = TimeBrush });
|
|
block.Inlines.Add(new Run(entry.Message) { Foreground = LevelBrush(entry.Level) });
|
|
}
|
|
|
|
private static void RebuildLog(SelectableTextBlock block, MainWindowViewModel vm)
|
|
{
|
|
block.Inlines?.Clear();
|
|
block.Inlines ??= [];
|
|
for (var i = 0; i < vm.Logs.Count; i++)
|
|
{
|
|
if (i > 0) block.Inlines.Add(new Run("\n"));
|
|
var entry = vm.Logs[i];
|
|
block.Inlines.Add(new Run(entry.Time + " ") { Foreground = TimeBrush });
|
|
block.Inlines.Add(new Run(entry.Message) { Foreground = LevelBrush(entry.Level) });
|
|
}
|
|
}
|
|
|
|
private static IBrush LevelBrush(string level) => level switch
|
|
{
|
|
"INFO" => InfoBrush,
|
|
"WARN" or "WARNING" => WarnBrush,
|
|
"ERROR" => ErrorBrush,
|
|
"DEBUG" => DebugBrush,
|
|
_ => DefaultBrush,
|
|
};
|
|
|
|
public void CurrencyImage_PointerPressed(object? sender, PointerPressedEventArgs e)
|
|
{
|
|
if (sender is not Control grid) return;
|
|
if (DataContext is not MainWindowViewModel mainVm) return;
|
|
var settingsVm = mainVm.SettingsVm;
|
|
if (settingsVm?.CurrencyTabImage == null) return;
|
|
|
|
// Viewbox puts us in image-pixel space — coords are already image pixels
|
|
var pos = e.GetPosition(grid);
|
|
settingsVm.OnCurrencyImageClick((int)pos.X, (int)pos.Y);
|
|
UpdateHoverMarker(settingsVm.SelectedCurrency);
|
|
}
|
|
|
|
public void CurrencyItem_PointerEntered(object? sender, PointerEventArgs e)
|
|
{
|
|
if (sender is Control { DataContext: CurrencyPositionViewModel vm })
|
|
UpdateHoverMarker(vm);
|
|
}
|
|
|
|
public void CurrencyItem_PointerExited(object? sender, PointerEventArgs e)
|
|
{
|
|
var marker = this.FindControl<Ellipse>("HoverMarker");
|
|
if (marker != null) marker.IsVisible = false;
|
|
}
|
|
|
|
private void UpdateHoverMarker(CurrencyPositionViewModel? vm)
|
|
{
|
|
var marker = this.FindControl<Ellipse>("HoverMarker");
|
|
if (marker == null) return;
|
|
if (vm == null || !vm.IsPositioned)
|
|
{
|
|
marker.IsVisible = false;
|
|
return;
|
|
}
|
|
|
|
// Canvas is in image-pixel space thanks to Viewbox
|
|
Canvas.SetLeft(marker, vm.X - marker.Width / 2);
|
|
Canvas.SetTop(marker, vm.Y - marker.Height / 2);
|
|
marker.IsVisible = true;
|
|
}
|
|
|
|
public void BrowserRow_PointerPressed(object? sender, PointerPressedEventArgs e)
|
|
{
|
|
if (sender is not Control { DataContext: FieldRowViewModel row }) return;
|
|
if (!row.IsPointer) return;
|
|
if (DataContext is not MainWindowViewModel mainVm) return;
|
|
mainVm.BrowserVm?.NavigateToPointer(row);
|
|
}
|
|
|
|
protected override void OnClosing(WindowClosingEventArgs e)
|
|
{
|
|
if (_store != null)
|
|
{
|
|
_store.UpdateSettings(s =>
|
|
{
|
|
s.WindowX = Position.X;
|
|
s.WindowY = Position.Y;
|
|
s.WindowWidth = Width;
|
|
s.WindowHeight = Height;
|
|
});
|
|
}
|
|
base.OnClosing(e);
|
|
}
|
|
}
|