Divorce the notion of a marquee being stopped from JS from the notion of being suspe...
[WebKit-https.git] / WebCore / khtml / rendering / render_layer.h
1 /*
2  * Copyright (C) 2003 Apple Computer, Inc.
3  *
4  * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5  *
6  * Other contributors:
7  *   Robert O'Callahan <roc+@cs.cmu.edu>
8  *   David Baron <dbaron@fas.harvard.edu>
9  *   Christian Biesinger <cbiesinger@web.de>
10  *   Randall Jesup <rjesup@wgate.com>
11  *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
12  *   Josh Soref <timeless@mac.com>
13  *   Boris Zbarsky <bzbarsky@mit.edu>
14  *
15  * This library is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU Lesser General Public
17  * License as published by the Free Software Foundation; either
18  * version 2.1 of the License, or (at your option) any later version.
19  *
20  * This library is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  * Lesser General Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser General Public
26  * License along with this library; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  *
29  * Alternatively, the contents of this file may be used under the terms
30  * of either the Mozilla Public License Version 1.1, found at
31  * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
32  * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
33  * (the "GPL"), in which case the provisions of the MPL or the GPL are
34  * applicable instead of those above.  If you wish to allow use of your
35  * version of this file only under the terms of one of those two
36  * licenses (the MPL or the GPL) and not to allow others to use your
37  * version of this file under the LGPL, indicate your decision by
38  * deletingthe provisions above and replace them with the notice and
39  * other provisions required by the MPL or the GPL, as the case may be.
40  * If you do not delete the provisions above, a recipient may use your
41  * version of this file under any of the LGPL, the MPL or the GPL.
42  */
43
44 #ifndef render_layer_h
45 #define render_layer_h
46
47 #include <qcolor.h>
48 #include <qrect.h>
49 #include <assert.h>
50
51 #include "render_object.h"
52
53 class QScrollBar;
54 template <class T> class QPtrVector;
55
56 namespace khtml {
57     class RenderStyle;
58     class RenderTable;
59     class CachedObject;
60     class RenderCanvas;
61     class RenderText;
62     class RenderFrameSet;
63     class RenderObject;
64     class RenderScrollMediator;
65     
66 class RenderScrollMediator: public QObject
67 {
68 public:
69     RenderScrollMediator(RenderLayer* layer)
70     :m_layer(layer) {}
71
72     void slotValueChanged(int);
73     
74 private:
75     RenderLayer* m_layer;
76 };
77
78 // This class handles the auto-scrolling of layers with overflow: marquee.
79 class Marquee: public QObject
80 {
81     Q_OBJECT
82     
83 public:
84     Marquee(RenderLayer* l);
85
86     void timerEvent(QTimerEvent*);
87
88     int speed() const { return m_speed; }
89     int marqueeSpeed() const;
90     EMarqueeDirection direction() const;
91     EMarqueeDirection reverseDirection() const { return static_cast<EMarqueeDirection>(-direction()); }
92     bool isHorizontal() const;
93     bool isUnfurlMarquee() const;
94     int unfurlPos() const { return m_unfurlPos; }
95
96     EWhiteSpace whiteSpace() { return m_whiteSpace; }
97     
98     int computePosition(EMarqueeDirection dir, bool stopAtClientEdge);
99
100     void setEnd(int end) { m_end = end; }
101     
102     void start();
103     void suspend();
104     void stop();
105
106     void updateMarqueeStyle();
107     void updateMarqueePosition();
108
109 private:
110     RenderLayer* m_layer;
111     int m_currentLoop;
112     int m_totalLoops;
113     int m_timerId;
114     int m_start;
115     int m_end;
116     int m_speed;
117     int m_unfurlPos;
118     bool m_reset: 1;
119     bool m_suspended : 1;
120     bool m_stopped : 1;
121     EWhiteSpace m_whiteSpace : 2;
122     EMarqueeDirection m_direction : 4;
123 };
124
125 class RenderLayer
126 {
127 public:
128 #ifdef APPLE_CHANGES
129     static QScrollBar* gScrollBar;
130 #endif
131     
132     RenderLayer(RenderObject* object);
133     ~RenderLayer();
134     
135     RenderObject* renderer() const { return m_object; }
136     RenderLayer *parent() const { return m_parent; }
137     RenderLayer *previousSibling() const { return m_previous; }
138     RenderLayer *nextSibling() const { return m_next; }
139
140     RenderLayer *firstChild() const { return m_first; }
141     RenderLayer *lastChild() const { return m_last; }
142
143     void addChild(RenderLayer *newChild, RenderLayer* beforeChild = 0);
144     RenderLayer* removeChild(RenderLayer *oldChild);
145
146     void removeOnlyThisLayer();
147     void insertOnlyThisLayer();
148
149     void repaintIncludingDescendants();
150     
151     void styleChanged();
152     
153     Marquee* marquee() const { return m_marquee; }
154     void suspendMarquees();
155
156 #if APPLE_CHANGES
157     bool isTransparent();
158     RenderLayer* transparentAncestor();
159     void beginTransparencyLayers(QPainter* p);
160 #endif
161     
162     RenderLayer* root() {
163         RenderLayer* curr = this;
164         while (curr->parent()) curr = curr->parent();
165         return curr;
166     }
167     
168     int xPos() const { return m_x; }
169     int yPos() const { return m_y; }
170     int width() const { return m_width; }
171     int height() const { return m_height; }
172
173     void setWidth(int w) { m_width = w; }
174     void setHeight(int h) { m_height = h; }
175
176     int scrollWidth();
177     int scrollHeight();
178     
179     void setPos( int xPos, int yPos ) {
180         m_x = xPos;
181         m_y = yPos;
182     }
183
184     // Scrolling methods for layers that can scroll their overflow.
185     void scrollOffset(int& x, int& y);
186     void subtractScrollOffset(int& x, int& y);
187     int scrollXOffset() { return m_scrollX; }
188     int scrollYOffset() { return m_scrollY; }
189     void scrollToOffset(int x, int y, bool updateScrollbars = true, bool repaint = true);
190     void scrollToXOffset(int x) { scrollToOffset(x, m_scrollY); }
191     void scrollToYOffset(int y) { scrollToOffset(m_scrollX, y); }
192     void setHasHorizontalScrollbar(bool hasScrollbar);
193     void setHasVerticalScrollbar(bool hasScrollbar);
194     QScrollBar* horizontalScrollbar() { return m_hBar; }
195     QScrollBar* verticalScrollbar() { return m_vBar; }
196     int verticalScrollbarWidth();
197     int horizontalScrollbarHeight();
198     void moveScrollbarsAside();
199     void positionScrollbars(const QRect& absBounds);
200 #ifdef APPLE_CHANGES
201     void paintScrollbars(QPainter* p, const QRect& damageRect);
202 #endif
203     void updateScrollInfoAfterLayout();
204     void slotValueChanged(int);
205     void updateScrollPositionFromScrollbars();
206
207     void updateLayerPosition();
208     void updateLayerPositions(bool doFullRepaint = false, bool checkForRepaint=true);
209     void computeRepaintRects();
210     void relativePositionOffset(int& relX, int& relY) {
211         relX += m_relX; relY += m_relY;
212     }
213
214     // Get the enclosing stacking context for this layer.  A stacking context is a layer
215     // that has a non-auto z-index.
216     RenderLayer* stackingContext() const;
217     bool isStackingContext() const { return !hasAutoZIndex() || renderer()->isCanvas(); }
218
219     void dirtyZOrderLists();
220     void updateZOrderLists();
221     QPtrVector<RenderLayer>* posZOrderList() const { return m_posZOrderList; }
222     QPtrVector<RenderLayer>* negZOrderList() const { return m_negZOrderList; }
223     
224     // Gets the nearest enclosing positioned ancestor layer (also includes
225     // the <html> layer and the root layer).
226     RenderLayer* enclosingPositionedAncestor() const;
227     
228     void convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int& y) const;
229     
230     bool hasAutoZIndex() const { return renderer()->style()->hasAutoZIndex(); }
231     int zIndex() const { return renderer()->style()->zIndex(); }
232
233     // The two main functions that use the layer system.  The paint method
234     // paints the layers that intersect the damage rect from back to
235     // front.  The nodeAtPoint method looks for mouse events by walking
236     // layers that intersect the point from front to back.
237     void paint(QPainter *p, const QRect& damageRect, bool selectionOnly=false, RenderObject *paintingRoot=0);
238     bool nodeAtPoint(RenderObject::NodeInfo& info, int x, int y);
239
240     // This method figures out our layerBounds in coordinates relative to
241     // |rootLayer}.  It also computes our background and foreground clip rects
242     // for painting/event handling.
243     void calculateRects(const RenderLayer* rootLayer, const QRect& paintDirtyRect, QRect& layerBounds,
244                         QRect& backgroundRect, QRect& foregroundRect);
245     void calculateClipRects(const RenderLayer* rootLayer, QRect& overflowClipRect,
246                             QRect& posClipRect, QRect& fixedClipRect);
247
248     bool intersectsDamageRect(const QRect& layerBounds, const QRect& damageRect) const;
249     bool containsPoint(int x, int y, const QRect& damageRect) const;
250     
251     void updateHoverActiveState(RenderObject::NodeInfo& info);
252     
253     QRect repaintRect() const { return m_repaintRect; }
254
255     void detach(RenderArena* renderArena);
256
257      // Overloaded new operator.  Derived classes must override operator new
258     // in order to allocate out of the RenderArena.
259     void* operator new(size_t sz, RenderArena* renderArena) throw();    
260
261     // Overridden to prevent the normal delete from being called.
262     void operator delete(void* ptr, size_t sz);
263         
264 private:
265     // The normal operator new is disallowed on all render objects.
266     void* operator new(size_t sz) throw();
267
268 private:
269     void setNextSibling(RenderLayer* next) { m_next = next; }
270     void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
271     void setParent(RenderLayer* parent) { m_parent = parent; }
272     void setFirstChild(RenderLayer* first) { m_first = first; }
273     void setLastChild(RenderLayer* last) { m_last = last; }
274
275     void collectLayers(QPtrVector<RenderLayer>*&, QPtrVector<RenderLayer>*&);
276
277     void paintLayer(RenderLayer* rootLayer, QPainter *p, const QRect& paintDirtyRect, 
278                     bool haveTransparency, bool selectionOnly, RenderObject *paintingRoot);
279     RenderLayer* nodeAtPointForLayer(RenderLayer* rootLayer, RenderObject::NodeInfo& info,
280                                      int x, int y, const QRect& hitTestRect);
281
282     void computeScrollDimensions(bool* needHBar = 0, bool* needVBar = 0);
283     
284 protected:   
285     RenderObject* m_object;
286     
287     RenderLayer* m_parent;
288     RenderLayer* m_previous;
289     RenderLayer* m_next;
290
291     RenderLayer* m_first;
292     RenderLayer* m_last;
293
294     QRect m_repaintRect; // Cached repaint rects. Used by layout.
295     QRect m_fullRepaintRect;
296
297     // Our current relative position offset.
298     int m_relX;
299     int m_relY;
300
301     // Our (x,y) coordinates are in our parent layer's coordinate space.
302     int m_x;
303     int m_y;
304
305     // The layer's width/height
306     int m_width;
307     int m_height;
308     
309     // Our scroll offsets if the view is scrolled.
310     int m_scrollX;
311     int m_scrollY;
312     
313     // The width/height of our scrolled area.
314     int m_scrollWidth;
315     int m_scrollHeight;
316     
317     // For layers with overflow, we have a pair of scrollbars.
318     QScrollBar* m_hBar;
319     QScrollBar* m_vBar;
320     RenderScrollMediator* m_scrollMediator;
321
322     // For layers that establish stacking contexts, m_posZOrderList holds a sorted list of all the
323     // descendant layers within the stacking context that have z-indices of 0 or greater
324     // (auto will count as 0).  m_negZOrderList holds descendants within our stacking context with negative
325     // z-indices.
326     QPtrVector<RenderLayer>* m_posZOrderList;
327     QPtrVector<RenderLayer>* m_negZOrderList;
328     
329     bool m_scrollDimensionsDirty : 1;
330     bool m_zOrderListsDirty : 1;
331 #if APPLE_CHANGES
332     bool m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether
333                                  // we ended up painting this layer or any descendants (and therefore need to
334                                  // blend).
335 #endif
336
337     Marquee* m_marquee; // Used by layers with overflow:marquee
338 };
339
340 }; // namespace
341 #endif