Home | History | Annotate | Download | only in web
      1 /*
      2  * Copyright (C) 2011 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "ScrollbarGroup.h"
     28 
     29 #include "WebPluginScrollbarImpl.h"
     30 #include "core/page/FrameView.h"
     31 #include "core/platform/Scrollbar.h"
     32 #include "core/platform/ScrollbarTheme.h"
     33 #include "public/platform/WebRect.h"
     34 
     35 using namespace WebCore;
     36 
     37 namespace WebKit {
     38 
     39 ScrollbarGroup::ScrollbarGroup(FrameView* frameView, const IntRect& frameRect)
     40     : m_frameView(frameView)
     41     , m_frameRect(frameRect)
     42     , m_horizontalScrollbar(0)
     43     , m_verticalScrollbar(0)
     44 {
     45 }
     46 
     47 ScrollbarGroup::~ScrollbarGroup()
     48 {
     49     ASSERT(!m_horizontalScrollbar);
     50     ASSERT(!m_verticalScrollbar);
     51 }
     52 
     53 void ScrollbarGroup::scrollbarCreated(WebPluginScrollbarImpl* scrollbar)
     54 {
     55     bool hadScrollbars = m_horizontalScrollbar || m_verticalScrollbar;
     56     if (scrollbar->scrollbar()->orientation() == HorizontalScrollbar) {
     57         ASSERT(!m_horizontalScrollbar);
     58         m_horizontalScrollbar = scrollbar;
     59         didAddHorizontalScrollbar(scrollbar->scrollbar());
     60     } else {
     61         ASSERT(!m_verticalScrollbar);
     62         m_verticalScrollbar = scrollbar;
     63         didAddVerticalScrollbar(scrollbar->scrollbar());
     64     }
     65 
     66     if (!hadScrollbars) {
     67         m_frameView->addScrollableArea(this);
     68         m_frameView->setNeedsLayout();
     69     }
     70 }
     71 
     72 void ScrollbarGroup::scrollbarDestroyed(WebPluginScrollbarImpl* scrollbar)
     73 {
     74     if (scrollbar == m_horizontalScrollbar) {
     75         willRemoveHorizontalScrollbar(scrollbar->scrollbar());
     76         m_horizontalScrollbar = 0;
     77     } else {
     78         ASSERT(scrollbar == m_verticalScrollbar);
     79         willRemoveVerticalScrollbar(scrollbar->scrollbar());
     80         m_verticalScrollbar = 0;
     81     }
     82 
     83     if (!m_horizontalScrollbar && !m_verticalScrollbar) {
     84         m_frameView->removeScrollableArea(this);
     85         m_frameView->setNeedsLayout();
     86     }
     87 }
     88 
     89 void ScrollbarGroup::setLastMousePosition(const IntPoint& point)
     90 {
     91     m_lastMousePosition = point;
     92 }
     93 
     94 int ScrollbarGroup::scrollSize(WebCore::ScrollbarOrientation orientation) const
     95 {
     96     WebPluginScrollbarImpl* webScrollbar = orientation == HorizontalScrollbar ? m_horizontalScrollbar : m_verticalScrollbar;
     97     if (!webScrollbar)
     98         return 0;
     99     Scrollbar* scrollbar = webScrollbar->scrollbar();
    100     return scrollbar->totalSize() - scrollbar->visibleSize();
    101 }
    102 
    103 void ScrollbarGroup::setScrollOffset(const IntPoint& offset)
    104 {
    105     if (m_horizontalScrollbar && m_horizontalScrollbar->scrollOffset() != offset.x())
    106         m_horizontalScrollbar->setScrollOffset(offset.x());
    107     else if (m_verticalScrollbar && m_verticalScrollbar->scrollOffset() != offset.y())
    108         m_verticalScrollbar->setScrollOffset(offset.y());
    109 }
    110 
    111 void ScrollbarGroup::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
    112 {
    113     if (m_horizontalScrollbar && scrollbar == m_horizontalScrollbar->scrollbar())
    114         m_horizontalScrollbar->invalidateScrollbarRect(rect);
    115     else if (m_verticalScrollbar && scrollbar == m_verticalScrollbar->scrollbar())
    116         m_verticalScrollbar->invalidateScrollbarRect(rect);
    117 }
    118 
    119 void ScrollbarGroup::invalidateScrollCornerRect(const IntRect&)
    120 {
    121 }
    122 
    123 bool ScrollbarGroup::isActive() const
    124 {
    125     return true;
    126 }
    127 
    128 ScrollableArea* ScrollbarGroup::enclosingScrollableArea() const
    129 {
    130     // FIXME: Return a parent scrollable area that can be scrolled.
    131     return 0;
    132 }
    133 
    134 void ScrollbarGroup::setFrameRect(const IntRect& frameRect)
    135 {
    136     m_frameRect = frameRect;
    137 }
    138 
    139 IntRect ScrollbarGroup::scrollableAreaBoundingBox() const
    140 {
    141     return m_frameRect;
    142 }
    143 
    144 bool ScrollbarGroup::isScrollCornerVisible() const
    145 {
    146     return false;
    147 }
    148 
    149 void ScrollbarGroup::getTickmarks(Vector<IntRect>& tickmarks) const
    150 {
    151     if (m_verticalScrollbar)
    152         m_verticalScrollbar->getTickmarks(tickmarks);
    153 }
    154 
    155 IntPoint ScrollbarGroup::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
    156 {
    157     if (m_horizontalScrollbar && scrollbar == m_horizontalScrollbar->scrollbar())
    158         return m_horizontalScrollbar->convertFromContainingViewToScrollbar(parentPoint);
    159     if (m_verticalScrollbar && scrollbar == m_verticalScrollbar->scrollbar())
    160         return m_verticalScrollbar->convertFromContainingViewToScrollbar(parentPoint);
    161     WEBKIT_ASSERT_NOT_REACHED();
    162     return IntPoint();
    163 }
    164 
    165 Scrollbar* ScrollbarGroup::horizontalScrollbar() const
    166 {
    167     return m_horizontalScrollbar ? m_horizontalScrollbar->scrollbar() : 0;
    168 }
    169 
    170 Scrollbar* ScrollbarGroup::verticalScrollbar() const
    171 {
    172     return m_verticalScrollbar ? m_verticalScrollbar->scrollbar() : 0;
    173 }
    174 
    175 IntPoint ScrollbarGroup::scrollPosition() const
    176 {
    177     int x = m_horizontalScrollbar ? m_horizontalScrollbar->scrollOffset() : 0;
    178     int y = m_verticalScrollbar ? m_verticalScrollbar->scrollOffset() : 0;
    179     return IntPoint(x, y);
    180 }
    181 
    182 IntPoint ScrollbarGroup::minimumScrollPosition() const
    183 {
    184     return IntPoint();
    185 }
    186 
    187 IntPoint ScrollbarGroup::maximumScrollPosition() const
    188 {
    189     return IntPoint(contentsSize().width() - visibleWidth(), contentsSize().height() - visibleHeight());
    190 }
    191 
    192 int ScrollbarGroup::visibleHeight() const
    193 {
    194     if (m_verticalScrollbar)
    195         return m_verticalScrollbar->scrollbar()->height();
    196     if (m_horizontalScrollbar)
    197         return m_horizontalScrollbar->scrollbar()->height();
    198     WEBKIT_ASSERT_NOT_REACHED();
    199     return 0;
    200 }
    201 
    202 int ScrollbarGroup::visibleWidth() const
    203 {
    204     if (m_horizontalScrollbar)
    205         return m_horizontalScrollbar->scrollbar()->width();
    206     if (m_verticalScrollbar)
    207         return m_verticalScrollbar->scrollbar()->width();
    208     WEBKIT_ASSERT_NOT_REACHED();
    209     return 0;
    210 }
    211 
    212 IntSize ScrollbarGroup::contentsSize() const
    213 {
    214     IntSize size;
    215     if (m_horizontalScrollbar)
    216         size.setWidth(m_horizontalScrollbar->scrollbar()->totalSize());
    217     else if (m_verticalScrollbar) {
    218         size.setWidth(m_verticalScrollbar->scrollbar()->x());
    219         if (m_verticalScrollbar->scrollbar()->isOverlayScrollbar())
    220             size.expand(WebPluginScrollbar::defaultThickness(), 0);
    221     }
    222     if (m_verticalScrollbar)
    223         size.setHeight(m_verticalScrollbar->scrollbar()->totalSize());
    224     else if (m_horizontalScrollbar) {
    225         size.setHeight(m_horizontalScrollbar->scrollbar()->y());
    226         if (m_horizontalScrollbar->scrollbar()->isOverlayScrollbar())
    227             size.expand(0, WebPluginScrollbar::defaultThickness());
    228     }
    229     return size;
    230 }
    231 
    232 IntSize ScrollbarGroup::overhangAmount() const
    233 {
    234     return IntSize();
    235 }
    236 
    237 IntPoint ScrollbarGroup::lastKnownMousePosition() const
    238 {
    239     return m_lastMousePosition;
    240 }
    241 
    242 bool ScrollbarGroup::shouldSuspendScrollAnimations() const
    243 {
    244     return false;
    245 }
    246 
    247 void ScrollbarGroup::scrollbarStyleChanged(int, bool forceUpdate)
    248 {
    249     if (!forceUpdate)
    250         return;
    251 
    252     if (m_horizontalScrollbar)
    253         m_horizontalScrollbar->scrollbarStyleChanged();
    254     if (m_verticalScrollbar)
    255         m_verticalScrollbar->scrollbarStyleChanged();
    256 }
    257 
    258 bool ScrollbarGroup::scrollbarsCanBeActive() const
    259 {
    260     return true;
    261 }
    262 
    263 bool ScrollbarGroup::userInputScrollable(ScrollbarOrientation orientation) const
    264 {
    265     return orientation == HorizontalScrollbar ? horizontalScrollbar() : verticalScrollbar();
    266 }
    267 
    268 int ScrollbarGroup::pageStep(ScrollbarOrientation orientation) const
    269 {
    270     int length;
    271     if (orientation == VerticalScrollbar) {
    272         if (!m_verticalScrollbar)
    273             return 0;
    274 
    275         length = m_verticalScrollbar->scrollbar()->height();
    276     } else {
    277         if (!m_horizontalScrollbar)
    278             return 0;
    279 
    280         length = m_horizontalScrollbar->scrollbar()->width();
    281     }
    282 
    283     int pageStep = std::max(
    284         static_cast<int>(static_cast<float>(length) * ScrollableArea::minFractionToStepWhenPaging()),
    285         length - ScrollableArea::maxOverlapBetweenPages());
    286 
    287     return std::max(pageStep, 1);
    288 }
    289 
    290 } // namespace WebKit
    291