Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Unified Diff: ash/wm/overview/window_selector_item.cc

Issue 690103008: Implemented swipe to close in overview mode. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Implemented swipe to close on top of other changes in overview mode Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 789205011c17911eb459c9d8efd242431edd61de..1b4cf86f0c559aa298dc8813d7bebeb1e2770944 100644
--- a/ash/wm/overview/window_selector_item.cc
+++ b/ash/wm/overview/window_selector_item.cc
@@ -38,6 +38,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.
@@ -73,6 +80,37 @@ 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) {
+ ui::Layer* layer = window->layer();
flackr 2015/02/10 17:49:49 layer is only used once, remove this and access as
bruthig 2015/02/12 18:08:55 Done.
+ ScopedOverviewAnimationSettings animation_settings(
+ OverviewAnimationType::OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_OUT,
+ 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.0 - static_cast<float>(abs(distance)) / min_opacity_distance;
flackr 2015/02/10 17:49:49 nit: 1.0 is a double, use 1.0f for float calculati
bruthig 2015/02/12 18:08:55 Done.
+ return std::min(1.0f, std::max(kMinimumOpacity, opacity));
flackr 2015/02/10 17:49:49 Why std::min with 1.0f? opacity should always be s
bruthig 2015/02/12 18:08:55 Not if min_opacity_distance < 0. Alternatively I
flackr 2015/02/12 18:52:43 I'd prefer DCHECK, min_opacity_distance < 0 doesn'
+}
+
// An image button with a close window icon.
class OverviewCloseButton : public views::ImageButton {
public:
@@ -97,6 +135,61 @@ OverviewCloseButton::OverviewCloseButton(views::ButtonListener* listener)
OverviewCloseButton::~OverviewCloseButton() {
}
+// Specialized views::LabelButton that captures touch gestures.
+class WindowSelectorItemButton : public views::LabelButton {
+ public:
+ WindowSelectorItemButton(WindowSelectorItem* selector_item,
+ const base::string16& text);
+
+ // views::LabelButton:
+ void OnGestureEvent(ui::GestureEvent* event) override;
+
+ private:
+ // The WindowSelectorItem that the touch gestures are delegated to.
+ // Not owned.
+ WindowSelectorItem* selector_item_;
+
+ // The original X location for a scroll begin event. |original_x_| is in the
+ // local coordinate space as |this|.
flackr 2015/02/10 17:49:49 s/as |this|/of |this| ?
bruthig 2015/02/12 18:08:55 Done.
+ float scroll_x_origin_;
+
+ DISALLOW_COPY_AND_ASSIGN(WindowSelectorItemButton);
+};
+
+WindowSelectorItemButton::WindowSelectorItemButton(
+ WindowSelectorItem* selector_item,
+ const base::string16& text)
+ : views::LabelButton(selector_item, text),
+ selector_item_(selector_item) {
+}
+
+void WindowSelectorItemButton::OnGestureEvent(ui::GestureEvent* event) {
+ int delta_x = event->x() - scroll_x_origin_;
flackr 2015/02/10 17:49:49 nit: While the variable is not used in this case,
bruthig 2015/02/12 18:08:55 Done.
+
+ switch (event->type()) {
+ case ui::ET_GESTURE_SCROLL_BEGIN:
+ event->SetHandled();
+ selector_item_->OnScrollBegin();
+ scroll_x_origin_ = event->x();
+ break;
+ case ui::ET_GESTURE_SCROLL_UPDATE:
+ selector_item_->OnScrollUpdate(delta_x);
+ break;
+ case ui::ET_GESTURE_SCROLL_END:
+ selector_item_->OnScrollEnd(delta_x);
+ break;
+ case ui::ET_SCROLL_FLING_START:
+ selector_item_->OnFling(delta_x, fabs(event->details().velocity_x()));
flackr 2015/02/10 17:49:49 I think rather than delegating these events to the
bruthig 2015/02/12 18:08:55 Discussed offline but will summarize here. It wou
+ break;
+ case ui::ET_GESTURE_END:
+ scroll_x_origin_ = 0;
+ break;
+ default:
+ break;
+ }
+ views::LabelButton::OnGestureEvent(event);
+}
+
} // namespace
WindowSelectorItem::WindowSelectorItem(aura::Window* window)
@@ -213,6 +306,58 @@ void WindowSelectorItem::OnWindowTitleChanged(aura::Window* window) {
UpdateCloseButtonAccessibilityName();
}
+void WindowSelectorItem::OnScrollBegin() {
+ close_button_->SetEnabled(false);
+ SetupFadeOut(close_button_widget_.GetNativeWindow());
+}
+
+void WindowSelectorItem::OnScrollUpdate(int delta_x) {
+ ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings;
+ transform_window_.BeginScopedAnimation(
+ OverviewAnimationType::OVERVIEW_ANIMATION_SCROLL_SELECTOR_ITEM,
flackr 2015/02/10 17:49:49 It confuses me that we have an animation type for
bruthig 2015/02/12 18:08:55 It was a while ago and I can't remember the exact
flackr 2015/02/12 18:52:43 Acknowledged, though seems like something worth in
+ &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);
+}
+
+void WindowSelectorItem::OnScrollEnd(int delta_x) {
+ if (abs(delta_x) > GetMinimumCloseDistance()) {
+ transform_window_.Close();
+ return;
+ }
+ ResetScrolledWindow();
+}
+
+void WindowSelectorItem::OnFling(int delta_x, float velocity_x) {
+ if (abs(delta_x) > GetMinimumCloseDistance() ||
+ velocity_x > kMinimumFlingVelocity) {
+ transform_window_.Close();
+ return;
+ }
+ ResetScrolledWindow();
+}
+
+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());
@@ -246,8 +391,7 @@ void WindowSelectorItem::UpdateWindowLabel(
if (!window_label_->IsVisible()) {
window_label_->Show();
- ScopedOverviewAnimationSettings::SetupFadeInAfterLayout(
- window_label_->GetNativeWindow());
+ SetupFadeInAfterLayout(window_label_->GetNativeWindow());
}
gfx::Rect converted_bounds =
@@ -273,7 +417,11 @@ void WindowSelectorItem::CreateWindowLabel(const base::string16& title) {
params.visible_on_all_workspaces = true;
window_label_->set_focus_on_creation(false);
window_label_->Init(params);
- window_label_button_view_ = new views::LabelButton(this, title);
+ if (Shell::GetInstance()->window_selector_controller()->
+ swipe_to_close_disabled())
flackr 2015/02/10 17:49:49 You should check the flag directly here.
bruthig 2015/02/12 18:08:55 The flag check has been moved in to the OverviewLa
+ window_label_button_view_ = new views::LabelButton(this, title);
+ else
+ window_label_button_view_ = new WindowSelectorItemButton(this, title);
window_label_button_view_->SetTextColor(views::LabelButton::STATE_NORMAL,
kLabelColor);
window_label_button_view_->SetTextColor(views::LabelButton::STATE_HOVERED,
@@ -296,8 +444,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());
@@ -319,4 +466,8 @@ void WindowSelectorItem::UpdateCloseButtonAccessibilityName() {
GetWindow()->title()));
}
+int WindowSelectorItem::GetMinimumCloseDistance() const {
+ return target_bounds_.size().width() / 2;
+}
+
} // namespace ash

Powered by Google App Engine
This is Rietveld 408576698