| Index: webkit/port/platform/ScrollViewWin.cpp
|
| ===================================================================
|
| --- webkit/port/platform/ScrollViewWin.cpp (revision 3423)
|
| +++ webkit/port/platform/ScrollViewWin.cpp (working copy)
|
| @@ -1,1229 +0,0 @@
|
| -/*
|
| - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
|
| - *
|
| - * Redistribution and use in source and binary forms, with or without
|
| - * modification, are permitted provided that the following conditions
|
| - * are met:
|
| - * 1. Redistributions of source code must retain the above copyright
|
| - * notice, this list of conditions and the following disclaimer.
|
| - * 2. Redistributions in binary form must reproduce the above copyright
|
| - * notice, this list of conditions and the following disclaimer in the
|
| - * documentation and/or other materials provided with the distribution.
|
| - *
|
| - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
|
| - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
| - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
|
| - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
| - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
| - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
| - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
| - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| - */
|
| -
|
| -#include "config.h"
|
| -#include "ScrollView.h"
|
| -
|
| -#include "Chrome.h"
|
| -#include "ChromeClient.h"
|
| -#include "FloatRect.h"
|
| -#include "FocusController.h"
|
| -#include "Frame.h"
|
| -#include "FrameView.h"
|
| -#include "GraphicsContext.h"
|
| -#include "IntRect.h"
|
| -#include "NotImplemented.h"
|
| -#include "Page.h"
|
| -#include "PlatformScrollBar.h"
|
| -#include "PlatformMouseEvent.h"
|
| -#include "PlatformWheelEvent.h"
|
| -#include "Range.h"
|
| -#include "RenderTheme.h"
|
| -#include "ScrollBar.h"
|
| -#include "SkiaUtils.h"
|
| -#include "WidgetClientWin.h"
|
| -#include <algorithm>
|
| -#include <wtf/Assertions.h>
|
| -#include <wtf/HashSet.h>
|
| -
|
| -#undef LOG
|
| -#include "base/gfx/platform_canvas_win.h"
|
| -#include "webkit/glue/webframe_impl.h"
|
| -#include "webkit/glue/webview_impl.h"
|
| -
|
| -using namespace std;
|
| -
|
| -namespace WebCore {
|
| -
|
| -class ScrollView::ScrollViewPrivate : public ScrollbarClient {
|
| -public:
|
| - ScrollViewPrivate(ScrollView* view)
|
| - : m_view(view)
|
| - , m_hasStaticBackground(false)
|
| - , m_scrollbarsSuppressed(false)
|
| - , m_inUpdateScrollbars(false)
|
| - , m_scrollbarsAvoidingResizer(0)
|
| - , m_vScrollbarMode(ScrollbarAuto)
|
| - , m_hScrollbarMode(ScrollbarAuto)
|
| - , m_visible(false)
|
| - , m_attachedToWindow(false)
|
| - , m_panScrollIconPoint(0,0)
|
| - , m_drawPanScrollIcon(false)
|
| - {
|
| - }
|
| -
|
| - ~ScrollViewPrivate()
|
| - {
|
| - setHasHorizontalScrollbar(false);
|
| - setHasVerticalScrollbar(false);
|
| - }
|
| -
|
| - void setHasHorizontalScrollbar(bool hasBar);
|
| - void setHasVerticalScrollbar(bool hasBar);
|
| -
|
| - virtual void valueChanged(Scrollbar*);
|
| - virtual IntRect windowClipRect() const;
|
| - virtual bool isActive() const;
|
| -
|
| - void scrollBackingStore(const IntSize& scrollDelta);
|
| -
|
| - // Get the vector containing the result from the FindInPage operation.
|
| - const Vector<RefPtr<Range> >* getTickmarks() const;
|
| -
|
| - // Retrieves the index of the active tickmark for a given frame. If the
|
| - // frame does not have an active tickmark (for example if the active
|
| - // tickmark resides in another frame) this function returns kNoTickmark.
|
| - size_t ScrollView::ScrollViewPrivate::getActiveTickmarkIndex() const;
|
| -
|
| - // This is a helper function for accessing the bitmaps that have been cached
|
| - // in the renderer.
|
| - const SkBitmap* GetPreloadedBitmapFromRenderer(int resource_id) const;
|
| -
|
| - // Highlight the matches found during FindInPage operation.
|
| - void highlightMatches(GraphicsContext* context) const;
|
| -
|
| - // Highlights the node selected in the DOM inspector.
|
| - void highlightInspectedNode(GraphicsContext* context, Frame* frame) const;
|
| -
|
| - // Highlight a certain Range on the page.
|
| - void highlightRange(HDC hdc, HDC mem_dc, RefPtr<Range> range) const;
|
| -
|
| - void setAllowsScrolling(bool);
|
| - bool allowsScrolling() const;
|
| -
|
| - ScrollView* m_view;
|
| - IntSize m_scrollOffset;
|
| - IntSize m_contentsSize;
|
| - bool m_hasStaticBackground;
|
| - bool m_scrollbarsSuppressed;
|
| - bool m_inUpdateScrollbars;
|
| - int m_scrollbarsAvoidingResizer;
|
| - ScrollbarMode m_vScrollbarMode;
|
| - ScrollbarMode m_hScrollbarMode;
|
| - RefPtr<PlatformScrollbar> m_vBar;
|
| - RefPtr<PlatformScrollbar> m_hBar;
|
| - HRGN m_dirtyRegion;
|
| - HashSet<Widget*> m_children;
|
| - bool m_visible;
|
| - bool m_attachedToWindow;
|
| - IntPoint m_panScrollIconPoint;
|
| - bool m_drawPanScrollIcon;
|
| -};
|
| -
|
| -const int panIconSizeLength = 20;
|
| -
|
| -void ScrollView::ScrollViewPrivate::setHasHorizontalScrollbar(bool hasBar)
|
| -{
|
| - if (Scrollbar::hasPlatformScrollbars()) {
|
| - if (hasBar && !m_hBar) {
|
| - m_hBar = PlatformScrollbar::create(this, HorizontalScrollbar, RegularScrollbar);
|
| - m_view->addChild(m_hBar.get());
|
| - } else if (!hasBar && m_hBar) {
|
| - m_view->removeChild(m_hBar.get());
|
| - m_hBar = 0;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ScrollView::ScrollViewPrivate::setHasVerticalScrollbar(bool hasBar)
|
| -{
|
| - if (Scrollbar::hasPlatformScrollbars()) {
|
| - if (hasBar && !m_vBar) {
|
| - m_vBar = PlatformScrollbar::create(this, VerticalScrollbar, RegularScrollbar);
|
| - m_view->addChild(m_vBar.get());
|
| - } else if (!hasBar && m_vBar) {
|
| - m_view->removeChild(m_vBar.get());
|
| - m_vBar = 0;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ScrollView::ScrollViewPrivate::valueChanged(Scrollbar* bar)
|
| -{
|
| - // Figure out if we really moved.
|
| - IntSize newOffset = m_scrollOffset;
|
| - if (bar) {
|
| - if (bar == m_hBar)
|
| - newOffset.setWidth(bar->value());
|
| - else if (bar == m_vBar)
|
| - newOffset.setHeight(bar->value());
|
| - }
|
| - IntSize scrollDelta = newOffset - m_scrollOffset;
|
| - if (scrollDelta == IntSize())
|
| - return;
|
| - m_scrollOffset = newOffset;
|
| -
|
| - if (m_scrollbarsSuppressed)
|
| - return;
|
| -
|
| - scrollBackingStore(scrollDelta);
|
| -
|
| - if (Frame* frame = static_cast<FrameView*>(m_view)->frame()) {
|
| - frame->sendScrollEvent();
|
| -
|
| - // Inform the delegate that the scroll position has changed.
|
| - WidgetClientWin* client =
|
| - static_cast<WidgetClientWin*>(m_view->client());
|
| - if (client)
|
| - client->onScrollPositionChanged(m_view);
|
| - }
|
| -}
|
| -
|
| -void ScrollView::ScrollViewPrivate::scrollBackingStore(const IntSize& scrollDelta)
|
| -{
|
| - // Since scrolling is double buffered, we will be blitting the scroll view's intersection
|
| - // with the clip rect every time to keep it smooth.
|
| -
|
| - IntRect clipRect = m_view->windowClipRect();
|
| - IntRect scrollViewRect = m_view->convertToContainingWindow(IntRect(0, 0, m_view->visibleWidth(), m_view->visibleHeight()));
|
| -
|
| - // Negative when our frame is smaller than the min scrollbar width.
|
| - if (scrollViewRect.width() < 0)
|
| - scrollViewRect.setWidth(0);
|
| - if (scrollViewRect.height() < 0)
|
| - scrollViewRect.setHeight(0);
|
| -
|
| - if (!m_hasStaticBackground) { // The main frame can just blit the WebView window
|
| - // FIXME: Find a way to blit subframes without blitting overlapping content
|
| - m_view->scrollBackingStore(-scrollDelta.width(), -scrollDelta.height(), scrollViewRect, clipRect);
|
| - } else {
|
| - IntRect updateRect = clipRect;
|
| - updateRect.intersect(scrollViewRect);
|
| -
|
| - // We need to go ahead and repaint the entire backing store. Do it now before moving the
|
| - // plugins.
|
| - m_view->addToDirtyRegion(updateRect);
|
| - m_view->updateBackingStore();
|
| - }
|
| -
|
| - // This call will move child HWNDs (plugins) and invalidate them as well.
|
| - m_view->geometryChanged();
|
| -}
|
| -
|
| -void ScrollView::ScrollViewPrivate::setAllowsScrolling(bool flag)
|
| -{
|
| - if (flag && m_vScrollbarMode == ScrollbarAlwaysOff)
|
| - m_vScrollbarMode = ScrollbarAuto;
|
| - else if (!flag)
|
| - m_vScrollbarMode = ScrollbarAlwaysOff;
|
| -
|
| - if (flag && m_hScrollbarMode == ScrollbarAlwaysOff)
|
| - m_hScrollbarMode = ScrollbarAuto;
|
| - else if (!flag)
|
| - m_hScrollbarMode = ScrollbarAlwaysOff;
|
| -
|
| - m_view->updateScrollbars(m_scrollOffset);
|
| -}
|
| -
|
| -bool ScrollView::ScrollViewPrivate::allowsScrolling() const
|
| -{
|
| - // Return YES if either horizontal or vertical scrolling is allowed.
|
| - return m_hScrollbarMode != ScrollbarAlwaysOff || m_vScrollbarMode != ScrollbarAlwaysOff;
|
| -}
|
| -
|
| -IntRect ScrollView::ScrollViewPrivate::windowClipRect() const
|
| -{
|
| - // FrameView::windowClipRect() will exclude the scrollbars, but here we
|
| - // want to include them, so we are forced to cast to FrameView in order to
|
| - // call the non-virtual version of windowClipRect :-(
|
| - //
|
| - // The non-frame case exists to support FramelessScrollView.
|
| -
|
| - const FrameView* frameView = static_cast<const FrameView*>(m_view);
|
| - if (frameView->frame())
|
| - return frameView->windowClipRect(false);
|
| -
|
| - return m_view->windowClipRect();
|
| -}
|
| -
|
| -bool ScrollView::ScrollViewPrivate::isActive() const
|
| -{
|
| - Page* page = static_cast<const FrameView*>(m_view)->frame()->page();
|
| - return page && page->focusController()->isActive();
|
| -}
|
| -
|
| -const Vector<RefPtr<Range> >* ScrollView::ScrollViewPrivate::getTickmarks() const
|
| -{
|
| - FrameView* view = static_cast<FrameView*>(m_view);
|
| - ASSERT(view);
|
| - Frame* frame = view->frame();
|
| -
|
| - if (!frame)
|
| - return NULL; // NOTE: Frame can be null for dropdown boxes.
|
| -
|
| - WidgetClientWin* c = static_cast<WidgetClientWin*>(m_view->client());
|
| - ASSERT(c);
|
| - return c->getTickmarks(view->frame());
|
| -}
|
| -
|
| -size_t ScrollView::ScrollViewPrivate::getActiveTickmarkIndex() const
|
| -{
|
| - FrameView* view = static_cast<FrameView*>(m_view);
|
| - ASSERT(view);
|
| - Frame* frame = view->frame();
|
| -
|
| - // NOTE: Frame can be null for dropdown boxes.
|
| - if (!frame)
|
| - return WidgetClientWin::kNoTickmark;
|
| -
|
| - WidgetClientWin* c = static_cast<WidgetClientWin*>(m_view->client());
|
| - ASSERT(c);
|
| - return c->getActiveTickmarkIndex(view->frame());
|
| -}
|
| -
|
| -const SkBitmap* ScrollView::ScrollViewPrivate::GetPreloadedBitmapFromRenderer(
|
| - int resource_id) const
|
| -{
|
| - WidgetClientWin* c = static_cast<WidgetClientWin*>(m_view->client());
|
| - if (!c)
|
| - return NULL;
|
| -
|
| - return c->getPreloadedResourceBitmap(resource_id);
|
| -}
|
| -
|
| -void ScrollView::ScrollViewPrivate::highlightMatches(
|
| - GraphicsContext* context) const
|
| -{
|
| - if (context->paintingDisabled())
|
| - return;
|
| -
|
| - const Vector<RefPtr<Range> >* tickmarks = getTickmarks();
|
| - if (!tickmarks || tickmarks->isEmpty())
|
| - return;
|
| -
|
| - context->save();
|
| - context->translate(m_view->x(), m_view->y());
|
| -
|
| - // NOTE: We tolerate the platformContext() call here because the scrollbars
|
| - // will not be serialized, i.e. composition is done in the renderer and
|
| - // never in the browser.
|
| - // Prepare for drawing the arrows along the scroll bar.
|
| - gfx::PlatformCanvas* canvas = context->platformContext()->canvas();
|
| -
|
| - int horz_start = 0;
|
| - int horz_end = m_view->width();
|
| - int vert_start = 0;
|
| - int vert_end = m_view->height();
|
| -
|
| - if (m_vBar) {
|
| - // Account for the amount of scrolling on the vertical scroll bar.
|
| - vert_start += m_scrollOffset.height();
|
| - vert_end += m_scrollOffset.height();
|
| - // Don't draw atop the vertical scrollbar.
|
| - horz_end -= PlatformScrollbar::verticalScrollbarWidth() + 1;
|
| - }
|
| -
|
| - if (m_hBar) {
|
| - // Account for the amount of scrolling on the horizontal scroll bar.
|
| - horz_start += m_scrollOffset.width();
|
| - horz_end += m_scrollOffset.width();
|
| - // Don't draw atop the horizontal scrollbar.
|
| - vert_end -= PlatformScrollbar::horizontalScrollbarHeight() + 1;
|
| - }
|
| -
|
| - IntRect view_rect(IntPoint(), m_view->size());
|
| - HDC hdc = context->getWindowsContext(view_rect);
|
| -
|
| - // We create a memory DC, copy the bits we want to highlight to the DC and
|
| - // then MERGE_COPY pieces of it back with a yellow brush selected (which
|
| - // gives them yellow highlighting).
|
| - HDC mem_dc = CreateCompatibleDC(hdc);
|
| - HBITMAP mem_bmp = CreateCompatibleBitmap(hdc, m_view->width(),
|
| - m_view->height());
|
| - HGDIOBJ old_bmp = SelectObject(mem_dc, mem_bmp);
|
| -
|
| - // Now create a brush for hit highlighting. This is needed for the MERGECOPY
|
| - // to paint a yellow highlight onto the matches found. For more details, see
|
| - // the documentation for BitBlt.
|
| - static const COLORREF kFillColor = RGB(255, 250, 150); // Light yellow.
|
| - HGDIOBJ inactive_brush = CreateSolidBrush(kFillColor);
|
| - static const COLORREF kFillColorActive = RGB(255, 150, 50); // Orange.
|
| - HGDIOBJ active_brush = CreateSolidBrush(kFillColorActive);
|
| - HGDIOBJ old_brush = SelectObject(hdc, inactive_brush);
|
| -
|
| - // Keep a copy of what's on screen, so we can MERGECOPY it back later for
|
| - // the purpose of highlighting the text.
|
| - BitBlt(mem_dc, 0, 0, m_view->width(), m_view->height(),
|
| - hdc, 0, 0, SRCCOPY);
|
| -
|
| - const size_t active_tickmark = getActiveTickmarkIndex();
|
| - for (Vector<RefPtr<Range> >::const_iterator i = tickmarks->begin();
|
| - i != tickmarks->end(); ++i) {
|
| - const RefPtr<Range> range = (*i);
|
| - const IntRect& bounds = range->boundingBox();
|
| - // To highlight the word, we check if the rectangle boundary is within
|
| - // the bounds vertically as well as horizontally.
|
| - if (bounds.bottomRight().y() > vert_start &&
|
| - bounds.topLeft().y() < vert_end &&
|
| - bounds.bottomRight().x() > horz_start &&
|
| - bounds.topLeft().x() < horz_end &&
|
| - WebFrameImpl::RangeShouldBeHighlighted(range.get())) {
|
| - // We highlight the active tick-mark with a green color instead
|
| - // of the normal yellow color.
|
| - SelectObject(hdc, ((i - tickmarks->begin()) == active_tickmark) ?
|
| - active_brush : inactive_brush);
|
| - highlightRange(hdc, mem_dc, range);
|
| - }
|
| - }
|
| -
|
| - SelectObject(mem_dc, old_brush);
|
| - DeleteObject(active_brush);
|
| - DeleteObject(inactive_brush);
|
| -
|
| - SelectObject(mem_dc, old_bmp);
|
| - DeleteObject(mem_bmp);
|
| -
|
| - DeleteDC(mem_dc);
|
| -
|
| - context->releaseWindowsContext(hdc, view_rect);
|
| - context->restore();
|
| -}
|
| -
|
| -// TODO(ojan): http://b/1143983 make this work for inline elements as they can
|
| -// wrap (use highlightRange instead?)
|
| -void ScrollView::ScrollViewPrivate::highlightInspectedNode(
|
| - GraphicsContext* context, Frame* frame) const
|
| -{
|
| - WebViewImpl* c = static_cast<WebViewImpl*>(m_view->client());
|
| - const WebCore::Node* inspected_node = c->getInspectedNode(frame);
|
| -
|
| - if (!inspected_node)
|
| - return;
|
| -
|
| - SkPaint paint;
|
| - paint.setARGB(122, 255, 225, 0); // Yellow
|
| -
|
| - // TODO(ojan): http://b/1143991 Once we sync a Skia version that supports
|
| - // it, use SkPorterDuff::kScreenMode and remove the transparency.
|
| - // Then port highlightMatches/highlightRanges to use this as well.
|
| - // Although, perhaps the web inspector really should be using
|
| - // an alpha overlay? It's less pretty, but more clear what node
|
| - // is being overlayed. In this case, the TODO is to make
|
| - // highlightMatches/Ranges use Skia and to leave this as is.
|
| - //
|
| - // paint.setPorterDuffXfermode(SkPorterDuff::kScreenMode);
|
| -
|
| - // TODO(ojan): http://b/1143975 Draw the padding/border/margin boxes in
|
| - // different colors.
|
| - context->platformContext()->paintSkPaint(inspected_node->getRect(), paint);
|
| -}
|
| -
|
| -void ScrollView::ScrollViewPrivate::highlightRange(HDC hdc, HDC mem_dc,
|
| - RefPtr<Range> range) const {
|
| - // We need to figure out whether the match that we want to
|
| - // highlight is on a single line or on multiple lines.
|
| - IntRect start = VisiblePosition(range->startPosition()).caretRect();
|
| - IntRect end = VisiblePosition(range->endPosition()).caretRect();
|
| - IntRect bounds = range->boundingBox();
|
| -
|
| - // Multi-line bounds have different y pos for start and end.
|
| - if (start.y() == end.y()) {
|
| - int x = bounds.topLeft().x() - m_scrollOffset.width();
|
| - int y = bounds.topLeft().y() - m_scrollOffset.height();
|
| - int w = bounds.bottomRight().x() - bounds.topLeft().x() + 1;
|
| - int h = bounds.bottomRight().y() - bounds.topLeft().y() + 1;
|
| -
|
| - // MERGECOPY the relevant bits back, creating a highlight.
|
| - BitBlt(hdc, x, y, w, h, mem_dc, x, y, MERGECOPY);
|
| - } else {
|
| - // Multi line bounds, for example, when we need to highlight
|
| - // all the numbers (and only the numbers) in this block of
|
| - // text:
|
| - //
|
| - // xxxxxxxxxxxxxxxx11111111
|
| - // 222222222222222222222222
|
| - // 222222222222222222222222
|
| - // 333333333333333xxxxxxxxx
|
| - //
|
| - // In this case, the bounding box will contain all the text,
|
| - // (including the exes (x)). We highlight in three steps.
|
| - // First we highlight the segment containing the ones (1)
|
| - // above. Then the whole middle section is highlighted, or the
|
| - // twos (2), and finally the remaining segment consisting of
|
| - // the threes (3) is highlighted.
|
| -
|
| - const int row_height = start.height();
|
| - int x = 0, y = 0, w = 0, h = 0;
|
| -
|
| - // The start and end caret can be outside the bounding box, for leading
|
| - // and trailing whitespace and we should not highlight those.
|
| - if (start.intersects(bounds)) {
|
| - // Highlight the first segment.
|
| - x = start.x() - m_scrollOffset.width();
|
| - y = start.y() - m_scrollOffset.height();
|
| - w = bounds.topRight().x() - start.x() + 1;
|
| - h = row_height;
|
| -
|
| - BitBlt(hdc, x, y, w, h, mem_dc, x, y, MERGECOPY);
|
| - }
|
| -
|
| - // Figure out how large the middle section is.
|
| - int rows_between = (end.y() - start.y()) / row_height - 1;
|
| -
|
| - if (rows_between > 0) {
|
| - // Highlight the middle segment.
|
| - x = bounds.x() - m_scrollOffset.width();
|
| - y = bounds.y() - m_scrollOffset.height() + row_height;
|
| - w = bounds.width();
|
| - h = rows_between * row_height;
|
| -
|
| - BitBlt(hdc, x, y, w, h, mem_dc, x, y, MERGECOPY);
|
| - }
|
| -
|
| - // The end caret might not intersect the bounding box, for example
|
| - // when highlighting the last letter of a line that wraps. In that
|
| - // case the end caret is set to the beginning of the next line, and
|
| - // since it doesn't intersect with the bounding box we don't need to
|
| - // highlight.
|
| - if (end.intersects(bounds)) {
|
| - // Highlight the remaining segment.
|
| - x = bounds.bottomLeft().x() - m_scrollOffset.width();
|
| - y = bounds.bottomLeft().y() - m_scrollOffset.height() -
|
| - row_height + 1;
|
| - w = end.x() - bounds.bottomLeft().x();
|
| - h = row_height;
|
| -
|
| - BitBlt(hdc, x, y, w, h, mem_dc, x, y, MERGECOPY);
|
| - }
|
| - }
|
| -}
|
| -
|
| -ScrollView::ScrollView()
|
| -{
|
| - m_data = new ScrollViewPrivate(this);
|
| -}
|
| -
|
| -ScrollView::~ScrollView()
|
| -{
|
| - delete m_data;
|
| -}
|
| -
|
| -void ScrollView::updateContents(const IntRect& rect, bool now)
|
| -{
|
| - if (rect.isEmpty())
|
| - return;
|
| -
|
| - IntRect containingWindowRect = contentsToWindow(rect);
|
| -
|
| - if (containingWindowRect.x() < 0)
|
| - containingWindowRect.setX(0);
|
| - if (containingWindowRect.y() < 0)
|
| - containingWindowRect.setY(0);
|
| -
|
| - updateWindowRect(containingWindowRect, now);
|
| -}
|
| -
|
| -void ScrollView::updateWindowRect(const IntRect& rect, bool now)
|
| -{
|
| - // TODO(dglazkov): make sure this is actually the right way to do this
|
| -
|
| - // Cache the dirty spot.
|
| - addToDirtyRegion(rect);
|
| -
|
| - // since painting always happens asynchronously, we don't have a way to
|
| - // honor the "now" parameter. it is unclear if it matters.
|
| - if (now) {
|
| - // TODO(iyengar): Should we force a layout to occur here?
|
| - geometryChanged();
|
| - }
|
| -}
|
| -
|
| -void ScrollView::update()
|
| -{
|
| - // TODO(iyengar): Should we force a layout to occur here?
|
| - geometryChanged();
|
| -}
|
| -
|
| -int ScrollView::visibleWidth() const
|
| -{
|
| - return width() - (m_data->m_vBar ? m_data->m_vBar->width() : 0);
|
| -}
|
| -
|
| -int ScrollView::visibleHeight() const
|
| -{
|
| - return height() - (m_data->m_hBar ? m_data->m_hBar->height() : 0);
|
| -}
|
| -
|
| -FloatRect ScrollView::visibleContentRect() const
|
| -{
|
| - return FloatRect(contentsX(), contentsY(), visibleWidth(), visibleHeight());
|
| -}
|
| -
|
| -FloatRect ScrollView::visibleContentRectConsideringExternalScrollers() const
|
| -{
|
| - // external scrollers not supported for now
|
| - return visibleContentRect();
|
| -}
|
| -
|
| -void ScrollView::setContentsPos(int newX, int newY)
|
| -{
|
| - int dx = newX - contentsX();
|
| - int dy = newY - contentsY();
|
| - scrollBy(dx, dy);
|
| -}
|
| -
|
| -void ScrollView::resizeContents(int w, int h)
|
| -{
|
| - IntSize newContentsSize(w, h);
|
| - if (m_data->m_contentsSize != newContentsSize) {
|
| - m_data->m_contentsSize = newContentsSize;
|
| - updateScrollbars(m_data->m_scrollOffset);
|
| - }
|
| -}
|
| -
|
| -void ScrollView::setFrameGeometry(const IntRect& newGeometry)
|
| -{
|
| - IntRect normalizedNewGeometry = newGeometry;
|
| -
|
| - // Webkit sometimes attempts to set negative sizes due to
|
| - // sloppy calculations of width with margins and such.
|
| - // (RenderPart:updateWidgetPosition is one example.)
|
| - // Safeguard against this and prevent negative heights/widths.
|
| - if (normalizedNewGeometry.width() < 0)
|
| - normalizedNewGeometry.setWidth(0);
|
| - if (normalizedNewGeometry.height() < 0)
|
| - normalizedNewGeometry.setHeight(0);
|
| -
|
| - IntRect oldGeometry = frameGeometry();
|
| - Widget::setFrameGeometry(normalizedNewGeometry);
|
| -
|
| - if (normalizedNewGeometry == oldGeometry)
|
| - return;
|
| -
|
| - if (normalizedNewGeometry.width() != oldGeometry.width() ||
|
| - normalizedNewGeometry.height() != oldGeometry.height()) {
|
| - updateScrollbars(m_data->m_scrollOffset);
|
| -
|
| - // when used to display a popup menu, we do not have a frame
|
| - FrameView* frameView = static_cast<FrameView*>(this);
|
| - if (frameView->frame())
|
| - frameView->setNeedsLayout();
|
| - }
|
| -
|
| - geometryChanged();
|
| -}
|
| -
|
| -int ScrollView::contentsX() const
|
| -{
|
| - return scrollOffset().width();
|
| -}
|
| -
|
| -int ScrollView::contentsY() const
|
| -{
|
| - return scrollOffset().height();
|
| -}
|
| -
|
| -int ScrollView::contentsWidth() const
|
| -{
|
| - return m_data->m_contentsSize.width();
|
| -}
|
| -
|
| -int ScrollView::contentsHeight() const
|
| -{
|
| - return m_data->m_contentsSize.height();
|
| -}
|
| -
|
| -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);
|
| -}
|
| -
|
| -IntPoint ScrollView::convertChildToSelf(const Widget* child, const IntPoint& point) const
|
| -{
|
| - IntPoint newPoint = point;
|
| - if (child != m_data->m_hBar && child != m_data->m_vBar)
|
| - newPoint = point - scrollOffset();
|
| - return Widget::convertChildToSelf(child, newPoint);
|
| -}
|
| -
|
| -IntPoint ScrollView::convertSelfToChild(const Widget* child, const IntPoint& point) const
|
| -{
|
| - IntPoint newPoint = point;
|
| - if (child != m_data->m_hBar && child != m_data->m_vBar)
|
| - newPoint = point + scrollOffset();
|
| - return Widget::convertSelfToChild(child, newPoint);
|
| -}
|
| -
|
| -IntSize ScrollView::scrollOffset() const
|
| -{
|
| - return m_data->m_scrollOffset;
|
| -}
|
| -
|
| -IntSize ScrollView::maximumScroll() const
|
| -{
|
| - // We should not check whether scrolling is allowed for this view before calculating
|
| - // the maximumScroll. Please refer to http://b/issue?id=1164704, where in scrolling
|
| - // would not work on a scrollview created with scrollbars disabled. The current
|
| - // behavior mirrors Safari's webkit implementation. Firefox also behaves similarly.
|
| - IntSize delta = (m_data->m_contentsSize - IntSize(visibleWidth(), visibleHeight())) - scrollOffset();
|
| - delta.clampNegativeToZero();
|
| - return delta;
|
| -}
|
| -
|
| -void ScrollView::scrollBy(int dx, int dy)
|
| -{
|
| - IntSize scrollOffset = m_data->m_scrollOffset;
|
| - IntSize newScrollOffset = scrollOffset + IntSize(dx, dy).shrunkTo(maximumScroll());
|
| - newScrollOffset.clampNegativeToZero();
|
| -
|
| - if (newScrollOffset == scrollOffset)
|
| - return;
|
| -
|
| - updateScrollbars(newScrollOffset);
|
| -}
|
| -
|
| -void ScrollView::scrollRectIntoViewRecursively(const IntRect& r)
|
| -{
|
| - IntPoint p(max(0, r.x()), max(0, r.y()));
|
| - ScrollView* view = this;
|
| - while (view) {
|
| - view->setContentsPos(p.x(), p.y());
|
| - p.move(view->x() - view->scrollOffset().width(), view->y() - view->scrollOffset().height());
|
| - view = static_cast<ScrollView*>(view->parent());
|
| - }
|
| -}
|
| -
|
| -WebCore::ScrollbarMode ScrollView::hScrollbarMode() const
|
| -{
|
| - return m_data->m_hScrollbarMode;
|
| -}
|
| -
|
| -WebCore::ScrollbarMode ScrollView::vScrollbarMode() const
|
| -{
|
| - return m_data->m_vScrollbarMode;
|
| -}
|
| -
|
| -void ScrollView::suppressScrollbars(bool suppressed, bool repaintOnSuppress)
|
| -{
|
| - m_data->m_scrollbarsSuppressed = suppressed;
|
| - if (repaintOnSuppress && !suppressed) {
|
| - if (m_data->m_hBar)
|
| - m_data->m_hBar->invalidate();
|
| - if (m_data->m_vBar)
|
| - m_data->m_vBar->invalidate();
|
| -
|
| - // Invalidate the scroll corner too on unsuppress.
|
| - IntRect hCorner;
|
| - if (m_data->m_hBar && width() - m_data->m_hBar->width() > 0) {
|
| - hCorner = IntRect(m_data->m_hBar->width(),
|
| - height() - m_data->m_hBar->height(),
|
| - width() - m_data->m_hBar->width(),
|
| - m_data->m_hBar->height());
|
| - invalidateRect(hCorner);
|
| - }
|
| -
|
| - if (m_data->m_vBar && height() - m_data->m_vBar->height() > 0) {
|
| - IntRect vCorner(width() - m_data->m_vBar->width(),
|
| - m_data->m_vBar->height(),
|
| - m_data->m_vBar->width(),
|
| - height() - m_data->m_vBar->height());
|
| - if (vCorner != hCorner)
|
| - invalidateRect(vCorner);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ScrollView::setHScrollbarMode(ScrollbarMode newMode)
|
| -{
|
| - if (m_data->m_hScrollbarMode != newMode) {
|
| - m_data->m_hScrollbarMode = newMode;
|
| - updateScrollbars(m_data->m_scrollOffset);
|
| - }
|
| -}
|
| -
|
| -void ScrollView::setVScrollbarMode(ScrollbarMode newMode)
|
| -{
|
| - if (m_data->m_vScrollbarMode != newMode) {
|
| - m_data->m_vScrollbarMode = newMode;
|
| - updateScrollbars(m_data->m_scrollOffset);
|
| - }
|
| -}
|
| -
|
| -void ScrollView::setScrollbarsMode(ScrollbarMode newMode)
|
| -{
|
| - if (m_data->m_hScrollbarMode != newMode ||
|
| - m_data->m_vScrollbarMode != newMode) {
|
| - m_data->m_hScrollbarMode = m_data->m_vScrollbarMode = newMode;
|
| - updateScrollbars(m_data->m_scrollOffset);
|
| - }
|
| -}
|
| -
|
| -void ScrollView::setStaticBackground(bool flag)
|
| -{
|
| - m_data->m_hasStaticBackground = flag;
|
| -}
|
| -
|
| -void ScrollView::updateScrollbars(const IntSize& desiredOffset)
|
| -{
|
| - // Don't allow re-entrancy into this function.
|
| - if (m_data->m_inUpdateScrollbars)
|
| - return;
|
| -
|
| - m_data->m_inUpdateScrollbars = true;
|
| -
|
| - bool hasVerticalScrollbar = m_data->m_vBar;
|
| - bool hasHorizontalScrollbar = m_data->m_hBar;
|
| - bool oldHasVertical = hasVerticalScrollbar;
|
| - bool oldHasHorizontal = hasHorizontalScrollbar;
|
| - ScrollbarMode hScroll = m_data->m_hScrollbarMode;
|
| - ScrollbarMode vScroll = m_data->m_vScrollbarMode;
|
| -
|
| - const int cVerticalWidth = PlatformScrollbar::verticalScrollbarWidth();
|
| - const int cHorizontalHeight = PlatformScrollbar::horizontalScrollbarHeight();
|
| -
|
| - // we may not be able to support scrollbars due to our frame geometry
|
| - if (width() < cVerticalWidth)
|
| - vScroll = ScrollbarAlwaysOff;
|
| - if (height() < cHorizontalHeight)
|
| - hScroll = ScrollbarAlwaysOff;
|
| -
|
| - for (int pass = 0; pass < 2; pass++) {
|
| - bool scrollsVertically;
|
| - bool scrollsHorizontally;
|
| -
|
| - if (!m_data->m_scrollbarsSuppressed && (hScroll == ScrollbarAuto || vScroll == ScrollbarAuto)) {
|
| - // Do a layout if pending before checking if scrollbars are needed.
|
| - if (hasVerticalScrollbar != oldHasVertical || hasHorizontalScrollbar != oldHasHorizontal)
|
| - static_cast<FrameView*>(this)->layout();
|
| -
|
| - scrollsVertically = (vScroll == ScrollbarAlwaysOn) || (vScroll == ScrollbarAuto && contentsHeight() > height());
|
| - if (scrollsVertically)
|
| - scrollsHorizontally = (hScroll == ScrollbarAlwaysOn) || (hScroll == ScrollbarAuto && contentsWidth() + cVerticalWidth > width());
|
| - else {
|
| - scrollsHorizontally = (hScroll == ScrollbarAlwaysOn) || (hScroll == ScrollbarAuto && contentsWidth() > width());
|
| - if (scrollsHorizontally)
|
| - scrollsVertically = (vScroll == ScrollbarAlwaysOn) || (vScroll == ScrollbarAuto && contentsHeight() + cHorizontalHeight > height());
|
| - }
|
| - }
|
| - else {
|
| - scrollsHorizontally = (hScroll == ScrollbarAuto) ? hasHorizontalScrollbar : (hScroll == ScrollbarAlwaysOn);
|
| - scrollsVertically = (vScroll == ScrollbarAuto) ? hasVerticalScrollbar : (vScroll == ScrollbarAlwaysOn);
|
| - }
|
| -
|
| - if (hasVerticalScrollbar != scrollsVertically) {
|
| - m_data->setHasVerticalScrollbar(scrollsVertically);
|
| - hasVerticalScrollbar = scrollsVertically;
|
| - }
|
| -
|
| - if (hasHorizontalScrollbar != scrollsHorizontally) {
|
| - m_data->setHasHorizontalScrollbar(scrollsHorizontally);
|
| - hasHorizontalScrollbar = scrollsHorizontally;
|
| - }
|
| - }
|
| -
|
| - // Set up the range (and page step/line step).
|
| - IntSize maxScrollPosition(contentsWidth() - visibleWidth(), contentsHeight() - visibleHeight());
|
| - IntSize scroll = desiredOffset.shrunkTo(maxScrollPosition);
|
| - scroll.clampNegativeToZero();
|
| -
|
| - if (m_data->m_hBar) {
|
| - int clientWidth = visibleWidth();
|
| - m_data->m_hBar->setEnabled(contentsWidth() > clientWidth);
|
| - int pageStep = (clientWidth - PAGE_KEEP);
|
| - if (pageStep < 0) pageStep = clientWidth;
|
| - IntRect oldRect(m_data->m_hBar->frameGeometry());
|
| - IntRect hBarRect = IntRect(0,
|
| - height() - m_data->m_hBar->height(),
|
| - width() - (m_data->m_vBar ? m_data->m_vBar->width() : 0),
|
| - m_data->m_hBar->height());
|
| - m_data->m_hBar->setRect(hBarRect);
|
| - if (!m_data->m_scrollbarsSuppressed && oldRect != m_data->m_hBar->frameGeometry())
|
| - m_data->m_hBar->invalidate();
|
| -
|
| - if (m_data->m_scrollbarsSuppressed)
|
| - m_data->m_hBar->setSuppressInvalidation(true);
|
| - m_data->m_hBar->setSteps(LINE_STEP, pageStep);
|
| - m_data->m_hBar->setProportion(clientWidth, contentsWidth());
|
| - m_data->m_hBar->setValue(scroll.width());
|
| - if (m_data->m_scrollbarsSuppressed)
|
| - m_data->m_hBar->setSuppressInvalidation(false);
|
| - }
|
| -
|
| - if (m_data->m_vBar) {
|
| - int clientHeight = visibleHeight();
|
| - m_data->m_vBar->setEnabled(contentsHeight() > clientHeight);
|
| - int pageStep = (clientHeight - PAGE_KEEP);
|
| - if (pageStep < 0) pageStep = clientHeight;
|
| - IntRect oldRect(m_data->m_vBar->frameGeometry());
|
| - IntRect vBarRect = IntRect(width() - m_data->m_vBar->width(),
|
| - 0,
|
| - m_data->m_vBar->width(),
|
| - height() - (m_data->m_hBar ? m_data->m_hBar->height() : 0));
|
| - m_data->m_vBar->setRect(vBarRect);
|
| - if (!m_data->m_scrollbarsSuppressed && oldRect != m_data->m_vBar->frameGeometry())
|
| - m_data->m_vBar->invalidate();
|
| -
|
| - if (m_data->m_scrollbarsSuppressed)
|
| - m_data->m_vBar->setSuppressInvalidation(true);
|
| - m_data->m_vBar->setSteps(LINE_STEP, pageStep);
|
| - m_data->m_vBar->setProportion(clientHeight, contentsHeight());
|
| - m_data->m_vBar->setValue(scroll.height());
|
| - if (m_data->m_scrollbarsSuppressed)
|
| - m_data->m_vBar->setSuppressInvalidation(false);
|
| - }
|
| -
|
| - if (oldHasVertical != (m_data->m_vBar != 0) || oldHasHorizontal != (m_data->m_hBar != 0))
|
| - geometryChanged();
|
| -
|
| - // See if our offset has changed in a situation where we might not have scrollbars.
|
| - // This can happen when editing a body with overflow:hidden and scrolling to reveal selection.
|
| - // It can also happen when maximizing a window that has scrollbars (but the new maximized result
|
| - // does not).
|
| - IntSize scrollDelta = scroll - m_data->m_scrollOffset;
|
| - if (scrollDelta != IntSize()) {
|
| - m_data->m_scrollOffset = scroll;
|
| - m_data->scrollBackingStore(scrollDelta);
|
| -
|
| - // Inform the delegate that the scroll position has changed.
|
| - WidgetClientWin* c = static_cast<WidgetClientWin*>(client());
|
| - if (c)
|
| - c->onScrollPositionChanged(this);
|
| - }
|
| -
|
| - m_data->m_inUpdateScrollbars = false;
|
| -
|
| - ASSERT(visibleWidth() >= 0);
|
| - ASSERT(visibleHeight() >= 0);
|
| -}
|
| -
|
| -PlatformScrollbar* ScrollView::scrollbarUnderMouse(const PlatformMouseEvent& mouseEvent)
|
| -{
|
| - IntPoint viewPoint = convertFromContainingWindow(mouseEvent.pos());
|
| - if (m_data->m_hBar && m_data->m_hBar->frameGeometry().contains(viewPoint))
|
| - return m_data->m_hBar.get();
|
| - if (m_data->m_vBar && m_data->m_vBar->frameGeometry().contains(viewPoint))
|
| - return m_data->m_vBar.get();
|
| - return 0;
|
| -}
|
| -
|
| -void ScrollView::addChild(Widget* child)
|
| -{
|
| - child->setParent(this);
|
| -
|
| - // There is only one global widget client (which should be the WebViewImpl).
|
| - // It is responsible for things like capturing the mouse.
|
| - child->setClient(client());
|
| -
|
| - m_data->m_children.add(child);
|
| -}
|
| -
|
| -void ScrollView::removeChild(Widget* child)
|
| -{
|
| - child->setParent(0);
|
| - m_data->m_children.remove(child);
|
| -}
|
| -
|
| -void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
|
| -{
|
| - // FIXME: This code is here so we don't have to fork FrameView.h/.cpp.
|
| - // In the end, FrameView should just merge with ScrollView.
|
| - ASSERT(isFrameView());
|
| -
|
| - if (context->paintingDisabled())
|
| - return;
|
| -
|
| - if (Frame* frame = static_cast<FrameView*>(this)->frame()) {
|
| - IntRect documentDirtyRect = rect;
|
| - documentDirtyRect.intersect(frameGeometry());
|
| -
|
| - context->save();
|
| -
|
| - context->translate(x(), y());
|
| - documentDirtyRect.move(-x(), -y());
|
| -
|
| - context->translate(-contentsX(), -contentsY());
|
| - documentDirtyRect.move(contentsX(), contentsY());
|
| -
|
| - // do not allow painting outside of the dirty rect
|
| - context->clip(documentDirtyRect);
|
| -
|
| - frame->paint(context, documentDirtyRect);
|
| -
|
| - // Highlights the node selected in the DOM inspector.
|
| - m_data->highlightInspectedNode(context, frame);
|
| -
|
| - context->restore();
|
| - }
|
| -
|
| - // Highlight the matches found on the page, during a FindInPage operation.
|
| - m_data->highlightMatches(context);
|
| -
|
| - // Now paint the scrollbars.
|
| - if (!m_data->m_scrollbarsSuppressed && (m_data->m_hBar || m_data->m_vBar)) {
|
| - context->save();
|
| - IntRect scrollViewDirtyRect = rect;
|
| - scrollViewDirtyRect.intersect(frameGeometry());
|
| - context->translate(x(), y());
|
| - scrollViewDirtyRect.move(-x(), -y());
|
| - if (m_data->m_hBar)
|
| - m_data->m_hBar->paint(context, scrollViewDirtyRect);
|
| - if (m_data->m_vBar)
|
| - m_data->m_vBar->paint(context, scrollViewDirtyRect);
|
| -
|
| - // Fill the scroll corner with white.
|
| - IntRect hCorner;
|
| - if (m_data->m_hBar && width() - m_data->m_hBar->width() > 0) {
|
| - hCorner = IntRect(m_data->m_hBar->width(),
|
| - height() - m_data->m_hBar->height(),
|
| - width() - m_data->m_hBar->width(),
|
| - m_data->m_hBar->height());
|
| - if (hCorner.intersects(scrollViewDirtyRect))
|
| - context->fillRect(hCorner, Color::white);
|
| - }
|
| -
|
| - if (m_data->m_vBar && height() - m_data->m_vBar->height() > 0) {
|
| - IntRect vCorner(width() - m_data->m_vBar->width(),
|
| - m_data->m_vBar->height(),
|
| - m_data->m_vBar->width(),
|
| - height() - m_data->m_vBar->height());
|
| - if (vCorner != hCorner && vCorner.intersects(scrollViewDirtyRect))
|
| - context->fillRect(vCorner, Color::white);
|
| - }
|
| -
|
| - context->restore();
|
| - }
|
| -}
|
| -
|
| -void ScrollView::themeChanged()
|
| -{
|
| - PlatformScrollbar::themeChanged();
|
| - theme()->themeChanged();
|
| - invalidate();
|
| -}
|
| -
|
| -void ScrollView::wheelEvent(PlatformWheelEvent& e)
|
| -{
|
| - if (!m_data->allowsScrolling())
|
| - return;
|
| -
|
| - // Determine how much we want to scroll. If we can move at all, we will accept the event.
|
| - IntSize maxScrollDelta = maximumScroll();
|
| - 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();
|
| - scrollBy(-e.deltaX() * LINE_STEP, -e.deltaY() * LINE_STEP);
|
| - }
|
| -}
|
| -
|
| -HashSet<Widget*>* ScrollView::children()
|
| -{
|
| - return &(m_data->m_children);
|
| -}
|
| -
|
| -void ScrollView::geometryChanged() const
|
| -{
|
| - HashSet<Widget*>::const_iterator end = m_data->m_children.end();
|
| - for (HashSet<Widget*>::const_iterator current = m_data->m_children.begin(); current != end; ++current)
|
| - (*current)->geometryChanged();
|
| -}
|
| -
|
| -bool ScrollView::scroll(ScrollDirection direction, ScrollGranularity granularity)
|
| -{
|
| - if (direction == ScrollUp || direction == ScrollDown) {
|
| - if (m_data->m_vBar)
|
| - return m_data->m_vBar->scroll(direction, granularity);
|
| - } else {
|
| - if (m_data->m_hBar)
|
| - return m_data->m_hBar->scroll(direction, granularity);
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -IntRect ScrollView::windowResizerRect()
|
| -{
|
| - return IntRect();
|
| -}
|
| -
|
| -bool ScrollView::resizerOverlapsContent() const
|
| -{
|
| - return !m_data->m_scrollbarsAvoidingResizer;
|
| -}
|
| -
|
| -void ScrollView::adjustOverlappingScrollbarCount(int overlapDelta)
|
| -{
|
| - int oldCount = m_data->m_scrollbarsAvoidingResizer;
|
| - m_data->m_scrollbarsAvoidingResizer += overlapDelta;
|
| - if (parent() && parent()->isFrameView())
|
| - static_cast<FrameView*>(parent())->adjustOverlappingScrollbarCount(overlapDelta);
|
| - else if (!m_data->m_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_data->m_scrollbarsAvoidingResizer == 0 ||
|
| - oldCount == 0 && m_data->m_scrollbarsAvoidingResizer > 0)
|
| - invalidateRect(windowResizerRect());
|
| - }
|
| -}
|
| -
|
| -void ScrollView::setParent(ScrollView* parentView)
|
| -{
|
| - if (!parentView && m_data->m_scrollbarsAvoidingResizer && parent() && parent()->isFrameView())
|
| - static_cast<FrameView*>(parent())->adjustOverlappingScrollbarCount(false);
|
| - Widget::setParent(parentView);
|
| -}
|
| -
|
| -void ScrollView::addToDirtyRegion(const IntRect& containingWindowRect)
|
| -{
|
| - WidgetClientWin* c = static_cast<WidgetClientWin*>(client());
|
| - if (c)
|
| - c->invalidateRect(containingWindowRect);
|
| -}
|
| -
|
| -void ScrollView::scrollBackingStore(int dx, int dy, const IntRect& scrollViewRect, const IntRect& clipRect)
|
| -{
|
| - // We don't know how to scroll in two directions at once.
|
| - if (dx && dy) {
|
| - IntRect updateRect = clipRect;
|
| - updateRect.intersect(scrollViewRect);
|
| - addToDirtyRegion(updateRect);
|
| - return;
|
| - }
|
| -
|
| - WidgetClientWin* c = static_cast<WidgetClientWin*>(client());
|
| - if (c) {
|
| - // TODO(ericroman): would be better to pass both the scroll rect
|
| - // and clip rect up to the client and let them decide how best to
|
| - // scroll the backing store.
|
| - IntRect clippedScrollRect = scrollViewRect;
|
| - clippedScrollRect.intersect(clipRect);
|
| - c->scrollRect(dx, dy, clippedScrollRect);
|
| - }
|
| -}
|
| -
|
| -void ScrollView::updateBackingStore()
|
| -{
|
| - // nothing to do. painting happens asynchronously.
|
| -}
|
| -
|
| -bool ScrollView::inWindow() const
|
| -{
|
| - WidgetClientWin* c = static_cast<WidgetClientWin*>(client());
|
| - if (!c)
|
| - return false;
|
| -
|
| - return !c->isHidden();
|
| -}
|
| -
|
| -void ScrollView::attachToWindow()
|
| -{
|
| - if (m_data->m_attachedToWindow)
|
| - return;
|
| -
|
| - m_data->m_attachedToWindow = true;
|
| -
|
| - if (m_data->m_visible) {
|
| - HashSet<Widget*>::iterator end = m_data->m_children.end();
|
| - for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it)
|
| - (*it)->attachToWindow();
|
| - }
|
| -}
|
| -
|
| -void ScrollView::detachFromWindow()
|
| -{
|
| - if (!m_data->m_attachedToWindow)
|
| - return;
|
| -
|
| - if (m_data->m_visible) {
|
| - HashSet<Widget*>::iterator end = m_data->m_children.end();
|
| - for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it)
|
| - (*it)->detachFromWindow();
|
| - }
|
| -
|
| - m_data->m_attachedToWindow = false;
|
| -}
|
| -
|
| -void ScrollView::show()
|
| -{
|
| - if (!m_data->m_visible) {
|
| - m_data->m_visible = true;
|
| - if (isAttachedToWindow()) {
|
| - HashSet<Widget*>::iterator end = m_data->m_children.end();
|
| - for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it)
|
| - (*it)->attachToWindow();
|
| - }
|
| - }
|
| -
|
| - Widget::show();
|
| -}
|
| -
|
| -void ScrollView::hide()
|
| -{
|
| - if (m_data->m_visible) {
|
| - if (isAttachedToWindow()) {
|
| - HashSet<Widget*>::iterator end = m_data->m_children.end();
|
| - for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it)
|
| - (*it)->detachFromWindow();
|
| - }
|
| - m_data->m_visible = false;
|
| - }
|
| -
|
| - Widget::hide();
|
| -}
|
| -
|
| -bool ScrollView::isAttachedToWindow() const
|
| -{
|
| - return m_data->m_attachedToWindow;
|
| -}
|
| -
|
| -void ScrollView::setAllowsScrolling(bool flag)
|
| -{
|
| - m_data->setAllowsScrolling(flag);
|
| -}
|
| -
|
| -bool ScrollView::allowsScrolling() const
|
| -{
|
| - return m_data->allowsScrolling();
|
| -}
|
| -
|
| -void ScrollView::printPanScrollIcon(const IntPoint& iconPosition)
|
| -{
|
| - m_data->m_drawPanScrollIcon = true;
|
| - m_data->m_panScrollIconPoint = IntPoint(iconPosition.x() - panIconSizeLength / 2 , iconPosition.y() - panIconSizeLength / 2) ;
|
| -
|
| - updateWindowRect(IntRect(m_data->m_panScrollIconPoint, IntSize(panIconSizeLength,panIconSizeLength)), true);
|
| -}
|
| -
|
| -void ScrollView::removePanScrollIcon()
|
| -{
|
| - m_data->m_drawPanScrollIcon = false;
|
| -
|
| - updateWindowRect(IntRect(m_data->m_panScrollIconPoint, IntSize(panIconSizeLength, panIconSizeLength)), true);
|
| -}
|
| -
|
| -bool ScrollView::isScrollable()
|
| -{
|
| - return m_data->m_vBar != 0 || m_data->m_hBar != 0;
|
| -}
|
| -
|
| -} // namespace WebCore
|
|
|