ScreenPage.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using System;
  2. using System.Globalization;
  3. using System.Linq;
  4. using System.Net.Http.Headers;
  5. using Avalonia;
  6. using Avalonia.Controls;
  7. using Avalonia.Media;
  8. using Avalonia.Platform;
  9. using Avalonia.Rendering;
  10. using Avalonia.Threading;
  11. namespace ControlCatalog.Pages
  12. {
  13. public class ScreenPage : UserControl
  14. {
  15. private double _leftMost;
  16. private double _topMost;
  17. private IBrush _primaryBrush = SolidColorBrush.Parse("#FF0078D7");
  18. private IBrush _defaultBrush = Brushes.LightGray;
  19. private IPen _activePen = new Pen(Brushes.Black);
  20. private IPen _defaultPen = new Pen(Brushes.DarkGray);
  21. public ScreenPage()
  22. {
  23. var button = new Button();
  24. button.Content = "Request ScreenDetails";
  25. button.VerticalAlignment = Avalonia.Layout.VerticalAlignment.Top;
  26. button.Click += async (sender, args) =>
  27. {
  28. var success = TopLevel.GetTopLevel(this)!.Screens is { } screens ?
  29. await screens.RequestScreenDetails() :
  30. false;
  31. button.Content = "Request ScreenDetails: " + (success ? "Granted" : "Denied");
  32. };
  33. Content = button;
  34. }
  35. protected override bool BypassFlowDirectionPolicies => true;
  36. protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
  37. {
  38. base.OnAttachedToVisualTree(e);
  39. var topLevel = TopLevel.GetTopLevel(this);
  40. if (topLevel is Window w)
  41. {
  42. w.PositionChanged += (_, _) => InvalidateVisual();
  43. }
  44. if (topLevel?.Screens is { } screens)
  45. {
  46. screens.Changed += (_, _) =>
  47. {
  48. Console.WriteLine("Screens Changed");
  49. InvalidateVisual();
  50. };
  51. }
  52. }
  53. public override void Render(DrawingContext context)
  54. {
  55. base.Render(context);
  56. double beginOffset = (Content as Visual)?.Bounds.Height + 10 ?? 0;
  57. var topLevel = TopLevel.GetTopLevel(this)!;
  58. if (topLevel.Screens is not { } screens)
  59. {
  60. var formattedText = CreateFormattedText("Current platform doesn't support Screens API.");
  61. context.DrawText(formattedText, new Point(15, 15 + beginOffset));
  62. return;
  63. }
  64. var activeScreen = screens.ScreenFromTopLevel(topLevel);
  65. double maxBottom = 0;
  66. for (int i = 0; i<screens.ScreenCount; i++ )
  67. {
  68. var screen = screens.All[i];
  69. if (screen.Bounds.X / 10f < _leftMost)
  70. {
  71. _leftMost = screen.Bounds.X / 10f;
  72. Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
  73. return;
  74. }
  75. if (screen.Bounds.Y / 10f < _topMost)
  76. {
  77. _topMost = screen.Bounds.Y / 10f;
  78. Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
  79. return;
  80. }
  81. bool primary = screen.IsPrimary;
  82. bool active = screen.Equals(activeScreen);
  83. Rect boundsRect = new Rect(screen.Bounds.X / 10f + Math.Abs(_leftMost), screen.Bounds.Y / 10f+Math.Abs(_topMost) + beginOffset, screen.Bounds.Width / 10f,
  84. screen.Bounds.Height / 10f);
  85. Rect workingAreaRect = new Rect(screen.WorkingArea.X / 10f + Math.Abs(_leftMost), screen.WorkingArea.Y / 10f+Math.Abs(_topMost) + beginOffset, screen.WorkingArea.Width / 10f,
  86. screen.WorkingArea.Height / 10f);
  87. context.DrawRectangle(primary ? _primaryBrush : _defaultBrush, active ? _activePen : _defaultPen, boundsRect);
  88. context.DrawRectangle(primary ? _primaryBrush : _defaultBrush, active ? _activePen : _defaultPen, workingAreaRect);
  89. var identifier = CreateScreenIdentifier((i+1).ToString(), primary);
  90. var center = boundsRect.Center - new Point(identifier.Width / 2.0f, identifier.Height / 2.0f + beginOffset);
  91. context.DrawText(identifier, center);
  92. maxBottom = Math.Max(maxBottom, boundsRect.Bottom);
  93. }
  94. double currentHeight = maxBottom;
  95. for(int i = 0; i< screens.ScreenCount; i++)
  96. {
  97. var screen = screens.All[i];
  98. var formattedText = CreateFormattedText($"Screen {i+1}", 18);
  99. context.DrawText(formattedText, new Point(0, currentHeight));
  100. currentHeight += 25;
  101. formattedText = CreateFormattedText($"DisplayName: {screen.DisplayName}");
  102. context.DrawText(formattedText, new Point(15, currentHeight));
  103. currentHeight += 20;
  104. formattedText = CreateFormattedText($"Handle: {screen.TryGetPlatformHandle()}");
  105. context.DrawText(formattedText, new Point(15, currentHeight));
  106. currentHeight += 20;
  107. formattedText = CreateFormattedText($"Bounds: {screen.Bounds.Width}:{screen.Bounds.Height}");
  108. context.DrawText(formattedText, new Point(15, currentHeight));
  109. currentHeight += 20;
  110. formattedText = CreateFormattedText($"WorkArea: {screen.WorkingArea.Width}:{screen.WorkingArea.Height}");
  111. context.DrawText(formattedText, new Point(15, currentHeight));
  112. currentHeight += 20;
  113. formattedText = CreateFormattedText($"Scaling: {screen.Scaling * 100}%");
  114. context.DrawText(formattedText, new Point(15, currentHeight));
  115. currentHeight += 20;
  116. formattedText = CreateFormattedText($"IsPrimary: {screen.IsPrimary}");
  117. context.DrawText(formattedText, new Point(15, currentHeight));
  118. currentHeight += 20;
  119. formattedText = CreateFormattedText($"CurrentOrientation: {screen.CurrentOrientation}");
  120. context.DrawText(formattedText, new Point(15, currentHeight));
  121. currentHeight += 20;
  122. formattedText = CreateFormattedText( $"Current: {screen.Equals(activeScreen)}");
  123. context.DrawText(formattedText, new Point(15, currentHeight));
  124. currentHeight += 30;
  125. }
  126. if (topLevel is Window w)
  127. {
  128. var wPos = w.Position;
  129. var wSize = PixelSize.FromSize(w.FrameSize ?? w.ClientSize, w.DesktopScaling);
  130. context.DrawRectangle(_activePen,
  131. new Rect(wPos.X / 10f + Math.Abs(_leftMost), wPos.Y / 10f + Math.Abs(_topMost) + beginOffset,
  132. wSize.Width / 10d, wSize.Height / 10d));
  133. }
  134. }
  135. private static FormattedText CreateFormattedText(string textToFormat, double size = 12)
  136. {
  137. return new FormattedText(textToFormat, CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
  138. Typeface.Default, size, Brushes.Green);
  139. }
  140. private static FormattedText CreateScreenIdentifier(string textToFormat, bool primary)
  141. {
  142. return new FormattedText(textToFormat, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, Typeface.Default, 20, primary ? Brushes.White : Brushes.Black);
  143. }
  144. }
  145. }