-
Notifications
You must be signed in to change notification settings - Fork 927
Expand file tree
/
Copy pathTableViewColumnHeaderAutomationPeer.cpp
More file actions
161 lines (143 loc) · 5.09 KB
/
Copy pathTableViewColumnHeaderAutomationPeer.cpp
File metadata and controls
161 lines (143 loc) · 5.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
#include "pch.h"
#include "common.h"
#include "TableView.h"
#include "TableViewCellsPanel.h"
#include "TableViewAutomationHelpers.h"
#include "TableViewColumnHeaderAutomationPeer.h"
#include "TableViewColumnHeaderAutomationPeer.properties.cpp"
#include <limits>
TableViewColumnHeaderAutomationPeer::TableViewColumnHeaderAutomationPeer(
winrt::TableView const& owner,
winrt::TableViewColumn const& column)
: ReferenceTracker(owner)
, m_column(winrt::make_weak(column))
{
}
hstring TableViewColumnHeaderAutomationPeer::GetClassNameCore()
{
return L"TableViewColumnHeader";
}
hstring TableViewColumnHeaderAutomationPeer::GetNameCore()
{
// Prefer string headers so screen readers announce a distinct column name.
if (auto const headerString = TryGetColumnHeaderString(m_column.get()))
{
return *headerString;
}
// For template headers, use the realized header cell and avoid the TableView owner's name.
if (auto const headerElement = GetHeaderElement())
{
if (auto const peer = winrt::FrameworkElementAutomationPeer::CreatePeerForElement(headerElement))
{
const auto name = peer.GetName();
if (!name.empty())
{
return name;
}
}
}
return {};
}
winrt::Windows::Foundation::Collections::IVector<winrt::AutomationPeer> TableViewColumnHeaderAutomationPeer::GetChildrenCore()
{
// Column headers are leaf HeaderItems; do not expose the TableView subtree.
return winrt::single_threaded_vector<winrt::AutomationPeer>();
}
winrt::AutomationControlType TableViewColumnHeaderAutomationPeer::GetAutomationControlTypeCore()
{
// HeaderItem is the UIA control type for table column headers.
return winrt::AutomationControlType::HeaderItem;
}
int32_t TableViewColumnHeaderAutomationPeer::GetPositionInSetCore()
{
// 1-based column position so AT can announce "column i of n".
const auto index = GetColumnIndex();
return index >= 0 ? index + 1 : -1;
}
int32_t TableViewColumnHeaderAutomationPeer::GetSizeOfSetCore()
{
// Total visible column count, so PositionInSet reads as "i of n".
if (auto const owner = Owner().try_as<winrt::TableView>())
{
if (auto const columns = owner.Columns())
{
int32_t count = 0;
for (auto const& col : columns)
{
if (IsVisibleColumn(col)) { ++count; }
}
if (count > 0) { return count; }
}
}
return -1;
}
winrt::Windows::Foundation::Rect TableViewColumnHeaderAutomationPeer::GetBoundingRectangleCore()
{
// Use this header's realized cell bounds; unrealized headers have no on-screen rect.
if (auto const headerElement = GetHeaderElement())
{
if (auto const peer = winrt::FrameworkElementAutomationPeer::CreatePeerForElement(headerElement))
{
return peer.GetBoundingRectangle();
}
}
return {};
}
winrt::Windows::Foundation::Point TableViewColumnHeaderAutomationPeer::GetClickablePointCore()
{
if (auto const headerElement = GetHeaderElement())
{
if (auto const peer = winrt::FrameworkElementAutomationPeer::CreatePeerForElement(headerElement))
{
return peer.GetClickablePoint();
}
}
// Unrealized headers have no clickable point (NaN per UIA convention).
return { std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::quiet_NaN() };
}
int32_t TableViewColumnHeaderAutomationPeer::GetColumnIndex()
{
// Logical visible column index, matching GetSizeOfSetCore's visible basis
// and the rendered header order, so PositionInSet ("i") and SizeOfSet ("n") stay
// consistent even when Columns contains null holes or collapsed columns.
// Columns are matched by identity; a column instance is a single logical position
// (single-owner model), so the same instance appearing twice in Columns is unsupported.
if (auto const owner = Owner().try_as<winrt::TableView>())
{
if (auto const col = m_column.get())
{
if (!IsVisibleColumn(col))
{
return -1;
}
if (auto const columns = owner.Columns())
{
int32_t logicalIndex = 0;
for (auto const& c : columns)
{
if (c == col) { return logicalIndex; }
if (IsVisibleColumn(c)) { ++logicalIndex; }
}
}
}
}
return -1;
}
winrt::FrameworkElement TableViewColumnHeaderAutomationPeer::GetHeaderElement()
{
// Match by Tag so null Columns entries do not skew logical indexes.
auto const owner = Owner().try_as<winrt::TableView>();
auto const col = m_column.get();
if (!owner || !col)
{
return nullptr;
}
auto const host = winrt::get_self<TableView>(owner)->GetHeaderHostInternal();
if (!host)
{
return nullptr;
}
return TableViewCellsPanel::CellForColumn(host, col);
}