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/pinch_zoom_scrollbars_manager.h" |
| 6 |
| 7 #include "cc/renderer.h" |
| 8 #include "skia/ext/platform_canvas.h" |
| 9 #include "ui/gfx/rect.h" |
| 10 |
| 11 using WebKit::WebRect; |
| 12 using WebKit::WebScrollbar; |
| 13 using WebKit::WebScrollbarThemeGeometry; |
| 14 |
| 15 namespace cc { |
| 16 |
| 17 scoped_ptr<PinchZoomScrollbarsManager> PinchZoomScrollbarsManager::create() |
| 18 { |
| 19 return make_scoped_ptr(new PinchZoomScrollbarsManager()); |
| 20 } |
| 21 |
| 22 PinchZoomScrollbarsManager::PinchZoomScrollbarsManager() |
| 23 : m_scrollbarVertical(this, WebKit::WebScrollbar::Vertical) |
| 24 , m_scrollbarHorizontal(this, WebKit::WebScrollbar::Horizontal) |
| 25 , m_pinchZoomScrollbarVertical(0) |
| 26 , m_pinchZoomScrollbarHorizontal(0) |
| 27 , m_viewportScale(1) |
| 28 , m_deviceScaleFactor(1) |
| 29 , m_enabled(false) |
| 30 { |
| 31 } |
| 32 |
| 33 PinchZoomScrollbarsManager::~PinchZoomScrollbarsManager() |
| 34 { |
| 35 } |
| 36 |
| 37 void PinchZoomScrollbarsManager::setScrollbarVertical(ScrollbarLayerImpl* scroll
bar) |
| 38 { |
| 39 if (m_pinchZoomScrollbarVertical == scrollbar) |
| 40 return; |
| 41 m_pinchZoomScrollbarVertical = scrollbar; |
| 42 if (m_pinchZoomScrollbarVertical) { |
| 43 m_pinchZoomScrollbarVertical->setScrollbarGeometry(PZScrollbarGeometry::
create(make_scoped_ptr(new ScrollbarThemeGeometry(this)).PassAs<WebScrollbarThem
eGeometry>(), this)); |
| 44 m_pinchZoomScrollbarVertical->setScrollbarData(&m_scrollbarVertical); |
| 45 } |
| 46 } |
| 47 |
| 48 void PinchZoomScrollbarsManager::setScrollbarHorizontal(ScrollbarLayerImpl* scro
llbar) |
| 49 { |
| 50 if (m_pinchZoomScrollbarHorizontal == scrollbar) |
| 51 return; |
| 52 |
| 53 m_pinchZoomScrollbarHorizontal = scrollbar; |
| 54 if (m_pinchZoomScrollbarHorizontal) { |
| 55 m_pinchZoomScrollbarHorizontal->setScrollbarGeometry(PZScrollbarGeometry
::create(make_scoped_ptr(new ScrollbarThemeGeometry(this)).PassAs<WebScrollbarTh
emeGeometry>(), this)); |
| 56 m_pinchZoomScrollbarHorizontal->setScrollbarData(&m_scrollbarHorizontal)
; |
| 57 } |
| 58 } |
| 59 |
| 60 scoped_ptr<ScrollbarGeometryFixedThumb> |
| 61 PinchZoomScrollbarsManager::PZScrollbarGeometry::create(scoped_ptr<WebKit::WebSc
rollbarThemeGeometry> theme, PinchZoomScrollbarsManager* owner) |
| 62 { |
| 63 return make_scoped_ptr(new PZScrollbarGeometry(theme.Pass(), owner)).PassAs<
ScrollbarGeometryFixedThumb>(); |
| 64 } |
| 65 |
| 66 PinchZoomScrollbarsManager::PZScrollbarGeometry::PZScrollbarGeometry(scoped_ptr<
WebKit::WebScrollbarThemeGeometry> theme, PinchZoomScrollbarsManager* owner) |
| 67 : ScrollbarGeometryFixedThumb(theme.Pass()) |
| 68 , m_owner(owner) |
| 69 { |
| 70 } |
| 71 |
| 72 PinchZoomScrollbarsManager::PZScrollbarGeometry::~PZScrollbarGeometry() |
| 73 { |
| 74 } |
| 75 |
| 76 WebKit::WebScrollbarThemeGeometry* PinchZoomScrollbarsManager::PZScrollbarGeomet
ry::clone() const |
| 77 { |
| 78 PZScrollbarGeometry* geometry = |
| 79 new PZScrollbarGeometry(make_scoped_ptr(ScrollbarGeometryFixedThumb::clo
ne()), m_owner); |
| 80 |
| 81 return geometry; |
| 82 } |
| 83 |
| 84 int PinchZoomScrollbarsManager::PZScrollbarGeometry::thumbLength(WebKit::WebScro
llbar* scrollbar) |
| 85 { |
| 86 return m_owner->thumbLength(scrollbar); |
| 87 } |
| 88 |
| 89 int PinchZoomScrollbarsManager::PZScrollbarGeometry::thumbPosition(WebKit::WebSc
rollbar* scrollbar) |
| 90 { |
| 91 return m_owner->position(scrollbar); |
| 92 } |
| 93 |
| 94 void PinchZoomScrollbarsManager::PZScrollbarGeometry::splitTrack(WebKit::WebScro
llbar* scrollbar, const WebKit::WebRect& track, WebKit::WebRect& startTrack, Web
Kit::WebRect& thumb, WebKit::WebRect& endTrack) |
| 95 { |
| 96 thumb = m_owner->thumbRect(scrollbar); |
| 97 // PinchZoomScrollbarsManager encodes the thumb positions in the thumbRect, |
| 98 // but callers to this function will expect a zero-offset rect. |
| 99 thumb.x = 0; |
| 100 thumb.y = 0; |
| 101 } |
| 102 |
| 103 bool PinchZoomScrollbarsManager::Scrollbar::isOverlay() const |
| 104 { |
| 105 return true; |
| 106 } |
| 107 |
| 108 int PinchZoomScrollbarsManager::Scrollbar::value() const |
| 109 { |
| 110 return m_owner->position(this); |
| 111 } |
| 112 |
| 113 WebKit::WebPoint PinchZoomScrollbarsManager::Scrollbar::location() const |
| 114 { |
| 115 WebRect rect = m_owner->trackRect(this); |
| 116 return WebKit::WebPoint(rect.x, rect.y); |
| 117 } |
| 118 |
| 119 WebKit::WebSize PinchZoomScrollbarsManager::Scrollbar::size() const |
| 120 { |
| 121 WebRect rect = m_owner->trackRect(this); |
| 122 return WebKit::WebSize(rect.width, rect.height); |
| 123 } |
| 124 |
| 125 bool PinchZoomScrollbarsManager::Scrollbar::enabled() const |
| 126 { |
| 127 return true; |
| 128 } |
| 129 |
| 130 int PinchZoomScrollbarsManager::Scrollbar::maximum() const |
| 131 { |
| 132 return m_owner->maximum(this); |
| 133 } |
| 134 |
| 135 int PinchZoomScrollbarsManager::Scrollbar::totalSize() const |
| 136 { |
| 137 return m_owner->trackLength(this); |
| 138 } |
| 139 |
| 140 bool PinchZoomScrollbarsManager::Scrollbar::isScrollViewScrollbar() const |
| 141 { |
| 142 return false; |
| 143 } |
| 144 |
| 145 bool PinchZoomScrollbarsManager::Scrollbar::isScrollableAreaActive() const |
| 146 { |
| 147 return true; |
| 148 } |
| 149 |
| 150 void PinchZoomScrollbarsManager::Scrollbar::getTickmarks(WebKit::WebVector<WebKi
t::WebRect>& tickmarks) const |
| 151 { |
| 152 // Our overlay pinch-zoom scroll bars do not have tick marks. |
| 153 } |
| 154 |
| 155 WebScrollbar::ScrollbarControlSize PinchZoomScrollbarsManager::Scrollbar::contro
lSize() const |
| 156 { |
| 157 return WebScrollbar::RegularScrollbar; |
| 158 } |
| 159 |
| 160 WebScrollbar::ScrollbarPart PinchZoomScrollbarsManager::Scrollbar::pressedPart()
const |
| 161 { |
| 162 return WebScrollbar::NoPart; |
| 163 } |
| 164 |
| 165 WebScrollbar::ScrollbarPart PinchZoomScrollbarsManager::Scrollbar::hoveredPart()
const |
| 166 { |
| 167 return WebScrollbar::NoPart; |
| 168 } |
| 169 |
| 170 WebScrollbar::ScrollbarOverlayStyle PinchZoomScrollbarsManager::Scrollbar::scrol
lbarOverlayStyle() const |
| 171 { |
| 172 return WebScrollbar::ScrollbarOverlayStyleDefault; |
| 173 } |
| 174 |
| 175 WebScrollbar::Orientation PinchZoomScrollbarsManager::Scrollbar::orientation() c
onst |
| 176 { |
| 177 return m_orientation; |
| 178 } |
| 179 |
| 180 bool PinchZoomScrollbarsManager::Scrollbar::isCustomScrollbar() const |
| 181 { |
| 182 return true; |
| 183 } |
| 184 |
| 185 WebScrollbarThemeGeometry* PinchZoomScrollbarsManager::ScrollbarThemeGeometry::c
lone() const |
| 186 { |
| 187 return new ScrollbarThemeGeometry(m_owner); |
| 188 } |
| 189 |
| 190 int PinchZoomScrollbarsManager::ScrollbarThemeGeometry::thumbPosition(WebScrollb
ar* scrollbar) |
| 191 { |
| 192 return m_owner->position(scrollbar); |
| 193 } |
| 194 |
| 195 int PinchZoomScrollbarsManager::ScrollbarThemeGeometry::thumbLength(WebScrollbar
* scrollbar) |
| 196 { |
| 197 return m_owner->thumbLength(scrollbar); |
| 198 } |
| 199 |
| 200 int PinchZoomScrollbarsManager::ScrollbarThemeGeometry::trackPosition(WebScrollb
ar*) |
| 201 { |
| 202 return 0; |
| 203 } |
| 204 |
| 205 int PinchZoomScrollbarsManager::ScrollbarThemeGeometry::trackLength(WebScrollbar
*) |
| 206 { |
| 207 return 0; |
| 208 } |
| 209 |
| 210 bool PinchZoomScrollbarsManager::ScrollbarThemeGeometry::hasButtons(WebScrollbar
*) |
| 211 { |
| 212 return false; |
| 213 } |
| 214 |
| 215 bool PinchZoomScrollbarsManager::ScrollbarThemeGeometry::hasThumb(WebScrollbar*) |
| 216 { |
| 217 return true; |
| 218 } |
| 219 |
| 220 WebRect PinchZoomScrollbarsManager::ScrollbarThemeGeometry::trackRect(WebScrollb
ar* scrollbar) |
| 221 { |
| 222 return m_owner->trackRect(scrollbar); |
| 223 } |
| 224 |
| 225 WebRect PinchZoomScrollbarsManager::thumbRect(const WebScrollbar* scrollbar) con
st |
| 226 { |
| 227 WebRect rect; |
| 228 if (scrollbar->orientation() == WebScrollbar::Vertical) { |
| 229 rect = gfx::Rect(m_layoutViewportSize.width() - trackWidth(), position(s
crollbar), trackWidth(), thumbLength(scrollbar)); |
| 230 } else { |
| 231 rect = gfx::Rect(position(scrollbar), m_layoutViewportSize.height() - tr
ackWidth(), thumbLength(scrollbar), trackWidth()); |
| 232 } |
| 233 return rect; |
| 234 } |
| 235 |
| 236 WebRect PinchZoomScrollbarsManager::trackRect(const WebScrollbar* scrollbar) con
st |
| 237 { |
| 238 if (scrollbar->orientation() == WebScrollbar::Vertical) |
| 239 return WebRect(m_layoutViewportSize.width() - trackWidth(), 0, trackWidt
h(), m_layoutViewportSize.height()); |
| 240 else |
| 241 return WebRect(0, m_layoutViewportSize.height() - trackWidth(), m_layout
ViewportSize.width(), trackWidth()); |
| 242 } |
| 243 |
| 244 int PinchZoomScrollbarsManager::thumbLength(const WebScrollbar* scrollbar) const |
| 245 { |
| 246 if (scrollbar->orientation() == WebScrollbar::Vertical) { |
| 247 float thumbFraction = static_cast<float>(m_layoutViewportSize.height()) |
| 248 / m_layoutDocumentSize.height() * m_deviceScaleF
actor; |
| 249 return thumbFraction * trackLength(scrollbar); |
| 250 } else { |
| 251 float thumbFraction = static_cast<float>(m_layoutViewportSize.width()) |
| 252 / m_layoutDocumentSize.width() * m_deviceScal
eFactor; |
| 253 return thumbFraction * trackLength(scrollbar); |
| 254 } |
| 255 } |
| 256 |
| 257 int PinchZoomScrollbarsManager::trackLength(const WebScrollbar* scrollbar) const |
| 258 { |
| 259 if (scrollbar->orientation() == WebScrollbar::Vertical) |
| 260 return m_layoutViewportSize.height() - trackWidth(); |
| 261 else |
| 262 return m_layoutViewportSize.width() - trackWidth(); |
| 263 } |
| 264 |
| 265 int PinchZoomScrollbarsManager::position(const WebScrollbar* scrollbar) const |
| 266 { |
| 267 if (scrollbar->orientation() == WebScrollbar::Vertical) { |
| 268 float maxOffset = m_rootMaxScrollOffset.y() + (m_viewportScale - 1) / m_
viewportScale * m_layoutViewportSize.height(); |
| 269 if (maxOffset < 1) |
| 270 return 0; |
| 271 |
| 272 float offset = m_rootScrollOffset.y() + m_layoutViewportPosition.y(); |
| 273 int scrollPosition = offset / maxOffset * maximum(scrollbar); |
| 274 return scrollPosition; |
| 275 } else { |
| 276 float maxOffset = m_rootMaxScrollOffset.x() + (m_viewportScale - 1) / m_
viewportScale * m_layoutViewportSize.width(); |
| 277 if (maxOffset < 1) |
| 278 return 0; |
| 279 |
| 280 float offset = m_rootScrollOffset.x() + m_layoutViewportPosition.x(); |
| 281 int scrollPosition = offset / maxOffset * maximum(scrollbar); |
| 282 return scrollPosition; |
| 283 } |
| 284 } |
| 285 |
| 286 int PinchZoomScrollbarsManager::maximum(const WebScrollbar* scrollbar) const |
| 287 { |
| 288 return trackLength(scrollbar) - thumbLength(scrollbar); |
| 289 } |
| 290 |
| 291 WebRect PinchZoomScrollbarsManager::ScrollbarThemeGeometry::thumbRect(WebScrollb
ar* scrollbar) |
| 292 { |
| 293 return m_owner->thumbRect(scrollbar); |
| 294 } |
| 295 |
| 296 int PinchZoomScrollbarsManager::ScrollbarThemeGeometry::minimumThumbLength(WebSc
rollbar*) |
| 297 { |
| 298 return 0; |
| 299 } |
| 300 |
| 301 int PinchZoomScrollbarsManager::ScrollbarThemeGeometry::scrollbarThickness(WebSc
rollbar*) |
| 302 { |
| 303 return 0; |
| 304 } |
| 305 |
| 306 WebRect PinchZoomScrollbarsManager::ScrollbarThemeGeometry::backButtonStartRect(
WebScrollbar*) |
| 307 { |
| 308 return WebRect(); |
| 309 } |
| 310 |
| 311 WebRect PinchZoomScrollbarsManager::ScrollbarThemeGeometry::backButtonEndRect(We
bScrollbar*) |
| 312 { |
| 313 return WebRect(); |
| 314 } |
| 315 |
| 316 WebRect PinchZoomScrollbarsManager::ScrollbarThemeGeometry::forwardButtonStartRe
ct(WebScrollbar*) |
| 317 { |
| 318 return WebRect(); |
| 319 } |
| 320 |
| 321 WebRect PinchZoomScrollbarsManager::ScrollbarThemeGeometry::forwardButtonEndRect
(WebScrollbar*) |
| 322 { |
| 323 return WebRect(); |
| 324 } |
| 325 |
| 326 WebRect PinchZoomScrollbarsManager::ScrollbarThemeGeometry::constrainTrackRectTo
TrackPieces(WebScrollbar*, const WebRect&) |
| 327 { |
| 328 return WebRect(); |
| 329 } |
| 330 |
| 331 void PinchZoomScrollbarsManager::ScrollbarThemeGeometry::splitTrack(WebScrollbar
* scrollbar, const WebRect& track, WebRect& startTrack, WebRect& thumb, WebRect&
endTrack) |
| 332 { |
| 333 NOTREACHED() << "This call is supposed to be overridden by PZScrollbarGeomet
ry."; |
| 334 } |
| 335 |
| 336 void allocateTextureResourceIfNeeded(scoped_ptr<ScopedResource>& texture, const
gfx::Size& size, ResourceProvider* resourceProvider) |
| 337 { |
| 338 if (!texture) |
| 339 texture = ScopedResource::create(resourceProvider); |
| 340 |
| 341 if (texture->size() != size) |
| 342 texture->Free(); |
| 343 |
| 344 if (!texture->id()) |
| 345 texture->Allocate(Renderer::ImplPool, size, GL_RGBA, ResourceProvider::T
extureUsageAny); |
| 346 } |
| 347 |
| 348 void PinchZoomScrollbarsManager::updateOneThumb(ScrollbarLayerImpl* scrollbarImp
l, |
| 349 Scrollbar& scrollbar, |
| 350 scoped_ptr<ScopedResource>& thumbTexture, |
| 351 scoped_ptr<SkCanvas>& thumbCanvas, |
| 352 ResourceProvider* resourceProvider) |
| 353 { |
| 354 gfx::Rect thumbRect = this->thumbRect(&scrollbar); |
| 355 thumbRect = gfx::Rect(thumbRect.width() * m_deviceScaleFactor, thumbRect.hei
ght() * m_deviceScaleFactor); |
| 356 |
| 357 allocateTextureResourceIfNeeded(thumbTexture, thumbRect.size(), resourceProv
ider); |
| 358 scrollbarImpl->setThumbResourceId(thumbTexture->id()); |
| 359 |
| 360 SkISize canvasSize; |
| 361 if (thumbCanvas) |
| 362 canvasSize = thumbCanvas->getDeviceSize(); |
| 363 else |
| 364 canvasSize.set(0, 0); |
| 365 |
| 366 if (canvasSize.fWidth == thumbRect.width() && canvasSize.fHeight == thumbRec
t.height() && thumbCanvas) |
| 367 return; |
| 368 |
| 369 thumbCanvas = make_scoped_ptr(skia::CreateBitmapCanvas(thumbRect.width(), th
umbRect.height(), false /* opaque */)); |
| 370 |
| 371 thumbCanvas->clear(SkColorSetARGB(0, 0, 0, 0)); |
| 372 SkPaint paint; |
| 373 // WJM: the 255 below refers to blue, not red, but I haven't applied a swizz
le. |
| 374 paint.setColor(SkColorSetARGB(128, 255, 0, 0)); |
| 375 SkScalar border = m_deviceScaleFactor; |
| 376 SkScalar cornerRadius = m_deviceScaleFactor * 5; |
| 377 |
| 378 SkRect rect = SkRect::MakeXYWH(border, border, |
| 379 thumbRect.width() - 2 * border, |
| 380 thumbRect.height() - 2 * border); |
| 381 thumbCanvas->drawRoundRect(rect, cornerRadius, cornerRadius, paint); |
| 382 |
| 383 const SkBitmap* bitmap = &thumbCanvas->getDevice()->accessBitmap(false); |
| 384 SkAutoLockPixels locker(*bitmap); |
| 385 gfx::Rect layerRect(gfx::Point(), thumbRect.size()); |
| 386 DCHECK(bitmap->config() == SkBitmap::kARGB_8888_Config); |
| 387 resourceProvider->setPixels(thumbTexture->id(), static_cast<const uint8_t*>(
bitmap->getPixels()), layerRect, layerRect, gfx::Vector2d()); |
| 388 } |
| 389 |
| 390 void PinchZoomScrollbarsManager::updateThumbTextures(ResourceProvider* resourceP
rovider) |
| 391 { |
| 392 if (m_pinchZoomScrollbarVertical) |
| 393 updateOneThumb(m_pinchZoomScrollbarVertical, m_scrollbarVertical, m_vert
icalThumbTexture, |
| 394 m_verticalThumbCanvas, resourceProvider); |
| 395 if (m_pinchZoomScrollbarHorizontal) |
| 396 updateOneThumb(m_pinchZoomScrollbarHorizontal, m_scrollbarHorizontal, m_
horizontalThumbTexture, |
| 397 m_horizontalThumbCanvas, resourceProvider); |
| 398 } |
| 399 |
| 400 void PinchZoomScrollbarsManager::updateScrollbarImpl(ScrollbarLayerImpl* scrollb
arLayerImpl, |
| 401 WebScrollbar* scrollbar) |
| 402 { |
| 403 if (!scrollbarLayerImpl || !scrollbar) |
| 404 return; |
| 405 |
| 406 scrollbarLayerImpl->setCurrentPos(scrollbar->value()); |
| 407 scrollbarLayerImpl->setMaximum(scrollbar->maximum()); |
| 408 scrollbarLayerImpl->setTotalSize(scrollbar->totalSize()); |
| 409 WebRect rect = thumbRect(scrollbar); |
| 410 scrollbarLayerImpl->setPosition(gfx::PointF(rect.x, rect.y)); |
| 411 scrollbarLayerImpl->setBounds(gfx::Size(rect.width, rect.height)); |
| 412 scrollbarLayerImpl->setContentBounds(gfx::Size(rect.width, rect.height)); |
| 413 scrollbarLayerImpl->setDrawsContent(m_enabled); |
| 414 } |
| 415 |
| 416 void PinchZoomScrollbarsManager::setContentBounds(const gfx::Size& size) |
| 417 { |
| 418 m_layoutDocumentSize = size; |
| 419 updateScrollbarImpl(m_pinchZoomScrollbarVertical, &m_scrollbarVertical); |
| 420 updateScrollbarImpl(m_pinchZoomScrollbarHorizontal, &m_scrollbarHorizontal); |
| 421 } |
| 422 |
| 423 void PinchZoomScrollbarsManager::setPinchZoomViewportPosition(const gfx::Vector2
dF& location, float scale) |
| 424 { |
| 425 m_layoutViewportPosition = location; |
| 426 m_viewportScale = scale; |
| 427 updateScrollbarImpl(m_pinchZoomScrollbarVertical, &m_scrollbarVertical); |
| 428 updateScrollbarImpl(m_pinchZoomScrollbarHorizontal, &m_scrollbarHorizontal); |
| 429 } |
| 430 |
| 431 void PinchZoomScrollbarsManager::setPinchZoomViewportBounds(const gfx::Size& siz
e) |
| 432 { |
| 433 m_layoutViewportSize = size; |
| 434 updateScrollbarImpl(m_pinchZoomScrollbarVertical, &m_scrollbarVertical); |
| 435 updateScrollbarImpl(m_pinchZoomScrollbarHorizontal, &m_scrollbarHorizontal); |
| 436 } |
| 437 |
| 438 void PinchZoomScrollbarsManager::setRootScrollLayerOffset(const gfx::Vector2d& o
ffset, const gfx::Vector2d& maxOffset) |
| 439 { |
| 440 m_rootScrollOffset = offset; |
| 441 m_rootMaxScrollOffset = maxOffset; |
| 442 updateScrollbarImpl(m_pinchZoomScrollbarVertical, &m_scrollbarVertical); |
| 443 updateScrollbarImpl(m_pinchZoomScrollbarHorizontal, &m_scrollbarHorizontal); |
| 444 } |
| 445 |
| 446 } |
OLD | NEW |