Home | History | Annotate | Download | only in ui
      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 
     13 FocusRingController::FocusRingController()
     14     : visible_(false),
     15       widget_(NULL) {
     16 }
     17 
     18 FocusRingController::~FocusRingController() {
     19   SetVisible(false);
     20 }
     21 
     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 
     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 
     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 
     77 void FocusRingController::OnWidgetDestroying(views::Widget* widget) {
     78   DCHECK_EQ(widget_, widget);
     79   SetWidget(NULL);
     80 }
     81 
     82 void FocusRingController::OnWidgetBoundsChanged(views::Widget* widget,
     83                                                 const gfx::Rect& new_bounds) {
     84   DCHECK_EQ(widget_, widget);
     85   UpdateFocusRing();
     86 }
     87 
     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 
     95 void FocusRingController::OnWillChangeFocus(views::View* focused_before,
     96                                             views::View* focused_now) {
     97 }
     98 
     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