diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-03 20:29:13 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-03 20:29:13 +0000 |
commit | 7b398483f56fcbe4a84dc3eee6f80d1ec96c925a (patch) | |
tree | c1fdca22837562229f445cd529d39f2362201dd4 /ui | |
parent | a2a1baf4c5f6b4246eff6b9ed9f480ec64539ee6 (diff) | |
download | chromium_src-7b398483f56fcbe4a84dc3eee6f80d1ec96c925a.zip chromium_src-7b398483f56fcbe4a84dc3eee6f80d1ec96c925a.tar.gz chromium_src-7b398483f56fcbe4a84dc3eee6f80d1ec96c925a.tar.bz2 |
Switch to using FocusEvent for focus change notifications.
I also removed ViewStorage usage for now. Jay described generally the kind of cases where this might be useful but I have not encountered them yet in my current testing. I will reintroduce this code if it becomes necessary.
Note that I have not yet verified that this works. That comes next.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/6368083
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73655 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/views/events/event.cc | 2 | ||||
-rw-r--r-- | ui/views/events/event.h | 3 | ||||
-rw-r--r-- | ui/views/events/focus_event.cc | 19 | ||||
-rw-r--r-- | ui/views/events/focus_event.h | 51 | ||||
-rw-r--r-- | ui/views/focus/focus_manager.cc | 209 | ||||
-rw-r--r-- | ui/views/focus/focus_manager.h | 57 | ||||
-rw-r--r-- | ui/views/focus/view_storage.cc | 115 | ||||
-rw-r--r-- | ui/views/focus/view_storage.h | 74 | ||||
-rw-r--r-- | ui/views/view.cc | 4 | ||||
-rw-r--r-- | ui/views/view.h | 11 | ||||
-rw-r--r-- | ui/views/views.gyp | 4 |
11 files changed, 175 insertions, 374 deletions
diff --git a/ui/views/events/event.cc b/ui/views/events/event.cc index f1d04b9..a6da13b 100644 --- a/ui/views/events/event.cc +++ b/ui/views/events/event.cc @@ -54,4 +54,4 @@ MouseEvent::MouseEvent(const MouseEvent& other, View* source, View* target) : LocatedEvent(other, source, target) { } -} // namespace views +} // namespace ui diff --git a/ui/views/events/event.h b/ui/views/events/event.h index d8ad17f..c3cbce0 100644 --- a/ui/views/events/event.h +++ b/ui/views/events/event.h @@ -30,7 +30,8 @@ class Event { ET_KEY_PRESSED, ET_KEY_RELEASED, ET_MOUSEWHEEL, - ET_DROP_TARGET_EVENT }; + ET_DROP_TARGET_EVENT, + ET_FOCUS_CHANGE }; // Event flags currently supported. Although this is a "views" // file, this header is used on non-views platforms (e.g. OSX). For diff --git a/ui/views/events/focus_event.cc b/ui/views/events/focus_event.cc new file mode 100644 index 0000000..4a05999 --- /dev/null +++ b/ui/views/events/focus_event.cc @@ -0,0 +1,19 @@ +// 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/events/focus_event.h" + +namespace ui { + +//////////////////////////////////////////////////////////////////////////////// +// FocusEvent, public: + +FocusEvent::FocusEvent(Type type, Reason reason, TraversalDirection direction) + : type_(type), + reason_(reason), + direction_(direction), + Event(ET_FOCUS_CHANGE, 0) { +} + +} // namespace ui diff --git a/ui/views/events/focus_event.h b/ui/views/events/focus_event.h new file mode 100644 index 0000000..377c3f7 --- /dev/null +++ b/ui/views/events/focus_event.h @@ -0,0 +1,51 @@ +// 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_EVENTS_FOCUS_EVENT_H_ +#define UI_VIEWS_EVENTS_FOCUS_EVENT_H_ +#pragma once + +#include "base/basictypes.h" +#include "ui/views/events/event.h" + +namespace ui { + +class FocusEvent : public Event { + public: + enum Type { + TYPE_FOCUS_IN, // Target View did gain focus + TYPE_FOCUS_OUT // Target View will lose focus + }; + + enum Reason { + REASON_TRAVERSAL, // Focus change occurred because of a tab-traversal + REASON_RESTORE, // Focus was restored (e.g. window activation). + REASON_DIRECT // Focus was directly set (e.g. with mouse click). + }; + + enum TraversalDirection { + DIRECTION_NONE, + DIRECTION_FORWARD, + DIRECTION_REVERSE + }; + + FocusEvent(Type type, + Reason reason, + TraversalDirection direction); + + Type type() const { return type_; } + Reason reason() const { return reason_; } + TraversalDirection direction() const { return direction_; } + + private: + Type type_; + Reason reason_; + TraversalDirection direction_; + + DISALLOW_COPY_AND_ASSIGN(FocusEvent); +}; + +} // namespace ui + +#endif // UI_VIEWS_EVENTS_FOCUS_EVENT_H_ diff --git a/ui/views/focus/focus_manager.cc b/ui/views/focus/focus_manager.cc index 501d270..47a0e10 100644 --- a/ui/views/focus/focus_manager.cc +++ b/ui/views/focus/focus_manager.cc @@ -14,8 +14,8 @@ #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/focus/view_storage.h" #include "ui/views/view.h" #include "ui/views/widget/root_view.h" #include "ui/views/widget/native_widget.h" @@ -23,6 +23,38 @@ 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( @@ -74,11 +106,8 @@ FocusManager::WidgetFocusManager::GetInstance() { FocusManager::FocusManager(Widget* widget) : widget_(widget), - focused_view_(NULL), - focus_change_reason_(kReasonDirectFocusChange) { + focused_view_(NULL) { DCHECK(widget_); - stored_focused_view_storage_id_ = - ViewStorage::GetInstance()->CreateStorageID(); } FocusManager::~FocusManager() { @@ -93,34 +122,21 @@ FocusManager::WidgetFocusManager* FocusManager::GetWidgetFocusManager() { } bool FocusManager::OnKeyEvent(const KeyEvent& event) { -#if defined(OS_WIN) // 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 WidgetGtk::OnKeyEvent(). if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(event)) return true; -#endif // Intercept Tab related messages for focus traversal. - // Note that we don't do 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. -#if defined(OS_WIN) - HWND top_window = widget_->native_widget()->GetNativeView(); - HWND active_window = ::GetActiveWindow(); - if ((active_window == top_window || ::IsChild(active_window, top_window)) && - IsTabTraversalKeyEvent(event)) { - AdvanceFocus(event.IsShiftDown()); - return false; - } -#else - if (IsTabTraversalKeyEvent(event)) { - AdvanceFocus(event.IsShiftDown()); + if (CanTraverseFocus(widget_) && IsTabTraversalKeyEvent(event)) { + AdvanceFocus(DirectionFromKeyEvent(event)); return false; } -#endif // 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 || @@ -139,7 +155,9 @@ bool FocusManager::OnKeyEvent(const KeyEvent& event) { } else if (index >= static_cast<int>(views.size())) { index = 0; } - SetFocusedViewWithReason(views[index], kReasonFocusTraversal); + SetFocusedViewWithReasonAndDirection(views[index], + FocusEvent::REASON_TRAVERSAL, + DirectionFromBool(next)); return false; } @@ -164,33 +182,34 @@ void FocusManager::RemoveView(View* view) { // Clear focus if the removed child was focused. if (focused_view_ == view) ClearFocus(); - - ViewStorage::GetInstance()->RemoveView(view); } -void FocusManager::AdvanceFocus(bool reverse) { - View* v = GetNextFocusableView(focused_view_, reverse, false); +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 (v) { - v->OnFocus(); // TODO(beng): AboutToRequestFocusFromTabTraversal(reverse); - SetFocusedViewWithReason(v, kReasonFocusTraversal); + if (view) { + SetFocusedViewWithReasonAndDirection(view, FocusEvent::REASON_TRAVERSAL, + direction); } } -void FocusManager::SetFocusedViewWithReason( - View* view, FocusChangeReason reason) { - focus_change_reason_ = reason; - +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(); + 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; @@ -201,12 +220,9 @@ void FocusManager::SetFocusedViewWithReason( focused_view_ = view; - if (prev_focused_view) - prev_focused_view->Invalidate(); // Remove focus artifacts. - if (view) { view->Invalidate(); - view->OnFocus(); + view->OnFocus(FocusEvent(FocusEvent::TYPE_FOCUS_IN, reason, direction)); // The view might be deleted now. } } @@ -223,83 +239,6 @@ void FocusManager::ValidateFocusedView() { } } -void FocusManager::StoreFocusedView() { - ViewStorage* view_storage = ViewStorage::GetInstance(); - if (!view_storage) { - // This should never happen but bug 981648 seems to indicate it could. - NOTREACHED(); - return; - } - - // TODO (jcampan): when a TabContents containing a popup is closed, the focus - // is stored twice causing an assert. We should find a better alternative than - // removing the view from the storage explicitly. - view_storage->RemoveViewByID(stored_focused_view_storage_id_); - - if (!focused_view_) - return; - - view_storage->StoreView(stored_focused_view_storage_id_, focused_view_); - - View* v = focused_view_; - - { - // Temporarily disable notification. ClearFocus() will set the focus to the - // main browser window. This extra focus bounce which happens during - // deactivation can confuse registered WidgetFocusListeners, as the focus - // is not changing due to a user-initiated event. - AutoNativeNotificationDisabler local_notification_disabler; - ClearFocus(); - } - - if (v) - v->Invalidate(); // Remove focus border. -} - -void FocusManager::RestoreFocusedView() { - ViewStorage* view_storage = ViewStorage::GetInstance(); - if (!view_storage) { - // This should never happen but bug 981648 seems to indicate it could. - NOTREACHED(); - return; - } - - View* view = view_storage->RetrieveView(stored_focused_view_storage_id_); - if (view) { - if (ContainsView(view)) { - if (!view->IsFocusableInRootView() && - view->IsAccessibilityFocusableInRootView()) { - // RequestFocus would fail, but we want to restore focus to controls - // that had focus in accessibility mode. - SetFocusedViewWithReason(view, kReasonFocusRestore); - } else { - // This usually just sets the focus if this view is focusable, but - // let the view override RequestFocus if necessary. - view->RequestFocus(); - - // If it succeeded, the reason would be incorrect; set it to - // focus restore. - if (focused_view_ == view) - focus_change_reason_ = kReasonFocusRestore; - } - } - } else { - // Clearing the focus will focus the root window, so we still get key - // events. - ClearFocus(); - } -} - -void FocusManager::ClearStoredFocusedView() { - ViewStorage* view_storage = ViewStorage::GetInstance(); - if (!view_storage) { - // This should never happen but bug 981648 seems to indicate it could. - NOTREACHED(); - return; - } - view_storage->RemoveViewByID(stored_focused_view_storage_id_); -} - void FocusManager::RegisterAccelerator( const Accelerator& accelerator, AcceleratorTarget* target) { @@ -402,9 +341,10 @@ FocusManager* FocusManager::GetFocusManagerForNativeWindow( //////////////////////////////////////////////////////////////////////////////// // FocusManager, private: -View* FocusManager::GetNextFocusableView(View* original_starting_view, - bool reverse, - bool dont_loop) { +View* FocusManager::GetNextFocusableView( + View* original_starting_view, + FocusEvent::TraversalDirection direction, + bool dont_loop) { FocusTraversable* focus_traversable = NULL; // Let's re-validate the focused view. @@ -426,7 +366,7 @@ View* FocusManager::GetNextFocusableView(View* original_starting_view, } if (!focus_traversable) { - if (!reverse) { + if (IsTraverseForward(direction)) { // If the starting view has a focus traversable, use it. // This is the case with WidgetWins for example. focus_traversable = original_starting_view->GetFocusTraversable(); @@ -450,7 +390,7 @@ View* FocusManager::GetNextFocusableView(View* original_starting_view, } // Traverse the FocusTraversable tree down to find the focusable view. - View* v = FindFocusableView(focus_traversable, starting_view, reverse); + View* v = FindFocusableView(focus_traversable, starting_view, direction); if (v) { return v; } else { @@ -462,16 +402,16 @@ View* FocusManager::GetNextFocusableView(View* original_starting_view, 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 = reverse; + bool check_starting_view = !IsTraverseForward(direction); v = parent_focus_traversable->GetFocusSearch()->FindNextFocusableView( - starting_view, reverse, FocusSearch::UP, + 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, reverse); + v = FindFocusableView(new_focus_traversable, NULL, direction); } if (v) @@ -489,23 +429,24 @@ View* FocusManager::GetNextFocusableView(View* 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, reverse, true); + return GetNextFocusableView(NULL, direction, true); } } return NULL; } -// Find the next (previous if reverse is true) focusable view for the specified -// FocusTraversable, starting at the specified view, traversing down the -// FocusTraversable hierarchy. -View* FocusManager::FindFocusableView(FocusTraversable* focus_traversable, - View* starting_view, - bool reverse) { +// 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, - reverse, + !IsTraverseForward(direction), FocusSearch::DOWN, false, &new_focus_traversable, @@ -520,7 +461,7 @@ View* FocusManager::FindFocusableView(FocusTraversable* focus_traversable, starting_view = NULL; v = focus_traversable->GetFocusSearch()->FindNextFocusableView( starting_view, - reverse, + !IsTraverseForward(direction), FocusSearch::DOWN, false, &new_focus_traversable, diff --git a/ui/views/focus/focus_manager.h b/ui/views/focus/focus_manager.h index 863b7d3..a4a919c 100644 --- a/ui/views/focus/focus_manager.h +++ b/ui/views/focus/focus_manager.h @@ -14,6 +14,7 @@ #include "base/singleton.h" #include "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. @@ -161,20 +162,6 @@ class FocusManager { DISALLOW_COPY_AND_ASSIGN(WidgetFocusManager); }; - // The reason why the focus changed. - enum FocusChangeReason { - // The focus changed because the user traversed focusable views using - // keys like Tab or Shift+Tab. - kReasonFocusTraversal, - - // The focus changed due to restoring the focus. - kReasonFocusRestore, - - // The focus changed due to a click or a shortcut to jump directly to - // a particular view. - kReasonDirectFocusChange - }; - explicit FocusManager(Widget* widget); virtual ~FocusManager(); @@ -195,22 +182,21 @@ class FocusManager { void RemoveView(View* view); // Advances the focus (backward if reverse is true). - void AdvanceFocus(bool reverse); + 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 (and optionally provide - // a reason). If the focus change should only happen if the view is - // currently focusable, enabled, and visible, call view->RequestFocus(). - void SetFocusedViewWithReason(View* view, FocusChangeReason reason); + // 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) { - SetFocusedViewWithReason(view, kReasonDirectFocusChange); - } - - // Get the reason why the focus most recently changed. - FocusChangeReason focus_change_reason() const { - return focus_change_reason_; + SetFocusedViewWithReasonAndDirection(view, FocusEvent::REASON_DIRECT, + FocusEvent::DIRECTION_NONE); } // Clears the focused view. The window associated with the top root view gets @@ -221,14 +207,6 @@ class FocusManager { // attached to the window hierarchy anymore. void ValidateFocusedView(); - // Stores and restores the focused view. Used when the window becomes - // active/inactive. - void StoreFocusedView(); - void RestoreFocusedView(); - - // Clears the stored focused view. - void ClearStoredFocusedView(); - // Register a keyboard accelerator for the specified target. If multiple // targets are registered for an accelerator, a target registered later has // higher priority. @@ -282,7 +260,9 @@ class FocusManager { private: // Returns the next focusable view. - View* GetNextFocusableView(View* starting_view, bool reverse, bool dont_loop); + 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 @@ -290,7 +270,7 @@ class FocusManager { // Returns NULL if no focusable view were found. View* FindFocusableView(FocusTraversable* focus_traversable, View* starting_view, - bool reverse); + FocusEvent::TraversalDirection direction); // The top-level Widget this FocusManager is associated with. Widget* widget_; @@ -298,13 +278,6 @@ class FocusManager { // The view that currently is focused. View* focused_view_; - // The storage id used in the ViewStorage to store/restore the view that last - // had focus. - int stored_focused_view_storage_id_; - - // The reason why the focus most recently changed. - FocusChangeReason focus_change_reason_; - // The accelerators and associated targets. typedef std::list<AcceleratorTarget*> AcceleratorTargetList; typedef std::map<Accelerator, AcceleratorTargetList> AcceleratorMap; diff --git a/ui/views/focus/view_storage.cc b/ui/views/focus/view_storage.cc deleted file mode 100644 index e9c9799..0000000 --- a/ui/views/focus/view_storage.cc +++ /dev/null @@ -1,115 +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/view_storage.h" - -#include <algorithm> - -#include "base/logging.h" -#include "base/stl_util-inl.h" - -namespace ui { - -// static -ViewStorage* ViewStorage::GetInstance() { - return Singleton<ViewStorage>::get(); -} - -ViewStorage::ViewStorage() : view_storage_next_id_(0) { -} - -ViewStorage::~ViewStorage() { - STLDeleteContainerPairSecondPointers(view_to_ids_.begin(), - view_to_ids_.end()); -} - -int ViewStorage::CreateStorageID() { - return view_storage_next_id_++; -} - -void ViewStorage::StoreView(int storage_id, View* view) { - DCHECK(view); - std::map<int, View*>::iterator iter = id_to_view_.find(storage_id); - - if (iter != id_to_view_.end()) { - NOTREACHED(); - RemoveViewByID(storage_id); - } - - id_to_view_[storage_id] = view; - - std::vector<int>* ids = NULL; - std::map<View*, std::vector<int>*>::iterator id_iter = - view_to_ids_.find(view); - if (id_iter == view_to_ids_.end()) { - ids = new std::vector<int>(); - view_to_ids_[view] = ids; - } else { - ids = id_iter->second; - } - ids->push_back(storage_id); -} - -View* ViewStorage::RetrieveView(int storage_id) { - std::map<int, View*>::iterator iter = id_to_view_.find(storage_id); - if (iter == id_to_view_.end()) - return NULL; - return iter->second; -} - -void ViewStorage::RemoveViewByID(int storage_id) { - EraseView(storage_id, false); -} - -void ViewStorage::RemoveView(View* view) { - // Let's first retrieve the ids for that view. - std::map<View*, std::vector<int>*>::iterator ids_iter = - view_to_ids_.find(view); - - if (ids_iter == view_to_ids_.end()) { - // That view is not in the view storage. - return; - } - - std::vector<int>* ids = ids_iter->second; - DCHECK(!ids->empty()); - EraseView((*ids)[0], true); -} - -void ViewStorage::EraseView(int storage_id, bool remove_all_ids) { - // Remove the view from id_to_view_location_. - std::map<int, View*>::iterator view_iter = id_to_view_.find(storage_id); - if (view_iter == id_to_view_.end()) - return; - - View* view = view_iter->second; - id_to_view_.erase(view_iter); - - // Also update view_to_ids_. - std::map<View*, std::vector<int>*>::iterator ids_iter = - view_to_ids_.find(view); - DCHECK(ids_iter != view_to_ids_.end()); - std::vector<int>* ids = ids_iter->second; - - if (remove_all_ids) { - for (size_t i = 0; i < ids->size(); ++i) { - view_iter = id_to_view_.find((*ids)[i]); - if (view_iter != id_to_view_.end()) - id_to_view_.erase(view_iter); - } - ids->clear(); - } else { - std::vector<int>::iterator id_iter = - std::find(ids->begin(), ids->end(), storage_id); - DCHECK(id_iter != ids->end()); - ids->erase(id_iter); - } - - if (ids->empty()) { - delete ids; - view_to_ids_.erase(ids_iter); - } -} - -} // namespace ui diff --git a/ui/views/focus/view_storage.h b/ui/views/focus/view_storage.h deleted file mode 100644 index 1923f0b..0000000 --- a/ui/views/focus/view_storage.h +++ /dev/null @@ -1,74 +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_VIEW_STORAGE_H_ -#define UI_VIEWS_FOCUS_VIEW_STORAGE_H_ -#pragma once - -#include <map> - -#include "base/singleton.h" -#include "ui/views/view.h" - -// This class is a simple storage place for storing/retrieving views. It is -// used for example in the FocusManager to store/restore focused views when the -// main window becomes active/inactive. -// It automatically removes a view from the storage if the view is removed from -// the tree hierarchy. -// -// To use it, you first need to create a view storage id that can then be used -// to store/retrieve views. - -namespace ui { - -class ViewStorage { - public: - // Returns the global ViewStorage instance. - // It is guaranted to be non NULL. - static ViewStorage* GetInstance(); - - // Returns a unique storage id that can be used to store/retrieve views. - int CreateStorageID(); - - // Associates |view| with the specified |storage_id|. - void StoreView(int storage_id, View* view); - - // Returns the view associated with |storage_id| if any, NULL otherwise. - View* RetrieveView(int storage_id); - - // Removes the view associated with |storage_id| if any. - void RemoveViewByID(int storage_id); - - // Removes the specified View. - void RemoveView(View* view); - -#ifdef UNIT_TEST - size_t view_count() const { return view_to_ids_.size(); } -#endif - - private: - friend struct DefaultSingletonTraits<ViewStorage>; - - ViewStorage(); - ~ViewStorage(); - - // Removes the view associated with |storage_id|. If |remove_all_ids| is true, - // all other mapping pointing to the same view are removed as well. - void EraseView(int storage_id, bool remove_all_ids); - - // Next id for the view storage. - int view_storage_next_id_; - - // The association id to View used for the view storage. - std::map<int, View*> id_to_view_; - - // Association View to id, used to speed up view notification removal. - std::map<View*, std::vector<int>*> view_to_ids_; - - DISALLOW_COPY_AND_ASSIGN(ViewStorage); -}; - -} // namespace ui - -#endif // UI_VIEWS_FOCUS_VIEW_STORAGE_H_ diff --git a/ui/views/view.cc b/ui/views/view.cc index cc92c35..b102eef 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc @@ -520,10 +520,10 @@ FocusTraversable* View::GetPaneFocusTraversable() const { return NULL; } -void View::OnFocus(/* const FocusEvent& event */) { +void View::OnFocus(const FocusEvent& event) { } -void View::OnBlur() { +void View::OnBlur(const FocusEvent& event) { } //////////////////////////////////////////////////////////////////////////////// diff --git a/ui/views/view.h b/ui/views/view.h index 931ea5d..701efea 100644 --- a/ui/views/view.h +++ b/ui/views/view.h @@ -9,8 +9,8 @@ #include "base/logging.h" #include "base/scoped_ptr.h" +#include "gfx/native_widget_types.h" #include "gfx/rect.h" -#include "ui/views/events/event.h" namespace gfx { class Canvas; @@ -27,9 +27,14 @@ class Accelerator; class Border; class ContextMenuController; class DragController; +class FocusEvent; class FocusManager; class FocusTraversable; +class KeyEvent; class LayoutManager; +class MouseEvent; +class MouseWheelEvent; +class OSExchangeData; class ThemeProvider; class Widget; @@ -287,8 +292,8 @@ class View { virtual bool IsAccessibilityFocusableInRootView() const; virtual FocusTraversable* GetPaneFocusTraversable() const; - virtual void OnFocus(/* const FocusEvent& event */); - virtual void OnBlur(); + virtual void OnFocus(const FocusEvent& event); + virtual void OnBlur(const FocusEvent& event); private: friend internal::RootView; diff --git a/ui/views/views.gyp b/ui/views/views.gyp index 3fb91fc..1778464 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -59,14 +59,14 @@ 'events/event.cc', 'events/event.h', 'events/event_win.cc', + 'events/focus_event.cc', + 'events/focus_event.h', 'focus/accelerator_handler.h', 'focus/accelerator_handler_win.cc', 'focus/focus_manager.cc', 'focus/focus_manager.h', 'focus/focus_search.cc', 'focus/focus_search.h', - 'focus/view_storage.cc', - 'focus/view_storage.h', 'layout/fill_layout.cc', 'layout/fill_layout.h', 'layout/layout_manager.cc', |