diff options
author | mhm@chromium.org <mhm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-15 03:22:17 +0000 |
---|---|---|
committer | mhm@chromium.org <mhm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-15 03:22:17 +0000 |
commit | d02a669af17789501d5f78376a45c8818c69e796 (patch) | |
tree | 7b788961ea4e47edde78fdd922fd828400822968 | |
parent | d66df9d20006d6208882235516919e11fdb34057 (diff) | |
download | chromium_src-d02a669af17789501d5f78376a45c8818c69e796.zip chromium_src-d02a669af17789501d5f78376a45c8818c69e796.tar.gz chromium_src-d02a669af17789501d5f78376a45c8818c69e796.tar.bz2 |
Revert 32012-32017
git cl dcommit somehow committed all my local changes in cygwin
TBR=evan
BUG=none
Review URL: http://codereview.chromium.org/396006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@32019 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/views/accessible_toolbar_view.cc | 273 | ||||
-rw-r--r-- | chrome/browser/views/accessible_toolbar_view.h | 65 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.cc | 30 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.h | 11 | ||||
-rw-r--r-- | chrome/browser/views/detachable_toolbar_view.h | 4 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.cc | 20 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.h | 7 | ||||
-rw-r--r-- | chrome/browser/views/toolbar_view.cc | 249 | ||||
-rw-r--r-- | chrome/browser/views/toolbar_view.h | 39 | ||||
-rwxr-xr-x | chrome/chrome.gyp | 4 | ||||
-rw-r--r-- | views/controls/button/menu_button.cc | 7 | ||||
-rw-r--r-- | views/controls/button/menu_button.h | 8 |
12 files changed, 315 insertions, 402 deletions
diff --git a/chrome/browser/views/accessible_toolbar_view.cc b/chrome/browser/views/accessible_toolbar_view.cc deleted file mode 100644 index 425d699..0000000 --- a/chrome/browser/views/accessible_toolbar_view.cc +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright (c) 2009 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 "base/logging.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/accessible_toolbar_view.h" -#include "views/controls/button/menu_button.h" -#include "views/focus/view_storage.h" -#include "views/widget/root_view.h" -#include "views/widget/tooltip_manager.h" -#include "views/widget/widget.h" - -AccessibleToolbarView::AccessibleToolbarView() - : selected_focused_view_(NULL), - last_focused_view_storage_id_( - views::ViewStorage::GetSharedInstance()->CreateStorageID()) { -} - -AccessibleToolbarView::~AccessibleToolbarView() { -} - -void AccessibleToolbarView::InitiateTraversal() { - // We only traverse if accessibility is active. - if (selected_focused_view_ != NULL) - return; - - // Save the last focused view so that when the user presses ESC, it will - // return back to the last focus. - views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); - view_storage->StoreView(last_focused_view_storage_id_, - GetRootView()->GetFocusedView()); - - // Request focus to the toolbar. - RequestFocus(); -} - -int AccessibleToolbarView::GetNextAccessibleViewIndex(int view_index, - bool forward) { - int modifier = forward ? 1 : -1; - int current_view_index = view_index + modifier; - - while ((current_view_index >= 0) && - (current_view_index < GetChildViewCount())) { - // Try to find the next available view that can be interacted with. That - // view must be enabled, visible, and traversable. - views::View* current_view = GetChildViewAt(current_view_index); - if (current_view->IsEnabled() && current_view->IsVisible() && - IsAccessibleViewTraversable(current_view)) { - return current_view_index; - } - current_view_index += modifier; - } - - // No button is available in the specified direction. - return -1; -} - -bool AccessibleToolbarView::IsAccessibleViewTraversable(views::View* view) { - return true; -} - -void AccessibleToolbarView::DidGainFocus() { - // Check to see if the accessible focus should be restored to previously - // focused button. The must be enabled and visible in the toolbar. - if (!selected_focused_view_ || - !selected_focused_view_->IsEnabled() || - !selected_focused_view_->IsVisible()) { - // Find first accessible child (-1 to start search at parent). - int first_acc_child = GetNextAccessibleViewIndex(-1, true); - - // No buttons enabled or visible. - if (first_acc_child == -1) - return; - - selected_focused_view_ = GetChildViewAt(first_acc_child); - } - - // Set the focus to the current accessible view. - SetFocusToAccessibleView(); -} - -void AccessibleToolbarView::WillLoseFocus() { - // Any tooltips that are active should be hidden when toolbar loses focus. - if (GetWidget() && GetWidget()->GetTooltipManager()) - GetWidget()->GetTooltipManager()->HideKeyboardTooltip(); - - // Removes the child accessibility view's focus and the view from the - // ViewStorage, when toolbar loses focus. - if (selected_focused_view_) { - selected_focused_view_->SetHotTracked(false); - selected_focused_view_ = NULL; - views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); - view_storage->RemoveView(last_focused_view_storage_id_); - } -} - -void AccessibleToolbarView::ShowContextMenu(int x, int y, - bool is_mouse_gesture) { - if (selected_focused_view_) - selected_focused_view_->ShowContextMenu(x, y, is_mouse_gesture); -} - -void AccessibleToolbarView::RequestFocus() { - // When the toolbar needs to request focus, the default implementation of - // View::RequestFocus requires the View to be focusable. Since ToolbarView is - // not technically focused, we need to temporarily set and remove focus so - // that it can focus back to its focused state. |selected_focused_view_| is - // not necessarily set since it can be null if this view has already lost - // focus, such as traversing through the context menu. - SetFocusable(true); - View::RequestFocus(); - SetFocusable(false); -} - -bool AccessibleToolbarView::OnKeyPressed(const views::KeyEvent& e) { - // Paranoia check, button should be initialized upon toolbar gaining focus. - if (!selected_focused_view_) - return View::OnKeyPressed(e); - - int focused_view = GetChildIndex(selected_focused_view_); - int next_view = focused_view; - - switch (e.GetKeyCode()) { - case base::VKEY_LEFT: - next_view = GetNextAccessibleViewIndex(focused_view, false); - break; - case base::VKEY_RIGHT: - next_view = GetNextAccessibleViewIndex(focused_view, true); - break; - case base::VKEY_DOWN: - case base::VKEY_RETURN: - if (selected_focused_view_->GetClassName() == - views::MenuButton::kViewClassName) { - // If a menu button is activated and its menu is displayed, then the - // active tooltip should be hidden. - if (GetWidget()->GetTooltipManager()) - GetWidget()->GetTooltipManager()->HideKeyboardTooltip(); - - // Safe to cast, given to above check. - static_cast<views::MenuButton*>(selected_focused_view_)->Activate(); - - // If activate did not trigger a focus change, the menu button should - // remain hot tracked since the view is still focused. - if (selected_focused_view_) { - // Re-enable hot-tracking, as Activate() will disable it. - selected_focused_view_->SetHotTracked(true); - } - return true; - } - default: - // If key is not handled explicitly, pass it on to view. - return selected_focused_view_->OnKeyPressed(e); - } - - // No buttons enabled, visible, or focus hasn't moved. - if (next_view == -1) - return false; - - // Remove hot-tracking from old focused button. - selected_focused_view_->SetHotTracked(false); - - // All is well, update the focused child member variable. - selected_focused_view_ = GetChildViewAt(next_view); - - // Set the focus to the current accessible view. - SetFocusToAccessibleView(); - return true; -} - -bool AccessibleToolbarView::OnKeyReleased(const views::KeyEvent& e) { - // Paranoia check, button should be initialized upon toolbar gaining focus. - if (!selected_focused_view_) - return false; - - // Have keys be handled by the views themselves. - return selected_focused_view_->OnKeyReleased(e); -} - -bool AccessibleToolbarView::SkipDefaultKeyEventProcessing( - const views::KeyEvent& e) { - // Accessibility focus must be present in order to handle ESC and TAB related - // key events. - if (!selected_focused_view_) - return false; - - // The ancestor *must* be a BrowserView. - views::View* view = GetAncestorWithClassName(BrowserView::kViewClassName); - if (!view) - return false; - - // Given the check above, we can ensure its a BrowserView. - BrowserView* browser_view = static_cast<BrowserView*>(view); - - // Handle ESC and TAB events. - switch (e.GetKeyCode()) { - case base::VKEY_ESCAPE: { - // Retrieve the focused view from the storage so we can request focus back - // to it. If |focus_view| is null, we place focus on the default view. - // |selected_focused_view_| doesn't need to be reset here since it will be - // dealt within the WillLoseFocus method. - views::ViewStorage* view_storage = - views::ViewStorage::GetSharedInstance(); - views::View* focused_view = - view_storage->RetrieveView(last_focused_view_storage_id_); - if (focused_view) { - view_storage->RemoveView(last_focused_view_storage_id_); - focused_view->RequestFocus(); - } else { - browser_view->SetFocusToLocationBar(); - } - return true; - } - case base::VKEY_TAB: { - if (e.IsShiftDown()) { - browser_view->TraverseNextAccessibleToolbar(false); - } else { - browser_view->TraverseNextAccessibleToolbar(true); - } - return true; - } - default: return false; - } -} - -bool AccessibleToolbarView::GetAccessibleName(std::wstring* name) { - *name = accessible_name_; - return !accessible_name_.empty(); -} - -bool AccessibleToolbarView::GetAccessibleRole(AccessibilityTypes::Role* role) { - DCHECK(role); - - *role = AccessibilityTypes::ROLE_TOOLBAR; - return true; -} - -void AccessibleToolbarView::SetAccessibleName(const std::wstring& name) { - accessible_name_ = name; -} - -void AccessibleToolbarView::ViewHierarchyChanged(bool is_add, View* parent, - View* child) { - // When the toolbar is removed, traverse to the next accessible toolbar. - if (!is_add && parent->GetClassName() == BrowserView::kViewClassName) { - // Given the check above, we can ensure its a BrowserView. - BrowserView* browser_view = static_cast<BrowserView*>(parent); - browser_view->TraverseNextAccessibleToolbar(true); - } -} - -void AccessibleToolbarView::SetFocusToAccessibleView() { - // Hot-track new focused button. - selected_focused_view_->SetHotTracked(true); - - // Show the tooltip for the view that got the focus. - if (GetWidget()->GetTooltipManager()) { - GetWidget()->GetTooltipManager()->ShowKeyboardTooltip( - selected_focused_view_); - } - -#if defined(OS_WIN) - // Retrieve information to generate an accessible focus event. - gfx::NativeView wnd = GetWidget()->GetNativeView(); - int view_id = selected_focused_view_->GetID(); - // Notify Access Technology that there was a change in keyboard focus. - ::NotifyWinEvent(EVENT_OBJECT_FOCUS, wnd, OBJID_CLIENT, - static_cast<LONG>(view_id)); -#else - NOTIMPLEMENTED(); -#endif -} diff --git a/chrome/browser/views/accessible_toolbar_view.h b/chrome/browser/views/accessible_toolbar_view.h deleted file mode 100644 index 2827ba5..0000000 --- a/chrome/browser/views/accessible_toolbar_view.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2009 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 CHROME_BROWSER_VIEWS_ACCESSIBLE_TOOLBAR_VIEW_H_ -#define CHROME_BROWSER_VIEWS_ACCESSIBLE_TOOLBAR_VIEW_H_ - -#include "views/view.h" - -// This class provides keyboard access to any view that extends it by intiating -// ALT+SHIFT+T. And once you press TAB or SHIFT-TAB, it will traverse all the -// toolbars within Chrome. Child views are traversed in the order they were -// added. - -class AccessibleToolbarView : public views::View { - public: - AccessibleToolbarView(); - virtual ~AccessibleToolbarView(); - - // Initiate the traversal on the toolbar. - void InitiateTraversal(); - - // Overridden from views::View: - virtual void DidGainFocus(); - virtual void WillLoseFocus(); - virtual bool OnKeyPressed(const views::KeyEvent& e); - virtual bool OnKeyReleased(const views::KeyEvent& e); - virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e); - virtual void ShowContextMenu(int x, int y, bool is_mouse_gesture); - virtual void RequestFocus(); - virtual bool GetAccessibleName(std::wstring* name); - virtual bool GetAccessibleRole(AccessibilityTypes::Role* role); - virtual void SetAccessibleName(const std::wstring& name); - virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); - virtual View* GetAccFocusedChildView() { return selected_focused_view_; } - - protected: - // Returns the index of the next view of the toolbar, starting from the given - // view index. |forward| when true means it will navigate from left to right, - // and vice versa when false. If |view_index| is -1 the first accessible child - // is returned. - int GetNextAccessibleViewIndex(int view_index, bool forward); - - // Invoked from GetNextAccessibleViewIndex to determine if |view| can be - // traversed to. Default implementation returns true, override to return false - // for views you don't want reachable. - virtual bool IsAccessibleViewTraversable(views::View* view); - - private: - // Sets the focus to the currently |acc_focused_view_| view. - void SetFocusToAccessibleView(); - - // Storage of strings needed for accessibility. - std::wstring accessible_name_; - - // Selected child view currently having accessibility focus. - views::View* selected_focused_view_; - - // Last focused view that issued this traversal. - int last_focused_view_storage_id_; - - DISALLOW_COPY_AND_ASSIGN(AccessibleToolbarView); -}; - -#endif // CHROME_BROWSER_VIEWS_ACCESSIBLE_TOOLBAR_VIEW_H_ diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 675038a..a8876de 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -39,6 +39,7 @@ #include "grit/theme_resources.h" #include "views/controls/button/menu_button.h" #include "views/controls/label.h" +#include "views/controls/button/menu_button.h" #include "views/controls/menu/menu_item_view.h" #include "views/drag_utils.h" #include "views/view_constants.h" @@ -692,8 +693,25 @@ int BookmarkBarView::OnPerformDrop(const DropTargetEvent& event) { index); } -bool BookmarkBarView::IsAccessibleViewTraversable(views::View* view) { - return view != bookmarks_separator_view_ && view != instructions_; +bool BookmarkBarView::GetAccessibleName(std::wstring* name) { + DCHECK(name); + + if (!accessible_name_.empty()) { + name->assign(accessible_name_); + return true; + } + return false; +} + +bool BookmarkBarView::GetAccessibleRole(AccessibilityTypes::Role* role) { + DCHECK(role); + + *role = AccessibilityTypes::ROLE_TOOLBAR; + return true; +} + +void BookmarkBarView::SetAccessibleName(const std::wstring& name) { + accessible_name_.assign(name); } void BookmarkBarView::OnStateChanged() { @@ -853,17 +871,15 @@ void BookmarkBarView::Init() { if (!kDefaultFavIcon) kDefaultFavIcon = rb.GetBitmapNamed(IDR_DEFAULT_FAVICON); - // Child views are traversed in the order they are added. Make sure the order
- // they are added matches the visual order. + other_bookmarked_button_ = CreateOtherBookmarkedButton(); + AddChildView(other_bookmarked_button_); + sync_error_button_ = CreateSyncErrorButton(); AddChildView(sync_error_button_); overflow_button_ = CreateOverflowButton(); AddChildView(overflow_button_); - other_bookmarked_button_ = CreateOtherBookmarkedButton(); - AddChildView(other_bookmarked_button_); - bookmarks_separator_view_ = new ButtonSeparatorView(); bookmarks_separator_view_->SetAccessibleName( l10n_util::GetString(IDS_ACCNAME_SEPARATOR)); diff --git a/chrome/browser/views/bookmark_bar_view.h b/chrome/browser/views/bookmark_bar_view.h index 1653ae2..49ac37f 100644 --- a/chrome/browser/views/bookmark_bar_view.h +++ b/chrome/browser/views/bookmark_bar_view.h @@ -71,7 +71,7 @@ class BookmarkBarView : public DetachableToolbarView, static const int kNewtabBarHeight; - BookmarkBarView(Profile* profile, Browser* browser); + explicit BookmarkBarView(Profile* profile, Browser* browser); virtual ~BookmarkBarView(); // Resets the profile. This removes any buttons for the current profile and @@ -112,9 +112,9 @@ class BookmarkBarView : public DetachableToolbarView, virtual int OnDragUpdated(const views::DropTargetEvent& event); virtual void OnDragExited(); virtual int OnPerformDrop(const views::DropTargetEvent& event); - - // AccessibleToolbarView methods: - virtual bool IsAccessibleViewTraversable(views::View* view); + virtual bool GetAccessibleName(std::wstring* name); + virtual bool GetAccessibleRole(AccessibilityTypes::Role* role); + virtual void SetAccessibleName(const std::wstring& name); // ProfileSyncServiceObserver method. virtual void OnStateChanged(); @@ -485,6 +485,9 @@ class BookmarkBarView : public DetachableToolbarView, // Background for extension toolstrips. SkBitmap toolstrip_background_; + // Storage of strings needed for accessibility. + std::wstring accessible_name_; + DISALLOW_COPY_AND_ASSIGN(BookmarkBarView); }; diff --git a/chrome/browser/views/detachable_toolbar_view.h b/chrome/browser/views/detachable_toolbar_view.h index d27ee53..875ad98 100644 --- a/chrome/browser/views/detachable_toolbar_view.h +++ b/chrome/browser/views/detachable_toolbar_view.h @@ -5,14 +5,14 @@ #ifndef CHROME_BROWSER_VIEWS_DETACHABLE_TOOLBAR_VIEW_H_ #define CHROME_BROWSER_VIEWS_DETACHABLE_TOOLBAR_VIEW_H_ -#include "chrome/browser/views/accessible_toolbar_view.h" +#include "views/view.h" class SkBitmap; struct SkRect; // DetachableToolbarView contains functionality common to views that can detach // from the Chrome frame, such as the BookmarkBarView and the Extension shelf. -class DetachableToolbarView : public AccessibleToolbarView { +class DetachableToolbarView : public views::View { public: // The color gradient start value close to the edge of the divider. static const SkColor kEdgeDividerColor; diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index a10fa5b..dd241d1 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -125,7 +125,7 @@ static const int kNewtabBarRoundness = 5; // ------------ // Returned from BrowserView::GetClassName. -const char BrowserView::kViewClassName[] = "browser/views/BrowserView"; +static const char kBrowserViewClassName[] = "browser/views/BrowserView"; /////////////////////////////////////////////////////////////////////////////// // BookmarkExtensionBackground, private: @@ -657,17 +657,6 @@ void BrowserView::PrepareToRunSystemMenu(HMENU menu) { } #endif -void BrowserView::TraverseNextAccessibleToolbar(bool forward) { - // TODO(mohamed) This needs to be smart, that applies to all toolbars. - // Currently it just traverses between bookmarks and toolbar. - if (!forward && toolbar_->IsVisible() && toolbar_->IsEnabled()) { - toolbar_->InitiateTraversal(); - } else if (forward && bookmark_bar_view_->IsVisible() && - bookmark_bar_view_->IsEnabled()) { - bookmark_bar_view_->InitiateTraversal(); - } -} - // static void BrowserView::RegisterBrowserViewPrefs(PrefService* prefs) { prefs->RegisterIntegerPref(prefs::kPluginMessageResponseTimeout, @@ -970,7 +959,7 @@ void BrowserView::UpdateToolbar(TabContents* contents, } void BrowserView::FocusToolbar() { - toolbar_->InitiateTraversal(); + toolbar_->InitializeTraversal(); } void BrowserView::DestroyBrowser() { @@ -1565,6 +1554,7 @@ int BrowserView::NonClientHitTest(const gfx::Point& point) { // Determine if the TabStrip exists and is capable of being clicked on. We // might be a popup window without a TabStrip. if (IsTabStripVisible()) { + // See if the mouse pointer is within the bounds of the TabStrip. gfx::Point point_in_tabstrip_coords(point); View::ConvertPointToView(GetParent(), tabstrip_->GetView(), @@ -1652,7 +1642,7 @@ gfx::Size BrowserView::GetMinimumSize() { // BrowserView, views::View overrides: std::string BrowserView::GetClassName() const { - return kViewClassName; + return kBrowserViewClassName; } void BrowserView::Layout() { @@ -2086,7 +2076,7 @@ bool BrowserView::UpdateChildViewAndLayout(views::View* new_view, new_view->SetBounds((*old_view)->bounds()); new_view->SchedulePaint(); } else if (new_view) { - DCHECK_EQ(0, new_height); + DCHECK(new_height == 0); // The heights are the same, but the old view is null. This only happens // when the height is zero. Zero out the bounds. new_view->SetBounds(0, 0, 0, 0); diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index 7778017..cf4ca78 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -71,9 +71,6 @@ class BrowserView : public BrowserWindow, public views::WindowDelegate, public views::ClientView { public: - // The browser view's class name. - static const char kViewClassName[]; - // Explicitly sets how windows are shown. Use a value of -1 to give the // default behavior. This is used during testing and not generally useful // otherwise. @@ -184,10 +181,6 @@ class BrowserView : public BrowserWindow, void PrepareToRunSystemMenu(HMENU menu); #endif - // Traverses to the next toolbar. |forward| when true, will navigate from left - // to right and vice versa when false. - void TraverseNextAccessibleToolbar(bool forward); - // Returns true if the Browser object associated with this BrowserView is a // normal-type window (i.e. a browser window, not an app or popup). bool IsBrowserTypeNormal() const { diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc index 20346c2..0747331 100644 --- a/chrome/browser/views/toolbar_view.cc +++ b/chrome/browser/views/toolbar_view.cc @@ -51,6 +51,9 @@ #include "views/controls/button/button_dropdown.h" #include "views/controls/label.h" #include "views/drag_utils.h" +#include "views/focus/view_storage.h" +#include "views/widget/root_view.h" +#include "views/widget/tooltip_manager.h" #include "views/window/non_client_view.h" #include "views/window/window.h" @@ -150,6 +153,9 @@ void ZoomMenuModel::Build() { ToolbarView::ToolbarView(Browser* browser) : model_(browser->toolbar_model()), + acc_focused_view_(NULL), + last_focused_view_storage_id_( + views::ViewStorage::GetSharedInstance()->CreateStorageID()), back_(NULL), forward_(NULL), reload_(NULL), @@ -218,11 +224,48 @@ void ToolbarView::Update(TabContents* tab, bool should_restore_state) { browser_actions_->RefreshBrowserActionViews(); } -//////////////////////////////////////////////////////////////////////////////// -// ToolbarView, AccessibleToolbarView overrides: +int ToolbarView::GetNextAccessibleViewIndex(int view_index, bool nav_left) { + int modifier = 1; + + if (nav_left) + modifier = -1; + + int current_view_index = view_index + modifier; + + while ((current_view_index >= 0) && + (current_view_index < GetChildViewCount())) { + // Skip the location bar, as it has its own keyboard navigation. Also skip + // any views that cannot be interacted with. + if (current_view_index == GetChildIndex(location_bar_) || + !GetChildViewAt(current_view_index)->IsEnabled() || + !GetChildViewAt(current_view_index)->IsVisible()) { + current_view_index += modifier; + continue; + } + // Update view_index with the available button index found. + view_index = current_view_index; + break; + } + // Returns the next available button index, or if no button is available in + // the specified direction, remains where it was. + return view_index; +} + +void ToolbarView::InitializeTraversal() { + // If MSAA focus exists, we don't need to traverse, since its already active. + if (acc_focused_view_ != NULL) + return; -bool ToolbarView::IsAccessibleViewTraversable(views::View* view) { - return view != location_bar_; + // Save the last focused view so that when the user presses ESC, it will + // return back to the last focus. + views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); + view_storage->StoreView(last_focused_view_storage_id_, + GetRootView()->GetFocusedView()); + + // HACK: Do not use RequestFocus() here, as the toolbar is not marked as + // "focusable". Instead bypass the sanity check in RequestFocus() and just + // force it to focus, which will do the right thing. + GetRootView()->FocusView(this); } //////////////////////////////////////////////////////////////////////////////// @@ -586,6 +629,204 @@ void ToolbarView::ThemeChanged() { LoadRightSideControlsImages(); } +void ToolbarView::ShowContextMenu(int x, int y, bool is_mouse_gesture) { + if (acc_focused_view_) + acc_focused_view_->ShowContextMenu(x, y, is_mouse_gesture); +} + +void ToolbarView::DidGainFocus() { + // Check to see if MSAA focus should be restored to previously focused button, + // and if button is an enabled, visibled child of toolbar. + if (!acc_focused_view_ || + (acc_focused_view_->GetParent()->GetID() != VIEW_ID_TOOLBAR) || + !acc_focused_view_->IsEnabled() || + !acc_focused_view_->IsVisible()) { + // Find first accessible child (-1 to start search at parent). + int first_acc_child = GetNextAccessibleViewIndex(-1, false); + + // No buttons enabled or visible. + if (first_acc_child == -1) + return; + + set_acc_focused_view(GetChildViewAt(first_acc_child)); + } + + // Default focus is on the toolbar. + int view_index = VIEW_ID_TOOLBAR; + + // Set hot-tracking for child, and update focused_view for MSAA focus event. + if (acc_focused_view_) { + acc_focused_view_->SetHotTracked(true); + + // Show the tooltip for the view that got the focus. + if (GetWidget()->GetTooltipManager()) + GetWidget()->GetTooltipManager()->ShowKeyboardTooltip(acc_focused_view_); + + // Update focused_view with MSAA-adjusted child id. + view_index = acc_focused_view_->GetID(); + } + +#if defined(OS_WIN) + gfx::NativeView wnd = GetWidget()->GetNativeView(); + + // Notify Access Technology that there was a change in keyboard focus. + ::NotifyWinEvent(EVENT_OBJECT_FOCUS, wnd, OBJID_CLIENT, + static_cast<LONG>(view_index)); +#else + // TODO(port): deal with toolbar a11y focus. + NOTIMPLEMENTED(); +#endif +} + +void ToolbarView::WillLoseFocus() { + // Any tooltips that are active should be hidden when toolbar loses focus. + if (GetWidget() && GetWidget()->GetTooltipManager()) + GetWidget()->GetTooltipManager()->HideKeyboardTooltip(); + + // Removes the Child MSAA view's focus and the view from the ViewStorage, + // when toolbar loses focus. + if (acc_focused_view_) { + acc_focused_view_->SetHotTracked(false); + acc_focused_view_ = NULL; + views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); + view_storage->RemoveView(last_focused_view_storage_id_); + } +} + +void ToolbarView::RequestFocus() { + // When the toolbar needs to request focus, the default implementation of + // View::RequestFocus requires the View to be focusable. Since ToolbarView is + // not technically focused, we need to temporarily set and remove focus so + // that it can focus back to its MSAA focused state. |acc_focused_view_| is + // not necessarily set since it can be null if this view has already lost + // focus, such as traversing through the context menu. + SetFocusable(true); + View::RequestFocus(); + SetFocusable(false); +} + +bool ToolbarView::OnKeyPressed(const views::KeyEvent& e) { + // Paranoia check, button should be initialized upon toolbar gaining focus. + if (!acc_focused_view_) + return false; + + int focused_view = GetChildIndex(acc_focused_view_); + int next_view = focused_view; + + switch (e.GetKeyCode()) { + case base::VKEY_LEFT: + next_view = GetNextAccessibleViewIndex(focused_view, true); + break; + case base::VKEY_RIGHT: + next_view = GetNextAccessibleViewIndex(focused_view, false); + break; + case base::VKEY_DOWN: + case base::VKEY_RETURN: + // VKEY_SPACE is already handled by the default case. + if (acc_focused_view_->GetID() == VIEW_ID_PAGE_MENU || + acc_focused_view_->GetID() == VIEW_ID_APP_MENU) { + // If a menu button in toolbar is activated and its menu is displayed, + // then active tooltip should be hidden. + if (GetWidget()->GetTooltipManager()) + GetWidget()->GetTooltipManager()->HideKeyboardTooltip(); + // Safe to cast, given to above view id check. + static_cast<views::MenuButton*>(acc_focused_view_)->Activate(); + if (!acc_focused_view_) { + // Activate triggered a focus change, don't try to change focus. + return true; + } + // Re-enable hot-tracking, as Activate() will disable it. + acc_focused_view_->SetHotTracked(true); + break; + } + default: + // If key is not handled explicitly, pass it on to view. + return acc_focused_view_->OnKeyPressed(e); + } + + // No buttons enabled or visible. + if (next_view == -1) + return false; + + // Only send an event if focus moved. + if (next_view != focused_view) { + // Remove hot-tracking from old focused button. + acc_focused_view_->SetHotTracked(false); + + // All is well, update the focused child member variable. + acc_focused_view_ = GetChildViewAt(next_view); + + // Hot-track new focused button. + acc_focused_view_->SetHotTracked(true); + + // Show the tooltip for the view that got the focus. + if (GetWidget()->GetTooltipManager()) { + GetWidget()->GetTooltipManager()-> + ShowKeyboardTooltip(GetChildViewAt(next_view)); + } +#if defined(OS_WIN) + // Retrieve information to generate an MSAA focus event. + gfx::NativeView wnd = GetWidget()->GetNativeView(); + int view_id = acc_focused_view_->GetID(); + // Notify Access Technology that there was a change in keyboard focus. + ::NotifyWinEvent(EVENT_OBJECT_FOCUS, wnd, OBJID_CLIENT, + static_cast<LONG>(view_id)); +#else + NOTIMPLEMENTED(); +#endif + return true; + } + return false; +} + +bool ToolbarView::OnKeyReleased(const views::KeyEvent& e) { + // Paranoia check, button should be initialized upon toolbar gaining focus. + if (!acc_focused_view_) + return false; + + // Have keys be handled by the views themselves. + return acc_focused_view_->OnKeyReleased(e); +} + +bool ToolbarView::SkipDefaultKeyEventProcessing(const views::KeyEvent& e) { + if (acc_focused_view_ && e.GetKeyCode() == base::VKEY_ESCAPE) { + // Retrieve the focused view from the storage so we can request focus back + // to it. If |focus_view| is null, we place focus on the location bar. + // |acc_focused_view_| doesn't need to be resetted here since it will be + // dealt within the WillLoseFocus method. + views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); + views::View* focused_view = + view_storage->RetrieveView(last_focused_view_storage_id_); + if (focused_view) { + view_storage->RemoveView(last_focused_view_storage_id_); + focused_view->RequestFocus(); + } else { + location_bar_->RequestFocus(); + } + return true; + } + return false; +} + +bool ToolbarView::GetAccessibleName(std::wstring* name) { + if (!accessible_name_.empty()) { + (*name).assign(accessible_name_); + return true; + } + return false; +} + +bool ToolbarView::GetAccessibleRole(AccessibilityTypes::Role* role) { + DCHECK(role); + + *role = AccessibilityTypes::ROLE_TOOLBAR; + return true; +} + +void ToolbarView::SetAccessibleName(const std::wstring& name) { + accessible_name_.assign(name); +} + //////////////////////////////////////////////////////////////////////////////// // ToolbarView, views::DragController implementation: diff --git a/chrome/browser/views/toolbar_view.h b/chrome/browser/views/toolbar_view.h index cfca8b4..94b54e4 100644 --- a/chrome/browser/views/toolbar_view.h +++ b/chrome/browser/views/toolbar_view.h @@ -12,7 +12,6 @@ #include "chrome/browser/bubble_positioner.h" #include "chrome/browser/command_updater.h" #include "chrome/browser/user_data_manager.h" -#include "chrome/browser/views/accessible_toolbar_view.h" #include "chrome/browser/views/go_button.h" #include "chrome/browser/views/location_bar_view.h" #include "chrome/common/pref_member.h" @@ -64,8 +63,8 @@ class ZoomMenuModel : public views::SimpleMenuModel { DISALLOW_COPY_AND_ASSIGN(ZoomMenuModel); }; -// The Browser Window's toolbar. -class ToolbarView : public AccessibleToolbarView, +// The Browser Window's toolbar. Used within BrowserView. +class ToolbarView : public views::View, public views::ViewMenuDelegate, public views::DragController, public views::SimpleMenuModel::Delegate, @@ -92,6 +91,19 @@ class ToolbarView : public AccessibleToolbarView, // (such as user editing) as well. void Update(TabContents* tab, bool should_restore_state); + // Returns the index of the next view of the toolbar, starting from the given + // view index (skipping the location bar), in the given navigation direction + // (nav_left true means navigation right to left, and vice versa). -1 finds + // first accessible child, based on the above policy. + int GetNextAccessibleViewIndex(int view_index, bool nav_left); + + // Initialize the MSAA focus traversal on the toolbar. + void InitializeTraversal(); + + void set_acc_focused_view(views::View* acc_focused_view) { + acc_focused_view_ = acc_focused_view; + } + // Accessors... Browser* browser() const { return browser_; } BrowserActionsContainer* browser_actions() const { return browser_actions_; } @@ -101,9 +113,6 @@ class ToolbarView : public AccessibleToolbarView, views::MenuButton* page_menu() const { return page_menu_; } views::MenuButton* app_menu() const { return app_menu_; } - // Overridden from AccessibleToolbarView: - virtual bool IsAccessibleViewTraversable(views::View* view); - // Overridden from Menu::BaseControllerDelegate: virtual bool GetAcceleratorInfo(int id, views::Accelerator* accel); @@ -143,6 +152,17 @@ class ToolbarView : public AccessibleToolbarView, virtual void Layout(); virtual void Paint(gfx::Canvas* canvas); virtual void ThemeChanged(); + virtual void ShowContextMenu(int x, int y, bool is_mouse_gesture); + virtual void DidGainFocus(); + virtual void WillLoseFocus(); + virtual void RequestFocus(); + virtual bool OnKeyPressed(const views::KeyEvent& e); + virtual bool OnKeyReleased(const views::KeyEvent& e); + virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e); + virtual bool GetAccessibleName(std::wstring* name); + virtual bool GetAccessibleRole(AccessibilityTypes::Role* role); + virtual void SetAccessibleName(const std::wstring& name); + virtual View* GetAccFocusedChildView() { return acc_focused_view_; } private: // Overridden from views::DragController: @@ -191,6 +211,13 @@ class ToolbarView : public AccessibleToolbarView, // The model that contains the security level, text, icon to display... ToolbarModel* model_; + // Storage of strings needed for accessibility. + std::wstring accessible_name_; + // Child view currently having MSAA focus (location bar excluded from arrow + // navigation). + views::View* acc_focused_view_; + int last_focused_view_storage_id_; + // Controls views::ImageButton* back_; views::ImageButton* forward_; diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 9c4ec31..e35bf5e 100755 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -2244,8 +2244,6 @@ 'browser/views/about_network_dialog.h', 'browser/views/accelerator_table_gtk.cc', 'browser/views/accelerator_table_gtk.h', - 'browser/views/accessible_toolbar_view.cc', - 'browser/views/accessible_toolbar_view.h', 'browser/views/autocomplete/autocomplete_popup_contents_view.cc', 'browser/views/autocomplete/autocomplete_popup_contents_view.h', 'browser/views/autocomplete/autocomplete_popup_win.cc', @@ -2804,8 +2802,6 @@ ['include', '^browser/extensions/'], ['include', '^browser/views/accelerator_table_gtk.cc'], ['include', '^browser/views/accelerator_table_gtk.h'], - ['include', '^browser/views/accessible_toolbar_view.cc'], - ['include', '^browser/views/accessible_toolbar_view.h'], ['include', '^browser/views/autocomplete/autocomplete_popup_contents_view.cc'], ['include', '^browser/views/autocomplete/autocomplete_popup_contents_view.h'], ['include', '^browser/views/autocomplete/autocomplete_popup_gtk.cc'], diff --git a/views/controls/button/menu_button.cc b/views/controls/button/menu_button.cc index eb9d952..7fb81cb 100644 --- a/views/controls/button/menu_button.cc +++ b/views/controls/button/menu_button.cc @@ -35,9 +35,6 @@ static const SkBitmap* kMenuMarker = NULL; static const int kMenuMarkerPaddingLeft = 3; static const int kMenuMarkerPaddingRight = -1; -// static -const char MenuButton::kViewClassName[] = "views/MenuButton"; - //////////////////////////////////////////////////////////////////////////////// // // MenuButton - constructors, destructors, initialization @@ -255,8 +252,4 @@ bool MenuButton::GetAccessibleState(AccessibilityTypes::State* state) { return true; } -std::string MenuButton::GetClassName() const { - return kViewClassName; -} - } // namespace views diff --git a/views/controls/button/menu_button.h b/views/controls/button/menu_button.h index 44a93c6..1f5f8e8 100644 --- a/views/controls/button/menu_button.h +++ b/views/controls/button/menu_button.h @@ -5,8 +5,6 @@ #ifndef VIEWS_CONTROLS_BUTTON_MENU_BUTTON_H_ #define VIEWS_CONTROLS_BUTTON_MENU_BUTTON_H_ -#include <string> - #include "app/gfx/font.h" #include "base/time.h" #include "views/background.h" @@ -27,9 +25,6 @@ class ViewMenuDelegate; //////////////////////////////////////////////////////////////////////////////// class MenuButton : public TextButton { public: - // The menu button's class name. - static const char kViewClassName[]; - // // Create a Button MenuButton(ButtonListener* listener, @@ -61,9 +56,6 @@ class MenuButton : public TextButton { virtual bool GetAccessibleRole(AccessibilityTypes::Role* role); virtual bool GetAccessibleState(AccessibilityTypes::State* state); - // Returns views/MenuButton. - virtual std::string GetClassName() const; - protected: // True if the menu is currently visible. bool menu_visible_; |