Skip to content

Commit 5eccf7a

Browse files
committed
Initial commit
1 parent 79b7621 commit 5eccf7a

15 files changed

+754
-1
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using CommunityToolkit.WinUI;
5+
using Microsoft.UI;
6+
using Microsoft.UI.Xaml;
7+
using Microsoft.UI.Xaml.Controls;
8+
using Microsoft.UI.Xaml.Input;
9+
using Microsoft.UI.Xaml.Markup;
10+
using Microsoft.UI.Xaml.Media;
11+
using Microsoft.UI.Xaml.Shapes;
12+
13+
namespace Files.App.Controls
14+
{
15+
public sealed partial class BreadcrumbBar : Control
16+
{
17+
[GeneratedDependencyProperty]
18+
public partial object? ItemsSource { get; set; }
19+
20+
[GeneratedDependencyProperty]
21+
public partial object? ItemTemplate { get; set; }
22+
23+
partial void OnItemsSourceChanged(object? newValue)
24+
{
25+
}
26+
27+
partial void OnItemTemplateChanged(object? newValue)
28+
{
29+
}
30+
}
31+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using CommunityToolkit.WinUI;
5+
using Microsoft.UI;
6+
using Microsoft.UI.Xaml;
7+
using Microsoft.UI.Xaml.Controls;
8+
using Microsoft.UI.Xaml.Input;
9+
using Microsoft.UI.Xaml.Markup;
10+
using Microsoft.UI.Xaml.Media;
11+
using Microsoft.UI.Xaml.Shapes;
12+
using System;
13+
using Windows.Foundation;
14+
15+
namespace Files.App.Controls
16+
{
17+
// Template parts
18+
[TemplatePart(Name = "PART_ItemsRepeater", Type = typeof(ItemsRepeater))]
19+
public sealed partial class BreadcrumbBar : Control
20+
{
21+
// Constants
22+
23+
private const string _itemsRepeaterName = "PART_RootItemsRepeater";
24+
25+
// Fields
26+
27+
private ItemsRepeater _itemsRepeater = null!;
28+
private BreadcrumbBarLayout _itemsRepeaterLayout = null!;
29+
30+
// Events
31+
32+
/// <summary>
33+
/// Occurs when an item is clicked in this <see cref="BreadcrumbBar"/> instance.
34+
/// </summary>
35+
public event TypedEventHandler<BreadcrumbBar, BreadcrumbBarItemClickedEventArgs>? ItemClicked;
36+
37+
// Constructor
38+
39+
public BreadcrumbBar()
40+
{
41+
DefaultStyleKey = typeof(BreadcrumbBar);
42+
43+
_itemsRepeaterLayout = new(this);
44+
}
45+
46+
// Methods
47+
48+
protected override void OnApplyTemplate()
49+
{
50+
base.OnApplyTemplate();
51+
52+
_itemsRepeater = GetTemplateChild(_itemsRepeaterName) as ItemsRepeater
53+
?? throw new MissingFieldException($"Could not find {_itemsRepeaterName} in the given {nameof(BreadcrumbBar)}'s style.");
54+
55+
//_itemsRepeater.Layout = _itemsRepeaterLayout;
56+
57+
_itemsRepeater.ElementPrepared += ItemsRepeater_ElementPrepared;
58+
}
59+
60+
internal void RaiseItemClickedEvent(BreadcrumbBarItem item)
61+
{
62+
var index = _itemsRepeater.GetElementIndex(item);
63+
var eventArgs = new BreadcrumbBarItemClickedEventArgs(item, index);
64+
ItemClicked?.Invoke(this, eventArgs);
65+
}
66+
67+
// Event methods
68+
69+
private void ItemsRepeater_ElementPrepared(ItemsRepeater sender, ItemsRepeaterElementPreparedEventArgs args)
70+
{
71+
if (args.Element is not BreadcrumbBarItem item)
72+
return;
73+
74+
item.SetOwner(this);
75+
}
76+
}
77+
}
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
<!-- Copyright (c) Files Community. Licensed under the MIT License. -->
2+
<ResourceDictionary
3+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:animatedvisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals"
6+
xmlns:local="using:Files.App.Controls">
7+
8+
<x:Double x:Key="BreadcrumbBarItemHeight">32</x:Double>
9+
10+
<Style BasedOn="{StaticResource DefaultBreadcrumbBarStyle}" TargetType="local:BreadcrumbBar" />
11+
<Style BasedOn="{StaticResource DefaultBreadcrumbBarItemStyle}" TargetType="local:BreadcrumbBarItem" />
12+
13+
<Style x:Key="DefaultBreadcrumbBarStyle" TargetType="local:BreadcrumbBar">
14+
<Setter Property="AutomationProperties.LandmarkType" Value="Navigation" />
15+
<Setter Property="IsTabStop" Value="False" />
16+
<Setter Property="Template">
17+
<Setter.Value>
18+
<ControlTemplate TargetType="local:BreadcrumbBar">
19+
<ItemsRepeater
20+
x:Name="PART_RootItemsRepeater"
21+
ItemTemplate="{Binding ItemTemplate, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
22+
ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}">
23+
<ItemsRepeater.Layout>
24+
<StackLayout Orientation="Horizontal" />
25+
</ItemsRepeater.Layout>
26+
</ItemsRepeater>
27+
</ControlTemplate>
28+
</Setter.Value>
29+
</Setter>
30+
</Style>
31+
32+
<Style x:Key="DefaultBreadcrumbBarItemStyle" TargetType="local:BreadcrumbBarItem">
33+
<Setter Property="Background" Value="{ThemeResource BreadcrumbBarBackgroundBrush}" />
34+
<Setter Property="BorderBrush" Value="{ThemeResource BreadcrumbBarBorderBrush}" />
35+
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
36+
<Setter Property="FontSize" Value="{ThemeResource BreadcrumbBarItemThemeFontSize}" />
37+
<Setter Property="FontWeight" Value="{ThemeResource BreadcrumbBarItemFontWeight}" />
38+
<Setter Property="Foreground" Value="{ThemeResource BreadcrumbBarForegroundBrush}" />
39+
<Setter Property="Height" Value="{ThemeResource BreadcrumbBarItemHeight}" />
40+
<Setter Property="HorizontalAlignment" Value="Stretch" />
41+
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
42+
<Setter Property="IsTabStop" Value="True" />
43+
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
44+
<Setter Property="VerticalAlignment" Value="Stretch" />
45+
<Setter Property="VerticalContentAlignment" Value="Stretch" />
46+
<Setter Property="CornerRadius" Value="2" />
47+
<Setter Property="Template">
48+
<Setter.Value>
49+
<ControlTemplate TargetType="local:BreadcrumbBarItem">
50+
<Grid x:Name="PART_LayoutRoot" ColumnSpacing="2">
51+
<Grid.ColumnDefinitions>
52+
<ColumnDefinition x:Name="PART_ContentColumn" Width="Auto" />
53+
<ColumnDefinition x:Name="PART_ChevronColumn" Width="Auto" />
54+
</Grid.ColumnDefinitions>
55+
56+
<!-- Clickable Area -->
57+
<Border
58+
x:Name="PART_ItemButton"
59+
Background="Transparent"
60+
CornerRadius="{TemplateBinding CornerRadius}">
61+
<Border.BackgroundTransition>
62+
<BrushTransition Duration="0:0:0.083" />
63+
</Border.BackgroundTransition>
64+
65+
<ContentPresenter
66+
x:Name="PART_ItemContentPresenter"
67+
Margin="8,0"
68+
HorizontalAlignment="Center"
69+
VerticalAlignment="Center"
70+
Content="{TemplateBinding Content}"
71+
ContentTemplate="{TemplateBinding ContentTemplate}" />
72+
73+
</Border>
74+
75+
<!-- Chevron -->
76+
<Border
77+
x:Name="PART_ChevronButton"
78+
Grid.Column="1"
79+
Background="Transparent"
80+
CornerRadius="{TemplateBinding CornerRadius}">
81+
<Border.BackgroundTransition>
82+
<BrushTransition Duration="0:0:0.083" />
83+
</Border.BackgroundTransition>
84+
<FlyoutBase.AttachedFlyout>
85+
<MenuFlyout
86+
x:Name="PART_ChevronDropDownMenuFlyout"
87+
Placement="Bottom"
88+
ScrollViewer.VerticalScrollBarVisibility="Auto"
89+
ScrollViewer.VerticalScrollMode="Auto">
90+
<MenuFlyout.MenuFlyoutPresenterStyle>
91+
<Style TargetType="MenuFlyoutPresenter">
92+
<Setter Property="MaxHeight" Value="400" />
93+
<!-- Workaround for https://github.com/files-community/Files/issues/13078 -->
94+
<Setter Target="HighContrastAdjustment" Value="None" />
95+
</Style>
96+
</MenuFlyout.MenuFlyoutPresenterStyle>
97+
</MenuFlyout>
98+
</FlyoutBase.AttachedFlyout>
99+
100+
<AnimatedIcon
101+
x:Name="PART_ChevronAnimatedIcon"
102+
Width="12"
103+
Height="12"
104+
Margin="4,0"
105+
HorizontalAlignment="Center"
106+
VerticalAlignment="Center"
107+
AnimatedIcon.State="NormalOff"
108+
MirroredWhenRightToLeft="True"
109+
RenderTransformOrigin="0.5, 0.5">
110+
<AnimatedIcon.FallbackIconSource>
111+
<FontIconSource
112+
x:Name="ChevronAnimatedIconFallbackFontIcon"
113+
FontSize="12"
114+
Glyph="&#xE76C;"
115+
IsTextScaleFactorEnabled="False" />
116+
</AnimatedIcon.FallbackIconSource>
117+
118+
<animatedvisuals:AnimatedChevronRightDownSmallVisualSource />
119+
120+
</AnimatedIcon>
121+
122+
</Border>
123+
124+
<VisualStateManager.VisualStateGroups>
125+
126+
<VisualStateGroup x:Name="PointerStates">
127+
<VisualState x:Name="PointerNormal" />
128+
129+
<VisualState x:Name="PointerOverItem">
130+
<VisualState.Setters>
131+
<Setter Target="PART_ItemButton.Background" Value="{ThemeResource ControlFillColorSecondaryBrush}" />
132+
<Setter Target="PART_ChevronButton.Background" Value="{ThemeResource ControlFillColorSecondaryBrush}" />
133+
</VisualState.Setters>
134+
</VisualState>
135+
<VisualState x:Name="PointerOverChevron">
136+
<VisualState.Setters>
137+
<Setter Target="PART_ChevronButton.Background" Value="{ThemeResource ControlFillColorSecondaryBrush}" />
138+
</VisualState.Setters>
139+
</VisualState>
140+
141+
<VisualState x:Name="PointerPressedOnItem">
142+
<VisualState.Setters>
143+
<Setter Target="PART_ItemButton.Background" Value="{ThemeResource ControlFillColorTertiaryBrush}" />
144+
<Setter Target="PART_ChevronButton.Background" Value="{ThemeResource ControlFillColorTertiaryBrush}" />
145+
</VisualState.Setters>
146+
</VisualState>
147+
<VisualState x:Name="PointerPressedOnChevron">
148+
<VisualState.Setters>
149+
<Setter Target="PART_ChevronButton.Background" Value="{ThemeResource ControlFillColorTertiaryBrush}" />
150+
</VisualState.Setters>
151+
</VisualState>
152+
153+
</VisualStateGroup>
154+
155+
<VisualStateGroup x:Name="ItemTypeStates">
156+
<VisualState x:Name="DefaultItemType" />
157+
<VisualState x:Name="LastItemType">
158+
<VisualState.Setters>
159+
<Setter Target="PART_ItemButton.Visibility" Value="Collapsed" />
160+
</VisualState.Setters>
161+
</VisualState>
162+
</VisualStateGroup>
163+
164+
<VisualStateGroup x:Name="ChevronStates">
165+
<VisualState x:Name="ChevronNormalOff" />
166+
<VisualState x:Name="ChevronNormalOn">
167+
<VisualState.Setters>
168+
<Setter Target="PART_ChevronAnimatedIcon.(AnimatedIcon.State)" Value="NormalOn" />
169+
</VisualState.Setters>
170+
</VisualState>
171+
</VisualStateGroup>
172+
173+
</VisualStateManager.VisualStateGroups>
174+
</Grid>
175+
</ControlTemplate>
176+
</Setter.Value>
177+
</Setter>
178+
</Style>
179+
180+
<Style x:Key="DefaultBreadcrumbEllipsisFlyoutStyle" TargetType="FlyoutPresenter">
181+
<Setter Property="Background" Value="{ThemeResource BreadcrumbBarEllipsisFlyoutPresenterBackground}" />
182+
<Setter Property="BorderBrush" Value="{ThemeResource BreadcrumbBarEllipsisFlyoutPresenterBorderBrush}" />
183+
<Setter Property="BorderThickness" Value="{ThemeResource BreadcrumbBarEllipsisFlyoutPresenterBorderThemeThickness}" />
184+
<Setter Property="Padding" Value="0,2" />
185+
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
186+
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto" />
187+
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
188+
<Setter Property="ScrollViewer.IsHorizontalRailEnabled" Value="False" />
189+
<Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="False" />
190+
<Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
191+
<Setter Property="MaxWidth" Value="{ThemeResource FlyoutThemeMaxWidth}" />
192+
<Setter Property="MinHeight" Value="40" />
193+
<Setter Property="CornerRadius" Value="{ThemeResource OverlayCornerRadius}" />
194+
<Setter Property="Template">
195+
<Setter.Value>
196+
<ControlTemplate TargetType="FlyoutPresenter">
197+
<Grid
198+
Background="{TemplateBinding Background}"
199+
BackgroundSizing="InnerBorderEdge"
200+
CornerRadius="{TemplateBinding CornerRadius}">
201+
<ScrollViewer
202+
x:Name="FlyoutPresenterScrollViewer"
203+
Margin="{TemplateBinding Padding}"
204+
AutomationProperties.AccessibilityView="Raw"
205+
Content="{TemplateBinding Content}"
206+
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
207+
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
208+
IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
209+
IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
210+
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
211+
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
212+
ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}" />
213+
<Border
214+
x:Name="FlyoutPresenterBorder"
215+
BorderBrush="{TemplateBinding BorderBrush}"
216+
BorderThickness="{TemplateBinding BorderThickness}"
217+
CornerRadius="{TemplateBinding CornerRadius}" />
218+
</Grid>
219+
</ControlTemplate>
220+
</Setter.Value>
221+
</Setter>
222+
</Style>
223+
224+
</ResourceDictionary>

0 commit comments

Comments
 (0)