| 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 |