diff --git a/native/Avalonia.Native/src/OSX/menu.mm b/native/Avalonia.Native/src/OSX/menu.mm index d9dfe36444..1d2f075ccb 100644 --- a/native/Avalonia.Native/src/OSX/menu.mm +++ b/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 diff --git a/native/Avalonia.Native/src/OSX/window.h b/native/Avalonia.Native/src/OSX/window.h index 557e19e7a8..932bc56a2e 100644 --- a/native/Avalonia.Native/src/OSX/window.h +++ b/native/Avalonia.Native/src/OSX/window.h @@ -15,6 +15,7 @@ class WindowBaseImpl; @end @interface AvnWindow : NSWindow ++(void) closeAll; -(AvnWindow* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent; -(void) setCanBecomeKeyAndMain; -(void) pollModalSession: (NSModalSession _Nonnull) session; diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index dbb437243a..9c7e9323e0 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -1076,6 +1076,17 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent bool _isAppMenuApplied; } ++(void)closeAll +{ + NSArray* windows = [NSArray arrayWithArray:[NSApp windows]]; + auto numWindows = [windows count]; + + for(int i = 0; i < numWindows; i++) + { + [[windows objectAtIndex:i] performClose:nil]; + } +} + - (void)dealloc { } diff --git a/samples/ControlCatalog/DecoratedWindow.xaml.cs b/samples/ControlCatalog/DecoratedWindow.xaml.cs index 2e7218b956..bdf5b8fbee 100644 --- a/samples/ControlCatalog/DecoratedWindow.xaml.cs +++ b/samples/ControlCatalog/DecoratedWindow.xaml.cs @@ -18,18 +18,18 @@ namespace ControlCatalog { var ctl = this.FindControl(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("TitleBar").PointerPressed += delegate + this.FindControl("TitleBar").PointerPressed += (i, e) => { - PlatformImpl?.BeginMoveDrag(); + PlatformImpl?.BeginMoveDrag(e); }; SetupSide("Left", StandardCursorType.LeftSide, WindowEdge.West); SetupSide("Right", StandardCursorType.RightSide, WindowEdge.East); diff --git a/src/Avalonia.Base/AvaloniaObjectExtensions.cs b/src/Avalonia.Base/AvaloniaObjectExtensions.cs index 393482cccf..ad1cefd4ea 100644 --- a/src/Avalonia.Base/AvaloniaObjectExtensions.cs +++ b/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 /// The property changed observable. /// Given a TTarget, returns the handler. /// A disposable that can be used to terminate the subscription. + [Obsolete("Use overload taking Action.")] public static IDisposable AddClassHandler( this IObservable observable, Func> handler) @@ -238,9 +239,7 @@ namespace Avalonia Func> handler) where TTarget : class { - var target = e.Sender as TTarget; - - if (target != null) + if (e.Sender is TTarget target) { handler(target)(e); } diff --git a/src/Avalonia.Controls.DataGrid/DataGrid.cs b/src/Avalonia.Controls.DataGrid/DataGrid.cs index 490a724eda..b65fd2a8b7 100644 --- a/src/Avalonia.Controls.DataGrid/DataGrid.cs +++ b/src/Avalonia.Controls.DataGrid/DataGrid.cs @@ -723,29 +723,29 @@ namespace Avalonia.Controls PseudoClass(IsValidProperty, x => !x, ":invalid"); - ItemsProperty.Changed.AddClassHandler(x => x.OnItemsPropertyChanged); - CanUserResizeColumnsProperty.Changed.AddClassHandler(x => x.OnCanUserResizeColumnsChanged); - ColumnWidthProperty.Changed.AddClassHandler(x => x.OnColumnWidthChanged); - RowBackgroundProperty.Changed.AddClassHandler(x => x.OnRowBackgroundChanged); - AlternatingRowBackgroundProperty.Changed.AddClassHandler(x => x.OnRowBackgroundChanged); - FrozenColumnCountProperty.Changed.AddClassHandler(x => x.OnFrozenColumnCountChanged); - GridLinesVisibilityProperty.Changed.AddClassHandler(x => x.OnGridLinesVisibilityChanged); - HeadersVisibilityProperty.Changed.AddClassHandler(x => x.OnHeadersVisibilityChanged); - HorizontalGridLinesBrushProperty.Changed.AddClassHandler(x => x.OnHorizontalGridLinesBrushChanged); - IsReadOnlyProperty.Changed.AddClassHandler(x => x.OnIsReadOnlyChanged); - MaxColumnWidthProperty.Changed.AddClassHandler(x => x.OnMaxColumnWidthChanged); - MinColumnWidthProperty.Changed.AddClassHandler(x => x.OnMinColumnWidthChanged); - RowHeightProperty.Changed.AddClassHandler(x => x.OnRowHeightChanged); - RowHeaderWidthProperty.Changed.AddClassHandler(x => x.OnRowHeaderWidthChanged); - SelectionModeProperty.Changed.AddClassHandler(x => x.OnSelectionModeChanged); - VerticalGridLinesBrushProperty.Changed.AddClassHandler(x => x.OnVerticalGridLinesBrushChanged); - SelectedIndexProperty.Changed.AddClassHandler(x => x.OnSelectedIndexChanged); - SelectedItemProperty.Changed.AddClassHandler(x => x.OnSelectedItemChanged); - IsEnabledProperty.Changed.AddClassHandler(x => x.DataGrid_IsEnabledChanged); - AreRowGroupHeadersFrozenProperty.Changed.AddClassHandler(x => x.OnAreRowGroupHeadersFrozenChanged); - RowDetailsTemplateProperty.Changed.AddClassHandler(x => x.OnRowDetailsTemplateChanged); - RowDetailsVisibilityModeProperty.Changed.AddClassHandler(x => x.OnRowDetailsVisibilityModeChanged); - AutoGenerateColumnsProperty.Changed.AddClassHandler(x => x.OnAutoGenerateColumnsChanged); + ItemsProperty.Changed.AddClassHandler((x, e) => x.OnItemsPropertyChanged(e)); + CanUserResizeColumnsProperty.Changed.AddClassHandler((x, e) => x.OnCanUserResizeColumnsChanged(e)); + ColumnWidthProperty.Changed.AddClassHandler((x, e) => x.OnColumnWidthChanged(e)); + RowBackgroundProperty.Changed.AddClassHandler((x, e) => x.OnRowBackgroundChanged(e)); + AlternatingRowBackgroundProperty.Changed.AddClassHandler((x, e) => x.OnRowBackgroundChanged(e)); + FrozenColumnCountProperty.Changed.AddClassHandler((x, e) => x.OnFrozenColumnCountChanged(e)); + GridLinesVisibilityProperty.Changed.AddClassHandler((x, e) => x.OnGridLinesVisibilityChanged(e)); + HeadersVisibilityProperty.Changed.AddClassHandler((x, e) => x.OnHeadersVisibilityChanged(e)); + HorizontalGridLinesBrushProperty.Changed.AddClassHandler((x, e) => x.OnHorizontalGridLinesBrushChanged(e)); + IsReadOnlyProperty.Changed.AddClassHandler((x, e) => x.OnIsReadOnlyChanged(e)); + MaxColumnWidthProperty.Changed.AddClassHandler((x, e) => x.OnMaxColumnWidthChanged(e)); + MinColumnWidthProperty.Changed.AddClassHandler((x, e) => x.OnMinColumnWidthChanged(e)); + RowHeightProperty.Changed.AddClassHandler((x, e) => x.OnRowHeightChanged(e)); + RowHeaderWidthProperty.Changed.AddClassHandler((x, e) => x.OnRowHeaderWidthChanged(e)); + SelectionModeProperty.Changed.AddClassHandler((x, e) => x.OnSelectionModeChanged(e)); + VerticalGridLinesBrushProperty.Changed.AddClassHandler((x, e) => x.OnVerticalGridLinesBrushChanged(e)); + SelectedIndexProperty.Changed.AddClassHandler((x, e) => x.OnSelectedIndexChanged(e)); + SelectedItemProperty.Changed.AddClassHandler((x, e) => x.OnSelectedItemChanged(e)); + IsEnabledProperty.Changed.AddClassHandler((x, e) => x.DataGrid_IsEnabledChanged(e)); + AreRowGroupHeadersFrozenProperty.Changed.AddClassHandler((x, e) => x.OnAreRowGroupHeadersFrozenChanged(e)); + RowDetailsTemplateProperty.Changed.AddClassHandler((x, e) => x.OnRowDetailsTemplateChanged(e)); + RowDetailsVisibilityModeProperty.Changed.AddClassHandler((x, e) => x.OnRowDetailsVisibilityModeChanged(e)); + AutoGenerateColumnsProperty.Changed.AddClassHandler((x, e) => x.OnAutoGenerateColumnsChanged(e)); } /// @@ -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 diff --git a/src/Avalonia.Controls.DataGrid/DataGridCell.cs b/src/Avalonia.Controls.DataGrid/DataGridCell.cs index a21583b38e..e56c534f50 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridCell.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridCell.cs @@ -29,7 +29,7 @@ namespace Avalonia.Controls static DataGridCell() { PointerPressedEvent.AddClassHandler( - x => x.DataGridCell_PointerPressed, handledEventsToo: true); + (x,e) => x.DataGridCell_PointerPressed(e), handledEventsToo: true); } public DataGridCell() { } @@ -219,4 +219,4 @@ namespace Avalonia.Controls } } } -} \ No newline at end of file +} diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs index 6cb0807e29..d1651b2d09 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs @@ -67,7 +67,7 @@ namespace Avalonia.Controls static DataGridColumnHeader() { - AreSeparatorsVisibleProperty.Changed.AddClassHandler(x => x.OnAreSeparatorsVisibleChanged); + AreSeparatorsVisibleProperty.Changed.AddClassHandler((x,e) => x.OnAreSeparatorsVisibleChanged(e)); } /// @@ -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; } diff --git a/src/Avalonia.Controls.DataGrid/DataGridRow.cs b/src/Avalonia.Controls.DataGrid/DataGridRow.cs index 04a1575486..c9924660be 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRow.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRow.cs @@ -116,10 +116,10 @@ namespace Avalonia.Controls static DataGridRow() { - HeaderProperty.Changed.AddClassHandler(x => x.OnHeaderChanged); - DetailsTemplateProperty.Changed.AddClassHandler(x => x.OnDetailsTemplateChanged); - AreDetailsVisibleProperty.Changed.AddClassHandler(x => x.OnAreDetailsVisibleChanged); - PointerPressedEvent.AddClassHandler(x => x.DataGridRow_PointerPressed, handledEventsToo: true); + HeaderProperty.Changed.AddClassHandler((x, e) => x.OnHeaderChanged(e)); + DetailsTemplateProperty.Changed.AddClassHandler((x, e) => x.OnDetailsTemplateChanged(e)); + AreDetailsVisibleProperty.Changed.AddClassHandler((x, e) => x.OnAreDetailsVisibleChanged(e)); + PointerPressedEvent.AddClassHandler((x, e) => x.DataGridRow_PointerPressed(e), handledEventsToo: true); } /// diff --git a/src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs b/src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs index 716997f62c..7dafef9d8b 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs @@ -109,7 +109,7 @@ namespace Avalonia.Controls static DataGridRowGroupHeader() { - SublevelIndentProperty.Changed.AddClassHandler(x => x.OnSublevelIndentChanged); + SublevelIndentProperty.Changed.AddClassHandler((x,e) => x.OnSublevelIndentChanged(e)); } /// @@ -446,4 +446,4 @@ namespace Avalonia.Controls } } -} \ No newline at end of file +} diff --git a/src/Avalonia.Controls/AutoCompleteBox.cs b/src/Avalonia.Controls/AutoCompleteBox.cs index 1e2fc9f9d0..ce4358648b 100644 --- a/src/Avalonia.Controls/AutoCompleteBox.cs +++ b/src/Avalonia.Controls/AutoCompleteBox.cs @@ -805,15 +805,15 @@ namespace Avalonia.Controls { FocusableProperty.OverrideDefaultValue(true); - MinimumPopulateDelayProperty.Changed.AddClassHandler(x => x.OnMinimumPopulateDelayChanged); - IsDropDownOpenProperty.Changed.AddClassHandler(x => x.OnIsDropDownOpenChanged); - SelectedItemProperty.Changed.AddClassHandler(x => x.OnSelectedItemPropertyChanged); - TextProperty.Changed.AddClassHandler(x => x.OnTextPropertyChanged); - SearchTextProperty.Changed.AddClassHandler(x => x.OnSearchTextPropertyChanged); - FilterModeProperty.Changed.AddClassHandler(x => x.OnFilterModePropertyChanged); - ItemFilterProperty.Changed.AddClassHandler(x => x.OnItemFilterPropertyChanged); - ItemsProperty.Changed.AddClassHandler(x => x.OnItemsPropertyChanged); - IsEnabledProperty.Changed.AddClassHandler(x => x.OnControlIsEnabledChanged); + MinimumPopulateDelayProperty.Changed.AddClassHandler((x,e) => x.OnMinimumPopulateDelayChanged(e)); + IsDropDownOpenProperty.Changed.AddClassHandler((x,e) => x.OnIsDropDownOpenChanged(e)); + SelectedItemProperty.Changed.AddClassHandler((x,e) => x.OnSelectedItemPropertyChanged(e)); + TextProperty.Changed.AddClassHandler((x,e) => x.OnTextPropertyChanged(e)); + SearchTextProperty.Changed.AddClassHandler((x,e) => x.OnSearchTextPropertyChanged(e)); + FilterModeProperty.Changed.AddClassHandler((x,e) => x.OnFilterModePropertyChanged(e)); + ItemFilterProperty.Changed.AddClassHandler((x,e) => x.OnItemFilterPropertyChanged(e)); + ItemsProperty.Changed.AddClassHandler((x,e) => x.OnItemsPropertyChanged(e)); + IsEnabledProperty.Changed.AddClassHandler((x,e) => x.OnControlIsEnabledChanged(e)); } /// diff --git a/src/Avalonia.Controls/Button.cs b/src/Avalonia.Controls/Button.cs index d39ea73828..78d02e200f 100644 --- a/src/Avalonia.Controls/Button.cs +++ b/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; diff --git a/src/Avalonia.Controls/Calendar/Calendar.cs b/src/Avalonia.Controls/Calendar/Calendar.cs index 56805e1d6a..beafab3edf 100644 --- a/src/Avalonia.Controls/Calendar/Calendar.cs +++ b/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(x => x.OnIsEnabledChanged); - FirstDayOfWeekProperty.Changed.AddClassHandler(x => x.OnFirstDayOfWeekChanged); - IsTodayHighlightedProperty.Changed.AddClassHandler(x => x.OnIsTodayHighlightedChanged); - DisplayModeProperty.Changed.AddClassHandler(x => x.OnDisplayModePropertyChanged); - SelectionModeProperty.Changed.AddClassHandler(x => x.OnSelectionModeChanged); - SelectedDateProperty.Changed.AddClassHandler(x => x.OnSelectedDateChanged); - DisplayDateProperty.Changed.AddClassHandler(x => x.OnDisplayDateChanged); - DisplayDateStartProperty.Changed.AddClassHandler(x => x.OnDisplayDateStartChanged); - DisplayDateEndProperty.Changed.AddClassHandler(x => x.OnDisplayDateEndChanged); - KeyDownEvent.AddClassHandler(x => x.Calendar_KeyDown); - KeyUpEvent.AddClassHandler(x => x.Calendar_KeyUp); - + IsEnabledProperty.Changed.AddClassHandler((x,e) => x.OnIsEnabledChanged(e)); + FirstDayOfWeekProperty.Changed.AddClassHandler((x,e) => x.OnFirstDayOfWeekChanged(e)); + IsTodayHighlightedProperty.Changed.AddClassHandler((x,e) => x.OnIsTodayHighlightedChanged(e)); + DisplayModeProperty.Changed.AddClassHandler((x,e) => x.OnDisplayModePropertyChanged(e)); + SelectionModeProperty.Changed.AddClassHandler((x,e) => x.OnSelectionModeChanged(e)); + SelectedDateProperty.Changed.AddClassHandler((x,e) => x.OnSelectedDateChanged(e)); + DisplayDateProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateChanged(e)); + DisplayDateStartProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateStartChanged(e)); + DisplayDateEndProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateEndChanged(e)); + KeyDownEvent.AddClassHandler((x,e) => x.Calendar_KeyDown(e)); + KeyUpEvent.AddClassHandler((x,e) => x.Calendar_KeyUp(e)); } /// diff --git a/src/Avalonia.Controls/Calendar/CalendarButton.cs b/src/Avalonia.Controls/Calendar/CalendarButton.cs index 53852defb3..a273e68d56 100644 --- a/src/Avalonia.Controls/Calendar/CalendarButton.cs +++ b/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); } } diff --git a/src/Avalonia.Controls/Calendar/CalendarDayButton.cs b/src/Avalonia.Controls/Calendar/CalendarDayButton.cs index cb2a98e5ca..e62a1ce1f4 100644 --- a/src/Avalonia.Controls/Calendar/CalendarDayButton.cs +++ b/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); } } diff --git a/src/Avalonia.Controls/Calendar/DatePicker.cs b/src/Avalonia.Controls/Calendar/DatePicker.cs index 55797ae1e3..841b73cd92 100644 --- a/src/Avalonia.Controls/Calendar/DatePicker.cs +++ b/src/Avalonia.Controls/Calendar/DatePicker.cs @@ -393,14 +393,14 @@ namespace Avalonia.Controls { FocusableProperty.OverrideDefaultValue(true); - DisplayDateProperty.Changed.AddClassHandler(x => x.OnDisplayDateChanged); - DisplayDateStartProperty.Changed.AddClassHandler(x => x.OnDisplayDateStartChanged); - DisplayDateEndProperty.Changed.AddClassHandler(x => x.OnDisplayDateEndChanged); - IsDropDownOpenProperty.Changed.AddClassHandler(x => x.OnIsDropDownOpenChanged); - SelectedDateProperty.Changed.AddClassHandler(x => x.OnSelectedDateChanged); - SelectedDateFormatProperty.Changed.AddClassHandler(x => x.OnSelectedDateFormatChanged); - CustomDateFormatStringProperty.Changed.AddClassHandler(x => x.OnCustomDateFormatStringChanged); - TextProperty.Changed.AddClassHandler(x => x.OnTextChanged); + DisplayDateProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateChanged(e)); + DisplayDateStartProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateStartChanged(e)); + DisplayDateEndProperty.Changed.AddClassHandler((x,e) => x.OnDisplayDateEndChanged(e)); + IsDropDownOpenProperty.Changed.AddClassHandler((x,e) => x.OnIsDropDownOpenChanged(e)); + SelectedDateProperty.Changed.AddClassHandler((x,e) => x.OnSelectedDateChanged(e)); + SelectedDateFormatProperty.Changed.AddClassHandler((x,e) => x.OnSelectedDateFormatChanged(e)); + CustomDateFormatStringProperty.Changed.AddClassHandler((x,e) => x.OnCustomDateFormatStringChanged(e)); + TextProperty.Changed.AddClassHandler((x,e) => x.OnTextChanged(e)); } /// /// Initializes a new instance of the diff --git a/src/Avalonia.Controls/Carousel.cs b/src/Avalonia.Controls/Carousel.cs index 069bf40820..ebc8890721 100644 --- a/src/Avalonia.Controls/Carousel.cs +++ b/src/Avalonia.Controls/Carousel.cs @@ -84,17 +84,5 @@ namespace Avalonia.Controls --SelectedIndex; } } - - /// - protected override void OnKeyDown(KeyEventArgs e) - { - // Ignore key presses. - } - - /// - protected override void OnPointerPressed(PointerPressedEventArgs e) - { - // Ignore pointer presses. - } } } diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs index a70d26624c..c2cf20b32d 100644 --- a/src/Avalonia.Controls/ComboBox.cs +++ b/src/Avalonia.Controls/ComboBox.cs @@ -65,8 +65,8 @@ namespace Avalonia.Controls { ItemsPanelProperty.OverrideDefaultValue(DefaultPanel); FocusableProperty.OverrideDefaultValue(true); - SelectedItemProperty.Changed.AddClassHandler(x => x.SelectedItemChanged); - KeyDownEvent.AddClassHandler(x => x.OnKeyDown, Interactivity.RoutingStrategies.Tunnel); + SelectedItemProperty.Changed.AddClassHandler((x,e) => x.SelectedItemChanged(e)); + KeyDownEvent.AddClassHandler((x, e) => x.OnKeyDown(e), Interactivity.RoutingStrategies.Tunnel); } /// diff --git a/src/Avalonia.Controls/ContentControl.cs b/src/Avalonia.Controls/ContentControl.cs index 02d7890404..bb3cc4585b 100644 --- a/src/Avalonia.Controls/ContentControl.cs +++ b/src/Avalonia.Controls/ContentControl.cs @@ -43,7 +43,7 @@ namespace Avalonia.Controls static ContentControl() { - ContentProperty.Changed.AddClassHandler(x => x.ContentChanged); + ContentProperty.Changed.AddClassHandler((x, e) => x.ContentChanged(e)); } /// diff --git a/src/Avalonia.Controls/ContextMenu.cs b/src/Avalonia.Controls/ContextMenu.cs index a5025df82d..5dfa5863f5 100644 --- a/src/Avalonia.Controls/ContextMenu.cs +++ b/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; diff --git a/src/Avalonia.Controls/DataValidationErrors.cs b/src/Avalonia.Controls/DataValidationErrors.cs index 50b387e636..2588b7cc11 100644 --- a/src/Avalonia.Controls/DataValidationErrors.cs +++ b/src/Avalonia.Controls/DataValidationErrors.cs @@ -56,7 +56,7 @@ namespace Avalonia.Controls { ErrorsProperty.Changed.Subscribe(ErrorsChanged); HasErrorsProperty.Changed.Subscribe(HasErrorsChanged); - TemplatedParentProperty.Changed.AddClassHandler(x => x.OnTemplatedParentChange); + TemplatedParentProperty.Changed.AddClassHandler((x, e) => x.OnTemplatedParentChange(e)); } private void OnTemplatedParentChange(AvaloniaPropertyChangedEventArgs e) diff --git a/src/Avalonia.Controls/Decorator.cs b/src/Avalonia.Controls/Decorator.cs index 15651b918e..6f16870b9f 100644 --- a/src/Avalonia.Controls/Decorator.cs +++ b/src/Avalonia.Controls/Decorator.cs @@ -29,7 +29,7 @@ namespace Avalonia.Controls static Decorator() { AffectsMeasure(ChildProperty, PaddingProperty); - ChildProperty.Changed.AddClassHandler(x => x.ChildChanged); + ChildProperty.Changed.AddClassHandler((x, e) => x.ChildChanged(e)); } /// diff --git a/src/Avalonia.Controls/Expander.cs b/src/Avalonia.Controls/Expander.cs index 1fa9798784..b2a442b6cc 100644 --- a/src/Avalonia.Controls/Expander.cs +++ b/src/Avalonia.Controls/Expander.cs @@ -37,7 +37,7 @@ namespace Avalonia.Controls PseudoClass(IsExpandedProperty, ":expanded"); - IsExpandedProperty.Changed.AddClassHandler(x => x.OnIsExpandedChanged); + IsExpandedProperty.Changed.AddClassHandler((x, e) => x.OnIsExpandedChanged(e)); } public IPageTransition ContentTransition diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index 11fdd0457d..b027da6d0c 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -64,8 +64,8 @@ namespace Avalonia.Controls /// static ItemsControl() { - ItemsProperty.Changed.AddClassHandler(x => x.ItemsChanged); - ItemTemplateProperty.Changed.AddClassHandler(x => x.ItemTemplateChanged); + ItemsProperty.Changed.AddClassHandler((x, e) => x.ItemsChanged(e)); + ItemTemplateProperty.Changed.AddClassHandler((x, e) => x.ItemTemplateChanged(e)); } /// diff --git a/src/Avalonia.Controls/LayoutTransformControl.cs b/src/Avalonia.Controls/LayoutTransformControl.cs index 1430c39c76..db67a24159 100644 --- a/src/Avalonia.Controls/LayoutTransformControl.cs +++ b/src/Avalonia.Controls/LayoutTransformControl.cs @@ -28,11 +28,13 @@ namespace Avalonia.Controls ClipToBoundsProperty.OverrideDefaultValue(true); LayoutTransformProperty.Changed - .AddClassHandler(x => x.OnLayoutTransformChanged); + .AddClassHandler((x, e) => x.OnLayoutTransformChanged(e)); ChildProperty.Changed - .AddClassHandler(x => x.OnChildChanged); - UseRenderTransformProperty.Changed.AddClassHandler(x => x.OnUseRenderTransformPropertyChanged); + .AddClassHandler((x, e) => x.OnChildChanged(e)); + + UseRenderTransformProperty.Changed + .AddClassHandler((x, e) => x.OnUseRenderTransformPropertyChanged(e)); } /// diff --git a/src/Avalonia.Controls/MenuBase.cs b/src/Avalonia.Controls/MenuBase.cs index 8eed58bb4d..be677b5479 100644 --- a/src/Avalonia.Controls/MenuBase.cs +++ b/src/Avalonia.Controls/MenuBase.cs @@ -64,7 +64,7 @@ namespace Avalonia.Controls /// static MenuBase() { - MenuItem.SubmenuOpenedEvent.AddClassHandler(x => x.OnSubmenuOpened); + MenuItem.SubmenuOpenedEvent.AddClassHandler((x, e) => x.OnSubmenuOpened(e)); } /// diff --git a/src/Avalonia.Controls/MenuItem.cs b/src/Avalonia.Controls/MenuItem.cs index 33a708b6a5..3ba0007f6b 100644 --- a/src/Avalonia.Controls/MenuItem.cs +++ b/src/Avalonia.Controls/MenuItem.cs @@ -102,13 +102,13 @@ namespace Avalonia.Controls SelectableMixin.Attach(IsSelectedProperty); CommandProperty.Changed.Subscribe(CommandChanged); FocusableProperty.OverrideDefaultValue(true); - HeaderProperty.Changed.AddClassHandler(x => x.HeaderChanged); - IconProperty.Changed.AddClassHandler(x => x.IconChanged); - IsSelectedProperty.Changed.AddClassHandler(x => x.IsSelectedChanged); + HeaderProperty.Changed.AddClassHandler((x, e) => x.HeaderChanged(e)); + IconProperty.Changed.AddClassHandler((x, e) => x.IconChanged(e)); + IsSelectedProperty.Changed.AddClassHandler((x, e) => x.IsSelectedChanged(e)); ItemsPanelProperty.OverrideDefaultValue(DefaultPanel); - ClickEvent.AddClassHandler(x => x.OnClick); - SubmenuOpenedEvent.AddClassHandler(x => x.OnSubmenuOpened); - IsSubMenuOpenProperty.Changed.AddClassHandler(x => x.SubMenuOpenChanged); + ClickEvent.AddClassHandler((x, e) => x.OnClick(e)); + SubmenuOpenedEvent.AddClassHandler((x, e) => x.OnSubmenuOpened(e)); + IsSubMenuOpenProperty.Changed.AddClassHandler((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)); } diff --git a/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs b/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs index 98f925cd0c..b5dbd1e668 100644 --- a/src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs +++ b/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; diff --git a/src/Avalonia.Controls/Platform/IWindowImpl.cs b/src/Avalonia.Controls/Platform/IWindowImpl.cs index bc5d38c845..91b895f38a 100644 --- a/src/Avalonia.Controls/Platform/IWindowImpl.cs +++ b/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. /// Func Closing { get; set; } - + /// /// Starts moving a window with left button being held. Should be called from left mouse button press event handler. /// - void BeginMoveDrag(); + void BeginMoveDrag(PointerPressedEventArgs e); /// /// 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 /// - void BeginResizeDrag(WindowEdge edge); - + void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e); + /// /// Sets the client size of the top level. /// void Resize(Size clientSize); - + /// /// Sets the client size of the top level. /// void Move(PixelPoint point); - + /// /// Minimum width of the window. /// diff --git a/src/Avalonia.Controls/Presenters/CarouselPresenter.cs b/src/Avalonia.Controls/Presenters/CarouselPresenter.cs index dedab3e43e..89de24a81a 100644 --- a/src/Avalonia.Controls/Presenters/CarouselPresenter.cs +++ b/src/Avalonia.Controls/Presenters/CarouselPresenter.cs @@ -46,8 +46,8 @@ namespace Avalonia.Controls.Presenters /// static CarouselPresenter() { - IsVirtualizedProperty.Changed.AddClassHandler(x => x.IsVirtualizedChanged); - SelectedIndexProperty.Changed.AddClassHandler(x => x.SelectedIndexChanged); + IsVirtualizedProperty.Changed.AddClassHandler((x, e) => x.IsVirtualizedChanged(e)); + SelectedIndexProperty.Changed.AddClassHandler((x, e) => x.SelectedIndexChanged(e)); } /// diff --git a/src/Avalonia.Controls/Presenters/ContentPresenter.cs b/src/Avalonia.Controls/Presenters/ContentPresenter.cs index a5374e7c5a..5e1a844720 100644 --- a/src/Avalonia.Controls/Presenters/ContentPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ContentPresenter.cs @@ -94,9 +94,9 @@ namespace Avalonia.Controls.Presenters { AffectsRender(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty, CornerRadiusProperty); AffectsMeasure(BorderThicknessProperty, PaddingProperty); - ContentProperty.Changed.AddClassHandler(x => x.ContentChanged); - ContentTemplateProperty.Changed.AddClassHandler(x => x.ContentChanged); - TemplatedParentProperty.Changed.AddClassHandler(x => x.TemplatedParentChanged); + ContentProperty.Changed.AddClassHandler((x, e) => x.ContentChanged(e)); + ContentTemplateProperty.Changed.AddClassHandler((x, e) => x.ContentChanged(e)); + TemplatedParentProperty.Changed.AddClassHandler((x, e) => x.TemplatedParentChanged(e)); } /// diff --git a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs index 500c7aa187..ab40fbd53b 100644 --- a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs @@ -35,7 +35,7 @@ namespace Avalonia.Controls.Presenters KeyboardNavigationMode.Once); VirtualizationModeProperty.Changed - .AddClassHandler(x => x.VirtualizationModeChanged); + .AddClassHandler((x, e) => x.VirtualizationModeChanged(e)); } /// diff --git a/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs b/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs index ea56a0c6fc..0f0cdc37cf 100644 --- a/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs +++ b/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs @@ -45,7 +45,7 @@ namespace Avalonia.Controls.Presenters /// static ItemsPresenterBase() { - TemplatedParentProperty.Changed.AddClassHandler(x => x.TemplatedParentChanged); + TemplatedParentProperty.Changed.AddClassHandler((x,e) => x.TemplatedParentChanged(e)); } /// diff --git a/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs b/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs index ec6a228421..48d0aff551 100644 --- a/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs @@ -73,7 +73,7 @@ namespace Avalonia.Controls.Presenters static ScrollContentPresenter() { ClipToBoundsProperty.OverrideDefaultValue(typeof(ScrollContentPresenter), true); - ChildProperty.Changed.AddClassHandler(x => x.ChildChanged); + ChildProperty.Changed.AddClassHandler((x, e) => x.ChildChanged(e)); AffectsArrange(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); /// diff --git a/src/Avalonia.Controls/Primitives/HeaderedContentControl.cs b/src/Avalonia.Controls/Primitives/HeaderedContentControl.cs index 3cf50a7b80..d431420a8f 100644 --- a/src/Avalonia.Controls/Primitives/HeaderedContentControl.cs +++ b/src/Avalonia.Controls/Primitives/HeaderedContentControl.cs @@ -30,7 +30,7 @@ namespace Avalonia.Controls.Primitives /// static HeaderedContentControl() { - ContentProperty.Changed.AddClassHandler(x => x.HeaderChanged); + ContentProperty.Changed.AddClassHandler((x, e) => x.HeaderChanged(e)); } /// diff --git a/src/Avalonia.Controls/Primitives/HeaderedItemsControl.cs b/src/Avalonia.Controls/Primitives/HeaderedItemsControl.cs index e0eb0b005f..f4af694f28 100644 --- a/src/Avalonia.Controls/Primitives/HeaderedItemsControl.cs +++ b/src/Avalonia.Controls/Primitives/HeaderedItemsControl.cs @@ -24,7 +24,7 @@ namespace Avalonia.Controls.Primitives /// static HeaderedItemsControl() { - HeaderProperty.Changed.AddClassHandler(x => x.HeaderChanged); + HeaderProperty.Changed.AddClassHandler((x, e) => x.HeaderChanged(e)); } /// diff --git a/src/Avalonia.Controls/Primitives/HeaderedSelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/HeaderedSelectingItemsControl.cs index 533b643ea6..5e053ed9b4 100644 --- a/src/Avalonia.Controls/Primitives/HeaderedSelectingItemsControl.cs +++ b/src/Avalonia.Controls/Primitives/HeaderedSelectingItemsControl.cs @@ -24,7 +24,7 @@ namespace Avalonia.Controls.Primitives /// static HeaderedSelectingItemsControl() { - HeaderProperty.Changed.AddClassHandler(x => x.HeaderChanged); + HeaderProperty.Changed.AddClassHandler((x, e) => x.HeaderChanged(e)); } /// diff --git a/src/Avalonia.Controls/Primitives/Popup.cs b/src/Avalonia.Controls/Primitives/Popup.cs index b3f86e8a76..77febf9384 100644 --- a/src/Avalonia.Controls/Primitives/Popup.cs +++ b/src/Avalonia.Controls/Primitives/Popup.cs @@ -93,8 +93,8 @@ namespace Avalonia.Controls.Primitives static Popup() { IsHitTestVisibleProperty.OverrideDefaultValue(false); - ChildProperty.Changed.AddClassHandler(x => x.ChildChanged); - IsOpenProperty.Changed.AddClassHandler(x => x.IsOpenChanged); + ChildProperty.Changed.AddClassHandler((x, e) => x.ChildChanged(e)); + IsOpenProperty.Changed.AddClassHandler((x, e) => x.IsOpenChanged(e)); } public Popup() diff --git a/src/Avalonia.Controls/Primitives/PopupRoot.cs b/src/Avalonia.Controls/Primitives/PopupRoot.cs index b7f0c8f47d..74a6d288f4 100644 --- a/src/Avalonia.Controls/Primitives/PopupRoot.cs +++ b/src/Avalonia.Controls/Primitives/PopupRoot.cs @@ -17,7 +17,7 @@ namespace Avalonia.Controls.Primitives /// /// The root window of a . /// - 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; diff --git a/src/Avalonia.Controls/Primitives/ScrollBar.cs b/src/Avalonia.Controls/Primitives/ScrollBar.cs index c6119e89dc..9251ca273f 100644 --- a/src/Avalonia.Controls/Primitives/ScrollBar.cs +++ b/src/Avalonia.Controls/Primitives/ScrollBar.cs @@ -58,8 +58,8 @@ namespace Avalonia.Controls.Primitives PseudoClass(OrientationProperty, o => o == Orientation.Vertical, ":vertical"); PseudoClass(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal"); - Thumb.DragDeltaEvent.AddClassHandler(o => o.OnThumbDragDelta, RoutingStrategies.Bubble); - Thumb.DragCompletedEvent.AddClassHandler(o => o.OnThumbDragComplete, RoutingStrategies.Bubble); + Thumb.DragDeltaEvent.AddClassHandler((x, e) => x.OnThumbDragDelta(e), RoutingStrategies.Bubble); + Thumb.DragCompletedEvent.AddClassHandler((x, e) => x.OnThumbDragComplete(e), RoutingStrategies.Bubble); } /// diff --git a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs index c6172c0f36..7fddee1012 100644 --- a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs +++ b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs @@ -119,7 +119,7 @@ namespace Avalonia.Controls.Primitives /// static SelectingItemsControl() { - IsSelectedChangedEvent.AddClassHandler(x => x.ContainerSelectionChanged); + IsSelectedChangedEvent.AddClassHandler((x, e) => x.ContainerSelectionChanged(e)); } /// @@ -1088,8 +1088,8 @@ namespace Avalonia.Controls.Primitives } else { - SelectedIndex = _updateSelectedIndex != int.MinValue ? - _updateSelectedIndex : + SelectedIndex = _updateSelectedIndex != int.MinValue ? + _updateSelectedIndex : AlwaysSelected ? 0 : -1; } } diff --git a/src/Avalonia.Controls/Primitives/TemplatedControl.cs b/src/Avalonia.Controls/Primitives/TemplatedControl.cs index 7d0f306db8..0ace387185 100644 --- a/src/Avalonia.Controls/Primitives/TemplatedControl.cs +++ b/src/Avalonia.Controls/Primitives/TemplatedControl.cs @@ -99,7 +99,7 @@ namespace Avalonia.Controls.Primitives static TemplatedControl() { ClipToBoundsProperty.OverrideDefaultValue(true); - TemplateProperty.Changed.AddClassHandler(x => x.OnTemplateChanged); + TemplateProperty.Changed.AddClassHandler((x, e) => x.OnTemplateChanged(e)); } /// diff --git a/src/Avalonia.Controls/Primitives/Thumb.cs b/src/Avalonia.Controls/Primitives/Thumb.cs index b01ddd5dba..7e9680dc9f 100644 --- a/src/Avalonia.Controls/Primitives/Thumb.cs +++ b/src/Avalonia.Controls/Primitives/Thumb.cs @@ -22,9 +22,9 @@ namespace Avalonia.Controls.Primitives static Thumb() { - DragStartedEvent.AddClassHandler(x => x.OnDragStarted, RoutingStrategies.Bubble); - DragDeltaEvent.AddClassHandler(x => x.OnDragDelta, RoutingStrategies.Bubble); - DragCompletedEvent.AddClassHandler(x => x.OnDragCompleted, RoutingStrategies.Bubble); + DragStartedEvent.AddClassHandler((x,e) => x.OnDragStarted(e), RoutingStrategies.Bubble); + DragDeltaEvent.AddClassHandler((x, e) => x.OnDragDelta(e), RoutingStrategies.Bubble); + DragCompletedEvent.AddClassHandler((x, e) => x.OnDragCompleted(e), RoutingStrategies.Bubble); } public event EventHandler DragStarted diff --git a/src/Avalonia.Controls/Primitives/Track.cs b/src/Avalonia.Controls/Primitives/Track.cs index a569808b35..292c65aa06 100644 --- a/src/Avalonia.Controls/Primitives/Track.cs +++ b/src/Avalonia.Controls/Primitives/Track.cs @@ -48,9 +48,9 @@ namespace Avalonia.Controls.Primitives { PseudoClass(OrientationProperty, o => o == Orientation.Vertical, ":vertical"); PseudoClass(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal"); - ThumbProperty.Changed.AddClassHandler(x => x.ThumbChanged); - IncreaseButtonProperty.Changed.AddClassHandler(x => x.ButtonChanged); - DecreaseButtonProperty.Changed.AddClassHandler(x => x.ButtonChanged); + ThumbProperty.Changed.AddClassHandler((x,e) => x.ThumbChanged(e)); + IncreaseButtonProperty.Changed.AddClassHandler((x, e) => x.ButtonChanged(e)); + DecreaseButtonProperty.Changed.AddClassHandler((x, e) => x.ButtonChanged(e)); AffectsArrange(MinimumProperty, MaximumProperty, ValueProperty, OrientationProperty); } diff --git a/src/Avalonia.Controls/Primitives/UniformGrid.cs b/src/Avalonia.Controls/Primitives/UniformGrid.cs index f3580eee10..09554412db 100644 --- a/src/Avalonia.Controls/Primitives/UniformGrid.cs +++ b/src/Avalonia.Controls/Primitives/UniformGrid.cs @@ -28,6 +28,11 @@ namespace Avalonia.Controls.Primitives private int _rows; private int _columns; + static UniformGrid() + { + AffectsMeasure(RowsProperty, ColumnsProperty, FirstColumnProperty); + } + /// /// Specifies the row count. If set to 0, row count will be calculated automatically. /// diff --git a/src/Avalonia.Controls/ProgressBar.cs b/src/Avalonia.Controls/ProgressBar.cs index 29e3a17f74..94898951a9 100644 --- a/src/Avalonia.Controls/ProgressBar.cs +++ b/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(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal"); PseudoClass(IsIndeterminateProperty, ":indeterminate"); - ValueProperty.Changed.AddClassHandler(x => x.UpdateIndicatorWhenPropChanged); - IsIndeterminateProperty.Changed.AddClassHandler(x => x.UpdateIndicatorWhenPropChanged); + ValueProperty.Changed.AddClassHandler((x, e) => x.UpdateIndicatorWhenPropChanged(e)); + IsIndeterminateProperty.Changed.AddClassHandler((x, e) => x.UpdateIndicatorWhenPropChanged(e)); } public bool IsIndeterminate diff --git a/src/Avalonia.Controls/RepeatButton.cs b/src/Avalonia.Controls/RepeatButton.cs index 07a1e82638..a982a0970c 100644 --- a/src/Avalonia.Controls/RepeatButton.cs +++ b/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(); } } } -} \ No newline at end of file +} diff --git a/src/Avalonia.Controls/ScrollViewer.cs b/src/Avalonia.Controls/ScrollViewer.cs index c9b5cbb75b..cdf5010920 100644 --- a/src/Avalonia.Controls/ScrollViewer.cs +++ b/src/Avalonia.Controls/ScrollViewer.cs @@ -163,8 +163,8 @@ namespace Avalonia.Controls { AffectsValidation(ExtentProperty, OffsetProperty); AffectsValidation(ViewportProperty, OffsetProperty); - HorizontalScrollBarVisibilityProperty.Changed.AddClassHandler(x => x.ScrollBarVisibilityChanged); - VerticalScrollBarVisibilityProperty.Changed.AddClassHandler(x => x.ScrollBarVisibilityChanged); + HorizontalScrollBarVisibilityProperty.Changed.AddClassHandler((x, e) => x.ScrollBarVisibilityChanged(e)); + VerticalScrollBarVisibilityProperty.Changed.AddClassHandler((x, e) => x.ScrollBarVisibilityChanged(e)); } /// diff --git a/src/Avalonia.Controls/Slider.cs b/src/Avalonia.Controls/Slider.cs index 9eaa246434..f71be8d836 100644 --- a/src/Avalonia.Controls/Slider.cs +++ b/src/Avalonia.Controls/Slider.cs @@ -45,9 +45,9 @@ namespace Avalonia.Controls OrientationProperty.OverrideDefaultValue(typeof(Slider), Orientation.Horizontal); PseudoClass(OrientationProperty, o => o == Orientation.Vertical, ":vertical"); PseudoClass(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal"); - Thumb.DragStartedEvent.AddClassHandler(x => x.OnThumbDragStarted, RoutingStrategies.Bubble); - Thumb.DragDeltaEvent.AddClassHandler(x => x.OnThumbDragDelta, RoutingStrategies.Bubble); - Thumb.DragCompletedEvent.AddClassHandler(x => x.OnThumbDragCompleted, RoutingStrategies.Bubble); + Thumb.DragStartedEvent.AddClassHandler((x, e) => x.OnThumbDragStarted(e), RoutingStrategies.Bubble); + Thumb.DragDeltaEvent.AddClassHandler((x, e) => x.OnThumbDragDelta(e), RoutingStrategies.Bubble); + Thumb.DragCompletedEvent.AddClassHandler((x, e) => x.OnThumbDragCompleted(e), RoutingStrategies.Bubble); } /// diff --git a/src/Avalonia.Controls/TabControl.cs b/src/Avalonia.Controls/TabControl.cs index 50bcb034ac..61ac0822b0 100644 --- a/src/Avalonia.Controls/TabControl.cs +++ b/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 diff --git a/src/Avalonia.Controls/TabItem.cs b/src/Avalonia.Controls/TabItem.cs index 47a2348d59..fca1e022aa 100644 --- a/src/Avalonia.Controls/TabItem.cs +++ b/src/Avalonia.Controls/TabItem.cs @@ -30,8 +30,8 @@ namespace Avalonia.Controls { SelectableMixin.Attach(IsSelectedProperty); FocusableProperty.OverrideDefaultValue(typeof(TabItem), true); - IsSelectedProperty.Changed.AddClassHandler(x => x.UpdateSelectedContent); - DataContextProperty.Changed.AddClassHandler(x => x.UpdateHeader); + IsSelectedProperty.Changed.AddClassHandler((x, e) => x.UpdateSelectedContent(e)); + DataContextProperty.Changed.AddClassHandler((x, e) => x.UpdateHeader(e)); } /// diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs index c54ebd5360..293809bf51 100644 --- a/src/Avalonia.Controls/TopLevel.cs +++ b/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 /// The event args. protected virtual void OnOpened(EventArgs e) => Opened?.Invoke(this, e); + /// + /// Raises the event. + /// + /// The event args. + protected virtual void OnClosed(EventArgs e) => Closed?.Invoke(this, e); + /// /// Tries to get a service from an , logging a /// warning if not found. diff --git a/src/Avalonia.Controls/TreeViewItem.cs b/src/Avalonia.Controls/TreeViewItem.cs index c7fd96b68a..07d5497c14 100644 --- a/src/Avalonia.Controls/TreeViewItem.cs +++ b/src/Avalonia.Controls/TreeViewItem.cs @@ -54,7 +54,7 @@ namespace Avalonia.Controls SelectableMixin.Attach(IsSelectedProperty); FocusableProperty.OverrideDefaultValue(true); ItemsPanelProperty.OverrideDefaultValue(DefaultPanel); - RequestBringIntoViewEvent.AddClassHandler(x => x.OnRequestBringIntoView); + RequestBringIntoViewEvent.AddClassHandler((x, e) => x.OnRequestBringIntoView(e)); } /// diff --git a/src/Avalonia.Controls/Utils/SelectingItemsControlSelectionAdapter.cs b/src/Avalonia.Controls/Utils/SelectingItemsControlSelectionAdapter.cs index 4d814170c6..78361fcc8f 100644 --- a/src/Avalonia.Controls/Utils/SelectingItemsControlSelectionAdapter.cs +++ b/src/Avalonia.Controls/Utils/SelectingItemsControlSelectionAdapter.cs @@ -178,7 +178,7 @@ namespace Avalonia.Controls.Utils /// The event data. private void OnSelectorPointerReleased(object sender, PointerReleasedEventArgs e) { - if (e.MouseButton == MouseButton.Left) + if (e.InitialPressMouseButton == MouseButton.Left) { OnCommit(); } diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index ef43746665..1816a6c81d 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -261,13 +261,13 @@ namespace Avalonia.Controls /// /// Starts moving a window with left button being held. Should be called from left mouse button press event handler /// - public void BeginMoveDrag() => PlatformImpl?.BeginMoveDrag(); + public void BeginMoveDrag(PointerPressedEventArgs e) => PlatformImpl?.BeginMoveDrag(e); /// /// 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 /// - public void BeginResizeDrag(WindowEdge edge) => PlatformImpl?.BeginResizeDrag(edge); + public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e) => PlatformImpl?.BeginResizeDrag(edge, e); /// /// 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 } /// - protected override void HandleResized(Size clientSize) + protected sealed override void HandleResized(Size clientSize) { if (!AutoSizing) { diff --git a/src/Avalonia.Controls/WindowBase.cs b/src/Avalonia.Controls/WindowBase.cs index a47c55f87c..196110edf7 100644 --- a/src/Avalonia.Controls/WindowBase.cs +++ b/src/Avalonia.Controls/WindowBase.cs @@ -47,7 +47,7 @@ namespace Avalonia.Controls static WindowBase() { IsVisibleProperty.OverrideDefaultValue(false); - IsVisibleProperty.Changed.AddClassHandler(x => x.IsVisibleChanged); + IsVisibleProperty.Changed.AddClassHandler((x,e) => x.IsVisibleChanged(e)); TopmostProperty.Changed.AddClassHandler((w, e) => w.PlatformImpl?.SetTopmost((bool)e.NewValue)); diff --git a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs index 40524ad4b7..86e34ca6d4 100644 --- a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs +++ b/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) { } diff --git a/src/Avalonia.DesignerSupport/Remote/Stubs.cs b/src/Avalonia.DesignerSupport/Remote/Stubs.cs index 16d434b614..4bba5ef41b 100644 --- a/src/Avalonia.DesignerSupport/Remote/Stubs.cs +++ b/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 ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent) => - Task.FromResult((string[]) null); + Task.FromResult((string[])null); public Task ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent) => - Task.FromResult((string) null); + Task.FromResult((string)null); } class ScreenStub : IScreenImpl diff --git a/src/Avalonia.Input/Gestures.cs b/src/Avalonia.Input/Gestures.cs index 6b06151773..a5bd4feb64 100644 --- a/src/Avalonia.Input/Gestures.cs +++ b/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)); } } diff --git a/src/Avalonia.Input/InputElement.cs b/src/Avalonia.Input/InputElement.cs index 47e85416cf..535b930f8b 100644 --- a/src/Avalonia.Input/InputElement.cs +++ b/src/Avalonia.Input/InputElement.cs @@ -169,18 +169,18 @@ namespace Avalonia.Input { IsEnabledProperty.Changed.Subscribe(IsEnabledChanged); - GotFocusEvent.AddClassHandler(x => x.OnGotFocus); - LostFocusEvent.AddClassHandler(x => x.OnLostFocus); - KeyDownEvent.AddClassHandler(x => x.OnKeyDown); - KeyUpEvent.AddClassHandler(x => x.OnKeyUp); - TextInputEvent.AddClassHandler(x => x.OnTextInput); - PointerEnterEvent.AddClassHandler(x => x.OnPointerEnterCore); - PointerLeaveEvent.AddClassHandler(x => x.OnPointerLeaveCore); - PointerMovedEvent.AddClassHandler(x => x.OnPointerMoved); - PointerPressedEvent.AddClassHandler(x => x.OnPointerPressed); - PointerReleasedEvent.AddClassHandler(x => x.OnPointerReleased); - PointerCaptureLostEvent.AddClassHandler(x => x.OnPointerCaptureLost); - PointerWheelChangedEvent.AddClassHandler(x => x.OnPointerWheelChanged); + GotFocusEvent.AddClassHandler((x, e) => x.OnGotFocus(e)); + LostFocusEvent.AddClassHandler((x, e) => x.OnLostFocus(e)); + KeyDownEvent.AddClassHandler((x, e) => x.OnKeyDown(e)); + KeyUpEvent.AddClassHandler((x, e) => x.OnKeyUp(e)); + TextInputEvent.AddClassHandler((x, e) => x.OnTextInput(e)); + PointerEnterEvent.AddClassHandler((x, e) => x.OnPointerEnterCore(e)); + PointerLeaveEvent.AddClassHandler((x, e) => x.OnPointerLeaveCore(e)); + PointerMovedEvent.AddClassHandler((x, e) => x.OnPointerMoved(e)); + PointerPressedEvent.AddClassHandler((x, e) => x.OnPointerPressed(e)); + PointerReleasedEvent.AddClassHandler((x, e) => x.OnPointerReleased(e)); + PointerCaptureLostEvent.AddClassHandler((x, e) => x.OnPointerCaptureLost(e)); + PointerWheelChangedEvent.AddClassHandler((x, e) => x.OnPointerWheelChanged(e)); PseudoClass(IsEffectivelyEnabledProperty, x => !x, ":disabled"); PseudoClass(IsFocusedProperty, ":focus"); diff --git a/src/Avalonia.Input/MouseDevice.cs b/src/Avalonia.Input/MouseDevice.cs index 0d5471f790..c84596b913 100644 --- a/src/Avalonia.Input/MouseDevice.cs +++ b/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); diff --git a/src/Avalonia.Input/PointerEventArgs.cs b/src/Avalonia.Input/PointerEventArgs.cs index 5b3c43e4df..e12a20f7a2 100644 --- a/src/Avalonia.Input/PointerEventArgs.cs +++ b/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); + + /// + /// Returns the PointerPoint associated with the current event + /// + /// The visual which coordinate system to use. Pass null for toplevel coordinate system + /// + public PointerPoint GetCurrentPoint(IVisual relativeTo) => new PointerPoint(Pointer, GetPosition(relativeTo), _properties); + /// + /// Returns the current pointer point properties + /// 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(); + /// + /// Gets the mouse button that triggered the corresponding PointerPressed event + /// + 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 diff --git a/src/Avalonia.Input/PointerPoint.cs b/src/Avalonia.Input/PointerPoint.cs index d823a78090..e9f3c02b7f 100644 --- a/src/Avalonia.Input/PointerPoint.cs +++ b/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; + } + } } diff --git a/src/Avalonia.Input/TouchDevice.cs b/src/Avalonia.Input/TouchDevice.cs index 765e02848f..b231c9fff4 100644 --- a/src/Avalonia.Input/TouchDevice.cs +++ b/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)); } } diff --git a/src/Avalonia.Interactivity/RoutedEvent.cs b/src/Avalonia.Interactivity/RoutedEvent.cs index cfbaddb327..bc5dec9a90 100644 --- a/src/Avalonia.Interactivity/RoutedEvent.cs +++ b/src/Avalonia.Interactivity/RoutedEvent.cs @@ -113,24 +113,38 @@ namespace Avalonia.Interactivity Contract.Requires(ownerType != null); } + [Obsolete("Use overload taking Action.")] public IDisposable AddClassHandler( Func> handler, RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble, bool handledEventsToo = false) - where TTarget : class, IInteractive + where TTarget : class, IInteractive { - EventHandler 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( + Action 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); } } } diff --git a/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs b/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs index 1a22b95409..950943d54a 100644 --- a/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs +++ b/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 _menuItems = new List(); + private static Dictionary osxKeys = new Dictionary + { + {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 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); } diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index d8ff370c45..209e1bc7ea 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/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) { } diff --git a/src/Avalonia.Styling/StyledElement.cs b/src/Avalonia.Styling/StyledElement.cs index 1465b9eb85..de8093c048 100644 --- a/src/Avalonia.Styling/StyledElement.cs +++ b/src/Avalonia.Styling/StyledElement.cs @@ -73,7 +73,7 @@ namespace Avalonia /// static StyledElement() { - DataContextProperty.Changed.AddClassHandler(x => x.OnDataContextChangedCore); + DataContextProperty.Changed.AddClassHandler((x,e) => x.OnDataContextChangedCore(e)); } /// diff --git a/src/Avalonia.Visuals/Media/Geometry.cs b/src/Avalonia.Visuals/Media/Geometry.cs index 748d2526af..f9bcea85af 100644 --- a/src/Avalonia.Visuals/Media/Geometry.cs +++ b/src/Avalonia.Visuals/Media/Geometry.cs @@ -22,7 +22,7 @@ namespace Avalonia.Media static Geometry() { - TransformProperty.Changed.AddClassHandler(x => x.TransformChanged); + TransformProperty.Changed.AddClassHandler((x,e) => x.TransformChanged(e)); } /// diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs index 161cbc099e..87c9ed0bae 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs +++ b/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) diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs index f579bf0a62..d342f2eb2e 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs +++ b/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(); } diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs index 860456a838..2630f9cf96 100644 --- a/src/Avalonia.X11/X11Window.cs +++ b/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) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index e8c3177ec5..4f4c9852e8 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/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 EdgeDic = new Dictionary @@ -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)); diff --git a/tests/Avalonia.Controls.UnitTests/Platform/DefaultMenuInteractionHandlerTests.cs b/tests/Avalonia.Controls.UnitTests/Platform/DefaultMenuInteractionHandlerTests.cs index ff11bc513d..989bd744a6 100644 --- a/tests/Avalonia.Controls.UnitTests/Platform/DefaultMenuInteractionHandlerTests.cs +++ b/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 { diff --git a/tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs b/tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs index 58ee63cea4..414e67bb94 100644 --- a/tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs +++ b/tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs @@ -331,7 +331,7 @@ namespace Avalonia.Interactivity.UnitTests var target = CreateTree(ev, null, 0); - ev.AddClassHandler(x => x.ClassHandler, RoutingStrategies.Bubble); + ev.AddClassHandler((x, e) => x.ClassHandler(e), RoutingStrategies.Bubble); var args = new RoutedEventArgs(ev, target); target.RaiseEvent(args); diff --git a/tests/Avalonia.UnitTests/MouseTestHelper.cs b/tests/Avalonia.UnitTests/MouseTestHelper.cs index d6e64936c7..48c4d73471 100644 --- a/tests/Avalonia.UnitTests/MouseTestHelper.cs +++ b/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); diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs index 13bcd27240..5fd14e9ea9 100644 --- a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs +++ b/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() { diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/VisualNodeTests.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/VisualNodeTests.cs index 24ba2d1c48..3211c3397b 100644 --- a/tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/VisualNodeTests.cs +++ b/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(), null); + var child1 = new VisualNode(Mock.Of(), null); + var child2 = new VisualNode(Mock.Of(), null); + var child3 = new VisualNode(Mock.Of(), 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); + } } }