Browse Source

Changes in CommandBar icon foreground inheritance (#21251)

* Fix navigation Fluent resources

* Fix 21016

* More tests
pull/21261/head
Javier Suárez 4 weeks ago
committed by GitHub
parent
commit
e81f3f7ff7
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 28
      samples/ControlCatalog/Pages/CommandBar/CommandBarCustomizationPage.xaml
  2. 39
      samples/ControlCatalog/Pages/CommandBar/CommandBarCustomizationPage.xaml.cs
  3. 19
      src/Avalonia.Controls/CommandBar/CommandBarButton.cs
  4. 19
      src/Avalonia.Controls/CommandBar/CommandBarToggleButton.cs
  5. 2
      src/Avalonia.Themes.Fluent/Controls/CarouselPage.xaml
  6. 8
      src/Avalonia.Themes.Fluent/Controls/NavigationPage.xaml
  7. 1
      src/Avalonia.Themes.Fluent/Controls/PathIcon.xaml
  8. 1
      src/Avalonia.Themes.Simple/Controls/PathIcon.xaml
  9. 137
      tests/Avalonia.Controls.UnitTests/CommandBarTests.cs

28
samples/ControlCatalog/Pages/CommandBar/CommandBarCustomizationPage.xaml

@ -29,10 +29,19 @@
HorizontalAlignment="Stretch"
SelectionChanged="OnBgPresetChanged">
<ComboBoxItem Content="Default" />
<ComboBoxItem Content="Blue (#0078D4)" />
<ComboBoxItem Content="Dark (#1C1C1E)" />
<ComboBoxItem Content="Gradient" />
<ComboBoxItem Content="Transparent" />
<ComboBoxItem Content="Blue (#0078D4)" Tag="#0078D4" />
<ComboBoxItem Content="Indigo (#3F51B5)" Tag="#3F51B5" />
<ComboBoxItem Content="Purple (#7B1FA2)" Tag="#7B1FA2" />
<ComboBoxItem Content="Pink (#C2185B)" Tag="#C2185B" />
<ComboBoxItem Content="Red (#D13438)" Tag="#D13438" />
<ComboBoxItem Content="Orange (#FF8C00)" Tag="#FF8C00" />
<ComboBoxItem Content="Green (#107C10)" Tag="#107C10" />
<ComboBoxItem Content="Teal (#008575)" Tag="#008575" />
<ComboBoxItem Content="Slate (#2F3A4A)" Tag="#2F3A4A" />
<ComboBoxItem Content="Light Gray (#F3F2F1)" Tag="#F3F2F1" />
<ComboBoxItem Content="Dark (#1C1C1E)" Tag="#1C1C1E" />
<ComboBoxItem Content="Gradient" Tag="Gradient" />
<ComboBoxItem Content="Transparent" Tag="Transparent" />
</ComboBox>
<TextBlock Text="Foreground" />
@ -41,8 +50,15 @@
HorizontalAlignment="Stretch"
SelectionChanged="OnFgChanged">
<ComboBoxItem Content="Default" />
<ComboBoxItem Content="White" />
<ComboBoxItem Content="Black" />
<ComboBoxItem Content="White (#FFFFFF)" Tag="#FFFFFF" />
<ComboBoxItem Content="Black (#000000)" Tag="#000000" />
<ComboBoxItem Content="Blue (#0078D4)" Tag="#0078D4" />
<ComboBoxItem Content="Purple (#7B1FA2)" Tag="#7B1FA2" />
<ComboBoxItem Content="Red (#D13438)" Tag="#D13438" />
<ComboBoxItem Content="Orange (#FF8C00)" Tag="#FF8C00" />
<ComboBoxItem Content="Green (#107C10)" Tag="#107C10" />
<ComboBoxItem Content="Teal (#008575)" Tag="#008575" />
<ComboBoxItem Content="Light Gray (#F3F2F1)" Tag="#F3F2F1" />
</ComboBox>
<TextBlock Text="Corner Radius" />

39
samples/ControlCatalog/Pages/CommandBar/CommandBarCustomizationPage.xaml.cs

@ -14,16 +14,16 @@ namespace ControlCatalog.Pages
{
if (LiveBar == null)
return;
switch (BgPresetCombo.SelectedIndex)
if (BgPresetCombo.SelectedItem is not ComboBoxItem { Tag: string preset })
{
case 1:
LiveBar.Background = new SolidColorBrush(Color.Parse("#0078D4"));
break;
case 2:
LiveBar.Background = new SolidColorBrush(Color.Parse("#1C1C1E"));
break;
case 3:
LiveBar.ClearValue(BackgroundProperty);
return;
}
switch (preset)
{
case "Gradient":
LiveBar.Background = new LinearGradientBrush
{
StartPoint = new Avalonia.RelativePoint(0, 0, Avalonia.RelativeUnit.Relative),
@ -35,11 +35,11 @@ namespace ControlCatalog.Pages
}
};
break;
case 4:
case "Transparent":
LiveBar.Background = Brushes.Transparent;
break;
default:
LiveBar.ClearValue(BackgroundProperty);
LiveBar.Background = new SolidColorBrush(Color.Parse(preset));
break;
}
}
@ -48,19 +48,14 @@ namespace ControlCatalog.Pages
{
if (LiveBar == null)
return;
switch (FgCombo.SelectedIndex)
if (FgCombo.SelectedItem is ComboBoxItem { Tag: string color })
{
case 1:
LiveBar.Foreground = Brushes.White;
break;
case 2:
LiveBar.Foreground = Brushes.Black;
break;
default:
LiveBar.ClearValue(ForegroundProperty);
break;
LiveBar.Foreground = new SolidColorBrush(Color.Parse(color));
return;
}
LiveBar.ClearValue(ForegroundProperty);
}
private void OnRadiusChanged(object? sender, Avalonia.Controls.Primitives.RangeBaseValueChangedEventArgs e)

19
src/Avalonia.Controls/CommandBar/CommandBarButton.cs

@ -5,12 +5,6 @@ namespace Avalonia.Controls
/// </summary>
public class CommandBarButton : Button, ICommandBarElement
{
static CommandBarButton()
{
ForegroundProperty.Changed.AddClassHandler<CommandBarButton>((x, _) => x.UpdateIconForeground());
IconProperty.Changed.AddClassHandler<CommandBarButton>((x, _) => x.UpdateIconForeground());
}
/// <summary>
/// Defines the <see cref="Label"/> property.
/// </summary>
@ -102,18 +96,5 @@ namespace Avalonia.Controls
get => GetValue(IsInOverflowProperty);
set => SetValue(IsInOverflowProperty, value);
}
private void UpdateIconForeground()
{
if (Icon is IconElement icon)
{
var fg = Foreground;
if (fg != null)
icon.SetValue(ForegroundProperty, fg);
else
icon.ClearValue(ForegroundProperty);
}
}
}
}

19
src/Avalonia.Controls/CommandBar/CommandBarToggleButton.cs

@ -7,12 +7,6 @@ namespace Avalonia.Controls
/// </summary>
public class CommandBarToggleButton : ToggleButton, ICommandBarElement
{
static CommandBarToggleButton()
{
ForegroundProperty.Changed.AddClassHandler<CommandBarToggleButton>((x, _) => x.UpdateIconForeground());
IconProperty.Changed.AddClassHandler<CommandBarToggleButton>((x, _) => x.UpdateIconForeground());
}
/// <summary>
/// Defines the <see cref="Label"/> property.
/// </summary>
@ -104,18 +98,5 @@ namespace Avalonia.Controls
get => GetValue(IsInOverflowProperty);
set => SetValue(IsInOverflowProperty, value);
}
private void UpdateIconForeground()
{
if (Icon is IconElement icon)
{
var fg = Foreground;
if (fg != null)
icon.SetValue(ForegroundProperty, fg);
else
icon.ClearValue(ForegroundProperty);
}
}
}
}

2
src/Avalonia.Themes.Fluent/Controls/CarouselPage.xaml

@ -14,7 +14,7 @@
</Design.PreviewWith>
<ControlTheme x:Key="{x:Type CarouselPage}" TargetType="CarouselPage">
<Setter Property="Background" Value="{DynamicResource SolidBackgroundFillColorBaseBrush}" />
<Setter Property="Background" Value="{DynamicResource SystemControlPageBackgroundAltHighBrush}" />
<Setter Property="Template">
<ControlTemplate>
<Carousel Name="PART_Carousel"

8
src/Avalonia.Themes.Fluent/Controls/NavigationPage.xaml

@ -83,10 +83,10 @@
<Setter Property="CornerRadius" Value="4" />
</Style>
<Style Selector="Button#PART_BackButton:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightListLowBrush}" />
</Style>
<Style Selector="Button#PART_BackButton:pressed /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTertiaryBrush}" />
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightListMediumBrush}" />
</Style>
<Style Selector="Button#PART_BackButton:disabled">
<Setter Property="Opacity" Value="0.4" />
@ -104,10 +104,10 @@
<Setter Property="CornerRadius" Value="0" />
</Style>
<Style Selector="Button#PART_OverflowButton:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightListLowBrush}" />
</Style>
<Style Selector="Button#PART_OverflowButton:pressed /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTertiaryBrush}" />
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightListMediumBrush}" />
</Style>
</Grid.Styles>

1
src/Avalonia.Themes.Fluent/Controls/PathIcon.xaml

@ -10,7 +10,6 @@
</StackPanel>
</Design.PreviewWith>
<ControlTheme x:Key="{x:Type PathIcon}" TargetType="PathIcon">
<Setter Property="Foreground" Value="{DynamicResource TextControlForeground}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Height" Value="{DynamicResource IconElementThemeHeight}" />
<Setter Property="Width" Value="{DynamicResource IconElementThemeWidth}" />

1
src/Avalonia.Themes.Simple/Controls/PathIcon.xaml

@ -3,7 +3,6 @@
x:ClassModifier="internal">
<ControlTheme x:Key="{x:Type PathIcon}"
TargetType="PathIcon">
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundColor}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Height" Value="{DynamicResource IconElementThemeHeight}" />
<Setter Property="Width" Value="{DynamicResource IconElementThemeWidth}" />

137
tests/Avalonia.Controls.UnitTests/CommandBarTests.cs

@ -3,9 +3,14 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.LogicalTree;
using Avalonia.Media;
using Avalonia.Styling;
using Avalonia.Themes.Simple;
using Avalonia.Threading;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
@ -118,6 +123,28 @@ public class CommandBarButtonTests : ScopedTestBase
var btn = new CommandBarButton { CommandParameter = "param" };
Assert.Equal("param", btn.CommandParameter);
}
[Fact]
public void Foreground_DoesNotSetOrOverwriteIconElementForeground()
{
var icon = new PathIcon();
var btn = new CommandBarButton
{
Icon = icon,
Foreground = Brushes.Red
};
Assert.False(icon.IsSet(TemplatedControl.ForegroundProperty));
btn.Foreground = Brushes.Blue;
Assert.False(icon.IsSet(TemplatedControl.ForegroundProperty));
icon.Foreground = Brushes.Green;
btn.Foreground = Brushes.Red;
Assert.Same(Brushes.Green, icon.Foreground);
}
}
public class CommandBarToggleButtonTests : ScopedTestBase
@ -205,6 +232,28 @@ public class CommandBarToggleButtonTests : ScopedTestBase
var btn = new CommandBarToggleButton { CommandParameter = 42 };
Assert.Equal(42, btn.CommandParameter);
}
[Fact]
public void Foreground_DoesNotSetOrOverwriteIconElementForeground()
{
var icon = new PathIcon();
var btn = new CommandBarToggleButton
{
Icon = icon,
Foreground = Brushes.Red
};
Assert.False(icon.IsSet(TemplatedControl.ForegroundProperty));
btn.Foreground = Brushes.Blue;
Assert.False(icon.IsSet(TemplatedControl.ForegroundProperty));
icon.Foreground = Brushes.Green;
btn.Foreground = Brushes.Red;
Assert.Same(Brushes.Green, icon.Foreground);
}
}
public class CommandBarSeparatorTests : ScopedTestBase
@ -309,6 +358,54 @@ public class CommandBarDefaultsTests : ScopedTestBase
public void Content_DefaultIsNull()
=> Assert.Null(new CommandBar().Content);
[Fact]
public void Foreground_IsInheritedByCommandBarButtonPathIconThroughThemeTemplate()
{
using var app = UnitTestApplication.Start(TestServices.StyledWindow);
var icon = new PathIcon();
var btn = new CommandBarButton
{
Icon = icon
};
var commandBar = new CommandBar
{
Foreground = Brushes.Red
};
commandBar.PrimaryCommands.Add(btn);
Assert.Same(icon, ApplySimpleThemeAndGetPresentedPathIcon(commandBar, btn));
Assert.Same(Brushes.Red, icon.Foreground);
commandBar.Foreground = Brushes.Blue;
Assert.Same(Brushes.Blue, icon.Foreground);
}
[Fact]
public void Foreground_IsInheritedByCommandBarToggleButtonPathIconThroughThemeTemplate()
{
using var app = UnitTestApplication.Start(TestServices.StyledWindow);
var icon = new PathIcon();
var btn = new CommandBarToggleButton
{
Icon = icon
};
var commandBar = new CommandBar
{
Foreground = Brushes.Red
};
commandBar.PrimaryCommands.Add(btn);
Assert.Same(icon, ApplySimpleThemeAndGetPresentedPathIcon(commandBar, btn));
Assert.Same(Brushes.Red, icon.Foreground);
commandBar.Foreground = Brushes.Blue;
Assert.Same(Brushes.Blue, icon.Foreground);
}
[Fact]
public void PrimaryCommands_NotNull()
=> Assert.NotNull(new CommandBar().PrimaryCommands);
@ -370,6 +467,46 @@ public class CommandBarDefaultsTests : ScopedTestBase
[Fact]
public void ItemWidthCollapsed_DefaultIs42()
=> Assert.Equal(42d, new CommandBar().ItemWidthCollapsed);
private static PathIcon ApplySimpleThemeAndGetPresentedPathIcon(CommandBar commandBar, TemplatedControl command)
{
var simpleTheme = new SimpleTheme();
Assert.True(simpleTheme.TryGetResource(typeof(CommandBar), ThemeVariant.Default, out var commandBarTheme));
Assert.True(simpleTheme.TryGetResource(command.GetType(), ThemeVariant.Default, out var commandTheme));
commandBar.Theme = Assert.IsType<ControlTheme>(commandBarTheme);
command.Theme = Assert.IsType<ControlTheme>(commandTheme);
var root = new TestRoot
{
Width = 500,
Height = 200,
Child = commandBar,
Styles =
{
simpleTheme
}
};
root.ApplyStyling();
commandBar.ApplyStyling();
commandBar.ApplyTemplate();
root.LayoutManager.ExecuteInitialLayoutPass();
command.ApplyStyling();
command.ApplyTemplate();
var presenter = command.GetTemplateChildren()
.OfType<ContentPresenter>()
.Single(x => x.Name == "PART_IconPresenter");
presenter.ApplyStyling();
presenter.UpdateChild();
var pathIcon = Assert.IsType<PathIcon>(presenter.Child);
pathIcon.ApplyStyling();
return pathIcon;
}
}
public class CommandBarPropertyRoundTripTests : ScopedTestBase

Loading…
Cancel
Save