From bb8549ef94bd7ef8c81455b218fdb7af0f610b7f Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Fri, 12 Oct 2018 17:03:16 +0300 Subject: [PATCH 1/5] listbox toggle selection not working unit test #1971 --- .../ListBoxTests.cs | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs index 1debccd3c5..ebfd56027d 100644 --- a/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ListBoxTests.cs @@ -1,13 +1,11 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. -using System; -using System.Collections.ObjectModel; using System.Linq; using Avalonia.Collections; using Avalonia.Controls.Presenters; using Avalonia.Controls.Templates; -using Avalonia.Data; +using Avalonia.Input; using Avalonia.LogicalTree; using Avalonia.Styling; using Avalonia.UnitTests; @@ -196,6 +194,45 @@ namespace Avalonia.Controls.UnitTests target.Presenter.Panel.Children.Cast().Select(x => (string)x.Content)); } + [Fact] + public void Toggle_Selection_Should_Update_Containers() + { + var items = Enumerable.Range(0, 10).Select(x => $"Item {x}").ToArray(); + var target = new ListBox + { + Template = ListBoxTemplate(), + Items = items, + SelectionMode = SelectionMode.Toggle, + ItemTemplate = new FuncDataTemplate(x => new TextBlock { Height = 10 }) + }; + + Prepare(target); + + var lbItems = target.GetLogicalChildren().OfType().ToArray(); + + var item = lbItems[0]; + + Assert.Equal(false, item.IsSelected); + + RaisePressedEvent(target, item, MouseButton.Left); + + Assert.Equal(true, item.IsSelected); + + RaisePressedEvent(target, item, MouseButton.Left); + + Assert.Equal(false, item.IsSelected); + } + + private void RaisePressedEvent(ListBox listBox, ListBoxItem item, MouseButton mouseButton) + { + listBox.RaiseEvent(new PointerPressedEventArgs + { + Source = item, + RoutedEvent = InputElement.PointerPressedEvent, + MouseButton = mouseButton + }); + } + private FuncControlTemplate ListBoxTemplate() { return new FuncControlTemplate(parent => From 889156df434cd59eccf267101ea470e68e62ab4e Mon Sep 17 00:00:00 2001 From: Andrey Kunchev Date: Tue, 16 Oct 2018 01:09:43 +0300 Subject: [PATCH 2/5] fixes #1971 listbox toggle selection --- .../Primitives/SelectingItemsControl.cs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs index f8440aac47..ccbdc71b1d 100644 --- a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs +++ b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs @@ -62,7 +62,7 @@ namespace Avalonia.Controls.Primitives AvaloniaProperty.RegisterDirect( nameof(SelectedItem), o => o.SelectedItem, - (o, v) => o.SelectedItem = v, + (o, v) => o.SelectedItem = v, defaultBindingMode: BindingMode.TwoWay); /// @@ -88,7 +88,7 @@ namespace Avalonia.Controls.Primitives /// public static readonly RoutedEvent IsSelectedChangedEvent = RoutedEvent.Register( - "IsSelectedChanged", + "IsSelectedChanged", RoutingStrategies.Bubble); /// @@ -96,7 +96,7 @@ namespace Avalonia.Controls.Primitives /// public static readonly RoutedEvent SelectionChangedEvent = RoutedEvent.Register( - "SelectionChanged", + "SelectionChanged", RoutingStrategies.Bubble); private static readonly IList Empty = new object[0]; @@ -521,7 +521,7 @@ namespace Avalonia.Controls.Primitives else if (multi && range) { SynchronizeItems( - SelectedItems, + SelectedItems, GetRange(Items, SelectedIndex, index)); } else @@ -583,7 +583,7 @@ namespace Avalonia.Controls.Primitives } /// - /// Updates the selection based on an event that may have originated in a container that + /// Updates the selection based on an event that may have originated in a container that /// belongs to the control. /// /// The control that raised the event. @@ -595,7 +595,7 @@ namespace Avalonia.Controls.Primitives /// false. /// protected bool UpdateSelectionFromEventSource( - IInteractive eventSource, + IInteractive eventSource, bool select = true, bool rangeModifier = false, bool toggleModifier = false) @@ -807,12 +807,10 @@ namespace Avalonia.Controls.Primitives SelectedIndex = -1; } } - else + + foreach (var item in e.OldItems) { - foreach (var item in e.OldItems) - { - MarkItemSelected(item, false); - } + MarkItemSelected(item, false); } removed = e.OldItems; From 3a9967f4988b4aeae4980064ba8f9a2296959524 Mon Sep 17 00:00:00 2001 From: Tom Daffin Date: Sun, 21 Oct 2018 08:06:27 -0600 Subject: [PATCH 3/5] Map GdkKey.grave to Key.OemTilde --- src/Gtk/Avalonia.Gtk3/KeyTransform.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Gtk/Avalonia.Gtk3/KeyTransform.cs b/src/Gtk/Avalonia.Gtk3/KeyTransform.cs index ae85d618d1..a62b611df1 100644 --- a/src/Gtk/Avalonia.Gtk3/KeyTransform.cs +++ b/src/Gtk/Avalonia.Gtk3/KeyTransform.cs @@ -185,8 +185,8 @@ namespace Avalonia.Gtk.Common { GdkKey.comma, Key.OemComma }, { GdkKey.minus, Key.OemMinus }, { GdkKey.period, Key.OemPeriod }, - { GdkKey.slash, Key.Oem2 } - //{ GdkKey.?, Key.OemTilde } + { GdkKey.slash, Key.Oem2 }, + { GdkKey.grave, Key.OemTilde }, //{ GdkKey.?, Key.AbntC1 } //{ GdkKey.?, Key.AbntC2 } //{ GdkKey.?, Key.Oem4 } From 376b48ef4d1b4cdaa30b471fba30b8f38292b528 Mon Sep 17 00:00:00 2001 From: Tom Daffin Date: Wed, 24 Oct 2018 05:21:24 -0600 Subject: [PATCH 4/5] Map some more Gdk keys --- src/Gtk/Avalonia.Gtk3/KeyTransform.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Gtk/Avalonia.Gtk3/KeyTransform.cs b/src/Gtk/Avalonia.Gtk3/KeyTransform.cs index a62b611df1..07037de40b 100644 --- a/src/Gtk/Avalonia.Gtk3/KeyTransform.cs +++ b/src/Gtk/Avalonia.Gtk3/KeyTransform.cs @@ -14,6 +14,7 @@ namespace Avalonia.Gtk.Common { GdkKey.Linefeed, Key.LineFeed }, { GdkKey.Clear, Key.Clear }, { GdkKey.Return, Key.Return }, + { GdkKey.KP_Enter, Key.Return }, { GdkKey.Pause, Key.Pause }, { GdkKey.Caps_Lock, Key.CapsLock }, //{ GdkKey.?, Key.HangulMode } @@ -112,7 +113,7 @@ namespace Avalonia.Gtk.Common { GdkKey.z, Key.Z }, //{ GdkKey.?, Key.LWin } //{ GdkKey.?, Key.RWin } - //{ GdkKey.?, Key.Apps } + { GdkKey.Menu, Key.Apps }, //{ GdkKey.?, Key.Sleep } { GdkKey.KP_0, Key.NumPad0 }, { GdkKey.KP_1, Key.NumPad1 }, @@ -125,11 +126,12 @@ namespace Avalonia.Gtk.Common { GdkKey.KP_8, Key.NumPad8 }, { GdkKey.KP_9, Key.NumPad9 }, { GdkKey.multiply, Key.Multiply }, - //{ GdkKey.?, Key.Add } + { GdkKey.KP_Multiply, Key.Multiply }, + { GdkKey.KP_Add, Key.Add }, //{ GdkKey.?, Key.Separator } - //{ GdkKey.?, Key.Subtract } + { GdkKey.KP_Subtract, Key.Subtract }, //{ GdkKey.?, Key.Decimal } - //{ GdkKey.?, Key.Divide } + { GdkKey.KP_Divide, Key.Divide }, { GdkKey.F1, Key.F1 }, { GdkKey.F2, Key.F2 }, { GdkKey.F3, Key.F3 }, @@ -182,6 +184,7 @@ namespace Avalonia.Gtk.Common //{ GdkKey.?, Key.LaunchApplication2 } { GdkKey.semicolon, Key.OemSemicolon }, { GdkKey.plus, Key.OemPlus }, + { GdkKey.equal, Key.OemPlus }, { GdkKey.comma, Key.OemComma }, { GdkKey.minus, Key.OemMinus }, { GdkKey.period, Key.OemPeriod }, @@ -189,10 +192,10 @@ namespace Avalonia.Gtk.Common { GdkKey.grave, Key.OemTilde }, //{ GdkKey.?, Key.AbntC1 } //{ GdkKey.?, Key.AbntC2 } - //{ GdkKey.?, Key.Oem4 } - //{ GdkKey.?, Key.OemPipe } - //{ GdkKey.?, Key.OemCloseBrackets } - //{ GdkKey.?, Key.Oem7 } + { GdkKey.bracketleft, Key.OemOpenBrackets }, + { GdkKey.backslash, Key.OemPipe }, + { GdkKey.bracketright, Key.OemCloseBrackets }, + { GdkKey.apostrophe, Key.OemQuotes }, //{ GdkKey.?, Key.Oem8 } //{ GdkKey.?, Key.Oem102 } //{ GdkKey.?, Key.ImeProcessed } From 82c17b95824ad3272df1b775435a939e620607a0 Mon Sep 17 00:00:00 2001 From: Tom Daffin Date: Wed, 24 Oct 2018 09:01:00 -0600 Subject: [PATCH 5/5] Map some more GdkKeys --- src/Gtk/Avalonia.Gtk3/KeyTransform.cs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Gtk/Avalonia.Gtk3/KeyTransform.cs b/src/Gtk/Avalonia.Gtk3/KeyTransform.cs index 07037de40b..4299e07094 100644 --- a/src/Gtk/Avalonia.Gtk3/KeyTransform.cs +++ b/src/Gtk/Avalonia.Gtk3/KeyTransform.cs @@ -28,7 +28,9 @@ namespace Avalonia.Gtk.Common //{ GdkKey.?, Key.ImeModeChange } { GdkKey.space, Key.Space }, { GdkKey.Prior, Key.Prior }, + { GdkKey.KP_Prior, Key.Prior }, { GdkKey.Page_Down, Key.PageDown }, + { GdkKey.KP_Page_Down, Key.PageDown }, { GdkKey.End, Key.End }, { GdkKey.KP_End, Key.End }, { GdkKey.Home, Key.Home }, @@ -46,19 +48,20 @@ namespace Avalonia.Gtk.Common { GdkKey.Execute, Key.Execute }, //{ GdkKey.?, Key.Snapshot } { GdkKey.Insert, Key.Insert }, + { GdkKey.KP_Insert, Key.Insert }, { GdkKey.Delete, Key.Delete }, { GdkKey.KP_Delete, Key.Delete }, { GdkKey.Help, Key.Help }, - //{ GdkKey.?, Key.D0 } - //{ GdkKey.?, Key.D1 } - //{ GdkKey.?, Key.D2 } - //{ GdkKey.?, Key.D3 } - //{ GdkKey.?, Key.D4 } - //{ GdkKey.?, Key.D5 } - //{ GdkKey.?, Key.D6 } - //{ GdkKey.?, Key.D7 } - //{ GdkKey.?, Key.D8 } - //{ GdkKey.?, Key.D9 } + { GdkKey.Key_0, Key.D0 }, + { GdkKey.Key_1, Key.D1 }, + { GdkKey.Key_2, Key.D2 }, + { GdkKey.Key_3, Key.D3 }, + { GdkKey.Key_4, Key.D4 }, + { GdkKey.Key_5, Key.D5 }, + { GdkKey.Key_6, Key.D6 }, + { GdkKey.Key_7, Key.D7 }, + { GdkKey.Key_8, Key.D8 }, + { GdkKey.Key_9, Key.D9 }, { GdkKey.A, Key.A }, { GdkKey.B, Key.B }, { GdkKey.C, Key.C }, @@ -130,7 +133,7 @@ namespace Avalonia.Gtk.Common { GdkKey.KP_Add, Key.Add }, //{ GdkKey.?, Key.Separator } { GdkKey.KP_Subtract, Key.Subtract }, - //{ GdkKey.?, Key.Decimal } + { GdkKey.KP_Decimal, Key.Decimal }, { GdkKey.KP_Divide, Key.Divide }, { GdkKey.F1, Key.F1 }, { GdkKey.F2, Key.F2 },