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 @@
#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 "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"
namespace chromeos {
......@@ -37,23 +43,59 @@ void FocusRingController::SetVisible(bool visible) {
}
void FocusRingController::UpdateFocusRing() {
views::View* focused_view = NULL;
views::View* view = NULL;
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
// widget content area (such as RenderWidgetHostWidgetAura).
if (!focused_view ||
focused_view->ConvertRectToWidget(focused_view->bounds()) ==
if (!view ||
view->ConvertRectToWidget(view->bounds()) ==
widget_->GetContentsView()->bounds()) {
focus_ring_layer_.reset();
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_)
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) {
......
......@@ -7,6 +7,7 @@
#include "base/basictypes.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/widget_focus_manager.h"
#include "ui/views/widget/widget_observer.h"
......@@ -18,12 +19,11 @@ class Widget;
namespace chromeos {
class FocusRingLayer;
// FocusRingController manages the focus ring around the focused view. It
// follows widget focus change and update the focus ring layer when the focused
// view of the widget changes.
class FocusRingController : public views::WidgetObserver,
class FocusRingController : public FocusRingLayerDelegate,
public views::WidgetObserver,
public views::WidgetFocusChangeListener,
public views::FocusChangeListener {
public:
......@@ -34,6 +34,9 @@ class FocusRingController : public views::WidgetObserver,
void SetVisible(bool visible);
private:
// FocusRingLayerDelegate.
virtual void OnDeviceScaleFactorChanged() OVERRIDE;
// Sets the focused |widget|.
void SetWidget(views::Widget* widget);
......
......@@ -4,16 +4,10 @@
#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 "ui/aura/window.h"
#include "ui/compositor/layer.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 {
......@@ -25,18 +19,17 @@ const SkColor kShadowColor = SkColorSetRGB(77, 144, 254);
} // namespace
FocusRingLayer::FocusRingLayer()
: window_(NULL),
FocusRingLayerDelegate::~FocusRingLayerDelegate() {}
FocusRingLayer::FocusRingLayer(FocusRingLayerDelegate* delegate)
: delegate_(delegate),
root_window_(NULL) {
}
FocusRingLayer::~FocusRingLayer() {}
void FocusRingLayer::Update() {
if (!window_)
return;
aura::Window* root_window = window_->GetRootWindow();
void FocusRingLayer::Set(aura::Window* root_window, const gfx::Rect& bounds) {
focus_ring_ = bounds;
if (!layer_ || root_window != root_window_) {
root_window_ = root_window;
ui::Layer* root_layer = root_window->layer();
......@@ -51,64 +44,18 @@ void FocusRingLayer::Update() {
// since we created this layer.
layer_->parent()->StackAtTop(layer_.get());
// Translate native window coordinates to root window coordinates.
gfx::Point origin = focus_ring_.origin();
aura::Window::ConvertPointToTarget(window_, root_window_, &origin);
gfx::Rect layer_bounds = focus_ring_;
layer_bounds.set_origin(origin);
// Update the layer bounds.
gfx::Rect layer_bounds = bounds;
int inset = -(kShadowRadius + 2);
layer_bounds.Inset(inset, inset, inset, inset);
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) {
if (focus_ring_.IsEmpty())
if (!root_window_ || focus_ring_.IsEmpty())
return;
// Convert the focus ring from native-window-relative coordinates to
// 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);
gfx::Rect bounds = focus_ring_ - layer_->bounds().OffsetFromOrigin();
SkPaint paint;
paint.setColor(kShadowColor);
paint.setFlags(SkPaint::kAntiAlias_Flag);
......@@ -129,7 +76,8 @@ void FocusRingLayer::OnDelegatedFrameDamage(
}
void FocusRingLayer::OnDeviceScaleFactorChanged(float device_scale_factor) {
Update();
if (delegate_)
delegate_->OnDeviceScaleFactorChanged();
}
base::Closure FocusRingLayer::PrepareForLayerBoundsChange() {
......
......@@ -18,23 +18,26 @@ namespace ui {
class Layer;
}
namespace views {
class View;
}
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 {
public:
FocusRingLayer();
explicit FocusRingLayer(FocusRingLayerDelegate* delegate);
virtual ~FocusRingLayer();
// Create the layer and update its bounds and position in the hierarchy.
void Update();
// Updates the focus ring layer for the view or clears it if |view| is NULL.
void SetForView(views::View* view);
// Move the focus ring layer to the given bounds in the coordinates of
// the given root window.
void Set(aura::Window* root_window, const gfx::Rect& bounds);
private:
// ui::LayerDelegate overrides:
......@@ -44,13 +47,14 @@ class FocusRingLayer : public ui::LayerDelegate {
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE;
// The window containing focus.
aura::Window* window_;
// The object that owns this layer.
FocusRingLayerDelegate* delegate_;
// The current root window containing the focused object.
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_;
// 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