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 #pragma warning(push, 0)
32 #include <WebCore/GraphicsContext.h>
33 #include <WebCore/PlatformMouseEvent.h>
34 #include <WebCore/Scrollbar.h>
35 #include <WebCore/ScrollbarTheme.h>
36 #pragma warning(pop)
37
38 using namespace WebCore;
39
40 // WebScrollBar ---------------------------------------------------------------------
41
WebScrollBar()42 WebScrollBar::WebScrollBar()
43 : m_refCount(0)
44 , m_containingWindow(0)
45 {
46 gClassCount++;
47 gClassNameCount.add("WebScrollBar");
48 }
49
~WebScrollBar()50 WebScrollBar::~WebScrollBar()
51 {
52 gClassCount--;
53 gClassNameCount.remove("WebScrollBar");
54 }
55
createInstance()56 WebScrollBar* WebScrollBar::createInstance()
57 {
58 WebScrollBar* instance = new WebScrollBar();
59 instance->AddRef();
60 return instance;
61 }
62
63 // IUnknown -------------------------------------------------------------------
64
QueryInterface(REFIID riid,void ** ppvObject)65 HRESULT STDMETHODCALLTYPE WebScrollBar::QueryInterface(REFIID riid, void** ppvObject)
66 {
67 *ppvObject = 0;
68 if (IsEqualGUID(riid, IID_IUnknown))
69 *ppvObject = static_cast<IUnknown*>(this);
70 else if (IsEqualGUID(riid, IID_IWebScrollBarPrivate))
71 *ppvObject = static_cast<IWebScrollBarPrivate*>(this);
72 else
73 return E_NOINTERFACE;
74
75 AddRef();
76 return S_OK;
77 }
78
AddRef(void)79 ULONG STDMETHODCALLTYPE WebScrollBar::AddRef(void)
80 {
81 return ++m_refCount;
82 }
83
Release(void)84 ULONG STDMETHODCALLTYPE WebScrollBar::Release(void)
85 {
86 ULONG newRef = --m_refCount;
87 if (!newRef)
88 delete(this);
89
90 return newRef;
91 }
92
93 // IWebScrollBarPrivate ------------------------------------------------------------------
init(IWebScrollBarDelegatePrivate * delegate,OLE_HANDLE containingWindow,WebScrollBarOrientation orientation,WebScrollBarControlSize controlSize)94 HRESULT STDMETHODCALLTYPE WebScrollBar::init(
95 /* [in] */ IWebScrollBarDelegatePrivate* delegate,
96 /* [in] */ OLE_HANDLE containingWindow,
97 /* [in] */ WebScrollBarOrientation orientation,
98 /* [in] */ WebScrollBarControlSize controlSize)
99 {
100 if (!delegate || !containingWindow)
101 return E_FAIL;
102 ScrollbarOrientation webCoreOrientation = (ScrollbarOrientation) orientation;
103 ScrollbarControlSize webCoreControlSize = (ScrollbarControlSize) controlSize;
104 m_delegate = delegate;
105 m_scrollBar = Scrollbar::createNativeScrollbar(this, webCoreOrientation, webCoreControlSize);
106 if (!m_scrollBar)
107 return E_FAIL;
108 m_containingWindow = (HWND)(ULONG64)containingWindow;
109 return S_OK;
110 }
111
setEnabled(BOOL enabled)112 HRESULT STDMETHODCALLTYPE WebScrollBar::setEnabled(
113 /* [in] */ BOOL enabled)
114 {
115 m_scrollBar->setEnabled(!!enabled);
116 return S_OK;
117 }
118
setSteps(int lineStep,int pageStep)119 HRESULT STDMETHODCALLTYPE WebScrollBar::setSteps(
120 /* [in] */ int lineStep,
121 /* [in] */ int pageStep)
122 {
123 m_scrollBar->setSteps(lineStep, pageStep);
124 return S_OK;
125 }
126
setProportion(int visibleSize,int totalSize)127 HRESULT STDMETHODCALLTYPE WebScrollBar::setProportion(
128 /* [in] */ int visibleSize,
129 /* [in] */ int totalSize)
130 {
131 m_scrollBar->setProportion(visibleSize, totalSize);
132 return S_OK;
133 }
134
setRect(RECT bounds)135 HRESULT STDMETHODCALLTYPE WebScrollBar::setRect(
136 /* [in] */ RECT bounds)
137 {
138 IntRect rect(bounds.left, bounds.top, bounds.right-bounds.left, bounds.bottom-bounds.top);
139 m_scrollBar->setFrameRect(rect);
140 return S_OK;
141 }
142
setValue(int value)143 HRESULT STDMETHODCALLTYPE WebScrollBar::setValue(
144 /* [in] */ int value)
145 {
146 m_scrollBar->setValue(value);
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_scrollBar->value();
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.right();
177 bounds->top = rect.y();
178 bounds->bottom = rect.bottom();
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 m_scrollBar->scroll(webCoreScrollDirection, webCoreGranularity, multiplier);
251 return S_OK;
252 }
253
254 // ScrollbarClient -------------------------------------------------------
valueChanged(Scrollbar * scrollBar)255 void WebScrollBar::valueChanged(Scrollbar* scrollBar)
256 {
257 if (m_scrollBar != scrollBar) {
258 ASSERT(false); // shouldn't happen
259 return;
260 }
261 m_delegate->valueChanged(this);
262 }
263
invalidateScrollbarRect(Scrollbar *,const IntRect & rect)264 void WebScrollBar::invalidateScrollbarRect(Scrollbar*, const IntRect& rect)
265 {
266 RECT r = rect;
267 ::InvalidateRect(m_containingWindow, &r, false);
268 }
269