StatusCard.cs 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. using Avalonia;
  2. using Avalonia.Controls;
  3. using Avalonia.Media;
  4. using System.Globalization;
  5. namespace YZWater.Avalonia.Controls;
  6. public class StatusCard : Control
  7. {
  8. public static readonly StyledProperty<string> TitleProperty = AvaloniaProperty.Register<StatusCard, string>(nameof(Title), "Device");
  9. public static readonly StyledProperty<string> StatusProperty = AvaloniaProperty.Register<StatusCard, string>(nameof(Status), "RUNNING");
  10. public static readonly StyledProperty<string> IconProperty = AvaloniaProperty.Register<StatusCard, string>(nameof(Icon), "P1");
  11. public static readonly StyledProperty<bool> IsActiveProperty = AvaloniaProperty.Register<StatusCard, bool>(nameof(IsActive), false);
  12. public static readonly StyledProperty<IBrush> ActiveColorProperty = AvaloniaProperty.Register<StatusCard, IBrush>(nameof(ActiveColor));
  13. public static readonly StyledProperty<IBrush> InactiveColorProperty = AvaloniaProperty.Register<StatusCard, IBrush>(nameof(InactiveColor));
  14. public string Title { get => GetValue(TitleProperty); set => SetValue(TitleProperty, value); }
  15. public string Status { get => GetValue(StatusProperty); set => SetValue(StatusProperty, value); }
  16. public string Icon { get => GetValue(IconProperty); set => SetValue(IconProperty, value); }
  17. public bool IsActive { get => GetValue(IsActiveProperty); set => SetValue(IsActiveProperty, value); }
  18. public IBrush ActiveColor { get => GetValue(ActiveColorProperty); set => SetValue(ActiveColorProperty, value); }
  19. public IBrush InactiveColor { get => GetValue(InactiveColorProperty); set => SetValue(InactiveColorProperty, value); }
  20. static StatusCard() { AffectsRender<StatusCard>(TitleProperty, StatusProperty, IconProperty, IsActiveProperty, ActiveColorProperty, InactiveColorProperty); }
  21. protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { base.OnAttachedToVisualTree(e); ThemeHelper.ThemeChanged += OnThemeChanged; }
  22. protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) { ThemeHelper.ThemeChanged -= OnThemeChanged; base.OnDetachedFromVisualTree(e); }
  23. private void OnThemeChanged() => InvalidateVisual();
  24. private static readonly Typeface s_monoTypeface = new("Consolas, monospace");
  25. private static readonly Typeface s_labelTypeface = new("Microsoft YaHei");
  26. public override void Render(DrawingContext context)
  27. {
  28. base.Render(context);
  29. var bounds = new Rect(Bounds.Size);
  30. var statusColor = IsActive ? (ActiveColor ?? ThemeHelper.Success) : (InactiveColor ?? ThemeHelper.TextDisabled);
  31. var statusBrush = statusColor as SolidColorBrush;
  32. var statusColorValue = statusBrush?.Color ?? Colors.Gray;
  33. context.DrawRectangle(ThemeHelper.PanelBg, null, bounds);
  34. context.DrawRectangle(statusColor, null, new Rect(0, 0, 3, bounds.Height));
  35. var ledX = 12.0; var ledY = bounds.Height / 2 - 5;
  36. if (IsActive) context.DrawEllipse(new SolidColorBrush(statusColorValue, 0.3), null, new Rect(ledX - 3, ledY - 3, 16, 16));
  37. context.DrawEllipse(statusColor, null, new Rect(ledX, ledY, 10, 10));
  38. var iconText = new FormattedText(Icon, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, s_monoTypeface, 11, ThemeHelper.TextPrimary);
  39. context.DrawText(iconText, new Point(28, 6));
  40. var titleText = new FormattedText(Title, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, s_labelTypeface, 10, ThemeHelper.TextSecondary);
  41. context.DrawText(titleText, new Point(28, 22));
  42. var statusText = new FormattedText(Status, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, s_monoTypeface, 9, statusColor);
  43. context.DrawText(statusText, new Point(bounds.Width - statusText.Width - 10, bounds.Height / 2 - statusText.Height / 2));
  44. }
  45. protected override Size MeasureOverride(Size availableSize) => new Size(230, 42);
  46. }