重构 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

@ -11,26 +11,29 @@
<showcase:ShowCaseItem <showcase:ShowCaseItem
Title="Basic usage" Title="Basic usage"
Description="Basic usage example."> Description="Basic usage example.">
<atom:LineEdit Watermark="Basic usage"/> <atom:LineEdit Watermark="Basic usage" />
</showcase:ShowCaseItem> </showcase:ShowCaseItem>
<showcase:ShowCaseItem <showcase:ShowCaseItem
Title="Three sizes of Input" Title="Three sizes of Input"
Description="There are three sizes of an Input box: large (40px), default (32px) and small (24px)."> 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"> <StackPanel Orientation="Vertical" Spacing="10" Margin="0, 0, 20, 0">
<atom:LineEdit Watermark="Large" SizeType="Large" InnerLeftContent="{atom:IconProvider Kind=UserOutlined}"/> <atom:LineEdit Watermark="Large" SizeType="Large"
<atom:LineEdit Watermark="Middle" SizeType="Middle" InnerLeftContent="{atom:IconProvider Kind=UserOutlined}"/> InnerLeftContent="{atom:IconProvider Kind=UserOutlined}" />
<atom:LineEdit Watermark="Small" SizeType="Small" InnerLeftContent="{atom:IconProvider Kind=UserOutlined}"/> <atom:LineEdit Watermark="Middle" SizeType="Middle"
</StackPanel> InnerLeftContent="{atom:IconProvider Kind=UserOutlined}" />
<atom:LineEdit Watermark="Small" SizeType="Small"
InnerLeftContent="{atom:IconProvider Kind=UserOutlined}" />
</StackPanel>
</showcase:ShowCaseItem> </showcase:ShowCaseItem>
<showcase:ShowCaseItem <showcase:ShowCaseItem
Title="Variants" Title="Variants"
Description="Variants of Input."> Description="Variants of Input.">
<StackPanel Orientation="Vertical" Spacing="10"> <StackPanel Orientation="Vertical" Spacing="10">
<atom:LineEdit Watermark="Outlined" StyleVariant="Outline"/> <atom:LineEdit Watermark="Outlined" StyleVariant="Outline" />
<atom:LineEdit Watermark="Filled" StyleVariant="Filled"/> <atom:LineEdit Watermark="Filled" StyleVariant="Filled" />
<atom:LineEdit Watermark="Borderless" StyleVariant="Borderless"/> <atom:LineEdit Watermark="Borderless" StyleVariant="Borderless" />
</StackPanel> </StackPanel>
</showcase:ShowCaseItem> </showcase:ShowCaseItem>
@ -60,13 +63,13 @@
Description="Input type of password."> Description="Input type of password.">
<StackPanel Orientation="Vertical" Spacing="10"> <StackPanel Orientation="Vertical" Spacing="10">
<atom:LineEdit Watermark="input password" <atom:LineEdit Watermark="input password"
Width="400" Width="400"
PasswordChar="*" PasswordChar="*"
RevealPassword="False" RevealPassword="False"
HorizontalAlignment="Left" HorizontalAlignment="Left"
IsEnableRevealButton="True"/> IsEnableRevealButton="True"/>
<atom:LineEdit Watermark="input password" <atom:LineEdit Watermark="input password"
Width="400" Width="400"
PasswordChar="*" PasswordChar="*"
RevealPassword="False" RevealPassword="False"
HorizontalAlignment="Left" HorizontalAlignment="Left"
@ -95,42 +98,42 @@
<atom:LineEdit Watermark="Warning" Status="Warning"/> <atom:LineEdit Watermark="Warning" Status="Warning"/>
<atom:LineEdit Watermark="Error with prefix" InnerLeftContent="{atom:IconProvider Kind=ClockCircleOutlined}" Status="Error"/> <atom:LineEdit Watermark="Error with prefix" InnerLeftContent="{atom:IconProvider Kind=ClockCircleOutlined}" Status="Error"/>
<atom:LineEdit Watermark="Warning with prefix" InnerLeftContent="{atom:IconProvider Kind=ClockCircleOutlined}" Status="Warning"/> <atom:LineEdit Watermark="Warning with prefix" InnerLeftContent="{atom:IconProvider Kind=ClockCircleOutlined}" Status="Warning"/>
<atom:LineEdit Watermark="Error" Status="Error" InnerLeftContent="{atom:IconProvider Kind=ClockCircleOutlined}" StyleVariant="Filled"/> <atom:LineEdit Watermark="Error" Status="Error" InnerLeftContent="{atom:IconProvider Kind=ClockCircleOutlined}" StyleVariant="Filled"/>
<atom:LineEdit Watermark="Warning" Status="Warning" InnerLeftContent="{atom:IconProvider Kind=ClockCircleOutlined}" StyleVariant="Filled"/> <atom:LineEdit Watermark="Warning" Status="Warning" InnerLeftContent="{atom:IconProvider Kind=ClockCircleOutlined}" StyleVariant="Filled"/>
<atom:LineEdit Watermark="Error" Status="Error" InnerLeftContent="{atom:IconProvider Kind=ClockCircleOutlined}" StyleVariant="Borderless"/> <atom:LineEdit Watermark="Error" Status="Error" InnerLeftContent="{atom:IconProvider Kind=ClockCircleOutlined}" StyleVariant="Borderless"/>
<atom:LineEdit Watermark="Warning" Status="Warning" InnerLeftContent="{atom:IconProvider Kind=ClockCircleOutlined}" StyleVariant="Borderless"/> <atom:LineEdit Watermark="Warning" Status="Warning" InnerLeftContent="{atom:IconProvider Kind=ClockCircleOutlined}" StyleVariant="Borderless"/>
</StackPanel> </StackPanel>
</showcase:ShowCaseItem> </showcase:ShowCaseItem>
<showcase:ShowCaseItem <!-- <showcase:ShowCaseItem -->
Title="Search box" <!-- Title="Search box" -->
Description="Example of creating a search box by grouping a standard input with a search button."> <!-- 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"> <!-- <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"/> -->
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonText="Search"/> <!-- <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"/> <!-- <atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonStyle="Primary" SearchButtonText="Search"/> -->
<!-- -->
<atom:SearchEdit Watermark="input search text" <!-- <atom:SearchEdit Watermark="input search text" -->
Width="400" <!-- Width="400" -->
HorizontalAlignment="Left" <!-- HorizontalAlignment="Left" -->
SearchButtonStyle="Primary" <!-- SearchButtonStyle="Primary" -->
SearchButtonText="Search" <!-- SearchButtonText="Search" -->
IsEnableClearButton="True" <!-- IsEnableClearButton="True" -->
SizeType="Large"/> <!-- SizeType="Large"/> -->
<atom:SearchEdit Watermark="input search text" <!-- <atom:SearchEdit Watermark="input search text" -->
Width="400" <!-- Width="400" -->
HorizontalAlignment="Left" <!-- HorizontalAlignment="Left" -->
SearchButtonStyle="Primary" <!-- SearchButtonStyle="Primary" -->
SearchButtonText="搜索一下" <!-- SearchButtonText="搜索一下" -->
InnerRightContent="{atom:IconProvider Kind=AudioOutlined, NormalFilledColor=#1677ff, Width=16, Height=16}" <!-- InnerRightContent="{atom:IconProvider Kind=AudioOutlined, NormalFilledColor=#1677ff, Width=16, Height=16}" -->
IsEnableClearButton="True" <!-- IsEnableClearButton="True" -->
SizeType="Large"/> <!-- SizeType="Large"/> -->
</StackPanel> <!-- </StackPanel> -->
</showcase:ShowCaseItem> <!-- </showcase:ShowCaseItem> -->
</showcase:ShowCasePanel> </showcase:ShowCasePanel>
</UserControl> </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.Theme.Styling;
using AtomUI.Utils; using AtomUI.Utils;
using Avalonia; using Avalonia;
@ -8,7 +9,7 @@ using Avalonia.Controls.Primitives;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Data; using Avalonia.Data;
namespace AtomUI.Controls.AddOnDecoratedBox; namespace AtomUI.Controls;
public enum AddOnDecoratedVariant public enum AddOnDecoratedVariant
{ {
@ -153,7 +154,6 @@ public class AddOnDecoratedBox : ContentControl
protected Control? _leftAddOnPresenter; protected Control? _leftAddOnPresenter;
protected Control? _rightAddOnPresenter; protected Control? _rightAddOnPresenter;
protected Border? _innerBoxDecorator;
static AddOnDecoratedBox() static AddOnDecoratedBox()
{ {
@ -161,6 +161,35 @@ public class AddOnDecoratedBox : ContentControl
AffectsMeasure<AddOnDecoratedBox>(LeftAddOnProperty, RightAddOnProperty); 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) protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{ {
base.OnApplyTemplate(e); base.OnApplyTemplate(e);
@ -169,9 +198,40 @@ public class AddOnDecoratedBox : ContentControl
new RenderScaleAwareThicknessConfigure(this)); new RenderScaleAwareThicknessConfigure(this));
_leftAddOnPresenter = e.NameScope.Find<Control>(AddOnDecoratedBoxTheme.LeftAddOnPart); _leftAddOnPresenter = e.NameScope.Find<Control>(AddOnDecoratedBoxTheme.LeftAddOnPart);
_rightAddOnPresenter = e.NameScope.Find<Control>(AddOnDecoratedBoxTheme.RightAddOnPart); _rightAddOnPresenter = e.NameScope.Find<Control>(AddOnDecoratedBoxTheme.RightAddOnPart);
_innerBoxDecorator = e.NameScope.Find<Border>(AddOnDecoratedBoxTheme.InnerBoxDecoratorPart);
SetupInnerBoxCornerRadius(); 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() private void SetupInnerBoxCornerRadius()
{ {

View File

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

View File

@ -2,7 +2,7 @@
using Avalonia; using Avalonia;
using Avalonia.Media; using Avalonia.Media;
namespace AtomUI.Controls.AddOnDecoratedBox; namespace AtomUI.Controls;
[ControlDesignToken] [ControlDesignToken]
internal class AddOnDecoratedBoxToken : AbstractControlDesignToken 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;
using AtomUI.Theme.Styling;
using AtomUI.Utils;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.Layout;
using Avalonia.Styling;
namespace AtomUI.Controls.AddOnDecoratedBox; namespace AtomUI.Controls;
internal class AddOnDecoratedInnerBoxTheme : BaseControlTheme 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() 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.Controls.Utils;
using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using AtomUI.Utils;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Input; using Avalonia.Input;
namespace AtomUI.Controls; namespace AtomUI.Controls;
public enum TextBoxVariant
{
Outline,
Filled,
Borderless
}
public enum TextBoxStatus
{
Default,
Warning,
Error
}
public class LineEdit : TextBox public class LineEdit : TextBox
{ {
public const string ErrorPC = ":error"; public const string ErrorPC = ":error";
@ -40,11 +22,11 @@ public class LineEdit : TextBox
public static readonly StyledProperty<SizeType> SizeTypeProperty = public static readonly StyledProperty<SizeType> SizeTypeProperty =
AvaloniaProperty.Register<LineEdit, SizeType>(nameof(SizeType), SizeType.Middle); AvaloniaProperty.Register<LineEdit, SizeType>(nameof(SizeType), SizeType.Middle);
public static readonly StyledProperty<TextBoxVariant> StyleVariantProperty = public static readonly StyledProperty<AddOnDecoratedVariant> StyleVariantProperty =
AvaloniaProperty.Register<LineEdit, TextBoxVariant>(nameof(StyleVariant), TextBoxVariant.Outline); AvaloniaProperty.Register<LineEdit, AddOnDecoratedVariant>(nameof(StyleVariant), AddOnDecoratedVariant.Outline);
public static readonly StyledProperty<TextBoxStatus> StatusProperty = public static readonly StyledProperty<AddOnDecoratedStatus> StatusProperty =
AvaloniaProperty.Register<LineEdit, TextBoxStatus>(nameof(Status), TextBoxStatus.Default); AvaloniaProperty.Register<LineEdit, AddOnDecoratedStatus>(nameof(Status), AddOnDecoratedStatus.Default);
public static readonly StyledProperty<bool> IsEnableClearButtonProperty = public static readonly StyledProperty<bool> IsEnableClearButtonProperty =
AvaloniaProperty.Register<LineEdit, bool>(nameof(IsEnableClearButton), false); AvaloniaProperty.Register<LineEdit, bool>(nameof(IsEnableClearButton), false);
@ -70,13 +52,13 @@ public class LineEdit : TextBox
set => SetValue(SizeTypeProperty, value); set => SetValue(SizeTypeProperty, value);
} }
public TextBoxVariant StyleVariant public AddOnDecoratedVariant StyleVariant
{ {
get => GetValue(StyleVariantProperty); get => GetValue(StyleVariantProperty);
set => SetValue(StyleVariantProperty, value); set => SetValue(StyleVariantProperty, value);
} }
public TextBoxStatus Status public AddOnDecoratedStatus Status
{ {
get => GetValue(StatusProperty); get => GetValue(StatusProperty);
set => SetValue(StatusProperty, value); set => SetValue(StatusProperty, value);
@ -97,71 +79,11 @@ public class LineEdit : TextBox
#endregion #endregion
#region #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 = internal static readonly DirectProperty<LineEdit, bool> IsEffectiveShowClearButtonProperty =
AvaloniaProperty.RegisterDirect<LineEdit, bool>(nameof(IsEffectiveShowClearButton), AvaloniaProperty.RegisterDirect<LineEdit, bool>(nameof(IsEffectiveShowClearButton),
o => o.IsEffectiveShowClearButton, o => o.IsEffectiveShowClearButton,
(o, v) => o.IsEffectiveShowClearButton = v); (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; private bool _isEffectiveShowClearButton;
internal bool IsEffectiveShowClearButton internal bool IsEffectiveShowClearButton
@ -172,42 +94,22 @@ public class LineEdit : TextBox
#endregion #endregion
protected Control? _leftAddOnPresenter;
protected Control? _rightAddOnPresenter;
protected Border? _lineEditKernelDecorator;
static LineEdit() static LineEdit()
{ {
AffectsRender<LineEdit>(BorderBrushProperty, BackgroundProperty); AffectsRender<LineEdit>(BorderBrushProperty, BackgroundProperty);
AffectsMeasure<LineEdit>(LeftAddOnProperty, RightAddOnProperty); // AffectsMeasure<LineEdit>(LeftAddOnProperty, RightAddOnProperty);
} }
protected override void OnApplyTemplate(TemplateAppliedEventArgs e) protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{ {
base.OnApplyTemplate(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(); SetupEffectiveShowClearButton();
} }
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{ {
base.OnPropertyChanged(change); 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 || if (change.Property == AcceptsReturnProperty ||
change.Property == IsReadOnlyProperty || change.Property == IsReadOnlyProperty ||
change.Property == TextProperty || change.Property == TextProperty ||
@ -232,82 +134,18 @@ 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) // protected override void OnPointerPressed(PointerPressedEventArgs e)
{ // {
return base.ArrangeOverride(new Size(finalSize.Width - BorderThickness.Left - BorderThickness.Right, finalSize.Height)); // if (_lineEditKernelDecorator is null) {
} // return;
// }
protected override void OnPointerPressed(PointerPressedEventArgs e) // var targetRect = new Rect(_lineEditKernelDecorator.DesiredSize);
{ // if (!targetRect.Contains(e.GetPosition(_lineEditKernelDecorator))) {
if (_lineEditKernelDecorator is null) { // return;
return; // }
} // base.OnPointerPressed(e);
var targetRect = new Rect(_lineEditKernelDecorator.DesiredSize); // }
if (!targetRect.Contains(e.GetPosition(_lineEditKernelDecorator))) {
return;
}
base.OnPointerPressed(e);
}
private void SetupEffectiveShowClearButton() private void SetupEffectiveShowClearButton()
{ {
@ -321,7 +159,7 @@ public class LineEdit : TextBox
private void UpdatePseudoClasses() private void UpdatePseudoClasses()
{ {
PseudoClasses.Set(ErrorPC, Status == TextBoxStatus.Error); PseudoClasses.Set(ErrorPC, Status == AddOnDecoratedStatus.Error);
PseudoClasses.Set(WarningPC, Status == TextBoxStatus.Warning); 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.Data;
using AtomUI.Media;
using AtomUI.Theme; using AtomUI.Theme;
using AtomUI.Theme.Styling; using AtomUI.Theme.Styling;
using AtomUI.Theme.Utils;
using AtomUI.Utils;
using Avalonia.Animation;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Presenters; using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
@ -19,21 +15,11 @@ namespace AtomUI.Controls;
[ControlThemeProvider] [ControlThemeProvider]
internal class LineEditTheme : BaseControlTheme 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 TextPresenterPart = "PART_TextPresenter";
public const string WatermarkPart = "PART_Watermark"; public const string WatermarkPart = "PART_Watermark";
public const string ScrollViewerPart = "PART_ScrollViewer"; 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(Type targetType) : base(targetType) { }
public LineEditTheme() : base(typeof(LineEdit)) { } public LineEditTheme() : base(typeof(LineEdit)) { }
@ -42,162 +28,46 @@ internal class LineEditTheme : BaseControlTheme
{ {
return new FuncControlTemplate<LineEdit>((lineEdit, scope) => return new FuncControlTemplate<LineEdit>((lineEdit, scope) =>
{ {
var mainLayout = new Grid() var decoratedBox = new AddOnDecoratedBox()
{ {
Name = MainLayoutPart, Name = DecoratedBoxPart,
ColumnDefinitions = new ColumnDefinitions() Focusable = true
{
new ColumnDefinition(GridLength.Auto),
new ColumnDefinition(GridLength.Star),
new ColumnDefinition(GridLength.Auto)
}
}; };
BuildGridChildren(lineEdit, mainLayout, scope); CreateTemplateParentBinding(decoratedBox, AddOnDecoratedBox.StyleVariantProperty, LineEdit.StyleVariantProperty);
return mainLayout; 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); var editInnerBox = new LineEditInnerBox(lineEdit)
BuildLineEditKernel(lineEdit, layout, scope);
BuildRightAddOn(layout, scope);
}
protected virtual void BuildLeftAddOn(Grid layout, INameScope scope)
{
var leftAddOnContentPresenter = new ContentPresenter()
{ {
Name = LeftAddOnPart, Name = LineEditInnerBoxPart,
VerticalAlignment = VerticalAlignment.Stretch, Cursor = new Cursor(StandardCursorType.Ibeam),
VerticalContentAlignment = VerticalAlignment.Center, IsRevealButtonVisible = true
HorizontalAlignment = HorizontalAlignment.Left,
Focusable = false
}; };
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.ContentProperty, CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.LeftAddOnContentProperty, LineEdit.InnerLeftContentProperty);
LineEdit.LeftAddOnProperty); CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.RightAddOnContentProperty, LineEdit.InnerRightContentProperty);
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.BorderThicknessProperty, CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.SizeTypeProperty, LineEdit.SizeTypeProperty);
LineEdit.LeftAddOnBorderThicknessProperty); CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.IsClearButtonVisibleProperty, LineEdit.IsEffectiveShowClearButtonProperty);
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.CornerRadiusProperty, CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.IsRevealButtonVisibleProperty, LineEdit.IsEnableRevealButtonProperty);
LineEdit.LeftAddOnCornerRadiusProperty); CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.IsRevealButtonCheckedProperty, LineEdit.RevealPasswordProperty);
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.IsVisibleProperty,
LineEdit.LeftAddOnProperty,
BindingMode.Default, ObjectConverters.IsNotNull);
leftAddOnContentPresenter.RegisterInNameScope(scope);
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 var scrollViewer = new ScrollViewer
{ {
Name = ScrollViewerPart, Name = ScrollViewerPart,
Focusable = true
}; };
// TODO attach 属性不知道怎么指定 Avalonia 控件所在的名称控件,无法用模板绑定的方式进行绑定 // TODO attach 属性不知道怎么指定 Avalonia 控件所在的名称控件,无法用模板绑定的方式进行绑定
BindUtils.RelayBind(lineEdit, ScrollViewer.AllowAutoHideProperty, scrollViewer, BindUtils.RelayBind(lineEdit, ScrollViewer.AllowAutoHideProperty, scrollViewer,
ScrollViewer.AllowAutoHideProperty); ScrollViewer.AllowAutoHideProperty);
@ -207,11 +77,11 @@ internal class LineEditTheme : BaseControlTheme
ScrollViewer.VerticalScrollBarVisibilityProperty); ScrollViewer.VerticalScrollBarVisibilityProperty);
BindUtils.RelayBind(lineEdit, ScrollViewer.VerticalScrollBarVisibilityProperty, scrollViewer, BindUtils.RelayBind(lineEdit, ScrollViewer.VerticalScrollBarVisibilityProperty, scrollViewer,
ScrollViewer.IsScrollChainingEnabledProperty); ScrollViewer.IsScrollChainingEnabledProperty);
scrollViewer.RegisterInNameScope(scope); scrollViewer.RegisterInNameScope(scope);
var textPresenterLayout = new Panel(); var textPresenterLayout = new Panel();
var watermark = new TextBlock var watermark = new TextBlock
{ {
Name = WatermarkPart, Name = WatermarkPart,
@ -226,14 +96,14 @@ internal class LineEditTheme : BaseControlTheme
CreateTemplateParentBinding(watermark, TextBlock.TextWrappingProperty, LineEdit.TextWrappingProperty); CreateTemplateParentBinding(watermark, TextBlock.TextWrappingProperty, LineEdit.TextWrappingProperty);
CreateTemplateParentBinding(watermark, TextBlock.IsVisibleProperty, LineEdit.TextProperty, BindingMode.Default, CreateTemplateParentBinding(watermark, TextBlock.IsVisibleProperty, LineEdit.TextProperty, BindingMode.Default,
StringConverters.IsNullOrEmpty); StringConverters.IsNullOrEmpty);
watermark.RegisterInNameScope(scope); watermark.RegisterInNameScope(scope);
var textPresenter = new TextPresenter var textPresenter = new TextPresenter
{ {
Name = TextPresenterPart, Name = TextPresenterPart
}; };
CreateTemplateParentBinding(textPresenter, TextPresenter.HorizontalAlignmentProperty, CreateTemplateParentBinding(textPresenter, TextPresenter.HorizontalAlignmentProperty,
LineEdit.HorizontalContentAlignmentProperty); LineEdit.HorizontalContentAlignmentProperty);
CreateTemplateParentBinding(textPresenter, TextPresenter.VerticalAlignmentProperty, CreateTemplateParentBinding(textPresenter, TextPresenter.VerticalAlignmentProperty,
@ -253,98 +123,45 @@ internal class LineEditTheme : BaseControlTheme
CreateTemplateParentBinding(textPresenter, TextPresenter.TextProperty, LineEdit.TextProperty, BindingMode.TwoWay); CreateTemplateParentBinding(textPresenter, TextPresenter.TextProperty, LineEdit.TextProperty, BindingMode.TwoWay);
CreateTemplateParentBinding(textPresenter, TextPresenter.TextAlignmentProperty, LineEdit.TextAlignmentProperty); CreateTemplateParentBinding(textPresenter, TextPresenter.TextAlignmentProperty, LineEdit.TextAlignmentProperty);
CreateTemplateParentBinding(textPresenter, TextPresenter.TextWrappingProperty, LineEdit.TextWrappingProperty); CreateTemplateParentBinding(textPresenter, TextPresenter.TextWrappingProperty, LineEdit.TextWrappingProperty);
textPresenterLayout.Children.Add(watermark); textPresenterLayout.Children.Add(watermark);
textPresenterLayout.Children.Add(textPresenter); textPresenterLayout.Children.Add(textPresenter);
textPresenter.RegisterInNameScope(scope); textPresenter.RegisterInNameScope(scope);
scrollViewer.Content = textPresenterLayout; scrollViewer.Content = textPresenterLayout;
layout.TextPresenter = scrollViewer;
} editInnerBox.Content = scrollViewer;
protected virtual void BuildClearButton(LineEditKernel layout, INameScope scope) return editInnerBox;
{
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);
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;
} }
protected override void BuildStyles() protected override void BuildStyles()
{ {
BuildFixedStyle();
BuildCommonStyle(); BuildCommonStyle();
BuildFilledStyle(); BuildFixedStyle();
BuildOutLineStyle();
BuildBorderlessStyle();
BuildDisabledStyle();
} }
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() private void BuildFixedStyle()
{ {
this.Add(LineEdit.SelectionBrushProperty, GlobalResourceKey.SelectionBackground); this.Add(LineEdit.SelectionBrushProperty, GlobalResourceKey.SelectionBackground);
@ -354,366 +171,4 @@ internal class LineEditTheme : BaseControlTheme
this.Add(ScrollViewer.IsScrollChainingEnabledProperty, true); 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; // using Avalonia;
//
namespace AtomUI.Controls; // namespace AtomUI.Controls;
//
public enum SearchEditButtonStyle // public enum SearchEditButtonStyle
{ // {
Default, // Default,
Primary // Primary
} // }
//
public class SearchEdit : LineEdit // public class SearchEdit : LineEdit
{ // {
#region // #region 公共属性定
//
public static readonly StyledProperty<SearchEditButtonStyle> SearchButtonStyleProperty = // public static readonly StyledProperty<SearchEditButtonStyle> SearchButtonStyleProperty =
AvaloniaProperty.Register<SearchEdit, SearchEditButtonStyle>(nameof(SearchButtonStyle), SearchEditButtonStyle.Default); // AvaloniaProperty.Register<SearchEdit, SearchEditButtonStyle>(nameof(SearchButtonStyle), SearchEditButtonStyle.Default);
//
public static readonly StyledProperty<string> SearchButtonTextProperty = // public static readonly StyledProperty<string> SearchButtonTextProperty =
AvaloniaProperty.Register<SearchEdit, string>(nameof(SearchButtonText)); // AvaloniaProperty.Register<SearchEdit, string>(nameof(SearchButtonText));
//
public SearchEditButtonStyle SearchButtonStyle // public SearchEditButtonStyle SearchButtonStyle
{ // {
get => GetValue(SearchButtonStyleProperty); // get => GetValue(SearchButtonStyleProperty);
set => SetValue(SearchButtonStyleProperty, value); // set => SetValue(SearchButtonStyleProperty, value);
} // }
//
public object? SearchButtonText // public object? SearchButtonText
{ // {
get => GetValue(SearchButtonTextProperty); // get => GetValue(SearchButtonTextProperty);
set => SetValue(SearchButtonTextProperty, value); // set => SetValue(SearchButtonTextProperty, value);
} // }
#endregion // #endregion
//
private Rect? _originRect; // private Rect? _originRect;
//
protected override void NotifyAddOnBorderInfoCalculated() // protected override void NotifyAddOnBorderInfoCalculated()
{ // {
RightAddOnBorderThickness = BorderThickness; // RightAddOnBorderThickness = BorderThickness;
} // }
//
protected override Size ArrangeOverride(Size finalSize) // protected override Size ArrangeOverride(Size finalSize)
{ // {
var size = base.ArrangeOverride(finalSize); // var size = base.ArrangeOverride(finalSize);
if (_originRect is null) { // if (_originRect is null) {
_originRect = _rightAddOnPresenter?.Bounds; // _originRect = _rightAddOnPresenter?.Bounds;
} // }
if (_rightAddOnPresenter is not null && _originRect.HasValue) { // if (_rightAddOnPresenter is not null && _originRect.HasValue) {
_rightAddOnPresenter.Arrange(_originRect.Value.Inflate(new Thickness(1, 0, 0, 0))); // _rightAddOnPresenter.Arrange(_originRect.Value.Inflate(new Thickness(1, 0, 0, 0)));
} // }
//
return size; // return size;
} // }
} // }

View File

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

View File

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