| Index: ash/common/wm/overview/window_selector_item.cc
|
| diff --git a/ash/common/wm/overview/window_selector_item.cc b/ash/common/wm/overview/window_selector_item.cc
|
| index 91d08e97c7bf56069619e81a3fe30c6f596d2c6e..acbdfb1b75402001bc4ef32ae3fb70b80a2f4557 100644
|
| --- a/ash/common/wm/overview/window_selector_item.cc
|
| +++ b/ash/common/wm/overview/window_selector_item.cc
|
| @@ -10,6 +10,7 @@
|
| #include "ash/common/material_design/material_design_controller.h"
|
| #include "ash/common/metrics/user_metrics_action.h"
|
| #include "ash/common/shell_window_ids.h"
|
| +#include "ash/common/wm/overview/cleanup_animation_observer.h"
|
| #include "ash/common/wm/overview/overview_animation_type.h"
|
| #include "ash/common/wm/overview/scoped_overview_animation_settings.h"
|
| #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h"
|
| @@ -30,7 +31,10 @@
|
| #include "grit/ash_strings.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
| #include "ui/base/resource/resource_bundle.h"
|
| +#include "ui/compositor/layer_animation_sequence.h"
|
| +#include "ui/compositor/scoped_animation_duration_scale_mode.h"
|
| #include "ui/gfx/canvas.h"
|
| +#include "ui/gfx/color_utils.h"
|
| #include "ui/gfx/geometry/safe_integer_conversions.h"
|
| #include "ui/gfx/geometry/vector2d.h"
|
| #include "ui/gfx/paint_vector_icon.h"
|
| @@ -39,7 +43,6 @@
|
| #include "ui/strings/grit/ui_strings.h"
|
| #include "ui/views/background.h"
|
| #include "ui/views/border.h"
|
| -#include "ui/views/controls/button/image_button.h"
|
| #include "ui/views/layout/box_layout.h"
|
| #include "ui/views/window/non_client_view.h"
|
| #include "ui/wm/core/shadow.h"
|
| @@ -66,10 +69,12 @@ static const SkColor kLabelColor = SK_ColorWHITE;
|
| // TODO(tdanderson): Move this to a central location.
|
| static const SkColor kCloseButtonColor = SK_ColorWHITE;
|
|
|
| -// Label background color used with Material Design.
|
| -// TODO(varkha): Make background color conform to window header.
|
| +// Label background color used with Material Design once in overview mode.
|
| static const SkColor kLabelBackgroundColor = SkColorSetARGB(25, 255, 255, 255);
|
|
|
| +// Label background color used with Material Design when exiting overview mode.
|
| +static const SkColor kLabelExitColor = SkColorSetARGB(255, 90, 90, 90);
|
| +
|
| // Corner radius for the selection tiles used with Material Design.
|
| static int kLabelBackgroundRadius = 2;
|
|
|
| @@ -97,9 +102,20 @@ static const float kDimmedItemOpacity = 0.5f;
|
| // Opacity for fading out during closing a window.
|
| static const float kClosingItemOpacity = 0.8f;
|
|
|
| +// Opacity for the item header.
|
| +static const float kHeaderOpacity =
|
| + (SkColorGetA(kLabelBackgroundColor) / 255.f);
|
| +
|
| +// Duration it takes for the header to shift from opaque header color to
|
| +// |kLabelBackgroundColor|.
|
| +static const int kSelectorColorSlideMilliseconds = 240;
|
| +
|
| // Duration of background opacity transition for the selected label.
|
| static const int kSelectorFadeInMilliseconds = 350;
|
|
|
| +// Duration of background opacity transition when exiting overview mode.
|
| +static const int kExitFadeInMilliseconds = 30;
|
| +
|
| // Before closing a window animate both the window and the caption to shrink by
|
| // this fraction of size.
|
| static const float kPreCloseScale = 0.02f;
|
| @@ -120,19 +136,10 @@ void SetupFadeInAfterLayout(views::Widget* widget) {
|
| window->SetOpacity(1.0f);
|
| }
|
|
|
| -// An image button with a close window icon.
|
| -class OverviewCloseButton : public views::ImageButton {
|
| - public:
|
| - explicit OverviewCloseButton(views::ButtonListener* listener);
|
| - ~OverviewCloseButton() override;
|
| -
|
| - private:
|
| - gfx::ImageSkia icon_image_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(OverviewCloseButton);
|
| -};
|
| +} // namespace
|
|
|
| -OverviewCloseButton::OverviewCloseButton(views::ButtonListener* listener)
|
| +WindowSelectorItem::OverviewCloseButton::OverviewCloseButton(
|
| + views::ButtonListener* listener)
|
| : views::ImageButton(listener) {
|
| if (ash::MaterialDesignController::IsOverviewMaterial()) {
|
| icon_image_ = gfx::CreateVectorIcon(gfx::VectorIconId::WINDOW_CONTROL_CLOSE,
|
| @@ -154,45 +161,176 @@ OverviewCloseButton::OverviewCloseButton(views::ButtonListener* listener)
|
| }
|
| }
|
|
|
| -OverviewCloseButton::~OverviewCloseButton() {}
|
| +WindowSelectorItem::OverviewCloseButton::~OverviewCloseButton() {}
|
|
|
| -// A View having rounded corners and a specified background color which is
|
| +// A View having rounded top corners and a specified background color which is
|
| // only painted within the bounds defined by the rounded corners.
|
| -// TODO(varkha): This duplicates code from RoundedImageView. Refactor these
|
| -// classes and move into ui/views.
|
| -class RoundedContainerView : public views::View {
|
| +// This class coordinates the transitions of the overview mode header when
|
| +// entering the overview mode. Those animations are:
|
| +// - Opacity animation. The header is initially same color as the original
|
| +// window's header. It starts as transparent and is faded in. When the full
|
| +// opacity is reached the original header is hidden (which is nearly
|
| +// imperceptable because this view obscures the original header) and a color
|
| +// animation starts.
|
| +// - Color animation is used to change the color from the opaque color of the
|
| +// original window's header to semi-transparent color of the overview mode
|
| +// header (on entry to overview). It is also used on exit from overview to
|
| +// quickly change the color to a close opaque color in parallel with an
|
| +// opacity transition to mask the original header reappearing.
|
| +class WindowSelectorItem::RoundedContainerView
|
| + : public views::View,
|
| + public gfx::AnimationDelegate,
|
| + public ui::LayerAnimationObserver {
|
| public:
|
| - RoundedContainerView(int corner_radius, SkColor background)
|
| - : corner_radius_(corner_radius), background_(background) {}
|
| + RoundedContainerView(WindowSelectorItem* item,
|
| + WmWindow* item_window,
|
| + int corner_radius,
|
| + SkColor background)
|
| + : item_(item),
|
| + item_window_(item_window),
|
| + corner_radius_(corner_radius),
|
| + initial_color_(background),
|
| + target_color_(background),
|
| + current_value_(0),
|
| + layer_(nullptr),
|
| + animation_(new gfx::SlideAnimation(this)) {}
|
| +
|
| + ~RoundedContainerView() override { StopObservingLayerAnimations(); }
|
| +
|
| + void OnItemRestored() { item_ = nullptr; }
|
| +
|
| + // Starts observing layer animations so that actions can be taken when
|
| + // particular animations (opacity) complete. It should only be called once
|
| + // when the initial fade in animation is started.
|
| + void ObserveLayerAnimations(ui::Layer* layer) {
|
| + DCHECK(!layer_);
|
| + layer_ = layer;
|
| + layer_->GetAnimator()->AddObserver(this);
|
| + }
|
| +
|
| + // Stops observing layer animations
|
| + void StopObservingLayerAnimations() {
|
| + if (!layer_)
|
| + return;
|
| + layer_->GetAnimator()->RemoveObserver(this);
|
| + layer_ = nullptr;
|
| + }
|
|
|
| - ~RoundedContainerView() override {}
|
| + void set_color(SkColor target_color) { target_color_ = target_color; }
|
| +
|
| + // Starts a color animation using |tween_type|. The animation will change the
|
| + // color from |initial_color_| to |target_color_| over |duration| specified
|
| + // in milliseconds.
|
| + // This animation can start once the implicit layer fade-in opacity animation
|
| + // is completed. It is used to transition color from the opaque original
|
| + // window header color to |kLabelBackgroundColor| on entry into overview mode
|
| + // and from |kLabelBackgroundColor| back to the original window header color
|
| + // on exit from the overview mode.
|
| + void AnimateColor(gfx::Tween::Type tween_type, int duration) {
|
| + DCHECK(!layer_); // layer animations should be completed.
|
| + animation_->SetSlideDuration(duration);
|
| + animation_->SetTweenType(tween_type);
|
| + animation_->Reset(0);
|
| + animation_->Show();
|
| +
|
| + // Tests complete animations immediately. Emulate by invoking the callback.
|
| + if (ui::ScopedAnimationDurationScaleMode::duration_scale_mode() ==
|
| + ui::ScopedAnimationDurationScaleMode::ZERO_DURATION) {
|
| + AnimationEnded(animation_.get());
|
| + }
|
| + }
|
|
|
| + // Changes the view opacity by animating its background color. The animation
|
| + // will change the alpha value in |target_color_| from its current value to
|
| + // |opacity| * 255 but preserve the RGB values.
|
| + void AnimateBackgroundOpacity(float opacity) {
|
| + animation_->SetSlideDuration(kSelectorFadeInMilliseconds);
|
| + animation_->SetTweenType(gfx::Tween::EASE_OUT);
|
| + animation_->Reset(0);
|
| + animation_->Show();
|
| + target_color_ = SkColorSetA(target_color_, opacity * 255);
|
| + }
|
| +
|
| + // views::View:
|
| void OnPaint(gfx::Canvas* canvas) override {
|
| views::View::OnPaint(canvas);
|
| -
|
| SkScalar radius = SkIntToScalar(corner_radius_);
|
| - const SkScalar kRadius[8] = {radius, radius, radius, radius,
|
| - radius, radius, radius, radius};
|
| + const SkScalar kRadius[8] = {radius, radius, radius, radius, 0, 0, 0, 0};
|
| SkPath path;
|
| gfx::Rect bounds(size());
|
| - bounds.set_height(bounds.height() + radius);
|
| path.addRoundRect(gfx::RectToSkRect(bounds), kRadius);
|
|
|
| SkPaint paint;
|
| paint.setAntiAlias(true);
|
| canvas->ClipPath(path, true);
|
| - canvas->DrawColor(background_);
|
| +
|
| + SkColor target_color = initial_color_;
|
| + if (target_color_ != target_color) {
|
| + target_color = color_utils::AlphaBlend(target_color_, initial_color_,
|
| + current_value_);
|
| + }
|
| + canvas->DrawColor(target_color);
|
| }
|
|
|
| private:
|
| + // gfx::AnimationDelegate:
|
| + void AnimationEnded(const gfx::Animation* animation) override {
|
| + initial_color_ = target_color_;
|
| + // Tabbed browser windows show the overview mode header behind the window
|
| + // during the initial animation. Once the initial fade-in completes and the
|
| + // overview header is fully exposed update stacking to keep the label above
|
| + // the item which prevents input events from reaching the window.
|
| + WmWindow* label_window = WmLookup::Get()->GetWindowForWidget(GetWidget());
|
| + if (label_window && item_window_)
|
| + label_window->GetParent()->StackChildAbove(label_window, item_window_);
|
| + item_window_ = nullptr;
|
| + }
|
| +
|
| + void AnimationProgressed(const gfx::Animation* animation) override {
|
| + current_value_ = animation_->CurrentValueBetween(0, 255);
|
| + SchedulePaint();
|
| + }
|
| +
|
| + void AnimationCanceled(const gfx::Animation* animation) override {
|
| + item_window_ = nullptr;
|
| + initial_color_ = target_color_;
|
| + current_value_ = 255;
|
| + SchedulePaint();
|
| + }
|
| +
|
| + // ui::LayerAnimationObserver:
|
| + void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
|
| + if (0 != (sequence->properties() &
|
| + ui::LayerAnimationElement::AnimatableProperty::OPACITY)) {
|
| + if (item_)
|
| + item_->HideHeaderAndSetShape(0);
|
| + StopObservingLayerAnimations();
|
| + AnimateColor(gfx::Tween::EASE_IN, kSelectorColorSlideMilliseconds);
|
| + }
|
| + }
|
| +
|
| + void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {
|
| + if (0 != (sequence->properties() &
|
| + ui::LayerAnimationElement::AnimatableProperty::OPACITY)) {
|
| + StopObservingLayerAnimations();
|
| + }
|
| + }
|
| +
|
| + void OnLayerAnimationScheduled(
|
| + ui::LayerAnimationSequence* sequence) override {}
|
| +
|
| + WindowSelectorItem* item_;
|
| + WmWindow* item_window_;
|
| int corner_radius_;
|
| - SkColor background_;
|
| + SkColor initial_color_;
|
| + SkColor target_color_;
|
| + int current_value_;
|
| + ui::Layer* layer_;
|
| + std::unique_ptr<gfx::SlideAnimation> animation_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(RoundedContainerView);
|
| };
|
|
|
| -} // namespace
|
| -
|
| bool WindowSelectorItem::use_mask_ = false;
|
| bool WindowSelectorItem::use_shape_ = false;
|
|
|
| @@ -223,8 +361,10 @@ gfx::Rect WindowSelectorItem::OverviewLabelButton::GetChildAreaBounds() {
|
| class WindowSelectorItem::CaptionContainerView : public views::View {
|
| public:
|
| CaptionContainerView(WindowSelectorItem::OverviewLabelButton* label,
|
| - views::ImageButton* close_button)
|
| - : label_(label), close_button_(close_button) {
|
| + views::ImageButton* close_button,
|
| + WindowSelectorItem::RoundedContainerView* background)
|
| + : label_(label), close_button_(close_button), background_(background) {
|
| + AddChildView(background_);
|
| AddChildView(label_);
|
| AddChildView(close_button_);
|
| }
|
| @@ -239,6 +379,10 @@ class WindowSelectorItem::CaptionContainerView : public views::View {
|
| // events from reaching the transformed window in overview.
|
| gfx::Rect bounds(GetLocalBounds());
|
| bounds.Inset(kWindowSelectorMargin, kWindowSelectorMargin);
|
| + gfx::Rect background_bounds(bounds);
|
| + background_bounds.set_height(close_button_->GetPreferredSize().height());
|
| + background_->SetBoundsRect(background_bounds);
|
| +
|
| const int visible_height = close_button_->GetPreferredSize().height();
|
| gfx::Insets label_padding(0, 0, bounds.height() - visible_height,
|
| visible_height);
|
| @@ -250,11 +394,10 @@ class WindowSelectorItem::CaptionContainerView : public views::View {
|
| close_button_->SetBoundsRect(bounds);
|
| }
|
|
|
| - void OnBoundsChanged(const gfx::Rect& previous_bounds) override { Layout(); }
|
| -
|
| private:
|
| WindowSelectorItem::OverviewLabelButton* label_;
|
| views::ImageButton* close_button_;
|
| + WindowSelectorItem::RoundedContainerView* background_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(CaptionContainerView);
|
| };
|
| @@ -265,10 +408,12 @@ WindowSelectorItem::WindowSelectorItem(WmWindow* window,
|
| root_window_(window->GetRootWindow()),
|
| transform_window_(window),
|
| in_bounds_update_(false),
|
| + selected_(false),
|
| caption_container_view_(nullptr),
|
| window_label_button_view_(nullptr),
|
| close_button_(new OverviewCloseButton(this)),
|
| - window_selector_(window_selector) {
|
| + window_selector_(window_selector),
|
| + background_view_(nullptr) {
|
| CreateWindowLabel(window->GetTitle());
|
| if (!ash::MaterialDesignController::IsOverviewMaterial()) {
|
| views::Widget::InitParams params;
|
| @@ -308,7 +453,34 @@ WmWindow* WindowSelectorItem::GetWindow() {
|
| }
|
|
|
| void WindowSelectorItem::RestoreWindow() {
|
| + window_label_button_view_->ResetListener();
|
| + close_button_->ResetListener();
|
| transform_window_.RestoreWindow();
|
| + if (background_view_) {
|
| + background_view_->OnItemRestored();
|
| + background_view_ = nullptr;
|
| + }
|
| + UpdateHeaderLayout(
|
| + HeaderFadeInMode::EXIT,
|
| + OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS);
|
| +}
|
| +
|
| +void WindowSelectorItem::Shutdown() {
|
| + if (transform_window_.GetTopInset()) {
|
| + // Activating a window (even when it is the window that was active before
|
| + // overview) results in stacking it at the top. Maintain the label window
|
| + // stacking position above the item to make the header transformation more
|
| + // gradual upon exiting the overview mode.
|
| + WmWindow* label_window =
|
| + WmLookup::Get()->GetWindowForWidget(window_label_.get());
|
| + label_window->GetParent()->StackChildAbove(label_window,
|
| + transform_window_.window());
|
| + }
|
| + if (background_view_) {
|
| + background_view_->OnItemRestored();
|
| + background_view_ = nullptr;
|
| + }
|
| + FadeOut(std::move(window_label_));
|
| }
|
|
|
| void WindowSelectorItem::ShowWindowOnExit() {
|
| @@ -339,7 +511,7 @@ void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds,
|
|
|
| // SetItemBounds is called before UpdateHeaderLayout so the header can
|
| // properly use the updated windows bounds.
|
| - UpdateHeaderLayout(animation_type);
|
| + UpdateHeaderLayout(HeaderFadeInMode::UPDATE, animation_type);
|
| if (!ash::MaterialDesignController::IsOverviewMaterial())
|
| UpdateWindowLabel(target_bounds, animation_type);
|
| }
|
| @@ -347,28 +519,21 @@ void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds,
|
| void WindowSelectorItem::SetSelected(bool selected) {
|
| if (!ash::MaterialDesignController::IsOverviewMaterial())
|
| return;
|
| - WmWindow* window =
|
| - WmLookup::Get()->GetWindowForWidget(window_label_selector_.get());
|
| - ui::ScopedLayerAnimationSettings animation_settings(
|
| - window->GetLayer()->GetAnimator());
|
| - animation_settings.SetTransitionDuration(
|
| - base::TimeDelta::FromMilliseconds(kSelectorFadeInMilliseconds));
|
| - animation_settings.SetTweenType(selected ? gfx::Tween::FAST_OUT_LINEAR_IN
|
| - : gfx::Tween::LINEAR_OUT_SLOW_IN);
|
| - animation_settings.SetPreemptionStrategy(
|
| - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
|
| - window->SetOpacity(selected ? 0.0f : 1.0f);
|
| -
|
| - ui::ScopedLayerAnimationSettings animation_settings_shadow(
|
| - shadow_->shadow_layer()->GetAnimator());
|
| - animation_settings_shadow.SetTransitionDuration(
|
| - base::TimeDelta::FromMilliseconds(kSelectorFadeInMilliseconds));
|
| - animation_settings_shadow.SetTweenType(selected
|
| - ? gfx::Tween::FAST_OUT_LINEAR_IN
|
| - : gfx::Tween::LINEAR_OUT_SLOW_IN);
|
| - animation_settings_shadow.SetPreemptionStrategy(
|
| - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
|
| - shadow_->shadow_layer()->SetOpacity(selected ? 0.0f : 1.0f);
|
| + selected_ = selected;
|
| + background_view_->AnimateBackgroundOpacity(selected ? 0.f : kHeaderOpacity);
|
| +
|
| + if (shadow_) {
|
| + ui::ScopedLayerAnimationSettings animation_settings_shadow(
|
| + shadow_->shadow_layer()->GetAnimator());
|
| + animation_settings_shadow.SetTransitionDuration(
|
| + base::TimeDelta::FromMilliseconds(kSelectorFadeInMilliseconds));
|
| + animation_settings_shadow.SetTweenType(
|
| + selected ? gfx::Tween::FAST_OUT_LINEAR_IN
|
| + : gfx::Tween::LINEAR_OUT_SLOW_IN);
|
| + animation_settings_shadow.SetPreemptionStrategy(
|
| + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
|
| + shadow_->shadow_layer()->SetOpacity(selected ? 0.0f : 1.0f);
|
| + }
|
| }
|
|
|
| void WindowSelectorItem::RecomputeWindowTransforms() {
|
| @@ -381,7 +546,8 @@ void WindowSelectorItem::RecomputeWindowTransforms() {
|
| else
|
| inset_bounds.Inset(kWindowMargin, kWindowMargin);
|
| SetItemBounds(inset_bounds, OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
|
| - UpdateHeaderLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
|
| + UpdateHeaderLayout(HeaderFadeInMode::UPDATE,
|
| + OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
|
| }
|
|
|
| void WindowSelectorItem::SendAccessibleSelectionEvent() {
|
| @@ -409,6 +575,10 @@ void WindowSelectorItem::CloseWindow() {
|
| transform_window_.Close();
|
| }
|
|
|
| +void WindowSelectorItem::HideHeaderAndSetShape(int radius) {
|
| + transform_window_.HideHeaderAndSetShape(use_mask_, use_shape_, radius);
|
| +}
|
| +
|
| void WindowSelectorItem::SetDimmed(bool dimmed) {
|
| dimmed_ = dimmed;
|
| SetOpacity(dimmed ? kDimmedItemOpacity : 1.0f);
|
| @@ -473,17 +643,17 @@ void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds,
|
| screen_rect, selector_item_bounds);
|
| ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings;
|
| transform_window_.BeginScopedAnimation(animation_type, &animation_settings);
|
| - // Rounded corners are achieved by using a mask layer on the original window
|
| - // before the transform. Dividing by scale factor obtains the corner radius
|
| - // which when scaled will yield |kLabelBackgroundRadius|.
|
| - transform_window_.SetTransform(
|
| - root_window_, transform, use_mask_, use_shape_,
|
| - (kLabelBackgroundRadius / GetItemScale(target_bounds.size())));
|
| + transform_window_.SetTransform(root_window_, transform, use_mask_);
|
| transform_window_.set_overview_transform(transform);
|
| }
|
|
|
| void WindowSelectorItem::SetOpacity(float opacity) {
|
| window_label_->SetOpacity(opacity);
|
| + if (background_view_) {
|
| + background_view_->AnimateBackgroundOpacity(
|
| + selected_ ? 0.f : kHeaderOpacity * opacity);
|
| + }
|
| +
|
| if (!ash::MaterialDesignController::IsOverviewMaterial())
|
| close_button_widget_->SetOpacity(opacity);
|
|
|
| @@ -514,23 +684,47 @@ void WindowSelectorItem::UpdateWindowLabel(
|
|
|
| void WindowSelectorItem::CreateWindowLabel(const base::string16& title) {
|
| const bool material = ash::MaterialDesignController::IsOverviewMaterial();
|
| - window_label_.reset(new views::Widget);
|
| - views::Widget::InitParams params;
|
| - params.type = views::Widget::InitParams::TYPE_POPUP;
|
| - params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
| - params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
|
| - params.visible_on_all_workspaces = true;
|
| - params.name = "OverviewModeLabel";
|
| - window_label_->set_focus_on_creation(false);
|
| + if (material) {
|
| + background_view_ = new RoundedContainerView(
|
| + this, transform_window_.window(), kLabelBackgroundRadius,
|
| + transform_window_.GetTopColor());
|
| + // |background_view_| will get added as a child to CaptionContainerView.
|
| + }
|
| + views::Widget::InitParams params_label;
|
| + params_label.type = views::Widget::InitParams::TYPE_POPUP;
|
| + params_label.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
| + params_label.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
|
| + params_label.visible_on_all_workspaces = true;
|
| + params_label.name = "OverviewModeLabel";
|
| + params_label.activatable =
|
| + views::Widget::InitParams::Activatable::ACTIVATABLE_DEFAULT;
|
| + params_label.accept_events = true;
|
| root_window_->GetRootWindowController()
|
| ->ConfigureWidgetInitParamsForContainer(
|
| - window_label_.get(), kShellWindowId_StatusContainer, ¶ms);
|
| - window_label_->Init(params);
|
| + window_label_.get(),
|
| + transform_window_.window()->GetParent()->GetShellWindowId(),
|
| + ¶ms_label);
|
| + window_label_.reset(new views::Widget);
|
| + window_label_->set_focus_on_creation(false);
|
| + window_label_->Init(params_label);
|
| window_label_button_view_ = new OverviewLabelButton(this, title);
|
| window_label_button_view_->SetBorder(views::Border::NullBorder());
|
| window_label_button_view_->SetEnabledTextColors(kLabelColor);
|
| window_label_button_view_->set_animate_on_state_change(false);
|
| if (material) {
|
| + WmWindow* label_window =
|
| + WmLookup::Get()->GetWindowForWidget(window_label_.get());
|
| + if (transform_window_.GetTopInset()) {
|
| + // For windows with headers the overview header fades in above the
|
| + // original window header.
|
| + label_window->GetParent()->StackChildAbove(label_window,
|
| + transform_window_.window());
|
| + } else {
|
| + // For tabbed windows the overview header slides from behind. The stacking
|
| + // is then corrected when the animation completes.
|
| + label_window->GetParent()->StackChildBelow(label_window,
|
| + transform_window_.window());
|
| + }
|
| window_label_button_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
| } else {
|
| window_label_button_view_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
|
| @@ -545,28 +739,27 @@ void WindowSelectorItem::CreateWindowLabel(const base::string16& title) {
|
| // Hint at the background color that the label will be drawn onto (for
|
| // subpixel antialiasing). Does not actually set the background color.
|
| window_label_button_view_->SetBackgroundColorHint(kLabelBackgroundColor);
|
| - caption_container_view_ =
|
| - new CaptionContainerView(window_label_button_view_, close_button_);
|
| + caption_container_view_ = new CaptionContainerView(
|
| + window_label_button_view_, close_button_, background_view_);
|
| window_label_->SetContentsView(caption_container_view_);
|
| window_label_button_view_->SetVisible(false);
|
| + window_label_->SetOpacity(0);
|
| window_label_->Show();
|
|
|
| - shadow_.reset(new ::wm::Shadow());
|
| - shadow_->Init(::wm::Shadow::STYLE_INACTIVE);
|
| - shadow_->layer()->SetVisible(true);
|
| - window_label_->GetLayer()->Add(shadow_->layer());
|
| + // TODO(varkha): Restore shadows when programmatic shadows exist.
|
| + // Note: current shadow implementation does not allow proper animation when
|
| + // the parent layer bounds change during the animation since
|
| + // Shadow::UpdateLayerBounds() only happens before the animation starts.
|
| + if (ash::MaterialDesignController::GetMode() ==
|
| + ash::MaterialDesignController::Mode::MATERIAL_EXPERIMENTAL) {
|
| + shadow_.reset(new ::wm::Shadow());
|
| + shadow_->Init(::wm::Shadow::STYLE_INACTIVE);
|
| + shadow_->layer()->SetVisible(true);
|
| + window_label_->GetLayer()->Add(shadow_->layer());
|
| + }
|
| window_label_->GetLayer()->SetMasksToBounds(false);
|
| -
|
| - views::View* background_view =
|
| - new RoundedContainerView(kLabelBackgroundRadius, kLabelBackgroundColor);
|
| - window_label_selector_.reset(new views::Widget);
|
| - params.activatable = views::Widget::InitParams::Activatable::ACTIVATABLE_NO;
|
| - params.accept_events = false;
|
| - params.name = "OverviewModeLabelSelector";
|
| - window_label_selector_->Init(params);
|
| - window_label_selector_->set_focus_on_creation(false);
|
| - window_label_selector_->SetContentsView(background_view);
|
| - window_label_selector_->Show();
|
| + UpdateHeaderLayout(HeaderFadeInMode::ENTER,
|
| + OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
|
| } else {
|
| // Indicate that the label will be drawn onto a transparent background
|
| // (disables subpixel antialiasing).
|
| @@ -576,50 +769,65 @@ void WindowSelectorItem::CreateWindowLabel(const base::string16& title) {
|
| }
|
|
|
| void WindowSelectorItem::UpdateHeaderLayout(
|
| + HeaderFadeInMode mode,
|
| OverviewAnimationType animation_type) {
|
| gfx::Rect transformed_window_bounds = root_window_->ConvertRectFromScreen(
|
| transform_window_.GetTransformedBounds(hide_header()));
|
|
|
| if (ash::MaterialDesignController::IsOverviewMaterial()) {
|
| gfx::Rect label_rect(close_button_->GetPreferredSize());
|
| - label_rect.set_y(-label_rect.height());
|
| label_rect.set_width(transformed_window_bounds.width());
|
| -
|
| + // For tabbed windows the initial bounds of the caption are set such that it
|
| + // appears to be "growing" up from the window content area.
|
| + label_rect.set_y(
|
| + (mode != HeaderFadeInMode::ENTER || transform_window_.GetTopInset())
|
| + ? -label_rect.height()
|
| + : 0);
|
| + if (background_view_) {
|
| + if (mode == HeaderFadeInMode::ENTER) {
|
| + background_view_->ObserveLayerAnimations(window_label_->GetLayer());
|
| + background_view_->set_color(kLabelBackgroundColor);
|
| + // The color will be animated only once the label widget is faded in.
|
| + } else if (mode == HeaderFadeInMode::EXIT) {
|
| + // Normally the observer is disconnected when the fade-in animations
|
| + // complete but some tests invoke animations with |NON_ZERO_DURATION|
|
| + // without waiting for completion so do it here.
|
| + background_view_->StopObservingLayerAnimations();
|
| + // Make the header visible above the window. It will be faded out when
|
| + // the Shutdown() is called.
|
| + background_view_->AnimateColor(gfx::Tween::EASE_OUT,
|
| + kExitFadeInMilliseconds);
|
| + background_view_->set_color(kLabelExitColor);
|
| + }
|
| + }
|
| if (!window_label_button_view_->visible()) {
|
| window_label_button_view_->SetVisible(true);
|
| SetupFadeInAfterLayout(window_label_.get());
|
| - SetupFadeInAfterLayout(window_label_selector_.get());
|
| }
|
| WmWindow* window_label_window =
|
| WmLookup::Get()->GetWindowForWidget(window_label_.get());
|
| - WmWindow* window_label_selector_window =
|
| - WmLookup::Get()->GetWindowForWidget(window_label_selector_.get());
|
| std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings =
|
| ScopedOverviewAnimationSettingsFactory::Get()
|
| ->CreateOverviewAnimationSettings(animation_type,
|
| window_label_window);
|
| - std::unique_ptr<ScopedOverviewAnimationSettings>
|
| - animation_settings_selector =
|
| - ScopedOverviewAnimationSettingsFactory::Get()
|
| - ->CreateOverviewAnimationSettings(animation_type,
|
| - window_label_selector_window);
|
| - window_label_selector_window->SetBounds(label_rect);
|
| // |window_label_window| covers both the transformed window and the header
|
| // as well as the gap between the windows to prevent events from reaching
|
| // the window including its sizing borders.
|
| - label_rect.set_height(label_rect.height() +
|
| - transformed_window_bounds.height());
|
| - gfx::Rect shadow_bounds(label_rect.size());
|
| + if (mode != HeaderFadeInMode::ENTER) {
|
| + label_rect.set_height(close_button_->GetPreferredSize().height() +
|
| + transformed_window_bounds.height());
|
| + }
|
| label_rect.Inset(-kWindowSelectorMargin, -kWindowSelectorMargin);
|
| window_label_window->SetBounds(label_rect);
|
| gfx::Transform label_transform;
|
| label_transform.Translate(transformed_window_bounds.x(),
|
| transformed_window_bounds.y());
|
| window_label_window->SetTransform(label_transform);
|
| - window_label_selector_window->SetTransform(label_transform);
|
|
|
| - shadow_bounds.Offset(kWindowSelectorMargin, kWindowSelectorMargin);
|
| - shadow_->SetContentBounds(shadow_bounds);
|
| + gfx::Rect shadow_bounds(label_rect.size());
|
| + shadow_bounds.Inset(kWindowSelectorMargin, kWindowSelectorMargin);
|
| + if (shadow_)
|
| + shadow_->SetContentBounds(shadow_bounds);
|
| } else {
|
| if (!close_button_->visible()) {
|
| close_button_->SetVisible(true);
|
| @@ -647,21 +855,14 @@ void WindowSelectorItem::AnimateOpacity(float opacity,
|
| transform_window_.BeginScopedAnimation(animation_type, &animation_settings);
|
| transform_window_.SetOpacity(opacity);
|
|
|
| + const float header_opacity = selected_ ? 0.f : kHeaderOpacity * opacity;
|
| WmWindow* window_label_window =
|
| WmLookup::Get()->GetWindowForWidget(window_label_.get());
|
| std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings_label =
|
| ScopedOverviewAnimationSettingsFactory::Get()
|
| ->CreateOverviewAnimationSettings(animation_type,
|
| window_label_window);
|
| - window_label_window->SetOpacity(opacity);
|
| -
|
| - WmWindow* window_label_selector_window =
|
| - WmLookup::Get()->GetWindowForWidget(window_label_selector_.get());
|
| - std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings_selector =
|
| - ScopedOverviewAnimationSettingsFactory::Get()
|
| - ->CreateOverviewAnimationSettings(animation_type,
|
| - window_label_selector_window);
|
| - window_label_selector_window->SetOpacity(opacity);
|
| + window_label_window->SetOpacity(header_opacity);
|
| }
|
|
|
| void WindowSelectorItem::UpdateCloseButtonAccessibilityName() {
|
| @@ -670,4 +871,29 @@ void WindowSelectorItem::UpdateCloseButtonAccessibilityName() {
|
| GetWindow()->GetTitle()));
|
| }
|
|
|
| +void WindowSelectorItem::FadeOut(std::unique_ptr<views::Widget> widget) {
|
| + widget->SetOpacity(1.f);
|
| +
|
| + // Fade out the widget. This animation continues past the lifetime of |this|.
|
| + WmWindow* widget_window = WmLookup::Get()->GetWindowForWidget(widget.get());
|
| + std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings =
|
| + ScopedOverviewAnimationSettingsFactory::Get()
|
| + ->CreateOverviewAnimationSettings(
|
| + OverviewAnimationType::
|
| + OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_FADE_OUT,
|
| + widget_window);
|
| + // CleanupAnimationObserver will delete itself (and the widget) when the
|
| + // opacity animation is complete.
|
| + // Ownership over the observer is passed to the window_selector_->delegate()
|
| + // which has longer lifetime so that animations can continue even after the
|
| + // overview mode is shut down.
|
| + views::Widget* widget_ptr = widget.get();
|
| + std::unique_ptr<CleanupAnimationObserver> observer(
|
| + new CleanupAnimationObserver(std::move(widget)));
|
| + animation_settings->AddObserver(observer.get());
|
| + window_selector_->delegate()->AddDelayedAnimationObserver(
|
| + std::move(observer));
|
| + widget_ptr->SetOpacity(0.f);
|
| +}
|
| +
|
| } // namespace ash
|
|
|