mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-22 17:35:30 +08:00
Add PaginationNavItem
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
<InternalsVisibleTo Include="AtomUI"/>
|
||||
<InternalsVisibleTo Include="AtomUI.Controls"/>
|
||||
<InternalsVisibleTo Include="AtomUI.Theme"/>
|
||||
<InternalsVisibleTo Include="AtomUI.IconPkg"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -172,7 +172,7 @@ internal class AlertTheme : BaseControlTheme
|
||||
return descriptionLabel;
|
||||
}
|
||||
|
||||
protected override void BuildStyles()
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
BuildAlertTypeStyle();
|
||||
BuildMessageLabelStyle();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<TargetFrameworks>$(AtomUIDevelopTargetFramework);$(AtomUIProductionTargetFramework)</TargetFrameworks>
|
||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||
<CompilerGeneratedFilesOutputPath>GeneratedFiles</CompilerGeneratedFilesOutputPath>
|
||||
<RootNamespace>AtomUI.Controls</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+3
@@ -74,6 +74,9 @@
|
||||
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.NumericUpDownTheme());
|
||||
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.OptionButtonGroupTheme());
|
||||
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.OptionButtonTheme());
|
||||
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.PaginationNavItemTheme());
|
||||
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.PaginationNavTheme());
|
||||
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.PaginationTheme());
|
||||
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.PickerClearUpButtonTheme());
|
||||
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.PopupConfirmContainerTheme());
|
||||
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.PrimaryButtonTheme());
|
||||
|
||||
+1
@@ -32,6 +32,7 @@
|
||||
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.NotificationToken));
|
||||
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.NumericUpDownToken));
|
||||
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.OptionButtonToken));
|
||||
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.PaginationToken));
|
||||
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.PopupConfirmToken));
|
||||
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.ProgressBarToken));
|
||||
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.RadioButtonToken));
|
||||
|
||||
+18
@@ -504,6 +504,24 @@ namespace AtomUI.Theme.Styling
|
||||
public static readonly TokenResourceKey PaddingSM = new TokenResourceKey("OptionButton.PaddingSM");
|
||||
}
|
||||
|
||||
public static class PaginationTokenKey
|
||||
{
|
||||
public static readonly TokenResourceKey InputOutlineOffset = new TokenResourceKey("Pagination.InputOutlineOffset");
|
||||
public static readonly TokenResourceKey ItemActiveBg = new TokenResourceKey("Pagination.ItemActiveBg");
|
||||
public static readonly TokenResourceKey ItemActiveBgDisabled = new TokenResourceKey("Pagination.ItemActiveBgDisabled");
|
||||
public static readonly TokenResourceKey ItemActiveColorDisabled = new TokenResourceKey("Pagination.ItemActiveColorDisabled");
|
||||
public static readonly TokenResourceKey ItemBg = new TokenResourceKey("Pagination.ItemBg");
|
||||
public static readonly TokenResourceKey ItemInputBg = new TokenResourceKey("Pagination.ItemInputBg");
|
||||
public static readonly TokenResourceKey ItemLinkBg = new TokenResourceKey("Pagination.ItemLinkBg");
|
||||
public static readonly TokenResourceKey ItemSize = new TokenResourceKey("Pagination.ItemSize");
|
||||
public static readonly TokenResourceKey ItemSizeSM = new TokenResourceKey("Pagination.ItemSizeSM");
|
||||
public static readonly TokenResourceKey MiniOptionsSizeChangerTop = new TokenResourceKey("Pagination.MiniOptionsSizeChangerTop");
|
||||
public static readonly TokenResourceKey PaginationItemPaddingInline = new TokenResourceKey("Pagination.PaginationItemPaddingInline");
|
||||
public static readonly TokenResourceKey PaginationMiniOptionsMarginInline = new TokenResourceKey("Pagination.PaginationMiniOptionsMarginInline");
|
||||
public static readonly TokenResourceKey PaginationMiniQuickJumperInputWidth = new TokenResourceKey("Pagination.PaginationMiniQuickJumperInputWidth");
|
||||
public static readonly TokenResourceKey PaginationSlashMarginInline = new TokenResourceKey("Pagination.PaginationSlashMarginInline");
|
||||
}
|
||||
|
||||
public static class PopupConfirmTokenKey
|
||||
{
|
||||
public static readonly TokenResourceKey ButtonContainerMargin = new TokenResourceKey("PopupConfirm.ButtonContainerMargin");
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
using System.Diagnostics;
|
||||
using AtomUI.IconPkg.AntDesign;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.LogicalTree;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public enum PaginationAlign
|
||||
{
|
||||
Start,
|
||||
Center,
|
||||
End
|
||||
}
|
||||
|
||||
public class Pagination : TemplatedControl,
|
||||
ISizeTypeAware,
|
||||
IMotionAwareControl,
|
||||
IControlSharedTokenResourcesHost
|
||||
{
|
||||
public const int DefaultPageSize = 10;
|
||||
public const int DefaultCurrentPage = 1;
|
||||
#region 公共属性定义
|
||||
|
||||
public static readonly StyledProperty<PaginationAlign> AlignProperty =
|
||||
AvaloniaProperty.Register<Button, PaginationAlign>(nameof(PaginationAlign));
|
||||
|
||||
public static readonly StyledProperty<SizeType> SizeTypeProperty =
|
||||
SizeTypeAwareControlProperty.SizeTypeProperty.AddOwner<Pagination>();
|
||||
|
||||
public static readonly DirectProperty<Pagination, int> CurrentPageProperty =
|
||||
AvaloniaProperty.RegisterDirect<Pagination, int>(nameof(CurrentPage),
|
||||
o => o.CurrentPage,
|
||||
(o, v) => o.CurrentPage = v,
|
||||
unsetValue: DefaultCurrentPage);
|
||||
|
||||
public static readonly DirectProperty<Pagination, int> PageSizeProperty =
|
||||
AvaloniaProperty.RegisterDirect<Pagination, int>(nameof(PageSize),
|
||||
o => o.PageSize,
|
||||
(o, v) => o.PageSize = v,
|
||||
unsetValue: DefaultPageSize);
|
||||
|
||||
public static readonly DirectProperty<Pagination, long> TotalProperty =
|
||||
AvaloniaProperty.RegisterDirect<Pagination, long>(nameof(Total),
|
||||
o => o.Total,
|
||||
(o, v) => o.Total = v);
|
||||
|
||||
public static readonly DirectProperty<Pagination, bool> HideOnSinglePageProperty =
|
||||
AvaloniaProperty.RegisterDirect<Pagination, bool>(nameof(HideOnSinglePage),
|
||||
o => o.HideOnSinglePage,
|
||||
(o, v) => o.HideOnSinglePage = v);
|
||||
|
||||
public static readonly DirectProperty<Pagination, bool> ShowSizeChangerProperty =
|
||||
AvaloniaProperty.RegisterDirect<Pagination, bool>(nameof(ShowSizeChanger),
|
||||
o => o.ShowSizeChanger,
|
||||
(o, v) => o.ShowSizeChanger = v);
|
||||
|
||||
public static readonly DirectProperty<Pagination, bool> ShowTotalInfoProperty =
|
||||
AvaloniaProperty.RegisterDirect<Pagination, bool>(nameof(ShowTotalInfo),
|
||||
o => o.ShowTotalInfo,
|
||||
(o, v) => o.ShowTotalInfo = v);
|
||||
|
||||
public static readonly StyledProperty<IDataTemplate?> TotalInfoTemplateProperty =
|
||||
AvaloniaProperty.Register<Button, IDataTemplate?>(nameof(TotalInfoTemplate));
|
||||
|
||||
public static readonly StyledProperty<bool> IsMotionEnabledProperty
|
||||
= WaveSpiritAwareControlProperty.IsMotionEnabledProperty.AddOwner<CheckBox>();
|
||||
|
||||
public SizeType SizeType
|
||||
{
|
||||
get => GetValue(SizeTypeProperty);
|
||||
set => SetValue(SizeTypeProperty, value);
|
||||
}
|
||||
|
||||
public PaginationAlign Align
|
||||
{
|
||||
get => GetValue(AlignProperty);
|
||||
set => SetValue(AlignProperty, value);
|
||||
}
|
||||
|
||||
private int _currentPage = DefaultCurrentPage;
|
||||
public int CurrentPage
|
||||
{
|
||||
get => _currentPage;
|
||||
set => SetAndRaise(CurrentPageProperty, ref _currentPage, value);
|
||||
}
|
||||
|
||||
private int _pageSize = DefaultPageSize;
|
||||
public int PageSize
|
||||
{
|
||||
get => _pageSize;
|
||||
set => SetAndRaise(PageSizeProperty, ref _pageSize, value);
|
||||
}
|
||||
|
||||
private long _total;
|
||||
public long Total
|
||||
{
|
||||
get => _total;
|
||||
set => SetAndRaise(TotalProperty, ref _total, value);
|
||||
}
|
||||
|
||||
private bool _hideOnSinglePage;
|
||||
public bool HideOnSinglePage
|
||||
{
|
||||
get => _hideOnSinglePage;
|
||||
set => SetAndRaise(HideOnSinglePageProperty, ref _hideOnSinglePage, value);
|
||||
}
|
||||
|
||||
private bool _showSizeChanger;
|
||||
public bool ShowSizeChanger
|
||||
{
|
||||
get => _hideOnSinglePage;
|
||||
set => SetAndRaise(ShowSizeChangerProperty, ref _showSizeChanger, value);
|
||||
}
|
||||
|
||||
private bool _showTotalInfo;
|
||||
public bool ShowTotalInfo
|
||||
{
|
||||
get => _showTotalInfo;
|
||||
set => SetAndRaise(ShowTotalInfoProperty, ref _showTotalInfo, value);
|
||||
}
|
||||
|
||||
public IDataTemplate? TotalInfoTemplate
|
||||
{
|
||||
get => GetValue(TotalInfoTemplateProperty);
|
||||
set => SetValue(TotalInfoTemplateProperty, value);
|
||||
}
|
||||
|
||||
public bool IsMotionEnabled
|
||||
{
|
||||
get => GetValue(IsMotionEnabledProperty);
|
||||
set => SetValue(IsMotionEnabledProperty, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 内部属性定义
|
||||
Control IMotionAwareControl.PropertyBindTarget => this;
|
||||
Control IControlSharedTokenResourcesHost.HostControl => this;
|
||||
string IControlSharedTokenResourcesHost.TokenId => PaginationToken.ID;
|
||||
#endregion
|
||||
|
||||
private PaginationNav? _paginationNav;
|
||||
private PaginationNavItem? _previousPageItem;
|
||||
private PaginationNavItem? _nextPageItem;
|
||||
private PaginationNavItem? _leftEllipsesItem;
|
||||
private PaginationNavItem? _rightEllipsesItem;
|
||||
|
||||
static Pagination()
|
||||
{
|
||||
AffectsMeasure<Button>(SizeTypeProperty);
|
||||
}
|
||||
|
||||
public Pagination()
|
||||
{
|
||||
this.RegisterResources();
|
||||
this.BindMotionProperties();
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
_paginationNav = e.NameScope.Find<PaginationNav>(PaginationTheme.NavPart);
|
||||
Debug.Assert(_paginationNav is not null);
|
||||
var count = _paginationNav.ItemCount;
|
||||
_paginationNav.ContainerPrepared += (sender, args) =>
|
||||
{
|
||||
if (args.Container is PaginationNavItem navItem)
|
||||
{
|
||||
if (0 == args.Index)
|
||||
{
|
||||
navItem.PaginationItemType = PaginationItemType.Previous;
|
||||
_previousPageItem = navItem;
|
||||
_previousPageItem.Content = AntDesignIconPackage.LeftOutlined();
|
||||
}
|
||||
else if (2 == args.Index)
|
||||
{
|
||||
navItem.PaginationItemType = PaginationItemType.Ellipses;
|
||||
_leftEllipsesItem = navItem;
|
||||
_leftEllipsesItem.Content = AntDesignIconPackage.EllipsisOutlined();
|
||||
}
|
||||
else if (count - 1 == args.Index)
|
||||
{
|
||||
navItem.PaginationItemType = PaginationItemType.Next;
|
||||
_nextPageItem = navItem;
|
||||
_nextPageItem.Content = AntDesignIconPackage.RightOutlined();
|
||||
}
|
||||
else if (count - 3 == args.Index)
|
||||
{
|
||||
navItem.PaginationItemType = PaginationItemType.Ellipses;
|
||||
_rightEllipsesItem = navItem;
|
||||
_rightEllipsesItem.Content = AntDesignIconPackage.EllipsisOutlined();
|
||||
}
|
||||
else
|
||||
{
|
||||
navItem.PaginationItemType = PaginationItemType.PageIndicator;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Data;
|
||||
using AtomUI.Theme;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.LogicalTree;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
internal class PaginationNav : SelectingItemsControl,
|
||||
ISizeTypeAware,
|
||||
ITokenResourceConsumer
|
||||
{
|
||||
#region 公共属性
|
||||
|
||||
public static readonly StyledProperty<SizeType> SizeTypeProperty =
|
||||
SizeTypeAwareControlProperty.SizeTypeProperty.AddOwner<PaginationNav>();
|
||||
|
||||
public SizeType SizeType
|
||||
{
|
||||
get => GetValue(SizeTypeProperty);
|
||||
set => SetValue(SizeTypeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<bool> IsMotionEnabledProperty
|
||||
= MotionAwareControlProperty.IsMotionEnabledProperty.AddOwner<PaginationNav>();
|
||||
|
||||
public bool IsMotionEnabled
|
||||
{
|
||||
get => GetValue(IsMotionEnabledProperty);
|
||||
set => SetValue(IsMotionEnabledProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 内部属性
|
||||
|
||||
CompositeDisposable? ITokenResourceConsumer.TokenBindingsDisposable => _tokenBindingsDisposable;
|
||||
|
||||
#endregion
|
||||
|
||||
private CompositeDisposable? _tokenBindingsDisposable;
|
||||
|
||||
static PaginationNav()
|
||||
{
|
||||
AffectsMeasure<PaginationNav>(SizeTypeProperty);
|
||||
}
|
||||
|
||||
public PaginationNav()
|
||||
{
|
||||
for (var i = 0; i < 11; i++)
|
||||
{
|
||||
Items.Add(new PaginationNavItem());
|
||||
}
|
||||
|
||||
SelectionMode = SelectionMode.Single;
|
||||
}
|
||||
|
||||
protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey)
|
||||
{
|
||||
return new PaginationNavItem();
|
||||
}
|
||||
|
||||
protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey)
|
||||
{
|
||||
return NeedsContainer<PaginationNavItem>(item, out recycleKey);
|
||||
}
|
||||
|
||||
protected override void PrepareContainerForItemOverride(Control container, object? item, int index)
|
||||
{
|
||||
base.PrepareContainerForItemOverride(container, item, index);
|
||||
if (container is PaginationNavItem navItem)
|
||||
{
|
||||
BindUtils.RelayBind(this, SizeTypeProperty, navItem, PaginationNavItem.SizeTypeProperty);
|
||||
BindUtils.RelayBind(this, IsMotionEnabledProperty, navItem, PaginationNavItem.IsMotionEnabledProperty);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
|
||||
{
|
||||
_tokenBindingsDisposable = new CompositeDisposable();
|
||||
base.OnAttachedToLogicalTree(e);
|
||||
}
|
||||
|
||||
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnDetachedFromLogicalTree(e);
|
||||
this.DisposeTokenBindings();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.IconPkg;
|
||||
using AtomUI.Media;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Data;
|
||||
using AtomUI.Theme.Styling;
|
||||
using Avalonia;
|
||||
using Avalonia.Animation;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Mixins;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.LogicalTree;
|
||||
using Avalonia.Rendering;
|
||||
using Avalonia.VisualTree;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
internal enum PaginationItemType
|
||||
{
|
||||
Previous,
|
||||
PageIndicator,
|
||||
Next,
|
||||
Ellipses
|
||||
}
|
||||
|
||||
internal class PaginationNavItem : ContentControl,
|
||||
ISelectable,
|
||||
ICustomHitTest,
|
||||
ITokenResourceConsumer
|
||||
{
|
||||
public static readonly StyledProperty<bool> IsSelectedProperty =
|
||||
SelectingItemsControl.IsSelectedProperty.AddOwner<PaginationNavItem>();
|
||||
|
||||
public static readonly StyledProperty<PaginationItemType> PaginationItemTypeProperty
|
||||
= AvaloniaProperty.Register<PaginationNavItem, PaginationItemType>(nameof(PaginationItemType));
|
||||
|
||||
public bool IsSelected
|
||||
{
|
||||
get => GetValue(IsSelectedProperty);
|
||||
set => SetValue(IsSelectedProperty, value);
|
||||
}
|
||||
|
||||
public PaginationItemType PaginationItemType
|
||||
{
|
||||
get => GetValue(PaginationItemTypeProperty);
|
||||
set => SetValue(PaginationItemTypeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<SizeType> SizeTypeProperty =
|
||||
SizeTypeAwareControlProperty.SizeTypeProperty.AddOwner<PaginationNavItem>();
|
||||
|
||||
public static readonly StyledProperty<bool> IsMotionEnabledProperty
|
||||
= MotionAwareControlProperty.IsMotionEnabledProperty.AddOwner<PaginationNavItem>();
|
||||
|
||||
public SizeType SizeType
|
||||
{
|
||||
get => GetValue(SizeTypeProperty);
|
||||
set => SetValue(SizeTypeProperty, value);
|
||||
}
|
||||
|
||||
public bool IsMotionEnabled
|
||||
{
|
||||
get => GetValue(IsMotionEnabledProperty);
|
||||
set => SetValue(IsMotionEnabledProperty, value);
|
||||
}
|
||||
|
||||
CompositeDisposable? ITokenResourceConsumer.TokenBindingsDisposable => _tokenBindingsDisposable;
|
||||
|
||||
private CompositeDisposable? _tokenBindingsDisposable;
|
||||
|
||||
static PaginationNavItem()
|
||||
{
|
||||
SelectableMixin.Attach<PaginationNavItem>(IsSelectedProperty);
|
||||
PressedMixin.Attach<PaginationNavItem>();
|
||||
FocusableProperty.OverrideDefaultValue<PaginationNavItem>(true);
|
||||
AffectsRender<PaginationNavItem>(BackgroundProperty);
|
||||
}
|
||||
|
||||
|
||||
public PaginationNavItem()
|
||||
{
|
||||
_tokenBindingsDisposable = new CompositeDisposable();
|
||||
}
|
||||
|
||||
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnDetachedFromLogicalTree(e);
|
||||
this.DisposeTokenBindings();
|
||||
}
|
||||
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToVisualTree(e);
|
||||
SetupTransitions();
|
||||
if (Content is Icon icon)
|
||||
{
|
||||
SetupIconFillColors(icon);
|
||||
SetupIconSizeType(icon);
|
||||
SetupIconStatus(icon);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
|
||||
if (this.IsAttachedToVisualTree())
|
||||
{
|
||||
if (change.Property == IsMotionEnabledProperty)
|
||||
{
|
||||
SetupTransitions();
|
||||
}
|
||||
|
||||
if (change.Property == ContentProperty)
|
||||
{
|
||||
if (change.NewValue is Icon newIcon)
|
||||
{
|
||||
SetupIconFillColors(newIcon);
|
||||
SetupIconSizeType(newIcon);
|
||||
SetupIconStatus(newIcon);
|
||||
}
|
||||
}
|
||||
else if (change.Property == IsEnabledProperty)
|
||||
{
|
||||
if (Content is Icon icon)
|
||||
{
|
||||
SetupIconStatus(icon);
|
||||
}
|
||||
}
|
||||
else if (change.Property == SizeTypeProperty)
|
||||
{
|
||||
if (Content is Icon icon)
|
||||
{
|
||||
SetupIconSizeType(icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupIconFillColors(Icon icon)
|
||||
{
|
||||
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(icon, Icon.NormalFilledBrushProperty, SharedTokenKey.ColorText));
|
||||
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(icon, Icon.DisabledFilledBrushProperty, SharedTokenKey.ColorTextDisabled));
|
||||
}
|
||||
|
||||
private void SetupIconStatus(Icon icon)
|
||||
{
|
||||
if (IsEnabled)
|
||||
{
|
||||
icon.IconMode = IconMode.Normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
icon.IconMode = IconMode.Disabled;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupIconSizeType(Icon icon)
|
||||
{
|
||||
if (SizeType == SizeType.Large)
|
||||
{
|
||||
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(icon, WidthProperty, SharedTokenKey.IconSizeLG));
|
||||
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(icon, HeightProperty, SharedTokenKey.IconSizeLG));
|
||||
}
|
||||
else if (SizeType == SizeType.Middle)
|
||||
{
|
||||
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(icon, WidthProperty, SharedTokenKey.IconSize));
|
||||
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(icon, HeightProperty, SharedTokenKey.IconSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(icon, WidthProperty, SharedTokenKey.IconSizeSM));
|
||||
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(icon, HeightProperty, SharedTokenKey.IconSizeSM));
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupTransitions()
|
||||
{
|
||||
if (IsMotionEnabled)
|
||||
{
|
||||
Transitions ??= new Transitions
|
||||
{
|
||||
AnimationUtils.CreateTransition<SolidColorBrushTransition>(BackgroundProperty)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
Transitions = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HitTest(Point point)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.IconPkg;
|
||||
using AtomUI.IconPkg.AntDesign;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Styling;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Data.Converters;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Styling;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
[ControlThemeProvider]
|
||||
internal class PaginationNavItemTheme : BaseControlTheme
|
||||
{
|
||||
public const string RootLayoutPart = "PART_RootLayoutPart";
|
||||
public const string MainFramePart = "PART_MainFrame";
|
||||
public const string ContentPart = "PART_Content";
|
||||
|
||||
public PaginationNavItemTheme()
|
||||
: base(typeof(PaginationNavItem))
|
||||
{
|
||||
}
|
||||
|
||||
protected override IControlTemplate BuildControlTemplate()
|
||||
{
|
||||
return new FuncControlTemplate<PaginationNavItem>((paginationNavItem, scope) =>
|
||||
{
|
||||
var rootLayout = new Panel
|
||||
{
|
||||
Name = RootLayoutPart
|
||||
};
|
||||
var mainFrame = new Border
|
||||
{
|
||||
Name = MainFramePart
|
||||
};
|
||||
rootLayout.Children.Add(mainFrame);
|
||||
CreateTemplateParentBinding(mainFrame, Border.BackgroundProperty, TemplatedControl.BackgroundProperty);
|
||||
CreateTemplateParentBinding(mainFrame, Border.CornerRadiusProperty, TemplatedControl.CornerRadiusProperty);
|
||||
CreateTemplateParentBinding(mainFrame, Decorator.PaddingProperty, TemplatedControl.PaddingProperty);
|
||||
|
||||
var contentPresenter = new ContentPresenter
|
||||
{
|
||||
Name = ContentPart,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
HorizontalContentAlignment = HorizontalAlignment.Center,
|
||||
VerticalContentAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
contentPresenter.RegisterInNameScope(scope);
|
||||
CreateTemplateParentBinding(contentPresenter, ContentPresenter.ContentProperty,
|
||||
ContentControl.ContentProperty,
|
||||
BindingMode.Default,
|
||||
new FuncValueConverter<object?, object?>(content =>
|
||||
{
|
||||
if (content is string text)
|
||||
{
|
||||
return new TextBlock()
|
||||
{
|
||||
Text = text,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
}
|
||||
return content;
|
||||
}));
|
||||
rootLayout.Children.Add(contentPresenter);
|
||||
return rootLayout;
|
||||
});
|
||||
}
|
||||
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
var commonStyle = new Style(selector => selector.Nesting());
|
||||
commonStyle.Add(TemplatedControl.CornerRadiusProperty, SharedTokenKey.BorderRadius);
|
||||
commonStyle.Add(TemplatedControl.FontSizeProperty, SharedTokenKey.FontSize);
|
||||
commonStyle.Add(TemplatedControl.PaddingProperty, PaginationTokenKey.PaginationItemPaddingInline);
|
||||
|
||||
var enabledStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(InputElement.IsEnabledProperty, true));
|
||||
enabledStyle.Add(InputElement.CursorProperty, new SetterValueFactory<Cursor>(() => new Cursor(StandardCursorType.Hand)));
|
||||
BuildPageIndicatorEnabledStyle(enabledStyle);
|
||||
BuildPreviousAndNextItemEnabledStyle(enabledStyle);
|
||||
commonStyle.Add(enabledStyle);
|
||||
Add(commonStyle);
|
||||
BuildSizeTypeStyle();
|
||||
BuildDisabledStyle();
|
||||
}
|
||||
|
||||
private void BuildPageIndicatorEnabledStyle(Style enabledStyle)
|
||||
{
|
||||
var indicatorStyle = new Style(selector =>
|
||||
selector.Nesting().PropertyEquals(PaginationNavItem.PaginationItemTypeProperty,
|
||||
PaginationItemType.PageIndicator));
|
||||
var selectedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Selected));
|
||||
|
||||
indicatorStyle.Add(selectedStyle);
|
||||
var notSelectedStyle =
|
||||
new Style(selector => selector.Nesting().Not(x => x.Nesting().Class(StdPseudoClass.Selected)));
|
||||
notSelectedStyle.Add(TemplatedControl.BackgroundProperty, SharedTokenKey.ColorTransparent);
|
||||
notSelectedStyle.Add(TemplatedControl.ForegroundProperty, SharedTokenKey.ColorText);
|
||||
{
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(TemplatedControl.BackgroundProperty, SharedTokenKey.ColorBgTextHover);
|
||||
notSelectedStyle.Add(hoverStyle);
|
||||
}
|
||||
{
|
||||
var pressedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Pressed));
|
||||
pressedStyle.Add(TemplatedControl.BackgroundProperty, SharedTokenKey.ColorBgTextActive);
|
||||
notSelectedStyle.Add(pressedStyle);
|
||||
}
|
||||
indicatorStyle.Add(notSelectedStyle);
|
||||
enabledStyle.Add(indicatorStyle);
|
||||
}
|
||||
|
||||
private void BuildPreviousAndNextItemEnabledStyle(Style enabledStyle)
|
||||
{
|
||||
var previousAndNextStyle = new Style(selector =>
|
||||
Selectors.Or(selector.Nesting().PropertyEquals(PaginationNavItem.PaginationItemTypeProperty,
|
||||
PaginationItemType.Previous),
|
||||
selector.Nesting().PropertyEquals(PaginationNavItem.PaginationItemTypeProperty,
|
||||
PaginationItemType.Next)));
|
||||
previousAndNextStyle.Add(TemplatedControl.BackgroundProperty, SharedTokenKey.ColorTransparent);
|
||||
previousAndNextStyle.Add(TemplatedControl.ForegroundProperty, SharedTokenKey.ColorText);
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(TemplatedControl.BackgroundProperty, SharedTokenKey.ColorBgTextHover);
|
||||
previousAndNextStyle.Add(hoverStyle);
|
||||
var pressedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Pressed));
|
||||
pressedStyle.Add(TemplatedControl.BackgroundProperty, SharedTokenKey.ColorBgTextActive);
|
||||
previousAndNextStyle.Add(pressedStyle);
|
||||
enabledStyle.Add(previousAndNextStyle);
|
||||
}
|
||||
|
||||
private void BuildSizeTypeStyle()
|
||||
{
|
||||
var largeSizeStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(PaginationNavItem.SizeTypeProperty, SizeType.Large));
|
||||
largeSizeStyle.Add(Layoutable.HeightProperty, PaginationTokenKey.ItemSize);
|
||||
largeSizeStyle.Add(Layoutable.MinWidthProperty, PaginationTokenKey.ItemSize);
|
||||
Add(largeSizeStyle);
|
||||
|
||||
var middleSizeStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(PaginationNavItem.SizeTypeProperty, SizeType.Middle));
|
||||
middleSizeStyle.Add(Layoutable.HeightProperty, PaginationTokenKey.ItemSize);
|
||||
middleSizeStyle.Add(Layoutable.MinWidthProperty, PaginationTokenKey.ItemSize);
|
||||
Add(middleSizeStyle);
|
||||
|
||||
var smallSizeStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(PaginationNavItem.SizeTypeProperty, SizeType.Small));
|
||||
smallSizeStyle.Add(Layoutable.HeightProperty, PaginationTokenKey.ItemSizeSM);
|
||||
smallSizeStyle.Add(Layoutable.MinWidthProperty, PaginationTokenKey.ItemSizeSM);
|
||||
Add(smallSizeStyle);
|
||||
}
|
||||
|
||||
private void BuildDisabledStyle()
|
||||
{
|
||||
var disabledStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled));
|
||||
disabledStyle.Add(TemplatedControl.ForegroundProperty, SharedTokenKey.ColorTextDisabled);
|
||||
Add(disabledStyle);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Data;
|
||||
using AtomUI.Theme.Styling;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Layout;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
[ControlThemeProvider]
|
||||
internal class PaginationNavTheme : BaseControlTheme
|
||||
{
|
||||
public const string FramePart = "PART_Frame";
|
||||
public const string ItemsPresenterPart = "PART_ItemsPresenter";
|
||||
|
||||
public PaginationNavTheme()
|
||||
: base(typeof(PaginationNav))
|
||||
{
|
||||
}
|
||||
|
||||
protected override IControlTemplate BuildControlTemplate()
|
||||
{
|
||||
return new FuncControlTemplate<PaginationNav>((paginationNav, scope) =>
|
||||
{
|
||||
var frame = new Border
|
||||
{
|
||||
Name = FramePart,
|
||||
ClipToBounds = true
|
||||
};
|
||||
var itemsPresenter = new ItemsPresenter
|
||||
{
|
||||
Name = ItemsPresenterPart,
|
||||
ItemsPanel = new FuncTemplate<Panel?>(() =>
|
||||
{
|
||||
var panel = new StackPanel()
|
||||
{
|
||||
Orientation = Orientation.Horizontal
|
||||
};
|
||||
paginationNav.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(panel, StackPanel.SpacingProperty, SharedTokenKey.MarginXS));
|
||||
return panel;
|
||||
})
|
||||
};
|
||||
itemsPresenter.RegisterInNameScope(scope);
|
||||
frame.Child = itemsPresenter;
|
||||
|
||||
CreateTemplateParentBinding(frame, Border.CornerRadiusProperty,
|
||||
TemplatedControl.CornerRadiusProperty);
|
||||
CreateTemplateParentBinding(frame, Decorator.PaddingProperty, TemplatedControl.PaddingProperty);
|
||||
return frame;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Styling;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Layout;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
[ControlThemeProvider]
|
||||
internal class PaginationTheme : BaseControlTheme
|
||||
{
|
||||
public const string RootLayoutPart = "PART_RootLayout";
|
||||
public const string NavPart = "PART_Nav";
|
||||
|
||||
public PaginationTheme()
|
||||
: base(typeof(Pagination))
|
||||
{
|
||||
}
|
||||
|
||||
protected override IControlTemplate BuildControlTemplate()
|
||||
{
|
||||
var controlTemplate = new FuncControlTemplate<Pagination>((pagination, scope) =>
|
||||
{
|
||||
var rootLayout = new StackPanel()
|
||||
{
|
||||
Name = RootLayoutPart,
|
||||
Orientation = Orientation.Horizontal
|
||||
};
|
||||
var nav = new PaginationNav()
|
||||
{
|
||||
Name = NavPart
|
||||
};
|
||||
nav.RegisterInNameScope(scope);
|
||||
CreateTemplateParentBinding(nav, PaginationNav.IsMotionEnabledProperty, Pagination.IsMotionEnabledProperty);
|
||||
CreateTemplateParentBinding(nav, PaginationNav.SizeTypeProperty, Pagination.SizeTypeProperty);
|
||||
rootLayout.Children.Add(nav);
|
||||
return rootLayout;
|
||||
});
|
||||
return controlTemplate;
|
||||
}
|
||||
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using AtomUI.Theme.TokenSystem;
|
||||
using Avalonia;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
[ControlDesignToken]
|
||||
internal class PaginationToken : AbstractControlDesignToken
|
||||
{
|
||||
public const string ID = "Pagination";
|
||||
|
||||
/// <summary>
|
||||
/// 页码选项背景色
|
||||
/// Background color of Pagination item
|
||||
/// </summary>
|
||||
public Color ItemBg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 页码尺寸
|
||||
/// Size of Pagination item
|
||||
/// </summary>
|
||||
public double ItemSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 页码激活态背景色
|
||||
/// Background color of active Pagination item
|
||||
/// </summary>
|
||||
public Color ItemActiveBg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 小号页码尺寸
|
||||
/// Size of small Pagination item
|
||||
/// </summary>
|
||||
public double ItemSizeSM { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 页码链接背景色
|
||||
/// Background color of Pagination item link
|
||||
/// </summary>
|
||||
public Color ItemLinkBg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 页码激活态禁用状态背景色
|
||||
/// Background color of disabled active Pagination item
|
||||
/// </summary>
|
||||
public Color ItemActiveBgDisabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 页码激活态禁用状态文字颜色
|
||||
/// Text color of disabled active Pagination item
|
||||
/// </summary>
|
||||
public Color ItemActiveColorDisabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 输入框背景色
|
||||
/// Background color of input
|
||||
/// </summary>
|
||||
public Color ItemInputBg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 每页展示数量选择器 top
|
||||
/// Top of Pagination size changer
|
||||
/// </summary>
|
||||
public double MiniOptionsSizeChangerTop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 输入框轮廓偏移量
|
||||
/// Outline offset of input
|
||||
/// </summary>
|
||||
public Thickness InputOutlineOffset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 迷你选项横向外边距
|
||||
/// Horizontal margin of mini options
|
||||
/// </summary>
|
||||
public Thickness PaginationMiniOptionsMarginInline { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 迷你快速跳转输入框宽度
|
||||
/// Width of mini quick jumper input
|
||||
/// </summary>
|
||||
public double PaginationMiniQuickJumperInputWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 页码横向内边距
|
||||
/// Horizontal padding of Pagination item
|
||||
/// </summary>
|
||||
public Thickness PaginationItemPaddingInline { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 斜杠横向外边距
|
||||
/// Horizontal margin of slash
|
||||
/// </summary>
|
||||
public Thickness PaginationSlashMarginInline { get; set; }
|
||||
|
||||
public PaginationToken()
|
||||
: base(ID)
|
||||
{
|
||||
}
|
||||
|
||||
internal override void CalculateFromAlias()
|
||||
{
|
||||
base.CalculateFromAlias();
|
||||
ItemBg = SharedToken.ColorBgContainer;
|
||||
ItemSize = SharedToken.ControlHeight;
|
||||
ItemSizeSM = SharedToken.ControlHeightSM;
|
||||
ItemActiveBg = SharedToken.ColorBgContainer;
|
||||
ItemLinkBg = SharedToken.ColorBgContainer;
|
||||
ItemActiveColorDisabled = SharedToken.ColorTextDisabled;
|
||||
ItemActiveBgDisabled = SharedToken.ControlItemBgActiveDisabled;
|
||||
ItemInputBg = SharedToken.ColorBgContainer;
|
||||
MiniOptionsSizeChangerTop = 0;
|
||||
|
||||
InputOutlineOffset = new Thickness(0);
|
||||
PaginationMiniOptionsMarginInline = new Thickness(SharedToken.MarginXXS / 2);
|
||||
PaginationMiniQuickJumperInputWidth = SharedToken.ControlHeightLG * 1.1;
|
||||
PaginationItemPaddingInline = new Thickness(SharedToken.MarginXXS * 1.5);
|
||||
PaginationSlashMarginInline = new Thickness(SharedToken.MarginXXS, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public class SimplePagination
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using AtomUI.Controls.Utils;
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.Data;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Styling;
|
||||
@@ -10,6 +11,7 @@ using Avalonia.Controls.Metadata;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.LogicalTree;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.VisualTree;
|
||||
|
||||
@@ -104,7 +106,7 @@ public class Segmented : SelectingItemsControl,
|
||||
Control IMotionAwareControl.PropertyBindTarget => this;
|
||||
Control IControlSharedTokenResourcesHost.HostControl => this;
|
||||
string IControlSharedTokenResourcesHost.TokenId => SegmentedToken.ID;
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
static Segmented()
|
||||
|
||||
@@ -29,14 +29,14 @@ internal class SegmentedTheme : BaseControlTheme
|
||||
Name = FramePart,
|
||||
ClipToBounds = true
|
||||
};
|
||||
// TODO 需要观察是否会有内存泄漏
|
||||
var itemsPresenter = new ItemsPresenter
|
||||
{
|
||||
Name = ItemsPresenterPart,
|
||||
ItemsPanel = new FuncTemplate<Panel?>(() =>
|
||||
{
|
||||
var panel = new SegmentedStackPanel();
|
||||
BindUtils.RelayBind(segmented, Segmented.IsExpandingProperty, panel, SegmentedStackPanel.IsExpandingProperty);
|
||||
BindUtils.RelayBind(segmented, Segmented.IsExpandingProperty, panel,
|
||||
SegmentedStackPanel.IsExpandingProperty);
|
||||
return panel;
|
||||
})
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Globalization;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Utilities;
|
||||
|
||||
namespace AtomUI.IconPkg;
|
||||
|
||||
@@ -60,44 +60,42 @@ public record struct ColorInfo
|
||||
public static ColorInfo Parse(string expr)
|
||||
{
|
||||
const string exceptionMessage = "Invalid ColorInfo.";
|
||||
using (var tokenizer = new StringTokenizer(expr, CultureInfo.InvariantCulture, exceptionMessage))
|
||||
using var tokenizer = new SpanStringTokenizer(expr, CultureInfo.InvariantCulture);
|
||||
try
|
||||
{
|
||||
try
|
||||
var colorInfo = new ColorInfo();
|
||||
if (tokenizer.TryReadString(out var color1Str))
|
||||
{
|
||||
var colorInfo = new ColorInfo();
|
||||
if (tokenizer.TryReadString(out var color1Str))
|
||||
colorInfo.NormalColor = Color.Parse(color1Str);
|
||||
if (tokenizer.TryReadString(out var color2Str))
|
||||
{
|
||||
colorInfo.NormalColor = Color.Parse(color1Str);
|
||||
if (tokenizer.TryReadString(out var color2Str))
|
||||
colorInfo.ActiveColor = Color.Parse(color2Str);
|
||||
if (tokenizer.TryReadString(out var color3Str))
|
||||
{
|
||||
colorInfo.ActiveColor = Color.Parse(color2Str);
|
||||
if (tokenizer.TryReadString(out var color3Str))
|
||||
colorInfo.SelectedColor = Color.Parse(color3Str);
|
||||
if (tokenizer.TryReadString(out var color4Str))
|
||||
{
|
||||
colorInfo.SelectedColor = Color.Parse(color3Str);
|
||||
if (tokenizer.TryReadString(out var color4Str))
|
||||
{
|
||||
colorInfo.DisabledColor = Color.Parse(color4Str);
|
||||
}
|
||||
colorInfo.DisabledColor = Color.Parse(color4Str);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 至少要一个
|
||||
throw new FormatException(exceptionMessage);
|
||||
}
|
||||
|
||||
return colorInfo;
|
||||
}
|
||||
catch (Exception e)
|
||||
else
|
||||
{
|
||||
if (e is not FormatException)
|
||||
{
|
||||
throw new FormatException(exceptionMessage, e);
|
||||
}
|
||||
|
||||
throw;
|
||||
// 至少要一个
|
||||
throw new FormatException(exceptionMessage);
|
||||
}
|
||||
|
||||
return colorInfo;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is not FormatException)
|
||||
{
|
||||
throw new FormatException(exceptionMessage, e);
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,7 +108,7 @@ public record struct TwoToneColorInfo
|
||||
public static TwoToneColorInfo Parse(string expr)
|
||||
{
|
||||
const string exceptionMessage = "Invalid TwoToneColorInfo.";
|
||||
using (var tokenizer = new StringTokenizer(expr, CultureInfo.InvariantCulture, exceptionMessage))
|
||||
using (var tokenizer = new SpanStringTokenizer(expr, CultureInfo.InvariantCulture))
|
||||
{
|
||||
if (tokenizer.TryReadString(out var color1Str))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user