1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #ifndef nsViewManager_h___
39 : #define nsViewManager_h___
40 : #include "nsCOMPtr.h"
41 : #include "nsIViewManager.h"
42 : #include "nsCRT.h"
43 : #include "nsITimer.h"
44 : #include "prtime.h"
45 : #include "prinrval.h"
46 : #include "nsVoidArray.h"
47 : #include "nsThreadUtils.h"
48 : #include "nsView.h"
49 : #include "nsIPresShell.h"
50 : #include "nsDeviceContext.h"
51 :
52 :
53 : /**
54 : Invalidation model:
55 :
56 : 1) Callers call into the view manager and ask it to invalidate a view.
57 :
58 : 2) The view manager finds the "right" widget for the view, henceforth called
59 : the root widget.
60 :
61 : 3) The view manager traverses descendants of the root widget and for each
62 : one that needs invalidation stores the rect to invalidate on the widget's
63 : view (batching).
64 :
65 : 4) The dirty region is flushed to the right widget when
66 : ProcessPendingUpdates is called from the RefreshDriver.
67 :
68 : It's important to note that widgets associated to views outside this view
69 : manager can end up being invalidated during step 3. Therefore, the end of a
70 : view update batch really needs to traverse the entire view tree, to ensure
71 : that those invalidates happen.
72 :
73 : To cope with this, invalidation processing and should only happen on the
74 : root viewmanager.
75 : */
76 :
77 : class nsViewManager : public nsIViewManager {
78 : public:
79 : nsViewManager();
80 :
81 0 : NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
82 :
83 : NS_DECL_ISUPPORTS
84 :
85 : NS_IMETHOD Init(nsDeviceContext* aContext);
86 :
87 : NS_IMETHOD_(nsIView*) CreateView(const nsRect& aBounds,
88 : const nsIView* aParent,
89 : nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow);
90 :
91 : NS_IMETHOD_(nsIView*) GetRootView();
92 : NS_IMETHOD SetRootView(nsIView *aView);
93 :
94 : NS_IMETHOD GetWindowDimensions(nscoord *width, nscoord *height);
95 : NS_IMETHOD SetWindowDimensions(nscoord width, nscoord height);
96 : NS_IMETHOD FlushDelayedResize(bool aDoReflow);
97 :
98 : NS_IMETHOD InvalidateView(nsIView *aView);
99 : NS_IMETHOD InvalidateViewNoSuppression(nsIView *aView, const nsRect &aRect);
100 : NS_IMETHOD InvalidateAllViews();
101 :
102 : NS_IMETHOD DispatchEvent(nsGUIEvent *aEvent,
103 : nsIView* aTargetView, nsEventStatus* aStatus);
104 :
105 : NS_IMETHOD InsertChild(nsIView *parent, nsIView *child, nsIView *sibling,
106 : bool above);
107 :
108 : NS_IMETHOD InsertChild(nsIView *parent, nsIView *child,
109 : PRInt32 zindex);
110 :
111 : NS_IMETHOD RemoveChild(nsIView *parent);
112 :
113 : NS_IMETHOD MoveViewTo(nsIView *aView, nscoord aX, nscoord aY);
114 :
115 : NS_IMETHOD ResizeView(nsIView *aView, const nsRect &aRect, bool aRepaintExposedAreaOnly = false);
116 :
117 : NS_IMETHOD SetViewFloating(nsIView *aView, bool aFloating);
118 :
119 : NS_IMETHOD SetViewVisibility(nsIView *aView, nsViewVisibility aVisible);
120 :
121 : NS_IMETHOD SetViewZIndex(nsIView *aView, bool aAuto, PRInt32 aZIndex, bool aTopMost=false);
122 :
123 0 : virtual void SetPresShell(nsIPresShell *aPresShell) { mPresShell = aPresShell; }
124 0 : virtual nsIPresShell* GetPresShell() { return mPresShell; }
125 :
126 : NS_IMETHOD GetDeviceContext(nsDeviceContext *&aContext);
127 :
128 : virtual nsIViewManager* IncrementDisableRefreshCount();
129 : virtual void DecrementDisableRefreshCount();
130 :
131 : NS_IMETHOD GetRootWidget(nsIWidget **aWidget);
132 :
133 : NS_IMETHOD IsPainting(bool& aIsPainting);
134 : NS_IMETHOD GetLastUserEventTime(PRUint32& aTime);
135 : static PRUint32 gLastUserEventTime;
136 :
137 : /* Update the cached RootViewManager pointer on this view manager. */
138 : void InvalidateHierarchy();
139 :
140 : virtual void ProcessPendingUpdates();
141 : virtual void UpdateWidgetGeometry();
142 :
143 : protected:
144 : virtual ~nsViewManager();
145 :
146 : private:
147 :
148 : void FlushPendingInvalidates();
149 : void ProcessPendingUpdatesForView(nsView *aView,
150 : bool aFlushDirtyRegion = true);
151 : void FlushDirtyRegionToWidget(nsView* aView);
152 : /**
153 : * Call WillPaint() on all view observers under this vm root.
154 : */
155 : void CallWillPaintOnObservers(bool aWillSendDidPaint);
156 : void CallDidPaintOnObserver();
157 : void ReparentChildWidgets(nsIView* aView, nsIWidget *aNewWidget);
158 : void ReparentWidgets(nsIView* aView, nsIView *aParent);
159 : void InvalidateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedRegion);
160 :
161 : void InvalidateViews(nsView *aView);
162 :
163 : // aView is the view for aWidget and aRegion is relative to aWidget.
164 : void Refresh(nsView *aView, nsIWidget *aWidget, const nsIntRegion& aRegion,
165 : bool aWillSendDidPaint);
166 :
167 : void InvalidateRectDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut);
168 : void InvalidateHorizontalBandDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut,
169 : nscoord aY1, nscoord aY2, bool aInCutOut);
170 :
171 : // Utilities
172 :
173 : bool IsViewInserted(nsView *aView);
174 :
175 : /**
176 : * Intersects aRect with aView's bounds and then transforms it from aView's
177 : * coordinate system to the coordinate system of the widget attached to
178 : * aView.
179 : */
180 : nsIntRect ViewToWidget(nsView *aView, const nsRect &aRect) const;
181 :
182 : void DoSetWindowDimensions(nscoord aWidth, nscoord aHeight);
183 :
184 0 : bool IsPainting() const {
185 0 : return RootViewManager()->mPainting;
186 : }
187 :
188 0 : void SetPainting(bool aPainting) {
189 0 : RootViewManager()->mPainting = aPainting;
190 0 : }
191 :
192 : nsresult InvalidateView(nsIView *aView, const nsRect &aRect);
193 :
194 : public: // NOT in nsIViewManager, so private to the view module
195 0 : nsView* GetRootViewImpl() const { return mRootView; }
196 0 : nsViewManager* RootViewManager() const { return mRootViewManager; }
197 0 : bool IsRootVM() const { return this == RootViewManager(); }
198 :
199 : // Whether synchronous painting is allowed at the moment. For example,
200 : // widget geometry changes can cause synchronous painting, so they need to
201 : // be deferred while refresh is disabled.
202 0 : bool IsPaintingAllowed() { return RootViewManager()->mRefreshDisableCount == 0; }
203 :
204 : // Call this when you need to let the viewmanager know that it now has
205 : // pending updates.
206 : void PostPendingUpdate();
207 :
208 0 : PRUint32 AppUnitsPerDevPixel() const
209 : {
210 0 : return mContext->AppUnitsPerDevPixel();
211 : }
212 :
213 : private:
214 : nsRefPtr<nsDeviceContext> mContext;
215 : nsIPresShell *mPresShell;
216 :
217 : // The size for a resize that we delayed until the root view becomes
218 : // visible again.
219 : nsSize mDelayedResize;
220 :
221 : nsView *mRootView;
222 : // mRootViewManager is a strong ref unless it equals |this|. It's
223 : // never null (if we have no ancestors, it will be |this|).
224 : nsViewManager *mRootViewManager;
225 :
226 : // The following members should not be accessed directly except by
227 : // the root view manager. Some have accessor functions to enforce
228 : // this, as noted.
229 :
230 : PRInt32 mRefreshDisableCount;
231 : // Use IsPainting() and SetPainting() to access mPainting.
232 : bool mPainting;
233 : bool mRecursiveRefreshPending;
234 : bool mHasPendingUpdates;
235 : bool mHasPendingWidgetGeometryChanges;
236 : bool mInScroll;
237 :
238 : //from here to public should be static and locked... MMP
239 : static PRInt32 mVMCount; //number of viewmanagers
240 :
241 : //list of view managers
242 : static nsVoidArray *gViewManagers;
243 : };
244 :
245 : #endif /* nsViewManager_h___ */
|