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

Side by Side Diff: ui/views/focus/focus_manager.cc

Issue 2380303004: Move MdFocusRing to be a property of FocusManager. (Closed)
Patch Set: Created 4 years, 2 months 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
« no previous file with comments | « ui/views/focus/focus_manager.h ('k') | ui/views/view.h » ('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) 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
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
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
OLDNEW
« no previous file with comments | « ui/views/focus/focus_manager.h ('k') | ui/views/view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698