Retain tray bubble's rounded corners when the bubble animates out

by transferring ownership of a layer mask to the associated layer.

BUG=235563
TEST=Manual: when closing an Ash tray menu or tray notification, watch corners
     to make sure they remain rounded.
R=piman@chromium.org, msw@chromium.org, mukai@chromium.org, skuhne@chromium.org

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@239930 0039d316-1c4b-4281-b951-d872f2087c98
parent 634bc017
......@@ -57,8 +57,6 @@ Layer::Layer()
layer_brightness_(0.0f),
layer_grayscale_(0.0f),
layer_inverted_(false),
layer_mask_(NULL),
layer_mask_back_link_(NULL),
zoom_(1),
zoom_inset_(0),
delegate_(NULL),
......@@ -81,8 +79,6 @@ Layer::Layer(LayerType type)
layer_brightness_(0.0f),
layer_grayscale_(0.0f),
layer_inverted_(false),
layer_mask_(NULL),
layer_mask_back_link_(NULL),
zoom_(1),
zoom_inset_(0),
delegate_(NULL),
......@@ -101,12 +97,10 @@ Layer::~Layer() {
animator_ = NULL;
if (compositor_)
compositor_->SetRootLayer(NULL);
if (layer_mask_.get())
SetMaskLayer(scoped_ptr<Layer>());
if (parent_)
parent_->Remove(this);
if (layer_mask_)
SetMaskLayer(NULL);
if (layer_mask_back_link_)
layer_mask_back_link_->SetMaskLayer(NULL);
for (size_t i = 0; i < children_.size(); ++i)
children_[i]->parent_ = NULL;
cc_layer_->RemoveLayerAnimationEventObserver(this);
......@@ -281,28 +275,18 @@ void Layer::SetLayerInverted(bool inverted) {
SetLayerFilters();
}
void Layer::SetMaskLayer(Layer* layer_mask) {
void Layer::SetMaskLayer(scoped_ptr<Layer> layer_mask) {
// The provided mask should not have a layer mask itself.
DCHECK(!layer_mask ||
DCHECK(!layer_mask.get() ||
(!layer_mask->layer_mask_layer() &&
layer_mask->children().empty() &&
!layer_mask->layer_mask_back_link_));
DCHECK(!layer_mask_back_link_);
if (layer_mask_ == layer_mask)
layer_mask->children().empty()));
if (layer_mask_.get() == layer_mask.get())
return;
// We need to de-reference the currently linked object so that no problem
// arises if the mask layer gets deleted before this object.
if (layer_mask_)
layer_mask_->layer_mask_back_link_ = NULL;
layer_mask_ = layer_mask;
layer_mask_ = layer_mask.Pass();
cc_layer_->SetMaskLayer(
layer_mask ? layer_mask->cc_layer() : NULL);
// We need to reference the linked object so that it can properly break the
// link to us when it gets deleted.
if (layer_mask) {
layer_mask->layer_mask_back_link_ = this;
layer_mask->OnDeviceScaleFactorChanged(device_scale_factor_);
}
layer_mask_.get() ? layer_mask_->cc_layer() : NULL);
if (layer_mask_.get())
layer_mask_->OnDeviceScaleFactorChanged(device_scale_factor_);
}
void Layer::SetBackgroundZoom(float zoom, int inset) {
......
......@@ -198,11 +198,10 @@ class COMPOSITOR_EXPORT Layer
// Set a layer mask for a layer.
// Note the provided layer mask can neither have a layer mask itself nor can
// it have any children. The ownership of |layer_mask| will not be
// transferred with this call.
// it have any children.
// Furthermore: A mask layer can only be set to one layer.
void SetMaskLayer(Layer* layer_mask);
Layer* layer_mask_layer() { return layer_mask_; }
void SetMaskLayer(scoped_ptr<Layer> layer_mask);
Layer* layer_mask_layer() { return layer_mask_.get(); }
// Sets the visibility of the Layer. A Layer may be visible but not
// drawn. This happens if any ancestor of a Layer is not visible.
......@@ -449,12 +448,8 @@ class COMPOSITOR_EXPORT Layer
float layer_grayscale_;
bool layer_inverted_;
// The associated mask layer with this layer.
Layer* layer_mask_;
// The back link from the mask layer to it's associated masked layer.
// We keep this reference for the case that if the mask layer gets deleted
// while attached to the main layer before the main layer is deleted.
Layer* layer_mask_back_link_;
// The mask layer associated with this layer.
scoped_ptr<Layer> layer_mask_;
// The zoom factor to scale the layer by. Zooming is disabled when this is
// set to 1.
......
......@@ -179,7 +179,7 @@ class TrayBubbleContentMask : public ui::LayerDelegate {
explicit TrayBubbleContentMask(int corner_radius);
virtual ~TrayBubbleContentMask();
ui::Layer* layer() { return &layer_; }
void set_bounds(gfx::Rect bounds) { bounds_ = bounds; }
// Overridden from LayerDelegate.
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE;
......@@ -187,25 +187,22 @@ class TrayBubbleContentMask : public ui::LayerDelegate {
virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE;
private:
ui::Layer layer_;
gfx::Rect bounds_;
SkScalar corner_radius_;
DISALLOW_COPY_AND_ASSIGN(TrayBubbleContentMask);
};
TrayBubbleContentMask::TrayBubbleContentMask(int corner_radius)
: layer_(ui::LAYER_TEXTURED),
corner_radius_(corner_radius) {
layer_.set_delegate(this);
: corner_radius_(corner_radius) {
}
TrayBubbleContentMask::~TrayBubbleContentMask() {
layer_.set_delegate(NULL);
}
void TrayBubbleContentMask::OnPaintLayer(gfx::Canvas* canvas) {
SkPath path;
path.addRoundRect(gfx::RectToSkRect(gfx::Rect(layer()->bounds().size())),
path.addRoundRect(gfx::RectToSkRect(gfx::Rect(bounds_.size())),
corner_radius_, corner_radius_);
SkPaint paint;
paint.setAlpha(255);
......@@ -340,6 +337,10 @@ TrayBubbleView::TrayBubbleView(gfx::NativeView parent_window,
TrayBubbleView::~TrayBubbleView() {
mouse_watcher_.reset();
if (layer()->parent()->layer_mask_layer())
layer()->parent()->layer_mask_layer()->set_delegate(NULL);
// Inform host items (models) that their views are being destroyed.
if (delegate_)
delegate_->BubbleViewDestroyed();
......@@ -350,8 +351,11 @@ void TrayBubbleView::InitializeAndShowBubble() {
SetAlignment(params_.arrow_alignment);
bubble_border_->UpdateArrowOffset();
if (get_use_acceleration_when_possible())
layer()->parent()->SetMaskLayer(bubble_content_mask_->layer());
if (get_use_acceleration_when_possible()) {
scoped_ptr<ui::Layer> mask_layer(new ui::Layer(ui::LAYER_TEXTURED));
mask_layer->set_delegate(bubble_content_mask_.get());
layer()->parent()->SetMaskLayer(mask_layer.Pass());
}
GetWidget()->Show();
UpdateBubble();
......@@ -359,8 +363,11 @@ void TrayBubbleView::InitializeAndShowBubble() {
void TrayBubbleView::UpdateBubble() {
SizeToContents();
if (get_use_acceleration_when_possible())
bubble_content_mask_->layer()->SetBounds(layer()->bounds());
if (get_use_acceleration_when_possible()) {
bubble_content_mask_->set_bounds(layer()->bounds());
if (layer()->parent()->layer_mask_layer())
layer()->parent()->layer_mask_layer()->SetBounds(layer()->bounds());
}
GetWidget()->GetRootView()->SchedulePaint();
}
......
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