blob: 5b6968dc16f399c43f459be52fce8d487965d03e [file] [log] [blame]
// 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/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> ScrollbarLayerImpl::create(int id)
{
return make_scoped_ptr(new ScrollbarLayerImpl(id));
}
ScrollbarLayerImpl::ScrollbarLayerImpl(int id)
: LayerImpl(id)
, m_scrollbar(this)
, m_backTrackResourceId(0)
, m_foreTrackResourceId(0)
, m_thumbResourceId(0)
, 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()
{
}
void ScrollbarLayerImpl::setScrollbarGeometry(scoped_ptr<ScrollbarGeometryFixedThumb> geometry)
{
m_geometry = geometry.Pass();
}
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);
m_geometry->update(scrollbar);
}
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);
}
void ScrollbarLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuadsData)
{
bool premultipledAlpha = false;
bool flipped = false;
gfx::RectF uvRect(0, 0, 1, 1);
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;
scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create();
quad->SetNew(sharedQuadState, quadRect, opaqueRect, m_thumbResourceId, premultipledAlpha, uvRect, 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());
scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create();
quad->SetNew(sharedQuadState, quadRect, opaqueRect, m_foreTrackResourceId, premultipledAlpha, toUVRect(foreTrackRect, boundsRect), 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());
scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create();
quad->SetNew(sharedQuadState, quadRect, opaqueRect, m_backTrackResourceId, premultipledAlpha, uvRect, flipped);
quadSink.append(quad.PassAs<DrawQuad>(), appendQuadsData);
}
}
void ScrollbarLayerImpl::didLoseContext()
{
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->m_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->m_maximum;
}
int ScrollbarLayerImpl::Scrollbar::totalSize() const
{
return m_owner->m_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