Browse Source

Merge branch 'master' into fixes/list-selection-interactions

pull/11455/head
Max Katz 3 years ago
committed by GitHub
parent
commit
908e3d2888
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      .ncrunch/AppWithoutLifetime.v3.ncrunchproject
  2. 5
      .ncrunch/Avalonia.Headless.NUnit.netstandard2.0.v3.ncrunchproject
  3. 5
      .ncrunch/Avalonia.Headless.XUnit.netstandard2.0.v3.ncrunchproject
  4. 112
      src/Android/Avalonia.Android/Platform/Input/AndroidKeyboardDevice.cs
  5. 2
      src/Avalonia.Base/Animation/AnimatorKeyFrame.cs
  6. 2
      src/Avalonia.Base/AvaloniaProperty.cs
  7. 2
      src/Avalonia.Base/AvaloniaProperty`1.cs
  8. 2
      src/Avalonia.Base/Collections/AvaloniaListConverter.cs
  9. 4
      src/Avalonia.Base/Data/BindingValue.cs
  10. 2
      src/Avalonia.Base/Data/Converters/DefaultValueConverter.cs
  11. 2
      src/Avalonia.Base/Data/Core/BindingExpression.cs
  12. 0
      src/Avalonia.Base/Data/TemplateBinding.cs
  13. 8
      src/Avalonia.Base/Diagnostics/TrimmingMessages.cs
  14. 3
      src/Avalonia.Base/Input/IAccessKeyHandler.cs
  15. 5
      src/Avalonia.Base/Input/IInputRoot.cs
  16. 5
      src/Avalonia.Base/Input/IMainMenu.cs
  17. 46
      src/Avalonia.Base/Interactivity/RoutedPropertyChangedEventArgs.cs
  18. 1
      src/Avalonia.Base/Properties/AssemblyInfo.cs
  19. 2
      src/Avalonia.Base/PropertyStore/DirectUntypedBindingObserver.cs
  20. 2
      src/Avalonia.Base/PropertyStore/LocalValueBindingObserver.cs
  21. 4
      src/Avalonia.Base/PropertyStore/UntypedValueUtils.cs
  22. 2
      src/Avalonia.Base/StyledProperty.cs
  23. 4
      src/Avalonia.Base/Styling/PropertyEqualsSelector.cs
  24. 2
      src/Avalonia.Base/Styling/Setter.cs
  25. 10
      src/Avalonia.Base/Utilities/TypeUtilities.cs
  26. 2
      src/Avalonia.Base/Visual.cs
  27. 6
      src/Avalonia.Controls.ColorPicker/ColorSlider/ColorSlider.cs
  28. 2
      src/Avalonia.Controls/Avalonia.Controls.csproj
  29. 4
      src/Avalonia.Controls/Button.cs
  30. 4
      src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.cs
  31. 7
      src/Avalonia.Controls/ComboBox.cs
  32. 11
      src/Avalonia.Controls/ContentControl.cs
  33. 3
      src/Avalonia.Controls/IContentControl.cs
  34. 2
      src/Avalonia.Controls/IHeadered.cs
  35. 3
      src/Avalonia.Controls/IMenu.cs
  36. 3
      src/Avalonia.Controls/IMenuElement.cs
  37. 3
      src/Avalonia.Controls/IMenuItem.cs
  38. 2
      src/Avalonia.Controls/INativeMenuExporterEventsImplBridge.cs
  39. 2
      src/Avalonia.Controls/Menu.cs
  40. 2
      src/Avalonia.Controls/MenuItemAccessKeyHandler.cs
  41. 2
      src/Avalonia.Controls/Panel.cs
  42. 459
      src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs
  43. 58
      src/Avalonia.Controls/Platform/ExportAvaloniaModuleAttribute.cs
  44. 4
      src/Avalonia.Controls/Platform/IMenuInteractionHandler.cs
  45. 11
      src/Avalonia.Controls/Presenters/ContentPresenter.cs
  46. 5
      src/Avalonia.Controls/Presenters/IContentPresenterHost.cs
  47. 2
      src/Avalonia.Controls/Primitives/AccessText.cs
  48. 37
      src/Avalonia.Controls/Primitives/RangeBase.cs
  49. 18
      src/Avalonia.Controls/Slider.cs
  50. 6
      src/Avalonia.Controls/SplitButton/SplitButton.cs
  51. 18
      src/Avalonia.Controls/SplitView/SplitView.cs
  52. 6
      src/Avalonia.Controls/TextBlock.cs
  53. 2
      src/Avalonia.Controls/TextBox.cs
  54. 2
      src/Avalonia.Controls/ToggleSwitch.cs
  55. 25
      src/Avalonia.Controls/TopLevel.cs
  56. 4
      src/Avalonia.Controls/Window.cs
  57. 12
      src/Avalonia.Controls/WindowBase.cs
  58. 2
      src/Avalonia.Diagnostics/Diagnostics/Models/ConsoleContext.cs
  59. 2
      src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
  60. 2
      src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
  61. 2
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CompiledBindingPath.cs
  62. 6
      src/Markup/Avalonia.Markup/Avalonia.Markup.csproj
  63. 4
      src/Markup/Avalonia.Markup/Data/BindingBase.cs
  64. 2
      src/Markup/Avalonia.Markup/Markup/Data/DelayedBinding.cs
  65. 5
      src/Markup/Avalonia.Markup/Markup/Parsers/ArgumentListParser.cs
  66. 5
      src/Markup/Avalonia.Markup/Markup/Parsers/PropertyPathGrammar.cs
  67. 2
      src/Markup/Avalonia.Markup/Markup/Parsers/SelectorParser.cs
  68. 2
      tests/Avalonia.Controls.UnitTests/MaskedTextBoxTests.cs
  69. 2
      tests/Avalonia.Controls.UnitTests/Platform/DefaultMenuInteractionHandlerTests.cs
  70. 2
      tests/Avalonia.Controls.UnitTests/TextBoxTests.cs
  71. 2
      tests/Avalonia.Controls.UnitTests/TopLevelTests.cs
  72. 2
      tests/Avalonia.Markup.Xaml.UnitTests/XamlTestBase.cs
  73. 2
      tests/Avalonia.UnitTests/TestRoot.cs

5
.ncrunch/AppWithoutLifetime.v3.ncrunchproject

@ -0,0 +1,5 @@
<ProjectConfiguration>
<Settings>
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
</Settings>
</ProjectConfiguration>

5
.ncrunch/Avalonia.Headless.NUnit.netstandard2.0.v3.ncrunchproject

@ -0,0 +1,5 @@
<ProjectConfiguration>
<Settings>
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
</Settings>
</ProjectConfiguration>

5
.ncrunch/Avalonia.Headless.XUnit.netstandard2.0.v3.ncrunchproject

@ -0,0 +1,5 @@
<ProjectConfiguration>
<Settings>
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
</Settings>
</ProjectConfiguration>

112
src/Android/Avalonia.Android/Platform/Input/AndroidKeyboardDevice.cs

@ -5,8 +5,9 @@ using Avalonia.Input;
namespace Avalonia.Android.Platform.Input
{
internal class AndroidKeyboardDevice : KeyboardDevice, IKeyboardDevice {
private static readonly Dictionary<Keycode, Key> KeyDic = new Dictionary<Keycode, Key>
internal class AndroidKeyboardDevice : KeyboardDevice, IKeyboardDevice
{
private static readonly Dictionary<Keycode, Key> KeyDic = new Dictionary<Keycode, Key>
{
// { Keycode.Cancel?, Key.Cancel },
{ Keycode.Del, Key.Back },
@ -15,7 +16,7 @@ namespace Avalonia.Android.Platform.Input
{ Keycode.Clear, Key.Clear },
{ Keycode.Enter, Key.Return },
{ Keycode.MediaPause, Key.Pause },
//{ Keycode.?, Key.CapsLock }
{ Keycode.CapsLock, Key.CapsLock },
//{ Keycode.?, Key.HangulMode }
//{ Keycode.?, Key.JunjaMode }
//{ Keycode.?, Key.FinalMode }
@ -28,8 +29,8 @@ namespace Avalonia.Android.Platform.Input
{ Keycode.Space, Key.Space },
{ Keycode.PageUp, Key.Prior },
{ Keycode.PageDown, Key.PageDown },
// { Keycode.end?, Key.End },
{ Keycode.Home, Key.Home },
{ Keycode.MoveEnd, Key.End },
{ Keycode.MoveHome, Key.Home },
{ Keycode.DpadLeft, Key.Left },
{ Keycode.DpadUp, Key.Up },
{ Keycode.DpadRight, Key.Right },
@ -37,20 +38,20 @@ namespace Avalonia.Android.Platform.Input
// { Keycode.ButtonSelect?, Key.Select },
// { Keycode.print?, Key.Print },
//{ Keycode.execute?, Key.Execute },
// { Keycode.snap, Key.Snapshot }
//{ Keycode.snap?, Key.Snapshot }
{ Keycode.Insert, Key.Insert },
{ Keycode.ForwardDel, Key.Delete },
//{ Keycode.help, Key.Help },
//{ Keycode.?, Key.D0 }
//{ Keycode.?, Key.D1 }
//{ Keycode.?, Key.D2 }
//{ Keycode.?, Key.D3 }
//{ Keycode.?, Key.D4 }
//{ Keycode.?, Key.D5 }
//{ Keycode.?, Key.D6 }
//{ Keycode.?, Key.D7 }
//{ Keycode.?, Key.D8 }
//{ Keycode.?, Key.D9 }
{ Keycode.Help, Key.Help },
{ Keycode.Num0, Key.D0 },
{ Keycode.Num1, Key.D1 },
{ Keycode.Num2, Key.D2 },
{ Keycode.Num3, Key.D3 },
{ Keycode.Num4, Key.D4 },
{ Keycode.Num5, Key.D5 },
{ Keycode.Num6, Key.D6 },
{ Keycode.Num7, Key.D7 },
{ Keycode.Num8, Key.D8 },
{ Keycode.Num9, Key.D9 },
{ Keycode.A, Key.A },
{ Keycode.B, Key.B },
{ Keycode.C, Key.C },
@ -106,22 +107,22 @@ namespace Avalonia.Android.Platform.Input
//{ Keycode.?, Key.LWin }
//{ Keycode.?, Key.RWin }
//{ Keycode.?, Key.Apps }
//{ Keycode.?, Key.Sleep }
//{ Keycode.?, Key.NumPad0 }
//{ Keycode.?, Key.NumPad1 }
//{ Keycode.?, Key.NumPad2 }
//{ Keycode.?, Key.NumPad3 }
//{ Keycode.?, Key.NumPad4 }
//{ Keycode.?, Key.NumPad5 }
//{ Keycode.?, Key.NumPad6 }
//{ Keycode.?, Key.NumPad7 }
//{ Keycode.?, Key.NumPad8 }
//{ Keycode.?, Key.NumPad9 }
{ Keycode.Sleep, Key.Sleep },
{ Keycode.Numpad0, Key.NumPad0 },
{ Keycode.Numpad1, Key.NumPad1 },
{ Keycode.Numpad2, Key.NumPad2 },
{ Keycode.Numpad3, Key.NumPad3 },
{ Keycode.Numpad4, Key.NumPad4 },
{ Keycode.Numpad5, Key.NumPad5 },
{ Keycode.Numpad6, Key.NumPad6 },
{ Keycode.Numpad7, Key.NumPad7 },
{ Keycode.Numpad8, Key.NumPad8 },
{ Keycode.Numpad9, Key.NumPad9 },
{ Keycode.NumpadMultiply, Key.Multiply },
{ Keycode.NumpadAdd, Key.Add },
{ Keycode.NumpadComma, Key.Separator },
{ Keycode.NumpadSubtract, Key.Subtract },
//{ Keycode.numpaddecimal?, Key.Decimal }
{ Keycode.NumpadDot, Key.Decimal },
{ Keycode.NumpadDivide, Key.Divide },
{ Keycode.F1, Key.F1 },
{ Keycode.F2, Key.F2 },
@ -147,14 +148,14 @@ namespace Avalonia.Android.Platform.Input
//{ Keycode.R2, Key.F22 },
//{ Keycode.F23, Key.F23 },
//{ Keycode.R4, Key.F24 },
// { Keycode.numpad, Key.NumLock }
{ Keycode.NumLock, Key.NumLock },
{ Keycode.ScrollLock, Key.Scroll },
{ Keycode.ShiftLeft, Key.LeftShift },
//{ Keycode.?, Key.RightShift }
//{ Keycode.?, Key.LeftCtrl }
//{ Keycode.?, Key.RightCtrl }
//{ Keycode.?, Key.LeftAlt }
//{ Keycode.?, Key.RightAlt }
{ Keycode.ShiftRight, Key.RightShift },
{ Keycode.CtrlLeft, Key.LeftCtrl },
{ Keycode.CtrlRight, Key.RightCtrl },
{ Keycode.AltLeft, Key.LeftAlt },
{ Keycode.AltRight, Key.RightAlt },
//{ Keycode.?, Key.BrowserBack }
//{ Keycode.?, Key.BrowserForward }
//{ Keycode.?, Key.BrowserRefresh }
@ -163,28 +164,30 @@ namespace Avalonia.Android.Platform.Input
//{ Keycode.?, Key.BrowserFavorites }
//{ Keycode.?, Key.BrowserHome }
//{ Keycode.?, Key.VolumeMute }
//{ Keycode.?, Key.VolumeDown }
//{ Keycode.?, Key.VolumeUp }
//{ Keycode.?, Key.MediaNextTrack }
//{ Keycode.?, Key.MediaPreviousTrack }
//{ Keycode.?, Key.MediaStop }
//{ Keycode.?, Key.MediaPlayPause }
{ Keycode.VolumeDown, Key.VolumeDown },
{ Keycode.VolumeUp, Key.VolumeUp },
{ Keycode.MediaNext, Key.MediaNextTrack },
{ Keycode.MediaPrevious, Key.MediaPreviousTrack },
{ Keycode.MediaStop, Key.MediaStop },
{ Keycode.MediaPlayPause, Key.MediaPlayPause },
//{ Keycode.?, Key.LaunchMail }
//{ Keycode.?, Key.SelectMedia }
//{ Keycode.?, Key.LaunchApplication1 }
//{ Keycode.?, Key.LaunchApplication2 }
//{ Keycode.?, Key.OemSemicolon }
//{ Keycode.?, Key.OemPlus }
//{ Keycode.?, Key.OemComma }
//{ Keycode.?, Key.OemMinus }
//{ Keycode.?, Key.OemPeriod }
{ Keycode.Semicolon, Key.OemSemicolon },
{ Keycode.Plus, Key.OemPlus },
{ Keycode.Comma, Key.OemComma },
{ Keycode.Minus, Key.OemMinus },
{ Keycode.Period, Key.OemPeriod },
//{ Keycode.?, Key.Oem2 }
//{ Keycode.?, Key.OemTilde }
{ Keycode.Grave, Key.OemTilde },
//{ Keycode.?, Key.AbntC1 }
//{ Keycode.?, Key.AbntC2 }
//{ Keycode.?, Key.Oem4 }
//{ Keycode.?, Key.OemPipe }
//{ Keycode.?, Key.OemCloseBrackets }
{ Keycode.Apostrophe, Key.OemQuotes },
{ Keycode.Slash, Key.OemQuestion },
{ Keycode.LeftBracket, Key.OemOpenBrackets },
{ Keycode.RightBracket, Key.OemCloseBrackets },
//{ Keycode.?, Key.Oem7 }
//{ Keycode.?, Key.Oem8 }
//{ Keycode.?, Key.Oem102 }
@ -200,17 +203,18 @@ namespace Avalonia.Android.Platform.Input
//{ Keycode.?, Key.DbeEnterWordRegisterMode }
//{ Keycode.?, Key.DbeEnterImeConfigureMode }
//{ Keycode.?, Key.EraseEof }
//{ Keycode.?, Key.Play }
{ Keycode.MediaPlay, Key.Play },
//{ Keycode.?, Key.Zoom }
//{ Keycode.?, Key.NoName }
//{ Keycode.?, Key.DbeEnterDialogConversionMode }
//{ Keycode.?, Key.OemClear }
//{ Keycode.?, Key.DeadCharProcessed }
{ Keycode.Backslash, Key.OemBackslash }
};
internal static Key ConvertKey(Keycode key) {
Key result;
return KeyDic.TryGetValue(key, out result) ? result : Key.None;
internal static Key ConvertKey(Keycode key)
{
return KeyDic.TryGetValue(key, out var result) ? result : Key.None;
}
}
}
}

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

@ -67,7 +67,7 @@ namespace Avalonia.Animation
}
}
[RequiresUnreferencedCode(TrimmingMessages.TypeConvertionRequiresUnreferencedCodeMessage)]
[RequiresUnreferencedCode(TrimmingMessages.TypeConversionRequiresUnreferencedCodeMessage)]
public T GetTypedValue<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>()
{
var typeConv = TypeDescriptor.GetConverter(typeof(T));

2
src/Avalonia.Base/AvaloniaProperty.cs

@ -476,7 +476,7 @@ namespace Avalonia
/// </summary>
/// <param name="value">The value.</param>
/// <returns>True if the value is valid, otherwise false.</returns>
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConvertionRequiresUnreferencedCodeMessage)]
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConversionRequiresUnreferencedCodeMessage)]
public bool IsValidValue(object? value)
{
return TypeUtilities.TryConvertImplicit(PropertyType, value, out _);

2
src/Avalonia.Base/AvaloniaProperty`1.cs

@ -70,7 +70,7 @@ namespace Avalonia
private protected override IObservable<AvaloniaPropertyChangedEventArgs> GetChanged() => Changed;
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConversionSupressWarningMessage)]
private protected BindingValue<object?> TryConvert(object? value)
{
if (value == UnsetValue)

2
src/Avalonia.Base/Collections/AvaloniaListConverter.cs

@ -9,7 +9,7 @@ namespace Avalonia.Collections
/// <summary>
/// Creates an <see cref="AvaloniaList{T}"/> from a string representation.
/// </summary>
[RequiresUnreferencedCode(TrimmingMessages.TypeConvertionRequiresUnreferencedCodeMessage)]
[RequiresUnreferencedCode(TrimmingMessages.TypeConversionRequiresUnreferencedCodeMessage)]
public class AvaloniaListConverter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T> : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)

4
src/Avalonia.Base/Data/BindingValue.cs

@ -237,7 +237,7 @@ namespace Avalonia.Data
/// </summary>
/// <param name="value">The untyped value.</param>
/// <returns>The typed binding value.</returns>
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConvertionRequiresUnreferencedCodeMessage)]
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConversionRequiresUnreferencedCodeMessage)]
public static BindingValue<T> FromUntyped(object? value)
{
return FromUntyped(value, typeof(T));
@ -251,7 +251,7 @@ namespace Avalonia.Data
/// <param name="value">The untyped value.</param>
/// <param name="targetType">The runtime target type.</param>
/// <returns>The typed binding value.</returns>
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConvertionRequiresUnreferencedCodeMessage)]
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConversionRequiresUnreferencedCodeMessage)]
public static BindingValue<T> FromUntyped(object? value, Type targetType)
{
if (value == AvaloniaProperty.UnsetValue)

2
src/Avalonia.Base/Data/Converters/DefaultValueConverter.cs

@ -10,7 +10,7 @@ namespace Avalonia.Data.Converters
/// Provides a default set of value conversions for bindings that do not specify a value
/// converter.
/// </summary>
[RequiresUnreferencedCode(TrimmingMessages.TypeConvertionRequiresUnreferencedCodeMessage)]
[RequiresUnreferencedCode(TrimmingMessages.TypeConversionRequiresUnreferencedCodeMessage)]
public class DefaultValueConverter : IValueConverter
{
/// <summary>

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

@ -12,7 +12,7 @@ namespace Avalonia.Data.Core
/// Binds to an expression on an object using a type value converter to convert the values
/// that are sent and received.
/// </summary>
[RequiresUnreferencedCode(TrimmingMessages.TypeConvertionRequiresUnreferencedCodeMessage)]
[RequiresUnreferencedCode(TrimmingMessages.TypeConversionRequiresUnreferencedCodeMessage)]
internal class BindingExpression : LightweightObservableBase<object?>, IAvaloniaSubject<object?>, IDescription
{
private readonly ExpressionObserver _inner;

0
src/Markup/Avalonia.Markup/Data/TemplateBinding.cs → src/Avalonia.Base/Data/TemplateBinding.cs

8
src/Avalonia.Base/Diagnostics/TrimmingMessages.cs

@ -2,11 +2,11 @@
internal static class TrimmingMessages
{
public const string ImplicitTypeConvertionSupressWarningMessage = "Implicit convertion methods might be removed by the linker. We don't have a reliable way to prevent it, except converting everything in compile time when possible.";
public const string ImplicitTypeConvertionRequiresUnreferencedCodeMessage = "Implicit convertion methods are required for type conversion.";
public const string ImplicitTypeConversionSupressWarningMessage = "Implicit conversion methods might be removed by the linker. We don't have a reliable way to prevent it, except converting everything in compile time when possible.";
public const string ImplicitTypeConversionRequiresUnreferencedCodeMessage = "Implicit conversion methods are required for type conversion.";
public const string TypeConvertionSupressWarningMessage = "Convertion methods might be removed by the linker. We don't have a reliable way to prevent it, except converting everything in compile time when possible.";
public const string TypeConvertionRequiresUnreferencedCodeMessage = "Convertion methods are required for type conversion, including op_Implicit, op_Explicit, Parse and TypeConverter.";
public const string TypeConversionSupressWarningMessage = "Conversion methods might be removed by the linker. We don't have a reliable way to prevent it, except converting everything in compile time when possible.";
public const string TypeConversionRequiresUnreferencedCodeMessage = "Conversion methods are required for type conversion, including op_Implicit, op_Explicit, Parse and TypeConverter.";
public const string ReflectionBindingRequiresUnreferencedCodeMessage = "BindingExpression and ReflectionBinding heavily use reflection. Consider using CompiledBindings instead.";
public const string ReflectionBindingSupressWarningMessage = "BindingExpression and ReflectionBinding internal heavily use reflection.";

3
src/Avalonia.Base/Input/IAccessKeyHandler.cs

@ -5,8 +5,7 @@ namespace Avalonia.Input
/// <summary>
/// Defines the interface for classes that handle access keys for a window.
/// </summary>
[Unstable]
public interface IAccessKeyHandler
internal interface IAccessKeyHandler
{
/// <summary>
/// Gets or sets the window's main menu.

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

@ -8,11 +8,6 @@ namespace Avalonia.Input
[NotClientImplementable]
public interface IInputRoot : IInputElement
{
/// <summary>
/// Gets or sets the access key handler.
/// </summary>
IAccessKeyHandler AccessKeyHandler { get; }
/// <summary>
/// Gets or sets the keyboard navigation handler.
/// </summary>

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

@ -1,15 +1,12 @@
using System;
using Avalonia.Interactivity;
using Avalonia.Metadata;
using Avalonia.VisualTree;
namespace Avalonia.Input
{
/// <summary>
/// Defines the interface for a window's main menu.
/// </summary>
[NotClientImplementable]
public interface IMainMenu
internal interface IMainMenu
{
/// <summary>
/// Gets a value indicating whether the menu is open.

46
src/Avalonia.Base/Interactivity/RoutedPropertyChangedEventArgs.cs

@ -0,0 +1,46 @@
namespace Avalonia.Interactivity
{
/// <summary>
/// Provides both old and new property values with a routed event.
/// </summary>
/// <typeparam name="T">The type of values.</typeparam>
public class RoutedPropertyChangedEventArgs<T> : RoutedEventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="RoutedPropertyChangedEventArgs{T}"/> class.
/// </summary>
/// <param name="oldValue">The old property value.</param>
/// <param name="newValue">The new property value.</param>
/// <param name="routedEvent">The routed event associated with these event args.</param>
public RoutedPropertyChangedEventArgs(T oldValue, T newValue, RoutedEvent? routedEvent)
: base(routedEvent)
{
OldValue = oldValue;
NewValue = newValue;
}
/// <summary>
/// Initializes a new instance of the <see cref="RoutedPropertyChangedEventArgs{T}"/> class.
/// </summary>
/// <param name="oldValue">The old property value.</param>
/// <param name="newValue">The new property value.</param>
/// <param name="routedEvent">The routed event associated with these event args.</param>
/// <param name="source">The source object that raised the routed event.</param>
public RoutedPropertyChangedEventArgs(T oldValue, T newValue, RoutedEvent? routedEvent, object? source)
: base(routedEvent, source)
{
OldValue = oldValue;
NewValue = newValue;
}
/// <summary>
/// Gets the old value of the property.
/// </summary>
public T OldValue { get; init; }
/// <summary>
/// Gets the new value of the property.
/// </summary>
public T NewValue { get; init; }
}
}

1
src/Avalonia.Base/Properties/AssemblyInfo.cs

@ -6,6 +6,7 @@ using Avalonia.Metadata;
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Animation")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Animation.Easings")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Data")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Data.Converters")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Input")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Input.GestureRecognizers")]

2
src/Avalonia.Base/PropertyStore/DirectUntypedBindingObserver.cs

@ -5,7 +5,7 @@ using Avalonia.Threading;
namespace Avalonia.PropertyStore
{
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConversionSupressWarningMessage)]
internal class DirectUntypedBindingObserver<T> : IObserver<object?>,
IDisposable
{

2
src/Avalonia.Base/PropertyStore/LocalValueBindingObserver.cs

@ -14,7 +14,7 @@ namespace Avalonia.PropertyStore
public void Start(IObservable<object?> source) => _subscription = source.Subscribe(this);
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConversionSupressWarningMessage)]
public void OnNext(object? value)
{
if (value == BindingOperations.DoNothing)

4
src/Avalonia.Base/PropertyStore/UntypedValueUtils.cs

@ -7,7 +7,7 @@ namespace Avalonia.PropertyStore
{
internal static class UntypedValueUtils
{
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConversionSupressWarningMessage)]
public static BindingValue<T> ConvertAndValidate<T>(
object? value,
Type targetType,
@ -24,7 +24,7 @@ namespace Avalonia.PropertyStore
return v;
}
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConversionSupressWarningMessage)]
public static bool TryConvertAndValidate<T>(
StyledProperty<T> property,
object? value,

2
src/Avalonia.Base/StyledProperty.cs

@ -221,7 +221,7 @@ namespace Avalonia
return target.Bind<TValue>(this, source, priority);
}
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConversionSupressWarningMessage)]
private bool ShouldSetValue(AvaloniaObject target, object? value, [NotNullWhen(true)] out TValue? converted)
{
if (value == BindingOperations.DoNothing)

4
src/Avalonia.Base/Styling/PropertyEqualsSelector.cs

@ -91,8 +91,8 @@ namespace Avalonia.Styling
private protected override Selector? MovePrevious() => _previous;
private protected override Selector? MovePreviousOrParent() => _previous;
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.TypeConvertionSupressWarningMessage)]
[UnconditionalSuppressMessage("Trimming", "IL2067", Justification = TrimmingMessages.TypeConvertionSupressWarningMessage)]
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.TypeConversionSupressWarningMessage)]
[UnconditionalSuppressMessage("Trimming", "IL2067", Justification = TrimmingMessages.TypeConversionSupressWarningMessage)]
internal static bool Compare(Type propertyType, object? propertyValue, object? value)
{
if (propertyType == typeof(object) &&

2
src/Avalonia.Base/Styling/Setter.cs

@ -65,7 +65,7 @@ namespace Avalonia.Styling
void IValueEntry.Unsubscribe() { }
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConversionSupressWarningMessage)]
internal override ISetterInstance Instance(IStyleInstance instance, StyledElement target)
{
if (target is not AvaloniaObject ao)

10
src/Avalonia.Base/Utilities/TypeUtilities.cs

@ -126,7 +126,7 @@ namespace Avalonia.Utilities
/// <param name="culture">The culture to use.</param>
/// <param name="result">If successful, contains the convert value.</param>
/// <returns>True if the cast was successful, otherwise false.</returns>
[RequiresUnreferencedCode(TrimmingMessages.TypeConvertionRequiresUnreferencedCodeMessage)]
[RequiresUnreferencedCode(TrimmingMessages.TypeConversionRequiresUnreferencedCodeMessage)]
public static bool TryConvert(Type to, object? value, CultureInfo? culture, out object? result)
{
if (value == null)
@ -246,7 +246,7 @@ namespace Avalonia.Utilities
/// <param name="value">The value to convert.</param>
/// <param name="result">If successful, contains the converted value.</param>
/// <returns>True if the convert was successful, otherwise false.</returns>
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConvertionRequiresUnreferencedCodeMessage)]
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConversionRequiresUnreferencedCodeMessage)]
public static bool TryConvertImplicit(Type to, object? value, out object? result)
{
if (value == null)
@ -309,7 +309,7 @@ namespace Avalonia.Utilities
/// <param name="type">The type to convert to..</param>
/// <param name="culture">The culture to use.</param>
/// <returns>A value of <paramref name="type"/>.</returns>
[RequiresUnreferencedCode(TrimmingMessages.TypeConvertionRequiresUnreferencedCodeMessage)]
[RequiresUnreferencedCode(TrimmingMessages.TypeConversionRequiresUnreferencedCodeMessage)]
public static object? ConvertOrDefault(object? value, Type type, CultureInfo culture)
{
return TryConvert(type, value, culture, out var result) ? result : Default(type);
@ -322,13 +322,13 @@ namespace Avalonia.Utilities
/// <param name="value">The value to convert.</param>
/// <param name="type">The type to convert to.</param>
/// <returns>A value of <paramref name="type"/>.</returns>
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConvertionRequiresUnreferencedCodeMessage)]
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConversionRequiresUnreferencedCodeMessage)]
public static object? ConvertImplicitOrDefault(object? value, Type type)
{
return TryConvertImplicit(type, value, out var result) ? result : Default(type);
}
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConvertionRequiresUnreferencedCodeMessage)]
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConversionRequiresUnreferencedCodeMessage)]
public static T ConvertImplicit<T>(object? value)
{
if (TryConvertImplicit(typeof(T), value, out var result))

2
src/Avalonia.Base/Visual.cs

@ -774,7 +774,7 @@ namespace Avalonia
/// Computes the <see cref="HasMirrorTransform"/> value according to the
/// <see cref="FlowDirection"/> and <see cref="BypassFlowDirectionPolicies"/>
/// </summary>
public virtual void InvalidateMirrorTransform()
protected internal virtual void InvalidateMirrorTransform()
{
var flowDirection = this.FlowDirection;
var parentFlowDirection = FlowDirection.LeftToRight;

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

@ -98,10 +98,10 @@ namespace Avalonia.Controls.Primitives
int pixelWidth;
int pixelHeight;
if (base._track != null)
if (base.Track != null)
{
pixelWidth = Convert.ToInt32(base._track.Bounds.Width * scale);
pixelHeight = Convert.ToInt32(base._track.Bounds.Height * scale);
pixelWidth = Convert.ToInt32(base.Track.Bounds.Width * scale);
pixelHeight = Convert.ToInt32(base.Track.Bounds.Height * scale);
}
else
{

2
src/Avalonia.Controls/Avalonia.Controls.csproj

@ -14,6 +14,7 @@
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Controls.ItemsRepeater, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Controls.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Markup.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.DesignerSupport, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Diagnostics, PublicKey=$(AvaloniaPublicKey)"/>
<InternalsVisibleTo Include="Avalonia.LeakTests, PublicKey=$(AvaloniaPublicKey)" />
@ -22,5 +23,6 @@
<InternalsVisibleTo Include="Avalonia.X11, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.DesignerSupport.Remote, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Browser, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7" />
</ItemGroup>
</Project>

4
src/Avalonia.Controls/Button.cs

@ -34,8 +34,8 @@ namespace Avalonia.Controls
[PseudoClasses(pcFlyoutOpen, pcPressed)]
public class Button : ContentControl, ICommandSource, IClickableControl
{
protected const string pcPressed = ":pressed";
protected const string pcFlyoutOpen = ":flyout-open";
private const string pcPressed = ":pressed";
private const string pcFlyoutOpen = ":flyout-open";
/// <summary>
/// Defines the <see cref="ClickMode"/> property.

4
src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.cs

@ -26,8 +26,8 @@ namespace Avalonia.Controls
[PseudoClasses(pcFlyoutOpen, pcPressed)]
public partial class CalendarDatePicker : TemplatedControl
{
protected const string pcPressed = ":pressed";
protected const string pcFlyoutOpen = ":flyout-open";
private const string pcPressed = ":pressed";
private const string pcFlyoutOpen = ":flyout-open";
private const string ElementTextBox = "PART_TextBox";
private const string ElementButton = "PART_Button";

7
src/Avalonia.Controls/ComboBox.cs

@ -21,8 +21,9 @@ namespace Avalonia.Controls
[PseudoClasses(pcDropdownOpen, pcPressed)]
public class ComboBox : SelectingItemsControl
{
public const string pcDropdownOpen = ":dropdownopen";
public const string pcPressed = ":pressed";
internal const string pcDropdownOpen = ":dropdownopen";
internal const string pcPressed = ":pressed";
/// <summary>
/// The default value for the <see cref="ItemsControl.ItemsPanel"/> property.
/// </summary>
@ -164,7 +165,7 @@ namespace Avalonia.Controls
UpdateSelectionBoxItem(SelectedItem);
}
public override void InvalidateMirrorTransform()
protected internal override void InvalidateMirrorTransform()
{
base.InvalidateMirrorTransform();
UpdateFlowDirection();

11
src/Avalonia.Controls/ContentControl.cs

@ -116,19 +116,14 @@ namespace Avalonia.Controls
return false;
}
protected virtual void ContentChanged(AvaloniaPropertyChangedEventArgs e)
private void ContentChanged(AvaloniaPropertyChangedEventArgs e)
{
UpdateLogicalTree(e.OldValue, e.NewValue);
}
protected void UpdateLogicalTree(object? toRemove, object? toAdd)
{
if (toRemove is ILogical oldChild)
if (e.OldValue is ILogical oldChild)
{
LogicalChildren.Remove(oldChild);
}
if (toAdd is ILogical newChild)
if (e.NewValue is ILogical newChild)
{
LogicalChildren.Add(newChild);
}

3
src/Avalonia.Controls/IContentControl.cs

@ -8,8 +8,7 @@ namespace Avalonia.Controls
/// Defines a control that displays <see cref="Content"/> according to a
/// <see cref="Avalonia.Controls.Templates.FuncDataTemplate"/>.
/// </summary>
[NotClientImplementable]
public interface IContentControl
internal interface IContentControl
{
/// <summary>
/// Gets or sets the content to display.

2
src/Avalonia.Controls/IHeadered.cs

@ -3,7 +3,7 @@ namespace Avalonia.Controls
/// <summary>
/// Defines a headered object.
/// </summary>
public interface IHeadered
internal interface IHeadered
{
/// <summary>
/// Gets or set the header.

3
src/Avalonia.Controls/IMenu.cs

@ -8,8 +8,7 @@ namespace Avalonia.Controls
/// <summary>
/// Represents a <see cref="Menu"/> or <see cref="ContextMenu"/>.
/// </summary>
[NotClientImplementable]
public interface IMenu : IMenuElement, IInputElement
internal interface IMenu : IMenuElement, IInputElement
{
/// <summary>
/// Gets the menu interaction handler.

3
src/Avalonia.Controls/IMenuElement.cs

@ -8,8 +8,7 @@ namespace Avalonia.Controls
/// <summary>
/// Represents an <see cref="IMenu"/> or <see cref="IMenuItem"/>.
/// </summary>
[NotClientImplementable]
public interface IMenuElement : IInputElement, ILogical
internal interface IMenuElement : IInputElement, ILogical
{
/// <summary>
/// Gets or sets the currently selected submenu item.

3
src/Avalonia.Controls/IMenuItem.cs

@ -5,8 +5,7 @@ namespace Avalonia.Controls
/// <summary>
/// Represents a <see cref="MenuItem"/>.
/// </summary>
[NotClientImplementable]
public interface IMenuItem : IMenuElement
internal interface IMenuItem : IMenuElement
{
/// <summary>
/// Gets or sets a value that indicates whether the item has a submenu.

2
src/Avalonia.Controls/INativeMenuExporterEventsImplBridge.cs

@ -2,7 +2,7 @@ using Avalonia.Metadata;
namespace Avalonia.Controls
{
[Unstable]
[PrivateApi]
public interface INativeMenuExporterEventsImplBridge
{
void RaiseNeedsUpdate ();

2
src/Avalonia.Controls/Menu.cs

@ -87,7 +87,7 @@ namespace Avalonia.Controls
{
base.OnAttachedToVisualTree(e);
var inputRoot = e.Root as IInputRoot;
var inputRoot = e.Root as TopLevel;
if (inputRoot?.AccessKeyHandler != null)
{

2
src/Avalonia.Controls/MenuItemAccessKeyHandler.cs

@ -9,7 +9,7 @@ namespace Avalonia.Controls
/// <summary>
/// Handles access keys within a <see cref="MenuItem"/>
/// </summary>
public class MenuItemAccessKeyHandler : IAccessKeyHandler
internal class MenuItemAccessKeyHandler : IAccessKeyHandler
{
/// <summary>
/// The registered access keys.

2
src/Avalonia.Controls/Panel.cs

@ -213,7 +213,7 @@ namespace Avalonia.Controls
}
/// <inheritdoc />
public bool TryGetTotalCount(out int count)
bool IChildIndexProvider.TryGetTotalCount(out int count)
{
count = Children.Count;
return true;

459
src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs

@ -39,91 +39,20 @@ namespace Avalonia.Controls.Platform
DelayRun = delayRun;
}
public virtual void Attach(IMenu menu)
{
if (Menu != null)
{
throw new NotSupportedException("DefaultMenuInteractionHandler is already attached.");
}
Menu = menu;
Menu.GotFocus += GotFocus;
Menu.LostFocus += LostFocus;
Menu.KeyDown += KeyDown;
Menu.PointerPressed += PointerPressed;
Menu.PointerReleased += PointerReleased;
Menu.AddHandler(AccessKeyHandler.AccessKeyPressedEvent, AccessKeyPressed);
Menu.AddHandler(MenuBase.MenuOpenedEvent, MenuOpened);
Menu.AddHandler(MenuItem.PointerEnteredItemEvent, PointerEntered);
Menu.AddHandler(MenuItem.PointerExitedItemEvent, PointerExited);
Menu.AddHandler(InputElement.PointerMovedEvent, PointerMoved);
_root = Menu.VisualRoot;
if (_root is InputElement inputRoot)
{
inputRoot.AddHandler(InputElement.PointerPressedEvent, RootPointerPressed, RoutingStrategies.Tunnel);
}
if (_root is WindowBase window)
{
window.Deactivated += WindowDeactivated;
}
if (_root is TopLevel tl && tl.PlatformImpl is ITopLevelImpl pimpl)
pimpl.LostFocus += TopLevelLostPlatformFocus;
_inputManagerSubscription = InputManager?.Process.Subscribe(RawInput);
}
public virtual void Detach(IMenu menu)
{
if (Menu != menu)
{
throw new NotSupportedException("DefaultMenuInteractionHandler is not attached to the menu.");
}
Menu.GotFocus -= GotFocus;
Menu.LostFocus -= LostFocus;
Menu.KeyDown -= KeyDown;
Menu.PointerPressed -= PointerPressed;
Menu.PointerReleased -= PointerReleased;
Menu.RemoveHandler(AccessKeyHandler.AccessKeyPressedEvent, AccessKeyPressed);
Menu.RemoveHandler(MenuBase.MenuOpenedEvent, MenuOpened);
Menu.RemoveHandler(MenuItem.PointerEnteredItemEvent, PointerEntered);
Menu.RemoveHandler(MenuItem.PointerExitedItemEvent, PointerExited);
Menu.RemoveHandler(InputElement.PointerMovedEvent, PointerMoved);
if (_root is InputElement inputRoot)
{
inputRoot.RemoveHandler(InputElement.PointerPressedEvent, RootPointerPressed);
}
if (_root is WindowBase root)
{
root.Deactivated -= WindowDeactivated;
}
if (_root is TopLevel tl && tl.PlatformImpl != null)
tl.PlatformImpl.LostFocus -= TopLevelLostPlatformFocus;
_inputManagerSubscription?.Dispose();
Menu = null;
_root = null;
}
public void Attach(MenuBase menu) => AttachCore(menu);
public void Detach(MenuBase menu) => DetachCore(menu);
protected Action<Action, TimeSpan> DelayRun { get; }
protected IInputManager? InputManager { get; }
protected IMenu? Menu { get; private set; }
internal IMenu? Menu { get; private set; }
protected static TimeSpan MenuShowDelay { get; } = TimeSpan.FromMilliseconds(400);
protected internal virtual void GotFocus(object? sender, GotFocusEventArgs e)
{
var item = GetMenuItem(e.Source as Control);
var item = GetMenuItemCore(e.Source as Control);
if (item?.Parent != null)
{
@ -133,7 +62,7 @@ namespace Avalonia.Controls.Platform
protected internal virtual void LostFocus(object? sender, RoutedEventArgs e)
{
var item = GetMenuItem(e.Source as Control);
var item = GetMenuItemCore(e.Source as Control);
if (item != null)
{
@ -143,146 +72,12 @@ namespace Avalonia.Controls.Platform
protected internal virtual void KeyDown(object? sender, KeyEventArgs e)
{
KeyDown(GetMenuItem(e.Source as Control), e);
}
protected internal virtual void KeyDown(IMenuItem? item, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Up:
case Key.Down:
{
if (item?.IsTopLevel == true && item.HasSubMenu)
{
if (!item.IsSubMenuOpen)
{
Open(item, true);
}
else
{
item.MoveSelection(NavigationDirection.First, true);
}
e.Handled = true;
}
else
{
goto default;
}
break;
}
case Key.Left:
{
if (item is { IsSubMenuOpen: true, SelectedItem: null })
{
item.Close();
}
else if (item?.Parent is IMenuItem { IsTopLevel: false, IsSubMenuOpen: true } parent)
{
parent.Close();
parent.Focus();
e.Handled = true;
}
else
{
goto default;
}
break;
}
case Key.Right:
{
if (item != null && !item.IsTopLevel && item.HasSubMenu)
{
Open(item, true);
e.Handled = true;
}
else
{
goto default;
}
break;
}
case Key.Enter:
{
if (item != null)
{
if (!item.HasSubMenu)
{
Click(item);
}
else
{
Open(item, true);
}
e.Handled = true;
}
break;
}
case Key.Escape:
{
if (item?.Parent is IMenuElement parent)
{
parent.Close();
parent.Focus();
}
else
{
Menu!.Close();
}
e.Handled = true;
break;
}
default:
{
var direction = e.Key.ToNavigationDirection();
if (direction?.IsDirectional() == true)
{
if (item == null && _isContextMenu)
{
if (Menu!.MoveSelection(direction.Value, true) == true)
{
e.Handled = true;
}
}
else if (item?.Parent?.MoveSelection(direction.Value, true) == true)
{
// If the the parent is an IMenu which successfully moved its selection,
// and the current menu is open then close the current menu and open the
// new menu.
if (item.IsSubMenuOpen &&
item.Parent is IMenu &&
item.Parent.SelectedItem is object &&
item.Parent.SelectedItem != item)
{
item.Close();
Open(item.Parent.SelectedItem, true);
}
e.Handled = true;
}
}
break;
}
}
if (!e.Handled && item?.Parent is IMenuItem parentItem)
{
KeyDown(parentItem, e);
}
KeyDown(GetMenuItemCore(e.Source as Control), e);
}
protected internal virtual void AccessKeyPressed(object? sender, RoutedEventArgs e)
{
var item = GetMenuItem(e.Source as Control);
var item = GetMenuItemCore(e.Source as Control);
if (item == null)
{
@ -303,7 +98,7 @@ namespace Avalonia.Controls.Platform
protected internal virtual void PointerEntered(object? sender, RoutedEventArgs e)
{
var item = GetMenuItem(e.Source as Control);
var item = GetMenuItemCore(e.Source as Control);
if (item?.Parent == null)
{
@ -349,7 +144,7 @@ namespace Avalonia.Controls.Platform
protected internal virtual void PointerMoved(object? sender, PointerEventArgs e)
{
// HACK: #8179 needs to be addressed to correctly implement it in the PointerPressed method.
var item = GetMenuItem(e.Source as Control) as MenuItem;
var item = GetMenuItemCore(e.Source as Control) as MenuItem;
if (item == null)
return;
@ -370,7 +165,7 @@ namespace Avalonia.Controls.Platform
protected internal virtual void PointerExited(object? sender, RoutedEventArgs e)
{
var item = GetMenuItem(e.Source as Control);
var item = GetMenuItemCore(e.Source as Control);
if (item?.Parent == null)
{
@ -405,7 +200,7 @@ namespace Avalonia.Controls.Platform
protected internal virtual void PointerPressed(object? sender, PointerPressedEventArgs e)
{
var item = GetMenuItem(e.Source as Control);
var item = GetMenuItemCore(e.Source as Control);
if (sender is Visual visual &&
e.GetCurrentPoint(visual).Properties.IsLeftButtonPressed && item?.HasSubMenu == true)
@ -436,7 +231,7 @@ namespace Avalonia.Controls.Platform
protected internal virtual void PointerReleased(object? sender, PointerReleasedEventArgs e)
{
var item = GetMenuItem(e.Source as Control);
var item = GetMenuItemCore(e.Source as Control);
if (e.InitialPressMouseButton == MouseButton.Left && item?.HasSubMenu == false)
{
@ -478,13 +273,84 @@ namespace Avalonia.Controls.Platform
{
Menu?.Close();
}
private void TopLevelLostPlatformFocus()
internal static MenuItem? GetMenuItem(StyledElement? item) => (MenuItem?)GetMenuItemCore(item);
internal void AttachCore(IMenu menu)
{
Menu?.Close();
if (Menu != null)
{
throw new NotSupportedException("DefaultMenuInteractionHandler is already attached.");
}
Menu = menu;
Menu.GotFocus += GotFocus;
Menu.LostFocus += LostFocus;
Menu.KeyDown += KeyDown;
Menu.PointerPressed += PointerPressed;
Menu.PointerReleased += PointerReleased;
Menu.AddHandler(AccessKeyHandler.AccessKeyPressedEvent, AccessKeyPressed);
Menu.AddHandler(MenuBase.MenuOpenedEvent, MenuOpened);
Menu.AddHandler(MenuItem.PointerEnteredItemEvent, PointerEntered);
Menu.AddHandler(MenuItem.PointerExitedItemEvent, PointerExited);
Menu.AddHandler(InputElement.PointerMovedEvent, PointerMoved);
_root = Menu.VisualRoot;
if (_root is InputElement inputRoot)
{
inputRoot.AddHandler(InputElement.PointerPressedEvent, RootPointerPressed, RoutingStrategies.Tunnel);
}
if (_root is WindowBase window)
{
window.Deactivated += WindowDeactivated;
}
if (_root is TopLevel tl && tl.PlatformImpl is ITopLevelImpl pimpl)
pimpl.LostFocus += TopLevelLostPlatformFocus;
_inputManagerSubscription = InputManager?.Process.Subscribe(RawInput);
}
protected void Click(IMenuItem item)
internal void DetachCore(IMenu menu)
{
if (Menu != menu)
{
throw new NotSupportedException("DefaultMenuInteractionHandler is not attached to the menu.");
}
Menu.GotFocus -= GotFocus;
Menu.LostFocus -= LostFocus;
Menu.KeyDown -= KeyDown;
Menu.PointerPressed -= PointerPressed;
Menu.PointerReleased -= PointerReleased;
Menu.RemoveHandler(AccessKeyHandler.AccessKeyPressedEvent, AccessKeyPressed);
Menu.RemoveHandler(MenuBase.MenuOpenedEvent, MenuOpened);
Menu.RemoveHandler(MenuItem.PointerEnteredItemEvent, PointerEntered);
Menu.RemoveHandler(MenuItem.PointerExitedItemEvent, PointerExited);
Menu.RemoveHandler(InputElement.PointerMovedEvent, PointerMoved);
if (_root is InputElement inputRoot)
{
inputRoot.RemoveHandler(InputElement.PointerPressedEvent, RootPointerPressed);
}
if (_root is WindowBase root)
{
root.Deactivated -= WindowDeactivated;
}
if (_root is TopLevel tl && tl.PlatformImpl != null)
tl.PlatformImpl.LostFocus -= TopLevelLostPlatformFocus;
_inputManagerSubscription?.Dispose();
Menu = null;
_root = null;
}
internal void Click(IMenuItem item)
{
item.RaiseClick();
@ -494,7 +360,7 @@ namespace Avalonia.Controls.Platform
}
}
protected void CloseMenu(IMenuItem item)
internal void CloseMenu(IMenuItem item)
{
var current = (IMenuElement?)item;
@ -506,7 +372,7 @@ namespace Avalonia.Controls.Platform
current?.Close();
}
protected void CloseWithDelay(IMenuItem item)
internal void CloseWithDelay(IMenuItem item)
{
void Execute()
{
@ -519,7 +385,141 @@ namespace Avalonia.Controls.Platform
DelayRun(Execute, MenuShowDelay);
}
protected void Open(IMenuItem item, bool selectFirst)
internal void KeyDown(IMenuItem? item, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Up:
case Key.Down:
{
if (item?.IsTopLevel == true && item.HasSubMenu)
{
if (!item.IsSubMenuOpen)
{
Open(item, true);
}
else
{
item.MoveSelection(NavigationDirection.First, true);
}
e.Handled = true;
}
else
{
goto default;
}
break;
}
case Key.Left:
{
if (item is { IsSubMenuOpen: true, SelectedItem: null })
{
item.Close();
}
else if (item?.Parent is IMenuItem { IsTopLevel: false, IsSubMenuOpen: true } parent)
{
parent.Close();
parent.Focus();
e.Handled = true;
}
else
{
goto default;
}
break;
}
case Key.Right:
{
if (item != null && !item.IsTopLevel && item.HasSubMenu)
{
Open(item, true);
e.Handled = true;
}
else
{
goto default;
}
break;
}
case Key.Enter:
{
if (item != null)
{
if (!item.HasSubMenu)
{
Click(item);
}
else
{
Open(item, true);
}
e.Handled = true;
}
break;
}
case Key.Escape:
{
if (item?.Parent is IMenuElement parent)
{
parent.Close();
parent.Focus();
}
else
{
Menu!.Close();
}
e.Handled = true;
break;
}
default:
{
var direction = e.Key.ToNavigationDirection();
if (direction?.IsDirectional() == true)
{
if (item == null && _isContextMenu)
{
if (Menu!.MoveSelection(direction.Value, true) == true)
{
e.Handled = true;
}
}
else if (item?.Parent?.MoveSelection(direction.Value, true) == true)
{
// If the the parent is an IMenu which successfully moved its selection,
// and the current menu is open then close the current menu and open the
// new menu.
if (item.IsSubMenuOpen &&
item.Parent is IMenu &&
item.Parent.SelectedItem is object &&
item.Parent.SelectedItem != item)
{
item.Close();
Open(item.Parent.SelectedItem, true);
}
e.Handled = true;
}
}
break;
}
}
if (!e.Handled && item?.Parent is IMenuItem parentItem)
{
KeyDown(parentItem, e);
}
}
internal void Open(IMenuItem item, bool selectFirst)
{
item.Open();
@ -529,7 +529,7 @@ namespace Avalonia.Controls.Platform
}
}
protected void OpenWithDelay(IMenuItem item)
internal void OpenWithDelay(IMenuItem item)
{
void Execute()
{
@ -542,7 +542,7 @@ namespace Avalonia.Controls.Platform
DelayRun(Execute, MenuShowDelay);
}
protected void SelectItemAndAncestors(IMenuItem item)
internal void SelectItemAndAncestors(IMenuItem item)
{
var current = (IMenuItem?)item;
@ -553,7 +553,7 @@ namespace Avalonia.Controls.Platform
}
}
protected static IMenuItem? GetMenuItem(StyledElement? item)
internal static IMenuItem? GetMenuItemCore(StyledElement? item)
{
while (true)
{
@ -565,6 +565,11 @@ namespace Avalonia.Controls.Platform
}
}
private void TopLevelLostPlatformFocus()
{
Menu?.Close();
}
private static void DefaultDelayRun(Action action, TimeSpan timeSpan)
{
DispatcherTimer.RunOnce(action, timeSpan);

58
src/Avalonia.Controls/Platform/ExportAvaloniaModuleAttribute.cs

@ -1,58 +0,0 @@
using System;
namespace Avalonia.Platform
{
/// <summary>
/// Defines an "Avalonia Module", a 3rd party extension to Avalonia that can be automatically initialized by an AppBuilder instance.
/// </summary>
/// <remarks>
/// Avalonia Modules can either be platform independent (ex default control styles provider) or dependent on a
/// specific windowing or rendering subsystem being used (ex native rendering speedup, subsystem-specific interop backends).
/// In the case of a subsystem-specific module, you can specify multiple module implementations, and also a fallback
/// platform-independent module if you so choose. Additionally, these different implementations can be in different assemblies.
/// They just need to all share the same module name.
///
/// For example, if I had a module Foo that has a special back-end for Skia and a less performant/less user friendly back-end for
/// any other rendering subsystem, I would do the following:
/// <code>
/// // In assembly FooModuleSkia.dll
/// [assembly:ExportAvaloniaModule("Foo", typeof(FooModuleSkia), ForRenderingSubsystem="Skia")]
///
/// class FooModuleSkia
/// {
/// public FooModuleSkia()
/// {
/// InitializeModule();
/// }
/// }
///
/// // In assembly FooModuleFallback.dll
/// [assembly:ExportAvaloniaModule("Foo", typeof(FooModuleFallback))]
///
/// class FooModuleFallback
/// {
/// public FooModuleFallback()
/// {
/// InitializeModule();
/// }
/// }
///
/// </code>
/// The fallback module will only be initialized if the Skia-specific module is not applicable.
/// </remarks>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ExportAvaloniaModuleAttribute : Attribute
{
public ExportAvaloniaModuleAttribute(string name, Type moduleType)
{
Name = name;
ModuleType = moduleType;
}
public string Name { get; private set; }
public Type ModuleType { get; private set; }
public string ForWindowingSubsystem { get; set; } = "";
public string ForRenderingSubsystem { get; set; } = "";
}
}

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

@ -12,11 +12,11 @@ namespace Avalonia.Controls.Platform
/// Attaches the interaction handler to a menu.
/// </summary>
/// <param name="menu">The menu.</param>
void Attach(IMenu menu);
void Attach(MenuBase menu);
/// <summary>
/// Detaches the interaction handler from the attached menu.
/// </summary>
void Detach(IMenu menu);
void Detach(MenuBase menu);
}
}

11
src/Avalonia.Controls/Presenters/ContentPresenter.cs

@ -540,17 +540,6 @@ namespace Avalonia.Controls.Presenters
BoxShadow);
}
/// <summary>
/// Creates the child control.
/// </summary>
/// <returns>The child control or null.</returns>
protected virtual Control? CreateChild()
{
var content = Content;
var oldChild = Child;
return CreateChild(content, oldChild, ContentTemplate);
}
private Control? CreateChild(object? content, Control? oldChild, IDataTemplate? template)
{
var newChild = content as Control;

5
src/Avalonia.Controls/Presenters/IContentPresenterHost.cs

@ -1,7 +1,5 @@
using Avalonia.Collections;
using Avalonia.LogicalTree;
using Avalonia.Metadata;
using Avalonia.Styling;
namespace Avalonia.Controls.Presenters
{
@ -16,8 +14,7 @@ namespace Avalonia.Controls.Presenters
/// parent control's template is instantiated so they register themselves using this
/// interface.
/// </remarks>
[NotClientImplementable]
public interface IContentPresenterHost
internal interface IContentPresenterHost
{
/// <summary>
/// Gets a collection describing the logical children of the host control.

2
src/Avalonia.Controls/Primitives/AccessText.cs

@ -86,7 +86,7 @@ namespace Avalonia.Controls.Primitives
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
_accessKeys = (e.Root as IInputRoot)?.AccessKeyHandler;
_accessKeys = (e.Root as TopLevel)?.AccessKeyHandler;
if (_accessKeys != null && AccessKey != 0)
{

37
src/Avalonia.Controls/Primitives/RangeBase.cs

@ -1,5 +1,6 @@
using System;
using Avalonia.Data;
using Avalonia.Interactivity;
using Avalonia.Utilities;
namespace Avalonia.Controls.Primitives
@ -42,7 +43,23 @@ namespace Avalonia.Controls.Primitives
AvaloniaProperty.Register<RangeBase, double>(nameof(LargeChange), 10);
/// <summary>
/// Gets or sets the minimum value.
/// Defines the <see cref="ValueChanged"/> event.
/// </summary>
public static readonly RoutedEvent<RoutedPropertyChangedEventArgs<double>> ValueChangedEvent =
RoutedEvent.Register<RangeBase, RoutedPropertyChangedEventArgs<double>>(
nameof(ValueChanged), RoutingStrategies.Bubble);
/// <summary>
/// Occurs when the <see cref="Value"/> property changes.
/// </summary>
public event EventHandler<RoutedPropertyChangedEventArgs<double>>? ValueChanged
{
add => AddHandler(ValueChangedEvent, value);
remove => RemoveHandler(ValueChangedEvent, value);
}
/// <summary>
/// Gets or sets the minimum possible value.
/// </summary>
public double Minimum
{
@ -65,7 +82,7 @@ namespace Avalonia.Controls.Primitives
}
/// <summary>
/// Gets or sets the maximum value.
/// Gets or sets the maximum possible value.
/// </summary>
public double Maximum
{
@ -104,18 +121,25 @@ namespace Avalonia.Controls.Primitives
: sender.GetValue(ValueProperty);
}
/// <summary>
/// Gets or sets the small increment value added or subtracted from the <see cref="Value"/>.
/// </summary>
public double SmallChange
{
get => GetValue(SmallChangeProperty);
set => SetValue(SmallChangeProperty, value);
}
/// <summary>
/// Gets or sets the large increment value added or subtracted from the <see cref="Value"/>.
/// </summary>
public double LargeChange
{
get => GetValue(LargeChangeProperty);
set => SetValue(LargeChangeProperty, value);
}
/// <inheritdoc/>
protected override void OnInitialized()
{
base.OnInitialized();
@ -124,6 +148,7 @@ namespace Avalonia.Controls.Primitives
CoerceValue(ValueProperty);
}
/// <inheritdoc/>
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
@ -136,6 +161,14 @@ namespace Avalonia.Controls.Primitives
{
OnMaximumChanged();
}
else if (change.Property == ValueProperty)
{
var valueChangedEventArgs = new RoutedPropertyChangedEventArgs<double>(
change.GetOldValue<double>(),
change.GetNewValue<double>(),
ValueChangedEvent);
RaiseEvent(valueChangedEventArgs);
}
}
/// <summary>

18
src/Avalonia.Controls/Slider.cs

@ -86,10 +86,10 @@ namespace Avalonia.Controls
TickBar.TicksProperty.AddOwner<Slider>();
// Slider required parts
protected bool _isDragging;
protected Track? _track;
protected Button? _decreaseButton;
protected Button? _increaseButton;
private bool _isDragging;
private Track? _track;
private Button? _decreaseButton;
private Button? _increaseButton;
private IDisposable? _decreaseButtonPressDispose;
private IDisposable? _decreaseButtonReleaseDispose;
private IDisposable? _increaseButtonSubscription;
@ -181,6 +181,16 @@ namespace Avalonia.Controls
set { SetValue(TickPlacementProperty, value); }
}
/// <summary>
/// Gets a value indicating whether the <see cref="Slider"/> is currently being dragged.
/// </summary>
protected bool IsDragging => _isDragging;
/// <summary>
/// Gets the <see cref="Track"/> part of the <see cref="Slider"/>.
/// </summary>
protected Track? Track => _track;
/// <inheritdoc/>
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{

6
src/Avalonia.Controls/SplitButton/SplitButton.cs

@ -18,9 +18,9 @@ namespace Avalonia.Controls
[PseudoClasses(pcFlyoutOpen, pcPressed)]
public class SplitButton : ContentControl, ICommandSource
{
protected const string pcChecked = ":checked";
protected const string pcPressed = ":pressed";
protected const string pcFlyoutOpen = ":flyout-open";
internal const string pcChecked = ":checked";
internal const string pcPressed = ":pressed";
internal const string pcFlyoutOpen = ":flyout-open";
/// <summary>
/// Raised when the user presses the primary part of the <see cref="SplitButton"/>.

18
src/Avalonia.Controls/SplitView/SplitView.cs

@ -22,15 +22,15 @@ namespace Avalonia.Controls
[PseudoClasses(pcLightDismiss)]
public class SplitView : ContentControl
{
protected const string pcOpen = ":open";
protected const string pcClosed = ":closed";
protected const string pcCompactOverlay = ":compactoverlay";
protected const string pcCompactInline = ":compactinline";
protected const string pcOverlay = ":overlay";
protected const string pcInline = ":inline";
protected const string pcLeft = ":left";
protected const string pcRight = ":right";
protected const string pcLightDismiss = ":lightDismiss";
private const string pcOpen = ":open";
private const string pcClosed = ":closed";
private const string pcCompactOverlay = ":compactoverlay";
private const string pcCompactInline = ":compactinline";
private const string pcOverlay = ":overlay";
private const string pcInline = ":inline";
private const string pcLeft = ":left";
private const string pcRight = ":right";
private const string pcLightDismiss = ":lightDismiss";
/// <summary>
/// Defines the <see cref="CompactPaneLength"/> property

6
src/Avalonia.Controls/TextBlock.cs

@ -144,8 +144,8 @@ namespace Avalonia.Controls
AvaloniaProperty.RegisterDirect<TextBlock, InlineCollection?>(
nameof(Inlines), t => t.Inlines, (t, v) => t.Inlines = v);
protected TextLayout? _textLayout;
protected Size _constraint;
private TextLayout? _textLayout;
private Size _constraint;
private IReadOnlyList<TextRun>? _textRuns;
private InlineCollection? _inlines;
@ -829,7 +829,7 @@ namespace Avalonia.Controls
InvalidateTextLayout();
}
protected readonly record struct SimpleTextSource : ITextSource
private readonly record struct SimpleTextSource : ITextSource
{
private readonly string _text;
private readonly TextRunProperties _defaultProperties;

2
src/Avalonia.Controls/TextBox.cs

@ -1017,7 +1017,7 @@ namespace Avalonia.Controls
}
}
public string? RemoveInvalidCharacters(string? text)
private string? RemoveInvalidCharacters(string? text)
{
if (text is null)
return null;

2
src/Avalonia.Controls/ToggleSwitch.cs

@ -241,7 +241,7 @@ namespace Avalonia.Controls
}
}
protected void UpdateKnobPos(bool value)
private void UpdateKnobPos(bool value)
{
if ((_switchKnob != null) && (_knobsPanel != null))
{

25
src/Avalonia.Controls/TopLevel.cs

@ -375,7 +375,16 @@ namespace Avalonia.Controls
/// Gets the platform-specific window implementation.
/// </summary>
public ITopLevelImpl? PlatformImpl { get; private set; }
/// <summary>
/// Trys to get the platform handle for the TopLevel-derived control.
/// </summary>
/// <returns>
/// An <see cref="IPlatformHandle"/> describing the window handle, or null if the handle
/// could not be retrieved.
/// </returns>
public IPlatformHandle? TryGetPlatformHandle() => ((IWindowBaseImpl?) PlatformImpl)?.Handle;
/// <summary>
/// Gets the renderer for the window.
/// </summary>
@ -386,7 +395,7 @@ namespace Avalonia.Controls
/// <summary>
/// Gets the access key handler for the window.
/// </summary>
IAccessKeyHandler IInputRoot.AccessKeyHandler => _accessKeyHandler!;
internal IAccessKeyHandler AccessKeyHandler => _accessKeyHandler!;
/// <summary>
/// Gets or sets the keyboard navigation handler for the window.
@ -523,13 +532,13 @@ namespace Avalonia.Controls
/// <summary>
/// Creates the layout manager for this <see cref="TopLevel" />.
/// </summary>
protected virtual ILayoutManager CreateLayoutManager() => new LayoutManager(this);
private protected virtual ILayoutManager CreateLayoutManager() => new LayoutManager(this);
/// <summary>
/// Handles a paint notification from <see cref="ITopLevelImpl.Resized"/>.
/// </summary>
/// <param name="rect">The dirty area.</param>
protected virtual void HandlePaint(Rect rect)
private void HandlePaint(Rect rect)
{
Renderer.Paint(rect);
}
@ -537,7 +546,7 @@ namespace Avalonia.Controls
/// <summary>
/// Handles a closed notification from <see cref="ITopLevelImpl.Closed"/>.
/// </summary>
protected virtual void HandleClosed()
private protected virtual void HandleClosed()
{
Renderer.SceneInvalidated -= SceneInvalidated;
// We need to wait for the renderer to complete any in-flight operations
@ -595,7 +604,7 @@ namespace Avalonia.Controls
/// <see cref="ITopLevelImpl.ScalingChanged"/>.
/// </summary>
/// <param name="scaling">The window scaling.</param>
protected virtual void HandleScalingChanged(double scaling)
private void HandleScalingChanged(double scaling)
{
LayoutHelper.InvalidateSelfAndChildrenMeasure(this);
ScalingChanged?.Invoke(this, EventArgs.Empty);
@ -615,7 +624,7 @@ namespace Avalonia.Controls
return false;
}
protected virtual void HandleTransparencyLevelChanged(WindowTransparencyLevel transparencyLevel)
private void HandleTransparencyLevelChanged(WindowTransparencyLevel transparencyLevel)
{
if(_transparencyFallbackBorder != null)
{
@ -740,7 +749,7 @@ namespace Avalonia.Controls
protected override bool BypassFlowDirectionPolicies => true;
public override void InvalidateMirrorTransform()
protected internal override void InvalidateMirrorTransform()
{
// Do nothing becuase TopLevel should't apply MirrorTransform on himself.
}

4
src/Avalonia.Controls/Window.cs

@ -535,7 +535,7 @@ namespace Avalonia.Controls
return true;
}
protected virtual void HandleWindowStateChanged(WindowState state)
private void HandleWindowStateChanged(WindowState state)
{
WindowState = state;
@ -979,7 +979,7 @@ namespace Avalonia.Controls
return ClientSize;
}
protected sealed override void HandleClosed()
private protected sealed override void HandleClosed()
{
RaiseEvent(new RoutedEventArgs(WindowClosedEvent));

12
src/Avalonia.Controls/WindowBase.cs

@ -60,7 +60,7 @@ namespace Avalonia.Controls
impl.PositionChanged = HandlePositionChanged;
}
protected IDisposable FreezeVisibilityChangeHandling()
private protected IDisposable FreezeVisibilityChangeHandling()
{
return new IgnoreVisibilityChangesDisposable(this);
}
@ -178,14 +178,6 @@ namespace Avalonia.Controls
}
}
/// <summary>
/// Trys to get the platform handle for the window.
/// </summary>
/// <returns>
/// An <see cref="IPlatformHandle"/> describing the window handle, or null if the handle
/// could not be retrieved.
/// </returns>
public IPlatformHandle? TryGetPlatformHandle() => PlatformImpl?.Handle;
/// <summary>
/// Ensures that the window is initialized.
@ -226,7 +218,7 @@ namespace Avalonia.Controls
/// <param name="e">An <see cref="EventArgs"/> that contains the event data.</param>
protected virtual void OnResized(WindowResizedEventArgs e) => Resized?.Invoke(this, e);
protected override void HandleClosed()
private protected override void HandleClosed()
{
using (FreezeVisibilityChangeHandling())
{

2
src/Avalonia.Diagnostics/Diagnostics/Models/ConsoleContext.cs

@ -4,7 +4,7 @@ using Avalonia.Diagnostics.ViewModels;
namespace Avalonia.Diagnostics.Models
{
public class ConsoleContext
internal class ConsoleContext
{
private readonly ConsoleViewModel _owner;

2
src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj

@ -71,6 +71,8 @@
<Import Project="..\..\..\build\NullableEnable.props" />
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Designer.HostApp, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.DesignerSupport, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Markup.Xaml.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
</ItemGroup>
</Project>

2
src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs

@ -9,7 +9,7 @@ namespace Avalonia.Markup.Xaml
/// </summary>
public static class AvaloniaXamlLoader
{
public interface IRuntimeXamlLoader
internal interface IRuntimeXamlLoader
{
object Load(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration);
}

2
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CompiledBindingPath.cs

@ -173,7 +173,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
public CompiledBindingPath Build() => new CompiledBindingPath(_elements.ToArray(), _rawSource);
}
public interface ICompiledBindingPathElement
internal interface ICompiledBindingPathElement
{
}

6
src/Markup/Avalonia.Markup/Avalonia.Markup.csproj

@ -19,7 +19,13 @@
<Import Project="..\..\..\build\TrimmingEnable.props" />
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Base.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Benchmarks, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Controls.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Designer.HostApp, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Markup.Xaml, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Markup.Xaml.Loader, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Markup.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Markup.Xaml.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
</ItemGroup>
</Project>

4
src/Markup/Avalonia.Markup/Data/BindingBase.cs

@ -76,7 +76,7 @@ namespace Avalonia.Data
bool enableDataValidation);
/// <inheritdoc/>
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.TypeConvertionSupressWarningMessage)]
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.TypeConversionSupressWarningMessage)]
public InstancedBinding? Initiate(
AvaloniaObject target,
AvaloniaProperty? targetProperty,
@ -234,7 +234,7 @@ namespace Avalonia.Data
return result;
}
protected IObservable<object?> GetParentDataContext(AvaloniaObject target)
private IObservable<object?> GetParentDataContext(AvaloniaObject target)
{
// The DataContext is based on the visual parent and not the logical parent: this may
// seem counter intuitive considering the fact that property inheritance works on the logical

2
src/Markup/Avalonia.Markup/Markup/Data/DelayedBinding.cs

@ -18,7 +18,7 @@ namespace Avalonia.Markup.Data
/// is applied to the property before the properties on the `Binding` object are set. Looking
/// at WPF it uses a similar mechanism for bindings that come from XAML.
/// </remarks>
public static class DelayedBinding
internal static class DelayedBinding
{
private static readonly ConditionalWeakTable<StyledElement, List<Entry>> _entries = new();

5
src/Markup/Avalonia.Markup/Markup/Parsers/ArgumentListParser.cs

@ -4,10 +4,7 @@ using Avalonia.Utilities;
namespace Avalonia.Markup.Parsers
{
#if !BUILDTASK
public
#endif
static class ArgumentListParser
internal static class ArgumentListParser
{
public static IList<string> ParseArguments(this ref CharacterReader r, char open, char close, char delimiter = ',')
{

5
src/Markup/Avalonia.Markup/Markup/Parsers/PropertyPathGrammar.cs

@ -7,10 +7,7 @@ using Avalonia.Utilities;
namespace Avalonia.Markup.Parsers
{
#if !BUILDTASK
public
#endif
class PropertyPathGrammar
internal class PropertyPathGrammar
{
private enum State
{

2
src/Markup/Avalonia.Markup/Markup/Parsers/SelectorParser.cs

@ -11,7 +11,7 @@ namespace Avalonia.Markup.Parsers
/// <summary>
/// Parses a <see cref="Selector"/> from text.
/// </summary>
public class SelectorParser
internal class SelectorParser
{
private readonly Func<string, string, Type> _typeResolver;

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

@ -1004,7 +1004,7 @@ namespace Avalonia.Controls.UnitTests
_layoutManager = layoutManager ?? new LayoutManager(this);
}
protected override ILayoutManager CreateLayoutManager() => _layoutManager;
private protected override ILayoutManager CreateLayoutManager() => _layoutManager;
}
private static Mock<ITopLevelImpl> CreateMockTopLevelImpl()

2
tests/Avalonia.Controls.UnitTests/Platform/DefaultMenuInteractionHandlerTests.cs

@ -554,7 +554,7 @@ namespace Avalonia.Controls.UnitTests.Platform
var contextMenu = Mock.Of<IMenu>(x => x.MoveSelection(NavigationDirection.Down, true) == true);
var e = new KeyEventArgs { Key = Key.Down, Source = contextMenu };
target.Attach(contextMenu);
target.AttachCore(contextMenu);
target.KeyDown(contextMenu, e);
Mock.Get(contextMenu).Verify(x => x.MoveSelection(NavigationDirection.Down, true));

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

@ -1208,7 +1208,7 @@ namespace Avalonia.Controls.UnitTests
_layoutManager = layoutManager ?? new LayoutManager(this);
}
protected override ILayoutManager CreateLayoutManager() => _layoutManager;
private protected override ILayoutManager CreateLayoutManager() => _layoutManager;
}
private static Mock<ITopLevelImpl> CreateMockTopLevelImpl()

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

@ -339,7 +339,7 @@ namespace Avalonia.Controls.UnitTests
_layoutManager = layoutManager ?? new LayoutManager(this);
}
protected override ILayoutManager CreateLayoutManager() => _layoutManager;
private protected override ILayoutManager CreateLayoutManager() => _layoutManager;
}
}
}

2
tests/Avalonia.Markup.Xaml.UnitTests/XamlTestBase.cs

@ -13,7 +13,7 @@ namespace Avalonia.Markup.Xaml.UnitTests
public XamlTestBase()
{
// Ensure necessary assemblies are loaded.
var _ = typeof(TemplateBinding);
var _ = typeof(Binding);
GC.KeepAlive(typeof(ItemsRepeater));
if (AvaloniaLocator.Current.GetService<AvaloniaXamlLoader.IRuntimeXamlLoader>() == null)
AvaloniaLocator.CurrentMutable.Bind<AvaloniaXamlLoader.IRuntimeXamlLoader>()

2
tests/Avalonia.UnitTests/TestRoot.cs

@ -51,8 +51,6 @@ namespace Avalonia.UnitTests
public IRenderer Renderer { get; set; }
public IAccessKeyHandler AccessKeyHandler => null;
public IKeyboardNavigationHandler KeyboardNavigationHandler => null;
public IFocusManager FocusManager => AvaloniaLocator.Current.GetService<IFocusManager>();

Loading…
Cancel
Save