Refactor PopupConfirm

use axaml theme
This commit is contained in:
CHINBOY
2025-06-10 11:01:01 +08:00
parent e4993fa3eb
commit 39d3248f5a
10 changed files with 125 additions and 249 deletions
@@ -36,6 +36,7 @@
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="Alert\Themes\AlertTheme.axaml" />
<AdditionalFiles Include="Pagination\Themes\Pagination.axaml" />
<AdditionalFiles Include="Pagination\Themes\PaginationNavItemTheme.axaml" />
<AdditionalFiles Include="Pagination\Themes\PaginationNavTheme.axaml" />
@@ -43,6 +44,7 @@
<AdditionalFiles Include="Pagination\Themes\PaginationTheme.axaml" />
<AdditionalFiles Include="Pagination\Themes\QuickJumperBarTheme.axaml" />
<AdditionalFiles Include="Pagination\Themes\SimplePaginationTheme.axaml" />
<AdditionalFiles Include="Tag\Themes\TagTheme.axaml" />
</ItemGroup>
</Project>
@@ -4,9 +4,10 @@
x:Class="AtomUI.Controls.AtomUIOSSControlThemesProvider"
Id="AtomUI.Controls">
<atom:ControlThemesProvider.ControlThemes>
<ResourceInclude Source="Alert/AlertTheme.axaml" />
<ResourceInclude Source="Tag/TagTheme.axaml" />
<ResourceInclude Source="Alert/Themes/AlertTheme.axaml" />
<ResourceInclude Source="Tag/Themes/TagTheme.axaml" />
<ResourceInclude Source="Pagination/Themes/PaginationThemes.axaml" />
<ResourceInclude Source="ScrollBar/Themes/ScrollBarThemes.axaml" />
<ResourceInclude Source="PopupConfirm/Themes/PopupConfirmContainerTheme.axaml" />
</atom:ControlThemesProvider.ControlThemes>
</atom:ControlThemesProvider>
@@ -79,7 +79,6 @@ namespace AtomUI.Theme
themes.Add(new AtomUI.Controls.OptionButtonGroupTheme());
themes.Add(new AtomUI.Controls.OptionButtonTheme());
themes.Add(new AtomUI.Controls.PickerClearUpButtonTheme());
themes.Add(new AtomUI.Controls.PopupConfirmContainerTheme());
themes.Add(new AtomUI.Controls.PrimaryButtonTheme());
themes.Add(new AtomUI.Controls.PrimaryDropdownButtonTheme());
themes.Add(new AtomUI.Controls.ProgressBarTheme());
@@ -1,7 +1,5 @@
using System.Diagnostics;
using AtomUI.IconPkg;
using AtomUI.IconPkg;
using AtomUI.IconPkg.AntDesign;
using AtomUI.Reflection;
using AtomUI.Theme;
using AtomUI.Theme.Utils;
using Avalonia;
@@ -118,17 +116,21 @@ internal class PopupConfirmContainer : TemplatedControl,
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
_okButton = e.NameScope.Find<Button>(PopupConfirmContainerTheme.OkButtonPart);
_cancelButton = e.NameScope.Find<Button>(PopupConfirmContainerTheme.CancelButtonPart);
SetupDefaultIcon();
_okButton = e.NameScope.Find<Button>(PopupConfirmContainerThemeConstants.OkButtonPart);
_cancelButton = e.NameScope.Find<Button>(PopupConfirmContainerThemeConstants.CancelButtonPart);
if (_okButton is not null)
{
_okButton.Click += HandleButtonClicked;
_okButton.Click += HandleButtonClicked;
_okButton.Width = double.NaN;
_okButton.Height = double.NaN;
}
if (_cancelButton is not null)
{
_cancelButton.Click += HandleButtonClicked;
_cancelButton.Click += HandleButtonClicked;
_cancelButton.Width = double.NaN;
_cancelButton.Height = double.NaN;
}
}
@@ -162,14 +164,6 @@ internal class PopupConfirmContainer : TemplatedControl,
{
if (change.Property == IconProperty)
{
if (change.OldValue is Icon oldIcon)
{
oldIcon.SetTemplatedParent(null);
}
if (change.NewValue is Icon newIcon)
{
newIcon.SetTemplatedParent(this);
}
SetupDefaultIcon();
}
}
@@ -182,13 +176,5 @@ internal class PopupConfirmContainer : TemplatedControl,
ClearValue(IconProperty);
SetValue(IconProperty, AntDesignIconPackage.ExclamationCircleFilled(), BindingPriority.Template);
}
Debug.Assert(Icon != null);
Icon.SetTemplatedParent(this);
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
SetupDefaultIcon();
}
}
@@ -1,214 +0,0 @@
using AtomUI.IconPkg;
using AtomUI.Reflection;
using AtomUI.Theme;
using AtomUI.Theme.Styling;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Data.Converters;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.Styling;
namespace AtomUI.Controls;
[ControlThemeProvider]
internal class PopupConfirmContainerTheme : BaseControlTheme
{
public const string MainLayoutPart = "PART_MainLayout";
public const string ButtonLayoutPart = "PART_ButtonLayout";
public const string OkButtonPart = "PART_OkButton";
public const string CancelButtonPart = "PART_CancelButton";
public const string TitlePart = "PART_Title";
public const string ContentPart = "PART_Content";
public const string IconContentPart = "PART_IconContent";
public PopupConfirmContainerTheme()
: base(typeof(PopupConfirmContainer))
{
}
protected override IControlTemplate BuildControlTemplate()
{
return new FuncControlTemplate<PopupConfirmContainer>((popupConfirmContainer, scope) =>
{
var mainLayout = new DockPanel
{
Name = MainLayoutPart,
LastChildFill = true
};
var buttons = BuildButtons(popupConfirmContainer, scope);
mainLayout.Children.Add(buttons);
var content = BuildContent(popupConfirmContainer, scope);
mainLayout.Children.Add(content);
return mainLayout;
});
}
private DockPanel BuildContent(PopupConfirmContainer popupConfirmContainer, INameScope scope)
{
var wrapperLayout = new DockPanel
{
LastChildFill = true
};
var contentLayout = new DockPanel
{
LastChildFill = true
};
var iconContentPresenter = new ContentPresenter
{
Name = IconContentPart
};
iconContentPresenter.SetTemplatedParent(popupConfirmContainer);
CreateTemplateParentBinding(iconContentPresenter, ContentPresenter.ContentProperty,
PopupConfirmContainer.IconProperty);
CreateTemplateParentBinding(iconContentPresenter, Visual.IsVisibleProperty,
PopupConfirmContainer.IconProperty,
BindingMode.Default,
ObjectConverters.IsNotNull);
DockPanel.SetDock(iconContentPresenter, Dock.Left);
wrapperLayout.Children.Add(iconContentPresenter);
wrapperLayout.Children.Add(contentLayout);
var titleTextBlock = new TextBlock
{
Name = TitlePart,
VerticalAlignment = VerticalAlignment.Center,
};
CreateTemplateParentBinding(titleTextBlock, TextBlock.TextProperty, PopupConfirmContainer.TitleProperty);
DockPanel.SetDock(titleTextBlock, Dock.Top);
contentLayout.Children.Add(titleTextBlock);
var contentPresenter = new ContentPresenter
{
Name = ContentPart
};
CreateTemplateParentBinding(contentPresenter, ContentPresenter.ContentProperty,
PopupConfirmContainer.ConfirmContentProperty);
CreateTemplateParentBinding(contentPresenter, ContentPresenter.ContentTemplateProperty,
PopupConfirmContainer.ConfirmContentTemplateProperty);
contentLayout.Children.Add(contentPresenter);
return wrapperLayout;
}
private Panel BuildButtons(PopupConfirmContainer popupConfirmContainer, INameScope scope)
{
var buttonLayout = new StackPanel
{
Name = ButtonLayoutPart,
Orientation = Orientation.Horizontal,
HorizontalAlignment = HorizontalAlignment.Right,
VerticalAlignment = VerticalAlignment.Bottom,
};
DockPanel.SetDock(buttonLayout, Dock.Bottom);
var cancelButton = new Button
{
Name = CancelButtonPart,
SizeType = SizeType.Small,
Margin = new Thickness(0),
Width = double.NaN,
Height = double.NaN,
};
cancelButton.RegisterInNameScope(scope);
CreateTemplateParentBinding(cancelButton, Button.TextProperty, PopupConfirmContainer.CancelTextProperty);
CreateTemplateParentBinding(cancelButton, Visual.IsVisibleProperty,
PopupConfirmContainer.IsShowCancelButtonProperty);
buttonLayout.Children.Add(cancelButton);
var okButton = new Button
{
Name = OkButtonPart,
SizeType = SizeType.Small,
Margin = new Thickness(0),
Width = double.NaN,
Height = double.NaN,
};
okButton.RegisterInNameScope(scope);
CreateTemplateParentBinding(okButton, Button.TextProperty, PopupConfirmContainer.OkTextProperty);
CreateTemplateParentBinding(okButton, Button.ButtonTypeProperty, PopupConfirmContainer.OkButtonTypeProperty);
buttonLayout.Children.Add(okButton);
return buttonLayout;
}
protected override void BuildStyles()
{
var commonStyle = new Style(selector => selector.Nesting());
var mainLayoutStyle = new Style(selector => selector.Nesting().Template().Name(MainLayoutPart));
mainLayoutStyle.Add(Layoutable.MinWidthProperty, PopupConfirmTokenKey.PopupMinWidth);
mainLayoutStyle.Add(Layoutable.MinHeightProperty, PopupConfirmTokenKey.PopupMinHeight);
commonStyle.Add(mainLayoutStyle);
var iconContentPresenter = new Style(selector => selector.Nesting().Template().Name(IconContentPart));
iconContentPresenter.Add(Layoutable.MarginProperty, PopupConfirmTokenKey.IconMargin);
commonStyle.Add(iconContentPresenter);
var titleStyle = new Style(selector => selector.Nesting().Template().Name(TitlePart));
titleStyle.Add(Layoutable.MarginProperty, PopupConfirmTokenKey.TitleMargin);
titleStyle.Add(TextBlock.ForegroundProperty, SharedTokenKey.ColorTextHeading);
titleStyle.Add(TextBlock.FontWeightProperty, FontWeight.SemiBold);
commonStyle.Add(titleStyle);
var contentStyle = new Style(selector => selector.Nesting().Template().Name(ContentPart));
contentStyle.Add(Layoutable.MarginProperty, PopupConfirmTokenKey.ContentContainerMargin);
commonStyle.Add(contentStyle);
var buttonContainerStyle = new Style(selector => selector.Nesting().Template().Name(ButtonLayoutPart));
buttonContainerStyle.Add(StackPanel.SpacingProperty, PopupConfirmTokenKey.ButtonSpacing);
buttonContainerStyle.Add(StackPanel.MarginProperty, PopupConfirmTokenKey.ButtonContainerMargin);
commonStyle.Add(buttonContainerStyle);
Add(commonStyle);
BuildInfoIconStyle();
}
private void BuildInfoIconStyle()
{
{
var iconStyle = new Style(selector => selector.Nesting().Template().Name(IconContentPart).Descendant().OfType<Icon>());
iconStyle.Add(Layoutable.WidthProperty, SharedTokenKey.IconSizeLG);
iconStyle.Add(Layoutable.HeightProperty, SharedTokenKey.IconSizeLG);
iconStyle.Add(Layoutable.VerticalAlignmentProperty, VerticalAlignment.Top);
Add(iconStyle);
}
var infoStatusStyle = new Style(selector => selector.Nesting().PropertyEquals(PopupConfirmContainer.ConfirmStatusProperty,
PopupConfirmStatus.Info));
{
var iconStyle = new Style(selector => selector.Nesting().Template().Name(IconContentPart).Descendant().OfType<Icon>());
iconStyle.Add(Icon.NormalFilledBrushProperty, SharedTokenKey.ColorPrimary);
infoStatusStyle.Add(iconStyle);
}
Add(infoStatusStyle);
var warningStatusStyle = new Style(selector => selector.Nesting().PropertyEquals(PopupConfirmContainer.ConfirmStatusProperty,
PopupConfirmStatus.Warning));
{
var iconStyle = new Style(selector => selector.Nesting().Template().Name(IconContentPart).Descendant().OfType<Icon>());
iconStyle.Add(Icon.NormalFilledBrushProperty, SharedTokenKey.ColorWarning);
warningStatusStyle.Add(iconStyle);
}
Add(warningStatusStyle);
var errorStatusStyle = new Style(selector => selector.Nesting().PropertyEquals(PopupConfirmContainer.ConfirmStatusProperty,
PopupConfirmStatus.Error));
{
var iconStyle = new Style(selector => selector.Nesting().Template().Name(IconContentPart).Descendant().OfType<Icon>());
iconStyle.Add(Icon.NormalFilledBrushProperty, SharedTokenKey.ColorError);
errorStatusStyle.Add(iconStyle);
}
Add(errorStatusStyle);
}
}
@@ -0,0 +1,12 @@
namespace AtomUI.Controls;
internal class PopupConfirmContainerThemeConstants
{
public const string MainLayoutPart = "PART_MainLayout";
public const string ButtonLayoutPart = "PART_ButtonLayout";
public const string OkButtonPart = "PART_OkButton";
public const string CancelButtonPart = "PART_CancelButton";
public const string TitlePart = "PART_Title";
public const string ContentPart = "PART_Content";
public const string IconPresenterPart = "PART_IconPresenter";
}
@@ -0,0 +1,90 @@
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:atom="https://atomui.net">
<ControlTheme x:Key="{x:Type atom:PopupConfirmContainer}" TargetType="atom:PopupConfirmContainer">
<Setter Property="Template">
<ControlTemplate>
<DockPanel Name="{x:Static atom:PopupConfirmContainerThemeConstants.MainLayoutPart}"
LastChildFill="True">
<StackPanel Name="{x:Static atom:PopupConfirmContainerThemeConstants.ButtonLayoutPart}"
Orientation="Horizontal"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
DockPanel.Dock="Bottom">
<atom:Button Name="{x:Static atom:PopupConfirmContainerThemeConstants.CancelButtonPart}"
SizeType="Small"
Margin="0"
Text="{TemplateBinding CancelText}"
IsVisible="{TemplateBinding IsShowCancelButton}" />
<atom:Button Name="{x:Static atom:PopupConfirmContainerThemeConstants.OkButtonPart}"
SizeType="Small"
Margin="0"
Text="{TemplateBinding OkText}"
ButtonType="{TemplateBinding OkButtonType}" />
</StackPanel>
<DockPanel LastChildFill="True">
<atom:IconPresenter
Name="{x:Static atom:PopupConfirmContainerThemeConstants.IconPresenterPart}"
Icon="{TemplateBinding Icon}"
IsVisible="{TemplateBinding Icon, Converter={x:Static ObjectConverters.IsNotNull}}"
DockPanel.Dock="Left" />
<DockPanel LastChildFill="True">
<atom:TextBlock Name="{x:Static atom:PopupConfirmContainerThemeConstants.TitlePart}"
VerticalAlignment="Center"
Text="{TemplateBinding Title}"
DockPanel.Dock="Top" />
<ContentPresenter Name="{x:Static atom:PopupConfirmContainerThemeConstants.ContentPart}"
Content="{TemplateBinding ConfirmContent}"
ContentTemplate="{TemplateBinding ConfirmContentTemplate}" />
</DockPanel>
</DockPanel>
</DockPanel>
</ControlTemplate>
</Setter>
<Style Selector="^ /template/ DockPanel#PART_MainLayout">
<Setter Property="MinWidth" Value="{DynamicResource {x:Static atom:PopupConfirmTokenKey.PopupMinWidth}}" />
<Setter Property="MinHeight" Value="{DynamicResource {x:Static atom:PopupConfirmTokenKey.PopupMinHeight}}" />
</Style>
<Style Selector="^ /template/ atom|TextBlock#PART_Title">
<Setter Property="Margin" Value="{DynamicResource {x:Static atom:PopupConfirmTokenKey.TitleMargin}}" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorTextHeading}}" />
<Setter Property="FontWeight" Value="SemiBold" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_Content">
<Setter Property="Margin"
Value="{DynamicResource {x:Static atom:PopupConfirmTokenKey.ContentContainerMargin}}" />
</Style>
<Style Selector="^ /template/ StackPanel#PART_ButtonLayout">
<Setter Property="Spacing" Value="{DynamicResource {x:Static atom:PopupConfirmTokenKey.ButtonSpacing}}" />
<Setter Property="Margin"
Value="{DynamicResource {x:Static atom:PopupConfirmTokenKey.ButtonContainerMargin}}" />
</Style>
<Style Selector="^ /template/ atom|IconPresenter#PART_IconPresenter">
<Setter Property="Margin" Value="{DynamicResource {x:Static atom:PopupConfirmTokenKey.IconMargin}}" />
<Setter Property="IconWidth" Value="{DynamicResource {x:Static atom:SharedTokenKey.IconSizeLG}}" />
<Setter Property="IconHeight" Value="{DynamicResource {x:Static atom:SharedTokenKey.IconSizeLG}}" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style Selector="^[ConfirmStatus=Info]">
<Style Selector="^ /template/ atom|IconPresenter#PART_IconPresenter">
<Setter Property="NormalIconBrush" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorPrimary}}" />
</Style>
</Style>
<Style Selector="^[ConfirmStatus=Warning]">
<Style Selector="^ /template/ atom|IconPresenter#PART_IconPresenter">
<Setter Property="NormalIconBrush" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorWarning}}" />
</Style>
</Style>
<Style Selector="^[ConfirmStatus=Error]">
<Style Selector="^ /template/ atom|IconPresenter#PART_IconPresenter">
<Setter Property="NormalIconBrush" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorError}}" />
</Style>
</Style>
</ControlTheme>
</ResourceDictionary>
+8 -8
View File
@@ -30,19 +30,19 @@ public class IconPresenter : Control
public static readonly StyledProperty<IBrush?> NormalIconBrushProperty =
AvaloniaProperty.Register<IconPresenter, IBrush?>(
nameof(NormalIconColor));
nameof(NormalIconBrush));
public static readonly StyledProperty<IBrush?> ActiveIconBrushProperty =
AvaloniaProperty.Register<IconPresenter, IBrush?>(
nameof(ActiveIconColor));
nameof(ActiveIconBrush));
public static readonly StyledProperty<IBrush?> SelectedIconBrushProperty =
AvaloniaProperty.Register<IconPresenter, IBrush?>(
nameof(SelectedIconColor));
nameof(SelectedIconBrush));
public static readonly StyledProperty<IBrush?> DisabledIconBrushProperty =
AvaloniaProperty.Register<IconPresenter, IBrush?>(
nameof(DisabledIconColor));
nameof(DisabledIconBrush));
public static readonly StyledProperty<double> IconWidthProperty
= AvaloniaProperty.Register<IconPresenter, double>(nameof(IconWidth));
@@ -87,25 +87,25 @@ public class IconPresenter : Control
set => SetValue(IconHeightProperty, value);
}
public IBrush? NormalIconColor
public IBrush? NormalIconBrush
{
get => GetValue(NormalIconBrushProperty);
set => SetValue(NormalIconBrushProperty, value);
}
public IBrush? ActiveIconColor
public IBrush? ActiveIconBrush
{
get => GetValue(ActiveIconBrushProperty);
set => SetValue(ActiveIconBrushProperty, value);
}
public IBrush? SelectedIconColor
public IBrush? SelectedIconBrush
{
get => GetValue(SelectedIconBrushProperty);
set => SetValue(SelectedIconBrushProperty, value);
}
public IBrush? DisabledIconColor
public IBrush? DisabledIconBrush
{
get => GetValue(DisabledIconBrushProperty);
set => SetValue(DisabledIconBrushProperty, value);