summaryrefslogtreecommitdiffstats
path: root/views/widget
diff options
context:
space:
mode:
Diffstat (limited to 'views/widget')
-rw-r--r--views/widget/root_view.cc228
-rw-r--r--views/widget/root_view.h15
-rw-r--r--views/widget/widget_gtk.cc12
-rw-r--r--views/widget/widget_gtk.h9
-rw-r--r--views/widget/widget_win.cc12
-rw-r--r--views/widget/widget_win.h10
6 files changed, 17 insertions, 269 deletions
diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc
index 12faf68..ff08d29 100644
--- a/views/widget/root_view.cc
+++ b/views/widget/root_view.cc
@@ -62,6 +62,7 @@ RootView::RootView(Widget* widget)
mouse_move_handler_(NULL),
last_click_handler_(NULL),
widget_(widget),
+ ALLOW_THIS_IN_INITIALIZER_LIST(focus_search_(this, false, false)),
invalid_rect_urgent_(false),
pending_paint_task_(NULL),
paint_task_needed_(false),
@@ -575,210 +576,8 @@ View* RootView::GetFocusedView() {
return NULL;
}
-View* RootView::FindNextFocusableView(View* starting_view,
- bool reverse,
- Direction direction,
- bool check_starting_view,
- FocusTraversable** focus_traversable,
- View** focus_traversable_view) {
- *focus_traversable = NULL;
- *focus_traversable_view = NULL;
-
- if (GetChildViewCount() == 0) {
- NOTREACHED();
- // Nothing to focus on here.
- return NULL;
- }
-
- if (!starting_view) {
- // Default to the first/last child
- starting_view = reverse ? GetChildViewAt(GetChildViewCount() - 1) :
- GetChildViewAt(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 part of this RootView.
- DCHECK(IsParentOf(starting_view));
- }
-
- View* v = NULL;
- if (!reverse) {
- v = FindNextFocusableViewImpl(starting_view, check_starting_view,
- true,
- (direction == DOWN) ? true : false,
- starting_view->GetGroup(),
- 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) && !starting_view->IsFocusable();
- v = FindPreviousFocusableViewImpl(starting_view, check_starting_view,
- true,
- can_go_down,
- starting_view->GetGroup(),
- focus_traversable,
- focus_traversable_view);
- }
-
- // Doing some sanity checks.
- if (v) {
- DCHECK(v->IsFocusable());
- return v;
- }
- if (*focus_traversable) {
- DCHECK(*focus_traversable_view);
- return NULL;
- }
- // Nothing found.
- return 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* RootView::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) {
- 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 (v && v->IsFocusable())
- 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->GetChildViewCount() > 0) {
- View* v = FindNextFocusableViewImpl(starting_view->GetChildViewAt(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 = starting_view->GetParent();
- while (parent) {
- sibling = parent->GetNextFocusableView();
- if (sibling) {
- return FindNextFocusableViewImpl(sibling,
- true, true, true,
- skip_group_id,
- focus_traversable,
- focus_traversable_view);
- }
- parent = parent->GetParent();
- }
- }
-
- // 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* RootView::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) {
- // 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->GetChildViewCount() > 0) {
- View* view =
- starting_view->GetChildViewAt(starting_view->GetChildViewCount() - 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 (v && v->IsFocusable())
- 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 = starting_view->GetParent();
- if (parent)
- return FindPreviousFocusableViewImpl(parent,
- true, true, false,
- skip_group_id,
- focus_traversable,
- focus_traversable_view);
- }
-
- // We found nothing.
- return NULL;
+FocusSearch* RootView::GetFocusSearch() {
+ return &focus_search_;
}
FocusTraversable* RootView::GetFocusTraversableParent() {
@@ -803,27 +602,6 @@ void RootView::NotifyNativeViewHierarchyChanged(bool attached,
PropagateNativeViewHierarchyChanged(attached, native_view, this);
}
-// static
-View* RootView::FindSelectedViewForGroup(View* view) {
- if (view->IsGroupFocusTraversable() ||
- view->GetGroup() == -1) // No group for that view.
- return view;
-
- View* selected_view = view->GetSelectedViewForGroup(view->GetGroup());
- if (selected_view)
- return selected_view;
-
- // No view selected for that group, default to the specified view.
- return view;
-}
-
-// static
-bool RootView::IsViewFocusableCandidate(View* v, int skip_group_id) {
- return v->IsFocusable() &&
- (v->IsGroupFocusTraversable() || skip_group_id == -1 ||
- v->GetGroup() != skip_group_id);
-}
-
bool RootView::ProcessKeyEvent(const KeyEvent& event) {
bool consumed = false;
diff --git a/views/widget/root_view.h b/views/widget/root_view.h
index ba1d5d22..280742f 100644
--- a/views/widget/root_view.h
+++ b/views/widget/root_view.h
@@ -10,6 +10,7 @@
#include "base/ref_counted.h"
#include "views/focus/focus_manager.h"
+#include "views/focus/focus_search.h"
#include "views/view.h"
#if defined(OS_LINUX)
@@ -104,10 +105,6 @@ class RootView : public View,
// Make the provided view focused. Also make sure that our Widget is focused.
void FocusView(View* view);
- // Check whether the provided view is in the focus path. The focus path is the
- // path between the focused view (included) to the root view.
- bool IsInFocusPath(View* view);
-
// Returns the View in this RootView hierarchy that has the focus, or NULL if
// no View currently has the focus.
View* GetFocusedView();
@@ -138,12 +135,7 @@ class RootView : public View,
virtual bool IsVisibleInRootView() const;
// FocusTraversable implementation.
- virtual View* FindNextFocusableView(View* starting_view,
- bool reverse,
- Direction direction,
- bool check_starting_view,
- FocusTraversable** focus_traversable,
- View** focus_traversable_view);
+ virtual FocusSearch* GetFocusSearch();
virtual FocusTraversable* GetFocusTraversableParent();
virtual View* GetFocusTraversableParentView();
@@ -285,6 +277,9 @@ class RootView : public View,
// The host Widget
Widget* widget_;
+ // The focus search algorithm.
+ FocusSearch focus_search_;
+
// The rectangle that should be painted
gfx::Rect invalid_rect_;
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index f38267b..2f21358 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -831,16 +831,8 @@ bool WidgetGtk::ContainsNativeView(gfx::NativeView native_view) {
////////////////////////////////////////////////////////////////////////////////
// WidgetGtk, FocusTraversable implementation:
-View* WidgetGtk::FindNextFocusableView(
- View* starting_view, bool reverse, Direction direction,
- bool check_starting_view, FocusTraversable** focus_traversable,
- View** focus_traversable_view) {
- return root_view_->FindNextFocusableView(starting_view,
- reverse,
- direction,
- check_starting_view,
- focus_traversable,
- focus_traversable_view);
+FocusSearch* WidgetGtk::GetFocusSearch() {
+ return root_view_->GetFocusSearch();
}
FocusTraversable* WidgetGtk::GetFocusTraversableParent() {
diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h
index 8f7ca17..3b95140 100644
--- a/views/widget/widget_gtk.h
+++ b/views/widget/widget_gtk.h
@@ -25,6 +25,7 @@ namespace views {
class DefaultThemeProvider;
class DropTargetGtk;
+class FocusSearch;
class TooltipManagerGtk;
class View;
class WindowGtk;
@@ -188,14 +189,8 @@ class WidgetGtk
View *child);
virtual bool ContainsNativeView(gfx::NativeView native_view);
-
// Overridden from FocusTraversable:
- virtual View* FindNextFocusableView(View* starting_view,
- bool reverse,
- Direction direction,
- bool check_starting_view,
- FocusTraversable** focus_traversable,
- View** focus_traversable_view);
+ virtual FocusSearch* GetFocusSearch();
virtual FocusTraversable* GetFocusTraversableParent();
virtual View* GetFocusTraversableParentView();
diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc
index ef6612a..90cffe5 100644
--- a/views/widget/widget_win.cc
+++ b/views/widget/widget_win.cc
@@ -467,16 +467,8 @@ void WidgetWin::DidProcessMessage(const MSG& msg) {
////////////////////////////////////////////////////////////////////////////////
// FocusTraversable
-View* WidgetWin::FindNextFocusableView(
- View* starting_view, bool reverse, Direction direction,
- bool check_starting_view, FocusTraversable** focus_traversable,
- View** focus_traversable_view) {
- return root_view_->FindNextFocusableView(starting_view,
- reverse,
- direction,
- check_starting_view,
- focus_traversable,
- focus_traversable_view);
+FocusSearch* WidgetWin::GetFocusSearch() {
+ return root_view_->GetFocusSearch();
}
FocusTraversable* WidgetWin::GetFocusTraversableParent() {
diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h
index e0cdc44d..699d60e3 100644
--- a/views/widget/widget_win.h
+++ b/views/widget/widget_win.h
@@ -24,10 +24,11 @@ class Rect;
namespace views {
+class DefaultThemeProvider;
class DropTargetWin;
+class FocusSearch;
class RootView;
class TooltipManagerWin;
-class DefaultThemeProvider;
class Window;
bool SetRootViewForHWND(HWND hwnd, RootView* root_view);
@@ -222,12 +223,7 @@ class WidgetWin : public app::WindowImpl,
virtual void DidProcessMessage(const MSG& msg);
// Overridden from FocusTraversable:
- virtual View* FindNextFocusableView(View* starting_view,
- bool reverse,
- Direction direction,
- bool check_starting_view,
- FocusTraversable** focus_traversable,
- View** focus_traversable_view);
+ virtual FocusSearch* GetFocusSearch();
virtual FocusTraversable* GetFocusTraversableParent();
virtual View* GetFocusTraversableParentView();