feat: 调整Timeline样式

This commit is contained in:
liuyushuai 2024-09-06 09:13:32 +08:00
parent 203b835b42
commit 48e4896ea0
7 changed files with 123 additions and 42 deletions

View File

@ -69,17 +69,17 @@
<atom:Timeline Pending="Recording..." Reverse="True">
<atom:TimelineItem Label="2024-01-01">
<TextBlock>
2024-01-01 AtomUI Officially Initiated
2024-01-01 AtomUI Officially Initiated. 1
</TextBlock>
</atom:TimelineItem>
<atom:TimelineItem Label="2024-08-12">
<TextBlock>
2024-01-01 AtomUI Officially Initiated
2024-01-01 AtomUI Officially Initiated. 2
</TextBlock>
</atom:TimelineItem>
<atom:TimelineItem Label="2024-10-01">
<TextBlock>
2024-01-01 AtomUI Officially Initiated
2024-01-01 AtomUI Officially Initiated. 3
</TextBlock>
</atom:TimelineItem>
</atom:Timeline>

View File

@ -529,7 +529,10 @@ namespace AtomUI.Theme.Styling
public static readonly TokenResourceKey DotBg = new TokenResourceKey("Timeline.DotBg", "AtomUI.Token");
public static readonly TokenResourceKey ItemBgColor = new TokenResourceKey("Timeline.ItemBgColor", "AtomUI.Token");
public static readonly TokenResourceKey ItemPaddingBottom = new TokenResourceKey("Timeline.ItemPaddingBottom", "AtomUI.Token");
public static readonly TokenResourceKey ContentMargin = new TokenResourceKey("Timeline.ContentMargin", "AtomUI.Token");
public static readonly TokenResourceKey RightMargin = new TokenResourceKey("Timeline.RightMargin", "AtomUI.Token");
public static readonly TokenResourceKey LeftMargin = new TokenResourceKey("Timeline.LeftMargin", "AtomUI.Token");
public static readonly TokenResourceKey LastItemContentMinHeight = new TokenResourceKey("Timeline.LastItemContentMinHeight", "AtomUI.Token");
public static readonly TokenResourceKey FontSize = new TokenResourceKey("Timeline.FontSize", "AtomUI.Token");
}
public static class ToolTipTokenResourceKey

View File

@ -3,6 +3,7 @@ using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using AtomUI.Utils;
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
@ -35,7 +36,11 @@ public class Timeline : ItemsControl
public bool Reverse
{
get => GetValue(ReverseProperty);
set => SetValue(ReverseProperty, value);
set
{
SetValue(ReverseProperty, value);
// Items.Reverse();
}
}
protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey)
@ -56,7 +61,9 @@ public class Timeline : ItemsControl
{
timelineItem.Index = index;
timelineItem.Mode = Mode;
timelineItem.IsLast = Items.Count - 1 == index;
BindUtils.RelayBind(this, ModeProperty, timelineItem, TimelineItem.ModeProperty);
BindUtils.RelayBind(this, ReverseProperty, timelineItem, TimelineItem.ReverseProperty);
foreach (var child in Items)
{
if (child is TimelineItem otherItem)

View File

@ -12,7 +12,9 @@ public class TimelineItem : ContentControl
public static readonly StyledProperty<int> IndexProperty = AvaloniaProperty.Register<TimelineItem, int>(nameof(Index), 0);
public static readonly StyledProperty<string> ModeProperty = AvaloniaProperty.Register<TimelineItem, string>(nameof(Mode), "left");
public static readonly StyledProperty<string> ColorProperty = AvaloniaProperty.Register<TimelineItem, string>(nameof(Color), "blue");
public static readonly StyledProperty<bool> HasLabelProperty = AvaloniaProperty.Register<TimelineItem, bool>(nameof(Color), false);
public static readonly StyledProperty<bool> HasLabelProperty = AvaloniaProperty.Register<TimelineItem, bool>(nameof(HasLabel), false);
public static readonly StyledProperty<bool> IsLastProperty = AvaloniaProperty.Register<TimelineItem, bool>(nameof(IsLast), false);
public static readonly StyledProperty<bool> ReverseProperty = AvaloniaProperty.Register<TimelineItem, bool>(nameof(Reverse), false);
public int Index
{
@ -43,4 +45,16 @@ public class TimelineItem : ContentControl
get => GetValue(HasLabelProperty);
set => SetValue(HasLabelProperty, value);
}
public bool IsLast
{
get => GetValue(IsLastProperty);
set => SetValue(IsLastProperty, value);
}
public bool Reverse
{
get => GetValue(ReverseProperty);
set => SetValue(ReverseProperty, value);
}
}

View File

@ -37,12 +37,15 @@ internal class TimelineItemTheme : BaseControlTheme
var contentIndex = 2;
var labelTextAlign = HorizontalAlignment.Right;
var contentTextAlign = HorizontalAlignment.Right;
CalculateGridIndex(timelineItem, out labelIndex, out splitIndex, out contentIndex, out labelTextAlign, out contentTextAlign);
System.Console.WriteLine("TimelineItem Mode: {0},hasLabel: {1}, index: {2} labelIndex: {3} splitIndex:{4} contentIndex{5}", timelineItem.Mode, timelineItem.HasLabel, timelineItem.Index,labelIndex,splitIndex,contentIndex);
CalculateGridIndex(timelineItem, out labelIndex, out splitIndex, out contentIndex, out labelTextAlign,
out contentTextAlign);
System.Console.WriteLine(
"TimelineItem Mode: {0},hasLabel: {1}, index: {2} labelIndex: {3} splitIndex:{4} contentIndex{5}",
timelineItem.Mode, timelineItem.HasLabel, timelineItem.Index, labelIndex, splitIndex, contentIndex);
var columnDefinition = CalculateGridColumn(timelineItem, labelIndex);
var grid = new Grid()
{
Name = GridPart,
@ -52,7 +55,7 @@ internal class TimelineItemTheme : BaseControlTheme
new RowDefinition(GridLength.Star),
},
};
if (timelineItem.HasLabel)
{
var labelBlock = new TextBlock()
@ -60,18 +63,28 @@ internal class TimelineItemTheme : BaseControlTheme
Name = LabelPart,
VerticalAlignment = VerticalAlignment.Top,
HorizontalAlignment = labelTextAlign,
Margin = new Thickness(0,0,14,0)
};
CreateTemplateParentBinding(labelBlock, TextBlock.TextProperty, TimelineItem.LabelProperty);
var labelStyle = new Style(selector => selector.Nesting().Template().Name(LabelPart));
labelStyle.Add(ContentPresenter.MarginProperty, TimelineTokenResourceKey.ContentMargin);
labelStyle.Add(ContentPresenter.FontSizeProperty, TimelineTokenResourceKey.FontSize);
// todo 未生效
if (labelIndex == 0)
{
labelStyle.Add(ContentPresenter.MarginProperty, TimelineTokenResourceKey.RightMargin);
}
else
{
labelStyle.Add(ContentPresenter.MarginProperty, TimelineTokenResourceKey.LeftMargin);
}
Grid.SetColumn(labelBlock, labelIndex);
grid.Children.Add(labelBlock);
}
var splitPanel = new DockPanel()
{
Width = 10,
@ -86,7 +99,7 @@ internal class TimelineItemTheme : BaseControlTheme
Name = SplitHeadPart,
};
var contentPresenterStyle = new Style(selector => selector.Nesting().Template().Name(SplitHeadPart));
if (timelineItem.Color.StartsWith("#"))
{
try
@ -97,7 +110,8 @@ internal class TimelineItemTheme : BaseControlTheme
}
catch (Exception)
{
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty, GlobalTokenResourceKey.ColorPrimary);
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty,
GlobalTokenResourceKey.ColorPrimary);
}
}
else
@ -106,23 +120,28 @@ internal class TimelineItemTheme : BaseControlTheme
switch (timelineItem.Color)
{
case "blue":
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty, GlobalTokenResourceKey.ColorPrimary);
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty,
GlobalTokenResourceKey.ColorPrimary);
break;
case "green":
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty, GlobalTokenResourceKey.ColorSuccess);
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty,
GlobalTokenResourceKey.ColorSuccess);
break;
case "red":
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty, GlobalTokenResourceKey.ColorError);
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty,
GlobalTokenResourceKey.ColorError);
break;
case "gray":
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty, GlobalTokenResourceKey.ColorTextDisabled);
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty,
GlobalTokenResourceKey.ColorTextDisabled);
break;
default:
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty, GlobalTokenResourceKey.ColorPrimary);
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty,
GlobalTokenResourceKey.ColorPrimary);
break;
}
}
}
contentPresenterStyle.Add(ContentPresenter.BackgroundProperty, TimelineTokenResourceKey.DotBg);
Add(contentPresenterStyle);
@ -133,10 +152,16 @@ internal class TimelineItemTheme : BaseControlTheme
{
Name = SplitLinePart,
};
contentPresenterStyle = new Style(selector => selector.Nesting().Template().Name(SplitLinePart));
contentPresenterStyle.Add(ContentPresenter.BackgroundProperty, TimelineTokenResourceKey.TailColor);
contentPresenterStyle.Add(ContentPresenter.WidthProperty, TimelineTokenResourceKey.TailWidth);
Add(contentPresenterStyle);
var borderStyle = new Style(selector => selector.Nesting().Template().Name(SplitLinePart));
borderStyle.Add(ContentPresenter.BackgroundProperty, TimelineTokenResourceKey.TailColor);
borderStyle.Add(ContentPresenter.WidthProperty, TimelineTokenResourceKey.TailWidth);
borderStyle.Add(ContentPresenter.PaddingProperty, TimelineTokenResourceKey.ItemPaddingBottom);
if (timelineItem.IsLast)
{
borderStyle.Add(ContentPresenter.MinHeightProperty, TimelineTokenResourceKey.LastItemContentMinHeight);
}
Add(borderStyle);
splitPanel.Children.Add(border);
@ -154,7 +179,16 @@ internal class TimelineItemTheme : BaseControlTheme
TimelineItem.ContentProperty);
contentPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ItemsPresenterPart));
contentPresenterStyle.Add(ContentPresenter.MarginProperty, TimelineTokenResourceKey.ContentMargin);
contentPresenterStyle.Add(ContentPresenter.FontSizeProperty, TimelineTokenResourceKey.FontSize);
if (contentIndex == 0)
{
contentPresenterStyle.Add(ContentPresenter.MarginProperty, TimelineTokenResourceKey.RightMargin);
}
else
{
contentPresenterStyle.Add(ContentPresenter.MarginProperty, TimelineTokenResourceKey.LeftMargin);
}
Add(contentPresenterStyle);
Grid.SetColumn(contentPresenter, contentIndex);
@ -163,7 +197,8 @@ internal class TimelineItemTheme : BaseControlTheme
});
}
private void CalculateGridIndex(TimelineItem timelineItem, out int labelIndex, out int splitIndex, out int contentIndex, out HorizontalAlignment labelTextAlign, out HorizontalAlignment contentTextAlign)
private void CalculateGridIndex(TimelineItem timelineItem, out int labelIndex, out int splitIndex,
out int contentIndex, out HorizontalAlignment labelTextAlign, out HorizontalAlignment contentTextAlign)
{
labelIndex = 0;
splitIndex = 1;
@ -185,7 +220,7 @@ internal class TimelineItemTheme : BaseControlTheme
contentIndex = 1;
contentTextAlign = HorizontalAlignment.Left;
}
if (!timelineItem.HasLabel && timelineItem.Mode == "right")
{
splitIndex = 1;
@ -196,7 +231,6 @@ internal class TimelineItemTheme : BaseControlTheme
private ColumnDefinitions CalculateGridColumn(TimelineItem timelineItem, int labelIndex)
{
if (timelineItem.HasLabel || timelineItem.Mode == "alternate")
{
return new ColumnDefinitions()
@ -206,6 +240,7 @@ internal class TimelineItemTheme : BaseControlTheme
new ColumnDefinition(GridLength.Star)
};
}
if (labelIndex == 0)
{
return new ColumnDefinitions()

View File

@ -28,10 +28,10 @@ internal class TimelineTheme : BaseControlTheme
{
Name = FrameDecoratorPart
};
CreateTemplateParentBinding(frameBorder, Border.BackgroundProperty, Timeline.BackgroundProperty);
CreateTemplateParentBinding(frameBorder, Border.BorderBrushProperty, Timeline.BorderBrushProperty);
CreateTemplateParentBinding(frameBorder, Border.BorderThicknessProperty, Timeline.BorderThicknessProperty);
CreateTemplateParentBinding(frameBorder, Border.CornerRadiusProperty, Timeline.CornerRadiusProperty);
// CreateTemplateParentBinding(frameBorder, Border.BackgroundProperty, Timeline.BackgroundProperty);
// CreateTemplateParentBinding(frameBorder, Border.BorderBrushProperty, Timeline.BorderBrushProperty);
// CreateTemplateParentBinding(frameBorder, Border.BorderThicknessProperty, Timeline.BorderThicknessProperty);
// CreateTemplateParentBinding(frameBorder, Border.CornerRadiusProperty, Timeline.CornerRadiusProperty);
var itemsPresenter = BuildItemsPresenter(timeline, scope);
var scrollViewer = BuildScrollViewer(timeline, scope);

View File

@ -49,13 +49,29 @@ internal class TimelineToken : AbstractControlDesignToken
/// <summary>
/// 时间项下间距
/// </summary>
public double ItemPaddingBottom { get; set; }
public Thickness ItemPaddingBottom { get; set; }
/// <summary>
/// content left margin
/// right margin
/// </summary>
public Thickness ContentMargin { get; set; }
public Thickness RightMargin { get; set; }
/// <summary>
/// left margin
/// </summary>
public Thickness LeftMargin { get; set; }
/// <summary>
/// 最后一个Item的Content最小高度
/// </summary>
public double LastItemContentMinHeight { get; set; }
/// <summary>
/// 字体大小
/// </summary>
public double FontSize { get; set; }
internal override void CalculateFromAlias()
{
base.CalculateFromAlias();
@ -67,8 +83,14 @@ internal class TimelineToken : AbstractControlDesignToken
? _globalToken.StyleToken.LineWidthBold
: _globalToken.SeedToken.LineWidth * 3;
DotBg = _globalToken.ColorToken.ColorNeutralToken.ColorBgContainer;
ItemPaddingBottom = _globalToken.Padding * 1.25;
ItemPaddingBottom = new Thickness(0, 0, 0, _globalToken.Padding * 1.25);
ContentMargin = new Thickness(_globalToken.Margin, 0, 0, 0);
LeftMargin = new Thickness(_globalToken.Margin, 0, 0, 0);
RightMargin = new Thickness(0, 0, _globalToken.MarginSM, 0);
LastItemContentMinHeight = _globalToken.HeightToken.ControlHeightLG * 1.2;
FontSize = _globalToken.FontToken.FontSize;
}
}