Add accessibility

This commit is contained in:
Robert McRackan 2024-05-07 10:39:30 -04:00
parent d19fe2250c
commit 27b2fe741c
10 changed files with 220 additions and 101 deletions

View File

@ -0,0 +1,49 @@
using System.Windows.Forms;
namespace LibationWinForms
{
public class AccessibleDataGridViewButtonCell : DataGridViewButtonCell
{
protected string AccessibilityName
{
get => MyAccessibilityObject.AccessibilityName;
set => MyAccessibilityObject.AccessibilityName = value;
}
/// <summary>
/// Get or set description for accessibility. eg: screen readers. Also sets the ToolTipText
/// </summary>
protected string AccessibilityDescription
{
get => MyAccessibilityObject.AccessibilityDescription;
set
{
MyAccessibilityObject.AccessibilityDescription = value;
MyAccessibilityObject.Owner.ToolTipText = value;
}
}
protected ButtonCellAccessibilityObject MyAccessibilityObject { get; set; }
protected override AccessibleObject CreateAccessibilityInstance() => MyAccessibilityObject;
public AccessibleDataGridViewButtonCell(string accessibilityName) : base()
{
MyAccessibilityObject = new(this, name: accessibilityName, description: "");
}
protected class ButtonCellAccessibilityObject : DataGridViewButtonCellAccessibleObject
{
public string AccessibilityName { get; set; }
public string AccessibilityDescription { get; set; }
public override string Name => AccessibilityName;
public override string Description => AccessibilityDescription;
public ButtonCellAccessibilityObject(DataGridViewCell owner, string name, string description) : base(owner)
{
AccessibilityName = name;
AccessibilityDescription = description;
}
}
}
}

View File

@ -0,0 +1,49 @@
using System.Windows.Forms;
namespace LibationWinForms
{
internal class AccessibleDataGridViewTextBoxCell : DataGridViewTextBoxCell
{
protected virtual string AccessibilityName
{
get => MyAccessibilityObject.AccessibilityName;
set => MyAccessibilityObject.AccessibilityName = value;
}
/// <summary>
/// Get or set description for accessibility. eg: screen readers. Also sets the ToolTipText
/// </summary>
protected string AccessibilityDescription
{
get => MyAccessibilityObject.AccessibilityDescription;
set
{
MyAccessibilityObject.AccessibilityDescription = value;
MyAccessibilityObject.Owner.ToolTipText = value;
}
}
protected ButtonCellAccessibilityObject MyAccessibilityObject { get; set; }
protected override AccessibleObject CreateAccessibilityInstance() => MyAccessibilityObject;
public AccessibleDataGridViewTextBoxCell(string accessibilityName) : base()
{
MyAccessibilityObject = new(this, name: accessibilityName, description: "");
}
protected class ButtonCellAccessibilityObject : DataGridViewTextBoxCellAccessibleObject
{
public string AccessibilityName { get; set; }
public string AccessibilityDescription { get; set; }
public override string Name => AccessibilityName;
public override string Description => AccessibilityDescription;
public ButtonCellAccessibilityObject(DataGridViewCell owner, string name, string description) : base(owner)
{
AccessibilityName = name;
AccessibilityDescription = description;
}
}
}
}

View File

@ -51,7 +51,7 @@ namespace LibationWinForms.Dialogs
private void AddAccountToGrid(Account account)
{
int row = dataGridView1.Rows.Add(
var row = dataGridView1.Rows.Add(
"X",
"Export",
account.LibraryScan,

View File

@ -24,23 +24,39 @@ namespace LibationWinForms.Dialogs
private const string COL_MoveUp = nameof(MoveUp);
private const string COL_MoveDown = nameof(MoveDown);
internal class DisableButtonCell : DataGridViewButtonCell
internal class DisableButtonCell : AccessibleDataGridViewButtonCell
{
private int LastRowIndex => DataGridView.Rows[^1].IsNewRow ? DataGridView.Rows[^1].Index - 1 : DataGridView.Rows[^1].Index;
public DisableButtonCell() : base("Edit Filter button") { }
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
if ((OwningColumn.Name == COL_MoveUp && rowIndex == 0)
|| (OwningColumn.Name == COL_MoveDown && rowIndex == LastRowIndex)
|| OwningRow.IsNewRow)
var isMoveUp = OwningColumn.Name == COL_MoveUp;
var isMoveDown = OwningColumn.Name == COL_MoveDown;
var isDelete = OwningColumn.Name == COL_Delete;
var isNewRow = OwningRow.IsNewRow;
if (isNewRow
|| (isMoveUp && rowIndex == 0)
|| (isMoveDown && rowIndex == LastRowIndex))
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, paintParts ^ (DataGridViewPaintParts.ContentBackground | DataGridViewPaintParts.ContentForeground | DataGridViewPaintParts.SelectionBackground));
ButtonRenderer.DrawButton(graphics, cellBounds, value as string, cellStyle.Font, false, System.Windows.Forms.VisualStyles.PushButtonState.Disabled);
}
else
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
}
int LastRowIndex => DataGridView.Rows[^1].IsNewRow ? DataGridView.Rows[^1].Index - 1 : DataGridView.Rows[^1].Index;
if (isMoveUp)
AccessibilityDescription = "Move up";
else if (isMoveDown)
AccessibilityDescription = "Move down";
else if (isDelete)
AccessibilityDescription = "Delete";
}
}
}
public EditQuickFilters()

View File

@ -1,10 +1,11 @@
using System.Drawing;
using System.Windows.Forms;
namespace LibationWinForms.GridView
{
public class DataGridViewImageButtonCell : DataGridViewButtonCell
public class DataGridViewImageButtonCell : AccessibleDataGridViewButtonCell
{
public DataGridViewImageButtonCell(string accessibilityName) : base(accessibilityName) { }
protected void DrawButtonImage(Graphics graphics, Image image, Rectangle cellBounds)
{
var scaleFactor = OwningColumn is IDataGridScaleColumn scCol ? scCol.ScaleFactor : 1f;

View File

@ -21,19 +21,32 @@ namespace LibationWinForms.GridView
internal class EditTagsDataGridViewImageButtonCell : DataGridViewImageButtonCell
{
public EditTagsDataGridViewImageButtonCell() : base("Edit Tags button") { }
private static Image ButtonImage { get; } = Properties.Resources.edit_25x25;
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
// series
if (rowIndex >= 0 && DataGridView.GetBoundItem<IGridEntry>(rowIndex) is ISeriesEntry)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
}
// tag: empty
else if (value is string tagStr && tagStr.Length == 0)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, paintParts);
DrawButtonImage(graphics, ButtonImage, cellBounds);
AccessibilityDescription = "Click to edit tags";
}
// tag: not empty
else
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
AccessibilityDescription = (string)value;
}
}
}
}

View File

@ -1,7 +1,7 @@
using LibationUiBase.GridView;
using System;
using System;
using System.Drawing;
using System.Windows.Forms;
using LibationUiBase.GridView;
namespace LibationWinForms.GridView
{
@ -21,14 +21,18 @@ namespace LibationWinForms.GridView
}
}
internal class LastDownloadedGridViewCell : DataGridViewTextBoxCell
internal class LastDownloadedGridViewCell : AccessibleDataGridViewTextBoxCell
{
private LastDownloadStatus LastDownload => (LastDownloadStatus)Value;
public LastDownloadedGridViewCell() : base("Last Downloaded") { }
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
if (value is LastDownloadStatus lastDl)
ToolTipText = lastDl.ToolTipText;
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
if (value is LastDownloadStatus lastDl)
AccessibilityDescription = lastDl.ToolTipText;
}
protected override void OnDoubleClick(DataGridViewCellEventArgs e)

View File

@ -16,25 +16,7 @@ namespace LibationWinForms.GridView
internal class LiberateDataGridViewImageButtonCell : DataGridViewImageButtonCell
{
#region Accessibility
private string accessibilityName => "Liberate Image Button";
private string accessibilityDescription = "undefined";
protected override AccessibleObject CreateAccessibilityInstance() => new MyAccessibilityObject(accessibilityName, accessibilityDescription);
protected class MyAccessibilityObject : DataGridViewCellAccessibleObject
{
public override string Name => _name;
public override string Description => _description;
private string _name { get; }
private string _description { get; }
public MyAccessibilityObject(string name, string description) : base()
{
_name = name;
_description = description;
}
}
#endregion
public LiberateDataGridViewImageButtonCell() : base("Liberate button") { }
private static readonly Brush DISABLED_GRAY = new SolidBrush(Color.FromArgb(0x60, Color.LightGray));
private static readonly Color HiddenForeColor = Color.LightGray;
@ -51,8 +33,7 @@ namespace LibationWinForms.GridView
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, paintParts);
DrawButtonImage(graphics, (Image)status.ButtonImage, cellBounds);
accessibilityDescription = status.ToolTip;
ToolTipText = status.ToolTip;
AccessibilityDescription = status.ToolTip;
if (status.IsUnavailable || status.Opacity < 1)
graphics.FillRectangle(DISABLED_GRAY, cellBounds);

View File

@ -1,9 +1,9 @@
using DataLayer;
using System;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using DataLayer;
namespace LibationWinForms.GridView
{
@ -24,14 +24,17 @@ namespace LibationWinForms.GridView
}
}
internal class MyRatingGridViewCell : DataGridViewTextBoxCell
internal class MyRatingGridViewCell : AccessibleDataGridViewTextBoxCell
{
private static Rating DefaultRating => new Rating(0, 0, 0);
public override object DefaultNewRowValue => DefaultRating;
public override Type EditType => typeof(MyRatingCellEditor);
public override Type ValueType => typeof(Rating);
public MyRatingGridViewCell() { ToolTipText = ReadOnly ? "" : "Click to change ratings"; }
public MyRatingGridViewCell() : base("My Rating")
{
AccessibilityDescription = ReadOnly ? "" : "Click to change ratings";
}
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
@ -46,10 +49,10 @@ namespace LibationWinForms.GridView
{
if (value is Rating rating)
{
ToolTipText = ReadOnly ? "" : "Click to change ratings";
var starString = rating.ToStarString();
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, starString, starString, errorText, cellStyle, advancedBorderStyle, paintParts);
AccessibilityDescription = ReadOnly ? "" : "Click to change ratings";
}
else
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, string.Empty, string.Empty, errorText, cellStyle, advancedBorderStyle, paintParts);

View File

@ -13,14 +13,22 @@ namespace LibationWinForms.SeriesView
CellTemplate.Style.WrapMode = DataGridViewTriState.True;
}
}
internal class DownloadButtonColumnCell : DataGridViewButtonCell
internal class DownloadButtonColumnCell : AccessibleDataGridViewButtonCell
{
public DownloadButtonColumnCell() : base("Download Series button") { }
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
if (value is SeriesButton sentry)
if (value is not SeriesButton seriesEntry)
{
string cellValue = sentry.DisplayText;
if (!sentry.Enabled)
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
return;
}
string cellValue = seriesEntry.DisplayText;
AccessibilityDescription = cellValue;
if (!seriesEntry.Enabled)
{
//Draw disabled button
Rectangle buttonArea = cellBounds;
@ -29,10 +37,10 @@ namespace LibationWinForms.SeriesView
buttonArea.Y += buttonAdjustment.Y;
buttonArea.Height -= buttonAdjustment.Height;
buttonArea.Width -= buttonAdjustment.Width;
ButtonRenderer.DrawButton(graphics, buttonArea, cellValue, cellStyle.Font, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak, focused: false, PushButtonState.Disabled);
ButtonRenderer.DrawButton(graphics, buttonArea, cellValue, cellStyle.Font, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak, focused: false, PushButtonState.Disabled);
}
else if (sentry.HasButtonAction)
else if (seriesEntry.HasButtonAction)
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, cellValue, cellValue, errorText, cellStyle, advancedBorderStyle, paintParts);
else
{
@ -40,10 +48,5 @@ namespace LibationWinForms.SeriesView
TextRenderer.DrawText(graphics, cellValue, cellStyle.Font, cellBounds, cellStyle.ForeColor);
}
}
else
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
}
}
}
}