feat: simplify container generation, and add vertical demo.
This commit is contained in:
@@ -6,13 +6,16 @@ using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Markup.Xaml.Templates;
|
||||
using Irihi.Avalonia.Shared.Helpers;
|
||||
|
||||
namespace Ursa.Controls;
|
||||
|
||||
[PseudoClasses(PC_Overflow)]
|
||||
[TemplatePart(PART_OverflowPanel, typeof(Panel))]
|
||||
public class ToolBar: HeaderedItemsControl
|
||||
{
|
||||
public const string PART_OverflowPanel = "PART_OverflowPanel";
|
||||
public const string PC_Overflow = ":overflow";
|
||||
|
||||
internal Panel? OverflowPanel { get; private set; }
|
||||
|
||||
@@ -27,14 +30,14 @@ public class ToolBar: HeaderedItemsControl
|
||||
get => GetValue(OrientationProperty);
|
||||
set => SetValue(OrientationProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<int> BandProperty = AvaloniaProperty.Register<ToolBar, int>(
|
||||
nameof(Band));
|
||||
|
||||
public int Band
|
||||
|
||||
public static readonly StyledProperty<PlacementMode> PopupPlacementProperty =
|
||||
Popup.PlacementProperty.AddOwner<ToolBar>();
|
||||
|
||||
public PlacementMode PopupPlacement
|
||||
{
|
||||
get => GetValue(BandProperty);
|
||||
set => SetValue(BandProperty, value);
|
||||
get => GetValue(PopupPlacementProperty);
|
||||
set => SetValue(PopupPlacementProperty, value);
|
||||
}
|
||||
|
||||
public static readonly AttachedProperty<OverflowMode> OverflowModeProperty =
|
||||
@@ -49,11 +52,27 @@ public class ToolBar: HeaderedItemsControl
|
||||
internal static void SetIsOverflowItem(Control obj, bool value) => obj.SetValue(IsOverflowItemProperty, value);
|
||||
internal static bool GetIsOverflowItem(Control obj) => obj.GetValue(IsOverflowItemProperty);
|
||||
|
||||
private bool _hasOverflowItems;
|
||||
internal bool HasOverflowItems
|
||||
{
|
||||
get => _hasOverflowItems;
|
||||
set
|
||||
{
|
||||
_hasOverflowItems = value;
|
||||
PseudoClasses.Set(PC_Overflow, value);
|
||||
}
|
||||
}
|
||||
|
||||
static ToolBar()
|
||||
{
|
||||
IsTabStopProperty.OverrideDefaultValue<ToolBar>(false);
|
||||
ItemsPanelProperty.OverrideDefaultValue<ToolBar>(DefaultTemplate);
|
||||
OrientationProperty.OverrideDefaultValue<ToolBar>(Orientation.Horizontal);
|
||||
// TODO: use helper method after merged and upgrade helper dependency.
|
||||
IsOverflowItemProperty.Changed.AddClassHandler<Control, bool>((o, e) =>
|
||||
{
|
||||
PseudolassesExtensions.Set(o.Classes, PC_Overflow, e.NewValue.Value);
|
||||
});
|
||||
}
|
||||
|
||||
protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey)
|
||||
@@ -63,29 +82,11 @@ public class ToolBar: HeaderedItemsControl
|
||||
|
||||
protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey)
|
||||
{
|
||||
return new ContentPresenter();
|
||||
}
|
||||
|
||||
protected override void ContainerForItemPreparedOverride(Control container, object? item, int index)
|
||||
{
|
||||
base.ContainerForItemPreparedOverride(container, item, index);
|
||||
if (item is Control s)
|
||||
if(item is Control c)
|
||||
{
|
||||
container[!ToolBar.OverflowModeProperty] = s[!ToolBar.OverflowModeProperty];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (container is ContentPresenter p)
|
||||
{
|
||||
p.ApplyTemplate();
|
||||
var c = p.Child;
|
||||
if (c != null)
|
||||
{
|
||||
container[ToolBar.OverflowModeProperty] = c[ToolBar.OverflowModeProperty];
|
||||
// container[!ToolBar.OverflowModeProperty] = c[!ToolBar.OverflowModeProperty];
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
return ItemTemplate?.Build(item) ?? new ContentPresenter();
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace Ursa.Controls;
|
||||
|
||||
public class ToolBarOverflowPanel: StackPanel
|
||||
{
|
||||
|
||||
}
|
||||
@@ -10,18 +10,9 @@ public class ToolBarPanel: StackPanel
|
||||
private ToolBar? _parent;
|
||||
private Panel? _overflowPanel;
|
||||
|
||||
internal Panel? OverflowPanel => _overflowPanel ??= _parent?.OverflowPanel;
|
||||
private Panel? OverflowPanel => _overflowPanel ??= _parent?.OverflowPanel;
|
||||
internal ToolBar? ParentToolBar => _parent ??= this.TemplatedParent as ToolBar;
|
||||
|
||||
public static readonly StyledProperty<Orientation> OrientationProperty =
|
||||
StackPanel.OrientationProperty.AddOwner<ToolBar>();
|
||||
|
||||
public Orientation Orientation
|
||||
{
|
||||
get => GetValue(OrientationProperty);
|
||||
set => SetValue(OrientationProperty, value);
|
||||
}
|
||||
|
||||
static ToolBarPanel()
|
||||
{
|
||||
OrientationProperty.OverrideDefaultValue<ToolBarPanel>(Orientation.Horizontal);
|
||||
@@ -38,13 +29,11 @@ public class ToolBarPanel: StackPanel
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var logicalChildren = _parent?.GetLogicalChildren().OfType<Control>().ToList();
|
||||
var parent = this.GetLogicalParent();
|
||||
Size size = new Size();
|
||||
double spacing = 0;
|
||||
Size measureSize = availableSize;
|
||||
bool horizontal = Orientation == Orientation.Horizontal;
|
||||
bool hasVisibleChildren = false;
|
||||
int index = 0;
|
||||
if (logicalChildren is null) return size;
|
||||
for (int i = 0; i < logicalChildren.Count; i++)
|
||||
{
|
||||
@@ -54,7 +43,6 @@ public class ToolBarPanel: StackPanel
|
||||
if (mode == OverflowMode.Always)
|
||||
{
|
||||
ToolBar.SetIsOverflowItem(control, true);
|
||||
continue;
|
||||
}
|
||||
else if (mode == OverflowMode.Never)
|
||||
{
|
||||
@@ -114,30 +102,33 @@ public class ToolBarPanel: StackPanel
|
||||
{
|
||||
Children.Clear();
|
||||
OverflowPanel?.Children.Clear();
|
||||
InvalidateVisual();
|
||||
var logicalChildren = _parent?.GetLogicalChildren().OfType<Control>().ToList();
|
||||
if(logicalChildren is null) return finalSize;
|
||||
bool overflow = false;
|
||||
foreach (var child in logicalChildren)
|
||||
{
|
||||
if (ToolBar.GetIsOverflowItem(child))
|
||||
{
|
||||
OverflowPanel?.Children.Add(child);
|
||||
overflow = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Children.Add(child);
|
||||
Children.Add(child);
|
||||
}
|
||||
}
|
||||
|
||||
if (_parent != null) _parent.HasOverflowItems = overflow;
|
||||
return base.ArrangeOverride(finalSize);
|
||||
}
|
||||
|
||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
var list = OverflowPanel?.Children?.ToList();
|
||||
var list = OverflowPanel?.Children.ToList();
|
||||
if (list is not null)
|
||||
{
|
||||
OverflowPanel?.Children?.Clear();
|
||||
this.Children.AddRange(list);
|
||||
OverflowPanel?.Children.Clear();
|
||||
Children.AddRange(list);
|
||||
}
|
||||
base.OnDetachedFromVisualTree(e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user