feat: add toggle registration.
This commit is contained in:
@@ -2,34 +2,50 @@
|
|||||||
x:Class="Ursa.Demo.Pages.NavMenuDemo"
|
x:Class="Ursa.Demo.Pages.NavMenuDemo"
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:converters="clr-namespace:Ursa.Demo.Converters"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:u="https://irihi.tech/ursa"
|
xmlns:u="https://irihi.tech/ursa"
|
||||||
xmlns:vm="using:Ursa.Demo.ViewModels"
|
xmlns:vm="using:Ursa.Demo.ViewModels"
|
||||||
xmlns:converters="clr-namespace:Ursa.Demo.Converters"
|
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800"
|
d:DesignWidth="800"
|
||||||
x:CompileBindings="True"
|
x:CompileBindings="True"
|
||||||
x:DataType="vm:NavMenuDemoViewModel"
|
x:DataType="vm:NavMenuDemoViewModel"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<converters:IconNameToPathConverter x:Key="IconConverter"/>
|
<converters:IconNameToPathConverter x:Key="IconConverter" />
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid ColumnDefinitions="Auto, Auto" RowDefinitions="Auto, Auto, *" HorizontalAlignment="Left">
|
<Grid
|
||||||
<ToggleButton Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Name="collapse">Collapse</ToggleButton>
|
HorizontalAlignment="Left"
|
||||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="{ReflectionBinding #menu.SelectedItem.Header}" />
|
ColumnDefinitions="Auto, Auto"
|
||||||
<Border Grid.Row="2" Grid.Column="0" Theme="{DynamicResource CardBorder}" HorizontalAlignment="Left" Padding="0">
|
RowDefinitions="Auto, Auto, *">
|
||||||
|
<ToggleButton
|
||||||
|
Name="collapse"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.ColumnSpan="2">
|
||||||
|
Collapse
|
||||||
|
</ToggleButton>
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Text="{ReflectionBinding #menu.SelectedItem.Header}" />
|
||||||
|
<Border
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="0"
|
||||||
|
Padding="0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Theme="{DynamicResource CardBorder}">
|
||||||
<u:NavMenu
|
<u:NavMenu
|
||||||
Name="menu"
|
Name="menu"
|
||||||
Header="Welcome to Ursa!"
|
|
||||||
HeaderBinding="{Binding Header}"
|
HeaderBinding="{Binding Header}"
|
||||||
IconBinding="{Binding IconIndex}"
|
IconBinding="{Binding IconIndex}"
|
||||||
IsHorizontalCollapsed="{Binding #collapse.IsChecked, Mode=OneWay}"
|
IsHorizontalCollapsed="{Binding #collapse.IsChecked, Mode=OneWay}"
|
||||||
ItemsSource="{Binding MenuItems}"
|
ItemsSource="{Binding MenuItems}"
|
||||||
SubMenuBinding="{Binding Children}">
|
SubMenuBinding="{Binding Children}">
|
||||||
<u:NavMenu.Styles>
|
<u:NavMenu.Styles>
|
||||||
<Style Selector="u|NavMenuItem" x:DataType="vm:MenuItem">
|
<Style x:DataType="vm:MenuItem" Selector="u|NavMenuItem">
|
||||||
<Setter Property="IsSeparator" Value="{Binding IsSeparator}"></Setter>
|
<Setter Property="IsSeparator" Value="{Binding IsSeparator}" />
|
||||||
</Style>
|
</Style>
|
||||||
</u:NavMenu.Styles>
|
</u:NavMenu.Styles>
|
||||||
<u:NavMenu.IconTemplate>
|
<u:NavMenu.IconTemplate>
|
||||||
@@ -37,26 +53,43 @@
|
|||||||
<u:TwoTonePathIcon
|
<u:TwoTonePathIcon
|
||||||
Width="16"
|
Width="16"
|
||||||
Height="16"
|
Height="16"
|
||||||
Data="{Binding Converter={StaticResource IconConverter}}"
|
|
||||||
StrokeBrush="{DynamicResource SemiGrey5}"
|
|
||||||
Foreground="{DynamicResource SemiGrey5}"
|
|
||||||
ActiveStrokeBrush="{DynamicResource SemiBlue5}"
|
|
||||||
ActiveForeground="{DynamicResource SemiBlue5}"
|
ActiveForeground="{DynamicResource SemiBlue5}"
|
||||||
IsActive="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=u:NavMenuItem}, Path=IsHighlighted, Mode=TwoWay}">
|
ActiveStrokeBrush="{DynamicResource SemiBlue5}"
|
||||||
</u:TwoTonePathIcon>
|
Data="{Binding Converter={StaticResource IconConverter}}"
|
||||||
|
Foreground="{DynamicResource SemiGrey5}"
|
||||||
|
IsActive="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=u:NavMenuItem}, Path=IsHighlighted, Mode=TwoWay}"
|
||||||
|
StrokeBrush="{DynamicResource SemiGrey5}" />
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</u:NavMenu.IconTemplate>
|
</u:NavMenu.IconTemplate>
|
||||||
<u:NavMenu.Footer>
|
<u:NavMenu.Header>
|
||||||
<Image
|
<Grid ColumnDefinitions="Auto, Auto" HorizontalAlignment="Center">
|
||||||
Width="48"
|
<Image
|
||||||
Height="48"
|
u:NavMenu.CanToggle="True"
|
||||||
RenderOptions.BitmapInterpolationMode="HighQuality"
|
Width="48"
|
||||||
Source="../Assets/Ursa.ico" />
|
Height="48"
|
||||||
</u:NavMenu.Footer>
|
Margin="4 12"
|
||||||
|
RenderOptions.BitmapInterpolationMode="HighQuality"
|
||||||
|
Source="../Assets/Ursa.ico" />
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="1"
|
||||||
|
Classes="H5"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="Ursa Avalonia"
|
||||||
|
IsVisible="{Binding !#menu.IsHorizontalCollapsed}"
|
||||||
|
Theme="{DynamicResource TitleTextBlock}" />
|
||||||
|
</Grid>
|
||||||
|
</u:NavMenu.Header>
|
||||||
</u:NavMenu>
|
</u:NavMenu>
|
||||||
</Border>
|
</Border>
|
||||||
<TextBlock Grid.Row="1" Grid.Column="1" Text="{ReflectionBinding #menu2.SelectedItem.Header}"></TextBlock>
|
<TextBlock
|
||||||
<u:NavMenu Grid.Row="2" Grid.Column="1" Name="menu2" IsHorizontalCollapsed="{Binding #collapse.IsChecked}">
|
Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Text="{ReflectionBinding #menu2.SelectedItem.Header}" />
|
||||||
|
<u:NavMenu
|
||||||
|
Name="menu2"
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="1"
|
||||||
|
IsHorizontalCollapsed="{Binding #collapse.IsChecked}">
|
||||||
<u:NavMenuItem Header="Menu 1">
|
<u:NavMenuItem Header="Menu 1">
|
||||||
<u:NavMenuItem.Icon>
|
<u:NavMenuItem.Icon>
|
||||||
<Rectangle
|
<Rectangle
|
||||||
@@ -64,9 +97,9 @@
|
|||||||
Height="10"
|
Height="10"
|
||||||
Fill="Red" />
|
Fill="Red" />
|
||||||
</u:NavMenuItem.Icon>
|
</u:NavMenuItem.Icon>
|
||||||
<u:NavMenuItem Header="Sub Menu 1"></u:NavMenuItem>
|
<u:NavMenuItem Header="Sub Menu 1" />
|
||||||
<u:NavMenuItem Header="Sub Menu 2"></u:NavMenuItem>
|
<u:NavMenuItem Header="Sub Menu 2" />
|
||||||
<u:NavMenuItem Header="Sub Menu 3"></u:NavMenuItem>
|
<u:NavMenuItem Header="Sub Menu 3" />
|
||||||
</u:NavMenuItem>
|
</u:NavMenuItem>
|
||||||
<u:NavMenuItem Header="Menu 2">
|
<u:NavMenuItem Header="Menu 2">
|
||||||
<u:NavMenuItem.Icon>
|
<u:NavMenuItem.Icon>
|
||||||
|
|||||||
@@ -128,6 +128,9 @@
|
|||||||
<Setter Property="Template" Value="{StaticResource DefaultNavMenuItemTemplate}" />
|
<Setter Property="Template" Value="{StaticResource DefaultNavMenuItemTemplate}" />
|
||||||
<Style Selector="^:selected">
|
<Style Selector="^:selected">
|
||||||
<Setter Property="Background" Value="{DynamicResource NavigationMenuItemSelectedBackground}" />
|
<Setter Property="Background" Value="{DynamicResource NavigationMenuItemSelectedBackground}" />
|
||||||
|
<Style Selector="^:pointerover">
|
||||||
|
<Setter Property="Background" Value="{DynamicResource NavigationMenuItemSelectedBackground}" />
|
||||||
|
</Style>
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="^:vertical-collapsed /template/ ItemsPresenter#PART_ItemsPresenter">
|
<Style Selector="^:vertical-collapsed /template/ ItemsPresenter#PART_ItemsPresenter">
|
||||||
<Setter Property="Height" Value="0" />
|
<Setter Property="Height" Value="0" />
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using Avalonia.Controls.Metadata;
|
|||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
using Avalonia.Controls.Templates;
|
using Avalonia.Controls.Templates;
|
||||||
using Avalonia.Data;
|
using Avalonia.Data;
|
||||||
|
using Avalonia.Input;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.LogicalTree;
|
using Avalonia.LogicalTree;
|
||||||
using Avalonia.Metadata;
|
using Avalonia.Metadata;
|
||||||
using Irihi.Avalonia.Shared.Helpers;
|
using Irihi.Avalonia.Shared.Helpers;
|
||||||
@@ -125,11 +127,39 @@ public class NavMenu: ItemsControl
|
|||||||
get => GetValue(FooterProperty);
|
get => GetValue(FooterProperty);
|
||||||
set => SetValue(FooterProperty, value);
|
set => SetValue(FooterProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly AttachedProperty<bool> CanToggleProperty =
|
||||||
|
AvaloniaProperty.RegisterAttached<NavMenu, InputElement, bool>("CanToggle");
|
||||||
|
|
||||||
|
public static void SetCanToggle(InputElement obj, bool value) => obj.SetValue(CanToggleProperty, value);
|
||||||
|
public static bool GetCanToggle(InputElement obj) => obj.GetValue(CanToggleProperty);
|
||||||
|
|
||||||
static NavMenu()
|
static NavMenu()
|
||||||
{
|
{
|
||||||
SelectedItemProperty.Changed.AddClassHandler<NavMenu, object?>((o, e) => o.OnSelectedItemChange(e));
|
SelectedItemProperty.Changed.AddClassHandler<NavMenu, object?>((o, e) => o.OnSelectedItemChange(e));
|
||||||
PropertyToPseudoClassMixin.Attach<NavMenu>(IsHorizontalCollapsedProperty, PC_HorizontalCollapsed);
|
PropertyToPseudoClassMixin.Attach<NavMenu>(IsHorizontalCollapsedProperty, PC_HorizontalCollapsed);
|
||||||
|
CanToggleProperty.Changed.AddClassHandler<InputElement, bool>(OnInputRegisteredAsToggle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnInputRegisteredAsToggle(InputElement input, AvaloniaPropertyChangedEventArgs<bool> e)
|
||||||
|
{
|
||||||
|
if (e.NewValue.Value)
|
||||||
|
{
|
||||||
|
input.AddHandler(PointerPressedEvent, OnElementToggle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
input.RemoveHandler(PointerPressedEvent, OnElementToggle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnElementToggle(object? sender, RoutedEventArgs args)
|
||||||
|
{
|
||||||
|
if (sender is not InputElement input) return;
|
||||||
|
var nav = input.FindLogicalAncestorOfType<NavMenu>();
|
||||||
|
if(nav is null) return;
|
||||||
|
bool collapsed = nav.IsHorizontalCollapsed;
|
||||||
|
nav.IsHorizontalCollapsed = !collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSelectedItemChange(AvaloniaPropertyChangedEventArgs<object?> args)
|
private void OnSelectedItemChange(AvaloniaPropertyChangedEventArgs<object?> args)
|
||||||
|
|||||||
Reference in New Issue
Block a user