Skip to content

Commit 13a9bf4

Browse files
authored
Merge pull request #804 from vgromfeld/addOptionsFlyout
Add options flyout
2 parents c1ea10c + 26b6aa6 commit 13a9bf4

3 files changed

Lines changed: 112 additions & 6 deletions

File tree

components/Ribbon/samples/RibbonCustomSample.xaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,16 @@
2727
</Style>
2828
</StackPanel.Resources>
2929

30-
<controls:Ribbon HorizontalAlignment="Stretch">
30+
<controls:Ribbon HorizontalAlignment="Stretch"
31+
OptionsAccessKey="O"
32+
OptionsAccessibleName="Options">
33+
34+
<controls:Ribbon.OptionsFlyout>
35+
<MenuFlyout Placement="BottomEdgeAlignedRight">
36+
<ToggleMenuFlyoutItem Text="Always show toolbar" />
37+
<MenuFlyoutItem Text="Configure" />
38+
</MenuFlyout>
39+
</controls:Ribbon.OptionsFlyout>
3140

3241
<controls:RibbonCollapsibleGroup AccessKey="AB"
3342
CollapsedAccessKey="AA"

components/Ribbon/src/Ribbon.cs

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ namespace CommunityToolkit.WinUI.Controls;
1919
[TemplateVisualState(GroupName = ScrollButtonGroupNameTemplatePart, Name = DecrementButtonStateTemplatePart)]
2020
[TemplateVisualState(GroupName = ScrollButtonGroupNameTemplatePart, Name = IncrementButtonStateTemplatePart)]
2121
[TemplateVisualState(GroupName = ScrollButtonGroupNameTemplatePart, Name = BothButtonsStateTemplatePart)]
22+
[TemplateVisualState(GroupName = OptionsGroupNameTemplatePart, Name = OptionsVisibleStateTemplatePart)]
23+
[TemplateVisualState(GroupName = OptionsGroupNameTemplatePart, Name = OptionsCollapsedStateTemplatePart)]
2224
public sealed partial class Ribbon : Control
2325
{
2426
private const string PanelTemplatePart = "Panel";
@@ -30,6 +32,9 @@ public sealed partial class Ribbon : Control
3032
private const string DecrementButtonStateTemplatePart = "DecrementButton";
3133
private const string IncrementButtonStateTemplatePart = "IncrementButton";
3234
private const string BothButtonsStateTemplatePart = "BothButtons";
35+
private const string OptionsGroupNameTemplatePart = "OptionsGroup";
36+
private const string OptionsVisibleStateTemplatePart = "OptionsVisible";
37+
private const string OptionsCollapsedStateTemplatePart = "OptionsCollapsed";
3338

3439
private Panel? _panel;
3540
private ScrollViewer? _scrollViewer;
@@ -47,20 +52,74 @@ public sealed partial class Ribbon : Control
4752
new PropertyMetadata(20.0));
4853

4954
/// <summary>
50-
/// The amount to add or remove from the current scroll position.
55+
/// The DP to store the <see cref="OptionsFlyout"/> property value.
56+
/// </summary>
57+
public static readonly DependencyProperty OptionsFlyoutProperty = DependencyProperty.Register(
58+
nameof(OptionsFlyout),
59+
typeof(FlyoutBase),
60+
typeof(Ribbon),
61+
new PropertyMetadata(null, OnOptionsFlyoutPropertyChanged));
62+
63+
/// <summary>
64+
/// The DP to store the <see cref="OptionsAccessibleName"/> property value.
65+
/// </summary>
66+
public static readonly DependencyProperty OptionsAccessibleNameProperty = DependencyProperty.Register(
67+
nameof(OptionsAccessibleName),
68+
typeof(string),
69+
typeof(Ribbon),
70+
new PropertyMetadata(string.Empty));
71+
72+
/// <summary>
73+
/// The DP to store the <see cref="OptionsAccessKey"/> property value.
74+
/// </summary>
75+
public static readonly DependencyProperty OptionsAccessKeyProperty = DependencyProperty.Register(
76+
nameof(OptionsAccessKey),
77+
typeof(string),
78+
typeof(Ribbon),
79+
new PropertyMetadata(string.Empty));
80+
81+
public Ribbon()
82+
{
83+
DefaultStyleKey = typeof(Ribbon);
84+
85+
_items = [];
86+
_items.CollectionChanged += OnItemsCollectionChanged;
87+
}
88+
89+
/// <summary>
90+
/// Gets or sets the amount to add or remove from the current scroll position.
5191
/// </summary>
5292
public double ScrollStep
5393
{
5494
get => (double)GetValue(ScrollStepProperty);
5595
set => SetValue(ScrollStepProperty, value);
5696
}
5797

58-
public Ribbon()
98+
/// <summary>
99+
/// Gets or sets the flyout to display when the user clicks on the ribbon options button.
100+
/// </summary>
101+
public FlyoutBase? OptionsFlyout
59102
{
60-
DefaultStyleKey = typeof(Ribbon);
103+
get => (FlyoutBase?)GetValue(OptionsFlyoutProperty);
104+
set => SetValue(OptionsFlyoutProperty, value);
105+
}
61106

62-
_items = [];
63-
_items.CollectionChanged += OnItemsCollectionChanged;
107+
/// <summary>
108+
/// Gets or sets the accessible name for the options button.
109+
/// </summary>
110+
public string OptionsAccessibleName
111+
{
112+
get => (string)GetValue(OptionsAccessibleNameProperty);
113+
set => SetValue(OptionsAccessibleNameProperty, value);
114+
}
115+
116+
/// <summary>
117+
/// Gets or sets the access key to set on the options flyout button.
118+
/// </summary>
119+
public string OptionsAccessKey
120+
{
121+
get => (string)GetValue(OptionsAccessKeyProperty);
122+
set => SetValue(OptionsAccessKeyProperty, value);
64123
}
65124

66125
public IList<UIElement> Items => _items;
@@ -97,6 +156,8 @@ protected override void OnApplyTemplate()
97156
_scrollViewer.SizeChanged += OnSizeChanged;
98157
UpdateScrollButtonsState();
99158
}
159+
160+
UpdateOptionsFlyoutState();
100161
}
101162

102163
private void OnItemsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
@@ -198,4 +259,15 @@ private void OnDecrementScrollViewer(object sender, RoutedEventArgs e)
198259

199260
private void OnIncrementScrollViewer(object sender, RoutedEventArgs e)
200261
=> _scrollViewer?.ChangeView(_scrollViewer.HorizontalOffset + ScrollStep, verticalOffset: null, zoomFactor: null);
262+
263+
private static void OnOptionsFlyoutPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
264+
{
265+
var ribbon = (Ribbon)d;
266+
ribbon.UpdateOptionsFlyoutState();
267+
}
268+
269+
private void UpdateOptionsFlyoutState() => VisualStateManager.GoToState(
270+
this,
271+
OptionsFlyout != null ? OptionsVisibleStateTemplatePart : OptionsCollapsedStateTemplatePart,
272+
useTransitions: true);
201273
}

components/Ribbon/src/RibbonStyle.xaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@
358358
<ColumnDefinition Width="Auto" />
359359
<ColumnDefinition Width="*" />
360360
<ColumnDefinition Width="Auto" />
361+
<ColumnDefinition Width="Auto" />
361362
</Grid.ColumnDefinitions>
362363

363364
<VisualStateManager.VisualStateGroups>
@@ -380,6 +381,14 @@
380381
</VisualState.Setters>
381382
</VisualState>
382383
</VisualStateGroup>
384+
<VisualStateGroup x:Name="OptionsGroup">
385+
<VisualState x:Name="OptionsCollapsed" />
386+
<VisualState x:Name="OptionsVisible">
387+
<VisualState.Setters>
388+
<Setter Target="OptionsButton.Visibility" Value="Visible" />
389+
</VisualState.Setters>
390+
</VisualState>
391+
</VisualStateGroup>
383392
</VisualStateManager.VisualStateGroups>
384393

385394
<ScrollViewer x:Name="ScrollViewer"
@@ -397,6 +406,22 @@
397406
Grid.Column="2"
398407
Style="{StaticResource RibbonScrollIncrementButtonStyle}"
399408
Visibility="Collapsed" />
409+
410+
<Button x:Name="OptionsButton"
411+
Grid.Column="3"
412+
Margin="4"
413+
Padding="4"
414+
VerticalAlignment="Bottom"
415+
AccessKey="{TemplateBinding OptionsAccessKey}"
416+
AutomationProperties.Name="{TemplateBinding OptionsAccessibleName}"
417+
Background="Transparent"
418+
BorderBrush="Transparent"
419+
Flyout="{TemplateBinding OptionsFlyout}"
420+
Visibility="Collapsed">
421+
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
422+
FontSize="12"
423+
Glyph="&#xE70D;" />
424+
</Button>
400425
</Grid>
401426
</ControlTemplate>
402427
</Setter.Value>

0 commit comments

Comments
 (0)