Fix Win32 bustage.
[WebKit-https.git] / WebCore / platform / win / ScrollViewWin.cpp
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2006 Justin Haygood <jhaygood@spsu.edu>.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #include "config.h"
28 #include "ScrollView.h"
29
30 #include <algorithm>
31 #include "FloatRect.h"
32 #include "IntRect.h"
33 #include <windows.h>
34
35 using namespace std;
36
37 namespace WebCore {
38
39 class ScrollView::ScrollViewPrivate {
40 public:
41     ScrollViewPrivate()
42         : hasStaticBackground(false)
43         , suppressScrollBars(false)
44         , vScrollBarMode(ScrollBarAuto)
45         , hScrollBarMode(ScrollBarAuto)
46     {
47     }
48     IntSize scrollOffset;
49     IntSize contentsSize;
50     bool hasStaticBackground;
51     bool suppressScrollBars;
52     ScrollBarMode vScrollBarMode;
53     ScrollBarMode hScrollBarMode;
54 };
55
56 ScrollView::ScrollView()
57     : m_data(new ScrollViewPrivate())
58 {
59 }
60
61 ScrollView::~ScrollView()
62 {
63     delete m_data;
64 }
65
66 void ScrollView::updateContents(const IntRect& updateRect, bool now)
67 {
68     IntRect adjustedDirtyRect(updateRect);
69     adjustedDirtyRect.move(-m_data->scrollOffset);
70
71     RECT dirtyRect = RECT(adjustedDirtyRect);
72 #if PAINT_FLASHING_DEBUG
73     HDC dc = GetDC(containingWindow());
74     FillRect(dc, &dirtyRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
75     ReleaseDC(containingWindow(), dc);
76 #endif
77
78     InvalidateRect(containingWindow(), &dirtyRect, true);
79     if (now)
80         UpdateWindow(containingWindow());
81 }
82
83 int ScrollView::visibleWidth() const
84 {
85     RECT bounds;
86     GetClientRect(containingWindow(), &bounds);
87     return (bounds.right - bounds.left);
88 }
89
90 int ScrollView::visibleHeight() const
91 {
92     RECT bounds;
93     GetClientRect(containingWindow(), &bounds);
94     return (bounds.bottom - bounds.top);
95 }
96
97 FloatRect ScrollView::visibleContentRect() const
98 {
99     RECT bounds;
100     GetClientRect(containingWindow(), &bounds);
101     FloatRect contentRect = bounds;
102     contentRect.move(m_data->scrollOffset);
103     return contentRect;
104 }
105
106 void ScrollView::setContentsPos(int newX, int newY)
107 {
108     int dx = newX - contentsX();
109     int dy = newY - contentsY();
110     scrollBy(dx, dy);
111 }
112
113 void ScrollView::resizeContents(int w,int h)
114 {
115     IntSize newSize(w,h);
116     if (m_data->contentsSize != newSize) {
117         m_data->contentsSize = newSize;
118         updateScrollBars(m_data->scrollOffset);
119     }    
120 }
121
122 int ScrollView::contentsX() const
123 {
124     return scrollOffset().width();
125 }
126
127 int ScrollView::contentsY() const
128 {
129     return scrollOffset().height();
130 }
131
132 int ScrollView::contentsWidth() const
133 {
134     return m_data->contentsSize.width();
135 }
136
137 int ScrollView::contentsHeight() const
138 {
139     return m_data->contentsSize.height();
140 }
141
142 IntPoint ScrollView::contentsToWindow(const IntPoint& point) const
143 {
144     return point - scrollOffset();
145 }
146
147 IntPoint ScrollView::windowToContents(const IntPoint& point) const
148 {
149     return point + scrollOffset();
150 }
151
152 IntSize ScrollView::scrollOffset() const
153 {
154     return m_data->scrollOffset;
155 }
156
157 IntSize ScrollView::maximumScroll() const
158 {
159     IntSize delta = m_data->contentsSize - m_data->scrollOffset;
160     delta.clampNegativeToZero();
161     return delta;
162 }
163
164 void ScrollView::scrollBy(int dx, int dy)
165 {
166     IntSize scrollOffset = m_data->scrollOffset;
167     IntSize maxScroll = maximumScroll();
168     IntSize newScrollOffset = scrollOffset + IntSize(dx, dy);
169     newScrollOffset.clampNegativeToZero();
170
171     if (newScrollOffset != scrollOffset) {
172         m_data->scrollOffset = newScrollOffset;
173         updateScrollBars(m_data->scrollOffset);
174         // ScrollBar updates can fail, so we check the final delta before scrolling
175         IntSize scrollDelta = m_data->scrollOffset - scrollOffset;
176         if (scrollDelta == IntSize())
177             return;
178         if (!m_data->hasStaticBackground)
179             // FIXME: This could be made more efficient by passing a valid clip rect for only the document content.
180             ScrollWindowEx(containingWindow(), -scrollDelta.width(), -scrollDelta.height(), 0, 0, 0, 0, SW_INVALIDATE);
181         else
182             InvalidateRect(containingWindow(), 0, true);
183     }
184 }
185
186 WebCore::ScrollBarMode ScrollView::hScrollBarMode() const
187 {
188     return m_data->hScrollBarMode;
189 }
190
191 WebCore::ScrollBarMode ScrollView::vScrollBarMode() const
192 {
193     return m_data->vScrollBarMode;
194 }
195
196 void ScrollView::suppressScrollBars(bool suppressed, bool repaintOnSuppress)
197 {
198     m_data->suppressScrollBars = suppressed;
199     if (repaintOnSuppress)
200         updateScrollBars(m_data->scrollOffset);
201 }
202
203 void ScrollView::setHScrollBarMode(ScrollBarMode newMode)
204 {
205     if (m_data->hScrollBarMode != newMode) {
206         m_data->hScrollBarMode = newMode;
207         updateScrollBars(m_data->scrollOffset);
208     }
209 }
210
211 void ScrollView::setVScrollBarMode(ScrollBarMode newMode)
212 {
213     if (m_data->vScrollBarMode != newMode) {
214         m_data->vScrollBarMode = newMode;
215         updateScrollBars(m_data->scrollOffset);
216     }
217 }
218
219 void ScrollView::setScrollBarsMode(ScrollBarMode newMode)
220 {
221     m_data->hScrollBarMode = m_data->vScrollBarMode = newMode;
222     updateScrollBars(m_data->scrollOffset);
223 }
224
225 void ScrollView::setStaticBackground(bool flag)
226 {
227     m_data->hasStaticBackground = flag;
228 }
229
230 static int updateScrollInfo(ScrollView* view, short type, int current, int max, int pageSize)
231 {
232     SCROLLINFO si;
233     si.cbSize = sizeof(si);
234     si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
235     si.nMin   = 0;
236     si.nMax   = max;
237     si.nPage  = pageSize;
238     si.nPos   = current;
239     SetScrollInfo(view->containingWindow(), type, &si, TRUE);
240     GetScrollInfo(view->containingWindow(), type, &si);
241     return si.nPos;
242 }
243
244 void ScrollView::updateScrollBars(const IntPoint&)
245
246     IntSize maxScrollPosition(contentsWidth(), contentsHeight());
247     IntSize scroll = scrollOffset().shrunkTo(maxScrollPosition);
248     scroll.clampNegativeToZero();
249
250     m_data->scrollOffset = 
251         IntSize(updateScrollInfo(this, SB_HORZ, scroll.width(), contentsWidth() - 1, width()),
252                 updateScrollInfo(this, SB_VERT, scroll.height(), contentsHeight() - 1, height()));
253
254     if (m_data->hScrollBarMode != ScrollBarAuto || m_data->suppressScrollBars)
255         ShowScrollBar(containingWindow(), SB_HORZ, (m_data->hScrollBarMode != ScrollBarAlwaysOff) && !m_data->suppressScrollBars);
256     if (m_data->vScrollBarMode != ScrollBarAuto || m_data->suppressScrollBars)
257         ShowScrollBar(containingWindow(), SB_VERT, (m_data->vScrollBarMode != ScrollBarAlwaysOff) && !m_data->suppressScrollBars);
258 }
259
260 }