wip: layout.

This commit is contained in:
rabbitism
2024-01-02 22:32:25 +08:00
parent d5b5792870
commit 1d6d8feaec
7 changed files with 197 additions and 72 deletions

View File

@@ -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<Panel?> DefaultPanel = new((Func<Panel>)(() => new TimelinePanel()));
public static readonly StyledProperty<IBinding?> IconMemberBindingProperty = AvaloniaProperty.Register<Timeline, IBinding?>(
nameof(IconMemberBinding));
@@ -66,6 +69,29 @@ public class Timeline: ItemsControl
set => SetValue(DescriptionTemplateProperty, value);
}
public static readonly StyledProperty<TimelineDisplayMode> ModeProperty = AvaloniaProperty.Register<Timeline, TimelineDisplayMode>(
nameof(Mode));
public TimelineDisplayMode Mode
{
get => GetValue(ModeProperty);
set => SetValue(ModeProperty, value);
}
static Timeline()
{
ItemsPanelProperty.OverrideDefaultValue<Timeline>(DefaultPanel);
ModeProperty.Changed.AddClassHandler<Timeline, TimelineDisplayMode>((t, e) => { t.OnDisplayModeChanged(e); });
}
private void OnDisplayModeChanged(AvaloniaPropertyChangedEventArgs<TimelineDisplayMode> 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;

View File

@@ -0,0 +1,9 @@
namespace Ursa.Controls;
public enum TimelineDisplayMode
{
Left,
Center,
Right,
Alternate,
}

View File

@@ -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<object?> IconProperty = AvaloniaProperty.Register<TimelineItem, object?>(
nameof(Icon));
@@ -37,10 +41,47 @@ public class TimelineItem: HeaderedContentControl
get => GetValue(TypeProperty);
set => SetValue(TypeProperty, value);
}
public static readonly DirectProperty<TimelineItem, double> LeftWidthProperty = AvaloniaProperty.RegisterDirect<TimelineItem, double>(
nameof(LeftWidth), o => o.LeftWidth, (o, v) => o.LeftWidth = v);
private double _leftWidth;
public double LeftWidth
{
get => _leftWidth;
set => SetAndRaise(LeftWidthProperty, ref _leftWidth, value);
}
public static readonly DirectProperty<TimelineItem, double> IconWidthProperty = AvaloniaProperty.RegisterDirect<TimelineItem, double>(
nameof(IconWidth), o => o.IconWidth, (o, v) => o.IconWidth = v);
private double _iconWidth;
public double IconWidth
{
get => _iconWidth;
set => SetAndRaise(IconWidthProperty, ref _iconWidth, value);
}
public static readonly DirectProperty<TimelineItem, double> RightWidthProperty = AvaloniaProperty.RegisterDirect<TimelineItem, double>(
nameof(RightWidth), o => o.RightWidth, (o, v) => o.RightWidth = v);
private double _rightWidth;
public double RightWidth
{
get => _rightWidth;
set => SetAndRaise(RightWidthProperty, ref _rightWidth, value);
}
static TimelineItem()
{
IconProperty.Changed.AddClassHandler<TimelineItem, object?>((item, args) => { item.OnIconChanged(args); });
}
private void OnIconChanged(AvaloniaPropertyChangedEventArgs<object?> args)
{
PseudoClasses.Set(PC_EmptyIcon, args.NewValue.Value is null);
}
internal void SetEnd(bool start, bool end)
{
PseudoClasses.Set(":first", start);
PseudoClasses.Set(":last", end);
PseudoClasses.Set(PC_First, start);
PseudoClasses.Set(PC_Last, end);
}
}

View File

@@ -0,0 +1,43 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Layout;
namespace Ursa.Controls;
public class TimelinePanel: Panel
{
public static readonly StyledProperty<TimelineDisplayMode> ModeProperty =
Timeline.ModeProperty.AddOwner<TimelinePanel>();
public TimelineDisplayMode Mode
{
get => GetValue(ModeProperty);
set => SetValue(ModeProperty, value);
}
static TimelinePanel()
{
AffectsMeasure<TimelinePanel>(ModeProperty);
}
protected override Size MeasureOverride(Size availableSize)
{
double left = 0;
double right = 0;
double icon = 0;
foreach (var child in Children)
{
if (child is TimelineItem t)
{
}
}
return base.MeasureOverride(availableSize);
}
protected override Size ArrangeOverride(Size finalSize)
{
return base.ArrangeOverride(finalSize);
}
}