summaryrefslogtreecommitdiffstats
path: root/ui/views/focus
diff options
context:
space:
mode:
authortfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-26 20:52:36 +0000
committertfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-26 20:52:36 +0000
commitaca5148cbb5c19f23c20e8421ce4e74d3bbd7a05 (patch)
tree6b6dfa178f15c227bfe6cc2afb61e033d4b1c414 /ui/views/focus
parentd1735a7513c5516d2a14eaa8355100e4d7a90cef (diff)
downloadchromium_src-aca5148cbb5c19f23c20e8421ce4e74d3bbd7a05.zip
chromium_src-aca5148cbb5c19f23c20e8421ce4e74d3bbd7a05.tar.gz
chromium_src-aca5148cbb5c19f23c20e8421ce4e74d3bbd7a05.tar.bz2
Remove src/ui/views.
BUG=101590 R=pkasting@chromium.org Review URL: http://codereview.chromium.org/8395036 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@107428 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views/focus')
-rw-r--r--ui/views/focus/accelerator_handler.h68
-rw-r--r--ui/views/focus/accelerator_handler_win.cc59
-rw-r--r--ui/views/focus/focus_manager.cc461
-rw-r--r--ui/views/focus/focus_manager.h303
-rw-r--r--ui/views/focus/focus_search.cc273
-rw-r--r--ui/views/focus/focus_search.h122
6 files changed, 0 insertions, 1286 deletions
diff --git a/ui/views/focus/accelerator_handler.h b/ui/views/focus/accelerator_handler.h
deleted file mode 100644
index 3d0c5e0..0000000
--- a/ui/views/focus/accelerator_handler.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// 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 UI_VIEWS_FOCUS_ACCELERATOR_HANDLER_H_
-#define UI_VIEWS_FOCUS_ACCELERATOR_HANDLER_H_
-#pragma once
-
-#include "build/build_config.h"
-
-#if defined(TOOLKIT_USES_GTK)
-#include <gdk/gdk.h>
-#endif
-
-#include <set>
-#include <vector>
-
-#include "base/message_loop.h"
-
-namespace ui {
-
-#if defined(TOUCH_UI)
-// Dispatch an XEvent to the RootView. Return true if the event was dispatched
-// and handled, false otherwise.
-bool DispatchXEvent(XEvent* xevent);
-
-// Keep a list of touch devices so that it is possible to determine if a pointer
-// event is a touch-event or a mouse-event.
-void SetTouchDeviceList(std::vector<unsigned int>& devices);
-#endif // TOUCH_UI
-
-////////////////////////////////////////////////////////////////////////////////
-// AcceleratorHandler class
-//
-// An object that pre-screens all UI messages for potential accelerators.
-// Registered accelerators are processed regardless of focus within a given
-// Widget or Window.
-//
-// This processing is done at the Dispatcher level rather than on the Widget
-// because of the global nature of this processing, and the fact that not all
-// controls within a window need to be Widgets - some are native controls from
-// the underlying toolkit wrapped by NativeViewHost.
-//
-class AcceleratorHandler : public MessageLoopForUI::Dispatcher {
- public:
- AcceleratorHandler();
- // Dispatcher method. This returns true if an accelerator was processed by the
- // focus manager
-#if defined(OS_WIN)
- virtual bool Dispatch(const MSG& msg);
-#elif defined(TOUCH_UI)
- virtual MesasgePumpDispatcher::DispatchStatus Dispatch(XEvent* xev);
-#else
- virtual bool Dispatch(GdkEvent* event);
-#endif
-
- private:
-#if defined(OS_WIN)
- // The keys currently pressed and consumed by the FocusManager.
- std::set<WPARAM> pressed_keys_;
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(AcceleratorHandler);
-};
-
-} // namespace ui
-
-#endif // UI_VIEWS_FOCUS_ACCELERATOR_HANDLER_H_
diff --git a/ui/views/focus/accelerator_handler_win.cc b/ui/views/focus/accelerator_handler_win.cc
deleted file mode 100644
index ab059ec..0000000
--- a/ui/views/focus/accelerator_handler_win.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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 "ui/views/focus/accelerator_handler.h"
-
-#include "ui/base/keycodes/keyboard_codes.h"
-#include "ui/base/keycodes/keyboard_code_conversion_win.h"
-#include "ui/views/events/event.h"
-#include "ui/views/focus/focus_manager.h"
-#include "ui/views/widget/widget.h"
-
-namespace ui {
-
-AcceleratorHandler::AcceleratorHandler() {
-}
-
-bool AcceleratorHandler::Dispatch(const MSG& msg) {
- bool process_message = true;
-
- if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST) {
- Widget* widget = Widget::GetTopLevelWidgetForNativeView(msg.hwnd);
- FocusManager* focus_manager = widget ? widget->GetFocusManager() : NULL;
- if (focus_manager) {
- switch (msg.message) {
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN: {
- process_message = focus_manager->OnKeyEvent(KeyEvent(msg));
- if (!process_message) {
- // Record that this key is pressed so we can remember not to
- // translate and dispatch the associated WM_KEYUP.
- pressed_keys_.insert(msg.wParam);
- }
- break;
- }
- case WM_KEYUP:
- case WM_SYSKEYUP: {
- std::set<WPARAM>::iterator iter = pressed_keys_.find(msg.wParam);
- if (iter != pressed_keys_.end()) {
- // Don't translate/dispatch the KEYUP since we have eaten the
- // associated KEYDOWN.
- pressed_keys_.erase(iter);
- return true;
- }
- break;
- }
- }
- }
- }
-
- if (process_message) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- return true;
-}
-
-} // namespace ui
diff --git a/ui/views/focus/focus_manager.cc b/ui/views/focus/focus_manager.cc
deleted file mode 100644
index efe65b1..0000000
--- a/ui/views/focus/focus_manager.cc
+++ /dev/null
@@ -1,461 +0,0 @@
-// 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 "ui/views/focus/focus_manager.h"
-
-#include <algorithm>
-
-#include "build/build_config.h"
-
-#if defined(TOOLKIT_USES_GTK)
-#include <gtk/gtk.h>
-#endif
-
-#include "base/logging.h"
-#include "ui/base/keycodes/keyboard_codes.h"
-#include "ui/views/events/event.h"
-#include "ui/views/focus/focus_search.h"
-#include "ui/views/view.h"
-#include "ui/views/widget/root_view.h"
-#include "ui/views/widget/native_widget.h"
-#include "ui/views/widget/widget.h"
-
-namespace ui {
-
-namespace {
-
-FocusEvent::TraversalDirection DirectionFromBool(bool forward) {
- return forward ? FocusEvent::DIRECTION_FORWARD
- : FocusEvent::DIRECTION_REVERSE;
-}
-
-FocusEvent::TraversalDirection DirectionFromKeyEvent(const KeyEvent& event) {
- return DirectionFromBool(!event.IsShiftDown());
-}
-
-bool IsTraverseForward(FocusEvent::TraversalDirection direction) {
- return direction == FocusEvent::DIRECTION_FORWARD;
-}
-
-#if defined(OS_WIN)
-// Don't allow focus traversal if the root window is not part of the active
-// window hierarchy as this would mean we have no focused view and would focus
-// the first focusable view.
-bool CanTraverseFocus(Widget* widget) {
- HWND top_window = widget->native_widget()->GetNativeView();
- HWND active_window = ::GetActiveWindow();
- return active_window == top_window || ::IsChild(active_window, top_window);
-}
-#else
-bool CanTraverseFocus(Widget* widget) {
- return true;
-}
-#endif
-
-}
-
-// FocusManager::WidgetFocusManager ---------------------------------
-
-void FocusManager::WidgetFocusManager::AddFocusChangeListener(
- WidgetFocusChangeListener* listener) {
- DCHECK(std::find(focus_change_listeners_.begin(),
- focus_change_listeners_.end(), listener) ==
- focus_change_listeners_.end()) <<
- "Adding a WidgetFocusChangeListener twice.";
- focus_change_listeners_.push_back(listener);
-}
-
-void FocusManager::WidgetFocusManager::RemoveFocusChangeListener(
- WidgetFocusChangeListener* listener) {
- WidgetFocusChangeListenerList::iterator iter(std::find(
- focus_change_listeners_.begin(),
- focus_change_listeners_.end(),
- listener));
- if (iter != focus_change_listeners_.end()) {
- focus_change_listeners_.erase(iter);
- } else {
- NOTREACHED() <<
- "Attempting to remove an unregistered WidgetFocusChangeListener.";
- }
-}
-
-void FocusManager::WidgetFocusManager::OnWidgetFocusEvent(
- gfx::NativeView focused_before,
- gfx::NativeView focused_now) {
- if (!enabled_)
- return;
-
- // Perform a safe iteration over the focus listeners, as the array
- // may change during notification.
- WidgetFocusChangeListenerList local_listeners(focus_change_listeners_);
- WidgetFocusChangeListenerList::iterator iter(local_listeners.begin());
- for (;iter != local_listeners.end(); ++iter) {
- (*iter)->NativeFocusWillChange(focused_before, focused_now);
- }
-}
-
-// static
-FocusManager::WidgetFocusManager*
-FocusManager::WidgetFocusManager::GetInstance() {
- return Singleton<WidgetFocusManager>::get();
-}
-
-FocusManager::WidgetFocusManager::WidgetFocusManager() : enabled_(true) {}
-
-FocusManager::WidgetFocusManager::~WidgetFocusManager() {}
-
-////////////////////////////////////////////////////////////////////////////////
-// FocusManager, public:
-
-FocusManager::FocusManager(Widget* widget)
- : widget_(widget),
- focused_view_(NULL) {
- DCHECK(widget_);
-}
-
-FocusManager::~FocusManager() {
- // If there are still registered FocusChange listeners, chances are they were
- // leaked so warn about them.
- DCHECK(focus_change_listeners_.empty());
-}
-
-// static
-FocusManager::WidgetFocusManager* FocusManager::GetWidgetFocusManager() {
- return WidgetFocusManager::GetInstance();
-}
-
-bool FocusManager::OnKeyEvent(const KeyEvent& event) {
- // If the focused view wants to process the key event as is, let it be.
- // On Linux we always dispatch key events to the focused view first, so
- // we should not do this check here. See also NativeWidgetGtk::OnKeyEvent().
- if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(event))
- return true;
-
- // Intercept Tab related messages for focus traversal.
- if (CanTraverseFocus(widget_) && IsTabTraversalKeyEvent(event)) {
- AdvanceFocus(DirectionFromKeyEvent(event));
- return false;
- }
-
- // Intercept arrow key messages to switch between grouped views.
- // TODO(beng): Perhaps make this a FocusTraversable that is created for
- // Views that have a group set?
- ui::KeyboardCode key_code = event.key_code();
- if (focused_view_ && focused_view_->group() != -1 &&
- (key_code == ui::VKEY_UP || key_code == ui::VKEY_DOWN ||
- key_code == ui::VKEY_LEFT || key_code == ui::VKEY_RIGHT)) {
- bool next = (key_code == ui::VKEY_RIGHT || key_code == ui::VKEY_DOWN);
- std::vector<View*> views;
- focused_view_->parent()->GetViewsInGroup(focused_view_->group(), &views);
- std::vector<View*>::const_iterator iter = std::find(views.begin(),
- views.end(),
- focused_view_);
- DCHECK(iter != views.end());
- int index = static_cast<int>(iter - views.begin());
- index += next ? 1 : -1;
- if (index < 0) {
- index = static_cast<int>(views.size()) - 1;
- } else if (index >= static_cast<int>(views.size())) {
- index = 0;
- }
- SetFocusedViewWithReasonAndDirection(views[index],
- FocusEvent::REASON_TRAVERSAL,
- DirectionFromBool(next));
- return false;
- }
-
- // Process keyboard accelerators.
- // If the key combination matches an accelerator, the accelerator is
- // triggered, otherwise the key event is processed as usual.
- Accelerator accelerator(event.key_code(), event.GetModifiers());
- if (ProcessAccelerator(accelerator)) {
- // If a shortcut was activated for this keydown message, do not propagate
- // the event further.
- return false;
- }
- return true;
-}
-
-bool FocusManager::ContainsView(View* view) const {
- Widget* widget = view->GetWidget();
- return widget ? widget->GetFocusManager() == this : false;
-}
-
-void FocusManager::RemoveView(View* view) {
- // Clear focus if the removed child was focused.
- if (focused_view_ == view)
- ClearFocus();
-}
-
-void FocusManager::AdvanceFocus(FocusEvent::TraversalDirection direction) {
- View* view = GetNextFocusableView(focused_view_, direction, false);
- // Note: Do not skip this next block when v == focused_view_. If the user
- // tabs past the last focusable element in a web page, we'll get here, and if
- // the TabContentsContainerView is the only focusable view (possible in
- // full-screen mode), we need to run this block in order to cycle around to
- // the first element on the page.
- if (view) {
- SetFocusedViewWithReasonAndDirection(view, FocusEvent::REASON_TRAVERSAL,
- direction);
- }
-}
-
-void FocusManager::SetFocusedViewWithReasonAndDirection(
- View* view,
- FocusEvent::Reason reason,
- FocusEvent::TraversalDirection direction) {
- if (focused_view_ == view)
- return;
-
- View* prev_focused_view = focused_view_;
- if (focused_view_) {
- focused_view_->OnBlur(
- FocusEvent(FocusEvent::TYPE_FOCUS_OUT, reason, direction));
- focused_view_->Invalidate();
- }
-
- // Notified listeners that the focus changed.
- FocusChangeListenerList::const_iterator iter;
- for (iter = focus_change_listeners_.begin();
- iter != focus_change_listeners_.end(); ++iter) {
- (*iter)->FocusWillChange(prev_focused_view, view);
- }
-
- focused_view_ = view;
-
- if (view) {
- view->Invalidate();
- view->OnFocus(FocusEvent(FocusEvent::TYPE_FOCUS_IN, reason, direction));
- // The view might be deleted now.
- }
-}
-
-void FocusManager::ClearFocus() {
- SetFocusedView(NULL);
- widget_->native_widget()->FocusNativeView(NULL);
-}
-
-void FocusManager::ValidateFocusedView() {
- if (focused_view_) {
- if (!ContainsView(focused_view_))
- ClearFocus();
- }
-}
-
-void FocusManager::RegisterAccelerator(
- const Accelerator& accelerator,
- AcceleratorTarget* target) {
- AcceleratorTargetList& targets = accelerators_[accelerator];
- DCHECK(std::find(targets.begin(), targets.end(), target) == targets.end())
- << "Registering the same target multiple times";
- targets.push_front(target);
-}
-
-void FocusManager::UnregisterAccelerator(const Accelerator& accelerator,
- AcceleratorTarget* target) {
- AcceleratorMap::iterator map_iter = accelerators_.find(accelerator);
- if (map_iter == accelerators_.end()) {
- NOTREACHED() << "Unregistering non-existing accelerator";
- return;
- }
-
- AcceleratorTargetList* targets = &map_iter->second;
- AcceleratorTargetList::iterator target_iter =
- std::find(targets->begin(), targets->end(), target);
- if (target_iter == targets->end()) {
- NOTREACHED() << "Unregistering accelerator for wrong target";
- return;
- }
-
- targets->erase(target_iter);
-}
-
-void FocusManager::UnregisterAccelerators(AcceleratorTarget* target) {
- for (AcceleratorMap::iterator map_iter = accelerators_.begin();
- map_iter != accelerators_.end(); ++map_iter) {
- AcceleratorTargetList* targets = &map_iter->second;
- targets->remove(target);
- }
-}
-
-bool FocusManager::ProcessAccelerator(const Accelerator& accelerator) {
- AcceleratorMap::iterator map_iter = accelerators_.find(accelerator);
- if (map_iter != accelerators_.end()) {
- // We have to copy the target list here, because an AcceleratorPressed
- // event handler may modify the list.
- AcceleratorTargetList targets(map_iter->second);
- for (AcceleratorTargetList::iterator iter = targets.begin();
- iter != targets.end(); ++iter) {
- if ((*iter)->AcceleratorPressed(accelerator))
- return true;
- }
- }
- return false;
-}
-
-void FocusManager::AddFocusChangeListener(FocusChangeListener* listener) {
- DCHECK(std::find(focus_change_listeners_.begin(),
- focus_change_listeners_.end(), listener) ==
- focus_change_listeners_.end()) << "Adding a listener twice.";
- focus_change_listeners_.push_back(listener);
-}
-
-void FocusManager::RemoveFocusChangeListener(FocusChangeListener* listener) {
- FocusChangeListenerList::iterator place =
- std::find(focus_change_listeners_.begin(), focus_change_listeners_.end(),
- listener);
- if (place == focus_change_listeners_.end()) {
- NOTREACHED() << "Removing a listener that isn't registered.";
- return;
- }
- focus_change_listeners_.erase(place);
-}
-
-AcceleratorTarget* FocusManager::GetCurrentTargetForAccelerator(
- const Accelerator& accelerator) const {
- AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator);
- if (map_iter == accelerators_.end() || map_iter->second.empty())
- return NULL;
- return map_iter->second.front();
-}
-
-// static
-bool FocusManager::IsTabTraversalKeyEvent(const KeyEvent& key_event) {
- return key_event.key_code() == ui::VKEY_TAB &&
- !key_event.IsControlDown();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// FocusManager, private:
-
-View* FocusManager::GetNextFocusableView(
- View* original_starting_view,
- FocusEvent::TraversalDirection direction,
- bool dont_loop) {
- FocusTraversable* focus_traversable = NULL;
-
- // Let's re-validate the focused view.
- ValidateFocusedView();
-
- View* starting_view = NULL;
- if (original_starting_view) {
- // Search up the containment hierarchy to see if a view is acting as
- // a pane, and wants to implement its own focus traversable to keep
- // the focus trapped within that pane.
- View* pane_search = original_starting_view;
- while (pane_search) {
- focus_traversable = pane_search->GetPaneFocusTraversable();
- if (focus_traversable) {
- starting_view = original_starting_view;
- break;
- }
- pane_search = pane_search->parent();
- }
-
- if (!focus_traversable) {
- if (IsTraverseForward(direction)) {
- // If the starting view has a focus traversable, use it.
- // This is the case with NativeWidgetWins for example.
- focus_traversable = original_starting_view->GetFocusTraversable();
-
- // Otherwise default to the root view.
- if (!focus_traversable) {
- focus_traversable =
- original_starting_view->GetWidget()->GetFocusTraversable();
- starting_view = original_starting_view;
- }
- } else {
- // When you are going back, starting view's FocusTraversable
- // should not be used.
- focus_traversable =
- original_starting_view->GetWidget()->GetFocusTraversable();
- starting_view = original_starting_view;
- }
- }
- } else {
- focus_traversable = widget_->GetFocusTraversable();
- }
-
- // Traverse the FocusTraversable tree down to find the focusable view.
- View* v = FindFocusableView(focus_traversable, starting_view, direction);
- if (v) {
- return v;
- } else {
- // Let's go up in the FocusTraversable tree.
- FocusTraversable* parent_focus_traversable =
- focus_traversable->GetFocusTraversableParent();
- starting_view = focus_traversable->GetFocusTraversableParentView();
- while (parent_focus_traversable) {
- FocusTraversable* new_focus_traversable = NULL;
- View* new_starting_view = NULL;
- // When we are going backward, the parent view might gain the next focus.
- bool check_starting_view = !IsTraverseForward(direction);
- v = parent_focus_traversable->GetFocusSearch()->FindNextFocusableView(
- starting_view, !IsTraverseForward(direction), FocusSearch::UP,
- check_starting_view, &new_focus_traversable, &new_starting_view);
-
- if (new_focus_traversable) {
- DCHECK(!v);
-
- // There is a FocusTraversable, traverse it down.
- v = FindFocusableView(new_focus_traversable, NULL, direction);
- }
-
- if (v)
- return v;
-
- starting_view = focus_traversable->GetFocusTraversableParentView();
- parent_focus_traversable =
- parent_focus_traversable->GetFocusTraversableParent();
- }
-
- // If we get here, we have reached the end of the focus hierarchy, let's
- // loop. Make sure there was at least a view to start with, to prevent
- // infinitely looping in empty windows.
- if (!dont_loop && original_starting_view) {
- // Easy, just clear the selection and press tab again.
- // By calling with NULL as the starting view, we'll start from the
- // top_root_view.
- return GetNextFocusableView(NULL, direction, true);
- }
- }
- return NULL;
-}
-
-// Find the next focusable view for the specified FocusTraversable, starting at
-// the specified view, traversing down the FocusTraversable hierarchy in
-// |direction|.
-View* FocusManager::FindFocusableView(
- FocusTraversable* focus_traversable,
- View* starting_view,
- FocusEvent::TraversalDirection direction) {
- FocusTraversable* new_focus_traversable = NULL;
- View* new_starting_view = NULL;
- View* v = focus_traversable->GetFocusSearch()->FindNextFocusableView(
- starting_view,
- !IsTraverseForward(direction),
- FocusSearch::DOWN,
- false,
- &new_focus_traversable,
- &new_starting_view);
-
- // Let's go down the FocusTraversable tree as much as we can.
- while (new_focus_traversable) {
- DCHECK(!v);
- focus_traversable = new_focus_traversable;
- starting_view = new_starting_view;
- new_focus_traversable = NULL;
- starting_view = NULL;
- v = focus_traversable->GetFocusSearch()->FindNextFocusableView(
- starting_view,
- !IsTraverseForward(direction),
- FocusSearch::DOWN,
- false,
- &new_focus_traversable,
- &new_starting_view);
- }
- return v;
-}
-
-} // namespace ui
diff --git a/ui/views/focus/focus_manager.h b/ui/views/focus/focus_manager.h
deleted file mode 100644
index 2236619..0000000
--- a/ui/views/focus/focus_manager.h
+++ /dev/null
@@ -1,303 +0,0 @@
-// 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 UI_VIEWS_FOCUS_FOCUS_MANAGER_H_
-#define UI_VIEWS_FOCUS_FOCUS_MANAGER_H_
-#pragma once
-
-#include <list>
-#include <map>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/memory/singleton.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/views/events/accelerator.h"
-#include "ui/views/events/focus_event.h"
-
-// The FocusManager class is used to handle focus traversal, store/restore
-// focused views and handle keyboard accelerators.
-//
-// There are 2 types of focus:
-// - the native focus, which is the focus that an gfx::NativeView has.
-// - the view focus, which is the focus that a views::View has.
-//
-// Each native view must register with their Focus Manager so the focus manager
-// gets notified when they are focused (and keeps track of the native focus) and
-// as well so that the tab key events can be intercepted.
-// They can provide when they register a View that is kept in synch in term of
-// focus. This is used in NativeControl for example, where a View wraps an
-// actual native window.
-// This is already done for you if you subclass the NativeControl class or if
-// you use the NativeViewHost class.
-//
-// When creating a top window (derived from views::Widget) that is not a child
-// window, it creates and owns a FocusManager to manage the focus for itself and
-// all its child windows.
-//
-// The FocusTraversable interface exposes the methods a class should implement
-// in order to be able to be focus traversed when tab key is pressed.
-// RootViews implement FocusTraversable.
-// The FocusManager contains a top FocusTraversable instance, which is the top
-// RootView.
-//
-// If you just use views, then the focus traversal is handled for you by the
-// RootView. The default traversal order is the order in which the views have
-// been added to their container. You can modify this order by using the View
-// method SetNextFocusableView().
-//
-// If you are embedding a native view containing a nested RootView (for example
-// by adding a NativeControl that contains a NativeWidgetWin as its native
-// component), then you need to:
-// - override the View::GetFocusTraversable() method in your outer component.
-// It should return the RootView of the inner component. This is used when
-// the focus traversal traverse down the focus hierarchy to enter the nested
-// RootView. In the example mentioned above, the NativeControl overrides
-// GetFocusTraversable() and returns hwnd_view_container_->GetRootView().
-// - call RootView::SetFocusTraversableParent() on the nested RootView and point
-// it to the outter RootView. This is used when the focus goes out of the
-// nested RootView. In the example:
-// hwnd_view_container_->GetRootView()->SetFocusTraversableParent(
-// native_control->GetRootView());
-// - call RootView::SetFocusTraversableParentView() on the nested RootView with
-// the parent view that directly contains the native window. This is needed
-// when traversing up from the nested RootView to know which view to start
-// with when going to the next/previous view.
-// In our example:
-// hwnd_view_container_->GetRootView()->SetFocusTraversableParent(
-// native_control);
-//
-// Note that FocusTraversable do not have to be RootViews: AccessibleToolbarView
-// is FocusTraversable.
-
-namespace ui {
-
-class FocusSearch;
-class RootView;
-class View;
-class Widget;
-
-// The FocusTraversable interface is used by components that want to process
-// focus traversal events (due to Tab/Shift-Tab key events).
-class FocusTraversable {
- public:
- // Return a FocusSearch object that implements the algorithm to find
- // the next or previous focusable view.
- virtual const FocusSearch* GetFocusSearch() const = 0;
-
- // Should return the parent FocusTraversable.
- // The top RootView which is the top FocusTraversable returns NULL.
- virtual FocusTraversable* GetFocusTraversableParent() const = 0;
-
- // This should return the View this FocusTraversable belongs to.
- // It is used when walking up the view hierarchy tree to find which view
- // should be used as the starting view for finding the next/previous view.
- virtual View* GetFocusTraversableParentView() const = 0;
-
- protected:
- virtual ~FocusTraversable() {}
-};
-
-// This interface should be implemented by classes that want to be notified when
-// the focus is about to change. See the Add/RemoveFocusChangeListener methods.
-class FocusChangeListener {
- public:
- virtual void FocusWillChange(View* focused_before, View* focused_now) = 0;
-
- protected:
- virtual ~FocusChangeListener() {}
-};
-
-// This interface should be implemented by classes that want to be notified when
-// the native focus is about to change. Listeners implementing this interface
-// will be invoked for all native focus changes across the entire Chrome
-// application. FocusChangeListeners are only called for changes within the
-// children of a single top-level native-view.
-class WidgetFocusChangeListener {
- public:
- virtual void NativeFocusWillChange(gfx::NativeView focused_before,
- gfx::NativeView focused_now) = 0;
-
- protected:
- virtual ~WidgetFocusChangeListener() {}
-};
-
-class FocusManager {
- public:
- class WidgetFocusManager {
- public:
- // Returns the singleton instance.
- static WidgetFocusManager* GetInstance();
-
- // Adds/removes a WidgetFocusChangeListener |listener| to the set of
- // active listeners.
- void AddFocusChangeListener(WidgetFocusChangeListener* listener);
- void RemoveFocusChangeListener(WidgetFocusChangeListener* listener);
-
- // To be called when native-focus shifts from |focused_before| to
- // |focused_now|.
- // TODO(port) : Invocations to this routine are only implemented for
- // the Win32 platform. Calls need to be placed appropriately for
- // non-Windows environments.
- void OnWidgetFocusEvent(gfx::NativeView focused_before,
- gfx::NativeView focused_now);
-
- // Enable/Disable notification of registered listeners during calls
- // to OnWidgetFocusEvent. Used to prevent unwanted focus changes from
- // propagating notifications.
- void EnableNotifications() { enabled_ = true; }
- void DisableNotifications() { enabled_ = false; }
-
- private:
- WidgetFocusManager();
- ~WidgetFocusManager();
-
- typedef std::vector<WidgetFocusChangeListener*>
- WidgetFocusChangeListenerList;
- WidgetFocusChangeListenerList focus_change_listeners_;
-
- bool enabled_;
-
- friend struct DefaultSingletonTraits<WidgetFocusManager>;
- DISALLOW_COPY_AND_ASSIGN(WidgetFocusManager);
- };
-
- explicit FocusManager(Widget* widget);
- virtual ~FocusManager();
-
- // Returns the global WidgetFocusManager instance for the running application.
- static WidgetFocusManager* GetWidgetFocusManager();
-
- // Processes the passed key event for accelerators and tab traversal.
- // Returns false if the event has been consumed and should not be processed
- // further.
- bool OnKeyEvent(const KeyEvent& event);
-
- // Returns true is the specified is part of the hierarchy of the window
- // associated with this FocusManager.
- bool ContainsView(View* view) const;
-
- // Stops tracking this View in the focus manager. If the View is focused,
- // focus is cleared.
- void RemoveView(View* view);
-
- // Advances the focus (backward if reverse is true).
- void AdvanceFocus(FocusEvent::TraversalDirection direction);
-
- // The FocusManager keeps track of the focused view within a RootView.
- View* focused_view() const { return focused_view_; }
-
- // Low-level methods to force the focus to change. If the focus change should
- // only happen if the view is currently focusable, enabled, and visible, call
- // view->RequestFocus().
- void SetFocusedViewWithReasonAndDirection(
- View* view,
- FocusEvent::Reason reason,
- FocusEvent::TraversalDirection direction);
- void SetFocusedView(View* view) {
- SetFocusedViewWithReasonAndDirection(view, FocusEvent::REASON_DIRECT,
- FocusEvent::DIRECTION_NONE);
- }
-
- // Clears the focused view. The window associated with the top root view gets
- // the native focus (so we still get keyboard events).
- void ClearFocus();
-
- // Validates the focused view, clearing it if the window it belongs too is not
- // attached to the window hierarchy anymore.
- void ValidateFocusedView();
-
- // Register a keyboard accelerator for the specified target. If multiple
- // targets are registered for an accelerator, a target registered later has
- // higher priority.
- // Note that we are currently limited to accelerators that are either:
- // - a key combination including Ctrl or Alt
- // - the escape key
- // - the enter key
- // - any F key (F1, F2, F3 ...)
- // - any browser specific keys (as available on special keyboards)
- void RegisterAccelerator(const Accelerator& accelerator,
- AcceleratorTarget* target);
-
- // Unregister the specified keyboard accelerator for the specified target.
- void UnregisterAccelerator(const Accelerator& accelerator,
- AcceleratorTarget* target);
-
- // Unregister all keyboard accelerator for the specified target.
- void UnregisterAccelerators(AcceleratorTarget* target);
-
- // Activate the target associated with the specified accelerator.
- // First, AcceleratorPressed handler of the most recently registered target
- // is called, and if that handler processes the event (i.e. returns true),
- // this method immediately returns. If not, we do the same thing on the next
- // target, and so on.
- // Returns true if an accelerator was activated.
- bool ProcessAccelerator(const Accelerator& accelerator);
-
- // Adds/removes a listener. The FocusChangeListener is notified every time
- // the focused view is about to change.
- void AddFocusChangeListener(FocusChangeListener* listener);
- void RemoveFocusChangeListener(FocusChangeListener* listener);
-
- // Returns the AcceleratorTarget that should be activated for the specified
- // keyboard accelerator, or NULL if no view is registered for that keyboard
- // accelerator.
- AcceleratorTarget* GetCurrentTargetForAccelerator(
- const Accelerator& accelertor) const;
-
- // Convenience method that returns true if the passed |key_event| should
- // trigger tab traversal (if it is a TAB key press with or without SHIFT
- // pressed).
- static bool IsTabTraversalKeyEvent(const KeyEvent& key_event);
-
- private:
- // Returns the next focusable view.
- View* GetNextFocusableView(View* starting_view,
- FocusEvent::TraversalDirection direction,
- bool dont_loop);
-
- // Returns the focusable view found in the FocusTraversable specified starting
- // at the specified view. This traverses down along the FocusTraversable
- // hierarchy.
- // Returns NULL if no focusable view were found.
- View* FindFocusableView(FocusTraversable* focus_traversable,
- View* starting_view,
- FocusEvent::TraversalDirection direction);
-
- // The top-level Widget this FocusManager is associated with.
- Widget* widget_;
-
- // The view that currently is focused.
- View* focused_view_;
-
- // The accelerators and associated targets.
- typedef std::list<AcceleratorTarget*> AcceleratorTargetList;
- typedef std::map<Accelerator, AcceleratorTargetList> AcceleratorMap;
- AcceleratorMap accelerators_;
-
- // The list of registered FocusChange listeners.
- typedef std::vector<FocusChangeListener*> FocusChangeListenerList;
- FocusChangeListenerList focus_change_listeners_;
-
- DISALLOW_COPY_AND_ASSIGN(FocusManager);
-};
-
-// A basic helper class that is used to disable native focus change
-// notifications within a scope.
-class AutoNativeNotificationDisabler {
- public:
- AutoNativeNotificationDisabler() {
- FocusManager::GetWidgetFocusManager()->DisableNotifications();
- }
-
- ~AutoNativeNotificationDisabler() {
- FocusManager::GetWidgetFocusManager()->EnableNotifications();
- }
- private:
- DISALLOW_COPY_AND_ASSIGN(AutoNativeNotificationDisabler);
-};
-
-} // namespace ui
-
-#endif // UI_VIEWS_FOCUS_FOCUS_MANAGER_H_
diff --git a/ui/views/focus/focus_search.cc b/ui/views/focus/focus_search.cc
deleted file mode 100644
index 083fc7c..0000000
--- a/ui/views/focus/focus_search.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-// 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 "base/logging.h"
-#include "ui/views/focus/focus_manager.h"
-#include "ui/views/focus/focus_search.h"
-#include "ui/views/view.h"
-
-namespace ui {
-
-FocusSearch::FocusSearch(View* root, bool cycle, bool accessibility_mode)
- : root_(root),
- cycle_(cycle),
- accessibility_mode_(accessibility_mode) {
-}
-
-View* FocusSearch::FindNextFocusableView(View* starting_view,
- bool reverse,
- Direction direction,
- bool check_starting_view,
- FocusTraversable** focus_traversable,
- View** focus_traversable_view) const {
- *focus_traversable = NULL;
- *focus_traversable_view = NULL;
-
- if (root_->children_empty()) {
- NOTREACHED();
- // Nothing to focus on here.
- return NULL;
- }
-
- View* initial_starting_view = starting_view;
- int starting_view_group = -1;
- if (starting_view)
- starting_view_group = starting_view->group();
-
- if (!starting_view) {
- // Default to the first/last child
- starting_view =
- reverse ?
- root_->child_at(root_->children_size() - 1) :
- root_->child_at(0);
- // If there was no starting view, then the one we select is a potential
- // focus candidate.
- check_starting_view = true;
- } else {
- // The starting view should be a direct or indirect child of the root.
- DCHECK(root_->Contains(*starting_view));
- }
-
- View* v = NULL;
- if (!reverse) {
- v = FindNextFocusableViewImpl(starting_view, check_starting_view,
- true,
- (direction == DOWN) ? true : false,
- starting_view_group,
- focus_traversable,
- focus_traversable_view);
- } else {
- // If the starting view is focusable, we don't want to go down, as we are
- // traversing the view hierarchy tree bottom-up.
- bool can_go_down = (direction == DOWN) && !IsFocusable(starting_view);
- v = FindPreviousFocusableViewImpl(starting_view, check_starting_view,
- true,
- can_go_down,
- starting_view_group,
- focus_traversable,
- focus_traversable_view);
- }
-
- // Don't set the focus to something outside of this view hierarchy.
- if (v && v != root_ && !root_->Contains(*v))
- v = NULL;
-
- // If |cycle_| is true, prefer to keep cycling rather than returning NULL.
- if (cycle_ && !v && initial_starting_view) {
- v = FindNextFocusableView(NULL, reverse, direction, check_starting_view,
- focus_traversable, focus_traversable_view);
- DCHECK(IsFocusable(v));
- return v;
- }
-
- // Doing some sanity checks.
- if (v) {
- DCHECK(IsFocusable(v));
- return v;
- }
- if (*focus_traversable) {
- DCHECK(*focus_traversable_view);
- return NULL;
- }
- // Nothing found.
- return NULL;
-}
-
-bool FocusSearch::IsViewFocusableCandidate(View* v, int skip_group_id) const {
- return IsFocusable(v) &&
- (v->IsGroupFocusTraversable() || skip_group_id == -1 ||
- v->group() != skip_group_id);
-}
-
-bool FocusSearch::IsFocusable(View* v) const {
- if (accessibility_mode_)
- return v && v->IsAccessibilityFocusableInRootView();
-
- return v && v->IsFocusableInRootView();
-}
-
-View* FocusSearch::FindSelectedViewForGroup(View* view) const {
- // No group for that view.
- if (view->IsGroupFocusTraversable() || view->group() == -1)
- return view;
-
- View* selected_view = view->GetSelectedViewForGroup(view->group());
- if (selected_view)
- return selected_view;
-
- // No view selected for that group, default to the specified view.
- return view;
-}
-
-View* FocusSearch::GetParent(View* v) const {
- return root_->Contains(*v) ? v->parent() : NULL;
-}
-
-// Strategy for finding the next focusable view:
-// - keep going down the first child, stop when you find a focusable view or
-// a focus traversable view (in that case return it) or when you reach a view
-// with no children.
-// - go to the right sibling and start the search from there (by invoking
-// FindNextFocusableViewImpl on that view).
-// - if the view has no right sibling, go up the parents until you find a parent
-// with a right sibling and start the search from there.
-View* FocusSearch::FindNextFocusableViewImpl(
- View* starting_view,
- bool check_starting_view,
- bool can_go_up,
- bool can_go_down,
- int skip_group_id,
- FocusTraversable** focus_traversable,
- View** focus_traversable_view) const {
- if (check_starting_view) {
- if (IsViewFocusableCandidate(starting_view, skip_group_id)) {
- View* v = FindSelectedViewForGroup(starting_view);
- // The selected view might not be focusable (if it is disabled for
- // example).
- if (IsFocusable(v))
- return v;
- }
-
- *focus_traversable = starting_view->GetFocusTraversable();
- if (*focus_traversable) {
- *focus_traversable_view = starting_view;
- return NULL;
- }
- }
-
- // First let's try the left child.
- if (can_go_down) {
- if (!starting_view->children_empty()) {
- View* v = FindNextFocusableViewImpl(starting_view->child_at(0),
- true, false, true, skip_group_id,
- focus_traversable,
- focus_traversable_view);
- if (v || *focus_traversable)
- return v;
- }
- }
-
- // Then try the right sibling.
- View* sibling = starting_view->GetNextFocusableView();
- if (sibling) {
- View* v = FindNextFocusableViewImpl(sibling,
- true, false, true, skip_group_id,
- focus_traversable,
- focus_traversable_view);
- if (v || *focus_traversable)
- return v;
- }
-
- // Then go up to the parent sibling.
- if (can_go_up) {
- View* parent = GetParent(starting_view);
- while (parent) {
- sibling = parent->GetNextFocusableView();
- if (sibling) {
- return FindNextFocusableViewImpl(sibling,
- true, true, true,
- skip_group_id,
- focus_traversable,
- focus_traversable_view);
- }
- parent = GetParent(parent);
- }
- }
-
- // We found nothing.
- return NULL;
-}
-
-// Strategy for finding the previous focusable view:
-// - keep going down on the right until you reach a view with no children, if it
-// it is a good candidate return it.
-// - start the search on the left sibling.
-// - if there are no left sibling, start the search on the parent (without going
-// down).
-View* FocusSearch::FindPreviousFocusableViewImpl(
- View* starting_view,
- bool check_starting_view,
- bool can_go_up,
- bool can_go_down,
- int skip_group_id,
- FocusTraversable** focus_traversable,
- View** focus_traversable_view) const {
- // Let's go down and right as much as we can.
- if (can_go_down) {
- // Before we go into the direct children, we have to check if this view has
- // a FocusTraversable.
- *focus_traversable = starting_view->GetFocusTraversable();
- if (*focus_traversable) {
- *focus_traversable_view = starting_view;
- return NULL;
- }
-
- if (!starting_view->children_empty()) {
- View* view = starting_view->child_at(starting_view->children_size() - 1);
- View* v = FindPreviousFocusableViewImpl(view, true, false, true,
- skip_group_id,
- focus_traversable,
- focus_traversable_view);
- if (v || *focus_traversable)
- return v;
- }
- }
-
- // Then look at this view. Here, we do not need to see if the view has
- // a FocusTraversable, since we do not want to go down any more.
- if (check_starting_view &&
- IsViewFocusableCandidate(starting_view, skip_group_id)) {
- View* v = FindSelectedViewForGroup(starting_view);
- // The selected view might not be focusable (if it is disabled for
- // example).
- if (IsFocusable(v))
- return v;
- }
-
- // Then try the left sibling.
- View* sibling = starting_view->GetPreviousFocusableView();
- if (sibling) {
- return FindPreviousFocusableViewImpl(sibling,
- true, true, true,
- skip_group_id,
- focus_traversable,
- focus_traversable_view);
- }
-
- // Then go up the parent.
- if (can_go_up) {
- View* parent = GetParent(starting_view);
- if (parent)
- return FindPreviousFocusableViewImpl(parent,
- true, true, false,
- skip_group_id,
- focus_traversable,
- focus_traversable_view);
- }
-
- // We found nothing.
- return NULL;
-}
-
-} // namespace ui
diff --git a/ui/views/focus/focus_search.h b/ui/views/focus/focus_search.h
deleted file mode 100644
index 3cda790..0000000
--- a/ui/views/focus/focus_search.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// 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 UI_VIEWS_FOCUS_FOCUS_SEARCH_H_
-#define UI_VIEWS_FOCUS_FOCUS_SEARCH_H_
-#pragma once
-
-#include "ui/views/view.h"
-
-namespace ui {
-
-class FocusTraversable;
-
-// FocusSearch is an object that implements the algorithm to find the
-// next view to focus.
-class FocusSearch {
- public:
- // The direction in which the focus traversal is going.
- // TODO (jcampan): add support for lateral (left, right) focus traversal. The
- // goal is to switch to focusable views on the same level when using the arrow
- // keys (ala Windows: in a dialog box, arrow keys typically move between the
- // dialog OK, Cancel buttons).
- enum Direction {
- UP = 0,
- DOWN
- };
-
- // Constructor.
- // - |root| is the root of the view hierarchy to traverse. Focus will be
- // trapped inside.
- // - |cycle| should be true if you want FindNextFocusableView to cycle back
- // to the first view within this root when the traversal reaches
- // the end. If this is true, then if you pass a valid starting
- // view to FindNextFocusableView you will always get a valid view
- // out, even if it's the same view.
- // - |accessibility_mode| should be true if full keyboard accessibility is
- // needed and you want to check IsAccessibilityFocusableInRootView(),
- // rather than IsFocusableInRootView().
- FocusSearch(View* root, bool cycle, bool accessibility_mode);
- virtual ~FocusSearch() {}
-
- // Finds the next view that should be focused and returns it. If a
- // FocusTraversable is found while searching for the focusable view,
- // returns NULL and sets |focus_traversable| to the FocusTraversable
- // and |focus_traversable_view| to the view associated with the
- // FocusTraversable.
- //
- // Return NULL if the end of the focus loop is reached, unless this object
- // was initialized with |cycle|=true, in which case it goes back to the
- // beginning when it reaches the end of the traversal.
- // - |starting_view| is the view that should be used as the starting point
- // when looking for the previous/next view. It may be NULL (in which case
- // the first/last view should be used depending if normal/reverse).
- // - |reverse| whether we should find the next (reverse is false) or the
- // previous (reverse is true) view.
- // - |direction| specifies whether we are traversing down (meaning we should
- // look into child views) or traversing up (don't look at child views).
- // - |check_starting_view| is true if starting_view may obtain the next focus.
- // - |focus_traversable| is set to the focus traversable that should be
- // traversed if one is found (in which case the call returns NULL).
- // - |focus_traversable_view| is set to the view associated with the
- // FocusTraversable set in the previous parameter (it is used as the
- // starting view when looking for the next focusable view).
- virtual View* FindNextFocusableView(View* starting_view,
- bool reverse,
- Direction direction,
- bool check_starting_view,
- FocusTraversable** focus_traversable,
- View** focus_traversable_view) const;
-
- private:
- // Convenience method that returns true if a view is focusable and does not
- // belong to the specified group.
- bool IsViewFocusableCandidate(View* v, int skip_group_id) const;
-
- // Convenience method; returns true if a view is not NULL and is focusable
- // (checking IsAccessibilityFocusableInRootView() if accessibility_mode_ is
- // true).
- bool IsFocusable(View* v) const;
-
- // Returns the view selected for the group of the selected view. If the view
- // does not belong to a group or if no view is selected in the group, the
- // specified view is returned.
- View* FindSelectedViewForGroup(View* view) const;
-
- // Get the parent, but stay within the root. Returns NULL if asked for
- // the parent of root_.
- View* GetParent(View* view) const;
-
- // Returns the next focusable view or view containing a FocusTraversable
- // (NULL if none was found), starting at the starting_view.
- // |check_starting_view|, |can_go_up| and |can_go_down| controls the
- // traversal of the views hierarchy. |skip_group_id| specifies a group_id,
- // -1 means no group. All views from a group are traversed in one pass.
- View* FindNextFocusableViewImpl(View* starting_view,
- bool check_starting_view,
- bool can_go_up,
- bool can_go_down,
- int skip_group_id,
- FocusTraversable** focus_traversable,
- View** focus_traversable_view) const;
-
- // Same as FindNextFocusableViewImpl but returns the previous focusable view.
- View* FindPreviousFocusableViewImpl(View* starting_view,
- bool check_starting_view,
- bool can_go_up,
- bool can_go_down,
- int skip_group_id,
- FocusTraversable** focus_traversable,
- View** focus_traversable_view) const;
-
- View* root_;
- bool cycle_;
- bool accessibility_mode_;
-
- DISALLOW_COPY_AND_ASSIGN(FocusSearch);
-};
-
-} // namespace ui
-
-#endif // UI_VIEWS_FOCUS_FOCUS_SEARCH_H_