Refactor Transitions configure

This commit is contained in:
chinboy
2025-10-28 10:06:44 +08:00
parent f7cf6dee05
commit 8ba714f436
13 changed files with 165 additions and 280 deletions
@@ -37,6 +37,9 @@ internal class PaletteColorItem : AvaloniaRadioButton
internal static readonly StyledProperty<bool> IsMotionEnabledProperty =
MotionAwareControlProperty.IsMotionEnabledProperty.AddOwner<PaletteColorItem>();
internal static readonly StyledProperty<ITransform?> CheckedMarkRenderTransformProperty =
AvaloniaProperty.Register<PaletteColorItem, ITransform?>(nameof (CheckedMarkRenderTransform));
internal static readonly DirectProperty<PaletteColorItem, bool> IsLightColorProperty =
AvaloniaProperty.RegisterDirect<PaletteColorItem, bool>(
nameof(IsLightColor),
@@ -48,6 +51,12 @@ internal class PaletteColorItem : AvaloniaRadioButton
get => GetValue(IsMotionEnabledProperty);
set => SetValue(IsMotionEnabledProperty, value);
}
internal ITransform? CheckedMarkRenderTransform
{
get => GetValue(CheckedMarkRenderTransformProperty);
set => SetValue(CheckedMarkRenderTransformProperty, value);
}
private bool _isLightColor;
@@ -58,7 +67,6 @@ internal class PaletteColorItem : AvaloniaRadioButton
}
#endregion
private Icon? _checkedMark;
private IDisposable? _borderThicknessDisposable;
static PaletteColorItem()
@@ -84,7 +92,6 @@ internal class PaletteColorItem : AvaloniaRadioButton
if (change.Property == IsMotionEnabledProperty)
{
ConfigureTransitions(true);
ConfigureCheckedMarkTransitions(true);
}
}
}
@@ -104,30 +111,6 @@ internal class PaletteColorItem : AvaloniaRadioButton
_borderThicknessDisposable?.Dispose();
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
_checkedMark = e.NameScope.Find<Icon>(PaletteColorItemThemeConstants.CheckedMarkPart);
if (_checkedMark != null)
{
_checkedMark.Loaded += HandleCheckedMarkLoaded;
_checkedMark.Unloaded += HandleCheckedMarkUnLoaded;
}
}
private void HandleCheckedMarkLoaded(object? sender, RoutedEventArgs e)
{
ConfigureCheckedMarkTransitions(false);
}
private void HandleCheckedMarkUnLoaded(object? sender, RoutedEventArgs e)
{
if (_checkedMark != null)
{
_checkedMark.Transitions = null;
}
}
private void ConfigureTransitions(bool force)
{
if (IsMotionEnabled)
@@ -136,6 +119,8 @@ internal class PaletteColorItem : AvaloniaRadioButton
{
Transitions = [
TransitionUtils.CreateTransition<SolidColorBrushTransition>(BorderBrushProperty),
TransitionUtils.CreateTransition<TransformOperationsTransition>(CheckedMarkRenderTransformProperty, SharedTokenKey.MotionDurationMid,
new BackEaseOut())
];
}
}
@@ -145,30 +130,6 @@ internal class PaletteColorItem : AvaloniaRadioButton
}
}
private void ConfigureCheckedMarkTransitions(bool force)
{
if (IsMotionEnabled)
{
if (_checkedMark != null)
{
if (force || _checkedMark.Transitions == null)
{
_checkedMark.Transitions = [
TransitionUtils.CreateTransition<TransformOperationsTransition>(RenderTransformProperty, SharedTokenKey.MotionDurationMid,
new BackEaseOut()),
];
}
}
}
else
{
if (_checkedMark != null)
{
_checkedMark.Transitions = null;
}
}
}
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
@@ -19,7 +19,9 @@
IconInfo="{atom:IconInfoProvider CheckBoldOutlined}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsVisible="False" />
IsVisible="False"
RenderTransform="{TemplateBinding CheckedMarkRenderTransform}"
RenderTransformOrigin="{x:Static RelativePoint.Center}"/>
</Border>
</Border>
</ControlTemplate>
@@ -43,14 +45,15 @@
<Style Selector="^ /template/ atom|Icon#PART_CheckedMark">
<Setter Property="Width" Value="{DynamicResource {x:Static atom:ColorPickerTokenKey.CheckedMarkSize}}" />
<Setter Property="Height" Value="{DynamicResource {x:Static atom:ColorPickerTokenKey.CheckedMarkSize}}" />
<Setter Property="RenderTransform" Value="scale(0.1)"/>
</Style>
<Setter Property="CheckedMarkRenderTransform" Value="scale(0.1)"/>
<Style Selector="^[IsChecked=True]">
<Style Selector="^ /template/ atom|Icon#PART_CheckedMark">
<Setter Property="IsVisible" Value="True" />
<Setter Property="RenderTransform" Value="scale(1.0)"/>
</Style>
<Setter Property="CheckedMarkRenderTransform" Value="scale(1.0)"/>
</Style>
<Style Selector="^[IsLightColor=True]">
@@ -53,6 +53,9 @@ internal class CarouselPageIndicator : ContentControl, ISelectable
#endregion
internal static readonly StyledProperty<double> FrameOpacityProperty =
AvaloniaProperty.Register<CarouselPageIndicator, double>(nameof(FrameOpacity));
internal static readonly DirectProperty<CarouselPageIndicator, double> ProgressValueProperty =
AvaloniaProperty.RegisterDirect<CarouselPageIndicator, double>(
nameof(ProgressValue),
@@ -64,6 +67,12 @@ internal class CarouselPageIndicator : ContentControl, ISelectable
nameof(EffectiveProgressWidth),
o => o.EffectiveProgressWidth,
(o, v) => o.EffectiveProgressWidth = v);
internal double FrameOpacity
{
get => GetValue(FrameOpacityProperty);
set => SetValue(FrameOpacityProperty, value);
}
private double _progressValue;
@@ -106,7 +115,6 @@ internal class CarouselPageIndicator : ContentControl, ISelectable
if (change.Property == IsMotionEnabledProperty)
{
ConfigureTransitions(true);
ConfigureFrameTransitions(true);
}
}
@@ -134,10 +142,11 @@ internal class CarouselPageIndicator : ContentControl, ISelectable
{
if (force || Transitions == null)
{
Transitions = new Transitions()
{
TransitionUtils.CreateTransition<DoubleTransition>(WidthProperty)
};
Transitions =
[
TransitionUtils.CreateTransition<DoubleTransition>(WidthProperty),
TransitionUtils.CreateTransition<DoubleTransition>(FrameOpacityProperty)
];
}
}
else
@@ -162,17 +171,6 @@ internal class CarouselPageIndicator : ContentControl, ISelectable
{
base.OnApplyTemplate(e);
_frame = e.NameScope.Find<Border>(CarouselPageIndicatorThemeConstants.FramePart);
if (_frame != null)
{
_frame.Loaded += (sender, args) =>
{
ConfigureFrameTransitions(false);
};
_frame.Unloaded += (sender, args) =>
{
_frame.Transitions = null;
};
}
if (IsShowTransitionProgress)
{
BuildProgressAnimation(false);
@@ -206,30 +204,6 @@ internal class CarouselPageIndicator : ContentControl, ISelectable
_cancellationTokenSource = null;
}
}
private void ConfigureFrameTransitions(bool force)
{
if (IsMotionEnabled)
{
if (_frame != null)
{
if (force || _frame.Transitions == null)
{
_frame.Transitions =
[
TransitionUtils.CreateTransition<DoubleTransition>(Border.OpacityProperty)
];
}
}
}
else
{
if (_frame != null)
{
_frame.Transitions = null;
}
}
}
private void ConfigureProgressAnimation()
{
@@ -11,14 +11,15 @@
CornerRadius="{TemplateBinding CornerRadius}"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}"
Background="{TemplateBinding Background}" />
Background="{TemplateBinding Background}"
Opacity="{TemplateBinding FrameOpacity}"/>
<Border Name="Progress"
CornerRadius="{TemplateBinding CornerRadius}"
Height="{TemplateBinding Height}"
Width="{TemplateBinding EffectiveProgressWidth}"
Background="{TemplateBinding Background}"
IsVisible="False"
HorizontalAlignment="Left"/>
IsVisible="False"
HorizontalAlignment="Left" />
</Panel>
</ControlTemplate>
</Setter>
@@ -28,14 +29,10 @@
<Setter Property="Background" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorBgContainer}}" />
<Setter Property="Cursor" Value="Hand" />
<Style Selector="^ /template/ Border#PART_Frame">
<Setter Property="Opacity" Value="0.2" />
</Style>
<Setter Property="FrameOpacity" Value="0.2" />
<Style Selector="^:pointerover">
<Style Selector="^ /template/ Border#PART_Frame">
<Setter Property="Opacity" Value="0.75" />
</Style>
<Setter Property="FrameOpacity" Value="0.75" />
</Style>
<Style Selector="^[IsSelected=True]">
@@ -44,9 +41,7 @@
<Style Selector="^[IsShowTransitionProgress=False]">
<Style Selector="^[IsSelected=True]">
<Style Selector="^ /template/ Border#PART_Frame">
<Setter Property="Opacity" Value="1" />
</Style>
<Setter Property="FrameOpacity" Value="1" />
</Style>
</Style>
@@ -59,8 +54,8 @@
<Style Selector="^ /template/ Border#Progress">
<Setter Property="IsVisible" Value="False" />
</Style>
</Style>
</Style>
</Style>
</Style>
</ControlTheme>
</ResourceDictionary>
@@ -20,6 +20,7 @@
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsMotionEnabled="{TemplateBinding IsMotionEnabled}"
Icon="{TemplateBinding ExpandIcon}"
IsVisible="{TemplateBinding IsShowExpandIcon}"
IsEnabled="{TemplateBinding IsEnabled}"/>
-43
View File
@@ -1,6 +1,5 @@
using System.Diagnostics;
using AtomUI.Controls.Themes;
using AtomUI.Controls.Utils;
using AtomUI.IconPkg;
using AtomUI.IconPkg.AntDesign;
using AtomUI.MotionScene;
@@ -9,7 +8,6 @@ using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using AtomUI.Theme.Utils;
using Avalonia;
using Avalonia.Animation;
using Avalonia.Animation.Easings;
using Avalonia.Controls;
using Avalonia.Controls.Metadata;
@@ -250,15 +248,6 @@ public class Expander : AvaloniaExpander,
IsExpanded = !IsExpanded;
};
_expandButton.Loaded += (sender, args) =>
{
ConfigureExpandButtonTransitions(false);
};
_expandButton.Unloaded += (sender, args) =>
{
_expandButton.Transitions = null;
};
}
SetupDefaultIcon();
UpdatePseudoClasses();
@@ -274,14 +263,6 @@ public class Expander : AvaloniaExpander,
SetupDefaultIcon();
}
}
if (IsLoaded)
{
if (change.Property == IsMotionEnabledProperty)
{
ConfigureExpandButtonTransitions(true);
}
}
if (change.Property == IsExpandedProperty)
{
@@ -438,30 +419,6 @@ public class Expander : AvaloniaExpander,
}
}
private void ConfigureExpandButtonTransitions(bool force)
{
if (IsMotionEnabled)
{
if (_expandButton != null)
{
if (force || _expandButton.Transitions == null)
{
_expandButton.Transitions =
[
TransitionUtils.CreateTransition<TransformOperationsTransition>(RenderTransformProperty)
];
}
}
}
else
{
if (_expandButton != null)
{
_expandButton.Transitions = null;
}
}
}
private void UpdatePseudoClasses()
{
PseudoClasses.Set(ExpanderPseudoClass.CustomHeaderPadding, HeaderPadding != null);
@@ -24,6 +24,7 @@
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsMotionEnabled="{TemplateBinding IsMotionEnabled}"
Icon="{TemplateBinding ExpandIcon}"
IsVisible="{TemplateBinding IsShowExpandIcon}"
IsEnabled="{TemplateBinding IsEnabled}" />
@@ -32,7 +32,25 @@ public abstract class RangeInfoPickerInput : InfoPickerInput
internal static readonly DirectProperty<RangeInfoPickerInput, RangeActivatedPart> RangeActivatedPartProperty =
AvaloniaProperty.RegisterDirect<RangeInfoPickerInput, RangeActivatedPart>(nameof(RangeActivatedPart),
o => o.RangeActivatedPart);
internal static readonly StyledProperty<double> RangePickerIndicatorOpacityProperty =
AvaloniaProperty.Register<InfoPickerInput, double>(nameof(RangePickerIndicatorOpacity), 0d);
internal double RangePickerIndicatorOpacity
{
get => GetValue(RangePickerIndicatorOpacityProperty);
set => SetValue(RangePickerIndicatorOpacityProperty, value);
}
internal static readonly StyledProperty<double> PickerIndicatorOffsetXProperty =
AvaloniaProperty.Register<RangeInfoPickerInput, double>(nameof(PickerIndicatorOffsetX), double.NaN);
internal static readonly StyledProperty<double> PickerIndicatorOffsetYProperty =
AvaloniaProperty.Register<RangeInfoPickerInput, double>(nameof(PickerIndicatorOffsetY));
internal static readonly StyledProperty<string?> SecondaryTextProperty =
AvaloniaProperty.Register<TextBlock, string?>(nameof(SecondaryText));
private RangeActivatedPart _rangeActivatedPart;
internal RangeActivatedPart RangeActivatedPart
@@ -40,28 +58,20 @@ public abstract class RangeInfoPickerInput : InfoPickerInput
get => _rangeActivatedPart;
set => SetAndRaise(RangeActivatedPartProperty, ref _rangeActivatedPart, value);
}
internal static readonly StyledProperty<double> PickerIndicatorOffsetXProperty =
AvaloniaProperty.Register<RangeInfoPickerInput, double>(nameof(PickerIndicatorOffsetX), double.NaN);
internal double PickerIndicatorOffsetX
{
get => GetValue(PickerIndicatorOffsetXProperty);
set => SetValue(PickerIndicatorOffsetXProperty, value);
}
internal static readonly StyledProperty<double> PickerIndicatorOffsetYProperty =
AvaloniaProperty.Register<RangeInfoPickerInput, double>(nameof(PickerIndicatorOffsetY));
internal double PickerIndicatorOffsetY
{
get => GetValue(PickerIndicatorOffsetYProperty);
set => SetValue(PickerIndicatorOffsetYProperty, value);
}
internal static readonly StyledProperty<string?> SecondaryTextProperty =
AvaloniaProperty.Register<TextBlock, string?>(nameof(SecondaryText));
internal string? SecondaryText
{
get => GetValue(SecondaryTextProperty);
@@ -92,17 +102,6 @@ public abstract class RangeInfoPickerInput : InfoPickerInput
SecondaryInfoInputBox = e.NameScope.Get<TextBox>(RangeInfoPickerInputThemeConstants.SecondaryInfoInputBoxPart);
RangePickerIndicator = e.NameScope.Get<Rectangle>(RangeInfoPickerInputThemeConstants.RangePickerIndicatorPart);
RangePickerArrow = e.NameScope.Get<Icon>(RangeInfoPickerInputThemeConstants.RangePickerArrowPart);
if (RangePickerIndicator != null)
{
RangePickerIndicator.Loaded += (sender, args) =>
{
ConfigureRangePickerIndicatorTransitions(false);
};
RangePickerIndicator.Unloaded += (sender, args) =>
{
RangePickerIndicator.Transitions = null;
};
}
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
@@ -111,31 +110,6 @@ public abstract class RangeInfoPickerInput : InfoPickerInput
_topLevel = TopLevel.GetTopLevel(this);
}
private void ConfigureRangePickerIndicatorTransitions(bool force)
{
if (IsMotionEnabled)
{
if (RangePickerIndicator != null)
{
if (force || RangePickerIndicator.Transitions == null)
{
RangePickerIndicator.Transitions =
[
TransitionUtils.CreateTransition<DoubleTransition>(OpacityProperty),
TransitionUtils.CreateTransition<DoubleTransition>(OpacityProperty)
];
}
}
}
else
{
if (RangePickerIndicator != null)
{
RangePickerIndicator.Transitions = null;
}
}
}
private void ConfigureTransitions(bool force)
{
if (IsMotionEnabled)
@@ -144,7 +118,8 @@ public abstract class RangeInfoPickerInput : InfoPickerInput
{
Transitions =
[
TransitionUtils.CreateTransition<DoubleTransition>(PickerIndicatorOffsetXProperty)
TransitionUtils.CreateTransition<DoubleTransition>(PickerIndicatorOffsetXProperty),
TransitionUtils.CreateTransition<DoubleTransition>(RangePickerIndicatorOpacityProperty)
];
}
}
@@ -301,7 +276,6 @@ public abstract class RangeInfoPickerInput : InfoPickerInput
if (change.Property == IsMotionEnabledProperty)
{
ConfigureTransitions(true);
ConfigureRangePickerIndicatorTransitions(true);
}
}
}
@@ -370,19 +344,19 @@ public abstract class RangeInfoPickerInput : InfoPickerInput
if (_rangeActivatedPart == RangeActivatedPart.None)
{
RangePickerIndicator.Opacity = 0;
RangePickerIndicatorOpacity = 0;
}
else if (_rangeActivatedPart == RangeActivatedPart.Start)
{
RangePickerIndicator.Opacity = 1;
RangePickerIndicator.Width = InfoInputBox.Bounds.Width;
RangePickerIndicatorOpacity = 1;
RangePickerIndicator.Width = InfoInputBox.Bounds.Width;
var offset = InfoInputBox.TranslatePoint(new Point(0, 0), this) ?? default;
PickerIndicatorOffsetX = offset.X;
}
else if (_rangeActivatedPart == RangeActivatedPart.End)
{
RangePickerIndicator.Opacity = 1;
RangePickerIndicator.Width = SecondaryInfoInputBox.Bounds.Width;
RangePickerIndicatorOpacity = 1;
RangePickerIndicator.Width = SecondaryInfoInputBox.Bounds.Width;
var offset = SecondaryInfoInputBox.TranslatePoint(new Point(0, 0), this) ?? default;
PickerIndicatorOffsetX = offset.X;
}
@@ -84,7 +84,7 @@
<Canvas>
<Rectangle Name="{x:Static atom:RangeInfoPickerInputThemeConstants.RangePickerIndicatorPart}"
Opacity="0" />
Opacity="{TemplateBinding RangePickerIndicatorOpacity}" />
</Canvas>
</Panel>
</ControlTemplate>
+44 -36
View File
@@ -7,6 +7,8 @@ using Avalonia.Animation.Easings;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Media.Transformation;
using Avalonia.VisualTree;
@@ -21,11 +23,20 @@ public class TabControl : BaseTabControl
internal static readonly StyledProperty<double> SelectedIndicatorThicknessProperty =
AvaloniaProperty.Register<TabControl, double>(nameof(SelectedIndicatorThickness));
internal static readonly StyledProperty<ITransform?> SelectedIndicatorRenderTransformProperty =
AvaloniaProperty.Register<TabControl, ITransform?>(nameof (SelectedIndicatorRenderTransform));
internal double SelectedIndicatorThickness
{
get => GetValue(SelectedIndicatorThicknessProperty);
set => SetValue(SelectedIndicatorThicknessProperty, value);
}
internal ITransform? SelectedIndicatorRenderTransform
{
get => GetValue(SelectedIndicatorRenderTransformProperty);
set => SetValue(SelectedIndicatorRenderTransformProperty, value);
}
#endregion
@@ -45,28 +56,6 @@ public class TabControl : BaseTabControl
SetupSelectedIndicator();
}
}
private void ConfigureSelectedIndicatorTransitions(bool force)
{
if (_selectedIndicator is not null)
{
if (IsMotionEnabled)
{
if (force || _selectedIndicator.Transitions == null)
{
_selectedIndicator.Transitions =
[
TransitionUtils.CreateTransition<TransformOperationsTransition>(RenderTransformProperty,
SharedTokenKey.MotionDurationSlow, new ExponentialEaseOut())
];
}
}
else
{
_selectedIndicator.Transitions = null;
}
}
}
private void SetupSelectedIndicator()
{
@@ -101,7 +90,7 @@ public class TabControl : BaseTabControl
builder.AppendTranslate(0, offset.Y + selectedBounds.Y);
}
_selectedIndicator.RenderTransform = builder.Build();
SelectedIndicatorRenderTransform = builder.Build();
}
}
@@ -144,18 +133,6 @@ public class TabControl : BaseTabControl
{
_scrollViewer.TabControl = this;
}
if (_selectedIndicator != null)
{
_selectedIndicator.Loaded += (sender, args) =>
{
ConfigureSelectedIndicatorTransitions(false);
};
_selectedIndicator.Unloaded += (sender, args) =>
{
_selectedIndicator.Transitions = null;
};
}
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
@@ -165,8 +142,39 @@ public class TabControl : BaseTabControl
{
if (change.Property == IsMotionEnabledProperty)
{
ConfigureSelectedIndicatorTransitions(true);
ConfigureTransitions(true);
}
}
}
private void ConfigureTransitions(bool force)
{
if (IsMotionEnabled)
{
if (force || Transitions == null)
{
Transitions =
[
TransitionUtils.CreateTransition<TransformOperationsTransition>(SelectedIndicatorRenderTransformProperty,
SharedTokenKey.MotionDurationSlow, new ExponentialEaseOut())
];
}
}
else
{
Transitions = null;
}
}
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
ConfigureTransitions(false);
}
protected override void OnUnloaded(RoutedEventArgs e)
{
base.OnUnloaded(e);
Transitions = null;
}
}
@@ -7,6 +7,8 @@ using Avalonia.Animation.Easings;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Media.Transformation;
using Avalonia.VisualTree;
@@ -21,12 +23,21 @@ public class TabStrip : BaseTabStrip
internal static readonly StyledProperty<double> SelectedIndicatorThicknessProperty =
AvaloniaProperty.Register<TabStrip, double>(nameof(SelectedIndicatorThickness));
internal static readonly StyledProperty<ITransform?> SelectedIndicatorRenderTransformProperty =
AvaloniaProperty.Register<TabStrip, ITransform?>(nameof (SelectedIndicatorRenderTransform));
internal double SelectedIndicatorThickness
{
get => GetValue(SelectedIndicatorThicknessProperty);
set => SetValue(SelectedIndicatorThicknessProperty, value);
}
internal ITransform? SelectedIndicatorRenderTransform
{
get => GetValue(SelectedIndicatorRenderTransformProperty);
set => SetValue(SelectedIndicatorRenderTransformProperty, value);
}
#endregion
private Border? _selectedIndicator;
@@ -45,29 +56,7 @@ public class TabStrip : BaseTabStrip
SetupSelectedIndicator();
}
}
private void ConfigureSelectedIndicatorTransitions(bool force)
{
if (_selectedIndicator is not null)
{
if (IsMotionEnabled)
{
if (force || _selectedIndicator.Transitions == null)
{
_selectedIndicator.Transitions =
[
TransitionUtils.CreateTransition<TransformOperationsTransition>(RenderTransformProperty,
SharedTokenKey.MotionDurationSlow, new ExponentialEaseOut())
];
}
}
else
{
_selectedIndicator.Transitions = null;
}
}
}
private void SetupSelectedIndicator()
{
if (_selectedIndicator is not null && SelectedItem is not null && ContainerFromItem(SelectedItem) is TabStripItem tabStripItem)
@@ -101,7 +90,7 @@ public class TabStrip : BaseTabStrip
builder.AppendTranslate(0, offset.Y + selectedBounds.Y);
}
_selectedIndicator.RenderTransform = builder.Build();
SelectedIndicatorRenderTransform = builder.Build();
}
}
@@ -144,30 +133,50 @@ public class TabStrip : BaseTabStrip
{
_scrollViewer.TabStrip = this;
}
if (_selectedIndicator != null)
{
_selectedIndicator.Loaded += (sender, args) =>
{
ConfigureSelectedIndicatorTransitions(false);
};
_selectedIndicator.Unloaded += (sender, args) =>
{
_selectedIndicator.Transitions = null;
};
}
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (IsLoaded)
{
if (change.Property == IsMotionEnabledProperty)
{
ConfigureSelectedIndicatorTransitions(true);
ConfigureTransitions(true);
}
}
}
private void ConfigureTransitions(bool force)
{
if (IsMotionEnabled)
{
if (force || Transitions == null)
{
Transitions =
[
TransitionUtils.CreateTransition<TransformOperationsTransition>(SelectedIndicatorRenderTransformProperty,
SharedTokenKey.MotionDurationSlow, new ExponentialEaseOut())
];
}
}
else
{
Transitions = null;
}
}
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
ConfigureTransitions(false);
}
protected override void OnUnloaded(RoutedEventArgs e)
{
base.OnUnloaded(e);
Transitions = null;
}
}
@@ -33,7 +33,8 @@
Name="{x:Static atom:TabControlThemeConstants.ItemsPresenterPart}"
ItemsPanel="{TemplateBinding ItemsPanel}" />
<Border
Name="{x:Static atom:TabControlThemeConstants.SelectedItemIndicatorPart}" />
Name="{x:Static atom:TabControlThemeConstants.SelectedItemIndicatorPart}"
RenderTransform="{TemplateBinding SelectedIndicatorRenderTransform}"/>
</Panel>
</atom:TabControlScrollViewer>
</DockPanel>
@@ -29,7 +29,8 @@
<ItemsPresenter
Name="{x:Static atom:TabStripThemeConstants.ItemsPresenterPart}"
ItemsPanel="{TemplateBinding ItemsPanel}" />
<Border Name="{x:Static atom:TabStripThemeConstants.SelectedItemIndicatorPart}" />
<Border Name="{x:Static atom:TabStripThemeConstants.SelectedItemIndicatorPart}"
RenderTransform="{TemplateBinding SelectedIndicatorRenderTransform}"/>
</Panel>
</atom:TabStripScrollViewer>
</DockPanel>