diff options
Diffstat (limited to 'views/widget')
-rw-r--r-- | views/widget/root_view.cc | 228 | ||||
-rw-r--r-- | views/widget/root_view.h | 15 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 12 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 9 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 12 | ||||
-rw-r--r-- | views/widget/widget_win.h | 10 |
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(); |