// 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/quad_sink.h" #include "cc/scrollbar_animation_controller.h" #include "cc/texture_draw_quad.h" #include "ui/gfx/rect_conversions.h" using WebKit::WebRect; using WebKit::WebScrollbar; namespace cc { scoped_ptr ScrollbarLayerImpl::create(LayerTreeImpl* treeImpl, int id, scoped_ptr geometry) { return make_scoped_ptr(new ScrollbarLayerImpl(treeImpl, id, geometry.Pass())); } ScrollbarLayerImpl::ScrollbarLayerImpl(LayerTreeImpl* treeImpl, int id, scoped_ptr 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 ScrollbarLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl) { return ScrollbarLayerImpl::create(treeImpl, id(), m_geometry.Pass()).PassAs(); } void ScrollbarLayerImpl::pushPropertiesTo(LayerImpl* layer) { LayerImpl::pushPropertiesTo(layer); ScrollbarLayerImpl* scrollbarLayer = static_cast(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 = false; 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 (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 quad = TextureDrawQuad::Create(); quad->SetNew(sharedQuadState, quadRect, opaqueRect, m_thumbResourceId, premultipledAlpha, uvTopLeft, uvBottomRight, opacity, flipped); quadSink.append(quad.PassAs(), 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 quad = TextureDrawQuad::Create(); quad->SetNew(sharedQuadState, quadRect, opaqueRect, m_foreTrackResourceId, premultipledAlpha, uvRect.origin(), uvRect.bottom_right(), opacity, flipped); quadSink.append(quad.PassAs(), 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 quad = TextureDrawQuad::Create(); quad->SetNew(sharedQuadState, quadRect, opaqueRect, m_backTrackResourceId, premultipledAlpha, uvTopLeft, uvBottomRight, opacity, flipped); quadSink.append(quad.PassAs(), 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& 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