Commit 9e3a723c authored by dmazzoni's avatar dmazzoni Committed by Commit bot

Move view logic from FocusRingLayer to FocusRingController.

BUG=314889

Review URL: https://codereview.chromium.org/537893003

Cr-Commit-Position: refs/heads/master@{#294445}
parent db7b0295
...@@ -4,8 +4,14 @@ ...@@ -4,8 +4,14 @@
#include "chrome/browser/chromeos/ui/focus_ring_controller.h" #include "chrome/browser/chromeos/ui/focus_ring_controller.h"
#include "ash/system/tray/actionable_view.h"
#include "ash/system/tray/tray_background_view.h"
#include "ash/system/tray/tray_popup_header_button.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
#include "chrome/browser/chromeos/ui/focus_ring_layer.h" #include "chrome/browser/chromeos/ui/focus_ring_layer.h"
#include "ui/aura/window.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
namespace chromeos { namespace chromeos {
...@@ -37,23 +43,59 @@ void FocusRingController::SetVisible(bool visible) { ...@@ -37,23 +43,59 @@ void FocusRingController::SetVisible(bool visible) {
} }
void FocusRingController::UpdateFocusRing() { void FocusRingController::UpdateFocusRing() {
views::View* focused_view = NULL; views::View* view = NULL;
if (widget_ && widget_->GetFocusManager()) if (widget_ && widget_->GetFocusManager())
focused_view = widget_->GetFocusManager()->GetFocusedView(); view = widget_->GetFocusManager()->GetFocusedView();
// No focus ring if no focused view or the focused view covers the whole // No focus ring if no focused view or the focused view covers the whole
// widget content area (such as RenderWidgetHostWidgetAura). // widget content area (such as RenderWidgetHostWidgetAura).
if (!focused_view || if (!view ||
focused_view->ConvertRectToWidget(focused_view->bounds()) == view->ConvertRectToWidget(view->bounds()) ==
widget_->GetContentsView()->bounds()) { widget_->GetContentsView()->bounds()) {
focus_ring_layer_.reset(); focus_ring_layer_.reset();
return; return;
} }
gfx::Rect view_bounds = view->GetContentsBounds();
// Workarounds that attempts to pick a better bounds.
if (view->GetClassName() == views::LabelButton::kViewClassName) {
view_bounds = view->GetLocalBounds();
view_bounds.Inset(2, 2, 2, 2);
}
// Workarounds for system tray items that have customized focus borders. The
// insets here must be consistent with the ones used by those classes.
if (view->GetClassName() == ash::ActionableView::kViewClassName) {
view_bounds = view->GetLocalBounds();
view_bounds.Inset(1, 1, 3, 3);
} else if (view->GetClassName() == ash::TrayBackgroundView::kViewClassName) {
view_bounds.Inset(1, 1, 3, 3);
} else if (view->GetClassName() ==
ash::TrayPopupHeaderButton::kViewClassName) {
view_bounds = view->GetLocalBounds();
view_bounds.Inset(2, 1, 2, 2);
}
// Convert view bounds to widget/window coordinates.
view_bounds = view->ConvertRectToWidget(view_bounds);
// Translate window coordinates to root window coordinates.
DCHECK(view->GetWidget());
aura::Window* window = view->GetWidget()->GetNativeWindow();
aura::Window* root_window = window->GetRootWindow();
gfx::Point origin = view_bounds.origin();
aura::Window::ConvertPointToTarget(window, root_window, &origin);
view_bounds.set_origin(origin);
// Update the focus ring layer.
if (!focus_ring_layer_) if (!focus_ring_layer_)
focus_ring_layer_.reset(new FocusRingLayer); focus_ring_layer_.reset(new FocusRingLayer(this));
focus_ring_layer_->Set(root_window, view_bounds);
}
focus_ring_layer_->SetForView(focused_view); void FocusRingController::OnDeviceScaleFactorChanged() {
UpdateFocusRing();
} }
void FocusRingController::SetWidget(views::Widget* widget) { void FocusRingController::SetWidget(views::Widget* widget) {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "chrome/browser/chromeos/ui/focus_ring_layer.h"
#include "ui/views/focus/focus_manager.h" #include "ui/views/focus/focus_manager.h"
#include "ui/views/focus/widget_focus_manager.h" #include "ui/views/focus/widget_focus_manager.h"
#include "ui/views/widget/widget_observer.h" #include "ui/views/widget/widget_observer.h"
...@@ -18,12 +19,11 @@ class Widget; ...@@ -18,12 +19,11 @@ class Widget;
namespace chromeos { namespace chromeos {
class FocusRingLayer;
// FocusRingController manages the focus ring around the focused view. It // FocusRingController manages the focus ring around the focused view. It
// follows widget focus change and update the focus ring layer when the focused // follows widget focus change and update the focus ring layer when the focused
// view of the widget changes. // view of the widget changes.
class FocusRingController : public views::WidgetObserver, class FocusRingController : public FocusRingLayerDelegate,
public views::WidgetObserver,
public views::WidgetFocusChangeListener, public views::WidgetFocusChangeListener,
public views::FocusChangeListener { public views::FocusChangeListener {
public: public:
...@@ -34,6 +34,9 @@ class FocusRingController : public views::WidgetObserver, ...@@ -34,6 +34,9 @@ class FocusRingController : public views::WidgetObserver,
void SetVisible(bool visible); void SetVisible(bool visible);
private: private:
// FocusRingLayerDelegate.
virtual void OnDeviceScaleFactorChanged() OVERRIDE;
// Sets the focused |widget|. // Sets the focused |widget|.
void SetWidget(views::Widget* widget); void SetWidget(views::Widget* widget);
......
...@@ -4,16 +4,10 @@ ...@@ -4,16 +4,10 @@
#include "chrome/browser/chromeos/ui/focus_ring_layer.h" #include "chrome/browser/chromeos/ui/focus_ring_layer.h"
#include "ash/system/tray/actionable_view.h"
#include "ash/system/tray/tray_background_view.h"
#include "ash/system/tray/tray_popup_header_button.h"
#include "base/bind.h" #include "base/bind.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/compositor/layer.h" #include "ui/compositor/layer.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
namespace chromeos { namespace chromeos {
...@@ -25,18 +19,17 @@ const SkColor kShadowColor = SkColorSetRGB(77, 144, 254); ...@@ -25,18 +19,17 @@ const SkColor kShadowColor = SkColorSetRGB(77, 144, 254);
} // namespace } // namespace
FocusRingLayer::FocusRingLayer() FocusRingLayerDelegate::~FocusRingLayerDelegate() {}
: window_(NULL),
FocusRingLayer::FocusRingLayer(FocusRingLayerDelegate* delegate)
: delegate_(delegate),
root_window_(NULL) { root_window_(NULL) {
} }
FocusRingLayer::~FocusRingLayer() {} FocusRingLayer::~FocusRingLayer() {}
void FocusRingLayer::Update() { void FocusRingLayer::Set(aura::Window* root_window, const gfx::Rect& bounds) {
if (!window_) focus_ring_ = bounds;
return;
aura::Window* root_window = window_->GetRootWindow();
if (!layer_ || root_window != root_window_) { if (!layer_ || root_window != root_window_) {
root_window_ = root_window; root_window_ = root_window;
ui::Layer* root_layer = root_window->layer(); ui::Layer* root_layer = root_window->layer();
...@@ -51,64 +44,18 @@ void FocusRingLayer::Update() { ...@@ -51,64 +44,18 @@ void FocusRingLayer::Update() {
// since we created this layer. // since we created this layer.
layer_->parent()->StackAtTop(layer_.get()); layer_->parent()->StackAtTop(layer_.get());
// Translate native window coordinates to root window coordinates. // Update the layer bounds.
gfx::Point origin = focus_ring_.origin(); gfx::Rect layer_bounds = bounds;
aura::Window::ConvertPointToTarget(window_, root_window_, &origin);
gfx::Rect layer_bounds = focus_ring_;
layer_bounds.set_origin(origin);
int inset = -(kShadowRadius + 2); int inset = -(kShadowRadius + 2);
layer_bounds.Inset(inset, inset, inset, inset); layer_bounds.Inset(inset, inset, inset, inset);
layer_->SetBounds(layer_bounds); layer_->SetBounds(layer_bounds);
} }
void FocusRingLayer::SetForView(views::View* view) {
if (!view) {
if (layer_ && !focus_ring_.IsEmpty())
layer_->SchedulePaint(focus_ring_);
focus_ring_ = gfx::Rect();
return;
}
DCHECK(view->GetWidget());
window_ = view->GetWidget()->GetNativeWindow();
gfx::Rect view_bounds = view->GetContentsBounds();
// Workarounds that attempts to pick a better bounds.
if (view->GetClassName() == views::LabelButton::kViewClassName) {
view_bounds = view->GetLocalBounds();
view_bounds.Inset(2, 2, 2, 2);
}
// Workarounds for system tray items that have customized focus borders. The
// insets here must be consistent with the ones used by those classes.
if (view->GetClassName() == ash::ActionableView::kViewClassName) {
view_bounds = view->GetLocalBounds();
view_bounds.Inset(1, 1, 3, 3);
} else if (view->GetClassName() == ash::TrayBackgroundView::kViewClassName) {
view_bounds.Inset(1, 1, 3, 3);
} else if (view->GetClassName() ==
ash::TrayPopupHeaderButton::kViewClassName) {
view_bounds = view->GetLocalBounds();
view_bounds.Inset(2, 1, 2, 2);
}
focus_ring_ = view->ConvertRectToWidget(view_bounds);
Update();
}
void FocusRingLayer::OnPaintLayer(gfx::Canvas* canvas) { void FocusRingLayer::OnPaintLayer(gfx::Canvas* canvas) {
if (focus_ring_.IsEmpty()) if (!root_window_ || focus_ring_.IsEmpty())
return; return;
// Convert the focus ring from native-window-relative coordinates to gfx::Rect bounds = focus_ring_ - layer_->bounds().OffsetFromOrigin();
// layer-relative coordinates.
gfx::Point origin = focus_ring_.origin();
aura::Window::ConvertPointToTarget(window_, root_window_, &origin);
origin -= layer_->bounds().OffsetFromOrigin();
gfx::Rect bounds = focus_ring_;
bounds.set_origin(origin);
SkPaint paint; SkPaint paint;
paint.setColor(kShadowColor); paint.setColor(kShadowColor);
paint.setFlags(SkPaint::kAntiAlias_Flag); paint.setFlags(SkPaint::kAntiAlias_Flag);
...@@ -129,7 +76,8 @@ void FocusRingLayer::OnDelegatedFrameDamage( ...@@ -129,7 +76,8 @@ void FocusRingLayer::OnDelegatedFrameDamage(
} }
void FocusRingLayer::OnDeviceScaleFactorChanged(float device_scale_factor) { void FocusRingLayer::OnDeviceScaleFactorChanged(float device_scale_factor) {
Update(); if (delegate_)
delegate_->OnDeviceScaleFactorChanged();
} }
base::Closure FocusRingLayer::PrepareForLayerBoundsChange() { base::Closure FocusRingLayer::PrepareForLayerBoundsChange() {
......
...@@ -18,23 +18,26 @@ namespace ui { ...@@ -18,23 +18,26 @@ namespace ui {
class Layer; class Layer;
} }
namespace views {
class View;
}
namespace chromeos { namespace chromeos {
// FocusRingLayer draws a focus ring for a given view. // A delegate interface implemented by the object that owns a FocusRingLayer.
class FocusRingLayerDelegate {
public:
virtual void OnDeviceScaleFactorChanged() = 0;
protected:
virtual ~FocusRingLayerDelegate();
};
// FocusRingLayer draws a focus ring at a given global rectangle.
class FocusRingLayer : public ui::LayerDelegate { class FocusRingLayer : public ui::LayerDelegate {
public: public:
FocusRingLayer(); explicit FocusRingLayer(FocusRingLayerDelegate* delegate);
virtual ~FocusRingLayer(); virtual ~FocusRingLayer();
// Create the layer and update its bounds and position in the hierarchy. // Move the focus ring layer to the given bounds in the coordinates of
void Update(); // the given root window.
void Set(aura::Window* root_window, const gfx::Rect& bounds);
// Updates the focus ring layer for the view or clears it if |view| is NULL.
void SetForView(views::View* view);
private: private:
// ui::LayerDelegate overrides: // ui::LayerDelegate overrides:
...@@ -44,13 +47,14 @@ class FocusRingLayer : public ui::LayerDelegate { ...@@ -44,13 +47,14 @@ class FocusRingLayer : public ui::LayerDelegate {
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE; virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE; virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE;
// The window containing focus. // The object that owns this layer.
aura::Window* window_; FocusRingLayerDelegate* delegate_;
// The current root window containing the focused object. // The current root window containing the focused object.
aura::Window* root_window_; aura::Window* root_window_;
// The bounding rectangle of the focused object, in |window_| coordinates. // The bounding rectangle of the focused object, in |root_window_|
// coordinates.
gfx::Rect focus_ring_; gfx::Rect focus_ring_;
// The current layer. // The current layer.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment