Chromium Code Reviews| 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 32b38419fb99bc159d73dfce496e6e0b34d828ac..c2a4020bfc2153806107bf4131247a627c47dff2 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" |
| @@ -68,7 +69,7 @@ static const SkColor kCloseButtonColor = SK_ColorWHITE; |
| // Label background color used with Material Design. |
| // TODO(varkha): Make background color conform to window header. |
| -static const SkColor kLabelBackgroundColor = SkColorSetARGB(25, 255, 255, 255); |
| +static const SkColor kLabelBackgroundColor = SkColorSetARGB(254, 225, 225, 225); |
| // Corner radius for the selection tiles used with Material Design. |
| static int kLabelBackgroundRadius = 2; |
| @@ -97,9 +98,15 @@ 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 = 0.2f; |
| + |
| // Duration of background opacity transition for the selected label. |
| static const int kSelectorFadeInMilliseconds = 350; |
| +// The time duration for fade out animations when exiting overview mode. |
| +const int kTransitionMilliseconds = 300; |
|
bruthig
2016/08/30 17:57:33
Should this have 'static' just like the rest of th
varkha
2016/09/02 11:22:51
Done.
|
| + |
| // 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,6 +127,17 @@ void SetupFadeInAfterLayout(views::Widget* widget) { |
| window->SetOpacity(1.0f); |
| } |
| +void SetupOpacityAfterLayout(views::Widget* widget) { |
| + WmWindow* window = WmLookup::Get()->GetWindowForWidget(widget); |
| + std::unique_ptr<ScopedOverviewAnimationSettings> |
| + scoped_overview_animation_settings = |
| + ScopedOverviewAnimationSettingsFactory::Get() |
| + ->CreateOverviewAnimationSettings( |
| + OverviewAnimationType::OVERVIEW_ANIMATION_FADE_IN_HEADER, |
| + window); |
| + window->SetOpacity(kHeaderOpacity); |
| +} |
| + |
| // An image button with a close window icon. |
| class OverviewCloseButton : public views::ImageButton { |
| public: |
| @@ -265,6 +283,8 @@ WindowSelectorItem::WindowSelectorItem(WmWindow* window, |
| root_window_(window->GetRootWindow()), |
| transform_window_(window), |
| in_bounds_update_(false), |
| + selected_(false), |
| + first_time_(true), |
| caption_container_view_(nullptr), |
| window_label_button_view_(nullptr), |
| close_button_(new OverviewCloseButton(this)), |
| @@ -309,6 +329,11 @@ WmWindow* WindowSelectorItem::GetWindow() { |
| void WindowSelectorItem::RestoreWindow() { |
| transform_window_.RestoreWindow(); |
| + UpdateHeaderLayout( |
| + OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS); |
| + FadeOut(std::move(window_label_)); |
| + if (window_label_selector_) |
| + FadeOut(std::move(window_label_selector_)); |
| } |
| void WindowSelectorItem::ShowWindowOnExit() { |
| @@ -347,6 +372,7 @@ void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds, |
| void WindowSelectorItem::SetSelected(bool selected) { |
| if (!ash::MaterialDesignController::IsOverviewMaterial()) |
| return; |
| + selected_ = selected; |
| WmWindow* window = |
| WmLookup::Get()->GetWindowForWidget(window_label_selector_.get()); |
| ui::ScopedLayerAnimationSettings animation_settings( |
| @@ -357,7 +383,7 @@ void WindowSelectorItem::SetSelected(bool selected) { |
| : gfx::Tween::LINEAR_OUT_SLOW_IN); |
| animation_settings.SetPreemptionStrategy( |
| ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| - window->SetOpacity(selected ? 0.0f : 1.0f); |
| + window->SetOpacity(selected ? 0.0f : kHeaderOpacity); |
| ui::ScopedLayerAnimationSettings animation_settings_shadow( |
| shadow_->shadow_layer()->GetAnimator()); |
| @@ -478,12 +504,18 @@ void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds, |
| // which when scaled will yield |kLabelBackgroundRadius|. |
| transform_window_.SetTransform( |
| root_window_, transform, use_mask_, use_shape_, |
| - (kLabelBackgroundRadius / GetItemScale(target_bounds.size()))); |
| + (kLabelBackgroundRadius / GetItemScale(target_bounds.size())), |
| + animation_type != OverviewAnimationType::OVERVIEW_ANIMATION_NONE); |
| transform_window_.set_overview_transform(transform); |
| } |
| void WindowSelectorItem::SetOpacity(float opacity) { |
| window_label_->SetOpacity(opacity); |
| + if (window_label_selector_) { |
| + window_label_selector_->SetOpacity(selected_ ? 0.f |
| + : kHeaderOpacity * opacity); |
| + } |
| + |
| if (!ash::MaterialDesignController::IsOverviewMaterial()) |
| close_button_widget_->SetOpacity(opacity); |
| @@ -514,17 +546,34 @@ 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); |
| root_window_->GetRootWindowController() |
| ->ConfigureWidgetInitParamsForContainer( |
| window_label_.get(), kShellWindowId_StatusContainer, ¶ms); |
| + |
| + if (material) { |
| + views::View* background_view = |
| + new RoundedContainerView(kLabelBackgroundRadius, kLabelBackgroundColor); |
| + window_label_selector_.reset(new views::Widget); |
| + params.activatable = views::Widget::InitParams::Activatable::ACTIVATABLE_NO; |
|
bruthig
2016/08/30 17:57:33
I feel like re-using |params| like this creates mo
varkha
2016/09/02 11:22:51
I've managed to kill the second widget with some r
|
| + params.accept_events = false; |
| + window_label_selector_->Init(params); |
| + window_label_selector_->set_focus_on_creation(false); |
| + window_label_selector_->SetContentsView(background_view); |
| + window_label_selector_->Show(); |
| + } |
| + |
| + params.activatable = |
| + views::Widget::InitParams::Activatable::ACTIVATABLE_DEFAULT; |
| + params.accept_events = true; |
| + params.name = "OverviewModeLabelSelector"; |
| + window_label_.reset(new views::Widget); |
| + window_label_->set_focus_on_creation(false); |
| window_label_->Init(params); |
| window_label_button_view_ = new OverviewLabelButton(this, title); |
| window_label_button_view_->SetBorder(views::Border::NullBorder()); |
| @@ -556,23 +605,14 @@ void WindowSelectorItem::CreateWindowLabel(const base::string16& title) { |
| 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(OverviewAnimationType::OVERVIEW_ANIMATION_NONE); |
| } else { |
| // Indicate that the label will be drawn onto a transparent background |
| // (disables subpixel antialiasing). |
| window_label_button_view_->SetBackgroundColorHint(SK_ColorTRANSPARENT); |
| window_label_->SetContentsView(window_label_button_view_); |
| } |
| + first_time_ = false; |
| } |
| void WindowSelectorItem::UpdateHeaderLayout( |
| @@ -582,13 +622,23 @@ void WindowSelectorItem::UpdateHeaderLayout( |
| if (ash::MaterialDesignController::IsOverviewMaterial()) { |
| gfx::Rect label_rect(close_button_->GetPreferredSize()); |
| - label_rect.set_y(-label_rect.height()); |
| + if (first_time_) { |
| + if (transform_window_.GetTopInset() == 0) { |
| + label_rect.set_y(0); |
| + label_rect.set_height(0); |
| + } else { |
| + label_rect.set_y(-transform_window_.GetTopInset()); |
| + } |
| + } else { |
| + label_rect.set_y(-label_rect.height()); |
| + } |
| label_rect.set_width(transformed_window_bounds.width()); |
| if (!window_label_button_view_->visible()) { |
| window_label_button_view_->SetVisible(true); |
| SetupFadeInAfterLayout(window_label_.get()); |
| SetupFadeInAfterLayout(window_label_selector_.get()); |
| + SetupOpacityAfterLayout(window_label_selector_.get()); |
| } |
| WmWindow* window_label_window = |
| WmLookup::Get()->GetWindowForWidget(window_label_.get()); |
| @@ -647,13 +697,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); |
| + window_label_window->SetOpacity(header_opacity); |
| WmWindow* window_label_selector_window = |
| WmLookup::Get()->GetWindowForWidget(window_label_selector_.get()); |
| @@ -661,7 +712,7 @@ void WindowSelectorItem::AnimateOpacity(float opacity, |
| ScopedOverviewAnimationSettingsFactory::Get() |
| ->CreateOverviewAnimationSettings(animation_type, |
| window_label_selector_window); |
| - window_label_selector_window->SetOpacity(opacity); |
| + window_label_selector_window->SetOpacity(header_opacity); |
| } |
| void WindowSelectorItem::UpdateCloseButtonAccessibilityName() { |
| @@ -670,4 +721,30 @@ 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()); |
| + ui::ScopedLayerAnimationSettings animation_settings( |
|
bruthig
2016/08/30 17:57:33
For consistency, would it make more sense to add a
varkha
2016/09/02 11:22:51
Yes, will do.
|
| + widget_window->GetLayer()->GetAnimator()); |
| + animation_settings.SetTransitionDuration( |
| + base::TimeDelta::FromMilliseconds(kTransitionMilliseconds)); |
| + animation_settings.SetTweenType(gfx::Tween::EASE_OUT); |
| + animation_settings.SetPreemptionStrategy( |
| + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| + // 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 |