| // Copyright 2021 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/javascript_dialogs/views/layer_dimmer.h" |
| |
| #include <memory> |
| |
| #include "base/time/time.h" |
| #include "ui/aura/window.h" |
| #include "ui/compositor/layer.h" |
| #include "ui/compositor/layer_animator.h" |
| #include "ui/compositor/scoped_layer_animation_settings.h" |
| |
| namespace javascript_dialogs { |
| |
| LayerDimmer::LayerDimmer(aura::Window* parent, aura::Window* dialog) |
| : parent_(parent), dialog_(dialog) { |
| auto* parentLayer = parent_->layer(); |
| |
| layer_ = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR); |
| layer_->SetName(parent_->GetName() + "_LayerDimmer"); |
| layer_->SetAnimator(new ui::LayerAnimator(base::Milliseconds(200))); |
| layer_->SetColor(SkColorSetA(SK_ColorBLACK, 127)); |
| { |
| // Don't animate these changes right now. |
| ui::ScopedLayerAnimationSettings settings(layer_->GetAnimator()); |
| settings.SetTransitionDuration(base::Milliseconds(0)); |
| layer_->SetOpacity(0.f); |
| layer_->SetBounds(parent_->bounds()); |
| } |
| |
| parentLayer->Add(layer_.get()); |
| StackLayerUnderDialog(); |
| |
| parent_->AddObserver(this); |
| dialog_->AddObserver(this); |
| } |
| |
| LayerDimmer::~LayerDimmer() { |
| if (parent_) { |
| parent_->RemoveObserver(this); |
| } |
| if (dialog_) { |
| dialog_->RemoveObserver(this); |
| } |
| } |
| |
| void LayerDimmer::Show() { |
| layer_->SetOpacity(1.0f); |
| layer_->ScheduleDraw(); |
| } |
| |
| void LayerDimmer::Hide() { |
| layer_->SetOpacity(0.f); |
| layer_->ScheduleDraw(); |
| } |
| |
| void LayerDimmer::StackLayerUnderDialog() { |
| auto* parentLayer = parent_->layer(); |
| parentLayer->StackBelow(layer_.get(), dialog_->layer()); |
| layer_->ScheduleDraw(); |
| } |
| |
| void LayerDimmer::OnWindowBoundsChanged(aura::Window* window, |
| const gfx::Rect& old_bounds, |
| const gfx::Rect& new_bounds, |
| ui::PropertyChangeReason reason) { |
| if (window == parent_) { |
| // Don't animate this bounds change. |
| ui::ScopedLayerAnimationSettings settings(layer_->GetAnimator()); |
| settings.SetTransitionDuration(base::Milliseconds(0)); |
| layer_->SetBounds(gfx::Rect(new_bounds.size())); |
| } |
| } |
| |
| void LayerDimmer::OnWindowDestroying(aura::Window* window) { |
| if (window == parent_) { |
| parent_->RemoveObserver(this); |
| parent_ = nullptr; |
| } else { |
| DCHECK_EQ(dialog_, window); |
| dialog_->RemoveObserver(this); |
| dialog_ = nullptr; |
| } |
| } |
| |
| void LayerDimmer::OnWindowStackingChanged(aura::Window* window) { |
| if (window == dialog_) { |
| StackLayerUnderDialog(); |
| } |
| } |
| |
| } // namespace javascript_dialogs |