- add sources.
[platform/framework/web/crosswalk.git] / src / ui / views / controls / slide_out_view.cc
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.
4
5 #include "ui/views/controls/slide_out_view.h"
6
7 #include "ui/compositor/layer.h"
8 #include "ui/compositor/scoped_layer_animation_settings.h"
9 #include "ui/gfx/transform.h"
10
11 namespace views {
12
13 SlideOutView::SlideOutView()
14     : gesture_scroll_amount_(0.f) {
15   // If accelerated compositing is not available, this widget tracks the
16   // OnSlideOut event but does not render any visible changes.
17   if (get_use_acceleration_when_possible()) {
18     SetPaintToLayer(true);
19     SetFillsBoundsOpaquely(false);
20   }
21 }
22
23 SlideOutView::~SlideOutView() {
24 }
25
26 void SlideOutView::OnGestureEvent(ui::GestureEvent* event) {
27   if (event->type() == ui::ET_SCROLL_FLING_START) {
28     // The threshold for the fling velocity is computed empirically.
29     // The unit is in pixels/second.
30     const float kFlingThresholdForClose = 800.f;
31     if (fabsf(event->details().velocity_x()) > kFlingThresholdForClose) {
32       SlideOutAndClose(event->details().velocity_x() < 0 ? SLIDE_LEFT :
33                        SLIDE_RIGHT);
34       event->StopPropagation();
35       return;
36     }
37     RestoreVisualState();
38     return;
39   }
40
41   if (!event->IsScrollGestureEvent())
42     return;
43
44   if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN) {
45     gesture_scroll_amount_ = 0.f;
46   } else if (event->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
47     // The scroll-update events include the incremental scroll amount.
48     gesture_scroll_amount_ += event->details().scroll_x();
49
50     if (get_use_acceleration_when_possible()) {
51       gfx::Transform transform;
52       transform.Translate(gesture_scroll_amount_, 0.0);
53       layer()->SetTransform(transform);
54       layer()->SetOpacity(
55           1.f - std::min(fabsf(gesture_scroll_amount_) / width(), 1.f));
56     }
57
58   } else if (event->type() == ui::ET_GESTURE_SCROLL_END) {
59     const float kScrollRatioForClosingNotification = 0.5f;
60     float scrolled_ratio = fabsf(gesture_scroll_amount_) / width();
61     if (scrolled_ratio >= kScrollRatioForClosingNotification) {
62       SlideOutAndClose(gesture_scroll_amount_ < 0 ? SLIDE_LEFT : SLIDE_RIGHT);
63       event->StopPropagation();
64       return;
65     }
66     RestoreVisualState();
67   }
68
69   event->SetHandled();
70 }
71
72 void SlideOutView::RestoreVisualState() {
73   if (!get_use_acceleration_when_possible())
74     return;
75
76   // Restore the layer state.
77   const int kSwipeRestoreDurationMS = 150;
78   ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator());
79   settings.SetTransitionDuration(
80       base::TimeDelta::FromMilliseconds(kSwipeRestoreDurationMS));
81   layer()->SetTransform(gfx::Transform());
82   layer()->SetOpacity(1.f);
83 }
84
85 void SlideOutView::SlideOutAndClose(SlideDirection direction) {
86   if (!get_use_acceleration_when_possible()) {
87     // No animations, so don't wait to fire the OnSlideOut event.
88     OnSlideOut();
89     return;
90   }
91   const int kSwipeOutTotalDurationMS = 150;
92   int swipe_out_duration = kSwipeOutTotalDurationMS * layer()->opacity();
93   ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator());
94   settings.SetTransitionDuration(
95       base::TimeDelta::FromMilliseconds(swipe_out_duration));
96   settings.AddObserver(this);
97
98   gfx::Transform transform;
99   transform.Translate(direction == SLIDE_LEFT ? -width() : width(), 0.0);
100   layer()->SetTransform(transform);
101   layer()->SetOpacity(0.f);
102 }
103
104 void SlideOutView::OnImplicitAnimationsCompleted() {
105   OnSlideOut();
106 }
107
108 }  // namespace views