mirror of
https://gitee.com/chinware/atomui.git
synced 2024-11-30 02:47:45 +08:00
重构 LineEdit
This commit is contained in:
parent
74aef57895
commit
e794c7b3ce
@ -18,9 +18,12 @@
|
||||
Title="Three sizes of Input"
|
||||
Description="There are three sizes of an Input box: large (40px), default (32px) and small (24px).">
|
||||
<StackPanel Orientation="Vertical" Spacing="10" Margin="0, 0, 20, 0">
|
||||
<atom:LineEdit Watermark="Large" SizeType="Large" InnerLeftContent="{atom:IconProvider Kind=UserOutlined}"/>
|
||||
<atom:LineEdit Watermark="Middle" SizeType="Middle" InnerLeftContent="{atom:IconProvider Kind=UserOutlined}"/>
|
||||
<atom:LineEdit Watermark="Small" SizeType="Small" InnerLeftContent="{atom:IconProvider Kind=UserOutlined}"/>
|
||||
<atom:LineEdit Watermark="Large" SizeType="Large"
|
||||
InnerLeftContent="{atom:IconProvider Kind=UserOutlined}" />
|
||||
<atom:LineEdit Watermark="Middle" SizeType="Middle"
|
||||
InnerLeftContent="{atom:IconProvider Kind=UserOutlined}" />
|
||||
<atom:LineEdit Watermark="Small" SizeType="Small"
|
||||
InnerLeftContent="{atom:IconProvider Kind=UserOutlined}" />
|
||||
</StackPanel>
|
||||
</showcase:ShowCaseItem>
|
||||
|
||||
@ -104,33 +107,33 @@
|
||||
</StackPanel>
|
||||
</showcase:ShowCaseItem>
|
||||
|
||||
<showcase:ShowCaseItem
|
||||
Title="Search box"
|
||||
Description="Example of creating a search box by grouping a standard input with a search button.">
|
||||
<StackPanel Orientation="Vertical" Spacing="10" Margin="0, 0, 20, 0">
|
||||
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left"/>
|
||||
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonText="Search"/>
|
||||
|
||||
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonStyle="Primary" SearchButtonText="Search"/>
|
||||
<atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonStyle="Primary" SearchButtonText="Search"/>
|
||||
|
||||
<atom:SearchEdit Watermark="input search text"
|
||||
Width="400"
|
||||
HorizontalAlignment="Left"
|
||||
SearchButtonStyle="Primary"
|
||||
SearchButtonText="Search"
|
||||
IsEnableClearButton="True"
|
||||
SizeType="Large"/>
|
||||
<atom:SearchEdit Watermark="input search text"
|
||||
Width="400"
|
||||
HorizontalAlignment="Left"
|
||||
SearchButtonStyle="Primary"
|
||||
SearchButtonText="搜索一下"
|
||||
InnerRightContent="{atom:IconProvider Kind=AudioOutlined, NormalFilledColor=#1677ff, Width=16, Height=16}"
|
||||
IsEnableClearButton="True"
|
||||
SizeType="Large"/>
|
||||
</StackPanel>
|
||||
</showcase:ShowCaseItem>
|
||||
<!-- <showcase:ShowCaseItem -->
|
||||
<!-- Title="Search box" -->
|
||||
<!-- Description="Example of creating a search box by grouping a standard input with a search button."> -->
|
||||
<!-- <StackPanel Orientation="Vertical" Spacing="10" Margin="0, 0, 20, 0"> -->
|
||||
<!-- <atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left"/> -->
|
||||
<!-- <atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonText="Search"/> -->
|
||||
<!-- -->
|
||||
<!-- <atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonStyle="Primary" SearchButtonText="Search"/> -->
|
||||
<!-- <atom:SearchEdit Watermark="input search text" Width="400" HorizontalAlignment="Left" SearchButtonStyle="Primary" SearchButtonText="Search"/> -->
|
||||
<!-- -->
|
||||
<!-- <atom:SearchEdit Watermark="input search text" -->
|
||||
<!-- Width="400" -->
|
||||
<!-- HorizontalAlignment="Left" -->
|
||||
<!-- SearchButtonStyle="Primary" -->
|
||||
<!-- SearchButtonText="Search" -->
|
||||
<!-- IsEnableClearButton="True" -->
|
||||
<!-- SizeType="Large"/> -->
|
||||
<!-- <atom:SearchEdit Watermark="input search text" -->
|
||||
<!-- Width="400" -->
|
||||
<!-- HorizontalAlignment="Left" -->
|
||||
<!-- SearchButtonStyle="Primary" -->
|
||||
<!-- SearchButtonText="搜索一下" -->
|
||||
<!-- InnerRightContent="{atom:IconProvider Kind=AudioOutlined, NormalFilledColor=#1677ff, Width=16, Height=16}" -->
|
||||
<!-- IsEnableClearButton="True" -->
|
||||
<!-- SizeType="Large"/> -->
|
||||
<!-- </StackPanel> -->
|
||||
<!-- </showcase:ShowCaseItem> -->
|
||||
|
||||
</showcase:ShowCasePanel>
|
||||
</UserControl>
|
@ -1,4 +1,5 @@
|
||||
using AtomUI.Theme.Data;
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.Theme.Data;
|
||||
using AtomUI.Theme.Styling;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia;
|
||||
@ -8,7 +9,7 @@ using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Data;
|
||||
|
||||
namespace AtomUI.Controls.AddOnDecoratedBox;
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public enum AddOnDecoratedVariant
|
||||
{
|
||||
@ -153,7 +154,6 @@ public class AddOnDecoratedBox : ContentControl
|
||||
|
||||
protected Control? _leftAddOnPresenter;
|
||||
protected Control? _rightAddOnPresenter;
|
||||
protected Border? _innerBoxDecorator;
|
||||
|
||||
static AddOnDecoratedBox()
|
||||
{
|
||||
@ -161,6 +161,35 @@ public class AddOnDecoratedBox : ContentControl
|
||||
AffectsMeasure<AddOnDecoratedBox>(LeftAddOnProperty, RightAddOnProperty);
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
|
||||
if (VisualRoot is not null) {
|
||||
if (change.Property == LeftAddOnProperty || change.Property == RightAddOnProperty) {
|
||||
SetupInnerBoxCornerRadius();
|
||||
}
|
||||
}
|
||||
|
||||
if (change.Property == CornerRadiusProperty || change.Property == BorderThicknessProperty) {
|
||||
SetupAddOnBorderInfo();
|
||||
}
|
||||
|
||||
if (change.Property == StatusProperty) {
|
||||
UpdatePseudoClasses();
|
||||
}
|
||||
|
||||
if (change.Property == LeftAddOnProperty || change.Property == RightAddOnProperty) {
|
||||
if (change.OldValue is Control oldControl) {
|
||||
UIStructureUtils.SetTemplateParent(oldControl, null);
|
||||
}
|
||||
|
||||
if (change.NewValue is Control newControl) {
|
||||
UIStructureUtils.SetTemplateParent(newControl, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
@ -169,10 +198,41 @@ public class AddOnDecoratedBox : ContentControl
|
||||
new RenderScaleAwareThicknessConfigure(this));
|
||||
_leftAddOnPresenter = e.NameScope.Find<Control>(AddOnDecoratedBoxTheme.LeftAddOnPart);
|
||||
_rightAddOnPresenter = e.NameScope.Find<Control>(AddOnDecoratedBoxTheme.RightAddOnPart);
|
||||
_innerBoxDecorator = e.NameScope.Find<Border>(AddOnDecoratedBoxTheme.InnerBoxDecoratorPart);
|
||||
SetupInnerBoxCornerRadius();
|
||||
}
|
||||
|
||||
private void SetupAddOnBorderInfo()
|
||||
{
|
||||
var topLeftRadius = CornerRadius.TopLeft;
|
||||
var topRightRadius = CornerRadius.TopRight;
|
||||
var bottomLeftRadius = CornerRadius.BottomLeft;
|
||||
var bottomRightRadius = CornerRadius.BottomRight;
|
||||
|
||||
var topThickness = BorderThickness.Top;
|
||||
var rightThickness = BorderThickness.Right;
|
||||
var bottomThickness = BorderThickness.Bottom;
|
||||
var leftThickness = BorderThickness.Left;
|
||||
|
||||
LeftAddOnCornerRadius = new CornerRadius(topLeft: topLeftRadius,
|
||||
topRight: 0,
|
||||
bottomLeft:bottomLeftRadius,
|
||||
bottomRight:0);
|
||||
RightAddOnCornerRadius = new CornerRadius(topLeft: 0,
|
||||
topRight: topRightRadius,
|
||||
bottomLeft:0,
|
||||
bottomRight:bottomRightRadius);
|
||||
|
||||
LeftAddOnBorderThickness = new Thickness(top: topThickness, right:0, bottom:bottomThickness, left: leftThickness);
|
||||
RightAddOnBorderThickness = new Thickness(top: topThickness, right:rightThickness, bottom:bottomThickness, left: 0);
|
||||
|
||||
NotifyAddOnBorderInfoCalculated();
|
||||
}
|
||||
|
||||
protected virtual void NotifyAddOnBorderInfoCalculated()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void SetupInnerBoxCornerRadius()
|
||||
{
|
||||
var topLeftRadius = CornerRadius.TopLeft;
|
||||
|
@ -12,12 +12,12 @@ using Avalonia.Data.Converters;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Styling;
|
||||
|
||||
namespace AtomUI.Controls.AddOnDecoratedBox;
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
[ControlThemeProvider]
|
||||
internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
{
|
||||
public const string MainLayoutPart = "PART_FrameDecorator";
|
||||
public const string MainLayoutPart = "PART_MainLayout";
|
||||
public const string LeftAddOnPart = "PART_LeftAddOn";
|
||||
public const string RightAddOnPart = "PART_RightAddOn";
|
||||
public const string InnerBoxContentPart = "PART_InnerBoxContent";
|
||||
@ -26,7 +26,7 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
public const int NormalZIndex = 1000;
|
||||
public const int ActivatedZIndex = 2000;
|
||||
|
||||
public AddOnDecoratedBoxTheme(Type targetType) : base(targetType) { }
|
||||
public AddOnDecoratedBoxTheme() : base(typeof(AddOnDecoratedBox)) { }
|
||||
|
||||
protected override IControlTemplate BuildControlTemplate()
|
||||
{
|
||||
@ -175,14 +175,14 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.PaddingProperty, LineEditResourceKey.PaddingLG);
|
||||
innerBoxDecoratorStyle.Add(Border.PaddingProperty, AddOnDecoratedBoxResourceKey.PaddingLG);
|
||||
largeStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart),
|
||||
selector.Nesting().Template().Name(RightAddOnPart)));
|
||||
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.PaddingLG);
|
||||
addOnStyle.Add(ContentPresenter.PaddingProperty, AddOnDecoratedBoxResourceKey.PaddingLG);
|
||||
largeStyle.Add(addOnStyle);
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
largeStyle.Add(addOnContentIconStyle);
|
||||
}
|
||||
|
||||
largeStyle.Add(AddOnDecoratedBox.FontSizeProperty, LineEditResourceKey.InputFontSizeLG);
|
||||
largeStyle.Add(AddOnDecoratedBox.FontSizeProperty, AddOnDecoratedBoxResourceKey.FontSizeLG);
|
||||
largeStyle.Add(AddOnDecoratedBox.MinHeightProperty, GlobalResourceKey.FontHeightLG);
|
||||
largeStyle.Add(AddOnDecoratedBox.CornerRadiusProperty, GlobalResourceKey.BorderRadiusLG);
|
||||
commonStyle.Add(largeStyle);
|
||||
@ -205,14 +205,14 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.PaddingProperty, LineEditResourceKey.Padding);
|
||||
innerBoxDecoratorStyle.Add(Border.PaddingProperty, AddOnDecoratedBoxResourceKey.Padding);
|
||||
middleStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart),
|
||||
selector.Nesting().Template().Name(RightAddOnPart)));
|
||||
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.Padding);
|
||||
addOnStyle.Add(ContentPresenter.PaddingProperty, AddOnDecoratedBoxResourceKey.Padding);
|
||||
middleStyle.Add(addOnStyle);
|
||||
}
|
||||
|
||||
@ -225,7 +225,7 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
middleStyle.Add(addOnContentIconStyle);
|
||||
}
|
||||
|
||||
middleStyle.Add(AddOnDecoratedBox.FontSizeProperty, LineEditResourceKey.InputFontSize);
|
||||
middleStyle.Add(AddOnDecoratedBox.FontSizeProperty, AddOnDecoratedBoxResourceKey.FontSize);
|
||||
middleStyle.Add(AddOnDecoratedBox.MinHeightProperty, GlobalResourceKey.FontHeight);
|
||||
middleStyle.Add(AddOnDecoratedBox.CornerRadiusProperty, GlobalResourceKey.BorderRadius);
|
||||
commonStyle.Add(middleStyle);
|
||||
@ -235,14 +235,14 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.PaddingProperty, LineEditResourceKey.PaddingSM);
|
||||
innerBoxDecoratorStyle.Add(Border.PaddingProperty, AddOnDecoratedBoxResourceKey.PaddingSM);
|
||||
smallStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart),
|
||||
selector.Nesting().Template().Name(RightAddOnPart)));
|
||||
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.PaddingSM);
|
||||
addOnStyle.Add(ContentPresenter.PaddingProperty, AddOnDecoratedBoxResourceKey.PaddingSM);
|
||||
smallStyle.Add(addOnStyle);
|
||||
}
|
||||
|
||||
@ -255,7 +255,7 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
smallStyle.Add(addOnContentIconStyle);
|
||||
}
|
||||
|
||||
smallStyle.Add(AddOnDecoratedBox.FontSizeProperty, LineEditResourceKey.InputFontSizeSM);
|
||||
smallStyle.Add(AddOnDecoratedBox.FontSizeProperty, AddOnDecoratedBoxResourceKey.FontSizeSM);
|
||||
smallStyle.Add(AddOnDecoratedBox.MinHeightProperty, GlobalResourceKey.FontHeightSM);
|
||||
smallStyle.Add(AddOnDecoratedBox.CornerRadiusProperty, GlobalResourceKey.BorderRadiusSM);
|
||||
commonStyle.Add(smallStyle);
|
||||
@ -267,57 +267,92 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
{
|
||||
var outlineStyle =
|
||||
new Style(selector => selector.Nesting()
|
||||
.PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, TextBoxVariant.Outline));
|
||||
.PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, AddOnDecoratedVariant.Outline));
|
||||
|
||||
{
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorBorder);
|
||||
outlineStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(Border.BorderBrushProperty, LineEditResourceKey.HoverBorderColor);
|
||||
innerBoxDecoratorStyle.Add(hoverStyle);
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, AddOnDecoratedBoxResourceKey.HoverBorderColor);
|
||||
hoverStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
|
||||
outlineStyle.Add(hoverStyle);
|
||||
|
||||
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
|
||||
focusStyle.Add(Border.BorderBrushProperty, LineEditResourceKey.ActiveBorderColor);
|
||||
innerBoxDecoratorStyle.Add(focusStyle);
|
||||
outlineStyle.Add(innerBoxDecoratorStyle);
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, AddOnDecoratedBoxResourceKey.ActiveBorderColor);
|
||||
focusStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
outlineStyle.Add(focusStyle);
|
||||
}
|
||||
{
|
||||
var errorStyle = new Style(selector => selector.Nesting().Class(AddOnDecoratedBox.ErrorPC));
|
||||
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
|
||||
errorStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorErrorBorderHover);
|
||||
innerBoxDecoratorStyle.Add(hoverStyle);
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorErrorBorderHover);
|
||||
hoverStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
errorStyle.Add(hoverStyle);
|
||||
|
||||
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
|
||||
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
|
||||
innerBoxDecoratorStyle.Add(focusStyle);
|
||||
|
||||
errorStyle.Add(innerBoxDecoratorStyle);
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
|
||||
focusStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
errorStyle.Add(focusStyle);
|
||||
outlineStyle.Add(errorStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var warningStyle = new Style(selector => selector.Nesting().Class(AddOnDecoratedBox.WarningPC));
|
||||
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
|
||||
warningStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarningBorderHover);
|
||||
innerBoxDecoratorStyle.Add(hoverStyle);
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarningBorderHover);
|
||||
hoverStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
warningStyle.Add(hoverStyle);
|
||||
|
||||
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
|
||||
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
|
||||
innerBoxDecoratorStyle.Add(focusStyle);
|
||||
|
||||
warningStyle.Add(innerBoxDecoratorStyle);
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
|
||||
focusStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
warningStyle.Add(focusStyle);
|
||||
outlineStyle.Add(warningStyle);
|
||||
}
|
||||
|
||||
@ -328,7 +363,7 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
{
|
||||
var borderlessStyle =
|
||||
new Style(selector => selector.Nesting()
|
||||
.PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, TextBoxVariant.Borderless));
|
||||
.PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, AddOnDecoratedVariant.Borderless));
|
||||
|
||||
{
|
||||
var errorStyle = new Style(selector => selector.Nesting().Class(AddOnDecoratedBox.ErrorPC));
|
||||
@ -354,8 +389,9 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
private void BuildFilledStyle()
|
||||
{
|
||||
var filledStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, TextBoxVariant.Filled));
|
||||
new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedBox.StyleVariantProperty, AddOnDecoratedVariant.Filled));
|
||||
|
||||
{
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
@ -363,36 +399,57 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorTransparent);
|
||||
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorFillTertiary);
|
||||
filledStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorFillSecondary);
|
||||
innerBoxDecoratorStyle.Add(hoverStyle);
|
||||
{
|
||||
var innerBoxDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorFillSecondary);
|
||||
hoverStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
filledStyle.Add(hoverStyle);
|
||||
|
||||
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
|
||||
focusStyle.Add(Border.BorderBrushProperty, LineEditResourceKey.ActiveBorderColor);
|
||||
focusStyle.Add(Border.BackgroundProperty, LineEditResourceKey.ActiveBg);
|
||||
innerBoxDecoratorStyle.Add(focusStyle);
|
||||
filledStyle.Add(innerBoxDecoratorStyle);
|
||||
{
|
||||
var innerBoxDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, AddOnDecoratedBoxResourceKey.ActiveBorderColor);
|
||||
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, AddOnDecoratedBoxResourceKey.ActiveBg);
|
||||
focusStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
filledStyle.Add(focusStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var errorStyle = new Style(selector => selector.Nesting().Class(AddOnDecoratedBox.ErrorPC));
|
||||
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorTransparent);
|
||||
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorErrorBg);
|
||||
errorStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorErrorBgHover);
|
||||
innerBoxDecoratorStyle.Add(hoverStyle);
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorErrorBgHover);
|
||||
hoverStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
errorStyle.Add(hoverStyle);
|
||||
|
||||
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
|
||||
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
|
||||
focusStyle.Add(Border.BackgroundProperty, LineEditResourceKey.ActiveBg);
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
|
||||
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, AddOnDecoratedBoxResourceKey.ActiveBg);
|
||||
focusStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
|
||||
innerBoxDecoratorStyle.Add(focusStyle);
|
||||
errorStyle.Add(focusStyle);
|
||||
|
||||
var scrollViewerStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)
|
||||
.Class(StdPseudoClass.FocusWithIn)
|
||||
@ -401,37 +458,45 @@ internal class AddOnDecoratedBoxTheme : BaseControlTheme
|
||||
|
||||
errorStyle.Add(scrollViewerStyle);
|
||||
|
||||
errorStyle.Add(innerBoxDecoratorStyle);
|
||||
filledStyle.Add(errorStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var warningStyle = new Style(selector => selector.Nesting().Class(AddOnDecoratedBox.WarningPC));
|
||||
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorTransparent);
|
||||
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorWarningBg);
|
||||
warningStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorWarningBgHover);
|
||||
innerBoxDecoratorStyle.Add(hoverStyle);
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorWarningBgHover);
|
||||
hoverStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
warningStyle.Add(hoverStyle);
|
||||
|
||||
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
|
||||
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
|
||||
focusStyle.Add(Border.BackgroundProperty, LineEditResourceKey.ActiveBg);
|
||||
|
||||
innerBoxDecoratorStyle.Add(focusStyle);
|
||||
{
|
||||
var innerBoxDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart));
|
||||
innerBoxDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
|
||||
innerBoxDecoratorStyle.Add(Border.BackgroundProperty, AddOnDecoratedBoxResourceKey.ActiveBg);
|
||||
focusStyle.Add(innerBoxDecoratorStyle);
|
||||
}
|
||||
warningStyle.Add(focusStyle);
|
||||
|
||||
var scrollViewerStyle = new Style(selector => selector.Nesting().Template().Name(InnerBoxDecoratorPart)
|
||||
.Descendant().OfType<ScrollViewer>());
|
||||
scrollViewerStyle.Add(ScrollViewer.ForegroundProperty, GlobalResourceKey.ColorWarningText);
|
||||
|
||||
warningStyle.Add(scrollViewerStyle);
|
||||
|
||||
warningStyle.Add(innerBoxDecoratorStyle);
|
||||
filledStyle.Add(warningStyle);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace AtomUI.Controls.AddOnDecoratedBox;
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
[ControlDesignToken]
|
||||
internal class AddOnDecoratedBoxToken : AbstractControlDesignToken
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -1,20 +1,200 @@
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Styling;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Styling;
|
||||
|
||||
namespace AtomUI.Controls.AddOnDecoratedBox;
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
internal class AddOnDecoratedInnerBoxTheme : BaseControlTheme
|
||||
{
|
||||
protected override IControlTemplate? BuildControlTemplate()
|
||||
public const string MainLayoutPart = "PART_MainLayout";
|
||||
public const string ContentPresenterPart = "PART_ContentPresenter";
|
||||
public const string LeftAddOnPart = "PART_LeftAddOn";
|
||||
public const string RightAddOnPart = "PART_RightAddOn";
|
||||
public const string LeftAddOnLayoutPart = "PART_LeftAddOnLayout";
|
||||
public const string RightAddOnLayoutPart = "PART_RightAddOnLayout";
|
||||
public const string ClearButtonPart = "PART_ClearButton";
|
||||
public const string RevealButtonPart = "PART_RevealButton";
|
||||
|
||||
public AddOnDecoratedInnerBoxTheme(Type targetType) : base(targetType) { }
|
||||
|
||||
protected override IControlTemplate BuildControlTemplate()
|
||||
{
|
||||
return new FuncControlTemplate<AddOnDecoratedInnerBox>((innerBox, scope) =>
|
||||
return new FuncControlTemplate<AddOnDecoratedInnerBox>((decoratedBox, scope) =>
|
||||
{
|
||||
return default!;
|
||||
var mainLayout = new Grid()
|
||||
{
|
||||
Name = MainLayoutPart,
|
||||
ColumnDefinitions = new ColumnDefinitions()
|
||||
{
|
||||
new ColumnDefinition(GridLength.Auto),
|
||||
new ColumnDefinition(GridLength.Star),
|
||||
new ColumnDefinition(GridLength.Auto)
|
||||
}
|
||||
};
|
||||
BuildGridChildren(decoratedBox, mainLayout, scope);
|
||||
return mainLayout;
|
||||
});
|
||||
}
|
||||
|
||||
protected virtual void BuildGridChildren(AddOnDecoratedInnerBox decoratedBox, Grid mainLayout, INameScope scope)
|
||||
{
|
||||
BuildLeftAddOn(mainLayout, scope);
|
||||
BuildContent(decoratedBox, mainLayout, scope);
|
||||
BuildRightAddOn(mainLayout, scope);
|
||||
}
|
||||
|
||||
protected virtual void BuildLeftAddOn(Grid layout, INameScope scope)
|
||||
{
|
||||
// 理论上可以支持多个,暂时先支持一个
|
||||
var addLayout = new StackPanel()
|
||||
{
|
||||
Name = LeftAddOnLayoutPart,
|
||||
Orientation = Orientation.Horizontal,
|
||||
};
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(addLayout, StackPanel.SpacingProperty, GlobalResourceKey.PaddingXXS);
|
||||
addLayout.RegisterInNameScope(scope);
|
||||
|
||||
var leftAddOnContentPresenter = new ContentPresenter()
|
||||
{
|
||||
Name = LeftAddOnPart,
|
||||
VerticalAlignment = VerticalAlignment.Stretch,
|
||||
VerticalContentAlignment = VerticalAlignment.Center,
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
Focusable = false,
|
||||
};
|
||||
|
||||
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.ContentProperty,
|
||||
AddOnDecoratedInnerBox.LeftAddOnContentProperty);
|
||||
leftAddOnContentPresenter.RegisterInNameScope(scope);
|
||||
|
||||
addLayout.Children.Add(leftAddOnContentPresenter);
|
||||
|
||||
Grid.SetColumn(addLayout, 0);
|
||||
layout.Children.Add(addLayout);
|
||||
}
|
||||
|
||||
protected virtual void BuildContent(AddOnDecoratedInnerBox decoratedBox, Grid layout, INameScope scope)
|
||||
{
|
||||
var innerBox = new ContentPresenter()
|
||||
{
|
||||
Name = ContentPresenterPart,
|
||||
};
|
||||
innerBox.RegisterInNameScope(scope);
|
||||
|
||||
CreateTemplateParentBinding(innerBox, ContentPresenter.MarginProperty, AddOnDecoratedInnerBox.ContentPresenterMarginProperty);
|
||||
CreateTemplateParentBinding(innerBox, ContentPresenter.ContentProperty, AddOnDecoratedInnerBox.ContentProperty);
|
||||
CreateTemplateParentBinding(innerBox, ContentPresenter.ContentTemplateProperty,
|
||||
AddOnDecoratedInnerBox.ContentTemplateProperty);
|
||||
|
||||
layout.Children.Add(innerBox);
|
||||
Grid.SetColumn(innerBox, 1);
|
||||
}
|
||||
|
||||
private void BuildRightAddOn(Grid layout, INameScope scope)
|
||||
{
|
||||
var addLayout = new StackPanel()
|
||||
{
|
||||
Name = RightAddOnLayoutPart,
|
||||
Orientation = Orientation.Horizontal
|
||||
};
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(addLayout, StackPanel.SpacingProperty, GlobalResourceKey.PaddingXXS);
|
||||
addLayout.RegisterInNameScope(scope);
|
||||
var rightAddOnContentPresenter = new ContentPresenter()
|
||||
{
|
||||
Name = RightAddOnPart,
|
||||
VerticalAlignment = VerticalAlignment.Stretch,
|
||||
VerticalContentAlignment = VerticalAlignment.Center,
|
||||
HorizontalAlignment = HorizontalAlignment.Right,
|
||||
Focusable = false
|
||||
};
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.ContentProperty,
|
||||
AddOnDecoratedInnerBox.RightAddOnContentProperty);
|
||||
|
||||
rightAddOnContentPresenter.RegisterInNameScope(scope);
|
||||
addLayout.Children.Add(rightAddOnContentPresenter);
|
||||
|
||||
BuildRightAddOnItems(addLayout, scope);
|
||||
|
||||
layout.Children.Add(addLayout);
|
||||
Grid.SetColumn(addLayout, 2);
|
||||
}
|
||||
|
||||
protected virtual void BuildRightAddOnItems(StackPanel layout, INameScope scope)
|
||||
{
|
||||
BuildClearButton(layout, scope);
|
||||
}
|
||||
|
||||
protected virtual void BuildClearButton(StackPanel addOnLayout, INameScope scope)
|
||||
{
|
||||
var closeIcon = new PathIcon()
|
||||
{
|
||||
Kind = "CloseCircleFilled"
|
||||
};
|
||||
var clearButton = new IconButton()
|
||||
{
|
||||
Name = ClearButtonPart,
|
||||
Icon = closeIcon
|
||||
};
|
||||
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.WidthProperty, GlobalResourceKey.IconSize);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.HeightProperty, GlobalResourceKey.IconSize);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.NormalFilledBrushProperty,
|
||||
GlobalResourceKey.ColorTextQuaternary);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.ActiveFilledBrushProperty,
|
||||
GlobalResourceKey.ColorTextTertiary);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.SelectedFilledBrushProperty,
|
||||
GlobalResourceKey.ColorText);
|
||||
|
||||
clearButton.RegisterInNameScope(scope);
|
||||
CreateTemplateParentBinding(clearButton, IconButton.IsVisibleProperty,
|
||||
AddOnDecoratedInnerBox.IsClearButtonVisibleProperty);
|
||||
addOnLayout.Children.Add(clearButton);
|
||||
}
|
||||
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
BuildCommonStyle();
|
||||
}
|
||||
|
||||
private void BuildCommonStyle()
|
||||
{
|
||||
var commonStyle = new Style(selector => selector.Nesting());
|
||||
|
||||
var largeStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.SizeTypeProperty, SizeType.Large));
|
||||
{
|
||||
var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType<PathIcon>());
|
||||
iconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSizeLG);
|
||||
iconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSizeLG);
|
||||
largeStyle.Add(iconStyle);
|
||||
}
|
||||
commonStyle.Add(largeStyle);
|
||||
|
||||
var middleStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.SizeTypeProperty, SizeType.Middle));
|
||||
{
|
||||
var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType<PathIcon>());
|
||||
iconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSize);
|
||||
iconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSize);
|
||||
middleStyle.Add(iconStyle);
|
||||
}
|
||||
commonStyle.Add(middleStyle);
|
||||
|
||||
var smallStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(AddOnDecoratedInnerBox.SizeTypeProperty, SizeType.Small));
|
||||
{
|
||||
var iconStyle = new Style(selector => selector.Nesting().Template().Descendant().OfType<PathIcon>());
|
||||
iconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSizeSM);
|
||||
iconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSizeSM);
|
||||
smallStyle.Add(iconStyle);
|
||||
}
|
||||
commonStyle.Add(smallStyle);
|
||||
|
||||
Add(commonStyle);
|
||||
}
|
||||
}
|
@ -1,29 +1,11 @@
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.Theme.Data;
|
||||
using AtomUI.Theme.Styling;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Input;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public enum TextBoxVariant
|
||||
{
|
||||
Outline,
|
||||
Filled,
|
||||
Borderless
|
||||
}
|
||||
|
||||
public enum TextBoxStatus
|
||||
{
|
||||
Default,
|
||||
Warning,
|
||||
Error
|
||||
}
|
||||
|
||||
public class LineEdit : TextBox
|
||||
{
|
||||
public const string ErrorPC = ":error";
|
||||
@ -40,11 +22,11 @@ public class LineEdit : TextBox
|
||||
public static readonly StyledProperty<SizeType> SizeTypeProperty =
|
||||
AvaloniaProperty.Register<LineEdit, SizeType>(nameof(SizeType), SizeType.Middle);
|
||||
|
||||
public static readonly StyledProperty<TextBoxVariant> StyleVariantProperty =
|
||||
AvaloniaProperty.Register<LineEdit, TextBoxVariant>(nameof(StyleVariant), TextBoxVariant.Outline);
|
||||
public static readonly StyledProperty<AddOnDecoratedVariant> StyleVariantProperty =
|
||||
AvaloniaProperty.Register<LineEdit, AddOnDecoratedVariant>(nameof(StyleVariant), AddOnDecoratedVariant.Outline);
|
||||
|
||||
public static readonly StyledProperty<TextBoxStatus> StatusProperty =
|
||||
AvaloniaProperty.Register<LineEdit, TextBoxStatus>(nameof(Status), TextBoxStatus.Default);
|
||||
public static readonly StyledProperty<AddOnDecoratedStatus> StatusProperty =
|
||||
AvaloniaProperty.Register<LineEdit, AddOnDecoratedStatus>(nameof(Status), AddOnDecoratedStatus.Default);
|
||||
|
||||
public static readonly StyledProperty<bool> IsEnableClearButtonProperty =
|
||||
AvaloniaProperty.Register<LineEdit, bool>(nameof(IsEnableClearButton), false);
|
||||
@ -70,13 +52,13 @@ public class LineEdit : TextBox
|
||||
set => SetValue(SizeTypeProperty, value);
|
||||
}
|
||||
|
||||
public TextBoxVariant StyleVariant
|
||||
public AddOnDecoratedVariant StyleVariant
|
||||
{
|
||||
get => GetValue(StyleVariantProperty);
|
||||
set => SetValue(StyleVariantProperty, value);
|
||||
}
|
||||
|
||||
public TextBoxStatus Status
|
||||
public AddOnDecoratedStatus Status
|
||||
{
|
||||
get => GetValue(StatusProperty);
|
||||
set => SetValue(StatusProperty, value);
|
||||
@ -98,71 +80,11 @@ public class LineEdit : TextBox
|
||||
|
||||
#region 内部属性定义
|
||||
|
||||
internal static readonly DirectProperty<LineEdit, CornerRadius> EditKernelCornerRadiusProperty =
|
||||
AvaloniaProperty.RegisterDirect<LineEdit, CornerRadius>(nameof(EditKernelCornerRadius),
|
||||
o => o.EditKernelCornerRadius,
|
||||
(o, v) => o.EditKernelCornerRadius = v);
|
||||
|
||||
internal static readonly DirectProperty<LineEdit, CornerRadius> LeftAddOnCornerRadiusProperty =
|
||||
AvaloniaProperty.RegisterDirect<LineEdit, CornerRadius>(nameof(LeftAddOnCornerRadius),
|
||||
o => o.LeftAddOnCornerRadius,
|
||||
(o, v) => o.LeftAddOnCornerRadius = v);
|
||||
|
||||
internal static readonly DirectProperty<LineEdit, CornerRadius> RightAddOnCornerRadiusProperty =
|
||||
AvaloniaProperty.RegisterDirect<LineEdit, CornerRadius>(nameof(RightAddOnCornerRadius),
|
||||
o => o.RightAddOnCornerRadius,
|
||||
(o, v) => o.RightAddOnCornerRadius = v);
|
||||
|
||||
internal static readonly DirectProperty<LineEdit, Thickness> LeftAddOnBorderThicknessProperty =
|
||||
AvaloniaProperty.RegisterDirect<LineEdit, Thickness>(nameof(LeftAddOnBorderThickness),
|
||||
o => o.LeftAddOnBorderThickness,
|
||||
(o, v) => o.LeftAddOnBorderThickness = v);
|
||||
|
||||
internal static readonly DirectProperty<LineEdit, Thickness> RightAddOnBorderThicknessProperty =
|
||||
AvaloniaProperty.RegisterDirect<LineEdit, Thickness>(nameof(RightAddOnBorderThickness),
|
||||
o => o.RightAddOnBorderThickness,
|
||||
(o, v) => o.RightAddOnBorderThickness = v);
|
||||
|
||||
internal static readonly DirectProperty<LineEdit, bool> IsEffectiveShowClearButtonProperty =
|
||||
AvaloniaProperty.RegisterDirect<LineEdit, bool>(nameof(IsEffectiveShowClearButton),
|
||||
o => o.IsEffectiveShowClearButton,
|
||||
(o, v) => o.IsEffectiveShowClearButton = v);
|
||||
|
||||
private CornerRadius _editKernelCornerRadius;
|
||||
internal CornerRadius EditKernelCornerRadius
|
||||
{
|
||||
get => _editKernelCornerRadius;
|
||||
set => SetAndRaise(EditKernelCornerRadiusProperty, ref _editKernelCornerRadius, value);
|
||||
}
|
||||
|
||||
private CornerRadius _leftAddOnCornerRadius;
|
||||
internal CornerRadius LeftAddOnCornerRadius
|
||||
{
|
||||
get => _leftAddOnCornerRadius;
|
||||
set => SetAndRaise(LeftAddOnCornerRadiusProperty, ref _leftAddOnCornerRadius, value);
|
||||
}
|
||||
|
||||
private CornerRadius _rightAddOnCornerRadius;
|
||||
internal CornerRadius RightAddOnCornerRadius
|
||||
{
|
||||
get => _rightAddOnCornerRadius;
|
||||
set => SetAndRaise(RightAddOnCornerRadiusProperty, ref _rightAddOnCornerRadius, value);
|
||||
}
|
||||
|
||||
private Thickness _leftAddOnBorderThickness;
|
||||
internal Thickness LeftAddOnBorderThickness
|
||||
{
|
||||
get => _leftAddOnBorderThickness;
|
||||
set => SetAndRaise(LeftAddOnBorderThicknessProperty, ref _leftAddOnBorderThickness, value);
|
||||
}
|
||||
|
||||
private Thickness _rightAddOnBorderThickness;
|
||||
internal Thickness RightAddOnBorderThickness
|
||||
{
|
||||
get => _rightAddOnBorderThickness;
|
||||
set => SetAndRaise(RightAddOnBorderThicknessProperty, ref _rightAddOnBorderThickness, value);
|
||||
}
|
||||
|
||||
private bool _isEffectiveShowClearButton;
|
||||
internal bool IsEffectiveShowClearButton
|
||||
{
|
||||
@ -172,25 +94,15 @@ public class LineEdit : TextBox
|
||||
|
||||
#endregion
|
||||
|
||||
protected Control? _leftAddOnPresenter;
|
||||
protected Control? _rightAddOnPresenter;
|
||||
protected Border? _lineEditKernelDecorator;
|
||||
|
||||
static LineEdit()
|
||||
{
|
||||
AffectsRender<LineEdit>(BorderBrushProperty, BackgroundProperty);
|
||||
AffectsMeasure<LineEdit>(LeftAddOnProperty, RightAddOnProperty);
|
||||
// AffectsMeasure<LineEdit>(LeftAddOnProperty, RightAddOnProperty);
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
TokenResourceBinder.CreateGlobalResourceBinding(this, BorderThicknessProperty, GlobalResourceKey.BorderThickness,
|
||||
BindingPriority.Template, new RenderScaleAwareThicknessConfigure(this));
|
||||
_leftAddOnPresenter = e.NameScope.Find<Control>(LineEditTheme.LeftAddOnPart);
|
||||
_rightAddOnPresenter = e.NameScope.Find<Control>(LineEditTheme.RightAddOnPart);
|
||||
_lineEditKernelDecorator = e.NameScope.Find<Border>(LineEditTheme.LineEditKernelDecoratorPart);
|
||||
SetupEditKernelCornerRadius();
|
||||
SetupEffectiveShowClearButton();
|
||||
}
|
||||
|
||||
@ -198,16 +110,6 @@ public class LineEdit : TextBox
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
|
||||
if (VisualRoot is not null) {
|
||||
if (change.Property == LeftAddOnProperty || change.Property == RightAddOnProperty) {
|
||||
SetupEditKernelCornerRadius();
|
||||
}
|
||||
}
|
||||
|
||||
if (change.Property == CornerRadiusProperty || change.Property == BorderThicknessProperty) {
|
||||
SetupAddOnBorderInfo();
|
||||
}
|
||||
|
||||
if (change.Property == AcceptsReturnProperty ||
|
||||
change.Property == IsReadOnlyProperty ||
|
||||
change.Property == TextProperty ||
|
||||
@ -233,81 +135,17 @@ public class LineEdit : TextBox
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupAddOnBorderInfo()
|
||||
{
|
||||
var topLeftRadius = CornerRadius.TopLeft;
|
||||
var topRightRadius = CornerRadius.TopRight;
|
||||
var bottomLeftRadius = CornerRadius.BottomLeft;
|
||||
var bottomRightRadius = CornerRadius.BottomRight;
|
||||
|
||||
var topThickness = BorderThickness.Top;
|
||||
var rightThickness = BorderThickness.Right;
|
||||
var bottomThickness = BorderThickness.Bottom;
|
||||
var leftThickness = BorderThickness.Left;
|
||||
|
||||
LeftAddOnCornerRadius = new CornerRadius(topLeft: topLeftRadius,
|
||||
topRight: 0,
|
||||
bottomLeft:bottomLeftRadius,
|
||||
bottomRight:0);
|
||||
RightAddOnCornerRadius = new CornerRadius(topLeft: 0,
|
||||
topRight: topRightRadius,
|
||||
bottomLeft:0,
|
||||
bottomRight:bottomRightRadius);
|
||||
|
||||
LeftAddOnBorderThickness = new Thickness(top: topThickness, right:0, bottom:bottomThickness, left: leftThickness);
|
||||
RightAddOnBorderThickness = new Thickness(top: topThickness, right:rightThickness, bottom:bottomThickness, left: 0);
|
||||
|
||||
NotifyAddOnBorderInfoCalculated();
|
||||
}
|
||||
|
||||
protected virtual void NotifyAddOnBorderInfoCalculated()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void SetupEditKernelCornerRadius()
|
||||
{
|
||||
var topLeftRadius = CornerRadius.TopLeft;
|
||||
var topRightRadius = CornerRadius.TopRight;
|
||||
var bottomLeftRadius = CornerRadius.BottomLeft;
|
||||
var bottomRightRadius = CornerRadius.BottomRight;
|
||||
|
||||
if (_leftAddOnPresenter is not null && _leftAddOnPresenter.IsVisible) {
|
||||
topLeftRadius = 0;
|
||||
bottomLeftRadius = 0;
|
||||
}
|
||||
if (_rightAddOnPresenter is not null && _rightAddOnPresenter.IsVisible) {
|
||||
topRightRadius = 0;
|
||||
bottomRightRadius = 0;
|
||||
}
|
||||
|
||||
EditKernelCornerRadius = new CornerRadius(topLeft: topLeftRadius,
|
||||
topRight: topRightRadius,
|
||||
bottomLeft:bottomLeftRadius,
|
||||
bottomRight:bottomRightRadius);
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
return base.MeasureOverride(new Size(availableSize.Width - BorderThickness.Left - BorderThickness.Right, availableSize.Height));
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
return base.ArrangeOverride(new Size(finalSize.Width - BorderThickness.Left - BorderThickness.Right, finalSize.Height));
|
||||
}
|
||||
|
||||
protected override void OnPointerPressed(PointerPressedEventArgs e)
|
||||
{
|
||||
if (_lineEditKernelDecorator is null) {
|
||||
return;
|
||||
}
|
||||
var targetRect = new Rect(_lineEditKernelDecorator.DesiredSize);
|
||||
if (!targetRect.Contains(e.GetPosition(_lineEditKernelDecorator))) {
|
||||
return;
|
||||
}
|
||||
base.OnPointerPressed(e);
|
||||
}
|
||||
// protected override void OnPointerPressed(PointerPressedEventArgs e)
|
||||
// {
|
||||
// if (_lineEditKernelDecorator is null) {
|
||||
// return;
|
||||
// }
|
||||
// var targetRect = new Rect(_lineEditKernelDecorator.DesiredSize);
|
||||
// if (!targetRect.Contains(e.GetPosition(_lineEditKernelDecorator))) {
|
||||
// return;
|
||||
// }
|
||||
// base.OnPointerPressed(e);
|
||||
// }
|
||||
|
||||
private void SetupEffectiveShowClearButton()
|
||||
{
|
||||
@ -321,7 +159,7 @@ public class LineEdit : TextBox
|
||||
|
||||
private void UpdatePseudoClasses()
|
||||
{
|
||||
PseudoClasses.Set(ErrorPC, Status == TextBoxStatus.Error);
|
||||
PseudoClasses.Set(WarningPC, Status == TextBoxStatus.Warning);
|
||||
PseudoClasses.Set(ErrorPC, Status == AddOnDecoratedStatus.Error);
|
||||
PseudoClasses.Set(WarningPC, Status == AddOnDecoratedStatus.Warning);
|
||||
}
|
||||
}
|
42
src/AtomUI.Controls/Input/LineEditInnerBox.cs
Normal file
42
src/AtomUI.Controls/Input/LineEditInnerBox.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
60
src/AtomUI.Controls/Input/LineEditInnerBoxTheme.cs
Normal file
60
src/AtomUI.Controls/Input/LineEditInnerBoxTheme.cs
Normal 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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -1,10 +1,6 @@
|
||||
using AtomUI.Data;
|
||||
using AtomUI.Media;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Styling;
|
||||
using AtomUI.Theme.Utils;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia.Animation;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Templates;
|
||||
@ -19,21 +15,11 @@ namespace AtomUI.Controls;
|
||||
[ControlThemeProvider]
|
||||
internal class LineEditTheme : BaseControlTheme
|
||||
{
|
||||
public const string MainLayoutPart = "PART_FrameDecorator";
|
||||
public const string DecoratedBoxPart = "PART_DecoratedBox";
|
||||
public const string LineEditInnerBoxPart = "PART_LineEditInnerBox";
|
||||
public const string TextPresenterPart = "PART_TextPresenter";
|
||||
public const string WatermarkPart = "PART_Watermark";
|
||||
public const string ScrollViewerPart = "PART_ScrollViewer";
|
||||
public const string LeftAddOnPart = "PART_LeftAddOn";
|
||||
public const string RightAddOnPart = "PART_RightAddOn";
|
||||
public const string LeftInnerContentPart = "PART_LeftInnerContent";
|
||||
public const string RightInnerContentPart = "PART_RightInnerContent";
|
||||
public const string ClearButtonPart = "PART_ClearButton";
|
||||
public const string RevealButtonPart = "PART_RevealButton";
|
||||
public const string LineEditKernelPart = "PART_LineEditKernel";
|
||||
public const string LineEditKernelDecoratorPart = "PART_LineEditKernelDecorator";
|
||||
|
||||
public const int NormalZIndex = 1000;
|
||||
public const int ActivatedZIndex = 2000;
|
||||
|
||||
public LineEditTheme(Type targetType) : base(targetType) { }
|
||||
public LineEditTheme() : base(typeof(LineEdit)) { }
|
||||
@ -42,160 +28,44 @@ internal class LineEditTheme : BaseControlTheme
|
||||
{
|
||||
return new FuncControlTemplate<LineEdit>((lineEdit, scope) =>
|
||||
{
|
||||
var mainLayout = new Grid()
|
||||
var decoratedBox = new AddOnDecoratedBox()
|
||||
{
|
||||
Name = MainLayoutPart,
|
||||
ColumnDefinitions = new ColumnDefinitions()
|
||||
{
|
||||
new ColumnDefinition(GridLength.Auto),
|
||||
new ColumnDefinition(GridLength.Star),
|
||||
new ColumnDefinition(GridLength.Auto)
|
||||
}
|
||||
Name = DecoratedBoxPart,
|
||||
Focusable = true
|
||||
};
|
||||
BuildGridChildren(lineEdit, mainLayout, scope);
|
||||
return mainLayout;
|
||||
CreateTemplateParentBinding(decoratedBox, AddOnDecoratedBox.StyleVariantProperty, LineEdit.StyleVariantProperty);
|
||||
CreateTemplateParentBinding(decoratedBox, AddOnDecoratedBox.SizeTypeProperty, LineEdit.SizeTypeProperty);
|
||||
CreateTemplateParentBinding(decoratedBox, AddOnDecoratedBox.StatusProperty, LineEdit.StatusProperty);
|
||||
CreateTemplateParentBinding(decoratedBox, AddOnDecoratedBox.LeftAddOnProperty, LineEdit.LeftAddOnProperty);
|
||||
CreateTemplateParentBinding(decoratedBox, AddOnDecoratedBox.RightAddOnProperty, LineEdit.RightAddOnProperty);
|
||||
decoratedBox.RegisterInNameScope(scope);
|
||||
var lineEditKernel = BuildLineEditKernel(lineEdit, scope);
|
||||
decoratedBox.Content = lineEditKernel;
|
||||
lineEditKernel.RegisterInNameScope(scope);
|
||||
return decoratedBox;
|
||||
});
|
||||
}
|
||||
|
||||
protected virtual void BuildGridChildren(LineEdit lineEdit, Grid layout, INameScope scope)
|
||||
protected virtual LineEditInnerBox BuildLineEditKernel(LineEdit lineEdit, INameScope scope)
|
||||
{
|
||||
BuildLeftAddOn(layout, scope);
|
||||
BuildLineEditKernel(lineEdit, layout, scope);
|
||||
BuildRightAddOn(layout, scope);
|
||||
}
|
||||
|
||||
protected virtual void BuildLeftAddOn(Grid layout, INameScope scope)
|
||||
var editInnerBox = new LineEditInnerBox(lineEdit)
|
||||
{
|
||||
var leftAddOnContentPresenter = new ContentPresenter()
|
||||
{
|
||||
Name = LeftAddOnPart,
|
||||
VerticalAlignment = VerticalAlignment.Stretch,
|
||||
VerticalContentAlignment = VerticalAlignment.Center,
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
Focusable = false
|
||||
Name = LineEditInnerBoxPart,
|
||||
Cursor = new Cursor(StandardCursorType.Ibeam),
|
||||
IsRevealButtonVisible = true
|
||||
};
|
||||
|
||||
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.ContentProperty,
|
||||
LineEdit.LeftAddOnProperty);
|
||||
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.BorderThicknessProperty,
|
||||
LineEdit.LeftAddOnBorderThicknessProperty);
|
||||
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.CornerRadiusProperty,
|
||||
LineEdit.LeftAddOnCornerRadiusProperty);
|
||||
CreateTemplateParentBinding(leftAddOnContentPresenter, ContentPresenter.IsVisibleProperty,
|
||||
LineEdit.LeftAddOnProperty,
|
||||
BindingMode.Default, ObjectConverters.IsNotNull);
|
||||
leftAddOnContentPresenter.RegisterInNameScope(scope);
|
||||
CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.LeftAddOnContentProperty, LineEdit.InnerLeftContentProperty);
|
||||
CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.RightAddOnContentProperty, LineEdit.InnerRightContentProperty);
|
||||
CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.SizeTypeProperty, LineEdit.SizeTypeProperty);
|
||||
CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.IsClearButtonVisibleProperty, LineEdit.IsEffectiveShowClearButtonProperty);
|
||||
CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.IsRevealButtonVisibleProperty, LineEdit.IsEnableRevealButtonProperty);
|
||||
CreateTemplateParentBinding(editInnerBox, LineEditInnerBox.IsRevealButtonCheckedProperty, LineEdit.RevealPasswordProperty);
|
||||
|
||||
TokenResourceBinder.CreateTokenBinding(leftAddOnContentPresenter, ContentPresenter.BackgroundProperty,
|
||||
LineEditResourceKey.AddonBg);
|
||||
TokenResourceBinder.CreateTokenBinding(leftAddOnContentPresenter, ContentPresenter.BorderBrushProperty,
|
||||
GlobalResourceKey.ColorBorder);
|
||||
|
||||
Grid.SetColumn(leftAddOnContentPresenter, 0);
|
||||
layout.Children.Add(leftAddOnContentPresenter);
|
||||
}
|
||||
|
||||
protected virtual void BuildLineEditKernel(LineEdit lineEdit, Grid layout, INameScope scope)
|
||||
{
|
||||
var kernelDecorator = new Border()
|
||||
{
|
||||
Name = LineEditKernelDecoratorPart,
|
||||
Transitions = new Transitions()
|
||||
{
|
||||
AnimationUtils.CreateTransition<SolidColorBrushTransition>(Border.BorderBrushProperty),
|
||||
AnimationUtils.CreateTransition<SolidColorBrushTransition>(Border.BackgroundProperty)
|
||||
}
|
||||
};
|
||||
|
||||
kernelDecorator.RegisterInNameScope(scope);
|
||||
|
||||
var kernelLayout = new LineEditKernel()
|
||||
{
|
||||
Name = LineEditKernelPart,
|
||||
Cursor = new Cursor(StandardCursorType.Ibeam)
|
||||
};
|
||||
|
||||
CreateTemplateParentBinding(kernelDecorator, Border.BorderThicknessProperty, LineEdit.BorderThicknessProperty);
|
||||
CreateTemplateParentBinding(kernelDecorator, Border.CornerRadiusProperty,
|
||||
LineEdit.EditKernelCornerRadiusProperty);
|
||||
|
||||
BuildInnerLeftContent(kernelLayout, scope);
|
||||
BuildTextPresenter(lineEdit, kernelLayout, scope);
|
||||
BuildClearButton(kernelLayout, scope);
|
||||
BuildRevealButton(kernelLayout, scope);
|
||||
BuildInnerRightContent(kernelLayout, scope);
|
||||
|
||||
kernelDecorator.Child = kernelLayout;
|
||||
layout.Children.Add(kernelDecorator);
|
||||
Grid.SetColumn(kernelDecorator, 1);
|
||||
}
|
||||
|
||||
protected virtual void BuildRightAddOn(Grid layout, INameScope scope)
|
||||
{
|
||||
var rightAddOnContentPresenter = new ContentPresenter()
|
||||
{
|
||||
Name = RightAddOnPart,
|
||||
VerticalAlignment = VerticalAlignment.Stretch,
|
||||
VerticalContentAlignment = VerticalAlignment.Center,
|
||||
HorizontalAlignment = HorizontalAlignment.Right,
|
||||
Focusable = false
|
||||
};
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.ContentProperty,
|
||||
LineEdit.RightAddOnProperty);
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.BorderThicknessProperty,
|
||||
LineEdit.RightAddOnBorderThicknessProperty);
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.CornerRadiusProperty,
|
||||
LineEdit.RightAddOnCornerRadiusProperty);
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, ContentPresenter.IsVisibleProperty,
|
||||
LineEdit.RightAddOnProperty,
|
||||
BindingMode.Default, ObjectConverters.IsNotNull);
|
||||
|
||||
TokenResourceBinder.CreateTokenBinding(rightAddOnContentPresenter, ContentPresenter.BackgroundProperty,
|
||||
LineEditResourceKey.AddonBg);
|
||||
TokenResourceBinder.CreateTokenBinding(rightAddOnContentPresenter, ContentPresenter.BorderBrushProperty,
|
||||
GlobalResourceKey.ColorBorder);
|
||||
|
||||
rightAddOnContentPresenter.RegisterInNameScope(scope);
|
||||
layout.Children.Add(rightAddOnContentPresenter);
|
||||
Grid.SetColumn(rightAddOnContentPresenter, 2);
|
||||
}
|
||||
|
||||
protected virtual void BuildInnerLeftContent(LineEditKernel layout, INameScope scope)
|
||||
{
|
||||
var innerLeftContentPresenter = new ContentPresenter()
|
||||
{
|
||||
Name = LeftInnerContentPart,
|
||||
VerticalAlignment = VerticalAlignment.Center
|
||||
};
|
||||
CreateTemplateParentBinding(innerLeftContentPresenter, ContentPresenter.IsVisibleProperty,
|
||||
LineEdit.InnerLeftContentProperty,
|
||||
BindingMode.Default, ObjectConverters.IsNotNull);
|
||||
CreateTemplateParentBinding(innerLeftContentPresenter, ContentPresenter.ContentProperty,
|
||||
LineEdit.InnerLeftContentProperty);
|
||||
innerLeftContentPresenter.RegisterInNameScope(scope);
|
||||
layout.LeftInnerContent = innerLeftContentPresenter;
|
||||
}
|
||||
|
||||
protected virtual void BuildInnerRightContent(LineEditKernel layout, INameScope scope)
|
||||
{
|
||||
var innerRightContentPresenter = new ContentPresenter()
|
||||
{
|
||||
Name = RightInnerContentPart
|
||||
};
|
||||
CreateTemplateParentBinding(innerRightContentPresenter, ContentPresenter.IsVisibleProperty,
|
||||
LineEdit.InnerRightContentProperty,
|
||||
BindingMode.Default, ObjectConverters.IsNotNull);
|
||||
CreateTemplateParentBinding(innerRightContentPresenter, ContentPresenter.ContentProperty,
|
||||
LineEdit.InnerRightContentProperty);
|
||||
innerRightContentPresenter.RegisterInNameScope(scope);
|
||||
layout.RightInnerContent = innerRightContentPresenter;
|
||||
}
|
||||
|
||||
protected virtual void BuildTextPresenter(LineEdit lineEdit, LineEditKernel layout, INameScope scope)
|
||||
{
|
||||
var scrollViewer = new ScrollViewer
|
||||
{
|
||||
Name = ScrollViewerPart,
|
||||
Focusable = true
|
||||
};
|
||||
|
||||
// TODO attach 属性不知道怎么指定 Avalonia 控件所在的名称控件,无法用模板绑定的方式进行绑定
|
||||
@ -231,7 +101,7 @@ internal class LineEditTheme : BaseControlTheme
|
||||
|
||||
var textPresenter = new TextPresenter
|
||||
{
|
||||
Name = TextPresenterPart,
|
||||
Name = TextPresenterPart
|
||||
};
|
||||
|
||||
CreateTemplateParentBinding(textPresenter, TextPresenter.HorizontalAlignmentProperty,
|
||||
@ -259,90 +129,37 @@ internal class LineEditTheme : BaseControlTheme
|
||||
|
||||
textPresenter.RegisterInNameScope(scope);
|
||||
scrollViewer.Content = textPresenterLayout;
|
||||
layout.TextPresenter = scrollViewer;
|
||||
}
|
||||
|
||||
protected virtual void BuildClearButton(LineEditKernel layout, INameScope scope)
|
||||
{
|
||||
var closeIcon = new PathIcon()
|
||||
{
|
||||
Kind = "CloseCircleFilled"
|
||||
};
|
||||
var clearButton = new IconButton()
|
||||
{
|
||||
Name = ClearButtonPart,
|
||||
Icon = closeIcon
|
||||
};
|
||||
editInnerBox.Content = scrollViewer;
|
||||
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.WidthProperty, GlobalResourceKey.IconSize);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.HeightProperty, GlobalResourceKey.IconSize);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.NormalFilledBrushProperty,
|
||||
GlobalResourceKey.ColorTextQuaternary);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.ActiveFilledBrushProperty,
|
||||
GlobalResourceKey.ColorTextTertiary);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(closeIcon, PathIcon.SelectedFilledBrushProperty,
|
||||
GlobalResourceKey.ColorText);
|
||||
CreateTemplateParentBinding(clearButton, IconButton.CommandProperty, nameof(LineEdit.Clear));
|
||||
|
||||
clearButton.RegisterInNameScope(scope);
|
||||
CreateTemplateParentBinding(clearButton, IconButton.IsVisibleProperty,
|
||||
LineEdit.IsEffectiveShowClearButtonProperty);
|
||||
layout.ClearButton = clearButton;
|
||||
}
|
||||
|
||||
protected virtual void BuildRevealButton(LineEditKernel layout, INameScope scope)
|
||||
{
|
||||
var checkedIcon = new PathIcon()
|
||||
{
|
||||
Kind = "EyeTwoTone"
|
||||
};
|
||||
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(checkedIcon, PathIcon.WidthProperty, GlobalResourceKey.IconSize);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(checkedIcon, PathIcon.HeightProperty, GlobalResourceKey.IconSize);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(checkedIcon, PathIcon.PrimaryFilledBrushProperty,
|
||||
LineEditResourceKey.ActiveBorderColor);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(checkedIcon, PathIcon.SecondaryFilledBrushProperty,
|
||||
GlobalResourceKey.ColorPrimaryBgHover);
|
||||
|
||||
var unCheckedIcon = new PathIcon()
|
||||
{
|
||||
Kind = "EyeInvisibleOutlined"
|
||||
};
|
||||
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.WidthProperty, GlobalResourceKey.IconSize);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.HeightProperty, GlobalResourceKey.IconSize);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.NormalFilledBrushProperty,
|
||||
GlobalResourceKey.ColorTextQuaternary);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.ActiveFilledBrushProperty,
|
||||
GlobalResourceKey.ColorTextTertiary);
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(unCheckedIcon, PathIcon.SelectedFilledBrushProperty,
|
||||
GlobalResourceKey.ColorText);
|
||||
|
||||
var revealButton = new ToggleIconButton()
|
||||
{
|
||||
Name = RevealButtonPart,
|
||||
CheckedIcon = checkedIcon,
|
||||
UnCheckedIcon = unCheckedIcon
|
||||
};
|
||||
|
||||
revealButton.RegisterInNameScope(scope);
|
||||
|
||||
CreateTemplateParentBinding(revealButton, ToggleIconButton.IsVisibleProperty,
|
||||
LineEdit.IsEnableRevealButtonProperty);
|
||||
CreateTemplateParentBinding(revealButton, ToggleIconButton.IsCheckedProperty, LineEdit.RevealPasswordProperty,
|
||||
BindingMode.TwoWay);
|
||||
|
||||
layout.RevealButton = revealButton;
|
||||
return editInnerBox;
|
||||
}
|
||||
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
BuildFixedStyle();
|
||||
BuildCommonStyle();
|
||||
BuildFilledStyle();
|
||||
BuildOutLineStyle();
|
||||
BuildBorderlessStyle();
|
||||
BuildDisabledStyle();
|
||||
BuildFixedStyle();
|
||||
}
|
||||
|
||||
private void BuildCommonStyle()
|
||||
{
|
||||
var commonStyle = new Style(selector => selector.Nesting());
|
||||
var largeStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.SizeTypeProperty, SizeType.Large));
|
||||
largeStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeightLG);
|
||||
commonStyle.Add(largeStyle);
|
||||
|
||||
var middleStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.SizeTypeProperty, SizeType.Middle));
|
||||
middleStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeight);
|
||||
commonStyle.Add(middleStyle);
|
||||
|
||||
var smallStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.SizeTypeProperty, SizeType.Small));
|
||||
smallStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeightSM);
|
||||
commonStyle.Add(smallStyle);
|
||||
|
||||
Add(commonStyle);
|
||||
}
|
||||
|
||||
private void BuildFixedStyle()
|
||||
@ -354,366 +171,4 @@ internal class LineEditTheme : BaseControlTheme
|
||||
this.Add(ScrollViewer.IsScrollChainingEnabledProperty, true);
|
||||
}
|
||||
|
||||
private void BuildCommonStyle()
|
||||
{
|
||||
var commonStyle = new Style(selector => selector.Nesting());
|
||||
commonStyle.Add(LineEdit.ForegroundProperty, GlobalResourceKey.ColorText);
|
||||
|
||||
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
decoratorStyle.Add(Border.ZIndexProperty, NormalZIndex);
|
||||
commonStyle.Add(decoratorStyle);
|
||||
|
||||
// 输入框左右小组件的 margin 设置
|
||||
var leftInnerContentStyle = new Style(selector => selector.Nesting().Template().Name(LeftInnerContentPart));
|
||||
leftInnerContentStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.LeftInnerAddOnMargin);
|
||||
commonStyle.Add(leftInnerContentStyle);
|
||||
|
||||
var rightInnerContentStyle = new Style(selector => selector.Nesting().Template().Name(RightInnerContentPart));
|
||||
rightInnerContentStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.RightInnerAddOnMargin);
|
||||
commonStyle.Add(rightInnerContentStyle);
|
||||
|
||||
var clearButtonStyle = new Style(selector => selector.Nesting().Template().Name(ClearButtonPart));
|
||||
clearButtonStyle.Add(IconButton.PaddingProperty, LineEditResourceKey.RightInnerAddOnMargin);
|
||||
commonStyle.Add(clearButtonStyle);
|
||||
|
||||
var revealButtonStyle = new Style(selector => selector.Nesting().Template().Name(RevealButtonPart));
|
||||
revealButtonStyle.Add(ToggleIconButton.PaddingProperty, LineEditResourceKey.RightInnerAddOnMargin);
|
||||
commonStyle.Add(revealButtonStyle);
|
||||
|
||||
{
|
||||
// 左右 inner icon 的大小
|
||||
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
|
||||
innerContentIconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSize);
|
||||
innerContentIconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSize);
|
||||
commonStyle.Add(innerContentIconStyle);
|
||||
}
|
||||
|
||||
var largeStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.SizeTypeProperty, SizeType.Large));
|
||||
{
|
||||
var editKernelDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
editKernelDecoratorStyle.Add(Border.PaddingProperty, LineEditResourceKey.PaddingLG);
|
||||
largeStyle.Add(editKernelDecoratorStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart),
|
||||
selector.Nesting().Template().Name(RightAddOnPart)));
|
||||
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.PaddingLG);
|
||||
largeStyle.Add(addOnStyle);
|
||||
}
|
||||
|
||||
{
|
||||
// 左右 AddOn icon 的大小
|
||||
var addOnContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightAddOnPart).Descendant().OfType<PathIcon>()));
|
||||
addOnContentIconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSizeLG);
|
||||
addOnContentIconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSizeLG);
|
||||
largeStyle.Add(addOnContentIconStyle);
|
||||
}
|
||||
|
||||
largeStyle.Add(LineEdit.FontSizeProperty, LineEditResourceKey.InputFontSizeLG);
|
||||
largeStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeightLG);
|
||||
largeStyle.Add(LineEdit.CornerRadiusProperty, GlobalResourceKey.BorderRadiusLG);
|
||||
commonStyle.Add(largeStyle);
|
||||
|
||||
var middleStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.SizeTypeProperty, SizeType.Middle));
|
||||
{
|
||||
var editKernelDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
editKernelDecoratorStyle.Add(Border.PaddingProperty, LineEditResourceKey.Padding);
|
||||
middleStyle.Add(editKernelDecoratorStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart),
|
||||
selector.Nesting().Template().Name(RightAddOnPart)));
|
||||
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.Padding);
|
||||
middleStyle.Add(addOnStyle);
|
||||
}
|
||||
|
||||
{
|
||||
// 左右 AddOn icon 的大小
|
||||
var addOnContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightAddOnPart).Descendant().OfType<PathIcon>()));
|
||||
addOnContentIconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSize);
|
||||
addOnContentIconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSize);
|
||||
middleStyle.Add(addOnContentIconStyle);
|
||||
}
|
||||
|
||||
middleStyle.Add(LineEdit.FontSizeProperty, LineEditResourceKey.InputFontSize);
|
||||
middleStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeight);
|
||||
middleStyle.Add(LineEdit.CornerRadiusProperty, GlobalResourceKey.BorderRadius);
|
||||
commonStyle.Add(middleStyle);
|
||||
|
||||
var smallStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.SizeTypeProperty, SizeType.Small));
|
||||
{
|
||||
var editKernelDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
editKernelDecoratorStyle.Add(Border.PaddingProperty, LineEditResourceKey.PaddingSM);
|
||||
smallStyle.Add(editKernelDecoratorStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var addOnStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart),
|
||||
selector.Nesting().Template().Name(RightAddOnPart)));
|
||||
addOnStyle.Add(ContentPresenter.PaddingProperty, LineEditResourceKey.PaddingSM);
|
||||
smallStyle.Add(addOnStyle);
|
||||
}
|
||||
|
||||
{
|
||||
// 左右 AddOn icon 的大小
|
||||
var addOnContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftAddOnPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightAddOnPart).Descendant().OfType<PathIcon>()));
|
||||
addOnContentIconStyle.Add(PathIcon.WidthProperty, GlobalResourceKey.IconSizeSM);
|
||||
addOnContentIconStyle.Add(PathIcon.HeightProperty, GlobalResourceKey.IconSizeSM);
|
||||
smallStyle.Add(addOnContentIconStyle);
|
||||
}
|
||||
|
||||
smallStyle.Add(LineEdit.FontSizeProperty, LineEditResourceKey.InputFontSizeSM);
|
||||
smallStyle.Add(LineEdit.LineHeightProperty, GlobalResourceKey.FontHeightSM);
|
||||
smallStyle.Add(LineEdit.CornerRadiusProperty, GlobalResourceKey.BorderRadiusSM);
|
||||
commonStyle.Add(smallStyle);
|
||||
|
||||
Add(commonStyle);
|
||||
}
|
||||
|
||||
private void BuildOutLineStyle()
|
||||
{
|
||||
var outlineStyle =
|
||||
new Style(selector => selector.Nesting()
|
||||
.PropertyEquals(LineEdit.StyleVariantProperty, TextBoxVariant.Outline));
|
||||
|
||||
{
|
||||
var editKernelDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
editKernelDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorBorder);
|
||||
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(Border.BorderBrushProperty, LineEditResourceKey.HoverBorderColor);
|
||||
editKernelDecoratorStyle.Add(hoverStyle);
|
||||
|
||||
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
|
||||
focusStyle.Add(Border.BorderBrushProperty, LineEditResourceKey.ActiveBorderColor);
|
||||
editKernelDecoratorStyle.Add(focusStyle);
|
||||
outlineStyle.Add(editKernelDecoratorStyle);
|
||||
}
|
||||
{
|
||||
var errorStyle = new Style(selector => selector.Nesting().Class(LineEdit.ErrorPC));
|
||||
{
|
||||
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
|
||||
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorError);
|
||||
errorStyle.Add(innerContentIconStyle);
|
||||
}
|
||||
|
||||
var editKernelDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
editKernelDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
|
||||
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorErrorBorderHover);
|
||||
editKernelDecoratorStyle.Add(hoverStyle);
|
||||
|
||||
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
|
||||
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
|
||||
editKernelDecoratorStyle.Add(focusStyle);
|
||||
|
||||
errorStyle.Add(editKernelDecoratorStyle);
|
||||
outlineStyle.Add(errorStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var warningStyle = new Style(selector => selector.Nesting().Class(LineEdit.WarningPC));
|
||||
|
||||
{
|
||||
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
|
||||
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorWarning);
|
||||
warningStyle.Add(innerContentIconStyle);
|
||||
}
|
||||
|
||||
var editKernelDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
editKernelDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
|
||||
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarningBorderHover);
|
||||
editKernelDecoratorStyle.Add(hoverStyle);
|
||||
|
||||
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
|
||||
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
|
||||
editKernelDecoratorStyle.Add(focusStyle);
|
||||
|
||||
warningStyle.Add(editKernelDecoratorStyle);
|
||||
outlineStyle.Add(warningStyle);
|
||||
}
|
||||
|
||||
Add(outlineStyle);
|
||||
}
|
||||
|
||||
private void BuildBorderlessStyle()
|
||||
{
|
||||
var borderlessStyle =
|
||||
new Style(selector => selector.Nesting()
|
||||
.PropertyEquals(LineEdit.StyleVariantProperty, TextBoxVariant.Borderless));
|
||||
|
||||
{
|
||||
var errorStyle = new Style(selector => selector.Nesting().Class(LineEdit.ErrorPC));
|
||||
{
|
||||
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
|
||||
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorError);
|
||||
errorStyle.Add(innerContentIconStyle);
|
||||
}
|
||||
var scrollViewerStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart)
|
||||
.Descendant().OfType<ScrollViewer>());
|
||||
scrollViewerStyle.Add(ScrollViewer.ForegroundProperty, GlobalResourceKey.ColorErrorText);
|
||||
errorStyle.Add(scrollViewerStyle);
|
||||
borderlessStyle.Add(errorStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var warningStyle = new Style(selector => selector.Nesting().Class(LineEdit.WarningPC));
|
||||
{
|
||||
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
|
||||
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorWarning);
|
||||
warningStyle.Add(innerContentIconStyle);
|
||||
}
|
||||
var scrollViewerStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart)
|
||||
.Descendant().OfType<ScrollViewer>());
|
||||
scrollViewerStyle.Add(ScrollViewer.ForegroundProperty, GlobalResourceKey.ColorWarningText);
|
||||
warningStyle.Add(scrollViewerStyle);
|
||||
borderlessStyle.Add(warningStyle);
|
||||
}
|
||||
|
||||
Add(borderlessStyle);
|
||||
}
|
||||
|
||||
private void BuildFilledStyle()
|
||||
{
|
||||
var filledStyle =
|
||||
new Style(selector => selector.Nesting().PropertyEquals(LineEdit.StyleVariantProperty, TextBoxVariant.Filled));
|
||||
|
||||
{
|
||||
var editKernelDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
|
||||
editKernelDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorTransparent);
|
||||
editKernelDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorFillTertiary);
|
||||
filledStyle.Add(editKernelDecoratorStyle);
|
||||
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorFillSecondary);
|
||||
editKernelDecoratorStyle.Add(hoverStyle);
|
||||
|
||||
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
|
||||
focusStyle.Add(Border.BorderBrushProperty, LineEditResourceKey.ActiveBorderColor);
|
||||
focusStyle.Add(Border.BackgroundProperty, LineEditResourceKey.ActiveBg);
|
||||
editKernelDecoratorStyle.Add(focusStyle);
|
||||
filledStyle.Add(editKernelDecoratorStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var errorStyle = new Style(selector => selector.Nesting().Class(LineEdit.ErrorPC));
|
||||
|
||||
{
|
||||
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
|
||||
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorError);
|
||||
errorStyle.Add(innerContentIconStyle);
|
||||
}
|
||||
|
||||
var editKernelDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
|
||||
editKernelDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorTransparent);
|
||||
editKernelDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorErrorBg);
|
||||
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorErrorBgHover);
|
||||
editKernelDecoratorStyle.Add(hoverStyle);
|
||||
|
||||
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
|
||||
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorError);
|
||||
focusStyle.Add(Border.BackgroundProperty, LineEditResourceKey.ActiveBg);
|
||||
|
||||
editKernelDecoratorStyle.Add(focusStyle);
|
||||
|
||||
var scrollViewerStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart)
|
||||
.Class(StdPseudoClass.FocusWithIn)
|
||||
.Descendant().OfType<ScrollViewer>());
|
||||
scrollViewerStyle.Add(ScrollViewer.ForegroundProperty, GlobalResourceKey.ColorErrorText);
|
||||
|
||||
errorStyle.Add(scrollViewerStyle);
|
||||
|
||||
errorStyle.Add(editKernelDecoratorStyle);
|
||||
filledStyle.Add(errorStyle);
|
||||
}
|
||||
|
||||
{
|
||||
var warningStyle = new Style(selector => selector.Nesting().Class(LineEdit.WarningPC));
|
||||
|
||||
{
|
||||
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
|
||||
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorWarning);
|
||||
warningStyle.Add(innerContentIconStyle);
|
||||
}
|
||||
|
||||
var editKernelDecoratorStyle =
|
||||
new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
|
||||
editKernelDecoratorStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorTransparent);
|
||||
editKernelDecoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorWarningBg);
|
||||
warningStyle.Add(editKernelDecoratorStyle);
|
||||
|
||||
var hoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver));
|
||||
hoverStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorWarningBgHover);
|
||||
editKernelDecoratorStyle.Add(hoverStyle);
|
||||
|
||||
var focusStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.FocusWithIn));
|
||||
focusStyle.Add(Border.BorderBrushProperty, GlobalResourceKey.ColorWarning);
|
||||
focusStyle.Add(Border.BackgroundProperty, LineEditResourceKey.ActiveBg);
|
||||
|
||||
{
|
||||
var innerContentIconStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LeftInnerContentPart).Descendant().OfType<PathIcon>(),
|
||||
selector.Nesting().Template().Name(RightInnerContentPart).Descendant().OfType<PathIcon>()));
|
||||
innerContentIconStyle.Add(PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorWarning);
|
||||
focusStyle.Add(innerContentIconStyle);
|
||||
}
|
||||
|
||||
editKernelDecoratorStyle.Add(focusStyle);
|
||||
|
||||
var scrollViewerStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart)
|
||||
.Descendant().OfType<ScrollViewer>());
|
||||
scrollViewerStyle.Add(ScrollViewer.ForegroundProperty, GlobalResourceKey.ColorWarningText);
|
||||
|
||||
warningStyle.Add(scrollViewerStyle);
|
||||
|
||||
warningStyle.Add(editKernelDecoratorStyle);
|
||||
filledStyle.Add(warningStyle);
|
||||
}
|
||||
|
||||
Add(filledStyle);
|
||||
}
|
||||
|
||||
private void BuildDisabledStyle()
|
||||
{
|
||||
var disabledStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled));
|
||||
disabledStyle.Add(LineEdit.ForegroundProperty, GlobalResourceKey.ColorTextDisabled);
|
||||
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
decoratorStyle.Add(Border.BackgroundProperty, GlobalResourceKey.ColorBgContainerDisabled);
|
||||
disabledStyle.Add(decoratorStyle);
|
||||
// TODO 暂时这么简单处理吧
|
||||
var addOnStyle = new Style(selector => selector.Nesting().Template().OfType<ContentPresenter>());
|
||||
addOnStyle.Add(ContentPresenter.ForegroundProperty, GlobalResourceKey.ColorTextDisabled);
|
||||
disabledStyle.Add(addOnStyle);
|
||||
Add(disabledStyle);
|
||||
}
|
||||
}
|
@ -1,53 +1,53 @@
|
||||
using Avalonia;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public enum SearchEditButtonStyle
|
||||
{
|
||||
Default,
|
||||
Primary
|
||||
}
|
||||
|
||||
public class SearchEdit : LineEdit
|
||||
{
|
||||
#region 公共属性定义
|
||||
|
||||
public static readonly StyledProperty<SearchEditButtonStyle> SearchButtonStyleProperty =
|
||||
AvaloniaProperty.Register<SearchEdit, SearchEditButtonStyle>(nameof(SearchButtonStyle), SearchEditButtonStyle.Default);
|
||||
|
||||
public static readonly StyledProperty<string> SearchButtonTextProperty =
|
||||
AvaloniaProperty.Register<SearchEdit, string>(nameof(SearchButtonText));
|
||||
|
||||
public SearchEditButtonStyle SearchButtonStyle
|
||||
{
|
||||
get => GetValue(SearchButtonStyleProperty);
|
||||
set => SetValue(SearchButtonStyleProperty, value);
|
||||
}
|
||||
|
||||
public object? SearchButtonText
|
||||
{
|
||||
get => GetValue(SearchButtonTextProperty);
|
||||
set => SetValue(SearchButtonTextProperty, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
private Rect? _originRect;
|
||||
|
||||
protected override void NotifyAddOnBorderInfoCalculated()
|
||||
{
|
||||
RightAddOnBorderThickness = BorderThickness;
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
var size = base.ArrangeOverride(finalSize);
|
||||
if (_originRect is null) {
|
||||
_originRect = _rightAddOnPresenter?.Bounds;
|
||||
}
|
||||
if (_rightAddOnPresenter is not null && _originRect.HasValue) {
|
||||
_rightAddOnPresenter.Arrange(_originRect.Value.Inflate(new Thickness(1, 0, 0, 0)));
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
}
|
||||
// using Avalonia;
|
||||
//
|
||||
// namespace AtomUI.Controls;
|
||||
//
|
||||
// public enum SearchEditButtonStyle
|
||||
// {
|
||||
// Default,
|
||||
// Primary
|
||||
// }
|
||||
//
|
||||
// public class SearchEdit : LineEdit
|
||||
// {
|
||||
// #region 公共属性定义
|
||||
//
|
||||
// public static readonly StyledProperty<SearchEditButtonStyle> SearchButtonStyleProperty =
|
||||
// AvaloniaProperty.Register<SearchEdit, SearchEditButtonStyle>(nameof(SearchButtonStyle), SearchEditButtonStyle.Default);
|
||||
//
|
||||
// public static readonly StyledProperty<string> SearchButtonTextProperty =
|
||||
// AvaloniaProperty.Register<SearchEdit, string>(nameof(SearchButtonText));
|
||||
//
|
||||
// public SearchEditButtonStyle SearchButtonStyle
|
||||
// {
|
||||
// get => GetValue(SearchButtonStyleProperty);
|
||||
// set => SetValue(SearchButtonStyleProperty, value);
|
||||
// }
|
||||
//
|
||||
// public object? SearchButtonText
|
||||
// {
|
||||
// get => GetValue(SearchButtonTextProperty);
|
||||
// set => SetValue(SearchButtonTextProperty, value);
|
||||
// }
|
||||
// #endregion
|
||||
//
|
||||
// private Rect? _originRect;
|
||||
//
|
||||
// protected override void NotifyAddOnBorderInfoCalculated()
|
||||
// {
|
||||
// RightAddOnBorderThickness = BorderThickness;
|
||||
// }
|
||||
//
|
||||
// protected override Size ArrangeOverride(Size finalSize)
|
||||
// {
|
||||
// var size = base.ArrangeOverride(finalSize);
|
||||
// if (_originRect is null) {
|
||||
// _originRect = _rightAddOnPresenter?.Bounds;
|
||||
// }
|
||||
// if (_rightAddOnPresenter is not null && _originRect.HasValue) {
|
||||
// _rightAddOnPresenter.Arrange(_originRect.Value.Inflate(new Thickness(1, 0, 0, 0)));
|
||||
// }
|
||||
//
|
||||
// return size;
|
||||
// }
|
||||
// }
|
@ -5,81 +5,81 @@ using Avalonia.Controls.Templates;
|
||||
using Avalonia.Styling;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
[ControlThemeProvider]
|
||||
internal class SearchEditTheme : LineEditTheme
|
||||
{
|
||||
public SearchEditTheme() : base(typeof(SearchEdit)) { }
|
||||
|
||||
protected override void BuildRightAddOn(Grid layout, INameScope scope)
|
||||
{
|
||||
var searchIcon = new PathIcon()
|
||||
{
|
||||
Kind = "SearchOutlined"
|
||||
};
|
||||
TokenResourceBinder.CreateGlobalTokenBinding(searchIcon, PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorIcon);
|
||||
var rightAddOnContentPresenter = new Button()
|
||||
{
|
||||
Name = RightAddOnPart,
|
||||
Focusable = false,
|
||||
Icon = searchIcon
|
||||
};
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.ContentProperty,
|
||||
SearchEdit.RightAddOnProperty);
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.BorderThicknessProperty,
|
||||
SearchEdit.RightAddOnBorderThicknessProperty);
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.CornerRadiusProperty,
|
||||
SearchEdit.RightAddOnCornerRadiusProperty);
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.TextProperty,
|
||||
SearchEdit.SearchButtonTextProperty);
|
||||
CreateTemplateParentBinding(rightAddOnContentPresenter, Button.SizeTypeProperty,
|
||||
SearchEdit.SizeTypeProperty);
|
||||
|
||||
rightAddOnContentPresenter.RegisterInNameScope(scope);
|
||||
layout.Children.Add(rightAddOnContentPresenter);
|
||||
Grid.SetColumn(rightAddOnContentPresenter, 2);
|
||||
}
|
||||
|
||||
protected override void BuildStyles()
|
||||
{
|
||||
base.BuildStyles();
|
||||
|
||||
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
decoratorStyle.Add(Border.ZIndexProperty, NormalZIndex);
|
||||
Add(decoratorStyle);
|
||||
|
||||
var decoratorHoverOrFocusStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LineEditKernelDecoratorPart).Class(StdPseudoClass.FocusWithIn),
|
||||
selector.Nesting().Template().Name(LineEditKernelDecoratorPart).Class(StdPseudoClass.PointerOver)));
|
||||
decoratorHoverOrFocusStyle.Add(Border.ZIndexProperty, ActivatedZIndex);
|
||||
Add(decoratorHoverOrFocusStyle);
|
||||
|
||||
var searchButtonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
|
||||
searchButtonStyle.Add(Border.ZIndexProperty, NormalZIndex);
|
||||
Add(searchButtonStyle);
|
||||
|
||||
var searchButtonStyleHoverOrFocusStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(RightAddOnPart).Class(StdPseudoClass.Pressed),
|
||||
selector.Nesting().Template().Name(RightAddOnPart).Class(StdPseudoClass.PointerOver)));
|
||||
searchButtonStyleHoverOrFocusStyle.Add(Border.ZIndexProperty, ActivatedZIndex);
|
||||
Add(searchButtonStyleHoverOrFocusStyle);
|
||||
|
||||
// Icon button
|
||||
var iconSearchButtonStyle = new Style(selector => selector.Nesting().PropertyEquals(SearchEdit.SearchButtonStyleProperty, SearchEditButtonStyle.Default));
|
||||
{
|
||||
var buttonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
|
||||
buttonStyle.Add(Button.IsIconVisibleProperty, true);
|
||||
buttonStyle.Add(Button.ButtonTypeProperty, ButtonType.Default);
|
||||
iconSearchButtonStyle.Add(buttonStyle);
|
||||
}
|
||||
Add(iconSearchButtonStyle);
|
||||
|
||||
// primary button
|
||||
var primarySearchButtonStyle = new Style(selector => selector.Nesting().PropertyEquals(SearchEdit.SearchButtonStyleProperty, SearchEditButtonStyle.Primary));
|
||||
{
|
||||
var buttonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
|
||||
buttonStyle.Add(Button.IsIconVisibleProperty, false);
|
||||
buttonStyle.Add(Button.ButtonTypeProperty, ButtonType.Primary);
|
||||
primarySearchButtonStyle.Add(buttonStyle);
|
||||
}
|
||||
Add(primarySearchButtonStyle);
|
||||
}
|
||||
}
|
||||
//
|
||||
// [ControlThemeProvider]
|
||||
// internal class SearchEditTheme : LineEditTheme
|
||||
// {
|
||||
// public SearchEditTheme() : base(typeof(SearchEdit)) { }
|
||||
//
|
||||
// protected override void BuildRightAddOn(Grid layout, INameScope scope)
|
||||
// {
|
||||
// var searchIcon = new PathIcon()
|
||||
// {
|
||||
// Kind = "SearchOutlined"
|
||||
// };
|
||||
// TokenResourceBinder.CreateGlobalTokenBinding(searchIcon, PathIcon.NormalFilledBrushProperty, GlobalResourceKey.ColorIcon);
|
||||
// var rightAddOnContentPresenter = new Button()
|
||||
// {
|
||||
// Name = RightAddOnPart,
|
||||
// Focusable = false,
|
||||
// Icon = searchIcon
|
||||
// };
|
||||
// CreateTemplateParentBinding(rightAddOnContentPresenter, Button.ContentProperty,
|
||||
// SearchEdit.RightAddOnProperty);
|
||||
// CreateTemplateParentBinding(rightAddOnContentPresenter, Button.BorderThicknessProperty,
|
||||
// SearchEdit.RightAddOnBorderThicknessProperty);
|
||||
// CreateTemplateParentBinding(rightAddOnContentPresenter, Button.CornerRadiusProperty,
|
||||
// SearchEdit.RightAddOnCornerRadiusProperty);
|
||||
// CreateTemplateParentBinding(rightAddOnContentPresenter, Button.TextProperty,
|
||||
// SearchEdit.SearchButtonTextProperty);
|
||||
// CreateTemplateParentBinding(rightAddOnContentPresenter, Button.SizeTypeProperty,
|
||||
// SearchEdit.SizeTypeProperty);
|
||||
//
|
||||
// rightAddOnContentPresenter.RegisterInNameScope(scope);
|
||||
// layout.Children.Add(rightAddOnContentPresenter);
|
||||
// Grid.SetColumn(rightAddOnContentPresenter, 2);
|
||||
// }
|
||||
//
|
||||
// protected override void BuildStyles()
|
||||
// {
|
||||
// base.BuildStyles();
|
||||
//
|
||||
// var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(LineEditKernelDecoratorPart));
|
||||
// decoratorStyle.Add(Border.ZIndexProperty, NormalZIndex);
|
||||
// Add(decoratorStyle);
|
||||
//
|
||||
// var decoratorHoverOrFocusStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(LineEditKernelDecoratorPart).Class(StdPseudoClass.FocusWithIn),
|
||||
// selector.Nesting().Template().Name(LineEditKernelDecoratorPart).Class(StdPseudoClass.PointerOver)));
|
||||
// decoratorHoverOrFocusStyle.Add(Border.ZIndexProperty, ActivatedZIndex);
|
||||
// Add(decoratorHoverOrFocusStyle);
|
||||
//
|
||||
// var searchButtonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
|
||||
// searchButtonStyle.Add(Border.ZIndexProperty, NormalZIndex);
|
||||
// Add(searchButtonStyle);
|
||||
//
|
||||
// var searchButtonStyleHoverOrFocusStyle = new Style(selector => Selectors.Or(selector.Nesting().Template().Name(RightAddOnPart).Class(StdPseudoClass.Pressed),
|
||||
// selector.Nesting().Template().Name(RightAddOnPart).Class(StdPseudoClass.PointerOver)));
|
||||
// searchButtonStyleHoverOrFocusStyle.Add(Border.ZIndexProperty, ActivatedZIndex);
|
||||
// Add(searchButtonStyleHoverOrFocusStyle);
|
||||
//
|
||||
// // Icon button
|
||||
// var iconSearchButtonStyle = new Style(selector => selector.Nesting().PropertyEquals(SearchEdit.SearchButtonStyleProperty, SearchEditButtonStyle.Default));
|
||||
// {
|
||||
// var buttonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
|
||||
// buttonStyle.Add(Button.IsIconVisibleProperty, true);
|
||||
// buttonStyle.Add(Button.ButtonTypeProperty, ButtonType.Default);
|
||||
// iconSearchButtonStyle.Add(buttonStyle);
|
||||
// }
|
||||
// Add(iconSearchButtonStyle);
|
||||
//
|
||||
// // primary button
|
||||
// var primarySearchButtonStyle = new Style(selector => selector.Nesting().PropertyEquals(SearchEdit.SearchButtonStyleProperty, SearchEditButtonStyle.Primary));
|
||||
// {
|
||||
// var buttonStyle = new Style(selector => selector.Nesting().Template().Name(RightAddOnPart));
|
||||
// buttonStyle.Add(Button.IsIconVisibleProperty, false);
|
||||
// buttonStyle.Add(Button.ButtonTypeProperty, ButtonType.Primary);
|
||||
// primarySearchButtonStyle.Add(buttonStyle);
|
||||
// }
|
||||
// Add(primarySearchButtonStyle);
|
||||
// }
|
||||
// }
|
@ -2,9 +2,9 @@
|
||||
using AtomUI.Theme.Styling;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
[ControlThemeProvider]
|
||||
internal class NumericUpDownTheme : BaseControlTheme
|
||||
{
|
||||
|
||||
}
|
||||
//
|
||||
// [ControlThemeProvider]
|
||||
// internal class NumericUpDownTheme : BaseControlTheme
|
||||
// {
|
||||
//
|
||||
// }
|
Loading…
Reference in New Issue
Block a user