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