Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: views/focus/focus_manager.h

Issue 8588064: views: Move bubble, events, focus and layout to ui/views/. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « views/focus/external_focus_tracker.cc ('k') | views/focus/focus_manager.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef VIEWS_FOCUS_FOCUS_MANAGER_H_ 5 #ifndef VIEWS_FOCUS_FOCUS_MANAGER_H_
6 #define VIEWS_FOCUS_FOCUS_MANAGER_H_ 6 #define VIEWS_FOCUS_FOCUS_MANAGER_H_
7 #pragma once 7 #pragma once
8 8
9 #include <list> 9 #include "ui/views/focus/focus_manager.h"
10 #include <map> 10 // TODO(tfarina): remove this file once all includes have been updated.
11
12 #include "base/basictypes.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/observer_list.h"
15 #include "ui/base/models/accelerator.h"
16 #include "ui/gfx/native_widget_types.h"
17 #include "views/views_export.h"
18 #include "views/events/event.h"
19
20 // The FocusManager class is used to handle focus traversal, store/restore
21 // focused views and handle keyboard accelerators.
22 //
23 // There are 2 types of focus:
24 // - the native focus, which is the focus that an gfx::NativeView has.
25 // - the view focus, which is the focus that a views::View has.
26 //
27 // Each native view must register with their Focus Manager so the focus manager
28 // gets notified when they are focused (and keeps track of the native focus) and
29 // as well so that the tab key events can be intercepted.
30 // They can provide when they register a View that is kept in synch in term of
31 // focus. This is used in NativeControl for example, where a View wraps an
32 // actual native window.
33 // This is already done for you if you subclass the NativeControl class or if
34 // you use the NativeViewHost class.
35 //
36 // When creating a top window (derived from views::Widget) that is not a child
37 // window, it creates and owns a FocusManager to manage the focus for itself and
38 // all its child windows.
39 //
40 // The FocusTraversable interface exposes the methods a class should implement
41 // in order to be able to be focus traversed when tab key is pressed.
42 // RootViews implement FocusTraversable.
43 // The FocusManager contains a top FocusTraversable instance, which is the top
44 // RootView.
45 //
46 // If you just use views, then the focus traversal is handled for you by the
47 // RootView. The default traversal order is the order in which the views have
48 // been added to their container. You can modify this order by using the View
49 // method SetNextFocusableView().
50 //
51 // If you are embedding a native view containing a nested RootView (for example
52 // by adding a NativeControl that contains a NativeWidgetWin as its native
53 // component), then you need to:
54 // - override the View::GetFocusTraversable() method in your outer component.
55 // It should return the RootView of the inner component. This is used when
56 // the focus traversal traverse down the focus hierarchy to enter the nested
57 // RootView. In the example mentioned above, the NativeControl overrides
58 // GetFocusTraversable() and returns hwnd_view_container_->GetRootView().
59 // - call Widget::SetFocusTraversableParent() on the nested RootView and point
60 // it to the outer RootView. This is used when the focus goes out of the
61 // nested RootView. In the example:
62 // hwnd_view_container_->GetWidget()->SetFocusTraversableParent(
63 // native_control->GetRootView());
64 // - call RootView::SetFocusTraversableParentView() on the nested RootView with
65 // the parent view that directly contains the native window. This is needed
66 // when traversing up from the nested RootView to know which view to start
67 // with when going to the next/previous view.
68 // In our example:
69 // hwnd_view_container_->GetWidget()->SetFocusTraversableParent(
70 // native_control);
71 //
72 // Note that FocusTraversable do not have to be RootViews: AccessibleToolbarView
73 // is FocusTraversable.
74
75 namespace ui {
76 class AcceleratorTarget;
77 class AcceleratorManager;
78 }
79
80 namespace views {
81
82 class FocusSearch;
83 class RootView;
84 class View;
85 class Widget;
86
87 // The FocusTraversable interface is used by components that want to process
88 // focus traversal events (due to Tab/Shift-Tab key events).
89 class VIEWS_EXPORT FocusTraversable {
90 public:
91 // Return a FocusSearch object that implements the algorithm to find
92 // the next or previous focusable view.
93 virtual FocusSearch* GetFocusSearch() = 0;
94
95 // Should return the parent FocusTraversable.
96 // The top RootView which is the top FocusTraversable returns NULL.
97 virtual FocusTraversable* GetFocusTraversableParent() = 0;
98
99 // This should return the View this FocusTraversable belongs to.
100 // It is used when walking up the view hierarchy tree to find which view
101 // should be used as the starting view for finding the next/previous view.
102 virtual View* GetFocusTraversableParentView() = 0;
103
104 protected:
105 virtual ~FocusTraversable() {}
106 };
107
108 // This interface should be implemented by classes that want to be notified when
109 // the focus is about to change. See the Add/RemoveFocusChangeListener methods.
110 class VIEWS_EXPORT FocusChangeListener {
111 public:
112 // No change to focus state has occurred yet when this function is called.
113 virtual void OnWillChangeFocus(View* focused_before, View* focused_now) = 0;
114
115 // Called after focus state has changed.
116 virtual void OnDidChangeFocus(View* focused_before, View* focused_now) = 0;
117
118 protected:
119 virtual ~FocusChangeListener() {}
120 };
121
122 class VIEWS_EXPORT FocusManager {
123 public:
124 // The reason why the focus changed.
125 enum FocusChangeReason {
126 // The focus changed because the user traversed focusable views using
127 // keys like Tab or Shift+Tab.
128 kReasonFocusTraversal,
129
130 // The focus changed due to restoring the focus.
131 kReasonFocusRestore,
132
133 // The focus changed due to a click or a shortcut to jump directly to
134 // a particular view.
135 kReasonDirectFocusChange
136 };
137
138 explicit FocusManager(Widget* widget);
139 virtual ~FocusManager();
140
141 // Processes the passed key event for accelerators and tab traversal.
142 // Returns false if the event has been consumed and should not be processed
143 // further.
144 bool OnKeyEvent(const KeyEvent& event);
145
146 // Returns true is the specified is part of the hierarchy of the window
147 // associated with this FocusManager.
148 bool ContainsView(View* view);
149
150 // Advances the focus (backward if reverse is true).
151 void AdvanceFocus(bool reverse);
152
153 // The FocusManager keeps track of the focused view within a RootView.
154 View* GetFocusedView() { return focused_view_; }
155 const View* GetFocusedView() const { return focused_view_; }
156
157 // Low-level methods to force the focus to change (and optionally provide
158 // a reason). If the focus change should only happen if the view is
159 // currenty focusable, enabled, and visible, call view->RequestFocus().
160 void SetFocusedViewWithReason(View* view, FocusChangeReason reason);
161 void SetFocusedView(View* view) {
162 SetFocusedViewWithReason(view, kReasonDirectFocusChange);
163 }
164
165 // Get the reason why the focus most recently changed.
166 FocusChangeReason focus_change_reason() const {
167 return focus_change_reason_;
168 }
169
170 // Clears the focused view. The window associated with the top root view gets
171 // the native focus (so we still get keyboard events).
172 void ClearFocus();
173
174 // Validates the focused view, clearing it if the window it belongs too is not
175 // attached to the window hierarchy anymore.
176 void ValidateFocusedView();
177
178 // Stores and restores the focused view. Used when the window becomes
179 // active/inactive.
180 void StoreFocusedView();
181 void RestoreFocusedView();
182
183 // Clears the stored focused view.
184 void ClearStoredFocusedView();
185
186 // Returns true if in the process of changing the focused view.
187 bool is_changing_focus() const { return is_changing_focus_; }
188
189 // Register a keyboard accelerator for the specified target. If multiple
190 // targets are registered for an accelerator, a target registered later has
191 // higher priority.
192 // Note that we are currently limited to accelerators that are either:
193 // - a key combination including Ctrl or Alt
194 // - the escape key
195 // - the enter key
196 // - any F key (F1, F2, F3 ...)
197 // - any browser specific keys (as available on special keyboards)
198 void RegisterAccelerator(const ui::Accelerator& accelerator,
199 ui::AcceleratorTarget* target);
200
201 // Unregister the specified keyboard accelerator for the specified target.
202 void UnregisterAccelerator(const ui::Accelerator& accelerator,
203 ui::AcceleratorTarget* target);
204
205 // Unregister all keyboard accelerator for the specified target.
206 void UnregisterAccelerators(ui::AcceleratorTarget* target);
207
208 // Activate the target associated with the specified accelerator.
209 // First, AcceleratorPressed handler of the most recently registered target
210 // is called, and if that handler processes the event (i.e. returns true),
211 // this method immediately returns. If not, we do the same thing on the next
212 // target, and so on.
213 // Returns true if an accelerator was activated.
214 bool ProcessAccelerator(const ui::Accelerator& accelerator);
215
216 // Called by a RootView when a view within its hierarchy is removed
217 // from its parent. This will only be called by a RootView in a
218 // hierarchy of Widgets that this FocusManager is attached to the
219 // parent Widget of.
220 void ViewRemoved(View* removed);
221
222 // Adds/removes a listener. The FocusChangeListener is notified every time
223 // the focused view is about to change.
224 void AddFocusChangeListener(FocusChangeListener* listener);
225 void RemoveFocusChangeListener(FocusChangeListener* listener);
226
227 // Returns the AcceleratorTarget that should be activated for the specified
228 // keyboard accelerator, or NULL if no view is registered for that keyboard
229 // accelerator.
230 ui::AcceleratorTarget* GetCurrentTargetForAccelerator(
231 const ui::Accelerator& accelertor) const;
232
233 // Sets the focus to the specified native view.
234 virtual void FocusNativeView(gfx::NativeView native_view);
235
236 // Clears the native view having the focus.
237 virtual void ClearNativeFocus();
238
239 // Convenience method that returns true if the passed |key_event| should
240 // trigger tab traversal (if it is a TAB key press with or without SHIFT
241 // pressed).
242 static bool IsTabTraversalKeyEvent(const KeyEvent& key_event);
243
244 private:
245 // Returns the next focusable view.
246 View* GetNextFocusableView(View* starting_view, bool reverse, bool dont_loop);
247
248 // Returns the focusable view found in the FocusTraversable specified starting
249 // at the specified view. This traverses down along the FocusTraversable
250 // hierarchy.
251 // Returns NULL if no focusable view were found.
252 View* FindFocusableView(FocusTraversable* focus_traversable,
253 View* starting_view,
254 bool reverse);
255
256 // The top-level Widget this FocusManager is associated with.
257 Widget* widget_;
258
259 // The view that currently is focused.
260 View* focused_view_;
261
262 // The AcceleratorManager this FocusManager is associated with.
263 scoped_ptr<ui::AcceleratorManager> accelerator_manager_;
264
265 // The storage id used in the ViewStorage to store/restore the view that last
266 // had focus.
267 int stored_focused_view_storage_id_;
268
269 // The reason why the focus most recently changed.
270 FocusChangeReason focus_change_reason_;
271
272 // The list of registered FocusChange listeners.
273 ObserverList<FocusChangeListener, true> focus_change_listeners_;
274
275 // See description above getter.
276 bool is_changing_focus_;
277
278 DISALLOW_COPY_AND_ASSIGN(FocusManager);
279 };
280
281 } // namespace views
282 11
283 #endif // VIEWS_FOCUS_FOCUS_MANAGER_H_ 12 #endif // VIEWS_FOCUS_FOCUS_MANAGER_H_
OLDNEW
« no previous file with comments | « views/focus/external_focus_tracker.cc ('k') | views/focus/focus_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698