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
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/
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
15 * The Original Code is mozilla.org code.
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.
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.
36 * ***** END LICENSE BLOCK ***** */
41 #include "nsISupports.h"
45 #include "nsNativeWidget.h"
46 #include "nsIWidget.h"
47 #include "nsWidgetInitData.h"
56 // Enumerated type to indicate the visibility of a layer.
57 // hide - the layer is not shown.
58 // show - the layer is shown irrespective of the visibility of
59 // the layer's parent.
60 enum nsViewVisibility
{
61 nsViewVisibility_kHide
= 0,
62 nsViewVisibility_kShow
= 1
65 #define NS_IVIEW_IID \
66 { 0xda62efbf, 0x0711, 0x4b79, \
67 { 0x87, 0x85, 0x9e, 0xec, 0xed, 0xf5, 0xb0, 0x32 } }
71 // Indicates that the view is using auto z-indexing
72 #define NS_VIEW_FLAG_AUTO_ZINDEX 0x0004
74 // Indicates that the view is a floating view.
75 #define NS_VIEW_FLAG_FLOATING 0x0008
77 // If set it indicates that this view should be
78 // displayed above z-index:auto views if this view
79 // is z-index:auto also
80 #define NS_VIEW_FLAG_TOPMOST 0x0010
82 //----------------------------------------------------------------------
87 * Views are NOT reference counted. Use the Destroy() member function to
90 * The lifetime of the view hierarchy is bounded by the lifetime of the
91 * view manager that owns the views.
93 * Most of the methods here are read-only. To set the corresponding properties
94 * of a view, go through nsIViewManager.
100 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IVIEW_IID
)
103 * Find the view for the given widget, if there is one.
104 * @return the view the widget belongs to, or null if the widget doesn't
105 * belong to any view.
107 static nsIView
* GetViewFor(nsIWidget
* aWidget
);
110 * Get the view manager which "owns" the view.
111 * This method might require some expensive traversal work in the future. If you can get the
112 * view manager from somewhere else, do that instead.
113 * @result the view manager
115 nsIViewManager
* GetViewManager() const
116 { return reinterpret_cast<nsIViewManager
*>(mViewManager
); }
121 * The view destroys its child views, and destroys and releases its
122 * widget (if it has one).
124 * Also informs the view manager that the view is destroyed by calling
125 * SetRootView(NULL) if the view is the root view and calling RemoveChild()
131 * Called to get the position of a view.
132 * The specified coordinates are relative to the parent view's origin, but
133 * are in appunits of this.
134 * This is the (0, 0) origin of the coordinate space established by this view.
135 * @param x out parameter for x position
136 * @param y out parameter for y position
138 nsPoint
GetPosition() const {
139 // Call ExternalIsRoot here so that we can get to it from other
141 NS_ASSERTION(!ExternalIsRoot() || (mPosX
== 0 && mPosY
== 0),
142 "root views should always have explicit position of (0,0)");
143 return nsPoint(mPosX
, mPosY
);
147 * Set the position of a view. This does not cause any invalidation. It
148 * does reposition any widgets in this view or its descendants.
150 virtual void SetPosition(nscoord aX
, nscoord aY
) = 0;
153 * Called to get the dimensions and position of the view's bounds.
154 * The view's bounds (x,y) are relative to the origin of the parent view, but
155 * are in appunits of this.
156 * The view's bounds (x,y) might not be the same as the view's position,
157 * if the view has content above or to the left of its origin.
158 * @param aBounds out parameter for bounds
160 nsRect
GetBounds() const { return mDimBounds
; }
163 * The bounds of this view relative to this view. So this is the same as
164 * GetBounds except this is relative to this view instead of the parent view.
166 nsRect
GetDimensions() const {
167 nsRect r
= mDimBounds
; r
.MoveBy(-mPosX
, -mPosY
); return r
;
171 * Set the dimensions at which invalidations are clipped, which can
172 * be different than |GetDimensions()|. |aRect| is relative to
173 * |this|. It can be null, in which case invalidations return to
174 * being clipped to the view dimensions.
176 * The caller is responsible for invalidating the area that may lie
177 * outside the view dimensions but inside |aRect| after this call.
179 void SetInvalidationDimensions(const nsRect
* aRect
);
182 * Get the offset between the coordinate systems of |this| and aOther.
183 * Adding the return value to a point in the coordinate system of |this|
184 * will transform the point to the coordinate system of aOther.
186 * The offset is expressed in appunits of |this|. So if you are getting the
187 * offset between views in different documents that might have different
188 * appunits per devpixel ratios you need to be careful how you use the
191 * If aOther is null, this will return the offset of |this| from the
192 * root of the viewmanager tree.
194 * This function is fastest when aOther is an ancestor of |this|.
196 * NOTE: this actually returns the offset from aOther to |this|, but
197 * that offset is added to transform _coordinates_ from |this| to aOther.
199 nsPoint
GetOffsetTo(const nsIView
* aOther
) const;
202 * Get the offset between the origin of |this| and the origin of aWidget.
203 * Adding the return value to a point in the coordinate system of |this|
204 * will transform the point to the coordinate system of aWidget.
206 * The offset is expressed in appunits of |this|.
208 nsPoint
GetOffsetToWidget(nsIWidget
* aWidget
) const;
211 * Takes a point aPt that is in the coordinate system of |this|'s parent view
212 * and converts it to be in the coordinate system of |this| taking into
213 * account the offset and any app unit per dev pixel ratio differences.
215 nsPoint
ConvertFromParentCoords(nsPoint aPt
) const;
218 * Called to query the visibility state of a view.
219 * @result current visibility state
221 nsViewVisibility
GetVisibility() const { return mVis
; }
224 * Get whether the view "floats" above all other views,
225 * which tells the compositor not to consider higher views in
226 * the view hierarchy that would geometrically intersect with
227 * this view. This is a hack, but it fixes some problems with
228 * views that need to be drawn in front of all other views.
229 * @result true if the view floats, false otherwise.
231 bool GetFloating() const { return (mVFlags
& NS_VIEW_FLAG_FLOATING
) != 0; }
234 * Called to query the parent of the view.
235 * @result view's parent
237 nsIView
* GetParent() const { return reinterpret_cast<nsIView
*>(mParent
); }
240 * The view's first child is the child which is earliest in document order.
241 * @result first child
243 nsIView
* GetFirstChild() const { return reinterpret_cast<nsIView
*>(mFirstChild
); }
246 * Called to query the next sibling of the view.
247 * @result view's next sibling
249 nsIView
* GetNextSibling() const { return reinterpret_cast<nsIView
*>(mNextSibling
); }
250 void SetNextSibling(nsIView
*aSibling
) {
251 mNextSibling
= reinterpret_cast<nsView
*>(aSibling
);
255 * Set the view's frame.
257 void SetFrame(nsIFrame
* aRootFrame
) { mFrame
= aRootFrame
; }
260 * Retrieve the view's frame.
262 nsIFrame
* GetFrame() const { return mFrame
; }
265 * Get the nearest widget in this view or a parent of this view and
266 * the offset from the widget's origin to this view's origin
267 * @param aOffset - if non-null the offset from this view's origin to the
268 * widget's origin (usually positive) expressed in appunits of this will be
269 * returned in aOffset.
270 * @return the widget closest to this view; can be null because some view trees
271 * don't have widgets at all (e.g., printing), but if any view in the view tree
272 * has a widget, then it's safe to assume this will not return null
273 * XXX Remove this 'virtual' when gfx+widget are merged into gklayout;
274 * Mac widget depends on this method, which is BOGUS!
276 virtual nsIWidget
* GetNearestWidget(nsPoint
* aOffset
) const;
279 * Create a widget to associate with this view. This variant of
280 * CreateWidget*() will look around in the view hierarchy for an
281 * appropriate parent widget for the view.
283 * @param aWidgetInitData data used to initialize this view's widget before
284 * its create is called.
285 * @return error status
287 nsresult
CreateWidget(nsWidgetInitData
*aWidgetInitData
= nsnull
,
288 bool aEnableDragDrop
= true,
289 bool aResetVisibility
= true);
292 * Create a widget for this view with an explicit parent widget.
293 * |aParentWidget| must be nonnull. The other params are the same
294 * as for |CreateWidget()|.
296 nsresult
CreateWidgetForParent(nsIWidget
* aParentWidget
,
297 nsWidgetInitData
*aWidgetInitData
= nsnull
,
298 bool aEnableDragDrop
= true,
299 bool aResetVisibility
= true);
302 * Create a popup widget for this view. Pass |aParentWidget| to
303 * explicitly set the popup's parent. If it's not passed, the view
304 * hierarchy will be searched for an appropriate parent widget. The
305 * other params are the same as for |CreateWidget()|, except that
306 * |aWidgetInitData| must be nonnull.
308 nsresult
CreateWidgetForPopup(nsWidgetInitData
*aWidgetInitData
,
309 nsIWidget
* aParentWidget
= nsnull
,
310 bool aEnableDragDrop
= true,
311 bool aResetVisibility
= true);
314 * Destroys the associated widget for this view. If this method is
315 * not called explicitly, the widget when be destroyed when its
316 * view gets destroyed.
318 void DestroyWidget();
321 * Attach/detach a top level widget from this view. When attached, the view
322 * updates the widget's device context and allows the view to begin receiving
323 * gecko events. The underlying base window associated with the widget will
324 * continues to receive events it expects.
326 * An attached widget will not be destroyed when the view is destroyed,
327 * allowing the recycling of a single top level widget over multiple views.
329 * @param aWidget The widget to attach to / detach from.
331 nsresult
AttachToTopLevelWidget(nsIWidget
* aWidget
);
332 nsresult
DetachFromTopLevelWidget();
335 * Returns a flag indicating whether the view owns it's widget
336 * or is attached to an existing top level widget.
338 bool IsAttachedToTopLevel() const { return mWidgetIsTopLevel
; }
341 * In 4.0, the "cutout" nature of a view is queryable.
342 * If we believe that all cutout view have a native widget, this
343 * could be a replacement.
344 * @param aWidget out parameter for widget that this view contains,
345 * or nsnull if there is none.
347 nsIWidget
* GetWidget() const { return mWindow
; }
350 * Returns true if the view has a widget associated with it.
352 bool HasWidget() const { return mWindow
!= nsnull
; }
355 * Make aWidget direct its events to this view.
356 * The caller must call DetachWidgetEventHandler before this view
359 EVENT_CALLBACK
AttachWidgetEventHandler(nsIWidget
* aWidget
);
361 * Stop aWidget directing its events to this view.
363 void DetachWidgetEventHandler(nsIWidget
* aWidget
);
367 * Output debug info to FILE
368 * @param out output file handle
369 * @param aIndent indentation depth
370 * NOTE: virtual so that debugging tools not linked into gklayout can access it
372 virtual void List(FILE* out
, PRInt32 aIndent
= 0) const;
376 * @result true iff this is the root view for its view manager
380 virtual bool ExternalIsRoot() const;
382 void SetDeletionObserver(nsWeakView
* aDeletionObserver
);
384 nsIntRect
CalcWidgetBounds(nsWindowType aType
);
386 bool IsEffectivelyVisible();
388 // This is an app unit offset to add when converting view coordinates to
389 // widget coordinates. It is the offset in view coordinates from widget
390 // origin (unlike views, widgets can't extend above or to the left of their
391 // origin) to view origin expressed in appunits of this.
392 nsPoint
ViewToWidgetOffset() const { return mViewToWidgetOffset
; }
395 friend class nsWeakView
;
396 nsViewManager
*mViewManager
;
399 nsView
*mNextSibling
;
403 nsViewVisibility mVis
;
404 // position relative our parent view origin but in our appunits
405 nscoord mPosX
, mPosY
;
406 // relative to parent, but in our appunits
409 nsPoint mViewToWidgetOffset
;
412 nsWeakView
* mDeletionObserver
;
413 bool mWidgetIsTopLevel
;
415 virtual ~nsIView() {}
419 const nsView
* Impl() const;
422 NS_DEFINE_STATIC_IID_ACCESSOR(nsIView
, NS_IVIEW_IID
)
424 // nsWeakViews must *not* be used in heap!
428 nsWeakView(nsIView
* aView
) : mPrev(nsnull
), mView(aView
)
431 mView
->SetDeletionObserver(this);
438 NS_ASSERTION(mView
->mDeletionObserver
== this,
439 "nsWeakViews deleted in wrong order!");
440 // Clear deletion observer temporarily.
441 mView
->SetDeletionObserver(nsnull
);
442 // Put back the previous deletion observer.
443 mView
->SetDeletionObserver(mPrev
);
447 bool IsAlive() { return !!mView
; }
449 nsIView
* GetView() { return mView
; }
451 void SetPrevious(nsWeakView
* aWeakView
) { mPrev
= aWeakView
; }
461 static void* operator new(size_t) CPP_THROW_NEW
{ return 0; }
462 static void operator delete(void*, size_t) {}