| 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 HWND has. | 23 // - the native focus, which is the focus that an gfx::NativeView 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, if it derives from WidgetWin, the | 35 // When creating a top window (derived from views::Widget) that is not a child |
| 36 // |has_own_focus_manager| of the Init method lets you specify whether that | 36 // window, it creates and owns a FocusManager to manage the focus for itself and |
| 37 // window should have its own focus manager (so focus traversal stays confined | 37 // all its child windows. |
| 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). | |
| 42 // | 38 // |
| 43 // The FocusTraversable interface exposes the methods a class should implement | 39 // The FocusTraversable interface exposes the methods a class should implement |
| 44 // in order to be able to be focus traversed when tab key is pressed. | 40 // in order to be able to be focus traversed when tab key is pressed. |
| 45 // RootViews implement FocusTraversable. | 41 // RootViews implement FocusTraversable. |
| 46 // The FocusManager contains a top FocusTraversable instance, which is the top | 42 // The FocusManager contains a top FocusTraversable instance, which is the top |
| 47 // RootView. | 43 // RootView. |
| 48 // | 44 // |
| 49 // If you just use views, then the focus traversal is handled for you by the | 45 // If you just use views, then the focus traversal is handled for you by the |
| 50 // RootView. The default traversal order is the order in which the views have | 46 // RootView. The default traversal order is the order in which the views have |
| 51 // been added to their container. You can modify this order by using the View | 47 // been added to their container. You can modify this order by using the View |
| (...skipping 18 matching lines...) Expand all Loading... |
| 70 // with when going to the next/previous view. | 66 // with when going to the next/previous view. |
| 71 // In our example: | 67 // In our example: |
| 72 // hwnd_view_container_->GetRootView()->SetFocusTraversableParent( | 68 // hwnd_view_container_->GetRootView()->SetFocusTraversableParent( |
| 73 // native_control); | 69 // native_control); |
| 74 // | 70 // |
| 75 // Note that FocusTraversable do not have to be RootViews: TabContents is | 71 // Note that FocusTraversable do not have to be RootViews: TabContents is |
| 76 // FocusTraversable. | 72 // FocusTraversable. |
| 77 | 73 |
| 78 namespace views { | 74 namespace views { |
| 79 | 75 |
| 76 class RootView; |
| 80 class View; | 77 class View; |
| 81 class RootView; | 78 class Widget; |
| 82 | 79 |
| 83 // The FocusTraversable interface is used by components that want to process | 80 // The FocusTraversable interface is used by components that want to process |
| 84 // focus traversal events (due to Tab/Shift-Tab key events). | 81 // focus traversal events (due to Tab/Shift-Tab key events). |
| 85 class FocusTraversable { | 82 class FocusTraversable { |
| 86 public: | 83 public: |
| 87 // The direction in which the focus traversal is going. | 84 // The direction in which the focus traversal is going. |
| 88 // TODO (jcampan): add support for lateral (left, right) focus traversal. The | 85 // TODO (jcampan): add support for lateral (left, right) focus traversal. The |
| 89 // goal is to switch to focusable views on the same level when using the arrow | 86 // goal is to switch to focusable views on the same level when using the arrow |
| 90 // keys (ala Windows: in a dialog box, arrow keys typically move between the | 87 // keys (ala Windows: in a dialog box, arrow keys typically move between the |
| 91 // dialog OK, Cancel buttons). | 88 // dialog OK, Cancel buttons). |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 | 143 |
| 147 // This interface should be implemented by classes that want to be notified when | 144 // This interface should be implemented by classes that want to be notified when |
| 148 // the focus is about to change. See the Add/RemoveFocusChangeListener methods. | 145 // the focus is about to change. See the Add/RemoveFocusChangeListener methods. |
| 149 class FocusChangeListener { | 146 class FocusChangeListener { |
| 150 public: | 147 public: |
| 151 virtual void FocusWillChange(View* focused_before, View* focused_now) = 0; | 148 virtual void FocusWillChange(View* focused_before, View* focused_now) = 0; |
| 152 }; | 149 }; |
| 153 | 150 |
| 154 class FocusManager { | 151 class FocusManager { |
| 155 public: | 152 public: |
| 156 #if defined(OS_WIN) | 153 explicit FocusManager(Widget* widget); |
| 157 // Creates a FocusManager for the specified window. Top level windows | 154 ~FocusManager(); |
| 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); | |
| 165 | 155 |
| 166 #if defined(OS_WIN) | 156 #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); | |
| 172 // OnKeyDown covers WM_KEYDOWN and WM_SYSKEYDOWN. | 157 // OnKeyDown covers WM_KEYDOWN and WM_SYSKEYDOWN. |
| 173 bool OnKeyDown(HWND window, | 158 bool OnKeyDown(HWND window, |
| 174 UINT message, | 159 UINT message, |
| 175 WPARAM wparam, | 160 WPARAM wparam, |
| 176 LPARAM lparam); | 161 LPARAM lparam); |
| 177 bool OnKeyUp(HWND window, | 162 bool OnKeyUp(HWND window, |
| 178 UINT message, | 163 UINT message, |
| 179 WPARAM wparam, | 164 WPARAM wparam, |
| 180 LPARAM lparam); | 165 LPARAM lparam); |
| 181 #endif | 166 #endif |
| 182 | 167 |
| 183 // Returns true is the specified is part of the hierarchy of the window | 168 // Returns true is the specified is part of the hierarchy of the window |
| 184 // associated with this FocusManager. | 169 // associated with this FocusManager. |
| 185 bool ContainsView(View* view); | 170 bool ContainsView(View* view); |
| 186 | 171 |
| 187 // Advances the focus (backward if reverse is true). | 172 // Advances the focus (backward if reverse is true). |
| 188 void AdvanceFocus(bool reverse); | 173 void AdvanceFocus(bool reverse); |
| 189 | 174 |
| 190 // The FocusManager is handling the selected view for the RootView. | 175 // The FocusManager is handling the selected view for the RootView. |
| 191 View* GetFocusedView() const { return focused_view_; } | 176 View* GetFocusedView() const { return focused_view_; } |
| 192 void SetFocusedView(View* view); | 177 void SetFocusedView(View* view); |
| 193 | 178 |
| 194 // Clears the focused view. The window associated with the top root view gets | 179 // Clears the focused view. The window associated with the top root view gets |
| 195 // the native focus (so we still get keyboard events). | 180 // the native focus (so we still get keyboard events). |
| 196 void ClearFocus(); | 181 void ClearFocus(); |
| 197 | 182 |
| 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 | |
| 208 // Validates the focused view, clearing it if the window it belongs too is not | 183 // Validates the focused view, clearing it if the window it belongs too is not |
| 209 // attached to the window hierarchy anymore. | 184 // attached to the window hierarchy anymore. |
| 210 void ValidateFocusedView(); | 185 void ValidateFocusedView(); |
| 211 | 186 |
| 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 | |
| 219 // Stores and restores the focused view. Used when the window becomes | 187 // Stores and restores the focused view. Used when the window becomes |
| 220 // active/inactive. | 188 // active/inactive. |
| 221 void StoreFocusedView(); | 189 void StoreFocusedView(); |
| 222 void RestoreFocusedView(); | 190 void RestoreFocusedView(); |
| 223 | 191 |
| 224 // Clears the stored focused view. | 192 // Clears the stored focused view. |
| 225 void ClearStoredFocusedView(); | 193 void ClearStoredFocusedView(); |
| 226 | 194 |
| 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 | |
| 232 // Register a keyboard accelerator for the specified target. If multiple | 195 // Register a keyboard accelerator for the specified target. If multiple |
| 233 // targets are registered for an accelerator, a target registered later has | 196 // targets are registered for an accelerator, a target registered later has |
| 234 // higher priority. | 197 // higher priority. |
| 235 // Note that we are currently limited to accelerators that are either: | 198 // Note that we are currently limited to accelerators that are either: |
| 236 // - a key combination including Ctrl or Alt | 199 // - a key combination including Ctrl or Alt |
| 237 // - the escape key | 200 // - the escape key |
| 238 // - the enter key | 201 // - the enter key |
| 239 // - any F key (F1, F2, F3 ...) | 202 // - any F key (F1, F2, F3 ...) |
| 240 // - any browser specific keys (as available on special keyboards) | 203 // - any browser specific keys (as available on special keyboards) |
| 241 void RegisterAccelerator(const Accelerator& accelerator, | 204 void RegisterAccelerator(const Accelerator& accelerator, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 // keyboard accelerator, or NULL if no view is registered for that keyboard | 236 // keyboard accelerator, or NULL if no view is registered for that keyboard |
| 274 // accelerator. | 237 // accelerator. |
| 275 AcceleratorTarget* GetCurrentTargetForAccelerator( | 238 AcceleratorTarget* GetCurrentTargetForAccelerator( |
| 276 const Accelerator& accelertor) const; | 239 const Accelerator& accelertor) const; |
| 277 | 240 |
| 278 // Convenience method that returns true if the passed |key_event| should | 241 // Convenience method that returns true if the passed |key_event| should |
| 279 // trigger tab traversal (if it is a TAB key press with or without SHIFT | 242 // trigger tab traversal (if it is a TAB key press with or without SHIFT |
| 280 // pressed). | 243 // pressed). |
| 281 static bool IsTabTraversalKeyEvent(const KeyEvent& key_event); | 244 static bool IsTabTraversalKeyEvent(const KeyEvent& key_event); |
| 282 | 245 |
| 246 // Sets the focus to the specified native view. |
| 247 virtual void FocusNativeView(gfx::NativeView native_view); |
| 248 |
| 249 // Clears the native view having the focus. |
| 250 virtual void ClearNativeFocus(); |
| 251 |
| 252 // Retrieves the FocusManager associated with the passed native view. |
| 253 static FocusManager* GetFocusManagerForNativeView( |
| 254 gfx::NativeView native_view); |
| 255 |
| 283 private: | 256 private: |
| 284 #if defined(OS_WIN) | |
| 285 explicit FocusManager(HWND root, RootView* root_view); | |
| 286 | |
| 287 // Subclasses the specified window. The subclassed window procedure listens | |
| 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); | |
| 293 | |
| 294 // Uninstalls the window subclass installed by InstallFocusSubclass. | |
| 295 static void UninstallFocusSubclass(HWND window); | |
| 296 #endif | |
| 297 ~FocusManager(); | |
| 298 | |
| 299 // Returns the next focusable view. | 257 // Returns the next focusable view. |
| 300 View* GetNextFocusableView(View* starting_view, bool reverse, bool dont_loop); | 258 View* GetNextFocusableView(View* starting_view, bool reverse, bool dont_loop); |
| 301 | 259 |
| 302 // Returns the focusable view found in the FocusTraversable specified starting | 260 // Returns the focusable view found in the FocusTraversable specified starting |
| 303 // at the specified view. This traverses down along the FocusTraversable | 261 // at the specified view. This traverses down along the FocusTraversable |
| 304 // hierarchy. | 262 // hierarchy. |
| 305 // Returns NULL if no focusable view were found. | 263 // Returns NULL if no focusable view were found. |
| 306 View* FindFocusableView(FocusTraversable* focus_traversable, | 264 View* FindFocusableView(FocusTraversable* focus_traversable, |
| 307 View* starting_view, | 265 View* starting_view, |
| 308 bool reverse); | 266 bool reverse); |
| 309 | 267 |
| 310 // The RootView of the window associated with this FocusManager. | 268 // The top-level Widget this FocusManager is associated with. |
| 311 RootView* top_root_view_; | 269 Widget* widget_; |
| 312 | 270 |
| 313 // The view that currently is focused. | 271 // The view that currently is focused. |
| 314 View* focused_view_; | 272 View* focused_view_; |
| 315 | 273 |
| 316 // The storage id used in the ViewStorage to store/restore the view that last | 274 // The storage id used in the ViewStorage to store/restore the view that last |
| 317 // had focus. | 275 // had focus. |
| 318 int stored_focused_view_storage_id_; | 276 int stored_focused_view_storage_id_; |
| 319 | 277 |
| 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 | |
| 327 // The accelerators and associated targets. | 278 // The accelerators and associated targets. |
| 328 typedef std::list<AcceleratorTarget*> AcceleratorTargetList; | 279 typedef std::list<AcceleratorTarget*> AcceleratorTargetList; |
| 329 typedef std::map<Accelerator, AcceleratorTargetList> AcceleratorMap; | 280 typedef std::map<Accelerator, AcceleratorTargetList> AcceleratorMap; |
| 330 AcceleratorMap accelerators_; | 281 AcceleratorMap accelerators_; |
| 331 | 282 |
| 332 // The list of registered keystroke listeners | 283 // The list of registered keystroke listeners |
| 333 typedef std::vector<KeystrokeListener*> KeystrokeListenerList; | 284 typedef std::vector<KeystrokeListener*> KeystrokeListenerList; |
| 334 KeystrokeListenerList keystroke_listeners_; | 285 KeystrokeListenerList keystroke_listeners_; |
| 335 | 286 |
| 336 // The list of registered FocusChange listeners. | 287 // The list of registered FocusChange listeners. |
| 337 typedef std::vector<FocusChangeListener*> FocusChangeListenerList; | 288 typedef std::vector<FocusChangeListener*> FocusChangeListenerList; |
| 338 FocusChangeListenerList focus_change_listeners_; | 289 FocusChangeListenerList focus_change_listeners_; |
| 339 | 290 |
| 340 DISALLOW_COPY_AND_ASSIGN(FocusManager); | 291 DISALLOW_COPY_AND_ASSIGN(FocusManager); |
| 341 }; | 292 }; |
| 342 | 293 |
| 343 } // namespace views | 294 } // namespace views |
| 344 | 295 |
| 345 #endif // VIEWS_FOCUS_FOCUS_MANAGER_H_ | 296 #endif // VIEWS_FOCUS_FOCUS_MANAGER_H_ |
| OLD | NEW |