From ca5cdd00c87e2e821a2fe2d9dbcfc23328f2143f Mon Sep 17 00:00:00 2001 From: Dominik Titl <78549750+morning4coffe-dev@users.noreply.github.com> Date: Mon, 11 Mar 2024 20:01:30 +0100 Subject: [PATCH] feat: Implement `RichTextBlockAutomationPeer` --- .../RichTextBlockAutomationPeer.cs | 4 +- .../Peers/RichTextBlockAutomationPeer.cs | 99 +++++++++++++++++++ 2 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 src/Uno.UI/UI/Xaml/Automation/Peers/RichTextBlockAutomationPeer.cs diff --git a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Automation.Peers/RichTextBlockAutomationPeer.cs b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Automation.Peers/RichTextBlockAutomationPeer.cs index 609c275cb7b8..e0b43a22750c 100644 --- a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Automation.Peers/RichTextBlockAutomationPeer.cs +++ b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Automation.Peers/RichTextBlockAutomationPeer.cs @@ -3,12 +3,12 @@ #pragma warning disable 114 // new keyword hiding namespace Microsoft.UI.Xaml.Automation.Peers { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false [global::Uno.NotImplemented] #endif public partial class RichTextBlockAutomationPeer : global::Microsoft.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] public RichTextBlockAutomationPeer(global::Microsoft.UI.Xaml.Controls.RichTextBlock owner) : base(owner) { diff --git a/src/Uno.UI/UI/Xaml/Automation/Peers/RichTextBlockAutomationPeer.cs b/src/Uno.UI/UI/Xaml/Automation/Peers/RichTextBlockAutomationPeer.cs new file mode 100644 index 000000000000..50e0209ca26c --- /dev/null +++ b/src/Uno.UI/UI/Xaml/Automation/Peers/RichTextBlockAutomationPeer.cs @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. +// MUX Reference RichTextBlockAutomationPeer_Partial.cpp, tag winui3/release/1.4.2 +using System; +using DirectUI; +using Windows.Foundation; +using Microsoft.UI.Xaml.Controls; +using System.Collections.Generic; + +namespace Microsoft.UI.Xaml.Automation.Peers; + +/// +/// Exposes RichTextBlock types to Microsoft UI Automation. +/// +public partial class RichTextBlockAutomationPeer : FrameworkElementAutomationPeer +{ + public RichTextBlockAutomationPeer(RichTextBlock owner) : base(owner) + { + } + + protected override object GetPatternCore(PatternInterface patternInterface) + { + if (patternInterface == PatternInterface.Text) + { + //if (!m_pTextPattern) + //{ + // ctl::ComPtr spOwner; + // ctl::ComPtr spTextAdapter; + + // IFC(get_Owner(&spOwner)); + // IFCPTR(spOwner.Get()); + + // IFC(ActivationAPI::ActivateAutomationInstance(KnownTypeIndex::TextAdapter, static_cast(spOwner.Get())->GetHandle(), spTextAdapter.GetAddressOf())); + + // m_pTextPattern = spTextAdapter.Detach(); + // IFC(m_pTextPattern->put_Owner(spOwner.Get())); + //} + //*ppReturnValue = ctl::as_iinspectable((m_pTextPattern)); + //ctl::addref_interface(m_pTextPattern); + } + else + { + return base.GetPatternCore(patternInterface); + } + } + + protected override string GetClassNameCore() => nameof(RichTextBlock); + + protected override AutomationControlType GetAutomationControlTypeCore() + => AutomationControlType.Text; + + // We populate automation peer children from its block collection recursively + // Here we need to eliminate all text elements which are overflowing to next RichTextBlockOverflow if any + protected override IList GetChildrenCore() + { + var owner = Owner as Controls.RichTextBlockOverflow; + + var posContentStart = 0; + var posOverflowStart = int.MaxValue; + + var returnValue = base.GetChildrenCore(); + + if (owner.ContentStart is { } contentStart) + { + posContentStart = contentStart.Offset; + + if (owner.HasOverflowContent) + { + if (owner.OverflowContentTarget?.ContentStart is { } spOverflowStart) + { + posOverflowStart = spOverflowStart.Offset; + } + } + } + + var spSourceControl = owner.ContentSource; + var spBlocks = spSourceControl.Blocks; + var count = spBlocks.Count; + + for (var i = 0; i < count; i++) + { + var spBlock = spBlocks[i]; + if (owner.HasOverflowContent) + { + var blockStart = spBlock.ContentStart; + + if (blockStart.Offset >= posOverflowStart) + { + break; + } + } + + //UNO TODO: AppendAutomationPeerChildren + returnValue = spBlock.AppendAutomationPeerChildren(posContentStart, posOverflowStart); + } + + return returnValue; + } +}