1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/ui/focus_ring_controller.h"
6
7 #include "ash/wm/window_util.h"
8 #include "chrome/browser/chromeos/ui/focus_ring_layer.h"
9 #include "ui/views/widget/widget.h"
10
11 namespace chromeos {
12
FocusRingController()13 FocusRingController::FocusRingController()
14 : visible_(false),
15 widget_(NULL) {
16 }
17
~FocusRingController()18 FocusRingController::~FocusRingController() {
19 SetVisible(false);
20 }
21
SetVisible(bool visible)22 void FocusRingController::SetVisible(bool visible) {
23 if (visible_ == visible)
24 return;
25
26 visible_ = visible;
27
28 if (visible_) {
29 views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this);
30 aura::Window* active_window = ash::wm::GetActiveWindow();
31 if (active_window)
32 SetWidget(views::Widget::GetWidgetForNativeWindow(active_window));
33 } else {
34 views::WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(this);
35 SetWidget(NULL);
36 }
37 }
38
UpdateFocusRing()39 void FocusRingController::UpdateFocusRing() {
40 views::View* focused_view = NULL;
41 if (widget_ && widget_->GetFocusManager())
42 focused_view = widget_->GetFocusManager()->GetFocusedView();
43
44 // No focus ring if no focused view or the focused view covers the whole
45 // widget content area (such as RenderWidgetHostWidgetAura).
46 if (!focused_view ||
47 focused_view->ConvertRectToWidget(focused_view->bounds()) ==
48 widget_->GetContentsView()->bounds()) {
49 focus_ring_layer_.reset();
50 return;
51 }
52
53 if (!focus_ring_layer_)
54 focus_ring_layer_.reset(new FocusRingLayer);
55
56 focus_ring_layer_->SetForView(focused_view);
57 }
58
SetWidget(views::Widget * widget)59 void FocusRingController::SetWidget(views::Widget* widget) {
60 if (widget_) {
61 widget_->RemoveObserver(this);
62 if (widget_->GetFocusManager())
63 widget_->GetFocusManager()->RemoveFocusChangeListener(this);
64 }
65
66 widget_ = widget;
67
68 if (widget_) {
69 widget_->AddObserver(this);
70 if (widget_->GetFocusManager())
71 widget_->GetFocusManager()->AddFocusChangeListener(this);
72 }
73
74 UpdateFocusRing();
75 }
76
OnWidgetDestroying(views::Widget * widget)77 void FocusRingController::OnWidgetDestroying(views::Widget* widget) {
78 DCHECK_EQ(widget_, widget);
79 SetWidget(NULL);
80 }
81
OnWidgetBoundsChanged(views::Widget * widget,const gfx::Rect & new_bounds)82 void FocusRingController::OnWidgetBoundsChanged(views::Widget* widget,
83 const gfx::Rect& new_bounds) {
84 DCHECK_EQ(widget_, widget);
85 UpdateFocusRing();
86 }
87
OnNativeFocusChange(gfx::NativeView focused_before,gfx::NativeView focused_now)88 void FocusRingController::OnNativeFocusChange(gfx::NativeView focused_before,
89 gfx::NativeView focused_now) {
90 views::Widget* widget =
91 focused_now ? views::Widget::GetWidgetForNativeWindow(focused_now) : NULL;
92 SetWidget(widget);
93 }
94
OnWillChangeFocus(views::View * focused_before,views::View * focused_now)95 void FocusRingController::OnWillChangeFocus(views::View* focused_before,
96 views::View* focused_now) {
97 }
98
OnDidChangeFocus(views::View * focused_before,views::View * focused_now)99 void FocusRingController::OnDidChangeFocus(views::View* focused_before,
100 views::View* focused_now) {
101 DCHECK_EQ(focused_now, widget_->GetFocusManager()->GetFocusedView());
102 UpdateFocusRing();
103 }
104
105 } // namespace chromeos
106