Skip to content

Commit

Permalink
Return ScrollableTabControl and fix Scroller
Browse files Browse the repository at this point in the history
  • Loading branch information
SKProCH committed Nov 15, 2023
1 parent c19d6ec commit 5ba7aa1
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 269 deletions.
3 changes: 1 addition & 2 deletions Material.Demo/Pages/TabsDemo.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
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"
xmlns:styles="clr-namespace:Material.Styles;assembly=Material.Styles"
xmlns:showMeTheXaml="clr-namespace:ShowMeTheXaml;assembly=ShowMeTheXaml.Avalonia"
x:Class="Material.Demo.Pages.TabsDemo">
<StackPanel Margin="16, 0">
Expand Down Expand Up @@ -47,7 +46,7 @@
<DockPanel>
<TextBlock Classes="Headline6 Subheadline2" Text="Standard tabs with scroll helper" />
<showMeTheXaml:XamlDisplay UniqueId="Tabs1">
<TabControl AutoScrollToSelectedItem="True" Classes="Scrollable">
<TabControl AutoScrollToSelectedItem="True" Theme="{StaticResource ScrollableTabControl}">
<TabControl.Items>
<TabItem Header="Item 1">
<TextBlock Classes="Centered" Text="Page 1" />
Expand Down
17 changes: 10 additions & 7 deletions Material.Styles/Controls/Scroller.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
<ControlTheme x:Key="TabControlScroller" TargetType="controls:Scroller">
<Setter Property="ScrollSpeed" Value="50" />
<Setter Property="SmallScrollMultiplier" Value="0.5" />
<Setter Property="VerticalScrollBarVisibility" Value="Hidden" />
<Setter Property="HorizontalScrollBarVisibility" Value="Hidden" />
<Setter Property="Template">
<ControlTemplate>
<Panel Name="PART_RootPanel">
<ScrollContentPresenter Name="PART_ContentPresenter"
<Grid Name="PART_RootPanel"
ColumnDefinitions="Auto * Auto">
<ScrollContentPresenter Name="PART_ContentPresenter" Grid.Column="1"
Padding="{TemplateBinding Padding}">
<ScrollContentPresenter.GestureRecognizers>
<ScrollGestureRecognizer
Expand All @@ -21,13 +24,13 @@
</ScrollContentPresenter.GestureRecognizers>
</ScrollContentPresenter>

<Button Name="PART_PageUpButton"
IsEnabled="{TemplateBinding controls:Scroller.CanScrollToStart}"
<Button Name="PART_PageUpButton" Grid.Column="0"
IsVisible="{TemplateBinding controls:Scroller.CanScrollToStart}"
Command="{Binding $parent[controls:Scroller].ScrollPageBackOnce}" />
<Button Name="PART_PageDownButton"
IsEnabled="{TemplateBinding controls:Scroller.CanScrollToEnd}"
<Button Name="PART_PageDownButton" Grid.Column="2"
IsVisible="{TemplateBinding controls:Scroller.CanScrollToEnd}"
Command="{Binding $parent[controls:Scroller].ScrollPageForwardOnce}" />
</Panel>
</Grid>
</ControlTemplate>
</Setter>

Expand Down
189 changes: 2 additions & 187 deletions Material.Styles/Controls/Scroller.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Layout;

namespace Material.Styles.Controls {
/// <summary>
/// A customized ScrollViewer that designed for scrolling in TabControl and Breadcrumbs.
/// Suitable for single orientation scrolls (horizontally or vertically, for standard scroll: <see cref="ScrollViewer"/>)
/// </summary>
/// TODO: Complete component modification
public sealed class Scroller : ContentControl, IScrollable, IScrollAnchorProvider {
public sealed class Scroller : ScrollViewer {
/// <summary>
/// Defines the <see cref="Orientation"/> property.
/// </summary>
Expand Down Expand Up @@ -45,33 +42,6 @@ public sealed class Scroller : ContentControl, IScrollable, IScrollAnchorProvide
AvaloniaProperty.RegisterDirect<Scroller, bool>(nameof(CanVerticallyScroll),
o => o.CanVerticallyScroll);

/// <summary>
/// Defines the <see cref="Extent"/> property.
/// </summary>
public static readonly StyledProperty<Size> ExtentProperty =
AvaloniaProperty.Register<Scroller, Size>(nameof(Extent));

/// <summary>
/// Defines the <see cref="Offset"/> property.
/// </summary>
public static readonly StyledProperty<Vector> OffsetProperty =
AvaloniaProperty.Register<Scroller, Vector>(nameof(Offset),
coerce: CoerceOffset);

/// <summary>
/// Defines the <see cref="Viewport"/> property.
/// </summary>
public static readonly StyledProperty<Size> ViewportProperty =
AvaloniaProperty.Register<Scroller, Size>(nameof(Viewport));

/// <summary>
/// Defines the <see cref="ScrollChanged"/> event.
/// </summary>
public static readonly RoutedEvent<ScrollChangedEventArgs> ScrollChangedEvent =
RoutedEvent.Register<Scroller, ScrollChangedEventArgs>(
nameof(ScrollChanged),
RoutingStrategies.Bubble);

/// <summary>
/// Defines the <see cref="CanScrollToStart"/> property.
/// </summary>
Expand Down Expand Up @@ -161,55 +131,6 @@ public bool CanScrollToEnd {
private set => SetAndRaise(CanScrollToEndProperty, ref _canScrollToEnd, value);
}

/// <summary>
/// Gets a value indicating whether the viewer can scroll horizontally.
/// </summary>
public bool CanHorizontallyScroll => Orientation == Orientation.Horizontal;

/// <summary>
/// Gets a value indicating whether the viewer can scroll vertically.
/// </summary>
public bool CanVerticallyScroll => Orientation == Orientation.Vertical;

/// <summary>
/// Gets the extent of the scrollable content.
/// </summary>
public Size Extent {
get => GetValue(ExtentProperty);
private set => SetValue(ExtentProperty, value);
}

/// <summary>
/// Gets or sets the current scroll offset.
/// </summary>
public Vector Offset {
get => GetValue(OffsetProperty);
set => SetValue(OffsetProperty, value);
}

/// <summary>
/// Gets the size of the viewport on the scrollable content.
/// </summary>
public Size Viewport {
get => GetValue(ViewportProperty);
private set => SetValue(ViewportProperty, value);
}

/// <inheritdoc/>
public Control? CurrentAnchor => Presenter is IScrollAnchorProvider scrollAnchorProvider
? scrollAnchorProvider.CurrentAnchor
: null;

/// <inheritdoc/>
public void RegisterAnchorCandidate(Control element) {
(Presenter as IScrollAnchorProvider)?.RegisterAnchorCandidate(element);
}

/// <inheritdoc/>
public void UnregisterAnchorCandidate(Control element) {
(Presenter as IScrollAnchorProvider)?.UnregisterAnchorCandidate(element);
}

/// <inheritdoc />
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) {
base.OnPropertyChanged(change);
Expand All @@ -220,14 +141,6 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang
CalculatedPropertiesChanged();
}

/// <summary>
/// Occurs when changes are detected to the scroll position, extent, or viewport size.
/// </summary>
public event EventHandler<ScrollChangedEventArgs> ScrollChanged {
add => AddHandler(ScrollChangedEvent, value);
remove => RemoveHandler(ScrollChangedEvent, value);
}

public void ScrollBackOnce() {
switch (Orientation) {
case Orientation.Horizontal:
Expand Down Expand Up @@ -284,91 +197,6 @@ public void ScrollPageForwardOnce() {
}
}

/// <summary>
/// Scrolls the content up once with <see cref="ScrollSpeed"/>.
/// </summary>
public void LineUp() {
Offset -= new Vector(0, ScrollSpeed);
}

/// <summary>
/// Scrolls the content down once with <see cref="ScrollSpeed"/>.
/// </summary>
public void LineDown() {
Offset += new Vector(0, ScrollSpeed);
}

/// <summary>
/// Scrolls the content left once with <see cref="ScrollSpeed"/>.
/// </summary>
public void LineLeft() {
Offset -= new Vector(ScrollSpeed, 0);
}

/// <summary>
/// Scrolls the content right once with <see cref="ScrollSpeed"/>.
/// </summary>
public void LineRight() {
Offset += new Vector(ScrollSpeed, 0);
}


/// <summary>
/// Scrolls the content up once with <see cref="ScrollSpeed"/>.
/// </summary>
public void PageUp() {
Offset -= new Vector(0, Viewport.Height);
}

/// <summary>
/// Scrolls the content down once with <see cref="ScrollSpeed"/>.
/// </summary>
public void PageDown() {
Offset += new Vector(0, Viewport.Height);
}

/// <summary>
/// Scrolls the content left once with <see cref="ScrollSpeed"/>.
/// </summary>
public void PageLeft() {
Offset -= new Vector(Viewport.Width, 0);
}

/// <summary>
/// Scrolls the content right once with <see cref="ScrollSpeed"/>.
/// </summary>
public void PageRight() {
Offset += new Vector(Viewport.Width, 0);
}

/// <summary>
/// Scrolls to the top-left corner of the content.
/// </summary>
public void ScrollToHome() {
Offset = new Vector(double.NegativeInfinity, double.NegativeInfinity);
}

/// <summary>
/// Scrolls to the bottom-left corner of the content.
/// </summary>
public void ScrollToEnd() {
Offset = new Vector(double.NegativeInfinity, double.PositiveInfinity);
}

protected override bool RegisterContentPresenter(ContentPresenter presenter) {
_childSubscription?.Dispose();
_childSubscription = null;

if (!base.RegisterContentPresenter(presenter))
return false;

// BUG: Obsolete API?
// _childSubscription = Presenter?
// .GetObservable(ContentPresenter.ChildProperty)
// .Subscribe(ChildChanged);
return true;
}

protected override void OnPointerWheelChanged(PointerWheelEventArgs e) {
var isHandle = HandleMouseWheel;

Expand Down Expand Up @@ -417,19 +245,6 @@ private void CalculatedPropertiesChanged() {
}
}

/// <summary>
/// Called when a change in scrolling state is detected, such as a change in scroll
/// position, extent, or viewport size.
/// </summary>
/// <param name="e">The event args.</param>
/// <remarks>
/// If you override this method, call `base.OnScrollChanged(ScrollChangedEventArgs)` to
/// ensure that this event is raised.
/// </remarks>
private void OnScrollChanged(ScrollChangedEventArgs e) {
RaiseEvent(e);
}

private void OnLayoutUpdated(object sender, EventArgs e) => RaiseScrollChanged();

private void RaiseScrollChanged() {
Expand All @@ -450,4 +265,4 @@ private void RaiseScrollChanged() {
_oldViewport = Viewport;
}
}
}
}
Loading

0 comments on commit 5ba7aa1

Please sign in to comment.