More UI improvements
This commit is contained in:
@@ -168,12 +168,13 @@ public class FrameHandler :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.NavigateFromObject(control, navigationOptions);
|
|
||||||
foreach (Action postAction in postNavigateActions)
|
foreach (Action postAction in postNavigateActions)
|
||||||
{
|
{
|
||||||
postAction.Invoke();
|
postAction.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frame.NavigateFromObject(control, navigationOptions);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,19 +4,19 @@
|
|||||||
xmlns:controls="using:Toolkit.UI.Controls.Avalonia">
|
xmlns:controls="using:Toolkit.UI.Controls.Avalonia">
|
||||||
<ResourceDictionary.ThemeDictionaries>
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
<ResourceDictionary x:Key="Light">
|
<ResourceDictionary x:Key="Light">
|
||||||
<StaticResource x:Key="PersonPictureForegroundThemeBrush" ResourceKey="TextFillColorPrimaryBrush" />
|
<StaticResource x:Key="PersonPictureForegroundThemeBrush" ResourceKey="TextOnAccentFillColorSelectedText" />
|
||||||
<StaticResource x:Key="PersonPictureEllipseBadgeForegroundThemeBrush" ResourceKey="TextOnAccentFillColorPrimaryBrush" />
|
<StaticResource x:Key="PersonPictureEllipseBadgeForegroundThemeBrush" ResourceKey="TextOnAccentFillColorPrimaryBrush" />
|
||||||
<StaticResource x:Key="PersonPictureEllipseBadgeFillThemeBrush" ResourceKey="AccentFillColorDefaultBrush" />
|
<StaticResource x:Key="PersonPictureEllipseBadgeFillThemeBrush" ResourceKey="AccentFillColorDefaultBrush" />
|
||||||
<StaticResource x:Key="PersonPictureEllipseBadgeStrokeThemeBrush" ResourceKey="ControlFillColorTransparentBrush" />
|
<StaticResource x:Key="PersonPictureEllipseBadgeStrokeThemeBrush" ResourceKey="ControlFillColorTransparentBrush" />
|
||||||
<StaticResource x:Key="PersonPictureEllipseFillThemeBrush" ResourceKey="ControlAltFillColorQuarternaryBrush" />
|
<StaticResource x:Key="PersonPictureEllipseFillThemeBrush" ResourceKey="ControlFillColorDefaultBrush" />
|
||||||
<StaticResource x:Key="PersonPictureEllipseFillStrokeBrush" ResourceKey="CardStrokeColorDefaultBrush" />
|
<StaticResource x:Key="PersonPictureEllipseFillStrokeBrush" ResourceKey="CardStrokeColorDefaultBrush" />
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
<ResourceDictionary x:Key="Dark">
|
<ResourceDictionary x:Key="Dark">
|
||||||
<StaticResource x:Key="PersonPictureForegroundThemeBrush" ResourceKey="TextFillColorPrimaryBrush" />
|
<StaticResource x:Key="PersonPictureForegroundThemeBrush" ResourceKey="TextOnAccentFillColorSelectedText" />
|
||||||
<StaticResource x:Key="PersonPictureEllipseBadgeForegroundThemeBrush" ResourceKey="TextOnAccentFillColorPrimaryBrush" />
|
<StaticResource x:Key="PersonPictureEllipseBadgeForegroundThemeBrush" ResourceKey="TextOnAccentFillColorPrimaryBrush" />
|
||||||
<StaticResource x:Key="PersonPictureEllipseBadgeFillThemeBrush" ResourceKey="AccentFillColorDefaultBrush" />
|
<StaticResource x:Key="PersonPictureEllipseBadgeFillThemeBrush" ResourceKey="AccentFillColorDefaultBrush" />
|
||||||
<StaticResource x:Key="PersonPictureEllipseBadgeStrokeThemeBrush" ResourceKey="ControlFillColorTransparentBrush" />
|
<StaticResource x:Key="PersonPictureEllipseBadgeStrokeThemeBrush" ResourceKey="ControlFillColorTransparentBrush" />
|
||||||
<StaticResource x:Key="PersonPictureEllipseFillThemeBrush" ResourceKey="ControlAltFillColorQuarternaryBrush" />
|
<StaticResource x:Key="PersonPictureEllipseFillThemeBrush" ResourceKey="ControlFillColorDefaultBrush" />
|
||||||
<StaticResource x:Key="PersonPictureEllipseFillStrokeBrush" ResourceKey="CardStrokeColorDefaultBrush" />
|
<StaticResource x:Key="PersonPictureEllipseFillStrokeBrush" ResourceKey="CardStrokeColorDefaultBrush" />
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</ResourceDictionary.ThemeDictionaries>
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
@@ -27,18 +27,19 @@
|
|||||||
<Thickness x:Key="PersonPictureBadgeGridMargin">0,-4,-4,0</Thickness>
|
<Thickness x:Key="PersonPictureBadgeGridMargin">0,-4,-4,0</Thickness>
|
||||||
<ControlTheme x:Key="{x:Type controls:PersonPicture}" TargetType="controls:PersonPicture">
|
<ControlTheme x:Key="{x:Type controls:PersonPicture}" TargetType="controls:PersonPicture">
|
||||||
<Setter Property="Foreground" Value="{DynamicResource PersonPictureForegroundThemeBrush}" />
|
<Setter Property="Foreground" Value="{DynamicResource PersonPictureForegroundThemeBrush}" />
|
||||||
|
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}" />
|
||||||
|
<Setter Property="Background" Value="{DynamicResource PersonPictureEllipseFillThemeBrush}" />
|
||||||
|
<Setter Property="FontWeight" Value="600" />
|
||||||
|
<Setter Property="IsTabStop" Value="False" />
|
||||||
<Setter Property="Width" Value="100" />
|
<Setter Property="Width" Value="100" />
|
||||||
<Setter Property="Height" Value="100" />
|
<Setter Property="Height" Value="100" />
|
||||||
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}" />
|
|
||||||
<Setter Property="FontWeight" Value="350" />
|
|
||||||
<Setter Property="IsTabStop" Value="False" />
|
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Grid x:Name="RootGrid">
|
<Grid x:Name="RootGrid">
|
||||||
<Ellipse
|
<Ellipse
|
||||||
Width="{TemplateBinding Width}"
|
Width="{TemplateBinding Width}"
|
||||||
Height="{TemplateBinding Height}"
|
Height="{TemplateBinding Height}"
|
||||||
Fill="{DynamicResource PersonPictureEllipseFillThemeBrush}"
|
Fill="{TemplateBinding Background}"
|
||||||
Stroke="{DynamicResource PersonPictureEllipseFillStrokeBrush}"
|
Stroke="{DynamicResource PersonPictureEllipseFillStrokeBrush}"
|
||||||
StrokeThickness="{DynamicResource PersonPictureEllipseStrokeThickness}" />
|
StrokeThickness="{DynamicResource PersonPictureEllipseStrokeThickness}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Avalonia.Media.Imaging;
|
|||||||
|
|
||||||
namespace Toolkit.UI.Controls.Avalonia;
|
namespace Toolkit.UI.Controls.Avalonia;
|
||||||
|
|
||||||
|
|
||||||
public class PersonPicture : TemplatedControl
|
public class PersonPicture : TemplatedControl
|
||||||
{
|
{
|
||||||
public static readonly StyledProperty<string> BadgeGlyphProperty =
|
public static readonly StyledProperty<string> BadgeGlyphProperty =
|
||||||
@@ -36,11 +37,12 @@ public class PersonPicture : TemplatedControl
|
|||||||
private static readonly StyledProperty<PersonPictureTemplateSettings> TemplateSettingsProperty =
|
private static readonly StyledProperty<PersonPictureTemplateSettings> TemplateSettingsProperty =
|
||||||
AvaloniaProperty.Register<PersonPicture, PersonPictureTemplateSettings>(nameof(TemplateSettings));
|
AvaloniaProperty.Register<PersonPicture, PersonPictureTemplateSettings>(nameof(TemplateSettings));
|
||||||
|
|
||||||
|
private readonly ImageBrush? badgeImageBrush;
|
||||||
private FontIcon? badgeGlyphIcon;
|
private FontIcon? badgeGlyphIcon;
|
||||||
private ImageBrush? badgeImageBrush;
|
|
||||||
private TextBlock? badgeNumberTextBlock;
|
private TextBlock? badgeNumberTextBlock;
|
||||||
private Ellipse? badgingBackgroundEllipse;
|
private Ellipse? badgingBackgroundEllipse;
|
||||||
private Ellipse? badgingEllipse;
|
private Ellipse? badgingEllipse;
|
||||||
|
private PersonPictureColourGenerator colourGenerator = new(hue: 210, saturation: 0.8f, lightness: 0.6f);
|
||||||
private string? displayNameInitials;
|
private string? displayNameInitials;
|
||||||
private TextBlock? initialsTextBlock;
|
private TextBlock? initialsTextBlock;
|
||||||
|
|
||||||
@@ -335,6 +337,12 @@ public class PersonPicture : TemplatedControl
|
|||||||
PersonPictureTemplateSettings templateSettings = TemplateSettings;
|
PersonPictureTemplateSettings templateSettings = TemplateSettings;
|
||||||
templateSettings.ActualInitials = initials;
|
templateSettings.ActualInitials = initials;
|
||||||
|
|
||||||
|
if (DisplayName is { Length: > 0 })
|
||||||
|
{
|
||||||
|
Color rgb = colourGenerator.Create(DisplayName);
|
||||||
|
SetValue(BackgroundProperty, new SolidColorBrush(Color.FromArgb(rgb.A, rgb.R, rgb.G, rgb.B)));
|
||||||
|
}
|
||||||
|
|
||||||
if (imageSource is not null)
|
if (imageSource is not null)
|
||||||
{
|
{
|
||||||
ImageBrush? imageBrush = templateSettings.ActualImageBrush;
|
ImageBrush? imageBrush = templateSettings.ActualImageBrush;
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
using Avalonia.Media;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Toolkit.UI.Controls.Avalonia;
|
||||||
|
|
||||||
|
public class PersonPictureColourGenerator
|
||||||
|
{
|
||||||
|
private readonly float hue;
|
||||||
|
private readonly float saturation;
|
||||||
|
private readonly float lightness;
|
||||||
|
private const float minLightness = 0.2f;
|
||||||
|
private const float maxLightness = 0.8f;
|
||||||
|
|
||||||
|
public PersonPictureColourGenerator(float hue = 210,
|
||||||
|
float saturation = 0.8f,
|
||||||
|
float lightness = 0.6f)
|
||||||
|
{
|
||||||
|
this.hue = hue;
|
||||||
|
this.saturation = saturation;
|
||||||
|
this.lightness = lightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color Create(string input)
|
||||||
|
{
|
||||||
|
byte[] hashBytes = GetHash(input);
|
||||||
|
|
||||||
|
float h = (hashBytes[0] + hue) % 360;
|
||||||
|
float s = (hashBytes[1] / 255.0f) * saturation;
|
||||||
|
float l = EnsureNonExtremeLightness((hashBytes[2] / 255.0f) * lightness);
|
||||||
|
|
||||||
|
(byte r, byte g, byte b) = HslToRgb(h, s, l);
|
||||||
|
|
||||||
|
return Color.FromRgb(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] GetHash(string input) =>
|
||||||
|
SHA256.HashData(Encoding.UTF8.GetBytes(input));
|
||||||
|
|
||||||
|
private float EnsureNonExtremeLightness(float calculatedLightness) =>
|
||||||
|
calculatedLightness < minLightness ? minLightness : calculatedLightness > maxLightness ?
|
||||||
|
maxLightness : calculatedLightness;
|
||||||
|
|
||||||
|
private (byte r, byte g, byte b) HslToRgb(float h, float s, float l)
|
||||||
|
{
|
||||||
|
h /= 360;
|
||||||
|
float r, g, b;
|
||||||
|
|
||||||
|
if (s == 0)
|
||||||
|
{
|
||||||
|
r = g = b = l;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
|
||||||
|
float p = 2 * l - q;
|
||||||
|
|
||||||
|
r = HueToRgb(p, q, h + 1.0f / 3.0f);
|
||||||
|
g = HueToRgb(p, q, h);
|
||||||
|
b = HueToRgb(p, q, h - 1.0f / 3.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((byte)(r * 255), (byte)(g * 255), (byte)(b * 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
private float HueToRgb(float p, float q, float t)
|
||||||
|
{
|
||||||
|
if (t < 0) t += 1;
|
||||||
|
if (t > 1) t -= 1;
|
||||||
|
if (t < 1.0f / 6.0f) return p + (q - p) * 6 * t;
|
||||||
|
if (t < 1.0f / 2.0f) return q;
|
||||||
|
if (t < 2.0f / 3.0f) return p + (q - p) * (2.0f / 3.0f - t) * 6;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user