mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-24 02:09:37 +08:00
Add SkeletonAvatar
This commit is contained in:
+1
@@ -661,6 +661,7 @@ namespace AtomUI.Theme.Styling
|
||||
|
||||
public static class SkeletonTokenKey
|
||||
{
|
||||
public static readonly TokenResourceKey AvatarMarginRight = new TokenResourceKey("Skeleton.AvatarMarginRight");
|
||||
public static readonly TokenResourceKey BlockRadius = new TokenResourceKey("Skeleton.BlockRadius");
|
||||
public static readonly TokenResourceKey GradientFromColor = new TokenResourceKey("Skeleton.GradientFromColor");
|
||||
public static readonly TokenResourceKey GradientToColor = new TokenResourceKey("Skeleton.GradientToColor");
|
||||
|
||||
@@ -17,9 +17,6 @@ public abstract class AbstractSkeleton : TemplatedControl
|
||||
public static readonly StyledProperty<bool> IsActiveProperty =
|
||||
AvaloniaProperty.Register<AbstractSkeleton, bool>(nameof(IsActive));
|
||||
|
||||
// public static readonly StyledProperty<SizeType> SizeTypeProperty =
|
||||
// SizeTypeAwareControlProperty.SizeTypeProperty.AddOwner<AbstractSkeleton>();
|
||||
|
||||
public static readonly StyledProperty<TimeSpan> MotionDurationProperty =
|
||||
MotionAwareControlProperty.MotionDurationProperty.AddOwner<AbstractSkeleton>();
|
||||
|
||||
@@ -31,13 +28,7 @@ public abstract class AbstractSkeleton : TemplatedControl
|
||||
get => GetValue(IsActiveProperty);
|
||||
set => SetValue(IsActiveProperty, value);
|
||||
}
|
||||
|
||||
// public SizeType SizeType
|
||||
// {
|
||||
// get => GetValue(SizeTypeProperty);
|
||||
// set => SetValue(SizeTypeProperty, value);
|
||||
// }
|
||||
//
|
||||
|
||||
public TimeSpan MotionDuration
|
||||
{
|
||||
get => GetValue(MotionDurationProperty);
|
||||
@@ -117,19 +108,19 @@ public abstract class AbstractSkeleton : TemplatedControl
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (change.Property == LoadingBackgroundStartProperty ||
|
||||
change.Property == LoadingBackgroundMiddleProperty ||
|
||||
change.Property == LoadingBackgroundEndProperty ||
|
||||
change.Property == MotionDurationProperty)
|
||||
{
|
||||
if (!IsFollowMode)
|
||||
|
||||
if (change.Property == LoadingBackgroundStartProperty ||
|
||||
change.Property == LoadingBackgroundMiddleProperty ||
|
||||
change.Property == LoadingBackgroundEndProperty ||
|
||||
change.Property == MotionDurationProperty)
|
||||
{
|
||||
BuildActiveAnimation(true);
|
||||
if (IsActive)
|
||||
if (!IsFollowMode)
|
||||
{
|
||||
StartActiveAnimation();
|
||||
BuildActiveAnimation(true);
|
||||
if (IsActive)
|
||||
{
|
||||
StartActiveAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,160 @@
|
||||
using System.Diagnostics;
|
||||
using AtomUI.Controls.Themes;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public class Skeleton : ContentControl
|
||||
public class Skeleton : AbstractSkeleton, IControlSharedTokenResourcesHost
|
||||
{
|
||||
#region 公共属性定义
|
||||
|
||||
public static readonly StyledProperty<bool> IsLoadingProperty =
|
||||
AvaloniaProperty.Register<Skeleton, bool>(nameof(IsLoading));
|
||||
|
||||
public static readonly StyledProperty<bool> IsShowAvatarProperty =
|
||||
AvaloniaProperty.Register<Skeleton, bool>(nameof(IsShowAvatar));
|
||||
|
||||
public static readonly StyledProperty<bool> IsShowParagraphProperty =
|
||||
AvaloniaProperty.Register<Skeleton, bool>(nameof(IsShowParagraph), true);
|
||||
|
||||
public static readonly StyledProperty<bool> IsShowTitleProperty =
|
||||
AvaloniaProperty.Register<Skeleton, bool>(nameof(IsShowTitle), true);
|
||||
|
||||
public static readonly StyledProperty<bool> IsRoundProperty =
|
||||
SkeletonLine.IsRoundProperty.AddOwner<Skeleton>();
|
||||
|
||||
public static readonly StyledProperty<SkeletonWidth> TitleWidthProperty =
|
||||
AvaloniaProperty.Register<Skeleton, SkeletonWidth>(nameof(TitleWidth), new SkeletonWidth(50, SkeletonUnitType.Percentage));
|
||||
|
||||
public static readonly StyledProperty<int> ParagraphRowsProperty =
|
||||
AvaloniaProperty.Register<Skeleton, int>(nameof(ParagraphRows), 2, validate: i => i >= 1);
|
||||
|
||||
public static readonly StyledProperty<SkeletonWidth> ParagraphLastLineWidthProperty =
|
||||
AvaloniaProperty.Register<Skeleton, SkeletonWidth>(nameof(ParagraphLastLineWidth), new SkeletonWidth(61.0, SkeletonUnitType.Percentage));
|
||||
|
||||
public static readonly StyledProperty<List<SkeletonWidth>?> ParagraphLineWidthsProperty =
|
||||
AvaloniaProperty.Register<Skeleton, List<SkeletonWidth>?>(nameof(ParagraphLineWidths));
|
||||
|
||||
public static readonly StyledProperty<AvatarShape> AvatarShapeProperty =
|
||||
AvaloniaProperty.Register<Skeleton, AvatarShape>(nameof(AvatarShape), AvatarShape.Circle);
|
||||
|
||||
public static readonly StyledProperty<AvatarSizeType> AvatarSizeTypeProperty =
|
||||
AvaloniaProperty.Register<Skeleton, AvatarSizeType>(nameof(AvatarSizeType), AvatarSizeType.Middle);
|
||||
|
||||
public static readonly StyledProperty<double> AvatarSizeProperty =
|
||||
AvaloniaProperty.Register<Skeleton, double>(nameof(AvatarSizeType), Double.NaN);
|
||||
|
||||
public bool IsLoading
|
||||
{
|
||||
get => GetValue(IsLoadingProperty);
|
||||
set => SetValue(IsLoadingProperty, value);
|
||||
}
|
||||
|
||||
public bool IsShowAvatar
|
||||
{
|
||||
get => GetValue(IsShowAvatarProperty);
|
||||
set => SetValue(IsShowAvatarProperty, value);
|
||||
}
|
||||
|
||||
public bool IsShowParagraph
|
||||
{
|
||||
get => GetValue(IsShowParagraphProperty);
|
||||
set => SetValue(IsShowParagraphProperty, value);
|
||||
}
|
||||
|
||||
public bool IsShowTitle
|
||||
{
|
||||
get => GetValue(IsShowTitleProperty);
|
||||
set => SetValue(IsShowTitleProperty, value);
|
||||
}
|
||||
|
||||
public bool IsRound
|
||||
{
|
||||
get => GetValue(IsRoundProperty);
|
||||
set => SetValue(IsRoundProperty, value);
|
||||
}
|
||||
|
||||
public SkeletonWidth TitleWidth
|
||||
{
|
||||
get => GetValue(TitleWidthProperty);
|
||||
set => SetValue(TitleWidthProperty, value);
|
||||
}
|
||||
|
||||
public int ParagraphRows
|
||||
{
|
||||
get => GetValue(ParagraphRowsProperty);
|
||||
set => SetValue(ParagraphRowsProperty, value);
|
||||
}
|
||||
|
||||
public SkeletonWidth ParagraphLastLineWidth
|
||||
{
|
||||
get => GetValue(ParagraphLastLineWidthProperty);
|
||||
set => SetValue(ParagraphLastLineWidthProperty, value);
|
||||
}
|
||||
|
||||
public List<SkeletonWidth>? ParagraphLineWidths
|
||||
{
|
||||
get => GetValue(ParagraphLineWidthsProperty);
|
||||
set => SetValue(ParagraphLineWidthsProperty, value);
|
||||
}
|
||||
|
||||
public AvatarSizeType AvatarSizeType
|
||||
{
|
||||
get => GetValue(AvatarSizeTypeProperty);
|
||||
set => SetValue(AvatarSizeTypeProperty, value);
|
||||
}
|
||||
|
||||
public AvatarShape AvatarShape
|
||||
{
|
||||
get => GetValue(AvatarShapeProperty);
|
||||
set => SetValue(AvatarShapeProperty, value);
|
||||
}
|
||||
|
||||
public double AvatarSize
|
||||
{
|
||||
get => GetValue(AvatarSizeProperty);
|
||||
set => SetValue(AvatarSizeProperty, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 内部属性定义
|
||||
|
||||
Control IControlSharedTokenResourcesHost.HostControl => this;
|
||||
string IControlSharedTokenResourcesHost.TokenId => SkeletonToken.ID;
|
||||
|
||||
#endregion
|
||||
|
||||
public Skeleton()
|
||||
{
|
||||
this.RegisterResources();
|
||||
}
|
||||
|
||||
private SkeletonAvatar? _avatar;
|
||||
private SkeletonTitle? _title;
|
||||
private SkeletonParagraph? _paragraph;
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
_avatar = e.NameScope.Find<SkeletonAvatar>(SkeletonThemeConstants.AvatarPart);
|
||||
_title = e.NameScope.Find<SkeletonTitle>(SkeletonThemeConstants.TitlePart);
|
||||
_paragraph = e.NameScope.Find<SkeletonParagraph>(SkeletonThemeConstants.ParagraphPart);
|
||||
|
||||
Debug.Assert(_avatar != null);
|
||||
Debug.Assert(_title != null);
|
||||
Debug.Assert(_paragraph != null);
|
||||
|
||||
_avatar.Follow(this);
|
||||
_title.Follow(this);
|
||||
_paragraph.Follow(this);
|
||||
|
||||
if (IsActive)
|
||||
{
|
||||
StartActiveAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,117 @@
|
||||
using System.Diagnostics;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Data;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public class SkeletonAvatar : AbstractSkeleton
|
||||
public class SkeletonAvatar : AbstractSkeleton, IControlSharedTokenResourcesHost
|
||||
{
|
||||
#region 公共属性定义
|
||||
public static readonly StyledProperty<AvatarShape> ShapeProperty =
|
||||
AvaloniaProperty.Register<SkeletonAvatar, AvatarShape>(nameof(AvatarShape), AvatarShape.Circle);
|
||||
|
||||
public static readonly StyledProperty<AvatarSizeType> SizeTypeProperty =
|
||||
Avatar.SizeTypeProperty.AddOwner<SkeletonAvatar>();
|
||||
|
||||
public static readonly StyledProperty<double> SizeProperty =
|
||||
AvaloniaProperty.Register<SkeletonAvatar, double>(nameof(Size), Double.NaN);
|
||||
|
||||
public AvatarShape Shape
|
||||
{
|
||||
get => GetValue(ShapeProperty);
|
||||
set => SetValue(ShapeProperty, value);
|
||||
}
|
||||
|
||||
public AvatarSizeType SizeType
|
||||
{
|
||||
get => GetValue(SizeTypeProperty);
|
||||
set => SetValue(SizeTypeProperty, value);
|
||||
}
|
||||
|
||||
public double Size
|
||||
{
|
||||
get => GetValue(SizeProperty);
|
||||
set => SetValue(SizeProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 内部属性定义
|
||||
|
||||
Control IControlSharedTokenResourcesHost.HostControl => this;
|
||||
string IControlSharedTokenResourcesHost.TokenId => SkeletonToken.ID;
|
||||
|
||||
#endregion
|
||||
|
||||
private AvatarSizeType? _originSizeType;
|
||||
|
||||
public SkeletonAvatar()
|
||||
{
|
||||
this.RegisterResources();
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
if (change.Property == SizeProperty)
|
||||
{
|
||||
if (!double.IsNaN(Size))
|
||||
{
|
||||
_originSizeType = SizeType;
|
||||
SizeType = AvatarSizeType.Custom;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_originSizeType.HasValue)
|
||||
{
|
||||
SizeType = _originSizeType.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (change.Property == SizeTypeProperty)
|
||||
{
|
||||
ConfigureSize();
|
||||
}
|
||||
else if (change.Property == ShapeProperty)
|
||||
{
|
||||
ConfigureShape();
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureShape()
|
||||
{
|
||||
if (Shape == AvatarShape.Circle)
|
||||
{
|
||||
SetValue(CornerRadiusProperty, new CornerRadius(Width / 2), BindingPriority.Template);
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureSize()
|
||||
{
|
||||
if (SizeType == AvatarSizeType.Custom)
|
||||
{
|
||||
Debug.Assert(!double.IsNaN(Size));
|
||||
// 不影响模板设置
|
||||
SetValue(WidthProperty, Size, BindingPriority.Template);
|
||||
SetValue(HeightProperty, Size, BindingPriority.Template);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
ConfigureShape();
|
||||
ConfigureSize();
|
||||
if (!IsFollowMode)
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
StartActiveAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using AtomUI.Controls.Themes;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
@@ -6,7 +8,7 @@ using Avalonia.VisualTree;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public class SkeletonParagraph : AbstractSkeleton
|
||||
public class SkeletonParagraph : AbstractSkeleton, IControlSharedTokenResourcesHost
|
||||
{
|
||||
#region 公共属性定义
|
||||
|
||||
@@ -19,6 +21,9 @@ public class SkeletonParagraph : AbstractSkeleton
|
||||
public static readonly StyledProperty<int> RowsProperty =
|
||||
AvaloniaProperty.Register<SkeletonParagraph, int>(nameof(Rows), 2, validate: i => i >= 1);
|
||||
|
||||
public static readonly StyledProperty<bool> IsRoundProperty =
|
||||
SkeletonLine.IsRoundProperty.AddOwner<SkeletonParagraph>();
|
||||
|
||||
public SkeletonWidth LastLineWidth
|
||||
{
|
||||
get => GetValue(LastLineWidthProperty);
|
||||
@@ -37,10 +42,28 @@ public class SkeletonParagraph : AbstractSkeleton
|
||||
set => SetValue(RowsProperty, value);
|
||||
}
|
||||
|
||||
public bool IsRound
|
||||
{
|
||||
get => GetValue(IsRoundProperty);
|
||||
set => SetValue(IsRoundProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 内部属性定义
|
||||
|
||||
Control IControlSharedTokenResourcesHost.HostControl => this;
|
||||
string IControlSharedTokenResourcesHost.TokenId => SkeletonToken.ID;
|
||||
|
||||
#endregion
|
||||
|
||||
private StackPanel? _linesLayout;
|
||||
|
||||
public SkeletonParagraph()
|
||||
{
|
||||
this.RegisterResources();
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
|
||||
@@ -1,9 +1,25 @@
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Utils;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public class SkeletonTitle : SkeletonLine
|
||||
public class SkeletonTitle : SkeletonLine, IControlSharedTokenResourcesHost
|
||||
{
|
||||
#region 内部属性定义
|
||||
|
||||
Control IControlSharedTokenResourcesHost.HostControl => this;
|
||||
string IControlSharedTokenResourcesHost.TokenId => SkeletonToken.ID;
|
||||
|
||||
#endregion
|
||||
|
||||
static SkeletonTitle()
|
||||
{
|
||||
LineWidthProperty.OverrideDefaultValue<SkeletonTitle>(new SkeletonWidth(50, SkeletonUnitType.Percentage));
|
||||
}
|
||||
|
||||
public SkeletonTitle()
|
||||
{
|
||||
this.RegisterResources();
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,11 @@ internal class SkeletonToken : AbstractControlDesignToken
|
||||
/// </summary>
|
||||
public Thickness ParagraphMarginTop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像骨架屏右间距
|
||||
/// </summary>
|
||||
public Thickness AvatarMarginRight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 段落骨架屏单行高度
|
||||
/// Line height of paragraph skeleton
|
||||
@@ -74,6 +79,7 @@ internal class SkeletonToken : AbstractControlDesignToken
|
||||
TitleHeight = SharedToken.ControlHeight / 2;
|
||||
BlockRadius = SharedToken.BorderRadiusSM;
|
||||
ParagraphMarginTop = new Thickness(0, SharedToken.UniformlyMarginLG + SharedToken.UniformlyMarginXXS, 0, 0);
|
||||
AvatarMarginRight = new Thickness(0, 0, SharedToken.UniformlyMargin, 0);
|
||||
ParagraphLineHeight = SharedToken.ControlHeight / 2;
|
||||
ParagraphLineRoundCornerRadius = new CornerRadius(ParagraphLineHeight / 2);
|
||||
LoadingMotionDuration = TimeSpan.FromSeconds(1.4);
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<ResourceDictionary
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:atom="https://atomui.net"
|
||||
x:ClassModifier="internal">
|
||||
<ControlTheme x:Key="{x:Type atom:SkeletonAvatar}" TargetType="atom:SkeletonAvatar">
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<Panel>
|
||||
<Border Name="{x:Static atom:SkeletonThemeConstants.ActiveAnimationLayerPart}"
|
||||
Background="{TemplateBinding AnimationLayerFill}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
IsVisible="{TemplateBinding IsActive}"/>
|
||||
<Border Name="Avatar"
|
||||
Background="{TemplateBinding Background}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
IsVisible="{TemplateBinding IsActive, Converter={x:Static BoolConverters.Not}}"/>
|
||||
</Panel>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
|
||||
<Setter Property="MotionDuration" Value="{DynamicResource {x:Static atom:SkeletonTokenKey.LoadingMotionDuration}}"/>
|
||||
<Setter Property="LoadingBackgroundStart" Value="{DynamicResource {x:Static atom:SkeletonTokenKey.LoadingBackgroundStart}}"/>
|
||||
<Setter Property="LoadingBackgroundMiddle" Value="{DynamicResource {x:Static atom:SkeletonTokenKey.LoadingBackgroundMiddle}}"/>
|
||||
<Setter Property="LoadingBackgroundEnd" Value="{DynamicResource {x:Static atom:SkeletonTokenKey.LoadingBackgroundEnd}}"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Top" />
|
||||
<Setter Property="Background" Value="{DynamicResource {x:Static atom:SkeletonTokenKey.GradientFromColor}}" />
|
||||
|
||||
<Style Selector="^[SizeType=Large]">
|
||||
<Setter Property="Width" Value="{DynamicResource {x:Static atom:SharedTokenKey.ControlHeightLG}}" />
|
||||
<Setter Property="Height" Value="{DynamicResource {x:Static atom:SharedTokenKey.ControlHeightLG}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[SizeType=Middle]">
|
||||
<Setter Property="Width" Value="{DynamicResource {x:Static atom:SharedTokenKey.ControlHeight}}" />
|
||||
<Setter Property="Height" Value="{DynamicResource {x:Static atom:SharedTokenKey.ControlHeight}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[SizeType=Small]">
|
||||
<Setter Property="Width" Value="{DynamicResource {x:Static atom:SharedTokenKey.ControlHeightSM}}" />
|
||||
<Setter Property="Height" Value="{DynamicResource {x:Static atom:SharedTokenKey.ControlHeightSM}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[Shape=Square]">
|
||||
<Style Selector="^[SizeType=Large]">
|
||||
<Setter Property="CornerRadius" Value="{DynamicResource {x:Static atom:SharedTokenKey.BorderRadiusLG}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[SizeType=Middle]">
|
||||
<Setter Property="CornerRadius" Value="{DynamicResource {x:Static atom:SharedTokenKey.BorderRadius}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[SizeType=Small]">
|
||||
<Setter Property="CornerRadius" Value="{DynamicResource {x:Static atom:SharedTokenKey.BorderRadiusSM}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[SizeType=Custom]">
|
||||
<Setter Property="CornerRadius" Value="{DynamicResource {x:Static atom:SharedTokenKey.BorderRadius}}" />
|
||||
</Style>
|
||||
</Style>
|
||||
</ControlTheme>
|
||||
</ResourceDictionary>
|
||||
@@ -11,7 +11,8 @@
|
||||
<Rectangle Name="{x:Static atom:SkeletonThemeConstants.ActiveAnimationLayerPart}"
|
||||
Fill="{TemplateBinding AnimationLayerFill}"
|
||||
IsVisible="{TemplateBinding IsActive}"/>
|
||||
<Rectangle Name="Line"/>
|
||||
<Rectangle Name="Line"
|
||||
IsVisible="{TemplateBinding IsActive, Converter={x:Static BoolConverters.Not}}"/>
|
||||
</Panel>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
|
||||
@@ -3,4 +3,75 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:atom="https://atomui.net"
|
||||
x:ClassModifier="internal">
|
||||
<ControlTheme x:Key="{x:Type atom:Skeleton}" TargetType="atom:Skeleton">
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<DockPanel LastChildFill="True">
|
||||
<atom:SkeletonAvatar DockPanel.Dock="Left"
|
||||
Name="{x:Static atom:SkeletonThemeConstants.AvatarPart}"
|
||||
SizeType="{TemplateBinding AvatarSizeType}"
|
||||
Shape="{TemplateBinding AvatarShape}"
|
||||
Size="{TemplateBinding AvatarSize}"
|
||||
IsVisible="{TemplateBinding IsShowAvatar}"
|
||||
IsActive="{TemplateBinding IsActive}"/>
|
||||
<StackPanel Orientation="Vertical"
|
||||
Name="{x:Static atom:SkeletonThemeConstants.ContentPart}">
|
||||
<atom:SkeletonTitle Name="{x:Static atom:SkeletonThemeConstants.TitlePart}"
|
||||
IsVisible="{TemplateBinding IsShowTitle}"
|
||||
IsRound="{TemplateBinding IsRound}"
|
||||
LineWidth="{TemplateBinding TitleWidth}"
|
||||
IsActive="{TemplateBinding IsActive}"/>
|
||||
<atom:SkeletonParagraph Name="{x:Static atom:SkeletonThemeConstants.ParagraphPart}"
|
||||
IsVisible="{TemplateBinding IsShowParagraph}"
|
||||
IsRound="{TemplateBinding IsRound}"
|
||||
Rows="{TemplateBinding ParagraphRows}"
|
||||
LastLineWidth="{TemplateBinding ParagraphLastLineWidth}"
|
||||
LineWidths="{TemplateBinding ParagraphLineWidths}"
|
||||
IsActive="{TemplateBinding IsActive}"/>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
|
||||
<Setter Property="MotionDuration" Value="{DynamicResource {x:Static atom:SkeletonTokenKey.LoadingMotionDuration}}"/>
|
||||
<Setter Property="LoadingBackgroundStart" Value="{DynamicResource {x:Static atom:SkeletonTokenKey.LoadingBackgroundStart}}"/>
|
||||
<Setter Property="LoadingBackgroundMiddle" Value="{DynamicResource {x:Static atom:SkeletonTokenKey.LoadingBackgroundMiddle}}"/>
|
||||
<Setter Property="LoadingBackgroundEnd" Value="{DynamicResource {x:Static atom:SkeletonTokenKey.LoadingBackgroundEnd}}"/>
|
||||
|
||||
<Setter Property="AvatarSizeType" Value="Large"/>
|
||||
<Setter Property="AvatarShape" Value="Circle"/>
|
||||
|
||||
<Style Selector="^ /template/ atom|SkeletonAvatar">
|
||||
<Setter Property="Margin" Value="{DynamicResource {x:Static atom:SkeletonTokenKey.AvatarMarginRight}}"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsShowTitle=True][IsShowParagraph=False]">
|
||||
<Setter Property="AvatarShape" Value="Square"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsShowAvatar=False][IsShowParagraph=True]">
|
||||
<Setter Property="TitleWidth" Value="38%"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsShowAvatar=True][IsShowParagraph=True]">
|
||||
<Setter Property="TitleWidth" Value="50%"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsShowAvatar=False][IsShowTitle=False]">
|
||||
<Setter Property="ParagraphLastLineWidth" Value="61%"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsShowTitle=True]">
|
||||
<Style Selector="^ /template/ atom|SkeletonParagraph">
|
||||
<Setter Property="Margin" Value="{DynamicResource {x:Static atom:SkeletonTokenKey.ParagraphMarginTop}}"/>
|
||||
</Style>
|
||||
</Style>
|
||||
|
||||
<Setter Property="ParagraphRows" Value="2"/>
|
||||
|
||||
<Style Selector="^[IsShowAvatar=False][IsShowTitle=True]">
|
||||
<Setter Property="ParagraphRows" Value="3"/>
|
||||
</Style>
|
||||
|
||||
</ControlTheme>
|
||||
</ResourceDictionary>
|
||||
@@ -3,6 +3,10 @@ namespace AtomUI.Controls.Themes;
|
||||
internal static class SkeletonThemeConstants
|
||||
{
|
||||
public const string ActiveAnimationLayerPart = "PART_ActiveAnimationLayer";
|
||||
public const string AvatarPart = "PART_Avatar";
|
||||
public const string TitlePart = "PART_Title";
|
||||
public const string ContentPart = "PART_Content";
|
||||
public const string ParagraphPart = "PART_Paragraph";
|
||||
}
|
||||
|
||||
internal static class SkeletonParagraphThemeConstants
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceInclude Source="SkeletonTheme.axaml" />
|
||||
<ResourceInclude Source="SkeletonLineTheme.axaml" />
|
||||
<ResourceInclude Source="SkeletonAvatarTheme.axaml" />
|
||||
<ResourceInclude Source="SkeletonParagraphTheme.axaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
Reference in New Issue
Block a user