Browse Source

Rename PipsPager button theme APIs (#20954)

* Rename PipsPager button theme

* Updated PipsPager render tests

* Updated tests

* Updated Avalonia.nupkg.xml
master
Javier Suárez 4 hours ago
committed by GitHub
parent
commit
d30779c5a6
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 96
      api/Avalonia.nupkg.xml
  2. 26
      samples/ControlCatalog/Pages/PipsPager/PipsPagerCustomButtonThemesPage.xaml
  3. 11
      samples/ControlCatalog/Pages/PipsPager/PipsPagerCustomButtonThemesPage.xaml.cs
  4. 11
      samples/ControlCatalog/Pages/PipsPager/PipsPagerCustomButtonsPage.xaml.cs
  5. 6
      samples/ControlCatalog/Pages/PipsPagerPage.xaml.cs
  6. 17
      src/Avalonia.Controls/Page/NavigationPage.cs
  7. 28
      src/Avalonia.Controls/PipsPager/PipsPager.cs
  8. 61
      src/Avalonia.Themes.Fluent/Controls/PipsPager.xaml
  9. 4
      src/Avalonia.Themes.Simple/Controls/PipsPager.xaml
  10. 2
      tests/Avalonia.Controls.UnitTests/DrawerPageTests.cs
  11. 28
      tests/Avalonia.Controls.UnitTests/NavigationPageTests.cs
  12. 40
      tests/Avalonia.Controls.UnitTests/PipsPagerTests.cs
  13. 45
      tests/Avalonia.RenderTests/Controls/PipsPagerTests.cs
  14. BIN
      tests/TestFiles/Skia/Controls/PipsPager/PipsPager_Default.expected.png
  15. BIN
      tests/TestFiles/Skia/Controls/PipsPager/PipsPager_Preselected_Index.expected.png

96
api/Avalonia.nupkg.xml

@ -5641,4 +5641,100 @@
<Left>baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>F:Avalonia.Controls.NavigationPage.IsBackButtonEffectivelyVisibleProperty</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.NavigationPage.get_IsBackButtonEffectivelyVisible</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>F:Avalonia.Controls.PipsPager.PreviousButtonStyleProperty</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>F:Avalonia.Controls.PipsPager.NextButtonStyleProperty</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.PipsPager.get_PreviousButtonStyle</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.PipsPager.set_PreviousButtonStyle(Avalonia.Styling.ControlTheme)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.PipsPager.get_NextButtonStyle</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.PipsPager.set_NextButtonStyle(Avalonia.Styling.ControlTheme)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>F:Avalonia.Controls.NavigationPage.IsBackButtonEffectivelyVisibleProperty</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.NavigationPage.get_IsBackButtonEffectivelyVisible</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>F:Avalonia.Controls.PipsPager.PreviousButtonStyleProperty</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>F:Avalonia.Controls.PipsPager.NextButtonStyleProperty</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.PipsPager.get_PreviousButtonStyle</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.PipsPager.set_PreviousButtonStyle(Avalonia.Styling.ControlTheme)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.PipsPager.get_NextButtonStyle</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.PipsPager.set_NextButtonStyle(Avalonia.Styling.ControlTheme)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
</Suppressions>

26
samples/ControlCatalog/Pages/PipsPager/PipsPagerCustomButtonsPage.xaml → samples/ControlCatalog/Pages/PipsPager/PipsPagerCustomButtonThemesPage.xaml

@ -1,17 +1,17 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.Pages.PipsPagerCustomButtonsPage">
x:Class="ControlCatalog.Pages.PipsPagerCustomButtonThemesPage">
<DockPanel>
<ScrollViewer DockPanel.Dock="Right" Width="220">
<StackPanel Margin="12" Spacing="8">
<TextBlock Text="Custom Buttons" FontSize="16" FontWeight="SemiBold"
<TextBlock Text="Custom Button Themes" FontSize="16" FontWeight="SemiBold"
Foreground="{DynamicResource SystemControlHighlightAccentBrush}" />
<TextBlock TextWrapping="Wrap" FontSize="12" Opacity="0.7"
Text="Replace the default chevron navigation buttons with custom styled buttons using PreviousButtonStyle and NextButtonStyle." />
Text="Replace the default chevron navigation buttons with custom button themes using PreviousButtonTheme and NextButtonTheme." />
<Separator />
<TextBlock Text="Properties" FontSize="13" FontWeight="SemiBold" />
<TextBlock FontSize="12" TextWrapping="Wrap" Text="PreviousButtonStyle" />
<TextBlock FontSize="12" TextWrapping="Wrap" Text="NextButtonStyle" />
<TextBlock FontSize="12" TextWrapping="Wrap" Text="PreviousButtonTheme" />
<TextBlock FontSize="12" TextWrapping="Wrap" Text="NextButtonTheme" />
<TextBlock FontSize="12" TextWrapping="Wrap" Text="IsPreviousButtonVisible" />
<TextBlock FontSize="12" TextWrapping="Wrap" Text="IsNextButtonVisible" />
</StackPanel>
@ -27,7 +27,7 @@
<PipsPager NumberOfPages="5" MaxVisiblePips="5"
IsPreviousButtonVisible="True" IsNextButtonVisible="True">
<PipsPager.Resources>
<ControlTheme x:Key="CustomPreviousButtonStyle" TargetType="Button">
<ControlTheme x:Key="CustomPreviousButtonTheme" TargetType="Button">
<Setter Property="Content" Value="Prev" />
<Setter Property="Background" Value="LightGray" />
<Setter Property="Foreground" Value="Black" />
@ -41,7 +41,7 @@
</ControlTemplate>
</Setter>
</ControlTheme>
<ControlTheme x:Key="CustomNextButtonStyle" TargetType="Button">
<ControlTheme x:Key="CustomNextButtonTheme" TargetType="Button">
<Setter Property="Content" Value="Next" />
<Setter Property="Background" Value="LightGray" />
<Setter Property="Foreground" Value="Black" />
@ -56,12 +56,12 @@
</Setter>
</ControlTheme>
</PipsPager.Resources>
<PipsPager.PreviousButtonStyle>
<StaticResource ResourceKey="CustomPreviousButtonStyle" />
</PipsPager.PreviousButtonStyle>
<PipsPager.NextButtonStyle>
<StaticResource ResourceKey="CustomNextButtonStyle" />
</PipsPager.NextButtonStyle>
<PipsPager.PreviousButtonTheme>
<StaticResource ResourceKey="CustomPreviousButtonTheme" />
</PipsPager.PreviousButtonTheme>
<PipsPager.NextButtonTheme>
<StaticResource ResourceKey="CustomNextButtonTheme" />
</PipsPager.NextButtonTheme>
</PipsPager>
</StackPanel>

11
samples/ControlCatalog/Pages/PipsPager/PipsPagerCustomButtonThemesPage.xaml.cs

@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace ControlCatalog.Pages;
public partial class PipsPagerCustomButtonThemesPage : UserControl
{
public PipsPagerCustomButtonThemesPage()
{
InitializeComponent();
}
}

11
samples/ControlCatalog/Pages/PipsPager/PipsPagerCustomButtonsPage.xaml.cs

@ -1,11 +0,0 @@
using Avalonia.Controls;
namespace ControlCatalog.Pages;
public partial class PipsPagerCustomButtonsPage : UserControl
{
public PipsPagerCustomButtonsPage()
{
InitializeComponent();
}
}

6
samples/ControlCatalog/Pages/PipsPagerPage.xaml.cs

@ -25,9 +25,9 @@ namespace ControlCatalog.Pages
("Appearance", "Custom Colors",
"Override pip indicator colors using resource keys for normal, selected, and hover states.",
() => new PipsPagerCustomColorsPage()),
("Appearance", "Custom Buttons",
"Replace the default chevron navigation buttons with custom styled buttons.",
() => new PipsPagerCustomButtonsPage()),
("Appearance", "Custom Button Themes",
"Replace the default chevron navigation buttons with custom button themes.",
() => new PipsPagerCustomButtonThemesPage()),
("Appearance", "Custom Templates",
"Override pip item templates to create squares, pills, numbers, or any custom shape.",
() => new PipsPagerCustomTemplatesPage()),

17
src/Avalonia.Controls/Page/NavigationPage.cs

@ -63,13 +63,14 @@ namespace Avalonia.Controls
private ContentPresenter? _modalPresenter;
private ContentPresenter? _topCommandBarPresenter;
private IDisposable? _hasNavigationBarSub;
private IDisposable? _hasBackButtonSub;
private IDisposable? _isBackButtonEnabledSub;
private IDisposable? _barLayoutBehaviorSub;
private IDisposable? _barHeightSub;
private IDisposable? _backButtonContentSub;
private bool _isNavigating;
private bool _canGoBack;
private bool? _isBackButtonEffectivelyVisible;
private bool _isBackButtonEffectivelyVisible;
private bool _isNavBarEffectivelyVisible;
private double _effectiveBarHeight;
private bool _isBackButtonEffectivelyEnabled;
@ -110,8 +111,8 @@ namespace Avalonia.Controls
/// <summary>
/// Defines the <see cref="IsBackButtonEffectivelyVisible"/> property.
/// </summary>
public static readonly DirectProperty<NavigationPage, bool?> IsBackButtonEffectivelyVisibleProperty =
AvaloniaProperty.RegisterDirect<NavigationPage, bool?>(nameof(IsBackButtonEffectivelyVisible), o => o.IsBackButtonEffectivelyVisible);
public static readonly DirectProperty<NavigationPage, bool> IsBackButtonEffectivelyVisibleProperty =
AvaloniaProperty.RegisterDirect<NavigationPage, bool>(nameof(IsBackButtonEffectivelyVisible), o => o.IsBackButtonEffectivelyVisible);
/// <summary>
/// Defines the <see cref="IsNavBarEffectivelyVisible"/> property.
@ -330,7 +331,7 @@ namespace Avalonia.Controls
/// <summary>
/// Gets the effective back-button visibility.
/// </summary>
public bool? IsBackButtonEffectivelyVisible
public bool IsBackButtonEffectivelyVisible
{
get => _isBackButtonEffectivelyVisible;
private set => SetAndRaise(IsBackButtonEffectivelyVisibleProperty, ref _isBackButtonEffectivelyVisible, value);
@ -730,6 +731,8 @@ namespace Avalonia.Controls
_hasNavigationBarSub?.Dispose();
_hasNavigationBarSub = null;
_hasBackButtonSub?.Dispose();
_hasBackButtonSub = null;
_isBackButtonEnabledSub?.Dispose();
_isBackButtonEnabledSub = null;
_barLayoutBehaviorSub?.Dispose();
@ -1840,6 +1843,9 @@ namespace Avalonia.Controls
_hasNavigationBarSub?.Dispose();
_hasNavigationBarSub = null;
_hasBackButtonSub?.Dispose();
_hasBackButtonSub = null;
_isBackButtonEnabledSub?.Dispose();
_isBackButtonEnabledSub = null;
@ -1857,6 +1863,9 @@ namespace Avalonia.Controls
_hasNavigationBarSub = page.GetObservable(HasNavigationBarProperty)
.Subscribe(new AnonymousObserver<bool>(_ => UpdateIsNavBarEffectivelyVisible()));
_hasBackButtonSub = page.GetObservable(HasBackButtonProperty)
.Subscribe(new AnonymousObserver<bool>(_ => UpdateIsBackButtonEffectivelyVisible()));
_isBackButtonEnabledSub = page.GetObservable(IsBackButtonEnabledProperty)
.Subscribe(new AnonymousObserver<bool>(_ => UpdateIsBackButtonEffectivelyEnabled()));

28
src/Avalonia.Controls/PipsPager/PipsPager.cs

@ -87,16 +87,16 @@ namespace Avalonia.Controls
x => x.TemplateSettings);
/// <summary>
/// Defines the <see cref="PreviousButtonStyle"/> property.
/// Defines the <see cref="PreviousButtonTheme"/> property.
/// </summary>
public static readonly StyledProperty<ControlTheme?> PreviousButtonStyleProperty =
AvaloniaProperty.Register<PipsPager, ControlTheme?>(nameof(PreviousButtonStyle));
public static readonly StyledProperty<ControlTheme?> PreviousButtonThemeProperty =
AvaloniaProperty.Register<PipsPager, ControlTheme?>(nameof(PreviousButtonTheme));
/// <summary>
/// Defines the <see cref="NextButtonStyle"/> property.
/// Defines the <see cref="NextButtonTheme"/> property.
/// </summary>
public static readonly StyledProperty<ControlTheme?> NextButtonStyleProperty =
AvaloniaProperty.Register<PipsPager, ControlTheme?>(nameof(NextButtonStyle));
public static readonly StyledProperty<ControlTheme?> NextButtonThemeProperty =
AvaloniaProperty.Register<PipsPager, ControlTheme?>(nameof(NextButtonTheme));
/// <summary>
/// Defines the <see cref="SelectedIndexChanged"/> event.
@ -195,21 +195,21 @@ namespace Avalonia.Controls
}
/// <summary>
/// Gets or sets the style for the previous button.
/// Gets or sets the theme for the previous button.
/// </summary>
public ControlTheme? PreviousButtonStyle
public ControlTheme? PreviousButtonTheme
{
get => GetValue(PreviousButtonStyleProperty);
set => SetValue(PreviousButtonStyleProperty, value);
get => GetValue(PreviousButtonThemeProperty);
set => SetValue(PreviousButtonThemeProperty, value);
}
/// <summary>
/// Gets or sets the style for the next button.
/// Gets or sets the theme for the next button.
/// </summary>
public ControlTheme? NextButtonStyle
public ControlTheme? NextButtonTheme
{
get => GetValue(NextButtonStyleProperty);
set => SetValue(NextButtonStyleProperty, value);
get => GetValue(NextButtonThemeProperty);
set => SetValue(NextButtonThemeProperty, value);
}
/// <inheritdoc/>

61
src/Avalonia.Themes.Fluent/Controls/PipsPager.xaml

@ -13,12 +13,12 @@
<StreamGeometry x:Key="PipsPagerPreviousPageButtonVerticalData">M 2.29,8.12 L 7.00,3.41 C 7.27,3.14 7.71,3.14 7.98,3.41 L 12.69,8.12 C 13.14,8.57 12.82,9.33 12.19,9.33 L 2.79,9.33 C 2.16,9.33 1.84,8.57 2.29,8.12 Z</StreamGeometry>
<StreamGeometry x:Key="PipsPagerNextPageButtonVerticalData">M 2.29,3.88 L 7.00,8.59 C 7.27,8.86 7.71,8.86 7.98,8.59 L 12.69,3.88 C 13.14,3.43 12.82,2.67 12.19,2.67 L 2.79,2.67 C 2.16,2.67 1.84,3.43 2.29,3.88 Z</StreamGeometry>
<!-- Base navigation button theme (for custom button styles to inherit from) -->
<!-- Base navigation button theme (for custom button themes to inherit from) -->
<ControlTheme x:Key="PipsPagerNavigationButtonTheme" TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Background" Value="{DynamicResource PipsPagerNavigationButtonBackground}" />
<Setter Property="Foreground" Value="{DynamicResource PipsPagerNavigationButtonForeground}" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="{DynamicResource PipsPagerNavigationButtonBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Width" Value="24" />
<Setter Property="Height" Value="24" />
<Setter Property="Padding" Value="0" />
@ -41,16 +41,20 @@
</Setter>
<Style Selector="^:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Background" Value="{DynamicResource PipsPagerNavigationButtonBackgroundPointerOver}" />
<Setter Property="BorderBrush" Value="{DynamicResource PipsPagerNavigationButtonBorderBrushPointerOver}" />
<Setter Property="Foreground" Value="{DynamicResource PipsPagerNavigationButtonForegroundPointerOver}" />
</Style>
<Style Selector="^:pressed /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Background" Value="{DynamicResource PipsPagerNavigationButtonBackgroundPressed}" />
<Setter Property="BorderBrush" Value="{DynamicResource PipsPagerNavigationButtonBorderBrushPressed}" />
<Setter Property="Foreground" Value="{DynamicResource PipsPagerNavigationButtonForegroundPressed}" />
</Style>
<Style Selector="^:disabled /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource PipsPagerNavigationButtonBackgroundDisabled}" />
<Setter Property="BorderBrush" Value="{DynamicResource PipsPagerNavigationButtonBorderBrushDisabled}" />
<Setter Property="Foreground" Value="{DynamicResource PipsPagerNavigationButtonForegroundDisabled}" />
</Style>
</ControlTheme>
@ -73,6 +77,21 @@
<Setter Property="Template">
<ControlTemplate>
<Grid Background="Transparent">
<Ellipse Name="PipBackground"
Width="10"
Height="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="{DynamicResource PipsPagerSelectionIndicatorBackground}"
Stroke="{DynamicResource PipsPagerSelectionIndicatorBorderBrush}"
StrokeThickness="1">
<Ellipse.Transitions>
<Transitions>
<BrushTransition Property="Fill" Duration="0:0:0.167" />
<BrushTransition Property="Stroke" Duration="0:0:0.167" />
</Transitions>
</Ellipse.Transitions>
</Ellipse>
<Ellipse Name="Pip"
Width="4"
Height="4"
@ -96,25 +115,45 @@
<Setter Property="Height" Value="6" />
<Setter Property="Fill" Value="{DynamicResource PipsPagerSelectionIndicatorForegroundPointerOver}" />
</Style>
<Style Selector="^:pointerover /template/ Ellipse#PipBackground">
<Setter Property="Fill" Value="{DynamicResource PipsPagerSelectionIndicatorBackgroundPointerOver}" />
<Setter Property="Stroke" Value="{DynamicResource PipsPagerSelectionIndicatorBorderBrushPointerOver}" />
</Style>
<Style Selector="^:pressed /template/ Ellipse#Pip">
<Setter Property="Width" Value="4" />
<Setter Property="Height" Value="4" />
<Setter Property="Fill" Value="{DynamicResource PipsPagerSelectionIndicatorForegroundPressed}" />
</Style>
<Style Selector="^:pressed /template/ Ellipse#PipBackground">
<Setter Property="Fill" Value="{DynamicResource PipsPagerSelectionIndicatorBackgroundPressed}" />
<Setter Property="Stroke" Value="{DynamicResource PipsPagerSelectionIndicatorBorderBrushPressed}" />
</Style>
<Style Selector="^:selected /template/ Ellipse#Pip">
<Setter Property="Width" Value="6" />
<Setter Property="Height" Value="6" />
<Setter Property="Fill" Value="{DynamicResource PipsPagerSelectionIndicatorForegroundSelected}" />
</Style>
<Style Selector="^:selected /template/ Ellipse#PipBackground">
<Setter Property="Fill" Value="{DynamicResource PipsPagerSelectionIndicatorBackgroundSelected}" />
<Setter Property="Stroke" Value="{DynamicResource PipsPagerSelectionIndicatorBorderBrushSelected}" />
</Style>
<Style Selector="^:selected:pointerover /template/ Ellipse#Pip">
<Setter Property="Width" Value="6" />
<Setter Property="Height" Value="6" />
<Setter Property="Fill" Value="{DynamicResource PipsPagerSelectionIndicatorForegroundPointerOver}" />
</Style>
<Style Selector="^:selected:pointerover /template/ Ellipse#PipBackground">
<Setter Property="Fill" Value="{DynamicResource PipsPagerSelectionIndicatorBackgroundPointerOver}" />
<Setter Property="Stroke" Value="{DynamicResource PipsPagerSelectionIndicatorBorderBrushPointerOver}" />
</Style>
<Style Selector="^:disabled /template/ Ellipse#Pip">
<Setter Property="Fill" Value="{DynamicResource PipsPagerSelectionIndicatorForegroundDisabled}" />
</Style>
<Style Selector="^:disabled /template/ Ellipse#PipBackground">
<Setter Property="Fill" Value="{DynamicResource PipsPagerSelectionIndicatorBackgroundDisabled}" />
<Setter Property="Stroke" Value="{DynamicResource PipsPagerSelectionIndicatorBorderBrushDisabled}" />
</Style>
</ControlTheme>
<ControlTheme x:Key="{x:Type PipsPager}" TargetType="PipsPager">
@ -122,8 +161,8 @@
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="PreviousButtonStyle" Value="{StaticResource PipsPagerPreviousButtonTheme}" />
<Setter Property="NextButtonStyle" Value="{StaticResource PipsPagerNextButtonTheme}" />
<Setter Property="PreviousButtonTheme" Value="{StaticResource PipsPagerPreviousButtonTheme}" />
<Setter Property="NextButtonTheme" Value="{StaticResource PipsPagerNextButtonTheme}" />
<Setter Property="Template">
<ControlTemplate>
<StackPanel Name="PART_RootPanel"
@ -131,7 +170,7 @@
Background="{TemplateBinding Background}"
ClipToBounds="False">
<Button Name="PART_PreviousButton"
Theme="{TemplateBinding PreviousButtonStyle}"
Theme="{TemplateBinding PreviousButtonTheme}"
IsVisible="{TemplateBinding IsPreviousButtonVisible}"
VerticalAlignment="Center"
HorizontalAlignment="Center">
@ -168,7 +207,7 @@
</ListBox>
<Button Name="PART_NextButton"
Theme="{TemplateBinding NextButtonStyle}"
Theme="{TemplateBinding NextButtonTheme}"
IsVisible="{TemplateBinding IsNextButtonVisible}"
VerticalAlignment="Center"
HorizontalAlignment="Center">
@ -309,4 +348,4 @@
<SolidColorBrush x:Key="PipsPagerNavigationButtonForegroundDisabled" Color="#3FFFFFFF" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</ResourceDictionary>

4
src/Avalonia.Themes.Simple/Controls/PipsPager.xaml

@ -10,6 +10,8 @@
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="PreviousButtonTheme" Value="{StaticResource {x:Type Button}}" />
<Setter Property="NextButtonTheme" Value="{StaticResource {x:Type Button}}" />
<Setter Property="Template">
<ControlTemplate>
<StackPanel Name="PART_RootPanel"
@ -19,6 +21,7 @@
ClipToBounds="False">
<Button Name="PART_PreviousButton"
Theme="{TemplateBinding PreviousButtonTheme}"
Width="24"
Height="24"
Padding="0"
@ -99,6 +102,7 @@
</ListBox>
<Button Name="PART_NextButton"
Theme="{TemplateBinding NextButtonTheme}"
Width="24"
Height="24"
Padding="0"

2
tests/Avalonia.Controls.UnitTests/DrawerPageTests.cs

@ -1321,7 +1321,7 @@ public class DrawerPageTests
Assert.True(nav.IsBackButtonEffectivelyVisible);
root.Child = null;
Assert.False(nav.IsBackButtonEffectivelyVisible ?? false);
Assert.False(nav.IsBackButtonEffectivelyVisible);
root.Child = dp;
Assert.True(nav.IsBackButtonEffectivelyVisible);

28
tests/Avalonia.Controls.UnitTests/NavigationPageTests.cs

@ -429,7 +429,7 @@ public class NavigationPageTests
{
var nav = new NavigationPage();
await nav.PushAsync(new ContentPage());
Assert.Equal(false, nav.IsBackButtonEffectivelyVisible);
Assert.False(nav.IsBackButtonEffectivelyVisible);
}
[Fact]
@ -438,7 +438,7 @@ public class NavigationPageTests
var nav = new NavigationPage();
await nav.PushAsync(new ContentPage());
await nav.PushAsync(new ContentPage());
Assert.Equal(true, nav.IsBackButtonEffectivelyVisible);
Assert.True(nav.IsBackButtonEffectivelyVisible);
}
[Fact]
@ -447,7 +447,7 @@ public class NavigationPageTests
var nav = new NavigationPage { IsBackButtonVisible = false };
await nav.PushAsync(new ContentPage());
await nav.PushAsync(new ContentPage());
Assert.Equal(false, nav.IsBackButtonEffectivelyVisible);
Assert.False(nav.IsBackButtonEffectivelyVisible);
}
[Fact]
@ -458,7 +458,7 @@ public class NavigationPageTests
var top = new ContentPage();
NavigationPage.SetHasBackButton(top, false);
await nav.PushAsync(top);
Assert.Equal(false, nav.IsBackButtonEffectivelyVisible);
Assert.False(nav.IsBackButtonEffectivelyVisible);
}
[Fact]
@ -468,7 +468,25 @@ public class NavigationPageTests
await nav.PushAsync(new ContentPage());
await nav.PushAsync(new ContentPage());
nav.IsBackButtonVisible = true;
Assert.Equal(true, nav.IsBackButtonEffectivelyVisible);
Assert.True(nav.IsBackButtonEffectivelyVisible);
}
[Fact]
public async Task BackButtonVisible_UpdatesWhenCurrentPageHasBackButtonChanges()
{
var nav = new NavigationPage();
await nav.PushAsync(new ContentPage());
var top = new ContentPage();
await nav.PushAsync(top);
Assert.True(nav.IsBackButtonEffectivelyVisible);
NavigationPage.SetHasBackButton(top, false);
Assert.False(nav.IsBackButtonEffectivelyVisible);
NavigationPage.SetHasBackButton(top, true);
Assert.True(nav.IsBackButtonEffectivelyVisible);
}
}

40
tests/Avalonia.Controls.UnitTests/PipsPagerTests.cs

@ -5,6 +5,8 @@ using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Styling;
using Avalonia.Themes.Simple;
using System.Linq;
using Xunit;
@ -201,6 +203,44 @@ namespace Avalonia.Controls.UnitTests
Assert.True(target.IsNextButtonVisible);
}
[Fact]
public void SimpleTheme_Should_Forward_Custom_Button_Themes()
{
using var unittestApplication = UnitTestApplication.Start(TestServices.StyledWindow);
var previousTheme = new ControlTheme(typeof(Button));
var nextTheme = new ControlTheme(typeof(Button));
var simpleTheme = new SimpleTheme();
var target = new PipsPager
{
NumberOfPages = 5,
PreviousButtonTheme = previousTheme,
NextButtonTheme = nextTheme
};
var root = new TestRoot
{
Child = target,
Styles =
{
simpleTheme
}
};
Assert.True(simpleTheme.TryGetResource(typeof(PipsPager), ThemeVariant.Default, out var theme));
target.Theme = Assert.IsType<ControlTheme>(theme);
target.ApplyTemplate();
root.LayoutManager.ExecuteInitialLayoutPass();
var previousButton = target.GetVisualDescendants().OfType<Button>().First(b => b.Name == "PART_PreviousButton");
var nextButton = target.GetVisualDescendants().OfType<Button>().First(b => b.Name == "PART_NextButton");
Assert.Same(previousTheme, previousButton.Theme);
Assert.Same(nextTheme, nextButton.Theme);
}
[Fact]
public void Rapid_Page_Changes_Should_Maintain_Integrity()
{

45
tests/Avalonia.RenderTests/Controls/PipsPagerTests.cs

@ -1,24 +1,28 @@
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Shapes;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.Controls.Shapes;
using Avalonia.Styling;
using Avalonia.Threading;
using Xunit;
#if AVALONIA_SKIA
namespace Avalonia.Skia.RenderTests
#else
namespace Avalonia.Direct2D1.RenderTests.Controls
#endif
{
public class PipsPagerTests : TestBase
{
public PipsPagerTests()
: base(@"Controls/PipsPager")
: base(@"Controls\PipsPager")
{
}
private static IControlTemplate CreatePipsPagerTemplate()
{
return new FuncControlTemplate<PipsPager>((control, scope) =>
@ -26,7 +30,7 @@ namespace Avalonia.Skia.RenderTests
var stackPanel = new StackPanel
{
Name = "PART_RootPanel",
Spacing = 5,
Spacing = 4,
[!StackPanel.OrientationProperty] = control[!PipsPager.OrientationProperty],
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
@ -48,7 +52,7 @@ namespace Avalonia.Skia.RenderTests
var prevButton = new Button
{
Name = "PART_PreviousButton",
Content = "<",
Content = "<",
Template = buttonTemplate,
Width = 20,
Height = 20,
@ -65,8 +69,7 @@ namespace Avalonia.Skia.RenderTests
[!Button.IsVisibleProperty] = control[!PipsPager.IsNextButtonVisibleProperty]
}.RegisterInNameScope(scope);
// Simple ListBox Template (ItemsPresenter)
var listBoxTemplate = new FuncControlTemplate<ListBox>((lb, s) =>
var listBoxTemplate = new FuncControlTemplate<ListBox>((lb, s) =>
new ItemsPresenter
{
Name = "PART_ItemsPresenter",
@ -79,26 +82,24 @@ namespace Avalonia.Skia.RenderTests
Template = listBoxTemplate,
[!ListBox.ItemsSourceProperty] = new Binding("TemplateSettings.Pips") { Source = control },
[!ListBox.SelectedIndexProperty] = control[!PipsPager.SelectedPageIndexProperty],
ItemsPanel = new FuncTemplate<Panel?>(() => new StackPanel
{
ItemsPanel = new FuncTemplate<Panel?>(() => new StackPanel
{
Spacing = 2,
[!StackPanel.OrientationProperty] = control[!PipsPager.OrientationProperty]
[!StackPanel.OrientationProperty] = control[!PipsPager.OrientationProperty]
})
}.RegisterInNameScope(scope);
// Default Item Style
var itemStyle = new Style(x => x.OfType<ListBoxItem>());
itemStyle.Setters.Add(new Setter(ListBoxItem.TemplateProperty, new FuncControlTemplate<ListBoxItem>((item, s) =>
new Ellipse { Name="Pip", Width = 10, Height = 10 }.RegisterInNameScope(s))));
// Default Pip Fill Style
itemStyle.Setters.Add(new Setter(ListBoxItem.TemplateProperty,
new FuncControlTemplate<ListBoxItem>((item, s) =>
new Rectangle { Name = "Pip", Width = 10, Height = 10 }.RegisterInNameScope(s))));
var defaultPipStyle = new Style(x => x.OfType<ListBoxItem>().Template().Name("Pip"));
defaultPipStyle.Setters.Add(new Setter(Ellipse.FillProperty, Brushes.Gray));
// Selected Item Style
defaultPipStyle.Setters.Add(new Setter(Rectangle.FillProperty, Brushes.Gray));
var selectedStyle = new Style(x => x.OfType<ListBoxItem>().Class(":selected").Template().Name("Pip"));
selectedStyle.Setters.Add(new Setter(Ellipse.FillProperty, Brushes.Red));
selectedStyle.Setters.Add(new Setter(Rectangle.FillProperty, Brushes.Red));
pipsList.Styles.Add(itemStyle);
pipsList.Styles.Add(defaultPipStyle);
pipsList.Styles.Add(selectedStyle);
@ -135,7 +136,7 @@ namespace Avalonia.Skia.RenderTests
Dispatcher.UIThread.RunJobs(null, TestContext.Current.CancellationToken);
await RenderToFile(target);
CompareImages();
CompareImages(skipImmediate: true);
}
[Fact]
@ -162,7 +163,7 @@ namespace Avalonia.Skia.RenderTests
Dispatcher.UIThread.RunJobs(null, TestContext.Current.CancellationToken);
await RenderToFile(target);
CompareImages();
CompareImages(skipImmediate: true);
}
}
}

BIN
tests/TestFiles/Skia/Controls/PipsPager/PipsPager_Default.expected.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
tests/TestFiles/Skia/Controls/PipsPager/PipsPager_Preselected_Index.expected.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Loading…
Cancel
Save