| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 | 7 |
| 8 #if defined(OS_WIN) | 8 #if defined(OS_WIN) |
| 9 #include <windows.h> | 9 #include <windows.h> |
| 10 #endif | 10 #endif |
| 11 #include <vector> | 11 #include <vector> |
| 12 #include <map> | 12 #include <map> |
| 13 #include <list> | 13 #include <list> |
| 14 | 14 |
| 15 #include "base/basictypes.h" | 15 #include "base/basictypes.h" |
| 16 #include "base/gfx/native_widget_types.h" | 16 #include "base/gfx/native_widget_types.h" |
| 17 #include "views/accelerator.h" | 17 #include "views/accelerator.h" |
| 18 | 18 |
| 19 // The FocusManager class is used to handle focus traversal, store/restore | 19 // The FocusManager class is used to handle focus traversal, store/restore |
| 20 // focused views and handle keyboard accelerators. | 20 // focused views and handle keyboard accelerators. |
| 21 // | 21 // |
| 22 // There are 2 types of focus: | 22 // There are 2 types of focus: |
| 23 // - the native focus, which is the focus that an gfx::NativeView has. | 23 // - the native focus, which is the focus that an HWND has. |
| 24 // - the view focus, which is the focus that a views::View has. | 24 // - the view focus, which is the focus that a views::View has. |
| 25 // | 25 // |
| 26 // Each native view must register with their Focus Manager so the focus manager | 26 // Each native view must register with their Focus Manager so the focus manager |
| 27 // gets notified when they are focused (and keeps track of the native focus) and | 27 // gets notified when they are focused (and keeps track of the native focus) and |
| 28 // as well so that the tab key events can be intercepted. | 28 // as well so that the tab key events can be intercepted. |
| 29 // They can provide when they register a View that is kept in synch in term of | 29 // They can provide when they register a View that is kept in synch in term of |
| 30 // focus. This is used in NativeControl for example, where a View wraps an | 30 // focus. This is used in NativeControl for example, where a View wraps an |
| 31 // actual native window. | 31 // actual native window. |
| 32 // This is already done for you if you subclass the NativeControl class or if | 32 // This is already done for you if you subclass the NativeControl class or if |
| 33 // you use the NativeViewHost class. | 33 // you use the NativeViewHost class. |
| 34 // | 34 // |
| 35 // When creating a top window (derived from views::Widget) that is not a child | 35 // When creating a top window, if it derives from WidgetWin, the |
| 36 // window, it creates and owns a FocusManager to manage the focus for itself and | 36 // |has_own_focus_manager| of the Init method lets you specify whether that |
| 37 // all its child windows. | 37 // window should have its own focus manager (so focus traversal stays confined |
| 38 // in that window). If you are not deriving from WidgetWin or one of its |
| 39 // derived classes (Window, FramelessWindow, ConstrainedWindow), you must |
| 40 // create a FocusManager when the window is created (it is automatically deleted |
| 41 // when the window is destroyed). |
| 38 // | 42 // |
| 39 // The FocusTraversable interface exposes the methods a class should implement | 43 // The FocusTraversable interface exposes the methods a class should implement |
| 40 // in order to be able to be focus traversed when tab key is pressed. | 44 // in order to be able to be focus traversed when tab key is pressed. |
| 41 // RootViews implement FocusTraversable. | 45 // RootViews implement FocusTraversable. |
| 42 // The FocusManager contains a top FocusTraversable instance, which is the top | 46 // The FocusManager contains a top FocusTraversable instance, which is the top |
| 43 // RootView. | 47 // RootView. |
| 44 // | 48 // |
| 45 // If you just use views, then the focus traversal is handled for you by the | 49 // If you just use views, then the focus traversal is handled for you by the |
| 46 // RootView. The default traversal order is the order in which the views have | 50 // RootView. The default traversal order is the order in which the views have |
| 47 // been added to their container. You can modify this order by using the View | 51 // been added to their container. You can modify this order by using the View |
| (...skipping 18 matching lines...) Expand all Loading... |
| 66 // with when going to the next/previous view. | 70 // with when going to the next/previous view. |
| 67 // In our example: | 71 // In our example: |
| 68 // hwnd_view_container_->GetRootView()->SetFocusTraversableParent( | 72 // hwnd_view_container_->GetRootView()->SetFocusTraversableParent( |
| 69 // native_control); | 73 // native_control); |
| 70 // | 74 // |
| 71 // Note that FocusTraversable do not have to be RootViews: TabContents is | 75 // Note that FocusTraversable do not have to be RootViews: TabContents is |
| 72 // FocusTraversable. | 76 // FocusTraversable. |
| 73 | 77 |
| 74 namespace views { | 78 namespace views { |
| 75 | 79 |
| 80 class View; |
| 76 class RootView; | 81 class RootView; |
| 77 class View; | |
| 78 class Widget; | |
| 79 | 82 |
| 80 // The FocusTraversable interface is used by components that want to process | 83 // The FocusTraversable interface is used by components that want to process |
| 81 // focus traversal events (due to Tab/Shift-Tab key events). | 84 // focus traversal events (due to Tab/Shift-Tab key events). |
| 82 class FocusTraversable { | 85 class FocusTraversable { |
| 83 public: | 86 public: |
| 84 // The direction in which the focus traversal is going. | 87 // The direction in which the focus traversal is going. |
| 85 // TODO (jcampan): add support for lateral (left, right) focus traversal. The | 88 // TODO (jcampan): add support for lateral (left, right) focus traversal. The |
| 86 // goal is to switch to focusable views on the same level when using the arrow | 89 // goal is to switch to focusable views on the same level when using the arrow |
| 87 // keys (ala Windows: in a dialog box, arrow keys typically move between the | 90 // keys (ala Windows: in a dialog box, arrow keys typically move between the |
| 88 // dialog OK, Cancel buttons). | 91 // dialog OK, Cancel buttons). |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 | 146 |
| 144 // This interface should be implemented by classes that want to be notified when | 147 // This interface should be implemented by classes that want to be notified when |
| 145 // the focus is about to change. See the Add/RemoveFocusChangeListener methods. | 148 // the focus is about to change. See the Add/RemoveFocusChangeListener methods. |
| 146 class FocusChangeListener { | 149 class FocusChangeListener { |
| 147 public: | 150 public: |
| 148 virtual void FocusWillChange(View* focused_before, View* focused_now) = 0; | 151 virtual void FocusWillChange(View* focused_before, View* focused_now) = 0; |
| 149 }; | 152 }; |
| 150 | 153 |
| 151 class FocusManager { | 154 class FocusManager { |
| 152 public: | 155 public: |
| 153 explicit FocusManager(Widget* widget); | 156 #if defined(OS_WIN) |
| 154 ~FocusManager(); | 157 // Creates a FocusManager for the specified window. Top level windows |
| 158 // must invoked this when created. |
| 159 // The RootView specified should be the top RootView of the window. |
| 160 // This also invokes InstallFocusSubclass. |
| 161 static FocusManager* CreateFocusManager(HWND window, RootView* root_view); |
| 162 #endif |
| 163 |
| 164 static FocusManager* GetFocusManager(gfx::NativeView window); |
| 155 | 165 |
| 156 #if defined(OS_WIN) | 166 #if defined(OS_WIN) |
| 167 // Message handlers (for messages received from registered windows). |
| 168 // Should return true if the message should be forwarded to the window |
| 169 // original proc function, false otherwise. |
| 170 bool OnSetFocus(HWND window); |
| 171 bool OnNCDestroy(HWND window); |
| 157 // OnKeyDown covers WM_KEYDOWN and WM_SYSKEYDOWN. | 172 // OnKeyDown covers WM_KEYDOWN and WM_SYSKEYDOWN. |
| 158 bool OnKeyDown(HWND window, | 173 bool OnKeyDown(HWND window, |
| 159 UINT message, | 174 UINT message, |
| 160 WPARAM wparam, | 175 WPARAM wparam, |
| 161 LPARAM lparam); | 176 LPARAM lparam); |
| 162 bool OnKeyUp(HWND window, | 177 bool OnKeyUp(HWND window, |
| 163 UINT message, | 178 UINT message, |
| 164 WPARAM wparam, | 179 WPARAM wparam, |
| 165 LPARAM lparam); | 180 LPARAM lparam); |
| 166 #endif | 181 #endif |
| 167 | 182 |
| 168 // Returns true is the specified is part of the hierarchy of the window | 183 // Returns true is the specified is part of the hierarchy of the window |
| 169 // associated with this FocusManager. | 184 // associated with this FocusManager. |
| 170 bool ContainsView(View* view); | 185 bool ContainsView(View* view); |
| 171 | 186 |
| 172 // Advances the focus (backward if reverse is true). | 187 // Advances the focus (backward if reverse is true). |
| 173 void AdvanceFocus(bool reverse); | 188 void AdvanceFocus(bool reverse); |
| 174 | 189 |
| 175 // The FocusManager is handling the selected view for the RootView. | 190 // The FocusManager is handling the selected view for the RootView. |
| 176 View* GetFocusedView() const { return focused_view_; } | 191 View* GetFocusedView() const { return focused_view_; } |
| 177 void SetFocusedView(View* view); | 192 void SetFocusedView(View* view); |
| 178 | 193 |
| 179 // Clears the focused view. The window associated with the top root view gets | 194 // Clears the focused view. The window associated with the top root view gets |
| 180 // the native focus (so we still get keyboard events). | 195 // the native focus (so we still get keyboard events). |
| 181 void ClearFocus(); | 196 void ClearFocus(); |
| 182 | 197 |
| 198 // Clears the HWND that has the focus by focusing the HWND from the top |
| 199 // RootView (so we still get keyboard events). |
| 200 // Note that this does not change the currently focused view. |
| 201 void ClearHWNDFocus(); |
| 202 |
| 203 #if defined(OS_WIN) |
| 204 // Focus the specified |hwnd| without changing the focused view. |
| 205 void FocusHWND(HWND hwnd); |
| 206 #endif |
| 207 |
| 183 // Validates the focused view, clearing it if the window it belongs too is not | 208 // Validates the focused view, clearing it if the window it belongs too is not |
| 184 // attached to the window hierarchy anymore. | 209 // attached to the window hierarchy anymore. |
| 185 void ValidateFocusedView(); | 210 void ValidateFocusedView(); |
| 186 | 211 |
| 212 #if defined(OS_WIN) |
| 213 // Returns the view associated with the specified window if any. |
| 214 // If |look_in_parents| is true, it goes up the window parents until it find |
| 215 // a view. |
| 216 static View* GetViewForWindow(HWND window, bool look_in_parents); |
| 217 #endif |
| 218 |
| 187 // Stores and restores the focused view. Used when the window becomes | 219 // Stores and restores the focused view. Used when the window becomes |
| 188 // active/inactive. | 220 // active/inactive. |
| 189 void StoreFocusedView(); | 221 void StoreFocusedView(); |
| 190 void RestoreFocusedView(); | 222 void RestoreFocusedView(); |
| 191 | 223 |
| 192 // Clears the stored focused view. | 224 // Clears the stored focused view. |
| 193 void ClearStoredFocusedView(); | 225 void ClearStoredFocusedView(); |
| 194 | 226 |
| 227 // Returns the FocusManager of the parent window of the window that is the |
| 228 // root of this FocusManager. This is useful with ConstrainedWindows that have |
| 229 // their own FocusManager and need to return focus to the browser when closed. |
| 230 FocusManager* GetParentFocusManager() const; |
| 231 |
| 195 // Register a keyboard accelerator for the specified target. If multiple | 232 // Register a keyboard accelerator for the specified target. If multiple |
| 196 // targets are registered for an accelerator, a target registered later has | 233 // targets are registered for an accelerator, a target registered later has |
| 197 // higher priority. | 234 // higher priority. |
| 198 // Note that we are currently limited to accelerators that are either: | 235 // Note that we are currently limited to accelerators that are either: |
| 199 // - a key combination including Ctrl or Alt | 236 // - a key combination including Ctrl or Alt |
| 200 // - the escape key | 237 // - the escape key |
| 201 // - the enter key | 238 // - the enter key |
| 202 // - any F key (F1, F2, F3 ...) | 239 // - any F key (F1, F2, F3 ...) |
| 203 // - any browser specific keys (as available on special keyboards) | 240 // - any browser specific keys (as available on special keyboards) |
| 204 void RegisterAccelerator(const Accelerator& accelerator, | 241 void RegisterAccelerator(const Accelerator& accelerator, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 // keyboard accelerator, or NULL if no view is registered for that keyboard | 273 // keyboard accelerator, or NULL if no view is registered for that keyboard |
| 237 // accelerator. | 274 // accelerator. |
| 238 AcceleratorTarget* GetCurrentTargetForAccelerator( | 275 AcceleratorTarget* GetCurrentTargetForAccelerator( |
| 239 const Accelerator& accelertor) const; | 276 const Accelerator& accelertor) const; |
| 240 | 277 |
| 241 // Convenience method that returns true if the passed |key_event| should | 278 // Convenience method that returns true if the passed |key_event| should |
| 242 // trigger tab traversal (if it is a TAB key press with or without SHIFT | 279 // trigger tab traversal (if it is a TAB key press with or without SHIFT |
| 243 // pressed). | 280 // pressed). |
| 244 static bool IsTabTraversalKeyEvent(const KeyEvent& key_event); | 281 static bool IsTabTraversalKeyEvent(const KeyEvent& key_event); |
| 245 | 282 |
| 246 // Sets the focus to the specified native view. | 283 private: |
| 247 virtual void FocusNativeView(gfx::NativeView native_view); | 284 #if defined(OS_WIN) |
| 285 explicit FocusManager(HWND root, RootView* root_view); |
| 248 | 286 |
| 249 // Clears the native view having the focus. | 287 // Subclasses the specified window. The subclassed window procedure listens |
| 250 virtual void ClearNativeFocus(); | 288 // for WM_SETFOCUS notification and keeps the FocusManager's focus owner |
| 289 // property in sync. |
| 290 // It's not necessary to explicitly invoke Uninstall, it's automatically done |
| 291 // when the window is destroyed and Uninstall wasn't invoked. |
| 292 static void InstallFocusSubclass(HWND window, View* view); |
| 251 | 293 |
| 252 // Retrieves the FocusManager associated with the passed native view. | 294 // Uninstalls the window subclass installed by InstallFocusSubclass. |
| 253 static FocusManager* GetFocusManagerForNativeView( | 295 static void UninstallFocusSubclass(HWND window); |
| 254 gfx::NativeView native_view); | 296 #endif |
| 297 ~FocusManager(); |
| 255 | 298 |
| 256 private: | |
| 257 // Returns the next focusable view. | 299 // Returns the next focusable view. |
| 258 View* GetNextFocusableView(View* starting_view, bool reverse, bool dont_loop); | 300 View* GetNextFocusableView(View* starting_view, bool reverse, bool dont_loop); |
| 259 | 301 |
| 260 // Returns the focusable view found in the FocusTraversable specified starting | 302 // Returns the focusable view found in the FocusTraversable specified starting |
| 261 // at the specified view. This traverses down along the FocusTraversable | 303 // at the specified view. This traverses down along the FocusTraversable |
| 262 // hierarchy. | 304 // hierarchy. |
| 263 // Returns NULL if no focusable view were found. | 305 // Returns NULL if no focusable view were found. |
| 264 View* FindFocusableView(FocusTraversable* focus_traversable, | 306 View* FindFocusableView(FocusTraversable* focus_traversable, |
| 265 View* starting_view, | 307 View* starting_view, |
| 266 bool reverse); | 308 bool reverse); |
| 267 | 309 |
| 268 // The top-level Widget this FocusManager is associated with. | 310 // The RootView of the window associated with this FocusManager. |
| 269 Widget* widget_; | 311 RootView* top_root_view_; |
| 270 | 312 |
| 271 // The view that currently is focused. | 313 // The view that currently is focused. |
| 272 View* focused_view_; | 314 View* focused_view_; |
| 273 | 315 |
| 274 // The storage id used in the ViewStorage to store/restore the view that last | 316 // The storage id used in the ViewStorage to store/restore the view that last |
| 275 // had focus. | 317 // had focus. |
| 276 int stored_focused_view_storage_id_; | 318 int stored_focused_view_storage_id_; |
| 277 | 319 |
| 320 // The window associated with this focus manager. |
| 321 gfx::NativeView root_; |
| 322 |
| 323 // Used to allow setting the focus on an HWND without changing the currently |
| 324 // focused view. |
| 325 bool ignore_set_focus_msg_; |
| 326 |
| 278 // The accelerators and associated targets. | 327 // The accelerators and associated targets. |
| 279 typedef std::list<AcceleratorTarget*> AcceleratorTargetList; | 328 typedef std::list<AcceleratorTarget*> AcceleratorTargetList; |
| 280 typedef std::map<Accelerator, AcceleratorTargetList> AcceleratorMap; | 329 typedef std::map<Accelerator, AcceleratorTargetList> AcceleratorMap; |
| 281 AcceleratorMap accelerators_; | 330 AcceleratorMap accelerators_; |
| 282 | 331 |
| 283 // The list of registered keystroke listeners | 332 // The list of registered keystroke listeners |
| 284 typedef std::vector<KeystrokeListener*> KeystrokeListenerList; | 333 typedef std::vector<KeystrokeListener*> KeystrokeListenerList; |
| 285 KeystrokeListenerList keystroke_listeners_; | 334 KeystrokeListenerList keystroke_listeners_; |
| 286 | 335 |
| 287 // The list of registered FocusChange listeners. | 336 // The list of registered FocusChange listeners. |
| 288 typedef std::vector<FocusChangeListener*> FocusChangeListenerList; | 337 typedef std::vector<FocusChangeListener*> FocusChangeListenerList; |
| 289 FocusChangeListenerList focus_change_listeners_; | 338 FocusChangeListenerList focus_change_listeners_; |
| 290 | 339 |
| 291 DISALLOW_COPY_AND_ASSIGN(FocusManager); | 340 DISALLOW_COPY_AND_ASSIGN(FocusManager); |
| 292 }; | 341 }; |
| 293 | 342 |
| 294 } // namespace views | 343 } // namespace views |
| 295 | 344 |
| 296 #endif // VIEWS_FOCUS_FOCUS_MANAGER_H_ | 345 #endif // VIEWS_FOCUS_FOCUS_MANAGER_H_ |
| OLD | NEW |