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

Side by Side Diff: Source/platform/scroll/ScrollbarStateTransitionAnimator.cpp

Issue 246293006: Blink Support for Overlay Scrollbar Animation Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: fix unittest and move unittest to blink_platform_unittests Created 6 years, 3 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 "config.h"
6
7 #include "platform/scroll/ScrollbarStateTransitionAnimator.h"
8
9 #include "platform/TraceEvent.h"
10 #include "platform/scroll/ScrollableArea.h"
11 #include "wtf/CurrentTime.h"
12 #include "wtf/PassOwnPtr.h"
13 #include <algorithm>
14
15 using namespace std;
16
17 namespace {
18 // This number is calculated from scrollbar animation controller thinning. It is supposed to last 300 milliseconds.
19 const double kDefaultStateTransitionTime = 0.3;
20
21 } // namespace
22
23 namespace blink {
24
25 PassOwnPtr<ScrollbarStateTransitionAnimator> ScrollbarStateTransitionAnimator::c reate(ScrollableArea* scrollableArea)
26 {
27 if (scrollableArea->hasOverlayScrollbars())
28 return adoptPtr(new ScrollbarStateTransitionAnimator(scrollableArea));
29 return PassOwnPtr<ScrollbarStateTransitionAnimator>();
30 }
31
32 ScrollbarStateTransitionAnimator::StateTransitionData::StateTransitionData(Scrol lbarStateTransitionAnimator* parent)
33 {
34 reset();
35 }
36
37 void ScrollbarStateTransitionAnimator::StateTransitionData::reset()
38 {
39 m_startTime = 0;
40 m_animationTime = kDefaultStateTransitionTime;
41 m_lastAnimatedTime = 0;
42 m_progress = 0;
43 m_startState = blink::WebThemeEngine::StateDisabled;
44 m_endState = blink::WebThemeEngine::StateDisabled;
45 }
46
47 void ScrollbarStateTransitionAnimator::StateTransitionData::startStateTransition Animation(double currentTime, blink::WebThemeEngine::State startState, blink::We bThemeEngine::State endState, const Parameters parameters)
48 {
49 if (m_startTime) {
50 // Animation is going on. This is probably because we need to reverse an imation state.
51 if (startState == m_endState || endState == m_startState) {
52 // Since one set of the state could be either hover/pressed, check w hether the other
53 // state is the same. (normal state)
54 double progressedTime = currentTime - m_startTime;
55 // startTime is used to calculate progress, we are faking a startTim e.
56 m_startTime = currentTime - (m_animationTime - progressedTime);
57 m_progress = 1 - m_progress;
58 }
59 } else {
60 m_startTime = currentTime;
61 m_progress = 0;
62 }
63 m_startState = startState;
64 m_endState = endState;
65 }
66
67 bool ScrollbarStateTransitionAnimator::StateTransitionData::animate(double curre ntTime)
68 {
69 if (!duringAnimation(currentTime)) {
70 // Animation should end.
71 reset();
72 m_lastAnimatedTime = currentTime;
73 return false;
74 }
75
76 m_progress = (currentTime - m_startTime) / m_animationTime;
77
78 // Store progress of size/opacity so ScrollbarTheme can read.
79 return true;
80 }
81
82 bool ScrollbarStateTransitionAnimator::StateTransitionData::duringAnimation(doub le currentTime) const
83 {
84 return m_startTime && m_startTime <= currentTime && currentTime <= m_startTi me + m_animationTime;
85 }
86
87 ScrollbarStateTransitionAnimator::ScrollbarStateTransitionAnimator(ScrollableAre a* scrollableArea)
88 : m_scrollableArea(scrollableArea)
89 , m_data(this)
90 , m_animationActive(false)
91 {
92 m_parameters.m_isEnabled = scrollableArea->hasOverlayScrollbars();
93 m_parameters.m_animationTime = kDefaultStateTransitionTime;
94 }
95
96 ScrollbarStateTransitionAnimator::~ScrollbarStateTransitionAnimator()
97 {
98 stopAnimationTimerIfNeeded();
99 }
100
101 void ScrollbarStateTransitionAnimator::cancelAnimations()
102 {
103 m_animationActive = false;
104 }
105
106 void ScrollbarStateTransitionAnimator::serviceAnimations()
107 {
108 if (m_animationActive)
109 animationTimerFired();
110 }
111
112 void ScrollbarStateTransitionAnimator::mouseEnteredScrollbar(Scrollbar* scrollba r)
113 {
114 if (!m_parameters.m_isEnabled)
115 return;
116
117 // Start transition from normal to hover/pressed.
118 double currentTime = this->currentTime();
119 blink::WebThemeEngine::State startState = blink::WebThemeEngine::StateNormal ;
120 blink::WebThemeEngine::State endState = blink::WebThemeEngine::StateHover;
121
122 if (scrollbar) {
123 ScrollbarPart pressedPart = scrollbar->pressedPart();
124 if (pressedPart == ThumbPart)
125 endState = blink::WebThemeEngine::StatePressed;
126 }
127
128 m_data.startStateTransitionAnimation(currentTime, startState, endState, m_pa rameters);
129 animationWillStart();
130 animationTimerFired();
131 }
132
133 void ScrollbarStateTransitionAnimator::mouseExitedScrollbar(Scrollbar* scrollbar )
134 {
135 if (!m_parameters.m_isEnabled)
136 return;
137
138 // Start transition from hover/pressed to normal.
139 double currentTime = this->currentTime();
140 blink::WebThemeEngine::State endState = blink::WebThemeEngine::StateNormal;
141 blink::WebThemeEngine::State startState = blink::WebThemeEngine::StateHover;
142
143 if (scrollbar) {
144 ScrollbarPart pressedPart = scrollbar->pressedPart();
145 if (pressedPart == ThumbPart)
146 endState = blink::WebThemeEngine::StatePressed;
147 }
148
149 m_data.startStateTransitionAnimation(currentTime, startState, endState, m_pa rameters);
150 animationWillStart();
151 animationTimerFired();
152 }
153
154 bool ScrollbarStateTransitionAnimator::isDuringStateTransitionAnimation() const
155 {
156 double currentTime = this->currentTime();
157 return m_animationActive && m_data.duringAnimation(currentTime);
158 }
159
160 void ScrollbarStateTransitionAnimator::notifyStateTransitionInProgress() const
161 {
162 m_scrollableArea->stateTransitionInProgress();
163 }
164
165 void ScrollbarStateTransitionAnimator::animationTimerFired()
166 {
167 TRACE_EVENT0("webkit", "ScrollbarStateTransitionAnimator::animationTimerFire d");
168
169 double currentTime = this->currentTime();
170
171 if (m_data.animate(currentTime)) {
172 startNextTimer();
173 } else {
174 m_animationActive = false;
175 animationDidFinish();
176 }
177
178 notifyStateTransitionInProgress();
179 }
180
181 void ScrollbarStateTransitionAnimator::startNextTimer()
182 {
183 if (scrollableArea()->scheduleAnimation())
184 m_animationActive = true;
185 }
186
187 bool ScrollbarStateTransitionAnimator::animationTimerActive()
188 {
189 return m_animationActive;
190 }
191
192 void ScrollbarStateTransitionAnimator::stopAnimationTimerIfNeeded()
193 {
194 if (animationTimerActive()) {
195 m_animationActive = false;
196 }
197 }
198
199 double ScrollbarStateTransitionAnimator::currentTime() const
200 {
201 return WTF::monotonicallyIncreasingTime();
202 }
203
204 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698