diff --git a/Handlers/FlyoutPageHandler.cs b/Handlers/FlyoutPageHandler.cs index a9c0674..7faff09 100644 --- a/Handlers/FlyoutPageHandler.cs +++ b/Handlers/FlyoutPageHandler.cs @@ -171,7 +171,7 @@ public partial class FlyoutPageHandler : ViewHandler // Sync flyout colors if (shell.FlyoutBackgroundColor is Color flyoutBgColor) { - platformView.FlyoutBackgroundColor = flyoutBgColor.ToSKColor(); + platformView.FlyoutBackgroundColor = flyoutBgColor; } else if (shell.FlyoutBackground is SolidColorBrush flyoutBrush) { - platformView.FlyoutBackgroundColor = flyoutBrush.Color.ToSKColor(); + platformView.FlyoutBackgroundColor = flyoutBrush.Color; } // Sync nav bar colors if (shell.BackgroundColor is Color bgColor) { - platformView.NavBarBackgroundColor = bgColor.ToSKColor(); + platformView.NavBarBackgroundColor = bgColor; } } @@ -293,7 +293,7 @@ public partial class ShellHandler : ViewHandler if (shell.FlyoutBackgroundColor is Color color) { - handler.PlatformView.FlyoutBackgroundColor = color.ToSKColor(); + handler.PlatformView.FlyoutBackgroundColor = color; } } @@ -303,7 +303,7 @@ public partial class ShellHandler : ViewHandler if (shell.FlyoutBackground is SolidColorBrush solidBrush) { - handler.PlatformView.FlyoutBackgroundColor = solidBrush.Color.ToSKColor(); + handler.PlatformView.FlyoutBackgroundColor = solidBrush.Color; } } @@ -313,7 +313,7 @@ public partial class ShellHandler : ViewHandler if (shell.BackgroundColor is Color color) { - handler.PlatformView.NavBarBackgroundColor = color.ToSKColor(); + handler.PlatformView.NavBarBackgroundColor = color; } } diff --git a/Handlers/TabbedPageHandler.cs b/Handlers/TabbedPageHandler.cs index 355db82..4dcb084 100644 --- a/Handlers/TabbedPageHandler.cs +++ b/Handlers/TabbedPageHandler.cs @@ -126,7 +126,7 @@ public partial class TabbedPageHandler : ViewHandler /// Gets or sets the current position (item index). /// @@ -79,12 +86,30 @@ public class SkiaCarouselView : SkiaLayoutView /// /// Gets or sets the indicator color. /// - public SKColor IndicatorColor { get; set; } = new SKColor(180, 180, 180); + public Color IndicatorColor + { + get => _indicatorColor; + set + { + _indicatorColor = value; + _indicatorColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Gets or sets the selected indicator color. /// - public SKColor SelectedIndicatorColor { get; set; } = new SKColor(33, 150, 243); + public Color SelectedIndicatorColor + { + get => _selectedIndicatorColor; + set + { + _selectedIndicatorColor = value; + _selectedIndicatorColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Event raised when position changes. @@ -279,14 +304,14 @@ public class SkiaCarouselView : SkiaLayoutView using var normalPaint = new SKPaint { - Color = IndicatorColor, + Color = _indicatorColorSK, Style = SKPaintStyle.Fill, IsAntialias = true }; using var selectedPaint = new SKPaint { - Color = SelectedIndicatorColor, + Color = _selectedIndicatorColorSK, Style = SKPaintStyle.Fill, IsAntialias = true }; diff --git a/Views/SkiaCheckBox.cs b/Views/SkiaCheckBox.cs index 8167790..0e142d8 100644 --- a/Views/SkiaCheckBox.cs +++ b/Views/SkiaCheckBox.cs @@ -22,11 +22,7 @@ public class SkiaCheckBox : SkiaView private static SKColor ToSKColor(Color? color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } #endregion diff --git a/Views/SkiaCollectionView.cs b/Views/SkiaCollectionView.cs index 8cc47b7..872b311 100644 --- a/Views/SkiaCollectionView.cs +++ b/Views/SkiaCollectionView.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using Microsoft.Maui.Controls; +using Microsoft.Maui.Graphics; using SkiaSharp; namespace Microsoft.Maui.Platform; @@ -91,27 +92,27 @@ public class SkiaCollectionView : SkiaItemsView public static readonly BindableProperty SelectionColorProperty = BindableProperty.Create( nameof(SelectionColor), - typeof(SKColor), + typeof(Color), typeof(SkiaCollectionView), - new SKColor(33, 150, 243, 89), + Color.FromRgba(33, 150, 243, 89), BindingMode.TwoWay, - propertyChanged: (b, o, n) => ((SkiaCollectionView)b).Invalidate()); + propertyChanged: (b, o, n) => ((SkiaCollectionView)b).OnSelectionColorChanged((Color?)n)); public static readonly BindableProperty HeaderBackgroundColorProperty = BindableProperty.Create( nameof(HeaderBackgroundColor), - typeof(SKColor), + typeof(Color), typeof(SkiaCollectionView), - new SKColor(245, 245, 245), + Color.FromRgb(245, 245, 245), BindingMode.TwoWay, - propertyChanged: (b, o, n) => ((SkiaCollectionView)b).Invalidate()); + propertyChanged: (b, o, n) => ((SkiaCollectionView)b).OnHeaderBackgroundColorChanged((Color?)n)); public static readonly BindableProperty FooterBackgroundColorProperty = BindableProperty.Create( nameof(FooterBackgroundColor), - typeof(SKColor), + typeof(Color), typeof(SkiaCollectionView), - new SKColor(245, 245, 245), + Color.FromRgb(245, 245, 245), BindingMode.TwoWay, - propertyChanged: (b, o, n) => ((SkiaCollectionView)b).Invalidate()); + propertyChanged: (b, o, n) => ((SkiaCollectionView)b).OnFooterBackgroundColorChanged((Color?)n)); #endregion @@ -120,6 +121,11 @@ public class SkiaCollectionView : SkiaItemsView private bool _isSelectingItem; private bool _heightsChangedDuringDraw; + // SKColor fields for rendering + private SKColor _selectionColorSK = SkiaTheme.PrimarySelectionSK; + private SKColor _headerBackgroundColorSK = SkiaTheme.Gray100SK; + private SKColor _footerBackgroundColorSK = SkiaTheme.Gray100SK; + public SkiaSelectionMode SelectionMode { get => (SkiaSelectionMode)GetValue(SelectionModeProperty); @@ -192,24 +198,33 @@ public class SkiaCollectionView : SkiaItemsView set => SetValue(FooterHeightProperty, value); } - public SKColor SelectionColor + public Color SelectionColor { - get => (SKColor)GetValue(SelectionColorProperty); + get => (Color)GetValue(SelectionColorProperty); set => SetValue(SelectionColorProperty, value); } - public SKColor HeaderBackgroundColor + /// Gets the SKColor for rendering selection highlight. + public SKColor SelectionColorSK => _selectionColorSK; + + public Color HeaderBackgroundColor { - get => (SKColor)GetValue(HeaderBackgroundColorProperty); + get => (Color)GetValue(HeaderBackgroundColorProperty); set => SetValue(HeaderBackgroundColorProperty, value); } - public SKColor FooterBackgroundColor + /// Gets the SKColor for rendering header background. + public SKColor HeaderBackgroundColorSK => _headerBackgroundColorSK; + + public Color FooterBackgroundColor { - get => (SKColor)GetValue(FooterBackgroundColorProperty); + get => (Color)GetValue(FooterBackgroundColorProperty); set => SetValue(FooterBackgroundColorProperty, value); } + /// Gets the SKColor for rendering footer background. + public SKColor FooterBackgroundColorSK => _footerBackgroundColorSK; + public event EventHandler? SelectionChanged; protected override void RefreshItems() @@ -266,6 +281,24 @@ public class SkiaCollectionView : SkiaItemsView Invalidate(); } + private void OnSelectionColorChanged(Color? newValue) + { + _selectionColorSK = newValue?.ToSKColor() ?? SkiaTheme.PrimarySelectionSK; + Invalidate(); + } + + private void OnHeaderBackgroundColorChanged(Color? newValue) + { + _headerBackgroundColorSK = newValue?.ToSKColor() ?? SkiaTheme.Gray100SK; + Invalidate(); + } + + private void OnFooterBackgroundColorChanged(Color? newValue) + { + _footerBackgroundColorSK = newValue?.ToSKColor() ?? SkiaTheme.Gray100SK; + Invalidate(); + } + private void SelectItem(object item) { if (SelectionMode == SkiaSelectionMode.None) @@ -365,7 +398,7 @@ public class SkiaCollectionView : SkiaItemsView if (Orientation == ItemsLayoutOrientation.Vertical && SpanCount == 1) { - paint.Color = new SKColor(224, 224, 224); + paint.Color = SkiaTheme.Gray300SK; paint.Style = SKPaintStyle.Stroke; paint.StrokeWidth = 1f; canvas.DrawLine(bounds.Left, bounds.Bottom, bounds.Right, bounds.Bottom, paint); @@ -409,7 +442,7 @@ public class SkiaCollectionView : SkiaItemsView if (isSelected) { - paint.Color = SelectionColor; + paint.Color = SelectionColorSK; paint.Style = SKPaintStyle.Fill; canvas.DrawRoundRect(actualBounds, 12f, 12f, paint); } @@ -433,13 +466,13 @@ public class SkiaCollectionView : SkiaItemsView return; } - paint.Color = SKColors.Black; + paint.Color = SkiaTheme.TextPrimarySK; paint.Style = SKPaintStyle.Fill; using var font = new SKFont(SKTypeface.Default, 14f, 1f, 0f); using var textPaint = new SKPaint(font) { - Color = SKColors.Black, + Color = SkiaTheme.TextPrimarySK, IsAntialias = true }; @@ -461,7 +494,7 @@ public class SkiaCollectionView : SkiaItemsView { using var paint = new SKPaint { - Color = new SKColor(33, 150, 243), + Color = SkiaTheme.PrimarySK, Style = SKPaintStyle.Stroke, StrokeWidth = 2f, IsAntialias = true, @@ -627,7 +660,7 @@ public class SkiaCollectionView : SkiaItemsView { using var cellBgPaint = new SKPaint { - Color = _selectedItems.Contains(item) ? SelectionColor : new SKColor(250, 250, 250), + Color = _selectedItems.Contains(item) ? SelectionColorSK : SkiaTheme.Gray50SK, Style = SKPaintStyle.Fill }; canvas.DrawRoundRect(new SKRoundRect(cellRect, 4f), cellBgPaint); @@ -657,7 +690,7 @@ public class SkiaCollectionView : SkiaItemsView using var trackPaint = new SKPaint { - Color = new SKColor(0, 0, 0, 20), + Color = SkiaTheme.Shadow10SK, Style = SKPaintStyle.Fill }; canvas.DrawRoundRect(new SKRoundRect(trackRect, 3f), trackPaint); @@ -673,7 +706,7 @@ public class SkiaCollectionView : SkiaItemsView using var thumbPaint = new SKPaint { - Color = new SKColor(100, 100, 100, 180), + Color = SkiaTheme.ScrollbarThumbSK, Style = SKPaintStyle.Fill, IsAntialias = true }; @@ -690,7 +723,7 @@ public class SkiaCollectionView : SkiaItemsView { using var bgPaint = new SKPaint { - Color = HeaderBackgroundColor, + Color = HeaderBackgroundColorSK, Style = SKPaintStyle.Fill }; canvas.DrawRect(bounds, bgPaint); @@ -701,7 +734,7 @@ public class SkiaCollectionView : SkiaItemsView using var font = new SKFont(SKTypeface.Default, 16f, 1f, 0f); using var textPaint = new SKPaint(font) { - Color = SKColors.Black, + Color = SkiaTheme.TextPrimarySK, IsAntialias = true }; @@ -715,7 +748,7 @@ public class SkiaCollectionView : SkiaItemsView using var sepPaint = new SKPaint { - Color = new SKColor(224, 224, 224), + Color = SkiaTheme.Gray300SK, Style = SKPaintStyle.Stroke, StrokeWidth = 1f }; @@ -726,14 +759,14 @@ public class SkiaCollectionView : SkiaItemsView { using var bgPaint = new SKPaint { - Color = FooterBackgroundColor, + Color = FooterBackgroundColorSK, Style = SKPaintStyle.Fill }; canvas.DrawRect(bounds, bgPaint); using var sepPaint = new SKPaint { - Color = new SKColor(224, 224, 224), + Color = SkiaTheme.Gray300SK, Style = SKPaintStyle.Stroke, StrokeWidth = 1f }; @@ -745,7 +778,7 @@ public class SkiaCollectionView : SkiaItemsView using var font = new SKFont(SKTypeface.Default, 14f, 1f, 0f); using var textPaint = new SKPaint(font) { - Color = new SKColor(128, 128, 128), + Color = SkiaTheme.TextPlaceholderSK, IsAntialias = true }; diff --git a/Views/SkiaContextMenu.cs b/Views/SkiaContextMenu.cs index e0a9b38..dd94ee9 100644 --- a/Views/SkiaContextMenu.cs +++ b/Views/SkiaContextMenu.cs @@ -12,15 +12,15 @@ public class SkiaContextMenu : SkiaView private int _hoveredIndex = -1; private SKRect[] _itemBounds = Array.Empty(); - private static readonly SKColor MenuBackground = new SKColor(255, 255, 255); - private static readonly SKColor MenuBackgroundDark = new SKColor(48, 48, 48); - private static readonly SKColor ItemHoverBackground = new SKColor(227, 242, 253); - private static readonly SKColor ItemHoverBackgroundDark = new SKColor(80, 80, 80); - private static readonly SKColor ItemTextColor = new SKColor(33, 33, 33); - private static readonly SKColor ItemTextColorDark = new SKColor(224, 224, 224); - private static readonly SKColor DisabledTextColor = new SKColor(158, 158, 158); - private static readonly SKColor SeparatorColor = new SKColor(224, 224, 224); - private static readonly SKColor ShadowColor = new SKColor(0, 0, 0, 40); + private static readonly SKColor MenuBackground = SkiaTheme.BackgroundWhiteSK; + private static readonly SKColor MenuBackgroundDark = SkiaTheme.DarkBackgroundSK; + private static readonly SKColor ItemHoverBackground = SkiaTheme.PrimarySelectionSK; + private static readonly SKColor ItemHoverBackgroundDark = SkiaTheme.DarkHoverSK; + private static readonly SKColor ItemTextColor = SkiaTheme.TextPrimarySK; + private static readonly SKColor ItemTextColorDark = SkiaTheme.DarkTextSK; + private static readonly SKColor DisabledTextColor = SkiaTheme.TextDisabledSK; + private static readonly SKColor SeparatorColor = SkiaTheme.Gray300SK; + private static readonly SKColor ShadowColor = SkiaTheme.Shadow25SK; private const float MenuPadding = 4f; private const float ItemHeight = 32f; diff --git a/Views/SkiaDatePicker.cs b/Views/SkiaDatePicker.cs index b63828f..e14a803 100644 --- a/Views/SkiaDatePicker.cs +++ b/Views/SkiaDatePicker.cs @@ -235,11 +235,7 @@ public class SkiaDatePicker : SkiaView private static SKColor ToSKColor(Color? color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } /// @@ -248,11 +244,7 @@ public class SkiaDatePicker : SkiaView private static SKColor ToSKColorWithAlpha(Color? color, byte alpha) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - alpha); + return color.ToSKColor().WithAlpha(alpha); } #endregion @@ -318,7 +310,7 @@ public class SkiaDatePicker : SkiaView using var bgPaint = new SKPaint { - Color = IsEnabled ? GetEffectiveBackgroundColor() : new SKColor(245, 245, 245), + Color = IsEnabled ? GetEffectiveBackgroundColor() : SkiaTheme.Gray100SK, Style = SKPaintStyle.Fill, IsAntialias = true }; @@ -410,7 +402,7 @@ public class SkiaDatePicker : SkiaView using var shadowPaint = new SKPaint { - Color = new SKColor(0, 0, 0, 40), + Color = SkiaTheme.Shadow25SK, MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 4f), Style = SKPaintStyle.Fill }; @@ -457,7 +449,7 @@ public class SkiaDatePicker : SkiaView using var font = new SKFont(SKTypeface.Default, 16f, 1f, 0f); using var textPaint = new SKPaint(font) { - Color = SKColors.White, + Color = SkiaTheme.BackgroundWhiteSK, IsAntialias = true }; @@ -468,7 +460,7 @@ public class SkiaDatePicker : SkiaView using var arrowPaint = new SKPaint { - Color = SKColors.White, + Color = SkiaTheme.BackgroundWhiteSK, Style = SKPaintStyle.Stroke, StrokeWidth = 2f, IsAntialias = true, @@ -496,7 +488,7 @@ public class SkiaDatePicker : SkiaView using var font = new SKFont(SKTypeface.Default, 12f, 1f, 0f); using var paint = new SKPaint(font) { - Color = new SKColor(128, 128, 128), + Color = SkiaTheme.TextPlaceholderSK, IsAntialias = true }; @@ -563,7 +555,7 @@ public class SkiaDatePicker : SkiaView canvas.DrawCircle(cellRect.MidX, cellRect.MidY, Math.Min(cellRect.Width, cellRect.Height) / 2f - 2f, bgPaint); } - textPaint.Color = isSelected ? SKColors.White : (isDisabled ? disabledDayColor : textColor); + textPaint.Color = isSelected ? SkiaTheme.BackgroundWhiteSK : (isDisabled ? disabledDayColor : textColor); string dayText = day.ToString(); SKRect dayTextBounds = default; textPaint.MeasureText(dayText, ref dayTextBounds); diff --git a/Views/SkiaEditor.cs b/Views/SkiaEditor.cs index 6767e65..ebb9e94 100644 --- a/Views/SkiaEditor.cs +++ b/Views/SkiaEditor.cs @@ -315,11 +315,7 @@ public class SkiaEditor : SkiaView, IInputContext private static SKColor ToSKColor(Color? color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } /// @@ -327,7 +323,7 @@ public class SkiaEditor : SkiaView, IInputContext /// private SKColor GetEffectiveTextColor() { - return TextColor != null ? ToSKColor(TextColor) : SKColors.Black; + return TextColor != null ? ToSKColor(TextColor) : SkiaTheme.TextPrimarySK; } /// @@ -335,7 +331,7 @@ public class SkiaEditor : SkiaView, IInputContext /// private SKColor GetEffectivePlaceholderColor() { - return PlaceholderColor != null ? ToSKColor(PlaceholderColor) : new SKColor(0x80, 0x80, 0x80); + return PlaceholderColor != null ? ToSKColor(PlaceholderColor) : SkiaTheme.TextPlaceholderSK; } /// @@ -886,7 +882,7 @@ public class SkiaEditor : SkiaView, IInputContext // Draw background var bgColor = EditorBackgroundColor != null ? ToSKColor(EditorBackgroundColor) : - (IsEnabled ? SKColors.White : new SKColor(0xF5, 0xF5, 0xF5)); + (IsEnabled ? SkiaTheme.BackgroundWhiteSK : SkiaTheme.Gray100SK); using var bgPaint = new SKPaint { Color = bgColor, @@ -1052,7 +1048,7 @@ public class SkiaEditor : SkiaView, IInputContext using var paint = new SKPaint { - Color = new SKColor(0, 0, 0, 60), + Color = SkiaTheme.Shadow25SK, Style = SKPaintStyle.Fill, IsAntialias = true }; diff --git a/Views/SkiaEntry.cs b/Views/SkiaEntry.cs index fc439ff..de2edfa 100644 --- a/Views/SkiaEntry.cs +++ b/Views/SkiaEntry.cs @@ -777,11 +777,7 @@ public class SkiaEntry : SkiaView, IInputContext private static SKColor ToSKColor(Color? color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } /// @@ -789,7 +785,7 @@ public class SkiaEntry : SkiaView, IInputContext /// private SKColor GetEffectiveTextColor() { - return TextColor != null ? ToSKColor(TextColor) : SKColors.Black; + return TextColor != null ? ToSKColor(TextColor) : SkiaTheme.TextPrimarySK; } /// @@ -797,7 +793,7 @@ public class SkiaEntry : SkiaView, IInputContext /// private SKColor GetEffectivePlaceholderColor() { - return PlaceholderColor != null ? ToSKColor(PlaceholderColor) : new SKColor(0x9E, 0x9E, 0x9E); + return PlaceholderColor != null ? ToSKColor(PlaceholderColor) : SkiaTheme.TextDisabledSK; } /// @@ -1018,7 +1014,7 @@ public class SkiaEntry : SkiaView, IInputContext // Draw circle background using var circlePaint = new SKPaint { - Color = new SKColor(0xBD, 0xBD, 0xBD), + Color = SkiaTheme.Gray400SK, IsAntialias = true, Style = SKPaintStyle.Fill }; @@ -1027,7 +1023,7 @@ public class SkiaEntry : SkiaView, IInputContext // Draw X using var xPaint = new SKPaint { - Color = SKColors.White, + Color = SkiaTheme.BackgroundWhiteSK, IsAntialias = true, Style = SKPaintStyle.Stroke, StrokeWidth = 2, diff --git a/Views/SkiaFlyoutPage.cs b/Views/SkiaFlyoutPage.cs index d6384d0..ac8f4d2 100644 --- a/Views/SkiaFlyoutPage.cs +++ b/Views/SkiaFlyoutPage.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.Maui.Graphics; using SkiaSharp; namespace Microsoft.Maui.Platform; @@ -22,6 +23,10 @@ public class SkiaFlyoutPage : SkiaLayoutView private float _dragStartX; private float _dragCurrentX; + // ScrimColor backing fields + private SKColor _scrimColorSK = SkiaTheme.Overlay40SK; + private Color _scrimColor = SkiaTheme.Overlay40; + /// /// Gets or sets the flyout content (menu). /// @@ -128,7 +133,16 @@ public class SkiaFlyoutPage : SkiaLayoutView /// /// Background color of the scrim when flyout is open. /// - public SKColor ScrimColor { get; set; } = new SKColor(0, 0, 0, 100); + public Color ScrimColor + { + get => _scrimColor; + set + { + _scrimColor = value; + _scrimColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Shadow width for the flyout. @@ -194,7 +208,7 @@ public class SkiaFlyoutPage : SkiaLayoutView // Draw scrim (semi-transparent overlay) using var scrimPaint = new SKPaint { - Color = ScrimColor.WithAlpha((byte)(ScrimColor.Alpha * _flyoutAnimationProgress)), + Color = _scrimColorSK.WithAlpha((byte)(_scrimColorSK.Alpha * _flyoutAnimationProgress)), Style = SKPaintStyle.Fill }; canvas.DrawRect(Bounds, scrimPaint); @@ -228,7 +242,7 @@ public class SkiaFlyoutPage : SkiaLayoutView Shader = SKShader.CreateLinearGradient( new SKPoint(shadowRect.Left, shadowRect.MidY), new SKPoint(shadowRect.Right, shadowRect.MidY), - new SKColor[] { new SKColor(0, 0, 0, 60), SKColors.Transparent }, + new SKColor[] { SkiaTheme.Shadow25SK, SKColors.Transparent }, null, SKShaderTileMode.Clamp) }; diff --git a/Views/SkiaImage.cs b/Views/SkiaImage.cs index d65f6b5..93aeb0a 100644 --- a/Views/SkiaImage.cs +++ b/Views/SkiaImage.cs @@ -177,15 +177,12 @@ public class SkiaImage : SkiaView /// /// Converts a MAUI Color to SkiaSharp SKColor. + /// Uses the ToSKColor() extension from ColorExtensions for MAUI-compliant theming. /// private static SKColor ToSKColor(Color color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } #endregion diff --git a/Views/SkiaImageButton.cs b/Views/SkiaImageButton.cs index 8e021ce..5040bfb 100644 --- a/Views/SkiaImageButton.cs +++ b/Views/SkiaImageButton.cs @@ -28,14 +28,14 @@ public class SkiaImageButton : SkiaView #endregion #region SKColor Helper + /// + /// Converts a MAUI Color to SkiaSharp SKColor. + /// Uses the ToSKColor() extension from ColorExtensions for MAUI-compliant theming. + /// private static SKColor ToSKColor(Color? color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } #endregion @@ -343,7 +343,7 @@ public class SkiaImageButton : SkiaView { using var focusPaint = new SKPaint { - Color = new SKColor(0x00, 0x00, 0x00, 0x40), + Color = SkiaTheme.Shadow25SK, Style = SKPaintStyle.Stroke, StrokeWidth = 2, IsAntialias = true diff --git a/Views/SkiaIndicatorView.cs b/Views/SkiaIndicatorView.cs index 6221303..4aaa9be 100644 --- a/Views/SkiaIndicatorView.cs +++ b/Views/SkiaIndicatorView.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.Maui.Graphics; using SkiaSharp; namespace Microsoft.Maui.Platform; @@ -14,6 +15,16 @@ public class SkiaIndicatorView : SkiaView private int _count = 0; private int _position = 0; + // SKColor fields for rendering + private SKColor _indicatorColorSK = SkiaTheme.IndicatorUnselectedSK; + private SKColor _selectedIndicatorColorSK = SkiaTheme.PrimarySK; + private SKColor _borderColorSK = SkiaTheme.Gray600SK; + + // MAUI Color backing fields + private Color _indicatorColor = Color.FromRgb(180, 180, 180); + private Color _selectedIndicatorColor = Color.FromRgb(33, 150, 243); + private Color _borderColor = Color.FromRgb(100, 100, 100); + /// /// Gets or sets the number of indicators to display. /// @@ -55,12 +66,30 @@ public class SkiaIndicatorView : SkiaView /// /// Gets or sets the indicator color. /// - public SKColor IndicatorColor { get; set; } = new SKColor(180, 180, 180); + public Color IndicatorColor + { + get => _indicatorColor; + set + { + _indicatorColor = value; + _indicatorColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Gets or sets the selected indicator color. /// - public SKColor SelectedIndicatorColor { get; set; } = new SKColor(33, 150, 243); + public Color SelectedIndicatorColor + { + get => _selectedIndicatorColor; + set + { + _selectedIndicatorColor = value; + _selectedIndicatorColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Gets or sets the indicator size. @@ -90,7 +119,16 @@ public class SkiaIndicatorView : SkiaView /// /// Gets or sets the border color. /// - public SKColor BorderColor { get; set; } = new SKColor(100, 100, 100); + public Color BorderColor + { + get => _borderColor; + set + { + _borderColor = value; + _borderColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Gets or sets the border width. @@ -150,21 +188,21 @@ public class SkiaIndicatorView : SkiaView using var normalPaint = new SKPaint { - Color = IndicatorColor, + Color = _indicatorColorSK, Style = SKPaintStyle.Fill, IsAntialias = true }; using var selectedPaint = new SKPaint { - Color = SelectedIndicatorColor, + Color = _selectedIndicatorColorSK, Style = SKPaintStyle.Fill, IsAntialias = true }; using var borderPaint = new SKPaint { - Color = BorderColor, + Color = _borderColorSK, Style = SKPaintStyle.Stroke, StrokeWidth = BorderWidth, IsAntialias = true diff --git a/Views/SkiaItemsView.cs b/Views/SkiaItemsView.cs index 311704a..372b227 100644 --- a/Views/SkiaItemsView.cs +++ b/Views/SkiaItemsView.cs @@ -35,8 +35,8 @@ public class SkiaItemsView : SkiaView // Scroll bar private bool _showVerticalScrollBar = true; private float _scrollBarWidth = 8; - private SKColor _scrollBarColor = new SKColor(128, 128, 128, 128); - private SKColor _scrollBarTrackColor = new SKColor(200, 200, 200, 64); + private Color _scrollBarColor = SkiaTheme.ScrollbarThumb; + private Color _scrollBarTrackColor = SkiaTheme.ScrollbarTrack; public IEnumerable? ItemsSource { @@ -261,7 +261,7 @@ public class SkiaItemsView : SkiaView // Draw selection highlight if (index == SelectedIndex) { - paint.Color = new SKColor(0x21, 0x96, 0xF3, 0x59); // Light blue with 35% opacity + paint.Color = SkiaTheme.PrimarySelectionSK; paint.Style = SKPaintStyle.Fill; canvas.DrawRect(bounds, paint); } @@ -312,7 +312,7 @@ public class SkiaItemsView : SkiaView } // Draw separator - paint.Color = new SKColor(0xE0, 0xE0, 0xE0); + paint.Color = SkiaTheme.Gray300SK; paint.Style = SKPaintStyle.Stroke; paint.StrokeWidth = 1; canvas.DrawLine(bounds.Left, bounds.Bottom, bounds.Right, bounds.Bottom, paint); @@ -325,13 +325,13 @@ public class SkiaItemsView : SkiaView } // Default rendering - just show ToString - paint.Color = SKColors.Black; + paint.Color = SkiaTheme.TextPrimarySK; paint.Style = SKPaintStyle.Fill; using var font = new SKFont(SKTypeface.Default, 14); using var textPaint = new SKPaint(font) { - Color = SKColors.Black, + Color = SkiaTheme.TextPrimarySK, IsAntialias = true }; @@ -348,14 +348,14 @@ public class SkiaItemsView : SkiaView { using var paint = new SKPaint { - Color = new SKColor(0x80, 0x80, 0x80), + Color = SkiaTheme.TextPlaceholderSK, IsAntialias = true }; using var font = new SKFont(SKTypeface.Default, 16); using var textPaint = new SKPaint(font) { - Color = new SKColor(0x80, 0x80, 0x80), + Color = SkiaTheme.TextPlaceholderSK, IsAntialias = true }; @@ -379,7 +379,7 @@ public class SkiaItemsView : SkiaView // Draw track using var trackPaint = new SKPaint { - Color = _scrollBarTrackColor, + Color = SkiaTheme.ScrollbarTrackSK, Style = SKPaintStyle.Fill }; canvas.DrawRect(trackRect, trackPaint); @@ -399,7 +399,7 @@ public class SkiaItemsView : SkiaView // Draw thumb using var thumbPaint = new SKPaint { - Color = _scrollBarColor, + Color = SkiaTheme.ScrollbarThumbSK, Style = SKPaintStyle.Fill, IsAntialias = true }; diff --git a/Views/SkiaLabel.cs b/Views/SkiaLabel.cs index afe56df..3641274 100644 --- a/Views/SkiaLabel.cs +++ b/Views/SkiaLabel.cs @@ -608,12 +608,8 @@ public class SkiaLabel : SkiaView private SKColor ToSKColor(Color? color) { - if (color == null) return SKColors.Black; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + if (color == null) return SkiaTheme.TextPrimarySK; + return color.ToSKColor(); } private string GetDisplayText() @@ -791,7 +787,7 @@ public class SkiaLabel : SkiaView using var selectionPaint = new SKPaint { - Color = new SKColor(0x21, 0x96, 0xF3, 0x60), // Semi-transparent blue + Color = SkiaTheme.PrimaryLightSK, Style = SKPaintStyle.Fill }; diff --git a/Views/SkiaMenuBar.cs b/Views/SkiaMenuBar.cs index c960ae4..72cb6da 100644 --- a/Views/SkiaMenuBar.cs +++ b/Views/SkiaMenuBar.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.Maui.Graphics; using SkiaSharp; namespace Microsoft.Maui.Platform; @@ -15,30 +16,78 @@ public class SkiaMenuBar : SkiaView private int _openIndex = -1; private SkiaMenuFlyout? _openFlyout; + // Internal SKColor fields for rendering + private SKColor _menuBackgroundColorSK = SkiaTheme.MenuBackgroundSK; + private SKColor _textColorSK = SkiaTheme.TextPrimarySK; + private SKColor _hoverBackgroundColorSK = SkiaTheme.MenuHoverSK; + private SKColor _activeBackgroundColorSK = SkiaTheme.MenuActiveSK; + + // MAUI Color backing fields + private Color _menuBackgroundColor = Color.FromRgb(240, 240, 240); + private Color _textColor = Color.FromRgb(33, 33, 33); + private Color _hoverBackgroundColor = Color.FromRgb(220, 220, 220); + private Color _activeBackgroundColor = Color.FromRgb(200, 200, 200); + /// /// Gets the menu bar items. /// public IList Items => _items; /// - /// Gets or sets the background color. + /// Gets or sets the menu bar background color. /// - public SKColor BackgroundColor { get; set; } = new SKColor(240, 240, 240); + public new Color MenuBackgroundColor + { + get => _menuBackgroundColor; + set + { + _menuBackgroundColor = value; + _menuBackgroundColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Gets or sets the text color. /// - public SKColor TextColor { get; set; } = new SKColor(33, 33, 33); + public Color TextColor + { + get => _textColor; + set + { + _textColor = value; + _textColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Gets or sets the hover background color. /// - public SKColor HoverBackgroundColor { get; set; } = new SKColor(220, 220, 220); + public Color HoverBackgroundColor + { + get => _hoverBackgroundColor; + set + { + _hoverBackgroundColor = value; + _hoverBackgroundColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Gets or sets the active background color. /// - public SKColor ActiveBackgroundColor { get; set; } = new SKColor(200, 200, 200); + public Color ActiveBackgroundColor + { + get => _activeBackgroundColor; + set + { + _activeBackgroundColor = value; + _activeBackgroundColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Gets or sets the bar height. @@ -67,7 +116,7 @@ public class SkiaMenuBar : SkiaView // Draw background using var bgPaint = new SKPaint { - Color = BackgroundColor, + Color = _menuBackgroundColorSK, Style = SKPaintStyle.Fill }; canvas.DrawRect(Bounds, bgPaint); @@ -75,7 +124,7 @@ public class SkiaMenuBar : SkiaView // Draw bottom border using var borderPaint = new SKPaint { - Color = new SKColor(200, 200, 200), + Color = SkiaTheme.BorderMediumSK, Style = SKPaintStyle.Stroke, StrokeWidth = 1 }; @@ -84,7 +133,7 @@ public class SkiaMenuBar : SkiaView // Draw menu items using var textPaint = new SKPaint { - Color = TextColor, + Color = _textColorSK, TextSize = FontSize, IsAntialias = true }; @@ -103,12 +152,12 @@ public class SkiaMenuBar : SkiaView // Draw item background if (i == _openIndex) { - using var activePaint = new SKPaint { Color = ActiveBackgroundColor, Style = SKPaintStyle.Fill }; + using var activePaint = new SKPaint { Color = _activeBackgroundColorSK, Style = SKPaintStyle.Fill }; canvas.DrawRect(itemBounds, activePaint); } else if (i == _hoveredIndex) { - using var hoverPaint = new SKPaint { Color = HoverBackgroundColor, Style = SKPaintStyle.Fill }; + using var hoverPaint = new SKPaint { Color = _hoverBackgroundColorSK, Style = SKPaintStyle.Fill }; canvas.DrawRect(itemBounds, hoverPaint); } diff --git a/Views/SkiaMenuFlyout.cs b/Views/SkiaMenuFlyout.cs index 909b0cc..a27dc52 100644 --- a/Views/SkiaMenuFlyout.cs +++ b/Views/SkiaMenuFlyout.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using Microsoft.Maui.Graphics; using SkiaSharp; namespace Microsoft.Maui.Platform; @@ -12,19 +13,73 @@ public class SkiaMenuFlyout : SkiaView private int _hoveredIndex = -1; private SKRect _bounds; + // SKColor fields for rendering + private SKColor _menuBackgroundColorSK = SkiaTheme.BackgroundWhiteSK; + private SKColor _textColorSK = SkiaTheme.TextPrimarySK; + private SKColor _disabledTextColorSK = SkiaTheme.TextDisabledSK; + private SKColor _hoverBackgroundColorSK = SkiaTheme.Gray200SK; + private SKColor _separatorColorSK = SkiaTheme.MenuSeparatorSK; + + // Color backing fields + private Color _menuBackgroundColor = Colors.White; + private Color _textColor = Color.FromRgb(33, 33, 33); + private Color _disabledTextColor = Color.FromRgb(160, 160, 160); + private Color _hoverBackgroundColor = Color.FromRgb(230, 230, 230); + private Color _separatorColor = Color.FromRgb(220, 220, 220); + public List Items { get; set; } = new List(); public SKPoint Position { get; set; } - public new SKColor BackgroundColor { get; set; } = SKColors.White; + public Color MenuBackgroundColor + { + get => _menuBackgroundColor; + set + { + _menuBackgroundColor = value; + _menuBackgroundColorSK = value.ToSKColor(); + } + } - public SKColor TextColor { get; set; } = new SKColor(33, 33, 33); + public Color TextColor + { + get => _textColor; + set + { + _textColor = value; + _textColorSK = value.ToSKColor(); + } + } - public SKColor DisabledTextColor { get; set; } = new SKColor(160, 160, 160); + public Color DisabledTextColor + { + get => _disabledTextColor; + set + { + _disabledTextColor = value; + _disabledTextColorSK = value.ToSKColor(); + } + } - public SKColor HoverBackgroundColor { get; set; } = new SKColor(230, 230, 230); + public Color HoverBackgroundColor + { + get => _hoverBackgroundColor; + set + { + _hoverBackgroundColor = value; + _hoverBackgroundColorSK = value.ToSKColor(); + } + } - public SKColor SeparatorColor { get; set; } = new SKColor(220, 220, 220); + public Color SeparatorColor + { + get => _separatorColor; + set + { + _separatorColor = value; + _separatorColorSK = value.ToSKColor(); + } + } public float FontSize { get; set; } = 13f; @@ -77,14 +132,14 @@ public class SkiaMenuFlyout : SkiaView // Draw shadow using var shadowPaint = new SKPaint { - ImageFilter = SKImageFilter.CreateDropShadow(0f, 2f, 8f, 8f, new SKColor(0, 0, 0, 40)) + ImageFilter = SKImageFilter.CreateDropShadow(0f, 2f, 8f, 8f, SkiaTheme.Shadow25SK) }; canvas.DrawRect(_bounds, shadowPaint); // Draw background using var bgPaint = new SKPaint { - Color = BackgroundColor, + Color = _menuBackgroundColorSK, Style = SKPaintStyle.Fill }; canvas.DrawRect(_bounds, bgPaint); @@ -92,7 +147,7 @@ public class SkiaMenuFlyout : SkiaView // Draw border using var borderPaint = new SKPaint { - Color = new SKColor(200, 200, 200), + Color = SkiaTheme.BorderMediumSK, Style = SKPaintStyle.Stroke, StrokeWidth = 1f }; @@ -100,7 +155,7 @@ public class SkiaMenuFlyout : SkiaView // Draw items float y = _bounds.Top; - textPaint.Color = TextColor; + textPaint.Color = _textColorSK; for (int i = 0; i < Items.Count; i++) { @@ -111,7 +166,7 @@ public class SkiaMenuFlyout : SkiaView float separatorY = y + SeparatorHeight / 2f; using var sepPaint = new SKPaint { - Color = SeparatorColor, + Color = _separatorColorSK, StrokeWidth = 1f }; canvas.DrawLine(_bounds.Left + 8f, separatorY, _bounds.Right - 8f, separatorY, sepPaint); @@ -126,7 +181,7 @@ public class SkiaMenuFlyout : SkiaView { using var hoverPaint = new SKPaint { - Color = HoverBackgroundColor, + Color = _hoverBackgroundColorSK, Style = SKPaintStyle.Fill }; canvas.DrawRect(itemBounds, hoverPaint); @@ -137,7 +192,7 @@ public class SkiaMenuFlyout : SkiaView { using var checkPaint = new SKPaint { - Color = menuItem.IsEnabled ? TextColor : DisabledTextColor, + Color = menuItem.IsEnabled ? _textColorSK : _disabledTextColorSK, TextSize = FontSize, IsAntialias = true }; @@ -145,13 +200,13 @@ public class SkiaMenuFlyout : SkiaView } // Draw text - textPaint.Color = menuItem.IsEnabled ? TextColor : DisabledTextColor; + textPaint.Color = menuItem.IsEnabled ? _textColorSK : _disabledTextColorSK; canvas.DrawText(menuItem.Text, _bounds.Left + 28f, y + ItemHeight / 2f + 5f, textPaint); // Draw shortcut if (!string.IsNullOrEmpty(menuItem.Shortcut)) { - textPaint.Color = DisabledTextColor; + textPaint.Color = _disabledTextColorSK; var shortcutBounds = new SKRect(); textPaint.MeasureText(menuItem.Shortcut, ref shortcutBounds); canvas.DrawText(menuItem.Shortcut, _bounds.Right - shortcutBounds.Width - 12f, y + ItemHeight / 2f + 5f, textPaint); diff --git a/Views/SkiaNavigationPage.cs b/Views/SkiaNavigationPage.cs index 7cc6a36..0cd1f69 100644 --- a/Views/SkiaNavigationPage.cs +++ b/Views/SkiaNavigationPage.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.Maui.Graphics; using Microsoft.Maui.Platform.Linux; using SkiaSharp; @@ -23,28 +24,32 @@ public class SkiaNavigationPage : SkiaView private bool _isPushAnimation; // Navigation bar styling - private SKColor _barBackgroundColor = new SKColor(0x21, 0x96, 0xF3); + private SKColor _barBackgroundColor = SkiaTheme.PrimarySK; private SKColor _barTextColor = SKColors.White; + private Color _barBackgroundColorMaui = Color.FromRgb(0x21, 0x96, 0xF3); + private Color _barTextColorMaui = Colors.White; private float _navigationBarHeight = 56; private bool _showBackButton = true; - public SKColor BarBackgroundColor + public Color BarBackgroundColor { - get => _barBackgroundColor; + get => _barBackgroundColorMaui; set { - _barBackgroundColor = value; + _barBackgroundColorMaui = value; + _barBackgroundColor = value.ToSKColor(); UpdatePageNavigationBar(); Invalidate(); } } - public SKColor BarTextColor + public Color BarTextColor { - get => _barTextColor; + get => _barTextColorMaui; set { - _barTextColor = value; + _barTextColorMaui = value; + _barTextColor = value.ToSKColor(); UpdatePageNavigationBar(); Invalidate(); } @@ -194,8 +199,8 @@ public class SkiaNavigationPage : SkiaView private void ConfigurePage(SkiaPage page, bool showBackButton) { page.ShowNavigationBar = true; - page.TitleBarColor = _barBackgroundColor; - page.TitleTextColor = _barTextColor; + page.TitleBarColor = _barBackgroundColorMaui; + page.TitleTextColor = _barTextColorMaui; page.NavigationBarHeight = _navigationBarHeight; _showBackButton = showBackButton && _navigationStack.Count > 0; } @@ -204,8 +209,8 @@ public class SkiaNavigationPage : SkiaView { if (_currentPage != null) { - _currentPage.TitleBarColor = _barBackgroundColor; - _currentPage.TitleTextColor = _barTextColor; + _currentPage.TitleBarColor = _barBackgroundColorMaui; + _currentPage.TitleTextColor = _barTextColorMaui; _currentPage.NavigationBarHeight = _navigationBarHeight; } } diff --git a/Views/SkiaPage.cs b/Views/SkiaPage.cs index 146e2a8..7a26541 100644 --- a/Views/SkiaPage.cs +++ b/Views/SkiaPage.cs @@ -13,8 +13,10 @@ public class SkiaPage : SkiaView { private SkiaView? _content; private string _title = ""; - private SKColor _titleBarColor = new SKColor(0x21, 0x96, 0xF3); // Material Blue - private SKColor _titleTextColor = SKColors.White; + protected SKColor _titleBarColor = SkiaTheme.PrimarySK; + protected SKColor _titleTextColor = SKColors.White; + private Color _titleBarColorMaui = Color.FromRgb(0x21, 0x96, 0xF3); // Material Blue + private Color _titleTextColorMaui = Colors.White; private bool _showNavigationBar = false; private float _navigationBarHeight = 56; @@ -52,22 +54,24 @@ public class SkiaPage : SkiaView } } - public SKColor TitleBarColor + public Color TitleBarColor { - get => _titleBarColor; + get => _titleBarColorMaui; set { - _titleBarColor = value; + _titleBarColorMaui = value; + _titleBarColor = value.ToSKColor(); Invalidate(); } } - public SKColor TitleTextColor + public Color TitleTextColor { - get => _titleTextColor; + get => _titleTextColorMaui; set { - _titleTextColor = value; + _titleTextColorMaui = value; + _titleTextColor = value.ToSKColor(); Invalidate(); } } @@ -228,7 +232,7 @@ public class SkiaPage : SkiaView // Draw shadow using var shadowPaint = new SKPaint { - Color = new SKColor(0, 0, 0, 30), + Color = SkiaTheme.Shadow20SK, Style = SKPaintStyle.Fill, MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 2) }; @@ -240,7 +244,7 @@ public class SkiaPage : SkiaView // Draw semi-transparent overlay using var overlayPaint = new SKPaint { - Color = new SKColor(255, 255, 255, 180), + Color = SkiaTheme.WhiteSemiTransparentSK, Style = SKPaintStyle.Fill }; canvas.DrawRect(bounds, overlayPaint); @@ -379,7 +383,7 @@ public class SkiaContentPage : SkiaPage // Draw navigation bar background using var barPaint = new SKPaint { - Color = TitleBarColor, + Color = _titleBarColor, Style = SKPaintStyle.Fill }; canvas.DrawRect(bounds, barPaint); @@ -390,7 +394,7 @@ public class SkiaContentPage : SkiaPage using var font = new SKFont(SKTypeface.Default, 20); using var textPaint = new SKPaint(font) { - Color = TitleTextColor, + Color = _titleTextColor, IsAntialias = true }; @@ -408,7 +412,7 @@ public class SkiaContentPage : SkiaPage // Draw shadow using var shadowPaint = new SKPaint { - Color = new SKColor(0, 0, 0, 30), + Color = SkiaTheme.Shadow20SK, Style = SKPaintStyle.Fill, MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 2) }; @@ -424,7 +428,7 @@ public class SkiaContentPage : SkiaPage using var font = new SKFont(SKTypeface.Default, 14); using var textPaint = new SKPaint(font) { - Color = TitleTextColor, + Color = _titleTextColor, IsAntialias = true }; diff --git a/Views/SkiaPicker.cs b/Views/SkiaPicker.cs index 6c6bf62..df72398 100644 --- a/Views/SkiaPicker.cs +++ b/Views/SkiaPicker.cs @@ -24,11 +24,7 @@ public class SkiaPicker : SkiaView private static SKColor ToSKColor(Color? color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } #endregion @@ -584,7 +580,7 @@ public class SkiaPicker : SkiaView // Draw shadow using var shadowPaint = new SKPaint { - Color = new SKColor(0, 0, 0, 40), + Color = SkiaTheme.Shadow25SK, MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 4), Style = SKPaintStyle.Fill }; diff --git a/Views/SkiaProgressBar.cs b/Views/SkiaProgressBar.cs index 7a83913..bffa185 100644 --- a/Views/SkiaProgressBar.cs +++ b/Views/SkiaProgressBar.cs @@ -21,11 +21,7 @@ public class SkiaProgressBar : SkiaView private static SKColor ToSKColor(Color? color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } #endregion diff --git a/Views/SkiaRadioButton.cs b/Views/SkiaRadioButton.cs index 6664e57..e179058 100644 --- a/Views/SkiaRadioButton.cs +++ b/Views/SkiaRadioButton.cs @@ -24,11 +24,7 @@ public class SkiaRadioButton : SkiaView private static SKColor ToSKColor(Color? color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } #endregion diff --git a/Views/SkiaRefreshView.cs b/Views/SkiaRefreshView.cs index ab0857a..3e2b57d 100644 --- a/Views/SkiaRefreshView.cs +++ b/Views/SkiaRefreshView.cs @@ -3,6 +3,7 @@ using System; using System.Windows.Input; +using Microsoft.Maui.Graphics; using SkiaSharp; namespace Microsoft.Maui.Platform; @@ -21,6 +22,14 @@ public class SkiaRefreshView : SkiaLayoutView private float _spinnerRotation = 0f; private DateTime _lastSpinnerUpdate; + // SKColor fields for rendering + private SKColor _refreshColorSK = SkiaTheme.PrimarySK; + private SKColor _refreshBackgroundColorSK = SKColors.White; + + // MAUI Color backing fields + private Color _refreshColor = Color.FromRgb(33, 150, 243); + private Color _refreshBackgroundColor = Colors.White; + /// /// Gets or sets the content view. /// @@ -81,12 +90,30 @@ public class SkiaRefreshView : SkiaLayoutView /// /// Gets or sets the refresh indicator color. /// - public SKColor RefreshColor { get; set; } = new SKColor(33, 150, 243); + public Color RefreshColor + { + get => _refreshColor; + set + { + _refreshColor = value; + _refreshColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Gets or sets the background color of the refresh indicator. /// - public SKColor RefreshBackgroundColor { get; set; } = SKColors.White; + public Color RefreshBackgroundColor + { + get => _refreshBackgroundColor; + set + { + _refreshBackgroundColor = value; + _refreshBackgroundColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Gets or sets the command to execute when refresh is triggered. @@ -154,19 +181,19 @@ public class SkiaRefreshView : SkiaLayoutView // Draw background circle using var bgPaint = new SKPaint { - Color = RefreshBackgroundColor, + Color = _refreshBackgroundColorSK, Style = SKPaintStyle.Fill, IsAntialias = true }; // Add shadow - bgPaint.ImageFilter = SKImageFilter.CreateDropShadow(0, 2, 4, 4, new SKColor(0, 0, 0, 40)); + bgPaint.ImageFilter = SKImageFilter.CreateDropShadow(0, 2, 4, 4, SkiaTheme.Shadow25SK); canvas.DrawCircle(x, y, size / 2, bgPaint); // Draw spinner using var spinnerPaint = new SKPaint { - Color = RefreshColor, + Color = _refreshColorSK, Style = SKPaintStyle.Stroke, StrokeWidth = 3, IsAntialias = true, diff --git a/Views/SkiaScrollView.cs b/Views/SkiaScrollView.cs index 4544059..84d178f 100644 --- a/Views/SkiaScrollView.cs +++ b/Views/SkiaScrollView.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.Maui.Graphics; using SkiaSharp; namespace Microsoft.Maui.Platform; @@ -54,11 +55,19 @@ public class SkiaScrollView : SkiaView public static readonly BindableProperty ScrollBarColorProperty = BindableProperty.Create( nameof(ScrollBarColor), - typeof(SKColor), + typeof(Color), typeof(SkiaScrollView), - new SKColor(0x80, 0x80, 0x80, 0x80), + Color.FromRgba(0x80, 0x80, 0x80, 0x80), BindingMode.TwoWay, - propertyChanged: (b, o, n) => ((SkiaScrollView)b).Invalidate()); + propertyChanged: (b, o, n) => + { + var view = (SkiaScrollView)b; + if (n is Color color) + { + view._scrollBarColorSK = color.ToSKColor(); + } + view.Invalidate(); + }); /// /// Bindable property for ScrollBarWidth. @@ -106,9 +115,9 @@ public class SkiaScrollView : SkiaView /// /// Scrollbar color. /// - public SKColor ScrollBarColor + public Color ScrollBarColor { - get => (SKColor)GetValue(ScrollBarColorProperty); + get => (Color)GetValue(ScrollBarColorProperty); set => SetValue(ScrollBarColorProperty, value); } @@ -126,6 +135,7 @@ public class SkiaScrollView : SkiaView private SkiaView? _content; private float _scrollX; private float _scrollY; + private SKColor _scrollBarColorSK = SkiaTheme.ScrollbarThumbSK; private float _velocityX; private float _velocityY; private bool _isDragging; @@ -353,7 +363,7 @@ public class SkiaScrollView : SkiaView using var paint = new SKPaint { - Color = ScrollBarColor, + Color = _scrollBarColorSK, IsAntialias = true }; @@ -376,7 +386,7 @@ public class SkiaScrollView : SkiaView using var paint = new SKPaint { - Color = ScrollBarColor, + Color = _scrollBarColorSK, IsAntialias = true }; diff --git a/Views/SkiaSearchBar.cs b/Views/SkiaSearchBar.cs index ac79d9d..24319f4 100644 --- a/Views/SkiaSearchBar.cs +++ b/Views/SkiaSearchBar.cs @@ -133,36 +133,6 @@ public class SkiaSearchBar : SkiaView #endregion - #region Helper Methods - - /// - /// Converts a MAUI Color to SkiaSharp SKColor. - /// - private static SKColor ToSKColor(Color? color) - { - if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); - } - - /// - /// Converts a MAUI Color to SKColor with modified alpha. - /// - private static SKColor ToSKColorWithAlpha(Color? color, byte alpha) - { - if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - alpha); - } - - #endregion - #region Drawing protected override void OnDraw(SKCanvas canvas, SKRect bounds) @@ -175,7 +145,7 @@ public class SkiaSearchBar : SkiaView // Draw background using var bgPaint = new SKPaint { - Color = ToSKColor(SearchBarBackgroundColor), + Color = SearchBarBackgroundColor.ToSKColor(), IsAntialias = true, Style = SKPaintStyle.Fill }; @@ -188,7 +158,7 @@ public class SkiaSearchBar : SkiaView { using var borderPaint = new SKPaint { - Color = ToSKColor(FocusedBorderColor), + Color = FocusedBorderColor.ToSKColor(), IsAntialias = true, Style = SKPaintStyle.Stroke, StrokeWidth = 2 @@ -224,7 +194,7 @@ public class SkiaSearchBar : SkiaView { using var paint = new SKPaint { - Color = ToSKColor(IconColor), + Color = IconColor.ToSKColor(), IsAntialias = true, Style = SKPaintStyle.Stroke, StrokeWidth = 2, @@ -252,7 +222,7 @@ public class SkiaSearchBar : SkiaView // Draw circle background using var bgPaint = new SKPaint { - Color = ToSKColorWithAlpha(ClearButtonColor, 80), + Color = ClearButtonColor.ToSKColor().WithAlpha(80), IsAntialias = true, Style = SKPaintStyle.Fill }; @@ -261,7 +231,7 @@ public class SkiaSearchBar : SkiaView // Draw X using var paint = new SKPaint { - Color = ToSKColor(ClearButtonColor), + Color = ClearButtonColor.ToSKColor(), IsAntialias = true, Style = SKPaintStyle.Stroke, StrokeWidth = 2, diff --git a/Views/SkiaShell.cs b/Views/SkiaShell.cs index 73746f6..40c5f13 100644 --- a/Views/SkiaShell.cs +++ b/Views/SkiaShell.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.Maui.Graphics; using SkiaSharp; namespace Microsoft.Maui.Platform; @@ -56,11 +57,11 @@ public class SkiaShell : SkiaLayoutView public static readonly BindableProperty FlyoutBackgroundColorProperty = BindableProperty.Create( nameof(FlyoutBackgroundColor), - typeof(SKColor), + typeof(Color), typeof(SkiaShell), - SKColors.White, + Colors.White, BindingMode.TwoWay, - propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate()); + propertyChanged: (b, o, n) => ((SkiaShell)b).OnFlyoutBackgroundColorChanged()); /// /// Bindable property for FlyoutTextColor. @@ -68,11 +69,11 @@ public class SkiaShell : SkiaLayoutView public static readonly BindableProperty FlyoutTextColorProperty = BindableProperty.Create( nameof(FlyoutTextColor), - typeof(SKColor), + typeof(Color), typeof(SkiaShell), - new SKColor(33, 33, 33), + Color.FromRgb(33, 33, 33), BindingMode.TwoWay, - propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate()); + propertyChanged: (b, o, n) => ((SkiaShell)b).OnFlyoutTextColorChanged()); /// /// Bindable property for NavBarBackgroundColor. @@ -80,11 +81,11 @@ public class SkiaShell : SkiaLayoutView public static readonly BindableProperty NavBarBackgroundColorProperty = BindableProperty.Create( nameof(NavBarBackgroundColor), - typeof(SKColor), + typeof(Color), typeof(SkiaShell), - new SKColor(33, 150, 243), + Color.FromRgb(33, 150, 243), BindingMode.TwoWay, - propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate()); + propertyChanged: (b, o, n) => ((SkiaShell)b).OnNavBarBackgroundColorChanged()); /// /// Bindable property for NavBarTextColor. @@ -92,11 +93,11 @@ public class SkiaShell : SkiaLayoutView public static readonly BindableProperty NavBarTextColorProperty = BindableProperty.Create( nameof(NavBarTextColor), - typeof(SKColor), + typeof(Color), typeof(SkiaShell), - SKColors.White, + Colors.White, BindingMode.TwoWay, - propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate()); + propertyChanged: (b, o, n) => ((SkiaShell)b).OnNavBarTextColorChanged()); /// /// Bindable property for NavBarHeight. @@ -164,11 +165,11 @@ public class SkiaShell : SkiaLayoutView public static readonly BindableProperty ContentBackgroundColorProperty = BindableProperty.Create( nameof(ContentBackgroundColor), - typeof(SKColor), + typeof(Color), typeof(SkiaShell), - new SKColor(250, 250, 250), + Color.FromRgb(250, 250, 250), BindingMode.TwoWay, - propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate()); + propertyChanged: (b, o, n) => ((SkiaShell)b).OnContentBackgroundColorChanged()); /// /// Bindable property for Title. @@ -197,6 +198,43 @@ public class SkiaShell : SkiaLayoutView private readonly Dictionary> _registeredRoutes = new(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _routeTitles = new(StringComparer.OrdinalIgnoreCase); + // Internal SKColor fields for rendering + private SKColor _flyoutBackgroundColorSK = SkiaTheme.BackgroundWhiteSK; + private SKColor _flyoutTextColorSK = SkiaTheme.TextPrimarySK; + private SKColor _navBarBackgroundColorSK = SkiaTheme.PrimarySK; + private SKColor _navBarTextColorSK = SkiaTheme.BackgroundWhiteSK; + private SKColor _contentBackgroundColorSK = SkiaTheme.Gray50SK; + + private void OnFlyoutBackgroundColorChanged() + { + _flyoutBackgroundColorSK = FlyoutBackgroundColor?.ToSKColor() ?? SkiaTheme.BackgroundWhiteSK; + Invalidate(); + } + + private void OnFlyoutTextColorChanged() + { + _flyoutTextColorSK = FlyoutTextColor?.ToSKColor() ?? SkiaTheme.TextPrimarySK; + Invalidate(); + } + + private void OnNavBarBackgroundColorChanged() + { + _navBarBackgroundColorSK = NavBarBackgroundColor?.ToSKColor() ?? SkiaTheme.PrimarySK; + Invalidate(); + } + + private void OnNavBarTextColorChanged() + { + _navBarTextColorSK = NavBarTextColor?.ToSKColor() ?? SkiaTheme.BackgroundWhiteSK; + Invalidate(); + } + + private void OnContentBackgroundColorChanged() + { + _contentBackgroundColorSK = ContentBackgroundColor?.ToSKColor() ?? SkiaTheme.Gray50SK; + Invalidate(); + } + private void OnFlyoutIsPresentedChanged(bool newValue) { _flyoutAnimationProgress = newValue ? 1f : 0f; @@ -234,18 +272,18 @@ public class SkiaShell : SkiaLayoutView /// /// Background color of the flyout. /// - public SKColor FlyoutBackgroundColor + public Color? FlyoutBackgroundColor { - get => (SKColor)GetValue(FlyoutBackgroundColorProperty); + get => (Color?)GetValue(FlyoutBackgroundColorProperty); set => SetValue(FlyoutBackgroundColorProperty, value); } /// /// Text color in the flyout. /// - public SKColor FlyoutTextColor + public Color? FlyoutTextColor { - get => (SKColor)GetValue(FlyoutTextColorProperty); + get => (Color?)GetValue(FlyoutTextColorProperty); set => SetValue(FlyoutTextColorProperty, value); } @@ -272,18 +310,18 @@ public class SkiaShell : SkiaLayoutView /// /// Background color of the navigation bar. /// - public SKColor NavBarBackgroundColor + public Color? NavBarBackgroundColor { - get => (SKColor)GetValue(NavBarBackgroundColorProperty); + get => (Color?)GetValue(NavBarBackgroundColorProperty); set => SetValue(NavBarBackgroundColorProperty, value); } /// /// Text color of the navigation bar title. /// - public SKColor NavBarTextColor + public Color? NavBarTextColor { - get => (SKColor)GetValue(NavBarTextColorProperty); + get => (Color?)GetValue(NavBarTextColorProperty); set => SetValue(NavBarTextColorProperty, value); } @@ -335,9 +373,9 @@ public class SkiaShell : SkiaLayoutView /// /// Background color of the content area. /// - public SKColor ContentBackgroundColor + public Color? ContentBackgroundColor { - get => (SKColor)GetValue(ContentBackgroundColorProperty); + get => (Color?)GetValue(ContentBackgroundColorProperty); set => SetValue(ContentBackgroundColorProperty, value); } @@ -789,7 +827,7 @@ public class SkiaShell : SkiaLayoutView // Draw background using var bgPaint = new SKPaint { - Color = NavBarBackgroundColor, + Color = _navBarBackgroundColorSK, Style = SKPaintStyle.Fill, IsAntialias = true }; @@ -798,7 +836,7 @@ public class SkiaShell : SkiaLayoutView // Draw nav icon (back arrow if can go back, else hamburger menu if flyout enabled) using var iconPaint = new SKPaint { - Color = NavBarTextColor, + Color = _navBarTextColorSK, Style = SKPaintStyle.Stroke, StrokeWidth = 2, StrokeCap = SKStrokeCap.Round, @@ -813,7 +851,7 @@ public class SkiaShell : SkiaLayoutView // Draw iOS-style back chevron "<" using var chevronPaint = new SKPaint { - Color = NavBarTextColor, + Color = _navBarTextColorSK, Style = SKPaintStyle.Stroke, StrokeWidth = 2.5f, StrokeCap = SKStrokeCap.Round, @@ -838,7 +876,7 @@ public class SkiaShell : SkiaLayoutView // Draw title using var titlePaint = new SKPaint { - Color = NavBarTextColor, + Color = _navBarTextColorSK, TextSize = 20f, IsAntialias = true, FakeBoldText = true @@ -865,7 +903,7 @@ public class SkiaShell : SkiaLayoutView // Draw background using var bgPaint = new SKPaint { - Color = SKColors.White, + Color = SkiaTheme.BackgroundWhiteSK, Style = SKPaintStyle.Fill, IsAntialias = true }; @@ -874,7 +912,7 @@ public class SkiaShell : SkiaLayoutView // Draw top border using var borderPaint = new SKPaint { - Color = new SKColor(224, 224, 224), + Color = SkiaTheme.Gray300SK, Style = SKPaintStyle.Stroke, StrokeWidth = 1 }; @@ -894,7 +932,7 @@ public class SkiaShell : SkiaLayoutView var item = section.Items[i]; bool isSelected = i == _selectedItemIndex; - textPaint.Color = isSelected ? NavBarBackgroundColor : new SKColor(117, 117, 117); + textPaint.Color = isSelected ? _navBarBackgroundColorSK : SkiaTheme.TextTertiarySK; var textBounds = new SKRect(); textPaint.MeasureText(item.Title, ref textBounds); @@ -911,7 +949,7 @@ public class SkiaShell : SkiaLayoutView // Draw scrim using var scrimPaint = new SKPaint { - Color = new SKColor(0, 0, 0, (byte)(100 * _flyoutAnimationProgress)), + Color = SkiaTheme.Shadow40SK.WithAlpha((byte)(100 * _flyoutAnimationProgress)), Style = SKPaintStyle.Fill }; canvas.DrawRect(bounds, scrimPaint); @@ -926,7 +964,7 @@ public class SkiaShell : SkiaLayoutView using var flyoutPaint = new SKPaint { - Color = FlyoutBackgroundColor, + Color = _flyoutBackgroundColorSK, Style = SKPaintStyle.Fill, IsAntialias = true }; @@ -952,14 +990,14 @@ public class SkiaShell : SkiaLayoutView { using var selectionPaint = new SKPaint { - Color = new SKColor(33, 150, 243, 30), + Color = SkiaTheme.PrimarySelectionSK.WithAlpha(30), Style = SKPaintStyle.Fill }; var selectionRect = new SKRect(flyoutBounds.Left, itemY, flyoutBounds.Right, itemY + itemHeight); canvas.DrawRect(selectionRect, selectionPaint); } - itemTextPaint.Color = isSelected ? NavBarBackgroundColor : new SKColor(33, 33, 33); + itemTextPaint.Color = isSelected ? _navBarBackgroundColorSK : _flyoutTextColorSK; canvas.DrawText(section.Title, flyoutBounds.Left + 16, itemY + 30, itemTextPaint); itemY += itemHeight; diff --git a/Views/SkiaSlider.cs b/Views/SkiaSlider.cs index bed5ae5..987b7db 100644 --- a/Views/SkiaSlider.cs +++ b/Views/SkiaSlider.cs @@ -22,11 +22,7 @@ public class SkiaSlider : SkiaView private static SKColor ToSKColor(Color? color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } #endregion @@ -187,10 +183,10 @@ public class SkiaSlider : SkiaView set => SetValue(ThumbColorProperty, value); } - // Platform defaults for colors when null - private static readonly SKColor DefaultMinimumTrackColor = new SKColor(0x21, 0x96, 0xF3); // Material Blue - private static readonly SKColor DefaultMaximumTrackColor = new SKColor(0xE0, 0xE0, 0xE0); // Gray - private static readonly SKColor DefaultThumbColor = new SKColor(0x21, 0x96, 0xF3); // Material Blue + // Platform defaults for colors when null - using centralized theme + private static readonly SKColor DefaultMinimumTrackColor = SkiaTheme.PrimarySK; // Material Blue + private static readonly SKColor DefaultMaximumTrackColor = SkiaTheme.Gray300SK; // Gray + private static readonly SKColor DefaultThumbColor = SkiaTheme.PrimarySK; // Material Blue private SKColor GetEffectiveMinimumTrackColor() => MinimumTrackColor != null ? ToSKColor(MinimumTrackColor) : DefaultMinimumTrackColor; private SKColor GetEffectiveMaximumTrackColor() => MaximumTrackColor != null ? ToSKColor(MaximumTrackColor) : DefaultMaximumTrackColor; @@ -346,7 +342,7 @@ public class SkiaSlider : SkiaView { using var shadowPaint = new SKPaint { - Color = new SKColor(0, 0, 0, 30), + Color = SkiaTheme.Shadow20SK, IsAntialias = true, MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 3) }; diff --git a/Views/SkiaStepper.cs b/Views/SkiaStepper.cs index 445bc8a..703a072 100644 --- a/Views/SkiaStepper.cs +++ b/Views/SkiaStepper.cs @@ -21,11 +21,7 @@ public class SkiaStepper : SkiaView private static SKColor ToSKColor(Color? color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } #endregion diff --git a/Views/SkiaSwitch.cs b/Views/SkiaSwitch.cs index 38811d0..8ce05eb 100644 --- a/Views/SkiaSwitch.cs +++ b/Views/SkiaSwitch.cs @@ -23,11 +23,7 @@ public class SkiaSwitch : SkiaView private static SKColor ToSKColor(Color? color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } #endregion @@ -345,7 +341,7 @@ public class SkiaSwitch : SkiaView { using var shadowPaint = new SKPaint { - Color = new SKColor(0, 0, 0, 40), + Color = SkiaTheme.Shadow25SK, IsAntialias = true, MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 2f) }; @@ -355,7 +351,7 @@ public class SkiaSwitch : SkiaView // Draw thumb using var thumbPaint = new SKPaint { - Color = IsEnabled ? thumbColorSK : new SKColor(245, 245, 245), + Color = IsEnabled ? thumbColorSK : SkiaTheme.Gray100SK, IsAntialias = true, Style = SKPaintStyle.Fill }; diff --git a/Views/SkiaTabbedPage.cs b/Views/SkiaTabbedPage.cs index d2faa34..26f723a 100644 --- a/Views/SkiaTabbedPage.cs +++ b/Views/SkiaTabbedPage.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.Maui.Graphics; using SkiaSharp; namespace Microsoft.Maui.Platform; @@ -15,6 +16,18 @@ public class SkiaTabbedPage : SkiaLayoutView private float _tabBarHeight = 48f; private bool _tabBarOnBottom = false; + // SKColor fields for rendering + private SKColor _tabBarBackgroundColorSK = SkiaTheme.PrimarySK; + private SKColor _selectedTabColorSK = SKColors.White; + private SKColor _unselectedTabColorSK = SkiaTheme.WhiteSemiTransparentSK; + private SKColor _indicatorColorSK = SKColors.White; + + // MAUI Color backing fields + private Color _tabBarBackgroundColor = Color.FromRgb(33, 150, 243); + private Color _selectedTabColor = Colors.White; + private Color _unselectedTabColor = Color.FromRgba(255, 255, 255, 180); + private Color _indicatorColor = Colors.White; + /// /// Gets or sets the height of the tab bar. /// @@ -80,22 +93,58 @@ public class SkiaTabbedPage : SkiaLayoutView /// /// Background color for the tab bar. /// - public SKColor TabBarBackgroundColor { get; set; } = new SKColor(33, 150, 243); // Material Blue + public Color TabBarBackgroundColor + { + get => _tabBarBackgroundColor; + set + { + _tabBarBackgroundColor = value; + _tabBarBackgroundColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Color for selected tab text/icon. /// - public SKColor SelectedTabColor { get; set; } = SKColors.White; + public Color SelectedTabColor + { + get => _selectedTabColor; + set + { + _selectedTabColor = value; + _selectedTabColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Color for unselected tab text/icon. /// - public SKColor UnselectedTabColor { get; set; } = new SKColor(255, 255, 255, 180); + public Color UnselectedTabColor + { + get => _unselectedTabColor; + set + { + _unselectedTabColor = value; + _unselectedTabColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Color of the selection indicator. /// - public SKColor IndicatorColor { get; set; } = SKColors.White; + public Color IndicatorColor + { + get => _indicatorColor; + set + { + _indicatorColor = value; + _indicatorColorSK = value.ToSKColor(); + Invalidate(); + } + } /// /// Height of the selection indicator. @@ -252,7 +301,7 @@ public class SkiaTabbedPage : SkiaLayoutView // Draw background using var bgPaint = new SKPaint { - Color = TabBarBackgroundColor, + Color = _tabBarBackgroundColorSK, Style = SKPaintStyle.Fill, IsAntialias = true }; @@ -281,7 +330,7 @@ public class SkiaTabbedPage : SkiaLayoutView tabBarBounds.Bottom); bool isSelected = i == _selectedIndex; - textPaint.Color = isSelected ? SelectedTabColor : UnselectedTabColor; + textPaint.Color = isSelected ? _selectedTabColorSK : _unselectedTabColorSK; textPaint.FakeBoldText = isSelected; // Draw tab title centered @@ -299,7 +348,7 @@ public class SkiaTabbedPage : SkiaLayoutView { using var indicatorPaint = new SKPaint { - Color = IndicatorColor, + Color = _indicatorColorSK, Style = SKPaintStyle.Fill, IsAntialias = true }; diff --git a/Views/SkiaTheme.cs b/Views/SkiaTheme.cs new file mode 100644 index 0000000..9e31ff3 --- /dev/null +++ b/Views/SkiaTheme.cs @@ -0,0 +1,320 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Maui.Graphics; +using SkiaSharp; + +namespace Microsoft.Maui.Platform; + +/// +/// Centralized theme colors for Skia views using MAUI Color types. +/// All colors are defined as MAUI Colors for API compliance and converted to SKColor for rendering. +/// +public static class SkiaTheme +{ + #region Primary Colors + + /// Material Blue - Primary accent color + public static readonly Color Primary = Color.FromRgb(0x21, 0x96, 0xF3); + + /// Material Blue Dark - Darker primary variant + public static readonly Color PrimaryDark = Color.FromRgb(0x19, 0x76, 0xD2); + + /// Material Blue Light with transparency + public static readonly Color PrimaryLight = Color.FromRgba(0x21, 0x96, 0xF3, 0x60); + + /// Material Blue with 35% opacity for selection + public static readonly Color PrimarySelection = Color.FromRgba(0x21, 0x96, 0xF3, 0x59); + + /// Material Blue with 50% opacity + public static readonly Color PrimaryHalf = Color.FromRgba(0x21, 0x96, 0xF3, 0x80); + + #endregion + + #region Text Colors + + /// Primary text color - dark gray + public static readonly Color TextPrimary = Color.FromRgb(0x21, 0x21, 0x21); + + /// Secondary text color - medium gray + public static readonly Color TextSecondary = Color.FromRgb(0x61, 0x61, 0x61); + + /// Tertiary/hint text color + public static readonly Color TextTertiary = Color.FromRgb(0x75, 0x75, 0x75); + + /// Disabled text color + public static readonly Color TextDisabled = Color.FromRgb(0x9E, 0x9E, 0x9E); + + /// Placeholder text color + public static readonly Color TextPlaceholder = Color.FromRgb(0x80, 0x80, 0x80); + + /// Link text color + public static readonly Color TextLink = Color.FromRgb(0x21, 0x96, 0xF3); + + /// Visited link text color - Material Purple + public static readonly Color TextLinkVisited = Color.FromRgb(0x9C, 0x27, 0xB0); + + #endregion + + #region Background Colors + + /// White background + public static readonly Color BackgroundWhite = Colors.White; + + /// Semi-transparent white (59% opacity) + public static readonly Color WhiteSemiTransparent = Color.FromRgba(255, 255, 255, 150); + + /// Light gray background + public static readonly Color BackgroundLight = Color.FromRgb(0xF5, 0xF5, 0xF5); + + /// Slightly darker light background + public static readonly Color BackgroundLightAlt = Color.FromRgb(0xFA, 0xFA, 0xFA); + + /// Surface background (cards, dialogs) + public static readonly Color BackgroundSurface = Color.FromRgb(0xFF, 0xFF, 0xFF); + + /// Disabled background + public static readonly Color BackgroundDisabled = Color.FromRgb(0xEE, 0xEE, 0xEE); + + #endregion + + #region Gray Scale + + /// Gray 50 - lightest + public static readonly Color Gray50 = Color.FromRgb(0xFA, 0xFA, 0xFA); + + /// Gray 100 + public static readonly Color Gray100 = Color.FromRgb(0xF5, 0xF5, 0xF5); + + /// Gray 200 + public static readonly Color Gray200 = Color.FromRgb(0xEE, 0xEE, 0xEE); + + /// Gray 300 + public static readonly Color Gray300 = Color.FromRgb(0xE0, 0xE0, 0xE0); + + /// Gray 400 + public static readonly Color Gray400 = Color.FromRgb(0xBD, 0xBD, 0xBD); + + /// Gray 500 + public static readonly Color Gray500 = Color.FromRgb(0x9E, 0x9E, 0x9E); + + /// Gray 600 + public static readonly Color Gray600 = Color.FromRgb(0x75, 0x75, 0x75); + + /// Gray 700 + public static readonly Color Gray700 = Color.FromRgb(0x61, 0x61, 0x61); + + /// Gray 800 + public static readonly Color Gray800 = Color.FromRgb(0x42, 0x42, 0x42); + + /// Gray 900 - darkest + public static readonly Color Gray900 = Color.FromRgb(0x21, 0x21, 0x21); + + #endregion + + #region Border Colors + + /// Light border color + public static readonly Color BorderLight = Color.FromRgb(0xE0, 0xE0, 0xE0); + + /// Medium border color + public static readonly Color BorderMedium = Color.FromRgb(0xC8, 0xC8, 0xC8); + + /// Dark border color + public static readonly Color BorderDark = Color.FromRgb(0xA0, 0xA0, 0xA0); + + #endregion + + #region Shadow Colors + + /// Shadow with 10% opacity + public static readonly Color Shadow10 = Color.FromRgba(0, 0, 0, 0x1A); + + /// Shadow with 15% opacity + public static readonly Color Shadow15 = Color.FromRgba(0, 0, 0, 0x26); + + /// Shadow with 20% opacity + public static readonly Color Shadow20 = Color.FromRgba(0, 0, 0, 0x33); + + /// Shadow with 25% opacity + public static readonly Color Shadow25 = Color.FromRgba(0, 0, 0, 0x40); + + /// Shadow with 40% opacity + public static readonly Color Shadow40 = Color.FromRgba(0, 0, 0, 0x64); + + /// Shadow with 50% opacity + public static readonly Color Shadow50 = Color.FromRgba(0, 0, 0, 0x80); + + #endregion + + #region Overlay Colors + + /// Scrim/overlay with 40% opacity + public static readonly Color Overlay40 = Color.FromRgba(0, 0, 0, 0x64); + + /// Scrim/overlay with 50% opacity + public static readonly Color Overlay50 = Color.FromRgba(0, 0, 0, 0x80); + + #endregion + + #region Status Colors + + /// Error/danger color - Material Red + public static readonly Color Error = Color.FromRgb(0xF4, 0x43, 0x36); + + /// Success color - Material Green + public static readonly Color Success = Color.FromRgb(0x4C, 0xAF, 0x50); + + /// Warning color - Material Orange + public static readonly Color Warning = Color.FromRgb(0xFF, 0x98, 0x00); + + #endregion + + #region Button Colors + + /// Cancel button background + public static readonly Color ButtonCancel = Color.FromRgb(0x9E, 0x9E, 0x9E); + + /// Cancel button hover + public static readonly Color ButtonCancelHover = Color.FromRgb(0x75, 0x75, 0x75); + + #endregion + + #region Scrollbar Colors + + /// Scrollbar thumb color + public static readonly Color ScrollbarThumb = Color.FromRgba(0x80, 0x80, 0x80, 0x80); + + /// Scrollbar track color + public static readonly Color ScrollbarTrack = Color.FromRgba(0xC8, 0xC8, 0xC8, 0x40); + + #endregion + + #region Indicator Colors + + /// Unselected indicator color + public static readonly Color IndicatorUnselected = Color.FromRgb(0xB4, 0xB4, 0xB4); + + /// Selected indicator color + public static readonly Color IndicatorSelected = Color.FromRgb(0x21, 0x96, 0xF3); + + #endregion + + #region Menu Colors + + /// Menu background + public static readonly Color MenuBackground = Color.FromRgb(0xF0, 0xF0, 0xF0); + + /// Menu hover background + public static readonly Color MenuHover = Color.FromRgb(0xDC, 0xDC, 0xDC); + + /// Menu active/pressed background + public static readonly Color MenuActive = Color.FromRgb(0xC8, 0xC8, 0xC8); + + /// Menu separator color + public static readonly Color MenuSeparator = Color.FromRgb(0xDC, 0xDC, 0xDC); + + #endregion + + #region Dark Theme Colors + + /// Dark theme background + public static readonly Color DarkBackground = Color.FromRgb(0x30, 0x30, 0x30); + + /// Dark theme surface + public static readonly Color DarkSurface = Color.FromRgb(0x50, 0x50, 0x50); + + /// Dark theme text + public static readonly Color DarkText = Color.FromRgb(0xE0, 0xE0, 0xE0); + + /// Dark theme hover + public static readonly Color DarkHover = Color.FromRgb(0x50, 0x50, 0x50); + + #endregion + + #region SKColor Cached Conversions (for rendering performance) + + // Primary + public static readonly SKColor PrimarySK = Primary.ToSKColor(); + public static readonly SKColor PrimaryDarkSK = PrimaryDark.ToSKColor(); + public static readonly SKColor PrimaryLightSK = PrimaryLight.ToSKColor(); + public static readonly SKColor PrimarySelectionSK = PrimarySelection.ToSKColor(); + public static readonly SKColor PrimaryHalfSK = PrimaryHalf.ToSKColor(); + + // Text + public static readonly SKColor TextPrimarySK = TextPrimary.ToSKColor(); + public static readonly SKColor TextSecondarySK = TextSecondary.ToSKColor(); + public static readonly SKColor TextTertiarySK = TextTertiary.ToSKColor(); + public static readonly SKColor TextDisabledSK = TextDisabled.ToSKColor(); + public static readonly SKColor TextPlaceholderSK = TextPlaceholder.ToSKColor(); + public static readonly SKColor TextLinkSK = TextLink.ToSKColor(); + public static readonly SKColor TextLinkVisitedSK = TextLinkVisited.ToSKColor(); + + // Backgrounds + public static readonly SKColor BackgroundWhiteSK = SKColors.White; + public static readonly SKColor WhiteSemiTransparentSK = WhiteSemiTransparent.ToSKColor(); + public static readonly SKColor BackgroundLightSK = BackgroundLight.ToSKColor(); + public static readonly SKColor BackgroundLightAltSK = BackgroundLightAlt.ToSKColor(); + public static readonly SKColor BackgroundSurfaceSK = BackgroundSurface.ToSKColor(); + public static readonly SKColor BackgroundDisabledSK = BackgroundDisabled.ToSKColor(); + + // Gray scale + public static readonly SKColor Gray50SK = Gray50.ToSKColor(); + public static readonly SKColor Gray100SK = Gray100.ToSKColor(); + public static readonly SKColor Gray200SK = Gray200.ToSKColor(); + public static readonly SKColor Gray300SK = Gray300.ToSKColor(); + public static readonly SKColor Gray400SK = Gray400.ToSKColor(); + public static readonly SKColor Gray500SK = Gray500.ToSKColor(); + public static readonly SKColor Gray600SK = Gray600.ToSKColor(); + public static readonly SKColor Gray700SK = Gray700.ToSKColor(); + public static readonly SKColor Gray800SK = Gray800.ToSKColor(); + public static readonly SKColor Gray900SK = Gray900.ToSKColor(); + + // Borders + public static readonly SKColor BorderLightSK = BorderLight.ToSKColor(); + public static readonly SKColor BorderMediumSK = BorderMedium.ToSKColor(); + public static readonly SKColor BorderDarkSK = BorderDark.ToSKColor(); + + // Shadows + public static readonly SKColor Shadow10SK = Shadow10.ToSKColor(); + public static readonly SKColor Shadow15SK = Shadow15.ToSKColor(); + public static readonly SKColor Shadow20SK = Shadow20.ToSKColor(); + public static readonly SKColor Shadow25SK = Shadow25.ToSKColor(); + public static readonly SKColor Shadow40SK = Shadow40.ToSKColor(); + public static readonly SKColor Shadow50SK = Shadow50.ToSKColor(); + + // Overlays + public static readonly SKColor Overlay40SK = Overlay40.ToSKColor(); + public static readonly SKColor Overlay50SK = Overlay50.ToSKColor(); + + // Status + public static readonly SKColor ErrorSK = Error.ToSKColor(); + public static readonly SKColor SuccessSK = Success.ToSKColor(); + public static readonly SKColor WarningSK = Warning.ToSKColor(); + + // Buttons + public static readonly SKColor ButtonCancelSK = ButtonCancel.ToSKColor(); + public static readonly SKColor ButtonCancelHoverSK = ButtonCancelHover.ToSKColor(); + + // Scrollbars + public static readonly SKColor ScrollbarThumbSK = ScrollbarThumb.ToSKColor(); + public static readonly SKColor ScrollbarTrackSK = ScrollbarTrack.ToSKColor(); + + // Indicators + public static readonly SKColor IndicatorUnselectedSK = IndicatorUnselected.ToSKColor(); + public static readonly SKColor IndicatorSelectedSK = IndicatorSelected.ToSKColor(); + + // Menu + public static readonly SKColor MenuBackgroundSK = MenuBackground.ToSKColor(); + public static readonly SKColor MenuHoverSK = MenuHover.ToSKColor(); + public static readonly SKColor MenuActiveSK = MenuActive.ToSKColor(); + public static readonly SKColor MenuSeparatorSK = MenuSeparator.ToSKColor(); + + // Dark theme + public static readonly SKColor DarkBackgroundSK = DarkBackground.ToSKColor(); + public static readonly SKColor DarkSurfaceSK = DarkSurface.ToSKColor(); + public static readonly SKColor DarkTextSK = DarkText.ToSKColor(); + public static readonly SKColor DarkHoverSK = DarkHover.ToSKColor(); + + #endregion +} diff --git a/Views/SkiaTimePicker.cs b/Views/SkiaTimePicker.cs index c0ed135..e37b247 100644 --- a/Views/SkiaTimePicker.cs +++ b/Views/SkiaTimePicker.cs @@ -4,6 +4,7 @@ using Microsoft.Maui.Controls; using Microsoft.Maui.Graphics; using Microsoft.Maui.Platform.Linux; +using Microsoft.Maui.Platform.Linux.Converters; using SkiaSharp; namespace Microsoft.Maui.Platform; @@ -223,11 +224,7 @@ public class SkiaTimePicker : SkiaView private static SKColor ToSKColor(Color? color) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - (byte)(color.Alpha * 255)); + return color.ToSKColor(); } /// @@ -236,11 +233,7 @@ public class SkiaTimePicker : SkiaView private static SKColor ToSKColorWithAlpha(Color? color, byte alpha) { if (color == null) return SKColors.Transparent; - return new SKColor( - (byte)(color.Red * 255), - (byte)(color.Green * 255), - (byte)(color.Blue * 255), - alpha); + return color.ToSKColor().WithAlpha(alpha); } /// @@ -298,7 +291,7 @@ public class SkiaTimePicker : SkiaView using var bgPaint = new SKPaint { - Color = IsEnabled ? GetEffectiveBackgroundColor() : new SKColor(245, 245, 245), + Color = IsEnabled ? GetEffectiveBackgroundColor() : SkiaTheme.Gray100SK, Style = SKPaintStyle.Fill, IsAntialias = true }; @@ -375,7 +368,7 @@ public class SkiaTimePicker : SkiaView float cornerRadius = (float)CornerRadius; var popupRect = GetPopupRect(bounds); - using var shadowPaint = new SKPaint { Color = new SKColor(0, 0, 0, 40), MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 4), Style = SKPaintStyle.Fill }; + using var shadowPaint = new SKPaint { Color = SkiaTheme.Shadow25SK, MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 4), Style = SKPaintStyle.Fill }; canvas.DrawRoundRect(new SKRoundRect(new SKRect(popupRect.Left + 2, popupRect.Top + 2, popupRect.Right + 2, popupRect.Bottom + 2), cornerRadius), shadowPaint); using var bgPaint = new SKPaint { Color = ToSKColor(ClockBackgroundColor), Style = SKPaintStyle.Fill, IsAntialias = true }; @@ -399,8 +392,8 @@ public class SkiaTimePicker : SkiaView canvas.DrawRect(new SKRect(bounds.Left, bounds.Top + cornerRadius, bounds.Right, bounds.Bottom), headerPaint); using var font = new SKFont(SKTypeface.Default, 32); - using var selectedPaint = new SKPaint(font) { Color = SKColors.White, IsAntialias = true }; - using var unselectedPaint = new SKPaint(font) { Color = new SKColor(255, 255, 255, 150), IsAntialias = true }; + using var selectedPaint = new SKPaint(font) { Color = SkiaTheme.BackgroundWhiteSK, IsAntialias = true }; + using var unselectedPaint = new SKPaint(font) { Color = SkiaTheme.WhiteSemiTransparentSK, IsAntialias = true }; var hourText = _selectedHour.ToString("D2"); var minuteText = _selectedMinute.ToString("D2"); @@ -448,7 +441,7 @@ public class SkiaTimePicker : SkiaView { using var selBgPaint = new SKPaint { Color = selectedColor, Style = SKPaintStyle.Fill, IsAntialias = true }; canvas.DrawCircle(x, y, 18, selBgPaint); - textPaint.Color = SKColors.White; + textPaint.Color = SkiaTheme.BackgroundWhiteSK; } else textPaint.Color = textColor; var tBounds = new SKRect(); @@ -470,7 +463,7 @@ public class SkiaTimePicker : SkiaView { using var selBgPaint = new SKPaint { Color = selectedColor, Style = SKPaintStyle.Fill, IsAntialias = true }; canvas.DrawCircle(x, y, 18, selBgPaint); - textPaint.Color = SKColors.White; + textPaint.Color = SkiaTheme.BackgroundWhiteSK; } else textPaint.Color = textColor; var tBounds = new SKRect(); diff --git a/Views/SkiaView.cs b/Views/SkiaView.cs index 90852fb..1e34edf 100644 --- a/Views/SkiaView.cs +++ b/Views/SkiaView.cs @@ -100,19 +100,19 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible InitializeHighContrastService(); return _highContrastService?.GetColors() ?? new HighContrastColors { - Background = SKColors.White, - Foreground = new SKColor(33, 33, 33), - Accent = new SKColor(33, 150, 243), - Border = new SKColor(200, 200, 200), - Error = new SKColor(244, 67, 54), - Success = new SKColor(76, 175, 80), - Warning = new SKColor(255, 152, 0), - Link = new SKColor(33, 150, 243), - LinkVisited = new SKColor(156, 39, 176), - Selection = new SKColor(33, 150, 243), - SelectionText = SKColors.White, - DisabledText = new SKColor(158, 158, 158), - DisabledBackground = new SKColor(238, 238, 238) + Background = SkiaTheme.BackgroundWhiteSK, + Foreground = SkiaTheme.TextPrimarySK, + Accent = SkiaTheme.PrimarySK, + Border = SkiaTheme.BorderMediumSK, + Error = SkiaTheme.ErrorSK, + Success = SkiaTheme.SuccessSK, + Warning = SkiaTheme.WarningSK, + Link = SkiaTheme.TextLinkSK, + LinkVisited = SkiaTheme.TextLinkVisitedSK, + Selection = SkiaTheme.PrimarySK, + SelectionText = SkiaTheme.BackgroundWhiteSK, + DisabledText = SkiaTheme.TextDisabledSK, + DisabledBackground = SkiaTheme.BackgroundDisabledSK }; } @@ -1386,12 +1386,8 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible if (Shadow == null) return; var shadowColor = Shadow.Brush is SolidColorBrush scb - ? new SKColor( - (byte)(scb.Color.Red * 255), - (byte)(scb.Color.Green * 255), - (byte)(scb.Color.Blue * 255), - (byte)(scb.Color.Alpha * 255 * Shadow.Opacity)) - : new SKColor(0, 0, 0, (byte)(255 * Shadow.Opacity)); + ? scb.Color.ToSKColor().WithAlpha((byte)(scb.Color.Alpha * 255 * Shadow.Opacity)) + : SKColors.Black.WithAlpha((byte)(255 * Shadow.Opacity)); using var shadowPaint = new SKPaint { @@ -1484,11 +1480,7 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible if (Background is SolidColorBrush scb) { - paint.Color = new SKColor( - (byte)(scb.Color.Red * 255), - (byte)(scb.Color.Green * 255), - (byte)(scb.Color.Blue * 255), - (byte)(scb.Color.Alpha * 255)); + paint.Color = scb.Color.ToSKColor(); canvas.DrawRect(bounds, paint); } else if (Background is LinearGradientBrush lgb) @@ -1500,12 +1492,7 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible bounds.Left + (float)(lgb.EndPoint.X * bounds.Width), bounds.Top + (float)(lgb.EndPoint.Y * bounds.Height)); - var colors = lgb.GradientStops.Select(s => - new SKColor( - (byte)(s.Color.Red * 255), - (byte)(s.Color.Green * 255), - (byte)(s.Color.Blue * 255), - (byte)(s.Color.Alpha * 255))).ToArray(); + var colors = lgb.GradientStops.Select(s => s.Color.ToSKColor()).ToArray(); var positions = lgb.GradientStops.Select(s => s.Offset).ToArray(); paint.Shader = SKShader.CreateLinearGradient(start, end, colors, positions, SKShaderTileMode.Clamp); @@ -1518,12 +1505,7 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible bounds.Top + (float)(rgb.Center.Y * bounds.Height)); var radius = (float)(rgb.Radius * Math.Max(bounds.Width, bounds.Height)); - var colors = rgb.GradientStops.Select(s => - new SKColor( - (byte)(s.Color.Red * 255), - (byte)(s.Color.Green * 255), - (byte)(s.Color.Blue * 255), - (byte)(s.Color.Alpha * 255))).ToArray(); + var colors = rgb.GradientStops.Select(s => s.Color.ToSKColor()).ToArray(); var positions = rgb.GradientStops.Select(s => s.Offset).ToArray(); paint.Shader = SKShader.CreateRadialGradient(center, radius, colors, positions, SKShaderTileMode.Clamp); diff --git a/Views/SkiaWebView.cs b/Views/SkiaWebView.cs index 1cb3f29..63faad3 100644 --- a/Views/SkiaWebView.cs +++ b/Views/SkiaWebView.cs @@ -1377,7 +1377,7 @@ public class SkiaWebView : SkiaView using var borderPaint = new SKPaint { - Color = new SKColor(200, 200, 200), + Color = SkiaTheme.BorderMediumSK, Style = SKPaintStyle.Stroke, StrokeWidth = 1 }; @@ -1388,7 +1388,7 @@ public class SkiaWebView : SkiaView using var iconPaint = new SKPaint { - Color = new SKColor(100, 100, 100), + Color = SkiaTheme.Gray600SK, Style = SKPaintStyle.Stroke, StrokeWidth = 2, IsAntialias = true @@ -1399,7 +1399,7 @@ public class SkiaWebView : SkiaView using var textPaint = new SKPaint { - Color = new SKColor(80, 80, 80), + Color = SkiaTheme.Gray700SK, IsAntialias = true, TextSize = 14 }; @@ -1429,7 +1429,7 @@ public class SkiaWebView : SkiaView { using var hintPaint = new SKPaint { - Color = new SKColor(120, 120, 120), + Color = SkiaTheme.Gray600SK, IsAntialias = true, TextSize = 11 }; @@ -1441,12 +1441,12 @@ public class SkiaWebView : SkiaView if (_loadProgress > 0 && _loadProgress < 1) { var progressRect = new SKRect(bounds.Left + 20, bounds.Bottom - 30, bounds.Right - 20, bounds.Bottom - 20); - using var progressBgPaint = new SKPaint { Color = new SKColor(230, 230, 230), Style = SKPaintStyle.Fill }; + using var progressBgPaint = new SKPaint { Color = SkiaTheme.Gray200SK, Style = SKPaintStyle.Fill }; canvas.DrawRoundRect(new SKRoundRect(progressRect, 5), progressBgPaint); float filledWidth = progressRect.Width * (float)_loadProgress; var filledRect = new SKRect(progressRect.Left, progressRect.Top, progressRect.Left + filledWidth, progressRect.Bottom); - using var progressPaint = new SKPaint { Color = new SKColor(33, 150, 243), Style = SKPaintStyle.Fill }; + using var progressPaint = new SKPaint { Color = SkiaTheme.PrimarySK, Style = SKPaintStyle.Fill }; canvas.DrawRoundRect(new SKRoundRect(filledRect, 5), progressPaint); } } diff --git a/Views/SwipeItem.cs b/Views/SwipeItem.cs index a229ea6..b000b91 100644 --- a/Views/SwipeItem.cs +++ b/Views/SwipeItem.cs @@ -36,18 +36,10 @@ public class SwipeItem /// /// Helper to convert BackgroundColor to SKColor for rendering. /// - internal SKColor GetBackgroundColorSK() => new SKColor( - (byte)(BackgroundColor.Red * 255), - (byte)(BackgroundColor.Green * 255), - (byte)(BackgroundColor.Blue * 255), - (byte)(BackgroundColor.Alpha * 255)); + internal SKColor GetBackgroundColorSK() => BackgroundColor.ToSKColor(); /// /// Helper to convert TextColor to SKColor for rendering. /// - internal SKColor GetTextColorSK() => new SKColor( - (byte)(TextColor.Red * 255), - (byte)(TextColor.Green * 255), - (byte)(TextColor.Blue * 255), - (byte)(TextColor.Alpha * 255)); + internal SKColor GetTextColorSK() => TextColor.ToSKColor(); }