c5abd58d30e6c65fa2bdf8a767cb4d9ac88fa726
[WebKit-https.git] / WebCore / platform / gdk / ScrollViewGdk.cpp
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com 
4  * Copyright (C) 2007 Holger Hans Peter Freyther
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
28  */
29
30 #include "config.h"
31 #include "ScrollView.h"
32
33 #include "FloatRect.h"
34 #include "Frame.h"
35 #include "FrameView.h"
36 #include "GraphicsContext.h"
37 #include "IntRect.h"
38 #include "NotImplemented.h"
39 #include "RenderLayer.h"
40
41 #include <gdk/gdk.h>
42 #include <gtk/gtk.h>
43
44 using namespace std;
45
46 namespace WebCore {
47
48 class ScrollView::ScrollViewPrivate
49 {
50 public:
51     ScrollViewPrivate()
52         : hasStaticBackground(false)
53         , suppressScrollbars(false)
54         , vScrollbarMode(ScrollbarAuto)
55         , hScrollbarMode(ScrollbarAuto)
56         , layout(0)
57         , horizontalAdjustment(0)
58         , verticalAdjustment(0)
59     { }
60
61     bool hasStaticBackground;
62     bool suppressScrollbars;
63     ScrollbarMode vScrollbarMode;
64     ScrollbarMode hScrollbarMode;
65     GtkLayout *layout;
66     GtkAdjustment *horizontalAdjustment;
67     GtkAdjustment *verticalAdjustment;
68     IntSize contentsSize;
69     IntSize viewPortSize;
70 };
71
72 ScrollView::ScrollView()
73     : m_data(new ScrollViewPrivate)
74 {}
75
76 ScrollView::~ScrollView()
77 {
78     delete m_data;
79 }
80
81 void ScrollView::updateView(const IntRect& updateRect, bool now)
82 {
83     GdkRectangle rect = { updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height() };
84     GdkDrawable* gdkdrawable = Widget::drawable();
85     if (GDK_IS_WINDOW(gdkdrawable)) {
86         GdkWindow* window = GDK_WINDOW(gdkdrawable);
87         gdk_window_invalidate_rect(window, &rect, true);
88         if (now)
89             gdk_window_process_updates(window, true);
90     }
91 }
92
93 void ScrollView::updateContents(const IntRect& updateRect, bool now)
94 {
95     updateView(updateRect, now);
96 }
97
98 void ScrollView::update()
99 {
100     notImplemented();
101 }
102
103 int ScrollView::visibleWidth() const
104 {
105     return m_data->viewPortSize.width();
106 }
107
108 int ScrollView::visibleHeight() const
109 {
110     return m_data->viewPortSize.height();
111 }
112
113 // Region of the content currently visible in the viewport in the content view's coordinate system.
114 FloatRect ScrollView::visibleContentRect() const
115 {
116     return FloatRect(contentsX(), contentsY(), visibleWidth(), visibleHeight());
117 }
118
119 FloatRect ScrollView::visibleContentRectConsideringExternalScrollers() const
120 {
121     // external scrollers not supported for now
122     return visibleContentRect();
123 }
124
125 void ScrollView::setContentsPos(int newX, int newY)
126 {
127     int dx = newX - contentsX();
128     int dy = newY - contentsY();
129     scrollBy(dx, dy);
130 }
131
132 void ScrollView::resizeContents(int w, int h)
133 {
134     IntSize newSize(w, h);
135     if (m_data->contentsSize == newSize)
136         return;
137
138     m_data->contentsSize = newSize;
139     
140     if (m_data->layout) {
141         gtk_layout_set_size(m_data->layout, w, h);
142         updateScrollbars(); 
143     }
144 }
145
146 int ScrollView::contentsX() const
147 {
148     g_return_val_if_fail(m_data->horizontalAdjustment, 0);
149     return static_cast<int>(gtk_adjustment_get_value(m_data->horizontalAdjustment));
150 }
151
152 int ScrollView::contentsY() const
153 {
154     g_return_val_if_fail(m_data->verticalAdjustment, 0);
155     return static_cast<int>(gtk_adjustment_get_value(m_data->verticalAdjustment));
156 }
157
158 int ScrollView::contentsWidth() const
159 {
160     return m_data->contentsSize.width();
161 }
162
163 int ScrollView::contentsHeight() const
164 {
165     return m_data->contentsSize.height();
166 }
167
168 IntSize ScrollView::scrollOffset() const
169 {
170     g_return_val_if_fail(m_data, IntSize());
171     return IntSize(contentsX(), contentsY());
172 }
173
174 void ScrollView::scrollBy(int dx, int dy)
175 {
176     g_return_if_fail(m_data->horizontalAdjustment);
177     g_return_if_fail(m_data->verticalAdjustment);
178
179     int current_x = contentsX();
180     int current_y = contentsY();
181
182     gtk_adjustment_set_value(m_data->horizontalAdjustment,
183                              CLAMP(current_x+dx, m_data->horizontalAdjustment->lower,
184                                    MAX(0.0, m_data->horizontalAdjustment->upper - m_data->horizontalAdjustment->page_size)));
185     gtk_adjustment_set_value(m_data->verticalAdjustment,
186                              CLAMP(current_y+dy, m_data->verticalAdjustment->lower,
187                                    MAX(0.0, m_data->verticalAdjustment->upper - m_data->verticalAdjustment->page_size)));
188 }
189
190 ScrollbarMode ScrollView::hScrollbarMode() const
191 {
192     return m_data->hScrollbarMode;
193 }
194
195 ScrollbarMode ScrollView::vScrollbarMode() const
196 {
197     return m_data->vScrollbarMode;
198 }
199
200 void ScrollView::suppressScrollbars(bool suppressed, bool repaintOnSuppress)
201 {
202     m_data->suppressScrollbars = suppressed;
203     if (repaintOnSuppress)
204         updateScrollbars();
205 }
206
207 void ScrollView::setHScrollbarMode(ScrollbarMode newMode)
208 {
209     if (m_data->hScrollbarMode != newMode) {
210         m_data->hScrollbarMode = newMode;
211         updateScrollbars();
212     }
213 }
214
215 void ScrollView::setVScrollbarMode(ScrollbarMode newMode)
216 {
217     if (m_data->vScrollbarMode != newMode) {
218         m_data->vScrollbarMode = newMode;
219         updateScrollbars();
220     }
221 }
222
223 void ScrollView::setScrollbarsMode(ScrollbarMode newMode)
224 {
225     m_data->hScrollbarMode = m_data->vScrollbarMode = newMode;
226     updateScrollbars();
227 }
228
229 void ScrollView::setStaticBackground(bool flag)
230 {
231     m_data->hasStaticBackground = flag;
232 }
233
234 /*
235  * only update the adjustments, the GtkLayout is doing the work
236  * for us (assuming it is in a box...).
237  */
238 void ScrollView::setFrameGeometry(const IntRect& r)
239 {
240     Widget::setFrameGeometry(r);
241     updateGeometry(r.width(), r.height());
242 }
243
244 void ScrollView::updateGeometry(int width, int height)
245 {
246     m_data->viewPortSize = IntSize(width,height);
247 }
248
249 void ScrollView::setGtkWidget(GtkLayout* layout)
250 {
251     g_return_if_fail(GTK_LAYOUT(layout));
252     m_data->layout = layout;
253     m_data->horizontalAdjustment = gtk_layout_get_hadjustment(layout);
254     m_data->verticalAdjustment = gtk_layout_get_vadjustment(layout);
255
256     Widget::setGtkWidget(GTK_WIDGET(layout));
257     if (!GDK_IS_WINDOW(drawable())) {
258         LOG_ERROR("image scrollview not supported");
259         return;
260     }
261 }
262
263 void ScrollView::addChild(Widget*)
264
265     notImplemented();
266 }
267
268 void ScrollView::removeChild(Widget*)
269 {
270     notImplemented();
271 }
272
273 void ScrollView::scrollRectIntoViewRecursively(const IntRect&)
274 {
275     notImplemented();
276 }
277
278 bool ScrollView::inWindow() const
279 {
280     notImplemented();
281     return true;
282 }
283
284 void ScrollView::wheelEvent(PlatformWheelEvent&)
285 {
286     notImplemented();
287 }
288
289 void ScrollView::updateScrollbars()
290 {
291     g_return_if_fail(m_data->horizontalAdjustment);
292     g_return_if_fail(m_data->verticalAdjustment);
293     
294     m_data->horizontalAdjustment->page_size = visibleWidth();
295     m_data->horizontalAdjustment->step_increment = 13;
296     
297     m_data->verticalAdjustment->page_size = visibleHeight();
298     m_data->verticalAdjustment->step_increment = 13;
299     
300     gtk_adjustment_changed(m_data->horizontalAdjustment);
301     gtk_adjustment_value_changed(m_data->horizontalAdjustment);
302     
303     gtk_adjustment_changed(m_data->verticalAdjustment);
304     gtk_adjustment_value_changed(m_data->verticalAdjustment);
305 }
306
307 IntPoint ScrollView::windowToContents(const IntPoint& point) const
308
309     return point;
310 }
311
312 IntPoint ScrollView::contentsToWindow(const IntPoint& point) const
313 {
314     return point;
315 }
316
317 PlatformScrollbar* ScrollView::scrollbarUnderMouse(const PlatformMouseEvent& mouseEvent)
318
319     notImplemented();
320     return 0;
321 }
322
323 }