OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/accessibility/native_view_accessibility.h" | 5 #include "ui/views/accessibility/native_view_accessibility.h" |
6 | 6 |
7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
8 #include "build/build_config.h" | 8 #include "build/build_config.h" |
9 #include "ui/accessibility/ax_view_state.h" | 9 #include "ui/accessibility/ax_view_state.h" |
10 #include "ui/events/event_utils.h" | 10 #include "ui/events/event_utils.h" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 if (!view_->enabled()) | 89 if (!view_->enabled()) |
90 data_.state |= (1 << ui::AX_STATE_DISABLED); | 90 data_.state |= (1 << ui::AX_STATE_DISABLED); |
91 | 91 |
92 if (!view_->visible()) | 92 if (!view_->visible()) |
93 data_.state |= (1 << ui::AX_STATE_INVISIBLE); | 93 data_.state |= (1 << ui::AX_STATE_INVISIBLE); |
94 | 94 |
95 return data_; | 95 return data_; |
96 } | 96 } |
97 | 97 |
98 int NativeViewAccessibility::GetChildCount() { | 98 int NativeViewAccessibility::GetChildCount() { |
99 int child_count = view_->child_count(); | 99 int child_count = 0; |
| 100 for (int i = 0; i < view_->child_count(); ++i) { |
| 101 View* child = view_->child_at(i); |
| 102 if (child->GetNativeViewAccessibility()->IsIgnored()) { |
| 103 // If not visible to accessibility clients, then use the children instead. |
| 104 child_count += child->GetNativeViewAccessibility()->GetChildCount(); |
| 105 } else { |
| 106 ++child_count; |
| 107 } |
| 108 } |
100 | 109 |
101 std::vector<Widget*> child_widgets; | 110 std::vector<Widget*> child_widgets; |
102 PopulateChildWidgetVector(&child_widgets); | 111 PopulateChildWidgetVector(&child_widgets); |
103 child_count += child_widgets.size(); | 112 child_count += child_widgets.size(); |
104 | 113 |
105 return child_count; | 114 return child_count; |
106 } | 115 } |
107 | 116 |
108 gfx::NativeViewAccessible NativeViewAccessibility::ChildAtIndex(int index) { | 117 gfx::NativeViewAccessible NativeViewAccessibility::ChildAtIndex(int index) { |
109 // If this is a root view, our widget might have child widgets. Include | 118 if (IsLeafElement()) |
| 119 return nullptr; |
| 120 |
| 121 // Include the child widgets that may be present if this is a root view. |
110 std::vector<Widget*> child_widgets; | 122 std::vector<Widget*> child_widgets; |
111 PopulateChildWidgetVector(&child_widgets); | 123 PopulateChildWidgetVector(&child_widgets); |
112 int child_widget_count = static_cast<int>(child_widgets.size()); | 124 int child_widget_count = static_cast<int>(child_widgets.size()); |
113 | 125 |
114 if (index < view_->child_count()) { | 126 int ax_child_count = GetChildCount(); |
115 return view_->child_at(index)->GetNativeViewAccessible(); | 127 if (index < ax_child_count) { |
116 } else if (index < view_->child_count() + child_widget_count) { | 128 int curr_child_count = 0; |
| 129 for (int i = 0; i < view_->child_count(); ++i) { |
| 130 View* child = view_->child_at(i); |
| 131 bool ignored = child->GetNativeViewAccessibility()->IsIgnored(); |
| 132 int pending_children = |
| 133 ignored ? child->GetNativeViewAccessibility()->GetChildCount() : 1; |
| 134 if (index < curr_child_count + pending_children) { |
| 135 if (ignored) { |
| 136 return child->GetNativeViewAccessibility()->ChildAtIndex( |
| 137 index - curr_child_count); |
| 138 } |
| 139 return child->GetNativeViewAccessible(); |
| 140 } |
| 141 curr_child_count += pending_children; |
| 142 } |
| 143 } else if (index < ax_child_count + child_widget_count) { |
117 Widget* child_widget = child_widgets[index - view_->child_count()]; | 144 Widget* child_widget = child_widgets[index - view_->child_count()]; |
118 return child_widget->GetRootView()->GetNativeViewAccessible(); | 145 return child_widget->GetRootView()->GetNativeViewAccessible(); |
119 } | 146 } |
120 | 147 |
121 return nullptr; | 148 return nullptr; |
122 } | 149 } |
123 | 150 |
124 gfx::NativeWindow NativeViewAccessibility::GetTopLevelWidget() { | 151 gfx::NativeWindow NativeViewAccessibility::GetTopLevelWidget() { |
125 if (view_->GetWidget()) | 152 if (view_->GetWidget()) |
126 return view_->GetWidget()->GetTopLevelWidget()->GetNativeWindow(); | 153 return view_->GetWidget()->GetTopLevelWidget()->GetNativeWindow(); |
127 return nullptr; | 154 return nullptr; |
128 } | 155 } |
129 | 156 |
130 gfx::NativeViewAccessible NativeViewAccessibility::GetParent() { | 157 gfx::NativeViewAccessible NativeViewAccessibility::GetParent() { |
131 if (view_->parent()) | 158 View* parent_view = view_->parent(); |
132 return view_->parent()->GetNativeViewAccessible(); | 159 if (parent_view) { |
| 160 if (parent_view->GetNativeViewAccessibility()->IsIgnored()) |
| 161 return parent_view->GetNativeViewAccessibility()->GetParent(); |
| 162 else |
| 163 return parent_view->GetNativeViewAccessible(); |
| 164 } |
133 | 165 |
134 // TODO: move this to NativeViewAccessibilityMac. | 166 // TODO: move this to NativeViewAccessibilityMac. |
135 #if defined(OS_MACOSX) | 167 #if defined(OS_MACOSX) |
136 if (view_->GetWidget()) | 168 if (view_->GetWidget()) |
137 return view_->GetWidget()->GetNativeView(); | 169 return view_->GetWidget()->GetNativeView(); |
138 #endif | 170 #endif |
139 | 171 |
140 if (parent_widget_) | 172 if (parent_widget_) |
141 return parent_widget_->GetRootView()->GetNativeViewAccessible(); | 173 return parent_widget_->GetRootView()->GetNativeViewAccessible(); |
142 | 174 |
(...skipping 12 matching lines...) Expand all Loading... |
155 std::vector<Widget*> child_widgets; | 187 std::vector<Widget*> child_widgets; |
156 PopulateChildWidgetVector(&child_widgets); | 188 PopulateChildWidgetVector(&child_widgets); |
157 for (Widget* child_widget : child_widgets) { | 189 for (Widget* child_widget : child_widgets) { |
158 View* child_root_view = child_widget->GetRootView(); | 190 View* child_root_view = child_widget->GetRootView(); |
159 gfx::Point point(x, y); | 191 gfx::Point point(x, y); |
160 View::ConvertPointFromScreen(child_root_view, &point); | 192 View::ConvertPointFromScreen(child_root_view, &point); |
161 if (child_root_view->HitTestPoint(point)) | 193 if (child_root_view->HitTestPoint(point)) |
162 return child_root_view->GetNativeViewAccessible(); | 194 return child_root_view->GetNativeViewAccessible(); |
163 } | 195 } |
164 | 196 |
| 197 if (IsLeafElement()) { |
| 198 if (IsIgnored()) |
| 199 return GetParent(); |
| 200 return GetNativeObject(); |
| 201 } |
| 202 |
165 gfx::Point point(x, y); | 203 gfx::Point point(x, y); |
166 View::ConvertPointFromScreen(view_, &point); | 204 View::ConvertPointFromScreen(view_, &point); |
167 if (!view_->HitTestPoint(point)) | 205 if (!view_->HitTestPoint(point)) |
168 return nullptr; | 206 return nullptr; |
169 | 207 |
170 // Check if the point is within any of the immediate children of this | 208 // Check if the point is within any of the immediate children of this view. We |
171 // view. We don't have to search further because AXPlatformNode will | 209 // don't have to search further because AXPlatformNodeWin will do a recursive |
172 // do a recursive hit test if we return anything other than |this| or NULL. | 210 // hit test if we return anything other than |GetNativeObject()| or nullptr. |
173 for (int i = view_->child_count() - 1; i >= 0; --i) { | 211 for (int i = view_->child_count() - 1; i >= 0; --i) { |
174 View* child_view = view_->child_at(i); | 212 View* child_view = view_->child_at(i); |
175 if (!child_view->visible()) | 213 if (!child_view->visible()) |
176 continue; | 214 continue; |
177 | 215 |
178 gfx::Point point_in_child_coords(point); | 216 gfx::Point point_in_child_coords(point); |
179 view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords); | 217 view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords); |
180 if (child_view->HitTestPoint(point_in_child_coords)) | 218 if (child_view->HitTestPoint(point_in_child_coords)) |
181 return child_view->GetNativeViewAccessible(); | 219 return child_view->GetNativeViewAccessible(); |
182 } | 220 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 } | 276 } |
239 } | 277 } |
240 | 278 |
241 void NativeViewAccessibility::SetParentWidget(Widget* parent_widget) { | 279 void NativeViewAccessibility::SetParentWidget(Widget* parent_widget) { |
242 if (parent_widget_) | 280 if (parent_widget_) |
243 parent_widget_->RemoveObserver(this); | 281 parent_widget_->RemoveObserver(this); |
244 parent_widget_ = parent_widget; | 282 parent_widget_ = parent_widget; |
245 parent_widget_->AddObserver(this); | 283 parent_widget_->AddObserver(this); |
246 } | 284 } |
247 | 285 |
| 286 bool NativeViewAccessibility::IsLeafElement() { |
| 287 if (GetChildCount() != 0) |
| 288 return false; |
| 289 return true; |
| 290 } |
| 291 |
| 292 bool NativeViewAccessibility::IsIgnored() { |
| 293 if (view_->focus_behavior() == ClientView::FocusBehavior::NEVER) |
| 294 return true; |
| 295 return false; |
| 296 } |
| 297 |
248 void NativeViewAccessibility::PopulateChildWidgetVector( | 298 void NativeViewAccessibility::PopulateChildWidgetVector( |
249 std::vector<Widget*>* result_child_widgets) { | 299 std::vector<Widget*>* result_child_widgets) { |
250 // Only attach child widgets to the root view. | 300 // Only attach child widgets to the root view. |
251 Widget* widget = view_->GetWidget(); | 301 Widget* widget = view_->GetWidget(); |
252 if (!widget || widget->GetRootView() != view_) | 302 if (!widget || widget->GetRootView() != view_) |
253 return; | 303 return; |
254 | 304 |
255 std::set<Widget*> child_widgets; | 305 std::set<Widget*> child_widgets; |
256 Widget::GetAllOwnedWidgets(widget->GetNativeView(), &child_widgets); | 306 Widget::GetAllOwnedWidgets(widget->GetNativeView(), &child_widgets); |
257 for (auto iter = child_widgets.begin(); iter != child_widgets.end(); ++iter) { | 307 for (auto iter = child_widgets.begin(); iter != child_widgets.end(); ++iter) { |
(...skipping 16 matching lines...) Expand all Loading... |
274 child_widget_platform_node->GetDelegate()); | 324 child_widget_platform_node->GetDelegate()); |
275 if (child_widget_view_accessibility->parent_widget() != widget) | 325 if (child_widget_view_accessibility->parent_widget() != widget) |
276 child_widget_view_accessibility->SetParentWidget(widget); | 326 child_widget_view_accessibility->SetParentWidget(widget); |
277 } | 327 } |
278 | 328 |
279 result_child_widgets->push_back(child_widget); | 329 result_child_widgets->push_back(child_widget); |
280 } | 330 } |
281 } | 331 } |
282 | 332 |
283 } // namespace views | 333 } // namespace views |
OLD | NEW |