diff --git a/demo/Ursa.Demo.Desktop/Ursa.Demo.Desktop.csproj b/demo/Ursa.Demo.Desktop/Ursa.Demo.Desktop.csproj
index 3d3f388..64e44ce 100644
--- a/demo/Ursa.Demo.Desktop/Ursa.Demo.Desktop.csproj
+++ b/demo/Ursa.Demo.Desktop/Ursa.Demo.Desktop.csproj
@@ -6,6 +6,7 @@
net7.0
enable
true
+ false
diff --git a/demo/Ursa.Demo/Pages/TimelineDemo.axaml b/demo/Ursa.Demo/Pages/TimelineDemo.axaml
index 39e428a..04d12b4 100644
--- a/demo/Ursa.Demo/Pages/TimelineDemo.axaml
+++ b/demo/Ursa.Demo/Pages/TimelineDemo.axaml
@@ -4,37 +4,67 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:selectors="clr-namespace:Ursa.Demo.TemplateSelectors"
xmlns:u="https://irihi.tech/ursa"
xmlns:viewModels="clr-namespace:Ursa.Demo.ViewModels"
- xmlns:selectors="clr-namespace:Ursa.Demo.TemplateSelectors"
d:DesignHeight="450"
d:DesignWidth="800"
- x:DataType="viewModels:TimelineDemoViewModel"
x:CompileBindings="True"
+ x:DataType="viewModels:TimelineDemoViewModel"
mc:Ignorable="d">
-
-
-
-
-
+
+
+
+
+
-
-
+
-
-
-
+
+
+
diff --git a/src/Ursa.Themes.Semi/Controls/Timeline.axaml b/src/Ursa.Themes.Semi/Controls/Timeline.axaml
index 7b192ce..dd7c25f 100644
--- a/src/Ursa.Themes.Semi/Controls/Timeline.axaml
+++ b/src/Ursa.Themes.Semi/Controls/Timeline.axaml
@@ -26,48 +26,35 @@
+ WarningBrush="{DynamicResource WarningTimelineIconForeground}" />
-
-
+
-
-
-
-
-
-
+ Grid.Column="1"
+ Width="1"
+ Height="8"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Top"
+ Classes="start"
+ Fill="{DynamicResource TimelineLineBrush}" />
+
-
+ Foreground="Gray" />
-
-
-
-
-
-
diff --git a/src/Ursa/Controls/Timeline/Timeline.cs b/src/Ursa/Controls/Timeline/Timeline.cs
index 1586733..3577226 100644
--- a/src/Ursa/Controls/Timeline/Timeline.cs
+++ b/src/Ursa/Controls/Timeline/Timeline.cs
@@ -6,12 +6,15 @@ using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Data;
+using Avalonia.Layout;
using Avalonia.Metadata;
namespace Ursa.Controls;
public class Timeline: ItemsControl
{
+ private static readonly FuncTemplate DefaultPanel = new((Func)(() => new TimelinePanel()));
+
public static readonly StyledProperty IconMemberBindingProperty = AvaloniaProperty.Register(
nameof(IconMemberBinding));
@@ -66,6 +69,29 @@ public class Timeline: ItemsControl
set => SetValue(DescriptionTemplateProperty, value);
}
+ public static readonly StyledProperty ModeProperty = AvaloniaProperty.Register(
+ nameof(Mode));
+
+ public TimelineDisplayMode Mode
+ {
+ get => GetValue(ModeProperty);
+ set => SetValue(ModeProperty, value);
+ }
+
+ static Timeline()
+ {
+ ItemsPanelProperty.OverrideDefaultValue(DefaultPanel);
+ ModeProperty.Changed.AddClassHandler((t, e) => { t.OnDisplayModeChanged(e); });
+ }
+
+ private void OnDisplayModeChanged(AvaloniaPropertyChangedEventArgs e)
+ {
+ if (this.ItemsPanelRoot is TimelinePanel panel)
+ {
+ panel.Mode = e.NewValue.Value;
+ }
+ }
+
protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey)
{
recycleKey = null;
diff --git a/src/Ursa/Controls/Timeline/TimelineDisplayMode.cs b/src/Ursa/Controls/Timeline/TimelineDisplayMode.cs
new file mode 100644
index 0000000..1907672
--- /dev/null
+++ b/src/Ursa/Controls/Timeline/TimelineDisplayMode.cs
@@ -0,0 +1,9 @@
+namespace Ursa.Controls;
+
+public enum TimelineDisplayMode
+{
+ Left,
+ Center,
+ Right,
+ Alternate,
+}
\ No newline at end of file
diff --git a/src/Ursa/Controls/Timeline/TimelineItem.cs b/src/Ursa/Controls/Timeline/TimelineItem.cs
index 20e57d6..8f08983 100644
--- a/src/Ursa/Controls/Timeline/TimelineItem.cs
+++ b/src/Ursa/Controls/Timeline/TimelineItem.cs
@@ -8,9 +8,13 @@ using Avalonia.Media;
namespace Ursa.Controls;
-[PseudoClasses(":first", ":last")]
+[PseudoClasses(PC_First, PC_Last, PC_EmptyIcon)]
public class TimelineItem: HeaderedContentControl
{
+ public const string PC_First = ":first";
+ public const string PC_Last = ":last";
+ public const string PC_EmptyIcon = ":empty-icon";
+
public static readonly StyledProperty