Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(478)

Unified Diff: Source/core/frame/FrameView.cpp

Issue 641733004: Merge FrameView and ScrollView. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebaseline. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/frame/FrameView.h ('k') | Source/core/html/HTMLFrameOwnerElement.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/frame/FrameView.cpp
diff --git a/Source/core/frame/FrameView.cpp b/Source/core/frame/FrameView.cpp
index 5ce154376e5b1144603590d76c3a153c2afd6162..f145456bb85ac2c64bee43768a27489f3ff878ea 100644
--- a/Source/core/frame/FrameView.cpp
+++ b/Source/core/frame/FrameView.cpp
@@ -75,17 +75,21 @@
#include "core/rendering/svg/RenderSVGRoot.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGSVGElement.h"
+#include "platform/HostWindow.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/ScriptForbiddenScope.h"
#include "platform/TraceEvent.h"
#include "platform/fonts/FontCache.h"
#include "platform/geometry/FloatRect.h"
#include "platform/graphics/GraphicsContext.h"
+#include "platform/graphics/GraphicsContextStateSaver.h"
+#include "platform/graphics/GraphicsLayer.h"
#include "platform/graphics/GraphicsLayerDebugInfo.h"
#include "platform/scroll/ScrollAnimator.h"
#include "platform/scroll/ScrollbarTheme.h"
#include "platform/text/TextStream.h"
#include "wtf/CurrentTime.h"
+#include "wtf/StdLibExtras.h"
#include "wtf/TemporaryChange.h"
namespace blink {
@@ -124,6 +128,15 @@ FrameView::FrameView(LocalFrame* frame)
, m_didScrollTimer(this, &FrameView::didScrollTimerFired)
, m_needsUpdateWidgetPositions(false)
, m_topControlsViewportAdjustment(0)
+ , m_horizontalScrollbarMode(ScrollbarAuto)
+ , m_verticalScrollbarMode(ScrollbarAuto)
+ , m_horizontalScrollbarLock(false)
+ , m_verticalScrollbarLock(false)
+ , m_scrollbarsAvoidingResizer(0)
+ , m_scrollbarsSuppressed(false)
+ , m_inUpdateScrollbars(false)
+ , m_drawPanScrollIcon(false)
+ , m_clipsRepaints(true)
{
ASSERT(m_frame);
init();
@@ -331,7 +344,7 @@ void FrameView::setFrameRect(const IntRect& newRect)
if (newRect.width() != oldRect.width() && m_frame->isMainFrame() && m_frame->settings()->textAutosizingEnabled())
autosizerNeedsUpdating = true;
- ScrollView::setFrameRect(newRect);
+ setFrameRectInternal(newRect);
updateScrollableAreaSet();
@@ -367,7 +380,7 @@ RenderView* FrameView::renderView() const
void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
{
m_canHaveScrollbars = canHaveScrollbars;
- ScrollView::setCanHaveScrollbars(canHaveScrollbars);
+ setCanHaveScrollbarsInternal(canHaveScrollbars);
}
bool FrameView::shouldUseCustomScrollbars(Element*& customScrollbarElement, LocalFrame*& customScrollbarFrame)
@@ -415,7 +428,7 @@ PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientatio
return RenderScrollbar::createCustomScrollbar(this, orientation, customScrollbarElement, customScrollbarFrame);
// Nobody set a custom style, so we just use a native scrollbar.
- return ScrollView::createScrollbar(orientation);
+ return createScrollbarInternal(orientation);
}
void FrameView::setContentsSize(const IntSize& size)
@@ -423,8 +436,8 @@ void FrameView::setContentsSize(const IntSize& size)
if (size == contentsSize())
return;
- ScrollView::setContentsSize(size);
- ScrollView::contentsResized();
+ setContentsSizeInternal(size);
+ ScrollableArea::contentsResized();
Page* page = frame().page();
if (!page)
@@ -459,7 +472,7 @@ void FrameView::adjustViewSize()
const IntRect rect = renderView->documentRect();
const IntSize& size = rect.size();
- ScrollView::setScrollOrigin(IntPoint(-rect.x(), -rect.y()), !m_frame->document()->printing(), size == contentsSize());
+ setScrollOrigin(IntPoint(-rect.x(), -rect.y()), !m_frame->document()->printing(), size == contentsSize());
setContentsSize(size);
}
@@ -1302,7 +1315,7 @@ void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
}
}
- ScrollView::scrollContentsSlowPath(updateRect);
+ scrollContentsSlowPathInternal(updateRect);
}
void FrameView::restoreScrollbar()
@@ -1437,7 +1450,7 @@ void FrameView::setScrollPosition(const DoublePoint& scrollPoint, ScrollBehavior
else
scrollBehavior = ScrollBehaviorInstant;
}
- ScrollView::setScrollPosition(newScrollPosition, scrollBehavior);
+ setScrollPositionInternal(newScrollPosition, scrollBehavior);
}
void FrameView::setScrollPositionNonProgrammatically(const IntPoint& scrollPoint)
@@ -1598,7 +1611,7 @@ void FrameView::contentRectangleForPaintInvalidation(const IntRect& r)
RELEASE_ASSERT_NOT_REACHED();
}
- ScrollView::contentRectangleForPaintInvalidation(r);
+ contentRectangleForPaintInvalidationInternal(r);
}
void FrameView::contentsResized()
@@ -1608,7 +1621,7 @@ void FrameView::contentsResized()
textAutosizer->updatePageInfoInAllFrames();
}
- ScrollView::contentsResized();
+ ScrollableArea::contentsResized();
setNeedsLayout();
}
@@ -2087,7 +2100,7 @@ bool FrameView::isActive() const
void FrameView::scrollTo(const DoublePoint& newPosition)
{
DoublePoint position = scrollPositionDouble();
- ScrollView::scrollTo(newPosition);
+ scrollToInternal(newPosition);
if (position != scrollPositionDouble()) {
updateLayersAndCompositingAfterScrollIfNeeded();
scrollPositionChanged();
@@ -2223,7 +2236,7 @@ void FrameView::scrollbarStyleChanged()
// FIXME: Why does this only apply to the main frame?
if (!m_frame->isMainFrame())
return;
- ScrollView::scrollbarStyleChanged();
+ scrollbarStyleChangedInternal();
}
void FrameView::notifyPageThatContentAreaWillPaint() const
@@ -2304,7 +2317,7 @@ void FrameView::updateScrollCorner()
m_scrollCorner = nullptr;
}
- ScrollView::updateScrollCorner();
+ updateScrollCornerInternal();
}
void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
@@ -2317,7 +2330,7 @@ void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& corne
return;
}
- ScrollView::paintScrollCorner(context, cornerRect);
+ paintScrollCornerInternal(context, cornerRect);
}
void FrameView::paintScrollbar(GraphicsContext* context, Scrollbar* bar, const IntRect& rect)
@@ -2329,7 +2342,7 @@ void FrameView::paintScrollbar(GraphicsContext* context, Scrollbar* bar, const I
context->fillRect(toFill, baseBackgroundColor());
}
- ScrollView::paintScrollbar(context, bar, rect);
+ paintScrollbarInternal(context, bar, rect);
}
Color FrameView::documentBackgroundColor() const
@@ -2527,7 +2540,7 @@ void FrameView::paintOverhangAreas(GraphicsContext* context, const IntRect& hori
return;
}
- ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
+ paintOverhangAreasInternal(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
}
void FrameView::updateWidgetPositionsIfNeeded()
@@ -2749,9 +2762,9 @@ IntPoint FrameView::convertToRenderer(const RenderObject& renderer, const IntPoi
IntRect FrameView::convertToContainingView(const IntRect& localRect) const
{
- if (const ScrollView* parentScrollView = toScrollView(parent())) {
+ if (const FrameView* parentScrollView = toFrameView(parent())) {
if (parentScrollView->isFrameView()) {
- const FrameView* parentView = toFrameView(parentScrollView);
+ const FrameView* parentView = parentScrollView;
// Get our renderer in the parent view
RenderPart* renderer = m_frame->ownerRenderer();
if (!renderer)
@@ -2772,9 +2785,9 @@ IntRect FrameView::convertToContainingView(const IntRect& localRect) const
IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
{
- if (const ScrollView* parentScrollView = toScrollView(parent())) {
+ if (const FrameView* parentScrollView = toFrameView(parent())) {
if (parentScrollView->isFrameView()) {
- const FrameView* parentView = toFrameView(parentScrollView);
+ const FrameView* parentView = parentScrollView;
// Get our renderer in the parent view
RenderPart* renderer = m_frame->ownerRenderer();
@@ -2796,9 +2809,9 @@ IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
{
- if (const ScrollView* parentScrollView = toScrollView(parent())) {
+ if (const FrameView* parentScrollView = toFrameView(parent())) {
if (parentScrollView->isFrameView()) {
- const FrameView* parentView = toFrameView(parentScrollView);
+ const FrameView* parentView = parentScrollView;
// Get our renderer in the parent view
RenderPart* renderer = m_frame->ownerRenderer();
@@ -2821,9 +2834,9 @@ IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
{
- if (const ScrollView* parentScrollView = toScrollView(parent())) {
+ if (const FrameView* parentScrollView = toFrameView(parent())) {
if (parentScrollView->isFrameView()) {
- const FrameView* parentView = toFrameView(parentScrollView);
+ const FrameView* parentView = parentScrollView;
// Get our renderer in the parent view
RenderPart* renderer = m_frame->ownerRenderer();
@@ -2915,7 +2928,7 @@ void FrameView::removeScrollableArea(ScrollableArea* scrollableArea)
void FrameView::setParent(Widget* widget)
{
- ScrollView::setParent(widget);
+ setParentInternal(widget);
updateScrollableAreaSet();
}
@@ -2924,7 +2937,7 @@ void FrameView::removeChild(Widget* widget)
if (widget->isFrameView())
removeScrollableArea(toFrameView(widget));
- ScrollView::removeChild(widget);
+ removeChildInternal(widget);
}
bool FrameView::wheelEvent(const PlatformWheelEvent& wheelEvent)
@@ -2995,7 +3008,7 @@ void FrameView::frameRectsChanged()
if (layoutSizeFixedToFrameSize())
setLayoutSizeInternal(frameRect().size());
- ScrollView::frameRectsChanged();
+ frameRectsChangedInternal();
}
void FrameView::setLayoutSizeInternal(const IntSize& size)
@@ -3042,4 +3055,1128 @@ IntPoint FrameView::maximumScrollPosition() const
return maximumOffset;
}
+// --- ScrollView ---
+
+void FrameView::addChild(PassRefPtr<Widget> prpChild)
+{
+ Widget* child = prpChild.get();
+ ASSERT(child != this && !child->parent());
+ child->setParent(this);
+ m_children.add(prpChild);
+}
+
+void FrameView::removeChildInternal(Widget* child)
+{
+ ASSERT(child->parent() == this);
+ child->setParent(0);
+ m_children.remove(child);
+}
+
+void FrameView::setHasHorizontalScrollbar(bool hasBar)
+{
+ if (hasBar && !m_horizontalScrollbar) {
+ m_horizontalScrollbar = createScrollbar(HorizontalScrollbar);
+ addChild(m_horizontalScrollbar.get());
+ didAddScrollbar(m_horizontalScrollbar.get(), HorizontalScrollbar);
+ m_horizontalScrollbar->styleChanged();
+ } else if (!hasBar && m_horizontalScrollbar) {
+ willRemoveScrollbar(m_horizontalScrollbar.get(), HorizontalScrollbar);
+ // If the scrollbar has been marked as overlapping the window resizer,
+ // then its removal should reduce the count.
+ if (m_horizontalScrollbar->overlapsResizer())
+ adjustScrollbarsAvoidingResizerCount(-1);
+ removeChild(m_horizontalScrollbar.get());
+ m_horizontalScrollbar = nullptr;
+ }
+}
+
+void FrameView::setHasVerticalScrollbar(bool hasBar)
+{
+ if (hasBar && !m_verticalScrollbar) {
+ m_verticalScrollbar = createScrollbar(VerticalScrollbar);
+ addChild(m_verticalScrollbar.get());
+ didAddScrollbar(m_verticalScrollbar.get(), VerticalScrollbar);
+ m_verticalScrollbar->styleChanged();
+ } else if (!hasBar && m_verticalScrollbar) {
+ willRemoveScrollbar(m_verticalScrollbar.get(), VerticalScrollbar);
+ // If the scrollbar has been marked as overlapping the window resizer,
+ // then its removal should reduce the count.
+ if (m_verticalScrollbar->overlapsResizer())
+ adjustScrollbarsAvoidingResizerCount(-1);
+ removeChild(m_verticalScrollbar.get());
+ m_verticalScrollbar = nullptr;
+ }
+}
+
+PassRefPtr<Scrollbar> FrameView::createScrollbarInternal(ScrollbarOrientation orientation)
+{
+ return Scrollbar::create(this, orientation, RegularScrollbar);
+}
+
+void FrameView::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;
+
+ updateScrollbars(scrollOffsetDouble());
+
+ if (!layerForScrolling())
+ return;
+ blink::WebLayer* layer = layerForScrolling()->platformLayer();
+ if (!layer)
+ return;
+ layer->setUserScrollable(userInputScrollable(HorizontalScrollbar), userInputScrollable(VerticalScrollbar));
+}
+
+void FrameView::scrollbarModes(ScrollbarMode& horizontalMode, ScrollbarMode& verticalMode) const
+{
+ horizontalMode = m_horizontalScrollbarMode;
+ verticalMode = m_verticalScrollbarMode;
+}
+
+void FrameView::setCanHaveScrollbarsInternal(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 FrameView::setClipsRepaints(bool clipsRepaints)
+{
+ m_clipsRepaints = clipsRepaints;
+}
+
+IntSize FrameView::unscaledVisibleContentSize(IncludeScrollbarsInRect scrollbarInclusion) const
+{
+ return scrollbarInclusion == ExcludeScrollbars ? excludeScrollbars(frameRect().size()) : frameRect().size();
+}
+
+IntSize FrameView::excludeScrollbars(const IntSize& size) const
+{
+ int verticalScrollbarWidth = 0;
+ int horizontalScrollbarHeight = 0;
+
+ if (Scrollbar* verticalBar = verticalScrollbar())
+ verticalScrollbarWidth = !verticalBar->isOverlayScrollbar() ? verticalBar->width() : 0;
+ if (Scrollbar* horizontalBar = horizontalScrollbar())
+ horizontalScrollbarHeight = !horizontalBar->isOverlayScrollbar() ? horizontalBar->height() : 0;
+
+ return IntSize(std::max(0, size.width() - verticalScrollbarWidth),
+ std::max(0, size.height() - horizontalScrollbarHeight));
+
+}
+
+IntRect FrameView::visibleContentRect(IncludeScrollbarsInRect scollbarInclusion) const
+{
+ FloatSize visibleContentSize = unscaledVisibleContentSize(scollbarInclusion);
+ visibleContentSize.scale(1 / visibleContentScaleFactor());
+ return IntRect(flooredIntPoint(m_scrollPosition), expandedIntSize(visibleContentSize));
+}
+
+IntSize FrameView::contentsSize() const
+{
+ return m_contentsSize;
+}
+
+void FrameView::setContentsSizeInternal(const IntSize& newSize)
+{
+ if (contentsSize() == newSize)
+ return;
+ m_contentsSize = newSize;
+ updateScrollbars(scrollOffsetDouble());
+ updateOverhangAreas();
+}
+
+IntPoint FrameView::minimumScrollPosition() const
+{
+ return IntPoint(-scrollOrigin().x(), -scrollOrigin().y());
+}
+
+IntPoint FrameView::adjustScrollPositionWithinRange(const IntPoint& scrollPoint) const
+{
+ if (!constrainsScrollingToContentEdge())
+ return scrollPoint;
+
+ IntPoint newScrollPosition = scrollPoint.shrunkTo(maximumScrollPosition());
+ newScrollPosition = newScrollPosition.expandedTo(minimumScrollPosition());
+ return newScrollPosition;
+}
+
+DoublePoint FrameView::adjustScrollPositionWithinRange(const DoublePoint& scrollPoint) const
+{
+ if (!constrainsScrollingToContentEdge())
+ return scrollPoint;
+ DoublePoint newScrollPosition = scrollPoint.shrunkTo(
+ maximumScrollPosition().x(), maximumScrollPosition().y());
+ newScrollPosition = newScrollPosition.expandedTo(
+ minimumScrollPosition().x(), minimumScrollPosition().y());
+ return newScrollPosition;
+}
+
+void FrameView::adjustScrollbarOpacity()
+{
+ if (m_horizontalScrollbar && layerForHorizontalScrollbar()) {
+ bool isOpaqueScrollbar = !m_horizontalScrollbar->isOverlayScrollbar();
+ layerForHorizontalScrollbar()->setContentsOpaque(isOpaqueScrollbar);
+ }
+ if (m_verticalScrollbar && layerForVerticalScrollbar()) {
+ bool isOpaqueScrollbar = !m_verticalScrollbar->isOverlayScrollbar();
+ layerForVerticalScrollbar()->setContentsOpaque(isOpaqueScrollbar);
+ }
+}
+
+int FrameView::scrollSize(ScrollbarOrientation orientation) const
+{
+ Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_horizontalScrollbar : m_verticalScrollbar).get();
+
+ // If no scrollbars are present, the content may still be scrollable.
+ if (!scrollbar) {
+ IntSize scrollSize = m_contentsSize - visibleContentRect().size();
+ scrollSize.clampNegativeToZero();
+ return orientation == HorizontalScrollbar ? scrollSize.width() : scrollSize.height();
+ }
+
+ return scrollbar->totalSize() - scrollbar->visibleSize();
+}
+
+void FrameView::notifyPageThatContentAreaWillPaintInternal() const
+{
+}
+
+void FrameView::setScrollOffset(const IntPoint& offset)
+{
+ scrollTo(DoublePoint(adjustScrollPositionWithinRange(offset)));
+}
+
+void FrameView::setScrollOffset(const DoublePoint& offset)
+{
+ scrollTo(adjustScrollPositionWithinRange(offset));
+}
+
+void FrameView::scrollToInternal(const DoublePoint& newPosition)
+{
+ DoubleSize scrollDelta = newPosition - m_scrollPosition;
+ if (scrollDelta.isZero())
+ return;
+ m_scrollPosition = newPosition;
+
+ if (scrollbarsSuppressed())
+ return;
+
+ // FIXME: Change scrollContents() to take DoubleSize. crbug.com/414283.
+ if (isFrameView())
+ m_pendingScrollDelta += scrollDelta;
+ else
+ scrollContents(flooredIntSize(scrollDelta));
+}
+
+void FrameView::setScrollPositionInternal(const DoublePoint& scrollPoint, ScrollBehavior scrollBehavior)
+{
+ DoublePoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);
+
+ if (newScrollPosition == scrollPositionDouble())
+ return;
+
+ if (scrollBehavior == ScrollBehaviorInstant) {
+ DoubleSize newOffset(newScrollPosition.x(), newScrollPosition.y());
+ updateScrollbars(newOffset);
+ } else {
+ programmaticallyScrollSmoothlyToOffset(toFloatPoint(newScrollPosition));
+ }
+}
+
+bool FrameView::scroll(ScrollDirection direction, ScrollGranularity granularity)
+{
+ ScrollDirection physicalDirection =
+ toPhysicalDirection(direction, isVerticalDocument(), isFlippedDocument());
+
+ return ScrollableArea::scroll(physicalDirection, granularity);
+}
+
+IntSize FrameView::overhangAmount() const
+{
+ IntSize stretch;
+
+ IntPoint currentScrollPosition = scrollPosition();
+ IntPoint minScrollPosition = minimumScrollPosition();
+ IntPoint maxScrollPosition = maximumScrollPosition();
+
+ if (currentScrollPosition.x() < minScrollPosition.x())
+ stretch.setWidth(currentScrollPosition.x() - minScrollPosition.x());
+ if (currentScrollPosition.x() > maxScrollPosition.x())
+ stretch.setWidth(currentScrollPosition.x() - maxScrollPosition.x());
+
+ if (currentScrollPosition.y() < minScrollPosition.y())
+ stretch.setHeight(currentScrollPosition.y() - minScrollPosition.y());
+ if (currentScrollPosition.y() > maxScrollPosition.y())
+ stretch.setHeight(currentScrollPosition.y() - maxScrollPosition.y());
+
+ return stretch;
+}
+
+void FrameView::windowResizerRectChanged()
+{
+ updateScrollbars(scrollOffsetDouble());
+}
+
+static bool useOverlayScrollbars()
+{
+ // FIXME: Need to detect the presence of CSS custom scrollbars, which are non-overlay regardless the ScrollbarTheme.
+ return ScrollbarTheme::theme()->usesOverlayScrollbars();
+}
+
+void FrameView::computeScrollbarExistence(bool& newHasHorizontalScrollbar, bool& newHasVerticalScrollbar, const IntSize& docSize, ComputeScrollbarExistenceOption option) const
+{
+ bool hasHorizontalScrollbar = m_horizontalScrollbar;
+ bool hasVerticalScrollbar = m_verticalScrollbar;
+
+ newHasHorizontalScrollbar = hasHorizontalScrollbar;
+ 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))
+ return;
+
+ if (hScroll == ScrollbarAuto)
+ newHasHorizontalScrollbar = docSize.width() > visibleWidth();
+ if (vScroll == ScrollbarAuto)
+ newHasVerticalScrollbar = docSize.height() > visibleHeight();
+
+ if (useOverlayScrollbars())
+ return;
+
+ IntSize fullVisibleSize = visibleContentRect(IncludeScrollbars).size();
+
+ bool attemptToRemoveScrollbars = (option == FirstPass
+ && docSize.width() <= fullVisibleSize.width() && docSize.height() <= fullVisibleSize.height());
+ if (attemptToRemoveScrollbars) {
+ if (hScroll == ScrollbarAuto)
+ newHasHorizontalScrollbar = false;
+ if (vScroll == ScrollbarAuto)
+ newHasVerticalScrollbar = false;
+ }
+
+ // If we ever turn one scrollbar off, always turn the other one off too.
+ // Never ever try to both gain/lose a scrollbar in the same pass.
+ if (!newHasHorizontalScrollbar && hasHorizontalScrollbar && vScroll != ScrollbarAlwaysOn)
+ newHasVerticalScrollbar = false;
+ if (!newHasVerticalScrollbar && hasVerticalScrollbar && hScroll != ScrollbarAlwaysOn)
+ newHasHorizontalScrollbar = false;
+}
+
+void FrameView::updateScrollbarGeometry()
+{
+ if (m_horizontalScrollbar) {
+ int clientWidth = visibleWidth();
+ IntRect oldRect(m_horizontalScrollbar->frameRect());
+ IntRect hBarRect((shouldPlaceVerticalScrollbarOnLeft() && m_verticalScrollbar) ? m_verticalScrollbar->width() : 0,
+ height() - m_horizontalScrollbar->height(),
+ width() - (m_verticalScrollbar ? m_verticalScrollbar->width() : 0),
+ m_horizontalScrollbar->height());
+ m_horizontalScrollbar->setFrameRect(adjustScrollbarRectForResizer(hBarRect, m_horizontalScrollbar.get()));
+ if (!m_scrollbarsSuppressed && oldRect != m_horizontalScrollbar->frameRect())
+ m_horizontalScrollbar->invalidate();
+
+ if (m_scrollbarsSuppressed)
+ m_horizontalScrollbar->setSuppressInvalidation(true);
+ m_horizontalScrollbar->setEnabled(contentsWidth() > clientWidth);
+ m_horizontalScrollbar->setProportion(clientWidth, contentsWidth());
+ m_horizontalScrollbar->offsetDidChange();
+ if (m_scrollbarsSuppressed)
+ m_horizontalScrollbar->setSuppressInvalidation(false);
+ }
+
+ if (m_verticalScrollbar) {
+ int clientHeight = visibleHeight();
+ IntRect oldRect(m_verticalScrollbar->frameRect());
+ IntRect vBarRect(shouldPlaceVerticalScrollbarOnLeft() ? 0 : (width() - m_verticalScrollbar->width()),
+ 0,
+ m_verticalScrollbar->width(),
+ height() - (m_horizontalScrollbar ? m_horizontalScrollbar->height() : 0));
+ m_verticalScrollbar->setFrameRect(adjustScrollbarRectForResizer(vBarRect, m_verticalScrollbar.get()));
+ if (!m_scrollbarsSuppressed && oldRect != m_verticalScrollbar->frameRect())
+ m_verticalScrollbar->invalidate();
+
+ if (m_scrollbarsSuppressed)
+ m_verticalScrollbar->setSuppressInvalidation(true);
+ m_verticalScrollbar->setEnabled(contentsHeight() > clientHeight);
+ m_verticalScrollbar->setProportion(clientHeight, contentsHeight());
+ m_verticalScrollbar->offsetDidChange();
+ if (m_scrollbarsSuppressed)
+ m_verticalScrollbar->setSuppressInvalidation(false);
+ }
+}
+
+IntRect FrameView::adjustScrollbarRectForResizer(const IntRect& rect, Scrollbar* scrollbar)
+{
+ // Get our window resizer rect and see if we overlap. Adjust to avoid the overlap
+ // if necessary.
+ IntRect adjustedRect(rect);
+ bool overlapsResizer = false;
+ if (!rect.isEmpty() && !windowResizerRect().isEmpty()) {
+ IntRect resizerRect = convertFromContainingWindow(windowResizerRect());
+ if (rect.intersects(resizerRect)) {
+ if (scrollbar->orientation() == HorizontalScrollbar) {
+ int overlap = rect.maxX() - resizerRect.x();
+ if (overlap > 0 && resizerRect.maxX() >= rect.maxX()) {
+ adjustedRect.setWidth(rect.width() - overlap);
+ overlapsResizer = true;
+ }
+ } else {
+ int overlap = rect.maxY() - resizerRect.y();
+ if (overlap > 0 && resizerRect.maxY() >= rect.maxY()) {
+ adjustedRect.setHeight(rect.height() - overlap);
+ overlapsResizer = true;
+ }
+ }
+ }
+ }
+ if (overlapsResizer != scrollbar->overlapsResizer()) {
+ scrollbar->setOverlapsResizer(overlapsResizer);
+ adjustScrollbarsAvoidingResizerCount(overlapsResizer ? 1 : -1);
+ }
+ return adjustedRect;
+}
+
+bool FrameView::adjustScrollbarExistence(ComputeScrollbarExistenceOption option)
+{
+ ASSERT(m_inUpdateScrollbars);
+
+ // If we came in here with the view already needing a layout, then go ahead and do that
+ // first. (This will be the common case, e.g., when the page changes due to window resizing for example).
+ // This layout will not re-enter updateScrollbars and does not count towards our max layout pass total.
+ if (!m_scrollbarsSuppressed)
+ scrollbarExistenceDidChange();
+
+ bool hasHorizontalScrollbar = m_horizontalScrollbar;
+ bool hasVerticalScrollbar = m_verticalScrollbar;
+
+ bool newHasHorizontalScrollbar = false;
+ bool newHasVerticalScrollbar = false;
+ computeScrollbarExistence(newHasHorizontalScrollbar, newHasVerticalScrollbar, contentsSize(), option);
+
+ bool scrollbarExistenceChanged = hasHorizontalScrollbar != newHasHorizontalScrollbar || hasVerticalScrollbar != newHasVerticalScrollbar;
+ if (!scrollbarExistenceChanged)
+ return false;
+
+ setHasHorizontalScrollbar(newHasHorizontalScrollbar);
+ setHasVerticalScrollbar(newHasVerticalScrollbar);
+
+ if (m_scrollbarsSuppressed)
+ return true;
+
+ if (!useOverlayScrollbars())
+ contentsResized();
+ scrollbarExistenceDidChange();
+ return true;
+}
+
+void FrameView::updateScrollbars(const DoubleSize& desiredOffset)
+{
+ if (scrollbarsDisabled()) {
+ setScrollOffsetFromUpdateScrollbars(desiredOffset);
+ return;
+ }
+
+ if (m_inUpdateScrollbars)
+ return;
+ InUpdateScrollbarsScope inUpdateScrollbarsScope(this);
+
+ IntSize oldVisibleSize = visibleSize();
+
+ bool scrollbarExistenceChanged = false;
+ int maxUpdateScrollbarsPass = useOverlayScrollbars() || m_scrollbarsSuppressed ? 1 : 3;
+ for (int updateScrollbarsPass = 0; updateScrollbarsPass < maxUpdateScrollbarsPass; updateScrollbarsPass++) {
+ if (!adjustScrollbarExistence(updateScrollbarsPass ? Incremental : FirstPass))
+ break;
+ scrollbarExistenceChanged = true;
+ }
+
+ updateScrollbarGeometry();
+
+ if (scrollbarExistenceChanged) {
+ // FIXME: Is frameRectsChanged really necessary here? Have any frame rects changed?
+ frameRectsChanged();
+ positionScrollbarLayers();
+ updateScrollCorner();
+ }
+
+ // FIXME: We don't need to do this if we are composited.
+ IntSize newVisibleSize = visibleSize();
+ if (newVisibleSize.width() > oldVisibleSize.width()) {
+ if (shouldPlaceVerticalScrollbarOnLeft())
+ invalidateRect(IntRect(0, 0, newVisibleSize.width() - oldVisibleSize.width(), newVisibleSize.height()));
+ else
+ invalidateRect(IntRect(oldVisibleSize.width(), 0, newVisibleSize.width() - oldVisibleSize.width(), newVisibleSize.height()));
+ }
+ if (newVisibleSize.height() > oldVisibleSize.height())
+ invalidateRect(IntRect(0, oldVisibleSize.height(), newVisibleSize.width(), newVisibleSize.height() - oldVisibleSize.height()));
+
+ setScrollOffsetFromUpdateScrollbars(desiredOffset);
+}
+
+void FrameView::setScrollOffsetFromUpdateScrollbars(const DoubleSize& offset)
+{
+ DoublePoint adjustedScrollPosition = DoublePoint(offset);
+
+ if (!isRubberBandInProgress())
+ adjustedScrollPosition = adjustScrollPositionWithinRange(adjustedScrollPosition);
+
+ if (adjustedScrollPosition != scrollPositionDouble() || scrollOriginChanged()) {
+ ScrollableArea::scrollToOffsetWithoutAnimation(toFloatPoint(adjustedScrollPosition));
+ resetScrollOriginChanged();
+ }
+}
+
+const int panIconSizeLength = 16;
+
+IntRect FrameView::rectToCopyOnScroll() const
+{
+ IntRect scrollViewRect = convertToContainingWindow(IntRect((shouldPlaceVerticalScrollbarOnLeft() && verticalScrollbar()) ? verticalScrollbar()->width() : 0, 0, visibleWidth(), visibleHeight()));
+ if (hasOverlayScrollbars()) {
+ int verticalScrollbarWidth = (verticalScrollbar() && !hasLayerForVerticalScrollbar()) ? verticalScrollbar()->width() : 0;
+ int horizontalScrollbarHeight = (horizontalScrollbar() && !hasLayerForHorizontalScrollbar()) ? horizontalScrollbar()->height() : 0;
+
+ scrollViewRect.setWidth(scrollViewRect.width() - verticalScrollbarWidth);
+ scrollViewRect.setHeight(scrollViewRect.height() - horizontalScrollbarHeight);
+ }
+ return scrollViewRect;
+}
+
+void FrameView::scrollContentsIfNeeded()
+{
+ if (m_pendingScrollDelta.isZero())
+ return;
+ DoubleSize scrollDelta = m_pendingScrollDelta;
+ m_pendingScrollDelta = DoubleSize();
+ // FIXME: Change scrollContents() to take DoubleSize. crbug.com/414283.
+ scrollContents(flooredIntSize(scrollDelta));
+}
+
+void FrameView::scrollContents(const IntSize& scrollDelta)
+{
+ HostWindow* window = hostWindow();
+ if (!window)
+ return;
+
+ IntRect clipRect = windowClipRect();
+ IntRect updateRect = clipRect;
+ updateRect.intersect(rectToCopyOnScroll());
+
+ if (m_drawPanScrollIcon) {
+ // FIXME: the pan icon is broken when accelerated compositing is on, since it will draw under the compositing layers.
+ // https://bugs.webkit.org/show_bug.cgi?id=47837
+ int panIconDirtySquareSizeLength = 2 * (panIconSizeLength + std::max(abs(scrollDelta.width()), abs(scrollDelta.height()))); // We only want to repaint what's necessary
+ IntPoint panIconDirtySquareLocation = IntPoint(m_panScrollIconPoint.x() - (panIconDirtySquareSizeLength / 2), m_panScrollIconPoint.y() - (panIconDirtySquareSizeLength / 2));
+ IntRect panScrollIconDirtyRect = IntRect(panIconDirtySquareLocation, IntSize(panIconDirtySquareSizeLength, panIconDirtySquareSizeLength));
+ panScrollIconDirtyRect.intersect(clipRect);
+ window->invalidateContentsAndRootView(panScrollIconDirtyRect);
+ }
+
+ if (!scrollContentsFastPath(-scrollDelta))
+ scrollContentsSlowPath(updateRect);
+
+ // Invalidate the overhang areas if they are visible.
+ updateOverhangAreas();
+
+ // This call will move children with native widgets (plugins) and invalidate them as well.
+ frameRectsChanged();
+}
+
+void FrameView::scrollContentsSlowPathInternal(const IntRect& updateRect)
+{
+ hostWindow()->invalidateContentsForSlowScroll(updateRect);
+}
+
+IntPoint FrameView::rootViewToContents(const IntPoint& rootViewPoint) const
+{
+ IntPoint viewPoint = convertFromContainingWindow(rootViewPoint);
+ return viewPoint + scrollOffset();
+}
+
+IntPoint FrameView::contentsToRootView(const IntPoint& contentsPoint) const
+{
+ IntPoint viewPoint = contentsPoint - scrollOffset();
+ return convertToContainingWindow(viewPoint);
+}
+
+IntRect FrameView::rootViewToContents(const IntRect& rootViewRect) const
+{
+ IntRect viewRect = convertFromContainingWindow(rootViewRect);
+ viewRect.move(scrollOffset());
+ return viewRect;
+}
+
+IntRect FrameView::contentsToRootView(const IntRect& contentsRect) const
+{
+ IntRect viewRect = contentsRect;
+ viewRect.move(-scrollOffset());
+ return convertToContainingWindow(viewRect);
+}
+
+IntPoint FrameView::windowToContents(const IntPoint& windowPoint) const
+{
+ IntPoint viewPoint = convertFromContainingWindow(windowPoint);
+ return viewPoint + scrollOffset();
+}
+
+FloatPoint FrameView::windowToContents(const FloatPoint& windowPoint) const
+{
+ FloatPoint viewPoint = convertFromContainingWindow(windowPoint);
+ return viewPoint + scrollOffset();
+}
+
+IntPoint FrameView::contentsToWindow(const IntPoint& contentsPoint) const
+{
+ IntPoint viewPoint = contentsPoint - scrollOffset();
+ return convertToContainingWindow(viewPoint);
+}
+
+IntRect FrameView::windowToContents(const IntRect& windowRect) const
+{
+ IntRect viewRect = convertFromContainingWindow(windowRect);
+ viewRect.move(scrollOffset());
+ return viewRect;
+}
+
+IntRect FrameView::contentsToWindow(const IntRect& contentsRect) const
+{
+ IntRect viewRect = contentsRect;
+ viewRect.move(-scrollOffset());
+ return convertToContainingWindow(viewRect);
+}
+
+IntRect FrameView::contentsToScreen(const IntRect& rect) const
+{
+ HostWindow* window = hostWindow();
+ if (!window)
+ return IntRect();
+ return window->rootViewToScreen(contentsToRootView(rect));
+}
+
+bool FrameView::containsScrollbarsAvoidingResizer() const
+{
+ return !m_scrollbarsAvoidingResizer;
+}
+
+void FrameView::adjustScrollbarsAvoidingResizerCount(int overlapDelta)
+{
+ int oldCount = m_scrollbarsAvoidingResizer;
+ m_scrollbarsAvoidingResizer += overlapDelta;
+ if (parent()) {
+ toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(overlapDelta);
+ } else if (!scrollbarsSuppressed()) {
+ // If we went from n to 0 or from 0 to n and we're the outermost view,
+ // we need to invalidate the windowResizerRect(), since it will now need to paint
+ // differently.
+ if ((oldCount > 0 && m_scrollbarsAvoidingResizer == 0)
+ || (oldCount == 0 && m_scrollbarsAvoidingResizer > 0))
+ invalidateRect(windowResizerRect());
+ }
+}
+
+void FrameView::setParentInternal(Widget* parentView)
+{
+ if (parentView == parent())
+ return;
+
+ if (m_scrollbarsAvoidingResizer && parent())
+ toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(-m_scrollbarsAvoidingResizer);
+
+ Widget::setParent(parentView);
+
+ if (m_scrollbarsAvoidingResizer && parent())
+ toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(m_scrollbarsAvoidingResizer);
+}
+
+void FrameView::setScrollbarsSuppressed(bool suppressed, bool repaintOnUnsuppress)
+{
+ if (suppressed == m_scrollbarsSuppressed)
+ return;
+
+ m_scrollbarsSuppressed = suppressed;
+
+ if (repaintOnUnsuppress && !suppressed) {
+ if (m_horizontalScrollbar)
+ m_horizontalScrollbar->invalidate();
+ if (m_verticalScrollbar)
+ m_verticalScrollbar->invalidate();
+
+ // Invalidate the scroll corner too on unsuppress.
+ invalidateRect(scrollCornerRect());
+ }
+}
+
+Scrollbar* FrameView::scrollbarAtWindowPoint(const IntPoint& windowPoint)
+{
+ IntPoint viewPoint = convertFromContainingWindow(windowPoint);
+ return scrollbarAtViewPoint(viewPoint);
+}
+
+Scrollbar* FrameView::scrollbarAtViewPoint(const IntPoint& viewPoint)
+{
+ if (m_horizontalScrollbar && m_horizontalScrollbar->shouldParticipateInHitTesting() && m_horizontalScrollbar->frameRect().contains(viewPoint))
+ return m_horizontalScrollbar.get();
+ if (m_verticalScrollbar && m_verticalScrollbar->shouldParticipateInHitTesting() && m_verticalScrollbar->frameRect().contains(viewPoint))
+ return m_verticalScrollbar.get();
+ return 0;
+}
+
+void FrameView::setFrameRectInternal(const IntRect& newRect)
+{
+ IntRect oldRect = frameRect();
+
+ if (newRect == oldRect)
+ return;
+
+ Widget::setFrameRect(newRect);
+
+ updateScrollbars(scrollOffsetDouble());
+
+ frameRectsChanged();
+}
+
+void FrameView::frameRectsChangedInternal()
+{
+ HashSet<RefPtr<Widget> >::const_iterator end = m_children.end();
+ for (HashSet<RefPtr<Widget> >::const_iterator current = m_children.begin(); current != end; ++current)
+ (*current)->frameRectsChanged();
+}
+
+static void positionScrollbarLayer(GraphicsLayer* graphicsLayer, Scrollbar* scrollbar)
+{
+ if (!graphicsLayer || !scrollbar)
+ return;
+
+ IntRect scrollbarRect = scrollbar->frameRect();
+ graphicsLayer->setPosition(scrollbarRect.location());
+
+ if (scrollbarRect.size() == graphicsLayer->size())
+ return;
+
+ graphicsLayer->setSize(scrollbarRect.size());
+
+ if (graphicsLayer->hasContentsLayer()) {
+ graphicsLayer->setContentsRect(IntRect(0, 0, scrollbarRect.width(), scrollbarRect.height()));
+ return;
+ }
+
+ graphicsLayer->setDrawsContent(true);
+ graphicsLayer->setNeedsDisplay();
+}
+
+static void positionScrollCornerLayer(GraphicsLayer* graphicsLayer, const IntRect& cornerRect)
+{
+ if (!graphicsLayer)
+ return;
+ graphicsLayer->setDrawsContent(!cornerRect.isEmpty());
+ graphicsLayer->setPosition(cornerRect.location());
+ if (cornerRect.size() != graphicsLayer->size())
+ graphicsLayer->setNeedsDisplay();
+ graphicsLayer->setSize(cornerRect.size());
+}
+
+void FrameView::positionScrollbarLayers()
+{
+ positionScrollbarLayer(layerForHorizontalScrollbar(), horizontalScrollbar());
+ positionScrollbarLayer(layerForVerticalScrollbar(), verticalScrollbar());
+ positionScrollCornerLayer(layerForScrollCorner(), scrollCornerRect());
+}
+
+bool FrameView::userInputScrollable(ScrollbarOrientation orientation) const
+{
+ ScrollbarMode mode = (orientation == HorizontalScrollbar) ?
+ m_horizontalScrollbarMode : m_verticalScrollbarMode;
+
+ return mode == ScrollbarAuto || mode == ScrollbarAlwaysOn;
+}
+
+bool FrameView::shouldPlaceVerticalScrollbarOnLeft() const
+{
+ return false;
+}
+
+void FrameView::contentRectangleForPaintInvalidationInternal(const IntRect& rect)
+{
+ IntRect paintRect = rect;
+ if (clipsPaintInvalidations())
+ paintRect.intersect(visibleContentRect());
+ if (paintRect.isEmpty())
+ return;
+
+ if (HostWindow* window = hostWindow())
+ window->invalidateContentsAndRootView(contentsToWindow(paintRect));
+}
+
+IntRect FrameView::scrollCornerRect() const
+{
+ IntRect cornerRect;
+
+ if (hasOverlayScrollbars())
+ return cornerRect;
+
+ if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) {
+ cornerRect.unite(IntRect(shouldPlaceVerticalScrollbarOnLeft() ? 0 : 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(shouldPlaceVerticalScrollbarOnLeft() ? 0 : (width() - m_verticalScrollbar->width()),
+ m_verticalScrollbar->height(),
+ m_verticalScrollbar->width(),
+ height() - m_verticalScrollbar->height()));
+ }
+
+ return cornerRect;
+}
+
+bool FrameView::isScrollCornerVisible() const
+{
+ return !scrollCornerRect().isEmpty();
+}
+
+void FrameView::scrollbarStyleChangedInternal()
+{
+ adjustScrollbarOpacity();
+ contentsResized();
+ updateScrollbars(scrollOffsetDouble());
+ positionScrollbarLayers();
+}
+
+void FrameView::updateScrollCornerInternal()
+{
+}
+
+void FrameView::paintScrollCornerInternal(GraphicsContext* context, const IntRect& cornerRect)
+{
+ ScrollbarTheme::theme()->paintScrollCorner(context, cornerRect);
+}
+
+void FrameView::paintScrollbarInternal(GraphicsContext* context, Scrollbar* bar, const IntRect& rect)
+{
+ bar->paint(context, rect);
+}
+
+void FrameView::invalidateScrollCornerRect(const IntRect& rect)
+{
+ invalidateRect(rect);
+}
+
+void FrameView::paintScrollbars(GraphicsContext* context, const IntRect& rect)
+{
+ if (m_horizontalScrollbar && !layerForHorizontalScrollbar())
+ paintScrollbar(context, m_horizontalScrollbar.get(), rect);
+ if (m_verticalScrollbar && !layerForVerticalScrollbar())
+ paintScrollbar(context, m_verticalScrollbar.get(), rect);
+
+ if (layerForScrollCorner())
+ return;
+ paintScrollCorner(context, scrollCornerRect());
+}
+
+void FrameView::paintPanScrollIcon(GraphicsContext* context)
+{
+ DEFINE_STATIC_REF(Image, panScrollIcon, (Image::loadPlatformResource("panIcon")));
+ IntPoint iconGCPoint = m_panScrollIconPoint;
+ if (parent())
+ iconGCPoint = toFrameView(parent())->windowToContents(iconGCPoint);
+ context->drawImage(panScrollIcon, iconGCPoint);
+}
+
+void FrameView::paint(GraphicsContext* context, const IntRect& rect)
+{
+ notifyPageThatContentAreaWillPaint();
+
+ IntRect documentDirtyRect = rect;
+ IntRect visibleAreaWithoutScrollbars(location(), visibleContentRect().size());
+ documentDirtyRect.intersect(visibleAreaWithoutScrollbars);
+
+ if (!documentDirtyRect.isEmpty()) {
+ GraphicsContextStateSaver stateSaver(*context);
+
+ context->translate(x() - scrollX(), y() - scrollY());
+ context->clip(visibleContentRect());
+
+ documentDirtyRect.moveBy(-location() + scrollPosition());
+ paintContents(context, documentDirtyRect);
+ }
+
+ calculateAndPaintOverhangAreas(context, rect);
+
+ // Now paint the scrollbars.
+ if (!m_scrollbarsSuppressed && (m_horizontalScrollbar || m_verticalScrollbar)) {
+ GraphicsContextStateSaver stateSaver(*context);
+ IntRect scrollViewDirtyRect = rect;
+ IntRect visibleAreaWithScrollbars(location(), visibleContentRect(IncludeScrollbars).size());
+ scrollViewDirtyRect.intersect(visibleAreaWithScrollbars);
+ context->translate(x(), y());
+ scrollViewDirtyRect.moveBy(-location());
+ context->clip(IntRect(IntPoint(), visibleAreaWithScrollbars.size()));
+
+ paintScrollbars(context, scrollViewDirtyRect);
+ }
+
+ // Paint the panScroll Icon
+ if (m_drawPanScrollIcon)
+ paintPanScrollIcon(context);
+}
+
+void FrameView::calculateOverhangAreasForPainting(IntRect& horizontalOverhangRect, IntRect& verticalOverhangRect)
+{
+ int verticalScrollbarWidth = (verticalScrollbar() && !verticalScrollbar()->isOverlayScrollbar())
+ ? verticalScrollbar()->width() : 0;
+ int horizontalScrollbarHeight = (horizontalScrollbar() && !horizontalScrollbar()->isOverlayScrollbar())
+ ? horizontalScrollbar()->height() : 0;
+
+ int physicalScrollY = scrollPosition().y() + scrollOrigin().y();
+ if (physicalScrollY < 0) {
+ horizontalOverhangRect = frameRect();
+ horizontalOverhangRect.setHeight(-physicalScrollY);
+ horizontalOverhangRect.setWidth(horizontalOverhangRect.width() - verticalScrollbarWidth);
+ } else if (contentsHeight() && physicalScrollY > contentsHeight() - visibleHeight()) {
+ int height = physicalScrollY - (contentsHeight() - visibleHeight());
+ horizontalOverhangRect = frameRect();
+ horizontalOverhangRect.setY(frameRect().maxY() - height - horizontalScrollbarHeight);
+ horizontalOverhangRect.setHeight(height);
+ horizontalOverhangRect.setWidth(horizontalOverhangRect.width() - verticalScrollbarWidth);
+ }
+
+ int physicalScrollX = scrollPosition().x() + scrollOrigin().x();
+ if (physicalScrollX < 0) {
+ verticalOverhangRect.setWidth(-physicalScrollX);
+ verticalOverhangRect.setHeight(frameRect().height() - horizontalOverhangRect.height() - horizontalScrollbarHeight);
+ verticalOverhangRect.setX(frameRect().x());
+ if (horizontalOverhangRect.y() == frameRect().y())
+ verticalOverhangRect.setY(frameRect().y() + horizontalOverhangRect.height());
+ else
+ verticalOverhangRect.setY(frameRect().y());
+ } else if (contentsWidth() && physicalScrollX > contentsWidth() - visibleWidth()) {
+ int width = physicalScrollX - (contentsWidth() - visibleWidth());
+ verticalOverhangRect.setWidth(width);
+ verticalOverhangRect.setHeight(frameRect().height() - horizontalOverhangRect.height() - horizontalScrollbarHeight);
+ verticalOverhangRect.setX(frameRect().maxX() - width - verticalScrollbarWidth);
+ if (horizontalOverhangRect.y() == frameRect().y())
+ verticalOverhangRect.setY(frameRect().y() + horizontalOverhangRect.height());
+ else
+ verticalOverhangRect.setY(frameRect().y());
+ }
+}
+
+void FrameView::updateOverhangAreas()
+{
+ HostWindow* window = hostWindow();
+ if (!window)
+ return;
+
+ IntRect horizontalOverhangRect;
+ IntRect verticalOverhangRect;
+ calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect);
+ if (!horizontalOverhangRect.isEmpty())
+ window->invalidateContentsAndRootView(horizontalOverhangRect);
+ if (!verticalOverhangRect.isEmpty())
+ window->invalidateContentsAndRootView(verticalOverhangRect);
+}
+
+void FrameView::paintOverhangAreasInternal(GraphicsContext* context, const IntRect& horizontalOverhangRect, const IntRect& verticalOverhangRect, const IntRect& dirtyRect)
+{
+ ScrollbarTheme::theme()->paintOverhangBackground(context, horizontalOverhangRect, verticalOverhangRect, dirtyRect);
+ ScrollbarTheme::theme()->paintOverhangShadows(context, scrollOffset(), horizontalOverhangRect, verticalOverhangRect, dirtyRect);
+}
+
+void FrameView::calculateAndPaintOverhangAreas(GraphicsContext* context, const IntRect& dirtyRect)
+{
+ IntRect horizontalOverhangRect;
+ IntRect verticalOverhangRect;
+ calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect);
+
+ if (dirtyRect.intersects(horizontalOverhangRect) || dirtyRect.intersects(verticalOverhangRect))
+ paintOverhangAreas(context, horizontalOverhangRect, verticalOverhangRect, dirtyRect);
+}
+
+void FrameView::calculateAndPaintOverhangBackground(GraphicsContext* context, const IntRect& dirtyRect)
+{
+ IntRect horizontalOverhangRect;
+ IntRect verticalOverhangRect;
+ calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect);
+
+ if (dirtyRect.intersects(horizontalOverhangRect) || dirtyRect.intersects(verticalOverhangRect))
+ ScrollbarTheme::theme()->paintOverhangBackground(context, horizontalOverhangRect, verticalOverhangRect, dirtyRect);
+}
+
+bool FrameView::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 FrameView::scrollbarCornerPresent() const
+{
+ return (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0)
+ || (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0);
+}
+
+IntRect FrameView::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& localRect) const
+{
+ // Scrollbars won't be transformed within us
+ IntRect newRect = localRect;
+ newRect.moveBy(scrollbar->location());
+ return newRect;
+}
+
+IntRect FrameView::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
+{
+ IntRect newRect = parentRect;
+ // Scrollbars won't be transformed within us
+ newRect.moveBy(-scrollbar->location());
+ return newRect;
+}
+
+// FIXME: test these on windows
+IntPoint FrameView::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& localPoint) const
+{
+ // Scrollbars won't be transformed within us
+ IntPoint newPoint = localPoint;
+ newPoint.moveBy(scrollbar->location());
+ return newPoint;
+}
+
+IntPoint FrameView::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
+{
+ IntPoint newPoint = parentPoint;
+ // Scrollbars won't be transformed within us
+ newPoint.moveBy(-scrollbar->location());
+ return newPoint;
+}
+
+void FrameView::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 FrameView::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 FrameView::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();
+}
+
+void FrameView::addPanScrollIcon(const IntPoint& iconPosition)
+{
+ HostWindow* window = hostWindow();
+ if (!window)
+ return;
+ m_drawPanScrollIcon = true;
+ m_panScrollIconPoint = IntPoint(iconPosition.x() - panIconSizeLength / 2 , iconPosition.y() - panIconSizeLength / 2);
+ window->invalidateContentsAndRootView(IntRect(m_panScrollIconPoint, IntSize(panIconSizeLength, panIconSizeLength)));
+}
+
+void FrameView::removePanScrollIcon()
+{
+ HostWindow* window = hostWindow();
+ if (!window)
+ return;
+ m_drawPanScrollIcon = false;
+ window->invalidateContentsAndRootView(IntRect(m_panScrollIconPoint, IntSize(panIconSizeLength, panIconSizeLength)));
+}
+
+void FrameView::setScrollOrigin(const IntPoint& origin, bool updatePositionAtAll, bool updatePositionSynchronously)
+{
+ if (scrollOrigin() == origin)
+ return;
+
+ ScrollableArea::setScrollOrigin(origin);
+
+ // Update if the scroll origin changes, since our position will be different if the content size did not change.
+ if (updatePositionAtAll && updatePositionSynchronously)
+ updateScrollbars(scrollOffsetDouble());
+}
+
} // namespace blink
« no previous file with comments | « Source/core/frame/FrameView.h ('k') | Source/core/html/HTMLFrameOwnerElement.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698