Browse Source

Merge branch 'master' into feature/extend-client-area-to-decorations

pull/3967/head
danwalmsley 6 years ago
committed by GitHub
parent
commit
086c4bffeb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 26
      samples/ControlCatalog/Pages/ProgressBarPage.xaml
  2. 1
      src/Avalonia.Base/Collections/AvaloniaListExtensions.cs
  3. 164
      src/Avalonia.Controls/ProgressBar.cs
  4. 9
      src/Avalonia.Controls/Utils/IEnumerableUtils.cs
  5. 10
      src/Avalonia.Diagnostics/Diagnostics/DevTools.cs
  6. 29
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/LogicalTreeNode.cs
  7. 23
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs
  8. 14
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs
  9. 78
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNodeCollection.cs
  10. 10
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs
  11. 37
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/VisualTreeNode.cs
  12. 22
      src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs
  13. 12
      src/Avalonia.Themes.Default/ProgressBar.xaml
  14. 5
      src/Avalonia.Themes.Fluent/Accents/FluentBaseDark.xaml
  15. 6
      src/Avalonia.Themes.Fluent/Accents/FluentBaseLight.xaml
  16. 9
      src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml
  17. 8
      src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesLight.xaml
  18. 44
      src/Avalonia.Themes.Fluent/FocusAdorner.xaml
  19. 191
      src/Avalonia.Themes.Fluent/ProgressBar.xaml
  20. 16
      src/Avalonia.Themes.Fluent/ToolTip.xaml

26
samples/ControlCatalog/Pages/ProgressBarPage.xaml

@ -1,29 +1,19 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.Pages.ProgressBarPage">
<UserControl xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="ControlCatalog.Pages.ProgressBarPage">
<StackPanel Orientation="Vertical" Spacing="4">
<TextBlock Classes="h1">ProgressBar</TextBlock>
<TextBlock Classes="h2">A progress bar control</TextBlock>
<StackPanel>
<CheckBox
x:Name="showProgress"
Margin="10,16,0,0"
Content="Show Progress Text" />
<StackPanel Orientation="Horizontal"
Margin="0,16,0,0"
HorizontalAlignment="Center"
Spacing="16">
<CheckBox x:Name="showProgress" Margin="10,16,0,0" Content="Show Progress Text" />
<CheckBox x:Name="isIndeterminate" Margin="10,16,0,0" Content="Toggle Indeterminate" />
<StackPanel Orientation="Horizontal" Margin="0,16,0,0" HorizontalAlignment="Center" Spacing="16">
<StackPanel Spacing="16">
<ProgressBar ShowProgressText="{Binding #showProgress.IsChecked}" Value="{Binding #hprogress.Value}" />
<ProgressBar IsIndeterminate="True"/>
<ProgressBar IsIndeterminate="{Binding #isIndeterminate.IsChecked}" ShowProgressText="{Binding #showProgress.IsChecked}" Value="{Binding #hprogress.Value}" />
</StackPanel>
<ProgressBar ShowProgressText="{Binding #showProgress.IsChecked}" Value="{Binding #vprogress.Value}" Orientation="Vertical" />
<ProgressBar Orientation="Vertical" IsIndeterminate="True" />
<ProgressBar IsIndeterminate="{Binding #isIndeterminate.IsChecked}" ShowProgressText="{Binding #showProgress.IsChecked}" Value="{Binding #vprogress.Value}" Orientation="Vertical" />
</StackPanel>
<StackPanel Margin="16">
<Slider Name="hprogress" Maximum="100" Value="40"/>
<Slider Name="vprogress" Maximum="100" Value="60"/>
<Slider Name="hprogress" Maximum="100" Value="40" />
<Slider Name="vprogress" Maximum="100" Value="60" />
</StackPanel>
</StackPanel>
</StackPanel>

1
src/Avalonia.Base/Collections/AvaloniaListExtensions.cs

@ -140,6 +140,7 @@ namespace Avalonia.Collections
}
}
[Obsolete("Causes memory leaks. Use DynamicData or similar instead.")]
public static IAvaloniaReadOnlyList<TDerived> CreateDerivedList<TSource, TDerived>(
this IAvaloniaReadOnlyList<TSource> collection,
Func<TSource, TDerived> select)

164
src/Avalonia.Controls/ProgressBar.cs

@ -1,8 +1,7 @@
using System;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Layout;
using Avalonia.Media;
namespace Avalonia.Controls
{
@ -11,6 +10,92 @@ namespace Avalonia.Controls
/// </summary>
public class ProgressBar : RangeBase
{
public class ProgressBarTemplateProperties : AvaloniaObject
{
private double _container2Width;
private double _containerWidth;
private double _containerAnimationStartPosition;
private double _containerAnimationEndPosition;
private double _container2AnimationStartPosition;
private double _container2AnimationEndPosition;
public static readonly DirectProperty<ProgressBarTemplateProperties, double> ContainerAnimationStartPositionProperty =
AvaloniaProperty.RegisterDirect<ProgressBarTemplateProperties, double>(
nameof(ContainerAnimationStartPosition),
p => p.ContainerAnimationStartPosition,
(p, o) => p.ContainerAnimationStartPosition = o, 0d);
public static readonly DirectProperty<ProgressBarTemplateProperties, double> ContainerAnimationEndPositionProperty =
AvaloniaProperty.RegisterDirect<ProgressBarTemplateProperties, double>(
nameof(ContainerAnimationEndPosition),
p => p.ContainerAnimationEndPosition,
(p, o) => p.ContainerAnimationEndPosition = o, 0d);
public static readonly DirectProperty<ProgressBarTemplateProperties, double> Container2AnimationStartPositionProperty =
AvaloniaProperty.RegisterDirect<ProgressBarTemplateProperties, double>(
nameof(Container2AnimationStartPosition),
p => p.Container2AnimationStartPosition,
(p, o) => p.Container2AnimationStartPosition = o, 0d);
public static readonly DirectProperty<ProgressBarTemplateProperties, double> Container2AnimationEndPositionProperty =
AvaloniaProperty.RegisterDirect<ProgressBarTemplateProperties, double>(
nameof(Container2AnimationEndPosition),
p => p.Container2AnimationEndPosition,
(p, o) => p.Container2AnimationEndPosition = o);
public static readonly DirectProperty<ProgressBarTemplateProperties, double> Container2WidthProperty =
AvaloniaProperty.RegisterDirect<ProgressBarTemplateProperties, double>(
nameof(Container2Width),
p => p.Container2Width,
(p, o) => p.Container2Width = o);
public static readonly DirectProperty<ProgressBarTemplateProperties, double> ContainerWidthProperty =
AvaloniaProperty.RegisterDirect<ProgressBarTemplateProperties, double>(
nameof(ContainerWidth),
p => p.ContainerWidth,
(p, o) => p.ContainerWidth = o);
public double ContainerAnimationStartPosition
{
get => _containerAnimationStartPosition;
set => SetAndRaise(ContainerAnimationStartPositionProperty, ref _containerAnimationStartPosition, value);
}
public double ContainerAnimationEndPosition
{
get => _containerAnimationEndPosition;
set => SetAndRaise(ContainerAnimationEndPositionProperty, ref _containerAnimationEndPosition, value);
}
public double Container2AnimationStartPosition
{
get => _container2AnimationStartPosition;
set => SetAndRaise(Container2AnimationStartPositionProperty, ref _container2AnimationStartPosition, value);
}
public double Container2Width
{
get => _container2Width;
set => SetAndRaise(Container2WidthProperty, ref _container2Width, value);
}
public double ContainerWidth
{
get => _containerWidth;
set => SetAndRaise(ContainerWidthProperty, ref _containerWidth, value);
}
public double Container2AnimationEndPosition
{
get => _container2AnimationEndPosition;
set => SetAndRaise(Container2AnimationEndPositionProperty, ref _container2AnimationEndPosition, value);
}
}
private double _indeterminateStartingOffset;
private double _indeterminateEndingOffset;
private Border _indicator;
public static readonly StyledProperty<bool> IsIndeterminateProperty =
AvaloniaProperty.Register<ProgressBar, bool>(nameof(IsIndeterminate));
@ -20,19 +105,33 @@ namespace Avalonia.Controls
public static readonly StyledProperty<Orientation> OrientationProperty =
AvaloniaProperty.Register<ProgressBar, Orientation>(nameof(Orientation), Orientation.Horizontal);
private static readonly DirectProperty<ProgressBar, double> IndeterminateStartingOffsetProperty =
[Obsolete("To be removed when Avalonia.Themes.Default is discontinued.")]
public static readonly DirectProperty<ProgressBar, double> IndeterminateStartingOffsetProperty =
AvaloniaProperty.RegisterDirect<ProgressBar, double>(
nameof(IndeterminateStartingOffset),
p => p.IndeterminateStartingOffset,
(p, o) => p.IndeterminateStartingOffset = o);
private static readonly DirectProperty<ProgressBar, double> IndeterminateEndingOffsetProperty =
[Obsolete("To be removed when Avalonia.Themes.Default is discontinued.")]
public static readonly DirectProperty<ProgressBar, double> IndeterminateEndingOffsetProperty =
AvaloniaProperty.RegisterDirect<ProgressBar, double>(
nameof(IndeterminateEndingOffset),
p => p.IndeterminateEndingOffset,
(p, o) => p.IndeterminateEndingOffset = o);
private Border _indicator;
[Obsolete("To be removed when Avalonia.Themes.Default is discontinued.")]
public double IndeterminateStartingOffset
{
get => _indeterminateStartingOffset;
set => SetAndRaise(IndeterminateStartingOffsetProperty, ref _indeterminateStartingOffset, value);
}
[Obsolete("To be removed when Avalonia.Themes.Default is discontinued.")]
public double IndeterminateEndingOffset
{
get => _indeterminateEndingOffset;
set => SetAndRaise(IndeterminateEndingOffsetProperty, ref _indeterminateEndingOffset, value);
}
static ProgressBar()
{
@ -45,6 +144,8 @@ namespace Avalonia.Controls
UpdatePseudoClasses(IsIndeterminate, Orientation);
}
public ProgressBarTemplateProperties TemplateProperties { get; } = new ProgressBarTemplateProperties();
public bool IsIndeterminate
{
get => GetValue(IsIndeterminateProperty);
@ -62,19 +163,6 @@ namespace Avalonia.Controls
get => GetValue(OrientationProperty);
set => SetValue(OrientationProperty, value);
}
private double _indeterminateStartingOffset;
private double IndeterminateStartingOffset
{
get => _indeterminateStartingOffset;
set => SetAndRaise(IndeterminateStartingOffsetProperty, ref _indeterminateStartingOffset, value);
}
private double _indeterminateEndingOffset;
private double IndeterminateEndingOffset
{
get => _indeterminateEndingOffset;
set => SetAndRaise(IndeterminateEndingOffsetProperty, ref _indeterminateEndingOffset, value);
}
/// <inheritdoc/>
protected override Size ArrangeOverride(Size finalSize)
@ -111,21 +199,33 @@ namespace Avalonia.Controls
{
if (IsIndeterminate)
{
if (Orientation == Orientation.Horizontal)
{
var width = bounds.Width / 5.0;
IndeterminateStartingOffset = -width;
_indicator.Width = width;
IndeterminateEndingOffset = bounds.Width;
// Pulled from ModernWPF.
}
else
{
var height = bounds.Height / 5.0;
IndeterminateStartingOffset = -bounds.Height;
_indicator.Height = height;
IndeterminateEndingOffset = height;
}
var dim = Orientation == Orientation.Horizontal ? bounds.Width : bounds.Height;
var barIndicatorWidth = dim * 0.4; // Indicator width at 40% of ProgressBar
var barIndicatorWidth2 = dim * 0.6; // Indicator width at 60% of ProgressBar
TemplateProperties.ContainerWidth = barIndicatorWidth;
TemplateProperties.Container2Width = barIndicatorWidth2;
TemplateProperties.ContainerAnimationStartPosition = barIndicatorWidth * -1.8; // Position at -180%
TemplateProperties.ContainerAnimationEndPosition = barIndicatorWidth * 3.0; // Position at 300%
TemplateProperties.Container2AnimationStartPosition = barIndicatorWidth2 * -1.5; // Position at -150%
TemplateProperties.Container2AnimationEndPosition = barIndicatorWidth2 * 1.66; // Position at 166%
// Remove these properties when we switch to fluent as default and removed the old one.
IndeterminateStartingOffset = -(dim / 5d);
IndeterminateEndingOffset = dim;
var padding = Padding;
var rectangle = new RectangleGeometry(
new Rect(
padding.Left,
padding.Top,
bounds.Width - (padding.Right + padding.Left),
bounds.Height - (padding.Bottom + padding.Top)
));
}
else
{

9
src/Avalonia.Controls/Utils/IEnumerableUtils.cs

@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Avalonia.Controls.Utils
@ -15,12 +16,14 @@ namespace Avalonia.Controls.Utils
{
if (items != null)
{
var collection = items as ICollection;
if (collection != null)
if (items is ICollection collection)
{
return collection.Count;
}
else if (items is IReadOnlyCollection<object> readOnly)
{
return readOnly.Count;
}
else
{
return Enumerable.Count(items.Cast<object>());

10
src/Avalonia.Diagnostics/Diagnostics/DevTools.cs

@ -45,7 +45,15 @@ namespace Avalonia.Diagnostics
window.Closed += DevToolsClosed;
s_open.Add(root, window);
window.Show();
if (root is Window inspectedWindow)
{
window.Show(inspectedWindow);
}
else
{
window.Show();
}
}
return Disposable.Create(() => window?.Close());

29
src/Avalonia.Diagnostics/Diagnostics/ViewModels/LogicalTreeNode.cs

@ -1,3 +1,4 @@
using System;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.LogicalTree;
@ -9,7 +10,7 @@ namespace Avalonia.Diagnostics.ViewModels
public LogicalTreeNode(ILogical logical, TreeNode parent)
: base((Control)logical, parent)
{
Children = logical.LogicalChildren.CreateDerivedList(x => new LogicalTreeNode(x, this));
Children = new LogicalTreeNodeCollection(this, logical);
}
public static LogicalTreeNode[] Create(object control)
@ -17,5 +18,31 @@ namespace Avalonia.Diagnostics.ViewModels
var logical = control as ILogical;
return logical != null ? new[] { new LogicalTreeNode(logical, null) } : null;
}
internal class LogicalTreeNodeCollection : TreeNodeCollection
{
private readonly ILogical _control;
private IDisposable _subscription;
public LogicalTreeNodeCollection(TreeNode owner, ILogical control)
: base(owner)
{
_control = control;
}
public override void Dispose()
{
base.Dispose();
_subscription?.Dispose();
}
protected override void Initialize(AvaloniaList<TreeNode> nodes)
{
_subscription = _control.LogicalChildren.ForEachItem(
(i, item) => nodes.Insert(i, new LogicalTreeNode(item, Owner)),
(i, item) => nodes.RemoveAt(i),
() => nodes.Clear());
}
}
}
}

23
src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs

@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using Avalonia.Controls;
using Avalonia.Diagnostics.Models;
using Avalonia.Input;
@ -12,6 +13,7 @@ namespace Avalonia.Diagnostics.ViewModels
private readonly TreePageViewModel _logicalTree;
private readonly TreePageViewModel _visualTree;
private readonly EventsPageViewModel _events;
private readonly IDisposable _pointerOverSubscription;
private ViewModelBase _content;
private int _selectedTab;
private string _focusedControl;
@ -25,16 +27,9 @@ namespace Avalonia.Diagnostics.ViewModels
_events = new EventsPageViewModel(root);
UpdateFocusedControl();
KeyboardDevice.Instance.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(KeyboardDevice.Instance.FocusedElement))
{
UpdateFocusedControl();
}
};
KeyboardDevice.Instance.PropertyChanged += KeyboardPropertyChanged;
SelectedTab = 0;
root.GetObservable(TopLevel.PointerOverElementProperty)
_pointerOverSubscription = root.GetObservable(TopLevel.PointerOverElementProperty)
.Subscribe(x => PointerOverElement = x?.GetType().Name);
Console = new ConsoleViewModel(UpdateConsoleContext);
}
@ -129,6 +124,8 @@ namespace Avalonia.Diagnostics.ViewModels
public void Dispose()
{
KeyboardDevice.Instance.PropertyChanged -= KeyboardPropertyChanged;
_pointerOverSubscription.Dispose();
_logicalTree.Dispose();
_visualTree.Dispose();
}
@ -137,5 +134,13 @@ namespace Avalonia.Diagnostics.ViewModels
{
FocusedControl = KeyboardDevice.Instance.FocusedElement?.GetType().Name;
}
private void KeyboardPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(KeyboardDevice.Instance.FocusedElement))
{
UpdateFocusedControl();
}
}
}
}

14
src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNode.cs

@ -3,15 +3,15 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reactive;
using System.Reactive.Linq;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.LogicalTree;
using Avalonia.VisualTree;
namespace Avalonia.Diagnostics.ViewModels
{
internal class TreeNode : ViewModelBase
internal class TreeNode : ViewModelBase, IDisposable
{
private IDisposable _classesSubscription;
private string _classes;
private bool _isExpanded;
@ -33,7 +33,7 @@ namespace Avalonia.Diagnostics.ViewModels
x => control.Classes.CollectionChanged -= x)
.TakeUntil(removed);
classesChanged.Select(_ => Unit.Default)
_classesSubscription = classesChanged.Select(_ => Unit.Default)
.StartWith(Unit.Default)
.Subscribe(_ =>
{
@ -49,7 +49,7 @@ namespace Avalonia.Diagnostics.ViewModels
}
}
public IAvaloniaReadOnlyList<TreeNode> Children
public TreeNodeCollection Children
{
get;
protected set;
@ -104,6 +104,12 @@ namespace Avalonia.Diagnostics.ViewModels
}
}
public void Dispose()
{
_classesSubscription.Dispose();
Children.Dispose();
}
private static int IndexOf(IReadOnlyList<TreeNode> collection, TreeNode item)
{
var count = collection.Count;

78
src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreeNodeCollection.cs

@ -0,0 +1,78 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using Avalonia.Collections;
namespace Avalonia.Diagnostics.ViewModels
{
internal abstract class TreeNodeCollection : IAvaloniaReadOnlyList<TreeNode>, IDisposable
{
private AvaloniaList<TreeNode> _inner;
public TreeNodeCollection(TreeNode owner) => Owner = owner;
public TreeNode this[int index]
{
get
{
EnsureInitialized();
return _inner[index];
}
}
public int Count
{
get
{
EnsureInitialized();
return _inner.Count;
}
}
protected TreeNode Owner { get; }
public event NotifyCollectionChangedEventHandler CollectionChanged
{
add => _inner.CollectionChanged += value;
remove => _inner.CollectionChanged -= value;
}
public event PropertyChangedEventHandler PropertyChanged
{
add => _inner.PropertyChanged += value;
remove => _inner.PropertyChanged -= value;
}
public virtual void Dispose()
{
if (_inner is object)
{
foreach (var node in _inner)
{
node.Dispose();
}
}
}
public IEnumerator<TreeNode> GetEnumerator()
{
EnsureInitialized();
return _inner.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
protected abstract void Initialize(AvaloniaList<TreeNode> nodes);
private void EnsureInitialized()
{
if (_inner is null)
{
_inner = new AvaloniaList<TreeNode>();
Initialize(_inner);
}
}
}
}

10
src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs

@ -62,7 +62,15 @@ namespace Avalonia.Diagnostics.ViewModels
}
}
public void Dispose() => _details?.Dispose();
public void Dispose()
{
foreach (var node in Nodes)
{
node.Dispose();
}
_details?.Dispose();
}
public TreeNode FindNode(IControl control)
{

37
src/Avalonia.Diagnostics/Diagnostics/ViewModels/VisualTreeNode.cs

@ -1,3 +1,4 @@
using System;
using Avalonia.Collections;
using Avalonia.Styling;
using Avalonia.VisualTree;
@ -9,16 +10,7 @@ namespace Avalonia.Diagnostics.ViewModels
public VisualTreeNode(IVisual visual, TreeNode parent)
: base(visual, parent)
{
var host = visual as IVisualTreeHost;
if (host?.Root == null)
{
Children = visual.VisualChildren.CreateDerivedList(x => new VisualTreeNode(x, this));
}
else
{
Children = new AvaloniaList<VisualTreeNode>(new[] { new VisualTreeNode(host.Root, this) });
}
Children = new VisualTreeNodeCollection(this, visual);
if ((Visual is IStyleable styleable))
{
@ -33,5 +25,30 @@ namespace Avalonia.Diagnostics.ViewModels
var visual = control as IVisual;
return visual != null ? new[] { new VisualTreeNode(visual, null) } : null;
}
internal class VisualTreeNodeCollection : TreeNodeCollection
{
private readonly IVisual _control;
private IDisposable _subscription;
public VisualTreeNodeCollection(TreeNode owner, IVisual control)
: base(owner)
{
_control = control;
}
public override void Dispose()
{
_subscription?.Dispose();
}
protected override void Initialize(AvaloniaList<TreeNode> nodes)
{
_subscription = _control.VisualChildren.ForEachItem(
(i, item) => nodes.Insert(i, new VisualTreeNode(item, Owner)),
(i, item) => nodes.RemoveAt(i),
() => nodes.Clear());
}
}
}
}

22
src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml.cs

@ -14,8 +14,8 @@ namespace Avalonia.Diagnostics.Views
{
internal class MainWindow : Window, IStyleHost
{
private readonly IDisposable _keySubscription;
private TopLevel _root;
private IDisposable _keySubscription;
public MainWindow()
{
@ -33,8 +33,22 @@ namespace Avalonia.Diagnostics.Views
{
if (_root != value)
{
if (_root != null)
{
_root.Closed -= RootClosed;
}
_root = value;
DataContext = new MainViewModel(value);
if (_root != null)
{
_root.Closed += RootClosed;
DataContext = new MainViewModel(value);
}
else
{
DataContext = null;
}
}
}
}
@ -45,6 +59,8 @@ namespace Avalonia.Diagnostics.Views
{
base.OnClosed(e);
_keySubscription.Dispose();
_root.Closed -= RootClosed;
_root = null;
((MainViewModel)DataContext)?.Dispose();
}
@ -70,5 +86,7 @@ namespace Avalonia.Diagnostics.Views
}
}
}
private void RootClosed(object sender, EventArgs e) => Close();
}
}

12
src/Avalonia.Themes.Default/ProgressBar.xaml

@ -1,4 +1,12 @@
<Styles xmlns="https://github.com/avaloniaui">
<Design.PreviewWith>
<Border Padding="20">
<StackPanel>
<ProgressBar VerticalAlignment="Center" IsIndeterminate="True" />
<ProgressBar HorizontalAlignment="Left" IsIndeterminate="True" Orientation="Vertical" />
</StackPanel>
</Border>
</Design.PreviewWith>
<Style Selector="ProgressBar">
<Setter Property="Background" Value="{DynamicResource ThemeAccentBrush4}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeAccentBrush}"/>
@ -69,11 +77,11 @@
Easing="LinearEasing">
<KeyFrame Cue="0%">
<Setter Property="TranslateTransform.Y"
Value="{Binding IndeterminateStartingOffset, RelativeSource={RelativeSource TemplatedParent}}" />
Value="{Binding TemplateProperties.IndeterminateStartingOffset, RelativeSource={RelativeSource TemplatedParent}}" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="TranslateTransform.Y"
Value="{Binding IndeterminateEndingOffset, RelativeSource={RelativeSource TemplatedParent}}" />
Value="{Binding TemplateProperties.IndeterminateEndingOffset, RelativeSource={RelativeSource TemplatedParent}}" />
</KeyFrame>
</Animation>
</Style.Animations>

5
src/Avalonia.Themes.Fluent/Accents/FluentBaseDark.xaml

@ -184,6 +184,11 @@
<SolidColorBrush x:Key="ListBoxItemSelectedDisabledForegroundThemeBrush" Color="#99000000" />
<SolidColorBrush x:Key="ListBoxItemSelectedForegroundThemeBrush" Color="White" />
<SolidColorBrush x:Key="ListBoxItemSelectedPointerOverBackgroundThemeBrush" Color="#FF5F37BE" />
<!-- BaseResources for ProgressBar.xaml -->
<SolidColorBrush x:Key="ProgressBarBackgroundThemeBrush" Color="#30000000" />
<SolidColorBrush x:Key="ProgressBarBorderThemeBrush" Color="Transparent" />
<SolidColorBrush x:Key="ProgressBarForegroundThemeBrush" Color="#FF4617B4" />
<SolidColorBrush x:Key="ProgressBarIndeterminateForegroundThemeBrush" Color="#FF4617B4" />
<!-- BaseResources for TextBox.xaml -->
<StaticResource x:Key="TextControlForeground" ResourceKey="SystemControlForegroundBaseHighBrush" />

6
src/Avalonia.Themes.Fluent/Accents/FluentBaseLight.xaml

@ -187,6 +187,12 @@
<SolidColorBrush x:Key="ListBoxItemSelectedForegroundThemeBrush" Color="White" />
<SolidColorBrush x:Key="ListBoxItemSelectedPointerOverBackgroundThemeBrush" Color="#FF5F37BE" />
<!-- BaseResources for ProgressBar.xaml -->
<SolidColorBrush x:Key="ProgressBarBackgroundThemeBrush" Color="#59FFFFFF" />
<SolidColorBrush x:Key="ProgressBarBorderThemeBrush" Color="Transparent" />
<SolidColorBrush x:Key="ProgressBarForegroundThemeBrush" Color="#FF5B2EC5" />
<SolidColorBrush x:Key="ProgressBarIndeterminateForegroundThemeBrush" Color="#FF8A57FF" />
<!-- BaseResources for TextBox.xaml -->
<StaticResource x:Key="TextControlForeground" ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="TextControlForegroundPointerOver" ResourceKey="SystemControlForegroundBaseHighBrush" />

9
src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml

@ -336,6 +336,15 @@
<StaticResource x:Key="MenuFlyoutSubItemRevealBorderBrushDisabled" ResourceKey="SystemControlTransparentBrush" />-->
<!--<Thickness x:Key="LanguageSwitcherMenuFlyoutItemPlaceholderThemeThickness">44,0,0,0</Thickness>-->
<!-- Resources for ProgressBar.xaml -->
<x:Double x:Key="ProgressBarIndicatorPauseOpacity">0.6</x:Double>
<x:Double x:Key="ProgressBarThemeMinHeight">4</x:Double>
<Thickness x:Key="ProgressBarBorderThemeThickness">0</Thickness>
<SolidColorBrush x:Key="ProgressBarBackgroundThemeBrush" Color="#59FFFFFF" />
<SolidColorBrush x:Key="ProgressBarBorderThemeBrush" Color="Transparent" />
<SolidColorBrush x:Key="ProgressBarForegroundThemeBrush" Color="#FF5B2EC5" />
<SolidColorBrush x:Key="ProgressBarIndeterminateForegroundThemeBrush" Color="#FF8A57FF" />
<!-- Resources for TextBox.xaml -->
<SolidColorBrush x:Key="TextBoxForegroundHeaderThemeBrush" Color="#FFFFFFFF" />
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush" Color="#AB000000" />

8
src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesLight.xaml

@ -248,6 +248,14 @@
<SolidColorBrush x:Key="ListBoxItemSelectedDisabledForegroundThemeBrush" Color="#99FFFFFF" />
<SolidColorBrush x:Key="ListBoxItemSelectedForegroundThemeBrush" Color="White" />
<SolidColorBrush x:Key="ListBoxItemSelectedPointerOverBackgroundThemeBrush" Color="#FF5F37BE" />
<!-- Resources for ProgressBar.xaml -->
<x:Double x:Key="ProgressBarIndicatorPauseOpacity">0.6</x:Double>
<x:Double x:Key="ProgressBarThemeMinHeight">4</x:Double>
<Thickness x:Key="ProgressBarBorderThemeThickness">0</Thickness>
<SolidColorBrush x:Key="ProgressBarBackgroundThemeBrush" Color="#30000000" />
<SolidColorBrush x:Key="ProgressBarBorderThemeBrush" Color="Transparent" />
<SolidColorBrush x:Key="ProgressBarForegroundThemeBrush" Color="#FF4617B4" />
<SolidColorBrush x:Key="ProgressBarIndeterminateForegroundThemeBrush" Color="#FF4617B4" />
<!-- Resources for MenuFlyout.xaml (Menu, ContextMenu, etc) -->
<x:Double x:Key="MenuFlyoutSeparatorThemeHeight">1</x:Double>

44
src/Avalonia.Themes.Fluent/FocusAdorner.xaml

@ -1,10 +1,34 @@
<Style xmlns="https://github.com/avaloniaui" Selector=":is(Control)">
<Setter Property="FocusAdorner">
<FocusAdornerTemplate>
<Rectangle Stroke="Black"
StrokeThickness="1"
StrokeDashArray="1,2"
Margin="1"/>
</FocusAdornerTemplate>
</Setter>
</Style>
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Styles.Resources>
<Thickness x:Key="SystemControlFocusVisualMargin">0</Thickness>
<Thickness x:Key="SystemControlFocusVisualPrimaryThickness">2</Thickness>
<Thickness x:Key="SystemControlFocusVisualSecondaryThickness">1</Thickness>
</Styles.Resources>
<!-- HighVisibility FocusAdorner -->
<Style Selector=":is(Control)">
<Setter Property="FocusAdorner">
<FocusAdornerTemplate>
<Border BorderThickness="{StaticResource SystemControlFocusVisualPrimaryThickness}"
BorderBrush="{DynamicResource SystemControlFocusVisualPrimaryBrush}"
Margin="{StaticResource SystemControlFocusVisualMargin}">
<Border BorderThickness="{StaticResource SystemControlFocusVisualSecondaryThickness}"
BorderBrush="{DynamicResource SystemControlFocusVisualSecondaryBrush}" />
</Border>
</FocusAdornerTemplate>
</Setter>
</Style>
<!-- DottedLine FocusAdorner -->
<Style Selector="Window.DottedLineFocusAdorner :is(Control)">
<Setter Property="FocusAdorner">
<FocusAdornerTemplate>
<Rectangle Stroke="{StaticResource SystemControlFocusVisualPrimaryBrush}"
StrokeThickness="1"
StrokeDashArray="1,2"
Margin="1" />
</FocusAdornerTemplate>
</Setter>
</Style>
</Styles>

191
src/Avalonia.Themes.Fluent/ProgressBar.xaml

@ -1,81 +1,176 @@
<Styles xmlns="https://github.com/avaloniaui">
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Design.PreviewWith>
<Border Padding="20">
<StackPanel>
<ProgressBar VerticalAlignment="Center" IsIndeterminate="True" />
<ProgressBar HorizontalAlignment="Left" IsIndeterminate="True" Orientation="Vertical" />
</StackPanel>
</Border>
</Design.PreviewWith>
<Style Selector="ProgressBar">
<Setter Property="Background" Value="{DynamicResource ThemeAccentBrush4}"/>
<Setter Property="Foreground" Value="{DynamicResource ThemeAccentBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource SystemControlHighlightAccentBrush}" />
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundBaseLowBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource ProgressBarBorderThemeThickness}" />
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlHighlightTransparentBrush}" />
<Setter Property="Maximum" Value="100" />
<Setter Property="MinHeight" Value="{DynamicResource ProgressBarThemeMinHeight}" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Template">
<ControlTemplate>
<Grid>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Border Name="PART_Indicator" Background="{TemplateBinding Foreground}"/>
</Border>
<LayoutTransformControl
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsVisible="{Binding ShowProgressText, RelativeSource={RelativeSource TemplatedParent}}"
Name="PART_LayoutTransformControl">
<TextBlock
Foreground="{DynamicResource ThemeForegroundBrush}"
Text="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, StringFormat={}{0:0}%}" />
</LayoutTransformControl>
</Grid>
<Border x:Name="ProgressBarRoot" ClipToBounds="True" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{DynamicResource ControlCornerRadius}">
<Panel>
<Panel x:Name="DeterminateRoot">
<Border CornerRadius="{DynamicResource ControlCornerRadius}" x:Name="PART_Indicator" Margin="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}" />
</Panel>
<Panel x:Name="IndeterminateRoot">
<Border x:Name="IndeterminateProgressBarIndicator" CornerRadius="{DynamicResource ControlCornerRadius}" Margin="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}" />
<Border x:Name="IndeterminateProgressBarIndicator2" CornerRadius="{DynamicResource ControlCornerRadius}" Margin="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}" />
</Panel>
</Panel>
</Border>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="ProgressBar:horizontal /template/ Border#PART_Indicator">
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Stretch" />
</Style>
<Style Selector="ProgressBar:vertical /template/ Border#PART_Indicator">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Bottom" />
</Style>
<Style Selector="ProgressBar:horizontal">
<Setter Property="MinWidth" Value="200"/>
<Setter Property="MinHeight" Value="16"/>
<Setter Property="MinWidth" Value="200" />
<Setter Property="MinHeight" Value="4" />
</Style>
<Style Selector="ProgressBar:vertical">
<Setter Property="MinWidth" Value="16"/>
<Setter Property="MinHeight" Value="200"/>
<Setter Property="MinWidth" Value="4" />
<Setter Property="MinHeight" Value="200" />
</Style>
<Style Selector="ProgressBar:vertical /template/ LayoutTransformControl#PART_LayoutTransformControl">
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="90"/>
<RotateTransform Angle="90" />
</Setter.Value>
</Setter>
</Style>
<Style Selector="ProgressBar:horizontal:indeterminate /template/ Border#PART_Indicator">
<!-- FadeInAnimation mockup-->
<Style Selector="ProgressBar /template/ Panel#DeterminateRoot">
<Setter Property="Transitions">
<Transitions>
<DoubleTransition Property="Opacity" Duration="0:0:0.197" />
</Transitions>
</Setter>
</Style>
<Style Selector="ProgressBar /template/ Panel#IndeterminateRoot">
<Setter Property="Transitions">
<Transitions>
<DoubleTransition Property="Opacity" Duration="0:0:0.197" />
</Transitions>
</Setter>
</Style>
<Style Selector="ProgressBar /template/ Panel#DeterminateRoot">
<Setter Property="Opacity" Value="1" />
</Style>
<Style Selector="ProgressBar /template/ Panel#IndeterminateRoot">
<Setter Property="Opacity" Value="0" />
</Style>
<Style Selector="ProgressBar:indeterminate /template/ Panel#DeterminateRoot">
<Setter Property="Opacity" Value="0" />
</Style>
<Style Selector="ProgressBar:indeterminate /template/ Panel#IndeterminateRoot">
<Setter Property="Opacity" Value="1" />
</Style>
<Style Selector="ProgressBar:horizontal:indeterminate /template/ Border#IndeterminateProgressBarIndicator">
<Style.Animations>
<Animation Duration="0:0:2" IterationCount="Infinite">
<KeyFrame KeyTime="0:0:0" KeySpline="0.4,0,0.6,1">
<Setter Property="TranslateTransform.X" Value="{Binding $parent[ProgressBar].TemplateProperties.ContainerAnimationStartPosition}" />
</KeyFrame>
<KeyFrame KeyTime="0:0:1.5" KeySpline="0.4,0,0.6,1">
<Setter Property="TranslateTransform.X" Value="{Binding $parent[ProgressBar].TemplateProperties.ContainerAnimationEndPosition}" />
</KeyFrame>
<KeyFrame KeyTime="0:0:2" KeySpline="0.4,0,0.6,1">
<Setter Property="TranslateTransform.X" Value="{Binding $parent[ProgressBar].TemplateProperties.ContainerAnimationEndPosition}" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
<Style Selector="ProgressBar:horizontal:indeterminate /template/ Border#IndeterminateProgressBarIndicator2">
<Style.Animations>
<Animation Duration="0:0:2" IterationCount="Infinite">
<KeyFrame KeyTime="0:0:0" KeySpline="0.4,0,0.6,1">
<Setter Property="TranslateTransform.X" Value="{Binding $parent[ProgressBar].TemplateProperties.Container2AnimationStartPosition}" />
</KeyFrame>
<KeyFrame KeyTime="0:0:0.75" KeySpline="0.4,0,0.6,1">
<Setter Property="TranslateTransform.X" Value="{Binding $parent[ProgressBar].TemplateProperties.Container2AnimationStartPosition}" />
</KeyFrame>
<KeyFrame KeyTime="0:0:2" KeySpline="0.4,0,0.6,1">
<Setter Property="TranslateTransform.X" Value="{Binding $parent[ProgressBar].TemplateProperties.Container2AnimationEndPosition}" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
<Style Selector="ProgressBar:vertical:indeterminate /template/ Border#IndeterminateProgressBarIndicator">
<Style.Animations>
<Animation Duration="0:0:3"
IterationCount="Infinite"
Easing="LinearEasing">
<KeyFrame Cue="0%">
<Setter Property="TranslateTransform.X"
Value="{Binding IndeterminateStartingOffset, RelativeSource={RelativeSource TemplatedParent}}" />
<Animation Duration="0:0:2" IterationCount="Infinite">
<KeyFrame KeyTime="0:0:0" KeySpline="0.4,0,0.6,1">
<Setter Property="TranslateTransform.Y" Value="{Binding $parent[ProgressBar].TemplateProperties.ContainerAnimationStartPosition}" />
</KeyFrame>
<KeyFrame KeyTime="0:0:1.5" KeySpline="0.4,0,0.6,1">
<Setter Property="TranslateTransform.Y" Value="{Binding $parent[ProgressBar].TemplateProperties.ContainerAnimationEndPosition}" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="TranslateTransform.X"
Value="{Binding IndeterminateEndingOffset, RelativeSource={RelativeSource TemplatedParent}}" />
<KeyFrame KeyTime="0:0:2" KeySpline="0.4,0,0.6,1">
<Setter Property="TranslateTransform.Y" Value="{Binding $parent[ProgressBar].TemplateProperties.ContainerAnimationEndPosition}" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
<Style Selector="ProgressBar:vertical:indeterminate /template/ Border#PART_Indicator">
<Style Selector="ProgressBar:vertical:indeterminate /template/ Border#IndeterminateProgressBarIndicator2">
<Style.Animations>
<Animation Duration="0:0:3"
IterationCount="Infinite"
Easing="LinearEasing">
<KeyFrame Cue="0%">
<Setter Property="TranslateTransform.Y"
Value="{Binding IndeterminateStartingOffset, RelativeSource={RelativeSource TemplatedParent}}" />
<Animation Duration="0:0:2" IterationCount="Infinite">
<KeyFrame KeyTime="0:0:0" KeySpline="0.4,0,0.6,1">
<Setter Property="TranslateTransform.Y" Value="{Binding $parent[ProgressBar].TemplateProperties.Container2AnimationStartPosition}" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="TranslateTransform.Y"
Value="{Binding IndeterminateEndingOffset, RelativeSource={RelativeSource TemplatedParent}}" />
<KeyFrame KeyTime="0:0:0.75" KeySpline="0.4,0,0.6,1">
<Setter Property="TranslateTransform.Y" Value="{Binding $parent[ProgressBar].TemplateProperties.Container2AnimationStartPosition}" />
</KeyFrame>
<KeyFrame KeyTime="0:0:2" KeySpline="0.4,0,0.6,1">
<Setter Property="TranslateTransform.Y" Value="{Binding $parent[ProgressBar].TemplateProperties.Container2AnimationEndPosition}" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
<Style Selector="ProgressBar:horizontal /template/ Border#IndeterminateProgressBarIndicator">
<Setter Property="Width" Value="{Binding $parent[ProgressBar].TemplateProperties.ContainerWidth}" />
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="{Binding $parent[ProgressBar].TemplateProperties.ContainerAnimationStartPosition}" />
</Setter.Value>
</Setter>
</Style>
<Style Selector="ProgressBar:horizontal /template/ Border#IndeterminateProgressBarIndicator2">
<Setter Property="Width" Value="{Binding $parent[ProgressBar].TemplateProperties.Container2Width}" />
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="{Binding $parent[ProgressBar].TemplateProperties.Container2AnimationStartPosition}" />
</Setter.Value>
</Setter>
</Style>
<Style Selector="ProgressBar:vertical /template/ Border#IndeterminateProgressBarIndicator">
<Setter Property="Height" Value="{Binding $parent[ProgressBar].TemplateProperties.ContainerWidth}" />
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform Y="{Binding $parent[ProgressBar].TemplateProperties.ContainerAnimationStartPosition}" />
</Setter.Value>
</Setter>
</Style>
<Style Selector="ProgressBar:vertical /template/ Border#IndeterminateProgressBarIndicator2">
<Setter Property="Height" Value="{Binding $parent[ProgressBar].TemplateProperties.Container2Width}" />
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform Y="{Binding $parent[ProgressBar].TemplateProperties.Container2AnimationStartPosition}" />
</Setter.Value>
</Setter>
</Style>
</Styles>

16
src/Avalonia.Themes.Fluent/ToolTip.xaml

@ -1,11 +1,14 @@
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard">
<Design.PreviewWith>
<Grid RowDefinitions="Auto,Auto"
ColumnDefinitions="Auto,Auto"
HorizontalAlignment="Center">
<Border Grid.Column="0"
Grid.Row="1"
Background="{DynamicResource ThemeAccentBrush}"
Background="{DynamicResource SystemControlBackgroundAccentBrush}"
Margin="5"
Padding="50"
ToolTip.Tip="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.">
@ -19,7 +22,7 @@
<Border Name="Border"
Grid.Column="1"
Grid.Row="1"
Background="{DynamicResource ThemeAccentBrush}"
Background="{DynamicResource SystemControlBackgroundAccentBrush}"
Margin="5"
Padding="50"
ToolTip.Placement="Bottom">
@ -34,6 +37,10 @@
</Grid>
</Design.PreviewWith>
<Styles.Resources>
<sys:Double x:Key="ToolTipContentMaxWidth">320</sys:Double>
</Styles.Resources>
<Style Selector="ToolTip">
<Setter Property="Foreground" Value="{DynamicResource ToolTipForeground}" />
<Setter Property="Background" Value="{DynamicResource ToolTipBackground}" />
@ -42,6 +49,7 @@
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{DynamicResource ToolTipContentThemeFontSize}" />
<Setter Property="Padding" Value="{DynamicResource ToolTipBorderThemePadding}" />
<Setter Property="MaxWidth" Value="{DynamicResource ToolTipContentMaxWidth}" />
<Setter Property="Transitions">
<Transitions>
<DoubleTransition Property="Opacity" Duration="0:0:0.15" />
@ -56,7 +64,7 @@
Padding="{TemplateBinding Padding}"
CornerRadius="{DynamicResource OverlayCornerRadius}">
<ContentPresenter Name="PART_ContentPresenter"
MaxWidth="320"
MaxWidth="{TemplateBinding MaxWidth}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</Border>

Loading…
Cancel
Save