Skip to content

Commit

Permalink
Add automation support
Browse files Browse the repository at this point in the history
  • Loading branch information
wieslawsoltes committed Mar 29, 2024
1 parent c45d58d commit b0ec12c
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 0 deletions.
54 changes: 54 additions & 0 deletions src/DataBox/Automation/Peers/DataBoxAutomationPeer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Avalonia.Automation.Peers;
using Avalonia.Automation.Provider;
using Avalonia.Controls;

namespace DataBox.Automation.Peers;

public class DataBoxAutomationPeer : ControlAutomationPeer, IScrollProvider
{
private bool _searchedForScrollable;
private IScrollProvider? _scroller;

public DataBoxAutomationPeer(DataBox owner)
: base(owner)
{
}

public new DataBox Owner => (DataBox)base.Owner;
public bool HorizontallyScrollable => _scroller?.HorizontallyScrollable ?? false;
public double HorizontalScrollPercent => _scroller?.HorizontalScrollPercent ?? -1;
public double HorizontalViewSize => _scroller?.HorizontalViewSize ?? 0;
public bool VerticallyScrollable => _scroller?.VerticallyScrollable ?? false;
public double VerticalScrollPercent => _scroller?.VerticalScrollPercent ?? -1;
public double VerticalViewSize => _scroller?.VerticalViewSize ?? 0;

protected virtual IScrollProvider? Scroller
{
get
{
if (!_searchedForScrollable)
{
if (Owner.RowsPresenter?.GetValue(ListBox.ScrollProperty) is Control scrollable)
_scroller = GetOrCreate(scrollable).GetProvider<IScrollProvider>();
_searchedForScrollable = true;
}

return _scroller;
}
}

protected override AutomationControlType GetAutomationControlTypeCore()
{
return AutomationControlType.DataGrid;
}

public void Scroll(ScrollAmount horizontalAmount, ScrollAmount verticalAmount)
{
_scroller?.Scroll(horizontalAmount, verticalAmount);
}

public void SetScrollPercent(double horizontalPercent, double verticalPercent)
{
_scroller?.SetScrollPercent(horizontalPercent, verticalPercent);
}
}
22 changes: 22 additions & 0 deletions src/DataBox/Automation/Peers/DataBoxCellAutomationPeer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Avalonia.Automation.Peers;

namespace DataBox.Automation.Peers;

public class DataBoxCellAutomationPeer : ContentControlAutomationPeer
{
public DataBoxCellAutomationPeer(DataBoxCell owner)
: base(owner)
{
}

public new DataBoxCell Owner => (DataBoxCell)base.Owner;

protected override AutomationControlType GetAutomationControlTypeCore()
{
return AutomationControlType.Custom;
}

protected override bool IsContentElementCore() => true;

protected override bool IsControlElementCore() => true;
}
22 changes: 22 additions & 0 deletions src/DataBox/Automation/Peers/DataBoxColumnHeaderAutomationPeer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Avalonia.Automation.Peers;

namespace DataBox.Automation.Peers;

public class DataBoxColumnHeaderAutomationPeer : ContentControlAutomationPeer
{
public DataBoxColumnHeaderAutomationPeer(DataBoxColumnHeader owner)
: base(owner)
{
}

public new DataBoxColumnHeader Owner => (DataBoxColumnHeader)base.Owner;

protected override AutomationControlType GetAutomationControlTypeCore()
{
return AutomationControlType.HeaderItem;
}

protected override bool IsContentElementCore() => false;

protected override bool IsControlElementCore() => true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Avalonia.Automation.Peers;
using DataBox.Primitives;

namespace DataBox.Automation.Peers;

public class DataBoxColumnHeadersPresenterAutomationPeer : ControlAutomationPeer
{
public DataBoxColumnHeadersPresenterAutomationPeer(DataBoxColumnHeadersPresenter owner)
: base(owner)
{
}

public new DataBoxColumnHeadersPresenter Owner => (DataBoxColumnHeadersPresenter)base.Owner;

protected override AutomationControlType GetAutomationControlTypeCore()
{
return AutomationControlType.Header;
}

protected override bool IsContentElementCore() => false;

protected override bool IsControlElementCore() => true;
}
81 changes: 81 additions & 0 deletions src/DataBox/Automation/Peers/DataBoxRowAutomationPeer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using Avalonia.Automation.Peers;
using Avalonia.Automation.Provider;
using Avalonia.Controls;

namespace DataBox.Automation.Peers;

public class DataBoxRowAutomationPeer : ContentControlAutomationPeer,
ISelectionItemProvider
{
public DataBoxRowAutomationPeer(ContentControl owner)
: base(owner)
{
}

public bool IsSelected => Owner.GetValue(ListBoxItem.IsSelectedProperty);

public ISelectionProvider? SelectionContainer
{
get
{
if (Owner.Parent is DataBox parent)
{
var parentPeer = GetOrCreate(parent);
return parentPeer.GetProvider<ISelectionProvider>();
}

return null;
}
}

public void Select()
{
EnsureEnabled();

if (Owner.Parent is DataBox parent && parent.RowsPresenter is not null)
{
var index = parent.RowsPresenter.IndexFromContainer(Owner);

if (index != -1)
parent.RowsPresenter.SelectedIndex = index;
}
}

void ISelectionItemProvider.AddToSelection()
{
EnsureEnabled();

if (Owner.Parent is DataBox parent
&& parent.RowsPresenter is not null
&& parent.RowsPresenter.GetValue(ListBox.SelectionProperty) is { } selectionModel)
{
var index = parent.RowsPresenter.IndexFromContainer(Owner);

if (index != -1)
selectionModel.Select(index);
}
}

void ISelectionItemProvider.RemoveFromSelection()
{
EnsureEnabled();

if (Owner.Parent is DataBox parent
&& parent.RowsPresenter is not null
&& parent.GetValue(ListBox.SelectionProperty) is { } selectionModel)
{
var index = parent.RowsPresenter.IndexFromContainer(Owner);

if (index != -1)
selectionModel.Deselect(index);
}
}

protected override AutomationControlType GetAutomationControlTypeCore()
{
return AutomationControlType.DataItem;
}

protected override bool IsContentElementCore() => true;
protected override bool IsControlElementCore() => true;
}
7 changes: 7 additions & 0 deletions src/DataBox/DataBox.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System.Collections;
using Avalonia;
using Avalonia.Automation.Peers;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Media;
using Avalonia.Metadata;
using DataBox.Automation.Peers;
using DataBox.Primitives;

namespace DataBox;
Expand Down Expand Up @@ -127,6 +129,11 @@ public DataBox()
_columns = new AvaloniaList<DataBoxColumn>();
}

protected override AutomationPeer OnCreateAutomationPeer()
{
return new DataBoxAutomationPeer(this);
}

protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
Expand Down
7 changes: 7 additions & 0 deletions src/DataBox/DataBoxCell.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using Avalonia;
using Avalonia.Automation.Peers;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes;
using DataBox.Automation.Peers;

namespace DataBox;

Expand All @@ -16,6 +18,11 @@ public class DataBoxCell : ContentControl

protected override Type StyleKeyOverride => typeof(DataBoxCell);

protected override AutomationPeer OnCreateAutomationPeer()
{
return new DataBoxCellAutomationPeer(this);
}

protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
Expand Down
7 changes: 7 additions & 0 deletions src/DataBox/DataBoxColumnHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
using System.ComponentModel;
using System.Linq;
using Avalonia;
using Avalonia.Automation.Peers;
using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Media;
using Avalonia.VisualTree;
using DataBox.Automation.Peers;

namespace DataBox;

Expand Down Expand Up @@ -57,6 +59,11 @@ internal bool IsPressed

internal IReadOnlyList<DataBoxColumnHeader>? ColumnHeaders { get; set; }

protected override AutomationPeer OnCreateAutomationPeer()
{
return new DataBoxColumnHeaderAutomationPeer(this);
}

protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
Expand Down
7 changes: 7 additions & 0 deletions src/DataBox/DataBoxRow.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using Avalonia.Automation.Peers;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes;
using DataBox.Automation.Peers;
using DataBox.Primitives;

namespace DataBox;
Expand All @@ -16,6 +18,11 @@ public class DataBoxRow : ListBoxItem

protected override Type StyleKeyOverride => typeof(DataBoxRow);

protected override AutomationPeer OnCreateAutomationPeer()
{
return new DataBoxRowAutomationPeer(this);
}

protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
Expand Down
7 changes: 7 additions & 0 deletions src/DataBox/Primitives/DataBoxColumnHeadersPresenter.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using Avalonia;
using Avalonia.Automation.Peers;
using Avalonia.Controls;
using Avalonia.Layout;
using DataBox.Automation.Peers;
using DataBox.Primitives.Layout;

namespace DataBox.Primitives;
Expand All @@ -16,6 +18,11 @@ public class DataBoxColumnHeadersPresenter : Panel

protected override Type StyleKeyOverride => typeof(DataBoxColumnHeadersPresenter);

protected override AutomationPeer OnCreateAutomationPeer()
{
return new DataBoxColumnHeadersPresenterAutomationPeer(this);
}

protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromVisualTree(e);
Expand Down

0 comments on commit b0ec12c

Please sign in to comment.