OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "cc/scrollbar_layer_impl.h" | |
6 | |
7 #include "cc/animation/scrollbar_animation_controller.h" | |
8 #include "cc/layer.h" | |
9 #include "cc/quad_sink.h" | |
10 #include "cc/quads/solid_color_draw_quad.h" | |
11 #include "cc/quads/texture_draw_quad.h" | |
12 #include "cc/trees/layer_tree_impl.h" | |
13 #include "cc/trees/layer_tree_settings.h" | |
14 #include "ui/gfx/rect_conversions.h" | |
15 | |
16 using WebKit::WebRect; | |
17 using WebKit::WebScrollbar; | |
18 | |
19 namespace cc { | |
20 | |
21 scoped_ptr<ScrollbarLayerImpl> ScrollbarLayerImpl::Create( | |
22 LayerTreeImpl* tree_impl, | |
23 int id, | |
24 scoped_ptr<ScrollbarGeometryFixedThumb> geometry) { | |
25 return make_scoped_ptr(new ScrollbarLayerImpl(tree_impl, | |
26 id, | |
27 geometry.Pass())); | |
28 } | |
29 | |
30 ScrollbarLayerImpl::ScrollbarLayerImpl( | |
31 LayerTreeImpl* tree_impl, | |
32 int id, | |
33 scoped_ptr<ScrollbarGeometryFixedThumb> geometry) | |
34 : ScrollbarLayerImplBase(tree_impl, id), | |
35 scrollbar_(this), | |
36 back_track_resource_id_(0), | |
37 fore_track_resource_id_(0), | |
38 thumb_resource_id_(0), | |
39 geometry_(geometry.Pass()), | |
40 current_pos_(0), | |
41 total_size_(0), | |
42 maximum_(0), | |
43 vertical_adjust_(0.f), | |
44 scroll_layer_id_(Layer::INVALID_ID), | |
45 scrollbar_overlay_style_(WebScrollbar::ScrollbarOverlayStyleDefault), | |
46 orientation_(WebScrollbar::Horizontal), | |
47 control_size_(WebScrollbar::RegularScrollbar), | |
48 pressed_part_(WebScrollbar::NoPart), | |
49 hovered_part_(WebScrollbar::NoPart), | |
50 is_scrollable_area_active_(false), | |
51 is_scroll_view_scrollbar_(false), | |
52 enabled_(false), | |
53 is_custom_scrollbar_(false), | |
54 is_overlay_scrollbar_(false) {} | |
55 | |
56 ScrollbarLayerImpl::~ScrollbarLayerImpl() {} | |
57 | |
58 ScrollbarLayerImpl* ScrollbarLayerImpl::ToScrollbarLayer() { | |
59 return this; | |
60 } | |
61 | |
62 void ScrollbarLayerImpl::SetScrollbarData(WebScrollbar* scrollbar) { | |
63 scrollbar_overlay_style_ = scrollbar->scrollbarOverlayStyle(); | |
64 orientation_ = scrollbar->orientation(); | |
65 control_size_ = scrollbar->controlSize(); | |
66 pressed_part_ = scrollbar->pressedPart(); | |
67 hovered_part_ = scrollbar->hoveredPart(); | |
68 is_scrollable_area_active_ = scrollbar->isScrollableAreaActive(); | |
69 is_scroll_view_scrollbar_ = scrollbar->isScrollViewScrollbar(); | |
70 enabled_ = scrollbar->enabled(); | |
71 is_custom_scrollbar_ = scrollbar->isCustomScrollbar(); | |
72 is_overlay_scrollbar_ = scrollbar->isOverlay(); | |
73 | |
74 scrollbar->getTickmarks(tickmarks_); | |
75 } | |
76 | |
77 void ScrollbarLayerImpl::SetThumbSize(gfx::Size size) { | |
78 thumb_size_ = size; | |
79 if (!geometry_) { | |
80 // In impl-side painting, the ScrollbarLayerImpl in the pending tree | |
81 // simply holds properties that are later pushed to the active tree's | |
82 // layer, but it doesn't hold geometry or append quads. | |
83 DCHECK(layer_tree_impl()->IsPendingTree()); | |
84 return; | |
85 } | |
86 geometry_->setThumbSize(size); | |
87 } | |
88 | |
89 void ScrollbarLayerImpl::SetViewportWithinScrollableArea( | |
90 gfx::RectF scrollable_viewport, gfx::SizeF scrollable_area) { | |
91 normalized_viewport_ = gfx::RectF( | |
92 scrollable_viewport.x() / scrollable_area.width(), | |
93 scrollable_viewport.y() / scrollable_area.height(), | |
94 scrollable_viewport.width() / scrollable_area.width(), | |
95 scrollable_viewport.height() / scrollable_area.height()); | |
96 } | |
97 | |
98 float ScrollbarLayerImpl::CurrentPos() const { | |
99 return current_pos_; | |
100 } | |
101 | |
102 int ScrollbarLayerImpl::TotalSize() const { | |
103 return total_size_; | |
104 } | |
105 | |
106 int ScrollbarLayerImpl::Maximum() const { | |
107 return maximum_; | |
108 } | |
109 | |
110 WebKit::WebScrollbar::Orientation ScrollbarLayerImpl::Orientation() const { | |
111 return orientation_; | |
112 } | |
113 | |
114 static gfx::RectF ToUVRect(gfx::Rect r, gfx::Rect bounds) { | |
115 return gfx::ScaleRect(r, 1.f / bounds.width(), 1.f / bounds.height()); | |
116 } | |
117 | |
118 gfx::Rect ScrollbarLayerImpl::ScrollbarLayerRectToContentRect( | |
119 gfx::RectF layer_rect) const { | |
120 // Don't intersect with the bounds as in layerRectToContentRect() because | |
121 // layer_rect here might be in coordinates of the containing layer. | |
122 gfx::RectF content_rect = gfx::ScaleRect(layer_rect, | |
123 contents_scale_x(), | |
124 contents_scale_y()); | |
125 return gfx::ToEnclosingRect(content_rect); | |
126 } | |
127 | |
128 scoped_ptr<LayerImpl> ScrollbarLayerImpl::CreateLayerImpl( | |
129 LayerTreeImpl* tree_impl) { | |
130 return ScrollbarLayerImpl::Create(tree_impl, | |
131 id(), | |
132 geometry_.Pass()).PassAs<LayerImpl>(); | |
133 } | |
134 | |
135 void ScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) { | |
136 LayerImpl::PushPropertiesTo(layer); | |
137 | |
138 ScrollbarLayerImpl* scrollbar_layer = static_cast<ScrollbarLayerImpl*>(layer); | |
139 | |
140 scrollbar_layer->SetScrollbarData(&scrollbar_); | |
141 scrollbar_layer->SetThumbSize(thumb_size_); | |
142 | |
143 scrollbar_layer->set_back_track_resource_id(back_track_resource_id_); | |
144 scrollbar_layer->set_fore_track_resource_id(fore_track_resource_id_); | |
145 scrollbar_layer->set_thumb_resource_id(thumb_resource_id_); | |
146 } | |
147 | |
148 void ScrollbarLayerImpl::AppendQuads(QuadSink* quad_sink, | |
149 AppendQuadsData* append_quads_data) { | |
150 bool premultipled_alpha = true; | |
151 bool flipped = false; | |
152 gfx::PointF uv_top_left(0.f, 0.f); | |
153 gfx::PointF uv_bottom_right(1.f, 1.f); | |
154 gfx::Rect boundsRect(bounds()); | |
155 gfx::Rect contentBoundsRect(content_bounds()); | |
156 | |
157 SharedQuadState* shared_quad_state = | |
158 quad_sink->UseSharedQuadState(CreateSharedQuadState()); | |
159 AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data); | |
160 | |
161 if (layer_tree_impl()->settings().solidColorScrollbars) { | |
162 gfx::Rect track_rect = geometry_->trackRect(&scrollbar_); | |
163 int thickness_override = | |
164 layer_tree_impl()->settings().solidColorScrollbarThicknessDIP; | |
165 gfx::RectF thumb_rect; | |
166 if (scrollbar_.orientation() == WebScrollbar::Horizontal) { | |
167 track_rect.set_y(track_rect.y() + vertical_adjust_); | |
168 thumb_rect = gfx::RectF(track_rect.x() + | |
169 (normalized_viewport_.x() * track_rect.width()), | |
170 track_rect.y(), | |
171 normalized_viewport_.width() * track_rect.width(), | |
172 track_rect.height()); | |
173 if (thickness_override != -1) | |
174 thumb_rect.set_height(thickness_override); | |
175 } else { | |
176 track_rect.set_height(track_rect.height() + vertical_adjust_); | |
177 thumb_rect = gfx::RectF( | |
178 track_rect.x(), | |
179 track_rect.y() + (normalized_viewport_.y() * track_rect.height()), | |
180 track_rect.width(), | |
181 normalized_viewport_.height() * track_rect.height()); | |
182 if (thickness_override != -1) | |
183 thumb_rect.set_width(thickness_override); | |
184 } | |
185 gfx::Rect quad_rect(ScrollbarLayerRectToContentRect(thumb_rect)); | |
186 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create(); | |
187 quad->SetNew(shared_quad_state, | |
188 quad_rect, | |
189 layer_tree_impl()->settings().solidColorScrollbarColor); | |
190 quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data); | |
191 return; | |
192 } | |
193 | |
194 WebRect thumb_rect, back_track_rect, foreTrackRect; | |
195 geometry_->splitTrack(&scrollbar_, | |
196 geometry_->trackRect(&scrollbar_), | |
197 back_track_rect, | |
198 thumb_rect, | |
199 foreTrackRect); | |
200 if (!geometry_->hasThumb(&scrollbar_)) | |
201 thumb_rect = WebRect(); | |
202 | |
203 if (thumb_resource_id_ && !thumb_rect.isEmpty()) { | |
204 gfx::Rect quad_rect(ScrollbarLayerRectToContentRect(gfx::Rect(thumb_rect))); | |
205 gfx::Rect opaque_rect; | |
206 const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; | |
207 scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); | |
208 quad->SetNew(shared_quad_state, | |
209 quad_rect, | |
210 opaque_rect, | |
211 thumb_resource_id_, | |
212 premultipled_alpha, | |
213 uv_top_left, | |
214 uv_bottom_right, | |
215 opacity, | |
216 flipped); | |
217 quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data); | |
218 } | |
219 | |
220 if (!back_track_resource_id_) | |
221 return; | |
222 | |
223 // We only paint the track in two parts if we were given a texture for the | |
224 // forward track part. | |
225 if (fore_track_resource_id_ && !foreTrackRect.isEmpty()) { | |
226 gfx::Rect quad_rect(ScrollbarLayerRectToContentRect( | |
227 gfx::Rect(foreTrackRect))); | |
228 gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect()); | |
229 gfx::RectF uv_rect(ToUVRect(foreTrackRect, boundsRect)); | |
230 const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; | |
231 scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); | |
232 quad->SetNew(shared_quad_state, | |
233 quad_rect, | |
234 opaque_rect, | |
235 fore_track_resource_id_, | |
236 premultipled_alpha, | |
237 uv_rect.origin(), | |
238 uv_rect.bottom_right(), | |
239 opacity, | |
240 flipped); | |
241 quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data); | |
242 } | |
243 | |
244 // Order matters here: since the back track texture is being drawn to the | |
245 // entire contents rect, we must append it after the thumb and fore track | |
246 // quads. The back track texture contains (and displays) the buttons. | |
247 if (!contentBoundsRect.IsEmpty()) { | |
248 gfx::Rect quad_rect(contentBoundsRect); | |
249 gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect()); | |
250 const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; | |
251 scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); | |
252 quad->SetNew(shared_quad_state, | |
253 quad_rect, | |
254 opaque_rect, | |
255 back_track_resource_id_, | |
256 premultipled_alpha, | |
257 uv_top_left, | |
258 uv_bottom_right, | |
259 opacity, | |
260 flipped); | |
261 quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data); | |
262 } | |
263 } | |
264 | |
265 void ScrollbarLayerImpl::DidLoseOutputSurface() { | |
266 back_track_resource_id_ = 0; | |
267 fore_track_resource_id_ = 0; | |
268 thumb_resource_id_ = 0; | |
269 } | |
270 | |
271 bool ScrollbarLayerImpl::Scrollbar::isOverlay() const { | |
272 return owner_->is_overlay_scrollbar_; | |
273 } | |
274 | |
275 int ScrollbarLayerImpl::Scrollbar::value() const { | |
276 return owner_->CurrentPos(); | |
277 } | |
278 | |
279 WebKit::WebPoint ScrollbarLayerImpl::Scrollbar::location() const { | |
280 return WebKit::WebPoint(); | |
281 } | |
282 | |
283 WebKit::WebSize ScrollbarLayerImpl::Scrollbar::size() const { | |
284 return WebKit::WebSize(owner_->bounds().width(), owner_->bounds().height()); | |
285 } | |
286 | |
287 bool ScrollbarLayerImpl::Scrollbar::enabled() const { | |
288 return owner_->enabled_; | |
289 } | |
290 | |
291 int ScrollbarLayerImpl::Scrollbar::maximum() const { | |
292 return owner_->Maximum(); | |
293 } | |
294 | |
295 int ScrollbarLayerImpl::Scrollbar::totalSize() const { | |
296 return owner_->TotalSize(); | |
297 } | |
298 | |
299 bool ScrollbarLayerImpl::Scrollbar::isScrollViewScrollbar() const { | |
300 return owner_->is_scroll_view_scrollbar_; | |
301 } | |
302 | |
303 bool ScrollbarLayerImpl::Scrollbar::isScrollableAreaActive() const { | |
304 return owner_->is_scrollable_area_active_; | |
305 } | |
306 | |
307 void ScrollbarLayerImpl::Scrollbar::getTickmarks( | |
308 WebKit::WebVector<WebRect>& tickmarks) const { | |
309 tickmarks = owner_->tickmarks_; | |
310 } | |
311 | |
312 WebScrollbar::ScrollbarControlSize ScrollbarLayerImpl::Scrollbar::controlSize() | |
313 const { | |
314 return owner_->control_size_; | |
315 } | |
316 | |
317 WebScrollbar::ScrollbarPart ScrollbarLayerImpl::Scrollbar::pressedPart() const { | |
318 return owner_->pressed_part_; | |
319 } | |
320 | |
321 WebScrollbar::ScrollbarPart ScrollbarLayerImpl::Scrollbar::hoveredPart() const { | |
322 return owner_->hovered_part_; | |
323 } | |
324 | |
325 WebScrollbar::ScrollbarOverlayStyle | |
326 ScrollbarLayerImpl::Scrollbar::scrollbarOverlayStyle() const { | |
327 return owner_->scrollbar_overlay_style_; | |
328 } | |
329 | |
330 WebScrollbar::Orientation ScrollbarLayerImpl::Scrollbar::orientation() const { | |
331 return owner_->orientation_; | |
332 } | |
333 | |
334 bool ScrollbarLayerImpl::Scrollbar::isCustomScrollbar() const { | |
335 return owner_->is_custom_scrollbar_; | |
336 } | |
337 | |
338 const char* ScrollbarLayerImpl::LayerTypeAsString() const { | |
339 return "ScrollbarLayer"; | |
340 } | |
341 | |
342 } // namespace cc | |
OLD | NEW |