mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-17 05:31:01 +08:00
Add Motion support for DataGridRowExpander
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
@@ -18,7 +19,10 @@ public sealed class DataGridDetailExpanderColumn : DataGridColumn
|
||||
|
||||
protected override Control GenerateElement(DataGridCell cell, object dataItem)
|
||||
{
|
||||
return new DataGridRowExpander();
|
||||
Debug.Assert(OwningGrid != null);
|
||||
var expander = new DataGridRowExpander();
|
||||
expander[!DataGridColumnHeader.IsMotionEnabledProperty] = OwningGrid[!DataGrid.IsMotionEnabledProperty];
|
||||
return expander;
|
||||
}
|
||||
|
||||
protected override object? PrepareCellForEdit(Control editingElement, RoutedEventArgs editingEventArgs)
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Animations;
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Data;
|
||||
using AtomUI.Theme.Styling;
|
||||
using Avalonia;
|
||||
using Avalonia.Animation;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Shapes;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Rendering;
|
||||
using Avalonia.VisualTree;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
@@ -15,25 +19,35 @@ internal class DataGridRowExpander : ToggleButton,
|
||||
IResourceBindingManager,
|
||||
ICustomHitTest
|
||||
{
|
||||
|
||||
internal static readonly DirectProperty<DataGridRowExpander, double> IndicatorThicknessProperty =
|
||||
AvaloniaProperty.RegisterDirect<DataGridRowExpander, double>(
|
||||
nameof(IndicatorThickness),
|
||||
o => o.IndicatorThickness,
|
||||
(o, v) => o.IndicatorThickness = v);
|
||||
|
||||
|
||||
internal static readonly StyledProperty<bool> IsMotionEnabledProperty =
|
||||
MotionAwareControlProperty.IsMotionEnabledProperty.AddOwner<DataGridRowExpander>();
|
||||
|
||||
internal double IndicatorThickness
|
||||
{
|
||||
get => _indicatorThickness;
|
||||
set => SetAndRaise(IndicatorThicknessProperty, ref _indicatorThickness, value);
|
||||
}
|
||||
|
||||
private double _indicatorThickness;
|
||||
|
||||
|
||||
internal bool IsMotionEnabled
|
||||
{
|
||||
get => GetValue(IsMotionEnabledProperty);
|
||||
set => SetValue(IsMotionEnabledProperty, value);
|
||||
}
|
||||
|
||||
private CompositeDisposable? _resourceBindingsDisposable;
|
||||
CompositeDisposable? IResourceBindingManager.ResourceBindingsDisposable => _resourceBindingsDisposable;
|
||||
|
||||
private Rectangle? _horizontalIndicator;
|
||||
private Rectangle? _verticalIndicator;
|
||||
private Border? _frame;
|
||||
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
@@ -45,6 +59,31 @@ internal class DataGridRowExpander : ToggleButton,
|
||||
new RenderScaleAwareThicknessConfigure(this)));
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
var size = base.ArrangeOverride(finalSize);
|
||||
var delta = IndicatorThickness / 2;
|
||||
if (_verticalIndicator != null)
|
||||
{
|
||||
var indicatorSize = _verticalIndicator.DesiredSize;
|
||||
var x = (finalSize.Width - indicatorSize.Width) / 2 - delta;
|
||||
var y = (finalSize.Height - indicatorSize.Height) / 2 - delta;
|
||||
Canvas.SetLeft(_verticalIndicator, x);
|
||||
Canvas.SetTop(_verticalIndicator, y);
|
||||
}
|
||||
|
||||
if (_horizontalIndicator != null)
|
||||
{
|
||||
var indicatorSize = _horizontalIndicator.DesiredSize;
|
||||
var x = (finalSize.Width - indicatorSize.Width) / 2 - delta;
|
||||
var y = (finalSize.Height - indicatorSize.Height) / 2 - delta;
|
||||
Canvas.SetLeft(_horizontalIndicator, x);
|
||||
Canvas.SetTop(_horizontalIndicator, y);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
@@ -52,6 +91,14 @@ internal class DataGridRowExpander : ToggleButton,
|
||||
{
|
||||
IndicatorThickness = BorderThickness.Left;
|
||||
}
|
||||
|
||||
if (this.IsAttachedToVisualTree())
|
||||
{
|
||||
if (change.Property == IsMotionEnabledProperty)
|
||||
{
|
||||
ConfigureTransitions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
@@ -65,10 +112,62 @@ internal class DataGridRowExpander : ToggleButton,
|
||||
base.OnApplyTemplate(e);
|
||||
_verticalIndicator = e.NameScope.Find<Rectangle>(DataGridRowExpanderThemeConstants.VerticalIndicatorPart);
|
||||
_horizontalIndicator = e.NameScope.Find<Rectangle>(DataGridRowExpanderThemeConstants.HorizontalIndicatorPart);
|
||||
_frame = e.NameScope.Find<Border>(DataGridRowExpanderThemeConstants.FramePart);
|
||||
ConfigureTransitions();
|
||||
}
|
||||
|
||||
public bool HitTest(Point point)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ConfigureTransitions()
|
||||
{
|
||||
if (IsMotionEnabled)
|
||||
{
|
||||
if (_frame != null)
|
||||
{
|
||||
_frame.Transitions = new Transitions()
|
||||
{
|
||||
TransitionUtils.CreateTransition<SolidColorBrushTransition>(Border.BorderBrushProperty)
|
||||
};
|
||||
}
|
||||
|
||||
if (_verticalIndicator != null)
|
||||
{
|
||||
_verticalIndicator.Transitions = new Transitions()
|
||||
{
|
||||
TransitionUtils.CreateTransition<SolidColorBrushTransition>(Rectangle.FillProperty),
|
||||
TransitionUtils.CreateTransition<TransformOperationsTransition>(Visual.RenderTransformProperty)
|
||||
};
|
||||
}
|
||||
|
||||
if (_horizontalIndicator != null)
|
||||
{
|
||||
_horizontalIndicator.Transitions = new Transitions()
|
||||
{
|
||||
TransitionUtils.CreateTransition<SolidColorBrushTransition>(Rectangle.FillProperty),
|
||||
TransitionUtils.CreateTransition<TransformOperationsTransition>(Visual.RenderTransformProperty)
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_frame != null)
|
||||
{
|
||||
_frame.Transitions?.Clear();
|
||||
_frame.Transitions = null;
|
||||
}
|
||||
if (_verticalIndicator != null)
|
||||
{
|
||||
_verticalIndicator.Transitions?.Clear();
|
||||
_verticalIndicator.Transitions = null;
|
||||
}
|
||||
if (_horizontalIndicator != null)
|
||||
{
|
||||
_horizontalIndicator.Transitions?.Clear();
|
||||
_horizontalIndicator.Transitions = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,30 +7,33 @@
|
||||
<ControlTemplate>
|
||||
<Border Name="{x:Static atom:DataGridRowExpanderThemeConstants.FramePart}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}">
|
||||
<Panel>
|
||||
<Canvas VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
|
||||
<Rectangle Name="{x:Static atom:DataGridRowExpanderThemeConstants.HorizontalIndicatorPart}"
|
||||
Height="{TemplateBinding IndicatorThickness}"
|
||||
Height="1"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
<Rectangle Name="{x:Static atom:DataGridRowExpanderThemeConstants.VerticalIndicatorPart}"
|
||||
Width="{TemplateBinding IndicatorThickness}"
|
||||
Width="1"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Panel>
|
||||
</Canvas>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
|
||||
<Style Selector="^ /template/ Border#PART_Frame">
|
||||
<Setter Property="CornerRadius" Value="{DynamicResource {x:Static atom:SharedTokenKey.BorderRadiusSM}}"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource {x:Static atom:DataGridTokenKey.TableBorderColor}}"/>
|
||||
<Setter Property="Width" Value="{DynamicResource {x:Static atom:SharedTokenKey.SizeMS}}"/>
|
||||
<Setter Property="Height" Value="{DynamicResource {x:Static atom:SharedTokenKey.SizeMS}}"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^ /template/ Rectangle">
|
||||
<Setter Property="Fill" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorText}}"/>
|
||||
<Setter Property="Fill" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorTextSecondary}}"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:focus">
|
||||
@@ -61,11 +64,23 @@
|
||||
</Style>
|
||||
|
||||
<Style Selector="^ /template/ Rectangle#PART_VerticalIndicator">
|
||||
<Setter Property="Height" Value="{DynamicResource {x:Static atom:SharedTokenKey.SizeXS}}"/>
|
||||
<Setter Property="Height" Value="9"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^ /template/ Rectangle#PART_HorizontalIndicator">
|
||||
<Setter Property="Width" Value="{DynamicResource {x:Static atom:SharedTokenKey.SizeXS}}"/>
|
||||
<Setter Property="Width" Value="9"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsChecked=True]">
|
||||
<Style Selector="^ /template/ Rectangle#PART_VerticalIndicator">
|
||||
<Setter Property="Opacity" Value="0"/>
|
||||
<Setter Property="RenderTransform" Value="rotate(90deg)"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^ /template/ Rectangle#PART_HorizontalIndicator">
|
||||
<Setter Property="RenderTransform" Value="rotate(180deg)"/>
|
||||
</Style>
|
||||
</Style>
|
||||
|
||||
</ControlTheme>
|
||||
</ResourceDictionary>
|
||||
Reference in New Issue
Block a user