Color issues

This commit is contained in:
2026-01-17 03:36:37 +00:00
parent aad915ad86
commit a367365ce5
46 changed files with 970 additions and 443 deletions

View File

@@ -171,7 +171,7 @@ public partial class FlyoutPageHandler : ViewHandler<IFlyoutView, SkiaFlyoutPage
if (flyoutView is FlyoutPage flyoutPage && flyoutPage.Background is SolidColorBrush solidBrush) if (flyoutView is FlyoutPage flyoutPage && flyoutPage.Background is SolidColorBrush solidBrush)
{ {
handler.PlatformView.ScrimColor = solidBrush.Color.ToSKColor().WithAlpha(100); handler.PlatformView.ScrimColor = solidBrush.Color.WithAlpha(100f / 255f);
} }
} }
} }

View File

@@ -89,7 +89,7 @@ public partial class IndicatorViewHandler : ViewHandler<IndicatorView, SkiaIndic
if (indicatorView.IndicatorColor is not null) if (indicatorView.IndicatorColor is not null)
{ {
handler.PlatformView.IndicatorColor = indicatorView.IndicatorColor.ToSKColor(); handler.PlatformView.IndicatorColor = indicatorView.IndicatorColor;
} }
} }
@@ -99,7 +99,7 @@ public partial class IndicatorViewHandler : ViewHandler<IndicatorView, SkiaIndic
if (indicatorView.SelectedIndicatorColor is not null) if (indicatorView.SelectedIndicatorColor is not null)
{ {
handler.PlatformView.SelectedIndicatorColor = indicatorView.SelectedIndicatorColor.ToSKColor(); handler.PlatformView.SelectedIndicatorColor = indicatorView.SelectedIndicatorColor;
} }
} }

View File

@@ -364,7 +364,7 @@ public partial class NavigationPageHandler : ViewHandler<NavigationPage, SkiaNav
if (navigationPage.BarBackgroundColor is not null) if (navigationPage.BarBackgroundColor is not null)
{ {
handler.PlatformView.BarBackgroundColor = navigationPage.BarBackgroundColor.ToSKColor(); handler.PlatformView.BarBackgroundColor = navigationPage.BarBackgroundColor;
} }
} }
@@ -374,7 +374,7 @@ public partial class NavigationPageHandler : ViewHandler<NavigationPage, SkiaNav
if (navigationPage.BarBackground is SolidColorBrush solidBrush) if (navigationPage.BarBackground is SolidColorBrush solidBrush)
{ {
handler.PlatformView.BarBackgroundColor = solidBrush.Color.ToSKColor(); handler.PlatformView.BarBackgroundColor = solidBrush.Color;
} }
} }
@@ -384,7 +384,7 @@ public partial class NavigationPageHandler : ViewHandler<NavigationPage, SkiaNav
if (navigationPage.BarTextColor is not null) if (navigationPage.BarTextColor is not null)
{ {
handler.PlatformView.BarTextColor = navigationPage.BarTextColor.ToSKColor(); handler.PlatformView.BarTextColor = navigationPage.BarTextColor;
} }
} }

View File

@@ -123,7 +123,7 @@ public partial class RefreshViewHandler : ViewHandler<RefreshView, SkiaRefreshVi
if (refreshView.RefreshColor is not null) if (refreshView.RefreshColor is not null)
{ {
handler.PlatformView.RefreshColor = refreshView.RefreshColor.ToSKColor(); handler.PlatformView.RefreshColor = refreshView.RefreshColor;
} }
} }
@@ -145,7 +145,7 @@ public partial class RefreshViewHandler : ViewHandler<RefreshView, SkiaRefreshVi
if (refreshView.Background is SolidColorBrush solidBrush) if (refreshView.Background is SolidColorBrush solidBrush)
{ {
handler.PlatformView.RefreshBackgroundColor = solidBrush.Color.ToSKColor(); handler.PlatformView.RefreshBackgroundColor = solidBrush.Color;
} }
} }
} }

View File

@@ -239,17 +239,17 @@ public partial class ShellHandler : ViewHandler<Shell, SkiaShell>
// Sync flyout colors // Sync flyout colors
if (shell.FlyoutBackgroundColor is Color flyoutBgColor) if (shell.FlyoutBackgroundColor is Color flyoutBgColor)
{ {
platformView.FlyoutBackgroundColor = flyoutBgColor.ToSKColor(); platformView.FlyoutBackgroundColor = flyoutBgColor;
} }
else if (shell.FlyoutBackground is SolidColorBrush flyoutBrush) else if (shell.FlyoutBackground is SolidColorBrush flyoutBrush)
{ {
platformView.FlyoutBackgroundColor = flyoutBrush.Color.ToSKColor(); platformView.FlyoutBackgroundColor = flyoutBrush.Color;
} }
// Sync nav bar colors // Sync nav bar colors
if (shell.BackgroundColor is Color bgColor) if (shell.BackgroundColor is Color bgColor)
{ {
platformView.NavBarBackgroundColor = bgColor.ToSKColor(); platformView.NavBarBackgroundColor = bgColor;
} }
} }
@@ -293,7 +293,7 @@ public partial class ShellHandler : ViewHandler<Shell, SkiaShell>
if (shell.FlyoutBackgroundColor is Color color) if (shell.FlyoutBackgroundColor is Color color)
{ {
handler.PlatformView.FlyoutBackgroundColor = color.ToSKColor(); handler.PlatformView.FlyoutBackgroundColor = color;
} }
} }
@@ -303,7 +303,7 @@ public partial class ShellHandler : ViewHandler<Shell, SkiaShell>
if (shell.FlyoutBackground is SolidColorBrush solidBrush) 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<Shell, SkiaShell>
if (shell.BackgroundColor is Color color) if (shell.BackgroundColor is Color color)
{ {
handler.PlatformView.NavBarBackgroundColor = color.ToSKColor(); handler.PlatformView.NavBarBackgroundColor = color;
} }
} }

View File

@@ -126,7 +126,7 @@ public partial class TabbedPageHandler : ViewHandler<ITabbedView, SkiaTabbedPage
if (tabbedView is TabbedPage tabbedPage && tabbedPage.BarBackgroundColor is Color color) if (tabbedView is TabbedPage tabbedPage && tabbedPage.BarBackgroundColor is Color color)
{ {
handler.PlatformView.TabBarBackgroundColor = color.ToSKColor(); handler.PlatformView.TabBarBackgroundColor = color;
} }
} }
@@ -137,7 +137,7 @@ public partial class TabbedPageHandler : ViewHandler<ITabbedView, SkiaTabbedPage
if (tabbedView is TabbedPage tabbedPage && tabbedPage.BarTextColor is Color color) if (tabbedView is TabbedPage tabbedPage && tabbedPage.BarTextColor is Color color)
{ {
// BarTextColor applies to unselected tabs // BarTextColor applies to unselected tabs
handler.PlatformView.UnselectedTabColor = color.ToSKColor(); handler.PlatformView.UnselectedTabColor = color;
} }
} }
@@ -147,8 +147,8 @@ public partial class TabbedPageHandler : ViewHandler<ITabbedView, SkiaTabbedPage
if (tabbedView is TabbedPage tabbedPage && tabbedPage.SelectedTabColor is Color color) if (tabbedView is TabbedPage tabbedPage && tabbedPage.SelectedTabColor is Color color)
{ {
handler.PlatformView.SelectedTabColor = color.ToSKColor(); handler.PlatformView.SelectedTabColor = color;
handler.PlatformView.IndicatorColor = color.ToSKColor(); handler.PlatformView.IndicatorColor = color;
} }
} }
@@ -158,7 +158,7 @@ public partial class TabbedPageHandler : ViewHandler<ITabbedView, SkiaTabbedPage
if (tabbedView is TabbedPage tabbedPage && tabbedPage.UnselectedTabColor is Color color) if (tabbedView is TabbedPage tabbedPage && tabbedPage.UnselectedTabColor is Color color)
{ {
handler.PlatformView.UnselectedTabColor = color.ToSKColor(); handler.PlatformView.UnselectedTabColor = color;
} }
} }
} }

View File

@@ -259,47 +259,37 @@ public class LinuxViewRenderer
// Flyout background color // Flyout background color
if (shell.FlyoutBackgroundColor != null && shell.FlyoutBackgroundColor != Colors.Transparent) if (shell.FlyoutBackgroundColor != null && shell.FlyoutBackgroundColor != Colors.Transparent)
{ {
var color = shell.FlyoutBackgroundColor; skiaShell.FlyoutBackgroundColor = shell.FlyoutBackgroundColor;
skiaShell.FlyoutBackgroundColor = new SKColor(
(byte)(color.Red * 255f),
(byte)(color.Green * 255f),
(byte)(color.Blue * 255f),
(byte)(color.Alpha * 255f));
Console.WriteLine($"[ApplyShellColors] FlyoutBackgroundColor from MAUI: {skiaShell.FlyoutBackgroundColor}"); Console.WriteLine($"[ApplyShellColors] FlyoutBackgroundColor from MAUI: {skiaShell.FlyoutBackgroundColor}");
} }
else else
{ {
skiaShell.FlyoutBackgroundColor = isDark skiaShell.FlyoutBackgroundColor = isDark
? new SKColor(30, 30, 30) ? Color.FromRgb(30, 30, 30)
: new SKColor(255, 255, 255); : Color.FromRgb(255, 255, 255);
Console.WriteLine($"[ApplyShellColors] Using default FlyoutBackgroundColor: {skiaShell.FlyoutBackgroundColor}"); Console.WriteLine($"[ApplyShellColors] Using default FlyoutBackgroundColor: {skiaShell.FlyoutBackgroundColor}");
} }
// Flyout text color // Flyout text color
skiaShell.FlyoutTextColor = isDark skiaShell.FlyoutTextColor = isDark
? new SKColor(224, 224, 224) ? Color.FromRgb(224, 224, 224)
: new SKColor(33, 33, 33); : Color.FromRgb(33, 33, 33);
Console.WriteLine($"[ApplyShellColors] FlyoutTextColor: {skiaShell.FlyoutTextColor}"); Console.WriteLine($"[ApplyShellColors] FlyoutTextColor: {skiaShell.FlyoutTextColor}");
// Content background color // Content background color
skiaShell.ContentBackgroundColor = isDark skiaShell.ContentBackgroundColor = isDark
? new SKColor(18, 18, 18) ? Color.FromRgb(18, 18, 18)
: new SKColor(250, 250, 250); : Color.FromRgb(250, 250, 250);
Console.WriteLine($"[ApplyShellColors] ContentBackgroundColor: {skiaShell.ContentBackgroundColor}"); Console.WriteLine($"[ApplyShellColors] ContentBackgroundColor: {skiaShell.ContentBackgroundColor}");
// NavBar background color // NavBar background color
if (shell.BackgroundColor != null && shell.BackgroundColor != Colors.Transparent) if (shell.BackgroundColor != null && shell.BackgroundColor != Colors.Transparent)
{ {
var color = shell.BackgroundColor; skiaShell.NavBarBackgroundColor = shell.BackgroundColor;
skiaShell.NavBarBackgroundColor = new SKColor(
(byte)(color.Red * 255f),
(byte)(color.Green * 255f),
(byte)(color.Blue * 255f),
(byte)(color.Alpha * 255f));
} }
else else
{ {
skiaShell.NavBarBackgroundColor = new SKColor(33, 150, 243); // Material blue skiaShell.NavBarBackgroundColor = Color.FromRgb(33, 150, 243); // Material blue
} }
} }

View File

@@ -393,7 +393,7 @@ public class LinuxWebView : SkiaView
// Draw a placeholder rectangle where the WebView will be overlaid // Draw a placeholder rectangle where the WebView will be overlaid
using var paint = new SKPaint using var paint = new SKPaint
{ {
Color = new SKColor(240, 240, 240), Color = SkiaTheme.MenuBackgroundSK,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
canvas.DrawRect(bounds, paint); canvas.DrawRect(bounds, paint);
@@ -401,7 +401,7 @@ public class LinuxWebView : SkiaView
// Draw border // Draw border
using var borderPaint = new SKPaint using var borderPaint = new SKPaint
{ {
Color = new SKColor(200, 200, 200), Color = SkiaTheme.BorderMediumSK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 1 StrokeWidth = 1
}; };
@@ -412,7 +412,7 @@ public class LinuxWebView : SkiaView
{ {
using var textPaint = new SKPaint using var textPaint = new SKPaint
{ {
Color = SKColors.Gray, Color = SkiaTheme.TextPlaceholderSK,
TextSize = 14, TextSize = 14,
IsAntialias = true IsAntialias = true
}; };

View File

@@ -21,11 +21,7 @@ public class SkiaActivityIndicator : SkiaView
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
#endregion #endregion

View File

@@ -22,17 +22,17 @@ public class SkiaAlertDialog : SkiaView
private bool _cancelHovered; private bool _cancelHovered;
private bool _acceptHovered; private bool _acceptHovered;
// Dialog styling // Dialog styling - using SkiaTheme for MAUI-compliant theming
private static readonly SKColor OverlayColor = new SKColor(0, 0, 0, 128); private static readonly SKColor OverlayColor = SkiaTheme.Overlay50SK;
private static readonly SKColor DialogBackground = SKColors.White; private static readonly SKColor DialogBackground = SkiaTheme.BackgroundWhiteSK;
private static readonly SKColor TitleColor = new SKColor(0x21, 0x21, 0x21); private static readonly SKColor TitleColor = SkiaTheme.TextPrimarySK;
private static readonly SKColor MessageColor = new SKColor(0x61, 0x61, 0x61); private static readonly SKColor MessageColor = SkiaTheme.TextSecondarySK;
private static readonly SKColor ButtonColor = new SKColor(0x21, 0x96, 0xF3); private static readonly SKColor ButtonColor = SkiaTheme.PrimarySK;
private static readonly SKColor ButtonHoverColor = new SKColor(0x19, 0x76, 0xD2); private static readonly SKColor ButtonHoverColor = SkiaTheme.PrimaryDarkSK;
private static readonly SKColor ButtonTextColor = SKColors.White; private static readonly SKColor ButtonTextColor = SkiaTheme.BackgroundWhiteSK;
private static readonly SKColor CancelButtonColor = new SKColor(0x9E, 0x9E, 0x9E); private static readonly SKColor CancelButtonColor = SkiaTheme.ButtonCancelSK;
private static readonly SKColor CancelButtonHoverColor = new SKColor(0x75, 0x75, 0x75); private static readonly SKColor CancelButtonHoverColor = SkiaTheme.ButtonCancelHoverSK;
private static readonly SKColor BorderColor = new SKColor(0xE0, 0xE0, 0xE0); private static readonly SKColor BorderColor = SkiaTheme.BorderLightSK;
private const float DialogWidth = 400; private const float DialogWidth = 400;
private const float DialogPadding = 24; private const float DialogPadding = 24;
@@ -80,7 +80,7 @@ public class SkiaAlertDialog : SkiaView
// Draw dialog shadow // Draw dialog shadow
using var shadowPaint = new SKPaint using var shadowPaint = new SKPaint
{ {
Color = new SKColor(0, 0, 0, 60), Color = SkiaTheme.Shadow25SK,
MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 8), MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 8),
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };

View File

@@ -234,11 +234,7 @@ public class SkiaBorder : SkiaLayoutView
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
#endregion #endregion

View File

@@ -49,11 +49,7 @@ public class SkiaBoxView : SkiaView
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
#endregion #endregion

View File

@@ -523,11 +523,7 @@ public class SkiaButton : SkiaView, IButtonController
private SKColor ToSKColor(Color? color) private SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
private float GetEffectiveCornerRadius() private float GetEffectiveCornerRadius()
@@ -554,11 +550,11 @@ public class SkiaButton : SkiaView, IButtonController
} }
else if (IsPressed) else if (IsPressed)
{ {
currentBgColor = hasBackground ? DarkenColor(bgColor, 0.2f) : new SKColor(0, 0, 0, 30); currentBgColor = hasBackground ? DarkenColor(bgColor, 0.2f) : SkiaTheme.Shadow20SK;
} }
else if (IsPointerOver) else if (IsPointerOver)
{ {
currentBgColor = hasBackground ? LightenColor(bgColor, 0.1f) : new SKColor(0, 0, 0, 15); currentBgColor = hasBackground ? LightenColor(bgColor, 0.1f) : SkiaTheme.Shadow10SK;
} }
else else
{ {
@@ -605,7 +601,7 @@ public class SkiaButton : SkiaView, IButtonController
{ {
using var focusPaint = new SKPaint using var focusPaint = new SKPaint
{ {
Color = new SKColor(33, 150, 243, 128), Color = SkiaTheme.PrimaryHalfSK,
IsAntialias = true, IsAntialias = true,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 2f StrokeWidth = 2f
@@ -645,7 +641,7 @@ public class SkiaButton : SkiaView, IButtonController
fontSize); fontSize);
// Prepare text color (null means use platform default: white for buttons) // Prepare text color (null means use platform default: white for buttons)
var textColor = TextColor != null ? ToSKColor(TextColor) : SKColors.White; var textColor = TextColor != null ? ToSKColor(TextColor) : SkiaTheme.BackgroundWhiteSK;
if (!IsEnabled) if (!IsEnabled)
{ {
textColor = textColor.WithAlpha(128); textColor = textColor.WithAlpha(128);
@@ -765,7 +761,7 @@ public class SkiaButton : SkiaView, IButtonController
if (!IsEnabled) if (!IsEnabled)
{ {
imagePaint.ColorFilter = SKColorFilter.CreateBlendMode( imagePaint.ColorFilter = SKColorFilter.CreateBlendMode(
new SKColor(128, 128, 128, 128), SKBlendMode.Modulate); SkiaTheme.ScrollbarThumbSK, SKBlendMode.Modulate);
} }
canvas.DrawBitmap(_loadedImage!, imageRect, imagePaint); canvas.DrawBitmap(_loadedImage!, imageRect, imagePaint);
@@ -781,7 +777,7 @@ public class SkiaButton : SkiaView, IButtonController
if (!IsEnabled) if (!IsEnabled)
{ {
imagePaint.ColorFilter = SKColorFilter.CreateBlendMode( imagePaint.ColorFilter = SKColorFilter.CreateBlendMode(
new SKColor(128, 128, 128, 128), SKBlendMode.Modulate); SkiaTheme.ScrollbarThumbSK, SKBlendMode.Modulate);
} }
canvas.DrawBitmap(_loadedImage!, imageRect, imagePaint); canvas.DrawBitmap(_loadedImage!, imageRect, imagePaint);
} }
@@ -815,7 +811,7 @@ public class SkiaButton : SkiaView, IButtonController
{ {
using var shadowPaint = new SKPaint using var shadowPaint = new SKPaint
{ {
Color = new SKColor(0, 0, 0, 50), Color = SkiaTheme.Shadow20SK,
IsAntialias = true, IsAntialias = true,
MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 4f) MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 4f)
}; };

View File

@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements. // Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Maui.Graphics;
using SkiaSharp; using SkiaSharp;
namespace Microsoft.Maui.Platform; namespace Microsoft.Maui.Platform;
@@ -28,6 +29,12 @@ public class SkiaCarouselView : SkiaLayoutView
private DateTime _animationStartTime; private DateTime _animationStartTime;
private const float AnimationDurationMs = 300f; private const float AnimationDurationMs = 300f;
// Indicator color fields
private Color _indicatorColor = Color.FromRgb(180, 180, 180);
private Color _selectedIndicatorColor = Color.FromRgb(33, 150, 243);
private SKColor _indicatorColorSK = SkiaTheme.IndicatorUnselectedSK;
private SKColor _selectedIndicatorColorSK = SkiaTheme.PrimarySK;
/// <summary> /// <summary>
/// Gets or sets the current position (item index). /// Gets or sets the current position (item index).
/// </summary> /// </summary>
@@ -79,12 +86,30 @@ public class SkiaCarouselView : SkiaLayoutView
/// <summary> /// <summary>
/// Gets or sets the indicator color. /// Gets or sets the indicator color.
/// </summary> /// </summary>
public SKColor IndicatorColor { get; set; } = new SKColor(180, 180, 180); public Color IndicatorColor
{
get => _indicatorColor;
set
{
_indicatorColor = value;
_indicatorColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Gets or sets the selected indicator color. /// Gets or sets the selected indicator color.
/// </summary> /// </summary>
public SKColor SelectedIndicatorColor { get; set; } = new SKColor(33, 150, 243); public Color SelectedIndicatorColor
{
get => _selectedIndicatorColor;
set
{
_selectedIndicatorColor = value;
_selectedIndicatorColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Event raised when position changes. /// Event raised when position changes.
@@ -279,14 +304,14 @@ public class SkiaCarouselView : SkiaLayoutView
using var normalPaint = new SKPaint using var normalPaint = new SKPaint
{ {
Color = IndicatorColor, Color = _indicatorColorSK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };
using var selectedPaint = new SKPaint using var selectedPaint = new SKPaint
{ {
Color = SelectedIndicatorColor, Color = _selectedIndicatorColorSK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };

View File

@@ -22,11 +22,7 @@ public class SkiaCheckBox : SkiaView
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
#endregion #endregion

View File

@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.Maui.Controls; using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using SkiaSharp; using SkiaSharp;
namespace Microsoft.Maui.Platform; namespace Microsoft.Maui.Platform;
@@ -91,27 +92,27 @@ public class SkiaCollectionView : SkiaItemsView
public static readonly BindableProperty SelectionColorProperty = BindableProperty.Create( public static readonly BindableProperty SelectionColorProperty = BindableProperty.Create(
nameof(SelectionColor), nameof(SelectionColor),
typeof(SKColor), typeof(Color),
typeof(SkiaCollectionView), typeof(SkiaCollectionView),
new SKColor(33, 150, 243, 89), Color.FromRgba(33, 150, 243, 89),
BindingMode.TwoWay, 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( public static readonly BindableProperty HeaderBackgroundColorProperty = BindableProperty.Create(
nameof(HeaderBackgroundColor), nameof(HeaderBackgroundColor),
typeof(SKColor), typeof(Color),
typeof(SkiaCollectionView), typeof(SkiaCollectionView),
new SKColor(245, 245, 245), Color.FromRgb(245, 245, 245),
BindingMode.TwoWay, 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( public static readonly BindableProperty FooterBackgroundColorProperty = BindableProperty.Create(
nameof(FooterBackgroundColor), nameof(FooterBackgroundColor),
typeof(SKColor), typeof(Color),
typeof(SkiaCollectionView), typeof(SkiaCollectionView),
new SKColor(245, 245, 245), Color.FromRgb(245, 245, 245),
BindingMode.TwoWay, BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaCollectionView)b).Invalidate()); propertyChanged: (b, o, n) => ((SkiaCollectionView)b).OnFooterBackgroundColorChanged((Color?)n));
#endregion #endregion
@@ -120,6 +121,11 @@ public class SkiaCollectionView : SkiaItemsView
private bool _isSelectingItem; private bool _isSelectingItem;
private bool _heightsChangedDuringDraw; 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 public SkiaSelectionMode SelectionMode
{ {
get => (SkiaSelectionMode)GetValue(SelectionModeProperty); get => (SkiaSelectionMode)GetValue(SelectionModeProperty);
@@ -192,24 +198,33 @@ public class SkiaCollectionView : SkiaItemsView
set => SetValue(FooterHeightProperty, value); set => SetValue(FooterHeightProperty, value);
} }
public SKColor SelectionColor public Color SelectionColor
{ {
get => (SKColor)GetValue(SelectionColorProperty); get => (Color)GetValue(SelectionColorProperty);
set => SetValue(SelectionColorProperty, value); set => SetValue(SelectionColorProperty, value);
} }
public SKColor HeaderBackgroundColor /// <summary>Gets the SKColor for rendering selection highlight.</summary>
public SKColor SelectionColorSK => _selectionColorSK;
public Color HeaderBackgroundColor
{ {
get => (SKColor)GetValue(HeaderBackgroundColorProperty); get => (Color)GetValue(HeaderBackgroundColorProperty);
set => SetValue(HeaderBackgroundColorProperty, value); set => SetValue(HeaderBackgroundColorProperty, value);
} }
public SKColor FooterBackgroundColor /// <summary>Gets the SKColor for rendering header background.</summary>
public SKColor HeaderBackgroundColorSK => _headerBackgroundColorSK;
public Color FooterBackgroundColor
{ {
get => (SKColor)GetValue(FooterBackgroundColorProperty); get => (Color)GetValue(FooterBackgroundColorProperty);
set => SetValue(FooterBackgroundColorProperty, value); set => SetValue(FooterBackgroundColorProperty, value);
} }
/// <summary>Gets the SKColor for rendering footer background.</summary>
public SKColor FooterBackgroundColorSK => _footerBackgroundColorSK;
public event EventHandler<CollectionSelectionChangedEventArgs>? SelectionChanged; public event EventHandler<CollectionSelectionChangedEventArgs>? SelectionChanged;
protected override void RefreshItems() protected override void RefreshItems()
@@ -266,6 +281,24 @@ public class SkiaCollectionView : SkiaItemsView
Invalidate(); 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) private void SelectItem(object item)
{ {
if (SelectionMode == SkiaSelectionMode.None) if (SelectionMode == SkiaSelectionMode.None)
@@ -365,7 +398,7 @@ public class SkiaCollectionView : SkiaItemsView
if (Orientation == ItemsLayoutOrientation.Vertical && SpanCount == 1) if (Orientation == ItemsLayoutOrientation.Vertical && SpanCount == 1)
{ {
paint.Color = new SKColor(224, 224, 224); paint.Color = SkiaTheme.Gray300SK;
paint.Style = SKPaintStyle.Stroke; paint.Style = SKPaintStyle.Stroke;
paint.StrokeWidth = 1f; paint.StrokeWidth = 1f;
canvas.DrawLine(bounds.Left, bounds.Bottom, bounds.Right, bounds.Bottom, paint); canvas.DrawLine(bounds.Left, bounds.Bottom, bounds.Right, bounds.Bottom, paint);
@@ -409,7 +442,7 @@ public class SkiaCollectionView : SkiaItemsView
if (isSelected) if (isSelected)
{ {
paint.Color = SelectionColor; paint.Color = SelectionColorSK;
paint.Style = SKPaintStyle.Fill; paint.Style = SKPaintStyle.Fill;
canvas.DrawRoundRect(actualBounds, 12f, 12f, paint); canvas.DrawRoundRect(actualBounds, 12f, 12f, paint);
} }
@@ -433,13 +466,13 @@ public class SkiaCollectionView : SkiaItemsView
return; return;
} }
paint.Color = SKColors.Black; paint.Color = SkiaTheme.TextPrimarySK;
paint.Style = SKPaintStyle.Fill; paint.Style = SKPaintStyle.Fill;
using var font = new SKFont(SKTypeface.Default, 14f, 1f, 0f); using var font = new SKFont(SKTypeface.Default, 14f, 1f, 0f);
using var textPaint = new SKPaint(font) using var textPaint = new SKPaint(font)
{ {
Color = SKColors.Black, Color = SkiaTheme.TextPrimarySK,
IsAntialias = true IsAntialias = true
}; };
@@ -461,7 +494,7 @@ public class SkiaCollectionView : SkiaItemsView
{ {
using var paint = new SKPaint using var paint = new SKPaint
{ {
Color = new SKColor(33, 150, 243), Color = SkiaTheme.PrimarySK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 2f, StrokeWidth = 2f,
IsAntialias = true, IsAntialias = true,
@@ -627,7 +660,7 @@ public class SkiaCollectionView : SkiaItemsView
{ {
using var cellBgPaint = new SKPaint 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 Style = SKPaintStyle.Fill
}; };
canvas.DrawRoundRect(new SKRoundRect(cellRect, 4f), cellBgPaint); canvas.DrawRoundRect(new SKRoundRect(cellRect, 4f), cellBgPaint);
@@ -657,7 +690,7 @@ public class SkiaCollectionView : SkiaItemsView
using var trackPaint = new SKPaint using var trackPaint = new SKPaint
{ {
Color = new SKColor(0, 0, 0, 20), Color = SkiaTheme.Shadow10SK,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
canvas.DrawRoundRect(new SKRoundRect(trackRect, 3f), trackPaint); canvas.DrawRoundRect(new SKRoundRect(trackRect, 3f), trackPaint);
@@ -673,7 +706,7 @@ public class SkiaCollectionView : SkiaItemsView
using var thumbPaint = new SKPaint using var thumbPaint = new SKPaint
{ {
Color = new SKColor(100, 100, 100, 180), Color = SkiaTheme.ScrollbarThumbSK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };
@@ -690,7 +723,7 @@ public class SkiaCollectionView : SkiaItemsView
{ {
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = HeaderBackgroundColor, Color = HeaderBackgroundColorSK,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
canvas.DrawRect(bounds, bgPaint); canvas.DrawRect(bounds, bgPaint);
@@ -701,7 +734,7 @@ public class SkiaCollectionView : SkiaItemsView
using var font = new SKFont(SKTypeface.Default, 16f, 1f, 0f); using var font = new SKFont(SKTypeface.Default, 16f, 1f, 0f);
using var textPaint = new SKPaint(font) using var textPaint = new SKPaint(font)
{ {
Color = SKColors.Black, Color = SkiaTheme.TextPrimarySK,
IsAntialias = true IsAntialias = true
}; };
@@ -715,7 +748,7 @@ public class SkiaCollectionView : SkiaItemsView
using var sepPaint = new SKPaint using var sepPaint = new SKPaint
{ {
Color = new SKColor(224, 224, 224), Color = SkiaTheme.Gray300SK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 1f StrokeWidth = 1f
}; };
@@ -726,14 +759,14 @@ public class SkiaCollectionView : SkiaItemsView
{ {
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = FooterBackgroundColor, Color = FooterBackgroundColorSK,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
canvas.DrawRect(bounds, bgPaint); canvas.DrawRect(bounds, bgPaint);
using var sepPaint = new SKPaint using var sepPaint = new SKPaint
{ {
Color = new SKColor(224, 224, 224), Color = SkiaTheme.Gray300SK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 1f StrokeWidth = 1f
}; };
@@ -745,7 +778,7 @@ public class SkiaCollectionView : SkiaItemsView
using var font = new SKFont(SKTypeface.Default, 14f, 1f, 0f); using var font = new SKFont(SKTypeface.Default, 14f, 1f, 0f);
using var textPaint = new SKPaint(font) using var textPaint = new SKPaint(font)
{ {
Color = new SKColor(128, 128, 128), Color = SkiaTheme.TextPlaceholderSK,
IsAntialias = true IsAntialias = true
}; };

View File

@@ -12,15 +12,15 @@ public class SkiaContextMenu : SkiaView
private int _hoveredIndex = -1; private int _hoveredIndex = -1;
private SKRect[] _itemBounds = Array.Empty<SKRect>(); private SKRect[] _itemBounds = Array.Empty<SKRect>();
private static readonly SKColor MenuBackground = new SKColor(255, 255, 255); private static readonly SKColor MenuBackground = SkiaTheme.BackgroundWhiteSK;
private static readonly SKColor MenuBackgroundDark = new SKColor(48, 48, 48); private static readonly SKColor MenuBackgroundDark = SkiaTheme.DarkBackgroundSK;
private static readonly SKColor ItemHoverBackground = new SKColor(227, 242, 253); private static readonly SKColor ItemHoverBackground = SkiaTheme.PrimarySelectionSK;
private static readonly SKColor ItemHoverBackgroundDark = new SKColor(80, 80, 80); private static readonly SKColor ItemHoverBackgroundDark = SkiaTheme.DarkHoverSK;
private static readonly SKColor ItemTextColor = new SKColor(33, 33, 33); private static readonly SKColor ItemTextColor = SkiaTheme.TextPrimarySK;
private static readonly SKColor ItemTextColorDark = new SKColor(224, 224, 224); private static readonly SKColor ItemTextColorDark = SkiaTheme.DarkTextSK;
private static readonly SKColor DisabledTextColor = new SKColor(158, 158, 158); private static readonly SKColor DisabledTextColor = SkiaTheme.TextDisabledSK;
private static readonly SKColor SeparatorColor = new SKColor(224, 224, 224); private static readonly SKColor SeparatorColor = SkiaTheme.Gray300SK;
private static readonly SKColor ShadowColor = new SKColor(0, 0, 0, 40); private static readonly SKColor ShadowColor = SkiaTheme.Shadow25SK;
private const float MenuPadding = 4f; private const float MenuPadding = 4f;
private const float ItemHeight = 32f; private const float ItemHeight = 32f;

View File

@@ -235,11 +235,7 @@ public class SkiaDatePicker : SkiaView
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
/// <summary> /// <summary>
@@ -248,11 +244,7 @@ public class SkiaDatePicker : SkiaView
private static SKColor ToSKColorWithAlpha(Color? color, byte alpha) private static SKColor ToSKColorWithAlpha(Color? color, byte alpha)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor().WithAlpha(alpha);
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
alpha);
} }
#endregion #endregion
@@ -318,7 +310,7 @@ public class SkiaDatePicker : SkiaView
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = IsEnabled ? GetEffectiveBackgroundColor() : new SKColor(245, 245, 245), Color = IsEnabled ? GetEffectiveBackgroundColor() : SkiaTheme.Gray100SK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };
@@ -410,7 +402,7 @@ public class SkiaDatePicker : SkiaView
using var shadowPaint = new SKPaint using var shadowPaint = new SKPaint
{ {
Color = new SKColor(0, 0, 0, 40), Color = SkiaTheme.Shadow25SK,
MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 4f), MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 4f),
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
@@ -457,7 +449,7 @@ public class SkiaDatePicker : SkiaView
using var font = new SKFont(SKTypeface.Default, 16f, 1f, 0f); using var font = new SKFont(SKTypeface.Default, 16f, 1f, 0f);
using var textPaint = new SKPaint(font) using var textPaint = new SKPaint(font)
{ {
Color = SKColors.White, Color = SkiaTheme.BackgroundWhiteSK,
IsAntialias = true IsAntialias = true
}; };
@@ -468,7 +460,7 @@ public class SkiaDatePicker : SkiaView
using var arrowPaint = new SKPaint using var arrowPaint = new SKPaint
{ {
Color = SKColors.White, Color = SkiaTheme.BackgroundWhiteSK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 2f, StrokeWidth = 2f,
IsAntialias = true, IsAntialias = true,
@@ -496,7 +488,7 @@ public class SkiaDatePicker : SkiaView
using var font = new SKFont(SKTypeface.Default, 12f, 1f, 0f); using var font = new SKFont(SKTypeface.Default, 12f, 1f, 0f);
using var paint = new SKPaint(font) using var paint = new SKPaint(font)
{ {
Color = new SKColor(128, 128, 128), Color = SkiaTheme.TextPlaceholderSK,
IsAntialias = true 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); 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(); string dayText = day.ToString();
SKRect dayTextBounds = default; SKRect dayTextBounds = default;
textPaint.MeasureText(dayText, ref dayTextBounds); textPaint.MeasureText(dayText, ref dayTextBounds);

View File

@@ -315,11 +315,7 @@ public class SkiaEditor : SkiaView, IInputContext
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
/// <summary> /// <summary>
@@ -327,7 +323,7 @@ public class SkiaEditor : SkiaView, IInputContext
/// </summary> /// </summary>
private SKColor GetEffectiveTextColor() private SKColor GetEffectiveTextColor()
{ {
return TextColor != null ? ToSKColor(TextColor) : SKColors.Black; return TextColor != null ? ToSKColor(TextColor) : SkiaTheme.TextPrimarySK;
} }
/// <summary> /// <summary>
@@ -335,7 +331,7 @@ public class SkiaEditor : SkiaView, IInputContext
/// </summary> /// </summary>
private SKColor GetEffectivePlaceholderColor() private SKColor GetEffectivePlaceholderColor()
{ {
return PlaceholderColor != null ? ToSKColor(PlaceholderColor) : new SKColor(0x80, 0x80, 0x80); return PlaceholderColor != null ? ToSKColor(PlaceholderColor) : SkiaTheme.TextPlaceholderSK;
} }
/// <summary> /// <summary>
@@ -886,7 +882,7 @@ public class SkiaEditor : SkiaView, IInputContext
// Draw background // Draw background
var bgColor = EditorBackgroundColor != null ? ToSKColor(EditorBackgroundColor) : var bgColor = EditorBackgroundColor != null ? ToSKColor(EditorBackgroundColor) :
(IsEnabled ? SKColors.White : new SKColor(0xF5, 0xF5, 0xF5)); (IsEnabled ? SkiaTheme.BackgroundWhiteSK : SkiaTheme.Gray100SK);
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = bgColor, Color = bgColor,
@@ -1052,7 +1048,7 @@ public class SkiaEditor : SkiaView, IInputContext
using var paint = new SKPaint using var paint = new SKPaint
{ {
Color = new SKColor(0, 0, 0, 60), Color = SkiaTheme.Shadow25SK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };

View File

@@ -777,11 +777,7 @@ public class SkiaEntry : SkiaView, IInputContext
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
/// <summary> /// <summary>
@@ -789,7 +785,7 @@ public class SkiaEntry : SkiaView, IInputContext
/// </summary> /// </summary>
private SKColor GetEffectiveTextColor() private SKColor GetEffectiveTextColor()
{ {
return TextColor != null ? ToSKColor(TextColor) : SKColors.Black; return TextColor != null ? ToSKColor(TextColor) : SkiaTheme.TextPrimarySK;
} }
/// <summary> /// <summary>
@@ -797,7 +793,7 @@ public class SkiaEntry : SkiaView, IInputContext
/// </summary> /// </summary>
private SKColor GetEffectivePlaceholderColor() private SKColor GetEffectivePlaceholderColor()
{ {
return PlaceholderColor != null ? ToSKColor(PlaceholderColor) : new SKColor(0x9E, 0x9E, 0x9E); return PlaceholderColor != null ? ToSKColor(PlaceholderColor) : SkiaTheme.TextDisabledSK;
} }
/// <summary> /// <summary>
@@ -1018,7 +1014,7 @@ public class SkiaEntry : SkiaView, IInputContext
// Draw circle background // Draw circle background
using var circlePaint = new SKPaint using var circlePaint = new SKPaint
{ {
Color = new SKColor(0xBD, 0xBD, 0xBD), Color = SkiaTheme.Gray400SK,
IsAntialias = true, IsAntialias = true,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
@@ -1027,7 +1023,7 @@ public class SkiaEntry : SkiaView, IInputContext
// Draw X // Draw X
using var xPaint = new SKPaint using var xPaint = new SKPaint
{ {
Color = SKColors.White, Color = SkiaTheme.BackgroundWhiteSK,
IsAntialias = true, IsAntialias = true,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 2, StrokeWidth = 2,

View File

@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements. // Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Maui.Graphics;
using SkiaSharp; using SkiaSharp;
namespace Microsoft.Maui.Platform; namespace Microsoft.Maui.Platform;
@@ -22,6 +23,10 @@ public class SkiaFlyoutPage : SkiaLayoutView
private float _dragStartX; private float _dragStartX;
private float _dragCurrentX; private float _dragCurrentX;
// ScrimColor backing fields
private SKColor _scrimColorSK = SkiaTheme.Overlay40SK;
private Color _scrimColor = SkiaTheme.Overlay40;
/// <summary> /// <summary>
/// Gets or sets the flyout content (menu). /// Gets or sets the flyout content (menu).
/// </summary> /// </summary>
@@ -128,7 +133,16 @@ public class SkiaFlyoutPage : SkiaLayoutView
/// <summary> /// <summary>
/// Background color of the scrim when flyout is open. /// Background color of the scrim when flyout is open.
/// </summary> /// </summary>
public SKColor ScrimColor { get; set; } = new SKColor(0, 0, 0, 100); public Color ScrimColor
{
get => _scrimColor;
set
{
_scrimColor = value;
_scrimColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Shadow width for the flyout. /// Shadow width for the flyout.
@@ -194,7 +208,7 @@ public class SkiaFlyoutPage : SkiaLayoutView
// Draw scrim (semi-transparent overlay) // Draw scrim (semi-transparent overlay)
using var scrimPaint = new SKPaint using var scrimPaint = new SKPaint
{ {
Color = ScrimColor.WithAlpha((byte)(ScrimColor.Alpha * _flyoutAnimationProgress)), Color = _scrimColorSK.WithAlpha((byte)(_scrimColorSK.Alpha * _flyoutAnimationProgress)),
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
canvas.DrawRect(Bounds, scrimPaint); canvas.DrawRect(Bounds, scrimPaint);
@@ -228,7 +242,7 @@ public class SkiaFlyoutPage : SkiaLayoutView
Shader = SKShader.CreateLinearGradient( Shader = SKShader.CreateLinearGradient(
new SKPoint(shadowRect.Left, shadowRect.MidY), new SKPoint(shadowRect.Left, shadowRect.MidY),
new SKPoint(shadowRect.Right, 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, null,
SKShaderTileMode.Clamp) SKShaderTileMode.Clamp)
}; };

View File

@@ -177,15 +177,12 @@ public class SkiaImage : SkiaView
/// <summary> /// <summary>
/// Converts a MAUI Color to SkiaSharp SKColor. /// Converts a MAUI Color to SkiaSharp SKColor.
/// Uses the ToSKColor() extension from ColorExtensions for MAUI-compliant theming.
/// </summary> /// </summary>
private static SKColor ToSKColor(Color color) private static SKColor ToSKColor(Color color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
#endregion #endregion

View File

@@ -28,14 +28,14 @@ public class SkiaImageButton : SkiaView
#endregion #endregion
#region SKColor Helper #region SKColor Helper
/// <summary>
/// Converts a MAUI Color to SkiaSharp SKColor.
/// Uses the ToSKColor() extension from ColorExtensions for MAUI-compliant theming.
/// </summary>
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
#endregion #endregion
@@ -343,7 +343,7 @@ public class SkiaImageButton : SkiaView
{ {
using var focusPaint = new SKPaint using var focusPaint = new SKPaint
{ {
Color = new SKColor(0x00, 0x00, 0x00, 0x40), Color = SkiaTheme.Shadow25SK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 2, StrokeWidth = 2,
IsAntialias = true IsAntialias = true

View File

@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements. // Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Maui.Graphics;
using SkiaSharp; using SkiaSharp;
namespace Microsoft.Maui.Platform; namespace Microsoft.Maui.Platform;
@@ -14,6 +15,16 @@ public class SkiaIndicatorView : SkiaView
private int _count = 0; private int _count = 0;
private int _position = 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);
/// <summary> /// <summary>
/// Gets or sets the number of indicators to display. /// Gets or sets the number of indicators to display.
/// </summary> /// </summary>
@@ -55,12 +66,30 @@ public class SkiaIndicatorView : SkiaView
/// <summary> /// <summary>
/// Gets or sets the indicator color. /// Gets or sets the indicator color.
/// </summary> /// </summary>
public SKColor IndicatorColor { get; set; } = new SKColor(180, 180, 180); public Color IndicatorColor
{
get => _indicatorColor;
set
{
_indicatorColor = value;
_indicatorColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Gets or sets the selected indicator color. /// Gets or sets the selected indicator color.
/// </summary> /// </summary>
public SKColor SelectedIndicatorColor { get; set; } = new SKColor(33, 150, 243); public Color SelectedIndicatorColor
{
get => _selectedIndicatorColor;
set
{
_selectedIndicatorColor = value;
_selectedIndicatorColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Gets or sets the indicator size. /// Gets or sets the indicator size.
@@ -90,7 +119,16 @@ public class SkiaIndicatorView : SkiaView
/// <summary> /// <summary>
/// Gets or sets the border color. /// Gets or sets the border color.
/// </summary> /// </summary>
public SKColor BorderColor { get; set; } = new SKColor(100, 100, 100); public Color BorderColor
{
get => _borderColor;
set
{
_borderColor = value;
_borderColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Gets or sets the border width. /// Gets or sets the border width.
@@ -150,21 +188,21 @@ public class SkiaIndicatorView : SkiaView
using var normalPaint = new SKPaint using var normalPaint = new SKPaint
{ {
Color = IndicatorColor, Color = _indicatorColorSK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };
using var selectedPaint = new SKPaint using var selectedPaint = new SKPaint
{ {
Color = SelectedIndicatorColor, Color = _selectedIndicatorColorSK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };
using var borderPaint = new SKPaint using var borderPaint = new SKPaint
{ {
Color = BorderColor, Color = _borderColorSK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = BorderWidth, StrokeWidth = BorderWidth,
IsAntialias = true IsAntialias = true

View File

@@ -35,8 +35,8 @@ public class SkiaItemsView : SkiaView
// Scroll bar // Scroll bar
private bool _showVerticalScrollBar = true; private bool _showVerticalScrollBar = true;
private float _scrollBarWidth = 8; private float _scrollBarWidth = 8;
private SKColor _scrollBarColor = new SKColor(128, 128, 128, 128); private Color _scrollBarColor = SkiaTheme.ScrollbarThumb;
private SKColor _scrollBarTrackColor = new SKColor(200, 200, 200, 64); private Color _scrollBarTrackColor = SkiaTheme.ScrollbarTrack;
public IEnumerable? ItemsSource public IEnumerable? ItemsSource
{ {
@@ -261,7 +261,7 @@ public class SkiaItemsView : SkiaView
// Draw selection highlight // Draw selection highlight
if (index == SelectedIndex) if (index == SelectedIndex)
{ {
paint.Color = new SKColor(0x21, 0x96, 0xF3, 0x59); // Light blue with 35% opacity paint.Color = SkiaTheme.PrimarySelectionSK;
paint.Style = SKPaintStyle.Fill; paint.Style = SKPaintStyle.Fill;
canvas.DrawRect(bounds, paint); canvas.DrawRect(bounds, paint);
} }
@@ -312,7 +312,7 @@ public class SkiaItemsView : SkiaView
} }
// Draw separator // Draw separator
paint.Color = new SKColor(0xE0, 0xE0, 0xE0); paint.Color = SkiaTheme.Gray300SK;
paint.Style = SKPaintStyle.Stroke; paint.Style = SKPaintStyle.Stroke;
paint.StrokeWidth = 1; paint.StrokeWidth = 1;
canvas.DrawLine(bounds.Left, bounds.Bottom, bounds.Right, bounds.Bottom, paint); canvas.DrawLine(bounds.Left, bounds.Bottom, bounds.Right, bounds.Bottom, paint);
@@ -325,13 +325,13 @@ public class SkiaItemsView : SkiaView
} }
// Default rendering - just show ToString // Default rendering - just show ToString
paint.Color = SKColors.Black; paint.Color = SkiaTheme.TextPrimarySK;
paint.Style = SKPaintStyle.Fill; paint.Style = SKPaintStyle.Fill;
using var font = new SKFont(SKTypeface.Default, 14); using var font = new SKFont(SKTypeface.Default, 14);
using var textPaint = new SKPaint(font) using var textPaint = new SKPaint(font)
{ {
Color = SKColors.Black, Color = SkiaTheme.TextPrimarySK,
IsAntialias = true IsAntialias = true
}; };
@@ -348,14 +348,14 @@ public class SkiaItemsView : SkiaView
{ {
using var paint = new SKPaint using var paint = new SKPaint
{ {
Color = new SKColor(0x80, 0x80, 0x80), Color = SkiaTheme.TextPlaceholderSK,
IsAntialias = true IsAntialias = true
}; };
using var font = new SKFont(SKTypeface.Default, 16); using var font = new SKFont(SKTypeface.Default, 16);
using var textPaint = new SKPaint(font) using var textPaint = new SKPaint(font)
{ {
Color = new SKColor(0x80, 0x80, 0x80), Color = SkiaTheme.TextPlaceholderSK,
IsAntialias = true IsAntialias = true
}; };
@@ -379,7 +379,7 @@ public class SkiaItemsView : SkiaView
// Draw track // Draw track
using var trackPaint = new SKPaint using var trackPaint = new SKPaint
{ {
Color = _scrollBarTrackColor, Color = SkiaTheme.ScrollbarTrackSK,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
canvas.DrawRect(trackRect, trackPaint); canvas.DrawRect(trackRect, trackPaint);
@@ -399,7 +399,7 @@ public class SkiaItemsView : SkiaView
// Draw thumb // Draw thumb
using var thumbPaint = new SKPaint using var thumbPaint = new SKPaint
{ {
Color = _scrollBarColor, Color = SkiaTheme.ScrollbarThumbSK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };

View File

@@ -608,12 +608,8 @@ public class SkiaLabel : SkiaView
private SKColor ToSKColor(Color? color) private SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Black; if (color == null) return SkiaTheme.TextPrimarySK;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
private string GetDisplayText() private string GetDisplayText()
@@ -791,7 +787,7 @@ public class SkiaLabel : SkiaView
using var selectionPaint = new SKPaint using var selectionPaint = new SKPaint
{ {
Color = new SKColor(0x21, 0x96, 0xF3, 0x60), // Semi-transparent blue Color = SkiaTheme.PrimaryLightSK,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };

View File

@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements. // Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Maui.Graphics;
using SkiaSharp; using SkiaSharp;
namespace Microsoft.Maui.Platform; namespace Microsoft.Maui.Platform;
@@ -15,30 +16,78 @@ public class SkiaMenuBar : SkiaView
private int _openIndex = -1; private int _openIndex = -1;
private SkiaMenuFlyout? _openFlyout; 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);
/// <summary> /// <summary>
/// Gets the menu bar items. /// Gets the menu bar items.
/// </summary> /// </summary>
public IList<MenuBarItem> Items => _items; public IList<MenuBarItem> Items => _items;
/// <summary> /// <summary>
/// Gets or sets the background color. /// Gets or sets the menu bar background color.
/// </summary> /// </summary>
public SKColor BackgroundColor { get; set; } = new SKColor(240, 240, 240); public new Color MenuBackgroundColor
{
get => _menuBackgroundColor;
set
{
_menuBackgroundColor = value;
_menuBackgroundColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Gets or sets the text color. /// Gets or sets the text color.
/// </summary> /// </summary>
public SKColor TextColor { get; set; } = new SKColor(33, 33, 33); public Color TextColor
{
get => _textColor;
set
{
_textColor = value;
_textColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Gets or sets the hover background color. /// Gets or sets the hover background color.
/// </summary> /// </summary>
public SKColor HoverBackgroundColor { get; set; } = new SKColor(220, 220, 220); public Color HoverBackgroundColor
{
get => _hoverBackgroundColor;
set
{
_hoverBackgroundColor = value;
_hoverBackgroundColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Gets or sets the active background color. /// Gets or sets the active background color.
/// </summary> /// </summary>
public SKColor ActiveBackgroundColor { get; set; } = new SKColor(200, 200, 200); public Color ActiveBackgroundColor
{
get => _activeBackgroundColor;
set
{
_activeBackgroundColor = value;
_activeBackgroundColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Gets or sets the bar height. /// Gets or sets the bar height.
@@ -67,7 +116,7 @@ public class SkiaMenuBar : SkiaView
// Draw background // Draw background
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = BackgroundColor, Color = _menuBackgroundColorSK,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
canvas.DrawRect(Bounds, bgPaint); canvas.DrawRect(Bounds, bgPaint);
@@ -75,7 +124,7 @@ public class SkiaMenuBar : SkiaView
// Draw bottom border // Draw bottom border
using var borderPaint = new SKPaint using var borderPaint = new SKPaint
{ {
Color = new SKColor(200, 200, 200), Color = SkiaTheme.BorderMediumSK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 1 StrokeWidth = 1
}; };
@@ -84,7 +133,7 @@ public class SkiaMenuBar : SkiaView
// Draw menu items // Draw menu items
using var textPaint = new SKPaint using var textPaint = new SKPaint
{ {
Color = TextColor, Color = _textColorSK,
TextSize = FontSize, TextSize = FontSize,
IsAntialias = true IsAntialias = true
}; };
@@ -103,12 +152,12 @@ public class SkiaMenuBar : SkiaView
// Draw item background // Draw item background
if (i == _openIndex) 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); canvas.DrawRect(itemBounds, activePaint);
} }
else if (i == _hoveredIndex) 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); canvas.DrawRect(itemBounds, hoverPaint);
} }

View File

@@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Maui.Graphics;
using SkiaSharp; using SkiaSharp;
namespace Microsoft.Maui.Platform; namespace Microsoft.Maui.Platform;
@@ -12,19 +13,73 @@ public class SkiaMenuFlyout : SkiaView
private int _hoveredIndex = -1; private int _hoveredIndex = -1;
private SKRect _bounds; 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<MenuItem> Items { get; set; } = new List<MenuItem>(); public List<MenuItem> Items { get; set; } = new List<MenuItem>();
public SKPoint Position { get; set; } 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; public float FontSize { get; set; } = 13f;
@@ -77,14 +132,14 @@ public class SkiaMenuFlyout : SkiaView
// Draw shadow // Draw shadow
using var shadowPaint = new SKPaint 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); canvas.DrawRect(_bounds, shadowPaint);
// Draw background // Draw background
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = BackgroundColor, Color = _menuBackgroundColorSK,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
canvas.DrawRect(_bounds, bgPaint); canvas.DrawRect(_bounds, bgPaint);
@@ -92,7 +147,7 @@ public class SkiaMenuFlyout : SkiaView
// Draw border // Draw border
using var borderPaint = new SKPaint using var borderPaint = new SKPaint
{ {
Color = new SKColor(200, 200, 200), Color = SkiaTheme.BorderMediumSK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 1f StrokeWidth = 1f
}; };
@@ -100,7 +155,7 @@ public class SkiaMenuFlyout : SkiaView
// Draw items // Draw items
float y = _bounds.Top; float y = _bounds.Top;
textPaint.Color = TextColor; textPaint.Color = _textColorSK;
for (int i = 0; i < Items.Count; i++) for (int i = 0; i < Items.Count; i++)
{ {
@@ -111,7 +166,7 @@ public class SkiaMenuFlyout : SkiaView
float separatorY = y + SeparatorHeight / 2f; float separatorY = y + SeparatorHeight / 2f;
using var sepPaint = new SKPaint using var sepPaint = new SKPaint
{ {
Color = SeparatorColor, Color = _separatorColorSK,
StrokeWidth = 1f StrokeWidth = 1f
}; };
canvas.DrawLine(_bounds.Left + 8f, separatorY, _bounds.Right - 8f, separatorY, sepPaint); canvas.DrawLine(_bounds.Left + 8f, separatorY, _bounds.Right - 8f, separatorY, sepPaint);
@@ -126,7 +181,7 @@ public class SkiaMenuFlyout : SkiaView
{ {
using var hoverPaint = new SKPaint using var hoverPaint = new SKPaint
{ {
Color = HoverBackgroundColor, Color = _hoverBackgroundColorSK,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
canvas.DrawRect(itemBounds, hoverPaint); canvas.DrawRect(itemBounds, hoverPaint);
@@ -137,7 +192,7 @@ public class SkiaMenuFlyout : SkiaView
{ {
using var checkPaint = new SKPaint using var checkPaint = new SKPaint
{ {
Color = menuItem.IsEnabled ? TextColor : DisabledTextColor, Color = menuItem.IsEnabled ? _textColorSK : _disabledTextColorSK,
TextSize = FontSize, TextSize = FontSize,
IsAntialias = true IsAntialias = true
}; };
@@ -145,13 +200,13 @@ public class SkiaMenuFlyout : SkiaView
} }
// Draw text // 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); canvas.DrawText(menuItem.Text, _bounds.Left + 28f, y + ItemHeight / 2f + 5f, textPaint);
// Draw shortcut // Draw shortcut
if (!string.IsNullOrEmpty(menuItem.Shortcut)) if (!string.IsNullOrEmpty(menuItem.Shortcut))
{ {
textPaint.Color = DisabledTextColor; textPaint.Color = _disabledTextColorSK;
var shortcutBounds = new SKRect(); var shortcutBounds = new SKRect();
textPaint.MeasureText(menuItem.Shortcut, ref shortcutBounds); textPaint.MeasureText(menuItem.Shortcut, ref shortcutBounds);
canvas.DrawText(menuItem.Shortcut, _bounds.Right - shortcutBounds.Width - 12f, y + ItemHeight / 2f + 5f, textPaint); canvas.DrawText(menuItem.Shortcut, _bounds.Right - shortcutBounds.Width - 12f, y + ItemHeight / 2f + 5f, textPaint);

View File

@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Platform.Linux; using Microsoft.Maui.Platform.Linux;
using SkiaSharp; using SkiaSharp;
@@ -23,28 +24,32 @@ public class SkiaNavigationPage : SkiaView
private bool _isPushAnimation; private bool _isPushAnimation;
// Navigation bar styling // Navigation bar styling
private SKColor _barBackgroundColor = new SKColor(0x21, 0x96, 0xF3); private SKColor _barBackgroundColor = SkiaTheme.PrimarySK;
private SKColor _barTextColor = SKColors.White; private SKColor _barTextColor = SKColors.White;
private Color _barBackgroundColorMaui = Color.FromRgb(0x21, 0x96, 0xF3);
private Color _barTextColorMaui = Colors.White;
private float _navigationBarHeight = 56; private float _navigationBarHeight = 56;
private bool _showBackButton = true; private bool _showBackButton = true;
public SKColor BarBackgroundColor public Color BarBackgroundColor
{ {
get => _barBackgroundColor; get => _barBackgroundColorMaui;
set set
{ {
_barBackgroundColor = value; _barBackgroundColorMaui = value;
_barBackgroundColor = value.ToSKColor();
UpdatePageNavigationBar(); UpdatePageNavigationBar();
Invalidate(); Invalidate();
} }
} }
public SKColor BarTextColor public Color BarTextColor
{ {
get => _barTextColor; get => _barTextColorMaui;
set set
{ {
_barTextColor = value; _barTextColorMaui = value;
_barTextColor = value.ToSKColor();
UpdatePageNavigationBar(); UpdatePageNavigationBar();
Invalidate(); Invalidate();
} }
@@ -194,8 +199,8 @@ public class SkiaNavigationPage : SkiaView
private void ConfigurePage(SkiaPage page, bool showBackButton) private void ConfigurePage(SkiaPage page, bool showBackButton)
{ {
page.ShowNavigationBar = true; page.ShowNavigationBar = true;
page.TitleBarColor = _barBackgroundColor; page.TitleBarColor = _barBackgroundColorMaui;
page.TitleTextColor = _barTextColor; page.TitleTextColor = _barTextColorMaui;
page.NavigationBarHeight = _navigationBarHeight; page.NavigationBarHeight = _navigationBarHeight;
_showBackButton = showBackButton && _navigationStack.Count > 0; _showBackButton = showBackButton && _navigationStack.Count > 0;
} }
@@ -204,8 +209,8 @@ public class SkiaNavigationPage : SkiaView
{ {
if (_currentPage != null) if (_currentPage != null)
{ {
_currentPage.TitleBarColor = _barBackgroundColor; _currentPage.TitleBarColor = _barBackgroundColorMaui;
_currentPage.TitleTextColor = _barTextColor; _currentPage.TitleTextColor = _barTextColorMaui;
_currentPage.NavigationBarHeight = _navigationBarHeight; _currentPage.NavigationBarHeight = _navigationBarHeight;
} }
} }

View File

@@ -13,8 +13,10 @@ public class SkiaPage : SkiaView
{ {
private SkiaView? _content; private SkiaView? _content;
private string _title = ""; private string _title = "";
private SKColor _titleBarColor = new SKColor(0x21, 0x96, 0xF3); // Material Blue protected SKColor _titleBarColor = SkiaTheme.PrimarySK;
private SKColor _titleTextColor = SKColors.White; 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 bool _showNavigationBar = false;
private float _navigationBarHeight = 56; private float _navigationBarHeight = 56;
@@ -52,22 +54,24 @@ public class SkiaPage : SkiaView
} }
} }
public SKColor TitleBarColor public Color TitleBarColor
{ {
get => _titleBarColor; get => _titleBarColorMaui;
set set
{ {
_titleBarColor = value; _titleBarColorMaui = value;
_titleBarColor = value.ToSKColor();
Invalidate(); Invalidate();
} }
} }
public SKColor TitleTextColor public Color TitleTextColor
{ {
get => _titleTextColor; get => _titleTextColorMaui;
set set
{ {
_titleTextColor = value; _titleTextColorMaui = value;
_titleTextColor = value.ToSKColor();
Invalidate(); Invalidate();
} }
} }
@@ -228,7 +232,7 @@ public class SkiaPage : SkiaView
// Draw shadow // Draw shadow
using var shadowPaint = new SKPaint using var shadowPaint = new SKPaint
{ {
Color = new SKColor(0, 0, 0, 30), Color = SkiaTheme.Shadow20SK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 2) MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 2)
}; };
@@ -240,7 +244,7 @@ public class SkiaPage : SkiaView
// Draw semi-transparent overlay // Draw semi-transparent overlay
using var overlayPaint = new SKPaint using var overlayPaint = new SKPaint
{ {
Color = new SKColor(255, 255, 255, 180), Color = SkiaTheme.WhiteSemiTransparentSK,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
canvas.DrawRect(bounds, overlayPaint); canvas.DrawRect(bounds, overlayPaint);
@@ -379,7 +383,7 @@ public class SkiaContentPage : SkiaPage
// Draw navigation bar background // Draw navigation bar background
using var barPaint = new SKPaint using var barPaint = new SKPaint
{ {
Color = TitleBarColor, Color = _titleBarColor,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
canvas.DrawRect(bounds, barPaint); canvas.DrawRect(bounds, barPaint);
@@ -390,7 +394,7 @@ public class SkiaContentPage : SkiaPage
using var font = new SKFont(SKTypeface.Default, 20); using var font = new SKFont(SKTypeface.Default, 20);
using var textPaint = new SKPaint(font) using var textPaint = new SKPaint(font)
{ {
Color = TitleTextColor, Color = _titleTextColor,
IsAntialias = true IsAntialias = true
}; };
@@ -408,7 +412,7 @@ public class SkiaContentPage : SkiaPage
// Draw shadow // Draw shadow
using var shadowPaint = new SKPaint using var shadowPaint = new SKPaint
{ {
Color = new SKColor(0, 0, 0, 30), Color = SkiaTheme.Shadow20SK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 2) MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 2)
}; };
@@ -424,7 +428,7 @@ public class SkiaContentPage : SkiaPage
using var font = new SKFont(SKTypeface.Default, 14); using var font = new SKFont(SKTypeface.Default, 14);
using var textPaint = new SKPaint(font) using var textPaint = new SKPaint(font)
{ {
Color = TitleTextColor, Color = _titleTextColor,
IsAntialias = true IsAntialias = true
}; };

View File

@@ -24,11 +24,7 @@ public class SkiaPicker : SkiaView
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
#endregion #endregion
@@ -584,7 +580,7 @@ public class SkiaPicker : SkiaView
// Draw shadow // Draw shadow
using var shadowPaint = new SKPaint using var shadowPaint = new SKPaint
{ {
Color = new SKColor(0, 0, 0, 40), Color = SkiaTheme.Shadow25SK,
MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 4), MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 4),
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };

View File

@@ -21,11 +21,7 @@ public class SkiaProgressBar : SkiaView
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
#endregion #endregion

View File

@@ -24,11 +24,7 @@ public class SkiaRadioButton : SkiaView
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
#endregion #endregion

View File

@@ -3,6 +3,7 @@
using System; using System;
using System.Windows.Input; using System.Windows.Input;
using Microsoft.Maui.Graphics;
using SkiaSharp; using SkiaSharp;
namespace Microsoft.Maui.Platform; namespace Microsoft.Maui.Platform;
@@ -21,6 +22,14 @@ public class SkiaRefreshView : SkiaLayoutView
private float _spinnerRotation = 0f; private float _spinnerRotation = 0f;
private DateTime _lastSpinnerUpdate; 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;
/// <summary> /// <summary>
/// Gets or sets the content view. /// Gets or sets the content view.
/// </summary> /// </summary>
@@ -81,12 +90,30 @@ public class SkiaRefreshView : SkiaLayoutView
/// <summary> /// <summary>
/// Gets or sets the refresh indicator color. /// Gets or sets the refresh indicator color.
/// </summary> /// </summary>
public SKColor RefreshColor { get; set; } = new SKColor(33, 150, 243); public Color RefreshColor
{
get => _refreshColor;
set
{
_refreshColor = value;
_refreshColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Gets or sets the background color of the refresh indicator. /// Gets or sets the background color of the refresh indicator.
/// </summary> /// </summary>
public SKColor RefreshBackgroundColor { get; set; } = SKColors.White; public Color RefreshBackgroundColor
{
get => _refreshBackgroundColor;
set
{
_refreshBackgroundColor = value;
_refreshBackgroundColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Gets or sets the command to execute when refresh is triggered. /// Gets or sets the command to execute when refresh is triggered.
@@ -154,19 +181,19 @@ public class SkiaRefreshView : SkiaLayoutView
// Draw background circle // Draw background circle
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = RefreshBackgroundColor, Color = _refreshBackgroundColorSK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };
// Add shadow // 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); canvas.DrawCircle(x, y, size / 2, bgPaint);
// Draw spinner // Draw spinner
using var spinnerPaint = new SKPaint using var spinnerPaint = new SKPaint
{ {
Color = RefreshColor, Color = _refreshColorSK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 3, StrokeWidth = 3,
IsAntialias = true, IsAntialias = true,

View File

@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements. // Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Maui.Graphics;
using SkiaSharp; using SkiaSharp;
namespace Microsoft.Maui.Platform; namespace Microsoft.Maui.Platform;
@@ -54,11 +55,19 @@ public class SkiaScrollView : SkiaView
public static readonly BindableProperty ScrollBarColorProperty = public static readonly BindableProperty ScrollBarColorProperty =
BindableProperty.Create( BindableProperty.Create(
nameof(ScrollBarColor), nameof(ScrollBarColor),
typeof(SKColor), typeof(Color),
typeof(SkiaScrollView), typeof(SkiaScrollView),
new SKColor(0x80, 0x80, 0x80, 0x80), Color.FromRgba(0x80, 0x80, 0x80, 0x80),
BindingMode.TwoWay, 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();
});
/// <summary> /// <summary>
/// Bindable property for ScrollBarWidth. /// Bindable property for ScrollBarWidth.
@@ -106,9 +115,9 @@ public class SkiaScrollView : SkiaView
/// <summary> /// <summary>
/// Scrollbar color. /// Scrollbar color.
/// </summary> /// </summary>
public SKColor ScrollBarColor public Color ScrollBarColor
{ {
get => (SKColor)GetValue(ScrollBarColorProperty); get => (Color)GetValue(ScrollBarColorProperty);
set => SetValue(ScrollBarColorProperty, value); set => SetValue(ScrollBarColorProperty, value);
} }
@@ -126,6 +135,7 @@ public class SkiaScrollView : SkiaView
private SkiaView? _content; private SkiaView? _content;
private float _scrollX; private float _scrollX;
private float _scrollY; private float _scrollY;
private SKColor _scrollBarColorSK = SkiaTheme.ScrollbarThumbSK;
private float _velocityX; private float _velocityX;
private float _velocityY; private float _velocityY;
private bool _isDragging; private bool _isDragging;
@@ -353,7 +363,7 @@ public class SkiaScrollView : SkiaView
using var paint = new SKPaint using var paint = new SKPaint
{ {
Color = ScrollBarColor, Color = _scrollBarColorSK,
IsAntialias = true IsAntialias = true
}; };
@@ -376,7 +386,7 @@ public class SkiaScrollView : SkiaView
using var paint = new SKPaint using var paint = new SKPaint
{ {
Color = ScrollBarColor, Color = _scrollBarColorSK,
IsAntialias = true IsAntialias = true
}; };

View File

@@ -133,36 +133,6 @@ public class SkiaSearchBar : SkiaView
#endregion #endregion
#region Helper Methods
/// <summary>
/// Converts a MAUI Color to SkiaSharp SKColor.
/// </summary>
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));
}
/// <summary>
/// Converts a MAUI Color to SKColor with modified alpha.
/// </summary>
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 #region Drawing
protected override void OnDraw(SKCanvas canvas, SKRect bounds) protected override void OnDraw(SKCanvas canvas, SKRect bounds)
@@ -175,7 +145,7 @@ public class SkiaSearchBar : SkiaView
// Draw background // Draw background
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = ToSKColor(SearchBarBackgroundColor), Color = SearchBarBackgroundColor.ToSKColor(),
IsAntialias = true, IsAntialias = true,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
@@ -188,7 +158,7 @@ public class SkiaSearchBar : SkiaView
{ {
using var borderPaint = new SKPaint using var borderPaint = new SKPaint
{ {
Color = ToSKColor(FocusedBorderColor), Color = FocusedBorderColor.ToSKColor(),
IsAntialias = true, IsAntialias = true,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 2 StrokeWidth = 2
@@ -224,7 +194,7 @@ public class SkiaSearchBar : SkiaView
{ {
using var paint = new SKPaint using var paint = new SKPaint
{ {
Color = ToSKColor(IconColor), Color = IconColor.ToSKColor(),
IsAntialias = true, IsAntialias = true,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 2, StrokeWidth = 2,
@@ -252,7 +222,7 @@ public class SkiaSearchBar : SkiaView
// Draw circle background // Draw circle background
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = ToSKColorWithAlpha(ClearButtonColor, 80), Color = ClearButtonColor.ToSKColor().WithAlpha(80),
IsAntialias = true, IsAntialias = true,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
@@ -261,7 +231,7 @@ public class SkiaSearchBar : SkiaView
// Draw X // Draw X
using var paint = new SKPaint using var paint = new SKPaint
{ {
Color = ToSKColor(ClearButtonColor), Color = ClearButtonColor.ToSKColor(),
IsAntialias = true, IsAntialias = true,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 2, StrokeWidth = 2,

View File

@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements. // Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Maui.Graphics;
using SkiaSharp; using SkiaSharp;
namespace Microsoft.Maui.Platform; namespace Microsoft.Maui.Platform;
@@ -56,11 +57,11 @@ public class SkiaShell : SkiaLayoutView
public static readonly BindableProperty FlyoutBackgroundColorProperty = public static readonly BindableProperty FlyoutBackgroundColorProperty =
BindableProperty.Create( BindableProperty.Create(
nameof(FlyoutBackgroundColor), nameof(FlyoutBackgroundColor),
typeof(SKColor), typeof(Color),
typeof(SkiaShell), typeof(SkiaShell),
SKColors.White, Colors.White,
BindingMode.TwoWay, BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate()); propertyChanged: (b, o, n) => ((SkiaShell)b).OnFlyoutBackgroundColorChanged());
/// <summary> /// <summary>
/// Bindable property for FlyoutTextColor. /// Bindable property for FlyoutTextColor.
@@ -68,11 +69,11 @@ public class SkiaShell : SkiaLayoutView
public static readonly BindableProperty FlyoutTextColorProperty = public static readonly BindableProperty FlyoutTextColorProperty =
BindableProperty.Create( BindableProperty.Create(
nameof(FlyoutTextColor), nameof(FlyoutTextColor),
typeof(SKColor), typeof(Color),
typeof(SkiaShell), typeof(SkiaShell),
new SKColor(33, 33, 33), Color.FromRgb(33, 33, 33),
BindingMode.TwoWay, BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate()); propertyChanged: (b, o, n) => ((SkiaShell)b).OnFlyoutTextColorChanged());
/// <summary> /// <summary>
/// Bindable property for NavBarBackgroundColor. /// Bindable property for NavBarBackgroundColor.
@@ -80,11 +81,11 @@ public class SkiaShell : SkiaLayoutView
public static readonly BindableProperty NavBarBackgroundColorProperty = public static readonly BindableProperty NavBarBackgroundColorProperty =
BindableProperty.Create( BindableProperty.Create(
nameof(NavBarBackgroundColor), nameof(NavBarBackgroundColor),
typeof(SKColor), typeof(Color),
typeof(SkiaShell), typeof(SkiaShell),
new SKColor(33, 150, 243), Color.FromRgb(33, 150, 243),
BindingMode.TwoWay, BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate()); propertyChanged: (b, o, n) => ((SkiaShell)b).OnNavBarBackgroundColorChanged());
/// <summary> /// <summary>
/// Bindable property for NavBarTextColor. /// Bindable property for NavBarTextColor.
@@ -92,11 +93,11 @@ public class SkiaShell : SkiaLayoutView
public static readonly BindableProperty NavBarTextColorProperty = public static readonly BindableProperty NavBarTextColorProperty =
BindableProperty.Create( BindableProperty.Create(
nameof(NavBarTextColor), nameof(NavBarTextColor),
typeof(SKColor), typeof(Color),
typeof(SkiaShell), typeof(SkiaShell),
SKColors.White, Colors.White,
BindingMode.TwoWay, BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate()); propertyChanged: (b, o, n) => ((SkiaShell)b).OnNavBarTextColorChanged());
/// <summary> /// <summary>
/// Bindable property for NavBarHeight. /// Bindable property for NavBarHeight.
@@ -164,11 +165,11 @@ public class SkiaShell : SkiaLayoutView
public static readonly BindableProperty ContentBackgroundColorProperty = public static readonly BindableProperty ContentBackgroundColorProperty =
BindableProperty.Create( BindableProperty.Create(
nameof(ContentBackgroundColor), nameof(ContentBackgroundColor),
typeof(SKColor), typeof(Color),
typeof(SkiaShell), typeof(SkiaShell),
new SKColor(250, 250, 250), Color.FromRgb(250, 250, 250),
BindingMode.TwoWay, BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate()); propertyChanged: (b, o, n) => ((SkiaShell)b).OnContentBackgroundColorChanged());
/// <summary> /// <summary>
/// Bindable property for Title. /// Bindable property for Title.
@@ -197,6 +198,43 @@ public class SkiaShell : SkiaLayoutView
private readonly Dictionary<string, Func<SkiaView?>> _registeredRoutes = new(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, Func<SkiaView?>> _registeredRoutes = new(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, string> _routeTitles = new(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, string> _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) private void OnFlyoutIsPresentedChanged(bool newValue)
{ {
_flyoutAnimationProgress = newValue ? 1f : 0f; _flyoutAnimationProgress = newValue ? 1f : 0f;
@@ -234,18 +272,18 @@ public class SkiaShell : SkiaLayoutView
/// <summary> /// <summary>
/// Background color of the flyout. /// Background color of the flyout.
/// </summary> /// </summary>
public SKColor FlyoutBackgroundColor public Color? FlyoutBackgroundColor
{ {
get => (SKColor)GetValue(FlyoutBackgroundColorProperty); get => (Color?)GetValue(FlyoutBackgroundColorProperty);
set => SetValue(FlyoutBackgroundColorProperty, value); set => SetValue(FlyoutBackgroundColorProperty, value);
} }
/// <summary> /// <summary>
/// Text color in the flyout. /// Text color in the flyout.
/// </summary> /// </summary>
public SKColor FlyoutTextColor public Color? FlyoutTextColor
{ {
get => (SKColor)GetValue(FlyoutTextColorProperty); get => (Color?)GetValue(FlyoutTextColorProperty);
set => SetValue(FlyoutTextColorProperty, value); set => SetValue(FlyoutTextColorProperty, value);
} }
@@ -272,18 +310,18 @@ public class SkiaShell : SkiaLayoutView
/// <summary> /// <summary>
/// Background color of the navigation bar. /// Background color of the navigation bar.
/// </summary> /// </summary>
public SKColor NavBarBackgroundColor public Color? NavBarBackgroundColor
{ {
get => (SKColor)GetValue(NavBarBackgroundColorProperty); get => (Color?)GetValue(NavBarBackgroundColorProperty);
set => SetValue(NavBarBackgroundColorProperty, value); set => SetValue(NavBarBackgroundColorProperty, value);
} }
/// <summary> /// <summary>
/// Text color of the navigation bar title. /// Text color of the navigation bar title.
/// </summary> /// </summary>
public SKColor NavBarTextColor public Color? NavBarTextColor
{ {
get => (SKColor)GetValue(NavBarTextColorProperty); get => (Color?)GetValue(NavBarTextColorProperty);
set => SetValue(NavBarTextColorProperty, value); set => SetValue(NavBarTextColorProperty, value);
} }
@@ -335,9 +373,9 @@ public class SkiaShell : SkiaLayoutView
/// <summary> /// <summary>
/// Background color of the content area. /// Background color of the content area.
/// </summary> /// </summary>
public SKColor ContentBackgroundColor public Color? ContentBackgroundColor
{ {
get => (SKColor)GetValue(ContentBackgroundColorProperty); get => (Color?)GetValue(ContentBackgroundColorProperty);
set => SetValue(ContentBackgroundColorProperty, value); set => SetValue(ContentBackgroundColorProperty, value);
} }
@@ -789,7 +827,7 @@ public class SkiaShell : SkiaLayoutView
// Draw background // Draw background
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = NavBarBackgroundColor, Color = _navBarBackgroundColorSK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true 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) // Draw nav icon (back arrow if can go back, else hamburger menu if flyout enabled)
using var iconPaint = new SKPaint using var iconPaint = new SKPaint
{ {
Color = NavBarTextColor, Color = _navBarTextColorSK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 2, StrokeWidth = 2,
StrokeCap = SKStrokeCap.Round, StrokeCap = SKStrokeCap.Round,
@@ -813,7 +851,7 @@ public class SkiaShell : SkiaLayoutView
// Draw iOS-style back chevron "<" // Draw iOS-style back chevron "<"
using var chevronPaint = new SKPaint using var chevronPaint = new SKPaint
{ {
Color = NavBarTextColor, Color = _navBarTextColorSK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 2.5f, StrokeWidth = 2.5f,
StrokeCap = SKStrokeCap.Round, StrokeCap = SKStrokeCap.Round,
@@ -838,7 +876,7 @@ public class SkiaShell : SkiaLayoutView
// Draw title // Draw title
using var titlePaint = new SKPaint using var titlePaint = new SKPaint
{ {
Color = NavBarTextColor, Color = _navBarTextColorSK,
TextSize = 20f, TextSize = 20f,
IsAntialias = true, IsAntialias = true,
FakeBoldText = true FakeBoldText = true
@@ -865,7 +903,7 @@ public class SkiaShell : SkiaLayoutView
// Draw background // Draw background
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = SKColors.White, Color = SkiaTheme.BackgroundWhiteSK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };
@@ -874,7 +912,7 @@ public class SkiaShell : SkiaLayoutView
// Draw top border // Draw top border
using var borderPaint = new SKPaint using var borderPaint = new SKPaint
{ {
Color = new SKColor(224, 224, 224), Color = SkiaTheme.Gray300SK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 1 StrokeWidth = 1
}; };
@@ -894,7 +932,7 @@ public class SkiaShell : SkiaLayoutView
var item = section.Items[i]; var item = section.Items[i];
bool isSelected = i == _selectedItemIndex; bool isSelected = i == _selectedItemIndex;
textPaint.Color = isSelected ? NavBarBackgroundColor : new SKColor(117, 117, 117); textPaint.Color = isSelected ? _navBarBackgroundColorSK : SkiaTheme.TextTertiarySK;
var textBounds = new SKRect(); var textBounds = new SKRect();
textPaint.MeasureText(item.Title, ref textBounds); textPaint.MeasureText(item.Title, ref textBounds);
@@ -911,7 +949,7 @@ public class SkiaShell : SkiaLayoutView
// Draw scrim // Draw scrim
using var scrimPaint = new SKPaint using var scrimPaint = new SKPaint
{ {
Color = new SKColor(0, 0, 0, (byte)(100 * _flyoutAnimationProgress)), Color = SkiaTheme.Shadow40SK.WithAlpha((byte)(100 * _flyoutAnimationProgress)),
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
canvas.DrawRect(bounds, scrimPaint); canvas.DrawRect(bounds, scrimPaint);
@@ -926,7 +964,7 @@ public class SkiaShell : SkiaLayoutView
using var flyoutPaint = new SKPaint using var flyoutPaint = new SKPaint
{ {
Color = FlyoutBackgroundColor, Color = _flyoutBackgroundColorSK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };
@@ -952,14 +990,14 @@ public class SkiaShell : SkiaLayoutView
{ {
using var selectionPaint = new SKPaint using var selectionPaint = new SKPaint
{ {
Color = new SKColor(33, 150, 243, 30), Color = SkiaTheme.PrimarySelectionSK.WithAlpha(30),
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };
var selectionRect = new SKRect(flyoutBounds.Left, itemY, flyoutBounds.Right, itemY + itemHeight); var selectionRect = new SKRect(flyoutBounds.Left, itemY, flyoutBounds.Right, itemY + itemHeight);
canvas.DrawRect(selectionRect, selectionPaint); 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); canvas.DrawText(section.Title, flyoutBounds.Left + 16, itemY + 30, itemTextPaint);
itemY += itemHeight; itemY += itemHeight;

View File

@@ -22,11 +22,7 @@ public class SkiaSlider : SkiaView
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
#endregion #endregion
@@ -187,10 +183,10 @@ public class SkiaSlider : SkiaView
set => SetValue(ThumbColorProperty, value); set => SetValue(ThumbColorProperty, value);
} }
// Platform defaults for colors when null // Platform defaults for colors when null - using centralized theme
private static readonly SKColor DefaultMinimumTrackColor = new SKColor(0x21, 0x96, 0xF3); // Material Blue private static readonly SKColor DefaultMinimumTrackColor = SkiaTheme.PrimarySK; // Material Blue
private static readonly SKColor DefaultMaximumTrackColor = new SKColor(0xE0, 0xE0, 0xE0); // Gray private static readonly SKColor DefaultMaximumTrackColor = SkiaTheme.Gray300SK; // Gray
private static readonly SKColor DefaultThumbColor = new SKColor(0x21, 0x96, 0xF3); // Material Blue private static readonly SKColor DefaultThumbColor = SkiaTheme.PrimarySK; // Material Blue
private SKColor GetEffectiveMinimumTrackColor() => MinimumTrackColor != null ? ToSKColor(MinimumTrackColor) : DefaultMinimumTrackColor; private SKColor GetEffectiveMinimumTrackColor() => MinimumTrackColor != null ? ToSKColor(MinimumTrackColor) : DefaultMinimumTrackColor;
private SKColor GetEffectiveMaximumTrackColor() => MaximumTrackColor != null ? ToSKColor(MaximumTrackColor) : DefaultMaximumTrackColor; private SKColor GetEffectiveMaximumTrackColor() => MaximumTrackColor != null ? ToSKColor(MaximumTrackColor) : DefaultMaximumTrackColor;
@@ -346,7 +342,7 @@ public class SkiaSlider : SkiaView
{ {
using var shadowPaint = new SKPaint using var shadowPaint = new SKPaint
{ {
Color = new SKColor(0, 0, 0, 30), Color = SkiaTheme.Shadow20SK,
IsAntialias = true, IsAntialias = true,
MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 3) MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 3)
}; };

View File

@@ -21,11 +21,7 @@ public class SkiaStepper : SkiaView
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
#endregion #endregion

View File

@@ -23,11 +23,7 @@ public class SkiaSwitch : SkiaView
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
#endregion #endregion
@@ -345,7 +341,7 @@ public class SkiaSwitch : SkiaView
{ {
using var shadowPaint = new SKPaint using var shadowPaint = new SKPaint
{ {
Color = new SKColor(0, 0, 0, 40), Color = SkiaTheme.Shadow25SK,
IsAntialias = true, IsAntialias = true,
MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 2f) MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 2f)
}; };
@@ -355,7 +351,7 @@ public class SkiaSwitch : SkiaView
// Draw thumb // Draw thumb
using var thumbPaint = new SKPaint using var thumbPaint = new SKPaint
{ {
Color = IsEnabled ? thumbColorSK : new SKColor(245, 245, 245), Color = IsEnabled ? thumbColorSK : SkiaTheme.Gray100SK,
IsAntialias = true, IsAntialias = true,
Style = SKPaintStyle.Fill Style = SKPaintStyle.Fill
}; };

View File

@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements. // Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Maui.Graphics;
using SkiaSharp; using SkiaSharp;
namespace Microsoft.Maui.Platform; namespace Microsoft.Maui.Platform;
@@ -15,6 +16,18 @@ public class SkiaTabbedPage : SkiaLayoutView
private float _tabBarHeight = 48f; private float _tabBarHeight = 48f;
private bool _tabBarOnBottom = false; 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;
/// <summary> /// <summary>
/// Gets or sets the height of the tab bar. /// Gets or sets the height of the tab bar.
/// </summary> /// </summary>
@@ -80,22 +93,58 @@ public class SkiaTabbedPage : SkiaLayoutView
/// <summary> /// <summary>
/// Background color for the tab bar. /// Background color for the tab bar.
/// </summary> /// </summary>
public SKColor TabBarBackgroundColor { get; set; } = new SKColor(33, 150, 243); // Material Blue public Color TabBarBackgroundColor
{
get => _tabBarBackgroundColor;
set
{
_tabBarBackgroundColor = value;
_tabBarBackgroundColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Color for selected tab text/icon. /// Color for selected tab text/icon.
/// </summary> /// </summary>
public SKColor SelectedTabColor { get; set; } = SKColors.White; public Color SelectedTabColor
{
get => _selectedTabColor;
set
{
_selectedTabColor = value;
_selectedTabColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Color for unselected tab text/icon. /// Color for unselected tab text/icon.
/// </summary> /// </summary>
public SKColor UnselectedTabColor { get; set; } = new SKColor(255, 255, 255, 180); public Color UnselectedTabColor
{
get => _unselectedTabColor;
set
{
_unselectedTabColor = value;
_unselectedTabColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Color of the selection indicator. /// Color of the selection indicator.
/// </summary> /// </summary>
public SKColor IndicatorColor { get; set; } = SKColors.White; public Color IndicatorColor
{
get => _indicatorColor;
set
{
_indicatorColor = value;
_indicatorColorSK = value.ToSKColor();
Invalidate();
}
}
/// <summary> /// <summary>
/// Height of the selection indicator. /// Height of the selection indicator.
@@ -252,7 +301,7 @@ public class SkiaTabbedPage : SkiaLayoutView
// Draw background // Draw background
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = TabBarBackgroundColor, Color = _tabBarBackgroundColorSK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };
@@ -281,7 +330,7 @@ public class SkiaTabbedPage : SkiaLayoutView
tabBarBounds.Bottom); tabBarBounds.Bottom);
bool isSelected = i == _selectedIndex; bool isSelected = i == _selectedIndex;
textPaint.Color = isSelected ? SelectedTabColor : UnselectedTabColor; textPaint.Color = isSelected ? _selectedTabColorSK : _unselectedTabColorSK;
textPaint.FakeBoldText = isSelected; textPaint.FakeBoldText = isSelected;
// Draw tab title centered // Draw tab title centered
@@ -299,7 +348,7 @@ public class SkiaTabbedPage : SkiaLayoutView
{ {
using var indicatorPaint = new SKPaint using var indicatorPaint = new SKPaint
{ {
Color = IndicatorColor, Color = _indicatorColorSK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };

320
Views/SkiaTheme.cs Normal file
View File

@@ -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;
/// <summary>
/// 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.
/// </summary>
public static class SkiaTheme
{
#region Primary Colors
/// <summary>Material Blue - Primary accent color</summary>
public static readonly Color Primary = Color.FromRgb(0x21, 0x96, 0xF3);
/// <summary>Material Blue Dark - Darker primary variant</summary>
public static readonly Color PrimaryDark = Color.FromRgb(0x19, 0x76, 0xD2);
/// <summary>Material Blue Light with transparency</summary>
public static readonly Color PrimaryLight = Color.FromRgba(0x21, 0x96, 0xF3, 0x60);
/// <summary>Material Blue with 35% opacity for selection</summary>
public static readonly Color PrimarySelection = Color.FromRgba(0x21, 0x96, 0xF3, 0x59);
/// <summary>Material Blue with 50% opacity</summary>
public static readonly Color PrimaryHalf = Color.FromRgba(0x21, 0x96, 0xF3, 0x80);
#endregion
#region Text Colors
/// <summary>Primary text color - dark gray</summary>
public static readonly Color TextPrimary = Color.FromRgb(0x21, 0x21, 0x21);
/// <summary>Secondary text color - medium gray</summary>
public static readonly Color TextSecondary = Color.FromRgb(0x61, 0x61, 0x61);
/// <summary>Tertiary/hint text color</summary>
public static readonly Color TextTertiary = Color.FromRgb(0x75, 0x75, 0x75);
/// <summary>Disabled text color</summary>
public static readonly Color TextDisabled = Color.FromRgb(0x9E, 0x9E, 0x9E);
/// <summary>Placeholder text color</summary>
public static readonly Color TextPlaceholder = Color.FromRgb(0x80, 0x80, 0x80);
/// <summary>Link text color</summary>
public static readonly Color TextLink = Color.FromRgb(0x21, 0x96, 0xF3);
/// <summary>Visited link text color - Material Purple</summary>
public static readonly Color TextLinkVisited = Color.FromRgb(0x9C, 0x27, 0xB0);
#endregion
#region Background Colors
/// <summary>White background</summary>
public static readonly Color BackgroundWhite = Colors.White;
/// <summary>Semi-transparent white (59% opacity)</summary>
public static readonly Color WhiteSemiTransparent = Color.FromRgba(255, 255, 255, 150);
/// <summary>Light gray background</summary>
public static readonly Color BackgroundLight = Color.FromRgb(0xF5, 0xF5, 0xF5);
/// <summary>Slightly darker light background</summary>
public static readonly Color BackgroundLightAlt = Color.FromRgb(0xFA, 0xFA, 0xFA);
/// <summary>Surface background (cards, dialogs)</summary>
public static readonly Color BackgroundSurface = Color.FromRgb(0xFF, 0xFF, 0xFF);
/// <summary>Disabled background</summary>
public static readonly Color BackgroundDisabled = Color.FromRgb(0xEE, 0xEE, 0xEE);
#endregion
#region Gray Scale
/// <summary>Gray 50 - lightest</summary>
public static readonly Color Gray50 = Color.FromRgb(0xFA, 0xFA, 0xFA);
/// <summary>Gray 100</summary>
public static readonly Color Gray100 = Color.FromRgb(0xF5, 0xF5, 0xF5);
/// <summary>Gray 200</summary>
public static readonly Color Gray200 = Color.FromRgb(0xEE, 0xEE, 0xEE);
/// <summary>Gray 300</summary>
public static readonly Color Gray300 = Color.FromRgb(0xE0, 0xE0, 0xE0);
/// <summary>Gray 400</summary>
public static readonly Color Gray400 = Color.FromRgb(0xBD, 0xBD, 0xBD);
/// <summary>Gray 500</summary>
public static readonly Color Gray500 = Color.FromRgb(0x9E, 0x9E, 0x9E);
/// <summary>Gray 600</summary>
public static readonly Color Gray600 = Color.FromRgb(0x75, 0x75, 0x75);
/// <summary>Gray 700</summary>
public static readonly Color Gray700 = Color.FromRgb(0x61, 0x61, 0x61);
/// <summary>Gray 800</summary>
public static readonly Color Gray800 = Color.FromRgb(0x42, 0x42, 0x42);
/// <summary>Gray 900 - darkest</summary>
public static readonly Color Gray900 = Color.FromRgb(0x21, 0x21, 0x21);
#endregion
#region Border Colors
/// <summary>Light border color</summary>
public static readonly Color BorderLight = Color.FromRgb(0xE0, 0xE0, 0xE0);
/// <summary>Medium border color</summary>
public static readonly Color BorderMedium = Color.FromRgb(0xC8, 0xC8, 0xC8);
/// <summary>Dark border color</summary>
public static readonly Color BorderDark = Color.FromRgb(0xA0, 0xA0, 0xA0);
#endregion
#region Shadow Colors
/// <summary>Shadow with 10% opacity</summary>
public static readonly Color Shadow10 = Color.FromRgba(0, 0, 0, 0x1A);
/// <summary>Shadow with 15% opacity</summary>
public static readonly Color Shadow15 = Color.FromRgba(0, 0, 0, 0x26);
/// <summary>Shadow with 20% opacity</summary>
public static readonly Color Shadow20 = Color.FromRgba(0, 0, 0, 0x33);
/// <summary>Shadow with 25% opacity</summary>
public static readonly Color Shadow25 = Color.FromRgba(0, 0, 0, 0x40);
/// <summary>Shadow with 40% opacity</summary>
public static readonly Color Shadow40 = Color.FromRgba(0, 0, 0, 0x64);
/// <summary>Shadow with 50% opacity</summary>
public static readonly Color Shadow50 = Color.FromRgba(0, 0, 0, 0x80);
#endregion
#region Overlay Colors
/// <summary>Scrim/overlay with 40% opacity</summary>
public static readonly Color Overlay40 = Color.FromRgba(0, 0, 0, 0x64);
/// <summary>Scrim/overlay with 50% opacity</summary>
public static readonly Color Overlay50 = Color.FromRgba(0, 0, 0, 0x80);
#endregion
#region Status Colors
/// <summary>Error/danger color - Material Red</summary>
public static readonly Color Error = Color.FromRgb(0xF4, 0x43, 0x36);
/// <summary>Success color - Material Green</summary>
public static readonly Color Success = Color.FromRgb(0x4C, 0xAF, 0x50);
/// <summary>Warning color - Material Orange</summary>
public static readonly Color Warning = Color.FromRgb(0xFF, 0x98, 0x00);
#endregion
#region Button Colors
/// <summary>Cancel button background</summary>
public static readonly Color ButtonCancel = Color.FromRgb(0x9E, 0x9E, 0x9E);
/// <summary>Cancel button hover</summary>
public static readonly Color ButtonCancelHover = Color.FromRgb(0x75, 0x75, 0x75);
#endregion
#region Scrollbar Colors
/// <summary>Scrollbar thumb color</summary>
public static readonly Color ScrollbarThumb = Color.FromRgba(0x80, 0x80, 0x80, 0x80);
/// <summary>Scrollbar track color</summary>
public static readonly Color ScrollbarTrack = Color.FromRgba(0xC8, 0xC8, 0xC8, 0x40);
#endregion
#region Indicator Colors
/// <summary>Unselected indicator color</summary>
public static readonly Color IndicatorUnselected = Color.FromRgb(0xB4, 0xB4, 0xB4);
/// <summary>Selected indicator color</summary>
public static readonly Color IndicatorSelected = Color.FromRgb(0x21, 0x96, 0xF3);
#endregion
#region Menu Colors
/// <summary>Menu background</summary>
public static readonly Color MenuBackground = Color.FromRgb(0xF0, 0xF0, 0xF0);
/// <summary>Menu hover background</summary>
public static readonly Color MenuHover = Color.FromRgb(0xDC, 0xDC, 0xDC);
/// <summary>Menu active/pressed background</summary>
public static readonly Color MenuActive = Color.FromRgb(0xC8, 0xC8, 0xC8);
/// <summary>Menu separator color</summary>
public static readonly Color MenuSeparator = Color.FromRgb(0xDC, 0xDC, 0xDC);
#endregion
#region Dark Theme Colors
/// <summary>Dark theme background</summary>
public static readonly Color DarkBackground = Color.FromRgb(0x30, 0x30, 0x30);
/// <summary>Dark theme surface</summary>
public static readonly Color DarkSurface = Color.FromRgb(0x50, 0x50, 0x50);
/// <summary>Dark theme text</summary>
public static readonly Color DarkText = Color.FromRgb(0xE0, 0xE0, 0xE0);
/// <summary>Dark theme hover</summary>
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
}

View File

@@ -4,6 +4,7 @@
using Microsoft.Maui.Controls; using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics; using Microsoft.Maui.Graphics;
using Microsoft.Maui.Platform.Linux; using Microsoft.Maui.Platform.Linux;
using Microsoft.Maui.Platform.Linux.Converters;
using SkiaSharp; using SkiaSharp;
namespace Microsoft.Maui.Platform; namespace Microsoft.Maui.Platform;
@@ -223,11 +224,7 @@ public class SkiaTimePicker : SkiaView
private static SKColor ToSKColor(Color? color) private static SKColor ToSKColor(Color? color)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor();
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
} }
/// <summary> /// <summary>
@@ -236,11 +233,7 @@ public class SkiaTimePicker : SkiaView
private static SKColor ToSKColorWithAlpha(Color? color, byte alpha) private static SKColor ToSKColorWithAlpha(Color? color, byte alpha)
{ {
if (color == null) return SKColors.Transparent; if (color == null) return SKColors.Transparent;
return new SKColor( return color.ToSKColor().WithAlpha(alpha);
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
alpha);
} }
/// <summary> /// <summary>
@@ -298,7 +291,7 @@ public class SkiaTimePicker : SkiaView
using var bgPaint = new SKPaint using var bgPaint = new SKPaint
{ {
Color = IsEnabled ? GetEffectiveBackgroundColor() : new SKColor(245, 245, 245), Color = IsEnabled ? GetEffectiveBackgroundColor() : SkiaTheme.Gray100SK,
Style = SKPaintStyle.Fill, Style = SKPaintStyle.Fill,
IsAntialias = true IsAntialias = true
}; };
@@ -375,7 +368,7 @@ public class SkiaTimePicker : SkiaView
float cornerRadius = (float)CornerRadius; float cornerRadius = (float)CornerRadius;
var popupRect = GetPopupRect(bounds); 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); 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 }; 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); canvas.DrawRect(new SKRect(bounds.Left, bounds.Top + cornerRadius, bounds.Right, bounds.Bottom), headerPaint);
using var font = new SKFont(SKTypeface.Default, 32); using var font = new SKFont(SKTypeface.Default, 32);
using var selectedPaint = new SKPaint(font) { Color = SKColors.White, IsAntialias = true }; using var selectedPaint = new SKPaint(font) { Color = SkiaTheme.BackgroundWhiteSK, IsAntialias = true };
using var unselectedPaint = new SKPaint(font) { Color = new SKColor(255, 255, 255, 150), IsAntialias = true }; using var unselectedPaint = new SKPaint(font) { Color = SkiaTheme.WhiteSemiTransparentSK, IsAntialias = true };
var hourText = _selectedHour.ToString("D2"); var hourText = _selectedHour.ToString("D2");
var minuteText = _selectedMinute.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 }; using var selBgPaint = new SKPaint { Color = selectedColor, Style = SKPaintStyle.Fill, IsAntialias = true };
canvas.DrawCircle(x, y, 18, selBgPaint); canvas.DrawCircle(x, y, 18, selBgPaint);
textPaint.Color = SKColors.White; textPaint.Color = SkiaTheme.BackgroundWhiteSK;
} }
else textPaint.Color = textColor; else textPaint.Color = textColor;
var tBounds = new SKRect(); var tBounds = new SKRect();
@@ -470,7 +463,7 @@ public class SkiaTimePicker : SkiaView
{ {
using var selBgPaint = new SKPaint { Color = selectedColor, Style = SKPaintStyle.Fill, IsAntialias = true }; using var selBgPaint = new SKPaint { Color = selectedColor, Style = SKPaintStyle.Fill, IsAntialias = true };
canvas.DrawCircle(x, y, 18, selBgPaint); canvas.DrawCircle(x, y, 18, selBgPaint);
textPaint.Color = SKColors.White; textPaint.Color = SkiaTheme.BackgroundWhiteSK;
} }
else textPaint.Color = textColor; else textPaint.Color = textColor;
var tBounds = new SKRect(); var tBounds = new SKRect();

View File

@@ -100,19 +100,19 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
InitializeHighContrastService(); InitializeHighContrastService();
return _highContrastService?.GetColors() ?? new HighContrastColors return _highContrastService?.GetColors() ?? new HighContrastColors
{ {
Background = SKColors.White, Background = SkiaTheme.BackgroundWhiteSK,
Foreground = new SKColor(33, 33, 33), Foreground = SkiaTheme.TextPrimarySK,
Accent = new SKColor(33, 150, 243), Accent = SkiaTheme.PrimarySK,
Border = new SKColor(200, 200, 200), Border = SkiaTheme.BorderMediumSK,
Error = new SKColor(244, 67, 54), Error = SkiaTheme.ErrorSK,
Success = new SKColor(76, 175, 80), Success = SkiaTheme.SuccessSK,
Warning = new SKColor(255, 152, 0), Warning = SkiaTheme.WarningSK,
Link = new SKColor(33, 150, 243), Link = SkiaTheme.TextLinkSK,
LinkVisited = new SKColor(156, 39, 176), LinkVisited = SkiaTheme.TextLinkVisitedSK,
Selection = new SKColor(33, 150, 243), Selection = SkiaTheme.PrimarySK,
SelectionText = SKColors.White, SelectionText = SkiaTheme.BackgroundWhiteSK,
DisabledText = new SKColor(158, 158, 158), DisabledText = SkiaTheme.TextDisabledSK,
DisabledBackground = new SKColor(238, 238, 238) DisabledBackground = SkiaTheme.BackgroundDisabledSK
}; };
} }
@@ -1386,12 +1386,8 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
if (Shadow == null) return; if (Shadow == null) return;
var shadowColor = Shadow.Brush is SolidColorBrush scb var shadowColor = Shadow.Brush is SolidColorBrush scb
? new SKColor( ? scb.Color.ToSKColor().WithAlpha((byte)(scb.Color.Alpha * 255 * Shadow.Opacity))
(byte)(scb.Color.Red * 255), : SKColors.Black.WithAlpha((byte)(255 * Shadow.Opacity));
(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));
using var shadowPaint = new SKPaint using var shadowPaint = new SKPaint
{ {
@@ -1484,11 +1480,7 @@ public abstract class SkiaView : BindableObject, IDisposable, IAccessible
if (Background is SolidColorBrush scb) if (Background is SolidColorBrush scb)
{ {
paint.Color = new SKColor( paint.Color = scb.Color.ToSKColor();
(byte)(scb.Color.Red * 255),
(byte)(scb.Color.Green * 255),
(byte)(scb.Color.Blue * 255),
(byte)(scb.Color.Alpha * 255));
canvas.DrawRect(bounds, paint); canvas.DrawRect(bounds, paint);
} }
else if (Background is LinearGradientBrush lgb) 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.Left + (float)(lgb.EndPoint.X * bounds.Width),
bounds.Top + (float)(lgb.EndPoint.Y * bounds.Height)); bounds.Top + (float)(lgb.EndPoint.Y * bounds.Height));
var colors = lgb.GradientStops.Select(s => var colors = lgb.GradientStops.Select(s => s.Color.ToSKColor()).ToArray();
new SKColor(
(byte)(s.Color.Red * 255),
(byte)(s.Color.Green * 255),
(byte)(s.Color.Blue * 255),
(byte)(s.Color.Alpha * 255))).ToArray();
var positions = lgb.GradientStops.Select(s => s.Offset).ToArray(); var positions = lgb.GradientStops.Select(s => s.Offset).ToArray();
paint.Shader = SKShader.CreateLinearGradient(start, end, colors, positions, SKShaderTileMode.Clamp); 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)); bounds.Top + (float)(rgb.Center.Y * bounds.Height));
var radius = (float)(rgb.Radius * Math.Max(bounds.Width, bounds.Height)); var radius = (float)(rgb.Radius * Math.Max(bounds.Width, bounds.Height));
var colors = rgb.GradientStops.Select(s => var colors = rgb.GradientStops.Select(s => s.Color.ToSKColor()).ToArray();
new SKColor(
(byte)(s.Color.Red * 255),
(byte)(s.Color.Green * 255),
(byte)(s.Color.Blue * 255),
(byte)(s.Color.Alpha * 255))).ToArray();
var positions = rgb.GradientStops.Select(s => s.Offset).ToArray(); var positions = rgb.GradientStops.Select(s => s.Offset).ToArray();
paint.Shader = SKShader.CreateRadialGradient(center, radius, colors, positions, SKShaderTileMode.Clamp); paint.Shader = SKShader.CreateRadialGradient(center, radius, colors, positions, SKShaderTileMode.Clamp);

View File

@@ -1377,7 +1377,7 @@ public class SkiaWebView : SkiaView
using var borderPaint = new SKPaint using var borderPaint = new SKPaint
{ {
Color = new SKColor(200, 200, 200), Color = SkiaTheme.BorderMediumSK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 1 StrokeWidth = 1
}; };
@@ -1388,7 +1388,7 @@ public class SkiaWebView : SkiaView
using var iconPaint = new SKPaint using var iconPaint = new SKPaint
{ {
Color = new SKColor(100, 100, 100), Color = SkiaTheme.Gray600SK,
Style = SKPaintStyle.Stroke, Style = SKPaintStyle.Stroke,
StrokeWidth = 2, StrokeWidth = 2,
IsAntialias = true IsAntialias = true
@@ -1399,7 +1399,7 @@ public class SkiaWebView : SkiaView
using var textPaint = new SKPaint using var textPaint = new SKPaint
{ {
Color = new SKColor(80, 80, 80), Color = SkiaTheme.Gray700SK,
IsAntialias = true, IsAntialias = true,
TextSize = 14 TextSize = 14
}; };
@@ -1429,7 +1429,7 @@ public class SkiaWebView : SkiaView
{ {
using var hintPaint = new SKPaint using var hintPaint = new SKPaint
{ {
Color = new SKColor(120, 120, 120), Color = SkiaTheme.Gray600SK,
IsAntialias = true, IsAntialias = true,
TextSize = 11 TextSize = 11
}; };
@@ -1441,12 +1441,12 @@ public class SkiaWebView : SkiaView
if (_loadProgress > 0 && _loadProgress < 1) if (_loadProgress > 0 && _loadProgress < 1)
{ {
var progressRect = new SKRect(bounds.Left + 20, bounds.Bottom - 30, bounds.Right - 20, bounds.Bottom - 20); 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); canvas.DrawRoundRect(new SKRoundRect(progressRect, 5), progressBgPaint);
float filledWidth = progressRect.Width * (float)_loadProgress; float filledWidth = progressRect.Width * (float)_loadProgress;
var filledRect = new SKRect(progressRect.Left, progressRect.Top, progressRect.Left + filledWidth, progressRect.Bottom); 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); canvas.DrawRoundRect(new SKRoundRect(filledRect, 5), progressPaint);
} }
} }

View File

@@ -36,18 +36,10 @@ public class SwipeItem
/// <summary> /// <summary>
/// Helper to convert BackgroundColor to SKColor for rendering. /// Helper to convert BackgroundColor to SKColor for rendering.
/// </summary> /// </summary>
internal SKColor GetBackgroundColorSK() => new SKColor( internal SKColor GetBackgroundColorSK() => BackgroundColor.ToSKColor();
(byte)(BackgroundColor.Red * 255),
(byte)(BackgroundColor.Green * 255),
(byte)(BackgroundColor.Blue * 255),
(byte)(BackgroundColor.Alpha * 255));
/// <summary> /// <summary>
/// Helper to convert TextColor to SKColor for rendering. /// Helper to convert TextColor to SKColor for rendering.
/// </summary> /// </summary>
internal SKColor GetTextColorSK() => new SKColor( internal SKColor GetTextColorSK() => TextColor.ToSKColor();
(byte)(TextColor.Red * 255),
(byte)(TextColor.Green * 255),
(byte)(TextColor.Blue * 255),
(byte)(TextColor.Alpha * 255));
} }