重构 LineEdit

This commit is contained in:
polarboy 2024-08-16 18:44:14 +08:00
parent 74aef57895
commit e794c7b3ce
14 changed files with 922 additions and 1272 deletions

View File

@ -18,9 +18,12 @@
Title="Three sizes of Input"
Description="There are three sizes of an Input box: large (40px), default (32px) and small (24px).">
<StackPanel Orientation="Vertical" Spacing="10" Margin="0, 0, 20, 0">
<atom:LineEdit Watermark="Large" SizeType="Large" InnerLeftContent="{atom:IconProvider Kind=UserOutlined}"/>
<atom:LineEdit Watermark="Middle" SizeType="Middle" InnerLeftContent="{atom:IconProvider Kind=UserOutlined}"/>
<atom:LineEdit Watermark="Small" SizeType="Small" InnerLeftContent="{atom:IconProvider Kind=UserOutlined}"/>
<atom:LineEdit Watermark="Large" SizeType="Large"
InnerLeftContent="{atom:IconProvider Kind=UserOutlined}" />
<atom:LineEdit Watermark="Middle" SizeType="Middle"
InnerLeftContent="{atom:IconProvider Kind=UserOutlined}" />
<atom:LineEdit Watermark="Small" SizeType="Small"
InnerLeftContent="{atom:IconProvider Kind=UserOutlined}" />
</StackPanel>
</showcase:ShowCaseItem>
@ -104,33 +107,33 @@
</StackPanel>
</showcase:ShowCaseItem>
<showcase:ShowCaseItem
Title="Search box"
Description="Example of creating a search box by grouping a standard input with a search button.">
<StackPanel Orientation="Vertical" Spacing="10" Margin="0, 0, 20, 0">
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left"/>
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonText="Search"/>
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonStyle="Primary" SearchButtonText="Search"/>
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonStyle="Primary" SearchButtonText="Search"/>
<atom:SearchEdit Watermark="input search text"
Width="400"
HorizontalAlignment="Left"
SearchButtonStyle="Primary"
SearchButtonText="Search"
IsEnableClearButton="True"
SizeType="Large"/>
<atom:SearchEdit Watermark="input search text"
Width="400"
HorizontalAlignment="Left"
SearchButtonStyle="Primary"
SearchButtonText="搜索一下"
InnerRightContent="{atom:IconProvider Kind=AudioOutlined, NormalFilledColor=#1677ff, Width=16, Height=16}"
IsEnableClearButton="True"
SizeType="Large"/>
</StackPanel>
</showcase:ShowCaseItem>
<!-- <showcase:ShowCaseItem -->
<!-- Title="Search box" -->
<!-- Description="Example of creating a search box by grouping a standard input with a search button."> -->
<!-- <StackPanel Orientation="Vertical" Spacing="10" Margin="0, 0, 20, 0"> -->
<!-- <atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left"/> -->
<!-- <atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonText="Search"/> -->
<!-- -->
<!-- <atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonStyle="Primary" SearchButtonText="Search"/> -->
<!-- <atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonStyle="Primary" SearchButtonText="Search"/> -->
<!-- -->
<!-- <atom:SearchEdit Watermark="input search text" -->
<!-- Width="400" -->
<!-- HorizontalAlignment="Left" -->
<!-- SearchButtonStyle="Primary" -->
<!-- SearchButtonText="Search" -->
<!-- IsEnableClearButton="True" -->
<!-- SizeType="Large"/> -->
<!-- <atom:SearchEdit Watermark="input search text" -->
<!-- Width="400" -->
<!-- HorizontalAlignment="Left" -->
<!-- SearchButtonStyle="Primary" -->
<!-- SearchButtonText="搜索一下" -->
<!-- InnerRightContent="{atom:IconProvider Kind=AudioOutlined, NormalFilledColor=#1677ff, Width=16, Height=16}" -->
<!-- IsEnableClearButton="True" -->
<!-- SizeType="Large"/> -->
<!-- </StackPanel> -->
<!-- </showcase:ShowCaseItem> -->
</showcase:ShowCasePanel>
</UserControl>

View File

@ -1,4 +1,5 @@
using AtomUI.Theme.Data;
using AtomUI.Controls.Utils;
using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using AtomUI.Utils;
using Avalonia;
@ -8,7 +9,7 @@ using Avalonia.Controls.Primitives;
using Avalonia.Controls;
using Avalonia.Data;
namespace AtomUI.Controls.AddOnDecoratedBox;
namespace AtomUI.Controls;
public enum AddOnDecoratedVariant
{
@ -153,7 +154,6 @@ public class AddOnDecoratedBox : ContentControl
protected Control? _leftAddOnPresenter;
protected Control? _rightAddOnPresenter;
protected Border? _innerBoxDecorator;
static AddOnDecoratedBox()
{
@ -161,6 +161,35 @@ public class AddOnDecoratedBox : ContentControl
AffectsMeasure<AddOnDecoratedBox>(LeftAddOnProperty, RightAddOnProperty);
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (VisualRoot is not null) {
if (change.Property == LeftAddOnProperty || change.Property == RightAddOnProperty) {
SetupInnerBoxCornerRadius();
}
}
if (change.Property == CornerRadiusProperty || change.Property == BorderThicknessProperty) {
SetupAddOnBorderInfo();
}
if (change.Property == StatusProperty) {
UpdatePseudoClasses();
}
if (change.Property == LeftAddOnProperty || change.Property == RightAddOnProperty) {
if (change.OldValue is Control oldControl) {
UIStructureUtils.SetTemplateParent(oldControl, null);
}
if (change.NewValue is Control newControl) {
UIStructureUtils.SetTemplateParent(newControl, this);
}
}
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
@ -169,10 +198,41 @@ public class AddOnDecoratedBox : ContentControl
new RenderScaleAwareThicknessConfigure(this));
_leftAddOnPresenter = e.NameScope.Find<Control>(AddOnDecoratedBoxTheme.LeftAddOnPart);
_rightAddOnPresenter = e.NameScope.Find<Control>(AddOnDecoratedBoxTheme.RightAddOnPart);
_innerBoxDecorator = e.NameScope.Find<Border>(AddOnDecoratedBoxTheme.InnerBoxDecoratorPart);
SetupInnerBoxCornerRadius();
}
private void SetupAddOnBorderInfo()
{
var topLeftRadius = CornerRadius.TopLeft;
var topRightRadius = CornerRadius.TopRight;
var bottomLeftRadius = CornerRadius.BottomLeft;
var bottomRightRadius = CornerRadius.BottomRight;
var topThickness = BorderThickness.Top;
var rightThickness = BorderThickness.Right;
var bottomThickness = BorderThickness.Bottom;
var leftThickness = BorderThickness.Left;
LeftAddOnCornerRadius = new CornerRadius(topLeft: topLeftRadius,
topRight: 0,
bottomLeft:bottomLeftRadius,
bottomRight:0);
RightAddOnCornerRadius = new CornerRadius(topLeft: 0,
topRight: topRightRadius,
bottomLeft:0,
bottomRight:bottomRightRadius);
LeftAddOnBorderThickness = new Thickness(top: topThickness, right:0, bottom:bottomThickness, left: leftThickness);
RightAddOnBorderThickness = new Thickness(top: topThickness, right:rightThickness, bottom:bottomThickness, left: 0);
NotifyAddOnBorderInfoCalculated();
}
protected virtual void NotifyAddOnBorderInfoCalculated()
{
}
private void SetupInnerBoxCornerRadius()
{
var topLeftRadius = CornerRadius.TopLeft;

View File

@ -12,12 +12,12 @@ using Avalonia.Data.Converters;
using Avalonia.Layout;
using Avalonia.Styling;
namespace AtomUI.Controls.AddOnDecoratedBox;
namespace AtomUI.Controls;
[ControlThemeProvider]
internal class AddOnDecoratedBoxTheme : BaseControlTheme
{
public const string MainLayoutPart = "PART_FrameDecorator";
public const string MainLayoutPart = "PART_MainLayout";
public const string LeftAddOnPart = "PART_LeftAddOn";
public const string RightAddOnPart = "PART_RightAddOn";
public const string InnerBoxContentPart = "PART_InnerBoxContent";
@ -26,7 +26,7 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
public const int NormalZIndex = 1000;
public const int ActivatedZIndex = 2000;
public AddOnDecoratedBoxTheme(Type targetType) : base(targetType) { }
public AddOnDecoratedBoxTheme() : base(typeof(AddOnDecoratedBox)) { }
protected override IControlTemplate BuildControlTemplate()
{
@ -175,14 +175,14 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.PaddingProperty, LineEditResourceKey.PaddingLG);
innerBoxDecoratorStyle.Add(Border.PaddingProperty, AddOnDecoratedBoxResourceKey.PaddingLG);
largeStyle.Add(innerBoxDecoratorStyle);
}
{
var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart),
selector.Nesting().Template().Name(RightAddOnPart)));
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.PaddingLG);
addOnStyle.Add(ContentPresenter.PaddingProperty, AddOnDecoratedBoxResourceKey.PaddingLG);
largeStyle.Add(addOnStyle);
}
@ -195,7 +195,7 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
largeStyle.Add(addOnContentIconStyle);
}
largeStyle.Add(AddOnDecoratedBox.FontSizeProperty, LineEditResourceKey.InputFontSizeLG);
largeStyle.Add(AddOnDecoratedBox.FontSizeProperty, AddOnDecoratedBoxResourceKey.FontSizeLG);
largeStyle.Add(AddOnDecoratedBox.MinHeightProperty, GlobalResourceKey.FontHeightLG);
largeStyle.Add(AddOnDecoratedBox.CornerRadiusProperty, GlobalResourceKey.BorderRadiusLG);
commonStyle.Add(largeStyle);
@ -205,14 +205,14 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.PaddingProperty, LineEditResourceKey.Padding);
innerBoxDecoratorStyle.Add(Border.PaddingProperty, AddOnDecoratedBoxResourceKey.Padding);
middleStyle.Add(innerBoxDecoratorStyle);
}
{
var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart),
selector.Nesting().Template().Name(RightAddOnPart)));
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.Padding);
addOnStyle.Add(ContentPresenter.PaddingProperty, AddOnDecoratedBoxResourceKey.Padding);
middleStyle.Add(addOnStyle);
}
@ -225,7 +225,7 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
middleStyle.Add(addOnContentIconStyle);
}
middleStyle.Add(AddOnDecoratedBox.FontSizeProperty, LineEditResourceKey.InputFontSize);
middleStyle.Add(AddOnDecoratedBox.FontSizeProperty, AddOnDecoratedBoxResourceKey.FontSize);
middleStyle.Add(AddOnDecoratedBox.MinHeightProperty, GlobalResourceKey.FontHeight);
middleStyle.Add(AddOnDecoratedBox.CornerRadiusProperty, GlobalResourceKey.BorderRadius);
commonStyle.Add(middleStyle);
@ -235,14 +235,14 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.PaddingProperty, LineEditResourceKey.PaddingSM);
innerBoxDecoratorStyle.Add(Border.PaddingProperty, AddOnDecoratedBoxResourceKey.PaddingSM);
smallStyle.Add(innerBoxDecoratorStyle);
}
{
var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart),
selector.Nesting().Template().Name(RightAddOnPart)));
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.PaddingSM);
addOnStyle.Add(ContentPresenter.PaddingProperty, AddOnDecoratedBoxResourceKey.PaddingSM);
smallStyle.Add(addOnStyle);
}
@ -255,7 +255,7 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
smallStyle.Add(addOnContentIconStyle);
}
smallStyle.Add(AddOnDecoratedBox.FontSizeProperty, LineEditResourceKey.InputFontSizeSM);
smallStyle.Add(AddOnDecoratedBox.FontSizeProperty, AddOnDecoratedBoxResourceKey.FontSizeSM);
smallStyle.Add(AddOnDecoratedBox.MinHeightProperty, GlobalResourceKey.FontHeightSM);
smallStyle.Add(AddOnDecoratedBox.CornerRadiusProperty, GlobalResourceKey.BorderRadiusSM);
commonStyle.Add(smallStyle);
@ -267,57 +267,92 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
{
var outlineStyle =
new Style(selector => selector.Nesting()
.PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, TextBoxVariant.Outline));
.PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, AddOnDecoratedVariant.Outline));
{
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorBorder);
outlineStyle.Add(innerBoxDecoratorStyle);
}
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
hoverStyle.Add(Border.BorderBrushProperty, LineEditResourceKey.HoverBorderColor);
innerBoxDecoratorStyle.Add(hoverStyle);
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, AddOnDecoratedBoxResourceKey.HoverBorderColor);
hoverStyle.Add(innerBoxDecoratorStyle);
}
outlineStyle.Add(hoverStyle);
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
focusStyle.Add(Border.BorderBrushProperty, LineEditResourceKey.ActiveBorderColor);
innerBoxDecoratorStyle.Add(focusStyle);
outlineStyle.Add(innerBoxDecoratorStyle);
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, AddOnDecoratedBoxResourceKey.ActiveBorderColor);
focusStyle.Add(innerBoxDecoratorStyle);
}
outlineStyle.Add(focusStyle);
}
{
var errorStyle = new Style(selector => selector.Nesting().Class(AddOnDecoratedBox.ErrorPC));
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
errorStyle.Add(innerBoxDecoratorStyle);
}
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
hoverStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorErrorBorderHover);
innerBoxDecoratorStyle.Add(hoverStyle);
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorErrorBorderHover);
hoverStyle.Add(innerBoxDecoratorStyle);
}
errorStyle.Add(hoverStyle);
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
innerBoxDecoratorStyle.Add(focusStyle);
errorStyle.Add(innerBoxDecoratorStyle);
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
focusStyle.Add(innerBoxDecoratorStyle);
}
errorStyle.Add(focusStyle);
outlineStyle.Add(errorStyle);
}
{
var warningStyle = new Style(selector => selector.Nesting().Class(AddOnDecoratedBox.WarningPC));
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
warningStyle.Add(innerBoxDecoratorStyle);
}
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
hoverStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarningBorderHover);
innerBoxDecoratorStyle.Add(hoverStyle);
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarningBorderHover);
hoverStyle.Add(innerBoxDecoratorStyle);
}
warningStyle.Add(hoverStyle);
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
innerBoxDecoratorStyle.Add(focusStyle);
warningStyle.Add(innerBoxDecoratorStyle);
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
focusStyle.Add(innerBoxDecoratorStyle);
}
warningStyle.Add(focusStyle);
outlineStyle.Add(warningStyle);
}
@ -328,7 +363,7 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
{
var borderlessStyle =
new Style(selector => selector.Nesting()
.PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, TextBoxVariant.Borderless));
.PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, AddOnDecoratedVariant.Borderless));
{
var errorStyle = new Style(selector => selector.Nesting().Class(AddOnDecoratedBox.ErrorPC));
@ -354,8 +389,9 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
private void BuildFilledStyle()
{
var filledStyle =
new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, TextBoxVariant.Filled));
new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, AddOnDecoratedVariant.Filled));
{
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
@ -363,36 +399,57 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorTransparent);
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorFillTertiary);
filledStyle.Add(innerBoxDecoratorStyle);
}
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
hoverStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorFillSecondary);
innerBoxDecoratorStyle.Add(hoverStyle);
{
var innerBoxDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorFillSecondary);
hoverStyle.Add(innerBoxDecoratorStyle);
}
filledStyle.Add(hoverStyle);
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
focusStyle.Add(Border.BorderBrushProperty, LineEditResourceKey.ActiveBorderColor);
focusStyle.Add(Border.BackgroundProperty, LineEditResourceKey.ActiveBg);
innerBoxDecoratorStyle.Add(focusStyle);
filledStyle.Add(innerBoxDecoratorStyle);
{
var innerBoxDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, AddOnDecoratedBoxResourceKey.ActiveBorderColor);
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, AddOnDecoratedBoxResourceKey.ActiveBg);
focusStyle.Add(innerBoxDecoratorStyle);
}
filledStyle.Add(focusStyle);
}
{
var errorStyle = new Style(selector => selector.Nesting().Class(AddOnDecoratedBox.ErrorPC));
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorTransparent);
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorErrorBg);
errorStyle.Add(innerBoxDecoratorStyle);
}
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
hoverStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorErrorBgHover);
innerBoxDecoratorStyle.Add(hoverStyle);
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorErrorBgHover);
hoverStyle.Add(innerBoxDecoratorStyle);
}
errorStyle.Add(hoverStyle);
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
focusStyle.Add(Border.BackgroundProperty, LineEditResourceKey.ActiveBg);
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, AddOnDecoratedBoxResourceKey.ActiveBg);
focusStyle.Add(innerBoxDecoratorStyle);
}
innerBoxDecoratorStyle.Add(focusStyle);
errorStyle.Add(focusStyle);
var scrollViewerStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)
.Class(StdPseudoClass.FocusWithIn)
@ -401,37 +458,45 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
errorStyle.Add(scrollViewerStyle);
errorStyle.Add(innerBoxDecoratorStyle);
filledStyle.Add(errorStyle);
}
{
var warningStyle = new Style(selector => selector.Nesting().Class(AddOnDecoratedBox.WarningPC));
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorTransparent);
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorWarningBg);
warningStyle.Add(innerBoxDecoratorStyle);
}
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
hoverStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorWarningBgHover);
innerBoxDecoratorStyle.Add(hoverStyle);
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorWarningBgHover);
hoverStyle.Add(innerBoxDecoratorStyle);
}
warningStyle.Add(hoverStyle);
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
focusStyle.Add(Border.BackgroundProperty, LineEditResourceKey.ActiveBg);
innerBoxDecoratorStyle.Add(focusStyle);
{
var innerBoxDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, AddOnDecoratedBoxResourceKey.ActiveBg);
focusStyle.Add(innerBoxDecoratorStyle);
}
warningStyle.Add(focusStyle);
var scrollViewerStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)
.Descendant().OfType<ScrollViewer>());
scrollViewerStyle.Add(ScrollViewer.ForegroundProperty, GlobalResourceKey.ColorWarningText);
warningStyle.Add(scrollViewerStyle);
warningStyle.Add(innerBoxDecoratorStyle);
filledStyle.Add(warningStyle);
}

View File

@ -2,7 +2,7 @@
using Avalonia;
using Avalonia.Media;
namespace AtomUI.Controls.AddOnDecoratedBox;
namespace AtomUI.Controls;
[ControlDesignToken]
internal class AddOnDecoratedBoxToken : AbstractControlDesignToken

View File

@ -1,8 +1,159 @@
using Avalonia.Controls;
using AtomUI.Controls.Utils;
using AtomUI.Theme.Styling;
using AtomUI.Utils;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
namespace AtomUI.Controls.AddOnDecoratedBox;
namespace AtomUI.Controls;
public class AddOnDecoratedInnerBox : ContentControl
[TemplatePart(AddOnDecoratedInnerBoxTheme.ContentPresenterPart, typeof(ContentPresenter), IsRequired = true)]
public abstract class AddOnDecoratedInnerBox : ContentControl
{
#region
public static readonly StyledProperty<SizeType> SizeTypeProperty =
AddOnDecoratedBox.SizeTypeProperty.AddOwner<AddOnDecoratedInnerBox>();
public static readonly StyledProperty<object?> LeftAddOnContentProperty =
AvaloniaProperty.Register<AddOnDecoratedInnerBox, object?>(nameof(LeftAddOnContent));
public static readonly StyledProperty<object?> RightAddOnContentProperty =
AvaloniaProperty.Register<AddOnDecoratedInnerBox, object?>(nameof(RightAddOnContent));
public static readonly StyledProperty<bool> IsClearButtonVisibleProperty =
AvaloniaProperty.Register<AddOnDecoratedInnerBox, bool>(nameof(IsClearButtonVisible));
public SizeType SizeType
{
get => GetValue(SizeTypeProperty);
set => SetValue(SizeTypeProperty, value);
}
public object? LeftAddOnContent
{
get => GetValue(LeftAddOnContentProperty);
set => SetValue(LeftAddOnContentProperty, value);
}
public object? RightAddOnContent
{
get => GetValue(RightAddOnContentProperty);
set => SetValue(RightAddOnContentProperty, value);
}
public bool IsClearButtonVisible
{
get => GetValue(IsClearButtonVisibleProperty);
set => SetValue(IsClearButtonVisibleProperty, value);
}
#endregion
#region
internal static readonly DirectProperty<AddOnDecoratedInnerBox, Thickness> ContentPresenterMarginProperty =
AvaloniaProperty.RegisterDirect<AddOnDecoratedInnerBox, Thickness>(nameof(ContentPresenterMargin),
o => o.ContentPresenterMargin,
(o, v) => o.ContentPresenterMargin = v);
private static readonly DirectProperty<AddOnDecoratedInnerBox, double> MarginXSTokenProperty =
AvaloniaProperty.RegisterDirect<AddOnDecoratedInnerBox, double>(nameof(MarginXSToken),
o => o.MarginXSToken,
(o, v) => o.MarginXSToken = v);
private double _marginXSToken;
private double MarginXSToken
{
get => _marginXSToken;
set => SetAndRaise(MarginXSTokenProperty, ref _marginXSToken, value);
}
private Thickness _contentPresenterMargin;
internal Thickness ContentPresenterMargin
{
get => _contentPresenterMargin;
set => SetAndRaise(ContentPresenterMarginProperty, ref _contentPresenterMargin, value);
}
#endregion
private StackPanel? _leftAddOnLayout;
private StackPanel? _rightAddOnLayout;
private ToggleIconButton? _revealButton;
private IconButton? _clearButton;
protected virtual void NotifyClearButtonClicked()
{
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == LeftAddOnContentProperty || change.Property == RightAddOnContentProperty) {
if (change.OldValue is Control oldControl) {
UIStructureUtils.SetTemplateParent(oldControl, null);
}
if (change.NewValue is Control newControl) {
UIStructureUtils.SetTemplateParent(newControl, this);
}
}
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
TokenResourceBinder.CreateGlobalResourceBinding(this, MarginXSTokenProperty, GlobalResourceKey.MarginXS);
_leftAddOnLayout = e.NameScope.Find<StackPanel>(AddOnDecoratedInnerBoxTheme.LeftAddOnLayoutPart);
_rightAddOnLayout = e.NameScope.Find<StackPanel>(AddOnDecoratedInnerBoxTheme.RightAddOnLayoutPart);
_revealButton = e.NameScope.Find<ToggleIconButton>(AddOnDecoratedInnerBoxTheme.RevealButtonPart);
_clearButton = e.NameScope.Find<IconButton>(AddOnDecoratedInnerBoxTheme.ClearButtonPart);
if (_leftAddOnLayout is not null) {
_leftAddOnLayout.SizeChanged += HandleLayoutSizeChanged;
}
if (_rightAddOnLayout is not null) {
_rightAddOnLayout.SizeChanged += HandleLayoutSizeChanged;
}
if (_clearButton is not null) {
_clearButton.Click += (sender, args) =>
{
NotifyClearButtonClicked();
};
}
SetupContentPresenterMargin();
}
private void HandleLayoutSizeChanged(object? sender, SizeChangedEventArgs args)
{
SetupContentPresenterMargin();
}
private void SetupContentPresenterMargin()
{
var marginLeft = 0d;
var marginRight = 0d;
if (_leftAddOnLayout is not null) {
if (_leftAddOnLayout.DesiredSize.Width > 0 && _leftAddOnLayout.DesiredSize.Height > 0) {
marginLeft = _marginXSToken;
}
}
if (_rightAddOnLayout is not null) {
if (_rightAddOnLayout.DesiredSize.Width > 0 && _rightAddOnLayout.DesiredSize.Height > 0) {
marginRight = _marginXSToken;
}
}
ContentPresenterMargin = new Thickness(marginLeft, 0, marginRight, 0);
}
}

View File

@ -1,20 +1,200 @@
using AtomUI.Theme;
using AtomUI.Theme.Styling;
using AtomUI.Utils;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using Avalonia.Layout;
using Avalonia.Styling;
namespace AtomUI.Controls.AddOnDecoratedBox;
namespace AtomUI.Controls;
internal class AddOnDecoratedInnerBoxTheme : BaseControlTheme
{
protected override IControlTemplate? BuildControlTemplate()
public const string MainLayoutPart = "PART_MainLayout";
public const string ContentPresenterPart = "PART_ContentPresenter";
public const string LeftAddOnPart = "PART_LeftAddOn";
public const string RightAddOnPart = "PART_RightAddOn";
public const string LeftAddOnLayoutPart = "PART_LeftAddOnLayout";
public const string RightAddOnLayoutPart = "PART_RightAddOnLayout";
public const string ClearButtonPart = "PART_ClearButton";
public const string RevealButtonPart = "PART_RevealButton";
public AddOnDecoratedInnerBoxTheme(Type targetType) : base(targetType) { }
protected override IControlTemplate BuildControlTemplate()
{
return new FuncControlTemplate<AddOnDecoratedInnerBox>((innerBox, scope) =>
return new FuncControlTemplate<AddOnDecoratedInnerBox>((decoratedBox, scope) =>
{
return default!;
var mainLayout = new Grid()
{
Name = MainLayoutPart,
ColumnDefinitions = new ColumnDefinitions()
{
new ColumnDefinition(GridLength.Auto),
new ColumnDefinition(GridLength.Star),
new ColumnDefinition(GridLength.Auto)
}
};
BuildGridChildren(decoratedBox, mainLayout, scope);
return mainLayout;
});
}
protected virtual void BuildGridChildren(AddOnDecoratedInnerBox decoratedBox, Grid mainLayout, INameScope scope)
{
BuildLeftAddOn(mainLayout, scope);
BuildContent(decoratedBox, mainLayout, scope);
BuildRightAddOn(mainLayout, scope);
}
protected virtual void BuildLeftAddOn(Grid layout, INameScope scope)
{
// 理论上可以支持多个,暂时先支持一个
var addLayout = new StackPanel()
{
Name = LeftAddOnLayoutPart,
Orientation = Orientation.Horizontal,
};
TokenResourceBinder.CreateGlobalTokenBinding(addLayout, StackPanel.SpacingProperty, GlobalResourceKey.PaddingXXS);
addLayout.RegisterInNameScope(scope);
var leftAddOnContentPresenter = new ContentPresenter()
{
Name = LeftAddOnPart,
VerticalAlignment = VerticalAlignment.Stretch,
VerticalContentAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Left,
Focusable = false,
};
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.ContentProperty,
AddOnDecoratedInnerBox.LeftAddOnContentProperty);
leftAddOnContentPresenter.RegisterInNameScope(scope);
addLayout.Children.Add(leftAddOnContentPresenter);
Grid.SetColumn(addLayout, 0);
layout.Children.Add(addLayout);
}
protected virtual void BuildContent(AddOnDecoratedInnerBox decoratedBox, Grid layout, INameScope scope)
{
var innerBox = new ContentPresenter()
{
Name = ContentPresenterPart,
};
innerBox.RegisterInNameScope(scope);
CreateTemplateParentBinding(innerBox, ContentPresenter.MarginProperty, AddOnDecoratedInnerBox.ContentPresenterMarginProperty);
CreateTemplateParentBinding(innerBox, ContentPresenter.ContentProperty, AddOnDecoratedInnerBox.ContentProperty);
CreateTemplateParentBinding(innerBox, ContentPresenter.ContentTemplateProperty,
AddOnDecoratedInnerBox.ContentTemplateProperty);
layout.Children.Add(innerBox);
Grid.SetColumn(innerBox, 1);
}
private void BuildRightAddOn(Grid layout, INameScope scope)
{
var addLayout = new StackPanel()
{
Name = RightAddOnLayoutPart,
Orientation = Orientation.Horizontal
};
TokenResourceBinder.CreateGlobalTokenBinding(addLayout, StackPanel.SpacingProperty, GlobalResourceKey.PaddingXXS);
addLayout.RegisterInNameScope(scope);
var rightAddOnContentPresenter = new ContentPresenter()
{
Name = RightAddOnPart,
VerticalAlignment = VerticalAlignment.Stretch,
VerticalContentAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Right,
Focusable = false
};
CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.ContentProperty,
AddOnDecoratedInnerBox.RightAddOnContentProperty);
rightAddOnContentPresenter.RegisterInNameScope(scope);
addLayout.Children.Add(rightAddOnContentPresenter);
BuildRightAddOnItems(addLayout, scope);
layout.Children.Add(addLayout);
Grid.SetColumn(addLayout, 2);
}
protected virtual void BuildRightAddOnItems(StackPanel layout, INameScope scope)
{
BuildClearButton(layout, scope);
}
protected virtual void BuildClearButton(StackPanel addOnLayout, INameScope scope)
{
var closeIcon = new PathIcon()
{
Kind = "CloseCircleFilled"
};
var clearButton = new IconButton()
{
Name = ClearButtonPart,
Icon = closeIcon
};
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.WidthProperty, GlobalResourceKey.IconSize);
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.HeightProperty, GlobalResourceKey.IconSize);
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.NormalFilledBrushProperty,
GlobalResourceKey.ColorTextQuaternary);
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.ActiveFilledBrushProperty,
GlobalResourceKey.ColorTextTertiary);
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.SelectedFilledBrushProperty,
GlobalResourceKey.ColorText);
clearButton.RegisterInNameScope(scope);
CreateTemplateParentBinding(clearButton, IconButton.IsVisibleProperty,
AddOnDecoratedInnerBox.IsClearButtonVisibleProperty);
addOnLayout.Children.Add(clearButton);
}
protected override void BuildStyles()
{
BuildCommonStyle();
}
private void BuildCommonStyle()
{
var commonStyle = new Style(selector => selector.Nesting());
var largeStyle =
new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.SizeTypeProperty, SizeType.Large));
{
var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType<PathIcon>());
iconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSizeLG);
iconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSizeLG);
largeStyle.Add(iconStyle);
}
commonStyle.Add(largeStyle);
var middleStyle =
new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.SizeTypeProperty, SizeType.Middle));
{
var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType<PathIcon>());
iconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSize);
iconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSize);
middleStyle.Add(iconStyle);
}
commonStyle.Add(middleStyle);
var smallStyle =
new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.SizeTypeProperty, SizeType.Small));
{
var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType<PathIcon>());
iconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSizeSM);
iconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSizeSM);
smallStyle.Add(iconStyle);
}
commonStyle.Add(smallStyle);
Add(commonStyle);
}
}

View File

@ -1,29 +1,11 @@
using AtomUI.Controls.Utils;
using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using AtomUI.Utils;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Input;
namespace AtomUI.Controls;
public enum TextBoxVariant
{
Outline,
Filled,
Borderless
}
public enum TextBoxStatus
{
Default,
Warning,
Error
}
public class LineEdit : TextBox
{
public const string ErrorPC = ":error";
@ -40,11 +22,11 @@ public class LineEdit : TextBox
public static readonly StyledProperty<SizeType> SizeTypeProperty =
AvaloniaProperty.Register<LineEdit, SizeType>(nameof(SizeType), SizeType.Middle);
public static readonly StyledProperty<TextBoxVariant> StyleVariantProperty =
AvaloniaProperty.Register<LineEdit, TextBoxVariant>(nameof(StyleVariant), TextBoxVariant.Outline);
public static readonly StyledProperty<AddOnDecoratedVariant> StyleVariantProperty =
AvaloniaProperty.Register<LineEdit, AddOnDecoratedVariant>(nameof(StyleVariant), AddOnDecoratedVariant.Outline);
public static readonly StyledProperty<TextBoxStatus> StatusProperty =
AvaloniaProperty.Register<LineEdit, TextBoxStatus>(nameof(Status), TextBoxStatus.Default);
public static readonly StyledProperty<AddOnDecoratedStatus> StatusProperty =
AvaloniaProperty.Register<LineEdit, AddOnDecoratedStatus>(nameof(Status), AddOnDecoratedStatus.Default);
public static readonly StyledProperty<bool> IsEnableClearButtonProperty =
AvaloniaProperty.Register<LineEdit, bool>(nameof(IsEnableClearButton), false);
@ -70,13 +52,13 @@ public class LineEdit : TextBox
set => SetValue(SizeTypeProperty, value);
}
public TextBoxVariant StyleVariant
public AddOnDecoratedVariant StyleVariant
{
get => GetValue(StyleVariantProperty);
set => SetValue(StyleVariantProperty, value);
}
public TextBoxStatus Status
public AddOnDecoratedStatus Status
{
get => GetValue(StatusProperty);
set => SetValue(StatusProperty, value);
@ -98,71 +80,11 @@ public class LineEdit : TextBox
#region
internal static readonly DirectProperty<LineEdit, CornerRadius> EditKernelCornerRadiusProperty =
AvaloniaProperty.RegisterDirect<LineEdit, CornerRadius>(nameof(EditKernelCornerRadius),
o => o.EditKernelCornerRadius,
(o, v) => o.EditKernelCornerRadius = v);
internal static readonly DirectProperty<LineEdit, CornerRadius> LeftAddOnCornerRadiusProperty =
AvaloniaProperty.RegisterDirect<LineEdit, CornerRadius>(nameof(LeftAddOnCornerRadius),
o => o.LeftAddOnCornerRadius,
(o, v) => o.LeftAddOnCornerRadius = v);
internal static readonly DirectProperty<LineEdit, CornerRadius> RightAddOnCornerRadiusProperty =
AvaloniaProperty.RegisterDirect<LineEdit, CornerRadius>(nameof(RightAddOnCornerRadius),
o => o.RightAddOnCornerRadius,
(o, v) => o.RightAddOnCornerRadius = v);
internal static readonly DirectProperty<LineEdit, Thickness> LeftAddOnBorderThicknessProperty =
AvaloniaProperty.RegisterDirect<LineEdit, Thickness>(nameof(LeftAddOnBorderThickness),
o => o.LeftAddOnBorderThickness,
(o, v) => o.LeftAddOnBorderThickness = v);
internal static readonly DirectProperty<LineEdit, Thickness> RightAddOnBorderThicknessProperty =
AvaloniaProperty.RegisterDirect<LineEdit, Thickness>(nameof(RightAddOnBorderThickness),
o => o.RightAddOnBorderThickness,
(o, v) => o.RightAddOnBorderThickness = v);
internal static readonly DirectProperty<LineEdit, bool> IsEffectiveShowClearButtonProperty =
AvaloniaProperty.RegisterDirect<LineEdit, bool>(nameof(IsEffectiveShowClearButton),
o => o.IsEffectiveShowClearButton,
(o, v) => o.IsEffectiveShowClearButton = v);
private CornerRadius _editKernelCornerRadius;
internal CornerRadius EditKernelCornerRadius
{
get => _editKernelCornerRadius;
set => SetAndRaise(EditKernelCornerRadiusProperty, ref _editKernelCornerRadius, value);
}
private CornerRadius _leftAddOnCornerRadius;
internal CornerRadius LeftAddOnCornerRadius
{
get => _leftAddOnCornerRadius;
set => SetAndRaise(LeftAddOnCornerRadiusProperty, ref _leftAddOnCornerRadius, value);
}
private CornerRadius _rightAddOnCornerRadius;
internal CornerRadius RightAddOnCornerRadius
{
get => _rightAddOnCornerRadius;
set => SetAndRaise(RightAddOnCornerRadiusProperty, ref _rightAddOnCornerRadius, value);
}
private Thickness _leftAddOnBorderThickness;
internal Thickness LeftAddOnBorderThickness
{
get => _leftAddOnBorderThickness;
set => SetAndRaise(LeftAddOnBorderThicknessProperty, ref _leftAddOnBorderThickness, value);
}
private Thickness _rightAddOnBorderThickness;
internal Thickness RightAddOnBorderThickness
{
get => _rightAddOnBorderThickness;
set => SetAndRaise(RightAddOnBorderThicknessProperty, ref _rightAddOnBorderThickness, value);
}
private bool _isEffectiveShowClearButton;
internal bool IsEffectiveShowClearButton
{
@ -172,25 +94,15 @@ public class LineEdit : TextBox
#endregion
protected Control? _leftAddOnPresenter;
protected Control? _rightAddOnPresenter;
protected Border? _lineEditKernelDecorator;
static LineEdit()
{
AffectsRender<LineEdit>(BorderBrushProperty, BackgroundProperty);
AffectsMeasure<LineEdit>(LeftAddOnProperty, RightAddOnProperty);
// AffectsMeasure<LineEdit>(LeftAddOnProperty, RightAddOnProperty);
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
TokenResourceBinder.CreateGlobalResourceBinding(this, BorderThicknessProperty, GlobalResourceKey.BorderThickness,
BindingPriority.Template, new RenderScaleAwareThicknessConfigure(this));
_leftAddOnPresenter = e.NameScope.Find<Control>(LineEditTheme.LeftAddOnPart);
_rightAddOnPresenter = e.NameScope.Find<Control>(LineEditTheme.RightAddOnPart);
_lineEditKernelDecorator = e.NameScope.Find<Border>(LineEditTheme.LineEditKernelDecoratorPart);
SetupEditKernelCornerRadius();
SetupEffectiveShowClearButton();
}
@ -198,16 +110,6 @@ public class LineEdit : TextBox
{
base.OnPropertyChanged(change);
if (VisualRoot is not null) {
if (change.Property == LeftAddOnProperty || change.Property == RightAddOnProperty) {
SetupEditKernelCornerRadius();
}
}
if (change.Property == CornerRadiusProperty || change.Property == BorderThicknessProperty) {
SetupAddOnBorderInfo();
}
if (change.Property == AcceptsReturnProperty ||
change.Property == IsReadOnlyProperty ||
change.Property == TextProperty ||
@ -233,81 +135,17 @@ public class LineEdit : TextBox
}
}
private void SetupAddOnBorderInfo()
{
var topLeftRadius = CornerRadius.TopLeft;
var topRightRadius = CornerRadius.TopRight;
var bottomLeftRadius = CornerRadius.BottomLeft;
var bottomRightRadius = CornerRadius.BottomRight;
var topThickness = BorderThickness.Top;
var rightThickness = BorderThickness.Right;
var bottomThickness = BorderThickness.Bottom;
var leftThickness = BorderThickness.Left;
LeftAddOnCornerRadius = new CornerRadius(topLeft: topLeftRadius,
topRight: 0,
bottomLeft:bottomLeftRadius,
bottomRight:0);
RightAddOnCornerRadius = new CornerRadius(topLeft: 0,
topRight: topRightRadius,
bottomLeft:0,
bottomRight:bottomRightRadius);
LeftAddOnBorderThickness = new Thickness(top: topThickness, right:0, bottom:bottomThickness, left: leftThickness);
RightAddOnBorderThickness = new Thickness(top: topThickness, right:rightThickness, bottom:bottomThickness, left: 0);
NotifyAddOnBorderInfoCalculated();
}
protected virtual void NotifyAddOnBorderInfoCalculated()
{
}
private void SetupEditKernelCornerRadius()
{
var topLeftRadius = CornerRadius.TopLeft;
var topRightRadius = CornerRadius.TopRight;
var bottomLeftRadius = CornerRadius.BottomLeft;
var bottomRightRadius = CornerRadius.BottomRight;
if (_leftAddOnPresenter is not null && _leftAddOnPresenter.IsVisible) {
topLeftRadius = 0;
bottomLeftRadius = 0;
}
if (_rightAddOnPresenter is not null && _rightAddOnPresenter.IsVisible) {
topRightRadius = 0;
bottomRightRadius = 0;
}
EditKernelCornerRadius = new CornerRadius(topLeft: topLeftRadius,
topRight: topRightRadius,
bottomLeft:bottomLeftRadius,
bottomRight:bottomRightRadius);
}
protected override Size MeasureOverride(Size availableSize)
{
return base.MeasureOverride(new Size(availableSize.Width - BorderThickness.Left - BorderThickness.Right, availableSize.Height));
}
protected override Size ArrangeOverride(Size finalSize)
{
return base.ArrangeOverride(new Size(finalSize.Width - BorderThickness.Left - BorderThickness.Right, finalSize.Height));
}
protected override void OnPointerPressed(PointerPressedEventArgs e)
{
if (_lineEditKernelDecorator is null) {
return;
}
var targetRect = new Rect(_lineEditKernelDecorator.DesiredSize);
if (!targetRect.Contains(e.GetPosition(_lineEditKernelDecorator))) {
return;
}
base.OnPointerPressed(e);
}
// protected override void OnPointerPressed(PointerPressedEventArgs e)
// {
// if (_lineEditKernelDecorator is null) {
// return;
// }
// var targetRect = new Rect(_lineEditKernelDecorator.DesiredSize);
// if (!targetRect.Contains(e.GetPosition(_lineEditKernelDecorator))) {
// return;
// }
// base.OnPointerPressed(e);
// }
private void SetupEffectiveShowClearButton()
{
@ -321,7 +159,7 @@ public class LineEdit : TextBox
private void UpdatePseudoClasses()
{
PseudoClasses.Set(ErrorPC, Status == TextBoxStatus.Error);
PseudoClasses.Set(WarningPC, Status == TextBoxStatus.Warning);
PseudoClasses.Set(ErrorPC, Status == AddOnDecoratedStatus.Error);
PseudoClasses.Set(WarningPC, Status == AddOnDecoratedStatus.Warning);
}
}

View File

@ -0,0 +1,42 @@
using Avalonia;
namespace AtomUI.Controls;
public class LineEditInnerBox : AddOnDecoratedInnerBox
{
#region
public static readonly StyledProperty<bool> IsRevealButtonVisibleProperty =
AvaloniaProperty.Register<LineEditInnerBox, bool>(nameof(IsRevealButtonVisible));
public static readonly StyledProperty<bool> IsRevealButtonCheckedProperty =
AvaloniaProperty.Register<LineEditInnerBox, bool>(nameof(IsRevealButtonChecked));
public bool IsRevealButtonVisible
{
get => GetValue(IsRevealButtonVisibleProperty);
set => SetValue(IsRevealButtonVisibleProperty, value);
}
public bool IsRevealButtonChecked
{
get => GetValue(IsRevealButtonCheckedProperty);
set => SetValue(IsRevealButtonCheckedProperty, value);
}
#endregion
private WeakReference<LineEdit> _lineEdit;
public LineEditInnerBox(LineEdit edit)
{
_lineEdit = new WeakReference<LineEdit>(edit);
}
protected override void NotifyClearButtonClicked()
{
if (_lineEdit.TryGetTarget(out var lineEdit)) {
lineEdit.Clear();
}
}
}

View File

@ -0,0 +1,60 @@
using AtomUI.Theme.Styling;
using AtomUI.Utils;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.Data;
namespace AtomUI.Controls;
[ControlThemeProvider]
internal class LineEditInnerBoxTheme : AddOnDecoratedInnerBoxTheme
{
public LineEditInnerBoxTheme() : base(typeof(LineEditInnerBox)) {}
protected override void BuildRightAddOnItems(StackPanel layout, INameScope scope)
{
BuildClearButton(layout, scope);
BuildRevealButton(layout, scope);
}
protected virtual void BuildRevealButton(StackPanel addOnLayout, INameScope scope)
{
var checkedIcon = new PathIcon()
{
Kind = "EyeTwoTone"
};
TokenResourceBinder.CreateGlobalTokenBinding(checkedIcon, PathIcon.PrimaryFilledBrushProperty,
AddOnDecoratedBoxResourceKey.ActiveBorderColor);
TokenResourceBinder.CreateGlobalTokenBinding(checkedIcon, PathIcon.SecondaryFilledBrushProperty,
GlobalResourceKey.ColorPrimaryBgHover);
var unCheckedIcon = new PathIcon()
{
Kind = "EyeInvisibleOutlined"
};
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.NormalFilledBrushProperty,
GlobalResourceKey.ColorTextQuaternary);
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.ActiveFilledBrushProperty,
GlobalResourceKey.ColorTextTertiary);
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.SelectedFilledBrushProperty,
GlobalResourceKey.ColorText);
var revealButton = new ToggleIconButton()
{
Name = RevealButtonPart,
CheckedIcon = checkedIcon,
UnCheckedIcon = unCheckedIcon,
};
TokenResourceBinder.CreateGlobalTokenBinding(revealButton, ToggleIconButton.IconHeightProperty, GlobalResourceKey.IconSize);
TokenResourceBinder.CreateGlobalTokenBinding(revealButton, ToggleIconButton.IconWidthProperty, GlobalResourceKey.IconSize);
revealButton.RegisterInNameScope(scope);
CreateTemplateParentBinding(revealButton, ToggleIconButton.IsVisibleProperty,
LineEditInnerBox.IsRevealButtonVisibleProperty);
CreateTemplateParentBinding(revealButton, ToggleIconButton.IsCheckedProperty,
LineEditInnerBox.IsRevealButtonCheckedProperty, BindingMode.TwoWay);
addOnLayout.Children.Add(revealButton);
}
}

View File

@ -1,204 +0,0 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
namespace AtomUI.Controls;
internal class LineEditKernel : Panel
{
#region
public static readonly DirectProperty<LineEditKernel, ContentPresenter?> LeftInnerContentProperty =
AvaloniaProperty.RegisterDirect<LineEditKernel, ContentPresenter?>(nameof(LeftInnerContent),
o => o.LeftInnerContent,
(o, v) => o.LeftInnerContent = v);
public static readonly DirectProperty<LineEditKernel, ContentPresenter?> RightInnerContentProperty =
AvaloniaProperty.RegisterDirect<LineEditKernel, ContentPresenter?>(nameof(RightInnerContent),
o => o.RightInnerContent,
(o, v) => o.RightInnerContent = v);
public static readonly DirectProperty<LineEditKernel, IconButton?> ClearButtonProperty =
AvaloniaProperty.RegisterDirect<LineEditKernel, IconButton?>(nameof(ClearButton),
o => o.ClearButton,
(o, v) => o.ClearButton = v);
public static readonly DirectProperty<LineEditKernel, ToggleIconButton?> RevealButtonProperty =
AvaloniaProperty.RegisterDirect<LineEditKernel, ToggleIconButton?>(nameof(RevealButton),
o => o.RevealButton,
(o, v) => o.RevealButton = v);
public static readonly DirectProperty<LineEditKernel, ScrollViewer?> TextPresenterProperty =
AvaloniaProperty.RegisterDirect<LineEditKernel, ScrollViewer?>(nameof(TextPresenter),
o => o.TextPresenter,
(o, v) => o.TextPresenter = v);
private ContentPresenter? _leftInnerContent;
public ContentPresenter? LeftInnerContent
{
get => _leftInnerContent;
set => SetAndRaise(LeftInnerContentProperty, ref _leftInnerContent, value);
}
private ContentPresenter? _rightInnerContent;
public ContentPresenter? RightInnerContent
{
get => _rightInnerContent;
set => SetAndRaise(RightInnerContentProperty, ref _rightInnerContent, value);
}
private IconButton? _clearButton;
public IconButton? ClearButton
{
get => _clearButton;
set => SetAndRaise(ClearButtonProperty, ref _clearButton, value);
}
private ToggleIconButton? _revealButton;
public ToggleIconButton? RevealButton
{
get => _revealButton;
set => SetAndRaise(RevealButtonProperty, ref _revealButton, value);
}
private ScrollViewer? _textPresenter;
public ScrollViewer? TextPresenter
{
get => _textPresenter;
set => SetAndRaise(TextPresenterProperty, ref _textPresenter, value);
}
#endregion
static LineEditKernel()
{
AffectsMeasure<TabsContainerPanel>(LeftInnerContentProperty,
RightInnerContentProperty,
ClearButtonProperty,
RevealButtonProperty,
TextPresenterProperty);
}
public LineEditKernel()
{
Focusable = true;
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == LeftInnerContentProperty) {
var oldLeftInnerContent = change.GetOldValue<ContentPresenter?>();
if (oldLeftInnerContent is not null) {
Children.Remove(oldLeftInnerContent);
}
if (LeftInnerContent is not null) {
Children.Add(LeftInnerContent);
}
} else if (change.Property == RightInnerContentProperty) {
var oldRightInnerContent = change.GetOldValue<ContentPresenter?>();
if (oldRightInnerContent is not null) {
Children.Remove(oldRightInnerContent);
}
if (RightInnerContent is not null) {
Children.Add(RightInnerContent);
}
} else if (change.Property == ClearButtonProperty) {
var oldClearButton = change.GetOldValue<IconButton?>();
if (oldClearButton is not null) {
Children.Remove(oldClearButton);
}
if (ClearButton is not null) {
Children.Add(ClearButton);
}
} else if (change.Property == RevealButtonProperty) {
var oldRevealButton = change.GetOldValue<ToggleIconButton?>();
if (oldRevealButton is not null) {
Children.Remove(oldRevealButton);
}
if (RevealButton is not null) {
Children.Add(RevealButton);
}
} else if (change.Property == TextPresenterProperty) {
var oldTextPresenter = change.GetOldValue<ScrollViewer?>();
if (oldTextPresenter is not null) {
Children.Remove(oldTextPresenter);
}
if (TextPresenter is not null) {
Children.Add(TextPresenter);
}
}
}
protected override Size MeasureOverride(Size availableSize)
{
// 不考虑任何 border 和 Padding外层的 Decorator 已经考虑
var height = 0d;
var remainWidth = availableSize.Width;
if (LeftInnerContent is not null && LeftInnerContent.IsVisible) {
LeftInnerContent.Measure(availableSize);
height = Math.Max(height, LeftInnerContent.DesiredSize.Height);
remainWidth -= LeftInnerContent.DesiredSize.Width;
}
if (RightInnerContent is not null && RightInnerContent.IsVisible) {
RightInnerContent.Measure(availableSize);
height = Math.Max(height, RightInnerContent.DesiredSize.Height);
remainWidth -= RightInnerContent.DesiredSize.Width;
}
if (RevealButton is not null && RevealButton.IsVisible) {
RevealButton.Measure(availableSize);
height = Math.Max(height, RevealButton.DesiredSize.Height);
remainWidth -= RevealButton.DesiredSize.Width;
}
if (ClearButton is not null && ClearButton.IsVisible) {
ClearButton.Measure(availableSize);
height = Math.Max(height, ClearButton.DesiredSize.Height);
remainWidth -= ClearButton.DesiredSize.Width;
}
if (TextPresenter is not null && TextPresenter.IsVisible) {
TextPresenter.Measure(new Size(remainWidth, availableSize.Height));
height = Math.Max(height, TextPresenter.DesiredSize.Height);
}
return new Size(availableSize.Width, height);
}
protected override Size ArrangeOverride(Size finalSize)
{
var offsetLeft = 0d;
if (LeftInnerContent is not null && LeftInnerContent.IsVisible) {
LeftInnerContent.Arrange(new Rect(new Point(offsetLeft, (finalSize.Height - LeftInnerContent.DesiredSize.Height) / 2), LeftInnerContent.DesiredSize));
offsetLeft += LeftInnerContent.DesiredSize.Width;
}
var offsetRight = finalSize.Width;
if (RightInnerContent is not null && RightInnerContent.IsVisible) {
offsetRight -= RightInnerContent.DesiredSize.Width;
RightInnerContent.Arrange(new Rect(new Point(offsetRight, (finalSize.Height - RightInnerContent.DesiredSize.Height) / 2), RightInnerContent.DesiredSize));
}
if (RevealButton is not null && RevealButton.IsVisible) {
offsetRight -= RevealButton.DesiredSize.Width;
RevealButton.Arrange(new Rect(new Point(offsetRight, (finalSize.Height - RevealButton.DesiredSize.Height) / 2), RevealButton.DesiredSize));
}
if (ClearButton is not null && ClearButton.IsVisible) {
offsetRight -= ClearButton.DesiredSize.Width;
ClearButton.Arrange(new Rect(new Point(offsetRight, (finalSize.Height - ClearButton.DesiredSize.Height) / 2), ClearButton.DesiredSize));
}
if (TextPresenter is not null && TextPresenter.IsVisible) {
TextPresenter.Arrange(new Rect(new Point(offsetLeft, 0), new Size(offsetRight - offsetLeft, finalSize.Height)));
}
return new Size(finalSize.Width, finalSize.Height);
}
}

View File

@ -1,10 +1,6 @@
using AtomUI.Data;
using AtomUI.Media;
using AtomUI.Theme;
using AtomUI.Theme.Styling;
using AtomUI.Theme.Utils;
using AtomUI.Utils;
using Avalonia.Animation;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
@ -19,21 +15,11 @@ namespace AtomUI.Controls;
[ControlThemeProvider]
internal class LineEditTheme : BaseControlTheme
{
public const string MainLayoutPart = "PART_FrameDecorator";
public const string DecoratedBoxPart = "PART_DecoratedBox";
public const string LineEditInnerBoxPart = "PART_LineEditInnerBox";
public const string TextPresenterPart = "PART_TextPresenter";
public const string WatermarkPart = "PART_Watermark";
public const string ScrollViewerPart = "PART_ScrollViewer";
public const string LeftAddOnPart = "PART_LeftAddOn";
public const string RightAddOnPart = "PART_RightAddOn";
public const string LeftInnerContentPart = "PART_LeftInnerContent";
public const string RightInnerContentPart = "PART_RightInnerContent";
public const string ClearButtonPart = "PART_ClearButton";
public const string RevealButtonPart = "PART_RevealButton";
public const string LineEditKernelPart = "PART_LineEditKernel";
public const string LineEditKernelDecoratorPart = "PART_LineEditKernelDecorator";
public const int NormalZIndex = 1000;
public const int ActivatedZIndex = 2000;
public LineEditTheme(Type targetType) : base(targetType) { }
public LineEditTheme() : base(typeof(LineEdit)) { }
@ -42,160 +28,44 @@ internal class LineEditTheme : BaseControlTheme
{
return new FuncControlTemplate<LineEdit>((lineEdit, scope) =>
{
var mainLayout = new Grid()
var decoratedBox = new AddOnDecoratedBox()
{
Name = MainLayoutPart,
ColumnDefinitions = new ColumnDefinitions()
{
new ColumnDefinition(GridLength.Auto),
new ColumnDefinition(GridLength.Star),
new ColumnDefinition(GridLength.Auto)
}
Name = DecoratedBoxPart,
Focusable = true
};
BuildGridChildren(lineEdit, mainLayout, scope);
return mainLayout;
CreateTemplateParentBinding(decoratedBox, AddOnDecoratedBox.StyleVariantProperty, LineEdit.StyleVariantProperty);
CreateTemplateParentBinding(decoratedBox, AddOnDecoratedBox.SizeTypeProperty, LineEdit.SizeTypeProperty);
CreateTemplateParentBinding(decoratedBox, AddOnDecoratedBox.StatusProperty, LineEdit.StatusProperty);
CreateTemplateParentBinding(decoratedBox, AddOnDecoratedBox.LeftAddOnProperty, LineEdit.LeftAddOnProperty);
CreateTemplateParentBinding(decoratedBox, AddOnDecoratedBox.RightAddOnProperty, LineEdit.RightAddOnProperty);
decoratedBox.RegisterInNameScope(scope);
var lineEditKernel = BuildLineEditKernel(lineEdit, scope);
decoratedBox.Content = lineEditKernel;
lineEditKernel.RegisterInNameScope(scope);
return decoratedBox;
});
}
protected virtual void BuildGridChildren(LineEdit lineEdit, Grid layout, INameScope scope)
protected virtual LineEditInnerBox BuildLineEditKernel(LineEdit lineEdit, INameScope scope)
{
BuildLeftAddOn(layout, scope);
BuildLineEditKernel(lineEdit, layout, scope);
BuildRightAddOn(layout, scope);
}
protected virtual void BuildLeftAddOn(Grid layout, INameScope scope)
var editInnerBox = new LineEditInnerBox(lineEdit)
{
var leftAddOnContentPresenter = new ContentPresenter()
{
Name = LeftAddOnPart,
VerticalAlignment = VerticalAlignment.Stretch,
VerticalContentAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Left,
Focusable = false
Name = LineEditInnerBoxPart,
Cursor = new Cursor(StandardCursorType.Ibeam),
IsRevealButtonVisible = true
};
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.ContentProperty,
LineEdit.LeftAddOnProperty);
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.BorderThicknessProperty,
LineEdit.LeftAddOnBorderThicknessProperty);
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.CornerRadiusProperty,
LineEdit.LeftAddOnCornerRadiusProperty);
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.IsVisibleProperty,
LineEdit.LeftAddOnProperty,
BindingMode.Default, ObjectConverters.IsNotNull);
leftAddOnContentPresenter.RegisterInNameScope(scope);
CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.LeftAddOnContentProperty, LineEdit.InnerLeftContentProperty);
CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.RightAddOnContentProperty, LineEdit.InnerRightContentProperty);
CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.SizeTypeProperty, LineEdit.SizeTypeProperty);
CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.IsClearButtonVisibleProperty, LineEdit.IsEffectiveShowClearButtonProperty);
CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.IsRevealButtonVisibleProperty, LineEdit.IsEnableRevealButtonProperty);
CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.IsRevealButtonCheckedProperty, LineEdit.RevealPasswordProperty);
TokenResourceBinder.CreateTokenBinding(leftAddOnContentPresenter, ContentPresenter.BackgroundProperty,
LineEditResourceKey.AddonBg);
TokenResourceBinder.CreateTokenBinding(leftAddOnContentPresenter, ContentPresenter.BorderBrushProperty,
GlobalResourceKey.ColorBorder);
Grid.SetColumn(leftAddOnContentPresenter, 0);
layout.Children.Add(leftAddOnContentPresenter);
}
protected virtual void BuildLineEditKernel(LineEdit lineEdit, Grid layout, INameScope scope)
{
var kernelDecorator = new Border()
{
Name = LineEditKernelDecoratorPart,
Transitions = new Transitions()
{
AnimationUtils.CreateTransition<SolidColorBrushTransition>(Border.BorderBrushProperty),
AnimationUtils.CreateTransition<SolidColorBrushTransition>(Border.BackgroundProperty)
}
};
kernelDecorator.RegisterInNameScope(scope);
var kernelLayout = new LineEditKernel()
{
Name = LineEditKernelPart,
Cursor = new Cursor(StandardCursorType.Ibeam)
};
CreateTemplateParentBinding(kernelDecorator, Border.BorderThicknessProperty, LineEdit.BorderThicknessProperty);
CreateTemplateParentBinding(kernelDecorator, Border.CornerRadiusProperty,
LineEdit.EditKernelCornerRadiusProperty);
BuildInnerLeftContent(kernelLayout, scope);
BuildTextPresenter(lineEdit, kernelLayout, scope);
BuildClearButton(kernelLayout, scope);
BuildRevealButton(kernelLayout, scope);
BuildInnerRightContent(kernelLayout, scope);
kernelDecorator.Child = kernelLayout;
layout.Children.Add(kernelDecorator);
Grid.SetColumn(kernelDecorator, 1);
}
protected virtual void BuildRightAddOn(Grid layout, INameScope scope)
{
var rightAddOnContentPresenter = new ContentPresenter()
{
Name = RightAddOnPart,
VerticalAlignment = VerticalAlignment.Stretch,
VerticalContentAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Right,
Focusable = false
};
CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.ContentProperty,
LineEdit.RightAddOnProperty);
CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.BorderThicknessProperty,
LineEdit.RightAddOnBorderThicknessProperty);
CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.CornerRadiusProperty,
LineEdit.RightAddOnCornerRadiusProperty);
CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.IsVisibleProperty,
LineEdit.RightAddOnProperty,
BindingMode.Default, ObjectConverters.IsNotNull);
TokenResourceBinder.CreateTokenBinding(rightAddOnContentPresenter, ContentPresenter.BackgroundProperty,
LineEditResourceKey.AddonBg);
TokenResourceBinder.CreateTokenBinding(rightAddOnContentPresenter, ContentPresenter.BorderBrushProperty,
GlobalResourceKey.ColorBorder);
rightAddOnContentPresenter.RegisterInNameScope(scope);
layout.Children.Add(rightAddOnContentPresenter);
Grid.SetColumn(rightAddOnContentPresenter, 2);
}
protected virtual void BuildInnerLeftContent(LineEditKernel layout, INameScope scope)
{
var innerLeftContentPresenter = new ContentPresenter()
{
Name = LeftInnerContentPart,
VerticalAlignment = VerticalAlignment.Center
};
CreateTemplateParentBinding(innerLeftContentPresenter, ContentPresenter.IsVisibleProperty,
LineEdit.InnerLeftContentProperty,
BindingMode.Default, ObjectConverters.IsNotNull);
CreateTemplateParentBinding(innerLeftContentPresenter, ContentPresenter.ContentProperty,
LineEdit.InnerLeftContentProperty);
innerLeftContentPresenter.RegisterInNameScope(scope);
layout.LeftInnerContent = innerLeftContentPresenter;
}
protected virtual void BuildInnerRightContent(LineEditKernel layout, INameScope scope)
{
var innerRightContentPresenter = new ContentPresenter()
{
Name = RightInnerContentPart
};
CreateTemplateParentBinding(innerRightContentPresenter, ContentPresenter.IsVisibleProperty,
LineEdit.InnerRightContentProperty,
BindingMode.Default, ObjectConverters.IsNotNull);
CreateTemplateParentBinding(innerRightContentPresenter, ContentPresenter.ContentProperty,
LineEdit.InnerRightContentProperty);
innerRightContentPresenter.RegisterInNameScope(scope);
layout.RightInnerContent = innerRightContentPresenter;
}
protected virtual void BuildTextPresenter(LineEdit lineEdit, LineEditKernel layout, INameScope scope)
{
var scrollViewer = new ScrollViewer
{
Name = ScrollViewerPart,
Focusable = true
};
// TODO attach 属性不知道怎么指定 Avalonia 控件所在的名称控件,无法用模板绑定的方式进行绑定
@ -231,7 +101,7 @@ internal class LineEditTheme : BaseControlTheme
var textPresenter = new TextPresenter
{
Name = TextPresenterPart,
Name = TextPresenterPart
};
CreateTemplateParentBinding(textPresenter, TextPresenter.HorizontalAlignmentProperty,
@ -259,90 +129,37 @@ internal class LineEditTheme : BaseControlTheme
textPresenter.RegisterInNameScope(scope);
scrollViewer.Content = textPresenterLayout;
layout.TextPresenter = scrollViewer;
}
protected virtual void BuildClearButton(LineEditKernel layout, INameScope scope)
{
var closeIcon = new PathIcon()
{
Kind = "CloseCircleFilled"
};
var clearButton = new IconButton()
{
Name = ClearButtonPart,
Icon = closeIcon
};
editInnerBox.Content = scrollViewer;
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.WidthProperty, GlobalResourceKey.IconSize);
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.HeightProperty, GlobalResourceKey.IconSize);
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.NormalFilledBrushProperty,
GlobalResourceKey.ColorTextQuaternary);
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.ActiveFilledBrushProperty,
GlobalResourceKey.ColorTextTertiary);
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.SelectedFilledBrushProperty,
GlobalResourceKey.ColorText);
CreateTemplateParentBinding(clearButton, IconButton.CommandProperty, nameof(LineEdit.Clear));
clearButton.RegisterInNameScope(scope);
CreateTemplateParentBinding(clearButton, IconButton.IsVisibleProperty,
LineEdit.IsEffectiveShowClearButtonProperty);
layout.ClearButton = clearButton;
}
protected virtual void BuildRevealButton(LineEditKernel layout, INameScope scope)
{
var checkedIcon = new PathIcon()
{
Kind = "EyeTwoTone"
};
TokenResourceBinder.CreateGlobalTokenBinding(checkedIcon, PathIcon.WidthProperty, GlobalResourceKey.IconSize);
TokenResourceBinder.CreateGlobalTokenBinding(checkedIcon, PathIcon.HeightProperty, GlobalResourceKey.IconSize);
TokenResourceBinder.CreateGlobalTokenBinding(checkedIcon, PathIcon.PrimaryFilledBrushProperty,
LineEditResourceKey.ActiveBorderColor);
TokenResourceBinder.CreateGlobalTokenBinding(checkedIcon, PathIcon.SecondaryFilledBrushProperty,
GlobalResourceKey.ColorPrimaryBgHover);
var unCheckedIcon = new PathIcon()
{
Kind = "EyeInvisibleOutlined"
};
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.WidthProperty, GlobalResourceKey.IconSize);
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.HeightProperty, GlobalResourceKey.IconSize);
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.NormalFilledBrushProperty,
GlobalResourceKey.ColorTextQuaternary);
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.ActiveFilledBrushProperty,
GlobalResourceKey.ColorTextTertiary);
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.SelectedFilledBrushProperty,
GlobalResourceKey.ColorText);
var revealButton = new ToggleIconButton()
{
Name = RevealButtonPart,
CheckedIcon = checkedIcon,
UnCheckedIcon = unCheckedIcon
};
revealButton.RegisterInNameScope(scope);
CreateTemplateParentBinding(revealButton, ToggleIconButton.IsVisibleProperty,
LineEdit.IsEnableRevealButtonProperty);
CreateTemplateParentBinding(revealButton, ToggleIconButton.IsCheckedProperty, LineEdit.RevealPasswordProperty,
BindingMode.TwoWay);
layout.RevealButton = revealButton;
return editInnerBox;
}
protected override void BuildStyles()
{
BuildFixedStyle();
BuildCommonStyle();
BuildFilledStyle();
BuildOutLineStyle();
BuildBorderlessStyle();
BuildDisabledStyle();
BuildFixedStyle();
}
private void BuildCommonStyle()
{
var commonStyle = new Style(selector => selector.Nesting());
var largeStyle =
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.SizeTypeProperty, SizeType.Large));
largeStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeightLG);
commonStyle.Add(largeStyle);
var middleStyle =
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.SizeTypeProperty, SizeType.Middle));
middleStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeight);
commonStyle.Add(middleStyle);
var smallStyle =
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.SizeTypeProperty, SizeType.Small));
smallStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeightSM);
commonStyle.Add(smallStyle);
Add(commonStyle);
}
private void BuildFixedStyle()
@ -354,366 +171,4 @@ internal class LineEditTheme : BaseControlTheme
this.Add(ScrollViewer.IsScrollChainingEnabledProperty, true);
}
private void BuildCommonStyle()
{
var commonStyle = new Style(selector => selector.Nesting());
commonStyle.Add(LineEdit.ForegroundProperty, GlobalResourceKey.ColorText);
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
decoratorStyle.Add(Border.ZIndexProperty, NormalZIndex);
commonStyle.Add(decoratorStyle);
// 输入框左右小组件的 margin 设置
var leftInnerContentStyle = new Style(selector => selector.Nesting().Template().Name(LeftInnerContentPart));
leftInnerContentStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.LeftInnerAddOnMargin);
commonStyle.Add(leftInnerContentStyle);
var rightInnerContentStyle = new Style(selector => selector.Nesting().Template().Name(RightInnerContentPart));
rightInnerContentStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.RightInnerAddOnMargin);
commonStyle.Add(rightInnerContentStyle);
var clearButtonStyle = new Style(selector => selector.Nesting().Template().Name(ClearButtonPart));
clearButtonStyle.Add(IconButton.PaddingProperty, LineEditResourceKey.RightInnerAddOnMargin);
commonStyle.Add(clearButtonStyle);
var revealButtonStyle = new Style(selector => selector.Nesting().Template().Name(RevealButtonPart));
revealButtonStyle.Add(ToggleIconButton.PaddingProperty, LineEditResourceKey.RightInnerAddOnMargin);
commonStyle.Add(revealButtonStyle);
{
// 左右 inner icon 的大小
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
innerContentIconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSize);
innerContentIconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSize);
commonStyle.Add(innerContentIconStyle);
}
var largeStyle =
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.SizeTypeProperty, SizeType.Large));
{
var editKernelDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
editKernelDecoratorStyle.Add(Border.PaddingProperty, LineEditResourceKey.PaddingLG);
largeStyle.Add(editKernelDecoratorStyle);
}
{
var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart),
selector.Nesting().Template().Name(RightAddOnPart)));
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.PaddingLG);
largeStyle.Add(addOnStyle);
}
{
// 左右 AddOn icon 的大小
var addOnContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart).Descendant().OfType<PathIcon>(),
selector.Nesting().Template().Name(RightAddOnPart).Descendant().OfType<PathIcon>()));
addOnContentIconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSizeLG);
addOnContentIconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSizeLG);
largeStyle.Add(addOnContentIconStyle);
}
largeStyle.Add(LineEdit.FontSizeProperty, LineEditResourceKey.InputFontSizeLG);
largeStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeightLG);
largeStyle.Add(LineEdit.CornerRadiusProperty, GlobalResourceKey.BorderRadiusLG);
commonStyle.Add(largeStyle);
var middleStyle =
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.SizeTypeProperty, SizeType.Middle));
{
var editKernelDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
editKernelDecoratorStyle.Add(Border.PaddingProperty, LineEditResourceKey.Padding);
middleStyle.Add(editKernelDecoratorStyle);
}
{
var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart),
selector.Nesting().Template().Name(RightAddOnPart)));
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.Padding);
middleStyle.Add(addOnStyle);
}
{
// 左右 AddOn icon 的大小
var addOnContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart).Descendant().OfType<PathIcon>(),
selector.Nesting().Template().Name(RightAddOnPart).Descendant().OfType<PathIcon>()));
addOnContentIconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSize);
addOnContentIconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSize);
middleStyle.Add(addOnContentIconStyle);
}
middleStyle.Add(LineEdit.FontSizeProperty, LineEditResourceKey.InputFontSize);
middleStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeight);
middleStyle.Add(LineEdit.CornerRadiusProperty, GlobalResourceKey.BorderRadius);
commonStyle.Add(middleStyle);
var smallStyle =
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.SizeTypeProperty, SizeType.Small));
{
var editKernelDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
editKernelDecoratorStyle.Add(Border.PaddingProperty, LineEditResourceKey.PaddingSM);
smallStyle.Add(editKernelDecoratorStyle);
}
{
var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart),
selector.Nesting().Template().Name(RightAddOnPart)));
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.PaddingSM);
smallStyle.Add(addOnStyle);
}
{
// 左右 AddOn icon 的大小
var addOnContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart).Descendant().OfType<PathIcon>(),
selector.Nesting().Template().Name(RightAddOnPart).Descendant().OfType<PathIcon>()));
addOnContentIconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSizeSM);
addOnContentIconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSizeSM);
smallStyle.Add(addOnContentIconStyle);
}
smallStyle.Add(LineEdit.FontSizeProperty, LineEditResourceKey.InputFontSizeSM);
smallStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeightSM);
smallStyle.Add(LineEdit.CornerRadiusProperty, GlobalResourceKey.BorderRadiusSM);
commonStyle.Add(smallStyle);
Add(commonStyle);
}
private void BuildOutLineStyle()
{
var outlineStyle =
new Style(selector => selector.Nesting()
.PropertyEquals(LineEdit.StyleVariantProperty, TextBoxVariant.Outline));
{
var editKernelDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
editKernelDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorBorder);
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
hoverStyle.Add(Border.BorderBrushProperty, LineEditResourceKey.HoverBorderColor);
editKernelDecoratorStyle.Add(hoverStyle);
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
focusStyle.Add(Border.BorderBrushProperty, LineEditResourceKey.ActiveBorderColor);
editKernelDecoratorStyle.Add(focusStyle);
outlineStyle.Add(editKernelDecoratorStyle);
}
{
var errorStyle = new Style(selector => selector.Nesting().Class(LineEdit.ErrorPC));
{
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorError);
errorStyle.Add(innerContentIconStyle);
}
var editKernelDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
editKernelDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
hoverStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorErrorBorderHover);
editKernelDecoratorStyle.Add(hoverStyle);
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
editKernelDecoratorStyle.Add(focusStyle);
errorStyle.Add(editKernelDecoratorStyle);
outlineStyle.Add(errorStyle);
}
{
var warningStyle = new Style(selector => selector.Nesting().Class(LineEdit.WarningPC));
{
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorWarning);
warningStyle.Add(innerContentIconStyle);
}
var editKernelDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
editKernelDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
hoverStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarningBorderHover);
editKernelDecoratorStyle.Add(hoverStyle);
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
editKernelDecoratorStyle.Add(focusStyle);
warningStyle.Add(editKernelDecoratorStyle);
outlineStyle.Add(warningStyle);
}
Add(outlineStyle);
}
private void BuildBorderlessStyle()
{
var borderlessStyle =
new Style(selector => selector.Nesting()
.PropertyEquals(LineEdit.StyleVariantProperty, TextBoxVariant.Borderless));
{
var errorStyle = new Style(selector => selector.Nesting().Class(LineEdit.ErrorPC));
{
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorError);
errorStyle.Add(innerContentIconStyle);
}
var scrollViewerStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart)
.Descendant().OfType<ScrollViewer>());
scrollViewerStyle.Add(ScrollViewer.ForegroundProperty, GlobalResourceKey.ColorErrorText);
errorStyle.Add(scrollViewerStyle);
borderlessStyle.Add(errorStyle);
}
{
var warningStyle = new Style(selector => selector.Nesting().Class(LineEdit.WarningPC));
{
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorWarning);
warningStyle.Add(innerContentIconStyle);
}
var scrollViewerStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart)
.Descendant().OfType<ScrollViewer>());
scrollViewerStyle.Add(ScrollViewer.ForegroundProperty, GlobalResourceKey.ColorWarningText);
warningStyle.Add(scrollViewerStyle);
borderlessStyle.Add(warningStyle);
}
Add(borderlessStyle);
}
private void BuildFilledStyle()
{
var filledStyle =
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.StyleVariantProperty, TextBoxVariant.Filled));
{
var editKernelDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
editKernelDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorTransparent);
editKernelDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorFillTertiary);
filledStyle.Add(editKernelDecoratorStyle);
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
hoverStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorFillSecondary);
editKernelDecoratorStyle.Add(hoverStyle);
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
focusStyle.Add(Border.BorderBrushProperty, LineEditResourceKey.ActiveBorderColor);
focusStyle.Add(Border.BackgroundProperty, LineEditResourceKey.ActiveBg);
editKernelDecoratorStyle.Add(focusStyle);
filledStyle.Add(editKernelDecoratorStyle);
}
{
var errorStyle = new Style(selector => selector.Nesting().Class(LineEdit.ErrorPC));
{
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorError);
errorStyle.Add(innerContentIconStyle);
}
var editKernelDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
editKernelDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorTransparent);
editKernelDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorErrorBg);
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
hoverStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorErrorBgHover);
editKernelDecoratorStyle.Add(hoverStyle);
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
focusStyle.Add(Border.BackgroundProperty, LineEditResourceKey.ActiveBg);
editKernelDecoratorStyle.Add(focusStyle);
var scrollViewerStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart)
.Class(StdPseudoClass.FocusWithIn)
.Descendant().OfType<ScrollViewer>());
scrollViewerStyle.Add(ScrollViewer.ForegroundProperty, GlobalResourceKey.ColorErrorText);
errorStyle.Add(scrollViewerStyle);
errorStyle.Add(editKernelDecoratorStyle);
filledStyle.Add(errorStyle);
}
{
var warningStyle = new Style(selector => selector.Nesting().Class(LineEdit.WarningPC));
{
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorWarning);
warningStyle.Add(innerContentIconStyle);
}
var editKernelDecoratorStyle =
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
editKernelDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorTransparent);
editKernelDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorWarningBg);
warningStyle.Add(editKernelDecoratorStyle);
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
hoverStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorWarningBgHover);
editKernelDecoratorStyle.Add(hoverStyle);
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
focusStyle.Add(Border.BackgroundProperty, LineEditResourceKey.ActiveBg);
{
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorWarning);
focusStyle.Add(innerContentIconStyle);
}
editKernelDecoratorStyle.Add(focusStyle);
var scrollViewerStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart)
.Descendant().OfType<ScrollViewer>());
scrollViewerStyle.Add(ScrollViewer.ForegroundProperty, GlobalResourceKey.ColorWarningText);
warningStyle.Add(scrollViewerStyle);
warningStyle.Add(editKernelDecoratorStyle);
filledStyle.Add(warningStyle);
}
Add(filledStyle);
}
private void BuildDisabledStyle()
{
var disabledStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled));
disabledStyle.Add(LineEdit.ForegroundProperty, GlobalResourceKey.ColorTextDisabled);
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
decoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorBgContainerDisabled);
disabledStyle.Add(decoratorStyle);
// TODO 暂时这么简单处理吧
var addOnStyle = new Style(selector => selector.Nesting().Template().OfType<ContentPresenter>());
addOnStyle.Add(ContentPresenter.ForegroundProperty, GlobalResourceKey.ColorTextDisabled);
disabledStyle.Add(addOnStyle);
Add(disabledStyle);
}
}

View File

@ -1,53 +1,53 @@
using Avalonia;
namespace AtomUI.Controls;
public enum SearchEditButtonStyle
{
Default,
Primary
}
public class SearchEdit : LineEdit
{
#region
public static readonly StyledProperty<SearchEditButtonStyle> SearchButtonStyleProperty =
AvaloniaProperty.Register<SearchEdit, SearchEditButtonStyle>(nameof(SearchButtonStyle), SearchEditButtonStyle.Default);
public static readonly StyledProperty<string> SearchButtonTextProperty =
AvaloniaProperty.Register<SearchEdit, string>(nameof(SearchButtonText));
public SearchEditButtonStyle SearchButtonStyle
{
get => GetValue(SearchButtonStyleProperty);
set => SetValue(SearchButtonStyleProperty, value);
}
public object? SearchButtonText
{
get => GetValue(SearchButtonTextProperty);
set => SetValue(SearchButtonTextProperty, value);
}
#endregion
private Rect? _originRect;
protected override void NotifyAddOnBorderInfoCalculated()
{
RightAddOnBorderThickness = BorderThickness;
}
protected override Size ArrangeOverride(Size finalSize)
{
var size = base.ArrangeOverride(finalSize);
if (_originRect is null) {
_originRect = _rightAddOnPresenter?.Bounds;
}
if (_rightAddOnPresenter is not null && _originRect.HasValue) {
_rightAddOnPresenter.Arrange(_originRect.Value.Inflate(new Thickness(1, 0, 0, 0)));
}
return size;
}
}
// using Avalonia;
//
// namespace AtomUI.Controls;
//
// public enum SearchEditButtonStyle
// {
// Default,
// Primary
// }
//
// public class SearchEdit : LineEdit
// {
// #region 公共属性定
//
// public static readonly StyledProperty<SearchEditButtonStyle> SearchButtonStyleProperty =
// AvaloniaProperty.Register<SearchEdit, SearchEditButtonStyle>(nameof(SearchButtonStyle), SearchEditButtonStyle.Default);
//
// public static readonly StyledProperty<string> SearchButtonTextProperty =
// AvaloniaProperty.Register<SearchEdit, string>(nameof(SearchButtonText));
//
// public SearchEditButtonStyle SearchButtonStyle
// {
// get => GetValue(SearchButtonStyleProperty);
// set => SetValue(SearchButtonStyleProperty, value);
// }
//
// public object? SearchButtonText
// {
// get => GetValue(SearchButtonTextProperty);
// set => SetValue(SearchButtonTextProperty, value);
// }
// #endregion
//
// private Rect? _originRect;
//
// protected override void NotifyAddOnBorderInfoCalculated()
// {
// RightAddOnBorderThickness = BorderThickness;
// }
//
// protected override Size ArrangeOverride(Size finalSize)
// {
// var size = base.ArrangeOverride(finalSize);
// if (_originRect is null) {
// _originRect = _rightAddOnPresenter?.Bounds;
// }
// if (_rightAddOnPresenter is not null && _originRect.HasValue) {
// _rightAddOnPresenter.Arrange(_originRect.Value.Inflate(new Thickness(1, 0, 0, 0)));
// }
//
// return size;
// }
// }

View File

@ -5,81 +5,81 @@ using Avalonia.Controls.Templates;
using Avalonia.Styling;
namespace AtomUI.Controls;
[ControlThemeProvider]
internal class SearchEditTheme : LineEditTheme
{
public SearchEditTheme() : base(typeof(SearchEdit)) { }
protected override void BuildRightAddOn(Grid layout, INameScope scope)
{
var searchIcon = new PathIcon()
{
Kind = "SearchOutlined"
};
TokenResourceBinder.CreateGlobalTokenBinding(searchIcon, PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorIcon);
var rightAddOnContentPresenter = new Button()
{
Name = RightAddOnPart,
Focusable = false,
Icon = searchIcon
};
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.ContentProperty,
SearchEdit.RightAddOnProperty);
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.BorderThicknessProperty,
SearchEdit.RightAddOnBorderThicknessProperty);
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.CornerRadiusProperty,
SearchEdit.RightAddOnCornerRadiusProperty);
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.TextProperty,
SearchEdit.SearchButtonTextProperty);
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.SizeTypeProperty,
SearchEdit.SizeTypeProperty);
rightAddOnContentPresenter.RegisterInNameScope(scope);
layout.Children.Add(rightAddOnContentPresenter);
Grid.SetColumn(rightAddOnContentPresenter, 2);
}
protected override void BuildStyles()
{
base.BuildStyles();
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
decoratorStyle.Add(Border.ZIndexProperty, NormalZIndex);
Add(decoratorStyle);
var decoratorHoverOrFocusStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LineEditKernelDecoratorPart).Class(StdPseudoClass.FocusWithIn),
selector.Nesting().Template().Name(LineEditKernelDecoratorPart).Class(StdPseudoClass.PointerOver)));
decoratorHoverOrFocusStyle.Add(Border.ZIndexProperty, ActivatedZIndex);
Add(decoratorHoverOrFocusStyle);
var searchButtonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
searchButtonStyle.Add(Border.ZIndexProperty, NormalZIndex);
Add(searchButtonStyle);
var searchButtonStyleHoverOrFocusStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(RightAddOnPart).Class(StdPseudoClass.Pressed),
selector.Nesting().Template().Name(RightAddOnPart).Class(StdPseudoClass.PointerOver)));
searchButtonStyleHoverOrFocusStyle.Add(Border.ZIndexProperty, ActivatedZIndex);
Add(searchButtonStyleHoverOrFocusStyle);
// Icon button
var iconSearchButtonStyle = new Style(selector => selector.Nesting().PropertyEquals(SearchEdit.SearchButtonStyleProperty, SearchEditButtonStyle.Default));
{
var buttonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
buttonStyle.Add(Button.IsIconVisibleProperty, true);
buttonStyle.Add(Button.ButtonTypeProperty, ButtonType.Default);
iconSearchButtonStyle.Add(buttonStyle);
}
Add(iconSearchButtonStyle);
// primary button
var primarySearchButtonStyle = new Style(selector => selector.Nesting().PropertyEquals(SearchEdit.SearchButtonStyleProperty, SearchEditButtonStyle.Primary));
{
var buttonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
buttonStyle.Add(Button.IsIconVisibleProperty, false);
buttonStyle.Add(Button.ButtonTypeProperty, ButtonType.Primary);
primarySearchButtonStyle.Add(buttonStyle);
}
Add(primarySearchButtonStyle);
}
}
//
// [ControlThemeProvider]
// internal class SearchEditTheme : LineEditTheme
// {
// public SearchEditTheme() : base(typeof(SearchEdit)) { }
//
// protected override void BuildRightAddOn(Grid layout, INameScope scope)
// {
// var searchIcon = new PathIcon()
// {
// Kind = "SearchOutlined"
// };
// TokenResourceBinder.CreateGlobalTokenBinding(searchIcon, PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorIcon);
// var rightAddOnContentPresenter = new Button()
// {
// Name = RightAddOnPart,
// Focusable = false,
// Icon = searchIcon
// };
// CreateTemplateParentBinding(rightAddOnContentPresenter, Button.ContentProperty,
// SearchEdit.RightAddOnProperty);
// CreateTemplateParentBinding(rightAddOnContentPresenter, Button.BorderThicknessProperty,
// SearchEdit.RightAddOnBorderThicknessProperty);
// CreateTemplateParentBinding(rightAddOnContentPresenter, Button.CornerRadiusProperty,
// SearchEdit.RightAddOnCornerRadiusProperty);
// CreateTemplateParentBinding(rightAddOnContentPresenter, Button.TextProperty,
// SearchEdit.SearchButtonTextProperty);
// CreateTemplateParentBinding(rightAddOnContentPresenter, Button.SizeTypeProperty,
// SearchEdit.SizeTypeProperty);
//
// rightAddOnContentPresenter.RegisterInNameScope(scope);
// layout.Children.Add(rightAddOnContentPresenter);
// Grid.SetColumn(rightAddOnContentPresenter, 2);
// }
//
// protected override void BuildStyles()
// {
// base.BuildStyles();
//
// var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
// decoratorStyle.Add(Border.ZIndexProperty, NormalZIndex);
// Add(decoratorStyle);
//
// var decoratorHoverOrFocusStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LineEditKernelDecoratorPart).Class(StdPseudoClass.FocusWithIn),
// selector.Nesting().Template().Name(LineEditKernelDecoratorPart).Class(StdPseudoClass.PointerOver)));
// decoratorHoverOrFocusStyle.Add(Border.ZIndexProperty, ActivatedZIndex);
// Add(decoratorHoverOrFocusStyle);
//
// var searchButtonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
// searchButtonStyle.Add(Border.ZIndexProperty, NormalZIndex);
// Add(searchButtonStyle);
//
// var searchButtonStyleHoverOrFocusStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(RightAddOnPart).Class(StdPseudoClass.Pressed),
// selector.Nesting().Template().Name(RightAddOnPart).Class(StdPseudoClass.PointerOver)));
// searchButtonStyleHoverOrFocusStyle.Add(Border.ZIndexProperty, ActivatedZIndex);
// Add(searchButtonStyleHoverOrFocusStyle);
//
// // Icon button
// var iconSearchButtonStyle = new Style(selector => selector.Nesting().PropertyEquals(SearchEdit.SearchButtonStyleProperty, SearchEditButtonStyle.Default));
// {
// var buttonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
// buttonStyle.Add(Button.IsIconVisibleProperty, true);
// buttonStyle.Add(Button.ButtonTypeProperty, ButtonType.Default);
// iconSearchButtonStyle.Add(buttonStyle);
// }
// Add(iconSearchButtonStyle);
//
// // primary button
// var primarySearchButtonStyle = new Style(selector => selector.Nesting().PropertyEquals(SearchEdit.SearchButtonStyleProperty, SearchEditButtonStyle.Primary));
// {
// var buttonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
// buttonStyle.Add(Button.IsIconVisibleProperty, false);
// buttonStyle.Add(Button.ButtonTypeProperty, ButtonType.Primary);
// primarySearchButtonStyle.Add(buttonStyle);
// }
// Add(primarySearchButtonStyle);
// }
// }

View File

@ -2,9 +2,9 @@
using AtomUI.Theme.Styling;
namespace AtomUI.Controls;
[ControlThemeProvider]
internal class NumericUpDownTheme : BaseControlTheme
{
}
//
// [ControlThemeProvider]
// internal class NumericUpDownTheme : BaseControlTheme
// {
//
// }