summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-03 20:29:13 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-03 20:29:13 +0000
commit7b398483f56fcbe4a84dc3eee6f80d1ec96c925a (patch)
treec1fdca22837562229f445cd529d39f2362201dd4 /ui
parenta2a1baf4c5f6b4246eff6b9ed9f480ec64539ee6 (diff)
downloadchromium_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.cc2
-rw-r--r--ui/views/events/event.h3
-rw-r--r--ui/views/events/focus_event.cc19
-rw-r--r--ui/views/events/focus_event.h51
-rw-r--r--ui/views/focus/focus_manager.cc209
-rw-r--r--ui/views/focus/focus_manager.h57
-rw-r--r--ui/views/focus/view_storage.cc115
-rw-r--r--ui/views/focus/view_storage.h74
-rw-r--r--ui/views/view.cc4
-rw-r--r--ui/views/view.h11
-rw-r--r--ui/views/views.gyp4
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',