initial import
[vuplus_webkit] / Source / WebKit / win / WebScrollBar.cpp
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 }