Forge
csharp4405de34
1using Avalonia;
2using Avalonia.Controls;
3using Avalonia.Media;
4using Avalonia.Styling;
5using CascadeIDE.Services;
6
7namespace CascadeIDE.Views;
8
9/// <summary>
10/// Базовое окно: подписка на указатель для MCP (Avalonia 12 не даёт <c>PointerOverElement</c> на <see cref="TopLevel"/>).
11/// </summary>
12public class PointerTrackingWindow : Window
13{
14 private static readonly SolidColorBrush FallbackWindowBackground = new(Color.Parse("#FF1E1E1E"));
15
16 protected PointerTrackingWindow()
17 {
18 Background = FallbackWindowBackground;
19 UiPointerClientPosition.Attach(this);
20 Opened += (_, _) => EnsureOpaqueClientBackground();
21 UiThemeApply.ThemeApplied += (_, _) => EnsureOpaqueClientBackground();
22 }
23
24 /// <summary>Непрозрачный фон клиента: DynamicResource + Fluent PART_WindowBorder (см. App.axaml).</summary>
25 protected void EnsureOpaqueClientBackground()
26 {
27 if (TryResolveMainWindowBackgroundBrush(out var brush))
28 Background = EnsureOpaqueBrush(brush);
29 else
30 Background = FallbackWindowBackground;
31 }
32
33 private static IBrush EnsureOpaqueBrush(IBrush brush)
34 {
35 if (brush is SolidColorBrush solid)
36 {
37 var c = solid.Color;
38 if (c.A < byte.MaxValue)
39 return new SolidColorBrush(Color.FromArgb(byte.MaxValue, c.R, c.G, c.B));
40 }
41
42 return brush;
43 }
44
45 private static bool TryResolveMainWindowBackgroundBrush(out IBrush brush)
46 {
47 brush = FallbackWindowBackground;
48 if (Application.Current?.Resources is not { } resources)
49 return false;
50
51 if (resources.TryGetResource(UiThemeApply.Keys.MainWindowBackground, ThemeVariant.Default, out var value)
52 && value is IBrush resolved)
53 {
54 brush = resolved;
55 return true;
56 }
57
58 return false;
59 }
60}
61
View only · write via MCP/CIDE