mirror of
https://gitee.com/chinware/atomui.git
synced 2024-11-29 18:38:16 +08:00
NavMenu dark mode completed
This commit is contained in:
parent
003cb21847
commit
8710ccbd48
@ -63,6 +63,7 @@ Welcome to communicate and give suggestions to AtomUI, thank you for giving the
|
||||
| Breadcrumb | TODO |
|
||||
| Dropdown | Completed ✅ |
|
||||
| Menu | Completed ✅ |
|
||||
| NavMenu | Completed ✅ |
|
||||
| Pagination | TODO |
|
||||
| Steps | TODO |
|
||||
|
||||
|
@ -90,7 +90,8 @@ PS: AtomUI 目前仅在 Windows 11 平台测试<br>
|
||||
|:---------------|:-------|
|
||||
| Breadcrumb 面包屑 | 未完成 |
|
||||
| Dropdown 下拉菜单 | 已完成 ✅ |
|
||||
| Menu 导航菜单 | 已完成 ✅ |
|
||||
| Menu 菜单 | 已完成 ✅ |
|
||||
| NavMenu 导航菜单 | 已完成 ✅ |
|
||||
| Pagination 分页 | 进行中 💪 |
|
||||
| Steps 步骤条 | 未完成 |
|
||||
|
||||
|
@ -241,7 +241,7 @@
|
||||
<atom:NavMenuItem Header="Option 1" />
|
||||
<atom:NavMenuItem Header="Option 2" />
|
||||
</atom:NavMenuItem>
|
||||
|
||||
|
||||
<atom:NavMenuItem Header="Item 2">
|
||||
<atom:NavMenuItem Header="Option 3" />
|
||||
<atom:NavMenuItem Header="Option 4" />
|
||||
@ -250,6 +250,36 @@
|
||||
<atom:NavMenuItem Header="Navigation Four"/>
|
||||
</atom:NavMenu>
|
||||
</desktop:ShowCaseItem>
|
||||
|
||||
<desktop:ShowCaseItem
|
||||
Title="Switch the menu type"
|
||||
Description="Show the dynamic switching mode (between inline and vertical).">
|
||||
<StackPanel Orientation="Vertical" Spacing="10">
|
||||
<StackPanel Orientation="Horizontal" Spacing="5">
|
||||
<atom:ToggleSwitch Name="ChangeModeSwitch"/>
|
||||
<TextBlock>Change Mode</TextBlock>
|
||||
<atom:ToggleSwitch Margin="10, 0, 0, 0" Name="ChangeStyleSwitch"/>
|
||||
<TextBlock>Change Style</TextBlock>
|
||||
</StackPanel>
|
||||
<atom:NavMenu Mode="{Binding Mode}" Width="256" Margin="0, 0, 0, 20" IsDarkStyle="{Binding IsDark}">
|
||||
<atom:NavMenuItem Header="Navigation One" Icon="{atom:IconProvider Kind=MailOutlined}" />
|
||||
<atom:NavMenuItem Header="Navigation Two" Icon="{atom:IconProvider Kind=AppstoreOutlined}" IsEnabled="False"/>
|
||||
<atom:NavMenuItem Header="Navigation Three - Submenu" Icon="{atom:IconProvider Kind=SettingOutlined}">
|
||||
<atom:NavMenuItem Header="Item 1">
|
||||
<atom:NavMenuItem Header="Option 1" />
|
||||
<atom:NavMenuItem Header="Option 2" />
|
||||
</atom:NavMenuItem>
|
||||
|
||||
<atom:NavMenuItem Header="Item 2">
|
||||
<atom:NavMenuItem Header="Option 3" />
|
||||
<atom:NavMenuItem Header="Option 4" />
|
||||
</atom:NavMenuItem>
|
||||
</atom:NavMenuItem>
|
||||
<atom:NavMenuItem Header="Navigation Four"/>
|
||||
</atom:NavMenu>
|
||||
</StackPanel>
|
||||
|
||||
</desktop:ShowCaseItem>
|
||||
|
||||
</desktop:ShowCasePanel>
|
||||
</UserControl>
|
@ -1,11 +1,66 @@
|
||||
using AtomUI.Controls;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace AtomUI.Demo.Desktop.ShowCase;
|
||||
|
||||
public partial class MenuShowCase : UserControl
|
||||
{
|
||||
public static readonly StyledProperty<bool> IsDarkProperty =
|
||||
AvaloniaProperty.Register<ButtonShowCase, bool>(nameof(IsDark), false);
|
||||
|
||||
public static readonly StyledProperty<NavMenuMode> ModeProperty =
|
||||
AvaloniaProperty.Register<ButtonShowCase, NavMenuMode>(nameof(Mode), NavMenuMode.Inline);
|
||||
|
||||
public bool IsDark
|
||||
{
|
||||
get => GetValue(IsDarkProperty);
|
||||
set => SetValue(IsDarkProperty, value);
|
||||
}
|
||||
|
||||
public NavMenuMode Mode
|
||||
{
|
||||
get => GetValue(ModeProperty);
|
||||
set => SetValue(ModeProperty, value);
|
||||
}
|
||||
|
||||
public MenuShowCase()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
ChangeModeSwitch.IsCheckedChanged += HandleChangeModeCheckChanged;
|
||||
ChangeStyleSwitch.IsCheckedChanged += HandleChangeStyleCheckChanged;
|
||||
}
|
||||
|
||||
private void HandleChangeModeCheckChanged(object? sender, RoutedEventArgs? args)
|
||||
{
|
||||
if (ChangeModeSwitch.IsChecked.HasValue)
|
||||
{
|
||||
if (ChangeModeSwitch.IsChecked.Value)
|
||||
{
|
||||
Mode = NavMenuMode.Vertical;
|
||||
}
|
||||
else
|
||||
{
|
||||
Mode = NavMenuMode.Inline;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Mode = NavMenuMode.Inline;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleChangeStyleCheckChanged(object? sender, RoutedEventArgs? args)
|
||||
{
|
||||
if (ChangeStyleSwitch.IsChecked.HasValue)
|
||||
{
|
||||
IsDark = ChangeStyleSwitch.IsChecked.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsDark = false;
|
||||
}
|
||||
}
|
||||
}
|
@ -406,6 +406,7 @@ namespace AtomUI.Theme.Styling
|
||||
public static readonly TokenResourceKey ItemContentMargin = new TokenResourceKey("NavMenu.ItemContentMargin", "AtomUI.Token");
|
||||
public static readonly TokenResourceKey ItemContentPadding = new TokenResourceKey("NavMenu.ItemContentPadding", "AtomUI.Token");
|
||||
public static readonly TokenResourceKey VerticalItemsPanelSpacing = new TokenResourceKey("NavMenu.VerticalItemsPanelSpacing", "AtomUI.Token");
|
||||
public static readonly TokenResourceKey VerticalMenuContentPadding = new TokenResourceKey("NavMenu.VerticalMenuContentPadding", "AtomUI.Token");
|
||||
public static readonly TokenResourceKey ItemMargin = new TokenResourceKey("NavMenu.ItemMargin", "AtomUI.Token");
|
||||
public static readonly TokenResourceKey HorizontalItemMargin = new TokenResourceKey("NavMenu.HorizontalItemMargin", "AtomUI.Token");
|
||||
public static readonly TokenResourceKey HorizontalItemHoverBg = new TokenResourceKey("NavMenu.HorizontalItemHoverBg", "AtomUI.Token");
|
||||
|
@ -20,7 +20,7 @@ namespace AtomUI.Controls;
|
||||
|
||||
internal class BaseNavMenuItemTheme : BaseControlTheme
|
||||
{
|
||||
public const string ItemDecoratorPart = "PART_ItemDecorator";
|
||||
public const string HeaderDecoratorPart = "PART_HeaderDecorator";
|
||||
public const string MainContainerPart = "PART_MainContainer";
|
||||
public const string ItemIconPresenterPart = "PART_ItemIconPresenter";
|
||||
public const string ItemTextPresenterPart = "PART_ItemTextPresenter";
|
||||
@ -35,7 +35,6 @@ internal class BaseNavMenuItemTheme : BaseControlTheme
|
||||
{
|
||||
return new FuncControlTemplate<NavMenuItem>((item, scope) =>
|
||||
{
|
||||
BuildInstanceStyles(item);
|
||||
// 仅仅为了把 Popup 包进来,没有其他什么作用
|
||||
var layoutWrapper = new Panel();
|
||||
var header = BuildMenuItemContent(item, scope);
|
||||
@ -49,13 +48,14 @@ internal class BaseNavMenuItemTheme : BaseControlTheme
|
||||
{
|
||||
var headerFrame = new Border
|
||||
{
|
||||
Name = ItemDecoratorPart
|
||||
Name = HeaderDecoratorPart,
|
||||
Transitions = new Transitions()
|
||||
{
|
||||
AnimationUtils.CreateTransition<SolidColorBrushTransition>(Border.BackgroundProperty),
|
||||
AnimationUtils.CreateTransition<SolidColorBrushTransition>(TemplatedControl.ForegroundProperty)
|
||||
}
|
||||
};
|
||||
|
||||
var transitions = new Transitions();
|
||||
transitions.Add(AnimationUtils.CreateTransition<SolidColorBrushTransition>(Border.BackgroundProperty));
|
||||
headerFrame.Transitions = transitions;
|
||||
|
||||
headerFrame.RegisterInNameScope(scope);
|
||||
headerFrame.Child = BuildMenuItemInfoGrid(navMenuItem, scope);
|
||||
return headerFrame;
|
||||
}
|
||||
@ -84,17 +84,16 @@ internal class BaseNavMenuItemTheme : BaseControlTheme
|
||||
};
|
||||
layout.RegisterInNameScope(scope);
|
||||
|
||||
var iconPresenter = new Viewbox
|
||||
var iconPresenter = new ContentPresenter()
|
||||
{
|
||||
Name = ItemIconPresenterPart,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Stretch = Stretch.Uniform
|
||||
};
|
||||
|
||||
Grid.SetColumn(iconPresenter, 0);
|
||||
iconPresenter.RegisterInNameScope(scope);
|
||||
CreateTemplateParentBinding(iconPresenter, Viewbox.ChildProperty, NavMenuItem.IconProperty);
|
||||
CreateTemplateParentBinding(iconPresenter, ContentPresenter.ContentProperty, NavMenuItem.IconProperty);
|
||||
TokenResourceBinder.CreateTokenBinding(iconPresenter, Layoutable.MarginProperty,
|
||||
NavMenuTokenResourceKey.ItemMargin);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(iconPresenter, Layoutable.WidthProperty,
|
||||
@ -161,17 +160,9 @@ internal class BaseNavMenuItemTheme : BaseControlTheme
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Kind = "RightOutlined"
|
||||
};
|
||||
|
||||
|
||||
CreateTemplateParentBinding(menuIndicatorIcon, PathIcon.IsEnabledProperty, NavMenuItem.IsEnabledProperty);
|
||||
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(menuIndicatorIcon, PathIcon.NormalFilledBrushProperty,
|
||||
NavMenuTokenResourceKey.ItemColor);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(menuIndicatorIcon, PathIcon.SelectedFilledBrushProperty,
|
||||
NavMenuTokenResourceKey.ItemSelectedColor);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(menuIndicatorIcon, PathIcon.DisabledFilledBrushProperty,
|
||||
NavMenuTokenResourceKey.ItemDisabledColor);
|
||||
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(menuIndicatorIcon, Layoutable.WidthProperty,
|
||||
NavMenuTokenResourceKey.MenuArrowSize);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(menuIndicatorIcon, Layoutable.HeightProperty,
|
||||
@ -199,17 +190,17 @@ internal class BaseNavMenuItemTheme : BaseControlTheme
|
||||
commonStyle.Add(keyGestureStyle);
|
||||
}
|
||||
{
|
||||
var borderStyle = new Style(selector => selector.Nesting().Template().Name(ItemDecoratorPart));
|
||||
var borderStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
|
||||
borderStyle.Add(Border.CursorProperty, new Cursor(StandardCursorType.Hand));
|
||||
borderStyle.Add(Layoutable.MinHeightProperty, NavMenuTokenResourceKey.ItemHeight);
|
||||
borderStyle.Add(Decorator.PaddingProperty, NavMenuTokenResourceKey.ItemContentPadding);
|
||||
borderStyle.Add(Border.MinHeightProperty, NavMenuTokenResourceKey.ItemHeight);
|
||||
borderStyle.Add(Border.PaddingProperty, NavMenuTokenResourceKey.ItemContentPadding);
|
||||
borderStyle.Add(Border.BackgroundProperty, NavMenuTokenResourceKey.ItemBg);
|
||||
borderStyle.Add(Border.CornerRadiusProperty, NavMenuTokenResourceKey.ItemBorderRadius);
|
||||
commonStyle.Add(borderStyle);
|
||||
}
|
||||
|
||||
// Hover 状态
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Template().Name(ItemDecoratorPart).Class(StdPseudoClass.PointerOver));
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart).Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(TemplatedControl.ForegroundProperty, NavMenuTokenResourceKey.ItemHoverColor);
|
||||
hoverStyle.Add(Border.BackgroundProperty, NavMenuTokenResourceKey.ItemHoverBg);
|
||||
commonStyle.Add(hoverStyle);
|
||||
@ -219,7 +210,7 @@ internal class BaseNavMenuItemTheme : BaseControlTheme
|
||||
{
|
||||
var selectedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Selected));
|
||||
{
|
||||
var itemDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(ItemDecoratorPart));
|
||||
var itemDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
|
||||
itemDecoratorStyle.Add(Border.BackgroundProperty, NavMenuTokenResourceKey.ItemSelectedBg);
|
||||
itemDecoratorStyle.Add(TemplatedControl.ForegroundProperty, NavMenuTokenResourceKey.ItemSelectedColor);
|
||||
selectedStyle.Add(itemDecoratorStyle);
|
||||
@ -232,7 +223,7 @@ internal class BaseNavMenuItemTheme : BaseControlTheme
|
||||
{
|
||||
var selectedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Selected));
|
||||
{
|
||||
var itemDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(ItemDecoratorPart));
|
||||
var itemDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
|
||||
itemDecoratorStyle.Add(TemplatedControl.ForegroundProperty, NavMenuTokenResourceKey.ItemSelectedColor);
|
||||
selectedStyle.Add(itemDecoratorStyle);
|
||||
}
|
||||
@ -240,25 +231,94 @@ internal class BaseNavMenuItemTheme : BaseControlTheme
|
||||
}
|
||||
commonStyle.Add(hasSubMenuStyle);
|
||||
Add(commonStyle);
|
||||
|
||||
BuildDarkCommonStyle();
|
||||
}
|
||||
|
||||
private void BuildDarkCommonStyle()
|
||||
{
|
||||
var darkCommonStyle = new Style(selector => selector.Nesting().PropertyEquals(NavMenuItem.IsDarkStyleProperty, true));
|
||||
darkCommonStyle.Add(NavMenuItem.ForegroundProperty, NavMenuTokenResourceKey.DarkItemColor);
|
||||
|
||||
{
|
||||
var borderStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
|
||||
borderStyle.Add(Border.BackgroundProperty, NavMenuTokenResourceKey.DarkItemBg);
|
||||
darkCommonStyle.Add(borderStyle);
|
||||
}
|
||||
|
||||
// 选中分两种,一种是有子菜单一种是没有子菜单
|
||||
var hasNoSubMenuStyle = new Style(selector => selector.Nesting().PropertyEquals(NavMenuItem.HasSubMenuProperty, false));
|
||||
{
|
||||
// Hover 状态
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart).Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(TemplatedControl.ForegroundProperty, NavMenuTokenResourceKey.DarkItemHoverColor);
|
||||
hoverStyle.Add(Border.BackgroundProperty, NavMenuTokenResourceKey.DarkItemHoverBg);
|
||||
hasNoSubMenuStyle.Add(hoverStyle);
|
||||
|
||||
var selectedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Selected));
|
||||
{
|
||||
var itemDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
|
||||
itemDecoratorStyle.Add(Border.BackgroundProperty, NavMenuTokenResourceKey.DarkItemSelectedBg);
|
||||
itemDecoratorStyle.Add(TemplatedControl.ForegroundProperty, NavMenuTokenResourceKey.DarkItemSelectedColor);
|
||||
selectedStyle.Add(itemDecoratorStyle);
|
||||
}
|
||||
hasNoSubMenuStyle.Add(selectedStyle);
|
||||
}
|
||||
darkCommonStyle.Add(hasNoSubMenuStyle);
|
||||
|
||||
var hasSubMenuStyle = new Style(selector => selector.Nesting().PropertyEquals(NavMenuItem.HasSubMenuProperty, true));
|
||||
{
|
||||
// Hover 状态
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart).Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(TemplatedControl.ForegroundProperty, NavMenuTokenResourceKey.DarkItemColor);
|
||||
hoverStyle.Add(Border.BackgroundProperty, NavMenuTokenResourceKey.DarkItemBg);
|
||||
hasSubMenuStyle.Add(hoverStyle);
|
||||
|
||||
var selectedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Selected));
|
||||
{
|
||||
var itemDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
|
||||
itemDecoratorStyle.Add(TemplatedControl.ForegroundProperty, NavMenuTokenResourceKey.DarkItemSelectedColor);
|
||||
selectedStyle.Add(itemDecoratorStyle);
|
||||
}
|
||||
hasSubMenuStyle.Add(selectedStyle);
|
||||
}
|
||||
darkCommonStyle.Add(hasSubMenuStyle);
|
||||
|
||||
Add(darkCommonStyle);
|
||||
}
|
||||
|
||||
private void BuildMenuIndicatorStyle()
|
||||
{
|
||||
{
|
||||
{
|
||||
var menuIndicatorStyle = new Style(selector => selector.Nesting().Template().Name(MenuIndicatorIconPart));
|
||||
menuIndicatorStyle.Add(Visual.IsVisibleProperty, true);
|
||||
Add(menuIndicatorStyle);
|
||||
}
|
||||
var menuIndicatorStyle = new Style(selector => selector.Nesting().Template().Name(MenuIndicatorIconPart));
|
||||
menuIndicatorStyle.Add(Visual.IsVisibleProperty, true);
|
||||
menuIndicatorStyle.Add(PathIcon.NormalFilledBrushProperty, NavMenuTokenResourceKey.ItemColor);
|
||||
menuIndicatorStyle.Add(PathIcon.SelectedFilledBrushProperty, NavMenuTokenResourceKey.ItemSelectedColor);
|
||||
menuIndicatorStyle.Add(PathIcon.DisabledFilledBrushProperty, NavMenuTokenResourceKey.ItemDisabledColor);
|
||||
// 设置颜色
|
||||
|
||||
var selectedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Selected));
|
||||
Add(menuIndicatorStyle);
|
||||
}
|
||||
{
|
||||
var darkCommonStyle = new Style(selector => selector.Nesting().PropertyEquals(NavMenuItem.IsDarkStyleProperty, true));
|
||||
{
|
||||
var menuIndicatorStyle = new Style(selector => selector.Nesting().Template().Name(MenuIndicatorIconPart));
|
||||
menuIndicatorStyle.Add(PathIcon.IconModeProperty, IconMode.Selected);
|
||||
selectedStyle.Add(menuIndicatorStyle);
|
||||
menuIndicatorStyle.Add(PathIcon.NormalFilledBrushProperty, NavMenuTokenResourceKey.DarkItemColor);
|
||||
menuIndicatorStyle.Add(PathIcon.SelectedFilledBrushProperty, NavMenuTokenResourceKey.DarkItemSelectedColor);
|
||||
menuIndicatorStyle.Add(PathIcon.DisabledFilledBrushProperty, NavMenuTokenResourceKey.DarkItemDisabledColor);
|
||||
darkCommonStyle.Add(menuIndicatorStyle);
|
||||
}
|
||||
Add(selectedStyle);
|
||||
Add(darkCommonStyle);
|
||||
}
|
||||
|
||||
var selectedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Selected));
|
||||
{
|
||||
var menuIndicatorStyle = new Style(selector => selector.Nesting().Template().Name(MenuIndicatorIconPart));
|
||||
menuIndicatorStyle.Add(PathIcon.IconModeProperty, IconMode.Selected);
|
||||
selectedStyle.Add(menuIndicatorStyle);
|
||||
}
|
||||
Add(selectedStyle);
|
||||
|
||||
var hasNoSubMenuStyle = new Style(selector => selector.Nesting().PropertyEquals(NavMenuItem.HasSubMenuProperty, false));
|
||||
{
|
||||
var menuIndicatorStyle = new Style(selector => selector.Nesting().Template().Name(MenuIndicatorIconPart));
|
||||
@ -271,41 +331,34 @@ internal class BaseNavMenuItemTheme : BaseControlTheme
|
||||
private void BuildMenuIconStyle()
|
||||
{
|
||||
{
|
||||
var iconViewBoxStyle = new Style(selector => selector.Nesting().Template().Name(ItemIconPresenterPart));
|
||||
iconViewBoxStyle.Add(Visual.IsVisibleProperty, false);
|
||||
Add(iconViewBoxStyle);
|
||||
var iconContentPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ItemIconPresenterPart));
|
||||
iconContentPresenterStyle.Add(Visual.IsVisibleProperty, false);
|
||||
Add(iconContentPresenterStyle);
|
||||
}
|
||||
|
||||
var hasIconStyle = new Style(selector => selector.Nesting().Class(":icon"));
|
||||
{
|
||||
var iconViewBoxStyle = new Style(selector => selector.Nesting().Template().Name(ItemIconPresenterPart));
|
||||
iconViewBoxStyle.Add(Visual.IsVisibleProperty, true);
|
||||
hasIconStyle.Add(iconViewBoxStyle);
|
||||
var iconContentPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ItemIconPresenterPart));
|
||||
iconContentPresenterStyle.Add(Visual.IsVisibleProperty, true);
|
||||
hasIconStyle.Add(iconContentPresenterStyle);
|
||||
}
|
||||
Add(hasIconStyle);
|
||||
}
|
||||
|
||||
private void BuildDisabledStyle()
|
||||
{
|
||||
var disabledStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled));
|
||||
disabledStyle.Add(TemplatedControl.ForegroundProperty, NavMenuTokenResourceKey.ItemDisabledColor);
|
||||
Add(disabledStyle);
|
||||
{
|
||||
var disabledStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled));
|
||||
disabledStyle.Add(TemplatedControl.ForegroundProperty, NavMenuTokenResourceKey.ItemDisabledColor);
|
||||
Add(disabledStyle);
|
||||
}
|
||||
var darkStyle = new Style(selector => selector.Nesting().PropertyEquals(NavMenuItem.IsDarkStyleProperty, true));
|
||||
{
|
||||
var disabledStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled));
|
||||
disabledStyle.Add(TemplatedControl.ForegroundProperty, NavMenuTokenResourceKey.DarkItemDisabledColor);
|
||||
darkStyle.Add(disabledStyle);
|
||||
}
|
||||
Add(darkStyle);
|
||||
}
|
||||
|
||||
protected override void BuildInstanceStyles(Control control)
|
||||
{
|
||||
{
|
||||
var iconStyle = new Style(selector => selector.Name(ThemeConstants.ItemIconPart));
|
||||
iconStyle.Add(PathIcon.WidthProperty, NavMenuTokenResourceKey.ItemIconSize);
|
||||
iconStyle.Add(PathIcon.HeightProperty, NavMenuTokenResourceKey.ItemIconSize);
|
||||
iconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalTokenResourceKey.ColorText);
|
||||
iconStyle.Add(PathIcon.DisabledFilledBrushProperty, NavMenuTokenResourceKey.ItemDisabledColor);
|
||||
iconStyle.Add(PathIcon.SelectedFilledBrushProperty, GlobalTokenResourceKey.ColorPrimary);
|
||||
control.Styles.Add(iconStyle);
|
||||
}
|
||||
|
||||
var disabledIconStyle = new Style(selector => selector.OfType<PathIcon>().Class(StdPseudoClass.Disabled));
|
||||
disabledIconStyle.Add(PathIcon.IconModeProperty, IconMode.Disabled);
|
||||
control.Styles.Add(disabledIconStyle);
|
||||
}
|
||||
}
|
@ -56,20 +56,21 @@ internal class InlineNavMenuItemTheme : BaseNavMenuItemTheme
|
||||
|
||||
var headerContent = base.BuildMenuItemContent(navMenuItem, scope);
|
||||
|
||||
TokenResourceBinder.CreateTokenBinding(headerContent, Control.MarginProperty, NavMenuTokenResourceKey.VerticalItemsPanelSpacing, BindingPriority.Template,
|
||||
(v) =>
|
||||
{
|
||||
if (v is double dval)
|
||||
{
|
||||
return new Thickness(0, 0, 0, dval);
|
||||
}
|
||||
|
||||
return new Thickness();
|
||||
});
|
||||
var childItemsLayoutTransform = new LayoutTransformControl()
|
||||
{
|
||||
Name = ChildItemsLayoutTransformPart,
|
||||
};
|
||||
TokenResourceBinder.CreateTokenBinding(childItemsLayoutTransform, LayoutTransformControl.MarginProperty,
|
||||
NavMenuTokenResourceKey.VerticalItemsPanelSpacing, BindingPriority.Template,
|
||||
(v) =>
|
||||
{
|
||||
if (v is double dval)
|
||||
{
|
||||
return new Thickness(0, dval, 0, 0);
|
||||
}
|
||||
|
||||
return new Thickness();
|
||||
});
|
||||
childItemsLayoutTransform.RegisterInNameScope(scope);
|
||||
|
||||
var itemsPresenter = new ItemsPresenter
|
||||
@ -106,6 +107,10 @@ internal class InlineNavMenuItemTheme : BaseNavMenuItemTheme
|
||||
{
|
||||
base.BuildStyles();
|
||||
BuildMenuIndicatorStyle();
|
||||
|
||||
var itemsPanelStyle = new Style(selector => selector.Nesting().Template().Name(ChildItemsPresenterPart).Child().OfType<StackPanel>());
|
||||
itemsPanelStyle.Add(StackPanel.SpacingProperty, NavMenuTokenResourceKey.VerticalItemsPanelSpacing);
|
||||
Add(itemsPanelStyle);
|
||||
}
|
||||
|
||||
private void BuildMenuIndicatorStyle()
|
||||
|
@ -147,13 +147,20 @@ public class NavMenu : NavMenuBase
|
||||
{
|
||||
if (change.Property == ModeProperty)
|
||||
{
|
||||
SetupItemContainerTheme(true);
|
||||
SetupInteractionHandler(true);
|
||||
HandleModeChanged();
|
||||
}
|
||||
UpdatePseudoClasses();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleModeChanged()
|
||||
{
|
||||
CloseChildItemsRecursively();
|
||||
SetupItemContainerTheme(true);
|
||||
RegenerateContainersRecursively();
|
||||
SetupInteractionHandler(true);
|
||||
}
|
||||
|
||||
protected override void PrepareContainerForItemOverride(Control element, object? item, int index)
|
||||
{
|
||||
base.PrepareContainerForItemOverride(element, item, index);
|
||||
@ -172,7 +179,9 @@ public class NavMenu : NavMenuBase
|
||||
BindUtils.RelayBind(this, ActiveBarWidthProperty, navMenuItem, NavMenuItem.ActiveBarWidthProperty);
|
||||
}
|
||||
BindUtils.RelayBind(this, ModeProperty, navMenuItem, NavMenuItem.ModeProperty);
|
||||
BindUtils.RelayBind(this, IsDarkStyleProperty, navMenuItem, NavMenuItem.IsDarkStyleProperty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void UpdatePseudoClasses()
|
||||
@ -276,4 +285,48 @@ public class NavMenu : NavMenuBase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseChildItemsRecursively()
|
||||
{
|
||||
CloseInlineItems();
|
||||
foreach (var i in ((INavMenu)this).SubItems)
|
||||
{
|
||||
i.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void RegenerateContainersRecursively()
|
||||
{
|
||||
foreach (var item in Items)
|
||||
{
|
||||
if (item is NavMenuItem navMenuItem)
|
||||
{
|
||||
navMenuItem.RegenerateContainers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseInlineItems()
|
||||
{
|
||||
foreach (var item in Items)
|
||||
{
|
||||
if (item is NavMenuItem navMenuItem)
|
||||
{
|
||||
CloseInlineItemRecursively(navMenuItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseInlineItemRecursively(NavMenuItem navMenuItem)
|
||||
{
|
||||
foreach (var item in navMenuItem.Items)
|
||||
{
|
||||
if (item is NavMenuItem childNavMenuItem)
|
||||
{
|
||||
CloseInlineItemRecursively(childNavMenuItem);
|
||||
}
|
||||
}
|
||||
navMenuItem.CloseInlineItem();
|
||||
navMenuItem.IsSubMenuOpen = false;
|
||||
}
|
||||
}
|
@ -61,8 +61,8 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
/// <summary>
|
||||
/// Defines the <see cref="Icon"/> property.
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<object?> IconProperty =
|
||||
AvaloniaProperty.Register<NavMenuItem, object?>(nameof(Icon));
|
||||
public static readonly StyledProperty<PathIcon?> IconProperty =
|
||||
AvaloniaProperty.Register<NavMenuItem, PathIcon?>(nameof(Icon));
|
||||
|
||||
/// <summary>
|
||||
/// Defines the <see cref="InputGesture"/> property.
|
||||
@ -71,7 +71,7 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
AvaloniaProperty.Register<NavMenuItem, KeyGesture?>(nameof(InputGesture));
|
||||
|
||||
/// <summary>
|
||||
/// Defines the <see cref="IsSubMenuOpen"/> property.
|
||||
/// Defines the <see cref="IsSubMenuOpen"/> property.
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<bool> IsSubMenuOpenProperty =
|
||||
AvaloniaProperty.Register<NavMenuItem, bool>(nameof(IsSubMenuOpen));
|
||||
@ -126,7 +126,7 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
/// <summary>
|
||||
/// Gets or sets the icon that appears in a <see cref="NavMenuItem"/>.
|
||||
/// </summary>
|
||||
public object? Icon
|
||||
public PathIcon? Icon
|
||||
{
|
||||
get => GetValue(IconProperty);
|
||||
set => SetValue(IconProperty, value);
|
||||
@ -285,6 +285,11 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
o => o.InlineItemIndentUnit,
|
||||
(o, v) => o.InlineItemIndentUnit = v);
|
||||
|
||||
internal static readonly DirectProperty<NavMenuItem, bool> IsDarkStyleProperty =
|
||||
AvaloniaProperty.RegisterDirect<NavMenuItem, bool>(nameof(IsDarkStyle),
|
||||
o => o.IsDarkStyle,
|
||||
(o, v) => o.IsDarkStyle = v);
|
||||
|
||||
internal double ActiveBarWidth
|
||||
{
|
||||
get => GetValue(ActiveBarWidthProperty);
|
||||
@ -340,6 +345,14 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
set => SetAndRaise(InlineItemIndentUnitProperty, ref _inlineItemIndentUnit, value);
|
||||
}
|
||||
|
||||
private bool _isDarkStyle;
|
||||
|
||||
internal bool IsDarkStyle
|
||||
{
|
||||
get => _isDarkStyle;
|
||||
set => SetAndRaise(IsDarkStyleProperty, ref _isDarkStyle, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 公共事件定义
|
||||
@ -444,6 +457,7 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
private Border? _horizontalFrame;
|
||||
private IDisposable? _itemContainerThemeDisposable;
|
||||
private LayoutTransformControl? _childItemsLayoutTransform;
|
||||
private Border? _headerFrame;
|
||||
private bool _animating = false;
|
||||
|
||||
static NavMenuItem()
|
||||
@ -639,7 +653,13 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
_popup.DependencyResolver = null;
|
||||
}
|
||||
|
||||
_popup = e.NameScope.Find<Popup>("PART_Popup");
|
||||
_popup = e.NameScope.Find<Popup>(ThemeConstants.PopupPart);
|
||||
_headerFrame = e.NameScope.Find<Border>(BaseNavMenuItemTheme.HeaderDecoratorPart);
|
||||
if (_headerFrame is not null)
|
||||
{
|
||||
_headerFrame.PointerEntered += HandleHeaderFrameEnter;
|
||||
_headerFrame.PointerExited += HandleHeaderFrameExit;
|
||||
}
|
||||
|
||||
if (_popup != null)
|
||||
{
|
||||
@ -670,6 +690,34 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleHeaderFrameEnter(object? sender, PointerEventArgs args)
|
||||
{
|
||||
if (!IsDarkStyle || Icon is null || HasSubMenu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Icon.IconMode = IconMode.Active;
|
||||
}
|
||||
|
||||
private void HandleHeaderFrameExit(object? sender, PointerEventArgs args)
|
||||
{
|
||||
if (!IsDarkStyle || Icon is null || HasSubMenu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsSelected)
|
||||
{
|
||||
Icon.IconMode = IconMode.Selected;
|
||||
}
|
||||
else
|
||||
{
|
||||
Icon.IconMode = IconMode.Normal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void UpdateDataValidation(
|
||||
AvaloniaProperty property,
|
||||
BindingValueType state,
|
||||
@ -816,10 +864,7 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
{
|
||||
SetupHorizontalEffectiveIndicatorWidth();
|
||||
}
|
||||
else if (change.Property == IconProperty)
|
||||
{
|
||||
SetupItemIcon();
|
||||
} else if (change.Property == ModeProperty)
|
||||
else if (change.Property == ModeProperty)
|
||||
{
|
||||
SetupItemContainerTheme(true);
|
||||
} else if (change.Property == ItemCountProperty)
|
||||
@ -832,14 +877,36 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
{
|
||||
SetupEffectivePopupMinWidth();
|
||||
}
|
||||
|
||||
|
||||
if (change.Property == IconProperty ||
|
||||
change.Property == IsDarkStyleProperty)
|
||||
{
|
||||
SetupItemIcon();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupItemIcon()
|
||||
{
|
||||
if (Icon is not null && Icon is PathIcon menuItemIcon)
|
||||
{
|
||||
menuItemIcon.Name = ThemeConstants.ItemIconPart;
|
||||
BindUtils.RelayBind(this, IsEnabledProperty, menuItemIcon, PathIcon.IsEnabledProperty);
|
||||
TokenResourceBinder.CreateTokenBinding(menuItemIcon, PathIcon.WidthProperty, NavMenuTokenResourceKey.ItemIconSize);
|
||||
TokenResourceBinder.CreateTokenBinding(menuItemIcon, PathIcon.HeightProperty, NavMenuTokenResourceKey.ItemIconSize);
|
||||
|
||||
if (IsDarkStyle)
|
||||
{
|
||||
TokenResourceBinder.CreateTokenBinding(menuItemIcon, PathIcon.NormalFilledBrushProperty, NavMenuTokenResourceKey.DarkItemColor);
|
||||
TokenResourceBinder.CreateTokenBinding(menuItemIcon, PathIcon.SelectedFilledBrushProperty, NavMenuTokenResourceKey.DarkItemSelectedColor);
|
||||
TokenResourceBinder.CreateTokenBinding(menuItemIcon, PathIcon.ActiveFilledBrushProperty, NavMenuTokenResourceKey.DarkItemHoverColor);
|
||||
TokenResourceBinder.CreateTokenBinding(menuItemIcon, PathIcon.DisabledFilledBrushProperty, NavMenuTokenResourceKey.DarkItemDisabledColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
TokenResourceBinder.CreateTokenBinding(menuItemIcon, PathIcon.NormalFilledBrushProperty, NavMenuTokenResourceKey.ItemColor);
|
||||
TokenResourceBinder.CreateTokenBinding(menuItemIcon, PathIcon.SelectedFilledBrushProperty, NavMenuTokenResourceKey.ItemSelectedColor);
|
||||
TokenResourceBinder.CreateTokenBinding(menuItemIcon, PathIcon.ActiveFilledBrushProperty, NavMenuTokenResourceKey.ItemHoverColor);
|
||||
TokenResourceBinder.CreateTokenBinding(menuItemIcon, PathIcon.DisabledFilledBrushProperty, NavMenuTokenResourceKey.ItemDisabledColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -901,7 +968,7 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
/// <param name="e">The property change event.</param>
|
||||
private void IconChanged(AvaloniaPropertyChangedEventArgs e)
|
||||
{
|
||||
var (oldValue, newValue) = e.GetOldAndNewValue<object?>();
|
||||
var (oldValue, newValue) = e.GetOldAndNewValue<PathIcon?>();
|
||||
|
||||
if (oldValue is ILogical oldLogical)
|
||||
{
|
||||
@ -988,7 +1055,7 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenInlineItem()
|
||||
internal void OpenInlineItem()
|
||||
{
|
||||
if (_childItemsLayoutTransform is not null)
|
||||
{
|
||||
@ -1011,7 +1078,7 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseInlineItem()
|
||||
internal void CloseInlineItem()
|
||||
{
|
||||
if (_childItemsLayoutTransform is not null)
|
||||
{
|
||||
@ -1030,6 +1097,7 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
_animating = false;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1116,6 +1184,7 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
if (element is NavMenuItem navMenuItem)
|
||||
{
|
||||
BindUtils.RelayBind(this, ModeProperty, navMenuItem, ModeProperty);
|
||||
BindUtils.RelayBind(this, IsDarkStyleProperty, navMenuItem, IsDarkStyleProperty);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1130,6 +1199,20 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void RegenerateContainers()
|
||||
{
|
||||
foreach (var item in Items)
|
||||
{
|
||||
if (item is NavMenuItem childNavMenuItem)
|
||||
{
|
||||
childNavMenuItem.RegenerateContainers();
|
||||
}
|
||||
}
|
||||
|
||||
ItemsPanel = new FuncTemplate<Panel?>(() => new StackPanel());
|
||||
RefreshContainers();
|
||||
}
|
||||
|
||||
private static int CalculateDistanceFromLogicalParent<T>(ILogical? logical, int @default = -1) where T : class
|
||||
{
|
||||
@ -1143,4 +1226,5 @@ public class NavMenuItem : HeaderedSelectingItemsControl,
|
||||
|
||||
return logical != null ? result : @default;
|
||||
}
|
||||
|
||||
}
|
@ -13,6 +13,7 @@ namespace AtomUI.Controls;
|
||||
internal class NavMenuItemTheme : BaseNavMenuItemTheme
|
||||
{
|
||||
public const string ItemsPresenterPart = "PART_ItemsPresenter";
|
||||
public const string PopupFramePart = "PART_PopupFrame";
|
||||
|
||||
public NavMenuItemTheme()
|
||||
: base(typeof(NavMenuItem))
|
||||
@ -37,12 +38,16 @@ internal class NavMenuItemTheme : BaseNavMenuItemTheme
|
||||
Name = ThemeConstants.PopupPart,
|
||||
WindowManagerAddShadowHint = false,
|
||||
IsLightDismissEnabled = false,
|
||||
Placement = PlacementMode.RightEdgeAlignedTop
|
||||
Placement = PlacementMode.RightEdgeAlignedTop,
|
||||
};
|
||||
|
||||
var border = new Border();
|
||||
TokenResourceBinder.CreateTokenBinding(border, Border.BackgroundProperty,
|
||||
GlobalTokenResourceKey.ColorBgContainer);
|
||||
var border = new Border()
|
||||
{
|
||||
Name = PopupFramePart
|
||||
};
|
||||
|
||||
TokenResourceBinder.CreateTokenBinding(popup, Popup.MarginToAnchorProperty,
|
||||
NavMenuTokenResourceKey.TopLevelItemPopupMarginToAnchor);
|
||||
TokenResourceBinder.CreateTokenBinding(border, Border.CornerRadiusProperty,
|
||||
NavMenuTokenResourceKey.MenuPopupBorderRadius);
|
||||
TokenResourceBinder.CreateTokenBinding(border, Layoutable.MinWidthProperty,
|
||||
@ -70,7 +75,7 @@ internal class NavMenuItemTheme : BaseNavMenuItemTheme
|
||||
NavMenuTokenResourceKey.TopLevelItemPopupMarginToAnchor);
|
||||
TokenResourceBinder.CreateTokenBinding(popup, Popup.MaskShadowsProperty,
|
||||
NavMenuTokenResourceKey.MenuPopupBoxShadows);
|
||||
CreateTemplateParentBinding(popup, Avalonia.Controls.Primitives.Popup.IsOpenProperty,
|
||||
CreateTemplateParentBinding(popup, Popup.IsOpenProperty,
|
||||
NavMenuItem.IsSubMenuOpenProperty, BindingMode.TwoWay);
|
||||
|
||||
return popup;
|
||||
@ -82,5 +87,19 @@ internal class NavMenuItemTheme : BaseNavMenuItemTheme
|
||||
var itemsPanelStyle = new Style(selector => selector.Nesting().Template().Name(ItemsPresenterPart).Child().OfType<StackPanel>());
|
||||
itemsPanelStyle.Add(StackPanel.SpacingProperty, NavMenuTokenResourceKey.VerticalItemsPanelSpacing);
|
||||
Add(itemsPanelStyle);
|
||||
|
||||
{
|
||||
var popupFrameStyle = new Style(selector => selector.Nesting().Template().Name(PopupFramePart));
|
||||
popupFrameStyle.Add(Border.BackgroundProperty, GlobalTokenResourceKey.ColorBgContainer);
|
||||
Add(popupFrameStyle);
|
||||
}
|
||||
|
||||
var darkCommonStyle = new Style(selector => selector.Nesting().PropertyEquals(NavMenuItem.IsDarkStyleProperty, true));
|
||||
{
|
||||
var popupFrameStyle = new Style(selector => selector.Nesting().Template().Name(PopupFramePart));
|
||||
popupFrameStyle.Add(Border.BackgroundProperty, NavMenuTokenResourceKey.DarkItemBg);
|
||||
darkCommonStyle.Add(popupFrameStyle);
|
||||
}
|
||||
Add(darkCommonStyle);
|
||||
}
|
||||
}
|
@ -72,7 +72,6 @@ internal class NavMenuTheme : BaseControlTheme
|
||||
var commonStyle = new Style(selector => selector.Nesting());
|
||||
|
||||
commonStyle.Add(TemplatedControl.BorderBrushProperty, GlobalTokenResourceKey.ColorBorderSecondary);
|
||||
commonStyle.Add(TemplatedControl.CornerRadiusProperty, GlobalTokenResourceKey.BorderRadius);
|
||||
|
||||
var horizontalStyle = new Style(selector => selector.Nesting().Class(NavMenu.HorizontalModePC));
|
||||
horizontalStyle.Add(NavMenu.BackgroundProperty, GlobalTokenResourceKey.ColorBgContainer);
|
||||
@ -92,6 +91,7 @@ internal class NavMenuTheme : BaseControlTheme
|
||||
|
||||
var verticalOrInlineStyle = new Style(selector => Selectors.Or(selector.Nesting().Class(NavMenu.VerticalModePC),
|
||||
selector.Nesting().Class(NavMenu.InlineModePC)));
|
||||
verticalOrInlineStyle.Add(NavMenu.PaddingProperty, NavMenuTokenResourceKey.VerticalMenuContentPadding);
|
||||
verticalOrInlineStyle.Add(NavMenu.HorizontalAlignmentProperty, HorizontalAlignment.Left);
|
||||
verticalOrInlineStyle.Add(NavMenu.VerticalAlignmentProperty, VerticalAlignment.Stretch);
|
||||
verticalOrInlineStyle.Add(NavMenu.BackgroundProperty, GlobalTokenResourceKey.ColorBgContainer);
|
||||
|
@ -190,6 +190,11 @@ internal class NavMenuToken : AbstractControlDesignToken
|
||||
/// </summary>
|
||||
public double VerticalItemsPanelSpacing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 垂直面板的内容内间距
|
||||
/// </summary>
|
||||
public Thickness VerticalMenuContentPadding { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜单项内部元素边距
|
||||
/// </summary>
|
||||
@ -444,7 +449,7 @@ internal class NavMenuToken : AbstractControlDesignToken
|
||||
MenuPopupMinWidth = 160d;
|
||||
MenuPopupMaxWidth = 800d;
|
||||
MenuPopupMaxHeight = ItemHeight * 30;
|
||||
TopLevelItemPopupMarginToAnchor = _globalToken.MarginXXS;
|
||||
TopLevelItemPopupMarginToAnchor = _globalToken.MarginXS;
|
||||
|
||||
MenuPopupBg = _globalToken.ColorBgElevated;
|
||||
MenuPopupBorderRadius = _globalToken.BorderRadiusLG;
|
||||
@ -452,6 +457,7 @@ internal class NavMenuToken : AbstractControlDesignToken
|
||||
MenuPopupBoxShadows = _globalToken.BoxShadowsSecondary;
|
||||
VerticalItemsPanelSpacing = _globalToken.MarginXXS;
|
||||
|
||||
InlineItemIndentUnit = ItemHeight / 2;
|
||||
InlineItemIndentUnit = ItemHeight / 2;
|
||||
VerticalMenuContentPadding = new Thickness(_globalToken.PaddingXXS);
|
||||
}
|
||||
}
|
@ -471,16 +471,16 @@ public sealed class PathIcon : Control, ICustomHitTest
|
||||
base.OnAttachedToLogicalTree(e);
|
||||
SetupTransitions();
|
||||
SetupRotateAnimation();
|
||||
if (_sourceGeometriesData.Count == 0)
|
||||
{
|
||||
BuildSourceRenderData();
|
||||
SetupFilledBrush();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToVisualTree(e);
|
||||
if (_sourceGeometriesData.Count == 0)
|
||||
{
|
||||
BuildSourceRenderData();
|
||||
SetupFilledBrush();
|
||||
}
|
||||
if (_animation is not null && _animationCancellationTokenSource is null)
|
||||
{
|
||||
_animationCancellationTokenSource = new CancellationTokenSource();
|
||||
@ -516,28 +516,25 @@ public sealed class PathIcon : Control, ICustomHitTest
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
if (_sourceGeometriesData.Count != 0)
|
||||
_transforms.Clear();
|
||||
// This should probably use GetRenderBounds(strokeThickness) but then the calculations
|
||||
// will multiply the stroke thickness as well, which isn't correct.
|
||||
for (var i = 0; i < _sourceGeometriesData.Count; i++)
|
||||
{
|
||||
// This should probably use GetRenderBounds(strokeThickness) but then the calculations
|
||||
// will multiply the stroke thickness as well, which isn't correct.
|
||||
for (var i = 0; i < _sourceGeometriesData.Count; i++)
|
||||
{
|
||||
var sourceGeometry = _sourceGeometriesData[i];
|
||||
var (_, transform) = CalculateSizeAndTransform(finalSize, sourceGeometry.Bounds);
|
||||
_transforms.Insert(i, transform);
|
||||
}
|
||||
|
||||
return finalSize;
|
||||
var sourceGeometry = _sourceGeometriesData[i];
|
||||
var (_, transform) = CalculateSizeAndTransform(finalSize, sourceGeometry.Bounds);
|
||||
_transforms.Insert(i, transform);
|
||||
}
|
||||
|
||||
return default;
|
||||
return finalSize;
|
||||
}
|
||||
|
||||
public override void Render(DrawingContext context)
|
||||
{
|
||||
if (_sourceGeometriesData.Count > 0 &&
|
||||
DesiredSize.Width > 0 &&
|
||||
DesiredSize.Width > 0)
|
||||
if (IsVisible &&
|
||||
_sourceGeometriesData.Count > 0 &&
|
||||
Bounds.Width > 0 &&
|
||||
Bounds.Width > 0)
|
||||
{
|
||||
for (var i = 0; i < _sourceGeometriesData.Count; i++)
|
||||
{
|
||||
@ -577,7 +574,7 @@ public sealed class PathIcon : Control, ICustomHitTest
|
||||
{
|
||||
fillBrush = FilledBrush;
|
||||
}
|
||||
|
||||
|
||||
using var state = context.PushTransform(_transforms[i]);
|
||||
context.DrawGeometry(fillBrush, null, renderedGeometry);
|
||||
}
|
||||
|
@ -70,8 +70,8 @@ public class Popup : AvaloniaPopup
|
||||
private IDisposable? _selfLightDismissDisposable;
|
||||
private bool _initialized;
|
||||
private ManagedPopupPositionerInfo? _managedPopupPositioner;
|
||||
protected bool _animating;
|
||||
private bool _isNeedFlip = true;
|
||||
protected bool _animating;
|
||||
|
||||
// 当鼠标移走了,但是打开动画还没完成,我们需要记录下来这个信号
|
||||
internal bool RequestCloseWhereAnimationCompleted { get; set; }
|
||||
|
@ -309,7 +309,7 @@ public class ToggleSwitch : ToggleButton,
|
||||
_switchKnob.KnobSize = new Size(handleSize, handleSize);
|
||||
}
|
||||
|
||||
CalculateElementsOffset(DesiredSize);
|
||||
CalculateElementsOffset(Bounds.Size);
|
||||
}
|
||||
|
||||
protected override void OnPointerPressed(PointerPressedEventArgs e)
|
||||
@ -524,7 +524,7 @@ public class ToggleSwitch : ToggleButton,
|
||||
CollectStyleState();
|
||||
if (e.Property == IsCheckedProperty)
|
||||
{
|
||||
CalculateElementsOffset(DesiredSize);
|
||||
CalculateElementsOffset(Bounds.Size);
|
||||
WaveSpiritAdorner.ShowWaveAdorner(this, WaveType.PillWave);
|
||||
}
|
||||
}
|
||||
@ -546,12 +546,12 @@ public class ToggleSwitch : ToggleButton,
|
||||
|
||||
private Rect GrooveRect()
|
||||
{
|
||||
return new Rect(new Point(0, 0), DesiredSize);
|
||||
return new Rect(new Point(0, 0), Bounds.Size);
|
||||
}
|
||||
|
||||
private Rect HandleRect()
|
||||
{
|
||||
return HandleRect(IsChecked.HasValue && IsChecked.Value, DesiredSize);
|
||||
return HandleRect(IsChecked.HasValue && IsChecked.Value, Bounds.Size);
|
||||
}
|
||||
|
||||
private Rect HandleRect(bool isChecked, Size controlSize)
|
||||
|
Loading…
Reference in New Issue
Block a user