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);
}