Home | History | Annotate | Download | only in win
      1 /*
      2  * Copyright (C) 2007 Apple 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  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "WebKitDLL.h"
     28 #include "WebKit.h"
     29 #include "WebScrollBar.h"
     30 
     31 #include <WebCore/GraphicsContext.h>
     32 #include <WebCore/PlatformMouseEvent.h>
     33 #include <WebCore/Scrollbar.h>
     34 #include <WebCore/ScrollbarTheme.h>
     35 
     36 using namespace WebCore;
     37 
     38 // WebScrollBar ---------------------------------------------------------------------
     39 
     40 WebScrollBar::WebScrollBar()
     41     : m_refCount(0)
     42     , m_containingWindow(0)
     43     , m_currentPosition(0)
     44 {
     45     gClassCount++;
     46     gClassNameCount.add("WebScrollBar");
     47 }
     48 
     49 WebScrollBar::~WebScrollBar()
     50 {
     51     gClassCount--;
     52     gClassNameCount.remove("WebScrollBar");
     53 }
     54 
     55 WebScrollBar* WebScrollBar::createInstance()
     56 {
     57     WebScrollBar* instance = new WebScrollBar();
     58     instance->AddRef();
     59     return instance;
     60 }
     61 
     62 // IUnknown -------------------------------------------------------------------
     63 
     64 HRESULT STDMETHODCALLTYPE WebScrollBar::QueryInterface(REFIID riid, void** ppvObject)
     65 {
     66     *ppvObject = 0;
     67     if (IsEqualGUID(riid, IID_IUnknown))
     68         *ppvObject = static_cast<IUnknown*>(this);
     69     else if (IsEqualGUID(riid, IID_IWebScrollBarPrivate))
     70         *ppvObject = static_cast<IWebScrollBarPrivate*>(this);
     71     else
     72         return E_NOINTERFACE;
     73 
     74     AddRef();
     75     return S_OK;
     76 }
     77 
     78 ULONG STDMETHODCALLTYPE WebScrollBar::AddRef(void)
     79 {
     80     return ++m_refCount;
     81 }
     82 
     83 ULONG STDMETHODCALLTYPE WebScrollBar::Release(void)
     84 {
     85     ULONG newRef = --m_refCount;
     86     if (!newRef)
     87         delete(this);
     88 
     89     return newRef;
     90 }
     91 
     92 // IWebScrollBarPrivate ------------------------------------------------------------------
     93 HRESULT STDMETHODCALLTYPE WebScrollBar::init(
     94     /* [in] */ IWebScrollBarDelegatePrivate* delegate,
     95     /* [in] */ OLE_HANDLE containingWindow,
     96     /* [in] */ WebScrollBarOrientation orientation,
     97     /* [in] */ WebScrollBarControlSize controlSize)
     98 {
     99     if (!delegate || !containingWindow)
    100         return E_FAIL;
    101     ScrollbarOrientation webCoreOrientation = (ScrollbarOrientation) orientation;
    102     ScrollbarControlSize webCoreControlSize = (ScrollbarControlSize) controlSize;
    103     m_delegate = delegate;
    104     m_scrollBar = Scrollbar::createNativeScrollbar(this, webCoreOrientation, webCoreControlSize);
    105     if (!m_scrollBar)
    106         return E_FAIL;
    107     m_containingWindow = (HWND)(ULONG64)containingWindow;
    108     return S_OK;
    109 }
    110 
    111 HRESULT STDMETHODCALLTYPE WebScrollBar::setEnabled(
    112     /* [in] */ BOOL enabled)
    113 {
    114     m_scrollBar->setEnabled(!!enabled);
    115     return S_OK;
    116 }
    117 
    118 HRESULT STDMETHODCALLTYPE WebScrollBar::setSteps(
    119     /* [in] */ int lineStep,
    120     /* [in] */ int pageStep)
    121 {
    122     m_scrollBar->setSteps(lineStep, pageStep);
    123     return S_OK;
    124 }
    125 
    126 HRESULT STDMETHODCALLTYPE WebScrollBar::setProportion(
    127     /* [in] */ int visibleSize,
    128     /* [in] */ int totalSize)
    129 {
    130     m_scrollBar->setProportion(visibleSize, totalSize);
    131     return S_OK;
    132 }
    133 
    134 HRESULT STDMETHODCALLTYPE WebScrollBar::setRect(
    135     /* [in] */ RECT bounds)
    136 {
    137     IntRect rect(bounds.left, bounds.top, bounds.right-bounds.left, bounds.bottom-bounds.top);
    138     m_scrollBar->setFrameRect(rect);
    139     return S_OK;
    140 }
    141 
    142 HRESULT STDMETHODCALLTYPE WebScrollBar::setValue(
    143     /* [in] */ int value)
    144 {
    145     m_currentPosition = value;
    146     ScrollableArea::scrollToOffsetWithoutAnimation(m_scrollBar->orientation(), m_currentPosition);
    147     return S_OK;
    148 }
    149 
    150 HRESULT STDMETHODCALLTYPE WebScrollBar::value(
    151     /* [retval][out] */ int* value)
    152 {
    153     if (!value)
    154         return E_POINTER;
    155     *value = m_currentPosition;
    156     return S_OK;
    157 }
    158 
    159 HRESULT STDMETHODCALLTYPE WebScrollBar::paint(
    160     /* [in] */ HDC dc,
    161     /* [in] */ RECT damageRect)
    162 {
    163     GraphicsContext context(dc);
    164     IntRect rect(damageRect.left, damageRect.top, damageRect.right-damageRect.left, damageRect.bottom-damageRect.top);
    165     m_scrollBar->paint(&context, rect);
    166     return S_OK;
    167 }
    168 
    169 HRESULT STDMETHODCALLTYPE WebScrollBar::frameRect(
    170     /* [retval][out] */ RECT* bounds)
    171 {
    172     if (!bounds)
    173         return E_POINTER;
    174     IntRect rect = m_scrollBar->frameRect();
    175     bounds->left = rect.x();
    176     bounds->right = rect.maxX();
    177     bounds->top = rect.y();
    178     bounds->bottom = rect.maxY();
    179     return S_OK;
    180 }
    181 
    182 HRESULT STDMETHODCALLTYPE WebScrollBar::width(
    183     /* [retval][out] */ int* w)
    184 {
    185     if (!w)
    186         return E_POINTER;
    187     *w = m_scrollBar->width();
    188     return S_OK;
    189 }
    190 
    191 HRESULT STDMETHODCALLTYPE WebScrollBar::height(
    192     /* [retval][out] */ int* h)
    193 {
    194     if (!h)
    195         return E_POINTER;
    196     *h = m_scrollBar->height();
    197     return S_OK;
    198 }
    199 
    200 HRESULT STDMETHODCALLTYPE WebScrollBar::requestedWidth(
    201     /* [retval][out] */ int* w)
    202 {
    203     if (!w)
    204         return E_POINTER;
    205 
    206     *w = m_scrollBar->orientation() == VerticalScrollbar ? ScrollbarTheme::nativeTheme()->scrollbarThickness(m_scrollBar->controlSize()) : -1;
    207     return S_OK;
    208 }
    209 
    210 HRESULT STDMETHODCALLTYPE WebScrollBar::requestedHeight(
    211     /* [retval][out] */ int* h)
    212 {
    213     if (!h)
    214         return E_POINTER;
    215 
    216     *h = m_scrollBar->orientation() == HorizontalScrollbar ? ScrollbarTheme::nativeTheme()->scrollbarThickness(m_scrollBar->controlSize()) : -1;
    217     return S_OK;
    218 }
    219 
    220 
    221 HRESULT STDMETHODCALLTYPE WebScrollBar::handleMouseEvent(
    222     OLE_HANDLE window,
    223     UINT msg,
    224     WPARAM wParam,
    225     LPARAM lParam)
    226 {
    227     PlatformMouseEvent mouseEvent((HWND)(ULONG64)window, msg, wParam, lParam);
    228     switch (msg) {
    229         case WM_LBUTTONDOWN:
    230             m_scrollBar->mouseDown(mouseEvent);
    231             break;
    232         case WM_LBUTTONUP:
    233             m_scrollBar->mouseUp();
    234             break;
    235         case WM_MOUSEMOVE:
    236             m_scrollBar->mouseMoved(mouseEvent);
    237             break;
    238     }
    239 
    240     return S_OK;
    241 }
    242 
    243 HRESULT STDMETHODCALLTYPE WebScrollBar::scroll(
    244     WebScrollDirection direction,
    245     WebScrollGranularity granularity,
    246     float multiplier)
    247 {
    248     ScrollDirection webCoreScrollDirection = (ScrollDirection) direction;
    249     ScrollGranularity webCoreGranularity = (ScrollGranularity) granularity;
    250     ScrollableArea::scroll(webCoreScrollDirection, webCoreGranularity, multiplier);
    251     return S_OK;
    252 }
    253 
    254 // ScrollableArea -------------------------------------------------------
    255 
    256 int WebScrollBar::scrollSize(ScrollbarOrientation orientation) const
    257 {
    258     return (orientation == m_scrollBar->orientation()) ? (m_scrollBar->totalSize() - m_scrollBar->visibleSize()) : 0;
    259 }
    260 
    261 int WebScrollBar::scrollPosition(Scrollbar*) const
    262 {
    263     return m_currentPosition;
    264 }
    265 
    266 void WebScrollBar::setScrollOffset(const IntPoint& offset)
    267 {
    268     m_currentPosition = (m_scrollBar->orientation() == HorizontalScrollbar) ? offset.x() : offset.y();
    269     m_delegate->valueChanged(this);
    270 }
    271 
    272 void WebScrollBar::invalidateScrollbarRect(Scrollbar*, const IntRect& rect)
    273 {
    274     RECT r = rect;
    275     ::InvalidateRect(m_containingWindow, &r, false);
    276 }
    277 
    278 Scrollbar* WebScrollBar::horizontalScrollbar() const
    279 {
    280     return m_scrollBar->orientation() == HorizontalScrollbar ? m_scrollBar.get() : 0;
    281 }
    282 
    283 Scrollbar* WebScrollBar::verticalScrollbar() const
    284 {
    285     return m_scrollBar->orientation() == VerticalScrollbar ? m_scrollBar.get() : 0;
    286 }
    287