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.Controls.ApplicationLifetimes;
using Avalonia.Data.Core.Plugins; using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
@@ -6,7 +7,7 @@ using Avalonia.Markup.Xaml;
namespace HandyControlDemo; namespace HandyControlDemo;
public partial class App : Application public class App : Application
{ {
public override void Initialize() public override void Initialize()
{ {
@@ -15,6 +16,7 @@ public partial class App : Application
public override void OnFrameworkInitializationCompleted() public override void OnFrameworkInitializationCompleted()
{ {
Properties.Langs.Lang.Culture = new CultureInfo("en");
BindingPlugins.DataValidators.RemoveAt(0); BindingPlugins.DataValidators.RemoveAt(0);
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
@@ -1,7 +1,7 @@
[ [
{ {
"title": "Styles", "title": "Styles",
"selectedIndex": 0, "selectedIndex": -1,
"group": false, "group": false,
"demoItemList": [ "demoItemList": [
[ "Brush", "BrushDemoCtl", "Brush.Brush", "", "" ], [ "Brush", "BrushDemoCtl", "Brush.Brush", "", "" ],
@@ -57,6 +57,10 @@
<Compile Update="Views\Styles\ButtonDemoCtrl.axaml.cs"> <Compile Update="Views\Styles\ButtonDemoCtrl.axaml.cs">
<DependentUpon>ButtonDemoCtrl.axaml</DependentUpon> <DependentUpon>ButtonDemoCtrl.axaml</DependentUpon>
</Compile> </Compile>
<Compile Update="UserControl\Styles\BrushDemoCtl.axaml.cs">
<DependentUpon>BoderDemoCtl.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -6,46 +6,55 @@
Margin="16,16,0,16" Margin="16,16,0,16"
CornerRadius="10" CornerRadius="10"
Effect="{StaticResource EffectShadow4}"> Effect="{StaticResource EffectShadow4}">
<TabControl BorderThickness="0 1 0 0" <DockPanel>
SelectionChanged="TabControl_OnSelectionChanged" <Button Content="Practical demos"
ItemsSource="{Binding DemoInfoCollection}" DockPanel.Dock="Top"
Background="Transparent" HorizontalAlignment="Stretch"
SelectedIndex="0"> Margin="10,10,10,4"
<TabControl.ItemTemplate> BorderThickness="0"
<DataTemplate DataType="data:DemoInfoModel"> Background="{DynamicResource SecondaryRegionBrush}" />
<TextBlock Text="{Binding Title}" /> <TabControl BorderThickness="0 1 0 0"
</DataTemplate> Classes="inline"
</TabControl.ItemTemplate> SelectionChanged="TabControl_OnSelectionChanged"
<TabControl.ContentTemplate> ItemsSource="{Binding DemoInfoCollection}"
<DataTemplate DataType="data:DemoInfoModel"> Background="Transparent"
<Panel Margin="10"> SelectedIndex="0">
<ListBox SelectionMode="Single" <TabControl.ItemTemplate>
Padding="0" <DataTemplate DataType="data:DemoInfoModel">
BorderThickness="0" <TextBlock Text="{Binding Title}" />
SelectedIndex="{Binding SelectedIndex}" </DataTemplate>
ItemsSource="{Binding DemoItemList}"> </TabControl.ItemTemplate>
<ListBox.ItemTemplate> <TabControl.ContentTemplate>
<DataTemplate DataType="data:DemoItemModel"> <DataTemplate DataType="data:DemoInfoModel">
<StackPanel Orientation="Horizontal"> <Panel Margin="10">
<Rectangle Width="16" <ListBox SelectionMode="Single"
Height="16" Padding="0"
Fill="{Binding ImageBrush}" /> BorderThickness="0"
<TextBlock Margin="6,0,0,0" SelectedIndex="{Binding SelectedIndex}"
Text="{Binding Name}" /> ItemsSource="{Binding DemoItemList}">
<Path IsVisible="{Binding IsNew}" <ListBox.ItemTemplate>
VerticalAlignment="Center" <DataTemplate DataType="data:DemoItemModel">
Data="{StaticResource NewGeometry}" <StackPanel Orientation="Horizontal">
Stretch="Uniform" <Rectangle Width="16"
Margin="10,0,0,0" Height="16"
Width="30" Fill="{Binding ImageBrush}" />
Height="14" <TextBlock Margin="6,0,0,0"
Fill="{DynamicResource AccentBrush}" /> Text="{Binding Name}" />
</StackPanel> <Path IsVisible="{Binding IsNew}"
</DataTemplate> VerticalAlignment="Center"
</ListBox.ItemTemplate> Data="{StaticResource NewGeometry}"
</ListBox> Stretch="Uniform"
</Panel> Margin="10,0,0,0"
</DataTemplate> Width="30"
</TabControl.ContentTemplate> Height="14"
</TabControl> Fill="{DynamicResource AccentBrush}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Panel>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</DockPanel>
</UserControl> </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" <UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 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" x:Class="HandyControlDemo.UserControl.ButtonDemoCtl"
xmlns:hc="https://handyorg.github.io/handycontrol"
Background="{DynamicResource RegionBrush}"> Background="{DynamicResource RegionBrush}">
<ScrollViewer> <ScrollViewer>
<StackPanel Orientation="Horizontal" <hc:UniformSpacingPanel ChildWrapping="Wrap"
VerticalAlignment="Top" Spacing="32"
Spacing="4" Margin="32">
Margin="32"> <hc:UniformSpacingPanel Orientation="Vertical"
<Button Content="default" /> Spacing="32">
<Button Content="primary" <WrapPanel>
Classes="primary" /> <StackPanel>
<Button Content="success" <Button Content="default"
Classes="success" /> Margin="5" />
<Button Content="info" <Button IsEnabled="False"
Classes="info" /> Content="default"
<Button Content="warning" Margin="5" />
Classes="warning" /> </StackPanel>
<Button Content="danger" <StackPanel>
Classes="danger" /> <Button Content="primary"
</StackPanel> 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> </ScrollViewer>
</UserControl> </UserControl>
@@ -69,7 +69,7 @@ public class MainViewModel : DemoViewModelBase<DemoDataModel>
return; return;
} }
ContentTitle = Lang.ResourceManager.GetString(DemoItemCurrent.Name); ContentTitle = Lang.ResourceManager.GetString(DemoItemCurrent.Name, Lang.Culture);
}); });
//load items //load items
@@ -91,7 +91,7 @@ public class MainViewModel : DemoViewModelBase<DemoDataModel>
} }
DemoItemCurrent = item; 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}"); object? demoControl = AssemblyHelper.ResolveByKey(item.TargetCtlName) ?? AssemblyHelper.CreateInternalInstance($"UserControl.{item.TargetCtlName}");
SubContent = demoControl; 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> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)" /> <PackageReference Include="Avalonia" Version="$(AvaloniaVersion)"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -26,7 +26,4 @@
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
</Project> </Project>
@@ -1,19 +1,11 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui" <ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTheme x:Key="{x:Type Button}" <ControlTheme x:Key="ButtonBaseStyle"
TargetType="Button"> TargetType="Button">
<Setter Property="Background" <Setter Property="Height"
Value="{DynamicResource RegionBrush}" /> Value="{StaticResource DefaultControlHeight}" />
<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="Padding" <Setter Property="Padding"
Value="{DynamicResource DefaultControlPadding}" /> Value="{StaticResource DefaultControlPadding}" />
<Setter Property="HorizontalAlignment" <Setter Property="HorizontalAlignment"
Value="Center" /> Value="Center" />
<Setter Property="VerticalAlignment" <Setter Property="VerticalAlignment"
@@ -22,8 +14,18 @@
Value="Center" /> Value="Center" />
<Setter Property="VerticalContentAlignment" <Setter Property="VerticalContentAlignment"
Value="Center" /> 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"> <Setter Property="Template">
<ControlTemplate TargetType="Button"> <ControlTemplate>
<ContentPresenter x:Name="PART_ContentPresenter" <ContentPresenter x:Name="PART_ContentPresenter"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
@@ -38,104 +40,85 @@
</ControlTemplate> </ControlTemplate>
</Setter> </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" <Setter Property="Background"
Value="{DynamicResource SecondaryRegionBrush}" /> Value="{DynamicResource SecondaryRegionBrush}" />
</Style> </Style>
<Style Selector="^:pressed"> <Style Selector="^:pressed /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" <Setter Property="Background"
Value="{DynamicResource BorderBrush}" /> Value="{DynamicResource BorderBrush}" />
</Style> </Style>
</ControlTheme>
<Style Selector="^:disabled"> <ControlTheme x:Key="{x:Type Button}"
<Setter Property="Opacity" BasedOn="{StaticResource ButtonDefault}"
Value=".4" /> TargetType="Button" />
</Style>
<Style Selector="^.primary"> <ControlTheme x:Key="ButtonPrimary"
<Setter Property="Foreground" BasedOn="{StaticResource ButtonBaseStyle}"
Value="{DynamicResource TextIconBrush}" /> TargetType="Button">
<Setter Property="Background" <Setter Property="Background"
Value="{DynamicResource PrimaryBrush}" /> Value="{DynamicResource PrimaryBrush}" />
<Setter Property="BorderBrush" <Setter Property="BorderBrush"
Value="{DynamicResource PrimaryBrush}" /> Value="{DynamicResource PrimaryBrush}" />
<Style Selector="^:pointerover"> </ControlTheme>
<Setter Property="Opacity"
Value=".9" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Opacity"
Value=".6" />
</Style>
</Style>
<Style Selector="^.success"> <ControlTheme x:Key="ButtonSuccess"
<Setter Property="Foreground" BasedOn="{StaticResource ButtonBaseStyle}"
Value="{DynamicResource TextIconBrush}" /> TargetType="Button">
<Setter Property="Background" <Setter Property="Background"
Value="{DynamicResource SuccessBrush}" /> Value="{DynamicResource SuccessBrush}" />
<Setter Property="BorderBrush" <Setter Property="BorderBrush"
Value="{DynamicResource SuccessBrush}" /> Value="{DynamicResource SuccessBrush}" />
<Style Selector="^:pointerover"> </ControlTheme>
<Setter Property="Opacity"
Value=".9" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Opacity"
Value=".6" />
</Style>
</Style>
<Style Selector="^.info"> <ControlTheme x:Key="ButtonInfo"
<Setter Property="Foreground" BasedOn="{StaticResource ButtonBaseStyle}"
Value="{DynamicResource TextIconBrush}" /> TargetType="Button">
<Setter Property="Background" <Setter Property="Background"
Value="{DynamicResource InfoBrush}" /> Value="{DynamicResource InfoBrush}" />
<Setter Property="BorderBrush" <Setter Property="BorderBrush"
Value="{DynamicResource InfoBrush}" /> Value="{DynamicResource InfoBrush}" />
<Style Selector="^:pointerover"> </ControlTheme>
<Setter Property="Opacity"
Value=".9" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Opacity"
Value=".6" />
</Style>
</Style>
<Style Selector="^.warning"> <ControlTheme x:Key="ButtonWarning"
<Setter Property="Foreground" BasedOn="{StaticResource ButtonBaseStyle}"
Value="{DynamicResource TextIconBrush}" /> TargetType="Button">
<Setter Property="Background" <Setter Property="Background"
Value="{DynamicResource WarningBrush}" /> Value="{DynamicResource WarningBrush}" />
<Setter Property="BorderBrush" <Setter Property="BorderBrush"
Value="{DynamicResource WarningBrush}" /> Value="{DynamicResource WarningBrush}" />
<Style Selector="^:pointerover"> </ControlTheme>
<Setter Property="Opacity"
Value=".9" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Opacity"
Value=".6" />
</Style>
</Style>
<Style Selector="^.danger"> <ControlTheme x:Key="ButtonDanger"
<Setter Property="Foreground" BasedOn="{StaticResource ButtonBaseStyle}"
Value="{DynamicResource TextIconBrush}" /> TargetType="Button">
<Setter Property="Background" <Setter Property="Background"
Value="{DynamicResource DangerBrush}" /> Value="{DynamicResource DangerBrush}" />
<Setter Property="BorderBrush" <Setter Property="BorderBrush"
Value="{DynamicResource DangerBrush}" /> Value="{DynamicResource DangerBrush}" />
<Style Selector="^:pointerover">
<Setter Property="Opacity"
Value=".9" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Opacity"
Value=".6" />
</Style>
</Style>
</ControlTheme> </ControlTheme>
</ResourceDictionary> </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}" /> Value="{DynamicResource BorderBrush}" />
<Setter Property="BorderThickness" <Setter Property="BorderThickness"
Value="1" /> Value="1" />
<Setter Property="CornerRadius"
Value="{StaticResource DefaultCornerRadius}" />
<Setter Property="Padding" <Setter Property="Padding"
Value="4" /> Value="4" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" <Setter Property="ScrollViewer.HorizontalScrollBarVisibility"
@@ -1,5 +1,6 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui" <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}" <ControlTheme x:Key="{x:Type ListBoxItem}"
TargetType="ListBoxItem"> TargetType="ListBoxItem">
<Setter Property="Padding" <Setter Property="Padding"
@@ -12,6 +13,8 @@
Value="{DynamicResource RegionBrush}" /> Value="{DynamicResource RegionBrush}" />
<Setter Property="BorderBrush" <Setter Property="BorderBrush"
Value="Transparent" /> Value="Transparent" />
<Setter Property="CornerRadius"
Value="{StaticResource DefaultCornerRadius}" />
<Setter Property="BorderThickness" <Setter Property="BorderThickness"
Value="0" /> Value="0" />
<Setter Property="Margin" <Setter Property="Margin"
@@ -33,27 +36,14 @@
<Style Selector="^:pointerover /template/ ContentPresenter"> <Style Selector="^:pointerover /template/ ContentPresenter">
<Setter Property="Background" <Setter Property="Background"
Value="{DynamicResource ThemeControlHighlightMidBrush}" /> Value="{DynamicResource SecondaryRegionBrush}" />
</Style> </Style>
<Style Selector="^:selected /template/ ContentPresenter"> <Style Selector="^:selected /template/ ContentPresenter">
<Setter Property="Background" <Setter Property="Background"
Value="{DynamicResource ThemeAccentBrush4}" /> Value="{DynamicResource PrimaryBrush}" />
</Style> <Setter Property="Foreground"
Value="{DynamicResource TextIconBrush}" />
<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}" />
</Style> </Style>
</ControlTheme> </ControlTheme>
</ResourceDictionary> </ResourceDictionary>
@@ -17,6 +17,7 @@
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/ListBox.axaml" /> <MergeResourceInclude Source="avares://HandyControl/Themes/Styles/ListBox.axaml" />
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/ScrollBar.axaml" /> <MergeResourceInclude Source="avares://HandyControl/Themes/Styles/ScrollBar.axaml" />
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/ScrollViewer.axaml" /> <MergeResourceInclude Source="avares://HandyControl/Themes/Styles/ScrollViewer.axaml" />
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/Label.axaml" />
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </ResourceDictionary>
</Styles.Resources> </Styles.Resources>
@@ -2,69 +2,73 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTheme x:Key="{x:Type TabControl}" <ControlTheme x:Key="{x:Type TabControl}"
TargetType="TabControl"> TargetType="TabControl">
<Setter Property="Padding" <Setter Property="BorderBrush"
Value="8" /> Value="{DynamicResource BorderBrush}" />
<Setter Property="Background"
Value="{DynamicResource RegionBrush}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border Padding="{TemplateBinding Padding}" <DockPanel>
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" <ItemsPresenter Name="PART_ItemsPresenter"
VerticalAlignment="{TemplateBinding VerticalAlignment}" ItemsPanel="{TemplateBinding ItemsPanel}" />
Background="{TemplateBinding Background}" <Border Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
BorderThickness="{TemplateBinding BorderThickness}" VerticalAlignment="{TemplateBinding VerticalAlignment}"
CornerRadius="{TemplateBinding CornerRadius}"> Background="{TemplateBinding Background}"
<DockPanel> BorderBrush="{TemplateBinding BorderBrush}"
<ItemsPresenter Name="PART_ItemsPresenter" BorderThickness="{TemplateBinding BorderThickness}"
ItemsPanel="{TemplateBinding ItemsPanel}" /> CornerRadius="{TemplateBinding CornerRadius}">
<ContentPresenter Name="PART_SelectedContentHost" <ContentPresenter Name="PART_SelectedContentHost"
Margin="{TemplateBinding Padding}" Margin="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding SelectedContent}" Content="{TemplateBinding SelectedContent}"
ContentTemplate="{TemplateBinding SelectedContentTemplate}" /> ContentTemplate="{TemplateBinding SelectedContentTemplate}" />
</DockPanel> </Border>
</Border> </DockPanel>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
<Style Selector="^[TabStripPlacement=Top]">
<Setter Property="Padding"
Value="0 4 0 0" />
</Style>
<Style Selector="^[TabStripPlacement=Top] /template/ ItemsPresenter#PART_ItemsPresenter"> <Style Selector="^[TabStripPlacement=Top] /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="DockPanel.Dock" <Setter Property="DockPanel.Dock"
Value="Top" /> Value="Top" />
</Style> </Style>
<Style Selector="^[TabStripPlacement=Bottom] /template/ ItemsPresenter#PART_ItemsPresenter"> <Style Selector="^[TabStripPlacement=Bottom] /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="DockPanel.Dock" <Setter Property="DockPanel.Dock"
Value="Bottom" /> Value="Bottom" />
</Style> </Style>
<Style Selector="^[TabStripPlacement=Bottom]">
<Setter Property="Padding"
Value="0 0 0 4" />
</Style>
<Style Selector="^[TabStripPlacement=Left] /template/ ItemsPresenter#PART_ItemsPresenter"> <Style Selector="^[TabStripPlacement=Left] /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="DockPanel.Dock" <Setter Property="DockPanel.Dock"
Value="Left" /> Value="Left" />
</Style> </Style>
<Style Selector="^[TabStripPlacement=Left] /template/ ItemsPresenter#PART_ItemsPresenter > WrapPanel"> <Style Selector="^[TabStripPlacement=Left] /template/ ItemsPresenter#PART_ItemsPresenter > WrapPanel">
<Setter Property="Orientation" <Setter Property="Orientation"
Value="Vertical" /> Value="Vertical" />
</Style> </Style>
<Style Selector="^[TabStripPlacement=Left]">
<Setter Property="Padding"
Value="4 0 0 0" />
</Style>
<Style Selector="^[TabStripPlacement=Right] /template/ ItemsPresenter#PART_ItemsPresenter"> <Style Selector="^[TabStripPlacement=Right] /template/ ItemsPresenter#PART_ItemsPresenter">
<Setter Property="DockPanel.Dock" <Setter Property="DockPanel.Dock"
Value="Right" /> Value="Right" />
</Style> </Style>
<Style Selector="^[TabStripPlacement=Right] /template/ ItemsPresenter#PART_ItemsPresenter > WrapPanel"> <Style Selector="^[TabStripPlacement=Right] /template/ ItemsPresenter#PART_ItemsPresenter > WrapPanel">
<Setter Property="Orientation" <Setter Property="Orientation"
Value="Vertical" /> Value="Vertical" />
</Style> </Style>
<Style Selector="^[TabStripPlacement=Right]">
<Setter Property="Padding" <Style Selector="^.inline">
Value="0 0 4 0" /> <Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<UniformGrid Rows="1"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style> </Style>
</ControlTheme> </ControlTheme>
</ResourceDictionary> </ResourceDictionary>
@@ -15,31 +15,42 @@
<Setter Property="MinHeight" <Setter Property="MinHeight"
Value="{StaticResource DefaultControlHeight}" /> Value="{StaticResource DefaultControlHeight}" />
<Setter Property="HorizontalContentAlignment" <Setter Property="HorizontalContentAlignment"
Value="Stretch" /> Value="Center" />
<Setter Property="VerticalContentAlignment" <Setter Property="VerticalContentAlignment"
Value="Stretch" /> Value="Center" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate TargetType="TabItem"> <ControlTemplate>
<Border Name="PART_LayoutRoot" <Panel>
Background="{TemplateBinding Background}" <Border Name="mainBorder"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="0"
CornerRadius="{TemplateBinding CornerRadius}" Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"> Margin="0" />
<Panel> <ContentPresenter Name="PART_ContentPresenter"
<ContentPresenter Name="PART_ContentPresenter" Padding="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Header}" Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}" ContentTemplate="{TemplateBinding HeaderTemplate}"
RecognizesAccessKey="True" /> CornerRadius="{TemplateBinding CornerRadius}"
<Border Name="PART_SelectedPipe" RecognizesAccessKey="True" />
Background="{DynamicResource TabItemHeaderSelectedPipeFill}" </Panel>
CornerRadius="{DynamicResource ControlCornerRadius}"
IsVisible="False" />
</Panel>
</Border>
</ControlTemplate> </ControlTemplate>
</Setter> </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> </ControlTheme>
</ResourceDictionary> </ResourceDictionary>
@@ -12,7 +12,7 @@
<Setter Property="Foreground" <Setter Property="Foreground"
Value="{DynamicResource PrimaryTextBrush}" /> Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="FontSize" <Setter Property="FontSize"
Value="13" /> Value="12" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate TargetType="Window"> <ControlTemplate TargetType="Window">
<Panel> <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="RowDefinition0" Height="Auto" />
<RowDefinition x:Name="RowDefinition1" Height="*" /> <RowDefinition x:Name="RowDefinition1" Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TabPanel x:Name="headerPanel" Background="Transparent" Grid.Column="0" IsItemsHost="true" Margin="0" Grid.Row="0" /> <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.Column="0" Grid.Row="1"> <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}" /> <ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border> </Border>
</Grid> </Grid>
@@ -9,16 +9,12 @@ namespace HandyControl.Controls;
public class UniformSpacingPanel : Panel public class UniformSpacingPanel : Panel
{ {
private Orientation _orientation; private Orientation _orientation = Orientation.Horizontal;
public UniformSpacingPanel()
{
_orientation = Orientation.Horizontal;
}
public static readonly DependencyProperty OrientationProperty = public static readonly DependencyProperty OrientationProperty =
StackPanel.OrientationProperty.AddOwner(typeof(UniformSpacingPanel), 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) private static void OnOrientationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ {
@@ -132,7 +128,8 @@ public class UniformSpacingPanel : Panel
return false; 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; double u = 0;
var isHorizontal = _orientation == Orientation.Horizontal; var isHorizontal = _orientation == Orientation.Horizontal;
@@ -191,7 +188,7 @@ public class UniformSpacingPanel : Panel
var itemHorizontalAlignment = ItemHorizontalAlignment; var itemHorizontalAlignment = ItemHorizontalAlignment;
var itemVerticalAlignment = ItemVerticalAlignment; var itemVerticalAlignment = ItemVerticalAlignment;
var itemHorizontalAlignmentSet = itemHorizontalAlignment != null; var itemHorizontalAlignmentSet = itemHorizontalAlignment != null;
var itemVerticalAlignmentSet = ItemVerticalAlignment != null; var itemVerticalAlignmentSet = itemVerticalAlignment != null;
var spacingSize = GetSpacingSize(); var spacingSize = GetSpacingSize();
var childConstraint = new Size( var childConstraint = new Size(
@@ -201,7 +198,48 @@ public class UniformSpacingPanel : Panel
var children = InternalChildren; var children = InternalChildren;
var isFirst = true; 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++) 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.U = Math.Max(curLineSize.U, panelSize.U);
panelSize.V += curLineSize.V; panelSize.V += curLineSize.V;
@@ -337,7 +334,11 @@ public class UniformSpacingPanel : Panel
var children = InternalChildren; var children = InternalChildren;
var isFirst = true; 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++) for (int i = 0, count = children.Count; i < count; i++)
{ {
@@ -369,13 +370,10 @@ public class UniformSpacingPanel : Panel
if (firstInLine < children.Count) 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; return finalSize;
} }