mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-28 23:08:36 +08:00
Refactor TabControl
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user