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 #ifndef CONTENT_BROWSER_ANDROID_OVERSCROLL_GLOW_H_ 6 #define CONTENT_BROWSER_ANDROID_OVERSCROLL_GLOW_H_ 7 8 #include "base/callback.h" 9 #include "base/memory/ref_counted.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/time/time.h" 12 #include "ui/gfx/size_f.h" 13 #include "ui/gfx/vector2d_f.h" 14 15 namespace cc { 16 class Layer; 17 } 18 19 namespace content { 20 21 class EdgeEffectBase; 22 23 /* |OverscrollGlow| mirrors its Android counterpart, OverscrollGlow.java. 24 * Conscious tradeoffs were made to align this as closely as possible with the 25 * original Android Java version. 26 */ 27 class OverscrollGlow { 28 public: 29 enum Edge { EDGE_TOP = 0, EDGE_LEFT, EDGE_BOTTOM, EDGE_RIGHT, EDGE_COUNT }; 30 31 // Allows lazy creation of the edge effects. 32 typedef base::Callback<scoped_ptr<EdgeEffectBase>(void)> EdgeEffectProvider; 33 34 // |edge_effect_provider| must be valid for the duration of the effect's 35 // lifetime. The effect is enabled by default, but will remain dormant until 36 // the first overscroll event. 37 explicit OverscrollGlow(const EdgeEffectProvider& edge_effect_provider); 38 39 ~OverscrollGlow(); 40 41 // Enable the effect. If the effect was previously disabled, it will remain 42 // dormant until subsequent calls to |OnOverscrolled()|. 43 void Enable(); 44 45 // Deactivate and detach the effect. Subsequent calls to |OnOverscrolled()| or 46 // |Animate()| will have no effect. 47 void Disable(); 48 49 // Effect layers will be attached to |overscrolling_layer| if necessary. 50 // |accumulated_overscroll| and |overscroll_delta| are in device pixels, while 51 // |velocity| is in device pixels / second. 52 // Returns true if the effect still needs animation ticks. 53 bool OnOverscrolled(cc::Layer* overscrolling_layer, 54 base::TimeTicks current_time, 55 gfx::Vector2dF accumulated_overscroll, 56 gfx::Vector2dF overscroll_delta, 57 gfx::Vector2dF velocity, 58 gfx::Vector2dF overscroll_location); 59 60 // Returns true if the effect still needs animation ticks. 61 // Note: The effect will detach itself when no further animation is required. 62 bool Animate(base::TimeTicks current_time); 63 64 // Update the effect according to the most recent display parameters, 65 // Note: All dimensions are in device pixels. 66 struct DisplayParameters { 67 DisplayParameters(); 68 gfx::SizeF size; 69 float edge_offsets[EDGE_COUNT]; 70 }; 71 void UpdateDisplayParameters(const DisplayParameters& params); 72 73 private: 74 enum Axis { AXIS_X, AXIS_Y }; 75 76 // Returns whether the effect is initialized. 77 bool InitializeIfNecessary(); 78 bool NeedsAnimate() const; 79 void UpdateLayerAttachment(cc::Layer* parent); 80 void Detach(); 81 void Pull(base::TimeTicks current_time, 82 const gfx::Vector2dF& overscroll_delta, 83 const gfx::Vector2dF& overscroll_location); 84 void Absorb(base::TimeTicks current_time, 85 const gfx::Vector2dF& velocity, 86 bool x_overscroll_started, 87 bool y_overscroll_started); 88 void Release(base::TimeTicks current_time); 89 90 EdgeEffectBase* GetOppositeEdge(int edge_index); 91 92 EdgeEffectProvider edge_effect_provider_; 93 scoped_ptr<EdgeEffectBase> edge_effects_[EDGE_COUNT]; 94 95 DisplayParameters display_params_; 96 bool enabled_; 97 bool initialized_; 98 99 scoped_refptr<cc::Layer> root_layer_; 100 101 DISALLOW_COPY_AND_ASSIGN(OverscrollGlow); 102 }; 103 104 } // namespace content 105 106 #endif // CONTENT_BROWSER_ANDROID_SCROLL_GLOW_H_ 107