Browse Source

Merge branch 'master' into fixes/3094-focusable-hang

pull/3096/head
danwalmsley 7 years ago
committed by GitHub
parent
commit
15ea7ed1d2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      native/Avalonia.Native/src/OSX/menu.mm
  2. 1
      native/Avalonia.Native/src/OSX/window.h
  3. 11
      native/Avalonia.Native/src/OSX/window.mm
  4. 8
      samples/ControlCatalog/DecoratedWindow.xaml.cs
  5. 9
      src/Avalonia.Base/AvaloniaObjectExtensions.cs
  6. 50
      src/Avalonia.Controls.DataGrid/DataGrid.cs
  7. 4
      src/Avalonia.Controls.DataGrid/DataGridCell.cs
  8. 4
      src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
  9. 8
      src/Avalonia.Controls.DataGrid/DataGridRow.cs
  10. 4
      src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs
  11. 18
      src/Avalonia.Controls/AutoCompleteBox.cs
  12. 2
      src/Avalonia.Controls/Button.cs
  13. 25
      src/Avalonia.Controls/Calendar/Calendar.cs
  14. 2
      src/Avalonia.Controls/Calendar/CalendarButton.cs
  15. 2
      src/Avalonia.Controls/Calendar/CalendarDayButton.cs
  16. 16
      src/Avalonia.Controls/Calendar/DatePicker.cs
  17. 12
      src/Avalonia.Controls/Carousel.cs
  18. 4
      src/Avalonia.Controls/ComboBox.cs
  19. 2
      src/Avalonia.Controls/ContentControl.cs
  20. 2
      src/Avalonia.Controls/ContextMenu.cs
  21. 2
      src/Avalonia.Controls/DataValidationErrors.cs
  22. 2
      src/Avalonia.Controls/Decorator.cs
  23. 2
      src/Avalonia.Controls/Expander.cs
  24. 4
      src/Avalonia.Controls/ItemsControl.cs
  25. 8
      src/Avalonia.Controls/LayoutTransformControl.cs
  26. 2
      src/Avalonia.Controls/MenuBase.cs
  27. 16
      src/Avalonia.Controls/MenuItem.cs
  28. 2
      src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs
  29. 13
      src/Avalonia.Controls/Platform/IWindowImpl.cs
  30. 4
      src/Avalonia.Controls/Presenters/CarouselPresenter.cs
  31. 6
      src/Avalonia.Controls/Presenters/ContentPresenter.cs
  32. 2
      src/Avalonia.Controls/Presenters/ItemsPresenter.cs
  33. 2
      src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs
  34. 6
      src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs
  35. 2
      src/Avalonia.Controls/Primitives/HeaderedContentControl.cs
  36. 2
      src/Avalonia.Controls/Primitives/HeaderedItemsControl.cs
  37. 2
      src/Avalonia.Controls/Primitives/HeaderedSelectingItemsControl.cs
  38. 4
      src/Avalonia.Controls/Primitives/Popup.cs
  39. 2
      src/Avalonia.Controls/Primitives/PopupRoot.cs
  40. 4
      src/Avalonia.Controls/Primitives/ScrollBar.cs
  41. 6
      src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
  42. 2
      src/Avalonia.Controls/Primitives/TemplatedControl.cs
  43. 6
      src/Avalonia.Controls/Primitives/Thumb.cs
  44. 6
      src/Avalonia.Controls/Primitives/Track.cs
  45. 5
      src/Avalonia.Controls/Primitives/UniformGrid.cs
  46. 5
      src/Avalonia.Controls/ProgressBar.cs
  47. 4
      src/Avalonia.Controls/RepeatButton.cs
  48. 4
      src/Avalonia.Controls/ScrollViewer.cs
  49. 6
      src/Avalonia.Controls/Slider.cs
  50. 2
      src/Avalonia.Controls/TabControl.cs
  51. 4
      src/Avalonia.Controls/TabItem.cs
  52. 8
      src/Avalonia.Controls/TopLevel.cs
  53. 2
      src/Avalonia.Controls/TreeViewItem.cs
  54. 2
      src/Avalonia.Controls/Utils/SelectingItemsControlSelectionAdapter.cs
  55. 8
      src/Avalonia.Controls/Window.cs
  56. 2
      src/Avalonia.Controls/WindowBase.cs
  57. 5
      src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
  58. 14
      src/Avalonia.DesignerSupport/Remote/Stubs.cs
  59. 2
      src/Avalonia.Input/Gestures.cs
  60. 24
      src/Avalonia.Input/InputElement.cs
  61. 5
      src/Avalonia.Input/MouseDevice.cs
  62. 29
      src/Avalonia.Input/PointerEventArgs.cs
  63. 25
      src/Avalonia.Input/PointerPoint.cs
  64. 2
      src/Avalonia.Input/TouchDevice.cs
  65. 30
      src/Avalonia.Interactivity/RoutedEvent.cs
  66. 142
      src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
  67. 4
      src/Avalonia.Native/WindowImplBase.cs
  68. 2
      src/Avalonia.Styling/StyledElement.cs
  69. 2
      src/Avalonia.Visuals/Media/Geometry.cs
  70. 4
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
  71. 2
      src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs
  72. 12
      src/Avalonia.X11/X11Window.cs
  73. 5
      src/Windows/Avalonia.Win32/WindowImpl.cs
  74. 4
      tests/Avalonia.Controls.UnitTests/Platform/DefaultMenuInteractionHandlerTests.cs
  75. 2
      tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs
  76. 3
      tests/Avalonia.UnitTests/MouseTestHelper.cs
  77. 53
      tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs
  78. 19
      tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/VisualNodeTests.cs

4
native/Avalonia.Native/src/OSX/menu.mm

@ -1,6 +1,7 @@
#include "common.h"
#include "menu.h"
#include "window.h"
@implementation AvnMenu
@end
@ -283,7 +284,8 @@ extern void SetAppMenu (NSString* appName, IAvnAppMenu* menu)
auto quitItem = [[NSMenuItem alloc] init];
quitItem.title = [@"Quit " stringByAppendingString:appName];
quitItem.keyEquivalent = @"q";
quitItem.action = @selector(terminate:);
quitItem.target = [AvnWindow class];
quitItem.action = @selector(closeAll);
[appMenu addItem:quitItem];
}
else

1
native/Avalonia.Native/src/OSX/window.h

@ -15,6 +15,7 @@ class WindowBaseImpl;
@end
@interface AvnWindow : NSWindow <NSWindowDelegate>
+(void) closeAll;
-(AvnWindow* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent;
-(void) setCanBecomeKeyAndMain;
-(void) pollModalSession: (NSModalSession _Nonnull) session;

11
native/Avalonia.Native/src/OSX/window.mm

@ -1076,6 +1076,17 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
bool _isAppMenuApplied;
}
+(void)closeAll
{
NSArray<NSWindow*>* windows = [NSArray arrayWithArray:[NSApp windows]];
auto numWindows = [windows count];
for(int i = 0; i < numWindows; i++)
{
[[windows objectAtIndex:i] performClose:nil];
}
}
- (void)dealloc
{
}

8
samples/ControlCatalog/DecoratedWindow.xaml.cs

@ -18,18 +18,18 @@ namespace ControlCatalog
{
var ctl = this.FindControl<Control>(name);
ctl.Cursor = new Cursor(cursor);
ctl.PointerPressed += delegate
ctl.PointerPressed += (i, e) =>
{
PlatformImpl?.BeginResizeDrag(edge);
PlatformImpl?.BeginResizeDrag(edge, e);
};
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
this.FindControl<Control>("TitleBar").PointerPressed += delegate
this.FindControl<Control>("TitleBar").PointerPressed += (i, e) =>
{
PlatformImpl?.BeginMoveDrag();
PlatformImpl?.BeginMoveDrag(e);
};
SetupSide("Left", StandardCursorType.LeftSide, WindowEdge.West);
SetupSide("Right", StandardCursorType.RightSide, WindowEdge.East);

9
src/Avalonia.Base/AvaloniaObjectExtensions.cs

@ -192,9 +192,9 @@ namespace Avalonia
{
return observable.Subscribe(e =>
{
if (e.Sender is TTarget)
if (e.Sender is TTarget target)
{
action((TTarget)e.Sender, e);
action(target, e);
}
});
}
@ -207,6 +207,7 @@ namespace Avalonia
/// <param name="observable">The property changed observable.</param>
/// <param name="handler">Given a TTarget, returns the handler.</param>
/// <returns>A disposable that can be used to terminate the subscription.</returns>
[Obsolete("Use overload taking Action<TTarget, AvaloniaPropertyChangedEventArgs>.")]
public static IDisposable AddClassHandler<TTarget>(
this IObservable<AvaloniaPropertyChangedEventArgs> observable,
Func<TTarget, Action<AvaloniaPropertyChangedEventArgs>> handler)
@ -238,9 +239,7 @@ namespace Avalonia
Func<TTarget, Action<AvaloniaPropertyChangedEventArgs>> handler)
where TTarget : class
{
var target = e.Sender as TTarget;
if (target != null)
if (e.Sender is TTarget target)
{
handler(target)(e);
}

50
src/Avalonia.Controls.DataGrid/DataGrid.cs

@ -723,29 +723,29 @@ namespace Avalonia.Controls
PseudoClass<DataGrid, bool>(IsValidProperty, x => !x, ":invalid");
ItemsProperty.Changed.AddClassHandler<DataGrid>(x => x.OnItemsPropertyChanged);
CanUserResizeColumnsProperty.Changed.AddClassHandler<DataGrid>(x => x.OnCanUserResizeColumnsChanged);
ColumnWidthProperty.Changed.AddClassHandler<DataGrid>(x => x.OnColumnWidthChanged);
RowBackgroundProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowBackgroundChanged);
AlternatingRowBackgroundProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowBackgroundChanged);
FrozenColumnCountProperty.Changed.AddClassHandler<DataGrid>(x => x.OnFrozenColumnCountChanged);
GridLinesVisibilityProperty.Changed.AddClassHandler<DataGrid>(x => x.OnGridLinesVisibilityChanged);
HeadersVisibilityProperty.Changed.AddClassHandler<DataGrid>(x => x.OnHeadersVisibilityChanged);
HorizontalGridLinesBrushProperty.Changed.AddClassHandler<DataGrid>(x => x.OnHorizontalGridLinesBrushChanged);
IsReadOnlyProperty.Changed.AddClassHandler<DataGrid>(x => x.OnIsReadOnlyChanged);
MaxColumnWidthProperty.Changed.AddClassHandler<DataGrid>(x => x.OnMaxColumnWidthChanged);
MinColumnWidthProperty.Changed.AddClassHandler<DataGrid>(x => x.OnMinColumnWidthChanged);
RowHeightProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowHeightChanged);
RowHeaderWidthProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowHeaderWidthChanged);
SelectionModeProperty.Changed.AddClassHandler<DataGrid>(x => x.OnSelectionModeChanged);
VerticalGridLinesBrushProperty.Changed.AddClassHandler<DataGrid>(x => x.OnVerticalGridLinesBrushChanged);
SelectedIndexProperty.Changed.AddClassHandler<DataGrid>(x => x.OnSelectedIndexChanged);
SelectedItemProperty.Changed.AddClassHandler<DataGrid>(x => x.OnSelectedItemChanged);
IsEnabledProperty.Changed.AddClassHandler<DataGrid>(x => x.DataGrid_IsEnabledChanged);
AreRowGroupHeadersFrozenProperty.Changed.AddClassHandler<DataGrid>(x => x.OnAreRowGroupHeadersFrozenChanged);
RowDetailsTemplateProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowDetailsTemplateChanged);
RowDetailsVisibilityModeProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowDetailsVisibilityModeChanged);
AutoGenerateColumnsProperty.Changed.AddClassHandler<DataGrid>(x => x.OnAutoGenerateColumnsChanged);
ItemsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnItemsPropertyChanged(e));
CanUserResizeColumnsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnCanUserResizeColumnsChanged(e));
ColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnColumnWidthChanged(e));
RowBackgroundProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowBackgroundChanged(e));
AlternatingRowBackgroundProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowBackgroundChanged(e));
FrozenColumnCountProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnFrozenColumnCountChanged(e));
GridLinesVisibilityProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnGridLinesVisibilityChanged(e));
HeadersVisibilityProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnHeadersVisibilityChanged(e));
HorizontalGridLinesBrushProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnHorizontalGridLinesBrushChanged(e));
IsReadOnlyProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnIsReadOnlyChanged(e));
MaxColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnMaxColumnWidthChanged(e));
MinColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnMinColumnWidthChanged(e));
RowHeightProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowHeightChanged(e));
RowHeaderWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowHeaderWidthChanged(e));
SelectionModeProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnSelectionModeChanged(e));
VerticalGridLinesBrushProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnVerticalGridLinesBrushChanged(e));
SelectedIndexProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnSelectedIndexChanged(e));
SelectedItemProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnSelectedItemChanged(e));
IsEnabledProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.DataGrid_IsEnabledChanged(e));
AreRowGroupHeadersFrozenProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnAreRowGroupHeadersFrozenChanged(e));
RowDetailsTemplateProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowDetailsTemplateChanged(e));
RowDetailsVisibilityModeProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowDetailsVisibilityModeChanged(e));
AutoGenerateColumnsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnAutoGenerateColumnsChanged(e));
}
/// <summary>
@ -3533,7 +3533,7 @@ namespace Avalonia.Controls
if (AreColumnHeadersVisible &&
_vScrollBar != null && _vScrollBar.IsVisible)
{
_topRightCornerHeader.IsVisible = true; ;
_topRightCornerHeader.IsVisible = true;
}
else
{
@ -5594,7 +5594,7 @@ namespace Avalonia.Controls
{
// This will trigger a call to this method via Cells_SizeChanged for
// which no processing is needed.
_vScrollBar.IsVisible = true; ;
_vScrollBar.IsVisible = true;
if (_vScrollBar.DesiredSize.Width == 0)
{
// We need to know the width for the rest of layout to work correctly so measure it now

4
src/Avalonia.Controls.DataGrid/DataGridCell.cs

@ -29,7 +29,7 @@ namespace Avalonia.Controls
static DataGridCell()
{
PointerPressedEvent.AddClassHandler<DataGridCell>(
x => x.DataGridCell_PointerPressed, handledEventsToo: true);
(x,e) => x.DataGridCell_PointerPressed(e), handledEventsToo: true);
}
public DataGridCell()
{ }
@ -219,4 +219,4 @@ namespace Avalonia.Controls
}
}
}
}
}

4
src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs

@ -67,7 +67,7 @@ namespace Avalonia.Controls
static DataGridColumnHeader()
{
AreSeparatorsVisibleProperty.Changed.AddClassHandler<DataGridColumnHeader>(x => x.OnAreSeparatorsVisibleChanged);
AreSeparatorsVisibleProperty.Changed.AddClassHandler<DataGridColumnHeader>((x,e) => x.OnAreSeparatorsVisibleChanged(e));
}
/// <summary>
@ -468,7 +468,7 @@ namespace Avalonia.Controls
private void DataGridColumnHeader_PointerReleased(object sender, PointerReleasedEventArgs e)
{
if (OwningColumn == null || e.Handled || !IsEnabled || e.MouseButton != MouseButton.Left)
if (OwningColumn == null || e.Handled || !IsEnabled || e.InitialPressMouseButton != MouseButton.Left)
{
return;
}

8
src/Avalonia.Controls.DataGrid/DataGridRow.cs

@ -116,10 +116,10 @@ namespace Avalonia.Controls
static DataGridRow()
{
HeaderProperty.Changed.AddClassHandler<DataGridRow>(x => x.OnHeaderChanged);
DetailsTemplateProperty.Changed.AddClassHandler<DataGridRow>(x => x.OnDetailsTemplateChanged);
AreDetailsVisibleProperty.Changed.AddClassHandler<DataGridRow>(x => x.OnAreDetailsVisibleChanged);
PointerPressedEvent.AddClassHandler<DataGridRow>(x => x.DataGridRow_PointerPressed, handledEventsToo: true);
HeaderProperty.Changed.AddClassHandler<DataGridRow>((x, e) => x.OnHeaderChanged(e));
DetailsTemplateProperty.Changed.AddClassHandler<DataGridRow>((x, e) => x.OnDetailsTemplateChanged(e));
AreDetailsVisibleProperty.Changed.AddClassHandler<DataGridRow>((x, e) => x.OnAreDetailsVisibleChanged(e));
PointerPressedEvent.AddClassHandler<DataGridRow>((x, e) => x.DataGridRow_PointerPressed(e), handledEventsToo: true);
}
/// <summary>

4
src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs

@ -109,7 +109,7 @@ namespace Avalonia.Controls
static DataGridRowGroupHeader()
{
SublevelIndentProperty.Changed.AddClassHandler<DataGridRowGroupHeader>(x => x.OnSublevelIndentChanged);
SublevelIndentProperty.Changed.AddClassHandler<DataGridRowGroupHeader>((x,e) => x.OnSublevelIndentChanged(e));
}
/// <summary>
@ -446,4 +446,4 @@ namespace Avalonia.Controls
}
}
}
}

18
src/Avalonia.Controls/AutoCompleteBox.cs

@ -805,15 +805,15 @@ namespace Avalonia.Controls
{
FocusableProperty.OverrideDefaultValue<AutoCompleteBox>(true);
MinimumPopulateDelayProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnMinimumPopulateDelayChanged);
IsDropDownOpenProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnIsDropDownOpenChanged);
SelectedItemProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnSelectedItemPropertyChanged);
TextProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnTextPropertyChanged);
SearchTextProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnSearchTextPropertyChanged);
FilterModeProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnFilterModePropertyChanged);
ItemFilterProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnItemFilterPropertyChanged);
ItemsProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnItemsPropertyChanged);
IsEnabledProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnControlIsEnabledChanged);
MinimumPopulateDelayProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnMinimumPopulateDelayChanged(e));
IsDropDownOpenProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnIsDropDownOpenChanged(e));
SelectedItemProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnSelectedItemPropertyChanged(e));
TextProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnTextPropertyChanged(e));
SearchTextProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnSearchTextPropertyChanged(e));
FilterModeProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnFilterModePropertyChanged(e));
ItemFilterProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnItemFilterPropertyChanged(e));
ItemsProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnItemsPropertyChanged(e));
IsEnabledProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnControlIsEnabledChanged(e));
}
/// <summary>

2
src/Avalonia.Controls/Button.cs

@ -294,7 +294,7 @@ namespace Avalonia.Controls
{
base.OnPointerReleased(e);
if (IsPressed && e.MouseButton == MouseButton.Left)
if (IsPressed && e.InitialPressMouseButton == MouseButton.Left)
{
IsPressed = false;
e.Handled = true;

25
src/Avalonia.Controls/Calendar/Calendar.cs

@ -1565,7 +1565,7 @@ namespace Avalonia.Controls
protected override void OnPointerReleased(PointerReleasedEventArgs e)
{
base.OnPointerReleased(e);
if (!HasFocusInternal && e.MouseButton == MouseButton.Left)
if (!HasFocusInternal && e.InitialPressMouseButton == MouseButton.Left)
{
FocusManager.Instance.Focus(this);
}
@ -2057,18 +2057,17 @@ namespace Avalonia.Controls
static Calendar()
{
IsEnabledProperty.Changed.AddClassHandler<Calendar>(x => x.OnIsEnabledChanged);
FirstDayOfWeekProperty.Changed.AddClassHandler<Calendar>(x => x.OnFirstDayOfWeekChanged);
IsTodayHighlightedProperty.Changed.AddClassHandler<Calendar>(x => x.OnIsTodayHighlightedChanged);
DisplayModeProperty.Changed.AddClassHandler<Calendar>(x => x.OnDisplayModePropertyChanged);
SelectionModeProperty.Changed.AddClassHandler<Calendar>(x => x.OnSelectionModeChanged);
SelectedDateProperty.Changed.AddClassHandler<Calendar>(x => x.OnSelectedDateChanged);
DisplayDateProperty.Changed.AddClassHandler<Calendar>(x => x.OnDisplayDateChanged);
DisplayDateStartProperty.Changed.AddClassHandler<Calendar>(x => x.OnDisplayDateStartChanged);
DisplayDateEndProperty.Changed.AddClassHandler<Calendar>(x => x.OnDisplayDateEndChanged);
KeyDownEvent.AddClassHandler<Calendar>(x => x.Calendar_KeyDown);
KeyUpEvent.AddClassHandler<Calendar>(x => x.Calendar_KeyUp);
IsEnabledProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnIsEnabledChanged(e));
FirstDayOfWeekProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnFirstDayOfWeekChanged(e));
IsTodayHighlightedProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnIsTodayHighlightedChanged(e));
DisplayModeProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnDisplayModePropertyChanged(e));
SelectionModeProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnSelectionModeChanged(e));
SelectedDateProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnSelectedDateChanged(e));
DisplayDateProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnDisplayDateChanged(e));
DisplayDateStartProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnDisplayDateStartChanged(e));
DisplayDateEndProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnDisplayDateEndChanged(e));
KeyDownEvent.AddClassHandler<Calendar>((x,e) => x.Calendar_KeyDown(e));
KeyUpEvent.AddClassHandler<Calendar>((x,e) => x.Calendar_KeyUp(e));
}
/// <summary>

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

@ -173,7 +173,7 @@ namespace Avalonia.Controls.Primitives
protected override void OnPointerReleased(PointerReleasedEventArgs e)
{
base.OnPointerReleased(e);
if (e.MouseButton == MouseButton.Left)
if (e.InitialPressMouseButton == MouseButton.Left)
CalendarLeftMouseButtonUp?.Invoke(this, e);
}
}

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

@ -231,7 +231,7 @@ namespace Avalonia.Controls.Primitives
{
base.OnPointerReleased(e);
if (e.MouseButton == MouseButton.Left)
if (e.InitialPressMouseButton == MouseButton.Left)
CalendarDayButtonMouseUp?.Invoke(this, e);
}
}

16
src/Avalonia.Controls/Calendar/DatePicker.cs

@ -393,14 +393,14 @@ namespace Avalonia.Controls
{
FocusableProperty.OverrideDefaultValue<DatePicker>(true);
DisplayDateProperty.Changed.AddClassHandler<DatePicker>(x => x.OnDisplayDateChanged);
DisplayDateStartProperty.Changed.AddClassHandler<DatePicker>(x => x.OnDisplayDateStartChanged);
DisplayDateEndProperty.Changed.AddClassHandler<DatePicker>(x => x.OnDisplayDateEndChanged);
IsDropDownOpenProperty.Changed.AddClassHandler<DatePicker>(x => x.OnIsDropDownOpenChanged);
SelectedDateProperty.Changed.AddClassHandler<DatePicker>(x => x.OnSelectedDateChanged);
SelectedDateFormatProperty.Changed.AddClassHandler<DatePicker>(x => x.OnSelectedDateFormatChanged);
CustomDateFormatStringProperty.Changed.AddClassHandler<DatePicker>(x => x.OnCustomDateFormatStringChanged);
TextProperty.Changed.AddClassHandler<DatePicker>(x => x.OnTextChanged);
DisplayDateProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnDisplayDateChanged(e));
DisplayDateStartProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnDisplayDateStartChanged(e));
DisplayDateEndProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnDisplayDateEndChanged(e));
IsDropDownOpenProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnIsDropDownOpenChanged(e));
SelectedDateProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnSelectedDateChanged(e));
SelectedDateFormatProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnSelectedDateFormatChanged(e));
CustomDateFormatStringProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnCustomDateFormatStringChanged(e));
TextProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnTextChanged(e));
}
/// <summary>
/// Initializes a new instance of the

12
src/Avalonia.Controls/Carousel.cs

@ -84,17 +84,5 @@ namespace Avalonia.Controls
--SelectedIndex;
}
}
/// <inheritdoc/>
protected override void OnKeyDown(KeyEventArgs e)
{
// Ignore key presses.
}
/// <inheritdoc/>
protected override void OnPointerPressed(PointerPressedEventArgs e)
{
// Ignore pointer presses.
}
}
}

4
src/Avalonia.Controls/ComboBox.cs

@ -65,8 +65,8 @@ namespace Avalonia.Controls
{
ItemsPanelProperty.OverrideDefaultValue<ComboBox>(DefaultPanel);
FocusableProperty.OverrideDefaultValue<ComboBox>(true);
SelectedItemProperty.Changed.AddClassHandler<ComboBox>(x => x.SelectedItemChanged);
KeyDownEvent.AddClassHandler<ComboBox>(x => x.OnKeyDown, Interactivity.RoutingStrategies.Tunnel);
SelectedItemProperty.Changed.AddClassHandler<ComboBox>((x,e) => x.SelectedItemChanged(e));
KeyDownEvent.AddClassHandler<ComboBox>((x, e) => x.OnKeyDown(e), Interactivity.RoutingStrategies.Tunnel);
}
/// <summary>

2
src/Avalonia.Controls/ContentControl.cs

@ -43,7 +43,7 @@ namespace Avalonia.Controls
static ContentControl()
{
ContentProperty.Changed.AddClassHandler<ContentControl>(x => x.ContentChanged);
ContentProperty.Changed.AddClassHandler<ContentControl>((x, e) => x.ContentChanged(e));
}
/// <summary>

2
src/Avalonia.Controls/ContextMenu.cs

@ -192,7 +192,7 @@ namespace Avalonia.Controls
e.Handled = true;
}
if (e.MouseButton == MouseButton.Right)
if (e.InitialPressMouseButton == MouseButton.Right)
{
if (contextMenu.CancelOpening())
return;

2
src/Avalonia.Controls/DataValidationErrors.cs

@ -56,7 +56,7 @@ namespace Avalonia.Controls
{
ErrorsProperty.Changed.Subscribe(ErrorsChanged);
HasErrorsProperty.Changed.Subscribe(HasErrorsChanged);
TemplatedParentProperty.Changed.AddClassHandler<DataValidationErrors>(x => x.OnTemplatedParentChange);
TemplatedParentProperty.Changed.AddClassHandler<DataValidationErrors>((x, e) => x.OnTemplatedParentChange(e));
}
private void OnTemplatedParentChange(AvaloniaPropertyChangedEventArgs e)

2
src/Avalonia.Controls/Decorator.cs

@ -29,7 +29,7 @@ namespace Avalonia.Controls
static Decorator()
{
AffectsMeasure<Decorator>(ChildProperty, PaddingProperty);
ChildProperty.Changed.AddClassHandler<Decorator>(x => x.ChildChanged);
ChildProperty.Changed.AddClassHandler<Decorator>((x, e) => x.ChildChanged(e));
}
/// <summary>

2
src/Avalonia.Controls/Expander.cs

@ -37,7 +37,7 @@ namespace Avalonia.Controls
PseudoClass<Expander>(IsExpandedProperty, ":expanded");
IsExpandedProperty.Changed.AddClassHandler<Expander>(x => x.OnIsExpandedChanged);
IsExpandedProperty.Changed.AddClassHandler<Expander>((x, e) => x.OnIsExpandedChanged(e));
}
public IPageTransition ContentTransition

4
src/Avalonia.Controls/ItemsControl.cs

@ -64,8 +64,8 @@ namespace Avalonia.Controls
/// </summary>
static ItemsControl()
{
ItemsProperty.Changed.AddClassHandler<ItemsControl>(x => x.ItemsChanged);
ItemTemplateProperty.Changed.AddClassHandler<ItemsControl>(x => x.ItemTemplateChanged);
ItemsProperty.Changed.AddClassHandler<ItemsControl>((x, e) => x.ItemsChanged(e));
ItemTemplateProperty.Changed.AddClassHandler<ItemsControl>((x, e) => x.ItemTemplateChanged(e));
}
/// <summary>

8
src/Avalonia.Controls/LayoutTransformControl.cs

@ -28,11 +28,13 @@ namespace Avalonia.Controls
ClipToBoundsProperty.OverrideDefaultValue<LayoutTransformControl>(true);
LayoutTransformProperty.Changed
.AddClassHandler<LayoutTransformControl>(x => x.OnLayoutTransformChanged);
.AddClassHandler<LayoutTransformControl>((x, e) => x.OnLayoutTransformChanged(e));
ChildProperty.Changed
.AddClassHandler<LayoutTransformControl>(x => x.OnChildChanged);
UseRenderTransformProperty.Changed.AddClassHandler<LayoutTransformControl>(x => x.OnUseRenderTransformPropertyChanged);
.AddClassHandler<LayoutTransformControl>((x, e) => x.OnChildChanged(e));
UseRenderTransformProperty.Changed
.AddClassHandler<LayoutTransformControl>((x, e) => x.OnUseRenderTransformPropertyChanged(e));
}
/// <summary>

2
src/Avalonia.Controls/MenuBase.cs

@ -64,7 +64,7 @@ namespace Avalonia.Controls
/// </summary>
static MenuBase()
{
MenuItem.SubmenuOpenedEvent.AddClassHandler<MenuBase>(x => x.OnSubmenuOpened);
MenuItem.SubmenuOpenedEvent.AddClassHandler<MenuBase>((x, e) => x.OnSubmenuOpened(e));
}
/// <summary>

16
src/Avalonia.Controls/MenuItem.cs

@ -102,13 +102,13 @@ namespace Avalonia.Controls
SelectableMixin.Attach<MenuItem>(IsSelectedProperty);
CommandProperty.Changed.Subscribe(CommandChanged);
FocusableProperty.OverrideDefaultValue<MenuItem>(true);
HeaderProperty.Changed.AddClassHandler<MenuItem>(x => x.HeaderChanged);
IconProperty.Changed.AddClassHandler<MenuItem>(x => x.IconChanged);
IsSelectedProperty.Changed.AddClassHandler<MenuItem>(x => x.IsSelectedChanged);
HeaderProperty.Changed.AddClassHandler<MenuItem>((x, e) => x.HeaderChanged(e));
IconProperty.Changed.AddClassHandler<MenuItem>((x, e) => x.IconChanged(e));
IsSelectedProperty.Changed.AddClassHandler<MenuItem>((x, e) => x.IsSelectedChanged(e));
ItemsPanelProperty.OverrideDefaultValue<MenuItem>(DefaultPanel);
ClickEvent.AddClassHandler<MenuItem>(x => x.OnClick);
SubmenuOpenedEvent.AddClassHandler<MenuItem>(x => x.OnSubmenuOpened);
IsSubMenuOpenProperty.Changed.AddClassHandler<MenuItem>(x => x.SubMenuOpenChanged);
ClickEvent.AddClassHandler<MenuItem>((x, e) => x.OnClick(e));
SubmenuOpenedEvent.AddClassHandler<MenuItem>((x, e) => x.OnSubmenuOpened(e));
IsSubMenuOpenProperty.Changed.AddClassHandler<MenuItem>((x, e) => x.SubMenuOpenChanged(e));
}
public MenuItem()
@ -337,7 +337,7 @@ namespace Avalonia.Controls
{
base.OnPointerEnter(e);
var point = e.GetPointerPoint(null);
var point = e.GetCurrentPoint(null);
RaiseEvent(new PointerEventArgs(PointerEnterItemEvent, this, e.Pointer, this.VisualRoot, point.Position,
e.Timestamp, point.Properties, e.KeyModifiers));
}
@ -347,7 +347,7 @@ namespace Avalonia.Controls
{
base.OnPointerLeave(e);
var point = e.GetPointerPoint(null);
var point = e.GetCurrentPoint(null);
RaiseEvent(new PointerEventArgs(PointerLeaveItemEvent, this, e.Pointer, this.VisualRoot, point.Position,
e.Timestamp, point.Properties, e.KeyModifiers));
}

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

@ -356,7 +356,7 @@ namespace Avalonia.Controls.Platform
{
var item = GetMenuItem(e.Source as IControl);
if (e.MouseButton == MouseButton.Left && item?.HasSubMenu == false)
if (e.InitialPressMouseButton == MouseButton.Left && item?.HasSubMenu == false)
{
Click(item);
e.Handled = true;

13
src/Avalonia.Controls/Platform/IWindowImpl.cs

@ -3,6 +3,7 @@
using System;
using Avalonia.Controls;
using Avalonia.Input;
namespace Avalonia.Platform
{
@ -57,28 +58,28 @@ namespace Avalonia.Platform
/// Return true to prevent the underlying implementation from closing.
/// </summary>
Func<bool> Closing { get; set; }
/// <summary>
/// Starts moving a window with left button being held. Should be called from left mouse button press event handler.
/// </summary>
void BeginMoveDrag();
void BeginMoveDrag(PointerPressedEventArgs e);
/// <summary>
/// Starts resizing a window. This function is used if an application has window resizing controls.
/// Should be called from left mouse button press event handler
/// </summary>
void BeginResizeDrag(WindowEdge edge);
void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e);
/// <summary>
/// Sets the client size of the top level.
/// </summary>
void Resize(Size clientSize);
/// <summary>
/// Sets the client size of the top level.
/// </summary>
void Move(PixelPoint point);
/// <summary>
/// Minimum width of the window.
/// </summary>

4
src/Avalonia.Controls/Presenters/CarouselPresenter.cs

@ -46,8 +46,8 @@ namespace Avalonia.Controls.Presenters
/// </summary>
static CarouselPresenter()
{
IsVirtualizedProperty.Changed.AddClassHandler<CarouselPresenter>(x => x.IsVirtualizedChanged);
SelectedIndexProperty.Changed.AddClassHandler<CarouselPresenter>(x => x.SelectedIndexChanged);
IsVirtualizedProperty.Changed.AddClassHandler<CarouselPresenter>((x, e) => x.IsVirtualizedChanged(e));
SelectedIndexProperty.Changed.AddClassHandler<CarouselPresenter>((x, e) => x.SelectedIndexChanged(e));
}
/// <summary>

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

@ -94,9 +94,9 @@ namespace Avalonia.Controls.Presenters
{
AffectsRender<ContentPresenter>(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty, CornerRadiusProperty);
AffectsMeasure<ContentPresenter>(BorderThicknessProperty, PaddingProperty);
ContentProperty.Changed.AddClassHandler<ContentPresenter>(x => x.ContentChanged);
ContentTemplateProperty.Changed.AddClassHandler<ContentPresenter>(x => x.ContentChanged);
TemplatedParentProperty.Changed.AddClassHandler<ContentPresenter>(x => x.TemplatedParentChanged);
ContentProperty.Changed.AddClassHandler<ContentPresenter>((x, e) => x.ContentChanged(e));
ContentTemplateProperty.Changed.AddClassHandler<ContentPresenter>((x, e) => x.ContentChanged(e));
TemplatedParentProperty.Changed.AddClassHandler<ContentPresenter>((x, e) => x.TemplatedParentChanged(e));
}
/// <summary>

2
src/Avalonia.Controls/Presenters/ItemsPresenter.cs

@ -35,7 +35,7 @@ namespace Avalonia.Controls.Presenters
KeyboardNavigationMode.Once);
VirtualizationModeProperty.Changed
.AddClassHandler<ItemsPresenter>(x => x.VirtualizationModeChanged);
.AddClassHandler<ItemsPresenter>((x, e) => x.VirtualizationModeChanged(e));
}
/// <summary>

2
src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs

@ -45,7 +45,7 @@ namespace Avalonia.Controls.Presenters
/// </summary>
static ItemsPresenterBase()
{
TemplatedParentProperty.Changed.AddClassHandler<ItemsPresenterBase>(x => x.TemplatedParentChanged);
TemplatedParentProperty.Changed.AddClassHandler<ItemsPresenterBase>((x,e) => x.TemplatedParentChanged(e));
}
/// <summary>

6
src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs

@ -73,7 +73,7 @@ namespace Avalonia.Controls.Presenters
static ScrollContentPresenter()
{
ClipToBoundsProperty.OverrideDefaultValue(typeof(ScrollContentPresenter), true);
ChildProperty.Changed.AddClassHandler<ScrollContentPresenter>(x => x.ChildChanged);
ChildProperty.Changed.AddClassHandler<ScrollContentPresenter>((x, e) => x.ChildChanged(e));
AffectsArrange<ScrollContentPresenter>(OffsetProperty);
}
@ -246,7 +246,7 @@ namespace Avalonia.Controls.Presenters
if (isLogical)
_activeLogicalGestureScrolls?.TryGetValue(e.Id, out delta);
delta += e.Delta;
if (Extent.Height > Viewport.Height)
{
double dy;
@ -293,7 +293,7 @@ namespace Avalonia.Controls.Presenters
}
}
private void OnScrollGestureEnded(object sender, ScrollGestureEndedEventArgs e)
private void OnScrollGestureEnded(object sender, ScrollGestureEndedEventArgs e)
=> _activeLogicalGestureScrolls?.Remove(e.Id);
/// <inheritdoc/>

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

@ -30,7 +30,7 @@ namespace Avalonia.Controls.Primitives
/// </summary>
static HeaderedContentControl()
{
ContentProperty.Changed.AddClassHandler<HeaderedContentControl>(x => x.HeaderChanged);
ContentProperty.Changed.AddClassHandler<HeaderedContentControl>((x, e) => x.HeaderChanged(e));
}
/// <summary>

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

@ -24,7 +24,7 @@ namespace Avalonia.Controls.Primitives
/// </summary>
static HeaderedItemsControl()
{
HeaderProperty.Changed.AddClassHandler<HeaderedItemsControl>(x => x.HeaderChanged);
HeaderProperty.Changed.AddClassHandler<HeaderedItemsControl>((x, e) => x.HeaderChanged(e));
}
/// <summary>

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

@ -24,7 +24,7 @@ namespace Avalonia.Controls.Primitives
/// </summary>
static HeaderedSelectingItemsControl()
{
HeaderProperty.Changed.AddClassHandler<HeaderedSelectingItemsControl>(x => x.HeaderChanged);
HeaderProperty.Changed.AddClassHandler<HeaderedSelectingItemsControl>((x, e) => x.HeaderChanged(e));
}
/// <summary>

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

@ -93,8 +93,8 @@ namespace Avalonia.Controls.Primitives
static Popup()
{
IsHitTestVisibleProperty.OverrideDefaultValue<Popup>(false);
ChildProperty.Changed.AddClassHandler<Popup>(x => x.ChildChanged);
IsOpenProperty.Changed.AddClassHandler<Popup>(x => x.IsOpenChanged);
ChildProperty.Changed.AddClassHandler<Popup>((x, e) => x.ChildChanged(e));
IsOpenProperty.Changed.AddClassHandler<Popup>((x, e) => x.IsOpenChanged(e));
}
public Popup()

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

@ -17,7 +17,7 @@ namespace Avalonia.Controls.Primitives
/// <summary>
/// The root window of a <see cref="Popup"/>.
/// </summary>
public class PopupRoot : WindowBase, IInteractive, IHostedVisualTreeRoot, IDisposable, IStyleHost, IPopupHost
public sealed class PopupRoot : WindowBase, IInteractive, IHostedVisualTreeRoot, IDisposable, IStyleHost, IPopupHost
{
private readonly TopLevel _parent;
private PopupPositionerParameters _positionerParameters;

4
src/Avalonia.Controls/Primitives/ScrollBar.cs

@ -58,8 +58,8 @@ namespace Avalonia.Controls.Primitives
PseudoClass<ScrollBar, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass<ScrollBar, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
Thumb.DragDeltaEvent.AddClassHandler<ScrollBar>(o => o.OnThumbDragDelta, RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<ScrollBar>(o => o.OnThumbDragComplete, RoutingStrategies.Bubble);
Thumb.DragDeltaEvent.AddClassHandler<ScrollBar>((x, e) => x.OnThumbDragDelta(e), RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<ScrollBar>((x, e) => x.OnThumbDragComplete(e), RoutingStrategies.Bubble);
}
/// <summary>

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

@ -119,7 +119,7 @@ namespace Avalonia.Controls.Primitives
/// </summary>
static SelectingItemsControl()
{
IsSelectedChangedEvent.AddClassHandler<SelectingItemsControl>(x => x.ContainerSelectionChanged);
IsSelectedChangedEvent.AddClassHandler<SelectingItemsControl>((x, e) => x.ContainerSelectionChanged(e));
}
/// <summary>
@ -1088,8 +1088,8 @@ namespace Avalonia.Controls.Primitives
}
else
{
SelectedIndex = _updateSelectedIndex != int.MinValue ?
_updateSelectedIndex :
SelectedIndex = _updateSelectedIndex != int.MinValue ?
_updateSelectedIndex :
AlwaysSelected ? 0 : -1;
}
}

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

@ -99,7 +99,7 @@ namespace Avalonia.Controls.Primitives
static TemplatedControl()
{
ClipToBoundsProperty.OverrideDefaultValue<TemplatedControl>(true);
TemplateProperty.Changed.AddClassHandler<TemplatedControl>(x => x.OnTemplateChanged);
TemplateProperty.Changed.AddClassHandler<TemplatedControl>((x, e) => x.OnTemplateChanged(e));
}
/// <summary>

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

@ -22,9 +22,9 @@ namespace Avalonia.Controls.Primitives
static Thumb()
{
DragStartedEvent.AddClassHandler<Thumb>(x => x.OnDragStarted, RoutingStrategies.Bubble);
DragDeltaEvent.AddClassHandler<Thumb>(x => x.OnDragDelta, RoutingStrategies.Bubble);
DragCompletedEvent.AddClassHandler<Thumb>(x => x.OnDragCompleted, RoutingStrategies.Bubble);
DragStartedEvent.AddClassHandler<Thumb>((x,e) => x.OnDragStarted(e), RoutingStrategies.Bubble);
DragDeltaEvent.AddClassHandler<Thumb>((x, e) => x.OnDragDelta(e), RoutingStrategies.Bubble);
DragCompletedEvent.AddClassHandler<Thumb>((x, e) => x.OnDragCompleted(e), RoutingStrategies.Bubble);
}
public event EventHandler<VectorEventArgs> DragStarted

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

@ -48,9 +48,9 @@ namespace Avalonia.Controls.Primitives
{
PseudoClass<Track, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass<Track, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
ThumbProperty.Changed.AddClassHandler<Track>(x => x.ThumbChanged);
IncreaseButtonProperty.Changed.AddClassHandler<Track>(x => x.ButtonChanged);
DecreaseButtonProperty.Changed.AddClassHandler<Track>(x => x.ButtonChanged);
ThumbProperty.Changed.AddClassHandler<Track>((x,e) => x.ThumbChanged(e));
IncreaseButtonProperty.Changed.AddClassHandler<Track>((x, e) => x.ButtonChanged(e));
DecreaseButtonProperty.Changed.AddClassHandler<Track>((x, e) => x.ButtonChanged(e));
AffectsArrange<Track>(MinimumProperty, MaximumProperty, ValueProperty, OrientationProperty);
}

5
src/Avalonia.Controls/Primitives/UniformGrid.cs

@ -28,6 +28,11 @@ namespace Avalonia.Controls.Primitives
private int _rows;
private int _columns;
static UniformGrid()
{
AffectsMeasure<UniformGrid>(RowsProperty, ColumnsProperty, FirstColumnProperty);
}
/// <summary>
/// Specifies the row count. If set to 0, row count will be calculated automatically.
/// </summary>

5
src/Avalonia.Controls/ProgressBar.cs

@ -2,6 +2,7 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using Avalonia.Controls.Primitives;
using Avalonia.Layout;
@ -38,8 +39,8 @@ namespace Avalonia.Controls
PseudoClass<ProgressBar, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
PseudoClass<ProgressBar>(IsIndeterminateProperty, ":indeterminate");
ValueProperty.Changed.AddClassHandler<ProgressBar>(x => x.UpdateIndicatorWhenPropChanged);
IsIndeterminateProperty.Changed.AddClassHandler<ProgressBar>(x => x.UpdateIndicatorWhenPropChanged);
ValueProperty.Changed.AddClassHandler<ProgressBar>((x, e) => x.UpdateIndicatorWhenPropChanged(e));
IsIndeterminateProperty.Changed.AddClassHandler<ProgressBar>((x, e) => x.UpdateIndicatorWhenPropChanged(e));
}
public bool IsIndeterminate

4
src/Avalonia.Controls/RepeatButton.cs

@ -98,10 +98,10 @@ namespace Avalonia.Controls
{
base.OnPointerReleased(e);
if (e.MouseButton == MouseButton.Left)
if (e.InitialPressMouseButton == MouseButton.Left)
{
StopTimer();
}
}
}
}
}

4
src/Avalonia.Controls/ScrollViewer.cs

@ -163,8 +163,8 @@ namespace Avalonia.Controls
{
AffectsValidation(ExtentProperty, OffsetProperty);
AffectsValidation(ViewportProperty, OffsetProperty);
HorizontalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>(x => x.ScrollBarVisibilityChanged);
VerticalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>(x => x.ScrollBarVisibilityChanged);
HorizontalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>((x, e) => x.ScrollBarVisibilityChanged(e));
VerticalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>((x, e) => x.ScrollBarVisibilityChanged(e));
}
/// <summary>

6
src/Avalonia.Controls/Slider.cs

@ -45,9 +45,9 @@ namespace Avalonia.Controls
OrientationProperty.OverrideDefaultValue(typeof(Slider), Orientation.Horizontal);
PseudoClass<Slider, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass<Slider, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
Thumb.DragStartedEvent.AddClassHandler<Slider>(x => x.OnThumbDragStarted, RoutingStrategies.Bubble);
Thumb.DragDeltaEvent.AddClassHandler<Slider>(x => x.OnThumbDragDelta, RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<Slider>(x => x.OnThumbDragCompleted, RoutingStrategies.Bubble);
Thumb.DragStartedEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragStarted(e), RoutingStrategies.Bubble);
Thumb.DragDeltaEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragDelta(e), RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragCompleted(e), RoutingStrategies.Bubble);
}
/// <summary>

2
src/Avalonia.Controls/TabControl.cs

@ -196,7 +196,7 @@ namespace Avalonia.Controls
protected override void OnPointerReleased(PointerReleasedEventArgs e)
{
if (e.MouseButton == MouseButton.Left && e.Pointer.Type != PointerType.Mouse)
if (e.InitialPressMouseButton == MouseButton.Left && e.Pointer.Type != PointerType.Mouse)
{
var container = GetContainerFromEventSource(e.Source);
if (container != null

4
src/Avalonia.Controls/TabItem.cs

@ -30,8 +30,8 @@ namespace Avalonia.Controls
{
SelectableMixin.Attach<TabItem>(IsSelectedProperty);
FocusableProperty.OverrideDefaultValue(typeof(TabItem), true);
IsSelectedProperty.Changed.AddClassHandler<TabItem>(x => x.UpdateSelectedContent);
DataContextProperty.Changed.AddClassHandler<TabItem>(x => x.UpdateHeader);
IsSelectedProperty.Changed.AddClassHandler<TabItem>((x, e) => x.UpdateSelectedContent(e));
DataContextProperty.Changed.AddClassHandler<TabItem>((x, e) => x.UpdateHeader(e));
}
/// <summary>

8
src/Avalonia.Controls/TopLevel.cs

@ -271,7 +271,7 @@ namespace Avalonia.Controls
{
(this as IInputRoot).MouseDevice?.TopLevelClosed(this);
PlatformImpl = null;
Closed?.Invoke(this, EventArgs.Empty);
OnClosed(EventArgs.Empty);
Renderer?.Dispose();
Renderer = null;
}
@ -317,6 +317,12 @@ namespace Avalonia.Controls
/// <param name="e">The event args.</param>
protected virtual void OnOpened(EventArgs e) => Opened?.Invoke(this, e);
/// <summary>
/// Raises the <see cref="Closed"/> event.
/// </summary>
/// <param name="e">The event args.</param>
protected virtual void OnClosed(EventArgs e) => Closed?.Invoke(this, e);
/// <summary>
/// Tries to get a service from an <see cref="IAvaloniaDependencyResolver"/>, logging a
/// warning if not found.

2
src/Avalonia.Controls/TreeViewItem.cs

@ -54,7 +54,7 @@ namespace Avalonia.Controls
SelectableMixin.Attach<TreeViewItem>(IsSelectedProperty);
FocusableProperty.OverrideDefaultValue<TreeViewItem>(true);
ItemsPanelProperty.OverrideDefaultValue<TreeViewItem>(DefaultPanel);
RequestBringIntoViewEvent.AddClassHandler<TreeViewItem>(x => x.OnRequestBringIntoView);
RequestBringIntoViewEvent.AddClassHandler<TreeViewItem>((x, e) => x.OnRequestBringIntoView(e));
}
/// <summary>

2
src/Avalonia.Controls/Utils/SelectingItemsControlSelectionAdapter.cs

@ -178,7 +178,7 @@ namespace Avalonia.Controls.Utils
/// <param name="e">The event data.</param>
private void OnSelectorPointerReleased(object sender, PointerReleasedEventArgs e)
{
if (e.MouseButton == MouseButton.Left)
if (e.InitialPressMouseButton == MouseButton.Left)
{
OnCommit();
}

8
src/Avalonia.Controls/Window.cs

@ -261,13 +261,13 @@ namespace Avalonia.Controls
/// <summary>
/// Starts moving a window with left button being held. Should be called from left mouse button press event handler
/// </summary>
public void BeginMoveDrag() => PlatformImpl?.BeginMoveDrag();
public void BeginMoveDrag(PointerPressedEventArgs e) => PlatformImpl?.BeginMoveDrag(e);
/// <summary>
/// Starts resizing a window. This function is used if an application has window resizing controls.
/// Should be called from left mouse button press event handler
/// </summary>
public void BeginResizeDrag(WindowEdge edge) => PlatformImpl?.BeginResizeDrag(edge);
public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e) => PlatformImpl?.BeginResizeDrag(edge, e);
/// <summary>
/// Carries out the arrange pass of the window.
@ -557,7 +557,7 @@ namespace Avalonia.Controls
return result;
}
protected override void HandleClosed()
protected sealed override void HandleClosed()
{
RaiseEvent(new RoutedEventArgs(WindowClosedEvent));
@ -565,7 +565,7 @@ namespace Avalonia.Controls
}
/// <inheritdoc/>
protected override void HandleResized(Size clientSize)
protected sealed override void HandleResized(Size clientSize)
{
if (!AutoSizing)
{

2
src/Avalonia.Controls/WindowBase.cs

@ -47,7 +47,7 @@ namespace Avalonia.Controls
static WindowBase()
{
IsVisibleProperty.OverrideDefaultValue<WindowBase>(false);
IsVisibleProperty.Changed.AddClassHandler<WindowBase>(x => x.IsVisibleChanged);
IsVisibleProperty.Changed.AddClassHandler<WindowBase>((x,e) => x.IsVisibleChanged(e));
TopmostProperty.Changed.AddClassHandler<WindowBase>((w, e) => w.PlatformImpl?.SetTopmost((bool)e.NewValue));

5
src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs

@ -2,6 +2,7 @@
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Controls.Remote.Server;
using Avalonia.Input;
using Avalonia.Platform;
using Avalonia.Remote.Protocol;
using Avalonia.Remote.Protocol.Viewport;
@ -27,11 +28,11 @@ namespace Avalonia.DesignerSupport.Remote
{
}
public void BeginMoveDrag()
public void BeginMoveDrag(PointerPressedEventArgs e)
{
}
public void BeginResizeDrag(WindowEdge edge)
public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{
}

14
src/Avalonia.DesignerSupport/Remote/Stubs.cs

@ -46,7 +46,7 @@ namespace Avalonia.DesignerSupport.Remote
Resize(size);
}));
}
public IRenderer CreateRenderer(IRenderRoot root) => new ImmediateRenderer(root);
public void Dispose()
{
@ -75,11 +75,11 @@ namespace Avalonia.DesignerSupport.Remote
{
}
public void BeginMoveDrag()
public void BeginMoveDrag(PointerPressedEventArgs e)
{
}
public void BeginResizeDrag(WindowEdge edge)
public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{
}
@ -93,7 +93,7 @@ namespace Avalonia.DesignerSupport.Remote
public void Move(PixelPoint point)
{
}
public IScreenImpl Screen { get; } = new ScreenStub();
@ -153,7 +153,7 @@ namespace Avalonia.DesignerSupport.Remote
{
public void Save(Stream outputStream)
{
}
}
@ -167,10 +167,10 @@ namespace Avalonia.DesignerSupport.Remote
class SystemDialogsStub : ISystemDialogImpl
{
public Task<string[]> ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent) =>
Task.FromResult((string[]) null);
Task.FromResult((string[])null);
public Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent) =>
Task.FromResult((string) null);
Task.FromResult((string)null);
}
class ScreenStub : IScreenImpl

2
src/Avalonia.Input/Gestures.cs

@ -97,7 +97,7 @@ namespace Avalonia.Input
if (s_lastPress.TryGetTarget(out var target) && target == e.Source)
{
var et = e.MouseButton != MouseButton.Right ? TappedEvent : RightTappedEvent;
var et = e.InitialPressMouseButton != MouseButton.Right ? TappedEvent : RightTappedEvent;
e.Source.RaiseEvent(new RoutedEventArgs(et));
}
}

24
src/Avalonia.Input/InputElement.cs

@ -169,18 +169,18 @@ namespace Avalonia.Input
{
IsEnabledProperty.Changed.Subscribe(IsEnabledChanged);
GotFocusEvent.AddClassHandler<InputElement>(x => x.OnGotFocus);
LostFocusEvent.AddClassHandler<InputElement>(x => x.OnLostFocus);
KeyDownEvent.AddClassHandler<InputElement>(x => x.OnKeyDown);
KeyUpEvent.AddClassHandler<InputElement>(x => x.OnKeyUp);
TextInputEvent.AddClassHandler<InputElement>(x => x.OnTextInput);
PointerEnterEvent.AddClassHandler<InputElement>(x => x.OnPointerEnterCore);
PointerLeaveEvent.AddClassHandler<InputElement>(x => x.OnPointerLeaveCore);
PointerMovedEvent.AddClassHandler<InputElement>(x => x.OnPointerMoved);
PointerPressedEvent.AddClassHandler<InputElement>(x => x.OnPointerPressed);
PointerReleasedEvent.AddClassHandler<InputElement>(x => x.OnPointerReleased);
PointerCaptureLostEvent.AddClassHandler<InputElement>(x => x.OnPointerCaptureLost);
PointerWheelChangedEvent.AddClassHandler<InputElement>(x => x.OnPointerWheelChanged);
GotFocusEvent.AddClassHandler<InputElement>((x, e) => x.OnGotFocus(e));
LostFocusEvent.AddClassHandler<InputElement>((x, e) => x.OnLostFocus(e));
KeyDownEvent.AddClassHandler<InputElement>((x, e) => x.OnKeyDown(e));
KeyUpEvent.AddClassHandler<InputElement>((x, e) => x.OnKeyUp(e));
TextInputEvent.AddClassHandler<InputElement>((x, e) => x.OnTextInput(e));
PointerEnterEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerEnterCore(e));
PointerLeaveEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerLeaveCore(e));
PointerMovedEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerMoved(e));
PointerPressedEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerPressed(e));
PointerReleasedEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerReleased(e));
PointerCaptureLostEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerCaptureLost(e));
PointerWheelChangedEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerWheelChanged(e));
PseudoClass<InputElement, bool>(IsEffectivelyEnabledProperty, x => !x, ":disabled");
PseudoClass<InputElement>(IsFocusedProperty, ":focus");

5
src/Avalonia.Input/MouseDevice.cs

@ -221,7 +221,7 @@ namespace Avalonia.Input
_lastClickTime = timestamp;
_lastClickRect = new Rect(p, new Size())
.Inflate(new Thickness(settings.DoubleClickSize.Width / 2, settings.DoubleClickSize.Height / 2));
_lastMouseDownButton = properties.GetObsoleteMouseButton();
_lastMouseDownButton = properties.PointerUpdateKind.GetMouseButton();
var e = new PointerPressedEventArgs(source, _pointer, root, p, timestamp, properties, inputModifiers, _clickCount);
source.RaiseEvent(e);
return e.Handled;
@ -267,7 +267,8 @@ namespace Avalonia.Input
if (hit != null)
{
var source = GetSource(hit);
var e = new PointerReleasedEventArgs(source, _pointer, root, p, timestamp, props, inputModifiers);
var e = new PointerReleasedEventArgs(source, _pointer, root, p, timestamp, props, inputModifiers,
_lastMouseDownButton);
source?.RaiseEvent(e);
_pointer.Capture(null);

29
src/Avalonia.Input/PointerEventArgs.cs

@ -88,9 +88,20 @@ namespace Avalonia.Input
return _rootVisualPosition * _rootVisual.TransformToVisual(relativeTo) ?? default;
}
public PointerPoint GetPointerPoint(IVisual relativeTo)
[Obsolete("Use GetCurrentPoint")]
public PointerPoint GetPointerPoint(IVisual relativeTo) => GetCurrentPoint(relativeTo);
/// <summary>
/// Returns the PointerPoint associated with the current event
/// </summary>
/// <param name="relativeTo">The visual which coordinate system to use. Pass null for toplevel coordinate system</param>
/// <returns></returns>
public PointerPoint GetCurrentPoint(IVisual relativeTo)
=> new PointerPoint(Pointer, GetPosition(relativeTo), _properties);
/// <summary>
/// Returns the current pointer point properties
/// </summary>
protected PointerPointProperties Properties => _properties;
}
@ -124,7 +135,7 @@ namespace Avalonia.Input
public int ClickCount => _obsoleteClickCount;
[Obsolete("Use PointerUpdateKind")]
public MouseButton MouseButton => Properties.GetObsoleteMouseButton();
public MouseButton MouseButton => Properties.PointerUpdateKind.GetMouseButton();
}
public class PointerReleasedEventArgs : PointerEventArgs
@ -132,15 +143,21 @@ namespace Avalonia.Input
public PointerReleasedEventArgs(
IInteractive source, IPointer pointer,
IVisual rootVisual, Point rootVisualPosition, ulong timestamp,
PointerPointProperties properties, KeyModifiers modifiers)
PointerPointProperties properties, KeyModifiers modifiers,
MouseButton initialPressMouseButton)
: base(InputElement.PointerReleasedEvent, source, pointer, rootVisual, rootVisualPosition,
timestamp, properties, modifiers)
{
InitialPressMouseButton = initialPressMouseButton;
}
[Obsolete("Use PointerUpdateKind")]
public MouseButton MouseButton => Properties.GetObsoleteMouseButton();
/// <summary>
/// Gets the mouse button that triggered the corresponding PointerPressed event
/// </summary>
public MouseButton InitialPressMouseButton { get; }
[Obsolete("Either use GetCurrentPoint(this).Properties.PointerUpdateKind or InitialPressMouseButton, see https://github.com/AvaloniaUI/Avalonia/wiki/Pointer-events-in-0.9 for more details", true)]
public MouseButton MouseButton => InitialPressMouseButton;
}
public class PointerCaptureLostEventArgs : RoutedEventArgs

25
src/Avalonia.Input/PointerPoint.cs

@ -49,17 +49,6 @@ namespace Avalonia.Input
}
public static PointerPointProperties None { get; } = new PointerPointProperties();
public MouseButton GetObsoleteMouseButton()
{
if (PointerUpdateKind == PointerUpdateKind.LeftButtonPressed || PointerUpdateKind == PointerUpdateKind.LeftButtonReleased)
return MouseButton.Left;
if (PointerUpdateKind == PointerUpdateKind.MiddleButtonPressed || PointerUpdateKind == PointerUpdateKind.MiddleButtonReleased)
return MouseButton.Middle;
if (PointerUpdateKind == PointerUpdateKind.RightButtonPressed || PointerUpdateKind == PointerUpdateKind.RightButtonReleased)
return MouseButton.Right;
return MouseButton.None;
}
}
public enum PointerUpdateKind
@ -72,4 +61,18 @@ namespace Avalonia.Input
RightButtonReleased,
Other
}
public static class PointerUpdateKindExtensions
{
public static MouseButton GetMouseButton(this PointerUpdateKind kind)
{
if (kind == PointerUpdateKind.LeftButtonPressed || kind == PointerUpdateKind.LeftButtonReleased)
return MouseButton.Left;
if (kind == PointerUpdateKind.MiddleButtonPressed || kind == PointerUpdateKind.MiddleButtonReleased)
return MouseButton.Middle;
if (kind == PointerUpdateKind.RightButtonPressed || kind == PointerUpdateKind.RightButtonReleased)
return MouseButton.Right;
return MouseButton.None;
}
}
}

2
src/Avalonia.Input/TouchDevice.cs

@ -60,7 +60,7 @@ namespace Avalonia.Input
args.Root, args.Position, ev.Timestamp,
new PointerPointProperties(GetModifiers(args.InputModifiers, false),
PointerUpdateKind.LeftButtonReleased),
GetKeyModifiers(args.InputModifiers)));
GetKeyModifiers(args.InputModifiers), MouseButton.Left));
}
}

30
src/Avalonia.Interactivity/RoutedEvent.cs

@ -113,24 +113,38 @@ namespace Avalonia.Interactivity
Contract.Requires<ArgumentNullException>(ownerType != null);
}
[Obsolete("Use overload taking Action<TTarget, TEventArgs>.")]
public IDisposable AddClassHandler<TTarget>(
Func<TTarget, Action<TEventArgs>> handler,
RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble,
bool handledEventsToo = false)
where TTarget : class, IInteractive
where TTarget : class, IInteractive
{
EventHandler<RoutedEventArgs> adapter = (sender, e) =>
void Adapter(object sender, RoutedEventArgs e)
{
var target = sender as TTarget;
var args = e as TEventArgs;
if (target != null && args != null)
if (sender is TTarget target && e is TEventArgs args)
{
handler(target)(args);
}
};
}
return AddClassHandler(typeof(TTarget), Adapter, routes, handledEventsToo);
}
public IDisposable AddClassHandler<TTarget>(
Action<TTarget, TEventArgs> handler,
RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble,
bool handledEventsToo = false) where TTarget : class, IInteractive
{
void Adapter(object sender, RoutedEventArgs e)
{
if (sender is TTarget target && e is TEventArgs args)
{
handler(target, args);
}
}
return AddClassHandler(typeof(TTarget), adapter, routes, handledEventsToo);
return AddClassHandler(typeof(TTarget), Adapter, routes, handledEventsToo);
}
}
}

142
src/Avalonia.Native/AvaloniaNativeMenuExporter.cs

@ -5,12 +5,89 @@ using System.Linq;
using System.Text;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Native.Interop;
using Avalonia.Platform.Interop;
using Avalonia.Threading;
namespace Avalonia.Native
{
enum OsxUnicodeSpecialKey
{
NSUpArrowFunctionKey = 0xF700,
NSDownArrowFunctionKey = 0xF701,
NSLeftArrowFunctionKey = 0xF702,
NSRightArrowFunctionKey = 0xF703,
NSF1FunctionKey = 0xF704,
NSF2FunctionKey = 0xF705,
NSF3FunctionKey = 0xF706,
NSF4FunctionKey = 0xF707,
NSF5FunctionKey = 0xF708,
NSF6FunctionKey = 0xF709,
NSF7FunctionKey = 0xF70A,
NSF8FunctionKey = 0xF70B,
NSF9FunctionKey = 0xF70C,
NSF10FunctionKey = 0xF70D,
NSF11FunctionKey = 0xF70E,
NSF12FunctionKey = 0xF70F,
NSF13FunctionKey = 0xF710,
NSF14FunctionKey = 0xF711,
NSF15FunctionKey = 0xF712,
NSF16FunctionKey = 0xF713,
NSF17FunctionKey = 0xF714,
NSF18FunctionKey = 0xF715,
NSF19FunctionKey = 0xF716,
NSF20FunctionKey = 0xF717,
NSF21FunctionKey = 0xF718,
NSF22FunctionKey = 0xF719,
NSF23FunctionKey = 0xF71A,
NSF24FunctionKey = 0xF71B,
NSF25FunctionKey = 0xF71C,
NSF26FunctionKey = 0xF71D,
NSF27FunctionKey = 0xF71E,
NSF28FunctionKey = 0xF71F,
NSF29FunctionKey = 0xF720,
NSF30FunctionKey = 0xF721,
NSF31FunctionKey = 0xF722,
NSF32FunctionKey = 0xF723,
NSF33FunctionKey = 0xF724,
NSF34FunctionKey = 0xF725,
NSF35FunctionKey = 0xF726,
NSInsertFunctionKey = 0xF727,
NSDeleteFunctionKey = 0xF728,
NSHomeFunctionKey = 0xF729,
NSBeginFunctionKey = 0xF72A,
NSEndFunctionKey = 0xF72B,
NSPageUpFunctionKey = 0xF72C,
NSPageDownFunctionKey = 0xF72D,
NSPrintScreenFunctionKey = 0xF72E,
NSScrollLockFunctionKey = 0xF72F,
NSPauseFunctionKey = 0xF730,
NSSysReqFunctionKey = 0xF731,
NSBreakFunctionKey = 0xF732,
NSResetFunctionKey = 0xF733,
NSStopFunctionKey = 0xF734,
NSMenuFunctionKey = 0xF735,
NSUserFunctionKey = 0xF736,
NSSystemFunctionKey = 0xF737,
NSPrintFunctionKey = 0xF738,
NSClearLineFunctionKey = 0xF739,
NSClearDisplayFunctionKey = 0xF73A,
NSInsertLineFunctionKey = 0xF73B,
NSDeleteLineFunctionKey = 0xF73C,
NSInsertCharFunctionKey = 0xF73D,
NSDeleteCharFunctionKey = 0xF73E,
NSPrevFunctionKey = 0xF73F,
NSNextFunctionKey = 0xF740,
NSSelectFunctionKey = 0xF741,
NSExecuteFunctionKey = 0xF742,
NSUndoFunctionKey = 0xF743,
NSRedoFunctionKey = 0xF744,
NSFindFunctionKey = 0xF745,
NSHelpFunctionKey = 0xF746,
NSModeSwitchFunctionKey = 0xF747
}
public class MenuActionCallback : CallbackBase, IAvnActionCallback
{
private Action _action;
@ -50,6 +127,57 @@ namespace Avalonia.Native
private IAvnWindow _nativeWindow;
private List<NativeMenuItem> _menuItems = new List<NativeMenuItem>();
private static Dictionary<Key, OsxUnicodeSpecialKey> osxKeys = new Dictionary<Key, OsxUnicodeSpecialKey>
{
{Key.Up, OsxUnicodeSpecialKey.NSUpArrowFunctionKey },
{Key.Down, OsxUnicodeSpecialKey.NSDownArrowFunctionKey },
{Key.Left, OsxUnicodeSpecialKey.NSLeftArrowFunctionKey },
{Key.Right, OsxUnicodeSpecialKey.NSRightArrowFunctionKey },
{ Key.F1, OsxUnicodeSpecialKey.NSF1FunctionKey },
{ Key.F2, OsxUnicodeSpecialKey.NSF2FunctionKey },
{ Key.F3, OsxUnicodeSpecialKey.NSF3FunctionKey },
{ Key.F4, OsxUnicodeSpecialKey.NSF4FunctionKey },
{ Key.F5, OsxUnicodeSpecialKey.NSF5FunctionKey },
{ Key.F6, OsxUnicodeSpecialKey.NSF6FunctionKey },
{ Key.F7, OsxUnicodeSpecialKey.NSF7FunctionKey },
{ Key.F8, OsxUnicodeSpecialKey.NSF8FunctionKey },
{ Key.F9, OsxUnicodeSpecialKey.NSF9FunctionKey },
{ Key.F10, OsxUnicodeSpecialKey.NSF10FunctionKey },
{ Key.F11, OsxUnicodeSpecialKey.NSF11FunctionKey },
{ Key.F12, OsxUnicodeSpecialKey.NSF12FunctionKey },
{ Key.F13, OsxUnicodeSpecialKey.NSF13FunctionKey },
{ Key.F14, OsxUnicodeSpecialKey.NSF14FunctionKey },
{ Key.F15, OsxUnicodeSpecialKey.NSF15FunctionKey },
{ Key.F16, OsxUnicodeSpecialKey.NSF16FunctionKey },
{ Key.F17, OsxUnicodeSpecialKey.NSF17FunctionKey },
{ Key.F18, OsxUnicodeSpecialKey.NSF18FunctionKey },
{ Key.F19, OsxUnicodeSpecialKey.NSF19FunctionKey },
{ Key.F20, OsxUnicodeSpecialKey.NSF20FunctionKey },
{ Key.F21, OsxUnicodeSpecialKey.NSF21FunctionKey },
{ Key.F22, OsxUnicodeSpecialKey.NSF22FunctionKey },
{ Key.F23, OsxUnicodeSpecialKey.NSF23FunctionKey },
{ Key.F24, OsxUnicodeSpecialKey.NSF24FunctionKey },
{ Key.Insert, OsxUnicodeSpecialKey.NSInsertFunctionKey },
{ Key.Delete, OsxUnicodeSpecialKey.NSDeleteFunctionKey },
{ Key.Home, OsxUnicodeSpecialKey.NSHomeFunctionKey },
//{ Key.Begin, OsxUnicodeSpecialKey.NSBeginFunctionKey },
{ Key.End, OsxUnicodeSpecialKey.NSEndFunctionKey },
{ Key.PageUp, OsxUnicodeSpecialKey.NSPageUpFunctionKey },
{ Key.PageDown, OsxUnicodeSpecialKey.NSPageDownFunctionKey },
{ Key.PrintScreen, OsxUnicodeSpecialKey.NSPrintScreenFunctionKey },
{ Key.Scroll, OsxUnicodeSpecialKey.NSScrollLockFunctionKey },
//{ Key.SysReq, OsxUnicodeSpecialKey.NSSysReqFunctionKey },
//{ Key.Break, OsxUnicodeSpecialKey.NSBreakFunctionKey },
//{ Key.Reset, OsxUnicodeSpecialKey.NSResetFunctionKey },
//{ Key.Stop, OsxUnicodeSpecialKey.NSStopFunctionKey },
//{ Key.Menu, OsxUnicodeSpecialKey.NSMenuFunctionKey },
//{ Key.UserFunction, OsxUnicodeSpecialKey.NSUserFunctionKey },
//{ Key.SystemFunction, OsxUnicodeSpecialKey.NSSystemFunctionKey },
{ Key.Print, OsxUnicodeSpecialKey.NSPrintFunctionKey },
//{ Key.ClearLine, OsxUnicodeSpecialKey.NSClearLineFunctionKey },
//{ Key.ClearDisplay, OsxUnicodeSpecialKey.NSClearDisplayFunctionKey },
};
public AvaloniaNativeMenuExporter(IAvnWindow nativeWindow, IAvaloniaNativeFactory factory)
{
_factory = factory;
@ -147,6 +275,18 @@ namespace Avalonia.Native
}
}
private static string ConvertOSXSpecialKeyCodes(Key key)
{
if (osxKeys.ContainsKey(key))
{
return ((char)osxKeys[key]).ToString();
}
else
{
return key.ToString().ToLower();
}
}
private void SetChildren(IAvnAppMenu menu, ICollection<NativeMenuItemBase> children)
{
foreach (var i in children)
@ -164,7 +304,7 @@ namespace Avalonia.Native
if (item.Gesture != null)
{
using (var buffer = new Utf8Buffer(item.Gesture.Key.ToString().ToLower()))
using (var buffer = new Utf8Buffer(ConvertOSXSpecialKeyCodes(item.Gesture.Key)))
{
menuItem.SetGesture(buffer.DangerousGetHandle(), (AvnInputModifiers)item.Gesture.KeyModifiers);
}

4
src/Avalonia.Native/WindowImplBase.cs

@ -301,7 +301,7 @@ namespace Avalonia.Native
_native.Hide();
}
public void BeginMoveDrag()
public void BeginMoveDrag(PointerPressedEventArgs e)
{
_native.BeginMoveDrag();
}
@ -343,7 +343,7 @@ namespace Avalonia.Native
_native.SetMinMaxSize(minSize.ToAvnSize(), maxSize.ToAvnSize());
}
public void BeginResizeDrag(WindowEdge edge)
public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{
}

2
src/Avalonia.Styling/StyledElement.cs

@ -73,7 +73,7 @@ namespace Avalonia
/// </summary>
static StyledElement()
{
DataContextProperty.Changed.AddClassHandler<StyledElement>(x => x.OnDataContextChangedCore);
DataContextProperty.Changed.AddClassHandler<StyledElement>((x,e) => x.OnDataContextChangedCore(e));
}
/// <summary>

2
src/Avalonia.Visuals/Media/Geometry.cs

@ -22,7 +22,7 @@ namespace Avalonia.Media
static Geometry()
{
TransformProperty.Changed.AddClassHandler<Geometry>(x => x.TransformChanged);
TransformProperty.Changed.AddClassHandler<Geometry>((x,e) => x.TransformChanged(e));
}
/// <summary>

4
src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs

@ -240,6 +240,10 @@ namespace Avalonia.Rendering.SceneGraph
}
}
}
else
{
contextImpl.BeginUpdate(node).Dispose();
}
}
private void UpdateSize(Scene scene)

2
src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs

@ -218,7 +218,7 @@ namespace Avalonia.Rendering.SceneGraph
if (first < _children?.Count)
{
EnsureChildrenCreated();
for (int i = first; i < _children.Count - first; i++)
for (int i = first; i < _children.Count; i++)
{
_children[i].Dispose();
}

12
src/Avalonia.X11/X11Window.cs

@ -878,21 +878,23 @@ namespace Avalonia.X11
}
void BeginMoveResize(NetWmMoveResize side)
void BeginMoveResize(NetWmMoveResize side, PointerPressedEventArgs e)
{
var pos = GetCursorPos(_x11);
XUngrabPointer(_x11.Display, new IntPtr(0));
SendNetWMMessage (_x11.Atoms._NET_WM_MOVERESIZE, (IntPtr) pos.x, (IntPtr) pos.y,
(IntPtr) side,
(IntPtr) 1, (IntPtr)1); // left button
e.Pointer.Capture(null);
}
public void BeginMoveDrag()
public void BeginMoveDrag(PointerPressedEventArgs e)
{
BeginMoveResize(NetWmMoveResize._NET_WM_MOVERESIZE_MOVE);
BeginMoveResize(NetWmMoveResize._NET_WM_MOVERESIZE_MOVE, e);
}
public void BeginResizeDrag(WindowEdge edge)
public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{
var side = NetWmMoveResize._NET_WM_MOVERESIZE_CANCEL;
if (edge == WindowEdge.East)
@ -911,7 +913,7 @@ namespace Avalonia.X11
side = NetWmMoveResize._NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
if (edge == WindowEdge.SouthWest)
side = NetWmMoveResize._NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
BeginMoveResize(side);
BeginMoveResize(side, e);
}
public void SetTitle(string title)

5
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -331,11 +331,12 @@ namespace Avalonia.Win32
ShowWindow(_showWindowState);
}
public void BeginMoveDrag()
public void BeginMoveDrag(PointerPressedEventArgs e)
{
WindowsMouseDevice.Instance.Capture(null);
UnmanagedMethods.DefWindowProc(_hwnd, (int)UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN,
new IntPtr((int)UnmanagedMethods.HitTestValues.HTCAPTION), IntPtr.Zero);
e.Pointer.Capture(null);
}
static readonly Dictionary<WindowEdge, UnmanagedMethods.HitTestValues> EdgeDic = new Dictionary<WindowEdge, UnmanagedMethods.HitTestValues>
@ -350,7 +351,7 @@ namespace Avalonia.Win32
{WindowEdge.West, UnmanagedMethods.HitTestValues.HTLEFT}
};
public void BeginResizeDrag(WindowEdge edge)
public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{
#if USE_MANAGED_DRAG
_managedDrag.BeginResizeDrag(edge, ScreenToClient(MouseDevice.Position));

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

@ -18,7 +18,9 @@ namespace Avalonia.Controls.UnitTests.Platform
default);
static PointerReleasedEventArgs CreateReleased(IInteractive source) => new PointerReleasedEventArgs(source,
new FakePointer(), (IVisual)source, default,0, new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonReleased), default);
new FakePointer(), (IVisual)source, default,0,
new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonReleased),
default, MouseButton.Left);
public class TopLevel
{

2
tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs

@ -331,7 +331,7 @@ namespace Avalonia.Interactivity.UnitTests
var target = CreateTree(ev, null, 0);
ev.AddClassHandler<TestInteractive>(x => x.ClassHandler, RoutingStrategies.Bubble);
ev.AddClassHandler<TestInteractive>((x, e) => x.ClassHandler(e), RoutingStrategies.Bubble);
var args = new RoutedEventArgs(ev, target);
target.RaiseEvent(args);

3
tests/Avalonia.UnitTests/MouseTestHelper.cs

@ -86,8 +86,7 @@ namespace Avalonia.UnitTests
{
_pointer.Capture(null);
target.RaiseEvent(new PointerReleasedEventArgs(source, _pointer, (IVisual)target, position,
Timestamp(), props,
GetModifiers(modifiers)));
Timestamp(), props, GetModifiers(modifiers), _pressedButton));
}
else
Move(target, source, position);

53
tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs

@ -577,6 +577,59 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
}
}
[Fact]
public void Should_Not_Dispose_Active_VisualNode_When_Control_Reparented_And_Child_Made_Invisible()
{
// Issue #3115
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
StackPanel panel;
Border border1;
Border border2;
var tree = new TestRoot
{
Width = 100,
Height = 100,
Child = panel = new StackPanel
{
Children =
{
(border1 = new Border
{
Background = Brushes.Red,
}),
(border2 = new Border
{
Background = Brushes.Green,
}),
}
}
};
tree.Measure(Size.Infinity);
tree.Arrange(new Rect(tree.DesiredSize));
var scene = new Scene(tree);
var sceneBuilder = new SceneBuilder();
sceneBuilder.UpdateAll(scene);
var decorator = new Decorator();
tree.Child = null;
decorator.Child = panel;
tree.Child = decorator;
border1.IsVisible = false;
scene = scene.CloneScene();
var panelNode = (VisualNode)scene.FindNode(panel);
sceneBuilder.Update(scene, decorator);
Assert.Equal(2, panelNode.Children.Count);
Assert.False(panelNode.Children[0].Disposed);
Assert.False(panelNode.Children[1].Disposed);
}
}
[Fact]
public void Should_Update_ClipBounds_For_Negative_Margin()
{

19
tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/VisualNodeTests.cs

@ -101,5 +101,24 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
node.SortChildren(scene);
}
[Fact]
public void TrimChildren_Should_Work_Correctly()
{
var parent = new VisualNode(Mock.Of<IVisual>(), null);
var child1 = new VisualNode(Mock.Of<IVisual>(), null);
var child2 = new VisualNode(Mock.Of<IVisual>(), null);
var child3 = new VisualNode(Mock.Of<IVisual>(), null);
parent.AddChild(child1);
parent.AddChild(child2);
parent.AddChild(child3);
parent.TrimChildren(2);
Assert.Equal(2, parent.Children.Count);
Assert.False(child1.Disposed);
Assert.False(child2.Disposed);
Assert.True(child3.Disposed);
}
}
}

Loading…
Cancel
Save