From c45dde3c15cddbca7795cab1c28fa472148b01b1 Mon Sep 17 00:00:00 2001 From: "dmazzoni@chromium.org" Date: Thu, 3 Mar 2011 23:13:49 +0000 Subject: Refactor Views accessibility. BUG=none TEST=none Review URL: http://codereview.chromium.org/6581010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76825 0039d316-1c4b-4281-b951-d872f2087c98 --- views/accessibility/accessibility_types.h | 104 --- .../accessibility/native_view_accessibility_win.cc | 756 +++++++++++++++++++++ .../accessibility/native_view_accessibility_win.h | 170 +++++ views/accessibility/view_accessibility.cc | 725 -------------------- views/accessibility/view_accessibility.h | 165 ----- views/controls/button/button.cc | 20 +- views/controls/button/button.h | 7 +- views/controls/button/button_dropdown.cc | 16 +- views/controls/button/button_dropdown.h | 4 +- views/controls/button/checkbox.cc | 11 +- views/controls/button/checkbox.h | 3 +- views/controls/button/custom_button.cc | 19 +- views/controls/button/custom_button.h | 2 +- views/controls/button/menu_button.cc | 16 +- views/controls/button/menu_button.h | 4 +- views/controls/button/native_button_win.cc | 26 +- views/controls/button/radio_button.cc | 6 +- views/controls/button/radio_button.h | 14 +- views/controls/combobox/combobox.cc | 15 +- views/controls/combobox/combobox.h | 26 +- views/controls/image_view.cc | 7 +- views/controls/image_view.h | 9 +- views/controls/label.cc | 12 +- views/controls/label.h | 5 +- views/controls/label_unittest.cc | 13 +- views/controls/link.cc | 6 +- views/controls/link.h | 16 +- views/controls/menu/menu_controller.cc | 6 +- views/controls/menu/menu_item_view.cc | 18 +- views/controls/menu/menu_item_view.h | 6 +- views/controls/menu/menu_scroll_view_container.cc | 16 +- views/controls/menu/menu_scroll_view_container.h | 14 +- views/controls/menu/submenu_view.cc | 50 +- views/controls/menu/submenu_view.h | 24 +- views/controls/native_control.cc | 4 +- views/controls/native_control_gtk.cc | 6 +- views/controls/native_control_win.cc | 6 +- views/controls/progress_bar.cc | 10 +- views/controls/progress_bar.h | 8 +- views/controls/progress_bar_unittest.cc | 17 +- views/controls/resize_area.cc | 5 +- views/controls/resize_area.h | 13 +- views/controls/scrollbar/scroll_bar.cc | 5 +- views/controls/scrollbar/scroll_bar.h | 2 +- views/controls/separator.cc | 5 +- views/controls/separator.h | 11 +- views/controls/single_split_view.cc | 10 +- views/controls/single_split_view.h | 7 +- views/controls/tabbed_pane/tabbed_pane.cc | 18 +- views/controls/tabbed_pane/tabbed_pane.h | 24 +- views/controls/textfield/native_textfield_win.cc | 8 +- views/controls/textfield/textfield.cc | 26 +- views/controls/textfield/textfield.h | 10 +- views/controls/tree/tree_view.cc | 10 +- views/controls/tree/tree_view.h | 3 +- views/test/test_views_delegate.h | 20 +- views/view.cc | 33 +- views/view.h | 70 +- views/view_gtk.cc | 16 - views/view_win.cc | 29 +- views/views.gyp | 9 +- views/views_delegate.h | 6 +- views/widget/root_view.cc | 5 +- views/widget/root_view.h | 2 +- views/widget/widget.h | 12 + views/widget/widget_gtk.cc | 13 + views/widget/widget_gtk.h | 4 + views/widget/widget_win.cc | 24 +- views/widget/widget_win.h | 9 +- views/window/client_view.cc | 5 +- views/window/client_view.h | 7 +- views/window/dialog_delegate.h | 8 +- views/window/non_client_view.cc | 14 +- views/window/non_client_view.h | 24 +- views/window/window_delegate.h | 8 +- views/window/window_win.cc | 12 +- 76 files changed, 1404 insertions(+), 1445 deletions(-) delete mode 100644 views/accessibility/accessibility_types.h create mode 100644 views/accessibility/native_view_accessibility_win.cc create mode 100644 views/accessibility/native_view_accessibility_win.h delete mode 100644 views/accessibility/view_accessibility.cc delete mode 100644 views/accessibility/view_accessibility.h (limited to 'views') diff --git a/views/accessibility/accessibility_types.h b/views/accessibility/accessibility_types.h deleted file mode 100644 index e55996e..0000000 --- a/views/accessibility/accessibility_types.h +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef VIEWS_ACCESSIBILITY_ACCESSIBILITY_TYPES_H_ -#define VIEWS_ACCESSIBILITY_ACCESSIBILITY_TYPES_H_ -#pragma once - -#include "base/basictypes.h" - -//////////////////////////////////////////////////////////////////////////////// -// -// AccessibilityTypes -// -// Provides enumerations used to preserve platform-independence in accessibility -// functions used in various Views, both in Browser\Views and Views. -// -//////////////////////////////////////////////////////////////////////////////// -class AccessibilityTypes { - public: - - // This defines states of the supported accessibility roles in our - // Views (e.g. used in View::GetAccessibleState). Any interface using roles - // must provide a conversion to its own roles (see e.g. - // ViewAccessibility::get_accState and ViewAccessibility::MSAAState). - typedef uint32 State; - enum StateFlag { - STATE_CHECKED = 1 << 0, - STATE_COLLAPSED = 1 << 1, - STATE_DEFAULT = 1 << 2, - STATE_EXPANDED = 1 << 3, - STATE_HASPOPUP = 1 << 4, - STATE_HOTTRACKED = 1 << 5, - STATE_INVISIBLE = 1 << 6, - STATE_LINKED = 1 << 7, - STATE_OFFSCREEN = 1 << 8, - STATE_PRESSED = 1 << 9, - STATE_PROTECTED = 1 << 10, - STATE_READONLY = 1 << 11, - STATE_SELECTED = 1 << 12, - STATE_FOCUSED = 1 << 13, - STATE_UNAVAILABLE = 1 << 14 - }; - - // This defines an enumeration of the supported accessibility roles in our - // Views (e.g. used in View::GetAccessibleRole). Any interface using roles - // must provide a conversion to its own roles (see e.g. - // ViewAccessibility::get_accRole and ViewAccessibility::MSAARole). - enum Role { - ROLE_ALERT, - ROLE_APPLICATION, - ROLE_BUTTONDROPDOWN, - ROLE_BUTTONMENU, - ROLE_CHECKBUTTON, - ROLE_CLIENT, - ROLE_COMBOBOX, - ROLE_DIALOG, - ROLE_GRAPHIC, - ROLE_GROUPING, - ROLE_LINK, - ROLE_MENUBAR, - ROLE_MENUITEM, - ROLE_MENUPOPUP, - ROLE_OUTLINE, - ROLE_OUTLINEITEM, - ROLE_PAGETAB, - ROLE_PAGETABLIST, - ROLE_PANE, - ROLE_PROGRESSBAR, - ROLE_PUSHBUTTON, - ROLE_RADIOBUTTON, - ROLE_SCROLLBAR, - ROLE_SEPARATOR, - ROLE_STATICTEXT, - ROLE_TEXT, - ROLE_TITLEBAR, - ROLE_TOOLBAR, - ROLE_WINDOW - }; - - // This defines an enumeration of the supported accessibility events in our - // Views (e.g. used in View::NotifyAccessibilityEvent). Any interface using - // events must provide a conversion to its own events (see e.g. - // ViewAccessibility::MSAAEvent). - enum Event { - EVENT_ALERT, - EVENT_FOCUS, - EVENT_MENUSTART, - EVENT_MENUEND, - EVENT_MENUPOPUPSTART, - EVENT_MENUPOPUPEND, - EVENT_NAME_CHANGED, - EVENT_TEXT_CHANGED, - EVENT_SELECTION_CHANGED, - EVENT_VALUE_CHANGED - }; - - private: - // Do not instantiate this class. - AccessibilityTypes() {} - ~AccessibilityTypes() {} -}; - -#endif // VIEWS_ACCESSIBILITY_ACCESSIBILITY_TYPES_H_ diff --git a/views/accessibility/native_view_accessibility_win.cc b/views/accessibility/native_view_accessibility_win.cc new file mode 100644 index 0000000..07a459e --- /dev/null +++ b/views/accessibility/native_view_accessibility_win.cc @@ -0,0 +1,756 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "views/accessibility/native_view_accessibility_win.h" + +#include "ui/base/accessibility/accessible_view_state.h" +#include "ui/base/view_prop.h" +#include "views/controls/button/native_button.h" +#include "views/widget/widget.h" +#include "views/widget/widget_win.h" + +using ui::AccessibilityTypes; + +namespace views { + +const char kViewsNativeHostPropForAccessibility[] = + "Views_NativeViewHostHWNDForAccessibility"; + +// static +scoped_refptr NativeViewAccessibilityWin::Create( + views::View* view) { + CComObject* instance = NULL; + HRESULT hr = CComObject::CreateInstance( + &instance); + DCHECK(SUCCEEDED(hr)); + instance->set_view(view); + return scoped_refptr(instance); +} + +// static +IAccessible* NativeViewAccessibilityWin::GetAccessibleForView( + views::View* view) { + IAccessible* accessible = NULL; + + // First, check to see if the view is a native view. + if (view->GetClassName() == views::NativeViewHost::kViewClassName) { + views::NativeViewHost* native_host = + static_cast(view); + if (GetNativeIAccessibleInterface(native_host, &accessible) == S_OK) + return accessible; + } + + // Next, see if the view is a widget container. + if (view->child_widget()) { + views::WidgetWin* native_widget = + reinterpret_cast(view->child_widget()); + if (GetNativeIAccessibleInterface( + native_widget->GetNativeView(), &accessible) == S_OK) { + return accessible; + } + } + + // Finally, use our NativeViewAccessibilityWin implementation. + return view->GetNativeViewAccessibilityWin(); +} + +NativeViewAccessibilityWin::NativeViewAccessibilityWin() : view_(NULL) { +} + +NativeViewAccessibilityWin::~NativeViewAccessibilityWin() { +} + +// TODO(ctguil): Handle case where child View is not contained by parent. +STDMETHODIMP NativeViewAccessibilityWin::accHitTest( + LONG x_left, LONG y_top, VARIANT* child) { + if (!child) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + gfx::Point point(x_left, y_top); + views::View::ConvertPointToView(NULL, view_, &point); + + if (!view_->HitTest(point)) { + // If containing parent is not hit, return with failure. + child->vt = VT_EMPTY; + return S_FALSE; + } + + views::View* view = view_->GetEventHandlerForPoint(point); + if (view == view_) { + // No child hit, return parent id. + child->vt = VT_I4; + child->lVal = CHILDID_SELF; + } else { + child->vt = VT_DISPATCH; + child->pdispVal = GetAccessibleForView(view); + child->pdispVal->AddRef(); + } + return S_OK; +} + +HRESULT NativeViewAccessibilityWin::accDoDefaultAction(VARIANT var_id) { + if (!IsValidId(var_id)) + return E_INVALIDARG; + + if (view_->GetClassName() == views::NativeButton::kViewClassName) { + views::NativeButton* native_button = + static_cast(view_); + native_button->ButtonPressed(); + return S_OK; + } + + // The object does not support the method. This value is returned for + // controls that do not perform actions, such as edit fields. + return DISP_E_MEMBERNOTFOUND; +} + +STDMETHODIMP NativeViewAccessibilityWin::accLocation( + LONG* x_left, LONG* y_top, LONG* width, LONG* height, VARIANT var_id) { + if (!IsValidId(var_id) || !x_left || !y_top || !width || !height) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + if (!view_->bounds().IsEmpty()) { + *width = view_->width(); + *height = view_->height(); + gfx::Point topleft(view_->bounds().origin()); + views::View::ConvertPointToScreen( + view_->parent() ? view_->parent() : view_, &topleft); + *x_left = topleft.x(); + *y_top = topleft.y(); + } else { + return E_FAIL; + } + return S_OK; +} + +STDMETHODIMP NativeViewAccessibilityWin::accNavigate( + LONG nav_dir, VARIANT start, VARIANT* end) { + if (start.vt != VT_I4 || !end) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + switch (nav_dir) { + case NAVDIR_FIRSTCHILD: + case NAVDIR_LASTCHILD: { + if (start.lVal != CHILDID_SELF) { + // Start of navigation must be on the View itself. + return E_INVALIDARG; + } else if (!view_->has_children()) { + // No children found. + return S_FALSE; + } + + // Set child_id based on first or last child. + int child_id = 0; + if (nav_dir == NAVDIR_LASTCHILD) + child_id = view_->child_count() - 1; + + views::View* child = view_->GetChildViewAt(child_id); + end->vt = VT_DISPATCH; + end->pdispVal = GetAccessibleForView(child); + end->pdispVal->AddRef(); + return S_OK; + } + case NAVDIR_LEFT: + case NAVDIR_UP: + case NAVDIR_PREVIOUS: + case NAVDIR_RIGHT: + case NAVDIR_DOWN: + case NAVDIR_NEXT: { + // Retrieve parent to access view index and perform bounds checking. + views::View* parent = view_->parent(); + if (!parent) { + return E_FAIL; + } + + if (start.lVal == CHILDID_SELF) { + int view_index = parent->GetIndexOf(view_); + // Check navigation bounds, adjusting for View child indexing (MSAA + // child indexing starts with 1, whereas View indexing starts with 0). + if (!IsValidNav(nav_dir, view_index, -1, + parent->child_count() - 1)) { + // Navigation attempted to go out-of-bounds. + end->vt = VT_EMPTY; + return S_FALSE; + } else { + if (IsNavDirNext(nav_dir)) { + view_index += 1; + } else { + view_index -=1; + } + } + + views::View* child = parent->GetChildViewAt(view_index); + end->pdispVal = GetAccessibleForView(child); + end->vt = VT_DISPATCH; + end->pdispVal->AddRef(); + return S_OK; + } else { + // Check navigation bounds, adjusting for MSAA child indexing (MSAA + // child indexing starts with 1, whereas View indexing starts with 0). + if (!IsValidNav(nav_dir, start.lVal, 0, parent->child_count() + 1)) { + // Navigation attempted to go out-of-bounds. + end->vt = VT_EMPTY; + return S_FALSE; + } else { + if (IsNavDirNext(nav_dir)) { + start.lVal += 1; + } else { + start.lVal -= 1; + } + } + + HRESULT result = this->get_accChild(start, &end->pdispVal); + if (result == S_FALSE) { + // Child is a leaf. + end->vt = VT_I4; + end->lVal = start.lVal; + } else if (result == E_INVALIDARG) { + return E_INVALIDARG; + } else { + // Child is not a leaf. + end->vt = VT_DISPATCH; + } + } + break; + } + default: + return E_INVALIDARG; + } + // Navigation performed correctly. Global return for this function, if no + // error triggered an escape earlier. + return S_OK; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accChild(VARIANT var_child, + IDispatch** disp_child) { + if (var_child.vt != VT_I4 || !disp_child) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + LONG child_id = V_I4(&var_child); + + if (child_id == CHILDID_SELF) { + // Remain with the same dispatch. + return S_OK; + } + + views::View* child_view = NULL; + if (child_id > 0) { + int child_id_as_index = child_id - 1; + if (child_id_as_index < view_->child_count()) { + // Note: child_id is a one based index when indexing children. + child_view = view_->GetChildViewAt(child_id_as_index); + } else { + // Attempt to retrieve a child view with the specified id. + child_view = view_->GetViewByID(child_id); + } + } else { + // Negative values are used for events fired using the view's WidgetWin + views::WidgetWin* widget = + static_cast(view_->GetWidget()); + child_view = widget->GetAccessibilityViewEventAt(child_id); + } + + if (!child_view) { + // No child found. + *disp_child = NULL; + return E_FAIL; + } + + *disp_child = GetAccessibleForView(child_view); + (*disp_child)->AddRef(); + return S_OK; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accChildCount(LONG* child_count) { + if (!child_count || !view_) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + *child_count = view_->child_count(); + return S_OK; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accDefaultAction( + VARIANT var_id, BSTR* def_action) { + if (!IsValidId(var_id) || !def_action) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + ui::AccessibleViewState state; + view_->GetAccessibleState(&state); + string16 temp_action = state.default_action; + + if (!temp_action.empty()) { + *def_action = SysAllocString(temp_action.c_str()); + } else { + return S_FALSE; + } + + return S_OK; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accDescription( + VARIANT var_id, BSTR* desc) { + if (!IsValidId(var_id) || !desc) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + std::wstring temp_desc; + + view_->GetTooltipText(gfx::Point(), &temp_desc); + if (!temp_desc.empty()) { + *desc = SysAllocString(temp_desc.c_str()); + } else { + return S_FALSE; + } + + return S_OK; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accFocus(VARIANT* focus_child) { + if (!focus_child) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + views::View* focus = NULL; + views::FocusManager* focus_manager = view_->GetFocusManager(); + if (focus_manager) + focus = focus_manager->GetFocusedView(); + if (focus == view_) { + // This view has focus. + focus_child->vt = VT_I4; + focus_child->lVal = CHILDID_SELF; + } else if (focus && view_->Contains(focus)) { + // Return the child object that has the keyboard focus. + focus_child->pdispVal = GetAccessibleForView(focus); + focus_child->pdispVal->AddRef(); + return S_OK; + } else { + // Neither this object nor any of its children has the keyboard focus. + focus_child->vt = VT_EMPTY; + } + return S_OK; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accKeyboardShortcut( + VARIANT var_id, BSTR* acc_key) { + if (!IsValidId(var_id) || !acc_key) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + ui::AccessibleViewState state; + view_->GetAccessibleState(&state); + string16 temp_key = state.keyboard_shortcut; + + if (!temp_key.empty()) { + *acc_key = SysAllocString(temp_key.c_str()); + } else { + return S_FALSE; + } + + return S_OK; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accName( + VARIANT var_id, BSTR* name) { + if (!IsValidId(var_id) || !name) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + // Retrieve the current view's name. + ui::AccessibleViewState state; + view_->GetAccessibleState(&state); + string16 temp_name = state.name; + if (!temp_name.empty()) { + // Return name retrieved. + *name = SysAllocString(temp_name.c_str()); + } else { + // If view has no name, return S_FALSE. + return S_FALSE; + } + + return S_OK; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accParent( + IDispatch** disp_parent) { + if (!disp_parent) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + views::View* parent_view = view_->parent(); + + if (!parent_view) { + // This function can get called during teardown of WidetWin so we + // should bail out if we fail to get the HWND. + if (!view_->GetWidget() || !view_->GetWidget()->GetNativeView()) { + *disp_parent = NULL; + return S_FALSE; + } + + // For a View that has no parent (e.g. root), point the accessible parent + // to the default implementation, to interface with Windows' hierarchy + // and to support calls from e.g. WindowFromAccessibleObject. + HRESULT hr = + ::AccessibleObjectFromWindow(view_->GetWidget()->GetNativeView(), + OBJID_WINDOW, IID_IAccessible, + reinterpret_cast(disp_parent)); + + if (!SUCCEEDED(hr)) { + *disp_parent = NULL; + return S_FALSE; + } + + return S_OK; + } + + *disp_parent = GetAccessibleForView(parent_view); + (*disp_parent)->AddRef(); + return S_OK; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accRole( + VARIANT var_id, VARIANT* role) { + if (!IsValidId(var_id) || !role) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + ui::AccessibleViewState state; + view_->GetAccessibleState(&state); + role->vt = VT_I4; + role->lVal = MSAARole(state.role); + return S_OK; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accState( + VARIANT var_id, VARIANT* state) { + if (!IsValidId(var_id) || !state) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + state->vt = VT_I4; + + // Retrieve all currently applicable states of the parent. + SetState(state, view_); + + // Make sure that state is not empty, and has the proper type. + if (state->vt == VT_EMPTY) + return E_FAIL; + + return S_OK; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accValue( + VARIANT var_id, BSTR* value) { + if (!IsValidId(var_id) || !value) + return E_INVALIDARG; + + if (!view_) + return E_FAIL; + + // Retrieve the current view's value. + ui::AccessibleViewState state; + view_->GetAccessibleState(&state); + string16 temp_value = state.value; + + if (!temp_value.empty()) { + // Return value retrieved. + *value = SysAllocString(temp_value.c_str()); + } else { + // If view has no value, fall back into the default implementation. + *value = NULL; + return E_NOTIMPL; + } + + return S_OK; +} + +// Helper functions. + +bool NativeViewAccessibilityWin::IsNavDirNext(int nav_dir) const { + if (nav_dir == NAVDIR_RIGHT || nav_dir == NAVDIR_DOWN || + nav_dir == NAVDIR_NEXT) { + return true; + } + return false; +} + +bool NativeViewAccessibilityWin::IsValidNav( + int nav_dir, int start_id, int lower_bound, int upper_bound) const { + if (IsNavDirNext(nav_dir)) { + if ((start_id + 1) > upper_bound) { + return false; + } + } else { + if ((start_id - 1) <= lower_bound) { + return false; + } + } + return true; +} + +bool NativeViewAccessibilityWin::IsValidId(const VARIANT& child) const { + // View accessibility returns an IAccessible for each view so we only support + // the CHILDID_SELF id. + return (VT_I4 == child.vt) && (CHILDID_SELF == child.lVal); +} + +void NativeViewAccessibilityWin::SetState( + VARIANT* msaa_state, views::View* view) { + // Ensure the output param is initialized to zero. + msaa_state->lVal = 0; + + // Default state; all views can have accessibility focus. + msaa_state->lVal |= STATE_SYSTEM_FOCUSABLE; + + if (!view) + return; + + if (!view->IsEnabled()) + msaa_state->lVal |= STATE_SYSTEM_UNAVAILABLE; + if (!view->IsVisible()) + msaa_state->lVal |= STATE_SYSTEM_INVISIBLE; + if (view->IsHotTracked()) + msaa_state->lVal |= STATE_SYSTEM_HOTTRACKED; + if (view->HasFocus()) + msaa_state->lVal |= STATE_SYSTEM_FOCUSED; + + // Add on any view-specific states. + ui::AccessibleViewState view_state; + view->GetAccessibleState(&view_state); + msaa_state->lVal |= MSAAState(view_state.state); +} + +// IAccessible functions not supported. + +STDMETHODIMP NativeViewAccessibilityWin::get_accSelection(VARIANT* selected) { + if (selected) + selected->vt = VT_EMPTY; + return E_NOTIMPL; +} + +STDMETHODIMP NativeViewAccessibilityWin::accSelect( + LONG flagsSelect, VARIANT var_id) { + return E_NOTIMPL; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accHelp( + VARIANT var_id, BSTR* help) { + if (help) + *help = NULL; + return E_NOTIMPL; +} + +STDMETHODIMP NativeViewAccessibilityWin::get_accHelpTopic( + BSTR* help_file, VARIANT var_id, LONG* topic_id) { + if (help_file) { + *help_file = NULL; + } + if (topic_id) { + *topic_id = static_cast(-1); + } + return E_NOTIMPL; +} + +STDMETHODIMP NativeViewAccessibilityWin::put_accName( + VARIANT var_id, BSTR put_name) { + // Deprecated. + return E_NOTIMPL; +} + +STDMETHODIMP NativeViewAccessibilityWin::put_accValue( + VARIANT var_id, BSTR put_val) { + // Deprecated. + return E_NOTIMPL; +} + +int32 NativeViewAccessibilityWin::MSAAEvent(AccessibilityTypes::Event event) { + switch (event) { + case AccessibilityTypes::EVENT_ALERT: + return EVENT_SYSTEM_ALERT; + case AccessibilityTypes::EVENT_FOCUS: + return EVENT_OBJECT_FOCUS; + case AccessibilityTypes::EVENT_MENUSTART: + return EVENT_SYSTEM_MENUSTART; + case AccessibilityTypes::EVENT_MENUEND: + return EVENT_SYSTEM_MENUEND; + case AccessibilityTypes::EVENT_MENUPOPUPSTART: + return EVENT_SYSTEM_MENUPOPUPSTART; + case AccessibilityTypes::EVENT_MENUPOPUPEND: + return EVENT_SYSTEM_MENUPOPUPEND; + case AccessibilityTypes::EVENT_NAME_CHANGED: + return EVENT_OBJECT_NAMECHANGE; + case AccessibilityTypes::EVENT_TEXT_CHANGED: + return EVENT_OBJECT_VALUECHANGE; + case AccessibilityTypes::EVENT_SELECTION_CHANGED: + return EVENT_OBJECT_TEXTSELECTIONCHANGED; + case AccessibilityTypes::EVENT_VALUE_CHANGED: + return EVENT_OBJECT_VALUECHANGE; + default: + // Not supported or invalid event. + NOTREACHED(); + return -1; + } +} + +int32 NativeViewAccessibilityWin::MSAARole(AccessibilityTypes::Role role) { + switch (role) { + case AccessibilityTypes::ROLE_ALERT: +return ROLE_SYSTEM_ALERT; + case AccessibilityTypes::ROLE_APPLICATION: + return ROLE_SYSTEM_APPLICATION; + case AccessibilityTypes::ROLE_BUTTONDROPDOWN: + return ROLE_SYSTEM_BUTTONDROPDOWN; + case AccessibilityTypes::ROLE_BUTTONMENU: + return ROLE_SYSTEM_BUTTONMENU; + case AccessibilityTypes::ROLE_CHECKBUTTON: + return ROLE_SYSTEM_CHECKBUTTON; + case AccessibilityTypes::ROLE_COMBOBOX: + return ROLE_SYSTEM_COMBOBOX; + case AccessibilityTypes::ROLE_DIALOG: + return ROLE_SYSTEM_DIALOG; + case AccessibilityTypes::ROLE_GRAPHIC: + return ROLE_SYSTEM_GRAPHIC; + case AccessibilityTypes::ROLE_GROUPING: + return ROLE_SYSTEM_GROUPING; + case AccessibilityTypes::ROLE_LINK: + return ROLE_SYSTEM_LINK; + case AccessibilityTypes::ROLE_MENUBAR: + return ROLE_SYSTEM_MENUBAR; + case AccessibilityTypes::ROLE_MENUITEM: + return ROLE_SYSTEM_MENUITEM; + case AccessibilityTypes::ROLE_MENUPOPUP: + return ROLE_SYSTEM_MENUPOPUP; + case AccessibilityTypes::ROLE_OUTLINE: + return ROLE_SYSTEM_OUTLINE; + case AccessibilityTypes::ROLE_OUTLINEITEM: + return ROLE_SYSTEM_OUTLINEITEM; + case AccessibilityTypes::ROLE_PAGETAB: + return ROLE_SYSTEM_PAGETAB; + case AccessibilityTypes::ROLE_PAGETABLIST: + return ROLE_SYSTEM_PAGETABLIST; + case AccessibilityTypes::ROLE_PANE: + return ROLE_SYSTEM_PANE; + case AccessibilityTypes::ROLE_PROGRESSBAR: + return ROLE_SYSTEM_PROGRESSBAR; + case AccessibilityTypes::ROLE_PUSHBUTTON: + return ROLE_SYSTEM_PUSHBUTTON; + case AccessibilityTypes::ROLE_RADIOBUTTON: + return ROLE_SYSTEM_RADIOBUTTON; + case AccessibilityTypes::ROLE_SCROLLBAR: + return ROLE_SYSTEM_SCROLLBAR; + case AccessibilityTypes::ROLE_SEPARATOR: + return ROLE_SYSTEM_SEPARATOR; + case AccessibilityTypes::ROLE_STATICTEXT: + return ROLE_SYSTEM_STATICTEXT; + case AccessibilityTypes::ROLE_TEXT: + return ROLE_SYSTEM_TEXT; + case AccessibilityTypes::ROLE_TITLEBAR: + return ROLE_SYSTEM_TITLEBAR; + case AccessibilityTypes::ROLE_TOOLBAR: + return ROLE_SYSTEM_TOOLBAR; + case AccessibilityTypes::ROLE_WINDOW: + return ROLE_SYSTEM_WINDOW; + case AccessibilityTypes::ROLE_CLIENT: + default: + // This is the default role for MSAA. + return ROLE_SYSTEM_CLIENT; + } +} + +int32 NativeViewAccessibilityWin::MSAAState(AccessibilityTypes::State state) { + int32 msaa_state = 0; + if (state & AccessibilityTypes::STATE_CHECKED) + msaa_state |= STATE_SYSTEM_CHECKED; + if (state & AccessibilityTypes::STATE_COLLAPSED) + msaa_state |= STATE_SYSTEM_COLLAPSED; + if (state & AccessibilityTypes::STATE_DEFAULT) + msaa_state |= STATE_SYSTEM_DEFAULT; + if (state & AccessibilityTypes::STATE_EXPANDED) + msaa_state |= STATE_SYSTEM_EXPANDED; + if (state & AccessibilityTypes::STATE_HASPOPUP) + msaa_state |= STATE_SYSTEM_HASPOPUP; + if (state & AccessibilityTypes::STATE_HOTTRACKED) + msaa_state |= STATE_SYSTEM_HOTTRACKED; + if (state & AccessibilityTypes::STATE_INVISIBLE) + msaa_state |= STATE_SYSTEM_INVISIBLE; + if (state & AccessibilityTypes::STATE_LINKED) + msaa_state |= STATE_SYSTEM_LINKED; + if (state & AccessibilityTypes::STATE_OFFSCREEN) + msaa_state |= STATE_SYSTEM_OFFSCREEN; + if (state & AccessibilityTypes::STATE_PRESSED) + msaa_state |= STATE_SYSTEM_PRESSED; + if (state & AccessibilityTypes::STATE_PROTECTED) + msaa_state |= STATE_SYSTEM_PROTECTED; + if (state & AccessibilityTypes::STATE_READONLY) + msaa_state |= STATE_SYSTEM_READONLY; + if (state & AccessibilityTypes::STATE_SELECTED) + msaa_state |= STATE_SYSTEM_SELECTED; + if (state & AccessibilityTypes::STATE_FOCUSED) + msaa_state |= STATE_SYSTEM_FOCUSED; + if (state & AccessibilityTypes::STATE_UNAVAILABLE) + msaa_state |= STATE_SYSTEM_UNAVAILABLE; + return msaa_state; +} + +// static +HRESULT NativeViewAccessibilityWin::GetNativeIAccessibleInterface( + views::NativeViewHost* native_host, IAccessible** accessible) { + if (!native_host || !accessible) + return E_INVALIDARG; + + HWND native_view_window = static_cast( + ui::ViewProp::GetValue(native_host->native_view(), + kViewsNativeHostPropForAccessibility)); + if (!IsWindow(native_view_window)) { + native_view_window = native_host->native_view(); + } + + return GetNativeIAccessibleInterface(native_view_window, accessible); +} + +// static +HRESULT NativeViewAccessibilityWin::GetNativeIAccessibleInterface( + HWND native_view_window , IAccessible** accessible) { + if (IsWindow(native_view_window)) { + LRESULT ret = SendMessage(native_view_window, WM_GETOBJECT, 0, + OBJID_CLIENT); + return ObjectFromLresult(ret, IID_IDispatch, 0, + reinterpret_cast(accessible)); + } + + return E_FAIL; +} + +} // namespace views diff --git a/views/accessibility/native_view_accessibility_win.h b/views/accessibility/native_view_accessibility_win.h new file mode 100644 index 0000000..2e947e1 --- /dev/null +++ b/views/accessibility/native_view_accessibility_win.h @@ -0,0 +1,170 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef VIEWS_ACCESSIBILITY_NATIVE_VIEW_ACCESSIBILITY_WIN_H_ +#define VIEWS_ACCESSIBILITY_NATIVE_VIEW_ACCESSIBILITY_WIN_H_ +#pragma once + +#include +#include + +#include + +#include "base/scoped_ptr.h" +#include "ui/base/accessibility/accessible_view_state.h" +#include "views/controls/native/native_view_host.h" +#include "views/view.h" + +namespace views { + +//////////////////////////////////////////////////////////////////////////////// +// +// NativeViewAccessibilityWin +// +// Class implementing the MSAA IAccessible COM interface for a generic View, +// providing accessibility to be used by screen readers and other assistive +// technology (AT). +// +//////////////////////////////////////////////////////////////////////////////// +class ATL_NO_VTABLE NativeViewAccessibilityWin + : public CComObjectRootEx, + public IDispatchImpl { + public: + BEGIN_COM_MAP(NativeViewAccessibilityWin) + COM_INTERFACE_ENTRY2(IDispatch, IAccessible) + COM_INTERFACE_ENTRY(IAccessible) + END_COM_MAP() + + // Create method for view accessibility. + static scoped_refptr Create(views::View* view); + + // Returns the IAccessible interface for a view. + static IAccessible* GetAccessibleForView(views::View* view); + + virtual ~NativeViewAccessibilityWin(); + + void set_view(views::View* view) { view_ = view; } + + // Supported IAccessible methods. + + // Retrieves the child element or child object at a given point on the screen. + STDMETHODIMP accHitTest(LONG x_left, LONG y_top, VARIANT* child); + + // Performs the object's default action. + STDMETHODIMP accDoDefaultAction(VARIANT var_id); + + // Retrieves the specified object's current screen location. + STDMETHODIMP accLocation(LONG* x_left, + LONG* y_top, + LONG* width, + LONG* height, + VARIANT var_id); + + // Traverses to another UI element and retrieves the object. + STDMETHODIMP accNavigate(LONG nav_dir, VARIANT start, VARIANT* end); + + // Retrieves an IDispatch interface pointer for the specified child. + STDMETHODIMP get_accChild(VARIANT var_child, IDispatch** disp_child); + + // Retrieves the number of accessible children. + STDMETHODIMP get_accChildCount(LONG* child_count); + + // Retrieves a string that describes the object's default action. + STDMETHODIMP get_accDefaultAction(VARIANT var_id, BSTR* default_action); + + // Retrieves the tooltip description. + STDMETHODIMP get_accDescription(VARIANT var_id, BSTR* desc); + + // Retrieves the object that has the keyboard focus. + STDMETHODIMP get_accFocus(VARIANT* focus_child); + + // Retrieves the specified object's shortcut. + STDMETHODIMP get_accKeyboardShortcut(VARIANT var_id, BSTR* access_key); + + // Retrieves the name of the specified object. + STDMETHODIMP get_accName(VARIANT var_id, BSTR* name); + + // Retrieves the IDispatch interface of the object's parent. + STDMETHODIMP get_accParent(IDispatch** disp_parent); + + // Retrieves information describing the role of the specified object. + STDMETHODIMP get_accRole(VARIANT var_id, VARIANT* role); + + // Retrieves the current state of the specified object. + STDMETHODIMP get_accState(VARIANT var_id, VARIANT* state); + + // Retrieves the current value associated with the specified object. + STDMETHODIMP get_accValue(VARIANT var_id, BSTR* value); + + // Non-supported IAccessible methods. + + // Selections not applicable to views. + STDMETHODIMP get_accSelection(VARIANT* selected); + STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id); + + // Help functions not supported. + STDMETHODIMP get_accHelp(VARIANT var_id, BSTR* help); + STDMETHODIMP get_accHelpTopic(BSTR* help_file, + VARIANT var_id, + LONG* topic_id); + + // Deprecated functions, not implemented here. + STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name); + STDMETHODIMP put_accValue(VARIANT var_id, BSTR put_val); + + // Returns a conversion from the event (as defined in accessibility_types.h) + // to an MSAA event. + static int32 MSAAEvent(ui::AccessibilityTypes::Event event); + + // Returns a conversion from the Role (as defined in accessibility_types.h) + // to an MSAA role. + static int32 MSAARole(ui::AccessibilityTypes::Role role); + + // Returns a conversion from the State (as defined in accessibility_types.h) + // to MSAA states set. + static int32 MSAAState(ui::AccessibilityTypes::State state); + + private: + NativeViewAccessibilityWin(); + + // Determines navigation direction for accNavigate, based on left, up and + // previous being mapped all to previous and right, down, next being mapped + // to next. Returns true if navigation direction is next, false otherwise. + bool IsNavDirNext(int nav_dir) const; + + // Determines if the navigation target is within the allowed bounds. Returns + // true if it is, false otherwise. + bool IsValidNav(int nav_dir, + int start_id, + int lower_bound, + int upper_bound) const; + + // Determines if the child id variant is valid. + bool IsValidId(const VARIANT& child) const; + + // Helper function which sets applicable states of view. + void SetState(VARIANT* msaa_state, views::View* view); + + // Returns the IAccessible interface for a native view if applicable. + // Returns S_OK on success. + static HRESULT GetNativeIAccessibleInterface( + views::NativeViewHost* native_host, IAccessible** accessible); + + static HRESULT GetNativeIAccessibleInterface( + HWND native_view_window, IAccessible** accessible); + + // Give CComObject access to the class constructor. + template friend class CComObject; + + // Member View needed for view-specific calls. + views::View* view_; + + DISALLOW_COPY_AND_ASSIGN(NativeViewAccessibilityWin); +}; + +extern const char kViewsNativeHostPropForAccessibility[]; + +} // namespace views + +#endif // VIEWS_ACCESSIBILITY_NATIVE_VIEW_ACCESSIBILITY_WIN_H_ diff --git a/views/accessibility/view_accessibility.cc b/views/accessibility/view_accessibility.cc deleted file mode 100644 index ae9f889..0000000 --- a/views/accessibility/view_accessibility.cc +++ /dev/null @@ -1,725 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "views/accessibility/view_accessibility.h" - -#include "ui/base/view_prop.h" -#include "views/controls/button/native_button.h" -#include "views/widget/widget.h" -#include "views/widget/widget_win.h" - -const char kViewsNativeHostPropForAccessibility[] = - "Views_NativeViewHostHWNDForAccessibility"; - -// static -scoped_refptr ViewAccessibility::Create(views::View* view) { - CComObject* instance = NULL; - HRESULT hr = CComObject::CreateInstance(&instance); - DCHECK(SUCCEEDED(hr)); - instance->set_view(view); - return scoped_refptr(instance); -} - -// static -IAccessible* ViewAccessibility::GetAccessibleForView(views::View* view) { - IAccessible* accessible = NULL; - - // First, check to see if the view is a native view. - if (view->GetClassName() == views::NativeViewHost::kViewClassName) { - views::NativeViewHost* native_host = - static_cast(view); - if (GetNativeIAccessibleInterface(native_host, &accessible) == S_OK) - return accessible; - } - - // Next, see if the view is a widget container. - if (view->child_widget()) { - views::WidgetWin* native_widget = - reinterpret_cast(view->child_widget()); - if (GetNativeIAccessibleInterface( - native_widget->GetNativeView(), &accessible) == S_OK) { - return accessible; - } - } - - // Finally, use our ViewAccessibility implementation. - return view->GetViewAccessibility(); -} - -ViewAccessibility::ViewAccessibility() : view_(NULL) { -} - -ViewAccessibility::~ViewAccessibility() { -} - -// TODO(ctguil): Handle case where child View is not contained by parent. -STDMETHODIMP ViewAccessibility::accHitTest( - LONG x_left, LONG y_top, VARIANT* child) { - if (!child) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - gfx::Point point(x_left, y_top); - views::View::ConvertPointToView(NULL, view_, &point); - - if (!view_->HitTest(point)) { - // If containing parent is not hit, return with failure. - child->vt = VT_EMPTY; - return S_FALSE; - } - - views::View* view = view_->GetEventHandlerForPoint(point); - if (view == view_) { - // No child hit, return parent id. - child->vt = VT_I4; - child->lVal = CHILDID_SELF; - } else { - child->vt = VT_DISPATCH; - child->pdispVal = GetAccessibleForView(view); - child->pdispVal->AddRef(); - } - return S_OK; -} - -HRESULT ViewAccessibility::accDoDefaultAction(VARIANT var_id) { - if (!IsValidId(var_id)) - return E_INVALIDARG; - - if (view_->GetClassName() == views::NativeButton::kViewClassName) { - views::NativeButton* native_button = - static_cast(view_); - native_button->ButtonPressed(); - return S_OK; - } - - // The object does not support the method. This value is returned for - // controls that do not perform actions, such as edit fields. - return DISP_E_MEMBERNOTFOUND; -} - -STDMETHODIMP ViewAccessibility::accLocation( - LONG* x_left, LONG* y_top, LONG* width, LONG* height, VARIANT var_id) { - if (!IsValidId(var_id) || !x_left || !y_top || !width || !height) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - if (!view_->bounds().IsEmpty()) { - *width = view_->width(); - *height = view_->height(); - gfx::Point topleft(view_->bounds().origin()); - views::View::ConvertPointToScreen(view_->parent() ? view_->parent() : view_, - &topleft); - *x_left = topleft.x(); - *y_top = topleft.y(); - } else { - return E_FAIL; - } - return S_OK; -} - -STDMETHODIMP ViewAccessibility::accNavigate(LONG nav_dir, VARIANT start, - VARIANT* end) { - if (start.vt != VT_I4 || !end) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - switch (nav_dir) { - case NAVDIR_FIRSTCHILD: - case NAVDIR_LASTCHILD: { - if (start.lVal != CHILDID_SELF) { - // Start of navigation must be on the View itself. - return E_INVALIDARG; - } else if (!view_->has_children()) { - // No children found. - return S_FALSE; - } - - // Set child_id based on first or last child. - int child_id = 0; - if (nav_dir == NAVDIR_LASTCHILD) - child_id = view_->child_count() - 1; - - views::View* child = view_->GetChildViewAt(child_id); - end->vt = VT_DISPATCH; - end->pdispVal = GetAccessibleForView(child); - end->pdispVal->AddRef(); - return S_OK; - } - case NAVDIR_LEFT: - case NAVDIR_UP: - case NAVDIR_PREVIOUS: - case NAVDIR_RIGHT: - case NAVDIR_DOWN: - case NAVDIR_NEXT: { - // Retrieve parent to access view index and perform bounds checking. - views::View* parent = view_->parent(); - if (!parent) { - return E_FAIL; - } - - if (start.lVal == CHILDID_SELF) { - int view_index = parent->GetIndexOf(view_); - // Check navigation bounds, adjusting for View child indexing (MSAA - // child indexing starts with 1, whereas View indexing starts with 0). - if (!IsValidNav(nav_dir, view_index, -1, - parent->child_count() - 1)) { - // Navigation attempted to go out-of-bounds. - end->vt = VT_EMPTY; - return S_FALSE; - } else { - if (IsNavDirNext(nav_dir)) { - view_index += 1; - } else { - view_index -=1; - } - } - - views::View* child = parent->GetChildViewAt(view_index); - end->pdispVal = GetAccessibleForView(child); - end->vt = VT_DISPATCH; - end->pdispVal->AddRef(); - return S_OK; - } else { - // Check navigation bounds, adjusting for MSAA child indexing (MSAA - // child indexing starts with 1, whereas View indexing starts with 0). - if (!IsValidNav(nav_dir, start.lVal, 0, parent->child_count() + 1)) { - // Navigation attempted to go out-of-bounds. - end->vt = VT_EMPTY; - return S_FALSE; - } else { - if (IsNavDirNext(nav_dir)) { - start.lVal += 1; - } else { - start.lVal -= 1; - } - } - - HRESULT result = this->get_accChild(start, &end->pdispVal); - if (result == S_FALSE) { - // Child is a leaf. - end->vt = VT_I4; - end->lVal = start.lVal; - } else if (result == E_INVALIDARG) { - return E_INVALIDARG; - } else { - // Child is not a leaf. - end->vt = VT_DISPATCH; - } - } - break; - } - default: - return E_INVALIDARG; - } - // Navigation performed correctly. Global return for this function, if no - // error triggered an escape earlier. - return S_OK; -} - -STDMETHODIMP ViewAccessibility::get_accChild(VARIANT var_child, - IDispatch** disp_child) { - if (var_child.vt != VT_I4 || !disp_child) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - LONG child_id = V_I4(&var_child); - - if (child_id == CHILDID_SELF) { - // Remain with the same dispatch. - return S_OK; - } - - views::View* child_view = NULL; - if (child_id > 0) { - int child_id_as_index = child_id - 1; - if (child_id_as_index < view_->child_count()) { - // Note: child_id is a one based index when indexing children. - child_view = view_->GetChildViewAt(child_id_as_index); - } else { - // Attempt to retrieve a child view with the specified id. - child_view = view_->GetViewByID(child_id); - } - } else { - // Negative values are used for events fired using the view's WidgetWin - views::WidgetWin* widget = - static_cast(view_->GetWidget()); - child_view = widget->GetAccessibilityViewEventAt(child_id); - } - - if (!child_view) { - // No child found. - *disp_child = NULL; - return E_FAIL; - } - - *disp_child = GetAccessibleForView(child_view); - (*disp_child)->AddRef(); - return S_OK; -} - -STDMETHODIMP ViewAccessibility::get_accChildCount(LONG* child_count) { - if (!child_count || !view_) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - *child_count = view_->child_count(); - return S_OK; -} - -STDMETHODIMP ViewAccessibility::get_accDefaultAction( - VARIANT var_id, BSTR* def_action) { - if (!IsValidId(var_id) || !def_action) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - string16 temp_action = view_->GetAccessibleDefaultAction(); - - if (!temp_action.empty()) { - *def_action = SysAllocString(temp_action.c_str()); - } else { - return S_FALSE; - } - - return S_OK; -} - -STDMETHODIMP ViewAccessibility::get_accDescription(VARIANT var_id, BSTR* desc) { - if (!IsValidId(var_id) || !desc) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - std::wstring temp_desc; - - view_->GetTooltipText(gfx::Point(), &temp_desc); - if (!temp_desc.empty()) { - *desc = SysAllocString(temp_desc.c_str()); - } else { - return S_FALSE; - } - - return S_OK; -} - -STDMETHODIMP ViewAccessibility::get_accFocus(VARIANT* focus_child) { - if (!focus_child) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - views::View* focus = NULL; - views::FocusManager* focus_manager = view_->GetFocusManager(); - if (focus_manager) - focus = focus_manager->GetFocusedView(); - if (focus == view_) { - // This view has focus. - focus_child->vt = VT_I4; - focus_child->lVal = CHILDID_SELF; - } else if (focus && view_->Contains(focus)) { - // Return the child object that has the keyboard focus. - focus_child->pdispVal = GetAccessibleForView(focus); - focus_child->pdispVal->AddRef(); - return S_OK; - } else { - // Neither this object nor any of its children has the keyboard focus. - focus_child->vt = VT_EMPTY; - } - return S_OK; -} - -STDMETHODIMP ViewAccessibility::get_accKeyboardShortcut( - VARIANT var_id, BSTR* acc_key) { - if (!IsValidId(var_id) || !acc_key) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - string16 temp_key = view_->GetAccessibleKeyboardShortcut(); - - if (!temp_key.empty()) { - *acc_key = SysAllocString(temp_key.c_str()); - } else { - return S_FALSE; - } - - return S_OK; -} - -STDMETHODIMP ViewAccessibility::get_accName(VARIANT var_id, BSTR* name) { - if (!IsValidId(var_id) || !name) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - string16 temp_name; - - // Retrieve the current view's name. - view_->GetAccessibleName(&temp_name); - if (!temp_name.empty()) { - // Return name retrieved. - *name = SysAllocString(temp_name.c_str()); - } else { - // If view has no name, return S_FALSE. - return S_FALSE; - } - - return S_OK; -} - -STDMETHODIMP ViewAccessibility::get_accParent(IDispatch** disp_parent) { - if (!disp_parent) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - views::View* parent_view = view_->parent(); - - if (!parent_view) { - // This function can get called during teardown of WidetWin so we - // should bail out if we fail to get the HWND. - if (!view_->GetWidget() || !view_->GetWidget()->GetNativeView()) { - *disp_parent = NULL; - return S_FALSE; - } - - // For a View that has no parent (e.g. root), point the accessible parent to - // the default implementation, to interface with Windows' hierarchy and to - // support calls from e.g. WindowFromAccessibleObject. - HRESULT hr = - ::AccessibleObjectFromWindow(view_->GetWidget()->GetNativeView(), - OBJID_WINDOW, IID_IAccessible, - reinterpret_cast(disp_parent)); - - if (!SUCCEEDED(hr)) { - *disp_parent = NULL; - return S_FALSE; - } - - return S_OK; - } - - *disp_parent = GetAccessibleForView(parent_view); - (*disp_parent)->AddRef(); - return S_OK; -} - -STDMETHODIMP ViewAccessibility::get_accRole(VARIANT var_id, VARIANT* role) { - if (!IsValidId(var_id) || !role) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - role->vt = VT_I4; - role->lVal = MSAARole(view_->GetAccessibleRole()); - return S_OK; -} - -STDMETHODIMP ViewAccessibility::get_accState(VARIANT var_id, VARIANT* state) { - if (!IsValidId(var_id) || !state) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - state->vt = VT_I4; - - // Retrieve all currently applicable states of the parent. - SetState(state, view_); - - // Make sure that state is not empty, and has the proper type. - if (state->vt == VT_EMPTY) - return E_FAIL; - - return S_OK; -} - -STDMETHODIMP ViewAccessibility::get_accValue(VARIANT var_id, BSTR* value) { - if (!IsValidId(var_id) || !value) - return E_INVALIDARG; - - if (!view_) - return E_FAIL; - - // Retrieve the current view's value. - string16 temp_value = view_->GetAccessibleValue(); - - if (!temp_value.empty()) { - // Return value retrieved. - *value = SysAllocString(temp_value.c_str()); - } else { - // If view has no value, fall back into the default implementation. - *value = NULL; - return E_NOTIMPL; - } - - return S_OK; -} - -// Helper functions. - -bool ViewAccessibility::IsNavDirNext(int nav_dir) const { - if (nav_dir == NAVDIR_RIGHT || nav_dir == NAVDIR_DOWN || - nav_dir == NAVDIR_NEXT) { - return true; - } - return false; -} - -bool ViewAccessibility::IsValidNav(int nav_dir, int start_id, int lower_bound, - int upper_bound) const { - if (IsNavDirNext(nav_dir)) { - if ((start_id + 1) > upper_bound) { - return false; - } - } else { - if ((start_id - 1) <= lower_bound) { - return false; - } - } - return true; -} - -bool ViewAccessibility::IsValidId(const VARIANT& child) const { - // View accessibility returns an IAccessible for each view so we only support - // the CHILDID_SELF id. - return (VT_I4 == child.vt) && (CHILDID_SELF == child.lVal); -} - -void ViewAccessibility::SetState(VARIANT* msaa_state, views::View* view) { - // Ensure the output param is initialized to zero. - msaa_state->lVal = 0; - - // Default state; all views can have accessibility focus. - msaa_state->lVal |= STATE_SYSTEM_FOCUSABLE; - - if (!view) - return; - - if (!view->IsEnabled()) - msaa_state->lVal |= STATE_SYSTEM_UNAVAILABLE; - if (!view->IsVisible()) - msaa_state->lVal |= STATE_SYSTEM_INVISIBLE; - if (view->IsHotTracked()) - msaa_state->lVal |= STATE_SYSTEM_HOTTRACKED; - if (view->HasFocus()) - msaa_state->lVal |= STATE_SYSTEM_FOCUSED; - - // Add on any view-specific states. - msaa_state->lVal |= MSAAState(view->GetAccessibleState()); -} - -// IAccessible functions not supported. - -STDMETHODIMP ViewAccessibility::get_accSelection(VARIANT* selected) { - if (selected) - selected->vt = VT_EMPTY; - return E_NOTIMPL; -} - -STDMETHODIMP ViewAccessibility::accSelect(LONG flagsSelect, VARIANT var_id) { - return E_NOTIMPL; -} - -STDMETHODIMP ViewAccessibility::get_accHelp(VARIANT var_id, BSTR* help) { - if (help) - *help = NULL; - return E_NOTIMPL; -} - -STDMETHODIMP ViewAccessibility::get_accHelpTopic( - BSTR* help_file, VARIANT var_id, LONG* topic_id) { - if (help_file) { - *help_file = NULL; - } - if (topic_id) { - *topic_id = static_cast(-1); - } - return E_NOTIMPL; -} - -STDMETHODIMP ViewAccessibility::put_accName(VARIANT var_id, BSTR put_name) { - // Deprecated. - return E_NOTIMPL; -} - -STDMETHODIMP ViewAccessibility::put_accValue(VARIANT var_id, BSTR put_val) { - // Deprecated. - return E_NOTIMPL; -} - -int32 ViewAccessibility::MSAAEvent(AccessibilityTypes::Event event) { - switch (event) { - case AccessibilityTypes::EVENT_ALERT: - return EVENT_SYSTEM_ALERT; - case AccessibilityTypes::EVENT_FOCUS: - return EVENT_OBJECT_FOCUS; - case AccessibilityTypes::EVENT_MENUSTART: - return EVENT_SYSTEM_MENUSTART; - case AccessibilityTypes::EVENT_MENUEND: - return EVENT_SYSTEM_MENUEND; - case AccessibilityTypes::EVENT_MENUPOPUPSTART: - return EVENT_SYSTEM_MENUPOPUPSTART; - case AccessibilityTypes::EVENT_MENUPOPUPEND: - return EVENT_SYSTEM_MENUPOPUPEND; - case AccessibilityTypes::EVENT_NAME_CHANGED: - return EVENT_OBJECT_NAMECHANGE; - case AccessibilityTypes::EVENT_TEXT_CHANGED: - return EVENT_OBJECT_VALUECHANGE; - case AccessibilityTypes::EVENT_SELECTION_CHANGED: - return EVENT_OBJECT_TEXTSELECTIONCHANGED; - case AccessibilityTypes::EVENT_VALUE_CHANGED: - return EVENT_OBJECT_VALUECHANGE; - default: - // Not supported or invalid event. - NOTREACHED(); - return -1; - } -} - -int32 ViewAccessibility::MSAARole(AccessibilityTypes::Role role) { - switch (role) { - case AccessibilityTypes::ROLE_ALERT: -return ROLE_SYSTEM_ALERT; - case AccessibilityTypes::ROLE_APPLICATION: - return ROLE_SYSTEM_APPLICATION; - case AccessibilityTypes::ROLE_BUTTONDROPDOWN: - return ROLE_SYSTEM_BUTTONDROPDOWN; - case AccessibilityTypes::ROLE_BUTTONMENU: - return ROLE_SYSTEM_BUTTONMENU; - case AccessibilityTypes::ROLE_CHECKBUTTON: - return ROLE_SYSTEM_CHECKBUTTON; - case AccessibilityTypes::ROLE_COMBOBOX: - return ROLE_SYSTEM_COMBOBOX; - case AccessibilityTypes::ROLE_DIALOG: - return ROLE_SYSTEM_DIALOG; - case AccessibilityTypes::ROLE_GRAPHIC: - return ROLE_SYSTEM_GRAPHIC; - case AccessibilityTypes::ROLE_GROUPING: - return ROLE_SYSTEM_GROUPING; - case AccessibilityTypes::ROLE_LINK: - return ROLE_SYSTEM_LINK; - case AccessibilityTypes::ROLE_MENUBAR: - return ROLE_SYSTEM_MENUBAR; - case AccessibilityTypes::ROLE_MENUITEM: - return ROLE_SYSTEM_MENUITEM; - case AccessibilityTypes::ROLE_MENUPOPUP: - return ROLE_SYSTEM_MENUPOPUP; - case AccessibilityTypes::ROLE_OUTLINE: - return ROLE_SYSTEM_OUTLINE; - case AccessibilityTypes::ROLE_OUTLINEITEM: - return ROLE_SYSTEM_OUTLINEITEM; - case AccessibilityTypes::ROLE_PAGETAB: - return ROLE_SYSTEM_PAGETAB; - case AccessibilityTypes::ROLE_PAGETABLIST: - return ROLE_SYSTEM_PAGETABLIST; - case AccessibilityTypes::ROLE_PANE: - return ROLE_SYSTEM_PANE; - case AccessibilityTypes::ROLE_PROGRESSBAR: - return ROLE_SYSTEM_PROGRESSBAR; - case AccessibilityTypes::ROLE_PUSHBUTTON: - return ROLE_SYSTEM_PUSHBUTTON; - case AccessibilityTypes::ROLE_RADIOBUTTON: - return ROLE_SYSTEM_RADIOBUTTON; - case AccessibilityTypes::ROLE_SCROLLBAR: - return ROLE_SYSTEM_SCROLLBAR; - case AccessibilityTypes::ROLE_SEPARATOR: - return ROLE_SYSTEM_SEPARATOR; - case AccessibilityTypes::ROLE_STATICTEXT: - return ROLE_SYSTEM_STATICTEXT; - case AccessibilityTypes::ROLE_TEXT: - return ROLE_SYSTEM_TEXT; - case AccessibilityTypes::ROLE_TITLEBAR: - return ROLE_SYSTEM_TITLEBAR; - case AccessibilityTypes::ROLE_TOOLBAR: - return ROLE_SYSTEM_TOOLBAR; - case AccessibilityTypes::ROLE_WINDOW: - return ROLE_SYSTEM_WINDOW; - case AccessibilityTypes::ROLE_CLIENT: - default: - // This is the default role for MSAA. - return ROLE_SYSTEM_CLIENT; - } -} - -int32 ViewAccessibility::MSAAState(AccessibilityTypes::State state) { - int32 msaa_state = 0; - if (state & AccessibilityTypes::STATE_CHECKED) - msaa_state |= STATE_SYSTEM_CHECKED; - if (state & AccessibilityTypes::STATE_COLLAPSED) - msaa_state |= STATE_SYSTEM_COLLAPSED; - if (state & AccessibilityTypes::STATE_DEFAULT) - msaa_state |= STATE_SYSTEM_DEFAULT; - if (state & AccessibilityTypes::STATE_EXPANDED) - msaa_state |= STATE_SYSTEM_EXPANDED; - if (state & AccessibilityTypes::STATE_HASPOPUP) - msaa_state |= STATE_SYSTEM_HASPOPUP; - if (state & AccessibilityTypes::STATE_HOTTRACKED) - msaa_state |= STATE_SYSTEM_HOTTRACKED; - if (state & AccessibilityTypes::STATE_INVISIBLE) - msaa_state |= STATE_SYSTEM_INVISIBLE; - if (state & AccessibilityTypes::STATE_LINKED) - msaa_state |= STATE_SYSTEM_LINKED; - if (state & AccessibilityTypes::STATE_OFFSCREEN) - msaa_state |= STATE_SYSTEM_OFFSCREEN; - if (state & AccessibilityTypes::STATE_PRESSED) - msaa_state |= STATE_SYSTEM_PRESSED; - if (state & AccessibilityTypes::STATE_PROTECTED) - msaa_state |= STATE_SYSTEM_PROTECTED; - if (state & AccessibilityTypes::STATE_READONLY) - msaa_state |= STATE_SYSTEM_READONLY; - if (state & AccessibilityTypes::STATE_SELECTED) - msaa_state |= STATE_SYSTEM_SELECTED; - if (state & AccessibilityTypes::STATE_FOCUSED) - msaa_state |= STATE_SYSTEM_FOCUSED; - if (state & AccessibilityTypes::STATE_UNAVAILABLE) - msaa_state |= STATE_SYSTEM_UNAVAILABLE; - return msaa_state; -} - -// static -HRESULT ViewAccessibility::GetNativeIAccessibleInterface( - views::NativeViewHost* native_host, IAccessible** accessible) { - if (!native_host || !accessible) - return E_INVALIDARG; - - HWND native_view_window = static_cast( - ui::ViewProp::GetValue(native_host->native_view(), - kViewsNativeHostPropForAccessibility)); - if (!IsWindow(native_view_window)) { - native_view_window = native_host->native_view(); - } - - return GetNativeIAccessibleInterface(native_view_window, accessible); -} - -// static -HRESULT ViewAccessibility::GetNativeIAccessibleInterface( - HWND native_view_window , IAccessible** accessible) { - if (IsWindow(native_view_window)) { - LRESULT ret = SendMessage(native_view_window, WM_GETOBJECT, 0, - OBJID_CLIENT); - return ObjectFromLresult(ret, IID_IDispatch, 0, - reinterpret_cast(accessible)); - } - - return E_FAIL; -} diff --git a/views/accessibility/view_accessibility.h b/views/accessibility/view_accessibility.h deleted file mode 100644 index 9e2d7b8..0000000 --- a/views/accessibility/view_accessibility.h +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef VIEWS_ACCESSIBILITY_VIEW_ACCESSIBILITY_H_ -#define VIEWS_ACCESSIBILITY_VIEW_ACCESSIBILITY_H_ -#pragma once - -#include -#include - -#include - -#include "base/scoped_ptr.h" -#include "views/controls/native/native_view_host.h" -#include "views/view.h" - -//////////////////////////////////////////////////////////////////////////////// -// -// ViewAccessibility -// -// Class implementing the MSAA IAccessible COM interface for a generic View, -// providing accessibility to be used by screen readers and other assistive -// technology (AT). -// -//////////////////////////////////////////////////////////////////////////////// -class ATL_NO_VTABLE ViewAccessibility - : public CComObjectRootEx, - public IDispatchImpl { - public: - BEGIN_COM_MAP(ViewAccessibility) - COM_INTERFACE_ENTRY2(IDispatch, IAccessible) - COM_INTERFACE_ENTRY(IAccessible) - END_COM_MAP() - - // Create method for view accessibility. - static scoped_refptr Create(views::View* view); - - // Returns the IAccessible interface for a view. - static IAccessible* GetAccessibleForView(views::View* view); - - virtual ~ViewAccessibility(); - - void set_view(views::View* view) { view_ = view; } - - // Supported IAccessible methods. - - // Retrieves the child element or child object at a given point on the screen. - STDMETHODIMP accHitTest(LONG x_left, LONG y_top, VARIANT* child); - - // Performs the object's default action. - STDMETHODIMP accDoDefaultAction(VARIANT var_id); - - // Retrieves the specified object's current screen location. - STDMETHODIMP accLocation(LONG* x_left, - LONG* y_top, - LONG* width, - LONG* height, - VARIANT var_id); - - // Traverses to another UI element and retrieves the object. - STDMETHODIMP accNavigate(LONG nav_dir, VARIANT start, VARIANT* end); - - // Retrieves an IDispatch interface pointer for the specified child. - STDMETHODIMP get_accChild(VARIANT var_child, IDispatch** disp_child); - - // Retrieves the number of accessible children. - STDMETHODIMP get_accChildCount(LONG* child_count); - - // Retrieves a string that describes the object's default action. - STDMETHODIMP get_accDefaultAction(VARIANT var_id, BSTR* default_action); - - // Retrieves the tooltip description. - STDMETHODIMP get_accDescription(VARIANT var_id, BSTR* desc); - - // Retrieves the object that has the keyboard focus. - STDMETHODIMP get_accFocus(VARIANT* focus_child); - - // Retrieves the specified object's shortcut. - STDMETHODIMP get_accKeyboardShortcut(VARIANT var_id, BSTR* access_key); - - // Retrieves the name of the specified object. - STDMETHODIMP get_accName(VARIANT var_id, BSTR* name); - - // Retrieves the IDispatch interface of the object's parent. - STDMETHODIMP get_accParent(IDispatch** disp_parent); - - // Retrieves information describing the role of the specified object. - STDMETHODIMP get_accRole(VARIANT var_id, VARIANT* role); - - // Retrieves the current state of the specified object. - STDMETHODIMP get_accState(VARIANT var_id, VARIANT* state); - - // Retrieves the current value associated with the specified object. - STDMETHODIMP get_accValue(VARIANT var_id, BSTR* value); - - // Non-supported IAccessible methods. - - // Selections not applicable to views. - STDMETHODIMP get_accSelection(VARIANT* selected); - STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id); - - // Help functions not supported. - STDMETHODIMP get_accHelp(VARIANT var_id, BSTR* help); - STDMETHODIMP get_accHelpTopic(BSTR* help_file, - VARIANT var_id, - LONG* topic_id); - - // Deprecated functions, not implemented here. - STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name); - STDMETHODIMP put_accValue(VARIANT var_id, BSTR put_val); - - // Returns a conversion from the event (as defined in accessibility_types.h) - // to an MSAA event. - static int32 MSAAEvent(AccessibilityTypes::Event event); - - // Returns a conversion from the Role (as defined in accessibility_types.h) - // to an MSAA role. - static int32 MSAARole(AccessibilityTypes::Role role); - - // Returns a conversion from the State (as defined in accessibility_types.h) - // to MSAA states set. - static int32 MSAAState(AccessibilityTypes::State state); - - private: - ViewAccessibility(); - - // Determines navigation direction for accNavigate, based on left, up and - // previous being mapped all to previous and right, down, next being mapped - // to next. Returns true if navigation direction is next, false otherwise. - bool IsNavDirNext(int nav_dir) const; - - // Determines if the navigation target is within the allowed bounds. Returns - // true if it is, false otherwise. - bool IsValidNav(int nav_dir, - int start_id, - int lower_bound, - int upper_bound) const; - - // Determines if the child id variant is valid. - bool IsValidId(const VARIANT& child) const; - - // Helper function which sets applicable states of view. - void SetState(VARIANT* msaa_state, views::View* view); - - // Returns the IAccessible interface for a native view if applicable. - // Returns S_OK on success. - static HRESULT GetNativeIAccessibleInterface( - views::NativeViewHost* native_host, IAccessible** accessible); - - static HRESULT GetNativeIAccessibleInterface( - HWND native_view_window, IAccessible** accessible); - - // Give CComObject access to the class constructor. - template friend class CComObject; - - // Member View needed for view-specific calls. - views::View* view_; - - DISALLOW_COPY_AND_ASSIGN(ViewAccessibility); -}; - -extern const char kViewsNativeHostPropForAccessibility[]; - -#endif // VIEWS_ACCESSIBILITY_VIEW_ACCESSIBILITY_H_ diff --git a/views/controls/button/button.cc b/views/controls/button/button.cc index 7b6cc75..6d18204 100644 --- a/views/controls/button/button.cc +++ b/views/controls/button/button.cc @@ -3,7 +3,9 @@ // found in the LICENSE file. #include "views/controls/button/button.h" + #include "base/utf_string_conversions.h" +#include "ui/base/accessibility/accessible_view_state.h" namespace views { @@ -18,8 +20,12 @@ void Button::SetTooltipText(const std::wstring& tooltip_text) { TooltipTextChanged(); } -void Button::SetAccessibleKeyboardShortcut(const std::wstring& shortcut) { - accessible_shortcut_ = WideToUTF16Hack(shortcut); +void Button::SetAccessibleName(const string16& name) { + accessible_name_ = name; +} + +void Button::SetAccessibleKeyboardShortcut(const string16& shortcut) { + accessible_shortcut_ = shortcut; } //////////////////////////////////////////////////////////////////////////////// @@ -33,12 +39,10 @@ bool Button::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) { return true; } -string16 Button::GetAccessibleKeyboardShortcut() { - return accessible_shortcut_; -} - -AccessibilityTypes::Role Button::GetAccessibleRole() { - return AccessibilityTypes::ROLE_PUSHBUTTON; +void Button::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; + state->name = accessible_name_; + state->keyboard_shortcut = accessible_shortcut_; } //////////////////////////////////////////////////////////////////////////////// diff --git a/views/controls/button/button.h b/views/controls/button/button.h index 263e45f..0c9c6c7 100644 --- a/views/controls/button/button.h +++ b/views/controls/button/button.h @@ -36,13 +36,13 @@ class Button : public View { int mouse_event_flags() const { return mouse_event_flags_; } - void SetAccessibleKeyboardShortcut(const std::wstring& shortcut); + void SetAccessibleName(const string16& name); + void SetAccessibleKeyboardShortcut(const string16& shortcut); // Overridden from View: virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip) OVERRIDE; - virtual string16 GetAccessibleKeyboardShortcut() OVERRIDE; - virtual AccessibilityTypes::Role GetAccessibleRole() OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; protected: // Construct the Button with a Listener. The listener can be NULL. This can be @@ -61,6 +61,7 @@ class Button : public View { string16 tooltip_text_; // Accessibility data. + string16 accessible_name_; string16 accessible_shortcut_; // The id tag associated with this button. Used to disambiguate buttons in diff --git a/views/controls/button/button_dropdown.cc b/views/controls/button/button_dropdown.cc index d2f69e2..a5f7ab1 100644 --- a/views/controls/button/button_dropdown.cc +++ b/views/controls/button/button_dropdown.cc @@ -8,6 +8,7 @@ #include "base/message_loop.h" #include "base/utf_string_conversions.h" #include "grit/app_strings.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/l10n/l10n_util.h" #include "views/controls/menu/view_menu_delegate.h" #include "views/widget/widget.h" @@ -165,16 +166,11 @@ void ButtonDropDown::ShowDropDownMenu(gfx::NativeView window) { // //////////////////////////////////////////////////////////////////////////////// -string16 ButtonDropDown::GetAccessibleDefaultAction() { - return l10n_util::GetStringUTF16(IDS_APP_ACCACTION_PRESS); -} - -AccessibilityTypes::Role ButtonDropDown::GetAccessibleRole() { - return AccessibilityTypes::ROLE_BUTTONDROPDOWN; -} - -AccessibilityTypes::State ButtonDropDown::GetAccessibleState() { - return AccessibilityTypes::STATE_HASPOPUP; +void ButtonDropDown::GetAccessibleState(ui::AccessibleViewState* state) { + CustomButton::GetAccessibleState(state); + state->role = ui::AccessibilityTypes::ROLE_BUTTONDROPDOWN; + state->default_action = l10n_util::GetStringUTF16(IDS_APP_ACCACTION_PRESS); + state->state = ui::AccessibilityTypes::STATE_HASPOPUP; } } // namespace views diff --git a/views/controls/button/button_dropdown.h b/views/controls/button/button_dropdown.h index 07b8276..32f2c5c 100644 --- a/views/controls/button/button_dropdown.h +++ b/views/controls/button/button_dropdown.h @@ -26,9 +26,7 @@ class ButtonDropDown : public ImageButton { virtual ~ButtonDropDown(); // Accessibility accessors, overridden from View. - virtual string16 GetAccessibleDefaultAction() OVERRIDE; - virtual AccessibilityTypes::Role GetAccessibleRole() OVERRIDE; - virtual AccessibilityTypes::State GetAccessibleState() OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; private: // Overridden from CustomButton diff --git a/views/controls/button/checkbox.cc b/views/controls/button/checkbox.cc index 719dfd8..2a34cc5 100644 --- a/views/controls/button/checkbox.cc +++ b/views/controls/button/checkbox.cc @@ -5,6 +5,7 @@ #include "views/controls/button/checkbox.h" #include "base/logging.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/gfx/canvas.h" #include "views/controls/label.h" @@ -158,12 +159,10 @@ void Checkbox::OnBlur() { label_->set_paint_as_focused(false); } -AccessibilityTypes::Role Checkbox::GetAccessibleRole() { - return AccessibilityTypes::ROLE_CHECKBUTTON; -} - -AccessibilityTypes::State Checkbox::GetAccessibleState() { - return checked() ? AccessibilityTypes::STATE_CHECKED : 0; +void Checkbox::GetAccessibleState(ui::AccessibleViewState* state) { + Button::GetAccessibleState(state); + state->role = ui::AccessibilityTypes::ROLE_CHECKBUTTON; + state->state = checked() ? ui::AccessibilityTypes::STATE_CHECKED : 0; } std::string Checkbox::GetClassName() const { diff --git a/views/controls/button/checkbox.h b/views/controls/button/checkbox.h index 71d218d..801b0fd 100644 --- a/views/controls/button/checkbox.h +++ b/views/controls/button/checkbox.h @@ -57,8 +57,7 @@ class Checkbox : public NativeButton { virtual void OnBlur() OVERRIDE; // Accessibility accessors, overridden from View. - virtual AccessibilityTypes::Role GetAccessibleRole() OVERRIDE; - virtual AccessibilityTypes::State GetAccessibleState() OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; // Overridden from NativeButton: virtual void SetLabel(const std::wstring& label) OVERRIDE; diff --git a/views/controls/button/custom_button.cc b/views/controls/button/custom_button.cc index 1696d14..fc349a2 100644 --- a/views/controls/button/custom_button.cc +++ b/views/controls/button/custom_button.cc @@ -4,9 +4,11 @@ #include "views/controls/button/custom_button.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/animation/throb_animation.h" #include "ui/base/keycodes/keyboard_codes.h" #include "views/screen.h" +#include "views/widget/widget.h" namespace views { @@ -57,24 +59,23 @@ void CustomButton::SetAnimationDuration(int duration) { //////////////////////////////////////////////////////////////////////////////// // CustomButton, View overrides: -AccessibilityTypes::State CustomButton::GetAccessibleState() { - int state = 0; +void CustomButton::GetAccessibleState(ui::AccessibleViewState* state) { + Button::GetAccessibleState(state); switch (state_) { case BS_HOT: - state = AccessibilityTypes::STATE_HOTTRACKED; + state->state = ui::AccessibilityTypes::STATE_HOTTRACKED; break; case BS_PUSHED: - state = AccessibilityTypes::STATE_PRESSED; + state->state = ui::AccessibilityTypes::STATE_PRESSED; break; case BS_DISABLED: - state = AccessibilityTypes::STATE_UNAVAILABLE; + state->state = ui::AccessibilityTypes::STATE_UNAVAILABLE; break; case BS_NORMAL: case BS_COUNT: // No additional accessibility state set for this button state. break; } - return state; } void CustomButton::SetEnabled(bool enabled) { @@ -248,8 +249,10 @@ void CustomButton::SetHotTracked(bool flag) { if (state_ != BS_DISABLED) SetState(flag ? BS_HOT : BS_NORMAL); - if (flag) - NotifyAccessibilityEvent(AccessibilityTypes::EVENT_FOCUS); + if (flag) { + GetWidget()->NotifyAccessibilityEvent( + this, ui::AccessibilityTypes::EVENT_FOCUS, true); + } } bool CustomButton::IsHotTracked() const { diff --git a/views/controls/button/custom_button.h b/views/controls/button/custom_button.h index 17dafbf..1a0f75e 100644 --- a/views/controls/button/custom_button.h +++ b/views/controls/button/custom_button.h @@ -48,7 +48,7 @@ class CustomButton : public Button, void SetAnimationDuration(int duration); // Overridden from View: - virtual AccessibilityTypes::State GetAccessibleState() OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; virtual void SetEnabled(bool enabled) OVERRIDE; virtual bool IsEnabled() const OVERRIDE; virtual bool IsFocusable() const OVERRIDE; diff --git a/views/controls/button/menu_button.cc b/views/controls/button/menu_button.cc index f88b106..db138bb 100644 --- a/views/controls/button/menu_button.cc +++ b/views/controls/button/menu_button.cc @@ -7,6 +7,7 @@ #include "base/utf_string_conversions.h" #include "grit/app_strings.h" #include "grit/app_resources.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/dragdrop/drag_drop_types.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" @@ -260,16 +261,11 @@ void MenuButton::OnMouseExited(const MouseEvent& event) { // //////////////////////////////////////////////////////////////////////////////// -string16 MenuButton::GetAccessibleDefaultAction() { - return l10n_util::GetStringUTF16(IDS_APP_ACCACTION_PRESS); -} - -AccessibilityTypes::Role MenuButton::GetAccessibleRole() { - return AccessibilityTypes::ROLE_BUTTONMENU; -} - -AccessibilityTypes::State MenuButton::GetAccessibleState() { - return AccessibilityTypes::STATE_HASPOPUP; +void MenuButton::GetAccessibleState(ui::AccessibleViewState* state) { + CustomButton::GetAccessibleState(state); + state->role = ui::AccessibilityTypes::ROLE_BUTTONMENU; + state->default_action = l10n_util::GetStringUTF16(IDS_APP_ACCACTION_PRESS); + state->state = ui::AccessibilityTypes::STATE_HASPOPUP; } std::string MenuButton::GetClassName() const { diff --git a/views/controls/button/menu_button.h b/views/controls/button/menu_button.h index 55f5a89..c6f3092 100644 --- a/views/controls/button/menu_button.h +++ b/views/controls/button/menu_button.h @@ -58,9 +58,7 @@ class MenuButton : public TextButton { virtual bool OnKeyReleased(const KeyEvent& e); // Accessibility accessors, overridden from View. - virtual string16 GetAccessibleDefaultAction() OVERRIDE; - virtual AccessibilityTypes::Role GetAccessibleRole() OVERRIDE; - virtual AccessibilityTypes::State GetAccessibleState() OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; // Returns views/MenuButton. virtual std::string GetClassName() const; diff --git a/views/controls/button/native_button_win.cc b/views/controls/button/native_button_win.cc index fbba56a..2783c84 100644 --- a/views/controls/button/native_button_win.cc +++ b/views/controls/button/native_button_win.cc @@ -11,6 +11,7 @@ #include "base/win/scoped_comptr.h" #include "base/win/win_util.h" #include "base/win/windows_version.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "views/controls/button/checkbox.h" #include "views/controls/button/native_button.h" #include "views/controls/button/radio_button.h" @@ -71,18 +72,19 @@ void NativeButtonWin::UpdateDefault() { } void NativeButtonWin::UpdateAccessibleName() { - string16 name; - if (native_button_->GetAccessibleName(&name)) { - base::win::ScopedComPtr pAccPropServices; - HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, - IID_IAccPropServices, reinterpret_cast(&pAccPropServices)); - if (SUCCEEDED(hr)) { - VARIANT var; - var.vt = VT_BSTR; - var.bstrVal = SysAllocString(name.c_str()); - hr = pAccPropServices->SetHwndProp(native_view(), OBJID_WINDOW, - CHILDID_SELF, PROPID_ACC_NAME, var); - } + ui::AccessibleViewState state; + native_button_->GetAccessibleState(&state); + string16 name = state.name; + base::win::ScopedComPtr pAccPropServices; + HRESULT hr = CoCreateInstance( + CLSID_AccPropServices, NULL, CLSCTX_SERVER, + IID_IAccPropServices, reinterpret_cast(&pAccPropServices)); + if (SUCCEEDED(hr)) { + VARIANT var; + var.vt = VT_BSTR; + var.bstrVal = SysAllocString(name.c_str()); + hr = pAccPropServices->SetHwndProp(native_view(), OBJID_WINDOW, + CHILDID_SELF, PROPID_ACC_NAME, var); } } diff --git a/views/controls/button/radio_button.cc b/views/controls/button/radio_button.cc index 4074da4..f162f2c 100644 --- a/views/controls/button/radio_button.cc +++ b/views/controls/button/radio_button.cc @@ -5,6 +5,7 @@ #include "views/controls/button/radio_button.h" #include "base/logging.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "views/widget/root_view.h" namespace views { @@ -60,8 +61,9 @@ void RadioButton::SetChecked(bool checked) { //////////////////////////////////////////////////////////////////////////////// // RadioButton, View overrides: -AccessibilityTypes::Role RadioButton::GetAccessibleRole() { - return AccessibilityTypes::ROLE_RADIOBUTTON; +void RadioButton::GetAccessibleState(ui::AccessibleViewState* state) { + Checkbox::GetAccessibleState(state); + state->role = ui::AccessibilityTypes::ROLE_RADIOBUTTON; } View* RadioButton::GetSelectedViewForGroup(int group_id) { diff --git a/views/controls/button/radio_button.h b/views/controls/button/radio_button.h index 7ea35f5..5ff6f76 100644 --- a/views/controls/button/radio_button.h +++ b/views/controls/button/radio_button.h @@ -22,16 +22,18 @@ class RadioButton : public Checkbox { virtual ~RadioButton(); // Overridden from Checkbox: - virtual void SetChecked(bool checked); + virtual void SetChecked(bool checked) OVERRIDE; // Overridden from View: - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual View* GetSelectedViewForGroup(int group_id); - virtual bool IsGroupFocusTraversable() const; - virtual void OnMouseReleased(const MouseEvent& event, bool canceled); + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; + virtual View* GetSelectedViewForGroup(int group_id) OVERRIDE; + virtual bool IsGroupFocusTraversable() const OVERRIDE; + virtual void OnMouseReleased(const MouseEvent& event, bool canceled) + OVERRIDE; protected: - virtual std::string GetClassName() const; + // Overridden from View: + virtual std::string GetClassName() const OVERRIDE; // Overridden from NativeButton: virtual NativeButtonWrapper* CreateWrapper(); diff --git a/views/controls/combobox/combobox.cc b/views/controls/combobox/combobox.cc index be7d719..2f77942 100644 --- a/views/controls/combobox/combobox.cc +++ b/views/controls/combobox/combobox.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/utf_string_conversions.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/models/combobox_model.h" #include "views/controls/combobox/native_combobox_wrapper.h" @@ -52,6 +53,10 @@ void Combobox::SelectionChanged() { listener_->ItemChanged(this, prev_selected_item, selected_item_); } +void Combobox::SetAccessibleName(const string16& name) { + accessible_name_ = name; +} + //////////////////////////////////////////////////////////////////////////////// // Combobox, View overrides: @@ -89,12 +94,10 @@ void Combobox::OnPaintFocusBorder(gfx::Canvas* canvas) { View::OnPaintFocusBorder(canvas); } -AccessibilityTypes::Role Combobox::GetAccessibleRole() { - return AccessibilityTypes::ROLE_COMBOBOX; -} - -string16 Combobox::GetAccessibleValue() { - return model_->GetItemAt(selected_item_); +void Combobox::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_COMBOBOX; + state->name = accessible_name_; + state->value = model_->GetItemAt(selected_item_); } void Combobox::OnFocus() { diff --git a/views/controls/combobox/combobox.h b/views/controls/combobox/combobox.h index 1de06d6..c50fadd 100644 --- a/views/controls/combobox/combobox.h +++ b/views/controls/combobox/combobox.h @@ -58,20 +58,23 @@ class Combobox : public View { // Accessor for |model_|. ComboboxModel* model() const { return model_; } + // Set the accessible name of the combo box. + void SetAccessibleName(const string16& name); + // Overridden from View: - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - virtual void SetEnabled(bool enabled); - virtual bool SkipDefaultKeyEventProcessing(const KeyEvent& e); - virtual void OnPaintFocusBorder(gfx::Canvas* canvas); - virtual AccessibilityTypes::Role GetAccessibleRole() OVERRIDE; - virtual string16 GetAccessibleValue() OVERRIDE; + virtual gfx::Size GetPreferredSize() OVERRIDE; + virtual void Layout() OVERRIDE; + virtual void SetEnabled(bool enabled) OVERRIDE; + virtual bool SkipDefaultKeyEventProcessing(const KeyEvent& e) OVERRIDE; + virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; protected: - virtual void OnFocus(); + // Overridden from View: + virtual void OnFocus() OVERRIDE; virtual void ViewHierarchyChanged(bool is_add, View* parent, - View* child); - virtual std::string GetClassName() const; + View* child) OVERRIDE; + virtual std::string GetClassName() const OVERRIDE; // The object that actually implements the native combobox. NativeComboboxWrapper* native_wrapper_; @@ -86,6 +89,9 @@ class Combobox : public View { // The current selection. int selected_item_; + // The accessible name of the text field. + string16 accessible_name_; + DISALLOW_COPY_AND_ASSIGN(Combobox); }; diff --git a/views/controls/image_view.cc b/views/controls/image_view.cc index 7f05e97..bc86e55 100644 --- a/views/controls/image_view.cc +++ b/views/controls/image_view.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/utf_string_conversions.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/gfx/canvas.h" #include "ui/gfx/insets.h" @@ -126,8 +127,9 @@ void ImageView::OnPaint(gfx::Canvas* canvas) { } } -AccessibilityTypes::Role ImageView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_GRAPHIC; +void ImageView::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_GRAPHIC; + state->name = tooltip_text_; } void ImageView::SetHorizontalAlignment(Alignment ha) { @@ -154,7 +156,6 @@ ImageView::Alignment ImageView::GetVerticalAlignment() { void ImageView::SetTooltipText(const std::wstring& tooltip) { tooltip_text_ = WideToUTF16Hack(tooltip); - SetAccessibleName(WideToUTF16Hack(tooltip)); } std::wstring ImageView::GetTooltipText() { diff --git a/views/controls/image_view.h b/views/controls/image_view.h index b1791ac..cde4bfd 100644 --- a/views/controls/image_view.h +++ b/views/controls/image_view.h @@ -75,10 +75,11 @@ class ImageView : public View { std::wstring GetTooltipText(); // Overriden from View - virtual gfx::Size GetPreferredSize(); - virtual void OnPaint(gfx::Canvas* canvas); - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip); + virtual gfx::Size GetPreferredSize() OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; + virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip) + OVERRIDE; private: // Compute the image origin given the desired size and the receiver alignment diff --git a/views/controls/label.cc b/views/controls/label.cc index 1b105f0..6fedc80 100644 --- a/views/controls/label.cc +++ b/views/controls/label.cc @@ -12,6 +12,7 @@ #include "base/string_split.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/text/text_elider.h" #include "ui/gfx/canvas_skia.h" @@ -106,7 +107,6 @@ void Label::SetText(const std::wstring& text) { text_ = WideToUTF16Hack(text); url_set_ = false; text_size_valid_ = false; - SetAccessibleName(WideToUTF16Hack(text)); PreferredSizeChanged(); SchedulePaint(); } @@ -250,12 +250,10 @@ void Label::SizeToFit(int max_width) { SizeToPreferredSize(); } -AccessibilityTypes::Role Label::GetAccessibleRole() { - return AccessibilityTypes::ROLE_STATICTEXT; -} - -AccessibilityTypes::State Label::GetAccessibleState() { - return AccessibilityTypes::STATE_READONLY; +void Label::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_STATICTEXT; + state->state = ui::AccessibilityTypes::STATE_READONLY; + state->name = text_; } void Label::SetHasFocusBorder(bool has_focus_border) { diff --git a/views/controls/label.h b/views/controls/label.h index d916659..a0ef7d2 100644 --- a/views/controls/label.h +++ b/views/controls/label.h @@ -79,7 +79,7 @@ class Label : public View { virtual void OnPaintBackground(gfx::Canvas* canvas); // Set the font. - void SetFont(const gfx::Font& font); + virtual void SetFont(const gfx::Font& font); // Set the label text. void SetText(const std::wstring& text); @@ -180,8 +180,7 @@ class Label : public View { void SizeToFit(int max_width); // Accessibility accessors, overridden from View. - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual AccessibilityTypes::State GetAccessibleState(); + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; // Gets/sets the flag to determine whether the label should be collapsed when // it's hidden (not visible). If this flag is true, the label will return a diff --git a/views/controls/label_unittest.cc b/views/controls/label_unittest.cc index 6d2ba91..a7b2ac2 100644 --- a/views/controls/label_unittest.cc +++ b/views/controls/label_unittest.cc @@ -5,6 +5,7 @@ #include "base/i18n/rtl.h" #include "base/utf_string_conversions.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/canvas.h" #include "views/border.h" @@ -159,13 +160,11 @@ TEST(LabelTest, Accessibility) { string16 test_text(ASCIIToUTF16("My special text.")); label.SetText(UTF16ToWideHack(test_text)); - EXPECT_EQ(AccessibilityTypes::ROLE_STATICTEXT, label.GetAccessibleRole()); - - string16 name; - EXPECT_TRUE(label.GetAccessibleName(&name)); - EXPECT_EQ(test_text, name); - - EXPECT_TRUE(AccessibilityTypes::STATE_READONLY & label.GetAccessibleState()); + ui::AccessibleViewState state; + label.GetAccessibleState(&state); + EXPECT_EQ(ui::AccessibilityTypes::ROLE_STATICTEXT, state.role); + EXPECT_EQ(test_text, state.name); + EXPECT_TRUE(ui::AccessibilityTypes::STATE_READONLY & state.state); } TEST(LabelTest, SingleLineSizing) { diff --git a/views/controls/link.cc b/views/controls/link.cc index de7512b..c6e22f1 100644 --- a/views/controls/link.cc +++ b/views/controls/link.cc @@ -9,6 +9,7 @@ #endif #include "base/logging.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/font.h" @@ -148,8 +149,9 @@ bool Link::SkipDefaultKeyEventProcessing(const KeyEvent& e) { (e.key_code() == ui::VKEY_RETURN); } -AccessibilityTypes::Role Link::GetAccessibleRole() { - return AccessibilityTypes::ROLE_LINK; +void Link::GetAccessibleState(ui::AccessibleViewState* state) { + Label::GetAccessibleState(state); + state->role = ui::AccessibilityTypes::ROLE_LINK; } void Link::SetFont(const gfx::Font& font) { diff --git a/views/controls/link.h b/views/controls/link.h index 4c9cb8f..e616317 100644 --- a/views/controls/link.h +++ b/views/controls/link.h @@ -46,16 +46,16 @@ class Link : public Label { const LinkController* GetController(); // Overridden from View: - virtual bool OnMousePressed(const MouseEvent& event); - virtual bool OnMouseDragged(const MouseEvent& event); + virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE; + virtual bool OnMouseDragged(const MouseEvent& event) OVERRIDE; virtual void OnMouseReleased(const MouseEvent& event, - bool canceled); - virtual bool OnKeyPressed(const KeyEvent& e); - virtual bool SkipDefaultKeyEventProcessing(const KeyEvent& e); + bool canceled) OVERRIDE; + virtual bool OnKeyPressed(const KeyEvent& e) OVERRIDE; + virtual bool SkipDefaultKeyEventProcessing(const KeyEvent& e) OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; - // Accessibility accessors, overridden from View: - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual void SetFont(const gfx::Font& font); + // Overridden from Label: + virtual void SetFont(const gfx::Font& font) OVERRIDE; // Set whether the link is enabled. virtual void SetEnabled(bool f); diff --git a/views/controls/menu/menu_controller.cc b/views/controls/menu/menu_controller.cc index 906bd40..075b92e 100644 --- a/views/controls/menu/menu_controller.cc +++ b/views/controls/menu/menu_controller.cc @@ -760,8 +760,10 @@ void MenuController::SetSelection(MenuItemView* menu_item, // Notify an accessibility focus event on all menu items except for the root. if (menu_item && (MenuDepth(menu_item) != 1 || - menu_item->GetType() != MenuItemView::SUBMENU)) - menu_item->NotifyAccessibilityEvent(AccessibilityTypes::EVENT_FOCUS); + menu_item->GetType() != MenuItemView::SUBMENU)) { + menu_item->GetWidget()->NotifyAccessibilityEvent( + menu_item, ui::AccessibilityTypes::EVENT_FOCUS, true); + } } // static diff --git a/views/controls/menu/menu_item_view.cc b/views/controls/menu/menu_item_view.cc index ed44c3a..c729c2e 100644 --- a/views/controls/menu/menu_item_view.cc +++ b/views/controls/menu/menu_item_view.cc @@ -6,6 +6,7 @@ #include "base/utf_string_conversions.h" #include "grit/app_strings.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/menu_model.h" #include "ui/gfx/canvas.h" @@ -116,27 +117,23 @@ bool MenuItemView::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) { return false; } -AccessibilityTypes::Role MenuItemView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_MENUITEM; -} - -AccessibilityTypes::State MenuItemView::GetAccessibleState() { - int state = 0; +void MenuItemView::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_MENUITEM; + state->name = GetAccessibleNameForMenuItem(title_, GetAcceleratorText()); switch (GetType()) { case SUBMENU: - state |= AccessibilityTypes::STATE_HASPOPUP; + state->state |= ui::AccessibilityTypes::STATE_HASPOPUP; break; case CHECKBOX: case RADIO: - state |= GetDelegate()->IsItemChecked(GetCommand()) ? - AccessibilityTypes::STATE_CHECKED : 0; + state->state |= GetDelegate()->IsItemChecked(GetCommand()) ? + ui::AccessibilityTypes::STATE_CHECKED : 0; break; case NORMAL: case SEPARATOR: // No additional accessibility states currently for these menu states. break; } - return state; } // static @@ -320,7 +317,6 @@ SubmenuView* MenuItemView::CreateSubmenu() { void MenuItemView::SetTitle(const std::wstring& title) { title_ = WideToUTF16Hack(title); - SetAccessibleName(GetAccessibleNameForMenuItem(title_, GetAcceleratorText())); pref_size_.SetSize(0, 0); // Triggers preferred size recalculation. } diff --git a/views/controls/menu/menu_item_view.h b/views/controls/menu/menu_item_view.h index 5b5e09c..89eab3c 100644 --- a/views/controls/menu/menu_item_view.h +++ b/views/controls/menu/menu_item_view.h @@ -93,9 +93,9 @@ class MenuItemView : public View { virtual ~MenuItemView(); // Overridden from View: - virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip); - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual AccessibilityTypes::State GetAccessibleState(); + virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip) + OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; // Returns the preferred height of menu items. This is only valid when the // menu is about to be shown. diff --git a/views/controls/menu/menu_scroll_view_container.cc b/views/controls/menu/menu_scroll_view_container.cc index 6089838..7a644b1 100644 --- a/views/controls/menu/menu_scroll_view_container.cc +++ b/views/controls/menu/menu_scroll_view_container.cc @@ -10,6 +10,7 @@ #include #endif +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/gfx/canvas_skia.h" #include "ui/gfx/color_utils.h" #include "views/border.h" @@ -162,7 +163,8 @@ class MenuScrollViewContainer::MenuScrollView : public View { // MenuScrollViewContainer ---------------------------------------------------- -MenuScrollViewContainer::MenuScrollViewContainer(SubmenuView* content_view) { +MenuScrollViewContainer::MenuScrollViewContainer(SubmenuView* content_view) + : content_view_(content_view) { scroll_up_button_ = new MenuScrollButton(content_view, true); scroll_down_button_ = new MenuScrollButton(content_view, false); AddChildView(scroll_up_button_); @@ -266,14 +268,16 @@ gfx::Size MenuScrollViewContainer::GetPreferredSize() { return prefsize; } -AccessibilityTypes::Role MenuScrollViewContainer::GetAccessibleRole() { - return AccessibilityTypes::ROLE_MENUBAR; -} +void MenuScrollViewContainer::GetAccessibleState( + ui::AccessibleViewState* state) { + // Get the name from the submenu view. + content_view_->GetAccessibleState(state); -AccessibilityTypes::State MenuScrollViewContainer::GetAccessibleState() { + // Now change the role. + state->role = ui::AccessibilityTypes::ROLE_MENUBAR; // Some AT (like NVDA) will not process focus events on menu item children // unless a parent claims to be focused. - return AccessibilityTypes::STATE_FOCUSED; + state->state = ui::AccessibilityTypes::STATE_FOCUSED; } } // namespace views diff --git a/views/controls/menu/menu_scroll_view_container.h b/views/controls/menu/menu_scroll_view_container.h index 5472091..48914af 100644 --- a/views/controls/menu/menu_scroll_view_container.h +++ b/views/controls/menu/menu_scroll_view_container.h @@ -24,12 +24,11 @@ class MenuScrollViewContainer : public View { View* scroll_up_button() const { return scroll_up_button_; } // View overrides. - virtual void OnPaintBackground(gfx::Canvas* canvas); - virtual void Layout(); - virtual void OnBoundsChanged(); - virtual gfx::Size GetPreferredSize(); - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual AccessibilityTypes::State GetAccessibleState(); + virtual void OnPaintBackground(gfx::Canvas* canvas) OVERRIDE; + virtual void Layout() OVERRIDE; + virtual void OnBoundsChanged() OVERRIDE; + virtual gfx::Size GetPreferredSize() OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; private: class MenuScrollView; @@ -41,6 +40,9 @@ class MenuScrollViewContainer : public View { // The scroll view. MenuScrollView* scroll_view_; + // The content view. + SubmenuView* content_view_; + DISALLOW_COPY_AND_ASSIGN(MenuScrollViewContainer); }; diff --git a/views/controls/menu/submenu_view.cc b/views/controls/menu/submenu_view.cc index 7c1f69e..fb78762 100644 --- a/views/controls/menu/submenu_view.cc +++ b/views/controls/menu/submenu_view.cc @@ -4,12 +4,14 @@ #include "views/controls/menu/submenu_view.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/gfx/canvas.h" #include "views/controls/menu/menu_config.h" #include "views/controls/menu/menu_controller.h" #include "views/controls/menu/menu_host.h" #include "views/controls/menu/menu_scroll_view_container.h" #include "views/widget/root_view.h" +#include "views/widget/widget.h" // Height of the drop indicator. This should be an even number. static const int kDropIndicatorHeight = 2; @@ -125,8 +127,10 @@ void SubmenuView::OnBoundsChanged() { SchedulePaint(); } -AccessibilityTypes::Role SubmenuView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_MENUPOPUP; +void SubmenuView::GetAccessibleState(ui::AccessibleViewState* state) { + // Inherit most of the state from the parent menu item, except the role. + GetMenuItem()->GetAccessibleState(state); + state->role = ui::AccessibilityTypes::ROLE_MENUPOPUP; } void SubmenuView::PaintChildren(gfx::Canvas* canvas) { @@ -233,10 +237,14 @@ void SubmenuView::ShowAt(gfx::NativeWindow parent, if (host_) { host_->ShowMenuHost(do_capture); - GetScrollViewContainer()->NotifyAccessibilityEvent( - AccessibilityTypes::EVENT_MENUSTART); - - NotifyAccessibilityEvent(AccessibilityTypes::EVENT_MENUPOPUPSTART); + GetScrollViewContainer()->GetWidget()->NotifyAccessibilityEvent( + GetScrollViewContainer(), + ui::AccessibilityTypes::EVENT_MENUSTART, + true); + GetWidget()->NotifyAccessibilityEvent( + this, + ui::AccessibilityTypes::EVENT_MENUPOPUPSTART, + true); return; } @@ -247,10 +255,14 @@ void SubmenuView::ShowAt(gfx::NativeWindow parent, ScrollRectToVisible(gfx::Rect(gfx::Point(), gfx::Size(1, 1))); host_->Init(parent, bounds, scroll_view_container_, do_capture); - GetScrollViewContainer()->NotifyAccessibilityEvent( - AccessibilityTypes::EVENT_MENUSTART); - - NotifyAccessibilityEvent(AccessibilityTypes::EVENT_MENUPOPUPSTART); + GetScrollViewContainer()->GetWidget()->NotifyAccessibilityEvent( + GetScrollViewContainer(), + ui::AccessibilityTypes::EVENT_MENUSTART, + true); + GetWidget()->NotifyAccessibilityEvent( + this, + ui::AccessibilityTypes::EVENT_MENUPOPUPSTART, + true); } void SubmenuView::Reposition(const gfx::Rect& bounds) { @@ -260,10 +272,14 @@ void SubmenuView::Reposition(const gfx::Rect& bounds) { void SubmenuView::Close() { if (host_) { - NotifyAccessibilityEvent(AccessibilityTypes::EVENT_MENUPOPUPEND); - - GetScrollViewContainer()->NotifyAccessibilityEvent( - AccessibilityTypes::EVENT_MENUEND); + GetWidget()->NotifyAccessibilityEvent( + this, + ui::AccessibilityTypes::EVENT_MENUPOPUPEND, + true); + GetScrollViewContainer()->GetWidget()->NotifyAccessibilityEvent( + GetScrollViewContainer(), + ui::AccessibilityTypes::EVENT_MENUEND, + true); host_->DestroyMenuHost(); host_ = NULL; @@ -308,12 +324,6 @@ MenuScrollViewContainer* SubmenuView::GetScrollViewContainer() { scroll_view_container_ = new MenuScrollViewContainer(this); // Otherwise MenuHost would delete us. scroll_view_container_->set_parent_owned(false); - - // Use the parent menu item accessible name for the menu view. - string16 accessible_name; - GetMenuItem()->GetAccessibleName(&accessible_name); - scroll_view_container_->SetAccessibleName(accessible_name); - SetAccessibleName(accessible_name); } return scroll_view_container_; } diff --git a/views/controls/menu/submenu_view.h b/views/controls/menu/submenu_view.h index cbe2674..c16c081 100644 --- a/views/controls/menu/submenu_view.h +++ b/views/controls/menu/submenu_view.h @@ -50,15 +50,15 @@ class SubmenuView : public View { // Positions and sizes the child views. This tiles the views vertically, // giving each child the available width. - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); + virtual void Layout() OVERRIDE; + virtual gfx::Size GetPreferredSize() OVERRIDE; // View method. Overridden to schedule a paint. We do this so that when // scrolling occurs, everything is repainted correctly. - virtual void OnBoundsChanged(); + virtual void OnBoundsChanged() OVERRIDE; // Override from View. - virtual AccessibilityTypes::Role GetAccessibleRole(); + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; // Painting. void PaintChildren(gfx::Canvas* canvas); @@ -66,16 +66,16 @@ class SubmenuView : public View { // Drag and drop methods. These are forwarded to the MenuController. virtual bool GetDropFormats( int* formats, - std::set* custom_formats); - virtual bool AreDropTypesRequired(); - virtual bool CanDrop(const OSExchangeData& data); - virtual void OnDragEntered(const DropTargetEvent& event); - virtual int OnDragUpdated(const DropTargetEvent& event); - virtual void OnDragExited(); - virtual int OnPerformDrop(const DropTargetEvent& event); + std::set* custom_formats) OVERRIDE; + virtual bool AreDropTypesRequired() OVERRIDE; + virtual bool CanDrop(const OSExchangeData& data) OVERRIDE; + virtual void OnDragEntered(const DropTargetEvent& event) OVERRIDE; + virtual int OnDragUpdated(const DropTargetEvent& event) OVERRIDE; + virtual void OnDragExited() OVERRIDE; + virtual int OnPerformDrop(const DropTargetEvent& event) OVERRIDE; // Scrolls on menu item boundaries. - virtual bool OnMouseWheel(const MouseWheelEvent& e); + virtual bool OnMouseWheel(const MouseWheelEvent& e) OVERRIDE; // Returns true if the menu is showing. bool IsShowing(); diff --git a/views/controls/native_control.cc b/views/controls/native_control.cc index 34e243e..08d6843 100644 --- a/views/controls/native_control.cc +++ b/views/controls/native_control.cc @@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/scoped_ptr.h" +#include "ui/base/accessibility/accessibility_types.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/keycodes/keyboard_code_conversion_win.h" #include "ui/base/l10n/l10n_util_win.h" @@ -281,7 +282,8 @@ void NativeControl::OnFocus() { if (container_) { DCHECK(container_->GetControl()); ::SetFocus(container_->GetControl()); - NotifyAccessibilityEvent(AccessibilityTypes::EVENT_FOCUS, false); + GetWidget()->NotifyAccessibilityEvent( + this, ui::AccessibilityTypes::EVENT_FOCUS, false); } } diff --git a/views/controls/native_control_gtk.cc b/views/controls/native_control_gtk.cc index a17c4cb..88035c1 100644 --- a/views/controls/native_control_gtk.cc +++ b/views/controls/native_control_gtk.cc @@ -7,7 +7,9 @@ #include #include "base/logging.h" +#include "ui/base/accessibility/accessibility_types.h" #include "views/focus/focus_manager.h" +#include "views/widget/widget.h" namespace views { @@ -66,8 +68,8 @@ void NativeControlGtk::VisibilityChanged(View* starting_from, bool is_visible) { void NativeControlGtk::OnFocus() { DCHECK(native_view()); gtk_widget_grab_focus(native_view()); - - parent()->NotifyAccessibilityEvent(AccessibilityTypes::EVENT_FOCUS); + GetWidget()->NotifyAccessibilityEvent( + parent(), ui::AccessibilityTypes::EVENT_FOCUS, true); } void NativeControlGtk::NativeControlCreated(GtkWidget* native_control) { diff --git a/views/controls/native_control_win.cc b/views/controls/native_control_win.cc index 7e7312b..13a8c2b 100644 --- a/views/controls/native_control_win.cc +++ b/views/controls/native_control_win.cc @@ -7,10 +7,12 @@ #include #include "base/logging.h" +#include "ui/base/accessibility/accessibility_types.h" #include "ui/base/l10n/l10n_util_win.h" #include "ui/base/view_prop.h" #include "ui/base/win/hwnd_util.h" #include "views/focus/focus_manager.h" +#include "views/widget/widget.h" using ui::ViewProp; @@ -112,8 +114,8 @@ void NativeControlWin::OnFocus() { parent_view->HasFocus(); // Send the accessibility focus notification. - parent_view->NotifyAccessibilityEvent(AccessibilityTypes::EVENT_FOCUS, - send_native_event); + parent_view->GetWidget()->NotifyAccessibilityEvent( + parent_view, ui::AccessibilityTypes::EVENT_FOCUS, send_native_event); } //////////////////////////////////////////////////////////////////////////////// diff --git a/views/controls/progress_bar.cc b/views/controls/progress_bar.cc index a6aabb1..e460e27 100644 --- a/views/controls/progress_bar.cc +++ b/views/controls/progress_bar.cc @@ -11,6 +11,7 @@ #include "base/utf_string_conversions.h" #include "third_party/skia/include/effects/SkGradientShader.h" #include "third_party/skia/include/effects/SkBlurMaskFilter.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/gfx/canvas_skia.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/font.h" @@ -310,12 +311,9 @@ void ProgressBar::SetEnabled(bool enabled) { // TODO(denisromanov): Need to switch progress bar color here? } -AccessibilityTypes::Role ProgressBar::GetAccessibleRole() { - return AccessibilityTypes::ROLE_PROGRESSBAR; -} - -AccessibilityTypes::State ProgressBar::GetAccessibleState() { - return AccessibilityTypes::STATE_READONLY; +void ProgressBar::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_PROGRESSBAR; + state->state = ui::AccessibilityTypes::STATE_READONLY; } } // namespace views diff --git a/views/controls/progress_bar.h b/views/controls/progress_bar.h index b2f1202..4366519 100644 --- a/views/controls/progress_bar.h +++ b/views/controls/progress_bar.h @@ -52,14 +52,14 @@ class ProgressBar : public View { virtual void SetTooltipText(const std::wstring& tooltip_text); // Gets the tooltip text if has been specified with SetTooltipText(). - virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip); + virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip) + OVERRIDE; // Sets the enabled state. - virtual void SetEnabled(bool enabled); + virtual void SetEnabled(bool enabled) OVERRIDE; // Accessibility accessors, overridden from View. - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual AccessibilityTypes::State GetAccessibleState(); + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; // Maximum value of progress. static const int kMaxProgress; diff --git a/views/controls/progress_bar_unittest.cc b/views/controls/progress_bar_unittest.cc index 55acfd4..c7fc4df 100644 --- a/views/controls/progress_bar_unittest.cc +++ b/views/controls/progress_bar_unittest.cc @@ -5,6 +5,7 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "views/controls/progress_bar.h" namespace views { @@ -48,17 +49,11 @@ TEST(ProgressBarTest, Accessibility) { ProgressBar bar; bar.SetProgress(62); - EXPECT_EQ(AccessibilityTypes::ROLE_PROGRESSBAR, bar.GetAccessibleRole()); - - string16 name; - EXPECT_FALSE(bar.GetAccessibleName(&name)); - EXPECT_EQ(string16(), name); - string16 accessible_name = ASCIIToUTF16("My progress bar"); - bar.SetAccessibleName(accessible_name); - EXPECT_TRUE(bar.GetAccessibleName(&name)); - EXPECT_EQ(accessible_name, name); - - EXPECT_TRUE(AccessibilityTypes::STATE_READONLY & bar.GetAccessibleState()); + ui::AccessibleViewState state; + bar.GetAccessibleState(&state); + EXPECT_EQ(ui::AccessibilityTypes::ROLE_PROGRESSBAR, state.role); + EXPECT_EQ(string16(), state.name); + EXPECT_TRUE(ui::AccessibilityTypes::STATE_READONLY & state.state); } } // namespace views diff --git a/views/controls/resize_area.cc b/views/controls/resize_area.cc index b3897bb..0769cf9 100644 --- a/views/controls/resize_area.cc +++ b/views/controls/resize_area.cc @@ -5,6 +5,7 @@ #include "views/controls/resize_area.h" #include "base/logging.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/resource/resource_bundle.h" #if defined(OS_LINUX) @@ -74,8 +75,8 @@ void ResizeArea::OnMouseReleased(const views::MouseEvent& event, ReportResizeAmount(canceled ? initial_position_ : event.x(), true); } -AccessibilityTypes::Role ResizeArea::GetAccessibleRole() { - return AccessibilityTypes::ROLE_SEPARATOR; +void ResizeArea::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_SEPARATOR; } void ResizeArea::ReportResizeAmount(int resize_amount, bool last_update) { diff --git a/views/controls/resize_area.h b/views/controls/resize_area.h index 9adb60c..cf9bea7 100644 --- a/views/controls/resize_area.h +++ b/views/controls/resize_area.h @@ -41,13 +41,14 @@ class ResizeArea : public View { virtual ~ResizeArea(); // Overridden from views::View: - virtual std::string GetClassName() const; + virtual std::string GetClassName() const OVERRIDE; virtual gfx::NativeCursor GetCursorForPoint(ui::EventType event_type, - const gfx::Point& p); - virtual bool OnMousePressed(const views::MouseEvent& event); - virtual bool OnMouseDragged(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); - virtual AccessibilityTypes::Role GetAccessibleRole(); + const gfx::Point& p) OVERRIDE; + virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE; + virtual bool OnMouseDragged(const views::MouseEvent& event) OVERRIDE; + virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled) + OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; private: // Report the amount the user resized by to the delegate, accounting for diff --git a/views/controls/scrollbar/scroll_bar.cc b/views/controls/scrollbar/scroll_bar.cc index 94360bb..880a42a 100644 --- a/views/controls/scrollbar/scroll_bar.cc +++ b/views/controls/scrollbar/scroll_bar.cc @@ -5,6 +5,7 @@ #include "views/controls/scrollbar/scroll_bar.h" #include "base/logging.h" +#include "ui/base/accessibility/accessible_view_state.h" namespace views { @@ -22,8 +23,8 @@ ScrollBar::ScrollBar(bool is_horiz) : is_horiz_(is_horiz), ScrollBar::~ScrollBar() { } -AccessibilityTypes::Role ScrollBar::GetAccessibleRole() { - return AccessibilityTypes::ROLE_SCROLLBAR; +void ScrollBar::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_SCROLLBAR; } bool ScrollBar::IsHorizontal() const { diff --git a/views/controls/scrollbar/scroll_bar.h b/views/controls/scrollbar/scroll_bar.h index faed881..d7f187b 100644 --- a/views/controls/scrollbar/scroll_bar.h +++ b/views/controls/scrollbar/scroll_bar.h @@ -60,7 +60,7 @@ class ScrollBar : public View { virtual ~ScrollBar(); // Overridden from View: - virtual AccessibilityTypes::Role GetAccessibleRole(); + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; // Return whether this scrollbar is horizontal bool IsHorizontal() const; diff --git a/views/controls/separator.cc b/views/controls/separator.cc index 1a3ca70..bc1f522 100644 --- a/views/controls/separator.cc +++ b/views/controls/separator.cc @@ -5,6 +5,7 @@ #include "views/controls/separator.h" #include "base/logging.h" +#include "ui/base/accessibility/accessible_view_state.h" #if defined(OS_LINUX) #include "views/controls/native_control_gtk.h" #elif defined(OS_WIN) @@ -92,8 +93,8 @@ std::string Separator::GetClassName() const { return kViewClassName; } -AccessibilityTypes::Role Separator::GetAccessibleRole() { - return AccessibilityTypes::ROLE_SEPARATOR; +void Separator::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_SEPARATOR; } //////////////////////////////////////////////////////////////////////////////// diff --git a/views/controls/separator.h b/views/controls/separator.h index 186d84f..6c4d9c4 100644 --- a/views/controls/separator.h +++ b/views/controls/separator.h @@ -24,14 +24,15 @@ class Separator : public View { virtual ~Separator(); // Overridden from View: - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - virtual AccessibilityTypes::Role GetAccessibleRole(); + virtual void Layout() OVERRIDE; + virtual gfx::Size GetPreferredSize() OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; protected: + // Overridden from View: virtual void ViewHierarchyChanged(bool is_add, View* parent, - View* child); - virtual std::string GetClassName() const; + View* child) OVERRIDE; + virtual std::string GetClassName() const OVERRIDE; private: void CreateNativeWrapper(); diff --git a/views/controls/single_split_view.cc b/views/controls/single_split_view.cc index 2b076d6..96302f7 100644 --- a/views/controls/single_split_view.cc +++ b/views/controls/single_split_view.cc @@ -9,6 +9,7 @@ #endif #include "skia/ext/skia_utils_win.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/gfx/canvas.h" #include "views/background.h" @@ -65,8 +66,9 @@ void SingleSplitView::Layout() { View::Layout(); } -AccessibilityTypes::Role SingleSplitView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_GROUPING; +void SingleSplitView::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_GROUPING; + state->name = accessible_name_; } gfx::Size SingleSplitView::GetPreferredSize() { @@ -150,6 +152,10 @@ void SingleSplitView::CalculateChildrenBounds( } } +void SingleSplitView::SetAccessibleName(const string16& name) { + accessible_name_ = name; +} + bool SingleSplitView::OnMousePressed(const MouseEvent& event) { if (!IsPointInDivider(event.location())) return false; diff --git a/views/controls/single_split_view.h b/views/controls/single_split_view.h index dc69c67..38e7bbb 100644 --- a/views/controls/single_split_view.h +++ b/views/controls/single_split_view.h @@ -42,7 +42,7 @@ class SingleSplitView : public views::View { virtual void OnBoundsChanged(); virtual void Layout(); - virtual AccessibilityTypes::Role GetAccessibleRole(); + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; // SingleSplitView's preferred size is the sum of the preferred widths // and the max of the heights. @@ -75,6 +75,8 @@ class SingleSplitView : public views::View { gfx::Rect* leading_bounds, gfx::Rect* trailing_bounds) const; + void SetAccessibleName(const string16& name); + protected: virtual bool OnMousePressed(const MouseEvent& event); virtual bool OnMouseDragged(const MouseEvent& event); @@ -132,6 +134,9 @@ class SingleSplitView : public views::View { // Observer to notify about user initiated handle movements. Not own by us. Observer* observer_; + // The accessible name of this view. + string16 accessible_name_; + DISALLOW_COPY_AND_ASSIGN(SingleSplitView); }; diff --git a/views/controls/tabbed_pane/tabbed_pane.cc b/views/controls/tabbed_pane/tabbed_pane.cc index eb9f971..1091407 100644 --- a/views/controls/tabbed_pane/tabbed_pane.cc +++ b/views/controls/tabbed_pane/tabbed_pane.cc @@ -5,11 +5,13 @@ #include "views/controls/tabbed_pane/tabbed_pane.h" #include "base/logging.h" +#include "ui/base/accessibility/accessible_view_state.h" // TODO(avi): remove when not needed #include "base/utf_string_conversions.h" #include "ui/base/keycodes/keyboard_codes.h" #include "views/controls/native/native_view_host.h" #include "views/controls/tabbed_pane/native_tabbed_pane_wrapper.h" +#include "views/widget/widget.h" namespace views { @@ -38,7 +40,6 @@ void TabbedPane::AddTabAtIndex(int index, bool select_if_first_tab) { native_tabbed_pane_->AddTabAtIndex(index, title, contents, select_if_first_tab); - contents->SetAccessibleName(WideToUTF16Hack(title)); PreferredSizeChanged(); } @@ -60,6 +61,10 @@ void TabbedPane::SelectTabAt(int index) { native_tabbed_pane_->SelectTabAt(index); } +void TabbedPane::SetAccessibleName(const string16& name) { + accessible_name_ = name; +} + int TabbedPane::GetTabCount() { return native_tabbed_pane_->GetTabCount(); } @@ -118,8 +123,10 @@ void TabbedPane::OnFocus() { native_tabbed_pane_->SetFocus(); View* selected_tab = GetSelectedTab(); - if (selected_tab) - selected_tab->NotifyAccessibilityEvent(AccessibilityTypes::EVENT_FOCUS); + if (selected_tab) { + selected_tab->GetWidget()->NotifyAccessibilityEvent( + selected_tab, ui::AccessibilityTypes::EVENT_FOCUS, true); + } } else View::OnFocus(); // Will focus the RootView window (so we still get @@ -131,8 +138,9 @@ void TabbedPane::OnPaintFocusBorder(gfx::Canvas* canvas) { View::OnPaintFocusBorder(canvas); } -AccessibilityTypes::Role TabbedPane::GetAccessibleRole() { - return AccessibilityTypes::ROLE_PAGETABLIST; +void TabbedPane::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_PAGETABLIST; + state->name = accessible_name_; } gfx::Size TabbedPane::GetPreferredSize() { diff --git a/views/controls/tabbed_pane/tabbed_pane.h b/views/controls/tabbed_pane/tabbed_pane.h index 4fdb727..a968d36 100644 --- a/views/controls/tabbed_pane/tabbed_pane.h +++ b/views/controls/tabbed_pane/tabbed_pane.h @@ -14,7 +14,6 @@ class NativeTabbedPaneWrapper; // The TabbedPane class is a view that shows tabs. When the user clicks on a // tab, the associated view is displayed. - class TabbedPane : public View { public: TabbedPane(); @@ -63,16 +62,20 @@ class TabbedPane : public View { Listener* listener() const { return listener_; } + void SetAccessibleName(const string16& name); + // View overrides: - virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); + virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child) + OVERRIDE; // Handles Ctrl+Tab and Ctrl+Shift+Tab navigation of pages. - virtual bool AcceleratorPressed(const views::Accelerator& accelerator); - virtual std::string GetClassName() const; - virtual void Layout(); - virtual void OnFocus(); - virtual void OnPaintFocusBorder(gfx::Canvas* canvas); - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual gfx::Size GetPreferredSize(); + virtual bool AcceleratorPressed(const views::Accelerator& accelerator) + OVERRIDE; + virtual std::string GetClassName() const OVERRIDE; + virtual void Layout() OVERRIDE; + virtual void OnFocus() OVERRIDE; + virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; + virtual gfx::Size GetPreferredSize() OVERRIDE; NativeTabbedPaneWrapper* native_wrapper() const { return native_tabbed_pane_; @@ -96,6 +99,9 @@ class TabbedPane : public View { // The listener we notify about tab selection changes. Listener* listener_; + // The accessible name of this view. + string16 accessible_name_; + DISALLOW_COPY_AND_ASSIGN(TabbedPane); }; diff --git a/views/controls/textfield/native_textfield_win.cc b/views/controls/textfield/native_textfield_win.cc index 2047d40..8a735d0 100644 --- a/views/controls/textfield/native_textfield_win.cc +++ b/views/controls/textfield/native_textfield_win.cc @@ -12,6 +12,7 @@ #include "base/win/windows_version.h" #include "grit/app_strings.h" #include "skia/ext/skia_utils_win.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/keycodes/keyboard_codes.h" @@ -441,10 +442,11 @@ void NativeTextfieldWin::InitializeAccessibilityInfo() { // We expect it to be a Label preceeding this view (if it exists). string16 name; View* label_view = parent->GetChildViewAt(label_index); - if (label_view->GetClassName() == Label::kViewClassName && - label_view->GetAccessibleName(&name)) { + if (label_view->GetClassName() == Label::kViewClassName) { + ui::AccessibleViewState state; + label_view->GetAccessibleState(&state); hr = pAccPropServices->SetHwndPropStr(m_hWnd, OBJID_CLIENT, - CHILDID_SELF, PROPID_ACC_NAME, name.c_str()); + CHILDID_SELF, PROPID_ACC_NAME, state.name.c_str()); } } } diff --git a/views/controls/textfield/textfield.cc b/views/controls/textfield/textfield.cc index 2a72712..4366a0c 100644 --- a/views/controls/textfield/textfield.cc +++ b/views/controls/textfield/textfield.cc @@ -12,6 +12,7 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/gfx/insets.h" #include "views/controls/native/native_view_host.h" @@ -280,6 +281,10 @@ size_t Textfield::GetCursorPosition() const { return native_wrapper_ ? native_wrapper_->GetCursorPosition() : 0; } +void Textfield::SetAccessibleName(const string16& name) { + accessible_name_ = name; +} + //////////////////////////////////////////////////////////////////////////////// // Textfield, View overrides: @@ -360,23 +365,14 @@ void Textfield::OnBlur() { native_wrapper_->HandleBlur(); } -AccessibilityTypes::Role Textfield::GetAccessibleRole() { - return AccessibilityTypes::ROLE_TEXT; -} - -AccessibilityTypes::State Textfield::GetAccessibleState() { - int state = 0; +void Textfield::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_TEXT; + state->name = accessible_name_; if (read_only()) - state |= AccessibilityTypes::STATE_READONLY; + state->state |= ui::AccessibilityTypes::STATE_READONLY; if (IsPassword()) - state |= AccessibilityTypes::STATE_PROTECTED; - return state; -} - -string16 Textfield::GetAccessibleValue() { - if (!text_.empty()) - return text_; - return string16(); + state->state |= ui::AccessibilityTypes::STATE_PROTECTED; + state->value = text_; } void Textfield::SetEnabled(bool enabled) { diff --git a/views/controls/textfield/textfield.h b/views/controls/textfield/textfield.h index c8484d5..47285f7 100644 --- a/views/controls/textfield/textfield.h +++ b/views/controls/textfield/textfield.h @@ -247,6 +247,9 @@ class Textfield : public View { // only and has to be called after the wrapper is created. size_t GetCursorPosition() const; + // Set the accessible name of the text field. + void SetAccessibleName(const string16& name); + #ifdef UNIT_TEST gfx::NativeView GetTestingHandle() const { return native_wrapper_ ? native_wrapper_->GetTestingHandle() : NULL; @@ -269,9 +272,7 @@ class Textfield : public View { virtual bool OnKeyReleased(const views::KeyEvent& e) OVERRIDE; virtual void OnFocus() OVERRIDE; virtual void OnBlur() OVERRIDE; - virtual AccessibilityTypes::Role GetAccessibleRole() OVERRIDE; - virtual AccessibilityTypes::State GetAccessibleState() OVERRIDE; - virtual string16 GetAccessibleValue() OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; protected: virtual void ViewHierarchyChanged(bool is_add, View* parent, @@ -339,6 +340,9 @@ class Textfield : public View { // Text to display when empty. string16 text_to_display_when_empty_; + // The accessible name of the text field. + string16 accessible_name_; + DISALLOW_COPY_AND_ASSIGN(Textfield); }; diff --git a/views/controls/tree/tree_view.cc b/views/controls/tree/tree_view.cc index 3f6b8bf..4e8a53d 100644 --- a/views/controls/tree/tree_view.cc +++ b/views/controls/tree/tree_view.cc @@ -11,6 +11,7 @@ #include "base/stl_util-inl.h" #include "base/win/win_util.h" #include "grit/app_resources.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/keycodes/keyboard_code_conversion_win.h" #include "ui/base/resource/resource_bundle.h" @@ -60,12 +61,9 @@ TreeView::~TreeView() { ImageList_Destroy(image_list_); } -AccessibilityTypes::Role TreeView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_OUTLINE; -} - -AccessibilityTypes::State TreeView::GetAccessibleState() { - return AccessibilityTypes::STATE_READONLY; +void TreeView::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_OUTLINE; + state->state = ui::AccessibilityTypes::STATE_READONLY; } void TreeView::SetModel(TreeModel* model) { diff --git a/views/controls/tree/tree_view.h b/views/controls/tree/tree_view.h index d4d0771..a542e85 100644 --- a/views/controls/tree/tree_view.h +++ b/views/controls/tree/tree_view.h @@ -79,8 +79,7 @@ class TreeView : public NativeControl, ui::TreeModelObserver { } // Overridden from View: - virtual AccessibilityTypes::Role GetAccessibleRole(); - virtual AccessibilityTypes::State GetAccessibleState(); + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; // Edits the specified node. This cancels the current edit and expands // all parents of node. diff --git a/views/test/test_views_delegate.h b/views/test/test_views_delegate.h index cae1a64f..3d4f2e6 100644 --- a/views/test/test_views_delegate.h +++ b/views/test/test_views_delegate.h @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/scoped_ptr.h" +#include "ui/base/accessibility/accessibility_types.h" #include "ui/base/clipboard/clipboard.h" #include "views/views_delegate.h" @@ -16,7 +17,7 @@ class TestViewsDelegate : public views::ViewsDelegate { virtual ~TestViewsDelegate() {} // Overridden from views::ViewsDelegate: - virtual ui::Clipboard* GetClipboard() const { + virtual ui::Clipboard* GetClipboard() const OVERRIDE { if (!clipboard_.get()) { // Note that we need a MessageLoop for the next call to work. clipboard_.reset(new ui::Clipboard); @@ -26,31 +27,32 @@ class TestViewsDelegate : public views::ViewsDelegate { virtual void SaveWindowPlacement(views::Window* window, const std::wstring& window_name, const gfx::Rect& bounds, - bool maximized) { + bool maximized) OVERRIDE { } virtual bool GetSavedWindowBounds(views::Window* window, const std::wstring& window_name, - gfx::Rect* bounds) const { + gfx::Rect* bounds) const OVERRIDE { return false; } virtual bool GetSavedMaximizedState(views::Window* window, const std::wstring& window_name, - bool* maximized) const { + bool* maximized) const OVERRIDE { return false; } virtual void NotifyAccessibilityEvent( - views::View* view, AccessibilityTypes::Event event_type) {} + views::View* view, ui::AccessibilityTypes::Event event_type) OVERRIDE {} + #if defined(OS_WIN) - virtual HICON GetDefaultWindowIcon() const { + virtual HICON GetDefaultWindowIcon() const OVERRIDE { return NULL; } #endif - virtual void AddRef() {} - virtual void ReleaseRef() {} + + virtual void AddRef() OVERRIDE {} + virtual void ReleaseRef() OVERRIDE {} private: mutable scoped_ptr clipboard_; DISALLOW_COPY_AND_ASSIGN(TestViewsDelegate); }; - diff --git a/views/view.cc b/views/view.cc index bd778c645..dd511ab 100644 --- a/views/view.cc +++ b/views/view.cc @@ -11,6 +11,7 @@ #include "base/scoped_ptr.h" #include "base/utf_string_conversions.h" #include "third_party/skia/include/core/SkRect.h" +#include "ui/base/accessibility/accessibility_types.h" #include "ui/base/dragdrop/drag_drop_types.h" #include "ui/gfx/canvas_skia.h" #include "ui/gfx/path.h" @@ -26,7 +27,7 @@ #if defined(OS_WIN) #include "base/win/scoped_gdi_object.h" -#include "views/accessibility/view_accessibility.h" +#include "views/accessibility/native_view_accessibility_win.h" #endif #if defined(OS_LINUX) #include "ui/base/gtk/scoped_handle_gtk.h" @@ -86,8 +87,8 @@ View::~View() { } #if defined(OS_WIN) - if (view_accessibility_.get()) - view_accessibility_->set_view(NULL); + if (native_view_accessibility_win_.get()) + native_view_accessibility_win_->set_view(NULL); #endif } @@ -985,29 +986,6 @@ bool View::ExceededDragThreshold(int delta_x, int delta_y) { abs(delta_y) > GetVerticalDragThreshold()); } -// Accessibility --------------------------------------------------------------- - -void View::NotifyAccessibilityEvent(AccessibilityTypes::Event event_type) { - NotifyAccessibilityEvent(event_type, true); -} - -bool View::GetAccessibleName(string16* name) { - DCHECK(name); - - if (accessible_name_.empty()) - return false; - *name = accessible_name_; - return true; -} - -AccessibilityTypes::Role View::GetAccessibleRole() { - return AccessibilityTypes::ROLE_CLIENT; -} - -void View::SetAccessibleName(const string16& name) { - accessible_name_ = name; -} - // Scrolling ------------------------------------------------------------------- void View::ScrollRectToVisible(const gfx::Rect& rect) { @@ -1136,7 +1114,8 @@ void View::OnFocus() { // TODO(beng): Investigate whether it's possible for us to move this to // Focus(). // Notify assistive technologies of the focus change. - NotifyAccessibilityEvent(AccessibilityTypes::EVENT_FOCUS); + GetWidget()->NotifyAccessibilityEvent( + this, ui::AccessibilityTypes::EVENT_FOCUS, true); } void View::OnBlur() { diff --git a/views/view.h b/views/view.h index 83af008..f784c8e 100644 --- a/views/view.h +++ b/views/view.h @@ -20,13 +20,11 @@ #include "ui/gfx/native_widget_types.h" #include "ui/gfx/rect.h" #include "views/accelerator.h" -#include "views/accessibility/accessibility_types.h" #include "views/background.h" #include "views/border.h" using ui::OSExchangeData; -class ViewAccessibility; namespace gfx { class Canvas; @@ -35,6 +33,7 @@ class Path; } namespace ui { +struct AccessibleViewState; class ThemeProvider; class Transform; } @@ -52,6 +51,10 @@ class ScrollView; class Widget; class Window; +#if defined(OS_WIN) +class NativeViewAccessibilityWin; +#endif + // ContextMenuController is responsible for showing the context menu for a // View. To use a ContextMenuController invoke SetContextMenuController on a // View. When the appropriate user gesture occurs ShowContextMenu is invoked @@ -530,7 +533,7 @@ class View : public AcceleratorTarget { const Border* border() const { return border_.get(); } // Get the theme provider from the parent widget. - ThemeProvider* GetThemeProvider() const; + virtual ThemeProvider* GetThemeProvider() const; // RTL painting -------------------------------------------------------------- @@ -877,55 +880,15 @@ class View : public AcceleratorTarget { static bool ExceededDragThreshold(int delta_x, int delta_y); // Accessibility ------------------------------------------------------------- - // TODO(ctguil): Move all this out to a AccessibleInfo wrapper class. - - // Notify the platform specific accessibility client of changes in the user - // interface. This will always raise native notifications. - virtual void NotifyAccessibilityEvent(AccessibilityTypes::Event event_type); - - // Raise an accessibility notification with an option to also raise a native - // notification. - virtual void NotifyAccessibilityEvent(AccessibilityTypes::Event event_type, - bool send_native_event); - - // Returns the MSAA default action of the current view. The string returned - // describes the default action that will occur when executing - // IAccessible::DoDefaultAction. For instance, default action of a button is - // 'Press'. - virtual string16 GetAccessibleDefaultAction() { return string16(); } - - // Returns a string containing the mnemonic, or the keyboard shortcut, for a - // given control. - virtual string16 GetAccessibleKeyboardShortcut() { - return string16(); - } - - // Returns a brief, identifying string, containing a unique, readable name of - // a given control. Sets the input string appropriately, and returns true if - // successful. - bool GetAccessibleName(string16* name); - - // Returns the accessibility role of the current view. The role is what - // assistive technologies (ATs) use to determine what behavior to expect from - // a given control. - virtual AccessibilityTypes::Role GetAccessibleRole(); - // Returns the accessibility state of the current view. - virtual AccessibilityTypes::State GetAccessibleState() { - return 0; - } - - // Returns the current value associated with a view. - virtual string16 GetAccessibleValue() { return string16(); } - - // Assigns a string name to the given control. Needed as a View does not know - // which name will be associated with it until it is created to be a - // certain type. - void SetAccessibleName(const string16& name); + // Modifies |state| to reflect the current accessible state of this view. + virtual void GetAccessibleState(ui::AccessibleViewState* state) { } - // Returns an instance of the (platform-specific) accessibility interface for - // the View. - ViewAccessibility* GetViewAccessibility(); +#if defined(OS_WIN) + // Returns an instance of the Windows-specific accessibility interface + // for this View. + NativeViewAccessibilityWin* GetNativeViewAccessibilityWin(); +#endif // Scrolling ----------------------------------------------------------------- // TODO(beng): Figure out if this can live somewhere other than View, i.e. @@ -1408,12 +1371,9 @@ class View : public AcceleratorTarget { // Accessibility ------------------------------------------------------------- - // Name for this view, which can be retrieved by accessibility APIs. - string16 accessible_name_; - #if defined(OS_WIN) - // The accessibility implementation for this View. - scoped_refptr view_accessibility_; + // The Windows-specific accessibility implementation for this View. + scoped_refptr native_view_accessibility_win_; #endif DISALLOW_COPY_AND_ASSIGN(View); diff --git a/views/view_gtk.cc b/views/view_gtk.cc index b666338..5155099 100644 --- a/views/view_gtk.cc +++ b/views/view_gtk.cc @@ -7,25 +7,9 @@ #include #include "base/logging.h" -#include "views/views_delegate.h" namespace views { -void View::NotifyAccessibilityEvent(AccessibilityTypes::Event event_type, - bool send_native_event) { - // Send the notification to the delegate. - if (ViewsDelegate::views_delegate) - ViewsDelegate::views_delegate->NotifyAccessibilityEvent(this, event_type); - - // In the future if we add native GTK accessibility support, the - // notification should be sent here. -} - -ViewAccessibility* View::GetViewAccessibility() { - NOTIMPLEMENTED(); - return NULL; -} - int View::GetHorizontalDragThreshold() { static bool determined_threshold = false; static int drag_threshold = 8; diff --git a/views/view_win.cc b/views/view_win.cc index 2c213c2..011b319 100644 --- a/views/view_win.cc +++ b/views/view_win.cc @@ -13,7 +13,7 @@ #include "ui/base/dragdrop/drag_drop_types.h" #include "ui/gfx/canvas.h" #include "ui/gfx/path.h" -#include "views/accessibility/view_accessibility.h" +#include "views/accessibility/native_view_accessibility_win.h" #include "views/border.h" #include "views/views_delegate.h" #include "views/widget/root_view.h" @@ -22,28 +22,11 @@ namespace views { -void View::NotifyAccessibilityEvent(AccessibilityTypes::Event event_type, - bool send_native_event) { - // Send the notification to the delegate. - if (ViewsDelegate::views_delegate) - ViewsDelegate::views_delegate->NotifyAccessibilityEvent(this, event_type); - - // Now call the Windows-specific method to notify MSAA clients of this - // event. The widget gives us a temporary unique child ID to associate - // with this view so that clients can call get_accChild in ViewAccessibility - // to retrieve the IAccessible associated with this view. - if (send_native_event) { - WidgetWin* view_widget = static_cast(GetWidget()); - int child_id = view_widget->AddAccessibilityViewEvent(this); - ::NotifyWinEvent(ViewAccessibility::MSAAEvent(event_type), - view_widget->GetNativeView(), OBJID_CLIENT, child_id); - } -} - -ViewAccessibility* View::GetViewAccessibility() { - if (!view_accessibility_.get()) - view_accessibility_.swap(ViewAccessibility::Create(this)); - return view_accessibility_.get(); +NativeViewAccessibilityWin* View::GetNativeViewAccessibilityWin() { + if (!native_view_accessibility_win_.get()) + native_view_accessibility_win_.swap( + NativeViewAccessibilityWin::Create(this)); + return native_view_accessibility_win_.get(); } int View::GetHorizontalDragThreshold() { diff --git a/views/views.gyp b/views/views.gyp index f8b145c..41f70c5 100644 --- a/views/views.gyp +++ b/views/views.gyp @@ -74,9 +74,8 @@ # All .cc, .h under views, except unittests 'accelerator.cc', 'accelerator.h', - 'accessibility/accessibility_types.h', - 'accessibility/view_accessibility.cc', - 'accessibility/view_accessibility.h', + 'accessibility/native_view_accessibility_win.cc', + 'accessibility/native_view_accessibility_win.h', 'animation/bounds_animator.cc', 'animation/bounds_animator.h', 'background.cc', @@ -389,9 +388,7 @@ '../build/linux/system.gyp:xext', ], 'sources!': [ - 'accessibility/accessible_wrapper.cc', - 'accessibility/view_accessibility.cc', - 'accessibility/view_accessibility_wrapper.cc', + 'accessibility/native_view_accessibility_win.cc', 'controls/scrollbar/bitmap_scroll_bar.cc', 'controls/combo_box.cc', 'controls/hwnd_view.cc', diff --git a/views/views_delegate.h b/views/views_delegate.h index 98b734e..d7411f6 100644 --- a/views/views_delegate.h +++ b/views/views_delegate.h @@ -11,7 +11,7 @@ #include #endif -#include "views/accessibility/accessibility_types.h" +#include "ui/base/accessibility/accessibility_types.h" namespace gfx { class Rect; @@ -58,10 +58,8 @@ class ViewsDelegate { const std::wstring& window_name, bool* maximized) const = 0; - // Notify the delegate that an accessibility event has happened in - // a particular view. virtual void NotifyAccessibilityEvent( - views::View* view, AccessibilityTypes::Event event_type) = 0; + views::View* view, ui::AccessibilityTypes::Event event_type) = 0; #if defined(OS_WIN) // Retrieves the default window icon to use for windows if none is specified. diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc index 9d4bbc3..65e4002 100644 --- a/views/widget/root_view.cc +++ b/views/widget/root_view.cc @@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/message_loop.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/dragdrop/drag_drop_types.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/gfx/canvas_skia.h" @@ -419,8 +420,8 @@ std::string RootView::GetClassName() const { return kViewClassName; } -AccessibilityTypes::Role RootView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_APPLICATION; +void RootView::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_APPLICATION; } void RootView::OnPaint(gfx::Canvas* canvas) { diff --git a/views/widget/root_view.h b/views/widget/root_view.h index e6d5bcb..d9634b2 100644 --- a/views/widget/root_view.h +++ b/views/widget/root_view.h @@ -117,7 +117,7 @@ class RootView : public View, #endif virtual bool IsVisibleInRootView() const OVERRIDE; virtual std::string GetClassName() const OVERRIDE; - virtual AccessibilityTypes::Role GetAccessibleRole() OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; protected: // Overridden from View: diff --git a/views/widget/widget.h b/views/widget/widget.h index a9eb040..46a37d7 100644 --- a/views/widget/widget.h +++ b/views/widget/widget.h @@ -9,6 +9,7 @@ #include #include "base/scoped_ptr.h" +#include "ui/base/accessibility/accessibility_types.h" #include "ui/gfx/native_widget_types.h" #include "views/focus/focus_manager.h" #include "views/widget/native_widget_delegate.h" @@ -240,6 +241,17 @@ class Widget : public internal::NativeWidgetDelegate, void SetFocusTraversableParent(FocusTraversable* parent); void SetFocusTraversableParentView(View* parent_view); + // Notifies assistive technology that an accessibility event has + // occurred on |view|, such as when the view is focused or when its + // value changes. Pass true for |send_native_event| except for rare + // cases where the view is a native control that's already sending a + // native accessibility event and the duplicate event would cause + // problems. + virtual void NotifyAccessibilityEvent( + View* view, + ui::AccessibilityTypes::Event event_type, + bool send_native_event) = 0; + NativeWidget* native_widget() { return native_widget_; } // Overridden from FocusTraversable: diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 0ae89cb..dfa1b2e 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -21,6 +21,7 @@ #include "ui/base/x/x11_util.h" #include "ui/gfx/canvas_skia_paint.h" #include "ui/gfx/path.h" +#include "views/views_delegate.h" #include "views/focus/view_storage.h" #include "views/widget/drop_target_gtk.h" #include "views/widget/gtk_views_fixed.h" @@ -779,6 +780,18 @@ void WidgetGtk::ViewHierarchyChanged(bool is_add, View* parent, View* child) { } } +void WidgetGtk::NotifyAccessibilityEvent( + View* view, + ui::AccessibilityTypes::Event event_type, + bool send_native_event) { + // Send the notification to the delegate. + if (ViewsDelegate::views_delegate) + ViewsDelegate::views_delegate->NotifyAccessibilityEvent(view, event_type); + + // In the future if we add native GTK accessibility support, the + // notification should be sent here. +} + void WidgetGtk::ClearNativeFocus() { DCHECK(type_ != TYPE_CHILD); if (!GetNativeView()) { diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index 9facf90..a9a7034 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -173,6 +173,10 @@ class WidgetGtk : public Widget, virtual FocusManager* GetFocusManager(); virtual void ViewHierarchyChanged(bool is_add, View *parent, View *child); + virtual void NotifyAccessibilityEvent( + View* view, + ui::AccessibilityTypes::Event event_type, + bool send_native_event); // Clears the focus on the native widget having the focus. virtual void ClearNativeFocus(); diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index e81d5c2..cabe472 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -21,7 +21,7 @@ #include "ui/gfx/canvas_skia.h" #include "ui/gfx/native_theme_win.h" #include "ui/gfx/path.h" -#include "views/accessibility/view_accessibility.h" +#include "views/accessibility/native_view_accessibility_win.h" #include "views/controls/native_control_win.h" #include "views/focus/accelerator_handler.h" #include "views/focus/focus_util_win.h" @@ -507,6 +507,26 @@ void WidgetWin::SetCursor(gfx::NativeCursor cursor) { } } +void WidgetWin::NotifyAccessibilityEvent( + View* view, + ui::AccessibilityTypes::Event event_type, + bool send_native_event) { + // Send the notification to the delegate. + if (ViewsDelegate::views_delegate) + ViewsDelegate::views_delegate->NotifyAccessibilityEvent(view, event_type); + + // Now call the Windows-specific method to notify MSAA clients of this + // event. The widget gives us a temporary unique child ID to associate + // with this view so that clients can call get_accChild in + // NativeViewAccessibilityWin to retrieve the IAccessible associated + // with this view. + if (send_native_event) { + int child_id = AddAccessibilityViewEvent(view); + ::NotifyWinEvent(NativeViewAccessibilityWin::MSAAEvent(event_type), + GetNativeView(), OBJID_CLIENT, child_id); + } +} + //////////////////////////////////////////////////////////////////////////////// // WidgetWin, MessageLoop::Observer implementation: @@ -649,7 +669,7 @@ LRESULT WidgetWin::OnGetObject(UINT uMsg, WPARAM w_param, LPARAM l_param) { if (OBJID_CLIENT == l_param) { // Retrieve MSAA dispatch object for the root view. base::win::ScopedComPtr root( - ViewAccessibility::GetAccessibleForView(GetRootView())); + NativeViewAccessibilityWin::GetAccessibleForView(GetRootView())); // Create a reference that MSAA will marshall to the client. reference_result = LresultFromObject(IID_IAccessible, w_param, diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h index 72414be..add96c1 100644 --- a/views/widget/widget_win.h +++ b/views/widget/widget_win.h @@ -106,8 +106,9 @@ class WidgetWin : public ui::WindowImpl, } // Obtain the view event with the given MSAA child id. Used in - // ViewAccessibility::get_accChild to support requests for children of - // windowless controls. May return NULL (see ViewHierarchyChanged). + // NativeViewAccessibilityWin::get_accChild to support requests for + // children of windowless controls. May return NULL + // (see ViewHierarchyChanged). View* GetAccessibilityViewEventAt(int id); // Add a view that has recently fired an accessibility event. Returns a MSAA @@ -145,6 +146,10 @@ class WidgetWin : public ui::WindowImpl, virtual FocusManager* GetFocusManager(); virtual void ViewHierarchyChanged(bool is_add, View *parent, View *child); + virtual void NotifyAccessibilityEvent( + View* view, + ui::AccessibilityTypes::Event event_type, + bool send_native_event); BOOL IsWindow() const { return ::IsWindow(GetNativeView()); diff --git a/views/window/client_view.cc b/views/window/client_view.cc index de198ed..92dd06d 100644 --- a/views/window/client_view.cc +++ b/views/window/client_view.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/logging.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "views/window/client_view.h" #if defined(OS_LINUX) #include "views/window/hit_test.h" @@ -62,8 +63,8 @@ void ClientView::OnBoundsChanged() { // NonClientView::Layout. } -AccessibilityTypes::Role ClientView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_CLIENT; +void ClientView::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_CLIENT; } } // namespace views diff --git a/views/window/client_view.h b/views/window/client_view.h index 08ddcd4..6dd39fe 100644 --- a/views/window/client_view.h +++ b/views/window/client_view.h @@ -60,9 +60,10 @@ class ClientView : public View { protected: // Overridden from View: - virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); - virtual void OnBoundsChanged(); - virtual AccessibilityTypes::Role GetAccessibleRole(); + virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child) + OVERRIDE; + virtual void OnBoundsChanged() OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; // Accessors for private data members. Window* window() const { return window_; } diff --git a/views/window/dialog_delegate.h b/views/window/dialog_delegate.h index ac6d4e9..36090ca 100644 --- a/views/window/dialog_delegate.h +++ b/views/window/dialog_delegate.h @@ -6,8 +6,8 @@ #define VIEWS_WINDOW_DIALOG_DELEGATE_H_ #pragma once +#include "ui/base/accessibility/accessibility_types.h" #include "ui/base/message_box_flags.h" -#include "views/accessibility/accessibility_types.h" #include "views/window/dialog_client_view.h" #include "views/window/window_delegate.h" @@ -122,10 +122,10 @@ class DialogDelegate : public WindowDelegate { // delegate's Window. DialogClientView* GetDialogClientView() const; - private: + protected: // Overridden from WindowDelegate: - AccessibilityTypes::Role accessible_role() const { - return AccessibilityTypes::ROLE_DIALOG; + virtual ui::AccessibilityTypes::Role GetAccessibleRole() const { + return ui::AccessibilityTypes::ROLE_DIALOG; } }; diff --git a/views/window/non_client_view.cc b/views/window/non_client_view.cc index 210bd10..bb09fa3 100644 --- a/views/window/non_client_view.cc +++ b/views/window/non_client_view.cc @@ -4,6 +4,7 @@ #include "views/window/non_client_view.h" +#include "ui/base/accessibility/accessible_view_state.h" #include "views/widget/root_view.h" #include "views/widget/widget.h" #include "views/window/window.h" @@ -121,6 +122,10 @@ void NonClientView::LayoutFrameView() { frame_view_->Layout(); } +void NonClientView::SetAccessibleName(const string16& name) { + accessible_name_ = name; +} + //////////////////////////////////////////////////////////////////////////////// // NonClientView, View overrides: @@ -174,8 +179,9 @@ views::View* NonClientView::GetEventHandlerForPoint(const gfx::Point& point) { return View::GetEventHandlerForPoint(point); } -AccessibilityTypes::Role NonClientView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_WINDOW; +void NonClientView::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_WINDOW; + state->name = accessible_name_; } //////////////////////////////////////////////////////////////////////////////// @@ -248,8 +254,8 @@ bool NonClientFrameView::ShouldPaintAsActive() const { return GetWindow()->IsActive() || paint_as_active_; } -AccessibilityTypes::Role NonClientFrameView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_WINDOW; +void NonClientFrameView::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_WINDOW; } } // namespace views diff --git a/views/window/non_client_view.h b/views/window/non_client_view.h index db1daff..10c652c 100644 --- a/views/window/non_client_view.h +++ b/views/window/non_client_view.h @@ -69,8 +69,8 @@ class NonClientFrameView : public View { virtual void ResetWindowControls() = 0; // Overridden from View: - virtual bool HitTest(const gfx::Point& l) const; - virtual AccessibilityTypes::Role GetAccessibleRole(); + virtual bool HitTest(const gfx::Point& l) const OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; protected: virtual void OnBoundsChanged(); @@ -205,16 +205,21 @@ class NonClientView : public View { // of a window resize message. void LayoutFrameView(); + // Set the accessible name of this view. + void SetAccessibleName(const string16& name); + // NonClientView, View overrides: - virtual gfx::Size GetPreferredSize(); - virtual gfx::Size GetMinimumSize(); - virtual void Layout(); - virtual AccessibilityTypes::Role GetAccessibleRole(); + virtual gfx::Size GetPreferredSize() OVERRIDE; + virtual gfx::Size GetMinimumSize() OVERRIDE; + virtual void Layout() OVERRIDE; + virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; protected: // NonClientView, View overrides: - virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); - virtual views::View* GetEventHandlerForPoint(const gfx::Point& point); + virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child) + OVERRIDE; + virtual views::View* GetEventHandlerForPoint(const gfx::Point& point) + OVERRIDE; private: // The frame that hosts this NonClientView. @@ -230,6 +235,9 @@ class NonClientView : public View { // dynamically as the system settings change. scoped_ptr frame_view_; + // The accessible name of this view. + string16 accessible_name_; + DISALLOW_COPY_AND_ASSIGN(NonClientView); }; diff --git a/views/window/window_delegate.h b/views/window/window_delegate.h index 04ac6b3..6ef75cc 100644 --- a/views/window/window_delegate.h +++ b/views/window/window_delegate.h @@ -9,7 +9,7 @@ #include #include "base/scoped_ptr.h" -#include "views/accessibility/accessibility_types.h" +#include "ui/base/accessibility/accessibility_types.h" class SkBitmap; @@ -56,11 +56,11 @@ class WindowDelegate { return false; } - virtual AccessibilityTypes::Role accessible_role() const { - return AccessibilityTypes::ROLE_WINDOW; + virtual ui::AccessibilityTypes::Role GetAccessibleRole() const { + return ui::AccessibilityTypes::ROLE_WINDOW; } - virtual AccessibilityTypes::State accessible_state() const { + virtual ui::AccessibilityTypes::State GetAccessibleState() const { return 0; } diff --git a/views/window/window_win.cc b/views/window/window_win.cc index 7776bea..49c9b2a 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -11,6 +11,7 @@ #include "base/win/scoped_gdi_object.h" #include "base/win/win_util.h" #include "base/win/windows_version.h" +#include "ui/base/accessibility/accessibility_types.h" #include "ui/base/keycodes/keyboard_code_conversion_win.h" #include "ui/base/l10n/l10n_util_win.h" #include "ui/base/theme_provider.h" @@ -19,7 +20,7 @@ #include "ui/gfx/font.h" #include "ui/gfx/icon_util.h" #include "ui/gfx/path.h" -#include "views/accessibility/view_accessibility.h" +#include "views/accessibility/native_view_accessibility_win.h" #include "views/widget/root_view.h" #include "views/window/client_view.h" #include "views/window/custom_frame_view.h" @@ -1448,10 +1449,10 @@ void WindowWin::UpdateAccessibleRole() { IID_IAccPropServices, reinterpret_cast(&pAccPropServices)); if (SUCCEEDED(hr)) { VARIANT var; - AccessibilityTypes::Role role = window_delegate_->accessible_role(); + ui::AccessibilityTypes::Role role = window_delegate_->GetAccessibleRole(); if (role) { var.vt = VT_I4; - var.lVal = ViewAccessibility::MSAARole(role); + var.lVal = NativeViewAccessibilityWin::MSAARole(role); hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, var); } @@ -1464,9 +1465,10 @@ void WindowWin::UpdateAccessibleState() { IID_IAccPropServices, reinterpret_cast(&pAccPropServices)); if (SUCCEEDED(hr)) { VARIANT var; - AccessibilityTypes::State state = window_delegate_->accessible_state(); + ui::AccessibilityTypes::State state = + window_delegate_->GetAccessibleState(); if (state) { - var.lVal = ViewAccessibility::MSAAState(state); + var.lVal = NativeViewAccessibilityWin::MSAAState(state); hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_STATE, var); } -- cgit v1.1