diff options
Diffstat (limited to 'chromium/ash/wm/gestures/tray_gesture_handler.cc')
-rw-r--r-- | chromium/ash/wm/gestures/tray_gesture_handler.cc | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/chromium/ash/wm/gestures/tray_gesture_handler.cc b/chromium/ash/wm/gestures/tray_gesture_handler.cc new file mode 100644 index 00000000000..78b0fb308c8 --- /dev/null +++ b/chromium/ash/wm/gestures/tray_gesture_handler.cc @@ -0,0 +1,109 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/wm/gestures/tray_gesture_handler.h" + +#include "ash/shell.h" +#include "ash/system/tray/system_tray.h" +#include "ash/system/tray/system_tray_bubble.h" +#include "ui/aura/window.h" +#include "ui/base/events/event.h" +#include "ui/compositor/layer.h" +#include "ui/gfx/transform.h" +#include "ui/views/widget/widget.h" + +const int kMinBubbleHeight = 13; + +namespace ash { +namespace internal { + +TrayGestureHandler::TrayGestureHandler() + : widget_(NULL), + gesture_drag_amount_(0) { + // TODO(oshima): Support multiple display case. + SystemTray* tray = Shell::GetInstance()->GetPrimarySystemTray(); + tray->ShowDefaultView(BUBBLE_CREATE_NEW); + SystemTrayBubble* bubble = tray->GetSystemBubble(); + if (!bubble) + return; + bubble->bubble_view()->set_gesture_dragging(true); + widget_ = bubble->bubble_view()->GetWidget(); + widget_->AddObserver(this); + + gfx::Rect bounds = widget_->GetWindowBoundsInScreen(); + int height_change = bounds.height() - kMinBubbleHeight; + bounds.set_height(kMinBubbleHeight); + bounds.set_y(bounds.y() + height_change); + widget_->SetBounds(bounds); +} + +TrayGestureHandler::~TrayGestureHandler() { + if (widget_) + widget_->RemoveObserver(this); +} + +bool TrayGestureHandler::UpdateGestureDrag(const ui::GestureEvent& event) { + CHECK_EQ(ui::ET_GESTURE_SCROLL_UPDATE, event.type()); + if (!widget_) + return false; + + gesture_drag_amount_ += event.details().scroll_y(); + if (gesture_drag_amount_ > 0 && gesture_drag_amount_ < kMinBubbleHeight) { + widget_->Close(); + return false; + } + + gfx::Rect bounds = widget_->GetWindowBoundsInScreen(); + int new_height = std::min( + kMinBubbleHeight + std::max(0, static_cast<int>(-gesture_drag_amount_)), + widget_->GetContentsView()->GetPreferredSize().height()); + int height_change = bounds.height() - new_height; + bounds.set_height(new_height); + bounds.set_y(bounds.y() + height_change); + widget_->SetBounds(bounds); + return true; +} + +void TrayGestureHandler::CompleteGestureDrag(const ui::GestureEvent& event) { + if (!widget_) + return; + + widget_->RemoveObserver(this); + + // Close the widget if it hasn't been dragged enough. + bool should_close = false; + int height = widget_->GetWindowBoundsInScreen().height(); + int preferred_height = + widget_->GetContentsView()->GetPreferredSize().height(); + if (event.type() == ui::ET_GESTURE_SCROLL_END) { + const float kMinThresholdGestureDrag = 0.4f; + if (height < preferred_height * kMinThresholdGestureDrag) + should_close = true; + } else if (event.type() == ui::ET_SCROLL_FLING_START) { + const float kMinThresholdGestureDragExposeFling = 0.25f; + const float kMinThresholdGestureFling = 1000.f; + if (height < preferred_height * kMinThresholdGestureDragExposeFling && + event.details().velocity_y() > -kMinThresholdGestureFling) + should_close = true; + } else { + NOTREACHED(); + } + + if (should_close) { + widget_->Close(); + } else { + SystemTrayBubble* bubble = + Shell::GetInstance()->GetPrimarySystemTray()->GetSystemBubble(); + if (bubble) + bubble->bubble_view()->set_gesture_dragging(false); + } +} + +void TrayGestureHandler::OnWidgetDestroying(views::Widget* widget) { + CHECK_EQ(widget_, widget); + widget_ = NULL; +} + +} // namespace internal +} // namespace ash |