| // Copyright 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "cc/scrollbar_layer_impl.h" |
| |
| #include "cc/layer_tree_impl.h" |
| #include "cc/layer_tree_settings.h" |
| #include "cc/quad_sink.h" |
| #include "cc/scrollbar_animation_controller.h" |
| #include "cc/solid_color_draw_quad.h" |
| #include "cc/texture_draw_quad.h" |
| #include "ui/gfx/rect_conversions.h" |
| |
| using WebKit::WebRect; |
| using WebKit::WebScrollbar; |
| |
| namespace cc { |
| |
| scoped_ptr<ScrollbarLayerImpl> ScrollbarLayerImpl::create(LayerTreeImpl* treeImpl, int id, scoped_ptr<ScrollbarGeometryFixedThumb> geometry) |
| { |
| return make_scoped_ptr(new ScrollbarLayerImpl(treeImpl, id, geometry.Pass())); |
| } |
| |
| ScrollbarLayerImpl::ScrollbarLayerImpl(LayerTreeImpl* treeImpl, int id, scoped_ptr<ScrollbarGeometryFixedThumb> geometry) |
| : ScrollbarLayerImplBase(treeImpl, id) |
| , m_scrollbar(this) |
| , m_backTrackResourceId(0) |
| , m_foreTrackResourceId(0) |
| , m_thumbResourceId(0) |
| , m_geometry(geometry.Pass()) |
| , m_currentPos(0) |
| , m_totalSize(0) |
| , m_maximum(0) |
| , m_scrollLayerId(-1) |
| , m_scrollbarOverlayStyle(WebScrollbar::ScrollbarOverlayStyleDefault) |
| , m_orientation(WebScrollbar::Horizontal) |
| , m_controlSize(WebScrollbar::RegularScrollbar) |
| , m_pressedPart(WebScrollbar::NoPart) |
| , m_hoveredPart(WebScrollbar::NoPart) |
| , m_isScrollableAreaActive(false) |
| , m_isScrollViewScrollbar(false) |
| , m_enabled(false) |
| , m_isCustomScrollbar(false) |
| , m_isOverlayScrollbar(false) |
| { |
| } |
| |
| ScrollbarLayerImpl::~ScrollbarLayerImpl() |
| { |
| } |
| |
| ScrollbarLayerImpl* ScrollbarLayerImpl::toScrollbarLayer() |
| { |
| return this; |
| } |
| |
| void ScrollbarLayerImpl::setScrollbarData(WebScrollbar* scrollbar) |
| { |
| m_scrollbarOverlayStyle = scrollbar->scrollbarOverlayStyle(); |
| m_orientation = scrollbar->orientation(); |
| m_controlSize = scrollbar->controlSize(); |
| m_pressedPart = scrollbar->pressedPart(); |
| m_hoveredPart = scrollbar->hoveredPart(); |
| m_isScrollableAreaActive = scrollbar->isScrollableAreaActive(); |
| m_isScrollViewScrollbar = scrollbar->isScrollViewScrollbar(); |
| m_enabled = scrollbar->enabled(); |
| m_isCustomScrollbar = scrollbar->isCustomScrollbar(); |
| m_isOverlayScrollbar = scrollbar->isOverlay(); |
| |
| scrollbar->getTickmarks(m_tickmarks); |
| } |
| |
| void ScrollbarLayerImpl::setThumbSize(gfx::Size size) |
| { |
| m_thumbSize = size; |
| if (!m_geometry) { |
| // In impl-side painting, the ScrollbarLayerImpl in the pending tree |
| // simply holds properties that are later pushed to the active tree's |
| // layer, but it doesn't hold geometry or append quads. |
| DCHECK(layerTreeImpl()->IsPendingTree()); |
| return; |
| } |
| m_geometry->setThumbSize(size); |
| } |
| |
| float ScrollbarLayerImpl::currentPos() const |
| { |
| return m_currentPos; |
| } |
| |
| int ScrollbarLayerImpl::totalSize() const |
| { |
| return m_totalSize; |
| } |
| |
| int ScrollbarLayerImpl::maximum() const |
| { |
| return m_maximum; |
| } |
| |
| WebKit::WebScrollbar::Orientation ScrollbarLayerImpl::orientation() const |
| { |
| return m_orientation; |
| } |
| |
| static gfx::RectF toUVRect(const gfx::Rect& r, const gfx::Rect& bounds) |
| { |
| return gfx::ScaleRect(r, 1.0 / bounds.width(), 1.0 / bounds.height()); |
| } |
| |
| gfx::Rect ScrollbarLayerImpl::scrollbarLayerRectToContentRect(const gfx::Rect& layerRect) const |
| { |
| // Don't intersect with the bounds as in layerRectToContentRect() because |
| // layerRect here might be in coordinates of the containing layer. |
| gfx::RectF contentRect = gfx::ScaleRect(layerRect, contentsScaleX(), contentsScaleY()); |
| return gfx::ToEnclosingRect(contentRect); |
| } |
| |
| scoped_ptr<LayerImpl> ScrollbarLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl) |
| { |
| return ScrollbarLayerImpl::create(treeImpl, id(), m_geometry.Pass()).PassAs<LayerImpl>(); |
| } |
| |
| void ScrollbarLayerImpl::pushPropertiesTo(LayerImpl* layer) |
| { |
| LayerImpl::pushPropertiesTo(layer); |
| |
| ScrollbarLayerImpl* scrollbarLayer = static_cast<ScrollbarLayerImpl*>(layer); |
| |
| scrollbarLayer->setScrollbarData(&m_scrollbar); |
| scrollbarLayer->setThumbSize(m_thumbSize); |
| |
| scrollbarLayer->setBackTrackResourceId(m_backTrackResourceId); |
| scrollbarLayer->setForeTrackResourceId(m_foreTrackResourceId); |
| scrollbarLayer->setThumbResourceId(m_thumbResourceId); |
| } |
| |
| void ScrollbarLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuadsData) |
| { |
| bool premultipledAlpha = true; |
| bool flipped = false; |
| gfx::PointF uvTopLeft(0.f, 0.f); |
| gfx::PointF uvBottomRight(1.f, 1.f); |
| gfx::Rect boundsRect(gfx::Point(), bounds()); |
| gfx::Rect contentBoundsRect(gfx::Point(), contentBounds()); |
| |
| SharedQuadState* sharedQuadState = quadSink.useSharedQuadState(createSharedQuadState()); |
| appendDebugBorderQuad(quadSink, sharedQuadState, appendQuadsData); |
| |
| WebRect thumbRect, backTrackRect, foreTrackRect; |
| m_geometry->splitTrack(&m_scrollbar, m_geometry->trackRect(&m_scrollbar), backTrackRect, thumbRect, foreTrackRect); |
| if (!m_geometry->hasThumb(&m_scrollbar)) |
| thumbRect = WebRect(); |
| |
| if (layerTreeImpl()->settings().solidColorScrollbars) { |
| int thicknessOverride = layerTreeImpl()->settings().solidColorScrollbarThicknessDIP; |
| if (thicknessOverride != -1) { |
| if (m_scrollbar.orientation() == WebScrollbar::Vertical) |
| thumbRect.width = thicknessOverride; |
| else |
| thumbRect.height = thicknessOverride; |
| } |
| gfx::Rect quadRect(scrollbarLayerRectToContentRect(thumbRect)); |
| scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create(); |
| quad->SetNew(sharedQuadState, quadRect, layerTreeImpl()->settings().solidColorScrollbarColor); |
| quadSink.append(quad.PassAs<DrawQuad>(), appendQuadsData); |
| return; |
| } |
| |
| if (m_thumbResourceId && !thumbRect.isEmpty()) { |
| gfx::Rect quadRect(scrollbarLayerRectToContentRect(thumbRect)); |
| gfx::Rect opaqueRect; |
| const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; |
| scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); |
| quad->SetNew(sharedQuadState, quadRect, opaqueRect, m_thumbResourceId, premultipledAlpha, uvTopLeft, uvBottomRight, opacity, flipped); |
| quadSink.append(quad.PassAs<DrawQuad>(), appendQuadsData); |
| } |
| |
| if (!m_backTrackResourceId) |
| return; |
| |
| // We only paint the track in two parts if we were given a texture for the forward track part. |
| if (m_foreTrackResourceId && !foreTrackRect.isEmpty()) { |
| gfx::Rect quadRect(scrollbarLayerRectToContentRect(foreTrackRect)); |
| gfx::Rect opaqueRect(contentsOpaque() ? quadRect : gfx::Rect()); |
| gfx::RectF uvRect(toUVRect(foreTrackRect, boundsRect)); |
| const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; |
| scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); |
| quad->SetNew(sharedQuadState, quadRect, opaqueRect, m_foreTrackResourceId, premultipledAlpha, uvRect.origin(), uvRect.bottom_right(), opacity, flipped); |
| quadSink.append(quad.PassAs<DrawQuad>(), appendQuadsData); |
| } |
| |
| // Order matters here: since the back track texture is being drawn to the entire contents rect, we must append it after the thumb and |
| // fore track quads. The back track texture contains (and displays) the buttons. |
| if (!contentBoundsRect.IsEmpty()) { |
| gfx::Rect quadRect(contentBoundsRect); |
| gfx::Rect opaqueRect(contentsOpaque() ? quadRect : gfx::Rect()); |
| const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; |
| scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); |
| quad->SetNew(sharedQuadState, quadRect, opaqueRect, m_backTrackResourceId, premultipledAlpha, uvTopLeft, uvBottomRight, opacity, flipped); |
| quadSink.append(quad.PassAs<DrawQuad>(), appendQuadsData); |
| } |
| } |
| |
| void ScrollbarLayerImpl::didLoseOutputSurface() |
| { |
| m_backTrackResourceId = 0; |
| m_foreTrackResourceId = 0; |
| m_thumbResourceId = 0; |
| } |
| |
| bool ScrollbarLayerImpl::Scrollbar::isOverlay() const |
| { |
| return m_owner->m_isOverlayScrollbar; |
| } |
| |
| int ScrollbarLayerImpl::Scrollbar::value() const |
| { |
| return m_owner->currentPos(); |
| } |
| |
| WebKit::WebPoint ScrollbarLayerImpl::Scrollbar::location() const |
| { |
| return WebKit::WebPoint(); |
| } |
| |
| WebKit::WebSize ScrollbarLayerImpl::Scrollbar::size() const |
| { |
| return WebKit::WebSize(m_owner->bounds().width(), m_owner->bounds().height()); |
| } |
| |
| bool ScrollbarLayerImpl::Scrollbar::enabled() const |
| { |
| return m_owner->m_enabled; |
| } |
| |
| int ScrollbarLayerImpl::Scrollbar::maximum() const |
| { |
| return m_owner->maximum(); |
| } |
| |
| int ScrollbarLayerImpl::Scrollbar::totalSize() const |
| { |
| return m_owner->totalSize(); |
| } |
| |
| bool ScrollbarLayerImpl::Scrollbar::isScrollViewScrollbar() const |
| { |
| return m_owner->m_isScrollViewScrollbar; |
| } |
| |
| bool ScrollbarLayerImpl::Scrollbar::isScrollableAreaActive() const |
| { |
| return m_owner->m_isScrollableAreaActive; |
| } |
| |
| void ScrollbarLayerImpl::Scrollbar::getTickmarks(WebKit::WebVector<WebRect>& tickmarks) const |
| { |
| tickmarks = m_owner->m_tickmarks; |
| } |
| |
| WebScrollbar::ScrollbarControlSize ScrollbarLayerImpl::Scrollbar::controlSize() const |
| { |
| return m_owner->m_controlSize; |
| } |
| |
| WebScrollbar::ScrollbarPart ScrollbarLayerImpl::Scrollbar::pressedPart() const |
| { |
| return m_owner->m_pressedPart; |
| } |
| |
| WebScrollbar::ScrollbarPart ScrollbarLayerImpl::Scrollbar::hoveredPart() const |
| { |
| return m_owner->m_hoveredPart; |
| } |
| |
| WebScrollbar::ScrollbarOverlayStyle ScrollbarLayerImpl::Scrollbar::scrollbarOverlayStyle() const |
| { |
| return m_owner->m_scrollbarOverlayStyle; |
| } |
| |
| WebScrollbar::Orientation ScrollbarLayerImpl::Scrollbar::orientation() const |
| { |
| return m_owner->m_orientation; |
| } |
| |
| bool ScrollbarLayerImpl::Scrollbar::isCustomScrollbar() const |
| { |
| return m_owner->m_isCustomScrollbar; |
| } |
| |
| const char* ScrollbarLayerImpl::layerTypeAsString() const |
| { |
| return "ScrollbarLayer"; |
| } |
| |
| } // namespace cc |