Add synchronous Widget closing event
[chromium-blink-merge.git] / ash / wm / gestures / tray_gesture_handler.cc
blob78b0fb308c85e66764b2f33afa5a12d9d0c76c94
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/wm/gestures/tray_gesture_handler.h"
7 #include "ash/shell.h"
8 #include "ash/system/tray/system_tray.h"
9 #include "ash/system/tray/system_tray_bubble.h"
10 #include "ui/aura/window.h"
11 #include "ui/base/events/event.h"
12 #include "ui/compositor/layer.h"
13 #include "ui/gfx/transform.h"
14 #include "ui/views/widget/widget.h"
16 const int kMinBubbleHeight = 13;
18 namespace ash {
19 namespace internal {
21 TrayGestureHandler::TrayGestureHandler()
22 : widget_(NULL),
23 gesture_drag_amount_(0) {
24 // TODO(oshima): Support multiple display case.
25 SystemTray* tray = Shell::GetInstance()->GetPrimarySystemTray();
26 tray->ShowDefaultView(BUBBLE_CREATE_NEW);
27 SystemTrayBubble* bubble = tray->GetSystemBubble();
28 if (!bubble)
29 return;
30 bubble->bubble_view()->set_gesture_dragging(true);
31 widget_ = bubble->bubble_view()->GetWidget();
32 widget_->AddObserver(this);
34 gfx::Rect bounds = widget_->GetWindowBoundsInScreen();
35 int height_change = bounds.height() - kMinBubbleHeight;
36 bounds.set_height(kMinBubbleHeight);
37 bounds.set_y(bounds.y() + height_change);
38 widget_->SetBounds(bounds);
41 TrayGestureHandler::~TrayGestureHandler() {
42 if (widget_)
43 widget_->RemoveObserver(this);
46 bool TrayGestureHandler::UpdateGestureDrag(const ui::GestureEvent& event) {
47 CHECK_EQ(ui::ET_GESTURE_SCROLL_UPDATE, event.type());
48 if (!widget_)
49 return false;
51 gesture_drag_amount_ += event.details().scroll_y();
52 if (gesture_drag_amount_ > 0 && gesture_drag_amount_ < kMinBubbleHeight) {
53 widget_->Close();
54 return false;
57 gfx::Rect bounds = widget_->GetWindowBoundsInScreen();
58 int new_height = std::min(
59 kMinBubbleHeight + std::max(0, static_cast<int>(-gesture_drag_amount_)),
60 widget_->GetContentsView()->GetPreferredSize().height());
61 int height_change = bounds.height() - new_height;
62 bounds.set_height(new_height);
63 bounds.set_y(bounds.y() + height_change);
64 widget_->SetBounds(bounds);
65 return true;
68 void TrayGestureHandler::CompleteGestureDrag(const ui::GestureEvent& event) {
69 if (!widget_)
70 return;
72 widget_->RemoveObserver(this);
74 // Close the widget if it hasn't been dragged enough.
75 bool should_close = false;
76 int height = widget_->GetWindowBoundsInScreen().height();
77 int preferred_height =
78 widget_->GetContentsView()->GetPreferredSize().height();
79 if (event.type() == ui::ET_GESTURE_SCROLL_END) {
80 const float kMinThresholdGestureDrag = 0.4f;
81 if (height < preferred_height * kMinThresholdGestureDrag)
82 should_close = true;
83 } else if (event.type() == ui::ET_SCROLL_FLING_START) {
84 const float kMinThresholdGestureDragExposeFling = 0.25f;
85 const float kMinThresholdGestureFling = 1000.f;
86 if (height < preferred_height * kMinThresholdGestureDragExposeFling &&
87 event.details().velocity_y() > -kMinThresholdGestureFling)
88 should_close = true;
89 } else {
90 NOTREACHED();
93 if (should_close) {
94 widget_->Close();
95 } else {
96 SystemTrayBubble* bubble =
97 Shell::GetInstance()->GetPrimarySystemTray()->GetSystemBubble();
98 if (bubble)
99 bubble->bubble_view()->set_gesture_dragging(false);
103 void TrayGestureHandler::OnWidgetDestroying(views::Widget* widget) {
104 CHECK_EQ(widget_, widget);
105 widget_ = NULL;
108 } // namespace internal
109 } // namespace ash