Browse Source

Merge branch 'master' into fixes/moveFlowDirection

pull/9622/head
daniel mayost 4 years ago
parent
commit
c25c80e8d0
  1. 13
      .editorconfig
  2. 15
      packages/Avalonia/AvaloniaBuildTasks.targets
  3. 9
      samples/ControlCatalog.NetCore/Program.cs
  4. 11
      samples/ControlCatalog.NetCore/Properties/launchSettings.json
  5. 10
      samples/ControlCatalog/ControlCatalog.csproj
  6. 29
      samples/ControlCatalog/Converter/DegToRadConverter.cs
  7. 3
      samples/ControlCatalog/MainView.xaml
  8. 25
      samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml.cs
  9. 2
      samples/ControlCatalog/Pages/CompositionPage.axaml.cs
  10. 107
      samples/ControlCatalog/Pages/CustomDrawing.xaml
  11. 67
      samples/ControlCatalog/Pages/CustomDrawing.xaml.cs
  12. 215
      samples/ControlCatalog/Pages/CustomDrawingExampleControl.cs
  13. 2
      samples/ControlCatalog/Pages/ImagePage.xaml.cs
  14. 2
      samples/ControlCatalog/Pages/OpenGlPage.xaml.cs
  15. 3
      samples/ControlCatalog/Pages/ScreenPage.cs
  16. 2
      samples/ControlCatalog/Pages/TabControlPage.xaml.cs
  17. 3
      samples/Directory.Build.props
  18. 2
      src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs
  19. 2
      src/Android/Avalonia.Android/Platform/Storage/AndroidStorageItem.cs
  20. 2
      src/Avalonia.Base/Animation/Animators/GradientBrushAnimator.cs
  21. 2
      src/Avalonia.Base/Animation/KeySpline.cs
  22. 4
      src/Avalonia.Base/Controls/Classes.cs
  23. 2
      src/Avalonia.Base/CornerRadius.cs
  24. 2
      src/Avalonia.Base/Data/Core/ExpressionNode.cs
  25. 4
      src/Avalonia.Base/Data/Core/Parsers/ExpressionVisitorNodeBuilder.cs
  26. 2
      src/Avalonia.Base/Data/Core/Plugins/DataAnnotationsValidationPlugin.cs
  27. 2
      src/Avalonia.Base/Data/Core/Plugins/IndeiValidationPlugin.cs
  28. 2
      src/Avalonia.Base/Data/Core/Plugins/TaskStreamPlugin.cs
  29. 18
      src/Avalonia.Base/Input/AccessKeyHandler.cs
  30. 4
      src/Avalonia.Base/Input/DragDropDevice.cs
  31. 5
      src/Avalonia.Base/Input/KeyGesture.cs
  32. 2
      src/Avalonia.Base/Input/KeyboardDevice.cs
  33. 9
      src/Avalonia.Base/Input/MouseDevice.cs
  34. 2
      src/Avalonia.Base/Input/PenDevice.cs
  35. 4
      src/Avalonia.Base/Input/Pointer.cs
  36. 2
      src/Avalonia.Base/Input/TouchDevice.cs
  37. 2
      src/Avalonia.Base/Layout/AttachedLayout.cs
  38. 4
      src/Avalonia.Base/Layout/StackLayout.cs
  39. 2
      src/Avalonia.Base/Layout/UniformGridLayout.cs
  40. 5
      src/Avalonia.Base/Media/ArcSegment.cs
  41. 6
      src/Avalonia.Base/Media/BezierSegment .cs
  42. 8
      src/Avalonia.Base/Media/BoxShadow.cs
  43. 6
      src/Avalonia.Base/Media/LineSegment.cs
  44. 2
      src/Avalonia.Base/Media/PathFigure.cs
  45. 2
      src/Avalonia.Base/Media/PathGeometry.cs
  46. 12
      src/Avalonia.Base/Media/PathMarkupParser.cs
  47. 6
      src/Avalonia.Base/Media/QuadraticBezierSegment .cs
  48. 4
      src/Avalonia.Base/Platform/AssetLoader.cs
  49. 2
      src/Avalonia.Base/RelativePoint.cs
  50. 19
      src/Avalonia.Base/Rendering/Composition/Animations/KeyFrameAnimationInstance.cs
  51. 2
      src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
  52. 4
      src/Avalonia.Base/Rendering/Composition/CompositionTarget.cs
  53. 2
      src/Avalonia.Base/Rendering/Composition/Drawing/CompositionDrawingContext.cs
  54. 2
      src/Avalonia.Base/Rendering/Composition/Server/FpsCounter.cs
  55. 2
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs
  56. 4
      src/Avalonia.Base/Rendering/DeferredRenderer.cs
  57. 2
      src/Avalonia.Base/Rendering/RendererBase.cs
  58. 2
      src/Avalonia.Base/Rendering/SceneGraph/SceneBuilder.cs
  59. 2
      src/Avalonia.Base/Styling/Activators/IStyleActivator.cs
  60. 2
      src/Avalonia.Base/Thickness.cs
  61. 1
      src/Avalonia.Base/Visual.cs
  62. 2
      src/Avalonia.Base/VisualTree/TransformedBounds.cs
  63. 2
      src/Avalonia.Build.Tasks/Extensions.cs
  64. 2
      src/Avalonia.Build.Tasks/GenerateAvaloniaResourcesTask.cs
  65. 2
      src/Avalonia.Controls.ColorPicker/ColorSlider/ColorSlider.cs
  66. 2
      src/Avalonia.Controls.ColorPicker/ColorSpectrum/ColorSpectrum.cs
  67. 2
      src/Avalonia.Controls.DataGrid/DataGridTemplateColumn.cs
  68. 2
      src/Avalonia.Controls/Automation/Peers/ComboBoxAutomationPeer.cs
  69. 2
      src/Avalonia.Controls/Calendar/CalendarBlackoutDatesCollection.cs
  70. 3
      src/Avalonia.Controls/Calendar/SelectedDatesCollection.cs
  71. 2
      src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs
  72. 8
      src/Avalonia.Controls/Grid.cs
  73. 2
      src/Avalonia.Controls/GridSplitter.cs
  74. 11
      src/Avalonia.Controls/MenuItemAccessKeyHandler.cs
  75. 4
      src/Avalonia.Controls/Platform/InProcessDragSource.cs
  76. 6
      src/Avalonia.Controls/Primitives/Popup.cs
  77. 2
      src/Avalonia.Controls/Repeater/RecyclingElementFactory.cs
  78. 2
      src/Avalonia.Controls/Selection/IndexRange.cs
  79. 4
      src/Avalonia.Controls/Selection/SelectionNodeBase.cs
  80. 20
      src/Avalonia.Controls/Slider.cs
  81. 7
      src/Avalonia.Controls/SplitView.cs
  82. 2
      src/Avalonia.Controls/TextBox.cs
  83. 2
      src/Avalonia.Controls/TopLevel.cs
  84. 1
      src/Avalonia.Controls/UserControl.cs
  85. 2
      src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs
  86. 2
      src/Avalonia.DesignerSupport/Remote/HtmlTransport/SimpleWebSocketHttpServer.cs
  87. 2
      src/Avalonia.Diagnostics/Diagnostics/Screenshots/FilePickerHandler.cs
  88. 14
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs
  89. 8
      src/Avalonia.Dialogs/ManagedStorageProvider.cs
  90. 2
      src/Avalonia.FreeDesktop/DBusTrayIconImpl.cs
  91. 8
      src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs
  92. 2
      src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
  93. 3
      src/Avalonia.Native/IAvnMenu.cs
  94. 4
      src/Avalonia.OpenGL/Controls/OpenGlControlBase.cs
  95. 2
      src/Avalonia.Remote.Protocol/MetsysBson.cs
  96. 16
      src/Avalonia.Themes.Fluent/Controls/CalendarButton.xaml
  97. 39
      src/Avalonia.Themes.Fluent/Controls/Slider.xaml
  98. 18
      src/Avalonia.Themes.Simple/Controls/CalendarButton.xaml
  99. 2
      src/Avalonia.X11/X11IconLoader.cs
  100. 9
      src/Avalonia.X11/X11Platform.cs

13
.editorconfig

@ -137,14 +137,27 @@ space_within_single_line_array_initializer_braces = true
#Net Analyzer
dotnet_analyzer_diagnostic.category-Performance.severity = none #error - Uncomment when all violations are fixed.
# CA1304: Specify CultureInfo
dotnet_diagnostic.CA1304.severity = warning
# CA1802: Use literals where appropriate
dotnet_diagnostic.CA1802.severity = warning
# CA1820: Test for empty strings using string length
dotnet_diagnostic.CA1820.severity = warning
# CA1821: Remove empty finalizers
dotnet_diagnostic.CA1821.severity = warning
# CA1822: Mark members as static
dotnet_diagnostic.CA1822.severity = suggestion
dotnet_code_quality.CA1822.api_surface = private, internal
# CA1825: Avoid zero-length array allocations
dotnet_diagnostic.CA1825.severity = warning
# CA1826: Use property instead of Linq Enumerable method
dotnet_diagnostic.CA1826.severity = suggestion
# CA1827: Do not use Count/LongCount when Any can be used
dotnet_diagnostic.CA1827.severity = warning
# CA1828: Do not use CountAsync/LongCountAsync when AnyAsync can be used
dotnet_diagnostic.CA1828.severity = warning
# CA1829: Use Length/Count property instead of Enumerable.Count method
dotnet_diagnostic.CA1829.severity = warning
#CA1847: Use string.Contains(char) instead of string.Contains(string) with single characters
dotnet_diagnostic.CA1847.severity = warning

15
packages/Avalonia/AvaloniaBuildTasks.targets

@ -30,7 +30,9 @@
/>
<Target Name="AddAvaloniaResources" BeforeTargets="ResolveReferences">
<Target Name="AddAvaloniaResources"
BeforeTargets="ResolveReferences"
Condition="('@(AvaloniaResource->Count())' &gt; 0) or ('@(AvaloniaXaml->Count())' &gt; 0)">
<PropertyGroup>
<AvaloniaResourcesTemporaryFilePath Condition="'$(AvaloniaResourcesTemporaryFilePath)' == ''">$(IntermediateOutputPath)/Avalonia/resources</AvaloniaResourcesTemporaryFilePath>
</PropertyGroup>
@ -62,7 +64,9 @@
BeforeTargets="CoreCompile;CoreResGen"
Inputs="@(AvaloniaResource);@(AvaloniaXaml);@(CustomAdditionalGenerateAvaloniaResourcesInputs);$(MSBuildAllProjects)"
Outputs="$(AvaloniaResourcesTemporaryFilePath)"
DependsOnTargets="$(BuildAvaloniaResourcesDependsOn)">
DependsOnTargets="$(BuildAvaloniaResourcesDependsOn)"
Condition="('@(AvaloniaResource->Count())' &gt; 0) or ('@(AvaloniaXaml->Count())' &gt; 0)"
>
<ItemGroup>
<AvaloniaResource Include="@(AvaloniaXaml)"/>
</ItemGroup>
@ -81,7 +85,12 @@
<Target
Name="CompileAvaloniaXaml"
AfterTargets="AfterCompile"
Condition="Exists('@(IntermediateAssembly)') And $(DesignTimeBuild) != true And $(EnableAvaloniaXamlCompilation) != false"
Condition="
(('@(AvaloniaResource->Count())' &gt; 0)
or ('@(AvaloniaXaml->Count())' &gt; 0))
and Exists('@(IntermediateAssembly)')
And $(DesignTimeBuild) != true
And $(EnableAvaloniaXamlCompilation) != false"
>
<PropertyGroup>
<AvaloniaXamlReferencesTemporaryFilePath Condition="'$(AvaloniaXamlReferencesTemporaryFilePath)' == ''">$(IntermediateOutputPath)/Avalonia/references</AvaloniaXamlReferencesTemporaryFilePath>

9
samples/ControlCatalog.NetCore/Program.cs

@ -99,6 +99,15 @@ namespace ControlCatalog.NetCore
SilenceConsole();
return builder.StartLinuxDrm(args, scaling: GetScaling());
}
else if (args.Contains("--dxgi"))
{
builder.With(new Win32PlatformOptions()
{
UseLowLatencyDxgiSwapChain = true,
UseWindowsUIComposition = false
});
return builder.StartWithClassicDesktopLifetime(args);
}
else
return builder.StartWithClassicDesktopLifetime(args);
}

11
samples/ControlCatalog.NetCore/Properties/launchSettings.json

@ -0,0 +1,11 @@
{
"profiles": {
"ControlCatalog.NetCore": {
"commandName": "Project"
},
"Dxgi": {
"commandName": "Project",
"commandLineArgs": "--dxgi"
}
}
}

10
samples/ControlCatalog/ControlCatalog.csproj

@ -33,4 +33,14 @@
</ItemGroup>
<Import Project="..\..\build\BuildTargets.targets" />
<ItemGroup>
<None Remove="Pages\CustomDrawing.xaml" />
</ItemGroup>
<ItemGroup>
<AvaloniaResource Update="Pages\CustomDrawing.xaml">
<Generator></Generator>
</AvaloniaResource>
</ItemGroup>
</Project>

29
samples/ControlCatalog/Converter/DegToRadConverter.cs

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using Avalonia.Data.Converters;
namespace ControlCatalog.Converter
{
public class DegToRadConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is double rad)
{
return rad * 180.0d / Math.PI;
}
return 0.0d;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is double deg)
{
return deg / 180.0d * Math.PI;
}
return 0.0d;
}
}
}

3
samples/ControlCatalog/MainView.xaml

@ -66,6 +66,9 @@
<TabItem Header="Cursor" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<pages:CursorPage />
</TabItem>
<TabItem Header="Custom Drawing" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<pages:CustomDrawing/>
</TabItem>
<TabItem Header="DataGrid"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled">

25
samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml.cs

@ -14,7 +14,26 @@ namespace ControlCatalog.Pages
{
public class AutoCompleteBoxPage : UserControl
{
private StateData[] BuildAllStates()
public class StateData
{
public string Name { get; private set; }
public string Abbreviation { get; private set; }
public string Capital { get; private set; }
public StateData(string name, string abbreviatoin, string capital)
{
Name = name;
Abbreviation = abbreviatoin;
Capital = capital;
}
public override string ToString()
{
return Name;
}
}
private static StateData[] BuildAllStates()
{
return new StateData[]
{
@ -72,7 +91,7 @@ namespace ControlCatalog.Pages
}
public StateData[] States { get; private set; }
private LinkedList<string>[] BuildAllSentences()
private static LinkedList<string>[] BuildAllSentences()
{
return new string[]
{
@ -124,7 +143,7 @@ namespace ControlCatalog.Pages
.OfType<AutoCompleteBox>();
}
private bool StringContains(string str, string? query)
private static bool StringContains(string str, string? query)
{
if (query == null) return false;
return str.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0;

2
samples/ControlCatalog/Pages/CompositionPage.axaml.cs

@ -25,7 +25,7 @@ public partial class CompositionPage : UserControl
this.Get<ItemsControl>("Items").Items = CreateColorItems();
}
private List<CompositionPageColorItem> CreateColorItems()
private static List<CompositionPageColorItem> CreateColorItems()
{
var list = new List<CompositionPageColorItem>();

107
samples/ControlCatalog/Pages/CustomDrawing.xaml

@ -0,0 +1,107 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="using:ControlCatalog.Pages"
xmlns:converters="using:ControlCatalog.Converter"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ControlCatalog.Pages.CustomDrawing">
<UserControl.Resources>
<converters:DegToRadConverter x:Key="DegToRadConverter"/>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical">
<TextBlock Text="Translation" HorizontalAlignment="Center"/>
<Grid ColumnDefinitions="*,*"
RowDefinitions="Auto,Auto"
>
<TextBlock Text="Horizontal"/>
<TextBlock Text="Vertical" Grid.Column="1"/>
<TextBox IsEnabled="False"
Text="{Binding ElementName=CustomDrawingControl,
Path=ViewportCenterX,
Mode=OneWay,
StringFormat=\{0:g4\}}"
Grid.Row="1"
/>
<TextBox IsEnabled="False"
Text="{Binding ElementName=CustomDrawingControl,
Path=ViewportCenterY,
Mode=OneWay,
StringFormat=\{0:g4\}}"
Grid.Row="1" Grid.Column="1"
/>
</Grid>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Column="1"
>
<TextBlock Text="Rotation" HorizontalAlignment="Center"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center"
>
<Button Content="➖" Width="40" Height="40"
VerticalContentAlignment="Center"
VerticalAlignment="Center"
Click="RotateMinus"
/>
<TextBox IsEnabled="False"
Text="{Binding ElementName=CustomDrawingControl,
Path=Rotation,
Converter={StaticResource DegToRadConverter},
Mode=OneWay,
StringFormat=\{0:g4\}}"
Grid.Row="1" Grid.Column="1"
/>
<Button Content="➕" Width="40" Height="40"
VerticalContentAlignment="Center"
VerticalAlignment="Center"
Click="RotatePlus"
/>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Column="2"
>
<TextBlock Text="Scale" HorizontalAlignment="Center"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center"
>
<Button Content="➖" Width="40" Height="40"
VerticalContentAlignment="Center"
VerticalAlignment="Center"
Click="ZoomOut"
/>
<TextBox IsEnabled="False"
Text="{Binding ElementName=CustomDrawingControl,
Path=Scale,
Mode=OneWay,
StringFormat=\{0:g4\}}"
Grid.Row="1" Grid.Column="1"
/>
<Button Content="➕" Width="40" Height="40"
VerticalContentAlignment="Center"
VerticalAlignment="Center"
Click="ZoomIn"
/>
</StackPanel>
</StackPanel>
<Grid Grid.Row="1" Grid.ColumnSpan="3" ClipToBounds="True">
<local:CustomDrawingExampleControl
x:Name="CustomDrawingControl"
/>
</Grid>
</Grid>
</UserControl>

67
samples/ControlCatalog/Pages/CustomDrawing.xaml.cs

@ -0,0 +1,67 @@
using System;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
namespace ControlCatalog.Pages
{
public partial class CustomDrawing : UserControl
{
public CustomDrawing()
{
InitializeComponent();
}
private CustomDrawingExampleControl? _customControl;
public CustomDrawingExampleControl CustomDrawingControl
{
get
{
if (_customControl is not null)
return _customControl;
throw new System.Exception("Control did not get initialized");
}
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
var cntrl = this.FindControl<CustomDrawingExampleControl>("CustomDrawingControl");
if (cntrl != null)
{
_customControl = cntrl;
}
else
{
// be sad about it
}
}
private void RotateMinus (object? sender, RoutedEventArgs e)
{
if (_customControl is null) return;
_customControl.Rotation -= Math.PI / 20.0d;
}
private void RotatePlus(object? sender, RoutedEventArgs e)
{
if (_customControl is null)
return;
_customControl.Rotation += Math.PI / 20.0d;
}
private void ZoomIn(object? sender, RoutedEventArgs e)
{
if (_customControl is null)
return;
_customControl.Scale *= 1.2d;
}
private void ZoomOut(object? sender, RoutedEventArgs e)
{
if (_customControl is null)
return;
_customControl.Scale /= 1.2d;
}
}
}

215
samples/ControlCatalog/Pages/CustomDrawingExampleControl.cs

@ -0,0 +1,215 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
using Avalonia.Input;
using Avalonia.Threading;
using Avalonia.Controls.Shapes;
namespace ControlCatalog.Pages
{
public class CustomDrawingExampleControl : Control
{
private Point _cursorPoint;
public StyledProperty<double> ScaleProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(Scale), 1.0d);
public double Scale { get => GetValue(ScaleProperty); set => SetValue(ScaleProperty, value); }
public StyledProperty<double> RotationProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(Rotation));
/// <summary>
/// Rotation, measured in Radians!
/// </summary>
public double Rotation
{
get => GetValue(RotationProperty);
set
{
double valueToUse = value % (Math.PI * 2);
SetValue(RotationProperty, valueToUse);
}
}
public StyledProperty<double> ViewportCenterYProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(ViewportCenterY), 0.0d);
public double ViewportCenterY { get => GetValue(ViewportCenterYProperty); set => SetValue(ViewportCenterYProperty, value); }
public StyledProperty<double> ViewportCenterXProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(ViewportCenterX), 0.0d);
public double ViewportCenterX { get => GetValue(ViewportCenterXProperty); set => SetValue(ViewportCenterXProperty, value); }
private IPen _pen;
private System.Diagnostics.Stopwatch _timeKeeper = System.Diagnostics.Stopwatch.StartNew();
private bool _isPointerCaptured = false;
public CustomDrawingExampleControl()
{
_pen = new Pen(new SolidColorBrush(Colors.Black), lineCap: PenLineCap.Round);
var _arc = new ArcSegment()
{
IsLargeArc = false,
Point = new Point(0, 0),
RotationAngle = 0,
Size = new Size(25, 25),
SweepDirection = SweepDirection.Clockwise,
};
StreamGeometry sg = new StreamGeometry();
var cntx = sg.Open();
cntx.BeginFigure(new Point(-25.0d, -10.0d), false);
cntx.ArcTo(new Point(25.0d, -10.0d), new Size(10.0d, 10.0d), 0.0d, false, SweepDirection.Clockwise);
cntx.EndFigure(true);
_smileGeometry = sg.Clone();
}
private Geometry _smileGeometry;
protected override void OnPointerMoved(PointerEventArgs e)
{
base.OnPointerMoved(e);
Point previousPoint = _cursorPoint;
_cursorPoint = e.GetPosition(this);
if (_isPointerCaptured)
{
Point oldWorldPoint = UIPointToWorldPoint(previousPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation);
Point newWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation);
Vector diff = newWorldPoint - oldWorldPoint;
ViewportCenterX -= diff.X;
ViewportCenterY -= diff.Y;
}
}
protected override void OnPointerPressed(PointerPressedEventArgs e)
{
e.Handled = true;
e.Pointer.Capture(this);
_isPointerCaptured = true;
base.OnPointerPressed(e);
}
protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
{
base.OnPointerWheelChanged(e);
var oldScale = Scale;
Scale *= (1.0d + e.Delta.Y / 12.0d);
Point oldWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, oldScale, Rotation);
Point newWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation);
Vector diff = newWorldPoint - oldWorldPoint;
ViewportCenterX -= diff.X;
ViewportCenterY -= diff.Y;
}
protected override void OnPointerReleased(PointerReleasedEventArgs e)
{
e.Pointer.Capture(null);
_isPointerCaptured = false;
base.OnPointerReleased(e);
}
public override void Render(DrawingContext context)
{
var localBounds = new Rect(new Size(this.Bounds.Width, this.Bounds.Height));
var clip = context.PushClip(this.Bounds);
context.DrawRectangle(Brushes.White, _pen, localBounds, 1.0d);
var halfMax = Math.Max(this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d) * Math.Sqrt(2.0d);
var halfMin = Math.Min(this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d) / 1.3d;
var halfWidth = this.Bounds.Width / 2.0d;
var halfHeight = this.Bounds.Height / 2.0d;
// 0,0 refers to the top-left of the control now. It is not prime time to draw gui stuff because it'll be under the world
var translateModifier = context.PushPreTransform(Avalonia.Matrix.CreateTranslation(new Avalonia.Vector(halfWidth, halfHeight)));
// now 0,0 refers to the ViewportCenter(X,Y).
var rotationMatrix = Avalonia.Matrix.CreateRotation(Rotation);
var rotationModifier = context.PushPreTransform(rotationMatrix);
// everything is rotated but not scaled
var scaleModifier = context.PushPreTransform(Avalonia.Matrix.CreateScale(Scale, -Scale));
var mapPositionModifier = context.PushPreTransform(Matrix.CreateTranslation(new Vector(-ViewportCenterX, -ViewportCenterY)));
// now everything is rotated and scaled, and at the right position, now we're drawing strictly in world coordinates
context.DrawEllipse(Brushes.White, _pen, new Point(0.0d, 0.0d), 50.0d, 50.0d);
context.DrawLine(_pen, new Point(-25.0d, -5.0d), new Point(-25.0d, 15.0d));
context.DrawLine(_pen, new Point(25.0d, -5.0d), new Point(25.0d, 15.0d));
context.DrawGeometry(null, _pen, _smileGeometry);
Point cursorInWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation);
context.DrawEllipse(Brushes.Gray, _pen, cursorInWorldPoint, 20.0d, 20.0d);
for (int i = 0; i < 10; i++)
{
double orbitRadius = i * 100 + 200;
var orbitInput = ((_timeKeeper.Elapsed.TotalMilliseconds + 987654d) / orbitRadius) / 10.0d;
if (i % 3 == 0)
orbitInput *= -1;
Point orbitPosition = new Point(Math.Sin(orbitInput) * orbitRadius, Math.Cos(orbitInput) * orbitRadius);
context.DrawEllipse(Brushes.Gray, _pen, orbitPosition, 20.0d, 20.0d);
}
// end drawing the world
mapPositionModifier.Dispose();
scaleModifier.Dispose();
rotationModifier.Dispose();
translateModifier.Dispose();
// this is prime time to draw gui stuff
context.DrawLine(_pen, _cursorPoint + new Vector(-20, 0), _cursorPoint + new Vector(20, 0));
context.DrawLine(_pen, _cursorPoint + new Vector(0, -20), _cursorPoint + new Vector(0, 20));
clip.Dispose();
// oh and draw again when you can, no rush, right?
Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
}
private Point UIPointToWorldPoint(Point inPoint, double viewportCenterX, double viewportCenterY, double scale, double rotation)
{
Point workingPoint = new Point(inPoint.X, -inPoint.Y);
workingPoint += new Vector(-this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d);
workingPoint /= scale;
workingPoint = Matrix.CreateRotation(rotation).Transform(workingPoint);
workingPoint += new Vector(viewportCenterX, viewportCenterY);
return workingPoint;
}
private Point WorldPointToUIPoint(Point inPoint, double viewportCenterX, double viewportCenterY, double scale, double rotation)
{
Point workingPoint = new Point(inPoint.X, inPoint.Y);
workingPoint -= new Vector(viewportCenterX, viewportCenterY);
// undo rotation
workingPoint = Matrix.CreateRotation(-rotation).Transform(workingPoint);
workingPoint *= scale;
workingPoint -= new Vector(-this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d);
workingPoint = new Point(workingPoint.X, -workingPoint.Y);
return workingPoint;
}
}
}

2
samples/ControlCatalog/Pages/ImagePage.xaml.cs

@ -58,7 +58,7 @@ namespace ControlCatalog.Pages
}
}
private PixelRect GetCropRect(int index)
private static PixelRect GetCropRect(int index)
{
var bitmapWidth = 640;
var bitmapHeight = 426;

2
samples/ControlCatalog/Pages/OpenGlPage.xaml.cs

@ -247,7 +247,7 @@ namespace ControlCatalog.Pages
}
private void CheckError(GlInterface gl)
private static void CheckError(GlInterface gl)
{
int err;
while ((err = gl.GetError()) != GL_NO_ERROR)

3
samples/ControlCatalog/Pages/ScreenPage.cs

@ -66,6 +66,7 @@ namespace ControlCatalog.Pages
context.DrawText(formattedText, boundsRect.Position.WithY(boundsRect.Size.Height + 40));
formattedText = CreateFormattedText($"IsPrimary: {screen.IsPrimary}");
context.DrawText(formattedText, boundsRect.Position.WithY(boundsRect.Size.Height + 60));
formattedText =
@ -77,7 +78,7 @@ namespace ControlCatalog.Pages
context.DrawRectangle(p, new Rect(w.Position.X / 10f + Math.Abs(_leftMost), w.Position.Y / 10f, w.Bounds.Width / 10, w.Bounds.Height / 10));
}
private FormattedText CreateFormattedText(string textToFormat)
private static FormattedText CreateFormattedText(string textToFormat)
{
return new FormattedText(textToFormat, CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
Typeface.Default, 12, Brushes.Green);

2
samples/ControlCatalog/Pages/TabControlPage.xaml.cs

@ -49,7 +49,7 @@ namespace ControlCatalog.Pages
AvaloniaXamlLoader.Load(this);
}
private IBitmap LoadBitmap(string uri)
private static IBitmap LoadBitmap(string uri)
{
var assets = AvaloniaLocator.Current!.GetService<IAssetLoader>()!;
return new Bitmap(assets.Open(new Uri(uri)));

3
samples/Directory.Build.props

@ -4,4 +4,7 @@
<AvaloniaPreviewerNetCoreToolPath>$(MSBuildThisFileDirectory)..\src\tools\Avalonia.Designer.HostApp\bin\Debug\netcoreapp2.0\Avalonia.Designer.HostApp.dll</AvaloniaPreviewerNetCoreToolPath>
</PropertyGroup>
<Import Project="..\build\SharedVersion.props" />
<PropertyGroup>
<EnableNETAnalyzers>false</EnableNETAnalyzers>
</PropertyGroup>
</Project>

2
src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs

@ -30,7 +30,7 @@ namespace Avalonia.Android.Platform.Specific.Helpers
return DispatchKeyEventInternal(e, out callBase);
}
string UnicodeTextInput(KeyEvent keyEvent)
static string UnicodeTextInput(KeyEvent keyEvent)
{
return keyEvent.Action == KeyEventActions.Multiple
&& keyEvent.RepeatCount == 0

2
src/Android/Avalonia.Android/Platform/Storage/AndroidStorageItem.cs

@ -178,7 +178,7 @@ internal sealed class AndroidStorageFile : AndroidStorageItem, IStorageBookmarkF
return false;
}
private Stream? GetVirtualFileStream(Context context, AndroidUri uri, bool isOutput)
private static Stream? GetVirtualFileStream(Context context, AndroidUri uri, bool isOutput)
{
var mimeTypes = context.ContentResolver?.GetStreamTypes(uri, FilePickerFileTypes.All.MimeTypes![0]);
if (mimeTypes?.Length >= 1)

2
src/Avalonia.Base/Animation/Animators/GradientBrushAnimator.cs

@ -72,7 +72,7 @@ namespace Avalonia.Animation.Animators
return control.Bind((AvaloniaProperty<IBrush?>)Property, instance, BindingPriority.Animation);
}
private IReadOnlyList<ImmutableGradientStop> InterpolateStops(double progress, IReadOnlyList<IGradientStop> oldValue, IReadOnlyList<IGradientStop> newValue)
private static IReadOnlyList<ImmutableGradientStop> InterpolateStops(double progress, IReadOnlyList<IGradientStop> oldValue, IReadOnlyList<IGradientStop> newValue)
{
var resultCount = Math.Max(oldValue.Count, newValue.Count);
var stops = new ImmutableGradientStop[resultCount];

2
src/Avalonia.Base/Animation/KeySpline.cs

@ -196,7 +196,7 @@ namespace Avalonia.Animation
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private bool IsValidXValue(double value)
private static bool IsValidXValue(double value)
{
return value >= 0.0 && value <= 1.0;
}

4
src/Avalonia.Base/Controls/Classes.cs

@ -37,7 +37,7 @@ namespace Avalonia.Controls
/// <param name="items">The initial items.</param>
public Classes(params string[] items)
: base(items)
{
{
}
/// <summary>
@ -320,7 +320,7 @@ namespace Avalonia.Controls
listener.Changed();
}
private void ThrowIfPseudoclass(string name, string operation)
private static void ThrowIfPseudoclass(string name, string operation)
{
if (name.StartsWith(":"))
{

2
src/Avalonia.Base/CornerRadius.cs

@ -100,7 +100,7 @@ namespace Avalonia
public override string ToString()
{
return $"{TopLeft},{TopRight},{BottomRight},{BottomLeft}";
return FormattableString.Invariant($"{TopLeft},{TopRight},{BottomRight},{BottomLeft}");
}
public static CornerRadius Parse(string s)

2
src/Avalonia.Base/Data/Core/ExpressionNode.cs

@ -159,7 +159,7 @@ namespace Avalonia.Data.Core
_listening = false;
}
private BindingNotification TargetNullNotification()
private static BindingNotification TargetNullNotification()
{
return new BindingNotification(
new MarkupBindingChainException("Null value"),

4
src/Avalonia.Base/Data/Core/Parsers/ExpressionVisitorNodeBuilder.cs

@ -81,7 +81,7 @@ namespace Avalonia.Data.Core.Parsers
return node;
}
private T GetArgumentExpressionValue<T>(Expression expr)
private static T GetArgumentExpressionValue<T>(Expression expr)
{
try
{
@ -193,7 +193,7 @@ namespace Avalonia.Data.Core.Parsers
throw new ExpressionParseException(0, $"Invalid method call in binding expression: '{node.Method.DeclaringType!.AssemblyQualifiedName}.{node.Method.Name}'.");
}
private PropertyInfo? TryGetPropertyFromMethod(MethodInfo method)
private static PropertyInfo? TryGetPropertyFromMethod(MethodInfo method)
{
var type = method.DeclaringType;
return type?.GetRuntimeProperties().FirstOrDefault(prop => prop.GetMethod == method);

2
src/Avalonia.Base/Data/Core/Plugins/DataAnnotationsValidationPlugin.cs

@ -63,7 +63,7 @@ namespace Avalonia.Data.Core.Plugins
}
}
private Exception CreateException(IList<ValidationResult> errors)
private static Exception CreateException(IList<ValidationResult> errors)
{
if (errors.Count == 1)
{

2
src/Avalonia.Base/Data/Core/Plugins/IndeiValidationPlugin.cs

@ -108,7 +108,7 @@ namespace Avalonia.Data.Core.Plugins
return target;
}
private Exception GenerateException(IList<object> errors)
private static Exception GenerateException(IList<object> errors)
{
if (errors.Count == 1)
{

2
src/Avalonia.Base/Data/Core/Plugins/TaskStreamPlugin.cs

@ -59,7 +59,7 @@ namespace Avalonia.Data.Core.Plugins
return Observable.Empty<object?>();
}
private IObservable<object?> HandleCompleted(Task task)
private static IObservable<object?> HandleCompleted(Task task)
{
var resultProperty = task.GetType().GetRuntimeProperty("Result");

18
src/Avalonia.Base/Input/AccessKeyHandler.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Avalonia.Interactivity;
using Avalonia.VisualTree;
@ -23,7 +24,7 @@ namespace Avalonia.Input
/// <summary>
/// The registered access keys.
/// </summary>
private readonly List<Tuple<string, IInputElement>> _registered = new List<Tuple<string, IInputElement>>();
private readonly List<(string AccessKey, IInputElement Element)> _registered = new();
/// <summary>
/// The window to which the handler belongs.
@ -108,12 +109,12 @@ namespace Avalonia.Input
{
var existing = _registered.FirstOrDefault(x => x.Item2 == element);
if (existing != null)
if (existing != default)
{
_registered.Remove(existing);
}
_registered.Add(Tuple.Create(accessKey.ToString().ToUpper(), element));
_registered.Add((accessKey.ToString().ToUpperInvariant(), element));
}
/// <summary>
@ -143,7 +144,7 @@ namespace Avalonia.Input
{
// TODO: Use FocusScopes to store the current element and restore it when context menu is closed.
// Save currently focused input element.
_restoreFocusElement = FocusManager.Instance?.Current;
_restoreFocusElement = FocusManager.Instance?.Current;
// When Alt is pressed without a main menu, or with a closed main menu, show
// access key markers in the window (i.e. "_File").
@ -180,10 +181,11 @@ namespace Avalonia.Input
{
// If any other key is pressed with the Alt key held down, or the main menu is open,
// find all controls who have registered that access key.
var text = e.Key.ToString().ToUpper();
var text = e.Key.ToString();
var matches = _registered
.Where(x => x.Item1 == text && ((Visual)x.Item2).IsEffectivelyVisible)
.Select(x => x.Item2);
.Where(x => string.Equals(x.AccessKey, text, StringComparison.OrdinalIgnoreCase)
&& x.Element.IsEffectivelyVisible)
.Select(x => x.Element);
// If the menu is open, only match controls in the menu's visual tree.
if (menuIsOpen)
@ -194,7 +196,7 @@ namespace Avalonia.Input
var match = matches.FirstOrDefault();
// If there was a match, raise the AccessKeyPressed event on it.
if (match != null)
if (match is not null)
{
match.RaiseEvent(new RoutedEventArgs(AccessKeyPressedEvent));
e.Handled = true;

4
src/Avalonia.Base/Input/DragDropDevice.cs

@ -11,7 +11,7 @@ namespace Avalonia.Input
private Interactive? _lastTarget = null;
private Interactive? GetTarget(IInputRoot root, Point local)
private static Interactive? GetTarget(IInputRoot root, Point local)
{
var hit = root.InputHitTest(local) as Visual;
var target = hit?.GetSelfAndVisualAncestors()?.OfType<Interactive>()?.FirstOrDefault();
@ -20,7 +20,7 @@ namespace Avalonia.Input
return null;
}
private DragDropEffects RaiseDragEvent(Interactive? target, IInputRoot inputRoot, Point point, RoutedEvent<DragEventArgs> routedEvent, DragDropEffects operation, IDataObject data, KeyModifiers modifiers)
private static DragDropEffects RaiseDragEvent(Interactive? target, IInputRoot inputRoot, Point point, RoutedEvent<DragEventArgs> routedEvent, DragDropEffects operation, IDataObject data, KeyModifiers modifiers)
{
if (target == null)
return DragDropEffects.None;

5
src/Avalonia.Base/Input/KeyGesture.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using Avalonia.Utilities;
@ -143,7 +144,7 @@ namespace Avalonia.Input
// TODO: Move that to external key parser
private static Key ParseKey(string key)
{
if (s_keySynonyms.TryGetValue(key.ToLower(), out Key rv))
if (s_keySynonyms.TryGetValue(key.ToLower(CultureInfo.InvariantCulture), out Key rv))
return rv;
return EnumHelper.Parse<Key>(key, true);
@ -166,7 +167,7 @@ namespace Avalonia.Input
return EnumHelper.Parse<KeyModifiers>(modifier.ToString(), true);
}
private Key ResolveNumPadOperationKey(Key key)
private static Key ResolveNumPadOperationKey(Key key)
{
switch (key)
{

2
src/Avalonia.Base/Input/KeyboardDevice.cs

@ -25,7 +25,7 @@ namespace Avalonia.Input
public IInputElement? FocusedElement => _focusedElement;
private void ClearFocusWithinAncestors(IInputElement? element)
private static void ClearFocusWithinAncestors(IInputElement? element)
{
var el = element;

9
src/Avalonia.Base/Input/MouseDevice.cs

@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using Avalonia.Input.Raw;
using Avalonia.Interactivity;
using Avalonia.Platform;
using Avalonia.Utilities;
using Avalonia.VisualTree;
namespace Avalonia.Input
{
@ -34,7 +30,7 @@ namespace Avalonia.Input
ProcessRawEvent(margs);
}
int ButtonCount(PointerPointProperties props)
static int ButtonCount(PointerPointProperties props)
{
var rv = 0;
if (props.IsLeftButtonPressed)
@ -106,9 +102,10 @@ namespace Avalonia.Input
private void LeaveWindow()
{
}
PointerPointProperties CreateProperties(RawPointerEventArgs args)
static PointerPointProperties CreateProperties(RawPointerEventArgs args)
{
return new PointerPointProperties(args.InputModifiers, args.Type.ToUpdateKind());
}

2
src/Avalonia.Base/Input/PenDevice.cs

@ -99,7 +99,7 @@ namespace Avalonia.Input
return false;
}
private bool PenMove(Pointer pointer, ulong timestamp,
private static bool PenMove(Pointer pointer, ulong timestamp,
IInputRoot root, Point p, PointerPointProperties properties,
KeyModifiers inputModifiers, IInputElement? hitTest,
Lazy<IReadOnlyList<RawPointerPoint>?>? intermediatePoints)

4
src/Avalonia.Base/Input/Pointer.cs

@ -19,7 +19,7 @@ namespace Avalonia.Input
public int Id { get; }
IInputElement? FindCommonParent(IInputElement? control1, IInputElement? control2)
static IInputElement? FindCommonParent(IInputElement? control1, IInputElement? control2)
{
if (control1 is not Visual c1 || control2 is not Visual c2)
return null;
@ -54,7 +54,7 @@ namespace Avalonia.Input
v3.DetachedFromVisualTree += OnCaptureDetached;
}
IInputElement? GetNextCapture(Visual parent)
static IInputElement? GetNextCapture(Visual parent)
{
return parent as IInputElement ?? parent.FindAncestorOfType<IInputElement>();
}

2
src/Avalonia.Base/Input/TouchDevice.cs

@ -21,7 +21,7 @@ namespace Avalonia.Input
private Rect _lastClickRect;
private ulong _lastClickTime;
RawInputModifiers GetModifiers(RawInputModifiers modifiers, bool isLeftButtonDown)
static RawInputModifiers GetModifiers(RawInputModifiers modifiers, bool isLeftButtonDown)
{
var rv = modifiers &= RawInputModifiers.KeyboardMask;
if (isLeftButtonDown)

2
src/Avalonia.Base/Layout/AttachedLayout.cs

@ -184,7 +184,7 @@ namespace Avalonia.Layout
/// </summary>
protected void InvalidateArrange() => ArrangeInvalidated?.Invoke(this, EventArgs.Empty);
private VirtualizingLayoutContext GetVirtualizingLayoutContext(LayoutContext context)
private static VirtualizingLayoutContext GetVirtualizingLayoutContext(LayoutContext context)
{
if (context is VirtualizingLayoutContext virtualizingContext)
{

4
src/Avalonia.Base/Layout/StackLayout.cs

@ -335,7 +335,7 @@ namespace Avalonia.Layout
InvalidateLayout();
}
private double GetAverageElementSize(
private static double GetAverageElementSize(
Size availableSize,
VirtualizingLayoutContext context,
StackLayoutState stackLayoutState)
@ -359,6 +359,6 @@ namespace Avalonia.Layout
private void InvalidateLayout() => InvalidateMeasure();
private FlowLayoutAlgorithm GetFlowAlgorithm(VirtualizingLayoutContext context) => ((StackLayoutState)context.LayoutState!).FlowAlgorithm;
private static FlowLayoutAlgorithm GetFlowAlgorithm(VirtualizingLayoutContext context) => ((StackLayoutState)context.LayoutState!).FlowAlgorithm;
}
}

2
src/Avalonia.Base/Layout/UniformGridLayout.cs

@ -557,6 +557,6 @@ namespace Avalonia.Layout
private void InvalidateLayout() => InvalidateMeasure();
private FlowLayoutAlgorithm GetFlowAlgorithm(VirtualizingLayoutContext context) => ((UniformGridLayoutState)context.LayoutState!).FlowAlgorithm;
private static FlowLayoutAlgorithm GetFlowAlgorithm(VirtualizingLayoutContext context) => ((UniformGridLayoutState)context.LayoutState!).FlowAlgorithm;
}
}

5
src/Avalonia.Base/Media/ArcSegment.cs

@ -1,3 +1,4 @@
using System;
using System.Globalization;
namespace Avalonia.Media
@ -100,6 +101,6 @@ namespace Avalonia.Media
}
public override string ToString()
=> $"A {Size} {RotationAngle.ToString(CultureInfo.InvariantCulture)} {(IsLargeArc ? 1 : 0)} {(int)SweepDirection} {Point}";
=> FormattableString.Invariant($"A {Size} {RotationAngle} {(IsLargeArc ? 1 : 0)} {(int)SweepDirection} {Point}");
}
}
}

6
src/Avalonia.Base/Media/BezierSegment .cs

@ -1,3 +1,5 @@
using System;
namespace Avalonia.Media
{
public sealed class BezierSegment : PathSegment
@ -60,6 +62,6 @@ namespace Avalonia.Media
}
public override string ToString()
=> $"C {Point1} {Point2} {Point3}";
=> FormattableString.Invariant($"C {Point1} {Point2} {Point3}");
}
}
}

8
src/Avalonia.Base/Media/BoxShadow.cs

@ -94,22 +94,22 @@ namespace Avalonia.Media
if (OffsetX != 0.0)
{
sb.AppendFormat(" {0}", OffsetX.ToString());
sb.AppendFormat(" {0}", OffsetX.ToString(CultureInfo.InvariantCulture));
}
if (OffsetY != 0.0)
{
sb.AppendFormat(" {0}", OffsetY.ToString());
sb.AppendFormat(" {0}", OffsetY.ToString(CultureInfo.InvariantCulture));
}
if (Blur != 0.0)
{
sb.AppendFormat(" {0}", Blur.ToString());
sb.AppendFormat(" {0}", Blur.ToString(CultureInfo.InvariantCulture));
}
if (Spread != 0.0)
{
sb.AppendFormat(" {0}", Spread.ToString());
sb.AppendFormat(" {0}", Spread.ToString(CultureInfo.InvariantCulture));
}
sb.AppendFormat(" {0}", Color.ToString());

6
src/Avalonia.Base/Media/LineSegment.cs

@ -1,3 +1,5 @@
using System;
namespace Avalonia.Media
{
public sealed class LineSegment : PathSegment
@ -26,6 +28,6 @@ namespace Avalonia.Media
}
public override string ToString()
=> $"L {Point}";
=> FormattableString.Invariant($"L {Point}");
}
}
}

2
src/Avalonia.Base/Media/PathFigure.cs

@ -126,7 +126,7 @@ namespace Avalonia.Media
}
public override string ToString()
=> $"M {StartPoint} {string.Join(" ", _segments ?? Enumerable.Empty<PathSegment>())}{(IsClosed ? "Z" : "")}";
=> FormattableString.Invariant($"M {StartPoint} {string.Join(" ", _segments ?? Enumerable.Empty<PathSegment>())}{(IsClosed ? "Z" : "")}");
internal void ApplyTo(StreamGeometryContext ctx)
{

2
src/Avalonia.Base/Media/PathGeometry.cs

@ -133,7 +133,7 @@ namespace Avalonia.Media
public override string ToString()
{
var figuresString = _figures is not null ? string.Join(" ", _figures) : string.Empty;
return $"{(FillRule != FillRule.EvenOdd ? "F1 " : "")}{figuresString}";
return FormattableString.Invariant($"{(FillRule != FillRule.EvenOdd ? "F1 " : "")}{figuresString}");
}
}
}

12
src/Avalonia.Base/Media/PathMarkupParser.cs

@ -527,7 +527,7 @@ namespace Avalonia.Media
return span.Slice(i);
}
private bool ReadBool(ref ReadOnlySpan<char> span)
private static bool ReadBool(ref ReadOnlySpan<char> span)
{
span = SkipWhitespace(span);
@ -551,7 +551,7 @@ namespace Avalonia.Media
}
}
private double ReadDouble(ref ReadOnlySpan<char> span)
private static double ReadDouble(ref ReadOnlySpan<char> span)
{
if (!ReadArgument(ref span, out var doubleValue))
{
@ -561,7 +561,7 @@ namespace Avalonia.Media
return double.Parse(doubleValue.ToString(), CultureInfo.InvariantCulture);
}
private Size ReadSize(ref ReadOnlySpan<char> span)
private static Size ReadSize(ref ReadOnlySpan<char> span)
{
var width = ReadDouble(ref span);
span = ReadSeparator(span);
@ -569,7 +569,7 @@ namespace Avalonia.Media
return new Size(width, height);
}
private Point ReadPoint(ref ReadOnlySpan<char> span)
private static Point ReadPoint(ref ReadOnlySpan<char> span)
{
var x = ReadDouble(ref span);
span = ReadSeparator(span);
@ -577,7 +577,7 @@ namespace Avalonia.Media
return new Point(x, y);
}
private Point ReadRelativePoint(ref ReadOnlySpan<char> span, Point origin)
private static Point ReadRelativePoint(ref ReadOnlySpan<char> span, Point origin)
{
var x = ReadDouble(ref span);
span = ReadSeparator(span);
@ -585,7 +585,7 @@ namespace Avalonia.Media
return new Point(origin.X + x, origin.Y + y);
}
private bool ReadCommand(ref ReadOnlySpan<char> span, out Command command, out bool relative)
private static bool ReadCommand(ref ReadOnlySpan<char> span, out Command command, out bool relative)
{
span = SkipWhitespace(span);
if (span.IsEmpty)

6
src/Avalonia.Base/Media/QuadraticBezierSegment .cs

@ -1,3 +1,5 @@
using System;
namespace Avalonia.Media
{
public sealed class QuadraticBezierSegment : PathSegment
@ -44,6 +46,6 @@ namespace Avalonia.Media
}
public override string ToString()
=> $"Q {Point1} {Point2}";
=> FormattableString.Invariant($"Q {Point1} {Point2}");
}
}
}

4
src/Avalonia.Base/Platform/AssetLoader.cs

@ -187,13 +187,13 @@ namespace Avalonia.Platform
throw new ArgumentException($"Unsupported url type: " + uri.Scheme, nameof(uri));
}
private (IAssemblyDescriptor asm, string path) GetResAsmAndPath(Uri uri)
private static (IAssemblyDescriptor asm, string path) GetResAsmAndPath(Uri uri)
{
var asm = s_assemblyDescriptorResolver.GetAssembly(uri.Authority);
return (asm, uri.GetUnescapeAbsolutePath());
}
private IAssemblyDescriptor? GetAssembly(Uri? uri)
private static IAssemblyDescriptor? GetAssembly(Uri? uri)
{
if (uri != null)
{

2
src/Avalonia.Base/RelativePoint.cs

@ -199,7 +199,7 @@ namespace Avalonia
{
return _unit == RelativeUnit.Absolute ?
_point.ToString() :
string.Format(CultureInfo.InvariantCulture, "{0}%, {1}%", _point.X * 100, _point.Y * 100);
string.Format(CultureInfo.InvariantCulture, "{0}%, {1}%", _point.X * 100, _point.Y * 100);
}
}
}

19
src/Avalonia.Base/Rendering/Composition/Animations/KeyFrameAnimationInstance.cs

@ -87,7 +87,7 @@ namespace Avalonia.Rendering.Composition.Animations
if (elapsed < _delayTime)
{
if (_delayBehavior == AnimationDelayBehavior.SetInitialValueBeforeDelay)
return ExpressionVariant.Create(GetKeyFrame(ref ctx, _keyFrames[0]));
return ExpressionVariant.Create(KeyFrameAnimationInstance<T>.GetKeyFrame(ref ctx, _keyFrames[0]));
return currentValue;
}
@ -95,7 +95,7 @@ namespace Avalonia.Rendering.Composition.Animations
var iterationNumber = elapsed.Ticks / _duration.Ticks;
if (_iterationBehavior == AnimationIterationBehavior.Count
&& iterationNumber >= _iterationCount)
return ExpressionVariant.Create(GetKeyFrame(ref ctx, _keyFrames[_keyFrames.Length - 1]));
return ExpressionVariant.Create(KeyFrameAnimationInstance<T>.GetKeyFrame(ref ctx, _keyFrames[_keyFrames.Length - 1]));
var evenIterationNumber = iterationNumber % 2 == 0;
@ -124,13 +124,18 @@ namespace Avalonia.Rendering.Composition.Animations
{
// this is the last frame
if (c == _keyFrames.Length - 1)
return ExpressionVariant.Create(GetKeyFrame(ref ctx, kf));
return ExpressionVariant.Create(KeyFrameAnimationInstance<T>.GetKeyFrame(ref ctx, kf));
left = kf;
right = _keyFrames[c + 1];
}
else if (c == 0)
return ExpressionVariant.Create(GetKeyFrame(ref ctx, kf));
{
// The current progress is before the first frame, we implicitly use the starting value
// as the first frame in this case
right = _keyFrames[c];
break;
}
else
break;
}
@ -142,13 +147,13 @@ namespace Avalonia.Rendering.Composition.Animations
return currentValue;
return ExpressionVariant.Create(_interpolator.Interpolate(
GetKeyFrame(ref ctx, left),
GetKeyFrame(ref ctx, right),
KeyFrameAnimationInstance<T>.GetKeyFrame(ref ctx, left),
KeyFrameAnimationInstance<T>.GetKeyFrame(ref ctx, right),
easedKeyProgress
));
}
T GetKeyFrame(ref ExpressionEvaluationContext ctx, ServerKeyFrame<T> f)
static T GetKeyFrame(ref ExpressionEvaluationContext ctx, ServerKeyFrame<T> f)
{
if (f.Expression != null)
return f.Expression.Evaluate(ref ctx).CastOrDefault<T>();

2
src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs

@ -124,7 +124,7 @@ public class CompositingRenderer : IRendererWithCompositor
QueueUpdate();
}
private void SyncChildren(Visual v)
private static void SyncChildren(Visual v)
{
//TODO: Optimize by moving that logic to Visual itself
if(v.CompositionVisual == null)

4
src/Avalonia.Base/Rendering/Composition/CompositionTarget.cs

@ -62,7 +62,7 @@ namespace Avalonia.Rendering.Composition
return point * m;
}
bool TryGetInvertedTransform(CompositionVisual visual, out Matrix matrix)
static bool TryGetInvertedTransform(CompositionVisual visual, out Matrix matrix)
{
var m = visual.TryGetServerGlobalTransform();
if (m == null)
@ -75,7 +75,7 @@ namespace Avalonia.Rendering.Composition
return m33.TryInvert(out matrix);
}
bool TryTransformTo(CompositionVisual visual, Point globalPoint, out Point v)
static bool TryTransformTo(CompositionVisual visual, Point globalPoint, out Point v)
{
v = default;
if (TryGetInvertedTransform(visual, out var m))

2
src/Avalonia.Base/Rendering/Composition/Drawing/CompositionDrawingContext.cs

@ -368,7 +368,7 @@ internal class CompositionDrawingContext : IDrawingContextImpl, IDrawingContextW
: null;
}
private IDisposable? CreateChildScene(IBrush? brush)
private static IDisposable? CreateChildScene(IBrush? brush)
{
if (brush is VisualBrush visualBrush)
{

2
src/Avalonia.Base/Rendering/Composition/Server/FpsCounter.cs

@ -52,7 +52,7 @@ internal class FpsCounter
_lastFpsUpdate = now;
}
var fpsLine = $"Frame #{_totalFrames:00000000} FPS: {_fps:000} " + aux;
var fpsLine = FormattableString.Invariant($"Frame #{_totalFrames:00000000} FPS: {_fps:000} ") + aux;
double width = 0;
double height = 0;
foreach (var ch in fpsLine)

2
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs

@ -156,7 +156,7 @@ namespace Avalonia.Rendering.Composition.Server
(Compositor.BatchObjectPool.CurrentUsage + Compositor.BatchObjectPool.CurrentPool) *
Compositor.BatchObjectPool.ArraySize *
IntPtr.Size), false);
_fpsCounter.RenderFps(targetContext, $"M:{managedMem} / N:{nativeMem} R:{RenderedVisuals:0000}");
_fpsCounter.RenderFps(targetContext, FormattableString.Invariant($"M:{managedMem} / N:{nativeMem} R:{RenderedVisuals:0000}"));
}
RenderedVisuals = 0;

4
src/Avalonia.Base/Rendering/DeferredRenderer.cs

@ -272,7 +272,7 @@ namespace Avalonia.Rendering
}
}
Scene? TryGetChildScene(IRef<IDrawOperation>? op) => (op?.Item as BrushDrawOperation)?.Aux as Scene;
static Scene? TryGetChildScene(IRef<IDrawOperation>? op) => (op?.Item as BrushDrawOperation)?.Aux as Scene;
/// <inheritdoc/>
Size IVisualBrushRenderer.GetRenderTargetSize(IVisualBrush brush)
@ -725,7 +725,7 @@ namespace Avalonia.Rendering
foreach (var layer in Layers)
{
var fileName = Path.Combine(DebugFramesPath ?? string.Empty, $"frame-{id}-layer-{index++}.png");
var fileName = Path.Combine(DebugFramesPath ?? string.Empty, FormattableString.Invariant($"frame-{id}-layer-{index++}.png"));
layer.Bitmap.Item.Save(fileName);
}
}

2
src/Avalonia.Base/Rendering/RendererBase.cs

@ -36,7 +36,7 @@ namespace Avalonia.Rendering
_lastFpsUpdate = now;
}
var text = layerCount.HasValue ? $"Layers: {layerCount} FPS: {_fps:000}" : $"FPS: {_fps:000}";
var text = layerCount.HasValue ? FormattableString.Invariant($"Layers: {layerCount} FPS: {_fps:000}") : FormattableString.Invariant($"FPS: {_fps:000}");
var formattedText = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, Typeface.Default, s_fontSize, Brushes.White);

2
src/Avalonia.Base/Rendering/SceneGraph/SceneBuilder.cs

@ -318,7 +318,7 @@ namespace Avalonia.Rendering.SceneGraph
}
}
private void UpdateSize(Scene scene)
private static void UpdateSize(Scene scene)
{
var renderRoot = scene.Root.Visual as IRenderRoot;
var newSize = renderRoot?.ClientSize ?? scene.Root.Visual.Bounds.Size;

2
src/Avalonia.Base/Styling/Activators/IStyleActivator.cs

@ -39,7 +39,7 @@ namespace Avalonia.Styling.Activators
/// </summary>
/// <param name="sink">The listener.</param>
/// <remarks>
/// This method should not call <see cref="IStyleActivatorSink.OnNext(bool, int)"/>.
/// This method should not call <see cref="IStyleActivatorSink.OnNext(bool)"/>.
/// </remarks>
void Subscribe(IStyleActivatorSink sink);

2
src/Avalonia.Base/Thickness.cs

@ -277,7 +277,7 @@ namespace Avalonia
/// <returns>The string representation of the thickness.</returns>
public override string ToString()
{
return $"{_left},{_top},{_right},{_bottom}";
return FormattableString.Invariant($"{_left},{_top},{_right},{_bottom}");
}
/// <summary>

1
src/Avalonia.Base/Visual.cs

@ -417,6 +417,7 @@ namespace Avalonia
OnAttachedToVisualTree(e);
AttachedToVisualTree?.Invoke(this, e);
InvalidateVisual();
_visualRoot.Renderer?.RecalculateChildren(_visualParent!);
if (ZIndex != 0 && VisualParent is Visual parent)
parent.HasNonUniformZIndexChildren = true;

2
src/Avalonia.Base/VisualTree/TransformedBounds.cs

@ -77,6 +77,6 @@ namespace Avalonia.VisualTree
return !left.Equals(right);
}
public override string ToString() => $"Bounds: {Bounds} Clip: {Clip} Transform {Transform}";
public override string ToString() => FormattableString.Invariant($"Bounds: {Bounds} Clip: {Clip} Transform {Transform}");
}
}

2
src/Avalonia.Build.Tasks/Extensions.cs

@ -5,7 +5,7 @@ namespace Avalonia.Build.Tasks
{
static class Extensions
{
static string FormatErrorCode(BuildEngineErrorCode code) => $"AVLN:{(int)code:0000}";
static string FormatErrorCode(BuildEngineErrorCode code) => FormattableString.Invariant($"AVLN:{(int)code:0000}");
public static void LogError(this IBuildEngine engine, BuildEngineErrorCode code, string file, Exception ex,
int lineNumber = 0, int linePosition = 0)

2
src/Avalonia.Build.Tasks/GenerateAvaloniaResourcesTask.cs

@ -67,7 +67,7 @@ namespace Avalonia.Build.Tasks
{
var src = new Source(r.ItemSpec, Root);
BuildEngine.LogMessage($"avares -> name:{src.Path}, path: {src.SystemPath}, size:{src.Size}, ItemSpec:{r.ItemSpec}", _reportImportance);
BuildEngine.LogMessage(FormattableString.Invariant($"avares -> name:{src.Path}, path: {src.SystemPath}, size:{src.Size}, ItemSpec:{r.ItemSpec}"), _reportImportance);
return src;
}).ToList();

2
src/Avalonia.Controls.ColorPicker/ColorSlider/ColorSlider.cs

@ -154,7 +154,7 @@ namespace Avalonia.Controls.Primitives
/// </summary>
/// <param name="hsvColor">The <see cref="HsvColor"/> to round component values for.</param>
/// <returns>A new <see cref="HsvColor"/> with rounded component values.</returns>
private HsvColor RoundComponentValues(HsvColor hsvColor)
private static HsvColor RoundComponentValues(HsvColor hsvColor)
{
return new HsvColor(
Math.Round(hsvColor.A, 2, MidpointRounding.AwayFromZero),

2
src/Avalonia.Controls.ColorPicker/ColorSpectrum/ColorSpectrum.cs

@ -1146,7 +1146,7 @@ namespace Avalonia.Controls.Primitives
});
}
private void FillPixelForBox(
private static void FillPixelForBox(
double x,
double y,
Hsv baseHsv,

2
src/Avalonia.Controls.DataGrid/DataGridTemplateColumn.cs

@ -56,7 +56,7 @@ namespace Avalonia.Controls
set => SetAndRaise(CellEditingTemplateProperty, ref _cellEditingCellTemplate, value);
}
private void OnCellTemplateChanged(AvaloniaPropertyChangedEventArgs e)
private static void OnCellTemplateChanged(AvaloniaPropertyChangedEventArgs e)
{
var oldValue = (IDataTemplate)e.OldValue;
var value = (IDataTemplate)e.NewValue;

2
src/Avalonia.Controls/Automation/Peers/ComboBoxAutomationPeer.cs

@ -71,7 +71,7 @@ namespace Avalonia.Automation.Peers
}
}
private ExpandCollapseState ToState(bool value)
private static ExpandCollapseState ToState(bool value)
{
return value ? ExpandCollapseState.Expanded : ExpandCollapseState.Collapsed;
}

2
src/Avalonia.Controls/Calendar/CalendarBlackoutDatesCollection.cs

@ -206,7 +206,7 @@ namespace Avalonia.Controls.Primitives
return true;
}
private void EnsureValidThread()
private static void EnsureValidThread()
{
Dispatcher.UIThread.VerifyAccess();
}

3
src/Avalonia.Controls/Calendar/SelectedDatesCollection.cs

@ -6,7 +6,6 @@
using Avalonia.Threading;
using System;
using System.Collections.ObjectModel;
using System.Threading;
namespace Avalonia.Controls.Primitives
{
@ -353,7 +352,7 @@ namespace Avalonia.Controls.Primitives
return true;
}
private void EnsureValidThread()
private static void EnsureValidThread()
{
Dispatcher.UIThread.VerifyAccess();
}

2
src/Avalonia.Controls/DateTimePickers/DateTimePickerPanel.cs

@ -259,7 +259,7 @@ namespace Avalonia.Controls.Primitives
SelectedValue = (int)newSel * Increment + MinimumValue;
_suppressUpdateOffset = false;
System.Diagnostics.Debug.WriteLine($"Offset: {_offset} ItemHeight: {ItemHeight}");
System.Diagnostics.Debug.WriteLine(FormattableString.Invariant($"Offset: {_offset} ItemHeight: {ItemHeight}"));
}
}

8
src/Avalonia.Controls/Grid.cs

@ -1165,7 +1165,7 @@ namespace Avalonia.Controls
/// <remarks>
/// For "Auto" definitions MinWidth is used in place of PreferredSize.
/// </remarks>
private double GetMeasureSizeForRange(
private static double GetMeasureSizeForRange(
IReadOnlyList<DefinitionBase> definitions,
int start,
int count)
@ -1192,7 +1192,7 @@ namespace Avalonia.Controls
/// <param name="start">Starting index of the range.</param>
/// <param name="count">Number of definitions included in the range.</param>
/// <returns>Length type for given range.</returns>
private LayoutTimeSizeType GetLengthTypeForRange(
private static LayoutTimeSizeType GetLengthTypeForRange(
IReadOnlyList<DefinitionBase> definitions,
int start,
int count)
@ -1721,7 +1721,7 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="definitions">Array of definitions to use for calculations.</param>
/// <returns>Desired size.</returns>
private double CalculateDesiredSize(
private static double CalculateDesiredSize(
IReadOnlyList<DefinitionBase> definitions)
{
double desiredSize = 0;
@ -2281,7 +2281,7 @@ namespace Avalonia.Controls
/// <param name="start">Start of the range.</param>
/// <param name="count">Number of items in the range.</param>
/// <returns>Final size.</returns>
private double GetFinalSizeForRange(
private static double GetFinalSizeForRange(
IReadOnlyList<DefinitionBase> definitions,
int start,
int count)

2
src/Avalonia.Controls/GridSplitter.cs

@ -516,7 +516,7 @@ namespace Avalonia.Controls
/// <summary>
/// Retrieves the ActualWidth or ActualHeight of the definition depending on its type Column or Row.
/// </summary>
private double GetActualLength(DefinitionBase definition)
private static double GetActualLength(DefinitionBase definition)
{
var column = definition as ColumnDefinition;

11
src/Avalonia.Controls/MenuItemAccessKeyHandler.cs

@ -14,7 +14,7 @@ namespace Avalonia.Controls
/// <summary>
/// The registered access keys.
/// </summary>
private readonly List<Tuple<string, IInputElement>> _registered = new List<Tuple<string, IInputElement>>();
private readonly List<(string AccessKey, IInputElement Element)> _registered = new();
/// <summary>
/// The window to which the handler belongs.
@ -59,12 +59,12 @@ namespace Avalonia.Controls
{
var existing = _registered.FirstOrDefault(x => x.Item2 == element);
if (existing != null)
if (existing != default)
{
_registered.Remove(existing);
}
_registered.Add(Tuple.Create(accessKey.ToString().ToUpper(), element));
_registered.Add((accessKey.ToString().ToUpperInvariant(), element));
}
/// <summary>
@ -88,9 +88,10 @@ namespace Avalonia.Controls
{
if (!string.IsNullOrWhiteSpace(e.Text))
{
var text = e.Text.ToUpper();
var text = e.Text;
var focus = _registered
.FirstOrDefault(x => x.Item1 == text && x.Item2.IsEffectivelyVisible)?.Item2;
.FirstOrDefault(x => string.Equals(x.AccessKey, text, StringComparison.OrdinalIgnoreCase)
&& x.Element.IsEffectivelyVisible).Element;
focus?.RaiseEvent(new RoutedEventArgs(AccessKeyHandler.AccessKeyPressedEvent));

4
src/Avalonia.Controls/Platform/InProcessDragSource.cs

@ -69,7 +69,7 @@ namespace Avalonia.Platform
return effect;
}
private DragDropEffects GetPreferredEffect(DragDropEffects effect, RawInputModifiers modifiers)
private static DragDropEffects GetPreferredEffect(DragDropEffects effect, RawInputModifiers modifiers)
{
if (effect == DragDropEffects.Copy || effect == DragDropEffects.Move || effect == DragDropEffects.Link || effect == DragDropEffects.None)
return effect; // No need to check for the modifiers.
@ -80,7 +80,7 @@ namespace Avalonia.Platform
return DragDropEffects.Move;
}
private StandardCursorType GetCursorForDropEffect(DragDropEffects effects)
private static StandardCursorType GetCursorForDropEffect(DragDropEffects effects)
{
if (effects.HasAllFlags(DragDropEffects.Copy))
return StandardCursorType.DragCopy;

6
src/Avalonia.Controls/Primitives/Popup.cs

@ -1,6 +1,5 @@
using System;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Disposables;
using Avalonia.Automation.Peers;
using Avalonia.Controls.Mixins;
@ -15,7 +14,6 @@ using Avalonia.Metadata;
using Avalonia.Platform;
using Avalonia.VisualTree;
using Avalonia.Media;
using Avalonia.Utilities;
namespace Avalonia.Controls.Primitives
{
@ -639,7 +637,7 @@ namespace Avalonia.Controls.Primitives
return Disposable.Create((unsubscribe, target, handler), state => state.unsubscribe(state.target, state.handler));
}
private void WindowManagerAddShadowHintChanged(IPopupHost host, bool hint)
private static void WindowManagerAddShadowHintChanged(IPopupHost host, bool hint)
{
if(host is PopupRoot pr && pr.PlatformImpl is not null)
{
@ -769,7 +767,7 @@ namespace Avalonia.Controls.Primitives
}
}
private void PassThroughEvent(PointerPressedEventArgs e)
private static void PassThroughEvent(PointerPressedEventArgs e)
{
if (e.Source is LightDismissOverlayLayer layer &&
layer.GetVisualRoot() is InputElement root)

2
src/Avalonia.Controls/Repeater/RecyclingElementFactory.cs

@ -87,7 +87,7 @@ namespace Avalonia.Controls
protected virtual string OnSelectTemplateKeyCore(object? dataContext, Control? owner)
{
if (SelectTemplateKey is object)
if (SelectTemplateKey is not null)
{
_args ??= new SelectTemplateEventArgs();
_args.TemplateKey = null;

2
src/Avalonia.Controls/Selection/IndexRange.cs

@ -86,7 +86,7 @@ namespace Avalonia.Controls.Selection
return hashCode;
}
public override string ToString() => $"[{Begin}..{End}]";
public override string ToString() => FormattableString.Invariant($"[{Begin}..{End}]");
public static bool operator ==(IndexRange left, IndexRange right) => left.Equals(right);
public static bool operator !=(IndexRange left, IndexRange right) => !(left == right);

4
src/Avalonia.Controls/Selection/SelectionNodeBase.cs

@ -290,12 +290,12 @@ namespace Avalonia.Controls.Selection
// so bail.
//
// See unit test Handles_Selection_Made_In_CollectionChanged for more details.
if (ItemsView is object &&
if (ItemsView is not null &&
RangesEnabled &&
Ranges.Count > 0 &&
e.Action == NotifyCollectionChangedAction.Add)
{
var lastIndex = Ranges.Last().End;
var lastIndex = Ranges[Ranges.Count - 1].End;
if (e.NewStartingIndex <= lastIndex)
{

20
src/Avalonia.Controls/Slider.cs

@ -190,7 +190,7 @@ namespace Avalonia.Controls
_increaseButtonSubscription?.Dispose();
_increaseButtonReleaseDispose?.Dispose();
_pointerMovedDispose?.Dispose();
_decreaseButton = e.NameScope.Find<Button>("PART_DecreaseButton");
_track = e.NameScope.Find<Track>("PART_Track");
_increaseButton = e.NameScope.Find<Button>("PART_IncreaseButton");
@ -258,7 +258,7 @@ namespace Avalonia.Controls
e.Handled = handled;
}
private void MoveToNextTick(double direction)
{
if (direction == 0.0) return;
@ -317,6 +317,12 @@ namespace Avalonia.Controls
private void TrackMoved(object? sender, PointerEventArgs e)
{
if (!IsEnabled)
{
_isDragging = false;
return;
}
if (_isDragging)
{
MoveToPoint(e.GetCurrentPoint(_track));
@ -343,15 +349,15 @@ namespace Avalonia.Controls
return;
var orient = Orientation == Orientation.Horizontal;
var thumbLength = (orient
? _track.Thumb.Bounds.Width
var thumbLength = (orient
? _track.Thumb.Bounds.Width
: _track.Thumb.Bounds.Height) + double.Epsilon;
var trackLength = (orient
? _track.Bounds.Width
var trackLength = (orient
? _track.Bounds.Width
: _track.Bounds.Height) - thumbLength;
var trackPos = orient ? posOnTrack.Position.X : posOnTrack.Position.Y;
var logicalPos = MathUtilities.Clamp((trackPos - thumbLength * 0.5) / trackLength, 0.0d, 1.0d);
var invert = orient ?
var invert = orient ?
IsDirectionReversed ? 1 : 0 :
IsDirectionReversed ? 0 : 1;
var calcVal = Math.Abs(invert - logicalPos);

7
src/Avalonia.Controls/SplitView.cs

@ -1,14 +1,11 @@
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Metadata;
using Avalonia.Platform;
using Avalonia.VisualTree;
using System;
using System.Reactive.Disposables;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using Avalonia.LogicalTree;
@ -431,7 +428,7 @@ namespace Avalonia.Controls
}
}
private string GetPseudoClass(SplitViewDisplayMode mode)
private static string GetPseudoClass(SplitViewDisplayMode mode)
{
return mode switch
{
@ -443,7 +440,7 @@ namespace Avalonia.Controls
};
}
private string GetPseudoClass(SplitViewPanePlacement placement)
private static string GetPseudoClass(SplitViewPanePlacement placement)
{
return placement switch
{

2
src/Avalonia.Controls/TextBox.cs

@ -1588,7 +1588,7 @@ namespace Avalonia.Controls
private int CoerceCaretIndex(int value) => CoerceCaretIndex(value, Text);
private int CoerceCaretIndex(int value, string? text)
private static int CoerceCaretIndex(int value, string? text)
{
if (text == null)
{

2
src/Avalonia.Controls/TopLevel.cs

@ -427,7 +427,7 @@ namespace Avalonia.Controls
LayoutHelper.InvalidateSelfAndChildrenMeasure(this);
}
private bool TransparencyLevelsMatch (WindowTransparencyLevel requested, WindowTransparencyLevel received)
private static bool TransparencyLevelsMatch (WindowTransparencyLevel requested, WindowTransparencyLevel received)
{
if(requested == received)
{

1
src/Avalonia.Controls/UserControl.cs

@ -1,4 +1,3 @@
using System;
using Avalonia.Styling;
namespace Avalonia.Controls

2
src/Avalonia.DesignerSupport/Remote/HtmlTransport/HtmlTransport.cs

@ -162,7 +162,7 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport
if (sendNow != null && socket != null)
{
await socket.SendMessage(
$"frame:{sendNow.SequenceId}:{sendNow.Width}:{sendNow.Height}:{sendNow.Stride}:{sendNow.DpiX}:{sendNow.DpiY}");
FormattableString.Invariant($"frame:{sendNow.SequenceId}:{sendNow.Width}:{sendNow.Height}:{sendNow.Stride}:{sendNow.DpiX}:{sendNow.DpiY}"));
await socket.SendMessage(false, sendNow.Data);
}

2
src/Avalonia.DesignerSupport/Remote/HtmlTransport/SimpleWebSocketHttpServer.cs

@ -146,7 +146,7 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport
public async Task RespondAsync(int code, byte[] data, string contentType)
{
var headers = Encoding.UTF8.GetBytes($"HTTP/1.1 {code} {(HttpStatusCode)code}\r\nConnection: close\r\nContent-Type: {contentType}\r\nContent-Length: {data.Length}\r\n\r\n");
var headers = Encoding.UTF8.GetBytes(FormattableString.Invariant($"HTTP/1.1 {code} {(HttpStatusCode)code}\r\nConnection: close\r\nContent-Type: {contentType}\r\nContent-Length: {data.Length}\r\n\r\n"));
await _stream.WriteAsync(headers, 0, headers.Length);
await _stream.WriteAsync(data, 0, data.Length);
_stream.Dispose();

2
src/Avalonia.Diagnostics/Diagnostics/Screenshots/FilePickerHandler.cs

@ -47,7 +47,7 @@ namespace Avalonia.Diagnostics.Screenshots
/// </summary>
public string Title { get; } = "Save Screenshot to ...";
Window GetWindow(Control control)
static Window GetWindow(Control control)
{
var window = control.VisualRoot as Window;
var app = Application.Current;

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

@ -82,7 +82,7 @@ namespace Avalonia.Diagnostics.ViewModels
{
var setterValue = regularSetter.Value;
var resourceInfo = GetResourceInfo(setterValue);
var resourceInfo = GetResourceInfo(setterValue);
SetterViewModel setterVm;
@ -121,7 +121,7 @@ namespace Avalonia.Diagnostics.ViewModels
public bool CanNavigateToParentProperty => _selectedEntitiesStack.Count >= 1;
private (object resourceKey, bool isDynamic)? GetResourceInfo(object? value)
private static (object resourceKey, bool isDynamic)? GetResourceInfo(object? value)
{
if (value is StaticResourceExtension staticResource)
{
@ -136,7 +136,7 @@ namespace Avalonia.Diagnostics.ViewModels
return null;
}
private bool IsBinding(object? value)
private static bool IsBinding(object? value)
{
switch (value)
{
@ -253,7 +253,7 @@ namespace Avalonia.Diagnostics.ViewModels
}
}
private IEnumerable<PropertyViewModel> GetAvaloniaProperties(object o)
private static IEnumerable<PropertyViewModel> GetAvaloniaProperties(object o)
{
if (o is AvaloniaObject ao)
{
@ -267,7 +267,7 @@ namespace Avalonia.Diagnostics.ViewModels
}
}
private IEnumerable<PropertyViewModel> GetClrProperties(object o, bool showImplementedInterfaces)
private static IEnumerable<PropertyViewModel> GetClrProperties(object o, bool showImplementedInterfaces)
{
foreach (var p in GetClrProperties(o, o.GetType()))
{
@ -286,7 +286,7 @@ namespace Avalonia.Diagnostics.ViewModels
}
}
private IEnumerable<PropertyViewModel> GetClrProperties(object o, Type t)
private static IEnumerable<PropertyViewModel> GetClrProperties(object o, Type t)
{
return t.GetProperties()
.Where(x => x.GetIndexParameters().Length == 0)
@ -411,7 +411,7 @@ namespace Avalonia.Diagnostics.ViewModels
}
}
private int GroupIndex(string? group)
private static int GroupIndex(string? group)
{
switch (group)
{

8
src/Avalonia.Dialogs/ManagedStorageProvider.cs

@ -29,7 +29,7 @@ public class ManagedStorageProvider<T> : BclStorageProvider where T : Window, ne
public override async Task<IReadOnlyList<IStorageFile>> OpenFilePickerAsync(FilePickerOpenOptions options)
{
var model = new ManagedFileChooserViewModel(options, _managedOptions);
var results = await Show(model, _parent);
var results = await ManagedStorageProvider<T>.Show(model, _parent);
return results.Select(f => new BclStorageFile(new FileInfo(f))).ToArray();
}
@ -37,7 +37,7 @@ public class ManagedStorageProvider<T> : BclStorageProvider where T : Window, ne
public override async Task<IStorageFile?> SaveFilePickerAsync(FilePickerSaveOptions options)
{
var model = new ManagedFileChooserViewModel(options, _managedOptions);
var results = await Show(model, _parent);
var results = await ManagedStorageProvider<T>.Show(model, _parent);
return results.FirstOrDefault() is { } result
? new BclStorageFile(new FileInfo(result))
@ -47,12 +47,12 @@ public class ManagedStorageProvider<T> : BclStorageProvider where T : Window, ne
public override async Task<IReadOnlyList<IStorageFolder>> OpenFolderPickerAsync(FolderPickerOpenOptions options)
{
var model = new ManagedFileChooserViewModel(options, _managedOptions);
var results = await Show(model, _parent);
var results = await ManagedStorageProvider<T>.Show(model, _parent);
return results.Select(f => new BclStorageFolder(new DirectoryInfo(f))).ToArray();
}
private async Task<string[]> Show(ManagedFileChooserViewModel model, Window parent)
private static async Task<string[]> Show(ManagedFileChooserViewModel model, Window parent)
{
var dialog = new T
{

2
src/Avalonia.FreeDesktop/DBusTrayIconImpl.cs

@ -127,7 +127,7 @@ namespace Avalonia.FreeDesktop
var pid = Process.GetCurrentProcess().Id;
var tid = s_trayIconInstanceId++;
_sysTrayServiceName = $"org.kde.StatusNotifierItem-{pid}-{tid}";
_sysTrayServiceName = FormattableString.Invariant($"org.kde.StatusNotifierItem-{pid}-{tid}");
_statusNotifierItemDbusObj = new StatusNotifierItemDbusObj(_dbusMenuPath);
try

8
src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs

@ -34,14 +34,14 @@ namespace Avalonia.FreeDesktop
Poll(0);
}
private string GetSymlinkTarget(string x) => Path.GetFullPath(Path.Combine(DevByLabelDir, NativeMethods.ReadLink(x)));
private static string GetSymlinkTarget(string x) => Path.GetFullPath(Path.Combine(DevByLabelDir, NativeMethods.ReadLink(x)));
private string UnescapeString(string input, string regexText, int escapeBase) =>
private static string UnescapeString(string input, string regexText, int escapeBase) =>
new Regex(regexText).Replace(input, m => Convert.ToChar(Convert.ToByte(m.Groups[1].Value, escapeBase)).ToString());
private string UnescapePathFromProcMounts(string input) => UnescapeString(input, @"\\(\d{3})", 8);
private static string UnescapePathFromProcMounts(string input) => UnescapeString(input, @"\\(\d{3})", 8);
private string UnescapeDeviceLabel(string input) => UnescapeString(input, @"\\x([0-9a-f]{2})", 16);
private static string UnescapeDeviceLabel(string input) => UnescapeString(input, @"\\x([0-9a-f]{2})", 16);
private void Poll(long _)
{

2
src/Avalonia.Native/AvaloniaNativeMenuExporter.cs

@ -65,7 +65,7 @@ namespace Avalonia.Native
}
}
private NativeMenu CreateDefaultAppMenu()
private static NativeMenu CreateDefaultAppMenu()
{
var result = new NativeMenu();

3
src/Avalonia.Native/IAvnMenu.cs

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Platform.Interop;
namespace Avalonia.Native.Interop
{
@ -112,7 +111,7 @@ namespace Avalonia.Native.Interop.Impl
return result;
}
private __MicroComIAvnMenuItemProxy CreateNew(IAvaloniaNativeFactory factory, NativeMenuItemBase item)
private static __MicroComIAvnMenuItemProxy CreateNew(IAvaloniaNativeFactory factory, NativeMenuItemBase item)
{
var nativeItem = (__MicroComIAvnMenuItemProxy)(item is NativeMenuItemSeparator ?
factory.CreateMenuItemSeparator() :

4
src/Avalonia.OpenGL/Controls/OpenGlControlBase.cs

@ -38,7 +38,7 @@ namespace Avalonia.OpenGL.Controls
base.Render(context);
}
private void CheckError(GlInterface gl)
private static void CheckError(GlInterface gl)
{
int err;
while ((err = gl.GetError()) != GL_NO_ERROR)
@ -197,7 +197,7 @@ namespace Avalonia.OpenGL.Controls
}
}
private bool CheckFramebufferStatus(GlInterface gl)
private static bool CheckFramebufferStatus(GlInterface gl)
{
var status = gl.CheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)

2
src/Avalonia.Remote.Protocol/MetsysBson.cs

@ -562,7 +562,7 @@ namespace Metsys.Bson
{
if (_string == null && Value != null)
{
_string = BitConverter.ToString(Value).Replace("-", string.Empty).ToLower();
_string = BitConverter.ToString(Value).Replace("-", string.Empty).ToLowerInvariant();
}
return _string;

16
src/Avalonia.Themes.Fluent/Controls/CalendarButton.xaml

@ -35,13 +35,13 @@
<!-- To mimic WinUI SystemFocusVisual, Focus visual is drawn outside the bounds of the item -->
<Border Name="Root" Background="{TemplateBinding Background}"
BorderThickness="0" ClipToBounds="True">
<ContentControl Name="Content"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
FontSize="{TemplateBinding FontSize}"
Margin="{TemplateBinding Padding}" />
<ContentPresenter Name="Content"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
FontSize="{TemplateBinding FontSize}"
Margin="{TemplateBinding Padding}" />
</Border>
<!-- Drawn Border should render on top of background to preserve the 1px margin between items -->
@ -70,7 +70,7 @@
<Setter Property="BorderBrush" Value="{DynamicResource CalendarViewSelectedBorderBrush}" />
</Style>
<Style Selector="^ /template/ ContentControl#Content">
<Style Selector="^ /template/ ContentPresenter#Content">
<Setter Property="Foreground" Value="{DynamicResource CalendarViewTodayForeground}" />
<Setter Property="FontWeight" Value="SemiBold" />
</Style>

39
src/Avalonia.Themes.Fluent/Controls/Slider.xaml

@ -302,26 +302,6 @@
<Setter Property="IsVisible" Value="True" />
</Style>
<!-- Disabled State -->
<Style Selector="^:disabled">
<Style Selector="^ /template/ RepeatButton#PART_DecreaseButton">
<Setter Property="Background" Value="{DynamicResource SliderTrackValueFillDisabled}" />
</Style>
<Style Selector="^ /template/ RepeatButton#PART_IncreaseButton">
<Setter Property="Background" Value="{DynamicResource SliderTrackFillDisabled}" />
</Style>
<Style Selector="^ /template/ Thumb">
<Setter Property="Background" Value="{DynamicResource SliderThumbBackgroundDisabled}" />
</Style>
<Style Selector="^ /template/ TickBar">
<Setter Property="Fill" Value="{DynamicResource SliderTickBarFillDisabled}" />
</Style>
</Style>
<!-- PointerOver State -->
<Style Selector="^:pointerover">
<Style Selector="^ /template/ Grid#SliderContainer">
@ -362,6 +342,25 @@
</Style>
</Style>
<!-- Disabled State -->
<Style Selector="^:disabled">
<Style Selector="^ /template/ RepeatButton#PART_DecreaseButton">
<Setter Property="Background" Value="{DynamicResource SliderTrackValueFillDisabled}" />
</Style>
<Style Selector="^ /template/ RepeatButton#PART_IncreaseButton">
<Setter Property="Background" Value="{DynamicResource SliderTrackFillDisabled}" />
</Style>
<Style Selector="^ /template/ Thumb">
<Setter Property="Background" Value="{DynamicResource SliderThumbBackgroundDisabled}" />
</Style>
<Style Selector="^ /template/ TickBar">
<Setter Property="Fill" Value="{DynamicResource SliderTickBarFillDisabled}" />
</Style>
</Style>
<Style Selector="^:error">
<Setter Property="Foreground" Value="{DynamicResource SystemControlErrorTextForegroundBrush}" />
<Style Selector="^ /template/ Thumb">

18
src/Avalonia.Themes.Simple/Controls/CalendarButton.xaml

@ -32,14 +32,14 @@
Opacity="0.5" />
<!-- Focusable="False" -->
<ContentControl Name="Content"
Margin="1,0,1,1"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
FontSize="{TemplateBinding FontSize}"
Foreground="{TemplateBinding Foreground}" />
<ContentPresenter Name="Content"
Margin="1,0,1,1"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
FontSize="{TemplateBinding FontSize}"
Foreground="{TemplateBinding Foreground}" />
<Rectangle Name="FocusVisual"
IsHitTestVisible="False"
@ -62,7 +62,7 @@
<Setter Property="IsVisible" Value="True" />
</Style>
<Style Selector="^:inactive /template/ ContentControl#Content">
<Style Selector="^:inactive /template/ ContentPresenter#Content">
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundLowBrush}" />
</Style>

2
src/Avalonia.X11/X11IconLoader.cs

@ -9,7 +9,7 @@ namespace Avalonia.X11
{
class X11IconLoader : IPlatformIconLoader
{
IWindowIconImpl LoadIcon(Bitmap bitmap)
static IWindowIconImpl LoadIcon(Bitmap bitmap)
{
var rv = new X11IconData(bitmap);
bitmap.Dispose();

9
src/Avalonia.X11/X11Platform.cs

@ -5,7 +5,6 @@ using System.Reflection;
using System.Runtime.InteropServices;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Dialogs;
using Avalonia.FreeDesktop;
using Avalonia.FreeDesktop.DBusIme;
using Avalonia.Input;
@ -85,7 +84,7 @@ namespace Avalonia.X11
.Bind<IMountedVolumeInfoProvider>().ToConstant(new LinuxMountedVolumeInfoProvider())
.Bind<IPlatformLifetimeEventsImpl>().ToConstant(new X11PlatformLifetimeEvents(this));
X11Screens = Avalonia.X11.X11Screens.Init(this);
X11Screens = X11.X11Screens.Init(this);
Screens = new X11Screens(X11Screens);
if (Info.XInputVersion != null)
{
@ -143,7 +142,7 @@ namespace Avalonia.X11
throw new NotSupportedException();
}
bool EnableIme(X11PlatformOptions options)
static bool EnableIme(X11PlatformOptions options)
{
// Disable if explicitly asked by user
var avaloniaImModule = Environment.GetEnvironmentVariable("AVALONIA_IM_MODULE");
@ -164,8 +163,8 @@ namespace Avalonia.X11
return isCjkLocale;
}
bool ShouldUseXim()
static bool ShouldUseXim()
{
// Check if we are forbidden from using IME
if (Environment.GetEnvironmentVariable("AVALONIA_IM_MODULE") == "none"

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save