chore: add avalonia button and brush demo.

This commit is contained in:
NaBian committed 2024-07-17 22:56:54 +08:00
1 parent 63bf5c6aa7
commit 40bb60164e
23 files changed
+1027 -300

No files matched your search

@@ -1,4 +1,5 @@
using Avalonia;
using System.Globalization;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml;
@@ -6,7 +7,7 @@ using Avalonia.Markup.Xaml;
namespace HandyControlDemo;
public partial class App : Application
public class App : Application
{
public override void Initialize()
{
@@ -15,6 +16,7 @@ public partial class App : Application
public override void OnFrameworkInitializationCompleted()
{
Properties.Langs.Lang.Culture = new CultureInfo("en");
BindingPlugins.DataValidators.RemoveAt(0);
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
@@ -1,7 +1,7 @@
[
{
"title": "Styles",
"selectedIndex": 0,
"selectedIndex": -1,
"group": false,
"demoItemList": [
[ "Brush", "BrushDemoCtl", "Brush.Brush", "", "" ],
@@ -57,6 +57,10 @@
<Compile Update="Views\Styles\ButtonDemoCtrl.axaml.cs">
<DependentUpon>ButtonDemoCtrl.axaml</DependentUpon>
</Compile>
<Compile Update="UserControl\Styles\BrushDemoCtl.axaml.cs">
<DependentUpon>BoderDemoCtl.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
@@ -6,46 +6,55 @@
Margin="16,16,0,16"
CornerRadius="10"
Effect="{StaticResource EffectShadow4}">
<TabControl BorderThickness="0 1 0 0"
SelectionChanged="TabControl_OnSelectionChanged"
ItemsSource="{Binding DemoInfoCollection}"
Background="Transparent"
SelectedIndex="0">
<TabControl.ItemTemplate>
<DataTemplate DataType="data:DemoInfoModel">
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="data:DemoInfoModel">
<Panel Margin="10">
<ListBox SelectionMode="Single"
Padding="0"
BorderThickness="0"
SelectedIndex="{Binding SelectedIndex}"
ItemsSource="{Binding DemoItemList}">
<ListBox.ItemTemplate>
<DataTemplate DataType="data:DemoItemModel">
<StackPanel Orientation="Horizontal">
<Rectangle Width="16"
Height="16"
Fill="{Binding ImageBrush}" />
<TextBlock Margin="6,0,0,0"
Text="{Binding Name}" />
<Path IsVisible="{Binding IsNew}"
VerticalAlignment="Center"
Data="{StaticResource NewGeometry}"
Stretch="Uniform"
Margin="10,0,0,0"
Width="30"
Height="14"
Fill="{DynamicResource AccentBrush}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Panel>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
<DockPanel>
<Button Content="Practical demos"
DockPanel.Dock="Top"
HorizontalAlignment="Stretch"
Margin="10,10,10,4"
BorderThickness="0"
Background="{DynamicResource SecondaryRegionBrush}" />
<TabControl BorderThickness="0 1 0 0"
Classes="inline"
SelectionChanged="TabControl_OnSelectionChanged"
ItemsSource="{Binding DemoInfoCollection}"
Background="Transparent"
SelectedIndex="0">
<TabControl.ItemTemplate>
<DataTemplate DataType="data:DemoInfoModel">
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="data:DemoInfoModel">
<Panel Margin="10">
<ListBox SelectionMode="Single"
Padding="0"
BorderThickness="0"
SelectedIndex="{Binding SelectedIndex}"
ItemsSource="{Binding DemoItemList}">
<ListBox.ItemTemplate>
<DataTemplate DataType="data:DemoItemModel">
<StackPanel Orientation="Horizontal">
<Rectangle Width="16"
Height="16"
Fill="{Binding ImageBrush}" />
<TextBlock Margin="6,0,0,0"
Text="{Binding Name}" />
<Path IsVisible="{Binding IsNew}"
VerticalAlignment="Center"
Data="{StaticResource NewGeometry}"
Stretch="Uniform"
Margin="10,0,0,0"
Width="30"
Height="14"
Fill="{DynamicResource AccentBrush}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Panel>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</DockPanel>
</UserControl>
@@ -0,0 +1,117 @@
<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.BrushDemoCtl"
Background="{DynamicResource RegionBrush}">
<ScrollViewer>
<hc:UniformSpacingPanel ChildWrapping="Wrap"
ItemWidth="200"
Margin="32"
Spacing="16"
VerticalAlignment="Center"
MaxWidth="632">
<Label Content="PrimaryBrush"
Theme="{StaticResource LabelPrimary}" />
<Label Content="DarkPrimaryBrush"
Background="{DynamicResource DarkPrimaryBrush}"
Foreground="White"
BorderThickness="0" />
<Label Content="DangerBrush"
Theme="{StaticResource LabelDanger}" />
<Label Content="DarkDangerBrush"
Background="{DynamicResource DarkDangerBrush}"
Foreground="White"
BorderThickness="0" />
<Label Content="WarningBrush"
Theme="{StaticResource LabelWarning}" />
<Label Content="DarkWarningBrush"
Background="{DynamicResource DarkWarningBrush}"
Foreground="White"
BorderThickness="0" />
<Label Content="InfoBrush"
Theme="{StaticResource LabelInfo}" />
<Label Content="DarkInfoBrush"
Background="{DynamicResource DarkInfoBrush}"
Foreground="White"
BorderThickness="0" />
<Label Content="SuccessBrush"
Theme="{StaticResource LabelSuccess}" />
<Label Content="DarkSuccessBrush"
Background="{DynamicResource DarkSuccessBrush}"
Foreground="White"
BorderThickness="0" />
<Label Content="AccentBrush"
Background="{DynamicResource AccentBrush}"
Foreground="White"
BorderThickness="0" />
<Label Content="DarkAccentBrush"
Background="{DynamicResource DarkAccentBrush}"
Foreground="White"
BorderThickness="0" />
<Label Content="PrimaryTextBrush"
Background="{DynamicResource PrimaryTextBrush}"
Foreground="{DynamicResource ThirdlyTextBrush}" />
<Label Content="SecondaryTextBrush"
BorderThickness="0"
Background="{DynamicResource SecondaryTextBrush}"
Foreground="White" />
<Label Content="ThirdlyTextBrush"
BorderThickness="0"
Background="{DynamicResource ThirdlyTextBrush}"
Foreground="White" />
<Label Content="ReverseTextBrush"
BorderThickness="0"
Background="{DynamicResource ReverseTextBrush}"
Foreground="White" />
<Label Content="TextIconBrush"
Background="{DynamicResource TextIconBrush}"
Foreground="{DynamicResource ReverseTextBrush}" />
<Label Content="BorderBrush"
BorderThickness="0"
Background="{DynamicResource BorderBrush}"
Foreground="{DynamicResource PrimaryTextBrush}" />
<Label Content="SecondaryBorderBrush"
BorderThickness="0"
Background="{DynamicResource SecondaryBorderBrush}"
Foreground="White" />
<Label Content="BackgroundBrush"
BorderThickness="0"
Background="{DynamicResource BackgroundBrush}"
Foreground="{DynamicResource ReverseTextBrush}" />
<Label Content="RegionBrush"
Background="{DynamicResource RegionBrush}"
Foreground="{DynamicResource PrimaryTextBrush}" />
<Label Content="SecondaryRegionBrush"
BorderThickness="0"
Background="{DynamicResource SecondaryRegionBrush}"
Foreground="{DynamicResource PrimaryTextBrush}" />
<Label Content="ThirdlyRegionBrush"
Background="{DynamicResource ThirdlyRegionBrush}"
Foreground="{DynamicResource PrimaryTextBrush}" />
<Label Content="TitleBrush"
BorderThickness="0"
Background="{DynamicResource TitleBrush}"
Foreground="White" />
<Label Content="DefaultBrush"
Background="{DynamicResource DefaultBrush}"
Foreground="{DynamicResource PrimaryTextBrush}" />
<Label Content="DarkDefaultBrush"
BorderThickness="0"
Background="{DynamicResource DarkDefaultBrush}"
Foreground="{DynamicResource PrimaryTextBrush}" />
<Label Content="DarkMaskBrush"
BorderThickness="0"
Background="{DynamicResource DarkMaskBrush}"
Foreground="{DynamicResource PrimaryTextBrush}" />
<Label Content="DarkOpacityBrush"
BorderThickness="0"
Background="{DynamicResource DarkOpacityBrush}"
Foreground="White" />
</hc:UniformSpacingPanel>
</ScrollViewer>
</UserControl>
@@ -0,0 +1,9 @@
namespace HandyControlDemo.UserControl;
public partial class BrushDemoCtl : Avalonia.Controls.UserControl
{
public BrushDemoCtl()
{
InitializeComponent();
}
}
@@ -1,28 +1,69 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignWidth="800"
d:DesignHeight="450"
x:Class="HandyControlDemo.UserControl.ButtonDemoCtl"
xmlns:hc="https://handyorg.github.io/handycontrol"
Background="{DynamicResource RegionBrush}">
<ScrollViewer>
<StackPanel Orientation="Horizontal"
VerticalAlignment="Top"
Spacing="4"
Margin="32">
<Button Content="default" />
<Button Content="primary"
Classes="primary" />
<Button Content="success"
Classes="success" />
<Button Content="info"
Classes="info" />
<Button Content="warning"
Classes="warning" />
<Button Content="danger"
Classes="danger" />
</StackPanel>
<hc:UniformSpacingPanel ChildWrapping="Wrap"
Spacing="32"
Margin="32">
<hc:UniformSpacingPanel Orientation="Vertical"
Spacing="32">
<WrapPanel>
<StackPanel>
<Button Content="default"
Margin="5" />
<Button IsEnabled="False"
Content="default"
Margin="5" />
</StackPanel>
<StackPanel>
<Button Content="primary"
Margin="5"
Theme="{StaticResource ButtonPrimary}" />
<Button IsEnabled="False"
Content="primary"
Margin="5"
Theme="{StaticResource ButtonPrimary}" />
</StackPanel>
<StackPanel>
<Button Content="success"
Margin="5"
Theme="{StaticResource ButtonSuccess}" />
<Button IsEnabled="False"
Content="success"
Margin="5"
Theme="{StaticResource ButtonSuccess}" />
</StackPanel>
<StackPanel>
<Button Content="info"
Margin="5"
Theme="{StaticResource ButtonInfo}" />
<Button IsEnabled="False"
Content="info"
Margin="5"
Theme="{StaticResource ButtonInfo}" />
</StackPanel>
<StackPanel>
<Button Content="warning"
Margin="5"
Theme="{StaticResource ButtonWarning}" />
<Button IsEnabled="False"
Content="warning"
Margin="5"
Theme="{StaticResource ButtonWarning}" />
</StackPanel>
<StackPanel>
<Button Content="danger"
Margin="5"
Theme="{StaticResource ButtonDanger}" />
<Button IsEnabled="False"
Content="danger"
Margin="5"
Theme="{StaticResource ButtonDanger}" />
</StackPanel>
</WrapPanel>
</hc:UniformSpacingPanel>
</hc:UniformSpacingPanel>
</ScrollViewer>
</UserControl>
@@ -69,7 +69,7 @@ public class MainViewModel : DemoViewModelBase<DemoDataModel>
return;
}
ContentTitle = Lang.ResourceManager.GetString(DemoItemCurrent.Name);
ContentTitle = Lang.ResourceManager.GetString(DemoItemCurrent.Name, Lang.Culture);
});
//load items
@@ -91,7 +91,7 @@ public class MainViewModel : DemoViewModelBase<DemoDataModel>
}
DemoItemCurrent = item;
ContentTitle = Lang.ResourceManager.GetString(item.Name);
ContentTitle = Lang.ResourceManager.GetString(item.Name, Lang.Culture);
object? demoControl = AssemblyHelper.ResolveByKey(item.TargetCtlName) ?? AssemblyHelper.CreateInternalInstance($"UserControl.{item.TargetCtlName}");
SubContent = demoControl;
}
@@ -0,0 +1,373 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Layout;
using HandyControl.Data;
using HandyControl.Tools;
namespace HandyControl.Controls;
public class UniformSpacingPanel : Panel
{
public static readonly StyledProperty<Orientation> OrientationProperty =
StackPanel.OrientationProperty.AddOwner<UniformSpacingPanel>();
public static readonly StyledProperty<VisualWrapping> ChildWrappingProperty =
AvaloniaProperty.Register<UniformSpacingPanel, VisualWrapping>(nameof(ChildWrapping));
public static readonly StyledProperty<double> SpacingProperty =
StackPanel.SpacingProperty.AddOwner<UniformSpacingPanel>(
new StyledPropertyMetadata<double>(defaultValue: double.NaN, coerce: CoerceLength));
public static readonly StyledProperty<double> HorizontalSpacingProperty =
AvaloniaProperty.Register<UniformSpacingPanel, double>(nameof(HorizontalSpacing), defaultValue: double.NaN,
coerce: CoerceLength);
public static readonly StyledProperty<double> VerticalSpacingProperty =
AvaloniaProperty.Register<UniformSpacingPanel, double>(nameof(VerticalSpacing), defaultValue: double.NaN,
coerce: CoerceLength);
public static readonly StyledProperty<double> ItemWidthProperty =
AvaloniaProperty.Register<UniformSpacingPanel, double>(nameof(ItemWidth), defaultValue: double.NaN,
coerce: CoerceLength);
public static readonly StyledProperty<double> ItemHeightProperty =
AvaloniaProperty.Register<UniformSpacingPanel, double>(nameof(ItemHeight), defaultValue: double.NaN,
coerce: CoerceLength);
public static readonly StyledProperty<HorizontalAlignment?> ItemHorizontalAlignmentProperty =
AvaloniaProperty.Register<UniformSpacingPanel, HorizontalAlignment?>(nameof(ItemHorizontalAlignment),
defaultValue: HorizontalAlignment.Stretch);
public static readonly StyledProperty<VerticalAlignment?> ItemVerticalAlignmentProperty =
AvaloniaProperty.Register<UniformSpacingPanel, VerticalAlignment?>(nameof(ItemVerticalAlignment),
defaultValue: VerticalAlignment.Stretch);
private Orientation _orientation = Orientation.Horizontal;
static UniformSpacingPanel()
{
AffectsMeasure<StackPanel>(OrientationProperty);
AffectsMeasure<StackPanel>(ChildWrappingProperty);
AffectsMeasure<StackPanel>(SpacingProperty);
AffectsMeasure<StackPanel>(HorizontalSpacingProperty);
AffectsMeasure<StackPanel>(VerticalSpacingProperty);
AffectsMeasure<StackPanel>(ItemWidthProperty);
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;
public Orientation Orientation
{
get => GetValue(OrientationProperty);
set => SetValue(OrientationProperty, value);
}
public VisualWrapping ChildWrapping
{
get => GetValue(ChildWrappingProperty);
set => SetValue(ChildWrappingProperty, value);
}
public double Spacing
{
get => GetValue(SpacingProperty);
set => SetValue(SpacingProperty, value);
}
public double HorizontalSpacing
{
get => GetValue(HorizontalSpacingProperty);
set => SetValue(HorizontalSpacingProperty, value);
}
public double VerticalSpacing
{
get => GetValue(VerticalSpacingProperty);
set => SetValue(VerticalSpacingProperty, value);
}
public double ItemWidth
{
get => GetValue(ItemWidthProperty);
set => SetValue(ItemWidthProperty, value);
}
public double ItemHeight
{
get => GetValue(ItemHeightProperty);
set => SetValue(ItemHeightProperty, value);
}
public HorizontalAlignment? ItemHorizontalAlignment
{
get => GetValue(ItemHorizontalAlignmentProperty);
set => SetValue(ItemHorizontalAlignmentProperty, value);
}
public VerticalAlignment? ItemVerticalAlignment
{
get => GetValue(ItemVerticalAlignmentProperty);
set => SetValue(ItemVerticalAlignmentProperty, value);
}
protected override Size MeasureOverride(Size availableSize)
{
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);
bool itemHeightSet = !double.IsNaN(itemHeight);
var itemHorizontalAlignment = ItemHorizontalAlignment;
var itemVerticalAlignment = ItemVerticalAlignment;
bool itemHorizontalAlignmentSet = itemHorizontalAlignment != null;
bool itemVerticalAlignmentSet = itemVerticalAlignment != null;
var childWrapping = ChildWrapping;
var spacingSize = GetSpacingSize();
var childConstraint = new Size(
itemWidthSet ? itemWidth : availableSize.Width,
itemHeightSet ? itemHeight : availableSize.Height);
bool isFirst = true;
if (childWrapping == VisualWrapping.NoWrap)
{
var layoutSlotSize = new PanelUvSize(_orientation, availableSize);
if (_orientation == Orientation.Horizontal)
{
layoutSlotSize.U = double.PositiveInfinity;
}
else
{
layoutSlotSize.V = double.PositiveInfinity;
}
for (int i = 0, count = Children.Count; i < count; ++i)
{
var child = Children[i];
if (itemHorizontalAlignmentSet)
{
child.SetCurrentValue(HorizontalAlignmentProperty, itemHorizontalAlignment);
}
if (itemVerticalAlignmentSet)
{
child.SetCurrentValue(VerticalAlignmentProperty, itemVerticalAlignment);
}
child.Measure(new Size(layoutSlotSize.Width, layoutSlotSize.Height));
var sz = new PanelUvSize(
_orientation,
itemWidthSet ? itemWidth : child.DesiredSize.Width,
itemHeightSet ? itemHeight : child.DesiredSize.Height);
curLineSize.U += isFirst ? sz.U : sz.U + spacingSize.U;
curLineSize.V = Math.Max(sz.V, curLineSize.V);
isFirst = false;
}
}
else
{
for (int i = 0, count = Children.Count; i < count; i++)
{
var child = Children[i];
if (itemHorizontalAlignmentSet)
{
child.SetCurrentValue(HorizontalAlignmentProperty, itemHorizontalAlignment);
}
if (itemVerticalAlignmentSet)
{
child.SetCurrentValue(VerticalAlignmentProperty, itemVerticalAlignment);
}
child.Measure(childConstraint);
var sz = new PanelUvSize(
_orientation,
itemWidthSet ? itemWidth : child.DesiredSize.Width,
itemHeightSet ? itemHeight : child.DesiredSize.Height);
if (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;
}
}
}
panelSize.U = Math.Max(curLineSize.U, panelSize.U);
panelSize.V += curLineSize.V;
return new Size(panelSize.Width, panelSize.Height);
}
protected override Size ArrangeOverride(Size finalSize)
{
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);
bool itemWidthSet = !double.IsNaN(itemWidth);
bool itemHeightSet = !double.IsNaN(itemHeight);
bool useItemU = _orientation == Orientation.Horizontal ? itemWidthSet : itemHeightSet;
var childWrapping = ChildWrapping;
var spacingSize = GetSpacingSize();
bool isFirst = true;
if (childWrapping == VisualWrapping.NoWrap)
{
ArrangeLine(uvFinalSize.V, useItemU, itemU, spacingSize.U);
}
else
{
for (int i = 0, count = Children.Count; i < count; i++)
{
var child = Children[i];
var sz = new PanelUvSize(
_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))
{
ArrangeWrapLine(accumulatedV, curLineSize.V, firstInLine, i, useItemU, itemU, spacingSize.U);
accumulatedV += curLineSize.V + spacingSize.V;
curLineSize = sz;
firstInLine = i;
}
else
{
curLineSize.U += isFirst ? sz.U : sz.U + spacingSize.U;
curLineSize.V = Math.Max(sz.V, curLineSize.V);
}
isFirst = false;
}
if (firstInLine < Children.Count)
{
ArrangeWrapLine(accumulatedV, curLineSize.V, firstInLine, Children.Count, useItemU, itemU,
spacingSize.U);
}
}
return finalSize;
}
private PanelUvSize GetSpacingSize()
{
double spacing = Spacing;
if (!double.IsNaN(spacing))
{
return new PanelUvSize(_orientation, spacing, spacing);
}
double horizontalSpacing = HorizontalSpacing;
if (double.IsNaN(horizontalSpacing))
{
horizontalSpacing = 0;
}
double verticalSpacing = VerticalSpacing;
if (double.IsNaN(verticalSpacing))
{
verticalSpacing = 0;
}
return new PanelUvSize(_orientation, horizontalSpacing, verticalSpacing);
}
private void ArrangeLine(double lineV, bool useItemU, double itemU, double spacing)
{
double u = 0;
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);
double layoutSlotU = useItemU ? itemU : childSize.U;
child.Arrange(isHorizontal ? new Rect(u, 0, layoutSlotU, lineV) : new Rect(0, u, lineV, layoutSlotU));
if (layoutSlotU > 0)
{
u += layoutSlotU + spacing;
}
}
}
private void ArrangeWrapLine(
double v,
double lineV,
int start,
int end,
bool useItemU,
double itemU,
double spacing)
{
double u = 0;
bool isHorizontal = _orientation == Orientation.Horizontal;
for (int i = start; i < end; i++)
{
var child = Children[i];
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));
if (layoutSlotU > 0)
{
u += layoutSlotU + spacing;
}
}
}
}
@@ -0,0 +1,7 @@
namespace HandyControl.Data;
public enum VisualWrapping
{
NoWrap,
Wrap
}
@@ -0,0 +1,69 @@
using Avalonia;
using Avalonia.Layout;
namespace HandyControl.Data;
internal struct PanelUvSize
{
private readonly Orientation _orientation;
public Size ScreenSize => new(U, V);
public double U { get; set; }
public double V { get; set; }
public double Width
{
get => _orientation == Orientation.Horizontal ? U : V;
private set
{
if (_orientation == Orientation.Horizontal)
{
U = value;
}
else
{
V = value;
}
}
}
public double Height
{
get => _orientation == Orientation.Horizontal ? V : U;
private set
{
if (_orientation == Orientation.Horizontal)
{
V = value;
}
else
{
U = value;
}
}
}
public PanelUvSize(Orientation orientation, double width, double height)
{
U = V = 0d;
_orientation = orientation;
Width = width;
Height = height;
}
public PanelUvSize(Orientation orientation, Size size)
{
U = V = 0d;
_orientation = orientation;
Width = size.Width;
Height = size.Height;
}
public PanelUvSize(Orientation orientation)
{
U = V = 0d;
_orientation = orientation;
}
}
@@ -8,7 +8,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)" />
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)"/>
</ItemGroup>
<ItemGroup>
@@ -26,7 +26,4 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
</Project>
@@ -1,19 +1,11 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTheme x:Key="{x:Type Button}"
<ControlTheme x:Key="ButtonBaseStyle"
TargetType="Button">
<Setter Property="Background"
Value="{DynamicResource RegionBrush}" />
<Setter Property="Foreground"
Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource BorderBrush}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="CornerRadius"
Value="{DynamicResource DefaultCornerRadius}" />
<Setter Property="Height"
Value="{StaticResource DefaultControlHeight}" />
<Setter Property="Padding"
Value="{DynamicResource DefaultControlPadding}" />
Value="{StaticResource DefaultControlPadding}" />
<Setter Property="HorizontalAlignment"
Value="Center" />
<Setter Property="VerticalAlignment"
@@ -22,8 +14,18 @@
Value="Center" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Background"
Value="{DynamicResource RegionBrush}" />
<Setter Property="Foreground"
Value="{DynamicResource TextIconBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource BorderBrush}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="CornerRadius"
Value="{StaticResource DefaultCornerRadius}" />
<Setter Property="Template">
<ControlTemplate TargetType="Button">
<ControlTemplate>
<ContentPresenter x:Name="PART_ContentPresenter"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
@@ -38,104 +40,85 @@
</ControlTemplate>
</Setter>
<Style Selector="^:pointerover">
<Style Selector="^:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Opacity"
Value="0.9" />
</Style>
<Style Selector="^:pressed /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Opacity"
Value="0.6" />
</Style>
<Style Selector="^:disabled /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Opacity"
Value="0.4" />
</Style>
</ControlTheme>
<ControlTheme x:Key="ButtonDefault"
BasedOn="{StaticResource ButtonBaseStyle}"
TargetType="Button">
<Setter Property="Foreground"
Value="{DynamicResource PrimaryTextBrush}" />
<Style Selector="^:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background"
Value="{DynamicResource SecondaryRegionBrush}" />
</Style>
<Style Selector="^:pressed">
<Style Selector="^:pressed /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background"
Value="{DynamicResource BorderBrush}" />
</Style>
</ControlTheme>
<Style Selector="^:disabled">
<Setter Property="Opacity"
Value=".4" />
</Style>
<ControlTheme x:Key="{x:Type Button}"
BasedOn="{StaticResource ButtonDefault}"
TargetType="Button" />
<Style Selector="^.primary">
<Setter Property="Foreground"
Value="{DynamicResource TextIconBrush}" />
<Setter Property="Background"
Value="{DynamicResource PrimaryBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource PrimaryBrush}" />
<Style Selector="^:pointerover">
<Setter Property="Opacity"
Value=".9" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Opacity"
Value=".6" />
</Style>
</Style>
<ControlTheme x:Key="ButtonPrimary"
BasedOn="{StaticResource ButtonBaseStyle}"
TargetType="Button">
<Setter Property="Background"
Value="{DynamicResource PrimaryBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource PrimaryBrush}" />
</ControlTheme>
<Style Selector="^.success">
<Setter Property="Foreground"
Value="{DynamicResource TextIconBrush}" />
<Setter Property="Background"
Value="{DynamicResource SuccessBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource SuccessBrush}" />
<Style Selector="^:pointerover">
<Setter Property="Opacity"
Value=".9" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Opacity"
Value=".6" />
</Style>
</Style>
<ControlTheme x:Key="ButtonSuccess"
BasedOn="{StaticResource ButtonBaseStyle}"
TargetType="Button">
<Setter Property="Background"
Value="{DynamicResource SuccessBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource SuccessBrush}" />
</ControlTheme>
<Style Selector="^.info">
<Setter Property="Foreground"
Value="{DynamicResource TextIconBrush}" />
<Setter Property="Background"
Value="{DynamicResource InfoBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource InfoBrush}" />
<Style Selector="^:pointerover">
<Setter Property="Opacity"
Value=".9" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Opacity"
Value=".6" />
</Style>
</Style>
<ControlTheme x:Key="ButtonInfo"
BasedOn="{StaticResource ButtonBaseStyle}"
TargetType="Button">
<Setter Property="Background"
Value="{DynamicResource InfoBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource InfoBrush}" />
</ControlTheme>
<Style Selector="^.warning">
<Setter Property="Foreground"
Value="{DynamicResource TextIconBrush}" />
<Setter Property="Background"
Value="{DynamicResource WarningBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource WarningBrush}" />
<Style Selector="^:pointerover">
<Setter Property="Opacity"
Value=".9" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Opacity"
Value=".6" />
</Style>
</Style>
<ControlTheme x:Key="ButtonWarning"
BasedOn="{StaticResource ButtonBaseStyle}"
TargetType="Button">
<Setter Property="Background"
Value="{DynamicResource WarningBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource WarningBrush}" />
</ControlTheme>
<Style Selector="^.danger">
<Setter Property="Foreground"
Value="{DynamicResource TextIconBrush}" />
<Setter Property="Background"
Value="{DynamicResource DangerBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource DangerBrush}" />
<Style Selector="^:pointerover">
<Setter Property="Opacity"
Value=".9" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Opacity"
Value=".6" />
</Style>
</Style>
<ControlTheme x:Key="ButtonDanger"
BasedOn="{StaticResource ButtonBaseStyle}"
TargetType="Button">
<Setter Property="Background"
Value="{DynamicResource DangerBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource DangerBrush}" />
</ControlTheme>
</ResourceDictionary>
@@ -0,0 +1,94 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTheme x:Key="LabelBaseStyle"
TargetType="Label">
<Setter Property="Foreground"
Value="{DynamicResource TextIconBrush}" />
<Setter Property="Background"
Value="{DynamicResource RegionBrush}" />
<Setter Property="BorderBrush"
Value="{DynamicResource BorderBrush}" />
<Setter Property="CornerRadius"
Value="{StaticResource DefaultCornerRadius}" />
<Setter Property="Padding"
Value="{StaticResource DefaultControlPadding}" />
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="HorizontalAlignment"
Value="Center" />
<Setter Property="VerticalAlignment"
Value="Center" />
<Setter Property="Height"
Value="{StaticResource DefaultControlHeight}" />
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter Name="PART_ContentPresenter"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
CornerRadius="{TemplateBinding CornerRadius}"
RecognizesAccessKey="True" />
</ControlTemplate>
</Setter>
<Style Selector="^:disabled /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Opacity"
Value="0.4" />
</Style>
</ControlTheme>
<ControlTheme x:Key="LabelDefault"
BasedOn="{StaticResource LabelBaseStyle}"
TargetType="Label">
<Setter Property="Foreground"
Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="BorderThickness"
Value="1" />
</ControlTheme>
<ControlTheme x:Key="{x:Type Label}"
BasedOn="{StaticResource LabelDefault}"
TargetType="Label" />
<ControlTheme x:Key="LabelPrimary"
BasedOn="{StaticResource LabelBaseStyle}"
TargetType="Label">
<Setter Property="Background"
Value="{DynamicResource PrimaryBrush}" />
</ControlTheme>
<ControlTheme x:Key="LabelSuccess"
BasedOn="{StaticResource LabelBaseStyle}"
TargetType="Label">
<Setter Property="Background"
Value="{DynamicResource SuccessBrush}" />
</ControlTheme>
<ControlTheme x:Key="LabelInfo"
BasedOn="{StaticResource LabelBaseStyle}"
TargetType="Label">
<Setter Property="Background"
Value="{DynamicResource InfoBrush}" />
</ControlTheme>
<ControlTheme x:Key="LabelWarning"
BasedOn="{StaticResource LabelBaseStyle}"
TargetType="Label">
<Setter Property="Background"
Value="{DynamicResource WarningBrush}" />
</ControlTheme>
<ControlTheme x:Key="LabelDanger"
BasedOn="{StaticResource LabelBaseStyle}"
TargetType="Label">
<Setter Property="Background"
Value="{DynamicResource DangerBrush}" />
</ControlTheme>
</ResourceDictionary>
@@ -8,6 +8,8 @@
Value="{DynamicResource BorderBrush}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="CornerRadius"
Value="{StaticResource DefaultCornerRadius}" />
<Setter Property="Padding"
Value="4" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility"
@@ -1,5 +1,6 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:hc="clr-namespace:HandyControl.Controls">
<ControlTheme x:Key="{x:Type ListBoxItem}"
TargetType="ListBoxItem">
<Setter Property="Padding"
@@ -12,6 +13,8 @@
Value="{DynamicResource RegionBrush}" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="CornerRadius"
Value="{StaticResource DefaultCornerRadius}" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="Margin"
@@ -33,27 +36,14 @@
<Style Selector="^:pointerover /template/ ContentPresenter">
<Setter Property="Background"
Value="{DynamicResource ThemeControlHighlightMidBrush}" />
Value="{DynamicResource SecondaryRegionBrush}" />
</Style>
<Style Selector="^:selected /template/ ContentPresenter">
<Setter Property="Background"
Value="{DynamicResource ThemeAccentBrush4}" />
</Style>
<Style Selector="^:selected:focus /template/ ContentPresenter">
<Setter Property="Background"
Value="{DynamicResource ThemeAccentBrush3}" />
</Style>
<Style Selector="^:selected:pointerover /template/ ContentPresenter">
<Setter Property="Background"
Value="{DynamicResource ThemeAccentBrush3}" />
</Style>
<Style Selector="^:selected:focus:pointerover /template/ ContentPresenter">
<Setter Property="Background"
Value="{DynamicResource ThemeAccentBrush2}" />
Value="{DynamicResource PrimaryBrush}" />
<Setter Property="Foreground"
Value="{DynamicResource TextIconBrush}" />
</Style>
</ControlTheme>
</ResourceDictionary>
@@ -17,6 +17,7 @@
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/ListBox.axaml" />
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/ScrollBar.axaml" />
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/ScrollViewer.axaml" />
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/Label.axaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Styles.Resources>
@@ -2,69 +2,73 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTheme x:Key="{x:Type TabControl}"
TargetType="TabControl">
<Setter Property="Padding"
Value="8" />
<Setter Property="BorderBrush"
Value="{DynamicResource BorderBrush}" />
<Setter Property="Background"
Value="{DynamicResource RegionBrush}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Template">
<ControlTemplate>
<Border Padding="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<DockPanel>
<ItemsPresenter Name="PART_ItemsPresenter"
ItemsPanel="{TemplateBinding ItemsPanel}" />
<DockPanel>
<ItemsPresenter Name="PART_ItemsPresenter"
ItemsPanel="{TemplateBinding ItemsPanel}" />
<Border Padding="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<ContentPresenter Name="PART_SelectedContentHost"
Margin="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding SelectedContent}"
ContentTemplate="{TemplateBinding SelectedContentTemplate}" />
</DockPanel>
</Border>
</Border>
</DockPanel>
</ControlTemplate>
</Setter>
<Style Selector="^[TabStripPlacement=Top]">
<Setter Property="Padding"
Value="0 4 0 0" />
</Style>
<Style Selector="^[TabStripPlacement=Top] /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="DockPanel.Dock"
Value="Top" />
</Style>
<Style Selector="^[TabStripPlacement=Bottom] /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="DockPanel.Dock"
Value="Bottom" />
</Style>
<Style Selector="^[TabStripPlacement=Bottom]">
<Setter Property="Padding"
Value="0 0 0 4" />
</Style>
<Style Selector="^[TabStripPlacement=Left] /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="DockPanel.Dock"
Value="Left" />
</Style>
<Style Selector="^[TabStripPlacement=Left] /template/ ItemsPresenter#PART_ItemsPresenter > WrapPanel">
<Setter Property="Orientation"
Value="Vertical" />
</Style>
<Style Selector="^[TabStripPlacement=Left]">
<Setter Property="Padding"
Value="4 0 0 0" />
</Style>
<Style Selector="^[TabStripPlacement=Right] /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="DockPanel.Dock"
Value="Right" />
</Style>
<Style Selector="^[TabStripPlacement=Right] /template/ ItemsPresenter#PART_ItemsPresenter > WrapPanel">
<Setter Property="Orientation"
Value="Vertical" />
</Style>
<Style Selector="^[TabStripPlacement=Right]">
<Setter Property="Padding"
Value="0 0 4 0" />
<Style Selector="^.inline">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<UniformGrid Rows="1"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</ControlTheme>
</ResourceDictionary>
@@ -15,31 +15,42 @@
<Setter Property="MinHeight"
Value="{StaticResource DefaultControlHeight}" />
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
Value="Center" />
<Setter Property="VerticalContentAlignment"
Value="Stretch" />
Value="Center" />
<Setter Property="Template">
<ControlTemplate TargetType="TabItem">
<Border Name="PART_LayoutRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}">
<Panel>
<ContentPresenter Name="PART_ContentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
RecognizesAccessKey="True" />
<Border Name="PART_SelectedPipe"
Background="{DynamicResource TabItemHeaderSelectedPipeFill}"
CornerRadius="{DynamicResource ControlCornerRadius}"
IsVisible="False" />
</Panel>
</Border>
<ControlTemplate>
<Panel>
<Border Name="mainBorder"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="0"
Background="{TemplateBinding Background}"
Margin="0" />
<ContentPresenter Name="PART_ContentPresenter"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
CornerRadius="{TemplateBinding CornerRadius}"
RecognizesAccessKey="True" />
</Panel>
</ControlTemplate>
</Setter>
<Style Selector="^:disabled /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Opacity"
Value="0.4" />
</Style>
<Style Selector="^:selected /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground"
Value="{DynamicResource PrimaryBrush}" />
</Style>
<Style Selector="^:selected /template/ Border#mainBorder">
<Setter Property="BorderThickness"
Value="0,0,0,2" />
</Style>
</ControlTheme>
</ResourceDictionary>
@@ -12,7 +12,7 @@
<Setter Property="Foreground"
Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="FontSize"
Value="13" />
Value="12" />
<Setter Property="Template">
<ControlTemplate TargetType="Window">
<Panel>
@@ -0,0 +1,16 @@
using System;
namespace HandyControl.Tools;
internal static class MathHelper
{
public const double Epsilon = 2.2204460492503131e-016;
public static bool AreClose(double value1, double value2) =>
// ReSharper disable once CompareOfFloatsByEqualityOperator
value1 == value2 || IsVerySmall(value1 - value2);
public static bool IsVerySmall(double value) => Math.Abs(value) < 1E-06;
public static bool GreaterThan(double value1, double value2) => value1 > value2 && !AreClose(value1, value2);
}
@@ -10720,8 +10720,8 @@
<RowDefinition x:Name="RowDefinition0" Height="Auto" />
<RowDefinition x:Name="RowDefinition1" Height="*" />
</Grid.RowDefinitions>
<TabPanel x:Name="headerPanel" Background="Transparent" Grid.Column="0" IsItemsHost="true" Margin="0" Grid.Row="0" />
<Border x:Name="contentPanel" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{DynamicResource BorderBrush}" Background="{TemplateBinding Background}" Grid.Column="0" Grid.Row="1">
<TabPanel x:Name="headerPanel" Background="Transparent" IsItemsHost="true" Margin="0" Grid.Row="0" />
<Border x:Name="contentPanel" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{DynamicResource BorderBrush}" Background="{TemplateBinding Background}" Grid.Row="1">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</Grid>
@@ -9,16 +9,12 @@ namespace HandyControl.Controls;
public class UniformSpacingPanel : Panel
{
private Orientation _orientation;
public UniformSpacingPanel()
{
_orientation = Orientation.Horizontal;
}
private Orientation _orientation = Orientation.Horizontal;
public static readonly DependencyProperty OrientationProperty =
StackPanel.OrientationProperty.AddOwner(typeof(UniformSpacingPanel),
new FrameworkPropertyMetadata(Orientation.Horizontal, FrameworkPropertyMetadataOptions.AffectsMeasure, OnOrientationChanged));
new FrameworkPropertyMetadata(Orientation.Horizontal, FrameworkPropertyMetadataOptions.AffectsMeasure,
OnOrientationChanged));
private static void OnOrientationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
@@ -132,7 +128,8 @@ public class UniformSpacingPanel : Panel
return false;
}
private void ArrangeWrapLine(double v, double lineV, int start, int end, bool useItemU, double itemU, double spacing)
private void ArrangeWrapLine(double v, double lineV, int start, int end, bool useItemU, double itemU,
double spacing)
{
double u = 0;
var isHorizontal = _orientation == Orientation.Horizontal;
@@ -191,7 +188,7 @@ public class UniformSpacingPanel : Panel
var itemHorizontalAlignment = ItemHorizontalAlignment;
var itemVerticalAlignment = ItemVerticalAlignment;
var itemHorizontalAlignmentSet = itemHorizontalAlignment != null;
var itemVerticalAlignmentSet = ItemVerticalAlignment != null;
var itemVerticalAlignmentSet = itemVerticalAlignment != null;
var spacingSize = GetSpacingSize();
var childConstraint = new Size(
@@ -201,7 +198,48 @@ public class UniformSpacingPanel : Panel
var children = InternalChildren;
var isFirst = true;
if (childWrapping == VisualWrapping.Wrap)
if (childWrapping == VisualWrapping.NoWrap)
{
var layoutSlotSize = constraint;
if (_orientation == Orientation.Horizontal)
{
layoutSlotSize.Width = double.PositiveInfinity;
}
else
{
layoutSlotSize.Height = double.PositiveInfinity;
}
for (int i = 0, count = children.Count; i < count; ++i)
{
var child = children[i];
if (child == null) continue;
if (itemHorizontalAlignmentSet)
{
child.SetCurrentValue(HorizontalAlignmentProperty, itemHorizontalAlignment);
}
if (itemVerticalAlignmentSet)
{
child.SetCurrentValue(VerticalAlignmentProperty, itemVerticalAlignment);
}
child.Measure(layoutSlotSize);
var sz = new PanelUvSize(
_orientation,
itemWidthSet ? itemWidth : child.DesiredSize.Width,
itemHeightSet ? itemHeight : child.DesiredSize.Height);
curLineSize.U += isFirst ? sz.U : sz.U + spacingSize.U;
curLineSize.V = Math.Max(sz.V, curLineSize.V);
isFirst = false;
}
}
else
{
for (int i = 0, count = children.Count; i < count; i++)
{
@@ -247,47 +285,6 @@ public class UniformSpacingPanel : Panel
}
}
}
else
{
var layoutSlotSize = constraint;
if (_orientation == Orientation.Horizontal)
{
layoutSlotSize.Width = double.PositiveInfinity;
}
else
{
layoutSlotSize.Height = double.PositiveInfinity;
}
for (int i = 0, count = children.Count; i < count; ++i)
{
var child = children[i];
if (child == null) continue;
if (itemHorizontalAlignmentSet)
{
child.SetCurrentValue(HorizontalAlignmentProperty, itemHorizontalAlignment);
}
if (itemVerticalAlignmentSet)
{
child.SetCurrentValue(VerticalAlignmentProperty, itemVerticalAlignment);
}
child.Measure(layoutSlotSize);
var sz = new PanelUvSize(
_orientation,
itemWidthSet ? itemWidth : child.DesiredSize.Width,
itemHeightSet ? itemHeight : child.DesiredSize.Height);
curLineSize.U += isFirst ? sz.U : sz.U + spacingSize.U;
curLineSize.V = Math.Max(sz.V, curLineSize.V);
isFirst = false;
}
}
panelSize.U = Math.Max(curLineSize.U, panelSize.U);
panelSize.V += curLineSize.V;
@@ -337,7 +334,11 @@ public class UniformSpacingPanel : Panel
var children = InternalChildren;
var isFirst = true;
if (childWrapping == VisualWrapping.Wrap)
if (childWrapping == VisualWrapping.NoWrap)
{
ArrangeLine(uvFinalSize.V, useItemU, itemU, spacingSize.U);
}
else
{
for (int i = 0, count = children.Count; i < count; i++)
{
@@ -369,13 +370,10 @@ public class UniformSpacingPanel : Panel
if (firstInLine < children.Count)
{
ArrangeWrapLine(accumulatedV, curLineSize.V, firstInLine, children.Count, useItemU, itemU, spacingSize.U);
ArrangeWrapLine(accumulatedV, curLineSize.V, firstInLine, children.Count, useItemU, itemU,
spacingSize.U);
}
}
else
{
ArrangeLine(uvFinalSize.V, useItemU, itemU, spacingSize.U);
}
return finalSize;
}