chore: add avalonia border demo.

This commit is contained in:
NaBian 2024-07-22 23:30:59 +08:00
parent 40bb60164e
commit 17c2b8473b
8 changed files with 248 additions and 73 deletions

View File

@ -61,6 +61,10 @@
<DependentUpon>BoderDemoCtl.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="UserControl\Styles\BorderDemoCtl.axaml.cs">
<DependentUpon>BorderDemoCtl.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>

View File

@ -16,7 +16,7 @@
Grid.Row="0"
CornerRadius="10,10,0,0"
Background="{DynamicResource TitleBrush}"
Classes="clip">
Theme="{StaticResource BorderClip}">
<Panel>
<TextBlock Foreground="White"
HorizontalAlignment="Center"

View File

@ -0,0 +1,89 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:hc="https://handyorg.github.io/handycontrol"
x:Class="HandyControlDemo.UserControl.BorderDemoCtl"
Background="{DynamicResource RegionBrush}">
<ScrollViewer>
<hc:UniformSpacingPanel Margin="32"
Orientation="Vertical"
Spacing="32"
MaxWidth="664">
<hc:UniformSpacingPanel Spacing="32"
ItemWidth="200"
ItemHeight="200"
ChildWrapping="Wrap"
HorizontalAlignment="Center">
<Border Theme="{StaticResource BorderRegion}">
<Border Background="{DynamicResource PrimaryBrush}">
<TextBlock Text="Content"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White" />
</Border>
</Border>
<Border Theme="{StaticResource BorderRegion}"
Effect="{StaticResource EffectShadow1}">
<Border Background="{DynamicResource InfoBrush}">
<TextBlock Text="Content"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White" />
</Border>
</Border>
<Border Theme="{StaticResource BorderRegion}"
Effect="{StaticResource EffectShadow2}">
<Border Background="{DynamicResource WarningBrush}">
<TextBlock Text="Content"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White" />
</Border>
</Border>
<Border Theme="{StaticResource BorderRegion}"
Effect="{StaticResource EffectShadow3}">
<Border Background="{DynamicResource DangerBrush}">
<TextBlock Text="Content"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White" />
</Border>
</Border>
<Border Theme="{StaticResource BorderRegion}"
Effect="{StaticResource EffectShadow4}">
<Border Background="{DynamicResource AccentBrush}">
<TextBlock Text="Content"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White" />
</Border>
</Border>
<Border Theme="{StaticResource BorderRegion}"
Effect="{StaticResource EffectShadow5}">
<Border Background="{DynamicResource BorderBrush}">
<TextBlock Text="Content"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Border>
</Border>
</hc:UniformSpacingPanel>
<hc:UniformSpacingPanel Orientation="Vertical"
Spacing="10">
<Border Theme="{StaticResource BorderTipPrimary}">
<TextBlock Text="TitleTitleTitleTitleTitleTitleTitleTitleTitleTitle" />
</Border>
<Border Theme="{StaticResource BorderTipDanger}">
<TextBlock Text="TitleTitleTitleTitleTitleTitleTitleTitleTitleTitle" />
</Border>
<Border Theme="{StaticResource BorderTipWarning}">
<TextBlock Text="TitleTitleTitleTitleTitleTitleTitleTitleTitleTitle" />
</Border>
<Border Theme="{StaticResource BorderTipInfo}">
<TextBlock Text="TitleTitleTitleTitleTitleTitleTitleTitleTitleTitle" />
</Border>
<Border Theme="{StaticResource BorderTipSuccess}">
<TextBlock Text="TitleTitleTitleTitleTitleTitleTitleTitleTitleTitle" />
</Border>
</hc:UniformSpacingPanel>
</hc:UniformSpacingPanel>
</ScrollViewer>
</UserControl>

View File

@ -0,0 +1,9 @@
namespace HandyControlDemo.UserControl;
public partial class BorderDemoCtl : Avalonia.Controls.UserControl
{
public BorderDemoCtl()
{
InitializeComponent();
}
}

View File

@ -10,7 +10,8 @@ namespace HandyControl.Controls;
public class UniformSpacingPanel : Panel
{
public static readonly StyledProperty<Orientation> OrientationProperty =
StackPanel.OrientationProperty.AddOwner<UniformSpacingPanel>();
StackPanel.OrientationProperty.AddOwner<UniformSpacingPanel>(new StyledPropertyMetadata<Orientation>(
defaultValue: Orientation.Horizontal));
public static readonly StyledProperty<VisualWrapping> ChildWrappingProperty =
AvaloniaProperty.Register<UniformSpacingPanel, VisualWrapping>(nameof(ChildWrapping));
@ -43,8 +44,6 @@ public class UniformSpacingPanel : Panel
AvaloniaProperty.Register<UniformSpacingPanel, VerticalAlignment?>(nameof(ItemVerticalAlignment),
defaultValue: VerticalAlignment.Stretch);
private Orientation _orientation = Orientation.Horizontal;
static UniformSpacingPanel()
{
AffectsMeasure<StackPanel>(OrientationProperty);
@ -56,16 +55,6 @@ public class UniformSpacingPanel : Panel
AffectsMeasure<StackPanel>(ItemHeightProperty);
AffectsMeasure<StackPanel>(ItemHorizontalAlignmentProperty);
AffectsMeasure<StackPanel>(ItemVerticalAlignmentProperty);
OrientationProperty.Changed.AddClassHandler<UniformSpacingPanel>(OnOrientationChanged);
}
private static void OnOrientationChanged(UniformSpacingPanel self, AvaloniaPropertyChangedEventArgs args)
{
if (args.NewValue is Orientation orientation)
{
self._orientation = orientation;
}
}
private static double CoerceLength(AvaloniaObject _, double length) => length < 0 ? 0 : length;
@ -126,9 +115,10 @@ public class UniformSpacingPanel : Panel
protected override Size MeasureOverride(Size availableSize)
{
var curLineSize = new PanelUvSize(_orientation);
var panelSize = new PanelUvSize(_orientation);
var uvConstraint = new PanelUvSize(_orientation, availableSize);
var orientation = Orientation;
var curLineSize = new PanelUvSize(orientation);
var panelSize = new PanelUvSize(orientation);
var uvConstraint = new PanelUvSize(orientation, availableSize);
double itemWidth = ItemWidth;
double itemHeight = ItemHeight;
bool itemWidthSet = !double.IsNaN(itemWidth);
@ -148,15 +138,15 @@ public class UniformSpacingPanel : Panel
if (childWrapping == VisualWrapping.NoWrap)
{
var layoutSlotSize = new PanelUvSize(_orientation, availableSize);
var layoutSlotSize = new PanelUvSize(orientation, availableSize);
if (_orientation == Orientation.Horizontal)
if (orientation == Orientation.Horizontal)
{
layoutSlotSize.U = double.PositiveInfinity;
layoutSlotSize.V = double.PositiveInfinity;
}
else
{
layoutSlotSize.V = double.PositiveInfinity;
layoutSlotSize.U = double.PositiveInfinity;
}
for (int i = 0, count = Children.Count; i < count; ++i)
@ -176,7 +166,7 @@ public class UniformSpacingPanel : Panel
child.Measure(new Size(layoutSlotSize.Width, layoutSlotSize.Height));
var sz = new PanelUvSize(
_orientation,
orientation,
itemWidthSet ? itemWidth : child.DesiredSize.Width,
itemHeightSet ? itemHeight : child.DesiredSize.Height);
@ -205,30 +195,23 @@ public class UniformSpacingPanel : Panel
child.Measure(childConstraint);
var sz = new PanelUvSize(
_orientation,
orientation,
itemWidthSet ? itemWidth : child.DesiredSize.Width,
itemHeightSet ? itemHeight : child.DesiredSize.Height);
if (MathHelper.GreaterThan(curLineSize.U + sz.U + spacingSize.U, uvConstraint.U))
if (!isFirst && MathHelper.GreaterThan(curLineSize.U + sz.U + spacingSize.U, uvConstraint.U))
{
panelSize.U = Math.Max(curLineSize.U, panelSize.U);
panelSize.V += curLineSize.V + spacingSize.V;
curLineSize = sz;
if (MathHelper.GreaterThan(sz.U, uvConstraint.U))
{
panelSize.U = Math.Max(sz.U, panelSize.U);
panelSize.V += sz.V + spacingSize.V;
curLineSize = new PanelUvSize(_orientation);
}
}
else
{
curLineSize.U += isFirst ? sz.U : sz.U + spacingSize.U;
curLineSize.V = Math.Max(sz.V, curLineSize.V);
isFirst = false;
}
isFirst = false;
}
}
@ -240,16 +223,17 @@ public class UniformSpacingPanel : Panel
protected override Size ArrangeOverride(Size finalSize)
{
var orientation = Orientation;
int firstInLine = 0;
double itemWidth = ItemWidth;
double itemHeight = ItemHeight;
double accumulatedV = 0;
double itemU = _orientation == Orientation.Horizontal ? itemWidth : itemHeight;
var curLineSize = new PanelUvSize(_orientation);
var uvFinalSize = new PanelUvSize(_orientation, finalSize);
double itemU = orientation == Orientation.Horizontal ? itemWidth : itemHeight;
var curLineSize = new PanelUvSize(orientation);
var uvFinalSize = new PanelUvSize(orientation, finalSize);
bool itemWidthSet = !double.IsNaN(itemWidth);
bool itemHeightSet = !double.IsNaN(itemHeight);
bool useItemU = _orientation == Orientation.Horizontal ? itemWidthSet : itemHeightSet;
bool useItemU = orientation == Orientation.Horizontal ? itemWidthSet : itemHeightSet;
var childWrapping = ChildWrapping;
var spacingSize = GetSpacingSize();
@ -266,13 +250,14 @@ public class UniformSpacingPanel : Panel
var child = Children[i];
var sz = new PanelUvSize(
_orientation,
orientation,
itemWidthSet ? itemWidth : child.DesiredSize.Width,
itemHeightSet ? itemHeight : child.DesiredSize.Height);
if (MathHelper.GreaterThan(curLineSize.U + (isFirst ? sz.U : sz.U + spacingSize.U), uvFinalSize.U))
if (!isFirst && MathHelper.GreaterThan(curLineSize.U + sz.U + spacingSize.U, uvFinalSize.U))
{
ArrangeWrapLine(accumulatedV, curLineSize.V, firstInLine, i, useItemU, itemU, spacingSize.U);
ArrangeWrapLine(orientation, accumulatedV, curLineSize.V, firstInLine, i, useItemU, itemU,
spacingSize.U);
accumulatedV += curLineSize.V + spacingSize.V;
curLineSize = sz;
@ -290,7 +275,7 @@ public class UniformSpacingPanel : Panel
if (firstInLine < Children.Count)
{
ArrangeWrapLine(accumulatedV, curLineSize.V, firstInLine, Children.Count, useItemU, itemU,
ArrangeWrapLine(orientation, accumulatedV, curLineSize.V, firstInLine, Children.Count, useItemU, itemU,
spacingSize.U);
}
}
@ -300,11 +285,12 @@ public class UniformSpacingPanel : Panel
private PanelUvSize GetSpacingSize()
{
var orientation = Orientation;
double spacing = Spacing;
if (!double.IsNaN(spacing))
{
return new PanelUvSize(_orientation, spacing, spacing);
return new PanelUvSize(orientation, spacing, spacing);
}
double horizontalSpacing = HorizontalSpacing;
@ -319,19 +305,20 @@ public class UniformSpacingPanel : Panel
verticalSpacing = 0;
}
return new PanelUvSize(_orientation, horizontalSpacing, verticalSpacing);
return new PanelUvSize(orientation, horizontalSpacing, verticalSpacing);
}
private void ArrangeLine(double lineV, bool useItemU, double itemU, double spacing)
{
var orientation = Orientation;
double u = 0;
bool isHorizontal = _orientation == Orientation.Horizontal;
bool isHorizontal = orientation == Orientation.Horizontal;
// ReSharper disable once ForCanBeConvertedToForeach
for (int i = 0; i < Children.Count; i++)
{
Control child = Children[i];
var childSize = new PanelUvSize(_orientation, child.DesiredSize);
var childSize = new PanelUvSize(orientation, child.DesiredSize);
double layoutSlotU = useItemU ? itemU : childSize.U;
child.Arrange(isHorizontal ? new Rect(u, 0, layoutSlotU, lineV) : new Rect(0, u, lineV, layoutSlotU));
@ -344,6 +331,7 @@ public class UniformSpacingPanel : Panel
}
private void ArrangeWrapLine(
Orientation orientation,
double v,
double lineV,
int start,
@ -353,13 +341,13 @@ public class UniformSpacingPanel : Panel
double spacing)
{
double u = 0;
bool isHorizontal = _orientation == Orientation.Horizontal;
bool isHorizontal = orientation == Orientation.Horizontal;
for (int i = start; i < end; i++)
{
var child = Children[i];
var childSize = new PanelUvSize(_orientation, child.DesiredSize);
var childSize = new PanelUvSize(orientation, child.DesiredSize);
double layoutSlotU = useItemU ? itemU : childSize.U;
child.Arrange(isHorizontal ? new Rect(u, v, layoutSlotU, lineV) : new Rect(v, u, lineV, layoutSlotU));

View File

@ -5,26 +5,31 @@
<DropShadowEffect x:Key="EffectShadow1"
BlurRadius="5"
OffsetX="0"
OffsetY="1"
Color="{StaticResource EffectShadowColor}"
Opacity=".2" />
<DropShadowEffect x:Key="EffectShadow2"
BlurRadius="8"
OffsetX="0"
OffsetY="1.5"
Color="{StaticResource EffectShadowColor}"
Opacity=".2" />
<DropShadowEffect x:Key="EffectShadow3"
BlurRadius="14"
OffsetX="0"
OffsetY="4.5"
Color="{StaticResource EffectShadowColor}"
Opacity=".2" />
<DropShadowEffect x:Key="EffectShadow4"
BlurRadius="25"
OffsetX="0"
OffsetY="8"
Color="{StaticResource EffectShadowColor}"
Opacity=".2" />
<DropShadowEffect x:Key="EffectShadow5"
BlurRadius="35"
OffsetX="0"
OffsetY="13"
Color="{StaticResource EffectShadowColor}"
Opacity=".2" />

View File

@ -1,20 +1,107 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTheme x:Key="{x:Type Border}"
<ControlTheme x:Key="BorderRegion"
TargetType="Border">
<Style Selector="^.clip">
<Setter Property="Clip">
<Setter.Value>
<MultiBinding Converter="{StaticResource BorderClipConverter}">
<Binding Path="ActualWidth"
RelativeSource="{RelativeSource Self}" />
<Binding Path="ActualHeight"
RelativeSource="{RelativeSource Self}" />
<Binding Path="CornerRadius"
RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
<Setter Property="CornerRadius"
Value="{StaticResource DefaultCornerRadius}" />
<Setter Property="Padding"
Value="10" />
<Setter Property="Background"
Value="{DynamicResource RegionBrush}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="BorderBrush"
Value="{DynamicResource BorderBrush}" />
</ControlTheme>
<ControlTheme x:Key="BorderTipBaseStyle"
TargetType="Border">
<Setter Property="CornerRadius"
Value="{StaticResource DefaultCornerRadius}" />
<Setter Property="Padding"
Value="10" />
<Setter Property="BorderThickness"
Value="5,0,0,0" />
</ControlTheme>
<ControlTheme x:Key="BorderTipPrimary"
BasedOn="{StaticResource BorderTipBaseStyle}"
TargetType="Border">
<Setter Property="Background"
Value="{DynamicResource LightPrimaryBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource PrimaryBrush}" />
</ControlTheme>
<ControlTheme x:Key="BorderTipDanger"
BasedOn="{StaticResource BorderTipBaseStyle}"
TargetType="Border">
<Setter Property="Background"
Value="{DynamicResource LightDangerBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource DangerBrush}" />
</ControlTheme>
<ControlTheme x:Key="BorderTipWarning"
BasedOn="{StaticResource BorderTipBaseStyle}"
TargetType="Border">
<Setter Property="Background"
Value="{DynamicResource LightWarningBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource WarningBrush}" />
</ControlTheme>
<ControlTheme x:Key="BorderTipInfo"
BasedOn="{StaticResource BorderTipBaseStyle}"
TargetType="Border">
<Setter Property="Background"
Value="{DynamicResource LightInfoBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource InfoBrush}" />
</ControlTheme>
<ControlTheme x:Key="BorderTipSuccess"
BasedOn="{StaticResource BorderTipBaseStyle}"
TargetType="Border">
<Setter Property="Background"
Value="{DynamicResource LightSuccessBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource SuccessBrush}" />
</ControlTheme>
<ControlTheme x:Key="BorderVerticallySplitter"
TargetType="Border">
<Setter Property="Width"
Value="1" />
<Setter Property="HorizontalAlignment"
Value="Left" />
<Setter Property="Background"
Value="{DynamicResource ThirdlyTextBrush}" />
</ControlTheme>
<ControlTheme x:Key="BorderHorizontallySplitter"
TargetType="Border">
<Setter Property="Height"
Value="1" />
<Setter Property="VerticalAlignment"
Value="Top" />
<Setter Property="Background"
Value="{DynamicResource ThirdlyTextBrush}" />
</ControlTheme>
<ControlTheme x:Key="BorderClip"
TargetType="Border">
<Setter Property="Clip">
<Setter.Value>
<MultiBinding Converter="{StaticResource BorderClipConverter}">
<Binding Path="Bounds.Width"
RelativeSource="{RelativeSource Self}" />
<Binding Path="Bounds.Height"
RelativeSource="{RelativeSource Self}" />
<Binding Path="CornerRadius"
RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Setter.Value>
</Setter>
</ControlTheme>
</ResourceDictionary>

View File

@ -263,26 +263,19 @@ public class UniformSpacingPanel : Panel
itemWidthSet ? itemWidth : child.DesiredSize.Width,
itemHeightSet ? itemHeight : child.DesiredSize.Height);
if (MathHelper.GreaterThan(curLineSize.U + sz.U + spacingSize.U, uvConstraint.U))
if (!isFirst && MathHelper.GreaterThan(curLineSize.U + sz.U + spacingSize.U, uvConstraint.U))
{
panelSize.U = Math.Max(curLineSize.U, panelSize.U);
panelSize.V += curLineSize.V + spacingSize.V;
curLineSize = sz;
if (MathHelper.GreaterThan(sz.U, uvConstraint.U))
{
panelSize.U = Math.Max(sz.U, panelSize.U);
panelSize.V += sz.V + spacingSize.V;
curLineSize = new PanelUvSize(_orientation);
}
}
else
{
curLineSize.U += isFirst ? sz.U : sz.U + spacingSize.U;
curLineSize.V = Math.Max(sz.V, curLineSize.V);
isFirst = false;
}
isFirst = false;
}
}
@ -350,7 +343,7 @@ public class UniformSpacingPanel : Panel
itemWidthSet ? itemWidth : child.DesiredSize.Width,
itemHeightSet ? itemHeight : child.DesiredSize.Height);
if (MathHelper.GreaterThan(curLineSize.U + (isFirst ? sz.U : sz.U + spacingSize.U), uvFinalSize.U))
if (!isFirst && MathHelper.GreaterThan(curLineSize.U + sz.U + spacingSize.U, uvFinalSize.U))
{
ArrangeWrapLine(accumulatedV, curLineSize.V, firstInLine, i, useItemU, itemU, spacingSize.U);