| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "ui/views/focus/focus_manager.h" | 5 #include "ui/views/focus/focus_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "build/build_config.h" | 12 #include "build/build_config.h" |
| 13 #include "ui/base/accelerators/accelerator.h" | 13 #include "ui/base/accelerators/accelerator.h" |
| 14 #include "ui/base/ime/input_method.h" | 14 #include "ui/base/ime/input_method.h" |
| 15 #include "ui/base/ime/text_input_client.h" | 15 #include "ui/base/ime/text_input_client.h" |
| 16 #include "ui/events/event.h" | 16 #include "ui/events/event.h" |
| 17 #include "ui/events/keycodes/keyboard_codes.h" | 17 #include "ui/events/keycodes/keyboard_codes.h" |
| 18 #include "ui/gfx/canvas.h" |
| 19 #include "ui/native_theme/native_theme.h" |
| 18 #include "ui/views/focus/focus_manager_delegate.h" | 20 #include "ui/views/focus/focus_manager_delegate.h" |
| 19 #include "ui/views/focus/focus_search.h" | 21 #include "ui/views/focus/focus_search.h" |
| 20 #include "ui/views/focus/view_storage.h" | 22 #include "ui/views/focus/view_storage.h" |
| 21 #include "ui/views/focus/widget_focus_manager.h" | 23 #include "ui/views/focus/widget_focus_manager.h" |
| 22 #include "ui/views/view.h" | 24 #include "ui/views/view.h" |
| 23 #include "ui/views/widget/root_view.h" | 25 #include "ui/views/widget/root_view.h" |
| 24 #include "ui/views/widget/widget.h" | 26 #include "ui/views/widget/widget.h" |
| 25 #include "ui/views/widget/widget_delegate.h" | 27 #include "ui/views/widget/widget_delegate.h" |
| 26 | 28 |
| 27 namespace views { | 29 namespace views { |
| 28 | 30 |
| 31 namespace internal { |
| 32 |
| 33 // The stroke width of the focus border in dp. |
| 34 const int kFocusBorderThickness = 2; |
| 35 |
| 36 // The corner radius of the focus border roundrect. |
| 37 const int kFocusBorderCornerRadius = 3; |
| 38 |
| 39 // MdFocusRing is a View that is parented to the currently focused View. |
| 40 // It paints a ring around the view to indicate focus, and extends slightly |
| 41 // beyond the bounds of the view. By having a single focus ring per |
| 42 // FocusManager, we reduce the number of views and layers as well as the |
| 43 // number of focus change observers. |
| 44 class MdFocusRing : public View { |
| 45 public: |
| 46 MdFocusRing() { |
| 47 // A layer is necessary to paint beyond the parent's bounds. |
| 48 SetPaintToLayer(true); |
| 49 layer()->SetFillsBoundsOpaquely(false); |
| 50 set_owned_by_client(); |
| 51 } |
| 52 ~MdFocusRing() override {} |
| 53 |
| 54 void Install(views::View* focused_view) { |
| 55 focused_view->AddChildView(this); |
| 56 Layout(); |
| 57 } |
| 58 |
| 59 void Uninstall(views::View* unfocused_view) { |
| 60 if (parent() != unfocused_view) |
| 61 return; |
| 62 parent()->RemoveChildView(this); |
| 63 } |
| 64 |
| 65 // View: |
| 66 bool CanProcessEventsWithinSubtree() const override { return false; } |
| 67 |
| 68 void Layout() override { |
| 69 // The focus ring handles its own sizing, which is simply to fill the parent |
| 70 // and extend a little beyond its borders. |
| 71 gfx::Rect focus_bounds = parent()->GetLocalBounds(); |
| 72 focus_bounds.Inset(gfx::Insets(-kFocusBorderThickness)); |
| 73 SetBoundsRect(focus_bounds); |
| 74 } |
| 75 |
| 76 void OnPaint(gfx::Canvas* canvas) override { |
| 77 SkPaint paint; |
| 78 paint.setAntiAlias(true); |
| 79 paint.setColor( |
| 80 SkColorSetA(GetNativeTheme()->GetSystemColor( |
| 81 ui::NativeTheme::kColorId_FocusedBorderColor), |
| 82 0x66)); |
| 83 paint.setStyle(SkPaint::kStroke_Style); |
| 84 paint.setStrokeWidth(kFocusBorderThickness); |
| 85 gfx::RectF rect(GetLocalBounds()); |
| 86 rect.Inset(gfx::InsetsF(kFocusBorderThickness / 2.f)); |
| 87 canvas->DrawRoundRect(rect, kFocusBorderCornerRadius, paint); |
| 88 } |
| 89 |
| 90 private: |
| 91 DISALLOW_COPY_AND_ASSIGN(MdFocusRing); |
| 92 }; |
| 93 |
| 94 } // namespace internal |
| 95 |
| 29 bool FocusManager::arrow_key_traversal_enabled_ = false; | 96 bool FocusManager::arrow_key_traversal_enabled_ = false; |
| 30 | 97 |
| 31 FocusManager::FocusManager(Widget* widget, FocusManagerDelegate* delegate) | 98 FocusManager::FocusManager(Widget* widget, FocusManagerDelegate* delegate) |
| 32 : widget_(widget), | 99 : widget_(widget), |
| 33 delegate_(delegate), | 100 delegate_(delegate), |
| 34 focused_view_(NULL), | 101 focused_view_(NULL), |
| 35 accelerator_manager_(new ui::AcceleratorManager), | 102 accelerator_manager_(new ui::AcceleratorManager), |
| 36 shortcut_handling_suspended_(false), | 103 shortcut_handling_suspended_(false), |
| 37 focus_change_reason_(kReasonDirectFocusChange), | 104 focus_change_reason_(kReasonDirectFocusChange), |
| 38 is_changing_focus_(false), | 105 is_changing_focus_(false), |
| 39 keyboard_accessible_(false) { | 106 keyboard_accessible_(false), |
| 107 focus_ring_(nullptr) { |
| 40 DCHECK(widget_); | 108 DCHECK(widget_); |
| 41 stored_focused_view_storage_id_ = | 109 stored_focused_view_storage_id_ = |
| 42 ViewStorage::GetInstance()->CreateStorageID(); | 110 ViewStorage::GetInstance()->CreateStorageID(); |
| 43 } | 111 } |
| 44 | 112 |
| 45 FocusManager::~FocusManager() { | 113 FocusManager::~FocusManager() { |
| 46 } | 114 } |
| 47 | 115 |
| 48 bool FocusManager::OnKeyEvent(const ui::KeyEvent& event) { | 116 bool FocusManager::OnKeyEvent(const ui::KeyEvent& event) { |
| 49 const int key_code = event.key_code(); | 117 const int key_code = event.key_code(); |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 | 383 |
| 316 base::AutoReset<bool> auto_changing_focus(&is_changing_focus_, true); | 384 base::AutoReset<bool> auto_changing_focus(&is_changing_focus_, true); |
| 317 // Update the reason for the focus change (since this is checked by | 385 // Update the reason for the focus change (since this is checked by |
| 318 // some listeners), then notify all listeners. | 386 // some listeners), then notify all listeners. |
| 319 focus_change_reason_ = reason; | 387 focus_change_reason_ = reason; |
| 320 FOR_EACH_OBSERVER(FocusChangeListener, focus_change_listeners_, | 388 FOR_EACH_OBSERVER(FocusChangeListener, focus_change_listeners_, |
| 321 OnWillChangeFocus(focused_view_, view)); | 389 OnWillChangeFocus(focused_view_, view)); |
| 322 | 390 |
| 323 View* old_focused_view = focused_view_; | 391 View* old_focused_view = focused_view_; |
| 324 focused_view_ = view; | 392 focused_view_ = view; |
| 325 if (old_focused_view) | 393 if (old_focused_view) { |
| 326 old_focused_view->Blur(); | 394 old_focused_view->Blur(); |
| 395 if (focus_ring_) |
| 396 focus_ring_->Uninstall(old_focused_view); |
| 397 } |
| 327 // Also make |focused_view_| the stored focus view. This way the stored focus | 398 // Also make |focused_view_| the stored focus view. This way the stored focus |
| 328 // view is remembered if focus changes are requested prior to a show or while | 399 // view is remembered if focus changes are requested prior to a show or while |
| 329 // hidden. | 400 // hidden. |
| 330 SetStoredFocusView(focused_view_); | 401 SetStoredFocusView(focused_view_); |
| 331 if (focused_view_) | 402 if (focused_view_) { |
| 332 focused_view_->Focus(); | 403 focused_view_->Focus(); |
| 404 if (focused_view_->should_use_md_focus_ring()) { |
| 405 if (!focus_ring_) |
| 406 focus_ring_.reset(new internal::MdFocusRing()); |
| 407 focus_ring_->Install(focused_view_); |
| 408 } |
| 409 } |
| 333 | 410 |
| 334 FOR_EACH_OBSERVER(FocusChangeListener, focus_change_listeners_, | 411 FOR_EACH_OBSERVER(FocusChangeListener, focus_change_listeners_, |
| 335 OnDidChangeFocus(old_focused_view, focused_view_)); | 412 OnDidChangeFocus(old_focused_view, focused_view_)); |
| 336 } | 413 } |
| 337 | 414 |
| 338 void FocusManager::ClearFocus() { | 415 void FocusManager::ClearFocus() { |
| 339 // SetFocusedView(NULL) is going to clear out the stored view to. We need to | 416 // SetFocusedView(NULL) is going to clear out the stored view to. We need to |
| 340 // persist it in this case. | 417 // persist it in this case. |
| 341 views::View* focused_view = GetStoredFocusView(); | 418 views::View* focused_view = GetStoredFocusView(); |
| 342 SetFocusedView(NULL); | 419 SetFocusedView(NULL); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 // |keyboard_accessible_| is only used on Mac. | 630 // |keyboard_accessible_| is only used on Mac. |
| 554 #if defined(OS_MACOSX) | 631 #if defined(OS_MACOSX) |
| 555 return keyboard_accessible_ ? view->IsAccessibilityFocusable() | 632 return keyboard_accessible_ ? view->IsAccessibilityFocusable() |
| 556 : view->IsFocusable(); | 633 : view->IsFocusable(); |
| 557 #else | 634 #else |
| 558 return view->IsAccessibilityFocusable(); | 635 return view->IsAccessibilityFocusable(); |
| 559 #endif | 636 #endif |
| 560 } | 637 } |
| 561 | 638 |
| 562 } // namespace views | 639 } // namespace views |
| OLD | NEW |