Merge pull request #105 from irihitech/nav

Nav Menu Refactoring Step 1.
This commit is contained in:
Dong Bin
2024-02-14 21:09:55 +08:00
committed by GitHub
15 changed files with 1220 additions and 8 deletions

View File

@@ -0,0 +1,222 @@
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:Ursa.Themes.Semi.Converters"
xmlns:u="https://irihi.tech/ursa">
<!-- Add Resources Here -->
<converters:NavMenuMarginConverter x:Key="NavMarginConverter" />
<ControlTheme x:Key="{x:Type u:NavMenu}" TargetType="u:NavMenu">
<Setter Property="Grid.IsSharedSizeScope" Value="True" />
<Setter Property="SubMenuIndent" Value="24" />
<Setter Property="Template">
<ControlTemplate TargetType="u:NavMenu">
<DockPanel LastChildFill="True">
<ContentPresenter Content="{TemplateBinding Header}" DockPanel.Dock="Top"></ContentPresenter>
<ContentPresenter Content="{TemplateBinding Footer}" DockPanel.Dock="Bottom"></ContentPresenter>
<ScrollViewer HorizontalAlignment="Center" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<ItemsPresenter ItemsPanel="{TemplateBinding ItemsPanel}" />
</ScrollViewer>
</DockPanel>
</ControlTemplate>
</Setter>
<Style Selector="^:horizontal-collapsed">
<Setter Property="Width" Value="{x:Static x:Double.NaN}"></Setter>
<Setter Property="HorizontalAlignment" Value="Left"></Setter>
</Style>
</ControlTheme>
<ControlTemplate x:Key="DefaultNavMenuItemTemplate" TargetType="u:NavMenuItem">
<Grid RowDefinitions="Auto, *">
<Border
Name="PART_Border"
Grid.Row="0"
MinHeight="32"
Cursor="Hand"
Background="{TemplateBinding u:NavMenuItem.Background}"
CornerRadius="4">
<Grid
Name="PART_RootGrid"
HorizontalAlignment="Stretch"
VerticalAlignment="Center">
<Grid.Margin>
<MultiBinding Converter="{StaticResource NavMarginConverter}">
<Binding Path="SubMenuIndent" RelativeSource="{RelativeSource TemplatedParent}" />
<Binding Path="Level" RelativeSource="{RelativeSource TemplatedParent}" />
<Binding Path="IsHorizontalCollapsed" RelativeSource="{RelativeSource TemplatedParent}" />
</MultiBinding>
</Grid.Margin>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Icon" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Expander" />
</Grid.ColumnDefinitions>
<ContentPresenter
Name="PART_IconPresenter"
Padding="8"
HorizontalAlignment="Left"
Background="Transparent"
Content="{Binding Icon, RelativeSource={RelativeSource TemplatedParent}}"
ContentTemplate="{Binding IconTemplate, RelativeSource={RelativeSource TemplatedParent}}" />
<ContentPresenter
Name="PART_HeaderPresenter"
Grid.Column="1"
Padding="0,8"
Background="Transparent"
Content="{Binding Header, RelativeSource={RelativeSource TemplatedParent}}"
ContentTemplate="{Binding HeaderTemplate, RelativeSource={RelativeSource TemplatedParent}}" />
<PathIcon
Name="PART_ExpanderIcon"
Grid.Column="2"
Width="8"
Height="8"
Margin="12,0"
Data="{DynamicResource NavigationMenuItemExpandIconGlyph}"
Foreground="{DynamicResource NavigationMenuItemExpandIconForeground}">
<PathIcon.Transitions>
<Transitions>
<TransformOperationsTransition Property="RenderTransform" Duration="0.1" />
</Transitions>
</PathIcon.Transitions>
</PathIcon>
<Popup
Name="PART_Popup"
Grid.Column="0"
IsLightDismissEnabled="True"
Placement="RightEdgeAlignedTop"
PlacementTarget="{Binding #PART_Border}">
<Border
Margin="{DynamicResource NavigationMenuItemFlyoutMargin}"
Padding="{DynamicResource MenuFlyoutPadding}"
HorizontalAlignment="Stretch"
Background="{DynamicResource MenuFlyoutBackground}"
BorderBrush="{DynamicResource MenuFlyoutBorderBrush}"
BorderThickness="{DynamicResource MenuFlyoutBorderThickness}"
BoxShadow="{DynamicResource MenuFlyoutBorderBoxShadow}"
CornerRadius="{DynamicResource MenuFlyoutCornerRadius}">
<StackPanel Name="PART_OverflowPanel" />
</Border>
</Popup>
</Grid>
</Border>
<ItemsPresenter
Name="PART_ItemsPresenter"
Grid.Row="1"
Margin="0,4,0,0"
VerticalAlignment="Top"
Grid.IsSharedSizeScope="True"
ItemsPanel="{Binding ItemsPanel, RelativeSource={RelativeSource TemplatedParent}}"
RenderTransformOrigin="0.5,0">
<ItemsPresenter.Transitions>
<Transitions>
<DoubleTransition Property="Height" Duration="0.1" />
<TransformOperationsTransition Property="RenderTransform" Duration="0.1" />
</Transitions>
</ItemsPresenter.Transitions>
</ItemsPresenter>
</Grid>
</ControlTemplate>
<ControlTheme x:Key="{x:Type u:NavMenuItem}" TargetType="u:NavMenuItem">
<Setter Property="Background" Value="Transparent" />
<Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
<Setter Property="ItemsPanel">
<ItemsPanelTemplate>
<u:OverflowStackPanel />
</ItemsPanelTemplate>
</Setter>
<Setter Property="Template" Value="{StaticResource DefaultNavMenuItemTemplate}" />
<Style Selector="^:selected">
<Setter Property="Background" Value="{DynamicResource NavigationMenuItemSelectedBackground}" />
<Style Selector="^:pointerover">
<Setter Property="Background" Value="{DynamicResource NavigationMenuItemSelectedBackground}" />
</Style>
</Style>
<Style Selector="^:vertical-collapsed /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="Height" Value="0" />
<Setter Property="RenderTransform" Value="scale(1,0)" />
</Style>
<Style Selector="^:vertical-collapsed /template/ PathIcon#PART_ExpanderIcon">
<Setter Property="RenderTransform" Value="rotate(180deg)" />
</Style>
<Style Selector="^:empty /template/ PathIcon#PART_ExpanderIcon">
<Setter Property="IsVisible" Value="False" />
</Style>
<Style Selector="^ /template/ Border#PART_Border:pointerover">
<Setter Property="Background" Value="{DynamicResource NavigationMenuItemPointeroverBackground}" />
</Style>
<Style Selector="^:horizontal-collapsed:first-level">
<Setter Property="HorizontalAlignment" Value="Left"></Setter>
<Style Selector="^ /template/ Border#PART_Border">
<Setter Property="ToolTip.Tip" Value="{Binding Header, RelativeSource={RelativeSource TemplatedParent}}" />
<Setter Property="ToolTip.ShowDelay" Value="0" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<Style Selector="^ /template/ Border#PART_Border:pointerover">
<Setter Property="Background" Value="{DynamicResource NavigationMenuItemPointeroverBackground}" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_IconPresenter">
<Setter Property="Grid.ColumnSpan" Value="3" />
<Setter Property="Margin" Value="0 8"></Setter>
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_HeaderPresenter">
<Setter Property="IsVisible" Value="False" />
</Style>
<Style Selector="^ /template/ PathIcon#PART_ExpanderIcon">
<Setter Property="IsVisible" Value="False" />
</Style>
<Style Selector="^ /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="IsVisible" Value="False" />
</Style>
<Style Selector="^ /template/ Grid#PART_RootGrid">
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
</Style>
<Style Selector="^:horizontal-collapsed:not(:first-level)">
<Style Selector="^ /template/ PathIcon#PART_ExpanderIcon">
<Setter Property="RenderTransform" Value="rotate(-90deg)" />
</Style>
</Style>
<Style Selector="^[IsSeparator=True]">
<Setter Property="Template">
<ControlTemplate>
<StackPanel Cursor="No" Name="PART_RootPanel" Margin="{DynamicResource NavigationMenuSeparatorMargin}">
<ContentPresenter
Name="PART_HeaderPresenter"
Margin="{DynamicResource NavigationMenuSeparatorHeaderMargin}"
HorizontalAlignment="Left"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
Foreground="{DynamicResource TextBlockQuaternaryForeground}"
IsVisible="{TemplateBinding Header, Converter={x:Static ObjectConverters.IsNotNull}}">
<ContentPresenter.Styles>
<Style Selector="TextBlock">
<Setter Property="FontSize" Value="{DynamicResource NavigationMenuSeparatorHeaderFontSize}" />
</Style>
</ContentPresenter.Styles>
</ContentPresenter>
<Rectangle
Name="PART_SeparatorBorder"
Height="{DynamicResource NavigationMenuSeparatorBorderHeight}"
Margin="{DynamicResource NavigationMenuSeparatorBorderMargin}"
HorizontalAlignment="Stretch"
Fill="{DynamicResource SemiColorBorder}" />
</StackPanel>
</ControlTemplate>
</Setter>
<Style Selector="^:horizontal-collapsed:first-level">
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
<Style Selector="^ /template/ ContentPresenter#PART_HeaderPresenter">
<Setter Property="IsVisible" Value="False"></Setter>
</Style>
<Style Selector="^ /template/ Rectangle#PART_SeparatorBorder">
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
<Setter Property="Width" Value="12"></Setter>
</Style>
</Style>
</Style>
</ControlTheme>
</ResourceDictionary>

View File

@@ -18,6 +18,7 @@
<ResourceInclude Source="Loading.axaml" />
<ResourceInclude Source="MessageBox.axaml" />
<ResourceInclude Source="Navigation.axaml" />
<ResourceInclude Source="NavMenu.axaml" />
<ResourceInclude Source="NumericUpDown.axaml" />
<ResourceInclude Source="Pagination.axaml" />
<ResourceInclude Source="RangeSlider.axaml" />

View File

@@ -0,0 +1,17 @@
using System.Globalization;
using Avalonia;
using Avalonia.Data.Converters;
namespace Ursa.Themes.Semi.Converters;
public class NavMenuMarginConverter: IMultiValueConverter
{
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
{
if (values[0] is double indent && values[1] is int level && values[2] is bool b)
{
return b ? new Thickness() : new Thickness(indent * (level-1), 0, 0, 0);
}
return AvaloniaProperty.UnsetValue;
}
}