Refactor TabControl

This commit is contained in:
CHINBOY
2025-03-09 17:08:21 +08:00
parent 64c5a5e14d
commit db5924fbe5
7 changed files with 47 additions and 41 deletions
@@ -11,6 +11,7 @@ using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.LogicalTree;
using Avalonia.Media;
using Avalonia.VisualTree;
namespace AtomUI.Controls;
@@ -126,7 +127,6 @@ public class BaseTabControl : AvaloniaTabControl,
base.OnApplyTemplate(e);
_frame = e.NameScope.Find<Border>(BaseTabControlTheme.FramePart);
_alignWrapper = e.NameScope.Find<Panel>(BaseTabControlTheme.AlignWrapperPart);
HandlePlacementChanged();
}
protected override void PrepareContainerForItemOverride(Control container, object? item, int index)
@@ -142,10 +142,6 @@ public class BaseTabControl : AvaloniaTabControl,
{
base.OnAttachedToLogicalTree(e);
_tokenBindingsDisposable = new CompositeDisposable();
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, TabAndContentGutterProperty,
TabControlTokenKey.TabAndContentGutter));
UpdatePseudoClasses();
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
@@ -163,14 +159,22 @@ public class BaseTabControl : AvaloniaTabControl,
SharedTokenKey.BorderThickness, BindingPriority.Template,
new RenderScaleAwareThicknessConfigure(this)));
}
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, TabAndContentGutterProperty,
TabControlTokenKey.TabAndContentGutter));
UpdatePseudoClasses();
HandlePlacementChanged();
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == TabStripPlacementProperty)
if (this.IsAttachedToVisualTree())
{
HandlePlacementChanged();
if (change.Property == TabStripPlacementProperty)
{
UpdatePseudoClasses();
HandlePlacementChanged();
}
}
}
@@ -184,7 +188,6 @@ public class BaseTabControl : AvaloniaTabControl,
private void HandlePlacementChanged()
{
UpdatePseudoClasses();
if (TabStripPlacement == Dock.Top)
{
TabStripMargin = new Thickness(0, 0, 0, _tabAndContentGutter);
@@ -92,25 +92,13 @@ internal abstract class BaseTabScrollViewer : ScrollViewer,
AffectsMeasure<BaseTabScrollViewer>(TabStripPlacementProperty);
}
public BaseTabScrollViewer()
{
HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == TabStripPlacementProperty)
{
if (Presenter is TabScrollContentPresenter tabStripScrollContentPresenter)
{
tabStripScrollContentPresenter.TabStripPlacement = TabStripPlacement;
}
}
else if (change.Property == VerticalScrollBarVisibilityProperty ||
change.Property == OffsetProperty ||
change.Property == ExtentProperty ||
change.Property == ViewportProperty)
if (change.Property == VerticalScrollBarVisibilityProperty ||
change.Property == OffsetProperty ||
change.Property == ExtentProperty ||
change.Property == ViewportProperty)
{
SetupIndicatorsVisibility();
}
@@ -89,6 +89,8 @@ internal class BaseTabScrollViewerTheme : BaseControlTheme
Name = ScrollViewContentPart
};
CreateTemplateParentBinding(scrollViewContent, TabScrollContentPresenter.TabStripPlacementProperty,
BaseTabScrollViewer.TabStripPlacementProperty);
CreateTemplateParentBinding(scrollViewContent, Layoutable.MarginProperty,
TemplatedControl.PaddingProperty);
CreateTemplateParentBinding(scrollViewContent, ScrollContentPresenter.HorizontalSnapPointsAlignmentProperty,
@@ -117,6 +119,7 @@ internal class BaseTabScrollViewerTheme : BaseControlTheme
protected override void BuildStyles()
{
this.Add(BaseTabScrollViewer.HorizontalScrollBarVisibilityProperty, ScrollBarVisibility.Auto);
{
var menuIndicatorStyle =
new Style(selector => selector.Nesting().Template().Name(ScrollMenuIndicatorPart));
@@ -11,6 +11,7 @@ using Avalonia.Data;
using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.LogicalTree;
using Avalonia.VisualTree;
namespace AtomUI.Controls;
@@ -126,7 +127,7 @@ public class CardTabControl : BaseTabControl
{
base.OnPropertyChanged(change);
if (this.IsAttachedToLogicalTree())
if (this.IsAttachedToVisualTree())
{
if (change.Property == SizeTypeProperty)
{
@@ -164,20 +165,15 @@ public class CardTabControl : BaseTabControl
}
}
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnAttachedToLogicalTree(e);
SetupSizeTypeBinding();
this.AddTokenBindingDisposable(
TokenResourceBinder.CreateTokenBinding(this, CardSizeProperty, TabControlTokenKey.CardSize));
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, CardBorderThicknessProperty,
SharedTokenKey.BorderThickness, BindingPriority.Template,
new RenderScaleAwareThicknessConfigure(this)));
this.AddTokenBindingDisposable(
TokenResourceBinder.CreateTokenBinding(this, CardSizeProperty, TabControlTokenKey.CardSize));
SetupSizeTypeBinding();
}
protected override Size ArrangeOverride(Size finalSize)
+2 -2
View File
@@ -151,9 +151,9 @@ public class TabControl : BaseTabControl
_itemsPresenter = e.NameScope.Find<ItemsPresenter>(BaseTabControlTheme.ItemsPresenterPart);
}
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToLogicalTree(e);
base.OnAttachedToVisualTree(e);
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, SelectedIndicatorThicknessProperty,
SharedTokenKey.LineWidthBold));
}
+8 -4
View File
@@ -108,8 +108,6 @@ public class TabItem : AvaloniaTabItem,
base.OnApplyTemplate(e);
_closeButton = e.NameScope.Find<IconButton>(BaseTabItemTheme.ItemCloseButtonPart);
SetupTransitions();
if (_closeButton is not null)
{
_closeButton.Click += HandleCloseRequest;
@@ -188,7 +186,7 @@ public class TabItem : AvaloniaTabItem,
newIcon.SetTemplatedParent(this);
}
if (change.Property == CloseIconProperty)
if (change.Property == CloseIconProperty && CloseIcon is null)
{
SetupDefaultCloseIcon();
}
@@ -200,7 +198,6 @@ public class TabItem : AvaloniaTabItem,
_tokenBindingsDisposable = new CompositeDisposable();
SetupShapeThemeBindings();
base.OnAttachedToLogicalTree(e);
SetupDefaultCloseIcon();
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
@@ -209,6 +206,13 @@ public class TabItem : AvaloniaTabItem,
this.DisposeTokenBindings();
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
SetupTransitions();
SetupDefaultCloseIcon();
}
private void SetupShapeThemeBindings()
{
if (Shape == TabSharp.Line)
@@ -8,9 +8,21 @@ using Avalonia.Rendering;
namespace AtomUI.Controls;
internal class TabScrollContentPresenter : ScrollContentPresenter, ICustomHitTest
internal class TabScrollContentPresenter : ScrollContentPresenter,
ICustomHitTest
{
internal Dock TabStripPlacement { get; set; } = Dock.Top;
internal static readonly DirectProperty<TabScrollContentPresenter, Dock> TabStripPlacementProperty =
AvaloniaProperty.RegisterDirect<TabScrollContentPresenter, Dock>(nameof(TabStripPlacement),
o => o.TabStripPlacement,
(o, v) => o.TabStripPlacement = v);
private Dock _tabStripPlacement = Dock.Top;
internal Dock TabStripPlacement
{
get => _tabStripPlacement;
set => SetAndRaise(TabStripPlacementProperty, ref _tabStripPlacement, value);
}
private static readonly MethodInfo SnapOffsetMethodInfo;