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 "web/ScrollbarGroup.h"
     28 
     29 #include "core/frame/FrameView.h"
     30 #include "platform/scroll/Scrollbar.h"
     31 #include "platform/scroll/ScrollbarTheme.h"
     32 #include "public/platform/WebRect.h"
     33 #include "web/WebPluginScrollbarImpl.h"
     34 
     35 using namespace WebCore;
     36 
     37 namespace blink {
     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         didAddScrollbar(scrollbar->scrollbar(), HorizontalScrollbar);
     60     } else {
     61         ASSERT(!m_verticalScrollbar);
     62         m_verticalScrollbar = scrollbar;
     63         didAddScrollbar(scrollbar->scrollbar(), VerticalScrollbar);
     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         willRemoveScrollbar(scrollbar->scrollbar(), HorizontalScrollbar);
     76         m_horizontalScrollbar = 0;
     77     } else {
     78         ASSERT(scrollbar == m_verticalScrollbar);
     79         willRemoveScrollbar(scrollbar->scrollbar(), VerticalScrollbar);
     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 void ScrollbarGroup::setFrameRect(const IntRect& frameRect)
    129 {
    130     m_frameRect = frameRect;
    131 }
    132 
    133 IntRect ScrollbarGroup::scrollableAreaBoundingBox() const
    134 {
    135     return m_frameRect;
    136 }
    137 
    138 bool ScrollbarGroup::isScrollCornerVisible() const
    139 {
    140     return false;
    141 }
    142 
    143 void ScrollbarGroup::getTickmarks(Vector<IntRect>& tickmarks) const
    144 {
    145     if (m_verticalScrollbar)
    146         m_verticalScrollbar->getTickmarks(tickmarks);
    147 }
    148 
    149 IntPoint ScrollbarGroup::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
    150 {
    151     if (m_horizontalScrollbar && scrollbar == m_horizontalScrollbar->scrollbar())
    152         return m_horizontalScrollbar->convertFromContainingViewToScrollbar(parentPoint);
    153     if (m_verticalScrollbar && scrollbar == m_verticalScrollbar->scrollbar())
    154         return m_verticalScrollbar->convertFromContainingViewToScrollbar(parentPoint);
    155     BLINK_ASSERT_NOT_REACHED();
    156     return IntPoint();
    157 }
    158 
    159 Scrollbar* ScrollbarGroup::horizontalScrollbar() const
    160 {
    161     return m_horizontalScrollbar ? m_horizontalScrollbar->scrollbar() : 0;
    162 }
    163 
    164 Scrollbar* ScrollbarGroup::verticalScrollbar() const
    165 {
    166     return m_verticalScrollbar ? m_verticalScrollbar->scrollbar() : 0;
    167 }
    168 
    169 IntPoint ScrollbarGroup::scrollPosition() const
    170 {
    171     int x = m_horizontalScrollbar ? m_horizontalScrollbar->scrollOffset() : 0;
    172     int y = m_verticalScrollbar ? m_verticalScrollbar->scrollOffset() : 0;
    173     return IntPoint(x, y);
    174 }
    175 
    176 IntPoint ScrollbarGroup::minimumScrollPosition() const
    177 {
    178     return IntPoint();
    179 }
    180 
    181 IntPoint ScrollbarGroup::maximumScrollPosition() const
    182 {
    183     return IntPoint(contentsSize().width() - visibleWidth(), contentsSize().height() - visibleHeight());
    184 }
    185 
    186 int ScrollbarGroup::visibleHeight() const
    187 {
    188     if (m_verticalScrollbar)
    189         return m_verticalScrollbar->scrollbar()->height();
    190     if (m_horizontalScrollbar)
    191         return m_horizontalScrollbar->scrollbar()->height();
    192     BLINK_ASSERT_NOT_REACHED();
    193     return 0;
    194 }
    195 
    196 int ScrollbarGroup::visibleWidth() const
    197 {
    198     if (m_horizontalScrollbar)
    199         return m_horizontalScrollbar->scrollbar()->width();
    200     if (m_verticalScrollbar)
    201         return m_verticalScrollbar->scrollbar()->width();
    202     BLINK_ASSERT_NOT_REACHED();
    203     return 0;
    204 }
    205 
    206 IntSize ScrollbarGroup::contentsSize() const
    207 {
    208     IntSize size;
    209     if (m_horizontalScrollbar)
    210         size.setWidth(m_horizontalScrollbar->scrollbar()->totalSize());
    211     else if (m_verticalScrollbar) {
    212         size.setWidth(m_verticalScrollbar->scrollbar()->x());
    213         if (m_verticalScrollbar->scrollbar()->isOverlayScrollbar())
    214             size.expand(WebPluginScrollbar::defaultThickness(), 0);
    215     }
    216     if (m_verticalScrollbar)
    217         size.setHeight(m_verticalScrollbar->scrollbar()->totalSize());
    218     else if (m_horizontalScrollbar) {
    219         size.setHeight(m_horizontalScrollbar->scrollbar()->y());
    220         if (m_horizontalScrollbar->scrollbar()->isOverlayScrollbar())
    221             size.expand(0, WebPluginScrollbar::defaultThickness());
    222     }
    223     return size;
    224 }
    225 
    226 IntSize ScrollbarGroup::overhangAmount() const
    227 {
    228     return IntSize();
    229 }
    230 
    231 IntPoint ScrollbarGroup::lastKnownMousePosition() const
    232 {
    233     return m_lastMousePosition;
    234 }
    235 
    236 bool ScrollbarGroup::shouldSuspendScrollAnimations() const
    237 {
    238     return false;
    239 }
    240 
    241 void ScrollbarGroup::scrollbarStyleChanged()
    242 {
    243     if (m_horizontalScrollbar)
    244         m_horizontalScrollbar->scrollbarStyleChanged();
    245     if (m_verticalScrollbar)
    246         m_verticalScrollbar->scrollbarStyleChanged();
    247 }
    248 
    249 bool ScrollbarGroup::scrollbarsCanBeActive() const
    250 {
    251     return true;
    252 }
    253 
    254 bool ScrollbarGroup::userInputScrollable(ScrollbarOrientation orientation) const
    255 {
    256     return orientation == HorizontalScrollbar ? horizontalScrollbar() : verticalScrollbar();
    257 }
    258 
    259 bool ScrollbarGroup::shouldPlaceVerticalScrollbarOnLeft() const
    260 {
    261     return false;
    262 }
    263 
    264 int ScrollbarGroup::pageStep(ScrollbarOrientation orientation) const
    265 {
    266     int length;
    267     if (orientation == VerticalScrollbar) {
    268         if (!m_verticalScrollbar)
    269             return 0;
    270 
    271         length = m_verticalScrollbar->scrollbar()->height();
    272     } else {
    273         if (!m_horizontalScrollbar)
    274             return 0;
    275 
    276         length = m_horizontalScrollbar->scrollbar()->width();
    277     }
    278 
    279     int pageStep = std::max(
    280         static_cast<int>(static_cast<float>(length) * ScrollableArea::minFractionToStepWhenPaging()),
    281         length - ScrollableArea::maxOverlapBetweenPages());
    282 
    283     return std::max(pageStep, 1);
    284 }
    285 
    286 } // namespace blink
    287