From 152982701d66d7174189dcaecb6b773a6e11df4d Mon Sep 17 00:00:00 2001 From: Vsevolod Kukol Date: Mon, 11 Nov 2019 11:22:57 +0100 Subject: [NuGet] Reduce custom rendering in package selection list * Use regular check box cell view to select packages * Remove custom background rendering --- .../ManagePackagesCellView.cs | 167 +-------------------- .../ManagePackagesCellViewCheckBox.cs | 91 ----------- .../ManagePackagesDialog.cs | 81 +++++----- .../MonoDevelop.PackageManagement.csproj | 1 - 4 files changed, 39 insertions(+), 301 deletions(-) delete mode 100644 main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesCellViewCheckBox.cs (limited to 'main/src/addins') diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesCellView.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesCellView.cs index 09611a1daa..42321ab5ce 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesCellView.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesCellView.cs @@ -40,12 +40,6 @@ namespace MonoDevelop.PackageManagement { CellWidth = 260; - BackgroundColor = Styles.CellBackgroundColor; - StrongSelectionColor = Styles.CellStrongSelectionColor; - SelectionColor = Styles.CellSelectionColor; - - UseStrongSelectionColor = true; - if (Platform.IsWindows) { packageIdFontSize = 10; packageDescriptionFontSize = 9; @@ -57,19 +51,9 @@ namespace MonoDevelop.PackageManagement public IDataField PackageField { get; set; } public IDataField ImageField { get; set; } - public IDataField HasBackgroundColorField { get; set; } - public IDataField CheckBoxAlphaField { get; set; } public double CellWidth { get; set; } - public Color BackgroundColor { get; set; } - public Color StrongSelectionColor { get; set; } - public Color SelectionColor { get; set; } - - public bool UseStrongSelectionColor { get; set; } - - public event EventHandler PackageChecked; - protected override void OnDraw (Context ctx, Rectangle cellArea) { ManagePackagesSearchResultViewModel packageViewModel = GetValue (PackageField); @@ -77,10 +61,8 @@ namespace MonoDevelop.PackageManagement return; } - FillCellBackground (ctx); UpdateTextColor (ctx); - DrawCheckBox (ctx, packageViewModel, cellArea); DrawPackageImage (ctx, cellArea); double packageIdWidth = cellArea.Width - packageDescriptionPadding.HorizontalSpacing - packageDescriptionLeftOffset; @@ -134,108 +116,6 @@ namespace MonoDevelop.PackageManagement } } - void FillCellBackground (Context ctx) - { - if (Selected) { - FillCellBackground (ctx, GetSelectedColor ()); - } else if (IsBackgroundColorFieldSet ()) { - FillCellBackground (ctx, BackgroundColor); - } - } - - Color GetSelectedColor () - { - if (UseStrongSelectionColor) { - return StrongSelectionColor; - } - return SelectionColor; - } - - bool IsBackgroundColorFieldSet () - { - return GetValue (HasBackgroundColorField, false); - } - - void FillCellBackground (Context ctx, Color color) - { - ctx.Rectangle (BackgroundBounds); - ctx.SetColor (color); - ctx.Fill (); - } - - void DrawCheckBox (Context ctx, ManagePackagesSearchResultViewModel packageViewModel, Rectangle cellArea) - { - CreateCheckboxImages (); - - Image image = GetCheckBoxImage (packageViewModel.IsChecked); - double alpha = GetCheckBoxImageAlpha (); - ctx.DrawImage ( - image, - cellArea.Left + checkBoxPadding.Left, - cellArea.Top + ((cellArea.Height - checkBoxImageSize.Height - 2) / 2), - alpha); - } - - void CreateCheckboxImages () - { - if (whiteCheckedCheckBoxImage != null) - return; - - var widget = Toolkit.CurrentEngine.GetNativeWidget (ParentWidget); - var checkbox = new ManagePackagesCellViewCheckBox (ParentWidget.ParentWindow.Screen.ScaleFactor); - checkbox.Container = (Gtk.Widget)widget; - checkbox.Size = (int)checkBoxImageSize.Width + 1; - - // White checkbox. - whiteUncheckedCheckBoxImage = checkbox.CreateImage (); - checkbox.Active = true; - whiteCheckedCheckBoxImage = checkbox.CreateImage (); - - // Odd numbered checkbox. - checkbox.BackgroundColor = BackgroundColor; - checkedCheckBoxWithBackgroundColorImage = checkbox.CreateImage (); - checkbox.Active = false; - uncheckedCheckBoxWithBackgroundColorImage = checkbox.CreateImage (); - - // Grey check box. - checkbox.BackgroundColor = SelectionColor; - greyUncheckedCheckBoxImage = checkbox.CreateImage (); - checkbox.Active = true; - greyCheckedCheckBoxImage = checkbox.CreateImage (); - - // Blue check box. - checkbox.BackgroundColor = StrongSelectionColor; - blueCheckedCheckBoxImage = checkbox.CreateImage (); - checkbox.Active = false; - blueUncheckedCheckBoxImage = checkbox.CreateImage (); - } - - double GetCheckBoxImageAlpha () - { - return GetValue (CheckBoxAlphaField, 1); - } - - Image GetCheckBoxImage (bool checkBoxActive) - { - if (Selected && UseStrongSelectionColor && checkBoxActive) { - return blueCheckedCheckBoxImage; - } else if (Selected && checkBoxActive) { - return greyCheckedCheckBoxImage; - } else if (Selected && UseStrongSelectionColor) { - return blueUncheckedCheckBoxImage; - } else if (Selected) { - return greyUncheckedCheckBoxImage; - } else if (checkBoxActive && IsBackgroundColorFieldSet ()) { - return checkedCheckBoxWithBackgroundColorImage; - } else if (checkBoxActive) { - return whiteCheckedCheckBoxImage; - } else if (IsBackgroundColorFieldSet ()) { - return uncheckedCheckBoxWithBackgroundColorImage; - } else { - return whiteUncheckedCheckBoxImage; - } - } - void DrawPackageImage (Context ctx, Rectangle cellArea) { Image image = GetValue (ImageField); @@ -251,7 +131,7 @@ namespace MonoDevelop.PackageManagement Point imageLocation = GetPackageImageLocation (maxPackageImageSize, cellArea); ctx.DrawImage ( image, - cellArea.Left + packageImagePadding.Left + checkBoxAreaWidth + imageLocation.X, + cellArea.Left + packageImagePadding.Left + imageLocation.X, Math.Round( cellArea.Top + packageImagePadding.Top + imageLocation.Y), maxPackageImageSize.Width, maxPackageImageSize.Height); @@ -259,7 +139,7 @@ namespace MonoDevelop.PackageManagement Point imageLocation = GetPackageImageLocation (image.Size, cellArea); ctx.DrawImage ( image, - cellArea.Left + packageImagePadding.Left + checkBoxAreaWidth + imageLocation.X, + cellArea.Left + packageImagePadding.Left + imageLocation.X, Math.Round (cellArea.Top + packageImagePadding.Top + imageLocation.Y)); } } @@ -285,54 +165,17 @@ namespace MonoDevelop.PackageManagement return new Size (CellWidth, size.Height * linesDisplayedCount + packageDescriptionPaddingHeight + packageDescriptionPadding.VerticalSpacing); } - protected override void OnButtonPressed (ButtonEventArgs args) - { - ManagePackagesSearchResultViewModel packageViewModel = GetValue (PackageField); - if (packageViewModel == null) { - base.OnButtonPressed (args); - return; - } - - double x = args.X - Bounds.X; - double y = args.Y - Bounds.Y; - - if (checkBoxImageClickableRectangle.Contains (x, y)) { - packageViewModel.IsChecked = !packageViewModel.IsChecked; - OnPackageChecked (packageViewModel); - } - } - - void OnPackageChecked (ManagePackagesSearchResultViewModel packageViewModel) - { - if (PackageChecked != null) { - PackageChecked (this, new ManagePackagesCellViewEventArgs (packageViewModel)); - } - } - const int packageDescriptionPaddingHeight = 5; const int packageIdRightHandPaddingWidth = 5; const int linesDisplayedCount = 4; - const int checkBoxAreaWidth = 36; const int packageImageAreaWidth = 54; - const int packageDescriptionLeftOffset = checkBoxAreaWidth + packageImageAreaWidth + 8; + const int packageDescriptionLeftOffset = packageImageAreaWidth + 8; - WidgetSpacing packageDescriptionPadding = new WidgetSpacing (5, 5, 5, 10); - WidgetSpacing packageImagePadding = new WidgetSpacing (0, 0, 0, 5); - WidgetSpacing checkBoxPadding = new WidgetSpacing (10, 0, 0, 10); + WidgetSpacing packageDescriptionPadding = new WidgetSpacing (5, 5, 5, 5); + WidgetSpacing packageImagePadding = new WidgetSpacing (0, 0, 0, 0); Size maxPackageImageSize = new Size (48, 48); - Size checkBoxImageSize = new Size (16, 16); - Rectangle checkBoxImageClickableRectangle = new Rectangle (0, 10, 40, 50); - - Image whiteCheckedCheckBoxImage; - Image whiteUncheckedCheckBoxImage; - Image greyCheckedCheckBoxImage; - Image greyUncheckedCheckBoxImage; - Image blueCheckedCheckBoxImage; - Image blueUncheckedCheckBoxImage; - Image checkedCheckBoxWithBackgroundColorImage; - Image uncheckedCheckBoxWithBackgroundColorImage; static readonly Image defaultPackageImage = Image.FromResource (typeof(ManagePackagesCellView), "package-48.png"); } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesCellViewCheckBox.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesCellViewCheckBox.cs deleted file mode 100644 index c137669b79..0000000000 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesCellViewCheckBox.cs +++ /dev/null @@ -1,91 +0,0 @@ -// -// ManagePackagesCellViewCheckBox.cs -// -// Author: -// Matt Ward -// -// Copyright (c) 2014 Xamarin Inc. (http://xamarin.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using MonoDevelop.Components; -using Gtk; - -namespace MonoDevelop.PackageManagement -{ - internal class ManagePackagesCellViewCheckBox - { - static int indicatorSize; - static int indicatorSpacing; - double scaleFactor; - - static ManagePackagesCellViewCheckBox () - { - var cb = new Gtk.CheckButton (); - indicatorSize = (int) cb.StyleGetProperty ("indicator-size"); - indicatorSpacing = (int) cb.StyleGetProperty ("indicator-spacing"); - } - - public ManagePackagesCellViewCheckBox (double scaleFactor) - { - this.scaleFactor = scaleFactor; - Size = indicatorSize; - BackgroundColor = Xwt.Drawing.Colors.White; - } - - public int Size { get; set; } - public bool Active { get; set; } - public Widget Container { get; set; } - public Xwt.Drawing.Color BackgroundColor { get; set; } - - public Xwt.Drawing.Image CreateImage () - { - var bounds = new Gdk.Rectangle (0, 0, (int)(Size * scaleFactor), (int)(Size * scaleFactor)); - return CreatePixBuf (bounds).ToXwtImage ().WithSize (Size, Size); - } - - Gdk.Pixbuf CreatePixBuf (Gdk.Rectangle bounds) - { - using (var pmap = new Gdk.Pixmap (Container.GdkWindow, bounds.Width, bounds.Height)) { - using (Cairo.Context ctx = Gdk.CairoHelper.Create (pmap)) { - ctx.Rectangle (0, 0, bounds.Width, bounds.Height); - ctx.SetSourceRGBA (BackgroundColor.Red, BackgroundColor.Green, BackgroundColor.Blue, BackgroundColor.Alpha); - ctx.Paint (); - - Render (pmap, bounds, Gtk.StateType.Normal); - return Gdk.Pixbuf.FromDrawable (pmap, pmap.Colormap, 0, 0, 0, 0, bounds.Width, bounds.Height); - } - } - } - - void Render (Gdk.Drawable window, Gdk.Rectangle bounds, Gtk.StateType state) - { - Gtk.ShadowType sh = (bool) Active ? Gtk.ShadowType.In : Gtk.ShadowType.Out; - int s = (int)(scaleFactor * Size) - 1; - if (s > bounds.Height) - s = bounds.Height; - if (s > bounds.Width) - s = bounds.Width; - - Gtk.Style.PaintCheck (Container.Style, window, state, sh, bounds, Container, "checkbutton", bounds.X + indicatorSpacing - 1, bounds.Y + (bounds.Height - s)/2, s, s); - } - } -} - diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs index 7a64ec70bd..361becc59e 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs @@ -42,13 +42,12 @@ namespace MonoDevelop.PackageManagement IBackgroundPackageActionRunner backgroundActionRunner; ManagePackagesViewModel viewModel; List packageSources; - DataField packageHasBackgroundColorField = new DataField (); DataField packageViewModelField = new DataField (); DataField packageImageField = new DataField (); - DataField packageCheckBoxAlphaField = new DataField (); - const double packageCheckBoxSemiTransarentAlpha = 0.6; + DataField packageCheckBoxField = new DataField (); ListStore packageStore; ManagePackagesCellView packageCellView; + CheckBoxCellView packageCheckView; TimeSpan searchDelayTimeSpan = TimeSpan.FromMilliseconds (500); IDisposable searchTimer; SourceRepositoryViewModel dummyPackageSourceRepresentingConfigureSettingsItem = @@ -154,29 +153,45 @@ namespace MonoDevelop.PackageManagement void InitializeListView () { - packageStore = new ListStore (packageHasBackgroundColorField, packageCheckBoxAlphaField, packageImageField, packageViewModelField); + packageStore = new ListStore (packageImageField, packageViewModelField, packageCheckBoxField); packagesListView.DataSource = packageStore; - AddPackageCellViewToListView (); - + AddCellViewsToListView (); + packagesListView.SelectionChanged += PackagesListViewSelectionChanged; packagesListView.RowActivated += PackagesListRowActivated; packagesListView.VerticalScrollControl.ValueChanged += PackagesListViewScrollValueChanged; + + if (Toolkit.CurrentEngine.Type == ToolkitType.Gtk) { + // TODO: unlike Xwt.TreeView, Xwt.ListView has no UseAlternatingRowColors property + var gtkTreeView = packagesListView.Surface.NativeWidget as Gtk.Widget; + if (gtkTreeView is Gtk.ScrolledWindow scroll) + gtkTreeView = scroll.Child; + if (gtkTreeView is Gtk.TreeView tree) + tree.RulesHint = true; + } } - void AddPackageCellViewToListView () + void AddCellViewsToListView () { + var checkColumn = new ListViewColumn (GettextCatalog.GetString ("Add Package")); + + packageCheckView = new CheckBoxCellView (packageCheckBoxField) { Editable = true }; + packageCheckView.Toggled += PackageCheckCellViewPackageChecked; + + // HACK: Xwt has no custom cell padding, so we need to add an empty label for spacing + checkColumn.Views.Add (new TextCellView (" ")); + checkColumn.Views.Add (packageCheckView); + packagesListView.Columns.Add (checkColumn); + packageCellView = new ManagePackagesCellView { PackageField = packageViewModelField, - HasBackgroundColorField = packageHasBackgroundColorField, - CheckBoxAlphaField = packageCheckBoxAlphaField, ImageField = packageImageField, - CellWidth = 467 + CellWidth = 446 }; + var textColumn = new ListViewColumn ("Package", packageCellView); packagesListView.Columns.Add (textColumn); - - packageCellView.PackageChecked += PackageCellViewPackageChecked; } void InitializeProjectsListView () @@ -528,7 +543,6 @@ namespace MonoDevelop.PackageManagement { packageStore.Clear (); ResetPackagesListViewScroll (); - UpdatePackageListViewSelectionColor (); ShowLoadingMessage (); ShrinkImageCache (); DisposePopulatePackageVersionsTimer (); @@ -578,8 +592,6 @@ namespace MonoDevelop.PackageManagement void AppendPackageToListView (ManagePackagesSearchResultViewModel packageViewModel) { int row = packageStore.AddRow (); - packageStore.SetValue (row, packageHasBackgroundColorField, IsOddRow (row)); - packageStore.SetValue (row, packageCheckBoxAlphaField, GetPackageCheckBoxAlpha ()); packageStore.SetValue (row, packageViewModelField, packageViewModel); } @@ -595,14 +607,6 @@ namespace MonoDevelop.PackageManagement return (row % 2) == 0; } - double GetPackageCheckBoxAlpha () - { - if (PackagesCheckedCount == 0) { - return packageCheckBoxSemiTransarentAlpha; - } - return 1; - } - void ImageLoaded (object sender, ImageLoadedEventArgs e) { if (!e.HasError) { @@ -841,11 +845,17 @@ namespace MonoDevelop.PackageManagement return false; } + void PackageCheckCellViewPackageChecked (object sender, WidgetEventArgs e) + { + PackagesListRowActivated (sender, new ListViewRowEventArgs (packagesListView.CurrentEventRow)); + } + void PackagesListRowActivated (object sender, ListViewRowEventArgs e) { ManagePackagesSearchResultViewModel packageViewModel = packageStore.GetValue (e.RowIndex, packageViewModelField); packageViewModel.IsChecked = !packageViewModel.IsChecked; - PackageCellViewPackageChecked (null, null); + packageStore.SetValue (e.RowIndex, packageCheckBoxField, packageViewModel.IsChecked); + UpdateAddPackagesButton (); } void PackagesListViewScrollValueChanged (object sender, EventArgs e) @@ -870,13 +880,6 @@ namespace MonoDevelop.PackageManagement return (currentValue / (maxValue - pageSize)) > 0.7; } - void PackageCellViewPackageChecked (object sender, ManagePackagesCellViewEventArgs e) - { - UpdateAddPackagesButton (); - UpdatePackageListViewSelectionColor (); - UpdatePackageListViewCheckBoxAlpha (); - } - void UpdateAddPackagesButton () { addPackagesButton.Label = GetAddPackagesButtonLabel (); @@ -911,22 +914,6 @@ namespace MonoDevelop.PackageManagement return 1; } - void UpdatePackageListViewSelectionColor () - { - packageCellView.UseStrongSelectionColor = (PackagesCheckedCount == 0); - } - - void UpdatePackageListViewCheckBoxAlpha () - { - if (PackagesCheckedCount > 1) - return; - - double alpha = GetPackageCheckBoxAlpha (); - for (int row = 0; row < packageStore.RowCount; ++row) { - packageStore.SetValue (row, packageCheckBoxAlphaField, alpha); - } - } - bool OlderPackageInstalledThanPackageSelected () { if (PackagesCheckedCount != 0) { diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj index f72ad6522d..4ea333473e 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj @@ -146,7 +146,6 @@ - -- cgit v1.2.3 From 908e8476906befb48acf06f053ba0478043569b0 Mon Sep 17 00:00:00 2001 From: Vsevolod Kukol Date: Mon, 11 Nov 2019 12:54:05 +0100 Subject: [NuGet] Make package selection list view accessible Fixes VSTS #750376 --- .../AccessibleSpacerCellView.cs | 39 ++++++++++++++++++++++ .../ManagePackagesDialog.cs | 21 ++++++++++-- .../MonoDevelop.PackageManagement.csproj | 1 + 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/AccessibleSpacerCellView.cs (limited to 'main/src/addins') diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/AccessibleSpacerCellView.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/AccessibleSpacerCellView.cs new file mode 100644 index 0000000000..2b7dffa826 --- /dev/null +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/AccessibleSpacerCellView.cs @@ -0,0 +1,39 @@ +// +// AccessibleSpacerCellView.cs +// +// Author: +// Vsevolod Kukol +// +// Copyright (c) 2019 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using Xwt; + +namespace MonoDevelop.PackageManagement +{ + class AccessibleSpacerCellView : CanvasCellView + { + static Size size = new Size (5, 5); + + protected override Size OnGetRequiredSize (SizeConstraint widthConstraint) + { + return size; + } + } +} diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs index 361becc59e..603de55a95 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs @@ -45,6 +45,8 @@ namespace MonoDevelop.PackageManagement DataField packageViewModelField = new DataField (); DataField packageImageField = new DataField (); DataField packageCheckBoxField = new DataField (); + DataField packageCheckA11yField = new DataField (); + DataField packageDescriptionA11yField = new DataField (); ListStore packageStore; ManagePackagesCellView packageCellView; CheckBoxCellView packageCheckView; @@ -153,7 +155,7 @@ namespace MonoDevelop.PackageManagement void InitializeListView () { - packageStore = new ListStore (packageImageField, packageViewModelField, packageCheckBoxField); + packageStore = new ListStore (packageImageField, packageViewModelField, packageCheckBoxField, packageCheckA11yField, packageDescriptionA11yField); packagesListView.DataSource = packageStore; AddCellViewsToListView (); @@ -177,10 +179,13 @@ namespace MonoDevelop.PackageManagement var checkColumn = new ListViewColumn (GettextCatalog.GetString ("Add Package")); packageCheckView = new CheckBoxCellView (packageCheckBoxField) { Editable = true }; + packageCheckView.AccessibleFields.Label = packageCheckA11yField; packageCheckView.Toggled += PackageCheckCellViewPackageChecked; // HACK: Xwt has no custom cell padding, so we need to add an empty label for spacing - checkColumn.Views.Add (new TextCellView (" ")); + var spaceText = new AccessibleSpacerCellView (); + spaceText.AccessibleFields.Label = packageCheckA11yField; + checkColumn.Views.Add (spaceText); checkColumn.Views.Add (packageCheckView); packagesListView.Columns.Add (checkColumn); @@ -189,6 +194,7 @@ namespace MonoDevelop.PackageManagement ImageField = packageImageField, CellWidth = 446 }; + packageCellView.AccessibleFields.Label = packageDescriptionA11yField; var textColumn = new ListViewColumn ("Package", packageCellView); packagesListView.Columns.Add (textColumn); @@ -592,7 +598,16 @@ namespace MonoDevelop.PackageManagement void AppendPackageToListView (ManagePackagesSearchResultViewModel packageViewModel) { int row = packageStore.AddRow (); - packageStore.SetValue (row, packageViewModelField, packageViewModel); + var accessibleDescription = StringBuilderCache.Allocate (packageViewModel.Id); + if (packageViewModel.HasDownloadCount) + accessibleDescription.Append (", ").Append (packageViewModel.GetDownloadCountDisplayText ()).Append (" ").Append (GettextCatalog.GetString ("Downloads")); + if (!string.IsNullOrEmpty (packageViewModel.Summary)) + accessibleDescription.Append (", ").Append (packageViewModel.Summary); + packageStore.SetValues (row, + packageViewModelField, packageViewModel, + packageCheckBoxField, packageViewModel.IsChecked, + packageCheckA11yField, packageViewModel.Name, + packageDescriptionA11yField, StringBuilderCache.ReturnAndFree (accessibleDescription)); } void LoadPackageImage (int row, ManagePackagesSearchResultViewModel packageViewModel) diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj index 4ea333473e..1065766e15 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj @@ -348,6 +348,7 @@ + -- cgit v1.2.3 From c2d72bd296745847f794cdd03d4fe4ebd2f91e88 Mon Sep 17 00:00:00 2001 From: Vsevolod Kukol Date: Mon, 11 Nov 2019 17:22:11 +0100 Subject: [NuGet] Make header labels accessible --- .../ManagePackagesDialog.UI.cs | 9 ++++ .../ManagePackagesDialog.cs | 50 ++++++++++++++++++++-- 2 files changed, 55 insertions(+), 4 deletions(-) (limited to 'main/src/addins') diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.UI.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.UI.cs index c47a39aaf4..56a610a238 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.UI.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.UI.cs @@ -105,24 +105,33 @@ namespace MonoDevelop.PackageManagement browseLabel.Tag = browseLabel.Text; browseLabel.MinWidth = tabLabelMinWidth; browseLabel.MarginLeft = 10; + browseLabel.CanGetFocus = true; + browseLabel.Accessible.Role = Xwt.Accessibility.Role.Button; + topHBox.PackStart (browseLabel); installedLabel = new Label (); installedLabel.Text = GettextCatalog.GetString ("Installed"); installedLabel.Tag = installedLabel.Text; installedLabel.MinWidth = tabLabelMinWidth; + installedLabel.CanGetFocus = true; + installedLabel.Accessible.Role = Xwt.Accessibility.Role.Button; topHBox.PackStart (installedLabel); updatesLabel = new Label (); updatesLabel.Text = GettextCatalog.GetString ("Updates"); updatesLabel.Tag = updatesLabel.Text; updatesLabel.MinWidth = tabLabelMinWidth; + updatesLabel.CanGetFocus = true; + updatesLabel.Accessible.Role = Xwt.Accessibility.Role.Button; topHBox.PackStart (updatesLabel); consolidateLabel = new Label (); consolidateLabel.Text = GettextCatalog.GetString ("Consolidate"); consolidateLabel.Tag = consolidateLabel.Text; consolidateLabel.MinWidth = tabLabelMinWidth; + consolidateLabel.CanGetFocus = true; + consolidateLabel.Accessible.Role = Xwt.Accessibility.Role.Button; topHBox.PackStart (consolidateLabel); packageSearchEntry = new SearchTextEntry (); diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs index 603de55a95..a78b0b49d7 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs @@ -106,9 +106,13 @@ namespace MonoDevelop.PackageManagement imageLoader.Loaded += ImageLoaded; browseLabel.ButtonPressed += BrowseLabelButtonPressed; + browseLabel.KeyPressed += BrowseLabelKeyPressed; installedLabel.ButtonPressed += InstalledLabelButtonPressed; + installedLabel.KeyPressed += InstalledLabelKeyPressed; updatesLabel.ButtonPressed += UpdatesLabelButtonPressed; + updatesLabel.KeyPressed += UpdatesLabelKeyPressed; consolidateLabel.ButtonPressed += ConsolidateLabelButtonPressed; + consolidateLabel.KeyPressed += ConsolidateLabelKeyPressed; } public bool ShowPreferencesForPackageSources { get; private set; } @@ -1097,30 +1101,68 @@ namespace MonoDevelop.PackageManagement } } - void BrowseLabelButtonPressed (object sender, ButtonEventArgs e) + void UpdatePackageResultsLabel (ManagePackagesPage page, Button label) + { + string text = (string)label.Tag; + if (page == viewModel.PageSelected) { + label.Markup = string.Format ("{0}", text); + } else { + label.Markup = text; + } + } + + void BrowseLabelButtonPressed (object sender, EventArgs e) { viewModel.PageSelected = ManagePackagesPage.Browse; OnPackageResultsPageSelected (); } - void InstalledLabelButtonPressed (object sender, ButtonEventArgs e) + void BrowseLabelKeyPressed (object sender, KeyEventArgs e) + { + if (e.Modifiers == ModifierKeys.None && (e.Key == Key.Return || e.Key == Key.Space || e.Key == Key.NumPadEnter)) { + BrowseLabelButtonPressed (sender, e); + } + } + + void InstalledLabelButtonPressed (object sender, EventArgs e) { viewModel.PageSelected = ManagePackagesPage.Installed; OnPackageResultsPageSelected (); } - void UpdatesLabelButtonPressed (object sender, ButtonEventArgs e) + void InstalledLabelKeyPressed (object sender, KeyEventArgs e) + { + if (e.Modifiers == ModifierKeys.None && (e.Key == Key.Return || e.Key == Key.Space || e.Key == Key.NumPadEnter)) { + InstalledLabelButtonPressed (sender, e); + } + } + + void UpdatesLabelButtonPressed (object sender, EventArgs e) { viewModel.PageSelected = ManagePackagesPage.Updates; OnPackageResultsPageSelected (); } - void ConsolidateLabelButtonPressed (object sender, ButtonEventArgs e) + void UpdatesLabelKeyPressed (object sender, KeyEventArgs e) + { + if (e.Modifiers == ModifierKeys.None && (e.Key == Key.Return || e.Key == Key.Space || e.Key == Key.NumPadEnter)) { + UpdatesLabelButtonPressed (sender, e); + } + } + + void ConsolidateLabelButtonPressed (object sender, EventArgs e) { viewModel.PageSelected = ManagePackagesPage.Consolidate; OnPackageResultsPageSelected (); } + void ConsolidateLabelKeyPressed (object sender, KeyEventArgs e) + { + if (e.Modifiers == ModifierKeys.None && (e.Key == Key.Return || e.Key == Key.Space || e.Key == Key.NumPadEnter)) { + ConsolidateLabelButtonPressed (sender, e); + } + } + void OnPackageResultsPageSelected () { UpdatePackageResultsPageLabels (); -- cgit v1.2.3 From 22b1f06371676c82d481d27278fad0f131cd8400 Mon Sep 17 00:00:00 2001 From: Vsevolod Kukol Date: Mon, 11 Nov 2019 18:19:14 +0100 Subject: [Mac][NuGet] Use Components.SearchEntry for the Xwt.SearchEntry backend Xwt.GtkBackend.SearchEntry is a copy of Components.SearchEntry, but without accessibility features on macOS. Since we use that widget in PackageManagement only anway, let's just use the original widget that is accessible. We can review this once we get an updated SearchWidget backend in Xwt.Gtk. Fixes VSTS #750371 --- .../MacPlatform/AccessibleGtkSearchEntryBackend.cs | 68 ++++++++++++++++++++++ main/src/addins/MacPlatform/MacPlatform.cs | 2 + main/src/addins/MacPlatform/MacPlatform.csproj | 1 + .../ManagePackagesDialog.UI.cs | 1 + 4 files changed, 72 insertions(+) create mode 100644 main/src/addins/MacPlatform/AccessibleGtkSearchEntryBackend.cs (limited to 'main/src/addins') diff --git a/main/src/addins/MacPlatform/AccessibleGtkSearchEntryBackend.cs b/main/src/addins/MacPlatform/AccessibleGtkSearchEntryBackend.cs new file mode 100644 index 0000000000..02d09e7b82 --- /dev/null +++ b/main/src/addins/MacPlatform/AccessibleGtkSearchEntryBackend.cs @@ -0,0 +1,68 @@ +// +// AccessibleGtkSearchEntryBackend.cs +// +// Author: +// Vsevolod Kukol +// +// Copyright (c) 2019 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using MonoDevelop.Components; +using Xwt.Backends; +using Xwt.GtkBackend; + +namespace MacPlatform +{ + public class AccessibleGtkSearchEntryBackend : TextEntryBackend, ISearchTextEntryBackend + { + SearchEntry searchEntry; + + protected override Gtk.Entry TextEntry { + get { + return searchEntry.Entry; + } + } + + public override void Initialize () + { + searchEntry = new SearchEntry (); + searchEntry.ForceFilterButtonVisible = true; + searchEntry.RoundedShape = true; + searchEntry.HasFrame = true; + ((WidgetBackend)this).Widget = searchEntry; + searchEntry.Show (); + } + + public override void SetFocus () + { + base.SetFocus (); + TextEntry.GrabFocus (); + } + + public override bool ShowFrame { + get { + return searchEntry.HasFrame; + } + set { + searchEntry.HasFrame = value; + } + } + } +} diff --git a/main/src/addins/MacPlatform/MacPlatform.cs b/main/src/addins/MacPlatform/MacPlatform.cs index 3916678154..edfec54a46 100644 --- a/main/src/addins/MacPlatform/MacPlatform.cs +++ b/main/src/addins/MacPlatform/MacPlatform.cs @@ -161,6 +161,8 @@ namespace MonoDevelop.MacIntegration Xwt.Toolkit.CurrentEngine.RegisterBackend (); Xwt.Toolkit.CurrentEngine.RegisterBackend (); + Xwt.Toolkit.CurrentEngine.RegisterBackend (); + var description = XamMacBuildInfo.Value; if (string.IsNullOrEmpty (description)) { diff --git a/main/src/addins/MacPlatform/MacPlatform.csproj b/main/src/addins/MacPlatform/MacPlatform.csproj index 7f051bd92d..4fffdab94f 100644 --- a/main/src/addins/MacPlatform/MacPlatform.csproj +++ b/main/src/addins/MacPlatform/MacPlatform.csproj @@ -93,6 +93,7 @@ + diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.UI.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.UI.cs index 56a610a238..08f0404871 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.UI.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.UI.cs @@ -137,6 +137,7 @@ namespace MonoDevelop.PackageManagement packageSearchEntry = new SearchTextEntry (); packageSearchEntry.Name = "managePackagesDialogSearchEntry"; packageSearchEntry.WidthRequest = 187; + packageSearchEntry.Accessible.Label = GettextCatalog.GetString ("Package Search"); topHBox.PackEnd (packageSearchEntry); this.HeaderContent = topHBox; -- cgit v1.2.3 From c4639eedc198233f679676485f15b766ef59ea2b Mon Sep 17 00:00:00 2001 From: Vsevolod Kukol Date: Tue, 12 Nov 2019 11:53:25 +0100 Subject: [NuGet] Unsubscribe UI events when disposing --- .../ManagePackagesDialog.cs | 25 +++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'main/src/addins') diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs index a78b0b49d7..136ef23a9a 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialog.cs @@ -98,11 +98,11 @@ namespace MonoDevelop.PackageManagement LoadViewModel (initialSearch); closeButton.Clicked += CloseButtonClicked; - this.showPrereleaseCheckBox.Clicked += ShowPrereleaseCheckBoxClicked; - this.packageSourceComboBox.SelectionChanged += PackageSourceChanged; - this.addPackagesButton.Clicked += AddPackagesButtonClicked; - this.packageSearchEntry.Changed += PackageSearchEntryChanged; - this.packageVersionComboBox.SelectionChanged += PackageVersionChanged; + showPrereleaseCheckBox.Clicked += ShowPrereleaseCheckBoxClicked; + packageSourceComboBox.SelectionChanged += PackageSourceChanged; + addPackagesButton.Clicked += AddPackagesButtonClicked; + packageSearchEntry.Changed += PackageSearchEntryChanged; + packageVersionComboBox.SelectionChanged += PackageVersionChanged; imageLoader.Loaded += ImageLoaded; browseLabel.ButtonPressed += BrowseLabelButtonPressed; @@ -122,6 +122,21 @@ namespace MonoDevelop.PackageManagement closeButton.Clicked -= CloseButtonClicked; currentPackageVersionLabel.BoundsChanged -= PackageVersionLabelBoundsChanged; + showPrereleaseCheckBox.Clicked -= ShowPrereleaseCheckBoxClicked; + packageSourceComboBox.SelectionChanged -= PackageSourceChanged; + addPackagesButton.Clicked -= AddPackagesButtonClicked; + packageSearchEntry.Changed -= PackageSearchEntryChanged; + packageVersionComboBox.SelectionChanged -= PackageVersionChanged; + + browseLabel.ButtonPressed -= BrowseLabelButtonPressed; + browseLabel.KeyPressed -= BrowseLabelKeyPressed; + installedLabel.ButtonPressed -= InstalledLabelButtonPressed; + installedLabel.KeyPressed -= InstalledLabelKeyPressed; + updatesLabel.ButtonPressed -= UpdatesLabelButtonPressed; + updatesLabel.KeyPressed -= UpdatesLabelKeyPressed; + consolidateLabel.ButtonPressed -= ConsolidateLabelButtonPressed; + consolidateLabel.KeyPressed -= ConsolidateLabelKeyPressed; + imageLoader.Loaded -= ImageLoaded; imageLoader.Dispose (); -- cgit v1.2.3