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 36using namespace WebCore; 37 38// WebScrollBar --------------------------------------------------------------------- 39 40WebScrollBar::WebScrollBar() 41 : m_refCount(0) 42 , m_containingWindow(0) 43 , m_currentPosition(0) 44{ 45 gClassCount++; 46 gClassNameCount.add("WebScrollBar"); 47} 48 49WebScrollBar::~WebScrollBar() 50{ 51 gClassCount--; 52 gClassNameCount.remove("WebScrollBar"); 53} 54 55WebScrollBar* WebScrollBar::createInstance() 56{ 57 WebScrollBar* instance = new WebScrollBar(); 58 instance->AddRef(); 59 return instance; 60} 61 62// IUnknown ------------------------------------------------------------------- 63 64HRESULT 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 78ULONG STDMETHODCALLTYPE WebScrollBar::AddRef(void) 79{ 80 return ++m_refCount; 81} 82 83ULONG STDMETHODCALLTYPE WebScrollBar::Release(void) 84{ 85 ULONG newRef = --m_refCount; 86 if (!newRef) 87 delete(this); 88 89 return newRef; 90} 91 92// IWebScrollBarPrivate ------------------------------------------------------------------ 93HRESULT 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 111HRESULT STDMETHODCALLTYPE WebScrollBar::setEnabled( 112 /* [in] */ BOOL enabled) 113{ 114 m_scrollBar->setEnabled(!!enabled); 115 return S_OK; 116} 117 118HRESULT STDMETHODCALLTYPE WebScrollBar::setSteps( 119 /* [in] */ int lineStep, 120 /* [in] */ int pageStep) 121{ 122 m_scrollBar->setSteps(lineStep, pageStep); 123 return S_OK; 124} 125 126HRESULT STDMETHODCALLTYPE WebScrollBar::setProportion( 127 /* [in] */ int visibleSize, 128 /* [in] */ int totalSize) 129{ 130 m_scrollBar->setProportion(visibleSize, totalSize); 131 return S_OK; 132} 133 134HRESULT 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 142HRESULT 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 150HRESULT 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 159HRESULT 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 169HRESULT 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 182HRESULT 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 191HRESULT 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 200HRESULT 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 210HRESULT 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 221HRESULT 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 243HRESULT 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 256int WebScrollBar::scrollSize(ScrollbarOrientation orientation) const 257{ 258 return (orientation == m_scrollBar->orientation()) ? (m_scrollBar->totalSize() - m_scrollBar->visibleSize()) : 0; 259} 260 261int WebScrollBar::scrollPosition(Scrollbar*) const 262{ 263 return m_currentPosition; 264} 265 266void WebScrollBar::setScrollOffset(const IntPoint& offset) 267{ 268 m_currentPosition = (m_scrollBar->orientation() == HorizontalScrollbar) ? offset.x() : offset.y(); 269 m_delegate->valueChanged(this); 270} 271 272void WebScrollBar::invalidateScrollbarRect(Scrollbar*, const IntRect& rect) 273{ 274 RECT r = rect; 275 ::InvalidateRect(m_containingWindow, &r, false); 276} 277 278Scrollbar* WebScrollBar::horizontalScrollbar() const 279{ 280 return m_scrollBar->orientation() == HorizontalScrollbar ? m_scrollBar.get() : 0; 281} 282 283Scrollbar* WebScrollBar::verticalScrollbar() const 284{ 285 return m_scrollBar->orientation() == VerticalScrollbar ? m_scrollBar.get() : 0; 286} 287