#include "config.h"
#include "ScrollView.h"
#include "GraphicsContext.h"
#include "HostWindow.h"
#include "PlatformMouseEvent.h"
#include "PlatformWheelEvent.h"
#include "Scrollbar.h"
#include "ScrollbarTheme.h"
#include <wtf/StdLibExtras.h>
using std::max;
namespace WebCore {
ScrollView::ScrollView()
: m_horizontalScrollbarMode(ScrollbarAuto)
, m_verticalScrollbarMode(ScrollbarAuto)
, m_horizontalScrollbarLock(false)
, m_verticalScrollbarLock(false)
, m_prohibitsScrolling(false)
, m_canBlitOnScroll(true)
, m_scrollbarsAvoidingResizer(0)
, m_scrollbarsSuppressed(false)
, m_inUpdateScrollbars(false)
, m_updateScrollbarsPass(0)
, m_drawPanScrollIcon(false)
, m_useFixedLayout(false)
, m_paintsEntireContents(false)
{
platformInit();
}
ScrollView::~ScrollView()
{
platformDestroy();
}
void ScrollView::addChild(PassRefPtr<Widget> prpChild)
{
Widget* child = prpChild.get();
ASSERT(child != this && !child->parent());
child->setParent(this);
m_children.add(prpChild);
if (child->platformWidget())
platformAddChild(child);
}
void ScrollView::removeChild(Widget* child)
{
ASSERT(child->parent() == this);
child->setParent(0);
m_children.remove(child);
if (child->platformWidget())
platformRemoveChild(child);
}
void ScrollView::setHasHorizontalScrollbar(bool hasBar)
{
if (hasBar && avoidScrollbarCreation())
return;
if (hasBar && !m_horizontalScrollbar) {
m_horizontalScrollbar = createScrollbar(HorizontalScrollbar);
addChild(m_horizontalScrollbar.get());
m_horizontalScrollbar->styleChanged();
} else if (!hasBar && m_horizontalScrollbar) {
removeChild(m_horizontalScrollbar.get());
m_horizontalScrollbar = 0;
}
}
void ScrollView::setHasVerticalScrollbar(bool hasBar)
{
if (hasBar && avoidScrollbarCreation())
return;
if (hasBar && !m_verticalScrollbar) {
m_verticalScrollbar = createScrollbar(VerticalScrollbar);
addChild(m_verticalScrollbar.get());
m_verticalScrollbar->styleChanged();
} else if (!hasBar && m_verticalScrollbar) {
removeChild(m_verticalScrollbar.get());
m_verticalScrollbar = 0;
}
}
#if !PLATFORM(GTK)
PassRefPtr<Scrollbar> ScrollView::createScrollbar(ScrollbarOrientation orientation)
{
return Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
}
void ScrollView::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode,
bool horizontalLock, bool verticalLock)
{
bool needsUpdate = false;
if (horizontalMode != horizontalScrollbarMode() && !m_horizontalScrollbarLock) {
m_horizontalScrollbarMode = horizontalMode;
needsUpdate = true;
}
if (verticalMode != verticalScrollbarMode() && !m_verticalScrollbarLock) {
m_verticalScrollbarMode = verticalMode;
needsUpdate = true;
}
if (horizontalLock)
setHorizontalScrollbarLock();
if (verticalLock)
setVerticalScrollbarLock();
if (!needsUpdate)
return;
if (platformWidget())
platformSetScrollbarModes();
else
updateScrollbars(scrollOffset());
}
#endif
void ScrollView::scrollbarModes(ScrollbarMode& horizontalMode, ScrollbarMode& verticalMode) const
{
if (platformWidget()) {
platformScrollbarModes(horizontalMode, verticalMode);
return;
}
horizontalMode = m_horizontalScrollbarMode;
verticalMode = m_verticalScrollbarMode;
}
void ScrollView::setCanHaveScrollbars(bool canScroll)
{
ScrollbarMode newHorizontalMode;
ScrollbarMode newVerticalMode;
scrollbarModes(newHorizontalMode, newVerticalMode);
if (canScroll && newVerticalMode == ScrollbarAlwaysOff)
newVerticalMode = ScrollbarAuto;
else if (!canScroll)
newVerticalMode = ScrollbarAlwaysOff;
if (canScroll && newHorizontalMode == ScrollbarAlwaysOff)
newHorizontalMode = ScrollbarAuto;
else if (!canScroll)
newHorizontalMode = ScrollbarAlwaysOff;
setScrollbarModes(newHorizontalMode, newVerticalMode);
}
void ScrollView::setCanBlitOnScroll(bool b)
{
if (platformWidget()) {
platformSetCanBlitOnScroll(b);
return;
}
m_canBlitOnScroll = b;
}
bool ScrollView::canBlitOnScroll() const
{
if (platformWidget())
return platformCanBlitOnScroll();
return m_canBlitOnScroll;
}
void ScrollView::setPaintsEntireContents(bool paintsEntireContents)
{
m_paintsEntireContents = paintsEntireContents;
}
#if !PLATFORM(GTK)
IntRect ScrollView::visibleContentRect(bool includeScrollbars) const
{
if (platformWidget())
return platformVisibleContentRect(includeScrollbars);
return IntRect(IntPoint(m_scrollOffset.width(), m_scrollOffset.height()),
IntSize(max(0, width() - (verticalScrollbar() && !includeScrollbars ? verticalScrollbar()->width() : 0)),
max(0, height() - (horizontalScrollbar() && !includeScrollbars ? horizontalScrollbar()->height() : 0))));
}
#endif
int ScrollView::layoutWidth() const
{
return m_fixedLayoutSize.isEmpty() || !m_useFixedLayout ? visibleWidth() : m_fixedLayoutSize.width();
}
int ScrollView::layoutHeight() const
{
return m_fixedLayoutSize.isEmpty() || !m_useFixedLayout ? visibleHeight() : m_fixedLayoutSize.height();
}
IntSize ScrollView::fixedLayoutSize() const
{
return m_fixedLayoutSize;
}
void ScrollView::setFixedLayoutSize(const IntSize& newSize)
{
if (fixedLayoutSize() == newSize)
return;
m_fixedLayoutSize = newSize;
updateScrollbars(scrollOffset());
}
bool ScrollView::useFixedLayout() const
{
return m_useFixedLayout;
}
void ScrollView::setUseFixedLayout(bool enable)
{
if (useFixedLayout() == enable)
return;
m_useFixedLayout = enable;
updateScrollbars(scrollOffset());
}
IntSize ScrollView::contentsSize() const
{
if (platformWidget())
return platformContentsSize();
return m_contentsSize;
}
void ScrollView::setContentsSize(const IntSize& newSize)
{
if (contentsSize() == newSize)
return;
m_contentsSize = newSize;
if (platformWidget())
platformSetContentsSize();
else
updateScrollbars(scrollOffset());
}
IntPoint ScrollView::maximumScrollPosition() const
{
IntSize maximumOffset = contentsSize() - visibleContentRect().size();
maximumOffset.clampNegativeToZero();
return IntPoint(maximumOffset.width(), maximumOffset.height());
}
void ScrollView::valueChanged(Scrollbar* scrollbar)
{
IntSize newOffset = m_scrollOffset;
if (scrollbar) {
if (scrollbar->orientation() == HorizontalScrollbar)
newOffset.setWidth(scrollbar->value());
else if (scrollbar->orientation() == VerticalScrollbar)
newOffset.setHeight(scrollbar->value());
}
IntSize scrollDelta = newOffset - m_scrollOffset;
if (scrollDelta == IntSize())
return;
m_scrollOffset = newOffset;
if (scrollbarsSuppressed())
return;
scrollPositionChanged();
scrollContents(scrollDelta);
}
void ScrollView::setScrollPosition(const IntPoint& scrollPoint)
{
if (prohibitsScrolling())
return;
if (platformWidget()) {
platformSetScrollPosition(scrollPoint);
return;
}
IntPoint newScrollPosition = scrollPoint.shrunkTo(maximumScrollPosition());
newScrollPosition.clampNegativeToZero();
if (newScrollPosition == scrollPosition())
return;
updateScrollbars(IntSize(newScrollPosition.x(), newScrollPosition.y()));
}
bool ScrollView::scroll(ScrollDirection direction, ScrollGranularity granularity)
{
if (platformWidget())
return platformScroll(direction, granularity);
if (direction == ScrollUp || direction == ScrollDown) {
if (m_verticalScrollbar)
return m_verticalScrollbar->scroll(direction, granularity);
} else {
if (m_horizontalScrollbar)
return m_horizontalScrollbar->scroll(direction, granularity);
}
return false;
}
static const unsigned cMaxUpdateScrollbarsPass = 2;
void ScrollView::updateScrollbars(const IntSize& desiredOffset)
{
if (m_inUpdateScrollbars || prohibitsScrolling() || platformWidget())
return;
if (!m_scrollbarsSuppressed) {
m_inUpdateScrollbars = true;
visibleContentsResized();
m_inUpdateScrollbars = false;
}
bool hasHorizontalScrollbar = m_horizontalScrollbar;
bool hasVerticalScrollbar = m_verticalScrollbar;
bool newHasHorizontalScrollbar = hasHorizontalScrollbar;
bool newHasVerticalScrollbar = hasVerticalScrollbar;
ScrollbarMode hScroll = m_horizontalScrollbarMode;
ScrollbarMode vScroll = m_verticalScrollbarMode;
if (hScroll != ScrollbarAuto)
newHasHorizontalScrollbar = (hScroll == ScrollbarAlwaysOn);
if (vScroll != ScrollbarAuto)
newHasVerticalScrollbar = (vScroll == ScrollbarAlwaysOn);
if (m_scrollbarsSuppressed || (hScroll != ScrollbarAuto && vScroll != ScrollbarAuto)) {
if (hasHorizontalScrollbar != newHasHorizontalScrollbar)
setHasHorizontalScrollbar(newHasHorizontalScrollbar);
if (hasVerticalScrollbar != newHasVerticalScrollbar)
setHasVerticalScrollbar(newHasVerticalScrollbar);
} else {
bool sendContentResizedNotification = false;
IntSize docSize = contentsSize();
IntSize frameSize = frameRect().size();
if (hScroll == ScrollbarAuto) {
newHasHorizontalScrollbar = docSize.width() > visibleWidth();
if (newHasHorizontalScrollbar && !m_updateScrollbarsPass && docSize.width() <= frameSize.width() && docSize.height() <= frameSize.height())
newHasHorizontalScrollbar = false;
}
if (vScroll == ScrollbarAuto) {
newHasVerticalScrollbar = docSize.height() > visibleHeight();
if (newHasVerticalScrollbar && !m_updateScrollbarsPass && docSize.width() <= frameSize.width() && docSize.height() <= frameSize.height())
newHasVerticalScrollbar = false;
}
if (!newHasHorizontalScrollbar && hasHorizontalScrollbar && vScroll != ScrollbarAlwaysOn)
newHasVerticalScrollbar = false;
if (!newHasVerticalScrollbar && hasVerticalScrollbar && hScroll != ScrollbarAlwaysOn)
newHasHorizontalScrollbar = false;
if (hasHorizontalScrollbar != newHasHorizontalScrollbar) {
setHasHorizontalScrollbar(newHasHorizontalScrollbar);
sendContentResizedNotification = true;
}
if (hasVerticalScrollbar != newHasVerticalScrollbar) {
setHasVerticalScrollbar(newHasVerticalScrollbar);
sendContentResizedNotification = true;
}
if (sendContentResizedNotification && m_updateScrollbarsPass < cMaxUpdateScrollbarsPass) {
m_updateScrollbarsPass++;
contentsResized();
visibleContentsResized();
IntSize newDocSize = contentsSize();
if (newDocSize == docSize) {
updateScrollbars(desiredOffset);
}
m_updateScrollbarsPass--;
}
}
if (m_updateScrollbarsPass)
return;
m_inUpdateScrollbars = true;
IntSize maxScrollPosition(contentsWidth() - visibleWidth(), contentsHeight() - visibleHeight());
IntSize scroll = desiredOffset.shrunkTo(maxScrollPosition);
scroll.clampNegativeToZero();
if (m_horizontalScrollbar) {
int clientWidth = visibleWidth();
m_horizontalScrollbar->setEnabled(contentsWidth() > clientWidth);
int pageStep = max(max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1);
IntRect oldRect(m_horizontalScrollbar->frameRect());
IntRect hBarRect = IntRect(0,
height() - m_horizontalScrollbar->height(),
width() - (m_verticalScrollbar ? m_verticalScrollbar->width() : 0),
m_horizontalScrollbar->height());
m_horizontalScrollbar->setFrameRect(hBarRect);
if (!m_scrollbarsSuppressed && oldRect != m_horizontalScrollbar->frameRect())
m_horizontalScrollbar->invalidate();
if (m_scrollbarsSuppressed)
m_horizontalScrollbar->setSuppressInvalidation(true);
m_horizontalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
m_horizontalScrollbar->setProportion(clientWidth, contentsWidth());
m_horizontalScrollbar->setValue(scroll.width());
if (m_scrollbarsSuppressed)
m_horizontalScrollbar->setSuppressInvalidation(false);
}
if (m_verticalScrollbar) {
int clientHeight = visibleHeight();
m_verticalScrollbar->setEnabled(contentsHeight() > clientHeight);
int pageStep = max(max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
IntRect oldRect(m_verticalScrollbar->frameRect());
IntRect vBarRect = IntRect(width() - m_verticalScrollbar->width(),
0,
m_verticalScrollbar->width(),
height() - (m_horizontalScrollbar ? m_horizontalScrollbar->height() : 0));
m_verticalScrollbar->setFrameRect(vBarRect);
if (!m_scrollbarsSuppressed && oldRect != m_verticalScrollbar->frameRect())
m_verticalScrollbar->invalidate();
if (m_scrollbarsSuppressed)
m_verticalScrollbar->setSuppressInvalidation(true);
m_verticalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
m_verticalScrollbar->setProportion(clientHeight, contentsHeight());
m_verticalScrollbar->setValue(scroll.height());
if (m_scrollbarsSuppressed)
m_verticalScrollbar->setSuppressInvalidation(false);
}
if (hasHorizontalScrollbar != (m_horizontalScrollbar != 0) || hasVerticalScrollbar != (m_verticalScrollbar != 0)) {
frameRectsChanged();
updateScrollCorner();
}
IntSize scrollDelta = scroll - m_scrollOffset;
if (scrollDelta != IntSize()) {
m_scrollOffset = scroll;
scrollContents(scrollDelta);
}
m_inUpdateScrollbars = false;
}
const int panIconSizeLength = 16;
void ScrollView::scrollContents(const IntSize& scrollDelta)
{
if (!hostWindow())
return;
IntRect clipRect = windowClipRect();
IntRect scrollViewRect = convertToContainingWindow(IntRect(0, 0, visibleWidth(), visibleHeight()));
IntRect updateRect = clipRect;
updateRect.intersect(scrollViewRect);
hostWindow()->invalidateWindow(updateRect, false );
if (m_drawPanScrollIcon) {
int panIconDirtySquareSizeLength = 2 * (panIconSizeLength + max(abs(scrollDelta.width()), abs(scrollDelta.height()))); IntPoint panIconDirtySquareLocation = IntPoint(m_panScrollIconPoint.x() - (panIconDirtySquareSizeLength / 2), m_panScrollIconPoint.y() - (panIconDirtySquareSizeLength / 2));
IntRect panScrollIconDirtyRect = IntRect(panIconDirtySquareLocation , IntSize(panIconDirtySquareSizeLength, panIconDirtySquareSizeLength));
panScrollIconDirtyRect.intersect(clipRect);
hostWindow()->invalidateContentsAndWindow(panScrollIconDirtyRect, false );
}
if (canBlitOnScroll()) { hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect);
} else {
hostWindow()->invalidateContentsForSlowScroll(updateRect, false);
}
frameRectsChanged();
hostWindow()->invalidateWindow(IntRect(), true);
}
IntPoint ScrollView::windowToContents(const IntPoint& windowPoint) const
{
IntPoint viewPoint = convertFromContainingWindow(windowPoint);
return viewPoint + scrollOffset();
}
IntPoint ScrollView::contentsToWindow(const IntPoint& contentsPoint) const
{
IntPoint viewPoint = contentsPoint - scrollOffset();
return convertToContainingWindow(viewPoint);
}
IntRect ScrollView::windowToContents(const IntRect& windowRect) const
{
IntRect viewRect = convertFromContainingWindow(windowRect);
viewRect.move(scrollOffset());
return viewRect;
}
IntRect ScrollView::contentsToWindow(const IntRect& contentsRect) const
{
IntRect viewRect = contentsRect;
viewRect.move(-scrollOffset());
return convertToContainingWindow(viewRect);
}
IntRect ScrollView::contentsToScreen(const IntRect& rect) const
{
if (platformWidget())
return platformContentsToScreen(rect);
if (!hostWindow())
return IntRect();
return hostWindow()->windowToScreen(contentsToWindow(rect));
}
IntPoint ScrollView::screenToContents(const IntPoint& point) const
{
if (platformWidget())
return platformScreenToContents(point);
if (!hostWindow())
return IntPoint();
return windowToContents(hostWindow()->screenToWindow(point));
}
bool ScrollView::containsScrollbarsAvoidingResizer() const
{
return !m_scrollbarsAvoidingResizer;
}
void ScrollView::adjustScrollbarsAvoidingResizerCount(int overlapDelta)
{
int oldCount = m_scrollbarsAvoidingResizer;
m_scrollbarsAvoidingResizer += overlapDelta;
if (parent())
parent()->adjustScrollbarsAvoidingResizerCount(overlapDelta);
else if (!scrollbarsSuppressed()) {
if ((oldCount > 0 && m_scrollbarsAvoidingResizer == 0) ||
(oldCount == 0 && m_scrollbarsAvoidingResizer > 0))
invalidateRect(windowResizerRect());
}
}
void ScrollView::setParent(ScrollView* parentView)
{
if (parentView == parent())
return;
if (m_scrollbarsAvoidingResizer && parent())
parent()->adjustScrollbarsAvoidingResizerCount(-m_scrollbarsAvoidingResizer);
Widget::setParent(parentView);
if (m_scrollbarsAvoidingResizer && parent())
parent()->adjustScrollbarsAvoidingResizerCount(m_scrollbarsAvoidingResizer);
}
void ScrollView::setScrollbarsSuppressed(bool suppressed, bool repaintOnUnsuppress)
{
if (suppressed == m_scrollbarsSuppressed)
return;
m_scrollbarsSuppressed = suppressed;
if (platformWidget())
platformSetScrollbarsSuppressed(repaintOnUnsuppress);
else if (repaintOnUnsuppress && !suppressed) {
if (m_horizontalScrollbar)
m_horizontalScrollbar->invalidate();
if (m_verticalScrollbar)
m_verticalScrollbar->invalidate();
invalidateRect(scrollCornerRect());
}
}
Scrollbar* ScrollView::scrollbarAtPoint(const IntPoint& windowPoint)
{
if (platformWidget())
return 0;
IntPoint viewPoint = convertFromContainingWindow(windowPoint);
if (m_horizontalScrollbar && m_horizontalScrollbar->frameRect().contains(viewPoint))
return m_horizontalScrollbar.get();
if (m_verticalScrollbar && m_verticalScrollbar->frameRect().contains(viewPoint))
return m_verticalScrollbar.get();
return 0;
}
void ScrollView::wheelEvent(PlatformWheelEvent& e)
{
#if PLATFORM(WX)
if (!canHaveScrollbars()) {
#else
if (!canHaveScrollbars() || platformWidget()) {
#endif
return;
}
IntSize maxScrollDelta = maximumScrollPosition() - scrollPosition();
if ((e.deltaX() < 0 && maxScrollDelta.width() > 0) ||
(e.deltaX() > 0 && scrollOffset().width() > 0) ||
(e.deltaY() < 0 && maxScrollDelta.height() > 0) ||
(e.deltaY() > 0 && scrollOffset().height() > 0)) {
e.accept();
float deltaX = e.deltaX();
float deltaY = e.deltaY();
if (e.granularity() == ScrollByPageWheelEvent) {
ASSERT(deltaX == 0);
bool negative = deltaY < 0;
deltaY = max(max<int>(visibleHeight() * Scrollbar::minFractionToStepWhenPaging(), visibleHeight() - Scrollbar::maxOverlapBetweenPages()), 1);
if (negative)
deltaY = -deltaY;
}
scrollBy(IntSize(-deltaX, -deltaY));
}
}
void ScrollView::setFrameRect(const IntRect& newRect)
{
IntRect oldRect = frameRect();
if (newRect == oldRect)
return;
Widget::setFrameRect(newRect);
if (platformWidget())
return;
if (newRect.width() != oldRect.width() || newRect.height() != oldRect.height()) {
updateScrollbars(m_scrollOffset);
contentsResized();
}
frameRectsChanged();
}
void ScrollView::frameRectsChanged()
{
if (platformWidget())
return;
HashSet<RefPtr<Widget> >::const_iterator end = m_children.end();
for (HashSet<RefPtr<Widget> >::const_iterator current = m_children.begin(); current != end; ++current)
(*current)->frameRectsChanged();
}
void ScrollView::repaintContentRectangle(const IntRect& rect, bool now)
{
IntRect paintRect = rect;
if (!paintsEntireContents())
paintRect.intersect(visibleContentRect());
if (paintRect.isEmpty())
return;
if (platformWidget()) {
platformRepaintContentRectangle(paintRect, now);
return;
}
if (hostWindow())
hostWindow()->invalidateContentsAndWindow(contentsToWindow(paintRect), now );
}
IntRect ScrollView::scrollCornerRect() const
{
IntRect cornerRect;
if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) {
cornerRect.unite(IntRect(m_horizontalScrollbar->width(),
height() - m_horizontalScrollbar->height(),
width() - m_horizontalScrollbar->width(),
m_horizontalScrollbar->height()));
}
if (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0) {
cornerRect.unite(IntRect(width() - m_verticalScrollbar->width(),
m_verticalScrollbar->height(),
m_verticalScrollbar->width(),
height() - m_verticalScrollbar->height()));
}
return cornerRect;
}
void ScrollView::updateScrollCorner()
{
}
void ScrollView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
{
ScrollbarTheme::nativeTheme()->paintScrollCorner(this, context, cornerRect);
}
void ScrollView::paintScrollbars(GraphicsContext* context, const IntRect& rect)
{
if (m_horizontalScrollbar)
m_horizontalScrollbar->paint(context, rect);
if (m_verticalScrollbar)
m_verticalScrollbar->paint(context, rect);
paintScrollCorner(context, scrollCornerRect());
}
void ScrollView::paintPanScrollIcon(GraphicsContext* context)
{
DEFINE_STATIC_LOCAL(Image*, panScrollIcon, (Image::loadPlatformResource("panIcon").releaseRef()));
context->drawImage(panScrollIcon, DeviceColorSpace, m_panScrollIconPoint);
}
void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
{
if (platformWidget()) {
Widget::paint(context, rect);
return;
}
if (context->paintingDisabled() && !context->updatingControlTints())
return;
IntRect documentDirtyRect = rect;
documentDirtyRect.intersect(frameRect());
context->save();
context->translate(x(), y());
documentDirtyRect.move(-x(), -y());
context->translate(-scrollX(), -scrollY());
documentDirtyRect.move(scrollX(), scrollY());
context->clip(visibleContentRect());
paintContents(context, documentDirtyRect);
context->restore();
if (!m_scrollbarsSuppressed && (m_horizontalScrollbar || m_verticalScrollbar)) {
context->save();
IntRect scrollViewDirtyRect = rect;
scrollViewDirtyRect.intersect(frameRect());
context->translate(x(), y());
scrollViewDirtyRect.move(-x(), -y());
paintScrollbars(context, scrollViewDirtyRect);
context->restore();
}
if (m_drawPanScrollIcon)
paintPanScrollIcon(context);
}
bool ScrollView::isPointInScrollbarCorner(const IntPoint& windowPoint)
{
if (!scrollbarCornerPresent())
return false;
IntPoint viewPoint = convertFromContainingWindow(windowPoint);
if (m_horizontalScrollbar) {
int horizontalScrollbarYMin = m_horizontalScrollbar->frameRect().y();
int horizontalScrollbarYMax = m_horizontalScrollbar->frameRect().y() + m_horizontalScrollbar->frameRect().height();
int horizontalScrollbarXMin = m_horizontalScrollbar->frameRect().x() + m_horizontalScrollbar->frameRect().width();
return viewPoint.y() > horizontalScrollbarYMin && viewPoint.y() < horizontalScrollbarYMax && viewPoint.x() > horizontalScrollbarXMin;
}
int verticalScrollbarXMin = m_verticalScrollbar->frameRect().x();
int verticalScrollbarXMax = m_verticalScrollbar->frameRect().x() + m_verticalScrollbar->frameRect().width();
int verticalScrollbarYMin = m_verticalScrollbar->frameRect().y() + m_verticalScrollbar->frameRect().height();
return viewPoint.x() > verticalScrollbarXMin && viewPoint.x() < verticalScrollbarXMax && viewPoint.y() > verticalScrollbarYMin;
}
bool ScrollView::scrollbarCornerPresent() const
{
return (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) ||
(m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0);
}
IntRect ScrollView::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& localRect) const
{
IntRect newRect = localRect;
newRect.move(scrollbar->x(), scrollbar->y());
return newRect;
}
IntRect ScrollView::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
{
IntRect newRect = parentRect;
newRect.move(-scrollbar->x(), -scrollbar->y());
return newRect;
}
IntPoint ScrollView::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& localPoint) const
{
IntPoint newPoint = localPoint;
newPoint.move(scrollbar->x(), scrollbar->y());
return newPoint;
}
IntPoint ScrollView::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
{
IntPoint newPoint = parentPoint;
newPoint.move(-scrollbar->x(), -scrollbar->y());
return newPoint;
}
void ScrollView::setParentVisible(bool visible)
{
if (isParentVisible() == visible)
return;
Widget::setParentVisible(visible);
if (!isSelfVisible())
return;
HashSet<RefPtr<Widget> >::iterator end = m_children.end();
for (HashSet<RefPtr<Widget> >::iterator it = m_children.begin(); it != end; ++it)
(*it)->setParentVisible(visible);
}
void ScrollView::show()
{
if (!isSelfVisible()) {
setSelfVisible(true);
if (isParentVisible()) {
HashSet<RefPtr<Widget> >::iterator end = m_children.end();
for (HashSet<RefPtr<Widget> >::iterator it = m_children.begin(); it != end; ++it)
(*it)->setParentVisible(true);
}
}
Widget::show();
}
void ScrollView::hide()
{
if (isSelfVisible()) {
if (isParentVisible()) {
HashSet<RefPtr<Widget> >::iterator end = m_children.end();
for (HashSet<RefPtr<Widget> >::iterator it = m_children.begin(); it != end; ++it)
(*it)->setParentVisible(false);
}
setSelfVisible(false);
}
Widget::hide();
}
bool ScrollView::isOffscreen() const
{
if (platformWidget())
return platformIsOffscreen();
if (!isVisible())
return true;
return false;
}
void ScrollView::addPanScrollIcon(const IntPoint& iconPosition)
{
if (!hostWindow())
return;
m_drawPanScrollIcon = true;
m_panScrollIconPoint = IntPoint(iconPosition.x() - panIconSizeLength / 2 , iconPosition.y() - panIconSizeLength / 2) ;
hostWindow()->invalidateContentsAndWindow(IntRect(m_panScrollIconPoint, IntSize(panIconSizeLength, panIconSizeLength)), true );
}
void ScrollView::removePanScrollIcon()
{
if (!hostWindow())
return;
m_drawPanScrollIcon = false;
hostWindow()->invalidateContentsAndWindow(IntRect(m_panScrollIconPoint, IntSize(panIconSizeLength, panIconSizeLength)), true );
}
#if !PLATFORM(WX) && !PLATFORM(GTK) && !PLATFORM(QT) && !PLATFORM(EFL)
void ScrollView::platformInit()
{
}
void ScrollView::platformDestroy()
{
}
#endif
#if !PLATFORM(WX) && !PLATFORM(GTK) && !PLATFORM(QT) && !PLATFORM(MAC)
void ScrollView::platformAddChild(Widget*)
{
}
void ScrollView::platformRemoveChild(Widget*)
{
}
#endif
#if !PLATFORM(MAC)
void ScrollView::platformSetScrollbarsSuppressed(bool)
{
}
#endif
#if !PLATFORM(MAC) && !PLATFORM(WX)
void ScrollView::platformSetScrollbarModes()
{
}
void ScrollView::platformScrollbarModes(ScrollbarMode& horizontal, ScrollbarMode& vertical) const
{
horizontal = ScrollbarAuto;
vertical = ScrollbarAuto;
}
void ScrollView::platformSetCanBlitOnScroll(bool)
{
}
bool ScrollView::platformCanBlitOnScroll() const
{
return false;
}
IntRect ScrollView::platformVisibleContentRect(bool) const
{
return IntRect();
}
IntSize ScrollView::platformContentsSize() const
{
return IntSize();
}
void ScrollView::platformSetContentsSize()
{
}
IntRect ScrollView::platformContentsToScreen(const IntRect& rect) const
{
return rect;
}
IntPoint ScrollView::platformScreenToContents(const IntPoint& point) const
{
return point;
}
void ScrollView::platformSetScrollPosition(const IntPoint&)
{
}
bool ScrollView::platformScroll(ScrollDirection, ScrollGranularity)
{
return true;
}
void ScrollView::platformRepaintContentRectangle(const IntRect&, bool )
{
}
bool ScrollView::platformIsOffscreen() const
{
return false;
}
#endif
}