| Index: ash/wm/overview/window_selector_item.cc
|
| diff --git a/ash/wm/overview/window_selector_item.cc b/ash/wm/overview/window_selector_item.cc
|
| index 13b52b7856fe51df29935df38d369ac7848b1f63..2559362fffdf8dc848974cea9360559c60686dba 100644
|
| --- a/ash/wm/overview/window_selector_item.cc
|
| +++ b/ash/wm/overview/window_selector_item.cc
|
| @@ -37,6 +37,13 @@ namespace ash {
|
|
|
| namespace {
|
|
|
| +// The minimum fling velocity which will cause a window to be closed. Unit is
|
| +// pixels per second.
|
| +const float kMinimumFlingVelocity = 4000.0f;
|
| +
|
| +// The minimum opacity used during touch scroll gestures.
|
| +const float kMinimumOpacity = 0.2f;
|
| +
|
| // In the conceptual overview table, the window margin is the space reserved
|
| // around the window within the cell. This margin does not overlap so the
|
| // closest distance between adjacent windows will be twice this amount.
|
| @@ -72,6 +79,36 @@ gfx::Rect GetTransformedBounds(aura::Window* window) {
|
| return ToEnclosingRect(bounds);
|
| }
|
|
|
| +// Convenvience method to fade in a Window with predefined animation settings.
|
| +// Note: The fade in animation will occur after a delay where the delay is how
|
| +// long the lay out animations take.
|
| +void SetupFadeInAfterLayout(aura::Window* window) {
|
| + ui::Layer* layer = window->layer();
|
| + layer->SetOpacity(0.0f);
|
| + ScopedOverviewAnimationSettings animation_settings(
|
| + OverviewAnimationType::OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN,
|
| + window);
|
| + layer->SetOpacity(1.0f);
|
| +}
|
| +
|
| +// Convenience method to fade out a window using the animation settings defined
|
| +// by OverviewAnimationType::OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_OUT.
|
| +void SetupFadeOut(aura::Window* window) {
|
| + ScopedOverviewAnimationSettings animation_settings(
|
| + OverviewAnimationType::OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_OUT,
|
| + window);
|
| + window->layer()->SetOpacity(0.0f);
|
| +}
|
| +
|
| +// Calculates the window opacity from the given scroll |distance| and the
|
| +// |min opacity_distance|.
|
| +float CalculateOpacityFromScrollDistance(int distance,
|
| + int min_opacity_distance) {
|
| + float opacity =
|
| + 1.0f - static_cast<float>(abs(distance)) / min_opacity_distance;
|
| + return std::min(1.0f, std::max(kMinimumOpacity, opacity));
|
| +}
|
| +
|
| // An image button with a close window icon.
|
| class OverviewCloseButton : public views::ImageButton {
|
| public:
|
| @@ -99,9 +136,10 @@ OverviewCloseButton::~OverviewCloseButton() {
|
| } // namespace
|
|
|
| WindowSelectorItem::OverviewLabelButton::OverviewLabelButton(
|
| - views::ButtonListener* listener,
|
| + WindowSelectorItem* selector_item,
|
| const base::string16& text)
|
| - : LabelButton(listener, text),
|
| + : LabelButton(selector_item, text),
|
| + selector_item_(selector_item),
|
| top_padding_(0) {
|
| }
|
|
|
| @@ -114,6 +152,12 @@ gfx::Rect WindowSelectorItem::OverviewLabelButton::GetChildAreaBounds() {
|
| return bounds;
|
| }
|
|
|
| +void WindowSelectorItem::OverviewLabelButton::OnGestureEvent(
|
| + ui::GestureEvent* event) {
|
| + selector_item_->OnGestureEvent(event);
|
| + views::LabelButton::OnGestureEvent(event);
|
| +}
|
| +
|
| WindowSelectorItem::WindowSelectorItem(aura::Window* window)
|
| : dimmed_(false),
|
| root_window_(window->GetRootWindow()),
|
| @@ -216,6 +260,72 @@ void WindowSelectorItem::ButtonPressed(views::Button* sender,
|
| wm::GetWindowState(transform_window_.window())->Activate();
|
| }
|
|
|
| +void WindowSelectorItem::OnGestureEvent(ui::GestureEvent* event) {
|
| + if (Shell::GetInstance()->window_selector_controller()->
|
| + swipe_to_close_disabled())
|
| + return;
|
| +
|
| + int delta_x = 0;
|
| + if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN)
|
| + scroll_x_origin_ = event->x();
|
| + else
|
| + delta_x = event->x() - scroll_x_origin_;
|
| +
|
| + switch (event->type()) {
|
| + case ui::ET_GESTURE_SCROLL_BEGIN: {
|
| + // We need to call SetHandled() for the ET_GESTURE_SCROLL_BEGIN event so
|
| + // that future ET_GESTURE_SCROLL_* events are sent here.
|
| + event->SetHandled();
|
| + close_button_->SetEnabled(false);
|
| + SetupFadeOut(close_button_widget_.GetNativeWindow());
|
| + break;
|
| + }
|
| + case ui::ET_GESTURE_SCROLL_UPDATE: {
|
| + event->SetHandled();
|
| + ScopedTransformOverviewWindow::ScopedAnimationSettings
|
| + animation_settings;
|
| + transform_window_.BeginScopedAnimation(
|
| + OverviewAnimationType::OVERVIEW_ANIMATION_SCROLL_SELECTOR_ITEM,
|
| + &animation_settings);
|
| +
|
| + gfx::Transform new_transform;
|
| + new_transform.Translate(delta_x, 0);
|
| + new_transform.PreconcatTransform(
|
| + transform_window_.get_overview_transform());
|
| + transform_window_.SetTransform(root_window(), new_transform);
|
| +
|
| + const float opacity = CalculateOpacityFromScrollDistance(delta_x,
|
| + GetMinimumCloseDistance());
|
| + transform_window_.SetOpacity(opacity);
|
| + break;
|
| + }
|
| + case ui::ET_GESTURE_SCROLL_END: {
|
| + event->SetHandled();
|
| + if (abs(delta_x) > GetMinimumCloseDistance()) {
|
| + transform_window_.Close();
|
| + break;
|
| + }
|
| + ResetScrolledWindow();
|
| + break;
|
| + }
|
| + case ui::ET_SCROLL_FLING_START: {
|
| + event->SetHandled();
|
| + if (abs(delta_x) > GetMinimumCloseDistance() ||
|
| + fabs(event->details().velocity_x()) > kMinimumFlingVelocity) {
|
| + transform_window_.Close();
|
| + break;
|
| + }
|
| + ResetScrolledWindow();
|
| + break;
|
| + }
|
| + case ui::ET_GESTURE_END:
|
| + scroll_x_origin_ = 0;
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| +}
|
| +
|
| void WindowSelectorItem::OnWindowDestroying(aura::Window* window) {
|
| window->RemoveObserver(this);
|
| transform_window_.OnWindowDestroyed();
|
| @@ -228,6 +338,20 @@ void WindowSelectorItem::OnWindowTitleChanged(aura::Window* window) {
|
| UpdateCloseButtonAccessibilityName();
|
| }
|
|
|
| +void WindowSelectorItem::ResetScrolledWindow() {
|
| + ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings;
|
| + transform_window_.BeginScopedAnimation(
|
| + OverviewAnimationType::OVERVIEW_ANIMATION_CANCEL_SELECTOR_ITEM_SCROLL,
|
| + &animation_settings);
|
| +
|
| + transform_window_.SetTransform(root_window(),
|
| + transform_window_.get_overview_transform());
|
| + transform_window_.SetOpacity(1.0);
|
| +
|
| + SetupFadeInAfterLayout(close_button_widget_.GetNativeWindow());
|
| + close_button_->SetEnabled(true);
|
| +}
|
| +
|
| void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds,
|
| OverviewAnimationType animation_type) {
|
| DCHECK(root_window_ == GetWindow()->GetRootWindow());
|
| @@ -261,8 +385,7 @@ void WindowSelectorItem::UpdateWindowLabel(
|
|
|
| if (!window_label_->IsVisible()) {
|
| window_label_->Show();
|
| - ScopedOverviewAnimationSettings::SetupFadeInAfterLayout(
|
| - window_label_->GetNativeWindow());
|
| + SetupFadeInAfterLayout(window_label_->GetNativeWindow());
|
| }
|
|
|
| gfx::Rect converted_bounds =
|
| @@ -311,8 +434,7 @@ void WindowSelectorItem::UpdateCloseButtonLayout(
|
| OverviewAnimationType animation_type) {
|
| if (!close_button_->visible()) {
|
| close_button_->SetVisible(true);
|
| - ScopedOverviewAnimationSettings::SetupFadeInAfterLayout(
|
| - close_button_widget_.GetNativeWindow());
|
| + SetupFadeInAfterLayout(close_button_widget_.GetNativeWindow());
|
| }
|
| ScopedOverviewAnimationSettings animation_settings(animation_type,
|
| close_button_widget_.GetNativeWindow());
|
| @@ -334,4 +456,8 @@ void WindowSelectorItem::UpdateCloseButtonAccessibilityName() {
|
| GetWindow()->title()));
|
| }
|
|
|
| +int WindowSelectorItem::GetMinimumCloseDistance() const {
|
| + return target_bounds_.size().width() / 2;
|
| +}
|
| +
|
| } // namespace ash
|
|
|