OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/web_contents/aura/window_slider.h" | 5 #include "content/browser/web_contents/aura/window_slider.h" |
6 | 6 |
| 7 #include <algorithm> |
| 8 |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/callback.h" | 10 #include "base/callback.h" |
9 #include "content/browser/web_contents/aura/shadow_layer_delegate.h" | 11 #include "content/browser/web_contents/aura/shadow_layer_delegate.h" |
10 #include "content/public/browser/overscroll_configuration.h" | 12 #include "content/public/browser/overscroll_configuration.h" |
11 #include "ui/aura/window.h" | 13 #include "ui/aura/window.h" |
12 #include "ui/base/events/event.h" | 14 #include "ui/base/events/event.h" |
13 #include "ui/compositor/layer_animation_observer.h" | 15 #include "ui/compositor/layer_animation_observer.h" |
14 #include "ui/compositor/scoped_layer_animation_settings.h" | 16 #include "ui/compositor/scoped_layer_animation_settings.h" |
15 | 17 |
16 namespace content { | 18 namespace content { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 content::OVERSCROLL_CONFIG_MIN_THRESHOLD_START)), | 62 content::OVERSCROLL_CONFIG_MIN_THRESHOLD_START)), |
61 complete_threshold_(content::GetOverscrollConfig( | 63 complete_threshold_(content::GetOverscrollConfig( |
62 content::OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE)) { | 64 content::OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE)) { |
63 event_window_->AddPreTargetHandler(this); | 65 event_window_->AddPreTargetHandler(this); |
64 | 66 |
65 event_window_->AddObserver(this); | 67 event_window_->AddObserver(this); |
66 owner_->AddObserver(this); | 68 owner_->AddObserver(this); |
67 } | 69 } |
68 | 70 |
69 WindowSlider::~WindowSlider() { | 71 WindowSlider::~WindowSlider() { |
70 delegate_->OnWindowSliderDestroyed(); | |
71 if (event_window_) { | 72 if (event_window_) { |
72 event_window_->RemovePreTargetHandler(this); | 73 event_window_->RemovePreTargetHandler(this); |
73 event_window_->RemoveObserver(this); | 74 event_window_->RemoveObserver(this); |
74 } | 75 } |
75 if (owner_) | 76 if (owner_) |
76 owner_->RemoveObserver(this); | 77 owner_->RemoveObserver(this); |
| 78 delegate_->OnWindowSliderDestroyed(); |
77 } | 79 } |
78 | 80 |
79 void WindowSlider::ChangeOwner(aura::Window* new_owner) { | 81 void WindowSlider::ChangeOwner(aura::Window* new_owner) { |
80 if (owner_) | 82 if (owner_) |
81 owner_->RemoveObserver(this); | 83 owner_->RemoveObserver(this); |
82 owner_ = new_owner; | 84 owner_ = new_owner; |
83 if (owner_) { | 85 if (owner_) { |
84 owner_->AddObserver(this); | 86 owner_->AddObserver(this); |
85 UpdateForScroll(0.f, 0.f); | 87 UpdateForScroll(0.f, 0.f); |
86 } | 88 } |
87 } | 89 } |
88 | 90 |
| 91 bool WindowSlider::IsSlideInProgress() const { |
| 92 return fabs(delta_x_) >= min_start_threshold_ || slider_.get() || |
| 93 weak_factory_.HasWeakPtrs(); |
| 94 } |
| 95 |
89 void WindowSlider::SetupSliderLayer() { | 96 void WindowSlider::SetupSliderLayer() { |
90 ui::Layer* parent = owner_->layer()->parent(); | 97 ui::Layer* parent = owner_->layer()->parent(); |
91 parent->Add(slider_.get()); | 98 parent->Add(slider_.get()); |
92 if (delta_x_ < 0) | 99 if (delta_x_ < 0) |
93 parent->StackAbove(slider_.get(), owner_->layer()); | 100 parent->StackAbove(slider_.get(), owner_->layer()); |
94 else | 101 else |
95 parent->StackBelow(slider_.get(), owner_->layer()); | 102 parent->StackBelow(slider_.get(), owner_->layer()); |
96 slider_->SetBounds(owner_->layer()->bounds()); | 103 slider_->SetBounds(owner_->layer()->bounds()); |
97 slider_->SetVisible(true); | 104 slider_->SetVisible(true); |
98 } | 105 } |
99 | 106 |
100 void WindowSlider::UpdateForScroll(float x_offset, float y_offset) { | 107 void WindowSlider::UpdateForScroll(float x_offset, float y_offset) { |
101 float old_delta = delta_x_; | 108 float old_delta = delta_x_; |
102 delta_x_ += x_offset; | 109 delta_x_ += x_offset; |
103 if (fabs(delta_x_) < min_start_threshold_) { | 110 if (fabs(delta_x_) < min_start_threshold_ && !slider_.get()) |
104 ResetScroll(); | |
105 return; | 111 return; |
106 } | |
107 | 112 |
108 if ((old_delta < 0 && delta_x_ > 0) || | 113 if ((old_delta < 0 && delta_x_ > 0) || |
109 (old_delta > 0 && delta_x_ < 0)) { | 114 (old_delta > 0 && delta_x_ < 0)) { |
110 slider_.reset(); | 115 slider_.reset(); |
111 shadow_.reset(); | 116 shadow_.reset(); |
112 } | 117 } |
113 | 118 |
114 float translate = 0.f; | 119 float translate = 0.f; |
115 ui::Layer* translate_layer = NULL; | 120 ui::Layer* translate_layer = NULL; |
116 | 121 |
117 if (delta_x_ <= -min_start_threshold_) { | 122 if (delta_x_ <= -min_start_threshold_) { |
118 if (!slider_.get()) { | 123 if (!slider_.get()) { |
119 slider_.reset(delegate_->CreateFrontLayer()); | 124 slider_.reset(delegate_->CreateFrontLayer()); |
| 125 if (!slider_.get()) |
| 126 return; |
120 SetupSliderLayer(); | 127 SetupSliderLayer(); |
121 } | 128 } |
122 translate = event_window_->bounds().width() - | 129 translate = owner_->bounds().width() + |
123 fabs(delta_x_ - min_start_threshold_); | 130 std::max(delta_x_ + min_start_threshold_, |
| 131 static_cast<float>(-owner_->bounds().width())); |
124 translate_layer = slider_.get(); | 132 translate_layer = slider_.get(); |
125 } else if (delta_x_ >= min_start_threshold_) { | 133 } else if (delta_x_ >= min_start_threshold_) { |
126 if (!slider_.get()) { | 134 if (!slider_.get()) { |
127 slider_.reset(delegate_->CreateBackLayer()); | 135 slider_.reset(delegate_->CreateBackLayer()); |
| 136 if (!slider_.get()) |
| 137 return; |
128 SetupSliderLayer(); | 138 SetupSliderLayer(); |
129 } | 139 } |
130 translate = delta_x_ - min_start_threshold_; | 140 translate = std::min(delta_x_ - min_start_threshold_, |
| 141 static_cast<float>(owner_->bounds().width())); |
131 translate_layer = owner_->layer(); | 142 translate_layer = owner_->layer(); |
132 } else { | 143 } else { |
133 NOTREACHED(); | 144 NOTREACHED(); |
134 } | 145 } |
135 | 146 |
136 if (!shadow_.get()) | 147 if (!shadow_.get()) |
137 shadow_.reset(new ShadowLayerDelegate(translate_layer)); | 148 shadow_.reset(new ShadowLayerDelegate(translate_layer)); |
138 | 149 |
139 gfx::Transform transform; | 150 gfx::Transform transform; |
140 transform.Translate(translate, 0); | 151 transform.Translate(translate, 0); |
141 translate_layer->SetTransform(transform); | 152 translate_layer->SetTransform(transform); |
142 } | 153 } |
143 | 154 |
144 void WindowSlider::UpdateForFling(float x_velocity, float y_velocity) { | 155 void WindowSlider::UpdateForFling(float x_velocity, float y_velocity) { |
145 if (fabs(delta_x_) < min_start_threshold_) | 156 if (!slider_.get()) |
146 return; | 157 return; |
147 | 158 |
148 int width = owner_->bounds().width(); | 159 int width = owner_->bounds().width(); |
149 float ratio = (fabs(delta_x_) - min_start_threshold_) / width; | 160 float ratio = (fabs(delta_x_) - min_start_threshold_) / width; |
150 if (ratio < complete_threshold_) { | 161 if (ratio < complete_threshold_) { |
151 ResetScroll(); | 162 ResetScroll(); |
152 return; | 163 return; |
153 } | 164 } |
154 | 165 |
155 ui::Layer* sliding = delta_x_ < 0 ? slider_.get() : owner_->layer(); | 166 ui::Layer* sliding = delta_x_ < 0 ? slider_.get() : owner_->layer(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 } | 218 } |
208 | 219 |
209 delta_x_ = 0.f; | 220 delta_x_ = 0.f; |
210 } | 221 } |
211 | 222 |
212 void WindowSlider::CancelScroll() { | 223 void WindowSlider::CancelScroll() { |
213 ResetScroll(); | 224 ResetScroll(); |
214 } | 225 } |
215 | 226 |
216 void WindowSlider::CompleteWindowSlideAfterAnimation() { | 227 void WindowSlider::CompleteWindowSlideAfterAnimation() { |
| 228 // The delegate may delete the |owner_| from the |OnWindowSlideComplete()| |
| 229 // callback, which would trigger the |
| 230 // |WindowSlider::OnWindowRemovingFromRootWindow()| callback, which would try |
| 231 // to delete itself again. So avoid that by resetting |owner_| before calling |
| 232 // the |OnWindowSlideComplete()| callback on the delegate. |
| 233 owner_->RemoveObserver(this); |
| 234 owner_ = NULL; |
| 235 |
217 delegate_->OnWindowSlideComplete(); | 236 delegate_->OnWindowSlideComplete(); |
218 delete this; | 237 delete this; |
219 } | 238 } |
220 | 239 |
221 void WindowSlider::AbortWindowSlideAfterAnimation() { | 240 void WindowSlider::AbortWindowSlideAfterAnimation() { |
222 delegate_->OnWindowSlideAborted(); | 241 delegate_->OnWindowSlideAborted(); |
223 } | 242 } |
224 | 243 |
225 void WindowSlider::OnKeyEvent(ui::KeyEvent* event) { | 244 void WindowSlider::OnKeyEvent(ui::KeyEvent* event) { |
226 CancelScroll(); | 245 CancelScroll(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 } | 293 } |
275 | 294 |
276 void WindowSlider::OnWindowRemovingFromRootWindow(aura::Window* window) { | 295 void WindowSlider::OnWindowRemovingFromRootWindow(aura::Window* window) { |
277 if (window == event_window_) { | 296 if (window == event_window_) { |
278 window->RemoveObserver(this); | 297 window->RemoveObserver(this); |
279 window->RemovePreTargetHandler(this); | 298 window->RemovePreTargetHandler(this); |
280 event_window_ = NULL; | 299 event_window_ = NULL; |
281 } else if (window == owner_) { | 300 } else if (window == owner_) { |
282 window->RemoveObserver(this); | 301 window->RemoveObserver(this); |
283 owner_ = NULL; | 302 owner_ = NULL; |
284 if (!slider_.get()) | 303 delete this; |
285 delete this; | |
286 } else { | 304 } else { |
287 NOTREACHED(); | 305 NOTREACHED(); |
288 } | 306 } |
289 } | 307 } |
290 | 308 |
291 } // namespace content | 309 } // namespace content |
OLD | NEW |