OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 "cc/layers/scrollbar_layer_impl.h" | 5 #include "cc/layers/scrollbar_layer_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "cc/animation/scrollbar_animation_controller.h" | 9 #include "cc/animation/scrollbar_animation_controller.h" |
10 #include "cc/layers/layer.h" | 10 #include "cc/layers/layer.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 ScrollbarOrientation orientation) { | 23 ScrollbarOrientation orientation) { |
24 return make_scoped_ptr(new ScrollbarLayerImpl(tree_impl, | 24 return make_scoped_ptr(new ScrollbarLayerImpl(tree_impl, |
25 id, | 25 id, |
26 orientation)); | 26 orientation)); |
27 } | 27 } |
28 | 28 |
29 ScrollbarLayerImpl::ScrollbarLayerImpl( | 29 ScrollbarLayerImpl::ScrollbarLayerImpl( |
30 LayerTreeImpl* tree_impl, | 30 LayerTreeImpl* tree_impl, |
31 int id, | 31 int id, |
32 ScrollbarOrientation orientation) | 32 ScrollbarOrientation orientation) |
33 : LayerImpl(tree_impl, id), | 33 : ScrollbarLayerImplBase(tree_impl, id, orientation), |
34 track_ui_resource_id_(0), | 34 track_ui_resource_id_(0), |
35 thumb_ui_resource_id_(0), | 35 thumb_ui_resource_id_(0), |
36 current_pos_(0.f), | |
37 maximum_(0), | |
38 thumb_thickness_(0), | 36 thumb_thickness_(0), |
39 thumb_length_(0), | 37 thumb_length_(0), |
40 track_start_(0), | 38 track_start_(0), |
41 track_length_(0), | 39 track_length_(0), |
42 orientation_(orientation), | |
43 vertical_adjust_(0.f), | 40 vertical_adjust_(0.f), |
44 visible_to_total_length_ratio_(1.f), | 41 scroll_layer_id_(Layer::INVALID_ID) {} |
45 scroll_layer_id_(Layer::INVALID_ID), | |
46 is_overlay_scrollbar_(false) {} | |
47 | 42 |
48 ScrollbarLayerImpl::~ScrollbarLayerImpl() {} | 43 ScrollbarLayerImpl::~ScrollbarLayerImpl() {} |
49 | 44 |
50 ScrollbarLayerImpl* ScrollbarLayerImpl::ToScrollbarLayer() { | |
51 return this; | |
52 } | |
53 | |
54 scoped_ptr<LayerImpl> ScrollbarLayerImpl::CreateLayerImpl( | 45 scoped_ptr<LayerImpl> ScrollbarLayerImpl::CreateLayerImpl( |
55 LayerTreeImpl* tree_impl) { | 46 LayerTreeImpl* tree_impl) { |
56 return ScrollbarLayerImpl::Create(tree_impl, | 47 return ScrollbarLayerImpl::Create(tree_impl, |
57 id(), | 48 id(), |
58 orientation_).PassAs<LayerImpl>(); | 49 orientation()).PassAs<LayerImpl>(); |
59 } | 50 } |
60 | 51 |
61 void ScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) { | 52 void ScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) { |
62 LayerImpl::PushPropertiesTo(layer); | 53 ScrollbarLayerImplBase::PushPropertiesTo(layer); |
63 | 54 |
64 ScrollbarLayerImpl* scrollbar_layer = static_cast<ScrollbarLayerImpl*>(layer); | 55 ScrollbarLayerImpl* scrollbar_layer = static_cast<ScrollbarLayerImpl*>(layer); |
65 | 56 |
66 scrollbar_layer->SetThumbThickness(thumb_thickness_); | 57 scrollbar_layer->SetThumbThickness(thumb_thickness_); |
67 scrollbar_layer->SetThumbLength(thumb_length_); | 58 scrollbar_layer->SetThumbLength(thumb_length_); |
68 scrollbar_layer->SetTrackStart(track_start_); | 59 scrollbar_layer->SetTrackStart(track_start_); |
69 scrollbar_layer->SetTrackLength(track_length_); | 60 scrollbar_layer->SetTrackLength(track_length_); |
70 scrollbar_layer->set_is_overlay_scrollbar(is_overlay_scrollbar_); | |
71 | 61 |
72 scrollbar_layer->set_track_ui_resource_id(track_ui_resource_id_); | 62 scrollbar_layer->set_track_ui_resource_id(track_ui_resource_id_); |
73 scrollbar_layer->set_thumb_ui_resource_id(thumb_ui_resource_id_); | 63 scrollbar_layer->set_thumb_ui_resource_id(thumb_ui_resource_id_); |
74 } | 64 } |
75 | 65 |
76 bool ScrollbarLayerImpl::WillDraw(DrawMode draw_mode, | 66 bool ScrollbarLayerImpl::WillDraw(DrawMode draw_mode, |
77 ResourceProvider* resource_provider) { | 67 ResourceProvider* resource_provider) { |
78 if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE && | 68 DCHECK(draw_mode != DRAW_MODE_RESOURCELESS_SOFTWARE); |
79 !layer_tree_impl()->settings().solid_color_scrollbars) | |
80 return false; | |
81 return LayerImpl::WillDraw(draw_mode, resource_provider); | 69 return LayerImpl::WillDraw(draw_mode, resource_provider); |
82 } | 70 } |
83 | 71 |
84 void ScrollbarLayerImpl::AppendQuads(QuadSink* quad_sink, | 72 void ScrollbarLayerImpl::AppendQuads(QuadSink* quad_sink, |
85 AppendQuadsData* append_quads_data) { | 73 AppendQuadsData* append_quads_data) { |
86 bool premultipled_alpha = true; | 74 bool premultipled_alpha = true; |
87 bool flipped = false; | 75 bool flipped = false; |
88 gfx::PointF uv_top_left(0.f, 0.f); | 76 gfx::PointF uv_top_left(0.f, 0.f); |
89 gfx::PointF uv_bottom_right(1.f, 1.f); | 77 gfx::PointF uv_bottom_right(1.f, 1.f); |
90 gfx::Rect bounds_rect(bounds()); | 78 gfx::Rect bounds_rect(bounds()); |
91 gfx::Rect content_bounds_rect(content_bounds()); | 79 gfx::Rect content_bounds_rect(content_bounds()); |
92 | 80 |
93 SharedQuadState* shared_quad_state = | 81 SharedQuadState* shared_quad_state = |
94 quad_sink->UseSharedQuadState(CreateSharedQuadState()); | 82 quad_sink->UseSharedQuadState(CreateSharedQuadState()); |
95 AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data); | 83 AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data); |
96 | 84 |
97 gfx::Rect thumb_quad_rect = ComputeThumbQuadRect(); | 85 gfx::Rect thumb_quad_rect = ComputeThumbQuadRect(); |
98 | 86 |
99 if (layer_tree_impl()->settings().solid_color_scrollbars) { | |
100 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create(); | |
101 quad->SetNew(shared_quad_state, | |
102 thumb_quad_rect, | |
103 layer_tree_impl()->settings().solid_color_scrollbar_color, | |
104 false); | |
105 quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data); | |
106 return; | |
107 } | |
108 | |
109 ResourceProvider::ResourceId thumb_resource_id = | 87 ResourceProvider::ResourceId thumb_resource_id = |
110 layer_tree_impl()->ResourceIdForUIResource(thumb_ui_resource_id_); | 88 layer_tree_impl()->ResourceIdForUIResource(thumb_ui_resource_id_); |
111 ResourceProvider::ResourceId track_resource_id = | 89 ResourceProvider::ResourceId track_resource_id = |
112 layer_tree_impl()->ResourceIdForUIResource(track_ui_resource_id_); | 90 layer_tree_impl()->ResourceIdForUIResource(track_ui_resource_id_); |
113 | 91 |
114 if (thumb_resource_id && !thumb_quad_rect.IsEmpty()) { | 92 if (thumb_resource_id && !thumb_quad_rect.IsEmpty()) { |
115 gfx::Rect opaque_rect; | 93 gfx::Rect opaque_rect; |
116 const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; | 94 const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; |
117 scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); | 95 scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); |
118 quad->SetNew(shared_quad_state, | 96 quad->SetNew(shared_quad_state, |
(...skipping 21 matching lines...) Expand all Loading... |
140 premultipled_alpha, | 118 premultipled_alpha, |
141 uv_top_left, | 119 uv_top_left, |
142 uv_bottom_right, | 120 uv_bottom_right, |
143 SK_ColorTRANSPARENT, | 121 SK_ColorTRANSPARENT, |
144 opacity, | 122 opacity, |
145 flipped); | 123 flipped); |
146 quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data); | 124 quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data); |
147 } | 125 } |
148 } | 126 } |
149 | 127 |
150 ScrollbarOrientation ScrollbarLayerImpl::Orientation() const { | 128 void ScrollbarLayerImpl::DidLoseOutputSurface() { |
151 return orientation_; | 129 track_ui_resource_id_ = 0; |
| 130 thumb_ui_resource_id_ = 0; |
152 } | 131 } |
153 | 132 |
154 float ScrollbarLayerImpl::CurrentPos() const { | 133 const char* ScrollbarLayerImpl::LayerTypeAsString() const { |
155 return current_pos_; | 134 return "cc::ScrollbarLayerImpl"; |
156 } | 135 } |
157 | 136 |
158 int ScrollbarLayerImpl::Maximum() const { | 137 int ScrollbarLayerImpl::ThumbThickness() const { |
159 return maximum_; | 138 return thumb_thickness_; |
160 } | 139 } |
161 | 140 |
162 gfx::Rect ScrollbarLayerImpl::ScrollbarLayerRectToContentRect( | 141 int ScrollbarLayerImpl::ThumbLength() const { |
163 gfx::RectF layer_rect) const { | 142 return thumb_length_; |
164 // Don't intersect with the bounds as in layerRectToContentRect() because | |
165 // layer_rect here might be in coordinates of the containing layer. | |
166 gfx::RectF content_rect = gfx::ScaleRect(layer_rect, | |
167 contents_scale_x(), | |
168 contents_scale_y()); | |
169 return gfx::ToEnclosingRect(content_rect); | |
170 } | 143 } |
171 | 144 |
172 void ScrollbarLayerImpl::SetThumbThickness(int thumb_thickness) { | 145 void ScrollbarLayerImpl::SetThumbThickness(int thumb_thickness) { |
173 if (thumb_thickness_ == thumb_thickness) | 146 if (thumb_thickness_ == thumb_thickness) |
174 return; | 147 return; |
175 thumb_thickness_ = thumb_thickness; | 148 thumb_thickness_ = thumb_thickness; |
176 NoteLayerPropertyChanged(); | 149 NoteLayerPropertyChanged(); |
177 } | 150 } |
178 | 151 |
179 void ScrollbarLayerImpl::SetThumbLength(int thumb_length) { | 152 void ScrollbarLayerImpl::SetThumbLength(int thumb_length) { |
180 if (thumb_length_ == thumb_length) | 153 if (thumb_length_ == thumb_length) |
181 return; | 154 return; |
182 thumb_length_ = thumb_length; | 155 thumb_length_ = thumb_length; |
183 NoteLayerPropertyChanged(); | 156 NoteLayerPropertyChanged(); |
184 } | 157 } |
185 void ScrollbarLayerImpl::SetTrackStart(int track_start) { | 158 void ScrollbarLayerImpl::SetTrackStart(int track_start) { |
186 if (track_start_ == track_start) | 159 if (track_start_ == track_start) |
187 return; | 160 return; |
188 track_start_ = track_start; | 161 track_start_ = track_start; |
189 NoteLayerPropertyChanged(); | 162 NoteLayerPropertyChanged(); |
190 } | 163 } |
191 | 164 |
192 void ScrollbarLayerImpl::SetTrackLength(int track_length) { | 165 void ScrollbarLayerImpl::SetTrackLength(int track_length) { |
193 if (track_length_ == track_length) | 166 if (track_length_ == track_length) |
194 return; | 167 return; |
195 track_length_ = track_length; | 168 track_length_ = track_length; |
196 NoteLayerPropertyChanged(); | 169 NoteLayerPropertyChanged(); |
197 } | 170 } |
198 | 171 |
199 void ScrollbarLayerImpl::SetVerticalAdjust(float vertical_adjust) { | 172 float ScrollbarLayerImpl::TrackLength() const { |
200 if (vertical_adjust_ == vertical_adjust) | 173 return track_length_ + (orientation() == VERTICAL ? vertical_adjust() : 0); |
201 return; | |
202 vertical_adjust_ = vertical_adjust; | |
203 NoteLayerPropertyChanged(); | |
204 } | 174 } |
205 | 175 |
206 void ScrollbarLayerImpl::SetVisibleToTotalLengthRatio(float ratio) { | 176 int ScrollbarLayerImpl::TrackStart() const { |
207 if (visible_to_total_length_ratio_ == ratio) | 177 return track_start_; |
208 return; | |
209 visible_to_total_length_ratio_ = ratio; | |
210 NoteLayerPropertyChanged(); | |
211 } | |
212 | |
213 void ScrollbarLayerImpl::SetCurrentPos(float current_pos) { | |
214 if (current_pos_ == current_pos) | |
215 return; | |
216 current_pos_ = current_pos; | |
217 NoteLayerPropertyChanged(); | |
218 } | |
219 | |
220 void ScrollbarLayerImpl::SetMaximum(int maximum) { | |
221 if (maximum_ == maximum) | |
222 return; | |
223 maximum_ = maximum; | |
224 NoteLayerPropertyChanged(); | |
225 } | |
226 | |
227 gfx::Rect ScrollbarLayerImpl::ComputeThumbQuadRect() const { | |
228 // Thumb extent is the length of the thumb in the scrolling direction, thumb | |
229 // thickness is in the perpendicular direction. Here's an example of a | |
230 // horizontal scrollbar - inputs are above the scrollbar, computed values | |
231 // below: | |
232 // | |
233 // |<------------------- track_length_ ------------------->| | |
234 // | |
235 // |--| <-- start_offset | |
236 // | |
237 // +--+----------------------------+------------------+-------+--+ | |
238 // |<|| |##################| ||>| | |
239 // +--+----------------------------+------------------+-------+--+ | |
240 // | |
241 // |<- thumb_length ->| | |
242 // | |
243 // |<------- thumb_offset -------->| | |
244 // | |
245 // For painted, scrollbars, the length is fixed. For solid color scrollbars we | |
246 // have to compute it. The ratio of the thumb's length to the track's length | |
247 // is the same as that of the visible viewport to the total viewport, unless | |
248 // that would make the thumb's length less than its thickness. | |
249 // | |
250 // vertical_adjust_ is used when the layer geometry from the main thread is | |
251 // not in sync with what the user sees. For instance on Android scrolling the | |
252 // top bar controls out of view reveals more of the page content. We want the | |
253 // root layer scrollbars to reflect what the user sees even if we haven't | |
254 // received new layer geometry from the main thread. If the user has scrolled | |
255 // down by 50px and the initial viewport size was 950px the geometry would | |
256 // look something like this: | |
257 // | |
258 // vertical_adjust_ = 50, scroll position 0, visible ratios 99% | |
259 // Layer geometry: Desired thumb positions: | |
260 // +--------------------+-+ +----------------------+ <-- 0px | |
261 // | |v| | #| | |
262 // | |e| | #| | |
263 // | |r| | #| | |
264 // | |t| | #| | |
265 // | |i| | #| | |
266 // | |c| | #| | |
267 // | |a| | #| | |
268 // | |l| | #| | |
269 // | | | | #| | |
270 // | |l| | #| | |
271 // | |a| | #| | |
272 // | |y| | #| | |
273 // | |e| | #| | |
274 // | |r| | #| | |
275 // +--------------------+-+ | #| | |
276 // | horizontal layer | | | #| | |
277 // +--------------------+-+ | #| <-- 950px | |
278 // | | | #| | |
279 // | | |##################### | | |
280 // +----------------------+ +----------------------+ <-- 1000px | |
281 // | |
282 // The layer geometry is set up for a 950px tall viewport, but the user can | |
283 // actually see down to 1000px. Thus we have to move the quad for the | |
284 // horizontal scrollbar down by the vertical_adjust_ factor and lay the | |
285 // vertical thumb out on a track lengthed by the vertical_adjust_ factor. This | |
286 // means the quads may extend outside the layer's bounds. | |
287 | |
288 int thumb_length = thumb_length_; | |
289 float track_length = track_length_; | |
290 if (orientation_ == VERTICAL) | |
291 track_length += vertical_adjust_; | |
292 | |
293 if (layer_tree_impl()->settings().solid_color_scrollbars) { | |
294 thumb_length = std::max( | |
295 static_cast<int>(visible_to_total_length_ratio_ * track_length), | |
296 thumb_thickness_); | |
297 } | |
298 | |
299 // With the length known, we can compute the thumb's position. | |
300 float clamped_current_pos = | |
301 std::min(std::max(current_pos_, 0.f), static_cast<float>(maximum_)); | |
302 float ratio = clamped_current_pos / maximum_; | |
303 float max_offset = track_length - thumb_length; | |
304 int thumb_offset = static_cast<int>(ratio * max_offset) + track_start_; | |
305 | |
306 gfx::RectF thumb_rect; | |
307 if (orientation_ == HORIZONTAL) { | |
308 thumb_rect = gfx::RectF(thumb_offset, vertical_adjust_, | |
309 thumb_length, thumb_thickness_); | |
310 } else { | |
311 thumb_rect = gfx::RectF(0.f, thumb_offset, | |
312 thumb_thickness_, thumb_length); | |
313 } | |
314 | |
315 return ScrollbarLayerRectToContentRect(thumb_rect); | |
316 } | |
317 | |
318 const char* ScrollbarLayerImpl::LayerTypeAsString() const { | |
319 return "cc::ScrollbarLayerImpl"; | |
320 } | 178 } |
321 | 179 |
322 } // namespace cc | 180 } // namespace cc |
OLD | NEW |