Skip to content

Commit 91d1922

Browse files
committed
Initial commit
1 parent 79b7621 commit 91d1922

21 files changed

+1254
-2
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using Microsoft.UI;
5+
using Microsoft.UI.Xaml;
6+
using Microsoft.UI.Xaml.Controls;
7+
using Microsoft.UI.Xaml.Input;
8+
using Microsoft.UI.Xaml.Markup;
9+
using Microsoft.UI.Xaml.Media;
10+
using Microsoft.UI.Xaml.Shapes;
11+
12+
namespace Files.App.Controls
13+
{
14+
public partial class BreadcrumbBar
15+
{
16+
private void ItemsRepeater_ElementPrepared(ItemsRepeater sender, ItemsRepeaterElementPreparedEventArgs args)
17+
{
18+
if (args.Element is not BreadcrumbBarItem item || _itemsRepeater is null)
19+
return;
20+
21+
if (args.Index == _itemsRepeater.ItemsSourceView.Count - 1)
22+
{
23+
_lastBreadcrumbBarItem = item;
24+
_lastBreadcrumbBarItem.IsLastItem = true;
25+
}
26+
27+
item.SetOwner(this);
28+
}
29+
}
30+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using CommunityToolkit.WinUI;
5+
6+
namespace Files.App.Controls
7+
{
8+
public partial class BreadcrumbBar : Control
9+
{
10+
[GeneratedDependencyProperty]
11+
public partial FrameworkElement? RootItem { get; set; }
12+
13+
[GeneratedDependencyProperty]
14+
public partial object? ItemsSource { get; set; }
15+
16+
[GeneratedDependencyProperty]
17+
public partial object? ItemTemplate { get; set; }
18+
19+
partial void OnItemsSourceChanged(object? newValue)
20+
{
21+
}
22+
}
23+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using Microsoft.UI;
5+
using Microsoft.UI.Xaml;
6+
using Microsoft.UI.Xaml.Controls;
7+
using Microsoft.UI.Xaml.Input;
8+
using Microsoft.UI.Xaml.Markup;
9+
using Microsoft.UI.Xaml.Media;
10+
using Microsoft.UI.Xaml.Shapes;
11+
using System.Reflection;
12+
using Windows.Foundation;
13+
14+
namespace Files.App.Controls
15+
{
16+
public partial class BreadcrumbBar : Control
17+
{
18+
// Constants
19+
20+
private const string TemplatePartName_RootBreadcrumbBarItem = "PART_RootBreadcrumbBarItem";
21+
private const string TemplatePartName_EllipsisBreadcrumbBarItem = "PART_EllipsisBreadcrumbBarItem";
22+
private const string TemplatePartName_MainItemsRepeater = "PART_MainItemsRepeater";
23+
24+
// Fields
25+
26+
private readonly BreadcrumbBarLayout _itemsRepeaterLayout;
27+
28+
private BreadcrumbBarItem? _rootBreadcrumbBarItem;
29+
private BreadcrumbBarItem? _ellipsisBreadcrumbBarItem;
30+
private BreadcrumbBarItem? _lastBreadcrumbBarItem;
31+
private ItemsRepeater? _itemsRepeater;
32+
33+
private bool _isEllipsisRendered;
34+
35+
// Events
36+
37+
public event TypedEventHandler<BreadcrumbBar, BreadcrumbBarItemClickedEventArgs>? ItemClicked;
38+
public event EventHandler<BreadcrumbBarItemDropDownFlyoutEventArgs>? ItemDropDownFlyoutOpening;
39+
public event EventHandler<BreadcrumbBarItemDropDownFlyoutEventArgs>? ItemDropDownFlyoutClosed;
40+
41+
// Constructor
42+
43+
public BreadcrumbBar()
44+
{
45+
DefaultStyleKey = typeof(BreadcrumbBar);
46+
47+
_itemsRepeaterLayout = new(this, 2d);
48+
}
49+
50+
// Methods
51+
52+
protected override void OnApplyTemplate()
53+
{
54+
base.OnApplyTemplate();
55+
56+
_rootBreadcrumbBarItem = GetTemplateChild(TemplatePartName_RootBreadcrumbBarItem) as BreadcrumbBarItem
57+
?? throw new MissingFieldException($"Could not find {TemplatePartName_RootBreadcrumbBarItem} in the given {nameof(BreadcrumbBar)}'s style.");
58+
_ellipsisBreadcrumbBarItem = GetTemplateChild(TemplatePartName_EllipsisBreadcrumbBarItem) as BreadcrumbBarItem
59+
?? throw new MissingFieldException($"Could not find {TemplatePartName_EllipsisBreadcrumbBarItem} in the given {nameof(BreadcrumbBar)}'s style.");
60+
_itemsRepeater = GetTemplateChild(TemplatePartName_MainItemsRepeater) as ItemsRepeater
61+
?? throw new MissingFieldException($"Could not find {TemplatePartName_MainItemsRepeater} in the given {nameof(BreadcrumbBar)}'s style.");
62+
63+
_rootBreadcrumbBarItem.SetOwner(this);
64+
_ellipsisBreadcrumbBarItem.SetOwner(this);
65+
_itemsRepeater.Layout = _itemsRepeaterLayout;
66+
67+
_itemsRepeater.ElementPrepared += ItemsRepeater_ElementPrepared;
68+
}
69+
70+
internal protected virtual void RaiseItemClickedEvent(BreadcrumbBarItem item)
71+
{
72+
var index = _itemsRepeater?.GetElementIndex(item) ?? throw new ArgumentNullException($"{_itemsRepeater} is null.");
73+
var eventArgs = new BreadcrumbBarItemClickedEventArgs(item, index, item == _rootBreadcrumbBarItem);
74+
ItemClicked?.Invoke(this, eventArgs);
75+
}
76+
77+
internal protected virtual void RaiseItemDropDownFlyoutOpening(BreadcrumbBarItem item, MenuFlyout flyout)
78+
{
79+
var index = _itemsRepeater?.GetElementIndex(item) ?? throw new ArgumentNullException($"{_itemsRepeater} is null.");
80+
ItemDropDownFlyoutOpening?.Invoke(this, new(flyout, item, index, item == _rootBreadcrumbBarItem));
81+
}
82+
83+
internal protected virtual void RaiseItemDropDownFlyoutClosed(BreadcrumbBarItem item, MenuFlyout flyout)
84+
{
85+
var index = _itemsRepeater?.GetElementIndex(item) ?? throw new ArgumentNullException($"{_itemsRepeater} is null.");
86+
ItemDropDownFlyoutClosed?.Invoke(this, new(flyout, item, index, item == _rootBreadcrumbBarItem));
87+
}
88+
89+
internal protected virtual void OnLayoutUpdated()
90+
{
91+
if (_itemsRepeater is null || _isEllipsisRendered == _itemsRepeaterLayout.EllipsisIsRendered)
92+
return;
93+
94+
_isEllipsisRendered = _itemsRepeaterLayout.EllipsisIsRendered;
95+
if (_ellipsisBreadcrumbBarItem is not null)
96+
{
97+
_ellipsisBreadcrumbBarItem.Visibility = _isEllipsisRendered ? Visibility.Visible : Visibility.Collapsed;
98+
}
99+
}
100+
}
101+
}

0 commit comments

Comments
 (0)