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
WebScrollBar()40 WebScrollBar::WebScrollBar()
41 : m_refCount(0)
42 , m_containingWindow(0)
43 , m_currentPosition(0)
44 {
45 gClassCount++;
46 gClassNameCount.add("WebScrollBar");
47 }
48
~WebScrollBar()49 WebScrollBar::~WebScrollBar()
50 {
51 gClassCount--;
52 gClassNameCount.remove("WebScrollBar");
53 }
54
createInstance()55 WebScrollBar* WebScrollBar::createInstance()
56 {
57 WebScrollBar* instance = new WebScrollBar();
58 instance->AddRef();
59 return instance;
60 }
61
62 // IUnknown -------------------------------------------------------------------
63
QueryInterface(REFIID riid,void ** ppvObject)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
AddRef(void)78 ULONG STDMETHODCALLTYPE WebScrollBar::AddRef(void)
79 {
80 return ++m_refCount;
81 }
82
Release(void)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 ------------------------------------------------------------------
init(IWebScrollBarDelegatePrivate * delegate,OLE_HANDLE containingWindow,WebScrollBarOrientation orientation,WebScrollBarControlSize controlSize)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
setEnabled(BOOL enabled)111 HRESULT STDMETHODCALLTYPE WebScrollBar::setEnabled(
112 /* [in] */ BOOL enabled)
113 {
114 m_scrollBar->setEnabled(!!enabled);
115 return S_OK;
116 }
117
setSteps(int lineStep,int pageStep)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
setProportion(int visibleSize,int totalSize)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
setRect(RECT bounds)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
setValue(int value)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
value(int * value)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
paint(HDC dc,RECT damageRect)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
frameRect(RECT * bounds)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
width(int * w)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
height(int * h)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
requestedWidth(int * w)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
requestedHeight(int * h)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
handleMouseEvent(OLE_HANDLE window,UINT msg,WPARAM wParam,LPARAM lParam)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
scroll(WebScrollDirection direction,WebScrollGranularity granularity,float multiplier)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
scrollSize(ScrollbarOrientation orientation) const256 int WebScrollBar::scrollSize(ScrollbarOrientation orientation) const
257 {
258 return (orientation == m_scrollBar->orientation()) ? (m_scrollBar->totalSize() - m_scrollBar->visibleSize()) : 0;
259 }
260
scrollPosition(Scrollbar *) const261 int WebScrollBar::scrollPosition(Scrollbar*) const
262 {
263 return m_currentPosition;
264 }
265
setScrollOffset(const IntPoint & offset)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
invalidateScrollbarRect(Scrollbar *,const IntRect & rect)272 void WebScrollBar::invalidateScrollbarRect(Scrollbar*, const IntRect& rect)
273 {
274 RECT r = rect;
275 ::InvalidateRect(m_containingWindow, &r, false);
276 }
277
horizontalScrollbar() const278 Scrollbar* WebScrollBar::horizontalScrollbar() const
279 {
280 return m_scrollBar->orientation() == HorizontalScrollbar ? m_scrollBar.get() : 0;
281 }
282
verticalScrollbar() const283 Scrollbar* WebScrollBar::verticalScrollbar() const
284 {
285 return m_scrollBar->orientation() == VerticalScrollbar ? m_scrollBar.get() : 0;
286 }
287